[Pkg-javascript-commits] [dojo] 15/18: Imported Upstream version 1.7.2+dfsg

David Prévot taffit at alioth.debian.org
Fri Oct 25 19:59:28 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 28044c1deb5afeccc19105a0ced7ccbe69aaa679
Author: David Prévot <taffit at debian.org>
Date:   Thu Oct 24 18:21:39 2013 -0400

    Imported Upstream version 1.7.2+dfsg
---
 dijit/BackgroundIframe.js                          |  113 +
 dijit/Calendar.js                                  |  578 +-
 dijit/CalendarLite.js                              |  451 +
 dijit/CheckedMenuItem.js                           |   34 +-
 dijit/ColorPalette.js                              |   75 +-
 dijit/Declaration.js                               |   74 +-
 dijit/Dialog.js                                    |  481 +-
 dijit/DialogUnderlay.js                            |   45 +-
 dijit/DropDownMenu.js                              |   62 +
 dijit/Editor.js                                    |  387 +-
 dijit/InlineEditBox.js                             |  572 +-
 dijit/Menu.js                                      |  576 +-
 dijit/MenuBar.js                                   |   35 +-
 dijit/MenuBarItem.js                               |   37 +-
 dijit/MenuItem.js                                  |   77 +-
 dijit/MenuSeparator.js                             |   31 +-
 dijit/PopupMenuBarItem.js                          |   21 +-
 dijit/PopupMenuItem.js                             |   51 +-
 dijit/ProgressBar.js                               |   59 +-
 dijit/TitlePane.js                                 |  102 +-
 dijit/Toolbar.js                                   |   71 +-
 dijit/ToolbarSeparator.js                          |   31 +-
 dijit/Tooltip.js                                   |  345 +-
 dijit/TooltipDialog.js                             |  272 +-
 dijit/Tree.js                                      |  416 +-
 dijit/WidgetSet.js                                 |  229 +
 dijit/_BidiSupport.js                              |   69 +
 dijit/_Calendar.js                                 |   20 +-
 dijit/_Contained.js                                |  112 +-
 dijit/_Container.js                                |   69 +-
 dijit/_CssStateMixin.js                            |   64 +-
 dijit/_DialogMixin.js                              |   25 +-
 dijit/_FocusMixin.js                               |   73 +
 dijit/_HasDropDown.js                              |  206 +-
 dijit/_KeyNavContainer.js                          |  118 +-
 dijit/_MenuBase.js                                 |  391 +
 dijit/_OnDijitClickMixin.js                        |  125 +
 dijit/_PaletteMixin.js                             |  120 +-
 dijit/_Templated.js                                |  344 +-
 dijit/_TemplatedMixin.js                           |  304 +
 dijit/_TimePicker.js                               |  189 +-
 dijit/_Widget.js                                   |  341 +-
 dijit/_WidgetBase.js                               |  527 +-
 dijit/_WidgetsInTemplateMixin.js                   |   61 +
 dijit/_base.js                                     |   22 +-
 dijit/_base/focus.js                               |  721 +-
 dijit/_base/manager.js                             |  489 +-
 dijit/_base/place.js                               |  489 +-
 dijit/_base/popup.js                               |  427 +-
 dijit/_base/scroll.js                              |   22 +-
 dijit/_base/sniff.js                               |   16 +-
 dijit/_base/typematic.js                           |  184 +-
 dijit/_base/wai.js                                 |  232 +-
 dijit/_base/window.js                              |   18 +-
 dijit/_editor/RichText.js                          | 1429 +-
 dijit/_editor/_Plugin.js                           |   50 +-
 dijit/_editor/html.js                              |   20 +-
 dijit/_editor/nls/FontChoice.js                    |    2 +
 dijit/_editor/nls/LinkDialog.js                    |    2 +
 dijit/_editor/nls/az/FontChoice.js                 |   27 +
 dijit/_editor/nls/az/LinkDialog.js                 |   16 +
 dijit/_editor/nls/az/commands.js                   |   52 +
 dijit/_editor/nls/commands.js                      |    2 +
 dijit/_editor/nls/hr/FontChoice.js                 |   25 +
 dijit/_editor/nls/hr/LinkDialog.js                 |   14 +
 dijit/_editor/nls/hr/commands.js                   |   51 +
 dijit/_editor/plugins/AlwaysShowToolbar.js         |   82 +-
 dijit/_editor/plugins/EnterKeyHandling.js          |  239 +-
 dijit/_editor/plugins/FontChoice.js                |  171 +-
 dijit/_editor/plugins/FullScreen.js                |  207 +-
 dijit/_editor/plugins/LinkDialog.js                |  331 +-
 dijit/_editor/plugins/NewPage.js                   |   48 +-
 dijit/_editor/plugins/Print.js                     |   52 +-
 dijit/_editor/plugins/TabIndent.js                 |   46 +-
 dijit/_editor/plugins/TextColor.js                 |   90 +-
 dijit/_editor/plugins/ToggleDir.js                 |   51 +-
 dijit/_editor/plugins/ViewSource.js                |  188 +-
 dijit/_editor/range.js                             |  208 +-
 dijit/_editor/selection.js                         |  104 +-
 dijit/_tree/dndSource.js                           |   23 +-
 dijit/a11y.js                                      |  177 +
 dijit/dijit-all.js                                 |   73 +-
 dijit/dijit.js                                     |   34 +-
 dijit/dijit.profile.js                             |   39 +
 dijit/focus.js                                     |  389 +
 dijit/form/Button.js                               |  333 +-
 dijit/form/CheckBox.js                             |  167 +-
 dijit/form/ComboBox.js                             | 1216 +-
 dijit/form/ComboBoxMixin.js                        |  146 +
 dijit/form/ComboButton.js                          |   87 +-
 dijit/form/CurrencyTextBox.js                      |   72 +-
 dijit/form/DataList.js                             |   63 +
 dijit/form/DateTextBox.js                          |   34 +-
 dijit/form/DropDownButton.js                       |  103 +-
 dijit/form/FilteringSelect.js                      |  134 +-
 dijit/form/Form.js                                 |   83 +-
 dijit/form/HorizontalRule.js                       |   24 +-
 dijit/form/HorizontalRuleLabels.js                 |   27 +-
 dijit/form/HorizontalSlider.js                     |  183 +-
 dijit/form/MappedTextBox.js                        |   87 +-
 dijit/form/MultiSelect.js                          |   72 +-
 dijit/form/NumberSpinner.js                        |   31 +-
 dijit/form/NumberTextBox.js                        |  108 +-
 dijit/form/RadioButton.js                          |   22 +-
 dijit/form/RangeBoundTextBox.js                    |  141 +-
 dijit/form/Select.js                               |  149 +-
 dijit/form/SimpleTextarea.js                       |   46 +-
 dijit/form/Slider.js                               |   21 +-
 dijit/form/TextBox.js                              |  459 +-
 dijit/form/Textarea.js                             |  151 +-
 dijit/form/TimeTextBox.js                          |   62 +-
 dijit/form/ToggleButton.js                         |   31 +-
 dijit/form/ValidationTextBox.js                    |  268 +-
 dijit/form/VerticalRule.js                         |   42 +-
 dijit/form/VerticalRuleLabels.js                   |   38 +-
 dijit/form/VerticalSlider.js                       |   55 +-
 dijit/form/_AutoCompleterMixin.js                  |  764 +
 dijit/form/_ButtonMixin.js                         |   85 +
 dijit/form/_CheckBoxMixin.js                       |   77 +
 dijit/form/_ComboBoxMenu.js                        |  138 +
 dijit/form/_ComboBoxMenuMixin.js                   |  191 +
 dijit/form/_DateTimeTextBox.js                     |  109 +-
 dijit/form/_ExpandingTextAreaMixin.js              |  121 +
 dijit/form/_FormMixin.js                           |  199 +-
 dijit/form/_FormSelectWidget.js                    |  153 +-
 dijit/form/_FormValueMixin.js                      |   95 +
 dijit/form/_FormValueWidget.js                     |   58 +
 dijit/form/_FormWidget.js                          |  374 +-
 dijit/form/_FormWidgetMixin.js                     |  231 +
 dijit/form/_ListBase.js                            |  123 +
 dijit/form/_ListMouseMixin.js                      |   96 +
 dijit/form/_RadioButtonMixin.js                    |   70 +
 dijit/form/_Spinner.js                             |   72 +-
 dijit/form/_TextBoxMixin.js                        |  408 +
 dijit/form/_ToggleButtonMixin.js                   |   51 +
 dijit/form/nls/ComboBox.js                         |    2 +
 dijit/form/nls/Textarea.js                         |    4 +-
 dijit/form/nls/az/ComboBox.js                      |    8 +
 dijit/form/nls/az/Textarea.js                      |    8 +
 dijit/form/nls/az/validate.js                      |    9 +
 dijit/form/nls/hr/ComboBox.js                      |    6 +
 dijit/form/nls/hr/Textarea.js                      |    9 +
 dijit/form/nls/hr/validate.js                      |    7 +
 dijit/form/nls/validate.js                         |    2 +
 dijit/form/templates/Button.html                   |   16 +-
 dijit/form/templates/CheckBox.html                 |    4 +-
 dijit/form/templates/ComboButton.html              |   14 +-
 dijit/form/templates/DropDownBox.html              |    6 +-
 dijit/form/templates/DropDownButton.html           |   10 +-
 dijit/form/templates/HorizontalSlider.html         |   24 +-
 dijit/form/templates/Select.html                   |    8 +-
 dijit/form/templates/Spinner.html                  |    8 +-
 dijit/form/templates/TextBox.html                  |    2 +-
 dijit/form/templates/ValidationTextBox.html        |    4 +-
 dijit/form/templates/VerticalSlider.html           |   24 +-
 dijit/hccss.js                                     |   52 +
 dijit/icons/commonIcons.css                        |   11 +-
 dijit/icons/commonIcons_rtl.css                    |   12 +-
 dijit/icons/editorIcons.css                        |    2 +-
 dijit/layout/AccordionContainer.js                 |  537 +-
 dijit/layout/AccordionPane.js                      |   36 +-
 dijit/layout/BorderContainer.js                    |  524 +-
 dijit/layout/ContentPane.js                        |  157 +-
 dijit/layout/LayoutContainer.js                    |   62 +-
 dijit/layout/LinkPane.js                           |   75 +-
 dijit/layout/ScrollingTabController.js             |  185 +-
 dijit/layout/SplitContainer.js                     |  176 +-
 dijit/layout/StackContainer.js                     |  181 +-
 dijit/layout/StackController.js                    |  607 +-
 dijit/layout/TabContainer.js                       |   32 +-
 dijit/layout/TabController.js                      |  283 +-
 dijit/layout/_ContentPaneResizeMixin.js            |   83 +-
 dijit/layout/_LayoutWidget.js                      |  199 +-
 dijit/layout/_TabContainerBase.js                  |   56 +-
 dijit/layout/templates/AccordionButton.html        |    8 +-
 dijit/layout/templates/ScrollingTabController.html |   29 +-
 dijit/layout/templates/TabContainer.html           |    6 +-
 .../templates/_ScrollingTabControllerButton.html   |   10 +-
 dijit/layout/templates/_TabButton.html             |   18 +-
 dijit/layout/utils.js                              |  141 +
 dijit/lib/main.js                                  |   13 -
 dijit/main.js                                      |   10 +
 dijit/nls/az/common.js                             |   10 +
 dijit/nls/az/loading.js                            |    8 +
 dijit/nls/common.js                                |    2 +
 dijit/nls/hr/common.js                             |    8 +
 dijit/nls/hr/loading.js                            |    6 +
 dijit/nls/loading.js                               |    2 +
 dijit/package.json                                 |   45 +-
 dijit/place.js                                     |  369 +
 dijit/popup.js                                     |  379 +
 dijit/registry.js                                  |  174 +
 dijit/robot.js                                     |   13 +-
 dijit/robotx.js                                    |   44 +-
 dijit/templates/Calendar.html                      |   35 +-
 dijit/templates/CheckedMenuItem.html               |   12 +-
 dijit/templates/ColorPalette.html                  |    4 +-
 dijit/templates/Dialog.html                        |   10 +-
 dijit/templates/Menu.html                          |    4 +-
 dijit/templates/MenuBar.html                       |    2 +-
 dijit/templates/MenuBarItem.html                   |    6 +-
 dijit/templates/MenuItem.html                      |   12 +-
 dijit/templates/ProgressBar.html                   |    8 +-
 dijit/templates/TimePicker.html                    |   10 +-
 dijit/templates/TitlePane.html                     |   18 +-
 dijit/templates/Tooltip.html                       |    4 +-
 dijit/templates/TooltipDialog.html                 |    2 +-
 dijit/templates/Tree.html                          |    4 +-
 dijit/templates/TreeNode.html                      |   14 +-
 dijit/tests/Bidi.html                              |    6 +-
 dijit/tests/Dialog.html                            |   27 +-
 dijit/tests/NodeList-instantiate.html              |    8 +-
 dijit/tests/ProgressBar.html                       |   23 +-
 dijit/tests/Tooltip-placement.html                 |  101 +-
 .../BidiSupportModule/BidiSupportTest.js           |  181 +
 .../tests/_BidiSupport/BidiSupportModule/module.js |   11 +
 .../_BidiSupport/BidiSupportModule/runTests.html   |   11 +
 dijit/tests/_BidiSupport/_data/categoriesHeb.json  |   12 +
 dijit/tests/_BidiSupport/_data/countriesHeb.json   |   46 +
 .../DynamicChangeTextDir.html                      |  548 +
 .../dynamicallyChangeTextDir/module.js             |   11 +
 .../dynamicallyChangeTextDir/runTests.html         |   10 +
 dijit/tests/_BidiSupport/form/module.js            |   23 +
 .../_BidiSupport/form/noTextDirTextWidgets.html    |  433 +
 .../_BidiSupport/form/robot/InlineEditBox.html     |  264 +
 .../_BidiSupport/form/robot/SimpleComboBoxes.html  |  414 +
 .../_BidiSupport/form/robot/SimpleTextarea.html    |  388 +
 dijit/tests/_BidiSupport/form/robot/TextBoxes.html |  238 +
 dijit/tests/_BidiSupport/form/robot/Textarea.html  |  265 +
 dijit/tests/_BidiSupport/form/runTests.html        |   10 +
 .../_BidiSupport/form/test_InlineEditBox.html      |  107 +
 .../_BidiSupport/form/test_SimpleComboBoxes.html   |   87 +
 .../_BidiSupport/form/test_SimpleTextarea.html     |  106 +
 dijit/tests/_BidiSupport/form/test_TextBoxes.html  |   86 +
 dijit/tests/_BidiSupport/form/test_Textarea.html   |  129 +
 .../inheritance/Inher-ComplexMarkupContainers.html |  262 +
 .../inheritance/Inher-MarkupContainers.html        |  158 +
 .../_BidiSupport/inheritance/Inher-Simple.html     |  104 +
 dijit/tests/_BidiSupport/inheritance/module.js     |   15 +
 dijit/tests/_BidiSupport/inheritance/runTests.html |   11 +
 dijit/tests/_BidiSupport/module.js                 |   21 +
 dijit/tests/_BidiSupport/runTests.html             |   11 +
 .../tests/_BidiSupport/tree/ProgrammaticTree.html  |  292 +
 dijit/tests/_BidiSupport/tree/SimpleTree.html      |  270 +
 .../_BidiSupport/tree/TreeRootlessCustomIcons.html |  267 +
 dijit/tests/_BidiSupport/tree/module.js            |   15 +
 dijit/tests/_BidiSupport/tree/runTests.html        |   10 +
 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                        |   36 +-
 dijit/tests/_Templated-widgetsInTemplate.html      |  499 -
 dijit/tests/_Templated-widgetsInTemplate1.x.html   |   27 +-
 dijit/tests/_Templated.html                        |  229 -
 dijit/tests/_TemplatedMixin.html                   |  230 +
 dijit/tests/_Widget-attr.html                      |  275 +-
 dijit/tests/_Widget-connect-performance.html       |    2 +-
 dijit/tests/_Widget-deferredConnect.html           |    5 +-
 dijit/tests/_Widget-lifecycle.html                 |    2 +-
 dijit/tests/_Widget-on.html                        |   92 +
 dijit/tests/_Widget-ondijitclick.html              |   15 +-
 dijit/tests/_Widget-placeAt.html                   |    2 +-
 dijit/tests/_Widget-subscribe.html                 |    2 +-
 dijit/tests/_WidgetsInTemplateMixin.html           |  494 +
 dijit/tests/_altCalendar.html                      |   30 +-
 dijit/tests/_base/manager.html                     |    2 +-
 dijit/tests/_base/place.html                       |  144 +-
 dijit/tests/_base/robot/CrossWindow.html           |    5 +-
 dijit/tests/_base/robot/FocusManager.html          |    9 +-
 dijit/tests/_base/robot/focus_mouse.html           |   13 +-
 dijit/tests/_base/robot/popup.html                 |   77 +-
 dijit/tests/_base/robot/typematic.html             |    5 +-
 dijit/tests/_base/runTests.html                    |    9 +
 dijit/tests/_base/tabindex.html                    |    2 +-
 dijit/tests/_base/test_CrossWindow.html            |   39 +-
 dijit/tests/_base/test_FocusManager.html           |    5 +-
 dijit/tests/_base/test_focusWidget.html            |   11 +-
 dijit/tests/_base/test_popup.html                  |   44 +-
 dijit/tests/_base/test_typematic.html              |    8 +-
 dijit/tests/_base/wai.html                         |    6 +-
 dijit/tests/_data/SlowStore.js                     |    4 +-
 dijit/tests/_loadTest.js                           |   26 +-
 dijit/tests/_testCommon.js                         |  176 +-
 dijit/tests/delay.js                               |   19 +
 dijit/tests/editor/BackForwardState.html           |    1 +
 dijit/tests/editor/EnterKeyHandling.html           |    2 +-
 dijit/tests/editor/nls_8859-2.html                 |    2 +-
 dijit/tests/editor/nls_sjis.html                   |    2 +-
 dijit/tests/editor/nls_utf8.html                   |    2 +-
 dijit/tests/editor/robot/BackForwardState.html     |    5 +-
 dijit/tests/editor/robot/CustomPlugin.html         |   70 +-
 dijit/tests/editor/robot/Editor_FontChoice.html    |  151 +-
 dijit/tests/editor/robot/Editor_FullScreen.html    |  111 +-
 dijit/tests/editor/robot/Editor_LinkDialog.html    |   50 +-
 dijit/tests/editor/robot/Editor_NewPage.html       |    5 +-
 dijit/tests/editor/robot/Editor_ViewSource.html    |   69 +-
 dijit/tests/editor/robot/Editor_a11y.html          |   19 +-
 dijit/tests/editor/robot/Editor_misc.html          |   41 +-
 dijit/tests/editor/robot/Editor_mouse.html         |    7 +-
 dijit/tests/editor/robot/EnterKeyHandling.html     |   51 +-
 dijit/tests/editor/robot/TabIndent.html            |    7 +-
 dijit/tests/editor/robot/ToggleDir.html            |    7 +-
 dijit/tests/editor/robot/ToggleDir_rtl.html        |    7 +-
 dijit/tests/editor/test_CustomPlugin.html          |    8 +-
 dijit/tests/editor/test_Editor.html                |    8 +-
 dijit/tests/editor/test_LinkDialog.html            |    2 +-
 dijit/tests/editor/test_ToggleDir_rtl.html         |    2 +-
 dijit/tests/editor/test_ViewSource.html            |    8 +-
 dijit/tests/focus-framedojo-child.html             |   51 +
 dijit/tests/focus-framedojo.html                   |   22 +
 dijit/tests/form/AutoCompleterMixin.html           |  286 +
 dijit/tests/form/ButtonMixin.html                  |  168 +
 dijit/tests/form/CheckBoxMixin.html                |  295 +
 dijit/tests/form/DateTextBox.html                  |    2 +-
 dijit/tests/form/ExpandingTextAreaMixin.html       |  286 +
 dijit/tests/form/Form.html                         |   49 +-
 dijit/tests/form/RadioButtonMixin.html             |  187 +
 dijit/tests/form/TextBoxMixin.html                 |  264 +
 dijit/tests/form/TextBox_sizes.html                |   21 +-
 dijit/tests/form/TextBox_sizes.js                  |    8 +-
 dijit/tests/form/TextBox_types.html                |   87 +
 dijit/tests/form/ToggleButtonMixin.html            |  169 +
 dijit/tests/form/_autoComplete.html                |   17 +-
 dijit/tests/form/mobile.html                       |  201 +
 dijit/tests/form/module.js                         |   13 +-
 dijit/tests/form/robot/Button_a11y.html            |  155 +-
 dijit/tests/form/robot/Button_mouse.html           |  184 +-
 dijit/tests/form/robot/CheckBox_a11y.html          |   25 +-
 dijit/tests/form/robot/CheckBox_mouse.html         |    7 +-
 dijit/tests/form/robot/DateTextBox.html            |   82 +-
 dijit/tests/form/robot/Form_onsubmit.html          |   87 +-
 dijit/tests/form/robot/Form_state.html             |    7 +-
 dijit/tests/form/robot/MultiSelect.html            |   23 +-
 dijit/tests/form/robot/Select.html                 |  119 +-
 dijit/tests/form/robot/SimpleTextarea.html         |    5 +-
 dijit/tests/form/robot/Slider_a11y.html            |   67 +-
 dijit/tests/form/robot/Slider_mouse.html           |   64 +-
 dijit/tests/form/robot/Spinner_a11y.html           |   66 +-
 dijit/tests/form/robot/Spinner_mouse.html          |    7 +-
 dijit/tests/form/robot/Textarea.html               |   38 +-
 dijit/tests/form/robot/TimeTextBox.html            |   67 +-
 dijit/tests/form/robot/ValidationTextBox.html      |  142 +-
 dijit/tests/form/robot/_autoComplete_a11y.html     |  129 +-
 dijit/tests/form/robot/_autoComplete_mouse.html    |   35 +-
 dijit/tests/form/robot/validationMessages.html     |   82 +-
 dijit/tests/form/test_Button.html                  |   89 +-
 dijit/tests/form/test_CheckBox.html                |    6 +-
 dijit/tests/form/test_DateTextBox.html             |   10 +-
 dijit/tests/form/test_Form_onsubmit.html           |   12 +-
 dijit/tests/form/test_Form_state.html              |   16 +-
 dijit/tests/form/test_MultiSelect.html             |   12 +-
 dijit/tests/form/test_Select.html                  |  185 +-
 dijit/tests/form/test_SimpleTextarea.html          |    2 +-
 dijit/tests/form/test_Slider.html                  |   15 +-
 dijit/tests/form/test_Spinner.html                 |    6 +-
 dijit/tests/form/test_Textarea.html                |    6 +-
 dijit/tests/form/test_TimeTextBox.html             |   11 +-
 dijit/tests/form/test_validStatePerformance.html   |   39 +-
 dijit/tests/form/test_validate.html                |   93 +-
 dijit/tests/form/test_verticalAlign.html           |    2 +-
 dijit/tests/helpers.js                             |    8 +-
 dijit/tests/i18n/currency.html                     |    4 +-
 dijit/tests/i18n/date.html                         |    6 +-
 dijit/tests/i18n/digit.html                        |    6 +-
 dijit/tests/i18n/number.html                       |    4 +-
 dijit/tests/i18n/textbox.html                      |    4 +-
 dijit/tests/i18n/time.html                         |   10 +-
 dijit/tests/infrastructure-module.js               |    6 +-
 dijit/tests/layout/AccordionContainer.html         |   88 +-
 dijit/tests/layout/BorderContainer.html            |   77 +-
 dijit/tests/layout/ContentPane-remote.html         |   26 +-
 dijit/tests/layout/ContentPane.html                |   39 +-
 dijit/tests/layout/ContentPaneLayout.html          |   36 +-
 dijit/tests/layout/LayoutContainer.html            |    4 +-
 dijit/tests/layout/StackContainer.html             |  373 +
 dijit/tests/layout/TabContainer.html               |  119 +-
 dijit/tests/layout/TabContainerTitlePane.html      |    2 +-
 dijit/tests/layout/borderContainer.php             |    4 +-
 dijit/tests/layout/mobile.html                     |  142 +
 dijit/tests/layout/module.js                       |    2 +-
 dijit/tests/layout/multipleLayoutWidgets.php       |    4 +-
 dijit/tests/layout/nestedStack.html                |    2 +-
 .../layout/robot/AccordionContainer_a11y.html      |   12 +-
 .../layout/robot/AccordionContainer_mouse.html     |    2 +-
 dijit/tests/layout/robot/BorderContainer.html      |   10 +-
 .../layout/robot/BorderContainer_complex.html      |   70 +-
 dijit/tests/layout/robot/BorderContainer_full.html |    4 +-
 .../tests/layout/robot/BorderContainer_nested.html |    2 +-
 dijit/tests/layout/robot/GUI.html                  |    2 +-
 dijit/tests/layout/robot/StackContainer_mouse.html |  372 -
 dijit/tests/layout/robot/TabContainer_a11y.html    |    2 +-
 dijit/tests/layout/robot/TabContainer_mouse.html   |    6 +-
 .../tests/layout/robot/TabContainer_noLayout.html  |  534 +-
 dijit/tests/layout/test_AccordionContainer.html    |    7 +-
 dijit/tests/layout/test_BorderContainer.html       |   14 +-
 .../layout/test_BorderContainer_experimental.html  |    2 +-
 dijit/tests/layout/test_ContentPane.html           |   21 +-
 dijit/tests/layout/test_Gui.html                   |    6 +-
 dijit/tests/layout/test_SplitContainer.html        |    2 +-
 dijit/tests/layout/test_StackContainer.html        |  200 -
 dijit/tests/layout/test_TabContainer.html          |    2 +-
 dijit/tests/mobile.html                            |  183 +
 dijit/tests/module.js                              |    2 +
 dijit/tests/robot/BgIframe.html                    |    5 +-
 dijit/tests/robot/Calendar_a11y.html               |  114 +-
 dijit/tests/robot/ColorPalette.html                |   27 +-
 dijit/tests/robot/Dialog_a11y.html                 |   60 +-
 dijit/tests/robot/Dialog_focusDestroy.html         |    2 +-
 dijit/tests/robot/Dialog_mouse.html                |   86 +-
 dijit/tests/robot/InlineEditBox.html               |   16 +-
 dijit/tests/robot/Menu_a11y.html                   |  150 +-
 dijit/tests/robot/Menu_iframe.html                 |   22 +-
 dijit/tests/robot/Menu_mouse.html                  |    5 +-
 dijit/tests/robot/TitlePane.html                   |    8 +-
 dijit/tests/robot/Toolbar.html                     |   56 +-
 dijit/tests/robot/TooltipDialog_a11y.html          |   36 +-
 dijit/tests/robot/TooltipDialog_mouse.html         |   86 +-
 dijit/tests/robot/Tooltip_a11y.html                |    5 +-
 dijit/tests/robot/Tooltip_mouse.html               |   92 +-
 dijit/tests/robot/Tooltip_mouse_quirks.html        |    2 +-
 dijit/tests/robot/_Widget-deferredConnect.html     |    4 +-
 dijit/tests/robot/_Widget-ondijitclick_a11y.html   |   39 +-
 dijit/tests/robot/_Widget-ondijitclick_mouse.html  |   33 +-
 dijit/tests/test_Calendar.html                     |   12 +-
 dijit/tests/test_CalendarLite.html                 |   43 +
 dijit/tests/test_ColorPalette.html                 |   39 +-
 dijit/tests/test_Declaration.html                  |   26 +-
 dijit/tests/test_Declaration_1.x.html              |    2 +-
 dijit/tests/test_Dialog.html                       |   26 +-
 dijit/tests/test_Dialog_focusDestroy.html          |    4 +-
 dijit/tests/test_InlineEditBox.html                |    2 +-
 dijit/tests/test_Menu.html                         |   21 +-
 dijit/tests/test_Menu_iframe.html                  |    3 +
 dijit/tests/test_TitlePane.html                    |   18 +-
 dijit/tests/test_Toolbar.html                      |    6 +-
 dijit/tests/test_Tooltip.html                      |   35 +-
 dijit/tests/test_TooltipDialog.html                |   17 +-
 dijit/tests/test_UIWindowIssue_child.html          |   47 +
 dijit/tests/test_UIWindowIssue_main.html           |   75 +
 dijit/tests/tree/CustomLabel.html                  |    2 +-
 dijit/tests/tree/Tree.html                         |   55 +-
 dijit/tests/tree/Tree_with_JRS.html                |    2 +-
 dijit/tests/tree/module.js                         |    4 +-
 dijit/tests/tree/robot/Tree_a11y.html              |   43 +-
 dijit/tests/tree/robot/Tree_dnd.html               |   32 +-
 dijit/tests/tree/robot/Tree_dnd_multiParent.html   |   69 +-
 dijit/tests/tree/robot/Tree_selector.html          |   28 +-
 dijit/tests/tree/robot/Tree_v1.html                |   12 +-
 dijit/tests/tree/test_Tree.html                    |    8 +-
 dijit/tests/tree/test_Tree_DnD.html                |   32 +-
 dijit/tests/tree/test_Tree_v1.html                 |    2 +
 dijit/themes/claro/Calendar.css                    |   74 +-
 dijit/themes/claro/Calendar.less                   |   74 +-
 dijit/themes/claro/ColorPalette.css                |    8 +-
 dijit/themes/claro/ColorPalette.less               |   10 +-
 dijit/themes/claro/Common.css                      |   16 +-
 dijit/themes/claro/Common.less                     |   14 +-
 dijit/themes/claro/Dialog.css                      |    8 +-
 dijit/themes/claro/Dialog.less                     |   14 +-
 dijit/themes/claro/Editor.css                      |    4 +-
 dijit/themes/claro/Editor.less                     |    4 +-
 dijit/themes/claro/InlineEditBox.css               |    4 +-
 dijit/themes/claro/Menu.css                        |   24 +-
 dijit/themes/claro/Menu.less                       |   18 +-
 dijit/themes/claro/ProgressBar.css                 |   12 +-
 dijit/themes/claro/ProgressBar.less                |   10 +-
 dijit/themes/claro/README                          |   31 +-
 dijit/themes/claro/TimePicker.css                  |    4 +-
 dijit/themes/claro/TimePicker.less                 |    6 +-
 dijit/themes/claro/TitlePane.css                   |   12 +-
 dijit/themes/claro/TitlePane.less                  |   10 +-
 dijit/themes/claro/Toolbar.css                     |   55 +-
 dijit/themes/claro/Toolbar.less                    |   46 +-
 dijit/themes/claro/Tree.css                        |   28 +-
 dijit/themes/claro/Tree.less                       |   17 +-
 dijit/themes/claro/compile.js                      |    9 +-
 dijit/themes/claro/form/Button.css                 |   14 +-
 dijit/themes/claro/form/Button.less                |   10 +-
 dijit/themes/claro/form/Checkbox.css               |    8 +-
 dijit/themes/claro/form/Checkbox.less              |    8 +-
 dijit/themes/claro/form/Common.css                 |   35 +-
 dijit/themes/claro/form/Common.less                |   30 +-
 dijit/themes/claro/form/NumberSpinner.css          |    4 +-
 dijit/themes/claro/form/NumberSpinner.less         |    6 +-
 dijit/themes/claro/form/RadioButton.css            |    8 +-
 dijit/themes/claro/form/RadioButton.less           |    8 +-
 dijit/themes/claro/form/Select.css                 |   18 +-
 dijit/themes/claro/form/Select.less                |    6 +-
 dijit/themes/claro/form/Slider.css                 |   33 +-
 dijit/themes/claro/form/Slider.less                |   17 +-
 dijit/themes/claro/layout/AccordionContainer.css   |   21 +-
 dijit/themes/claro/layout/AccordionContainer.less  |    7 +-
 dijit/themes/claro/layout/BorderContainer.css      |    8 +-
 dijit/themes/claro/layout/BorderContainer.less     |    4 +-
 dijit/themes/claro/layout/TabContainer.css         |   42 +-
 dijit/themes/claro/layout/TabContainer.less        |   26 +-
 dijit/themes/claro/variables.less                  |  221 +-
 dijit/themes/dijit.css                             |  159 +-
 dijit/themes/dijit_rtl.css                         |   20 +-
 dijit/themes/nihilo/Calendar.css                   |    4 +-
 dijit/themes/nihilo/form/Button.css                |    4 +-
 dijit/themes/nihilo/form/Common.css                |    2 +-
 .../themes/nihilo/images/tooltipConnectorRight.png |  Bin 205 -> 363 bytes
 dijit/themes/soria/Calendar.css                    |    4 +-
 dijit/themes/soria/form/Button.css                 |    4 +-
 dijit/themes/soria/form/Common.css                 |    2 +-
 .../themes/soria/images/tooltipConnectorRight.png  |  Bin 1005 -> 363 bytes
 dijit/themes/themeTester-orig.html                 |   22 +-
 dijit/themes/themeTester.html                      |  370 +-
 dijit/themes/tundra/Calendar.css                   |    4 +-
 dijit/themes/tundra/Common.css                     |   11 +-
 dijit/themes/tundra/form/Common.css                |    2 +-
 dijit/tree/ForestStoreModel.js                     |   40 +-
 dijit/tree/TreeStoreModel.js                       |   80 +-
 dijit/tree/_dndContainer.js                        |  105 +-
 dijit/tree/_dndSelector.js                         |  181 +-
 dijit/tree/dndSource.js                            |  130 +-
 dijit/tree/model.js                                |   38 +-
 dijit/typematic.js                                 |  206 +
 dojo/AdapterRegistry.js                            |   27 +-
 dojo/DeferredList.js                               |   36 +-
 dojo/Evented.js                                    |   32 +
 dojo/NodeList-data.js                              |   71 +-
 dojo/NodeList-dom.js                               |  454 +
 dojo/NodeList-fx.js                                |  109 +-
 dojo/NodeList-html.js                              |   27 +-
 dojo/NodeList-manipulate.js                        |   43 +-
 dojo/NodeList-traverse.js                          |   73 +-
 dojo/OpenAjax.js                                   |   40 +-
 dojo/Stateful.js                                   |   31 +-
 dojo/_base.js                                      |   11 -
 dojo/_base/Color.js                                |  111 +-
 dojo/_base/Deferred.js                             |  462 +-
 dojo/_base/NodeList.js                             |  974 +-
 dojo/_base/_loader/bootstrap.js                    |  568 -
 dojo/_base/_loader/hostenv_browser.js              |  505 -
 dojo/_base/_loader/hostenv_ff_ext.js               |  331 -
 dojo/_base/_loader/hostenv_rhino.js                |  207 -
 dojo/_base/_loader/hostenv_spidermonkey.js         |   80 -
 dojo/_base/_loader/loader.js                       |  904 -
 dojo/_base/_loader/loader_debug.js                 |   75 -
 dojo/_base/_loader/loader_xd.js                    |  716 -
 dojo/_base/array.js                                |  570 +-
 dojo/_base/browser.js                              |   37 +-
 dojo/_base/config.js                               |  174 +
 dojo/_base/configFirefoxExtension.js               |  334 +
 dojo/_base/configNode.js                           |   87 +
 dojo/_base/configRhino.js                          |  121 +
 dojo/_base/configSpidermonkey.js                   |   84 +
 dojo/_base/connect.js                              |  429 +-
 dojo/_base/declare.js                              |   81 +-
 dojo/_base/event.js                                |  666 +-
 dojo/_base/fx.js                                   |  117 +-
 dojo/_base/html.js                                 | 1973 +-
 dojo/_base/json.js                                 |  147 +-
 dojo/_base/kernel.js                               |  302 +
 dojo/_base/lang.js                                 |  897 +-
 dojo/_base/loader.js                               |  671 +
 dojo/_base/query-sizzle.js                         |  875 -
 dojo/_base/query.js                                | 1670 +-
 dojo/_base/sniff.js                                |  187 +
 dojo/_base/unload.js                               |   81 +
 dojo/_base/url.js                                  |  111 +
 dojo/_base/window.js                               |   69 +-
 dojo/_base/xhr.js                                  |  501 +-
 dojo/_firebug/firebug.css                          |    2 +-
 dojo/_firebug/firebug.js                           |  282 +-
 dojo/aspect.js                                     |  207 +
 dojo/back.js                                       |   99 +-
 dojo/behavior.js                                   |   46 +-
 dojo/cache.js                                      |  117 +-
 dojo/cldr/monetary.js                              |    7 +-
 dojo/cldr/nls/ar/hebrew.js                         |   10 +-
 dojo/cldr/nls/ar/islamic-civil.js                  |  225 -
 dojo/cldr/nls/ar/islamic.js                        |   10 +-
 dojo/cldr/supplemental.js                          |    9 +-
 dojo/colors.js                                     |  317 +-
 dojo/cookie.js                                     |   16 +-
 dojo/currency.js                                   |   23 +-
 dojo/data/ItemFileReadStore.js                     |  103 +-
 dojo/data/ItemFileWriteStore.js                    |  167 +-
 dojo/data/ObjectStore.js                           |  130 +-
 dojo/data/api/Identity.js                          |   10 +-
 dojo/data/api/Notification.js                      |   11 +-
 dojo/data/api/Read.js                              |  167 +-
 dojo/data/api/Request.js                           |    7 +-
 dojo/data/api/Write.js                             |   93 +-
 dojo/data/util/filter.js                           |   15 +-
 dojo/data/util/simpleFetch.js                      |   20 +-
 dojo/data/util/sorter.js                           |   20 +-
 dojo/date.js                                       |   11 +-
 dojo/date/locale.js                                |   56 +-
 dojo/date/stamp.js                                 |   11 +-
 dojo/dnd/AutoSource.js                             |   13 +
 dojo/dnd/Avatar.js                                 |    7 +-
 dojo/dnd/Container.js                              |   37 +-
 dojo/dnd/Manager.js                                |   21 +-
 dojo/dnd/Moveable.js                               |   42 +-
 dojo/dnd/Mover.js                                  |   29 +-
 dojo/dnd/Selector.js                               |   31 +-
 dojo/dnd/Source.js                                 |   99 +-
 dojo/dnd/Target.js                                 |   13 +
 dojo/dnd/TimedMoveable.js                          |   44 +-
 dojo/dnd/autoscroll.js                             |   56 +-
 dojo/dnd/common.js                                 |    7 +-
 dojo/dnd/move.js                                   |   22 +-
 dojo/dojo.js                                       | 2013 +-
 dojo/dojo.profile.js                               |   40 +
 dojo/dom-attr.js                                   |  238 +
 dojo/dom-class.js                                  |  320 +
 dojo/dom-construct.js                              |  380 +
 dojo/dom-form.js                                   |  166 +
 dojo/dom-geometry.js                               |  763 +
 dojo/dom-prop.js                                   |  196 +
 dojo/dom-style.js                                  |  337 +
 dojo/dom.js                                        |  166 +
 dojo/domReady.js                                   |   95 +
 dojo/fx.js                                         |  172 +-
 dojo/fx/Toggler.js                                 |   24 +-
 dojo/fx/easing.js                                  |   25 +-
 dojo/gears.js                                      |   25 +-
 dojo/has.js                                        |  178 +
 dojo/hash.js                                       |   49 +-
 dojo/html.js                                       |   88 +-
 dojo/i18n.js                                       |  519 +-
 dojo/io-query.js                                   |   98 +
 dojo/io/iframe.js                                  |   22 +-
 dojo/io/script.js                                  |   81 +-
 dojo/jaxer.js                                      |    7 +-
 dojo/json.js                                       |  149 +
 dojo/keys.js                                       |   80 +
 dojo/lib/backCompat.js                             |  276 -
 dojo/lib/kernel.js                                 |   19 -
 dojo/lib/main-browser.js                           |   54 -
 dojo/lib/plugins/i18n.js                           |   87 -
 dojo/lib/plugins/text.js                           |   63 -
 dojo/loadInit.js                                   |    7 +
 dojo/main.js                                       |   50 +
 dojo/mouse.js                                      |  127 +
 dojo/nls/az/colors.js                              |  153 +
 dojo/nls/ca/colors.js                              |    1 +
 dojo/nls/colors.js                                 |    3 +
 dojo/nls/cs/colors.js                              |    1 +
 dojo/nls/da/colors.js                              |    1 +
 dojo/nls/de/colors.js                              |    1 +
 dojo/nls/el/colors.js                              |    1 +
 dojo/nls/es/colors.js                              |    1 +
 dojo/nls/fi/colors.js                              |    1 +
 dojo/nls/fr/colors.js                              |    1 +
 dojo/nls/hr/colors.js                              |  156 +
 dojo/nls/hu/colors.js                              |    1 +
 dojo/nls/it/colors.js                              |    1 +
 dojo/nls/ja/colors.js                              |    1 +
 dojo/nls/kk/colors.js                              |    2 +-
 dojo/nls/ko/colors.js                              |    1 +
 dojo/nls/nb/colors.js                              |    1 +
 dojo/nls/nl/colors.js                              |    1 +
 dojo/nls/pl/colors.js                              |    1 +
 dojo/nls/pt/colors.js                              |    1 +
 dojo/nls/ro/colors.js                              |    1 +
 dojo/nls/ru/colors.js                              |    1 +
 dojo/nls/sk/colors.js                              |    1 +
 dojo/nls/sl/colors.js                              |    1 +
 dojo/nls/sv/colors.js                              |    1 +
 dojo/nls/th/colors.js                              |    1 +
 dojo/nls/tr/colors.js                              |    1 +
 dojo/nls/zh-tw/colors.js                           |    1 +
 dojo/nls/zh/colors.js                              |    1 +
 dojo/number.js                                     |   61 +-
 dojo/on.js                                         |  474 +
 dojo/package.json                                  |   42 +-
 dojo/parser.js                                     |  694 +-
 dojo/query.js                                      |  713 +
 dojo/ready.js                                      |  138 +
 dojo/regexp.js                                     |    9 +-
 dojo/require.js                                    |    7 +
 dojo/resources/dnd.css                             |    2 +-
 dojo/robot.js                                      |   28 +-
 dojo/robotx.js                                     |   28 +-
 dojo/rpc/JsonService.js                            |   12 +-
 dojo/rpc/JsonpService.js                           |    7 +-
 dojo/rpc/RpcService.js                             |   28 +-
 dojo/selector/_loader.js                           |   45 +
 dojo/selector/acme.js                              | 1480 +
 dojo/selector/lite.js                              |  264 +
 dojo/store/Cache.js                                |   50 +-
 dojo/store/DataStore.js                            |   66 +-
 dojo/store/JsonRest.js                             |   55 +-
 dojo/store/Memory.js                               |   68 +-
 dojo/store/Observable.js                           |   63 +-
 dojo/store/api/Store.js                            |  594 +-
 dojo/store/util/QueryResults.js                    |   24 +-
 dojo/store/util/SimpleQueryEngine.js               |   13 +-
 dojo/string.js                                     |   63 +-
 dojo/tests/AdapterRegistry.js                      |    5 +-
 dojo/tests/DeferredList.js                         |  133 +-
 dojo/tests/NodeList-data.html                      |  371 +-
 dojo/tests/NodeList-data.js                        |    9 +-
 dojo/tests/NodeList-fx.html                        |    8 +-
 dojo/tests/NodeList-manipulate.html                |  639 +-
 dojo/tests/NodeList-manipulate.js                  |    9 +-
 dojo/tests/NodeList-traverse.html                  |  237 +-
 dojo/tests/NodeList-traverse.js                    |    9 +-
 dojo/tests/Stateful.js                             |  100 +-
 dojo/tests/_base.js                                |  162 +-
 dojo/tests/_base/AMD-build-transform/t1.js         |   38 -
 dojo/tests/_base/AMD-build-transform/t2.js         |   14 -
 dojo/tests/_base/AMD-build-transform/t3.js         |    8 -
 dojo/tests/_base/AMD-build-transform/t4.js         |   13 -
 dojo/tests/_base/AMD-build-transform/t5.js         |   13 -
 dojo/tests/_base/Color.js                          |    8 +-
 dojo/tests/_base/Deferred.js                       |   88 +-
 dojo/tests/_base/NodeList.html                     |  295 +-
 dojo/tests/_base/_loader/afterOnLoad.html          |   71 -
 dojo/tests/_base/_loader/bootstrap.js              |  134 -
 dojo/tests/_base/_loader/config-data-global.html   |   31 -
 dojo/tests/_base/_loader/config-data.html          |   24 -
 dojo/tests/_base/_loader/config-dj-elemt.html      |   24 -
 dojo/tests/_base/_loader/config-dj-global.html     |   29 -
 dojo/tests/_base/_loader/debugConsole.html         |   51 -
 dojo/tests/_base/_loader/hostenv_browser.js        |   17 -
 dojo/tests/_base/_loader/hostenv_rhino.js          |   13 -
 dojo/tests/_base/_loader/hostenv_spidermonkey.js   |   11 -
 dojo/tests/_base/_loader/loader.js                 |  115 -
 dojo/tests/_base/_loader/modules.js                |   21 -
 dojo/tests/_base/_loader/modules/full.js           |    7 -
 dojo/tests/_base/_loader/modules/wrapped.js        |    4 -
 dojo/tests/_base/_loader/scope/scope04.html        |   80 -
 dojo/tests/_base/_loader/scope/scopeContained.html |   71 -
 .../_base/_loader/scope/scopeContainedXd.html      |   84 -
 dojo/tests/_base/_loader/scope/scopeDjConfig.html  |   64 -
 dojo/tests/_base/_loader/scope/scopeSingle.html    |   62 -
 .../tests/_base/_loader/scope/scopeSingleDaac.html |   63 -
 dojo/tests/_base/array.js                          |   17 +-
 dojo/tests/_base/connect.js                        |   37 +-
 dojo/tests/_base/connectLeaks.html                 |   93 +
 dojo/tests/_base/declare.js                        |   27 +-
 dojo/tests/_base/eventKeyPress.html                |   10 +-
 dojo/tests/_base/eventKeyPressRobot.html           |   80 +-
 dojo/tests/_base/eventMouse.html                   |  114 +
 dojo/tests/_base/eventMouseRobot.html              |  160 +
 dojo/tests/_base/fx.html                           |  858 +-
 dojo/tests/_base/fx.js                             |    9 +-
 dojo/tests/_base/html.html                         |  102 +-
 dojo/tests/_base/html.js                           |   25 +-
 dojo/tests/_base/html_box.html                     |   97 +-
 dojo/tests/_base/html_box_quirks.html              |   91 +-
 dojo/tests/_base/html_docScroll.html               |   41 +-
 dojo/tests/_base/html_element.html                 |   11 +-
 dojo/tests/_base/html_id.html                      |   10 +-
 dojo/tests/_base/html_isBodyLtr.html               |   18 +-
 dojo/tests/_base/html_quirks.html                  |    9 +-
 dojo/tests/_base/html_rtl.html                     |   62 +-
 dojo/tests/_base/json.js                           |   31 +-
 dojo/tests/_base/lang.js                           |    8 +-
 dojo/tests/_base/loader.js                         |  135 +
 dojo/tests/_base/{_loader => loader}/8976.html     |    0
 dojo/tests/_base/{_loader => loader}/a.js          |    0
 .../_base/{_loader => loader}/addLoadEvents.html   |    0
 dojo/tests/_base/loader/afterOnLoad.html           |   79 +
 dojo/tests/_base/loader/amdModule.js               |    5 +
 dojo/tests/_base/loader/amdModule1.js              |    5 +
 dojo/tests/_base/loader/amdModule2.js              |    5 +
 dojo/tests/_base/loader/amdModuleDep.js            |    5 +
 dojo/tests/_base/loader/amdModuleDep1.js           |    5 +
 dojo/tests/_base/loader/amdModuleDep2.js           |    5 +
 dojo/tests/_base/loader/asyncWithDojoRequire.html  |  103 +
 dojo/tests/_base/loader/bootstrap.js               |  157 +
 dojo/tests/_base/loader/cdnTest.html               |   74 +
 dojo/tests/_base/loader/cdnTest.js                 |   39 +
 dojo/tests/_base/loader/config-has.html            |   59 +
 dojo/tests/_base/loader/config-sniff-djConfig.html |   50 +
 dojo/tests/_base/loader/config-sniff.html          |   48 +
 dojo/tests/_base/loader/config.html                |  156 +
 dojo/tests/_base/loader/configApi.html             |   94 +
 dojo/tests/_base/loader/coolio/calendar-amd.js     |    7 +
 dojo/tests/_base/loader/coolio/calendar.js         |    6 +
 dojo/tests/_base/loader/coolio/calendar1.js        |    6 +
 dojo/tests/_base/loader/coolio/coolio-built.html   |   60 +
 .../_base/loader/coolio/coolio-dev-async.html      |   70 +
 .../loader/coolio/coolio-dev-legacy-async.html     |   83 +
 .../_base/loader/coolio/coolio-dev-legacy.html     |   46 +
 dojo/tests/_base/loader/coolio/coolio.js           |   17 +
 dojo/tests/_base/loader/coolio/coolio.profile.js   |   34 +
 dojo/tests/_base/loader/coolio/test.html           |   45 +
 dojo/tests/_base/loader/core.js                    |   18 +
 dojo/tests/_base/loader/debugConsole.html          |   47 +
 dojo/tests/_base/loader/declareStepsOnProvide.html |   24 +
 dojo/tests/_base/loader/declareStepsOnProvide.js   |   14 +
 .../tests/_base/loader/declareStepsOnProvideAmd.js |    3 +
 .../_base/{_loader => loader}/fastbackTest.html    |    0
 dojo/tests/_base/{_loader => loader}/getText.txt   |    0
 dojo/tests/_base/loader/hostenv_rhino.js           |   13 +
 dojo/tests/_base/loader/hostenv_spidermonkey.js    |   11 +
 dojo/tests/_base/loader/moduleIds.js               |  210 +
 dojo/tests/_base/loader/modulePaths.html           |   37 +
 dojo/tests/_base/loader/modules.js                 |   24 +
 .../_base/{_loader => loader}/modules/anon.js      |    0
 .../_base/{_loader => loader}/modules/data.js      |    0
 .../{_loader => loader}/modules/factoryArity.js    |    0
 dojo/tests/_base/loader/modules/full.js            |    5 +
 dojo/tests/_base/loader/modules/wrapped.js         |   15 +
 dojo/tests/_base/loader/myTopLevelModule.js        |    3 +
 .../_base/loader/myTopLevelModule/myModule.js      |    2 +
 dojo/tests/_base/loader/nls/ab-cd-ef/amdBundle.js  |    3 +
 dojo/tests/_base/loader/nls/ab-cd-ef/syncBundle.js |    3 +
 dojo/tests/_base/loader/nls/ab/amdBundle.js        |    3 +
 dojo/tests/_base/loader/nls/ab/syncBundle.js       |    3 +
 dojo/tests/_base/loader/nls/amdBundle.js           |    7 +
 dojo/tests/_base/loader/nls/syncBundle.js          |    3 +
 dojo/tests/_base/loader/package.html               |   11 +
 dojo/tests/_base/loader/paths.html                 |   52 +
 dojo/tests/_base/loader/pub1.js                    |    3 +
 dojo/tests/_base/loader/pub2.js                    |    3 +
 dojo/tests/_base/loader/publishRequireResult.html  |   34 +
 dojo/tests/_base/loader/ready.html                 |   32 +
 dojo/tests/_base/loader/requirejs/bar              |    5 +
 .../tests/_base/loader/requirejs/circular-tests.js |   29 +
 dojo/tests/_base/loader/requirejs/circular.html    |   13 +
 dojo/tests/_base/loader/requirejs/config.html      |   41 +
 dojo/tests/_base/loader/requirejs/dataMain.html    |   12 +
 dojo/tests/_base/loader/requirejs/dataMain.js      |   16 +
 dojo/tests/_base/loader/requirejs/depoverlap.html  |   14 +
 dojo/tests/_base/loader/requirejs/depoverlap.js    |   35 +
 dojo/tests/_base/loader/requirejs/dimple.js        |    5 +
 dojo/tests/_base/loader/requirejs/dos.js           |   13 +
 .../tests/_base/loader/requirejs/exports/assign.js |    5 +
 .../_base/loader/requirejs/exports/assign2.js      |    4 +
 .../loader/requirejs/exports/exports-tests.js      |   24 +
 .../_base/loader/requirejs/exports/exports.html    |   18 +
 .../_base/loader/requirejs/exports/funcSet.js      |    5 +
 .../loader/requirejs/exports/implicitModule.js     |    7 +
 .../_base/loader/requirejs/exports/simpleReturn.js |   10 +
 .../_base/loader/requirejs/exports/usethis.js      |    3 +
 .../_base/loader/requirejs/exports/vanilla.js      |    5 +
 dojo/tests/_base/loader/requirejs/foo              |    5 +
 dojo/tests/_base/loader/requirejs/func.js          |    7 +
 dojo/tests/_base/loader/requirejs/funcFour.js      |   14 +
 dojo/tests/_base/loader/requirejs/funcOne.js       |   15 +
 dojo/tests/_base/loader/requirejs/funcThree.js     |   14 +
 dojo/tests/_base/loader/requirejs/funcTwo.js       |   15 +
 dojo/tests/_base/loader/requirejs/i18n/common.html |   53 +
 dojo/tests/_base/loader/requirejs/i18n/commonA.js  |    3 +
 dojo/tests/_base/loader/requirejs/i18n/commonB.js  |    3 +
 dojo/tests/_base/loader/requirejs/i18n/i18n.html   |   62 +
 dojo/tests/_base/loader/requirejs/i18n/i18n.js     |    4 +
 .../_base/loader/requirejs/i18n/nls/colors.js      |    9 +
 .../requirejs/i18n/nls/en-us-surfer/colors.js      |    3 +
 .../_base/loader/requirejs/i18n/nls/fr/colors.js   |    4 +
 .../_base/loader/requirejs/i18n/testModule.js      |    4 +
 .../loader/requirejs/layers/allplugins-text.html   |   33 +
 dojo/tests/_base/loader/requirejs/layers/build.sh  |    1 +
 .../tests/_base/loader/requirejs/layers/epsilon.js |    5 +
 .../_base/loader/requirejs/layers/helloWorld.txt   |    1 +
 dojo/tests/_base/loader/requirejs/layers/layer1.js |   31 +
 .../_base/loader/requirejs/layers/layers.html      |   67 +
 dojo/tests/_base/loader/requirejs/map.js           |    7 +
 dojo/tests/_base/loader/requirejs/one.js           |   13 +
 .../_base/loader/requirejs/paths/first.js/first.js |    8 +
 .../loader/requirejs/paths/first.js/second.js      |    8 +
 dojo/tests/_base/loader/requirejs/paths/paths.html |   59 +
 .../loader/requirejs/relative/foo/bar/message.txt  |    1 +
 .../_base/loader/requirejs/relative/foo/bar/one.js |   10 +
 .../_base/loader/requirejs/relative/foo/bar/two.js |    3 +
 .../_base/loader/requirejs/relative/foo/three.js   |    3 +
 .../loader/requirejs/relative/relative-tests.js    |   23 +
 .../_base/loader/requirejs/relative/relative.html  |   22 +
 .../_base/loader/requirejs/requirejs-setup.js      |   32 +
 .../_base/loader/requirejs/simple-badbase.html     |   55 +
 .../_base/loader/requirejs/simple-nohead.html      |   24 +
 dojo/tests/_base/loader/requirejs/simple-tests.js  |   23 +
 dojo/tests/_base/loader/requirejs/simple.html      |   35 +
 dojo/tests/_base/loader/requirejs/simple.js        |    7 +
 dojo/tests/_base/loader/requirejs/text/local.js    |    5 +
 .../loader/requirejs/text/resources/local.html     |    1 +
 .../loader/requirejs/text/resources/sample.html    |    8 +
 .../_base/loader/requirejs/text/subwidget.html     |    8 +
 .../tests/_base/loader/requirejs/text/subwidget.js |   10 +
 .../_base/loader/requirejs/text/subwidget2.html    |    1 +
 dojo/tests/_base/loader/requirejs/text/text.html   |   58 +
 .../_base/loader/requirejs/text/textOnly.html      |   42 +
 dojo/tests/_base/loader/requirejs/text/widget.html |    1 +
 dojo/tests/_base/loader/requirejs/text/widget.js   |   11 +
 dojo/tests/_base/loader/requirejs/tres.js          |    7 +
 dojo/tests/_base/loader/requirejs/two.js           |   12 +
 dojo/tests/_base/loader/requirejs/uniques/one.js   |    8 +
 dojo/tests/_base/loader/requirejs/uniques/three.js |    3 +
 dojo/tests/_base/loader/requirejs/uniques/two.js   |    8 +
 .../_base/loader/requirejs/uniques/uniques.html    |   43 +
 dojo/tests/_base/loader/requirejs/uno.js           |   14 +
 dojo/tests/_base/loader/requirejs/urlfetch/one.js  |    3 +
 .../tests/_base/loader/requirejs/urlfetch/three.js |   10 +
 dojo/tests/_base/loader/requirejs/urlfetch/two.js  |   10 +
 .../_base/loader/requirejs/urlfetch/urlfetch.html  |   69 +
 dojo/tests/_base/loader/scope04.html               |   80 +
 dojo/tests/_base/loader/syncFromAsyncModule.js     |    4 +
 dojo/tests/_base/loader/syncFromAsyncModuleDep.js  |    2 +
 dojo/tests/_base/loader/syncModule.js              |    9 +
 dojo/tests/_base/loader/syncModule1.js             |    5 +
 dojo/tests/_base/loader/syncModule2.js             |    5 +
 dojo/tests/_base/loader/syncModuleDep.js           |    4 +
 dojo/tests/_base/loader/syncModuleDep1.js          |    4 +
 dojo/tests/_base/loader/syncModuleDep2.js          |    4 +
 dojo/tests/_base/loader/traceApi.html              |   21 +
 .../_base/loader/xdomain/local1-browser-skip.js    |    1 +
 dojo/tests/_base/loader/xdomain/local1-browser.js  |    4 +
 dojo/tests/_base/loader/xdomain/local1-dep.js      |    4 +
 .../loader/xdomain/local1-runtimeDependent1.js     |    4 +
 dojo/tests/_base/loader/xdomain/local1.js          |   82 +
 dojo/tests/_base/loader/xdomain/local2.js          |   13 +
 dojo/tests/_base/loader/xdomain/local3.js          |   10 +
 dojo/tests/_base/loader/xdomain/xdomain.html       |  290 +
 dojo/tests/_base/object.js                         |   14 +-
 dojo/tests/_base/query.html                        |  122 +-
 dojo/tests/_base/query.js                          |   11 +-
 dojo/tests/_base/scrollingIframe.js                |   11 +-
 dojo/tests/_base/timeout.php                       |    2 +-
 dojo/tests/_base/window.html                       |  104 +
 dojo/tests/_base/window.js                         |   57 +-
 dojo/tests/_base/window_iframe_quirks.html         |   11 +
 dojo/tests/_base/window_iframe_standards.html      |   15 +
 dojo/tests/_base/xhr.html                          |   15 +-
 dojo/tests/_base/xhr.js                            |    9 +-
 dojo/tests/amd/backCompat.js                       |  118 -
 dojo/tests/amd/main.js                             |   26 -
 dojo/tests/amd/smoke-bdLoad.html                   |   42 -
 dojo/tests/amd/smoke-requirejs.html                |   46 -
 dojo/tests/amd/smoke.txt                           |    1 -
 dojo/tests/amd/text.html                           |    1 -
 dojo/tests/aspect.js                               |  119 +
 dojo/tests/back-hash.js                            |   10 +-
 dojo/tests/back.html                               |   19 +-
 dojo/tests/back.js                                 |    9 +-
 dojo/tests/baseonly.js                             |    8 +-
 dojo/tests/behavior.html                           |   94 +-
 dojo/tests/behavior.js                             |    9 +-
 dojo/tests/cache.js                                |   18 +-
 dojo/tests/cldr.js                                 |   14 +-
 dojo/tests/colors.js                               |   76 +-
 dojo/tests/cookie.html                             |  132 +-
 dojo/tests/cookie.js                               |    9 +-
 dojo/tests/currency.js                             |   78 +-
 dojo/tests/data.js                                 |    9 +-
 dojo/tests/data/ItemFileReadStore.js               |    7 +-
 dojo/tests/data/ItemFileWriteStore.js              |  102 +-
 dojo/tests/data/ObjectStore.js                     |   17 +-
 dojo/tests/data/readOnlyItemFileTestTemplates.js   |  192 +-
 dojo/tests/data/utils.js                           |    8 +-
 dojo/tests/date.js                                 |  208 +-
 dojo/tests/date/locale.js                          |   44 +-
 dojo/tests/date/stamp.js                           |    2 +-
 dojo/tests/dnd/flickr_viewer.html                  |    2 +
 dojo/tests/dnd/test_box_constraints.html           |    2 +
 dojo/tests/dnd/test_container.html                 |    4 +-
 dojo/tests/dnd/test_container_markup.html          |    2 +
 dojo/tests/dnd/test_custom_constraints.html        |    2 +
 dojo/tests/dnd/test_dnd.html                       |    6 +-
 dojo/tests/dnd/test_dnd_handles.html               |    4 +-
 dojo/tests/dnd/test_form.html                      |   19 +-
 dojo/tests/dnd/test_moveable.html                  |   14 +-
 dojo/tests/dnd/test_moveable_markup.html           |    2 +
 dojo/tests/dnd/test_params.html                    |    2 +
 dojo/tests/dnd/test_parent_constraints.html        |    2 +
 .../tests/dnd/test_parent_constraints_margins.html |    2 +
 dojo/tests/dnd/test_selector.html                  |    4 +-
 dojo/tests/dnd/test_selector_markup.html           |    2 +
 dojo/tests/dnd/test_timed_moveable.html            |    2 +
 dojo/tests/fx.html                                 |   58 +-
 dojo/tests/fx.js                                   |   12 +-
 dojo/tests/hash.js                                 |   19 +-
 dojo/tests/html.js                                 |    9 +-
 dojo/tests/html/test_set.html                      |   13 +-
 dojo/tests/i18n.html                               |   71 +
 dojo/tests/i18n.js                                 |  180 +-
 dojo/tests/io/iframe.html                          |  264 +-
 dojo/tests/io/iframe.js                            |    9 +-
 dojo/tests/io/script.html                          |  187 +-
 dojo/tests/io/script.js                            |    9 +-
 dojo/tests/json.js                                 |  166 +
 dojo/tests/module.js                               |   73 +-
 dojo/tests/number.js                               |  135 +-
 dojo/tests/on.js                                   |  229 +
 dojo/tests/parser.html                             |  790 +-
 dojo/tests/parser.js                               |    9 +-
 dojo/tests/regexp.js                               |   11 +-
 dojo/tests/resources/ApplicationState.js           |   10 +-
 dojo/tests/rpc.js                                  |   25 +-
 dojo/tests/runTests.html                           |    2 +-
 dojo/tests/sie/all.js                              |   22 -
 dojo/tests/sie/smoke-v15.html                      |   29 -
 dojo/tests/sie/smoke.html                          |   31 -
 dojo/tests/store.js                                |    8 +-
 dojo/tests/store/DataStore.js                      |   38 +-
 dojo/tests/store/JsonRest.js                       |   10 +-
 dojo/tests/store/Memory.js                         |    7 +-
 dojo/tests/store/Observable.js                     |   15 +-
 dojo/tests/string.js                               |   16 +-
 dojo/tests/test_FirebugLite.html                   |   33 +-
 dojo/tests/test_FirebugLitePopup.html              |   33 +-
 dojo/tests/test_fx.html                            |    9 +-
 dojo/tests/test_touch.html                         |  144 +
 dojo/tests/touch.js                                |    6 +
 dojo/tests/uacss.js                                |   13 +-
 dojo/tests/uacss/sniffQuirks.html                  |   11 +-
 dojo/tests/uacss/sniffStandards.html               |   10 +-
 dojo/tests/window.js                               |   16 +-
 dojo/tests/window/test_scroll.html                 |   93 +-
 dojo/tests/window/viewport.html                    |   53 +-
 dojo/text.js                                       |  212 +
 dojo/topic.js                                      |   33 +
 dojo/touch.js                                      |   89 +
 dojo/uacss.js                                      |   67 +-
 dojo/window.js                                     |   79 +-
 dojox/NodeList/README                              |    2 +-
 dojox/NodeList/delegate.js                         |   17 +-
 dojox/NodeList/tests/delegate-async.html           |   72 +
 dojox/analytics.js                                 |    6 +-
 dojox/analytics/Urchin.js                          |  247 +-
 dojox/analytics/_base.js                           |  236 +-
 dojox/analytics/plugins/consoleMessages.js         |   39 +-
 dojox/analytics/plugins/dojo.js                    |   40 +-
 dojox/analytics/plugins/idle.js                    |   61 +-
 dojox/analytics/plugins/mouseClick.js              |   81 +-
 dojox/analytics/plugins/mouseOver.js               |  155 +-
 dojox/analytics/plugins/window.js                  |   58 +-
 dojox/analytics/tests/test_GoogleAnalytics.html    |    2 -
 .../tests/test_GoogleAnalyticsMarkup.html          |    3 +-
 dojox/analytics/tests/test_analytics-async.html    |  121 +
 dojox/analytics/tests/test_analytics.html          |    9 +-
 dojox/app/README.txt                               |  174 +
 dojox/app/animation.js                             |  346 +
 dojox/app/bind.js                                  |   39 +
 dojox/app/main.js                                  |  115 +
 dojox/app/model.js                                 |   26 +
 dojox/app/module/env.js                            |   21 +
 dojox/app/module/history.js                        |   90 +
 dojox/app/module/lifecycle.js                      |   26 +
 dojox/app/scene.js                                 |  588 +
 dojox/app/schema/README                            |    1 +
 dojox/app/schema/application.json                  |   55 +
 dojox/app/schema/model.json                        |   11 +
 dojox/app/schema/scene.json                        |   29 +
 dojox/app/schema/store.json                        |   11 +
 dojox/app/schema/view.json                         |   30 +
 dojox/app/tests/images/a-icon-1-41x41.png          |  Bin 0 -> 3886 bytes
 dojox/app/tests/images/a-icon-1.png                |  Bin 0 -> 550 bytes
 dojox/app/tests/images/a-icon-10.png               |  Bin 0 -> 332 bytes
 dojox/app/tests/images/a-icon-11.png               |  Bin 0 -> 343 bytes
 dojox/app/tests/images/a-icon-12.png               |  Bin 0 -> 613 bytes
 dojox/app/tests/images/a-icon-13.png               |  Bin 0 -> 278 bytes
 dojox/app/tests/images/a-icon-14.png               |  Bin 0 -> 612 bytes
 dojox/app/tests/images/a-icon-15.png               |  Bin 0 -> 765 bytes
 dojox/app/tests/images/a-icon-16.png               |  Bin 0 -> 597 bytes
 dojox/app/tests/images/a-icon-17.png               |  Bin 0 -> 942 bytes
 dojox/app/tests/images/a-icon-18.png               |  Bin 0 -> 832 bytes
 dojox/app/tests/images/a-icon-2-41x41.png          |  Bin 0 -> 923 bytes
 dojox/app/tests/images/a-icon-2.png                |  Bin 0 -> 644 bytes
 dojox/app/tests/images/a-icon-3.png                |  Bin 0 -> 1509 bytes
 dojox/app/tests/images/a-icon-4.png                |  Bin 0 -> 695 bytes
 dojox/app/tests/images/b-app-icon-1.png            |  Bin 0 -> 1296 bytes
 dojox/app/tests/images/b-app-icon-2.png            |  Bin 0 -> 1325 bytes
 dojox/app/tests/images/b-app-icon-3.png            |  Bin 0 -> 1306 bytes
 dojox/app/tests/images/b-app-icon-4.png            |  Bin 0 -> 1301 bytes
 dojox/app/tests/images/b-app-icon-5.png            |  Bin 0 -> 1288 bytes
 dojox/app/tests/images/b-app-icon-6.png            |  Bin 0 -> 1323 bytes
 dojox/app/tests/images/b-app-icon-7.png            |  Bin 0 -> 1299 bytes
 dojox/app/tests/images/b-app-icon-8.png            |  Bin 0 -> 1315 bytes
 dojox/app/tests/images/b-icon-1.png                |  Bin 0 -> 933 bytes
 dojox/app/tests/images/b-icon-2.png                |  Bin 0 -> 936 bytes
 dojox/app/tests/images/b-icon-3.png                |  Bin 0 -> 934 bytes
 dojox/app/tests/images/b-icon-4.png                |  Bin 0 -> 926 bytes
 dojox/app/tests/images/b-icon-5.png                |  Bin 0 -> 948 bytes
 dojox/app/tests/images/b-icon-6.png                |  Bin 0 -> 946 bytes
 dojox/app/tests/images/b-icon-7.png                |  Bin 0 -> 915 bytes
 dojox/app/tests/images/b-icon-8.png                |  Bin 0 -> 960 bytes
 dojox/app/tests/images/chart.png                   |  Bin 0 -> 17937 bytes
 .../app/tests/images/checkboxRadioButtonStates.png |  Bin 0 -> 3438 bytes
 dojox/app/tests/images/dish1.jpg                   |  Bin 0 -> 6043 bytes
 dojox/app/tests/images/dish2.jpg                   |  Bin 0 -> 4532 bytes
 dojox/app/tests/images/dish3.jpg                   |  Bin 0 -> 4853 bytes
 dojox/app/tests/images/dish4.jpg                   |  Bin 0 -> 5655 bytes
 dojox/app/tests/images/dish5.jpg                   |  Bin 0 -> 3350 bytes
 dojox/app/tests/images/dish6.jpg                   |  Bin 0 -> 5542 bytes
 dojox/app/tests/images/dish7.jpg                   |  Bin 0 -> 4302 bytes
 dojox/app/tests/images/dish8.jpg                   |  Bin 0 -> 5550 bytes
 dojox/app/tests/images/dish9.jpg                   |  Bin 0 -> 3867 bytes
 dojox/app/tests/images/glass1.jpg                  |  Bin 0 -> 8903 bytes
 dojox/app/tests/images/glass10.jpg                 |  Bin 0 -> 5881 bytes
 dojox/app/tests/images/glass11.jpg                 |  Bin 0 -> 4192 bytes
 dojox/app/tests/images/glass12.jpg                 |  Bin 0 -> 4299 bytes
 dojox/app/tests/images/glass13.jpg                 |  Bin 0 -> 5958 bytes
 dojox/app/tests/images/glass14.jpg                 |  Bin 0 -> 4522 bytes
 dojox/app/tests/images/glass15.jpg                 |  Bin 0 -> 6524 bytes
 dojox/app/tests/images/glass16.jpg                 |  Bin 0 -> 7113 bytes
 dojox/app/tests/images/glass2.jpg                  |  Bin 0 -> 6121 bytes
 dojox/app/tests/images/glass3.jpg                  |  Bin 0 -> 7914 bytes
 dojox/app/tests/images/glass4.jpg                  |  Bin 0 -> 3703 bytes
 dojox/app/tests/images/glass5.jpg                  |  Bin 0 -> 7167 bytes
 dojox/app/tests/images/glass6.jpg                  |  Bin 0 -> 4836 bytes
 dojox/app/tests/images/glass7.jpg                  |  Bin 0 -> 6716 bytes
 dojox/app/tests/images/glass8.jpg                  |  Bin 0 -> 6203 bytes
 dojox/app/tests/images/glass9.jpg                  |  Bin 0 -> 4452 bytes
 dojox/app/tests/images/i-icon-1.png                |  Bin 0 -> 677 bytes
 dojox/app/tests/images/i-icon-10.png               |  Bin 0 -> 689 bytes
 dojox/app/tests/images/i-icon-2.png                |  Bin 0 -> 680 bytes
 dojox/app/tests/images/i-icon-3.png                |  Bin 0 -> 682 bytes
 dojox/app/tests/images/i-icon-4.png                |  Bin 0 -> 697 bytes
 dojox/app/tests/images/i-icon-5.png                |  Bin 0 -> 693 bytes
 dojox/app/tests/images/i-icon-6.png                |  Bin 0 -> 694 bytes
 dojox/app/tests/images/i-icon-7.png                |  Bin 0 -> 691 bytes
 dojox/app/tests/images/i-icon-8.png                |  Bin 0 -> 695 bytes
 dojox/app/tests/images/i-icon-9.png                |  Bin 0 -> 689 bytes
 dojox/app/tests/images/i-icon-all.png              |  Bin 0 -> 4450 bytes
 dojox/app/tests/images/icon-1.png                  |  Bin 0 -> 2626 bytes
 dojox/app/tests/images/not-images.png              |  Bin 0 -> 18459 bytes
 dojox/app/tests/images/pic1.jpg                    |  Bin 0 -> 267196 bytes
 dojox/app/tests/images/pic10.jpg                   |  Bin 0 -> 270933 bytes
 dojox/app/tests/images/pic2.jpg                    |  Bin 0 -> 255957 bytes
 dojox/app/tests/images/pic3.jpg                    |  Bin 0 -> 260893 bytes
 dojox/app/tests/images/pic4.jpg                    |  Bin 0 -> 262508 bytes
 dojox/app/tests/images/pic5.jpg                    |  Bin 0 -> 307923 bytes
 dojox/app/tests/images/pic6.jpg                    |  Bin 0 -> 254583 bytes
 dojox/app/tests/images/pic7.jpg                    |  Bin 0 -> 323165 bytes
 dojox/app/tests/images/pic8.jpg                    |  Bin 0 -> 296657 bytes
 dojox/app/tests/images/pic9.jpg                    |  Bin 0 -> 277204 bytes
 dojox/app/tests/images/red-button-bg.png           |  Bin 0 -> 178 bytes
 dojox/app/tests/images/red-button-sel-bg.png       |  Bin 0 -> 185 bytes
 dojox/app/tests/images/shell1.jpg                  |  Bin 0 -> 8172 bytes
 dojox/app/tests/images/shell10.jpg                 |  Bin 0 -> 3071 bytes
 dojox/app/tests/images/shell11.jpg                 |  Bin 0 -> 4010 bytes
 dojox/app/tests/images/shell2.jpg                  |  Bin 0 -> 3075 bytes
 dojox/app/tests/images/shell3.jpg                  |  Bin 0 -> 3006 bytes
 dojox/app/tests/images/shell4.jpg                  |  Bin 0 -> 5282 bytes
 dojox/app/tests/images/shell5.jpg                  |  Bin 0 -> 4584 bytes
 dojox/app/tests/images/shell6.jpg                  |  Bin 0 -> 5445 bytes
 dojox/app/tests/images/shell7.jpg                  |  Bin 0 -> 5113 bytes
 dojox/app/tests/images/shell8.jpg                  |  Bin 0 -> 6273 bytes
 dojox/app/tests/images/shell9.jpg                  |  Bin 0 -> 8676 bytes
 dojox/app/tests/images/stone1.jpg                  |  Bin 0 -> 7537 bytes
 dojox/app/tests/images/stone10.jpg                 |  Bin 0 -> 6310 bytes
 dojox/app/tests/images/stone2.jpg                  |  Bin 0 -> 3830 bytes
 dojox/app/tests/images/stone3.jpg                  |  Bin 0 -> 5431 bytes
 dojox/app/tests/images/stone4.jpg                  |  Bin 0 -> 4616 bytes
 dojox/app/tests/images/stone5.jpg                  |  Bin 0 -> 6573 bytes
 dojox/app/tests/images/stone6.jpg                  |  Bin 0 -> 3869 bytes
 dojox/app/tests/images/stone7.jpg                  |  Bin 0 -> 6667 bytes
 dojox/app/tests/images/stone8.jpg                  |  Bin 0 -> 3109 bytes
 dojox/app/tests/images/stone9.jpg                  |  Bin 0 -> 2578 bytes
 dojox/app/tests/images/tab-icon-10.png             |  Bin 0 -> 349 bytes
 dojox/app/tests/images/tab-icon-10h.png            |  Bin 0 -> 369 bytes
 dojox/app/tests/images/tab-icon-11.png             |  Bin 0 -> 343 bytes
 dojox/app/tests/images/tab-icon-11h.png            |  Bin 0 -> 366 bytes
 dojox/app/tests/images/tab-icon-12.png             |  Bin 0 -> 622 bytes
 dojox/app/tests/images/tab-icon-12h.png            |  Bin 0 -> 623 bytes
 dojox/app/tests/images/tab-icon-13.png             |  Bin 0 -> 277 bytes
 dojox/app/tests/images/tab-icon-13h.png            |  Bin 0 -> 299 bytes
 dojox/app/tests/images/tab-icon-14.png             |  Bin 0 -> 623 bytes
 dojox/app/tests/images/tab-icon-14h.png            |  Bin 0 -> 652 bytes
 dojox/app/tests/images/tab-icon-15.png             |  Bin 0 -> 765 bytes
 dojox/app/tests/images/tab-icon-15h.png            |  Bin 0 -> 777 bytes
 dojox/app/tests/images/tab-icon-16.png             |  Bin 0 -> 597 bytes
 dojox/app/tests/images/tab-icon-16h.png            |  Bin 0 -> 600 bytes
 dojox/app/tests/images/tab-icon-17.png             |  Bin 0 -> 967 bytes
 dojox/app/tests/images/tab-icon-17h.png            |  Bin 0 -> 959 bytes
 dojox/app/tests/images/tab-icon-18.png             |  Bin 0 -> 827 bytes
 dojox/app/tests/images/tab-icon-18h.png            |  Bin 0 -> 834 bytes
 dojox/app/tests/images/tab-icons.png               |  Bin 0 -> 4215 bytes
 dojox/app/tests/images/welcomeLogo.png             |  Bin 0 -> 28567 bytes
 dojox/app/tests/images/widget-bg.png               |  Bin 0 -> 26234 bytes
 dojox/app/tests/modelApp/config.json               |   97 +
 dojox/app/tests/modelApp/index.html                |   60 +
 dojox/app/tests/modelApp/modelApp.js               |   98 +
 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     |    7 +
 dojox/app/tests/multiSceneApp/config.json          |  167 +
 dojox/app/tests/multiSceneApp/gallery.html         |    3 +
 dojox/app/tests/multiSceneApp/index.html           |   77 +
 dojox/app/tests/multiSceneApp/multiSceneApp.js     |   15 +
 dojox/app/tests/multiSceneApp/simple.html          |    3 +
 dojox/app/tests/multiSceneApp/tabScene.html        |    8 +
 .../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/home.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/multiSceneApp/views/tabs/tab1.html |    5 +
 dojox/app/tests/multiSceneApp/views/tabs/tab2.html |    5 +
 dojox/app/tests/multiSceneApp/views/tabs/tab3.html |    5 +
 dojox/app/transition.js                            |   60 +
 dojox/app/view.js                                  |   15 +
 dojox/atom/README                                  |    4 +-
 dojox/atom/io/Connection.js                        |   38 +-
 dojox/atom/io/model.js                             |  201 +-
 dojox/atom/widget/FeedEntryEditor.js               |  208 +-
 dojox/atom/widget/FeedEntryViewer.js               |  163 +-
 dojox/atom/widget/FeedViewer.js                    |   93 +-
 dojox/atom/widget/nls/FeedEntryEditor.js           |   38 +-
 dojox/atom/widget/nls/FeedEntryViewer.js           |   38 +-
 dojox/atom/widget/nls/FeedViewerEntry.js           |   38 +-
 dojox/atom/widget/nls/PeopleEditor.js              |   38 +-
 dojox/atom/widget/nls/ar/FeedEntryEditor.js        |    4 +
 dojox/atom/widget/nls/ar/FeedEntryViewer.js        |    4 +
 dojox/atom/widget/nls/ar/FeedViewerEntry.js        |    4 +
 dojox/atom/widget/nls/ar/PeopleEditor.js           |    5 +-
 dojox/atom/widget/nls/az/FeedEntryEditor.js        |   10 +
 dojox/atom/widget/nls/az/FeedEntryViewer.js        |   15 +
 dojox/atom/widget/nls/az/FeedViewerEntry.js        |    7 +
 dojox/atom/widget/nls/az/PeopleEditor.js           |    9 +
 dojox/atom/widget/nls/ca/FeedEntryEditor.js        |    5 +-
 dojox/atom/widget/nls/ca/FeedEntryViewer.js        |    5 +-
 dojox/atom/widget/nls/ca/FeedViewerEntry.js        |    5 +-
 dojox/atom/widget/nls/ca/PeopleEditor.js           |    5 +-
 dojox/atom/widget/nls/cs/FeedEntryEditor.js        |    6 +-
 dojox/atom/widget/nls/cs/FeedEntryViewer.js        |    6 +-
 dojox/atom/widget/nls/cs/FeedViewerEntry.js        |    6 +-
 dojox/atom/widget/nls/cs/PeopleEditor.js           |    6 +-
 dojox/atom/widget/nls/da/FeedEntryEditor.js        |    4 +
 dojox/atom/widget/nls/da/FeedEntryViewer.js        |    5 +-
 dojox/atom/widget/nls/da/FeedViewerEntry.js        |    4 +
 dojox/atom/widget/nls/da/PeopleEditor.js           |    4 +
 dojox/atom/widget/nls/de/FeedEntryEditor.js        |    6 +-
 dojox/atom/widget/nls/de/FeedEntryViewer.js        |    6 +-
 dojox/atom/widget/nls/de/FeedViewerEntry.js        |    6 +-
 dojox/atom/widget/nls/de/PeopleEditor.js           |    6 +-
 dojox/atom/widget/nls/el/FeedEntryEditor.js        |    4 +
 dojox/atom/widget/nls/el/FeedEntryViewer.js        |    4 +
 dojox/atom/widget/nls/el/FeedViewerEntry.js        |    4 +
 dojox/atom/widget/nls/el/PeopleEditor.js           |    4 +
 dojox/atom/widget/nls/es/FeedEntryEditor.js        |    6 +-
 dojox/atom/widget/nls/es/FeedEntryViewer.js        |    6 +-
 dojox/atom/widget/nls/es/FeedViewerEntry.js        |    6 +-
 dojox/atom/widget/nls/es/PeopleEditor.js           |    6 +-
 dojox/atom/widget/nls/fi/FeedEntryEditor.js        |    4 +
 dojox/atom/widget/nls/fi/FeedEntryViewer.js        |    5 +-
 dojox/atom/widget/nls/fi/FeedViewerEntry.js        |    4 +
 dojox/atom/widget/nls/fi/PeopleEditor.js           |    5 +-
 dojox/atom/widget/nls/fr/FeedEntryEditor.js        |    6 +-
 dojox/atom/widget/nls/fr/FeedEntryViewer.js        |    6 +-
 dojox/atom/widget/nls/fr/FeedViewerEntry.js        |    6 +-
 dojox/atom/widget/nls/fr/PeopleEditor.js           |    6 +-
 dojox/atom/widget/nls/he/FeedEntryEditor.js        |    4 +
 dojox/atom/widget/nls/he/FeedEntryViewer.js        |    5 +-
 dojox/atom/widget/nls/he/FeedViewerEntry.js        |    4 +
 dojox/atom/widget/nls/he/PeopleEditor.js           |    4 +
 dojox/atom/widget/nls/hr/FeedEntryEditor.js        |    8 +
 dojox/atom/widget/nls/hr/FeedEntryViewer.js        |   13 +
 dojox/atom/widget/nls/hr/FeedViewerEntry.js        |    5 +
 dojox/atom/widget/nls/hr/PeopleEditor.js           |    7 +
 dojox/atom/widget/nls/hu/FeedEntryEditor.js        |    6 +-
 dojox/atom/widget/nls/hu/FeedEntryViewer.js        |    6 +-
 dojox/atom/widget/nls/hu/FeedViewerEntry.js        |    6 +-
 dojox/atom/widget/nls/hu/PeopleEditor.js           |    6 +-
 dojox/atom/widget/nls/it/FeedEntryEditor.js        |    6 +-
 dojox/atom/widget/nls/it/FeedEntryViewer.js        |    6 +-
 dojox/atom/widget/nls/it/FeedViewerEntry.js        |    6 +-
 dojox/atom/widget/nls/it/PeopleEditor.js           |    6 +-
 dojox/atom/widget/nls/ja/FeedEntryEditor.js        |    6 +-
 dojox/atom/widget/nls/ja/FeedEntryViewer.js        |    6 +-
 dojox/atom/widget/nls/ja/FeedViewerEntry.js        |    6 +-
 dojox/atom/widget/nls/ja/PeopleEditor.js           |    6 +-
 dojox/atom/widget/nls/kk/FeedEntryEditor.js        |    5 +-
 dojox/atom/widget/nls/kk/FeedEntryViewer.js        |    5 +-
 dojox/atom/widget/nls/kk/FeedViewerEntry.js        |    5 +-
 dojox/atom/widget/nls/kk/PeopleEditor.js           |    5 +-
 dojox/atom/widget/nls/ko/FeedEntryEditor.js        |    6 +-
 dojox/atom/widget/nls/ko/FeedEntryViewer.js        |    4 +
 dojox/atom/widget/nls/ko/FeedViewerEntry.js        |    6 +-
 dojox/atom/widget/nls/ko/PeopleEditor.js           |    6 +-
 dojox/atom/widget/nls/nb/FeedEntryEditor.js        |    4 +
 dojox/atom/widget/nls/nb/FeedEntryViewer.js        |    4 +
 dojox/atom/widget/nls/nb/FeedViewerEntry.js        |    4 +
 dojox/atom/widget/nls/nb/PeopleEditor.js           |    4 +
 dojox/atom/widget/nls/nl/FeedEntryEditor.js        |    4 +
 dojox/atom/widget/nls/nl/FeedEntryViewer.js        |    4 +
 dojox/atom/widget/nls/nl/FeedViewerEntry.js        |    4 +
 dojox/atom/widget/nls/nl/PeopleEditor.js           |    4 +
 dojox/atom/widget/nls/pl/FeedEntryEditor.js        |    5 +-
 dojox/atom/widget/nls/pl/FeedEntryViewer.js        |    5 +-
 dojox/atom/widget/nls/pl/FeedViewerEntry.js        |    6 +-
 dojox/atom/widget/nls/pl/PeopleEditor.js           |    6 +-
 dojox/atom/widget/nls/pt-pt/FeedEntryEditor.js     |    4 +
 dojox/atom/widget/nls/pt-pt/FeedEntryViewer.js     |    4 +
 dojox/atom/widget/nls/pt-pt/FeedViewerEntry.js     |    4 +
 dojox/atom/widget/nls/pt-pt/PeopleEditor.js        |    4 +
 dojox/atom/widget/nls/pt/FeedEntryEditor.js        |    6 +-
 dojox/atom/widget/nls/pt/FeedEntryViewer.js        |    6 +-
 dojox/atom/widget/nls/pt/FeedViewerEntry.js        |    6 +-
 dojox/atom/widget/nls/pt/PeopleEditor.js           |    6 +-
 dojox/atom/widget/nls/ro/FeedEntryEditor.js        |    5 +-
 dojox/atom/widget/nls/ro/FeedEntryViewer.js        |    5 +-
 dojox/atom/widget/nls/ro/FeedViewerEntry.js        |    5 +-
 dojox/atom/widget/nls/ro/PeopleEditor.js           |    5 +-
 dojox/atom/widget/nls/ru/FeedEntryEditor.js        |    6 +-
 dojox/atom/widget/nls/ru/FeedEntryViewer.js        |    6 +-
 dojox/atom/widget/nls/ru/FeedViewerEntry.js        |    6 +-
 dojox/atom/widget/nls/ru/PeopleEditor.js           |    6 +-
 dojox/atom/widget/nls/sk/FeedEntryEditor.js        |    5 +-
 dojox/atom/widget/nls/sk/FeedEntryViewer.js        |    5 +-
 dojox/atom/widget/nls/sk/FeedViewerEntry.js        |    5 +-
 dojox/atom/widget/nls/sk/PeopleEditor.js           |    5 +-
 dojox/atom/widget/nls/sl/FeedEntryEditor.js        |    5 +-
 dojox/atom/widget/nls/sl/FeedEntryViewer.js        |    5 +-
 dojox/atom/widget/nls/sl/FeedViewerEntry.js        |    5 +-
 dojox/atom/widget/nls/sl/PeopleEditor.js           |    5 +-
 dojox/atom/widget/nls/sv/FeedEntryEditor.js        |    4 +
 dojox/atom/widget/nls/sv/FeedEntryViewer.js        |    4 +
 dojox/atom/widget/nls/sv/FeedViewerEntry.js        |    4 +
 dojox/atom/widget/nls/sv/PeopleEditor.js           |    4 +
 dojox/atom/widget/nls/th/FeedEntryEditor.js        |    5 +-
 dojox/atom/widget/nls/th/FeedEntryViewer.js        |    5 +-
 dojox/atom/widget/nls/th/FeedViewerEntry.js        |    5 +-
 dojox/atom/widget/nls/th/PeopleEditor.js           |    5 +-
 dojox/atom/widget/nls/tr/FeedEntryEditor.js        |    4 +
 dojox/atom/widget/nls/tr/FeedEntryViewer.js        |    4 +
 dojox/atom/widget/nls/tr/FeedViewerEntry.js        |    4 +
 dojox/atom/widget/nls/tr/PeopleEditor.js           |    4 +
 dojox/atom/widget/nls/zh-tw/FeedEntryEditor.js     |    6 +-
 dojox/atom/widget/nls/zh-tw/FeedEntryViewer.js     |    4 +
 dojox/atom/widget/nls/zh-tw/FeedViewerEntry.js     |    6 +-
 dojox/atom/widget/nls/zh-tw/PeopleEditor.js        |    4 +
 dojox/atom/widget/nls/zh/FeedEntryEditor.js        |    6 +-
 dojox/atom/widget/nls/zh/FeedEntryViewer.js        |    6 +-
 dojox/atom/widget/nls/zh/FeedViewerEntry.js        |    6 +-
 dojox/atom/widget/nls/zh/PeopleEditor.js           |    6 +-
 dojox/calc/FuncGen.js                              |  259 +-
 dojox/calc/GraphPro.js                             |  261 +-
 dojox/calc/Grapher.js                              | 1147 +-
 dojox/calc/Standard.js                             |  643 +-
 dojox/calc/_Executor.js                            |  262 +-
 dojox/calc/_ExecutorIframe.html                    |    4 +-
 dojox/calc/templates/FuncGen.html                  |   20 +-
 dojox/calc/templates/GraphPro.html                 |   90 +-
 dojox/calc/templates/Grapher.html                  |   44 +-
 dojox/calc/templates/Standard.html                 |   58 +-
 dojox/calc/tests/test_Executor.html                |   83 +-
 dojox/calc/tests/test_GraphPro.html                |   41 +-
 dojox/calc/tests/test_Standard.html                |   36 +-
 dojox/calc/toFrac.js                               |  247 +-
 dojox/charting/BidiSupport.js                      |  264 +
 dojox/charting/Chart.js                            |  351 +-
 dojox/charting/Chart2D.js                          |   51 +-
 dojox/charting/Chart3D.js                          |   41 +-
 dojox/charting/DataChart.js                        |   73 +-
 dojox/charting/DataSeries.js                       |  332 +-
 dojox/charting/Element.js                          |  686 +-
 dojox/charting/Series.js                           |  107 +-
 dojox/charting/StoreSeries.js                      |  184 +-
 dojox/charting/Theme.js                            |  163 +-
 dojox/charting/action2d/Base.js                    |   84 +-
 dojox/charting/action2d/ChartAction.js             |   38 +
 dojox/charting/action2d/Highlight.js               |   52 +-
 dojox/charting/action2d/Magnify.js                 |   49 +-
 dojox/charting/action2d/MouseIndicator.js          |  221 +
 dojox/charting/action2d/MouseZoomAndPan.js         |  245 +
 dojox/charting/action2d/MoveSlice.js               |   59 +-
 dojox/charting/action2d/PlotAction.js              |   78 +
 dojox/charting/action2d/Shake.js                   |   45 +-
 dojox/charting/action2d/Tooltip.js                 |   81 +-
 dojox/charting/action2d/TouchIndicator.js          |  232 +
 dojox/charting/action2d/TouchZoomAndPan.js         |  249 +
 dojox/charting/action2d/_IndicatorElement.js       |  370 +
 dojox/charting/axis2d/Base.js                      |   14 +-
 dojox/charting/axis2d/Default.js                   |  392 +-
 dojox/charting/axis2d/Invisible.js                 |   47 +-
 dojox/charting/axis2d/common.js                    |   37 +-
 dojox/charting/plot2d/Areas.js                     |   24 +-
 dojox/charting/plot2d/Bars.js                      |   91 +-
 dojox/charting/plot2d/Base.js                      |   86 +-
 dojox/charting/plot2d/Bubble.js                    |   38 +-
 dojox/charting/plot2d/Candlesticks.js              |   37 +-
 dojox/charting/plot2d/ClusteredBars.js             |   25 +-
 dojox/charting/plot2d/ClusteredColumns.js          |   25 +-
 dojox/charting/plot2d/Columns.js                   |   64 +-
 dojox/charting/plot2d/Default.js                   |  259 +-
 dojox/charting/plot2d/Grid.js                      |  238 +-
 dojox/charting/plot2d/Lines.js                     |   23 +-
 dojox/charting/plot2d/Markers.js                   |   23 +-
 dojox/charting/plot2d/MarkersOnly.js               |   25 +-
 dojox/charting/plot2d/OHLC.js                      |   37 +-
 dojox/charting/plot2d/Pie.js                       |  177 +-
 dojox/charting/plot2d/Scatter.js                   |   45 +-
 dojox/charting/plot2d/Spider.js                    |  119 +-
 dojox/charting/plot2d/Stacked.js                   |   37 +-
 dojox/charting/plot2d/StackedAreas.js              |   26 +-
 dojox/charting/plot2d/StackedBars.js               |   27 +-
 dojox/charting/plot2d/StackedColumns.js            |   27 +-
 dojox/charting/plot2d/StackedLines.js              |   23 +-
 dojox/charting/plot2d/_PlotEvents.js               |  229 +-
 dojox/charting/plot2d/common.js                    |   77 +-
 dojox/charting/plot3d/Bars.js                      |   19 +-
 dojox/charting/plot3d/Base.js                      |   35 +-
 dojox/charting/plot3d/Cylinders.js                 |   21 +-
 dojox/charting/scaler/common.js                    |   35 +-
 dojox/charting/scaler/linear.js                    |   21 +-
 dojox/charting/scaler/primitive.js                 |   68 +-
 .../tests/BidiSupport/bidi_ChartAxisTitle.html     |  192 +
 .../tests/BidiSupport/bidi_DataSeries.html         |  237 +
 .../tests/BidiSupport/bidi_DeclerativeChart.html   |  107 +
 dojox/charting/tests/BidiSupport/bidi_Event2d.html |  249 +
 .../tests/BidiSupport/bidi_Label_shortening.html   |  233 +
 .../tests/BidiSupport/bidi_Pie_smart_label.html    |  170 +
 dojox/charting/tests/BidiSupport/bidi_Pies.html    |  123 +
 .../tests/BidiSupport/bidi_RotatedLabels.html      |  122 +
 .../tests/BidiSupport/bidi_SelectableLegend.html   |  208 +
 .../tests/BidiSupport/bidi_SetTextDir.html         |  356 +
 .../charting/tests/BidiSupport/bidi_Spider2d.html  |  274 +
 dojox/charting/tests/BidiSupport/module.js         |   31 +
 dojox/charting/tests/BidiSupport/runTests.html     |   11 +
 dojox/charting/tests/BidiSupport/stockHebrew.json  |    8 +
 dojox/charting/tests/Theme.js                      |   10 +-
 .../charting/tests/gradients/test_grad_bars1.html  |   18 +-
 .../charting/tests/gradients/test_grad_bars2.html  |   19 +-
 .../charting/tests/gradients/test_grad_bars3.html  |   18 +-
 .../charting/tests/gradients/test_grad_bars4.html  |   18 +-
 .../charting/tests/gradients/test_grad_bars5.html  |   18 +-
 .../tests/gradients/test_grad_bubble1.html         |   18 +-
 .../tests/gradients/test_grad_bubble2.html         |   18 +-
 .../tests/gradients/test_grad_bubble3.html         |   18 +-
 .../tests/gradients/test_grad_bubble4.html         |   18 +-
 .../tests/gradients/test_grad_bubble6.html         |   18 +-
 .../tests/gradients/test_grad_columns1.html        |   18 +-
 .../tests/gradients/test_grad_columns2.html        |   18 +-
 .../tests/gradients/test_grad_columns3.html        |   18 +-
 .../tests/gradients/test_grad_columns4.html        |   18 +-
 .../tests/gradients/test_grad_columns5.html        |   18 +-
 dojox/charting/tests/gradients/test_grad_pie1.html |   18 +-
 dojox/charting/tests/gradients/test_grad_pie2.html |   18 +-
 dojox/charting/tests/gradients/test_grad_pie3.html |   18 +-
 dojox/charting/tests/gradients/test_grad_pie4.html |   18 +-
 dojox/charting/tests/gradients/test_grad_pie7.html |   18 +-
 dojox/charting/tests/gradients/test_grad_pie8.html |   18 +-
 dojox/charting/tests/gradients/test_grad_pie9.html |   18 +-
 dojox/charting/tests/gradients/test_grad_pieA.html |   18 +-
 .../tests/gradients/test_grad_scatter1.html        |   18 +-
 .../tests/gradients/test_grad_scatter2.html        |   18 +-
 .../tests/gradients/test_grad_scatterB.html        |   18 +-
 dojox/charting/tests/test_DataChart.html           |   68 +-
 dojox/charting/tests/test_DataSeries.html          |   60 +-
 dojox/charting/tests/test_StoreSeries-amd.html     |  187 +
 dojox/charting/tests/test_StoreSeries.html         |   60 +-
 dojox/charting/tests/test_anim2d.html              |   18 +-
 dojox/charting/tests/test_axes.html                |   18 +-
 dojox/charting/tests/test_axisZoomControl.html     |   16 +-
 dojox/charting/tests/test_bars.html                |   23 +-
 dojox/charting/tests/test_chart2d-amd.html         |  856 +
 dojox/charting/tests/test_chart2d.html             |   19 +-
 dojox/charting/tests/test_chart2d_dynamics.html    |   22 +-
 dojox/charting/tests/test_chart2d_updating.html    |   18 +-
 dojox/charting/tests/test_chartAxisTitle.html      |   20 +-
 dojox/charting/tests/test_chartTitle.html          |   19 +-
 dojox/charting/tests/test_chartingsize.html        |   45 +
 dojox/charting/tests/test_cylinders.html           |   23 +-
 dojox/charting/tests/test_event2d.html             |   18 +-
 dojox/charting/tests/test_fillstroke.html          |  138 +
 dojox/charting/tests/test_fireEvent.html           |   22 +-
 dojox/charting/tests/test_label_shortening.html    |   19 +-
 dojox/charting/tests/test_labels2d.html            |   18 +-
 dojox/charting/tests/test_mouseIndicator.html      |   65 +
 dojox/charting/tests/test_mouseIndicator2.html     |   70 +
 dojox/charting/tests/test_mouseZoomAndPan.html     |   80 +
 dojox/charting/tests/test_nulls.html               |   18 +-
 dojox/charting/tests/test_pie2d.html               |   18 +-
 dojox/charting/tests/test_pie2d_zeroslice.html     |   65 +
 dojox/charting/tests/test_pie_smart_label.html     |   17 +-
 dojox/charting/tests/test_plot_order.html          |   18 +-
 dojox/charting/tests/test_rotatedLabels.html       |   20 +-
 dojox/charting/tests/test_scaler.html              |   20 +-
 dojox/charting/tests/test_selectableLegend.html    |   17 +-
 dojox/charting/tests/test_series_order.html        |   18 +-
 dojox/charting/tests/test_sparklines.html          |   25 +-
 dojox/charting/tests/test_spider2d.html            |   18 +-
 dojox/charting/tests/test_tension.html             |   18 +-
 dojox/charting/tests/test_themes-amd.html          |  316 +
 dojox/charting/tests/test_themes.html              |   18 +-
 dojox/charting/tests/test_touchIndicator.html      |  103 +
 dojox/charting/tests/test_touchZoomAndPan.html     |   63 +
 dojox/charting/tests/test_widget2d-amd.html        |  122 +
 dojox/charting/tests/test_widget2d.html            |   22 +-
 dojox/charting/tests/test_widget2d_deprecated.html |   16 +-
 dojox/charting/tests/test_win2d.html               |   26 +-
 dojox/charting/tests/theme_preview-amd.html        |  100 +
 dojox/charting/tests/theme_preview.html            |   15 +-
 dojox/charting/themes/Adobebricks.js               |   11 +-
 dojox/charting/themes/Algae.js                     |   11 +-
 dojox/charting/themes/Bahamation.js                |   11 +-
 dojox/charting/themes/BlueDusk.js                  |   11 +-
 dojox/charting/themes/Charged.js                   |   18 +-
 dojox/charting/themes/Chris.js                     |   18 +-
 dojox/charting/themes/Claro.js                     |   18 +-
 dojox/charting/themes/CubanShirts.js               |   11 +-
 dojox/charting/themes/Desert.js                    |   11 +-
 dojox/charting/themes/Distinctive.js               |   12 +-
 dojox/charting/themes/Dollar.js                    |   21 +-
 dojox/charting/themes/Electric.js                  |   18 +-
 dojox/charting/themes/Grasshopper.js               |   11 +-
 dojox/charting/themes/Grasslands.js                |   13 +-
 dojox/charting/themes/GreySkies.js                 |   13 +-
 dojox/charting/themes/Harmony.js                   |   13 +-
 dojox/charting/themes/IndigoNation.js              |   13 +-
 dojox/charting/themes/Ireland.js                   |   13 +-
 dojox/charting/themes/Julie.js                     |   20 +-
 dojox/charting/themes/MiamiNice.js                 |   13 +-
 dojox/charting/themes/Midwest.js                   |   13 +-
 dojox/charting/themes/Minty.js                     |   13 +-
 dojox/charting/themes/PlotKit/base.js              |   18 +-
 dojox/charting/themes/PlotKit/blue.js              |   13 +-
 dojox/charting/themes/PlotKit/cyan.js              |   13 +-
 dojox/charting/themes/PlotKit/green.js             |   13 +-
 dojox/charting/themes/PlotKit/orange.js            |   13 +-
 dojox/charting/themes/PlotKit/purple.js            |   13 +-
 dojox/charting/themes/PlotKit/red.js               |   13 +-
 dojox/charting/themes/PrimaryColors.js             |   17 +-
 dojox/charting/themes/PurpleRain.js                |   13 +-
 dojox/charting/themes/Renkoo.js                    |   20 +-
 dojox/charting/themes/RoyalPurples.js              |   13 +-
 dojox/charting/themes/SageToLime.js                |   13 +-
 dojox/charting/themes/Shrooms.js                   |   12 +-
 dojox/charting/themes/ThreeD.js                    |   26 +-
 dojox/charting/themes/Tom.js                       |   22 +-
 dojox/charting/themes/Tufte.js                     |  102 +-
 dojox/charting/themes/WatersEdge.js                |   13 +-
 dojox/charting/themes/Wetland.js                   |   13 +-
 dojox/charting/themes/common.js                    |    3 +
 dojox/charting/themes/gradientGenerator.js         |   30 +-
 dojox/charting/widget/BidiSupport.js               |   92 +
 dojox/charting/widget/Chart.js                     |   76 +-
 dojox/charting/widget/Chart2D.js                   |   23 +-
 dojox/charting/widget/Legend.js                    |  310 +-
 dojox/charting/widget/SelectableLegend.js          |  209 +-
 dojox/charting/widget/Sparkline.js                 |   35 +-
 dojox/collections.js                               |    5 +-
 dojox/collections/ArrayList.js                     |  247 +-
 dojox/collections/BinaryTree.js                    |  371 +-
 dojox/collections/Dictionary.js                    |  213 +-
 dojox/collections/Queue.js                         |  135 +-
 dojox/collections/Set.js                           |   20 +-
 dojox/collections/SortedList.js                    |  375 +-
 dojox/collections/Stack.js                         |  131 +-
 dojox/collections/_base.js                         |  184 +-
 dojox/color.js                                     |    5 +-
 dojox/color/Colorspace.js                          |    9 +-
 dojox/color/Palette.js                             |  126 +-
 dojox/color/_base.js                               |  137 +-
 dojox/color/tests/Generator.js                     |  150 -
 dojox/color/tests/color.js                         |    1 -
 dojox/cometd/RestChannels.js                       |   21 +-
 dojox/css3/README                                  |   37 +
 dojox/css3/fx.js                                   |  350 +-
 dojox/css3/transit.js                              |   62 +
 dojox/css3/transition.js                           |  344 +
 dojox/data/AndOrReadStore.js                       |   86 +-
 dojox/data/AndOrWriteStore.js                      |   58 +-
 dojox/data/AppStore.js                             |    4 +-
 dojox/data/AtomReadStore.js                        |    2 +-
 dojox/data/CdfStore.js                             |    2 +-
 dojox/data/ClientFilter.js                         |   65 +-
 dojox/data/CouchDBRestStore.js                     |    2 +-
 dojox/data/CssClassStore.js                        |   10 +-
 dojox/data/CssRuleStore.js                         |   50 +-
 dojox/data/CsvStore.js                             |   21 +-
 dojox/data/FileStore.js                            |   45 +-
 dojox/data/FlickrRestStore.js                      |   62 +-
 dojox/data/FlickrStore.js                          |   29 +-
 dojox/data/GoogleFeedStore.js                      |   11 +-
 dojox/data/GoogleSearchStore.js                    |   55 +-
 dojox/data/HtmlStore.js                            |   50 +-
 dojox/data/HtmlTableStore.js                       |   49 +-
 dojox/data/ItemExplorer.js                         |    4 +-
 dojox/data/JsonQueryRestStore.js                   |    4 +-
 dojox/data/JsonRestStore.js                        |  105 +-
 dojox/data/KeyValueStore.js                        |   20 +-
 dojox/data/OpenSearchStore.js                      |   33 +-
 dojox/data/OpmlStore.js                            |   28 +-
 dojox/data/PersevereStore.js                       |    8 +-
 dojox/data/PicasaStore.js                          |   23 +-
 dojox/data/QueryReadStore.js                       |    2 +-
 dojox/data/RailsStore.js                           |    2 +-
 dojox/data/S3Store.js                              |    9 +-
 dojox/data/ServiceStore.js                         |   22 +-
 dojox/data/SnapLogicStore.js                       |    2 +-
 dojox/data/WikipediaStore.js                       |   18 +-
 dojox/data/XmlItem.js                              |   43 +
 dojox/data/XmlStore.js                             |  118 +-
 dojox/data/css.js                                  |   48 +-
 .../data/demos/demo_CssStores_combo_tree_grid.html |    1 -
 dojox/data/demos/demo_DataDemoTable.html           |    2 +-
 dojox/data/demos/demo_FileStore_dojotree.html      |    4 +-
 .../demos/demo_FileStore_dojoxdata_combo_grid.html |    4 +-
 dojox/data/demos/demo_GoogleFeedStore.html         |    4 +-
 dojox/data/demos/demo_GoogleSearchStore_Grid.html  |    2 -
 dojox/data/demos/stores/filestore_dojotree.php     |    4 +-
 dojox/data/dom.js                                  |   27 +-
 dojox/data/tests/stores/AndOrReadStore.js          |   16 +-
 dojox/data/tests/stores/AndOrWriteStore.js         |   16 +-
 dojox/data/tests/stores/AtomReadStore.js           |    6 +-
 dojox/data/tests/stores/CssClassStore.js           |  100 +-
 dojox/data/tests/stores/CssRuleStore.js            |   81 +-
 dojox/data/tests/stores/CsvStore.js                |    2 +-
 dojox/data/tests/stores/FileStore.js               |    2 +-
 dojox/data/tests/stores/HtmlStore.js               |   12 +-
 dojox/data/tests/stores/HtmlTableStore.js          |    4 +-
 dojox/data/tests/stores/JsonRestStore.js           |    2 +-
 dojox/data/tests/stores/KeyValueStore.js           |    2 +-
 dojox/data/tests/stores/OpenSearchStore.js         |   12 +-
 dojox/data/tests/stores/OpmlStore.js               |    2 +-
 dojox/data/tests/stores/QueryReadStore.js          |    2 +-
 dojox/data/tests/stores/ServiceStore.js            |    2 +-
 dojox/data/tests/stores/SnapLogicStore.js          |    2 +-
 dojox/data/tests/stores/XmlStore.js                |   42 +-
 dojox/data/tests/stores/filestore_dojoxdatageo.php |    4 +-
 dojox/data/tests/stores/filestore_funcs.php        |    6 +-
 dojox/data/tests/stores/snap_pipeline.php          |    6 +-
 dojox/date/buddhist.js                             |   48 +-
 dojox/date/buddhist/Date.js                        |  110 +-
 dojox/date/buddhist/locale.js                      |  571 +-
 dojox/date/hebrew.js                               |   56 +-
 dojox/date/hebrew/Date.js                          |   72 +-
 dojox/date/hebrew/locale.js                        |  762 +-
 dojox/date/hebrew/numerals.js                      |    9 +-
 dojox/date/islamic.js                              |   44 +-
 dojox/date/islamic/Date.js                         |  118 +-
 dojox/date/islamic/locale.js                       |  589 +-
 dojox/date/php.js                                  |   15 +-
 dojox/date/posix.js                                |   51 +-
 dojox/date/relative.js                             |   56 +-
 dojox/date/tests/buddhist/Date.js                  |  109 +-
 dojox/date/tests/hebrew/Date.js                    |  120 +-
 dojox/date/tests/islamic/Date.js                   |   89 +-
 dojox/date/tests/module.js                         |    2 +
 dojox/date/tests/posix.js                          |    2 +-
 dojox/date/tests/timezoneFormatting.js             |    2 +-
 dojox/date/timezone.js                             |   92 +-
 dojox/dnd/BoundingBoxController.js                 |  255 +-
 dojox/dnd/Selector.js                              |  347 +-
 dojox/dnd/tests/robot/test_selector.html           |   71 -
 dojox/dnd/tests/runTests.html                      |   10 +
 dojox/dnd/tests/testAll.js                         |    8 +
 dojox/dnd/tests/test_boundingBoxController.html    |   79 +
 dojox/dnd/tests/test_selector.html                 |   73 +-
 dojox/dojox.profile.js                             |   68 +
 dojox/drawing/Drawing.js                           |   13 +-
 dojox/drawing/README                               |    2 +-
 dojox/drawing/annotations/Angle.js                 |    2 +-
 dojox/drawing/manager/Mouse.js                     |   17 +-
 dojox/drawing/manager/keys.js                      |    2 +-
 dojox/drawing/plugins/drawing/GreekPalette.js      |   85 +-
 dojox/drawing/resources/GreekPalette.css           |    6 +-
 dojox/drawing/tests/drawing.html                   |    3 +-
 dojox/drawing/tests/test_drawing.html              |    4 +-
 dojox/drawing/tests/test_drawing_toolbar.html      |    4 +-
 dojox/drawing/tests/test_paths.html                |    3 +-
 dojox/drawing/tools/TextBlock.js                   |   32 +-
 dojox/drawing/util/oo.js                           |    4 +-
 dojox/dtl.js                                       |    5 +-
 dojox/dtl/Context.js                               |  135 +-
 dojox/dtl/DomInline.js                             |   73 +-
 dojox/dtl/HtmlInline.js                            |    5 -
 dojox/dtl/Inline.js                                |   66 +-
 dojox/dtl/_DomTemplated.js                         |  167 +-
 dojox/dtl/_HtmlTemplated.js                        |    5 -
 dojox/dtl/_Templated.js                            |  238 +-
 dojox/dtl/_base.js                                 |  167 +-
 dojox/dtl/contrib/data.js                          |   32 +-
 dojox/dtl/contrib/dijit.js                         |   83 +-
 dojox/dtl/contrib/dom.js                           |   65 +-
 dojox/dtl/contrib/html.js                          |    3 -
 dojox/dtl/contrib/objects.js                       |   25 +-
 dojox/dtl/demos/demo_Animation.html                |    4 +-
 dojox/dtl/demos/demo_Animation_amd.html            |   53 +
 dojox/dtl/demos/demo_Blog.html                     |    4 +-
 dojox/dtl/demos/demo_Data.html                     |    6 +-
 dojox/dtl/demos/demo_DomTemplated.html             |    8 +-
 dojox/dtl/demos/demo_DomTemplated_amd.html         |   50 +
 dojox/dtl/demos/demo_Events.html                   |    8 +-
 dojox/dtl/demos/demo_NodeList_amd.html             |   42 +
 dojox/dtl/demos/demo_Table.html                    |    4 +-
 dojox/dtl/demos/demo_Templated.html                |    6 +-
 dojox/dtl/demos/demo_Templated_amd.html            |   42 +
 dojox/dtl/demos/demo_Tree.html                     |    6 +-
 dojox/dtl/demos/templates/blog_base.html           |    2 +-
 dojox/dtl/demos/templates/blog_list.html           |    2 +-
 dojox/dtl/demos/templates/blog_page.html           |    2 +-
 dojox/dtl/dom.js                                   |  126 +-
 dojox/dtl/ext-dojo/NodeList.js                     |   59 +-
 dojox/dtl/filter/dates.js                          |   29 +-
 dojox/dtl/filter/htmlstrings.js                    |   89 +-
 dojox/dtl/filter/integers.js                       |   57 +-
 dojox/dtl/filter/lists.js                          |  263 +-
 dojox/dtl/filter/logic.js                          |   75 +-
 dojox/dtl/filter/misc.js                           |  114 +-
 dojox/dtl/filter/strings.js                        |  601 +-
 dojox/dtl/html.js                                  |    4 -
 dojox/dtl/render/dom.js                            |   63 +-
 dojox/dtl/render/html.js                           |   16 +-
 dojox/dtl/tag/date.js                              |   63 +-
 dojox/dtl/tag/loader.js                            |   30 +-
 dojox/dtl/tag/logic.js                             |   30 +-
 dojox/dtl/tag/loop.js                              |   37 +-
 dojox/dtl/tag/misc.js                              |   43 +-
 dojox/dtl/tests/dom/tag.js                         |    1 +
 dojox/dtl/utils/date.js                            |  143 +-
 dojox/editor/README                                |   66 +-
 dojox/editor/plugins/AutoSave.js                   |   38 +-
 dojox/editor/plugins/AutoUrlLink.js                |   13 +-
 dojox/editor/plugins/Blockquote.js                 |   14 +-
 dojox/editor/plugins/Breadcrumb.js                 |   26 +-
 dojox/editor/plugins/CollapsibleToolbar.js         |   19 +-
 dojox/editor/plugins/EntityPalette.js              |   15 +-
 dojox/editor/plugins/FindReplace.js                |   40 +-
 dojox/editor/plugins/InsertAnchor.js               |   27 +-
 dojox/editor/plugins/InsertEntity.js               |   15 +-
 dojox/editor/plugins/LocalImage.js                 |   94 +-
 dojox/editor/plugins/NormalizeIndentOutdent.js     |   11 +-
 dojox/editor/plugins/NormalizeStyle.js             |   10 +-
 dojox/editor/plugins/PageBreak.js                  |   12 +-
 dojox/editor/plugins/PasteFromWord.js              |   22 +-
 dojox/editor/plugins/PrettyPrint.js                |   10 +-
 dojox/editor/plugins/Preview.js                    |   14 +-
 dojox/editor/plugins/SafePaste.js                  |  115 +
 dojox/editor/plugins/Save.js                       |   12 +-
 dojox/editor/plugins/ShowBlockNodes.js             |   13 +-
 dojox/editor/plugins/Smiley.js                     |   38 +-
 dojox/editor/plugins/SpellCheck.js                 |   11 +-
 dojox/editor/plugins/StatusBar.js                  |   14 +-
 dojox/editor/plugins/TablePlugins.js               |   45 +-
 dojox/editor/plugins/TextColor.js                  |   21 +-
 dojox/editor/plugins/ToolbarLineBreak.js           |   17 +-
 dojox/editor/plugins/UploadImage.js                |   11 +-
 dojox/editor/plugins/_SmileyPalette.js             |   15 +-
 dojox/editor/plugins/_SpellCheckParser.js          |    7 +-
 dojox/editor/plugins/nls/AutoSave.js               |   35 +
 dojox/editor/plugins/nls/Blockquote.js             |   37 +-
 dojox/editor/plugins/nls/Breadcrumb.js             |   35 +
 dojox/editor/plugins/nls/CollapsibleToolbar.js     |   37 +-
 dojox/editor/plugins/nls/FindReplace.js            |   35 +
 dojox/editor/plugins/nls/InsertAnchor.js           |   35 +
 dojox/editor/plugins/nls/InsertEntity.js           |   37 +-
 dojox/editor/plugins/nls/LocalImage.js             |   35 +
 dojox/editor/plugins/nls/PageBreak.js              |   37 +-
 dojox/editor/plugins/nls/PasteFromWord.js          |   38 +-
 dojox/editor/plugins/nls/Preview.js                |   37 +-
 dojox/editor/plugins/nls/SafePaste.js              |   35 +
 dojox/editor/plugins/nls/Save.js                   |   37 +-
 dojox/editor/plugins/nls/ShowBlockNodes.js         |   35 +
 dojox/editor/plugins/nls/Smiley.js                 |   38 +-
 dojox/editor/plugins/nls/SpellCheck.js             |   35 +
 dojox/editor/plugins/nls/TableDialog.js            |   37 +-
 dojox/editor/plugins/nls/TextColor.js              |   35 +
 dojox/editor/plugins/nls/ar/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/ar/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/ar/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/ar/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/ar/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/ar/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/ar/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/ar/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/ar/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/ar/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/ar/Preview.js             |    4 +
 dojox/editor/plugins/nls/ar/Save.js                |    4 +
 dojox/editor/plugins/nls/ar/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/ar/Smiley.js              |    4 +
 dojox/editor/plugins/nls/ar/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/ar/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/ar/TextColor.js           |    4 +
 dojox/editor/plugins/nls/ar/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/az/TableDialog.js         |   31 +
 dojox/editor/plugins/nls/ca/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/ca/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/ca/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/ca/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/ca/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/ca/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/ca/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/ca/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/ca/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/ca/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/ca/Preview.js             |    4 +
 dojox/editor/plugins/nls/ca/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/ca/Save.js                |    4 +
 dojox/editor/plugins/nls/ca/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/ca/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/ca/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/ca/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/ca/TextColor.js           |    4 +
 dojox/editor/plugins/nls/ca/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/cs/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/cs/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/cs/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/cs/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/cs/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/cs/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/cs/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/cs/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/cs/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/cs/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/cs/Preview.js             |    4 +
 dojox/editor/plugins/nls/cs/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/cs/Save.js                |    4 +
 dojox/editor/plugins/nls/cs/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/cs/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/cs/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/cs/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/cs/TextColor.js           |    4 +
 dojox/editor/plugins/nls/cs/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/da/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/da/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/da/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/da/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/da/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/da/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/da/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/da/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/da/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/da/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/da/Preview.js             |    4 +
 dojox/editor/plugins/nls/da/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/da/Save.js                |    4 +
 dojox/editor/plugins/nls/da/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/da/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/da/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/da/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/da/TextColor.js           |    4 +
 dojox/editor/plugins/nls/da/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/de/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/de/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/de/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/de/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/de/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/de/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/de/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/de/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/de/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/de/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/de/Preview.js             |    4 +
 dojox/editor/plugins/nls/de/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/de/Save.js                |    4 +
 dojox/editor/plugins/nls/de/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/de/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/de/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/de/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/de/TextColor.js           |    4 +
 dojox/editor/plugins/nls/de/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/el/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/el/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/el/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/el/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/el/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/el/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/el/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/el/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/el/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/el/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/el/Preview.js             |    4 +
 dojox/editor/plugins/nls/el/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/el/Save.js                |    4 +
 dojox/editor/plugins/nls/el/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/el/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/el/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/el/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/el/TextColor.js           |    4 +
 dojox/editor/plugins/nls/el/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/es/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/es/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/es/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/es/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/es/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/es/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/es/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/es/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/es/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/es/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/es/Preview.js             |    4 +
 dojox/editor/plugins/nls/es/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/es/Save.js                |    4 +
 dojox/editor/plugins/nls/es/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/es/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/es/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/es/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/es/TextColor.js           |    4 +
 dojox/editor/plugins/nls/es/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/fi/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/fi/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/fi/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/fi/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/fi/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/fi/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/fi/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/fi/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/fi/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/fi/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/fi/Preview.js             |    4 +
 dojox/editor/plugins/nls/fi/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/fi/Save.js                |    4 +
 dojox/editor/plugins/nls/fi/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/fi/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/fi/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/fi/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/fi/TextColor.js           |    4 +
 dojox/editor/plugins/nls/fi/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/fr/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/fr/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/fr/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/fr/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/fr/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/fr/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/fr/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/fr/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/fr/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/fr/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/fr/Preview.js             |    4 +
 dojox/editor/plugins/nls/fr/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/fr/Save.js                |    4 +
 dojox/editor/plugins/nls/fr/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/fr/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/fr/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/fr/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/fr/TextColor.js           |    4 +
 dojox/editor/plugins/nls/fr/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/he/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/he/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/he/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/he/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/he/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/he/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/he/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/he/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/he/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/he/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/he/Preview.js             |    4 +
 dojox/editor/plugins/nls/he/Save.js                |    4 +
 dojox/editor/plugins/nls/he/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/he/Smiley.js              |    4 +
 dojox/editor/plugins/nls/he/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/he/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/he/TextColor.js           |    4 +
 dojox/editor/plugins/nls/he/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/hr/AutoSave.js            |   15 +
 dojox/editor/plugins/nls/hr/Blockquote.js          |    5 +
 dojox/editor/plugins/nls/hr/Breadcrumb.js          |   11 +
 dojox/editor/plugins/nls/hr/CollapsibleToolbar.js  |    6 +
 dojox/editor/plugins/nls/hr/FindReplace.js         |   23 +
 dojox/editor/plugins/nls/hr/InsertAnchor.js        |   10 +
 dojox/editor/plugins/nls/hr/InsertEntity.js        |    5 +
 dojox/editor/plugins/nls/hr/LocalImage.js          |   12 +
 dojox/editor/plugins/nls/hr/PageBreak.js           |    5 +
 dojox/editor/plugins/nls/hr/PasteFromWord.js       |    8 +
 dojox/editor/plugins/nls/hr/Preview.js             |    5 +
 dojox/editor/plugins/nls/hr/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/hr/Save.js                |    5 +
 dojox/editor/plugins/nls/hr/ShowBlockNodes.js      |    5 +
 dojox/editor/plugins/nls/hr/Smiley.js              |   24 +
 dojox/editor/plugins/nls/hr/SpellCheck.js          |   18 +
 dojox/editor/plugins/nls/hr/TableDialog.js         |   31 +
 dojox/editor/plugins/nls/hr/TextColor.js           |    6 +
 dojox/editor/plugins/nls/hr/latinEntities.js       |  257 +
 dojox/editor/plugins/nls/hu/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/hu/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/hu/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/hu/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/hu/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/hu/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/hu/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/hu/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/hu/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/hu/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/hu/Preview.js             |    4 +
 dojox/editor/plugins/nls/hu/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/hu/Save.js                |    4 +
 dojox/editor/plugins/nls/hu/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/hu/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/hu/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/hu/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/hu/TextColor.js           |    4 +
 dojox/editor/plugins/nls/hu/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/it/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/it/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/it/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/it/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/it/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/it/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/it/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/it/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/it/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/it/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/it/Preview.js             |    4 +
 dojox/editor/plugins/nls/it/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/it/Save.js                |    4 +
 dojox/editor/plugins/nls/it/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/it/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/it/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/it/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/it/TextColor.js           |    4 +
 dojox/editor/plugins/nls/it/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/ja/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/ja/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/ja/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/ja/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/ja/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/ja/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/ja/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/ja/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/ja/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/ja/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/ja/Preview.js             |    4 +
 dojox/editor/plugins/nls/ja/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/ja/Save.js                |    4 +
 dojox/editor/plugins/nls/ja/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/ja/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/ja/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/ja/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/ja/TextColor.js           |    4 +
 dojox/editor/plugins/nls/ja/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/kk/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/kk/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/kk/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/kk/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/kk/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/kk/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/kk/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/kk/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/kk/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/kk/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/kk/Preview.js             |    4 +
 dojox/editor/plugins/nls/kk/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/kk/Save.js                |    4 +
 dojox/editor/plugins/nls/kk/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/kk/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/kk/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/kk/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/kk/TextColor.js           |    4 +
 dojox/editor/plugins/nls/kk/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/ko/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/ko/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/ko/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/ko/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/ko/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/ko/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/ko/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/ko/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/ko/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/ko/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/ko/Preview.js             |    4 +
 dojox/editor/plugins/nls/ko/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/ko/Save.js                |    4 +
 dojox/editor/plugins/nls/ko/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/ko/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/ko/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/ko/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/ko/TextColor.js           |    4 +
 dojox/editor/plugins/nls/ko/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/latinEntities.js          |   35 +
 dojox/editor/plugins/nls/nb/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/nb/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/nb/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/nb/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/nb/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/nb/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/nb/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/nb/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/nb/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/nb/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/nb/Preview.js             |    4 +
 dojox/editor/plugins/nls/nb/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/nb/Save.js                |    4 +
 dojox/editor/plugins/nls/nb/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/nb/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/nb/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/nb/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/nb/TextColor.js           |    4 +
 dojox/editor/plugins/nls/nb/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/nl/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/nl/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/nl/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/nl/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/nl/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/nl/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/nl/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/nl/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/nl/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/nl/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/nl/Preview.js             |    4 +
 dojox/editor/plugins/nls/nl/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/nl/Save.js                |    4 +
 dojox/editor/plugins/nls/nl/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/nl/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/nl/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/nl/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/nl/TextColor.js           |    4 +
 dojox/editor/plugins/nls/nl/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/pl/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/pl/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/pl/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/pl/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/pl/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/pl/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/pl/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/pl/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/pl/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/pl/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/pl/Preview.js             |    4 +
 dojox/editor/plugins/nls/pl/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/pl/Save.js                |    4 +
 dojox/editor/plugins/nls/pl/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/pl/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/pl/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/pl/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/pl/TextColor.js           |    4 +
 dojox/editor/plugins/nls/pl/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/pt-pt/AutoSave.js         |    4 +
 dojox/editor/plugins/nls/pt-pt/Blockquote.js       |    4 +
 dojox/editor/plugins/nls/pt-pt/Breadcrumb.js       |    4 +
 .../editor/plugins/nls/pt-pt/CollapsibleToolbar.js |    4 +
 dojox/editor/plugins/nls/pt-pt/FindReplace.js      |    5 +-
 dojox/editor/plugins/nls/pt-pt/InsertAnchor.js     |    4 +
 dojox/editor/plugins/nls/pt-pt/InsertEntity.js     |    4 +
 dojox/editor/plugins/nls/pt-pt/LocalImage.js       |    4 +
 dojox/editor/plugins/nls/pt-pt/PageBreak.js        |    4 +
 dojox/editor/plugins/nls/pt-pt/PasteFromWord.js    |    4 +
 dojox/editor/plugins/nls/pt-pt/Preview.js          |    4 +
 dojox/editor/plugins/nls/pt-pt/Save.js             |    4 +
 dojox/editor/plugins/nls/pt-pt/ShowBlockNodes.js   |    4 +
 dojox/editor/plugins/nls/pt-pt/Smiley.js           |    4 +
 dojox/editor/plugins/nls/pt-pt/SpellCheck.js       |    4 +
 dojox/editor/plugins/nls/pt-pt/TableDialog.js      |    4 +
 dojox/editor/plugins/nls/pt-pt/TextColor.js        |    4 +
 dojox/editor/plugins/nls/pt-pt/latinEntities.js    |    4 +
 dojox/editor/plugins/nls/pt/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/pt/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/pt/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/pt/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/pt/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/pt/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/pt/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/pt/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/pt/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/pt/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/pt/Preview.js             |    4 +
 dojox/editor/plugins/nls/pt/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/pt/Save.js                |    4 +
 dojox/editor/plugins/nls/pt/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/pt/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/pt/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/pt/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/pt/TextColor.js           |    4 +
 dojox/editor/plugins/nls/pt/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/ro/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/ro/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/ro/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/ro/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/ro/FindReplace.js         |    4 +
 dojox/editor/plugins/nls/ro/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/ro/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/ro/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/ro/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/ro/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/ro/Preview.js             |    4 +
 dojox/editor/plugins/nls/ro/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/ro/Save.js                |    4 +
 dojox/editor/plugins/nls/ro/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/ro/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/ro/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/ro/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/ro/TextColor.js           |    4 +
 dojox/editor/plugins/nls/ro/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/ru/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/ru/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/ru/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/ru/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/ru/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/ru/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/ru/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/ru/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/ru/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/ru/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/ru/Preview.js             |    4 +
 dojox/editor/plugins/nls/ru/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/ru/Save.js                |    4 +
 dojox/editor/plugins/nls/ru/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/ru/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/ru/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/ru/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/ru/TextColor.js           |    4 +
 dojox/editor/plugins/nls/ru/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/sk/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/sk/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/sk/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/sk/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/sk/FindReplace.js         |    4 +
 dojox/editor/plugins/nls/sk/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/sk/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/sk/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/sk/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/sk/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/sk/Preview.js             |    4 +
 dojox/editor/plugins/nls/sk/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/sk/Save.js                |    4 +
 dojox/editor/plugins/nls/sk/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/sk/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/sk/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/sk/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/sk/TextColor.js           |    4 +
 dojox/editor/plugins/nls/sk/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/sl/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/sl/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/sl/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/sl/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/sl/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/sl/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/sl/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/sl/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/sl/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/sl/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/sl/Preview.js             |    4 +
 dojox/editor/plugins/nls/sl/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/sl/Save.js                |    4 +
 dojox/editor/plugins/nls/sl/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/sl/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/sl/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/sl/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/sl/TextColor.js           |    4 +
 dojox/editor/plugins/nls/sl/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/sv/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/sv/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/sv/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/sv/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/sv/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/sv/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/sv/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/sv/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/sv/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/sv/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/sv/Preview.js             |    4 +
 dojox/editor/plugins/nls/sv/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/sv/Save.js                |    4 +
 dojox/editor/plugins/nls/sv/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/sv/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/sv/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/sv/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/sv/TextColor.js           |    4 +
 dojox/editor/plugins/nls/sv/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/th/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/th/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/th/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/th/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/th/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/th/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/th/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/th/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/th/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/th/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/th/Preview.js             |    4 +
 dojox/editor/plugins/nls/th/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/th/Save.js                |    4 +
 dojox/editor/plugins/nls/th/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/th/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/th/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/th/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/th/TextColor.js           |    4 +
 dojox/editor/plugins/nls/th/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/tr/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/tr/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/tr/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/tr/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/tr/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/tr/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/tr/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/tr/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/tr/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/tr/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/tr/Preview.js             |    4 +
 dojox/editor/plugins/nls/tr/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/tr/Save.js                |    4 +
 dojox/editor/plugins/nls/tr/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/tr/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/tr/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/tr/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/tr/TextColor.js           |    4 +
 dojox/editor/plugins/nls/tr/latinEntities.js       |    4 +
 dojox/editor/plugins/nls/zh-tw/AutoSave.js         |    4 +
 dojox/editor/plugins/nls/zh-tw/Blockquote.js       |    4 +
 dojox/editor/plugins/nls/zh-tw/Breadcrumb.js       |    4 +
 .../editor/plugins/nls/zh-tw/CollapsibleToolbar.js |    4 +
 dojox/editor/plugins/nls/zh-tw/FindReplace.js      |    5 +-
 dojox/editor/plugins/nls/zh-tw/InsertAnchor.js     |    4 +
 dojox/editor/plugins/nls/zh-tw/InsertEntity.js     |    4 +
 dojox/editor/plugins/nls/zh-tw/LocalImage.js       |    4 +
 dojox/editor/plugins/nls/zh-tw/PageBreak.js        |    4 +
 dojox/editor/plugins/nls/zh-tw/PasteFromWord.js    |    4 +
 dojox/editor/plugins/nls/zh-tw/Preview.js          |    4 +
 dojox/editor/plugins/nls/zh-tw/SafePaste.js        |    5 +
 dojox/editor/plugins/nls/zh-tw/Save.js             |    4 +
 dojox/editor/plugins/nls/zh-tw/ShowBlockNodes.js   |    4 +
 dojox/editor/plugins/nls/zh-tw/Smiley.js           |    7 +-
 dojox/editor/plugins/nls/zh-tw/SpellCheck.js       |    4 +
 dojox/editor/plugins/nls/zh-tw/TableDialog.js      |    4 +
 dojox/editor/plugins/nls/zh-tw/TextColor.js        |    4 +
 dojox/editor/plugins/nls/zh-tw/latinEntities.js    |    4 +
 dojox/editor/plugins/nls/zh/AutoSave.js            |    4 +
 dojox/editor/plugins/nls/zh/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/zh/Breadcrumb.js          |    4 +
 dojox/editor/plugins/nls/zh/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/zh/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/zh/InsertAnchor.js        |    4 +
 dojox/editor/plugins/nls/zh/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/zh/LocalImage.js          |    4 +
 dojox/editor/plugins/nls/zh/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/zh/PasteFromWord.js       |    4 +
 dojox/editor/plugins/nls/zh/Preview.js             |    4 +
 dojox/editor/plugins/nls/zh/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/zh/Save.js                |    4 +
 dojox/editor/plugins/nls/zh/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/zh/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/zh/SpellCheck.js          |    4 +
 dojox/editor/plugins/nls/zh/TableDialog.js         |    4 +
 dojox/editor/plugins/nls/zh/TextColor.js           |    4 +
 dojox/editor/plugins/nls/zh/latinEntities.js       |    4 +
 .../editor/plugins/resources/css/InsertEntity.css  |    6 +-
 dojox/editor/plugins/resources/css/SafePaste.css   |    3 +
 dojox/editor/tests/editorFindReplace.html          |    1 +
 dojox/editor/tests/editorSafePaste.html            |  105 +
 dojox/editor/tests/testPluginsAll.html             |   12 +-
 dojox/embed/Flash.js                               |   77 +-
 dojox/embed/IE/flash.js                            |   19 -
 dojox/embed/Object.js                              |   22 +-
 dojox/embed/Quicktime.js                           |   59 +-
 dojox/embed/flashVars.js                           |   11 +-
 dojox/embed/tests/flash.html                       |   25 +-
 dojox/embed/tests/object.html                      |    4 +-
 dojox/encoding/_base.js                            |    6 +-
 dojox/encoding/ascii85.js                          |   18 +-
 dojox/encoding/base64.js                           |   21 +-
 dojox/encoding/bits.js                             |  122 +-
 dojox/encoding/compression/lzw.js                  |   27 +-
 dojox/encoding/compression/splay.js                |  123 +-
 dojox/encoding/crypto/Blowfish.js                  |   82 +-
 dojox/encoding/crypto/RSAKey-ext.js                |   22 +-
 dojox/encoding/crypto/RSAKey.js                    |   21 +-
 dojox/encoding/crypto/SimpleAES.js                 |  584 +-
 dojox/encoding/crypto/_base.js                     |   25 +-
 dojox/encoding/digests/MD5.js                      |   14 +-
 dojox/encoding/digests/SHA1.js                     |   14 +-
 dojox/encoding/digests/_base.js                    |   14 +-
 dojox/encoding/easy64.js                           |   17 +-
 dojox/encoding/tests/ascii85.js                    |   10 +-
 dojox/encoding/tests/bits.js                       |   18 +-
 dojox/encoding/tests/compression/_base.js          |    9 +-
 dojox/encoding/tests/compression/lzw.js            |   11 +-
 dojox/encoding/tests/compression/splay.js          |   15 +-
 dojox/encoding/tests/crypto/Blowfish.js            |   16 +-
 dojox/encoding/tests/crypto/RSA.js                 |   19 +-
 dojox/encoding/tests/crypto/SimpleAES.js           |   12 +-
 dojox/encoding/tests/crypto/_base.js               |   11 +-
 dojox/encoding/tests/digests/MD5.js                |   16 +-
 dojox/encoding/tests/digests/SHA1.js               |   16 +-
 dojox/encoding/tests/digests/_base.js              |   10 +-
 dojox/encoding/tests/easy64.js                     |   10 +-
 dojox/encoding/tests/encoding.js                   |   10 +-
 dojox/form/BusyButton.js                           |   97 +-
 dojox/form/CheckedMultiSelect.js                   |  427 +-
 dojox/form/DateTextBox.js                          |   92 +-
 dojox/form/DropDownSelect.js                       |   14 +-
 dojox/form/DropDownStack.js                        |   22 +-
 dojox/form/FileInput.js                            |   42 +-
 dojox/form/FileInputAuto.js                        |   70 +-
 dojox/form/FileInputBlind.js                       |    9 +-
 dojox/form/FilePickerTextBox.js                    |  115 +-
 dojox/form/FileUploader.js                         |  365 +-
 dojox/form/ListInput.js                            |  435 +-
 dojox/form/Manager.js                              |   67 +-
 dojox/form/MultiComboBox.js                        |   36 +-
 dojox/form/PasswordValidator.js                    |  122 +-
 dojox/form/README                                  |   10 +-
 dojox/form/RadioStack.js                           |   18 +-
 dojox/form/RangeSlider.js                          |  323 +-
 dojox/form/Rating.js                               |   57 +-
 dojox/form/TimeSpinner.js                          |   41 +-
 dojox/form/TriStateCheckBox.js                     |  243 +
 dojox/form/Uploader.js                             |  248 +-
 dojox/form/_FormSelectWidget.js                    |   14 +-
 dojox/form/_HasDropDown.js                         |   14 +-
 dojox/form/_SelectStackMixin.js                    |   73 +-
 dojox/form/manager/_ClassMixin.js                  |   24 +-
 dojox/form/manager/_DisplayMixin.js                |   14 +-
 dojox/form/manager/_EnableMixin.js                 |   24 +-
 dojox/form/manager/_FormMixin.js                   |   27 +-
 dojox/form/manager/_Mixin.js                       |  125 +-
 dojox/form/manager/_NodeMixin.js                   |   86 +-
 dojox/form/manager/_ValueMixin.js                  |   14 +-
 dojox/form/nls/CheckedMultiSelect.js               |   36 +
 dojox/form/nls/PasswordValidator.js                |   38 +-
 dojox/form/nls/Uploader.js                         |   35 +
 dojox/form/nls/ar/PasswordValidator.js             |    5 +-
 dojox/form/nls/az/PasswordValidator.js             |    8 +
 dojox/form/nls/ca/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/ca/PasswordValidator.js             |    5 +-
 dojox/form/nls/ca/Uploader.js                      |    5 +
 dojox/form/nls/cs/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/cs/PasswordValidator.js             |    5 +-
 dojox/form/nls/cs/Uploader.js                      |    5 +
 dojox/form/nls/da/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/da/PasswordValidator.js             |    5 +-
 dojox/form/nls/da/Uploader.js                      |    5 +
 dojox/form/nls/de/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/de/PasswordValidator.js             |    5 +-
 dojox/form/nls/de/Uploader.js                      |    5 +
 dojox/form/nls/el/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/el/PasswordValidator.js             |    5 +-
 dojox/form/nls/el/Uploader.js                      |    5 +
 dojox/form/nls/es/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/es/PasswordValidator.js             |    4 +
 dojox/form/nls/es/Uploader.js                      |    5 +
 dojox/form/nls/fi/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/fi/PasswordValidator.js             |    4 +
 dojox/form/nls/fi/Uploader.js                      |    5 +
 dojox/form/nls/fr/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/fr/PasswordValidator.js             |    4 +
 dojox/form/nls/fr/Uploader.js                      |    5 +
 dojox/form/nls/he/PasswordValidator.js             |    4 +
 dojox/form/nls/hr/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/hr/PasswordValidator.js             |    6 +
 dojox/form/nls/hr/Uploader.js                      |    5 +
 dojox/form/nls/hu/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/hu/PasswordValidator.js             |    4 +
 dojox/form/nls/hu/Uploader.js                      |    5 +
 dojox/form/nls/it/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/it/PasswordValidator.js             |    4 +
 dojox/form/nls/it/Uploader.js                      |    5 +
 dojox/form/nls/ja/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/ja/PasswordValidator.js             |    4 +
 dojox/form/nls/ja/Uploader.js                      |    5 +
 dojox/form/nls/kk/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/kk/Uploader.js                      |    5 +
 dojox/form/nls/ko/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/ko/PasswordValidator.js             |    4 +
 dojox/form/nls/ko/Uploader.js                      |    5 +
 dojox/form/nls/nb/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/nb/PasswordValidator.js             |    4 +
 dojox/form/nls/nb/Uploader.js                      |    5 +
 dojox/form/nls/nl/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/nl/PasswordValidator.js             |    4 +
 dojox/form/nls/nl/Uploader.js                      |    5 +
 dojox/form/nls/pl/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/pl/PasswordValidator.js             |    4 +
 dojox/form/nls/pl/Uploader.js                      |    5 +
 dojox/form/nls/pt-pt/PasswordValidator.js          |    4 +
 dojox/form/nls/pt/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/pt/PasswordValidator.js             |    4 +
 dojox/form/nls/pt/Uploader.js                      |    5 +
 dojox/form/nls/ro/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/ro/PasswordValidator.js             |    4 +
 dojox/form/nls/ro/Uploader.js                      |    5 +
 dojox/form/nls/ru/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/ru/PasswordValidator.js             |    4 +
 dojox/form/nls/ru/Uploader.js                      |    5 +
 dojox/form/nls/sk/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/sk/PasswordValidator.js             |    4 +
 dojox/form/nls/sk/Uploader.js                      |    5 +
 dojox/form/nls/sl/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/sl/PasswordValidator.js             |    4 +
 dojox/form/nls/sl/Uploader.js                      |    5 +
 dojox/form/nls/sv/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/sv/PasswordValidator.js             |    4 +
 dojox/form/nls/sv/Uploader.js                      |    5 +
 dojox/form/nls/th/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/th/PasswordValidator.js             |    4 +
 dojox/form/nls/th/Uploader.js                      |    5 +
 dojox/form/nls/tr/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/tr/PasswordValidator.js             |    4 +
 dojox/form/nls/tr/Uploader.js                      |    5 +
 dojox/form/nls/zh-tw/CheckedMultiSelect.js         |    6 +
 dojox/form/nls/zh-tw/PasswordValidator.js          |    4 +
 dojox/form/nls/zh-tw/Uploader.js                   |    5 +
 dojox/form/nls/zh/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/zh/PasswordValidator.js             |    4 +
 dojox/form/nls/zh/Uploader.js                      |    5 +
 dojox/form/resources/CheckedMultiSelect.css        |  216 +-
 dojox/form/resources/CheckedMultiSelect.html       |   10 +-
 dojox/form/resources/FilePickerTextBox.css         |    8 +-
 dojox/form/resources/TriStateCheckBox.css          |  137 +
 dojox/form/resources/TriStateCheckBox.html         |    5 +
 dojox/form/resources/Uploader.html                 |   18 +
 dojox/form/resources/_CheckedMultiSelectItem.html  |    6 +-
 .../resources/_CheckedMultiSelectMenuItem.html     |   10 +
 .../resources/images/tristatecheckboxStates.png    |  Bin 0 -> 1458 bytes
 dojox/form/tests/test_BusyButton.html              |   12 +-
 dojox/form/tests/test_CheckedMultiSelect.html      |    2 +-
 .../tests/test_CheckedMultiSelectDropDown.html     |  200 +
 .../tests/test_CheckedMultiSelectNonDropDown.html  |  205 +
 dojox/form/tests/test_DateTextBox.html             |    5 -
 dojox/form/tests/test_FileInput.html               |    5 +-
 dojox/form/tests/test_FilePickerTextBox.html       |    1 +
 dojox/form/tests/test_FileUploaderCSS.html         |  110 +-
 dojox/form/tests/test_FileUploaderDialog.html      |    1 +
 dojox/form/tests/test_FileUploaderForm.html        |    3 +-
 dojox/form/tests/test_FileUploaderTabs.html        |    1 +
 dojox/form/tests/test_ListInput.html               |    2 +-
 dojox/form/tests/test_Manager1.html                |   16 +-
 dojox/form/tests/test_MultiComboBox.html           |    5 +-
 dojox/form/tests/test_PasswordValidator.html       |   71 +-
 dojox/form/tests/test_RangeSlider.html             |    1 +
 dojox/form/tests/test_Rating.html                  |    5 +-
 dojox/form/tests/test_TimeSpinner.html             |    1 +
 dojox/form/tests/test_TriStateCheckbox.html        |  135 +
 dojox/form/tests/test_Uploader.html                |   76 +-
 dojox/form/tests/test_UploaderAll.html             |    1 +
 dojox/form/uploader/Base.js                        |   59 +-
 dojox/form/uploader/FileList.js                    |   63 +-
 dojox/form/uploader/plugins/Flash.js               |   80 +-
 dojox/form/uploader/plugins/HTML5.js               |   88 +-
 dojox/form/uploader/plugins/IFrame.js              |   74 +-
 dojox/fx.js                                        |    6 +-
 dojox/fx/Shadow.js                                 |  288 +-
 dojox/fx/Timeline.js                               |   46 +-
 dojox/fx/_arg.js                                   |   12 +-
 dojox/fx/_base.js                                  |   78 +-
 dojox/fx/_core.js                                  |  114 +-
 dojox/fx/easing.js                                 |   11 +-
 dojox/fx/ext-dojo/NodeList-style.js                |   25 +-
 dojox/fx/ext-dojo/NodeList.js                      |   22 +-
 dojox/fx/ext-dojo/complex.js                       |  198 +-
 dojox/fx/ext-dojo/reverse.js                       |   21 +-
 dojox/fx/flip.js                                   |  191 +-
 dojox/fx/scroll.js                                 |   84 +-
 dojox/fx/split.js                                  |  160 +-
 dojox/fx/style.js                                  |   53 +-
 dojox/fx/tests/example_dojoAnimations.html         |    1 +
 dojox/fx/tests/example_easingChart2D.html          |    2 +-
 dojox/fx/tests/test_Nodelist-fx.html               |    4 +-
 dojox/fx/tests/test_Shadow.html                    |    2 +-
 dojox/fx/tests/test_animateClass.html              |   26 +-
 dojox/fx/tests/test_flip.html                      |  663 +-
 dojox/fx/tests/test_scroll.html                    |    7 +-
 dojox/fx/tests/test_sizeTo.html                    |    1 -
 dojox/fx/tests/test_split.html                     |    3 +-
 dojox/fx/tests/test_wipeTo.html                    |   41 +-
 dojox/fx/text.js                                   |  107 +-
 dojox/gantt/GanttProjectItem.js                    |    1 +
 dojox/gantt/GanttResourceItem.js                   |   53 +-
 dojox/gantt/GanttTaskItem.js                       |    1 +
 dojox/gauges/AnalogArcIndicator.js                 |   92 +
 dojox/gauges/AnalogArrowIndicator.js               |   52 +
 dojox/gauges/AnalogCircleIndicator.js              |   35 +
 dojox/gauges/AnalogGauge.js                        |  368 +
 dojox/gauges/AnalogIndicatorBase.js                |  200 +
 dojox/gauges/AnalogLineIndicator.js                |   29 +
 dojox/gauges/AnalogNeedleIndicator.js              |   46 +
 dojox/gauges/BarCircleIndicator.js                 |   45 +
 dojox/gauges/BarGauge.js                           |  180 +
 dojox/gauges/BarIndicator.js                       |   79 +
 dojox/gauges/BarLineIndicator.js                   |  133 +
 dojox/gauges/GlossyCircularGauge.js                |  236 +
 dojox/gauges/GlossyCircularGaugeBase.js            |  540 +
 dojox/gauges/GlossyCircularGaugeNeedle.js          |   64 +
 dojox/gauges/GlossyHorizontalGauge.js              |  567 +
 dojox/gauges/GlossyHorizontalGaugeMarker.js        |  129 +
 dojox/gauges/GlossySemiCircularGauge.js            |  244 +
 dojox/gauges/Range.js                              |   73 +
 dojox/gauges/TextIndicator.js                      |   78 +
 dojox/gauges/_Gauge.css                            |   63 +
 dojox/gauges/_Gauge.js                             |  844 +
 dojox/gauges/_Indicator.js                         |  260 +
 dojox/gauges/tests/images/flare.png                |  Bin 0 -> 9839 bytes
 dojox/gauges/tests/images/gaugeOverlay.png         |  Bin 0 -> 10675 bytes
 dojox/gauges/tests/test_AnalogGauge-AMD.html       |  284 +
 dojox/gauges/tests/test_AnalogGaugeWidget.html     |  554 +
 .../tests/test_AnalogGaugeWidgetIndicators.html    |  279 +
 .../test_AnalogGaugeWidgetLabelPlacement.html      |   91 +
 .../tests/test_AnalogGaugeWidgetOrientation.html   |  129 +
 dojox/gauges/tests/test_BarGaugeWidget.html        |  340 +
 dojox/gauges/tests/test_GlossyCircularGauge.html   |  300 +
 dojox/gauges/tests/test_GlossyGauges-AMD.html      |   61 +
 dojox/gauges/tests/test_GlossyHorizontalGauge.html |  205 +
 dojox/geo/README                                   |    8 +-
 dojox/geo/charting/Feature.js                      |  198 +
 dojox/geo/charting/KeyboardInteractionSupport.js   |  144 +
 dojox/geo/charting/Map.js                          |  595 +-
 dojox/geo/charting/MouseInteractionSupport.js      |  334 +
 dojox/geo/charting/TouchInteractionSupport.js      |  312 +
 dojox/geo/charting/_Feature.js                     |  169 -
 dojox/geo/charting/_Marker.js                      |   33 +-
 dojox/geo/charting/_base.js                        |   41 +-
 dojox/geo/charting/resources/Map.css               |   10 +-
 dojox/geo/charting/resources/data/USStates.json    |  517 +-
 dojox/geo/charting/resources/data/series.json      |   20 +
 dojox/geo/charting/tests/datastore/dataStore.json  |    2 +-
 dojox/geo/charting/tests/test_mapWithCharting.html |   94 +-
 dojox/geo/charting/tests/test_mapWithLegend.html   |   94 +-
 dojox/geo/charting/tests/test_maps.html            |   40 +-
 dojox/geo/charting/tests/test_widget.html          |   71 +
 dojox/geo/charting/widget/Legend.js                |   68 +-
 dojox/geo/charting/widget/Map.js                   |  181 +
 dojox/geo/openlayers/Collection.js                 |   27 +
 dojox/geo/openlayers/Feature.js                    |   78 +
 dojox/geo/openlayers/Geometry.js                   |   36 +
 dojox/geo/openlayers/GeometryFeature.js            |  404 +
 dojox/geo/openlayers/GfxLayer.js                   |  141 +
 dojox/geo/openlayers/GreatCircle.js                |  121 +
 dojox/geo/openlayers/JsonImport.js                 |  150 +
 dojox/geo/openlayers/Layer.js                      |  163 +
 dojox/geo/openlayers/LineString.js                 |   27 +
 dojox/geo/openlayers/Map.js                        |  591 +
 dojox/geo/openlayers/Patch.js                      |   66 +
 dojox/geo/openlayers/Point.js                      |   26 +
 dojox/geo/openlayers/TouchInteractionSupport.js    |  247 +
 dojox/geo/openlayers/WidgetFeature.js              |  205 +
 .../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/json/ContinentalEurope.json   |  222 +
 dojox/geo/openlayers/tests/json/test_json.html     |   76 +
 .../openlayers/tests/nonWidget/test_nonWidget.html |   51 +
 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         |  282 +
 dojox/geo/openlayers/tests/test_gfx.html           |  165 +
 dojox/geo/openlayers/tests/test_gfx2.html          |  219 +
 dojox/geo/openlayers/tests/test_resize.html        |  145 +
 dojox/geo/openlayers/tests/test_widget.html        |  100 +
 .../tests/widgetFeature/test_widgetFeature.html    |  350 +
 dojox/geo/openlayers/widget/Map.js                 |  160 +
 dojox/gesture/Base.js                              |  371 +
 dojox/gesture/README                               |   39 +
 dojox/gesture/swipe.js                             |  143 +
 dojox/gesture/tap.js                               |  144 +
 dojox/gesture/tests/doh/bubble.html                |  169 +
 dojox/gesture/tests/doh/swipe.html                 |  100 +
 dojox/gesture/tests/doh/tap.html                   |  137 +
 dojox/gesture/tests/module.js                      |    9 +
 dojox/gesture/tests/runTests.html                  |   11 +
 dojox/gesture/tests/test_gesture.html              |   94 +
 dojox/gfx.js                                       |   87 +-
 dojox/gfx/Moveable.js                              |  192 +-
 dojox/gfx/Mover.js                                 |  113 +-
 dojox/gfx/VectorText.js                            |  159 +-
 dojox/gfx/_base.js                                 |  733 +-
 dojox/gfx/_gfxBidiSupport.js                       |  404 +
 dojox/gfx/arc.js                                   |   62 +-
 dojox/gfx/attach.js                                |   15 +-
 dojox/gfx/canvas.js                                |  188 +-
 dojox/gfx/canvasWithEvents.js                      |  642 +
 dojox/gfx/canvas_attach.js                         |   17 +-
 dojox/gfx/decompose.js                             |   26 +-
 dojox/gfx/fx.js                                    |   72 +-
 dojox/gfx/gradient.js                              |   44 +-
 dojox/gfx/gradutils.js                             |   36 +-
 dojox/gfx/matrix.js                                |   40 +-
 dojox/gfx/move.js                                  |    6 +-
 dojox/gfx/path.js                                  |  808 +-
 dojox/gfx/renderer.js                              |   89 +
 dojox/gfx/resources/gfxSvgProxyFrame.html          |    3 +-
 dojox/gfx/resources/svg2gfx.xsl                    |   20 +-
 dojox/gfx/shape.js                                 | 1571 +-
 dojox/gfx/silverlight.js                           |  125 +-
 dojox/gfx/silverlight_attach.js                    |   16 +-
 dojox/gfx/svg.js                                   |  179 +-
 dojox/gfx/svg_attach.js                            |   42 +-
 .../canvas/dynamicallyChangeTextCanvas.html        |   84 +
 .../canvas/inheritFromSurfaceCanvas.html           |  184 +
 .../canvas/test_SurfaceGroupCanvas.html            |  262 +
 .../_gfxBidiSupport/canvas/textBidiCanvas.html     |   67 +
 .../_gfxBidiSupport/dynamicallyChangeText.html     |   84 +
 .../tests/_gfxBidiSupport/inheritFromSurface.html  |  184 +
 dojox/gfx/tests/_gfxBidiSupport/module.js          |   15 +
 dojox/gfx/tests/_gfxBidiSupport/runTests.html      |   11 +
 .../dynamicallyChangeTextSilverlight.html          |   84 +
 .../silverlight/inheritFromSurfaceSilverlight.html |  106 +
 .../silverlight/test_SurfaceGroupSilverlight.html  |  179 +
 .../silverlight/textBidiSilverlight.html           |   69 +
 .../svgWeb/dynamicallyChangeTextSvgWeb.html        |   89 +
 .../svgWeb/inheritFromSurfaceSvgWeb.html           |  192 +
 .../svgWeb/test_SurfaceGroupSvgWeb.html            |  274 +
 .../_gfxBidiSupport/svgWeb/textBidiSvgWeb.html     |   80 +
 .../_gfxBidiSupport/svgWeb/textpathBidiSvgWeb.html |  151 +
 .../tests/_gfxBidiSupport/test_SurfaceGroup.html   |  262 +
 dojox/gfx/tests/_gfxBidiSupport/textBidi.html      |   69 +
 dojox/gfx/tests/_gfxBidiSupport/textpathBidi.html  |  144 +
 dojox/gfx/tests/events-canvas.html                 |   47 +
 dojox/gfx/tests/smokeRenderer.html                 |   21 +
 dojox/gfx/tests/svgweb/sample.html                 |   17 +-
 dojox/gfx/tests/test.roundrect.html                |   37 -
 dojox/gfx/tests/test_arc.html                      |   11 +-
 dojox/gfx/tests/test_bezier.html                   |   11 +-
 dojox/gfx/tests/test_bubbling.html                 |   61 +
 dojox/gfx/tests/test_canvaspolyline.html           |   74 +
 dojox/gfx/tests/test_decompose.html                |    4 +-
 dojox/gfx/tests/test_gfx.html                      |   13 +-
 dojox/gfx/tests/test_gfx_amd.html                  |  457 +
 dojox/gfx/tests/test_group2.html                   |    3 +-
 dojox/gfx/tests/test_linearGradient.html           |   13 +-
 dojox/gfx/tests/test_loadCanvas.html               |   28 +
 dojox/gfx/tests/test_poly.html                     |   11 +-
 dojox/gfx/tests/test_rect_setShape_vml.html        |   37 +
 dojox/gfx/tests/test_registry.html                 |   89 +
 dojox/gfx/tests/test_resize.html                   |   11 +-
 dojox/gfx/tests/test_roundrect.html                |   36 +
 dojox/gfx/tests/test_setPath.html                  |    4 -
 dojox/gfx/tests/test_surfaceClip.html              |   33 +
 dojox/gfx/tests/test_tbbox.html                    |   11 +-
 dojox/gfx/tests/test_utils.html                    |   10 +-
 dojox/gfx/utils.js                                 |  118 +-
 dojox/gfx/vml.js                                   |  205 +-
 dojox/gfx/vml_attach.js                            |   56 +-
 dojox/gfx3d.js                                     |   11 +-
 dojox/gfx3d/_base.js                               |   32 +-
 dojox/gfx3d/gradient.js                            |   17 +-
 dojox/gfx3d/lighting.js                            |   85 +-
 dojox/gfx3d/matrix.js                              |  651 +-
 dojox/gfx3d/object.js                              |  275 +-
 dojox/gfx3d/scheduler.js                           |   62 +-
 dojox/gfx3d/tests/test_camerarotate.html           |    3 -
 dojox/gfx3d/tests/test_camerarotate_shaded.html    |    2 -
 dojox/gfx3d/tests/test_cylinder.html               |    4 +-
 dojox/gfx3d/vector.js                              |   29 +-
 dojox/grid/DataGrid.js                             |   87 +-
 dojox/grid/DataSelection.js                        |   34 +-
 dojox/grid/EnhancedGrid.js                         |   78 +-
 dojox/grid/LazyTreeGrid.js                         | 1073 +-
 dojox/grid/LazyTreeGridStoreModel.js               |   42 +-
 dojox/grid/README                                  |    9 +-
 dojox/grid/Selection.js                            |   32 +-
 dojox/grid/TreeGrid.js                             |  190 +-
 dojox/grid/TreeSelection.js                        |   29 +-
 dojox/grid/_Builder.js                             |  161 +-
 dojox/grid/_CheckBoxSelector.js                    |    6 +-
 dojox/grid/_EditManager.js                         |   43 +-
 dojox/grid/_Events.js                              |   84 +-
 dojox/grid/_FocusManager.js                        |  135 +-
 dojox/grid/_Grid.js                                |  217 +-
 dojox/grid/_Layout.js                              |   47 +-
 dojox/grid/_RadioSelector.js                       |    6 +-
 dojox/grid/_RowManager.js                          |   15 +-
 dojox/grid/_RowSelector.js                         |    9 +-
 dojox/grid/_Scroller.js                            |   38 +-
 dojox/grid/_SelectionPreserver.js                  |   66 +
 dojox/grid/_Selector.js                            |   80 +-
 dojox/grid/_TreeView.js                            |  121 +-
 dojox/grid/_View.js                                |  220 +-
 dojox/grid/_ViewManager.js                         |   24 +-
 dojox/grid/cells.js                                |    5 +-
 dojox/grid/cells/_base.js                          |  151 +-
 dojox/grid/cells/dijit.js                          |  153 +-
 dojox/grid/cells/tree.js                           |   17 +-
 dojox/grid/enhanced/_Events.js                     |   68 +-
 dojox/grid/enhanced/_FocusManager.js               |  160 +-
 dojox/grid/enhanced/_Plugin.js                     |   34 +-
 dojox/grid/enhanced/_PluginManager.js              |   64 +-
 dojox/grid/enhanced/nls/EnhancedGrid.js            |   40 +-
 dojox/grid/enhanced/nls/Filter.js                  |   43 +-
 dojox/grid/enhanced/nls/Pagination.js              |   40 +-
 dojox/grid/enhanced/nls/ar/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/ar/Filter.js               |    6 +-
 dojox/grid/enhanced/nls/ar/Pagination.js           |    7 +-
 dojox/grid/enhanced/nls/ca/EnhancedGrid.js         |   10 +-
 dojox/grid/enhanced/nls/ca/Filter.js               |   14 +-
 dojox/grid/enhanced/nls/ca/Pagination.js           |    9 +-
 dojox/grid/enhanced/nls/cs/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/cs/Filter.js               |   11 +-
 dojox/grid/enhanced/nls/cs/Pagination.js           |   24 +-
 dojox/grid/enhanced/nls/da/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/da/Filter.js               |   11 +-
 dojox/grid/enhanced/nls/da/Pagination.js           |    9 +-
 dojox/grid/enhanced/nls/de/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/de/Filter.js               |   11 +-
 dojox/grid/enhanced/nls/de/Pagination.js           |   14 +-
 dojox/grid/enhanced/nls/el/EnhancedGrid.js         |   10 +-
 dojox/grid/enhanced/nls/el/Filter.js               |   14 +-
 dojox/grid/enhanced/nls/el/Pagination.js           |    9 +-
 dojox/grid/enhanced/nls/es/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/es/Filter.js               |   11 +-
 dojox/grid/enhanced/nls/es/Pagination.js           |    8 +-
 dojox/grid/enhanced/nls/fi/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/fi/Filter.js               |   11 +-
 dojox/grid/enhanced/nls/fi/Pagination.js           |    9 +-
 dojox/grid/enhanced/nls/fr/EnhancedGrid.js         |    6 +-
 dojox/grid/enhanced/nls/fr/Filter.js               |   13 +-
 dojox/grid/enhanced/nls/fr/Pagination.js           |   16 +-
 dojox/grid/enhanced/nls/he/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/he/Filter.js               |    6 +-
 dojox/grid/enhanced/nls/he/Pagination.js           |    7 +-
 dojox/grid/enhanced/nls/hr/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/hr/Filter.js               |   11 +-
 dojox/grid/enhanced/nls/hr/Pagination.js           |    8 +-
 dojox/grid/enhanced/nls/hu/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/hu/Filter.js               |   11 +-
 dojox/grid/enhanced/nls/hu/Pagination.js           |    8 +-
 dojox/grid/enhanced/nls/it/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/it/Filter.js               |   11 +-
 dojox/grid/enhanced/nls/it/Pagination.js           |   20 +-
 dojox/grid/enhanced/nls/ja/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/ja/Filter.js               |    9 +-
 dojox/grid/enhanced/nls/ja/Pagination.js           |   10 +-
 dojox/grid/enhanced/nls/kk/EnhancedGrid.js         |   14 +-
 dojox/grid/enhanced/nls/kk/Filter.js               |   14 +-
 dojox/grid/enhanced/nls/kk/Pagination.js           |    9 +-
 dojox/grid/enhanced/nls/ko/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/ko/Filter.js               |   11 +-
 dojox/grid/enhanced/nls/ko/Pagination.js           |   20 +-
 dojox/grid/enhanced/nls/nb/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/nb/Filter.js               |   11 +-
 dojox/grid/enhanced/nls/nb/Pagination.js           |    9 +-
 dojox/grid/enhanced/nls/nl/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/nl/Filter.js               |   11 +-
 dojox/grid/enhanced/nls/nl/Pagination.js           |   16 +-
 dojox/grid/enhanced/nls/pl/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/pl/Filter.js               |   11 +-
 dojox/grid/enhanced/nls/pl/Pagination.js           |   20 +-
 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      |   10 +-
 dojox/grid/enhanced/nls/pt-pt/Filter.js            |    9 +-
 dojox/grid/enhanced/nls/pt-pt/Pagination.js        |    7 +-
 dojox/grid/enhanced/nls/pt/EnhancedGrid.js         |   10 +-
 dojox/grid/enhanced/nls/pt/Filter.js               |   35 +-
 dojox/grid/enhanced/nls/pt/Pagination.js           |    8 +-
 dojox/grid/enhanced/nls/ro/EnhancedGrid.js         |   12 +-
 dojox/grid/enhanced/nls/ro/Filter.js               |   13 +-
 dojox/grid/enhanced/nls/ro/Pagination.js           |    9 +-
 dojox/grid/enhanced/nls/ru/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/ru/Filter.js               |   11 +-
 dojox/grid/enhanced/nls/ru/Pagination.js           |   12 +-
 dojox/grid/enhanced/nls/sk/EnhancedGrid.js         |   18 +-
 dojox/grid/enhanced/nls/sk/Filter.js               |   11 +-
 dojox/grid/enhanced/nls/sk/Pagination.js           |    9 +-
 dojox/grid/enhanced/nls/sl/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/sl/Filter.js               |   11 +-
 dojox/grid/enhanced/nls/sl/Pagination.js           |    8 +-
 dojox/grid/enhanced/nls/sv/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/sv/Filter.js               |   11 +-
 dojox/grid/enhanced/nls/sv/Pagination.js           |    9 +-
 dojox/grid/enhanced/nls/th/EnhancedGrid.js         |   10 +-
 dojox/grid/enhanced/nls/th/Filter.js               |   14 +-
 dojox/grid/enhanced/nls/th/Pagination.js           |    9 +-
 dojox/grid/enhanced/nls/tr/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/tr/Filter.js               |   11 +-
 dojox/grid/enhanced/nls/tr/Pagination.js           |    9 +-
 dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js      |    4 +
 dojox/grid/enhanced/nls/zh-tw/Filter.js            |   11 +-
 dojox/grid/enhanced/nls/zh-tw/Pagination.js        |   16 +-
 dojox/grid/enhanced/nls/zh/EnhancedGrid.js         |    4 +
 dojox/grid/enhanced/nls/zh/Filter.js               |   11 +-
 dojox/grid/enhanced/nls/zh/Pagination.js           |   12 +-
 dojox/grid/enhanced/plugins/AutoScroll.js          |   46 +-
 dojox/grid/enhanced/plugins/CellMerge.js           |   57 +-
 dojox/grid/enhanced/plugins/Cookie.js              |  138 +-
 dojox/grid/enhanced/plugins/Dialog.js              |   55 +-
 dojox/grid/enhanced/plugins/DnD.js                 |  591 +-
 dojox/grid/enhanced/plugins/Exporter.js            |   65 +-
 dojox/grid/enhanced/plugins/Filter.js              |   68 +-
 dojox/grid/enhanced/plugins/GridSource.js          |   30 +-
 dojox/grid/enhanced/plugins/IndirectSelection.js   |  280 +-
 dojox/grid/enhanced/plugins/Menu.js                |   45 +-
 dojox/grid/enhanced/plugins/NestedSorting.js       |  238 +-
 dojox/grid/enhanced/plugins/Pagination.js          | 1637 +-
 dojox/grid/enhanced/plugins/Printer.js             |  145 +-
 dojox/grid/enhanced/plugins/Rearrange.js           |  122 +-
 dojox/grid/enhanced/plugins/Search.js              |   53 +-
 dojox/grid/enhanced/plugins/Selector.js            |  257 +-
 dojox/grid/enhanced/plugins/_RowMapLayer.js        |   20 +-
 dojox/grid/enhanced/plugins/_SelectionPreserver.js |   83 +-
 dojox/grid/enhanced/plugins/_StoreLayer.js         |   49 +-
 dojox/grid/enhanced/plugins/exporter/CSVWriter.js  |   28 +-
 .../grid/enhanced/plugins/exporter/TableWriter.js  |   72 +-
 .../enhanced/plugins/exporter/_ExportWriter.js     |    9 +-
 .../enhanced/plugins/filter/ClearFilterConfirm.js  |   28 +-
 dojox/grid/enhanced/plugins/filter/FilterBar.js    |  128 +-
 .../grid/enhanced/plugins/filter/FilterBuilder.js  |   46 +-
 .../enhanced/plugins/filter/FilterDefDialog.js     | 1790 +-
 dojox/grid/enhanced/plugins/filter/FilterLayer.js  |   72 +-
 .../enhanced/plugins/filter/FilterStatusTip.js     |   88 +-
 .../grid/enhanced/plugins/filter/_ConditionExpr.js |   63 +-
 dojox/grid/enhanced/plugins/filter/_DataExprs.js   |   34 +-
 dojox/grid/enhanced/plugins/filter/_FilterExpr.js  |  111 +-
 dojox/grid/enhanced/resources/Common.css           |   15 +-
 dojox/grid/enhanced/resources/Filter.css           |    2 +-
 dojox/grid/enhanced/resources/Filter_rtl.css       |    4 +
 dojox/grid/enhanced/resources/Pagination.css       |    9 +
 dojox/grid/enhanced/resources/Pagination_rtl.css   |    2 +-
 dojox/grid/enhanced/resources/Sorter.css           |    3 +-
 dojox/grid/enhanced/resources/claro/Common.css     |   75 +-
 dojox/grid/enhanced/resources/claro/Filter.css     |    1 -
 .../grid/enhanced/resources/claroEnhancedGrid.css  |    2 +
 .../enhanced/resources/images/sprite_icons.png     |  Bin 2836 -> 2912 bytes
 .../grid/enhanced/resources/tundraEnhancedGrid.css |    2 +
 .../grid/enhanced/templates/FilterStatusPane.html  |   15 +-
 dojox/grid/enhanced/templates/Pagination.html      |   31 +-
 dojox/grid/resources/claroGrid.css                 |   72 +-
 dojox/grid/tests/databaseModel.js                  |  333 -
 .../tests/enhanced/test_enhanced_grid_cookie.html  |    1 +
 .../test_enhanced_grid_leak_with_plugin.html       |    3 +-
 .../enhanced/test_enhanced_grid_pagination.html    |   65 +-
 .../tests/enhanced/test_enhanced_grid_plugins.html |    5 +-
 dojox/grid/tests/robot/7815.html                   |    2 +-
 dojox/grid/tests/robot/DataGrid_a11y.html          |    2 +-
 dojox/grid/tests/robot/DataGrid_mouse.html         |    4 +-
 dojox/grid/tests/support/test_data.js              |    1 +
 dojox/grid/tests/support/yahoo_search.js           |    2 +-
 dojox/grid/tests/test_data_grid.html               |    2 +-
 dojox/grid/tests/test_data_grid_hideHdr.html       |    4 +-
 dojox/grid/tests/test_grid_colspan_resize.html     |    1 -
 dojox/grid/tests/test_grid_tooltip_menu.html       |    3 -
 dojox/grid/tests/test_treegrid_lazyloading.html    |  117 +-
 dojox/grid/tests/test_treegrid_performance.html    |    6 +-
 dojox/grid/util.js                                 |   16 +-
 dojox/highlight.js                                 |    5 +-
 dojox/highlight/_base.js                           |   44 +-
 dojox/highlight/languages/_all.js                  |    7 +-
 dojox/highlight/languages/_dynamic.js              |   10 +-
 dojox/highlight/languages/_static.js               |    9 +-
 dojox/highlight/languages/_www.js                  |    9 +-
 dojox/highlight/languages/cpp.js                   |   12 +-
 dojox/highlight/languages/css.js                   |   17 +-
 dojox/highlight/languages/delphi.js                |   10 +-
 dojox/highlight/languages/django.js                |   12 +-
 dojox/highlight/languages/groovy.js                |   10 +-
 dojox/highlight/languages/html.js                  |   11 +-
 dojox/highlight/languages/java.js                  |    9 +-
 dojox/highlight/languages/javascript.js            |    9 +-
 dojox/highlight/languages/pygments/_html.js        |   40 +-
 dojox/highlight/languages/pygments/_www.js         |    9 +-
 dojox/highlight/languages/pygments/css.js          |   10 +-
 dojox/highlight/languages/pygments/html.js         |   11 +-
 dojox/highlight/languages/pygments/javascript.js   |    9 +-
 dojox/highlight/languages/pygments/xml.js          |  139 +-
 dojox/highlight/languages/python.js                |  190 +-
 dojox/highlight/languages/sql.js                   |    9 +-
 dojox/highlight/languages/xml.js                   |   12 +-
 dojox/highlight/languages/xquery.js                |   14 +-
 dojox/highlight/tests/test_highlight.html          |   71 +-
 dojox/highlight/widget/Code.js                     |  182 +-
 dojox/html.js                                      |    7 +-
 dojox/html/_base.js                                |  100 +-
 dojox/html/ellipsis.js                             |   30 +-
 dojox/html/entities.js                             |   24 +-
 dojox/html/ext-dojo/style.js                       |  864 +-
 dojox/html/format.js                               |  869 +-
 dojox/html/metrics.js                              |   50 +-
 dojox/html/styles.js                               |  195 +-
 dojox/html/tests/test_metrics.html                 |    1 -
 dojox/html/tests/test_metrics_getTextBox.html      |    1 -
 dojox/html/tests/test_set.html                     |    5 +-
 dojox/html/tests/test_styles.html                  |   53 +-
 dojox/html/tests/test_themes.html                  |    3 +
 dojox/image.js                                     |   10 +-
 dojox/image/Badge.js                               |  428 +-
 dojox/image/FlickrBadge.js                         |  183 +-
 dojox/image/Lightbox.js                            | 1148 +-
 dojox/image/LightboxNano.js                        |    5 +-
 dojox/image/Magnifier.js                           |  123 +-
 dojox/image/MagnifierLite.js                       |  253 +-
 dojox/image/SlideShow.js                           |   21 +-
 dojox/image/ThumbnailPicker.js                     |    8 +-
 dojox/image/_base.js                               |   23 +-
 dojox/image/tests/test_Badge.html                  |   20 +-
 dojox/image/tests/test_FlickrBadge.html            |   14 +-
 dojox/image/tests/test_Gallery.html                |   28 +-
 dojox/image/tests/test_Lightbox.html               |   24 +-
 dojox/image/tests/test_Magnifier.html              |   12 +-
 dojox/image/tests/test_MagnifierLite.html          |   19 +-
 dojox/image/tests/test_SlideShow.html              |   10 +-
 dojox/io/OAuth.js                                  |   23 +-
 dojox/io/httpParse.js                              |   10 +-
 dojox/io/proxy/tests/xip.html                      |   64 +-
 dojox/io/proxy/xip.js                              |   18 +-
 dojox/io/scriptFrame.js                            |   21 +-
 dojox/io/tests/scriptFrame.html                    |    9 +-
 dojox/io/tests/scriptFrame.js                      |    4 +-
 dojox/io/tests/scriptFrameRepeat.html              |   43 +-
 dojox/io/tests/windowName.html                     |   64 +-
 dojox/io/tests/windowName.js                       |   18 +-
 dojox/io/tests/xhrMultiPart.html                   |   73 +-
 dojox/io/tests/xhrPlugins.js                       |   26 +-
 dojox/io/windowName.js                             |   28 +-
 dojox/io/xhrMultiPart.js                           |   21 +-
 dojox/io/xhrPlugins.js                             |   15 +-
 dojox/io/xhrScriptPlugin.js                        |   17 +-
 dojox/io/xhrWindowNamePlugin.js                    |   26 +-
 dojox/json/query.js                                |   21 +-
 dojox/json/ref.js                                  |    9 +-
 dojox/json/schema.js                               |    6 +-
 dojox/json/tests/query.js                          |    8 +
 dojox/lang/functional.js                           |    8 +-
 dojox/lang/functional/array.js                     |   37 +-
 dojox/lang/functional/fold.js                      |   29 +-
 dojox/lang/functional/lambda.js                    |   14 +-
 dojox/lang/functional/object.js                    |   22 +-
 dojox/lang/functional/reversed.js                  |   28 +-
 dojox/lang/functional/scan.js                      |   13 +-
 dojox/lang/functional/sequence.js                  |   19 +-
 dojox/lang/utils.js                                |   23 +-
 dojox/layout/ContentPane.js                        |   35 +-
 dojox/layout/DragPane.js                           |   18 +-
 dojox/layout/ExpandoPane.js                        |   99 +-
 dojox/layout/FloatingPane.js                       |  129 +-
 dojox/layout/GridContainer.js                      | 1094 +-
 dojox/layout/GridContainerLite.js                  | 1464 +-
 dojox/layout/RadioGroup.js                         |   86 +-
 dojox/layout/ResizeHandle.js                       |  162 +-
 dojox/layout/RotatorContainer.js                   |   87 +-
 dojox/layout/ScrollPane.js                         |   52 +-
 dojox/layout/TableContainer.js                     |   63 +-
 dojox/layout/ToggleSplitter.js                     |  341 +-
 dojox/layout/resources/FloatingPane.css            |    2 +-
 dojox/layout/resources/ToggleSplitter.css          |  118 +-
 dojox/layout/resources/icons/splitterToggleH.png   |  Bin 0 -> 2937 bytes
 dojox/layout/resources/icons/splitterToggleV.png   |  Bin 0 -> 2938 bytes
 dojox/layout/tests/ContentPane.html                |    6 +-
 dojox/layout/tests/remote/getResponse.php          |    4 +-
 dojox/layout/tests/test_ExpandoPane.html           |    3 -
 dojox/layout/tests/test_ExpandoPane_more.html      |    2 +-
 dojox/layout/tests/test_ExpandoPane_prog.html      |    1 -
 dojox/layout/tests/test_FloatingPane.html          |    3 -
 dojox/layout/tests/test_GridContainer.html         |    2 -
 .../layout/tests/test_GridContainerColWidths.html  |    2 -
 .../tests/test_GridContainer_TitlePanes.html       |    1 -
 ...test_GridContainer_in_BorderContainer_prog.html |   24 +-
 dojox/layout/tests/test_ResizeHandle.html          |    3 +-
 dojox/layout/tests/test_RotatorContainer.html      |    1 +
 dojox/layout/tests/test_ScrollPane.html            |    3 -
 dojox/layout/tests/test_ScrollPaneSingle.html      |    5 +-
 dojox/layout/tests/test_TableContainer.html        |    3 -
 dojox/layout/tests/test_ToggleSplitter.html        |  118 +-
 dojox/layout/tests/test_TouchStackContainer.html   |   11 +-
 dojox/main.js                                      |    8 +
 dojox/math/BigInteger-ext.js                       |    8 +-
 dojox/math/BigInteger.js                           |   10 +-
 dojox/math/_base.js                                |    6 +-
 dojox/math/random/Simple.js                        |   41 +-
 dojox/math/random/prng4.js                         |    9 +-
 dojox/math/round.js                                |  103 +-
 dojox/math/stats.js                                |    9 +-
 dojox/mdnd/AreaManager.js                          | 1341 +-
 dojox/mdnd/AutoScroll.js                           |  385 +-
 dojox/mdnd/DropIndicator.js                        |  150 +-
 dojox/mdnd/LazyManager.js                          |  130 +-
 dojox/mdnd/Moveable.js                             |  481 +-
 dojox/mdnd/PureSource.js                           |  400 +-
 dojox/mdnd/adapter/DndFromDojo.js                  |  686 +-
 dojox/mdnd/adapter/DndToDojo.js                    |  895 +-
 dojox/mdnd/dropMode/DefaultDropMode.js             |  616 +-
 dojox/mdnd/dropMode/OverDropMode.js                |  566 +-
 dojox/mdnd/dropMode/VerticalDropMode.js            |  620 +-
 dojox/mdnd/tests/module.js                         |    8 -
 dojox/mdnd/tests/robot/test_dnd_acceptance.html    |  149 +-
 .../mdnd/tests/robot/test_dnd_defaultDropMode.html |    8 +-
 dojox/mdnd/tests/robot/test_dnd_dndFromDojo.html   |  168 +-
 dojox/mdnd/tests/robot/test_dnd_dndToDojo.html     |  106 +-
 dojox/mdnd/tests/robot/test_dnd_overDropMode.html  |  140 +-
 .../tests/robot/test_dnd_verticalDropMode.html     |    8 +-
 .../unitTests/dropMode/resources/domElement.html   |   65 -
 dojox/mobile.js                                    |   12 +-
 dojox/mobile/Button.js                             |   77 +
 dojox/mobile/Carousel.js                           |  322 +
 dojox/mobile/CheckBox.js                           |   35 +
 dojox/mobile/ComboBox.js                           |  224 +
 dojox/mobile/ContentPane.js                        |  125 +
 dojox/mobile/EdgeToEdgeCategory.js                 |   23 +
 dojox/mobile/EdgeToEdgeDataList.js                 |   24 +
 dojox/mobile/EdgeToEdgeList.js                     |   28 +
 dojox/mobile/ExpandingTextArea.js                  |   27 +
 dojox/mobile/FixedSplitter.js                      |  188 +-
 dojox/mobile/FixedSplitterPane.js                  |   40 +
 dojox/mobile/FlippableView.js                      |  138 +-
 dojox/mobile/Heading.js                            |  266 +
 dojox/mobile/IconContainer.js                      |  459 +-
 dojox/mobile/IconItem.js                           |  331 +
 dojox/mobile/ListItem.js                           |  375 +
 dojox/mobile/Opener.js                             |   73 +
 dojox/mobile/Overlay.js                            |   95 +
 dojox/mobile/PageIndicator.js                      |  104 +
 dojox/mobile/ProgressIndicator.js                  |  111 +
 dojox/mobile/README                                |    6 +-
 dojox/mobile/RadioButton.js                        |   20 +
 dojox/mobile/RoundRect.js                          |   48 +
 dojox/mobile/RoundRectCategory.js                  |   40 +
 dojox/mobile/RoundRectDataList.js                  |   24 +
 dojox/mobile/RoundRectList.js                      |   99 +
 dojox/mobile/ScrollableView.js                     |  227 +-
 dojox/mobile/Slider.js                             |  163 +
 dojox/mobile/SpinWheel.js                          |   97 +
 dojox/mobile/SpinWheelDatePicker.js                |  109 +
 dojox/mobile/SpinWheelSlot.js                      |  327 +
 dojox/mobile/SpinWheelTimePicker.js                |   57 +
 dojox/mobile/SwapView.js                           |  228 +
 dojox/mobile/Switch.js                             |  222 +
 dojox/mobile/TabBar.js                             |  330 +-
 dojox/mobile/TabBarButton.js                       |  231 +
 dojox/mobile/TabContainer.js                       |  151 -
 dojox/mobile/TextArea.js                           |   39 +
 dojox/mobile/TextBox.js                            |   41 +
 dojox/mobile/ToggleButton.js                       |   25 +
 dojox/mobile/ToolBarButton.js                      |  107 +
 dojox/mobile/Tooltip.js                            |   99 +
 dojox/mobile/TransitionEvent.js                    |   35 +
 dojox/mobile/View.js                               |  512 +
 dojox/mobile/ViewController.js                     |  263 +
 dojox/mobile/_ComboBoxMenu.js                      |   81 +
 dojox/mobile/_DataListMixin.js                     |  133 +
 dojox/mobile/_ItemBase.js                          |  248 +
 dojox/mobile/_ListTouchMixin.js                    |   32 +
 dojox/mobile/_ScrollableMixin.js                   |  168 +-
 dojox/mobile/_base.js                              | 1227 +-
 dojox/mobile/_compat.js                            |  544 +
 dojox/mobile/app.js                                |    8 +-
 dojox/mobile/app/TextBox.js                        |  319 +-
 dojox/mobile/app/_FormWidget.js                    |    1 +
 dojox/mobile/app/_base.js                          |    7 +-
 dojox/mobile/app/_event.js                         |    4 +-
 dojox/mobile/build/build.bat                       |   35 +-
 dojox/mobile/build/build.sh                        |   29 +-
 dojox/mobile/common.js                             |  496 +
 dojox/mobile/compat.js                             |  476 +-
 dojox/mobile/deviceTheme.js                        |  188 +
 dojox/mobile/i18n.js                               |   46 +
 dojox/mobile/mobile-all.js                         |   47 +
 dojox/mobile/parser.js                             |  172 +-
 dojox/mobile/scrollable.js                         |  868 +-
 dojox/mobile/sniff.js                              |   31 +
 dojox/mobile/tests/carousel-categ.json             |    8 +
 dojox/mobile/tests/carousel-dish.json              |   13 +
 dojox/mobile/tests/carousel-glass.json             |   20 +
 dojox/mobile/tests/carousel-shell.json             |   15 +
 dojox/mobile/tests/carousel-stone.json             |   14 +
 .../app/assistants/main-assistant.js               |    1 -
 dojox/mobile/tests/complexListApp/index.html       |   20 +-
 .../dialogApp/app/assistants/main-assistant.js     |    1 -
 .../tests/dialogApp/app/views/main/main-scene.html |    4 +-
 dojox/mobile/tests/dialogApp/index.html            |    6 +-
 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/EdgeToEdgeCatagory.js       |   71 +
 dojox/mobile/tests/doh/EdgeToEdgeCategory.html     |   41 +
 dojox/mobile/tests/doh/EdgeToEdgeDataList.html     |  155 +
 .../tests/doh/EdgeToEdgeDataList_Programmatic.html |  157 +
 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/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 +
 .../tests/doh/IconContainer_Programmatic.html      |  148 +
 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/RoundRect.html              |   69 +
 dojox/mobile/tests/doh/RoundRectDataList.html      |   71 +
 dojox/mobile/tests/doh/RoundRectDataList.js        |   55 +
 .../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/TestUtil.js                 |   83 +
 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 +
 dojox/mobile/tests/doh/index.html                  |   47 +
 dojox/mobile/tests/doh/module.js                   |   42 +
 dojox/mobile/tests/doh/progress-indicator.html     |   45 +
 dojox/mobile/tests/doh/runTests.html               |    9 +
 dojox/mobile/tests/doh/settings.json               |   14 +
 dojox/mobile/tests/doh/topHeading_defect.html      |   60 +
 dojox/mobile/tests/fragment1.html                  |    3 +
 .../flickr-image-thumb-view-assistant.js           |   12 +-
 .../app/assistants/flickr-image-view-assistant.js  |    9 +-
 .../assistants/flickr-search-group-assistant.js    |    1 -
 .../flickr-search-selection-assistant.js           |    1 -
 .../app/assistants/flickr-search-text-assistant.js |    1 -
 .../app/assistants/image-view-assistant.js         |    1 -
 .../app/assistants/main-assistant.js               |    1 -
 .../flickr-image-thumb-view-scene.html             |    2 +-
 .../flickr-search-group-scene.html                 |    2 +-
 .../flickr-search-group-scene.html                 |    2 +-
 dojox/mobile/tests/imageControlsApp/index.html     |    8 +-
 dojox/mobile/tests/images/a-icon-3.png             |  Bin 1346 -> 1509 bytes
 dojox/mobile/tests/images/a-icon-all.png           |  Bin 0 -> 14620 bytes
 dojox/mobile/tests/images/a-icon1.png              |  Bin 0 -> 1919 bytes
 dojox/mobile/tests/images/a-icon10.png             |  Bin 0 -> 2091 bytes
 dojox/mobile/tests/images/a-icon2.png              |  Bin 0 -> 2118 bytes
 dojox/mobile/tests/images/a-icon3.png              |  Bin 0 -> 2157 bytes
 dojox/mobile/tests/images/a-icon4.png              |  Bin 0 -> 2088 bytes
 dojox/mobile/tests/images/a-icon5.png              |  Bin 0 -> 2041 bytes
 dojox/mobile/tests/images/a-icon6.png              |  Bin 0 -> 2015 bytes
 dojox/mobile/tests/images/a-icon7.png              |  Bin 0 -> 2078 bytes
 dojox/mobile/tests/images/a-icon8.png              |  Bin 0 -> 2106 bytes
 dojox/mobile/tests/images/a-icon9.png              |  Bin 0 -> 2127 bytes
 dojox/mobile/tests/images/b-app-icon-1.png         |  Bin 0 -> 1296 bytes
 dojox/mobile/tests/images/b-app-icon-2.png         |  Bin 0 -> 1325 bytes
 dojox/mobile/tests/images/b-app-icon-3.png         |  Bin 0 -> 1306 bytes
 dojox/mobile/tests/images/b-app-icon-4.png         |  Bin 0 -> 1301 bytes
 dojox/mobile/tests/images/b-app-icon-5.png         |  Bin 0 -> 1288 bytes
 dojox/mobile/tests/images/b-app-icon-6.png         |  Bin 0 -> 1323 bytes
 dojox/mobile/tests/images/b-app-icon-7.png         |  Bin 0 -> 1299 bytes
 dojox/mobile/tests/images/b-app-icon-8.png         |  Bin 0 -> 1315 bytes
 dojox/mobile/tests/images/b-icon-1.png             |  Bin 0 -> 933 bytes
 dojox/mobile/tests/images/b-icon-2.png             |  Bin 0 -> 936 bytes
 dojox/mobile/tests/images/b-icon-3.png             |  Bin 0 -> 934 bytes
 dojox/mobile/tests/images/b-icon-4.png             |  Bin 0 -> 926 bytes
 dojox/mobile/tests/images/b-icon-5.png             |  Bin 0 -> 948 bytes
 dojox/mobile/tests/images/b-icon-6.png             |  Bin 0 -> 946 bytes
 dojox/mobile/tests/images/b-icon-7.png             |  Bin 0 -> 915 bytes
 dojox/mobile/tests/images/b-icon-8.png             |  Bin 0 -> 960 bytes
 dojox/mobile/tests/images/chart.png                |  Bin 0 -> 17937 bytes
 .../tests/images/checkboxRadioButtonStates.png     |  Bin 0 -> 3438 bytes
 dojox/mobile/tests/images/dish1.jpg                |  Bin 0 -> 6043 bytes
 dojox/mobile/tests/images/dish2.jpg                |  Bin 0 -> 4532 bytes
 dojox/mobile/tests/images/dish3.jpg                |  Bin 0 -> 4853 bytes
 dojox/mobile/tests/images/dish4.jpg                |  Bin 0 -> 5655 bytes
 dojox/mobile/tests/images/dish5.jpg                |  Bin 0 -> 3350 bytes
 dojox/mobile/tests/images/dish6.jpg                |  Bin 0 -> 5542 bytes
 dojox/mobile/tests/images/dish7.jpg                |  Bin 0 -> 4302 bytes
 dojox/mobile/tests/images/dish8.jpg                |  Bin 0 -> 5550 bytes
 dojox/mobile/tests/images/dish9.jpg                |  Bin 0 -> 3867 bytes
 dojox/mobile/tests/images/glass1.jpg               |  Bin 0 -> 8903 bytes
 dojox/mobile/tests/images/glass10.jpg              |  Bin 0 -> 5881 bytes
 dojox/mobile/tests/images/glass11.jpg              |  Bin 0 -> 4192 bytes
 dojox/mobile/tests/images/glass12.jpg              |  Bin 0 -> 4299 bytes
 dojox/mobile/tests/images/glass13.jpg              |  Bin 0 -> 5958 bytes
 dojox/mobile/tests/images/glass14.jpg              |  Bin 0 -> 4522 bytes
 dojox/mobile/tests/images/glass15.jpg              |  Bin 0 -> 6524 bytes
 dojox/mobile/tests/images/glass16.jpg              |  Bin 0 -> 7113 bytes
 dojox/mobile/tests/images/glass2.jpg               |  Bin 0 -> 6121 bytes
 dojox/mobile/tests/images/glass3.jpg               |  Bin 0 -> 7914 bytes
 dojox/mobile/tests/images/glass4.jpg               |  Bin 0 -> 3703 bytes
 dojox/mobile/tests/images/glass5.jpg               |  Bin 0 -> 7167 bytes
 dojox/mobile/tests/images/glass6.jpg               |  Bin 0 -> 4836 bytes
 dojox/mobile/tests/images/glass7.jpg               |  Bin 0 -> 6716 bytes
 dojox/mobile/tests/images/glass8.jpg               |  Bin 0 -> 6203 bytes
 dojox/mobile/tests/images/glass9.jpg               |  Bin 0 -> 4452 bytes
 dojox/mobile/tests/images/icon-all.png             |  Bin 0 -> 24738 bytes
 dojox/mobile/tests/images/icon1.png                |  Bin 0 -> 2542 bytes
 dojox/mobile/tests/images/icon10.png               |  Bin 0 -> 2720 bytes
 dojox/mobile/tests/images/icon2.png                |  Bin 0 -> 2830 bytes
 dojox/mobile/tests/images/icon3.png                |  Bin 0 -> 2858 bytes
 dojox/mobile/tests/images/icon4.png                |  Bin 0 -> 2749 bytes
 dojox/mobile/tests/images/icon5.png                |  Bin 0 -> 2841 bytes
 dojox/mobile/tests/images/icon6.png                |  Bin 0 -> 2641 bytes
 dojox/mobile/tests/images/icon7.png                |  Bin 0 -> 2818 bytes
 dojox/mobile/tests/images/icon8.png                |  Bin 0 -> 2724 bytes
 dojox/mobile/tests/images/icon9.png                |  Bin 0 -> 2701 bytes
 dojox/mobile/tests/images/pic1.jpg                 |  Bin 0 -> 267196 bytes
 dojox/mobile/tests/images/pic10.jpg                |  Bin 0 -> 270933 bytes
 dojox/mobile/tests/images/pic2.jpg                 |  Bin 0 -> 255957 bytes
 dojox/mobile/tests/images/pic3.jpg                 |  Bin 0 -> 260893 bytes
 dojox/mobile/tests/images/pic4.jpg                 |  Bin 0 -> 262508 bytes
 dojox/mobile/tests/images/pic5.jpg                 |  Bin 0 -> 307923 bytes
 dojox/mobile/tests/images/pic6.jpg                 |  Bin 0 -> 254583 bytes
 dojox/mobile/tests/images/pic7.jpg                 |  Bin 0 -> 323165 bytes
 dojox/mobile/tests/images/pic8.jpg                 |  Bin 0 -> 296657 bytes
 dojox/mobile/tests/images/pic9.jpg                 |  Bin 0 -> 277204 bytes
 dojox/mobile/tests/images/shell1.jpg               |  Bin 0 -> 8172 bytes
 dojox/mobile/tests/images/shell10.jpg              |  Bin 0 -> 3071 bytes
 dojox/mobile/tests/images/shell11.jpg              |  Bin 0 -> 4010 bytes
 dojox/mobile/tests/images/shell2.jpg               |  Bin 0 -> 3075 bytes
 dojox/mobile/tests/images/shell3.jpg               |  Bin 0 -> 3006 bytes
 dojox/mobile/tests/images/shell4.jpg               |  Bin 0 -> 5282 bytes
 dojox/mobile/tests/images/shell5.jpg               |  Bin 0 -> 4584 bytes
 dojox/mobile/tests/images/shell6.jpg               |  Bin 0 -> 5445 bytes
 dojox/mobile/tests/images/shell7.jpg               |  Bin 0 -> 5113 bytes
 dojox/mobile/tests/images/shell8.jpg               |  Bin 0 -> 6273 bytes
 dojox/mobile/tests/images/shell9.jpg               |  Bin 0 -> 8676 bytes
 dojox/mobile/tests/images/stone1.jpg               |  Bin 0 -> 7537 bytes
 dojox/mobile/tests/images/stone10.jpg              |  Bin 0 -> 6310 bytes
 dojox/mobile/tests/images/stone2.jpg               |  Bin 0 -> 3830 bytes
 dojox/mobile/tests/images/stone3.jpg               |  Bin 0 -> 5431 bytes
 dojox/mobile/tests/images/stone4.jpg               |  Bin 0 -> 4616 bytes
 dojox/mobile/tests/images/stone5.jpg               |  Bin 0 -> 6573 bytes
 dojox/mobile/tests/images/stone6.jpg               |  Bin 0 -> 3869 bytes
 dojox/mobile/tests/images/stone7.jpg               |  Bin 0 -> 6667 bytes
 dojox/mobile/tests/images/stone8.jpg               |  Bin 0 -> 3109 bytes
 dojox/mobile/tests/images/stone9.jpg               |  Bin 0 -> 2578 bytes
 dojox/mobile/tests/images/tab-icon-10w.png         |  Bin 0 -> 320 bytes
 dojox/mobile/tests/images/tab-icon-11w.png         |  Bin 0 -> 317 bytes
 dojox/mobile/tests/images/tab-icon-12w.png         |  Bin 0 -> 605 bytes
 dojox/mobile/tests/images/tab-icon-13w.png         |  Bin 0 -> 272 bytes
 dojox/mobile/tests/images/tab-icon-14w.png         |  Bin 0 -> 599 bytes
 dojox/mobile/tests/images/tab-icon-15w.png         |  Bin 0 -> 786 bytes
 dojox/mobile/tests/images/tab-icon-16w.png         |  Bin 0 -> 576 bytes
 dojox/mobile/tests/images/tab-icon-17w.png         |  Bin 0 -> 924 bytes
 dojox/mobile/tests/images/tab-icon-18w.png         |  Bin 0 -> 840 bytes
 dojox/mobile/tests/images/tab-icon-19.png          |  Bin 0 -> 810 bytes
 dojox/mobile/tests/images/tab-icon-19h.png         |  Bin 0 -> 910 bytes
 dojox/mobile/tests/images/tab-icon-19w.png         |  Bin 0 -> 782 bytes
 dojox/mobile/tests/images/tab-icon-20.png          |  Bin 0 -> 241 bytes
 dojox/mobile/tests/images/tab-icon-20h.png         |  Bin 0 -> 241 bytes
 dojox/mobile/tests/images/tab-icon-20w.png         |  Bin 0 -> 236 bytes
 dojox/mobile/tests/images/tab-icon-21.png          |  Bin 0 -> 855 bytes
 dojox/mobile/tests/images/tab-icon-21h.png         |  Bin 0 -> 571 bytes
 dojox/mobile/tests/images/tab-icon-21w.png         |  Bin 0 -> 702 bytes
 dojox/mobile/tests/images/tab-icon-22.png          |  Bin 0 -> 874 bytes
 dojox/mobile/tests/images/tab-icon-22h.png         |  Bin 0 -> 859 bytes
 dojox/mobile/tests/images/tab-icon-22w.png         |  Bin 0 -> 673 bytes
 dojox/mobile/tests/images/tab-icon-23.png          |  Bin 0 -> 897 bytes
 dojox/mobile/tests/images/tab-icon-23h.png         |  Bin 0 -> 953 bytes
 dojox/mobile/tests/images/tab-icon-23w.png         |  Bin 0 -> 869 bytes
 dojox/mobile/tests/images/tab-icon-24.png          |  Bin 0 -> 1022 bytes
 dojox/mobile/tests/images/tab-icon-24h.png         |  Bin 0 -> 1057 bytes
 dojox/mobile/tests/images/tab-icon-24w.png         |  Bin 0 -> 936 bytes
 dojox/mobile/tests/images/tab-icon-25.png          |  Bin 0 -> 1029 bytes
 dojox/mobile/tests/images/tab-icon-25h.png         |  Bin 0 -> 1051 bytes
 dojox/mobile/tests/images/tab-icon-25w.png         |  Bin 0 -> 944 bytes
 dojox/mobile/tests/images/tab-icon-26.png          |  Bin 0 -> 909 bytes
 dojox/mobile/tests/images/tab-icon-26h.png         |  Bin 0 -> 943 bytes
 dojox/mobile/tests/images/tab-icon-26w.png         |  Bin 0 -> 732 bytes
 dojox/mobile/tests/images/tab-icon-27.png          |  Bin 0 -> 1359 bytes
 dojox/mobile/tests/images/tab-icon-27h.png         |  Bin 0 -> 1346 bytes
 dojox/mobile/tests/images/tab-icon-27w.png         |  Bin 0 -> 1090 bytes
 dojox/mobile/tests/images/tab-icon-28.png          |  Bin 0 -> 1391 bytes
 dojox/mobile/tests/images/tab-icon-28h.png         |  Bin 0 -> 1377 bytes
 dojox/mobile/tests/images/tab-icon-28w.png         |  Bin 0 -> 1153 bytes
 dojox/mobile/tests/images/tab-icon-29.png          |  Bin 0 -> 794 bytes
 dojox/mobile/tests/images/tab-icon-29h.png         |  Bin 0 -> 805 bytes
 dojox/mobile/tests/images/tab-icon-29w.png         |  Bin 0 -> 628 bytes
 dojox/mobile/tests/images/tab-icon-30.png          |  Bin 0 -> 939 bytes
 dojox/mobile/tests/images/tab-icon-30h.png         |  Bin 0 -> 985 bytes
 dojox/mobile/tests/images/tab-icon-30w.png         |  Bin 0 -> 763 bytes
 dojox/mobile/tests/images/tab-icon-31.png          |  Bin 0 -> 1250 bytes
 dojox/mobile/tests/images/tab-icon-31h.png         |  Bin 0 -> 1269 bytes
 dojox/mobile/tests/images/tab-icon-31w.png         |  Bin 0 -> 1021 bytes
 dojox/mobile/tests/images/tab-icon-32.png          |  Bin 0 -> 639 bytes
 dojox/mobile/tests/images/tab-icon-32h.png         |  Bin 0 -> 637 bytes
 dojox/mobile/tests/images/tab-icon-32w.png         |  Bin 0 -> 433 bytes
 dojox/mobile/tests/images/tab-icon-33.png          |  Bin 0 -> 311 bytes
 dojox/mobile/tests/images/tab-icon-33h.png         |  Bin 0 -> 319 bytes
 dojox/mobile/tests/images/tab-icon-33w.png         |  Bin 0 -> 345 bytes
 dojox/mobile/tests/images/tab-icon-34.png          |  Bin 0 -> 208 bytes
 dojox/mobile/tests/images/tab-icon-34h.png         |  Bin 0 -> 228 bytes
 dojox/mobile/tests/images/tab-icon-34w.png         |  Bin 0 -> 202 bytes
 dojox/mobile/tests/images/tab-icon-35.png          |  Bin 0 -> 452 bytes
 dojox/mobile/tests/images/tab-icon-35h.png         |  Bin 0 -> 456 bytes
 dojox/mobile/tests/images/tab-icon-35w.png         |  Bin 0 -> 444 bytes
 dojox/mobile/tests/images/tab-icon-36.png          |  Bin 0 -> 986 bytes
 dojox/mobile/tests/images/tab-icon-36h.png         |  Bin 0 -> 967 bytes
 dojox/mobile/tests/images/tab-icon-36w.png         |  Bin 0 -> 928 bytes
 dojox/mobile/tests/images/tab-icon-37.png          |  Bin 0 -> 638 bytes
 dojox/mobile/tests/images/tab-icon-37h.png         |  Bin 0 -> 743 bytes
 dojox/mobile/tests/images/tab-icon-37w.png         |  Bin 0 -> 673 bytes
 dojox/mobile/tests/images/tab-icon-38.png          |  Bin 0 -> 666 bytes
 dojox/mobile/tests/images/tab-icon-38h.png         |  Bin 0 -> 690 bytes
 dojox/mobile/tests/images/tab-icon-38w.png         |  Bin 0 -> 687 bytes
 dojox/mobile/tests/index.html                      |  113 +-
 .../app/assistants/text-input-assistant.js         |    1 -
 .../app/views/text-input/text-input-scene.html     |   14 +-
 dojox/mobile/tests/inputApp/index.html             |    8 +-
 dojox/mobile/tests/insurance-car-coverage.html     |    6 +
 dojox/mobile/tests/insurance-car-safe.html         |    6 +
 dojox/mobile/tests/insurance-car.json              |    6 +
 dojox/mobile/tests/insurance-life-child.html       |    6 +
 dojox/mobile/tests/insurance-life-long.html        |    6 +
 dojox/mobile/tests/insurance-life.json             |    6 +
 dojox/mobile/tests/insurance-sports-boat.html      |    6 +
 dojox/mobile/tests/insurance-sports-moto.html      |    6 +
 dojox/mobile/tests/insurance-sports-snow.html      |    6 +
 dojox/mobile/tests/insurance-sports.json           |    7 +
 dojox/mobile/tests/insurance.json                  |    7 +
 dojox/mobile/tests/module.js                       |   12 +
 .../multiSceneApp/app/assistants/main-assistant.js |    3 +-
 .../app/assistants/second-assistant.js             |    4 +-
 .../app/assistants/third-assistant.js              |    2 -
 dojox/mobile/tests/multiSceneApp/index.html        |    6 +-
 dojox/mobile/tests/nls/it/sample.js                |   11 +
 dojox/mobile/tests/nls/ja/sample.js                |   13 +
 dojox/mobile/tests/nls/sample.js                   |   14 +
 dojox/mobile/tests/progressBarAnim.gif             |  Bin 0 -> 4458 bytes
 dojox/mobile/tests/robot/Animation.html            |   62 +
 dojox/mobile/tests/robot/Animation2.html           |   62 +
 dojox/mobile/tests/robot/ButtonList.html           |   50 +
 dojox/mobile/tests/robot/ButtonList2.html          |   50 +
 dojox/mobile/tests/robot/Flippable.html            |   56 +
 dojox/mobile/tests/robot/Icon.html                 |   50 +
 dojox/mobile/tests/robot/Icon2.html                |   50 +
 dojox/mobile/tests/robot/ListItem.html             |   47 +
 dojox/mobile/tests/robot/ScrollableView.html       |   54 +
 dojox/mobile/tests/robot/ScrollableView2.html      |   54 +
 dojox/mobile/tests/robot/ScrollableView3.html      |   54 +
 dojox/mobile/tests/robot/Settings.html             |  119 +
 dojox/mobile/tests/robot/Switch.html               |   50 +
 dojox/mobile/tests/robot/Switch2.html              |   50 +
 dojox/mobile/tests/robot/TabBar.html               |   65 +
 dojox/mobile/tests/robot/TabBar2.html              |   65 +
 dojox/mobile/tests/robot/module.js                 |   28 +
 dojox/mobile/tests/robot/runTests.html             |    9 +
 dojox/mobile/tests/runTests.html                   |    9 +
 dojox/mobile/tests/settings.json                   |   14 +
 .../simpleApp/app/assistants/main-assistant.js     |    1 -
 dojox/mobile/tests/simpleApp/index.html            |    6 +-
 .../simpleListApp/app/assistants/main-assistant.js |    1 -
 dojox/mobile/tests/simpleListApp/index.html        |    6 +-
 dojox/mobile/tests/sliderHthumb.png                |  Bin 0 -> 346 bytes
 dojox/mobile/tests/sliderVthumb.png                |  Bin 0 -> 338 bytes
 dojox/mobile/tests/test_Accessibility_Support.html |  116 +
 dojox/mobile/tests/test_Android-ButtonList.html    |   48 +-
 dojox/mobile/tests/test_Android-EdgeToEdge.html    |   12 +-
 .../tests/test_Android-EdgeToEdgeCategory.html     |   11 +-
 dojox/mobile/tests/test_Android-Heading.html       |   86 +-
 dojox/mobile/tests/test_Android-Icon.html          |   13 +-
 dojox/mobile/tests/test_Android-RoundRectList.html |   11 +-
 dojox/mobile/tests/test_Android-Settings.html      |   21 +-
 dojox/mobile/tests/test_Android-Switch.html        |   71 +-
 dojox/mobile/tests/test_Android-TabBar.html        |   19 +-
 dojox/mobile/tests/test_Android-TabContainer.html  |  144 -
 .../tests/test_Android-VariableHeightList.html     |   12 +-
 dojox/mobile/tests/test_Animation.html             |   79 +
 .../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_Carousel-async.html        |   58 +
 dojox/mobile/tests/test_Carousel-slideshow.html    |   40 +
 dojox/mobile/tests/test_Carousel.html              |   49 +
 dojox/mobile/tests/test_ComboBox.html              |  212 +
 dojox/mobile/tests/test_ContentPane.html           |   50 +
 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_EdgeToEdgeDataList.html    |   64 +
 dojox/mobile/tests/test_EdgeToEdgeList-check.html  |   66 +
 dojox/mobile/tests/test_FixedSplitter-H2-prog.html |   27 +-
 dojox/mobile/tests/test_FixedSplitter-H2.html      |    8 +-
 dojox/mobile/tests/test_FixedSplitter-V2H2.html    |   12 +-
 dojox/mobile/tests/test_FixedSplitter-V3.html      |   10 +-
 dojox/mobile/tests/test_FormControls.html          |  173 +
 .../tests/test_Opener-ActionSheet-async.html       |   91 +
 dojox/mobile/tests/test_Opener-Calendar-async.html |   65 +
 .../tests/test_Opener-ColorPalette-async.html      |   59 +
 dojox/mobile/tests/test_Opener-ColorPicker.html    |   58 +
 .../tests/test_Opener-DateSpinWheel-async.html     |   63 +
 .../tests/test_Opener-RoundSelectList-async.html   |  158 +
 .../mobile/tests/test_Opener-SearchList-async.html |  130 +
 dojox/mobile/tests/test_Overlay.html               |   86 +
 dojox/mobile/tests/test_RoundRectDataList.html     |   67 +
 dojox/mobile/tests/test_RoundRectList-check.html   |   65 +
 .../mobile/tests/test_ScrollableMixin-custom.html  |   59 +-
 dojox/mobile/tests/test_Slider.html                |  491 +
 dojox/mobile/tests/test_SpinWheel-1slot.html       |   28 +
 dojox/mobile/tests/test_SpinWheel-custom.html      |   70 +
 dojox/mobile/tests/test_SpinWheel-icons.html       |   76 +
 .../mobile/tests/test_SpinWheelDatePicker-sv.html  |  101 +
 dojox/mobile/tests/test_SpinWheelDatePicker.html   |   38 +
 dojox/mobile/tests/test_SpinWheelTimePicker.html   |   39 +
 dojox/mobile/tests/test_Switch-setter.html         |   43 +
 dojox/mobile/tests/test_Tooltip.html               |  117 +
 dojox/mobile/tests/test_ajax-html.html             |   11 +-
 dojox/mobile/tests/test_ajax-json.html             |   11 +-
 dojox/mobile/tests/test_anchor-label.html          |   11 +-
 dojox/mobile/tests/test_bookmarkable.html          |   13 +-
 dojox/mobile/tests/test_buttons.html               |   21 -
 dojox/mobile/tests/test_css-sprite.html            |   13 +-
 dojox/mobile/tests/test_domButtons.html            |   85 +
 .../tests/test_dynamic-ScrollableView-ah-af.html   |   32 +-
 .../tests/test_dynamic-ScrollableView-vh-vf.html   |   13 +-
 dojox/mobile/tests/test_dynamic-icons.html         |   23 +-
 dojox/mobile/tests/test_dynamic-items.html         |   32 +-
 dojox/mobile/tests/test_dynamic-view.html          |   13 +-
 .../tests/test_grouped-scrollable-views.html       |   14 +-
 dojox/mobile/tests/test_grouped-views.html         |   12 +-
 dojox/mobile/tests/test_hash-parameter.html        |   13 +-
 dojox/mobile/tests/test_html-form-controls.html    |   67 +
 dojox/mobile/tests/test_html-inputs.html           |   55 +
 dojox/mobile/tests/test_i18n.html                  |   82 +
 dojox/mobile/tests/test_iPad-Heading.html          |  124 +
 dojox/mobile/tests/test_iPad-Settings-async.html   |  241 +
 dojox/mobile/tests/test_iPad-Settings.html         |   25 +-
 dojox/mobile/tests/test_iPad-TabBar.html           |   66 +
 .../mobile/tests/test_iPhone-Animation-async.html  |   81 +
 dojox/mobile/tests/test_iPhone-Animation.html      |   12 +-
 dojox/mobile/tests/test_iPhone-Button.html         |   21 +-
 dojox/mobile/tests/test_iPhone-ButtonList.html     |   37 +-
 dojox/mobile/tests/test_iPhone-EdgeToEdge.html     |   16 +-
 .../tests/test_iPhone-EdgeToEdgeCategory.html      |   11 +-
 dojox/mobile/tests/test_iPhone-FlippableView.html  |   83 -
 dojox/mobile/tests/test_iPhone-Heading.html        |   58 +-
 dojox/mobile/tests/test_iPhone-Icon-sprite.html    |   62 +
 dojox/mobile/tests/test_iPhone-Icon.html           |   18 +-
 dojox/mobile/tests/test_iPhone-IconMulti.html      |   31 +-
 dojox/mobile/tests/test_iPhone-IconSingle.html     |   22 +-
 .../mobile/tests/test_iPhone-IconSingleBelow.html  |   22 +-
 dojox/mobile/tests/test_iPhone-ResultList.html     |   11 +-
 dojox/mobile/tests/test_iPhone-RoundRect.html      |   11 +-
 dojox/mobile/tests/test_iPhone-RoundRectList.html  |   11 +-
 .../test_iPhone-ScrollableView-demo-async.html     |  393 +
 .../test_iPhone-ScrollableView-demo-long.html      |  389 +
 .../tests/test_iPhone-ScrollableView-demo.html     |    5 +-
 .../mobile/tests/test_iPhone-ScrollableView-h.html |   13 +-
 .../tests/test_iPhone-ScrollableView-hv-ah-af.html |   13 +-
 .../tests/test_iPhone-ScrollableView-hv-vh-vf.html |   13 +-
 .../tests/test_iPhone-ScrollableView-hv.html       |   13 +-
 .../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  |   40 +-
 .../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  |   40 +-
 .../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  |   40 +-
 .../tests/test_iPhone-ScrollableView-v-vh.html     |   40 +-
 .../mobile/tests/test_iPhone-ScrollableView-v.html |   41 +-
 dojox/mobile/tests/test_iPhone-Settings.html       |   11 +-
 .../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         |   71 +-
 .../test_iPhone-TabBar-seg-grouped-scroll.html     |   15 +-
 .../tests/test_iPhone-TabBar-seg-grouped.html      |   13 +-
 dojox/mobile/tests/test_iPhone-TabBar-seg.html     |   13 +-
 dojox/mobile/tests/test_iPhone-TabBar.html         |   14 +-
 dojox/mobile/tests/test_iPhone-TabContainer.html   |  174 -
 .../tests/test_iPhone-VariableHeightList.html      |   11 +-
 dojox/mobile/tests/test_list-actions.html          |  225 +
 dojox/mobile/tests/test_list-domButtons.html       |  227 +
 .../test_new_transition-animations-standard.html   |   85 +
 .../tests/test_new_transition-animations.html      |   65 +
 .../tests/test_new_transition-animations2.html     |  260 +
 .../mobile/tests/test_orientation-transition.html  |   47 +-
 dojox/mobile/tests/test_progress-indicator.html    |   32 +-
 .../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 |   36 +-
 .../tests/test_scrollable-no-dojo-ah-af.html       |   39 +-
 dojox/mobile/tests/test_scrollable-no-dojo-ah.html |   41 +-
 dojox/mobile/tests/test_scrollable-no-dojo.html    |   39 +-
 .../test_transition-animations-extended1.html      |   66 +
 .../test_transition-animations-extended2.html      |   85 +
 .../test_transition-animations-extended3.html      |   85 +
 .../test_transition-animations-extended4.html      |   73 +
 .../test_transition-animations-extended5.html      |   59 +
 .../tests/test_transition-animations-standard.html |   73 +
 dojox/mobile/tests/test_transition-animations.html |   65 +
 .../mobile/tests/test_transition-animations2.html  |  258 +
 dojox/mobile/tests/test_transition-connect.html    |   68 +
 dojox/mobile/tests/test_transition-pubsub.html     |   67 +
 .../tests/test_transition-to-dynamic-view.html     |   83 +-
 dojox/mobile/themes/android/Button-compat.css      |   33 +
 dojox/mobile/themes/android/Button.css             |   45 +
 dojox/mobile/themes/android/Button.less            |    2 +
 dojox/mobile/themes/android/Carousel.css           |   60 +
 dojox/mobile/themes/android/Carousel.less          |    2 +
 dojox/mobile/themes/android/CheckBox-compat.css    |   37 +
 dojox/mobile/themes/android/CheckBox.css           |   44 +
 dojox/mobile/themes/android/CheckBox.less          |    2 +
 dojox/mobile/themes/android/ComboBox-compat.css    |    7 +
 dojox/mobile/themes/android/ComboBox.css           |   45 +
 dojox/mobile/themes/android/ComboBox.less          |    2 +
 dojox/mobile/themes/android/EdgeToEdgeCategory.css |   18 +
 .../mobile/themes/android/EdgeToEdgeCategory.less  |    2 +
 dojox/mobile/themes/android/EdgeToEdgeList.css     |   12 +
 dojox/mobile/themes/android/EdgeToEdgeList.less    |    2 +
 dojox/mobile/themes/android/Heading-compat.css     |   22 +
 dojox/mobile/themes/android/Heading.css            |   81 +
 dojox/mobile/themes/android/Heading.less           |    2 +
 .../mobile/themes/android/IconContainer-compat.css |   11 +
 dojox/mobile/themes/android/IconContainer.css      |   99 +
 dojox/mobile/themes/android/IconContainer.less     |    5 +
 dojox/mobile/themes/android/ListItem-compat.css    |   26 +
 dojox/mobile/themes/android/ListItem.css           |   84 +
 dojox/mobile/themes/android/ListItem.less          |    5 +
 dojox/mobile/themes/android/Opener-compat.css      |    3 +
 dojox/mobile/themes/android/Opener.css             |    7 +
 dojox/mobile/themes/android/Overlay-compat.css     |   13 +
 dojox/mobile/themes/android/Overlay.css            |   18 +
 dojox/mobile/themes/android/Overlay.less           |    5 +
 dojox/mobile/themes/android/PageIndicator.css      |   24 +
 dojox/mobile/themes/android/PageIndicator.less     |    2 +
 .../themes/android/ProgressIndicator-compat.css    |   46 +
 dojox/mobile/themes/android/ProgressIndicator.css  |   58 +
 dojox/mobile/themes/android/ProgressIndicator.less |    2 +
 dojox/mobile/themes/android/RadioButton-compat.css |   33 +
 dojox/mobile/themes/android/RadioButton.css        |   41 +
 dojox/mobile/themes/android/RadioButton.less       |    2 +
 dojox/mobile/themes/android/RoundRect-compat.css   |   64 +
 dojox/mobile/themes/android/RoundRect.css          |   13 +
 dojox/mobile/themes/android/RoundRect.less         |    2 +
 dojox/mobile/themes/android/RoundRectCategory.css  |   10 +
 dojox/mobile/themes/android/RoundRectCategory.less |    2 +
 .../mobile/themes/android/RoundRectList-compat.css |   64 +
 dojox/mobile/themes/android/RoundRectList.css      |   25 +
 dojox/mobile/themes/android/RoundRectList.less     |    2 +
 dojox/mobile/themes/android/Slider-compat.css      |   43 +
 dojox/mobile/themes/android/Slider.css             |   62 +
 dojox/mobile/themes/android/Slider.less            |    2 +
 dojox/mobile/themes/android/Switch-compat.css      |   70 +
 dojox/mobile/themes/android/Switch.css             |   18 +
 dojox/mobile/themes/android/Switch.less            |    4 +
 dojox/mobile/themes/android/TabBar-compat.css      |   35 +
 dojox/mobile/themes/android/TabBar.css             |  158 +
 dojox/mobile/themes/android/TabBar.less            |    2 +
 dojox/mobile/themes/android/TextArea-compat.css    |    7 +
 dojox/mobile/themes/android/TextArea.css           |   14 +
 dojox/mobile/themes/android/TextArea.less          |    2 +
 dojox/mobile/themes/android/TextBox-compat.css     |    7 +
 dojox/mobile/themes/android/TextBox.css            |    8 +
 dojox/mobile/themes/android/TextBox.less           |    2 +
 .../mobile/themes/android/ToggleButton-compat.css  |   30 +
 dojox/mobile/themes/android/ToggleButton.css       |   52 +
 dojox/mobile/themes/android/ToggleButton.less      |    2 +
 dojox/mobile/themes/android/ToolBarButton.css      |   31 +
 dojox/mobile/themes/android/ToolBarButton.less     |    2 +
 dojox/mobile/themes/android/Tooltip-compat.css     |   47 +
 dojox/mobile/themes/android/Tooltip.css            |  144 +
 dojox/mobile/themes/android/Tooltip.less           |    2 +
 dojox/mobile/themes/android/View.css               |   24 +
 dojox/mobile/themes/android/View.less              |    6 +
 dojox/mobile/themes/android/android-app-compat.css |    2 +-
 dojox/mobile/themes/android/android-app.css        |   20 +-
 dojox/mobile/themes/android/android-compat.css     |  308 +-
 dojox/mobile/themes/android/android.css            |  862 +-
 dojox/mobile/themes/android/base-compat.css        |    7 +
 dojox/mobile/themes/android/base.css               |   12 +
 dojox/mobile/themes/android/common.css             |   27 +
 dojox/mobile/themes/android/common.less            |    2 +
 .../themes/android/compat/blue-button-sel-bg.png   |  Bin 182 -> 0 bytes
 dojox/mobile/themes/android/compat/button-bg.png   |  Bin 0 -> 169 bytes
 .../mobile/themes/android/compat/button-sel-bg.png |  Bin 0 -> 156 bytes
 .../mobile/themes/android/compat/red-button-bg.png |  Bin 0 -> 248 bytes
 .../themes/android/compat/slider-h-bar-bg.png      |  Bin 0 -> 124 bytes
 dojox/mobile/themes/android/compat/slider-h-bg.png |  Bin 0 -> 135 bytes
 .../themes/android/compat/slider-handle-bg.png     |  Bin 0 -> 156 bytes
 .../mobile/themes/android/compat/switch-arc-l.gif  |  Bin 0 -> 958 bytes
 .../mobile/themes/android/compat/switch-arc-r.gif  |  Bin 0 -> 1047 bytes
 .../mobile/themes/android/compat/switch-arc1-k.gif |  Bin 0 -> 500 bytes
 .../mobile/themes/android/compat/switch-arc2-k.gif |  Bin 0 -> 554 bytes
 .../themes/android/compat/switch-blue-bg.png       |  Bin 199 -> 0 bytes
 .../themes/android/compat/switch-default-k.gif     |  Bin 0 -> 313 bytes
 .../themes/android/compat/switch-default-l.gif     |  Bin 0 -> 550 bytes
 .../themes/android/compat/switch-default-r.gif     |  Bin 0 -> 557 bytes
 .../themes/android/compat/switch-gray-bg.png       |  Bin 183 -> 0 bytes
 .../themes/android/compat/switch-green-bg.png      |  Bin 161 -> 0 bytes
 .../themes/android/compat/switch-knob-bg.png       |  Bin 174 -> 0 bytes
 .../themes/android/compat/switch-round-l.gif       |  Bin 0 -> 978 bytes
 .../themes/android/compat/switch-round-r.gif       |  Bin 0 -> 1106 bytes
 .../themes/android/compat/switch-round1-k.gif      |  Bin 0 -> 720 bytes
 .../themes/android/compat/switch-round2-k.gif      |  Bin 0 -> 785 bytes
 .../themes/android/compat/togglebutton-chk-bg.png  |  Bin 0 -> 154 bytes
 dojox/mobile/themes/android/variables.less         |  737 +
 dojox/mobile/themes/blackberry/Button-compat.css   |   33 +
 dojox/mobile/themes/blackberry/Button.css          |   45 +
 dojox/mobile/themes/blackberry/Button.less         |    2 +
 dojox/mobile/themes/blackberry/Carousel.css        |   60 +
 dojox/mobile/themes/blackberry/Carousel.less       |    2 +
 dojox/mobile/themes/blackberry/CheckBox-compat.css |   34 +
 dojox/mobile/themes/blackberry/CheckBox.css        |   44 +
 dojox/mobile/themes/blackberry/CheckBox.less       |    2 +
 dojox/mobile/themes/blackberry/ComboBox-compat.css |   17 +
 dojox/mobile/themes/blackberry/ComboBox.css        |   44 +
 dojox/mobile/themes/blackberry/ComboBox.less       |    2 +
 .../themes/blackberry/EdgeToEdgeCategory.css       |   18 +
 .../themes/blackberry/EdgeToEdgeCategory.less      |    2 +
 dojox/mobile/themes/blackberry/EdgeToEdgeList.css  |   12 +
 dojox/mobile/themes/blackberry/EdgeToEdgeList.less |    2 +
 dojox/mobile/themes/blackberry/Heading-compat.css  |   25 +
 dojox/mobile/themes/blackberry/Heading.css         |   83 +
 dojox/mobile/themes/blackberry/Heading.less        |    2 +
 .../themes/blackberry/IconContainer-compat.css     |   11 +
 dojox/mobile/themes/blackberry/IconContainer.css   |   97 +
 dojox/mobile/themes/blackberry/IconContainer.less  |    5 +
 dojox/mobile/themes/blackberry/ListItem-compat.css |   26 +
 dojox/mobile/themes/blackberry/ListItem.css        |   86 +
 dojox/mobile/themes/blackberry/ListItem.less       |    5 +
 dojox/mobile/themes/blackberry/Opener-compat.css   |    3 +
 dojox/mobile/themes/blackberry/Opener.css          |    3 +
 dojox/mobile/themes/blackberry/Overlay-compat.css  |   13 +
 dojox/mobile/themes/blackberry/Overlay.css         |   18 +
 dojox/mobile/themes/blackberry/Overlay.less        |    5 +
 dojox/mobile/themes/blackberry/PageIndicator.css   |   24 +
 dojox/mobile/themes/blackberry/PageIndicator.less  |    2 +
 .../themes/blackberry/ProgressIndicator-compat.css |   46 +
 .../mobile/themes/blackberry/ProgressIndicator.css |   58 +
 .../themes/blackberry/ProgressIndicator.less       |    2 +
 .../themes/blackberry/RadioButton-compat.css       |   33 +
 dojox/mobile/themes/blackberry/RadioButton.css     |   41 +
 dojox/mobile/themes/blackberry/RadioButton.less    |    2 +
 .../mobile/themes/blackberry/RoundRect-compat.css  |   64 +
 dojox/mobile/themes/blackberry/RoundRect.css       |   13 +
 dojox/mobile/themes/blackberry/RoundRect.less      |    2 +
 .../mobile/themes/blackberry/RoundRectCategory.css |   20 +
 .../themes/blackberry/RoundRectCategory.less       |    2 +
 .../themes/blackberry/RoundRectList-compat.css     |   64 +
 dojox/mobile/themes/blackberry/RoundRectList.css   |   39 +
 dojox/mobile/themes/blackberry/RoundRectList.less  |    2 +
 dojox/mobile/themes/blackberry/Slider-compat.css   |   43 +
 dojox/mobile/themes/blackberry/Slider.css          |   62 +
 dojox/mobile/themes/blackberry/Slider.less         |    2 +
 dojox/mobile/themes/blackberry/Switch-compat.css   |   70 +
 dojox/mobile/themes/blackberry/Switch.css          |   18 +
 dojox/mobile/themes/blackberry/Switch.less         |    4 +
 dojox/mobile/themes/blackberry/TabBar-compat.css   |   49 +
 dojox/mobile/themes/blackberry/TabBar.css          |  164 +
 dojox/mobile/themes/blackberry/TabBar.less         |    2 +
 dojox/mobile/themes/blackberry/TextArea-compat.css |    7 +
 dojox/mobile/themes/blackberry/TextArea.css        |   14 +
 dojox/mobile/themes/blackberry/TextArea.less       |    2 +
 dojox/mobile/themes/blackberry/TextBox-compat.css  |    7 +
 dojox/mobile/themes/blackberry/TextBox.css         |    8 +
 dojox/mobile/themes/blackberry/TextBox.less        |    2 +
 .../themes/blackberry/ToggleButton-compat.css      |   31 +
 dojox/mobile/themes/blackberry/ToggleButton.css    |   52 +
 dojox/mobile/themes/blackberry/ToggleButton.less   |    2 +
 dojox/mobile/themes/blackberry/ToolBarButton.css   |   27 +
 dojox/mobile/themes/blackberry/ToolBarButton.less  |    2 +
 dojox/mobile/themes/blackberry/Tooltip-compat.css  |   47 +
 dojox/mobile/themes/blackberry/Tooltip.css         |  143 +
 dojox/mobile/themes/blackberry/Tooltip.less        |    2 +
 dojox/mobile/themes/blackberry/View.css            |   24 +
 dojox/mobile/themes/blackberry/View.less           |    6 +
 dojox/mobile/themes/blackberry/base-compat.css     |    7 +
 dojox/mobile/themes/blackberry/base.css            |   12 +
 .../mobile/themes/blackberry/blackberry-compat.css |   18 +
 dojox/mobile/themes/blackberry/blackberry.css      |   22 +
 dojox/mobile/themes/blackberry/common.css          |   29 +
 dojox/mobile/themes/blackberry/common.less         |    2 +
 .../themes/blackberry/compat/arrow-button-bg.png   |  Bin 0 -> 129 bytes
 .../themes/blackberry/compat/arrow-button-head.gif |  Bin 0 -> 430 bytes
 .../themes/blackberry/compat/blue-button-bg.png    |  Bin 0 -> 199 bytes
 .../mobile/themes/blackberry/compat/button-bg.png  |  Bin 0 -> 177 bytes
 .../themes/blackberry/compat/button-sel-bg.png     |  Bin 0 -> 201 bytes
 .../mobile/themes/blackberry/compat/gray-arrow.png |  Bin 0 -> 920 bytes
 .../mobile/themes/blackberry/compat/heading-bg.png |  Bin 0 -> 109 bytes
 .../blackberry/compat/icon-content-heading-bg.png  |  Bin 0 -> 193 bytes
 .../themes/blackberry/compat/red-button-bg.png     |  Bin 0 -> 248 bytes
 .../themes/blackberry/compat/slider-h-bar-bg.png   |  Bin 0 -> 133 bytes
 .../themes/blackberry/compat/slider-h-bg.png       |  Bin 0 -> 133 bytes
 .../themes/blackberry/compat/slider-handle-bg.png  |  Bin 0 -> 165 bytes
 .../themes/blackberry/compat/switch-arc-l.gif      |  Bin 0 -> 1024 bytes
 .../themes/blackberry/compat/switch-arc-r.gif      |  Bin 0 -> 820 bytes
 .../themes/blackberry/compat/switch-arc1-k.gif     |  Bin 0 -> 497 bytes
 .../themes/blackberry/compat/switch-arc2-k.gif     |  Bin 0 -> 550 bytes
 .../themes/blackberry/compat/switch-default-k.gif  |  Bin 0 -> 533 bytes
 .../themes/blackberry/compat/switch-default-l.gif  |  Bin 0 -> 742 bytes
 .../themes/blackberry/compat/switch-default-r.gif  |  Bin 0 -> 699 bytes
 .../themes/blackberry/compat/switch-round-l.gif    |  Bin 0 -> 1014 bytes
 .../themes/blackberry/compat/switch-round-r.gif    |  Bin 0 -> 865 bytes
 .../themes/blackberry/compat/switch-round1-k.gif   |  Bin 0 -> 710 bytes
 .../themes/blackberry/compat/switch-round2-k.gif   |  Bin 0 -> 782 bytes
 .../themes/blackberry/compat/tab-button-bg.png     |  Bin 0 -> 277 bytes
 .../blackberry/compat/tab-orange-button-bg.png     |  Bin 0 -> 197 bytes
 .../themes/blackberry/compat/tab-sel-button-bg.png |  Bin 0 -> 286 bytes
 .../blackberry/images/thumb-overlay-large.png      |  Bin 0 -> 3697 bytes
 .../blackberry/images/thumb-overlay-small.png      |  Bin 0 -> 1549 bytes
 .../themes/blackberry/images/thumb-overlay.png     |  Bin 0 -> 2010 bytes
 dojox/mobile/themes/blackberry/variables.less      |  763 +
 dojox/mobile/themes/buttons-compat.css             |   30 -
 dojox/mobile/themes/buttons.css                    |  191 -
 dojox/mobile/themes/common/Button.less             |   29 +
 dojox/mobile/themes/common/Carousel.less           |   58 +
 dojox/mobile/themes/common/CheckBox.less           |   25 +
 dojox/mobile/themes/common/ComboBox.less           |   40 +
 dojox/mobile/themes/common/EdgeToEdgeCategory.less |    8 +
 dojox/mobile/themes/common/EdgeToEdgeList.less     |    8 +
 dojox/mobile/themes/{ => common}/FixedSplitter.css |    0
 dojox/mobile/themes/common/Heading.less            |   58 +
 dojox/mobile/themes/common/IconContainer.less      |   79 +
 .../themes/common/IconContainer_keyframes.css      |   48 +
 dojox/mobile/themes/common/ListItem.less           |   78 +
 dojox/mobile/themes/common/Overlay.less            |   15 +
 dojox/mobile/themes/common/PageIndicator.less      |   24 +
 dojox/mobile/themes/common/ProgressIndicator.less  |   58 +
 dojox/mobile/themes/common/RadioButton.less        |   23 +
 dojox/mobile/themes/common/RoundRect.less          |    7 +
 dojox/mobile/themes/common/RoundRectCategory.less  |    7 +
 dojox/mobile/themes/common/RoundRectList.less      |   17 +
 dojox/mobile/themes/common/Slider.less             |   47 +
 dojox/mobile/themes/common/SpinWheel-compat.css    |   36 +
 dojox/mobile/themes/common/SpinWheel.css           |   77 +
 dojox/mobile/themes/common/Switch.css              |  224 +
 dojox/mobile/themes/common/Switch.less             |   16 +
 dojox/mobile/themes/common/TabBar.less             |  147 +
 dojox/mobile/themes/common/TextArea.less           |    9 +
 dojox/mobile/themes/common/TextBox.less            |    4 +
 dojox/mobile/themes/common/ToggleButton.less       |   28 +
 dojox/mobile/themes/common/ToolBarButton.less      |   22 +
 dojox/mobile/themes/common/Tooltip.less            |  131 +
 dojox/mobile/themes/common/View.less               |   21 +
 dojox/mobile/themes/common/common.less             |   24 +
 .../mobile/themes/common/compat/spinwheel-bar.png  |  Bin 0 -> 182 bytes
 dojox/mobile/themes/common/compat/spinwheel-bg.png |  Bin 0 -> 532 bytes
 dojox/mobile/themes/common/compile.js              |   42 +
 .../mobile/themes/common/dijit/Calendar-compat.css |    9 +
 dojox/mobile/themes/common/dijit/Calendar.css      |  135 +
 dojox/mobile/themes/common/dijit/ColorPalette.css  |   18 +
 dojox/mobile/themes/common/dijit/ColorPicker.css   |   12 +
 dojox/mobile/themes/common/dijit/base.css          |   15 +
 .../common/dijit/compat/calendar-daylabel-bg.png   |  Bin 0 -> 130 bytes
 .../common/dijit/compat/calendar-month-bg.png      |  Bin 0 -> 185 bytes
 .../common/dijit/compat/calendar-year-bg.png       |  Bin 0 -> 177 bytes
 dojox/mobile/themes/common/dijit/dijit-compat.css  |    1 +
 dojox/mobile/themes/common/dijit/dijit.css         |    4 +
 dojox/mobile/themes/common/domButtons-compat.css   |   38 +
 dojox/mobile/themes/common/domButtons.css          |   42 +
 .../DomButtonBlackCircleCross-compat.css           |    8 +
 .../domButtons/DomButtonBlackCircleCross.css       |   49 +
 .../common/domButtons/DomButtonBlueBall-compat.css |    8 +
 .../themes/common/domButtons/DomButtonBlueBall.css |   15 +
 .../domButtons/DomButtonBlueCircleArrow-compat.css |    9 +
 .../common/domButtons/DomButtonBlueCircleArrow.css |   48 +
 .../domButtons/DomButtonBlueCircleMinus-compat.css |    9 +
 .../common/domButtons/DomButtonBlueCircleMinus.css |   37 +
 .../domButtons/DomButtonBlueCirclePlus-compat.css  |    9 +
 .../common/domButtons/DomButtonBlueCirclePlus.css  |   47 +
 .../domButtons/DomButtonCheckboxOff-compat.css     |    8 +
 .../common/domButtons/DomButtonCheckboxOff.css     |   40 +
 .../domButtons/DomButtonCheckboxOn-compat.css      |    8 +
 .../common/domButtons/DomButtonCheckboxOn.css      |   40 +
 .../domButtons/DomButtonColorButtons-compat.css    |   48 +
 .../common/domButtons/DomButtonColorButtons.css    |   55 +
 .../domButtons/DomButtonDarkBlueCheck-compat.css   |    8 +
 .../common/domButtons/DomButtonDarkBlueCheck.css   |   18 +
 .../domButtons/DomButtonGrayArrow-compat.css       |    8 +
 .../common/domButtons/DomButtonGrayArrow.css       |   18 +
 .../domButtons/DomButtonGrayRoundRect-compat.css   |    4 +
 .../common/domButtons/DomButtonGrayRoundRect.css   |   23 +
 .../common/domButtons/DomButtonGrayStar-compat.css |    8 +
 .../themes/common/domButtons/DomButtonGrayStar.css |   49 +
 .../domButtons/DomButtonGreenBall-compat.css       |    8 +
 .../common/domButtons/DomButtonGreenBall.css       |   15 +
 .../DomButtonGreenCircleArrow-compat.css           |    9 +
 .../domButtons/DomButtonGreenCircleArrow.css       |   48 +
 .../DomButtonGreenCircleMinus-compat.css           |    9 +
 .../domButtons/DomButtonGreenCircleMinus.css       |   37 +
 .../domButtons/DomButtonGreenCirclePlus-compat.css |    9 +
 .../common/domButtons/DomButtonGreenCirclePlus.css |   47 +
 .../domButtons/DomButtonOrangeBall-compat.css      |    8 +
 .../common/domButtons/DomButtonOrangeBall.css      |   15 +
 .../common/domButtons/DomButtonRedBall-compat.css  |    8 +
 .../themes/common/domButtons/DomButtonRedBall.css  |   15 +
 .../domButtons/DomButtonRedCircleArrow-compat.css  |    9 +
 .../common/domButtons/DomButtonRedCircleArrow.css  |   48 +
 .../domButtons/DomButtonRedCircleMinus-compat.css  |    9 +
 .../common/domButtons/DomButtonRedCircleMinus.css  |   37 +
 .../domButtons/DomButtonRedCirclePlus-compat.css   |    9 +
 .../common/domButtons/DomButtonRedCirclePlus.css   |   47 +
 .../DomButtonSilverCircleDownArrow-compat.css      |    8 +
 .../domButtons/DomButtonSilverCircleDownArrow.css  |   43 +
 .../DomButtonSilverCircleGrayButton-compat.css     |    8 +
 .../domButtons/DomButtonSilverCircleGrayButton.css |   27 +
 .../DomButtonSilverCircleGreenButton-compat.css    |    8 +
 .../DomButtonSilverCircleGreenButton.css           |   27 +
 .../DomButtonSilverCircleGreenPlus-compat.css      |    8 +
 .../domButtons/DomButtonSilverCircleGreenPlus.css  |   37 +
 .../DomButtonSilverCircleOrangeButton-compat.css   |    8 +
 .../DomButtonSilverCircleOrangeButton.css          |   27 +
 .../DomButtonSilverCircleRedCross-compat.css       |    8 +
 .../domButtons/DomButtonSilverCircleRedCross.css   |   38 +
 .../common/domButtons/DomButtonTransparent19.css   |    6 +
 .../common/domButtons/DomButtonTransparent29.css   |    6 +
 .../common/domButtons/DomButtonTransparent30.css   |    6 +
 .../domButtons/DomButtonWhiteArrow-compat.css      |    8 +
 .../common/domButtons/DomButtonWhiteArrow.css      |   18 +
 .../domButtons/DomButtonWhiteCheck-compat.css      |    8 +
 .../common/domButtons/DomButtonWhiteCheck.css      |   18 +
 .../domButtons/DomButtonWhiteDownArrow-compat.css  |    8 +
 .../common/domButtons/DomButtonWhiteDownArrow.css  |   22 +
 .../domButtons/DomButtonWhitePlus-compat.css       |    8 +
 .../common/domButtons/DomButtonWhitePlus.css       |   28 +
 .../domButtons/DomButtonWhiteSearch-compat.css     |    8 +
 .../common/domButtons/DomButtonWhiteSearch.css     |   30 +
 .../domButtons/DomButtonWhiteUpArrow-compat.css    |    8 +
 .../common/domButtons/DomButtonWhiteUpArrow.css    |   22 +
 .../domButtons/DomButtonYellowStar-compat.css      |    8 +
 .../common/domButtons/DomButtonYellowStar.css      |   49 +
 .../common/domButtons/compat/mblDomButtonArrow.png |  Bin 0 -> 3604 bytes
 .../compat/mblDomButtonBlackCircleCross.png        |  Bin 0 -> 1449 bytes
 .../domButtons/compat/mblDomButtonBlueBall.png     |  Bin 0 -> 347 bytes
 .../compat/mblDomButtonBlueCircleArrow.png         |  Bin 0 -> 1500 bytes
 .../compat/mblDomButtonBlueCircleMinus.png         |  Bin 0 -> 1379 bytes
 .../compat/mblDomButtonBlueCirclePlus.png          |  Bin 0 -> 1373 bytes
 .../domButtons/compat/mblDomButtonBlueMinus.png    |  Bin 0 -> 1055 bytes
 .../domButtons/compat/mblDomButtonBluePlus.png     |  Bin 0 -> 1073 bytes
 .../common/domButtons/compat/mblDomButtonCheck.png |  Bin 0 -> 3639 bytes
 .../domButtons/compat/mblDomButtonCheckboxOff.png} |  Bin 1081 -> 1081 bytes
 .../domButtons/compat/mblDomButtonCheckboxOn.png}  |  Bin 1148 -> 1148 bytes
 .../compat/mblDomButtonDarkBlueCheck.png           |  Bin 0 -> 3639 bytes
 .../compat/mblDomButtonDarkBlueMinus.png           |  Bin 0 -> 1048 bytes
 .../domButtons/compat/mblDomButtonDarkBluePlus.png |  Bin 0 -> 1065 bytes
 .../domButtons/compat/mblDomButtonGrayArrow.png    |  Bin 0 -> 3604 bytes
 .../domButtons/compat/mblDomButtonGrayStar.png     |  Bin 0 -> 680 bytes
 .../domButtons/compat/mblDomButtonGreenBall.png    |  Bin 0 -> 348 bytes
 .../compat/mblDomButtonGreenCircleArrow.png        |  Bin 0 -> 1599 bytes
 .../compat/mblDomButtonGreenCircleMinus.png        |  Bin 0 -> 1394 bytes
 .../compat/mblDomButtonGreenCirclePlus.png         |  Bin 0 -> 1428 bytes
 .../domButtons/compat/mblDomButtonOrangeBall.png   |  Bin 0 -> 353 bytes
 .../domButtons/compat/mblDomButtonRedBall.png      |  Bin 0 -> 348 bytes
 .../compat/mblDomButtonRedCircleArrow.png          |  Bin 0 -> 1524 bytes
 .../compat/mblDomButtonRedCircleMinus.png          |  Bin 0 -> 1355 bytes
 .../compat/mblDomButtonRedCirclePlus.png           |  Bin 0 -> 1395 bytes
 .../domButtons/compat/mblDomButtonRedMinus.png     |  Bin 0 -> 1051 bytes
 .../domButtons/compat/mblDomButtonRedPlus.png      |  Bin 0 -> 1069 bytes
 .../compat/mblDomButtonSilverCircleDownArrow.png   |  Bin 0 -> 1353 bytes
 .../compat/mblDomButtonSilverCircleGrayButton.png  |  Bin 0 -> 1260 bytes
 .../compat/mblDomButtonSilverCircleGreenButton.png |  Bin 0 -> 1438 bytes
 .../compat/mblDomButtonSilverCircleGreenPlus.png   |  Bin 0 -> 1065 bytes
 .../mblDomButtonSilverCircleOrangeButton.png       |  Bin 0 -> 1422 bytes
 .../compat/mblDomButtonSilverCircleRedCross.png    |  Bin 0 -> 1361 bytes
 .../domButtons/compat/mblDomButtonWhiteArrow.png   |  Bin 0 -> 3604 bytes
 .../domButtons/compat/mblDomButtonWhiteCheck.png   |  Bin 0 -> 3612 bytes
 .../compat/mblDomButtonWhiteDownArrow.png}         |  Bin 935 -> 935 bytes
 .../domButtons/compat/mblDomButtonWhitePlus.png}   |  Bin 918 -> 918 bytes
 .../domButtons/compat/mblDomButtonWhiteSearch.png  |  Bin 0 -> 414 bytes
 .../compat/mblDomButtonWhiteUpArrow.png}           |  Bin 933 -> 933 bytes
 .../domButtons/compat/mblDomButtonYellowStar.png   |  Bin 0 -> 438 bytes
 dojox/mobile/themes/common/transitions.css         |   11 +
 dojox/mobile/themes/common/transitions/cover.css   |   34 +
 dojox/mobile/themes/common/transitions/coverv.css  |   35 +
 .../mobile/themes/common/transitions/dissolve.css  |   18 +
 dojox/mobile/themes/common/transitions/fade.css    |   22 +
 dojox/mobile/themes/common/transitions/flip.css    |   35 +
 dojox/mobile/themes/common/transitions/reveal.css  |   35 +
 dojox/mobile/themes/common/transitions/revealv.css |   31 +
 dojox/mobile/themes/common/transitions/scaleIn.css |   33 +
 .../mobile/themes/common/transitions/scaleOut.css  |   33 +
 dojox/mobile/themes/common/transitions/slide.css   |   41 +
 dojox/mobile/themes/common/transitions/slidev.css  |   42 +
 dojox/mobile/themes/common/transitions/swirl.css   |   27 +
 dojox/mobile/themes/common/transitions/zoomIn.css  |   33 +
 dojox/mobile/themes/common/transitions/zoomOut.css |   33 +
 .../mobile/themes/compat/small-blue-button-bg.png  |  Bin 190 -> 0 bytes
 .../themes/compat/small-darkblue-button-bg.png     |  Bin 192 -> 0 bytes
 dojox/mobile/themes/compat/small-red-button-bg.png |  Bin 186 -> 0 bytes
 dojox/mobile/themes/custom/Button-compat.css       |    8 +
 dojox/mobile/themes/custom/Button.css              |   48 +
 dojox/mobile/themes/custom/Button.less             |    2 +
 dojox/mobile/themes/custom/Carousel.css            |   60 +
 dojox/mobile/themes/custom/Carousel.less           |    2 +
 dojox/mobile/themes/custom/CheckBox-compat.css     |   26 +
 dojox/mobile/themes/custom/CheckBox.css            |   45 +
 dojox/mobile/themes/custom/CheckBox.less           |    2 +
 dojox/mobile/themes/custom/ComboBox-compat.css     |    7 +
 dojox/mobile/themes/custom/ComboBox.css            |   44 +
 dojox/mobile/themes/custom/ComboBox.less           |    2 +
 .../themes/custom/EdgeToEdgeCategory-compat.css    |    4 +
 dojox/mobile/themes/custom/EdgeToEdgeCategory.css  |   19 +
 dojox/mobile/themes/custom/EdgeToEdgeCategory.less |    2 +
 dojox/mobile/themes/custom/EdgeToEdgeList.css      |   12 +
 dojox/mobile/themes/custom/EdgeToEdgeList.less     |    2 +
 dojox/mobile/themes/custom/Heading-compat.css      |   47 +
 dojox/mobile/themes/custom/Heading.css             |   85 +
 dojox/mobile/themes/custom/Heading.less            |    2 +
 .../mobile/themes/custom/IconContainer-compat.css  |   11 +
 dojox/mobile/themes/custom/IconContainer.css       |  101 +
 dojox/mobile/themes/custom/IconContainer.less      |    5 +
 dojox/mobile/themes/custom/ListItem-compat.css     |   16 +
 dojox/mobile/themes/custom/ListItem.css            |   84 +
 dojox/mobile/themes/custom/ListItem.less           |    5 +
 dojox/mobile/themes/custom/Opener-compat.css       |    3 +
 dojox/mobile/themes/custom/Opener.css              |    3 +
 dojox/mobile/themes/custom/Overlay-compat.css      |   13 +
 dojox/mobile/themes/custom/Overlay.css             |   18 +
 dojox/mobile/themes/custom/Overlay.less            |    5 +
 dojox/mobile/themes/custom/PageIndicator.css       |   24 +
 dojox/mobile/themes/custom/PageIndicator.less      |    2 +
 .../themes/custom/ProgressIndicator-compat.css     |   46 +
 dojox/mobile/themes/custom/ProgressIndicator.css   |   58 +
 dojox/mobile/themes/custom/ProgressIndicator.less  |    2 +
 dojox/mobile/themes/custom/RadioButton-compat.css  |   26 +
 dojox/mobile/themes/custom/RadioButton.css         |   41 +
 dojox/mobile/themes/custom/RadioButton.less        |    2 +
 dojox/mobile/themes/custom/RoundRect-compat.css    |   71 +
 dojox/mobile/themes/custom/RoundRect.css           |   15 +
 dojox/mobile/themes/custom/RoundRect.less          |    2 +
 dojox/mobile/themes/custom/RoundRectCategory.css   |   14 +
 dojox/mobile/themes/custom/RoundRectCategory.less  |    2 +
 .../mobile/themes/custom/RoundRectList-compat.css  |   91 +
 dojox/mobile/themes/custom/RoundRectList.css       |   21 +
 dojox/mobile/themes/custom/RoundRectList.less      |    2 +
 dojox/mobile/themes/custom/Slider-compat.css       |   42 +
 dojox/mobile/themes/custom/Slider.css              |   65 +
 dojox/mobile/themes/custom/Slider.less             |    2 +
 dojox/mobile/themes/custom/Switch-compat.css       |   59 +
 dojox/mobile/themes/custom/Switch.css              |   23 +
 dojox/mobile/themes/custom/Switch.less             |    4 +
 dojox/mobile/themes/custom/TabBar-compat.css       |   55 +
 dojox/mobile/themes/custom/TabBar.css              |  161 +
 dojox/mobile/themes/custom/TabBar.less             |    2 +
 dojox/mobile/themes/custom/TextArea-compat.css     |    7 +
 dojox/mobile/themes/custom/TextArea.css            |   12 +
 dojox/mobile/themes/custom/TextArea.less           |    2 +
 dojox/mobile/themes/custom/TextBox-compat.css      |    7 +
 dojox/mobile/themes/custom/TextBox.css             |    8 +
 dojox/mobile/themes/custom/TextBox.less            |    2 +
 dojox/mobile/themes/custom/ToggleButton-compat.css |   21 +
 dojox/mobile/themes/custom/ToggleButton.css        |   52 +
 dojox/mobile/themes/custom/ToggleButton.less       |    2 +
 dojox/mobile/themes/custom/ToolBarButton.css       |   32 +
 dojox/mobile/themes/custom/ToolBarButton.less      |    2 +
 dojox/mobile/themes/custom/Tooltip-compat.css      |   47 +
 dojox/mobile/themes/custom/Tooltip.css             |  142 +
 dojox/mobile/themes/custom/Tooltip.less            |    2 +
 dojox/mobile/themes/custom/View.css                |   24 +
 dojox/mobile/themes/custom/View.less               |    6 +
 dojox/mobile/themes/custom/base-compat.css         |    8 +
 dojox/mobile/themes/custom/base.css                |   12 +
 dojox/mobile/themes/custom/common-compat.css       |    8 +
 dojox/mobile/themes/custom/common.css              |   31 +
 dojox/mobile/themes/custom/common.less             |    2 +
 .../themes/custom/compat/arrow-button-head.png     |  Bin 0 -> 503 bytes
 dojox/mobile/themes/custom/compat/heading-bg.png   |  Bin 0 -> 339 bytes
 .../themes/custom/compat/slider-h-bar-bg.png       |  Bin 0 -> 135 bytes
 dojox/mobile/themes/custom/compat/ui-widget-bg.png |  Bin 0 -> 680 bytes
 dojox/mobile/themes/custom/custom-compat.css       |   18 +
 dojox/mobile/themes/custom/custom.css              |   22 +
 .../themes/custom/images/thumb-overlay-large.png   |  Bin 0 -> 3697 bytes
 .../themes/custom/images/thumb-overlay-small.png   |  Bin 0 -> 1549 bytes
 .../mobile/themes/custom/images/thumb-overlay.png  |  Bin 0 -> 2010 bytes
 dojox/mobile/themes/custom/variables.less          |  921 +
 dojox/mobile/themes/domButtons-compat.css          |    6 -
 dojox/mobile/themes/domButtons.css                 |    6 -
 dojox/mobile/themes/domButtons/Common-compat.css   |    3 -
 dojox/mobile/themes/domButtons/Common.css          |    6 -
 .../domButtons/DomButtonDownArrow-compat.css       |    8 -
 .../themes/domButtons/DomButtonDownArrow.css       |   21 -
 .../themes/domButtons/DomButtonPlus-compat.css     |    8 -
 dojox/mobile/themes/domButtons/DomButtonPlus.css   |   18 -
 .../themes/domButtons/DomButtonSearch-compat.css   |   12 -
 dojox/mobile/themes/domButtons/DomButtonSearch.css |   33 -
 .../themes/domButtons/DomButtonUpArrow-compat.css  |    8 -
 .../mobile/themes/domButtons/DomButtonUpArrow.css  |   21 -
 .../themes/domButtons/compat/search-button.gif     |  Bin 910 -> 0 bytes
 .../themes/domButtons/compat/search-button.png     |  Bin 420 -> 0 bytes
 dojox/mobile/themes/iphone/Button-compat.css       |   33 +
 dojox/mobile/themes/iphone/Button.css              |   45 +
 dojox/mobile/themes/iphone/Button.less             |    2 +
 dojox/mobile/themes/iphone/Carousel.css            |   60 +
 dojox/mobile/themes/iphone/Carousel.less           |    2 +
 dojox/mobile/themes/iphone/CheckBox-compat.css     |   36 +
 dojox/mobile/themes/iphone/CheckBox.css            |   44 +
 dojox/mobile/themes/iphone/CheckBox.less           |    2 +
 dojox/mobile/themes/iphone/ComboBox-compat.css     |    7 +
 dojox/mobile/themes/iphone/ComboBox.css            |   44 +
 dojox/mobile/themes/iphone/ComboBox.less           |    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      |   12 +
 dojox/mobile/themes/iphone/EdgeToEdgeList.less     |    2 +
 dojox/mobile/themes/iphone/Heading-compat.css      |   24 +
 dojox/mobile/themes/iphone/Heading.css             |   84 +
 dojox/mobile/themes/iphone/Heading.less            |    2 +
 .../mobile/themes/iphone/IconContainer-compat.css  |   11 +
 dojox/mobile/themes/iphone/IconContainer.css       |   97 +
 dojox/mobile/themes/iphone/IconContainer.less      |    5 +
 dojox/mobile/themes/iphone/ListItem-compat.css     |    7 +
 dojox/mobile/themes/iphone/ListItem.css            |   82 +
 dojox/mobile/themes/iphone/ListItem.less           |    5 +
 dojox/mobile/themes/iphone/Opener-compat.css       |    3 +
 dojox/mobile/themes/iphone/Opener.css              |    3 +
 dojox/mobile/themes/iphone/Overlay-compat.css      |   15 +
 dojox/mobile/themes/iphone/Overlay.css             |   17 +
 dojox/mobile/themes/iphone/Overlay.less            |    5 +
 dojox/mobile/themes/iphone/PageIndicator.css       |   24 +
 dojox/mobile/themes/iphone/PageIndicator.less      |    2 +
 .../themes/iphone/ProgressIndicator-compat.css     |   46 +
 dojox/mobile/themes/iphone/ProgressIndicator.css   |   58 +
 dojox/mobile/themes/iphone/ProgressIndicator.less  |    2 +
 dojox/mobile/themes/iphone/RadioButton-compat.css  |   33 +
 dojox/mobile/themes/iphone/RadioButton.css         |   41 +
 dojox/mobile/themes/iphone/RadioButton.less        |    2 +
 dojox/mobile/themes/iphone/RoundRect-compat.css    |   64 +
 dojox/mobile/themes/iphone/RoundRect.css           |   12 +
 dojox/mobile/themes/iphone/RoundRect.less          |    2 +
 dojox/mobile/themes/iphone/RoundRectCategory.css   |   12 +
 dojox/mobile/themes/iphone/RoundRectCategory.less  |    2 +
 .../mobile/themes/iphone/RoundRectList-compat.css  |   64 +
 dojox/mobile/themes/iphone/RoundRectList.css       |   25 +
 dojox/mobile/themes/iphone/RoundRectList.less      |    2 +
 dojox/mobile/themes/iphone/Slider-compat.css       |   43 +
 dojox/mobile/themes/iphone/Slider.css              |   62 +
 dojox/mobile/themes/iphone/Slider.less             |    2 +
 dojox/mobile/themes/iphone/Switch-compat.css       |   70 +
 dojox/mobile/themes/iphone/Switch.css              |   18 +
 dojox/mobile/themes/iphone/Switch.less             |    4 +
 dojox/mobile/themes/iphone/TabBar-compat.css       |   36 +
 dojox/mobile/themes/iphone/TabBar.css              |  142 +
 dojox/mobile/themes/iphone/TabBar.less             |    2 +
 dojox/mobile/themes/iphone/TextArea-compat.css     |    7 +
 dojox/mobile/themes/iphone/TextArea.css            |   14 +
 dojox/mobile/themes/iphone/TextArea.less           |    2 +
 dojox/mobile/themes/iphone/TextBox-compat.css      |    7 +
 dojox/mobile/themes/iphone/TextBox.css             |    8 +
 dojox/mobile/themes/iphone/TextBox.less            |    2 +
 dojox/mobile/themes/iphone/ToggleButton-compat.css |   30 +
 dojox/mobile/themes/iphone/ToggleButton.css        |   52 +
 dojox/mobile/themes/iphone/ToggleButton.less       |    2 +
 dojox/mobile/themes/iphone/ToolBarButton.css       |   28 +
 dojox/mobile/themes/iphone/ToolBarButton.less      |    2 +
 dojox/mobile/themes/iphone/Tooltip-compat.css      |   41 +
 dojox/mobile/themes/iphone/Tooltip.css             |  150 +
 dojox/mobile/themes/iphone/Tooltip.less            |    2 +
 dojox/mobile/themes/iphone/View.css                |   23 +
 dojox/mobile/themes/iphone/View.less               |    6 +
 dojox/mobile/themes/iphone/base-compat.css         |    7 +
 dojox/mobile/themes/iphone/base.css                |   12 +
 dojox/mobile/themes/iphone/common.css              |   26 +
 dojox/mobile/themes/iphone/common.less             |    2 +
 dojox/mobile/themes/iphone/compat/button-bg.png    |  Bin 0 -> 169 bytes
 .../mobile/themes/iphone/compat/button-sel-bg.png  |  Bin 0 -> 170 bytes
 .../mobile/themes/iphone/compat/red-button-bg.png  |  Bin 0 -> 248 bytes
 .../themes/iphone/compat/red-button-sel-bg.png     |  Bin 0 -> 179 bytes
 .../themes/iphone/compat/slider-h-bar-bg.png       |  Bin 0 -> 133 bytes
 dojox/mobile/themes/iphone/compat/slider-h-bg.png  |  Bin 0 -> 132 bytes
 .../themes/iphone/compat/slider-handle-bg.png      |  Bin 0 -> 163 bytes
 dojox/mobile/themes/iphone/compat/switch-arc-l.gif |  Bin 0 -> 1028 bytes
 dojox/mobile/themes/iphone/compat/switch-arc-r.gif |  Bin 0 -> 683 bytes
 .../mobile/themes/iphone/compat/switch-arc1-k.gif  |  Bin 0 -> 524 bytes
 .../mobile/themes/iphone/compat/switch-arc2-k.gif  |  Bin 0 -> 604 bytes
 .../mobile/themes/iphone/compat/switch-blue-bg.png |  Bin 199 -> 0 bytes
 .../themes/iphone/compat/switch-default-k.gif      |  Bin 0 -> 566 bytes
 .../themes/iphone/compat/switch-default-l.gif      |  Bin 0 -> 745 bytes
 .../themes/iphone/compat/switch-default-r.gif      |  Bin 0 -> 595 bytes
 .../mobile/themes/iphone/compat/switch-gray-bg.png |  Bin 183 -> 0 bytes
 .../mobile/themes/iphone/compat/switch-knob-bg.png |  Bin 174 -> 0 bytes
 .../mobile/themes/iphone/compat/switch-round-l.gif |  Bin 0 -> 1058 bytes
 .../mobile/themes/iphone/compat/switch-round-r.gif |  Bin 0 -> 683 bytes
 .../themes/iphone/compat/switch-round1-k.gif       |  Bin 0 -> 548 bytes
 .../themes/iphone/compat/switch-round2-k.gif       |  Bin 0 -> 636 bytes
 .../themes/iphone/compat/tooltip-button-bg.png     |  Bin 0 -> 181 bytes
 .../themes/iphone/compat/tooltip-heading-bg.png    |  Bin 0 -> 298 bytes
 dojox/mobile/themes/iphone/ipad-compat.css         |   11 +-
 dojox/mobile/themes/iphone/ipad.css                |  118 +-
 dojox/mobile/themes/iphone/iphone-app.css          |   20 +-
 dojox/mobile/themes/iphone/iphone-compat.css       |  315 +-
 dojox/mobile/themes/iphone/iphone.css              |  880 +-
 dojox/mobile/themes/iphone/variables.less          |  726 +
 dojox/mobile/transition.js                         |   19 +
 dojox/mobile/uacss.js                              |   15 +
 dojox/mvc.js                                       |    8 +
 dojox/mvc/Bind.js                                  |   61 +
 dojox/mvc/Generate.js                              |  154 +
 dojox/mvc/Group.js                                 |   16 +
 dojox/mvc/Output.js                                |   91 +
 dojox/mvc/README                                   |   82 +
 dojox/mvc/Repeat.js                                |  108 +
 dojox/mvc/StatefulModel.js                         |  462 +
 dojox/mvc/_Container.js                            |  107 +
 dojox/mvc/_DataBindingMixin.js                     |  389 +
 dojox/mvc/_base.js                                 |   64 +
 dojox/mvc/_patches.js                              |   49 +
 dojox/mvc/tests/_data/mvcGenerateData.json         |    9 +
 dojox/mvc/tests/_data/mvcRepeatData.json           |  105 +
 dojox/mvc/tests/css/android-format.css             |   27 +
 dojox/mvc/tests/css/app-format.css                 |   85 +
 dojox/mvc/tests/css/dijitTests.css                 |  116 +
 dojox/mvc/tests/css/index-format.css               |   26 +
 dojox/mvc/tests/css/iphone-format.css              |   28 +
 .../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/helpers.js                         |   74 +
 dojox/mvc/tests/images/MVC_patterns_in_Dojo.png    |  Bin 0 -> 4264 bytes
 dojox/mvc/tests/images/background.jpg              |  Bin 0 -> 70265 bytes
 dojox/mvc/tests/images/master_detail.png           |  Bin 0 -> 3054 bytes
 dojox/mvc/tests/images/validating_form_pattern.png |  Bin 0 -> 3524 bytes
 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               |  469 +
 dojox/mvc/tests/mobile/demo/demo.html              |  203 +
 dojox/mvc/tests/mobile/demo/demo.profile.js        |   17 +
 dojox/mvc/tests/mobile/demo/generateView.html      |   62 +
 dojox/mvc/tests/mobile/demo/iPad-Demo.html         |  213 +
 dojox/mvc/tests/mobile/demo/images/i-icon-1.png    |  Bin 0 -> 486 bytes
 dojox/mvc/tests/mobile/demo/images/i-icon-2.png    |  Bin 0 -> 459 bytes
 dojox/mvc/tests/mobile/demo/images/i-icon-3.png    |  Bin 0 -> 306 bytes
 dojox/mvc/tests/mobile/demo/images/mvc.png         |  Bin 0 -> 3457 bytes
 dojox/mvc/tests/mobile/demo/repeatDataBinding.html |   45 +
 dojox/mvc/tests/mobile/demo/shipToBillTo.html      |   51 +
 dojox/mvc/tests/mobile/demo/src-async-store.js     |  137 +
 dojox/mvc/tests/mobile/demo/src-async.js           |  167 +
 dojox/mvc/tests/mobile/demo/src-sync.js            |  148 +
 dojox/mvc/tests/mobile/demo/src.js                 |  167 +
 .../mobile/test_Android-repeat-data-store.html     |  104 +
 .../tests/mobile/test_iPhone-shipto-billto.html    |  121 +
 dojox/mvc/tests/models/LoanWizardModel.js          |  113 +
 dojox/mvc/tests/module.js                          |   31 +
 dojox/mvc/tests/moduleFullSet.js                   |   31 +
 dojox/mvc/tests/mvc_index.html                     |   37 +
 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/runTests.html                      |    9 +
 dojox/mvc/tests/runTestsFullSet.html               |    9 +
 dojox/mvc/tests/test_async-mvc_group-simple.html   |   81 +
 .../tests/test_async-mvc_input-output-simple.html  |   82 +
 dojox/mvc/tests/test_async-mvc_repeat-simple.html  |  193 +
 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  |   71 +
 dojox/mvc/tests/test_mvc_generate-view.html        |   75 +
 dojox/mvc/tests/test_mvc_input-output-simple.html  |   74 +
 dojox/mvc/tests/test_mvc_loan-stateful.html        |  187 +
 .../tests/test_mvc_programmatic-repeat-store.html  |  147 +
 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 +
 .../mvc/tests/test_mvc_search-results-ins-del.html |  239 +
 .../test_mvc_search-results-repeat-store.html      |  116 +
 .../mvc/tests/test_mvc_search-results-repeat.html  |  222 +
 .../tests/test_mvc_shipto-billto-hierarchical.html |  198 +
 .../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  |   64 +
 .../tests/test_templatedWidget/myMvcTemplated.js   |   22 +
 dojox/mvc/tests/test_templatedWidget/readme.txt    |    3 +
 .../test_templatedWidget/test_mvc_widget.html      |   78 +
 .../test_mvc_widget_template.html                  |   39 +
 dojox/mvc/tests/zips/10024.json                    |   12 +
 dojox/mvc/tests/zips/10706.json                    |   12 +
 dojox/package.json                                 |   23 +
 dojox/rails/README                                 |    3 +-
 dojox/rpc/Client.js                                |   17 +-
 dojox/rpc/JsonRest.js                              |    7 +-
 dojox/rpc/Rest.js                                  |    3 +
 dojox/rpc/Service.js                               |   10 +-
 dojox/rpc/tests/module.js                          |    2 +-
 dojox/rpc/tests/stores/JsonRestStore.js            |   25 +-
 dojox/secure/capability.js                         |    2 +-
 dojox/secure/sandbox.js                            |    7 +-
 dojox/secure/tests/fromJson.js                     |    2 +-
 dojox/secure/tests/sandbox.js                      |    7 +-
 dojox/sketch.js                                    |   16 +-
 dojox/sketch/Anchor.js                             |   21 +-
 dojox/sketch/Annotation.js                         |   54 +-
 dojox/sketch/DoubleArrowAnnotation.js              |   12 +-
 dojox/sketch/Figure.js                             |   20 +-
 dojox/sketch/LeadAnnotation.js                     |    9 +-
 dojox/sketch/PreexistingAnnotation.js              |   10 +-
 dojox/sketch/SingleArrowAnnotation.js              |    9 +-
 dojox/sketch/Slider.js                             |   74 +-
 dojox/sketch/Toolbar.js                            |  182 +-
 dojox/sketch/UnderlineAnnotation.js                |    9 +-
 dojox/sketch/UndoStack.js                          |   15 +-
 dojox/sketch/_Plugin.js                            |  147 +-
 dojox/sketch/tests/test_full.html                  |    9 +-
 dojox/socket.js                                    |    8 +-
 dojox/store/LightstreamerStore.js                  |  204 +
 dojox/store/README                                 |   47 +
 dojox/store/tests/test_LightstreamerStore.html     |   74 +
 dojox/string/BidiComplex.js                        |  118 +-
 dojox/string/BidiEngine.js                         | 1506 +
 dojox/string/Builder.js                            |  241 +-
 dojox/string/sprintf.js                            |  709 +-
 dojox/string/tests/BidiEngine/BidiEngineTest.js    | 1113 +
 .../tests/BidiEngine/BidiEngineTestLayouts.js      |  351 +
 dojox/string/tests/BidiEngine/module.js            |   10 +
 dojox/string/tests/BidiEngine/runTests.html        |   11 +
 dojox/string/tokenize.js                           |   74 +-
 dojox/timing.js                                    |    5 +-
 dojox/timing/Sequence.js                           |  253 +-
 dojox/timing/Streamer.js                           |  158 +-
 dojox/timing/ThreadPool.js                         |   10 +-
 dojox/timing/_base.js                              |   97 +-
 dojox/timing/doLater.js                            |   88 +-
 dojox/timing/tests/test_Sequence.html              |    2 +
 dojox/timing/tests/test_ThreadPool.html            |    1 -
 dojox/uuid.js                                      |    5 +-
 dojox/uuid/Uuid.js                                 |    7 +-
 dojox/uuid/_base.js                                |    8 +-
 dojox/uuid/generateRandomUuid.js                   |    6 +-
 dojox/uuid/generateTimeBasedUuid.js                |   16 +-
 dojox/uuid/tests/uuid.js                           |  133 +-
 dojox/validate.js                                  |   10 +-
 dojox/validate/_base.js                            |   44 +-
 dojox/validate/br.js                               |   30 +-
 dojox/validate/ca.js                               |   18 +-
 dojox/validate/check.js                            |   40 +-
 dojox/validate/creditCard.js                       |   36 +-
 dojox/validate/isbn.js                             |   18 +-
 dojox/validate/regexp.js                           |   99 +-
 dojox/validate/tests/br.js                         |  136 +-
 dojox/validate/tests/creditcard.js                 |  155 +-
 dojox/validate/tests/module.js                     |   16 +-
 dojox/validate/tests/validate.js                   |  385 +-
 dojox/validate/us.js                               |   33 +-
 dojox/validate/web.js                              |   42 +-
 dojox/widget/AnalogGauge.js                        |  356 +-
 dojox/widget/BarGauge.js                           |  294 +-
 dojox/widget/Calendar.js                           |    7 +-
 dojox/widget/Calendar/Calendar.css                 |    4 +
 dojox/widget/CalendarViews.js                      |    1 -
 dojox/widget/ColorPicker.js                        |  213 +-
 dojox/widget/Dialog.js                             |  487 +-
 dojox/widget/DialogSimple.js                       |   17 +-
 dojox/widget/FisheyeList.js                        |    7 +-
 dojox/widget/FisheyeLite.js                        |  293 +-
 dojox/widget/MultiSelectCalendar.js                |  974 +
 .../MultiSelectCalendar/MultiSelectCalendar.html   |    0
 dojox/widget/PlaceholderMenuItem.js                |   10 +-
 dojox/widget/Roller.js                             |  435 +-
 dojox/widget/RollingList.js                        |    2 +
 dojox/widget/Standby.js                            |  220 +-
 dojox/widget/TitleGroup.js                         |   27 +-
 dojox/widget/Toaster.js                            |   99 +-
 dojox/widget/Toaster/Toaster.css                   |    7 +-
 dojox/widget/Wizard.js                             |   60 +-
 dojox/widget/gauge/AnalogArcIndicator.js           |   66 +-
 dojox/widget/gauge/AnalogArrowIndicator.js         |   37 +-
 dojox/widget/gauge/AnalogNeedleIndicator.js        |   31 +-
 dojox/widget/gauge/BarIndicator.js                 |   72 +-
 dojox/widget/gauge/_Gauge.css                      |   63 -
 dojox/widget/gauge/_Gauge.html                     |    5 -
 dojox/widget/gauge/_Gauge.js                       |  758 +-
 dojox/widget/gauge/_Indicator.html                 |    4 -
 dojox/widget/nls/ColorPicker.js                    |   36 +
 dojox/widget/nls/FilePicker.js                     |   42 +-
 dojox/widget/nls/Wizard.js                         |   36 +
 dojox/widget/nls/ar/ColorPicker.js                 |    5 +-
 dojox/widget/nls/ar/Wizard.js                      |    5 +-
 dojox/widget/nls/az/ColorPicker.js                 |   16 +
 dojox/widget/nls/az/FilePicker.js                  |    9 +
 dojox/widget/nls/az/Wizard.js                      |    9 +
 dojox/widget/nls/ca/ColorPicker.js                 |    3 +
 dojox/widget/nls/ca/Wizard.js                      |    5 +-
 dojox/widget/nls/cs/ColorPicker.js                 |    4 +-
 dojox/widget/nls/cs/Wizard.js                      |    4 +
 dojox/widget/nls/da/ColorPicker.js                 |    4 +-
 dojox/widget/nls/da/Wizard.js                      |    4 +
 dojox/widget/nls/de/ColorPicker.js                 |    4 +-
 dojox/widget/nls/de/Wizard.js                      |    4 +
 dojox/widget/nls/el/ColorPicker.js                 |    4 +-
 dojox/widget/nls/el/Wizard.js                      |    4 +
 dojox/widget/nls/es/ColorPicker.js                 |    4 +-
 dojox/widget/nls/es/Wizard.js                      |    4 +
 dojox/widget/nls/fi/ColorPicker.js                 |    4 +-
 dojox/widget/nls/fi/Wizard.js                      |    4 +
 dojox/widget/nls/fr/ColorPicker.js                 |    4 +-
 dojox/widget/nls/fr/Wizard.js                      |    4 +
 dojox/widget/nls/he/ColorPicker.js                 |    4 +-
 dojox/widget/nls/he/Wizard.js                      |    4 +
 dojox/widget/nls/hr/ColorPicker.js                 |   14 +
 dojox/widget/nls/hr/FilePicker.js                  |    7 +
 dojox/widget/nls/hr/Wizard.js                      |    7 +
 dojox/widget/nls/hu/ColorPicker.js                 |    4 +-
 dojox/widget/nls/hu/Wizard.js                      |    4 +
 dojox/widget/nls/it/ColorPicker.js                 |    4 +-
 dojox/widget/nls/it/Wizard.js                      |    4 +
 dojox/widget/nls/ja/ColorPicker.js                 |    3 +
 dojox/widget/nls/ja/Wizard.js                      |    4 +
 dojox/widget/nls/kk/ColorPicker.js                 |    4 +-
 dojox/widget/nls/kk/Wizard.js                      |    5 +-
 dojox/widget/nls/ko/ColorPicker.js                 |    3 +
 dojox/widget/nls/ko/Wizard.js                      |    4 +
 dojox/widget/nls/nb/ColorPicker.js                 |    3 +
 dojox/widget/nls/nb/Wizard.js                      |    4 +
 dojox/widget/nls/nl/ColorPicker.js                 |    4 +-
 dojox/widget/nls/nl/Wizard.js                      |    4 +
 dojox/widget/nls/pl/ColorPicker.js                 |    4 +-
 dojox/widget/nls/pl/Wizard.js                      |    5 +-
 dojox/widget/nls/pt-pt/ColorPicker.js              |    4 +-
 dojox/widget/nls/pt-pt/Wizard.js                   |    4 +
 dojox/widget/nls/pt/ColorPicker.js                 |    3 +
 dojox/widget/nls/pt/Wizard.js                      |    4 +
 dojox/widget/nls/ro/ColorPicker.js                 |    4 +-
 dojox/widget/nls/ro/Wizard.js                      |    5 +-
 dojox/widget/nls/ru/ColorPicker.js                 |    4 +-
 dojox/widget/nls/ru/Wizard.js                      |    4 +
 dojox/widget/nls/sk/ColorPicker.js                 |    4 +-
 dojox/widget/nls/sk/Wizard.js                      |    5 +-
 dojox/widget/nls/sl/ColorPicker.js                 |    4 +-
 dojox/widget/nls/sl/Wizard.js                      |    5 +-
 dojox/widget/nls/sv/ColorPicker.js                 |    4 +-
 dojox/widget/nls/sv/Wizard.js                      |    4 +
 dojox/widget/nls/th/ColorPicker.js                 |    4 +-
 dojox/widget/nls/th/Wizard.js                      |    5 +-
 dojox/widget/nls/tr/ColorPicker.js                 |    4 +-
 dojox/widget/nls/tr/Wizard.js                      |    4 +
 dojox/widget/nls/zh-tw/ColorPicker.js              |    3 +
 dojox/widget/nls/zh-tw/Wizard.js                   |    4 +
 dojox/widget/nls/zh/ColorPicker.js                 |    3 +
 dojox/widget/nls/zh/Wizard.js                      |    4 +
 dojox/widget/tests/test_AnalogGaugeWidget.html     |  554 -
 dojox/widget/tests/test_BarGaugeWidget.html        |  339 -
 dojox/widget/tests/test_Calendar.html              |   10 +-
 dojox/widget/tests/test_CalendarViews.html         |    6 +-
 dojox/widget/tests/test_ColorPicker-async.html     |   79 +
 dojox/widget/tests/test_ColorPicker.html           |    6 +-
 dojox/widget/tests/test_Dialog.html                |   15 +-
 .../tests/test_MultiSelectCalendar-async.html      |   30 +
 dojox/widget/tests/test_MultiSelectCalendar.html   |   31 +
 dojox/widget/tests/test_TitleGroup.html            |   28 +-
 dojox/widget/tests/test_Wizard.html                |    2 -
 dojox/wire/demos/WidgetRepeater.js                 |    2 +-
 dojox/wire/ml/Action.js                            |    1 -
 dojox/wire/ml/Data.js                              |    1 -
 dojox/wire/ml/JsonHandler.js                       |   42 +
 dojox/wire/ml/RestHandler.js                       |  143 +
 dojox/wire/ml/Service.js                           |  234 -
 dojox/wire/ml/Transfer.js                          |    4 -
 dojox/wire/ml/XmlHandler.js                        |   63 +
 dojox/xml/DomParser.js                             |    8 +-
 dojox/xml/Script.js                                |   21 +-
 dojox/xml/parser.js                                |   18 +-
 dojox/xml/tests/mail.html                          |    2 +-
 dojox/xml/tests/module.js                          |    9 +-
 dojox/xml/tests/parser.js                          |   59 +-
 dojox/xml/tests/widgetParser.html                  |   15 +-
 dojox/xml/widgetParser.js                          |   27 +-
 dojox/xmpp/tests/test_xmppService.html             |    3 +-
 dojox/xmpp/widget/ChatSession.js                   |    4 +
 util/build/argv.js                                 |  583 +
 util/build/buildControl.js                         |  678 +
 util/build/buildControlBase.js                     |   51 +
 util/build/buildControlDefault.js                  |  251 +
 util/build/buildNotice.txt                         |    7 +
 util/build/copyright.txt                           |    6 +
 util/build/discover.js                             |  296 +
 util/build/examples/dojo-base-json-dot.profile.js  |    4 +
 util/build/examples/dojoConfig.js                  |    9 +
 util/build/examples/profile-with-code.profile.js   |   12 +
 util/build/examples/relative-base-path.profile.js  |    3 +
 util/build/examples/require.js                     |   10 +
 util/build/examples/simple1.profile.js             |    4 +
 util/build/examples/trees-dirs-files.profile.js    |   22 +
 util/build/fileHandleThrottle.js                   |   23 +
 util/build/fileUtils.js                            |  185 +
 util/build/fs.js                                   |    3 +
 util/build/help.txt                                |   77 +
 util/build/main.js                                 |  284 +
 util/build/messages.js                             |  302 +
 util/build/node/fs.js                              |   28 +
 util/build/node/process.js                         |   45 +
 util/build/optimizeRunner.js                       |  141 +
 util/build/plugins/domReady.js                     |   13 +
 util/build/plugins/has.js                          |   81 +
 util/build/plugins/i18n.js                         |   67 +
 util/build/plugins/loadInit.js                     |   13 +
 util/build/plugins/querySelector.js                |   15 +
 util/build/plugins/require.js                      |   24 +
 util/build/plugins/text.js                         |   59 +
 util/build/process.js                              |    3 +
 util/build/removeComments.js                       |   17 +
 util/build/replace.js                              |   47 +
 util/build/rhino/fs.js                             |   74 +
 util/build/rhino/process.js                        |   35 +
 util/build/stringify.js                            |  150 +
 util/build/transforms/copy.js                      |   15 +
 util/build/transforms/depsDump.js                  |  101 +
 util/build/transforms/depsScan.js                  |  627 +
 util/build/transforms/dojoBoot.js                  |    8 +
 util/build/transforms/dojoPragmas.js               |   80 +
 util/build/transforms/dojoReport.js                |   46 +
 util/build/transforms/hasFindAll.js                |   19 +
 util/build/transforms/hasFixup.js                  |   46 +
 util/build/transforms/hasReport.js                 |   28 +
 util/build/transforms/insertSymbols.js             |  103 +
 util/build/transforms/optimizeCss.js               |  134 +
 util/build/transforms/read.js                      |   57 +
 util/build/transforms/report.js                    |   22 +
 util/build/transforms/trace.js                     |    5 +
 util/build/transforms/write.js                     |   12 +
 util/build/transforms/writeAmd.js                  |  343 +
 util/build/transforms/writeCss.js                  |   66 +
 util/build/transforms/writeDojo.js                 |  184 +
 util/build/transforms/writeOptimized.js            |  299 +
 util/build/v1xProfiles.js                          |  346 +
 util/build/version.js                              |   13 +
 util/buildscripts/build.bat                        |   11 +-
 util/buildscripts/build.sh                         |  105 +-
 util/buildscripts/build_release.sh                 |   52 +-
 util/buildscripts/cdnBuild.sh                      |   16 +-
 util/buildscripts/changeVersion.js                 |   57 +-
 util/buildscripts/cldr/alias.js                    |   14 +-
 util/buildscripts/cldr/arrayInherit.js             |   31 +-
 util/buildscripts/cldr/cldrUtil.js                 |    5 +
 util/buildscripts/cldr/ldml/core.zip               |  Bin 4073422 -> 4098553 bytes
 util/buildscripts/cldr/specialLocale.js            |    6 +-
 util/buildscripts/jslib/buildUtil.js               | 2125 -
 util/buildscripts/profiles/base.profile.js         |    2 +
 util/buildscripts/profiles/cdn.profile.js          |    6 +
 util/buildscripts/profiles/demos-all.profile.js    |  208 +-
 util/buildscripts/profiles/gfx.profile.js          |   26 +
 util/buildscripts/profiles/layers.profile.js       |   66 -
 util/buildscripts/profiles/mobile-all.profile.js   |   21 +-
 util/buildscripts/profiles/mobile.profile.js       |   33 +-
 util/buildscripts/profiles/rhino.profile.js        |   31 +-
 util/buildscripts/profiles/standard.profile.js     |   10 +
 .../profiles/standardCustomBase.profile.js         |    4 +-
 util/checkstyle/checkstyleReport.html              |    3 +-
 util/closureCompiler/COPYING                       |  202 +
 util/closureCompiler/README                        |  278 +
 util/closureCompiler/compiler.jar                  |  Bin 0 -> 4332498 bytes
 util/docscripts/_browse.php                        |  236 -
 util/docscripts/_browse2.php                       |  289 -
 util/docscripts/_browse_tree.php                   |  142 +
 util/docscripts/cheat.php                          |    5 +-
 util/docscripts/cheat/lib.js                       |    9 +-
 util/docscripts/dumpObj.php                        |   29 +
 util/docscripts/generate.php                       |   66 +-
 util/docscripts/lib/generator/hash/Freezer.php     |   63 +
 util/docscripts/lib/generator/hash/Serializer.php  |   89 +
 util/docscripts/lib/parser2/Dojo.php               |    3 +-
 util/docscripts/lib/parser2/dojo2.inc              |  895 +-
 util/docscripts/modules/util.module                |   28 +
 util/docscripts/parsefile.php                      |    2 +
 util/docscripts/preview.php                        |  389 +
 util/docscripts/tests/alias.js                     |   10 +
 util/docscripts/tests/alias_amd.js                 |    8 +
 util/docscripts/tests/basic.js                     |  225 +
 util/docscripts/tests/declare_amd.js               |   31 +
 util/docscripts/tests/declare_returns.js           |    7 +
 util/docscripts/tests/doctests.js                  |    3 +
 util/docscripts/tests/extend_declare.js            |   57 +
 util/docscripts/tests/functional.js                |   12 +
 util/docscripts/tests/runTests.php                 |    9 +
 util/docscripts/tests/simple.js                    |  132 +
 util/docscripts/tests/simple_amd.js                |   25 +
 util/doh/README                                    |  103 +-
 util/doh/Robot.html                                |   21 +-
 util/doh/_browserRunner.js                         |  211 +-
 util/doh/_nodeRunner.js                            |   32 +
 util/doh/_parseURLargs.js                          |  233 +
 util/doh/_rhinoRunner.js                           |   33 +-
 util/doh/doh.profile.js                            |   30 +
 util/doh/main.js                                   |    7 +
 util/doh/mobileRunner.html                         |   89 +
 util/doh/package.json                              |   23 +
 util/doh/plugins/README.txt                        |    7 +
 util/doh/plugins/alwaysAudio.js                    |   11 +
 util/doh/plugins/hello.js                          |   15 +
 util/doh/robot.js                                  |   24 +-
 util/doh/robot/DOHRobot.jar                        |  Bin 45861 -> 46761 bytes
 util/doh/robot/DOHRobot.java                       |  255 +-
 util/doh/robot/compilerobot.bat                    |   11 +-
 util/doh/robot/signature.png                       |  Bin 0 -> 145 bytes
 util/doh/runner.html                               |  115 +-
 util/doh/runner.js                                 | 1224 +-
 util/doh/runner.sh                                 |    2 +-
 util/doh/tests/scopeTest.js                        |   15 +
 util/doh/tests/selfTest.js                         |  244 +
 util/less/LICENSE                                  |  179 +
 util/less/README                                   |    7 +
 util/less/browser.js                               |  369 +
 util/less/functions.js                             |  174 +
 util/less/index.js                                 |  137 +
 util/less/parser.js                                | 1110 +
 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 +
 4640 files changed, 253543 insertions(+), 84823 deletions(-)

diff --git a/dijit/BackgroundIframe.js b/dijit/BackgroundIframe.js
new file mode 100644
index 0000000..6d37e8d
--- /dev/null
+++ b/dijit/BackgroundIframe.js
@@ -0,0 +1,113 @@
+define([
+	"require",			// require.toUrl
+	".",	// 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){
+
+	// module:
+	//		dijit/BackgroundIFrame
+	// summary:
+	//		new dijit.BackgroundIframe(node)
+	//		Makes a background iframe as a child of node, that fills
+	//		area (and position) of node
+
+	// TODO: remove _frames, it isn't being used much, since popups never release their
+	// iframes (see [22236])
+	var _frames = new function(){
+		// summary:
+		//		cache of iframes
+
+		var queue = [];
+
+		this.pop = function(){
+			var iframe;
+			if(queue.length){
+				iframe = queue.pop();
+				iframe.style.display="";
+			}else{
+				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);
+				}else{
+					iframe = domConstruct.create("iframe");
+					iframe.src = 'javascript:""';
+					iframe.className = "dijitBackgroundIframe";
+					iframe.setAttribute("role", "presentation");
+					domStyle.set(iframe, "opacity", 0.1);
+				}
+				iframe.tabIndex = -1; // Magic to prevent iframe from getting focus on tab keypress - as style didn't work.
+			}
+			return iframe;
+		};
+
+		this.push = function(iframe){
+			iframe.style.display="none";
+			queue.push(iframe);
+		}
+	}();
+
+
+	dijit.BackgroundIframe = function(/*DomNode*/ node){
+		// summary:
+		//		For IE/FF z-index schenanigans. 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
+
+		if(!node.id){ throw new Error("no id"); }
+		if(has("ie") || has("mozilla")){
+			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);
+				}));
+			}else{
+				domStyle.set(iframe, {
+					width: '100%',
+					height: '100%'
+				});
+			}
+		}
+	};
+
+	lang.extend(dijit.BackgroundIframe, {
+		resize: function(node){
+			// summary:
+			// 		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, {
+					width: node.offsetWidth + 'px',
+					height: node.offsetHeight + 'px'
+				});
+			}
+		},
+		destroy: function(){
+			// summary:
+			//		destroy the iframe
+			if(this._conn){
+				this._conn.remove();
+				this._conn = null;
+			}
+			if(this.iframe){
+				_frames.push(this.iframe);
+				delete this.iframe;
+			}
+		}
+	});
+
+	return dijit.BackgroundIframe;
+});
diff --git a/dijit/Calendar.js b/dijit/Calendar.js
index 6a11efd..a0e9846 100644
--- a/dijit/Calendar.js
+++ b/dijit/Calendar.js
@@ -1,55 +1,49 @@
-define("dijit/Calendar", ["dojo", "dijit", "text!dijit/templates/Calendar.html", "dojo/cldr/supplemental", "dojo/date", "dojo/date/locale", "dijit/_Widget", "dijit/_Templated", "dijit/_CssStateMixin", "dijit/form/DropDownButton"], function(dojo, dijit) {
+define([
+	"dojo/_base/array", // array.map
+	"dojo/date",
+	"dojo/date/locale",
+	"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")
+	"./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){
 
-dojo.declare(
-	"dijit.Calendar",
-	[dijit._Widget, dijit._Templated, dijit._CssStateMixin],
-	{
+/*=====
+	var CalendarLite = dijit.CalendarLite;
+	var _CssStateMixin = dijit._CssStateMixin;
+	var _Widget = dijit._Widget;
+	var _TemplatedMixin = dijit._TemplatedMixin;
+	var DropDownButton = dijit.form.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()
+		{
 		// summary:
 		//		A simple GUI for choosing a date in the context of a monthly calendar.
 		//
 		// 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.
-		//
-		//		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`
-		//		so that they are serializable and locale-independent.
-		//
-		// example:
-		//	|	var calendar = new dijit.Calendar({}, dojo.byId("calendarNode"));
-		//
-		// example:
-		//	|	<div dojoType="dijit.Calendar"></div>
-
-		templateString: dojo.cache("dijit", "templates/Calendar.html"),
-		widgetsInTemplate: true,
-
-		// value: Date
-		//		The currently selected Date, initially set to invalid date to indicate no selection.
-		value: new Date(""),
-		// TODO: for 2.0 make this a string (ISO format) rather than a Date
-
-		// datePackage: String
-		//		JavaScript namespace to find Calendar routines.  Uses Gregorian Calendar routines
-		//		at dojo.date by default.
-		datePackage: "dojo.date",
-
-		// dayWidth: String
-		//		How to represent the days of the week in the calendar header. See dojo.date.locale
-		dayWidth: "narrow",
-
-		// tabIndex: Integer
-		//		Order fields are traversed when user hits the tab key
-		tabIndex: "0",
-		
-		// currentFocus: Date
-		//		Date object containing the currently focused date, or the date which would be focused
-		//		if the calendar itself was focused.   Also indicates which year and month to display,
-		//		i.e. the current "page" the calendar is on.
-		currentFocus: new Date(),
-
-		baseClass:"dijitCalendar",
+		//		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)
 
 		// Set node classes for various mouse events, see dijit._CssStateMixin for more details
 		cssStateNodes: {
@@ -59,305 +53,37 @@ dojo.declare(
 			"nextYearLabelNode": "dijitCalendarNextYear"
 		},
 
-		_isValidDate: function(/*Date*/ value){
-			// summary:
-			//		Runs various tests on the value, checking that it's a valid date, rather
-			//		than blank or NaN.
-			// tags:
-			//		private
-			return value && !isNaN(value) && typeof value == "object" &&
-				value.toString() != this.constructor.prototype.value.toString();
-		},
-
 		setValue: function(/*Date*/ value){
 			// summary:
 			//      Deprecated.   Use set('value', ...) instead.
 			// tags:
 			//      deprecated
-			dojo.deprecated("dijit.Calendar:setValue() is deprecated.  Use set('value', ...) instead.", "", "2.0");
+			kernel.deprecated("dijit.Calendar:setValue() is deprecated.  Use set('value', ...) instead.", "", "2.0");
 			this.set('value', value);
 		},
 
-		_getValueAttr: function(){
-			// summary:
-			//		Support get('value')
-
-			// this.value is set to 1AM, but return midnight, local time for back-compat
-			var value = new this.dateClassObj(this.value);
-			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);
-			}
-			return value;
-		},
-
-		_setValueAttr: function(/*Date|Number*/ value, /*Boolean*/ priorityChange){
+		_createMonthWidget: function(){
 			// summary:
-			//		Support set("value", ...)
-			// description:
-			// 		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);
-			}
-			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'));
-							this.onValueSelected(this.get('value'));	// remove in 2.0
-						}
-					}
-				}
-			}else{
-				// clear value, and repopulate grid (to deselect the previously selected day) without changing currentFocus
-				this._set("value", null);
-				this.set("currentFocus", this.currentFocus);
-			}
-		},
-
-		_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
-			while(node.firstChild){
-				node.removeChild(node.firstChild);
-			}
-			node.appendChild(dojo.doc.createTextNode(text));
-		},
-
-		_populateGrid: function(){
-			// summary:
-			//      Fills in the calendar grid with each day (1-31)
-			// tags:
-			//      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)),
-				today = new this.dateClassObj(),
-				dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
-			if(dayOffset > firstDay){ dayOffset -= 7; }
-
-			// Iterate through dates in the calendar and fill in date numbers and style info
-			dojo.query(".dijitCalendarDateTemplate", this.domNode).forEach(function(template, i){
-				i += dayOffset;
-				var date = new this.dateClassObj(month),
-					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 = this.dateFuncObj.add(date, "month", adj);
-				}
-				date.setDate(number);
-
-				if(!this.dateFuncObj.compare(date, today, "date")){
-					clazz = "dijitCalendarCurrentDate " + clazz;
-				}
-
-				if(this._isSelectedDate(date, this.lang)){
-					clazz = "dijitCalendarSelectedDate " + clazz;
-				}
-
-				if(this.isDisabledDate(date, this.lang)){
-					clazz = "dijitCalendarDisabledDate " + clazz;
-				}
-
-				var clazz2 = this.getClassForDate(date, this.lang);
-				if(clazz2){
-					clazz = clazz2 + " " + clazz;
-				}
-
-				template.className = clazz + "Month dijitCalendarDateTemplate";
-				template.dijitDateValue = date.valueOf();				// original code
-				dojo.attr(template, "dijitDateValue", date.valueOf());	// so I can dojo.query() it
-				var label = dojo.query(".dijitCalendarDateLabel", template)[0],
-					text = date.getDateLocalized ? date.getDateLocalized(this.lang) : date.getDate();
-				this._setText(label, text);
-			}, this);
-
-			// Repopulate month drop down list based on current year.
-			// Need to do this to hide leap months in Hebrew calendar.
-			var monthNames = this.dateLocaleModule.getNames('months', 'wide', 'standAlone', this.lang, month);
-			this.monthDropDownButton.dropDown.set("months", monthNames);
-
-			// 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.monthDropDownButton.containerNode.innerHTML =
-				(dojo.isIE == 6 ? "" : "<div class='dijitSpacer'>" + this.monthDropDownButton.dropDown.domNode.innerHTML + "</div>") +
-				"<div class='dijitCalendarMonthLabel dijitCalendarCurrentMonthLabel'>" +  monthNames[month.getMonth()] + "</div>";
-
-			// Fill in localized prev/current/next years
-			var y = month.getFullYear() - 1;
-			var d = new this.dateClassObj();
-			dojo.forEach(["previous", "current", "next"], function(name){
-				d.setFullYear(y++);
-				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
-			this.set('value', new this.dateClassObj());
-		},
-
-		constructor: function(/*Object*/args){
-			var dateClass = (args.datePackage && (args.datePackage != "dojo.date"))? args.datePackage + ".Date" : "Date";
-			this.dateClassObj = dojo.getObject(dateClass, false);
-			this.datePackage = args.datePackage || this.datePackage;
-			this.dateFuncObj = dojo.getObject(this.datePackage, false);
-			this.dateLocaleModule = dojo.getObject(this.datePackage + ".locale", false);
-		},
-
-		postMixInProperties: function(){
-			// Parser.instantiate sometimes passes in NaN for IE.  Use default value in prototype instead.
-			// TODO: remove this for 2.0 (thanks to #11511)
-			if(isNaN(this.value)){ delete this.value; }
-
-			this.inherited(arguments);
+			//		Creates the drop down button that displays the current month and lets user pick a new one
+
+			return new Calendar._MonthDropDownButton({
+				id: this.id + "_mddb",
+				tabIndex: -1,
+				onMonthSelect: lang.hitch(this, "_onMonthSelect"),
+				lang: this.lang,
+				dateLocaleModule: this.dateLocaleModule
+			}, this.monthNode);
 		},
 
 		buildRendering: function(){
 			this.inherited(arguments);
-			dojo.setSelectable(this.domNode, false);
-
-			var cloneClass = dojo.hitch(this, function(clazz, n){
-				var template = dojo.query(clazz, this.domNode)[0];
-	 			for(var i=0; i<n; i++){
-					template.parentNode.appendChild(template.cloneNode(true));
-				}
-			});
-
-			// clone the day label and calendar day templates 6 times to make 7 columns
-			cloneClass(".dijitCalendarDayLabelTemplate", 6);
-			cloneClass(".dijitCalendarDateTemplate", 6);
 
-			// now make 6 week rows
-			cloneClass(".dijitCalendarWeekTemplate", 5);
-
-			// insert localized day names in the header
-			var dayNames = this.dateLocaleModule.getNames('days', this.dayWidth, 'standAlone', this.lang);
-			var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
-			dojo.query(".dijitCalendarDayLabel", this.domNode).forEach(function(label, i){
-				this._setText(label, dayNames[(i + dayOffset) % 7]);
-			}, this);
-
-			var dateObj = new this.dateClassObj(this.currentFocus);
-
-			this.monthDropDownButton.dropDown = new dijit.Calendar._MonthDropDown({
-				id: this.id + "_mdd",
-				onChange: dojo.hitch(this, "_onMonthSelect")
-			});
-
-			this.set('currentFocus', dateObj, false);	// draw the grid to the month specified by currentFocus
-
-			// Set up repeating mouse behavior for increment/decrement of months/years
-			var _this = this;
-			var typematic = function(nodeProp, dateProp, adj){
-				_this._connects.push(
-					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);
-			typematic("nextYearLabelNode", "year", 1);
-			typematic("previousYearLabelNode", "year", -1);
-		},
-
-		_adjustDisplay: function(/*String*/ part, /*int*/ amount){
-			// summary:
-			//      Moves calendar forwards or backwards by months or years
-			// part:
-			//      "month" or "year"
-			// amount:
-			//      Number of months or years
-			// tags:
-			//      private
-			this._setCurrentFocusAttr(this.dateFuncObj.add(this.currentFocus, part, amount));
-		},
-
-		_setCurrentFocusAttr: function(/*Date*/ date, /*Boolean*/ forceFocus){
-			// summary:
-			//		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.
-			// forceFocus:
-			//		If true, will focus() the cell even if calendar itself doesn't have focus
-
-			var oldFocus = this.currentFocus,
-				oldCell = oldFocus ? dojo.query("[dijitDateValue=" + oldFocus.valueOf() + "]", this.domNode)[0] : 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);
-
-			this._set("currentFocus", date);
-
-			// TODO: only re-populate grid when month/year has changed
-			this._populateGrid();
-
-			// 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];
-			newCell.setAttribute("tabIndex", this.tabIndex);
-			if(this._focused || forceFocus){
-				newCell.focus();
-			}
-
-			// set tabIndex=-1 on old focusable cell
-			if(oldCell && oldCell != newCell){
-				if(dojo.isWebKit){	// see #11064 about webkit bug
-					oldCell.setAttribute("tabIndex", "-1");
-				}else{
-						oldCell.removeAttribute("tabIndex");
-				}
-			}
-		},
-
-		focus: function(){
-			// summary:
-			//		Focus the calendar by focusing one of the calendar cells
-			this._setCurrentFocusAttr(this.currentFocus, true);
+			// 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");
 		},
 
 		_onMonthSelect: function(/*Number*/ newMonth){
@@ -368,21 +94,8 @@ dojo.declare(
 
 			// move to selected month, bounding by the number of days in the month
 			// (ex: dec 31 --> jan 28, not jan 31)
-			this.currentFocus = this.dateFuncObj.add(this.currentFocus, "month",
-				newMonth - this.currentFocus.getMonth());
-			this._populateGrid();
-		},
-
-		_onDayClick: function(/*Event*/ evt){
-			// summary:
-			//      Handler for day clicks, selects the date if appropriate
-			// tags:
-			//      protected
-			dojo.stopEvent(evt);
-			for(var node = evt.target; node && !node.dijitDateValue; node = node.parentNode);
-			if(node && !dojo.hasClass(node, "dijitCalendarDisabledDate")){
-				this.set('value', node.dijitDateValue);
-			}
+			this._setCurrentFocusAttr(this.dateFuncObj.add(this.currentFocus, "month",
+				newMonth - this.currentFocus.getMonth()));
 		},
 
 		_onDayMouseOver: function(/*Event*/ evt){
@@ -394,12 +107,15 @@ dojo.declare(
 			// event can occur on <td> or the <span> inside the td,
 			// set node to the <td>.
 			var node =
-				dojo.hasClass(evt.target, "dijitCalendarDateLabel") ?
+				domClass.contains(evt.target, "dijitCalendarDateLabel") ?
 				evt.target.parentNode :
 				evt.target;
 
-			if(node && (node.dijitDateValue || node == this.previousYearLabelNode || node == this.nextYearLabelNode) ){
-				dojo.addClass(node, "dijitCalendarHoveredDate");
+			if(node && (
+				(node.dijitDateValue && !domClass.contains(node, "dijitCalendarDisabledDate"))
+					|| node == this.previousYearLabelNode || node == this.nextYearLabelNode
+				)){
+				domClass.add(node, "dijitCalendarHoveredDate");
 				this._currentNode = node;
 			}
 		},
@@ -409,35 +125,34 @@ dojo.declare(
 			//      Handler for mouse out events on days, clears hovered style
 			// tags:
 			//      protected
-	
+
 			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; }
 			var cls = "dijitCalendarHoveredDate";
-			if(dojo.hasClass(this._currentNode, "dijitCalendarActiveDate")) {
+			if(domClass.contains(this._currentNode, "dijitCalendarActiveDate")){
 				cls += " dijitCalendarActiveDate";
 			}
-			dojo.removeClass(this._currentNode, cls);
+			domClass.remove(this._currentNode, cls);
 			this._currentNode = null;
 		},
-		
+
 		_onDayMouseDown: function(/*Event*/ evt){
 			var node = evt.target.parentNode;
-			if(node && node.dijitDateValue){
-				dojo.addClass(node, "dijitCalendarActiveDate");
+			if(node && node.dijitDateValue && !domClass.contains(node, "dijitCalendarDisabledDate")){
+				domClass.add(node, "dijitCalendarActiveDate");
 				this._currentNode = node;
 			}
 		},
-		
+
 		_onDayMouseUp: function(/*Event*/ evt){
 			var node = evt.target.parentNode;
 			if(node && node.dijitDateValue){
-				dojo.removeClass(node, "dijitCalendarActiveDate");
+				domClass.remove(node, "dijitCalendarActiveDate");
 			}
 		},
 
-//TODO: use typematic
 		handleKey: function(/*Event*/ evt){
 			// summary:
 			//		Provides keyboard navigation of calendar.
@@ -450,42 +165,41 @@ dojo.declare(
 			//		to indicate that the event was handled by Calendar and shouldn't be propogated
 			// tags:
 			//		protected
-			var dk = dojo.keys,
-				increment = -1,
+			var increment = -1,
 				interval,
 				newValue = this.currentFocus;
-			switch(evt.keyCode){
-				case dk.RIGHT_ARROW:
+			switch(evt.charOrCode){
+				case keys.RIGHT_ARROW:
 					increment = 1;
 					//fallthrough...
-				case dk.LEFT_ARROW:
+				case keys.LEFT_ARROW:
 					interval = "day";
 					if(!this.isLeftToRight()){ increment *= -1; }
 					break;
-				case dk.DOWN_ARROW:
+				case keys.DOWN_ARROW:
 					increment = 1;
 					//fallthrough...
-				case dk.UP_ARROW:
+				case keys.UP_ARROW:
 					interval = "week";
 					break;
-				case dk.PAGE_DOWN:
+				case keys.PAGE_DOWN:
 					increment = 1;
 					//fallthrough...
-				case dk.PAGE_UP:
+				case keys.PAGE_UP:
 					interval = evt.ctrlKey || evt.altKey ? "year" : "month";
 					break;
-				case dk.END:
+				case keys.END:
 					// go to the next month
 					newValue = this.dateFuncObj.add(newValue, "month", 1);
 					// subtract a day from the result when we're done
 					interval = "day";
 					//fallthrough...
-				case dk.HOME:
+				case keys.HOME:
 					newValue = new this.dateClassObj(newValue);
 					newValue.setDate(1);
 					break;
-				case dk.ENTER:
-				case dk.SPACE:
+				case keys.ENTER:
+				case " ":
 					this.set("value", this.currentFocus);
 					break;
 				default:
@@ -505,13 +219,13 @@ dojo.declare(
 			// summary:
 			//		For handling keypress events on a stand alone calendar
 			if(!this.handleKey(evt)){
-				dojo.stopEvent(evt);
+				event.stop(evt);
 			}
 		},
 
-		onValueSelected: function(/*Date*/ date){
+		onValueSelected: function(/*Date*/ /*===== date =====*/){
 			// summary:
-			//		Notification that a date cell was selected.  It may be the same as the previous value.
+			//		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.
@@ -519,34 +233,16 @@ dojo.declare(
 			//      protected
 		},
 
-		onChange: function(/*Date*/ date){
-			// summary:
-			//		Called only when the selected date has changed
-		},
-
-		_isSelectedDate: function(/*Date*/ dateObject, /*String?*/ locale){
-			// summary:
-			//		Extension point so developers can subclass Calendar to
-			//		support multiple (concurrently) selected dates
-			// tags:
-			//		protected extension
-			return this._isValidDate(this.value) && !this.dateFuncObj.compare(dateObject, this.value, "date")
-		},
-
-		isDisabledDate: function(/*Date*/ dateObject, /*String?*/ locale){
-			// summary:
-			//		May be overridden to disable certain dates in the calendar e.g. `isDisabledDate=dojo.date.locale.isWeekend`
-			// tags:
-			//      extension
-/*=====
-			return false; // Boolean
-=====*/
+		onChange: function(value){
+			this.onValueSelected(value);	// remove in 2.0
 		},
 
-		getClassForDate: function(/*Date*/ dateObject, /*String?*/ locale){
+		getClassForDate: function(/*===== dateObject, 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.
+			// dateObject: Date
+			// locale: String?
 			// tags:
 			//      extension
 
@@ -554,40 +250,68 @@ dojo.declare(
 			return ""; // String
 =====*/
 		}
-	}
-);
-
-dojo.declare("dijit.Calendar._MonthDropDown", [dijit._Widget, dijit._Templated], {
-	// summary:
-	//		The month drop down
+	});
 
-	// months: String[]
-	//		List of names of months, possibly w/some undefined entries for Hebrew leap months
-	//		(ex: ["January", "February", undefined, "April", ...])
-	months: [],
+	Calendar._MonthDropDownButton = declare("dijit.Calendar._MonthDropDownButton", DropDownButton, {
+		// summary:
+		//		DropDownButton for the current month.    Displays name of current month
+		//		and a list of month names in the drop down
 
-	templateString: "<div class='dijitCalendarMonthMenu dijitMenu' " +
-		"dojoAttachEvent='onclick:_onClick,onmouseover:_onMenuHover,onmouseout:_onMenuHover'></div>",
+		onMonthSelect: function(){ },
 
-	_setMonthsAttr: function(/*String[]*/ months){
-		this.domNode.innerHTML = dojo.map(months, function(month, idx){
-				return month ? "<div class='dijitCalendarMonthLabel' month='" + idx +"'>" + month + "</div>" : "";
-			}).join("");
-	},
+		postCreate: function(){
+			this.inherited(arguments);
+			this.dropDown = new Calendar._MonthDropDown({
+				id: this.id + "_mdd", //do not change this id because it is referenced in the template
+				onChange: this.onMonthSelect
+			});
+		},
+		_setMonthAttr: function(month){
+			// summary:
+			//		Set the current month to display as a label
+			var monthNames = this.dateLocaleModule.getNames('months', 'wide', 'standAlone', this.lang, month);
+			this.dropDown.set("months", monthNames);
 
-	_onClick: function(/*Event*/ evt){
-		this.onChange(dojo.attr(evt.target, "month"));
-	},
+			// 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.containerNode.innerHTML =
+				(has("ie") == 6 ? "" : "<div class='dijitSpacer'>" + this.dropDown.domNode.innerHTML + "</div>") +
+				"<div class='dijitCalendarMonthLabel dijitCalendarCurrentMonthLabel'>" +  monthNames[month.getMonth()] + "</div>";
+		}
+	});
 
-	onChange: function(/*Number*/ month){
+	Calendar._MonthDropDown = declare("dijit.Calendar._MonthDropDown", [_Widget, _TemplatedMixin], {
 		// summary:
-		//		Callback when month is selected from drop down
-	},
+		//		The list-of-months drop down from the MonthDropDownButton
 
-	_onMenuHover: function(evt){
-		dojo.toggleClass(evt.target, "dijitCalendarMonthLabelHover", evt.type == "mouseover");
-	}
-});
+		// months: String[]
+		//		List of names of months, possibly w/some undefined entries for Hebrew leap months
+		//		(ex: ["January", "February", undefined, "April", ...])
+		months: [],
+
+		templateString: "<div class='dijitCalendarMonthMenu dijitMenu' " +
+			"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("");
+		},
+
+		_onClick: function(/*Event*/ evt){
+			this.onChange(domAttr.get(evt.target, "month"));
+		},
+
+		onChange: function(/*Number*/ /*===== month =====*/){
+			// summary:
+			//		Callback when month is selected from drop down
+		},
+
+		_onMenuHover: function(evt){
+			domClass.toggle(evt.target, "dijitCalendarMonthLabelHover", evt.type == "mouseover");
+		}
+	});
 
-return dijit.Calendar;
+	return Calendar;
 });
diff --git a/dijit/CalendarLite.js b/dijit/CalendarLite.js
new file mode 100644
index 0000000..66da5c6
--- /dev/null
+++ b/dijit/CalendarLite.js
@@ -0,0 +1,451 @@
+define([
+	"dojo/_base/array", // array.forEach array.map
+	"dojo/_base/declare", // declare
+	"dojo/cldr/supplemental", // cldrSupplemental.getFirstDayOfWeek
+	"dojo/date", // date
+	"dojo/date/locale",
+	"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/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){
+
+/*=====
+	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:
+		//		Lightweight version of Calendar widget aimed towards mobile use
+		//
+		// 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.
+		//
+		//		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`
+		//		so that they are serializable and locale-independent.
+		//
+		//		Also note that this widget isn't keyboard accessible; use dijit.Calendar for that
+		// example:
+		//	|	var calendar = new dijit.CalendarLite({}, dojo.byId("calendarNode"));
+		//
+		// example:
+		//	|	<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>',
+
+		// 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>',
+		weekTemplateString: '<tr class="dijitReset dijitCalendarWeekTemplate" role="row">${d}${d}${d}${d}${d}${d}${d}</tr>',
+
+		// value: Date
+		//		The currently selected Date, initially set to invalid date to indicate no selection.
+		value: new Date(""),
+		// 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,
+
+		// dayWidth: String
+		//		How to represent the days of the week in the calendar header. See locale
+		dayWidth: "narrow",
+
+		// tabIndex: Integer
+		//		Order fields are traversed when user hits the tab key
+		tabIndex: "0",
+
+		// currentFocus: Date
+		//		Date object containing the currently focused date, or the date which would be focused
+		//		if the calendar itself was focused.   Also indicates which year and month to display,
+		//		i.e. the current "page" the calendar is on.
+		currentFocus: new Date(),
+
+		baseClass:"dijitCalendar",
+
+		_isValidDate: function(/*Date*/ value){
+			// summary:
+			//		Runs various tests on the value, checking that it's a valid date, rather
+			//		than blank or NaN.
+			// tags:
+			//		private
+			return value && !isNaN(value) && typeof value == "object" &&
+				value.toString() != this.constructor.prototype.value.toString();
+		},
+
+		_getValueAttr: function(){
+			// summary:
+			//		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);
+				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);
+				}
+				return value;
+			}else{
+				return null;
+			}
+		},
+
+		_setValueAttr: function(/*Date|Number*/ value, /*Boolean*/ priorityChange){
+			// summary:
+			//		Support set("value", ...)
+			// description:
+			// 		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);
+			}
+			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'));
+						}
+					}
+				}
+			}else{
+				// clear value, and repopulate grid (to deselect the previously selected day) without changing currentFocus
+				this._set("value", null);
+				this.set("currentFocus", this.currentFocus);
+			}
+		},
+
+		_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
+			while(node.firstChild){
+				node.removeChild(node.firstChild);
+			}
+			node.appendChild(win.doc.createTextNode(text));
+		},
+
+		_populateGrid: function(){
+			// summary:
+			//      Fills in the calendar grid with each day (1-31)
+			// tags:
+			//      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)),
+				today = new this.dateClassObj(),
+				dayOffset = cldrSupplemental.getFirstDayOfWeek(this.lang);
+			if(dayOffset > firstDay){ dayOffset -= 7; }
+
+			// Mapping from date (as specified by number returned from Date.valueOf()) to corresponding <td>
+			this._date2cell = {};
+
+			// Iterate through dates in the calendar and fill in date numbers and style info
+			array.forEach(this.dateCells, function(template, idx){
+				var i = idx + dayOffset;
+				var date = new this.dateClassObj(month),
+					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 = this.dateFuncObj.add(date, "month", adj);
+				}
+				date.setDate(number);
+
+				if(!this.dateFuncObj.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);
+				}else{
+					clazz = "dijitCalendarEnabledDate " + clazz;
+					template.removeAttribute("aria-disabled");
+				}
+
+				var clazz2 = this.getClassForDate(date, this.lang);
+				if(clazz2){
+					clazz = clazz2 + " " + clazz;
+				}
+
+				template.className = clazz + "Month dijitCalendarDateTemplate";
+
+				// Each cell has an associated integer value representing it's date
+				var dateVal = date.valueOf();
+				this._date2cell[dateVal] = template;
+				template.dijitDateValue = dateVal;
+
+				// Set Date string (ex: "13").
+				this._setText(this.dateLabels[idx], date.getDateLocalized ? date.getDateLocalized(this.lang) : date.getDate());
+			}, this);
+
+			// 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);
+		},
+
+		goToToday: function(){
+			// summary:
+			//      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);
+		},
+
+		_createMonthWidget: function(){
+			// summary:
+			//		Creates the drop down button that displays the current month and lets user pick a new one
+
+			return CalendarLite._MonthWidget({
+				id: this.id + "_mw",
+				lang: this.lang,
+				dateLocaleModule: this.dateLocaleModule
+			}, this.monthNode);
+		},
+
+		buildRendering: function(){
+			// Markup for days of the week (referenced from template)
+			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]
+			});
+
+			// 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("");
+
+			// Instantiate from template.
+			// dateCells and dateLabels arrays filled when _Templated parses my template.
+			this.dateCells = [];
+			this.dateLabels = [];
+			this.inherited(arguments);
+
+			dom.setSelectable(this.domNode, false);
+
+			var dateObj = new this.dateClassObj(this.currentFocus);
+
+			this._supportingWidgets.push(this.monthWidget = this._createMonthWidget());
+
+			this.set('currentFocus', dateObj, false);	// draw the grid to the month specified by currentFocus
+
+			// 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));
+				});
+			});
+			connect("incrementMonth", "month", 1);
+			connect("decrementMonth", "month", -1);
+			connect("nextYearLabelNode", "year", 1);
+			connect("previousYearLabelNode", "year", -1);
+		},
+
+		_setCurrentFocusAttr: function(/*Date*/ date, /*Boolean*/ forceFocus){
+			// summary:
+			//		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.
+			// 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);
+
+			this._set("currentFocus", date);
+
+			// TODO: only re-populate grid when month/year has changed
+			this._populateGrid();
+
+			// set tabIndex=0 on new cell, and focus it (but only if Calendar itself is focused)
+			var newCell = this._date2cell[date.valueOf()];
+			newCell.setAttribute("tabIndex", this.tabIndex);
+			if(this.focused || forceFocus){
+				newCell.focus();
+			}
+
+			// set tabIndex=-1 on old focusable cell
+			if(oldCell && oldCell != newCell){
+				if(has("webkit")){	// see #11064 about webkit bug
+					oldCell.setAttribute("tabIndex", "-1");
+				}else{
+					oldCell.removeAttribute("tabIndex");
+				}
+			}
+		},
+
+		focus: function(){
+			// summary:
+			//		Focus the calendar by focusing one of the calendar cells
+			this._setCurrentFocusAttr(this.currentFocus, true);
+		},
+
+		_onDayClick: function(/*Event*/ evt){
+			// summary:
+			//      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);
+			if(node && !domClass.contains(node, "dijitCalendarDisabledDate")){
+				this.set('value', node.dijitDateValue);
+			}
+		},
+
+		onChange: function(/*Date*/ /*===== date =====*/){
+			// summary:
+			//		Called only when the selected date has changed
+		},
+
+		_isSelectedDate: function(dateObject /*===== , locale =====*/){
+			// 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")
+		},
+
+		isDisabledDate: function(/*===== dateObject, locale =====*/){
+			// summary:
+			//		May be overridden to disable certain dates in the calendar e.g. `isDisabledDate=dojo.date.locale.isWeekend`
+			// dateObject: Date
+			// locale: String?
+			// tags:
+			//      extension
+/*=====
+			return false; // Boolean
+=====*/
+		},
+
+		getClassForDate: function(/*===== dateObject, 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.
+			// dateObject: Date
+			// locale: String?
+			// tags:
+			//      extension
+
+/*=====
+			return ""; // String
+=====*/
+		}
+	});
+
+	CalendarLite._MonthWidget = declare("dijit.CalendarLite._MonthWidget", _WidgetBase, {
+		// summary:
+		//		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: ...
+		//		})
+
+		_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>");
+
+			// 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>";
+		}
+	});
+
+	return CalendarLite;
+});
diff --git a/dijit/CheckedMenuItem.js b/dijit/CheckedMenuItem.js
index 90154b9..8627f87 100644
--- a/dijit/CheckedMenuItem.js
+++ b/dijit/CheckedMenuItem.js
@@ -1,12 +1,25 @@
-define("dijit/CheckedMenuItem", ["dojo", "dijit", "text!dijit/templates/CheckedMenuItem.html", "dijit/MenuItem"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/dom-class", // domClass.toggle
+	"./MenuItem",
+	"dojo/text!./templates/CheckedMenuItem.html",
+	"./hccss"
+], function(declare, domClass, MenuItem, template){
 
-dojo.declare("dijit.CheckedMenuItem",
-		dijit.MenuItem,
-		{
+/*=====
+	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
 
-		templateString: dojo.cache("dijit", "templates/CheckedMenuItem.html"),
+		templateString: template,
 
 		// checked: Boolean
 		//		Our checked state
@@ -15,12 +28,14 @@ dojo.declare("dijit.CheckedMenuItem",
 			// summary:
 			//		Hook so attr('checked', bool) works.
 			//		Sets the class and state for the check box.
-			dojo.toggleClass(this.domNode, "dijitCheckedMenuItemChecked", checked);
-			dijit.setWaiState(this.domNode, "checked", checked);
+			domClass.toggle(this.domNode, "dijitCheckedMenuItemChecked", checked);
+			this.domNode.setAttribute("aria-checked", checked);
 			this._set("checked", checked);
 		},
 
-		onChange: function(/*Boolean*/ checked){
+		iconClass: "",	// override dijitNoIcon
+
+		onChange: function(/*Boolean*/ /*===== checked =====*/){
 			// summary:
 			//		User defined function to handle check/uncheck events
 			// tags:
@@ -39,7 +54,4 @@ dojo.declare("dijit.CheckedMenuItem",
 			this.inherited(arguments);
 		}
 	});
-
-
-return dijit.CheckedMenuItem;
 });
diff --git a/dijit/ColorPalette.js b/dijit/ColorPalette.js
index 0e60d61..ef41250 100644
--- a/dijit/ColorPalette.js
+++ b/dijit/ColorPalette.js
@@ -1,8 +1,33 @@
-define("dijit/ColorPalette", ["dojo", "dijit", "text!dijit/templates/ColorPalette.html", "dijit/_Widget", "dijit/_Templated", "dojo/colors", "dojo/i18n", "dojo/string", "dijit/_PaletteMixin", "i18n!dojo/nls/colors"], function(dojo, dijit) {
-
-dojo.declare("dijit.ColorPalette",
-	[dijit._Widget, dijit._Templated, dijit._PaletteMixin],
-	{
+define([
+	"require",		// require.toUrl
+	"dojo/text!./templates/ColorPalette.html",
+	"./_Widget",
+	"./_TemplatedMixin",
+	"./_PaletteMixin",
+	"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:
@@ -10,7 +35,7 @@ dojo.declare("dijit.ColorPalette",
 	//		Can be used standalone, or as a popup.
 	//
 	// example:
-	// |	<div dojoType="dijit.ColorPalette"></div>
+	// |	<div data-dojo-type="dijit.ColorPalette"></div>
 	//
 	// example:
 	// |	var picker = new dijit.ColorPalette({ },srcNode);
@@ -41,29 +66,35 @@ dojo.declare("dijit.ColorPalette",
 
 	// templateString: String
 	//		The template of this widget.
-	templateString: dojo.cache("dijit", "templates/ColorPalette.html"),
+	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.
-		// Pass in "customized" dijit._Color constructor for specified palette and high-contrast vs. normal mode
 		this._preparePalette(
 			this._palettes[this.palette],
-			dojo.i18n.getLocalization("dojo", "colors", this.lang),
-			dojo.declare(dijit._Color, {
-				hc: dojo.hasClass(dojo.body(), "dijit_a11y"),
-				palette: this.palette
-			})
-		);
+			i18n.getLocalization("dojo", "colors", this.lang));
 	}
 });
 
-dojo.declare("dijit._Color", dojo.Color, {
+ColorPalette._Color = declare("dijit._Color", Color, {
 	// summary:
 	//		Object associated with each cell in a ColorPalette palette.
 	//		Implements dijit.Dye.
@@ -86,15 +117,15 @@ dojo.declare("dijit._Color", dojo.Color, {
 	// _imagePaths: [protected] Map
 	//		This is stores the path to the palette images used for high-contrast mode display
 	_imagePaths: {
-		"7x10": dojo.moduleUrl("dijit.themes", "a11y/colors7x10.png"),
-		"3x4": dojo.moduleUrl("dijit.themes", "a11y/colors3x4.png")
+		"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(dojo.Color.named[alias]);
+		this.setColor(Color.named[alias]);
 	},
 
 	getValue: function(){
@@ -105,12 +136,12 @@ dojo.declare("dijit._Color", dojo.Color, {
 	},
 
 	fillCell: function(/*DOMNode*/ cell, /*String*/ blankGif){
-		var html = dojo.string.substitute(this.hc ? this.hcTemplate : this.template, {
+		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,
@@ -118,10 +149,10 @@ dojo.declare("dijit._Color", dojo.Color, {
 			size: this.palette == "7x10" ? "height: 145px; width: 206px" : "height: 64px; width: 86px"
 		});
 
-		dojo.place(html, cell);
+		domConstruct.place(html, cell);
 	}
 });
 
 
-return dijit.ColorPalette;
+return ColorPalette;
 });
diff --git a/dijit/Declaration.js b/dijit/Declaration.js
index a62f6e0..e885277 100644
--- a/dijit/Declaration.js
+++ b/dijit/Declaration.js
@@ -1,9 +1,29 @@
-define("dijit/Declaration", ["dojo", "dijit", "dijit/_Widget", "dijit/_Templated"], function(dojo, dijit) {
-
-dojo.declare(
-	"dijit.Declaration",
-	dijit._Widget,
-	{
+define([
+	"dojo/_base/array", // array.forEach array.map
+	"dojo/_base/connect", // connect.connect
+	"dojo/_base/declare", // declare
+	"dojo/_base/lang", // lang.getObject
+	"dojo/parser", // parser._functionFromScript
+	"dojo/query", // query
+	"./_Widget",
+	"./_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;
+=====*/
+
+	// 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:
 		//		The Declaration widget allows a developer to declare new widget
 		//		classes directly from a snippet of markup.
@@ -32,8 +52,8 @@ dojo.declare(
 
 		buildRendering: function(){
 			var src = this.srcNodeRef.parentNode.removeChild(this.srcNodeRef),
-				methods = dojo.query("> script[type^='dojo/method']", src).orphan(),
-				connects = dojo.query("> script[type^='dojo/connect']", src).orphan(),
+				methods = query("> script[type^='dojo/method']", src).orphan(),
+				connects = query("> script[type^='dojo/connect']", src).orphan(),
 				srcType = src.nodeName;
 
 			var propList = this.defaults || {};
@@ -42,9 +62,9 @@ dojo.declare(
 			// add that method to prototype.
 			// If there's no "event" specified then it's code to run on instantiation,
 			// so it becomes a connection to "postscript" (handled below).
-			dojo.forEach(methods, function(s){
+			array.forEach(methods, function(s){
 				var evt = s.getAttribute("event") || s.getAttribute("data-dojo-event"),
-					func = dojo.parser._functionFromScript(s);
+					func = parser._functionFromScript(s);
 				if(evt){
 					propList[evt] = func;
 				}else{
@@ -53,23 +73,23 @@ dojo.declare(
 			});
 
 			// map array of strings like [ "dijit.form.Button" ] to array of mixin objects
-			// (note that dojo.map(this.mixins, dojo.getObject) doesn't work because it passes
+			// (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 ?
-				dojo.map(this.mixins, function(name){ return dojo.getObject(name); } ) :
-				[ dijit._Widget, dijit._Templated ];
+				array.map(this.mixins, function(name){ return lang.getObject(name); } ) :
+				[ _Widget, _TemplatedMixin, _WidgetsInTemplateMixin ];
 
-			propList.widgetsInTemplate = true;
 			propList._skipNodeCache = true;
-			propList.templateString = "<"+srcType+" class='"+src.className+"' dojoAttachPoint='"+(src.getAttribute("dojoAttachPoint") || '')+"' dojoAttachEvent='"+(src.getAttribute("dojoAttachEvent") || '')+"' >"+src.innerHTML.replace(/\%7B/g,"{").replace(/\%7D/g,"}")+"</"+srcType+">";
-
-			// strip things so we don't create stuff under us in the initial setup phase
-			dojo.query("[dojoType]", src).forEach(function(node){
-				node.removeAttribute("dojoType");
-			});
+			propList.templateString =
+				"<"+srcType+" class='"+src.className+"'" +
+				" data-dojo-attach-point='"+
+					(src.getAttribute("data-dojo-attach-point") || src.getAttribute("dojoAttachPoint") || '')+
+				"' data-dojo-attach-event='"+
+					(src.getAttribute("data-dojo-attach-event") || src.getAttribute("dojoAttachEvent") || '')+
+				"' >"+src.innerHTML.replace(/\%7B/g,"{").replace(/\%7D/g,"}")+"</"+srcType+">";
 
 			// create the new widget class
-			var wc = dojo.declare(
+			var wc = declare(
 				this.widgetClass,
 				this.mixins,
 				propList
@@ -82,15 +102,11 @@ dojo.declare(
 			// (Note that the second one is just shorthand for a dojo/connect to postscript)
 			// Since this is a connect in the declaration, we are actually connection to the method
 			// in the _prototype_.
-			dojo.forEach(connects, function(s){
+			array.forEach(connects, function(s){
 				var evt = s.getAttribute("event") || s.getAttribute("data-dojo-event") || "postscript",
-					func = dojo.parser._functionFromScript(s);
-				dojo.connect(wc.prototype, evt, func);
+					func = parser._functionFromScript(s);
+				connect.connect(wc.prototype, evt, func);
 			});
 		}
-	}
-);
-
-
-return dijit.Declaration;
+	});
 });
diff --git a/dijit/Dialog.js b/dijit/Dialog.js
index 1076e24..387ee2d 100644
--- a/dijit/Dialog.js
+++ b/dijit/Dialog.js
@@ -1,22 +1,71 @@
-define("dijit/Dialog", ["dojo", "dijit", "text!dijit/templates/Dialog.html", "dojo/dnd/move", "dojo/dnd/TimedMoveable", "dojo/fx", "dojo/window", "dijit/_Widget", "dijit/_Templated", "dijit/_CssStateMixin", "dijit/form/_FormMixin",  "dijit/_DialogMixin", "dijit/DialogUnderlay", "dijit/layout/ContentPane", "i18n!dijit/nls/common", "dijit/TooltipDialog"], function(dojo, dijit) {
+define([
+	"require",
+	"dojo/_base/array", // array.forEach array.indexOf array.map
+	"dojo/_base/connect", // connect._keypress
+	"dojo/_base/declare", // declare
+	"dojo/_base/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/dnd/Moveable", // Moveable
+	"dojo/dnd/TimedMoveable", // TimedMoveable
+	"./focus",
+	"./_base/manager",	// manager.defaultDuration
+	"./_Widget",
+	"./_TemplatedMixin",
+	"./_CssStateMixin",
+	"./form/_FormMixin",
+	"./_DialogMixin",
+	"./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,
+			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;
+=====*/	
 
-// dijit/TooltipDialog required for back-compat.  TODO: remove in 2.0
 
-/*=====
-dijit._underlay = function(kwArgs){
+	// module:
+	//		dijit/Dialog
 	// summary:
-	//		A shared instance of a `dijit.DialogUnderlay`
-	//
-	// description:
-	//		A shared instance of a `dijit.DialogUnderlay` created and
-	//		used by `dijit.Dialog`, though never created until some Dialog
-	//		or subclass thereof is shown.
-};
-=====*/
-dojo.declare(
-	"dijit._DialogBase",
-	[dijit._Templated, dijit.form._FormMixin, dijit._DialogMixin, dijit._CssStateMixin],
-	{
+	//		A modal dialog Widget
+
+
+	/*=====
+	dijit._underlay = function(kwArgs){
+		// summary:
+		//		A shared instance of a `dijit.DialogUnderlay`
+		//
+		// description:
+		//		A shared instance of a `dijit.DialogUnderlay` created and
+		//		used by `dijit.Dialog`, though never created until some Dialog
+		//		or subclass thereof is shown.
+	};
+	=====*/
+
+	var _DialogBase = declare("dijit._DialogBase", [_TemplatedMixin, _FormMixin, _DialogMixin, _CssStateMixin], {
 		// summary:
 		//		A modal dialog Widget
 		//
@@ -26,28 +75,26 @@ dojo.declare(
 		//		ContentPane so it supports all the same parameters (href, etc.)
 		//
 		// example:
-		// |	<div dojoType="dijit.Dialog" href="test.html"></div>
+		// |	<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();
 
-		templateString: dojo.cache("dijit", "templates/Dialog.html"),
-		
+		templateString: template,
+
 		baseClass: "dijitDialog",
-		
+
 		cssStateNodes: {
 			closeButtonNode: "dijitDialogCloseIcon"
 		},
 
-		attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
-			title: [
-				{ node: "titleNode", type: "innerHTML" },
-				{ node: "titleBar", type: "attribute" }
-			],
-			"aria-describedby":""
-		}),
+		// Map widget attributes to DOMNode attributes.
+		_setTitleAttr: [
+			{ node: "titleNode", type: "innerHTML" },
+			{ node: "titleBar", type: "attribute" }
+		],
 
 		// open: [readonly] Boolean
 		//		True if Dialog is currently displayed on screen.
@@ -55,7 +102,7 @@ dojo.declare(
 
 		// duration: Integer
 		//		The time in milliseconds it takes the dialog to fade in and out
-		duration: dijit.defaultDuration,
+		duration: manager.defaultDuration,
 
 		// refocus: Boolean
 		// 		A Toggle to modify the default focus behavior of a Dialog, which
@@ -96,24 +143,24 @@ dojo.declare(
 		//		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 dojoType="dijit.Dialog" aria-describedby="intro" .....>
+		//		<div data-dojo-type="dijit.Dialog" aria-describedby="intro" .....>
 		//			<div id="intro">Introductory text</div>
 		//			<div>rest of dialog contents</div>
 		//		</div>
 		"aria-describedby":"",
 
 		postMixInProperties: function(){
-			var _nlsResources = dojo.i18n.getLocalization("dijit", "common");
-			dojo.mixin(this, _nlsResources);
+			var _nlsResources = i18n.getLocalization("dijit", "common");
+			lang.mixin(this, _nlsResources);
 			this.inherited(arguments);
 		},
 
 		postCreate: function(){
-			dojo.style(this.domNode, {
+			domStyle.set(this.domNode, {
 				display: "none",
 				position:"absolute"
 			});
-			dojo.body().appendChild(this.domNode);
+			win.body().appendChild(this.domNode);
 
 			this.inherited(arguments);
 
@@ -133,21 +180,23 @@ dojo.declare(
 			// when href is specified we need to reposition the dialog after the data is loaded
 			// and find the focusable elements
 			this._position();
-			if(this.autofocus && dijit._DialogLevelManager.isTop(this)){
+			if(this.autofocus && DialogLevelManager.isTop(this)){
 				this._getFocusItems(this.domNode);
-				dijit.focus(this._firstFocusItem);
+				focus.focus(this._firstFocusItem);
 			}
 			this.inherited(arguments);
 		},
 
-		_endDrag: function(e){
+		_endDrag: function(){
 			// summary:
-			//		Called after dragging the Dialog. Saves the position of the dialog in the viewport.
-			// tags:
-			//		private
-			if(e && e.node && e.node === this.domNode){
-				this._relativePosition = dojo.position(e.node);
-			}
+			//		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();
+			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;
+			this._position();
 		},
 
 		_setup: function(){
@@ -161,17 +210,16 @@ dojo.declare(
 			var node = this.domNode;
 
 			if(this.titleBar && this.draggable){
-				this._moveable = (dojo.isIE == 6) ?
-					new dojo.dnd.TimedMoveable(node, { handle: this.titleBar }) :	// prevent overload, see #5285
-					new dojo.dnd.Moveable(node, { handle: this.titleBar, timeout: 0 });
-				this._dndListener = dojo.subscribe("/dnd/move/stop",this,"_endDrag");
+				this._moveable = new ((has("ie") == 6) ? TimedMoveable // prevent overload, see #5285
+					: Moveable)(node, { handle: this.titleBar });
+				this.connect(this._moveable, "onMoveStop", "_endDrag");
 			}else{
-				dojo.addClass(node,"dijitDialogFixed");
+				domClass.add(node,"dijitDialogFixed");
 			}
 
 			this.underlayAttrs = {
 				dialogId: this.id,
-				"class": dojo.map(this["class"].split(/\s/), function(s){ return s+"_underlay"; }).join(" ")
+				"class": array.map(this["class"].split(/\s/), function(s){ return s+"_underlay"; }).join(" ")
 			};
 		},
 
@@ -185,32 +233,32 @@ dojo.declare(
 
 			// If we resized the dialog contents earlier, reset them back to original size, so
 			// that if the user later increases the viewport size, the dialog can display w/out a scrollbar.
-			// Need to do this before the dojo.marginBox(this.domNode) call below.
+			// Need to do this before the domGeometry.position(this.domNode) call below.
 			if(this._singleChild){
 				if(this._singleChildOriginalStyle){
 					this._singleChild.domNode.style.cssText = this._singleChildOriginalStyle;
 				}
 				delete this._singleChildOriginalStyle;
 			}else{
-				dojo.style(this.containerNode, {
+				domStyle.set(this.containerNode, {
 					width:"auto",
 					height:"auto"
 				});
 			}
 
-			var mb = dojo._getMarginSize(this.domNode);
-			var viewport = dojo.window.getBox();
-			if(mb.w >= viewport.w || mb.h >= viewport.h){
+			var bb = domGeometry.position(this.domNode);
+			var viewport = winUtils.getBox();
+			if(bb.w >= viewport.w || bb.h >= viewport.h){
 				// Reduce size of dialog contents so that dialog fits in viewport
 
-				var w = Math.min(mb.w, Math.floor(viewport.w * 0.75)),
-					h = Math.min(mb.h, Math.floor(viewport.h * 0.75));
+				var w = Math.min(bb.w, Math.floor(viewport.w * 0.75)),
+					h = Math.min(bb.h, Math.floor(viewport.h * 0.75));
 
 				if(this._singleChild && this._singleChild.resize){
 					this._singleChildOriginalStyle = this._singleChild.domNode.style.cssText;
 					this._singleChild.resize({w: w, h: h});
 				}else{
-					dojo.style(this.containerNode, {
+					domStyle.set(this.containerNode, {
 						width: w + "px",
 						height: h + "px",
 						overflow: "auto",
@@ -230,17 +278,15 @@ dojo.declare(
 			//		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.
-			// tags:
-			//		private
-			if(!dojo.hasClass(dojo.body(),"dojoMove")){
+			if(!domClass.contains(win.body(), "dojoMove")){	// don't do anything if called during auto-scroll
 				var node = this.domNode,
-					viewport = dojo.window.getBox(),
+					viewport = winUtils.getBox(),
 					p = this._relativePosition,
-					bb = p ? null : dojo._getBorderBox(node),
+					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))
 				;
-				dojo.style(node,{
+				domStyle.set(node,{
 					left: l + "px",
 					top: t + "px"
 				});
@@ -254,28 +300,27 @@ dojo.declare(
 			//		private
 
 			if(evt.charOrCode){
-				var dk = dojo.keys;
 				var node = evt.target;
-				if(evt.charOrCode === dk.TAB){
+				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 === dk.TAB){
+				if(node == this._firstFocusItem && evt.shiftKey && evt.charOrCode === keys.TAB){
 					if(!singleFocusItem){
-						dijit.focus(this._lastFocusItem); // send focus to last item in dialog
+						focus.focus(this._lastFocusItem); // send focus to last item in dialog
 					}
-					dojo.stopEvent(evt);
-				}else if(node == this._lastFocusItem && evt.charOrCode === dk.TAB && !evt.shiftKey){
+					event.stop(evt);
+				}else if(node == this._lastFocusItem && evt.charOrCode === keys.TAB && !evt.shiftKey){
 					if(!singleFocusItem){
-						dijit.focus(this._firstFocusItem); // send focus to first item in dialog
+						focus.focus(this._firstFocusItem); // send focus to first item in dialog
 					}
-					dojo.stopEvent(evt);
+					event.stop(evt);
 				}else{
 					// see if the key is for the dialog
 					while(node){
-						if(node == this.domNode || dojo.hasClass(node, "dijitPopup")){
-							if(evt.charOrCode == dk.ESCAPE){
+						if(node == this.domNode || domClass.contains(node, "dijitPopup")){
+							if(evt.charOrCode == keys.ESCAPE){
 								this.onCancel();
 							}else{
 								return; // just let it go
@@ -284,10 +329,10 @@ dojo.declare(
 						node = node.parentNode;
 					}
 					// this key is for the disabled document window
-					if(evt.charOrCode !== dk.TAB){ // allow tabbing into the dialog for a11y
-						dojo.stopEvent(evt);
+					if(evt.charOrCode !== keys.TAB){ // allow tabbing into the dialog for a11y
+						event.stop(evt);
 					// opera won't tab to a div
-					}else if(!dojo.isOpera){
+					}else if(!has("opera")){
 						try{
 							this._firstFocusItem.focus();
 						}catch(e){ /*squelch*/ }
@@ -318,21 +363,21 @@ dojo.declare(
 				this._fadeOutDeferred.cancel();
 			}
 
-			this._modalconnects.push(dojo.connect(window, "onscroll", this, "layout"));
-			this._modalconnects.push(dojo.connect(window, "onresize", this, function(){
+			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 = dojo.window.getBox();
+				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(dojo.connect(this.domNode, "onkeypress", this, "_onKey"));
+			})));
+			this._modalconnects.push(on(this.domNode, connect._keypress, lang.hitch(this, "_onKey")));
 
-			dojo.style(this.domNode, {
+			domStyle.set(this.domNode, {
 				opacity:0,
 				display:""
 			});
@@ -346,29 +391,29 @@ dojo.declare(
 			// fade-in Animation object, setup below
 			var fadeIn;
 
-			this._fadeInDeferred = new dojo.Deferred(dojo.hitch(this, function(){
+			this._fadeInDeferred = new Deferred(lang.hitch(this, function(){
 				fadeIn.stop();
 				delete this._fadeInDeferred;
 			}));
 
-			fadeIn = dojo.fadeIn({
+			fadeIn = fx.fadeIn({
 				node: this.domNode,
 				duration: this.duration,
-				beforeBegin: dojo.hitch(this, function(){
-					dijit._DialogLevelManager.show(this, this.underlayAttrs);
+				beforeBegin: lang.hitch(this, function(){
+					DialogLevelManager.show(this, this.underlayAttrs);
 				}),
-				onEnd: dojo.hitch(this, function(){
-					if(this.autofocus && dijit._DialogLevelManager.isTop(this)){
+				onEnd: lang.hitch(this, function(){
+					if(this.autofocus && DialogLevelManager.isTop(this)){
 						// find focusable items each time dialog is shown since if dialog contains a widget the
 						// first focusable items can change
 						this._getFocusItems(this.domNode);
-						dijit.focus(this._firstFocusItem);
+						focus.focus(this._firstFocusItem);
 					}
 					this._fadeInDeferred.callback(true);
 					delete this._fadeInDeferred;
 				})
 			}).play();
-			
+
 			return this._fadeInDeferred;
 		},
 
@@ -389,18 +434,19 @@ dojo.declare(
 			// fade-in Animation object, setup below
 			var fadeOut;
 
-			this._fadeOutDeferred = new dojo.Deferred(dojo.hitch(this, function(){
+			this._fadeOutDeferred = new Deferred(lang.hitch(this, function(){
 				fadeOut.stop();
 				delete this._fadeOutDeferred;
 			}));
+			// fire onHide when the promise resolves.
+			this._fadeOutDeferred.then(lang.hitch(this, 'onHide'));
 
-			fadeOut = dojo.fadeOut({
+			fadeOut = fx.fadeOut({
 				node: this.domNode,
 				duration: this.duration,
-				onEnd: dojo.hitch(this, function(){
+				onEnd: lang.hitch(this, function(){
 					this.domNode.style.display = "none";
-					dijit._DialogLevelManager.hide(this);
-					this.onHide();
+					DialogLevelManager.hide(this);
 					this._fadeOutDeferred.callback(true);
 					delete this._fadeOutDeferred;
 				})
@@ -409,8 +455,10 @@ dojo.declare(
 			if(this._scrollConnected){
 				this._scrollConnected = false;
 			}
-			dojo.forEach(this._modalconnects, dojo.disconnect);
-			this._modalconnects = [];
+			var h;
+			while(h = this._modalconnects.pop()){
+				h.remove();
+			}
 
 			if(this._relativePosition){
 				delete this._relativePosition;
@@ -443,147 +491,146 @@ dojo.declare(
 			if(this._moveable){
 				this._moveable.destroy();
 			}
-			if(this._dndListener){
-				dojo.unsubscribe(this._dndListener);
+			var h;
+			while(h = this._modalconnects.pop()){
+				h.remove();
 			}
-			dojo.forEach(this._modalconnects, dojo.disconnect);
 
-			dijit._DialogLevelManager.hide(this);
+			DialogLevelManager.hide(this);
 
 			this.inherited(arguments);
 		}
-	}
-);
-
-dojo.declare(
-	"dijit.Dialog",
-	[dijit.layout.ContentPane, dijit._DialogBase],
-	{}
-);
+	});
 
-dijit._DialogLevelManager = {
-	// summary:
-	//		Controls the various active "levels" on the page, starting with the
-	//		stuff initially visible on the page (at z-index 0), and then having an entry for
-	//		each Dialog shown.
+	var Dialog = declare("dijit.Dialog", [ContentPane, _DialogBase], {});
+	Dialog._DialogBase = _DialogBase;	// for monkey patching
 
-	show: function(/*dijit._Widget*/ dialog, /*Object*/ underlayAttrs){
+	var DialogLevelManager = Dialog._DialogLevelManager = {
 		// summary:
-		//		Call right before fade-in animation for new dialog.
-		//		Saves current focus, displays/adjusts underlay for new dialog,
-		//		and sets the z-index of the dialog itself.
-		//
-		//		New dialog will be displayed on top of all currently displayed dialogs.
-		//
-		//		Caller is responsible for setting focus in new dialog after the fade-in
-		//		animation completes.
-
-		var ds = dijit._dialogStack;
-
-		// Save current focus
-		ds[ds.length-1].focus = dijit.getFocus(dialog);
+		//		Controls the various active "levels" on the page, starting with the
+		//		stuff initially visible on the page (at z-index 0), and then having an entry for
+		//		each Dialog shown.
 
-		// 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 dijit.DialogUnderlay(underlayAttrs);
-		}else{
-			underlay.set(dialog.underlayAttrs);
-		}
-
-		// Set z-index a bit above previous dialog
-		var zIndex = ds[ds.length-1].dialog ? ds[ds.length-1].zIndex + 2 : 950;
-		if(ds.length == 1){	// first dialog
-			underlay.show();
-		}
-		dojo.style(dijit._underlay.domNode, 'zIndex', zIndex - 1);
-
-		// Dialog
-		dojo.style(dialog.domNode, 'zIndex', zIndex);
+		_beginZIndex: 950,
 
-		ds.push({dialog: dialog, underlayAttrs: underlayAttrs, zIndex: zIndex});
-	},
+		show: function(/*dijit._Widget*/ dialog, /*Object*/ underlayAttrs){
+			// summary:
+			//		Call right before fade-in animation for new dialog.
+			//		Saves current focus, displays/adjusts underlay for new dialog,
+			//		and sets the z-index of the dialog itself.
+			//
+			//		New dialog will be displayed on top of all currently displayed dialogs.
+			//
+			//		Caller is responsible for setting focus in new dialog after the fade-in
+			//		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);
+			}
 
-	hide: function(/*dijit._Widget*/ 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.
+			// 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);
 
-		var ds = dijit._dialogStack;
+			// Dialog
+			domStyle.set(dialog.domNode, 'zIndex', zIndex);
 
-		if(ds[ds.length-1].dialog == dialog){
-			// Removing the top (or only) dialog in the stack, return focus
-			// to previous dialog
+			ds.push({dialog: dialog, underlayAttrs: underlayAttrs, zIndex: zIndex});
+		},
 
-			ds.pop();
+		hide: function(/*dijit._Widget*/ 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.
+
+			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)
+
+				// 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();
+					}
+				}else{
+					// Popping back to previous dialog, adjust underlay
+					domStyle.set(dijit._underlay.domNode, 'zIndex', pd.zIndex - 1);
+					dijit._underlay.set(pd.underlayAttrs);
+				}
 
-			var pd = ds[ds.length-1];	// the new active dialog (or the base page itself)
+				// Adjust focus
+				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.
+					// This situation could happen if two dialogs appeared at nearly the same time,
+					// since a dialog doesn't set it's focus until the fade-in is finished.
+					var focus = pd.focus;
+					if(pd.dialog && (!focus || !dom.isDescendant(focus, pd.dialog.domNode))){
+						pd.dialog._getFocusItems(pd.dialog.domNode);
+						focus = pd.dialog._firstFocusItem;
+					}
 
-			// 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();
+					if(focus){
+						focus.focus();
+					}
 				}
 			}else{
-				// Popping back to previous dialog, adjust underlay
-				dojo.style(dijit._underlay.domNode, 'zIndex', pd.zIndex - 1);
-				dijit._underlay.set(pd.underlayAttrs);
-			}
-
-			// Adjust focus
-			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.
-				// This situation could happen if two dialogs appeared at nearly the same time,
-				// since a dialog doesn't set it's focus until the fade-in is finished.
-				var focus = pd.focus;
-				if(!focus || (pd.dialog && !dojo.isDescendant(focus.node, pd.dialog.domNode))){
-					pd.dialog._getFocusItems(pd.dialog.domNode);
-					focus = pd.dialog._firstFocusItem;
-				}
-	
-				try{
-					dijit.focus(focus);
-				}catch(e){
-					/* focus() will fail if user opened the dialog by clicking a non-focusable element */
+				// 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);
+				if(idx != -1){
+					ds.splice(idx, 1);
 				}
 			}
-		}else{
-			// Removing a dialog out of order (#9944, #10705).
-			// Don't need to mess with underlay or z-index or anything.
-			var idx = dojo.indexOf(dojo.map(ds, function(elem){return elem.dialog}), dialog);
-			if(idx != -1){
-				ds.splice(idx, 1);
-			}
-		}
-	},
+		},
 
-	isTop: function(/*dijit._Widget*/ dialog){
-		// summary:
-		//		Returns true if specified Dialog is the top in the task
-		var ds = dijit._dialogStack;
-		return ds[ds.length-1].dialog == dialog;
+		isTop: function(/*dijit._Widget*/ dialog){
+			// summary:
+			//		Returns true if specified Dialog is the top in the task
+			return ds[ds.length-1].dialog == dialog;
+		}
+	};
+
+	// Stack representing the various active "levels" on the page, starting with the
+	// stuff initially visible on the page (at z-index 0), and then having an entry for
+	// each Dialog shown.
+	// Each element in stack has form {
+	//		dialog: dialogWidget,
+	//		focus: returnFromGetFocus(),
+	//		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
+	];
+
+	// Back compat w/1.6, remove for 2.0
+	if(!kernel.isAsync){
+		ready(0, function(){
+			var requires = ["dijit/TooltipDialog"];
+			require(requires);	// use indirection so modules not rolled into a build
+		});
 	}
-};
-
-// Stack representing the various active "levels" on the page, starting with the
-// stuff initially visible on the page (at z-index 0), and then having an entry for
-// each Dialog shown.
-// Each element in stack has form {
-//		dialog: dialogWidget,
-//		focus: returnFromGetFocus(),
-//		underlayAttrs: attributes to set on underlay (when this widget is active)
-// }
-dijit._dialogStack = [
-	{dialog: null, focus: null, underlayAttrs: null}	// entry for stuff at z-index: 0
-];
-
-return dijit.Dialog;
+
+	return Dialog;
 });
diff --git a/dijit/DialogUnderlay.js b/dijit/DialogUnderlay.js
index 569fad0..0dcb216 100644
--- a/dijit/DialogUnderlay.js
+++ b/dijit/DialogUnderlay.js
@@ -1,9 +1,24 @@
-define("dijit/DialogUnderlay", ["dojo", "dijit", "dojo/window", "dijit/_Widget", "dijit/_Templated"], function(dojo, dijit) {
-
-dojo.declare(
-	"dijit.DialogUnderlay",
-	[dijit._Widget, dijit._Templated],
-	{
+define([
+	"dojo/_base/declare", // declare
+	"dojo/dom-attr", // domAttr.set
+	"dojo/_base/window", // win.body
+	"dojo/window", // winUtils.getBox
+	"./_Widget",
+	"./_TemplatedMixin",
+	"./BackgroundIframe"
+], function(declare, domAttr, win, winUtils, _Widget, _TemplatedMixin, BackgroundIframe){
+
+/*=====
+	var _Widget = dijit._Widget;
+	var _TemplatedMixin = dijit._TemplatedMixin;
+=====*/
+
+	// module:
+	//		dijit/DialogUnderlay
+	// summary:
+	//		The component that blocks the screen behind a `dijit.Dialog`
+
+	return declare("dijit.DialogUnderlay", [_Widget, _TemplatedMixin], {
 		// summary:
 		//		The component that blocks the screen behind a `dijit.Dialog`
 		//
@@ -20,7 +35,7 @@ dojo.declare(
 
 		// 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' dojoAttachPoint='node'></div></div>",
+		templateString: "<div class='dijitDialogUnderlayWrapper'><div class='dijitDialogUnderlay' data-dojo-attach-point='node'></div></div>",
 
 		// Parameters on creation or updatable later
 
@@ -32,10 +47,8 @@ dojo.declare(
 		//		This class name is used on the DialogUnderlay node, in addition to dijitDialogUnderlay
 		"class": "",
 
-		attributeMap: { id: "domNode" },
-
 		_setDialogIdAttr: function(id){
-			dojo.attr(this.node, "id", id + "_underlay");
+			domAttr.set(this.node, "id", id + "_underlay");
 			this._set("dialogId", id);
 		},
 
@@ -47,7 +60,7 @@ dojo.declare(
 		postCreate: function(){
 			// summary:
 			//		Append the underlay to the body
-			dojo.body().appendChild(this.domNode);
+			win.body().appendChild(this.domNode);
 		},
 
 		layout: function(){
@@ -70,7 +83,7 @@ dojo.declare(
 			os.display = "none";
 
 			// then resize and show
-			var viewport = dojo.window.getBox();
+			var viewport = winUtils.getBox();
 			os.top = viewport.t + "px";
 			os.left = viewport.l + "px";
 			is.width = viewport.w + "px";
@@ -83,7 +96,7 @@ dojo.declare(
 			//		Show the dialog underlay
 			this.domNode.style.display = "block";
 			this.layout();
-			this.bgIframe = new dijit.BackgroundIframe(this.domNode);
+			this.bgIframe = new BackgroundIframe(this.domNode);
 		},
 
 		hide: function(){
@@ -93,9 +106,5 @@ dojo.declare(
 			delete this.bgIframe;
 			this.domNode.style.display = "none";
 		}
-	}
-);
-
-
-return dijit.DialogUnderlay;
+	});
 });
diff --git a/dijit/DropDownMenu.js b/dijit/DropDownMenu.js
new file mode 100644
index 0000000..a5314a3
--- /dev/null
+++ b/dijit/DropDownMenu.js
@@ -0,0 +1,62 @@
+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;
+=====*/
+
+	// module:
+	//		dijit/DropDownMenu
+	// summary:
+	//		dijit.DropDownMenu widget
+
+	return declare("dijit.DropDownMenu", [_MenuBase, _OnDijitClickMixin], {
+		// summary:
+		//		A menu, without features for context menu (Meaning, drop down menu)
+
+		templateString: template,
+
+		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]);
+		},
+
+		_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;
+			}
+		}
+	});
+});
diff --git a/dijit/Editor.js b/dijit/Editor.js
index c58e538..3ba1f7a 100644
--- a/dijit/Editor.js
+++ b/dijit/Editor.js
@@ -1,9 +1,43 @@
-define("dijit/Editor", ["dojo", "dijit", "dijit/_editor/RichText", "dijit/Toolbar", "dijit/ToolbarSeparator", "dijit/_editor/_Plugin", "dijit/_editor/plugins/EnterKeyHandling", "dijit/_editor/range", "dijit/_Container", "dojo/i18n", "dijit/layout/_LayoutWidget", "i18n!dijit/_editor/nls/commands"], function(dojo, dijit) {
-
-dojo.declare(
-	"dijit.Editor",
-	dijit._editor.RichText,
-	{
+define([
+	"dojo/_base/array", // array.forEach
+	"dojo/_base/declare", // declare
+	"dojo/_base/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/string", // string.substitute
+	"dojo/topic", // topic.publish()
+	"dojo/_base/window", // win.withGlobal
+	"./_base/focus",	// dijit.getBookmark()
+	"./_Container",
+	"./Toolbar",
+	"./ToolbarSeparator",
+	"./layout/_LayoutWidget",
+	"./form/ToggleButton",
+	"./_editor/_Plugin",
+	"./_editor/plugins/EnterKeyHandling",
+	"./_editor/html",
+	"./_editor/range",
+	"./_editor/RichText",
+	".",	// 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,
+			_Plugin, EnterKeyHandling, html, rangeapi, RichText, dijit){
+
+	// module:
+	//		dijit/Editor
+	// summary:
+	//		A rich text Editing widget
+
+	var Editor = declare("dijit.Editor", RichText, {
 		// summary:
 		//		A rich text Editing widget
 		//
@@ -34,10 +68,10 @@ dojo.declare(
 			// tags:
 			//		private
 
-			if(!dojo.isArray(this.plugins)){
+			if(!lang.isArray(this.plugins)){
 				this.plugins=["undo","redo","|","cut","copy","paste","|","bold","italic","underline","strikethrough","|",
 				"insertOrderedList","insertUnorderedList","indent","outdent","|","justifyLeft","justifyRight","justifyCenter","justifyFull",
-				"dijit._editor.plugins.EnterKeyHandling" /*, "createLink"*/];
+				EnterKeyHandling /*, "createLink"*/];
 			}
 
 			this._plugins=[];
@@ -47,19 +81,19 @@ dojo.declare(
 			//when no iframe is used, focus will be lost whenever another element gets focus.
 			//For IE, we can connect to onBeforeDeactivate, which will be called right before
 			//the focus is lost, so we can obtain the selected range. For other browsers,
-			//no equivelent of onBeforeDeactivate, so we need to do two things to make sure
+			//no equivalent of onBeforeDeactivate, so we need to do two things to make sure
 			//selection is properly saved before focus is lost: 1) when user clicks another
 			//element in the page, in which case we listen to mousedown on the entire page and
 			//see whether user clicks out of a focus editor, if so, save selection (focus will
 			//only lost after onmousedown event is fired, so we can obtain correct caret pos.)
 			//2) when user tabs away from the editor, which is handled in onKeyDown below.
-			if(dojo.isIE){
+			if(has("ie")){
 				this.events.push("onBeforeDeactivate");
 				this.events.push("onBeforeActivate");
 			}
 		},
 
-		postMixInProperties: function() {
+		postMixInProperties: function(){
 			// summary:
 			//	Extension to make sure a deferred is in place before certain functions
 			//	execute, like making sure all the plugins are properly inserted.
@@ -67,52 +101,52 @@ dojo.declare(
 			// Set up a deferred so that the value isn't applied to the editor
 			// until all the plugins load, needed to avoid timing condition
 			// reported in #10537.
-			this.setValueDeferred = new dojo.Deferred();
+			this.setValueDeferred = new Deferred();
 			this.inherited(arguments);
 		},
-	
+
 		postCreate: function(){
 			//for custom undo/redo, if enabled.
 			this._steps=this._steps.slice(0);
 			this._undoedSteps=this._undoedSteps.slice(0);
 
-			if(dojo.isArray(this.extraPlugins)){
+			if(lang.isArray(this.extraPlugins)){
 				this.plugins=this.plugins.concat(this.extraPlugins);
 			}
 
 			this.inherited(arguments);
 
-			this.commands = dojo.i18n.getLocalization("dijit._editor", "commands", this.lang);
+			this.commands = i18n.getLocalization("dijit._editor", "commands", this.lang);
 
 			if(!this.toolbar){
 				// if we haven't been assigned a toolbar, create one
-				this.toolbar = new dijit.Toolbar({
+				this.toolbar = new Toolbar({
 					dir: this.dir,
 					lang: this.lang
 				});
 				this.header.appendChild(this.toolbar.domNode);
 			}
 
-			dojo.forEach(this.plugins, this.addPlugin, this);
+			array.forEach(this.plugins, this.addPlugin, this);
 
 			// Okay, denote the value can now be set.
 			this.setValueDeferred.callback(true);
 
-			dojo.addClass(this.iframe.parentNode, "dijitEditorIFrameContainer");
-			dojo.addClass(this.iframe, "dijitEditorIFrame");
-			dojo.attr(this.iframe, "allowTransparency", true);
+			domClass.add(this.iframe.parentNode, "dijitEditorIFrameContainer");
+			domClass.add(this.iframe, "dijitEditorIFrame");
+			domAttr.set(this.iframe, "allowTransparency", true);
 
-			if(dojo.isWebKit){
-				// Disable selecting the entire editor by inadvertant double-clicks.
+			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.
-				dojo.style(this.domNode, "KhtmlUserSelect", "none");
+				domStyle.set(this.domNode, "KhtmlUserSelect", "none");
 			}
 			this.toolbar.startup();
 			this.onNormalizedDisplayChanged(); //update toolbar button status
 		},
 		destroy: function(){
-			dojo.forEach(this._plugins, function(p){
+			array.forEach(this._plugins, function(p){
 				if(p && p.destroy){
 					p.destroy();
 				}
@@ -122,7 +156,7 @@ dojo.declare(
 			delete this.toolbar;
 			this.inherited(arguments);
 		},
-		addPlugin: function(/*String||Object*/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
@@ -131,7 +165,7 @@ dojo.declare(
 			//		array at that index. No big magic, but a nice helper for
 			//		passing in plugin names via markup.
 			//
-			// plugin: String, args object or plugin instance
+			// plugin: String, args object, plugin instance, or plugin constructor
 			//
 			// args:
 			//		This object will be passed to the plugin constructor
@@ -140,12 +174,22 @@ dojo.declare(
 			//		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=dojo.isString(plugin)?{name: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};
-				dojo.publish(dijit._scopeName + ".Editor.getPlugin",[o]);
+				if(args.name){
+					// search registry for a plugin factory matching args.name, if it's not there then
+					// fallback to 1.0 API:
+					// ask all loaded plugin modules to fill in o.plugin if they can (ie, if they implement args.name)
+					// remove fallback for 2.0.
+					if(_Plugin.registry[args.name]){
+						o.plugin = _Plugin.registry[args.name](args);
+					}else{
+						topic.publish(dijit._scopeName + ".Editor.getPlugin", o);	// publish
+					}
+				}
 				if(!o.plugin){
-					var pc = dojo.getObject(args.name);
+					var pc = args.ctor || lang.getObject(args.name);
 					if(pc){
 						o.plugin=new pc(args);
 					}
@@ -162,26 +206,20 @@ dojo.declare(
 				this._plugins.push(plugin);
 			}
 			plugin.setEditor(this);
-			if(dojo.isFunction(plugin.setToolbar)){
+			if(lang.isFunction(plugin.setToolbar)){
 				plugin.setToolbar(this.toolbar);
 			}
 		},
-		//the following 3 functions are required to make the editor play nice under a layout widget, see #4070
-		startup: function(){
-			// summary:
-			//		Exists to make Editor work as a child of a layout widget.
-			//		Developers don't need to call this method.
-			// tags:
-			//		protected
-			//console.log('startup',arguments);
-		},
+
+		//the following 2 functions are required to make the editor play nice under a layout widget, see #4070
+
 		resize: function(size){
 			// summary:
 			//		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
-				dijit.layout._LayoutWidget.prototype.resize.apply(this, arguments);
+				_LayoutWidget.prototype.resize.apply(this, arguments);
 			}
 			/*
 			else{
@@ -202,14 +240,15 @@ dojo.declare(
 			// calc off the added margins and padding too. See tracker: #10662
 			var areaHeight = (this._contentBox.h -
 				(this.getHeaderHeight() + this.getFooterHeight() +
-				 dojo._getPadBorderExtents(this.iframe.parentNode).h +
-				 dojo._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._layoutMode = true;
 		},
+
 		_onIEMouseDown: function(/*Event*/ e){
 			// summary:
 			//		IE only to prevent 2 clicks to focus
@@ -228,8 +267,7 @@ dojo.declare(
 			var offsetLeft = b.offsetLeft;
 
 			//Check for vertical scroller click.
-			bodyDir = b.dir ? b.dir.toLowerCase() : "";
-			if(bodyDir != "rtl"){
+			if(/^rtl$/i.test(b.dir || "")){
 				if(clientWidth < offsetWidth && e.x > clientWidth && e.x < offsetWidth){
 					// Check the click was between width and offset width, if so, scroller
 					outsideClientArea = true;
@@ -252,12 +290,12 @@ dojo.declare(
 				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(dojo.hitch(this, "placeCursorAtEnd"), 0);
+					setTimeout(lang.hitch(this, "placeCursorAtEnd"), 0);
 				}
 				this.inherited(arguments);
 			}
 		},
-		onBeforeActivate: function(e){
+		onBeforeActivate: function(){
 			this._restoreSelection();
 		},
 		onBeforeDeactivate: function(e){
@@ -309,7 +347,7 @@ dojo.declare(
 				if(this._editTimer){
 					clearTimeout(this._editTimer);
 				}
-				this._editTimer = setTimeout(dojo.hitch(this, this.endEditing), this._editInterval);
+				this._editTimer = setTimeout(lang.hitch(this, this.endEditing), this._editInterval);
 			}
 		},
 
@@ -330,30 +368,64 @@ dojo.declare(
 					this.endEditing();
 					this._beginEditing();
 				}
-				var r;
-				var isClipboard = /copy|cut|paste/.test(cmd);
-				try{
-					r = this.inherited(arguments);
-					if(dojo.isWebKit && isClipboard && !r){ //see #4598: webkit does not guarantee clipboard support from js
-						throw { code: 1011 }; // throw an object like Mozilla's error
-					}
-				}catch(e){
-					//TODO: when else might we get an exception?  Do we need the Mozilla test below?
-					if(e.code == 1011 /* Mozilla: service denied */ && isClipboard){
-						// Warn user of platform limitation.  Cannot programmatically access clipboard. See ticket #4136
-						var sub = dojo.string.substitute,
-							accel = {cut:'X', copy:'C', paste:'V'};
-						alert(sub(this.commands.systemShortcut,
-							[this.commands[cmd], sub(this.commands[dojo.isMac ? 'appleKey' : 'ctrlKey'], [accel[cmd]])]));
-					}
-					r = false;
-				}
+				var r = this.inherited(arguments);
 				if(this.customUndo){
 					this._endEditing();
 				}
 				return r;
 			}
 		},
+
+		_pasteImpl: function(){
+			// summary:
+			//		Over-ride of paste command control to make execCommand cleaner
+			// tags:
+			//		Protected
+			return this._clipboardCommand("paste");
+		},
+
+		_cutImpl: function(){
+			// summary:
+			//		Over-ride of cut command control to make execCommand cleaner
+			// tags:
+			//		Protected
+			return this._clipboardCommand("cut");
+		},
+
+		_copyImpl: function(){
+			// summary:
+			//		Over-ride of copy command control to make execCommand cleaner
+			// tags:
+			//		Protected
+			return this._clipboardCommand("copy");
+		},
+
+		_clipboardCommand: function(cmd){
+			// summary:
+			//		Function to handle processing clipboard commands (or at least try to).
+			// tags:
+			//		Private
+			var r;
+			try{
+				// Try to exec the superclass exec-command and see if it works.
+				r = this.document.execCommand(cmd, false, null);
+				if(has("webkit") && !r){ //see #4598: webkit does not guarantee clipboard support from js
+					throw { code: 1011 }; // throw an object like Mozilla's error
+				}
+			}catch(e){
+				//TODO: when else might we get an exception?  Do we need the Mozilla test below?
+				if(e.code == 1011 /* Mozilla: service denied */){
+					// Warn user of platform limitation.  Cannot programmatically access clipboard. See ticket #4136
+					var sub = string.substitute,
+						accel = {cut:'X', copy:'C', paste:'V'};
+					alert(sub(this.commands.systemShortcut,
+						[this.commands[cmd], sub(this.commands[has("mac") ? 'appleKey' : 'ctrlKey'], [accel[cmd]])]));
+				}
+				r = false;
+			}
+			return r;
+		},
+
 		queryCommandEnabled: function(cmd){
 			// summary:
 			//		Returns true if specified editor command is enabled.
@@ -376,24 +448,24 @@ dojo.declare(
 			var col = b.isCollapsed;
 			var r, sNode, eNode, sel;
 			if(mark){
-				if(dojo.isIE < 9){
-					if(dojo.isArray(mark)){
+				if(has("ie") < 9){
+					if(lang.isArray(mark)){
 						//IE CONTROL, have to use the native bookmark.
 						bookmark = [];
-						dojo.forEach(mark,function(n){
-							bookmark.push(dijit.range.getNode(n,this.editNode));
+						array.forEach(mark,function(n){
+							bookmark.push(rangeapi.getNode(n,this.editNode));
 						},this);
-						dojo.withGlobal(this.window,'moveToBookmark',dijit,[{mark: bookmark, isCollapsed: col}]);
+						win.withGlobal(this.window,'moveToBookmark',dijit,[{mark: bookmark, isCollapsed: col}]);
 					}else{
 						if(mark.startContainer && mark.endContainer){
 							// Use the pseudo WC3 range API.  This works better for positions
 							// than the IE native bookmark code.
-							sel = dijit.range.getSelection(this.window);
+							sel = rangeapi.getSelection(this.window);
 							if(sel && sel.removeAllRanges){
 								sel.removeAllRanges();
-								r = dijit.range.create(this.window);
-								sNode = dijit.range.getNode(mark.startContainer,this.editNode);
-								eNode = dijit.range.getNode(mark.endContainer,this.editNode);
+								r = rangeapi.create(this.window);
+								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
@@ -407,12 +479,12 @@ dojo.declare(
 						}
 					}
 				}else{//w3c range
-					sel = dijit.range.getSelection(this.window);
+					sel = rangeapi.getSelection(this.window);
 					if(sel && sel.removeAllRanges){
 						sel.removeAllRanges();
-						r = dijit.range.create(this.window);
-						sNode = dijit.range.getNode(mark.startContainer,this.editNode);
-						eNode = dijit.range.getNode(mark.endContainer,this.editNode);
+						r = rangeapi.create(this.window);
+						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
@@ -500,14 +572,14 @@ dojo.declare(
 			//		Get the currently selected text
 			// tags:
 			//		protected
-			var b=dojo.withGlobal(this.window,dijit.getBookmark);
+			var b=win.withGlobal(this.window,focusBase.getBookmark);
 			var tmp=[];
 			if(b && b.mark){
 				var mark = b.mark;
-				if(dojo.isIE < 9){
+				if(has("ie") < 9){
 					// Try to use the pseudo range API on IE for better accuracy.
-					var sel = dijit.range.getSelection(this.window);
-					if(!dojo.isArray(mark)){
+					var sel = rangeapi.getSelection(this.window);
+					if(!lang.isArray(mark)){
 						if(sel){
 							var range;
 							if(sel.rangeCount){
@@ -516,23 +588,23 @@ dojo.declare(
 							if(range){
 								b.mark = range.cloneRange();
 							}else{
-								b.mark = dojo.withGlobal(this.window,dijit.getBookmark);
+								b.mark = win.withGlobal(this.window,focusBase.getBookmark);
 							}
 						}
 					}else{
 						// Control ranges (img, table, etc), handle differently.
-						dojo.forEach(b.mark,function(n){
-							tmp.push(dijit.range.getIndex(n,this.editNode).o);
+						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=dijit.range.getIndex(b.mark.startContainer,this.editNode).o;
+						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:dijit.range.getIndex(b.mark.endContainer,this.editNode).o,
+							endContainer:b.mark.endContainer===b.mark.startContainer?tmp:rangeapi.getIndex(b.mark.endContainer,this.editNode).o,
 							endOffset:b.mark.endOffset};
 					}
 				}catch(e){
@@ -541,7 +613,7 @@ dojo.declare(
 			}
 			return b;
 		},
-		_beginEditing: function(cmd){
+		_beginEditing: function(){
 			// summary:
 			//		Called when the user starts typing alphanumeric characters.
 			//		Deals with saving undo; see editActionInterval parameter.
@@ -552,17 +624,17 @@ dojo.declare(
 				// 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':dijit._editor.getChildrenHtml(this.editNode),'bookmark':this._getBookmark()});
+				this._steps.push({'text':html.getChildrenHtml(this.editNode),'bookmark':this._getBookmark()});
 			}
 		},
-		_endEditing: function(ignore_caret){
+		_endEditing: function(){
 			// summary:
 			//		Called when the user stops typing alphanumeric characters.
 			//		Deals with saving undo; see editActionInterval parameter.
 			// tags:
 			//		private
 			// Avoid filtering to make sure selections restore.
-			var v = dijit._editor.getChildrenHtml(this.editNode);
+			var v = html.getChildrenHtml(this.editNode);
 
 			this._undoedSteps=[];//clear undoed steps
 			this._steps.push({text: v, bookmark: this._getBookmark()});
@@ -575,21 +647,21 @@ dojo.declare(
 
 			//We need to save selection if the user TAB away from this editor
 			//no need to call _saveSelection for IE, as that will be taken care of in onBeforeDeactivate
-			if(!dojo.isIE && !this.iframe && e.keyCode == dojo.keys.TAB && !this.tabIndent){
+			if(!has("ie") && !this.iframe && e.keyCode == keys.TAB && !this.tabIndent){
 				this._saveSelection();
 			}
 			if(!this.customUndo){
 				this.inherited(arguments);
 				return;
 			}
-			var k = e.keyCode, ks = dojo.keys;
+			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
-					dojo.stopEvent(e);
+					event.stop(e);
 					this.undo();
 					return;
 				}else if(k == 89 || k == 121){ //y
-					dojo.stopEvent(e);
+					event.stop(e);
 					this.redo();
 					return;
 				}
@@ -597,9 +669,9 @@ dojo.declare(
 			this.inherited(arguments);
 
 			switch(k){
-					case ks.ENTER:
-					case ks.BACKSPACE:
-					case ks.DELETE:
+					case keys.ENTER:
+					case keys.BACKSPACE:
+					case keys.DELETE:
 						this.beginEditing();
 						break;
 					case 88: //x
@@ -609,38 +681,38 @@ dojo.declare(
 							if(e.keyCode == 88){
 								this.beginEditing('cut');
 								//use timeout to trigger after the cut is complete
-								setTimeout(dojo.hitch(this, this.endEditing), 1);
+								setTimeout(lang.hitch(this, this.endEditing), 1);
 							}else{
 								this.beginEditing('paste');
 								//use timeout to trigger after the paste is complete
-								setTimeout(dojo.hitch(this, this.endEditing), 1);
+								setTimeout(lang.hitch(this, this.endEditing), 1);
 							}
 							break;
 						}
 						//pass through
 					default:
-						if(!e.ctrlKey && !e.altKey && !e.metaKey && (e.keyCode<dojo.keys.F1 || e.keyCode>dojo.keys.F15)){
+						if(!e.ctrlKey && !e.altKey && !e.metaKey && (e.keyCode<keys.F1 || e.keyCode>keys.F15)){
 							this.beginEditing();
 							break;
 						}
 						//pass through
-					case ks.ALT:
+					case keys.ALT:
 						this.endEditing();
 						break;
-					case ks.UP_ARROW:
-					case ks.DOWN_ARROW:
-					case ks.LEFT_ARROW:
-					case ks.RIGHT_ARROW:
-					case ks.HOME:
-					case ks.END:
-					case ks.PAGE_UP:
-					case ks.PAGE_DOWN:
+					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 ks.CTRL:
-					case ks.SHIFT:
-					case ks.TAB:
+					case keys.CTRL:
+					case keys.SHIFT:
+					case keys.TAB:
 						break;
 				}
 		},
@@ -661,7 +733,7 @@ dojo.declare(
 			//		private
 			try{
 				this._savedSelection=this._getBookmark();
-			}catch(e){ /* Squelch any errors that occur if selection save occurs due to being hidden simultaniously. */}
+			}catch(e){ /* Squelch any errors that occur if selection save occurs due to being hidden simultaneously. */}
 		},
 		_restoreSelection: function(){
 			// summary:
@@ -675,7 +747,7 @@ dojo.declare(
 				// 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(dojo.withGlobal(this.window,'isCollapsed',dijit)){
+				if(win.withGlobal(this.window,'isCollapsed',dijit)){
 					this._moveToBookmark(this._savedSelection);
 				}
 				delete this._savedSelection;
@@ -693,7 +765,7 @@ dojo.declare(
 
 		replaceValue: function(/*String*/ html){
 			// summary:
-			//		over-ride of replaceValue to support custom undo and stack maintainence.
+			//		over-ride of replaceValue to support custom undo and stack maintenance.
 			// tags:
 			//		protected
 			if(!this.customUndo){
@@ -704,24 +776,24 @@ dojo.declare(
 				}else{
 					this.beginEditing();
 					if(!html){
-						html = " "
+						html = " ";	//  
 					}
 					this.setValue(html);
 					this.endEditing();
 				}
 			}
 		},
-		
+
 		_setDisabledAttr: function(/*Boolean*/ value){
-			var disableFunc = dojo.hitch(this, function(){
+			var disableFunc = lang.hitch(this, function(){
 				if((!this.disabled && value) || (!this._buttonEnabledPlugins && value)){
 				// Disable editor: disable all enabled buttons and remember that list
-					dojo.forEach(this._plugins, function(p){
+					array.forEach(this._plugins, function(p){
 						p.set("disabled", true);
 				});
 			}else if(this.disabled && !value){
 					// Restore plugins to being active.
-					dojo.forEach(this._plugins, function(p){
+					array.forEach(this._plugins, function(p){
 						p.set("disabled", false);
 				});
 			}
@@ -729,48 +801,59 @@ dojo.declare(
 			this.setValueDeferred.addCallback(disableFunc);
 			this.inherited(arguments);
 		},
-		
+
 		_setStateClass: function(){
 			try{
 				this.inherited(arguments);
-			
+
 				// Let theme set the editor's text color based on editor enabled/disabled state.
 				// We need to jump through hoops because the main document (where the theme CSS is)
 				// is separate from the iframe's document.
 				if(this.document && this.document.body){
-					dojo.style(this.document.body, "color", dojo.style(this.iframe, "color"));
+					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 */}
 		}
+	});
+
+	// Register the "default plugins", ie, the built-in editor commands
+	function simplePluginFactory(args){
+		return new _Plugin({ command: args.name });
 	}
-);
-
-// Register the "default plugins", ie, the built-in editor commands
-dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
-	if(o.plugin){ return; }
-	var args = o.args, p;
-	var _p = dijit._editor._Plugin;
-	var name = args.name;
-	switch(name){
-		case "undo": case "redo": case "cut": case "copy": case "paste": case "insertOrderedList":
-		case "insertUnorderedList": case "indent": case "outdent": case "justifyCenter":
-		case "justifyFull": case "justifyLeft": case "justifyRight": case "delete":
-		case "selectAll": case "removeFormat": case "unlink":
-		case "insertHorizontalRule":
-			p = new _p({ command: name });
-			break;
-
-		case "bold": case "italic": case "underline": case "strikethrough":
-		case "subscript": case "superscript":
-			p = new _p({ buttonClass: dijit.form.ToggleButton, command: name });
-			break;
-		case "|":
-			p = new _p({ button: new dijit.ToolbarSeparator(), setEditor: function(editor) {this.editor = editor;} });
+	function togglePluginFactory(args){
+		return new _Plugin({ buttonClass: ToggleButton, command: args.name });
 	}
-//	console.log('name',name,p);
-	o.plugin=p;
-});
-
+	lang.mixin(_Plugin.registry, {
+		"undo": simplePluginFactory,
+		"redo": simplePluginFactory,
+		"cut": simplePluginFactory,
+		"copy": simplePluginFactory,
+		"paste": simplePluginFactory,
+		"insertOrderedList": simplePluginFactory,
+		"insertUnorderedList": simplePluginFactory,
+		"indent": simplePluginFactory,
+		"outdent": simplePluginFactory,
+		"justifyCenter": simplePluginFactory,
+		"justifyFull": simplePluginFactory,
+		"justifyLeft": simplePluginFactory,
+		"justifyRight": simplePluginFactory,
+		"delete": simplePluginFactory,
+		"selectAll": simplePluginFactory,
+		"removeFormat": simplePluginFactory,
+		"unlink": simplePluginFactory,
+		"insertHorizontalRule": simplePluginFactory,
+
+		"bold": togglePluginFactory,
+		"italic": togglePluginFactory,
+		"underline": togglePluginFactory,
+		"strikethrough": togglePluginFactory,
+		"subscript": togglePluginFactory,
+		"superscript": togglePluginFactory,
+
+		"|": function(){
+			return new _Plugin({ button: new ToolbarSeparator(), setEditor: function(editor){this.editor = editor;}});
+		}
+	});
 
-return dijit.Editor;
+	return Editor;
 });
diff --git a/dijit/InlineEditBox.js b/dijit/InlineEditBox.js
index 38a8e7b..36ad710 100644
--- a/dijit/InlineEditBox.js
+++ b/dijit/InlineEditBox.js
@@ -1,10 +1,254 @@
-define("dijit/InlineEditBox", ["dojo", "dijit", "text!dijit/templates/InlineEditBox.html", "dojo/i18n", "dijit/_Widget", "dijit/_Container", "dijit/form/Button", "dijit/form/TextBox", "i18n!dijit/nls/common"], function(dojo, dijit) {
+define([
+	"dojo/_base/array", // array.forEach
+	"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")
+	"./focus",
+	"./_Widget",
+	"./_TemplatedMixin",
+	"./_WidgetsInTemplateMixin",
+	"./_Container",
+	"./form/Button",
+	"./form/_TextBoxMixin",
+	"./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);
+
+		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);
+			}
+		}
+	},
+
+	_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 ? "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
+			}
+
+			// _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();
+		setTimeout(lang.hitch(this, function(){
+			if(this.editWidget.focusNode && this.editWidget.focusNode.tagName == "INPUT"){
+				_TextBoxMixin.selectInputText(this.editWidget.focusNode);
+			}
+		}), 0);
+	}
+});
 
-dojo.declare("dijit.InlineEditBox",
-	dijit._Widget,
-	{
+
+var InlineEditBox = declare("dijit.InlineEditBox", _Widget, {
 	// summary:
-	//		An element with in-line edit capabilites
+	//		An element with in-line edit capabilities
 	//
 	// description:
 	//		Behavior for an existing node (`<p>`, `<div>`, `<span>`, etc.) so that
@@ -45,12 +289,12 @@ dojo.declare("dijit.InlineEditBox",
 
 	// editor: String|Function
 	//		Class name (or reference to the Class) for Editor widget
-	editor: "dijit.form.TextBox",
+	editor: TextBox,
 
 	// editorWrapper: String|Function
 	//		Class name (or reference to the Class) for widget that wraps the editor widget, displaying save/cancel
 	//		buttons.
-	editorWrapper: "dijit._InlineEditor",
+	editorWrapper: InlineEditor,
 
 	// editorParams: Object
 	//		Set of parameters for editor, like {required: true}
@@ -60,7 +304,7 @@ dojo.declare("dijit.InlineEditBox",
 	//		If true, clicking the InlineEditBox to edit it will have no effect.
 	disabled: false,
 
-	onChange: function(value){
+	onChange: function(/*===== value =====*/){
 		// summary:
 		//		Set this handler to be notified of changes to value.
 		// tags:
@@ -84,9 +328,9 @@ dojo.declare("dijit.InlineEditBox",
 
 	// 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: dojo.isIE <= 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>",
+	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:
@@ -113,20 +357,20 @@ dojo.declare("dijit.InlineEditBox",
 		for(var name in events){
 			this.connect(this.displayNode, name, events[name]);
 		}
-		dijit.setWaiRole(this.displayNode, "button");
+		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 = dojo.trim(this.renderAsHtml ? this.displayNode.innerHTML :
-		      (this.displayNode.innerText||this.displayNode.textContent||""));
+			this.value = lang.trim(this.renderAsHtml ? this.displayNode.innerHTML :
+				(this.displayNode.innerText||this.displayNode.textContent||""));
 		}
 		if(!this.value){
-		    this.displayNode.innerHTML = this.noValueIndicator;
+			this.displayNode.innerHTML = this.noValueIndicator;
 		}
 
-		dojo.addClass(this.displayNode, 'dijitInlineEditBoxDisplayMode');
+		domClass.add(this.displayNode, 'dijitInlineEditBoxDisplayMode');
 	},
 
 	setDisabled: function(/*Boolean*/ disabled){
@@ -134,7 +378,7 @@ dojo.declare("dijit.InlineEditBox",
 		//		Deprecated.   Use set('disabled', ...) instead.
 		// tags:
 		//		deprecated
-		dojo.deprecated("dijit.InlineEditBox.setDisabled() is deprecated.  Use set('disabled', bool) instead.", "", "2.0");
+		kernel.deprecated("dijit.InlineEditBox.setDisabled() is deprecated.  Use set('disabled', bool) instead.", "", "2.0");
 		this.set('disabled', disabled);
 	},
 
@@ -142,13 +386,13 @@ dojo.declare("dijit.InlineEditBox",
 		// summary:
 		//		Hook to make set("disabled", ...) work.
 		//		Set disabled state of widget.
-		dijit.setWaiState(this.domNode, "disabled", disabled);
+		this.domNode.setAttribute("aria-disabled", disabled);
 		if(disabled){
 			this.displayNode.removeAttribute("tabIndex");
 		}else{
 			this.displayNode.setAttribute("tabIndex", 0);
 		}
-		dojo.toggleClass(this.displayNode, "dijitInlineEditBoxDisplayModeDisabled", disabled);
+		domClass.toggle(this.displayNode, "dijitInlineEditBoxDisplayModeDisabled", disabled);
 		this._set("disabled", disabled);
 	},
 
@@ -158,7 +402,7 @@ dojo.declare("dijit.InlineEditBox",
 		// tags:
 		//		private
 		if(!this.disabled){
-			dojo.addClass(this.displayNode, "dijitInlineEditBoxDisplayModeHover");
+			domClass.add(this.displayNode, "dijitInlineEditBoxDisplayModeHover");
 		}
 	},
 
@@ -167,7 +411,7 @@ dojo.declare("dijit.InlineEditBox",
 		//		Handler for onmouseout and onblur event.
 		// tags:
 		//		private
-		dojo.removeClass(this.displayNode, "dijitInlineEditBoxDisplayModeHover");
+		domClass.remove(this.displayNode, "dijitInlineEditBoxDisplayModeHover");
 	},
 
 	_onClick: function(/*Event*/ e){
@@ -176,11 +420,11 @@ dojo.declare("dijit.InlineEditBox",
 		// tags:
 		//		private
 		if(this.disabled){ return; }
-		if(e){ dojo.stopEvent(e); }
+		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(dojo.hitch(this, "edit"), 0);
+		setTimeout(lang.hitch(this, "edit"), 0);
 	},
 
 	edit: function(){
@@ -190,12 +434,12 @@ dojo.declare("dijit.InlineEditBox",
 		//		private
 
 		if(this.disabled || this.editing){ return; }
-		this.editing = true;
+		this._set('editing', true);
 
 		// save some display node values that can be restored later
-		this._savedPosition = dojo.style(this.displayNode, "position") || "static";
-		this._savedOpacity = dojo.style(this.displayNode, "opacity") || "1";
-		this._savedTabIndex = dojo.attr(this.displayNode, "tabIndex") || "0";
+		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;
@@ -204,10 +448,10 @@ dojo.declare("dijit.InlineEditBox",
 			// 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 = dojo.create("span", null, this.domNode, "before");
+			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" ? dojo.getObject(this.editorWrapper) : this.editorWrapper;
+			var ewc = typeof this.editorWrapper == "string" ? lang.getObject(this.editorWrapper) : this.editorWrapper;
 			this.wrapperWidget = new ewc({
 				value: this.value,
 				buttonSave: this.buttonSave,
@@ -217,9 +461,10 @@ dojo.declare("dijit.InlineEditBox",
 				tabIndex: this._savedTabIndex,
 				editor: this.editor,
 				inlineEditBox: this,
-				sourceStyle: dojo.getComputedStyle(this.displayNode),
-				save: dojo.hitch(this, "save"),
-				cancel: dojo.hitch(this, "cancel")
+				sourceStyle: domStyle.getComputedStyle(this.displayNode),
+				save: lang.hitch(this, "save"),
+				cancel: lang.hitch(this, "cancel"),
+				textDir: this.textDir
 			}, placeholder);
 			if(!this._started){
 				this.startup();
@@ -227,24 +472,21 @@ dojo.declare("dijit.InlineEditBox",
 		}
 		var ww = this.wrapperWidget;
 
-		if(dojo.isIE){
-			dijit.focus(dijit.getFocus()); // IE (at least 8) needs help with tab order changes
-		}
 		// 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
 
-		dojo.style(this.displayNode, { position: "absolute", opacity: "0", display: "none" }); // makes display node invisible, display style used for focus-ability
-		dojo.style(ww.domNode, { position: this._savedPosition, visibility: "visible", opacity: "1" });
-		dojo.attr(this.displayNode, "tabIndex", "-1"); // needed by WebKit for TAB from editor to skip displayNode
+		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(dojo.hitch(this, function(){
-			ww.focus(); // both nodes are showing, so we can switch focus safely
-			ww._resetValue = ww.getValue();
+		setTimeout(lang.hitch(ww, function(){
+			this.focus(); // both nodes are showing, so we can switch focus safely
+			this._resetValue = this.getValue();
 		}), 0);
 	},
 
@@ -258,7 +500,7 @@ dojo.declare("dijit.InlineEditBox",
 		this.inherited(arguments);
 		if(!this.editing){
 			/* causes IE focus problems, see TooltipDialog_a11y.html...
-			setTimeout(dojo.hitch(this, function(){
+			setTimeout(lang.hitch(this, function(){
 				if(this.wrapperWidget){
 					this.wrapperWidget.destroy();
 					delete this.wrapperWidget;
@@ -283,11 +525,11 @@ dojo.declare("dijit.InlineEditBox",
 		//		private
 
 		var ww = this.wrapperWidget;
-		dojo.style(ww.domNode, { position: "absolute", visibility: "hidden", opacity: "0" }); // hide the editor from mouse/keyboard events
-		dojo.style(this.displayNode, { position: this._savedPosition, opacity: this._savedOpacity, display: "" }); // make the original text visible
-		dojo.attr(this.displayNode, "tabIndex", this._savedTabIndex);
+		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){
-			dijit.focus(this.displayNode);
+			fm.focus(this.displayNode);
 		}
 	},
 
@@ -300,7 +542,7 @@ dojo.declare("dijit.InlineEditBox",
 		//		private
 
 		if(this.disabled || !this.editing){ return; }
-		this.editing = false;
+		this._set('editing', false);
 
 		var ww = this.wrapperWidget;
 		var value = ww.getValue();
@@ -314,7 +556,7 @@ dojo.declare("dijit.InlineEditBox",
 		//		Deprecated.   Use set('value', ...) instead.
 		// tags:
 		//		deprecated
-		dojo.deprecated("dijit.InlineEditBox.setValue() is deprecated.  Use set('value', ...) instead.", "", "2.0");
+		kernel.deprecated("dijit.InlineEditBox.setValue() is deprecated.  Use set('value', ...) instead.", "", "2.0");
 		return this.set("value", val);
 	},
 
@@ -323,14 +565,18 @@ dojo.declare("dijit.InlineEditBox",
 		// 		Hook to make set("value", ...) work.
 		//		Inserts specified HTML value into this node, or an "input needed" character if node is blank.
 
-		val = dojo.trim(val);
+		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
-			setTimeout(dojo.hitch(this, "onChange", val), 0); // setTimeout prevents browser freeze for long-running event handlers
+			setTimeout(lang.hitch(this, "onChange", val), 0); // setTimeout prevents browser freeze for long-running event handlers
+		}
+		// contextual (auto) text direction depends on the text value
+		if(this.textDir == "auto"){
+			this.applyTextDir(this.displayNode, this.displayNode.innerText);
 		}
 	},
 
@@ -339,7 +585,7 @@ dojo.declare("dijit.InlineEditBox",
 		//		Deprecated.   Use get('value') instead.
 		// tags:
 		//		deprecated
-		dojo.deprecated("dijit.InlineEditBox.getValue() is deprecated.  Use get('value') instead.", "", "2.0");
+		kernel.deprecated("dijit.InlineEditBox.getValue() is deprecated.  Use get('value') instead.", "", "2.0");
 		return this.get("value");
 	},
 
@@ -350,226 +596,30 @@ dojo.declare("dijit.InlineEditBox",
 		//		private
 
 		if(this.disabled || !this.editing){ return; }
-		this.editing = false;
+		this._set('editing', false);
 
 		// tell the world that we have no changes
-		setTimeout(dojo.hitch(this, "onCancel"), 0); // setTimeout prevents browser freeze for long-running event handlers
+		setTimeout(lang.hitch(this, "onCancel"), 0); // setTimeout prevents browser freeze for long-running event handlers
 
 		this._showText(focus);
-	}
-});
-
-dojo.declare(
-	"dijit._InlineEditor",
-	 [dijit._Widget, dijit._Templated],
-{
-	// 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: dojo.cache("dijit", "templates/InlineEditBox.html"),
-	widgetsInTemplate: true,
-
-	postMixInProperties: function(){
-		this.inherited(arguments);
-		this.messages = dojo.i18n.getLocalization("dijit", "common", this.lang);
-		dojo.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" ? dojo.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 = dojo.getComputedStyle(this.domNode);
-		dojo.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);
-		dojo.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 = dojo.delegate(this.inlineEditBox.editorParams, {
-			style: editStyle,
-			dir: this.dir,
-			lang: this.lang
-		});
-		editorParams[ "displayedValue" 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
-			dojo.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);
-			}
-		}
-	},
-
-	_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 ? "displayedValue" : "value"));
 	},
-
-	_onKeyPress: function(e){
+	_setTextDirAttr: function(/*String*/ textDir){
 		// summary:
-		//		Handler for keypress in the edit box in autoSave mode.
+		//		Setter for textDir.
 		// description:
-		//		For autoSave widgets, if Esc/Enter, call cancel/save.
+		//		Users shouldn't call this function; they should be calling
+		//		set('textDir', value)
 		// 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 == dojo.keys.ESCAPE){
-				dojo.stopEvent(e);
-				this.cancel(true); // sets editing=false which short-circuits _onBlur processing
-			}else if(e.charOrCode == dojo.keys.ENTER && e.target.tagName == "INPUT"){
-				dojo.stopEvent(e);
-				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.
+		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
 		}
-	},
-
-	_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()){
-			dojo.style(this.inlineEditBox.displayNode, { display: "" });
-			dijit.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();
-		setTimeout(dojo.hitch(this, function(){
-			if(this.editWidget.focusNode && this.editWidget.focusNode.tagName == "INPUT"){
-				dijit.selectInputText(this.editWidget.focusNode);
-			}
-		}), 0);
-	}
+   }
 });
 
+InlineEditBox._InlineEditor = InlineEditor;	// for monkey patching
 
-return dijit.InlineEditBox;
-});
+return InlineEditBox;
+});
\ No newline at end of file
diff --git a/dijit/Menu.js b/dijit/Menu.js
index 1e2e7e9..1cbd6c8 100644
--- a/dijit/Menu.js
+++ b/dijit/Menu.js
@@ -1,398 +1,50 @@
-define("dijit/Menu", ["dojo", "dijit", "text!dijit/templates/Menu.html", "dojo/window", "dijit/_Widget", "dijit/_KeyNavContainer", "dijit/_Templated", "dijit/MenuItem", "dijit/PopupMenuItem", "dijit/CheckedMenuItem", "dijit/MenuSeparator"], function(dojo, dijit) {
-
-// "dijit/MenuItem", "dijit/PopupMenuItem", "dijit/CheckedMenuItem", "dijit/MenuSeparator" for Back-compat (TODO: remove in 2.0)
+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/_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/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
+	});
+}
 
-dojo.declare("dijit._MenuBase",
-	[dijit._Widget, dijit._Templated, dijit._KeyNavContainer],
-{
+return declare("dijit.Menu", DropDownMenu, {
 	// 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,
-
-	startup: function(){
-		if(this._started){ return; }
-
-		dojo.forEach(this.getChildren(), function(child){ child.startup(); });
-		this.startupKeyNavChildren();
-
-		this.inherited(arguments);
-	},
-
-	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();
-			}
-		}
-	},
-
-	_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);
-		}
-	},
-
-	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 focuses it)
-		if(this.isActive){
-			this.focusChild(item);
-			if(this.focusedChild.popup && !this.focusedChild.disabled && !this.hover_timer){
-				this.hover_timer = setTimeout(dojo.hitch(this, "_openPopup"), this.popupDelay);
-			}
-		}
-		// 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;
-				}
-				dijit.popup.close(itemPopup); // this calls onClose
-			}, this.popupDelay);
-		}
-	},
-
-	onItemUnhover: function(/*MenuItem*/ item){
-		// summary:
-		//		Callback fires when mouse exits a MenuItem
-		// tags:
-		//		protected
-
-		if(this.isActive){
-			this._stopPopupTimer();
-		}
-		if(this._hoveredChild == item){ this._hoveredChild = null; }
-	},
-
-	_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;
-		}
-	},
-
-	_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;
-		}
-	},
-
-	_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;
-		}
-	},
-
-	_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
-
-		// this can't be done in _onFocus since the _onFocus events occurs asynchronously
-		if(typeof this.isShowingNow == 'undefined'){ // non-popup menu
-			this._markActive();
-		}
-
-		this.focusChild(item);
-
-		if(item.disabled){ return 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();
-
-			// user defined handler for click
-			item.onClick(evt);
-		}
-	},
-
-	_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);
-			dijit.popup.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;
-		dijit.popup.open({
-			parent: this,
-			popup: popup,
-			around: from_item.domNode,
-			orient: this._orient || (this.isLeftToRight() ?
-									{'TR': 'TL', 'TL': 'TR', 'BR': 'BL', 'BL': 'BR'} :
-									{'TL': 'TR', 'TR': 'TL', 'BL': 'BR', 'BR': 'BL'}),
-			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: dojo.hitch(this, "_cleanUp")
-		});
-
-		this.currentPopup = popup;
-		// detect mouseovers to handle lazy mouse movements that temporarily focus other menu items
-		popup.connect(popup.domNode, "onmouseenter", dojo.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(dojo.hitch(popup, function(){
-				this._focus_timer = null;
-				this.focus();
-			}), 0);
-		}
-	},
-
-	_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;
-		dojo.replaceClass(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
-
-		this.isShowingNow = true;
-		this._markActive();
-	},
-
-	_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
-		dojo.replaceClass(this.domNode, "dijitMenuPassive", "dijitMenuActive");
-	},
-
-	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();
-
-		var fromItem = this.focusedChild && this.focusedChild.from_item;
-
-		if(this.currentPopup){
-			// If focus is on my child menu then move focus to me,
-			// because IE doesn't like it when you display:none a node with focus
-			if(dijit._curFocus && dojo.isDescendant(dijit._curFocus, this.currentPopup.domNode)){
-				this.focusedChild.focusNode.focus();
-			}
-			// Close all popups that are open and descendants of this menu
-			dijit.popup.close(this.currentPopup);
-			this.currentPopup = null;
-		}
-
-		if(this.focusedChild){ // unhighlight the focused item
-			this.focusedChild._setSelected(false);
-			this.focusedChild._onUnhover();
-			this.focusedChild = 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._hoveredChild._onUnhover(); // any previous mouse movement is trumped by focus selection
-		}
-	},
-
-	_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
-
-		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();
-		}
-	}
-});
-
-dojo.declare("dijit.Menu",
-	dijit._MenuBase,
-	{
-	// summary
 	//		A context menu you can assign to multiple elements
 
-	// TODO: most of the code in here is just for context menu (right-click menu)
-	// support.  In retrospect that should have been a separate class (dijit.ContextMenu).
-	// Split them for 2.0
-
 	constructor: function(){
 		this._bindings = [];
 	},
 
-	templateString: dojo.cache("dijit", "templates/Menu.html"),
-
-	baseClass: "dijitMenu",
-
 	// 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.
@@ -404,7 +56,7 @@ dojo.declare("dijit.Menu",
 	contextMenuForWindow: false,
 
 	// leftClickToOpen: [const] Boolean
-	//		If true, menu will open on left click instead of right click, similiar to a file menu.
+	//		If true, menu will open on left click instead of right click, similar to a file menu.
 	leftClickToOpen: false,
 
 	// refocus: Boolean
@@ -413,44 +65,14 @@ dojo.declare("dijit.Menu",
 
 	postCreate: function(){
 		if(this.contextMenuForWindow){
-			this.bindDomNode(dojo.body());
+			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[]
+			// 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)
-			dojo.forEach(this.targetNodeIds, this.bindDomNode, this);
-		}
-		var k = dojo.keys, l = this.isLeftToRight();
-		this._openSubMenuKey = l ? k.RIGHT_ARROW : k.LEFT_ARROW;
-		this._closeSubMenuKey = l ? k.LEFT_ARROW : k.RIGHT_ARROW;
-		this.connectKeyNavHandlers([k.UP_ARROW], [k.DOWN_ARROW]);
-	},
-
-	_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);
-				dojo.stopEvent(evt);
-				break;
-			case this._closeSubMenuKey:
-				if(this.parentMenu){
-					if(this.parentMenu._isMenuBar){
-						this.parentMenu.focusPrev();
-					}else{
-						this.onCancel(false);
-					}
-				}else{
-					dojo.stopEvent(evt);
-				}
-				break;
+			array.forEach(this.targetNodeIds, this.bindDomNode, this);
 		}
+		this.inherited(arguments);
 	},
 
 	// thanks burstlib!
@@ -459,11 +81,10 @@ dojo.declare("dijit.Menu",
 		//		Returns the window reference of the passed iframe
 		// tags:
 		//		private
-		var win = dojo.window.get(this._iframeContentDocument(iframe_el)) ||
+		return winUtils.get(this._iframeContentDocument(iframe_el)) ||
 			// Moz. TODO: is this available when defaultView isn't?
 			this._iframeContentDocument(iframe_el)['__parent__'] ||
-			(iframe_el.name && dojo.doc.frames[iframe_el.name]) || null;
-		return win;	//	Window
+			(iframe_el.name && win.doc.frames[iframe_el.name]) || null;	//	Window
 	},
 
 	_iframeContentDocument: function(/* HTMLIFrameElement */iframe_el){
@@ -471,31 +92,30 @@ dojo.declare("dijit.Menu",
 		//		Returns a reference to the document object inside iframe_el
 		// tags:
 		//		protected
-		var doc = iframe_el.contentDocument // W3
+		return iframe_el.contentDocument // W3
 			|| (iframe_el.contentWindow && iframe_el.contentWindow.document) // IE
-			|| (iframe_el.name && dojo.doc.frames[iframe_el.name] && dojo.doc.frames[iframe_el.name].document)
-			|| null;
-		return doc;	//	HTMLDocument
+			|| (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 = dojo.byId(node);
+		node = dom.byId(node);
 
 		var cn;	// Connect node
 
-		// Support context menus on iframes.   Rather than binding to the iframe itself we need
+		// 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,
-				win = this._iframeContentWindow(iframe);
-			cn = dojo.withGlobal(win, dojo.body);
+				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 == dojo.body() ? dojo.doc.documentElement : node);
+			cn = (node == win.body() ? win.doc.documentElement : node);
 		}
 
 
@@ -506,29 +126,29 @@ dojo.declare("dijit.Menu",
 		};
 
 		// 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
+		// _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));
+		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 = dojo.hitch(this, function(cn){
+		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?
-				dojo.connect(cn, this.leftClickToOpen ? "onclick" : "oncontextmenu", this, function(evt){
+				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
-					dojo.stopEvent(evt);
+					event.stop(evt);
 					this._scheduleOpen(evt.target, iframe, {x: evt.pageX, y: evt.pageY});
-				}),
-				dojo.connect(cn, "onkeydown", this, function(evt){
-					if(evt.shiftKey && evt.keyCode == dojo.keys.F10){
-						dojo.stopEvent(evt);
+				})),
+				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
 					}
-				})
+				}))
 			];
 		});
 		binding.connects = cn ? doConnects(cn) : [];
@@ -537,14 +157,14 @@ dojo.declare("dijit.Menu",
 			// 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.
+			// Note: can't use connect.connect(), see #9609.
 
-			binding.onloadHandler = dojo.hitch(this, function(){
+			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 win = this._iframeContentWindow(iframe);
-					cn = dojo.withGlobal(win, dojo.body);
+				var window = this._iframeContentWindow(iframe);
+					cn = win.withGlobal(window, win.body);
 				binding.connects = doConnects(cn);
 			});
 			if(iframe.addEventListener){
@@ -561,9 +181,9 @@ dojo.declare("dijit.Menu",
 
 		var node;
 		try{
-			node = dojo.byId(nodeName);
+			node = dom.byId(nodeName);
 		}catch(e){
-			// On IE the dojo.byId() call will get an exception if the attach point was
+			// 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;
@@ -571,9 +191,11 @@ dojo.declare("dijit.Menu",
 
 		// node["_dijitMenu" + this.id] contains index(+1) into my _bindings[] array
 		var attrName = "_dijitMenu" + this.id;
-		if(node && dojo.hasAttr(node, attrName)){
-			var bid = dojo.attr(node, attrName)-1, b = this._bindings[bid];
-			dojo.forEach(b.connects, dojo.disconnect);
+		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();
+			}
 
 			// Remove listener for iframe onload events
 			var iframe = b.iframe;
@@ -585,7 +207,7 @@ dojo.declare("dijit.Menu",
 				}
 			}
 
-			dojo.removeAttr(node, attrName);
+			domAttr.remove(node, attrName);
 			delete this._bindings[bid];
 		}
 	},
@@ -599,11 +221,11 @@ dojo.declare("dijit.Menu",
 		//		context menu to appear in spite of stopEvent.
 		//
 		//		2. Avoid double-shows on linux, where shift-F10 generates an oncontextmenu event
-		//		even after a dojo.stopEvent(e).  (Shift-F10 on windows doesn't generate the
+		//		even after a event.stop(e).  (Shift-F10 on windows doesn't generate the
 		//		oncontextmenu event.)
 
 		if(!this._openTimer){
-			this._openTimer = setTimeout(dojo.hitch(this, function(){
+			this._openTimer = setTimeout(lang.hitch(this, function(){
 				delete this._openTimer;
 				this._openMyself({
 					target: target,
@@ -640,35 +262,37 @@ dojo.declare("dijit.Menu",
 		if(coords){
 			if(iframe){
 				// Specified coordinates are on <body> node of an <iframe>, convert to match main document
-				var od = target.ownerDocument,
-					ifc = dojo.position(iframe, true),
-					win = this._iframeContentWindow(iframe),
-					scroll = dojo.withGlobal(win, "_docScroll", dojo);
-	
-				var cs = dojo.getComputedStyle(iframe),
-					tp = dojo._toPixelValue,
-					left = (dojo.isIE && dojo.isQuirks ? 0 : tp(iframe, cs.paddingLeft)) + (dojo.isIE && dojo.isQuirks ? tp(iframe, cs.borderLeftWidth) : 0),
-					top = (dojo.isIE && dojo.isQuirks ? 0 : tp(iframe, cs.paddingTop)) + (dojo.isIE && dojo.isQuirks ? tp(iframe, cs.borderTopWidth) : 0);
+				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;
 			}
 		}else{
-			coords = dojo.position(target, true);
+			coords = domGeometry.position(target, true);
 			coords.x += 10;
 			coords.y += 10;
 		}
 
 		var self=this;
-		var savedFocus = dijit.getFocus(this);
+		var prevFocusNode = this._focusManager.get("prevNode");
+		var curFocusNode = this._focusManager.get("curNode");
+		var savedFocusNode = !curFocusNode || (dom.isDescendant(curFocusNode, this.domNode)) ? prevFocusNode : curFocusNode;
+
 		function closeAndRestoreFocus(){
 			// user has clicked on a menu or popup
-			if(self.refocus){
-				dijit.focus(savedFocus);
+			if(self.refocus && savedFocusNode){
+				savedFocusNode.focus();
 			}
-			dijit.popup.close(self);
+			pm.close(self);
 		}
-		dijit.popup.open({
+		pm.open({
 			popup: this,
 			x: coords.x,
 			y: coords.y,
@@ -682,18 +306,16 @@ dojo.declare("dijit.Menu",
 			this.inherited('_onBlur', arguments);
 			// Usually the parent closes the child widget but if this is a context
 			// menu then there is no parent
-			dijit.popup.close(this);
+			pm.close(this);
 			// don't try to restore focus; user has clicked another part of the screen
 			// and set focus there
 		};
 	},
 
 	uninitialize: function(){
- 		dojo.forEach(this._bindings, function(b){ if(b){ this.unBindDomNode(b.node); } }, this);
+ 		array.forEach(this._bindings, function(b){ if(b){ this.unBindDomNode(b.node); } }, this);
  		this.inherited(arguments);
 	}
-}
-);
+});
 
-return dijit.Menu;
 });
diff --git a/dijit/MenuBar.js b/dijit/MenuBar.js
index 20c8e0e..ef8e651 100644
--- a/dijit/MenuBar.js
+++ b/dijit/MenuBar.js
@@ -1,10 +1,25 @@
-define("dijit/MenuBar", ["dojo", "dijit", "text!dijit/templates/MenuBar.html", "dijit/Menu"], function(dojo, dijit) {
+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){
 
-dojo.declare("dijit.MenuBar", dijit._MenuBase, {
+/*=====
+	var _MenuBase = dijit._MenuBase;
+=====*/
+
+// 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
 
-	templateString: dojo.cache("dijit", "templates/MenuBar.html"),
+	templateString: template,
 
 	baseClass: "dijitMenuBar",
 
@@ -13,14 +28,14 @@ dojo.declare("dijit.MenuBar", dijit._MenuBase, {
 	_isMenuBar: true,
 
 	postCreate: function(){
-		var k = dojo.keys, l = this.isLeftToRight();
+		var l = this.isLeftToRight();
 		this.connectKeyNavHandlers(
-			l ? [k.LEFT_ARROW] : [k.RIGHT_ARROW],
-			l ? [k.RIGHT_ARROW] : [k.LEFT_ARROW]
+			l ? [keys.LEFT_ARROW] : [keys.RIGHT_ARROW],
+			l ? [keys.RIGHT_ARROW] : [keys.LEFT_ARROW]
 		);
 
 		// parameter to dijit.popup.open() about where to put popup (relative to this.domNode)
-		this._orient = this.isLeftToRight() ? {BL: 'TL'} : {BR: 'TR'};
+		this._orient = ["below"];
 	},
 
 	focusChild: function(item){
@@ -44,9 +59,9 @@ dojo.declare("dijit.MenuBar", dijit._MenuBase, {
 		if(evt.ctrlKey || evt.altKey){ return; }
 
 		switch(evt.charOrCode){
-			case dojo.keys.DOWN_ARROW:
+			case keys.DOWN_ARROW:
 				this._moveToPopup(evt);
-				dojo.stopEvent(evt);
+				event.stop(evt);
 		}
 	},
 
@@ -63,6 +78,4 @@ dojo.declare("dijit.MenuBar", dijit._MenuBase, {
 	}
 });
 
-
-return dijit.MenuBar;
 });
diff --git a/dijit/MenuBarItem.js b/dijit/MenuBarItem.js
index c0c7b6f..5a0dd6a 100644
--- a/dijit/MenuBarItem.js
+++ b/dijit/MenuBarItem.js
@@ -1,20 +1,33 @@
-define("dijit/MenuBarItem", ["dojo", "dijit", "text!dijit/templates/MenuBarItem.html", "dijit/MenuItem"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"./MenuItem",
+	"dojo/text!./templates/MenuBarItem.html"
+], function(declare, MenuItem, template){
 
-dojo.declare("dijit._MenuBarItemMixin", null, {
-	templateString: dojo.cache("dijit", "templates/MenuBarItem.html"),
+/*=====
+	var MenuItem = dijit.MenuItem;
+=====*/
 
-	// overriding attributeMap because we don't have icon
-	attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
-		label: { node: "containerNode", type: "innerHTML" }
-	})
-});
-
-dojo.declare("dijit.MenuBarItem", [dijit.MenuItem, dijit._MenuBarItemMixin], {
+	// 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,
+
+		// Map widget attributes to DOMNode attributes.
+		_setIconClassAttr: null	// cancel MenuItem setter because we don't have a place for an icon
+	});
+
+	var MenuBarItem = declare("dijit.MenuBarItem", [MenuItem, _MenuBarItemMixin], {
+		// summary:
+		//		Item in a MenuBar that's clickable, and doesn't spawn a submenu when pressed (or hovered)
+
+	});
+	MenuBarItem._MenuBarItemMixin = _MenuBarItemMixin;	// dojox.mobile is accessing this
 
 
-return dijit.MenuBarItem;
+	return MenuBarItem;
 });
diff --git a/dijit/MenuItem.js b/dijit/MenuItem.js
index 0b99098..85c2a5b 100644
--- a/dijit/MenuItem.js
+++ b/dijit/MenuItem.js
@@ -1,29 +1,53 @@
-define("dijit/MenuItem", ["dojo", "dijit", "text!dijit/templates/MenuItem.html", "dijit/_Widget", "dijit/_Templated", "dijit/_Contained", "dijit/_CssStateMixin"], function(dojo, dijit) {
-
-dojo.declare("dijit.MenuItem",
-		[dijit._Widget, dijit._Templated, dijit._Contained, dijit._CssStateMixin],
+define([
+	"dojo/_base/declare", // declare
+	"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")
+	"./_Widget",
+	"./_TemplatedMixin",
+	"./_Contained",
+	"./_CssStateMixin",
+	"dojo/text!./templates/MenuItem.html"
+], function(declare, dom, domAttr, domClass, event, kernel, has,
+			_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],
 		{
 		// summary:
 		//		A line item in a Menu Widget
 
 		// Make 3 columns
 		// icon, label, and expand arrow (BiDi-dependent) indicating sub-menu
-		templateString: dojo.cache("dijit", "templates/MenuItem.html"),
-
-		attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
-			label: { node: "containerNode", type: "innerHTML" },
-			iconClass: { node: "iconNode", type: "class" }
-		}),
+		templateString: template,
 
 		baseClass: "dijitMenuItem",
 
 		// label: String
 		//		Menu text
 		label: '',
+		_setLabelAttr: { node: "containerNode", type: "innerHTML" },
 
 		// iconClass: String
 		//		Class to apply to DOMNode to make it display an icon.
-		iconClass: "",
+		iconClass: "dijitNoIcon",
+		_setIconClassAttr: { node: "iconNode", type: "class" },
 
 		// accelKey: String
 		//		Text for the accelerator (shortcut) key combination.
@@ -48,13 +72,13 @@ dojo.declare("dijit.MenuItem",
 		buildRendering: function(){
 			this.inherited(arguments);
 			var label = this.id+"_text";
-			dojo.attr(this.containerNode, "id", label);
+			domAttr.set(this.containerNode, "id", label);
 			if(this.accelKeyNode){
-				dojo.attr(this.accelKeyNode, "id", this.id + "_accel");
+				domAttr.set(this.accelKeyNode, "id", this.id + "_accel");
 				label += " " + this.id + "_accel";
 			}
-			dijit.setWaiState(this.domNode, "labelledby", label);
-			dojo.setSelectable(this.domNode, false);
+			this.domNode.setAttribute("aria-labelledby", label);
+			dom.setSelectable(this.domNode, false);
 		},
 
 		_onHover: function(){
@@ -89,10 +113,10 @@ dojo.declare("dijit.MenuItem",
 			// tags:
 			//		private
 			this.getParent().onItemClick(this, evt);
-			dojo.stopEvent(evt);
+			event.stop(evt);
 		},
 
-		onClick: function(/*Event*/ evt){
+		onClick: function(/*Event*/){
 			// summary:
 			//		User defined function to handle clicks
 			// tags:
@@ -103,11 +127,11 @@ dojo.declare("dijit.MenuItem",
 			// summary:
 			//		Focus on this MenuItem
 			try{
-				if(dojo.isIE == 8){
+				if(has("ie") == 8){
 					// needed for IE8 which won't scroll TR tags into view on focus yet calling scrollIntoView creates flicker (#10275)
 					this.containerNode.focus();
 				}
-				dijit.focus(this.focusNode);
+				this.focusNode.focus();
 			}catch(e){
 				// this throws on IE (at least) in some scenarios
 			}
@@ -141,7 +165,7 @@ dojo.declare("dijit.MenuItem",
 			 * _onBlur()
 			 */
 
-			dojo.toggleClass(this.domNode, "dijitMenuItemSelected", selected);
+			domClass.toggle(this.domNode, "dijitMenuItemSelected", selected);
 		},
 
 		setLabel: function(/*String*/ content){
@@ -149,7 +173,7 @@ dojo.declare("dijit.MenuItem",
 			//		Deprecated.   Use set('label', ...) instead.
 			// tags:
 			//		deprecated
-			dojo.deprecated("dijit.MenuItem.setLabel() is deprecated.  Use set('label', ...) instead.", "", "2.0");
+			kernel.deprecated("dijit.MenuItem.setLabel() is deprecated.  Use set('label', ...) instead.", "", "2.0");
 			this.set("label", content);
 		},
 
@@ -158,7 +182,7 @@ dojo.declare("dijit.MenuItem",
 			//		Deprecated.   Use set('disabled', bool) instead.
 			// tags:
 			//		deprecated
-			dojo.deprecated("dijit.Menu.setDisabled() is deprecated.  Use set('disabled', bool) instead.", "", "2.0");
+			kernel.deprecated("dijit.Menu.setDisabled() is deprecated.  Use set('disabled', bool) instead.", "", "2.0");
 			this.set('disabled', disabled);
 		},
 		_setDisabledAttr: function(/*Boolean*/ value){
@@ -166,7 +190,7 @@ dojo.declare("dijit.MenuItem",
 			//		Hook for attr('disabled', ...) to work.
 			//		Enable or disable this menu item.
 
-			dijit.setWaiState(this.focusNode, 'disabled', value ? 'true' : 'false');
+			this.focusNode.setAttribute('aria-disabled', value ? 'true' : 'false');
 			this._set("disabled", value);
 		},
 		_setAccelKeyAttr: function(/*String*/ value){
@@ -177,12 +201,9 @@ dojo.declare("dijit.MenuItem",
 			this.accelKeyNode.style.display=value?"":"none";
 			this.accelKeyNode.innerHTML=value;
 			//have to use colSpan to make it work in IE
-			dojo.attr(this.containerNode,'colSpan',value?"1":"2");
-			
+			domAttr.set(this.containerNode,'colSpan',value?"1":"2");
+
 			this._set("accelKey", value);
 		}
 	});
-
-
-return dijit.MenuItem;
 });
diff --git a/dijit/MenuSeparator.js b/dijit/MenuSeparator.js
index 5dbe665..44c209a 100644
--- a/dijit/MenuSeparator.js
+++ b/dijit/MenuSeparator.js
@@ -1,16 +1,32 @@
-define("dijit/MenuSeparator", ["dojo", "dijit", "text!dijit/templates/MenuSeparator.html", "dijit/_Widget", "dijit/_Templated", "dijit/_Contained"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/dom", // dom.setSelectable
+	"./_WidgetBase",
+	"./_TemplatedMixin",
+	"./_Contained",
+	"dojo/text!./templates/MenuSeparator.html"
+], function(declare, dom, _WidgetBase, _TemplatedMixin, _Contained, template){
 
-dojo.declare("dijit.MenuSeparator",
-		[dijit._Widget, dijit._Templated, dijit._Contained],
-		{
+/*=====
+	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:
 		//		A line between two menu items
 
-		templateString: dojo.cache("dijit", "templates/MenuSeparator.html"),
+		templateString: template,
 
 		buildRendering: function(){
 			this.inherited(arguments);
-			dojo.setSelectable(this.domNode, false);
+			dom.setSelectable(this.domNode, false);
 		},
 
 		isFocusable: function(){
@@ -22,7 +38,4 @@ dojo.declare("dijit.MenuSeparator",
 			return false; // Boolean
 		}
 	});
-
-
-return dijit.MenuSeparator;
 });
diff --git a/dijit/PopupMenuBarItem.js b/dijit/PopupMenuBarItem.js
index dd63b08..04e8d20 100644
--- a/dijit/PopupMenuBarItem.js
+++ b/dijit/PopupMenuBarItem.js
@@ -1,10 +1,23 @@
-define("dijit/PopupMenuBarItem", ["dojo", "dijit", "dijit/PopupMenuItem", "dijit/MenuBarItem"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"./PopupMenuItem",
+	"./MenuBarItem"
+], function(declare, PopupMenuItem, MenuBarItem){
 
-dojo.declare("dijit.PopupMenuBarItem", [dijit.PopupMenuItem, dijit._MenuBarItemMixin], {
+	// 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 dijit.PopupMenuBarItem;
+	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 a231fe7..54eb730 100644
--- a/dijit/PopupMenuItem.js
+++ b/dijit/PopupMenuItem.js
@@ -1,8 +1,26 @@
-define("dijit/PopupMenuItem", ["dojo", "dijit", "dijit/MenuItem"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/dom-style", // domStyle.set
+	"dojo/query", // query
+	"dojo/_base/window", // win.body
+	"./registry",	// registry.byNode
+	"./MenuItem",
+	"./hccss"
+], function(declare, domStyle, query, win, registry, MenuItem){
+
+/*=====
+	var MenuItem = dijit.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:
+		//		An item in a Menu that spawn a drop down (usually a drop down menu)
 
-dojo.declare("dijit.PopupMenuItem",
-		dijit.MenuItem,
-		{
 		_fillContent: function(){
 			// summary:
 			//		When Menu is declared in markup, this code gets the menu label and
@@ -11,7 +29,7 @@ dojo.declare("dijit.PopupMenuItem",
 			//		srcNodeRefinnerHTML 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 dojoType="dijit.PopupMenuItem">
+			// |	<div data-dojo-type="dijit.PopupMenuItem">
 			// |		<span>pick me</span>
 			// |		<popup> ... </popup>
 			// |	</div>
@@ -19,8 +37,8 @@ dojo.declare("dijit.PopupMenuItem",
 			//		protected
 
 			if(this.srcNodeRef){
-				var nodes = dojo.query("*", this.srcNodeRef);
-				dijit.PopupMenuItem.superclass._fillContent.call(this, 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;
@@ -32,34 +50,31 @@ dojo.declare("dijit.PopupMenuItem",
 			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 dojo.doc.body.
+			// land now.  move it to win.doc.body.
 			if(!this.popup){
-				var node = dojo.query("[widgetId]", this.dropDownContainer)[0];
-				this.popup = dijit.byNode(node);
+				var node = query("[widgetId]", this.dropDownContainer)[0];
+				this.popup = registry.byNode(node);
 			}
-			dojo.body().appendChild(this.popup.domNode);
+			win.body().appendChild(this.popup.domNode);
 			this.popup.startup();
 
 			this.popup.domNode.style.display="none";
 			if(this.arrowWrapper){
-				dojo.style(this.arrowWrapper, "visibility", "");
+				domStyle.set(this.arrowWrapper, "visibility", "");
 			}
-			dijit.setWaiState(this.focusNode, "haspopup", "true");
+			this.focusNode.setAttribute("aria-haspopup", "true");
 		},
 
-		destroyDescendants: function(){
+		destroyDescendants: function(/*Boolean*/ preserveDom){
 			if(this.popup){
 				// Destroy the popup, unless it's already been destroyed.  This can happen because
 				// the popup is a direct child of <body> even though it's logically my child.
 				if(!this.popup._destroyed){
-					this.popup.destroyRecursive();
+					this.popup.destroyRecursive(preserveDom);
 				}
 				delete this.popup;
 			}
 			this.inherited(arguments);
 		}
 	});
-
-
-return dijit.PopupMenuItem;
 });
diff --git a/dijit/ProgressBar.js b/dijit/ProgressBar.js
index 87a0bbe..5c7a3d6 100644
--- a/dijit/ProgressBar.js
+++ b/dijit/ProgressBar.js
@@ -1,12 +1,33 @@
-define("dijit/ProgressBar", ["dojo", "dijit", "text!dijit/templates/ProgressBar.html", "dojo/fx", "dojo/number", "dijit/_Widget", "dijit/_Templated"], function(dojo, dijit) {
-
-dojo.declare("dijit.ProgressBar", [dijit._Widget, dijit._Templated], {
+define([
+	"require",			// require.toUrl
+	"dojo/_base/declare", // declare
+	"dojo/dom-class", // domClass.toggle
+	"dojo/_base/lang", // lang.mixin
+	"dojo/number", // number.format
+	"./_Widget",
+	"./_TemplatedMixin",
+	"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 dojoType="ProgressBar"
+	// |	<div data-dojo-type="ProgressBar"
 	// |		 places="0"
 	// |		 value="..." maximum="...">
 	// |	</div>
@@ -47,12 +68,12 @@ dojo.declare("dijit.ProgressBar", [dijit._Widget, dijit._Templated], {
 	//		this widget in a dijit.form.Form widget (such as dijit.Dialog)
 	name: '',
 
-	templateString: dojo.cache("dijit", "templates/ProgressBar.html"),
+	templateString: template,
 
-	// _indeterminateHighContrastImagePath: [private] dojo._URL
+	// _indeterminateHighContrastImagePath: [private] URL
 	//		URL to image to use for indeterminate progress bar when display is in high contrast mode
 	_indeterminateHighContrastImagePath:
-		dojo.moduleUrl("dijit", "themes/a11y/indeterminate_progress.gif"),
+		require.toUrl("./themes/a11y/indeterminate_progress.gif"),
 
 	postMixInProperties: function(){
 		this.inherited(arguments);
@@ -84,30 +105,30 @@ dojo.declare("dijit.ProgressBar", [dijit._Widget, dijit._Templated], {
 
 		// TODO: deprecate this method and use set() instead
 
-		dojo.mixin(this, attributes || {});
+		lang.mixin(this, attributes || {});
 		var tip = this.internalProgress, ap = this.domNode;
 		var percent = 1;
 		if(this.indeterminate){
-			dijit.removeWaiState(ap, "valuenow");
-			dijit.removeWaiState(ap, "valuemin");
-			dijit.removeWaiState(ap, "valuemax");
+			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;
 			}else{
 				this.progress = Math.min(this.progress, this.maximum);
-				percent = this.progress / this.maximum;
+				percent = this.maximum ? this.progress / this.maximum : 0;
 			}
 
-			dijit.setWaiState(ap, "describedby", this.labelNode.id);
-			dijit.setWaiState(ap, "valuenow", this.progress);
-			dijit.setWaiState(ap, "valuemin", 0);
-			dijit.setWaiState(ap, "valuemax", this.maximum);
+			ap.setAttribute("aria-describedby", this.labelNode.id);
+			ap.setAttribute("aria-valuenow", this.progress);
+			ap.setAttribute("aria-valuemin", 0);
+			ap.setAttribute("aria-valuemax", this.maximum);
 		}
 		this.labelNode.innerHTML = this.report(percent);
 
-		dojo.toggleClass(this.domNode, "dijitProgressBarIndeterminate", this.indeterminate);
+		domClass.toggle(this.domNode, "dijitProgressBarIndeterminate", this.indeterminate);
 		tip.style.width = (percent * 100) + "%";
 		this.onChange();
 	},
@@ -140,7 +161,7 @@ dojo.declare("dijit.ProgressBar", [dijit._Widget, dijit._Templated], {
 		//		extension
 
 		return this.label ? this.label :
-				(this.indeterminate ? " " : dojo.number.format(percent, { type: "percent", places: this.places, locale: this.lang }));
+				(this.indeterminate ? " " : number.format(percent, { type: "percent", places: this.places, locale: this.lang }));
 	},
 
 	onChange: function(){
@@ -151,6 +172,4 @@ dojo.declare("dijit.ProgressBar", [dijit._Widget, dijit._Templated], {
 	}
 });
 
-
-return dijit.ProgressBar;
 });
diff --git a/dijit/TitlePane.js b/dijit/TitlePane.js
index 7605628..f30c065 100644
--- a/dijit/TitlePane.js
+++ b/dijit/TitlePane.js
@@ -1,9 +1,36 @@
-define("dijit/TitlePane", ["dojo", "dijit", "text!dijit/templates/TitlePane.html", "dojo/fx", "dijit/_Templated", "dijit/layout/ContentPane", "dijit/_CssStateMixin"], function(dojo, dijit) {
-
-dojo.declare(
-	"dijit.TitlePane",
-	[dijit.layout.ContentPane, dijit._Templated, dijit._CssStateMixin],
-{
+define([
+	"dojo/_base/array", // array.forEach
+	"dojo/_base/declare", // declare
+	"dojo/dom", // dom.setSelectable
+	"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/_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,
+			_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.
 	//
@@ -19,17 +46,18 @@ dojo.declare(
 	//
 	// example:
 	// |	<!-- markup href example: -->
-	// |	<div dojoType="dijit.TitlePane" href="foobar.html" title="Title"></div>
+	// |	<div data-dojo-type="dijit.TitlePane" data-dojo-props="href: 'foobar.html', title: 'Title'"></div>
 	//
 	// example:
 	// |	<!-- markup with inline data -->
-	// | 	<div dojoType="dijit.TitlePane" title="Title">
+	// | 	<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.
@@ -46,28 +74,32 @@ dojo.declare(
 
 	// duration: Integer
 	//		Time in milliseconds to fade in/fade out
-	duration: dijit.defaultDuration,
+	duration: manager.defaultDuration,
 
 	// baseClass: [protected] String
 	//		The root className to be placed on this widget's domNode.
 	baseClass: "dijitTitlePane",
 
-	templateString: dojo.cache("dijit", "templates/TitlePane.html"),
+	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,
 
-	attributeMap: dojo.delegate(dijit.layout.ContentPane.prototype.attributeMap, {
-		title: { node: "titleNode", type: "innerHTML" },
-		tooltip: {node: "focusNode", type: "attribute", attribute: "title"},	// focusNode spans the entire width, titleNode doesn't
-		id:""
-	}),
+	// 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);
-		dojo.setSelectable(this.titleNode, false);
+		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
@@ -77,15 +109,15 @@ dojo.declare(
 
 		// setup open/close animations
 		var hideNode = this.hideNode, wipeNode = this.wipeNode;
-		this._wipeIn = dojo.fx.wipeIn({
-			node: this.wipeNode,
+		this._wipeIn = fxUtils.wipeIn({
+			node: wipeNode,
 			duration: this.duration,
 			beforeBegin: function(){
 				hideNode.style.display="";
 			}
 		});
-		this._wipeOut = dojo.fx.wipeOut({
-			node: this.wipeNode,
+		this._wipeOut = fxUtils.wipeOut({
+			node: wipeNode,
 			duration: this.duration,
 			onEnd: function(){
 				hideNode.style.display="none";
@@ -99,7 +131,7 @@ dojo.declare(
 		// open: Boolean
 		//		True if you want to open the pane, false if you want to close it.
 
-		dojo.forEach([this._wipeIn, this._wipeOut], function(animation){
+		array.forEach([this._wipeIn, this._wipeOut], function(animation){
 			if(animation && animation.status() == "playing"){
 				animation.stop();
 			}
@@ -124,8 +156,8 @@ dojo.declare(
 
 		this.arrowNodeInner.innerHTML = open ? "-" : "+";
 
-		dijit.setWaiState(this.containerNode,"hidden", open ? "false" : "true");
-		dijit.setWaiState(this.focusNode, "pressed", open ? "true" : "false");
+		this.containerNode.setAttribute("aria-hidden", open ? "false" : "true");
+		this.focusNode.setAttribute("aria-pressed", open ? "true" : "false");
 
 		this._set("open", open);
 
@@ -138,13 +170,13 @@ dojo.declare(
 		// canToggle: Boolean
 		//		True to allow user to open/close pane by clicking title bar.
 
-		dijit.setWaiRole(this.focusNode, canToggle ? "button" : "heading");
+		this.focusNode.setAttribute("role", canToggle ? "button" : "heading");
 		if(canToggle){
 			// TODO: if canToggle is switched from true to false shouldn't we remove this setting?
-			dijit.setWaiState(this.focusNode, "controls", this.id+"_pane");
-			dojo.attr(this.focusNode, "tabIndex", this.tabIndex);
+			this.focusNode.setAttribute("aria-controls", this.id+"_pane");
+			domAttr.set(this.focusNode, "tabIndex", this.tabIndex);
 		}else{
-			dojo.removeAttr(this.focusNode, "tabIndex");
+			domAttr.remove(this.focusNode, "tabIndex");
 		}
 
 		this._set("toggleable", canToggle);
@@ -166,7 +198,7 @@ dojo.declare(
 			}
 
 			// freeze container at current height so that adding new content doesn't make it jump
-			dojo.marginBox(this.wipeNode, { h: dojo.marginBox(this.wipeNode).h });
+			domGeometry.setMarginBox(this.wipeNode, { h: domGeometry.getMarginBox(this.wipeNode).h });
 
 			// add the new content (erasing the old content, if any)
 			this.inherited(arguments);
@@ -198,7 +230,7 @@ dojo.declare(
 		var node = this.titleBarNode || this.focusNode;
 		var oldCls = this._titleBarClass;
 		this._titleBarClass = "dijit" + (this.toggleable ? "" : "Fixed") + (this.open ? "Open" : "Closed");
-		dojo.replaceClass(node, this._titleBarClass, oldCls || "");
+		domClass.replace(node, this._titleBarClass, oldCls || "");
 
 		this.arrowNodeInner.innerHTML = this.open ? "-" : "+";
 	},
@@ -209,12 +241,12 @@ dojo.declare(
 		// tags:
 		//		private
 
-		if(e.charOrCode == dojo.keys.ENTER || e.charOrCode == ' '){
+		if(e.charOrCode == keys.ENTER || e.charOrCode == ' '){
 			if(this.toggleable){
 				this.toggle();
 			}
-			dojo.stopEvent(e);
-		}else if(e.charOrCode == dojo.keys.DOWN_ARROW && this.open){
+			event.stop(e);
+		}else if(e.charOrCode == keys.DOWN_ARROW && this.open){
 			this.containerNode.focus();
 			e.preventDefault();
 	 	}
@@ -235,11 +267,9 @@ dojo.declare(
 		//		Deprecated.  Use set('title', ...) instead.
 		// tags:
 		//		deprecated
-		dojo.deprecated("dijit.TitlePane.setTitle() is deprecated.  Use set('title', ...) instead.", "", "2.0");
+		kernel.deprecated("dijit.TitlePane.setTitle() is deprecated.  Use set('title', ...) instead.", "", "2.0");
 		this.set("title", title);
 	}
 });
 
-
-return dijit.TitlePane;
 });
diff --git a/dijit/Toolbar.js b/dijit/Toolbar.js
index fb074f4..df0201d 100644
--- a/dijit/Toolbar.js
+++ b/dijit/Toolbar.js
@@ -1,40 +1,51 @@
-define("dijit/Toolbar", ["dojo", "dijit", "dijit/_Widget", "dijit/_KeyNavContainer", "dijit/_Templated", "dijit/ToolbarSeparator"], function(dojo, dijit) {
-
-// Note: require of ToolbarSeparator is for back-compat, remove for 2.0
-
-dojo.declare("dijit.Toolbar",
-	[dijit._Widget, dijit._Templated, dijit._KeyNavContainer],
-	{
+define([
+	"require",
+	"dojo/_base/declare", // declare
+	"dojo/_base/kernel",
+	"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;
+=====*/
+
+	// module:
+	//		dijit/Toolbar
 	// summary:
 	//		A Toolbar widget, used to hold things like `dijit.Editor` buttons
 
-	templateString:
-		'<div class="dijit" role="toolbar" tabIndex="${tabIndex}" dojoAttachPoint="containerNode">' +
-		//	'<table style="table-layout: fixed" class="dijitReset dijitToolbarTable">' + // factor out style
-		//		'<tr class="dijitReset" dojoAttachPoint="containerNode"></tr>'+
-		//	'</table>' +
-		'</div>',
-
-	baseClass: "dijitToolbar",
 
-	postCreate: function(){
-		this.inherited(arguments);
+	// Back compat w/1.6, remove for 2.0
+	if(!kernel.isAsync){
+		ready(0, function(){
+			var requires = ["dijit/ToolbarSeparator"];
+			require(requires);	// use indirection so modules not rolled into a build
+		});
+	}
 
-		this.connectKeyNavHandlers(
-			this.isLeftToRight() ? [dojo.keys.LEFT_ARROW] : [dojo.keys.RIGHT_ARROW],
-			this.isLeftToRight() ? [dojo.keys.RIGHT_ARROW] : [dojo.keys.LEFT_ARROW]
-		);
-	},
+	return declare("dijit.Toolbar", [_Widget, _TemplatedMixin, _KeyNavContainer], {
+		// summary:
+		//		A Toolbar widget, used to hold things like `dijit.Editor` buttons
 
-	startup: function(){
-		if(this._started){ return; }
+		templateString:
+			'<div class="dijit" role="toolbar" tabIndex="${tabIndex}" data-dojo-attach-point="containerNode">' +
+			'</div>',
 
-		this.startupKeyNavChildren();
+		baseClass: "dijitToolbar",
 
-		this.inherited(arguments);
-	}
-}
-);
+		postCreate: function(){
+			this.inherited(arguments);
 
-return dijit.Toolbar;
+			this.connectKeyNavHandlers(
+				this.isLeftToRight() ? [keys.LEFT_ARROW] : [keys.RIGHT_ARROW],
+				this.isLeftToRight() ? [keys.RIGHT_ARROW] : [keys.LEFT_ARROW]
+			);
+		}
+	});
 });
diff --git a/dijit/ToolbarSeparator.js b/dijit/ToolbarSeparator.js
index 65817ac..33a7ca9 100644
--- a/dijit/ToolbarSeparator.js
+++ b/dijit/ToolbarSeparator.js
@@ -1,15 +1,32 @@
-define("dijit/ToolbarSeparator", ["dojo", "dijit", "dijit/_Widget", "dijit/_Templated"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/dom", // dom.setSelectable
+	"./_Widget",
+	"./_TemplatedMixin"
+], function(declare, dom, _Widget, _TemplatedMixin){
 
-dojo.declare("dijit.ToolbarSeparator",
-		[ dijit._Widget, dijit._Templated ],
-		{
+/*=====
+	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], {
 		// summary:
 		//		A spacer between two `dijit.Toolbar` items
+
 		templateString: '<div class="dijitToolbarSeparator dijitInline" role="presentation"></div>',
+
 		buildRendering: function(){
 			this.inherited(arguments);
-			dojo.setSelectable(this.domNode, false);
+			dom.setSelectable(this.domNode, false);
 		},
+
 		isFocusable: function(){
 			// summary:
 			//		This widget isn't focusable, so pass along that fact.
@@ -17,9 +34,5 @@ dojo.declare("dijit.ToolbarSeparator",
 			//		protected
 			return false;
 		}
-
 	});
-
-
-return dijit.ToolbarSeparator;
 });
diff --git a/dijit/Tooltip.js b/dijit/Tooltip.js
index 04fb493..7029689 100644
--- a/dijit/Tooltip.js
+++ b/dijit/Tooltip.js
@@ -1,9 +1,37 @@
-define("dijit/Tooltip", ["dojo", "dijit", "dijit/_Widget", "dijit/_Templated"], function(dojo, dijit) {
+define([
+	"dojo/_base/array", // array.forEach array.indexOf array.map
+	"dojo/_base/declare", // declare
+	"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-style", // domStyle.set, domStyle.get
+	"dojo/_base/lang", // lang.hitch lang.isArrayLike
+	"dojo/_base/sniff", // has("ie")
+	"dojo/_base/window", // win.body
+	"./_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,
+			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
+
 
-dojo.declare(
-	"dijit._MasterTooltip",
-	[dijit._Widget, dijit._Templated],
-	{
+	var MasterTooltip = declare("dijit._MasterTooltip", [_Widget, _TemplatedMixin], {
 		// summary:
 		//		Internal widget that holds the actual tooltip markup,
 		//		which occurs once per page.
@@ -14,26 +42,38 @@ dojo.declare(
 
 		// duration: Integer
 		//		Milliseconds to fade in/fade out
-		duration: dijit.defaultDuration,
+		duration: manager.defaultDuration,
 
-		templateString: dojo.cache("dijit", "templates/Tooltip.html"),
+		templateString: template,
 
 		postCreate: function(){
-			dojo.body().appendChild(this.domNode);
+			win.body().appendChild(this.domNode);
 
-			this.bgIframe = new dijit.BackgroundIframe(this.domNode);
+			this.bgIframe = new BackgroundIframe(this.domNode);
 
 			// Setup fade-in and fade-out functions.
-			this.fadeIn = dojo.fadeIn({ node: this.domNode, duration: this.duration, onEnd: dojo.hitch(this, "_onShow") });
-			this.fadeOut = dojo.fadeOut({ node: this.domNode, duration: this.duration, onEnd: dojo.hitch(this, "_onHide") });
+			this.fadeIn = fx.fadeIn({ node: this.domNode, duration: this.duration, onEnd: lang.hitch(this, "_onShow") });
+			this.fadeOut = fx.fadeOut({ node: this.domNode, duration: this.duration, onEnd: lang.hitch(this, "_onHide") });
 		},
 
-		show: function(/*String*/ innerHTML, /*DomNode*/ aroundNode, /*String[]?*/ position, /*Boolean*/ rtl){
+		show: function(innerHTML, aroundNode, position, rtl, textDir){
 			// summary:
 			//		Display tooltip w/specified contents to right of specified node
 			//		(To left if there's no space on the right, or if rtl == true)
-
-			if(this.aroundNode && this.aroundNode === aroundNode){
+			// innerHTML: String
+			//		Contents of the tooltip
+			// aroundNode: DomNode || dijit.__Rectangle
+			//		Specifies that tooltip should be next to this node / area
+			// position: String[]?
+			//		List of positions to try to position tooltip (ex: ["right", "above"])
+			// rtl: Boolean?
+			//		Corresponds to `WidgetBase.dir` attribute, where false means "ltr" and true
+			//		means "rtl"; specifies GUI direction, not text direction.
+			// textDir: String?
+			//		Corresponds to `WidgetBase.textdir` attribute; specifies direction of text.
+
+
+			if(this.aroundNode && this.aroundNode === aroundNode && this.containerNode.innerHTML == innerHTML){
 				return;
 			}
 
@@ -46,11 +86,25 @@ dojo.declare(
 				return;
 			}
 			this.containerNode.innerHTML=innerHTML;
-
-			var pos = dijit.placeOnScreenAroundElement(this.domNode, aroundNode, dijit.getPopupAroundAlignment((position && position.length) ? position : dijit.Tooltip.defaultPosition, !rtl), dojo.hitch(this, "orient"));
+			
+			this.set("textDir", textDir);
+			this.containerNode.align = rtl? "right" : "left"; //fix the text alignment
+
+			var pos = place.around(this.domNode, aroundNode,
+				position && position.length ? position : Tooltip.defaultPosition, !rtl, lang.hitch(this, "orient"));
+
+			// 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";
+			}
 
 			// show it
-			dojo.style(this.domNode, "opacity", 0);
+			domStyle.set(this.domNode, "opacity", 0);
 			this.fadeIn.play();
 			this.isShowingNow = true;
 			this.aroundNode = aroundNode;
@@ -64,12 +118,16 @@ dojo.declare(
 			// 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;
 
 			node.className = "dijitTooltip " +
 				{
+					"MR-ML": "dijitTooltipRight",
+					"ML-MR": "dijitTooltipLeft",
+					"TM-BM": "dijitTooltipAbove",
+					"BM-TM": "dijitTooltipBelow",
 					"BL-TL": "dijitTooltipBelow dijitTooltipABLeft",
 					"TL-BL": "dijitTooltipAbove dijitTooltipABLeft",
 					"BR-TR": "dijitTooltipBelow dijitTooltipABRight",
@@ -77,34 +135,34 @@ dojo.declare(
 					"BR-BL": "dijitTooltipRight",
 					"BL-BR": "dijitTooltipLeft"
 				}[aroundCorner + "-" + tooltipCorner];
-				
+
 			// reduce tooltip's width to the amount of width available, so that it doesn't overflow screen
 			this.domNode.style.width = "auto";
-			var size = dojo.contentBox(this.domNode);
-			
+			var size = domGeometry.getContentBox(this.domNode);
+
 			var width = Math.min((Math.max(tooltipSpaceAvaliableWidth,1)), size.w);
 			var widthWasReduced = width < size.w;
-			
+
 			this.domNode.style.width = width+"px";
-						
+
 			//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 + dojo.style(this.domNode,"paddingLeft") + dojo.style(this.domNode,"paddingRight");
+					scrollWidth = scrollWidth + domStyle.get(this.domNode,"paddingLeft") + domStyle.get(this.domNode,"paddingRight");
 					this.domNode.style.width = scrollWidth + "px";
 				}
 			}
-			
+
 			// Reposition the tooltip connector.
 			if(tooltipCorner.charAt(0) == 'B' && aroundCorner.charAt(0) == 'B'){
-				var mb = dojo.marginBox(node);
+				var mb = domGeometry.getMarginBox(node);
 				var tooltipConnectorHeight = this.connectorNode.offsetHeight;
 				if(mb.h > spaceAvailable.h){
 					// The tooltip starts at the top of the page and will extend past the aroundNode
-					var aroundNodePlacement = spaceAvailable.h - (aroundNodeCoords.h / 2) - (tooltipConnectorHeight / 2);
+					var aroundNodePlacement = spaceAvailable.h - ((aroundNodeCoords.h + tooltipConnectorHeight) >> 1);
 					this.connectorNode.style.top = aroundNodePlacement + "px";
 					this.connectorNode.style.bottom = "";
 				}else{
@@ -121,7 +179,7 @@ dojo.declare(
 				this.connectorNode.style.top = "";
 				this.connectorNode.style.bottom = "";
 			}
-			
+
 			return Math.max(0, size.w - tooltipSpaceAvaliableWidth);
 		},
 
@@ -130,7 +188,7 @@ dojo.declare(
 			//		Called at end of fade-in operation
 			// tags:
 			//		protected
-			if(dojo.isIE){
+			if(has("ie")){
 				// the arrow won't show up on a node w/an opacity filter
 				this.domNode.style.filter="";
 			}
@@ -168,31 +226,63 @@ dojo.declare(
 				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;
+    	    }  		             		        
+        }
+	});
+
+	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.
+		// innerHTML: String
+		//		Contents of the tooltip
+		// aroundNode: dijit.__Rectangle
+		//		Specifies that tooltip should be next to this node / area
+		// position: String[]?
+		//		List of positions to try to position tooltip (ex: ["right", "above"])
+		// rtl: Boolean?
+		//		Corresponds to `WidgetBase.dir` attribute, where false means "ltr" and true
+		//		means "rtl"; specifies GUI direction, not text direction.
+		// textDir: String?
+		//		Corresponds to `WidgetBase.textdir` attribute; specifies direction of text.
+		if(!Tooltip._masterTT){ dijit._masterTT = Tooltip._masterTT = new MasterTooltip(); }
+		return Tooltip._masterTT.show(innerHTML, aroundNode, position, rtl, textDir);
+	};
+
+	dijit.hideTooltip = function(aroundNode){
+		// summary:
+		//		Static method to hide the tooltip displayed via showTooltip()
+		return Tooltip._masterTT && Tooltip._masterTT.hide(aroundNode);
+	};
 
-dijit.showTooltip = function(/*String*/ innerHTML, /*DomNode*/ aroundNode, /*String[]?*/ position, /*Boolean*/ rtl){
-	// summary:
-	//		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.
-	if(!dijit._masterTT){ dijit._masterTT = new dijit._MasterTooltip(); }
-	return dijit._masterTT.show(innerHTML, aroundNode, position, rtl);
-};
-
-dijit.hideTooltip = function(aroundNode){
-	// summary:
-	//		Hide the tooltip
-	if(!dijit._masterTT){ dijit._masterTT = new dijit._MasterTooltip(); }
-	return dijit._masterTT.hide(aroundNode);
-};
-
-dojo.declare(
-	"dijit.Tooltip",
-	dijit._Widget,
-	{
+	var Tooltip = declare("dijit.Tooltip", _Widget, {
 		// summary:
 		//		Pops up a tooltip (a help message) when you hover over a node.
 
@@ -215,30 +305,31 @@ dojo.declare(
 		//		See description of `dijit.Tooltip.defaultPosition` for details on position parameter.
 		position: [],
 
-		_setConnectIdAttr: function(/*String*/ newId){
+		_setConnectIdAttr: function(/*String|String[]*/ newId){
 			// summary:
-			//		Connect to node(s) (specified by id)
+			//		Connect to specified node(s)
 
 			// Remove connections to old nodes (if there are any)
-			dojo.forEach(this._connections || [], function(nested){
-				dojo.forEach(nested, dojo.hitch(this, "disconnect"));
+			array.forEach(this._connections || [], function(nested){
+				array.forEach(nested, lang.hitch(this, "disconnect"));
 			}, this);
 
-			// Make connections to nodes in newIds.
-			var ary = dojo.isArrayLike(newId) ? newId : (newId ? [newId] : []);
-			this._connections = dojo.map(ary, function(id){
-				var node = dojo.byId(id);
-				return node ? [
-					this.connect(node, "onmouseenter", "_onTargetMouseEnter"),
-					this.connect(node, "onmouseleave", "_onTargetMouseLeave"),
-					this.connect(node, "onfocus", "_onTargetFocus"),
-					this.connect(node, "onblur", "_onTargetBlur")
-				] : [];
+			// 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); });
+
+			// Make connections
+			this._connections = array.map(this._connectIds, function(id){
+				var node = dom.byId(id);
+				return [
+					this.connect(node, "onmouseenter", "_onHover"),
+					this.connect(node, "onmouseleave", "_onUnHover"),
+					this.connect(node, "onfocus", "_onHover"),
+					this.connect(node, "onblur", "_onUnHover")
+				];
 			}, this);
-	
-			this._set("connectId", newId);
 
-			this._connectIds = ary;	// save as array
+			this._set("connectId", newId);
 		},
 
 		addTarget: function(/*DOMNODE || String*/ node){
@@ -248,19 +339,19 @@ dojo.declare(
 			// TODO: remove in 2.0 and just use set("connectId", ...) interface
 
 			var id = node.id || node;
-			if(dojo.indexOf(this._connectIds, id) == -1){
+			if(array.indexOf(this._connectIds, id) == -1){
 				this.set("connectId", this._connectIds.concat(id));
 			}
 		},
 
-		removeTarget: function(/*DOMNODE || String*/ node){
+		removeTarget: function(/*DomNode || String*/ node){
 			// summary:
 			//		Detach tooltip from specified node
 
 			// TODO: remove in 2.0 and just use set("connectId", ...) interface
-			
+
 			var id = node.id || node,	// map from DOMNode back to plain id string
-				idx = dojo.indexOf(this._connectIds, id);
+				idx = array.indexOf(this._connectIds, id);
 			if(idx >= 0){
 				// remove id (modifies original this._connectIds but that's OK in this case)
 				this._connectIds.splice(idx, 1);
@@ -270,7 +361,7 @@ dojo.declare(
 
 		buildRendering: function(){
 			this.inherited(arguments);
-			dojo.addClass(this.domNode,"dijitTooltipData");
+			domClass.add(this.domNode,"dijitTooltipData");
 		},
 
 		startup: function(){
@@ -279,43 +370,7 @@ dojo.declare(
 			// If this tooltip was created in a template, or for some other reason the specified connectId[s]
 			// didn't exist during the widget's initialization, then connect now.
 			var ids = this.connectId;
-			dojo.forEach(dojo.isArrayLike(ids) ? ids : [ids], this.addTarget, this);
-		},
-
-		_onTargetMouseEnter: function(/*Event*/ e){
-			// summary:
-			//		Handler for mouseenter event on the target node
-			// tags:
-			//		private
-			this._onHover(e);
-		},
-
-		_onTargetMouseLeave: function(/*Event*/ e){
-			// summary:
-			//		Handler for mouseleave event on the target node
-			// tags:
-			//		private
-			this._onUnHover(e);
-		},
-
-		_onTargetFocus: function(/*Event*/ e){
-			// summary:
-			//		Handler for focus event on the target node
-			// tags:
-			//		private
-
-			this._focus = true;
-			this._onHover(e);
-		},
-
-		_onTargetBlur: function(/*Event*/ e){
-			// summary:
-			//		Handler for blur event on the target node
-			// tags:
-			//		private
-
-			this._focus = false;
-			this._onUnHover(e);
+			array.forEach(lang.isArrayLike(ids) ? ids : [ids], this.addTarget, this);
 		},
 
 		_onHover: function(/*Event*/ e){
@@ -326,11 +381,11 @@ dojo.declare(
 			//		private
 			if(!this._showTimer){
 				var target = e.target;
-				this._showTimer = setTimeout(dojo.hitch(this, function(){this.open(target)}), this.showDelay);
+				this._showTimer = setTimeout(lang.hitch(this, function(){this.open(target)}), this.showDelay);
 			}
 		},
 
-		_onUnHover: function(/*Event*/ e){
+		_onUnHover: function(/*Event*/ /*===== e =====*/){
 			// summary:
 			//		Despite the name of this method, it actually handles both mouseleave and blur
 			//		events on the target node, hiding the tooltip.
@@ -358,7 +413,7 @@ dojo.declare(
 				clearTimeout(this._showTimer);
 				delete this._showTimer;
 			}
-			dijit.showTooltip(this.label || this.domNode.innerHTML, target, this.position, !this.isLeftToRight());
+			Tooltip.show(this.label || this.domNode.innerHTML, target, this.position, !this.isLeftToRight(), this.textDir);
 
 			this._connectNode = target;
 			this.onShow(target, this.position);
@@ -372,7 +427,7 @@ dojo.declare(
 
 			if(this._connectNode){
 				// if tooltip is currently shown
-				dijit.hideTooltip(this._connectNode);
+				Tooltip.hide(this._connectNode);
 				delete this._connectNode;
 				this.onHide();
 			}
@@ -383,7 +438,7 @@ dojo.declare(
 			}
 		},
 
-		onShow: function(target, position){
+		onShow: function(/*===== target, position =====*/){
 			// summary:
 			//		Called when the tooltip is shown
 			// tags:
@@ -401,30 +456,34 @@ dojo.declare(
 			this.close();
 			this.inherited(arguments);
 		}
-	}
-);
-
-// 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 following values:
-//
-//			* before: places tooltip to the left of the target node/widget, or to the right in
-//			  the case of RTL scripts like Hebrew and Arabic
-//			* after: places tooltip to the right of the target node/widget, or to the left in
-//			  the case of RTL scripts like Hebrew and Arabic
-//			* above: tooltip goes above target node
-//			* below: tooltip goes below target 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" 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.
-dijit.Tooltip.defaultPosition = ["after", "before"];
-
-
-return dijit.Tooltip;
+	});
+
+	Tooltip._MasterTooltip = MasterTooltip;		// for monkey patching
+	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"];
+
+
+	return Tooltip;
 });
diff --git a/dijit/TooltipDialog.js b/dijit/TooltipDialog.js
index 7ca8e28..78b58d2 100644
--- a/dijit/TooltipDialog.js
+++ b/dijit/TooltipDialog.js
@@ -1,134 +1,154 @@
-define("dijit/TooltipDialog", ["dojo", "dijit", "text!dijit/templates/TooltipDialog.html", "dijit/layout/ContentPane", "dijit/_Templated", "dijit/form/_FormMixin", "dijit/_DialogMixin"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/dom-class", // domClass.replace
+	"dojo/_base/event", // event.stop
+	"dojo/keys", // keys
+	"dojo/_base/lang", // lang.hitch
+	"./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;
+=====*/
+
+	// module:
+	//		dijit/TooltipDialog
+	// summary:
+	//		Pops up a dialog that appears like a Tooltip
+
+
+	return 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
+		},
 
-dojo.declare(
-		"dijit.TooltipDialog",
-		[dijit.layout.ContentPane, dijit._Templated, dijit.form._FormMixin, dijit._DialogMixin],
-		{
+		onClose: function(){
 			// 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: dojo.cache("dijit", "templates/TooltipDialog.html"),
-
-			_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");
-				
-				dojo.replaceClass(this.domNode, newC, this._currentOrientClass || "");
-				this._currentOrientClass = newC;
-			},
-
-			focus: function(){
-				// summary:
-				//		Focus on first field
+			//		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){
 				this._getFocusItems(this.containerNode);
-				dijit.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;
-				var dk = dojo.keys;
-				if(evt.charOrCode === dk.TAB){
-					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
 				}
-				var singleFocusItem = (this._firstFocusItem == this._lastFocusItem);
-				if(evt.charOrCode == dk.ESCAPE){
-					// Use setTimeout to avoid crash on IE, see #10396.
-					setTimeout(dojo.hitch(this, "onCancel"), 0);
-					dojo.stopEvent(evt);
-				}else if(node == this._firstFocusItem && evt.shiftKey && evt.charOrCode === dk.TAB){
-					if(!singleFocusItem){
-						dijit.focus(this._lastFocusItem); // send focus to last item in dialog
-					}
-					dojo.stopEvent(evt);
-				}else if(node == this._lastFocusItem && evt.charOrCode === dk.TAB && !evt.shiftKey){
-					if(!singleFocusItem){
-						dijit.focus(this._firstFocusItem); // send focus to first item in dialog
-					}
-					dojo.stopEvent(evt);
-				}else if(evt.charOrCode === dk.TAB){
-					// 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
 				}
+				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 dijit.TooltipDialog;
+	});
 });
diff --git a/dijit/Tree.js b/dijit/Tree.js
index 2dc6486..faf398d 100644
--- a/dijit/Tree.js
+++ b/dijit/Tree.js
@@ -1,8 +1,55 @@
-define("dijit/Tree", ["dojo", "dijit", "text!dijit/templates/TreeNode.html", "text!dijit/templates/Tree.html", "dojo/fx", "dojo/DeferredList", "dijit/_Widget", "dijit/_Templated", "dijit/_Container", "dijit/_Contained", "dijit/_CssStateMixin", "dojo/cookie", "dijit/tree/TreeStoreModel", "dijit/tree/ForestStoreModel", "dijit/tree/_dndSelector"], function(dojo, dijit) {
+define([
+	"dojo/_base/array", // array.filter array.forEach array.map
+	"dojo/_base/connect",	// connect.isCopyKey()
+	"dojo/cookie", // cookie
+	"dojo/_base/declare", // declare
+	"dojo/_base/Deferred", // Deferred
+	"dojo/DeferredList", // DeferredList
+	"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/fx", // fxUtils.wipeIn fxUtils.wipeOut
+	"dojo/_base/kernel", // kernel.deprecated
+	"dojo/keys",	// arrows etc.
+	"dojo/_base/lang", // lang.getObject lang.mixin lang.hitch
+	"dojo/topic",
+	"./focus",
+	"./registry",	// registry.getEnclosingWidget(), manager.defaultDuration
+	"./_base/manager",	// manager.getEnclosingWidget(), manager.defaultDuration
+	"./_Widget",
+	"./_TemplatedMixin",
+	"./_Container",
+	"./_Contained",
+	"./_CssStateMixin",
+	"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,
+			treeNodeTemplate, treeTemplate, TreeStoreModel, ForestStoreModel, _dndSelector){
 
-dojo.declare(
+/*=====
+	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",
-	[dijit._Widget, dijit._Templated, dijit._Container, dijit._Contained, dijit._CssStateMixin],
+	[_Widget, _TemplatedMixin, _Container, _Contained, _CssStateMixin],
 {
 	// summary:
 	//		Single node within a tree.   This class is used internally
@@ -10,7 +57,7 @@ dojo.declare(
 	// tags:
 	//		private
 
-	// item: [const] dojo.data.Item
+	// item: [const] Item
 	//		the dojo.data entry this tree represents
 	item: null,
 
@@ -22,6 +69,7 @@ dojo.declare(
 	// 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)
@@ -37,7 +85,7 @@ dojo.declare(
 	//		then after dojo.data query it becomes "LOADING" and, finally "LOADED"
 	state: "UNCHECKED",
 
-	templateString: dojo.cache("dijit", "templates/TreeNode.html"),
+	templateString: treeNodeTemplate,
 
 	baseClass: "dijitTreeNode",
 
@@ -47,10 +95,8 @@ dojo.declare(
 		labelNode: "dijitTreeLabel"
 	},
 
-	attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
-		label: {node: "labelNode", type: "innerText"},
-		tooltip: {node: "rowNode", type: "attribute", attribute: "title"}
-	}),
+	// 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);
@@ -62,7 +108,7 @@ dojo.declare(
 		this._updateItemClasses(this.item);
 
 		if(this.isExpandable){
-			dijit.setWaiState(this.labelNode, "expanded", this.isExpanded);
+			this.labelNode.setAttribute("aria-expanded", this.isExpanded);
 		}
 
 		//aria-selected should be false on all selectable elements.
@@ -79,13 +125,13 @@ dojo.declare(
 		// Math.max() is to prevent negative padding on hidden root node (when indent == -1)
 		var pixels = (Math.max(indent, 0) * this.tree._nodePixelIndent) + "px";
 
-		dojo.style(this.domNode, "backgroundPosition",	pixels + " 0px");
-		dojo.style(this.rowNode, this.isLeftToRight() ? "paddingLeft" : "paddingRight", pixels);
+		domStyle.set(this.domNode, "backgroundPosition",	pixels + " 0px");
+		domStyle.set(this.rowNode, this.isLeftToRight() ? "paddingLeft" : "paddingRight", pixels);
 
-		dojo.forEach(this.getChildren(), function(child){
+		array.forEach(this.getChildren(), function(child){
 			child.set("indent", indent+1);
 		});
-		
+
 		this._set("indent", indent);
 	},
 
@@ -143,9 +189,9 @@ dojo.declare(
 		var oldCls = this[clsName];
 
 		this[clsName] = this.tree["get" + upper + "Class"](item, this.isExpanded);
-		dojo.replaceClass(this[nodeName], this[clsName] || "", oldCls || "");
- 
-		dojo.style(this[nodeName], this.tree["get" + upper + "Style"](item, this.isExpanded) || {});
+		domClass.replace(this[nodeName], this[clsName] || "", oldCls || "");
+
+		domStyle.set(this[nodeName], this.tree["get" + upper + "Style"](item, this.isExpanded) || {});
  	},
 
 	_updateLayout: function(){
@@ -154,11 +200,11 @@ dojo.declare(
 		// tags:
 		//		private
 		var parent = this.getParent();
-		if(!parent || parent.rowNode.style.display == "none"){
+		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 */
-			dojo.addClass(this.domNode, "dijitTreeIsRoot");
+			domClass.add(this.domNode, "dijitTreeIsRoot");
 		}else{
-			dojo.toggleClass(this.domNode, "dijitTreeIsLast", !this.getNextSibling());
+			domClass.toggle(this.domNode, "dijitTreeIsLast", !this.getNextSibling());
 		}
 	},
 
@@ -174,7 +220,7 @@ dojo.declare(
 			idx = processing ? 0 : (this.isExpandable ?	(this.isExpanded ? 1 : 2) : 3);
 
 		// apply the appropriate class to the expando node
-		dojo.replaceClass(this.expandoNode, styles[idx], styles);
+		domClass.replace(this.expandoNode, styles[idx], styles);
 
 		// provide a non-image based indicator for images-off mode
 		this.expandoNodeText.innerHTML = _a11yStates[idx];
@@ -198,27 +244,27 @@ dojo.declare(
 		// All the state information for when a node is expanded, maybe this should be
 		// set when the animation completes instead
 		this.isExpanded = true;
-		dijit.setWaiState(this.labelNode, "expanded", "true");
+		this.labelNode.setAttribute("aria-expanded", "true");
 		if(this.tree.showRoot || this !== this.tree.rootNode){
-			dijit.setWaiRole(this.containerNode, "group");
+			this.containerNode.setAttribute("role", "group");
 		}
-		dojo.addClass(this.contentNode,'dijitTreeContentExpanded');
+		domClass.add(this.contentNode,'dijitTreeContentExpanded');
 		this._setExpando();
 		this._updateItemClasses(this.item);
 		if(this == this.tree.rootNode){
-			dijit.setWaiState(this.tree.domNode, "expanded", "true");
+			this.tree.domNode.setAttribute("aria-expanded", "true");
 		}
 
 		var def,
-			wipeIn = dojo.fx.wipeIn({
-				node: this.containerNode, duration: dijit.defaultDuration,
+			wipeIn = fxUtils.wipeIn({
+				node: this.containerNode, duration: manager.defaultDuration,
 				onEnd: function(){
 					def.callback(true);
 				}
 			});
 
 		// Deferred that fires when expand is complete
-		def = (this._expandDeferred = new dojo.Deferred(function(){
+		def = (this._expandDeferred = new Deferred(function(){
 			// Canceller
 			wipeIn.stop();
 		}));
@@ -241,17 +287,17 @@ dojo.declare(
 		}
 
 		this.isExpanded = false;
-		dijit.setWaiState(this.labelNode, "expanded", "false");
+		this.labelNode.setAttribute("aria-expanded", "false");
 		if(this == this.tree.rootNode){
-			dijit.setWaiState(this.tree.domNode, "expanded", "false");
+			this.tree.domNode.setAttribute("aria-expanded", "false");
 		}
-		dojo.removeClass(this.contentNode,'dijitTreeContentExpanded');
+		domClass.remove(this.contentNode,'dijitTreeContentExpanded');
 		this._setExpando();
 		this._updateItemClasses(this.item);
 
 		if(!this._wipeOut){
-			this._wipeOut = dojo.fx.wipeOut({
-				node: this.containerNode, duration: dijit.defaultDuration
+			this._wipeOut = fxUtils.wipeOut({
+				node: this.containerNode, duration: manager.defaultDuration
 			});
 		}
 		this._wipeOut.play();
@@ -279,8 +325,8 @@ dojo.declare(
 		// 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.
-		dojo.forEach(this.getChildren(), function(child){
-			dijit._Container.prototype.removeChild.call(this, child);
+		array.forEach(this.getChildren(), function(child){
+			_Container.prototype.removeChild.call(this, child);
 		}, this);
 
 		this.state = "LOADED";
@@ -291,7 +337,7 @@ dojo.declare(
 			// 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
-			dojo.forEach(items, function(item){
+			array.forEach(items, function(item){
 				var id = model.getIdentity(item),
 					existingNodes = tree._itemNodesMap[id],
 					node;
@@ -313,6 +359,7 @@ dojo.declare(
 							tooltip: tree.getTooltip(item),
 							dir: tree.dir,
 							lang: tree.lang,
+							textDir: tree.textDir,
 							indent: this.indent + 1
 						});
 					if(existingNodes){
@@ -325,14 +372,14 @@ dojo.declare(
 
 				// 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(item)){
+				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
-			dojo.forEach(this.getChildren(), function(child, idx){
+			array.forEach(this.getChildren(), function(child){
 				child._updateLayout();
 			});
 		}else{
@@ -360,7 +407,7 @@ dojo.declare(
 			}
 		}
 
-		return new dojo.DeferredList(defs);	// dojo.Deferred
+		return new DeferredList(defs);	// dojo.Deferred
 	},
 
 	getTreePath: function(){
@@ -375,7 +422,7 @@ dojo.declare(
 		return path;
 	},
 
-	getIdentity: function() {
+	getIdentity: function(){
 		return this.tree.model.getIdentity(this.item);
 	},
 
@@ -388,7 +435,7 @@ dojo.declare(
 			this.collapse();
 		}
 
-		dojo.forEach(children, function(child){
+		array.forEach(children, function(child){
 				child._updateLayout();
 		});
 	},
@@ -404,7 +451,7 @@ dojo.declare(
 		this._setExpando(false);
 	},
 
-	_onLabelFocus: function(evt){
+	_onLabelFocus: function(){
 		// summary:
 		//		Called when this row is focused (possibly programatically)
 		//		Note that we aren't using _onFocus() builtin to dijit
@@ -421,8 +468,8 @@ dojo.declare(
 		// 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).
-		dijit.setWaiState(this.labelNode, "selected", selected);
-		dojo.toggleClass(this.rowNode, "dijitTreeRowSelected", selected);
+		this.labelNode.setAttribute("aria-selected", selected);
+		domClass.toggle(this.rowNode, "dijitTreeRowSelected", selected);
 	},
 
 	setFocusable: function(/*Boolean*/ selected){
@@ -465,13 +512,20 @@ dojo.declare(
 		// 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);
+		}
 	}
 });
 
-dojo.declare(
-	"dijit.Tree",
-	[dijit._Widget, dijit._Templated],
-{
+var Tree = declare("dijit.Tree", [_Widget, _TemplatedMixin], {
 	// summary:
 	//		This widget displays hierarchical data from a store.
 
@@ -511,7 +565,7 @@ dojo.declare(
 	//		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: [],
@@ -535,7 +589,7 @@ dojo.declare(
 	//		If true, double-clicking a folder node's label will open it, rather than calling onDblClick()
 	openOnDblClick: false,
 
-	templateString: dojo.cache("dijit", "templates/Tree.html"),
+	templateString: treeTemplate,
 
 	// persist: Boolean
 	//		Enables/disables use of cookies for state saving.
@@ -545,11 +599,11 @@ dojo.declare(
 	//		Fully expand the tree on load.   Overrides `persist`.
 	autoExpand: false,
 
-	// dndController: [protected] String
-	//		Class name to use as as the dnd controller.  Specifying this class enables DnD.
-	//		Generally you should specify this as "dijit.tree.dndSource".
-	//      Default of "dijit.tree._dndSelector" handles selection only (no actual DnD).
-	dndController: "dijit.tree._dndSelector",
+	// 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"],
@@ -658,7 +712,7 @@ dojo.declare(
 	_publish: function(/*String*/ topicName, /*Object*/ message){
 		// summary:
 		//		Publish a message for this widget/topic
-		dojo.publish(this.id, [dojo.mixin({tree: this, event: topicName}, message || {})]);
+		topic.publish(this.id, lang.mixin({tree: this, event: topicName}, message || {}));	// publish
 	},
 
 	postMixInProperties: function(){
@@ -672,11 +726,11 @@ dojo.declare(
 
 		this._itemNodesMap={};
 
-		if(!this.cookieName){
+		if(!this.cookieName && this.id){
 			this.cookieName = this.id + "SaveStateCookie";
 		}
 
-		this._loadDeferred = new dojo.Deferred();
+		this._loadDeferred = new Deferred();
 
 		this.inherited(arguments);
 	},
@@ -699,8 +753,8 @@ dojo.declare(
 		this.inherited(arguments);
 
 		if(this.dndController){
-			if(dojo.isString(this.dndController)){
-				this.dndController = dojo.getObject(this.dndController);
+			if(lang.isString(this.dndController)){
+				this.dndController = lang.getObject(this.dndController);
 			}
 			var params={};
 			for(var i=0; i<this.dndParams.length;i++){
@@ -716,7 +770,7 @@ dojo.declare(
 		// summary:
 		//		User specified a store&query rather than model, so create model from store/query
 		this._v10Compat = true;
-		dojo.deprecated("Tree: from version 2.0, should specify a model object rather than a store/query");
+		kernel.deprecated("Tree: from version 2.0, should specify a model object rather than a store/query");
 
 		var modelParams = {
 			id: this.id + "_ForestStoreModel",
@@ -727,15 +781,15 @@ dojo.declare(
 
 		// Only override the model's mayHaveChildren() method if the user has specified an override
 		if(this.params.mayHaveChildren){
-			modelParams.mayHaveChildren = dojo.hitch(this, "mayHaveChildren");
+			modelParams.mayHaveChildren = lang.hitch(this, "mayHaveChildren");
 		}
 
 		if(this.params.getItemChildren){
-			modelParams.getChildren = dojo.hitch(this, function(item, onComplete, onError){
+			modelParams.getChildren = lang.hitch(this, function(item, onComplete, onError){
 				this.getItemChildren((this._v10Compat && item === this.model.root) ? null : item, onComplete, onError);
 			});
 		}
-		this.model = new dijit.tree.ForestStoreModel(modelParams);
+		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
@@ -757,22 +811,23 @@ dojo.declare(
 		//		Initial load of the tree.
 		//		Load root node (possibly hidden) and it's children.
 		this.model.getRoot(
-			dojo.hitch(this, function(item){
+			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
-					dijit.setWaiRole(this.domNode, 'presentation');
-					
-					dijit.setWaiRole(rn.labelNode, 'presentation');
-					dijit.setWaiRole(rn.containerNode, 'tree');
+					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);
@@ -785,7 +840,7 @@ dojo.declare(
 				rn._updateLayout();		// sets "dijitTreeIsRoot" CSS classname
 
 				// load top level children and then fire onLoad() event
-				this._expandNode(rn).addCallback(dojo.hitch(this, function(){
+				this._expandNode(rn).addCallback(lang.hitch(this, function(){
 					this._loadDeferred.callback(true);
 					this.onLoad();
 				}));
@@ -796,34 +851,34 @@ dojo.declare(
 		);
 	},
 
-	getNodesByItem: function(/*dojo.data.Item or id*/ item){
+	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 = dojo.isString(item) ? item : this.model.getIdentity(item);
+		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(/*dojo.data.Item or id*/ item){
+	_setSelectedItemAttr: function(/*Item or id*/ item){
 		this.set('selectedItems', [item]);
 	},
 
-	_setSelectedItemsAttr: function(/*dojo.data.Items or ids*/ items){
+	_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( dojo.hitch(this, function(){
-			var identities = dojo.map(items, function(item){
-				return (!item || dojo.isString(item)) ? item : tree.model.getIdentity(item);
+		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 = [];
-			dojo.forEach(identities, function(id){
+			array.forEach(identities, function(id){
 				nodes = nodes.concat(tree._itemNodesMap[id] || []);
 			});
 			this.set('selectedNodes', nodes);
@@ -833,14 +888,14 @@ dojo.declare(
 	_setPathAttr: function(/*Item[] || String[]*/ path){
 		// summary:
 		//      Singular variant of _setPathsAttr
-		if(path.length) {
+		if(path.length){
 			return this.set("paths", [path]);
-		} else {
-			//Empty list is interpreted as "select nothing"
+		}else{
+			// Empty list is interpreted as "select nothing"
 			return this.set("paths", []);
 		}
 	},
-	
+
 	_setPathsAttr: function(/*Item[][] || String[][]*/ paths){
 		// summary:
 		//		Select the tree nodes identified by passed paths.
@@ -853,12 +908,12 @@ dojo.declare(
 		// 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 dojo.DeferredList(dojo.map(paths, function(path){
-			var d = new dojo.Deferred();
-			
+		return new DeferredList(array.map(paths, function(path){
+			var d = new Deferred();
+
 			// normalize path to use identity
-			path = dojo.map(path, function(item){
-				return dojo.isString(item) ? item : tree.model.getIdentity(item);
+			path = array.map(path, function(item){
+				return lang.isString(item) ? item : tree.model.getIdentity(item);
 			});
 
 			if(path.length){
@@ -873,7 +928,7 @@ dojo.declare(
 		function selectPath(path, nodes, def){
 			// Traverse path; the next path component should be among "nodes".
 			var nextPath = path.shift();
-			var nextNode = dojo.filter(nodes, function(node){
+			var nextNode = array.filter(nodes, function(node){
 				return node.getIdentity() == nextPath;
 			})[0];
 			if(!!nextNode){
@@ -883,16 +938,16 @@ dojo.declare(
 					//Successfully reached the end of this path
 					def.callback(nextNode);
 				}
-			} else {
+			}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", dojo.map(
-				dojo.filter(newNodes,function(x){return x[0];}),
+			tree.set("selectedNodes", array.map(
+				array.filter(newNodes,function(x){return x[0];}),
 				function(x){return x[1];}));
 		}
 	},
@@ -901,7 +956,7 @@ dojo.declare(
 		this.set('selectedNodes', [node]);
 	},
 	_setSelectedNodesAttr: function(nodes){
-		this._loadDeferred.addCallback( dojo.hitch(this, function(){
+		this._loadDeferred.addCallback( lang.hitch(this, function(){
 			this.dndController.setSelection(nodes);
 		}));
 	},
@@ -910,7 +965,7 @@ dojo.declare(
 	////////////// Data store related functions //////////////////////
 	// These just get passed to the model; they are here for back-compat
 
-	mayHaveChildren: function(/*dojo.data.Item*/ item){
+	mayHaveChildren: function(/*dojo.data.Item*/ /*===== item =====*/){
 		// summary:
 		//		Deprecated.   This should be specified on the model itself.
 		//
@@ -922,7 +977,7 @@ dojo.declare(
 		//		deprecated
 	},
 
-	getItemChildren: function(/*dojo.data.Item*/ parentItem, /*function(items)*/ onComplete){
+	getItemChildren: function(/*===== parentItem, onComplete =====*/){
 		// summary:
 		//		Deprecated.   This should be specified on the model itself.
 		//
@@ -950,48 +1005,62 @@ dojo.declare(
 		return (!item || this.model.mayHaveChildren(item)) ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "dijitLeaf"
 	},
 
-	getLabelClass: function(/*dojo.data.Item*/ item, /*Boolean*/ opened){
+	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(/*dojo.data.Item*/ item, /*Boolean*/ opened){
+	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(/*dojo.data.Item*/ item, /*Boolean*/ opened){
+	getIconStyle: function(/*===== item, opened =====*/){
 		// summary:
 		//		Overridable function to return CSS styles to display icon
-		// returns:
+		// item: dojo.data.Item
+		// opened: Boolean
+		// returns: Object
 		//		Object suitable for input to dojo.style() like {backgroundImage: "url(...)"}
 		// tags:
 		//		extension
 	},
 
-	getLabelStyle: function(/*dojo.data.Item*/ item, /*Boolean*/ opened){
+	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(/*dojo.data.Item*/ item, /*Boolean*/ opened){
+	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){
+	getTooltip: function(/*dojo.data.Item*/ /*===== item =====*/){
 		// summary:
 		//		Overridable function to get the tooltip for a tree node (given the item)
 		// tags:
@@ -1005,8 +1074,7 @@ dojo.declare(
 		// summary:
 		//		Translates keypress events into commands for the controller
 		if(e.altKey){ return; }
-		var dk = dojo.keys;
-		var treeNode = dijit.getEnclosingWidget(e.target);
+		var treeNode = registry.getEnclosingWidget(e.target);
 		if(!treeNode){ return; }
 
 		var key = e.charOrCode;
@@ -1014,7 +1082,7 @@ dojo.declare(
 			// Check for key navigation.
 			if(!e.altKey && !e.ctrlKey && !e.shiftKey && !e.metaKey){
 				this._onLetterKeyNav( { node: treeNode, key: key.toLowerCase() } );
-				dojo.stopEvent(e);
+				event.stop(e);
 			}
 		}else{	// handle non-printables (arrow keys)
 			// clear record of recent printables (being saved for multi-char letter navigation),
@@ -1028,30 +1096,30 @@ dojo.declare(
 			if(!map){
 				// setup table mapping keys to events
 				map = {};
-				map[dk.ENTER]="_onEnterKey";
+				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[dk.SPACE]= map[" "] = "_onEnterKey";
-				map[this.isLeftToRight() ? dk.LEFT_ARROW : dk.RIGHT_ARROW]="_onLeftArrow";
-				map[this.isLeftToRight() ? dk.RIGHT_ARROW : dk.LEFT_ARROW]="_onRightArrow";
-				map[dk.UP_ARROW]="_onUpArrow";
-				map[dk.DOWN_ARROW]="_onDownArrow";
-				map[dk.HOME]="_onHomeKey";
-				map[dk.END]="_onEndKey";
+				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(this._keyHandlerMap[key]){
 				this[this._keyHandlerMap[key]]( { node: treeNode, item: treeNode.item, evt: e } );
-				dojo.stopEvent(e);
+				event.stop(e);
 			}
 		}
 	},
 
 	_onEnterKey: function(/*Object*/ message){
 		this._publish("execute", { item: message.item, node: message.node } );
-		this.dndController.userSelect(message.node, dojo.isCopyKey( message.evt ), message.evt.shiftKey);
+		this.dndController.userSelect(message.node, connect.isCopyKey( message.evt ), message.evt.shiftKey);
 		this.onClick(message.item, message.node, message.evt);
 	},
 
@@ -1136,7 +1204,7 @@ dojo.declare(
 		}
 	},
 
-	_onEndKey: function(/*Object*/ message){
+	_onEndKey: function(){
 		// summary:
 		//		End key pressed; go to last visible node.
 
@@ -1207,7 +1275,7 @@ dojo.declare(
 	isExpandoNode: function(node, widget){
 		// summary:
 		//		check whether a dom node is the expandoNode for a particular TreeNode widget
-		return dojo.isDescendant(node, widget.expandoNode);
+		return dom.isDescendant(node, widget.expandoNode);
 	},
 	_onClick: function(/*TreeNode*/ nodeWidget, /*Event*/ e){
 		// summary:
@@ -1226,7 +1294,7 @@ dojo.declare(
 			this.onClick(nodeWidget.item, nodeWidget, e);
 			this.focusNode(nodeWidget);
 		}
-		dojo.stopEvent(e);
+		event.stop(e);
 	},
 	_onDblClick: function(/*TreeNode*/ nodeWidget, /*Event*/ e){
 		// summary:
@@ -1245,7 +1313,7 @@ dojo.declare(
 			this.onDblClick(nodeWidget.item, nodeWidget, e);
 			this.focusNode(nodeWidget);
 		}
-		dojo.stopEvent(e);
+		event.stop(e);
 	},
 
 	_onExpandoClick: function(/*Object*/ message){
@@ -1265,27 +1333,37 @@ dojo.declare(
 		}
 	},
 
-	onClick: function(/* dojo.data */ item, /*TreeNode*/ node, /*Event*/ evt){
+	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(/* dojo.data */ item, /*TreeNode*/ node, /*Event*/ evt){
+	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(/* dojo.data */ item, /*TreeNode*/ node){
+	onOpen: function(/*===== item, node =====*/){
 		// summary:
 		//		Callback when a node is opened
+		// item: dojo.data.Item
+		// node: TreeNode
 		// tags:
 		//		callback
 	},
-	onClose: function(/* dojo.data */ item, /*TreeNode*/ node){
+	onClose: function(/*===== item, node =====*/){
 		// summary:
 		//		Callback when a node is closed
+		// item: dojo.data.Item
+		// node: TreeNode
 		// tags:
 		//		callback
 	},
@@ -1333,10 +1411,7 @@ dojo.declare(
 			node.collapse();
 			this.onClose(node.item, node);
 
-			if(node.item){
-				this._state(node.item,false);
-				this._saveState();
-			}
+			this._state(node, false);
 		}
 	},
 
@@ -1365,7 +1440,7 @@ dojo.declare(
 
 				// 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 dojo.Deferred());
+				var def = (node._expandNodeDeferred = new Deferred());
 
 				// Get the children
 				model.getChildren(
@@ -1402,10 +1477,7 @@ dojo.declare(
 
 				this.onOpen(node.item, node);
 
-				if(item){
-					this._state(item, true);
-					this._saveState();
-				}
+				this._state(node, true);
 		}
 
 		return def;	// dojo.Deferred
@@ -1420,7 +1492,7 @@ dojo.declare(
 		//		protected
 
 		// set focus so that the label will be voiced using screen readers
-		dijit.focus(node.labelNode);
+		focus.focus(node.labelNode);
 	},
 
 	_onNodeFocus: function(/*dijit._Widget*/ node){
@@ -1443,13 +1515,13 @@ dojo.declare(
 		}
 	},
 
-	_onNodeMouseEnter: function(/*dijit._Widget*/ 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){
+	_onNodeMouseLeave: function(/*dijit._Widget*/ /*===== node =====*/){
 		// summary:
 		//		Called when mouse leaves a node (onmouseleave event),
 		//		this is monitored by the DND code
@@ -1467,7 +1539,7 @@ dojo.declare(
 		if(nodes){
 			var label = this.getLabel(item),
 				tooltip = this.getTooltip(item);
-			dojo.forEach(nodes, function(node){
+			array.forEach(nodes, function(node){
 				node.set({
 					item: item,		// theoretically could be new JS Object representing same item
 					label: label,
@@ -1486,7 +1558,7 @@ dojo.declare(
 			parentNodes = this._itemNodesMap[identity];
 
 		if(parentNodes){
-			dojo.forEach(parentNodes,function(parentNode){
+			array.forEach(parentNodes,function(parentNode){
 				parentNode.setChildItems(newChildrenList);
 			});
 		}
@@ -1500,7 +1572,7 @@ dojo.declare(
 			nodes = this._itemNodesMap[identity];
 
 		if(nodes){
-			dojo.forEach(nodes,function(node){
+			array.forEach(nodes,function(node){
 				// Remove node from set of selected nodes (if it's selected)
 				this.dndController.removeTreeNode(node);
 
@@ -1520,43 +1592,39 @@ dojo.declare(
 	_initState: function(){
 		// summary:
 		//		Load in which nodes should be opened automatically
-		if(this.persist){
-			var cookie = dojo.cookie(this.cookieName);
-			this._openedItemIds = {};
-			if(cookie){
-				dojo.forEach(cookie.split(','), function(item){
-					this._openedItemIds[item] = true;
+		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(item,expanded){
+	_state: function(node, expanded){
 		// summary:
-		//		Query or set expanded state for an item,
+		//		Query or set expanded state for an node
 		if(!this.persist){
 			return false;
 		}
-		var id=this.model.getIdentity(item);
+		var path = array.map(node.getTreePath(), function(item){
+				return this.model.getIdentity(item);
+			}, this).join("/");
 		if(arguments.length === 1){
-			return this._openedItemIds[id];
-		}
-		if(expanded){
-			this._openedItemIds[id] = true;
+			return this._openedNodes[path];
 		}else{
-			delete this._openedItemIds[id];
-		}
-	},
-	_saveState: function(){
-		// summary:
-		//		Create and save a cookie with the currently expanded nodes identifiers
-		if(!this.persist){
-			return;
-		}
-		var ary = [];
-		for(var id in this._openedItemIds){
-			ary.push(id);
+			if(expanded){
+				this._openedNodes[path] = true;
+			}else{
+				delete this._openedNodes[path];
+			}
+			var ary = [];
+			for(var id in this._openedNodes){
+				ary.push(id);
+			}
+			cookie(this.cookieName, ary.join(","), {expires:365});
 		}
-		dojo.cookie(this.cookieName, ary.join(","), {expires:365});
 	},
 
 	destroy: function(){
@@ -1567,7 +1635,7 @@ dojo.declare(
 		if(this.rootNode){
 			this.rootNode.destroyRecursive();
 		}
-		if(this.dndController && !dojo.isString(this.dndController)){
+		if(this.dndController && !lang.isString(this.dndController)){
 			this.dndController.destroy();
 		}
 		this.rootNode = null;
@@ -1582,13 +1650,13 @@ dojo.declare(
 
 	resize: function(changeSize){
 		if(changeSize){
-			dojo.marginBox(this.domNode, 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 = dojo._getMarginSize(this.tree.indentDetector).w;
+		this._nodePixelIndent = domGeometry.position(this.tree.indentDetector).w;
 
 		if(this.tree.rootNode){
 			// If tree has already loaded, then reset indent for all the nodes
@@ -1604,12 +1672,18 @@ dojo.declare(
 		//		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 dijit._TreeNode(args);
+		return new TreeNode(args);
+	},
+
+	_setTextDirAttr: function(textDir){
+		if(textDir && this.textDir!= textDir){
+			this._set("textDir",textDir);
+			this.rootNode.set("textDir", textDir);
+		}
 	}
 });
 
-// For back-compat.  TODO: remove in 2.0
-
+Tree._TreeNode = TreeNode;	// for monkey patching
 
-return dijit.Tree;
+return Tree;
 });
diff --git a/dijit/WidgetSet.js b/dijit/WidgetSet.js
new file mode 100644
index 0000000..f5a2b6a
--- /dev/null
+++ b/dijit/WidgetSet.js
@@ -0,0 +1,229 @@
+define([
+	"dojo/_base/array", // array.forEach array.map
+	"dojo/_base/declare", // declare
+	"dojo/_base/window", // win.global
+	"./registry"	// to add functions to dijit.registry
+], function(array, declare, win, 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`
+		//
+		// 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 */ });
+
+		constructor: function(){
+			this._hash = {};
+			this.length = 0;
+		},
+
+		add: function(/*dijit._Widget*/ 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.
+			if(this._hash[widget.id]){
+				throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered");
+			}
+			this._hash[widget.id] = widget;
+			this.length++;
+		},
+
+		remove: function(/*String*/ id){
+			// summary:
+			//		Remove a widget from this WidgetSet. Does not destroy the widget; simply
+			//		removes the reference.
+			if(this._hash[id]){
+				delete this._hash[id];
+				this.length--;
+			}
+		},
+
+		forEach: function(/*Function*/ func, /* Object? */thisObj){
+			// summary:
+			//		Call specified function for each widget in this set.
+			//
+			// func:
+			//		A callback function to run for each item. Is passed the widget, the index
+			//		in the iteration, and the full hash, similar to `array.forEach`.
+			//
+			// thisObj:
+			//		An optional scope parameter
+			//
+			// example:
+			//		Using the default `dijit.registry` instance:
+			//		|	dijit.registry.forEach(function(widget){
+			//		|		console.log(widget.declaredClass);
+			//		|	});
+			//
+			// returns:
+			//		Returns self, in order to allow for further chaining.
+
+			thisObj = thisObj || win.global;
+			var i = 0, id;
+			for(id in this._hash){
+				func.call(thisObj, this._hash[id], i++, this._hash);
+			}
+			return this;	// dijit.WidgetSet
+		},
+
+		filter: function(/*Function*/ filter, /* Object? */thisObj){
+			// summary:
+			//		Filter down this WidgetSet to a smaller new WidgetSet
+			//		Works the same as `array.filter` and `NodeList.filter`
+			//
+			// filter:
+			//		Callback function to test truthiness. Is passed the widget
+			//		reference and the pseudo-index in the object.
+			//
+			// thisObj: Object?
+			//		Option scope to use for the filter function.
+			//
+			// example:
+			//		Arbitrary: select the odd widgets in this list
+			//		|	dijit.registry.filter(function(w, i){
+			//		|		return i % 2 == 0;
+			//		|	}).forEach(function(w){ /* odd ones */ });
+
+			thisObj = thisObj || win.global;
+			var res = new WidgetSet(), i = 0, id;
+			for(id in this._hash){
+				var w = this._hash[id];
+				if(filter.call(thisObj, w, i++, this._hash)){
+					res.add(w);
+				}
+			}
+			return res; // dijit.WidgetSet
+		},
+
+		byId: function(/*String*/ id){
+			// summary:
+			//		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
+
+			return this._hash[id];	// dijit._Widget
+		},
+
+		byClass: function(/*String*/ cls){
+			// summary:
+			//		Reduce this widgetset to a new WidgetSet of a particular `declaredClass`
+			//
+			// cls: String
+			//		The Class to scan for. Full dot-notated string.
+			//
+			// example:
+			//		Find all `dijit.TitlePane`s in a page:
+			//		|	dijit.registry.byClass("dijit.TitlePane").forEach(function(tp){ tp.close(); });
+
+			var res = new WidgetSet(), id, widget;
+			for(id in this._hash){
+				widget = this._hash[id];
+				if(widget.declaredClass == cls){
+					res.add(widget);
+				}
+			 }
+			 return res; // dijit.WidgetSet
+		},
+
+		toArray: function(){
+			// summary:
+			//		Convert this WidgetSet into a true Array
+			//
+			// example:
+			//		Work with the widget .domNodes in a real Array
+			//		|	array.map(dijit.registry.toArray(), function(w){ return w.domNode; });
+
+			var ar = [];
+			for(var id in this._hash){
+				ar.push(this._hash[id]);
+			}
+			return ar;	// dijit._Widget[]
+		},
+
+		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; });
+			//
+			// returns:
+			//		A new array of the returned values.
+			return array.map(this.toArray(), func, thisObj); // Array
+		},
+
+		every: function(func, thisObj){
+			// summary:
+			// 		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
+			//		when the first false return is encountered.
+			//
+			// thisObj: Object?
+			//		Optional scope parameter to use for the callback
+
+			thisObj = thisObj || win.global;
+			var x = 0, i;
+			for(i in this._hash){
+				if(!func.call(thisObj, this._hash[i], x++, this._hash)){
+					return false; // Boolean
+				}
+			}
+			return true; // Boolean
+		},
+
+		some: function(func, thisObj){
+			// summary:
+			// 		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
+			//		when the first true return is encountered.
+			//
+			// thisObj: Object?
+			//		Optional scope parameter to use for the callback
+
+			thisObj = thisObj || win.global;
+			var x = 0, i;
+			for(i in this._hash){
+				if(func.call(thisObj, this._hash[i], x++, this._hash)){
+					return true; // Boolean
+				}
+			}
+			return false; // Boolean
+		}
+
+	});
+
+	// 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){
+		registry[func] = WidgetSet.prototype[func];
+	});
+
+
+	return WidgetSet;
+});
diff --git a/dijit/_BidiSupport.js b/dijit/_BidiSupport.js
new file mode 100644
index 0000000..a533f73
--- /dev/null
+++ b/dijit/_BidiSupport.js
@@ -0,0 +1,69 @@
+define(["./_WidgetBase"], function(_WidgetBase){
+
+/*=====
+	var _WidgetBase = dijit._WidgetBase;
+====*/
+
+	// 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";
+		},
+
+		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.
+
+			var textDir = this.textDir == "auto" ? this._checkContextual(text) : this.textDir;
+			// update only when there's a difference
+			if(element.dir != textDir){
+				element.dir = textDir;
+			}
+		}
+	});
+
+	return _WidgetBase;
+});
diff --git a/dijit/_Calendar.js b/dijit/_Calendar.js
index f4454f2..96e52fa 100644
--- a/dijit/_Calendar.js
+++ b/dijit/_Calendar.js
@@ -1,11 +1,17 @@
-define("dijit/_Calendar", ["dojo", "dijit", "dijit/Calendar"], function(dojo, dijit) {
+define([
+	"dojo/_base/kernel", // kernel.deprecated
+	"./Calendar",
+	"."	// for exporting dijit.Calendar
+], function(kernel, Calendar, dijit){
 
-dojo.deprecated("dijit._Calendar is deprecated", "dijit._Calendar moved to dijit.Calendar", 1.5);
+	// module:
+	//		dijit/_Calendar
+	// summary:
+	//		Deprecated widget, used dijit/Calendar instead.   Will be removed in 2.0.
 
-// dijit._Calendar had an underscore all this time merely because it did
-// not satisfy dijit's a11y policy.
-dijit._Calendar = dijit.Calendar;
+	kernel.deprecated("dijit._Calendar is deprecated", "dijit._Calendar moved to dijit.Calendar", 2.0);
 
-
-return dijit._Calendar;
+	// dijit._Calendar had an underscore all this time merely because it did
+	// not satisfy dijit's a11y policy.
+	dijit._Calendar = Calendar;
 });
diff --git a/dijit/_Contained.js b/dijit/_Contained.js
index 25b2417..21c286d 100644
--- a/dijit/_Contained.js
+++ b/dijit/_Contained.js
@@ -1,68 +1,62 @@
-define("dijit/_Contained", ["dojo", "dijit"], function(dojo, dijit) {
-
-dojo.declare("dijit._Contained",
-		null,
-		{
+define([
+	"dojo/_base/declare", // declare
+	"./registry"	// registry.getEnclosingWidget(), registry.byNode()
+], function(declare, registry){
+
+	// 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],{});
+
+		_getSibling: function(/*String*/ which){
 			// summary:
-			//		Mixin for widgets that are children of a container widget
-			//
-			// example:
-			// | 	// make a basic custom widget that knows about it's parents
-			// |	dojo.declare("my.customClass",[dijit._Widget,dijit._Contained],{});
-
-			getParent: function(){
-				// summary:
-				//		Returns the parent widget of this widget, assuming the parent
-				//		specifies isContainer
-				var parent = dijit.getEnclosingWidget(this.domNode.parentNode);
-				return parent && parent.isContainer ? parent : null;
-			},
-
-			_getSibling: function(/*String*/ which){
-				// summary:
-				//      Returns next or previous sibling
-				// which:
-				//      Either "next" or "previous"
-				// tags:
-				//      private
-				var node = this.domNode;
-				do{
-					node = node[which+"Sibling"];
-				}while(node && node.nodeType != 1);
-				return node && dijit.byNode(node);	// dijit._Widget
-			},
-
-			getPreviousSibling: function(){
-				// summary:
-				//		Returns null if this is the first child of the parent,
-				//		otherwise returns the next element sibling to the "left".
+			//      Returns next or previous sibling
+			// which:
+			//      Either "next" or "previous"
+			// tags:
+			//      private
+			var node = this.domNode;
+			do{
+				node = node[which+"Sibling"];
+			}while(node && node.nodeType != 1);
+			return node && registry.byNode(node);	// dijit._Widget
+		},
+
+		getPreviousSibling: function(){
+			// summary:
+			//		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._Widget
+		},
 
-			getNextSibling: function(){
-				// summary:
-				//		Returns null if this is the last child of the parent,
-				//		otherwise returns the next element sibling to the "right".
+		getNextSibling: function(){
+			// summary:
+			//		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._Widget
+		},
 
-			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
+		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
 
-				var p = this.getParent();
-				if(!p || !p.getIndexOfChild){
-					return -1; // int
-				}
-				return p.getIndexOfChild(this); // int
+			var p = this.getParent();
+			if(!p || !p.getIndexOfChild){
+				return -1; // int
 			}
+			return p.getIndexOfChild(this); // int
 		}
-	);
-
-
-return dijit._Contained;
+	});
 });
diff --git a/dijit/_Container.js b/dijit/_Container.js
index 57c8817..a8bd92b 100644
--- a/dijit/_Container.js
+++ b/dijit/_Container.js
@@ -1,8 +1,16 @@
-define("dijit/_Container", ["dojo", "dijit"], function(dojo, dijit) {
-
-dojo.declare("dijit._Container",
-	null,
-	{
+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){
+
+	// 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:
@@ -16,17 +24,11 @@ dojo.declare("dijit._Container",
 		//		this.containerNode.   In that case calls like addChild(node, position)
 		//		wouldn't make sense.
 
-		// isContainer: [protected] Boolean
-		//		Indicates that this widget acts as a "parent" to the descendant widgets.
-		//		When the parent is started it will call startup() on the child widgets.
-		//		See also `isLayoutContainer`.
-		isContainer: true,
-
 		buildRendering: function(){
 			this.inherited(arguments);
 			if(!this.containerNode){
 				// all widgets with descendants must set containerNode
-	 				this.containerNode = this.domNode;
+	 			this.containerNode = this.domNode;
 			}
 		},
 
@@ -45,7 +47,7 @@ dojo.declare("dijit._Container",
 					insertIndex = "after";
 				}
 			}
-			dojo.place(widget.domNode, refNode, insertIndex);
+			domConstruct.place(widget.domNode, refNode, insertIndex);
 
 			// If I've been started but the child widget hasn't been started,
 			// start it now.  Make sure to do this after widget has been
@@ -56,7 +58,7 @@ dojo.declare("dijit._Container",
 			}
 		},
 
-		removeChild: function(/*Widget or int*/ widget){
+		removeChild: function(/*Widget|int*/ widget){
 			// summary:
 			//		Removes the passed widget instance from this widget but does
 			//		not destroy it.  You can also pass in an integer indicating
@@ -80,13 +82,6 @@ dojo.declare("dijit._Container",
 			return this.getChildren().length > 0;	// Boolean
 		},
 
-		destroyDescendants: function(/*Boolean*/ preserveDom){
-			// summary:
-			//      Destroys all the widgets inside this.containerNode,
-			//      but not this widget itself
-			dojo.forEach(this.getChildren(), function(child){ child.destroyRecursive(preserveDom); });
-		},
-
 		_getSiblingOfChild: function(/*dijit._Widget*/ child, /*int*/ dir){
 			// summary:
 			//		Get the next or previous widget sibling of child
@@ -99,38 +94,14 @@ dojo.declare("dijit._Container",
 				which = (dir>0 ? "nextSibling" : "previousSibling");
 			do{
 				node = node[which];
-			}while(node && (node.nodeType != 1 || !dijit.byNode(node)));
-			return node && dijit.byNode(node);	// dijit._Widget
+			}while(node && (node.nodeType != 1 || !registry.byNode(node)));
+			return node && registry.byNode(node);	// dijit._Widget
 		},
 
 		getIndexOfChild: function(/*dijit._Widget*/ child){
 			// summary:
 			//		Gets the index of the child in this container or -1 if not found
-			return dojo.indexOf(this.getChildren(), child);	// int
-		},
-
-		startup: function(){
-			// summary:
-			//		Called after all the widgets have been instantiated and their
-			//		dom nodes have been inserted somewhere under dojo.doc.body.
-			//
-			//		Widgets should override this method to do any initialization
-			//		dependent on other widgets existing, and then call
-			//		this superclass method to finish things off.
-			//
-			//		startup() in subclasses shouldn't do anything
-			//		size related because the size of the widget hasn't been set yet.
-
-			if(this._started){ return; }
-
-			// Startup all children of this widget
-			dojo.forEach(this.getChildren(), function(child){ child.startup(); });
-
-			this.inherited(arguments);
+			return array.indexOf(this.getChildren(), child);	// int
 		}
-	}
-);
-
-
-return dijit._Container;
+	});
 });
diff --git a/dijit/_CssStateMixin.js b/dijit/_CssStateMixin.js
index b25a379..820b2dd 100644
--- a/dijit/_CssStateMixin.js
+++ b/dijit/_CssStateMixin.js
@@ -1,6 +1,19 @@
-define("dijit/_CssStateMixin", ["dojo", "dijit"], function(dojo, dijit) {
-
-dojo.declare("dijit._CssStateMixin", [], {
+define([
+	"dojo/touch",
+	"dojo/_base/array", // array.forEach array.map
+	"dojo/_base/declare",	// declare
+	"dojo/dom-class", // domClass.toggle
+	"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.
@@ -32,7 +45,7 @@ dojo.declare("dijit._CssStateMixin", [], {
 	// 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,
@@ -45,13 +58,13 @@ dojo.declare("dijit._CssStateMixin", [], {
 		this.inherited(arguments);
 
 		// Automatically monitor mouse events (essentially :hover and :active) on this.domNode
-		dojo.forEach(["onmouseenter", "onmouseleave", "onmousedown"], function(e){
+		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
-		dojo.forEach(["disabled", "readOnly", "checked", "selected", "focused", "state", "hovering", "active"], function(attr){
-			this.watch(attr, dojo.hitch(this, "_setStateClass"));
+		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
@@ -82,13 +95,14 @@ dojo.declare("dijit._CssStateMixin", [], {
 					this._set("active", false);
 					break;
 
-				case "mousedown" :
+				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(dojo.body(), "onmouseup", function(){
+					var mouseUpConnector = this.connect(win.body(), touch.release, function(){
 						this._mouseDown = false;
 						this._set("active", false);
 						this.disconnect(mouseUpConnector);
@@ -128,7 +142,7 @@ dojo.declare("dijit._CssStateMixin", [], {
 		var newStateClasses = this.baseClass.split(" ");
 
 		function multiply(modifier){
-			newStateClasses = newStateClasses.concat(dojo.map(newStateClasses, function(c){ return c+modifier; }), "dijit"+modifier);
+			newStateClasses = newStateClasses.concat(array.map(newStateClasses, function(c){ return c+modifier; }), "dijit"+modifier);
 		}
 
 		if(!this.isLeftToRight()){
@@ -136,8 +150,9 @@ dojo.declare("dijit._CssStateMixin", [], {
 			multiply("Rtl");
 		}
 
+		var checkedState = this.checked == "mixed" ? "Mixed" : (this.checked ? "Checked" : "");
 		if(this.checked){
-			multiply("Checked");
+			multiply(checkedState);
 		}
 		if(this.state){
 			multiply(this.state);
@@ -158,7 +173,7 @@ dojo.declare("dijit._CssStateMixin", [], {
 			}
 		}
 
-		if(this._focused){
+		if(this.focused){
 			multiply("Focused");
 		}
 
@@ -167,13 +182,13 @@ dojo.declare("dijit._CssStateMixin", [], {
 		var tn = this.stateNode || this.domNode,
 			classHash = {};	// set of all classes (state and otherwise) for node
 
-		dojo.forEach(tn.className.split(" "), function(c){ classHash[c] = true; });
+		array.forEach(tn.className.split(" "), function(c){ classHash[c] = true; });
 
 		if("_stateClasses" in this){
-			dojo.forEach(this._stateClasses, function(c){ delete classHash[c]; });
+			array.forEach(this._stateClasses, function(c){ delete classHash[c]; });
 		}
 
-		dojo.forEach(newStateClasses, function(c){ classHash[c] = true; });
+		array.forEach(newStateClasses, function(c){ classHash[c] = true; });
 
 		var newClasses = [];
 		for(var c in classHash){
@@ -202,17 +217,17 @@ dojo.declare("dijit._CssStateMixin", [], {
 		//		CSS class name (ex: dijitSliderUpArrow).
 
 		// Current state of node (initially false)
-		// NB: setting specifically to false because dojo.toggleClass() needs true boolean as third arg
+		// 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 = dojo.hitch(this, "connect", node);
+			cn = lang.hitch(this, "connect", node);
 
 		function setClass(){
 			var disabled = ("disabled" in self && self.disabled) || ("readonly" in self && self.readonly);
-			dojo.toggleClass(node, clazz+"Hover", hovering && !active && !disabled);
-			dojo.toggleClass(node, clazz+"Active", active && !disabled);
-			dojo.toggleClass(node, clazz+"Focused", focused && !disabled);
+			domClass.toggle(node, clazz+"Hover", hovering && !active && !disabled);
+			domClass.toggle(node, clazz+"Active", active && !disabled);
+			domClass.toggle(node, clazz+"Focused", focused && !disabled);
 		}
 
 		// Mouse
@@ -225,11 +240,11 @@ dojo.declare("dijit._CssStateMixin", [], {
 			active = false;
 			setClass();
 		});
-		cn("onmousedown", function(){
+		cn(touch.press, function(){
 			active = true;
 			setClass();
 		});
-		cn("onmouseup", function(){
+		cn(touch.release, function(){
 			active = false;
 			setClass();
 		});
@@ -250,7 +265,4 @@ dojo.declare("dijit._CssStateMixin", [], {
 		this.watch("readOnly", setClass);
 	}
 });
-
-
-return dijit._CssStateMixin;
 });
diff --git a/dijit/_DialogMixin.js b/dijit/_DialogMixin.js
index 213a456..94433cb 100644
--- a/dijit/_DialogMixin.js
+++ b/dijit/_DialogMixin.js
@@ -1,13 +1,18 @@
-define("dijit/_DialogMixin", ["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"./a11y"	// _getTabNavigable
+], function(declare, a11y){
 
-dojo.declare("dijit._DialogMixin", null,
-	{
+	// module:
+	//		dijit/_DialogMixin
+	// summary:
+	//		_DialogMixin provides functions useful to Dialog and TooltipDialog
+
+	return declare("dijit._DialogMixin", null, {
 		// summary:
 		//		This provides functions useful to Dialog and TooltipDialog
 
-		attributeMap: dijit._Widget.prototype.attributeMap,
-
-		execute: function(/*Object*/ formContents){
+		execute: function(/*Object*/ /*===== formContents =====*/){
 			// summary:
 			//		Callback when the user hits the submit button.
 			//		Override this method to handle Dialog execution.
@@ -59,13 +64,9 @@ dojo.declare("dijit._DialogMixin", null,
 			// tags:
 			//		protected
 
-			var elems = dijit._getTabNavigable(this.containerNode);
+			var elems = a11y._getTabNavigable(this.containerNode);
 			this._firstFocusItem = elems.lowest || elems.first || this.closeButtonNode || this.domNode;
 			this._lastFocusItem = elems.last || elems.highest || this._firstFocusItem;
 		}
-	}
-);
-
-
-return dijit._DialogMixin;
+	});
 });
diff --git a/dijit/_FocusMixin.js b/dijit/_FocusMixin.js
new file mode 100644
index 0000000..e327a44
--- /dev/null
+++ b/dijit/_FocusMixin.js
@@ -0,0 +1,73 @@
+define([
+	"./focus",
+	"./_WidgetBase",
+	"dojo/_base/declare", // declare
+	"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.
+	lang.extend(_WidgetBase, {
+		// focused: [readonly] Boolean
+		//		This widget or a widget it contains has focus, or is "active" because
+		//		it was recently clicked.
+		focused: false,
+
+		onFocus: function(){
+			// summary:
+			//		Called when the widget becomes "active" because
+			//		it or a widget inside of it either has focus, or has recently
+			//		been clicked.
+			// tags:
+			//		callback
+		},
+
+		onBlur: function(){
+			// summary:
+			//		Called when the widget stops being "active" because
+			//		focus moved to something outside of it, or the user
+			//		clicked somewhere outside of it, or the widget was
+			//		hidden.
+			// tags:
+			//		callback
+		},
+
+		_onFocus: function(){
+			// summary:
+			//		This is where widgets do processing for when they are active,
+			//		such as changing CSS classes.  See onFocus() for more details.
+			// tags:
+			//		protected
+			this.onFocus();
+		},
+
+		_onBlur: function(){
+			// summary:
+			//		This is where widgets do processing for when they stop being active,
+			//		such as changing CSS classes.  See onBlur() for more details.
+			// tags:
+			//		protected
+			this.onBlur();
+		}
+	});
+
+	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
+
+		// flag that I want _onFocus()/_onBlur() notifications from focus manager
+		_focusManager: focus
+	});
+
+});
diff --git a/dijit/_HasDropDown.js b/dijit/_HasDropDown.js
index a6d8883..7f59760 100644
--- a/dijit/_HasDropDown.js
+++ b/dijit/_HasDropDown.js
@@ -1,33 +1,60 @@
-define("dijit/_HasDropDown", ["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit) {
-
-dojo.declare("dijit._HasDropDown",
-	null,
-	{
+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/keys", // keys.DOWN_ARROW keys.ENTER keys.ESCAPE
+	"dojo/_base/lang", // lang.hitch lang.isFunction
+	"dojo/touch",
+	"dojo/_base/window", // win.doc
+	"dojo/window", // winUtils.getBox
+	"./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){
+
+/*=====
+	var _FocusMixin = dijit._FocusMixin;
+=====*/
+
+	// module:
+	//		dijit/_HasDropDown
+	// summary:
+	//		Mixin for widgets that need drop down ability.
+
+	return declare("dijit._HasDropDown", _FocusMixin, {
 		// summary:
 		//		Mixin for widgets that need drop down ability.
 
 		// _buttonNode: [protected] DomNode
 		//		The button/icon/node to click to display the drop down.
-		//		Can be set via a dojoAttachPoint assignment.
+		//		Can be set via a data-dojo-attach-point assignment.
 		//		If missing, then either focusNode or domNode (if focusNode is also missing) will be used.
 		_buttonNode: null,
 
 		// _arrowWrapperNode: [protected] DomNode
 		//		Will set CSS class dijitUpArrow, dijitDownArrow, dijitRightArrow etc. on this node depending
 		//		on where the drop down is set to be positioned.
-		//		Can be set via a dojoAttachPoint assignment.
+		//		Can be set via a data-dojo-attach-point assignment.
 		//		If missing, then _buttonNode will be used.
 		_arrowWrapperNode: null,
 
 		// _popupStateNode: [protected] DomNode
 		//		The node to set the popupActive class on.
-		//		Can be set via a dojoAttachPoint assignment.
+		//		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,
 
 		// _aroundNode: [protected] DomNode
 		//		The node to display the popup around.
-		//		Can be set via a dojoAttachPoint assignment.
+		//		Can be set via a data-dojo-attach-point assignment.
 		//		If missing, then domNode will be used.
 		_aroundNode: null,
 
@@ -77,12 +104,15 @@ dojo.declare("dijit._HasDropDown",
 		_onDropDownMouseDown: function(/*Event*/ e){
 			// summary:
 			//		Callback when the user mousedown's on the arrow icon
-
 			if(this.disabled || this.readOnly){ return; }
 
-			dojo.stopEvent(e);
+			// Prevent default to stop things like text selection, but don't stop propogation, so that:
+			//		1. TimeTextBox etc. can focusthe <input> on mousedown
+			//		2. dropDownButtonActive class applied by _CssStateMixin (on button depress)
+			//		3. user defined onMouseDown handler fires
+			e.preventDefault();
 
-			this._docHandler = this.connect(dojo.doc, "onmouseup", "_onDropDownMouseUp");
+			this._docHandler = this.connect(win.doc, touch.release, "_onDropDownMouseUp");
 
 			this.toggleDropDown();
 		},
@@ -90,8 +120,8 @@ dojo.declare("dijit._HasDropDown",
 		_onDropDownMouseUp: function(/*Event?*/ e){
 			// summary:
 			//		Callback when the user lifts their mouse after mouse down on the arrow icon.
-			//		If the drop is a simple menu and the mouse is over the menu, we execute it, otherwise, we focus our
-			//		dropDown node.  If the event is missing, then we are not
+			//		If the drop down is a simple menu and the mouse 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
@@ -109,12 +139,12 @@ dojo.declare("dijit._HasDropDown",
 				// because it's so large.  In that case mouse-up shouldn't select a value from the menu.
 				// Find out if our target is somewhere in our dropdown widget,
 				// but not over our _buttonNode (the clickable node)
-				var c = dojo.position(this._buttonNode, true);
+				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)){
 					var t = e.target;
 					while(t && !overMenu){
-						if(dojo.hasClass(t, "dijitPopup")){
+						if(domClass.contains(t, "dijitPopup")){
 							overMenu = true;
 						}else{
 							t = t.parentNode;
@@ -124,7 +154,7 @@ dojo.declare("dijit._HasDropDown",
 						t = e.target;
 						if(dropDown.onItemClick){
 							var menuItem;
-							while(t && !(menuItem = dijit.byNode(t))){
+							while(t && !(menuItem = registry.byNode(t))){
 								t = t.parentNode;
 							}
 							if(menuItem && menuItem.onClick && menuItem.getParent){
@@ -135,17 +165,40 @@ dojo.declare("dijit._HasDropDown",
 					}
 				}
 			}
-			if(this._opened && 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(dojo.hitch(dropDown, "focus"), 1);
+			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);
+				}
+			}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);
 			}
 		},
 
 		_onDropDownClick: function(/*Event*/ e){
-			// the drop down was already opened on mousedown/keydown; just need to call stopEvent()
+			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().
 			if(this._stopClickEvents){
-				dojo.stopEvent(e);
+				event.stop(e);
 			}
 		},
 
@@ -165,7 +218,7 @@ dojo.declare("dijit._HasDropDown",
 					"left" : "Left",
 					"right" : "Right"
 			}[this.dropDownPosition[0]] || this.dropDownPosition[0] || "Down";
-			dojo.addClass(this._arrowWrapperNode || this._buttonNode, "dijit" + defaultPos + "ArrowButton");
+			domClass.add(this._arrowWrapperNode || this._buttonNode, "dijit" + defaultPos + "ArrowButton");
 		},
 
 		postCreate: function(){
@@ -174,7 +227,7 @@ dojo.declare("dijit._HasDropDown",
 
 			this.inherited(arguments);
 
-			this.connect(this._buttonNode, "onmousedown", "_onDropDownMouseDown");
+			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");
@@ -202,16 +255,16 @@ dojo.declare("dijit._HasDropDown",
 			if(d && this._opened && d.handleKey){
 				if(d.handleKey(e) === false){
 					/* false return code means that the drop down handled the key */
-					dojo.stopEvent(e);
+					event.stop(e);
 					return;
 				}
 			}
-			if(d && this._opened && e.charOrCode == dojo.keys.ESCAPE){
+			if(d && this._opened && e.charOrCode == keys.ESCAPE){
 				this.closeDropDown();
-				dojo.stopEvent(e);
+				event.stop(e);
 			}else if(!this._opened &&
-					(e.charOrCode == dojo.keys.DOWN_ARROW ||
-						( (e.charOrCode == dojo.keys.ENTER || e.charOrCode == " ") &&
+					(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'))))){
@@ -219,7 +272,7 @@ dojo.declare("dijit._HasDropDown",
 				// 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;
-				dojo.stopEvent(e);
+				event.stop(e);
 			}
 		},
 
@@ -229,7 +282,7 @@ dojo.declare("dijit._HasDropDown",
 				this.toggleDropDown();
 				var d = this.dropDown;	// drop down may not exist until toggleDropDown() call
 				if(d && d.focus){
-					setTimeout(dojo.hitch(d, "focus"), 1);
+					setTimeout(lang.hitch(d, "focus"), 1);
 				}
 			}
 		},
@@ -242,7 +295,7 @@ dojo.declare("dijit._HasDropDown",
 			// 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 = dijit._curFocus && this.dropDown && dojo.isDescendant(dijit._curFocus, this.dropDown.domNode);
+			var focusMe = focus.curNode && this.dropDown && dom.isDescendant(focus.curNode, this.dropDown.domNode);
 
 			this.closeDropDown(focusMe);
 
@@ -251,7 +304,7 @@ dojo.declare("dijit._HasDropDown",
 
 		isLoaded: function(){
 			// summary:
-			//		Returns whether or not the dropdown is loaded.  This can
+			//		Returns true if the dropdown exists and it's data is loaded.  This can
 			//		be overridden in order to force a call to loadDropDown().
 			// tags:
 			//		protected
@@ -259,17 +312,42 @@ dojo.declare("dijit._HasDropDown",
 			return true;
 		},
 
-		loadDropDown: function(/* Function */ loadCallback){
+		loadDropDown: function(/*Function*/ loadCallback){
 			// summary:
-			//		Loads the data for the dropdown, and at some point, calls
-			//		the given callback.   This is basically a callback when the
-			//		user presses the down arrow button to open the drop down.
+			//		Creates the drop down if it doesn't exist, loads the data
+			//		if there's an href and it hasn't been loaded yet, and then calls
+			//		the given callback.
 			// tags:
 			//		protected
 
+			// TODO: for 2.0, change API to return a Deferred, instead of calling loadCallback?
 			loadCallback();
 		},
 
+		loadAndOpenDropDown: function(){
+			// summary:
+			//		Creates the drop down if it doesn't exist, loads the data
+			//		if there's an href and it hasn't been loaded yet, and
+			//		then opens the drop down.  This is basically a callback when the
+			//		user presses the down arrow button to open the drop down.
+			// returns: Deferred
+			//		Deferred for the drop down widget that
+			//		fires when drop down is created and loaded
+			// tags:
+			//		protected
+			var d = new Deferred(),
+				afterLoad = lang.hitch(this, function(){
+					this.openDropDown();
+					d.resolve(this.dropDown);
+				});
+			if(!this.isLoaded()){
+				this.loadDropDown(afterLoad);
+			}else{
+				afterLoad();
+			}
+			return d;
+		},
+
 		toggleDropDown: function(){
 			// summary:
 			//		Callback when the user presses the down arrow button or presses
@@ -280,13 +358,7 @@ dojo.declare("dijit._HasDropDown",
 
 			if(this.disabled || this.readOnly){ return; }
 			if(!this._opened){
-				// If we aren't loaded, load it first so there isn't a flicker
-				if(!this.isLoaded()){
-					this.loadDropDown(dojo.hitch(this, "openDropDown"));
-					return;
-				}else{
-					this.openDropDown();
-				}
+				this.loadAndOpenDropDown();
 			}else{
 				this.closeDropDown();
 			}
@@ -334,29 +406,29 @@ dojo.declare("dijit._HasDropDown",
 				if(!this._explicitDDHeight){
 					myStyle.height = "";
 				}
-				dojo.style(ddNode, myStyle);
-				
+				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 = dojo.window.getBox(),
-						position = dojo.position(aroundNode, false);
+					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();
+					dropDown.startup(); // this has to be done after being added to the DOM
 				}
-
-				dijit.popup.moveOffScreen(dropDown);
 				// Get size of drop down, and determine if vertical scroll bar needed
-				var mb = dojo._getMarginSize(ddNode);
+				var mb = domGeometry.getMarginSize(ddNode);
 				var overHeight = (maxHeight && mb.h > maxHeight);
-				dojo.style(ddNode, {
+				domStyle.set(ddNode, {
 					overflowX: "hidden",
 					overflowY: overHeight ? "auto" : "hidden"
 				});
@@ -377,20 +449,20 @@ dojo.declare("dijit._HasDropDown",
 				}else{
 					delete mb.w;
 				}
-				
+
 				// And finally, resize the dropdown to calculated height and width
-				if(dojo.isFunction(dropDown.resize)){
+				if(lang.isFunction(dropDown.resize)){
 					dropDown.resize(mb);
 				}else{
-					dojo.marginBox(ddNode, mb);
+					domGeometry.setMarginBox(ddNode, mb);
 				}
 			}
 
-			var retVal = dijit.popup.open({
+			var retVal = popup.open({
 				parent: this,
 				popup: dropDown,
 				around: aroundNode,
-				orient: dijit.getPopupAroundAlignment((this.dropDownPosition && this.dropDownPosition.length) ? this.dropDownPosition : ["below"],this.isLeftToRight()),
+				orient: this.dropDownPosition,
 				onExecute: function(){
 					self.closeDropDown(true);
 				},
@@ -398,13 +470,13 @@ dojo.declare("dijit._HasDropDown",
 					self.closeDropDown(true);
 				},
 				onClose: function(){
-					dojo.attr(self._popupStateNode, "popupActive", false);
-					dojo.removeClass(self._popupStateNode, "dijitHasDropDownOpen");
+					domAttr.set(self._popupStateNode, "popupActive", false);
+					domClass.remove(self._popupStateNode, "dijitHasDropDownOpen");
 					self._opened = false;
 				}
 			});
-			dojo.attr(this._popupStateNode, "popupActive", "true");
-			dojo.addClass(self._popupStateNode, "dijitHasDropDownOpen");
+			domAttr.set(this._popupStateNode, "popupActive", "true");
+			domClass.add(self._popupStateNode, "dijitHasDropDownOpen");
 			this._opened=true;
 
 			// TODO: set this.checked and call setStateClass(), to affect button look while drop down is shown
@@ -421,14 +493,10 @@ dojo.declare("dijit._HasDropDown",
 
 			if(this._opened){
 				if(focus){ this.focus(); }
-				dijit.popup.close(this.dropDown);
+				popup.close(this.dropDown);
 				this._opened = false;
 			}
 		}
 
-	}
-);
-
-
-return dijit._HasDropDown;
+	});
 });
diff --git a/dijit/_KeyNavContainer.js b/dijit/_KeyNavContainer.js
index c50d648..647653c 100644
--- a/dijit/_KeyNavContainer.js
+++ b/dijit/_KeyNavContainer.js
@@ -1,16 +1,35 @@
-define("dijit/_KeyNavContainer", ["dojo", "dijit", "dijit/_Container"], function(dojo, dijit) {
+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.declare("dijit._KeyNavContainer",
-	dijit._Container,
-	{
+/*=====
+	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], {
 
 		// summary:
 		//		A _Container with keyboard navigation of its children.
 		// description:
 		//		To use this mixin, call connectKeyNavHandlers() in
-		//		postCreate() and call startupKeyNavChildren() in startup().
+		//		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
@@ -23,42 +42,41 @@ dojo.declare("dijit._KeyNavContainer",
 		//		moved to the first item in the container.
 		tabIndex: "0",
 
-		_keyNavCodes: {},
-
-		connectKeyNavHandlers: function(/*dojo.keys[]*/ prevKeyCodes, /*dojo.keys[]*/ nextKeyCodes){
+		connectKeyNavHandlers: function(/*keys[]*/ prevKeyCodes, /*keys[]*/ nextKeyCodes){
 			// summary:
 			//		Call in postCreate() to attach the keyboard handlers
 			//		to the container.
-			// preKeyCodes: dojo.keys[]
+			// preKeyCodes: keys[]
 			//		Key codes for navigating to the previous child.
-			// nextKeyCodes: dojo.keys[]
+			// nextKeyCodes: keys[]
 			//		Key codes for navigating to the next child.
 			// tags:
 			//		protected
 
+			// TODO: call this automatically from my own postCreate()
+
 			var keyCodes = (this._keyNavCodes = {});
-			var prev = dojo.hitch(this, this.focusPrev);
-			var next = dojo.hitch(this, this.focusNext);
-			dojo.forEach(prevKeyCodes, function(code){ keyCodes[code] = prev; });
-			dojo.forEach(nextKeyCodes, function(code){ keyCodes[code] = next; });
-			keyCodes[dojo.keys.HOME] = dojo.hitch(this, "focusFirstChild");
-			keyCodes[dojo.keys.END] = dojo.hitch(this, "focusLastChild");
+			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; });
+			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(){
-			// summary:
-			//		Call in startup() to set child tabindexes to -1
-			// tags:
-			//		protected
-			dojo.forEach(this.getChildren(), dojo.hitch(this, "_startupChild"));
+			kernel.deprecated("startupKeyNavChildren() call no longer needed", "", "2.0");
+		},
+
+		startup: function(){
+			this.inherited(arguments);
+			array.forEach(this.getChildren(), lang.hitch(this, "_startupChild"));
 		},
 
 		addChild: function(/*dijit._Widget*/ widget, /*int?*/ insertIndex){
-			// summary:
-			//		Add a child to our _Container
-			dijit._KeyNavContainer.superclass.addChild.apply(this, arguments);
+			this.inherited(arguments);
 			this._startupChild(widget);
 		},
 
@@ -73,10 +91,7 @@ dojo.declare("dijit._KeyNavContainer",
 			//		Focus the first focusable child in the container.
 			// tags:
 			//		protected
-			var child = this._getFirstFocusableChild();
-			if(child){ // edge case: Menu could be empty or hidden
-				this.focusChild(child);
-			}
+			this.focusChild(this._getFirstFocusableChild());
 		},
 
 		focusLastChild: function(){
@@ -84,10 +99,7 @@ dojo.declare("dijit._KeyNavContainer",
 			//		Focus the last focusable child in the container.
 			// tags:
 			//		protected
-			var child = this._getLastFocusableChild();
-			if(child){ // edge case: Menu could be empty or hidden
-				this.focusChild(child);
-			}
+			this.focusChild(this._getLastFocusableChild());
 		},
 
 		focusNext: function(){
@@ -95,8 +107,7 @@ dojo.declare("dijit._KeyNavContainer",
 			//		Focus the next widget
 			// tags:
 			//		protected
-			var child = this._getNextFocusableChild(this.focusedChild, 1);
-			this.focusChild(child);
+			this.focusChild(this._getNextFocusableChild(this.focusedChild, 1));
 		},
 
 		focusPrev: function(){
@@ -105,13 +116,12 @@ dojo.declare("dijit._KeyNavContainer",
 			//		(ex: go to the ComboButton icon section rather than button section)
 			// tags:
 			//		protected
-			var child = this._getNextFocusableChild(this.focusedChild, -1);
-			this.focusChild(child, true);
+			this.focusChild(this._getNextFocusableChild(this.focusedChild, -1), true);
 		},
 
 		focusChild: function(/*dijit._Widget*/ widget, /*Boolean*/ last){
 			// summary:
-			//		Focus widget.
+			//		Focus specified child widget.
 			// widget:
 			//		Reference to container's child widget
 			// last:
@@ -119,9 +129,11 @@ dojo.declare("dijit._KeyNavContainer",
 			//		last one instead of the first one
 			// tags:
 			//		protected
-			
+
+			if(!widget){ return; }
+
 			if(this.focusedChild && widget !== this.focusedChild){
-				this._onChildBlur(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");
@@ -136,9 +148,9 @@ dojo.declare("dijit._KeyNavContainer",
 			//		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);
@@ -160,10 +172,12 @@ dojo.declare("dijit._KeyNavContainer",
 			// 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.
 
-			// focus bubbles on Firefox,
-			// so just make sure that focus has really gone to the container
-			if(evt.target !== this.domNode){ return; }
+			// 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();
 
@@ -171,7 +185,7 @@ dojo.declare("dijit._KeyNavContainer",
 			// (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
-			dojo.attr(this.domNode, "tabIndex", "-1");
+			domAttr.set(this.domNode, "tabIndex", "-1");
 		},
 
 		_onBlur: function(evt){
@@ -180,8 +194,9 @@ dojo.declare("dijit._KeyNavContainer",
 			// 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){
-				dojo.attr(this.domNode, "tabIndex", this.tabIndex);
+				domAttr.set(this.domNode, "tabIndex", this.tabIndex);
 			}
+			this.focusedChild = null;
 			this.inherited(arguments);
 		},
 
@@ -195,14 +210,15 @@ dojo.declare("dijit._KeyNavContainer",
 			var func = this._keyNavCodes[evt.charOrCode];
 			if(func){
 				func();
-				dojo.stopEvent(evt);
+				event.stop(evt);
 			}
 		},
 
-		_onChildBlur: function(/*dijit._Widget*/ widget){
+		_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
 		},
@@ -244,9 +260,5 @@ dojo.declare("dijit._KeyNavContainer",
 			// no focusable child found
 			return null;	// dijit._Widget
 		}
-	}
-);
-
-
-return dijit._KeyNavContainer;
+	});
 });
diff --git a/dijit/_MenuBase.js b/dijit/_MenuBase.js
new file mode 100644
index 0000000..d1b3876
--- /dev/null
+++ b/dijit/_MenuBase.js
@@ -0,0 +1,391 @@
+define([
+	"./popup",
+	"dojo/window",
+	"./_Widget",
+	"./_KeyNavContainer",
+	"./_TemplatedMixin",
+	"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();
+			}
+		}
+	},
+
+	_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);
+		}
+	},
+
+	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 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);
+			}
+		}
+		// 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;
+				}
+				pm.close(itemPopup); // this calls onClose
+			}, this.popupDelay);
+		}
+	},
+
+	onItemUnhover: function(/*MenuItem*/ item){
+		// summary:
+		//		Callback fires when mouse exits a MenuItem
+		// tags:
+		//		protected
+
+		if(this.isActive){
+			this._stopPopupTimer();
+		}
+		if(this._hoveredChild == item){ this._hoveredChild = null; }
+	},
+
+	_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;
+		}
+	},
+
+	_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;
+		}
+	},
+
+	_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;
+		}
+	},
+
+	_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
+
+		// this can't be done in _onFocus since the _onFocus events occurs asynchronously
+		if(typeof this.isShowingNow == 'undefined'){ // non-popup menu
+			this._markActive();
+		}
+
+		this.focusChild(item);
+
+		if(item.disabled){ return 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();
+
+			// user defined handler for click
+			item.onClick(evt);
+		}
+	},
+
+	_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);
+		}
+	},
+
+	_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
+
+		this.isShowingNow = true;
+		this._markActive();
+	},
+
+	_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");
+	},
+
+	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();
+			}
+			// Close all popups that are open and descendants of this menu
+			pm.close(this.currentPopup);
+			this.currentPopup = null;
+		}
+
+		if(this.focusedChild){ // unhighlight the focused item
+			this.focusedChild._setSelected(false);
+			this.focusedChild._onUnhover();
+			this.focusedChild = 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._hoveredChild._onUnhover(); // any previous mouse movement is trumped by focus selection
+		}
+	},
+
+	_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
+
+		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();
+		}
+	}
+});
+
+});
diff --git a/dijit/_OnDijitClickMixin.js b/dijit/_OnDijitClickMixin.js
new file mode 100644
index 0000000..081ee86
--- /dev/null
+++ b/dijit/_OnDijitClickMixin.js
@@ -0,0 +1,125 @@
+define([
+	"dojo/on",
+	"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){
+
+	// 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
+
+			return this.inherited(arguments, [obj, event == "ondijitclick" ? a11yclick : event, method]);
+		}
+	});
+});
diff --git a/dijit/_PaletteMixin.js b/dijit/_PaletteMixin.js
index a265a16..cb9cbfb 100644
--- a/dijit/_PaletteMixin.js
+++ b/dijit/_PaletteMixin.js
@@ -1,8 +1,26 @@
-define("dijit/_PaletteMixin", ["dojo", "dijit", "dijit/_CssStateMixin"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"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
+	"./_CssStateMixin",
+	"./focus",
+	"./typematic"
+], function(declare, domAttr, domClass, domConstruct, event, keys, lang, _CssStateMixin, focus, typematic){
 
-dojo.declare("dijit._PaletteMixin",
-	[dijit._CssStateMixin],
-	{
+/*=====
+	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:
@@ -20,8 +38,8 @@ dojo.declare("dijit._PaletteMixin",
 
 	// value: String
 	//		Currently selected color/emoticon/etc.
-	value: null,
-	
+	value: "",
+
 	// _selectedCell: [private] Integer
 	//		Index of the currently selected cell. Initially, none selected
 	_selectedCell: -1,
@@ -58,8 +76,22 @@ dojo.declare("dijit._PaletteMixin",
 	//	 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, dyeClassObj) {
+	_preparePalette: function(choices, titles) {
 		// summary:
 		//		Subclass must call _preparePalette() from postCreate(), passing in the tooltip
 		//		for each cell
@@ -67,34 +99,30 @@ dojo.declare("dijit._PaletteMixin",
 		//		id's for each cell of the palette, used to create Dye JS object for each cell
 		// titles: String[]
 		//		Localized tooltip for each cell
-		// dyeClassObj: Constructor?
-		//		If specified, use this constructor rather than this.dyeClass
 
 		this._cells = [];
 		var url = this._blankGif;
-		
-		dyeClassObj = dyeClassObj || dojo.getObject(this.dyeClass);
+
+		this.connect(this.gridNode, "ondijitclick", "_onCellClick");
 
 		for(var row=0; row < choices.length; row++){
-			var rowNode = dojo.create("tr", {tabIndex: "-1"}, this.gridNode);
+			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 = new dyeClassObj(value, row, col);
-					
-					var cellNode = dojo.create("td", {
+					var cellObject = this._dyeFactory(value, row, col);
+
+					var cellNode = domConstruct.create("td", {
 						"class": this.cellClass,
 						tabIndex: "-1",
-						title: titles[value]
+						title: titles[value],
+						role: "gridcell"
 					});
 
 					// prepare cell inner structure
 					cellObject.fillCell(cellNode, url);
 
-					this.connect(cellNode, "ondijitclick", "_onCellClick");
-					this._trackMouseState(cellNode, this.cellClass);
-
-					dojo.place(cellNode, rowNode);
+					domConstruct.place(cellNode, rowNode);
 
 					cellNode.index = this._cells.length;
 
@@ -122,9 +150,9 @@ dojo.declare("dijit._PaletteMixin",
 		};
 		for(var key in keyIncrementMap){
 			this._connects.push(
-				dijit.typematic.addKeyListener(
+				typematic.addKeyListener(
 					this.domNode,
-					{charOrCode:dojo.keys[key], ctrlKey:false, altKey:false, shiftKey:false},
+					{charOrCode:keys[key], ctrlKey:false, altKey:false, shiftKey:false},
 					this,
 					function(){
 						var increment = keyIncrementMap[key];
@@ -149,7 +177,7 @@ dojo.declare("dijit._PaletteMixin",
 		//		Focus this widget.  Puts focus on the most recently focused cell.
 
 		// The cell already has tabIndex set, just need to set CSS and focus it
-		dijit.focus(this._currentFocus);
+		focus.focus(this._currentFocus);
 	},
 
 	_onCellClick: function(/*Event*/ evt){
@@ -160,25 +188,27 @@ dojo.declare("dijit._PaletteMixin",
 		// tags:
 		//		private
 
-		var target = evt.currentTarget,
-			value = this._getDye(target).getValue();
+		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;
+		}
+
+		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.
-		// 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);
-			this._setValueAttr(value, true);
-		}));
-
-		// workaround bug where hover class is not removed on popup because the popup is
-		// closed and then there's no onblur event on the cell
-		dojo.removeClass(target, "dijitPaletteCellHover");
+		focus.focus(target);
+		this._setValueAttr(value, true);
 
-		dojo.stopEvent(evt);
+		event.stop(evt);
 	},
 
 	_setCurrent: function(/*DomNode*/ node){
@@ -195,13 +225,13 @@ dojo.declare("dijit._PaletteMixin",
 		//		protected
 		if("_currentFocus" in this){
 			// Remove tabIndex on old cell
-			dojo.attr(this._currentFocus, "tabIndex", "-1");
+			domAttr.set(this._currentFocus, "tabIndex", "-1");
 		}
 
 		// Set tabIndex of new cell
 		this._currentFocus = node;
 		if(node){
-			dojo.attr(node, "tabIndex", this.tabIndex);
+			domAttr.set(node, "tabIndex", this.tabIndex);
 		}
 	},
 
@@ -214,10 +244,10 @@ dojo.declare("dijit._PaletteMixin",
 		// priorityChange:
 		//		Optional parameter used to tell the select whether or not to fire
 		//		onChange event.
-		
+
 		// clear old selected cell
 		if(this._selectedCell >= 0){
-			dojo.removeClass(this._cells[this._selectedCell].node, "dijitPaletteCellSelected");
+			domClass.remove(this._cells[this._selectedCell].node, this.cellClass + "Selected");
 		}
 		this._selectedCell = -1;
 
@@ -226,12 +256,12 @@ dojo.declare("dijit._PaletteMixin",
 			for(var i = 0; i < this._cells.length; i++){
 				if(value == this._cells[i].dye.getValue()){
 					this._selectedCell = i;
-					dojo.addClass(this._cells[i].node, "dijitPaletteCellSelected");
+					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);
 
@@ -240,7 +270,7 @@ dojo.declare("dijit._PaletteMixin",
 		}
 	},
 
-	onChange: function(value){
+	onChange: function(/*===== value =====*/){
 		// summary:
 		//		Callback when a cell is selected.
 		// value: String
@@ -268,7 +298,7 @@ dojo.declare("dijit._PaletteMixin",
 
 			// 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(dojo.hitch(dijit, "focus", focusNode), 0);
+			setTimeout(lang.hitch(dijit, "focus", focusNode), 0);
 		}
 	},
 
@@ -281,7 +311,7 @@ dojo.declare("dijit._PaletteMixin",
 });
 
 /*=====
-dojo.declare("dijit.Dye",
+declare("dijit.Dye",
 	null,
 	{
 		// summary:
@@ -312,6 +342,4 @@ dojo.declare("dijit.Dye",
 );
 =====*/
 
-
-return dijit._PaletteMixin;
 });
diff --git a/dijit/_Templated.js b/dijit/_Templated.js
index 80d6d99..22e1277 100644
--- a/dijit/_Templated.js
+++ b/dijit/_Templated.js
@@ -1,339 +1,71 @@
-define("dijit/_Templated", ["dojo", "dijit", "dijit/_Widget", "dojo/string", "dojo/parser", "dojo/cache"], function(dojo, dijit) {
+define([
+	"./_WidgetBase",
+	"./_TemplatedMixin",
+	"./_WidgetsInTemplateMixin",
+	"dojo/_base/array", // array.forEach
+	"dojo/_base/declare", // declare
+	"dojo/_base/lang", // lang.extend lang.isArray
+	"dojo/_base/kernel" // kernel.deprecated
+], function(_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, array, declare, lang, kernel){
 
-dojo.declare("dijit._Templated",
-	null,
-	{
-		// summary:
-		//		Mixin for widgets that are instantiated from a template
+/*=====
+	var _WidgetBase = dijit._WidgetBase;
+	var _TemplatedMixin = dijit._TemplatedMixin;
+	var _WidgetsInTemplateMixin = dijit._WidgetsInTemplateMixin;
+=====*/
 
-		// templateString: [protected] String
-		//		A string that represents the widget template. Pre-empts the
-		//		templatePath. In builds that have their strings "interned", the
-		//		templatePath is converted to an inline templateString, thereby
-		//		preventing a synchronous network call.
-		//
-		//		Use in conjunction with dojo.cache() to load from a file.
-		templateString: null,
+	// 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, {
+		waiRole: "",
+		waiState:""
+	});
 
-		// templatePath: [protected deprecated] String
-		//		Path to template (HTML file) for this widget relative to dojo.baseUrl.
-		//		Deprecated: use templateString with dojo.cache() instead.
-		templatePath: null,
+	return declare("dijit._Templated", [_TemplatedMixin, _WidgetsInTemplateMixin], {
+		// summary:
+		//		Deprecated mixin for widgets that are instantiated from a template.
+		//		Widgets should use _TemplatedMixin plus if necessary _WidgetsInTemplateMixin instead.
 
 		// widgetsInTemplate: [protected] Boolean
 		//		Should we parse the template to find widgets that might be
 		//		declared in markup inside it?  False by default.
 		widgetsInTemplate: false,
 
-		// skipNodeCache: [protected] Boolean
-		//		If using a cached widget template node poses issues for a
-		//		particular widget class, it can set this property to ensure
-		//		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 dojoAttachPoint=... in the
-		//		template, ex: ["containerNode", "labelNode"]
- 		_attachPoints: [],
- =====*/
-
-/*=====
-		// _attachEvents: [private] Handle[]
-		//		List of connections associated with dojoAttachEvent=... in the
-		//		template
- 		_attachEvents: [],
- =====*/
-
 		constructor: function(){
-			this._attachPoints = [];
-			this._attachEvents = [];
-		},
-
-		_stringRepl: function(tmpl){
-			// summary:
-			//		Does substitution of ${foo} type properties in template string
-			// tags:
-			//		private
-			var className = this.declaredClass, _this = this;
-			// Cache contains a string because we need to do property replacement
-			// do the property replacement
-			return dojo.string.substitute(tmpl, this, function(value, key){
-				if(key.charAt(0) == '!'){ value = dojo.getObject(key.substr(1), false, _this); }
-				if(typeof value == "undefined"){ throw new Error(className+" template:"+key); } // a debugging aide
-				if(value == null){ return ""; }
-
-				// Substitution keys beginning with ! will skip the transform step,
-				// in case a user wishes to insert unescaped markup, e.g. ${!foo}
-				return key.charAt(0) == "!" ? value :
-					// Safer substitution, see heading "Attribute values" in
-					// http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2
-					value.toString().replace(/"/g,"""); //TODO: add &amp? use encodeXML method?
-			}, this);
-		},
-
-		buildRendering: function(){
-			// summary:
-			//		Construct the UI for this widget from a template, setting this.domNode.
-			// tags:
-			//		protected
-
-			// 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 = dijit._Templated.getCachedTemplate(this.templatePath, this.templateString, this._skipNodeCache);
-
-			var node;
-			if(dojo.isString(cached)){
-				node = dojo._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);
-				}
-			}else{
-				// if it's a node, all we have to do is clone it
-				node = cached.cloneNode(true);
-			}
-
-			this.domNode = node;
-
-			// Call down to _Widget.buildRendering() to get base classes assigned
-			// TODO: change the baseClass assignment to attributeMap
-			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);
-
-			if(this.widgetsInTemplate){
-				// Store widgets that we need to start at a later point in time
-				var cw = (this._startupWidgets = dojo.parser.parse(node, {
-					noStart: !this._earlyTemplatedStartup,
-					template: true,
-					inherited: {dir: this.dir, lang: this.lang},
-					propsThis: this,	// so data-dojo-props of widgets in the template can reference "this" to refer to me
-					scope: "dojo"	// even in multi-version mode templates use dojoType/data-dojo-type
-				}));
-
-				this._supportingWidgets = dijit.findWidgets(node);
-
-				this._attachTemplateNodes(cw, function(n,p){
-					return n[p];
-				});
-			}
-
-			this._fillContent(this.srcNodeRef);
-		},
-
-		_fillContent: function(/*DomNode*/ source){
-			// summary:
-			//		Relocate source contents to templated container node.
-			//		this.containerNode must be able to receive children, or exceptions will be thrown.
-			// tags:
-			//		protected
-			var dest = this.containerNode;
-			if(source && dest){
-				while(source.hasChildNodes()){
-					dest.appendChild(source.firstChild);
-				}
-			}
+			kernel.deprecated(this.declaredClass + ": dijit._Templated deprecated, use dijit._TemplatedMixin and if necessary dijit._WidgetsInTemplateMixin", "", "2.0");
 		},
 
 		_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 dojoAttachPoint
-			//		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
-			//			* dojoAttachEvent
-			//			* waiRole
-			//			* waiState
-			// rootNode: DomNode|Array[Widgets]
-			//		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
 
-			getAttrFunc = getAttrFunc || function(n,p){ return n.getAttribute(p); };
+			this.inherited(arguments);
 
-			var nodes = dojo.isArray(rootNode) ? rootNode : (rootNode.all || rootNode.getElementsByTagName("*"));
-			var x = dojo.isArray(rootNode) ? 0 : -1;
+			// 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];
-				if(this.widgetsInTemplate && (getAttrFunc(baseNode, "dojoType") || getAttrFunc(baseNode, "data-dojo-type"))){
-					continue;
-				}
-				// Process dojoAttachPoint
-				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(dojo.isArray(this[point])){
-							this[point].push(baseNode);
-						}else{
-							this[point]=baseNode;
-						}
-						this._attachPoints.push(point);
-					}
-				}
-
-				// Process dojoAttachEvent
-				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 = dojo.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(this.connect(baseNode, event, thisFunc));
-						}
-					}
-				}
 
 				// waiRole, waiState
-				// TODO: remove this in 2.0, templates are now using role=... and aria-XXX=... attributes directicly
 				var role = getAttrFunc(baseNode, "waiRole");
 				if(role){
-					dijit.setWaiRole(baseNode, role);
+					baseNode.setAttribute("role", role);
 				}
 				var values = getAttrFunc(baseNode, "waiState");
 				if(values){
-					dojo.forEach(values.split(/\s*,\s*/), function(stateValue){
+					array.forEach(values.split(/\s*,\s*/), function(stateValue){
 						if(stateValue.indexOf('-') != -1){
 							var pair = stateValue.split('-');
-							dijit.setWaiState(baseNode, pair[0], pair[1]);
+							baseNode.setAttribute("aria-"+pair[0], pair[1]);
 						}
 					});
 				}
 			}
-		},
-
-		startup: function(){
-			dojo.forEach(this._startupWidgets, function(w){
-				if(w && !w._started && w.startup){
-					w.startup();
-				}
-			});
-			this.inherited(arguments);
-		},
-
-		destroyRendering: function(){
-			// Delete all attach points to prevent IE6 memory leaks.
-			dojo.forEach(this._attachPoints, function(point){
-				delete this[point];
-			}, this);
-			this._attachPoints = [];
-
-			// And same for event handlers
-			dojo.forEach(this._attachEvents, this.disconnect, this);
-			this._attachEvents = [];
-			
-			this.inherited(arguments);
-		}
-	}
-);
-
-// key is either templatePath or templateString; object is either string or DOM tree
-dijit._Templated._templateCache = {};
-
-dijit._Templated.getCachedTemplate = function(templatePath, templateString, alwaysUseString){
-	// summary:
-	//		Static method to get a template based on the templatePath or
-	//		templateString key
-	// templatePath: String||dojo.uri.Uri
-	//		The URL to get the template from.
-	// templateString: String?
-	//		a string to use in lieu of fetching the template from a URL. Takes precedence
-	//		over templatePath
-	// 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)
-
-	// is it already cached?
-	var tmplts = dijit._Templated._templateCache;
-	var key = templateString || templatePath;
-	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 == dojo.doc){
-				// string or node of the same document
-				return cached;
-			}
-		}catch(e){ /* squelch */ } // IE can throw an exception if cached.ownerDocument was reloaded
-		dojo.destroy(cached);
-	}
-
-	// If necessary, load template string from template path
-	if(!templateString){
-		templateString = dojo.cache(templatePath, {sanitize: true});
-	}
-	templateString = dojo.string.trim(templateString);
-
-	if(alwaysUseString || templateString.match(/\$\{([^\}]+)\}/g)){
-		// there are variables in the template so all we can do is cache the string
-		return (tmplts[key] = templateString); //String
-	}else{
-		// there are no variables in the template so we can cache the DOM tree
-		var node = dojo._toDom(templateString);
-		if(node.nodeType != 1){
-			throw new Error("Invalid template: " + templateString);
-		}
-		return (tmplts[key] = node); //Node
-	}
-};
-
-if(dojo.isIE){
-	dojo.addOnWindowUnload(function(){
-		var cache = dijit._Templated._templateCache;
-		for(var key in cache){
-			var value = cache[key];
-			if(typeof value == "object"){ // value is either a string or a DOM node template
-				dojo.destroy(value);
-			}
-			delete cache[key];
 		}
 	});
-}
-
-// 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.)
-dojo.extend(dijit._Widget,{
-	dojoAttachEvent: "",
-	dojoAttachPoint: "",
-	waiRole: "",
-	waiState:""
-});
-
-
-return dijit._Templated;
 });
diff --git a/dijit/_TemplatedMixin.js b/dijit/_TemplatedMixin.js
new file mode 100644
index 0000000..3171d9f
--- /dev/null
+++ b/dijit/_TemplatedMixin.js
@@ -0,0 +1,304 @@
+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;
+=====*/
+
+	// module:
+	//		dijit/_TemplatedMixin
+	// summary:
+	//		Mixin for widgets that are instantiated from a template
+
+	var _TemplatedMixin = declare("dijit._TemplatedMixin", null, {
+		// summary:
+		//		Mixin for widgets that are instantiated from a template
+
+		// templateString: [protected] String
+		//		A string that represents the widget template.
+		//		Use in conjunction with dojo.cache() to load from a file.
+		templateString: null,
+
+		// templatePath: [protected deprecated] String
+		//		Path to template (HTML file) for this widget relative to dojo.baseUrl.
+		//		Deprecated: use templateString with require([... "dojo/text!..."], ...) instead
+		templatePath: null,
+
+		// skipNodeCache: [protected] Boolean
+		//		If using a cached widget template nodes poses issues for a
+		//		particular widget class, it can set this property to ensure
+		//		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: [],
+ =====*/
+
+		constructor: function(){
+			this._attachPoints = [];
+			this._attachEvents = [];
+		},
+
+		_stringRepl: function(tmpl){
+			// summary:
+			//		Does substitution of ${foo} type properties in template string
+			// tags:
+			//		private
+			var className = this.declaredClass, _this = this;
+			// Cache contains a string because we need to do property replacement
+			// do the property replacement
+			return string.substitute(tmpl, this, function(value, key){
+				if(key.charAt(0) == '!'){ value = lang.getObject(key.substr(1), false, _this); }
+				if(typeof value == "undefined"){ throw new Error(className+" template:"+key); } // a debugging aide
+				if(value == null){ return ""; }
+
+				// Substitution keys beginning with ! will skip the transform step,
+				// in case a user wishes to insert unescaped markup, e.g. ${!foo}
+				return key.charAt(0) == "!" ? value :
+					// Safer substitution, see heading "Attribute values" in
+					// http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2
+					value.toString().replace(/"/g,"""); //TODO: add &amp? use encodeXML method?
+			}, this);
+		},
+
+		buildRendering: function(){
+			// summary:
+			//		Construct the UI for this widget from a template, setting this.domNode.
+			// 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);
+
+			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);
+				}
+			}else{
+				// if it's a node, all we have to do is clone it
+				node = cached.cloneNode(true);
+			}
+
+			this.domNode = node;
+
+			// Call down to _Widget.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);
+		},
+
+		_beforeFillContent: function(){
+		},
+
+		_fillContent: function(/*DomNode*/ source){
+			// summary:
+			//		Relocate source contents to templated container node.
+			//		this.containerNode must be able to receive children, or exceptions will be thrown.
+			// tags:
+			//		protected
+			var dest = this.containerNode;
+			if(source && dest){
+				while(source.hasChildNodes()){
+					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){
+		// summary:
+		//		Static method to get a template based on the templatePath or
+		//		templateString key
+		// templateString: String
+		//		The template
+		// alwaysUseString: Boolean
+		//		Don't cache the DOM tree for this template, even if it doesn't have any variables
+		// 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)
+
+		// is it already cached?
+		var tmplts = _TemplatedMixin._templateCache;
+		var key = templateString;
+		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){
+					// string or node of the same document
+					return cached;
+				}
+			}catch(e){ /* squelch */ } // IE can throw an exception if cached.ownerDocument was reloaded
+			domConstruct.destroy(cached);
+		}
+
+		templateString = string.trim(templateString);
+
+		if(alwaysUseString || templateString.match(/\$\{([^\}]+)\}/g)){
+			// there are variables in the template so all we can do is cache the string
+			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);
+			if(node.nodeType != 1){
+				throw new Error("Invalid template: " + templateString);
+			}
+			return (tmplts[key] = node); //Node
+		}
+	};
+
+	if(has("ie")){
+		unload.addOnWindowUnload(function(){
+			var cache = _TemplatedMixin._templateCache;
+			for(var key in cache){
+				var value = cache[key];
+				if(typeof value == "object"){ // value is either a string or a DOM node template
+					domConstruct.destroy(value);
+				}
+				delete cache[key];
+			}
+		});
+	}
+
+	// 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 c55bc7a..2ccdfe8 100644
--- a/dijit/_TimePicker.js
+++ b/dijit/_TimePicker.js
@@ -1,34 +1,64 @@
-define("dijit/_TimePicker", ["dojo", "dijit", "text!dijit/templates/TimePicker.html", "dijit/form/_FormWidget", "dojo/date/locale"], function(dojo, dijit) {
+define([
+	"dojo/_base/array", // array.forEach
+	"dojo/date", // date.compare
+	"dojo/date/locale", // locale.format
+	"dojo/date/stamp", // stamp.fromISOString stamp.toISOString
+	"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/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){
 
 /*=====
-dojo.declare(
-	"dijit._TimePicker.__Constraints",
-	dojo.date.locale.__FormatOptions,
-	{
-		// clickableIncrement: String
-		//		See `dijit._TimePicker.clickableIncrement`
-		clickableIncrement: "T00:15:00",
+	var _Widget = dijit._Widget;
+	var _TemplatedMixin = dijit._TemplatedMixin;
+	var _FormValueWidget = dijit.form._FormValueWidget;
+=====*/
 
-		// visibleIncrement: String
-		//		See `dijit._TimePicker.visibleIncrement`
-		visibleIncrement: "T01:00:00",
+	// module:
+	//		dijit/_TimePicker
+	// summary:
+	//		A graphical time picker.
 
-		// visibleRange: String
-		//		See `dijit._TimePicker.visibleRange`
-		visibleRange: "T05:00:00"
-	}
-);
-=====*/
 
-dojo.declare("dijit._TimePicker",
-	[dijit._Widget, dijit._Templated],
-	{
+	/*=====
+	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], {
 		// 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: dojo.cache("dijit", "templates/TimePicker.html"),
+		templateString: template,
 
 		// baseClass: [protected] String
 		//		The root className to use for the various states of this widget
@@ -90,7 +120,7 @@ dojo.declare("dijit._TimePicker",
 			//		protected
 		},
 =====*/
-		serialize: dojo.date.stamp.toISOString,
+		serialize: stamp.toISOString,
 
 /*=====
 		// filterString: string
@@ -103,7 +133,7 @@ dojo.declare("dijit._TimePicker",
 			//		Deprecated.  Used set('value') instead.
 			// tags:
 			//		deprecated
-			dojo.deprecated("dijit._TimePicker:setValue() is deprecated.  Use set('value', ...) instead.", "", "2.0");
+			kernel.deprecated("dijit._TimePicker:setValue() is deprecated.  Use set('value', ...) instead.", "", "2.0");
 			this.set('value', value);
 		},
 
@@ -126,9 +156,11 @@ dojo.declare("dijit._TimePicker",
 			this._showText();
 		},
 
-		isDisabledDate: function(/*Date*/ dateObject, /*String?*/ locale){
+		isDisabledDate: function(/*===== dateObject, locale =====*/){
 			// summary:
-			//		May be overridden to disable certain dates in the TimePicker e.g. `isDisabledDate=dojo.date.locale.isWeekend`
+			//		May be overridden to disable certain dates in the TimePicker e.g. `isDisabledDate=locale.isWeekend`
+			// dateObject: Date
+			// locale: String?
 			// type:
 			//		extension
 			return false; // Boolean
@@ -152,7 +184,7 @@ dojo.declare("dijit._TimePicker",
 				dec = before ? 1 : 0,
 				inc = 1 - dec;
 			do{
-				i = i - dec;
+				i -= dec;
 				n = this._createOption(i);
 				if(n){
 					if((before && n.date > lastValue) || (!before && n.date < lastValue)){
@@ -161,7 +193,7 @@ dojo.declare("dijit._TimePicker",
 					nodes[before ? "unshift" : "push"](n);
 					lastValue = n.date;
 				}
-				i = i + inc;
+				i += inc;
 			}while(nodes.length < maxNum && (i*chk) < max);
 			return nodes;
 		},
@@ -171,7 +203,7 @@ dojo.declare("dijit._TimePicker",
 			//		Displays the relevant choices in the drop down list
 			// tags:
 			//		private
-			var fromIso = dojo.date.stamp.fromISOString;
+			var fromIso = stamp.fromISOString;
 			this.timeMenu.innerHTML = "";
 			this._clickableIncrementDate=fromIso(this.clickableIncrement);
 			this._visibleIncrementDate=fromIso(this.visibleIncrement);
@@ -179,16 +211,15 @@ dojo.declare("dijit._TimePicker",
 			// get the value of the increments and the range in seconds (since 00:00:00) to find out how many divs to create
 			var
 				sinceMidnight = function(/*Date*/ date){
-				return date.getHours() * 60 * 60 + date.getMinutes() * 60 + date.getSeconds();
+					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
+				// round reference date to previous visible increment
 				time = (this.value || this.currentFocus).getTime();
 
-			this._refDate = new Date(time - time % (visibleIncrementSeconds*1000));
+			this._refDate = new Date(time - time % (clickableIncrementSeconds*1000));
 			this._refDate.setFullYear(1970,0,1); // match parse defaults
 
 			// assume clickable increment is the smallest unit
@@ -206,9 +237,15 @@ dojo.declare("dijit._TimePicker",
 			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>.
-				after = this._getFilteredNodes(0, Math.min(this._totalIncrements >> 1, 10) - 1),
-				before = this._getFilteredNodes(0, Math.min(this._totalIncrements, 10) - after.length, true, after[0]);
-			dojo.forEach(before.concat(after), function(n){this.timeMenu.appendChild(n);}, this);
+				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);
 		},
 
 		constructor: function(){
@@ -216,15 +253,15 @@ dojo.declare("dijit._TimePicker",
 		},
 
 		postMixInProperties: function(){
-		        this.inherited(arguments);
+			this.inherited(arguments);
 			this._setConstraintsAttr(this.constraints); // this needs to happen now (and later) due to codependency on _set*Attr calls
 		},
 
 		_setConstraintsAttr: function(/* Object */ constraints){
 			// brings in visibleRange, increments, etc.
-			dojo.mixin(this, constraints);
+			lang.mixin(this, constraints);
 
-			// dojo.date.locale needs the lang in the constraints as locale
+			// locale needs the lang in the constraints as locale
 			if(!constraints.locale){
 				constraints.locale = this.lang;
 			}
@@ -232,9 +269,9 @@ dojo.declare("dijit._TimePicker",
 
 		postCreate: function(){
 			// assign typematic mouse listeners to the arrow buttons
-			this.connect(this.timeMenu, dojo.isIE ? "onmousewheel" : 'DOMMouseScroll', "_mouseWheeled");
-			this._connects.push(dijit.typematic.addMouseListener(this.upArrow, this, "_onArrowUp", 33, 250));
-			this._connects.push(dijit.typematic.addMouseListener(this.downArrow, this, "_onArrowDown", 33, 250));
+			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);
 		},
@@ -247,7 +284,7 @@ dojo.declare("dijit._TimePicker",
 
 			// in non-IE browser the "mouseenter" event will become "mouseover",
 			// but in IE it's still "mouseenter"
-			dojo.toggleClass(e.currentTarget, e.currentTarget == this.upArrow ? "dijitUpArrowHover" : "dijitDownArrowHover",
+			domClass.toggle(e.currentTarget, e.currentTarget == this.upArrow ? "dijitUpArrowHover" : "dijitDownArrowHover",
 				e.type == "mouseenter" || e.type == "mouseover");
 		},
 
@@ -264,37 +301,37 @@ dojo.declare("dijit._TimePicker",
 			if(this.constraints.selector == "time"){
 				date.setFullYear(1970,0,1); // make sure each time is for the same date
 			}
-			var dateString = dojo.date.locale.format(date, this.constraints);
+			var dateString = locale.format(date, this.constraints);
 			if(this.filterString && dateString.toLowerCase().indexOf(this.filterString) !== 0){
 				// Doesn't match the filter - return null
 				return null;
 			}
 
-			var div = dojo.create("div", {"class": this.baseClass+"Item"});
+			var div = domConstruct.create("div", {"class": this.baseClass+"Item"});
 			div.date = date;
 			div.index = index;
-			dojo.create('div',{
+			domConstruct.create('div',{
 				"class": this.baseClass + "ItemInner",
 				innerHTML: dateString
 			}, div);
 
 			if(index%this._visibleIncrement<1 && index%this._visibleIncrement>-1){
-				dojo.addClass(div, this.baseClass+"Marker");
+				domClass.add(div, this.baseClass+"Marker");
 			}else if(!(index%this._clickableIncrement)){
-				dojo.addClass(div, this.baseClass+"Tick");
+				domClass.add(div, this.baseClass+"Tick");
 			}
 
 			if(this.isDisabledDate(date)){
 				// set disabled
-				dojo.addClass(div, this.baseClass+"ItemDisabled");
+				domClass.add(div, this.baseClass+"ItemDisabled");
 			}
-			if(this.value && !dojo.date.compare(this.value, date, this.constraints.selector)){
+			if(this.value && !ddate.compare(this.value, date, this.constraints.selector)){
 				div.selected = true;
-				dojo.addClass(div, this.baseClass+"ItemSelected");
-				if(dojo.hasClass(div, this.baseClass+"Marker")){
-					dojo.addClass(div, this.baseClass+"MarkerSelected");
+				domClass.add(div, this.baseClass+"ItemSelected");
+				if(domClass.contains(div, this.baseClass+"Marker")){
+					domClass.add(div, this.baseClass+"MarkerSelected");
 				}else{
-					dojo.addClass(div, this.baseClass+"TickSelected");
+					domClass.add(div, this.baseClass+"TickSelected");
 				}
 
 				// Initially highlight the current value.   User can change highlight by up/down arrow keys
@@ -316,7 +353,7 @@ dojo.declare("dijit._TimePicker",
 			this.onChange(tdate);
 		},
 
-		onChange: function(/*Date*/ time){
+		onChange: function(/*Date*/ /*===== time =====*/){
 			// summary:
 			//		Notification that a time was selected.  It may be the same as the previous value.
 			// tags:
@@ -339,11 +376,11 @@ dojo.declare("dijit._TimePicker",
 			}else{
 				this._highlighted_option = null;
 			}
-			dojo.toggleClass(node, this.baseClass+"ItemHover", highlight);
-			if(dojo.hasClass(node, this.baseClass+"Marker")){
-				dojo.toggleClass(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{
-				dojo.toggleClass(node, this.baseClass+"TickHover", highlight);
+				domClass.toggle(node, this.baseClass+"TickHover", highlight);
 			}
 		},
 
@@ -355,7 +392,7 @@ dojo.declare("dijit._TimePicker",
 			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(!dojo.hasClass(tgr, this.baseClass+"Item")){return;}
+			if(!domClass.contains(tgr, this.baseClass+"Item")){return;}
 			this._highlightOption(tgr, true);
 		},
 
@@ -375,9 +412,9 @@ dojo.declare("dijit._TimePicker",
 			// tags:
 			//		private
 			this._keyboardSelected = null;
-			dojo.stopEvent(e);
+			event.stop(e);
 			// we're not _measuring_ the scroll amount, just direction
-			var scrollAmount = (dojo.isIE ? e.wheelDelta : -e.detail);
+			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
 		},
 
@@ -421,24 +458,23 @@ dojo.declare("dijit._TimePicker",
 			//		from the `dijit.form.TimeTextBox` to be handled in this widget
 			// tags:
 			//		protected
-			var dk = dojo.keys;
-			if(e.charOrCode == dk.DOWN_ARROW || e.charOrCode == dk.UP_ARROW){
-				dojo.stopEvent(e);
+			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 || dojo.query("." + this.baseClass + "ItemSelected", timeMenu)[0];
+					tgt = this._highlighted_option || query("." + this.baseClass + "ItemSelected", timeMenu)[0];
 				if(!tgt){
 					tgt = timeMenu.childNodes[0];
 				}else if(timeMenu.childNodes.length){
-					if(e.charOrCode == dk.DOWN_ARROW && !tgt.nextSibling){
+					if(e.charOrCode == keys.DOWN_ARROW && !tgt.nextSibling){
 						this._onArrowDown();
-					}else if(e.charOrCode == dk.UP_ARROW && !tgt.previousSibling){
+					}else if(e.charOrCode == keys.UP_ARROW && !tgt.previousSibling){
 						this._onArrowUp();
 					}
-					if(e.charOrCode == dk.DOWN_ARROW){
+					if(e.charOrCode == keys.DOWN_ARROW){
 						tgt = tgt.nextSibling;
 					}else{
 						tgt = tgt.previousSibling;
@@ -447,25 +483,22 @@ dojo.declare("dijit._TimePicker",
 				this._highlightOption(tgt, true);
 				this._keyboardSelected = tgt;
 				return false;
-			}else if(e.charOrCode == dk.ENTER || e.charOrCode === dk.TAB){
+			}else if(e.charOrCode == keys.ENTER || e.charOrCode === keys.TAB){
 				// mouse hover followed by TAB is NO selection
-				if(!this._keyboardSelected && e.charOrCode === dk.TAB){
+				if(!this._keyboardSelected && e.charOrCode === keys.TAB){
 					return true;	// true means don't call stopEvent()
 				}
 
 				// Accept the currently-highlighted option as the value
 				if(this._highlighted_option){
-				this._onOptionSelected({target: this._highlighted_option});
-			}
+					this._onOptionSelected({target: this._highlighted_option});
+				}
 
 				// Call stopEvent() for ENTER key so that form doesn't submit,
 				// but not for TAB, so that TAB does switch focus
-				return e.charOrCode === dk.TAB;
+				return e.charOrCode === keys.TAB;
 			}
+			return undefined;
 		}
-	}
-);
-
-
-return dijit._TimePicker;
+	});
 });
diff --git a/dijit/_Widget.js b/dijit/_Widget.js
index 1f5941d..1b5f64d 100644
--- a/dijit/_Widget.js
+++ b/dijit/_Widget.js
@@ -1,56 +1,63 @@
-define("dijit/_Widget", ["dojo", "dijit", "dijit/_WidgetBase", "dijit/_base"], function(dojo, dijit) {
-
-
-////////////////// DEFERRED CONNECTS ///////////////////
+define([
+	"dojo/aspect",	// aspect.around
+	"dojo/_base/config",	// config.isDebug
+	"dojo/_base/connect",	// connect.connect
+	"dojo/_base/declare", // declare
+	"dojo/_base/kernel", // kernel.deprecated
+	"dojo/_base/lang", // lang.hitch
+	"dojo/query",
+	"dojo/ready",
+	"./registry",	// registry.byNode
+	"./_WidgetBase",
+	"./_OnDijitClickMixin",
+	"./_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,
+			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(){
+	// summary:
+	//		If user connects to a widget method === this function, then they will
+	//		instead actually be connecting the equivalent event on this.domNode
+}
 
-// This code is to assist deferring dojo.connect() calls in widgets (connecting to events on the widgets'
-// DOM nodes) until someone actually needs to monitor that event.
-dojo.connect(dojo, "_connect",
-	function(/*dijit._Widget*/ widget, /*String*/ event){
-		if(widget && dojo.isFunction(widget._onConnect)){
-			widget._onConnect(event);
+// Trap dojo.connect() calls to connectToDomNode methods, and redirect to _Widget.on()
+function aroundAdvice(originalConnect){
+	return function(obj, event, scope, method){
+		if(obj && typeof event == "string" && obj[event] == connectToDomNode){
+			return obj.on(event.substring(2).toLowerCase(), lang.hitch(scope, method));
 		}
-	});
-
-dijit._connectOnUseEventHandler = function(/*Event*/ event){};
-
-////////////////// ONDIJITCLICK SUPPORT ///////////////////
-
-// 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
-dijit._lastKeyDownNode = null;
-if(dojo.isIE){
-	(function(){
-		var keydownCallback = function(evt){
-			dijit._lastKeyDownNode = evt.srcElement;
-		};
-		dojo.doc.attachEvent('onkeydown', keydownCallback);
-		dojo.addOnWindowUnload(function(){
-			dojo.doc.detachEvent('onkeydown', keydownCallback);
-		});
-	})();
-}else{
-	dojo.doc.addEventListener('keydown', function(evt){
-		dijit._lastKeyDownNode = evt.target;
-	}, true);
+		return originalConnect.apply(connect, arguments);
+	};
+}
+aspect.around(connect, "connect", aroundAdvice);
+if(kernel.connect){
+	aspect.around(kernel, "connect", aroundAdvice);
 }
 
-(function(){
-
-dojo.declare("dijit._Widget", dijit._WidgetBase, {
+var _Widget = declare("dijit._Widget", [_WidgetBase, _OnDijitClickMixin, _FocusMixin], {
 	// summary:
 	//		Base class for all Dijit widgets.
 	//
 	//		Extends _WidgetBase, adding support for:
-	//			- deferred connections
-	//				A call like dojo.connect(myWidget, "onMouseMove", func)
-	//				will essentially do a dojo.connect(myWidget.domNode, "onMouseMove", func)
+	//			- declaratively/programatically specifying widget initialization parameters like
+	//				onMouseMove="foo" that call foo when this.domNode gets a mousemove event
 	//			- ondijitclick
-	//				Support new dojoAttachEvent="ondijitclick: ..." that is triggered by a mouse click or a SPACE/ENTER keypress
+	//				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.
@@ -60,28 +67,11 @@ dojo.declare("dijit._Widget", dijit._WidgetBase, {
 	//		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)
-	
 
-	////////////////// DEFERRED CONNECTS ///////////////////
 
-	// _deferredConnects: [protected] Object
-	//		attributeMap addendum for event handlers that should be connected only on first use
-	_deferredConnects: {
-		onClick: "",
-		onDblClick: "",
-		onKeyDown: "",
-		onKeyPress: "",
-		onKeyUp: "",
-		onMouseMove: "",
-		onMouseDown: "",
-		onMouseOut: "",
-		onMouseOver: "",
-		onMouseLeave: "",
-		onMouseEnter: "",
-		onMouseUp: ""
-	},
+	////////////////// DEFERRED CONNECTS ///////////////////
 
-	onClick: dijit._connectOnUseEventHandler,
+	onClick: connectToDomNode,
 	/*=====
 	onClick: function(event){
 		// summary:
@@ -92,7 +82,7 @@ dojo.declare("dijit._Widget", dijit._WidgetBase, {
 		//		callback
 	},
 	=====*/
-	onDblClick: dijit._connectOnUseEventHandler,
+	onDblClick: connectToDomNode,
 	/*=====
 	onDblClick: function(event){
 		// summary:
@@ -103,7 +93,7 @@ dojo.declare("dijit._Widget", dijit._WidgetBase, {
 		//		callback
 	},
 	=====*/
-	onKeyDown: dijit._connectOnUseEventHandler,
+	onKeyDown: connectToDomNode,
 	/*=====
 	onKeyDown: function(event){
 		// summary:
@@ -114,7 +104,7 @@ dojo.declare("dijit._Widget", dijit._WidgetBase, {
 		//		callback
 	},
 	=====*/
-	onKeyPress: dijit._connectOnUseEventHandler,
+	onKeyPress: connectToDomNode,
 	/*=====
 	onKeyPress: function(event){
 		// summary:
@@ -125,7 +115,7 @@ dojo.declare("dijit._Widget", dijit._WidgetBase, {
 		//		callback
 	},
 	=====*/
-	onKeyUp: dijit._connectOnUseEventHandler,
+	onKeyUp: connectToDomNode,
 	/*=====
 	onKeyUp: function(event){
 		// summary:
@@ -136,7 +126,7 @@ dojo.declare("dijit._Widget", dijit._WidgetBase, {
 		//		callback
 	},
 	=====*/
-	onMouseDown: dijit._connectOnUseEventHandler,
+	onMouseDown: connectToDomNode,
 	/*=====
 	onMouseDown: function(event){
 		// summary:
@@ -147,7 +137,7 @@ dojo.declare("dijit._Widget", dijit._WidgetBase, {
 		//		callback
 	},
 	=====*/
-	onMouseMove: dijit._connectOnUseEventHandler,
+	onMouseMove: connectToDomNode,
 	/*=====
 	onMouseMove: function(event){
 		// summary:
@@ -158,7 +148,7 @@ dojo.declare("dijit._Widget", dijit._WidgetBase, {
 		//		callback
 	},
 	=====*/
-	onMouseOut: dijit._connectOnUseEventHandler,
+	onMouseOut: connectToDomNode,
 	/*=====
 	onMouseOut: function(event){
 		// summary:
@@ -169,7 +159,7 @@ dojo.declare("dijit._Widget", dijit._WidgetBase, {
 		//		callback
 	},
 	=====*/
-	onMouseOver: dijit._connectOnUseEventHandler,
+	onMouseOver: connectToDomNode,
 	/*=====
 	onMouseOver: function(event){
 		// summary:
@@ -180,7 +170,7 @@ dojo.declare("dijit._Widget", dijit._WidgetBase, {
 		//		callback
 	},
 	=====*/
-	onMouseLeave: dijit._connectOnUseEventHandler,
+	onMouseLeave: connectToDomNode,
 	/*=====
 	onMouseLeave: function(event){
 		// summary:
@@ -191,7 +181,7 @@ dojo.declare("dijit._Widget", dijit._WidgetBase, {
 		//		callback
 	},
 	=====*/
-	onMouseEnter: dijit._connectOnUseEventHandler,
+	onMouseEnter: connectToDomNode,
 	/*=====
 	onMouseEnter: function(event){
 		// summary:
@@ -202,7 +192,7 @@ dojo.declare("dijit._Widget", dijit._WidgetBase, {
 		//		callback
 	},
 	=====*/
-	onMouseUp: dijit._connectOnUseEventHandler,
+	onMouseUp: connectToDomNode,
 	/*=====
 	onMouseUp: function(event){
 		// summary:
@@ -214,99 +204,41 @@ dojo.declare("dijit._Widget", dijit._WidgetBase, {
 	},
 	=====*/
 
-	create: function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){
-		// To avoid double-connects, remove entries from _deferredConnects
-		// that have been setup manually by a subclass (ex, by dojoAttachEvent).
-		// If a subclass has redefined a callback (ex: onClick) then assume it's being
-		// connected to manually.
-		this._deferredConnects = dojo.clone(this._deferredConnects);
-		for(var attr in this.attributeMap){
-			delete this._deferredConnects[attr]; // can't be in both attributeMap and _deferredConnects
-		}
-		for(attr in this._deferredConnects){
-			if(this[attr] !== dijit._connectOnUseEventHandler){
-				delete this._deferredConnects[attr];	// redefined, probably dojoAttachEvent exists
+	constructor: function(params){
+		// extract parameters like onMouseMove that should connect directly to this.domNode
+		this._toConnect = {};
+		for(var name in params){
+			if(this[name] === connectToDomNode){
+				this._toConnect[name.replace(/^on/, "").toLowerCase()] = params[name];
+				delete params[name];
 			}
 		}
+	},
 
+	postCreate: function(){
 		this.inherited(arguments);
 
-		if(this.domNode){
-			// If the developer has specified a handler as a widget parameter
-			// (ex: new Button({onClick: ...})
-			// then naturally need to connect from DOM node to that handler immediately,
-			for(attr in this.params){
-				this._onConnect(attr);
-			}
+		// perform connection from this.domNode to user specified handlers (ex: onMouseMove)
+		for(var name in this._toConnect){
+			this.on(name, this._toConnect[name]);
 		}
+		delete this._toConnect;
 	},
 
-	_onConnect: function(/*String*/ event){
-		// summary:
-		//		Called when someone connects to one of my handlers.
-		//		"Turn on" that handler if it isn't active yet.
-		//
-		//		This is also called for every single initialization parameter
-		//		so need to do nothing for parameters like "id".
-		// tags:
-		//		private
-		if(event in this._deferredConnects){
-			var mapNode = this[this._deferredConnects[event] || 'domNode'];
-			this.connect(mapNode, event.toLowerCase(), event);
-			delete this._deferredConnects[event];
+	on: function(/*String*/ type, /*Function*/ func){
+		if(this[this._onMap(type)] === connectToDomNode){
+			// Use connect.connect() rather than on() to get handling for "onmouseenter" on non-IE, etc.
+			// Also, need to specify context as "this" rather than the default context of the DOMNode
+			return connect.connect(this.domNode, type.toLowerCase(), this, func);
 		}
+		return this.inherited(arguments);
 	},
 
-	////////////////// FOCUS RELATED ///////////////////
-	// _onFocus() and _onBlur() are called by the focus manager
-
-	// focused: [readonly] Boolean
-	//		This widget or a widget it contains has focus, or is "active" because
-	//		it was recently clicked.
-	focused: false,
-
-	isFocusable: function(){
-		// summary:
-		//		Return true if this widget can currently be focused
-		//		and false if not
-		return this.focus && (dojo.style(this.domNode, "display") != "none");
-	},
-
-	onFocus: function(){
-		// summary:
-		//		Called when the widget becomes "active" because
-		//		it or a widget inside of it either has focus, or has recently
-		//		been clicked.
-		// tags:
-		//		callback
-	},
-
-	onBlur: function(){
-		// summary:
-		//		Called when the widget stops being "active" because
-		//		focus moved to something outside of it, or the user
-		//		clicked somewhere outside of it, or the widget was
-		//		hidden.
-		// tags:
-		//		callback
-	},
-
-	_onFocus: function(e){
-		// summary:
-		//		This is where widgets do processing for when they are active,
-		//		such as changing CSS classes.  See onFocus() for more details.
-		// tags:
-		//		protected
-		this.onFocus();
-	},
-
-	_onBlur: function(){
-		// summary:
-		//		This is where widgets do processing for when they stop being active,
-		//		such as changing CSS classes.  See onBlur() for more details.
-		// tags:
-		//		protected
-		this.onBlur();
+	_setFocusedAttr: function(val){
+		// Remove this method in 2.0 (or sooner), just here to set _focused == focused, for back compat
+		// (but since it's a private variable we aren't required to keep supporting it).
+		this._focused = val;
+		this._set("focused", val);
 	},
 
 	////////////////// DEPRECATED METHODS ///////////////////
@@ -316,7 +248,7 @@ dojo.declare("dijit._Widget", dijit._WidgetBase, {
 		//		Deprecated.  Use set() instead.
 		// tags:
 		//		deprecated
-		dojo.deprecated(this.declaredClass+"::setAttribute(attr, value) is deprecated. Use set() instead.", "", "2.0");
+		kernel.deprecated(this.declaredClass+"::setAttribute(attr, value) is deprecated. Use set() instead.", "", "2.0");
 		this.set(attr, value);
 	},
 
@@ -334,11 +266,11 @@ dojo.declare("dijit._Widget", dijit._WidgetBase, {
 		//		This method is deprecated, use get() or set() directly.
 
 		// Print deprecation warning but only once per calling function
-		if(dojo.config.isDebug){
+		if(config.isDebug){
 			var alreadyCalledHash = arguments.callee._ach || (arguments.callee._ach = {}),
 				caller = (arguments.callee.caller || "unknown caller").toString();
 			if(!alreadyCalledHash[caller]){
-				dojo.deprecated(this.declaredClass + "::attr() is deprecated. Use get() or set() instead, called from " +
+				kernel.deprecated(this.declaredClass + "::attr() is deprecated. Use get() or set() instead, called from " +
 				caller, "", "2.0");
 				alreadyCalledHash[caller] = true;
 			}
@@ -351,82 +283,15 @@ dojo.declare("dijit._Widget", dijit._WidgetBase, {
 			return this.get(name);
 		}
 	},
-	
-	////////////////// ONDIJITCLICK SUPPORT ///////////////////
-
-	// nodesWithKeyClick: [private] String[]
-	//		List of nodes that correctly handle click events via native browser support,
-	//		and don't need dijit's help
-	nodesWithKeyClick: ["input", "button"],
 
-	connect: function(
-			/*Object|null*/ obj,
-			/*String|Function*/ event,
-			/*String|Function*/ method){
+	getDescendants: function(){
 		// 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.
-		//		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 d = dojo,
-			dc = d._connect,
-			handles = this.inherited(arguments, [obj, event == "ondijitclick" ? "onclick" : event, method]);
-
-		if(event == "ondijitclick"){
-			// add key based click activation for unsupported nodes.
-			// do all processing onkey up to prevent spurious clicks
-			// for details see comments at top of this file where _lastKeyDownNode is defined
-			if(d.indexOf(this.nodesWithKeyClick, obj.nodeName.toLowerCase()) == -1){ // is NOT input or button
-				var m = d.hitch(this, method);
-				handles.push(
-					dc(obj, "onkeydown", this, function(e){
-						//console.log(this.id + ": onkeydown, e.target = ", e.target, ", lastKeyDownNode was ", dijit._lastKeyDownNode, ", equality is ", (e.target === dijit._lastKeyDownNode));
-						if((e.keyCode == d.keys.ENTER || e.keyCode == d.keys.SPACE) &&
-							!e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){
-							// needed on IE for when focus changes between keydown and keyup - otherwise dropdown menus do not work
-							dijit._lastKeyDownNode = e.target;
-							
-							// Stop event to prevent scrolling on space key in IE.
-							// But don't do this for _HasDropDown because it surpresses the onkeypress
-							// event needed to open the drop down when the user presses the SPACE key.
-							if(!("openDropDown" in this && obj == this._buttonNode)){
-								e.preventDefault();
-							}
-						}
-			 		}),
-					dc(obj, "onkeyup", this, function(e){
-						//console.log(this.id + ": onkeyup, e.target = ", e.target, ", lastKeyDownNode was ", dijit._lastKeyDownNode, ", equality is ", (e.target === dijit._lastKeyDownNode));
-						if( (e.keyCode == d.keys.ENTER || e.keyCode == d.keys.SPACE) &&
-							e.target == dijit._lastKeyDownNode &&	// === breaks greasemonkey
-							!e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){
-								//need reset here or have problems in FF when focus returns to trigger element after closing popup/alert
-								dijit._lastKeyDownNode = null;
-								return m(e);
-						}
-					})
-				);
-			}
-		}
+		//		Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
+		//		This method should generally be avoided as it returns widgets declared in templates, which are
+		//		supposed to be internal/hidden, but it's left here for back-compat reasons.
 
-		return handles;		// _Widget.Handle
+		kernel.deprecated(this.declaredClass+"::getDescendants() is deprecated. Use getChildren() instead.", "", "2.0");
+		return this.containerNode ? query('[widgetId]', this.containerNode).map(registry.byNode) : []; // dijit._Widget[]
 	},
 
 	////////////////// MISCELLANEOUS METHODS ///////////////////
@@ -475,8 +340,12 @@ dojo.declare("dijit._Widget", dijit._WidgetBase, {
 	}
 });
 
-})();
-
-
-return dijit._Widget;
+// For back-compat, remove in 2.0.
+if(!kernel.isAsync){
+	ready(0, function(){
+		var requires = ["dijit/_base"];
+		require(requires);	// use indirection so modules not rolled into a build
+	});
+}
+return _Widget;
 });
diff --git a/dijit/_WidgetBase.js b/dijit/_WidgetBase.js
index 634f1bc..fa269bb 100644
--- a/dijit/_WidgetBase.js
+++ b/dijit/_WidgetBase.js
@@ -1,11 +1,110 @@
-define("dijit/_WidgetBase", ["dojo", "dijit", "dijit/_base/manager", "dojo/Stateful"], function(dojo, dijit) {
+define([
+	"require",			// require.toUrl
+	"dojo/_base/array", // array.forEach array.map
+	"dojo/aspect",
+	"dojo/_base/config", // config.blankGif
+	"dojo/_base/connect", // connect.connect
+	"dojo/_base/declare", // declare
+	"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-style", // domStyle.set, domStyle.get
+	"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()
+], function(require, array, aspect, config, connect, declare,
+			dom, domAttr, domClass, domConstruct, domGeometry, domStyle, kernel,
+			lang, on, ready, Stateful, topic, win, registry){
 
-(function(){
+/*=====
+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;
+}
 
-dojo.declare("dijit._WidgetBase", dojo.Stateful, {
+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
@@ -13,6 +112,7 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 	//		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,
@@ -20,16 +120,32 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 	//		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
@@ -62,7 +178,7 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 	// 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 dojoAttachPoint syntax, but the domNode
+	//		template system's data-dojo-attach-point syntax, but the domNode
 	//		property is the canonical "top level" node in widget UI.
 	domNode: null,
 
@@ -71,20 +187,20 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 	//		"Children" in this case refers to both DOM nodes and widgets.
 	//		For example, for myWidget:
 	//
-	//		|	<div dojoType=myWidget>
+	//		|	<div data-dojo-type=myWidget>
 	//		|		<b> here's a plain DOM node
-	//		|		<span dojoType=subWidget>and a widget</span>
+	//		|		<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 dojoType=subWidget>and a widget</span>
+	//		|		<span data-dojo-type=subWidget>and a widget</span>
 	//		|		<i> and another plain DOM node </i>
 	//
 	//		In templated widgets, "containerNode" is set via a
-	//		dojoAttachPoint assignment.
+	//		data-dojo-attach-point assignment.
 	//
 	//		containerNode must be defined for any widget that accepts innerHTML
 	//		(like ContentPane or BorderContainer or even Button), and conversely
@@ -98,6 +214,9 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 =====*/
 
 	// 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
@@ -133,12 +252,12 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 	//		- string --> { node: string, type: "attribute" }, for example:
 	//	|	"focusNode" ---> { node: "focusNode", type: "attribute" }
 	//		- "" --> { node: "domNode", type: "attribute" }
-	attributeMap: {id:"", dir:"", lang:"", "class":"", style:"", title:""},
+	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: (dojo.config.blankGif || dojo.moduleUrl("dojo", "resources/blank.gif")).toString(),
+	_blankGif: config.blankGif || require.toUrl("dojo/resources/blank.gif"),
 
 	//////////// INITIALIZATION METHODS ///////////////////////////////////////
 
@@ -166,7 +285,7 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 		//			  tree
 		// description:
 		//		Create calls a number of widget methods (postMixInProperties, buildRendering, postCreate,
-		//		etc.), some of which of you'll want to override. See http://docs.dojocampus.org/dijit/_Widget
+		//		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
@@ -175,21 +294,21 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 		//		private
 
 		// store pointer to original DOM tree
-		this.srcNodeRef = dojo.byId(srcNodeRef);
+		this.srcNodeRef = dom.byId(srcNodeRef);
 
-		// For garbage collection.  An array of handles returned by Widget.connect()
-		// Each handle returned from Widget.connect() is an array of handles from dojo.connect()
+		// For garbage collection.  An array of listener handles returned by this.connect() / this.subscribe()
 		this._connects = [];
 
-		// For garbage collection.  An array of handles returned by Widget.subscribe()
-		// The handle returned from Widget.subscribe() is the handle returned from dojo.subscribe()
-		this._subscribes = [];
+		// For widgets internal to this widget, invisible to calling code
+		this._supportingWidgets = [];
 
-		// mix in our passed parameters
+		// 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; }
+
+		// mix in our passed parameters
 		if(params){
 			this.params = params;
-			dojo._mixin(this, params);
+			lang.mixin(this, params);
 		}
 		this.postMixInProperties();
 
@@ -197,9 +316,9 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 		// (be sure to do this before buildRendering() because that function might
 		// expect the id to be there.)
 		if(!this.id){
-			this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
+			this.id = registry.getUniqueId(this.declaredClass.replace(/\./g,"_"));
 		}
-		dijit.registry.add(this);
+		registry.add(this);
 
 		this.buildRendering();
 
@@ -235,52 +354,56 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 
 	_applyAttributes: function(){
 		// summary:
-		//		Step during widget creation to copy all widget attributes to the
-		//		DOM as per attributeMap and _setXXXAttr functions.
-		// description:
+		//		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.
 		//
-		//		It processes the attributes in the attribute map first, and then
-		//		it goes through and processes the attributes for the _setXXXAttr
-		//		functions that have been specified
+		//		For backwards-compatibility reasons attributeMap overrides _setXXXAttr when
+		//		_setXXXAttr is a hash/string/array, but _setXXXAttr as a functions override attributeMap.
 		// tags:
 		//		private
-		var condAttrApply = function(attr, scope){
-			if((scope.params && attr in scope.params) || scope[attr]){
-				scope.set(attr, scope[attr]);
-			}
-		};
-
-		// Do the attributes in attributeMap
-		for(var attr in this.attributeMap){
-			condAttrApply(attr, this);
-		}
 
-		// And also any attributes with custom setters
-		dojo.forEach(this._getSetterAttributes(), function(a){
-			if(!(a in this.attributeMap)){
-				condAttrApply(a, this);
+		// 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);
 			}
-		}, this);
-	},
 
-	_getSetterAttributes: function(){
-		// summary:
-		//		Returns list of attributes with custom setters for this widget
-		var ctor = this.constructor;
-		if(!ctor._setterAttrs){
-			var r = (ctor._setterAttrs = []),
-				attrs,
-				proto = ctor.prototype;
+			var proto = ctor.prototype;
 			for(var fxName in proto){
-				if(dojo.isFunction(proto[fxName]) && (attrs = fxName.match(/^_set([a-zA-Z]*)Attr$/)) && attrs[1]){
-					r.push(attrs[1].charAt(0).toLowerCase() + attrs[1].substr(1));
+				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);
 				}
 			}
 		}
-		return ctor._setterAttrs;	// String[]
+
+		// 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]);
+		}
 	},
 
 	postMixInProperties: function(){
@@ -295,16 +418,14 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 
 	buildRendering: function(){
 		// summary:
-		//		Construct the UI for this widget, setting this.domNode
-		// description:
-		//		Most widgets will mixin `dijit._Templated`, which implements this
-		//		method.
+		//		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 || dojo.create('div');
+			this.domNode = this.srcNodeRef || domConstruct.create('div');
 		}
 
 		// baseClass is a single class name or occasionally a space-separated list of names.
@@ -313,9 +434,9 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 		if(this.baseClass){
 			var classes = this.baseClass.split(" ");
 			if(!this.isLeftToRight()){
-				classes = classes.concat( dojo.map(classes, function(name){ return name+"Rtl"; }));
+				classes = classes.concat( array.map(classes, function(name){ return name+"Rtl"; }));
 			}
-			dojo.addClass(this.domNode, classes);
+			domClass.add(this.domNode, classes);
 		}
 	},
 
@@ -338,7 +459,14 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 		//		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;
+			}
+		});
 	},
 
 	//////////// DESTROY FUNCTIONS ////////////////////////////////
@@ -370,27 +498,25 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 
 		this._beingDestroyed = true;
 		this.uninitialize();
-		var d = dojo,
-			dfe = d.forEach,
-			dun = d.unsubscribe;
-		dfe(this._connects, function(array){
-			dfe(array, d.disconnect);
-		});
-		dfe(this._subscribes, function(handle){
-			dun(handle);
-		});
+
+		// remove this.connect() and this.subscribe() listeners
+		var c;
+		while(c = this._connects.pop()){
+			c.remove();
+		}
 
 		// destroy widgets created as part of template, etc.
-		dfe(this._supportingWidgets || [], function(w){
+		var w;
+		while(w = this._supportingWidgets.pop()){
 			if(w.destroyRecursive){
 				w.destroyRecursive();
 			}else if(w.destroy){
 				w.destroy();
 			}
-		});
+		}
 
 		this.destroyRendering(preserveDom);
-		dijit.registry.remove(this.id);
+		registry.remove(this.id);
 		this._destroyed = true;
 	},
 
@@ -411,16 +537,16 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 
 		if(this.domNode){
 			if(preserveDom){
-				dojo.removeAttr(this.domNode, "widgetId");
+				domAttr.remove(this.domNode, "widgetId");
 			}else{
-				dojo.destroy(this.domNode);
+				domConstruct.destroy(this.domNode);
 			}
 			delete this.domNode;
 		}
 
 		if(this.srcNodeRef){
 			if(!preserveDom){
-				dojo.destroy(this.srcNodeRef);
+				domConstruct.destroy(this.srcNodeRef);
 			}
 			delete this.srcNodeRef;
 		}
@@ -436,7 +562,7 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 		//		widgets.
 
 		// get all direct descendants and destroy them recursively
-		dojo.forEach(this.getChildren(), function(widget){
+		array.forEach(this.getChildren(), function(widget){
 			if(widget.destroyRecursive){
 				widget.destroyRecursive(preserveDom);
 			}
@@ -454,16 +580,6 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 
 	////////////////// GET/SET, CUSTOM SETTERS, ETC. ///////////////////
 
-	_setClassAttr: function(/*String*/ value){
-		// summary:
-		//		Custom setter for the CSS "class" attribute
-		// tags:
-		//		protected
-		var mapNode = this[this.attributeMap["class"] || 'domNode'];
-		dojo.replaceClass(mapNode, value, this["class"]);
-		this._set("class", value);
-	},
-
 	_setStyleAttr: function(/*String||Object*/ value){
 		// summary:
 		//		Sets the style attribute of the widget according to value,
@@ -475,13 +591,13 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 		// tags:
 		//		protected
 
-		var mapNode = this[this.attributeMap.style || 'domNode'];
+		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(dojo.isObject(value)){
-			dojo.style(mapNode, value);
+		if(lang.isObject(value)){
+			domStyle.set(mapNode, value);
 		}else{
 			if(mapNode.style.cssText){
 				mapNode.style.cssText += "; " + value;
@@ -493,18 +609,20 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 		this._set("style", value);
 	},
 
-	_attrToDom: function(/*String*/ attr, /*String*/ value){
+	_attrToDom: function(/*String*/ attr, /*String*/ value, /*Object?*/ commands){
 		// summary:
 		//		Reflect a widget attribute (title, tabIndex, duration etc.) to
-		//		the widget DOM, as specified in attributeMap.
+		//		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
 
-		var commands = this.attributeMap[attr];
-		dojo.forEach(dojo.isArray(commands) ? commands : [commands], function(command){
+		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
@@ -512,8 +630,8 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 
 			switch(type){
 				case "attribute":
-					if(dojo.isFunction(value)){ // functions execute in the context of the widget
-						value = dojo.hitch(this, value);
+					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
@@ -522,17 +640,17 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 					var attrName = command.attribute ? command.attribute :
 						(/^on[A-Z][a-zA-Z]*$/.test(attr) ? attr.toLowerCase() : attr);
 
-					dojo.attr(mapNode, attrName, value);
+					domAttr.set(mapNode, attrName, value);
 					break;
 				case "innerText":
 					mapNode.innerHTML = "";
-					mapNode.appendChild(dojo.doc.createTextNode(value));
+					mapNode.appendChild(win.doc.createTextNode(value));
 					break;
 				case "innerHTML":
 					mapNode.innerHTML = value;
 					break;
 				case "class":
-					dojo.replaceClass(mapNode, value, this[attr]);
+					domClass.replace(mapNode, value, this[attr]);
 					break;
 			}
 		}, this);
@@ -547,19 +665,17 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 		//		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 a properties "foo"
-		//		and "bar" and a method named "_getFooAttr", calling:
-		//	|	myWidget.get("foo");
-		//		would be equivalent to writing:
-		//	|	widget._getFooAttr();
-		//		and:
-		//	|	myWidget.get("bar");
-		//		would be equivalent to writing:
-		//	|	widget.bar;
+		//
+		// 		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
@@ -570,22 +686,21 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 		// description:
 		//		Sets named properties on a widget which may potentially be handled by a
 		// 		setter in the widget.
-		// 		For example, if the widget has a properties "foo"
-		//		and "bar" and a method named "_setFooAttr", calling:
-		//	|	myWidget.set("foo", "Howdy!");
-		//		would be equivalent to writing:
-		//	|	widget._setFooAttr("Howdy!");
-		//		and:
-		//	|	myWidget.set("bar", 3);
-		//		would be equivalent to writing:
-		//	|	widget.bar = 3;
 		//
-		//	set() may also be called with a hash of name/value pairs, ex:
+		// 		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)
+		//	|	});
+		//
+		//	This is equivalent to calling `set(foo, "Howdy")` and `set(bar, 3)`
 
 		if(typeof name === "object"){
 			for(var x in name){
@@ -593,20 +708,35 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 			}
 			return this;
 		}
-		var names = this._getAttrNames(name);
-		if(this[names.s]){
+		var names = this._getAttrNames(name),
+			setter = this[names.s];
+		if(lang.isFunction(setter)){
 			// use the explicit setter
-			var result = this[names.s].apply(this, Array.prototype.slice.call(arguments, 1));
+			var result = setter.apply(this, Array.prototype.slice.call(arguments, 1));
 		}else{
-			// if param is specified as DOM node attribute, copy it
-			if(name in this.attributeMap){
-				this._attrToDom(name, value);
+			// 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] :
+						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);
 			}
 			this._set(name, value);
 		}
 		return result || this;
 	},
-	
+
 	_attrPairNames: {},		// shared between all widgets
 	_getAttrNames: function(name){
 		// summary:
@@ -617,11 +747,12 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 
 		var apn = this._attrPairNames;
 		if(apn[name]){ return apn[name]; }
-		var uc = name.charAt(0).toUpperCase() + name.substr(1);
+		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",
-			g: "_get"+uc+"Attr"
+			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
 		});
 	},
 
@@ -636,6 +767,32 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 		}
 	},
 
+	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))`.
+
+		return aspect.after(this, this._onMap(type), 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;
+				}
+			}
+		}
+		return map[type.toLowerCase()];	// String
+	},
+
 	toString: function(){
 		// summary:
 		//		Returns a string that represents the widget
@@ -646,20 +803,17 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 		return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String
 	},
 
-	getDescendants: function(){
+	getChildren: function(){
 		// summary:
 		//		Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
-		//		This method should generally be avoided as it returns widgets declared in templates, which are
-		//		supposed to be internal/hidden, but it's left here for back-compat reasons.
-
-		return this.containerNode ? dojo.query('[widgetId]', this.containerNode).map(dijit.byNode) : []; // dijit._Widget[]
+		//		Does not return nested widgets, nor widgets that are part of this widget's template.
+		return this.containerNode ? registry.findWidgets(this.containerNode) : []; // dijit._Widget[]
 	},
 
-	getChildren: function(){
+	getParent: 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 ? dijit.findWidgets(this.containerNode) : []; // dijit._Widget[]
+		//		Returns the parent widget of this widget
+		return registry.getEnclosingWidget(this.domNode.parentNode);
 	},
 
 	connect: function(
@@ -687,35 +841,35 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 		// tags:
 		//		protected
 
-		var handles = [dojo._connect(obj, event, this, method)];
-		this._connects.push(handles);
-		return handles;		// _Widget.Handle
+		var handle = connect.connect(obj, event, this, method);
+		this._connects.push(handle);
+		return handle;		// _Widget.Handle
 	},
 
-	disconnect: function(/* _Widget.Handle */ handles){
+	disconnect: function(handle){
 		// summary:
 		//		Disconnects handle created by `connect`.
 		//		Also removes handle from this widget's list of connects.
 		// tags:
 		//		protected
-		for(var i=0; i<this._connects.length; i++){
-			if(this._connects[i] == handles){
-				dojo.forEach(handles, dojo.disconnect);
-				this._connects.splice(i, 1);
-				return;
-			}
+		var i = array.indexOf(this._connects, handle);
+		if(i != -1){
+			handle.remove();
+			this._connects.splice(i, 1);
 		}
 	},
 
-	subscribe: function(
-			/*String*/ topic,
-			/*String|Function*/ method){
+	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
@@ -723,24 +877,20 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 		//	|	btn.subscribe("/my/topic", function(v){
 		//	|		this.set("label", v);
 		//	|	});
-		var handle = dojo.subscribe(topic, this, method);
-
-		// return handles for Any widget that may need them
-		this._subscribes.push(handle);
-		return handle;
+		// 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
-		for(var i=0; i<this._subscribes.length; i++){
-			if(this._subscribes[i] == handle){
-				dojo.unsubscribe(handle);
-				this._subscribes.splice(i, 1);
-				return;
-			}
-		}
+		// tags:
+		//		protected
+		this.disconnect(handle);
 	},
 
 	isLeftToRight: function(){
@@ -748,13 +898,20 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 		//		Return this widget's explicit or implicit orientation (true for LTR, false for RTL)
 		// tags:
 		//		protected
-		return this.dir ? (this.dir == "ltr") : dojo._isBodyLtr(); //Boolean
+		return this.dir ? (this.dir == "ltr") : domGeometry.isBodyLtr(); //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's domNode reference somewhere in the DOM based
-		//		on standard dojo.place conventions, or passing a Widget reference that
+		//		on standard domConstruct.place conventions, or passing a Widget reference that
 		//		contains and addChild member.
 		//
 		// description:
@@ -763,12 +920,12 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 		//		somewhere in the dom, and allow chaining.
 		//
 		// reference:
-		//		The String id of a domNode, a domNode reference, or a reference to a Widget posessing
+		//		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 dojo.place does, one of: "first", "last",
+		//		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,
@@ -783,9 +940,9 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 		//
 		// example:
 		// | 	// create a Button with no srcNodeRef, and place it in the body:
-		// | 	var button = new dijit.form.Button({ label:"click" }).placeAt(dojo.body());
+		// | 	var button = new dijit.form.Button({ label:"click" }).placeAt(win.body());
 		// | 	// now, 'button' is still the widget reference to the newly created button
-		// | 	dojo.connect(button, "onClick", function(e){ console.log('click'); });
+		// | 	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":
@@ -803,14 +960,32 @@ dojo.declare("dijit._WidgetBase", dojo.Stateful, {
 		if(reference.declaredClass && reference.addChild){
 			reference.addChild(this, position);
 		}else{
-			dojo.place(this.domNode, reference, position);
+			domConstruct.place(this.domNode, reference, position);
 		}
 		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.
+	}
+});
 
-return dijit._WidgetBase;
 });
diff --git a/dijit/_WidgetsInTemplateMixin.js b/dijit/_WidgetsInTemplateMixin.js
new file mode 100644
index 0000000..a4e7c92
--- /dev/null
+++ b/dijit/_WidgetsInTemplateMixin.js
@@ -0,0 +1,61 @@
+define([
+	"dojo/_base/array", // array.forEach
+	"dojo/_base/declare", // declare
+	"dojo/parser", // parser.parse
+	"dijit/registry"	// registry.findWidgets
+], function(array, declare, parser, registry){
+
+	// module:
+	//		dijit/_WidgetsInTemplateMixin
+	// summary:
+	//		Mixin to supplement _TemplatedMixin when template contains widgets
+
+	return declare("dijit._WidgetsInTemplateMixin", null, {
+		// summary:
+		//		Mixin to supplement _TemplatedMixin when template contains widgets
+
+		// _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,
+
+		// widgetsInTemplate: [protected] Boolean
+		//		Should we parse the template to find widgets that might be
+		//		declared in markup inside it?  (Remove for 2.0 and assume true)
+		widgetsInTemplate: true,
+
+		_beforeFillContent: function(){
+			if(this.widgetsInTemplate){
+				// Before copying over content, instantiate widgets in template
+				var node = this.domNode;
+
+				var cw = (this._startupWidgets = 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
+					scope: "dojo"	// even in multi-version mode templates use dojoType/data-dojo-type
+				}));
+
+				this._supportingWidgets = registry.findWidgets(node);
+
+				this._attachTemplateNodes(cw, function(n,p){
+					return n[p];
+				});
+			}
+		},
+
+		startup: function(){
+			array.forEach(this._startupWidgets, function(w){
+				if(w && !w._started && w.startup){
+					w.startup();
+				}
+			});
+			this.inherited(arguments);
+		}
+	});
+});
diff --git a/dijit/_base.js b/dijit/_base.js
index b36827d..1fc06fa 100644
--- a/dijit/_base.js
+++ b/dijit/_base.js
@@ -1,6 +1,22 @@
-define("dijit/_base", ["dojo", "dijit", "dijit/_base/focus", "dijit/_base/manager", "dijit/_base/place", "dijit/_base/popup", "dijit/_base/scroll", "dijit/_base/sniff", "dijit/_base/typematic", "dijit/_base/wai", "dijit/_base/window"], function(dojo, dijit) {
+define([
+	".",
+	"./a11y",	// used to be in dijit/_base/manager
+	"./WidgetSet",	// used to be in dijit/_base/manager
+	"./_base/focus",
+	"./_base/manager",
+	"./_base/place",
+	"./_base/popup",
+	"./_base/scroll",
+	"./_base/sniff",
+	"./_base/typematic",
+	"./_base/wai",
+	"./_base/window"
+], function(dijit){
 
+	// module:
+	//		dijit/_base
+	// summary:
+	//		Includes all the modules in dijit/_base
 
-
-return dijit._base;
+	return dijit._base;
 });
diff --git a/dijit/_base/focus.js b/dijit/_base/focus.js
index 4f69e96..aa85d00 100644
--- a/dijit/_base/focus.js
+++ b/dijit/_base/focus.js
@@ -1,198 +1,256 @@
-define("dijit/_base/focus", ["dojo", "dijit", "dojo/window", "dijit/_base/manager"], function(dojo, dijit) {
-
-// summary:
-//		These functions are used to query or set the focus and selection.
-//
-//		Also, they trace when widgets become activated/deactivated,
-//		so that the widget can fire _onFocus/_onBlur events.
-//		"Active" here means something similar to "focused", but
-//		"focus" isn't quite the right word because we keep track of
-//		a whole stack of "active" widgets.  Example: ComboButton --> Menu -->
-//		MenuItem.  The onBlur event for ComboButton doesn't fire due to focusing
-//		on the Menu or a MenuItem, since they are considered part of the
-//		ComboButton widget.  It only happens when focus is shifted
-//		somewhere completely different.
-
-dojo.mixin(dijit, {
-	// _curFocus: DomNode
-	//		Currently focused item on screen
-	_curFocus: null,
-
-	// _prevFocus: DomNode
-	//		Previously focused item on screen
-	_prevFocus: null,
-
-	isCollapsed: function(){
-		// summary:
-		//		Returns true if there is no text selected
-		return dijit.getBookmark().isCollapsed;
-	},
-
-	getBookmark: function(){
-		// summary:
-		//		Retrieves a bookmark that can be used with moveToBookmark to return to the same range
-		var bm, rg, tg, sel = dojo.doc.selection, cf = dijit._curFocus;
-
-		if(dojo.global.getSelection){
-			//W3C Range API for selections.
-			sel = dojo.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.
+define([
+	"dojo/_base/array", // array.forEach
+	"dojo/dom", // dom.isDescendant
+	"dojo/_base/lang", // lang.isArray
+	"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){
+
+	// 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, {
+		// _curFocus: DomNode
+		//		Currently focused item on screen
+		_curFocus: null,
+
+		// _prevFocus: DomNode
+		//		Previously focused item on screen
+		_prevFocus: null,
+
+		isCollapsed: function(){
+			// summary:
+			//		Returns true if there is no text selected
+			return dijit.getBookmark().isCollapsed;
+		},
+
+		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()};
 					}
-					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
+			}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 = {};
+				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++));
+				//'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.isCollapsed = true;
-					bm.mark = null;
+					bm.mark = rg.getBookmark();
 				}
 			}else{
-				bm.mark = rg.getBookmark();
+				console.warn("No idea how to store the current selection for this browser!");
 			}
-		}else{
-			console.warn("No idea how to store the current selection for this browser!");
-		}
-		return bm; // Object
-	},
-
-	moveToBookmark: function(/*Object*/bookmark){
-		// summary:
-		//		Moves current selection to a bookmark
-		// bookmark:
-		//		This should be a returned object from dijit.getBookmark()
-
-		var _doc = dojo.doc,
-			mark = bookmark.mark;
-		if(mark){
-			if(dojo.global.getSelection){
-				//W3C Rangi API (FF, WebKit, Opera, etc)
-				var sel = dojo.global.getSelection();
-				if(sel && sel.removeAllRanges){
+			return bm; // Object
+		},
+
+		moveToBookmark: function(/*Object*/ bookmark){
+			// summary:
+			//		Moves current selection to a bookmark
+			// 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){
-						var r = mark;
-						var n = r.node;
-						n.selectionStart = r.start;
-						n.selectionEnd = r.end;
+						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{
-						sel.removeAllRanges();
-						sel.addRange(mark);
+						rg = _doc.body.createTextRange();
+						rg.moveToBookmark(mark);
 					}
-				}else{
-					console.warn("No idea how to restore selection for this browser!");
+					rg.select();
 				}
-			}else if(_doc.selection && mark){
-				//'IE' way.
-				var rg;
-				if(mark.pRange){
-					rg = mark.range;
-				}else if(dojo.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
-					dojo.forEach(mark, function(n){
-						rg.addElement(n);
-					});
-				}else{
-					rg = _doc.body.createTextRange();
-					rg.moveToBookmark(mark);
-				}
-				rg.select();
 			}
+		},
+
+		getFocus: function(/*Widget?*/ menu, /*Window?*/ openedForWindow){
+			// summary:
+			//		Called as getFocus(), this returns an Object showing the current focus
+			//		and selected text.
+			//
+			//		Called as getFocus(widget), where widget is a (widget representing) a button
+			//		that was just pressed, it returns where focus was before that button
+			//		was pressed.   (Pressing the button may have either shifted focus to the button,
+			//		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
+			//		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.
+			//
+			// openedForWindow:
+			//		iframe in which menu was opened
+			//
+			// returns:
+			//		A handle to restore focus/selection, to be passed to `dijit.focus`
+			var node = !focus.curNode || (menu && dom.isDescendant(focus.curNode, menu.domNode)) ? dijit._prevFocus : focus.curNode;
+			return {
+				node: node,
+				bookmark: node && (node == focus.curNode) && win.withGlobal(openedForWindow || win.global, dijit.getBookmark),
+				openedForWindow: openedForWindow
+			}; // Object
+		},
+
+		// _activeStack: dijit._Widget[]
+		//		List of currently active widgets (focused widget and it's ancestors)
+		_activeStack: [],
+
+		registerIframe: function(/*DomNode*/ 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 to pass to unregisterIframe()
+			return focus.registerIframe(iframe);
+		},
+
+		unregisterIframe: function(/*Object*/ handle){
+			// summary:
+			//		Unregisters listeners on the specified iframe created by registerIframe.
+			//		After calling be sure to delete or null out the handle itself.
+			// handle:
+			//		Handle returned by registerIframe()
+
+			handle && handle.remove();
+		},
+
+		registerWin: function(/*Window?*/targetWindow, /*DomNode?*/ 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:
+			//		If specified this is the window associated with the iframe,
+			//		i.e. iframe.contentWindow.
+			// effectiveNode:
+			//		If specified, report any focus events inside targetWindow as
+			//		an event on effectiveNode, rather than on evt.target.
+			// returns:
+			//		Handle to pass to unregisterWin()
+
+			return focus.registerWin(targetWindow, effectiveNode);
+		},
+
+		unregisterWin: function(/*Handle*/ handle){
+			// summary:
+			//		Unregisters listeners on the specified window (either the main
+			//		window or an iframe's window) according to handle returned from registerWin().
+			//		After calling be sure to delete or null out the handle itself.
+
+			handle && handle.remove();
 		}
-	},
-
-	getFocus: function(/*Widget?*/ menu, /*Window?*/ openedForWindow){
-		// summary:
-		//		Called as getFocus(), this returns an Object showing the current focus
-		//		and selected text.
-		//
-		//		Called as getFocus(widget), where widget is a (widget representing) a button
-		//		that was just pressed, it returns where focus was before that button
-		//		was pressed.   (Pressing the button may have either shifted focus to the button,
-		//		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
-		//		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.
-		//
-		// openedForWindow:
-		//		iframe in which menu was opened
-		//
-		// returns:
-		//		A handle to restore focus/selection, to be passed to `dijit.focus`
-		var node = !dijit._curFocus || (menu && dojo.isDescendant(dijit._curFocus, menu.domNode)) ? dijit._prevFocus : dijit._curFocus;
-		return {
-			node: node,
-			bookmark: (node == dijit._curFocus) && dojo.withGlobal(openedForWindow || dojo.global, dijit.getBookmark),
-			openedForWindow: openedForWindow
-		}; // Object
-	},
+	});
 
-	focus: function(/*Object || DomNode */ handle){
+	// 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){
 		// summary:
 		//		Sets the focused node and the selection according to argument.
 		//		To set focus to an iframe's content, pass in the iframe itself.
@@ -218,303 +276,44 @@ dojo.mixin(dijit, {
 					focusNode.focus();
 				}catch(e){/*quiet*/}
 			}
-			dijit._onFocusNode(node);
+			focus._onFocusNode(node);
 		}
 
 		// set the selection
 		// do not need to restore if current selection is not empty
 		// (use keyboard to select a menu item) or if previous selection was collapsed
 		// as it may cause focus shift (Esp in IE).
-		if(bookmark && dojo.withGlobal(openedForWindow || dojo.global, dijit.isCollapsed) && !collapsed){
+		if(bookmark && win.withGlobal(openedForWindow || win.global, dijit.isCollapsed) && !collapsed){
 			if(openedForWindow){
 				openedForWindow.focus();
 			}
 			try{
-				dojo.withGlobal(openedForWindow || dojo.global, dijit.moveToBookmark, null, [bookmark]);
+				win.withGlobal(openedForWindow || win.global, dijit.moveToBookmark, null, [bookmark]);
 			}catch(e2){
 				/*squelch IE internal error, see http://trac.dojotoolkit.org/ticket/1984 */
 			}
 		}
-	},
-
-	// _activeStack: dijit._Widget[]
-	//		List of currently active widgets (focused widget and it's ancestors)
-	_activeStack: [],
-
-	registerIframe: function(/*DomNode*/ 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 to pass to unregisterIframe()
-		return dijit.registerWin(iframe.contentWindow, iframe);
-	},
-
-	unregisterIframe: function(/*Object*/ handle){
-		// summary:
-		//		Unregisters listeners on the specified iframe created by registerIframe.
-		//		After calling be sure to delete or null out the handle itself.
-		// handle:
-		//		Handle returned by registerIframe()
-
-		dijit.unregisterWin(handle);
-	},
-
-	registerWin: function(/*Window?*/targetWindow, /*DomNode?*/ 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:
-		//		If specified this is the window associated with the iframe,
-		//		i.e. iframe.contentWindow.
-		// effectiveNode:
-		//		If specified, report any focus events inside targetWindow as
-		//		an event on effectiveNode, rather than on evt.target.
-		// returns:
-		//		Handle to pass to unregisterWin()
-
-		// TODO: make this function private in 2.0; Editor/users should call registerIframe(),
-
-		var mousedownListener = function(evt){
-			dijit._justMouseDowned = true;
-			setTimeout(function(){ dijit._justMouseDowned = false; }, 0);
-			
-			// workaround weird IE bug where the click is on an orphaned node
-			// (first time clicking a Select/DropDownButton inside a TooltipDialog)
-			if(dojo.isIE && evt && evt.srcElement && evt.srcElement.parentNode == null){
-				return;
-			}
-
-			dijit._onTouchNode(effectiveNode || evt.target || evt.srcElement, "mouse");
-		};
-		//dojo.connect(targetWindow, "onscroll", ???);
-
-		// 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 = dojo.isIE ? targetWindow.document.documentElement : targetWindow.document;
-		if(doc){
-			if(dojo.isIE){
-				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,
-					// Should consider those more like a mouse-click than a focus....
-					if(evt.srcElement.tagName.toLowerCase() != "#document" &&
-						dijit.isTabNavigable(evt.srcElement)){
-						dijit._onFocusNode(effectiveNode || evt.srcElement);
-					}else{
-						dijit._onTouchNode(effectiveNode || evt.srcElement);
-					}
-				};
-				doc.attachEvent('onactivate', activateListener);
-				var deactivateListener =  function(evt){
-					dijit._onBlurNode(effectiveNode || evt.srcElement);
-				};
-				doc.attachEvent('ondeactivate', deactivateListener);
-
-				return 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);
-				var focusListener = function(evt){
-					dijit._onFocusNode(effectiveNode || evt.target);
-				};
-				doc.addEventListener('focus', focusListener, true);
-				var blurListener = function(evt){
-					dijit._onBlurNode(effectiveNode || evt.target);
-				};
-				doc.addEventListener('blur', blurListener, true);
-
-				return function(){
-					doc.body.removeEventListener('mousedown', mousedownListener, true);
-					doc.removeEventListener('focus', focusListener, true);
-					doc.removeEventListener('blur', blurListener, true);
-					doc = null;	// prevent memory leak (apparent circular reference via closure)
-				};
-			}
-		}
-	},
-
-	unregisterWin: function(/*Handle*/ handle){
-		// summary:
-		//		Unregisters listeners on the specified window (either the main
-		//		window or an iframe's window) according to handle returned from registerWin().
-		//		After calling be sure to delete or null out the handle itself.
-
-		// Currently our handle is actually a function
-		handle && handle();
-	},
-
-	_onBlurNode: function(/*DomNode*/ node){
-		// summary:
-		// 		Called when focus leaves a node.
-		//		Usually ignored, _unless_ it *isn't* follwed by touching another node,
-		//		which indicates that we tabbed off the last field on the page,
-		//		in which case every widget is marked inactive
-		dijit._prevFocus = dijit._curFocus;
-		dijit._curFocus = null;
-
-		if(dijit._justMouseDowned){
-			// the mouse down caused a new widget to be marked as active; this blur event
-			// is coming late, so ignore it.
-			return;
-		}
-
-		// if the blur event isn't followed by a focus event then mark all widgets as inactive.
-		if(dijit._clearActiveWidgetsTimer){
-			clearTimeout(dijit._clearActiveWidgetsTimer);
+	};
+
+	// For back compatibility, monitor changes to focused node and active widget stack,
+	// publishing events and copying changes from focus manager variables into dijit (top level) variables
+	focus.watch("curNode", function(name, oldVal, newVal){
+		dijit._curFocus = newVal;
+		dijit._prevFocus = oldVal;
+		if(newVal){
+			topic.publish("focusNode", newVal);	// publish
 		}
-		dijit._clearActiveWidgetsTimer = setTimeout(function(){
-			delete dijit._clearActiveWidgetsTimer;
-			dijit._setStack([]);
-			dijit._prevFocus = null;
-		}, 100);
-	},
-
-	_onTouchNode: function(/*DomNode*/ node, /*String*/ by){
-		// summary:
-		//		Callback when node is focused or mouse-downed
-		// node:
-		//		The node that was touched.
-		// by:
-		//		"mouse" if the focus/touch was caused by a mouse down event
-
-		// ignore the recent blurNode event
-		if(dijit._clearActiveWidgetsTimer){
-			clearTimeout(dijit._clearActiveWidgetsTimer);
-			delete dijit._clearActiveWidgetsTimer;
-		}
-
-		// compute stack of active widgets (ex: ComboButton --> Menu --> MenuItem)
-		var newStack=[];
-		try{
-			while(node){
-				var popupParent = dojo.attr(node, "dijitPopupParent");
-				if(popupParent){
-					node=dijit.byId(popupParent).domNode;
-				}else if(node.tagName && node.tagName.toLowerCase() == "body"){
-					// is this the root of the document or just the root of an iframe?
-					if(node === dojo.body()){
-						// node is the root of the main document
-						break;
-					}
-					// otherwise, find the iframe this node refers to (can't access it via parentNode,
-					// need to do this trick instead). window.frameElement is supported in IE/FF/Webkit
-					node=dojo.window.get(node.ownerDocument).frameElement;
-				}else{
-					// if this node is the root node of a widget, then add widget id to stack,
-					// except ignore clicks on disabled widgets (actually focusing a disabled widget still works,
-					// to support MenuItem)
-					var id = node.getAttribute && node.getAttribute("widgetId"),
-						widget = id && dijit.byId(id);
-					if(widget && !(by == "mouse" && widget.get("disabled"))){
-						newStack.unshift(id);
-					}
-					node=node.parentNode;
-				}
-			}
-		}catch(e){ /* squelch */ }
-
-		dijit._setStack(newStack, by);
-	},
-
-	_onFocusNode: function(/*DomNode*/ node){
-		// summary:
-		//		Callback when node is focused
-
-		if(!node){
-			return;
-		}
-
-		if(node.nodeType == 9){
-			// Ignore focus events on the document itself.  This is here so that
-			// (for example) clicking the up/down arrows of a spinner
-			// (which don't get focus) won't cause that widget to blur. (FF issue)
-			return;
-		}
-
-		dijit._onTouchNode(node);
-
-		if(node == dijit._curFocus){ return; }
-		if(dijit._curFocus){
-			dijit._prevFocus = dijit._curFocus;
-		}
-		dijit._curFocus = node;
-		dojo.publish("focusNode", [node]);
-	},
-
-	_setStack: function(/*String[]*/ newStack, /*String*/ by){
-		// summary:
-		//		The stack of active widgets has changed.  Send out appropriate events and records new stack.
-		// newStack:
-		//		array of widget id's, starting from the top (outermost) widget
-		// by:
-		//		"mouse" if the focus/touch was caused by a mouse down event
-
-		var oldStack = dijit._activeStack;
-		dijit._activeStack = newStack;
-
-		// 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;
-			}
-		}
-
-		var widget;
-		// for all elements that have gone out of focus, send blur event
-		for(var i=oldStack.length-1; i>=nCommon; i--){
-			widget = dijit.byId(oldStack[i]);
-			if(widget){
-				widget._focused = false;
-				widget.set("focused", false);
-				widget._hasBeenBlurred = true;
-				if(widget._onBlur){
-					widget._onBlur(by);
-				}
-				dojo.publish("widgetBlur", [widget, by]);
-			}
-		}
-
-		// for all element that have come into focus, send focus event
-		for(i=nCommon; i<newStack.length; i++){
-			widget = dijit.byId(newStack[i]);
-			if(widget){
-				widget._focused = true;
-				widget.set("focused", true);
-				if(widget._onFocus){
-					widget._onFocus(by);
-				}
-				dojo.publish("widgetFocus", [widget, by]);
-			}
-		}
-	}
-});
-
-// register top window and all the iframes it contains
-dojo.addOnLoad(function(){
-	var handle = dijit.registerWin(window);
-	if(dojo.isIE){
-		dojo.addOnWindowUnload(function(){
-			dijit.unregisterWin(handle);
-			handle = null;
-		})
-	}
-});
-
-
-return dijit;
+	});
+	focus.watch("activeStack", function(name, oldVal, newVal){
+		dijit._activeStack = newVal;
+	});
+
+	focus.on("widget-blur", function(widget, by){
+		topic.publish("widgetBlur", widget, by);	// publish
+	});
+	focus.on("widget-focus", function(widget, by){
+		topic.publish("widgetFocus", widget, by);	// publish
+	});
+
+	return dijit;
 });
diff --git a/dijit/_base/manager.js b/dijit/_base/manager.js
index 7c38332..783c533 100644
--- a/dijit/_base/manager.js
+++ b/dijit/_base/manager.js
@@ -1,485 +1,76 @@
-define("dijit/_base/manager", ["dojo", "dijit"], function(dojo, dijit) {
-
-dojo.declare("dijit.WidgetSet", null, {
+define([
+	"dojo/_base/array",
+	"dojo/_base/config", // defaultDuration
+	"../registry",
+	".."	// for setting exports to dijit namespace
+], function(array, config, registry, dijit){
+
+	// module:
+	//		dijit/_base/manager
 	// summary:
-	//		A set of widgets indexed by id. A default instance of this class is
-	//		available as `dijit.registry`
-	//
-	// 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 */ });
-
-	constructor: function(){
-		this._hash = {};
-		this.length = 0;
-	},
-
-	add: function(/*dijit._Widget*/ 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.
-		if(this._hash[widget.id]){
-			throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered");
-		}
-		this._hash[widget.id] = widget;
-		this.length++;
-	},
-
-	remove: function(/*String*/ id){
-		// summary:
-		//		Remove a widget from this WidgetSet. Does not destroy the widget; simply
-		//		removes the reference.
-		if(this._hash[id]){
-			delete this._hash[id];
-			this.length--;
-		}
-	},
-
-	forEach: function(/*Function*/ func, /* Object? */thisObj){
-		// summary:
-		//		Call specified function for each widget in this set.
-		//
-		// func:
-		//		A callback function to run for each item. Is passed the widget, the index
-		//		in the iteration, and the full hash, similar to `dojo.forEach`.
-		//
-		// thisObj:
-		//		An optional scope parameter
-		//
-		// example:
-		//		Using the default `dijit.registry` instance:
-		//		|	dijit.registry.forEach(function(widget){
-		//		|		console.log(widget.declaredClass);
-		//		|	});
-		//
-		// returns:
-		//		Returns self, in order to allow for further chaining.
-
-		thisObj = thisObj || dojo.global;
-		var i = 0, id;
-		for(id in this._hash){
-			func.call(thisObj, this._hash[id], i++, this._hash);
-		}
-		return this;	// dijit.WidgetSet
-	},
-
-	filter: function(/*Function*/ filter, /* Object? */thisObj){
-		// summary:
-		//		Filter down this WidgetSet to a smaller new WidgetSet
-		//		Works the same as `dojo.filter` and `dojo.NodeList.filter`
-		//
-		// filter:
-		//		Callback function to test truthiness. Is passed the widget
-		//		reference and the pseudo-index in the object.
-		//
-		// thisObj: Object?
-		//		Option scope to use for the filter function.
-		//
-		// example:
-		//		Arbitrary: select the odd widgets in this list
-		//		|	dijit.registry.filter(function(w, i){
-		//		|		return i % 2 == 0;
-		//		|	}).forEach(function(w){ /* odd ones */ });
-
-		thisObj = thisObj || dojo.global;
-		var res = new dijit.WidgetSet(), i = 0, id;
-		for(id in this._hash){
-			var w = this._hash[id];
-			if(filter.call(thisObj, w, i++, this._hash)){
-				res.add(w);
-			}
-		}
-		return res; // dijit.WidgetSet
-	},
-
-	byId: function(/*String*/ id){
-		// summary:
-		//		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
-
-		return this._hash[id];	// dijit._Widget
-	},
-
-	byClass: function(/*String*/ cls){
-		// summary:
-		//		Reduce this widgetset to a new WidgetSet of a particular `declaredClass`
-		//
-		// cls: String
-		//		The Class to scan for. Full dot-notated string.
-		//
-		// example:
-		//		Find all `dijit.TitlePane`s in a page:
-		//		|	dijit.registry.byClass("dijit.TitlePane").forEach(function(tp){ tp.close(); });
-
-		var res = new dijit.WidgetSet(), id, widget;
-		for(id in this._hash){
-			widget = this._hash[id];
-			if(widget.declaredClass == cls){
-				res.add(widget);
-			}
-		 }
-		 return res; // dijit.WidgetSet
-},
-
-	toArray: function(){
-		// summary:
-		//		Convert this WidgetSet into a true Array
-		//
-		// example:
-		//		Work with the widget .domNodes in a real Array
-		//		|	dojo.map(dijit.registry.toArray(), function(w){ return w.domNode; });
-
-		var ar = [];
-		for(var id in this._hash){
-			ar.push(this._hash[id]);
-		}
-		return ar;	// dijit._Widget[]
-},
-
-	map: function(/* Function */func, /* Object? */thisObj){
-		// summary:
-		//		Create a new Array from this WidgetSet, following the same rules as `dojo.map`
-		// example:
-		//		|	var nodes = dijit.registry.map(function(w){ return w.domNode; });
-		//
-		// returns:
-		//		A new array of the returned values.
-		return dojo.map(this.toArray(), func, thisObj); // Array
-	},
-
-	every: function(func, thisObj){
-		// summary:
-		// 		A synthetic clone of `dojo.every` acting explicitly on this WidgetSet
-		//
-		// func: Function
-		//		A callback function run for every widget in this list. Exits loop
-		//		when the first false return is encountered.
-		//
-		// thisObj: Object?
-		//		Optional scope parameter to use for the callback
-
-		thisObj = thisObj || dojo.global;
-		var x = 0, i;
-		for(i in this._hash){
-			if(!func.call(thisObj, this._hash[i], x++, this._hash)){
-				return false; // Boolean
-			}
-		}
-		return true; // Boolean
-	},
-
-	some: function(func, thisObj){
-		// summary:
-		// 		A synthetic clone of `dojo.some` acting explictly on this WidgetSet
-		//
-		// func: Function
-		//		A callback function run for every widget in this list. Exits loop
-		//		when the first true return is encountered.
-		//
-		// thisObj: Object?
-		//		Optional scope parameter to use for the callback
-
-		thisObj = thisObj || dojo.global;
-		var x = 0, i;
-		for(i in this._hash){
-			if(func.call(thisObj, this._hash[i], x++, this._hash)){
-				return true; // Boolean
-			}
-		}
-		return false; // Boolean
-	}
-
-});
-
-(function(){
+	//		Shim to methods on registry, plus a few other declarations.
+	//		New code should access dijit/registry directly when possible.
 
 	/*=====
-	dijit.registry = {
-		// summary:
-		//		A list of widgets on a page.
-		// description:
-		//		Is an instance of `dijit.WidgetSet`
-	};
-	=====*/
-	dijit.registry = new dijit.WidgetSet();
-
-	var hash = dijit.registry._hash,
-		attr = dojo.attr,
-		hasAttr = dojo.hasAttr,
-		style = dojo.style;
-
-	dijit.byId = function(/*String|dijit._Widget*/ id){
+	dijit.byId = function(id){
 		// summary:
-		//		Returns a widget by it's id, or if passed a widget, no-op (like dojo.byId())
-		return typeof id == "string" ? hash[id] : id; // dijit._Widget
+		//		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
 	};
 
-	var _widgetTypeCtr = {};
-	dijit.getUniqueId = function(/*String*/widgetType){
+	dijit.getUniqueId = function(widgetType){
 		// summary:
 		//		Generates a unique id for a given widgetType
-	
-		var id;
-		do{
-			id = widgetType + "_" +
-				(widgetType in _widgetTypeCtr ?
-					++_widgetTypeCtr[widgetType] : _widgetTypeCtr[widgetType] = 0);
-		}while(hash[id]);
-		return dijit._scopeName == "dijit" ? id : dijit._scopeName + "_" + id; // String
+		// widgetType: String
+		return registry.getUniqueId(widgetType); // String
 	};
-	
-	dijit.findWidgets = function(/*DomNode*/ root){
+
+	dijit.findWidgets = function(root){
 		// summary:
 		//		Search subtree under root returning widgets found.
 		//		Doesn't search for nested widgets (ie, widgets inside other widgets).
-	
-		var outAry = [];
-	
-		function getChildrenHelper(root){
-			for(var node = root.firstChild; node; node = node.nextSibling){
-				if(node.nodeType == 1){
-					var widgetId = node.getAttribute("widgetId");
-					if(widgetId){
-						var widget = hash[widgetId];
-						if(widget){	// may be null on page w/multiple dojo's loaded
-							outAry.push(widget);
-						}
-					}else{
-						getChildrenHelper(node);
-					}
-				}
-			}
-		}
-	
-		getChildrenHelper(root);
-		return outAry;
+		// root: DOMNode
+		return registry.findWidgets(root);
 	};
-	
+
 	dijit._destroyAll = function(){
 		// summary:
 		//		Code to destroy all widgets and do other cleanup on page unload
-	
-		// Clean up focus manager lingering references to widgets and nodes
-		dijit._curFocus = null;
-		dijit._prevFocus = null;
-		dijit._activeStack = [];
-	
-		// Destroy all the widgets, top down
-		dojo.forEach(dijit.findWidgets(dojo.body()), function(widget){
-			// Avoid double destroy of widgets like Menu that are attached to <body>
-			// even though they are logically children of other widgets.
-			if(!widget._destroyed){
-				if(widget.destroyRecursive){
-					widget.destroyRecursive();
-				}else if(widget.destroy){
-					widget.destroy();
-				}
-			}
-		});
+
+		return registry._destroyAll();
 	};
-	
-	if(dojo.isIE){
-		// 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.
-		dojo.addOnWindowUnload(function(){
-			dijit._destroyAll();
-		});
-	}
-	
-	dijit.byNode = function(/*DOMNode*/ node){
+
+	dijit.byNode = function(node){
 		// summary:
 		//		Returns the widget corresponding to the given DOMNode
-		return hash[node.getAttribute("widgetId")]; // dijit._Widget
+		// node: DOMNode
+		return registry.byNode(node); // dijit._Widget
 	};
-	
-	dijit.getEnclosingWidget = function(/*DOMNode*/ node){
+
+	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
-		while(node){
-			var id = node.getAttribute && node.getAttribute("widgetId");
-			if(id){
-				return hash[id];
-			}
-			node = node.parentNode;
-		}
-		return null;
+		// node: DOMNode
+		return registry.getEnclosingWidget(node);
 	};
-
-	var shown = (dijit._isElementShown = function(/*Element*/ elem){
-		var s = style(elem);
-		return (s.visibility != "hidden")
-			&& (s.visibility != "collapsed")
-			&& (s.display != "none")
-			&& (attr(elem, "type") != "hidden");
-	});
-	
-	dijit.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 hasAttr(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
-					try{
-						body = elem.contentWindow.document.body;
-					}catch(e2){
-						return false;
-					}
-				}
-				return 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(attr(elem, "disabled")){
-			return false;
-		}else if(hasAttr(elem, "tabIndex")){
-			// Explicit tab index setting
-			return attr(elem, "tabIndex") >= 0; // boolean
-		}else{
-			// No explicit tabIndex setting, so depends on node type
-			return dijit.hasDefaultTabStop(elem);
-		}
+	=====*/
+	array.forEach(["byId", "getUniqueId", "findWidgets", "_destroyAll", "byNode", "getEnclosingWidget"], function(name){
+		dijit[name] = registry[name];
 	});
 
-	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();
-		}
-		var walkTree = function(/*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") || !shown(child)){
-					return;
-				}
-
-				if(isTabNavigable(child)){
-					var tabindex = attr(child, "tabIndex");
-					if(!hasAttr(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;
-						}
-					}
-					var rn = radioName(child);
-					if(dojo.attr(child, "checked") && rn) {
-						radioSelected[rn] = 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;
-		}
-		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(dojo.byId(root));
-		return elems.lowest ? elems.lowest : elems.first; // DomNode
-	};
-	
-	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(dojo.byId(root));
-		return elems.last ? elems.last : elems.highest; // DomNode
-	};
-	
 	/*=====
 	dojo.mixin(dijit, {
 		// defaultDuration: Integer
-		//		The default animation speed (in ms) to use for all Dijit
-		//		transitional animations, unless otherwise specified
+		//		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 = dojo.config["defaultDuration"] || 200;
-
-})();
-
+	dijit.defaultDuration = config["defaultDuration"] || 200;
 
-return dijit;
+	return dijit;
 });
diff --git a/dijit/_base/place.js b/dijit/_base/place.js
index 1d39c62..713bde9 100644
--- a/dijit/_base/place.js
+++ b/dijit/_base/place.js
@@ -1,366 +1,137 @@
-define("dijit/_base/place", ["dojo", "dijit", "dojo/window", "dojo/AdapterRegistry"], function(dojo, dijit) {
-
-dijit.getViewport = function(){
-	// summary:
-	//		Returns the dimensions and scroll position of the viewable area of a browser window
-
-	return dojo.window.getBox();
-};
-
-/*=====
-dijit.__Position = function(){
-	// x: Integer
-	//		horizontal coordinate in pixels, relative to document body
-	// y: Integer
-	//		vertical coordinate in pixels, relative to document body
-
-	thix.x = x;
-	this.y = y;
-}
-=====*/
-
-
-dijit.placeOnScreen = function(
-	/* DomNode */			node,
-	/* dijit.__Position */	pos,
-	/* String[] */			corners,
-	/* dijit.__Position? */	padding){
+define([
+	"dojo/_base/array", // array.forEach
+	"dojo/_base/lang", // lang.isArray
+	"dojo/window", // windowUtils.getBox
+	"../place",
+	".."	// export to dijit namespace
+], function(array, lang, windowUtils, place, dijit){
+
+	// module:
+	//		dijit/_base/place
 	// 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.
-	//	pos:
-	//		Object like {x: 10, y: 20}
-	//	corners:
-	//		Array of Strings representing order to try corners in, like ["TR", "BL"].
-	//		Possible values are:
-	//			* "BL" - bottom left
-	//			* "BR" - bottom right
-	//			* "TL" - top left
-	//			* "TR" - top right
-	//	padding:
-	//		set padding to put some buffer around the element you want to position.
-	// 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).
-	//	|	placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"])
-
-	var choices = dojo.map(corners, function(corner){
-		var c = { corner: corner, 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;
-		}
-		return c;
-	});
-
-	return dijit._place(node, choices);
-}
-
-dijit._place = function(/*DomNode*/ node, choices, layoutNode, /*Object*/ aroundNodeCoords){
-	// summary:
-	//		Given a list of spots to put node, put it at the first spot where it fits,
-	//		of if it doesn't fit anywhere then the place with the least overflow
-	// choices: Array
-	//		Array of elements like: {corner: 'TL', pos: {x: 10, y: 20} }
-	//		Above example says to put the top-left corner of the node at (10,20)
-	// layoutNode: Function(node, aroundNodeCorner, nodeCorner, size)
-	//		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.
-	//		It also passes in the available size for the popup, which is useful for tooltips to
-	//		tell them that their width is limited to a certain amount.   layoutNode() may return a value expressing
-	//		how much the popup had to be modified to fit into the available space.   This is used to determine
-	//		what the best placement is.
-	// aroundNodeCoords: Object
-	//		Size of aroundNode, ex: {w: 200, h: 50}
-
-	// get {x: 10, y: 10, w: 100, h:100} type obj representing position of
-	// viewport over document
-	var view = dojo.window.getBox();
-
-	// This won't work if the node is inside a <div style="position: relative">,
-	// so reattach it to dojo.doc.body.   (Otherwise, the positioning will be wrong
-	// and also it might get cutoff)
-	if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){
-		dojo.body().appendChild(node);
-	}
-
-	var best = null;
-	dojo.some(choices, function(choice){
-		var corner = choice.corner;
-		var pos = choice.pos;
-		var overflow = 0;
-
-		// calculate amount of space available given specified position of node
-		var spaceAvailable = {
-			w: corner.charAt(1) == 'L' ? (view.l + view.w) - pos.x : pos.x - view.l,
-			h: corner.charAt(1) == 'T' ? (view.t + view.h) - pos.y : pos.y - view.t
-		};
-
-		// 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)
-		if(layoutNode){
-			var res = layoutNode(node, choice.aroundCorner, corner, spaceAvailable, aroundNodeCoords);
-			overflow = typeof res == "undefined" ? 0 : res;
-		}
-
-		// get node's size
-		var style = node.style;
-		var oldDisplay = style.display;
-		var oldVis = style.visibility;
-		style.visibility = "hidden";
-		style.display = "";
-		var mb = dojo.marginBox(node);
-		style.display = oldDisplay;
-		style.visibility = oldVis;
-
-		// coordinates and size of node with specified corner placed at pos,
-		// and clipped by viewport
-		var startX = Math.max(view.l, corner.charAt(1) == 'L' ? pos.x : (pos.x - mb.w)),
-			startY = Math.max(view.t, corner.charAt(0) == 'T' ? pos.y : (pos.y - mb.h)),
-			endX = Math.min(view.l + view.w, corner.charAt(1) == 'L' ? (startX + mb.w) : pos.x),
-			endY = Math.min(view.t + view.h, corner.charAt(0) == 'T' ? (startY + mb.h) : pos.y),
-			width = endX - startX,
-			height = endY - startY;
-
-		overflow += (mb.w - width) + (mb.h - height);
-
-		if(best == null || overflow < best.overflow){
-			best = {
-				corner: corner,
-				aroundCorner: choice.aroundCorner,
-				x: startX,
-				y: startY,
-				w: width,
-				h: height,
-				overflow: overflow,
-				spaceAvailable: spaceAvailable
-			};
+	//		Back compatibility module, new code should use dijit/place directly instead of using this module.
+
+	dijit.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()
+
+		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;
+
+	/*=====
+	dijit.placeOnScreenAroundElement = function(node, aroundElement, 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){
+		// Convert old style {"BL": "TL", "BR": "TR"} type argument
+		// to style needed by dijit.place code:
+		//		[
+		// 			{aroundCorner: "BL", corner: "TL" },
+		//			{aroundCorner: "BR", corner: "TR" }
+		//		]
+		var positions;
+		if(lang.isArray(aroundCorners)){
+			positions = aroundCorners;
+		}else{
+			positions = [];
+			for(var key in aroundCorners){
+				positions.push({aroundCorner: key, corner: aroundCorners[key]});
+			}
 		}
-		
-		return !overflow;
-	});
-
-	// In case the best position is not the last one we checked, need to call
-	// layoutNode() again.
-	if(best.overflow && layoutNode){
-		layoutNode(node, best.aroundCorner, best.corner, best.spaceAvailable, aroundNodeCoords);
-	}
-
-	// And then position the node.   Do this last, after the layoutNode() above
-	// has sized the node, due to browser quirks when the viewport is scrolled
-	// (specifically that a Tooltip will shrink to fit as though the window was
-	// scrolled to the left).
-	//
-	// 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 = dojo._isBodyLtr(),
-		s = node.style;
-	s.top = best.y + "px";
-	s[l ? "left" : "right"] = (l ? best.x : view.w - best.x - best.w) + "px";
-	
-	return best;
-}
-
-dijit.placeOnScreenAroundNode = function(
-	/* DomNode */		node,
-	/* DomNode */		aroundNode,
-	/* Object */		aroundCorners,
-	/* Function? */		layoutNode){
 
-	// summary:
-	//		Position node adjacent or kitty-corner to aroundNode
-	//		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.
-	//
-	// aroundCorners:
-	//		Ordered list of pairs of corners to try matching up.
-	//		Each pair of corners is represented as a key/value in the hash,
-	//		where the key corresponds to the aroundNode's corner, and
-	//		the value corresponds to the node's corner:
-	//
-	//	|	{ aroundNodeCorner1: nodeCorner1, aroundNodeCorner2: nodeCorner2, ...}
-	//
-	//		The following strings are used to represent the four corners:
-	//			* "BL" - bottom left
-	//			* "BR" - bottom right
-	//			* "TL" - top left
-	//			* "TR" - top right
-	//
-	// 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:
-	//	|	dijit.placeOnScreenAroundNode(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
-	//		(ie, put node above aroundNode, with right edges aligned)
-	//
-
-	// get coordinates of aroundNode
-	aroundNode = dojo.byId(aroundNode);
-	var aroundNodePos = dojo.position(aroundNode, true);
-
-	// place the node around the calculated rectangle
-	return dijit._placeOnScreenAroundRect(node,
-		aroundNodePos.x, aroundNodePos.y, aroundNodePos.w, aroundNodePos.h,	// rectangle
-		aroundCorners, layoutNode);
-};
-
-/*=====
-dijit.__Rectangle = function(){
-	// x: Integer
-	//		horizontal offset in pixels, relative to document body
-	// y: Integer
-	//		vertical offset in pixels, relative to document body
-	// width: Integer
-	//		width in pixels
-	// height: Integer
-	//		height in pixels
-
-	this.x = x;
-	this.y = y;
-	this.width = width;
-	this.height = height;
-}
-=====*/
-
-
-dijit.placeOnScreenAroundRectangle = function(
-	/* DomNode */			node,
-	/* dijit.__Rectangle */	aroundRect,
-	/* Object */			aroundCorners,
-	/* Function */			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.
-
-	return dijit._placeOnScreenAroundRect(node,
-		aroundRect.x, aroundRect.y, aroundRect.width, aroundRect.height,	// rectangle
-		aroundCorners, layoutNode);
-};
-
-dijit._placeOnScreenAroundRect = function(
-	/* DomNode */		node,
-	/* Number */		x,
-	/* Number */		y,
-	/* Number */		width,
-	/* Number */		height,
-	/* Object */		aroundCorners,
-	/* Function */		layoutNode){
-
-	// summary:
-	//		Like dijit.placeOnScreenAroundNode(), except it accepts coordinates
-	//		of a rectangle to place node adjacent to.
-
-	// TODO: combine with placeOnScreenAroundRectangle()
-
-	// Generate list of possible positions for node
-	var choices = [];
-	for(var nodeCorner in aroundCorners){
-		choices.push( {
-			aroundCorner: nodeCorner,
-			corner: aroundCorners[nodeCorner],
-			pos: {
-				x: x + (nodeCorner.charAt(1) == 'L' ? 0 : width),
-				y: y + (nodeCorner.charAt(0) == 'T' ? 0 : height)
+		return place.around(node, aroundNode, positions, true, layoutNode);
+	};
+
+	/*=====
+	dijit.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.
+	};
+	=====*/
+	dijit.placeOnScreenAroundNode = dijit.placeOnScreenAroundElement;
+
+	/*=====
+	dijit.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.
+	};
+	=====*/
+	dijit.placeOnScreenAroundRectangle = dijit.placeOnScreenAroundElement;
+
+	dijit.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.
+		//
+		// 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
+		//
+		//		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;
+			switch(pos){
+				case "after":
+					align[leftToRight ? "BR" : "BL"] = leftToRight ? "BL" : "BR";
+					break;
+				case "before":
+					align[leftToRight ? "BL" : "BR"] = leftToRight ? "BR" : "BL";
+					break;
+				case "below-alt":
+					ltr = !ltr;
+					// fall through
+				case "below":
+					// first try to align left borders, next try to align right borders (or reverse for RTL mode)
+					align[ltr ? "BL" : "BR"] = ltr ? "TL" : "TR";
+					align[ltr ? "BR" : "BL"] = ltr ? "TR" : "TL";
+					break;
+				case "above-alt":
+					ltr = !ltr;
+					// fall through
+				case "above":
+				default:
+					// first try to align left borders, next try to align right borders (or reverse for RTL mode)
+					align[ltr ? "TL" : "TR"] = ltr ? "BL" : "BR";
+					align[ltr ? "TR" : "TL"] = ltr ? "BR" : "BL";
+					break;
 			}
 		});
-	}
-
-	return dijit._place(node, choices, layoutNode, {w: width, h: height});
-};
-
-dijit.placementRegistry= new dojo.AdapterRegistry();
-dijit.placementRegistry.register("node",
-	function(n, x){
-		return typeof x == "object" &&
-			typeof x.offsetWidth != "undefined" && typeof x.offsetHeight != "undefined";
-	},
-	dijit.placeOnScreenAroundNode);
-dijit.placementRegistry.register("rect",
-	function(n, x){
-		return typeof x == "object" &&
-			"x" in x && "y" in x && "width" in x && "height" in x;
-	},
-	dijit.placeOnScreenAroundRectangle);
-
-dijit.placeOnScreenAroundElement = function(
-	/* DomNode */		node,
-	/* Object */		aroundElement,
-	/* Object */		aroundCorners,
-	/* Function */		layoutNode){
-
-	// summary:
-	//		Like dijit.placeOnScreenAroundNode(), except it accepts an arbitrary object
-	//		for the "around" argument and finds a proper processor to place a node.
-
-	return dijit.placementRegistry.match.apply(dijit.placementRegistry, arguments);
-};
-
-dijit.getPopupAroundAlignment = function(/*Array*/ position, /*Boolean*/ leftToRight){
-	// summary:
-	//		Transforms the passed array of preferred positions into a format suitable for passing as the aroundCorners argument to dijit.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
-	//
-	//		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 = {};
-	dojo.forEach(position, function(pos){
-		switch(pos){
-			case "after":
-				align[leftToRight ? "BR" : "BL"] = leftToRight ? "BL" : "BR";
-				break;
-			case "before":
-				align[leftToRight ? "BL" : "BR"] = leftToRight ? "BR" : "BL";
-				break;
-			case "below-alt":
-				leftToRight = !leftToRight;
-				// fall through
-			case "below":
-				// first try to align left borders, next try to align right borders (or reverse for RTL mode)
-				align[leftToRight ? "BL" : "BR"] = leftToRight ? "TL" : "TR";
-				align[leftToRight ? "BR" : "BL"] = leftToRight ? "TR" : "TL";
-				break;
-			case "above-alt":
-				leftToRight = !leftToRight;
-				// fall through
-			case "above":
-			default:
-				// first try to align left borders, next try to align right borders (or reverse for RTL mode)
-				align[leftToRight ? "TL" : "TR"] = leftToRight ? "BL" : "BR";
-				align[leftToRight ? "TR" : "TL"] = leftToRight ? "BR" : "BL";
-				break;
-		}
-	});
-	return align;
-};
-
+		return align;
+	};
 
-return dijit;
+	return dijit;
 });
diff --git a/dijit/_base/popup.js b/dijit/_base/popup.js
index 42f457b..eedc453 100644
--- a/dijit/_base/popup.js
+++ b/dijit/_base/popup.js
@@ -1,393 +1,50 @@
-define("dijit/_base/popup", ["dojo", "dijit", "dijit/_base/focus", "dijit/_base/place", "dijit/_base/window"], function(dojo, dijit) {
-
-/*=====
-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 an
-	//		ordered list of tuples of the form (around-node-corner, popup-node-corner).
-	//		dijit.popup.open() tries to position the popup according to each tuple in the list, in order,
-	//		until the popup appears fully within the viewport.
-	//
-	//		The default value is {BL:'TL', TL:'BL'}, which represents a list of two tuples:
-	//			1. (BL, TL)
-	//			2. (TL, BL)
-	//		where BL means "bottom left" and "TL" means "top left".
-	//		So by default, it first tries putting the popup below the around node, left-aligning them,
-	//		and then tries to put it above the around node, still left-aligning them.   Note that the
-	//		default is horizontally reversed when in RTL mode.
-	//
-	//		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;
-}
-=====*/
-
-dijit.popup = {
-	// summary:
-	//		This singleton is used to show/hide widgets as popups.
-
-	// _stack: dijit._Widget[]
-	//		Stack of currently popped up widgets.
-	//		(someone opened _stack[0], and then it opened _stack[1], etc.)
-	_stack: [],
-	
-	// _beginZIndex: Number
-	//		Z-index of the first popup.   (If first popup opens other
-	//		popups they get a higher z-index.)
-	_beginZIndex: 1000,
-
-	_idGen: 1,
-
-	_createWrapper: function(/*Widget || DomNode*/ widget){
-		// summary:
-		//		Initialization for widgets that will be used as popups.
-		//		Puts widget inside a wrapper DIV (if not already in one),
-		//		and returns pointer to that wrapper DIV.
-
-		var wrapper = widget.declaredClass ? widget._popupWrapper : (widget.parentNode && dojo.hasClass(widget.parentNode, "dijitPopup")),
-			node = widget.domNode || widget;
-
-		if(!wrapper){
-			// 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 = dojo.create("div",{
-				"class":"dijitPopup",
-				style:{ display: "none"},
-				role: "presentation"
-			}, dojo.body());
-			wrapper.appendChild(node);
-
-			var s = node.style;
-			s.display = "";
-			s.visibility = "";
-			s.position = "";
-			s.top = "0px";
-
-			if(widget.declaredClass){		// TODO: in 2.0 change signature to always take widget, then remove if()
-				widget._popupWrapper = wrapper;
-				dojo.connect(widget, "destroy", function(){
-					dojo.destroy(wrapper);
-					delete widget._popupWrapper;
-				});
-			}
-		}
-		
-		return wrapper;
-	},
-
-	moveOffScreen: function(/*Widget || DomNode*/ 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.
-
-		// Create wrapper if not already there
-		var wrapper = this._createWrapper(widget);
-
-		dojo.style(wrapper, {
-			visibility: "hidden",
-			top: "-9999px",		// prevent transient scrollbar causing misalign (#5776), and initial flash in upper left (#10111)
-			display: ""
-		});
-	},
-
-	hide: function(/*dijit._Widget*/ 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.
-
-		// Create wrapper if not already there
-		var wrapper = this._createWrapper(widget);
-
-		dojo.style(wrapper, "display", "none");
-	},
-		
-	getTopPopup: function(){
-		// summary:
-		//		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--){
-			/* do nothing, just trying to get right value for pi */
-		}
-		return stack[pi];
-	},
-
-	open: function(/*dijit.popup.__OpenArgs*/ args){
-		// summary:
-		//		Popup the widget at the specified position
-		//
-		// example:
-		//		opening at the mouse position
-		//		|		dijit.popup.open({popup: menuWidget, x: evt.pageX, y: evt.pageY});
-		//
-		// example:
-		//		opening the widget as a dropdown
-		//		|		dijit.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.
-
-		var stack = this._stack,
-			widget = args.popup,
-			orient = args.orient || (
-				(args.parent ? args.parent.isLeftToRight() : dojo._isBodyLtr()) ?
-				{'BL':'TL', 'BR':'TR', 'TL':'BL', 'TR':'BR'} :
-				{'BR':'TR', 'BL':'TL', 'TR':'BR', 'TL':'BL'}
-			),
-			around = args.around,
-			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 || !dojo.isDescendant(args.parent.domNode, stack[stack.length-1].widget.domNode))){
-			dijit.popup.close(stack[stack.length-1].widget);
-		}
-
-		// Get pointer to popup wrapper, and create wrapper if it doesn't exist
-		var wrapper = this._createWrapper(widget);
-
-
-		dojo.attr(wrapper, {
-			id: id,
-			style: {
-				zIndex: this._beginZIndex + stack.length
-			},
-			"class": "dijitPopup " + (widget.baseClass || widget["class"] || "").split(" ")[0] +"Popup",
-			dijitPopupParent: args.parent ? args.parent.id : ""
-		});
-
-		if(dojo.isIE || dojo.isMoz){
-			if(!widget.bgIframe){
-				// setting widget.bgIframe triggers cleanup in _Widget.destroy()
-				widget.bgIframe = new dijit.BackgroundIframe(wrapper);
-			}
-		}
-
-		// position the wrapper node and make it visible
-		var best = around ?
-			dijit.placeOnScreenAroundElement(wrapper, around, orient, widget.orient ? dojo.hitch(widget, "orient") : null) :
-			dijit.placeOnScreen(wrapper, args, orient == 'R' ? ['TR','BR','TL','BL'] : ['TL','BL','TR','BR'], args.padding);
-
-		wrapper.style.display = "";
-		wrapper.style.visibility = "visible";
-		widget.domNode.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(dojo.connect(wrapper, "onkeypress", this, function(evt){
-			if(evt.charOrCode == dojo.keys.ESCAPE && args.onCancel){
-				dojo.stopEvent(evt);
-				args.onCancel();
-			}else if(evt.charOrCode === dojo.keys.TAB){
-				dojo.stopEvent(evt);
-				var topPopup = this.getTopPopup();
-				if(topPopup && topPopup.onCancel){
-					topPopup.onCancel();
-				}
-			}
-		}));
-
-		// watch for cancel/execute events on the popup and notify the caller
-		// (for a menu, "execute" means clicking an item)
-		if(widget.onCancel){
-			handlers.push(dojo.connect(widget, "onCancel", args.onCancel));
-		}
-
-		handlers.push(dojo.connect(widget, widget.onExecute ? "onExecute" : "onChange", this, function(){
-			var topPopup = this.getTopPopup();
-			if(topPopup && topPopup.onExecute){
-				topPopup.onExecute();
-			}
-		}));
-
-		stack.push({
-			widget: widget,
-			parent: args.parent,
-			onExecute: args.onExecute,
-			onCancel: args.onCancel,
- 			onClose: args.onClose,
-			handlers: handlers
-		});
-
-		if(widget.onOpen){
-			// TODO: in 2.0 standardize onShow() (used by StackContainer) and onOpen() (used here)
-			widget.onOpen(best);
-		}
-
-		return best;
-	},
-
-	close: function(/*dijit._Widget?*/ popup){
-		// summary:
-		//		Close specified popup and any popups that it parented.
-		//		If no popup is specified, closes all popups.
-
-		var stack = this._stack;
-
-		// Basically work backwards from the top of the stack closing popups
-		// until we hit the specified popup, but IIRC there was some issue where closing
-		// 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 && dojo.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)
-				widget.onClose();
-			}
-			dojo.forEach(top.handlers, dojo.disconnect);
-
-			// Hide the widget and it's wrapper unless it has already been destroyed in above onClose() etc.
-			if(widget && widget.domNode){
-				this.hide(widget);
-			}
-                        
-			if(onClose){
-				onClose();
-			}
-		}
+define([
+	"dojo/dom-class", // domClass.contains
+	"../popup",
+	"../BackgroundIframe"	// just loading for back-compat, in case client code is referencing it
+], function(domClass, popup){
+
+// module:
+//		dijit/_base/popup
+// summary:
+//		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)
+var origCreateWrapper = popup._createWrapper;
+popup._createWrapper = function(widget){
+	if(!widget.declaredClass){
+		// make fake widget to pass to new API
+		widget = {
+			_popupWrapper: (widget.parentNode && domClass.contains(widget.parentNode, "dijitPopup")) ?
+				widget.parentNode : null,
+			domNode: widget,
+			destroy: function(){}
+		};
 	}
+	return origCreateWrapper.call(this, widget);
 };
 
-// TODO: remove dijit._frames, it isn't being used much, since popups never release their
-// iframes (see [22236])
-dijit._frames = new function(){
-	// summary:
-	//		cache of iframes
-
-	var queue = [];
-
-	this.pop = function(){
-		var iframe;
-		if(queue.length){
-			iframe = queue.pop();
-			iframe.style.display="";
-		}else{
-			if(dojo.isIE < 9){
-				var burl = dojo.config["dojoBlankHtmlUrl"] || (dojo.moduleUrl("dojo", "resources/blank.html")+"") || "javascript:\"\"";
-				var html="<iframe src='" + burl + "'"
-					+ " style='position: absolute; left: 0px; top: 0px;"
-					+ "z-index: -1; filter:Alpha(Opacity=\"0\");'>";
-				iframe = dojo.doc.createElement(html);
-			}else{
-			 	iframe = dojo.create("iframe");
-				iframe.src = 'javascript:""';
-				iframe.className = "dijitBackgroundIframe";
-				dojo.style(iframe, "opacity", 0.1);
-			}
-			iframe.tabIndex = -1; // Magic to prevent iframe from getting focus on tab keypress - as style didn't work.
-			dijit.setWaiRole(iframe,"presentation");
-		}
-		return iframe;
-	};
-
-	this.push = function(iframe){
-		iframe.style.display="none";
-		queue.push(iframe);
+// Support old format of orient parameter
+var origOpen = popup.open;
+popup.open = function(/*dijit.popup.__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)
+	//		- "R" or "L" strings used to indicate positioning for context menus (when there is no around node)
+	//		- new format, ex: ["below", "above"]
+	//		- return value from deprecated dijit.getPopupAroundAlignment() method,
+	//			ex: ["below", "above"]
+	if(args.orient && typeof args.orient != "string" && !("length" in args.orient)){
+		var ary = [];
+		for(var key in args.orient){
+			ary.push({aroundCorner: key, corner: args.orient[key]});
+		}
+		args.orient = ary;
 	}
-}();
 
-
-dijit.BackgroundIframe = function(/*DomNode*/ node){
-	// summary:
-	//		For IE/FF z-index schenanigans. 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
-
-	if(!node.id){ throw new Error("no id"); }
-	if(dojo.isIE || dojo.isMoz){
-		var iframe = (this.iframe = dijit._frames.pop());
-		node.appendChild(iframe);
-		if(dojo.isIE<7 || dojo.isQuirks){
-			this.resize(node);
-			this._conn = dojo.connect(node, 'onresize', this, function(){
-				this.resize(node);
-			});
-		}else{
-			dojo.style(iframe, {
-				width: '100%',
-				height: '100%'
-			});
-		}
-	}
+	return origOpen.call(this, args);
 };
 
-dojo.extend(dijit.BackgroundIframe, {
-	resize: function(node){
-		// summary:
-		// 		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){
-			dojo.style(this.iframe, {
-				width: node.offsetWidth + 'px',
-				height: node.offsetHeight + 'px'
-			});
-		}
-	},
-	destroy: function(){
-		// summary:
-		//		destroy the iframe
-		if(this._conn){
-			dojo.disconnect(this._conn);
-			this._conn = null;
-		}
-		if(this.iframe){
-			dijit._frames.push(this.iframe);
-			delete this.iframe;
-		}
-	}
-});
-
-return dijit.popup;
+return popup;
 });
diff --git a/dijit/_base/scroll.js b/dijit/_base/scroll.js
index 6a3508e..a341a4b 100644
--- a/dijit/_base/scroll.js
+++ b/dijit/_base/scroll.js
@@ -1,13 +1,17 @@
-define("dijit/_base/scroll", ["dojo", "dijit", "dojo/window"], function(dojo, dijit) {
-
-dijit.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
+define([
+	"dojo/window", // windowUtils.scrollIntoView
+	".."	// export symbol to dijit
+], function(windowUtils, dijit){
+	// module:
+	//		dijit/_base/scroll
 	// summary:
-	//		Scroll the passed node into view, if it is not already.
-	//		Deprecated, use `dojo.window.scrollIntoView` instead.
-	
-	dojo.window.scrollIntoView(node, pos);
-};
+	//		Back compatibility module, new code should use windowUtils directly instead of using this module.
 
+	dijit.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
+		// summary:
+		//		Scroll the passed node into view, if it is not already.
+		//		Deprecated, use `windowUtils.scrollIntoView` instead.
 
-return dijit.scrollIntoView;
+		windowUtils.scrollIntoView(node, pos);
+	};
 });
diff --git a/dijit/_base/sniff.js b/dijit/_base/sniff.js
index 9524e85..450be52 100644
--- a/dijit/_base/sniff.js
+++ b/dijit/_base/sniff.js
@@ -1,12 +1,6 @@
-define("dijit/_base/sniff", ["dojo", "dijit", "dojo/uacss"], function(dojo, dijit) {
-
-// summary:
-//		Applies pre-set CSS classes to the top-level HTML node, see
-//		`dojo.uacss` for details.
-//
-//		Simply doing a require on this module will
-//		establish this CSS.  Modified version of Morris' CSS hack.
-
-
-return dijit;
+define([ "dojo/uacss" ], function(){
+	// module:
+	//		dijit/_base/sniff
+	// summary:
+	//		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 2054683..62017b4 100644
--- a/dijit/_base/typematic.js
+++ b/dijit/_base/typematic.js
@@ -1,183 +1,3 @@
-define("dijit/_base/typematic", ["dojo", "dijit"], function(dojo, dijit) {
-
-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(dojo.hitch(this, "_fireEventAndReload"), this._currentTimeout);
-	},
-
-	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 (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 = dojo.hitch(_this, callback);
-			this._fireEventAndReload();
-			this._evt = dojo.mixin({faux: true}, evt);
-		}
-	},
-
-	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:
-		// 		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:
-		//		an array of dojo.connect handles
-		if(keyObject.keyCode){
-			keyObject.charOrCode = keyObject.keyCode;
-			dojo.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);
-			dojo.deprecated("charCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.", "", "2.0");
-		}
-		return [
-			dojo.connect(node, "onkeypress", 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)){
-					dojo.stopEvent(evt);
-					dijit.typematic.trigger(evt, _this, node, callback, keyObject, subsequentDelay, initialDelay, minDelay);
-				}else if(dijit.typematic._obj == keyObject){
-					dijit.typematic.stop();
-				}
-			}),
-			dojo.connect(node, "onkeyup", this, function(evt){
-				if(dijit.typematic._obj == keyObject){
-					dijit.typematic.stop();
-				}
-			})
-		];
-	},
-
-	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:
-		//		an array of dojo.connect handles
-		var dc = dojo.connect;
-		return [
-			dc(node, "mousedown", this, function(evt){
-				dojo.stopEvent(evt);
-				dijit.typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay, minDelay);
-			}),
-			dc(node, "mouseup", this, function(evt){
-				dojo.stopEvent(evt);
-				dijit.typematic.stop();
-			}),
-			dc(node, "mouseout", this, function(evt){
-				dojo.stopEvent(evt);
-				dijit.typematic.stop();
-			}),
-			dc(node, "mousemove", this, function(evt){
-				evt.preventDefault();
-			}),
-			dc(node, "dblclick", this, function(evt){
-				dojo.stopEvent(evt);
-				if(dojo.isIE){
-					dijit.typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay, minDelay);
-					setTimeout(dojo.hitch(this, dijit.typematic.stop), 50);
-				}
-			})
-		];
-	},
-
-	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:
-		//		an array of dojo.connect handles
-		return this.addKeyListener(keyNode, keyObject, _this, callback, subsequentDelay, initialDelay, minDelay).concat(
-			this.addMouseListener(mouseNode, _this, callback, subsequentDelay, initialDelay, minDelay));
-	}
-};
-
-
-return dijit.typematic;
+define(["../typematic"], function(){
+	// for back-compat, just loads top level module
 });
diff --git a/dijit/_base/wai.js b/dijit/_base/wai.js
index c631934..1f93945 100644
--- a/dijit/_base/wai.js
+++ b/dijit/_base/wai.js
@@ -1,137 +1,105 @@
-define("dijit/_base/wai", ["dojo", "dijit"], function(dojo, dijit) {
-
-dijit.wai = {
-	onload: function(){
-		// summary:
-		//		Detects if we are in high-contrast mode or not
-
-		// This must be a named function and not an anonymous
-		// function, so that the widget parsing code can make sure it
-		// registers its onload function after this function.
-		// DO NOT USE "this" within this function.
-
-		// create div for testing if high contrast mode is on or images are turned off
-		var div = dojo.create("div",{
-			id: "a11yTestNode",
-			style:{
-				cssText:'border: 1px solid;'
-					+ 'border-color:red green;'
-					+ 'position: absolute;'
-					+ 'height: 5px;'
-					+ 'top: -999px;'
-					+ 'background-image: url("' + (dojo.config.blankGif || dojo.moduleUrl("dojo", "resources/blank.gif")) + '");'
-			}
-		}, dojo.body());
-
-		// test it
-		var cs = dojo.getComputedStyle(div);
-		if(cs){
-			var bkImg = cs.backgroundImage;
-			var needsA11y = (cs.borderTopColor == cs.borderRightColor) || (bkImg != null && (bkImg == "none" || bkImg == "url(invalid-url:)" ));
-			dojo[needsA11y ? "addClass" : "removeClass"](dojo.body(), "dijit_a11y");
-			if(dojo.isIE){
-				div.outerHTML = "";		// prevent mixed-content warning, see http://support.microsoft.com/kb/925014
+define([
+	"dojo/dom-attr", // domAttr.attr
+	"dojo/_base/lang", // lang.mixin
+	"..",	// 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, {
+		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
+			var waiRole = this.getWaiRole(elem);
+			return role ? (waiRole.indexOf(role) > -1) : (waiRole.length > 0);
+		},
+
+		getWaiRole: function(/*Element*/ elem){
+			// summary:
+			//		Gets the role for an element (which should be a wai role).
+			// returns:
+			//		The role of elem or an empty string if elem
+			//		does not have a role.
+			 return lang.trim((domAttr.get(elem, "role") || "").replace("wairole:",""));
+		},
+
+		setWaiRole: function(/*Element*/ elem, /*String*/ role){
+			// summary:
+			//		Sets the role on an element.
+			// description:
+			//		Replace existing role attribute with new role.
+
+			domAttr.set(elem, "role", role);
+		},
+
+		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.)
+
+			var roleValue = domAttr.get(elem, "role");
+			if(!roleValue){ return; }
+			if(role){
+				var t = lang.trim((" " + roleValue + " ").replace(" " + role + " ", " "));
+				domAttr.set(elem, "role", t);
 			}else{
-				dojo.body().removeChild(div);
+				elem.removeAttribute("role");
 			}
+		},
+
+		hasWaiState: function(/*Element*/ elem, /*String*/ state){
+			// summary:
+			//		Determines if an element has a given state.
+			// description:
+			//		Checks for an attribute called "aria-"+state.
+			// returns:
+			//		true if elem has a value for the given state and
+			//		false if it does not.
+
+			return elem.hasAttribute ? elem.hasAttribute("aria-"+state) : !!elem.getAttribute("aria-"+state);
+		},
+
+		getWaiState: function(/*Element*/ elem, /*String*/ state){
+			// summary:
+			//		Gets the value of a state on an element.
+			// description:
+			//		Checks for an attribute called "aria-"+state.
+			// returns:
+			//		The value of the requested state on elem
+			//		or an empty string if elem has no value for state.
+
+			return elem.getAttribute("aria-"+state) || "";
+		},
+
+		setWaiState: function(/*Element*/ elem, /*String*/ state, /*String*/ value){
+			// summary:
+			//		Sets a state on an element.
+			// description:
+			//		Sets an attribute called "aria-"+state.
+
+			elem.setAttribute("aria-"+state, value);
+		},
+
+		removeWaiState: function(/*Element*/ elem, /*String*/ state){
+			// summary:
+			//		Removes a state from an element.
+			// description:
+			//		Sets an attribute called "aria-"+state.
+
+			elem.removeAttribute("aria-"+state);
 		}
-	}
-};
-
-// Test if computer is in high contrast mode.
-// Make sure the a11y test runs first, before widgets are instantiated.
-if(dojo.isIE || dojo.isMoz){	// NOTE: checking in Safari messes things up
-	dojo._loaders.unshift(dijit.wai.onload);
-}
-
-dojo.mixin(dijit, {
-	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
-		var waiRole = this.getWaiRole(elem);
-		return role ? (waiRole.indexOf(role) > -1) : (waiRole.length > 0);
-	},
-
-	getWaiRole: function(/*Element*/ elem){
-		// summary:
-		//		Gets the role for an element (which should be a wai role).
-		// returns:
-		//		The role of elem or an empty string if elem
-		//		does not have a role.
-		 return dojo.trim((dojo.attr(elem, "role") || "").replace("wairole:",""));
-	},
-
-	setWaiRole: function(/*Element*/ elem, /*String*/ role){
-		// summary:
-		//		Sets the role on an element.
-		// description:
-		//		Replace existing role attribute with new role.
-
-			dojo.attr(elem, "role", role);
-	},
-
-	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.)
-
-		var roleValue = dojo.attr(elem, "role");
-		if(!roleValue){ return; }
-		if(role){
-			var t = dojo.trim((" " + roleValue + " ").replace(" " + role + " ", " "));
-			dojo.attr(elem, "role", t);
-		}else{
-			elem.removeAttribute("role");
-		}
-	},
-
-	hasWaiState: function(/*Element*/ elem, /*String*/ state){
-		// summary:
-		//		Determines if an element has a given state.
-		// description:
-		//		Checks for an attribute called "aria-"+state.
-		// returns:
-		//		true if elem has a value for the given state and
-		//		false if it does not.
-
-		return elem.hasAttribute ? elem.hasAttribute("aria-"+state) : !!elem.getAttribute("aria-"+state);
-	},
-
-	getWaiState: function(/*Element*/ elem, /*String*/ state){
-		// summary:
-		//		Gets the value of a state on an element.
-		// description:
-		//		Checks for an attribute called "aria-"+state.
-		// returns:
-		//		The value of the requested state on elem
-		//		or an empty string if elem has no value for state.
-
-		return elem.getAttribute("aria-"+state) || "";
-	},
-
-	setWaiState: function(/*Element*/ elem, /*String*/ state, /*String*/ value){
-		// summary:
-		//		Sets a state on an element.
-		// description:
-		//		Sets an attribute called "aria-"+state.
-
-		elem.setAttribute("aria-"+state, value);
-	},
-
-	removeWaiState: function(/*Element*/ elem, /*String*/ state){
-		// summary:
-		//		Removes a state from an element.
-		// description:
-		//		Sets an attribute called "aria-"+state.
-
-		elem.removeAttribute("aria-"+state);
-	}
-});
-
+	});
 
-return dijit;
+	return dijit;
 });
diff --git a/dijit/_base/window.js b/dijit/_base/window.js
index 0bf2322..4015ea3 100644
--- a/dijit/_base/window.js
+++ b/dijit/_base/window.js
@@ -1,9 +1,13 @@
-define("dijit/_base/window", ["dojo", "dijit", "dojo/window"], function(dojo, dijit) {
+define([
+	"dojo/window", // windowUtils.get
+	".."	// 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.
 
-dijit.getDocumentWindow = function(doc){
-	return dojo.window.get(doc);
-};
-
-
-return dijit;
+	dijit.getDocumentWindow = function(doc){
+		return windowUtils.get(doc);
+	};
 });
diff --git a/dijit/_editor/RichText.js b/dijit/_editor/RichText.js
index a5c19ec..a2e1ebf 100644
--- a/dijit/_editor/RichText.js
+++ b/dijit/_editor/RichText.js
@@ -1,50 +1,72 @@
-define("dijit/_editor/RichText", ["dojo", "dijit", "dijit/_Widget", "dijit/_CssStateMixin", "dijit/_editor/selection", "dijit/_editor/range", "dijit/_editor/html"], function(dojo, dijit) {
-
-// used to restore content when user leaves this page then comes back
-// but do not try doing dojo.doc.write if we are using xd loading.
-// dojo.doc.write will only work if RichText.js is included in the dojo.js
-// file. If it is included in dojo.js and you want to allow rich text saving
-// for back/forward actions, then set dojo.config.allowXdRichTextSave = true.
-if(!dojo.config["useXDomain"] || dojo.config["allowXdRichTextSave"]){
-	if(dojo._postLoad){
-		(function(){
-			var savetextarea = dojo.doc.createElement('textarea');
-			savetextarea.id = dijit._scopeName + "._editor.RichText.value";
-			dojo.style(savetextarea, {
-				display:'none',
-				position:'absolute',
-				top:"-100px",
-				height:"3px",
-				width:"3px"
-			});
-			dojo.body().appendChild(savetextarea);
-		})();
-	}else{
-		//dojo.body() is not available before onLoad is fired
-		try{
-			dojo.doc.write('<textarea id="' + dijit._scopeName + '._editor.RichText.value" ' +
-				'style="display:none;position:absolute;top:-100px;left:-100px;height:3px;width:3px;overflow:hidden;"></textarea>');
-		}catch(e){ }
-	}
-}
+define([
+	"dojo/_base/array", // array.forEach array.indexOf array.some
+	"dojo/_base/config", // config
+	"dojo/_base/declare", // declare
+	"dojo/_base/Deferred", // Deferred
+	"dojo/dom", // dom.byId
+	"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-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/_base/unload", // unload
+	"dojo/_base/url", // url
+	"dojo/_base/window", // win.body win.doc.body.focus win.doc.createElement win.global.location win.withGlobal
+	"../_Widget",
+	"../_CssStateMixin",
+	"./selection",
+	"./range",
+	"./html",
+	"../focus",
+	".."	// 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
 
-dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 	constructor: function(params){
-		// 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
-
 		// contentPreFilters: Function(String)[]
 		//		Pre content filter function register array.
 		//		these filters will be executed before the actual
@@ -80,11 +102,11 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 
 		this._keyHandlers = {};
 
-		if(params && dojo.isString(params.value)){
+		if(params && lang.isString(params.value)){
 			this.value = params.value;
 		}
 
-		this.onLoadDeferred = new dojo.Deferred();
+		this.onLoadDeferred = new Deferred();
 	},
 
 	baseClass: "dijitEditor",
@@ -151,30 +173,31 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 	disableSpellCheck: false,
 
 	postCreate: function(){
-		if("textarea" == this.domNode.tagName.toLowerCase()){
+		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 = [dojo.hitch(this, "_preFixUrlAttributes")].concat(this.contentPreFilters);
-		if(dojo.isMoz){
+		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(dojo.isWebKit){
+		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(dojo.isIE){
+		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);
 
-		dojo.publish(dijit._scopeName + "._editor.RichText::init", [this]);
+		topic.publish(dijit._scopeName + "._editor.RichText::init", this);
 		this.open();
 		this.setupDefaultShortcuts();
 	},
@@ -183,13 +206,13 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		// summary:
 		//		Add some default key handlers
 		// description:
-		// 		Overwrite this to setup your own handlers. The default
-		// 		implementation does not use Editor commands, but directly
+		//		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 = dojo.hitch(this, function(cmd, arg){
+		var exec = lang.hitch(this, function(cmd, arg){
 			return function(){
 				return !this.execCommand(cmd,arg);
 			};
@@ -211,11 +234,12 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			"\\": exec("insertunorderedlist")
 		};
 
-		if(!dojo.isIE){
+		if(!has("ie")){
 			ctrlKeyHandlers.Z = exec("redo"); //FIXME: undo?
 		}
 
-		for(var key in ctrlKeyHandlers){
+		var key;
+		for(key in ctrlKeyHandlers){
 			this.addKeyHandler(key, true, false, ctrlKeyHandlers[key]);
 		}
 	},
@@ -240,17 +264,17 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		Handle that here.
 		// tags:
 		//		private
-		if(dijit._editor._editorCommandsLocalized){
-			// Use the already generate cache of mappings.  
-			this._local2NativeFormatNames = dijit._editor._local2NativeFormatNames;
-			this._native2LocalFormatNames = dijit._editor._native2LocalFormatNames;
+		if(RichText._editorCommandsLocalized){
+			// Use the already generate cache of mappings.
+			this._local2NativeFormatNames = RichText._local2NativeFormatNames;
+			this._native2LocalFormatNames = RichText._native2LocalFormatNames;
 			return;
 		}
-		dijit._editor._editorCommandsLocalized = true;
-		dijit._editor._local2NativeFormatNames = {};
-		dijit._editor._native2LocalFormatNames = {};
-		this._local2NativeFormatNames = dijit._editor._local2NativeFormatNames;
-		this._native2LocalFormatNames = dijit._editor._native2LocalFormatNames;
+		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
@@ -270,22 +294,22 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		// 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 = dojo.create('div', {style: style, innerHTML: localhtml});
-		dojo.body().appendChild(div);
+		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 = dojo.hitch(this, function(){
+		var inject = lang.hitch(this, function(){
 			var node = div.firstChild;
 			while(node){
 				try{
-					dijit._editor.selection.selectElement(node.firstChild);
+					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 */ }
+				}catch(e){ /*Sqelch the occasional IE9 error */ }
 			}
 			div.parentNode.removeChild(div);
 			div.innerHTML = "";
@@ -304,13 +328,13 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		private
 
 		if(!this.onLoadDeferred || this.onLoadDeferred.fired >= 0){
-			this.onLoadDeferred = new dojo.Deferred();
+			this.onLoadDeferred = new Deferred();
 		}
 
 		if(!this.isClosed){ this.close(); }
-		dojo.publish(dijit._scopeName + "._editor.RichText::open", [ this ]);
+		topic.publish(dijit._scopeName + "._editor.RichText::open", this);
 
-		if(arguments.length == 1 && element.nodeName){ // else unchanged
+		if(arguments.length === 1 && element.nodeName){ // else unchanged
 			this.domNode = element;
 		}
 
@@ -320,7 +344,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		// initialize the editor.
 		var html;
 
-		if(dojo.isString(this.value)){
+		if(lang.isString(this.value)){
 			// Allow setting the editor content programmatically instead of
 			// relying on the initial content being contained within the target
 			// domNode.
@@ -333,28 +357,28 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			var ta = (this.textarea = dn);
 			this.name = ta.name;
 			html = ta.value;
-			dn = this.domNode = dojo.doc.createElement("div");
+			dn = this.domNode = win.doc.createElement("div");
 			dn.setAttribute('widgetId', this.id);
 			ta.removeAttribute('widgetId');
 			dn.cssText = ta.cssText;
 			dn.className += " " + ta.className;
-			dojo.place(dn, ta, "before");
-			var tmpFunc = dojo.hitch(this, function(){
+			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
-				dojo.style(ta, {
+				domStyle.set(ta, {
 					display: "block",
 					position: "absolute",
 					top: "-1000px"
 				});
 
-				if(dojo.isIE){ //nasty IE bug: abnormal formatting if overflow is not hidden
+				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(dojo.isIE){
+			if(has("ie")){
 				setTimeout(tmpFunc, 10);
 			}else{
 				tmpFunc();
@@ -364,34 +388,30 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 				var resetValue = ta.value;
 				this.reset = function(){
 					var current = this.getValue();
-					if(current != resetValue){
+					if(current !== resetValue){
 						this.replaceValue(resetValue);
 					}
 				};
-				dojo.connect(ta.form, "onsubmit", this, function(){
+				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?
-					dojo.attr(ta, 'disabled', this.disabled); // don't submit the value if disabled
+					domAttr.set(ta, 'disabled', this.disabled); // don't submit the value if disabled
 					ta.value = this.getValue();
-				});
+				}));
 			}
 		}else{
-			html = dijit._editor.getChildrenHtml(dn);
+			html = htmlapi.getChildrenHtml(dn);
 			dn.innerHTML = "";
 		}
 
-		var content = dojo.contentBox(dn);
-		this._oldHeight = content.h;
-		this._oldWidth = content.w;
-
 		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"){
+		if(dn.nodeName && dn.nodeName === "LI"){
 			dn.innerHTML = " <br>";
 		}
-	
+
 		// Construct the editor div structure.
 		this.header = dn.ownerDocument.createElement("div");
 		dn.appendChild(this.header);
@@ -407,13 +427,13 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		// 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 !== "" && (!dojo.config["useXDomain"] || dojo.config["allowXdRichTextSave"])){
-			var saveTextarea = dojo.byId(dijit._scopeName + "._editor.RichText.value");
+		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){
+					if(data[0] === this.name){
 						html = data[1];
 						datas = datas.splice(i, 1);
 						saveTextarea.value = datas.join(this._SEPARATOR);
@@ -422,24 +442,24 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 				}
 			}
 
-			if(!dijit._editor._globalSaveHandler){
-				dijit._editor._globalSaveHandler = {};
-				dojo.addOnUnload(function() {
+			if(!RichText._globalSaveHandler){
+				RichText._globalSaveHandler = {};
+				unload.addOnUnload(function(){
 					var id;
-					for(id in dijit._editor._globalSaveHandler){
-						var f = dijit._editor._globalSaveHandler[id];
-						if(dojo.isFunction(f)){
+					for(id in RichText._globalSaveHandler){
+						var f = RichText._globalSaveHandler[id];
+						if(lang.isFunction(f)){
 							f();
 						}
 					}
 				});
 			}
-			dijit._editor._globalSaveHandler[this.id] = dojo.hitch(this, "_saveContent");
+			RichText._globalSaveHandler[this.id] = lang.hitch(this, "_saveContent");
 		}
 
 		this.isClosed = false;
 
-		var ifr = (this.editorObject = this.iframe = dojo.doc.createElement('iframe'));
+		var ifr = (this.editorObject = this.iframe = win.doc.createElement('iframe'));
 		ifr.id = this.id+"_iframe";
 		this._iframeSrc = this._getIframeDocTxt();
 		ifr.style.border = "none";
@@ -449,7 +469,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			// <div> (which has the correct height set by Editor)
 			ifr.style.height = "100%";
 		}else{
-			if(dojo.isIE >= 7){
+			if(has("ie") >= 7){
 				if(this.height){
 					ifr.style.height = this.height;
 				}
@@ -461,26 +481,28 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			}
 		}
 		ifr.frameBorder = 0;
-		ifr._loadFunc = dojo.hitch( this, function(win){
-			this.window = win;
+		ifr._loadFunc = lang.hitch( this, function(w){
+			this.window = w;
 			this.document = this.window.document;
 
-			if(dojo.isIE){
+			if(has("ie")){
 				this._localizeEditorCommands();
 			}
-			
+
 			// Do final setup and set initial contents of editor
 			this.onLoad(html);
 		});
 
 		// Set the iframe's initial (blank) content.
-		var s = 'javascript:parent.' + dijit._scopeName + '.byId("'+this.id+'")._iframeSrc';
+		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);
 
-		if(dojo.isSafari <= 4){
+		if(has("safari") <= 4){
 			var src = ifr.getAttribute("src");
-			if(!src || src.indexOf("javascript") == -1){
+			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);
@@ -488,11 +510,11 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		}
 
 		// TODO: this is a guess at the default line-height, kinda works
-		if(dn.nodeName == "LI"){
+		if(dn.nodeName === "LI"){
 			dn.lastChild.style.marginTop = "-1.2em";
 		}
 
-		dojo.addClass(this.domNode, this.baseClass);
+		domClass.add(this.domNode, this.baseClass);
 	},
 
 	//static cache variables shared among all instance of this class
@@ -505,21 +527,21 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		Editor content (if not blank) should be added afterwards.
 		// tags:
 		//		private
-		var _cs = dojo.getComputedStyle(this.domNode);
+		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(dojo.isIE || dojo.isWebKit || (!this.height && !dojo.isMoz)){
+		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(dojo.isMoz){
+		}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 = " ";
+			html = " ";	//  
 		}
 
 		var font = [ _cs.fontWeight, _cs.fontSize, _cs.fontFamily ].join(" ");
@@ -544,7 +566,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			match = match.replace(/^;/ig,"") + ';';
 			var s = match.split(":")[0];
 			if(s){
-				s = dojo.trim(s);
+				s = lang.trim(s);
 				s = s.toLowerCase();
 				var i;
 				var sC = "";
@@ -558,18 +580,18 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 							sC += c;
 					}
 				}
-				dojo.style(self.domNode, sC, "");
+				domStyle.set(self.domNode, sC, "");
 			}
 			userStyle += match + ';';
 		});
 
 
 		// need to find any associated label element and update iframe document title
-		var label=dojo.query('label[for="'+this.id+'"]');
+		var label=query('label[for="'+this.id+'"]');
 
 		return [
 			this.isLeftToRight() ? "<html>\n<head>\n" : "<html dir='rtl'>\n<head>\n",
-			(dojo.isMoz && label.length ? "<title>" + label[0].innerHTML + "</title>\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",
@@ -580,10 +602,10 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			// 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.
-			((dojo.isWebKit)?"\t\twidth: 100%;\n":""),
-			((dojo.isWebKit)?"\t\theight: 100%;\n":""),
+			((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",
@@ -591,13 +613,13 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			"\t\tleft:0px;\n",
 			"\t\tright:0px;\n",
 			"\t\tfont:", font, ";\n",
-				((this.height||dojo.isOpera) ? "" : "\t\tposition: fixed;\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.
@@ -605,7 +627,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			"\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.
-			(!dojo.isIE ? "\tli{ min-height:1.2em; }\n" : ""), 
+			(!has("ie") ? "\tli{ min-height:1.2em; }\n" : ""),
 			"</style>\n",
 			this._applyEditingAreaStyleSheets(),"\n",
 			"</head>\n<body ",
@@ -631,7 +653,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 
 		var text='', i=0, url;
 		while((url=files[i++])){
-			var abstring = (new dojo._Url(dojo.global.location, url)).toString();
+			var abstring = (new _Url(win.global.location, url)).toString();
 			this.editingAreaStyleSheets.push(abstring);
 			text += '<link rel="stylesheet" type="text/css" href="'+abstring+'"/>';
 		}
@@ -646,17 +668,17 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		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 dojo._Url(dojo.global.location, url)).toString();
+		if(url.charAt(0) === '.' || (url.charAt(0) !== '/' && !uri.host)){
+			url = (new _Url(win.global.location, url)).toString();
 		}
 
-		if(dojo.indexOf(this.editingAreaStyleSheets, url) > -1){
+		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.addCallback(dojo.hitch(this, function(){
+		this.onLoadDeferred.addCallback(lang.hitch(this, function(){
 			if(this.document.createStyleSheet){ //IE
 				this.document.createStyleSheet(url);
 			}else{ //other browser
@@ -675,16 +697,16 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		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 dojo._Url(dojo.global.location, url)).toString();
+		if(url.charAt(0) === '.' || (url.charAt(0) !== '/' && !uri.host)){
+			url = (new _Url(win.global.location, url)).toString();
 		}
-		var index = dojo.indexOf(this.editingAreaStyleSheets, url);
-		if(index == -1){
+		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];
-		dojo.withGlobal(this.window,'query', dojo, ['link:[href="'+url+'"]']).orphan();
+		win.withGlobal(this.window,'query', dojo, ['link:[href="'+url+'"]']).orphan();
 	},
 
 	// disabled: Boolean
@@ -696,13 +718,17 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		value = !!value;
 		this._set("disabled", value);
 		if(!this.isLoaded){ return; } // this method requires init to be complete
-		if(dojo.isIE || dojo.isWebKit || dojo.isOpera){
-			var preventIEfocus = dojo.isIE && (this.isLoaded || !this.focusOnLoad);
+		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(){ _this.editNode.unselectable = "off"; }, 0);
+				setTimeout(function(){
+					if(_this.editNode){		// guard in case widget destroyed before timeout
+						_this.editNode.unselectable = "off";
+					}
+				}, 0);
 			}
 		}else{ //moz
 			try{
@@ -710,7 +736,8 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			}catch(e){ return; } // ! _disabledOK
 			if(!value && this._mozSettingProps){
 				var ps = this._mozSettingProps;
-				for(var n in ps){
+				var n;
+				for(n in ps){
 					if(ps.hasOwnProperty(n)){
 						try{
 							this.document.execCommand(n,false,ps[n]);
@@ -741,16 +768,16 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 
 		if(!this.window.__registeredWindow){
 			this.window.__registeredWindow = true;
-			this._iframeRegHandle = dijit.registerIframe(this.iframe);
+			this._iframeRegHandle = focus.registerIframe(this.iframe);
 		}
-		if(!dojo.isIE && !dojo.isWebKit && (this.height || dojo.isMoz)){
+		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(dojo.isIE){ // #4996 IE wants to focus the BODY tag
-				this.tabStop = dojo.create('div', { tabIndex: -1 }, this.editingArea);
+			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(); };
 			}
 		}
@@ -759,13 +786,13 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 
 		var events = this.events.concat(this.captureEvents);
 		var ap = this.iframe ? this.document : this.editNode;
-		dojo.forEach(events, function(item){
+		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(dojo.isIE){ // IE contentEditable
+		if(has("ie")){ // IE contentEditable
 			this.connect(this.document, "onmousedown", "_onIEMouseDown"); // #4996 fix focus
 
 			// give the node Layout on IE
@@ -782,8 +809,8 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 				delete this._cursorToStart;
 			});
 		}
-		
-		if(dojo.isWebKit){
+
+		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
@@ -794,12 +821,12 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 				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(dojo.hitch(this, "placeCursorAtEnd"), 0);
+					setTimeout(lang.hitch(this, "placeCursorAtEnd"), 0);
 				}
 			});
 		}
-		
-		if(dojo.isIE){
+
+		if(has("ie")){
 			// Try to make sure 'hidden' elements aren't visible in edit mode (like browsers other than IE
 			// do).  See #9103
 			try{
@@ -816,7 +843,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		// 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 = dojo.hitch(this, function(){
+		var setContent = lang.hitch(this, function(){
 			this.setValue(html);
 			if(this.onLoadDeferred){
 				this.onLoadDeferred.callback(true);
@@ -825,7 +852,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			if(this.focusOnLoad){
 				// after the document loads, then set focus after updateInterval expires so that
 				// onNormalizedDisplayChanged has run to avoid input caret issues
-				dojo.addOnLoad(dojo.hitch(this, function(){ setTimeout(dojo.hitch(this, "focus"), this.updateInterval); }));
+				ready(lang.hitch(this, function(){ setTimeout(lang.hitch(this, "focus"), this.updateInterval); }));
 			}
 			// Save off the initial content now
 			this.value = this.getValue(true);
@@ -847,8 +874,8 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		// 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.
 
-		if(e.keyCode === dojo.keys.TAB && this.isTabIndent ){
-			dojo.stopEvent(e); //prevent tab from moving focus out of editor
+		if(e.keyCode === keys.TAB && this.isTabIndent ){
+			event.stop(e); //prevent tab from moving focus out of editor
 
 			// FIXME: this is a poor-man's indent/outdent. It would be
 			// better if it added 4 " " chars in an undoable way.
@@ -857,8 +884,8 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 				this.execCommand((e.shiftKey ? "outdent" : "indent"));
 			}
 		}
-		if(dojo.isIE){
-			if(e.keyCode == dojo.keys.TAB && !this.isTabIndent){
+		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();
@@ -866,11 +893,11 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 					// focus the BODY so the browser will tab away from it instead
 					this.tabStop.focus();
 				}
-			}else if(e.keyCode === dojo.keys.BACKSPACE && this.document.selection.type === "Control"){
+			}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
-				dojo.stopEvent(e);
+				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!
@@ -879,15 +906,22 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 				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.
+					e.preventDefault();
+				}
+			}
+		}
 		return true;
 	},
 
-	onKeyUp: function(e){
+	onKeyUp: function(/*===== e =====*/){
 		// summary:
 		//		Handler for onkeyup event
 		// tags:
 		//      callback
-		return;
 	},
 
 	setDisabled: function(/*Boolean*/ disabled){
@@ -895,7 +929,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		Deprecated, use set('disabled', ...) instead.
 		// tags:
 		//		deprecated
-		dojo.deprecated('dijit.Editor::setDisabled is deprecated','use dijit.Editor::attr("disabled",boolean) instead', 2.0);
+		kernel.deprecated('dijit.Editor::setDisabled is deprecated','use dijit.Editor::attr("disabled",boolean) instead', 2.0);
 		this.set('disabled',disabled);
 	},
 	_setValueAttr: function(/*String*/ value){
@@ -905,11 +939,11 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 	},
 	_setDisableSpellCheckAttr: function(/*Boolean*/ disabled){
 		if(this.document){
-			dojo.attr(this.document.body, "spellcheck", !disabled);
+			domAttr.set(this.document.body, "spellcheck", !disabled);
 		}else{
 			// try again after the editor is finished loading
-			this.onLoadDeferred.addCallback(dojo.hitch(this, function(){
-				dojo.attr(this.document.body, "spellcheck", !disabled);
+			this.onLoadDeferred.addCallback(lang.hitch(this, function(){
+				domAttr.set(this.document.body, "spellcheck", !disabled);
 			}));
 		}
 		this._set("disableSpellCheck", disabled);
@@ -924,11 +958,11 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		var c = (e.keyChar && e.keyChar.toLowerCase()) || e.keyCode,
 			handlers = this._keyHandlers[c],
 			args = arguments;
-
+			
 		if(handlers && !e.altKey){
-			dojo.some(handlers, function(h){
+			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.shift ^ e.shiftKey) && !(h.ctrl ^ (e.ctrlKey||e.metaKey))){ 
 					if(!h.handler.apply(this, args)){
 						e.preventDefault();
 					}
@@ -939,7 +973,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 
 		// function call after the character has been inserted
 		if(!this._onKeyHitch){
-			this._onKeyHitch = dojo.hitch(this, "onKeyPressed");
+			this._onKeyHitch = lang.hitch(this, "onKeyPressed");
 		}
 		setTimeout(this._onKeyHitch, 1);
 		return true;
@@ -952,7 +986,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		The key argument should be in lowercase if it is a letter character
 		// tags:
 		//		protected
-		if(!dojo.isArray(this._keyHandlers[key])){
+		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
@@ -982,13 +1016,13 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		this.onDisplayChanged(e);
 	},
 
-	_onIEMouseDown: function(/*Event*/ e){
+	_onIEMouseDown: function(){
 		// summary:
 		//		IE only to prevent 2 clicks to focus
 		// tags:
 		//		protected
 
-		if(!this._focused && !this.disabled){
+		if(!this.focused && !this.disabled){
 			this.focus();
 		}
 	},
@@ -1004,7 +1038,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		this.inherited(arguments);
 
 		var newValue = this.getValue(true);
-		if(newValue != this.value){
+		if(newValue !== this.value){
 			this.onChange(newValue);
 		}
 		this._set("value", newValue);
@@ -1031,10 +1065,10 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		Remove focus from this instance.
 		// tags:
 		//		deprecated
-		if(!dojo.isIE && this.window.document.documentElement && this.window.document.documentElement.focus){
+		if(!has("ie") && this.window.document.documentElement && this.window.document.documentElement.focus){
 			this.window.document.documentElement.focus();
-		}else if(dojo.doc.body.focus){
-			dojo.doc.body.focus();
+		}else if(win.doc.body.focus){
+			win.doc.body.focus();
 		}
 	},
 
@@ -1052,8 +1086,8 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 				return;
 			}
 		}
-		if(!dojo.isIE){
-			dijit.focus(this.iframe);
+		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
@@ -1069,9 +1103,9 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 	// _lastUpdate: 0,
 	updateInterval: 200,
 	_updateTimer: null,
-	onDisplayChanged: function(/*Event*/ e){
+	onDisplayChanged: function(/*Event*/ /*===== e =====*/){
 		// summary:
-		//		This event will be fired everytime the display context
+		//		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,
@@ -1084,10 +1118,10 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			clearTimeout(this._updateTimer);
 		}
 		if(!this._updateHandler){
-			this._updateHandler = dojo.hitch(this,"onNormalizedDisplayChanged");
+			this._updateHandler = lang.hitch(this,"onNormalizedDisplayChanged");
 		}
 		this._updateTimer = setTimeout(this._updateHandler, 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.
 	},
@@ -1101,23 +1135,23 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		private
 		delete this._updateTimer;
 	},
-	onChange: function(newContent){
+	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 by dojo.connect to map our
+		//		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(dojo.isSafari && argument === undefined){ command = "heading"; }
-		}else if(command == "hilitecolor" && !dojo.isMoz){
+		if(command === "formatblock"){
+			if(has("safari") && argument === undefined){ command = "heading"; }
+		}else if(command === "hilitecolor" && !has("mozilla")){
 			command = "backcolor";
 		}
 
@@ -1203,10 +1237,10 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			default: return false;
 		}
 
-		return (dojo.isIE && supportedBy.ie) ||
-			(dojo.isMoz && supportedBy.mozilla) ||
-			(dojo.isWebKit && supportedBy.webkit) ||
-			(dojo.isOpera && supportedBy.opera);	// Boolean return true if the command is supported, false otherwise
+		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){
@@ -1226,11 +1260,11 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		this.focus();
 
 		command = this._normalizeCommand(command, argument);
-
+		
 		if(argument !== undefined){
-			if(command == "heading"){
+			if(command === "heading"){
 				throw new Error("unimplemented");
-			}else if((command == "formatblock") && dojo.isIE){
+			}else if((command === "formatblock") && has("ie")){
 				argument = '<'+argument+'>';
 			}
 		}
@@ -1243,7 +1277,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			returnValue = this[implFunc](argument);
 		}else{
 			argument = arguments.length > 1 ? argument : null;
-			if(argument || command!="createlink"){
+			if(argument || command !== "createlink"){
 				returnValue = this.document.execCommand(command, false, argument);
 			}
 		}
@@ -1255,38 +1289,24 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 	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);
-		if(dojo.isMoz || dojo.isWebKit){
-			if(command == "unlink"){ // mozilla returns true always
-				// console.debug(this._sCall("hasAncestorElement", ['a']));
-				return this._sCall("hasAncestorElement", ["a"]);
-			}else if(command == "inserttable"){
-				return true;
-			}
-		}
-		//see #4109
-		if(dojo.isWebKit){
-			if(command == "cut" || command == "copy") {
-				// WebKit deems clipboard activity as a security threat and natively would return false
-				var sel = this.window.getSelection();
-				if(sel){ sel = sel.toString(); }
-				return !!sel;
-			}else if(command == "paste"){
-				return true;
-			}
-		}
 
-		var elem = dojo.isIE ? this.document.selection.createRange() : this.document;
-		try{
-			return elem.queryCommandEnabled(command);
-		}catch(e){
-			//Squelch, occurs if editor is hidden on FF 3 (and maybe others.)
-			return false;
-		}
+		//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);
+		}
 	},
 
 	queryCommandState: function(command){
@@ -1315,9 +1335,9 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		if(this.disabled || !this._disabledOK){ return false; }
 		var r;
 		command = this._normalizeCommand(command);
-		if(dojo.isIE && command == "formatblock"){
+		if(has("ie") && command === "formatblock"){
 			r = this._native2LocalFormatNames[this.document.queryCommandValue(command)];
-		}else if(dojo.isMoz && command === "hilitecolor"){
+		}else if(has("mozilla") && command === "hilitecolor"){
 			var oldValue;
 			try{
 				oldValue = this.document.queryCommandValue("styleWithCSS");
@@ -1341,7 +1361,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		current editor instance's window, with the passed args.
 		// tags:
 		//		private
-		return dojo.withGlobal(this.window, name, dijit._editor.selection, args);
+		return win.withGlobal(this.window, name, selectionapi, args);
 	},
 
 	// FIXME: this is a TON of code duplication. Why?
@@ -1356,17 +1376,17 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 
 		//see comments in placeCursorAtEnd
 		var isvalid=false;
-		if(dojo.isMoz){
+		if(has("mozilla")){
 			// TODO:  Is this branch even necessary?
 			var first=this.editNode.firstChild;
 			while(first){
-				if(first.nodeType == 3){
+				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){
+				}else if(first.nodeType === 1){
 					isvalid=true;
 					var tg = first.tagName ? first.tagName.toLowerCase() : "";
 					// Collapse before childless tags.
@@ -1402,16 +1422,16 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		// cursor would be placed at the end of the closing tag of
 		//this.editNode.lastChild
 		var isvalid=false;
-		if(dojo.isMoz){
+		if(has("mozilla")){
 			var last=this.editNode.lastChild;
 			while(last){
-				if(last.nodeType == 3){
+				if(last.nodeType === 3){
 					if(last.nodeValue.replace(/^\s+|\s+$/g, "").length>0){
 						isvalid=true;
 						this._sCall("selectElement", [ last ]);
 						break;
 					}
-				}else if(last.nodeType == 1){
+				}else if(last.nodeType === 1){
 					isvalid=true;
 					if(last.lastChild){
 						this._sCall("selectElement", [ last.lastChild ]);
@@ -1467,7 +1487,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 
 		if(!this.isLoaded){
 			// try again after the editor is finished loading
-			this.onLoadDeferred.addCallback(dojo.hitch(this, function(){
+			this.onLoadDeferred.addCallback(lang.hitch(this, function(){
 				this.setValue(html);
 			}));
 			return;
@@ -1478,13 +1498,13 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		}else{
 			html = this._preFilterContent(html);
 			var node = this.isClosed ? this.domNode : this.editNode;
-			if(html && dojo.isMoz && html.toLowerCase() == "<p></p>"){
-				html = "<p> </p>";
+			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 && dojo.isWebKit){
-				html = " ";
+			if(!html && has("webkit")){
+				html = " ";	//  
 			}
 			node.innerHTML = html;
 			this._preDomFilterContent(node);
@@ -1504,7 +1524,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 
 		if(this.isClosed){
 			this.setValue(html);
-		}else if(this.window && this.window.getSelection && !dojo.isMoz){ // Safari
+		}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
@@ -1512,7 +1532,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			this.execCommand("selectall");
 			if(!html){
 				this._cursorToStart = true;
-				html = " ";
+				html = " ";	//  
 			}
 			this.execCommand("inserthtml", html);
 			this._preDomFilterContent(this.editNode);
@@ -1537,7 +1557,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		private
 
 		var ec = html;
-		dojo.forEach(this.contentPreFilters, function(ef){ if(ef){ ec = ef(ec); } });
+		array.forEach(this.contentPreFilters, function(ef){ if(ef){ ec = ef(ec); } });
 		return ec;
 	},
 	_preDomFilterContent: function(/*DomNode*/ dom){
@@ -1548,8 +1568,8 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		// tags:
 		//		private
 		dom = dom || this.editNode;
-		dojo.forEach(this.contentDomPreFilters, function(ef){
-			if(ef && dojo.isFunction(ef)){
+		array.forEach(this.contentDomPreFilters, function(ef){
+			if(ef && lang.isFunction(ef)){
 				ef(dom);
 			}
 		}, this);
@@ -1597,47 +1617,49 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		private
 
 		var ec;
-		if(!dojo.isString(dom)){
+		if(!lang.isString(dom)){
 			dom = dom || this.editNode;
 			if(this.contentDomPostFilters.length){
 				if(nonDestructive){
-					dom = dojo.clone(dom);
+					dom = lang.clone(dom);
 				}
-				dojo.forEach(this.contentDomPostFilters, function(ef){
+				array.forEach(this.contentDomPostFilters, function(ef){
 					dom = ef(dom);
 				});
 			}
-			ec = dijit._editor.getChildrenHtml(dom);
+			ec = htmlapi.getChildrenHtml(dom);
 		}else{
 			ec = dom;
 		}
 
-		if(!dojo.trim(ec.replace(/^\xA0\xA0*/, '').replace(/\xA0\xA0*$/, '')).length){
+		if(!lang.trim(ec.replace(/^\xA0\xA0*/, '').replace(/\xA0\xA0*$/, '')).length){
 			ec = "";
 		}
 
-		//	if(dojo.isIE){
+		//	if(has("ie")){
 		//		//removing appended <P> </P> for IE
 		//		ec = ec.replace(/(?:<p> </p>[\n\r]*)+$/i,"");
 		//	}
-		dojo.forEach(this.contentPostFilters, function(ef){
+		array.forEach(this.contentPostFilters, function(ef){
 			ec = ef(ec);
 		});
 
 		return ec;
 	},
 
-	_saveContent: function(/*Event*/ e){
+	_saveContent: function(){
 		// summary:
 		//		Saves the content in an onunload event if the editor has not been closed
 		// tags:
 		//		private
 
-		var saveTextarea = dojo.byId(dijit._scopeName + "._editor.RichText.value");
-		if(saveTextarea.value){
-			saveTextarea.value += this._SEPARATOR;
+		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);
 		}
-		saveTextarea.value += this.name + this._NAME_CONTENT_SEP + this.getValue(true);
 	},
 
 
@@ -1657,20 +1679,20 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 
 	getNodeHtml: function(/* DomNode */ node){
 		// summary:
-		//		Deprecated.   Use dijit._editor._getNodeHtml() instead.
+		//		Deprecated.   Use dijit/_editor/html::_getNodeHtml() instead.
 		// tags:
 		//		deprecated
-		dojo.deprecated('dijit.Editor::getNodeHtml is deprecated','use dijit._editor.getNodeHtml instead', 2);
-		return dijit._editor.getNodeHtml(node); // String
+		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.getChildrenHtml() instead.
+		//		Deprecated.   Use dijit/_editor/html::getChildrenHtml() instead.
 		// tags:
 		//		deprecated
-		dojo.deprecated('dijit.Editor::getNodeChildrenHtml is deprecated','use dijit._editor.getChildrenHtml instead', 2);
-		return dijit._editor.getChildrenHtml(dom);
+		kernel.deprecated('dijit.Editor::getNodeChildrenHtml is deprecated','use dijit/_editor/html::getChildrenHtml instead', 2);
+		return htmlapi.getChildrenHtml(dom);
 	},
 
 	close: function(/*Boolean?*/ save){
@@ -1690,7 +1712,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		}
 
 		// line height is squashed for iframes
-		// FIXME: why was this here? if (this.iframe){ this.domNode.style.lineHeight = null; }
+		// FIXME: why was this here? if(this.iframe){ this.domNode.style.lineHeight = null; }
 
 		if(this.interval){ clearInterval(this.interval); }
 
@@ -1701,13 +1723,13 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		}
 
 		// Guard against memory leaks on IE (see #9268)
-		if(dojo.isIE){
+		if(has("ie")){
 			 this.iframe.onfocus = null;
 		}
 		this.iframe._loadFunc = null;
 
 		if(this._iframeRegHandle){
-			dijit.unregisterIframe(this._iframeRegHandle);
+			this._iframeRegHandle.remove();
 			delete this._iframeRegHandle;
 		}
 
@@ -1715,12 +1737,12 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			var s = this.textarea.style;
 			s.position = "";
 			s.left = s.top = "";
-			if(dojo.isIE){
+			if(has("ie")){
 				s.overflow = this.__overflow;
 				this.__overflow = null;
 			}
 			this.textarea.value = this.value;
-			dojo.destroy(this.domNode);
+			domConstruct.destroy(this.domNode);
 			this.domNode = this.textarea;
 		}else{
 			// Note that this destroys the iframe
@@ -1728,7 +1750,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		}
 		delete this.iframe;
 
-		dojo.removeClass(this.domNode, this.baseClass);
+		domClass.remove(this.domNode, this.baseClass);
 		this.isClosed = true;
 		this.isLoaded = false;
 
@@ -1747,9 +1769,12 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 
 	destroy: function(){
 		if(!this.isClosed){ this.close(false); }
+		if(this._updateTimer){
+			clearTimeout(this._updateTimer);
+		}
 		this.inherited(arguments);
-		if(dijit._editor._globalSaveHandler){
-			delete dijit._editor._globalSaveHandler[this.id];
+		if(RichText._globalSaveHandler){
+			delete RichText._globalSaveHandler[this.id];
 		}
 	},
 
@@ -1803,6 +1828,139 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		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._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;
+	},
+
+	/*** execCommand implementations ***/
+
 	_inserthorizontalruleImpl: function(argument){
 		// summary:
 		//		This function implements the insertion of HTML 'HR' tags.
@@ -1812,7 +1970,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		arguments to the exec command, if any.
 		// tags:
 		//		protected
-		if(dojo.isIE){
+		if(has("ie")){
 			return this._inserthtmlImpl("<hr>");
 		}
 		return this.document.execCommand("inserthorizontalrule", false, argument);
@@ -1825,7 +1983,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		arguments to the exec command, if any.
 		// tags:
 		//		protected
-		if((this.queryCommandEnabled("unlink")) && (dojo.isMoz || dojo.isWebKit)){
+		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);
@@ -1841,14 +1999,18 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		// tags:
 		//		protected
 		var returnValue;
-		if(dojo.isMoz){
-			// mozilla doesn't support hilitecolor properly when useCSS is
-			// set to false (bugzilla #279330)
-			this.document.execCommand("styleWithCSS", false, true);
-			returnValue = this.document.execCommand("hilitecolor", false, argument);
-			this.document.execCommand("styleWithCSS", false, false);
-		}else{
-			returnValue = this.document.execCommand("hilitecolor", false, argument);
+		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;
 	},
@@ -1860,13 +2022,17 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		arguments to the exec command, if any.
 		// tags:
 		//		protected
-		if(dojo.isIE){
+		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;
 		}
-		return this.document.execCommand("backcolor", false, argument);
+		var isApplied = this._handleTextColorOrProperties("backcolor", argument);
+		if(!isApplied){
+			isApplied = this.document.execCommand("backcolor", false, argument);
+		}
+		return isApplied;
 	},
 
 	_forecolorImpl: function(argument){
@@ -1876,13 +2042,18 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		arguments to the exec command, if any.
 		// tags:
 		//		protected
-		if(dojo.isIE){
+		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;
 		}
-		return this.document.execCommand("forecolor", false, argument);
+		var isApplied = false;
+		isApplied = this._handleTextColorOrProperties("forecolor", argument);
+		if(!isApplied){
+			isApplied = this.document.execCommand("forecolor", false, argument);
+		}
+		return isApplied;
 	},
 
 	_inserthtmlImpl: function(argument){
@@ -1895,9 +2066,9 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		protected
 		argument = this._preFilterContent(argument);
 		var rv = true;
-		if(dojo.isIE){
+		if(has("ie")){
 			var insertRange = this.document.selection.createRange();
-			if(this.document.selection.type.toUpperCase() == 'CONTROL'){
+			if(this.document.selection.type.toUpperCase() === 'CONTROL'){
 				var n=insertRange.item(0);
 				while(insertRange.length){
 					insertRange.remove(insertRange.item(0));
@@ -1908,7 +2079,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			}
 			insertRange.select();
 			//insertRange.collapse(true);
-		}else if(dojo.isMoz && !argument.length){
+		}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
@@ -1925,12 +2096,17 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		Not used, operates by selection.
 		// tags:
 		//		protected
-		if(dojo.isIE){
-			this._adaptIESelection()
+		var applied = false;
+		if(has("ie")){
+			this._adaptIESelection();		
+			applied = this._adaptIEFormatAreaAndExec("bold");
+		}
+		if(!applied){
+			applied = this.document.execCommand("bold", false, argument);
 		}
-		return this.document.execCommand("bold", false, argument);
+		return applied;
 	},
-	
+
 	_italicImpl: function(argument){
 		// summary:
 		//		This function implements an over-ride of the italic command.
@@ -1938,10 +2114,15 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		Not used, operates by selection.
 		// tags:
 		//		protected
-		if(dojo.isIE){
-			this._adaptIESelection()
+		var applied = false;
+		if(has("ie")){
+			this._adaptIESelection();			
+			applied = this._adaptIEFormatAreaAndExec("italic");
 		}
-		return this.document.execCommand("italic", false, argument);
+		if(!applied){
+			applied = this.document.execCommand("italic", false, argument);
+		}
+		return applied;
 	},
 
 	_underlineImpl: function(argument){
@@ -1951,12 +2132,17 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		Not used, operates by selection.
 		// tags:
 		//		protected
-		if(dojo.isIE){
-			this._adaptIESelection()
+		var applied = false;
+		if(has("ie")){
+			this._adaptIESelection();			
+			applied = this._adaptIEFormatAreaAndExec("underline");
+		}
+		if(!applied){
+			applied = this.document.execCommand("underline", false, argument);
 		}
-		return this.document.execCommand("underline", false, argument);
+		return applied;
 	},
-	
+
 	_strikethroughImpl: function(argument){
 		// summary:
 		//		This function implements an over-ride of the strikethrough command.
@@ -1964,12 +2150,122 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		Not used, operates by selection.
 		// tags:
 		//		protected
-		if(dojo.isIE){
-			this._adaptIESelection()
+		var applied = false;
+		if(has("ie")){
+			this._adaptIESelection();			
+			applied = this._adaptIEFormatAreaAndExec("strikethrough");
 		}
-		return this.document.execCommand("strikethrough", false, argument);
+		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");
+			
+		}
+		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
@@ -1993,13 +2289,13 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			// so we have to walk over all the children manually.
 			var i;
 			for(i = 0; i < node.childNodes.length; i++){
-				var size = dojo.position(node.childNodes[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.
@@ -2007,17 +2303,17 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		The node to check.
 		// tags:
 		//		private.
-		if(node.nodeType == 1/*element*/){
+		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) == "");
+		}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
@@ -2042,7 +2338,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		}
 		return range;
 	},
-	
+
 	_adaptIESelection: function(){
 		// summary:
 		//		Function to adapt the IE range by removing leading 'newlines'
@@ -2052,13 +2348,13 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		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 = dijit.range.getSelection(this.window);
+		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){
+			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;
@@ -2066,7 +2362,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 
 			//Remove the starting ranges until the range does not start with an empty node.
 			var lastNode=null;
-			while(this._isNodeEmpty(firstNode, startOffset) && firstNode != lastNode){
+			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;
@@ -2075,8 +2371,521 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			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;
+					}
+					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(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.className){
+								newTg.className = parentC.className;
+								tagData.className = parentC.className;
+							}
+							
+							// 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;
+						}
+
+						// 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){
+								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.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();
+								newrange.setStart(sNode, 0);
+								newrange.setEnd(sNode, sNode.length);
+								selection.removeAllRanges();
+								selection.addRange(newrange);
+								selectionapi.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();
+								newrange.setStart(sNode, 0);
+								newrange.setEnd(sNode, sNode.length);
+								selection.removeAllRanges();
+								selection.addRange(newrange);
+								selectionapi.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;
+					}
+				}
+				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(){
+						var offset = range.startOffset;
+						if(rs.length < offset){
+							//We are not splitting the right node, try to locate the correct one
+							ret = this._adjustNodeAndOffset(rs, offset);
+							rs = ret.node;
+							offset = ret.offset;
+						}
+						txt = rs.nodeValue;
+						startNode = doc.createTextNode(txt.substring(0, offset));
+						var endText = txt.substring(offset);
+						if(endText !== ""){
+							endNode = doc.createTextNode(txt.substring(offset));
+						}
+						// Create a space, we'll select and bold it, so 
+						// the whole word doesn't get bolded
+						breaker = doc.createElement("span");
+						sNode = doc.createTextNode(".");
+						breaker.appendChild(sNode);
+						if(startNode.length){
+							domConstruct.place(startNode, rs, "after");
+						}else{
+							startNode = rs;
+						}
+						domConstruct.place(breaker, startNode, "after");
+						if(endNode){
+							domConstruct.place(endNode, breaker, "after");
+						}
+						domConstruct.destroy(rs);
+						var newrange = rangeapi.create();
+						newrange.setStart(sNode, 0);
+						newrange.setEnd(sNode, sNode.length);
+						selection.removeAllRanges();
+						selection.addRange(newrange);
+						doc.execCommand(command);
+						domConstruct.place(breaker.firstChild, breaker, "before");
+						domConstruct.destroy(breaker);
+						newrange.setStart(sNode, 0);
+						newrange.setEnd(sNode, sNode.length);
+						selection.removeAllRanges();
+						selection.addRange(newrange);
+						selectionapi.collapse(false);
+						sNode.parentNode.innerHTML = "";
+					}));
+					return true;
+				}
+			}
+		}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 
+							// the whole word doesn't get bolded
+							var lType = "ul";
+							if(command === "insertorderedlist"){
+								lType = "ol";
+							}
+							var list = domConstruct.create(lType);
+							var li = domConstruct.create("li", null, list);
+							domConstruct.place(list, sc, "before");
+							// Move in the text node as part of the li.
+							li.appendChild(sc);
+							// We need a br after it or the enter key handler
+							// sometimes throws errors.
+							domConstruct.create("br", null, list, "after");
+							// Okay, now lets move our cursor to the beginning.
+							var newrange = rangeapi.create();
+							newrange.setStart(sc, 0);
+							newrange.setEnd(sc, sc.length);
+							selection.removeAllRanges();
+							selection.addRange(newrange);
+							selectionapi.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(){
+						var offset = range.startOffset;
+						if(rs.length < offset){
+							//We are not splitting the right node, try to locate the correct one
+							ret = this._adjustNodeAndOffset(rs, offset);
+							rs = ret.node;
+							offset = ret.offset;
+						}
+						txt = rs.nodeValue;
+						startNode = doc.createTextNode(txt.substring(0, offset));
+						var endText = txt.substring(offset);
+						if(endText !== ""){
+							endNode = doc.createTextNode(txt.substring(offset));
+						}
+						// Create a space, we'll select and bold it, so 
+						// the whole word doesn't get bolded
+						breaker = domConstruct.create("span");
+						sNode = doc.createTextNode(".");
+						breaker.appendChild(sNode);
+						// Create a junk node to avoid it trying to stlye the breaker.
+						// This will get destroyed later.
+						var extraSpan = domConstruct.create("span");
+						breaker.appendChild(extraSpan);
+						if(startNode.length){
+							domConstruct.place(startNode, rs, "after");
+						}else{
+							startNode = rs;
+						}
+						domConstruct.place(breaker, startNode, "after");
+						if(endNode){
+							domConstruct.place(endNode, breaker, "after");
+						}
+						domConstruct.destroy(rs);
+						var newrange = rangeapi.create();
+						newrange.setStart(sNode, 0);
+						newrange.setEnd(sNode, sNode.length);
+						selection.removeAllRanges();
+						selection.addRange(newrange);
+						if(has("webkit")){
+							// 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";
+							if(command === "hilitecolor" || command === "backcolor"){
+								style = "backgroundColor";
+							}
+							domStyle.set(breaker, style, argument);
+							selectionapi.remove();
+							domConstruct.destroy(extraSpan);
+							breaker.innerHTML = " ";	//  
+							selectionapi.selectElement(breaker);
+							this.focus();
+						}else{
+							this.execCommand(command, argument);
+							domConstruct.place(breaker.firstChild, breaker, "before");
+							domConstruct.destroy(breaker);
+							newrange.setStart(sNode, 0);
+							newrange.setEnd(sNode, sNode.length);
+							selection.removeAllRanges();
+							selection.addRange(newrange);
+							selectionapi.collapse(false);
+							sNode.parentNode.removeChild(sNode);
+						}
+					}));
+					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];
+				while(b.firstChild){
+					domConstruct.place(b.firstChild, b, "before");
+				}
+				domConstruct.destroy(b);
+			}		
+		}));
+		return node;
 	}
 });
 
-return dijit._editor.RichText;
+return RichText;
+
 });
diff --git a/dijit/_editor/_Plugin.js b/dijit/_editor/_Plugin.js
index 64d948c..d1276f8 100644
--- a/dijit/_editor/_Plugin.js
+++ b/dijit/_editor/_Plugin.js
@@ -1,13 +1,25 @@
-define("dijit/_editor/_Plugin", ["dojo", "dijit", "dijit/_Widget", "dijit/form/Button"], function(dojo, dijit) {
+define([
+	"dojo/_base/connect", // connect.connect
+	"dojo/_base/declare", // declare
+	"dojo/_base/lang", // lang.mixin, lang.hitch
+	"../form/Button"
+], function(connect, declare, lang, Button){
 
-dojo.declare("dijit._editor._Plugin", null, {
-	// summary
+// 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, /*DomNode?*/node){
+	constructor: function(/*Object?*/args){
 		this.params = args || {};
-		dojo.mixin(this, this.params);
+		lang.mixin(this, this.params);
 		this._connects=[];
 		this._attrPairNames = {};
 	},
@@ -39,7 +51,7 @@ dojo.declare("dijit._editor._Plugin", null, {
 	//		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: dijit.form.Button,
+	buttonClass: Button,
 
 	// disabled: Boolean
 	//		Flag to indicate if this plugin has been disabled and should do nothing
@@ -65,7 +77,7 @@ dojo.declare("dijit._editor._Plugin", null, {
 				editor = this.editor,
 				className = this.iconClassPrefix+" "+this.iconClassPrefix + this.command.charAt(0).toUpperCase() + this.command.substr(1);
 			if(!this.button){
-				var props = dojo.mixin({
+				var props = lang.mixin({
 					label: label,
 					dir: editor.dir,
 					lang: editor.lang,
@@ -86,7 +98,8 @@ dojo.declare("dijit._editor._Plugin", null, {
 		// summary:
 		//		Destroy this plugin
 
-		dojo.forEach(this._connects, dojo.disconnect);
+		var h;
+		while(h = this._connects.pop()){ h.remove(); }
 		if(this.dropDown){
 			this.dropDown.destroyRecursive();
 		}
@@ -94,11 +107,11 @@ dojo.declare("dijit._editor._Plugin", null, {
 
 	connect: function(o, f, tf){
 		// summary:
-		//		Make a dojo.connect() that is automatically disconnected when this plugin is destroyed.
+		//		Make a connect.connect() that is automatically disconnected when this plugin is destroyed.
 		//		Similar to `dijit._Widget.connect`.
 		// tags:
 		//		protected
-		this._connects.push(dojo.connect(o, f, this, tf));
+		this._connects.push(connect.connect(o, f, this, tf));
 	},
 
 	updateState: function(){
@@ -154,7 +167,7 @@ dojo.declare("dijit._editor._Plugin", null, {
 		if(this.button && this.useDefaultCommand){
 			if(this.editor.queryCommandAvailable(this.command)){
 				this.connect(this.button, "onClick",
-					dojo.hitch(this.editor, "execCommand", this.command, this.commandArg)
+					lang.hitch(this.editor, "execCommand", this.command, this.commandArg)
 				);
 			}else{
 				// hide button because editor doesn't support command (due to browser limitations)
@@ -177,7 +190,7 @@ dojo.declare("dijit._editor._Plugin", null, {
 		}
 		// console.debug("adding", this.button, "to:", toolbar);
 	},
-	
+
 	set: function(/* attribute */ name, /* anything */ value){
 		// summary:
 		//		Set a property on a plugin
@@ -249,7 +262,7 @@ dojo.declare("dijit._editor._Plugin", null, {
 		this.disabled = disabled;
 		this.updateState();
 	},
-	
+
 	_getAttrNames: function(name){
 		// summary:
 		//		Helper function for get() and set().
@@ -265,14 +278,17 @@ dojo.declare("dijit._editor._Plugin", null, {
 			g: "_get"+uc+"Attr"
 		});
 	},
-	
+
 	_set: function(/*String*/ name, /*anything*/ value){
 		// summary:
 		//		Helper function to set new value for specified attribute
-		var oldValue = this[name];
 		this[name] = value;
 	}
 });
 
-return dijit._editor._Plugin;
-});
\ No newline at end of file
+// 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 71cd981..ac35b1d 100755
--- a/dijit/_editor/html.js
+++ b/dijit/_editor/html.js
@@ -1,5 +1,15 @@
-define("dijit/_editor/html", ["dojo", "dijit"], function(dojo, dijit) {
-dojo.getObject("_editor", true, dijit);
+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){
+
+// module:
+//		dijit/_editor/html
+// summary:
+//		Utility functions used by editor
+
+lang.getObject("_editor", true, dijit);
 
 dijit._editor.escapeXml=function(/*String*/str, /*Boolean?*/noSingleQuotes){
 	// summary:
@@ -31,7 +41,7 @@ dijit._editor.getNodeHtml=function(/* DomNode */node){
 			//attributes appear in the dictionary order
 			var attrarray = [];
 			var attr;
-			if(dojo.isIE && node.outerHTML){
+			if(has("ie") && node.outerHTML){
 				var s = node.outerHTML;
 				s = s.substr(0, s.indexOf('>'))
 					.replace(/(['"])[^"']*\1/g, ''); //to make the following regexp safe
@@ -106,7 +116,7 @@ dijit._editor.getNodeHtml=function(/* DomNode */node){
 			var j = 0;
 			while((attr = attrarray[j++])){
 				output += ' ' + attr[0] + '="' +
-					(dojo.isString(attr[1]) ? dijit._editor.escapeXml(attr[1], true) : attr[1]) + '"';
+					(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,
@@ -164,7 +174,7 @@ dijit._editor.getChildrenHtml = function(/* DomNode */dom){
 	//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 = !dojo.isIE || nodes !== dom;
+	var checkParent = !has("ie") || nodes !== dom;
 
 	var node, i = 0;
 	while((node = nodes[i++])){
diff --git a/dijit/_editor/nls/FontChoice.js b/dijit/_editor/nls/FontChoice.js
index f1cc889..c920f0f 100644
--- a/dijit/_editor/nls/FontChoice.js
+++ b/dijit/_editor/nls/FontChoice.js
@@ -47,6 +47,7 @@ define({ root:
 "ja": true,
 "it": true,
 "hu": true,
+"hr": true,
 "he": true,
 "fr": true,
 "fi": true,
@@ -56,5 +57,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"az": true,
 "ar": true
 });
diff --git a/dijit/_editor/nls/LinkDialog.js b/dijit/_editor/nls/LinkDialog.js
index b188243..00360ea 100644
--- a/dijit/_editor/nls/LinkDialog.js
+++ b/dijit/_editor/nls/LinkDialog.js
@@ -33,6 +33,7 @@ define({ root:
 "ja": true,
 "it": true,
 "hu": true,
+"hr": true,
 "he": true,
 "fr": true,
 "fi": true,
@@ -42,5 +43,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"az": true,
 "ar": true
 });
diff --git a/dijit/_editor/nls/az/FontChoice.js b/dijit/_editor/nls/az/FontChoice.js
new file mode 100644
index 0000000..b0538cb
--- /dev/null
+++ b/dijit/_editor/nls/az/FontChoice.js
@@ -0,0 +1,27 @@
+define(
+//begin v1.x content
+({
+	"1" : "xx-kiçik",
+	"2" : "x-kiçik",
+	"formatBlock" : "Format",
+	"3" : "kiçik",
+	"4" : "orta",
+	"5" : "böyük",
+	"6" : "çox-böyük",
+	"7" : "ən böyük",
+	"fantasy" : "fantaziya",
+	"serif" : "serif",
+	"p" : "Abzas",
+	"pre" : "Əvvəldən düzəldilmiş",
+	"sans-serif" : "sans-serif",
+	"fontName" : "Şrift",
+	"h1" : "Başlıq",
+	"h2" : "Alt Başlıq",
+	"h3" : "Alt Alt Başlıq",
+	"monospace" : "Tək aralıqlı",
+	"fontSize" : "Ölçü",
+	"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
new file mode 100644
index 0000000..2ddab8d
--- /dev/null
+++ b/dijit/_editor/nls/az/LinkDialog.js
@@ -0,0 +1,16 @@
+define(
+//begin v1.x content
+({
+	"text" : "Yazı:",
+	"insertImageTitle" : "Şəkil başlığı əlavə et",
+	"set" : "Yönəlt",
+	"newWindow" : "Yeni pəncərə",
+	"topWindow" : "Üst pəncərə",
+	"target" : "Hədəf:",
+	"createLinkTitle" : "Köprü başlığı yarat",
+	"parentWindow" : "Ana pəncərə",
+	"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
new file mode 100644
index 0000000..703a8e7
--- /dev/null
+++ b/dijit/_editor/nls/az/commands.js
@@ -0,0 +1,52 @@
+define(
+//begin v1.x content
+({
+	"removeFormat" : "Formatı Sil",
+	"copy" :"Köçür",
+	"paste" :"Yapışdır",
+	"selectAll" :"Hamısını seç",
+	"insertOrderedList" :"Nömrəli siyahı", 
+	"insertTable" :"Cədvəl əlavə et",
+	"print" :"Yazdır",
+	"underline" :"Altıxətli",
+	"foreColor" :"Ön plan rəngi",
+	"htmlToggle" :"HTML kodu",
+	"formatBlock" :"Abzas stili",
+	"newPage" :"Yeni səhifə",
+	"insertHorizontalRule" :"Üfüqi qayda",
+	"delete" :"Sil",
+	"insertUnorderedList" :"İşarələnmiş siyahı",
+	"tableProp" :"Cədvəl xüsusiyyətləri",
+	"insertImage" :"Şəkil əlavə et",
+	"superscript" :"Üst işarə",
+	"subscript" :"Alt işarə",
+	"createLink" :"Körpü yarat",
+	"undo" :"Geriyə al",
+	"fullScreen" :"Tam ekran aç",
+	"italic" :"İtalik",
+	"fontName" :"Yazı tipi",
+	"justifyLeft" :"Sol tərəfə Doğrult",
+	"unlink" :"Körpünü sil",
+	"toggleTableBorder" :"Cədvəl kənarlarını göstər/Gizlət",
+	"viewSource" :"HTML qaynaq kodunu göstər",
+	"fontSize" :"Yazı tipi böyüklüğü",
+	"systemShortcut" :"\"${0}\" prosesi yalnız printerinizdə klaviatura qısayolu ilə istifadə oluna bilər. Bundan istifadə edin",
+	"indent" :"Girinti",
+	"redo" :"Yenilə",
+	"strikethrough" :"Üstündən xətt çəkilmiş",
+	"justifyFull" :"Doğrult",
+	"justifyCenter" :"Ortaya doğrult",
+	"hiliteColor" :"Arxa plan rəngi",
+	"deleteTable" :"Cədvəli sil",
+	"outdent" :"Çıxıntı",
+	"cut" :"Kəs",
+	"plainFormatBlock" :"Abzas stili",
+	"toggleDir" :"İstiqaməti dəyişdir",
+	"bold" :"Qalın",
+	"tabIndent" :"Qulp girintisi",
+	"justifyRight" :"Sağa doğrult",
+	"appleKey" : "⌘${0}",
+	"ctrlKey" : "ctrl+${0}"
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/commands.js b/dijit/_editor/nls/commands.js
index dfdbd39..bf6a53d 100644
--- a/dijit/_editor/nls/commands.js
+++ b/dijit/_editor/nls/commands.js
@@ -70,6 +70,7 @@ define({ root:
 "ja": true,
 "it": true,
 "hu": true,
+"hr": true,
 "he": true,
 "fr": true,
 "fi": true,
@@ -79,5 +80,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"az": true,
 "ar": true
 });
diff --git a/dijit/_editor/nls/hr/FontChoice.js b/dijit/_editor/nls/hr/FontChoice.js
new file mode 100644
index 0000000..40684f5
--- /dev/null
+++ b/dijit/_editor/nls/hr/FontChoice.js
@@ -0,0 +1,25 @@
+define(
+({
+	fontSize: "Veličina",
+	fontName: "Font",
+	formatBlock: "Oblikovanje",
+	serif: "serif",
+	"sans-serif": "sans-serif",
+	monospace: "jednaki razmak",
+	cursive: "rukopisni",
+	fantasy: "fantastika",
+	noFormat: "Nijedan",
+	p: "Odlomak",
+	h1: "Naslov",
+	h2: "Podnaslov",
+	h3: "Pod-podnaslov",
+	pre: "Prethodno formatirano",
+	1: "vrlo vrlo malo",
+	2: "vrlo malo",
+	3: "malo",
+	4: "srednje",
+	5: "veliko",
+	6: "vrlo veliko",
+	7: "vrlo vrlo veliko"
+})
+);
diff --git a/dijit/_editor/nls/hr/LinkDialog.js b/dijit/_editor/nls/hr/LinkDialog.js
new file mode 100644
index 0000000..b8fd2ff
--- /dev/null
+++ b/dijit/_editor/nls/hr/LinkDialog.js
@@ -0,0 +1,14 @@
+define(
+({
+	createLinkTitle: "Svojstva veze",
+	insertImageTitle: "Svojstva slike",
+	url: "URL:",
+	text: "Opis:",
+	target: "Cilj:",
+	set: "Postavi",
+	currentWindow: "Aktivni prozor",
+	parentWindow: "Nadređeni prozor",
+	topWindow: "Najviši prozor",
+	newWindow: "Novi prozor"
+})
+);
diff --git a/dijit/_editor/nls/hr/commands.js b/dijit/_editor/nls/hr/commands.js
new file mode 100644
index 0000000..88822c8
--- /dev/null
+++ b/dijit/_editor/nls/hr/commands.js
@@ -0,0 +1,51 @@
+define(
+({
+	'bold': 'Podebljaj',
+	'copy': 'Kopiraj',
+	'cut': 'Izreži',
+	'delete': 'Izbriši',
+	'indent': 'Uvuci',
+	'insertHorizontalRule': 'Vodoravno ravnalo',
+	'insertOrderedList': 'Numerirani popis',
+	'insertUnorderedList': 'Popis s grafičkim oznakama',
+	'italic': 'Kurziv',
+	'justifyCenter': 'Centriraj',
+	'justifyFull': 'Poravnaj',
+	'justifyLeft': 'Poravnaj lijevo',
+	'justifyRight': 'Poravnaj desno',
+	'outdent': 'Izvuci',
+	'paste': 'Zalijepi',
+	'redo': 'Ponovno napravi',
+	'removeFormat': 'Ukloni oblikovanje',
+	'selectAll': 'Izaberi sve',
+	'strikethrough': 'Precrtaj',
+	'subscript': 'Indeks',
+	'superscript': 'Superskript',
+	'underline': 'Podcrtaj',
+	'undo': 'Poništi',
+	'unlink': 'Ukloni vezu',
+	'createLink': 'Kreiraj vezu',
+	'toggleDir': 'Prebaci smjer',
+	'insertImage': 'Umetni sliku',
+	'insertTable': 'Umetni/Uredi tablicu',
+	'toggleTableBorder': 'Prebaci rub tablice',
+	'deleteTable': 'Izbriši tablicu',
+	'tableProp': 'Svojstvo tablice',
+	'htmlToggle': 'HTML izvor',
+	'foreColor': 'Boja prednjeg plana',
+	'hiliteColor': 'Boja pozadine',
+	'plainFormatBlock': 'Stil odlomka',
+	'formatBlock': 'Stil odlomka',
+	'fontSize': 'Veličina fonta',
+	'fontName': 'Ime fonta',
+	'tabIndent': 'Tabulator uvlačenja',
+	"fullScreen": "Prebaci na potpun ekran",
+	"viewSource": "Pogledaj HTML izvor",
+	"print": "Ispis",
+	"newPage": "Nova stranica",
+	/* Error messages */
+	'systemShortcut': '"${0}" akcija je dostupna jedino u vašem pregledniku upotrebom prečice tipkovnice. Koristite ${1}.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
+})
+);
diff --git a/dijit/_editor/plugins/AlwaysShowToolbar.js b/dijit/_editor/plugins/AlwaysShowToolbar.js
index a8e9868..754541a 100644
--- a/dijit/_editor/plugins/AlwaysShowToolbar.js
+++ b/dijit/_editor/plugins/AlwaysShowToolbar.js
@@ -1,7 +1,29 @@
-define("dijit/_editor/plugins/AlwaysShowToolbar", ["dojo", "dijit", "dijit/_editor/_Plugin"], function(dojo, dijit) {
-
-dojo.declare("dijit._editor.plugins.AlwaysShowToolbar", dijit._editor._Plugin,
-	{
+define([
+	"dojo/_base/declare", // declare
+	"dojo/dom-class", // domClass.add domClass.remove
+	"dojo/dom-construct", // domConstruct.place
+	"dojo/dom-geometry",
+	"dojo/_base/lang", // lang.hitch
+	"dojo/_base/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,
@@ -12,8 +34,8 @@ dojo.declare("dijit._editor.plugins.AlwaysShowToolbar", dijit._editor._Plugin,
 	//		Specify this in extraPlugins (or plugins) parameter and also set
 	//		height to "".
 	// example:
-	//	|	<div dojoType="dijit.Editor" height=""
-	//	|	extraPlugins="['dijit._editor.plugins.AlwaysShowToolbar']">
+	//	|	<div data-dojo-type="dijit.Editor" height=""
+	//	|	data-dojo-props="extraPlugins: [dijit._editor.plugins.AlwaysShowToolbar]">
 
 	// _handleScroll: Boolean
 	//		Enables/disables the handler for scroll events
@@ -28,7 +50,7 @@ dojo.declare("dijit._editor.plugins.AlwaysShowToolbar", dijit._editor._Plugin,
 
 		this.editor = e;
 
-		e.onLoadDeferred.addCallback(dojo.hitch(this, this.enable));
+		e.onLoadDeferred.addCallback(lang.hitch(this, this.enable));
 	},
 
 	enable: function(d){
@@ -50,8 +72,8 @@ dojo.declare("dijit._editor.plugins.AlwaysShowToolbar", dijit._editor._Plugin,
 		if(!e.isLoaded){ return; }
 		if(e.height){ return; }
 
-		var height = dojo._getMarginSize(e.editNode).h;
-		if(dojo.isOpera){
+		var height = domGeometry.getMarginSize(e.editNode).h;
+		if(has("opera")){
 			height = e.editNode.scrollHeight;
 		}
 		// console.debug('height',height);
@@ -60,21 +82,21 @@ dojo.declare("dijit._editor.plugins.AlwaysShowToolbar", dijit._editor._Plugin,
 		//height maybe zero in some cases even though the content is not empty,
 		//we try the height of body instead
 		if(!height){
-			height = dojo._getMarginSize(e.document.body).h;
+			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(dojo.isIE <= 7 && this.editor.minHeight){
+		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";
-			dojo.marginBox(e.iframe, { h: this._lastHeight });
+			domGeometry.setMarginBox(e.iframe, { h: this._lastHeight });
 		}
 	},
 
@@ -88,33 +110,32 @@ dojo.declare("dijit._editor.plugins.AlwaysShowToolbar", dijit._editor._Plugin,
 		// tags:
 		//		private
 
-		var isIE6 = dojo.isIE < 7;
+		var isIE6 = has("ie") < 7;
 		if(!this._handleScroll){ return; }
 		var tdn = this.editor.header;
-		var db = dojo.body;
-
 		if(!this._scrollSetUp){
 			this._scrollSetUp = true;
-			this._scrollThreshold = dojo.position(tdn, true).y;
+			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)&&(dojo.style(db, "backgroundIimage")=="none")){
+//			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";
 //			}
 		}
 
-		var scrollPos = dojo._docScroll().y;
+		var scrollPos = domGeometry.docScroll().y;
 		var s = tdn.style;
 
 		if(scrollPos > this._scrollThreshold && scrollPos < this._scrollThreshold+this._lastHeight){
 			// dojo.debug(scrollPos);
 			if(!this._fixEnabled){
-				var tdnbox = dojo._getMarginSize(tdn);
+				var tdnbox = domGeometry.getMarginSize(tdn);
 				this.editor.iframe.style.marginTop = tdnbox.h+"px";
 
 				if(isIE6){
-					s.left = dojo.position(tdn).x;
+					s.left = domGeometry.position(tdn).x;
 					if(tdn.previousSibling){
 						this._IEOriginalPos = ['after',tdn.previousSibling];
 					}else if(tdn.nextSibling){
@@ -122,14 +143,14 @@ dojo.declare("dijit._editor.plugins.AlwaysShowToolbar", dijit._editor._Plugin,
 					}else{
 						this._IEOriginalPos = ['last',tdn.parentNode];
 					}
-					dojo.body().appendChild(tdn);
-					dojo.addClass(tdn,'dijitIEFixedToolbar');
+					win.body().appendChild(tdn);
+					domClass.add(tdn,'dijitIEFixedToolbar');
 				}else{
 					s.position = "fixed";
 					s.top = "0px";
 				}
 
-				dojo.marginBox(tdn, { w: tdnbox.w });
+				domGeometry.setMarginBox(tdn, { w: tdnbox.w });
 				s.zIndex = 2000;
 				this._fixEnabled = true;
 			}
@@ -150,12 +171,12 @@ dojo.declare("dijit._editor.plugins.AlwaysShowToolbar", dijit._editor._Plugin,
 			s.display = "";
 			if(isIE6){
 				s.left = "";
-				dojo.removeClass(tdn,'dijitIEFixedToolbar');
+				domClass.remove(tdn,'dijitIEFixedToolbar');
 				if(this._IEOriginalPos){
-					dojo.place(tdn, this._IEOriginalPos[1], this._IEOriginalPos[0]);
+					domConstruct.place(tdn, this._IEOriginalPos[1], this._IEOriginalPos[0]);
 					this._IEOriginalPos = null;
 				}else{
-					dojo.place(tdn, this.editor.iframe, 'before');
+					domConstruct.place(tdn, this.editor.iframe, 'before');
 				}
 			}
 			s.width = "";
@@ -167,15 +188,12 @@ dojo.declare("dijit._editor.plugins.AlwaysShowToolbar", dijit._editor._Plugin,
 		// Overrides _Plugin.destroy().   TODO: call this.inherited() rather than repeating code.
 		this._IEOriginalPos = null;
 		this._handleScroll = false;
-		dojo.forEach(this._connects, dojo.disconnect);
-//		clearInterval(this.scrollInterval);
+		this.inherited(arguments);
 
-		if(dojo.isIE < 7){
-			dojo.removeClass(this.editor.header, 'dijitIEFixedToolbar');
+		if(has("ie") < 7){
+			domClass.remove(this.editor.header, 'dijitIEFixedToolbar');
 		}
 	}
 });
 
-
-return dijit._editor.plugins.AlwaysShowToolbar;
 });
diff --git a/dijit/_editor/plugins/EnterKeyHandling.js b/dijit/_editor/plugins/EnterKeyHandling.js
index 410fc9d..6b91105 100644
--- a/dijit/_editor/plugins/EnterKeyHandling.js
+++ b/dijit/_editor/plugins/EnterKeyHandling.js
@@ -1,6 +1,32 @@
-define("dijit/_editor/plugins/EnterKeyHandling", ["dojo", "dijit", "dojo/window", "dijit/_editor/_Plugin", "dijit/_editor/range"], function(dojo, dijit) {
+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/window", // winUtils.scrollIntoView
+	"../_Plugin",
+	"../RichText",
+	"../range",
+	"../selection"
+], function(declare, domConstruct, event, keys, lang, has, win, winUtils, _Plugin, RichText, rangeapi, selectionapi){
 
-dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
+/*=====
+	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
@@ -10,11 +36,11 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 	// description:
 	//		This plugin has three modes:
 	//
-	//			* blockModeForEnter=BR
-	//			* blockModeForEnter=DIV
-	//			* blockModeForEnter=P
+	//			* blockNodeForEnter=BR
+	//			* blockNodeForEnter=DIV
+	//			* blockNodeForEnter=P
 	//
-	//		In blockModeForEnter=P, the ENTER key starts a new
+	//		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:
 	//
@@ -78,28 +104,28 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 			if("blockNodeForEnter" in args){
 				args.blockNodeForEnter = args.blockNodeForEnter.toUpperCase();
 			}
-			dojo.mixin(this,args);
+			lang.mixin(this,args);
 		}
 	},
 
 	setEditor: function(editor){
 		// Overrides _Plugin.setEditor().
-		if(this.editor === editor) { return; }
+		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(dojo.hitch(this,function(d){
+				editor.onLoadDeferred.addCallback(lang.hitch(this,function(d){
 				this.connect(editor.document, "onkeypress", function(e){
-					if(e.charOrCode == dojo.keys.ENTER){
+					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 = dojo.mixin({},e);
+						var ne = lang.mixin({},e);
 						ne.shiftKey = true;
 						if(!this.handleEnterKey(ne)){
-							dojo.stopEvent(e);
+							event.stop(e);
 						}
 					}
 				});
@@ -108,28 +134,28 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 		}else if(this.blockNodeForEnter){
 			// add enter key handler
 			// FIXME: need to port to the new event code!!
-			var h = dojo.hitch(this,this.handleEnterKey);
+			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(e){
+	onKeyPressed: function(){
 		// summary:
 		//		Handler for keypress events.
 		// tags:
 		//		private
 		if(this._checkListLater){
-			if(dojo.withGlobal(this.editor.window, 'isCollapsed', dijit)){
-				var liparent=dojo.withGlobal(this.editor.window, 'getAncestorElement', dijit._editor.selection, ['LI']);
+			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
-					dijit._editor.RichText.prototype.execCommand.call(this.editor, 'formatblock',this.blockNodeForEnter);
+					RichText.prototype.execCommand.call(this.editor, 'formatblock',this.blockNodeForEnter);
 					// set the innerHTML of the new block node
-					var block = dojo.withGlobal(this.editor.window, 'getAncestorElement', dijit._editor.selection, [this.blockNodeForEnter]);
+					var block = win.withGlobal(this.editor.window, 'getAncestorElement', selection, [this.blockNodeForEnter]);
 					if(block){
 						block.innerHTML=this.bogusHtmlContent;
-						if(dojo.isIE){
+						if(has("ie")){
 							// move to the start by moving backwards one char
 							var r = this.editor.document.selection.createRange();
 							r.move('character',-1);
@@ -139,7 +165,7 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 						console.error('onKeyPressed: Cannot find the new block node'); // FIXME
 					}
 				}else{
-					if(dojo.isMoz){
+					if(has("mozilla")){
 						if(liparent.parentNode.parentNode.nodeName == 'LI'){
 							liparent=liparent.parentNode.parentNode;
 						}
@@ -147,9 +173,9 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 					var fc=liparent.firstChild;
 					if(fc && fc.nodeType == 1 && (fc.nodeName == 'UL' || fc.nodeName == 'OL')){
 						liparent.insertBefore(fc.ownerDocument.createTextNode('\xA0'),fc);
-						var newrange = dijit.range.create(this.editor.window);
+						var newrange = rangeapi.create(this.editor.window);
 						newrange.setStart(liparent.firstChild,0);
-						var selection = dijit.range.getSelection(this.editor.window, true);
+						var selection = rangeapi.getSelection(this.editor.window, true);
 						selection.removeAllRanges();
 						selection.addRange(newrange);
 					}
@@ -168,7 +194,7 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 
 	// bogusHtmlContent: [private] String
 	//		HTML to stick into a new empty block
-	bogusHtmlContent: ' ',
+	bogusHtmlContent: ' ',		//  
 
 	// blockNodes: [private] Regex
 	//		Regex for testing if a given tag is a block level (display:block) tag
@@ -176,7 +202,7 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 
 	handleEnterKey: function(e){
 		// summary:
-		//		Handler for enter key events when blockModeForEnter is DIV or P.
+		//		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.
@@ -185,28 +211,28 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 
 		var selection, range, newrange, startNode, endNode, brNode, doc=this.editor.document,br,rs,txt;
 		if(e.shiftKey){		// shift+enter always generates <br>
-			var parent = dojo.withGlobal(this.editor.window, "getParentElement", dijit._editor.selection);
-			var header = dijit.range.getAncestor(parent,this.blockNodes);
+			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
 				}
-				selection = dijit.range.getSelection(this.editor.window);
+				selection = rangeapi.getSelection(this.editor.window);
 				range = selection.getRangeAt(0);
 				if(!range.collapsed){
 					range.deleteContents();
-					selection = dijit.range.getSelection(this.editor.window);
+					selection = rangeapi.getSelection(this.editor.window);
 					range = selection.getRangeAt(0);
 				}
-				if(dijit.range.atBeginningOfContainer(header, range.startContainer, range.startOffset)){
+				if(rangeapi.atBeginningOfContainer(header, range.startContainer, range.startOffset)){
 						br=doc.createElement('br');
-						newrange = dijit.range.create(this.editor.window);
+						newrange = rangeapi.create(this.editor.window);
 						header.insertBefore(br,header.firstChild);
-						newrange.setStartBefore(br.nextSibling);
+						newrange.setStartAfter(br);
 						selection.removeAllRanges();
 						selection.addRange(newrange);
-				}else if(dijit.range.atEndOfContainer(header, range.startContainer, range.startOffset)){
-					newrange = dijit.range.create(this.editor.window);
+				}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'));
@@ -218,19 +244,19 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 					if(rs && rs.nodeType == 3){
 						// Text node, we have to split it.
 						txt = rs.nodeValue;
-						dojo.withGlobal(this.editor.window, function(){
+						win.withGlobal(this.editor.window, function(){
 							startNode = doc.createTextNode(txt.substring(0, range.startOffset));
 							endNode = doc.createTextNode(txt.substring(range.startOffset));
 							brNode = doc.createElement("br");
-							
-							if(endNode.nodeValue == "" && dojo.isWebKit){
+
+							if(endNode.nodeValue == "" && has("webkit")){
 								endNode = doc.createTextNode('\xA0')
 							}
-							dojo.place(startNode, rs, "after");
-							dojo.place(brNode, startNode, "after");
-							dojo.place(endNode, brNode, "after");
-							dojo.destroy(rs);
-							newrange = dijit.range.create(dojo.gobal);
+							domConstruct.place(startNode, rs, "after");
+							domConstruct.place(brNode, startNode, "after");
+							domConstruct.place(endNode, brNode, "after");
+							domConstruct.destroy(rs);
+							newrange = rangeapi.create();
 							newrange.setStart(endNode,0);
 							selection.removeAllRanges();
 							selection.addRange(newrange);
@@ -240,21 +266,21 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 					return true; // let browser handle
 				}
 			}else{
-				selection = dijit.range.getSelection(this.editor.window);
+				selection = rangeapi.getSelection(this.editor.window);
 				if(selection.rangeCount){
 					range = selection.getRangeAt(0);
 					if(range && range.startContainer){
 						if(!range.collapsed){
 							range.deleteContents();
-							selection = dijit.range.getSelection(this.editor.window);
+							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.
-							dojo.withGlobal(this.editor.window, dojo.hitch(this, function(){
+							win.withGlobal(this.editor.window, lang.hitch(this, function(){
 								var endEmpty = false;
-							
+
 								var offset = range.startOffset;
 								if(rs.length < offset){
 									//We are not splitting the right node, try to locate the correct one
@@ -263,53 +289,62 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 									offset = ret.offset;
 								}
 								txt = rs.nodeValue;
-				
+
 								startNode = doc.createTextNode(txt.substring(0, offset));
 								endNode = doc.createTextNode(txt.substring(offset));
 								brNode = doc.createElement("br");
-								
+
 								if(!endNode.length){
 									endNode = doc.createTextNode('\xA0');
 									endEmpty = true;
 								}
-								
+
 								if(startNode.length){
-									dojo.place(startNode, rs, "after");
+									domConstruct.place(startNode, rs, "after");
 								}else{
 									startNode = rs;
 								}
-								dojo.place(brNode, startNode, "after");
-								dojo.place(endNode, brNode, "after");
-								dojo.destroy(rs);
-								newrange = dijit.range.create(dojo.gobal);
+								domConstruct.place(brNode, startNode, "after");
+								domConstruct.place(endNode, brNode, "after");
+								domConstruct.destroy(rs);
+								newrange = rangeapi.create();
 								newrange.setStart(endNode,0);
 								newrange.setEnd(endNode, endNode.length);
 								selection.removeAllRanges();
 								selection.addRange(newrange);
-								if(endEmpty && !dojo.isWebKit){
-									dijit._editor.selection.remove();
+								if(endEmpty && !has("webkit")){
+									selectionapi.remove();
 								}else{
-									dijit._editor.selection.collapse(true);
+									selectionapi.collapse(true);
 								}
 							}));
 						}else{
-							dojo.withGlobal(this.editor.window, dojo.hitch(this, function(){
+							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");
-								rs.appendChild(brNode);
 								var endNode = doc.createTextNode('\xA0');
-								rs.appendChild(endNode);
-								newrange = dijit.range.create(dojo.global);
+								if(!targetNode){
+									rs.appendChild(brNode);
+									rs.appendChild(endNode);
+								}else{
+									domConstruct.place(brNode, targetNode, "before");
+									domConstruct.place(endNode, brNode, "after");
+								}
+								newrange = rangeapi.create(win.global);
 								newrange.setStart(endNode,0);
 								newrange.setEnd(endNode, endNode.length);
 								selection.removeAllRanges();
 								selection.addRange(newrange);
-								dijit._editor.selection.collapse(true);
+								selectionapi.collapse(true);
 							}));
 						}
 					}
 				}else{
 					// don't change this: do not call this.execCommand, as that may have other logic in subclass
-					dijit._editor.RichText.prototype.execCommand.call(this.editor, 'inserthtml', '<br>');
+					RichText.prototype.execCommand.call(this.editor, 'inserthtml', '<br>');
 				}
 			}
 			return false;
@@ -317,29 +352,29 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 		var _letBrowserHandle = true;
 
 		// first remove selection
-		selection = dijit.range.getSelection(this.editor.window);
+		selection = rangeapi.getSelection(this.editor.window);
 		range = selection.getRangeAt(0);
 		if(!range.collapsed){
 			range.deleteContents();
-			selection = dijit.range.getSelection(this.editor.window);
+			selection = rangeapi.getSelection(this.editor.window);
 			range = selection.getRangeAt(0);
 		}
 
-		var block = dijit.range.getBlockAncestor(range.endContainer, null, this.editor.editNode);
+		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(dojo.isMoz){
+			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)){
+			if(/^(\s| | |\xA0|<span\b[^>]*\bclass=['"]Apple-style-span['"][^>]*>(\s| | |\xA0)<\/span>)?(<br>)?$/.test(blockNode.innerHTML)){
 				// empty LI node
 				blockNode.innerHTML = '';
-				if(dojo.isWebKit){ // WebKit tosses the range when innerHTML is reset
-					newrange = dijit.range.create(this.editor.window);
+				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);
@@ -352,11 +387,11 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 		// text node directly under body, let's wrap them in a node
 		if(!block.blockNode || block.blockNode===this.editor.editNode){
 			try{
-				dijit._editor.RichText.prototype.execCommand.call(this.editor, 'formatblock',this.blockNodeForEnter);
+				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:dojo.withGlobal(this.editor.window, "getAncestorElement", dijit._editor.selection, [this.blockNodeForEnter]),
+			block = {blockNode:win.withGlobal(this.editor.window, "getAncestorElement", selectionapi, [this.blockNodeForEnter]),
 					blockContainer: this.editor.editNode};
 			if(block.blockNode){
 				if(block.blockNode != this.editor.editNode &&
@@ -367,7 +402,7 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 			}else{	// we shouldn't be here if formatblock worked
 				block.blockNode = this.editor.editNode;
 			}
-			selection = dijit.range.getSelection(this.editor.window);
+			selection = rangeapi.getSelection(this.editor.window);
 			range = selection.getRangeAt(0);
 		}
 
@@ -382,39 +417,39 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 			node = ret.node;
 			endOffset = ret.offset;
 		}
-		if(dijit.range.atEndOfContainer(block.blockNode, node, endOffset)){
+		if(rangeapi.atEndOfContainer(block.blockNode, node, endOffset)){
 			if(block.blockNode === block.blockContainer){
 				block.blockNode.appendChild(newblock);
 			}else{
-				dojo.place(newblock, block.blockNode, "after");
+				domConstruct.place(newblock, block.blockNode, "after");
 			}
 			_letBrowserHandle = false;
 			// lets move caret to the newly created block
-			newrange = dijit.range.create(this.editor.window);
+			newrange = rangeapi.create(this.editor.window);
 			newrange.setStart(newblock, 0);
 			selection.removeAllRanges();
 			selection.addRange(newrange);
 			if(this.editor.height){
-				dojo.window.scrollIntoView(newblock);
+				winUtils.scrollIntoView(newblock);
 			}
-		}else if(dijit.range.atBeginningOfContainer(block.blockNode,
+		}else if(rangeapi.atBeginningOfContainer(block.blockNode,
 				range.startContainer, range.startOffset)){
-			dojo.place(newblock, block.blockNode, block.blockNode === block.blockContainer ? "first" : "before");
+			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 = dijit.range.create(this.editor.window);
+				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
-				dojo.window.scrollIntoView(newblock.nextSibling);
+				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{
-				dojo.place(newblock, block.blockNode, "after");
+				domConstruct.place(newblock, block.blockNode, "after");
 			}
 			_letBrowserHandle = false;
 
@@ -426,11 +461,11 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 					}
 				}
 			}
-			
+
 			// Okay, we probably have to split.
 			rs = range.startContainer;
 			var firstNodeMoved;
-			if(rs && rs.nodeType == 3){ 
+			if(rs && rs.nodeType == 3){
 				// Text node, we have to split it.
 				var nodeToMove, tNode;
 				endOffset = range.endOffset;
@@ -440,15 +475,15 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 					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.
-				dojo.place(startNode, rs, "before");
-				dojo.place(endNode, rs, "after");
-				dojo.destroy(rs);
+				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
@@ -465,7 +500,7 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 							}
 						}
 					}
-					// If font also need to clone over any font data. 
+					// If font also need to clone over any font data.
 					if(parentC.tagName === "FONT"){
 						if(parentC.color){
 							newTg.color = parentC.color;
@@ -477,14 +512,14 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 							newTg.size = parentC.size;
 						}
 					}
-					
+
 					nodeToMove = endNode;
 					while(nodeToMove){
 						tNode = nodeToMove.nextSibling;
 						newTg.appendChild(nodeToMove);
 						nodeToMove = tNode;
 					}
-					dojo.place(newTg, parentC, "after");
+					domConstruct.place(newTg, parentC, "after");
 					startNode = parentC;
 					endNode = newTg;
 					parentC = parentC.parentNode;
@@ -505,9 +540,9 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 					nodeToMove = tNode;
 				}
 			}
-			
+
 			//lets move caret to the newly created block
-			newrange = dijit.range.create(this.editor.window);
+			newrange = rangeapi.create(this.editor.window);
 			var nodeForCursor;
 			var innerMostFirstNodeMoved = firstNodeMoved;
 			if(this.blockNodeForEnter !== 'BR'){
@@ -522,12 +557,12 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 					selection.removeAllRanges();
 					selection.addRange(newrange);
 					if(this.editor.height){
-						dijit.scrollIntoView(newblock);
+						winUtils.scrollIntoView(newblock);
 					}
-					if(dojo.isMoz){
+					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;
 				}
@@ -536,9 +571,9 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 				selection.removeAllRanges();
 				selection.addRange(newrange);
 				if(this.editor.height){
-					dijit.scrollIntoView(newblock);
+					winUtils.scrollIntoView(newblock);
 				}
-				if(dojo.isMoz){
+				if(has("mozilla")){
 					// press enter in middle of P may leave a trailing <br/>, let's remove it later
 					this._pressedEnterInBlock = block.blockNode;
 				}
@@ -562,8 +597,7 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 			offset = offset - node.length;
 			node = node.nextSibling;
 		}
-		var ret = {"node": node, "offset": offset};
-		return ret;
+		return {"node": node, "offset": offset};
 	},
 
 	removeTrailingBr: function(container){
@@ -572,14 +606,14 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 		// tags:
 		//		private
 		var para = /P|DIV|LI/i.test(container.tagName) ?
-			container : dijit._editor.selection.getParentOfType(container,['P','DIV','LI']);
+			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'){
 
-				dojo.destroy(para.lastChild);
+				domConstruct.destroy(para.lastChild);
 			}
 		}
 		if(!para.childNodes.length){
@@ -588,5 +622,4 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 	}
 });
 
-return dijit._editor.plugins.EnterKeyHandling;
-});
\ No newline at end of file
+});
diff --git a/dijit/_editor/plugins/FontChoice.js b/dijit/_editor/plugins/FontChoice.js
index 058606f..042b693 100644
--- a/dijit/_editor/plugins/FontChoice.js
+++ b/dijit/_editor/plugins/FontChoice.js
@@ -1,7 +1,40 @@
-define("dijit/_editor/plugins/FontChoice", ["dojo", "dijit", "dijit/_editor/_Plugin", "dijit/_editor/range", "dijit/_editor/selection", "dijit/form/FilteringSelect", "dojo/data/ItemFileReadStore", "dojo/i18n", "i18n!dijit/_editor/nls/FontChoice"], function(dojo, dijit) {
-
-dojo.declare("dijit._editor.plugins._FontDropDown",
-	[dijit._Widget, dijit._Templated],{
+define([
+	"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",
+	"../../_WidgetsInTemplateMixin",
+	"../../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.
@@ -11,10 +44,6 @@ dojo.declare("dijit._editor.plugins._FontDropDown",
 	//		The label to apply to this particular FontDropDown.
 	label: "",
 
-	// widgetsInTemplate: [public] boolean
-	//		Over-ride denoting the template has widgets to parse.
-	widgetsInTemplate: true,
-
 	// plainText: [public] boolean
 	//		Flag to indicate that the returned label should be plain text
 	//		instead of an example.
@@ -25,8 +54,9 @@ dojo.declare("dijit._editor.plugins._FontDropDown",
 	templateString:
 		"<span style='white-space: nowrap' class='dijit dijitReset dijitInline'>" +
 			"<label class='dijitLeft dijitInline' for='${selectId}'>${label}</label>" +
-			"<input dojoType='dijit.form.FilteringSelect' required='false' labelType='html' labelAttr='label' searchAttr='name' " +
-					"tabIndex='-1' id='${selectId}' dojoAttachPoint='select' value=''/>" +
+			"<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(){
@@ -34,12 +64,12 @@ dojo.declare("dijit._editor.plugins._FontDropDown",
 		//		Over-ride to set specific properties.
 		this.inherited(arguments);
 
-		this.strings = dojo.i18n.getLocalization("dijit._editor", "FontChoice");
+		this.strings = i18n.getLocalization("dijit._editor", "FontChoice");
 
 		// Set some substitution variables used in the template
 		this.label = this.strings[this.command];
-		this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
-		this.selectId = this.id + "_select";
+		this.id = registry.getUniqueId(this.declaredClass.replace(/\./g,"_"));	// TODO: unneeded??
+		this.selectId = this.id + "_select";	// used in template
 
 		this.inherited(arguments);
 	},
@@ -51,21 +81,17 @@ dojo.declare("dijit._editor.plugins._FontDropDown",
 
 		// 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>" }
-		var	items = dojo.map(this.values, function(value){
+		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.store = new dojo.data.ItemFileReadStore({
-			data: {
-				identifier: "value",
-				items: items
-			}
-		});
+			}, this)
+		}));
 
 		this.select.set("value", "", false);
 		this.disabled = this.select.get("disabled");
@@ -81,9 +107,9 @@ dojo.declare("dijit._editor.plugins._FontDropDown",
 		//		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?true:false;
-		this.select.set('value', dojo.indexOf(this.values,value) < 0 ? "" : value, priorityChange);
+		// 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;
@@ -92,7 +118,7 @@ dojo.declare("dijit._editor.plugins._FontDropDown",
 
 	_getValueAttr: function(){
 		// summary:
-		//		Allow retreiving the value from the composite select on
+		//		Allow retrieving the value from the composite select on
 		//		call to button.get("value");
 		return this.select.get('value');
 	},
@@ -117,7 +143,7 @@ dojo.declare("dijit._editor.plugins._FontDropDown",
 });
 
 
-dojo.declare("dijit._editor.plugins._FontNameDropDown", dijit._editor.plugins._FontDropDown, {
+var _FontNameDropDown = declare("dijit._editor.plugins._FontNameDropDown", _FontDropDown, {
 	// summary:
 	//		Dropdown to select a font; goes in editor toolbar.
 
@@ -161,7 +187,7 @@ dojo.declare("dijit._editor.plugins._FontNameDropDown", dijit._editor.plugins._F
 		//		Over-ride for the default action of setting the
 		//		widget value, maps the input to known values
 
-		priorityChange = priorityChange !== false?true:false;
+		priorityChange = priorityChange !== false;
 		if(this.generic){
 			var map = {
 				"Arial": "sans-serif",
@@ -173,8 +199,9 @@ dojo.declare("dijit._editor.plugins._FontNameDropDown", dijit._editor.plugins._F
 				"Apple Chancery": "cursive",
 				"Courier": "monospace",
 				"Courier New": "monospace",
-				"Papyrus": "fantasy"
-//					,"????": "fantasy" TODO: IE doesn't map fantasy font-family?
+				"Papyrus": "fantasy",
+				"Estrangelo Edessa": "cursive", // Windows 7
+				"Gabriola": "fantasy" // Windows 7
 			};
 			value = map[value] || value;
 		}
@@ -182,7 +209,7 @@ dojo.declare("dijit._editor.plugins._FontNameDropDown", dijit._editor.plugins._F
 	}
 });
 
-dojo.declare("dijit._editor.plugins._FontSizeDropDown", dijit._editor.plugins._FontDropDown, {
+var _FontSizeDropDown = declare("dijit._editor.plugins._FontSizeDropDown", _FontDropDown, {
 	// summary:
 	//		Dropdown to select a font size; goes in editor toolbar.
 
@@ -216,7 +243,7 @@ dojo.declare("dijit._editor.plugins._FontSizeDropDown", dijit._editor.plugins._F
 		// summary:
 		//		Over-ride for the default action of setting the
 		//		widget value, maps the input to known values
-		priorityChange = priorityChange !== false?true:false;
+		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;
@@ -227,7 +254,7 @@ dojo.declare("dijit._editor.plugins._FontSizeDropDown", dijit._editor.plugins._F
 });
 
 
-dojo.declare("dijit._editor.plugins._FormatBlockDropDown", dijit._editor.plugins._FontDropDown, {
+var _FormatBlockDropDown = declare("dijit._editor.plugins._FormatBlockDropDown", _FontDropDown, {
 	// summary:
 	//		Dropdown to select a format (like paragraph or heading); goes in editor toolbar.
 
@@ -269,7 +296,7 @@ dojo.declare("dijit._editor.plugins._FormatBlockDropDown", dijit._editor.plugins
 		if(choice === "noFormat"){
 			var start;
 			var end;
-			var sel = dijit.range.getSelection(editor.window);
+			var sel = rangeapi.getSelection(editor.window);
 			if(sel && sel.rangeCount > 0){
 				var range = sel.getRangeAt(0);
 				var node, tag;
@@ -290,25 +317,25 @@ dojo.declare("dijit._editor.plugins._FormatBlockDropDown", dijit._editor.plugins
 						end = end.parentNode;
 					}
 
-					var processChildren = dojo.hitch(this, function(node, array){
+					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(dojo.withGlobal(editor.window, "inSelection", dijit._editor.selection, [c])){
+									if(win.withGlobal(editor.window, "inSelection", selectionapi, [c])){
 										var tag = c.tagName? c.tagName.toLowerCase(): "";
-										if(dojo.indexOf(this.values, tag) !== -1){
-											array.push(c);
+										if(array.indexOf(this.values, tag) !== -1){
+											ary.push(c);
 										}
-										processChildren(c,array);
+										processChildren(c, ary);
 									}
 								}
 							}
 						}
 					});
 
-					var unformatNodes = dojo.hitch(this, function(nodes){
+					var unformatNodes = lang.hitch(this, function(nodes){
 						// summary:
 						//		Internal function to clear format nodes.
 						// nodes:
@@ -331,7 +358,7 @@ dojo.declare("dijit._editor.plugins._FormatBlockDropDown", dijit._editor.plugins
 						while(node && node !== editor.editNode && node !== editor.document.body){
 							if(node.nodeType == 1){
 								tag = node.tagName? node.tagName.toLowerCase(): "";
-								if(dojo.indexOf(this.values, tag) !== -1){
+								if(array.indexOf(this.values, tag) !== -1){
 									block = node;
 									break;
 								}
@@ -342,15 +369,15 @@ dojo.declare("dijit._editor.plugins._FormatBlockDropDown", dijit._editor.plugins
 						//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); }
+						if(block){ clearNodes = [block].concat(clearNodes); }
 						unformatNodes(clearNodes);
 					}else{
 						// Probably a multi select, so we have to process it.  Whee.
 						node = start;
-						while(dojo.withGlobal(editor.window, "inSelection", dijit._editor.selection, [node])){
+						while(win.withGlobal(editor.window, "inSelection", selectionapi, [node])){
 							if(node.nodeType == 1){
 								tag = node.tagName? node.tagName.toLowerCase(): "";
-								if(dojo.indexOf(this.values, tag) !== -1){
+								if(array.indexOf(this.values, tag) !== -1){
 									clearNodes.push(node);
 								}
 								processChildren(node,clearNodes);
@@ -378,18 +405,18 @@ dojo.declare("dijit._editor.plugins._FormatBlockDropDown", dijit._editor.plugins
 			// customUndo and we turned it on for WebKit.  WebKit pasted funny,
 			// so couldn't use the execCommand approach
 			while(node.firstChild){
-				dojo.place(node.firstChild, node, "before");
+				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.
-			dojo.withGlobal(editor.window,
-				 "selectElementChildren", dijit._editor.selection, [node]);
-			var html = 	dojo.withGlobal(editor.window,
-				 "getSelectedHtml", dijit._editor.selection, [null]);
-			dojo.withGlobal(editor.window,
-				 "selectElement", dijit._editor.selection, [node]);
+			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||"");
 		}
 	}
@@ -397,7 +424,7 @@ dojo.declare("dijit._editor.plugins._FormatBlockDropDown", dijit._editor.plugins
 
 // TODO: for 2.0, split into FontChoice plugin into three separate classes,
 // one for each command (and change registry below)
-dojo.declare("dijit._editor.plugins.FontChoice", dijit._editor._Plugin,{
+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.
@@ -429,7 +456,7 @@ dojo.declare("dijit._editor.plugins.FontChoice", dijit._editor._Plugin,{
 	//		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] booleam
+	// useDefaultCommand: [protected] Boolean
 	//		Override _Plugin.useDefaultCommand...
 	//		processing is handled by this plugin, not by dijit.Editor.
 	useDefaultCommand: false,
@@ -443,9 +470,9 @@ dojo.declare("dijit._editor.plugins.FontChoice", dijit._editor._Plugin,{
 
 		// Create the widget to go into the toolbar (the so-called "button")
 		var clazz = {
-				fontName: dijit._editor.plugins._FontNameDropDown,
-				fontSize: dijit._editor.plugins._FontSizeDropDown,
-				formatBlock: dijit._editor.plugins._FormatBlockDropDown
+				fontName: _FontNameDropDown,
+				fontSize: _FontSizeDropDown,
+				formatBlock: _FormatBlockDropDown
 			}[this.command],
 		params = this.params;
 
@@ -456,14 +483,14 @@ dojo.declare("dijit._editor.plugins.FontChoice", dijit._editor._Plugin,{
 		}
 
 		var editor = this.editor;
-		this.button = new clazz(dojo.delegate({dir: editor.dir, lang: editor.lang}, params));
+		this.button = new clazz(lang.delegate({dir: editor.dir, lang: editor.lang}, params));
 
 		// 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.command == "fontName" && choice.indexOf(" ") != -1){ choice = "'" + choice + "'"; }
 
 			// Invoke, the editor already normalizes commands called through its
@@ -488,7 +515,7 @@ dojo.declare("dijit._editor.plugins.FontChoice", dijit._editor._Plugin,{
 		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);
@@ -502,7 +529,7 @@ dojo.declare("dijit._editor.plugins.FontChoice", dijit._editor._Plugin,{
 			}
 
 			// strip off single quotes, if any
-			var quoted = dojo.isString(value) && value.match(/'([^']*)'/);
+			var quoted = lang.isString(value) && value.match(/'([^']*)'/);
 			if(quoted){ value = quoted[1]; }
 
 			if(_c === "formatBlock"){
@@ -513,7 +540,7 @@ dojo.declare("dijit._editor.plugins.FontChoice", dijit._editor._Plugin,{
 					value = null;
 					var elem;
 					// Try to find the current element where the caret is.
-					var sel = dijit.range.getSelection(this.editor.window);
+					var sel = rangeapi.getSelection(this.editor.window);
 					if(sel && sel.rangeCount > 0){
 						var range = sel.getRangeAt(0);
 						if(range){
@@ -524,7 +551,7 @@ dojo.declare("dijit._editor.plugins.FontChoice", dijit._editor._Plugin,{
 					// 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 && dojo.indexOf(this.button.values, tg) > -1){
+						if(tg && array.indexOf(this.button.values, tg) > -1){
 							value = tg;
 							break;
 						}
@@ -537,7 +564,7 @@ dojo.declare("dijit._editor.plugins.FontChoice", dijit._editor._Plugin,{
 				}else{
 					// Check that the block format is one allowed, if not,
 					// null it so that it gets set to empty.
-					if(dojo.indexOf(this.button.values, value) < 0){
+					if(array.indexOf(this.button.values, value) < 0){
 						value = "noFormat";
 					}
 				}
@@ -551,18 +578,14 @@ dojo.declare("dijit._editor.plugins.FontChoice", dijit._editor._Plugin,{
 	}
 });
 
-// Register this plugin.
-dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
-	if(o.plugin){ return; }
-	switch(o.args.name){
-	case "fontName": case "fontSize": case "formatBlock":
-		o.plugin = new dijit._editor.plugins.FontChoice({
-			command: o.args.name,
-			plainText: o.args.plainText?o.args.plainText:false
+// Register these plugins
+array.forEach(["fontName", "fontSize", "formatBlock"], function(name){
+	_Plugin.registry[name] = function(args){
+		return new FontChoice({
+			command: name,
+			plainText: args.plainText
 		});
-	}
+	};
 });
 
-
-return dijit._editor.plugins.FontChoice;
 });
diff --git a/dijit/_editor/plugins/FullScreen.js b/dijit/_editor/plugins/FullScreen.js
index 0e5d4e8..8cbe9df 100755
--- a/dijit/_editor/plugins/FullScreen.js
+++ b/dijit/_editor/plugins/FullScreen.js
@@ -1,8 +1,42 @@
-define("dijit/_editor/plugins/FullScreen", ["dojo", "dijit", "dojo/window", "dojo/i18n", "dijit/_editor/_Plugin", "dijit/form/Button", "i18n!dijit/_editor/nls/commands"], function(dojo, dijit) {
-
-dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
+define([
+	"dojo/aspect",
+	"dojo/_base/declare", // declare
+	"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/_base/window", // win.body
+	"dojo/window", // winUtils.getBox winUtils.scrollIntoView
+	"../../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,
+			focus, _Plugin, ToggleButton, registry){
+
+/*=====
+	var _Plugin = dijit._editor._Plugin;
+=====*/
+
+
+// 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 cabability to the editor.  When
+	//		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.
@@ -37,16 +71,16 @@ dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
 	_initButton: function(){
 		// summary:
 		//		Over-ride for creation of the resize button.
-		var strings = dojo.i18n.getLocalization("dijit._editor", "commands"),
+		var strings = i18n.getLocalization("dijit._editor", "commands"),
 			editor = this.editor;
-		this.button = new dijit.form.ToggleButton({
+		this.button = new ToggleButton({
 			label: strings["fullScreen"],
 			dir: editor.dir,
 			lang: editor.lang,
 			showLabel: false,
 			iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "FullScreen",
 			tabIndex: "-1",
-			onChange: dojo.hitch(this, "_setFullScreen")
+			onChange: lang.hitch(this, "_setFullScreen")
 		});
 	},
 
@@ -58,11 +92,11 @@ dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
 		this.editor = editor;
 		this._initButton();
 
-		this.editor.addKeyHandler(dojo.keys.F11, true, true, dojo.hitch(this, function(e){
+		this.editor.addKeyHandler(keys.F11, true, true, lang.hitch(this, function(e){
 			// Enable the CTRL-SHIFT-F11 hotkey for fullscreen mode.
 			this.toggle();
-			dojo.stopEvent(e);
-			setTimeout(dojo.hitch(this, function(){this.editor.focus();}), 250);
+			event.stop(e);
+			setTimeout(lang.hitch(this, function(){this.editor.focus();}), 250);
 			return true;
 		}));
 		this.connect(this.editor.domNode, "onkeydown", "_containFocus");
@@ -80,31 +114,31 @@ dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
 			var ed = this.editor;
 			if(!ed.isTabIndent &&
 				ed._fullscreen_oldOnKeyDown &&
-				e.keyCode === dojo.keys.TAB){
+				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 = dijit.getFocus();
+				var f = focus.curNode;
 				var avn = this._getAltViewNode();
-				if(f.node == ed.iframe ||
-					(avn && f.node === avn)){
-					setTimeout(dojo.hitch(this, function(){
+				if(f == ed.iframe ||
+					(avn && f === avn)){
+					setTimeout(lang.hitch(this, function(){
 						ed.toolbar.focus();
 					}), 10);
 				}else{
-					if(avn && dojo.style(ed.iframe, "display") === "none"){
-						setTimeout(dojo.hitch(this, function(){
-							dijit.focus(avn);
+					if(avn && domStyle.get(ed.iframe, "display") === "none"){
+						setTimeout(lang.hitch(this, function(){
+							focus.focus(avn);
 						}), 10);
 					}else{
-						setTimeout(dojo.hitch(this, function(){
+						setTimeout(lang.hitch(this, function(){
 							ed.focus();
 						}), 10);
 					}
 				}
-				dojo.stopEvent(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.
@@ -119,25 +153,25 @@ dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
 		//		resizes (window scaled)
 		// tags:
 		//		private
-		var vp = dojo.window.getBox();
-		dojo.marginBox(this.editor.domNode, {
+		var vp = winUtils.getBox();
+		domGeometry.setMarginBox(this.editor.domNode, {
 			w: vp.w,
 			h: vp.h
 		});
 
-		//Adjust the inernal heights too, as they can be a bit off.
+		//Adjust the internal heights too, as they can be a bit off.
 		var hHeight = this.editor.getHeaderHeight();
 		var fHeight = this.editor.getFooterHeight();
-		var extents = dojo._getPadBorderExtents(this.editor.domNode);
-		var fcpExtents = dojo._getPadBorderExtents(this.editor.iframe.parentNode);
-		var fcmExtents = dojo._getMarginExtents(this.editor.iframe.parentNode);
-		
+		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);
-		dojo.marginBox(this.editor.iframe.parentNode, {
+		domGeometry.setMarginBox(this.editor.iframe.parentNode, {
 			h: cHeight,
 			w: vp.w
 		});
-		dojo.marginBox(this.editor.iframe, {
+		domGeometry.setMarginBox(this.editor.iframe, {
 			h: cHeight - (fcpExtents.h + fcmExtents.h)
 		});
 	},
@@ -157,57 +191,57 @@ dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
 		//		regular view.
 		// tags:
 		//		private
-		var vp = dojo.window.getBox();
+		var vp = winUtils.getBox();
 
 		//Alias this for shorter code.
 		var ed = this.editor;
-		var body = dojo.body();
+		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 eveything to position static.
-			while(editorParent && editorParent !== dojo.body()){
-				dojo.addClass(editorParent, "dijitForceStatic");
+			//have to set everything to position static.
+			while(editorParent && editorParent !== win.body()){
+				domClass.add(editorParent, "dijitForceStatic");
 				editorParent = editorParent.parentNode;
 			}
 
 			// Save off the resize function.  We want to kill its behavior.
 			this._editorResizeHolder = this.editor.resize;
-			ed.resize = function() {} ;
+			ed.resize = function(){} ;
 
 			// Try to constrain focus control.
 			ed._fullscreen_oldOnKeyDown = ed.onKeyDown;
-			ed.onKeyDown = dojo.hitch(this, this._containFocus);
+			ed.onKeyDown = lang.hitch(this, this._containFocus);
 
 			this._origState = {};
 			this._origiFrameState = {};
 
 			// Store the basic editor state we have to restore later.
-			// Not using dojo.style here, had problems, didn't
+			// 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,
-				domStyle = domNode && domNode.style || {};
+				rawStyle = domNode && domNode.style || {};
 			this._origState = {
-				width: domStyle.width || "",
-				height: domStyle.height || "",
-				top: dojo.style(domNode, "top") || "",
-				left: dojo.style(domNode, "left") || "",
-				position: dojo.style(domNode, "position") || "static",
-				marginBox: dojo.marginBox(ed.domNode)
+				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 dojo.style here, had problems, didn't
+			// 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 = dojo.style(ed.iframe, "backgroundColor");
+			var bc = domStyle.get(ed.iframe, "backgroundColor");
 			this._origiFrameState = {
 				backgroundColor: bc || "transparent",
 				width: iframeStyle.width || "auto",
@@ -216,7 +250,7 @@ dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
 			};
 
 			// Okay, size everything.
-			dojo.style(ed.domNode, {
+			domStyle.set(ed.domNode, {
 				position: "absolute",
 				top: "0px",
 				left: "0px",
@@ -225,7 +259,7 @@ dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
 				height: vp.h + "px"
 			});
 
-			dojo.style(ed.iframe, {
+			domStyle.set(ed.iframe, {
 				height: "100%",
 				width: "100%",
 				zIndex: this.zIndex,
@@ -233,7 +267,7 @@ dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
 					bc !== "rgba(0, 0, 0, 0)"?bc:"white"
 			});
 
-			dojo.style(ed.iframe.parentNode, {
+			domStyle.set(ed.iframe.parentNode, {
 				height: "95%",
 				width: "100%"
 			});
@@ -241,12 +275,12 @@ dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
 			// 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 = dojo.style(body, "overflow");
+				this._oldOverflow = domStyle.get(body, "overflow");
 			}else{
 				this._oldOverflow = "";
 			}
 
-			if(dojo.isIE && !dojo.isQuirks){
+			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.
@@ -256,20 +290,20 @@ dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
 					this._oldBodyParentOverflow = body.parentNode.style.overflow;
 				}else{
 					try{
-						this._oldBodyParentOverflow = dojo.style(body.parentNode, "overflow");
+						this._oldBodyParentOverflow = domStyle.get(body.parentNode, "overflow");
 					}catch(e){
 						this._oldBodyParentOverflow = "scroll";
 					}
 				}
-				dojo.style(body.parentNode, "overflow", "hidden");
+				domStyle.set(body.parentNode, "overflow", "hidden");
 			}
-			dojo.style(body, "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 = dojo.window.getBox();
+				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){
@@ -285,20 +319,20 @@ dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
 				}
 				// Timeout it to help avoid spamming resize on IE.
 				// Works for all browsers.
-				this._resizer = setTimeout(dojo.hitch(this, function(){
+				this._resizer = setTimeout(lang.hitch(this, function(){
 					delete this._resizer;
 					this._resizeEditor();
 				}), 10);
 			};
-			this._resizeHandle = dojo.connect(window, "onresize", this, resizer);
+			this._resizeHandle = on(window, "resize", lang.hitch(this, resizer));
 
 			// Also monitor for direct calls to resize and adapt editor.
-			this._resizeHandle2 = dojo.connect(ed, "resize", dojo.hitch(this, function(){
+			this._resizeHandle2 = aspect.after(ed, "onResize", lang.hitch(this, function(){
 				if(this._resizer){
 					clearTimeout(this._resizer);
 					delete this._resizer;
 				}
-				this._resizer = setTimeout(dojo.hitch(this, function(){
+				this._resizer = setTimeout(lang.hitch(this, function(){
 					delete this._resizer;
 					this._resizeEditor();
 				}), 10);
@@ -307,29 +341,29 @@ dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
 			// Call it once to work around IE glitchiness.  Safe for other browsers too.
 			this._resizeEditor();
 			var dn = this.editor.toolbar.domNode;
-			setTimeout(function(){dojo.window.scrollIntoView(dn);}, 250);
+			setTimeout(function(){winUtils.scrollIntoView(dn);}, 250);
 		}else{
 			if(this._resizeHandle){
 				// Cleanup resizing listeners
-				dojo.disconnect(this._resizeHandle);
+				this._resizeHandle.remove();
 				this._resizeHandle = null;
 			}
 			if(this._resizeHandle2){
 				// Cleanup resizing listeners
-				dojo.disconnect(this._resizeHandle2);
+				this._resizeHandle2.remove();
 				this._resizeHandle2 = null;
 			}
 			if(this._rst){
 				clearTimeout(this._rst);
 				this._rst = null;
 			}
-			
+
 			//Remove all position static class assigns.
-			while(editorParent && editorParent !== dojo.body()){
-				dojo.removeClass(editorParent, "dijitForceStatic");
+			while(editorParent && editorParent !== win.body()){
+				domClass.remove(editorParent, "dijitForceStatic");
 				editorParent = editorParent.parentNode;
 			}
-			
+
 			// Restore resize function
 			if(this._editorResizeHolder){
 				this.editor.resize = this._editorResizeHolder;
@@ -351,24 +385,24 @@ dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
 				// Restore all the editor state.
 				var mb = self._origState.marginBox;
 				var oh = self._origState.height;
-				if(dojo.isIE && !dojo.isQuirks){
+				if(has("ie") && !has("quirks")){
 					body.parentNode.style.overflow = self._oldBodyParentOverflow;
 					delete self._oldBodyParentOverflow;
 				}
-				dojo.style(body, "overflow", self._oldOverflow);
+				domStyle.set(body, "overflow", self._oldOverflow);
 				delete self._oldOverflow;
 
-				dojo.style(ed.domNode, self._origState);
-				dojo.style(ed.iframe.parentNode, {
+				domStyle.set(ed.domNode, self._origState);
+				domStyle.set(ed.iframe.parentNode, {
 					height: "",
 					width: ""
 				});
-				dojo.style(ed.iframe, self._origiFrameState);
+				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 = dijit.getEnclosingWidget(ed.domNode.parentNode);
+				var pWidget = registry.getEnclosingWidget(ed.domNode.parentNode);
 				if(pWidget && pWidget.resize){
 					pWidget.resize();
 				}else{
@@ -376,10 +410,10 @@ dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
 						// Resize if the original size wasn't set
 						// or wasn't in percent.  Timeout is to avoid
 						// an IE crash in unit testing.
-						setTimeout(dojo.hitch(this, function(){ed.resize({h: mb.h});}), 0);
+						setTimeout(lang.hitch(this, function(){ed.resize({h: mb.h});}), 0);
 					}
 				}
-				dojo.window.scrollIntoView(self.editor.toolbar.domNode);
+				winUtils.scrollIntoView(self.editor.toolbar.domNode);
 			}, 100);
 		}
 	},
@@ -395,12 +429,12 @@ dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
 		//		Over-ride to ensure the resize handle gets cleaned up.
 		if(this._resizeHandle){
 			// Cleanup resizing listeners
-			dojo.disconnect(this._resizeHandle);
+			this._resizeHandle.remove();
 			this._resizeHandle = null;
 		}
 		if(this._resizeHandle2){
 			// Cleanup resizing listeners
-			dojo.disconnect(this._resizeHandle2);
+			this._resizeHandle2.remove();
 			this._resizeHandle2 = null;
 		}
 		if(this._resizer){
@@ -411,18 +445,13 @@ dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
 	}
 });
 
-
 // Register this plugin.
-dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
-	if(o.plugin){ return; }
-	var name = o.args.name.toLowerCase();
-	if(name === "fullscreen"){
-		o.plugin = new dijit._editor.plugins.FullScreen({
-			zIndex: ("zIndex" in o.args)?o.args.zIndex:500
-		});
-	}
-});
-
-
-return dijit._editor.plugins.FullScreen;
+// 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 75dfcf5..a2e1d32 100644
--- a/dijit/_editor/plugins/LinkDialog.js
+++ b/dijit/_editor/plugins/LinkDialog.js
@@ -1,6 +1,31 @@
-define("dijit/_editor/plugins/LinkDialog", ["dojo", "dijit", "dijit/_Widget", "dijit/_editor/_Plugin", "dijit/TooltipDialog", "dijit/form/DropDownButton", "dijit/form/ValidationTextBox", "dijit/form/Select", "dijit/_editor/range", "dojo/i18n", "dojo/string", "i18n!dijit/nls/common", "i18n!dijit/_editor/nls/LinkDialog"], function(dojo, dijit) {
-
-dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
+define([
+	"require",
+	"dojo/_base/declare", // declare
+	"dojo/dom-attr", // domAttr.get
+	"dojo/keys", // keys.ENTER
+	"dojo/_base/lang", // lang.delegate lang.hitch lang.trim
+	"dojo/_base/sniff", // has("ie")
+	"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.
@@ -11,7 +36,7 @@ dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
 
 	// Override _Plugin.buttonClass.   This plugin is controlled by a DropDownButton
 	// (which triggers a TooltipDialog).
-	buttonClass: dijit.form.DropDownButton,
+	buttonClass: DropDownButton,
 
 	// Override _Plugin.useDefaultCommand... processing is handled by this plugin, not by dijit.Editor.
 	useDefaultCommand: false,
@@ -38,11 +63,11 @@ dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
 
 	// _hostRxp [private] RegExp
 	//		Regular expression used to validate url fragments (ip address, hostname, etc)
-	_hostRxp:  new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$"),
+	_hostRxp: /^((([^\[:]+):)?([^@]+)@)?(\[([^\]]+)\]|([^\[:]*))(:([0-9]+))?$/,
 
 	// _userAtRxp [private] RegExp
 	//		Regular expression used to validate e-mail address fragment.
-	_userAtRxp: new RegExp("^([!#-'*+\\-\\/-9=?A-Z^-~]+[.])*[!#-'*+\\-\\/-9=?A-Z^-~]+@", "i"),
+	_userAtRxp: /^([!#-'*+\-\/-9=?A-Z^-~]+[.])*[!#-'*+\-\/-9=?A-Z^-~]+@/i,
 
 	// linkDialogTemplate: [protected] String
 	//		Template for contents of TooltipDialog to pick URL
@@ -50,76 +75,105 @@ dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
 		"<table><tr><td>",
 		"<label for='${id}_urlInput'>${url}</label>",
 		"</td><td>",
-		"<input dojoType='dijit.form.ValidationTextBox' required='true' " +
-		"id='${id}_urlInput' name='urlInput' intermediateChanges='true'/>",
+		"<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 dojoType='dijit.form.ValidationTextBox' required='true' id='${id}_textInput' " +
-		"name='textInput' intermediateChanges='true'/>",
+		"<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' dojoType='dijit.form.Select'>",
+		"<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 dojoType='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>",
-		"<button dojoType='dijit.form.Button' type='button' id='${id}_cancelButton'>${buttonCancel}</button>",
+		"<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(){
-		// Override _Plugin._initButton() to initialize DropDownButton and TooltipDialog.
-		var _this = this;
-		this.tag = this.command == 'insertImage' ? 'img' : 'a';
-		var messages = dojo.mixin(dojo.i18n.getLocalization("dijit", "common", this.lang),
-			dojo.i18n.getLocalization("dijit._editor", "LinkDialog", this.lang));
-		var dropDown = (this.dropDown = new dijit.TooltipDialog({
-			title: messages[this.command + "Title"],
-			execute: dojo.hitch(this, "setValue"),
-			onOpen: function(){
-				_this._onOpenDialog();
-				dijit.TooltipDialog.prototype.onOpen.apply(this, arguments);
-			},
-			onCancel: function(){
-				setTimeout(dojo.hitch(_this, "_onCloseDialog"),0);
-			}
-		}));
-		messages.urlRegExp = this.urlRegExp;
-		messages.id = dijit.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>" +
-			dojo.string.substitute(this.linkDialogTemplate, messages));
-		dropDown.startup();
-		this._urlInput = dijit.byId(this._uniqueId + "_urlInput");
-		this._textInput = dijit.byId(this._uniqueId + "_textInput");
-		this._setButton = dijit.byId(this._uniqueId + "_setButton");
-		this.connect(dijit.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");
-		}
+		this.inherited(arguments);
 
-		// 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 = dojo.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);
-		});
+		// Setup to lazy create TooltipDialog first time the button is clicked
+		this.button.loadDropDown = lang.hitch(this, "_loadDropDown");
 
 		this._connectTagEvents();
-		this.inherited(arguments);
+	},
+	_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");
+			}
+
+			// 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.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'));
+					}
+				}
+			});
+
+			callback();
+		}));
 	},
 
 	_checkAndFixInput: function(){
@@ -135,7 +189,7 @@ dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
 			var appendHttp = false;
 			var appendMailto = false;
 			if(url && url.length > 1){
-				url = dojo.trim(url);
+				url = lang.trim(url);
 				if(url.indexOf("mailto:") !== 0){
 					if(url.indexOf("/") > 0){
 						if(url.indexOf("://") === -1){
@@ -173,7 +227,7 @@ dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
 	_connectTagEvents: function(){
 		// summary:
 		//		Over-ridable function that connects tag specific events.
-		this.editor.onLoadDeferred.addCallback(dojo.hitch(this, function(){
+		this.editor.onLoadDeferred.addCallback(lang.hitch(this, function(){
 			this.connect(this.editor.editNode, "ondblclick", this._onDblClick);
 		}));
 	},
@@ -216,8 +270,8 @@ dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
 		//		private
 		//TODO: prevent closing popup if the text is empty
 		this._onCloseDialog();
-		if(dojo.isIE < 9){ //see #4151
-			var sel = dijit.range.getSelection(this.editor.window);
+		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){
@@ -227,21 +281,21 @@ dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
 				a = a.parentNode;
 			}
 			if(a && (a.nodeName && a.nodeName.toLowerCase() !== this.tag)){
-				// Stll nothing, one last thing to try on IE, as it might be 'img'
+				// Still 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, [this.tag]);
+				a = win.withGlobal(this.editor.window,
+					"getSelectedElement", selectionapi, [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 targetted paste-over element, so we unlink the
+				// 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 childent, then unlink.  The following insert will
+					// Select all the link children, then unlink.  The following insert will
 					// then replace the selected text.
-					dojo.withGlobal(this.editor.window,
-						"selectElementChildren", dijit._editor.selection, [a]);
+					win.withGlobal(this.editor.window,
+						"selectElementChildren", selectionapi, [a]);
 					this.editor.execCommand("unlink");
 				}
 			}
@@ -249,7 +303,7 @@ dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
 		// make sure values are properly escaped, etc.
 		args = this._checkValues(args);
 		this.editor.execCommand('inserthtml',
-			dojo.string.substitute(this.htmlTemplate, args));
+			string.substitute(this.htmlTemplate, args));
 	},
 
 	_onCloseDialog: function(){
@@ -270,9 +324,9 @@ dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
 			url = a.getAttribute('_djrealurl') || a.getAttribute('href');
 			target = a.getAttribute('target') || "_self";
 			text = a.textContent || a.innerText;
-			dojo.withGlobal(this.editor.window, "selectElement", dijit._editor.selection, [a, true]);
+			win.withGlobal(this.editor.window, "selectElement", selectionapi, [a, true]);
 		}else{
-			text = dojo.withGlobal(this.editor.window, dijit._editor.selection.getSelectedText);
+			text = win.withGlobal(this.editor.window, selectionapi.getSelectedText);
 		}
 		return {urlInput: url || '', textInput: text || '', targetSelect: target || ''}; //Object;
 	},
@@ -282,10 +336,10 @@ dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
 		//		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(dojo.isIE < 9){
+		if(has("ie") < 9){
 			// IE is difficult to select the element in, using the range unified
 			// API seems to work reasonably well.
-			var sel = dijit.range.getSelection(this.editor.window);
+			var sel = rangeapi.getSelection(this.editor.window);
 			var range = sel.getRangeAt(0);
 			a = range.endContainer;
 			if(a.nodeType === 3){
@@ -295,14 +349,14 @@ dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
 				a = a.parentNode;
 			}
 			if(a && (a.nodeName && a.nodeName.toLowerCase() !== this.tag)){
-				// Stll nothing, one last thing to try on IE, as it might be 'img'
+				// Still 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, [this.tag]);
+				a = win.withGlobal(this.editor.window,
+					"getSelectedElement", selectionapi, [this.tag]);
 			}
 		}else{
-			a = dojo.withGlobal(this.editor.window,
-				"getAncestorElement", dijit._editor.selection, [this.tag]);
+			a = win.withGlobal(this.editor.window,
+				"getAncestorElement", selectionapi, [this.tag]);
 		}
 		this.dropDown.reset();
 		this._setButton.set("disabled", true);
@@ -321,24 +375,43 @@ dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
 		if(e && e.target){
 			var t = e.target;
 			var tg = t.tagName? t.tagName.toLowerCase() : "";
-			if(tg === this.tag && dojo.attr(t,"href")){
-				dojo.withGlobal(this.editor.window,
+			if(tg === this.tag && domAttr.get(t,"href")){
+				var editor = this.editor;
+
+				win.withGlobal(editor.window,
 					 "selectElement",
-					 dijit._editor.selection, [t]);
-				this.editor.onDisplayChanged();
-				
-				setTimeout(dojo.hitch(this, function(){
+					 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;
+				}
+				editor.onNormalizedDisplayChanged();
+
+				var button = this.button;
+				setTimeout(function(){
 					// Focus shift outside the event handler.
 					// IE doesn't like focus changes in event handles.
-					this.button.set("disabled", false);
-					this.button.openDropDown();
-				}), 10);
+					button.set("disabled", false);
+					button.loadAndOpenDropDown().then(function(){
+						if(button.dropDown.focus){
+							button.dropDown.focus();
+						}
+					});
+				}, 10);
 			}
 		}
 	}
 });
 
-dojo.declare("dijit._editor.plugins.ImgLinkDialog", [dijit._editor.plugins.LinkDialog], {
+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.
@@ -354,17 +427,17 @@ dojo.declare("dijit._editor.plugins.ImgLinkDialog", [dijit._editor.plugins.LinkD
 		"<label for='${id}_urlInput'>${url}</label>",
 		"</td><td>",
 		"<input dojoType='dijit.form.ValidationTextBox' regExp='${urlRegExp}' " +
-		"required='true' id='${id}_urlInput' name='urlInput' intermediateChanges='true'/>",
+		"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 dojoType='dijit.form.ValidationTextBox' required='false' id='${id}_textInput' " +
-		"name='textInput' intermediateChanges='true'/>",
+		"<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 dojoType='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>",
-		"<button dojoType='dijit.form.Button' type='button' id='${id}_cancelButton'>${buttonCancel}</button>",
+		"<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(""),
 
@@ -387,10 +460,10 @@ dojo.declare("dijit._editor.plugins.ImgLinkDialog", [dijit._editor.plugins.LinkD
 		if(img && img.tagName.toLowerCase() === this.tag){
 			url = img.getAttribute('_djrealurl') || img.getAttribute('src');
 			text = img.getAttribute('alt');
-			dojo.withGlobal(this.editor.window,
-				"selectElement", dijit._editor.selection, [img, true]);
+			win.withGlobal(this.editor.window,
+				"selectElement", selectionapi, [img, true]);
 		}else{
-			text = dojo.withGlobal(this.editor.window, dijit._editor.selection.getSelectedText);
+			text = win.withGlobal(this.editor.window, selectionapi.getSelectedText);
 		}
 		return {urlInput: url || '', textInput: text || ''}; //Object;
 	},
@@ -407,7 +480,7 @@ dojo.declare("dijit._editor.plugins.ImgLinkDialog", [dijit._editor.plugins.LinkD
 		// summary:
 		//		Over-ridable function that connects tag specific events.
 		this.inherited(arguments);
-		this.editor.onLoadDeferred.addCallback(dojo.hitch(this, function(){
+		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);
@@ -427,9 +500,9 @@ dojo.declare("dijit._editor.plugins.ImgLinkDialog", [dijit._editor.plugins.LinkD
 			var t = e.target;
 			var tg = t.tagName? t.tagName.toLowerCase() : "";
 			if(tg === this.tag){
-				dojo.withGlobal(this.editor.window,
+				win.withGlobal(this.editor.window,
 					"selectElement",
-					dijit._editor.selection, [t]);
+					selectionapi, [t]);
 			}
 		}
 	},
@@ -462,36 +535,52 @@ dojo.declare("dijit._editor.plugins.ImgLinkDialog", [dijit._editor.plugins.LinkD
 		//		protected.
 		if(e && e.target){
 			var t = e.target;
-			var tg = t.tagName? t.tagName.toLowerCase() : "";
-			if(tg === this.tag && dojo.attr(t,"src")){
-				dojo.withGlobal(this.editor.window,
+			var tg = t.tagName ? t.tagName.toLowerCase() : "";
+			if(tg === this.tag && domAttr.get(t,"src")){
+				var editor = this.editor;
+
+				win.withGlobal(editor.window,
 					 "selectElement",
-					 dijit._editor.selection, [t]);
-				this.editor.onDisplayChanged();
-				setTimeout(dojo.hitch(this, function(){
+					 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;
+				}
+				editor.onNormalizedDisplayChanged();
+
+				var button = this.button;
+				setTimeout(function(){
 					// Focus shift outside the event handler.
 					// IE doesn't like focus changes in event handles.
-					this.button.set("disabled", false);
-					this.button.openDropDown();
-				}), 10);
+					button.set("disabled", false);
+					button.loadAndOpenDropDown().then(function(){
+						if(button.dropDown.focus){
+							button.dropDown.focus();
+						}
+					});
+				}, 10);
 			}
 		}
 	}
 });
 
-// Register this plugin.
-dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
-	if(o.plugin){ return; }
-	switch(o.args.name){
-		case "createLink":
-			o.plugin = new dijit._editor.plugins.LinkDialog({command: o.args.name});
-			break;
-		case "insertImage":
-			o.plugin = new dijit._editor.plugins.ImgLinkDialog({command: o.args.name});
-			break;
-	}
-});
+// Register these plugins
+_Plugin.registry["createLink"] = function(){
+	return new LinkDialog({command: "createLink"});
+};
+_Plugin.registry["insertImage"] = function(){
+	return new ImgLinkDialog({command: "insertImage"});
+};
 
 
-return dijit._editor.plugins.LinkDialog;
+// Export both LinkDialog and ImgLinkDialog
+LinkDialog.ImgLinkDialog = ImgLinkDialog;
+return LinkDialog;
 });
diff --git a/dijit/_editor/plugins/NewPage.js b/dijit/_editor/plugins/NewPage.js
index c4486f4..3cd519b 100644
--- a/dijit/_editor/plugins/NewPage.js
+++ b/dijit/_editor/plugins/NewPage.js
@@ -1,8 +1,26 @@
-define("dijit/_editor/plugins/NewPage", ["dojo", "dijit", "dijit/_editor/_Plugin", "dijit/form/Button", "dojo/i18n", "i18n!dijit/_editor/nls/commands"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/i18n", // i18n.getLocalization
+	"dojo/_base/lang", // lang.hitch
+	"../_Plugin",
+	"../../form/Button",
+	"dojo/i18n!../nls/commands"
+], function(declare, i18n, lang, _Plugin, Button){
 
-dojo.declare("dijit._editor.plugins.NewPage",dijit._editor._Plugin,{
+/*=====
+	var _Plugin = dijit._editor._Plugin;
+=====*/
+
+// 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' calability.  In other
+	//		This plugin provides a simple 'new page' capability.  In other
 	//		words, set content to some default user defined string.
 
 	// content: [public] String
@@ -13,16 +31,16 @@ dojo.declare("dijit._editor.plugins.NewPage",dijit._editor._Plugin,{
 	_initButton: function(){
 		// summary:
 		//		Over-ride for creation of the Print button.
-		var strings = dojo.i18n.getLocalization("dijit._editor", "commands"),
+		var strings = i18n.getLocalization("dijit._editor", "commands"),
 			editor = this.editor;
-		this.button = new dijit.form.Button({
+		this.button = new Button({
 			label: strings["newPage"],
 			dir: editor.dir,
 			lang: editor.lang,
 			showLabel: false,
 			iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "NewPage",
 			tabIndex: "-1",
-			onClick: dojo.hitch(this, "_newPage")
+			onClick: lang.hitch(this, "_newPage")
 		});
 	},
 
@@ -54,16 +72,12 @@ dojo.declare("dijit._editor.plugins.NewPage",dijit._editor._Plugin,{
 });
 
 // Register this plugin.
-dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
-	if(o.plugin){ return; }
-	var name = o.args.name.toLowerCase();
-	if(name === "newpage"){
-		o.plugin = new dijit._editor.plugins.NewPage({
-			content: ("content" in o.args)?o.args.content:"<br>"
-		});
-	}
-});
-
+// 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 dijit._editor.plugins.NewPage;
+return NewPage;
 });
diff --git a/dijit/_editor/plugins/Print.js b/dijit/_editor/plugins/Print.js
index 4ac105e..df9aee8 100755
--- a/dijit/_editor/plugins/Print.js
+++ b/dijit/_editor/plugins/Print.js
@@ -1,23 +1,43 @@
-define("dijit/_editor/plugins/Print", ["dojo", "dijit", "dijit/_editor/_Plugin", "dijit/form/Button", "dojo/i18n", "i18n!dijit/_editor/nls/commands"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/i18n", // i18n.getLocalization
+	"dojo/_base/lang", // lang.hitch
+	"dojo/_base/sniff", // has("chrome") has("opera")
+	"../../focus",		// focus.focus()
+	"../_Plugin",
+	"../../form/Button",
+	"dojo/i18n!../nls/commands"
+], function(declare, i18n, lang, has, focus, _Plugin, Button){
 
-dojo.declare("dijit._editor.plugins.Print",dijit._editor._Plugin,{
+/*=====
+	var _Plugin = dijit._editor._Plugin;
+=====*/
+
+// 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 cabability to the editor.  When
+	//		This plugin provides Print capability to the editor.  When
 	//		clicked, the document in the editor frame will be printed.
 
 	_initButton: function(){
 		// summary:
 		//		Over-ride for creation of the Print button.
-		var strings = dojo.i18n.getLocalization("dijit._editor", "commands"),
+		var strings = i18n.getLocalization("dijit._editor", "commands"),
 			editor = this.editor;
-		this.button = new dijit.form.Button({
+		this.button = new Button({
 			label: strings["print"],
 			dir: editor.dir,
 			lang: editor.lang,
 			showLabel: false,
 			iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "Print",
 			tabIndex: "-1",
-			onClick: dojo.hitch(this, "_print")
+			onClick: lang.hitch(this, "_print")
 		});
 	},
 
@@ -32,7 +52,7 @@ dojo.declare("dijit._editor.plugins.Print",dijit._editor._Plugin,{
 		// Set up a check that we have a print function
 		// and disable button if we do not.
 		this.editor.onLoadDeferred.addCallback(
-			dojo.hitch(this, function(){
+			lang.hitch(this, function(){
 				if(!this.editor.iframe.contentWindow["print"]){
 					this.button.set("disabled", true);
 				}
@@ -60,8 +80,8 @@ dojo.declare("dijit._editor.plugins.Print",dijit._editor._Plugin,{
 			// IE requires the frame to be focused for
 			// print to work, but since this is okay for all
 			// no special casing.
-			if(!dojo.isOpera && !dojo.isChrome){
-				dijit.focus(edFrame);
+			if(!has("opera") && !has("chrome")){
+				focus.focus(edFrame);
 				edFrame.contentWindow.print();
 			}else{
 				// Neither Opera nor Chrome 3 et you print single frames.
@@ -79,7 +99,7 @@ dojo.declare("dijit._editor.plugins.Print",dijit._editor._Plugin,{
 				win.document.open();
 				win.document.write(content);
 				win.document.close();
-				var styles = [];
+
 				var styleNodes = edDoc.getElementsByTagName("style");
 				if(styleNodes){
 					// Clone over any editor view styles, since we can't print the iframe
@@ -100,14 +120,10 @@ dojo.declare("dijit._editor.plugins.Print",dijit._editor._Plugin,{
 });
 
 // Register this plugin.
-dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
-	if(o.plugin){ return; }
-	var name = o.args.name.toLowerCase();
-	if(name === "print"){
-		o.plugin = new dijit._editor.plugins.Print({command: "print"});
-	}
-});
+_Plugin.registry["print"] = function(){
+	return new Print({command: "print"});
+};
 
 
-return dijit._editor.plugins.Print;
+return Print;
 });
diff --git a/dijit/_editor/plugins/TabIndent.js b/dijit/_editor/plugins/TabIndent.js
index ef49134..66720b9 100644
--- a/dijit/_editor/plugins/TabIndent.js
+++ b/dijit/_editor/plugins/TabIndent.js
@@ -1,11 +1,26 @@
-define("dijit/_editor/plugins/TabIndent", ["dojo", "dijit", "dijit/_editor/_Plugin", "dijit/form/ToggleButton"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/_base/kernel", // kernel.experimental
+	"../_Plugin",
+	"../../form/ToggleButton"
+], function(declare, kernel, _Plugin, ToggleButton){
 
-dojo.experimental("dijit._editor.plugins.TabIndent");
+/*=====
+	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
 
-dojo.declare("dijit._editor.plugins.TabIndent",
-	dijit._editor._Plugin,
-	{
+
+	kernel.experimental("dijit._editor.plugins.TabIndent");
+
+
+	var TabIndent = declare("dijit._editor.plugins.TabIndent", _Plugin, {
 		// 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
@@ -15,7 +30,7 @@ dojo.declare("dijit._editor.plugins.TabIndent",
 		useDefaultCommand: false,
 
 		// Override _Plugin.buttonClass to use a ToggleButton for this plugin rather than a vanilla Button
-		buttonClass: dijit.form.ToggleButton,
+		buttonClass: ToggleButton,
 
 		command: "tabIndent",
 
@@ -42,18 +57,13 @@ dojo.declare("dijit._editor.plugins.TabIndent",
 			}
 			this.button.set('checked', this.editor.isTabIndent, false);
 		}
-	}
-);
-
-// Register this plugin.
-dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
-	if(o.plugin){ return; }
-	switch(o.args.name){
-	case "tabIndent":
-		o.plugin = new dijit._editor.plugins.TabIndent({command: o.args.name});
-	}
-});
+	});
+
+	// Register this plugin.
+	_Plugin.registry["tabIndent"] = function(){
+		return new TabIndent({command: "tabIndent"});
+	};
 
 
-return dijit._editor.plugins.TabIndent;
+	return TabIndent;
 });
diff --git a/dijit/_editor/plugins/TextColor.js b/dijit/_editor/plugins/TextColor.js
index 8ba6ef7..7c582e5 100644
--- a/dijit/_editor/plugins/TextColor.js
+++ b/dijit/_editor/plugins/TextColor.js
@@ -1,6 +1,23 @@
-define("dijit/_editor/plugins/TextColor", ["dojo", "dijit", "dijit/_editor/_Plugin", "dijit/ColorPalette"], function(dojo, dijit) {
+define([
+	"require",
+	"dojo/colors", // colors.fromRgb
+	"dojo/_base/declare", // declare
+	"dojo/_base/lang",
+	"../_Plugin",
+	"../../form/DropDownButton"
+], function(require, colors, declare, lang, _Plugin, DropDownButton){
 
-dojo.declare("dijit._editor.plugins.TextColor", dijit._editor._Plugin, {
+/*=====
+	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
 	//
@@ -8,20 +25,30 @@ dojo.declare("dijit._editor.plugins.TextColor", dijit._editor._Plugin, {
 	//		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: dijit.form.DropDownButton,
-	
+	buttonClass: DropDownButton,
+
 	// useDefaultCommand: Boolean
 	//		False as we do not use the default editor command/click behavior.
 	useDefaultCommand: false,
 
-	constructor: function(){
-		this.dropDown = new dijit.ColorPalette();
-		this.connect(this.dropDown, "onChange", function(color){
-			this.editor.execCommand(this.command, color);
-			
-		});
+	_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(){
@@ -30,18 +57,18 @@ dojo.declare("dijit._editor.plugins.TextColor", dijit._editor._Plugin, {
 		//		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(this.button){
 			var disabled = this.get("disabled");
 			this.button.set("disabled", disabled);
 			if(disabled){ return; }
-			
+
 			var value;
 			try{
 				value = _e.queryCommandValue(_c)|| "";
@@ -50,7 +77,7 @@ dojo.declare("dijit._editor.plugins.TextColor", dijit._editor._Plugin, {
 				value = "";
 			}
 		}
-		
+
 		if(value == ""){
 			value = "#000000";
 		}
@@ -61,35 +88,32 @@ dojo.declare("dijit._editor.plugins.TextColor", dijit._editor._Plugin, {
 		if(typeof value == "string"){
 			//if RGB value, convert to hex value
 			if(value.indexOf("rgb")> -1){
-				value = dojo.colorFromRgb(value).toHex();
+				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;
-			
+
 		}
-		
-		if(value !== this.dropDown.get('value')){
-			this.dropDown.set('value', value, false);
+
+		this.value = value;
+
+		var dropDown = this.button.dropDown;
+		if(dropDown && value !== dropDown.get('value')){
+			dropDown.set('value', value, false);
 		}
 	}
 });
 
 // Register this plugin.
-dojo.subscribe(dijit._scopeName + ".Editor.getPlugin", null, function(o){
-	if(o.plugin){
-		return;
-	}
-	switch(o.args.name){
-		case "foreColor":
-		case "hiliteColor":
-			o.plugin = new dijit._editor.plugins.TextColor({
-				command: o.args.name
-			});
-	}
-});
+_Plugin.registry["foreColor"] = function(){
+	return new TextColor({command: "foreColor"});
+};
+_Plugin.registry["hiliteColor"] = function(){
+	return new TextColor({command: "hiliteColor"});
+};
 
 
-return dijit._editor.plugins.TextColor;
+return TextColor;
 });
diff --git a/dijit/_editor/plugins/ToggleDir.js b/dijit/_editor/plugins/ToggleDir.js
index ba8aa67..767ee00 100644
--- a/dijit/_editor/plugins/ToggleDir.js
+++ b/dijit/_editor/plugins/ToggleDir.js
@@ -1,13 +1,26 @@
-define("dijit/_editor/plugins/ToggleDir", ["dojo", "dijit", "dijit/_editor/_Plugin", "dijit/form/ToggleButton"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/dom-style", // domStyle.getComputedStyle
+	"dojo/_base/kernel", // kernel.experimental
+	"dojo/_base/lang", // lang.hitch
+	"../_Plugin",
+	"../../form/ToggleButton"
+], function(declare, domStyle, kernel, lang, _Plugin, ToggleButton){
 
-dojo.experimental("dijit._editor.plugins.ToggleDir");
+/*=====
+	var _Plugin = dijit._editor._Plugin;
+=====*/
 
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.form.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.
 
-dojo.declare("dijit._editor.plugins.ToggleDir",
-	dijit._editor._Plugin,
-	{
+
+	kernel.experimental("dijit._editor.plugins.ToggleDir");
+
+	var ToggleDir = declare("dijit._editor.plugins.ToggleDir", _Plugin, {
 		// summary:
 		//		This plugin is used to toggle direction of the edited document,
 		//		independent of what direction the whole page is.
@@ -19,18 +32,18 @@ dojo.declare("dijit._editor.plugins.ToggleDir",
 		command: "toggleDir",
 
 		// Override _Plugin.buttonClass to use a ToggleButton for this plugin rather than a vanilla Button
-		buttonClass: dijit.form.ToggleButton,
+		buttonClass: ToggleButton,
 
 		_initButton: function(){
 			// Override _Plugin._initButton() to setup handler for button click events.
 			this.inherited(arguments);
-			this.editor.onLoadDeferred.addCallback(dojo.hitch(this, function(){
+			this.editor.onLoadDeferred.addCallback(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
 				//view.  But, the nice thing is this works for all supported browsers.
 				editDoc = editDoc.getElementsByTagName("body")[0];
-				var isLtr = dojo.getComputedStyle(editDoc).direction == "ltr";
+				var isLtr = domStyle.getComputedStyle(editDoc).direction == "ltr";
 				this.button.set("checked", !isLtr);
 				this.connect(this.button, "onChange", "_setRtl");
 			}));
@@ -53,18 +66,12 @@ dojo.declare("dijit._editor.plugins.ToggleDir",
 			editDoc = editDoc.getElementsByTagName("body")[0];
 			editDoc.dir/*html node*/ = dir;
 		}
-	}
-);
-
-// Register this plugin.
-dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
-	if(o.plugin){ return; }
-	switch(o.args.name){
-	case "toggleDir":
-		o.plugin = new dijit._editor.plugins.ToggleDir({command: o.args.name});
-	}
-});
+	});
 
+	// Register this plugin.
+	_Plugin.registry["toggleDir"] = function(){
+		return new ToggleDir({command: "toggleDir"});
+	};
 
-return dijit._editor.plugins.ToggleDir;
+	return ToggleDir;
 });
diff --git a/dijit/_editor/plugins/ViewSource.js b/dijit/_editor/plugins/ViewSource.js
index 6b0c6c4..3525f4a 100755
--- a/dijit/_editor/plugins/ViewSource.js
+++ b/dijit/_editor/plugins/ViewSource.js
@@ -1,6 +1,38 @@
-define("dijit/_editor/plugins/ViewSource", ["dojo", "dijit", "dojo/window", "dojo/i18n", "dijit/_editor/_Plugin", "dijit/form/Button", "i18n!dijit/_editor/nls/commands"], function(dojo, dijit) {
-
-dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
+define([
+	"dojo/_base/array", // array.forEach
+	"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/_base/lang", // lang.hitch
+	"dojo/on", // on()
+	"dojo/_base/sniff", // has("ie") has("webkit")
+	"dojo/_base/window", // win.body win.global
+	"dojo/window", // winUtils.getBox
+	"../../focus",	// focus.focus()
+	"../_Plugin",
+	"../../form/ToggleButton",
+	"../..",	// 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.
@@ -41,7 +73,7 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 		// 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(dojo.isWebKit){this._vsFocused = true;}
+		if(has("webkit")){this._vsFocused = true;}
 		this.button.set("checked", !this.button.get("checked"));
 
 	},
@@ -49,29 +81,29 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 	_initButton: function(){
 		// summary:
 		//		Over-ride for creation of the resize button.
-		var strings = dojo.i18n.getLocalization("dijit._editor", "commands"),
+		var strings = i18n.getLocalization("dijit._editor", "commands"),
 			editor = this.editor;
-		this.button = new dijit.form.ToggleButton({
+		this.button = new ToggleButton({
 			label: strings["viewSource"],
 			dir: editor.dir,
 			lang: editor.lang,
 			showLabel: false,
 			iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "ViewSource",
 			tabIndex: "-1",
-			onChange: dojo.hitch(this, "_showSource")
+			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(dojo.isIE == 7){
-			this._ieFixNode = dojo.create("div", {
+		if(has("ie") == 7){
+			this._ieFixNode = domConstruct.create("div", {
 				style: {
 					opacity: "0",
 					zIndex: "-1000",
 					position: "absolute",
 					top: "-1000px"
 				}
-			}, dojo.body());
+			}, win.body());
 		}
 		// Make sure readonly mode doesn't make the wrong cursor appear over the button.
 		this.button.set("readOnly", false);
@@ -86,16 +118,16 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 		this.editor = editor;
 		this._initButton();
 
-		this.editor.addKeyHandler(dojo.keys.F12, true, true, dojo.hitch(this, function(e){
+		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();
-			dojo.stopEvent(e);
+			event.stop(e);
 
 			// Call the focus shift outside of the handler.
-			setTimeout(dojo.hitch(this, function(){
+			setTimeout(lang.hitch(this, function(){
 				// We over-ride focus, so we just need to call.
 				this.editor.focus();
 			}), 100);
@@ -124,21 +156,15 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 				// plugins to check their state.
 				ed._sourceQueryCommandEnabled = ed.queryCommandEnabled;
 				ed.queryCommandEnabled = function(cmd){
-					var lcmd = cmd.toLowerCase();
-					if(lcmd === "viewsource"){
-						return true;
-					}else{
-						return false;
-					}
+					return cmd.toLowerCase() === "viewsource";
 				};
 				this.editor.onDisplayChanged();
 				html = ed.get("value");
 				html = this._filter(html);
 				ed.set("value", html);
-				this._pluginList = [];
-				dojo.forEach(edPlugins, function(p){
+				array.forEach(edPlugins, function(p){
 					// Turn off any plugins not controlled by queryCommandenabled.
-					if(!(p instanceof dijit._editor.plugins.ViewSource)){
+					if(!(p instanceof ViewSource)){
 						p.set("disabled", true)
 					}
 				});
@@ -152,15 +178,13 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 				}
 
 				this.sourceArea.value = html;
-				var is = dojo._getMarginSize(ed.iframe.parentNode);
 
-				dojo.marginBox(this.sourceArea, {
-					w: is.w,
-					h: is.h
-				});
-
-				dojo.style(ed.iframe, "display", "none");
-				dojo.style(this.sourceArea, {
+				// 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"
 				});
 
@@ -168,7 +192,7 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 					// function to handle resize events.
 					// Will check current VP and only resize if
 					// different.
-					var vp = dojo.window.getBox();
+					var vp = winUtils.getBox();
 
 					if("_prevW" in this && "_prevH" in this){
 						// No actual size change, ignore.
@@ -188,21 +212,21 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 					}
 					// Timeout it to help avoid spamming resize on IE.
 					// Works for all browsers.
-					this._resizer = setTimeout(dojo.hitch(this, function(){
+					this._resizer = setTimeout(lang.hitch(this, function(){
 						delete this._resizer;
 						this._resize();
 					}), 10);
 				};
-				this._resizeHandle = dojo.connect(window, "onresize", this, resizer);
+				this._resizeHandle = on(window, "resize", lang.hitch(this, resizer));
 
 				//Call this on a delay once to deal with IE glitchiness on initial size.
-				setTimeout(dojo.hitch(this, this._resize), 100);
+				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 = dojo.hitch(this, function() {
+				this.editor.getValue = lang.hitch(this, function(){
 					var txt = this.sourceArea.value;
 					txt = this._filter(txt);
 					return txt;
@@ -214,7 +238,7 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 				if(!ed._sourceQueryCommandEnabled){
 					return;
 				}
-				dojo.disconnect(this._resizeHandle);
+				this._resizeHandle.remove();
 				delete this._resizeHandle;
 
 				if(this.editor.__oldGetValue){
@@ -232,24 +256,24 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 					ed.endEditing();
 				}
 
-				dojo.forEach(edPlugins, function(p){
+				array.forEach(edPlugins, function(p){
 					// Turn back on any plugins we turned off.
 					p.set("disabled", false);
 				});
 
-				dojo.style(this.sourceArea, "display", "none");
-				dojo.style(ed.iframe, "display", "block");
+				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(dojo.hitch(this, function(){
+			setTimeout(lang.hitch(this, function(){
 				// Make resize calls.
 				var parent = ed.domNode.parentNode;
 				if(parent){
-					var container = dijit.getEnclosingWidget(parent);
+					var container = registry.getEnclosingWidget(parent);
 					if(container && container.resize){
 						container.resize();
 					}
@@ -275,30 +299,29 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 		var ed = this.editor;
 		var tbH = ed.getHeaderHeight();
 		var fH = ed.getFooterHeight();
-		var eb = dojo.position(ed.domNode);
+		var eb = domGeometry.position(ed.domNode);
 
 		// Styles are now applied to the internal source container, so we have
 		// to subtract them off.
-		var containerPadding = dojo._getPadBorderExtents(ed.iframe.parentNode);
-		var containerMargin = dojo._getMarginExtents(ed.iframe.parentNode);
+		var containerPadding = domGeometry.getPadBorderExtents(ed.iframe.parentNode);
+		var containerMargin = domGeometry.getMarginExtents(ed.iframe.parentNode);
 
-		var extents = dojo._getPadBorderExtents(ed.domNode);
-		var mExtents = dojo._getMarginExtents(ed.domNode);
+		var extents = domGeometry.getPadBorderExtents(ed.domNode);
 		var edb = {
-			w: eb.w - (extents.w + mExtents.w),
-			h: eb.h - (tbH + extents.h + mExtents.h + fH)
+			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 = dojo.window.getBox();
+			var vp = winUtils.getBox();
 			edb.w = (vp.w - extents.w);
 			edb.h = (vp.h - (tbH + extents.h + fH));
 		}
 
-		if(dojo.isIE){
+		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.
@@ -313,13 +336,13 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 			edb.h = Math.floor((edb.h + 0.9) / _ie7zoom);
 		}
 
-		dojo.marginBox(this.sourceArea, {
+		domGeometry.setMarginBox(this.sourceArea, {
 			w: edb.w - (containerPadding.w + containerMargin.w),
 			h: edb.h - (containerPadding.h + containerMargin.h)
 		});
 
 		// Scale the parent container too in this case.
-		dojo.marginBox(ed.iframe.parentNode, {
+		domGeometry.setMarginBox(ed.iframe.parentNode, {
 			h: edb.h
 		});
 	},
@@ -331,24 +354,24 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 		//		private
 		var ed = this.editor;
 		var edPlugins = ed._plugins;
-		this.sourceArea = dojo.create("textarea");
+		this.sourceArea = domConstruct.create("textarea");
 		if(this.readOnly){
-			dojo.attr(this.sourceArea, "readOnly", true);
+			domAttr.set(this.sourceArea, "readOnly", true);
 			this._readOnly = true;
 		}
-		dojo.style(this.sourceArea, {
+		domStyle.set(this.sourceArea, {
 			padding: "0px",
 			margin: "0px",
 			borderWidth: "0px",
 			borderStyle: "none"
 		});
-		dojo.place(this.sourceArea, ed.iframe, "before");
+		domConstruct.place(this.sourceArea, ed.iframe, "before");
 
-		if(dojo.isIE && ed.iframe.parentNode.lastChild !== ed.iframe){
+		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.
-			dojo.style(ed.iframe.parentNode.lastChild,{
+			domStyle.set(ed.iframe.parentNode.lastChild,{
 				width: "0px",
 				height: "0px",
 				padding: "0px",
@@ -372,7 +395,7 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 						// 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.
-						dijit.focus(ed.editNode);
+						focus.focus(ed.editNode);
 					}else{
 						ed._viewsource_oldFocus();
 					}
@@ -405,12 +428,12 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 
 		// 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", dojo.hitch(this, function(e){
-			if(this._sourceShown && e.keyCode == dojo.keys.F12 && e.ctrlKey && e.shiftKey){
+		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(dojo.hitch(this, function(){ed.focus();}), 100);
-				dojo.stopEvent(e);
+				setTimeout(lang.hitch(this, function(){ed.focus();}), 100);
+				event.stop(e);
 			}
 		}));
 	},
@@ -483,11 +506,11 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 		// summary:
 		//		Internal function to set the caret in the sourceArea
 		//		to 0x0
-		var win = dojo.global;
+		var global = win.global;
 		var elem = this.sourceArea;
-		dijit.focus(elem);
+		focus.focus(elem);
 		if(this._sourceShown && !this.readOnly){
-			if(dojo.isIE){
+			if(has("ie")){
 				if(this.sourceArea.createTextRange){
 					var range = elem.createTextRange();
 					range.collapse(true);
@@ -496,7 +519,7 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 					range.moveEnd("character", 0);
 					range.select();
 				}
-			}else if(win.getSelection){
+			}else if(global.getSelection){
 				if(elem.setSelectionRange){
 					elem.setSelectionRange(0,0);
 				}
@@ -509,14 +532,14 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 		//		Over-ride to remove the node used to correct for IE's
 		//		zoom bug.
 		if(this._ieFixNode){
-			dojo.body().removeChild(this._ieFixNode);
+			win.body().removeChild(this._ieFixNode);
 		}
 		if(this._resizer){
 			clearTimeout(this._resizer);
 			delete this._resizer;
 		}
 		if(this._resizeHandle){
-			dojo.disconnect(this._resizeHandle);
+			this._resizeHandle.remove();
 			delete this._resizeHandle;
 		}
 		this.inherited(arguments);
@@ -524,19 +547,18 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 });
 
 // Register this plugin.
-dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
-	if(o.plugin){ return; }
-	var name = o.args.name.toLowerCase();
-	if(name ===  "viewsource"){
-		o.plugin = new dijit._editor.plugins.ViewSource({
-			readOnly: ("readOnly" in o.args)?o.args.readOnly:false,
-			stripComments: ("stripComments" in o.args)?o.args.stripComments:true,
-			stripScripts: ("stripScripts" in o.args)?o.args.stripScripts:true,
-			stripIFrames: ("stripIFrames" in o.args)?o.args.stripIFrames:true
-		});
-	}
-});
+// 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 dijit._editor.plugins.ViewSource;
+return ViewSource;
 });
diff --git a/dijit/_editor/range.js b/dijit/_editor/range.js
index abc35cd..58a5d0a 100644
--- a/dijit/_editor/range.js
+++ b/dijit/_editor/range.js
@@ -1,18 +1,29 @@
-define("dijit/_editor/range", ["dojo", "dijit"], function(dojo, dijit) {
+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){
+dijit.range.getIndex = function(/*DomNode*/node, /*DomNode*/parent){
 //	dojo.profile.start("dijit.range.getIndex");
-	var ret=[], retR=[];
-	var stop = parent;
+	var ret = [], retR = [];
 	var onode = node;
 
 	var pnode, n;
-	while(node != stop){
+	while(node != parent){
 		var i = 0;
 		pnode = node.parentNode;
-		while((n=pnode.childNodes[i++])){
+		while((n = pnode.childNodes[i++])){
 			if(n === node){
 				--i;
 				break;
@@ -22,7 +33,7 @@ dijit.range.getIndex=function(/*DomNode*/node, /*DomNode*/parent){
 			//dojo.debug("Error finding index of a node in dijit.range.getIndex");
 		//}
 		ret.unshift(i);
-		retR.unshift(i-pnode.childNodes.length);
+		retR.unshift(i - pnode.childNodes.length);
 		node = pnode;
 	}
 
@@ -32,43 +43,43 @@ dijit.range.getIndex=function(/*DomNode*/node, /*DomNode*/parent){
 	if(ret.length > 0 && onode.nodeType == 3){
 		n = onode.previousSibling;
 		while(n && n.nodeType == 3){
-			ret[ret.length-1]--;
+			ret[ret.length - 1]--;
 			n = n.previousSibling;
 		}
 		n = onode.nextSibling;
 		while(n && n.nodeType == 3){
-			retR[retR.length-1]++;
+			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(!dojo.isArray(index) || index.length == 0){
+	if(!lang.isArray(index) || index.length == 0){
 		return parent;
 	}
 	var node = parent;
 //	if(!node)debugger
-	dojo.every(index, function(i){
+	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 dojo.every
+			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;
+dijit.range.getCommonAncestor = function(n1, n2, root){
+	root = root || n1.ownerDocument.body;
 	var getAncestors = function(n){
-		var as=[];
+		var as = [];
 		while(n){
 			as.unshift(n);
 			if(n !== root){
@@ -82,9 +93,9 @@ dijit.range.getCommonAncestor = function(n1,n2,root){
 	var n1as = getAncestors(n1);
 	var n2as = getAncestors(n2);
 
-	var m = Math.min(n1as.length,n2as.length);
+	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++){
+	for(var i = 1; i < m; i++){
 		if(n1as[i] === n2as[i]){
 			com = n1as[i]
 		}else{
@@ -92,12 +103,12 @@ dijit.range.getCommonAncestor = function(n1,n2,root){
 		}
 	}
 	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() ;
+		var name = node.nodeName.toUpperCase();
 		if(regex.test(name)){
 			return node;
 		}
@@ -105,15 +116,15 @@ dijit.range.getAncestor = function(/*DomNode*/node, /*RegEx?*/regex, /*DomNode?*
 		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;
+	var block = null, blockContainer;
 	while(node && node !== root){
-		var name = node.nodeName.toUpperCase() ;
+		var name = node.nodeName.toUpperCase();
 		if(!block && regex.test(name)){
 			block = node;
 		}
@@ -124,13 +135,13 @@ dijit.range.getBlockAncestor = function(/*DomNode*/node, /*RegEx?*/regex, /*DomN
 		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))){
+		if(/^[\s\xA0]+$/.test(node.nodeValue.substr(0, offset))){
 			offsetAtBeginning = true;
 		}
 	}
@@ -146,7 +157,7 @@ dijit.range.atBeginningOfContainer = function(/*DomNode*/container, /*DomNode*/n
 		}
 	}
 	return atBeginning;
-}
+};
 
 dijit.range.atEndOfContainer = function(/*DomNode*/container, /*DomNode*/node, /*Int*/offset){
 	var atEnd = false;
@@ -168,30 +179,30 @@ dijit.range.atEndOfContainer = function(/*DomNode*/container, /*DomNode*/node, /
 		}
 	}
 	return atEnd;
-}
+};
 
-dijit.range.adjacentNoneTextNode=function(startnode, next){
+dijit.range.adjacentNoneTextNode = function(startnode, next){
 	var node = startnode;
-	var len = (0-startnode.length) || 0;
-	var prop = next?'nextSibling':'previousSibling';
+	var len = (0 - startnode.length) || 0;
+	var prop = next ? 'nextSibling' : 'previousSibling';
 	while(node){
-		if(node.nodeType!=3){
+		if(node.nodeType != 3){
 			break;
 		}
-		len += node.length
+		len += node.length;
 		node = node[prop];
 	}
 	return [node,len];
-}
+};
 
 dijit.range._w3c = Boolean(window['getSelection']);
-dijit.range.create = function(/*Window?*/win){
+dijit.range.create = function(/*Window?*/window){
 	if(dijit.range._w3c){
-		return (win || dojo.global).document.createRange();
+		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){
@@ -203,10 +214,10 @@ dijit.range.getSelection = function(/*Window*/win, /*Boolean?*/ignoreUpdate){
 		}
 		return s;
 	}
-}
+};
 
 if(!dijit.range._w3c){
-	dijit.range.ie={
+	dijit.range.ie = {
 		cachedSelection: {},
 		selection: function(win){
 			this._ranges = [];
@@ -227,7 +238,7 @@ if(!dijit.range._w3c){
 			};
 			var _initCurrentRange = function(){
 				var r = win.document.selection.createRange();
-				var type=win.document.selection.type.toUpperCase();
+				var type = win.document.selection.type.toUpperCase();
 				if(type == "CONTROL"){
 					//TODO: multiple range selection(?)
 					return new dijit.range.W3CRange(dijit.range.ie.decomposeControlRange(r));
@@ -240,33 +251,36 @@ if(!dijit.range._w3c){
 			};
 			this._getCurrentSelection = function(){
 				this.removeAllRanges();
-				var r=_initCurrentRange();
+				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 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;
-			var endOffset = dijit.range.getIndex(lastnode, endContainer).o+1;
+			var startOffset = dijit.range.getIndex(firstnode, startContainer).o[0];
+			var endOffset = dijit.range.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 cmpstr = 'EndTo' + (end ? 'End' : 'Start');
 			var parentNode = atmrange.parentElement();
 
 			var startnode, startOffset, lastNode;
-			if(parentNode.childNodes.length>0){
-				dojo.every(parentNode.childNodes, function(node,i){
+			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){
+						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?
@@ -278,41 +292,41 @@ if(!dijit.range._w3c){
 								return false;
 							}
 						}else{
-							if(i == parentNode.childNodes.length-1){
+							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
+						if(i == parentNode.childNodes.length - 1){//at the end of this node
 							startnode = node;
 							calOffset = true;
 						}
 					}
-		//			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;
-
-							return false;
+					//			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);
 						}
-		//			}catch(e){ debugger }
+						atmrange.setEndPoint(cmpstr, range);
+						startOffset = atmrange.text.length - lenoffset;
+
+						return false;
+					}
+					//			}catch(e){ debugger }
 					lastNode = node;
 					return true;
 				});
@@ -325,7 +339,7 @@ if(!dijit.range._w3c){
 			//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;
+				var nextnode = startnode.nextSibling;
 				if(nextnode && nextnode.nodeType == 3){
 					startnode = nextnode;
 					startOffset = 0;
@@ -336,9 +350,9 @@ if(!dijit.range._w3c){
 		setEndPoint: function(range, container, offset){
 			//text node
 			var atmrange = range.duplicate(), node, len;
-			if(container.nodeType!=3){ //normal node
+			if(container.nodeType != 3){ //normal node
 				if(offset > 0){
-					node = container.childNodes[offset-1];
+					node = container.childNodes[offset - 1];
 					if(node){
 						if(node.nodeType == 3){
 							container = node;
@@ -346,11 +360,11 @@ if(!dijit.range._w3c){
 							//pass through
 						}else{
 							if(node.nextSibling && node.nextSibling.nodeType == 3){
-								container=node.nextSibling;
-								offset=0;
+								container = node.nextSibling;
+								offset = 0;
 								//pass through
 							}else{
-								atmrange.moveToElementText(node.nextSibling?node:container);
+								atmrange.moveToElementText(node.nextSibling ? node : container);
 								var parent = node.parentNode;
 								var tempNode = parent.insertBefore(node.ownerDocument.createTextNode(' '), node.nextSibling);
 								atmrange.collapse(false);
@@ -372,7 +386,7 @@ if(!dijit.range._w3c){
 					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'){
+					if(prevnode.contentEditable != 'inherit'){
 						len++;
 					}
 				}else{
@@ -381,8 +395,8 @@ if(!dijit.range._w3c){
 				}
 
 				offset += len;
-				if(offset>0){
-					if(atmrange.move('character',offset) != offset){
+				if(offset > 0){
+					if(atmrange.move('character', offset) != offset){
 						console.error('Error when moving!');
 					}
 				}
@@ -397,10 +411,10 @@ if(!dijit.range._w3c){
 
 			if(range.htmlText.length){
 				if(range.htmlText == range.text){ //in the same text node
-					endOffset = startOffset+range.text.length;
+					endOffset = startOffset + range.text.length;
 				}else{
-					tmpary = dijit.range.ie.getEndPoint(range,true);
-					endContainer = tmpary[0], endOffset = tmpary[1];
+					tmpary = dijit.range.ie.getEndPoint(range, true);
+					endContainer = tmpary[0],endOffset = tmpary[1];
 //					if(startContainer.tagName == "BODY"){
 //						startContainer = startContainer.firstChild;
 //					}
@@ -408,21 +422,20 @@ if(!dijit.range._w3c){
 			}
 			return [startContainer, startOffset, endContainer, endOffset];
 		},
-		setRange: function(range, startContainer,
-			startOffset, endContainer, endOffset, collapsed){
-			var start=dijit.range.ie.setEndPoint(range, startContainer, startOffset);
+		setRange: function(range, startContainer, startOffset, endContainer, endOffset, collapsed){
+			var start = dijit.range.ie.setEndPoint(range, startContainer, startOffset);
 
-			range.setEndPoint('StartToStart',start);
+			range.setEndPoint('StartToStart', start);
 			if(!collapsed){
-				var end=dijit.range.ie.setEndPoint(range, endContainer, endOffset);
+				var end = dijit.range.ie.setEndPoint(range, endContainer, endOffset);
 			}
-			range.setEndPoint('EndToEnd',end || start);
+			range.setEndPoint('EndToEnd', end || start);
 
 			return range;
 		}
-	}
+	};
 
-dojo.declare("dijit.range.W3CRange",null, {
+declare("dijit.range.W3CRange",null, {
 	constructor: function(){
 		if(arguments.length>0){
 			this.setStart(arguments[0][0],arguments[0][1]);
@@ -495,7 +508,7 @@ dojo.declare("dijit.range.W3CRange",null, {
 		dijit.range.ie.setRange(r, this.startContainer, this.startOffset, this.endContainer, this.endOffset, this.collapsed);
 		return r;
 	},
-	getBookmark: function(body){
+	getBookmark: function(){
 		this._getIERange();
 		return this._cachedBookmark;
 	},
@@ -504,7 +517,14 @@ dojo.declare("dijit.range.W3CRange",null, {
 		r.select();
 	},
 	deleteContents: function(){
-		var r = this._getIERange();
+		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;
diff --git a/dijit/_editor/selection.js b/dijit/_editor/selection.js
index cabd7e8..822aa87 100644
--- a/dijit/_editor/selection.js
+++ b/dijit/_editor/selection.js
@@ -1,25 +1,37 @@
-define("dijit/_editor/selection", ["dojo", "dijit"], function(dojo, dijit) {
+define([
+	"dojo/dom", // dom.byId
+	"dojo/_base/lang",
+	"dojo/_base/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)
+], function(dom, lang, has, win, dijit){
 
-dojo.getObject("_editor.selection", true, dijit);
+// module:
+//		dijit/_editor/selection
+// summary:
+//		Text selection API
+
+
+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.
 
-dojo.mixin(dijit._editor.selection, {
+lang.mixin(dijit._editor.selection, {
 	getType: function(){
 		// summary:
-		//		Get the selection type (like dojo.doc.select.type in IE).
-		if(dojo.isIE < 9){
-			return dojo.doc.selection.type.toLowerCase();
+		//		Get the selection type (like win.doc.select.type in IE).
+		if(has("ie") < 9){
+			return win.doc.selection.type.toLowerCase();
 		}else{
 			var stype = "text";
 
 			// Check if the actual selection is a CONTROL (IMG, TABLE, HR, etc...).
 			var oSel;
 			try{
-				oSel = dojo.global.getSelection();
+				oSel = win.global.getSelection();
 			}catch(e){ /*squelch*/ }
 
 			if(oSel && oSel.rangeCount == 1){
@@ -38,13 +50,13 @@ dojo.mixin(dijit._editor.selection, {
 	getSelectedText: function(){
 		// summary:
 		//		Return the text (no html tags) included in the current selection or null if no text is selected
-		if(dojo.isIE < 9){
+		if(has("ie") < 9){
 			if(dijit._editor.selection.getType() == 'control'){
 				return null;
 			}
-			return dojo.doc.selection.createRange().text;
+			return win.doc.selection.createRange().text;
 		}else{
-			var selection = dojo.global.getSelection();
+			var selection = win.global.getSelection();
 			if(selection){
 				return selection.toString(); //String
 			}
@@ -55,20 +67,20 @@ dojo.mixin(dijit._editor.selection, {
 	getSelectedHtml: function(){
 		// summary:
 		//		Return the html text of the current selection or null if unavailable
-		if(dojo.isIE < 9){
+		if(has("ie") < 9){
 			if(dijit._editor.selection.getType() == 'control'){
 				return null;
 			}
-			return dojo.doc.selection.createRange().htmlText;
+			return win.doc.selection.createRange().htmlText;
 		}else{
-			var selection = dojo.global.getSelection();
+			var selection = win.global.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 = dojo.doc.createElement("div");
+					var div = win.doc.createElement("div");
 					div.appendChild(frag);
 					html += div.innerHTML;
 				}
@@ -84,13 +96,13 @@ dojo.mixin(dijit._editor.selection, {
 		//		a single element (object like and image or a table) is
 		//		selected.
 		if(dijit._editor.selection.getType() == "control"){
-			if(dojo.isIE < 9){
-				var range = dojo.doc.selection.createRange();
+			if(has("ie") < 9){
+				var range = win.doc.selection.createRange();
 				if(range && range.item){
-					return dojo.doc.selection.createRange().item(0);
+					return win.doc.selection.createRange().item(0);
 				}
 			}else{
-				var selection = dojo.global.getSelection();
+				var selection = win.global.getSelection();
 				return selection.anchorNode.childNodes[ selection.anchorOffset ];
 			}
 		}
@@ -104,12 +116,12 @@ dojo.mixin(dijit._editor.selection, {
 			var p = this.getSelectedElement();
 			if(p){ return p.parentNode; }
 		}else{
-			if(dojo.isIE < 9){
-				var r = dojo.doc.selection.createRange();
+			if(has("ie") < 9){
+				var r = win.doc.selection.createRange();
 				r.collapse(true);
 				return r.parentElement();
 			}else{
-				var selection = dojo.global.getSelection();
+				var selection = win.global.getSelection();
 				if(selection){
 					var node = selection.anchorNode;
 					while(node && (node.nodeType != 1)){ // not an element
@@ -182,7 +194,7 @@ dojo.mixin(dijit._editor.selection, {
 		// beginning: Boolean
 		//		Boolean to indicate whether to collapse the cursor to the beginning of the selection or end.
 		if(window.getSelection){
-			var selection = dojo.global.getSelection();
+			var selection = win.global.getSelection();
 			if(selection.removeAllRanges){ // Mozilla
 				if(beginning){
 					selection.collapseToStart();
@@ -193,8 +205,8 @@ dojo.mixin(dijit._editor.selection, {
 				// pulled from WebCore/ecma/kjs_window.cpp, line 2536
 				selection.collapse(beginning);
 			}
-		}else if(dojo.isIE){ // IE
-			var range = dojo.doc.selection.createRange();
+		}else if(has("ie")){ // IE
+			var range = win.doc.selection.createRange();
 			range.collapse(beginning);
 			range.select();
 		}
@@ -203,14 +215,14 @@ dojo.mixin(dijit._editor.selection, {
 	remove: function(){
 		// summary:
 		//		Function to delete the currently selected content from the document.
-		var sel = dojo.doc.selection;
-		if(dojo.isIE < 9){
+		var sel = win.doc.selection;
+		if(has("ie") < 9){
 			if(sel.type.toLowerCase() != "none"){
 				sel.clear();
 			}
 			return sel; //Selection
 		}else{
-			sel = dojo.global.getSelection();
+			sel = win.global.getSelection();
 			sel.deleteFromDocument();
 			return sel; //Selection
 		}
@@ -224,11 +236,11 @@ dojo.mixin(dijit._editor.selection, {
 		//		The element you wish to select the children content of.
 		// nochangefocus: Boolean
 		//		Boolean to indicate if the foxus should change or not.
-		var win = dojo.global;
-		var doc = dojo.doc;
+		var global = win.global;
+		var doc = win.doc;
 		var range;
-		element = dojo.byId(element);
-		if(doc.selection && dojo.isIE < 9 && dojo.body().createTextRange){ // IE
+		element = dom.byId(element);
+		if(doc.selection && has("ie") < 9 && win.body().createTextRange){ // IE
 			range = element.ownerDocument.body.createTextRange();
 			range.moveToElementText(element);
 			if(!nochangefocus){
@@ -236,9 +248,9 @@ dojo.mixin(dijit._editor.selection, {
 					range.select(); // IE throws an exception here if the widget is hidden.  See #5439
 				}catch(e){ /* squelch */}
 			}
-		}else if(win.getSelection){
-			var selection = dojo.global.getSelection();
-			if(dojo.isOpera){
+		}else if(global.getSelection){
+			var selection = win.global.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
@@ -264,16 +276,16 @@ dojo.mixin(dijit._editor.selection, {
 		// nochangefocus: Boolean
 		//		Boolean indicating if the focus should be changed.  IE only.
 		var range;
-		var doc = dojo.doc;
-		var win = dojo.global;
-		element = dojo.byId(element);
-		if(dojo.isIE < 9 && dojo.body().createTextRange){
+		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 = dojo.body().createControlRange();
+					range = win.body().createControlRange();
 				}else{
-					range = dojo.body().createRange();
+					range = win.body().createRange();
 				}
 				range.addElement(element);
 				if(!nochangefocus){
@@ -282,12 +294,12 @@ dojo.mixin(dijit._editor.selection, {
 			}catch(e){
 				this.selectElementChildren(element,nochangefocus);
 			}
-		}else if(dojo.global.getSelection){
-			var selection = win.getSelection();
+		}else if(global.getSelection){
+			var selection = global.getSelection();
 			range = doc.createRange();
 			if(selection.removeAllRanges){ // Mozilla
 				// FIXME: does this work on Safari?
-				if(dojo.isOpera){
+				if(has("opera")){
 					//Opera works if you use the current range on
 					//the selection if present.
 					if(selection.getRangeAt(0)){
@@ -309,12 +321,12 @@ dojo.mixin(dijit._editor.selection, {
 		//		public
 		if(node){
 			var newRange;
-			var doc = dojo.doc;
+			var doc = win.doc;
 			var range;
 
-			if(dojo.global.getSelection){
+			if(win.global.getSelection){
 				//WC3
-				var sel = dojo.global.getSelection();
+				var sel = win.global.getSelection();
 				if(sel && sel.rangeCount > 0){
 					range = sel.getRangeAt(0);
 				}
diff --git a/dijit/_tree/dndSource.js b/dijit/_tree/dndSource.js
index f55d1d0..28db300 100644
--- a/dijit/_tree/dndSource.js
+++ b/dijit/_tree/dndSource.js
@@ -1,10 +1,15 @@
-define("dijit/_tree/dndSource", ["dojo", "dijit", "dijit/tree/dndSource"], function(dojo, dijit) {
-
-// TODO: remove this file in 2.0
-dojo.deprecated("dijit._tree.dndSource has been moved to dijit.tree.dndSource, use that instead", "", "2.0");
-
-dijit._tree.dndSource = dijit.tree.dndSource;
-
-
-return dijit._tree.dndSource;
+define([
+	"dojo/_base/kernel", // kernel.deprecated
+	"dojo/_base/lang", // lang.getObject
+	"../tree/dndSource"
+], function(kernel, lang, dndSource){
+	// module:
+	//		dijit/_tree/dndSource
+	// 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");
+
+	lang.setObject("dijit._tree.dndSource", dndSource);
 });
diff --git a/dijit/a11y.js b/dijit/a11y.js
new file mode 100644
index 0000000..d616335
--- /dev/null
+++ b/dijit/a11y.js
@@ -0,0 +1,177 @@
+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){
+
+	// 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){
+		// 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
+					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';
+		}
+	};
+
+	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);
+		}
+	});
+
+	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();
+		}
+
+		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;
+				}
+
+				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;
+						}
+						if(!highest || tabindex >= highestTabindex){
+							highestTabindex = tabindex;
+							highest = child;
+						}
+					}
+					var rn = radioName(child);
+					if(domAttr.get(child, "checked") && rn){
+						radioSelected[rn] = 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;
+		}
+
+		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
+	};
+
+	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
+	};
+
+	return {
+		hasDefaultTabStop: dijit.hasDefaultTabStop,
+		isTabNavigable: dijit.isTabNavigable,
+		_getTabNavigable: dijit._getTabNavigable,
+		getFirstInTabbingOrder: dijit.getFirstInTabbingOrder,
+		getLastInTabbingOrder: dijit.getLastInTabbingOrder
+	};
+});
diff --git a/dijit/dijit-all.js b/dijit/dijit-all.js
index 1276f47..db78661 100644
--- a/dijit/dijit-all.js
+++ b/dijit/dijit-all.js
@@ -1,13 +1,70 @@
-define("dijit/dijit-all", ["dojo", "dijit", "dijit/dijit", "dijit/ColorPalette", "dijit/Declaration", "dijit/Dialog", "dijit/DialogUnderlay", "dijit/TooltipDialog", "dijit/Editor", "dijit/_editor/plugins/FontChoice", "dijit/_editor/plugins/LinkDialog", "dijit/Menu", "dijit/MenuItem", "dijit/PopupMenuItem", "dijit/MenuBar", "dijit/MenuBarItem", "dijit/PopupMenuBarItem", "dijit/MenuSeparator", "dijit/ProgressBar", "dijit/TitlePane", "dijit/Toolbar", "dijit/Tooltip", "dijit/Tree", "dijit/In [...]
+define([
+	".",
+	"./dijit",
+	"./ColorPalette",
+	"./Declaration",
+	"./Dialog",
+	"./DialogUnderlay",
+	"./TooltipDialog",
+	"./Editor",
+	"./_editor/plugins/FontChoice",
+	"./_editor/plugins/LinkDialog",
+	"./Menu",
+	"./MenuItem",
+	"./PopupMenuItem",
+	"./CheckedMenuItem",
+	"./MenuBar",
+	"./MenuBarItem",
+	"./PopupMenuBarItem",
+	"./MenuSeparator",
+	"./ProgressBar",
+	"./TitlePane",
+	"./Toolbar",
+	"./Tooltip",
+	"./Tree",
+	"./InlineEditBox",
+	"./form/Form",
+	"./form/Button",
+	"./form/DropDownButton",
+	"./form/ComboButton",
+	"./form/ToggleButton",
+	"./form/CheckBox",
+	"./form/RadioButton",
+	"./form/TextBox",
+	"./form/ValidationTextBox",
+	"./form/CurrencyTextBox",
+	"./form/DateTextBox",
+	"./form/TimeTextBox",
+	"./form/NumberSpinner",
+	"./form/NumberTextBox",
+	"./form/ComboBox",
+	"./form/FilteringSelect",
+	"./form/MultiSelect",
+	"./form/Select",
+	"./form/HorizontalSlider",
+	"./form/VerticalSlider",
+	"./form/HorizontalRule",
+	"./form/VerticalRule",
+	"./form/HorizontalRuleLabels",
+	"./form/VerticalRuleLabels",
+	"./form/SimpleTextarea",
+	"./form/Textarea",
+	"./layout/AccordionContainer",
+	"./layout/ContentPane",
+	"./layout/BorderContainer",
+	"./layout/LayoutContainer",
+	"./layout/LinkPane",
+	"./layout/SplitContainer",
+	"./layout/StackContainer",
+	"./layout/TabContainer"
+], function(dijit){
 
-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");
-
-/*=====
-dijit["dijit-all"] = {
+	// module:
+	//		dijit/dijit-all
 	// summary:
 	//		A rollup that includes every dijit. You probably don't need this.
-};
-=====*/
 
-return dijit;
+	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");
+
+	return dijit;
 });
diff --git a/dijit/dijit.js b/dijit/dijit.js
index 9f44e61..de1de1c 100644
--- a/dijit/dijit.js
+++ b/dijit/dijit.js
@@ -1,23 +1,21 @@
-define("dijit/dijit", ["dojo", "dijit", "dijit/_base", "dojo/parser", "dijit/_Widget", "dijit/_Templated", "dijit/_Container", "dijit/layout/_LayoutWidget", "dijit/form/_FormWidget"], function(dojo, dijit) {
+define([
+	".",
+	"./_base",
+	"dojo/parser",
+	"./_Widget",
+	"./_TemplatedMixin",
+	"./_Container",
+	"./layout/_LayoutWidget",
+	"./form/_FormWidget",
+	"./form/_FormValueWidget"
+], function(dijit){
 
-/*=====
-dijit.dijit = {
+	// module:
+	//		dijit/dijit
 	// summary:
 	//		A roll-up for common dijit methods
-	// description:
-	//	A rollup file for the build system including the core and common
-	//	dijit files.
-	//
-	// example:
-	// | <script type="text/javascript" src="js/dojo/dijit/dijit.js"></script>
-	//
-};
-=====*/
+	//		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
 
-// 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;
+	return dijit;
 });
diff --git a/dijit/dijit.profile.js b/dijit/dijit.profile.js
new file mode 100644
index 0000000..dffbfa0
--- /dev/null
+++ b/dijit/dijit.profile.js
@@ -0,0 +1,39 @@
+var profile = (function(){
+	var testResourceRe = /^dijit\/tests\//,
+
+		copyOnly = function(filename, mid){
+			var list = {
+				"dijit/dijit.profile":1,
+				"dijit/package.json":1,
+				"dijit/themes/claro/compile":1
+			};
+			return (mid in list) || (/^dijit\/resources\//.test(mid) && !/\.css$/.test(filename)) || /(png|jpg|jpeg|gif|tiff)$/.test(filename);
+		};
+
+	return {
+		resourceTags:{
+			test: function(filename, mid){
+				return testResourceRe.test(mid) || mid=="dijit/robot" || mid=="dijit/robotx";
+			},
+
+			copyOnly: function(filename, mid){
+				return copyOnly(filename, mid);
+			},
+
+			amd: function(filename, mid){
+				return !testResourceRe.test(mid) && !copyOnly(filename, mid) && /\.js$/.test(filename);
+			},
+
+			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
new file mode 100644
index 0000000..4a3b335
--- /dev/null
+++ b/dijit/focus.js
@@ -0,0 +1,389 @@
+define([
+	"dojo/aspect",
+	"dojo/_base/declare", // declare
+	"dojo/dom", // domAttr.get dom.isDescendant
+	"dojo/dom-attr", // domAttr.get dom.isDescendant
+	"dojo/dom-construct", // connect to domConstruct.empty, domConstruct.destroy
+	"dojo/Evented",
+	"dojo/_base/lang", // lang.hitch
+	"dojo/on",
+	"dojo/ready",
+	"dojo/_base/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,
+			a11y, registry, dijit){
+
+	// module:
+	//		dijit/focus
+	// summary:
+	//		Returns a singleton that tracks the currently focused node, and which widgets are currently "active".
+
+/*=====
+	dijit.focus = {
+		// summary:
+		//		Tracks the currently focused node, and which widgets are currently "active".
+		//		Access via require(["dijit/focus"], function(focus){ ... }).
+		//
+		//		A widget is considered active if it or a descendant widget has focus,
+		//		or if a non-focusable node of this widget or a descendant was recently clicked.
+		//
+		//		Call focus.watch("curNode", callback) to track the current focused DOMNode,
+		//		or focus.watch("activeStack", callback) to track the currently focused stack of widgets.
+		//
+		//		Call focus.on("widget-blur", func) or focus.on("widget-focus", ...) to monitor when
+		//		when widgets become active/inactive
+		//
+		//		Finally, focus(node) will focus a node, suppressing errors if the node doesn't exist.
+
+		// curNode: DomNode
+		//		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[]
+		//		List of currently active widgets (focused widget and it's ancestors)
+		activeStack: [],
+
+		constructor: function(){
+			// Don't leave curNode/prevNode pointing to bogus elements
+			var check = lang.hitch(this, function(node){
+				if(dom.isDescendant(this.curNode, node)){
+					this.set("curNode", null);
+				}
+				if(dom.isDescendant(this.prevNode, node)){
+					this.set("prevNode", null);
+				}
+			});
+			aspect.before(domConstruct, "empty", check);
+			aspect.before(domConstruct, "destroy", check);
+		},
+
+		registerIframe: function(/*DomNode*/ 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.
+			return this.registerWin(iframe.contentWindow, iframe);
+		},
+
+		registerWin: function(/*Window?*/targetWindow, /*DomNode?*/ 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:
+			//		If specified this is the window associated with the iframe,
+			//		i.e. iframe.contentWindow.
+			// effectiveNode:
+			//		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.
+
+			// 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);
+
+				// 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 || evt.srcElement, "mouse");
+			};
+
+			// 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; }
+
+						// 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)
+						}
+					};
+				}
+			}
+		},
+
+		_onBlurNode: function(/*DomNode*/ /*===== node =====*/){
+			// summary:
+			// 		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(this._justMouseDowned){
+				// the mouse down caused a new widget to be marked as active; this blur event
+				// is coming late, so ignore it.
+				return;
+			}
+
+			// if the blur event isn't followed by a focus 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);
+		},
+
+		_onTouchNode: function(/*DomNode*/ node, /*String*/ by){
+			// summary:
+			//		Callback when node is focused or mouse-downed
+			// node:
+			//		The node that was touched.
+			// by:
+			//		"mouse" if the focus/touch was caused by a mouse down event
+
+			// ignore the recent blurNode event
+			if(this._clearActiveWidgetsTimer){
+				clearTimeout(this._clearActiveWidgetsTimer);
+				delete this._clearActiveWidgetsTimer;
+			}
+
+			// compute stack of active widgets (ex: ComboButton --> Menu --> MenuItem)
+			var newStack=[];
+			try{
+				while(node){
+					var popupParent = domAttr.get(node, "dijitPopupParent");
+					if(popupParent){
+						node=registry.byId(popupParent).domNode;
+					}else if(node.tagName && node.tagName.toLowerCase() == "body"){
+						// is this the root of the document or just the root of an iframe?
+						if(node === win.body()){
+							// node is the root of the main document
+							break;
+						}
+						// otherwise, find the iframe this node refers to (can't access it via parentNode,
+						// need to do this trick instead). window.frameElement is supported in IE/FF/Webkit
+						node=winUtils.get(node.ownerDocument).frameElement;
+					}else{
+						// if this node is the root node of a widget, then add widget id to stack,
+						// except ignore clicks on disabled widgets (actually focusing a disabled widget still works,
+						// to support MenuItem)
+						var id = node.getAttribute && node.getAttribute("widgetId"),
+							widget = id && registry.byId(id);
+						if(widget && !(by == "mouse" && widget.get("disabled"))){
+							newStack.unshift(id);
+						}
+						node=node.parentNode;
+					}
+				}
+			}catch(e){ /* squelch */ }
+
+			this._setStack(newStack, by);
+		},
+
+		_onFocusNode: function(/*DomNode*/ node){
+			// summary:
+			//		Callback when node is focused
+
+			if(!node){
+				return;
+			}
+
+			if(node.nodeType == 9){
+				// Ignore focus events on the document itself.  This is here so that
+				// (for example) clicking the up/down arrows of a spinner
+				// (which don't get focus) won't cause that widget to blur. (FF issue)
+				return;
+			}
+
+			this._onTouchNode(node);
+
+			if(node == this.curNode){ return; }
+			this.set("curNode", node);
+		},
+
+		_setStack: function(/*String[]*/ newStack, /*String*/ by){
+			// summary:
+			//		The stack of active widgets has changed.  Send out appropriate events and records new stack.
+			// newStack:
+			//		array of widget id's, starting from the top (outermost) widget
+			// by:
+			//		"mouse" if the focus/touch was caused by a mouse down event
+
+			var oldStack = this.activeStack;
+			this.set("activeStack", newStack);
+
+			// 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;
+				}
+			}
+
+			var widget;
+			// for all elements that have gone out of focus, set focused=false
+			for(var i=oldStack.length-1; i>=nCommon; i--){
+				widget = registry.byId(oldStack[i]);
+				if(widget){
+					widget._hasBeenBlurred = true;		// TODO: used by form widgets, should be moved there
+					widget.set("focused", false);
+					if(widget._focusManager == this){
+						widget._onBlur(by);
+					}
+					this.emit("widget-blur", widget, by);
+				}
+			}
+
+			// for all element that have come into focus, set focused=true
+			for(i=nCommon; i<newStack.length; i++){
+				widget = registry.byId(newStack[i]);
+				if(widget){
+					widget.set("focused", true);
+					if(widget._focusManager == this){
+						widget._onFocus(by);
+					}
+					this.emit("widget-focus", widget, by);
+				}
+			}
+		},
+
+		focus: function(node){
+			// summary:
+			//		Focus the specified node, suppressing errors if they occur
+			if(node){
+				try{ node.focus(); }catch(e){/*quiet*/}
+			}
+		}
+	});
+
+	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);
+		if(has("ie")){
+			unload.addOnWindowUnload(function(){
+				handle.remove();
+				handle = null;
+			})
+		}
+	});
+
+	// Setup dijit.focus as a pointer to the singleton but also (for backwards compatibility)
+	// as a function to set focus.
+	dijit.focus = function(node){
+		singleton.focus(node);	// indirection here allows dijit/_base/focus.js to override behavior
+	};
+	for(var attr in singleton){
+		if(!/^_/.test(attr)){
+			dijit.focus[attr] = typeof singleton[attr] == "function" ? lang.hitch(singleton, attr) : singleton[attr];
+		}
+	}
+	singleton.watch(function(attr, oldVal, newVal){
+		dijit.focus[attr] = newVal;
+	});
+
+	return singleton;
+});
diff --git a/dijit/form/Button.js b/dijit/form/Button.js
index e6c134f..a9ccbc2 100644
--- a/dijit/form/Button.js
+++ b/dijit/form/Button.js
@@ -1,8 +1,34 @@
-define("dijit/form/Button", ["dojo", "dijit", "text!dijit/form/templates/Button.html", "text!dijit/form/templates/DropDownButton.html", "text!dijit/form/templates/ComboButton.html", "dijit/form/_FormWidget", "dijit/_Container", "dijit/_HasDropDown"], function(dojo, dijit) {
-
-dojo.declare("dijit.form.Button",
-	dijit.form._FormWidget,
-	{
+define([
+	"require",
+	"dojo/_base/declare", // declare
+	"dojo/dom-class", // domClass.toggle
+	"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){
+
+/*=====
+	var _FormWidget = dijit.form._FormWidget;
+	var _ButtonMixin = dijit.form._ButtonMixin;
+=====*/
+
+// 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:
@@ -10,18 +36,12 @@ dojo.declare("dijit.form.Button",
 	//		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="dijit.form.Button" onClick="...">Hello world</button>
 	//
 	// example:
 	// |	var button1 = new dijit.form.Button({label: "hello world", onClick: foo});
 	// |	dojo.body().appendChild(button1.domNode);
 
-	// label: HTML String
-	//		Text to display in button.
-	//		If the label is hidden (showLabel=false) then and no title has
-	//		been specified, then label is also set as title attribute of icon.
-	label: "",
-
 	// showLabel: Boolean
 	//		Set this to true to hide the label text and display only the icon.
 	//		(If showLabel=false then iconClass must be specified.)
@@ -34,52 +54,28 @@ dojo.declare("dijit.form.Button",
 
 	// iconClass: String
 	//		Class to apply to DOMNode in button to make it display an icon
-	iconClass: "",
-
-	// type: String
-	//		Defines the type of button.  "button", "submit", or "reset".
-	type: "button",
+	iconClass: "dijitNoIcon",
+	_setIconClassAttr: { node: "iconNode", type: "class" },
 
 	baseClass: "dijitButton",
 
-	templateString: dojo.cache("dijit.form", "templates/Button.html"),
+	templateString: template,
 
-	attributeMap: dojo.delegate(dijit.form._FormWidget.prototype.attributeMap, {
-		value: "valueNode"
-	}),
+	// Map widget attributes to DOMNode attributes.
+	_setValueAttr: "valueNode",
 
 	_onClick: function(/*Event*/ e){
 		// summary:
 		//		Internal function to handle click actions
-		if(this.disabled){
-			return false;
-		}
-		this._clicked(); // widget click actions
-		return this.onClick(e); // user click actions
-	},
-
-	_onButtonClick: function(/*Event*/ e){
-		// summary:
-		//		Handler when the user activates the button portion.
-		if(this._onClick(e) === false){ // returning nothing is same as true
-			e.preventDefault(); // needed for checkbox
-		}else if(this.type == "submit" && !(this.valueNode||this.focusNode).form){ // see if a nonform widget needs to be signalled
-			for(var node=this.domNode; node.parentNode/*#5935*/; node=node.parentNode){
-				var widget=dijit.byNode(node);
-				if(widget && typeof widget._onSubmit == "function"){
-					widget._onSubmit(e);
-					break;
-				}
+		var ok = this.inherited(arguments);
+		if(ok){
+			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
 			}
-		}else if(this.valueNode){
-			this.valueNode.click();
-			e.preventDefault(); // cancel BUTTON click and continue with hidden INPUT click
 		}
-	},
-
-	buildRendering: function(){
-		this.inherited(arguments);
-		dojo.setSelectable(this.focusNode, false);
+		return ok;
 	},
 
 	_fillContent: function(/*DomNode*/ source){
@@ -88,35 +84,24 @@ dojo.declare("dijit.form.Button",
 		// 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))){
-			this.set('label', source.innerHTML);
+			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){
-			dojo.toggleClass(this.containerNode, "dijitDisplayNone", !val);
+			domClass.toggle(this.containerNode, "dijitDisplayNone", !val);
 		}
 		this._set("showLabel", val);
 	},
 
-	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
-	},
-
-	_clicked: function(/*Event*/ e){
-		// summary:
-		//		Internal overridable function for when the button is clicked
-	},
-
 	setLabel: function(/*String*/ content){
 		// summary:
 		//		Deprecated.  Use set('label', ...) instead.
-		dojo.deprecated("dijit.form.Button.setLabel() is deprecated.  Use set('label', ...) instead.", "", "2.0");
+		kernel.deprecated("dijit.form.Button.setLabel() is deprecated.  Use set('label', ...) instead.", "", "2.0");
 		this.set("label", content);
 	},
 
@@ -125,225 +110,15 @@ dojo.declare("dijit.form.Button",
 		//		Hook for set('label', ...) to work.
 		// description:
 		//		Set the label (text) of the button; takes an HTML string.
-		this._set("label", content);
-		this.containerNode.innerHTML = content;
-		if(this.showLabel == false && !this.params.title){
-			this.titleNode.title = dojo.trim(this.containerNode.innerText || this.containerNode.textContent || '');
-		}
-	},
-
-	_setIconClassAttr: function(/*String*/ val){
-		// Custom method so that icon node is hidden when not in use, to avoid excess padding/margin
-		// appearing around it (even if it's a 0x0 sized <img> node)
-
-		var oldVal = this.iconClass || "dijitNoIcon",
-			newVal = val || "dijitNoIcon";
-		dojo.replaceClass(this.iconNode, newVal, oldVal);
-		this._set("iconClass", val);
-	}
-});
-
-
-dojo.declare("dijit.form.DropDownButton", [dijit.form.Button, dijit._Container, dijit._HasDropDown], {
-	// summary:
-	//		A button with a drop down
-	//
-	// example:
-	// |	<button dojoType="dijit.form.DropDownButton" label="Hello world">
-	// |		<div dojotype="dijit.Menu">...</div>
-	// |	</button>
-	//
-	// example:
-	// |	var button1 = new dijit.form.DropDownButton({ label: "hi", dropDown: new dijit.Menu(...) });
-	// |	dojo.body().appendChild(button1);
-	//
-
-	baseClass : "dijitDropDownButton",
-
-	templateString: dojo.cache("dijit.form" , "templates/DropDownButton.html"),
-
-	_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 = dojo.query("*", this.srcNodeRef);
-			dijit.form.DropDownButton.superclass._fillContent.call(this, 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 = dojo.query("[widgetId]", this.dropDownContainer)[0];
-			this.dropDown = dijit.byNode(dropDownNode);
-			delete this.dropDownContainer;
-		}
-		if(this.dropDown){
-			dijit.popup.hide(this.dropDown);
-		}
-
+		//		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);
-	},
-
-	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(){
-		// Loads our dropdown
-		var dropDown = this.dropDown;
-		if(!dropDown){ return; }
-		if(!this.isLoaded()){
-			var handler = dojo.connect(dropDown, "onLoad", this, function(){
-				dojo.disconnect(handler);
-				this.openDropDown();
-			});
-			dropDown.refresh();
-		}else{
-			this.openDropDown();
-		}
-	},
-
-	isFocusable: function(){
-		// Overridden so that focus is handled by the _HasDropDown mixin, not by
-		// the _FormWidget mixin.
-		return this.inherited(arguments) && !this._mouseDown;
-	}
-});
-
-dojo.declare("dijit.form.ComboButton", dijit.form.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 dojoType="dijit.form.ComboButton" onClick="...">
-	// |		<span>Hello world</span>
-	// |		<div dojoType="dijit.Menu">...</div>
-	// |	</button>
-	//
-	// example:
-	// |	var button1 = new dijit.form.ComboButton({label: "hello world", onClick: foo, dropDown: "myMenu"});
-	// |	dojo.body().appendChild(button1.domNode);
-	//
-
-	templateString: dojo.cache("dijit.form", "templates/ComboButton.html"),
-
-	attributeMap: dojo.mixin(dojo.clone(dijit.form.Button.prototype.attributeMap), {
-		id: "",
-		tabIndex: ["focusNode", "titleNode"],
-		title: "titleNode"
-	}),
-
-	// optionsTitle: String
-	//		Text that describes the options menu (accessibility)
-	optionsTitle: "",
-
-	baseClass: "dijitComboButton",
-
-	// Set classes like dijitButtonContentsHover or dijitArrowButtonActive depending on
-	// mouse action over specified node
-	cssStateNodes: {
-		"buttonNode": "dijitButtonNode",
-		"titleNode": "dijitButtonContents",
-		"_popupStateNode": "dijitDownArrowButton"
-	},
-
-	_focusedNode: null,
-
-	_onButtonKeyPress: function(/*Event*/ evt){
-		// summary:
-		//		Handler for right arrow key when focus is on left part of button
-		if(evt.charOrCode == dojo.keys[this.isLeftToRight() ? "RIGHT_ARROW" : "LEFT_ARROW"]){
-			dijit.focus(this._popupStateNode);
-			dojo.stopEvent(evt);
-		}
-	},
-
-	_onArrowKeyPress: function(/*Event*/ evt){
-		// summary:
-		//		Handler for left arrow key when focus is on right part of button
-		if(evt.charOrCode == dojo.keys[this.isLeftToRight() ? "LEFT_ARROW" : "RIGHT_ARROW"]){
-			dijit.focus(this.titleNode);
-			dojo.stopEvent(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){
-			dijit.focus(position == "start" ? this.titleNode : this._popupStateNode);
+		if(!this.showLabel && !("title" in this.params)){
+			this.titleNode.title = lang.trim(this.containerNode.innerText || this.containerNode.textContent || '');
 		}
 	}
 });
 
-dojo.declare("dijit.form.ToggleButton", dijit.form.Button, {
-	// summary:
-	//		A button that can be in two states (checked or not).
-	//		Can be base class for things like tabs or checkbox or radio buttons
-
-	baseClass: "dijitToggleButton",
-
-	// 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,
-
-	attributeMap: dojo.mixin(dojo.clone(dijit.form.Button.prototype.attributeMap), {
-		checked:"focusNode"
-	}),
-
-	_clicked: function(/*Event*/ evt){
-		this.set('checked', !this.checked);
-	},
 
-	_setCheckedAttr: function(/*Boolean*/ value, /*Boolean?*/ priorityChange){
-		this._set("checked", value);
-		dojo.attr(this.focusNode || this.domNode, "checked", value);
-		dijit.setWaiState(this.focusNode || this.domNode, "pressed", value);
-		this._handleOnChange(value, priorityChange);
-	},
-
-	setChecked: function(/*Boolean*/ checked){
-		// summary:
-		//		Deprecated.  Use set('checked', true/false) instead.
-		dojo.deprecated("setChecked("+checked+") is deprecated. Use set('checked',"+checked+") instead.", "", "2.0");
-		this.set('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);
-	}
 });
 
-
-return dijit.form.Button;
-});
diff --git a/dijit/form/CheckBox.js b/dijit/form/CheckBox.js
index a530e26..53d9e63 100644
--- a/dijit/form/CheckBox.js
+++ b/dijit/form/CheckBox.js
@@ -1,9 +1,35 @@
-define("dijit/form/CheckBox", ["dojo", "dijit", "text!dijit/form/templates/CheckBox.html", "dijit/form/ToggleButton"], function(dojo, dijit) {
+define([
+	"require",
+	"dojo/_base/declare", // declare
+	"dojo/dom-attr", // domAttr.set
+	"dojo/_base/kernel",
+	"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;
+=====*/
+
+	// module:
+	//		dijit/form/CheckBox
+	// summary:
+	//		Checkbox widget
+
+	// Back compat w/1.6, remove for 2.0
+	if(!kernel.isAsync){
+		ready(0, function(){
+			var requires = ["dijit/form/RadioButton"];
+			require(requires);	// use indirection so modules not rolled into a build
+		});
+	}
 
-dojo.declare(
-	"dijit.form.CheckBox",
-	dijit.form.ToggleButton,
-	{
+	return declare("dijit.form.CheckBox", [ToggleButton, _CheckBoxMixin], {
 		// summary:
 		// 		Same as an HTML checkbox, but with fancy styling.
 		//
@@ -21,46 +47,10 @@ dojo.declare(
 		//		In case 2, the regular html inputs are invisible but still used by
 		//		the user. They are turned quasi-invisible and overlay the background-image.
 
-		templateString: dojo.cache("dijit.form", "templates/CheckBox.html"),
+		templateString: template,
 
 		baseClass: "dijitCheckBox",
 
-		// type: [private] String
-		//		type attribute on <input> node.
-		//		Overrides `dijit.form.Button.type`.  Users should not change this value.
-		type: "checkbox",
-
-		// value: String
-		//		As an initialization parameter, equivalent to value field on normal checkbox
-		//		(if checked, the value is passed as the value when form is submitted).
-		//
-		//		However, get('value') will return either the string or false depending on
-		//		whether or not the checkbox is checked.
-		//
-		//		set('value', string) will check the checkbox and change the value to the
-		//		specified string
-		//
-		//		set('value', boolean) will change the checked state.
-		value: "on",
-
-		// readOnly: Boolean
-		//		Should this widget respond to user input?
-		//		In markup, this is specified as "readOnly".
-		//		Similar to disabled except readOnly form values are submitted.
-		readOnly: false,
-		
-		// the attributeMap should inherit from dijit.form._FormWidget.prototype.attributeMap
-		// instead of ToggleButton as the icon mapping has no meaning for a CheckBox
-		attributeMap: dojo.delegate(dijit.form._FormWidget.prototype.attributeMap, {
-			readOnly: "focusNode"
-		}),
-
-		_setReadOnlyAttr: function(/*Boolean*/ value){
-			this._set("readOnly", value);
-			dojo.attr(this.focusNode, 'readOnly', value);
-			dijit.setWaiState(this.focusNode, "readonly", value);
-		},
-
 		_setValueAttr: function(/*String|Boolean*/ newValue, /*Boolean*/ priorityChange){
 			// summary:
 			//		Handler for value= attribute to constructor, and also calls to
@@ -72,10 +62,13 @@ dojo.declare(
 			//		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
-			//		dojoType="dijit.CheckBox" value="chicken">)
+			//		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);
-				dojo.attr(this.focusNode, 'value', newValue);
+				domAttr.set(this.focusNode, 'value', newValue);
 				newValue = true;
 			}
 			if(this._created){
@@ -91,105 +84,35 @@ dojo.declare(
 			return (this.checked ? this.value : false);
 		},
 
-		// 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,
+		// Override behavior from Button, since we don't have an iconNode
+		_setIconClassAttr: null,
 
 		postMixInProperties: function(){
-			if(this.value == ""){
-				this.value = "on";
-			}
+			this.inherited(arguments);
 
 			// Need to set initial checked state as part of template, so that form submit works.
-			// dojo.attr(node, "checked", bool) doesn't work on IEuntil node has been attached
+			// 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.inherited(arguments);
 		},
 
-		 _fillContent: function(/*DomNode*/ source){
+		 _fillContent: function(){
 			// Override Button::_fillContent() since it doesn't make sense for CheckBox,
 			// since CheckBox doesn't even have a container
 		},
 
-		reset: function(){
-			// Override ToggleButton.reset()
-
-			this._hasBeenBlurred = false;
-
-			this.set('checked', this.params.checked || false);
-
-			// Handle unlikely event that the <input type=checkbox> value attribute has changed
-			this._set("value", this.params.value || "on");
-			dojo.attr(this.focusNode, 'value', this.value);
-		},
-
 		_onFocus: function(){
 			if(this.id){
-				dojo.query("label[for='"+this.id+"']").addClass("dijitFocusedLabel");
+				query("label[for='"+this.id+"']").addClass("dijitFocusedLabel");
 			}
 			this.inherited(arguments);
 		},
 
 		_onBlur: function(){
 			if(this.id){
-				dojo.query("label[for='"+this.id+"']").removeClass("dijitFocusedLabel");
+				query("label[for='"+this.id+"']").removeClass("dijitFocusedLabel");
 			}
 			this.inherited(arguments);
-		},
-
-		_onClick: function(/*Event*/ e){
-			// summary:
-			//		Internal function to handle click actions - need to check
-			//		readOnly, since button no longer does that check.
-			if(this.readOnly){
-				dojo.stopEvent(e);
-				return false;
-			}
-			return this.inherited(arguments);
-		}
-	}
-);
-
-dojo.declare(
-	"dijit.form.RadioButton",
-	dijit.form.CheckBox,
-	{
-		// summary:
-		// 		Same as an HTML radio, but with fancy styling.
-
-		type: "radio",
-		baseClass: "dijitRadio",
-
-		_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(value){
-				var _this = this;
-				// search for radio buttons with the same name that need to be unchecked
-				dojo.query("INPUT[type=radio]", this.focusNode.form || dojo.doc).forEach( // can't use name= since dojo.query doesn't support [] in the name
-					function(inputNode){
-						if(inputNode.name == _this.name && inputNode != _this.focusNode && inputNode.form == _this.focusNode.form){
-							var widget = dijit.getEnclosingWidget(inputNode);
-							if(widget && widget.checked){
-								widget.set('checked', false);
-							}
-						}
-					}
-				);
-			}
-		},
-
-		_clicked: function(/*Event*/ e){
-			if(!this.checked){
-				this.set('checked', true);
-			}
 		}
-	}
-);
-
-
-return dijit.form.CheckBox;
+	});
 });
diff --git a/dijit/form/ComboBox.js b/dijit/form/ComboBox.js
index a0464ed..d585120 100644
--- a/dijit/form/ComboBox.js
+++ b/dijit/form/ComboBox.js
@@ -1,1077 +1,22 @@
-define("dijit/form/ComboBox", ["dojo", "dijit", "text!dijit/form/templates/DropDownBox.html", "dojo/window", "dojo/regexp", "dojo/data/util/simpleFetch", "dojo/data/util/filter", "dijit/_CssStateMixin", "dijit/form/_FormWidget", "dijit/form/ValidationTextBox", "dijit/_HasDropDown", "i18n!dijit/form/nls/ComboBox"], function(dojo, dijit) {
-
-dojo.declare(
-	"dijit.form.ComboBoxMixin",
-	dijit._HasDropDown,
-	{
-		// summary:
-		//		Implements the base functionality for `dijit.form.ComboBox`/`dijit.form.FilteringSelect`
-		// description:
-		//		All widgets that mix in dijit.form.ComboBoxMixin must extend `dijit.form._FormValueWidget`.
-		// tags:
-		//		protected
-
-		// item: Object
-		//		This is the item returned by the dojo.data.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] Object
-		//		Reference to data provider object used by this ComboBox
-		store: null,
-
-		// fetchProperties: Object
-		//		Mixin to the dojo.data 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
-		//		the `<input>` field
-		autoComplete: true,
-
-		// highlightMatch: String
-		// 		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"
-		//		then will probably want to change `queryExpr` parameter to '*${0}*'
-		//
-		//		Highlighting is only performed when `labelType` is "text", so as to not
-		//		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.
-		//		If not specified, the searchAttr attribute is used instead.
-		labelAttr: "",
-
-		// labelType: String
-		//		Specifies how to interpret the labelAttr in the data store items.
-		//		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,
-
-		// hasDownArrow: Boolean
-		//		Set this textbox to have a down arrow button, to display the drop down list.
-		//		Defaults to true.
-		hasDownArrow: true,
-
-		templateString: dojo.cache("dijit.form", "templates/DropDownBox.html"),
-
-		baseClass: "dijitTextBox dijitComboBox",
-
-		// dropDownClass: [protected extension] String
-		//		Name of the dropdown widget class used to select a date/time.
-		//		Subclasses should specify this.
-		dropDownClass: "dijit.form._ComboBoxMenu",
-
-		// Set classes like dijitDownArrowButtonHover depending on
-		// mouse action over button node
-		cssStateNodes: {
-			"_buttonNode": "dijitDownArrowButton"
-		},
-
-		// Flags to _HasDropDown to limit height of drop down to make it fit in viewport
-		maxHeight: -1,
-
-		// For backwards compatibility let onClick events propagate, even clicks on the down arrow button
-		_stopClickEvents: false,
-
-		_getCaretPos: function(/*DomNode*/ element){
-			// khtml 3.5.2 has selection* methods as does webkit nightlies from 2005-06-22
-			var pos = 0;
-			if(typeof(element.selectionStart) == "number"){
-				// FIXME: this is totally borked on Moz < 1.3. Any recourse?
-				pos = element.selectionStart;
-			}else if(dojo.isIE){
-				// in the case of a mouse click in a popup being handled,
-				// then the dojo.doc.selection is not the textarea, but the popup
-				// var r = dojo.doc.selection.createRange();
-				// hack to get IE 6 to play nice. What a POS browser.
-				var tr = dojo.doc.selection.createRange().duplicate();
-				var ntr = element.createTextRange();
-				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;
-				}catch(e){
-					// If focus has shifted, 0 is fine for caret pos.
-				}
-			}
-			return pos;
-		},
-
-		_setCaretPos: function(/*DomNode*/ element, /*Number*/ location){
-			location = parseInt(location);
-			dijit.selectInputText(element, location, location);
-		},
-
-		_setDisabledAttr: function(/*Boolean*/ value){
-			// Additional code to set disabled state of ComboBox node.
-			// Overrides _FormValueWidget._setDisabledAttr() or ValidationTextBox._setDisabledAttr().
-			this.inherited(arguments);
-			dijit.setWaiState(this.domNode, "disabled", value);
-		},
-
-		_abortQuery: function(){
-			// stop in-progress query
-			if(this.searchTimer){
-				clearTimeout(this.searchTimer);
-				this.searchTimer = null;
-			}
-			if(this._fetchHandle){
-				if(this._fetchHandle.abort){ this._fetchHandle.abort(); }
-				this._fetchHandle = null;
-			}
-		},
-
-		_onInput: function(/*Event*/ evt){
-			// summary:
-			//		Handles paste events
-			if(!this.searchTimer && (evt.type == 'paste'/*IE|WebKit*/ || evt.type == 'input'/*Firefox*/) && this._lastInput != this.textbox.value){
-				this.searchTimer = setTimeout(dojo.hitch(this, function(){
-					this._onKey({charOrCode: 229}); // fake IME key to cause a search
-				}), 100); // long delay that will probably be preempted by keyboard input
-			}
-			this.inherited(arguments);
-		},
-
-		_onKey: function(/*Event*/ evt){
-			// summary:
-			//		Handles keyboard events
-
-			var key = evt.charOrCode;
-
-			// except for cutting/pasting case - ctrl + x/v
-			if(evt.altKey || ((evt.ctrlKey || evt.metaKey) && (key != 'x' && key != 'v')) || key == dojo.keys.SHIFT){
-				return; // throw out weird key combinations and spurious events
-			}
-			
-			var doSearch = false;
-			var pw = this.dropDown;
-			var dk = dojo.keys;
-			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
-			this.inherited(arguments);
-
-			if(this._opened){
-				highlighted = pw.getHighlightedOption();
-			}
-			switch(key){
-				case dk.PAGE_DOWN:
-				case dk.DOWN_ARROW:
-				case dk.PAGE_UP:
-				case dk.UP_ARROW:
-					// Keystroke caused ComboBox_menu to move to a different item.
-					// Copy new item to <input> box.
-					if(this._opened){
-						this._announceOption(highlighted);
-					}
-					dojo.stopEvent(evt);
-					break;
-
-				case dk.ENTER:
-					// prevent submitting form if user presses enter. Also
-					// prevent accepting the value if either Next or Previous
-					// are selected
-					if(highlighted){
-						// only stop event on prev/next
-						if(highlighted == pw.nextButton){
-							this._nextSearch(1);
-							dojo.stopEvent(evt);
-							break;
-						}else if(highlighted == pw.previousButton){
-							this._nextSearch(-1);
-							dojo.stopEvent(evt);
-							break;
-						}
-					}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, but allow event to bubble
-					if(this._opened || this._fetchHandle){
-					evt.preventDefault();
-					}
-					// fall through
-
-				case dk.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"])
-					){
-						break;
-					}
-					if(highlighted){
-						this._selectOption();
-					}
-					if(this._opened){
-						this._lastQuery = null; // in case results come back later
-						this.closeDropDown();
-					}
-					break;
-
-				case ' ':
-					if(highlighted){
-						// user is effectively clicking a choice in the drop down menu
-						dojo.stopEvent(evt);
-						this._selectOption();
-						this.closeDropDown();
-					}else{
-						// user typed a space into the input box, treat as normal character
-						doSearch = true;
-					}
-					break;
-
-				case dk.DELETE:
-				case dk.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(dojo.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.
-
-			var fn = this.focusNode;
-
-			// IE7: clear selection so next highlight works all the time
-			dijit.selectInputText(fn, fn.value.length);
-			// does text autoComplete the value in the textbox?
-			var caseFilter = this.ignoreCase? 'toLowerCase' : 'substr';
-			if(text[caseFilter](0).indexOf(this.focusNode.value[caseFilter](0)) == 0){
-				var cpos = this._getCaretPos(fn);
-				// only try to extend if we added the last character at the end of the input
-				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);
-					// visually highlight the autocompleted characters
-					dijit.selectInputText(fn, cpos);
-				}
-			}else{
-				// text does not autoComplete; replace the whole value and highlight
-				fn.value = text;
-				dijit.selectInputText(fn);
-			}
-		},
-
-		_openResultList: function(/*Object*/ results, /*Object*/ dataObject){
-			// summary:
-			//		Callback when a search completes.
-			// description:
-			//		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 ||
-				(dataObject.query[this.searchAttr] != this._lastQuery)
-			){
-				return;
-			}
-			var wasSelected = this.dropDown._highlighted_option && dojo.hasClass(this.dropDown._highlighted_option, "dijitMenuItemSelected");
-			this.dropDown.clearResultList();
-			if(!results.length && !this._maxOptions){ // if no results and not just the previous choices button
-				this.closeDropDown();
-				return;
-			}
-
-			// 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.
-
-			dataObject._maxOptions = this._maxOptions;
-			var nodes = this.dropDown.createOptions(
-				results,
-				dataObject,
-				dojo.hitch(this, "_getMenuLabelFromItem")
-			);
-
-			// show our list (only if we have content, else nothing)
-			this._showResultList();
-
-			// #4091:
-			//		tell the screen reader that the paging callback finished by
-			//		shouting the next choice
-			if(dataObject.direction){
-				if(1 == dataObject.direction){
-					this.dropDown.highlightFirstOption();
-				}else if(-1 == dataObject.direction){
-					this.dropDown.highlightLastOption();
-				}
-				if(wasSelected){
-					this._announceOption(this.dropDown.getHighlightedOption());
-				}
-			}else if(this.autoComplete && !this._prev_key_backspace
-				// when the user clicks the arrow button to show the full list,
-				// startSearch looks for "*".
-				// it does not make sense to autocomplete
-				// if they are just previewing the options available.
-				&& !/^[*]+$/.test(dataObject.query[this.searchAttr])){
-					this._announceOption(nodes[1]); // 1st real item
-			}
-		},
-
-		_showResultList: function(){
-			// summary:
-			//		Display the drop down if not already displayed, or if it is displayed, then
-			//		reposition it if necessary (reposition may be necessary if drop down's height changed).
-
-			this.closeDropDown(true);
-
-			// hide the tooltip
-			this.displayMessage("");
-
-			this.openDropDown();
-
-			dijit.setWaiState(this.domNode, "expanded", "true");
-		},
-
-		loadDropDown: function(/*Function*/ callback){
-			// 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();
-		},
-
-		isLoaded: function(){
-			// signal to _HasDropDown that it needs to call loadDropDown() to load the
-			// drop down asynchronously before displaying it
-			return false;
-		},
-
-		closeDropDown: function(){
-			// Overrides _HasDropDown.closeDropDown().  Closes the drop down (assuming that it's open).
-			// This method is the callback when the user types ESC or clicking
-			// the button icon while the drop down is open.  It's also called by other code.
-			this._abortQuery();
-			if(this._opened){
-				this.inherited(arguments);
-				dijit.setWaiState(this.domNode, "expanded", "false");
-				dijit.removeWaiState(this.focusNode,"activedescendant");
-			}
-		},
-
-		_setBlurValue: function(){
-			// if the user clicks away from the textbox OR tabs away, set the
-			// value to the textbox value
-			// #4617:
-			//		if value is now more choices or previous choices, revert
-			//		the value
-			var newvalue = this.get('displayedValue');
-			var pw = this.dropDown;
-			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
-				this.item = null;
-				this.set('displayedValue', newvalue);
-			}else{
-				if(this.value != this._lastValueReported){
-					dijit.form._FormValueWidget.prototype._setValueAttr.call(this, this.value, true);
-				}
-				this._refreshState();
-			}
-		},
-
-		_onBlur: function(){
-			// summary:
-			//		Called magically when focus has shifted away from this widget and it's drop down
-			this.closeDropDown();
-			this.inherited(arguments);
-		},
-
-		_setItemAttr: function(/*item*/ item, /*Boolean?*/ priorityChange, /*String?*/ displayedValue){
-			// summary:
-			//		Set the displayed valued in the input box, and the hidden value
-			//		that gets submitted, based on a dojo.data store item.
-			// description:
-			//		Users shouldn't call this function; they should be calling
-			//		set('item', value)
-			// tags:
-			//		private
-			if(!displayedValue){
-				displayedValue = this.store.getValue(item, this.searchAttr);
-			}
-			var value = this._getValueField() != this.searchAttr? this.store.getIdentity(item) : displayedValue;
-			this._set("item", item);
-			dijit.form.ComboBox.superclass._setValueAttr.call(this, value, priorityChange, displayedValue);
-		},
-
-		_announceOption: function(/*Node*/ node){
-			// summary:
-			//		a11y code that puts the highlighted option in the textbox.
-			//		This way screen readers will know what is happening in the
-			//		menu.
-
-			if(!node){
-				return;
-			}
-			// pull the text value from the item attached to the DOM node
-			var newValue;
-			if(node == this.dropDown.nextButton ||
-				node == this.dropDown.previousButton){
-				newValue = node.innerHTML;
-				this.item = undefined;
-				this.value = '';
-			}else{
-				newValue = this.store.getValue(node.item, this.searchAttr).toString();
-				this.set('item', node.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);
-			// set up ARIA activedescendant
-			dijit.setWaiState(this.focusNode, "activedescendant", dojo.attr(node, "id"));
-			// autocomplete the rest of the option to announce change
-			this._autoCompleteText(newValue);
-		},
-
-		_selectOption: function(/*Event*/ evt){
-			// summary:
-			//		Menu callback function, called when an item in the menu is selected.
-			if(evt){
-				this._announceOption(evt.target);
-			}
-			this.closeDropDown();
-			this._setCaretPos(this.focusNode, this.focusNode.value.length);
-			dijit.form._FormValueWidget.prototype._setValueAttr.call(this, this.value, true); // set this.value and fire onChange
-		},
-
-		_startSearchAll: function(){
-			this._startSearch('');
-		},
-
-		_startSearchFromInput: function(){
-			this._startSearch(this.focusNode.value.replace(/([\\\*\?])/g, "\\$1"));
-		},
-
-		_getQueryString: function(/*String*/ text){
-			return dojo.string.substitute(this.queryExpr, [text]);
-		},
-
-		_startSearch: function(/*String*/ key){
-			// summary:
-			//		Starts a search for elements matching key (key=="" means to return all items),
-			//		and calls _openResultList() when the search completes, to display the results.
-			if(!this.dropDown){
-				var popupId = this.id + "_popup",
-				dropDownConstructor = dojo.getObject(this.dropDownClass, false);
-				this.dropDown = new dropDownConstructor({
-					onChange: dojo.hitch(this, this._selectOption),
-					id: popupId,
-					dir: this.dir
-				});
-				dijit.removeWaiState(this.focusNode,"activedescendant");
-				dijit.setWaiState(this.textbox,"owns",popupId); // associate popup with textbox
-			}
-			// create a new query to prevent accidentally querying for a hidden
-			// value from FilteringSelect's keyField
-			var query = dojo.clone(this.query); // #5970
-			this._lastInput = key; // Store exactly what was entered by the user.
-			this._lastQuery = query[this.searchAttr] = this._getQueryString(key);
-			// #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(dojo.hitch(this, function(query, _this){
-				this.searchTimer = null;
-				var fetch = {
-					queryOptions: {
-						ignoreCase: this.ignoreCase,
-						deep: true
-					},
-					query: query,
-					onBegin: dojo.hitch(this, "_setMaxOptions"),
-					onComplete: dojo.hitch(this, "_openResultList"),
-					onError: function(errText){
-						_this._fetchHandle = null;
-						console.error('dijit.form.ComboBox: ' + errText);
-						_this.closeDropDown();
-					},
-					start: 0,
-					count: this.pageSize
-				};
-				dojo.mixin(fetch, _this.fetchProperties);
-				this._fetchHandle = _this.store.fetch(fetch);
-
-				var nextSearch = function(dataObject, direction){
-					dataObject.start += dataObject.count*direction;
-					// #4091:
-					//		tell callback the direction of the paging so the screen
-					//		reader knows which menu option to shout
-					dataObject.direction = direction;
-					this._fetchHandle = this.store.fetch(dataObject);
-					this.focus();
-				};
-				this._nextSearch = this.dropDown.onPage = dojo.hitch(this, nextSearch, this._fetchHandle);
-			}, query, this), this.searchDelay);
-		},
-
-		_setMaxOptions: function(size, request){
-			 this._maxOptions = size;
-		},
-
-		_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.
-			return this.searchAttr;
-		},
-
-		//////////// INITIALIZATION METHODS ///////////////////////////////////////
-
-		constructor: function(){
-			this.query={};
-			this.fetchProperties={};
-		},
-
-		postMixInProperties: function(){
-			if(!this.store){
-				var srcNodeRef = this.srcNodeRef;
-
-				// if user didn't specify store, then assume there are option tags
-				this.store = new dijit.form._ComboBoxDataStore(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
-
-				// Firefox and Safari set value
-				// IE6 and Opera set selectedIndex, which is automatically set
-				// by the selected attribute of an option tag
-				// IE6 does not set value, Opera sets value = selectedIndex
-				if(!("value" in this.params)){
-					var item = (this.item = this.store.fetchSelectedItem());
-					if(item){
-						var valueField = this._getValueField();
-						this.value = this.store.getValue(item, valueField);
-					}
-				}
-			}
-
-			this.inherited(arguments);
-		},
-
-		postCreate: function(){
-			// summary:
-			//		Subclasses must call this method from their postCreate() methods
-			// tags:
-			//		protected
-
-			// find any associated label element and add to ComboBox node.
-			var label=dojo.query('label[for="'+this.id+'"]');
-			if(label.length){
-				label[0].id = (this.id+"_label");
-				dijit.setWaiState(this.domNode, "labelledby", label[0].id);
-
-			}
-			this.inherited(arguments);
-		},
-
-		_setHasDownArrowAttr: function(val){
-			this.hasDownArrow = val;
-			this._buttonNode.style.display = val ? "" : "none";
-		},
-
-		_getMenuLabelFromItem: function(/*Item*/ item){
-			var label = this.labelFunc(item, this.store),
-				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));
-				labelType = "html";
-			}
-			return {html: labelType == "html", label: label};
-		},
-
-		doHighlight: function(/*String*/ label, /*String*/ find){
-			// summary:
-			//		Highlights the string entered by the user in the menu.  By default this
-			//		highlights the first occurrence found. Override this method
-			//		to implement your custom highlighting.
-			// tags:
-			//		protected
-
-			var
-				// 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 = dojo.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>'
-			); // 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: &<>"'
-			str = String(str).replace(/&/gm, "&").replace(/</gm, "<")
-				.replace(/>/gm, ">").replace(/"/gm, """);
-			return str; // string
-		},
-
-		reset: function(){
-			// Overrides the _FormWidget.reset().
-			// Additionally reset the .item (to clean up).
-			this.item = null;
-			this.inherited(arguments);
-		},
-
-		labelFunc: function(/*item*/ item, /*dojo.data.store*/ store){
-			// summary:
-			//		Computes the label to display based on the dojo.data store item.
-			// returns:
-			//		The label that the ComboBox should display
-			// tags:
-			//		private
-
-			// Use toString() because XMLStore returns an XMLItem whereas this
-			// method is expected to return a String (#9354)
-			return store.getValue(item, this.labelAttr || this.searchAttr).toString(); // String
-		}
-	}
-);
-
-dojo.declare(
-	"dijit.form._ComboBoxMenu",
-	[dijit._Widget, dijit._Templated, dijit._CssStateMixin],
-	{
-		// summary:
-		//		Focus-less menu for internal use in `dijit.form.ComboBox`
-		// tags:
-		//		private
-
-		templateString: "<ul class='dijitReset dijitMenu' dojoAttachEvent='onmousedown:_onMouseDown,onmouseup:_onMouseUp,onmouseover:_onMouseOver,onmouseout:_onMouseOut' style='overflow: \"auto\"; overflow-x: \"hidden\";'>"
-				+"<li class='dijitMenuItem dijitMenuPreviousButton' dojoAttachPoint='previousButton' role='option'></li>"
-				+"<li class='dijitMenuItem dijitMenuNextButton' dojoAttachPoint='nextButton' role='option'></li>"
-			+"</ul>",
-
-		// _messages: Object
-		//		Holds "next" and "previous" text for paging buttons on drop down
-		_messages: null,
-		
-		baseClass: "dijitComboBoxMenu",
-
-		postMixInProperties: function(){
-			this.inherited(arguments);
-			this._messages = dojo.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);
-		},
-
-		// stubs
-		onChange: function(/*Object*/ value){
-			// summary:
-			//		Notifies ComboBox/FilteringSelect that user clicked an option in the drop down menu.
-			//		Probably should be called onSelect.
-			// 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._blurOptionNode();
-		},
-
-		_createOption: function(/*Object*/ item, labelFunc){
-			// summary:
-			//		Creates an option to appear on the popup menu subclassed by
-			//		`dijit.form.FilteringSelect`.
-
-			var menuitem = dojo.create("li", {
-				"class": "dijitReset dijitMenuItem" +(this.isLeftToRight() ? "" : " dijitMenuItemRtl"),
-				role: "option"
-			});
-			var labelObject = labelFunc(item);
-			if(labelObject.html){
-				menuitem.innerHTML = labelObject.label;
-			}else{
-				menuitem.appendChild(
-					dojo.doc.createTextNode(labelObject.label)
-				);
-			}
-			// #3250: in blank options, assign a normal height
-			if(menuitem.innerHTML == ""){
-				menuitem.innerHTML = " ";
-			}
-			menuitem.item=item;
-			return menuitem;
-		},
-
-		createOptions: function(results, dataObject, labelFunc){
-			// summary:
-			//		Fills in the items in the drop down list
-			// results:
-			//		Array of dojo.data items
-			// dataObject:
-			//		dojo.data store
-			// labelFunc:
-			//		Function to produce a label in the drop down list from a dojo.data item
-
-			//this._dataObject=dataObject;
-			//this._dataObject.onComplete=dojo.hitch(comboBox, comboBox._openResultList);
-			// display "Previous . . ." button
-			this.previousButton.style.display = (dataObject.start == 0) ? "none" : "";
-			dojo.attr(this.previousButton, "id", this.id + "_prev");
-			// create options using _createOption function defined by parent
-			// ComboBox (or FilteringSelect) class
-			// #2309:
-			//		iterate over cache nondestructively
-			dojo.forEach(results, function(item, i){
-				var menuitem = this._createOption(item, labelFunc);
-				dojo.attr(menuitem, "id", this.id + i);
-				this.domNode.insertBefore(menuitem, this.nextButton);
-			}, this);
-			// display "Next . . ." button
-			var displayMore = false;
-			//Try to determine if we should show 'more'...
-			if(dataObject._maxOptions && dataObject._maxOptions != -1){
-				if((dataObject.start + dataObject.count) < dataObject._maxOptions){
-					displayMore = true;
-				}else if((dataObject.start + dataObject.count) > dataObject._maxOptions && dataObject.count == results.length){
-					//Weird return from a datastore, 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(dataObject.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";
-			dojo.attr(this.nextButton,"id", this.id + "_next");
-			return this.domNode.childNodes;
-		},
-
-		clearResultList: function(){
-			// summary:
-			//		Clears the entries in the drop down list, but of course keeps the previous and next buttons.
-			while(this.domNode.childNodes.length>2){
-				this.domNode.removeChild(this.domNode.childNodes[this.domNode.childNodes.length-2]);
-			}
-			this._blurOptionNode();
-		},
-
-		_onMouseDown: function(/*Event*/ evt){
-			dojo.stopEvent(evt);
-		},
-
-		_onMouseUp: function(/*Event*/ evt){
-			if(evt.target === this.domNode || !this._highlighted_option){
-				// !this._highlighted_option check to prevent immediate selection when menu appears on top
-				// of <input>, see #9898.  Note that _HasDropDown also has code to prevent this.
-				return;
-			}else if(evt.target == this.previousButton){
-				this._blurOptionNode();
-				this.onPage(-1);
-			}else if(evt.target == this.nextButton){
-				this._blurOptionNode();
-				this.onPage(1);
-			}else{
-				var tgt = evt.target;
-				// while the clicked node is inside the div
-				while(!tgt.item){
-					// recurse to the top
-					tgt = tgt.parentNode;
-				}
-				this._setValueAttr({ target: tgt }, true);
-			}
-		},
-
-		_onMouseOver: function(/*Event*/ evt){
-			if(evt.target === this.domNode){ return; }
-			var tgt = evt.target;
-			if(!(tgt == this.previousButton || tgt == this.nextButton)){
-				// while the clicked node is inside the div
-				while(!tgt.item){
-					// recurse to the top
-					tgt = tgt.parentNode;
-				}
-			}
-			this._focusOptionNode(tgt);
-		},
-
-		_onMouseOut: function(/*Event*/ evt){
-			if(evt.target === this.domNode){ return; }
-			this._blurOptionNode();
-		},
-
-		_focusOptionNode: function(/*DomNode*/ node){
-			// summary:
-			//		Does the actual highlight.
-			if(this._highlighted_option != node){
-				this._blurOptionNode();
-				this._highlighted_option = node;
-				dojo.addClass(this._highlighted_option, "dijitMenuItemSelected");
-			}
-		},
-
-		_blurOptionNode: function(){
-			// summary:
-			//		Removes highlight on highlighted option.
-			if(this._highlighted_option){
-				dojo.removeClass(this._highlighted_option, "dijitMenuItemSelected");
-				this._highlighted_option = null;
-			}
-		},
-
-		_highlightNextOption: function(){
-			// summary:
-			// 		Highlight the item just below the current selection.
-			// 		If nothing selected, highlight first option.
-
-			// because each press of a button clears the menu,
-			// the highlighted option sometimes becomes detached from the menu!
-			// test to see if the option has a parent to see if this is the case.
-			if(!this.getHighlightedOption()){
-				var fc = this.domNode.firstChild;
-				this._focusOptionNode(fc.style.display == "none" ? fc.nextSibling : fc);
-			}else{
-				var ns = this._highlighted_option.nextSibling;
-				if(ns && ns.style.display != "none"){
-					this._focusOptionNode(ns);
-				}else{
-					this.highlightFirstOption();
-				}
-			}
-			// scrollIntoView is called outside of _focusOptionNode because in IE putting it inside causes the menu to scroll up on mouseover
-			dojo.window.scrollIntoView(this._highlighted_option);
-		},
-
-		highlightFirstOption: function(){
-			// summary:
-			// 		Highlight the first real item in the list (not Previous Choices).
-			var first = this.domNode.firstChild;
-			var second = first.nextSibling;
-			this._focusOptionNode(second.style.display == "none" ? first : second); // remotely possible that Previous Choices is the only thing in the list
-			dojo.window.scrollIntoView(this._highlighted_option);
-		},
-
-		highlightLastOption: function(){
-			// summary:
-			// 		Highlight the last real item in the list (not More Choices).
-			this._focusOptionNode(this.domNode.lastChild.previousSibling);
-			dojo.window.scrollIntoView(this._highlighted_option);
-		},
-
-		_highlightPrevOption: function(){
-			// summary:
-			// 		Highlight the item just above the current selection.
-			// 		If nothing selected, highlight last option (if
-			// 		you select Previous and try to keep scrolling up the list).
-			if(!this.getHighlightedOption()){
-				var lc = this.domNode.lastChild;
-				this._focusOptionNode(lc.style.display == "none" ? lc.previousSibling : lc);
-			}else{
-				var ps = this._highlighted_option.previousSibling;
-				if(ps && ps.style.display != "none"){
-					this._focusOptionNode(ps);
-				}else{
-					this.highlightLastOption();
-				}
-			}
-			dojo.window.scrollIntoView(this._highlighted_option);
-		},
-
-		_page: function(/*Boolean*/ up){
-			// summary:
-			//		Handles page-up and page-down keypresses
-
-			var scrollamount = 0;
-			var oldscroll = this.domNode.scrollTop;
-			var height = dojo.style(this.domNode, "height");
-			// if no item is highlighted, highlight the first option
-			if(!this.getHighlightedOption()){
-				this._highlightNextOption();
-			}
-			while(scrollamount<height){
-				if(up){
-					// stop at option 1
-					if(!this.getHighlightedOption().previousSibling ||
-						this._highlighted_option.previousSibling.style.display == "none"){
-						break;
-					}
-					this._highlightPrevOption();
-				}else{
-					// stop at last option
-					if(!this.getHighlightedOption().nextSibling ||
-						this._highlighted_option.nextSibling.style.display == "none"){
-						break;
-					}
-					this._highlightNextOption();
-				}
-				// going backwards
-				var newscroll=this.domNode.scrollTop;
-				scrollamount+=(newscroll-oldscroll)*(up ? -1:1);
-				oldscroll=newscroll;
-			}
-		},
-
-		pageUp: function(){
-			// summary:
-			//		Handles pageup keypress.
-			//		TODO: just call _page directly from handleKey().
-			// tags:
-			//		private
-			this._page(true);
-		},
-
-		pageDown: function(){
-			// summary:
-			//		Handles pagedown keypress.
-			//		TODO: just call _page directly from handleKey().
-			// tags:
-			//		private
-			this._page(false);
-		},
-
-		getHighlightedOption: function(){
-			// summary:
-			//		Returns the highlighted option.
-			var ho = this._highlighted_option;
-			return (ho && ho.parentNode) ? ho : null;
-		},
-
-		handleKey: function(evt){
-			// summary:
-			//		Handle keystroke event forwarded from ComboBox, returning false if it's
-			//		a keystroke I recognize and process, true otherwise.
-			switch(evt.charOrCode){
-				case dojo.keys.DOWN_ARROW:
-					this._highlightNextOption();
-					return false;
-				case dojo.keys.PAGE_DOWN:
-					this.pageDown();
-					return false;
-				case dojo.keys.UP_ARROW:
-					this._highlightPrevOption();
-					return false;
-				case dojo.keys.PAGE_UP:
-					this.pageUp();
-					return false;
-				default:
-					return true;
-			}
-		}
-	}
-);
+define([
+	"dojo/_base/declare", // declare
+	"./ValidationTextBox",
+	"./ComboBoxMixin"
+], function(declare, ValidationTextBox, ComboBoxMixin){
+
+/*=====
+	var ValidationTextBox = dijit.form.ValidationTextBox;
+	var ComboBoxMixin = dijit.form.ComboBoxMixin;
+=====*/
+
+	// module:
+	//		dijit/form/ComboBox
+	// summary:
+	//		Auto-completing text box
 
-dojo.declare(
-	"dijit.form.ComboBox",
-	[dijit.form.ValidationTextBox, dijit.form.ComboBoxMixin],
-	{
+	return declare("dijit.form.ComboBox", [ValidationTextBox, ComboBoxMixin], {
 		// summary:
-		//		Auto-completing text box, and base class for dijit.form.FilteringSelect.
+		//		Auto-completing text box
 		//
 		// description:
 		//		The drop down box's values are populated from an class called
@@ -1085,130 +30,5 @@ dojo.declare(
 		//
 		//		Some of the options to the ComboBox are actually arguments to the data
 		//		provider.
-
-		_setValueAttr: function(/*String*/ value, /*Boolean?*/ priorityChange, /*String?*/ displayedValue){
-			// summary:
-			//		Hook so set('value', value) works.
-			// description:
-			//		Sets the value of the select.
-			this._set("item", null); // value not looked up in store
-			if(!value){ value = ''; } // null translates to blank
-			dijit.form.ValidationTextBox.prototype._setValueAttr.call(this, value, priorityChange, displayedValue);
-		}
-	}
-);
-
-dojo.declare("dijit.form._ComboBoxDataStore", null, {
-	// summary:
-	//		Inefficient but small data store specialized for inlined `dijit.form.ComboBox` data
-	//
-	// description:
-	//		Provides a store for inlined data like:
-	//
-	//	|	<select>
-	//	|		<option value="AL">Alabama</option>
-	//	|		...
-	//
-	//		Actually. just implements the subset of dojo.data.Read/Notification
-	//		needed for ComboBox and FilteringSelect to work.
-	//
-	//		Note that an item is just a pointer to the <option> DomNode.
-
-	constructor: function( /*DomNode*/ root){
-		this.root = root;
-		if(root.tagName != "SELECT" && root.firstChild){
-			root = dojo.query("select", root);
-			if(root.length > 0){ // SELECT is a child of srcNodeRef
-				root = root[0];
-			}else{ // no select, so create 1 to parent the option tags to define selectedIndex
-				this.root.innerHTML = "<SELECT>"+this.root.innerHTML+"</SELECT>";
-				root = this.root.firstChild;
-			}
-			this.root = root;
-		}
-		dojo.query("> option", root).forEach(function(node){
-			//	TODO: this was added in #3858 but unclear why/if it's needed;  doesn't seem to be.
-			//	If it is needed then can we just hide the select itself instead?
-			//node.style.display="none";
-			node.innerHTML = dojo.trim(node.innerHTML);
-		});
-
-	},
-
-	getValue: function(	/*item*/ item,
-						/*attribute-name-string*/ attribute,
-						/*value?*/ defaultValue){
-		return (attribute == "value") ? item.value : (item.innerText || item.textContent || '');
-	},
-
-	isItemLoaded: function(/*anything*/ something){
-		return true;
-	},
-
-	getFeatures: function(){
-		return {"dojo.data.api.Read": true, "dojo.data.api.Identity": true};
-	},
-
-	_fetchItems: function(	/*Object*/ args,
-							/*Function*/ findCallback,
-							/*Function*/ errorCallback){
-		// summary:
-		//		See dojo.data.util.simpleFetch.fetch()
-		if(!args.query){ args.query = {}; }
-		if(!args.query.name){ args.query.name = ""; }
-		if(!args.queryOptions){ args.queryOptions = {}; }
-		var matcher = dojo.data.util.filter.patternToRegExp(args.query.name, args.queryOptions.ignoreCase),
-			items = dojo.query("> option", this.root).filter(function(option){
-				return (option.innerText || option.textContent || '').match(matcher);
-			} );
-		if(args.sort){
-			items.sort(dojo.data.util.sorter.createSortFunction(args.sort, this));
-		}
-		findCallback(items, args);
-	},
-
-	close: function(/*dojo.data.api.Request || args || null*/ request){
-		return;
-	},
-
-	getLabel: function(/*item*/ item){
-		return item.innerHTML;
-	},
-
-	getIdentity: function(/*item*/ item){
-		return dojo.attr(item, "value");
-	},
-
-	fetchItemByIdentity: function(/*Object*/ args){
-		// summary:
-		//		Given the identity of an item, this method returns the item that has
-		//		that identity through the onItem callback.
-		//		Refer to dojo.data.api.Identity.fetchItemByIdentity() for more details.
-		//
-		// description:
-		//		Given arguments like:
-		//
-		//	|		{identity: "CA", onItem: function(item){...}
-		//
-		//		Call `onItem()` with the DOM node `<option value="CA">California</option>`
-		var item = dojo.query("> option[value='" + args.identity + "']", this.root)[0];
-		args.onItem(item);
-	},
-
-	fetchSelectedItem: function(){
-		// summary:
-		//		Get the option marked as selected, like `<option selected>`.
-		//		Not part of dojo.data API.
-		var root = this.root,
-			si = root.selectedIndex;
-		return typeof si == "number"
-			? dojo.query("> option:nth-child(" + (si != -1 ? si+1 : 1) + ")", root)[0]
-			: null;	// dojo.data.Item
-	}
-});
-//Mix in the simple fetch implementation to this class.
-dojo.extend(dijit.form._ComboBoxDataStore,dojo.data.util.simpleFetch);
-
-
-return dijit.form.ComboBox;
+	});
 });
diff --git a/dijit/form/ComboBoxMixin.js b/dijit/form/ComboBoxMixin.js
new file mode 100644
index 0000000..ee4a9b8
--- /dev/null
+++ b/dijit/form/ComboBoxMixin.js
@@ -0,0 +1,146 @@
+define([
+	"dojo/_base/declare", // declare
+	"dojo/_base/Deferred",
+	"dojo/_base/kernel", // kernel.deprecated
+	"dojo/_base/lang", // lang.mixin
+	"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:
+		//		Provides main functionality of ComboBox widget
+
+		// dropDownClass: [protected extension] Function String
+		//		Dropdown widget class used to select a date/time.
+		//		Subclasses should specify this.
+		dropDownClass: _ComboBoxMenu,
+
+		// hasDownArrow: Boolean
+		//		Set this textbox to have a down arrow button, to display the drop down list.
+		//		Defaults to true.
+		hasDownArrow: true,
+
+		templateString: template,
+
+		baseClass: "dijitTextBox dijitComboBox",
+
+		/*=====
+		// 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
+		//		for backwards compatibility.
+		store: null,
+		=====*/
+
+		// Set classes like dijitDownArrowButtonHover depending on
+		// mouse action over button node
+		cssStateNodes: {
+			"_buttonNode": "dijitDownArrowButton"
+		},
+
+		_setHasDownArrowAttr: function(/*Boolean*/ val){
+			this._set("hasDownArrow", val);
+			this._buttonNode.style.display = val ? "" : "none";
+		},
+
+		_showResultList: function(){
+			// hide the tooltip
+			this.displayMessage("");
+			this.inherited(arguments);
+		},
+
+		_setStoreAttr: function(store){
+			// 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(){ fetchHandle.abort && fetchHandle.abort(); });
+						var fetchHandle = this.fetch(lang.mixin({
+							query: query,
+							onBegin: function(count){
+								deferred.total = count;
+							},
+							onComplete: function(results){
+								deferred.resolve(results);
+							},
+							onError: function(error){
+								deferred.reject(error);
+							}
+						}, options));
+						return QueryResults(deferred);
+					}
+				});
+			}
+			this._set("store", store);
+		},
+
+		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);
+			}
+
+			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){
+				var clazz = this.declaredClass;
+				lang.mixin(this.store, {
+					getValue: function(item, attr){
+						kernel.deprecated(clazz + ".store.getValue(item, attr) is deprecated for builtin store.  Use item.attr directly", "", "2.0");
+						return item[attr];
+					},
+					getLabel: function(item){
+						kernel.deprecated(clazz + ".store.getLabel(item) is deprecated for builtin store.  Use item.label directly", "", "2.0");
+						return item.name;
+					},
+					fetch: function(args){
+						kernel.deprecated(clazz + ".store.fetch() is deprecated for builtin store.", "Use store.query()", "2.0");
+						var shim = ["dojo/data/ObjectStore"];	// indirection so it doesn't get rolled into a build
+						require(shim, lang.hitch(this, function(ObjectStore){
+							new ObjectStore({objectStore: this}).fetch(args);
+						}));
+					}
+				});
+			}
+		}
+	});
+});
diff --git a/dijit/form/ComboButton.js b/dijit/form/ComboButton.js
index 0ece056..3d7dfc7 100644
--- a/dijit/form/ComboButton.js
+++ b/dijit/form/ComboButton.js
@@ -1,6 +1,89 @@
-define("dijit/form/ComboButton", ["dojo", "dijit", "dijit/form/Button"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/_base/event", // event.stop
+	"dojo/keys", // keys
+	"../focus",		// focus.focus()
+	"./DropDownButton",
+	"dojo/text!./templates/ComboButton.html"
+], function(declare, event, keys, focus, DropDownButton, template){
 
+/*=====
+	var DropDownButton = dijit.form.DropDownButton;
+=====*/
 
+// 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 dijit.form.ComboButton({label: "hello world", onClick: foo, dropDown: "myMenu"});
+	// |	dojo.body().appendChild(button1.domNode);
+	//
+
+	templateString: template,
+
+	// 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: "",
+
+	baseClass: "dijitComboButton",
+
+	// Set classes like dijitButtonContentsHover or dijitArrowButtonActive depending on
+	// mouse action over specified node
+	cssStateNodes: {
+		"buttonNode": "dijitButtonNode",
+		"titleNode": "dijitButtonContents",
+		"_popupStateNode": "dijitDownArrowButton"
+	},
+
+	_focusedNode: null,
+
+	_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);
+		}
+	},
+
+	_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);
+		}
+	}
+});
 
-return dijit.form.ComboButton;
 });
diff --git a/dijit/form/CurrencyTextBox.js b/dijit/form/CurrencyTextBox.js
index 315513a..191ac7d 100644
--- a/dijit/form/CurrencyTextBox.js
+++ b/dijit/form/CurrencyTextBox.js
@@ -1,27 +1,39 @@
-define("dijit/form/CurrencyTextBox", ["dojo", "dijit", "dojo/currency", "dijit/form/NumberTextBox"], function(dojo, dijit) {
+define([
+	"dojo/currency", // currency._mixInDefaults currency.format currency.parse currency.regexp
+	"dojo/_base/declare", // declare
+	"dojo/_base/lang", // lang.hitch
+	"./NumberTextBox"
+], function(currency, declare, lang, NumberTextBox){
 
 /*=====
-dojo.declare(
-	"dijit.form.CurrencyTextBox.__Constraints",
-	[dijit.form.NumberTextBox.__Constraints, dojo.currency.__FormatOptions, dojo.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`.
-	//		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):
-	//	|		{fractional:true}
-});
+	var NumberTextBox = dijit.form.NumberTextBox;
 =====*/
 
-dojo.declare(
-	"dijit.form.CurrencyTextBox",
-	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], {
+		// 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`.
+		//		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):
+		//	|		{fractional:true}
+	});
+	=====*/
+
+	return declare("dijit.form.CurrencyTextBox", NumberTextBox, {
 		// summary:
 		//		A validating currency textbox
 		// description:
@@ -44,21 +56,21 @@ dojo.declare(
 		//		formatting options.  See `dijit.form.CurrencyTextBox.__Constraints` for details.
 		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, [ dojo.mixin({}, constraints, this.editOptions) ]) + '|' : '')
-				+ dojo.currency.regexp(constraints) + ')';
+			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: dojo.currency.format,
+		_formatter: currency.format,
 
-		_parser: dojo.currency.parse,
+		_parser: currency.parse,
 
 		parse: function(/*String*/ value, /*Object*/ constraints){
 			// summary:
@@ -67,7 +79,7 @@ dojo.declare(
 			// 		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 = dojo.hitch(dojo.mixin({}, this, { _parser: dijit.form.NumberTextBox.prototype._parser }), "inherited")(arguments);
+				v = lang.hitch(lang.mixin({}, this, { _parser: NumberTextBox.prototype._parser }), "inherited")(arguments);
 			}
 			return v;
 		},
@@ -76,11 +88,7 @@ dojo.declare(
 			if(!constraints.currency && this.currency){
 				constraints.currency = this.currency;
 			}
-			this.inherited(arguments, [ dojo.currency._mixInDefaults(dojo.mixin(constraints, { exponent: false })) ]); // get places
+			this.inherited(arguments, [ currency._mixInDefaults(lang.mixin(constraints, { exponent: false })) ]); // get places
 		}
-	}
-);
-
-
-return dijit.form.CurrencyTextBox;
+	});
 });
diff --git a/dijit/form/DataList.js b/dijit/form/DataList.js
new file mode 100644
index 0000000..4d6a9f2
--- /dev/null
+++ b/dijit/form/DataList.js
@@ -0,0 +1,63 @@
+define([
+	"dojo/_base/declare", // declare
+	"dojo/dom", // dom.byId
+	"dojo/_base/lang", // lang.trim
+	"dojo/query", // query
+	"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
+		return {
+			id: option.value,
+			value: option.value,
+			name: lang.trim(option.innerText || option.textContent || '')
+		};
+	}
+
+	return declare("dijit.form.DataList", MemoryStore, {
+		// summary:
+		//		Inefficient but small data store specialized for inlined data via OPTION tags
+		//
+		// description:
+		//		Provides a store for inlined data like:
+		//
+		//	|	<datalist>
+		//	|		<option value="AL">Alabama</option>
+		//	|		...
+
+		constructor: function(/*Object?*/ params, /*DomNode|String*/ srcNodeRef){
+			// store pointer to original DOM tree
+			this.domNode = dom.byId(srcNodeRef);
+
+			lang.mixin(this, params);
+			if(this.id){
+				registry.add(this); // add to registry so it can be easily found by id
+			}
+			this.domNode.style.display = "none";
+
+			this.inherited(arguments, [{
+				data: query("option", this.domNode).map(toItem)
+			}]);
+		},
+
+		destroy: function(){
+			registry.remove(this.id);
+		},
+
+		fetchSelectedItem: function(){
+			// summary:
+			//		Get the option marked as selected, like `<option selected>`.
+			//		Not part of dojo.data API.
+			var option = query("> option[selected]", this.domNode)[0] || query("> option", this.domNode)[0];
+			return option && toItem(option);
+		}
+	});
+});
diff --git a/dijit/form/DateTextBox.js b/dijit/form/DateTextBox.js
index b6da6f3..cd30a67 100644
--- a/dijit/form/DateTextBox.js
+++ b/dijit/form/DateTextBox.js
@@ -1,9 +1,21 @@
-define("dijit/form/DateTextBox", ["dojo", "dijit", "dijit/Calendar", "dijit/form/_DateTimeTextBox"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"../Calendar",
+	"./_DateTimeTextBox"
+], function(declare, Calendar, _DateTimeTextBox){
 
-dojo.declare(
-	"dijit.form.DateTextBox",
-	dijit.form._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
 		//
@@ -11,20 +23,16 @@ dojo.declare(
 		// |	new dijit.form.DateTextBox({value: new Date(2009, 0, 20)})
 		//
 		//		Example:
-		// |	<input dojotype='dijit.form.DateTextBox' value='2009-01-20'>
+		// |	<input data-dojo-type='dijit.form.DateTextBox' value='2009-01-20'>
 
 		baseClass: "dijitTextBox dijitComboBox dijitDateTextBox",
-		popupClass: "dijit.Calendar",
+		popupClass: Calendar,
 		_selector: "date",
 
 		// 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 `dojo.date.stamp.fromISOString`.
+		//		If specified in markup, use the format specified in `stamp.fromISOString`.
 		//		set("value", ...) accepts either a Date object or a string.
 		value: new Date("")	// value.toString()="NaN"
-	}
-);
-
-
-return dijit.form.DateTextBox;
+	});
 });
diff --git a/dijit/form/DropDownButton.js b/dijit/form/DropDownButton.js
index 2580ffc..4561874 100644
--- a/dijit/form/DropDownButton.js
+++ b/dijit/form/DropDownButton.js
@@ -1,6 +1,105 @@
-define("dijit/form/DropDownButton", ["dojo", "dijit", "dijit/form/Button"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/_base/lang",	// hitch
+	"dojo/query", // query
+	"../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
+// 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().
+		//
+		// 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);
+		}
+
+		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;
+	}
+});
 
-return dijit.form.DropDownButton;
 });
diff --git a/dijit/form/FilteringSelect.js b/dijit/form/FilteringSelect.js
index 749babc..2a687b6 100644
--- a/dijit/form/FilteringSelect.js
+++ b/dijit/form/FilteringSelect.js
@@ -1,9 +1,24 @@
-define("dijit/form/FilteringSelect", ["dojo", "dijit", "dijit/form/ComboBox"], function(dojo, dijit) {
-
-dojo.declare(
-	"dijit.form.FilteringSelect",
-	[dijit.form.MappedTextBox, dijit.form.ComboBoxMixin],
-	{
+define([
+	"dojo/data/util/filter", // filter.patternToRegExp
+	"dojo/_base/declare", // declare
+	"dojo/_base/Deferred", // Deferred.when
+	"dojo/_base/lang", // lang.mixin
+	"./MappedTextBox",
+	"./ComboBoxMixin"
+], function(filter, declare, Deferred, lang, MappedTextBox, ComboBoxMixin){
+
+/*=====
+	var MappedTextBox = dijit.form.MappedTextBox;
+	var ComboBoxMixin = dijit.form.ComboBoxMixin;
+=====*/
+
+	// module:
+	//		dijit/form/FilteringSelect
+	// summary:
+	//		An enhanced version of the HTML SELECT tag, populated dynamically
+
+
+	return declare("dijit.form.FilteringSelect", [MappedTextBox, ComboBoxMixin], {
 		// summary:
 		//		An enhanced version of the HTML SELECT tag, populated dynamically
 		//
@@ -53,39 +68,37 @@ dojo.declare(
 
 		_callbackSetLabel: function(
 						/*Array*/ result,
-						/*Object*/ dataObject,
+						/*Object*/ query,
+						/*Object*/ options,
 						/*Boolean?*/ priorityChange){
 			// summary:
-			//		Callback from dojo.data after lookup of user entered value finishes
+			//		Callback from dojo.store after lookup of user entered value finishes
 
 			// setValue does a synchronous lookup,
 			// so it calls _callbackSetLabel directly,
 			// and so does not pass dataObject
 			// still need to test against _lastQuery in case it came too late
-			if((dataObject && dataObject.query[this.searchAttr] != this._lastQuery) || (!dataObject && result.length && this.store.getIdentity(result[0]) != this._lastQuery)){
+			if((query && query[this.searchAttr] !== this._lastQuery) || (!query && result.length && this.store.getIdentity(result[0]) != this._lastQuery)){
 				return;
 			}
 			if(!result.length){
 				//#3268: don't modify display value on bad input
 				//#3285: change CSS to indicate error
-				this.valueNode.value = "";
-				dijit.form.TextBox.superclass._setValueAttr.call(this, "", priorityChange || (priorityChange === undefined && !this._focused));
-				this._set("item", null);
-				this.validate(this._focused);
+				this.set("value", '', priorityChange || (priorityChange === undefined && !this.focused), this.textbox.value, null);
 			}else{
 				this.set('item', result[0], priorityChange);
 			}
 		},
 
-		_openResultList: function(/*Object*/ results, /*Object*/ dataObject){
+		_openResultList: function(/*Object*/ results, /*Object*/ query, /*Object*/ options){
 			// Callback when a data store query completes.
 			// Overrides ComboBox._openResultList()
 
 			// #3285: tap into search callback to see if user's query resembles a match
-			if(dataObject.query[this.searchAttr] != this._lastQuery){
+			if(query[this.searchAttr] !== this._lastQuery){
 				return;
 			}
-			dijit.form.ComboBoxMixin.prototype._openResultList.apply(this, arguments);
+			this.inherited(arguments);
 
 			if(this.item === undefined){ // item == undefined for keyboard search
 				// If the search returned no items that means that the user typed
@@ -109,28 +122,32 @@ dojo.declare(
 			return "value";
 		},
 
-		_setValueAttr: function(/*String*/ value, /*Boolean?*/ priorityChange){
+		_setValueAttr: function(/*String*/ value, /*Boolean?*/ priorityChange, /*String?*/ displayedValue, /*item?*/ item){
 			// summary:
 			//		Hook so set('value', value) works.
 			// description:
 			//		Sets the value of the select.
 			//		Also sets the label to the corresponding value by reverse lookup.
 			if(!this._onChangeActive){ priorityChange = null; }
-			this._lastQuery = value;
-
-			if(value === null || value === ''){
-				this._setDisplayedValueAttr('', priorityChange);
-				return;
-			}
 
-			//#3347: fetchItemByIdentity if no keyAttr specified
-			var self = this;
-			this.store.fetchItemByIdentity({
-				identity: value,
-				onItem: function(item){
-					self._callbackSetLabel(item? [item] : [], undefined, priorityChange);
+			if(item === undefined){
+				if(value === null || value === ''){
+					value = '';
+					if(!lang.isString(displayedValue)){
+						this._setDisplayedValueAttr(displayedValue||'', priorityChange);
+						return;
+					}
 				}
-			});
+
+				var self = this;
+				this._lastQuery = value;
+				Deferred.when(this.store.get(value), function(item){
+					self._callbackSetLabel(item? [item] : [], undefined, undefined, priorityChange);
+				});
+			}else{
+				this.valueNode.value = value;
+				this.inherited(arguments);
+			}
 		},
 
 		_setItemAttr: function(/*item*/ item, /*Boolean?*/ priorityChange, /*String?*/ displayedValue){
@@ -143,7 +160,6 @@ dojo.declare(
 			// tags:
 			//		private
 			this.inherited(arguments);
-			this.valueNode.value = this.value;
 			this._lastDisplayedValue = this.textbox.value;
 		},
 
@@ -175,9 +191,22 @@ dojo.declare(
 			// Note that if there's a custom labelFunc() this code
 			if(this.store){
 				this.closeDropDown();
-				var query = dojo.clone(this.query); // #6196: populate query with user-specifics
-				// escape meta characters of dojo.data.util.filter.patternToRegExp().
-				this._lastQuery = query[this.searchAttr] = this._getDisplayQueryString(label);
+				var query = lang.clone(this.query); // #6196: populate query with user-specifics
+
+				// Generate query
+				var qs = this._getDisplayQueryString(label), 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;
+
 				// If the label is not valid, the callback will never set it,
 				// so the last valid value will get the warning textbox.   Set the
 				// textbox value now so that the impending warning will make
@@ -186,33 +215,26 @@ dojo.declare(
 				this._lastDisplayedValue = label;
 				this._set("displayedValue", label);	// for watch("displayedValue") notification
 				var _this = this;
-				var fetch = {
-					query: query,
-					queryOptions: {
-						ignoreCase: this.ignoreCase,
-						deep: true
-					},
-					onComplete: function(result, dataObject){
-						_this._fetchHandle = null;
-						dojo.hitch(_this, "_callbackSetLabel")(result, dataObject, priorityChange);
-					},
-					onError: function(errText){
-						_this._fetchHandle = null;
-						console.error('dijit.form.FilteringSelect: ' + errText);
-						dojo.hitch(_this, "_callbackSetLabel")([], undefined, false);
-					}
+				var options = {
+					ignoreCase: this.ignoreCase,
+					deep: true
 				};
-				dojo.mixin(fetch, this.fetchProperties);
-				this._fetchHandle = this.store.fetch(fetch);
+				lang.mixin(options, this.fetchProperties);
+				this._fetchHandle = this.store.query(query, options);
+				Deferred.when(this._fetchHandle, function(result){
+					_this._fetchHandle = null;
+					_this._callbackSetLabel(result || [], query, options, priorityChange);
+				}, function(err){
+					_this._fetchHandle = null;
+					if(!_this._cancelingQuery){	// don't treat canceled query as an error
+						console.error('dijit.form.FilteringSelect: ' + err.toString());
+					}
+				});
 			}
 		},
 
 		undo: function(){
 			this.set('displayedValue', this._lastDisplayedValue);
 		}
-	}
-);
-
-
-return dijit.form.FilteringSelect;
+	});
 });
diff --git a/dijit/form/Form.js b/dijit/form/Form.js
index 87a5156..ca9266b 100644
--- a/dijit/form/Form.js
+++ b/dijit/form/Form.js
@@ -1,14 +1,34 @@
-define("dijit/form/Form", ["dojo", "dijit", "dijit/_Widget", "dijit/_Templated", "dijit/form/_FormMixin", "dijit/layout/_ContentPaneResizeMixin"], function(dojo, dijit) {
-
-dojo.declare(
-	"dijit.form.Form",
-	[dijit._Widget, dijit._Templated, dijit.form._FormMixin, dijit.layout._ContentPaneResizeMixin],
-	{
+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")
+	"../_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;
+=====*/
+
+	// module:
+	//		dijit/form/Form
+	// summary:
+	//		Widget corresponding to HTML form tag, for validation and serialization
+
+
+	return declare("dijit.form.Form", [_Widget, _TemplatedMixin, _FormMixin, _ContentPaneResizeMixin], {
 		// summary:
 		//		Widget corresponding to HTML form tag, for validation and serialization
 		//
 		// example:
-		//	|	<form dojoType="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"};
@@ -46,25 +66,16 @@ dojo.declare(
 		//		Target frame for the document to be opened in.
 		target: "",
 
-		templateString: "<form dojoAttachPoint='containerNode' dojoAttachEvent='onreset:_onReset,onsubmit:_onSubmit' ${!nameAttrSetting}></form>",
-
-		attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
-			action: "",
-			method: "",
-			encType: "",
-			"accept-charset": "",
-			accept: "",
-			target: ""
-		}),
+		templateString: "<form data-dojo-attach-point='containerNode' data-dojo-attach-event='onreset:_onReset,onsubmit:_onSubmit' ${!nameAttrSetting}></form>",
 
 		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 attributeMap to set the name due to IE limitations, see #8660
+			// Unfortunately we can't use _setNameAttr to set the name due to IE limitations, see #8660
 			this.nameAttrSetting = this.name ? ("name='" + this.name + "'") : "";
 			this.inherited(arguments);
 		},
 
-		execute: function(/*Object*/ formContents){
+		execute: function(/*Object*/ /*===== formContents =====*/){
 			// summary:
 			//		Deprecated: use submit()
 			// tags:
@@ -80,20 +91,8 @@ dojo.declare(
 
 		_setEncTypeAttr: function(/*String*/ value){
 			this.encType = value;
-			dojo.attr(this.domNode, "encType", value);
-			if(dojo.isIE){ this.domNode.encoding = value; }
-		},
-
-		postCreate: function(){
-			// IE tries to hide encType
-			// TODO: remove in 2.0, no longer necessary with data-dojo-params
-			if(dojo.isIE && this.srcNodeRef && this.srcNodeRef.attributes){
-				var item = this.srcNodeRef.attributes.getNamedItem('encType');
-				if(item && !item.specified && (typeof item.value == "string")){
-					this.set('encType', item.value);
-				}
-			}
-			this.inherited(arguments);
+			domAttr.set(this.domNode, "encType", value);
+			if(has("ie")){ this.domNode.encoding = value; }
 		},
 
 		reset: function(/*Event?*/ e){
@@ -117,7 +116,7 @@ dojo.declare(
 			}
 		},
 
-		onReset: function(/*Event?*/ e){
+		onReset: function(/*Event?*/ /*===== e =====*/){
 			// summary:
 			//		Callback when user resets the form. This method is intended
 			//		to be over-ridden. When the `reset` method is called
@@ -130,24 +129,24 @@ dojo.declare(
 
 		_onReset: function(e){
 			this.reset(e);
-			dojo.stopEvent(e);
+			event.stop(e);
 			return false;
 		},
 
 		_onSubmit: function(e){
-			var fp = dijit.form.Form.prototype;
+			var fp = this.constructor.prototype;
 			// TODO: remove this if statement beginning with 2.0
 			if(this.execute != fp.execute || this.onExecute != fp.onExecute){
-				dojo.deprecated("dijit.form.Form:execute()/onExecute() are deprecated. Use onSubmit() instead.", "", "2.0");
+				kernel.deprecated("dijit.form.Form:execute()/onExecute() are deprecated. Use onSubmit() instead.", "", "2.0");
 				this.onExecute();
 				this.execute(this.getValues());
 			}
 			if(this.onSubmit(e) === false){ // only exactly false stops submit
-				dojo.stopEvent(e);
+				event.stop(e);
 			}
 		},
 
-		onSubmit: function(/*Event?*/ e){
+		onSubmit: function(/*Event?*/ /*===== e =====*/){
 			// summary:
 			//		Callback when user submits the form.
 			// description:
@@ -169,9 +168,5 @@ dojo.declare(
 				this.containerNode.submit();
 			}
 		}
-	}
-);
-
-
-return dijit.form.Form;
+	});
 });
diff --git a/dijit/form/HorizontalRule.js b/dijit/form/HorizontalRule.js
index 89db758..6a1a391 100644
--- a/dijit/form/HorizontalRule.js
+++ b/dijit/form/HorizontalRule.js
@@ -1,7 +1,21 @@
-define("dijit/form/HorizontalRule", ["dojo", "dijit", "dijit/_Widget", "dijit/_Templated"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare",	// declare
+	"../_Widget",
+	"../_TemplatedMixin"
+], function(declare, _Widget, _TemplatedMixin){
 
-dojo.declare("dijit.form.HorizontalRule", [dijit._Widget, dijit._Templated],
-{
+/*=====
+	var _Widget = dijit._Widget;
+	var _TemplatedMixin = dijit._TemplatedMixin;
+=====*/
+
+// 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`
 
@@ -24,7 +38,7 @@ dojo.declare("dijit.form.HorizontalRule", [dijit._Widget, dijit._Templated],
 	_positionSuffix: '%;',
 	_suffix: '"></div>',
 
-	_genHTML: function(pos, ndx){
+	_genHTML: function(pos){
 		return this._positionPrefix + pos + this._positionSuffix + this.ruleStyle + this._suffix;
 	},
 
@@ -59,6 +73,4 @@ dojo.declare("dijit.form.HorizontalRule", [dijit._Widget, dijit._Templated],
 	}
 });
 
-
-return dijit.form.HorizontalRule;
 });
diff --git a/dijit/form/HorizontalRuleLabels.js b/dijit/form/HorizontalRuleLabels.js
index db71049..dc3da11 100644
--- a/dijit/form/HorizontalRuleLabels.js
+++ b/dijit/form/HorizontalRuleLabels.js
@@ -1,7 +1,20 @@
-define("dijit/form/HorizontalRuleLabels", ["dojo", "dijit", "dijit/form/HorizontalRule"], function(dojo, dijit) {
-
-dojo.declare("dijit.form.HorizontalRuleLabels", dijit.form.HorizontalRule,
-{
+define([
+	"dojo/_base/declare",	// declare
+	"dojo/number", // number.format
+	"dojo/query", // query
+	"./HorizontalRule"
+], function(declare, number, query, HorizontalRule){
+
+/*=====
+	var HorizontalRule = dijit.form.HorizontalRule;
+=====*/
+
+// module:
+//		dijit/form/HorizontalRuleLabels
+// summary:
+//		Labels for `dijit.form.HorizontalSlider`
+
+return declare("dijit.form.HorizontalRuleLabels", HorizontalRule, {
 	// summary:
 	//		Labels for `dijit.form.HorizontalSlider`
 
@@ -59,7 +72,7 @@ dojo.declare("dijit.form.HorizontalRuleLabels", dijit.form.HorizontalRule,
 		var labels = this.labels;
 		if(!labels.length){
 			// for markup creation, labels are specified as child elements
-			labels = dojo.query("> li", this.srcNodeRef).map(function(node){
+			labels = query("> li", this.srcNodeRef).map(function(node){
 				return String(node.innerHTML);
 			});
 		}
@@ -69,7 +82,7 @@ dojo.declare("dijit.form.HorizontalRuleLabels", dijit.form.HorizontalRule,
 			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)) ? '' : dojo.number.format(start, this.constraints));
+				labels.push((i < this.numericMargin || i >= (this.count-this.numericMargin)) ? '' : number.format(start, this.constraints));
 				start += inc;
 			}
 		}
@@ -83,6 +96,4 @@ dojo.declare("dijit.form.HorizontalRuleLabels", dijit.form.HorizontalRule,
 	}
 });
 
-
-return dijit.form.HorizontalRuleLabels;
 });
diff --git a/dijit/form/HorizontalSlider.js b/dijit/form/HorizontalSlider.js
index 19e661c..72fd776 100644
--- a/dijit/form/HorizontalSlider.js
+++ b/dijit/form/HorizontalSlider.js
@@ -1,13 +1,65 @@
-define("dijit/form/HorizontalSlider", ["dojo", "dijit", "text!dijit/form/templates/HorizontalSlider.html", "dijit/form/_FormWidget", "dijit/_Container", "dojo/dnd/move", "dijit/form/Button", "dojo/number"], function(dojo, dijit) {
+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/dnd/Moveable", // Moveable
+	"dojo/dnd/Mover", // Mover Mover.prototype.destroy.apply
+	"dojo/query", // query
+	"../registry", // registry.findWidgets
+	"../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();
+		}
+		var pixelValue = e[widget._mousePixelCoord] - abspos[widget._startingPixelCoord];
+		widget._setPixelValue_(widget._isReversed_ ? (abspos[widget._pixelCount]-pixelValue) : pixelValue, abspos[widget._pixelCount], false);
+	},
 
-dojo.declare(
-	"dijit.form.HorizontalSlider",
-	[dijit.form._FormValueWidget, dijit._Container],
-{
+	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: dojo.cache('dijit.form','templates/HorizontalSlider.html'),
+	templateString: template,
 
 	// Overrides FormValueWidget.value to indicate numeric value
 	value: 0,
@@ -51,14 +103,10 @@ dojo.declare(
 	// 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: dijit.defaultDuration,
-
-	// Flag to _Templated  (TODO: why is this here?  I see no widgets in the template.)
-	widgetsInTemplate: true,
+	slideDuration: registry.defaultDuration,
 
-	attributeMap: dojo.delegate(dijit.form._FormWidget.prototype.attributeMap, {
-		id: ""
-	}),
+	// Map widget attributes to DOMNode attributes.
+	_setIdAttr: "",		// Override _FormWidget which sends id to focusNode
 
 	baseClass: "dijitSlider",
 
@@ -72,7 +120,6 @@ dojo.declare(
 	_mousePixelCoord: "pageX",
 	_pixelCount: "w",
 	_startingPixelCoord: "x",
-	_startingPixelCount: "l",
 	_handleOffsetCoord: "left",
 	_progressPixelSize: "width",
 
@@ -84,38 +131,38 @@ dojo.declare(
 	_onKeyPress: function(/*Event*/ e){
 		if(this.disabled || this.readOnly || e.altKey || e.ctrlKey || e.metaKey){ return; }
 		switch(e.charOrCode){
-			case dojo.keys.HOME:
+			case keys.HOME:
 				this._setValueAttr(this.minimum, false);
 				break;
-			case dojo.keys.END:
+			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()) ? dojo.keys.RIGHT_ARROW : dojo.keys.LEFT_ARROW):
-			case (this._descending === false ? dojo.keys.DOWN_ARROW : dojo.keys.UP_ARROW):
-			case (this._descending === false ? dojo.keys.PAGE_DOWN : dojo.keys.PAGE_UP):
+			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()) ? dojo.keys.LEFT_ARROW : dojo.keys.RIGHT_ARROW):
-			case (this._descending === false ? dojo.keys.UP_ARROW : dojo.keys.DOWN_ARROW):
-			case (this._descending === false ? dojo.keys.PAGE_UP : dojo.keys.PAGE_DOWN):
+			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;
 		}
-		dojo.stopEvent(e);
+		event.stop(e);
 	},
 
 	_onHandleClick: function(e){
 		if(this.disabled || this.readOnly){ return; }
-		if(!dojo.isIE){
+		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)
-			dijit.focus(this.sliderHandle);
+			focus.focus(this.sliderHandle);
 		}
-		dojo.stopEvent(e);
+		event.stop(e);
 	},
 
 	_isReversed: function(){
@@ -128,9 +175,9 @@ dojo.declare(
 
 	_onBarClick: function(e){
 		if(this.disabled || this.readOnly || !this.clickSelect){ return; }
-		dijit.focus(this.sliderHandle);
-		dojo.stopEvent(e);
-		var abspos = dojo.position(this.sliderBarContainer, true);
+		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);
@@ -138,13 +185,12 @@ dojo.declare(
 
 	_setPixelValue: function(/*Number*/ pixelValue, /*Number*/ maxPixels, /*Boolean?*/ priorityChange){
 		if(this.disabled || this.readOnly){ return; }
-		pixelValue = pixelValue < 0 ? 0 : maxPixels < pixelValue ? maxPixels : pixelValue;
 		var count = this.discreteValues;
 		if(count <= 1 || count == Infinity){ count = maxPixels; }
 		count--;
 		var pixelsPerValue = maxPixels / count;
 		var wholeIncrements = Math.round(pixelValue / pixelsPerValue);
-		this._setValueAttr((this.maximum-this.minimum)*wholeIncrements/count + this.minimum, priorityChange);
+		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){
@@ -152,7 +198,7 @@ dojo.declare(
 		//		Hook so set('value', value) works.
 		this._set("value", value);
 		this.valueNode.value = value;
-		dijit.setWaiState(this.focusNode, "valuenow", 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;
@@ -169,11 +215,15 @@ dojo.declare(
 			if(duration == 0){ return; }
 			if(duration < 0){ duration = 0 - duration; }
 			props[this._progressPixelSize] = { start: start, end: percent*100, units:"%" };
-			this._inProgressAnim = dojo.animateProperty({ node: progressBar, duration: duration,
-				onAnimate: function(v){ remainingBar.style[_this._progressPixelSize] = (100-parseFloat(v[_this._progressPixelSize])) + "%"; },
-				onEnd: function(){ delete _this._inProgressAnim; },
+			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) + "%";
@@ -183,8 +233,8 @@ dojo.declare(
 
 	_bumpValue: function(signedChange, /*Boolean?*/ priorityChange){
 		if(this.disabled || this.readOnly){ return; }
-		var s = dojo.getComputedStyle(this.sliderBarContainer);
-		var c = dojo._getContentBox(this.sliderBarContainer, s);
+		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--;
@@ -213,7 +263,7 @@ dojo.declare(
 		//		Decrement slider
 		// tags:
 		//		private
-		this._bumpValue(e.charOrCode == dojo.keys.PAGE_DOWN ? -this.pageIncrement : -1);
+		this._bumpValue(e.charOrCode == keys.PAGE_DOWN ? -this.pageIncrement : -1);
 	},
 
 	increment: function(/*Event*/ e){
@@ -221,14 +271,14 @@ dojo.declare(
 		//		Increment slider
 		// tags:
 		//		private
-		this._bumpValue(e.charOrCode == dojo.keys.PAGE_UP ? this.pageIncrement : 1);
+		this._bumpValue(e.charOrCode == keys.PAGE_UP ? this.pageIncrement : 1);
 	},
 
 	_mouseWheeled: function(/*Event*/ evt){
 		// summary:
 		//		Event handler for mousewheel where supported
-		dojo.stopEvent(evt);
-		var janky = !dojo.isMozilla;
+		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
 	},
@@ -236,7 +286,7 @@ dojo.declare(
 	startup: function(){
 		if(this._started){ return; }
 
-		dojo.forEach(this.getChildren(), function(child){
+		array.forEach(this.getChildren(), function(child){
 			if(this[child.container] != this.containerNode){
 				this[child.container].appendChild(child.domNode);
 			}
@@ -261,32 +311,32 @@ dojo.declare(
 		}
 
 		// find any associated label element and add to slider focusnode.
-		var label = dojo.query('label[for="'+this.id+'"]');
+		var label = query('label[for="'+this.id+'"]');
 		if(label.length){
 			label[0].id = (this.id+"_label");
-			dijit.setWaiState(this.focusNode, "labelledby", label[0].id);
+			this.focusNode.setAttribute("aria-labelledby", label[0].id);
 		}
 
-		dijit.setWaiState(this.focusNode, "valuemin", this.minimum);
-		dijit.setWaiState(this.focusNode, "valuemax", this.maximum);
+		this.focusNode.setAttribute("aria-valuemin", this.minimum);
+		this.focusNode.setAttribute("aria-valuemax", this.maximum);
 	},
 
 	postCreate: function(){
 		this.inherited(arguments);
 
 		if(this.showButtons){
-			this._connects.push(dijit.typematic.addMouseListener(
+			this._connects.push(typematic.addMouseListener(
 				this.decrementButton, this, "_typematicCallback", 25, 500));
-			this._connects.push(dijit.typematic.addMouseListener(
+			this._connects.push(typematic.addMouseListener(
 				this.incrementButton, this, "_typematicCallback", 25, 500));
 		}
-		this.connect(this.domNode, !dojo.isMozilla ? "onmousewheel" : "DOMMouseScroll", "_mouseWheeled");
+		this.connect(this.domNode, !has("mozilla") ? "onmousewheel" : "DOMMouseScroll", "_mouseWheeled");
 
 		// define a custom constructor for a SliderMover that points back to me
-		var mover = dojo.declare(dijit.form._SliderMover, {
+		var mover = declare(_SliderMover, {
 			widget: this
 		});
-		this._movable = new dojo.dnd.Moveable(this.sliderHandle, {mover: mover});
+		this._movable = new Moveable(this.sliderHandle, {mover: mover});
 
 		this._layoutHackIE7();
 	},
@@ -296,35 +346,12 @@ dojo.declare(
 		if(this._inProgressAnim && this._inProgressAnim.status != "stopped"){
 			this._inProgressAnim.stop(true);
 		}
-		this._supportingWidgets = dijit.findWidgets(this.domNode); // tells destroy about pseudo-child widgets (ruler/labels)
+		this._supportingWidgets = registry.findWidgets(this.domNode); // tells destroy about pseudo-child widgets (ruler/labels)
 		this.inherited(arguments);
 	}
 });
 
-dojo.declare("dijit.form._SliderMover",
-	dojo.dnd.Mover,
-{
-	onMouseMove: function(e){
-		var widget = this.widget;
-		var abspos = widget._abspos;
-		if(!abspos){
-			abspos = widget._abspos = dojo.position(widget.sliderBarContainer, true);
-			widget._setPixelValue_ = dojo.hitch(widget, "_setPixelValue");
-			widget._isReversed_ = widget._isReversed();
-		}
-		var coordEvent = e.touches ? e.touches[0] : e, // if multitouch take first touch for coords
-			pixelValue = coordEvent[widget._mousePixelCoord] - abspos[widget._startingPixelCoord];
-		widget._setPixelValue_(widget._isReversed_ ? (abspos[widget._pixelCount]-pixelValue) : pixelValue, abspos[widget._pixelCount], false);
-	},
-
-	destroy: function(e){
-		dojo.dnd.Mover.prototype.destroy.apply(this, arguments);
-		var widget = this.widget;
-		widget._abspos = null;
-		widget._setValueAttr(widget.value, true);
-	}
-});
-
+HorizontalSlider._Mover = _SliderMover;	// for monkey patching
 
-return dijit.form.HorizontalSlider;
+return HorizontalSlider;
 });
diff --git a/dijit/form/MappedTextBox.js b/dijit/form/MappedTextBox.js
index 16e5fbf..e528d87 100644
--- a/dijit/form/MappedTextBox.js
+++ b/dijit/form/MappedTextBox.js
@@ -1,6 +1,89 @@
-define("dijit/form/MappedTextBox", ["dojo", "dijit", "dijit/form/ValidationTextBox"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/dom-construct", // domConstruct.place
+	"./ValidationTextBox"
+], function(declare, domConstruct, ValidationTextBox){
 
+/*=====
+	var ValidationTextBox = dijit.form.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 dijit.form.MappedTextBox;
+	return declare("dijit.form.MappedTextBox", ValidationTextBox, {
+		// 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.
+		// 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
+		//		locale-neutral.
+		// tags:
+		//		protected
+
+		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
+			this.nameAttrSetting = "";
+		},
+
+		// Override default behavior to assign name to focusNode
+		_setNameAttr: null,
+
+		serialize: function(val /*=====, options =====*/){
+			// summary:
+			//		Overridable function used to convert the get('value') result to a canonical
+			//		(non-localized) string.  For example, will print dates in ISO format, and
+			//		numbers the same way as they are represented in javascript.
+			// val: anything
+			// options: Object?
+			// tags:
+			//		protected extension
+			return val.toString ? val.toString() : ""; // String
+		},
+
+		toString: function(){
+			// summary:
+			//		Returns widget as a printable string using the widget's value
+			// tags:
+			//		protected
+			var val = this.filter(this.get('value')); // call filter in case value is nonstring and filter has been customized
+			return val != null ? (typeof val == "string" ? val : this.serialize(val, this.constraints)) : ""; // String
+		},
+
+		validate: function(){
+			// Overrides `dijit.form.TextBox.validate`
+			this.valueNode.value = this.toString();
+			return this.inherited(arguments);
+		},
+
+		buildRendering: function(){
+			// 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");
+		},
+
+		reset: function(){
+			// 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 ed36a72..89072bf 100644
--- a/dijit/form/MultiSelect.js
+++ b/dijit/form/MultiSelect.js
@@ -1,6 +1,22 @@
-define("dijit/form/MultiSelect", ["dojo", "dijit", "dijit/form/_FormWidget"], function(dojo, dijit) {
-
-dojo.declare("dijit.form.MultiSelect", dijit.form._FormValueWidget, {
+define([
+	"dojo/_base/array", // array.indexOf, array.map
+	"dojo/_base/declare", // declare
+	"dojo/dom-geometry", // domGeometry.setMarginBox
+	"dojo/query", // query
+	"./_FormValueWidget"
+], function(array, declare, domGeometry, query, _FormValueWidget){
+
+/*=====
+	var _FormValueWidget = dijit.form._FormValueWidget;
+=====*/
+
+// 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.
@@ -11,20 +27,7 @@ dojo.declare("dijit.form.MultiSelect", dijit.form._FormValueWidget, {
 	//		set the size via style="..." or CSS class names instead.
 	size: 7,
 
-	templateString: "<select multiple='true' ${!nameAttrSetting} dojoAttachPoint='containerNode,focusNode' dojoAttachEvent='onchange: _onChange'></select>",
-
-	attributeMap: dojo.delegate(dijit.form._FormWidget.prototype.attributeMap, {
-		size: "focusNode"
-	}),
-
-	reset: function(){
-		// summary:
-		//		Reset the widget's value to what it was at initialization time
-
-		// TODO: once we inherit from FormValueWidget this won't be needed
-		this._hasBeenBlurred = false;
-		this._setValueAttr(this._resetValue, true);
-	},
+	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:
@@ -46,12 +49,13 @@ dojo.declare("dijit.form.MultiSelect", dijit.form._FormValueWidget, {
 			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 dojo.query("option",this.containerNode).filter(function(n){
+		return query("option",this.containerNode).filter(function(n){
 			return n.selected; // Boolean
 		}); // dojo.NodeList
 	},
@@ -61,50 +65,54 @@ dojo.declare("dijit.form.MultiSelect", dijit.form._FormValueWidget, {
 		//		Hook so get('value') works.
 		// description:
 		//		Returns an array of the selected options' values.
-		return this.getSelected().map(function(n){
+
+		// 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){
+	_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
-		dojo.query("option",this.containerNode).forEach(function(n){
-			n.selected = (dojo.indexOf(values,n.value) != -1);
+		query("option",this.containerNode).forEach(function(n){
+			n.selected = (array.indexOf(values,n.value) != -1);
 		});
+		this.inherited(arguments);
 	},
 
-	invertSelection: function(onChange){
+	invertSelection: function(/*Boolean?*/ onChange){
 		// summary:
 		//		Invert the selection
 		// onChange: Boolean
-		//		If null, onChange is not fired.
-		dojo.query("option",this.containerNode).forEach(function(n){
-			n.selected = !n.selected;
+		//		If false, onChange is not fired.
+		var val = [];
+		query("option",this.containerNode).forEach(function(n){
+			if(!n.selected){ val.push(n.value); }
 		});
-		this._handleOnChange(this.get('value'), onChange == true);
+		this._setValueAttr(val, !(onChange === false || onChange == null));
 	},
 
-	_onChange: function(/*Event*/ e){
+	_onChange: function(/*Event*/){
 		this._handleOnChange(this.get('value'), true);
 	},
 
 	// for layout widgets:
 	resize: function(/*Object*/ size){
 		if(size){
-			dojo.marginBox(this.domNode, size);
+			domGeometry.setMarginBox(this.domNode, size);
 		}
 	},
 
 	postCreate: function(){
-		this._onChange();
+		this._set('value', this.get('value'));
+		this.inherited(arguments);
 	}
 });
 
-
-return dijit.form.MultiSelect;
 });
diff --git a/dijit/form/NumberSpinner.js b/dijit/form/NumberSpinner.js
index 7fd3e12..9cbf770 100644
--- a/dijit/form/NumberSpinner.js
+++ b/dijit/form/NumberSpinner.js
@@ -1,8 +1,23 @@
-define("dijit/form/NumberSpinner", ["dojo", "dijit", "dijit/form/_Spinner", "dijit/form/NumberTextBox"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/_base/event", // event.stop
+	"dojo/keys", // keys.END keys.HOME
+	"./_Spinner",
+	"./NumberTextBox"
+], function(declare, event, keys, _Spinner, NumberTextBox){
 
-dojo.declare("dijit.form.NumberSpinner",
-	[dijit.form._Spinner, dijit.form.NumberTextBoxMixin],
-	{
+/*=====
+	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
+
+
+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
 	//
@@ -44,18 +59,16 @@ dojo.declare("dijit.form.NumberSpinner",
 	},
 
 	_onKeyPress: function(e){
-		if((e.charOrCode == dojo.keys.HOME || e.charOrCode == dojo.keys.END) && !(e.ctrlKey || e.altKey || e.metaKey)
+		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 == dojo.keys.HOME ? "min" : "max")];
+			var value = this.constraints[(e.charOrCode == keys.HOME ? "min" : "max")];
 			if(typeof value == "number"){
 				this._setValueAttr(value, false);
 			}
 			// eat home or end key whether we change the value or not
-			dojo.stopEvent(e);
+			event.stop(e);
 		}
 	}
 });
 
-
-return dijit.form.NumberSpinner;
 });
diff --git a/dijit/form/NumberTextBox.js b/dijit/form/NumberTextBox.js
index ea7a005..f0c4a6b 100644
--- a/dijit/form/NumberTextBox.js
+++ b/dijit/form/NumberTextBox.js
@@ -1,27 +1,40 @@
-define("dijit/form/NumberTextBox", ["dojo", "dijit", "dijit/form/ValidationTextBox", "dojo/number"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/_base/lang", // lang.hitch lang.mixin
+	"dojo/number", // number._realNumberRegexp number.format number.parse number.regexp
+	"./RangeBoundTextBox"
+], function(declare, lang, number, RangeBoundTextBox){
 
 /*=====
-dojo.declare(
-	"dijit.form.NumberTextBox.__Constraints",
-	[dijit.form.RangeBoundTextBox.__Constraints, dojo.number.__FormatOptions, dojo.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 RangeBoundTextBox = dijit.form.RangeBoundTextBox;
 =====*/
 
-dojo.declare("dijit.form.NumberTextBoxMixin",
-	null,
-	{
+	// 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:
 		//		A mixin for all number textboxes
 		// tags:
@@ -29,7 +42,7 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 
 		// Override ValidationTextBox.regExpGen().... we use a reg-ex generating function rather
 		// than a straight regexp to deal with locale (plus formatting options too?)
-		regExpGen: dojo.number.regexp,
+		regExpGen: number.regexp,
 
 		/*=====
 		// constraints: dijit.form.NumberTextBox.__Constraints
@@ -71,7 +84,12 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 			return "12345";		// String
 		},
 		 =====*/
-		_formatter: dojo.number.format,
+		_formatter: number.format,
+
+		postMixInProperties: function(){
+			this.inherited(arguments);
+			this._set("type", "text"); // in case type="number" was specified which messes up parse/format
+		},
 
 		_setConstraintsAttr: function(/*Object*/ constraints){
 			var places = typeof constraints.places == "number"? constraints.places : 0;
@@ -113,8 +131,8 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 			if(!("rangeCheck" in this && this.rangeCheck(value, constraints)) && constraints.exponent !== false && /\de[-+]?\d/i.test(formattedValue)){
 				return formattedValue;
 			}
-			if(this.editOptions && this._focused){
-				constraints = dojo.mixin({}, constraints, this.editOptions);
+			if(this.editOptions && this.focused){
+				constraints = lang.mixin({}, constraints, this.editOptions);
 			}
 			return this._formatter(value, constraints);
 		},
@@ -133,16 +151,16 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 			return 123.45;		// Number
 		},
 		=====*/
-		_parser: dojo.number.parse,
+		_parser: number.parse,
 
-		parse: function(/*String*/ value, /*dojo.number.__FormatOptions*/ constraints){
+		parse: function(/*String*/ value, /*number.__FormatOptions*/ constraints){
 			// summary:
-			//		Replacable function to convert a formatted string to a number value
+			//		Replaceable function to convert a formatted string to a number value
 			// tags:
 			//		protected extension
 
-			var v = this._parser(value, dojo.mixin({}, constraints, (this.editOptions && this._focused) ? this.editOptions : {}));
-			if(this.editOptions && this._focused && isNaN(v)){
+			var v = this._parser(value, lang.mixin({}, constraints, (this.editOptions && this.focused) ? this.editOptions : {}));
+			if(this.editOptions && this.focused && isNaN(v)){
 				v = this._parser(value, constraints); // parse w/o editOptions: not technically needed but is nice for the user
 			}
 			return v;
@@ -172,7 +190,7 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 		},
 
 		_setBlurValue: function(){
-			var val = dojo.hitch(dojo.mixin({}, this, { _focused: true }), "get")('value'); // parse with editOptions
+			var val = lang.hitch(lang.mixin({}, this, { focused: true }), "get")('value'); // parse with editOptions
 			this._setValueAttr(val, true);
 		},
 
@@ -183,11 +201,11 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 				formattedValue = String(value);
 				if(typeof value == "number"){
 					if(isNaN(value)){ formattedValue = '' }
-					// check for exponential notation that dojo.number.format chokes on
+					// check for exponential notation that number.format chokes on
 					else if(("rangeCheck" in this && this.rangeCheck(value, this.constraints)) || this.constraints.exponent === false || !/\de[-+]?\d/i.test(formattedValue)){
-						formattedValue = undefined; // lets format comnpute a real string value
+						formattedValue = undefined; // lets format compute a real string value
 					}
-				}else if(!value){ // 0 processed in if branch above, ''|null|undefined flow thru here
+				}else if(!value){ // 0 processed in if branch above, ''|null|undefined flows through here
 					formattedValue = '';
 					value = NaN;
 				}else{ // non-numeric values
@@ -200,7 +218,7 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 		_getValueAttr: function(){
 			// summary:
 			//		Hook so get('value') works.
-			//		Returns Number, NaN for '', or undefined for unparsable text
+			//		Returns Number, NaN for '', or undefined for unparseable text
 			var v = this.inherited(arguments); // returns Number for all values accepted by parse() or NaN for all other displayed values
 
 			// If the displayed value of the textbox is gibberish (ex: "hello world"), this.inherited() above
@@ -208,7 +226,7 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 			// 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("^"+dojo.number._realNumberRegexp(dojo.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.mixin({}, 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{
@@ -221,8 +239,8 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 
 		isValid: function(/*Boolean*/ isFocused){
 			// Overrides dijit.form.RangeBoundTextBox.isValid to check that the editing-mode value is valid since
-			// it may not be formatted according to the regExp vaidation rules
-			if(!this._focused || this._isEmpty(this.textbox.value)){
+			// it may not be formatted according to the regExp validation rules
+			if(!this.focused || this._isEmpty(this.textbox.value)){
 				return this.inherited(arguments);
 			}else{
 				var v = this.get('value');
@@ -237,12 +255,12 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 				}
 			}
 		}
-	}
-);
+	});
+/*=====
+	NumberTextBoxMixin = dijit.form.NumberTextBoxMixin;
+=====*/
 
-dojo.declare("dijit.form.NumberTextBox",
-	[dijit.form.RangeBoundTextBox,dijit.form.NumberTextBoxMixin],
-	{
+	var NumberTextBox = declare("dijit.form.NumberTextBox", [RangeBoundTextBox,NumberTextBoxMixin], {
 		// summary:
 		//		A TextBox for entering numbers, with formatting and range checking
 		// description:
@@ -260,9 +278,9 @@ dojo.declare("dijit.form.NumberTextBox",
 		//				allowed on input, and number of places displayed when blurred (see `constraints` parameter).
 
 		baseClass: "dijitTextBox dijitNumberTextBox"
-	}
-);
+	});
 
+	NumberTextBox.Mixin = NumberTextBoxMixin;	// for monkey patching
 
-return dijit.form.NumberTextBox;
+	return NumberTextBox;
 });
diff --git a/dijit/form/RadioButton.js b/dijit/form/RadioButton.js
index 0eedc17..ca7e499 100644
--- a/dijit/form/RadioButton.js
+++ b/dijit/form/RadioButton.js
@@ -1,7 +1,23 @@
-define("dijit/form/RadioButton", ["dojo", "dijit", "dijit/form/CheckBox"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"./CheckBox",
+	"./_RadioButtonMixin"
+], function(declare, CheckBox, _RadioButtonMixin){
 
-// TODO: for 2.0, move the RadioButton code into this file
+/*=====
+	var CheckBox = dijit.form.CheckBox;
+	var _RadioButtonMixin = dijit.form._RadioButtonMixin;
+=====*/
 
+	// module:
+	//		dijit/form/RadioButton
+	// summary:
+	//		Radio button widget
 
-return dijit.form.RadioButton;
+	return declare("dijit.form.RadioButton", [CheckBox, _RadioButtonMixin], {
+		// summary:
+		// 		Same as an HTML radio, but with fancy styling.
+
+		baseClass: "dijitRadio"
+	});
 });
diff --git a/dijit/form/RangeBoundTextBox.js b/dijit/form/RangeBoundTextBox.js
index e27de43..274d608 100644
--- a/dijit/form/RangeBoundTextBox.js
+++ b/dijit/form/RangeBoundTextBox.js
@@ -1,6 +1,143 @@
-define("dijit/form/RangeBoundTextBox", ["dojo", "dijit", "dijit/form/ValidationTextBox"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/i18n", // i18n.getLocalization
+	"./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.
 
-return dijit.form.RangeBoundTextBox;
+	/*=====
+		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, {
+		// summary:
+		//		Base class for textbox form widgets which defines a range of valid values.
+
+		// rangeMessage: String
+		//		The message to display if value is out-of-range
+		rangeMessage: "",
+
+		/*=====
+		// constraints: 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:
+			//		protected
+			return	("min" in constraints? (this.compare(primitive,constraints.min) >= 0) : true) &&
+				("max" in constraints? (this.compare(primitive,constraints.max) <= 0) : true); // Boolean
+		},
+
+		isInRange: function(/*Boolean*/ /*===== isFocused =====*/){
+			// summary:
+			//		Tests if the value is in the min/max range specified in constraints
+			// tags:
+			//		protected
+			return this.rangeCheck(this.get('value'), this.constraints);
+		},
+
+		_isDefinitelyOutOfRange: function(){
+			// summary:
+			//		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("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;
+			}
+			if("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;
+			}
+			return isTooLittle || isTooMuch;
+		},
+
+		_isValidSubset: function(){
+			// summary:
+			//		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.
+			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
+			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
+				return this.rangeMessage; // String
+			}
+			return this.inherited(arguments);
+		},
+
+		postMixInProperties: function(){
+			this.inherited(arguments);
+			if(!this.rangeMessage){
+				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.
+		}
+	});
 });
diff --git a/dijit/form/Select.js b/dijit/form/Select.js
index 38e8884..e285a23 100644
--- a/dijit/form/Select.js
+++ b/dijit/form/Select.js
@@ -1,6 +1,42 @@
-define("dijit/form/Select", ["dojo", "dijit", "text!dijit/form/templates/Select.html", "dijit/form/_FormSelectWidget", "dijit/_HasDropDown", "dijit/Menu", "dijit/Tooltip", "i18n!dijit/form/nls/validate"], function(dojo, dijit) {
-
-dojo.declare("dijit.form._SelectMenu", dijit.Menu, {
+define([
+	"dojo/_base/array", // array.forEach
+	"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
+	"./_FormSelectWidget",
+	"../_HasDropDown",
+	"../Menu",
+	"../MenuItem",
+	"../MenuSeparator",
+	"../Tooltip",
+	"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(){
@@ -9,25 +45,25 @@ dojo.declare("dijit.form._SelectMenu", dijit.Menu, {
 		//		otherwise, we won't respond correctly to heights/overflows
 		this.inherited(arguments);
 		var o = (this.menuTableNode = this.domNode);
-		var n = (this.domNode = dojo.create("div", {style: {overflowX: "hidden", overflowY: "scroll"}}));
+		var n = (this.domNode = domConstruct.create("div", {style: {overflowX: "hidden", overflowY: "scroll"}}));
 		if(o.parentNode){
 			o.parentNode.replaceChild(n, o);
 		}
-		dojo.removeClass(o, "dijitMenuTable");
+		domClass.remove(o, "dijitMenuTable");
 		n.className = o.className + " dijitSelectMenu";
 		o.className = "dijitReset dijitMenuTable";
-		dijit.setWaiRole(o,"listbox");
-		dijit.setWaiRole(n,"presentation");
+		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
+		//		stop mousemove from selecting text on IE to be consistent with other browsers
 
 		this.inherited(arguments);
 
-		this.connect(this.domNode, "onmousemove", dojo.stopEvent);
+		this.connect(this.domNode, "onmousemove", event.stop);
 	},
 
 	resize: function(/*Object*/ mb){
@@ -40,7 +76,7 @@ dojo.declare("dijit.form._SelectMenu", dijit.Menu, {
 		// mb: Object
 		//		The margin box to set this dropdown to.
 		if(mb){
-			dojo.marginBox(this.domNode, 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
@@ -51,25 +87,21 @@ dojo.declare("dijit.form._SelectMenu", dijit.Menu, {
 	}
 });
 
-dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropDown], {
+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.
 
 	baseClass: "dijitSelect",
 
-	templateString: dojo.cache("dijit.form", "templates/Select.html"),
-
-	// attributeMap: Object
-	//		Add in our style to be applied to the focus node
-	attributeMap: dojo.mixin(dojo.clone(dijit.form._FormSelectWidget.prototype.attributeMap),{style:"tableNode"}),
+	templateString: template,
 
 	// required: Boolean
 	//		Can be true or false, default is false.
 	required: false,
 
-	// state: String
-	//		Shows current state (ie, validation result) of input (Normal, Warning, or Error)
+	// state: [readonly] String
+	//		"Incomplete" if this select is required but unset (i.e. blank value), "" otherwise
 	state: "",
 
 	// message: String
@@ -82,7 +114,7 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 
 	// emptyLabel: string
 	//		What to display in an "empty" dropdown
-	emptyLabel: " ",
+	emptyLabel: " ",	//  
 
 	// _isLoaded: Boolean
 	//		Whether or not we have been loaded
@@ -102,8 +134,8 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 			this.value = this.options[si >= 0 ? si : 0].value;
 		}
 		// Create the dropDown widget
-		this.dropDown = new dijit.form._SelectMenu({id: this.id + "_menu"});
-		dojo.addClass(this.dropDown.domNode, this.baseClass + "Menu");
+		this.dropDown = new _SelectMenu({id: this.id + "_menu"});
+		domClass.add(this.dropDown.domNode, this.baseClass + "Menu");
 	},
 
 	_getMenuItemForOption: function(/*dijit.form.__SelectOption*/ option){
@@ -112,17 +144,17 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 		//		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 dijit.MenuSeparator();
+			return new MenuSeparator();
 		}else{
 			// Just a regular menu option
-			var click = dojo.hitch(this, "_setValueAttr", option);
-			var item = new dijit.MenuItem({
+			var click = lang.hitch(this, "_setValueAttr", option);
+			var item = new MenuItem({
 				option: option,
 				label: option.label || this.emptyLabel,
 				onClick: click,
 				disabled: option.disabled || false
 			});
-			dijit.setWaiRole(item.focusNode, "listitem");
+			item.focusNode.setAttribute("role", "listitem");
 			return item;
 		}
 	},
@@ -164,8 +196,8 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 			}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)
-				dojo.forEach(this._getChildren(), function(child){ child.destroyRecursive(); });
-				var item = new dijit.MenuItem({label: " "});
+				array.forEach(this._getChildren(), function(child){ child.destroyRecursive(); });
+				var item = new MenuItem({label: " "});
 				this.dropDown.addChild(item);
 			}
 		}else{
@@ -183,7 +215,19 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 
 	_setValueAttr: function(value){
 		this.inherited(arguments);
-		dojo.attr(this.valueNode, "value", this.get("value"));
+		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){
@@ -191,32 +235,31 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 		//		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>';
-		dijit.setWaiState(this.focusNode, "valuetext", lbl);
+		this.focusNode.setAttribute("aria-valuetext", lbl);
 	},
 
 	validate: function(/*Boolean*/ isFocused){
 		// summary:
-		//		Called by oninit, onblur, and onkeypress.
+		//		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.isValid(isFocused);
-		this._set("state", isValid ? "" : "Error");
-		dijit.setWaiState(this.focusNode, "invalid", isValid ? "false" : "true");
+
+		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(this.message !== message){
-			this._set("message", message);
-			dijit.hideTooltip(this.domNode);
-			if(message){
-				dijit.showTooltip(message, this.domNode, this.tooltipPosition, !this.isLeftToRight());
-			}
+		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){
+	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.
@@ -227,16 +270,15 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 		// summary:
 		//		Overridden so that the state will be cleared.
 		this.inherited(arguments);
-		dijit.hideTooltip(this.domNode);
-		this._set("state", "");
-		this._set("message", "")
+		Tooltip.hide(this.domNode);
+		this.validate(this.focused);	// to update this.state
 	},
 
 	postMixInProperties: function(){
 		// summary:
 		//		set the missing message
 		this.inherited(arguments);
-		this._missingMsg = dojo.i18n.getLocalization("dijit.form", "validate",
+		this._missingMsg = i18n.getLocalization("dijit.form", "validate",
 									this.lang).missingMessage;
 	},
 
@@ -246,12 +288,12 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 
 		this.inherited(arguments);
 
-		this.connect(this.domNode, "onmousemove", dojo.stopEvent);
+		this.connect(this.domNode, "onmousemove", event.stop);
 	},
 
 	_setStyleAttr: function(/*String||Object*/ value){
 		this.inherited(arguments);
-		dojo.toggleClass(this.domNode, this.baseClass + "FixedWidth", !!this.tableNode.style.width);
+		domClass.toggle(this.domNode, this.baseClass + "FixedWidth", !!this.domNode.style.width);
 	},
 
 	isLoaded: function(){
@@ -284,9 +326,20 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 			delete this.dropDown;
 		}
 		this.inherited(arguments);
+	},
+
+	_onFocus: function(){
+		this.validate(true);	// show tooltip if second focus of required tooltip, but no selection
+		this.inherited(arguments);
+	},
+
+	_onBlur: function(){
+		Tooltip.hide(this.domNode);
+		this.inherited(arguments);
 	}
 });
 
+Select._Menu = _SelectMenu;	// for monkey patching
 
-return dijit.form.Select;
+return Select;
 });
diff --git a/dijit/form/SimpleTextarea.js b/dijit/form/SimpleTextarea.js
index bec0449..e82109a 100644
--- a/dijit/form/SimpleTextarea.js
+++ b/dijit/form/SimpleTextarea.js
@@ -1,25 +1,36 @@
-define("dijit/form/SimpleTextarea", ["dojo", "dijit", "dijit/form/TextBox"], function(dojo, dijit) {
+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
+	"./TextBox"
+], function(declare, domClass, has, win, TextBox){
 
-dojo.declare("dijit.form.SimpleTextarea",
-	dijit.form.TextBox,
-	{
+/*=====
+	var TextBox = dijit.form.TextBox;
+=====*/
+
+// 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 dojoType="dijit.form.SimpleTextarea" name="foo" value="bar" rows=30 cols=40></textarea>
+	//	|	<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",
 
-	attributeMap: dojo.delegate(dijit.form._FormValueWidget.prototype.attributeMap, {
-		rows:"textbox", cols: "textbox"
-	}),
-
 	// rows: Number
 	//		The number of rows of text.
 	rows: "3",
@@ -28,7 +39,7 @@ dojo.declare("dijit.form.SimpleTextarea",
 	//		The number of characters per line.
 	cols: "20",
 
-	templateString: "<textarea ${!nameAttrSetting} dojoAttachPoint='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)
@@ -41,8 +52,8 @@ dojo.declare("dijit.form.SimpleTextarea",
 
 	buildRendering: function(){
 		this.inherited(arguments);
-		if(dojo.isIE && this.cols){ // attribute selectors is not supported in IE6
-			dojo.addClass(this.textbox, "dijitTextAreaCols");
+		if(has("ie") && this.cols){ // attribute selectors is not supported in IE6
+			domClass.add(this.textbox, "dijitTextAreaCols");
 		}
 	},
 
@@ -55,7 +66,6 @@ dojo.declare("dijit.form.SimpleTextarea",
 		return this.inherited(arguments);
 	},
 
-	_previousValue: "",
 	_onInput: function(/*Event?*/ e){
 		// Override TextBox._onInput() to enforce maxLength restriction
 		if(this.maxLength){
@@ -63,19 +73,18 @@ dojo.declare("dijit.form.SimpleTextarea",
 			var value = this.textbox.value.replace(/\r/g,'');
 			var overflow = value.length - maxLength;
 			if(overflow > 0){
-				if(e){ dojo.stopEvent(e); }
 				var textarea = this.textbox;
 				if(textarea.selectionStart){
 					var pos = textarea.selectionStart;
 					var cr = 0;
-					if(dojo.isOpera){
+					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(dojo.doc.selection){ //IE
+				}else if(win.doc.selection){ //IE
 					textarea.focus();
-					var range = dojo.doc.selection.createRange();
+					var range = win.doc.selection.createRange();
 					// delete overflow characters
 					range.moveStart("character", -overflow);
 					range.text = '';
@@ -83,12 +92,9 @@ dojo.declare("dijit.form.SimpleTextarea",
 					range.select();
 				}
 			}
-			this._previousValue = this.textbox.value;
 		}
 		this.inherited(arguments);
 	}
 });
 
-
-return dijit.form.SimpleTextarea;
 });
diff --git a/dijit/form/Slider.js b/dijit/form/Slider.js
index 57522c2..3a3df38 100644
--- a/dijit/form/Slider.js
+++ b/dijit/form/Slider.js
@@ -1,9 +1,18 @@
-define("dijit/form/Slider", ["dojo", "dijit", "dijit/form/HorizontalSlider", "dijit/form/VerticalSlider", "dijit/form/HorizontalRule", "dijit/form/VerticalRule", "dijit/form/HorizontalRuleLabels", "dijit/form/VerticalRuleLabels"], function(dojo, dijit) {
+define([
+	"dojo/_base/kernel", // kernel.deprecated
+	"./HorizontalSlider",
+	"./VerticalSlider",
+	"./HorizontalRule",
+	"./VerticalRule",
+	"./HorizontalRuleLabels",
+	"./VerticalRuleLabels"
+], function(kernel){
 
-dojo.deprecated("Call require() for HorizontalSlider / VerticalRule, explicitly rather than 'dijit.form.Slider' itself", "", "2.0");
+	// module:
+	//		dijit/form/Slider
+	// summary:
+	//		Rollup of all the the Slider related widgets
+	//		For back-compat, remove for 2.0
 
-// For back-compat, remove for 2.0
-
-
-return dijit.form.Slider;
+	kernel.deprecated("Call require() for HorizontalSlider / VerticalRule, explicitly rather than 'dijit.form.Slider' itself", "", "2.0");
 });
diff --git a/dijit/form/TextBox.js b/dijit/form/TextBox.js
index ed26dfa..89138f6 100644
--- a/dijit/form/TextBox.js
+++ b/dijit/form/TextBox.js
@@ -1,418 +1,173 @@
-define("dijit/form/TextBox", ["dojo", "dijit", "text!dijit/form/templates/TextBox.html", "dijit/form/_FormWidget"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/dom-construct", // domConstruct.create
+	"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
+	"./_FormValueWidget",
+	"./_TextBoxMixin",
+	"dojo/text!./templates/TextBox.html",
+	".."	// to export dijit._setSelectionRange, remove in 2.0
+], function(declare, domConstruct, domStyle, kernel, lang, has, win,
+			_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
 
-dojo.declare(
-	"dijit.form.TextBox",
-	dijit.form._FormValueWidget,
-	{
+	var TextBox = declare(/*====="dijit.form.TextBox", =====*/ [_FormValueWidget, _TextBoxMixin], {
 		// summary:
 		//		A base class for textbox form inputs
 
-		// 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: "",
-		
-		templateString: dojo.cache("dijit.form", "templates/TextBox.html"),
-		_singleNodeTemplate: '<input class="dijit dijitReset dijitLeft dijitInputField" dojoAttachPoint="textbox,focusNode" autocomplete="off" type="${type}" ${!nameAttrSetting} />',
+		templateString: template,
+		_singleNodeTemplate: '<input class="dijit dijitReset dijitLeft dijitInputField" data-dojo-attach-point="textbox,focusNode" autocomplete="off" type="${type}" ${!nameAttrSetting} />',
 
-		_buttonInputDisabled: dojo.isIE ? "disabled" : "", // allows IE to disallow focus, but Firefox cannot be disabled for mousedown events
+		_buttonInputDisabled: has("ie") ? "disabled" : "", // allows IE to disallow focus, but Firefox cannot be disabled for mousedown events
 
 		baseClass: "dijitTextBox",
 
-		attributeMap: dojo.delegate(dijit.form._FormValueWidget.prototype.attributeMap, {
-			maxLength: "focusNode"
-		}),
-		
 		postMixInProperties: function(){
 			var type = this.type.toLowerCase();
-			if(this.templateString && this.templateString.toLowerCase() == "input" || ((type == "hidden" || type == "file") && this.templateString == dijit.form.TextBox.prototype.templateString)){
+			if(this.templateString && this.templateString.toLowerCase() == "input" || ((type == "hidden" || type == "file") && this.templateString == this.constructor.prototype.templateString)){
 				this.templateString = this._singleNodeTemplate;
 			}
 			this.inherited(arguments);
 		},
 
+		_onInput: function(e){
+			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);
+			}
+		},
+
 		_setPlaceHolderAttr: function(v){
 			this._set("placeHolder", v);
 			if(!this._phspan){
 				this._attachPoints.push('_phspan');
-				/* 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 = dojo.create('span',{className:'dijitPlaceHolder dijitInputField'},this.textbox,'after');
+				// 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.innerHTML="";
 			this._phspan.appendChild(document.createTextNode(v));
-			
 			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.focused&&!this.textbox.value)?"":"none";
 			}
 		},
 
-		_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"));
-			}
-
+			this.inherited(arguments);
 			this._updatePlaceHolder();
-
-			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: "",
-
 		getDisplayedValue: function(){
 			// summary:
 			//		Deprecated.  Use get('displayedValue') instead.
 			// tags:
 			//		deprecated
-			dojo.deprecated(this.declaredClass+"::getDisplayedValue() is deprecated. Use set('displayedValue') instead.", "", "2.0");
+			kernel.deprecated(this.declaredClass+"::getDisplayedValue() is deprecated. Use set('displayedValue') instead.", "", "2.0");
 			return this.get('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);
-		},
-
 		setDisplayedValue: function(/*String*/ value){
 			// summary:
 			//		Deprecated.  Use set('displayedValue', ...) instead.
 			// tags:
 			//		deprecated
-			dojo.deprecated(this.declaredClass+"::setDisplayedValue() is deprecated. Use set('displayedValue', ...) instead.", "", "2.0");
+			kernel.deprecated(this.declaredClass+"::setDisplayedValue() is deprecated. Use set('displayedValue', ...) instead.", "", "2.0");
 			this.set('displayedValue', 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'));
-		},
-
-		format: function(/*String*/ value, /*Object*/ constraints){
-			// summary:
-			//		Replacable function to convert a value to a properly formatted string.
-			// tags:
-			//		protected extension
-			return ((value == null || value == undefined) ? "" : (value.toString ? value.toString() : value));
-		},
-
-		parse: function(/*String*/ value, /*Object*/ constraints){
-			// summary:
-			//		Replacable function to convert a formatted string to a value
-			// 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(e){
-			if(e && e.type && /key/i.test(e.type) && e.keyCode){
-				switch(e.keyCode){
-					case dojo.keys.SHIFT:
-					case dojo.keys.ALT:
-					case dojo.keys.CTRL:
-					case dojo.keys.TAB:
-						return;
-				}
-			}
-			if(this.intermediateChanges){
-				var _this = this;
-				// the setTimeout allows the key to post to the widget input box
-				setTimeout(function(){ _this._handleOnChange(_this.get('value'), false); }, 0);
-			}
-			this._refreshState();
-
-			// In case someone is watch()'ing for changes to displayedValue
-			this._set("displayedValue", this.get("displayedValue"));
-		},
-
-		postCreate: function(){
-			if(dojo.isIE){ // 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(dojo.hitch(this, function(){
-				var s = dojo.getComputedStyle(this.domNode);
-				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;
-							}
-						}
-					}
-				}
-				}), 0);
-			}
-
-			// 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);
-
-			if(dojo.isMoz || dojo.isOpera){
-				this.connect(this.textbox, "oninput", "_onInput");
-			}else{
-				this.connect(this.textbox, "onkeydown", "_onInput");
-				this.connect(this.textbox, "onkeyup", "_onInput");
-				this.connect(this.textbox, "onpaste", "_onInput");
-				this.connect(this.textbox, "oncut", "_onInput");
-			}
-		},
-
-		_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 = dojo.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);
-			}
-			if(this.selectOnClick && dojo.isMoz){
-				this.textbox.selectionStart = this.textbox.selectionEnd = undefined; // clear selection so that the next mouse click doesn't reselect
-			}
-			
 			this._updatePlaceHolder();
 		},
 
 		_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
-					var textIsNotSelected;
-					if(dojo.isIE){
-						var range = dojo.doc.selection.createRange();
-						var parent = range.parentElement();
-						textIsNotSelected = parent == this.textbox && range.text.length == 0;
-					}else{
-						textIsNotSelected = this.textbox.selectionStart == this.textbox.selectionEnd;
-					}
-					if(textIsNotSelected){
-						dijit.selectInputText(this.textbox);
-					}
-				});
-			}
-
-			this._updatePlaceHolder();
-			
-			// 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._updatePlaceHolder();
+		}
+	});
 
-			this._refreshState();
-		},
+	if(has("ie")){
+		TextBox = declare(/*===== "dijit.form.TextBox.IEMixin", =====*/ TextBox, {
+			declaredClass: "dijit.form.TextBox",	// for user code referencing declaredClass
 
-		reset: function(){
-			// Overrides dijit._FormWidget.reset().
-			// Additionally resets the displayed textbox value to ''
-			this.textbox.value = '';
-			this.inherited(arguments);
-		}
-	}
-);
+			_isTextSelected: function(){
+				var range = win.doc.selection.createRange();
+				var parent = range.parentElement();
+				return parent == this.textbox && range.text.length == 0;
+			},
 
-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).
+			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);
+			}
+		});
 
-	// TODO: use functions in _editor/selection.js?
-	var _window = dojo.global;
-	var _document = dojo.doc;
-	element = dojo.byId(element);
-	if(isNaN(start)){ start = 0; }
-	if(isNaN(stop)){ stop = element.value ? element.value.length : 0; }
-	dijit.focus(element);
-	if(_document["selection"] && dojo.body()["createTextRange"]){ // IE
-		if(element.createTextRange){
-			var r = element.createTextRange();
-			r.collapse(true);
-			r.moveStart("character", -99999); // move to 0
-			r.moveStart("character", start); // delta from 0 is the correct position
-			r.moveEnd("character", stop-start);
-			r.select();
-		}
-	}else if(_window["getSelection"]){
-		if(element.setSelectionRange){
-			element.setSelectionRange(start, stop);
+		// Overrides definition of _setSelectionRange from _TextBoxMixin (TODO: move to _TextBoxMixin.js?)
+		dijit._setSelectionRange = _TextBoxMixin._setSelectionRange = function(/*DomNode*/ element, /*Number?*/ start, /*Number?*/ stop){
+			if(element.createTextRange){
+				var r = element.createTextRange();
+				r.collapse(true);
+				r.moveStart("character", -99999); // move to 0
+				r.moveStart("character", start); // delta from 0 is the correct position
+				r.moveEnd("character", stop-start);
+				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){
+				this.inherited(arguments);
+				if(this.selectOnClick){
+						// clear selection so that the next mouse click doesn't reselect
+					this.textbox.selectionStart = this.textbox.selectionEnd = undefined;
+				}
+			}
+		});
+	}else{
+		TextBox.prototype.declaredClass = "dijit.form.TextBox";
 	}
-};
-
+	lang.setObject("dijit.form.TextBox", TextBox);	// don't do direct assignment, it confuses API doc parser
 
-return dijit.form.TextBox;
+	return TextBox;
 });
diff --git a/dijit/form/Textarea.js b/dijit/form/Textarea.js
index 37a61e1..325c305 100644
--- a/dijit/form/Textarea.js
+++ b/dijit/form/Textarea.js
@@ -1,9 +1,22 @@
-define("dijit/form/Textarea", ["dojo", "dijit", "dijit/form/SimpleTextarea"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/dom-style", // domStyle.set
+	"./_ExpandingTextAreaMixin",
+	"./SimpleTextarea"
+], function(declare, domStyle, _ExpandingTextAreaMixin, SimpleTextarea){
 
-dojo.declare(
-	"dijit.form.Textarea",
-	dijit.form.SimpleTextarea,
-	{
+/*=====
+	var _ExpandingTextAreaMixin = dijit.form._ExpandingTextAreaMixin;
+	var SimpleTextarea = dijit.form.SimpleTextarea;
+=====*/
+
+// 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.
 	//
@@ -15,144 +28,22 @@ dojo.declare(
 	//		Rows is not supported since this widget adjusts the height.
 	//
 	// example:
-	// |	<textarea dojoType="dijit.form.TextArea">...</textarea>
+	// |	<textarea data-dojo-type="dijit.form.TextArea">...</textarea>
 
 
-	// TODO: for 2.0, rename this to ExpandingTextArea, and rename SimpleTextarea to Textarea
+	// TODO: for 2.0, rename this to ExpandingTextArea, and rename SimpleTextarea to TextArea
 
 	baseClass: "dijitTextBox dijitTextArea dijitExpandingTextArea",
 
 	// Override SimpleTextArea.cols to default to width:100%, for backward compatibility
 	cols: "",
 
-	_previousNewlines: 0,
-	_strictMode: (dojo.doc.compatMode != 'BackCompat'), // not the same as !dojo.isQuirks
-
-	_getHeight: function(textarea){
-		var newH = textarea.scrollHeight;
-		if(dojo.isIE){
-			newH += textarea.offsetHeight - textarea.clientHeight - ((dojo.isIE < 8 && this._strictMode) ? dojo._getPadBorderExtents(textarea).h : 0);
-		}else if(dojo.isMoz){
-			newH += textarea.offsetHeight - textarea.clientHeight; // creates room for horizontal scrollbar
-		}else if(dojo.isWebKit){
-			newH += dojo._getBorderExtents(textarea).h;
-		}else{ // Opera 9.6 (TODO: test if this is still needed)
-			newH += dojo._getPadBorderExtents(textarea).h;
-		}
-		return newH;
-	},
-
-	_estimateHeight: function(textarea){
-		// 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.
-		//
-		textarea.style.maxHeight = "";
-		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 + 1;
-	},
-
-	_needsHelpShrinking: dojo.isMoz || dojo.isWebKit,
-
-	_onInput: function(){
-		// Override SimpleTextArea._onInput() to deal with height adjustment
-		this.inherited(arguments);
-		if(this._busyResizing){ return; }
-		this._busyResizing = true;
-		var textarea = this.textbox;
-		if(textarea.scrollHeight && textarea.offsetHeight && textarea.clientHeight){
-			var newH = this._getHeight(textarea) + "px";
-			if(textarea.style.height != newH){
-				textarea.style.maxHeight = textarea.style.height = newH;
-			}
-			if(this._needsHelpShrinking){
-				if(this._setTimeoutHandle){
-					clearTimeout(this._setTimeoutHandle);
-				}
-				this._setTimeoutHandle = setTimeout(dojo.hitch(this, "_shrink"), 0); // try to collapse multiple shrinks into 1
-			}
-		}else{
-			// hidden content of unknown size
-			this._estimateHeight(textarea);
-		}
-		this._busyResizing = false;
-	},
-
-	_busyResizing: false,
-	_shrink: function(){
-		// grow paddingBottom to see if scrollHeight shrinks (when it is unneccesarily big)
-		this._setTimeoutHandle = null;
-		if(this._needsHelpShrinking && !this._busyResizing){
-			this._busyResizing = true;
-			var textarea = this.textbox;
-			var empty = false;
-			if(textarea.value == ''){
-				textarea.value = ' '; // prevent collapse all the way back to 0
-				empty = true;
-			}
-			var scrollHeight = textarea.scrollHeight;
-			if(!scrollHeight){
-				this._estimateHeight(textarea);
-			}else{
-				var oldPadding = textarea.style.paddingBottom;
-				var newPadding = dojo._getPadExtents(textarea);
-				newPadding = newPadding.h - newPadding.t;
-				textarea.style.paddingBottom = newPadding + 1 + "px"; // tweak padding to see if height can be reduced
-				var newH = this._getHeight(textarea) - 1 + "px"; // see if the height changed by the 1px added
-				if(textarea.style.maxHeight != newH){ // if can be reduced, so now try a big chunk
-					textarea.style.paddingBottom = newPadding + scrollHeight + "px";
-					textarea.scrollTop = 0;
-					textarea.style.maxHeight = this._getHeight(textarea) - scrollHeight + "px"; // scrollHeight is the added padding
-				}
-				textarea.style.paddingBottom = oldPadding;
-			}
-			if(empty){
-				textarea.value = '';
-			}
-			this._busyResizing = false;
-		}
-	},
-
-	resize: function(){
-		// summary:
-		//		Resizes the textarea vertically (should be called after a style/value change)
-		this._onInput();
-	},
-
-	_setValueAttr: function(){
-		this.inherited(arguments);
-		this.resize();
-	},
-
 	buildRendering: function(){
 		this.inherited(arguments);
 
 		// tweak textarea style to reduce browser differences
-		dojo.style(this.textbox, { overflowY: 'hidden', overflowX: 'auto', boxSizing: 'border-box', MsBoxSizing: 'border-box', WebkitBoxSizing: 'border-box', MozBoxSizing: 'border-box' });
-	},
-
-	postCreate: function(){
-		this.inherited(arguments);
-
-		this.connect(this.textbox, "onscroll", "_onInput");
-		this.connect(this.textbox, "onresize", "_onInput");
-		this.connect(this.textbox, "onfocus", "_onInput"); // useful when a previous estimate was off a bit
-		this._setTimeoutHandle = setTimeout(dojo.hitch(this, "resize"), 0);
-	},
-
-	uninitialize: function(){
-		if(this._setTimeoutHandle){
-			clearTimeout(this._setTimeoutHandle);
-		}
-		this.inherited(arguments);
+		domStyle.set(this.textbox, { overflowY: 'hidden', overflowX: 'auto', boxSizing: 'border-box', MsBoxSizing: 'border-box', WebkitBoxSizing: 'border-box', MozBoxSizing: 'border-box' });
 	}
 });
 
-
-return dijit.form.Textarea;
 });
diff --git a/dijit/form/TimeTextBox.js b/dijit/form/TimeTextBox.js
index 35a4711..5320f1f 100644
--- a/dijit/form/TimeTextBox.js
+++ b/dijit/form/TimeTextBox.js
@@ -1,21 +1,35 @@
-define("dijit/form/TimeTextBox", ["dojo", "dijit", "dijit/_TimePicker", "dijit/form/_DateTimeTextBox"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/keys", // keys.DOWN_ARROW keys.ENTER keys.ESCAPE keys.TAB keys.UP_ARROW
+	"dojo/_base/lang", // lang.hitch
+	"../_TimePicker",
+	"./_DateTimeTextBox"
+], function(declare, keys, lang, _TimePicker, _DateTimeTextBox){
 
 /*=====
-dojo.declare(
-	"dijit.form.TimeTextBox.__Constraints",
-	[dijit.form._DateTimeTextBox.__Constraints, dijit._TimePicker.__Constraints]
-);
+	var _TimePicker = dijit._TimePicker;
+	var _DateTimeTextBox = dijit.form._DateTimeTextBox;
 =====*/
 
-dojo.declare(
-	"dijit.form.TimeTextBox",
-	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]
+	);
+	=====*/
+
+	return declare("dijit.form.TimeTextBox", _DateTimeTextBox, {
 		// summary:
 		//		A validating, serializable, range-bound time text box with a drop down time picker
 
 		baseClass: "dijitTextBox dijitComboBox dijitTimeTextBox",
-		popupClass: "dijit._TimePicker",
+		popupClass: _TimePicker,
 		_selector: "time",
 
 /*=====
@@ -27,38 +41,39 @@ dojo.declare(
 		//		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: dojo.date.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
-		//		`dojo.date.stamp.fromISOString` format.
+		//		`stamp.fromISOString` format.
 		//
 		//		Example:
-		// |	<input dojotype='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
 
 		_onKey: function(evt){
+			if(this.disabled || this.readOnly){ return; }
 			this.inherited(arguments);
 
 			// If the user has backspaced or typed some numbers, then filter the result list
 			// by what they typed.  Maybe there's a better way to detect this, like _handleOnChange()?
 			switch(evt.keyCode){
-				case dojo.keys.ENTER:
-				case dojo.keys.TAB:
-				case dojo.keys.ESCAPE:
-				case dojo.keys.DOWN_ARROW:
-				case dojo.keys.UP_ARROW:
+				case keys.ENTER:
+				case keys.TAB:
+				case keys.ESCAPE:
+				case keys.DOWN_ARROW:
+				case keys.UP_ARROW:
 					// these keys have special meaning
 					break;
 				default:
 					// setTimeout() because the keystroke hasn't yet appeared in the <input>,
 					// so the get('displayedValue') call below won't give the result we want.
-					setTimeout(dojo.hitch(this, function(){
+					setTimeout(lang.hitch(this, 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');
 						this.filterString = (val && !this.parse(val, this.constraints)) ? val.toLowerCase() : "";
-	
+
 						// close the drop down and reopen it, in order to filter the items shown in the list
 						// and also since the drop down may need to be repositioned if the number of list items has changed
 						// and it's being displayed above the <input>
@@ -69,8 +84,5 @@ dojo.declare(
 					}), 0);
 			}
 		}
-	}
-);
-
-return dijit.form.TimeTextBox;
-});
\ No newline at end of file
+	});
+});
diff --git a/dijit/form/ToggleButton.js b/dijit/form/ToggleButton.js
index 45400fa..6cc481d 100644
--- a/dijit/form/ToggleButton.js
+++ b/dijit/form/ToggleButton.js
@@ -1,6 +1,33 @@
-define("dijit/form/ToggleButton", ["dojo", "dijit", "dijit/form/Button"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/_base/kernel", // kernel.deprecated
+	"./Button",
+	"./_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 dijit.form.ToggleButton;
+
+	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
+
+		baseClass: "dijitToggleButton",
+
+		setChecked: function(/*Boolean*/ checked){
+			// summary:
+			//		Deprecated.  Use set('checked', true/false) instead.
+			kernel.deprecated("setChecked("+checked+") is deprecated. Use set('checked',"+checked+") instead.", "", "2.0");
+			this.set('checked', checked);
+		}
+	});
 });
diff --git a/dijit/form/ValidationTextBox.js b/dijit/form/ValidationTextBox.js
index e00a9a6..670d0f1 100644
--- a/dijit/form/ValidationTextBox.js
+++ b/dijit/form/ValidationTextBox.js
@@ -1,26 +1,41 @@
-define("dijit/form/ValidationTextBox", ["dojo", "dijit", "text!dijit/form/templates/ValidationTextBox.html", "dojo/i18n", "dijit/form/TextBox", "dijit/Tooltip", "i18n!dijit/form/nls/validate"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/i18n", // i18n.getLocalization
+	"./TextBox",
+	"../Tooltip",
+	"dojo/text!./templates/ValidationTextBox.html",
+	"dojo/i18n!./nls/validate"
+], function(declare, i18n, TextBox, Tooltip, template){
 
 /*=====
-	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 Tooltip = dijit.Tooltip;
+	var TextBox = dijit.form.TextBox;
 =====*/
 
-dojo.declare(
-	"dijit.form.ValidationTextBox",
-	dijit.form.TextBox,
-	{
+	// 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_ = "";
+		}
+	=====*/
+
+	return 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: dojo.cache("dijit.form", "templates/ValidationTextBox.html"),
+		templateString: template,
 		baseClass: "dijitTextBox dijitValidationTextBox",
 
 		// required: Boolean
@@ -63,7 +78,7 @@ dojo.declare(
 		//		Do not specify both regExp and regExpGen
 		regExp: ".*",
 
-		regExpGen: function(/*dijit.form.ValidationTextBox.__Constraints*/ constraints){
+		regExpGen: function(/*dijit.form.ValidationTextBox.__Constraints*/ /*===== constraints =====*/){
 			// summary:
 			//		Overridable function used to generate regExp when dependent on constraints.
 			//		Do not specify both regExp and regExpGen.
@@ -84,7 +99,7 @@ dojo.declare(
 			// summary:
 			//		Hook so set('value', ...) works.
 			this.inherited(arguments);
-			this.validate(this._focused);
+			this.validate(this.focused);
 		},
 
 		validator: function(/*anything*/ value, /*dijit.form.ValidationTextBox.__Constraints*/ constraints){
@@ -104,7 +119,7 @@ dojo.declare(
 			return this.textbox.value.search(this._partialre) == 0;
 		},
 
-		isValid: function(/*Boolean*/ isFocused){
+		isValid: function(/*Boolean*/ /*===== isFocused =====*/){
 			// summary:
 			//		Tests if value is valid.
 			//		Can override with your own routine in a subclass.
@@ -119,7 +134,7 @@ dojo.declare(
 			return (this.trim ? /^\s*$/ : /^$/).test(value); // Boolean
 		},
 
-		getErrorMessage: function(/*Boolean*/ isFocused){
+		getErrorMessage: function(/*Boolean*/ /*===== isFocused =====*/){
 			// summary:
 			//		Return an error message to show if appropriate
 			// tags:
@@ -127,7 +142,7 @@ dojo.declare(
 			return (this.required && this._isEmpty(this.textbox.value)) ? this.missingMessage : this.invalidMessage; // String
 		},
 
-		getPromptMessage: function(/*Boolean*/ isFocused){
+		getPromptMessage: function(/*Boolean*/ /*===== isFocused =====*/){
 			// summary:
 			//		Return a hint message to show when widget is first focused
 			// tags:
@@ -149,7 +164,7 @@ dojo.declare(
 			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"));
-			dijit.setWaiState(this.focusNode, "invalid", isValid ? "false" : "true");
+			this.focusNode.setAttribute("aria-invalid", isValid ? "false" : "true");
 
 			if(this.state == "Error"){
 				this._maskValidSubsetError = isFocused && isValidSubset; // we want the error to show up after a blur and refocus
@@ -171,15 +186,16 @@ dojo.declare(
 			//		By default uses a tooltip.
 			// tags:
 			//		extension
-			dijit.hideTooltip(this.domNode);
-			if(message && this._focused){
-				dijit.showTooltip(message, this.domNode, this.tooltipPosition, !this.isLeftToRight());
+			if(message && this.focused){
+				Tooltip.show(message, this.domNode, this.tooltipPosition, !this.isLeftToRight());
+			}else{
+				Tooltip.hide(this.domNode);
 			}
 		},
 
 		_refreshState: function(){
 			// Overrides TextBox._refreshState()
-			this.validate(this._focused);
+			this.validate(this.focused);
 			this.inherited(arguments);
 		},
 
@@ -204,7 +220,7 @@ dojo.declare(
 			// 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){
+				function(re){
 					switch(re.charAt(0)){
 						case '{':
 						case '+':
@@ -236,7 +252,7 @@ dojo.declare(
 
 		postMixInProperties: function(){
 			this.inherited(arguments);
-			this.messages = dojo.i18n.getLocalization("dijit.form", "validate", this.lang);
+			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; }
@@ -251,7 +267,7 @@ dojo.declare(
 
 		_setRequiredAttr: function(/*Boolean*/ value){
 			this._set("required", value);
-			dijit.setWaiState(this.focusNode, "required", value);
+			this.focusNode.setAttribute("aria-required", value);
 			this._refreshState();
 		},
 
@@ -274,201 +290,5 @@ dojo.declare(
 
 			this.inherited(arguments);
 		}
-	}
-);
-
-dojo.declare(
-	"dijit.form.MappedTextBox",
-	dijit.form.ValidationTextBox,
-	{
-		// 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.
-		// 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
-		//		locale-neutral.
-		// tags:
-		//		protected
-
-		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
-			this.nameAttrSetting = "";
-		},
-
-		serialize: function(/*anything*/ val, /*Object?*/ options){
-			// summary:
-			//		Overridable function used to convert the get('value') result to a canonical
-			//		(non-localized) string.  For example, will print dates in ISO format, and
-			//		numbers the same way as they are represented in javascript.
-			// tags:
-			//		protected extension
-			return val.toString ? val.toString() : ""; // String
-		},
-
-		toString: function(){
-			// summary:
-			//		Returns widget as a printable string using the widget's value
-			// tags:
-			//		protected
-			var val = this.filter(this.get('value')); // call filter in case value is nonstring and filter has been customized
-			return val != null ? (typeof val == "string" ? val : this.serialize(val, this.constraints)) : ""; // String
-		},
-
-		validate: function(){
-			// Overrides `dijit.form.TextBox.validate`
-			this.valueNode.value = this.toString();
-			return this.inherited(arguments);
-		},
-
-		buildRendering: function(){
-			// Overrides `dijit._Templated.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 dojo.create() with an attrs argument
-			// to make dojo.query(input[name=...]) work on IE. (see #8660)
-			this.valueNode = dojo.place("<input type='hidden'" + (this.name ? " name='" + this.name.replace(/'/g, """) + "'" : "") + "/>", this.textbox, "after");
-		},
-
-		reset: function(){
-			// Overrides `dijit.form.ValidationTextBox.reset` to
-			// reset the hidden textbox value to ''
-			this.valueNode.value = '';
-			this.inherited(arguments);
-		}
-	}
-);
-
-/*=====
-	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;
-	}
-=====*/
-
-dojo.declare(
-	"dijit.form.RangeBoundTextBox",
-	dijit.form.MappedTextBox,
-	{
-		// summary:
-		//		Base class for textbox form widgets which defines a range of valid values.
-
-		// rangeMessage: String
-		//		The message to display if value is out-of-range
-		rangeMessage: "",
-
-		/*=====
-		// constraints: 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:
-			//		protected
-			return	("min" in constraints? (this.compare(primitive,constraints.min) >= 0) : true) &&
-				("max" in constraints? (this.compare(primitive,constraints.max) <= 0) : true); // Boolean
-		},
-
-		isInRange: function(/*Boolean*/ isFocused){
-			// summary:
-			//		Tests if the value is in the min/max range specified in constraints
-			// tags:
-			//		protected
-			return this.rangeCheck(this.get('value'), this.constraints);
-		},
-
-		_isDefinitelyOutOfRange: function(){
-			// summary:
-			//		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("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;
-			}
-			if("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;
-			}
-			return isTooLittle || isTooMuch;
-		},
-
-		_isValidSubset: function(){
-			// summary:
-			//		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.
-			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
-			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
-				return this.rangeMessage; // String
-			}
-			return this.inherited(arguments);
-		},
-
-		postMixInProperties: function(){
-			this.inherited(arguments);
-			if(!this.rangeMessage){
-				this.messages = dojo.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){
-					dijit.setWaiState(this.focusNode, "valuemin", this.constraints.min);
-				}else{
-					dijit.removeWaiState(this.focusNode, "valuemin");
-				}
-				if(this.constraints.max !== undefined){
-					dijit.setWaiState(this.focusNode, "valuemax", this.constraints.max);
-				}else{
-					dijit.removeWaiState(this.focusNode, "valuemax");
-				}
-			}
-		},
-
-		_setValueAttr: function(/*Number*/ value, /*Boolean?*/ priorityChange){
-			// summary:
-			//		Hook so set('value', ...) works.
-
-			dijit.setWaiState(this.focusNode, "valuenow", value);
-			this.inherited(arguments);
-		}
-	}
-);
-
-
-return dijit.form.ValidationTextBox;
+	});
 });
diff --git a/dijit/form/VerticalRule.js b/dijit/form/VerticalRule.js
index e51c6b5..389dcbd 100644
--- a/dijit/form/VerticalRule.js
+++ b/dijit/form/VerticalRule.js
@@ -1,26 +1,34 @@
-define("dijit/form/VerticalRule", ["dojo", "dijit", "dijit/form/HorizontalRule"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"./HorizontalRule"
+], function(declare, HorizontalRule){
 
-dojo.declare("dijit.form.VerticalRule", dijit.form.HorizontalRule,
-{
+/*=====
+	var HorizontalRule = dijit.form.HorizontalRule;
+=====*/
+
+	// module:
+	//		dijit/form/VerticalRule
 	// summary:
 	//		Hash marks for the `dijit.form.VerticalSlider`
 
-	templateString: '<div class="dijitRuleContainer dijitRuleContainerV"></div>',
-	_positionPrefix: '<div class="dijitRuleMark dijitRuleMarkV" style="top:',
+	return declare("dijit.form.VerticalRule", HorizontalRule, {
+		// summary:
+		//		Hash marks for the `dijit.form.VerticalSlider`
 
-/*=====
-	// container: String
-	//		This is either "leftDecoration" or "rightDecoration",
-	//		to indicate whether this rule goes to the left or to the right of the slider.
-	//		Note that on RTL system, "leftDecoration" would actually go to the right, and vice-versa.
-	container: "",
-=====*/
-
-	// Overrides HorizontalRule._isHorizontal
-	_isHorizontal: false
+		templateString: '<div class="dijitRuleContainer dijitRuleContainerV"></div>',
+		_positionPrefix: '<div class="dijitRuleMark dijitRuleMarkV" style="top:',
 
-});
+	/*=====
+		// container: String
+		//		This is either "leftDecoration" or "rightDecoration",
+		//		to indicate whether this rule goes to the left or to the right of the slider.
+		//		Note that on RTL system, "leftDecoration" would actually go to the right, and vice-versa.
+		container: "",
+	=====*/
 
+		// Overrides HorizontalRule._isHorizontal
+		_isHorizontal: false
 
-return dijit.form.VerticalRule;
+	});
 });
diff --git a/dijit/form/VerticalRuleLabels.js b/dijit/form/VerticalRuleLabels.js
index 4dbbb30..bcef05b 100644
--- a/dijit/form/VerticalRuleLabels.js
+++ b/dijit/form/VerticalRuleLabels.js
@@ -1,24 +1,32 @@
-define("dijit/form/VerticalRuleLabels", ["dojo", "dijit", "dijit/form/HorizontalRuleLabels"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"./HorizontalRuleLabels"
+], function(declare, HorizontalRuleLabels){
 
-dojo.declare("dijit.form.VerticalRuleLabels", dijit.form.HorizontalRuleLabels,
-{
+/*=====
+	var HorizontalRuleLabels = dijit.form.HorizontalRuleLabels;
+=====*/
+
+	// module:
+	//		dijit/form/VerticalRuleLabels
 	// summary:
 	//		Labels for the `dijit.form.VerticalSlider`
 
-	templateString: '<div class="dijitRuleContainer dijitRuleContainerV dijitRuleLabelsContainer dijitRuleLabelsContainerV"></div>',
-
-	_positionPrefix: '<div class="dijitRuleLabelContainer dijitRuleLabelContainerV" style="top:',
-	_labelPrefix: '"><span class="dijitRuleLabel dijitRuleLabelV">',
+	return declare("dijit.form.VerticalRuleLabels", HorizontalRuleLabels, {
+		// summary:
+		//		Labels for the `dijit.form.VerticalSlider`
 
-	_calcPosition: function(pos){
-		// Overrides HorizontalRuleLabel._calcPosition()
-		return 100-pos;
-	},
+		templateString: '<div class="dijitRuleContainer dijitRuleContainerV dijitRuleLabelsContainer dijitRuleLabelsContainerV"></div>',
 
-	// needed to prevent labels from being reversed in RTL mode
-	_isHorizontal: false
-});
+		_positionPrefix: '<div class="dijitRuleLabelContainer dijitRuleLabelContainerV" style="top:',
+		_labelPrefix: '"><span class="dijitRuleLabel dijitRuleLabelV">',
 
+		_calcPosition: function(pos){
+			// Overrides HorizontalRuleLabel._calcPosition()
+			return 100-pos;
+		},
 
-return dijit.form.VerticalRuleLabels;
+		// needed to prevent labels from being reversed in RTL mode
+		_isHorizontal: false
+	});
 });
diff --git a/dijit/form/VerticalSlider.js b/dijit/form/VerticalSlider.js
index 3b526b1..f786ee9 100644
--- a/dijit/form/VerticalSlider.js
+++ b/dijit/form/VerticalSlider.js
@@ -1,33 +1,40 @@
-define("dijit/form/VerticalSlider", ["dojo", "dijit", "text!dijit/form/templates/VerticalSlider.html", "dijit/form/HorizontalSlider"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"./HorizontalSlider",
+	"dojo/text!./templates/VerticalSlider.html"
+], function(declare, HorizontalSlider, template){
 
-dojo.declare(
-	"dijit.form.VerticalSlider",
-	dijit.form.HorizontalSlider,
-{
+/*=====
+	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
 
-	templateString: dojo.cache('dijit.form','templates/VerticalSlider.html'),
-	_mousePixelCoord: "pageY",
-	_pixelCount: "h",
-	_startingPixelCoord: "y",
-	_startingPixelCount: "t",
-	_handleOffsetCoord: "top",
-	_progressPixelSize: "height",
-
-	// _descending: Boolean
-	//		Specifies if the slider values go from high-on-top (true), or low-on-top (false)
-	//		TODO: expose this in 1.2 - the css progress/remaining bar classes need to be reversed
-	_descending: true,
 
-	_isReversed: function(){
+	return declare("dijit.form.VerticalSlider", HorizontalSlider, {
 		// summary:
-		//		Overrides HorizontalSlider._isReversed.
-		//		Indicates if values are high on top (with low numbers on the bottom).
-		return this._descending;
-	}
-});
+		//		A form widget that allows one to select a value with a vertically draggable handle
+
+		templateString: template,
+		_mousePixelCoord: "pageY",
+		_pixelCount: "h",
+		_startingPixelCoord: "y",
+		_handleOffsetCoord: "top",
+		_progressPixelSize: "height",
 
+		// _descending: Boolean
+		//		Specifies if the slider values go from high-on-top (true), or low-on-top (false)
+		//		TODO: expose this in 1.2 - the css progress/remaining bar classes need to be reversed
+		_descending: true,
 
-return dijit.form.VerticalSlider;
+		_isReversed: function(){
+			// summary:
+			//		Overrides HorizontalSlider._isReversed.
+			//		Indicates if values are high on top (with low numbers on the bottom).
+			return this._descending;
+		}
+	});
 });
diff --git a/dijit/form/_AutoCompleterMixin.js b/dijit/form/_AutoCompleterMixin.js
new file mode 100644
index 0000000..ca32797
--- /dev/null
+++ b/dijit/form/_AutoCompleterMixin.js
@@ -0,0 +1,764 @@
+define([
+	"dojo/_base/connect", // keys keys.SHIFT
+	"dojo/data/util/filter", // patternToRegExp
+	"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
+	"./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){
+
+	// 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, {
+		// summary:
+		//		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`.
+		// tags:
+		//		protected
+
+		// item: Object
+		//		This is the item returned by the dojo.data.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
+		//		the `<input>` field
+		autoComplete: true,
+
+		// highlightMatch: String
+		// 		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"
+		//		then will probably want to change `queryExpr` parameter to '*${0}*'
+		//
+		//		Highlighting is only performed when `labelType` is "text", so as to not
+		//		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.
+		//		If not specified, the searchAttr attribute is used instead.
+		labelAttr: "",
+
+		// labelType: String
+		//		Specifies how to interpret the labelAttr in the data store items.
+		//		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,
+
+		// For backwards compatibility let onClick events propagate, even clicks on the down arrow button
+		_stopClickEvents: false,
+
+		_getCaretPos: function(/*DomNode*/ element){
+			// khtml 3.5.2 has selection* methods as does webkit nightlies from 2005-06-22
+			var pos = 0;
+			if(typeof(element.selectionStart) == "number"){
+				// FIXME: this is totally borked on Moz < 1.3. Any recourse?
+				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();
+				// hack to get IE 6 to play nice. What a POS browser.
+				var tr = win.doc.selection.createRange().duplicate();
+				var ntr = element.createTextRange();
+				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;
+				}catch(e){
+					// If focus has shifted, 0 is fine for caret pos.
+				}
+			}
+			return pos;
+		},
+
+		_setCaretPos: function(/*DomNode*/ element, /*Number*/ location){
+			location = parseInt(location);
+			_TextBoxMixin.selectInputText(element, location, location);
+		},
+
+		_setDisabledAttr: function(/*Boolean*/ value){
+			// 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);
+			}
+		},
+
+		_onKey: function(/*Event*/ evt){
+			// summary:
+			//		Handles keyboard events
+
+			var key = evt.charOrCode;
+
+			// 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
+			}
+
+			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
+			this.inherited(arguments);
+
+			if(this._opened){
+				highlighted = pw.getHighlightedOption();
+			}
+			switch(key){
+				case keys.PAGE_DOWN:
+				case keys.DOWN_ARROW:
+				case keys.PAGE_UP:
+				case keys.UP_ARROW:
+					// Keystroke caused ComboBox_menu to move to a different item.
+					// Copy new item to <input> box.
+					if(this._opened){
+						this._announceOption(highlighted);
+					}
+					event.stop(evt);
+					break;
+
+				case keys.ENTER:
+					// prevent submitting form if user presses enter. Also
+					// prevent accepting the value if either Next or Previous
+					// are selected
+					if(highlighted){
+						// only stop event on prev/next
+						if(highlighted == pw.nextButton){
+							this._nextSearch(1);
+							event.stop(evt);
+							break;
+						}else if(highlighted == pw.previousButton){
+							this._nextSearch(-1);
+							event.stop(evt);
+							break;
+						}
+					}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
+
+				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"])
+					){
+						break;
+					}
+					if(highlighted){
+						this._selectOption(highlighted);
+					}
+					// fall through
+
+				case keys.ESCAPE:
+					if(this._opened){
+						this._lastQuery = null; // in case results come back later
+						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.
+
+			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';
+			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){
+					// only add to input node as we would overwrite Capitalisation of chars
+					// actually, that is ok
+					fn.value = text;//.substr(cpos);
+					// visually highlight the autocompleted characters
+					_TextBoxMixin.selectInputText(fn, cpos);
+				}
+			}else{
+				// text does not autoComplete; replace the whole value and highlight
+				fn.value = text;
+				_TextBoxMixin.selectInputText(fn);
+			}
+		},
+
+		_openResultList: function(/*Object*/ results, /*Object*/ query, /*Object*/ options){
+			// summary:
+			//		Callback when a search completes.
+			// description:
+			//		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;
+			}
+
+			// 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 nodes = this.dropDown.createOptions(
+				results,
+				options,
+				lang.hitch(this, "_getMenuLabelFromItem")
+			);
+
+			// show our list (only if we have content, else nothing)
+			this._showResultList();
+
+			// #4091:
+			//		tell the screen reader that the paging callback finished by
+			//		shouting the next choice
+			if(options.direction){
+				if(1 == options.direction){
+					this.dropDown.highlightFirstOption();
+				}else if(-1 == options.direction){
+					this.dropDown.highlightLastOption();
+				}
+				if(wasSelected){
+					this._announceOption(this.dropDown.getHighlightedOption());
+				}
+			}else if(this.autoComplete && !this._prev_key_backspace
+				// when the user clicks the arrow button to show the full list,
+				// startSearch looks for "*".
+				// 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
+			}
+		},
+
+		_showResultList: function(){
+			// summary:
+			//		Display the drop down if not already displayed, or if it is displayed, then
+			//		reposition it if necessary (reposition may be necessary if drop down's height changed).
+			this.closeDropDown(true);
+			this.openDropDown();
+			this.domNode.setAttribute("aria-expanded", "true");
+		},
+
+		loadDropDown: function(/*Function*/ /*===== callback =====*/){
+			// 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();
+		},
+
+		isLoaded: function(){
+			// signal to _HasDropDown that it needs to call loadDropDown() to load the
+			// drop down asynchronously before displaying it
+			return false;
+		},
+
+		closeDropDown: function(){
+			// Overrides _HasDropDown.closeDropDown().  Closes the drop down (assuming that it's open).
+			// This method is the callback when the user types ESC or clicking
+			// the button icon while the drop down is open.  It's also called by other code.
+			this._abortQuery();
+			if(this._opened){
+				this.inherited(arguments);
+				this.domNode.setAttribute("aria-expanded", "false");
+				this.focusNode.removeAttribute("aria-activedescendant");
+			}
+		},
+
+		_setBlurValue: function(){
+			// if the user clicks away from the textbox OR tabs away, set the
+			// value to the textbox value
+			// #4617:
+			//		if value is now more choices or previous choices, revert
+			//		the value
+			var newvalue = this.get('displayedValue');
+			var pw = this.dropDown;
+			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
+				this.item = null;
+				this.set('displayedValue', newvalue);
+			}else{
+				if(this.value != this._lastValueReported){
+					this._handleOnChange(this.value, true);
+				}
+				this._refreshState();
+			}
+		},
+
+		_setItemAttr: function(/*item*/ item, /*Boolean?*/ priorityChange, /*String?*/ displayedValue){
+			// summary:
+			//		Set the displayed valued in the input box, and the hidden value
+			//		that gets submitted, based on a dojo.data store item.
+			// description:
+			//		Users shouldn't call this function; they should be calling
+			//		set('item', value)
+			// tags:
+			//		private
+			var value = '';
+			if(item){
+				if(!displayedValue){
+					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;
+			}
+			this.set('value', value, priorityChange, displayedValue, item);
+		},
+
+		_announceOption: function(/*Node*/ node){
+			// summary:
+			//		a11y code that puts the highlighted option in the textbox.
+			//		This way screen readers will know what is happening in the
+			//		menu.
+
+			if(!node){
+				return;
+			}
+			// pull the text value from the item attached to the DOM node
+			var newValue;
+			if(node == this.dropDown.nextButton ||
+				node == this.dropDown.previousButton){
+				newValue = node.innerHTML;
+				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);
+			}
+			// get the text that the user manually entered (cut off autocompleted text)
+			this.focusNode.value = this.focusNode.value.substring(0, this._lastInput.length);
+			// set up ARIA activedescendant
+			this.focusNode.setAttribute("aria-activedescendant", domAttr.get(node, "id"));
+			// autocomplete the rest of the option to announce change
+			this._autoCompleteText(newValue);
+		},
+
+		_selectOption: function(/*DomNode*/ target){
+			// summary:
+			//		Menu callback function, called when an item in the menu is selected.
+			this.closeDropDown();
+			if(target){
+				this._announceOption(target);
+			}
+			this._setCaretPos(this.focusNode, this.focusNode.value.length);
+			this._handleOnChange(this.value, true);
+		},
+
+		_startSearchAll: function(){
+			this._startSearch('');
+		},
+
+		_startSearchFromInput: function(){
+			this._startSearch(this.focusNode.value.replace(/([\\\*\?])/g, "\\$1"));
+		},
+
+		_getQueryString: function(/*String*/ text){
+			return string.substitute(this.queryExpr, [text]);
+		},
+
+		_startSearch: function(/*String*/ key){
+			// summary:
+			//		Starts a search for elements matching key (key=="" means to return all items),
+			//		and calls _openResultList() when the search completes, to display the results.
+			if(!this.dropDown){
+				var popupId = this.id + "_popup",
+					dropDownConstructor = lang.isString(this.dropDownClass) ?
+						lang.getObject(this.dropDownClass, false) : this.dropDownClass;
+				this.dropDown = new dropDownConstructor({
+					onChange: lang.hitch(this, this._selectOption),
+					id: popupId,
+					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);
+		},
+
+		_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.
+			return this.searchAttr;
+		},
+
+		//////////// INITIALIZATION METHODS ///////////////////////////////////////
+
+		constructor: function(){
+			this.query={};
+			this.fetchProperties={};
+		},
+
+		postMixInProperties: function(){
+			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 there is no value set and there is an option list, set
+				// the value to the first value to be consistent with native Select
+				// Firefox and Safari set value
+				// IE6 and Opera set selectedIndex, which is automatically set
+				// by the selected attribute of an option tag
+				// IE6 does not set value, Opera sets value = selectedIndex
+				if(!("value" in this.params)){
+					var item = (this.item = this.store.fetchSelectedItem());
+					if(item){
+						var valueField = this._getValueField();
+						// remove getValue() for 2.0 (old dojo.data API)
+						this.value = this.store._oldAPI ? this.store.getValue(item, valueField) : item[valueField];
+					}
+				}
+			}
+
+			this.inherited(arguments);
+		},
+
+		postCreate: function(){
+			// summary:
+			//		Subclasses must call this method from their postCreate() methods
+			// tags:
+			//		protected
+
+			// find any associated label element and add to ComboBox node.
+			var label=query('label[for="'+this.id+'"]');
+			if(label.length){
+				label[0].id = (this.id+"_label");
+				this.domNode.setAttribute("aria-labelledby", label[0].id);
+
+			}
+			this.inherited(arguments);
+		},
+
+		_getMenuLabelFromItem: function(/*Item*/ item){
+			var label = this.labelFunc(item, this.store),
+				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));
+				labelType = "html";
+			}
+			return {html: labelType == "html", label: label};
+		},
+
+		doHighlight: function(/*String*/ label, /*String*/ find){
+			// summary:
+			//		Highlights the string entered by the user in the menu.  By default this
+			//		highlights the first occurrence found. Override this method
+			//		to implement your custom highlighting.
+			// tags:
+			//		protected
+
+			var
+				// 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>'
+			); // 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: &<>"'
+			str = String(str).replace(/&/gm, "&").replace(/</gm, "<")
+				.replace(/>/gm, ">").replace(/"/gm, """); //balance"
+			return str; // string
+		},
+
+		reset: function(){
+			// Overrides the _FormWidget.reset().
+			// Additionally reset the .item (to clean up).
+			this.item = null;
+			this.inherited(arguments);
+		},
+
+		labelFunc: function(/*item*/ item, /*dojo.store.api.Store*/ store){
+			// summary:
+			//		Computes the label to display based on the dojo.data store item.
+			// returns:
+			//		The label that the ComboBox should display
+			// tags:
+			//		private
+
+			// Use toString() because XMLStore returns an XMLItem whereas this
+			// method is expected to return a String (#9354).
+			// Remove getValue() for 2.0 (old dojo.data API)
+			return (store._oldAPI ? store.getValue(item, this.labelAttr || this.searchAttr) :
+				item[this.labelAttr || this.searchAttr]).toString(); // String
+		},
+
+		_setValueAttr: function(/*String*/ value, /*Boolean?*/ priorityChange, /*String?*/ displayedValue, /*item?*/ item){
+			// summary:
+			//		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.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);
+			}
+		}
+	});
+});
diff --git a/dijit/form/_ButtonMixin.js b/dijit/form/_ButtonMixin.js
new file mode 100644
index 0000000..f345d88
--- /dev/null
+++ b/dijit/form/_ButtonMixin.js
@@ -0,0 +1,85 @@
+define([
+	"dojo/_base/declare", // declare
+	"dojo/dom", // dom.setSelectable
+	"dojo/_base/event", // event.stop
+	"../registry"		// registry.byNode
+], function(declare, dom, event, registry){
+
+// module:
+//		dijit/form/_ButtonMixin
+// summary:
+//		A mixin to add a thin standard API wrapper to a normal HTML button
+
+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);
+
+	// label: HTML String
+	//		Content to display in button.
+	label: "",
+
+	// 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);
+			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;
+				}
+			}
+		}
+		if(preventDefault){
+			e.preventDefault();
+		}
+		return !preventDefault;
+	},
+
+	postCreate: function(){
+		this.inherited(arguments);
+		dom.setSelectable(this.focusNode, false);
+	},
+
+	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);
+		(this.containerNode||this.focusNode).innerHTML = content;
+	}
+});
+
+});
diff --git a/dijit/form/_CheckBoxMixin.js b/dijit/form/_CheckBoxMixin.js
new file mode 100644
index 0000000..76b0147
--- /dev/null
+++ b/dijit/form/_CheckBoxMixin.js
@@ -0,0 +1,77 @@
+define([
+	"dojo/_base/declare", // declare
+	"dojo/dom-attr", // domAttr.set
+	"dojo/_base/event" // event.stop
+], function(declare, domAttr, event){
+
+	// 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
+		//
+		// description:
+		//		User interacts with real html inputs.
+		//		On onclick (which occurs by mouse click, space-bar, or
+		//		using the arrow keys to switch the selected radio button),
+		//		we update the state of the checkbox/radio.
+		//
+
+		// type: [private] String
+		//		type attribute on <input> node.
+		//		Overrides `dijit.form.Button.type`.  Users should not change this value.
+		type: "checkbox",
+
+		// value: String
+		//		As an initialization parameter, equivalent to value field on normal checkbox
+		//		(if checked, the value is passed as the value when form is submitted).
+		value: "on",
+
+		// readOnly: Boolean
+		//		Should this widget respond to user input?
+		//		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
+		_setLabelAttr: undefined,
+
+		postMixInProperties: function(){
+			if(this.value == ""){
+				this.value = "on";
+			}
+			this.inherited(arguments);
+		},
+
+		reset: function(){
+			this.inherited(arguments);
+			// Handle unlikely event that the <input type=checkbox> value attribute has changed
+			this._set("value", this.params.value || "on");
+			domAttr.set(this.focusNode, 'value', this.value);
+		},
+
+		_onClick: function(/*Event*/ e){
+			// summary:
+			//		Internal function to handle click actions - need to check
+			//		readOnly, since button no longer does that check.
+			if(this.readOnly){
+				event.stop(e);
+				return false;
+			}
+			return this.inherited(arguments);
+		}
+	});
+});
diff --git a/dijit/form/_ComboBoxMenu.js b/dijit/form/_ComboBoxMenu.js
new file mode 100644
index 0000000..8704385
--- /dev/null
+++ b/dijit/form/_ComboBoxMenu.js
@@ -0,0 +1,138 @@
+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,
+			_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
+		// tags:
+		//		private
+
+		templateString: "<div class='dijitReset dijitMenu' data-dojo-attach-point='containerNode' style='overflow: auto; overflow-x: hidden;'>"
+				+"<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>",
+
+		baseClass: "dijitComboBoxMenu",
+
+		postCreate: function(){
+			this.inherited(arguments);
+			if(!this.isLeftToRight()){
+				domClass.add(this.previousButton, "dijitMenuItemRtl");
+				domClass.add(this.nextButton, "dijitMenuItemRtl");
+			}
+		},
+
+		_createMenuItem: function(){
+			return domConstruct.create("div", {
+				"class": "dijitReset dijitMenuItem" +(this.isLeftToRight() ? "" : " dijitMenuItemRtl"),
+				role: "option"
+			});
+		},
+
+		onHover: function(/*DomNode*/ node){
+			// summary:
+			//		Add hover CSS
+			domClass.add(node, "dijitMenuItemHover");
+		},
+
+		onUnhover: function(/*DomNode*/ node){
+			// summary:
+			//		Remove hover CSS
+			domClass.remove(node, "dijitMenuItemHover");
+		},
+
+		onSelect: function(/*DomNode*/ node){
+			// summary:
+			//		Add selected CSS
+			domClass.add(node, "dijitMenuItemSelected");
+		},
+
+		onDeselect: function(/*DomNode*/ node){
+			// summary:
+			//		Remove selected CSS
+			domClass.remove(node, "dijitMenuItemSelected");
+		},
+
+		_page: function(/*Boolean*/ up){
+			// summary:
+			//		Handles page-up and page-down keypresses
+
+			var scrollamount = 0;
+			var oldscroll = this.domNode.scrollTop;
+			var height = domStyle.get(this.domNode, "height");
+			// if no item is highlighted, highlight the first option
+			if(!this.getHighlightedOption()){
+				this.selectNextNode();
+			}
+			while(scrollamount<height){
+				var highlighted_option = this.getHighlightedOption();
+				if(up){
+					// stop at option 1
+					if(!highlighted_option.previousSibling ||
+						highlighted_option.previousSibling.style.display == "none"){
+						break;
+					}
+					this.selectPreviousNode();
+				}else{
+					// stop at last option
+					if(!highlighted_option.nextSibling ||
+						highlighted_option.nextSibling.style.display == "none"){
+						break;
+					}
+					this.selectNextNode();
+				}
+				// going backwards
+				var newscroll = this.domNode.scrollTop;
+				scrollamount += (newscroll-oldscroll)*(up ? -1:1);
+				oldscroll = newscroll;
+			}
+		},
+
+		handleKey: function(evt){
+			// summary:
+			//		Handle keystroke event forwarded from ComboBox, returning false if it's
+			//		a keystroke I recognize and process, true otherwise.
+			switch(evt.charOrCode){
+				case keys.DOWN_ARROW:
+					this.selectNextNode();
+					return false;
+				case keys.PAGE_DOWN:
+					this._page(false);
+					return false;
+				case keys.UP_ARROW:
+					this.selectPreviousNode();
+					return false;
+				case keys.PAGE_UP:
+					this._page(true);
+					return false;
+				default:
+					return true;
+			}
+		}
+	});
+});
diff --git a/dijit/form/_ComboBoxMenuMixin.js b/dijit/form/_ComboBoxMenuMixin.js
new file mode 100644
index 0000000..90ccd7d
--- /dev/null
+++ b/dijit/form/_ComboBoxMenuMixin.js
@@ -0,0 +1,191 @@
+define([
+	"dojo/_base/array", // array.forEach
+	"dojo/_base/declare", // declare
+	"dojo/dom-attr", // domAttr.set
+	"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
+	},
+
+	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(
+				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;
+	},
+
+	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
+				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;
+	},
+
+	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();
+		}
+	},
+
+	selectLastNode: function(){
+		this.inherited(arguments);
+		if(this.getHighlightedOption() == this.nextButton){
+			this.selectPreviousNode();
+		}
+	},
+
+	getHighlightedOption: function(){
+		return this._getSelectedAttr();
+	}
+});
+
+});
diff --git a/dijit/form/_DateTimeTextBox.js b/dijit/form/_DateTimeTextBox.js
index 406549b..29ecf18 100644
--- a/dijit/form/_DateTimeTextBox.js
+++ b/dijit/form/_DateTimeTextBox.js
@@ -1,28 +1,45 @@
-define("dijit/form/_DateTimeTextBox", ["dojo", "dijit", "text!dijit/form/templates/DropDownBox.html", "dojo/date", "dojo/date/locale", "dojo/date/stamp", "dijit/form/ValidationTextBox", "dijit/_HasDropDown"], function(dojo, dijit) {
-
-new Date("X"); // workaround for #11279, new Date("") == NaN
+define([
+	"dojo/date", // date date.compare
+	"dojo/date/locale", // locale.regexp
+	"dojo/date/stamp", // stamp.fromISOString stamp.toISOString
+	"dojo/_base/declare", // declare
+	"dojo/_base/lang", // lang.getObject
+	"./RangeBoundTextBox",
+	"../_HasDropDown",
+	"dojo/text!./templates/DropDownBox.html"
+], function(date, locale, stamp, declare, lang, RangeBoundTextBox, _HasDropDown, template){
 
 /*=====
-dojo.declare(
-	"dijit.form._DateTimeTextBox.__Constraints",
-	[dijit.form.RangeBoundTextBox.__Constraints, dojo.date.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 _HasDropDown = dijit._HasDropDown;
+	var RangeBoundTextBox = dijit.form.RangeBoundTextBox;
 =====*/
 
-dojo.declare(
-	"dijit.form._DateTimeTextBox",
-	[ dijit.form.RangeBoundTextBox, dijit._HasDropDown ],
-	{
+	// 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.
 
-		templateString: dojo.cache("dijit.form", "templates/DropDownBox.html"),
+		templateString: template,
 
 		// hasDownArrow: [const] Boolean
 		//		Set this textbox to display a down arrow button, to open the drop down list.
@@ -43,18 +60,23 @@ dojo.declare(
 
 		// Override ValidationTextBox.regExpGen().... we use a reg-ex generating function rather
 		// than a straight regexp to deal with locale  (plus formatting options too?)
-		regExpGen: dojo.date.locale.regexp,
+		regExpGen: locale.regexp,
 
 		// datePackage: String
 		//		JavaScript namespace to find calendar routines.	 Uses Gregorian calendar routines
 		//		at dojo.date, by default.
-		datePackage: "dojo.date",
+		datePackage: date,
+
+		postMixInProperties: function(){
+			this.inherited(arguments);
+			this._set("type", "text"); // in case type="date"|"time" was specified which messes up parse/format
+		},
 
 		// Override _FormWidget.compare() to work for dates/times
 		compare: function(/*Date*/ val1, /*Date*/ val2){
 			var isInvalid1 = this._isInvalidDate(val1);
 			var isInvalid2 = this._isInvalidDate(val2);
-			return isInvalid1 ? (isInvalid2 ? 0 : -1) : (isInvalid2 ? 1 : dojo.date.compare(val1, val2, this._selector));
+			return isInvalid1 ? (isInvalid2 ? 0 : -1) : (isInvalid2 ? 1 : date.compare(val1, val2, this._selector));
 		},
 
 		// flag to _HasDropDown to make drop down Calendar width == <input> width
@@ -83,7 +105,7 @@ dojo.declare(
 			if(val.toGregorian){
 				val = val.toGregorian();
 			}
-			return dojo.date.stamp.toISOString(val, options);
+			return stamp.toISOString(val, options);
 		},
 
 		// dropDownDefaultValue: Date
@@ -110,14 +132,14 @@ dojo.declare(
 		_selector: "",
 
 		constructor: function(/*Object*/ args){
-			var dateClass = args.datePackage ? args.datePackage + ".Date" : "Date";
-			this.dateClassObj = dojo.getObject(dateClass, false);
-			this.value = new this.dateClassObj("");
-
 			this.datePackage = args.datePackage || this.datePackage;
-			this.dateLocaleModule = dojo.getObject(this.datePackage + ".locale", false);
+			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;
-			this._invalidDate = dijit.form._DateTimeTextBox.prototype.value.toString();
+			this._invalidDate = this.constructor.prototype.value.toString();
 		},
 
 		buildRendering: function(){
@@ -139,7 +161,7 @@ dojo.declare(
 		_setConstraintsAttr: function(/*Object*/ constraints){
 			constraints.selector = this._selector;
 			constraints.fullYear = true; // see #5465 - always format with 4-digit years
-			var fromISO = dojo.date.stamp.fromISOString;
+			var fromISO = stamp.fromISOString;
 			if(typeof constraints.min == "string"){ constraints.min = fromISO(constraints.min); }
  			if(typeof constraints.max == "string"){ constraints.max = fromISO(constraints.max); }
 			this.inherited(arguments);
@@ -158,7 +180,7 @@ dojo.declare(
 			//		Sets the date on this textbox. Note: value can be a JavaScript Date literal or a string to be parsed.
 			if(value !== undefined){
 				if(typeof value == "string"){
-					value = dojo.date.stamp.fromISOString(value);
+					value = stamp.fromISOString(value);
 				}
 				if(this._isInvalidDate(value)){
 					value = null;
@@ -168,6 +190,9 @@ dojo.declare(
 				}
 			}
 			this.inherited(arguments);
+			if(this.value instanceof Date){
+				this.filterString = "";
+			}
 			if(this.dropDown){
 				this.dropDown.set('value', value, false);
 			}
@@ -184,8 +209,8 @@ dojo.declare(
 		_setDropDownDefaultValueAttr: function(/*Date*/ val){
 			if(this._isInvalidDate(val)){
 				// convert null setting into today's date, since there needs to be *some* default at all times.
-				 val = new this.dateClassObj()
-						}
+				 val = new this.dateClassObj();
+			}
 			this.dropDownDefaultValue = val;
 		},
 
@@ -194,17 +219,17 @@ dojo.declare(
 			if(this.dropDown){
 				this.dropDown.destroy();
 			}
-			var PopupProto = dojo.getObject(this.popupClass, false),
+			var PopupProto = lang.isString(this.popupClass) ? lang.getObject(this.popupClass, false) : this.popupClass,
 				textBox = this,
 				value = this.get("value");
 			this.dropDown = new PopupProto({
 				onChange: function(value){
-						// this will cause InlineEditBox and other handlers to do stuff so make sure it's last
-						dijit.form._DateTimeTextBox.superclass._setValueAttr.call(textBox, value, true);
-					},
-					id: this.id + "_popup",
-					dir: textBox.dir,
-					lang: textBox.lang,
+					// this will cause InlineEditBox and other handlers to do stuff so make sure it's last
+					textBox.set('value', value, true);
+				},
+				id: this.id + "_popup",
+				dir: textBox.dir,
+				lang: textBox.lang,
 				value: value,
 				currentFocus: !this._isInvalidDate(value) ? value : this.dropDownDefaultValue,
 					constraints: textBox.constraints,
@@ -229,9 +254,7 @@ dojo.declare(
 		_setDisplayedValueAttr: function(/*String*/ value, /*Boolean?*/ priorityChange){
 			this._setValueAttr(this.parse(value, this.constraints), priorityChange, value);
 		}
-	}
-);
-
+	});
 
-return dijit.form._DateTimeTextBox;
+	return _DateTimeTextBox;
 });
diff --git a/dijit/form/_ExpandingTextAreaMixin.js b/dijit/form/_ExpandingTextAreaMixin.js
new file mode 100644
index 0000000..74a65ee
--- /dev/null
+++ b/dijit/form/_ExpandingTextAreaMixin.js
@@ -0,0 +1,121 @@
+define([
+	"dojo/_base/declare", // declare
+	"dojo/dom-construct", // domConstruct.create
+	"dojo/_base/lang", // lang.hitch
+	"dojo/_base/window" // win.body
+], function(declare, domConstruct, lang, win){
+
+	// module:
+	//		dijit/form/_ExpandingTextAreaMixin
+	// summary:
+	//		Mixin for textarea widgets to add auto-expanding capability
+
+	// feature detection
+	var needsHelpShrinking;
+
+	return declare("dijit.form._ExpandingTextAreaMixin", null, {
+		// summary:
+		//		Mixin for textarea widgets to add auto-expanding capability
+
+		_setValueAttr: function(){
+			this.inherited(arguments);
+			this.resize();
+		},
+
+		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._resizeLater();
+		},
+
+		_onInput: function(e){
+			this.inherited(arguments);
+			this.resize();
+		},
+
+		_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.
+			//
+			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;
+		},
+
+		_resizeLater: function(){
+			setTimeout(lang.hitch(this, "resize"), 0);
+		},
+
+		resize: function(){
+			// summary:
+			//		Resizes the textarea vertically (should be called after a style/value change)
+			function textareaScrollHeight(){
+				var empty = false;
+				if(textarea.value === ''){
+					textarea.value = ' ';
+					empty = true;
+				}
+				var sh = textarea.scrollHeight;
+				if(empty){ textarea.value = ''; }
+				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 newHpx = newH + "px";
+				if(newHpx != textarea.style.height){
+					textarea.rows = 1;
+					textarea.style.height = newHpx;
+				}
+				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";
+					}
+					textarea.style.height = newHpx;
+				}
+				textarea.style.overflowY = textareaScrollHeight() > textarea.clientHeight ? "auto" : "hidden";
+			}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 a32be2a..f578cf7 100644
--- a/dijit/form/_FormMixin.js
+++ b/dijit/form/_FormMixin.js
@@ -1,45 +1,71 @@
-define("dijit/form/_FormMixin", ["dojo", "dijit", "dojo/window"], function(dojo, dijit) {
-
-dojo.declare("dijit.form._FormMixin", null, {
+define([
+	"dojo/_base/array", // array.every array.filter array.forEach array.indexOf array.map
+	"dojo/_base/declare", // declare
+	"dojo/_base/kernel", // kernel.deprecated
+	"dojo/_base/lang", // lang.hitch lang.isArray
+	"dojo/window" // winUtils.scrollIntoView
+], function(array, declare, kernel, lang, 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)
-	// description:
-	//		Can extract all the form widgets
-	//		values and combine them into a single javascript object, or alternately
-	//		take such an object and set the values for all the contained
-	//		form widgets
-
-/*=====
-	// value: Object
-	//		Name/value hash for each child widget with a name and value.
-	//		Child widgets without names are not part of the hash.
-	//
-	//		If there are multiple child widgets w/the same name, value is an array,
-	//		unless they are radio buttons in which case value is a scalar (since only
-	//		one radio button can be checked at a time).
-	//
-	//		If a child widget's name is a dot separated list (like a.b.c.d), it's a nested structure.
-	//
-	//		Example:
-	//	|	{ name: "John Smith", interests: ["sports", "movies"] }
-=====*/
-
-	// state: [readonly] String
-	//		Will be "Error" if one or more of the child widgets has an invalid value,
-	//		"Incomplete" if not all of the required child widgets are filled in.  Otherwise, "",
-	//		which indicates that the form is ready to be submitted.
-	state: "",
-
-	//	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}, ...])
-	//
-	//
+
+	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)
+		// description:
+		//		Can extract all the form widgets
+		//		values and combine them into a single javascript object, or alternately
+		//		take such an object and set the values for all the contained
+		//		form widgets
+
+	/*=====
+		// value: Object
+		//		Name/value hash for each child widget with a name and value.
+		//		Child widgets without names are not part of the hash.
+		//
+		//		If there are multiple child widgets w/the same name, value is an array,
+		//		unless they are radio buttons in which case value is a scalar (since only
+		//		one radio button can be checked at a time).
+		//
+		//		If a child widget's name is a dot separated list (like a.b.c.d), it's a nested structure.
+		//
+		//		Example:
+		//	|	{ name: "John Smith", interests: ["sports", "movies"] }
+	=====*/
+
+		// state: [readonly] String
+		//		Will be "Error" if one or more of the child widgets has an invalid value,
+		//		"Incomplete" if not all of the required child widgets are filled in.  Otherwise, "",
+		//		which indicates that the form is ready to be submitted.
+		state: "",
+
+		//	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){
+			// summary:
+			//		Returns all form widget descendants, searching through non-form child widgets like BorderContainer
+			var res = [];
+			array.forEach(children || this.getChildren(), function(child){
+				if("value" in child){
+					res.push(child);
+				}else{
+					res = res.concat(this._getDescendantFormWidgets(child.getChildren()));
+				}
+			}, this);
+			return res;
+		},
 
 		reset: function(){
-			dojo.forEach(this.getDescendants(), function(widget){
+			array.forEach(this._getDescendantFormWidgets(), function(widget){
 				if(widget.reset){
 					widget.reset();
 				}
@@ -55,14 +81,14 @@ dojo.declare("dijit.form._FormMixin", null, {
 			//		2 - it will call focus() on the first invalid
 			//			sub-widget
 			var didFocus = false;
-			return dojo.every(dojo.map(this.getDescendants(), function(widget){
+			return array.every(array.map(this._getDescendantFormWidgets(), function(widget){
 				// Need to set this so that "required" widgets get their
 				// state set.
 				widget._hasBeenBlurred = true;
 				var valid = widget.disabled || !widget.validate || widget.validate();
 				if(!valid && !didFocus){
 					// Set focus of the first non-valid widget
-					dojo.window.scrollIntoView(widget.containerNode || widget.domNode);
+					winUtils.scrollIntoView(widget.containerNode || widget.domNode);
 					widget.focus();
 					didFocus = true;
 				}
@@ -71,7 +97,7 @@ dojo.declare("dijit.form._FormMixin", null, {
 		},
 
 		setValues: function(val){
-			dojo.deprecated(this.declaredClass+"::setValues() is deprecated. Use set('value', val) instead.", "", "2.0");
+			kernel.deprecated(this.declaredClass+"::setValues() is deprecated. Use set('value', val) instead.", "", "2.0");
 			return this.set('value', val);
 		},
 		_setValueAttr: function(/*Object*/ obj){
@@ -80,7 +106,7 @@ dojo.declare("dijit.form._FormMixin", null, {
 
 			// generate map from name --> [list of widgets with that name]
 			var map = { };
-			dojo.forEach(this.getDescendants(), function(widget){
+			array.forEach(this._getDescendantFormWidgets(), function(widget){
 				if(!widget.name){ return; }
 				var entry = map[widget.name] || (map[widget.name] = [] );
 				entry.push(widget);
@@ -91,25 +117,25 @@ dojo.declare("dijit.form._FormMixin", null, {
 					continue;
 				}
 				var widgets = map[name],						// array of widgets w/this name
-					values = dojo.getObject(name, false, obj);	// list of values for those widgets
+					values = lang.getObject(name, false, obj);	// list of values for those widgets
 
 				if(values === undefined){
 					continue;
 				}
-				if(!dojo.isArray(values)){
+				if(!lang.isArray(values)){
 					values = [ values ];
 				}
 				if(typeof widgets[0].checked == 'boolean'){
 					// for checkbox/radio, values is a list of which widgets should be checked
-					dojo.forEach(widgets, function(w, i){
-						w.set('value', dojo.indexOf(values, w.value) != -1);
+					array.forEach(widgets, function(w){
+						w.set('value', array.indexOf(values, w.value) != -1);
 					});
 				}else if(widgets[0].multiple){
 					// it takes an array (e.g. multi-select)
 					widgets[0].set('value', values);
 				}else{
 					// otherwise, values is a list of values to be assigned sequentially to each widget
-					dojo.forEach(widgets, function(w, i){
+					array.forEach(widgets, function(w, i){
 						w.set('value', values[i]);
 					});
 				}
@@ -118,7 +144,7 @@ dojo.declare("dijit.form._FormMixin", null, {
 			/***
 			 * 	TODO: code for plain input boxes (this shouldn't run for inputs that are part of widgets)
 
-			dojo.forEach(this.containerNode.elements, function(element){
+			array.forEach(this.containerNode.elements, function(element){
 				if(element.name == ''){return};	// like "continue"
 				var namePath = element.name.split(".");
 				var myObj=obj;
@@ -160,20 +186,20 @@ dojo.declare("dijit.form._FormMixin", null, {
 				switch(element.type){
 					case "checkbox":
 						element.checked = (name in myObj) &&
-							dojo.some(myObj[name], function(val){ return val == element.value; });
+							array.some(myObj[name], function(val){ return val == element.value; });
 						break;
 					case "radio":
 						element.checked = (name in myObj) && myObj[name] == element.value;
 						break;
 					case "select-multiple":
 						element.selectedIndex=-1;
-						dojo.forEach(element.options, function(option){
-							option.selected = dojo.some(myObj[name], function(val){ return option.value == val; });
+						array.forEach(element.options, function(option){
+							option.selected = array.some(myObj[name], function(val){ return option.value == val; });
 						});
 						break;
 					case "select-one":
 						element.selectedIndex="0";
-						dojo.forEach(element.options, function(option){
+						array.forEach(element.options, function(option){
 							option.selected = option.value == myObj[name];
 						});
 						break;
@@ -186,13 +212,13 @@ dojo.declare("dijit.form._FormMixin", null, {
 				}
 	  		});
 	  		*/
-			
+
 			// Note: no need to call this._set("value", ...) as the child updates will trigger onChange events
 			// which I am monitoring.
 		},
 
 		getValues: function(){
-			dojo.deprecated(this.declaredClass+"::getValues() is deprecated. Use get('value') instead.", "", "2.0");
+			kernel.deprecated(this.declaredClass+"::getValues() is deprecated. Use get('value') instead.", "", "2.0");
 			return this.get('value');
 		},
 		_getValueAttr: function(){
@@ -205,14 +231,14 @@ dojo.declare("dijit.form._FormMixin", null, {
 			// 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 setTimout(..., 0) in _handleOnChange()
+			// and even if it did it would come too late due to the setTimeout(..., 0) 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.
 
 			// get widget values
 			var obj = { };
-			dojo.forEach(this.getDescendants(), function(widget){
+			array.forEach(this._getDescendantFormWidgets(), function(widget){
 				var name = widget.name;
 				if(!name || widget.disabled){ return; }
 
@@ -224,45 +250,45 @@ dojo.declare("dijit.form._FormMixin", null, {
 					if(/Radio/.test(widget.declaredClass)){
 						// radio button
 						if(value !== false){
-							dojo.setObject(name, value, obj);
+							lang.setObject(name, value, obj);
 						}else{
 							// give radio widgets a default of null
-							value = dojo.getObject(name, false, obj);
+							value = lang.getObject(name, false, obj);
 							if(value === undefined){
-								dojo.setObject(name, null, obj);
+								lang.setObject(name, null, obj);
 							}
 						}
 					}else{
 						// checkbox/toggle button
-						var ary=dojo.getObject(name, false, obj);
+						var ary=lang.getObject(name, false, obj);
 						if(!ary){
 							ary=[];
-							dojo.setObject(name, ary, obj);
+							lang.setObject(name, ary, obj);
 						}
 						if(value !== false){
 							ary.push(value);
 						}
 					}
 				}else{
-					var prev=dojo.getObject(name, false, obj);
+					var prev=lang.getObject(name, false, obj);
 					if(typeof prev != "undefined"){
-						if(dojo.isArray(prev)){
+						if(lang.isArray(prev)){
 							prev.push(value);
 						}else{
-							dojo.setObject(name, [prev, value], obj);
+							lang.setObject(name, [prev, value], obj);
 						}
 					}else{
 						// unique name
-						dojo.setObject(name, value, obj);
+						lang.setObject(name, value, obj);
 					}
 				}
 			});
 
 			/***
-			 * code for plain input boxes (see also dojo.formToObject, can we use that instead of this code?
+			 * code for plain input boxes (see also domForm.formToObject, can we use that instead of this code?
 			 * but it doesn't understand [] notation, presumably)
 			var obj = { };
-			dojo.forEach(this.containerNode.elements, function(elm){
+			array.forEach(this.containerNode.elements, function(elm){
 				if(!elm.name)	{
 					return;		// like "continue"
 				}
@@ -281,13 +307,13 @@ dojo.declare("dijit.form._FormMixin", null, {
 						if(typeof(myObj[nameA[0]][nameIndex]) == "undefined"){
 							myObj[nameA[0]][nameIndex] = { };
 						}
-					} else if(typeof(myObj[nameA[0]]) == "undefined"){
+					}else if(typeof(myObj[nameA[0]]) == "undefined"){
 						myObj[nameA[0]] = { }
 					} // if
 
 					if(nameA.length == 1){
 						myObj=myObj[nameA[0]];
-					} else{
+					}else{
 						myObj=myObj[nameA[0]][nameIndex];
 					} // if
 				} // for
@@ -295,15 +321,15 @@ dojo.declare("dijit.form._FormMixin", null, {
 				if((elm.type != "select-multiple" && elm.type != "checkbox" && elm.type != "radio") || (elm.type == "radio" && elm.checked)){
 					if(name == name.split("[")[0]){
 						myObj[name]=elm.value;
-					} else{
+					}else{
 						// can not set value when there is no name
 					}
-				} else if(elm.type == "checkbox" && elm.checked){
+				}else if(elm.type == "checkbox" && elm.checked){
 					if(typeof(myObj[name]) == 'undefined'){
 						myObj[name]=[ ];
 					}
 					myObj[name].push(elm.value);
-				} else if(elm.type == "select-multiple"){
+				}else if(elm.type == "select-multiple"){
 					if(typeof(myObj[name]) == 'undefined'){
 						myObj[name]=[ ];
 					}
@@ -327,7 +353,7 @@ dojo.declare("dijit.form._FormMixin", null, {
 			return this.state == "";
 		},
 
-		onValidStateChange: function(isValid){
+		onValidStateChange: function(/*Boolean*/ /*===== isValid =====*/){
 			// summary:
 			//		Stub function to connect to if you want to do something
 			//		(like disable/enable a submit button) when the valid
@@ -339,20 +365,20 @@ dojo.declare("dijit.form._FormMixin", null, {
 		_getState: function(){
 			// summary:
 			//		Compute what this.state should be based on state of children
-			var states = dojo.map(this._descendants, function(w){
+			var states = array.map(this._descendants, function(w){
 				return w.get("state") || "";
 			});
 
-			return dojo.indexOf(states, "Error") >= 0 ? "Error" :
-				dojo.indexOf(states, "Incomplete") >= 0 ? "Incomplete" : "";
+			return array.indexOf(states, "Error") >= 0 ? "Error" :
+				array.indexOf(states, "Incomplete") >= 0 ? "Incomplete" : "";
 		},
 
 		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.
-			dojo.forEach(this._childConnections || [], dojo.hitch(this, "disconnect"));
-			dojo.forEach(this._childWatches || [], function(w){ w.unwatch(); });
+			array.forEach(this._childConnections || [], lang.hitch(this, "disconnect"));
+			array.forEach(this._childWatches || [], function(w){ w.unwatch(); });
 		},
 
 		connectChildren: function(/*Boolean*/ inStartup){
@@ -369,10 +395,10 @@ dojo.declare("dijit.form._FormMixin", null, {
 			// Remove old connections, if any
 			this.disconnectChildren();
 
-			this._descendants = this.getDescendants();
+			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; } : dojo.hitch(this, "_set");
+			var set = inStartup ? function(name, val){ _this[name] = val; } : lang.hitch(this, "_set");
 			set("value", this.get("value"));
 			set("state", this._getState());
 
@@ -380,14 +406,14 @@ dojo.declare("dijit.form._FormMixin", null, {
 			// Form.state
 			var conns = (this._childConnections = []),
 				watches = (this._childWatches = []);
-			dojo.forEach(dojo.filter(this._descendants,
+			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.
-				dojo.forEach(["state", "disabled"], function(attr){
-					watches.push(widget.watch(attr, function(attr, oldVal, newVal){
+				array.forEach(["state", "disabled"], function(attr){
+					watches.push(widget.watch(attr, function(){
 						_this.set("state", _this._getState());
 					}));
 				});
@@ -397,7 +423,7 @@ dojo.declare("dijit.form._FormMixin", null, {
 			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()
@@ -412,8 +438,8 @@ dojo.declare("dijit.form._FormMixin", null, {
 					_this._set("value", _this.get("value"));
 				}, 10);
 			};
-			dojo.forEach(
-				dojo.filter(this._descendants, function(item){ return item.onChange; } ),
+			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,
@@ -446,7 +472,4 @@ dojo.declare("dijit.form._FormMixin", null, {
 		}
 
 	});
-
-
-return dijit.form._FormMixin;
 });
diff --git a/dijit/form/_FormSelectWidget.js b/dijit/form/_FormSelectWidget.js
index 92fbb87..c156475 100644
--- a/dijit/form/_FormSelectWidget.js
+++ b/dijit/form/_FormSelectWidget.js
@@ -1,4 +1,26 @@
-define("dijit/form/_FormSelectWidget", ["dojo", "dijit", "dijit/form/_FormWidget", "dojo/data/util/sorter"], function(dojo, dijit) {
+define([
+	"dojo/_base/array", // array.filter array.forEach array.map array.some
+	"dojo/aspect", // aspect.after
+	"dojo/data/util/sorter", // util.sorter.createSortFunction
+	"dojo/_base/declare", // declare
+	"dojo/dom", // dom.setSelectable
+	"dojo/dom-class", // domClass.toggle
+	"dojo/_base/kernel",	// _scopeName
+	"dojo/_base/lang", // lang.delegate lang.isArray lang.isObject lang.hitch
+	"dojo/query", // query
+	"./_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(){
@@ -18,7 +40,7 @@ dijit.form.__SelectOption = function(){
 }
 =====*/
 
-dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
+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.
@@ -35,7 +57,7 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 	options: null,
 
 	// store: dojo.data.api.Identity
-	//		A store which, at the very least impelements 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,
@@ -50,7 +72,7 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 
 	// onFetch: Function
 	//		A callback to do with an onFetch - but before any items are actually
-	//		iterated over (i.e. to filter even futher what you want to add)
+	//		iterated over (i.e. to filter even further what you want to add)
 	onFetch: null,
 
 	// sortByLabel: Boolean
@@ -101,13 +123,13 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		if(lookupValue === undefined){
 			return opts; // dijit.form.__SelectOption[]
 		}
-		if(dojo.isArray(lookupValue)){
-			return dojo.map(lookupValue, "return this.getOptions(item);", this); // dijit.form.__SelectOption[]
+		if(lang.isArray(lookupValue)){
+			return array.map(lookupValue, "return this.getOptions(item);", this); // dijit.form.__SelectOption[]
 		}
-		if(dojo.isObject(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(!dojo.some(this.options, function(o, idx){
+			if(!array.some(this.options, function(o, idx){
 				if(o === lookupValue ||
 					(o.value && o.value === lookupValue.value)){
 					lookupValue = idx;
@@ -127,7 +149,7 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 			}
 		}
 		if(typeof lookupValue == "number" && lookupValue >= 0 && lookupValue < l){
-			return this.options[lookupValue] // dijit.form.__SelectOption
+			return this.options[lookupValue]; // dijit.form.__SelectOption
 		}
 		return null; // null
 	},
@@ -138,9 +160,9 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		//		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(!dojo.isArray(option)){ option = [option]; }
-		dojo.forEach(option, function(i){
-			if(i && dojo.isObject(i)){
+		if(!lang.isArray(option)){ option = [option]; }
+		array.forEach(option, function(i){
+			if(i && lang.isObject(i)){
 				this.options.push(i);
 			}
 		}, this);
@@ -155,13 +177,13 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		//		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(!dojo.isArray(valueOrIdx)){ valueOrIdx = [valueOrIdx]; }
+		if(!lang.isArray(valueOrIdx)){ valueOrIdx = [valueOrIdx]; }
 		var oldOpts = this.getOptions(valueOrIdx);
-		dojo.forEach(oldOpts, function(i){
+		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 = dojo.filter(this.options, function(node, idx){
+				this.options = array.filter(this.options, function(node){
 					return (node.value !== i.value || node.label !== i.label);
 				});
 				this._removeOptionItem(i);
@@ -174,10 +196,10 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		// 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 yeild better performance since
+		//		in an array of new options will yield better performance since
 		//		the children will only be loaded once.
-		if(!dojo.isArray(newOption)){ newOption = [newOption]; }
-		dojo.forEach(newOption, function(i){
+		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]; }
@@ -195,8 +217,8 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		//		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 Identity,
-		//		and MAY implement Notification.
+		//		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
@@ -206,13 +228,14 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		fetchArgs = fetchArgs || {};
 		if(oStore !== store){
 			// Our store has changed, so update our notifications
-			dojo.forEach(this._notifyConnections || [], dojo.disconnect);
-			delete this._notifyConnections;
+			var h;
+			while(h = this._notifyConnections.pop()){ h.remove(); }
+
 			if(store && store.getFeatures()["dojo.data.api.Notification"]){
 				this._notifyConnections = [
-					dojo.connect(store, "onNew", this, "_onNewItem"),
-					dojo.connect(store, "onDelete", this, "_onDeleteItem"),
-					dojo.connect(store, "onSet", this, "_onSetItem")
+					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);
@@ -229,28 +252,28 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		// Add our new options
 		if(store){
 			this._loadingStore = true;
-			store.fetch(dojo.delegate(fetchArgs, {
+			store.fetch(lang.delegate(fetchArgs, {
 				onComplete: function(items, opts){
 					if(this.sortByLabel && !fetchArgs.sort && items.length){
-						items.sort(dojo.data.util.sorter.createSortFunction([{
+						items.sort(sorter.createSortFunction([{
 							attribute: store.getLabelAttributes(items[0])[0]
 						}], store));
 					}
-	
+
 					if(fetchArgs.onFetch){
 							items = fetchArgs.onFetch.call(this, items, opts);
 					}
 					// TODO: Add these guys as a batch, instead of separately
-					dojo.forEach(items, function(i){
+					array.forEach(items, function(i){
 						this._addOptionForItem(i);
 					}, this);
-	
+
 					// 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);
 					delete this._pendingValue;
-	
+
 					if(!this.loadChildrenOnOpen){
 						this._loadChildren();
 					}else{
@@ -284,30 +307,30 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 			return;
 		}
 		var opts = this.getOptions() || [];
-		if(!dojo.isArray(newValue)){
+		if(!lang.isArray(newValue)){
 			newValue = [newValue];
 		}
-		dojo.forEach(newValue, function(i, idx){
-			if(!dojo.isObject(i)){
+		array.forEach(newValue, function(i, idx){
+			if(!lang.isObject(i)){
 				i = i + "";
 			}
 			if(typeof i === "string"){
-				newValue[idx] = dojo.filter(opts, function(node){
+				newValue[idx] = array.filter(opts, function(node){
 					return node.value === i;
 				})[0] || {value: "", label: ""};
 			}
 		}, this);
 
 		// Make sure some sane default is set
-		newValue = dojo.filter(newValue, function(i){ return i && i.value; });
+		newValue = array.filter(newValue, function(i){ return i && i.value; });
 		if(!this.multiple && (!newValue[0] || !newValue[0].value) && opts.length){
 			newValue[0] = opts[0];
 		}
-		dojo.forEach(opts, function(i){
-			i.selected = dojo.some(newValue, function(v){ return v.value === i.value; });
+		array.forEach(opts, function(i){
+			i.selected = array.some(newValue, function(v){ return v.value === i.value; });
 		});
-		var val = dojo.map(newValue, function(i){ return i.value; }),
-			disp = dojo.map(newValue, function(i){ return i.label; });
+		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]);
@@ -319,10 +342,10 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		// summary:
 		//		returns the displayed value of the widget
 		var val = this.get("value");
-		if(!dojo.isArray(val)){
+		if(!lang.isArray(val)){
 			val = [val];
 		}
-		var ret = dojo.map(this.getOptions(val), function(v){
+		var ret = array.map(this.getOptions(val), function(v){
 			if(v && "label" in v){
 				return v.label;
 			}else if(v){
@@ -338,11 +361,11 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		//		Loads the children represented by this widget's options.
 		//		reset the menu to make it populatable on the next click
 		if(this._loadingStore){ return; }
-		dojo.forEach(this._getChildren(), function(child){
+		array.forEach(this._getChildren(), function(child){
 			child.destroyRecursive();
 		});
 		// Add each menu item
-		dojo.forEach(this.options, this._addOptionItem, this);
+		array.forEach(this.options, this._addOptionItem, this);
 
 		// Update states
 		this._updateSelection();
@@ -353,16 +376,16 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		//		Sets the "selected" class on the item for styling purposes
 		this._set("value", this._getValueFromOpts());
 		var val = this.value;
-		if(!dojo.isArray(val)){
+		if(!lang.isArray(val)){
 			val = [val];
 		}
 		if(val && val[0]){
-			dojo.forEach(this._getChildren(), function(child){
-				var isSelected = dojo.some(val, function(v){
+			array.forEach(this._getChildren(), function(child){
+				var isSelected = array.some(val, function(v){
 					return child.option && (v === child.option.value);
 				});
-				dojo.toggleClass(child.domNode, this.baseClass + "SelectedOption", isSelected);
-				dijit.setWaiState(child.domNode, "selected", isSelected);
+				domClass.toggle(child.domNode, this.baseClass + "SelectedOption", isSelected);
+				child.domNode.setAttribute("aria-selected", isSelected);
 			}, this);
 		}
 	},
@@ -374,7 +397,7 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		var opts = this.getOptions() || [];
 		if(!this.multiple && opts.length){
 			// Mirror what a select does - choose the first one
-			var opt = dojo.filter(opts, function(i){
+			var opt = array.filter(opts, function(i){
 				return i.selected;
 			})[0];
 			if(opt && opt.value){
@@ -385,7 +408,7 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 			}
 		}else if(this.multiple){
 			// Set value to be the sum of all selected
-			return dojo.map(dojo.filter(opts, function(i){
+			return array.map(array.filter(opts, function(i){
 				return i.selected;
 			}), function(i){
 				return i.value;
@@ -426,8 +449,8 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		var store = this.store;
 		if(!store.isItemLoaded(item)){
 			// We are not loaded - so let's load it and add later
-			store.loadItem({item: item, onComplete: function(i){
-				this._addOptionForItem(item);
+			store.loadItem({item: item, onItem: function(i){
+				this._addOptionForItem(i);
 			},
 			scope: this});
 			return;
@@ -441,11 +464,12 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		//		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);
-		dojo.setSelectable(this.focusNode, false);
+		dom.setSelectable(this.focusNode, false);
 	},
 
 	_fillContent: function(){
@@ -455,13 +479,13 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		//		function.
 		var opts = this.options;
 		if(!opts){
-			opts = this.options = this.srcNodeRef ? dojo.query(">",
+			opts = 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-" + dojo._scopeName + "-value") || node.getAttribute("value")),
+								value: (node.getAttribute("data-" + kernel._scopeName + "-value") || node.getAttribute("value")),
 										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?)
@@ -474,7 +498,7 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		if(!this.value){
 			this._set("value", this._getValueFromOpts());
 		}else if(this.multiple && typeof this.value == "string"){
-			this_set("value", this.value.split(","));
+			this._set("value", this.value.split(","));
 		}
 	},
 
@@ -496,7 +520,7 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		//		Connects in our store, if we have one defined
 		this.inherited(arguments);
 		var store = this.store, fetchArgs = {};
-		dojo.forEach(["query", "queryOptions", "onFetch"], function(i){
+		array.forEach(["query", "queryOptions", "onFetch"], function(i){
 			if(this[i]){
 				fetchArgs[i] = this[i];
 			}
@@ -513,11 +537,12 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 	destroy: function(){
 		// summary:
 		//		Clean up our connections
-		dojo.forEach(this._notifyConnections || [], dojo.disconnect);
+		var h;
+		while(h = this._notifyConnections.pop()){ h.remove(); }
 		this.inherited(arguments);
 	},
 
-	_addOptionItem: function(/*dijit.form.__SelectOption*/ option){
+	_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
@@ -525,13 +550,13 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		//		in the created option widget.
 	},
 
-	_removeOptionItem: function(/*dijit.form.__SelectOption*/ option){
+	_removeOptionItem: function(/*dijit.form.__SelectOption*/ /*===== option =====*/){
 		// summary:
 		//		User-overridable function which, for the given option, removes
 		//		its item from the select.
 	},
 
-	_setDisplay: function(/*String or String[]*/ newDisplay){
+	_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
@@ -551,7 +576,7 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		return this.getOptions(this.get("value"));
 	},
 
-	_pseudoLoadChildren: function(/*item[]*/ items){
+	_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.
@@ -567,6 +592,4 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 	}
 });
 
-
-return dijit.form._FormSelectWidget;
 });
diff --git a/dijit/form/_FormValueMixin.js b/dijit/form/_FormValueMixin.js
new file mode 100644
index 0000000..f04ea90
--- /dev/null
+++ b/dijit/form/_FormValueMixin.js
@@ -0,0 +1,95 @@
+define([
+	"dojo/_base/declare", // declare
+	"dojo/dom-attr", // domAttr.set
+	"dojo/keys", // keys.ESCAPE
+	"dojo/_base/sniff", // has("ie"), has("quirks")
+	"./_FormWidgetMixin"
+], function(declare, domAttr, keys, has, _FormWidgetMixin){
+
+/*=====
+	var _FormWidgetMixin = dijit.form._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.
+		// description:
+		//		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.
+
+		// readOnly: Boolean
+		//		Should this widget respond to user input?
+		//		In markup, this is specified as "readOnly".
+		//		Similar to disabled except readOnly form values are submitted.
+		readOnly: false,
+
+		_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){
+				this._lastValueReported = this._resetValue = this.value;
+			}
+		},
+
+		_setValueAttr: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
+			// summary:
+			//		Hook so set('value', value) works.
+			// description:
+			//		Sets the value of the widget.
+			//		If the value has changed, then fire onChange event, unless priorityChange
+			//		is specified as null (or false?)
+			this._handleOnChange(newValue, priorityChange);
+		},
+
+		_handleOnChange: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
+			// summary:
+			//		Called when the value of the widget has changed.  Saves the new value in this.value,
+			//		and calls onChange() if appropriate.   See _FormWidget._handleOnChange() for details.
+			this._set("value", newValue);
+			this.inherited(arguments);
+		},
+
+		undo: function(){
+			// summary:
+			//		Restore the value to the last value passed to onChange
+			this._setValueAttr(this._lastValueReported, false);
+		},
+
+		reset: function(){
+			// summary:
+			//		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
new file mode 100644
index 0000000..02b2810
--- /dev/null
+++ b/dijit/form/_FormValueWidget.js
@@ -0,0 +1,58 @@
+define([
+	"dojo/_base/declare", // declare
+	"dojo/_base/sniff", // has("ie")
+	"./_FormWidget",
+	"./_FormValueMixin"
+], function(declare, has, _FormWidget, _FormValueMixin){
+
+/*=====
+var _FormWidget = dijit.form._FormWidget;
+var _FormValueMixin = dijit.form._FormValueMixin;
+=====*/
+
+// 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(){
+		// 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;
+			}
+		}
+	}
+});
+
+});
diff --git a/dijit/form/_FormWidget.js b/dijit/form/_FormWidget.js
index 06fbe5a..bdb3118 100644
--- a/dijit/form/_FormWidget.js
+++ b/dijit/form/_FormWidget.js
@@ -1,7 +1,35 @@
-define("dijit/form/_FormWidget", ["dojo", "dijit", "dojo/window", "dijit/_Widget", "dijit/_Templated", "dijit/_CssStateMixin"], function(dojo, dijit) {
-
-dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated, dijit._CssStateMixin],
-	{
+define([
+	"dojo/_base/declare",	// declare
+	"dojo/_base/kernel", // kernel.deprecated
+	"dojo/ready",
+	"../_Widget",
+	"../_CssStateMixin",
+	"../_TemplatedMixin",
+	"./_FormWidgetMixin"
+], function(declare, 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
+// summary:
+//		FormWidget
+
+
+// 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.
@@ -13,353 +41,39 @@ dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated, dijit._
 	//
 	//		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: 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",
-
-	// 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,
-
-	// These mixins assume that the focus node is an INPUT, as many but not all _FormWidgets are.
-	attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
-		value: "focusNode",
-		id: "focusNode",
-		tabIndex: "focusNode",
-		alt: "focusNode",
-		title: "focusNode"
-	}),
-
-	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 attributeMap to set the name due to IE limitations, see #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);
-	},
-
-	postCreate: function(){
-		this.inherited(arguments);
-		this.connect(this.domNode, "onmousedown", "_onMouseDown");
-	},
-
-	_setDisabledAttr: function(/*Boolean*/ value){
-		this._set("disabled", value);
-		dojo.attr(this.focusNode, 'disabled', value);
-		if(this.valueNode){
-			dojo.attr(this.valueNode, 'disabled', value);
-		}
-		dijit.setWaiState(this.focusNode, "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 : "focusNode";
-			dojo.forEach(dojo.isArray(attachPointNames) ? attachPointNames : [attachPointNames], function(attachPointName){
-				var node = this[attachPointName];
-				// complex code because tabIndex=-1 on a <div> doesn't work on FF
-				if(dojo.isWebKit || dijit.hasDefaultTabStop(node)){	// see #11064 about webkit bug
-					node.setAttribute('tabIndex', "-1");
-				}else{
-					node.removeAttribute('tabIndex');
-				}
-			}, this);
-		}else{
-			if(this.tabIndex != ""){
-				this.focusNode.setAttribute('tabIndex', this.tabIndex);
-			}
-		}
-	},
-
 	setDisabled: function(/*Boolean*/ disabled){
 		// summary:
 		//		Deprecated.  Use set('disabled', ...) instead.
-		dojo.deprecated("setDisabled("+disabled+") is deprecated. Use set('disabled',"+disabled+") instead.", "", "2.0");
+		kernel.deprecated("setDisabled("+disabled+") is deprecated. Use set('disabled',"+disabled+") instead.", "", "2.0");
 		this.set('disabled', disabled);
 	},
 
-	_onFocus: function(e){
-		if(this.scrollOnFocus){
-			dojo.window.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 && (dojo.style(this.domNode, "display") != "none");
-	},
-
-	focus: function(){
-		// summary:
-		//		Put focus on this widget
-		if(!this.disabled){
-			dijit.focus(this.focusNode);
-		}
-	},
-
-	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){
-					clearTimeout(this._onChangeHandle);
-				}
-				// setTimout allows hidden value processing to run and
-				// also the onChange handler can safely adjust focus, etc
-				this._onChangeHandle = setTimeout(dojo.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);
-	},
-
 	setValue: function(/*String*/ value){
 		// summary:
 		//		Deprecated.  Use set('value', ...) instead.
-		dojo.deprecated("dijit.form._FormWidget:setValue("+value+") is deprecated.  Use set('value',"+value+") instead.", "", "2.0");
+		kernel.deprecated("dijit.form._FormWidget:setValue("+value+") is deprecated.  Use set('value',"+value+") instead.", "", "2.0");
 		this.set('value', value);
 	},
 
 	getValue: function(){
 		// summary:
 		//		Deprecated.  Use get('value') instead.
-		dojo.deprecated(this.declaredClass+"::getValue() is deprecated. Use get('value') instead.", "", "2.0");
+		kernel.deprecated(this.declaredClass+"::getValue() is deprecated. Use get('value') instead.", "", "2.0");
 		return this.get('value');
 	},
-	
-	_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.
-		if(!e.ctrlKey && dojo.mouseButtons.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(dojo.body(), "onmouseup", function(){
-				if (this.isFocusable()) {
-					this.focus();
-				}
-				this.disconnect(mouseUpConnector);
-			});
-		}
-	}
-});
-
-dojo.declare("dijit.form._FormValueWidget", dijit.form._FormWidget,
-{
-	// 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.
-	// TODO: unclear what that {value: ""} is for; FormWidget.attributeMap copies value to focusNode,
-	// so maybe {value: ""} is so the value *doesn't* get copied to focusNode?
-	// Seems like we really want value removed from attributeMap altogether
-	// (although there's no easy way to do that now)
-
-	// readOnly: Boolean
-	//		Should this widget respond to user input?
-	//		In markup, this is specified as "readOnly".
-	//		Similar to disabled except readOnly form values are submitted.
-	readOnly: false,
-
-	attributeMap: dojo.delegate(dijit.form._FormWidget.prototype.attributeMap, {
-		value: "",
-		readOnly: "focusNode"
-	}),
-
-	_setReadOnlyAttr: function(/*Boolean*/ value){
-		dojo.attr(this.focusNode, 'readOnly', value);
-		dijit.setWaiState(this.focusNode, "readonly", value);
-		this._set("readOnly", value);
-	},
-
-	postCreate: function(){
-		this.inherited(arguments);
-
-		if(dojo.isIE < 9 || (dojo.isIE && dojo.isQuirks)){ // 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){
-			this._lastValueReported = this._resetValue = this.value;
-		}
-	},
 
-	_setValueAttr: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
-		// summary:
-		//		Hook so set('value', value) works.
-		// description:
-		//		Sets the value of the widget.
-		//		If the value has changed, then fire onChange event, unless priorityChange
-		//		is specified as null (or false?)
-		this._handleOnChange(newValue, priorityChange);
-	},
-
-	_handleOnChange: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
-		// summary:
-		//		Called when the value of the widget has changed.  Saves the new value in this.value,
-		//		and calls onChange() if appropriate.   See _FormWidget._handleOnChange() for details.
-		this._set("value", newValue);
+	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);
 	},
 
-	undo: function(){
-		// summary:
-		//		Restore the value to the last value passed to onChange
-		this._setValueAttr(this._lastValueReported, false);
-	},
-
-	reset: function(){
-		// summary:
-		//		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 == dojo.keys.ESCAPE && !(e.ctrlKey || e.altKey || e.metaKey)){
-			var te;
-			if(dojo.isIE){
-				e.preventDefault(); // default behavior needs to be stopped here since keypress is too late
-				te = document.createEventObject();
-				te.keyCode = dojo.keys.ESCAPE;
-				te.shiftKey = e.shiftKey;
-				e.srcElement.fireEvent('onkeypress', te);
-			}
-		}
-	},
-
-	_layoutHackIE7: function(){
-		// summary:
-		//		Work around table sizing bugs on IE7 by forcing redraw
-
-		if(dojo.isIE == 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(e){
-							_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;
-			}
-		}
-	}
+	// 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
 });
 
-
-return dijit.form._FormWidget;
 });
diff --git a/dijit/form/_FormWidgetMixin.js b/dijit/form/_FormWidgetMixin.js
new file mode 100644
index 0000000..8d8198d
--- /dev/null
+++ b/dijit/form/_FormWidgetMixin.js
@@ -0,0 +1,231 @@
+define([
+	"dojo/_base/array", // array.forEach
+	"dojo/_base/declare", // declare
+	"dojo/dom-attr", // domAttr.set
+	"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/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");
+	},
+
+	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){
+					clearTimeout(this._onChangeHandle);
+				}
+				// 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();
+				}
+				this.disconnect(mouseUpConnector);
+			});
+		}
+	}
+});
+
+});
diff --git a/dijit/form/_ListBase.js b/dijit/form/_ListBase.js
new file mode 100644
index 0000000..7e832d4
--- /dev/null
+++ b/dijit/form/_ListBase.js
@@ -0,0 +1,123 @@
+define([
+	"dojo/_base/declare",	// declare
+	"dojo/window" // winUtils.scrollIntoView
+], function(declare, winUtils){
+
+// module:
+//		dijit/form/_ListBase
+// summary:
+//		Focus-less menu to handle UI events consistently
+
+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,
+
+	_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;
+	},
+
+	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);
+	},
+
+	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);
+	},
+
+	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;
+			}
+			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){
+				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);
+				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
new file mode 100644
index 0000000..896f866
--- /dev/null
+++ b/dijit/form/_ListMouseMixin.js
@@ -0,0 +1,96 @@
+define([
+	"dojo/_base/declare", // declare
+	"dojo/_base/event", // event.stop
+	"dojo/touch",
+	"./_ListBase"
+], function(declare, event, touch, _ListBase){
+
+/*=====
+var _ListBase = dijit.form._ListBase;
+=====*/
+
+// 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
+
+	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");
+	},
+
+	_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));
+	},
+
+	_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);
+		}
+	},
+
+	_onMouseOut: function(/*Event*/ /*===== evt ====*/){
+		if(this._hoveredNode){
+			this.onUnhover(this._hoveredNode);
+			if(this._getSelectedAttr() == this._hoveredNode){
+				this.onSelect(this._hoveredNode);
+			}
+			this._hoveredNode = null;
+		}
+		if(this._isDragging){
+			this._cancelDrag = (new Date()).getTime() + 1000; // cancel in 1 second if no _onMouseOver fires
+		}
+	},
+
+	_onMouseOver: function(/*Event*/ evt){
+		if(this._cancelDrag){
+			var time = (new Date()).getTime();
+			if(time > this._cancelDrag){
+				this._isDragging = false;
+			}
+			this._cancelDrag = null;
+		}
+		var node = this._getTarget(evt);
+		if(!node){ return; }
+		if(this._hoveredNode != node){
+			if(this._hoveredNode){
+				this._onMouseOut({ target: this._hoveredNode });
+			}
+			if(node && node.parentNode == this.containerNode){
+				if(this._isDragging){
+					this._setSelectedAttr(node);
+				}else{
+					this._hoveredNode = node;
+					this.onHover(node);
+				}
+			}
+		}
+	}
+});
+
+});
diff --git a/dijit/form/_RadioButtonMixin.js b/dijit/form/_RadioButtonMixin.js
new file mode 100644
index 0000000..f30bbad
--- /dev/null
+++ b/dijit/form/_RadioButtonMixin.js
@@ -0,0 +1,70 @@
+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){
+
+	// 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
+
+		// type: [private] String
+		//		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
+				lang.hitch(this, function(inputNode){
+					if(inputNode.name == this.name && inputNode.form == this.focusNode.form){
+						var widget = registry.getEnclosingWidget(inputNode);
+						if(widget){
+							ary.push(widget);
+						}
+					}
+				})
+			);
+			return ary;
+		},
+
+		_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(value){
+				array.forEach(this._getRelatedWidgets(), lang.hitch(this, function(widget){
+					if(widget != this && widget.checked){
+						widget.set('checked', false);
+					}
+				}));
+			}
+		},
+
+		_onClick: function(/*Event*/ e){
+			if(this.checked || this.disabled){ // nothing to do
+				event.stop(e);
+				return false;
+			}
+			if(this.readOnly){ // ignored by some browsers so we have to resync the DOM elements with widget values
+				event.stop(e);
+				array.forEach(this._getRelatedWidgets(), lang.hitch(this, function(widget){
+					domAttr.set(this.focusNode || this.domNode, 'checked', widget.checked);
+				}));
+				return false;
+			}
+			return this.inherited(arguments);
+		}
+	});
+});
diff --git a/dijit/form/_Spinner.js b/dijit/form/_Spinner.js
index dc29fd3..66250fc 100644
--- a/dijit/form/_Spinner.js
+++ b/dijit/form/_Spinner.js
@@ -1,9 +1,26 @@
-define("dijit/form/_Spinner", ["dojo", "dijit", "text!dijit/form/templates/Spinner.html", "dijit/form/ValidationTextBox"], function(dojo, dijit) {
-
-dojo.declare(
-	"dijit.form._Spinner",
-	dijit.form.RangeBoundTextBox,
-	{
+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",
+	"./RangeBoundTextBox",
+	"dojo/text!./templates/Spinner.html",
+	"./_TextBoxMixin"	// selectInputText
+], function(declare, event, keys, lang, has, typematic, RangeBoundTextBox, template, _TextBoxMixin){
+
+/*=====
+	var RangeBoundTextBox = dijit.form.RangeBoundTextBox;
+=====*/
+
+	// 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:
@@ -32,7 +49,7 @@ dojo.declare(
 		//		Adjust the value by this much when spinning using the PgUp/Dn keys
 		largeDelta: 10,
 
-		templateString: dojo.cache("dijit.form", "templates/Spinner.html"),
+		templateString: template,
 
 		baseClass: "dijitTextBox dijitSpinner",
 
@@ -43,10 +60,12 @@ dojo.declare(
 			"downArrowNode": "dijitDownArrowButton"
 		},
 
-		adjust: function(/*Object*/ val, /*Number*/ delta){
+		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.
+			// val: Object
+			// delta: Number
 			// tags:
 			//		protected extension
 			return val;
@@ -57,23 +76,21 @@ dojo.declare(
 			//		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);
-			dijit.selectInputText(this.textbox, this.textbox.value.length);
+			_TextBoxMixin.selectInputText(this.textbox, this.textbox.value.length);
 		},
 
-		_arrowReleased: function(/*Node*/ node){
+		_arrowReleased: function(/*Node*/ /*===== node =====*/){
 			// summary:
 			//		Handler for arrow button or arrow key being released
 			this._wheelTimer = null;
-			if(this.disabled || this.readOnly){ return; }
 		},
 
 		_typematicCallback: function(/*Number*/ count, /*DOMNode*/ node, /*Event*/ evt){
 			var inc=this.smallDelta;
 			if(node == this.textbox){
-				var k=dojo.keys;
 				var key = evt.charOrCode;
-				inc = (key == k.PAGE_UP || key == k.PAGE_DOWN) ? this.largeDelta : this.smallDelta;
-				node = (key == k.UP_ARROW || key == k.PAGE_UP) ? this.upArrowNode : this.downArrowNode;
+				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); }
@@ -84,11 +101,17 @@ dojo.declare(
 			// summary:
 			//		Mouse wheel listener where supported
 
-			dojo.stopEvent(evt);
+			event.stop(evt);
 			// FIXME: Safari bubbles
 
 			// be nice to DOH and scroll as much as the event says to
-			var scrollAmount = evt.detail ? (evt.detail * -1) : (evt.wheelDelta / 120);
+			var wheelDelta = evt.wheelDelta / 120;
+			if(Math.floor(wheelDelta) != wheelDelta){
+				// If not an int multiple of 120, then its touchpad scrolling.
+				// This can change very fast so just assume 1 wheel click to make it more manageable.
+				wheelDelta = evt.wheelDelta > 0 ? 1 : -1;
+			}
+			var scrollAmount = evt.detail ? (evt.detail * -1) : wheelDelta;
 			if(scrollAmount !== 0){
 				var node = this[(scrollAmount > 0 ? "upArrowNode" : "downArrowNode" )];
 
@@ -97,7 +120,7 @@ dojo.declare(
 				if(!this._wheelTimer){
 					clearTimeout(this._wheelTimer);
 				}
-				this._wheelTimer = setTimeout(dojo.hitch(this,"_arrowReleased",node), 50);
+				this._wheelTimer = setTimeout(lang.hitch(this,"_arrowReleased",node), 50);
 			}
 
 		},
@@ -106,14 +129,11 @@ dojo.declare(
 			this.inherited(arguments);
 
 			// extra listeners
-			this.connect(this.domNode, !dojo.isMozilla ? "onmousewheel" : 'DOMMouseScroll', "_mouseWheeled");
-			this._connects.push(dijit.typematic.addListener(this.upArrowNode, this.textbox, {charOrCode:dojo.keys.UP_ARROW,ctrlKey:false,altKey:false,shiftKey:false,metaKey:false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout, this.minimumTimeout));
-			this._connects.push(dijit.typematic.addListener(this.downArrowNode, this.textbox, {charOrCode:dojo.keys.DOWN_ARROW,ctrlKey:false,altKey:false,shiftKey:false,metaKey:false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout, this.minimumTimeout));
-			this._connects.push(dijit.typematic.addListener(this.upArrowNode, this.textbox, {charOrCode:dojo.keys.PAGE_UP,ctrlKey:false,altKey:false,shiftKey:false,metaKey:false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout, this.minimumTimeout));
-			this._connects.push(dijit.typematic.addListener(this.downArrowNode, this.textbox, {charOrCode:dojo.keys.PAGE_DOWN,ctrlKey:false,altKey:false,shiftKey:false,metaKey:false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout, this.minimumTimeout));
+			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));
 		}
-});
-
-
-return dijit.form._Spinner;
+	});
 });
diff --git a/dijit/form/_TextBoxMixin.js b/dijit/form/_TextBoxMixin.js
new file mode 100644
index 0000000..ad08b08
--- /dev/null
+++ b/dijit/form/_TextBoxMixin.js
@@ -0,0 +1,408 @@
+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;
+});
diff --git a/dijit/form/_ToggleButtonMixin.js b/dijit/form/_ToggleButtonMixin.js
new file mode 100644
index 0000000..4440984
--- /dev/null
+++ b/dijit/form/_ToggleButtonMixin.js
@@ -0,0 +1,51 @@
+define([
+	"dojo/_base/declare", // declare
+	"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);
+	}
+});
+
+});
diff --git a/dijit/form/nls/ComboBox.js b/dijit/form/nls/ComboBox.js
index da6e189..90ce9d3 100644
--- a/dijit/form/nls/ComboBox.js
+++ b/dijit/form/nls/ComboBox.js
@@ -25,6 +25,7 @@ define({ root:
 "ja": true,
 "it": true,
 "hu": true,
+"hr": true,
 "he": true,
 "fr": true,
 "fi": true,
@@ -34,5 +35,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"az": true,
 "ar": true
 });
diff --git a/dijit/form/nls/Textarea.js b/dijit/form/nls/Textarea.js
index f845b63..20d4253 100644
--- a/dijit/form/nls/Textarea.js
+++ b/dijit/form/nls/Textarea.js
@@ -1,6 +1,6 @@
 define({ root:
 //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: 'edit area',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'edit area frame'  // secondary title for editable IFRAME when focus is on outer container
@@ -28,6 +28,7 @@ define({ root:
 "ja": true,
 "it": true,
 "hu": true,
+"hr": true,
 "he": true,
 "fr": true,
 "fi": true,
@@ -37,5 +38,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"az": true,
 "ar": true
 });
diff --git a/dijit/form/nls/az/ComboBox.js b/dijit/form/nls/az/ComboBox.js
new file mode 100644
index 0000000..ab67dfe
--- /dev/null
+++ b/dijit/form/nls/az/ComboBox.js
@@ -0,0 +1,8 @@
+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
new file mode 100644
index 0000000..f99b83a
--- /dev/null
+++ b/dijit/form/nls/az/Textarea.js
@@ -0,0 +1,8 @@
+define(
+//begin v1.x content
+({
+	"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
new file mode 100644
index 0000000..9040e5f
--- /dev/null
+++ b/dijit/form/nls/az/validate.js
@@ -0,0 +1,9 @@
+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/hr/ComboBox.js b/dijit/form/nls/hr/ComboBox.js
new file mode 100644
index 0000000..262b0bd
--- /dev/null
+++ b/dijit/form/nls/hr/ComboBox.js
@@ -0,0 +1,6 @@
+define(
+({
+		previousMessage: "Prethodni izbori",
+		nextMessage: "Više izbora"
+})
+);
diff --git a/dijit/form/nls/hr/Textarea.js b/dijit/form/nls/hr/Textarea.js
new file mode 100644
index 0000000..3d8a46f
--- /dev/null
+++ b/dijit/form/nls/hr/Textarea.js
@@ -0,0 +1,9 @@
+define(
+// used by both the editor and textarea widgets to provide information to screen reader users
+({
+	iframeEditTitle: 'područje uređivanja',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
+	iframeFocusTitle: 'okvir područja uređivanja'  // 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/hr/validate.js b/dijit/form/nls/hr/validate.js
new file mode 100644
index 0000000..3b3b16f
--- /dev/null
+++ b/dijit/form/nls/hr/validate.js
@@ -0,0 +1,7 @@
+define(
+({
+	invalidMessage: "Unesena vrijednost nije važeća.",
+	missingMessage: "Potrebna je ova vrijednost.",
+	rangeMessage: "Ova vrijednost je izvan raspona."
+})
+);
diff --git a/dijit/form/nls/validate.js b/dijit/form/nls/validate.js
index 544440b..83d5a4b 100644
--- a/dijit/form/nls/validate.js
+++ b/dijit/form/nls/validate.js
@@ -26,6 +26,7 @@ define({ root:
 "ja": true,
 "it": true,
 "hu": true,
+"hr": true,
 "he": true,
 "fr": true,
 "fi": true,
@@ -35,5 +36,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"az": true,
 "ar": true
 });
diff --git a/dijit/form/templates/Button.html b/dijit/form/templates/Button.html
index 950331d..d167ac0 100644
--- a/dijit/form/templates/Button.html
+++ b/dijit/form/templates/Button.html
@@ -1,17 +1,17 @@
-<span class="dijit dijitReset dijitInline"
+<span class="dijit dijitReset dijitInline" role="presentation"
 	><span class="dijitReset dijitInline dijitButtonNode"
-		dojoAttachEvent="ondijitclick:_onButtonClick"
+		data-dojo-attach-event="ondijitclick:_onClick" role="presentation"
 		><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
-	><input ${!nameAttrSetting} type="${type}" value="${value}" class="dijitOffScreen" tabIndex="-1"
-		dojoAttachPoint="valueNode"
-/></span>
\ No newline at end of file
+	><input ${!nameAttrSetting} type="${type}" value="${value}" class="dijitOffScreen"
+		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 88e94f7..fd81fc2 100644
--- a/dijit/form/templates/CheckBox.html
+++ b/dijit/form/templates/CheckBox.html
@@ -2,6 +2,6 @@
 	><input
 	 	${!nameAttrSetting} type="${type}" ${checkedAttrSetting}
 		class="dijitReset dijitCheckBoxInput"
-		dojoAttachPoint="focusNode"
-	 	dojoAttachEvent="onclick:_onClick"
+		data-dojo-attach-point="focusNode"
+	 	data-dojo-attach-event="onclick:_onClick"
 /></div>
diff --git a/dijit/form/templates/ComboButton.html b/dijit/form/templates/ComboButton.html
index dcd5158..49eed10 100644
--- a/dijit/form/templates/ComboButton.html
+++ b/dijit/form/templates/ComboButton.html
@@ -1,23 +1,23 @@
 <table class="dijit dijitReset dijitInline dijitLeft"
 	cellspacing='0' cellpadding='0' role="presentation"
 	><tbody role="presentation"><tr role="presentation"
-		><td class="dijitReset dijitStretch dijitButtonNode" dojoAttachPoint="buttonNode" dojoAttachEvent="ondijitclick:_onButtonClick,onkeypress:_onButtonKeyPress"
+		><td class="dijitReset dijitStretch dijitButtonNode" data-dojo-attach-point="buttonNode" data-dojo-attach-event="ondijitclick:_onClick,onkeypress:_onButtonKeyPress"
 		><div id="${id}_button" class="dijitReset dijitButtonContents"
-			dojoAttachPoint="titleNode"
+			data-dojo-attach-point="titleNode"
 			role="button" aria-labelledby="${id}_label"
-			><div class="dijitReset dijitInline dijitIcon" dojoAttachPoint="iconNode" role="presentation"></div
-			><div class="dijitReset dijitInline dijitButtonText" id="${id}_label" dojoAttachPoint="containerNode" role="presentation"></div
+			><div class="dijitReset dijitInline dijitIcon" data-dojo-attach-point="iconNode" role="presentation"></div
+			><div class="dijitReset dijitInline dijitButtonText" id="${id}_label" data-dojo-attach-point="containerNode" role="presentation"></div
 		></div
 		></td
 		><td id="${id}_arrow" class='dijitReset dijitRight dijitButtonNode dijitArrowButton'
-			dojoAttachPoint="_popupStateNode,focusNode,_buttonNode"
-			dojoAttachEvent="onkeypress:_onArrowKeyPress"
+			data-dojo-attach-point="_popupStateNode,focusNode,_buttonNode"
+			data-dojo-attach-event="onkeypress:_onArrowKeyPress"
 			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}" dojoAttachPoint="valueNode"
+			><input ${!nameAttrSetting} type="${type}" value="${value}" data-dojo-attach-point="valueNode"
 		/></td></tr></tbody
 ></table>
diff --git a/dijit/form/templates/DropDownBox.html b/dijit/form/templates/DropDownBox.html
index ece3ae9..0314ad9 100644
--- a/dijit/form/templates/DropDownBox.html
+++ b/dijit/form/templates/DropDownBox.html
@@ -1,8 +1,8 @@
-<div class="dijit dijitReset dijitInlineTable dijitLeft"
+<div class="dijit dijitReset dijitInline dijitLeft"
 	id="widget_${id}"
 	role="combobox"
 	><div class='dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton dijitArrowButtonContainer'
-		dojoAttachPoint="_buttonNode, _popupStateNode" role="presentation"
+		data-dojo-attach-point="_buttonNode, _popupStateNode" role="presentation"
 		><input class="dijitReset dijitInputField dijitArrowButtonInner" value="▼ " type="text" tabIndex="-1" readonly="readonly" role="presentation"
 			${_buttonInputDisabled}
 	/></div
@@ -11,6 +11,6 @@
 	/></div
 	><div class="dijitReset dijitInputField dijitInputContainer"
 		><input class='dijitReset dijitInputInner' ${!nameAttrSetting} type="text" autocomplete="off"
-			dojoAttachPoint="textbox,focusNode" role="textbox" aria-haspopup="true"
+			data-dojo-attach-point="textbox,focusNode" role="textbox" aria-haspopup="true"
 	/></div
 ></div>
diff --git a/dijit/form/templates/DropDownButton.html b/dijit/form/templates/DropDownButton.html
index fde165d..56d2618 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'
-		dojoAttachEvent="ondijitclick:_onButtonClick" dojoAttachPoint="_buttonNode"
+		data-dojo-attach-event="ondijitclick:_onClick" data-dojo-attach-point="_buttonNode"
 		><span class="dijitReset dijitStretch dijitButtonContents"
-			dojoAttachPoint="focusNode,titleNode,_arrowWrapperNode"
+			data-dojo-attach-point="focusNode,titleNode,_arrowWrapperNode"
 			role="button" aria-haspopup="true" aria-labelledby="${id}_label"
 			><span class="dijitReset dijitInline dijitIcon"
-				dojoAttachPoint="iconNode"
+				data-dojo-attach-point="iconNode"
 			></span
 			><span class="dijitReset dijitInline dijitButtonText"
-				dojoAttachPoint="containerNode,_popupStateNode"
+				data-dojo-attach-point="containerNode,_popupStateNode"
 				id="${id}_label"
 			></span
 			><span class="dijitReset dijitInline dijitArrowButtonInner"></span
@@ -16,5 +16,5 @@
 		></span
 	></span
 	><input ${!nameAttrSetting} type="${type}" value="${value}" class="dijitOffScreen" tabIndex="-1"
-		dojoAttachPoint="valueNode"
+		data-dojo-attach-point="valueNode"
 /></span>
diff --git a/dijit/form/templates/HorizontalSlider.html b/dijit/form/templates/HorizontalSlider.html
index 3117f68..9fd16d4 100644
--- a/dijit/form/templates/HorizontalSlider.html
+++ b/dijit/form/templates/HorizontalSlider.html
@@ -1,37 +1,37 @@
-<table class="dijit dijitReset dijitSlider dijitSliderH" cellspacing="0" cellpadding="0" border="0" rules="none" dojoAttachEvent="onkeypress:_onKeyPress,onkeyup:_onKeyUp"
+<table class="dijit dijitReset dijitSlider dijitSliderH" cellspacing="0" cellpadding="0" border="0" rules="none" data-dojo-attach-event="onkeypress:_onKeyPress,onkeyup:_onKeyUp"
 	><tr class="dijitReset"
 		><td class="dijitReset" colspan="2"></td
-		><td dojoAttachPoint="topDecoration" class="dijitReset dijitSliderDecoration dijitSliderDecorationT dijitSliderDecorationH"></td
+		><td data-dojo-attach-point="topDecoration" class="dijitReset dijitSliderDecoration dijitSliderDecorationT dijitSliderDecorationH"></td
 		><td class="dijitReset" colspan="2"></td
 	></tr
 	><tr class="dijitReset"
 		><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerH"
-			><div class="dijitSliderDecrementIconH" style="display:none" dojoAttachPoint="decrementButton"><span class="dijitSliderButtonInner">-</span></div
+			><div class="dijitSliderDecrementIconH" style="display:none" data-dojo-attach-point="decrementButton"><span class="dijitSliderButtonInner">-</span></div
 		></td
 		><td class="dijitReset"
-			><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperH dijitSliderLeftBumper" dojoAttachEvent="onmousedown:_onClkDecBumper"></div
+			><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperH dijitSliderLeftBumper" data-dojo-attach-event="press:_onClkDecBumper"></div
 		></td
 		><td class="dijitReset"
-			><input dojoAttachPoint="valueNode" type="hidden" ${!nameAttrSetting}
-			/><div class="dijitReset dijitSliderBarContainerH" role="presentation" dojoAttachPoint="sliderBarContainer"
-				><div role="presentation" dojoAttachPoint="progressBar" class="dijitSliderBar dijitSliderBarH dijitSliderProgressBar dijitSliderProgressBarH" dojoAttachEvent="onmousedown:_onBarClick"
+			><input data-dojo-attach-point="valueNode" type="hidden" ${!nameAttrSetting}
+			/><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 dojoAttachPoint="sliderHandle,focusNode" class="dijitSliderImageHandle dijitSliderImageHandleH" dojoAttachEvent="onmousedown:_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" valuemin="${minimum}" valuemax="${maximum}"></div
 					></div
 				></div
-				><div role="presentation" dojoAttachPoint="remainingBar" class="dijitSliderBar dijitSliderBarH dijitSliderRemainingBar dijitSliderRemainingBarH" dojoAttachEvent="onmousedown:_onBarClick"></div
+				><div role="presentation" data-dojo-attach-point="remainingBar" class="dijitSliderBar dijitSliderBarH dijitSliderRemainingBar dijitSliderRemainingBarH" data-dojo-attach-event="press:_onBarClick"></div
 			></div
 		></td
 		><td class="dijitReset"
-			><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperH dijitSliderRightBumper" dojoAttachEvent="onmousedown:_onClkIncBumper"></div
+			><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperH dijitSliderRightBumper" data-dojo-attach-event="press:_onClkIncBumper"></div
 		></td
 		><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerH"
-			><div class="dijitSliderIncrementIconH" style="display:none" dojoAttachPoint="incrementButton"><span class="dijitSliderButtonInner">+</span></div
+			><div class="dijitSliderIncrementIconH" style="display:none" data-dojo-attach-point="incrementButton"><span class="dijitSliderButtonInner">+</span></div
 		></td
 	></tr
 	><tr class="dijitReset"
 		><td class="dijitReset" colspan="2"></td
-		><td dojoAttachPoint="containerNode,bottomDecoration" class="dijitReset dijitSliderDecoration dijitSliderDecorationB dijitSliderDecorationH"></td
+		><td data-dojo-attach-point="containerNode,bottomDecoration" class="dijitReset dijitSliderDecoration dijitSliderDecorationB dijitSliderDecorationH"></td
 		><td class="dijitReset" colspan="2"></td
 	></tr
 ></table>
diff --git a/dijit/form/templates/Select.html b/dijit/form/templates/Select.html
index f671701..9e917ab 100644
--- a/dijit/form/templates/Select.html
+++ b/dijit/form/templates/Select.html
@@ -1,12 +1,12 @@
 <table class="dijit dijitReset dijitInline dijitLeft"
-	dojoAttachPoint="_buttonNode,tableNode,focusNode" cellspacing='0' cellpadding='0'
+	data-dojo-attach-point="_buttonNode,tableNode,focusNode" cellspacing='0' cellpadding='0'
 	role="combobox" aria-haspopup="true"
 	><tbody role="presentation"><tr role="presentation"
 		><td class="dijitReset dijitStretch dijitButtonContents dijitButtonNode" role="presentation"
-			><span class="dijitReset dijitInline dijitButtonText"  dojoAttachPoint="containerNode,_popupStateNode"></span
-			><input type="hidden" ${!nameAttrSetting} dojoAttachPoint="valueNode" value="${value}" aria-hidden="true"
+			><span class="dijitReset dijitInline dijitButtonText"  data-dojo-attach-point="containerNode,_popupStateNode"></span
+			><input type="hidden" ${!nameAttrSetting} data-dojo-attach-point="valueNode" value="${value}" aria-hidden="true"
 		/></td><td class="dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton"
-				dojoAttachPoint="titleNode" role="presentation"
+				data-dojo-attach-point="titleNode" role="presentation"
 			><div class="dijitReset dijitArrowButtonInner" role="presentation"></div
 			><div class="dijitReset dijitArrowButtonChar" role="presentation">▼</div
 		></td
diff --git a/dijit/form/templates/Spinner.html b/dijit/form/templates/Spinner.html
index 34f1b1d..468613d 100644
--- a/dijit/form/templates/Spinner.html
+++ b/dijit/form/templates/Spinner.html
@@ -1,16 +1,16 @@
-<div class="dijit dijitReset dijitInlineTable dijitLeft"
+<div class="dijit dijitReset dijitInline dijitLeft"
 	id="widget_${id}" role="presentation"
 	><div class="dijitReset dijitButtonNode dijitSpinnerButtonContainer"
 		><input class="dijitReset dijitInputField dijitSpinnerButtonInner" type="text" tabIndex="-1" readonly="readonly" role="presentation"
 		/><div class="dijitReset dijitLeft dijitButtonNode dijitArrowButton dijitUpArrowButton"
-			dojoAttachPoint="upArrowNode"
+			data-dojo-attach-point="upArrowNode"
 			><div class="dijitArrowButtonInner"
 				><input class="dijitReset dijitInputField" value="▲" type="text" tabIndex="-1" readonly="readonly" role="presentation"
 					${_buttonInputDisabled}
 			/></div
 		></div
 		><div class="dijitReset dijitLeft dijitButtonNode dijitArrowButton dijitDownArrowButton"
-			dojoAttachPoint="downArrowNode"
+			data-dojo-attach-point="downArrowNode"
 			><div class="dijitArrowButtonInner"
 				><input class="dijitReset dijitInputField" value="▼" type="text" tabIndex="-1" readonly="readonly" role="presentation"
 					${_buttonInputDisabled}
@@ -21,7 +21,7 @@
 		><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' dojoAttachPoint="textbox,focusNode" type="${type}" dojoAttachEvent="onkeypress:_onKeyPress"
+		><input class='dijitReset dijitInputInner' data-dojo-attach-point="textbox,focusNode" type="${type}" data-dojo-attach-event="onkeypress:_onKeyPress"
 			role="spinbutton" autocomplete="off" ${!nameAttrSetting}
 	/></div
 ></div>
diff --git a/dijit/form/templates/TextBox.html b/dijit/form/templates/TextBox.html
index 3b3a602..fd543c6 100644
--- a/dijit/form/templates/TextBox.html
+++ b/dijit/form/templates/TextBox.html
@@ -1,6 +1,6 @@
 <div class="dijit dijitReset dijitInline dijitLeft" id="widget_${id}" role="presentation"
 	><div class="dijitReset dijitInputField dijitInputContainer"
-		><input class="dijitReset dijitInputInner" dojoAttachPoint='textbox,focusNode' autocomplete="off"
+		><input class="dijitReset dijitInputInner" data-dojo-attach-point='textbox,focusNode' autocomplete="off"
 			${!nameAttrSetting} type='${type}'
 	/></div
 ></div>
diff --git a/dijit/form/templates/ValidationTextBox.html b/dijit/form/templates/ValidationTextBox.html
index f1e80ba..d49dd8c 100644
--- a/dijit/form/templates/ValidationTextBox.html
+++ b/dijit/form/templates/ValidationTextBox.html
@@ -1,10 +1,10 @@
-<div class="dijit dijitReset dijitInlineTable dijitLeft"
+<div class="dijit dijitReset dijitInline dijitLeft"
 	id="widget_${id}" role="presentation"
 	><div class='dijitReset dijitValidationContainer'
 		><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" dojoAttachPoint='textbox,focusNode' autocomplete="off"
+		><input class="dijitReset dijitInputInner" data-dojo-attach-point='textbox,focusNode' autocomplete="off"
 			${!nameAttrSetting} type='${type}'
 	/></div
 ></div>
diff --git a/dijit/form/templates/VerticalSlider.html b/dijit/form/templates/VerticalSlider.html
index 989ca29..0c72ed9 100644
--- a/dijit/form/templates/VerticalSlider.html
+++ b/dijit/form/templates/VerticalSlider.html
@@ -1,44 +1,44 @@
-<table class="dijit dijitReset dijitSlider dijitSliderV" cellspacing="0" cellpadding="0" border="0" rules="none" dojoAttachEvent="onkeypress:_onKeyPress,onkeyup:_onKeyUp"
+<table class="dijit dijitReset dijitSlider dijitSliderV" cellspacing="0" cellpadding="0" border="0" rules="none" data-dojo-attach-event="onkeypress:_onKeyPress,onkeyup:_onKeyUp"
 	><tr class="dijitReset"
 		><td class="dijitReset"></td
 		><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerV"
-			><div class="dijitSliderIncrementIconV" style="display:none" dojoAttachPoint="decrementButton"><span class="dijitSliderButtonInner">+</span></div
+			><div class="dijitSliderIncrementIconV" style="display:none" data-dojo-attach-point="decrementButton"><span class="dijitSliderButtonInner">+</span></div
 		></td
 		><td class="dijitReset"></td
 	></tr
 	><tr class="dijitReset"
 		><td class="dijitReset"></td
 		><td class="dijitReset"
-			><center><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperV dijitSliderTopBumper" dojoAttachEvent="onmousedown:_onClkIncBumper"></div></center
+			><center><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperV dijitSliderTopBumper" data-dojo-attach-event="press:_onClkIncBumper"></div></center
 		></td
 		><td class="dijitReset"></td
 	></tr
 	><tr class="dijitReset"
-		><td dojoAttachPoint="leftDecoration" class="dijitReset dijitSliderDecoration dijitSliderDecorationL dijitSliderDecorationV"></td
+		><td data-dojo-attach-point="leftDecoration" class="dijitReset dijitSliderDecoration dijitSliderDecorationL dijitSliderDecorationV"></td
 		><td class="dijitReset dijitSliderDecorationC" style="height:100%;"
-			><input dojoAttachPoint="valueNode" type="hidden" ${!nameAttrSetting}
-			/><center class="dijitReset dijitSliderBarContainerV" role="presentation" dojoAttachPoint="sliderBarContainer"
-				><div role="presentation" dojoAttachPoint="remainingBar" class="dijitSliderBar dijitSliderBarV dijitSliderRemainingBar dijitSliderRemainingBarV" dojoAttachEvent="onmousedown:_onBarClick"><!--#5629--></div
-				><div role="presentation" dojoAttachPoint="progressBar" class="dijitSliderBar dijitSliderBarV dijitSliderProgressBar dijitSliderProgressBarV" dojoAttachEvent="onmousedown:_onBarClick"
+			><input data-dojo-attach-point="valueNode" type="hidden" ${!nameAttrSetting}
+			/><center class="dijitReset dijitSliderBarContainerV" role="presentation" data-dojo-attach-point="sliderBarContainer"
+				><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 dojoAttachPoint="sliderHandle,focusNode" class="dijitSliderImageHandle dijitSliderImageHandleV" dojoAttachEvent="onmousedown:_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" valuemin="${minimum}" valuemax="${maximum}"></div
 					></div
 				></div
 			></center
 		></td
-		><td dojoAttachPoint="containerNode,rightDecoration" class="dijitReset dijitSliderDecoration dijitSliderDecorationR dijitSliderDecorationV"></td
+		><td data-dojo-attach-point="containerNode,rightDecoration" class="dijitReset dijitSliderDecoration dijitSliderDecorationR dijitSliderDecorationV"></td
 	></tr
 	><tr class="dijitReset"
 		><td class="dijitReset"></td
 		><td class="dijitReset"
-			><center><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperV dijitSliderBottomBumper" dojoAttachEvent="onmousedown:_onClkDecBumper"></div></center
+			><center><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperV dijitSliderBottomBumper" data-dojo-attach-event="press:_onClkDecBumper"></div></center
 		></td
 		><td class="dijitReset"></td
 	></tr
 	><tr class="dijitReset"
 		><td class="dijitReset"></td
 		><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerV"
-			><div class="dijitSliderDecrementIconV" style="display:none" dojoAttachPoint="incrementButton"><span class="dijitSliderButtonInner">-</span></div
+			><div class="dijitSliderDecrementIconV" style="display:none" data-dojo-attach-point="incrementButton"><span class="dijitSliderButtonInner">-</span></div
 		></td
 		><td class="dijitReset"></td
 	></tr
diff --git a/dijit/hccss.js b/dijit/hccss.js
new file mode 100644
index 0000000..58db4e9
--- /dev/null
+++ b/dijit/hccss.js
@@ -0,0 +1,52 @@
+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){
+
+	// 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
+
+			// 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());
+
+			// 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);
+				}
+			}
+		});
+	}
+});
diff --git a/dijit/icons/commonIcons.css b/dijit/icons/commonIcons.css
index 6f27492..8d0060e 100644
--- a/dijit/icons/commonIcons.css
+++ b/dijit/icons/commonIcons.css
@@ -123,7 +123,7 @@ The 16 x 16px icons in these sprites are action and object type images which can
 }
 
 /*Action icons*/
-.dijitIconSave { background-position: 0px; }
+.dijitIconSave { background-position: 0; }
 .dijitIconPrint { background-position: -16px; }
 .dijitIconCut { background-position: -32px; }
 .dijitIconCopy { background-position: -48px; }
@@ -139,7 +139,6 @@ The 16 x 16px icons in these sprites are action and object type images which can
 .dijitIconConfigure { background-position: -208px; }
 .dijitIconSearch { background-position: -224px; }
 .dijitIconError { background-position: -496px; } 
-/* .dijitIconError is also called .dijitContentPaneError icon in the claro/common.css and is applied to HREF url errors that render in a dialog box with the error messsage */
 
 /*Object icons*/
 .dijitIconApplication { background-position: -240px; }
@@ -162,3 +161,11 @@ The 16 x 16px icons in these sprites are action and object type images which can
 .dijitIconFolderClosed, .dijitFolderClosed { background-position: -464px; }
 .dijitIconFolderOpen, .dijitFolderOpened { background-position: -480px; }
 
+/*Loading animation*/
+.dijitIconLoading {
+	background:url('images/loadingAnimation_rtl.gif') no-repeat;
+	height: 20px;
+	width: 20px;
+}
+
+
diff --git a/dijit/icons/commonIcons_rtl.css b/dijit/icons/commonIcons_rtl.css
index 4d4c26f..8d3ea03 100644
--- a/dijit/icons/commonIcons_rtl.css
+++ b/dijit/icons/commonIcons_rtl.css
@@ -38,7 +38,7 @@ The 16 x 16px icons in these sprites are action and object type images which can
 .dijitRtl .dijitIconFolderClosed,
 .dijitRtl .dijitFolderOpened,
 .dijitRtl .dijitIconFolderOpen,
-.dijitRtl .dijitIconError, .dijitRtl .dijitContentPaneError { 
+.dijitRtl .dijitIconError { 
 	background-image: url('images/commonIconsObjActEnabled_rtl.png'); /* Contains both object and action icons in a sprite image for the enabled state.  */
 	width: 16px;
 	height: 16px;
@@ -78,7 +78,7 @@ The 16 x 16px icons in these sprites are action and object type images which can
 .dj_ie6 .dijitRtl .dijitIconFolderClosed,
 .dj_ie6 .dijitRtl .dijitFolderOpened,
 .dj_ie6 .dijitRtl .dijitIconFolderOpen,
-.dj_ie6 .dijitRtl .dijitIconError, .dj_ie6 .dijitRtl .dijitContentPaneError {
+.dj_ie6 .dijitRtl .dijitIconError {
 	background-image: url('images/commonIconsObjActEnabled8bit_rtl.png');
 }
 
@@ -116,12 +116,6 @@ The 16 x 16px icons in these sprites are action and object type images which can
 .dijitRtl .dijitDisabled .dijitIconFolderClosed,
 .dijitRtl .dijitDisabled .dijitFolderOpened,
 .dijitRtl .dijitDisabled .dijitIconFolderOpen,
-.dijitRtl .dijitDisabled .dijitIconError, .dijitRtl .dijitDisabled .dijitContentPaneError {
+.dijitRtl .dijitDisabled .dijitIconError {
 	background-image: url('images/commonIconsObjActDisabled_rtl.png'); /* Contains both object and action icons as a sprite image for the disabled state. These would be used by buttons and menus.   */
 }
-
-
-/*For Claro and future themes.*/
-.dijitRtl .dijitContentPaneLoading {
-	background:url('images/loadingAnimation_rtl.gif') no-repeat;
-}
diff --git a/dijit/icons/editorIcons.css b/dijit/icons/editorIcons.css
index 8c667ac..1889e99 100644
--- a/dijit/icons/editorIcons.css
+++ b/dijit/icons/editorIcons.css
@@ -19,7 +19,7 @@ editorIcons.css contains references to the dijit editor widget icons. There are
 }
 
 
-.dijitEditorIconSep { background-position: 0px; }
+.dijitEditorIconSep { background-position: 0; }
 .dijitEditorIconSave { background-position: -18px; }
 .dijitEditorIconPrint { background-position: -36px; }
 .dijitEditorIconCut { background-position: -54px; }
diff --git a/dijit/layout/AccordionContainer.js b/dijit/layout/AccordionContainer.js
index 23a16fc..67cf66b 100644
--- a/dijit/layout/AccordionContainer.js
+++ b/dijit/layout/AccordionContainer.js
@@ -1,51 +1,269 @@
-define("dijit/layout/AccordionContainer", ["dojo", "dijit", "text!dijit/layout/templates/AccordionButton.html", "dijit/_Container", "dijit/_Templated", "dijit/_CssStateMixin", "dijit/layout/StackContainer", "dijit/layout/ContentPane", "dijit/layout/AccordionPane"], function(dojo, dijit) {
-
-//dojo.require("dijit.layout.AccordionPane ");	// for back compat, remove for 2.0
-
-// Design notes:
-//
-// An AccordionContainer is a StackContainer, but each child (typically ContentPane)
-// is wrapped in a _AccordionInnerContainer.   This is hidden from the caller.
-//
-// The resulting markup will look like:
-//
-//	<div class=dijitAccordionContainer>
-//		<div class=dijitAccordionInnerContainer>	(one pane)
-//				<div class=dijitAccordionTitle>		(title bar) ... </div>
-//				<div class=dijtAccordionChildWrapper>   (content pane) </div>
-//		</div>
-//	</div>
-//
-// Normally the dijtAccordionChildWrapper is hidden for all but one child (the shown
-// child), so the space for the content pane is all the title bars + the one dijtAccordionChildWrapper,
-// which on claro has a 1px border plus a 2px bottom margin.
-//
-// During animation there are two dijtAccordionChildWrapper's shown, so we need
-// to compensate for that.
-
-dojo.declare(
-	"dijit.layout.AccordionContainer",
-	dijit.layout.StackContainer,
-	{
+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/topic", // publish
+	"../focus",			// focus.focus()
+	"../_base/manager",	// manager.defaultDuration
+	"dojo/ready",
+	"../_Widget",
+	"../_Container",
+	"../_TemplatedMixin",
+	"../_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;
+=====*/
+
+	// 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:
+	//
+	// An AccordionContainer is a StackContainer, but each child (typically ContentPane)
+	// is wrapped in a _AccordionInnerContainer.   This is hidden from the caller.
+	//
+	// The resulting markup will look like:
+	//
+	//	<div class=dijitAccordionContainer>
+	//		<div class=dijitAccordionInnerContainer>	(one pane)
+	//				<div class=dijitAccordionTitle>		(title bar) ... </div>
+	//				<div class=dijtAccordionChildWrapper>   (content pane) </div>
+	//		</div>
+	//	</div>
+	//
+	// Normally the dijtAccordionChildWrapper is hidden for all but one child (the shown
+	// child), so the space for the content pane is all the title bars + the one dijtAccordionChildWrapper,
+	// which on claro has a 1px border plus a 2px bottom margin.
+	//
+	// 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.
+		//		Internal widget used by AccordionContainer.
+		// tags:
+		//		private
+
+		templateString: template,
+
+		// label: String
+		//		Title of the pane
+		label: "",
+		_setLabelAttr: {node: "titleTextNode", type: "innerHTML" },
+
+		// title: String
+		//		Tooltip that appears on hover
+		title: "",
+		_setTitleAttr: {node: "titleTextNode", type: "attribute", attribute: "title"},
+
+		// iconClassAttr: String
+		//		CSS class for icon to left of label
+		iconClassAttr: "",
+		_setIconClassAttr: { node: "iconNode", type: "class" },
+
+		baseClass: "dijitAccordionTitle",
+
+		getParent: function(){
+			// summary:
+			//		Returns the AccordionContainer parent.
+			// tags:
+			//		private
+			return this.parent;
+		},
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			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);
+		},
+
+		getTitleHeight: function(){
+			// summary:
+			//		Returns the height of the title dom node.
+			return domGeometry.getMarginSize(this.domNode).h;	// Integer
+		},
+
+		// TODO: maybe the parent should set these methods directly rather than forcing the code
+		// into the button widget?
+		_onTitleClick: function(){
+			// summary:
+			//		Callback when someone clicks my title.
+			var parent = this.getParent();
+				parent.selectChild(this.contentWidget, true);
+				focus.focus(this.focusNode);
+		},
+
+		_onTitleKeyPress: function(/*Event*/ evt){
+			return this.getParent()._onKeyPress(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("tabIndex", isSelected ? "0" : "-1");
+		}
+	});
+
+	var AccordionInnerContainer = declare("dijit.layout._AccordionInnerContainer", [_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: null,
+=====*/
+
+/*=====
+		// contentWidget: dijit._Widget
+		//		Pointer to the real child widget
+	 	contentWidget: null,
+=====*/
+
+		baseClass: "dijitAccordionInnerContainer",
+
+		// tell nested layout widget that we will take care of sizing
+		isLayoutContainer: true,
+
+		buildRendering: function(){
+			// Builds a template like:
+			//	<div class=dijitAccordionInnerContainer>
+			//		Button
+			//		<div class=dijitAccordionChildWrapper>
+			//			ContentPane
+			//		</div>
+			//	</div>
+
+			// Create wrapper div, placed where the child is now
+			this.domNode = domConstruct.place("<div class='" + this.baseClass +
+				"' role='presentation'>", this.contentWidget.domNode, "after");
+
+			// wrapper div's first child is the button widget (ie, the title bar)
+			var child = this.contentWidget,
+				cls = lang.isString(this.buttonWidget) ? lang.getObject(this.buttonWidget) : this.buttonWidget;
+			this.button = child._buttonWidget = (new cls({
+				contentWidget: child,
+				label: child.title,
+				title: child.tooltip,
+				dir: child.dir,
+				lang: child.lang,
+				textDir: child.textDir,
+				iconClass: child.iconClass,
+				id: child.id + "_button",
+				parent: this.parent
+			})).placeAt(this.domNode);
+
+			// 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);
+			domConstruct.place(this.contentWidget.domNode, this.containerNode);
+		},
+
+		postCreate: function(){
+			this.inherited(arguments);
+
+			// Map changes in content widget's title etc. to changes in the button
+			var button = this.button;
+			this._contentWidgetWatches = [
+				this.contentWidget.watch('title', lang.hitch(this, function(name, oldValue, newValue){
+					button.set("label", newValue);
+				})),
+				this.contentWidget.watch('tooltip', lang.hitch(this, function(name, oldValue, newValue){
+					button.set("title", newValue);
+				})),
+				this.contentWidget.watch('iconClass', lang.hitch(this, function(name, oldValue, newValue){
+					button.set("iconClass", newValue);
+				}))
+			];
+		},
+
+		_setSelectedAttr: function(/*Boolean*/ isSelected){
+			this._set("selected", isSelected);
+			this.button.set("selected", isSelected);
+			if(isSelected){
+				var cw = this.contentWidget;
+				if(cw.onSelected){ cw.onSelected(); }
+			}
+		},
+
+		startup: function(){
+			// Called by _Container.addChild()
+			this.contentWidget.startup();
+		},
+
+		destroy: function(){
+			this.button.destroyRecursive();
+
+			array.forEach(this._contentWidgetWatches || [], function(w){ w.unwatch(); });
+
+			delete this.contentWidget._buttonWidget;
+			delete this.contentWidget._wrapperWidget;
+
+			this.inherited(arguments);
+		},
+
+		destroyDescendants: function(/*Boolean*/ preserveDom){
+			// since getChildren isn't working for me, have to code this manually
+			this.contentWidget.destroyRecursive(preserveDom);
+		}
+	});
+
+	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 dojoType="dijit.layout.AccordionContainer">
-		//	|		<div dojoType="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 dojoType="dijit.layout.ContentPane" title="pane 2">
+		//	|		<div data-dojo-type="dijit.layout.ContentPane" title="pane 2">
 		//	|			<p>This is some text</p>
 		//	|		</div>
 		//	|	</div>
 
 		// duration: Integer
 		//		Amount of time (in ms) it takes to slide panes
-		duration: dijit.defaultDuration,
+		duration: manager.defaultDuration,
 
 		// buttonWidget: [const] String
 		//		The name of the widget used to display the title of each pane
-		buttonWidget: "dijit.layout._AccordionButton",
+		buttonWidget: AccordionButton,
 
 /*=====
 		// _verticalSpace: Number
@@ -58,7 +276,7 @@ dojo.declare(
 		buildRendering: function(){
 			this.inherited(arguments);
 			this.domNode.style.overflow = "hidden";		// TODO: put this in dijit.css
-			dijit.setWaiRole(this.domNode, "tablist");	// TODO: put this in template
+			this.domNode.setAttribute("role", "tablist");	// TODO: put this in template
 		},
 
 		startup: function(){
@@ -77,23 +295,26 @@ dojo.declare(
 			// Set the height of the open pane based on what room remains.
 
 			var openPane = this.selectedChildWidget;
-			
+
 			if(!openPane){ return;}
 
 			// space taken up by title, plus wrapper div (with border/margin) for open pane
 			var wrapperDomNode = openPane._wrapperWidget.domNode,
-				wrapperDomNodeMargin = dojo._getMarginExtents(wrapperDomNode),
-				wrapperDomNodePadBorder = dojo._getPadBorderExtents(wrapperDomNode),
+				wrapperDomNodeMargin = domGeometry.getMarginExtents(wrapperDomNode),
+				wrapperDomNodePadBorder = domGeometry.getPadBorderExtents(wrapperDomNode),
 				wrapperContainerNode = openPane._wrapperWidget.containerNode,
-				wrapperContainerNodeMargin = dojo._getMarginExtents(wrapperContainerNode),
-				wrapperContainerNodePadBorder = dojo._getPadBorderExtents(wrapperContainerNode),
+				wrapperContainerNodeMargin = domGeometry.getMarginExtents(wrapperContainerNode),
+				wrapperContainerNodePadBorder = domGeometry.getPadBorderExtents(wrapperContainerNode),
 				mySize = this._contentBox;
 
 			// get cumulative height of all the unselected title bars
 			var totalCollapsedHeight = 0;
-			dojo.forEach(this.getChildren(), function(child){
+			array.forEach(this.getChildren(), function(child){
 	            if(child != openPane){
-					totalCollapsedHeight += dojo._getMarginSize(child._wrapperWidget.domNode).h;
+					// 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).
+					totalCollapsedHeight += domGeometry.getMarginSize(child._wrapperWidget.domNode).h;
 				}
 			});
 			this._verticalSpace = mySize.h - totalCollapsedHeight - wrapperDomNodeMargin.h
@@ -116,12 +337,13 @@ dojo.declare(
 			// Overrides _LayoutWidget._setupChild().
 			// Put wrapper widget around the child widget, showing title
 
-			child._wrapperWidget = new dijit.layout._AccordionInnerContainer({
+			child._wrapperWidget = AccordionInnerContainer({
 				contentWidget: child,
 				buttonWidget: this.buttonWidget,
 				id: child.id + "_wrapper",
 				dir: child.dir,
 				lang: child.lang,
+				textDir: child.textDir,
 				parent: this
 			});
 
@@ -135,17 +357,25 @@ dojo.declare(
 				// the new child inside another child's wrapper.
 
 				// First add in child as a direct child of this AccordionContainer
-				dojo.place(child.domNode, this.containerNode, insertIndex);
+				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
-				dojo.publish(this.id+"-addChild", [child, insertIndex]);
+				topic.publish(this.id+"-addChild", child, insertIndex);	// publish
 				this.layout();
 				if(!this.selectedChildWidget){
 					this.selectChild(child);
@@ -164,19 +394,19 @@ dojo.declare(
 			// Replace wrapper widget with true child widget (ContentPane etc.).
 			// This step only happens if the AccordionContainer has been started; otherwise there's no wrapper.
 			if(child._wrapperWidget){
-				dojo.place(child.domNode, child._wrapperWidget.domNode, "after");
+				domConstruct.place(child.domNode, child._wrapperWidget.domNode, "after");
 				child._wrapperWidget.destroy();
 				delete child._wrapperWidget;
 			}
 
-			dojo.removeClass(child.domNode, "dijitHidden");
+			domClass.remove(child.domNode, "dijitHidden");
 
 			this.inherited(arguments);
 		},
 
 		getChildren: function(){
 			// Overrides _Container.getChildren() to return content panes rather than internal AccordionInnerContainer panes
-			return dojo.map(this.inherited(arguments), function(child){
+			return array.map(this.inherited(arguments), function(child){
 				return child.declaredClass == "dijit.layout._AccordionInnerContainer" ? child.contentWidget : child;
 			}, this);
 		},
@@ -185,7 +415,7 @@ dojo.declare(
 			if(this._animation){
 				this._animation.stop();
 			}
-			dojo.forEach(this.getChildren(), function(child){
+			array.forEach(this.getChildren(), function(child){
 				// If AccordionContainer has been started, then each child has a wrapper widget which
 				// also needs to be destroyed.
 				if(child._wrapperWidget){
@@ -212,7 +442,7 @@ dojo.declare(
 		_transition: function(/*dijit._Widget?*/ newWidget, /*dijit._Widget?*/ oldWidget, /*Boolean*/ animate){
 			// Overrides StackContainer._transition() to provide sliding of title bars etc.
 
-			if(dojo.isIE < 8){
+			if(has("ie") < 8){
 				// workaround animation bugs by not animating; not worth supporting animation for IE6 & 7
 				animate = false;
 			}
@@ -253,13 +483,13 @@ dojo.declare(
 				// which on claro takes up 4px extra space (compared to stable AccordionContainer).
 				// Have to compensate for that by immediately shrinking the pane being closed.
 				var wrapperContainerNode = newWidget._wrapperWidget.containerNode,
-					wrapperContainerNodeMargin = dojo._getMarginExtents(wrapperContainerNode),
-					wrapperContainerNodePadBorder = dojo._getPadBorderExtents(wrapperContainerNode),
+					wrapperContainerNodeMargin = domGeometry.getMarginExtents(wrapperContainerNode),
+					wrapperContainerNodePadBorder = domGeometry.getPadBorderExtents(wrapperContainerNode),
 					animationHeightOverhead = wrapperContainerNodeMargin.h + wrapperContainerNodePadBorder.h;
 
 				oldContents.style.height = (self._verticalSpace - animationHeightOverhead) + "px";
 
-				this._animation = new dojo.Animation({
+				this._animation = new fx.Animation({
 					node: newContents,
 					duration: this.duration,
 					curve: [1, this._verticalSpace - animationHeightOverhead - 1],
@@ -294,191 +524,30 @@ dojo.declare(
 			if(this.disabled || e.altKey || !(fromTitle || e.ctrlKey)){
 				return;
 			}
-			var k = dojo.keys,
-				c = e.charOrCode;
-			if((fromTitle && (c == k.LEFT_ARROW || c == k.UP_ARROW)) ||
-					(e.ctrlKey && c == k.PAGE_UP)){
+			var c = e.charOrCode;
+			if((fromTitle && (c == keys.LEFT_ARROW || c == keys.UP_ARROW)) ||
+					(e.ctrlKey && c == keys.PAGE_UP)){
 				this._adjacent(false)._buttonWidget._onTitleClick();
-				dojo.stopEvent(e);
-			}else if((fromTitle && (c == k.RIGHT_ARROW || c == k.DOWN_ARROW)) ||
-					(e.ctrlKey && (c == k.PAGE_DOWN || c == k.TAB))){
+				event.stop(e);
+			}else if((fromTitle && (c == keys.RIGHT_ARROW || c == keys.DOWN_ARROW)) ||
+					(e.ctrlKey && (c == keys.PAGE_DOWN || c == keys.TAB))){
 				this._adjacent(true)._buttonWidget._onTitleClick();
-				dojo.stopEvent(e);
+				event.stop(e);
 			}
 		}
+	});
+
+	// Back compat w/1.6, remove for 2.0
+	if(!kernel.isAsync){
+		ready(0, function(){
+			var requires = ["dijit/layout/AccordionPane"];
+			require(requires);	// use indirection so modules not rolled into a build
+		});
 	}
-);
-
-dojo.declare("dijit.layout._AccordionInnerContainer",
-	[dijit._Widget, dijit._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: String
-		//		Name of 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,
-=====*/
-
-		baseClass: "dijitAccordionInnerContainer",
-
-		// tell nested layout widget that we will take care of sizing
-		isContainer: true,
-		isLayoutContainer: true,
-
-		buildRendering: function(){
-			// Builds a template like:
-			//	<div class=dijitAccordionInnerContainer>
-			//		Button
-			//		<div class=dijitAccordionChildWrapper>
-			//			ContentPane
-			//		</div>
-			//	</div>
-
-			// Create wrapper div, placed where the child is now
-			this.domNode = dojo.place("<div class='" + this.baseClass + "'>", this.contentWidget.domNode, "after");
-			
-			// wrapper div's first child is the button widget (ie, the title bar)
-			var child = this.contentWidget,
-				cls = dojo.getObject(this.buttonWidget);
-			this.button = child._buttonWidget = (new cls({
-				contentWidget: child,
-				label: child.title,
-				title: child.tooltip,
-				dir: child.dir,
-				lang: child.lang,
-				iconClass: child.iconClass,
-				id: child.id + "_button",
-				parent: this.parent
-			})).placeAt(this.domNode);
-			
-			// and then the actual content widget (changing it from prior-sibling to last-child),
-			// wrapped by a <div class=dijitAccordionChildWrapper>
-			this.containerNode = dojo.place("<div class='dijitAccordionChildWrapper' style='display:none'>", this.domNode);
-			dojo.place(this.contentWidget.domNode, this.containerNode);
-		},
-
-		postCreate: function(){
-			this.inherited(arguments);
-
-			// Map changes in content widget's title etc. to changes in the button
-			var button = this.button;
-			this._contentWidgetWatches = [
-				this.contentWidget.watch('title', dojo.hitch(this, function(name, oldValue, newValue){
-					button.set("label", newValue);
-				})),
-				this.contentWidget.watch('tooltip', dojo.hitch(this, function(name, oldValue, newValue){
-					button.set("title", newValue);
-				})),
-				this.contentWidget.watch('iconClass', dojo.hitch(this, function(name, oldValue, newValue){
-					button.set("iconClass", newValue);
-				}))
-			];
-		},
-
-		_setSelectedAttr: function(/*Boolean*/ isSelected){
-			this._set("selected", isSelected);
-			this.button.set("selected", isSelected);
-			if(isSelected){
-				var cw = this.contentWidget;
-				if(cw.onSelected){ cw.onSelected(); }
-			}
-		},
-
-		startup: function(){
-			// Called by _Container.addChild()
-			this.contentWidget.startup();
-		},
-
-		destroy: function(){
-			this.button.destroyRecursive();
-
-			dojo.forEach(this._contentWidgetWatches || [], function(w){ w.unwatch(); });
-
-			delete this.contentWidget._buttonWidget;
-			delete this.contentWidget._wrapperWidget;
-
-			this.inherited(arguments);
-		},
-		
-		destroyDescendants: function(){
-			// since getChildren isn't working for me, have to code this manually
-			this.contentWidget.destroyRecursive();
-		}
-});
-
-dojo.declare("dijit.layout._AccordionButton",
-	[dijit._Widget, dijit._Templated, dijit._CssStateMixin],
-	{
-	// summary:
-	//		The title bar to click to open up an accordion pane.
-	//		Internal widget used by AccordionContainer.
-	// tags:
-	//		private
-
-	templateString: dojo.cache("dijit.layout", "templates/AccordionButton.html"),
-	attributeMap: dojo.mixin(dojo.clone(dijit.layout.ContentPane.prototype.attributeMap), {
-		label: {node: "titleTextNode", type: "innerHTML" },
-		title: {node: "titleTextNode", type: "attribute", attribute: "title"},
-		iconClass: { node: "iconNode", type: "class" }
-	}),
-
-	baseClass: "dijitAccordionTitle",
-
-	getParent: function(){
-		// summary:
-		//		Returns the AccordionContainer parent.
-		// tags:
-		//		private
-		return this.parent;
-	},
-
-	buildRendering: function(){
-		this.inherited(arguments);
-		var titleTextNodeId = this.id.replace(' ','_');
-		dojo.attr(this.titleTextNode, "id", titleTextNodeId+"_title");
-		dijit.setWaiState(this.focusNode, "labelledby", dojo.attr(this.titleTextNode, "id"));
-		dojo.setSelectable(this.domNode, false);
-	},
-
-	getTitleHeight: function(){
-		// summary:
-		//		Returns the height of the title dom node.
-		return dojo._getMarginSize(this.domNode).h;	// Integer
-	},
-
-	// TODO: maybe the parent should set these methods directly rather than forcing the code
-	// into the button widget?
-	_onTitleClick: function(){
-		// summary:
-		//		Callback when someone clicks my title.
-		var parent = this.getParent();
-			parent.selectChild(this.contentWidget, true);
-			dijit.focus(this.focusNode);
-	},
-
-	_onTitleKeyPress: function(/*Event*/ evt){
-		return this.getParent()._onKeyPress(evt, this.contentWidget);
-	},
-
-	_setSelectedAttr: function(/*Boolean*/ isSelected){
-		this._set("selected", isSelected);
-		dijit.setWaiState(this.focusNode, "expanded", isSelected);
-		dijit.setWaiState(this.focusNode, "selected", isSelected);
-		this.focusNode.setAttribute("tabIndex", isSelected ? "0" : "-1");
-	}
-});
 
+	// For monkey patching
+	AccordionContainer._InnerContainer = AccordionInnerContainer;
+	AccordionContainer._Button = AccordionButton;
 
-return dijit.layout.AccordionContainer;
+	return AccordionContainer;
 });
diff --git a/dijit/layout/AccordionPane.js b/dijit/layout/AccordionPane.js
index aceef97..9068242 100644
--- a/dijit/layout/AccordionPane.js
+++ b/dijit/layout/AccordionPane.js
@@ -1,21 +1,31 @@
-define("dijit/layout/AccordionPane", ["dojo", "dijit", "dijit/layout/ContentPane"], function(dojo, dijit) {
+define([
+	"dojo/_base/declare", // declare
+	"dojo/_base/kernel", // kernel.deprecated
+	"./ContentPane"
+], function(declare, kernel, ContentPane){
 
-dojo.declare("dijit.layout.AccordionPane", dijit.layout.ContentPane, {
+/*=====
+	var ContentPane = dijit.layout.ContentPane;
+=====*/
+
+	// module:
+	//		dijit/layout/AccordionPane
 	// summary:
 	//		Deprecated widget.   Use `dijit.layout.ContentPane` instead.
-	// tags:
-	//		deprecated
-
-	constructor: function(){
-		dojo.deprecated("dijit.layout.AccordionPane deprecated, use ContentPane instead", "", "2.0");
-	},
 
-	onSelected: function(){
+	return declare("dijit.layout.AccordionPane", ContentPane, {
 		// summary:
-		//		called when this pane is selected
-	}
-});
+		//		Deprecated widget.   Use `dijit.layout.ContentPane` instead.
+		// tags:
+		//		deprecated
 
+		constructor: function(){
+			kernel.deprecated("dijit.layout.AccordionPane deprecated, use ContentPane instead", "", "2.0");
+		},
 
-return dijit.layout.AccordionPane;
+		onSelected: function(){
+			// summary:
+			//		called when this pane is selected
+		}
+	});
 });
diff --git a/dijit/layout/BorderContainer.js b/dijit/layout/BorderContainer.js
index 74db0e1..5e0e3a4 100644
--- a/dijit/layout/BorderContainer.js
+++ b/dijit/layout/BorderContainer.js
@@ -1,10 +1,253 @@
-define("dijit/layout/BorderContainer", ["dojo", "dijit", "dijit/layout/_LayoutWidget", "dojo/cookie", "dijit/_Templated"], function(dojo, dijit) {
+define([
+	"dojo/_base/array", // array.filter array.forEach array.map
+	"dojo/cookie", // cookie
+	"dojo/_base/declare", // declare
+	"dojo/dom-class", // domClass.add domClass.remove domClass.toggle
+	"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/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){
 
-dojo.declare(
-	"dijit.layout.BorderContainer",
-	dijit.layout._LayoutWidget,
+/*=====
+	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;
+			}
+		}
+	},
+
+	_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],
+			spaceAvailable = domGeometry.getMarginBox(center.domNode)[dim];	// can expand until center is crushed to 0
+
+		return Math.min(this.child.maxSize, childSize + spaceAvailable);
+	},
+
+	_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;
+		}
+
+		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);
+	}
+});
+
+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"));
+	}
+});
+
+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:
@@ -23,13 +266,13 @@ dojo.declare(
 	//		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 conrol layout precedence of horizontal vs. vertical panes.
+	//		instead of the design attribute to control layout precedence of horizontal vs. vertical panes.
 	// example:
-	// |	<div dojoType="dijit.layout.BorderContainer" design="sidebar" gutters="false"
+	// |	<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design: 'sidebar', gutters: false"
 	// |            style="width: 400px; height: 300px;">
-	// |		<div dojoType="dijit.layout.ContentPane" region="top">header text</div>
-	// |		<div dojoType="dijit.layout.ContentPane" region="right" splitter="true" style="width: 200px;">table of contents</div>
-	// |		<div dojoType="dijit.layout.ContentPane" region="center">client area</div>
+	// |		<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
@@ -55,9 +298,9 @@ dojo.declare(
 
 	baseClass: "dijitBorderContainer",
 
-	// _splitterClass: String
+	// _splitterClass: Function||String
 	// 		Optional hook to override the default Splitter widget used by BorderContainer
-	_splitterClass: "dijit.layout._Splitter",
+	_splitterClass: _Splitter,
 
 	postMixInProperties: function(){
 		// change class name to indicate that BorderContainer is being used purely for
@@ -70,7 +313,7 @@ dojo.declare(
 
 	startup: function(){
 		if(this._started){ return; }
-		dojo.forEach(this.getChildren(), this._setupChild, this);
+		array.forEach(this.getChildren(), this._setupChild, this);
 		this.inherited(arguments);
 	},
 
@@ -81,7 +324,7 @@ dojo.declare(
 		if(region){
 			this.inherited(arguments);
 
-			dojo.addClass(child.domNode, this.baseClass+"Pane");
+			domClass.add(child.domNode, this.baseClass+"Pane");
 
 			var ltr = this.isLeftToRight();
 			if(region == "leading"){ region = ltr ? "left" : "right"; }
@@ -91,7 +334,10 @@ dojo.declare(
 			// 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 = dojo.getObject(child.splitter ? this._splitterClass : "dijit.layout._Gutter");
+				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,
@@ -102,7 +348,7 @@ dojo.declare(
 				splitter.isSplitter = true;
 				child._splitterWidget = splitter;
 
-				dojo.place(splitter.domNode, child.domNode, "after");
+				domConstruct.place(splitter.domNode, child.domNode, "after");
 
 				// Splitters aren't added as Contained children, so we need to call startup explicitly
 				splitter.startup();
@@ -128,32 +374,32 @@ dojo.declare(
 		// Override _LayoutWidget.removeChild().
 
 		var region = child.region;
-		var splitter = child._splitterWidget
+		var splitter = child._splitterWidget;
 		if(splitter){
 			splitter.destroy();
 			delete child._splitterWidget;
 		}
 		this.inherited(arguments);
-		
+
 		if(this._started){
 			this._layoutChildren();
 		}
 		// Clean up whatever style changes we made to the child pane.
 		// Unclear how height and width should be handled.
-		dojo.removeClass(child.domNode, this.baseClass+"Pane");
-		dojo.style(child.domNode, {
+		domClass.remove(child.domNode, this.baseClass+"Pane");
+		domStyle.set(child.domNode, {
 			top: "auto",
 			bottom: "auto",
 			left: "auto",
 			right: "auto",
 			position: "static"
 		});
-		dojo.style(child.domNode, region == "top" || region == "bottom" ? "width" : "height", "auto");
+		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 dojo.filter(this.inherited(arguments), function(widget){
+		return array.filter(this.inherited(arguments), function(widget){
 			return !widget.isSplitter;
 		});
 	},
@@ -164,7 +410,7 @@ dojo.declare(
 		//		Returns the widget responsible for rendering the splitter associated with region
 		// tags:
 		//		deprecated
-		return dojo.filter(this.getChildren(), function(child){
+		return array.filter(this.getChildren(), function(child){
 			return child.region == region;
 		})[0]._splitterWidget;
 	},
@@ -176,12 +422,12 @@ dojo.declare(
 		// 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 = dojo.getComputedStyle(node);
-			this.pe = dojo._getPadExtents(node, this.cs);
-			this.pe.r = dojo._toPixelValue(node, this.cs.paddingRight);
-			this.pe.b = dojo._toPixelValue(node, this.cs.paddingBottom);
+			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);
 
-			dojo.style(node, "padding", "0px");
+			domStyle.set(node, "padding", "0px");
 		}
 
 		this.inherited(arguments);
@@ -210,7 +456,7 @@ dojo.declare(
 
 		// 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 = dojo.map(this.getChildren(), function(child, idx){
+		var wrappers = array.map(this.getChildren(), function(child, idx){
 			return {
 				pane: child,
 				weight: [
@@ -233,7 +479,7 @@ dojo.declare(
 
 		// Make new list, combining the externally specified children with splitters and gutters
 		var childrenAndSplitters = [];
-		dojo.forEach(wrappers, function(wrapper){
+		array.forEach(wrappers, function(wrapper){
 			var pane = wrapper.pane;
 			childrenAndSplitters.push(pane);
 			if(pane._splitterWidget){
@@ -250,13 +496,13 @@ dojo.declare(
 		};
 
 		// Layout the children, possibly changing size due to a splitter drag
-		dijit.layout.layoutChildren(this.domNode, dim, childrenAndSplitters,
+		layoutUtils.layoutChildren(this.domNode, dim, childrenAndSplitters,
 			changedChildId, changedChildSize);
 	},
 
 	destroyRecursive: function(){
 		// Destroy splitters first, while getChildren() still works
-		dojo.forEach(this.getChildren(), function(child){
+		array.forEach(this.getChildren(), function(child){
 			var splitter = child._splitterWidget;
 			if(splitter){
 				splitter.destroy();
@@ -272,7 +518,7 @@ dojo.declare(
 // 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.)
-dojo.extend(dijit._Widget, {
+lang.extend(_WidgetBase, {
 	// region: [const] String
 	//		Parameter for children of `dijit.layout.BorderContainer`.
 	//		Values: "top", "bottom", "leading", "trailing", "left", "right", "center".
@@ -302,215 +548,9 @@ dojo.extend(dijit._Widget, {
 	maxSize: Infinity
 });
 
-dojo.declare("dijit.layout._Splitter", [ dijit._Widget, dijit._Templated ],
-{
-	// 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" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_startDrag,onmouseenter:_onMouse,onmouseleave:_onMouse" tabIndex="0" role="separator"><div class="dijitSplitterThumb"></div></div>',
-
-	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);
-
-		dojo.addClass(this.domNode, "dijitSplitter" + (this.horizontal ? "H" : "V"));
-
-		if(this.container.persist){
-			// restore old size
-			var persistSize = dojo.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 = dojo.marginBox(this.child.domNode)[dim],
-			center = dojo.filter(this.container.getChildren(), function(child){ return child.region == "center";})[0],
-			spaceAvailable = dojo.marginBox(center.domNode)[dim];	// can expand until center is crushed to 0
-
-		return Math.min(this.child.maxSize, childSize + spaceAvailable);
-	},
-
-	_startDrag: function(e){
-		if(!this.cover){
-			this.cover = dojo.doc.createElement('div');
-			dojo.addClass(this.cover, "dijitSplitterCover");
-			dojo.place(this.cover, this.child.domNode, "after");
-		}
-		dojo.addClass(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){ dojo.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");
-			dojo.addClass(this.domNode, "dijitSplitterShadow");
-			dojo.place(this.fake, this.domNode, "after");
-		}
-		dojo.addClass(this.domNode, "dijitSplitterActive dijitSplitter" + (this.horizontal ? "H" : "V") + "Active");
-		if(this.fake){
-			dojo.removeClass(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 = dojo.marginBox(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 = dojo.hitch(this.container, "_layoutChildren", this.child.id),
-			de = dojo.doc;
-
-		this._handlers = (this._handlers || []).concat([
-			dojo.connect(de, "onmousemove", 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";
-			}),
-			dojo.connect(de, "ondragstart", dojo.stopEvent),
-			dojo.connect(dojo.body(), "onselectstart", dojo.stopEvent),
-			dojo.connect(de, "onmouseup", this, "_stopDrag")
-		]);
-		dojo.stopEvent(e);
-	},
-
-	_onMouse: function(e){
-		var o = (e.type == "mouseover" || e.type == "mouseenter");
-		dojo.toggleClass(this.domNode, "dijitSplitterHover", o);
-		dojo.toggleClass(this.domNode, "dijitSplitter" + (this.horizontal ? "H" : "V") + "Hover", o);
-	},
-
-	_stopDrag: function(e){
-		try{
-			if(this.cover){
-				dojo.removeClass(this.cover, "dijitSplitterCoverActive");
-			}
-			if(this.fake){ dojo.destroy(this.fake); }
-			dojo.removeClass(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;
-		}
-
-		if(this.container.persist){
-			dojo.cookie(this._cookieName, this.child.domNode.style[this.horizontal ? "height" : "width"], {expires:365});
-		}
-	},
-
-	_cleanupHandlers: function(){
-		dojo.forEach(this._handlers, dojo.disconnect);
-		delete this._handlers;
-	},
-
-	_onKeyPress: function(/*Event*/ e){
-		// should we apply typematic to this?
-		this._resize = true;
-		var horizontal = this.horizontal;
-		var tick = 1;
-		var dk = dojo.keys;
-		switch(e.charOrCode){
-			case horizontal ? dk.UP_ARROW : dk.LEFT_ARROW:
-				tick *= -1;
-//				break;
-			case horizontal ? dk.DOWN_ARROW : dk.RIGHT_ARROW:
-				break;
-			default:
-//				this.inherited(arguments);
-				return;
-		}
-		var childSize = dojo._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));
-		dojo.stopEvent(e);
-	},
-
-	destroy: function(){
-		this._cleanupHandlers();
-		delete this.child;
-		delete this.container;
-		delete this.cover;
-		delete this.fake;
-		this.inherited(arguments);
-	}
-});
-
-dojo.declare("dijit.layout._Gutter", [dijit._Widget, dijit._Templated],
-{
-	// 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);
-		dojo.addClass(this.domNode, "dijitGutter" + (this.horizontal ? "H" : "V"));
-	}
-});
-
+// For monkey patching
+BorderContainer._Splitter = _Splitter;
+BorderContainer._Gutter = _Gutter;
 
-return dijit.layout.BorderContainer;
+return BorderContainer;
 });
diff --git a/dijit/layout/ContentPane.js b/dijit/layout/ContentPane.js
index a7569c5..319ef60 100644
--- a/dijit/layout/ContentPane.js
+++ b/dijit/layout/ContentPane.js
@@ -1,8 +1,35 @@
-define("dijit/layout/ContentPane", ["dojo", "dijit", "dijit/_Widget", "dijit/layout/_ContentPaneResizeMixin", "dojo/string", "dojo/html", "i18n!dijit/nls/loading"], function(dojo, dijit) {
+define([
+	"dojo/_base/kernel", // kernel.deprecated
+	"dojo/_base/lang", // lang.mixin lang.delegate lang.hitch lang.isFunction lang.isObject
+	"../_Widget",
+	"./_ContentPaneResizeMixin",
+	"dojo/string", // string.substitute
+	"dojo/html", // html._ContentSetter html._emptyNode
+	"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/_base/xhr", // xhr.get
+	"dojo/i18n" // i18n.getLocalization
+], function(kernel, lang, _Widget, _ContentPaneResizeMixin, string, html, nlsLoading,
+	array, declare, Deferred, dom, domAttr, win, xhr, i18n){
 
-dojo.declare(
-	"dijit.layout.ContentPane", [dijit._Widget, dijit.layout._ContentPaneResizeMixin],
-{
+/*=====
+	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.
@@ -37,13 +64,11 @@ dojo.declare(
 	//		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>.
@@ -59,7 +84,7 @@ dojo.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,
 
 	// preventCache: Boolean
 	//		Prevent caching of data from href's by appending a timestamp to the href.
@@ -75,11 +100,11 @@ dojo.declare(
 
 	// loadingMessage: String
 	//		Message that shows while downloading
-	loadingMessage: "<span class='dijitContentPaneLoading'>${loadingState}</span>",
+	loadingMessage: "<span class='dijitContentPaneLoading'><span class='dijitInline dijitIconLoading'></span>${loadingState}</span>",
 
 	// errorMessage: String
 	//		Message that shows if an error occurs
-	errorMessage: "<span class='dijitContentPaneError'>${errorState}</span>",
+	errorMessage: "<span class='dijitContentPaneError'><span class='dijitInline dijitIconError'></span>${errorState}</span>",
 
 	// isLoaded: [readonly] Boolean
 	//		True if the ContentPane has data in it, either specified
@@ -92,9 +117,15 @@ dojo.declare(
 
 	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 dojoType="dijit.layout.ContentPane" href="./bar" ioArgs="{timeout: 500}">
+	// |	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="href: './bar', ioArgs: {timeout: 500}">
 	ioArgs: {},
 
 	// onLoadDeferred: [readonly] dojo.Deferred
@@ -107,12 +138,10 @@ dojo.declare(
 	//		or content is loaded.
 	onLoadDeferred: null,
 
-	// Override _Widget's attributeMap because we don't want the title attribute (used to specify
+	// 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.
-	attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
-		title: []
-	}),
+	_setTitleAttr: null,
 
 	// Flag to parser that I'll parse my contents, so it shouldn't.
 	stopParser: true,
@@ -128,21 +157,21 @@ dojo.declare(
 		// 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 = dojo.doc.createDocumentFragment();
-			srcNodeRef = dojo.byId(srcNodeRef)
+			var df = win.doc.createDocumentFragment();
+			srcNodeRef = dom.byId(srcNodeRef);
 			while(srcNodeRef.firstChild){
 				df.appendChild(srcNodeRef.firstChild);
 			}
-			params = dojo.delegate(params, {content: df});
+			params = lang.delegate(params, {content: df});
 		}
 		this.inherited(arguments, [params, srcNodeRef]);
 	},
 
 	postMixInProperties: function(){
 		this.inherited(arguments);
-		var messages = dojo.i18n.getLocalization("dijit", "loading", this.lang);
-		this.loadingMessage = dojo.string.substitute(this.loadingMessage, messages);
-		this.errorMessage = dojo.string.substitute(this.errorMessage, messages);
+		var messages = i18n.getLocalization("dijit", "loading", this.lang);
+		this.loadingMessage = string.substitute(this.loadingMessage, messages);
+		this.errorMessage = string.substitute(this.errorMessage, messages);
 	},
 
 	buildRendering: function(){
@@ -158,12 +187,12 @@ dojo.declare(
 		// over a node  (TODO: remove in 2.0, no longer needed after #11490)
 		this.domNode.title = "";
 
-		if(!dojo.attr(this.domNode,"role")){
-			dijit.setWaiRole(this.domNode, "group");
+		if(!domAttr.get(this.domNode,"role")){
+			this.domNode.setAttribute("role", "group");
 		}
 	},
 
-	_startChildren: function(){
+	startup: function(){
 		// summary:
 		//		Call startup() on all children including non _Widget ones like dojo.dnd.Source objects
 
@@ -172,8 +201,8 @@ dojo.declare(
 
 		// And this catches stuff like dojo.dnd.Source
 		if(this._contentSetter){
-			dojo.forEach(this._contentSetter.parseResults, function(obj){
-				if(!obj._started && !obj._destroyed && dojo.isFunction(obj.startup)){
+			array.forEach(this._contentSetter.parseResults, function(obj){
+				if(!obj._started && !obj._destroyed && lang.isFunction(obj.startup)){
 					obj.startup();
 					obj._started = true;
 				}
@@ -184,7 +213,7 @@ dojo.declare(
 	setHref: function(/*String|Uri*/ href){
 		// summary:
 		//		Deprecated.   Use set('href', ...) instead.
-		dojo.deprecated("dijit.layout.ContentPane.setHref() is deprecated. Use set('href', ...) instead.", "", "2.0");
+		kernel.deprecated("dijit.layout.ContentPane.setHref() is deprecated. Use set('href', ...) instead.", "", "2.0");
 		return this.set("href", href);
 	},
 	_setHrefAttr: function(/*String|Uri*/ href){
@@ -199,8 +228,8 @@ dojo.declare(
 		// Cancel any in-flight requests (a set('href', ...) will cancel any in-flight set('href', ...))
 		this.cancel();
 
-		this.onLoadDeferred = new dojo.Deferred(dojo.hitch(this, "cancel"));
-		this.onLoadDeferred.addCallback(dojo.hitch(this, "onLoad"));
+		this.onLoadDeferred = new Deferred(lang.hitch(this, "cancel"));
+		this.onLoadDeferred.addCallback(lang.hitch(this, "onLoad"));
 
 		this._set("href", href);
 
@@ -215,13 +244,13 @@ dojo.declare(
 			this._hrefChanged = true;
 		}
 
-		return this.onLoadDeferred;		// dojo.Deferred
+		return this.onLoadDeferred;		// Deferred
 	},
 
 	setContent: function(/*String|DomNode|Nodelist*/data){
 		// summary:
 		//		Deprecated.   Use set('content', ...) instead.
-		dojo.deprecated("dijit.layout.ContentPane.setContent() is deprecated.  Use set('content', ...) instead.", "", "2.0");
+		kernel.deprecated("dijit.layout.ContentPane.setContent() is deprecated.  Use set('content', ...) instead.", "", "2.0");
 		this.set("content", data);
 	},
 	_setContentAttr: function(/*String|DomNode|Nodelist*/data){
@@ -243,19 +272,19 @@ dojo.declare(
 
 		// 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 dojo.Deferred(dojo.hitch(this, "cancel"));
+		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 dojoType=ContentPane>...</div>)
+			// 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(dojo.hitch(this, "onLoad"));
+			this.onLoadDeferred.addCallback(lang.hitch(this, "onLoad"));
 		}
 
 		this._setContent(data || "");
 
 		this._isDownloaded = false; // mark that content is from a set('content') not a set('href')
 
-		return this.onLoadDeferred; 	// dojo.Deferred
+		return this.onLoadDeferred; 	// Deferred
 	},
 	_getContentAttr: function(){
 		// summary:
@@ -325,8 +354,8 @@ dojo.declare(
 		// Cancel possible prior in-flight request
 		this.cancel();
 
-		this.onLoadDeferred = new dojo.Deferred(dojo.hitch(this, "cancel"));
-		this.onLoadDeferred.addCallback(dojo.hitch(this, "onLoad"));
+		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
 	},
@@ -344,11 +373,11 @@ dojo.declare(
 			url: this.href,
 			handleAs: "text"
 		};
-		if(dojo.isObject(this.ioArgs)){
-			dojo.mixin(getArgs, this.ioArgs);
+		if(lang.isObject(this.ioArgs)){
+			lang.mixin(getArgs, this.ioArgs);
 		}
 
-		var hand = (this._xhrDfd = (this.ioMethod || dojo.xhrGet)(getArgs));
+		var hand = (this._xhrDfd = (this.ioMethod || xhr.get)(getArgs));
 
 		hand.addCallback(function(html){
 			try{
@@ -397,7 +426,7 @@ dojo.declare(
 		}
 	},
 
-	destroyDescendants: function(){
+	destroyDescendants: function(/*Boolean*/ preserveDom){
 		// summary:
 		//		Destroy all the widgets inside the ContentPane and empty containerNode
 
@@ -412,24 +441,26 @@ dojo.declare(
 		// For historical reasons we need to delete all widgets under this.containerNode,
 		// even ones that the user has created manually.
 		var setter = this._contentSetter;
-		dojo.forEach(this.getChildren(), function(widget){
+		array.forEach(this.getChildren(), function(widget){
 			if(widget.destroyRecursive){
-				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
-			dojo.forEach(setter.parseResults, function(widget){
-				if(widget.destroyRecursive && widget.domNode && widget.domNode.parentNode == dojo.body()){
-					widget.destroyRecursive();
+			array.forEach(setter.parseResults, function(widget){
+				if(widget.destroyRecursive && widget.domNode && widget.domNode.parentNode == win.body()){
+					widget.destroyRecursive(preserveDom);
 				}
 			});
 			delete setter.parseResults;
 		}
 
 		// And then clear away all the DOM nodes
-		dojo.html._emptyNode(this.containerNode);
+		if(!preserveDom){
+			html._emptyNode(this.containerNode);
+		}
 
 		// Delete any state information we have about current contents
 		delete this._singleChild;
@@ -442,17 +473,17 @@ dojo.declare(
 		// first get rid of child widgets
 		this.destroyDescendants();
 
-		// dojo.html.set will take care of the rest of the details
+		// 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 dojo.html._ContentSetter)){
-			setter = this._contentSetter = new dojo.html._ContentSetter({
+		if(! (setter && setter instanceof html._ContentSetter)){
+			setter = this._contentSetter = new html._ContentSetter({
 				node: this.containerNode,
-				_onError: dojo.hitch(this, this._onError),
-				onContentError: dojo.hitch(this, function(e){
+				_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);
@@ -464,19 +495,20 @@ dojo.declare(
 				})/*,
 				_onError */
 			});
-		};
+		}
 
-		var setterParams = dojo.mixin({
+		var setterParams = lang.mixin({
 			cleanContent: this.cleanContent,
 			extractContent: this.extractContent,
-			parseContent: this.parseOnLoad,
+			parseContent: !cont.domNode && this.parseOnLoad,
 			parserScope: this.parserScope,
 			startup: false,
 			dir: this.dir,
-			lang: this.lang
+			lang: this.lang,
+			textDir: this.textDir
 		}, this._contentSetterParams || {});
 
-		setter.set( (dojo.isObject(cont) && cont.domNode) ? cont.domNode : cont, setterParams );
+		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;
@@ -488,8 +520,9 @@ dojo.declare(
 		if(!isFakeContent){
 			if(this._started){
 				// Startup each top level child widget (and they will start their children, recursively)
-				this._startChildren();
-	
+				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
@@ -514,7 +547,7 @@ dojo.declare(
 	},
 
 	// EVENT's, should be overide-able
-	onLoad: function(data){
+	onLoad: function(/*===== data =====*/){
 		// summary:
 		//		Event hook, is called after everything is loaded and widgetified
 		// tags:
@@ -540,7 +573,7 @@ dojo.declare(
 		return this.loadingMessage;
 	},
 
-	onContentError: function(/*Error*/ error){
+	onContentError: function(/*Error*/ /*===== error =====*/){
 		// summary:
 		//		Called on DOM faults, require faults etc. in content.
 		//
@@ -553,7 +586,7 @@ dojo.declare(
 		//		extension
 	},
 
-	onDownloadError: function(/*Error*/ error){
+	onDownloadError: function(/*Error*/ /*===== error =====*/){
 		// summary:
 		//		Called when download error occurs.
 		//
@@ -575,6 +608,4 @@ dojo.declare(
 	}
 });
 
-
-return dijit.layout.ContentPane;
 });
diff --git a/dijit/layout/LayoutContainer.js b/dijit/layout/LayoutContainer.js
index 2056e3f..96e8df5 100644
--- a/dijit/layout/LayoutContainer.js
+++ b/dijit/layout/LayoutContainer.js
@@ -1,8 +1,34 @@
-define("dijit/layout/LayoutContainer", ["dojo", "dijit", "dijit/layout/_LayoutWidget"], function(dojo, dijit) {
+define([
+	"dojo/_base/kernel", // kernel.deprecated
+	"dojo/_base/lang",
+	"dojo/_base/declare", // declare
+	"../_WidgetBase",
+	"./_LayoutWidget",
+	"./utils"		// layoutUtils.layoutChildren
+], function(kernel, lang, declare, _WidgetBase, _LayoutWidget, layoutUtils){
 
-dojo.declare("dijit.layout.LayoutContainer",
-	dijit.layout._LayoutWidget,
-	{
+/*=====
+	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'
+});
+
+return declare("dijit.layout.LayoutContainer", _LayoutWidget, {
 	// summary:
 	//		Deprecated.  Use `dijit.layout.BorderContainer` instead.
 	//
@@ -25,10 +51,10 @@ dojo.declare("dijit.layout.LayoutContainer",
 	// |	<style>
 	// |		html, body{ height: 100%; width: 100%; }
 	// |	</style>
-	// |	<div dojoType="dijit.layout.LayoutContainer" style="width: 100%; height: 100%">
-	// |		<div dojoType="dijit.layout.ContentPane" layoutAlign="top">header text</div>
-	// |		<div dojoType="dijit.layout.ContentPane" layoutAlign="left" style="width: 200px;">table of contents</div>
-	// |		<div dojoType="dijit.layout.ContentPane" layoutAlign="client">client area</div>
+	// |	<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.
@@ -40,38 +66,26 @@ dojo.declare("dijit.layout.LayoutContainer",
 	baseClass: "dijitLayoutContainer",
 
 	constructor: function(){
-		dojo.deprecated("dijit.layout.LayoutContainer is deprecated", "use BorderContainer instead", 2.0);
+		kernel.deprecated("dijit.layout.LayoutContainer is deprecated", "use BorderContainer instead", 2.0);
 	},
 
 	layout: function(){
-		dijit.layout.layoutChildren(this.domNode, this._contentBox, this.getChildren());
+		layoutUtils.layoutChildren(this.domNode, this._contentBox, this.getChildren());
 	},
 
 	addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){
 		this.inherited(arguments);
 		if(this._started){
-			dijit.layout.layoutChildren(this.domNode, this._contentBox, this.getChildren());
+			layoutUtils.layoutChildren(this.domNode, this._contentBox, this.getChildren());
 		}
 	},
 
 	removeChild: function(/*dijit._Widget*/ widget){
 		this.inherited(arguments);
 		if(this._started){
-			dijit.layout.layoutChildren(this.domNode, this._contentBox, this.getChildren());
+			layoutUtils.layoutChildren(this.domNode, this._contentBox, this.getChildren());
 		}
 	}
 });
 
-// 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.)
-dojo.extend(dijit._Widget, {
-	// layoutAlign: String
-	//		"none", "left", "right", "bottom", "top", and "client".
-	//		See the LayoutContainer description for details on this parameter.
-	layoutAlign: 'none'
-});
-
-
-return dijit.layout.LayoutContainer;
 });
diff --git a/dijit/layout/LinkPane.js b/dijit/layout/LinkPane.js
index 3f92b5f..5010de6 100644
--- a/dijit/layout/LinkPane.js
+++ b/dijit/layout/LinkPane.js
@@ -1,41 +1,52 @@
-define("dijit/layout/LinkPane", ["dojo", "dijit", "dijit/layout/ContentPane", "dijit/_Templated"], function(dojo, dijit) {
+define([
+	"./ContentPane",
+	"../_TemplatedMixin",
+	"dojo/_base/declare" // declare
+], function(ContentPane, _TemplatedMixin, declare){
 
-dojo.declare("dijit.layout.LinkPane",
-	[dijit.layout.ContentPane, dijit._Templated],
-	{
+/*=====
+	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.
-	// description:
-	//		LinkPane is just a ContentPane that is declared in markup similarly
-	//		to an anchor.  The anchor's body (the words between `<a>` and `</a>`)
-	//		become the title of the widget (used for TabContainer, AccordionContainer, etc.)
-	// example:
-	//	| <a href="foo.html">my title</a>
-
-	// I'm using a template because the user may specify the input as
-	// <a href="foo.html">title</a>, in which case we need to get rid of the
-	// <a> because we don't want a link.
-	templateString: '<div class="dijitLinkPane" dojoAttachPoint="containerNode"></div>',
-
-	postMixInProperties: function(){
-		// If user has specified node contents, they become the title
-		// (the link must be plain text)
-		if(this.srcNodeRef){
-			this.title += this.srcNodeRef.innerHTML;
-		}
-		this.inherited(arguments);
-	},
 
-	_fillContent: function(/*DomNode*/ source){
-		// Overrides _Templated._fillContent().
 
-		// _Templated._fillContent() relocates srcNodeRef innerHTML to templated container node,
-		// but in our case the srcNodeRef innerHTML is the title, so shouldn't be
-		// copied
-	}
-});
+	return declare("dijit.layout.LinkPane", [ContentPane, _TemplatedMixin], {
+		// summary:
+		//		A ContentPane with an href where (when declared in markup)
+		//		the title is specified as innerHTML rather than as a title attribute.
+		// description:
+		//		LinkPane is just a ContentPane that is declared in markup similarly
+		//		to an anchor.  The anchor's body (the words between `<a>` and `</a>`)
+		//		become the title of the widget (used for TabContainer, AccordionContainer, etc.)
+		// example:
+		//	| <a href="foo.html">my title</a>
 
+		// I'm using a template because the user may specify the input as
+		// <a href="foo.html">title</a>, in which case we need to get rid of the
+		// <a> because we don't want a link.
+		templateString: '<div class="dijitLinkPane" data-dojo-attach-point="containerNode"></div>',
 
-return dijit.layout.LinkPane;
+		postMixInProperties: function(){
+			// If user has specified node contents, they become the title
+			// (the link must be plain text)
+			if(this.srcNodeRef){
+				this.title += this.srcNodeRef.innerHTML;
+			}
+			this.inherited(arguments);
+		},
+
+		_fillContent: function(){
+			// Overrides _Templated._fillContent().
+
+			// _Templated._fillContent() relocates srcNodeRef innerHTML to templated container node,
+			// but in our case the srcNodeRef innerHTML is the title, so shouldn't be
+			// copied
+		}
+	});
 });
diff --git a/dijit/layout/ScrollingTabController.js b/dijit/layout/ScrollingTabController.js
index 0d8dbaa..d8fda3c 100644
--- a/dijit/layout/ScrollingTabController.js
+++ b/dijit/layout/ScrollingTabController.js
@@ -1,8 +1,44 @@
-define("dijit/layout/ScrollingTabController", ["dojo", "dijit", "text!dijit/layout/templates/ScrollingTabController.html", "text!dijit/layout/templates/_ScrollingTabControllerButton.html", "dijit/layout/TabController", "dijit/Menu", "dijit/form/Button", "dijit/_HasDropDown"], function(dojo, dijit) {
-
-dojo.declare("dijit.layout.ScrollingTabController",
-	dijit.layout.TabController,
-	{
+define([
+	"dojo/_base/array", // array.forEach
+	"dojo/_base/declare", // declare
+	"dojo/dom-class", // domClass.add domClass.contains
+	"dojo/dom-geometry", // domGeometry.contentBox
+	"dojo/dom-style", // domStyle.style
+	"dojo/_base/fx", // Animation
+	"dojo/_base/lang", // lang.hitch
+	"dojo/query", // query
+	"dojo/_base/sniff", // has("ie"), has("webkit"), has("quirks")
+	"../registry",	// registry.byId()
+	"dojo/text!./templates/ScrollingTabController.html",
+	"dojo/text!./templates/_ScrollingTabControllerButton.html",
+	"./TabController",
+	"./utils",	// marginBox2contextBox, layoutChildren
+	"../_WidgetsInTemplateMixin",
+	"../Menu",
+	"../MenuItem",
+	"../form/Button",
+	"../_HasDropDown",
+	"dojo/NodeList-dom" // NodeList.style
+], function(array, declare, domClass, domGeometry, domStyle, fx, lang, 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
+// summary:
+//		Set of tabs with left/right arrow keys and a menu to switch between tabs not
+//		all fitting on a single row.
+
+
+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.
@@ -11,7 +47,9 @@ dojo.declare("dijit.layout.ScrollingTabController",
 	// tags:
 	//		private
 
-	templateString: dojo.cache("dijit.layout", "templates/ScrollingTabController.html"),
+	baseClass: "dijitTabController dijitScrollingTabController",
+
+	templateString: tabControllerTemplate,
 
 	// useMenu: [const] Boolean
 	//		True if a menu should be used to select tabs when they are too
@@ -35,9 +73,8 @@ dojo.declare("dijit.layout.ScrollingTabController",
 	//		go all the way to the left/right.
 	_minScroll: 5,
 
-	attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
-		"class": "containerNode"
-	}),
+	// Override default behavior mapping class to DOMNode
+	_setClassAttr: { node: "containerNode", type: "class" },
 
 	buildRendering: function(){
 		this.inherited(arguments);
@@ -51,19 +88,19 @@ dojo.declare("dijit.layout.ScrollingTabController",
 				this.tabPosition.charAt(0).toUpperCase() +
 				this.tabPosition.substr(1).replace(/-.*/, "") +
 				"None";
-			dojo.addClass(n, "tabStrip-disabled")
+			domClass.add(n, "tabStrip-disabled")
 		}
 
-		dojo.addClass(this.tablistWrapper, this.tabStripClass);
+		domClass.add(this.tablistWrapper, this.tabStripClass);
 	},
 
 	onStartup: function(){
 		this.inherited(arguments);
 
-		// Do not show the TabController until the related
-		// StackController has added it's children.  This gives
-		// a less visually jumpy instantiation.
-		dojo.style(this.domNode, "visibility", "visible");
+		// 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;
 	},
 
@@ -72,9 +109,9 @@ dojo.declare("dijit.layout.ScrollingTabController",
 
 		// changes to the tab button label or iconClass will have changed the width of the
 		// buttons, so do a resize
-		dojo.forEach(["label", "iconClass"], function(attr){
+		array.forEach(["label", "iconClass"], function(attr){
 			this.pane2watches[page.id].push(
-				this.pane2button[page.id].watch(attr, dojo.hitch(this, function(name, oldValue, newValue){
+				this.pane2button[page.id].watch(attr, lang.hitch(this, function(){
 					if(this._postStartup && this._dim){
 						this.resize(this._dim);
 					}
@@ -86,8 +123,8 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		// This makes sure that the buttons never wrap.
 		// The value 200 is chosen as it should be bigger than most
 		// Tab button widths.
-		dojo.style(this.containerNode, "width",
-			(dojo.style(this.containerNode, "width") + 200) + "px");
+		domStyle.set(this.containerNode, "width",
+			(domStyle.get(this.containerNode, "width") + 200) + "px");
 	},
 
 	onRemoveChild: function(page, insertIndex){
@@ -109,13 +146,13 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		// wider than the TabContainer, and hide the other buttons.
 		// Also gets the total width of the displayed buttons.
 		this._btnWidth = 0;
-		this._buttons = dojo.query("> .tabStripButton", this.domNode).filter(function(btn){
+		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 += dojo._getMarginSize(btn).w;
+				this._btnWidth += domGeometry.getMarginSize(btn).w;
 				return true;
 			}else{
-				dojo.style(btn, "display", "none");
+				domStyle.set(btn, "display", "none");
 				return false;
 			}
 		}, this);
@@ -126,7 +163,7 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		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 + dojo.style(rightTab, "width") - leftTab.offsetLeft;
+			return rightTab.offsetLeft + domStyle.get(rightTab, "width") - leftTab.offsetLeft;
 		}else{
 			return 0;
 		}
@@ -137,7 +174,7 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		//		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 || dojo.style(this.scrollNode, "width");
+		width = width || domStyle.get(this.scrollNode, "width");
 		return tabsWidth > 0 && width < tabsWidth;
 	},
 
@@ -146,10 +183,6 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		//		Hides or displays the buttons used to scroll the tab list and launch the menu
 		//		that selects tabs.
 
-		if(this.domNode.offsetWidth == 0){
-			return;
-		}
-
 		// Save the dimensions to be used when a child is renamed.
 		this._dim = dim;
 
@@ -158,9 +191,9 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		// 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";
-		this._contentBox = dijit.layout.marginBox2contentBox(this.domNode, {h: 0, w: dim.w});
-		this._contentBox.h = this.scrollNode.offsetHeight;
-		dojo.contentBox(this.domNode, this._contentBox);
+		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.
@@ -171,7 +204,7 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		this._leftBtn.layoutAlign = "left";
 		this._rightBtn.layoutAlign = "right";
 		this._menuBtn.layoutAlign = this.isLeftToRight() ? "right" : "left";
-		dijit.layout.layoutChildren(this.domNode, this._contentBox,
+		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
@@ -179,14 +212,12 @@ dojo.declare("dijit.layout.ScrollingTabController",
 			if(this._anim && this._anim.status() == "playing"){
 				this._anim.stop();
 			}
-			var w = this.scrollNode,
-				sl = this._convertToScrollLeft(this._getScrollForSelectedTab());
-			w.scrollLeft = sl;
+			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.
@@ -199,10 +230,9 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		//		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"
-		var sl = (this.isLeftToRight() || dojo.isIE < 8 || (dojo.isIE && dojo.isQuirks) || dojo.isWebKit) ? this.scrollNode.scrollLeft :
-				dojo.style(this.containerNode, "width") - dojo.style(this.scrollNode, "width")
-					 + (dojo.isIE == 8 ? -1 : 1) * this.scrollNode.scrollLeft;
-		return sl;
+		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){
@@ -213,11 +243,11 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		//		to achieve that scroll.
 		//
 		//		This method is to adjust for RTL funniness in various browsers and versions.
-		if(this.isLeftToRight() || dojo.isIE < 8 || (dojo.isIE && dojo.isQuirks) || dojo.isWebKit){
+		if(this.isLeftToRight() || has("ie") < 8 || (has("ie") && has("quirks")) || has("webkit")){
 			return val;
 		}else{
-			var maxScroll = dojo.style(this.containerNode, "width") - dojo.style(this.scrollNode, "width");
-			return (dojo.isIE == 8 ? -1 : 1) * (val - maxScroll);
+			var maxScroll = domStyle.get(this.containerNode, "width") - domStyle.get(this.scrollNode, "width");
+			return (has("ie") == 8 ? -1 : 1) * (val - maxScroll);
 		}
 	},
 
@@ -228,17 +258,21 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		var tab = this.pane2button[page.id];
 		if(!tab || !page){return;}
 
-		// Scroll to the selected tab, except on startup, when scrolling is handled in resize()
 		var node = tab.domNode;
-		if(this._postResize && node != this._selectedTab){
+
+		// Save the selection
+		if(node != this._selectedTab){
 			this._selectedTab = node;
 
-			var sl = this._getScroll();
+			// 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 + dojo.style(this.scrollNode, "width") <
-					node.offsetLeft + dojo.style(node, "width")){
-				this.createSmoothScroll().play();
+				if(sl > node.offsetLeft ||
+						sl + domStyle.get(this.scrollNode, "width") <
+						node.offsetLeft + domStyle.get(node, "width")){
+					this.createSmoothScroll().play();
+				}
 			}
 		}
 
@@ -250,8 +284,8 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		//		Returns the minimum and maximum scroll setting to show the leftmost and rightmost
 		//		tabs (respectively)
 		var children = this.getChildren(),
-			scrollNodeWidth = dojo.style(this.scrollNode, "width"),		// about 500px
-			containerWidth = dojo.style(this.containerNode, "width"),	// 50,000px
+			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();
 
@@ -260,7 +294,7 @@ dojo.declare("dijit.layout.ScrollingTabController",
 			return {
 				min: this.isLeftToRight() ? 0 : children[children.length-1].domNode.offsetLeft,
 				max: this.isLeftToRight() ?
-					(children[children.length-1].domNode.offsetLeft + dojo.style(children[children.length-1].domNode, "width")) - scrollNodeWidth :
+					(children[children.length-1].domNode.offsetLeft + domStyle.get(children[children.length-1].domNode, "width")) - scrollNodeWidth :
 					maxPossibleScroll
 			};
 		}else{
@@ -279,12 +313,12 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		//		will appear in the center
 		var w = this.scrollNode,
 			n = this._selectedTab,
-			scrollNodeWidth = dojo.style(this.scrollNode, "width"),
+			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 + dojo.style(n, "width")/2) - scrollNodeWidth/2;
+		var pos = (n.offsetLeft + domStyle.get(n, "width")/2) - scrollNodeWidth/2;
 		pos = Math.min(Math.max(pos, scrollBounds.min), scrollBounds.max);
 
 		// TODO:
@@ -321,12 +355,12 @@ dojo.declare("dijit.layout.ScrollingTabController",
 
 		var self = this,
 			w = this.scrollNode,
-			anim = new dojo._Animation({
+			anim = new fx.Animation({
 				beforeBegin: function(){
 					if(this.curve){ delete this.curve; }
 					var oldS = w.scrollLeft,
 						newS = self._convertToScrollLeft(x);
-					anim.curve = new dojo._Line(oldS, newS);
+					anim.curve = new fx._Line(oldS, newS);
 				},
 				onAnimate: function(val){
 					w.scrollLeft = val;
@@ -346,7 +380,7 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		// e:
 		//		The mouse click event.
 		var n = e.target;
-		while(n && !dojo.hasClass(n, "tabStripButton")){
+		while(n && !domClass.contains(n, "tabStripButton")){
 			n = n.parentNode;
 		}
 		return n;
@@ -375,9 +409,9 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		//		If the direction is 1, the widget scrolls to the right, if it is
 		//		-1, it scrolls to the left.
 
-		if(node && dojo.hasClass(node, "dijitTabDisabled")){return;}
+		if(node && domClass.contains(node, "dijitTabDisabled")){return;}
 
-		var sWidth = dojo.style(this.scrollNode, "width");
+		var sWidth = domStyle.get(this.scrollNode, "width");
 		var d = (sWidth * 0.75) * direction;
 
 		var to = this._getScroll() + d;
@@ -401,10 +435,10 @@ dojo.declare("dijit.layout.ScrollingTabController",
 });
 
 
-dojo.declare("dijit.layout._ScrollingTabControllerButtonMixin", null, {
+var ScrollingTabControllerButtonMixin = declare("dijit.layout._ScrollingTabControllerButtonMixin", null, {
 	baseClass: "dijitTab tabStripButton",
 
-	templateString: dojo.cache("dijit.layout","templates/_ScrollingTabControllerButton.html"),
+	templateString: buttonTemplate,
 
 		// Override inherited tabIndex: 0 from dijit.form.Button, because user shouldn't be
 		// able to tab to the left/right/menu buttons
@@ -414,13 +448,18 @@ dojo.declare("dijit.layout._ScrollingTabControllerButtonMixin", null, {
 	// either (this override avoids focus() call in FormWidget.js)
 	isFocusable: function(){ return false; }
 });
+/*=====
+ScrollingTabControllerButtonMixin = dijit.layout._ScrollingTabControllerButtonMixin;
+=====*/
 
-dojo.declare("dijit.layout._ScrollingTabControllerButton",
-	[dijit.form.Button, dijit.layout._ScrollingTabControllerButtonMixin]);
+// Class used in template
+declare("dijit.layout._ScrollingTabControllerButton",
+	[Button, ScrollingTabControllerButtonMixin]);
 
-dojo.declare(
+// Class used in template
+declare(
 	"dijit.layout._ScrollingTabControllerMenuButton",
-	[dijit.form.Button, dijit._HasDropDown, dijit.layout._ScrollingTabControllerButtonMixin],
+	[Button, _HasDropDown, ScrollingTabControllerButtonMixin],
 {
 	// id of the TabContainer itself
 	containerId: "",
@@ -435,19 +474,21 @@ dojo.declare(
 	},
 
 	loadDropDown: function(callback){
-		this.dropDown = new dijit.Menu({
+		this.dropDown = new Menu({
 			id: this.containerId + "_menu",
 			dir: this.dir,
-			lang: this.lang
+			lang: this.lang,
+			textDir: this.textDir
 		});
-		var container = dijit.byId(this.containerId);
-		dojo.forEach(container.getChildren(), function(page){
-			var menuItem = new dijit.MenuItem({
+		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);
 				}
@@ -466,5 +507,5 @@ dojo.declare(
 	}
 });
 
-return dijit.layout.ScrollingTabController;
+return ScrollingTabController;
 });
diff --git a/dijit/layout/SplitContainer.js b/dijit/layout/SplitContainer.js
index a4aa12f..e16ece9 100644
--- a/dijit/layout/SplitContainer.js
+++ b/dijit/layout/SplitContainer.js
@@ -1,14 +1,60 @@
-define("dijit/layout/SplitContainer", ["dojo", "dijit", "dojo/cookie", "dijit/layout/_LayoutWidget"], function(dojo, dijit) {
+define([
+	"dojo/_base/array", // array.forEach array.indexOf array.some
+	"dojo/cookie", // cookie
+	"dojo/_base/declare", // declare
+	"dojo/dom", // dom.setSelectable
+	"dojo/dom-class", // domClass.add
+	"dojo/dom-construct", // domConstruct.create domConstruct.destroy
+	"dojo/dom-geometry", // domGeometry.marginBox domGeometry.position
+	"dojo/dom-style", // domStyle.style
+	"dojo/_base/event", // event.stop
+	"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
+	"../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;
+=====*/
+
+// module:
+//		dijit/layout/SplitContainer
+// summary:
+//		Deprecated.  Use `dijit.layout.BorderContainer` instead.
 
 //
 // FIXME: make it prettier
 // FIXME: active dragging upwards doesn't always shift other bars (direction calculation is wrong in this case)
+// 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,
 
-dojo.declare("dijit.layout.SplitContainer",
-	dijit.layout._LayoutWidget,
-	{
+	// 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, {
 	// summary:
 	//		Deprecated.  Use `dijit.layout.BorderContainer` instead.
 	// description:
@@ -22,7 +68,7 @@ dojo.declare("dijit.layout.SplitContainer",
 	//		deprecated
 
 	constructor: function(){
-		dojo.deprecated("dijit.layout.SplitContainer is deprecated", "use BorderContainer with splitter instead", 2.0);
+		kernel.deprecated("dijit.layout.SplitContainer is deprecated", "use BorderContainer with splitter instead", 2.0);
 	},
 
 	// activeSizing: Boolean
@@ -32,7 +78,7 @@ dojo.declare("dijit.layout.SplitContainer",
 
 	// sizerWidth: Integer
 	//		Size in pixels of the bar between each child
-	sizerWidth: 7, // FIXME: this should be a CSS attribute (at 7 because css wants it to be 7 until we fix to css)
+	sizerWidth: 7,
 
 	// orientation: String
 	//		either 'horizontal' or vertical; indicates whether the children are
@@ -56,7 +102,7 @@ dojo.declare("dijit.layout.SplitContainer",
 
 		// overflow has to be explicitly hidden for splitContainers using gekko (trac #1435)
 		// to keep other combined css classes from inadvertantly making the overflow visible
-		if(dojo.isMozilla){
+		if(has("mozilla")){
 			this.domNode.style.overflow = '-moz-scrollbars-none'; // hidden doesn't work
 		}
 
@@ -66,7 +112,7 @@ dojo.declare("dijit.layout.SplitContainer",
 				this.sizerWidth = parseInt(this.sizerWidth.toString());
 			}catch(e){ this.sizerWidth = 7; }
 		}
-		var sizer = dojo.doc.createElement('div');
+		var sizer = win.doc.createElement('div');
 		this.virtualSizer = sizer;
 		sizer.style.position = 'relative';
 
@@ -81,18 +127,21 @@ dojo.declare("dijit.layout.SplitContainer",
 		sizer.style.zIndex = 10;
 		sizer.className = this.isHorizontal ? 'dijitSplitContainerVirtualSizerH' : 'dijitSplitContainerVirtualSizerV';
 		this.domNode.appendChild(sizer);
-		dojo.setSelectable(sizer, false);
+		dom.setSelectable(sizer, false);
 	},
 
 	destroy: function(){
 		delete this.virtualSizer;
-		dojo.forEach(this._ownconnects, dojo.disconnect);
+		if(this._ownconnects){
+			var h;
+			while(h = this._ownconnects.pop()){ h.remove(); }
+		}
 		this.inherited(arguments);
 	},
 	startup: function(){
 		if(this._started){ return; }
 
-		dojo.forEach(this.getChildren(), function(child, i, children){
+		array.forEach(this.getChildren(), function(child, i, children){
 			// attach the children and create the draggers
 			this._setupChild(child);
 
@@ -111,7 +160,7 @@ dojo.declare("dijit.layout.SplitContainer",
 	_setupChild: function(/*dijit._Widget*/ child){
 		this.inherited(arguments);
 		child.domNode.style.position = "absolute";
-		dojo.addClass(child.domNode, "dijitSplitPane");
+		domClass.add(child.domNode, "dijitSplitPane");
 	},
 
 	_onSizerMouseDown: function(e){
@@ -130,22 +179,22 @@ dojo.declare("dijit.layout.SplitContainer",
 		index = index === undefined ? this.sizers.length : index;
 
 		// TODO: use a template for this!!!
-		var sizer = dojo.doc.createElement('div');
-		sizer.id=dijit.getUniqueId('dijit_layout_SplitterContainer_Splitter');
+		var sizer = win.doc.createElement('div');
+		sizer.id=registry.getUniqueId('dijit_layout_SplitterContainer_Splitter');
 		this.sizers.splice(index,0,sizer);
 		this.domNode.appendChild(sizer);
 
 		sizer.className = this.isHorizontal ? 'dijitSplitContainerSizerH' : 'dijitSplitContainerSizerV';
 
 		// add the thumb div
-		var thumb = dojo.doc.createElement('div');
+		var thumb = win.doc.createElement('div');
 		thumb.className = 'thumb';
 		sizer.appendChild(thumb);
 
 		// FIXME: are you serious? why aren't we using mover start/stop combo?
 		this.connect(sizer, "onmousedown", '_onSizerMouseDown');
 
-		dojo.setSelectable(sizer, false);
+		dom.setSelectable(sizer, false);
 	},
 
 	removeChild: function(widget){
@@ -153,12 +202,12 @@ dojo.declare("dijit.layout.SplitContainer",
 		//		Remove sizer, but only if widget is really our child and
 		// we have at least one sizer to throw away
 		if(this.sizers.length){
-			var i=dojo.indexOf(this.getChildren(), widget)
+			var i = array.indexOf(this.getChildren(), widget);
 			if(i != -1){
 				if(i == this.sizers.length){
 					i--;
 				}
-				dojo.destroy(this.sizers[i]);
+				domConstruct.destroy(this.sizers[i]);
 				this.sizers.splice(i,1);
 			}
 		}
@@ -217,7 +266,7 @@ dojo.declare("dijit.layout.SplitContainer",
 		// calculate total of SizeShare values
 		//
 		var outOf = 0;
-		dojo.forEach(children, function(child){
+		array.forEach(children, function(child){
 			outOf += child.sizeShare;
 		});
 
@@ -230,7 +279,7 @@ dojo.declare("dijit.layout.SplitContainer",
 		// set the SizeActual member of each pane
 		//
 		var totalSize = 0;
-		dojo.forEach(children.slice(0, children.length - 1), function(child){
+		array.forEach(children.slice(0, children.length - 1), function(child){
 			var size = Math.round(pixPerUnit * child.sizeShare);
 			child.sizeActual = size;
 			totalSize += size;
@@ -260,7 +309,7 @@ dojo.declare("dijit.layout.SplitContainer",
 			return;
 		}
 
-		dojo.some(children.slice(1), function(child, i){
+		array.some(children.slice(1), function(child, i){
 			// error-checking
 			if(!this.sizers[i]){
 				return true;
@@ -278,23 +327,24 @@ dojo.declare("dijit.layout.SplitContainer",
 	},
 
 	_movePanel: function(panel, pos, size){
+		var box;
 		if(this.isHorizontal){
 			panel.domNode.style.left = pos + 'px';	// TODO: resize() takes l and t parameters too, don't need to set manually
 			panel.domNode.style.top = 0;
-			var box = {w: size, h: this.paneHeight};
+			box = {w: size, h: this.paneHeight};
 			if(panel.resize){
 				panel.resize(box);
 			}else{
-				dojo.marginBox(panel.domNode, box);
+				domGeometry.setMarginBox(panel.domNode, box);
 			}
 		}else{
 			panel.domNode.style.left = 0;	// TODO: resize() takes l and t parameters too, don't need to set manually
 			panel.domNode.style.top = pos + 'px';
-			var box = {w: this.paneWidth, h: size};
+			box = {w: this.paneWidth, h: size};
 			if(panel.resize){
 				panel.resize(box);
 			}else{
-				dojo.marginBox(panel.domNode, box);
+				domGeometry.setMarginBox(panel.domNode, box);
 			}
 		}
 	},
@@ -303,11 +353,11 @@ dojo.declare("dijit.layout.SplitContainer",
 		if(this.isHorizontal){
 			slider.style.left = pos + 'px';
 			slider.style.top = 0;
-			dojo.marginBox(slider, { w: size, h: this.paneHeight });
+			domGeometry.setMarginBox(slider, { w: size, h: this.paneHeight });
 		}else{
 			slider.style.left = 0;
 			slider.style.top = pos + 'px';
-			dojo.marginBox(slider, { w: this.paneWidth, h: size });
+			domGeometry.setMarginBox(slider, { w: this.paneWidth, h: size });
 		}
 	},
 
@@ -335,7 +385,7 @@ dojo.declare("dijit.layout.SplitContainer",
 		var totalSize = 0;
 		var children = this.getChildren();
 
-		dojo.forEach(children, function(child){
+		array.forEach(children, function(child){
 			totalSize += child.sizeActual;
 			totalMinSize += child.sizeMin;
 		});
@@ -346,7 +396,7 @@ dojo.declare("dijit.layout.SplitContainer",
 
 			var growth = 0;
 
-			dojo.forEach(children, function(child){
+			array.forEach(children, function(child){
 				if(child.sizeActual < child.sizeMin){
 					growth += child.sizeMin - child.sizeActual;
 					child.sizeActual = child.sizeMin;
@@ -355,12 +405,12 @@ dojo.declare("dijit.layout.SplitContainer",
 
 			if(growth > 0){
 				var list = this.isDraggingLeft ? children.reverse() : children;
-				dojo.forEach(list, function(child){
+				array.forEach(list, function(child){
 					growth = this._growPane(growth, child);
 				}, this);
 			}
 		}else{
-			dojo.forEach(children, function(child){
+			array.forEach(children, function(child){
 				child.sizeActual = Math.round(totalSize * (child.sizeMin / totalMinSize));
 			});
 		}
@@ -375,7 +425,7 @@ dojo.declare("dijit.layout.SplitContainer",
 		this.sizingSplitter = this.sizers[i];
 
 		if(!this.cover){
-			this.cover = dojo.create('div', {
+			this.cover = domConstruct.create('div', {
 					style: {
 						position:'absolute',
 						zIndex:5,
@@ -391,14 +441,15 @@ dojo.declare("dijit.layout.SplitContainer",
 		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 = dojo.position(children[0].domNode, true);
+		this.originPos = domGeometry.position(children[0].domNode, true);
+		var client, screen;
 		if(this.isHorizontal){
-			var client = e.layerX || e.offsetX || 0;
-			var screen = e.pageX;
+			client = e.layerX || e.offsetX || 0;
+			screen = e.pageX;
 			this.originPos = this.originPos.x;
 		}else{
-			var client = e.layerY || e.offsetY || 0;
-			var screen = e.pageY;
+			client = e.layerY || e.offsetY || 0;
+			screen = e.pageY;
 			this.originPos = this.originPos.y;
 		}
 		this.startPoint = this.lastPoint = screen;
@@ -412,11 +463,12 @@ dojo.declare("dijit.layout.SplitContainer",
 		//
 		// attach mouse events
 		//
-		this._ownconnects = [];
-		this._ownconnects.push(dojo.connect(dojo.doc.documentElement, "onmousemove", this, "changeSizing"));
-		this._ownconnects.push(dojo.connect(dojo.doc.documentElement, "onmouseup", this, "endSizing"));
+		this._ownconnects = [
+			on(win.doc.documentElement, "mousemove", lang.hitch(this, "changeSizing")),
+			on(win.doc.documentElement, "mouseup", lang.hitch(this, "endSizing"))
+		];
 
-		dojo.stopEvent(e);
+		event.stop(e);
 	},
 
 	changeSizing: function(e){
@@ -428,10 +480,10 @@ dojo.declare("dijit.layout.SplitContainer",
 		}else{
 			this._moveSizingLine();
 		}
-		dojo.stopEvent(e);
+		event.stop(e);
 	},
 
-	endSizing: function(e){
+	endSizing: function(){
 		if(!this.isSizing){ return; }
 		if(this.cover){
 			this.cover.style.zIndex = -1;
@@ -448,7 +500,8 @@ dojo.declare("dijit.layout.SplitContainer",
 			this._saveState(this);
 		}
 
-		dojo.forEach(this._ownconnects, dojo.disconnect);
+		var h;
+		while(h = this._ownconnects.pop()){ h.remove(); }
 	},
 
 	movePoint: function(){
@@ -499,7 +552,7 @@ dojo.declare("dijit.layout.SplitContainer",
 		this.paneAfter.position	= pos + this.sizerWidth;
 		this.paneAfter.sizeActual = end_region - this.paneAfter.position;
 
-		dojo.forEach(this.getChildren(), function(child){
+		array.forEach(this.getChildren(), function(child){
 			child.sizeShare = child.sizeActual;
 		});
 
@@ -512,7 +565,7 @@ dojo.declare("dijit.layout.SplitContainer",
 
 		this._moveSizingLine();
 
-		dojo.marginBox(this.virtualSizer,
+		domGeometry.setMarginBox(this.virtualSizer,
 			this.isHorizontal ? { w: this.sizerWidth, h: this.paneHeight } : { w: this.paneWidth, h: this.sizerWidth });
 
 		this.virtualSizer.style.display = 'block';
@@ -524,7 +577,7 @@ dojo.declare("dijit.layout.SplitContainer",
 
 	_moveSizingLine: function(){
 		var pos = (this.lastPoint - this.startPoint) + this.sizingSplitter.position;
-		dojo.style(this.virtualSizer,(this.isHorizontal ? "left" : "top"),pos+"px");
+		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
 	},
 
@@ -533,9 +586,9 @@ dojo.declare("dijit.layout.SplitContainer",
 	},
 
 	_restoreState: function(){
-		dojo.forEach(this.getChildren(), function(child, i){
+		array.forEach(this.getChildren(), function(child, i){
 			var cookieName = this._getCookieName(i);
-			var cookieValue = dojo.cookie(cookieName);
+			var cookieValue = cookie(cookieName);
 			if(cookieValue){
 				var pos = parseInt(cookieValue);
 				if(typeof pos == "number"){
@@ -549,31 +602,10 @@ dojo.declare("dijit.layout.SplitContainer",
 		if(!this.persist){
 			return;
 		}
-		dojo.forEach(this.getChildren(), function(child, i){
-			dojo.cookie(this._getCookieName(i), child.sizeShare, {expires:365});
+		array.forEach(this.getChildren(), function(child, i){
+			cookie(this._getCookieName(i), child.sizeShare, {expires:365});
 		}, this);
 	}
 });
 
-// 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.)
-dojo.extend(dijit._Widget, {
-	// 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 dijit.layout.SplitContainer;
 });
diff --git a/dijit/layout/StackContainer.js b/dijit/layout/StackContainer.js
index c9db4f0..4f81a3e 100644
--- a/dijit/layout/StackContainer.js
+++ b/dijit/layout/StackContainer.js
@@ -1,9 +1,66 @@
-define("dijit/layout/StackContainer", ["dojo", "dijit", "dijit/_Templated", "dijit/layout/_LayoutWidget", "i18n!dijit/nls/common", "dojo/cookie", "dijit/layout/StackController"], function(dojo, dijit) {
+define([
+	"dojo/_base/array", // array.forEach array.indexOf array.some
+	"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/ready",
+	"dojo/topic", // publish
+	"../registry",	// registry.byId
+	"../_WidgetBase",
+	"./_LayoutWidget",
+	"dojo/i18n!../nls/common"
+], function(array, cookie, declare, domClass, kernel, lang, ready, topic,
+			registry, _WidgetBase, _LayoutWidget){
 
-dojo.declare(
-	"dijit.layout.StackContainer",
-	dijit.layout._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
@@ -35,8 +92,8 @@ dojo.declare(
 
 	buildRendering: function(){
 		this.inherited(arguments);
-		dojo.addClass(this.domNode, "dijitLayoutContainer");
-		dijit.setWaiRole(this.containerNode, "tabpanel");
+		domClass.add(this.domNode, "dijitLayoutContainer");
+		this.containerNode.setAttribute("role", "tabpanel");
 	},
 
 	postCreate: function(){
@@ -50,13 +107,13 @@ dojo.declare(
 		var children = this.getChildren();
 
 		// Setup each page panel to be initially hidden
-		dojo.forEach(children, this._setupChild, this);
+		array.forEach(children, this._setupChild, this);
 
 		// Figure out which child to initially display, defaulting to first one
 		if(this.persist){
-			this.selectedChildWidget = dijit.byId(dojo.cookie(this.id + "_selectedChild"));
+			this.selectedChildWidget = registry.byId(cookie(this.id + "_selectedChild"));
 		}else{
-			dojo.some(children, function(child){
+			array.some(children, function(child){
 				if(child.selected){
 					this.selectedChildWidget = child;
 				}
@@ -72,7 +129,7 @@ dojo.declare(
 		// 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.
-		dojo.publish(this.id+"-startup", [{children: children, selected: selected}]);
+		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.
@@ -81,12 +138,14 @@ dojo.declare(
 
 	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
+		// if we are initially visible). If this is the first time we've been made
 		// visible then show our first child.
-		var selected = this.selectedChildWidget;
-		if(selected && !this._hasBeenShown){
+		if(!this._hasBeenShown){
 			this._hasBeenShown = true;
-			this._showChild(selected);
+			var selected = this.selectedChildWidget;
+			if(selected){
+				this._showChild(selected);
+			}
 		}
 		this.inherited(arguments);
 	},
@@ -96,7 +155,7 @@ dojo.declare(
 
 		this.inherited(arguments);
 
-		dojo.replaceClass(child.domNode, "dijitHidden", "dijitVisible");
+		domClass.replace(child.domNode, "dijitHidden", "dijitVisible");
 
 		// remove the title attribute so it doesn't show up when i hover
 		// over a node
@@ -109,13 +168,15 @@ dojo.declare(
 		this.inherited(arguments);
 
 		if(this._started){
-			dojo.publish(this.id+"-addChild", [child, insertIndex]);
+			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()
+			// 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
@@ -132,12 +193,12 @@ dojo.declare(
 
 		if(this._started){
 			// this will notify any tablists to remove a button; do this first because it may affect sizing
-			dojo.publish(this.id + "-removeChild", [page]);
+			topic.publish(this.id + "-removeChild", page);	// publish
 		}
 
-		// If we 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._beingDestroyed){ return; }
+		// 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; }
 
 		// 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.
@@ -165,26 +226,32 @@ dojo.declare(
 		// page:
 		//		Reference to child widget or id of child widget
 
-		page = dijit.byId(page);
+		page = registry.byId(page);
 
 		if(this.selectedChildWidget != page){
 			// Deselect old page and select new one
 			var d = this._transition(page, this.selectedChildWidget, animate);
 			this._set("selectedChildWidget", page);
-			dojo.publish(this.id+"-selectChild", [page]);
+			topic.publish(this.id+"-selectChild", page);	// publish
 
 			if(this.persist){
-				dojo.cookie(this.id + "_selectedChild", this.selectedChildWidget.id);
+				cookie(this.id + "_selectedChild", this.selectedChildWidget.id);
 			}
 		}
 
 		return d;		// If child has an href, promise that fires when the child's href finishes loading
 	},
 
-	_transition: function(/*dijit._Widget*/ newWidget, /*dijit._Widget*/ oldWidget, /*Boolean*/ animate){
+	_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){
@@ -212,7 +279,7 @@ dojo.declare(
 		// summary:
 		//		Gets the next/previous child widget in this container from the current selection.
 		var children = this.getChildren();
-		var index = dojo.indexOf(children, this.selectedChildWidget);
+		var index = array.indexOf(children, this.selectedChildWidget);
 		index += forward ? 1 : children.length - 1;
 		return children[ index % children.length ]; // dijit._Widget
 	},
@@ -230,13 +297,18 @@ dojo.declare(
 	},
 
 	_onKeyPress: function(e){
-		dojo.publish(this.id+"-containerKeyPress", [{ e: e, page: this}]);
+		topic.publish(this.id+"-containerKeyPress", { e: e, page: this});	// publish
 	},
 
 	layout: function(){
 		// Implement _LayoutWidget.layout() virtual method.
-		if(this.doLayout && this.selectedChildWidget && this.selectedChildWidget.resize){
-			this.selectedChildWidget.resize(this._containerContentBox || this._contentBox);
+		var child = this.selectedChildWidget;
+		if(child && child.resize){
+			if(this.doLayout){
+				child.resize(this._containerContentBox || this._contentBox);
+			}else{
+				child.resize();
+			}
 		}
 	},
 
@@ -251,9 +323,9 @@ dojo.declare(
 		page.isLastChild = (page == children[children.length-1]);
 		page._set("selected", true);
 
-		dojo.replaceClass(page.domNode, "dijitVisible", "dijitHidden");
+		domClass.replace(page.domNode, "dijitVisible", "dijitHidden");
 
-		return page._onShow() || true;
+		return (page._onShow && page._onShow()) || true;
 	},
 
 	_hideChild: function(/*dijit._Widget*/ page){
@@ -261,9 +333,9 @@ dojo.declare(
 		//		Hide the specified child by changing it's CSS, and call _onHide() so
 		//		it's notified.
 		page._set("selected", false);
-		dojo.replaceClass(page.domNode, "dijitHidden", "dijitVisible");
+		domClass.replace(page.domNode, "dijitHidden", "dijitVisible");
 
-		page.onHide();
+		page.onHide && page.onHide();
 	},
 
 	closeChild: function(/*dijit._Widget*/ page){
@@ -281,43 +353,16 @@ dojo.declare(
 	},
 
 	destroyDescendants: function(/*Boolean*/ preserveDom){
-		dojo.forEach(this.getChildren(), function(child){
-			this.removeChild(child);
+		this._descendantsBeingDestroyed = true;
+		this.selectedChildWidget = undefined;
+		array.forEach(this.getChildren(), function(child){
+			if(!preserveDom){
+				this.removeChild(child);
+			}
 			child.destroyRecursive(preserveDom);
 		}, this);
+		this._descendantsBeingDestroyed = false;
 	}
 });
 
-// For back-compat, remove for 2.0
-
-
-// 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.)
-dojo.extend(dijit._Widget, {
-	// 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: "",
-
-	// 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 dijit.layout.StackContainer;
 });
diff --git a/dijit/layout/StackController.js b/dijit/layout/StackController.js
index c6fdb81..6f0cf81 100644
--- a/dijit/layout/StackController.js
+++ b/dijit/layout/StackController.js
@@ -1,285 +1,33 @@
-define("dijit/layout/StackController", ["dojo", "dijit", "dijit/_Widget", "dijit/_Templated", "dijit/_Container", "dijit/form/ToggleButton", "i18n!dijit/nls/common"], function(dojo, dijit) {
-
-dojo.declare(
-		"dijit.layout.StackController",
-		[dijit._Widget, dijit._Templated, dijit._Container],
-		{
-			// summary:
-			//		Set of buttons to select a page in a page list.
-			// description:
-			//		Monitors the specified StackContainer, and whenever a page is
-			//		added, deleted, or selected, updates itself accordingly.
-
-			templateString: "<span role='tablist' dojoAttachEvent='onkeypress' class='dijitStackController'></span>",
-
-			// containerId: [const] String
-			//		The id of the page container that I point to
-			containerId: "",
-
-			// buttonWidget: [const] String
-			//		The name of the button widget to create to correspond to each page
-			buttonWidget: "dijit.layout._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
-			},
-
-			buildRendering: function(){
-				this.inherited(arguments);
-				dijit.setWaiRole(this.domNode, "tablist");	// TODO: unneeded?   it's in template above.
-			},
-
-			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");
-			},
-
-			onStartup: function(/*Object*/ info){
-				// summary:
-				//		Called after StackContainer has finished initializing
-				// tags:
-				//		private
-				dojo.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(dijit.byId(pane));
-				}
-				this.inherited(arguments);
-			},
-
-			onAddChild: function(/*dijit._Widget*/ page, /*Integer?*/ insertIndex){
-				// summary:
-				//		Called whenever a page is added to the container.
-				//		Create button corresponding to the page.
-				// tags:
-				//		private
-
-				// create an instance of the button widget
-				var cls = dojo.getObject(this.buttonWidget);
-				var button = new cls({
-					id: this.id + "_" + page.id,
-					label: page.title,
-					dir: page.dir,
-					lang: page.lang,
-					showLabel: page.showTitle,
-					iconClass: page.iconClass,
-					closeButton: page.closable,
-					title: page.tooltip
-				});
-				dijit.setWaiState(button.focusNode,"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] = dojo.map(pageAttrList, function(pageAttr, idx){
-					return page.watch(pageAttr, function(name, oldVal, newVal){
-						button.set(buttonAttrList[idx], newVal);
-					});
-				});
-					
-				// connections so that clicking a tab button selects the corresponding page
-				this.pane2connects[page.id] = [
-					this.connect(button, 'onClick', dojo.hitch(this,"onButtonClick", page)),
-					this.connect(button, 'onClickCloseButton', dojo.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");
-					dijit.setWaiState(button.focusNode, "selected", "true");
-					this._currentChild = page;
-				}
-				// make sure all tabs have the same length
-				if(!this.isLeftToRight() && dojo.isIE && this._rectifyRtlTabList){
-					this._rectifyRtlTabList();
-				}
-			},
-
-			onRemoveChild: function(/*dijit._Widget*/ 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
-				dojo.forEach(this.pane2connects[page.id], dojo.hitch(this, "disconnect"));
-				delete this.pane2connects[page.id];
-				dojo.forEach(this.pane2watches[page.id], function(w){ w.unwatch(); });
-				delete this.pane2watches[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){
-				// summary:
-				//		Called when a page has been selected in the StackContainer, either by me or by another StackController
-				// tags:
-				//		private
-
-				if(!page){ return; }
-
-				if(this._currentChild){
-					var oldButton=this.pane2button[this._currentChild.id];
-					oldButton.set('checked', false);
-					dijit.setWaiState(oldButton.focusNode, "selected", "false");
-					oldButton.focusNode.setAttribute("tabIndex", "-1");
-				}
-
-				var newButton=this.pane2button[page.id];
-				newButton.set('checked', true);
-				dijit.setWaiState(newButton.focusNode, "selected", "true");
-				this._currentChild = page;
-				newButton.focusNode.setAttribute("tabIndex", "0");
-				var container = dijit.byId(this.containerId);
-				dijit.setWaiState(container.containerNode, "labelledby", newButton.id);
-			},
-
-			onButtonClick: function(/*dijit._Widget*/ page){
-				// summary:
-				//		Called whenever one of my child buttons is pressed in an attempt to select a page
-				// tags:
-				//		private
-
-				var container = dijit.byId(this.containerId);
-				container.selectChild(page);
-			},
-
-			onCloseButtonClick: function(/*dijit._Widget*/ page){
-				// summary:
-				//		Called whenever one of my child buttons [X] is pressed in an attempt to close a page
-				// tags:
-				//		private
-
-				var container = dijit.byId(this.containerId);
-				container.closeChild(page);
-				if(this._currentChild){
-					var b = this.pane2button[this._currentChild.id];
-					if(b){
-						dijit.focus(b.focusNode || b.domNode);
-					}
-				}
-			},
-
-			// 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
-				// tags:
-				//		private
-
-				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 = dojo.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
-			},
-
-			onkeypress: function(/*Event*/ e){
-				// 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; }
-				var forward = null;
-				if(e.ctrlKey || !e._djpage){
-					var k = dojo.keys;
-					switch(e.charOrCode){
-						case k.LEFT_ARROW:
-						case k.UP_ARROW:
-							if(!e._djpage){ forward = false; }
-							break;
-						case k.PAGE_UP:
-							if(e.ctrlKey){ forward = false; }
-							break;
-						case k.RIGHT_ARROW:
-						case k.DOWN_ARROW:
-							if(!e._djpage){ forward = true; }
-							break;
-						case k.PAGE_DOWN:
-							if(e.ctrlKey){ forward = true; }
-							break;
-						case k.HOME:
-						case k.END:
-							var children = this.getChildren();
-							if(children && children.length){
-								children[e.charOrCode == k.HOME ? 0 : children.length-1].onClick();
-							}
-							dojo.stopEvent(e);
-							break;
-						case k.DELETE:
-							if(this._currentChild.closable){
-								this.onCloseButtonClick(this._currentChild);
-							}
-							dojo.stopEvent(e);
-							break;
-						default:
-							if(e.ctrlKey){
-								if(e.charOrCode === k.TAB){
-									this.adjacent(!e.shiftKey).onClick();
-									dojo.stopEvent(e);
-								}else if(e.charOrCode == "w"){
-									if(this._currentChild.closable){
-										this.onCloseButtonClick(this._currentChild);
-									}
-									dojo.stopEvent(e); // avoid browser tab closing.
-								}
-							}
-					}
-					// handle next/previous page navigation (left/right arrow, etc.)
-					if(forward !== null){
-						this.adjacent(forward).onClick();
-						dojo.stopEvent(e);
-					}
-				}
-			},
-
-			onContainerKeyPress: function(/*Object*/ info){
-				// summary:
-				//		Called when there was a keypress on the container
-				// tags:
-				//		private
-				info.e._djpage = info.page;
-				this.onkeypress(info.e);
-			}
-	});
-
-
-dojo.declare("dijit.layout._StackButton",
-		dijit.form.ToggleButton,
-		{
+define([
+	"dojo/_base/array", // array.forEach array.indexOf array.map
+	"dojo/_base/declare", // declare
+	"dojo/_base/event", // event.stop
+	"dojo/keys", // keys
+	"dojo/_base/lang", // lang.getObject
+	"dojo/_base/sniff", // has("ie")
+	"../focus",		// focus.focus()
+	"../registry",	// registry.byId
+	"../_Widget",
+	"../_TemplatedMixin",
+	"../_Container",
+	"../form/ToggleButton",
+	"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;
+=====*/
+
+	// 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:
 		//		Internal widget used by StackContainer.
 		// description:
@@ -292,17 +40,26 @@ dojo.declare("dijit.layout._StackButton",
 		// Probably we should be calling this.startupKeyNavChildren() instead.
 		tabIndex: "-1",
 
+		// 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");
+		},
+
 		buildRendering: function(/*Event*/ evt){
 			this.inherited(arguments);
-			dijit.setWaiRole((this.focusNode || this.domNode), "tab");
+			(this.focusNode || this.domNode).setAttribute("role", "tab");
 		},
 
-		onClick: function(/*Event*/ evt){
+		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.
-			dijit.focus(this.focusNode);
+			focus.focus(this.focusNode);
 
 			// ... now let StackController catch the event and tell me what to do
 		},
@@ -317,5 +74,283 @@ dojo.declare("dijit.layout._StackButton",
 	});
 
 
-return dijit.layout.StackController;
+	var StackController = declare("dijit.layout.StackController", [_Widget, _TemplatedMixin, _Container], {
+		// summary:
+		//		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>",
+
+		// containerId: [const] String
+		//		The id of the page container that I point to
+		containerId: "",
+
+		// buttonWidget: [const] Constructor
+		//		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
+		},
+
+		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");
+		},
+
+		onStartup: function(/*Object*/ info){
+			// summary:
+			//		Called after StackContainer has finished initializing
+			// tags:
+			//		private
+			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));
+			}
+			this.inherited(arguments);
+		},
+
+		onAddChild: function(/*dijit._Widget*/ page, /*Integer?*/ insertIndex){
+			// summary:
+			//		Called whenever a page is added to the container.
+			//		Create button corresponding to the page.
+			// tags:
+			//		private
+
+			// 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({
+				id: this.id + "_" + page.id,
+				label: page.title,
+				dir: page.dir,
+				lang: page.lang,
+				textDir: page.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);
+				});
+			});
+
+			// 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();
+			}
+		},
+
+		onRemoveChild: function(/*dijit._Widget*/ 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];
+
+			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){
+			// summary:
+			//		Called when a page has been selected in the StackContainer, either by me or by another StackController
+			// tags:
+			//		private
+
+			if(!page){ return; }
+
+			if(this._currentChild){
+				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];
+			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){
+			// 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) {
+				//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){
+			// summary:
+			//		Called whenever one of my child buttons [X] is pressed in an attempt to close a page
+			// tags:
+			//		private
+
+			var container = registry.byId(this.containerId);
+			container.closeChild(page);
+			if(this._currentChild){
+				var b = this.pane2button[this._currentChild.id];
+				if(b){
+					focus.focus(b.focusNode || b.domNode);
+				}
+			}
+		},
+
+		// 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
+			// tags:
+			//		private
+
+			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
+		},
+
+		onkeypress: function(/*Event*/ e){
+			// 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; }
+			var forward = null;
+			if(e.ctrlKey || !e._djpage){
+				switch(e.charOrCode){
+					case keys.LEFT_ARROW:
+					case keys.UP_ARROW:
+						if(!e._djpage){ forward = false; }
+						break;
+					case keys.PAGE_UP:
+						if(e.ctrlKey){ forward = false; }
+						break;
+					case keys.RIGHT_ARROW:
+					case keys.DOWN_ARROW:
+						if(!e._djpage){ forward = true; }
+						break;
+					case keys.PAGE_DOWN:
+						if(e.ctrlKey){ forward = true; }
+						break;
+					case keys.HOME:
+					case keys.END:
+						var children = this.getChildren();
+						if(children && children.length){
+							children[e.charOrCode == keys.HOME ? 0 : children.length-1].onClick();
+						}
+						event.stop(e);
+						break;
+					case keys.DELETE:
+						if(this._currentChild.closable){
+							this.onCloseButtonClick(this._currentChild);
+						}
+						event.stop(e);
+						break;
+					default:
+						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.
+							}
+						}
+				}
+				// handle next/previous page navigation (left/right arrow, etc.)
+				if(forward !== null){
+					this.adjacent(forward).onClick();
+					event.stop(e);
+				}
+			}
+		},
+
+		onContainerKeyPress: function(/*Object*/ info){
+			// summary:
+			//		Called when there was a keypress on the container
+			// tags:
+			//		private
+			info.e._djpage = info.page;
+			this.onkeypress(info.e);
+		}
+	});
+
+	StackController.StackButton = StackButton;	// for monkey patching
+
+	return StackController;
 });
diff --git a/dijit/layout/TabContainer.js b/dijit/layout/TabContainer.js
index cc90e60..a04b59b 100644
--- a/dijit/layout/TabContainer.js
+++ b/dijit/layout/TabContainer.js
@@ -1,8 +1,24 @@
-define("dijit/layout/TabContainer", ["dojo", "dijit", "dijit/layout/_TabContainerBase", "dijit/layout/TabController", "dijit/layout/ScrollingTabController"], function(dojo, dijit) {
+define([
+	"dojo/_base/lang", // lang.getObject
+	"dojo/_base/declare", // declare
+	"./_TabContainerBase",
+	"./TabController",
+	"./ScrollingTabController"
+], function(lang, declare, _TabContainerBase, TabController, ScrollingTabController){
 
-dojo.declare("dijit.layout.TabContainer",
-	dijit.layout._TabContainerBase,
-	{
+/*=====
+	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, {
 		// summary:
 		//		A Container with tabs to select each child (only one of which is displayed at a time).
 		// description:
@@ -32,12 +48,13 @@ dojo.declare("dijit.layout.TabContainer",
 			//		protected extension
 
 			var cls = this.baseClass + "-tabs" + (this.doLayout ? "" : " dijitTabNoLayout"),
-				TabController = dojo.getObject(this.controllerWidget);
+				TabController = lang.getObject(this.controllerWidget);
 
 			return new TabController({
 				id: this.id + "_tablist",
 				dir: this.dir,
 				lang: this.lang,
+				textDir: this.textDir,
 				tabPosition: this.tabPosition,
 				doLayout: this.doLayout,
 				containerId: this.id,
@@ -58,8 +75,5 @@ dojo.declare("dijit.layout.TabContainer",
 							"dijit.layout.ScrollingTabController" : "dijit.layout.TabController";
 			}
 		}
-});
-
-
-return dijit.layout.TabContainer;
+	});
 });
diff --git a/dijit/layout/TabController.js b/dijit/layout/TabController.js
index 9517184..6ec46d9 100644
--- a/dijit/layout/TabController.js
+++ b/dijit/layout/TabController.js
@@ -1,149 +1,170 @@
-define("dijit/layout/TabController", ["dojo", "dijit", "text!dijit/layout/templates/_TabButton.html", "dijit/layout/StackController", "dijit/Menu", "dijit/MenuItem", "i18n!dijit/nls/common"], function(dojo, dijit) {
-
-// Menu is used for an accessible close button, would be nice to have a lighter-weight solution
-
-
-dojo.declare("dijit.layout.TabController",
-	dijit.layout.StackController,
-{
+define([
+	"dojo/_base/declare", // declare
+	"dojo/dom", // dom.setSelectable
+	"dojo/dom-attr", // domAttr.attr
+	"dojo/dom-class", // domClass.toggle
+	"dojo/i18n", // i18n.getLocalization
+	"dojo/_base/lang", // lang.hitch lang.trim
+	"./StackController",
+	"../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;
+=====*/
+
+	// 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`.
-	// description:
-	//		Lets the user select the currently shown pane in a TabContainer or StackContainer.
-	//		TabController also monitors the TabContainer, and whenever a pane is
-	//		added or deleted updates itself accordingly.
-	// tags:
-	//		private
-
-	templateString: "<div role='tablist' dojoAttachEvent='onkeypress:onkeypress'></div>",
-
-	// tabPosition: String
-	//		Defines where tabs go relative to the content.
-	//		"top", "bottom", "left-h", "right-h"
-	tabPosition: "top",
-
-	// buttonWidget: String
-	//		The name of the tab widget to create to correspond to each page
-	buttonWidget: "dijit.layout._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
-
-		if(0 >= this.tabPosition.indexOf('-h')){ return; }
-		if(!this.pane2button){ return; }
 
-		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';
-		}
-	}
-});
-
-dojo.declare("dijit.layout._TabButton",
-	dijit.layout._StackButton,
-	{
-	// summary:
-	//		A tab (the thing you click to select a pane).
-	// description:
-	//		Contains the title of the pane, and optionally a close-button to destroy the pane.
-	//		This is an internal widget and should not be instantiated directly.
-	// tags:
-	//		private
-
-	// baseClass: String
-	//		The CSS class applied to the domNode.
-	baseClass: "dijitTab",
-
-	// Apply dijitTabCloseButtonHover when close button is hovered
-	cssStateNodes: {
-		closeNode: "dijitTabCloseButton"
-	},
-
-	templateString: dojo.cache("dijit.layout","templates/_TabButton.html"),
-
-	// Override _FormWidget.scrollOnFocus.
-	// Don't scroll the whole tab container into view when the button is focused.
-	scrollOnFocus: false,
-
-	buildRendering: function(){
-		this.inherited(arguments);
-
-		dojo.setSelectable(this.containerNode, false);
-	},
-
-	startup: function(){
-		this.inherited(arguments);
-		var n = this.domNode;
-
-		// Required to give IE6 a kick, as it initially hides the
-		// tabs until they are focused on.
-		setTimeout(function(){
-			n.className = n.className;
-		}, 1);
-	},
-
-	_setCloseButtonAttr: function(/*Boolean*/ disp){
+	var TabButton = declare("dijit.layout._TabButton", StackController.StackButton, {
 		// summary:
-		//		Hide/show close button
-		this._set("closeButton", disp);
-		dojo.toggleClass(this.innerDiv, "dijitClosable", disp);
-		this.closeNode.style.display = disp ? "" : "none";
-		if(disp){
-			var _nlsResources = dojo.i18n.getLocalization("dijit", "common");
-			if(this.closeNode){
-				dojo.attr(this.closeNode,"title", _nlsResources.itemClose);
+		//		A tab (the thing you click to select a pane).
+		// description:
+		//		Contains the title of the pane, and optionally a close-button to destroy the pane.
+		//		This is an internal widget and should not be instantiated directly.
+		// tags:
+		//		private
+
+		// baseClass: String
+		//		The CSS class applied to the domNode.
+		baseClass: "dijitTab",
+
+		// Apply dijitTabCloseButtonHover when close button is hovered
+		cssStateNodes: {
+			closeNode: "dijitTabCloseButton"
+		},
+
+		templateString: template,
+
+		// Override _FormWidget.scrollOnFocus.
+		// Don't scroll the whole tab container into view when the button is focused.
+		scrollOnFocus: false,
+
+		buildRendering: function(){
+			this.inherited(arguments);
+
+			dom.setSelectable(this.containerNode, false);
+		},
+
+		startup: function(){
+			this.inherited(arguments);
+			var n = this.domNode;
+
+			// Required to give IE6 a kick, as it initially hides the
+			// tabs until they are focused on.
+			setTimeout(function(){
+				n.className = n.className;
+			}, 1);
+		},
+
+		_setCloseButtonAttr: function(/*Boolean*/ disp){
+			// summary:
+			//		Hide/show close button
+			this._set("closeButton", disp);
+			domClass.toggle(this.innerDiv, "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);
+				}
+				// 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;
+				}
+			}
+		},
+		_setLabelAttr: function(/*String*/ content){
+			// summary:
+			//		Hook for set('label', ...) to work.
+			// description:
+			//		takes an HTML string.
+			//		Inherited ToggleButton implementation will Set the label (text) of the button;
+			//		Need to set the alt attribute of icon on tab buttons if no label displayed
+			this.inherited(arguments);
+			if(!this.showLabel && !this.params.title){
+				this.iconNode.alt = lang.trim(this.containerNode.innerText || this.containerNode.textContent || '');
 			}
-			// add context menu onto title button
-			var _nlsResources = dojo.i18n.getLocalization("dijit", "common");
-			this._closeMenu = new dijit.Menu({
-				id: this.id+"_Menu",
-				dir: this.dir,
-				lang: this.lang,
-				targetNodeIds: [this.domNode]
-			});
-
-			this._closeMenu.addChild(new dijit.MenuItem({
-				label: _nlsResources.itemClose,
-				dir: this.dir,
-				lang: this.lang,
-				onClick: dojo.hitch(this, "onClickCloseButton")
-			}));
-		}else{
+		},
+
+		destroy: function(){
 			if(this._closeMenu){
 				this._closeMenu.destroyRecursive();
 				delete this._closeMenu;
 			}
+			this.inherited(arguments);
 		}
-	},
-	_setLabelAttr: function(/*String*/ content){
+	});
+
+	var TabController = declare("dijit.layout.TabController", StackController, {
 		// summary:
-		//		Hook for set('label', ...) to work.
+		// 		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:
-		//		takes an HTML string.
-		//		Inherited ToggleButton implementation will Set the label (text) of the button;
-		//		Need to set the alt attribute of icon on tab buttons if no label displayed
-		this.inherited(arguments);
-		if(this.showLabel == false && !this.params.title){
-			this.iconNode.alt = dojo.trim(this.containerNode.innerText || this.containerNode.textContent || '');
-		}
-	},
+		//		Lets the user select the currently shown pane in a TabContainer or StackContainer.
+		//		TabController also monitors the TabContainer, and whenever a pane is
+		//		added or deleted updates itself accordingly.
+		// tags:
+		//		private
+
+		baseClass: "dijitTabController",
+
+		templateString: "<div role='tablist' data-dojo-attach-event='onkeypress:onkeypress'></div>",
 
-	destroy: function(){
-		if(this._closeMenu){
-			this._closeMenu.destroyRecursive();
-			delete this._closeMenu;
+		// tabPosition: String
+		//		Defines where tabs go relative to the content.
+		//		"top", "bottom", "left-h", "right-h"
+		tabPosition: "top",
+
+		// buttonWidget: Constructor
+		//		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
+
+			if(0 >= this.tabPosition.indexOf('-h')){ return; }
+			if(!this.pane2button){ return; }
+
+			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';
+			}
 		}
-		this.inherited(arguments);
-	}
-});
+	});
 
+	TabController.TabButton = TabButton;	// for monkey patching
 
-return dijit.layout.TabController;
+	return TabController;
 });
diff --git a/dijit/layout/_ContentPaneResizeMixin.js b/dijit/layout/_ContentPaneResizeMixin.js
index 7db832d..aa348cb 100644
--- a/dijit/layout/_ContentPaneResizeMixin.js
+++ b/dijit/layout/_ContentPaneResizeMixin.js
@@ -1,6 +1,32 @@
-define("dijit/layout/_ContentPaneResizeMixin", ["dojo", "dijit", "dijit/_Contained", "dijit/layout/_LayoutWidget"], function(dojo, dijit) {
-
-dojo.declare("dijit.layout._ContentPaneResizeMixin", null, {
+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/_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.
@@ -15,28 +41,11 @@ dojo.declare("dijit.layout._ContentPaneResizeMixin", null, {
 	//				however big the ContentPane is
 	doLayout: true,
 
-	// isContainer: [protected] Boolean
-	//		Indicates that this widget acts as a "parent" to the descendant widgets.
-	//		When the parent is started it will call startup() on the child widgets.
-	//		See also `isLayoutContainer`.
-	isContainer: true,
-
 	// isLayoutContainer: [protected] Boolean
 	//		Indicates that this widget will call resize() on it's child widgets
 	//		when they become visible.
 	isLayoutContainer: true,
 
-	_startChildren: function(){
-		// summary:
-		//		Call startup() on all children including non _Widget ones like dojo.dnd.Source objects
-
-		// This starts all the widgets
-		dojo.forEach(this.getChildren(), function(child){
-			child.startup();
-			child._started = true;
-		});
-	},
-
 	startup: function(){
 		// summary:
 		//		See `dijit.layout._LayoutWidget.startup` for description.
@@ -45,7 +54,7 @@ dojo.declare("dijit.layout._ContentPaneResizeMixin", null, {
 
 		if(this._started){ return; }
 
-		var parent = dijit._Contained.prototype.getParent.call(this);
+		var parent = this.getParent();
 		this._childOfLayoutWidget = parent && parent.isLayoutContainer;
 
 		// I need to call resize() on my child/children (when I become visible), unless
@@ -54,8 +63,6 @@ dojo.declare("dijit.layout._ContentPaneResizeMixin", null, {
 
 		this.inherited(arguments);
 
-		this._startChildren();
-
 		if(this._isShown()){
 			this._onShow();
 		}
@@ -66,7 +73,7 @@ dojo.declare("dijit.layout._ContentPaneResizeMixin", null, {
 			// 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(dojo.isIE ? this.domNode : dojo.global, 'onresize', function(){
+			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();
@@ -81,13 +88,13 @@ dojo.declare("dijit.layout._ContentPaneResizeMixin", null, {
 		//		and should propagate startup() and resize() calls to it.
 		//		Skips over things like data stores since they aren't visible.
 
-		var childNodes = dojo.query("> *", this.containerNode).filter(function(node){
+		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 dojo.hasAttr(node, "data-dojo-type") || dojo.hasAttr(node, "dojoType") || dojo.hasAttr(node, "widgetId");
+				return domAttr.has(node, "data-dojo-type") || domAttr.has(node, "dojoType") || domAttr.has(node, "widgetId");
 			}),
-			candidateWidgets = dojo.filter(childWidgetNodes.map(dijit.byNode), function(widget){
+			candidateWidgets = array.filter(childWidgetNodes.map(registry.byNode), function(widget){
 				return widget && widget.domNode && widget.resize;
 			});
 
@@ -104,7 +111,7 @@ dojo.declare("dijit.layout._ContentPaneResizeMixin", null, {
 		}
 
 		// So we can set overflow: hidden to avoid a safari bug w/scrollbars showing up (#9449)
-		dojo.toggleClass(this.containerNode, this.baseClass + "SingleChild", !!this._singleChild);
+		domClass.toggle(this.containerNode, this.baseClass + "SingleChild", !!this._singleChild);
 	},
 
 	resize: function(changeSize, resultSize){
@@ -150,7 +157,7 @@ dojo.declare("dijit.layout._ContentPaneResizeMixin", null, {
 
 		// Set margin box size, unless it wasn't specified, in which case use current size.
 		if(changeSize){
-			dojo.marginBox(this.domNode, changeSize);
+			domGeometry.setMarginBox(this.domNode, changeSize);
 		}
 
 		// Compute content box size of containerNode in case we [later] need to size our single child.
@@ -160,20 +167,20 @@ dojo.declare("dijit.layout._ContentPaneResizeMixin", null, {
 			// 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 || {};
-			dojo.mixin(mb, changeSize || {}); // changeSize overrides resultSize
+			lang.mixin(mb, changeSize || {}); // changeSize overrides resultSize
 			if(!("h" in mb) || !("w" in mb)){
-				mb = dojo.mixin(dojo.marginBox(cn), mb); // just use dojo.marginBox() to fill in missing values
+				mb = lang.mixin(domGeometry.getMarginBox(cn), mb); // just use domGeometry.setMarginBox() to fill in missing values
 			}
-			this._contentBox = dijit.layout.marginBox2contentBox(cn, mb);
+			this._contentBox = layoutUtils.marginBox2contentBox(cn, mb);
 		}else{
-			this._contentBox = dojo.contentBox(cn);
+			this._contentBox = domGeometry.getContentBox(cn);
 		}
 
 		this._layoutChildren();
 
 		delete this._needLayout;
 	},
-	
+
 	_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.
@@ -182,7 +189,7 @@ dojo.declare("dijit.layout._ContentPaneResizeMixin", null, {
 		}
 
 		if(this._singleChild && this._singleChild.resize){
-			var cb = this._contentBox || dojo.contentBox(this.containerNode);
+			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
@@ -190,7 +197,7 @@ dojo.declare("dijit.layout._ContentPaneResizeMixin", null, {
 		}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.
-			dojo.forEach(this.getChildren(), function(widget){
+			array.forEach(this.getChildren(), function(widget){
 				if(widget.resize){
 					widget.resize();
 				}
@@ -217,7 +224,7 @@ dojo.declare("dijit.layout._ContentPaneResizeMixin", null, {
 			return this.open;		// for TitlePane, etc.
 		}else{
 			var node = this.domNode, parent = this.domNode.parentNode;
-			return (node.style.display != 'none') && (node.style.visibility != 'hidden') && !dojo.hasClass(node, "dijitHidden") &&
+			return (node.style.display != 'none') && (node.style.visibility != 'hidden') && !domClass.contains(node, "dijitHidden") &&
 					parent && parent.style && (parent.style.display != 'none');
 		}
 	},
@@ -245,6 +252,4 @@ dojo.declare("dijit.layout._ContentPaneResizeMixin", null, {
 	}
 });
 
-
-return dijit.layout._ContentPaneResizeMixin;
 });
diff --git a/dijit/layout/_LayoutWidget.js b/dijit/layout/_LayoutWidget.js
index 6436681..76324b4 100644
--- a/dijit/layout/_LayoutWidget.js
+++ b/dijit/layout/_LayoutWidget.js
@@ -1,8 +1,31 @@
-define("dijit/layout/_LayoutWidget", ["dojo", "dijit", "dijit/_Widget", "dijit/_Container", "dijit/_Contained"], function(dojo, dijit) {
+define([
+	"dojo/_base/lang", // lang.mixin
+	"../_Widget",
+	"../_Container",
+	"../_Contained",
+	"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;
+=====*/
+
+	// 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.
+
 
-dojo.declare("dijit.layout._LayoutWidget",
-	[dijit._Widget, dijit._Container, dijit._Contained],
-	{
+	return declare("dijit.layout._LayoutWidget", [_Widget, _Container, _Contained], {
 		// summary:
 		//		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.
@@ -20,13 +43,13 @@ dojo.declare("dijit.layout._LayoutWidget",
 
 		buildRendering: function(){
 			this.inherited(arguments);
-			dojo.addClass(this.domNode, "dijitContainer");
+			domClass.add(this.domNode, "dijitContainer");
 		},
 
 		startup: function(){
 			// summary:
 			//		Called after all the widgets have been instantiated and their
-			//		dom nodes have been inserted somewhere under dojo.doc.body.
+			//		dom nodes have been inserted somewhere under win.doc.body.
 			//
 			//		Widgets should override this method to do any initialization
 			//		dependent on other widgets existing, and then call
@@ -42,7 +65,7 @@ dojo.declare("dijit.layout._LayoutWidget",
 			this.inherited(arguments);
 
 			// If I am a not being controlled by a parent layout widget...
-			var parent = this.getParent && this.getParent()
+			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)
@@ -50,11 +73,9 @@ dojo.declare("dijit.layout._LayoutWidget",
 
 				// 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(dojo.isIE ? this.domNode : dojo.global, 'onresize', function(){
-					// Using function(){} closure to ensure no arguments to resize.
+				// 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();
 				});
 			}
@@ -100,35 +121,31 @@ dojo.declare("dijit.layout._LayoutWidget",
 
 			// set margin box size, unless it wasn't specified, in which case use current size
 			if(changeSize){
-				dojo.marginBox(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"; }
+				domGeometry.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 || {};
-			dojo.mixin(mb, changeSize || {});	// changeSize overrides resultSize
+			lang.mixin(mb, changeSize || {});	// changeSize overrides resultSize
 			if( !("h" in mb) || !("w" in mb) ){
-				mb = dojo.mixin(dojo.marginBox(node), mb);	// just use dojo.marginBox() to fill in missing values
+				mb = lang.mixin(domGeometry.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 dojo.contentBox() since that may fail if size was recently set)
-			var cs = dojo.getComputedStyle(node);
-			var me = dojo._getMarginExtents(node, cs);
-			var be = dojo._getBorderExtents(node, cs);
+			// (w/out calling domGeometry.getContentBox() since that may fail if size was recently set)
+			var cs = domStyle.getComputedStyle(node);
+			var me = domGeometry.getMarginExtents(node, cs);
+			var be = domGeometry.getBorderExtents(node, cs);
 			var bb = (this._borderBox = {
 				w: mb.w - (me.w + be.w),
 				h: mb.h - (me.h + be.h)
 			});
-			var pe = dojo._getPadExtents(node, cs);
+			var pe = domGeometry.getPadExtents(node, cs);
 			this._contentBox = {
-				l: dojo._toPixelValue(node, cs.paddingLeft),
-				t: dojo._toPixelValue(node, cs.paddingTop),
+				l: domStyle.toPixelValue(node, cs.paddingLeft),
+				t: domStyle.toPixelValue(node, cs.paddingTop),
 				w: bb.w - pe.w,
 				h: bb.h - pe.h
 			};
@@ -156,7 +173,7 @@ dojo.declare("dijit.layout._LayoutWidget",
 
 			var cls = this.baseClass + "-child "
 				+ (child.baseClass ? this.baseClass + "-" + child.baseClass : "");
-			dojo.addClass(child.domNode, cls);
+			domClass.add(child.domNode, cls);
 		},
 
 		addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){
@@ -172,131 +189,9 @@ dojo.declare("dijit.layout._LayoutWidget",
 			var cls = this.baseClass + "-child"
 					+ (child.baseClass ?
 						" " + this.baseClass + "-" + child.baseClass : "");
-			dojo.removeClass(child.domNode, cls);
-			
-			this.inherited(arguments);
-		}
-	}
-);
-
-dijit.layout.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 = dojo.getComputedStyle(node);
-	var me = dojo._getMarginExtents(node, cs);
-	var pb = dojo._getPadBorderExtents(node, cs);
-	return {
-		l: dojo._toPixelValue(node, cs.paddingLeft),
-		t: dojo._toPixelValue(node, cs.paddingTop),
-		w: mb.w - (me.w + pb.w),
-		h: mb.h - (me.h + pb.h)
-	};
-};
+			domClass.remove(child.domNode, cls);
 
-(function(){
-	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) : dojo.marginBox(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, dojo.marginBox(widget.domNode));
-			dojo.mixin(widget, dim);
+			this.inherited(arguments);
 		}
-	};
-
-	dijit.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
-		//			* 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);
-
-		dojo.addClass(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 = dojo.filter(children, function(item){ return item.region != "center" && item.layoutAlign != "client"; })
-			.concat(dojo.filter(children, function(item){ return item.region == "center" || item.layoutAlign == "client"; }));
-
-		// set positions/sizes
-		dojo.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";
-
-			dojo.addClass(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);
-			}
-		});
-	};
-
-})();
-
-
-return dijit.layout._LayoutWidget;
+	});
 });
diff --git a/dijit/layout/_TabContainerBase.js b/dijit/layout/_TabContainerBase.js
index 820f592..5796d74 100644
--- a/dijit/layout/_TabContainerBase.js
+++ b/dijit/layout/_TabContainerBase.js
@@ -1,8 +1,28 @@
-define("dijit/layout/_TabContainerBase", ["dojo", "dijit", "text!dijit/layout/templates/TabContainer.html", "dijit/layout/StackContainer", "dijit/_Templated"], function(dojo, dijit) {
-
-dojo.declare("dijit.layout._TabContainerBase",
-	[dijit.layout.StackContainer, dijit._Templated],
-	{
+define([
+	"dojo/text!./templates/TabContainer.html",
+	"./StackContainer",
+	"./utils",	// marginBox2contextBox, layoutChildren
+	"../_TemplatedMixin",
+	"dojo/_base/declare", // declare
+	"dojo/dom-class", // domClass.add
+	"dojo/dom-geometry", // domGeometry.contentBox
+	"dojo/dom-style" // domStyle.style
+], function(template, StackContainer, layoutUtils, _TemplatedMixin, declare, domClass, domGeometry, domStyle){
+
+
+/*=====
+	var StackContainer = dijit.layout.StackContainer;
+	var _TemplatedMixin = dijit._TemplatedMixin;
+=====*/
+
+// module:
+//		dijit/layout/_TabContainerBase
+// summary:
+//		Abstract base class for TabContainer.   Must define _makeController() to instantiate
+//		and return the widget that displays the tab labels
+
+
+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
@@ -29,13 +49,13 @@ dojo.declare("dijit.layout._TabContainerBase",
 	//		border since the outer TabContainer already has a border.
 	nested: false,
 
-	templateString: dojo.cache("dijit.layout", "templates/TabContainer.html"),
+	templateString: template,
 
 	postMixInProperties: function(){
 		// set class name according to tab position, ex: dijitTabContainerTop
 		this.baseClass += this.tabPosition.charAt(0).toUpperCase() + this.tabPosition.substr(1).replace(/-.*/, "");
 
-		this.srcNodeRef && dojo.style(this.srcNodeRef, "visibility", "hidden");
+		this.srcNodeRef && domStyle.set(this.srcNodeRef, "visibility", "hidden");
 
 		this.inherited(arguments);
 	},
@@ -46,24 +66,24 @@ dojo.declare("dijit.layout._TabContainerBase",
 		// 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.doLayout){ dojo.addClass(this.domNode, "dijitTabContainerNoLayout"); }
+		if(!this.doLayout){ domClass.add(this.domNode, "dijitTabContainerNoLayout"); }
 
 		if(this.nested){
 			/* workaround IE's lack of support for "a > b" selectors by
 			 * tagging each node in the template.
 			 */
-			dojo.addClass(this.domNode, "dijitTabContainerNested");
-			dojo.addClass(this.tablist.containerNode, "dijitTabContainerTabListNested");
-			dojo.addClass(this.tablistSpacer, "dijitTabContainerSpacerNested");
-			dojo.addClass(this.containerNode, "dijitTabPaneWrapperNested");
+			domClass.add(this.domNode, "dijitTabContainerNested");
+			domClass.add(this.tablist.containerNode, "dijitTabContainerTabListNested");
+			domClass.add(this.tablistSpacer, "dijitTabContainerSpacerNested");
+			domClass.add(this.containerNode, "dijitTabPaneWrapperNested");
 		}else{
-			dojo.addClass(this.domNode, "tabStrip-" + (this.tabStrip ? "enabled" : "disabled"));
+			domClass.add(this.domNode, "tabStrip-" + (this.tabStrip ? "enabled" : "disabled"));
 		}
 	},
 
 	_setupChild: function(/*dijit._Widget*/ tab){
 		// Overrides StackContainer._setupChild().
-		dojo.addClass(tab.domNode, "dijitTabPane");
+		domClass.add(tab.domNode, "dijitTabPane");
 		this.inherited(arguments);
 	},
 
@@ -95,11 +115,11 @@ dojo.declare("dijit.layout._TabContainerBase",
 				domNode: this.containerNode,
 				layoutAlign: "client"
 			}];
-			dijit.layout.layoutChildren(this.domNode, this._contentBox, children);
+			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 = dijit.layout.marginBox2contentBox(this.containerNode, children[2]);
+			this._containerContentBox = layoutUtils.marginBox2contentBox(this.containerNode, children[2]);
 
 			if(sc && sc.resize){
 				sc.resize(this._containerContentBox);
@@ -110,7 +130,7 @@ dojo.declare("dijit.layout._TabContainerBase",
 				//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 = dojo.contentBox(this.domNode).w;
+				var width = domGeometry.getContentBox(this.domNode).w;
 				s.width="";
 				this.tablist.resize({w: width});
 			}
@@ -130,6 +150,4 @@ dojo.declare("dijit.layout._TabContainerBase",
 	}
 });
 
-
-return dijit.layout._TabContainerBase;
 });
diff --git a/dijit/layout/templates/AccordionButton.html b/dijit/layout/templates/AccordionButton.html
index 8c0effc..d2a9eee 100644
--- a/dijit/layout/templates/AccordionButton.html
+++ b/dijit/layout/templates/AccordionButton.html
@@ -1,10 +1,10 @@
-<div dojoAttachEvent='onclick:_onTitleClick' class='dijitAccordionTitle'>
-	<div dojoAttachPoint='titleNode,focusNode' dojoAttachEvent='onkeypress:_onTitleKeyPress'
+<div data-dojo-attach-event='onclick:_onTitleClick' class='dijitAccordionTitle' role="presentation">
+	<div data-dojo-attach-point='titleNode,focusNode' data-dojo-attach-event='onkeypress:_onTitleKeyPress'
 			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" dojoAttachPoint='iconNode' style="vertical-align: middle" role="presentation"/>
-		<span role="presentation" dojoAttachPoint='titleTextNode' class='dijitAccordionText'></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>
 	</div>
 </div>
diff --git a/dijit/layout/templates/ScrollingTabController.html b/dijit/layout/templates/ScrollingTabController.html
index 28ad6b6..505b92f 100644
--- a/dijit/layout/templates/ScrollingTabController.html
+++ b/dijit/layout/templates/ScrollingTabController.html
@@ -1,19 +1,22 @@
 <div class="dijitTabListContainer-${tabPosition}" style="visibility:hidden">
-	<div dojoType="dijit.layout._ScrollingTabControllerMenuButton"
+	<div data-dojo-type="dijit.layout._ScrollingTabControllerMenuButton"
 			class="tabStripButton-${tabPosition}"
-			id="${id}_menuBtn" containerId="${containerId}" iconClass="dijitTabStripMenuIcon"
-			dropDownPosition="below-alt, above-alt"
-			dojoAttachPoint="_menuBtn" showLabel="false">▼</div>
-	<div dojoType="dijit.layout._ScrollingTabControllerButton"
+			id="${id}_menuBtn"
+			data-dojo-props="containerId: '${containerId}', iconClass: 'dijitTabStripMenuIcon',
+					dropDownPosition: ['below-alt', 'above-alt']"
+			data-dojo-attach-point="_menuBtn" showLabel="false" title="">▼</div>
+	<div data-dojo-type="dijit.layout._ScrollingTabControllerButton"
 			class="tabStripButton-${tabPosition}"
-			id="${id}_leftBtn" iconClass="dijitTabStripSlideLeftIcon"
-			dojoAttachPoint="_leftBtn" dojoAttachEvent="onClick: doSlideLeft" showLabel="false">◀</div>
-	<div dojoType="dijit.layout._ScrollingTabControllerButton"
+			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" iconClass="dijitTabStripSlideRightIcon"
-			dojoAttachPoint="_rightBtn" dojoAttachEvent="onClick: doSlideRight" showLabel="false">▶</div>
-	<div class='dijitTabListWrapper' dojoAttachPoint='tablistWrapper'>
-		<div role='tablist' dojoAttachEvent='onkeypress:onkeypress'
-				dojoAttachPoint='containerNode' class='nowrapTabStrip'></div>
+			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>
 </div>
\ No newline at end of file
diff --git a/dijit/layout/templates/TabContainer.html b/dijit/layout/templates/TabContainer.html
index d6dcf69..4630dbc 100644
--- a/dijit/layout/templates/TabContainer.html
+++ b/dijit/layout/templates/TabContainer.html
@@ -1,5 +1,5 @@
 <div class="dijitTabContainer">
-	<div class="dijitTabListWrapper" dojoAttachPoint="tablistNode"></div>
-	<div dojoAttachPoint="tablistSpacer" class="dijitTabSpacer ${baseClass}-spacer"></div>
-	<div class="dijitTabPaneWrapper ${baseClass}-container" dojoAttachPoint="containerNode"></div>
+	<div class="dijitTabListWrapper" data-dojo-attach-point="tablistNode"></div>
+	<div data-dojo-attach-point="tablistSpacer" class="dijitTabSpacer ${baseClass}-spacer"></div>
+	<div class="dijitTabPaneWrapper ${baseClass}-container" data-dojo-attach-point="containerNode"></div>
 </div>
diff --git a/dijit/layout/templates/_ScrollingTabControllerButton.html b/dijit/layout/templates/_ScrollingTabControllerButton.html
index 0c4b8f6..c7ef933 100644
--- a/dijit/layout/templates/_ScrollingTabControllerButton.html
+++ b/dijit/layout/templates/_ScrollingTabControllerButton.html
@@ -1,8 +1,8 @@
-<div dojoAttachEvent="onclick:_onButtonClick">
-	<div role="presentation" class="dijitTabInnerDiv" dojoattachpoint="innerDiv,focusNode">
-		<div role="presentation" class="dijitTabContent dijitButtonContents" dojoattachpoint="tabContent">
-			<img role="presentation" alt="" src="${_blankGif}" class="dijitTabStripIcon" dojoAttachPoint="iconNode"/>
-			<span dojoAttachPoint="containerNode,titleNode" class="dijitButtonText"></span>
+<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>
\ No newline at end of file
diff --git a/dijit/layout/templates/_TabButton.html b/dijit/layout/templates/_TabButton.html
index 53ce137..7d6570e 100644
--- a/dijit/layout/templates/_TabButton.html
+++ b/dijit/layout/templates/_TabButton.html
@@ -1,12 +1,12 @@
-<div role="presentation" dojoAttachPoint="titleNode" dojoAttachEvent='onclick:onClick'>
-    <div role="presentation" class='dijitTabInnerDiv' dojoAttachPoint='innerDiv'>
-        <div role="presentation" class='dijitTabContent' dojoAttachPoint='tabContent'>
-        	<div role="presentation" dojoAttachPoint='focusNode'>
-		        <img src="${_blankGif}" alt="" class="dijitIcon dijitTabButtonIcon" dojoAttachPoint='iconNode' />
-		        <span dojoAttachPoint='containerNode' class='tabLabel'></span>
-		        <span class="dijitInline dijitTabCloseButton dijitTabCloseIcon" dojoAttachPoint='closeNode'
-		        		dojoAttachEvent='onclick: onClickCloseButton' role="presentation">
-		            <span dojoAttachPoint='closeText' class='dijitTabCloseText'>[x]</span
+<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>
diff --git a/dijit/layout/utils.js b/dijit/layout/utils.js
new file mode 100644
index 0000000..6d8b4d4
--- /dev/null
+++ b/dijit/layout/utils.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
+	".."	// for exporting symbols to dijit, remove in 2.0
+], function(array, domClass, domGeometry, domStyle, lang, dijit){
+
+	// 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);
+	}
+
+	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
+		//			* 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";
+				}
+			}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/dijit/lib/main.js b/dijit/lib/main.js
deleted file mode 100644
index 70fd6d4..0000000
--- a/dijit/lib/main.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// AMD module id = dijit
-//
-// This is a package main module for the dijit package. The dijit package is somewhat unusual
-// in that is it currently constructed to just provide an empty object.
-//
-
-// for now, we publish dijit into the global namespace because so many tests and apps expect it.
-define(["dojo"], function(dojo) {
-	// the current dojo bootstrap defines dijit; this may change and this module provides a little
-	// future-proof with the disjunction.
-	dijit= dojo._dijit || {};
-	return dijit;
-});
diff --git a/dijit/main.js b/dijit/main.js
new file mode 100644
index 0000000..1b91ebb
--- /dev/null
+++ b/dijit/main.js
@@ -0,0 +1,10 @@
+define([
+	"dojo/_base/kernel"
+], function(dojo){
+	// module:
+	//		dijit
+	// summary:
+	//		The dijit package main module
+
+	return dojo.dijit;
+});
diff --git a/dijit/nls/az/common.js b/dijit/nls/az/common.js
new file mode 100644
index 0000000..49ef3dd
--- /dev/null
+++ b/dijit/nls/az/common.js
@@ -0,0 +1,10 @@
+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
new file mode 100644
index 0000000..4e868eb
--- /dev/null
+++ b/dijit/nls/az/loading.js
@@ -0,0 +1,8 @@
+define(
+//begin v1.x content
+({
+	"loadingState" : "Yüklənir...",
+	"errorState" : "Problem yarandı"
+})
+//end v1.x content
+);
diff --git a/dijit/nls/common.js b/dijit/nls/common.js
index e31c31e..e5151c2 100644
--- a/dijit/nls/common.js
+++ b/dijit/nls/common.js
@@ -27,6 +27,7 @@ define({ root:
 "ja": true,
 "it": true,
 "hu": true,
+"hr": true,
 "he": true,
 "fr": true,
 "fi": true,
@@ -36,5 +37,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"az": true,
 "ar": true
 });
diff --git a/dijit/nls/hr/common.js b/dijit/nls/hr/common.js
new file mode 100644
index 0000000..efdd4cb
--- /dev/null
+++ b/dijit/nls/hr/common.js
@@ -0,0 +1,8 @@
+define(
+({
+	buttonOk: "OK",
+	buttonCancel: "Opoziv",
+	buttonSave: "Spremi",
+	itemClose: "Zatvori"
+})
+);
diff --git a/dijit/nls/hr/loading.js b/dijit/nls/hr/loading.js
new file mode 100644
index 0000000..f14e8ee
--- /dev/null
+++ b/dijit/nls/hr/loading.js
@@ -0,0 +1,6 @@
+define(
+({
+	loadingState: "Učitavanje...",
+	errorState: "Žao nam je, došlo je do pogreške"
+})
+);
diff --git a/dijit/nls/loading.js b/dijit/nls/loading.js
index b46fc40..51ab92f 100644
--- a/dijit/nls/loading.js
+++ b/dijit/nls/loading.js
@@ -25,6 +25,7 @@ define({ root:
 "ja": true,
 "it": true,
 "hu": true,
+"hr": true,
 "he": true,
 "fr": true,
 "fi": true,
@@ -34,5 +35,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"az": true,
 "ar": true
 });
diff --git a/dijit/package.json b/dijit/package.json
index 9ca9423..b48f94c 100644
--- a/dijit/package.json
+++ b/dijit/package.json
@@ -1,24 +1,23 @@
 {
-  "name": "dijit",
-  "directories": {
-    "lib": "."
-  },
-  "main":"./lib/main",
-  "mappings": {
-    "dojo": "https://github.com/dojo/dojo/zipball/1.0.2"
-  },
-  "description": "Dijit is Dojo�s UI Library",
-  "licenses": [
-     {
-         "type": "AFLv2.1",
-         "url": "http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L43"
-     },
-     {
-         "type": "BSD",
-         "url": "http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L13"
-     }
-  ],
-  "bugs": "http://bugs.dojotoolkit.org/",
-  "keywords": ["JavaScript", "Dojo", "Widget"],
-  "homepage": "http://dojotoolkit.org/"
-}
\ No newline at end of file
+	"name": "dijit",
+	"version":"1.7.2",
+	"main":"main",
+	"dependencies": {
+		"dojo": "current"
+	},
+	"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": [
+		 {
+				 "type": "AFLv2.1",
+				 "url": "http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L43"
+		 },
+		 {
+				 "type": "BSD",
+				 "url": "http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L13"
+		 }
+	],
+	"bugs": "http://bugs.dojotoolkit.org/",
+	"keywords": ["JavaScript", "Dojo", "Widget"],
+	"homepage": "http://dojotoolkit.org/",
+	"dojoBuild": "dijit.profile.js"
+}
diff --git a/dijit/place.js b/dijit/place.js
new file mode 100644
index 0000000..47201d9
--- /dev/null
+++ b/dijit/place.js
@@ -0,0 +1,369 @@
+define([
+	"dojo/_base/array", // array.forEach array.map array.some
+	"dojo/dom-geometry", // domGeometry.getMarginBox 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){
+
+	// module:
+	//		dijit/place
+	// summary:
+	//		Code to place a popup relative to another node
+
+
+	function _place(/*DomNode*/ node, choices, layoutNode, aroundNodeCoords){
+		// summary:
+		//		Given a list of spots to put node, put it at the first spot where it fits,
+		//		of if it doesn't fit anywhere then the place with the least overflow
+		// choices: Array
+		//		Array of elements like: {corner: 'TL', pos: {x: 10, y: 20} }
+		//		Above example says to put the top-left corner of the node at (10,20)
+		// layoutNode: Function(node, aroundNodeCorner, nodeCorner, size)
+		//		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.
+		//		It also passes in the available size for the popup, which is useful for tooltips to
+		//		tell them that their width is limited to a certain amount.	 layoutNode() may return a value expressing
+		//		how much the popup had to be modified to fit into the available space.	 This is used to determine
+		//		what the best placement is.
+		// aroundNodeCoords: Object
+		//		Size of aroundNode, ex: {w: 200, h: 50}
+
+		// get {x: 10, y: 10, w: 100, h:100} type obj representing position of
+		// viewport over document
+		var view = winUtils.getBox();
+
+		// 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)
+		if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){
+			win.body().appendChild(node);
+		}
+
+		var best = null;
+		array.some(choices, function(choice){
+			var corner = choice.corner;
+			var pos = choice.pos;
+			var overflow = 0;
+
+			// calculate amount of space available given specified position of node
+			var spaceAvailable = {
+				w: {
+					'L': view.l + view.w - pos.x,
+					'R': pos.x - view.l,
+					'M': view.w
+				   }[corner.charAt(1)],
+				h: {
+					'T': view.t + view.h - pos.y,
+					'B': pos.y - view.t,
+					'M': view.h
+				   }[corner.charAt(0)]
+			};
+
+			// 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)
+			if(layoutNode){
+				var res = layoutNode(node, choice.aroundCorner, corner, spaceAvailable, aroundNodeCoords);
+				overflow = typeof res == "undefined" ? 0 : res;
+			}
+
+			// get node's size
+			var style = node.style;
+			var oldDisplay = style.display;
+			var oldVis = style.visibility;
+			if(style.display == "none"){
+				style.visibility = "hidden";
+				style.display = "";
+			}
+			var mb = domGeometry. getMarginBox(node);
+			style.display = oldDisplay;
+			style.visibility = oldVis;
+
+			// coordinates and size of node with specified corner placed at pos,
+			// and clipped by viewport
+			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
+				}[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)
+				}[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),
+				width = endX - startX,
+				height = endY - startY;
+
+			overflow += (mb.w - width) + (mb.h - height);
+
+			if(best == null || overflow < best.overflow){
+				best = {
+					corner: corner,
+					aroundCorner: choice.aroundCorner,
+					x: startX,
+					y: startY,
+					w: width,
+					h: height,
+					overflow: overflow,
+					spaceAvailable: spaceAvailable
+				};
+			}
+
+			return !overflow;
+		});
+
+		// In case the best position is not the last one we checked, need to call
+		// layoutNode() again.
+		if(best.overflow && layoutNode){
+			layoutNode(node, best.aroundCorner, best.corner, best.spaceAvailable, aroundNodeCoords);
+		}
+
+		// And then position the node.  Do this last, after the layoutNode() above
+		// has sized the node, due to browser quirks when the viewport is scrolled
+		// (specifically that a Tooltip will shrink to fit as though the window was
+		// scrolled to the left).
+		//
+		// 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;
+	}
+
+	/*=====
+	dijit.place.__Position = function(){
+		// x: Integer
+		//		horizontal coordinate in pixels, relative to document body
+		// y: Integer
+		//		vertical coordinate in pixels, relative to document body
+
+		this.x = x;
+		this.y = y;
+	};
+	=====*/
+
+	/*=====
+	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.
+
+		this.x = x;
+		this.y = y;
+		this.w = w;
+		this.h = h;
+	};
+	=====*/
+
+	return (dijit.place = {
+		// summary:
+		//		Code to place a DOMNode relative to another DOMNode.
+		//		Load using require(["dijit/place"], function(place){ ... }).
+
+		at: function(node, pos, corners, padding){
+			// 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.
+			// node: DOMNode
+			//		The node to 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"].
+			//		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.
+			// 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} };
+				if(padding){
+					c.pos.x += corner.charAt(1) == 'L' ? padding.x : -padding.x;
+					c.pos.y += corner.charAt(0) == 'T' ? padding.y : -padding.y;
+				}
+				return c;
+			});
+
+			return _place(node, choices);
+		},
+
+		around: function(
+			/*DomNode*/		node,
+			/*DomNode || dijit.place.__Rectangle*/ anchor,
+			/*String[]*/	positions,
+			/*Boolean*/		leftToRight,
+			/*Function?*/	layoutNode){
+
+			// 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).
+			//
+			// 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
+			//
+			// 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
+			//		(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;
+
+			// Adjust anchor positioning for the case that a parent node has overflw hidden, therefore cuasing the anchor not to be completely visible
+			if(anchor.parentNode){
+				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 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;
+					}	
+					parent = parent.parentNode;
+				}
+			}			
+
+			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);
+
+			// Convert positions arguments into choices argument for _place()
+			var choices = [];
+			function push(aroundCorner, corner){
+				choices.push({
+					aroundCorner: aroundCorner,
+					corner: corner,
+					pos: {
+						x: {
+							'L': x,
+							'R': x + width,
+							'M': x + (width >> 1)
+						   }[aroundCorner.charAt(1)],
+						y: {
+							'T': y,
+							'B': y + height,
+							'M': y + (height >> 1)
+						   }[aroundCorner.charAt(0)]
+					}
+				})
+			}
+			array.forEach(positions, function(pos){
+				var ltr =  leftToRight;
+				switch(pos){
+					case "above-centered":
+						push("TM", "BM");
+						break;
+					case "below-centered":
+						push("BM", "TM");
+						break;
+					case "after-centered":
+						ltr = !ltr;
+						// fall through
+					case "before-centered":
+						push(ltr ? "ML" : "MR", ltr ? "MR" : "ML");
+						break;
+					case "after":
+						ltr = !ltr;
+						// fall through
+					case "before":
+						push(ltr ? "TL" : "TR", ltr ? "TR" : "TL");
+						push(ltr ? "BL" : "BR", ltr ? "BR" : "BL");
+						break;
+					case "below-alt":
+						ltr = !ltr;
+						// fall through
+					case "below":
+						// first try to align left borders, next try to align right borders (or reverse for RTL mode)
+						push(ltr ? "BL" : "BR", ltr ? "TL" : "TR");
+						push(ltr ? "BR" : "BL", ltr ? "TR" : "TL");
+						break;
+					case "above-alt":
+						ltr = !ltr;
+						// fall through
+					case "above":
+						// first try to align left borders, next try to align right borders (or reverse for RTL mode)
+						push(ltr ? "TL" : "TR", ltr ? "BL" : "BR");
+						push(ltr ? "TR" : "TL", ltr ? "BR" : "BL");
+						break;
+					default:
+						// To assist dijit/_base/place, accept arguments of type {aroundCorner: "BL", corner: "TL"}.
+						// Not meant to be used directly.
+						push(pos.aroundCorner, pos.corner);
+				}
+			});
+
+			var position = _place(node, choices, layoutNode, {w: width, h: height});
+			position.aroundNodePos = aroundNodePos;
+
+			return position;
+		}
+	});
+});
diff --git a/dijit/popup.js b/dijit/popup.js
new file mode 100644
index 0000000..0e4387f
--- /dev/null
+++ b/dijit/popup.js
@@ -0,0 +1,379 @@
+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/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){
+
+	// 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;
+	}
+	=====*/
+
+	/*=====
+	dijit.popup = {
+		// 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 of currently popped up widgets.
+		//		(someone opened _stack[0], and then it opened _stack[1], etc.)
+		_stack: [],
+
+		// _beginZIndex: Number
+		//		Z-index of the first popup.   (If first popup opens other
+		//		popups they get a higher z-index.)
+		_beginZIndex: 1000,
+
+		_idGen: 1,
+
+		_createWrapper: function(/*Widget*/ widget){
+			// summary:
+			//		Initialization for widgets that will be used as popups.
+			//		Puts widget inside a wrapper DIV (if not already in one),
+			//		and returns pointer to that wrapper DIV.
+
+			var wrapper = widget._popupWrapper,
+				node = widget.domNode;
+
+			if(!wrapper){
+				// 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.appendChild(node);
+
+				var s = node.style;
+				s.display = "";
+				s.visibility = "";
+				s.position = "";
+				s.top = "0px";
+
+				widget._popupWrapper = wrapper;
+				aspect.after(widget, "destroy", function(){
+					domConstruct.destroy(wrapper);
+					delete widget._popupWrapper;
+				});
+			}
+
+			return wrapper;
+		},
+
+		moveOffScreen: function(/*Widget*/ 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.
+
+			// 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: ""
+			});
+		},
+
+		hide: function(/*Widget*/ 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.
+
+			// Create wrapper if not already there
+			var wrapper = this._createWrapper(widget);
+
+			domStyle.set(wrapper, "display", "none");
+		},
+
+		getTopPopup: function(){
+			// summary:
+			//		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--){
+				/* do nothing, just trying to get right value for pi */
+			}
+			return stack[pi];
+		},
+
+		open: function(/*dijit.popup.__OpenArgs*/ 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.
+
+			var stack = this._stack,
+				widget = args.popup,
+				orient = args.orient || ["below", "below-alt", "above", "above-alt"],
+				ltr = args.parent ? args.parent.isLeftToRight() : domGeometry.isBodyLtr(),
+				around = args.around,
+				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);
+			}
+
+			// Get pointer to popup wrapper, and create wrapper if it doesn't exist
+			var wrapper = this._createWrapper(widget);
+
+
+			domAttr.set(wrapper, {
+				id: id,
+				style: {
+					zIndex: this._beginZIndex + stack.length
+				},
+				"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);
+				}
+			}
+
+			// 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);
+
+			wrapper.style.display = "";
+			wrapper.style.visibility = "visible";
+			widget.domNode.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);
+					args.onCancel();
+				}else if(evt.charOrCode === keys.TAB){
+					event.stop(evt);
+					var topPopup = this.getTopPopup();
+					if(topPopup && topPopup.onCancel){
+						topPopup.onCancel();
+					}
+				}
+			})));
+
+			// watch for cancel/execute events on the popup and notify the caller
+			// (for a menu, "execute" means clicking an item)
+			if(widget.onCancel && args.onCancel){
+				handlers.push(widget.on("cancel", args.onCancel));
+			}
+
+			handlers.push(widget.on(widget.onExecute ? "execute" : "change", lang.hitch(this, function(){
+				var topPopup = this.getTopPopup();
+				if(topPopup && topPopup.onExecute){
+					topPopup.onExecute();
+				}
+			})));
+
+			stack.push({
+				widget: widget,
+				parent: args.parent,
+				onExecute: args.onExecute,
+				onCancel: args.onCancel,
+				onClose: args.onClose,
+				handlers: handlers
+			});
+
+			if(widget.onOpen){
+				// TODO: in 2.0 standardize onShow() (used by StackContainer) and onOpen() (used here)
+				widget.onOpen(best);
+			}
+
+			return best;
+		},
+
+		close: function(/*Widget?*/ popup){
+			// summary:
+			//		Close specified popup and any popups that it parented.
+			//		If no popup is specified, closes all popups.
+
+			var stack = this._stack;
+
+			// Basically work backwards from the top of the stack closing popups
+			// until we hit the specified popup, but IIRC there was some issue where closing
+			// 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;})) ||
+				(!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)
+					widget.onClose();
+				}
+
+				var h;
+				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){
+					this.hide(widget);
+				}
+
+				if(onClose){
+					onClose();
+				}
+			}
+		}
+	});
+
+	return (dijit.popup = new PopupManager());
+});
diff --git a/dijit/registry.js b/dijit/registry.js
new file mode 100644
index 0000000..cce4ef5
--- /dev/null
+++ b/dijit/registry.js
@@ -0,0 +1,174 @@
+define([
+	"dojo/_base/array", // array.forEach array.map
+	"dojo/_base/sniff", // has("ie")
+	"dojo/_base/unload", // unload.addOnWindowUnload
+	"dojo/_base/window", // win.body
+	"."	// dijit._scopeName
+], function(array, has, unload, 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
+
+		length: 0,
+
+		add: function(/*dijit._Widget*/ 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.
+			if(hash[widget.id]){
+				throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered");
+			}
+			hash[widget.id] = widget;
+			this.length++;
+		},
+
+		remove: function(/*String*/ id){
+			// summary:
+			//		Remove a widget from the registry. Does not destroy the widget; simply
+			//		removes the reference.
+			if(hash[id]){
+				delete hash[id];
+				this.length--;
+			}
+		},
+
+		byId: function(/*String|Widget*/ id){
+			// 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
+		},
+
+		byNode: function(/*DOMNode*/ node){
+			// summary:
+			//		Returns the widget corresponding to the given DOMNode
+			return hash[node.getAttribute("widgetId")]; // dijit._Widget
+		},
+
+		toArray: function(){
+			// summary:
+			//		Convert registry into a true Array
+			//
+			// example:
+			//		Work with the widget .domNodes in a real Array
+			//		|	array.map(dijit.registry.toArray(), function(w){ return w.domNode; });
+
+			var ar = [];
+			for(var id in hash){
+				ar.push(hash[id]);
+			}
+			return ar;	// dijit._Widget[]
+		},
+
+		getUniqueId: function(/*String*/widgetType){
+			// summary:
+			//		Generates a unique id for a given widgetType
+
+			var id;
+			do{
+				id = widgetType + "_" +
+					(widgetType in _widgetTypeCtr ?
+						++_widgetTypeCtr[widgetType] : _widgetTypeCtr[widgetType] = 0);
+			}while(hash[id]);
+			return dijit._scopeName == "dijit" ? id : dijit._scopeName + "_" + id; // String
+		},
+
+		findWidgets: function(/*DomNode*/ root){
+			// summary:
+			//		Search subtree under root returning widgets found.
+			//		Doesn't search for nested widgets (ie, widgets inside other widgets).
+
+			var outAry = [];
+
+			function getChildrenHelper(root){
+				for(var node = root.firstChild; node; node = node.nextSibling){
+					if(node.nodeType == 1){
+						var widgetId = node.getAttribute("widgetId");
+						if(widgetId){
+							var widget = hash[widgetId];
+							if(widget){	// may be null on page w/multiple dojo's loaded
+								outAry.push(widget);
+							}
+						}else{
+							getChildrenHelper(node);
+						}
+					}
+				}
+			}
+
+			getChildrenHelper(root);
+			return outAry;
+		},
+
+		_destroyAll: function(){
+			// summary:
+			//		Code to destroy all widgets and do other cleanup on page unload
+
+			// Clean up focus manager lingering references to widgets and nodes
+			dijit._curFocus = null;
+			dijit._prevFocus = null;
+			dijit._activeStack = [];
+
+			// Destroy all the widgets, top down
+			array.forEach(registry.findWidgets(win.body()), function(widget){
+				// Avoid double destroy of widgets like Menu that are attached to <body>
+				// even though they are logically children of other widgets.
+				if(!widget._destroyed){
+					if(widget.destroyRecursive){
+						widget.destroyRecursive();
+					}else if(widget.destroy){
+						widget.destroy();
+					}
+				}
+			});
+		},
+
+		getEnclosingWidget: function(/*DOMNode*/ 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
+			while(node){
+				var id = node.getAttribute && node.getAttribute("widgetId");
+				if(id){
+					return hash[id];
+				}
+				node = node.parentNode;
+			}
+			return null;
+		},
+
+		// In case someone needs to access hash.
+		// Actually, this is accessed from WidgetSet back-compatibility code
+		_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/robot.js b/dijit/robot.js
index 56b8b9e..a1d43b5 100644
--- a/dijit/robot.js
+++ b/dijit/robot.js
@@ -1,6 +1,11 @@
-define("dijit/robot", ["dojo", "dijit", "dojo/robot"], function(dojo, dijit) {
+define([
+	".",
+	"dojo/robot"
+], function(dijit){
+	// module:
+	//		dijit/robot
+	// summary:
+	//		Used to have code needed by robot test harness, but no longer
 
-
-
-return dijit;
+	return dijit;
 });
diff --git a/dijit/robotx.js b/dijit/robotx.js
index e25ed95..d42fff7 100644
--- a/dijit/robotx.js
+++ b/dijit/robotx.js
@@ -1,24 +1,34 @@
-define("dijit/robotx", ["dojo", "dijit", "dijit/robot", "dojo/robotx"], function(dojo, dijit_) {
+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){
 
-//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_"
+	// module:
+	//		dijit/robotx
+	// summary:
+	//		Code needed by robot test harness
 
-dojo.experimental("dijit.robotx");
-(function(){
-var __updateDocument = doh.robot._updateDocument;
 
-dojo.mixin(doh.robot,{
-	_updateDocument: function(){
-		__updateDocument();
-		var win = dojo.global;
-		if(win["dijit"]){
-			window.dijit = win.dijit; // window reference needed for IE
-		}
-	}
-});
+	//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_"
 
-})();
+	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
+			}
+		}
+	});
 
-return dijit_;
+	return dijit_;
 });
diff --git a/dijit/templates/Calendar.html b/dijit/templates/Calendar.html
index 15294bd..a3428f5 100644
--- a/dijit/templates/Calendar.html
+++ b/dijit/templates/Calendar.html
@@ -1,38 +1,35 @@
-<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" aria-labelledby="${id}_mddb ${id}_year">
 	<thead>
 		<tr class="dijitReset dijitCalendarMonthContainer" valign="top">
-			<th class='dijitReset dijitCalendarArrow' dojoAttachPoint="decrementMonth">
+			<th class='dijitReset dijitCalendarArrow' data-dojo-attach-point="decrementMonth">
 				<img src="${_blankGif}" alt="" class="dijitCalendarIncrementControl dijitCalendarDecrease" role="presentation"/>
-				<span dojoAttachPoint="decreaseArrowNode" class="dijitA11ySideArrow">-</span>
+				<span data-dojo-attach-point="decreaseArrowNode" class="dijitA11ySideArrow">-</span>
 			</th>
 			<th class='dijitReset' colspan="5">
-				<div dojoType="dijit.form.DropDownButton" dojoAttachPoint="monthDropDownButton"
-					id="${id}_mddb" tabIndex="-1">
+				<div data-dojo-attach-point="monthNode">
 				</div>
 			</th>
-			<th class='dijitReset dijitCalendarArrow' dojoAttachPoint="incrementMonth">
+			<th class='dijitReset dijitCalendarArrow' data-dojo-attach-point="incrementMonth">
 				<img src="${_blankGif}" alt="" class="dijitCalendarIncrementControl dijitCalendarIncrease" role="presentation"/>
-				<span dojoAttachPoint="increaseArrowNode" class="dijitA11ySideArrow">+</span>
+				<span data-dojo-attach-point="increaseArrowNode" class="dijitA11ySideArrow">+</span>
 			</th>
 		</tr>
 		<tr>
-			<th class="dijitReset dijitCalendarDayLabelTemplate" role="columnheader"><span class="dijitCalendarDayLabel"></span></th>
+			${!dayCellsHtml}
 		</tr>
 	</thead>
-	<tbody dojoAttachEvent="onclick: _onDayClick, onmouseover: _onDayMouseOver, onmouseout: _onDayMouseOut, onmousedown: _onDayMouseDown, onmouseup: _onDayMouseUp" class="dijitReset dijitCalendarBodyContainer">
-		<tr class="dijitReset dijitCalendarWeekTemplate" role="row">
-			<td class="dijitReset dijitCalendarDateTemplate" role="gridcell"><span class="dijitCalendarDateLabel"></span></td>
-		</tr>
+	<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">
-				<h3 class="dijitCalendarYearLabel">
-					<span dojoAttachPoint="previousYearLabelNode" class="dijitInline dijitCalendarPreviousYear"></span>
-					<span dojoAttachPoint="currentYearLabelNode" class="dijitInline dijitCalendarSelectedYear" id="${id}_year"></span>
-					<span dojoAttachPoint="nextYearLabelNode" class="dijitInline dijitCalendarNextYear"></span>
-				</h3>
+			<td class='dijitReset' valign="top" colspan="7" role="presentation">
+				<div 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" id="${id}_year"></span>
+					<span data-dojo-attach-point="nextYearLabelNode" class="dijitInline dijitCalendarNextYear" role="button"></span>
+				</div>
 			</td>
 		</tr>
 	</tfoot>
-</table>
\ No newline at end of file
+</table>
diff --git a/dijit/templates/CheckedMenuItem.html b/dijit/templates/CheckedMenuItem.html
index 1edfebf..8e1bf57 100644
--- a/dijit/templates/CheckedMenuItem.html
+++ b/dijit/templates/CheckedMenuItem.html
@@ -1,10 +1,10 @@
-<tr class="dijitReset dijitMenuItem" dojoAttachPoint="focusNode" role="menuitemcheckbox" tabIndex="-1"
-		dojoAttachEvent="onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick">
+<tr class="dijitReset dijitMenuItem" data-dojo-attach-point="focusNode" role="menuitemcheckbox" tabIndex="-1"
+		data-dojo-attach-event="onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick">
 	<td class="dijitReset dijitMenuItemIconCell" role="presentation">
-		<img src="${_blankGif}" alt="" class="dijitMenuItemIcon dijitCheckedMenuItemIcon" dojoAttachPoint="iconNode"/>
+		<img src="${_blankGif}" alt="" class="dijitMenuItemIcon dijitCheckedMenuItemIcon" data-dojo-attach-point="iconNode"/>
 		<span class="dijitCheckedMenuItemIconChar">✓</span>
 	</td>
-	<td class="dijitReset dijitMenuItemLabel" colspan="2" dojoAttachPoint="containerNode,labelNode"></td>
-	<td class="dijitReset dijitMenuItemAccelKey" style="display: none" dojoAttachPoint="accelKeyNode"></td>
-	<td class="dijitReset dijitMenuArrowCell" role="presentation"> </td>
+	<td class="dijitReset dijitMenuItemLabel" colspan="2" data-dojo-attach-point="containerNode,labelNode"></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 125bd88..3f7f960 100644
--- a/dijit/templates/ColorPalette.html
+++ b/dijit/templates/ColorPalette.html
@@ -1,5 +1,5 @@
 <div class="dijitInline dijitColorPalette">
-	<table class="dijitPaletteTable" cellSpacing="0" cellPadding="0">
-		<tbody dojoAttachPoint="gridNode"></tbody>
+	<table dojoAttachPoint="paletteTableNode" class="dijitPaletteTable" cellSpacing="0" cellPadding="0" role="grid">
+		<tbody data-dojo-attach-point="gridNode"></tbody>
 	</table>
 </div>
diff --git a/dijit/templates/Dialog.html b/dijit/templates/Dialog.html
index 2c263a8..1e4a223 100644
--- a/dijit/templates/Dialog.html
+++ b/dijit/templates/Dialog.html
@@ -1,9 +1,9 @@
 <div class="dijitDialog" role="dialog" aria-labelledby="${id}_title">
-	<div dojoAttachPoint="titleBar" class="dijitDialogTitleBar">
-	<span dojoAttachPoint="titleNode" class="dijitDialogTitle" id="${id}_title"></span>
-	<span dojoAttachPoint="closeButtonNode" class="dijitDialogCloseIcon" dojoAttachEvent="ondijitclick: onCancel" title="${buttonCancel}" role="button" tabIndex="-1">
-		<span dojoAttachPoint="closeText" class="closeText" title="${buttonCancel}">x</span>
+	<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>
 	</div>
-		<div dojoAttachPoint="containerNode" class="dijitDialogPaneContent"></div>
+		<div data-dojo-attach-point="containerNode" class="dijitDialogPaneContent"></div>
 </div>
diff --git a/dijit/templates/Menu.html b/dijit/templates/Menu.html
index b0a7cab..45e12a0 100644
--- a/dijit/templates/Menu.html
+++ b/dijit/templates/Menu.html
@@ -1,3 +1,3 @@
-<table class="dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable" role="menu" tabIndex="${tabIndex}" dojoAttachEvent="onkeypress:_onKeyPress" cellspacing="0">
-	<tbody class="dijitReset" dojoAttachPoint="containerNode"></tbody>
+<table class="dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable" role="menu" tabIndex="${tabIndex}" data-dojo-attach-event="onkeypress:_onKeyPress" 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 f94db38..3ba1ea2 100644
--- a/dijit/templates/MenuBar.html
+++ b/dijit/templates/MenuBar.html
@@ -1 +1 @@
-<div class="dijitMenuBar dijitMenuPassive" dojoAttachPoint="containerNode"  role="menubar" tabIndex="${tabIndex}" dojoAttachEvent="onkeypress: _onKeyPress"></div>
+<div class="dijitMenuBar dijitMenuPassive" data-dojo-attach-point="containerNode"  role="menubar" tabIndex="${tabIndex}" data-dojo-attach-event="onkeypress: _onKeyPress"></div>
diff --git a/dijit/templates/MenuBarItem.html b/dijit/templates/MenuBarItem.html
index 4705ad2..f5e2629 100644
--- a/dijit/templates/MenuBarItem.html
+++ b/dijit/templates/MenuBarItem.html
@@ -1,4 +1,4 @@
-<div class="dijitReset dijitInline dijitMenuItem dijitMenuItemLabel" dojoAttachPoint="focusNode" role="menuitem" tabIndex="-1"
-		dojoAttachEvent="onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick">
-	<span dojoAttachPoint="containerNode"></span>
+<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>
diff --git a/dijit/templates/MenuItem.html b/dijit/templates/MenuItem.html
index abde6bc..b4fe7d6 100644
--- a/dijit/templates/MenuItem.html
+++ b/dijit/templates/MenuItem.html
@@ -1,12 +1,12 @@
-<tr class="dijitReset dijitMenuItem" dojoAttachPoint="focusNode" role="menuitem" tabIndex="-1"
-		dojoAttachEvent="onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick">
+<tr class="dijitReset dijitMenuItem" data-dojo-attach-point="focusNode" role="menuitem" tabIndex="-1"
+		data-dojo-attach-event="onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick">
 	<td class="dijitReset dijitMenuItemIconCell" role="presentation">
-		<img src="${_blankGif}" alt="" class="dijitIcon dijitMenuItemIcon" dojoAttachPoint="iconNode"/>
+		<img src="${_blankGif}" alt="" class="dijitIcon dijitMenuItemIcon" data-dojo-attach-point="iconNode"/>
 	</td>
-	<td class="dijitReset dijitMenuItemLabel" colspan="2" dojoAttachPoint="containerNode"></td>
-	<td class="dijitReset dijitMenuItemAccelKey" style="display: none" dojoAttachPoint="accelKeyNode"></td>
+	<td class="dijitReset dijitMenuItemLabel" colspan="2" data-dojo-attach-point="containerNode"></td>
+	<td class="dijitReset dijitMenuItemAccelKey" style="display: none" data-dojo-attach-point="accelKeyNode"></td>
 	<td class="dijitReset dijitMenuArrowCell" role="presentation">
-		<div dojoAttachPoint="arrowWrapper" style="visibility: hidden">
+		<div data-dojo-attach-point="arrowWrapper" style="visibility: hidden">
 			<img src="${_blankGif}" alt="" class="dijitMenuExpand"/>
 			<span class="dijitMenuExpandA11y">+</span>
 		</div>
diff --git a/dijit/templates/ProgressBar.html b/dijit/templates/ProgressBar.html
index 33c7ee7..9ed12af 100644
--- a/dijit/templates/ProgressBar.html
+++ b/dijit/templates/ProgressBar.html
@@ -1,8 +1,8 @@
 <div class="dijitProgressBar dijitProgressBarEmpty" role="progressbar"
-	><div  dojoAttachPoint="internalProgress" class="dijitProgressBarFull"
+	><div  data-dojo-attach-point="internalProgress" class="dijitProgressBarFull"
 		><div class="dijitProgressBarTile" role="presentation"></div
-		><span style="visibility:hidden"> </span
+		><span style="visibility:hidden"> </span
 	></div
-	><div dojoAttachPoint="labelNode" class="dijitProgressBarLabel" id="${id}_label"></div
-	><img dojoAttachPoint="indeterminateHighContrastImage" class="dijitProgressBarIndeterminateHighContrastImage" alt=""
+	><div data-dojo-attach-point="labelNode" class="dijitProgressBarLabel" id="${id}_label"></div
+	><img data-dojo-attach-point="indeterminateHighContrastImage" class="dijitProgressBarIndeterminateHighContrastImage" alt=""
 /></div>
diff --git a/dijit/templates/TimePicker.html b/dijit/templates/TimePicker.html
index 66d5491..919fbb0 100644
--- a/dijit/templates/TimePicker.html
+++ b/dijit/templates/TimePicker.html
@@ -1,9 +1,9 @@
 <div id="widget_${id}" class="dijitMenu"
-    ><div dojoAttachPoint="upArrow" class="dijitButtonNode dijitUpArrowButton" dojoAttachEvent="onmouseenter:_buttonMouse,onmouseleave:_buttonMouse"
-		><div class="dijitReset dijitInline dijitArrowButtonInner" role="presentation"> </div
+    ><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 dojoAttachPoint="timeMenu,focusNode" dojoAttachEvent="onclick:_onOptionSelected,onmouseover,onmouseout"></div
-    ><div dojoAttachPoint="downArrow" class="dijitButtonNode dijitDownArrowButton" dojoAttachEvent="onmouseenter:_buttonMouse,onmouseleave:_buttonMouse"
-		><div class="dijitReset dijitInline dijitArrowButtonInner" role="presentation"> </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 82823d7..4e7aece 100644
--- a/dijit/templates/TitlePane.html
+++ b/dijit/templates/TitlePane.html
@@ -1,15 +1,15 @@
 <div>
-	<div dojoAttachEvent="onclick:_onTitleClick, onkeypress:_onTitleKey"
-			class="dijitTitlePaneTitle" dojoAttachPoint="titleBarNode">
-		<div class="dijitTitlePaneTitleFocus" dojoAttachPoint="focusNode">
-			<img src="${_blankGif}" alt="" dojoAttachPoint="arrowNode" class="dijitArrowNode" role="presentation"
-			/><span dojoAttachPoint="arrowNodeInner" class="dijitArrowNodeInner"></span
-			><span dojoAttachPoint="titleNode" class="dijitTitlePaneTextNode"></span>
+	<div data-dojo-attach-event="onclick:_onTitleClick, onkeypress:_onTitleKey"
+			class="dijitTitlePaneTitle" data-dojo-attach-point="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="titleNode" class="dijitTitlePaneTextNode"></span>
 		</div>
 	</div>
-	<div class="dijitTitlePaneContentOuter" dojoAttachPoint="hideNode" role="presentation">
-		<div class="dijitReset" dojoAttachPoint="wipeNode" role="presentation">
-			<div class="dijitTitlePaneContentInner" dojoAttachPoint="containerNode" role="region" id="${id}_pane">
+	<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">
 				<!-- 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 506ec74..fdb1a82 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" dojoAttachPoint="containerNode" role='alert'></div
-	><div class="dijitTooltipConnector" dojoAttachPoint="connectorNode"></div
+	><div class="dijitTooltipContainer dijitTooltipContents" data-dojo-attach-point="containerNode" role='alert'></div
+	><div class="dijitTooltipConnector" data-dojo-attach-point="connectorNode"></div
 ></div>
diff --git a/dijit/templates/TooltipDialog.html b/dijit/templates/TooltipDialog.html
index 2f1bba2..00a6022 100644
--- a/dijit/templates/TooltipDialog.html
+++ b/dijit/templates/TooltipDialog.html
@@ -1,6 +1,6 @@
 <div role="presentation" tabIndex="-1">
 	<div class="dijitTooltipContainer" role="presentation">
-		<div class ="dijitTooltipContents dijitTooltipFocusNode" dojoAttachPoint="containerNode" role="dialog"></div>
+		<div class ="dijitTooltipContents dijitTooltipFocusNode" data-dojo-attach-point="containerNode" role="dialog"></div>
 	</div>
 	<div class="dijitTooltipConnector" role="presentation"></div>
 </div>
diff --git a/dijit/templates/Tree.html b/dijit/templates/Tree.html
index e5112b0..4e1b943 100644
--- a/dijit/templates/Tree.html
+++ b/dijit/templates/Tree.html
@@ -1,4 +1,4 @@
 <div class="dijitTree dijitTreeContainer" role="tree"
-	dojoAttachEvent="onkeypress:_onKeyPress">
-	<div class="dijitInline dijitTreeIndent" style="position: absolute; top: -9999px" dojoAttachPoint="indentDetector"></div>
+	data-dojo-attach-event="onkeypress:_onKeyPress">
+	<div class="dijitInline dijitTreeIndent" style="position: absolute; top: -9999px" data-dojo-attach-point="indentDetector"></div>
 </div>
diff --git a/dijit/templates/TreeNode.html b/dijit/templates/TreeNode.html
index a9ac539..f55450c 100644
--- a/dijit/templates/TreeNode.html
+++ b/dijit/templates/TreeNode.html
@@ -1,13 +1,13 @@
 <div class="dijitTreeNode" role="presentation"
-	><div dojoAttachPoint="rowNode" class="dijitTreeRow" role="presentation" dojoAttachEvent="onmouseenter:_onMouseEnter, onmouseleave:_onMouseLeave, onclick:_onClick, ondblclick:_onDblClick"
-		><img src="${_blankGif}" alt="" dojoAttachPoint="expandoNode" class="dijitTreeExpando" role="presentation"
-		/><span dojoAttachPoint="expandoNodeText" class="dijitExpandoText" 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
-		><span dojoAttachPoint="contentNode"
+		><span data-dojo-attach-point="contentNode"
 			class="dijitTreeContent" role="presentation">
-			<img src="${_blankGif}" alt="" dojoAttachPoint="iconNode" class="dijitIcon dijitTreeIcon" role="presentation"
-			/><span dojoAttachPoint="labelNode" class="dijitTreeLabel" role="treeitem" tabindex="-1" aria-selected="false" dojoAttachEvent="onfocus:_onLabelFocus"></span>
+			<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
 	></div>
-	<div dojoAttachPoint="containerNode" class="dijitTreeContainer" role="presentation" style="display: none;"></div>
+	<div data-dojo-attach-point="containerNode" class="dijitTreeContainer" role="presentation" style="display: none;"></div>
 </div>
diff --git a/dijit/tests/Bidi.html b/dijit/tests/Bidi.html
index 06cdfee..b5843cc 100755
--- a/dijit/tests/Bidi.html
+++ b/dijit/tests/Bidi.html
@@ -63,7 +63,7 @@
 			);
 		}
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			doh.register("parse", function(){
 				dojo.parser.parse();
 			});
@@ -283,9 +283,9 @@
 				><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 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">
+						<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>
diff --git a/dijit/tests/Dialog.html b/dijit/tests/Dialog.html
index 09be048..a8fa1ea 100644
--- a/dijit/tests/Dialog.html
+++ b/dijit/tests/Dialog.html
@@ -25,8 +25,9 @@
 		dojo.require("doh.runner");
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dijit.Dialog");
+		dojo.require("dijit.focus");
 
-		dojo.addOnLoad(function(){
+		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.
@@ -65,7 +66,7 @@
 							doh.t(dialog1Z > underlayZ, "dialog1 (zIndex=" + dialog1Z +
 								") above underlay (zIndex=" + underlayZ + ")");
 
-							doh.is("dlg1_inputA", dojo.global.dijit._curFocus.id, "focus is on the first field");
+							doh.is("dlg1_inputA", dojo.global.dijit.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.							
@@ -107,7 +108,7 @@
 							doh.t(dialog2Z > underlayZ, "dialog2 (zIndex=" + dialog2Z +
 								") above underlay (zIndex=" + underlayZ + ")");
 
-							doh.is("dlg2_inputA", dojo.global.dijit._curFocus.id, "focus is on the first field");
+							doh.is("dlg2_inputA", dojo.global.dijit.focus.curNode.id, "focus is on the first field");
 						}));
 
 						return d;
@@ -127,7 +128,7 @@
 							doh.t(isVisible(dlg2), "dialog 2 is still visible");
 							doh.t(isVisible(dojo.global.dijit._underlay), "underlay is still visible");
 
-							doh.is("dlg2_inputA", dojo.global.dijit._curFocus.id, "dialog 2 still has focus");
+							doh.is("dlg2_inputA", dojo.global.dijit.focus.curNode.id, "dialog 2 still has focus");
 
 							var dialog2Z = dojo.style(dlg2.domNode, "zIndex"),
 								underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
@@ -173,7 +174,7 @@
 							doh.t(dialog3Z > underlayZ, "dialog3 (zIndex=" + dialog3Z +
 								") above underlay (zIndex=" + underlayZ + ")");
 
-							doh.is("dlg3_inputA", dojo.global.dijit._curFocus.id, "focus is on the first field");
+							doh.is("dlg3_inputA", dojo.global.dijit.focus.curNode.id, "focus is on the first field");
 						}));
 
 						return d;
@@ -206,7 +207,7 @@
 							doh.t(dialog4Z > underlayZ, "dialog4 (zIndex=" + dialog4Z +
 								") above underlay (zIndex=" + underlayZ + ")");
 
-							doh.is("dlg4_inputA", dojo.global.dijit._curFocus.id, "focus is on the first field");
+							doh.is("dlg4_inputA", dojo.global.dijit.focus.curNode.id, "focus is on the first field");
 						}));
 
 						return d;
@@ -224,7 +225,7 @@
 							doh.t(isVisible(dlg4), "dialog 4 is still visible");
 							doh.t(isVisible(dojo.global.dijit._underlay), "underlay is still visible");
 
-							doh.is("dlg4_inputA", dojo.global.dijit._curFocus.id, "dialog 4 still has focus");
+							doh.is("dlg4_inputA", dojo.global.dijit.focus.curNode.id, "dialog 4 still has focus");
 
 							var dialog4Z = dojo.style(dlg4.domNode, "zIndex"),
 								underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
@@ -258,7 +259,7 @@
 							doh.t(dialog2Z > underlayZ, "dialog2 (zIndex=" + dialog2Z +
 								") above underlay (zIndex=" + underlayZ + ")");
 
-							doh.is("dlg2_inputA", dojo.global.dijit._curFocus.id, "focus is on the first field");
+							doh.is("dlg2_inputA", dojo.global.dijit.focus.curNode.id, "focus is on the first field");
 						}));
 
 						return d;
@@ -277,7 +278,7 @@
 							doh.t(isHidden(dlg2), "dialog 4 is hidden");
 							doh.t(isHidden(dojo.global.dijit._underlay), "underlay hidden");
 
-							doh.is("button", dojo.global.dijit._curFocus.id, "focus is on the main page");
+							doh.is("button", dojo.global.dijit.focus.curNode.id, "focus is on the main page");
 						}));
 
 						return d;
@@ -380,13 +381,13 @@
 						
 						setTimeout(d.getTestErrback(function(){
 							fast.show();
-						}), slow.duration / 2)
+						}), 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")
-						}), slow.duration * 2)
+						}), slow.duration * 2);
 						return d;
 					}
 				},
@@ -400,9 +401,9 @@
 						fast.hide();
 						
 						setTimeout(d.getTestCallback(function(){
-							doh.is("slowOK", dojo.global.dijit._curFocus.id, "focused to dialog C");
+							doh.is("slowOK", dojo.global.dijit.focus.curNode.id, "focused to dialog C");
 							doh.t(dojo.global.slowFocused, "onfocus handler working");
-						}), fast.duration * 2)
+						}), fast.duration * 2);
 
 						return d;
 					}
diff --git a/dijit/tests/NodeList-instantiate.html b/dijit/tests/NodeList-instantiate.html
index ae72995..868288c 100644
--- a/dijit/tests/NodeList-instantiate.html
+++ b/dijit/tests/NodeList-instantiate.html
@@ -26,7 +26,7 @@
 			dojo.require("dijit.layout.TabContainer");
 			dojo.require("dijit.layout.ContentPane");
 
-	    	dojo.addOnLoad(function() {	
+	    	dojo.ready(function(){
 
 				// declare a simple widget to use as a base test:
 				dojo.declare("test._Widget",dijit._Widget,{
@@ -87,11 +87,13 @@
 						
 						var tabs = tc.tablist.getChildren();
 						doh.is(3, tabs.length);
-						dojo.forEach(tabs, function(tab, i) { doh.is("tab"+(i+1), tab.label); })
+						dojo.forEach(tabs, function(tab, i){
+							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); })
+						dojo.forEach(childrenContent, function(childrenContent, i){ doh.is("pane"+(i+1), childrenContent.innerHTML); })
 					},
 	
 					function Buttons(){
diff --git a/dijit/tests/ProgressBar.html b/dijit/tests/ProgressBar.html
index aa10a5b..e99bf48 100644
--- a/dijit/tests/ProgressBar.html
+++ b/dijit/tests/ProgressBar.html
@@ -37,7 +37,7 @@
 		dojo.require("dojo.string");
 		dojo.require("doh.runner");
 
-		dojo.addOnLoad(function go(){
+		dojo.ready(function go(){
 			doh.register("parse", function(){
 				dojo.parser.parse();
 			});
@@ -150,7 +150,7 @@
 						progressBar = dijit.byId("implied2");
 						doh.is("50", progressBar.progress);
 						doh.is("50%", dojo.byId("implied2_label").innerHTML);
-						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
 						doh.is("50%", visualProgress.style.width);
 					}
 				},
@@ -212,9 +212,23 @@
 							
 						doh.t(dojo.hasClass(progressBar.domNode, "dijitProgressBarIndeterminate"), "has class dijitProgressBarIndeterminate");
 						
-						var progressBar = dijit.byId("timerBar");
+						progressBar = dijit.byId("timerBar");
 						doh.t(80 < progressBar.progress <= 100, "Timer progress was " + progressBar.progress);
 					}
+				},
+				{
+					name: "set zero maximum",
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						var progressBar = dijit.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%", visualProgress.style.width);
+					}
 				}
 			]);
 			
@@ -250,7 +264,6 @@
 					if(response == "100%"){
 						clearInterval(_timer);
 						_timer = null;
-						return;
 					}
 				});
 			}, 3000); // on 3 second intervals
@@ -282,7 +295,7 @@
 		maximum:200, value:"20" '></div>
 
 	<h3>Test 2</h3>
-	Write here: <input type="text" value="" name="test" maxLength="256" id="test" style="width:300"/>
+	Write here: <input type="text" value="" name="test" maxLength="256" id="test" style="width:300px"/>
 	<br />
 	<br />
 	<div id="testBar" style='width:300px'></div>
diff --git a/dijit/tests/Tooltip-placement.html b/dijit/tests/Tooltip-placement.html
index d49e872..34d6cfd 100644
--- a/dijit/tests/Tooltip-placement.html
+++ b/dijit/tests/Tooltip-placement.html
@@ -25,8 +25,9 @@
 		dojo.require("dojo.parser");
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dijit.form.ValidationTextBox");
+		dojo.require("dijit.layout.ContentPane");
 		
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			doh.register("parse", function(){
 				dojo.parser.parse();
 			});
@@ -46,15 +47,15 @@
 					dijit.byId("test19").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("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"
 				}
 				
 				if(height < 600){
 					//Make the taller tooltips shorter
-					for(var i=1;i<22;i++) {
+					for(var i=1;i<22;i++){
 						if(i==7){
 							//skip
 						}else{
@@ -113,7 +114,7 @@
 			//	4. If the tooltip is not completely visible, verify that it uses all available height
 			function testRightOrLeft(textbox, verifyFullWidthIsUtilized){
 				verifyTooltipArrowPosition(textbox);
-			
+
 				var textboxPos = dojo.position(textbox.domNode);
 				var tooltipContainerPos = dojo.position(dojo.query(".dijitTooltip")[0]);
 				
@@ -125,13 +126,13 @@
 
 				doh.t(toTheLeft || toTheRight, "The tooltip was not to the left or right");
 
-				var tooltip = dojo.query("div[dojoattachpoint='containerNode']");
-				var tooltipPos = dojo.position(tooltip[0]);
+				var tooltip = dijit.Tooltip._masterTT.containerNode;
+				var tooltipPos = dojo.position(tooltip);
 
 				var view = dojo.window.getBox();
 				var isIE6 = dojo.isIE < 7;
 				//verify the entire width is utilized.  Small tooltips will not utilize the entire width.
-				if(verifyFullWidthIsUtilized && !isIE6 && !dojo.isOpera) {
+				if(verifyFullWidthIsUtilized && !isIE6 && !dojo.isOpera){
 					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{
@@ -140,8 +141,8 @@
 				}
 			
 				//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) && 
-										   (tooltipPos.y + tooltipPos.h <= view.h);
+				var canViewEntireTooltip = (tooltipContainerPos.x + tooltipContainerPos.w <= view.w+1) && 
+										   (tooltipPos.y + tooltipPos.h <= view.h+1);			
 				if(!canViewEntireTooltip && !isIE6 && !dojo.isOpera){
 					if(toTheLeft){
 						//verify there is more space on the left than the right
@@ -150,10 +151,23 @@
 						doh.t(textboxPos.x <= (view.w - textboxPos.x - textboxPos.w), "There is not more space on the right than the left");
 					}
 					//verify the entire height is utilized
-					doh.t(tooltipPos.h >= view.h, "The entire height was not utilized");
+					doh.t(tooltipPos.h >= view.h, "The entire height was not utilized. Tooltip height="+tooltipPos.h+". View height="+view.h);
 				}
 			}
 			
+			function toTheLeftOrRight(textbox){
+				var textboxPos = dojo.position(textbox.domNode);
+				var tooltipContainerPos = dojo.position(dojo.query(".dijitTooltip")[0]);
+				
+				var xDiff = textboxPos.x - tooltipContainerPos.x - tooltipContainerPos.w;
+				var toTheLeft = xDiff >= -1 && xDiff < 2;
+
+				xDiff = tooltipContainerPos.x - textboxPos.x - textboxPos.w;
+				var toTheRight = xDiff >= -1 && xDiff < 2;
+
+				doh.t(toTheLeft || toTheRight, "The tooltip was not to the left or right");
+			}
+			
 			//Verify the tooltip arrow is next to the textbox
 			function verifyTooltipArrowPosition(textbox){
 				var textboxPos = dojo.position(textbox.domNode);
@@ -162,9 +176,8 @@
 				var middleOfTextbox = textboxPos.y + (textboxPos.h / 2);
 				var middleOfTooltipConnector = tooltipConnectorPos.y + (tooltipConnectorPos.h /2);
 
-				var yDiff = 0;
 				var yDiff = middleOfTextbox - middleOfTooltipConnector;
-				var yAxisValid = yDiff <= 1.5 && yDiff >= -1.5; //tooltip arrow is at a similar y coord as the box
+				var yAxisValid = yDiff <= 2 && yDiff >= -1.5; //tooltip arrow is at a similar y coord as the box
 				doh.t(yAxisValid, "Y axis is invalid. yDiff was: "+yDiff);
 			}
 			
@@ -329,6 +342,50 @@
 					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);
+				}
+			}];
 
 			// rest of tests
 			for(var i=2; i<=21; i++){
@@ -479,6 +536,8 @@
 			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>
@@ -564,7 +623,7 @@
 	<tr>
 	<td>
 		<button id="aboveBelowButton" onclick="dijit.Tooltip.defaultPosition=['above', 'below']; 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 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>
@@ -711,5 +770,17 @@
 	</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"/>
+<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"/>
+</div>
+</td></tr></table>
+
 </body>
 </html>
diff --git a/dijit/tests/_BidiSupport/BidiSupportModule/BidiSupportTest.js b/dijit/tests/_BidiSupport/BidiSupportModule/BidiSupportTest.js
new file mode 100644
index 0000000..28f164d
--- /dev/null
+++ b/dijit/tests/_BidiSupport/BidiSupportModule/BidiSupportTest.js
@@ -0,0 +1,181 @@
+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("%^$^&)( )_($!"),"%^$^&)( )_($!");
+				
+			}
+		}
+	]);
+	
+});
diff --git a/dijit/tests/_BidiSupport/BidiSupportModule/module.js b/dijit/tests/_BidiSupport/BidiSupportModule/module.js
new file mode 100644
index 0000000..c45a5aa
--- /dev/null
+++ b/dijit/tests/_BidiSupport/BidiSupportModule/module.js
@@ -0,0 +1,11 @@
+dojo.provide("dijit.tests._BidiSupport.BidiSupportModule.module");
+
+try{
+
+	dojo.require("dijit.tests._BidiSupport.BidiSupportModule.BidiSupportTest");
+
+}catch(e){
+
+	doh.debug(e);
+
+}
diff --git a/dijit/tests/_BidiSupport/BidiSupportModule/runTests.html b/dijit/tests/_BidiSupport/BidiSupportModule/runTests.html
new file mode 100644
index 0000000..030cf83
--- /dev/null
+++ b/dijit/tests/_BidiSupport/BidiSupportModule/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.BidiSupportModule.module">
+	</head>
+	<body>
+		Redirecting to D.O.H runner.
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/_data/categoriesHeb.json b/dijit/tests/_BidiSupport/_data/categoriesHeb.json
new file mode 100644
index 0000000..8acefb4
--- /dev/null
+++ b/dijit/tests/_BidiSupport/_data/categoriesHeb.json
@@ -0,0 +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}
+	]
+}
diff --git a/dijit/tests/_BidiSupport/_data/countriesHeb.json b/dijit/tests/_BidiSupport/_data/countriesHeb.json
new file mode 100644
index 0000000..3df7477
--- /dev/null
+++ b/dijit/tests/_BidiSupport/_data/countriesHeb.json
@@ -0,0 +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' }
+]}
diff --git a/dijit/tests/_BidiSupport/dynamicallyChangeTextDir/DynamicChangeTextDir.html b/dijit/tests/_BidiSupport/dynamicallyChangeTextDir/DynamicChangeTextDir.html
new file mode 100644
index 0000000..508282f
--- /dev/null
+++ b/dijit/tests/_BidiSupport/dynamicallyChangeTextDir/DynamicChangeTextDir.html
@@ -0,0 +1,548 @@
+<!DOCTYPE html>
+
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">	
+		<title>Textarea with _BidiSupport</title>
+
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/themes/tundra/tundra.css";
+		</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("dijit.dijit"); // optimize: load dijit layer
+			dojo.require("dijit.form.Textarea");
+			dojo.require("dijit.form.TextBox");
+			dojo.require("dijit.form.SimpleTextarea");
+			dojo.require("dijit.layout.ContentPane");
+			dojo.require("dijit.layout.TabContainer");
+			dojo.require("dojo.parser");
+			dojo.require("doh.runner");
+			dojo.require("dijit.form.ComboBox");
+			dojo.require("dijit._BidiSupport");
+
+			dojo.ready(function(){
+				doh.register("parse", function(){
+					dojo.parser.parse();
+
+					programmaticTextareaLTR = new dijit.form.Textarea({
+						id: "blankTaP",
+						name: "blankTaP",
+						style:{width:"30em"},
+						textDir:"ltr",
+						value: ""
+					}, "blankTaP");
+
+					programmaticTextareaRTL = new dijit.form.Textarea({
+						id: "filledTaP",
+						name: "filledTaP",
+						style:{width:"30em"},
+						textDir:"ltr",
+						value: "created programmatically!"
+					}, "filledTaP");
+
+					programmaticSTaB = new dijit.form.SimpleTextarea({
+						id: "blankSTaP",
+						name: "blankSTaP",
+						style:{width:"30em"},
+						rows:"2",
+						textDir:"ltr",
+						value: ""
+					}, "blankSTaP");
+
+					programmaticSTaF = new dijit.form.SimpleTextarea({
+						id: "filledSTaP",
+						name: "filledSTaP",
+						style:{width:"30em"},
+						rows:"2",
+						textDir:"ltr",
+						value: "created programmatically!"
+					}, "filledSTaP");
+
+					programmaticTextBoxB = new dijit.form.TextBox({
+						id: "blankTbP",
+						name: "blankTbP",
+						style:{width:"30em"},
+						textDir:"ltr",
+						value: ""
+					}, "blankTbP");
+
+					programmaticTextBoxF = new dijit.form.TextBox({
+						id: "filledTbP",
+						name: "filledTbP",
+						style:{width:"30em"},
+						textDir:"ltr",
+						value: "\u05e0\u05d5\u05e6\u05e8\u0020\u05e4\u05e8\u05d5\u05d2\u05de\u05e8\u05d8\u05d9\u0021"
+					}, "filledTbP");
+				});
+
+				var blankTaP
+					, filledTaP
+					, blankTaM
+					, filledlTaM
+					, comboBM
+					, blankTbM
+					, filledTbM
+					, blankStaM
+					, filledStaM
+					, blankTbP
+					, filledTbP
+					, blankSTaP
+					, filledSTaP
+					, combo;	
+					
+				dijit.byId("comboBM").toggleDropDown();
+				dijit.byId("comboBM").closeDropDown();
+			
+				doh.register("test dynamic change of textDir initial", [
+					{
+						name: "initial textDir of all the widgets",
+
+						setUp: function(){
+							blankTaP = dijit.byId("blankTaP");
+							filledTaP = dijit.byId("filledTaP");
+							blankTaM = dijit.byId("blankTaM");
+							filledlTaM = dijit.byId("filledlTaM");
+							comboBM = dijit.byId("comboBM");
+							blankTbM = dijit.byId("blankTbM");
+							filledTbM = dijit.byId("filledTbM");
+							blankStaM = dijit.byId("blankStaM");
+							filledStaM = dijit.byId("filledStaM");
+							blankTbP = dijit.byId("blankTbP");
+							filledTbP = dijit.byId("filledTbP");
+							blankSTaP = dijit.byId("blankSTaP");
+							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");
+							doh.is("ltr",blankTaM.textDir, "direction of : blankTaM");
+							doh.is("ltr",filledlTaM.textDir, "direction of : filledlTaM");
+							doh.is("ltr",comboBM.textDir, "direction of : comboBM");
+							doh.is("ltr",blankTbM.textDir, "direction of : blankTbM");
+							doh.is("ltr",filledTbM.textDir, "direction of : filledTbM");
+							doh.is("ltr",blankStaM.textDir, "direction of : blankStaM");
+							doh.is("ltr",filledStaM.textDir, "direction of : filledStaM");
+							doh.is("ltr",blankTbP.textDir, "direction of : blankTbP");
+							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();
+							setTimeout(d.getTestCallback(function(){
+								//combo.toggleDropDown();
+								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);
+									}
+								});
+							}), 100);
+							return d;
+						},
+						
+						tearDown:function(){
+							combo.closeDropDown();
+						}
+					}
+				]);
+
+				doh.register("test dynamic change of textDir to RTL", [
+					{
+						name: "set textDir dynamically to RTL",
+
+						setUp: function(){
+							var buttonRTL = dojo.byId("swithchTD_RTL");
+							buttonRTL.click();
+						},
+
+						runTest: function(){
+
+							doh.is("rtl",blankTaP.textDir, "direction of : blankTaP");
+							doh.is("rtl",filledTaP.textDir, "direction of : filledTaP");
+							doh.is("rtl",blankTaM.textDir, "direction of : blankTaM");
+							doh.is("rtl",filledlTaM.textDir, "direction of : filledlTaM");
+							doh.is("rtl",comboBM.textDir, "direction of : comboBM");
+							doh.is("rtl",blankTbM.textDir, "direction of : blankTbM");
+							doh.is("rtl",filledTbM.textDir, "direction of : filledTbM");
+							doh.is("rtl",blankStaM.textDir, "direction of : blankStaM");
+							doh.is("rtl",filledStaM.textDir, "direction of : filledStaM");
+							doh.is("rtl",blankTbP.textDir, "direction of : blankTbP");
+							doh.is("rtl",filledTbP.textDir, "direction of : filledTbP");
+							doh.is("rtl",blankSTaP.textDir, "direction of : blankSTaP");
+							doh.is("rtl",filledSTaP.textDir, "direction of : filledSTaP");
+
+							doh.is("rtl",combo.dropDown.textDir, "direction of : combo.dropDown");
+						}
+					},
+					{
+						name: "check focusNode.dir == RTL",
+
+						runTest: function(){
+
+							doh.is("rtl",blankTaP.focusNode.dir, "direction of : blankTaP");
+							doh.is("rtl",filledTaP.focusNode.dir, "direction of : filledTaP");
+							doh.is("rtl",blankTaM.focusNode.dir, "direction of : blankTaM");
+							doh.is("rtl",filledlTaM.focusNode.dir, "direction of : filledlTaM");
+							doh.is("rtl",comboBM.focusNode.dir, "direction of : comboBM");
+							doh.is("rtl",blankTbM.focusNode.dir, "direction of : blankTbM");
+							doh.is("rtl",filledTbM.focusNode.dir, "direction of : filledTbM");
+							doh.is("rtl",blankStaM.focusNode.dir, "direction of : blankStaM");
+							doh.is("rtl",filledStaM.focusNode.dir, "direction of : filledStaM");
+							doh.is("rtl",blankTbP.focusNode.dir, "direction of : blankTbP");
+							doh.is("rtl",filledTbP.focusNode.dir, "direction of : filledTbP");
+							doh.is("rtl",blankSTaP.focusNode.dir, "direction of : blankSTaP");
+							doh.is("rtl",filledSTaP.focusNode.dir, "direction of : filledSTaP");
+
+							var d = new doh.Deferred();
+
+							combo.toggleDropDown();
+							setTimeout(d.getTestCallback(function(){
+								//combo.toggleDropDown();
+								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);
+									}
+								});
+							}), 100);
+							return d;
+						},
+						
+						tearDown:function(){
+							combo.closeDropDown();
+						}
+						
+					}
+				]);
+
+				doh.register("test dynamic change of textDir to LTR", [
+					{
+						name: "set textDir dynamically to LTR",
+
+						setUp: function(){
+							var buttonLTR = dojo.byId("swithchTD_LTR");
+							buttonLTR.click();
+						},
+
+						runTest: function(){
+
+							doh.is("ltr",blankTaP.textDir, "direction of : blankTaP");
+							doh.is("ltr",filledTaP.textDir, "direction of : filledTaP");
+							doh.is("ltr",blankTaM.textDir, "direction of : blankTaM");
+							doh.is("ltr",filledlTaM.textDir, "direction of : filledlTaM");
+							doh.is("ltr",comboBM.textDir, "direction of : comboBM");
+							doh.is("ltr",blankTbM.textDir, "direction of : blankTbM");
+							doh.is("ltr",filledTbM.textDir, "direction of : filledTbM");
+							doh.is("ltr",blankStaM.textDir, "direction of : blankStaM");
+							doh.is("ltr",filledStaM.textDir, "direction of : filledStaM");
+							doh.is("ltr",blankTbP.textDir, "direction of : blankTbP");
+							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");
+						}
+					},
+					{
+						name: "check focusNode.dir == LTR",
+
+						runTest: function(){
+
+							doh.is("ltr",blankTaP.focusNode.dir, "direction of : blankTaP");
+							doh.is("ltr",filledTaP.focusNode.dir, "direction of : filledTaP");
+							doh.is("ltr",blankTaM.focusNode.dir, "direction of : blankTaM");
+							doh.is("ltr",filledlTaM.focusNode.dir, "direction of : filledlTaM");
+							doh.is("ltr",comboBM.focusNode.dir, "direction of : comboBM");
+							doh.is("ltr",blankTbM.focusNode.dir, "direction of : blankTbM");
+							doh.is("ltr",filledTbM.focusNode.dir, "direction of : filledTbM");
+							doh.is("ltr",blankStaM.focusNode.dir, "direction of : blankStaM");
+							doh.is("ltr",filledStaM.focusNode.dir, "direction of : filledStaM");
+							doh.is("ltr",blankTbP.focusNode.dir, "direction of : blankTbP");
+							doh.is("ltr",filledTbP.focusNode.dir, "direction of : filledTbP");
+							doh.is("ltr",blankSTaP.focusNode.dir, "direction of : blankSTaP");
+							doh.is("ltr",filledSTaP.focusNode.dir, "direction of : filledSTaP");
+
+
+							var d = new doh.Deferred();
+
+							combo.toggleDropDown();
+							setTimeout(d.getTestCallback(function(){
+								//combo.toggleDropDown();
+								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);
+									}
+								});
+							}), 100);
+							return d;
+						},
+						
+						tearDown:function(){
+							combo.closeDropDown();
+						}
+					}
+				]);
+
+				doh.register("test dynamic change of textDir", [
+					{
+						name: "set textDir dynamically to auto",
+
+						setUp: function(){
+							var buttonAUTO = dojo.byId("switchTD_AUTO");
+							buttonAUTO.click();
+						},
+					
+						runTest: function(){
+
+							doh.is("auto",blankTaP.textDir, "direction of : blankTaP");
+							doh.is("auto",filledTaP.textDir, "direction of : filledTaP");
+							doh.is("auto",blankTaM.textDir, "direction of : blankTaM");
+							doh.is("auto",filledlTaM.textDir, "direction of : filledlTaM");
+							doh.is("auto",comboBM.textDir, "direction of : comboBM");
+							doh.is("auto",blankTbM.textDir, "direction of : blankTbM");
+							doh.is("auto",filledTbM.textDir, "direction of : filledTbM");
+							doh.is("auto",blankStaM.textDir, "direction of : blankStaM");
+							doh.is("auto",filledStaM.textDir, "direction of : filledStaM");
+							doh.is("auto",blankTbP.textDir, "direction of : blankTbP");
+							doh.is("auto",filledTbP.textDir, "direction of : filledTbP");
+							doh.is("auto",blankSTaP.textDir, "direction of : blankSTaP");
+							doh.is("auto",filledSTaP.textDir, "direction of : filledSTaP");
+
+							doh.is("auto",combo.dropDown.textDir, "direction of : combo.dropDown");
+						}
+					},
+					{
+						name: "check focusNode.dir of textDir == AUTO",
+
+						runTest: function(){
+
+							doh.is(filledTaP._checkContextual(filledTaP.value),filledTaP.focusNode.dir, "direction of : filledTaP");
+							doh.is(filledlTaM._checkContextual(filledlTaM.value),filledlTaM.focusNode.dir, "direction of : filledlTaM");
+							doh.is(comboBM._checkContextual(comboBM.displayedValue),comboBM.focusNode.dir, "direction of : comboBM");
+							doh.is(filledTbM._checkContextual(filledTbM.value),filledTbM.focusNode.dir, "direction of : filledTbM");
+							doh.is(filledStaM._checkContextual(filledStaM.value),filledStaM.focusNode.dir, "direction of : filledStaM");
+							doh.is(filledTbP._checkContextual(filledTbP.value),filledTbP.focusNode.dir, "direction of : filledTbP");
+							doh.is(filledSTaP._checkContextual(filledSTaP.value),filledSTaP.focusNode.dir, "direction of : filledSTaP");
+
+							var d = new doh.Deferred();
+
+							combo.toggleDropDown();
+							setTimeout(d.getTestCallback(function(){
+								var contextualDir;
+
+								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);							
+							}), 100);
+							return d;
+						},
+						
+						tearDown:function(){
+							combo.closeDropDown();
+						}
+					}
+				]);				
+
+				doh.run();
+			});
+		</script>
+	</head>
+	<body class="tundra" data-dojo-textdir="ltr">
+		<h1 class="testTitle">Dynamically changed textDir.</h1>
+		
+		<h2 class="testTitle">Textarea</h2>
+		<div class="testExample">
+			<table>
+				<tr>
+					<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>
+						<br>
+					</th>
+					<th>
+						<label >dijit.form.Textarea, initially filled, programmatically created:</label>
+						<br>
+						<textarea id="filledTaP"></textarea>
+						<br>
+					</th>
+				</tr>
+				<tr>
+					<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>
+						<br>
+					</th>
+					<th>
+						<label for="blankTaP">dijit.form.Textarea, initially blank, programmatically created:</label>
+						<br>
+						<textarea id="blankTaP"></textarea>
+						<br>
+					</th>
+				</tr>
+			</table>
+		</div>
+		<br>
+		<br>
+
+		<h2 class="testTitle">TextBox</h2>
+		<div class="testExample">
+			<table>
+				<tr>
+					<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"'/>
+						<br>
+					</th>
+					<th>
+						<label >dijit.form.TextBox, initially filled, programmatically created:</label>
+						<br>
+						<textarea id="filledTbP"></textarea>
+						<br>
+					</th>
+				</tr>
+				<tr>
+					<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"'/>
+						<br>
+					</th>
+					<th>
+						<label for="blankTaP">dijit.form.Textarea, initially blank, programmatically created:</label>
+						<br>
+						<textarea id="blankTbP"></textarea>
+						<br>
+					</th>
+				</tr>
+			</table>
+		</div>
+		<br>
+		<br>
+		<h2 class="testTitle">SimpleTextarea</h2>
+		<br>
+		<div class="testExample">
+			<table>
+				<tr>
+					<th>
+						<label>dijit.form.SimpleTextarea, initially filled, markup created</label>
+						<br>
+						<textarea id="filledStaM" data-dojo-type="dijit.form.SimpleTextarea"
+							data-dojo-props='name:"filledStaM",rows:"2", style:{width:"30em"}
+							'>שלום עולם, שלום לכולם אין יותר כיף מדוג'ו!
+						</textarea>
+						<br>
+					</th>
+					<th>
+						<label >dijit.form.SimpleTextarea, initially filled, programmatically created:</label>
+						<br>
+						<textarea id="filledSTaP"></textarea>
+						<br>
+					</th>
+				</tr>
+				<tr>
+					<th>
+						<label for="blankTbM">dijit.form.SimpleTextarea, initially blank, markup created:</label>
+						<br>
+						<textarea id="blankStaM" data-dojo-type="dijit.form.SimpleTextarea" 
+							data-dojo-props='name:"blankStaM",rows:"2", style:{width:"30em"},
+							textDir:"ltr"'>
+						</textarea>
+					</th>
+					<th>
+						<label>dijit.form.Textarea, initially blank, programmatically created:</label>
+						<br>
+						<textarea id="blankSTaP"></textarea>
+						<br>
+					</th>
+				</tr>
+			</table>
+		</div>
+				<br>
+		<br>
+		<label for="comboBM">dijit.form.ComboBox, markup</label>
+		<br>
+		<select id="comboBM" 
+			data-dojo-type="dijit.form.ComboBox" 
+			data-dojo-props='name:"comboBM",
+			textDir:"ltr"'>
+				<option >Apples!</option>
+				<option >Oranges!</option>
+				<option selected>Pears!</option>
+				<option >שלום לכם!</option>
+				<option >תפוח אדמה!</option>
+		</select>
+		<br>
+		<br>
+		<br>
+
+		<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('filledlTaM').set('textDir','rtl');
+				dijit.byId('comboBM').set('textDir','rtl');
+				dijit.byId('blankTbM').set('textDir','rtl');
+				dijit.byId('filledTbM').set('textDir','rtl');
+				dijit.byId('blankStaM').set('textDir','rtl');
+				dijit.byId('filledStaM').set('textDir','rtl');
+				dijit.byId('blankTbP').set('textDir','rtl');
+				dijit.byId('filledTbP').set('textDir','rtl');
+				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('filledlTaM').set('textDir','ltr');
+				dijit.byId('comboBM').set('textDir','ltr');
+				dijit.byId('blankTbM').set('textDir','ltr');
+				dijit.byId('filledTbM').set('textDir','ltr');
+				dijit.byId('blankStaM').set('textDir','ltr');
+				dijit.byId('filledStaM').set('textDir','ltr');
+				dijit.byId('blankTbP').set('textDir','ltr');
+				dijit.byId('filledTbP').set('textDir','ltr');
+				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('filledlTaM').set('textDir','auto');
+				dijit.byId('comboBM').set('textDir','auto');
+				dijit.byId('blankTbM').set('textDir','auto');
+				dijit.byId('filledTbM').set('textDir','auto');
+				dijit.byId('blankStaM').set('textDir','auto');
+				dijit.byId('filledStaM').set('textDir','auto');
+				dijit.byId('blankTbP').set('textDir','auto');
+				dijit.byId('filledTbP').set('textDir','auto');
+				dijit.byId('blankSTaP').set('textDir','auto');
+				dijit.byId('filledSTaP').set('textDir','auto');
+			"/>
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/dynamicallyChangeTextDir/module.js b/dijit/tests/_BidiSupport/dynamicallyChangeTextDir/module.js
new file mode 100644
index 0000000..2057f6a
--- /dev/null
+++ b/dijit/tests/_BidiSupport/dynamicallyChangeTextDir/module.js
@@ -0,0 +1,11 @@
+dojo.provide("dijit.tests._BidiSupport.dynamicallyChangeTextDir.module");
+
+try{
+
+	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/dynamicallyChangeTextDir/runTests.html b/dijit/tests/_BidiSupport/dynamicallyChangeTextDir/runTests.html
new file mode 100644
index 0000000..4cf5e97
--- /dev/null
+++ b/dijit/tests/_BidiSupport/dynamicallyChangeTextDir/runTests.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+
+<html>
+	<head>
+		<title>Dijit Unit Test Runner</title>
+		<meta http-equiv="REFRESH" content="0;url=../../../../util/doh/runner.html?testModule=dijit.tests._BidiSupport.dynamicallyChangeTextDir.module"></head>
+	<body>
+		Redirecting to D.O.H runner.
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/form/module.js b/dijit/tests/_BidiSupport/form/module.js
new file mode 100644
index 0000000..d5a883a
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/module.js
@@ -0,0 +1,23 @@
+dojo.provide("dijit.tests._BidiSupport.form.module");
+
+try{
+
+	doh.registerUrl("dijit.tests._BidiSupport.form.noTextDirTextWidgets", dojo.moduleUrl("dijit", "tests/_BidiSupport/form/noTextDirTextWidgets.html"));
+
+	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?");
+
+	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.registerUrl("dijit.tests._BidiSupport.form.robot.SimpleTextarea", dojo.moduleUrl("dijit","tests/_BidiSupport/form/robot/SimpleTextarea.html"+userArgs), 999999);
+
+    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);
+
+}catch(e){
+
+	doh.debug(e);
+
+}
diff --git a/dijit/tests/_BidiSupport/form/noTextDirTextWidgets.html b/dijit/tests/_BidiSupport/form/noTextDirTextWidgets.html
new file mode 100644
index 0000000..451e66a
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/noTextDirTextWidgets.html
@@ -0,0 +1,433 @@
+<!DOCTYPE html>
+
+<html dir="ltr" data-dojo-textdir="rtl">
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>DOH input fields witout textDir support Tests</title>
+
+		<style type="text/css">
+			@import "../../../../dijit/themes/tundra/tundra.css";
+			@import "../../../../dojo/resources/dojo.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../dojo/dojo.js"
+			data-dojo-config="isDebug: 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(){
+
+				doh.register("parse", function(){
+					dojo.parser.parse();
+				});
+
+				doh.register("initial direction of the textBoxes", [
+					{
+						name:"Group 1",
+
+						runTest:function(){
+
+							var textBox1 = dijit.byId("local_1"),
+								textBox2 = dijit.byId("local_12"),
+								textBox3 = dijit.byId("local_2"),
+								textBox4 = dijit.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("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("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.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);
+						}
+					},			
+					{
+						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");
+						
+							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("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("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.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);
+						}
+					},
+					{
+						name:"Group 3",
+
+						runTest:function(){
+
+							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("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("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.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);
+						}
+					},
+					{
+						name:"Group 4",
+
+						runTest:function(){
+
+							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("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("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.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);
+						}
+					},
+					{
+						name:"Group 5",
+
+						runTest:function(){
+	
+							var textBox1 = dijit.byId("q1"),
+								textBox2 = dijit.byId("q2"),
+								textBox3 = dijit.byId("q3"),
+								textBox4 = dijit.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.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("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.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.run();
+			});
+		</script>
+	</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>
+		</div>
+		<div class="testExample">
+			<table>
+				<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"'/>
+					</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"'/>	
+					</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"'/>	
+					</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"'/>	
+					</th>
+				</tr>
+			</table>
+		</div>
+		<div class="dojoTitlePaneLabel">
+			<label for="localLong_1">Group 2: Date (local format - long) </label>
+		</div>
+		<div class="testExample">
+			<table>
+				<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."'/>
+					</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"'/>
+					</th>
+				</tr>							
+				<tr>
+					<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"'/>
+					</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"'/>
+					</th>
+				</tr>
+			</table>
+		</div>
+	
+		<br>
+		<h1 class="testTitle">Test NumberSpinner Widget with _BidiSupport</h1>
+		<div class="dojoTitlePaneLabel">
+			<label >Group 3 </label>
+		</div>
+
+		Try typing values, and use the up/down arrow keys and/or the arrow push	buttons
+
+		<div class="testExample">
+			<table>
+				<tr>
+					<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"
+							data-dojo-props='
+							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"
+							data-dojo-props='
+							value:900,
+							"class":"bigFont",
+							constraints:{max:1550,places:0},
+							name:"integerspinner_12",
+							textDir:"ltr"'/>
+					</th>
+				</tr>							
+				<tr>
+					<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"
+							data-dojo-props='
+							value:900,
+							"class":"bigFont",
+							constraints:{max:1550,places:0},
+							dir:"rtl",
+							name:"integerspinner_2"'/>
+					</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"
+							data-dojo-props='
+							value:900,
+							"class":"bigFont",
+							constraints:{max:1550,places:0},
+							dir:"rtl",
+							textDir:"ltr",
+							name:"integerspinner_22"'/>						
+					</th>
+				</tr>
+			</table>					
+		</div>
+
+		<br>
+		<br>
+
+		<h1 class="testTitle">Test CurrencyTextBox Widget with _BidiSupport</h1>
+		<div class="dojoTitlePaneLabel">
+			<label >Group 4</label>
+		</div>
+		<div class="testExample">
+			<table>
+				<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> 
+					<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"'/>
+					</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"'/>
+					</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"'/>
+					</th>
+				</tr>
+			</table>
+		</div>
+	
+		<h1 class="testTitle">Test TimeTextBox Widget with _BidiSupport</h1>
+		<div class="dojoTitlePaneLabel">
+			<label >Group 5 </label>
+		</div>
+		<div class="testExample">
+			<table>
+				<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"'/>					
+					</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"'/>		
+					</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"'/>		
+					</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"'/>		
+					</th>
+				</tr>
+			</table>
+		</div>
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/form/robot/InlineEditBox.html b/dijit/tests/_BidiSupport/form/robot/InlineEditBox.html
new file mode 100644
index 0000000..99cb5ae
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/robot/InlineEditBox.html
@@ -0,0 +1,264 @@
+<!DOCTYPE html>
+
+<html>
+	<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 type="text/javascript">
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(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");
+							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);							
+							return d;
+						}
+					},
+					{
+						name: "paste Hebrew in 'rtlInlineEditBox'",
+						timeout:10000,
+
+						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};
+							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);					
+							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);
+						}  
+						
+					},					
+					{
+						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);
+							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);					
+							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");
+							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);							
+							return d;
+						}
+					},
+					{
+						name: "paste Hebrew in 'rtlInlineEditBox'",
+						timeout: 10000,
+
+						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};
+							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);					
+							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);
+						}  
+						
+					},					
+					{
+						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);
+
+						    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);					
+							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);
+							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('ltr', combo.get("textDir"), "direction of :" + inlineBox.id);
+								dojo.forEach(combo.dropDown.domNode.childNodes, function(node){
+									if(node.item){
+										doh.is("ltr", node.dir, node.textContent);
+									}
+								});
+								inlineBox.save(true);
+							}), 900);							
+							return d;
+						}
+					},
+					{
+						name: "test RTL ComboBox",
+						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);						
+							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);				
+							return d;
+						}
+					}					
+				]);	
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/_BidiSupport/form/robot/SimpleComboBoxes.html b/dijit/tests/_BidiSupport/form/robot/SimpleComboBoxes.html
new file mode 100644
index 0000000..4a6e9c2
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/robot/SimpleComboBoxes.html
@@ -0,0 +1,414 @@
+<!DOCTYPE html>
+
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<title>doh.robot ComboBox textDir Tests</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(){
+				var combo;
+
+				doh.robot.initRobot('../test_SimpleComboBoxes.html');
+
+				doh.register("Test LTR combo box", [
+					{
+						name:"check drop down items text direction.",
+						timeout:3000,
+
+						setUp: function(){
+							combo = dijit.byId("fruitLtr");
+							modifier = dojo.isMac ? {meta: true} : {ctrl: true};
+						},
+						
+						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("ltr", node.dir, node.textContent);
+									}
+								});
+							}), 900);
+							
+							return d;
+						},
+
+						tearDown: function(){
+							combo.closeDropDown();
+						}
+					},
+					{
+						name: "paste English in 'fruitLtr'",
+						timeout: 3000,
+
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.keyPress("a", 300, modifier);
+							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);								
+
+							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);								
+
+							return d;
+						}
+					}
+				]);			
+	
+				doh.register("Test RTL combo box", [
+					{
+						name:"check drop down items text direction.",
+						timeout:3000,
+
+						setUp: function(){
+							combo = dijit.byId("fruitRtl");
+						},
+						
+						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);
+							
+							return d;
+						},
+						
+						tearDown: function(){
+							combo.closeDropDown();
+						}
+					},
+					{
+						name: "paste English in 'fruitRtl'",
+						timeout: 3000,
+
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.keyPress("a", 300, modifier);
+							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);								
+
+							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);								
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("Test AUTO ComboBox", [
+					{
+						name:"check drop down items text direction.",
+						timeout:60000,
+
+						setUp:function(){
+							combo = dijit.byId("fruitContextual");
+							modifier = dojo.isMac ? {meta: true} : {ctrl: true};
+						},
+			
+						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);
+							
+							return d;
+						},
+
+						tearDown: function(){
+							combo.closeDropDown();
+						}
+					},
+					{
+						name:"input field text direction for each item in the menu.",
+						timeout:6000,
+
+						setUp:function(){
+							combo = dijit.byId("fruitContextual");
+							modifier = dojo.isMac ? {meta: true} : {ctrl: true};
+						},
+			
+						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);
+							}), 200);
+
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);
+							doh.robot.sequence(d.getTestErrback(function(){
+								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);
+							}), 200);
+
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
+							doh.robot.sequence(d.getTestErrback(function(){
+								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);
+							}), 200);
+
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("rtl",combo.focusNode.dir, combo.id);
+							}), 200);
+						
+							return d;
+						},
+
+						tearDown: function(){
+							combo.closeDropDown();
+						}
+					},
+					{
+						name: "text direction cut/paste English",
+						timeout: 3000,
+						
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.setClipboard("I am pasted!!!",'text/html');
+
+							doh.robot.keyPress("a", 500, modifier);
+							doh.robot.keyPress(dojo.keys.DELETE, 500, {});
+
+							doh.robot.keyPress("v", 500, modifier);
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("ltr",combo.focusNode.dir,"direction of :" + combo.id);
+							}), 300);								
+
+							return d;
+						}
+					},
+					{
+						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, {});	
+
+							doh.robot.keyPress("v", 400, modifier);
+							doh.robot.sequence(d.getTestCallback(function(){
+								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'",
+						timeout: 30000,
+
+						setUp: function(){
+							autoCompleted = dijit.byId("fruitContextualAC");
+						},
+
+						runTest: function(){
+							var d = new doh.Deferred();
+							autoCompleted.focusNode.focus();
+
+							// Filter drop down list to entries starting with ":"
+							doh.robot.sequence(function(){ autoCompleted.set("value", null); }, 400);
+							doh.robot.keyPress(":", 100);
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								doh.is("ltr", autoCompleted.focusNode.dir, "input field of fruitContextualAC");
+								var entries = dojo.query("div", dojo.byId("fruitContextualAC_popup"));
+								doh.is("ltr", entries[1].dir, "list #1");
+								doh.is("rtl", entries[2].dir, "list #2");
+							}), 900);
+
+							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");
+							}), 200);
+							
+							doh.robot.sequence(function(){ autoCompleted.set("value", null); }, 400);
+							doh.robot.keyPress("@", 100);
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								doh.is("ltr", autoCompleted.focusNode.dir, "input field of fruitContextualAC");
+								var entries = dojo.query("div", dojo.byId("fruitContextualAC_popup"));
+								doh.is("ltr", entries[1].dir, "list #1");
+							}), 900);
+
+							doh.robot.sequence(function(){ autoCompleted.set("value", null); }, 400);
+							doh.robot.keyPress("*", 100);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("rtl", autoCompleted.focusNode.dir, "input field of fruitContextualAC");
+								var entries = dojo.query("div", dojo.byId("fruitContextualAC_popup"));
+								doh.is("rtl", entries[1].dir, "list #1");
+							}), 900);
+
+							return d;
+						}
+					},
+					{
+						name: "test auto-completion popup and input field for autoComplete:false",
+						timeout: 12000,
+
+						setUp: function(){
+							notAutoCompleted = dijit.byId("fruitContextual");
+						},
+
+						runTest: function(){
+							var d = new doh.Deferred();
+							notAutoCompleted.focusNode.focus();
+
+							// Filter drop down list to entries starting with ":"
+							doh.robot.sequence(function(){ notAutoCompleted.set("value", null); }, 400);
+							doh.robot.keyPress(":", 300);
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								doh.is(notAutoCompleted.isLeftToRight() ? "ltr" : "rtl",
+										notAutoCompleted.focusNode.dir, "false autoComplete - :");
+								var entries = dojo.query("div", dojo.byId("fruitContextual_popup"));
+								doh.is("ltr", entries[1].dir, "list #1 - :");
+								doh.is("rtl", entries[2].dir, "list #2 - :");
+							}), 900);
+
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
+							doh.robot.sequence(d.getTestErrback(function(){
+								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 - :");
+							}), 200);
+
+							// Filter drop down list to entries starting with "@"							
+							doh.robot.sequence(function(){ 
+								notAutoCompleted.set("value", null); 
+							}, 400);
+							doh.robot.keyPress("@", 100);
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								doh.is(notAutoCompleted.isLeftToRight() ? "ltr" : "rtl",
+										notAutoCompleted.focusNode.dir, "false autoComplete - @");
+								var entries = dojo.query("div", dojo.byId("fruitContextual_popup"));
+								doh.is("ltr", entries[1].dir, "list #1 - @");
+							}), 900);
+
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
+							doh.robot.sequence(d.getTestErrback(function(){
+								doh.is("ltr",notAutoCompleted.focusNode.dir, "input field of fruitContextual - :");
+							}), 200);
+
+
+							// Filter drop down list to entries starting with "*"
+							doh.robot.sequence(function(){ notAutoCompleted.set("value", null); }, 400);
+							doh.robot.keyPress("*", 100);
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								doh.is(notAutoCompleted.isLeftToRight() ? "ltr" : "rtl",
+										notAutoCompleted.focusNode.dir, "false autoComplete - *");
+								var entries = dojo.query("div", dojo.byId("fruitContextual_popup"));
+								doh.is("rtl", entries[1].dir, "list #1 - *");
+							}), 900);
+
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("rtl",notAutoCompleted.focusNode.dir, "input field of fruitContextual - :");
+							}), 200);
+
+							
+							return d;
+						}
+					}
+				]);
+				
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/_BidiSupport/form/robot/SimpleTextarea.html b/dijit/tests/_BidiSupport/form/robot/SimpleTextarea.html
new file mode 100644
index 0000000..50bc8b5
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/robot/SimpleTextarea.html
@@ -0,0 +1,388 @@
+<!DOCTYPE html>
+
+<html>
+	<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 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(){
+							widget.disconnect(handler);
+							setTimeout(fcn, 1);
+						});
+						widget.focus();
+					}else{
+						fcn();
+					}
+				};
+
+				doh.register("LTR textarea", [
+					{
+						name: "initial text direction of filled 'ltrSimpleTexarea'",
+					
+						setUp: function(){
+							textarea = dijit.byId("ltrSimpleTexarea");
+							modifier = dojo.isMac ? {meta: true} : {ctrl: true};
+						},
+
+						runTest: function(){
+							doh.is("ltr",textarea.focusNode.dir,"direction of :" + textarea.id);
+						}
+					},
+					{
+						name: "write in English in 'ltrSimpleTexarea'",
+						timeout: 2000,
+						
+						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, 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,
+
+						setUp: function(){
+							textarea = dijit.byId("ltrSimpleTexarea");
+						},
+
+						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');
+
+								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("ltr",textarea.focusNode.dir,"direction of :" + textarea.id);
+								}), 400);
+							});
+
+							return d;
+						}
+					}
+				]);				
+				
+				doh.register("RTL textarea", [
+					{
+						name: "initial text direction of filled 'rtlSimpleTexarea'",
+					
+						setUp: function(){
+							textarea = dijit.byId("rtlSimpleTexarea");
+						},
+
+						runTest: function(){
+							doh.is("rtl",textarea.focusNode.dir,"direction of :" + textarea.id);
+						}
+					},
+					{
+						name: "write in English in 'rtlSimpleTexarea'",
+						timeout: 2000,
+						
+						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, 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,
+
+						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');
+
+								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",textarea.focusNode.dir,"direction of :" + textarea.id);
+								}), 400);
+							});
+							return d;
+						}
+					}
+				]);	
+
+				doh.register("Contextual textarea", [
+					{
+						name: "initial text direction of filled 'contextualSimpleTexarea'",
+					
+						setUp: function(){
+							textarea = dijit.byId("contextualSimpleTexarea");
+						},
+
+						runTest: function(){
+							doh.is("rtl",textarea.focusNode.dir,"direction of :" + textarea.id);
+						}
+					},
+					{
+						name: "write in English in 'contextualSimpleTexarea'",
+						timeout: 2000,
+						
+						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;
+						}
+					},
+					{
+						name: "text direction paste Hebrew before English",
+						timeout: 3000,
+
+						runTest: function(){
+							var d = new doh.Deferred(),
+								modifier = dojo.isMac ? {meta: true} : {ctrl: true},
+								textarea = dijit.byId("contextualSimpleTexarea");
+
+							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, {});	
+
+								doh.robot.keyPress("v", 400, modifier);
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.is("rtl",textarea.focusNode.dir,"direction of :" + textarea.id);
+								}), 800);
+							});
+
+							return d;
+						}
+					}
+				]);
+
+				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};
+						},
+
+						runTest: function(){
+							doh.is("auto",textarea.textDir,"direction of :" + textarea.id);
+						}
+					},
+					{
+						name: "write in English in 'programmaticAuto'",
+						timeout: 2000,
+						
+						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, 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,
+
+						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');
+
+								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",textarea.focusNode.dir,"direction of :" + textarea.id);
+								}), 400);
+							});
+
+							return d;
+						}
+					}
+				]);				
+				
+				doh.register("programmaticRTL textarea in the border container", [
+					{
+						name: "initial text direction of filled 'programmaticRTL'",
+					
+						setUp: function(){
+							textarea = dijit.byId("programmaticRTL");
+						},
+
+						runTest: function(){
+							doh.is("rtl",textarea.focusNode.dir,"direction of :" + textarea.id);
+						}
+					},
+					{
+						name: "write in English in 'programmaticRTL'",
+						timeout: 2000,
+						
+						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, 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,
+
+						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');
+
+								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",textarea.focusNode.dir,"direction of :" + textarea.id);
+								}), 400);
+							});
+							return d;
+						}
+					}
+				]);	
+
+				doh.register("programmaticLTR textarea in the border container", [
+					{
+						name: "initial text direction of filled 'programmaticLTR'",
+					
+						setUp: function(){
+							textarea = dijit.byId("programmaticLTR");
+						},
+
+						runTest: function(){
+							doh.is("ltr",textarea.focusNode.dir,"direction of :" + textarea.id);
+						}
+					},
+					{
+						name: "write in English in 'programmaticLTR'",
+						timeout: 2000,
+						
+						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;
+						}
+					},
+					{
+						name: "text direction paste Hebrew before English",
+						timeout: 3000,
+
+						runTest: function(){
+							var d = new doh.Deferred(),
+								modifier = dojo.isMac ? {meta: true} : {ctrl: true};
+
+							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');
+
+								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(){
+									doh.is("ltr",textarea.focusNode.dir,"direction of :" + textarea.id);
+								}), 800);
+								
+							});
+
+							return d;
+						}
+					}
+				]);				
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/_BidiSupport/form/robot/TextBoxes.html b/dijit/tests/_BidiSupport/form/robot/TextBoxes.html
new file mode 100644
index 0000000..7253c5a
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/robot/TextBoxes.html
@@ -0,0 +1,238 @@
+<!DOCTYPE html>
+
+<html>
+	<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>
+			@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_TextBoxes.html');
+				
+				// execute some test as soon as the widget gets focus
+				var focusThenRun = function(widget, fcn){
+					if(!widget.focused){
+						var handler = widget.connect(widget, '_onFocus', function(){
+							widget.disconnect(handler);
+							setTimeout(fcn, 1);
+						});
+						widget.focus();
+					}else{
+						fcn();
+					}
+				};
+
+				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.sequence(d.getTestCallback(function(){
+									doh.is("ltr",textBox.focusNode.dir,"direction of :" + textBox.id);
+								}), 400);
+							});
+
+							return d;
+						}
+					},
+					{
+						name: "paste Hebrew in 'ltrTextBox'",
+						timeout: 2000,
+
+						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);
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.is("ltr",textBox.focusNode.dir,"direction of :" + textBox.id);
+								}), 400);
+							});
+
+							return d;
+						}
+					}
+				]);				
+				
+				doh.register("RTL textBox", [
+					{
+						name: "initial text direction of empty 'rtlTextBox'",
+
+						setUp: function(){
+							textBox = dijit.byId("rtlTextBox");
+						},
+
+						runTest: function(){
+							doh.is("rtl",textBox.focusNode.dir,"direction of :" + textBox.id);
+						}
+					},
+					{
+						name: "write in English in 'rtlTextBox'",
+						timeout: 3000,
+
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							focusThenRun(textBox, function(){
+								doh.robot.typeKeys('Hello!', 1, 300);
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.is("rtl",textBox.focusNode.dir,"direction of :" + textBox.id);
+								}), 400);
+							});
+
+							return d;
+						}
+					},				
+					{
+						name: "paste Hebrew in 'rtlTextBox'",
+						timeout: 2000,
+
+						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);
+
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.is("rtl",textBox.focusNode.dir,"direction of :" + textBox.id);
+								}), 400);
+							});
+
+							return d;
+						}
+					}
+				]);	
+
+				doh.register("Contextual textBox", [
+					{
+						name: "initial text direction of empty 'contextualTextBox'",
+
+						setUp: function(){
+							textBox = dijit.byId("contextualTextBox");
+						},
+
+						runTest: function(){
+							doh.is("auto",textBox.textDir,"textDir of :" + textBox.id);
+						}
+					},
+					{
+						name: "write in English in 'contextualTextBox'",
+						timeout: 3000,
+
+						runTest: function(){
+							var d = new doh.Deferred(),
+								modifier = dojo.isMac ? {meta: true} : {ctrl: true},
+								textBox = dijit.byId("contextualTextBox");
+
+							focusThenRun(textBox, function(){
+								doh.robot.setClipboard("Hello!",'text/html');
+
+								doh.robot.keyPress("v", 600, modifier);
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.is("ltr",textBox.focusNode.dir,"direction of :" + textBox.id);
+								}), 300);	
+							});					
+
+							return d;
+						}
+					},
+					{
+						name: "text direction paste Hebrew before English",
+						timeout: 2000,
+
+						runTest: function(){
+							var d = new doh.Deferred(),
+								modifier = dojo.isMac ? {meta: true} : {ctrl: true},
+								textBox = dijit.byId("contextualTextBox");
+
+							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, {});	
+
+								doh.robot.keyPress("v", 400, modifier);
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.is("rtl",textBox.focusNode.dir,"direction of :" + textBox.id);
+								}), 400);
+							});
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("test the programmatic textBox in the tab container", [
+					{
+						name: "initial direction of the textBoxs",
+
+						setUp: function(){
+							textBox1 = dijit.byId("programmatic1");
+							textBox2 = dijit.byId("programmatic2");
+							textBox3 = dijit.byId("programmatic3");
+						},
+
+						runTest: function(){
+							doh.is("ltr",textBox1.focusNode.dir,"Initial direction of - 'programmatic'");
+							doh.is("rtl",textBox2.focusNode.dir,"Initial direction of - 'programmatic'");
+							doh.is("ltr",textBox3.focusNode.dir,"Initial direction of - 'programmatic'");
+						}
+					},
+					{
+						name: "direction of textBoxs after change value button in second tab is pressed",
+
+						runTest: function(){
+							var button = dojo.byId("changeValue");
+
+							button.click();
+
+							doh.is("ltr",textBox1.focusNode.dir,"Initial direction of - 'programmatic'");
+							doh.is("rtl",textBox2.focusNode.dir,"Initial direction of - 'programmatic'");
+							doh.is("rtl",textBox3.focusNode.dir,"Initial direction of - 'programmatic'");
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/_BidiSupport/form/robot/Textarea.html b/dijit/tests/_BidiSupport/form/robot/Textarea.html
new file mode 100644
index 0000000..d345a0c
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/robot/Textarea.html
@@ -0,0 +1,265 @@
+<!DOCTYPE html>
+
+<html>
+	<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 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){
+						var handler = widget.connect(widget, '_onFocus', function(){
+							widget.disconnect(handler);
+							setTimeout(fcn, 1);
+						});
+						widget.focus();
+					}else{
+						fcn();
+					}
+				};
+
+				doh.register("LTR textarea", [
+					{
+						name: "initial text direction of empty 'blankL'",
+						
+						setUp: function(){
+							textarea = dijit.byId("blankL");
+							modifier = dojo.isMac ? {meta: true} : {ctrl: true};
+						},
+
+						runTest: function(){
+							doh.is("ltr",textarea.focusNode.dir,"direction of :" + textarea.id);
+						}
+					},				
+					{
+						name: "write in English in 'blankL'",
+						timeout: 3000,
+
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							focusThenRun(textarea, function(){
+								doh.robot.typeKeys('Hello!', 1, 300);
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.is("ltr",textarea.focusNode.dir,"direction of :" + textarea.id);
+								}), 400);
+							});
+
+							return d;
+						}
+					},
+					{
+						name: "paste Hebrew in 'blankL'",
+						timeout: 2000,
+						
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							focusThenRun(textarea, 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);
+								doh.robot.sequence(d.getTestCallback(function(){
+									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");
+						},
+
+						runTest: function(){
+							doh.is("rtl",textarea.focusNode.dir,"direction of :" + textarea.id);
+						}
+					},
+					{
+						name: "write in English in 'blankR'",
+						timeout: 3000,
+
+						runTest: function(){
+							var d = new doh.Deferred();
+ 
+							focusThenRun(textarea, function(){
+								doh.robot.typeKeys('Hello!', 1, 300);
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.is("rtl",textarea.focusNode.dir,"direction of :" + textarea.id);
+								}), 400);
+							});
+
+							return d;
+						}
+					},				
+					{
+						name: "paste Hebrew in 'blankR'",
+						timeout: 2000,
+	
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							focusThenRun(textarea, 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);
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.is("rtl",textarea.focusNode.dir,"direction of :" + textarea.id);
+								}), 400);
+							});
+
+							return d;
+						}
+					}
+				]);	
+
+				doh.register("Contextual textarea", [
+					{
+						name: "initial text direction of empty 'blankA'",
+												
+						setUp: function(){
+							textarea = dijit.byId("blankA");
+						},
+
+						runTest: function(){
+							doh.is(textarea.isLeftToRight() ? "ltr" : "rtl", textarea.focusNode.dir,
+									"direction of :" + textarea.id);
+						}
+					},
+					{
+						name: "text direction cut/paste English",
+						timeout: 6000,
+
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							focusThenRun(textarea, function(){
+								doh.robot.setClipboard("Hello again I'm pasted!!!",'text/html');
+
+								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(){
+									doh.is("ltr",textarea.focusNode.dir,"direction of :" + textarea.id);
+								}), 900);
+							});
+
+							return d;
+						}
+					},
+					{
+						name: "text direction paste Hebrew before English",
+						timeout: 6000,
+
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							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, {});	
+
+								doh.robot.keyPress("v", 400, modifier);
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.is("rtl",textarea.focusNode.dir,"direction of :" + textarea.id);
+								}), 400);
+							});
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("Test the programmatic textareas in the tab container", [
+					{
+						name: "initial direction of the textareas",
+
+						setUp: function(){
+							textareaL = dijit.byId("programmaticLTR");
+							textareaR = dijit.byId("programmaticRTL");
+							textareaA = dijit.byId("programmaticAuto");
+						},
+						runTest: function(){
+							doh.is("ltr",textareaL.focusNode.dir,"Initial direction of - 'programmaticLTR'");
+							doh.is("rtl",textareaR.focusNode.dir,"Initial direction of - 'programmaticRTL'");
+							doh.is("ltr",textareaA.focusNode.dir,"Initial direction of - 'programmaticAUTO'");
+						}
+					},
+					{
+						name: "direction of textareas after Hebrew button in second tab is pressed",
+
+						runTest: function(){
+							var id = "buttonHebrew";
+							var buttonHebrew = dojo.byId("buttonHebrew");
+
+							buttonHebrew.click();
+
+							doh.is("ltr",textareaL.focusNode.dir,"Initial direction of - 'programmaticLTR'");
+							doh.is("rtl",textareaR.focusNode.dir,"Initial direction of - 'programmaticRTL'");
+							doh.is("rtl",textareaA.focusNode.dir,"Initial direction of - 'programmaticAUTO'");
+						}
+					},
+					{
+						name: "direction of textareas after English button in second tab is pressed",
+
+						runTest: function(){
+							var buttonEnglish = dojo.byId("buttonEnglish");
+
+							buttonEnglish.click();
+
+							doh.is("ltr",textareaL.focusNode.dir,"Initial direction of - 'programmaticLTR'");
+							doh.is("rtl",textareaR.focusNode.dir,"Initial direction of - 'programmaticRTL'");
+							doh.is("ltr",textareaA.focusNode.dir,"Initial direction of - 'programmaticAUTO'");
+						}
+					}
+				]);
+
+				doh.register("Test the large textareas", [
+					{
+						name: "initial direction of the textareas",
+
+						setUp: function(){
+							textareaL = dijit.byId("largeTextAreaLTR");
+							textareaR = dijit.byId("largeTextAreaRTL");
+						},
+
+						runTest: function(){
+							doh.is("ltr",textareaL.focusNode.dir,"Initial direction of - 'programmaticLTR'");
+							doh.is("rtl",textareaR.focusNode.dir,"Initial direction of - 'programmaticRTL'");
+						}
+					}
+				]);
+			
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/_BidiSupport/form/runTests.html b/dijit/tests/_BidiSupport/form/runTests.html
new file mode 100644
index 0000000..c09abc4
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/runTests.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+
+<html>
+	<head>
+		<title>Dijit Unit Test Runner</title>
+		<meta http-equiv="REFRESH" content="0;url=../../../../util/doh/runner.html?testModule=dijit.tests._BidiSupport.form.module"></head>
+	<body>
+		Redirecting to D.O.H runner.
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/form/test_InlineEditBox.html b/dijit/tests/_BidiSupport/form/test_InlineEditBox.html
new file mode 100644
index 0000000..d294e5f
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/test_InlineEditBox.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Inline Edit Box Test</title>
+
+		<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: -->
+		<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("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("dijit._BidiSupport");//lena
+
+			dojo.require("dojo.parser");	  // scan page for widgets and instantiate them
+
+			function myHandler(newValue){
+				this._onChangeValue = newValue;	// used by robot test file
+				console.debug("onChange for id = " + this.id + ", value: " + newValue);
+			}
+		</script>
+	</head>
+	<body class="claro">
+
+		<h1 class="testTitle">Dijit InlineEditBox Bidi Test</h1>
+
+	
+		<span data-dojo-id="productStore" data-dojo-type="dojo.data.ItemFileReadStore" >
+			<script type="dojo/method">
+				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"'>
+			</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"/>
+		  
+		
+		<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"/>
+		
+		
+		<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",
+					editorParams:{searchAttr: "name", store: productStore, autocomplete: false, hasDownArrow: false},
+					 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",
+					editorParams:{searchAttr: "name", store: productStore, autocomplete: false, hasDownArrow: false},
+					 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",
+					editorParams:{searchAttr: "name", store: productStore, autocomplete: false, hasDownArrow: false},
+					 width:"200px", autoSave:false, title:"item name"'>refrigerators...</span>					 
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/form/test_SimpleComboBoxes.html b/dijit/tests/_BidiSupport/form/test_SimpleComboBoxes.html
new file mode 100644
index 0000000..ef10033
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/test_SimpleComboBoxes.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+
+<html>
+	<head >
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>ComboBox with _BidiSupport</title>
+
+	<style>
+		@import "../../../themes/claro/document.css";
+		@import "../../../../util/doh/robot/robot.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="parseOnLoad: true, isDebug: 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);
+
+		</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" 
+			data-dojo-props='name:"fruitLtr",
+			textDir:"ltr"'>
+				<option >Apples!</option>
+				<option >Oranges!</option>
+				<option selected>Pears!</option>
+				<option >שלום לכם!</option>
+				<option >תפוח אדמה!</option>
+		</select>
+		<br>
+		<label for="fruitRtl"> <b>I'm a RTL ComboBox </b> </label>
+		<br>
+		<select id="fruitRtl" 
+			data-dojo-type="dijit.form.ComboBox" 
+			data-dojo-props='name:"fruitRtl",
+			textDir:"rtl"'>
+				<option >Apples!</option>
+				<option >Oranges!</option>
+				<option selected>Pears!</option>
+				<option >שלום לכם!</option>
+				<option >תפוח אדמה!</option>
+		</select>
+		<br>
+		<label for="fruitContextual"> <b>I'm a Contextual ComboBox </b> </label>
+		<br>
+		<select id="fruitContextual" 
+			data-dojo-type="dijit.form.ComboBox" 
+			data-dojo-props='name:"fruitContextual",
+			autoComplete:false,
+			textDir:"auto"'>
+				<option >@Apples!</option>
+				<option >:Oranges!</option>
+				<option selected>Pears!</option>
+				<option >*תפוח אדמה!</option>
+				<option >:שלום לכם!</option>
+		</select>
+		<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",				
+			textDir:"auto"'>
+				<option >@Apples!</option>
+				<option >:Oranges!</option>
+				<option selected>Pears!</option>
+				<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
new file mode 100644
index 0000000..797c366
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/test_SimpleTextarea.html
@@ -0,0 +1,106 @@
+<!DOCTYPE html>
+
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>SimpleTextarea with _BidiSupport</title>
+
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</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("dijit.dijit"); // optimize: load dijit layer
+			dojo.require("dijit.form.SimpleTextarea");
+			dojo.require("dijit._BidiSupport");
+		</script>
+	</head>
+
+	<body class="claro" style="padding:20px">
+
+		<h1 class="testTitle">SimpleTextarea with _BidiSupport</h1>
+		<p>The value of the textDir setted in all examples, in the text box widget itself.</p>
+		<label for="ltrSimpleTexarea" >
+			<b>I'm a LTR SimpleTextarea </b>
+		</label>
+		<br>
+		<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>
+		<br>
+		<br>
+		<label for="rtlSimpleTexarea" >
+			<b>I'm a RTL SimpleTextarea </b>
+		</label>
+		<br>
+		<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>
+		<br>
+		<br>
+		<label for="contextualSimpleTexarea" >
+			<b>I'm a contextual SimpleTexarea </b>
+		</label>
+		<br>
+		<textarea id="contextualSimpleTexarea" data-dojo-type="dijit.form.SimpleTextarea" 
+			data-dojo-props='name:"contextualSimpleTexarea",rows:"4", cols:"50",
+			textDir:"auto"
+			'> הטקסט מוצג כמו שצריך
+ואני קונטקסטואלי!</textarea>
+		<br>
+		<h2>Initially empty and programmatically created - Simple Textareas</h2>
+
+		<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>
+
+		<script type="text/javascript">
+			// See if we can make a widget in script
+			dojo.ready(function(){
+				programmaticTextareaLTR = new dijit.form.SimpleTextarea({
+					id: "programmaticLTR",
+					name: "programmaticTextAreaLTR",
+					cols: "60",
+					textDir:"ltr",
+					value: "", 
+					style: "border:5px solid gray;padding:11px;margin:7px;"
+				}, "programmaticLTR");
+
+				programmaticTextareaRTL = new dijit.form.SimpleTextarea({
+					id: "programmaticRTL",
+					name: "programmaticTextAreaRTL",
+					cols: "60",
+					textDir:"rtl",
+					value: "",
+					style: "border:5px solid gray;padding:11px;margin:7px;"
+				}, "programmaticRTL");
+
+				programmaticTextareaAuto = new dijit.form.SimpleTextarea({
+					id: "programmaticAuto",
+					name: "programmaticTextAreaAuto",
+					cols: "60",
+					textDir:"auto",
+					value: "",
+					style: "border:5px solid gray;padding:11px;margin:7px;"
+				}, "programmaticAuto");
+
+			});
+		</script>		
+		
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/form/test_TextBoxes.html b/dijit/tests/_BidiSupport/form/test_TextBoxes.html
new file mode 100644
index 0000000..e171068
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/test_TextBoxes.html
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+
+<html >
+	<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";	
+		</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("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"'/>
+
+		<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"'/>
+		
+		<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"'/>
+
+		<br>
+		<br>
+
+		<label for="programmatic1">dijit.form.Textarea programmatically created with custom styling:</label><br>
+		<input id="programmatic1"/>
+		<label for="programmatic2">dijit.form.Textarea programmatically created with custom styling:</label><br>
+		<input id="programmatic2"/>
+		<label for="programmatic3">dijit.form.Textarea programmatically created with custom styling:</label><br>
+		<input id="programmatic3"/>
+
+		<input id="changeValue" type="button" onclick="programmaticTextBox1.set('value', 'ערך חדש!');programmaticTextBox2.set('value', 'ערך חדש!');programmaticTextBox3.set('value', 'ערך חדש!');" value="change value"/>
+
+		<script type="text/javascript">
+			dojo.ready(function(){
+				programmaticTextBox1 = new dijit.form.TextBox({
+					id: "programmatic1",
+					name: "programmaticTextbox1",
+					textDir: "ltr",
+					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",
+					textDir: "rtl",
+					value: "created programatically with custom border, padding, margin! textDir=auto!",
+					style: {border:"5px solid gray", padding:"11px", margin:"7px"}
+				}, "programmatic2");
+
+				
+				programmaticTextBox3 = new dijit.form.TextBox({
+					id: "programmatic3",
+					name: "programmaticTextbox3",
+					textDir: "auto",
+					value: "created programatically with custom border, padding, margin! textDir=auto!",
+					style: {border:"5px solid gray", padding:"11px", margin:"7px"}
+				}, "programmatic3");
+
+			});
+		</script>
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/form/test_Textarea.html b/dijit/tests/_BidiSupport/form/test_Textarea.html
new file mode 100644
index 0000000..878f8c7
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/test_Textarea.html
@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">	
+		<title>Textarea with _BidiSupport</title>
+
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</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("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>
+	<body class="claro" >
+		<h1 class="testTitle">Textarea Widget Test with _BidiSupport</h1>
+		<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>
+		<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>
+		<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>
+		<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>
+
+		<br>
+		<input id="buttonHebrew" type="button" value="change value - Hebrew"
+			onclick="programmaticTextareaLTR.set('value', 'ערך חדש!'); programmaticTextareaRTL.set('value', 'ערך חדשׁ!'); programmaticTextareaAuto.set('value', 'ערך חדשׁ!');"
+		/>
+
+		<br>
+		<input id="buttonEnglish" type="button" value="change value - English"
+			onclick="programmaticTextareaLTR.set('value', 'New Value!'); programmaticTextareaRTL.set('value', 'New Value!'); programmaticTextareaAuto.set('value', 'New Value!');"
+		/>
+
+		<br>
+		<script type="text/javascript">
+			// See if we can make a widget in script
+			dojo.ready(function(){
+				programmaticTextareaLTR = new dijit.form.Textarea({
+					id: "programmaticLTR",
+					name: "programmaticTextAreaLTR",
+					cols: "60",
+					textDir:"ltr",
+					value: "created programatically!", 
+					style: "border:5px solid gray;padding:11px;margin:7px;"
+				}, "programmaticLTR");
+
+				programmaticTextareaRTL = new dijit.form.Textarea({
+					id: "programmaticRTL",
+					name: "programmaticTextAreaRTL",
+					cols: "60",
+					textDir:"rtl",
+					value: "created programatically!",
+					style: "border:5px solid gray;padding:11px;margin:7px;"
+				}, "programmaticRTL");
+
+				programmaticTextareaAuto = new dijit.form.Textarea({
+					id: "programmaticAuto",
+					name: "programmaticTextAreaAuto",
+					cols: "60",
+					textDir:"auto",
+					value: "created programatically!",
+					style: "border:5px solid gray;padding:11px;margin:7px;"
+				}, "programmaticAuto");
+
+			});
+		</script>
+		<br>
+
+		<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", 
+			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 [...]
+
+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 [...]
+
+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 [...]
+
+This is the end.</textarea>
+		<br>
+		<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>
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/inheritance/Inher-ComplexMarkupContainers.html b/dijit/tests/_BidiSupport/inheritance/Inher-ComplexMarkupContainers.html
new file mode 100644
index 0000000..2fcff89
--- /dev/null
+++ b/dijit/tests/_BidiSupport/inheritance/Inher-ComplexMarkupContainers.html
@@ -0,0 +1,262 @@
+<!DOCTYPE html>
+
+<html data-dojo-textdir="rtl">
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">	
+		<title>DOH complex inheritance test</title>
+
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../dojo/dojo.js"
+			data-dojo-config="isDebug: 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");
+			dojo.require("dijit.layout.TabContainer");
+			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+			dojo.require("dijit.form.FilteringSelect");
+			dojo.require("dijit.form.SimpleTextarea");
+			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();
+				});
+
+				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);
+						}
+					},
+					{
+						name: "check input field text direction",
+
+						runTest: function(){
+							var textBox = dijit.byId("simpleTextbox");
+
+							doh.is("rtl", textBox.textDir,textBox.id);
+						}
+					}
+				]);
+
+				doh.register("test 'BorderContainer Pane'", [
+					{
+						name: "textDir of the panes",
+
+						runTest: function(){
+							var bContainer = dijit.byId("borderContainerPane"),
+								cPane1 = dijit.byId("contentPane1"),
+								cPane2 = dijit.byId("contentPane2");
+
+							doh.is("auto",bContainer.textDir,"'borderContainerPane' textDir");
+							doh.is("ltr",cPane1.textDir,"'contentPane1' textDir");
+							doh.is("auto",cPane2.textDir,"'contentPane2' textDir");
+
+						}
+					},	
+					{
+						name: "textDir of textBoxes in the 'contentPane1' textDir='ltr'",
+
+						runTest: function(){
+							var select = dijit.byId("selectL"),
+								input1 = dijit.byId("inputLHeb"),
+								input2 = dijit.byId("inputLEn");
+
+							doh.is("ltr",select.textDir,"'selectL' textDir");
+							doh.is("ltr",input1.textDir,"'inputLHeb' textDir");
+							doh.is("ltr",input2.textDir,"'inputLEn' textDir");
+						}
+					},	
+					{
+						name: "textDir of textBoxes in the 'contentPane2' textDir='auto'",
+
+						runTest: function(){
+							var selectA = dijit.byId("selectA"),
+								input1 = dijit.byId("inputAHeb"),
+								input2 = dijit.byId("inputAEn");
+
+							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'", [
+					{
+						name: "textDir of the panes",
+
+						runTest: function(){
+							doh.is("auto",dijit.byId("embeddedLayoutPane").textDir,"'embeddedLayoutPane' textDir");
+							doh.is("ltr",dijit.byId("bContainer").textDir,"'bContainer' textDir");
+							doh.is("ltr",dijit.byId("contentPane3").textDir,"'contentPane3' textDir");
+							doh.is("auto",dijit.byId("contentPane4").textDir,"'contentPane4' textDir");
+							doh.is("auto",dijit.byId("tContainer").textDir,"'tContainer' textDir");
+							doh.is("rtl",dijit.byId("contentPane5").textDir,"'contentPane5' textDir");
+							doh.is("auto",dijit.byId("contentPane6").textDir,"'contentPane6' textDir");
+						}
+					},	
+					{
+						name: "textDir of textBoxes",
+
+						runTest: function(){
+							doh.is("ltr",dijit.byId("ltrSimpleTexarea").textDir,"'ltrSimpleTexarea' textDir");
+							doh.is("ltr",dijit.byId("ltrSimpleTexarea").focusNode.dir,"'ltrSimpleTexarea' dir");
+
+							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();			
+			});
+		</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",
+							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">
+					<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:"שלום!"'/>
+				</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"'>
+						<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">
+							<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:"שלום!"'/> 
+						</p>
+						<p>
+							<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"'>
+						<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">
+							<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:"שלום!"'/> 
+						</p>
+						<p>
+							<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",
+				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"'>
+							Left Pane:
+							<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"'>
+							Right Pane:
+							<textarea id="autoSimpleTexarea" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"autoSimpleTexarea", rows:"8", cols:"13"
+								'> לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית מוסן מנת.
+							</textarea>
+						</div>
+					</div>
+				</div>
+				<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", 
+							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"
+							'>מבחן.</textarea>
+						<textarea id="texarea2" data-dojo-type="dijit.form.Textarea" data-dojo-props='name:"texarea2", rows:"4", cols:"14"
+							'>Test.</textarea>
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/inheritance/Inher-MarkupContainers.html b/dijit/tests/_BidiSupport/inheritance/Inher-MarkupContainers.html
new file mode 100644
index 0000000..38aa84b
--- /dev/null
+++ b/dijit/tests/_BidiSupport/inheritance/Inher-MarkupContainers.html
@@ -0,0 +1,158 @@
+<!DOCTYPE html>
+
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">	
+		<title>DOH markup containers simple inheritance</title>
+
+		<style type="text/css">
+			@import "../../../../dijit/themes/tundra/tundra.css";
+			@import "../../../../dojo/resources/dojo.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../dojo/dojo.js"
+			data-dojo-config="isDebug: 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");
+			dojo.require("dijit.layout.ContentPane");
+			dojo.require("dijit.layout.BorderContainer");
+			dojo.require("dijit.layout.TabContainer");
+			dojo.require("dijit.form.FilteringSelect");
+			dojo.require("dijit.form.Textarea");
+			dojo.require("doh.runner");
+
+			dojo.ready(function(){
+
+				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"); 
+					},
+					function test_rtlFilterSelectInheritAccordion(){
+						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!!"); 
+					},
+					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"); 
+					},
+					function test_autoComboBoxInheritTableLtr(){
+						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"); 
+					},
+					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"); 
+					},
+					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"); 
+					},
+					function test_autoSimpleTextareaInheritPane1(){
+						doh.is("ltr", dijit.byId("ltrSimpleTexarea").focusNode.dir, "ltrSimpleTexarea: ltrSimpleTexarea"); 
+					},
+					function test_autoSimpleTextareaInheritPane2(){
+						doh.is("rtl", dijit.byId("autoSimpleTexarea").focusNode.dir, "autoSimpleTexarea: autoSimpleTexarea"); 
+					},
+					function test_RtrSimpleTexBoxInheritTabContainer(){
+						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!!"); 
+					},
+					function test_autoSimpleTexBoxInheritTabContainersPaneRtl(){
+						doh.is("rtl", dijit.byId("ltrTexarea").focusNode.dir, "ltrTexarea"); 
+					},
+					function test_autoSimpleTexBoxInheritTabContainersPaneRtl(){
+						doh.is("ltr", dijit.byId("trTexarea").focusNode.dir, "trTexarea"); 
+					}
+				]);
+
+				doh.run();
+			});
+		</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>
+			
+				<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:""'/>
+			</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">
+					<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"'>
+				<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"'>
+						Left Pane:
+						<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"'>
+						Right Pane:
+						<textarea id="autoSimpleTexarea" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"autoSimpleTexarea", rows:"8", cols:"13"
+							'> לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית מוסן מנת.
+						</textarea>
+					</div>
+				</div>
+				<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"
+							'>לורם איפסום.
+						</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"
+							'>מבחן.
+						</textarea>
+						<textarea id="trTexarea" data-dojo-type="dijit.form.Textarea" data-dojo-props='name:"trTexarea", rows:"4", cols:"14"
+							'>Test.
+						</textarea>
+					</div>
+				</div>
+				<p>
+					Text after the widgets.
+				</p>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/inheritance/Inher-Simple.html b/dijit/tests/_BidiSupport/inheritance/Inher-Simple.html
new file mode 100644
index 0000000..f415b8a
--- /dev/null
+++ b/dijit/tests/_BidiSupport/inheritance/Inher-Simple.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">	
+		<title>DOH simple inheritance textDir Tests</title>
+
+		<style type="text/css">
+			@import "../../../../dijit/themes/tundra/tundra.css";
+			@import "../../../../dojo/resources/dojo.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../dojo/dojo.js"
+			data-dojo-config="isDebug: 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");
+
+			dojo.ready(function(){
+
+				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"); 
+					},
+					function test_rtlTextBoxInheritBody(){
+						doh.is("rtl", dijit.byId("rtlTextBox").focusNode.dir, "rtlTextBox"); 
+					},
+					function test_ltrComboBoxInheritTable(){
+						doh.is("ltr", dijit.byId("fruitLtr").focusNode.dir, "fruitLtr"); 
+					},
+					function test_rtlComboBoxInheritTable(){
+						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!!"); 
+					},
+					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.run();
+			});
+		</script>
+	</head>
+	<body class="tundra" data-dojo-textdir="rtl">
+		<table data-dojo-textdir="auto">
+			<tr>
+				<td>
+					<div data-dojo-textdir="ltr">
+						<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"'/>
+					</div>
+				</td>
+			</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"'/>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<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>
+				<td>
+					<select id="fruitRtl" data-dojo-type="dijit.form.ComboBox" data-dojo-props='name:"fruitRtr"'>
+						<option >תפוחים.</option>
+						<option >אגסים.</option>
+						<option selected>אפרסקים.</option>
+					</select>
+				</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"'/>
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/inheritance/module.js b/dijit/tests/_BidiSupport/inheritance/module.js
new file mode 100644
index 0000000..d1907d4
--- /dev/null
+++ b/dijit/tests/_BidiSupport/inheritance/module.js
@@ -0,0 +1,15 @@
+dojo.provide("dijit.tests._BidiSupport.inheritance.module");
+
+try{
+
+	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.registerUrl("dijit.tests._BidiSupport.inheritance.Inher-ComplexMarkupContainers", dojo.moduleUrl("dijit", "tests/_BidiSupport/inheritance/Inher-ComplexMarkupContainers.html"));
+
+}catch(e){
+
+	doh.debug(e);
+
+}
diff --git a/dijit/tests/_BidiSupport/inheritance/runTests.html b/dijit/tests/_BidiSupport/inheritance/runTests.html
new file mode 100644
index 0000000..fb7125e
--- /dev/null
+++ b/dijit/tests/_BidiSupport/inheritance/runTests.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+
+<html>
+	<head>
+		<title>Inheritance Unit Test Runner</title>
+		<meta http-equiv="REFRESH" content="0;url=../../../../util/doh/runner.html?testModule=dijit.tests._BidiSupport.inheritance.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
new file mode 100644
index 0000000..5de408c
--- /dev/null
+++ b/dijit/tests/_BidiSupport/module.js
@@ -0,0 +1,21 @@
+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);
+
+}
diff --git a/dijit/tests/_BidiSupport/runTests.html b/dijit/tests/_BidiSupport/runTests.html
new file mode 100644
index 0000000..e31d9e5
--- /dev/null
+++ b/dijit/tests/_BidiSupport/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.module">
+	</head>
+	<body>
+			Redirecting to D.O.H runner.
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/tree/ProgrammaticTree.html b/dijit/tests/_BidiSupport/tree/ProgrammaticTree.html
new file mode 100644
index 0000000..499ef3b
--- /dev/null
+++ b/dijit/tests/_BidiSupport/tree/ProgrammaticTree.html
@@ -0,0 +1,292 @@
+<!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>	
+
+		<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() {
+                var store = new dojo.data.ItemFileReadStore({
+                    url: "../../../../dijit/tests/_BidiSupport/_data/countriesHeb.json"
+                });
+
+                var treeModel = new dijit.tree.ForestStoreModel({
+                   store: store,
+                    query: {
+                        "type": "continent"
+                    },
+                    rootId: "root",
+                    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();
+				});
+
+				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>
+    </head>
+    
+    <body class=" claro ">
+		<table>
+			<tr><td>
+					<label for="treeLtr" >
+						<b>  I'm a LTR Tree   </b>
+					</label>
+					<div id="treeLtr"></div>
+				</td>
+				<td>
+					<label for="treeRtl" >
+						<b>  I'm a RTL Tree   </b>
+					</label>
+					<div id="treeRtl"></td>
+				</td>
+				<td>
+					<label for="treeAuto" >
+						<b>  I'm a Contextual Tree   </b>
+					</label>
+					<div id="treeAuto"></td>
+				</td>
+			</tr>
+		</table>
+		<input id="buttonRtl" type="button" value="RTL"
+			onclick="dijit.byId('treeLtr').set('textDir','rtl');
+				dijit.byId('treeRtl').set('textDir','rtl');
+				dijit.byId('treeAuto').set('textDir','rtl');"
+		/>
+		<input id="buttonLtr" type="button" value="LTR"
+			onclick="dijit.byId('treeLtr').set('textDir','ltr');
+				dijit.byId('treeRtl').set('textDir','ltr');
+				dijit.byId('treeAuto').set('textDir','ltr');"
+		/>
+		<input id="buttonAuto" type="button" value="AUTO"
+			onclick="dijit.byId('treeLtr').set('textDir','auto');
+				dijit.byId('treeRtl').set('textDir','auto');
+				dijit.byId('treeAuto').set('textDir','auto');"
+		/>		
+
+ 
+    </body>
+
+</html>
diff --git a/dijit/tests/_BidiSupport/tree/SimpleTree.html b/dijit/tests/_BidiSupport/tree/SimpleTree.html
new file mode 100644
index 0000000..edad3fe
--- /dev/null
+++ b/dijit/tests/_BidiSupport/tree/SimpleTree.html
@@ -0,0 +1,270 @@
+<!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
new file mode 100644
index 0000000..1d3de73
--- /dev/null
+++ b/dijit/tests/_BidiSupport/tree/TreeRootlessCustomIcons.html
@@ -0,0 +1,267 @@
+<!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
new file mode 100644
index 0000000..8370f21
--- /dev/null
+++ b/dijit/tests/_BidiSupport/tree/module.js
@@ -0,0 +1,15 @@
+dojo.provide("dijit.tests._BidiSupport.tree.module");
+
+try{
+
+	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/tree/runTests.html b/dijit/tests/_BidiSupport/tree/runTests.html
new file mode 100644
index 0000000..4013e3e
--- /dev/null
+++ b/dijit/tests/_BidiSupport/tree/runTests.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+
+<html>
+	<head>
+		<title>Dijit Unit Test Runner</title>
+		<meta http-equiv="REFRESH" content="0;url=../../../../util/doh/runner.html?testModule=dijit.tests._BidiSupport.tree.module"></head>
+	<body>
+		Redirecting to D.O.H runner.
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/widgets/Tooltip.html b/dijit/tests/_BidiSupport/widgets/Tooltip.html
new file mode 100644
index 0000000..3ed4ddb
--- /dev/null
+++ b/dijit/tests/_BidiSupport/widgets/Tooltip.html
@@ -0,0 +1,305 @@
+<!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
new file mode 100644
index 0000000..5977ffa
--- /dev/null
+++ b/dijit/tests/_BidiSupport/widgets/module.js
@@ -0,0 +1,11 @@
+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
new file mode 100644
index 0000000..0326313
--- /dev/null
+++ b/dijit/tests/_BidiSupport/widgets/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.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 2a3d5e6..418cb65 100644
--- a/dijit/tests/_Container.html
+++ b/dijit/tests/_Container.html
@@ -15,7 +15,7 @@
 
 		dojo.require("dojo.parser");
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			dojo.declare("dijit.TestContainer",
 				[dijit._Widget, dijit._Container], { }
 			);
@@ -92,6 +92,39 @@
 							t.is("one", children[0].id);
 							t.is("three", children[1].id);
 						}
+					},
+					{
+						name: "addChild",
+						runTest: function(t){
+							var c = dijit.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 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 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");
+						}
 					}
 				]
 			);
@@ -104,6 +137,7 @@
 <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>
diff --git a/dijit/tests/_Templated-widgetsInTemplate.html b/dijit/tests/_Templated-widgetsInTemplate.html
deleted file mode 100644
index 613b758..0000000
--- a/dijit/tests/_Templated-widgetsInTemplate.html
+++ /dev/null
@@ -1,499 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
-		<title>testing widgetsInTemplate support</title>
-
-		<style type="text/css">
-			@import "../themes/claro/document.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">
-			dojo.require("doh.runner");
-
-			dojo.require("dojo.parser");
-
-			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.addOnLoad(function(){
-				dojo.declare('Test1Widget',
-					[dijit._Widget, dijit._Templated],
-				{
-					widgetsInTemplate: true,
-	
-					templateString: dojo.byId('Test1Template').value,
-					onClick: function(e){
-						if(e.target){
-							alert('onClick widgetId='+e.target.id);
-						}else{
-							if(e._counter == undefined){
-								e._counter = 1;
-							}else{
-								e._counter++;
-							}
-						}
-					}
-				});
-
-				dojo.declare('Test3Widget',
-					[dijit._Widget, dijit._Templated],
-				{
-					widgetsInTemplate: true,
-	
-					templateString: dojo.byId('Test3Template').value
-				});
-
-				dojo.declare('Test4Widget',
-					[dijit._Widget, dijit._Templated],
-				{
-					widgetsInTemplate: true,
-		
-					templateString: dojo.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;
-					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
-					doh.t(testW._started, "testW._started");
-					doh.t(testW.tabCont._started, "tabCont._started");
-					doh.t(testW.tab1._started, "tab1._started");
-					doh.t(testW.tab2._started, "tab2._started");
-				}
-			
-				dojo.declare('TestLayoutWidget', dijit.layout._LayoutWidget, {
-					startup: function(){
-						if(this._started){
-							this._doubleStarted = true;
-						}
-						this.inherited(arguments);
-					},
-					destroy: function(){
-						if(this._destroyed){
-							this._doubleDestroyed = true;
-						}
-						this.inherited(arguments);
-						this._destroyed = true;
-					}
-				});
-				dojo.declare('TestCtnrWidget', [dijit._Widget, dijit._Container], {
-					startup: function(){
-						if(this._started){
-							this._doubleStarted = true;
-						}
-						this.inherited(arguments);
-					},
-					destroy: function(){
-						if(this._destroyed){
-							this._doubleDestroyed = true;
-						}
-						this.inherited(arguments);
-						this._destroyed = true;
-					}
-				});
-				dojo.declare('TestCtndWidget', [dijit._Widget, dijit._Contained], {
-					startup: function(){
-						if(this._started){
-							this._doubleStarted = true;
-						}
-						this.inherited(arguments);
-					},
-					destroy: function(){
-						if(this._destroyed){
-							this._doubleDestroyed = true;
-						}
-						this.inherited(arguments);
-						this._destroyed = true;
-					}
-				});
-				dojo.declare('TestNonCtnrWidget', [dijit._Widget, dijit._Templated], {
-					templateString: "<div data-dojo-attach-point=containerNode></div>",
-					startup: function(){
-						if(this._started){
-							this._doubleStarted = true;
-						}
-						this.inherited(arguments);
-					},
-					destroy: function(){
-						if(this._destroyed){
-							this._doubleDestroyed = true;
-						}
-						this.inherited(arguments);
-						this._destroyed = true;
-					}
-				});
-				dojo.declare('TestStubWidget', dijit._Widget, {
-					startup: function(){
-						if(this._started){
-							this._doubleStarted = true;
-						}
-						this.inherited(arguments);
-					},
-					destroy: function(){
-						if(this._destroyed){
-							this._doubleDestroyed = true;
-						}
-						this.inherited(arguments);
-						this._destroyed = true;
-					}
-				});
-	
-				dojo.declare('Test5Widget',
-					[dijit._Widget, dijit._Templated],
-				{
-					widgetsInTemplate: true,
-		
-					templateString: dojo.byId('Test5Template').value,
-					startup: function(){
-						if(this._started){
-							this._doubleStarted = true;
-						}
-						this.inherited(arguments);
-					},
-					destroy: function(){
-						if(this._destroyed){
-							this._doubleDestroyed = true;
-						}
-						this.inherited(arguments);
-						this._destroyed = true;
-					}
-				});
-	
-				dojo.declare("Missing", [dijit._Widget, dijit._Templated], {
-					templateString: '<div>' +
-										'<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>',
-					widgetsInTemplate: true
-				});
-
-				function getTestWidgets(testW){
-					return [
-						testW,
-						testW.layout,
-						testW.layChild1,
-						testW.layChild2,
-						testW.container,
-						testW.contained1,
-						testW.contained2,
-						testW.nonContainer,
-						testW.nonContained1,
-						testW.nonContained2,
-						testW.threeLevel,
-						testW.secondLevel,
-						testW.bottomLevel,
-						testW.anotherThree,
-						testW.anotherSecond,
-						testW.anotherBottom,
-						testW.stub1
-					];
-				}
-		
-				function validateTest5Widget(t, testW) {
-					// Check that everything got started, but not double-started
-					dojo.forEach(getTestWidgets(testW), function(w){
-						doh.t(w._started, "w._started: " + w);
-						doh.is(undefined, w._doubleStarted, "w._doubleStarted: " + w);
-					});
-				}
-		
-				function validateTest5WidgetDestroy(t, testW) {
-					var savedWidgets = getTestWidgets(testW);
-					testW.destroy();
-					dojo.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("_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");
-							}
-						},
-						{
-							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");
-							}
-						},
-						{
-							// 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");
-
-/*** 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 desc = testW.getChildren();
-								doh.is(5, desc.length, "number of direct descendants");
-								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.4");
-								doh.is(desc[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;
-										}
-									}
-									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 dojoAttachPoint 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, "dojoAttachPoint 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");
-							}
-						}
-					]
-				);
-
-				// 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._Widget, dijit._Templated], {
-						widgetsInTemplate: true,
-						obj: {hello: "world"},
-						templateString:
-							"<div>" +
-								"<div data-dojo-type='dijit._Widget' data-dojo-props='hostObj: this.obj'" +
-								" data-dojo-attach-point='subWidget'></div>" +
-							"</div>"
-					});
-					
-					var hostWidget = new host(),
-						subWidget = hostWidget && hostWidget.subWidget;
-					doh.isNot(undefined, hostWidget, "created host widget");
-					doh.isNot(undefined, subWidget, "created sub widget");
-					doh.isNot(undefined, subWidget.hostObj, "sub widget got hostObj defined");
-					doh.is("world", subWidget.hostObj.hello, "object is correct")
-				});
-
-				doh.run();
-			});
-		</script>
-	</head>
-	<body class="claro">
-		<h1>testing widgetsInTemplate support</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>
-			</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>
-		</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>
-		</textarea>
-
-		<div data-dojo-type="Test5Widget" data-dojo-props="id: 'test5Widget'"></div>
-
-		<div data-dojo-type="Missing" data-dojo-props="id: 'missing'"></div>
-	</body>
-</html>
diff --git a/dijit/tests/_Templated-widgetsInTemplate1.x.html b/dijit/tests/_Templated-widgetsInTemplate1.x.html
index 59c9571..1a7f7f9 100644
--- a/dijit/tests/_Templated-widgetsInTemplate1.x.html
+++ b/dijit/tests/_Templated-widgetsInTemplate1.x.html
@@ -12,6 +12,8 @@
 
 			dojo.require("dojo.parser");
 
+			dojo.require("dijit._Widget");
+			dojo.require("dijit._Templated");
 			dojo.require("dijit.form.Button");
 			dojo.require("dijit.form.CheckBox");
 			dojo.require("dijit.ProgressBar");
@@ -20,8 +22,9 @@
 			dojo.require("dijit._Container");
 			dojo.require("dijit._Contained");
 			dojo.require("dijit.layout._LayoutWidget");
+			dojo.require("dijit.focus");	// dijit.focus()
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				var testW;
 
 				dojo.declare('Test1Widget',
@@ -59,7 +62,7 @@
 					templateString: dojo.byId('Test4Template').textContent || dojo.byId('Test4Template').innerText
 				});
 		
-				function validateTest4Widget(t, testW) {
+				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;
@@ -193,7 +196,7 @@
 					];
 				}
 		
-				function validateTest5Widget(t, testW) {
+				function validateTest5Widget(t, testW){
 					// Check that everything got started, but not double-started
 					dojo.forEach(getTestWidgets(testW), function(w){
 						t.t(w._started, "w._started: " + w);
@@ -201,7 +204,7 @@
 					});
 				}
 		
-				function validateTest5WidgetDestroy(t, testW) {
+				function validateTest5WidgetDestroy(t, testW){
 					var savedWidgets = getTestWidgets(testW);
 					testW.destroy();
 					dojo.forEach(savedWidgets, function(w, idx){
@@ -276,13 +279,13 @@
 									testW.getDescendants();
 								console.log("*** time for getDescendants(false): " + (new Date()-start));
 ***/
-								var desc = testW.getChildren();
-								t.is(5, desc.length, "number of direct descendants");
-								t.is(desc[0].id, "3.1");
-								t.is(desc[1].id, "3.2");
-								t.is(desc[2].id, "3.3");
-								t.is(desc[3].id, "3.4");
-								t.is(desc[4].id, "3.5");
+								var chil = testW.getChildren();
+								t.is(5, chil.length, "number of direct descendants");
+								t.is(chil[0].id, "3.1");
+								t.is(chil[1].id, "3.2");
+								t.is(chil[2].id, "3.3");
+								t.is(chil[3].id, "3.4");
+								t.is(chil[4].id, "3.5");
 
 								var desc = testW.getDescendants();
 								t.is(7, desc.length, "number of descendants (including nested ones)");
@@ -370,7 +373,7 @@
 								var testW = dijit.byId("missing");
 								doh.t(testW, "widget was created");
 								doh.t(testW.missingButton, "dojoAttachPoint created");
-								doh.is("dijit.form.Button", testW.missingButton.declaredClass, "and it's to a widget")
+								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");
 							}
 						}
diff --git a/dijit/tests/_Templated.html b/dijit/tests/_Templated.html
deleted file mode 100644
index 4989674..0000000
--- a/dijit/tests/_Templated.html
+++ /dev/null
@@ -1,229 +0,0 @@
-<!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"
-			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._Templated");
-
-			dojo.require("dijit.layout.LayoutContainer");
-
-			function getOuterHTML(/*DomNode*/ node){
-				var wrapper = dojo.doc.createElement("div");
-				wrapper.appendChild(node);
-				return wrapper.innerHTML.toLowerCase();		// IE prints <BUTTON> rather than <button>; normalize it.
-			}
-
-			dojo.addOnLoad(function(){
-				// Template with no variables (should be cached as a DOM tree)
-				dojo.declare("SimpleTemplate", [dijit._Widget, dijit._Templated], {
-					attributeMap: {},
-					id: "test1",
-					templateString: "<button type='button'><span>hello < world</span></button>"
-				});
-
-				// Template with variables
-				dojo.declare("VariableTemplate", [dijit._Widget, dijit._Templated], {
-					attributeMap: {},
-					id: "test2",
-					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._Templated], {
-					attributeMap: {},
-					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._Templated], {
-					attributeMap: {},
-					id: "test3",
-					text: "bar",
-					templateString: "<tr><td>${text}</td></tr>"
-				});
-
-				// Illegal substitution variable name
-				dojo.declare("IllegalSubstitution", [dijit._Widget, dijit._Templated], {
-					templateString: "<tr><td>${fake}</td></tr>"
-				});
-
-				// dojoAttachPoint
-				dojo.declare("AttachPoint", [dijit._Widget, dijit._Templated], {
-					attributeMap: {foo: "", style: "", bar: "buttonNode"},
-					templateString: "<div style='border: 1px solid red'>" +
-										"<button dojoAttachPoint='buttonNode,focusNode'>hi</button>" +
-										'<span><input dojoAttachPoint="inputNode" value="input"/></span>' +
-										"<span dojoAttachPoint='containerNode'></span>" +
-									"</div>"
-				});
-
-				// dojoAttachEvent
-				dojo.declare("AttachEvent", [dijit._Widget, dijit._Templated], {
-					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' dojoAttachPoint='left' dojoAttachEvent='onclick: click, onfocus'>left</button></td>" +
-										"<td><button type='button' dojoAttachPoint='right' dojoAttachEvent='onclick: click, onfocus: focus2'>right</button></td>" +
-									"</tr></table>"
-				});
-
-				var testW;
-
-				doh.register("parse", function(){
-					dojo.parser.parse();
-				});
-
-				doh.register("dijit.tests._Templated.html",
-					[
-						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"?/, ""));
-						},
-
-						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");
-						},
-
-						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");
-						},
-						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;
-						},
-
-						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._Templated], {
-								widgetsInTemplate:true,
-								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());
-							});
-
-						}
-					]
-				);
-				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>
-	</body>
-</html>
diff --git a/dijit/tests/_TemplatedMixin.html b/dijit/tests/_TemplatedMixin.html
new file mode 100644
index 0000000..d44bcb0
--- /dev/null
+++ b/dijit/tests/_TemplatedMixin.html
@@ -0,0 +1,230 @@
+<!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"
+			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");
+
+			function getOuterHTML(/*DomNode*/ node){
+				var wrapper = dojo.doc.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"?/, ""));
+						},
+
+						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");
+						},
+
+						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");
+						},
+						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;
+						},
+
+						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());
+							});
+
+						}
+					]
+				);
+				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>
+	</body>
+</html>
diff --git a/dijit/tests/_Widget-attr.html b/dijit/tests/_Widget-attr.html
index ec9435d..0b86518 100644
--- a/dijit/tests/_Widget-attr.html
+++ b/dijit/tests/_Widget-attr.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 <head>
-	<title>Widget.get()/set() unit test</title>
+	<title>widget.get()/set() unit test</title>
 	<style type="text/css">
 		@import "../themes/claro/document.css";
 		@import "css/dijitTests.css";
@@ -13,140 +13,187 @@
 
 	<script type="text/javascript">
 		dojo.require("doh.runner");
-		dojo.require("dojo.parser");
-		dojo.require("dijit.dijit");
-
-		dojo.addOnLoad(function(){
-			dojo.declare("Baz",
-				[ dijit._Widget, dijit._Templated ],
-				{
-					templateString: "<div><div dojoAttachPoint='nameNode'></div><span>${attr1}</span></div>",
-	
-					attributeMap: {
-						name: {node: "nameNode", type: "innerHTML" }
-					},
-	
-					name: "howdy!",
+
+		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"},
 	
-					attr1: 0,
-					_setAttr1Attr: function(value){
-						this.domNode.lastChild.innerHTML = value;
-						this.attr1 = value;
+							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");
 					},
-	
-					attr2: 0,
-					_getAttr2Attr: function(){
-					}
-				}
-			);
-			dojo.declare("Textbox",
-				[ dijit._Widget, dijit._Templated ],
-				{
-					attributeMap: {id:"", dir:"", lang:"", "class":"", style:"", title:"", disabled: "", readonly: ""},
-					templateString: "<input>"
-				}
-			);
-	
-			dojo.declare("Thud", Baz, {
-				get: function(name){
-					// default getter
-				},
-				set: function(name, value){
-					// default setter
-				}
-			});
-	
-			dojo.declare("AttrMap", [dijit._Widget, dijit._Templated], {
-				attributeMap: {foo: "", bar: "buttonNode", plainText: {node: "plainTextNode", type: "innerText"}},
-				templateString: "<div class='class1' style='border: 1px solid red; width: 456px'>" +
-									"<button dojoAttachPoint='buttonNode,focusNode'>hi</button>" +
-									'<span><input dojoAttachPoint="inputNode" value="input"></span>' +
-									"<span dojoAttachPoint='containerNode'></span>" +
-									"<span dojoAttachPoint='plainTextNode'>original plain text</span>" +
-								"</div>"
-			});
-
-			doh.register("parse", function(){
-				dojo.parser.parse();
-			});
-
-			doh.register("_Widget.attr",
-				[
-					function attr(){
-						var b = new Baz();
 
-						// widget attribute mapped to DOM node innerHTML
-						dojo.body().appendChild(b.domNode);
-						doh.is("howdy!", b.attr("name"));
-						doh.is("howdy!", b.nameNode.innerHTML);
-						b.attr("name", "thinger");
-						doh.is(b.attr("name"), "thinger");
-						doh.is(b.nameNode.innerHTML, "thinger");
+					// 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");
 
-						// hash setting
-						b.attr({
-							name: "bang",
-							foo: "zap"
+						// 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("bang", b.attr("name"));
-						doh.is("zap", b.attr("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");
+						}
 					},
-					function setGet(){
-						var b = new Baz();
 
-						// widget attribute mapped to DOM node innerHTML
-						dojo.body().appendChild(b.domNode);
-						doh.is("howdy!", b.get("name"));
-						doh.is("howdy!", b.nameNode.innerHTML);
-						b.set("name", "thinger");
-						doh.is(b.get("name"), "thinger");
-						doh.is(b.nameNode.innerHTML, "thinger");
+					// 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; }
+						});
 
-						// hash setting
-						b.set({
-							name: "bang",
-							foo: "zap"
+						var widget = new CustomSetters({
+							foo: 100
 						});
-						doh.is("bang", b.get("name"));
-						doh.is("zap", b.get("foo"));
+
+						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");
 					},
 
-					function domSetGet(){
-						// test setting widget attributes corresponding to DOM node attributes
-						var t = new Textbox();
-						doh.assertFalse(t.get("disabled"));
-						t.set("disabled", true);
-						doh.assertTrue(dojo.attr(t.domNode, "disabled"));
-						doh.assertTrue(t.get("disabled"));
+					// 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);
 					},
 
-					function domInnerHTML(){
-						// test initializing widget attributes corresponding to DOM node innerHTML
-						var b2 = new Baz({
-							foo: "blah",
-							name: "whatever"
+					// 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"}
 						});
-						doh.is("whatever", b2.get("name"));
-						doh.is("whatever", b2.nameNode.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 <>&;"
-						});
-						var wrapper = dojo.byId("attributeMapWrapper");
-						wrapper.appendChild(widget.domNode);
-						doh.is("value1", widget.domNode.getAttribute("foo"));
-						doh.is("value2", widget.buttonNode.getAttribute("bar"));
-						doh.assertTrue(dojo.hasClass(widget.domNode, "class1"));
-						doh.assertTrue(dojo.hasClass(widget.domNode, "class2"));
-						doh.is("123px", dojo.style(widget.domNode).height);
-						doh.is("456px", dojo.style(widget.domNode).width);
-						doh.is("hello world <>&;", widget.plainTextNode.innerHTML);
+						}).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");
 					}
+
 				]
 			);
 
@@ -156,7 +203,7 @@
 	</script>
 </head>
 <body>
-	<h1>Dijit Widget.get()/set() Unit Test</h1>
-	<div id="attributeMapWrapper"></div>
+	<h1>Dijit widget.get()/set() Unit Test</h1>
+	<div id="wrapper"></div>
 </body>
 </html>
diff --git a/dijit/tests/_Widget-connect-performance.html b/dijit/tests/_Widget-connect-performance.html
index 699e079..6670ccc 100644
--- a/dijit/tests/_Widget-connect-performance.html
+++ b/dijit/tests/_Widget-connect-performance.html
@@ -12,7 +12,7 @@
 		dojo.require("dijit._Widget");
 		dojo.require("dojo.parser");
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			dojo.declare("dijit.MyWidget", dijit._Widget, {
 				_eventHandler: function(){}
 			});
diff --git a/dijit/tests/_Widget-deferredConnect.html b/dijit/tests/_Widget-deferredConnect.html
index 7722e91..82864f6 100644
--- a/dijit/tests/_Widget-deferredConnect.html
+++ b/dijit/tests/_Widget-deferredConnect.html
@@ -12,6 +12,7 @@
 	<script type="text/javascript" src="../../dojo/dojo.js"
 		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	<script>
+		dojo.require("dojo.parser");
 		dojo.require("dijit.form.Button");
 
 		overrodeMouseMoved = false;
@@ -26,7 +27,7 @@
 			bothOverrodeMouseMoved = true;
 		}
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			dojo.connect(dijit.byId("connect"), "onMouseMove", function(){
 				if(!connectedMouseMoved){
 					console.log("'connect' button: mouse moved");
@@ -48,7 +49,7 @@
 	<h1>Test deferred connections</h1>
 	<p>
 		OnMouseMove is a deferred connection, _Widget only call dojo.connect()
-		(dojoAttachEvent) to connect the onmousemove event on the focusNode to
+		(data-dojo-attach-event) to connect the onmousemove event on the focusNode to
 		the widget method if needed.
 	</p>
 	<p>
diff --git a/dijit/tests/_Widget-lifecycle.html b/dijit/tests/_Widget-lifecycle.html
index c70e776..f9b3c91 100644
--- a/dijit/tests/_Widget-lifecycle.html
+++ b/dijit/tests/_Widget-lifecycle.html
@@ -10,7 +10,7 @@
 		dojo.require("doh.runner");
 		dojo.require("dijit._Widget");
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			var obj = {
 				foo: function(){
 					// summary: empty function that we connect to
diff --git a/dijit/tests/_Widget-on.html b/dijit/tests/_Widget-on.html
new file mode 100644
index 0000000..1cc342d
--- /dev/null
+++ b/dijit/tests/_Widget-on.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>_Widget on() 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>
+		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");
+
+
+		dojo.ready(function(){
+			var mousedOver, clicked;
+
+			doh.register("on", [
+				function setup(){
+					dojo.declare("MyWidget", [dijit._Widget], {
+						postCreate: function(){
+							dojo.on(this.domNode, "click", dojo.hitch(this, "onFooBar"));
+						},
+						onFooBar: function(){
+							// This is called whenever the widget is clicked
+						},
+						foobar: function(){
+							// A widget.on("foobar") should go to onFooBar() (above), not here
+						}
+					});
+
+					dojo.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(){
+						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(){
+						clicked = true;
+						console.log("click event");
+					});
+				},
+
+				function test(){
+					var myWidget = dijit.registry.byId("myWidget");
+
+					// Test that _Widget.on() catches click event
+					doh.f(clicked, "clicked");
+					dojo.on.emit(myWidget.domNode, "click", {
+						bubbles: true,
+						cancelable: true,
+						which: 1
+					});
+					doh.t(clicked, "clicked");
+
+					// Test that _Widget.on() catches mouseover event
+					doh.f(mousedOver, "mousedOver");
+					dojo.on.emit(myWidget.domNode, "mouseover", {
+						bubbles: true,
+						cancelable: true,
+						which: 1
+					});
+					doh.t(mousedOver, "mousedOver");
+				}
+			]);
+
+			doh.run();
+		});
+
+	</script>
+</head>
+<body class="claro">
+	<div id="myWidget" data-dojo-type="MyWidget">
+		mouseover and click events to console
+	</div>
+</body>
+</html>
diff --git a/dijit/tests/_Widget-ondijitclick.html b/dijit/tests/_Widget-ondijitclick.html
index e3ad564..fb611cd 100644
--- a/dijit/tests/_Widget-ondijitclick.html
+++ b/dijit/tests/_Widget-ondijitclick.html
@@ -11,18 +11,18 @@
 		dojo.require("dijit._Widget");
 		dojo.require("dojo.parser");
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			dojo.declare("dijit.WidgetWithOndijitclick",
 				dijit._Widget,
 				{
 					clickCount: 0,
 					onClick: function(){
 					},
-					_onClick: function() {
-						console.log(this.id + ": ondijitclick");
+					_onClick: function(){
+						this.clickCount++;
 						this.onClick();
 					},
-					postCreate: function() {
+					postCreate: function(){
 						this.connect(this.domNode, "ondijitclick", "_onClick");
 					}
 				}
@@ -64,7 +64,7 @@
 	<textarea id="textarea">hello world</textarea>
 
 	<br>
-	<button id="button2" style="margin-top: 2em;" type="button"
+	<button id="plainbutton2" style="margin-top: 2em;" type="button"
 			onClick="dojo.byId('third').focus();">
 		click me using space or enter, to focus ondijitclick widget below
 	</button>
@@ -78,5 +78,10 @@
 			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 w/ondijitclick
+	</button>
 </body>
 </html>
diff --git a/dijit/tests/_Widget-placeAt.html b/dijit/tests/_Widget-placeAt.html
index a03feba..e179155 100644
--- a/dijit/tests/_Widget-placeAt.html
+++ b/dijit/tests/_Widget-placeAt.html
@@ -31,7 +31,7 @@
 		dojo.require("dijit.layout.BorderContainer");
 
 		// run all the tests onload
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 
 			var pane1, pane2, tc;
 
diff --git a/dijit/tests/_Widget-subscribe.html b/dijit/tests/_Widget-subscribe.html
index 1d1ac5f..2996275 100644
--- a/dijit/tests/_Widget-subscribe.html
+++ b/dijit/tests/_Widget-subscribe.html
@@ -12,7 +12,7 @@
 		dojo.require("dijit._Widget");
 		dojo.require("dojo.parser");
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			var numCallsInternal = 0;
 			var numCallsExternal = 0;
 			var externalString = "";
diff --git a/dijit/tests/_WidgetsInTemplateMixin.html b/dijit/tests/_WidgetsInTemplateMixin.html
new file mode 100644
index 0000000..f09d795
--- /dev/null
+++ b/dijit/tests/_WidgetsInTemplateMixin.html
@@ -0,0 +1,494 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+		<title>WidgetsInTemplateMixin.js</title>
+
+		<style type="text/css">
+			@import "../themes/claro/document.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">
+			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,
+					onClick: function(e){
+						if(e.target){
+							alert('onClick widgetId='+e.target.id);
+						}else{
+							if(e._counter == undefined){
+								e._counter = 1;
+							}else{
+								e._counter++;
+							}
+						}
+					}
+				});
+
+				dojo.declare('Test3Widget',
+					[dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin],
+				{
+					templateString: dojo.byId('Test3Template').value
+				});
+
+				dojo.declare('Test4Widget',
+					[dijit._WidgetBase, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin],
+				{
+					templateString: dojo.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;
+					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
+					doh.t(testW._started, "testW._started");
+					doh.t(testW.tabCont._started, "tabCont._started");
+					doh.t(testW.tab1._started, "tab1._started");
+					doh.t(testW.tab2._started, "tab2._started");
+				}
+			
+				dojo.declare('TestLayoutWidget', dijit.layout._LayoutWidget, {
+					startup: function(){
+						if(this._started){
+							this._doubleStarted = true;
+						}
+						this.inherited(arguments);
+					},
+					destroy: function(){
+						if(this._destroyed){
+							this._doubleDestroyed = true;
+						}
+						this.inherited(arguments);
+						this._destroyed = true;
+					}
+				});
+				dojo.declare('TestCtnrWidget', [dijit._WidgetBase, dijit._Container], {
+					startup: function(){
+						if(this._started){
+							this._doubleStarted = true;
+						}
+						this.inherited(arguments);
+					},
+					destroy: function(){
+						if(this._destroyed){
+							this._doubleDestroyed = true;
+						}
+						this.inherited(arguments);
+						this._destroyed = true;
+					}
+				});
+				dojo.declare('TestCtndWidget', [dijit._WidgetBase, dijit._Contained], {
+					startup: function(){
+						if(this._started){
+							this._doubleStarted = true;
+						}
+						this.inherited(arguments);
+					},
+					destroy: function(){
+						if(this._destroyed){
+							this._doubleDestroyed = true;
+						}
+						this.inherited(arguments);
+						this._destroyed = true;
+					}
+				});
+				dojo.declare('TestNonCtnrWidget', [dijit._WidgetBase, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
+					templateString: "<div data-dojo-attach-point=containerNode></div>",
+					startup: function(){
+						if(this._started){
+							this._doubleStarted = true;
+						}
+						this.inherited(arguments);
+					},
+					destroy: function(){
+						if(this._destroyed){
+							this._doubleDestroyed = true;
+						}
+						this.inherited(arguments);
+						this._destroyed = true;
+					}
+				});
+				dojo.declare('TestStubWidget', dijit._WidgetBase, {
+					startup: function(){
+						if(this._started){
+							this._doubleStarted = true;
+						}
+						this.inherited(arguments);
+					},
+					destroy: function(){
+						if(this._destroyed){
+							this._doubleDestroyed = true;
+						}
+						this.inherited(arguments);
+						this._destroyed = true;
+					}
+				});
+	
+				dojo.declare('Test5Widget',
+					[dijit._WidgetBase, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin],
+				{
+					templateString: dojo.byId('Test5Template').value,
+					startup: function(){
+						if(this._started){
+							this._doubleStarted = true;
+						}
+						this.inherited(arguments);
+					},
+					destroy: function(){
+						if(this._destroyed){
+							this._doubleDestroyed = true;
+						}
+						this.inherited(arguments);
+						this._destroyed = true;
+					}
+				});
+	
+				dojo.declare("Missing", [dijit._WidgetBase, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
+					templateString: '<div>' +
+										'<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>'
+				});
+
+				function getTestWidgets(testW){
+					return [
+						testW,
+						testW.layout,
+						testW.layChild1,
+						testW.layChild2,
+						testW.container,
+						testW.contained1,
+						testW.contained2,
+						testW.nonContainer,
+						testW.nonContained1,
+						testW.nonContained2,
+						testW.threeLevel,
+						testW.secondLevel,
+						testW.bottomLevel,
+						testW.anotherThree,
+						testW.anotherSecond,
+						testW.anotherBottom,
+						testW.stub1
+					];
+				}
+		
+				function validateTest5Widget(t, testW){
+					// Check that everything got started, but not double-started
+					dojo.forEach(getTestWidgets(testW), function(w){
+						doh.t(w._started, "w._started: " + w);
+						doh.is(undefined, w._doubleStarted, "w._doubleStarted: " + w);
+					});
+				}
+		
+				function validateTest5WidgetDestroy(t, testW){
+					var savedWidgets = getTestWidgets(testW);
+					testW.destroy();
+					dojo.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("_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");
+							}
+						},
+						{
+							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");
+							}
+						},
+						{
+							// 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");
+
+/*** 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 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;
+										}
+									}
+									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");
+							}
+						}
+					]
+				);
+
+				// 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], {
+						obj: {hello: "world"},
+						templateString:
+							"<div>" +
+								"<div data-dojo-type='dijit._WidgetBase' data-dojo-props='hostObj: this.obj'" +
+								" data-dojo-attach-point='subWidget'></div>" +
+							"</div>"
+					});
+					
+					var hostWidget = new host(),
+						subWidget = hostWidget && hostWidget.subWidget;
+					doh.isNot(undefined, hostWidget, "created host widget");
+					doh.isNot(undefined, subWidget, "created sub widget");
+					doh.isNot(undefined, subWidget.hostObj, "sub widget got hostObj defined");
+					doh.is("world", subWidget.hostObj.hello, "object is correct")
+				});
+
+				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>
+			</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>
+		</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>
+		</textarea>
+
+		<div data-dojo-type="Test5Widget" data-dojo-props="id: 'test5Widget'"></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
index 8740d8d..134e45e 100644
--- a/dijit/tests/_altCalendar.html
+++ b/dijit/tests/_altCalendar.html
@@ -1,37 +1,35 @@
-<table cellspacing="0" cellpadding="0" class="dijitCalendarContainer" role="grid" dojoAttachEvent="onkeypress: _onKeyPress">
+<table cellspacing="0" cellpadding="0" class="dijitCalendarContainer" role="grid">
 	<thead>
 		<tr class="dijitReset dijitCalendarMonthContainer" valign="top">
 			<th>			
-			<span class='dijitReset dijitCalendarArrow' dojoAttachPoint="decrementMonth">
+			<span class='dijitReset dijitCalendarArrow' data-dojo-attach-point="decrementMonth">
 				<img src="${_blankGif}" alt="" class="dijitCalendarIncrementControl dijitCalendarDecrease" role="presentation">
-				<span dojoAttachPoint="decreaseArrowNode" class="dijitA11ySideArrow">-</span>
+				<span data-dojo-attach-point="decreaseArrowNode" class="dijitA11ySideArrow">-</span>
 			</span>
-			<span dojoAttachEvent="onclick: goToToday" style="cursor: pointer; cursor: hand;">ࣻ</span>
-			<span class='dijitReset dijitCalendarArrow' dojoAttachPoint="incrementMonth">
+			<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 dojoAttachPoint="increaseArrowNode" class="dijitA11ySideArrow">+</span>
+				<span data-dojo-attach-point="increaseArrowNode" class="dijitA11ySideArrow">+</span>
 			</span></th>
 			<th class='dijitReset' colspan="6">
-				<div data-dojo-type="dijit.form.DropDownButton" data-dojo-attach-point="monthDropDownButton">
+				<div data-dojo-attach-point="monthNode">
 				</div>
 			</th>
 		</tr>
 		<tr>
-			<th class="dijitReset dijitCalendarDayLabelTemplate" role="columnheader"><span class="dijitCalendarDayLabel"></span></th>
+			${!dayCellsHtml}
 		</tr>
 	</thead>
-	<tbody dojoAttachEvent="onclick: _onDayClick, onmouseover: _onDayMouseOver, onmouseout: _onDayMouseOut, onmousedown: _onDayMouseDown, onmouseup: _onDayMouseUp" class="dijitReset dijitCalendarBodyContainer">
-		<tr class="dijitReset dijitCalendarWeekTemplate" role="row">
-			<td class="dijitReset dijitCalendarDateTemplate" role="gridcell"><span class="dijitCalendarDateLabel"></span><span class="dijitCalendarDateDescription"></span></td>
-		</tr>
+	<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">
+			<td class='dijitReset' valign="top" colspan="7" role="presentation">
 				<h3 class="dijitCalendarYearLabel">
-					<span dojoAttachPoint="previousYearLabelNode" class="dijitInline dijitCalendarPreviousYear"></span>
-					«<span dojoAttachPoint="currentYearLabelNode" class="dijitInline dijitCalendarSelectedYear"></span>»
-					<span dojoAttachPoint="nextYearLabelNode" class="dijitInline dijitCalendarNextYear"></span>
+					<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>
diff --git a/dijit/tests/_base/manager.html b/dijit/tests/_base/manager.html
index a01d101..6cf6e27 100644
--- a/dijit/tests/_base/manager.html
+++ b/dijit/tests/_base/manager.html
@@ -16,7 +16,7 @@
 		dojo.require("dojo.parser");
 		dojo.require("dijit.dijit");
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			dojo.declare("foo", dijit._Widget, {
 				name: "",
 				attr1: 0,
diff --git a/dijit/tests/_base/place.html b/dijit/tests/_base/place.html
index 83c7b0a..f0fe3c4 100644
--- a/dijit/tests/_base/place.html
+++ b/dijit/tests/_base/place.html
@@ -7,10 +7,14 @@
 		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 
+		html {
+			overflow: hidden; /* ie6 needs this */
+		}
 		body {
 			height: 100%;
-			padding: 0px;
-			margin: 0px;
+			padding: 0;
+			margin: 0;
+			border: 0;
 		}
 
 		.aroundNode {
@@ -37,7 +41,7 @@
 		dojo.require("dijit.dijit");
 
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 
 			// The around nodes
 			var aroundTop = dojo.byId("aroundTop"),
@@ -119,6 +123,134 @@
 						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");
+					},
+					function placeOnScreenAroundNodeBM(t){
+						// bottom middle popup from "aroundBottom" node
+						var ret = dijit.placeOnScreenAroundNode(popup, aroundBottom, {
+							"TR": "TL",	// aroundBottom's top-right corner with the popup's top-left corner (fails)
+							"TM": "BM",	// aroundBottom's top-middle with the popup's bottom-middle (works)
+							"BM": "TM",	// aroundBottom's bottom-middle with the popup's top-middle (fails)
+							"TL": "TR"	// aroundBottom's top-left corner with the popup's top-right corner (fails)
+						});
+
+						doh.is("TM", ret.aroundCorner, "around middle");
+						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.t(aroundPos.x > popupPos.x, "starts before around node");
+						doh.t(aroundPos.x < (popupPos.x + popupPos.w), "ends after around node");
+					},
+					function placeOnScreenAroundNodeTM(t){
+						// top middle popup from "aroundTop" node
+						var ret = dijit.placeOnScreenAroundNode(popup, aroundTop, {
+							"BL": "BR",	// aroundTop's bottom-left corner with the popup's bottom-right corner (fails)
+							"TM": "BM",	// aroundTop's top-middle with the popup's bottom-middle (fails)
+							"BM": "TM",	// aroundTop's bottom-middle with the popup's top-middle (works)
+							"BR": "BL"	// aroundTop's bottom-right corner with the popup's bottom-left corner (fails)
+						});
+
+						doh.is("BM", ret.aroundCorner, "around middle");
+						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.t(aroundPos.x > popupPos.x, "starts before around node");
+						doh.t(aroundPos.x < (popupPos.x + popupPos.w), "ends after around node");
+					},
+					function placeOnScreenAroundNodeML(t){
+						// middle left 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)
+							"MR": "ML",	// aroundLeft's middle-right with the popup's middle-left (works)
+							"ML": "MR",	// aroundLeft's middle-left with the popup's middle-right (fails)
+							"TR": "BR"	// aroundLeft's top-right corner with the popup's bottom-right corner (fails)
+						});
+
+						doh.is("MR", ret.aroundCorner, "around middle");
+						doh.is("ML", ret.corner, "popup's middle");
+						var popupPos = dojo.position(popup);
+						var aroundPos = dojo.position(aroundLeft);
+						doh.is(aroundPos.x + aroundPos.w, 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 placeOnScreenAroundNodeMR(t){
+						// middle left popup from "aroundRight" node
+						var ret = dijit.placeOnScreenAroundNode(popup, aroundRight, {
+							"BL": "TL",	// aroundRight's bottom-left corner with the popup's top-left corner (fails)
+							"MR": "ML",	// aroundRight's middle-right with the popup's middle-left (fails)
+							"ML": "MR",	// aroundRight's middle-left with the popup's middle-right (works)
+							"TL": "BL"	// aroundRight's top-left corner with the popup's bottom-left corner (fails)
+						});
+
+						doh.is("ML", ret.aroundCorner, "around middle");
+						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.t(aroundPos.y > popupPos.y, "starts before around node");
+						doh.t(aroundPos.y < (popupPos.y + popupPos.h), "ends after around node");
+					},
+					function placeOnScreenAroundNodeMLB(t){
+						// 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)
+							"TR": "BR"	// aroundLeft's top-right corner with the popup's bottom-right corner (fails)
+						});
+
+						doh.is("BM", ret.aroundCorner, "around middle");
+						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(aroundPos.x, popupPos.x, "left aligned with around node");
+					},
+					function placeOnScreenAroundNodeMRT(t){
+						// top middle popup from "aroundRight" node
+						var ret = dijit.placeOnScreenAroundNode(popup, aroundRight, {
+							"BL": "TL",	// aroundRight's bottom-left corner with the popup's top-left corner (fails)
+							"TM": "BM",	// aroundRight's top-middle with the popup's bottom-middle (works)
+							"TL": "BL"	// aroundRight's top-left corner with the popup's bottom-left corner (fails)
+						});
+
+						doh.is("TM", ret.aroundCorner, "around middle");
+						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");
+					},
+					function placeOnScreenAroundNodeTML(t){
+						// middle left popup from "aroundTop" node
+						var ret = dijit.placeOnScreenAroundNode(popup, aroundTop, {
+							"BL": "BR",	// aroundTop's bottom-left corner with the popup's bottom-right corner (fails)
+							"ML": "MR",	// aroundTop's middle-left with the popup's middle-right (works)
+							"BR": "BL"	// aroundTop's bottom-right corner with the popup's bottom-left corner (fails)
+						});
+
+						doh.is("ML", ret.aroundCorner, "around middle");
+						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(aroundPos.y, popupPos.y, "top aligned with around node");
+					},
+					function placeOnScreenAroundNodeBMR(t){
+						// middle right popup from "aroundBottom" node
+						var ret = dijit.placeOnScreenAroundNode(popup, aroundBottom, {
+							"TL": "TR",	// aroundBottom's top-left corner with the popup's top-right corner (fails)
+							"MR": "ML",	// aroundBottom's middle-right with the popup's middle-left (works)
+							"TR": "TL"	// aroundBottom's top-right corner with the popup's top-left corner (fails)
+						});
+
+						doh.is("MR", ret.aroundCorner, "around middle");
+						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");
 					}
 				]
 			);
@@ -129,9 +261,9 @@
 </head>
 <body>
 	<h1>Dijit Place Unit Test</h1>
-	<div id="aroundTop" class="aroundNode" style="top: 0px; left: 50%;">T</div>
-	<div id="aroundLeft" class="aroundNode" style="top: 200px; left: 0;">L</div>
-	<div id="aroundRight" class="aroundNode" style="top: 200px; right: 1px;">R</div>
+	<div id="aroundTop" class="aroundNode" style="top: 0; left: 200px;">T</div>
+	<div id="aroundLeft" class="aroundNode" style="top: 350px; 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">
diff --git a/dijit/tests/_base/robot/CrossWindow.html b/dijit/tests/_base/robot/CrossWindow.html
index b682467..b9fc602 100644
--- a/dijit/tests/_base/robot/CrossWindow.html
+++ b/dijit/tests/_base/robot/CrossWindow.html
@@ -9,15 +9,14 @@
 		</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"></script>
 
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_CrossWindow.html');
 
 				doh.register("CrossWindow", [
diff --git a/dijit/tests/_base/robot/FocusManager.html b/dijit/tests/_base/robot/FocusManager.html
index c1b56df..072f891 100644
--- a/dijit/tests/_base/robot/FocusManager.html
+++ b/dijit/tests/_base/robot/FocusManager.html
@@ -9,13 +9,12 @@
 		</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"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_FocusManager.html');
 
 				doh.register("Dijit focus manager low level tests", [
@@ -104,8 +103,8 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Check that focus was returned to the textarea
-								doh.t(dojo.global.dijit._curFocus, "curFocus defined");
-								doh.is("textarea", dojo.global.dijit._curFocus.id, "focused on textarea");
+								doh.t(dojo.global.dijit.focus.curNode, "curFocus defined");
+								doh.is("textarea", dojo.global.dijit.focus.curNode.id, "focused on textarea");
 
 								// And that " there" was selected then deleted
 								doh.is("hello!", dojo.byId("textarea").value);
diff --git a/dijit/tests/_base/robot/focus_mouse.html b/dijit/tests/_base/robot/focus_mouse.html
index 40fbbbc..6093863 100644
--- a/dijit/tests/_base/robot/focus_mouse.html
+++ b/dijit/tests/_base/robot/focus_mouse.html
@@ -9,13 +9,12 @@
 		</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"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_focusWidget.html?animate=false');
 
 				// These are objects used to track calls to _onFocus and _onBlur in various widgets
@@ -69,7 +68,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Make sure that focus manager caught the focus event
-								doh.is(dojo.byId("first"), dojo.global.dijit._curFocus);
+								doh.is(dojo.byId("first"), dojo.global.dijit.focus.curNode);
 
 								// And that the dijit.form.Form widget is marked as
 								// being "in focus"
@@ -93,7 +92,7 @@
 							handle = dojo.connect(dijit.byId("select").focusNode, "onfocus", 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(dojo.byId("select"), dojo.global.dijit._curFocus);
+								doh.is(dojo.byId("select"), dojo.global.dijit.focus.curNode);
 
 								// The focus stack should show the ComboBox plus all parent widgets
 								var stack = dojo.global.dijit._activeStack;
@@ -200,7 +199,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Focus goes to an first item in the drop down menu
-								doh.is(dojo.byId("mi1").id, dojo.global.dijit._curFocus.id);
+								doh.is(dojo.byId("mi1").id, dojo.global.dijit.focus.curNode.id);
 
 								// The focus stack should show the ComboBox plus all parent widgets
 								var stack = dojo.global.dijit._activeStack;
@@ -235,7 +234,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Focus goes to an first item in the sub menu
-								doh.is(dojo.byId("smi1"), dojo.global.dijit._curFocus);
+								doh.is(dojo.byId("smi1"), dojo.global.dijit.focus.curNode);
 
 								// The focus stack should show the two submenus and then upwards
 								// to the ComboButton, and the rest
diff --git a/dijit/tests/_base/robot/popup.html b/dijit/tests/_base/robot/popup.html
index 393a0d9..4309a5a 100644
--- a/dijit/tests/_base/robot/popup.html
+++ b/dijit/tests/_base/robot/popup.html
@@ -18,9 +18,21 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			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
@@ -142,9 +154,6 @@
 
 					function closeAround(){
 						// Close the layer of popups
-						var around = dojo.global.choiceDropDownButton,
-							popup = dojo.global.choiceDropDown;
-
 						var around = dojo.global.nestedDropDownButton,
 							popup = dojo.global.nestedOpener,
 							nestedPopup = dojo.global.nestedChoice1;
@@ -160,61 +169,11 @@
 
 				// 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.
-				if(!dojo.isSafari){
-					doh.register("no hidden tab stops", [
-						{
-							name: "tab off end of viewport",
-							timeout: 10000,
-							runTest: function (){
-								var d = new doh.Deferred();
-								var focusId;
-		
-								dojo.byId("inputAtEnd").focus();
-								doh.robot.sequence(function(){
-									// Just to make sure that focus is on the input
-									focusId = dojo.global.dijit._curFocus ? dojo.global.dijit._curFocus.id : null;
-								}, 1000);
-	
-								doh.robot.keyPress(dojo.keys.TAB, 500, {});
-		
-								// Focus should end up on URL bar etc., not on a hidden <input> or <button> in a popup
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.is("inputAtEnd", focusId);
-									doh.f(dojo.global.dijit._curFocus && dojo.isDescendant(dojo.global.dijit._curFocus, dojo.global.dojo.body()), "no focus inside viewport");
-								}), 1000);
-		
-								return d;
-							}
-						},
-						{
-							name: "tab off beginning of viewport",
-							timeout: 10000,
-							runTest: function (){
-								var d = new doh.Deferred();
-								var focusId;
-
-								doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
-								doh.robot.sequence(function(){
-									dojo.byId("inputAtStart").focus();
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Just to make sure that focus is on the input
-									focusId = dojo.global.dijit._curFocus ? dojo.global.dijit._curFocus.id : null;
-								}, 1000);
-	
-								doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
-		
-								// Focus should end up on URL bar etc., not on a hidden <input> or <button> in a popup
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.is("inputAtStart", focusId);
-									doh.f(dojo.global.dijit._curFocus && dojo.isDescendant(dojo.global.dijit._curFocus, dojo.global.dojo.body()), "no focus inside viewport");
-								}), 1000);
-		
-								return d;
-							}
-						}
-					]);
-				}	// if(!dojo.isSafari)
+				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
 
diff --git a/dijit/tests/_base/robot/typematic.html b/dijit/tests/_base/robot/typematic.html
index a2da8b5..f18d371 100644
--- a/dijit/tests/_base/robot/typematic.html
+++ b/dijit/tests/_base/robot/typematic.html
@@ -9,13 +9,12 @@
 		</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"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_typematic.html');
 
 				doh.register("press and hold test", [
diff --git a/dijit/tests/_base/runTests.html b/dijit/tests/_base/runTests.html
new file mode 100644
index 0000000..953fa05
--- /dev/null
+++ b/dijit/tests/_base/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>Dijit _base Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?testModule=dijit.tests._base.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dijit/tests/_base/tabindex.html b/dijit/tests/_base/tabindex.html
index 9fcea43..c102995 100644
--- a/dijit/tests/_base/tabindex.html
+++ b/dijit/tests/_base/tabindex.html
@@ -18,7 +18,7 @@
 		dojo.require("dijit.dijit");
 		dojo.require("dijit.Editor");
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			doh.register("parse", function(){
 				dojo.parser.parse();
 			});
diff --git a/dijit/tests/_base/test_CrossWindow.html b/dijit/tests/_base/test_CrossWindow.html
index d014c26..035db11 100644
--- a/dijit/tests/_base/test_CrossWindow.html
+++ b/dijit/tests/_base/test_CrossWindow.html
@@ -10,13 +10,12 @@
 		</style>
 		<script type="text/javascript"
 			src="../../../dojo/dojo.js"
-			debugAtAllCosts="false"
 			djConfig="isDebug:true, popup:false, parseOnLoad:false">
 		</script>
 		<script type="text/javascript">
 
 			dojo.require("dijit._Widget");
-			dojo.require("dijit._Templated");
+			dojo.require("dijit._TemplatedMixin");
 			dojo.require("dojo.parser");
 
 			var w;
@@ -29,19 +28,23 @@
 			onPopClose = function(){
 				console.log("setting context back to main window...");
 				dojo.setContext(dojo.global, globalDocument);
-				if(dijit.byId('simple3')){ dijit.byId('simple3').destroy(); }
+				if(dijit.byId('simple3')){
+					dijit.byId('simple3').destroy();
+				}
 				console.log("Now building the widget in the main window...");
 				var div = dojo.doc.createElement("div");
 				dojo.byId("main").appendChild(div);
 				new widgetClass({id:"simple3"}, div);
 				console.log("There should now be two widgets at the top of the page.");
-			}
+			};
 
 			onPopLoad = function(){
 				globalDocument = dojo.doc;
 				dojo.setContext(dojo.global, popwin.document);
 
-				if(dijit.byId('simple2')){ dijit.byId('simple2').destroy(); }
+				if(dijit.byId('simple2')){
+					dijit.byId('simple2').destroy();
+				}
 				console.log("rendering one widget in popup...");
 
 				var div = dojo.doc.createElement("div");
@@ -51,19 +54,19 @@
 				console.log("The widget should have appeared in the popup window.");
 
 				onPopClose();
-			}
+			};
 
 			openPopup = function(){
-				popup = window.open ('',"mywin","width=240,height=180");
-				var doc=popup.document;
+				popup = window.open('', "mywin", "width=240,height=180");
+				var doc = popup.document;
 
 				var newbcolor = '#FFFFFF';
 				var newfcolor = '$FF0000';
 				var word = "";
-				var HTMLstring=	'<HTML><HEAD><TITLE>IE Cross Window</TITLE></HEAD>\n' +
-								'<BODY id="popup" bgColor="'+newbcolor+'">\n'+
-								'<div><div id="main"></div></div>\n'+
-								'</BODY></HTML>';
+				var HTMLstring = '<HTML><HEAD><TITLE>IE Cross Window</TITLE></HEAD>\n' +
+						'<BODY id="popup" bgColor="' + newbcolor + '">\n' +
+						'<div><div id="main"></div></div>\n' +
+						'</BODY></HTML>';
 
 				doc.write(HTMLstring);
 				doc.close();
@@ -81,7 +84,7 @@
 				}
 
 				return popup;
-			}
+			};
 
 			speedTest = function(){
 				console.log("Speed Test");
@@ -93,15 +96,15 @@
 				dojo.byId("main").appendChild(div);
 
 				for(var i = 0; i < amt; i++){
-					new widgetClass({id:"simple_"+i}, div);
+					new widgetClass({id:"simple_" + i}, div);
 				}
-				console.log("Time to render ", amt, " widgets:",  (new Date() - start) );
-			}
+				console.log("Time to render ", amt, " widgets:", (new Date() - start));
+			};
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				widgetClass = dojo.declare(
 					"Simple",
-					[dijit._Widget, dijit._Templated], {
+					[dijit._Widget, dijit._TemplatedMixin], {
 						templateString: '<div> Widget created: ${id} </div>'
 					}
 				);
diff --git a/dijit/tests/_base/test_FocusManager.html b/dijit/tests/_base/test_FocusManager.html
index 48eeece..5fdf59f 100644
--- a/dijit/tests/_base/test_FocusManager.html
+++ b/dijit/tests/_base/test_FocusManager.html
@@ -12,10 +12,11 @@
 	<script type="text/javascript" src="../../../dojo/dojo.js"
 		djConfig="isDebug: true"></script>
 	<script type="text/javascript">
-		dojo.require("dijit._base.focus");
+		dojo.require("dijit.focus");		// dijit.focus()
+		dojo.require("dijit._base.focus");	// dijit.getFocus()
 		dojo.require("dijit._editor.selection");	// accessed by robot test
 		var savedFocus, fakeWidget;
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			fakeWidget = { domNode: dojo.byId("save") };
 			dojo.subscribe("focusNode", function(node){ console.log("focused on " + (node?(node.id||node.tagName):"nothing"));});
 		});
diff --git a/dijit/tests/_base/test_focusWidget.html b/dijit/tests/_base/test_focusWidget.html
index 10f1a80..300204b 100644
--- a/dijit/tests/_base/test_focusWidget.html
+++ b/dijit/tests/_base/test_focusWidget.html
@@ -13,14 +13,21 @@
 		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
+
 		dojo.require("dijit.form.DateTextBox");
 		dojo.require("dijit.form.ComboBox");
 		dojo.require("dijit.form.NumberSpinner");
-		dojo.require("dijit.form.Button");
+		dojo.require("dijit.form.ComboButton");
+
 		dojo.require("dijit.Menu");
+		dojo.require("dijit.MenuItem");
+		dojo.require("dijit.PopupMenuItem");
+
 		dojo.require("dijit.layout.ContentPane");
 		dojo.require("dijit.Editor");
 
+		dojo.require("dijit._base.focus");
+
 		// This code does animation to change border color and width to show
 		// active vs. non-active widgets.
 		var queue=[];
@@ -57,7 +64,7 @@
 		// This flag controls animation and can be disabled by the test harness in robot/focus_mouse.html
 		animate = !window.location.search.match("animate=false");
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			dojo.subscribe("widgetFocus", function(widget){
 				console.log("focused on widget " + (widget?widget:"nothing"));
 				if(animate){
diff --git a/dijit/tests/_base/test_popup.html b/dijit/tests/_base/test_popup.html
index b356280..b366135 100644
--- a/dijit/tests/_base/test_popup.html
+++ b/dijit/tests/_base/test_popup.html
@@ -10,8 +10,8 @@
 
 		body {
 			height: 100%;
-			padding: 0px;
-			margin: 0px;
+			padding: 0;
+			margin: 0;
 		}
 
 		div {
@@ -33,15 +33,17 @@
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit");
+		dojo.require("dijit._base.popup");
+		dojo.require("dijit._Widget");
+		dojo.require("dijit._TemplatedMixin");
 
 		function log(str){
 			console.log(str);
 		}
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 
-			dojo.declare("SimpleDropDownButton", [dijit._Widget, dijit._Templated], {
+			dojo.declare("SimpleDropDownButton", [dijit._Widget, dijit._TemplatedMixin], {
 				// summary:
 				//		A button that shows a popup.
 				//		Supply popup as parameter when instantiating this widget.
@@ -49,7 +51,7 @@
 				label: "show popup",
 				orient: {'BL': 'TL', 'BR': 'TR'},
 
-				templateString: "<button dojoAttachEvent='onclick: openPopup'>${label}</button>",
+				templateString: "<button data-dojo-attach-event='onclick: openPopup'>${label}</button>",
 
 				openPopup: function(){
 					var self = this;
@@ -88,7 +90,14 @@
 				}
 			});
 
-			dojo.declare("SimpleChoiceWidget",  [dijit._Widget, dijit._Templated], {
+			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.
 
@@ -98,9 +107,9 @@
 
 				templateString:
 					"<div class='choice'>" +
-						"<div dojoAttachEvent='onclick: onClick'>${choice1}</div>" +
-						"<div dojoAttachEvent='onclick: onClick'>${choice2}</div>" +
-						"<div dojoAttachEvent='onclick: onClick'>${choice3}</div>" +
+						"<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){
@@ -123,7 +132,7 @@
 				popup: choiceDropDown
 			})).placeAt(dojo.byId("widgets"));
 
-			dojo.declare("DialogWithPopupWidget",  [dijit._Widget, dijit._Templated], {
+			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.
@@ -135,8 +144,8 @@
 					"<div style='width: 300px'>" +
 						"<div>${title}</div>" +
 						"<input><br>" +
-						"<button dojoAttachPoint='button'>${label}</button><br>" +
-						"<button dojoAttachEvent='onclick: onExecute'>OK</button>" +
+						"<button data-dojo-attach-point='button'>${label}</button><br>" +
+						"<button data-dojo-attach-event='onclick: onExecute'>OK</button>" +
 					"</div>",
 
 				postCreate: function(){
@@ -175,15 +184,15 @@
 				})
 			}).placeAt(dojo.byId("widgets"));
 
-			dojo.declare("NestedPopupOpener",  [dijit._Widget, dijit._Templated], {
+			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 dojoAttachEvent='onclick: onClick'>popup1</div>" +
-						"<div dojoAttachEvent='onclick: onClick'>popup2</div>" +
+						"<div data-dojo-attach-event='onclick: onClick'>popup1</div>" +
+						"<div data-dojo-attach-event='onclick: onClick'>popup2</div>" +
 					"</div>",
 
 				onClick: function(e){
@@ -259,6 +268,9 @@
 				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>
diff --git a/dijit/tests/_base/test_typematic.html b/dijit/tests/_base/test_typematic.html
index 83848c6..bbbc477 100644
--- a/dijit/tests/_base/test_typematic.html
+++ b/dijit/tests/_base/test_typematic.html
@@ -10,14 +10,14 @@
 	</style>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, debugAtAllCosts: true"></script>
+		djConfig="isDebug: true"></script>
 	<script type="text/javascript">
-		dojo.require("dijit._base.typematic");
+		dojo.require("dijit.typematic");
 
 		var lastCount = 0;
 		function typematicCallBack(count, node, evt){
 			var inputNode = dojo.byId('typematicInput');
-			if (node == inputNode){
+			if(node == inputNode){
 				key = "a";
 			}else{
 				key = "b";
@@ -30,7 +30,7 @@
 			}
 				inputNode.focus();
 		}
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			var keyNode = dojo.byId('typematicInput');
 			var mouseNode = dojo.byId('typematicButton');
 			dijit.typematic.addKeyListener(keyNode,
diff --git a/dijit/tests/_base/wai.html b/dijit/tests/_base/wai.html
index 9275e80..83a1720 100644
--- a/dijit/tests/_base/wai.html
+++ b/dijit/tests/_base/wai.html
@@ -7,7 +7,7 @@
 		dojo.require("doh.runner");
 		dojo.require("dijit.dijit");
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			doh.register("dijit.tests._base.wai",
 				[
 					function getWaiRoleOnElementWithNoRole(){
@@ -40,14 +40,14 @@
 						doh.assertEqual("menuitem", div.getAttribute("role"));
 					},
 
-					function setWaiRoleToExistingXHTML() {
+					function setWaiRoleToExistingXHTML(){
 						/* replacing XHTML role w/wai role */
 						var elem=dojo.byId("navigation-role");
 						dijit.setWaiRole(elem, "treeitem");
 						doh.assertEqual("treeitem", elem.getAttribute("role"));
 					},
 
-					function setWaiRoleToExistingWaiRole() {
+					function setWaiRoleToExistingWaiRole(){
 						/* replacing wai role w/another wai role */
 						var div= document.createElement("div");
 						dijit.setWaiRole(div, "menuitem");
diff --git a/dijit/tests/_data/SlowStore.js b/dijit/tests/_data/SlowStore.js
index 480da92..c304d9d 100644
--- a/dijit/tests/_data/SlowStore.js
+++ b/dijit/tests/_data/SlowStore.js
@@ -27,9 +27,7 @@ dojo.declare("dijit.tests._data.SlowStore", dojo.data.ItemFileReadStore, {
 				first = query[attr];
 				break;
 			}
-			if(dojo.isString(first)){
-					count = first.length;
-			}
+			count = first.toString().length;
 		}
 
 		var delay = 100;
diff --git a/dijit/tests/_loadTest.js b/dijit/tests/_loadTest.js
index 8d5d2bf..4ab4cb1 100644
--- a/dijit/tests/_loadTest.js
+++ b/dijit/tests/_loadTest.js
@@ -19,16 +19,30 @@ if(!file && window.location.href.search(/[?&]file[=]/i) > 0){
 }
 var readFile = function(file){
 	var xhr = null;
-	try{ xhr = new XMLHttpRequest() }catch(e0){
-	try{ xhr = new ActiveXObject('Msxml2.XMLHTTP') }catch(e1){
-	try{ xhr = new ActiveXObject('Microsoft.XMLHTTP') }catch(e2){
-	try{ xhr = new ActiveXObject('Msxml2.XMLHTTP.4.0') }catch(e3){}}}}
+	try{
+		xhr = new XMLHttpRequest();
+	}catch(e0){
+		try{
+			xhr = new ActiveXObject('Msxml2.XMLHTTP');
+		}catch(e1){
+			try{
+				xhr = new ActiveXObject('Microsoft.XMLHTTP');
+			}catch(e2){
+				try{
+					xhr = new ActiveXObject('Msxml2.XMLHTTP.4.0');
+				}catch(e3){
+				}
+			}
+		}
+	}
 	try{
 		xhr.open("GET", file, false);
 		xhr.send(null);
-	}catch(e){ return null } // file not found
+	}catch(e){
+		return null
+	} // file not found
 	return xhr.responseText;
-}
+};
 var text = readFile(file) || (file + " not found");
 var baseHref = file.replace(/^(.*\/)?[^\/]+$/, "$1");
 if(baseHref){
diff --git a/dijit/tests/_testCommon.js b/dijit/tests/_testCommon.js
index bb6ca81..0fc8ee8 100644
--- a/dijit/tests/_testCommon.js
+++ b/dijit/tests/_testCommon.js
@@ -1,24 +1,39 @@
-/*
-	_testCommon.js - a simple module to be included in dijit test pages to allow
-	for easy switching between the many many points of the test-matrix.
+// 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 ...
 
-	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-
-	constrast/image off emulation) ... probably not a genuine test for a11y.
+require([
+	"require",
+	"dojo/_base/array",
+	"dojo/_base/config",
+	"dojo/dom",
+	"dojo/dom-attr",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/query",
+	"dojo/ready",
+	"dojo/_base/window"
+], function(require, array, config, dom, domAttr, domClass, domConstruct, kernel, lang, query, ready, win){
 
-	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 ...
-*/
-
-(function(){
-	var d = dojo,
-		dir = "",
+	var dir = "",
 		theme = false,
+		themeModule = "dijit",
 		testMode = null,
 		defTheme = "claro",
 		vars={};
@@ -33,7 +48,7 @@
 			switch(key){
 				case "locale":
 					// locale string | null
-					dojo.locale = dojo.config.locale = locale = value;
+					kernel.locale = config.locale = locale = value;
 					break;
 				case "dir":
 					// rtl | null
@@ -46,82 +61,79 @@
 					break;
 				case "a11y":
 					if(value){ testMode = "dijit_a11y"; }
+					break;
+				case "themeModule":
+					// moduleName | null
+					if(value){ themeModule = value; }
 			}
 			vars[key] = value;
 		}
 	}
-	d._getVar = function(k, def){
+	kernel._getVar = function(k, def){	// TODO: not sure what this is
 		return vars[k] || def;
+	};
+
+	// BIDI
+	if(dir == "rtl"){
+		ready(0, function(){
+			// 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");
+		});
+	}
+
+	// a11y
+	if(testMode){
+		ready(0, function(){
+			var b = win.body();
+			if(testMode){
+				domClass.add(b, testMode);
+			}
+		});
 	}
 
 	// If URL specifies a non-claro theme then pull in those theme CSS files and modify
 	// <body> to point to that new theme instead of claro.
 	//
-	// Also defer parsing and any dojo.addOnLoad() calls that the test file makes
+	// Also defer parsing and any dojo.ready() calls that the test file makes
 	// until the CSS has finished loading.
-	if(theme || testMode || dir){
-
-		if(theme){
-			var themeCss = d.moduleUrl("dijit.themes",theme+"/"+theme+".css");
-			var themeCssRtl = d.moduleUrl("dijit.themes",theme+"/"+theme+"_rtl.css");
-			document.write('<link rel="stylesheet" type="text/css" href="'+themeCss+'"/>');
-			document.write('<link rel="stylesheet" type="text/css" href="'+themeCssRtl+'"/>');
-		}
-
-		if(dojo.config.parseOnLoad){
-			dojo.config.parseOnLoad = false;
-			dojo.config._deferParsing = true;
-			
-			// Capture any dojo.addOnLoad() calls the test makes and defer them until after
-			// the new CSS loads.   (TODO: would be more straightforward to just make a
-			// testAddOnLoad() function and call that from the test files)
-			var originalOnLoad = dojo.addOnLoad,
-				loadFuncs = [];
-			dojo.addOnLoad = function(f){ loadFuncs.push(f); };
-		}
-
-		(originalOnLoad || dojo.addOnLoad)(function(){
+	if(theme){
+		// Wait until JS modules have finished loading so this doesn't confuse
+		// AMD loader.
+		ready(1, function(){
 			// Reset <body> to point to the specified theme
-			var b = dojo.body();
-			if(theme){
-					dojo.removeClass(b, defTheme);
-					if(!d.hasClass(b, theme)){ d.addClass(b, theme); }
-					var n = d.byId("themeStyles");
-					if(n){ d.destroy(n); }
-			}
-			if(testMode){ d.addClass(b, testMode); }
+			var b = win.body();
+			domClass.replace(b, theme, defTheme);
 
-			// Claro has it's own reset css but for other themes using dojo/resources/dojo.css
-			if(theme){
-				dojo.query("style").forEach(function(node){
-					if(/claro\/document.css/.test(node.innerHTML)){
-						try{
-							node.innerHTML = node.innerHTML.replace("themes/claro/document.css",
-								"../dojo/resources/dojo.css");
-						}catch(e){
-							// fails on IE6-8 for some reason, works on IE9 and other browsers
-						}
-					}
-				});
-			}
-			if(dir == "rtl"){
-				// pretend all the labels are in an RTL language, because
-				// that affects how they lay out relative to inline form widgets
-				dojo.query("label").attr("dir", "rtl");
-			}
-
-			// Defer parsing and addOnLoad() execution until the specified CSS loads.
-			if(dojo.config._deferParsing){
-				setTimeout(function(){
-					dojo.addOnLoad = originalOnLoad;
-					dojo.parser.parse(b);
-					for(var i=0; i<loadFuncs.length; i++){
-						loadFuncs[i]();
-					}
-				}, 320);
-			}
+			// Remove claro CSS
+			query('link[href$="claro.css"]').orphan();
+			query('link[href$="claro/document.css"]').orphan();
 
+			// Load theme CSS.
+			// Eventually would like to use [something like]
+			// https://github.com/unscriptable/curl/blob/master/src/curl/plugin/css.js
+			// to load the CSS and then know exactly when it finishes loading.
+			var modules = [
+				require.toUrl(themeModule+"/themes/"+theme+"/"+theme+".css"),
+				require.toUrl(themeModule+"/themes/"+theme+"/"+theme+"_rtl.css"),
+				require.toUrl("dojo/resources/dojo.css")
+			];
+			var head = query("head")[0];
+			array.forEach(modules, function(css){
+				if(document.createStyleSheet){
+					// For IE
+					document.createStyleSheet(css);
+				}else{
+					// For other browsers
+					domConstruct.place('<link rel="stylesheet" type="text/css" href="'+css+'"/>',
+						head);
+				}
+			});
+		});
+		ready(2, function(){
+			// Delay parsing and other dojo.ready() callbacks (except ones in this file)
+			// until the injected <link>'s above have finished loading.
+			require(["dijit/tests/delay!320"]);
 		});
 	}
-
-})();
+});
diff --git a/dijit/tests/delay.js b/dijit/tests/delay.js
new file mode 100644
index 0000000..39090e0
--- /dev/null
+++ b/dijit/tests/delay.js
@@ -0,0 +1,19 @@
+// module:
+//		dijit/tests/delay.js
+// summary:
+//		AMD plugin that waits a specified number of ms before "loading".
+//		Used to delay execution of callbacks registered by dojo.ready().
+//		(Used by _testCommon.html)
+//
+//		Usage: ready(1, function(){ require(["dijit/tests/delay!300"]); });
+define({
+	load: function(delay, req, loaded){
+		setTimeout(function(){
+			loaded(1);
+		}, delay);
+	},
+	dynamic: 1,
+	normalize: function(id){
+		return id;
+	}
+});
\ No newline at end of file
diff --git a/dijit/tests/editor/BackForwardState.html b/dijit/tests/editor/BackForwardState.html
index 079a30c..4ea1d6e 100644
--- a/dijit/tests/editor/BackForwardState.html
+++ b/dijit/tests/editor/BackForwardState.html
@@ -42,5 +42,6 @@
 
 	<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>
+	<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/EnterKeyHandling.html b/dijit/tests/editor/EnterKeyHandling.html
index 849c039..8167821 100644
--- a/dijit/tests/editor/EnterKeyHandling.html
+++ b/dijit/tests/editor/EnterKeyHandling.html
@@ -17,7 +17,7 @@
 		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="../_testCommon.js"></script>
 
 
 	<script type="text/javascript">
diff --git a/dijit/tests/editor/nls_8859-2.html b/dijit/tests/editor/nls_8859-2.html
index e4d9a4a..8b22892 100644
--- a/dijit/tests/editor/nls_8859-2.html
+++ b/dijit/tests/editor/nls_8859-2.html
@@ -23,7 +23,7 @@
 		dojo.require("dijit.Editor");
 		dojo.require("dojo.parser");
 		
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 
 			doh.register("parse", function(){
 				dojo.parser.parse();
diff --git a/dijit/tests/editor/nls_sjis.html b/dijit/tests/editor/nls_sjis.html
index 7983040..c998f1e 100644
--- a/dijit/tests/editor/nls_sjis.html
+++ b/dijit/tests/editor/nls_sjis.html
@@ -23,7 +23,7 @@
 		dojo.require("dijit.Editor");
 		dojo.require("dojo.parser");
 		
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 
 			doh.register("parse", function(){
 				dojo.parser.parse();
diff --git a/dijit/tests/editor/nls_utf8.html b/dijit/tests/editor/nls_utf8.html
index 62487c9..ab60e86 100644
--- a/dijit/tests/editor/nls_utf8.html
+++ b/dijit/tests/editor/nls_utf8.html
@@ -23,7 +23,7 @@
 		dojo.require("dijit.Editor");
 		dojo.require("dojo.parser");
 		
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			 
 			doh.register("parse", function(){
 				dojo.parser.parse();
diff --git a/dijit/tests/editor/robot/BackForwardState.html b/dijit/tests/editor/robot/BackForwardState.html
index 962f912..bf47ebb 100644
--- a/dijit/tests/editor/robot/BackForwardState.html
+++ b/dijit/tests/editor/robot/BackForwardState.html
@@ -9,8 +9,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"></script>
 
 		<!-- functions to help test -->
 		<script type="text/javascript" src="../../helpers.js"></script>
@@ -23,7 +22,7 @@
 			// accidentlly navigates to a different page, and then returns to the
 			// page w/the editor by pressing the back button.
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../BackForwardState.html');
 
 				doh.register("back button restore", [
diff --git a/dijit/tests/editor/robot/CustomPlugin.html b/dijit/tests/editor/robot/CustomPlugin.html
index 6a0febc..ce0519b 100644
--- a/dijit/tests/editor/robot/CustomPlugin.html
+++ b/dijit/tests/editor/robot/CustomPlugin.html
@@ -9,8 +9,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"></script>
 
 		<script type="text/javascript" src="../../helpers.js"></script>
 
@@ -18,8 +17,10 @@
 			dojo.require("dojo.DeferredList");
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_CustomPlugin.html');
+				
+				var myPlugin;
 
 				doh.register("isVisible", [
 					{
@@ -41,59 +42,50 @@
 				doh.register("testCustomPlugin", [
 					{
 						name: "toggleOn",
+						setUp: function(){
+							var editor = dijit.byId("editor1");
+							dojo.forEach(editor._plugins, function(plugin){
+								if(plugin.name === "MyPlugin"){
+									myPlugin = plugin;
+								}
+							});
+						},
 						timeout: 15000,
 						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt(dojo.query(".customIcon")[0], 500);
+							var d = new doh.Deferred();	
+							myPlugin.button.focus();
+							doh.robot.mouseMoveAt(myPlugin.button.domNode, 500);
 							doh.robot.mouseClick({left:true}, 500);
 							
 							doh.robot.sequence(d.getTestCallback(function(){
 								var foundClass = false;
-								var parent = dojo.query(".customIcon")[0].parentNode;
-								while(parent && !foundClass){
-									foundClass = dojo.hasClass(parent, "dijitToggleButtonChecked");
-									parent = parent.parentNode;
-								}
-								doh.t(foundClass, "foundClass"); //Test that the button was toggled after we pressed it
-								
-								var editor = dijit.byId("editor1");
-								dojo.forEach(editor._plugins, function(plugin){
-									if(plugin.name === "MyPlugin"){
-										var sourceArea = plugin.sourceArea;
-										doh.t(isVisible(sourceArea), "isVisible(sourceArea)");
-									}
-								});
+								doh.t(myPlugin.button.get("checked"), "Verifying button was checked.");
+								var sourceArea = myPlugin.sourceArea;
+								doh.t(isVisible(sourceArea), "isVisible(sourceArea)");
 							}), 1000);
 							return d;
 						}
 					},
 					{
 						name: "toggleOff",
+						setUp: function(){
+							var editor = dijit.byId("editor1");
+							dojo.forEach(editor._plugins, function(plugin){
+								if(plugin.name === "MyPlugin"){
+									myPlugin = plugin;
+								}
+							});
+						},
 						timeout: 15000,
 						runTest: function(){
 							var d = new doh.Deferred();
-
-							//doh.robot.keyPress(dojo.keys.ENTER, 1000, {});
-							doh.robot.mouseMoveAt(dojo.query(".customIcon")[0], 500);
+							myPlugin.button.focus();
+							doh.robot.mouseMoveAt(myPlugin.button.domNode, 500);
 							doh.robot.mouseClick({left:true}, 500);
-							
 							doh.robot.sequence(d.getTestCallback(function(){
-								var foundClass = false;
-								var parent = dojo.query(".customIcon")[0].parentNode;
-								while(parent && !foundClass){
-									foundClass = dojo.hasClass(parent, "dijitToggleButtonChecked");
-									parent = parent.parentNode;
-								}
-								doh.f(foundClass, "foundClass"); //Test that the button was toggled off after we pressed it
-								
-								var editor = dijit.byId("editor1");
-								dojo.forEach(editor._plugins, function(plugin){
-									if(plugin.name === "MyPlugin"){
-										var sourceArea = plugin.sourceArea;
-										doh.f(isVisible(sourceArea), "isVisible(sourceArea)");
-									}
-								});
+								doh.f(myPlugin.button.get("checked"), "Verifying button was unchecked.");
+								var sourceArea = myPlugin.sourceArea;
+								doh.f(isVisible(sourceArea), "isVisible(sourceArea)");
 							}), 1000);
 							return d;
 						}
diff --git a/dijit/tests/editor/robot/Editor_FontChoice.html b/dijit/tests/editor/robot/Editor_FontChoice.html
index 72c81e2..e9cc32a 100755
--- a/dijit/tests/editor/robot/Editor_FontChoice.html
+++ b/dijit/tests/editor/robot/Editor_FontChoice.html
@@ -9,8 +9,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"></script>
 
 		<!-- functions to help test -->
 		<script type="text/javascript" src="../../helpers.js"></script>
@@ -20,7 +19,7 @@
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_FontChoice.html');
 
 				var editor;		// points to one of the editors (editor0, editor1, etc.)
@@ -32,7 +31,7 @@
 					var edPlugins = editor._plugins, i;
 					for(i = 0; i < edPlugins.length; i++){
 						var p = edPlugins[i];
-						if (p.declaredClass === "dijit._editor.plugins.FontChoice" && p.command == command) {
+						if(p.declaredClass === "dijit._editor.plugins.FontChoice" && p.command == command){
 							return p;
 						}
 					}
@@ -89,15 +88,15 @@
 									doh.robot.mouseMoveAt(editor.iframe, 1000);
 									doh.robot.mouseClick({left:true}, 1000);
 	
-									doh.robot.sequence(d.getTestErrback(function() {
+									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.withGlobal(editor.window, function(){ return dojo.byId(params.id); });
 										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() {
+										dojo.global.dojo.withGlobal(editor.window, function(){
 											dijit._editor.selection.selectElementChildren(node);
 											dijit._editor.selection.collapse(true);
 										});
@@ -159,15 +158,15 @@
 	
 									doh.robot.sequence(d.getTestErrback(function(){
 										// Find node
-										var p = dojo.withGlobal(editor.window, function() { return dojo.byId(params.id); });
+										var p = dojo.withGlobal(editor.window, function(){ return dojo.byId(params.id); });
 										doh.is(params.id, p && p.id, "found node");
 	
-										dojo.global.dojo.withGlobal(editor.window, function() {
+										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) };
+											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
@@ -216,10 +215,10 @@
 							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.withGlobal(editor.window, function(){ return dojo.byId("text"); });
 								doh.is("text", p && p.id, "found text");
 
-								dojo.global.dojo.withGlobal(editor.window, function() {
+								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);
@@ -240,10 +239,10 @@
 
 							// 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.withGlobal(editor.window, function(){ return dojo.byId("text1"); });
 								doh.is("text1", p && p.id, "found text1");
 
-								dojo.global.dojo.withGlobal(editor.window, function() {
+								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);
@@ -301,9 +300,9 @@
 							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.withGlobal(editor.window, function(){ return dojo.byId("text"); });
 								doh.is("text", p && p.id, "found text");
-								dojo.global.dojo.withGlobal(editor.window, function() {
+								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);
@@ -354,9 +353,9 @@
 							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.withGlobal(editor.window, function(){ return dojo.byId("text"); });
 								doh.is("text", p && p.id, "found text");
-								dojo.global.dojo.withGlobal(editor.window, function() {
+								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);
@@ -369,8 +368,8 @@
 							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() {
+								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);
 								});
@@ -378,7 +377,7 @@
 							}), 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"); });
+								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 i;
@@ -429,39 +428,17 @@
 							editor.focus();
 							doh.robot.mouseMoveAt(editor.iframe, 1000);
 							doh.robot.mouseClick({left:true}, 1000);
-							doh.robot.sequence(function(){
-								var i, passed = true, processed = 0;
-								for(i = 0; i < fcPlugin.length; i++){
+							doh.robot.sequence(d.getTestCallback(function(){
+								for(var i = 0; i < fcPlugin.length; i++){
 									var p = fcPlugin[i];
 									var store = p.button.select.store;
-									var onComplete = function(items){
-										try{
-											var j;
-											processed++;
-											for(j = 0; j < items.length; j++){
-												var item = items[j];
-												if(store.getValue(item, "name").indexOf("<") === 0){
-													console.log("failed on: " + store.getValue(item, "name"));
-													passed = false;
-												}
-											}
-											if(processed === fcPlugin.length){
-												if(passed){
-													d.callback(true);
-												}else{
-													d.errback(new Error("Non-plain text label!"));
-												}
-											}
-										}catch(e){
-											d.errback(e);
-										}
-									};
-									var onError = function(err){
-										d.errback(err);
+									var items = store.query();
+									for(var j = 0; j < items.length; j++){
+										var item = items[j];
+										doh.f(item.name.indexOf("<") === 0, "failed on: " + item.name);
 									}
-									store.fetch({query: {name: "*"}, onComplete: onComplete, onError: onError});
 								}
-							}, 1000);
+							}), 1000);
 
 							return d;
 						},
@@ -495,42 +472,23 @@
 							editor.focus();
 							doh.robot.mouseMoveAt(editor.iframe, 1000);
 							doh.robot.mouseClick({left:true}, 1000);
-							doh.robot.sequence(d.getTestErrback(function(){
-								var i, passed = true;
+							doh.robot.sequence(d.getTestCallback(function(){
 								var map = {
 									"sans-serif": false,
 									"serif": false,
 									"cursive": false,
 									"monospace": false,
 									"fantasy": false
-								}
-								var store = fcPlugin.button.select.store;
-								var onComplete = function(items){
-									try{
-										var j;
-										for(j = 0; j < items.length; j++){
-											var item = items[j];
-											map[store.getValue(item, "value")] = true;
-										}
-										for(j in map){
-											if(!map[j]){
-												passed = false;
-												break;
-											}
-										}
-										if(passed){
-											d.callback(true);
-										}else{
-											d.errback(new Error("Did not find all the generic names in the store."));
-										}
-									}catch(e){
-										d.errback(e);
-									}
 								};
-								var onError = function(err){
-									d.errback(err);
+								var store = fcPlugin.button.select.store;
+								var items = store.query();
+								for(var j = 0; j < items.length; j++){
+									var item = items[j];
+									map[item.value] = true;
+								}
+								for(j in map){
+									doh.t(map[j], j);
 								}
-								store.fetch({query: {value: "*"}, onComplete: onComplete, onError: onError});
 							}), 1000);
 
 							return d;
@@ -565,40 +523,21 @@
 							editor.focus();
 							doh.robot.mouseMoveAt(editor.iframe, 1000);
 							doh.robot.mouseClick({left:true}, 1000);
-							doh.robot.sequence(d.getTestErrback(function(){
-								var i, passed = true;
+							doh.robot.sequence(d.getTestCallback(function(){
 								var map = {
 									"Verdana": false,
 									"Myriad": false,
 									"Garamond": false
-								}
-								var store = fcPlugin.button.select.store;
-								var onComplete = function(items){
-									try{
-										var j;
-										for(j = 0; j < items.length; j++){
-											var item = items[j];
-											map[store.getValue(item, "value")] = true;
-										}
-										for(j in map){
-											if(!map[j]){
-												passed = false;
-												break;
-											}
-										}
-										if(passed){
-											d.callback(true);
-										}else{
-											d.errback(new Error("Did not find all the generic names in the store."));
-										}
-									}catch(e){
-										d.errback(e);
-									}
 								};
-								var onError = function(err){
-									d.errback(err);
+								var store = fcPlugin.button.select.store;
+								var items = store.query();
+								for(var j = 0; j < items.length; j++){
+									var item = items[j];
+									map[item.value] = true;
+								}
+								for(j in map){
+									doh.t(map[j], j);
 								}
-								store.fetch({query: {value: "*"}, onComplete: onComplete, onError: onError});
 							}), 1000);
 
 							return d;
diff --git a/dijit/tests/editor/robot/Editor_FullScreen.html b/dijit/tests/editor/robot/Editor_FullScreen.html
index 4ead3ea..5edd206 100644
--- a/dijit/tests/editor/robot/Editor_FullScreen.html
+++ b/dijit/tests/editor/robot/Editor_FullScreen.html
@@ -9,8 +9,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"></script>
 
 		<!-- functions to help test -->
 		<script type="text/javascript" src="../../helpers.js"></script>
@@ -20,7 +19,7 @@
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_FullScreen.html');
 
 				function getPlugin(/*Editor*/ editor){
@@ -61,8 +60,10 @@
 							var d = new doh.Deferred();
 
 							//Focus on the editor window
-							dojo.window.scrollIntoView(editor.domNode);
-							editor.focus();
+							doh.robot.sequence(d.getTestErrback(function(){
+								dojo.window.scrollIntoView(editor.domNode);
+								editor.focus();
+							}), 500);
 
 							doh.robot.keyPress(dojo.keys.F11, 500, {ctrl:true,shift:true});
 
@@ -94,8 +95,10 @@
 							var d = new doh.Deferred();
 
 							//Focus on the editor window
-							dojo.window.scrollIntoView(editor.domNode);
-							editor.focus();
+							doh.robot.sequence(d.getTestErrback(function(){
+								dojo.window.scrollIntoView(editor.domNode);
+								editor.focus();
+							}), 500);
 
 							doh.robot.keyPress(dojo.keys.F11, 500, {ctrl:true,shift:true});
 							doh.robot.keyPress(dojo.keys.F11, 1000, {ctrl:true,shift:true});
@@ -125,8 +128,10 @@
 							var d = new doh.Deferred();
 
 							//Focus on the editor window
-							dojo.window.scrollIntoView(editor.domNode);
-							editor.focus();
+							doh.robot.sequence(d.getTestErrback(function(){
+								dojo.window.scrollIntoView(editor.domNode);
+								editor.focus();
+							}), 500);
 
 							doh.robot.mouseMoveAt(fsPlugin.button.domNode, 500);
 							doh.robot.mouseClick({left: true}, 750);
@@ -159,9 +164,11 @@
 							var d = new doh.Deferred();
 
 							//Focus on the editor window
-							dojo.window.scrollIntoView(editor.domNode);
-							editor.focus();
-							doh.t(fsPlugin != null);
+							doh.robot.sequence(d.getTestErrback(function(){
+								dojo.window.scrollIntoView(editor.domNode);
+								editor.focus();
+							}), 500);
+
 							//Click it, then click it again!
 							doh.robot.mouseMoveAt(fsPlugin.button.domNode, 500);
 							doh.robot.mouseClick({left: true}, 750);
@@ -202,12 +209,14 @@
 							var d = new doh.Deferred();
 
 							//Focus on the editor window
-							dojo.window.scrollIntoView(editor.domNode);
-							editor.focus();
+							doh.robot.sequence(d.getTestErrback(function(){
+								dojo.window.scrollIntoView(editor.domNode);
+								editor.focus();
+							}), 500);
 
 							var origEditorSize = dojo.marginBox(editor.domNode);
 							var origContainerSize = dojo.marginBox(container.domNode);
-							os = {w: origContainerSize.w, h: origContainerSize.h}
+							os = {w: origContainerSize.w, h: origContainerSize.h};
 
 							doh.robot.sequence(d.getTestErrback(function(){
 								// Engage FullScreen Mode
@@ -230,7 +239,7 @@
 								var containerHdiff = origContainerSize.h - curContainerSize.h;
 								var eWdiff = origEditorSize.w - curEditorSize.w;
 								var eHdiff = origEditorSize.h - curEditorSize.h;
-								
+
 								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");
@@ -251,12 +260,14 @@
 							var d = new doh.Deferred();
 
 							//Focus on the editor window
-							dojo.window.scrollIntoView(editor.domNode);
-							editor.focus();
+							doh.robot.sequence(d.getTestErrback(function(){
+								dojo.window.scrollIntoView(editor.domNode);
+								editor.focus();
+							}), 500);
 
 							var origEditorSize = dojo.marginBox(editor.domNode);
 							var origContainerSize = dojo.marginBox(container.domNode);
-							os = {w: origContainerSize.w, h: origContainerSize.h}
+							os = {w: origContainerSize.w, h: origContainerSize.h};
 
 							doh.robot.sequence(d.getTestErrback(function(){
 								// Engage FullScreen Mode
@@ -279,7 +290,7 @@
 								var containerHdiff = -(origContainerSize.h - curContainerSize.h);
 								var eWdiff = -(origEditorSize.w - curEditorSize.w);
 								var eHdiff = -(origEditorSize.h - curEditorSize.h);
-								
+
 								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");
@@ -309,12 +320,14 @@
 							var d = new doh.Deferred();
 
 							//Focus on the editor window
-							dojo.window.scrollIntoView(editor.domNode);
-							editor.focus();
+							doh.robot.sequence(d.getTestErrback(function(){
+								dojo.window.scrollIntoView(editor.domNode);
+								editor.focus();
+							}), 500);
 
 							var origEditorSize = dojo.marginBox(editor.domNode);
 							var origContainerSize = dojo.marginBox(container.domNode);
-							os = {w: origContainerSize.w, h: origContainerSize.h}
+							os = {w: origContainerSize.w, h: origContainerSize.h};
 
 							doh.robot.sequence(d.getTestErrback(function(){
 								// Engage FullScreen Mode
@@ -337,7 +350,7 @@
 								var containerHdiff = origContainerSize.h - curContainerSize.h;
 								var eWdiff = origEditorSize.w - curEditorSize.w;
 								var eHdiff = origEditorSize.h - curEditorSize.h;
-								
+
 								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");
@@ -358,12 +371,14 @@
 							var d = new doh.Deferred();
 
 							//Focus on the editor window
-							dojo.window.scrollIntoView(editor.domNode);
-							editor.focus();
+							doh.robot.sequence(d.getTestErrback(function(){
+								dojo.window.scrollIntoView(editor.domNode);
+								editor.focus();
+							}), 500);
 
 							var origEditorSize = dojo.marginBox(editor.domNode);
 							var origContainerSize = dojo.marginBox(container.domNode);
-							os = {w: origContainerSize.w, h: origContainerSize.h}
+							os = {w: origContainerSize.w, h: origContainerSize.h};
 
 							doh.robot.sequence(d.getTestErrback(function(){
 								// Engage FullScreen Mode
@@ -386,7 +401,7 @@
 								var containerHdiff = -(origContainerSize.h - curContainerSize.h);
 								var eWdiff = -(origEditorSize.w - curEditorSize.w);
 								var eHdiff = -(origEditorSize.h - curEditorSize.h);
-								
+
 								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");
@@ -416,12 +431,14 @@
 							var d = new doh.Deferred();
 
 							//Focus on the editor window
-							dojo.window.scrollIntoView(editor.domNode);
-							editor.focus();
+							doh.robot.sequence(d.getTestErrback(function(){
+								dojo.window.scrollIntoView(editor.domNode);
+								editor.focus();
+							}), 500);
 
 							var origEditorSize = dojo.marginBox(editor.domNode);
 							var origContainerSize = dojo.marginBox(container.domNode);
-							os = {w: origContainerSize.w, h: origContainerSize.h}
+							os = {w: origContainerSize.w, h: origContainerSize.h};
 
 							doh.robot.sequence(d.getTestErrback(function(){
 								// Engage FullScreen Mode
@@ -444,7 +461,7 @@
 								var containerHdiff = origContainerSize.h - curContainerSize.h;
 								var eWdiff = origEditorSize.w - curEditorSize.w;
 								var eHdiff = origEditorSize.h - curEditorSize.h;
-								
+
 								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");
@@ -465,12 +482,14 @@
 							var d = new doh.Deferred();
 
 							//Focus on the editor window
-							dojo.window.scrollIntoView(editor.domNode);
-							editor.focus();
+							doh.robot.sequence(d.getTestErrback(function(){
+								dojo.window.scrollIntoView(editor.domNode);
+								editor.focus();
+							}), 500);
 
 							var origEditorSize = dojo.marginBox(editor.domNode);
 							var origContainerSize = dojo.marginBox(container.domNode);
-							os = {w: origContainerSize.w, h: origContainerSize.h}
+							os = {w: origContainerSize.w, h: origContainerSize.h};
 
 							doh.robot.sequence(d.getTestErrback(function(){
 								// Engage FullScreen Mode
@@ -493,7 +512,7 @@
 								var containerHdiff = -(origContainerSize.h - curContainerSize.h);
 								var eWdiff = -(origEditorSize.w - curEditorSize.w);
 								var eHdiff = -(origEditorSize.h - curEditorSize.h);
-								
+
 								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");
@@ -523,12 +542,14 @@
 							var d = new doh.Deferred();
 
 							//Focus on the editor window
-							dojo.window.scrollIntoView(editor.domNode);
-							editor.focus();
+							doh.robot.sequence(d.getTestErrback(function(){
+								dojo.window.scrollIntoView(editor.domNode);
+								editor.focus();
+							}), 500);
 
 							var origEditorSize = dojo.marginBox(editor.domNode);
 							var origContainerSize = dojo.marginBox(container.domNode);
-							os = {w: origContainerSize.w, h: origContainerSize.h}
+							os = {w: origContainerSize.w, h: origContainerSize.h};
 
 							doh.robot.sequence(d.getTestErrback(function(){
 								// Engage FullScreen Mode
@@ -551,7 +572,7 @@
 								var containerHdiff = origContainerSize.h - curContainerSize.h;
 								var eWdiff = origEditorSize.w - curEditorSize.w;
 								var eHdiff = origEditorSize.h - curEditorSize.h;
-								
+
 								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");
@@ -572,12 +593,14 @@
 							var d = new doh.Deferred();
 
 							//Focus on the editor window
-							dojo.window.scrollIntoView(editor.domNode);
-							editor.focus();
+							doh.robot.sequence(d.getTestErrback(function(){
+								dojo.window.scrollIntoView(editor.domNode);
+								editor.focus();
+							}), 500);
 
 							var origEditorSize = dojo.marginBox(editor.domNode);
 							var origContainerSize = dojo.marginBox(container.domNode);
-							os = {w: origContainerSize.w, h: origContainerSize.h}
+							os = {w: origContainerSize.w, h: origContainerSize.h};
 
 							doh.robot.sequence(d.getTestErrback(function(){
 								// Engage FullScreen Mode
@@ -600,7 +623,7 @@
 								var containerHdiff = -(origContainerSize.h - curContainerSize.h);
 								var eWdiff = -(origEditorSize.w - curEditorSize.w);
 								var eHdiff = -(origEditorSize.h - curEditorSize.h);
-								
+
 								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");
diff --git a/dijit/tests/editor/robot/Editor_LinkDialog.html b/dijit/tests/editor/robot/Editor_LinkDialog.html
index c23fe20..136d023 100644
--- a/dijit/tests/editor/robot/Editor_LinkDialog.html
+++ b/dijit/tests/editor/robot/Editor_LinkDialog.html
@@ -9,8 +9,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"></script>
 
 		<!-- functions to help test -->
 		<script type="text/javascript" src="../../helpers.js"></script>
@@ -20,7 +19,7 @@
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_LinkDialog.html');
 
 				var editor;
@@ -260,7 +259,9 @@
 								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
 
 								oldUrl = url.get("value");
+								doh.is("http://www.example.com/example.html", oldUrl, "old url");
 								oldDesc = desc.get("value");
+								doh.is("This is an example link in the page.", oldDesc, "old desc");
 
 								url.set("value", oldUrl + "_2");
 								desc.set("value", oldDesc + "_2");
@@ -553,23 +554,24 @@
 							doh.robot.mouseClick({left:true}, 100);
 							doh.robot.mouseClick({left:true}, 100);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							var f;
+							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isVisible(ldPlugin.dropDown.domNode),  "tooltip dialog is visible");
-
-								var f = dijit.getFocus();
-								if(f.node){
-									var w = dijit.getEnclosingWidget(f.node);
-									if(w){
-										var val = w.get("value");
-										doh.t(new RegExp("http://www.example.com/example.html").test(val), "Verifying the contents contained link url");
-									}else{
-										doh.t(false, "Failed to enclosing textbox widget.");
-									}
-								}else{
-									doh.t(false, "Failed to get focus.");	
-								}
+								f = dijit.getFocus();
+								doh.isNot(null, f && f.node, "is focus");
+								var w = dijit.getEnclosingWidget(f.node);
+								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.mouseClick({left:true}, 100);
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isVisible(ldPlugin.dropDown.domNode),  "tooltip dialog still visible");
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -701,7 +703,9 @@
 							doh.robot.sequence(d.getTestErrback(function(){
 								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
 								desc = dijit.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);
@@ -836,10 +840,11 @@
 							doh.robot.mouseClick({left:true}, 100);
 							doh.robot.mouseClick({left:true}, 100);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							var f;
+							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isVisible(ldPlugin.dropDown.domNode),  "tooltip dialog is visible");
 
-								var f = dijit.getFocus();
+								f = dijit.getFocus();
 								doh.t(f.node, "got focus");
 
 								var w = dijit.getEnclosingWidget(f.node);
@@ -849,6 +854,13 @@
 								doh.t(new RegExp(".*/sample.jpg").test(val), "Verifying the contents contained image name");
 							}), 2000);
 
+							// Clicking the <input> shouldn't close TooltipDialog (#14395)
+							doh.robot.mouseMoveAt(function(){ return f.node; }, 500, 1);
+							doh.robot.mouseClick({left:true}, 100);
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isVisible(ldPlugin.dropDown.domNode),  "tooltip dialog still visible");
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
diff --git a/dijit/tests/editor/robot/Editor_NewPage.html b/dijit/tests/editor/robot/Editor_NewPage.html
index 33e2c68..d919695 100755
--- a/dijit/tests/editor/robot/Editor_NewPage.html
+++ b/dijit/tests/editor/robot/Editor_NewPage.html
@@ -9,8 +9,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"></script>
 
 		<!-- functions to help test -->
 		<script type="text/javascript" src="../../helpers.js"></script>
@@ -20,7 +19,7 @@
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_NewPage.html');
 
 				function getPlugin(/*Editor*/ editor){
diff --git a/dijit/tests/editor/robot/Editor_ViewSource.html b/dijit/tests/editor/robot/Editor_ViewSource.html
index a2db279..94ab03f 100755
--- a/dijit/tests/editor/robot/Editor_ViewSource.html
+++ b/dijit/tests/editor/robot/Editor_ViewSource.html
@@ -9,8 +9,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"></script>
 
 		<!-- functions to help test -->
 		<script type="text/javascript" src="../../helpers.js"></script>
@@ -20,7 +19,7 @@
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_ViewSource.html');
 
 				var editor0, editor1, editor2, editor3;
@@ -53,7 +52,7 @@
 								}
 							}
 							doh.t(vsPlugin != null, "Checking for VS plugin.");
-							if(vsPlugin) { vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							if(vsPlugin){ vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
@@ -77,7 +76,7 @@
 							return d;
 						},
 						tearDown: function(){
-							 if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							 if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 							 fsPlugin = null;
 							 vsPlugin = null;
 						}
@@ -98,7 +97,7 @@
 								}
 							}
 							doh.t(vsPlugin != null, "Checking that the view source plugin was found.");
-							if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
@@ -122,7 +121,7 @@
 							return d;
 						},
 						tearDown: function(){
-							 if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							 if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						}
 					},
 					{
@@ -139,7 +138,7 @@
 								}
 							}
 							doh.t(vsPlugin != null, "Checking that the view source plugin was found.");
-							if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
@@ -162,7 +161,7 @@
 							return d;
 						},
 						tearDown: function(){
-							 if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							 if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 							 fsPlugin = null;
 							 vsPlugin = null;
 						}
@@ -181,7 +180,7 @@
 								}
 							}
 							doh.t(vsPlugin != null);
-							if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
@@ -206,7 +205,7 @@
 							return d;
 						},
 						tearDown: function(){
-							 if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							 if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 							 fsPlugin = null;
 							 vsPlugin = null;
 						}
@@ -231,8 +230,8 @@
 							}
 							doh.t(vsPlugin != null, "Checking for viewSource plugin.");
 							doh.t(fsPlugin != null, "Checking for fullScreen plugin.");
-							if(fsPlugin) {fsPlugin.button.set("checked", false);}
-							if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							if(fsPlugin){fsPlugin.button.set("checked", false);}
+							if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
@@ -258,8 +257,8 @@
 							return d;
 						},
 						tearDown: function(){
-							 if(fsPlugin) {fsPlugin.button.set("checked", false);}
-							 if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							 if(fsPlugin){fsPlugin.button.set("checked", false);}
+							 if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 							 fsPlugin = null;
 							 vsPlugin = null;
 						}
@@ -284,8 +283,8 @@
 							}
 							doh.t(vsPlugin != null, "Checking for viewSource plugin.");
 							doh.t(fsPlugin != null, "Checking for fullScreen plugin.");
-							if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
-							if(fsPlugin) {fsPlugin.button.set("checked", false);}
+							if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							if(fsPlugin){fsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
@@ -317,8 +316,8 @@
 							return d;
 						},
 						tearDown: function(){
-							 if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
-							 if(fsPlugin) {fsPlugin.button.set("checked", false);}
+							 if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							 if(fsPlugin){fsPlugin.button.set("checked", false);}
 							 fsPlugin = null;
 							 vsPlugin = null;
 						}
@@ -339,7 +338,7 @@
 								}
 							}
 							doh.t(vsPlugin != null, "Checking for VS plugin.");
-							if(vsPlugin) { vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							if(vsPlugin){ vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
@@ -380,7 +379,7 @@
 							return d;
 						},
 						tearDown: function(){
-							 if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							 if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 							 fsPlugin = null;
 							 vsPlugin = null;
 						}
@@ -401,7 +400,7 @@
 								}
 							}
 							doh.t(vsPlugin != null, "Checking for VS plugin.");
-							if(vsPlugin) { vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							if(vsPlugin){ vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
@@ -435,7 +434,7 @@
 							return d;
 						},
 						tearDown: function(){
-							 if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							 if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 							 fsPlugin = null;
 							 vsPlugin = null;
 						}
@@ -456,7 +455,7 @@
 								}
 							}
 							doh.t(vsPlugin != null, "Checking for VS plugin.");
-							if(vsPlugin) { vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							if(vsPlugin){ vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
@@ -492,7 +491,7 @@
 							return d;
 						},
 						tearDown: function(){
-							 if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							 if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 							 fsPlugin = null;
 							 vsPlugin = null;
 						}
@@ -513,7 +512,7 @@
 								}
 							}
 							doh.t(vsPlugin != null, "Checking for VS plugin.");
-							if(vsPlugin) { vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							if(vsPlugin){ vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
@@ -550,7 +549,7 @@
 							return d;
 						},
 						tearDown: function(){
-							 if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							 if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 							 fsPlugin = null;
 							 vsPlugin = null;
 						}
@@ -573,7 +572,7 @@
 								}
 							}
 							doh.t(vsPlugin != null, "Checking for VS plugin.");
-							if(vsPlugin) { vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							if(vsPlugin){ vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							 var d = new doh.Deferred();
@@ -611,7 +610,7 @@
 							return d;
 						},
 						tearDown: function(){
-							 if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							 if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 							 fsPlugin = null;
 							 vsPlugin = null;
 						}
@@ -632,7 +631,7 @@
 								}
 							}
 							doh.t(vsPlugin != null, "Checking for VS plugin.");
-							if(vsPlugin) { vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							if(vsPlugin){ vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
@@ -685,7 +684,7 @@
 							return d;
 						},
 						tearDown: function(){
-							 if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							 if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 							 fsPlugin = null;
 							 vsPlugin = null;
 						}
@@ -705,7 +704,7 @@
 									break;
 								}
 							}
-							if(vsPlugin) { vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							if(vsPlugin){ vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							 var d = new doh.Deferred();
@@ -729,7 +728,7 @@
 							return d;
 						},
 						tearDown: function(){
-							 if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							 if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 							 fsPlugin = null;
 							 vsPlugin = null;
 						}
@@ -751,7 +750,7 @@
 								}
 							}
 							doh.t(vsPlugin != null, "Checking for VS plugin.");
-							if(vsPlugin) { vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							if(vsPlugin){ vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
@@ -779,7 +778,7 @@
 							return d;
 						},
 						tearDown: function(){
-							if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 							editor0.set("value", value); 
 							fsPlugin = null;
 							vsPlugin = null;
diff --git a/dijit/tests/editor/robot/Editor_a11y.html b/dijit/tests/editor/robot/Editor_a11y.html
index 0eddfa4..14c529a 100644
--- a/dijit/tests/editor/robot/Editor_a11y.html
+++ b/dijit/tests/editor/robot/Editor_a11y.html
@@ -9,8 +9,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"></script>
 
 		<!-- functions to help test -->
 		<script type="text/javascript" src="../../helpers.js"></script>
@@ -31,12 +30,12 @@
 					replace(new RegExp(String.fromCharCode(160), "g"), " ");	// Safari: nbsp (char code 160) to normal space (char code 32)
 			}
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Editor.html');
 
 				// For some reason the meta key (meta-a for selection, meta-b for bold, etc) doesn't work
 				// on mac/safari... use ctrl- instead, just like on windows. (#9553)
-				var metaKey = {ctrl: true}
+				var metaKey = {ctrl: true};
 
 				var editor0,
 					editor1, editor1oldValue, editor1newValue, editor1onChange = "no onchange event yet";
@@ -277,7 +276,7 @@
 							// on whether the editor's contents have been modified (undo button enabled), and
 							// whether there is something in the browser's paste buffer, etc.)
 							doh.robot.sequence(d.getTestCallback(function(){
-								var curFocus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
+								var curFocus = dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode);
 								doh.isNot(-1, dojo.indexOf(editor1.toolbar.getChildren(), curFocus), "focused on button of editor1 toolbar");
 							}), 500);
 
@@ -294,7 +293,7 @@
 							doh.robot.keyPress(dojo.keys.TAB, 500);
 
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("editor1_iframe", dojo.global.dijit._curFocus.id, "focused on editor content");
+								doh.is("editor1_iframe", dojo.global.dijit.focus.curNode.id, "focused on editor content");
 							}), 500);
 
 							doh.robot.keyPress("a", 500, metaKey);	// select all
@@ -317,7 +316,7 @@
 							doh.robot.keyPress(dojo.keys.TAB, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("focusAfter", dojo.global.dijit._curFocus.id, "focused after editor1");
+								doh.is("focusAfter", dojo.global.dijit.focus.curNode.id, "focused after editor1");
 								
 								doh.is("tabbing test", editor1newValue, "watch()");
 								doh.is("tabbing test", editor1onChange, "onChange");
@@ -336,7 +335,7 @@
 							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("editor1_iframe", dojo.global.dijit._curFocus.id, "focused on editor content");
+								doh.is("editor1_iframe", dojo.global.dijit.focus.curNode.id, "focused on editor content");
 							}), 500);
 
 							return d;
@@ -351,7 +350,7 @@
 							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								var curFocus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
+								var curFocus = dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode);
 								doh.isNot(-1, dojo.indexOf(editor1.toolbar.getChildren(), curFocus), "focused on button of editor1 toolbar");
 							}), 500);
 
@@ -367,7 +366,7 @@
 							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("focusBefore", dojo.global.dijit._curFocus.id, "focused before editor1");
+								doh.is("focusBefore", dojo.global.dijit.focus.curNode.id, "focused before editor1");
 							}), 500);
 
 							return d;
diff --git a/dijit/tests/editor/robot/Editor_misc.html b/dijit/tests/editor/robot/Editor_misc.html
index 11b4c65..53282b5 100755
--- a/dijit/tests/editor/robot/Editor_misc.html
+++ b/dijit/tests/editor/robot/Editor_misc.html
@@ -9,8 +9,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"></script>
 
 		<!-- functions to help test -->
 		<script type="text/javascript" src="../../helpers.js"></script>
@@ -20,7 +19,7 @@
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Editor.html');
 				var editor0;
 				var height;
@@ -71,7 +70,7 @@
 						timeout: 3000,
 						runTest: function(){
 							var d = new doh.Deferred();
-								editor1.removeStyleSheet('test_editor.css')
+								editor1.removeStyleSheet('test_editor.css');
 
 							setTimeout(d.getTestCallback(function(){
 								var editorNodeText = editor1.editNode.firstChild;
@@ -264,6 +263,40 @@
 						tearDown: function(){
 							if(editor0){editor0.set("value", value);}
 						}
+					},
+					{
+						name: "Test page up/down.",
+						timeout: 4000,
+						setUp: function(){
+							editor0 = dijit.byId("editor0");
+							value = editor0.get("value");
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor0.domNode);
+							doh.robot.sequence(d.getTestErrback(function(){
+								editor0.focus();
+							}), 500);
+							
+							doh.robot.keyPress(dojo.keys.PAGE_UP, 500);
+							doh.robot.typeKeys("abc", 500);
+							doh.robot.keyPress(dojo.keys.PAGE_DOWN, 500);
+							doh.robot.typeKeys("def", 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								var value = editor0.get("value");
+								if(!dojo.isWebKit){	// commented out due to #14193
+									doh.t(value.indexOf("abcdef") == 0, "editor value = " + value);
+								}
+							}), 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 07b0cad..1130ad7 100644
--- a/dijit/tests/editor/robot/Editor_mouse.html
+++ b/dijit/tests/editor/robot/Editor_mouse.html
@@ -9,8 +9,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"></script>
 
 		<!-- functions to help test -->
 		<script type="text/javascript" src="../../helpers.js"></script>
@@ -31,12 +30,12 @@
 					replace(new RegExp(String.fromCharCode(160), "g"), " ");	// Safari: nbsp (char code 160) to normal space (char code 32)
 			}
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.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)
-				var metaKey = {ctrl: true}
+				var metaKey = {ctrl: true};
 
 				var editor0, editor1;
 
diff --git a/dijit/tests/editor/robot/EnterKeyHandling.html b/dijit/tests/editor/robot/EnterKeyHandling.html
index 4891afc..5a30fcc 100644
--- a/dijit/tests/editor/robot/EnterKeyHandling.html
+++ b/dijit/tests/editor/robot/EnterKeyHandling.html
@@ -9,8 +9,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"></script>
 
 		<!-- functions to help test -->
 		<script type="text/javascript" src="../../helpers.js"></script>
@@ -55,7 +54,7 @@
 				return out.join("");
 			}
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../EnterKeyHandling.html');
 
 				var metaKey = dojo.isMac? {meta: true} : {ctrl: true};
@@ -207,11 +206,11 @@
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(function(){
-                                editor._sCall("selectElementChildren", [node]);
+								editor._sCall("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, {}); }
+							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);
 
@@ -244,11 +243,11 @@
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(function(){
-                                editor._sCall("selectElementChildren", [node]);
+								editor._sCall("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, {}); }
+							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);
 
@@ -281,11 +280,11 @@
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(function(){
-                                editor._sCall("selectElementChildren", [node]);
+								editor._sCall("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, {}); }
+							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);
 
@@ -326,8 +325,7 @@
 							doh.robot.sequence(d.getTestCallback(function(){
 								var value = editor.get('value');
 								value = value.replace(/\xA0/g, "");
-								var expVal = dojo.isWebKit? 'testingCopyAndPastetestingCopyAndPastetestingCopyAndPaste<div></div>' : '<div>testingCopyAndPastetestingCopyAndPastetestingCopyAndPaste</div><div></div>';
-								doh.is(expVal,
+								doh.is('<div>testingCopyAndPastetestingCopyAndPastetestingCopyAndPaste</div><div></div>',
 										value,
 										"get('value')");
 							}), 1000);
@@ -365,8 +363,8 @@
 								// paragraphs.
 								var value = editor.get('value');
 								value = value.replace(/\xA0/g, "");
-								var expVal = dojo.isWebKit? 'testingCopyAndPastetestingCopyAndPastetestingCopyAndP<div>aste</div>' : '<div>testingCopyAndPastetestingCopyAndPastetestingCopyAndP</div><div>aste</div>';
-								doh.is(expVal,
+
+								doh.is('<div>testingCopyAndPastetestingCopyAndPastetestingCopyAndP</div><div>aste</div>',
 									value,
 									"get('value')");
 							}), 1000);
@@ -390,11 +388,11 @@
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(function(){
-                                editor._sCall("selectElementChildren", [node]);
+								editor._sCall("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, {}); }
+							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);
 
@@ -410,6 +408,29 @@
 						}
 					},
 					{
+						name: "shift enter to replace all content in p",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var editor = dijit.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);
+							});
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {shift: true});
+							doh.robot.sequence(d.getTestCallback(function(){
+								var val = editor.get("value");
+								doh.is(val, '<p><br /></p>');
+							}), 1000);
+							return d;
+						}
+					},
+					{
 						name: "copy and paste P",
 						timeout: 10000,
 						runTest: function(){
diff --git a/dijit/tests/editor/robot/TabIndent.html b/dijit/tests/editor/robot/TabIndent.html
index 06dc319..7d57f38 100644
--- a/dijit/tests/editor/robot/TabIndent.html
+++ b/dijit/tests/editor/robot/TabIndent.html
@@ -9,8 +9,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"></script>
 
 		<script type="text/javascript" src="../../helpers.js"></script>
 
@@ -18,10 +17,10 @@
 			dojo.require("dojo.DeferredList");
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_TabIndent.html');
 					
-				var metaKey = {ctrl: true}
+				var metaKey = {ctrl: true};
 					
 				doh.register("testTabIndent", [
 					{
diff --git a/dijit/tests/editor/robot/ToggleDir.html b/dijit/tests/editor/robot/ToggleDir.html
index b7e27d3..3084060 100644
--- a/dijit/tests/editor/robot/ToggleDir.html
+++ b/dijit/tests/editor/robot/ToggleDir.html
@@ -9,8 +9,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"></script>
 
 		<script type="text/javascript" src="../../helpers.js"></script>
 
@@ -18,10 +17,10 @@
 			dojo.require("dojo.DeferredList");
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_ToggleDir.html');
 					
-				var metaKey = {ctrl: true}
+				var metaKey = {ctrl: true};
 					
 				doh.register("testToggleDir", [
 					{
diff --git a/dijit/tests/editor/robot/ToggleDir_rtl.html b/dijit/tests/editor/robot/ToggleDir_rtl.html
index a85277b..d010596 100644
--- a/dijit/tests/editor/robot/ToggleDir_rtl.html
+++ b/dijit/tests/editor/robot/ToggleDir_rtl.html
@@ -9,8 +9,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"></script>
 
 		<script type="text/javascript" src="../../helpers.js"></script>
 
@@ -18,10 +17,10 @@
 			dojo.require("dojo.DeferredList");
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_ToggleDir_rtl.html');
 					
-				var metaKey = {ctrl: true}
+				var metaKey = {ctrl: true};
 					
 				doh.register("testToggleDir", [
 					{
diff --git a/dijit/tests/editor/test_CustomPlugin.html b/dijit/tests/editor/test_CustomPlugin.html
index 7b82f02..c093120 100644
--- a/dijit/tests/editor/test_CustomPlugin.html
+++ b/dijit/tests/editor/test_CustomPlugin.html
@@ -5,7 +5,7 @@
 	<title>Editor Custom Plugin Test/Tutorial</title>
 
 	<style type="text/css">
-		@import "../themes/claro/document.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 	</style>
 
@@ -37,7 +37,7 @@
 		dojo.require("dijit._editor._Plugin");
 		dojo.require("dojo.string");
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			dojo.declare("MyPlugin",
 				dijit._editor._Plugin,
 				{
@@ -66,6 +66,7 @@
 							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));
@@ -77,6 +78,7 @@
 						}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
@@ -97,7 +99,7 @@
 	</script>
 </head>
 <body class="claro">
-	<div id="editor1" data-dojo-type="dijit.Editor" data-dojo-props='extraPlugins:["MyPlugin"]'><p>
+	<div id="editor1" data-dojo-type="dijit.Editor" data-dojo-props='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 c6f09c4..d421a89 100644
--- a/dijit/tests/editor/test_Editor.html
+++ b/dijit/tests/editor/test_Editor.html
@@ -30,7 +30,7 @@
 		dojo.require("dijit._editor.plugins.LinkDialog");
 		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			// 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], {
@@ -51,8 +51,8 @@
 				value: "Custom Initial Content."
 			}, "programmatic3");
 
-			var progEditor = new dijit.Editor({
-				contentPreFilters: [function(txt) { return txt; }]		
+			var progEditor2 = new dijit.Editor({
+				contentPreFilters: [function(txt){ return txt; }]
 			}, "programmatic4");
 		});
 
@@ -78,7 +78,7 @@
 				setTimeout(function(){ try {
 					dijit.byId('automated').document.execCommand('bold', false, false);
 					document.getElementById('disabledOK').checked = (dijit.byId('automated').document.queryCommandState('bold') == false);
-				} catch(e) { document.getElementById('disabledOK').checked = true; }}, 0);
+				}catch(e){ document.getElementById('disabledOK').checked = true; }}, 0);
 			}
 		</script
 		><script type='dojo/method' data-dojo-event='onChange'>
diff --git a/dijit/tests/editor/test_LinkDialog.html b/dijit/tests/editor/test_LinkDialog.html
index 66f2a5c..0024fb0 100755
--- a/dijit/tests/editor/test_LinkDialog.html
+++ b/dijit/tests/editor/test_LinkDialog.html
@@ -28,7 +28,7 @@
 		<div id="editor" data-dojo-type="dijit.Editor" data-dojo-props='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 qriting their own, more complex, link and image handlers
+				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>
diff --git a/dijit/tests/editor/test_ToggleDir_rtl.html b/dijit/tests/editor/test_ToggleDir_rtl.html
index ab8de26..a5a17be 100755
--- a/dijit/tests/editor/test_ToggleDir_rtl.html
+++ b/dijit/tests/editor/test_ToggleDir_rtl.html
@@ -24,7 +24,7 @@
 	</script>
 </head>
 <body class="claro" dir="rtl">
-<div style="position:absolute;left:0px;" id=dummy>Text</div>
+<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"}]'>
 			<ol><li>the toggleDir plugin provides an extra button to switch text direction (BiDi). Useful when right-to-left 
diff --git a/dijit/tests/editor/test_ViewSource.html b/dijit/tests/editor/test_ViewSource.html
index 0da4f18..3bbc6ed 100755
--- a/dijit/tests/editor/test_ViewSource.html
+++ b/dijit/tests/editor/test_ViewSource.html
@@ -30,7 +30,7 @@
 	<br>
 	<div>
 		<div id="editor0" data-dojo-type="dijit.Editor"
-			data-dojo-props='extraPlugins:["viewsource"], style:"background-color: white; width: 800px;", height:"400px" '>
+			data-dojo-props='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
@@ -61,7 +61,7 @@
 	<br>
 	<div>
 		<div id="editor1" data-dojo-type="dijit.Editor"
-			data-dojo-props='extraPlugins:["fullscreen","viewsource"], style:"background-color: white; width: 800px;", height:"300px" '>
+			data-dojo-props='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>
@@ -78,7 +78,7 @@
 	<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" '>
+			data-dojo-props='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>
@@ -94,7 +94,7 @@
 	<br>
 	<div>
 		<div id="editor3" data-dojo-type="dijit.Editor"
-			data-dojo-props='extraPlugins:["fullscreen",{name: "viewsource", stripScripts: false, stripComments: false, stripIFrames: false}],
+			data-dojo-props='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/focus-framedojo-child.html b/dijit/tests/focus-framedojo-child.html
new file mode 100644
index 0000000..11081fe
--- /dev/null
+++ b/dijit/tests/focus-framedojo-child.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Focus Issue Child</title>
+	<script>
+	// open the parent, if user tries to open the child directly
+	if (parent == window)
+		location.href = './focus-framedojo.html';
+	</script>
+	<script type="text/javascript" src="../../dojo/dojo.js"
+		data-dojo-config="isDebug:true"></script>
+	<script type="text/javascript">
+		dojo.require("dijit.focus");
+		dojo.require("doh.runner");
+
+		// set objects in parent
+		for (var v in {'dijit':true, 'dojo':true, 'dojox':true})
+			parent[v] = window[v];
+
+		// This will execute before the dojo.ready() code in dijit.focus() executes
+		dojo.setContext(parent, parent.document);
+
+		dojo.ready(function(){
+			doh.register("focus", function focus(){
+				var d = new doh.Deferred();
+				doh.is("input", dojo.byId("input").id, "found input");
+
+				dijit.focus.watch("curNode", function(attr, oldVal, newVal){
+					console.log("focused on ", newVal);
+					if(!newVal){
+						return;	// IE gives spurious event
+					}
+					d.getTestCallback(function(){
+						doh.is("input", newVal.id, "notified that focused on input");
+					})();
+				});
+
+				dojo.byId("input").focus();
+
+				return d;
+			});
+
+			doh.run();
+		});
+	</script>
+</head>
+<body bgcolor="#e0e0e0">
+	this frame is for loading script only
+</body>
+</html>
diff --git a/dijit/tests/focus-framedojo.html b/dijit/tests/focus-framedojo.html
new file mode 100644
index 0000000..6e46cb9
--- /dev/null
+++ b/dijit/tests/focus-framedojo.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Focus Issue</title>
+	<style type="text/css">
+		@import "../themes/claro/claro.css";
+	</style>
+</head>
+<body class="claro">
+	<p>
+		Test case for focus code when dojo is loaded into an iframe.
+		Not supported officially but checking in test case anyway.
+	</p>
+
+	<p>Automated test will focus this input, causing a console message:</p>
+	<input id="input">
+
+	<p>Dojo is loaded into this iframe:</p>
+	<iframe style="width:100%;height:2em;" src="./focus-framedojo-child.html"></iframe>
+</body>
+</html>
diff --git a/dijit/tests/form/AutoCompleterMixin.html b/dijit/tests/form/AutoCompleterMixin.html
new file mode 100644
index 0000000..5958b79
--- /dev/null
+++ b/dijit/tests/form/AutoCompleterMixin.html
@@ -0,0 +1,286 @@
+<!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>_AutoCompleterMixin tests</title>
+
+	<style type="text/css">
+		@import "../../themes/claro/document.css";
+		@import "../../themes/dijit.css";
+		@import "../../themes/claro/claro.css";
+		@import "../../../dojox/mobile/themes/iphone/TextBox.css";
+		@import "../../../dojox/mobile/themes/iphone/ComboBox.css";
+
+		#table {
+			margin: 0;
+			padding: 2px;
+		}
+		#table .layout {
+			padding: 2px;
+			font-size: 100%;
+			margin: 0;
+		}
+	</style>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
+
+	<script type="text/javascript">
+		dojo.require("doh.runner");
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.form.DataList");
+		dojo.require("dijit.form.ComboBox");
+		dojo.require("dojox.mobile.ComboBox");
+
+		dojo.ready(function(){
+
+			doh.register("attributes", [
+				{
+					name: "dijit",
+					runTest: function(){
+						var dijit_attributes = dijit.byId('dijit_attributes');
+						doh.is("", dijit_attributes.textbox.value, "dijit original value");
+						doh.is("", dijit_attributes.get('value'), "dijit original get('value')");
+						doh.is(Infinity, dijit_attributes.get('pageSize'), "dijit original get('pageSize')");
+						dijit_attributes.set('pageSize', 9);
+						dijit_attributes.set('value', "test");
+						doh.is("test", dijit_attributes.textbox.value, "dijit value");
+						doh.is("test", dijit_attributes.get('value'), "dijit get('value')");
+						doh.is(9, dijit_attributes.get('pageSize'), "dijit get('pageSize')");
+					}
+	 			},
+				{
+					name: "mobile",
+					runTest: function(){
+						var mobile_attributes = dijit.byId('mobile_attributes');
+						doh.is("", mobile_attributes.textbox.value, "mobile original value");
+						doh.is("", mobile_attributes.get('value'), "mobile original get('value')");
+						doh.is(Infinity, mobile_attributes.get('pageSize'), "mobile original get('pageSize')");
+						mobile_attributes.set('pageSize', 9);
+						mobile_attributes.set('value', "test");
+						doh.is("test", mobile_attributes.textbox.value, "mobile value");
+						doh.is("test", mobile_attributes.get('value'), "mobile get('value')");
+						doh.is(9, mobile_attributes.get('pageSize'), "mobile get('pageSize')");
+					}
+	 			}
+			]);
+
+			doh.register("events", [
+				{
+					name: "dijit",
+					timeout: 2000,
+					runTest: function(){
+						var
+							d = new doh.Deferred(),
+							dijit_events = dijit.byId('dijit_events'),
+							nop = function(){ return false; };
+
+						function onFocus(){
+							dijit_events.set('onFocus', nop);
+							dijit_events.set('displayedValue', "Focus");
+							dijit_events.set('onChange', onChange);
+							dijit_events.set('onBlur', onBlur);
+							dijit.byId('mobile_events').focus();
+						}
+						function onBlur(){
+							dijit_events.set('onBlur', nop);
+							dijit_events.set('displayedValue', dijit_events.get('displayedValue')+"Blur");
+						}
+						function onChange(){
+							dijit_events.set('onChange', nop);
+							dijit_events.set('displayedValue', dijit_events.get('displayedValue')+"Change");
+							dijit_events.focus();
+							d.getTestCallback(function(){
+								doh.is("FocusBlurChange", dijit_events.textbox.value);
+							})();
+						}
+						doh.is(nop.toString(), dijit_events.get('onFocus').toString(), "get('onFocus')");
+						doh.is(nop.toString(), dijit_events.get('onBlur').toString(), "get('onBlur')");
+						doh.is(nop.toString(), dijit_events.get('onChange').toString(), "get('onChange')");
+						dijit_events.set('onFocus', onFocus);
+						setTimeout(dojo.hitch(dijit_events, "focus"), 0);
+
+						return d;
+					}
+	 			},
+				{
+					name: "mobile",
+					timeout: 2000,
+					runTest: function(){
+						var
+							d = new doh.Deferred(),
+							mobile_events = dijit.byId('mobile_events'),
+							focusHandle, blurhandle,
+							nop = function(){ return false; };
+
+						function onFocus(){
+							mobile_events.disconnect(focusHandle);
+							mobile_events.set('displayedValue', "Focus");
+							mobile_events.set('onChange', onChange);
+							blurhandle = mobile_events.connect(mobile_events.textbox, 'onblur', onBlur);
+							dijit.byId('dijit_events').focus();
+						}
+						function onBlur(){
+							mobile_events.disconnect(blurhandle);
+							mobile_events.set('displayedValue', mobile_events.get('displayedValue')+"Blur");
+						}
+						function onChange(){
+							mobile_events.set('onChange', nop);
+							mobile_events.set('displayedValue', mobile_events.get('displayedValue')+"Change");
+							mobile_events.focus();
+							d.getTestCallback(function(){
+								doh.is("FocusBlurChange", mobile_events.textbox.value);
+							})();
+						}
+						doh.is(nop.toString(), mobile_events.get('onChange').toString(), "get('onChange')");
+						focusHandle = mobile_events.connect(mobile_events.textbox, 'onfocus', onFocus);
+						setTimeout(dojo.hitch(mobile_events, "focus"), 0);
+
+						return d;
+					}
+	 			}
+			]);
+
+			doh.register("programmatic", [
+				{
+					name: "dijit",
+					timeout: 2000,
+					runTest: function(){
+						new dijit.form.ComboBox({id:"dijit_programmatic", list:"states"}).placeAt("dijit_programmatic_container", "first");
+						var dijit_programmatic = dijit.byId('dijit_programmatic');
+						var focushandle = dijit_programmatic.connect(dijit_programmatic, '_onFocus',
+							function(){
+								d.getTestCallback(function(){
+									dijit_programmatic.disconnect(focushandle);
+									var pos = dojo.position(dijit_programmatic.domNode, true);
+									doh.t(pos.w > 0 && pos.h > 0 && pos.x > 0 && pos.y > 0, 'dijit position');
+									doh.is("Alabama", dijit_programmatic.textbox.value, 'dijit textbox value');
+									doh.is("Alabama", dijit_programmatic.get('value'), 'dijit widget value');
+								})();
+							}
+						);
+						var d = new doh.Deferred();
+						setTimeout(dojo.hitch(dijit_programmatic, "focus"), 0);
+						return d;
+					}
+	 			},
+				{
+					name: "mobile",
+					timeout: 2000,
+					runTest: function(){
+						new dojox.mobile.ComboBox({id:"mobile_programmatic", list:"states"}).placeAt("mobile_programmatic_container", "first");
+						var mobile_programmatic = dijit.byId('mobile_programmatic');
+						var focushandle = mobile_programmatic.connect(mobile_programmatic.textbox, 'onfocus',
+							function(){
+								d.getTestCallback(function(){
+									mobile_programmatic.disconnect(focushandle);
+									var pos = dojo.position(mobile_programmatic.domNode, true);
+									doh.t(pos.w > 0 && pos.h > 0 && pos.x > 0 && pos.y > 0, 'mobile position');
+									doh.is("Alabama", mobile_programmatic.textbox.value, 'mobile textbox value');
+									doh.is("Alabama", mobile_programmatic.get('value'), 'mobile widget value');
+								})();
+							}
+						);
+						var d = new doh.Deferred();
+						setTimeout(dojo.hitch(mobile_programmatic, "focus"), 0);
+						return d;
+					}
+	 			}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+	<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"' >
+		<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">
+		<tr>
+			<th class="layout"> </th>
+			<th class="layout">dijit</th>
+			<th class="layout">mobile</th>
+		</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>
+		</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>
+		</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>
+</body>
+</html>
diff --git a/dijit/tests/form/ButtonMixin.html b/dijit/tests/form/ButtonMixin.html
new file mode 100644
index 0000000..d9eaa2b
--- /dev/null
+++ b/dijit/tests/form/ButtonMixin.html
@@ -0,0 +1,168 @@
+<!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>_ButtonMixin tests</title>
+
+	<style type="text/css">
+		@import "../../themes/claro/document.css";
+		@import "../../themes/dijit.css";
+
+		#table {
+			margin: 0;
+			padding: 2px;
+		}
+		#table, .dijit, BUTTON {
+			font-family: monospace;
+			font-size: 12pt;
+		}
+		#table .layout {
+			padding: 2px;
+			font-size: 100%;
+			margin: 0;
+		}
+	</style>
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
+
+	<script type="text/javascript">
+		dojo.require("doh.runner");
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.form.Button");
+		dojo.require("dojox.mobile.Button");
+
+		dojo.ready(function(){
+
+			doh.register("attributes", [
+				{
+					name: "dijit",
+					runTest: function(){
+						var dijit_attributes = dijit.byId('dijit_attributes');
+						doh.is("original", dijit_attributes.get('label'), "dijit original get('label')");
+						dijit_attributes.set('label', "label");
+						doh.is("label", dijit_attributes.get('label'), "dijit get('label')");
+						doh.t(dojo.hasClass(dijit_attributes.domNode, dijit_attributes.baseClass), "dijit baseClass");
+						doh.t(dojo.hasClass(dijit_attributes.domNode, "mblRedButton"), "dijit original class");
+						dijit_attributes.set('class', "mblBlueButton");
+						doh.t(dojo.hasClass(dijit_attributes.domNode, "mblBlueButton"), "dijit new class");
+					}
+	 			},
+				{
+					name: "mobile",
+					runTest: function(){
+						var mobile_attributes = dijit.byId('mobile_attributes');
+						doh.is("original", mobile_attributes.get('label'), "mobile original get('label')");
+						mobile_attributes.set('label', "label");
+						doh.is("label", mobile_attributes.get('label'), "mobile get('label')");
+						doh.t(dojo.hasClass(mobile_attributes.domNode, mobile_attributes.baseClass), "mobile baseClass");
+						doh.t(dojo.hasClass(mobile_attributes.domNode, "mblRedButton"), "mobile original class");
+						mobile_attributes.set('class', "mblBlueButton");
+						doh.t(dojo.hasClass(mobile_attributes.domNode, "mblBlueButton"), "mobile new class");
+					}
+	 			}
+			]);
+
+			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",
+					timeout: 2000,
+					runTest: function(){
+						new dijit.form.Button({id:"dijit_programmatic", type:"button", label:"No srcNodeRef"}).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');
+						doh.is("No srcNodeRef", dijit_programmatic.get('label'), 'dijit widget label');
+					}
+	 			},
+				{
+					name: "mobile",
+					timeout: 2000,
+					runTest: function(){
+						new dojox.mobile.Button({id:"mobile_programmatic", type:"button", label:"No srcNodeRef"}).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');
+						doh.is("No srcNodeRef", mobile_programmatic.get('label'), 'mobile widget label');
+					}
+	 			}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+	<h1 class="testTitle">_ButtonMixin (dijit and mobile) non-robot tests</h1>
+
+	<table id="table">
+		<tr>
+			<th class="layout"> </th>
+			<th class="layout">dijit</th>
+			<th class="layout">mobile</th>
+		</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"><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>
+</body>
+</html>
diff --git a/dijit/tests/form/CheckBoxMixin.html b/dijit/tests/form/CheckBoxMixin.html
new file mode 100644
index 0000000..d1fa521
--- /dev/null
+++ b/dijit/tests/form/CheckBoxMixin.html
@@ -0,0 +1,295 @@
+<!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>_CheckBoxMixin tests</title>
+
+	<style type="text/css">
+		@import "../../themes/claro/document.css";
+		@import "../../themes/dijit.css";
+
+		#table {
+			margin: 0;
+			padding: 2px;
+		}
+		#table, .dijit, BUTTON {
+			font-family: monospace;
+			font-size: 12pt;
+		}
+		#table .layout {
+			padding: 2px;
+			font-size: 100%;
+			margin: 0;
+		}
+		INPUT#mobile_attributes {
+			-webkit-appearance: radio;
+			width:32px;
+			height:32px;
+			border-radius: 0;
+		}
+		INPUT#mobile_events:not(:checked){
+			background-color:rgba(255,0,0,1);
+			border-radius: 32px;
+		}
+		INPUT#mobile_events {
+			width:32px;
+			height:32px;
+			background-color:rgba(0,0,255,1);
+			border-radius: 32px;
+		}
+		INPUT#mobile_programmatic {
+			width:32px;
+			height:32px;
+			background-color:rgba(0,0,0,0);
+			border:0 none rgba(0,0,0,0);
+			border-radius: 0;
+		}
+		INPUT#mobile_programmatic:not(:checked){
+			opacity:0;
+		}
+		.dijitCheckBox {
+			vertical-align: baseline !important;
+		}
+	</style>
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
+
+	<script type="text/javascript">
+		dojo.require("doh.runner");
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.form.CheckBox");
+		dojo.require("dojox.mobile.CheckBox");
+
+		dojo.ready(function(){
+
+			doh.register("attributes", [
+				{
+					name: "dijit",
+					runTest: function(){
+						var dijit_attributes = dijit.byId('dijit_attributes');
+						doh.is("something", dijit_attributes.focusNode.value, 'dijit HTML element original value');
+						doh.t(dijit_attributes.get('checked'), "dijit original get('checked')");
+						doh.t(!!dijit_attributes.focusNode.checked, 'dijit HTML element originally checked');
+						doh.t(dojo.hasClass(dijit_attributes.domNode, dijit_attributes.baseClass+"Checked"), "dijit baseClass checked");
+						dijit_attributes.set('value', "something else");
+						dijit_attributes.set('checked', false);
+						doh.f(dijit_attributes.get('checked'), "dijit get('checked')");
+						doh.t(!dijit_attributes.focusNode.checked, 'dijit HTML element unchecked');
+						doh.f(dojo.hasClass(dijit_attributes.domNode, dijit_attributes.baseClass+"Checked"), "dijit baseClass not checked");
+						doh.t(dojo.hasClass(dijit_attributes.domNode, dijit_attributes.baseClass), "dijit baseClass");
+						doh.t(dojo.hasClass(dijit_attributes.domNode, "mblRedButton"), "dijit original class");
+						doh.is("something else", dijit_attributes.focusNode.value, 'dijit HTML element value');
+					}
+	 			},
+				{
+					name: "mobile",
+					runTest: function(){
+						var mobile_attributes = dijit.byId('mobile_attributes');
+						doh.is("something", mobile_attributes.focusNode.value, 'mobile HTML element original value');
+						doh.t(mobile_attributes.get('checked'), "mobile original get('checked')");
+						doh.t(!!mobile_attributes.focusNode.checked, 'mobile HTML element originally checked');
+						doh.t(dojo.hasClass(mobile_attributes.domNode, mobile_attributes.baseClass+"Checked"), "mobile baseClass checked");
+						mobile_attributes.set('checked', false);
+						mobile_attributes.set('value', "something else");
+						doh.f(mobile_attributes.get('checked'), "mobile get('checked')");
+						doh.t(!mobile_attributes.focusNode.checked, 'mobile HTML element unchecked');
+						doh.f(dojo.hasClass(mobile_attributes.domNode, mobile_attributes.baseClass+"Checked"), "mobile baseClass not checked");
+						doh.t(dojo.hasClass(mobile_attributes.domNode, mobile_attributes.baseClass), "mobile baseClass");
+						doh.t(dojo.hasClass(mobile_attributes.domNode, "mblRedButton"), "mobile original class");
+						doh.is("something else", mobile_attributes.focusNode.value, 'mobile HTML element value');
+					}
+	 			}
+			]);
+
+			doh.register("events", [
+				{
+					name: "dijit",
+					timeout: 2000,
+					runTest: function(){
+						var
+							d = new doh.Deferred(),
+							dijit_events = dijit.byId('dijit_events'),
+							calledOnClick = false,
+							nop = function(){ return false; };
+
+						function onChange(v){
+							dijit_events.set('onChange', nop);
+							d.callback(true);
+						}
+						dijit_events.set('onChange', onChange);
+						dijit_events._onClick({ preventDefault: nop });
+
+						return d;
+					}
+	 			},
+				{
+					name: "mobile",
+					timeout: 2000,
+					runTest: function(){
+						var
+							d = new doh.Deferred(),
+							mobile_events = dijit.byId('mobile_events'),
+							nop = function(){ return false; };
+
+						function onChange(){
+							mobile_events.set('onChange', nop);
+							d.callback(true);
+						}
+						mobile_events.set("onChange", onChange);
+						setTimeout(function(){ mobile_events.focusNode.click({ preventDefault: nop }); }, 0);
+
+						return d;
+					}
+	 			}
+			]);
+
+			doh.register("programmatic", [
+				{
+					name: "dijit",
+					timeout: 2000,
+					runTest: function(){
+						new dijit.form.CheckBox({id:"dijit_programmatic", checked:true}).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');
+						doh.t(dijit_programmatic.get('checked'), 'dijit widget checked');
+						doh.t(!!dijit_programmatic.focusNode.checked, 'dijit HTML element checked');
+					}
+	 			},
+				{
+					name: "mobile",
+					timeout: 2000,
+					runTest: function(){
+						new dojox.mobile.CheckBox({id:"mobile_programmatic", checked:true}).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);
+						}
+						var pos = dojo.position(mobile_programmatic.domNode, true);
+						doh.t(pos.w > 0 && pos.h > 0 && pos.x > 0 && pos.y > 0, 'mobile position');
+						doh.t(!!mobile_programmatic.focusNode.checked, 'mobile HTML element checked');
+						doh.t(mobile_programmatic.get('checked'), 'mobile widget checked');
+					}
+	 			}
+			]);
+
+			var widgets = dijit.findWidgets(dojo.byId('onClickTests'));
+			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,
+					function(){
+						doh.is(expectedVal, widgetVal, 'widget value');
+						doh.is(expectedVal, widgetNodeVal, 'hidden node');
+					}
+				)
+			});
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+	<h1 class="testTitle">_CheckBoxMixin (dijit and mobile) non-robot tests</h1>
+
+	<table id="table">
+		<tr>
+			<th class="layout"> </th>
+			<th class="layout">dijit</th>
+			<th class="layout">mobile</th>
+		</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>
+		</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>
+		</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>
+	<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>
+		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>
+		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>
+		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>
+		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>
+</body>
+</html>
diff --git a/dijit/tests/form/DateTextBox.html b/dijit/tests/form/DateTextBox.html
index 197e9d2..ce4868b 100644
--- a/dijit/tests/form/DateTextBox.html
+++ b/dijit/tests/form/DateTextBox.html
@@ -27,7 +27,7 @@
 		dojo.require("dijit.form.DateTextBox");
 		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 
 			doh.register("parse", function(){
 				dojo.parser.parse();
diff --git a/dijit/tests/form/ExpandingTextAreaMixin.html b/dijit/tests/form/ExpandingTextAreaMixin.html
new file mode 100644
index 0000000..b99a669
--- /dev/null
+++ b/dijit/tests/form/ExpandingTextAreaMixin.html
@@ -0,0 +1,286 @@
+<!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>_ExpandingTextAreaMixin tests</title>
+
+	<style type="text/css">
+		@import "../../themes/claro/document.css";
+		@import "../../themes/dijit.css";
+
+		#table {
+			margin: 0;
+			padding: 2px;
+		}
+		#table, TEXTAREA {
+			font-family: monospace;
+			font-size: 12pt;
+		}
+		#table .layout {
+			padding: 2px;
+			font-size: 100%;
+			margin: 0;
+		}
+	</style>
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
+
+	<script type="text/javascript">
+		dojo.require("doh.runner");
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.form.Textarea");
+		dojo.require("dojox.mobile.ExpandingTextArea");
+
+		dojo.ready(function(){
+
+			var maxLengthNativeSupport = "maxLength" in document.createElement("textarea");
+
+			doh.register("attributes", [
+				{
+					name: "dijit",
+					runTest: function(){
+						var dijit_attributes = dijit.byId('dijit_attributes');
+						doh.is("", dijit_attributes.textbox.value, "dijit original value");
+						doh.is("", dijit_attributes.get('value'), "dijit original get('value')");
+						if(maxLengthNativeSupport){
+							doh.is("20", dijit_attributes.textbox.getAttribute("maxlength"), "dijit original maxLength");
+						}
+						doh.is("20", dijit_attributes.get('maxLength'), "dijit original get('maxLength')");
+						dijit_attributes.set('maxLength', "9");
+						doh.is("", dijit_attributes.textbox.value, "dijit value");
+						doh.is("", dijit_attributes.get('value'), "dijit get('value')");
+						if(maxLengthNativeSupport){
+							doh.is("9", dijit_attributes.textbox.getAttribute("maxlength"), "dijit maxLength");
+						}
+						doh.is("9", dijit_attributes.get('maxLength'), "dijit get('maxLength')");
+						// cols
+						doh.is("20", dijit_attributes.textbox.getAttribute("cols"), "dijit original cols");
+						doh.is("20", dijit_attributes.get('cols'), "dijit original get('cols')");
+						dijit_attributes.set('cols', "19");
+						doh.is("19", dijit_attributes.textbox.getAttribute("cols"), "dijit cols");
+						doh.is("19", dijit_attributes.get('cols'), "dijit get('cols')");
+					}
+	 			},
+				{
+					name: "mobile",
+					runTest: function(){
+						var mobile_attributes = dijit.byId('mobile_attributes');
+						doh.is("", mobile_attributes.textbox.value, "mobile original value");
+						doh.is("", mobile_attributes.get('value'), "mobile original get('value')");
+						if(maxLengthNativeSupport){
+							doh.is("20", mobile_attributes.textbox.getAttribute("maxlength"), "mobile original maxLength");
+						}
+						doh.is("20", mobile_attributes.get('maxLength'), "mobile original get('maxLength')");
+						mobile_attributes.set('maxLength', "9");
+						doh.is("", mobile_attributes.textbox.value, "mobile value");
+						doh.is("", mobile_attributes.get('value'), "mobile get('value')");
+						if(maxLengthNativeSupport){
+							doh.is("9", mobile_attributes.textbox.getAttribute("maxlength"), "mobile maxLength");
+						}
+						doh.is("9", mobile_attributes.get('maxLength'), "mobile get('maxLength')");
+						// cols
+						doh.is("20", mobile_attributes.textbox.getAttribute("cols"), "mobile original cols");
+						doh.is("20", mobile_attributes.get('cols'), "mobile original get('cols')");
+						mobile_attributes.set('cols', "19");
+						doh.is("19", mobile_attributes.textbox.getAttribute("cols"), "mobile cols");
+						doh.is("19", mobile_attributes.get('cols'), "mobile get('cols')");
+					}
+	 			}
+			]);
+
+			doh.register("events", [
+				{
+					name: "dijit",
+					timeout: 2000,
+					runTest: function(){
+						var
+							d = new doh.Deferred(),
+							dijit_events = dijit.byId('dijit_events'),
+							nop = function(){ return false; };
+
+						function onFocus(){
+							dijit_events.set('onFocus', nop);
+							dijit_events.textbox.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";
+						}
+						function onChange(){
+							dijit_events.set('onChange', nop);
+							dijit_events.textbox.value = "Change";
+							dijit_events.focus();
+							d.callback(true);
+						}
+						doh.is(nop.toString(), dijit_events.get('onFocus').toString(), "get('onFocus')");
+						doh.is(nop.toString(), dijit_events.get('onBlur').toString(), "get('onBlur')");
+						doh.is(nop.toString(), dijit_events.get('onChange').toString(), "get('onChange')");
+						dijit_events.set('onFocus', onFocus);
+						setTimeout(dojo.hitch(dijit_events, "focus"), 0);
+
+						return d;
+					}
+	 			},
+				{
+					name: "mobile",
+					timeout: 2000,
+					runTest: function(){
+						var
+							d = new doh.Deferred(),
+							mobile_events = dijit.byId('mobile_events'),
+							focusHandle, blurhandle,
+							nop = function(){ return false; };
+
+						function onFocus(){
+							mobile_events.disconnect(focusHandle);
+							mobile_events.textbox.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";
+						}
+						function onChange(){
+							mobile_events.set('onChange', nop);
+							mobile_events.textbox.value = "Change";
+							mobile_events.focus();
+							d.callback(true);
+						}
+						doh.is(nop.toString(), mobile_events.get('onChange').toString(), "get('onChange')");
+						mobile_events.textbox.value = "changing";
+						focusHandle = mobile_events.connect(mobile_events, '_onFocus', onFocus);
+						setTimeout(dojo.hitch(mobile_events, "focus"), 0);
+
+						return d;
+					}
+	 			}
+			]);
+
+			doh.register("programmatic", [
+				{
+					name: "dijit",
+					timeout: 2000,
+					runTest: function(){
+						new dijit.form.Textarea({id:"dijit_programmatic", value:"No srcNodeRef"}).placeAt("dijit_programmatic_container", "first");
+						var dijit_programmatic = dijit.byId('dijit_programmatic');
+						dijit_programmatic.resize();
+						var focushandle = dijit_programmatic.connect(dijit_programmatic, '_onFocus',
+							function(){
+								d.getTestCallback(function(){
+									dijit_programmatic.disconnect(focushandle);
+									var pos = dojo.position(dijit_programmatic.domNode, true);
+									doh.t(pos.w > 0 && pos.h > 0 && pos.x > 0 && pos.y > 0, 'dijit position');
+									doh.is("No srcNodeRef", dijit_programmatic.textbox.value, 'dijit textbox value');
+									doh.is("No srcNodeRef", dijit_programmatic.get('value'), 'dijit widget value');
+								})();
+							}
+						);
+						var d = new doh.Deferred();
+						setTimeout(dojo.hitch(dijit_programmatic, "focus"), 0);
+						return d;
+					}
+	 			},
+				{
+					name: "mobile",
+					timeout: 2000,
+					runTest: function(){
+						new dojox.mobile.ExpandingTextArea({id:"mobile_programmatic", value:"No srcNodeRef"}).placeAt("mobile_programmatic_container", "first");
+						var mobile_programmatic = dijit.byId('mobile_programmatic');
+						mobile_programmatic.resize();
+						var focushandle = mobile_programmatic.connect(mobile_programmatic, '_onFocus',
+							function(){
+								d.getTestCallback(function(){
+									mobile_programmatic.disconnect(focushandle);
+									var pos = dojo.position(mobile_programmatic.domNode, true);
+									doh.t(pos.w > 0 && pos.h > 0 && pos.x > 0 && pos.y > 0, 'mobile position');
+									doh.is("No srcNodeRef", mobile_programmatic.textbox.value, 'mobile textbox value');
+									doh.is("No srcNodeRef", mobile_programmatic.get('value'), 'mobile widget value');
+								})();
+							}
+						);
+						var d = new doh.Deferred();
+						setTimeout(dojo.hitch(mobile_programmatic, "focus"), 0);
+						return d;
+					}
+	 			}
+			]);
+
+			doh.register("sizes", [
+				{
+					name: "dijit",
+					runTest: function(){
+						var dijit_size = dijit.byId('dijit_size');
+						var originalH = dijit_size.domNode.offsetHeight;
+						var originalVal = dijit_size.value;
+						dijit_size.set('value', originalVal + "\n");
+						var newH = dijit_size.domNode.offsetHeight;
+						doh.t(newH > originalH, "expand: " + newH + ' ' + originalH);
+						dijit_size.set('value', originalVal);
+						newH = dijit_size.domNode.offsetHeight;
+						doh.is(newH, originalH, "shrink: " + newH + ' ' + originalH);
+					}
+	 			},
+				{
+					name: "mobile",
+					runTest: function(){
+						var mobile_size = dijit.byId('mobile_size');
+						var originalH = mobile_size.domNode.offsetHeight;
+						var originalVal = mobile_size.value;
+						mobile_size.set('value', originalVal + "\n");
+						var newH = mobile_size.domNode.offsetHeight;
+						doh.t(newH > originalH, "expand: " + newH + ' ' + originalH);
+						mobile_size.set('value', originalVal);
+						newH = mobile_size.domNode.offsetHeight;
+					}
+	 			}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+	<h1 class="testTitle">_ExpandingTextAreaMixin (dijit and mobile) non-robot tests</h1>
+	<table id="table">
+		<tr>
+			<th class="layout"> </th>
+			<th class="layout">dijit</th>
+			<th class="layout">mobile</th>
+		</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>
+		</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>
+		</tr>
+		<tr>
+			<td class="layout">Programmatic</td>
+			<td class="layout" id="dijit_programmatic_container"></td>
+			<td class="layout" id="mobile_programmatic_container"></td>
+		</tr>
+		<tr>
+			<td class="layout">Size</td>
+			<td class="layout"><textarea id="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=''
+>line 1
+line 2
+line 3</textarea></td>
+		</tr>
+	</table>
+</body>
+</html>
diff --git a/dijit/tests/form/Form.html b/dijit/tests/form/Form.html
index 075fa0a..6d21b10 100644
--- a/dijit/tests/form/Form.html
+++ b/dijit/tests/form/Form.html
@@ -27,10 +27,12 @@
 		dojo.require("dojo.date");
 		dojo.require("dojo.parser");
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.focus");
 		dojo.require("dijit.form.Form");
 		dojo.require("dijit.layout.ContentPane");
 		dojo.require("dijit.form.ComboBox");
 		dojo.require("dijit.form.CheckBox");
+		dojo.require("dijit.form.RadioButton");
 		dojo.require("dijit.form.DateTextBox");
 		dojo.require("dijit.form.Button");
 		dojo.require("dijit.form.MultiSelect");
@@ -107,7 +109,7 @@
 							cb: ["2"]
 		};
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 
 			doh.register("parse", function(){
 				dojo.parser.parse();
@@ -228,7 +230,7 @@
 					},
 					function nameAttributeSurvived(){  // ticket:4753
 						var radios = dojo.query("INPUT[type=radio]", "radio-cells").forEach(
-							function(r) {
+							function(r){
 								doh.is( r.name, "r" );
 							});
 					},
@@ -259,11 +261,17 @@
 				]
 			);
 
-			false && doh.register("watch('value')", [
-				// Setup watch("value", ...)
-				function setUp(){
+			doh.register("watch('value')", [
+				// Set() calls fire onChange() on a timer, so set calls from above may have unfired onChange events.
+				// Avoid spurious watch() notifications by waiting for lingering onChange() events to fire.
+				function coolDown(){
 					var d = new doh.Deferred();
+					setTimeout(function(){ d.callback(true); }, 100);
+					return d;
+				},
 
+				// Setup watch("value", ...)
+				function setUp(){
 					// Setup globals to reflect return from watch("value"), ...
 					calls = 0;
 					oldVal = null;
@@ -280,7 +288,7 @@
 				// and see if Form.watch("value", ...) does the right thing					
 				function formSet(){
 					var d = new doh.Deferred();
-
+					calls = 0;
 					formWidget.set("value", {
 						foo: {bar: {baz: {quux: "1967-10-20"} } },
 						available: {from: "1967-11-09"}
@@ -291,7 +299,7 @@
 						doh.is('2007-12-30', dojo.date.stamp.toISOString(oldVal.foo.bar.baz.quux, {selector: 'date'}), "old value");
 						doh.is('1967-10-20', dojo.date.stamp.toISOString(newVal.foo.bar.baz.quux, {selector: 'date'}), "new value");
 						doh.is('1967-11-09', dojo.date.stamp.toISOString(newVal.available.from, {selector: 'date'}), "new value2");
-					}), 50);
+					}), 500);
 					
 					return d;
 				},
@@ -308,7 +316,7 @@
 						doh.is(1, calls, "exactly one watch(value) call");
 						doh.is('1967-10-20', dojo.date.stamp.toISOString(oldVal.foo.bar.baz.quux, {selector: 'date'}), "old value");
 						doh.is('1981-10-12', dojo.date.stamp.toISOString(newVal.foo.bar.baz.quux, {selector: 'date'}), "new value");
-					}), 50);
+					}), 500);
 					
 					return d;
 				},
@@ -331,7 +339,7 @@
 						doh.is(2, newVal.cb.length, "number of checkboxes currently checked");
 						doh.is(1, newVal.cb[0], "new checkboxes, first checked");
 						doh.is(4, newVal.cb[1], "new checkboxes, second checked");
-					}), 50);
+					}), 500);
 					
 					return d;
 				},
@@ -353,7 +361,7 @@
 
 						doh.is(1, newVal.cb.length, "number of checkboxes currently checked");
 						doh.is(4, newVal.cb[0], "new checkboxes, first checked");
-					}), 50);
+					}), 500);
 					
 					return d;
 				},
@@ -377,7 +385,7 @@
 						doh.is(2, newVal.cb.length, "number of checkboxes currently checked");
 						doh.is(2, newVal.cb[0], "new checkboxes, first checked");
 						doh.is(4, newVal.cb[1], "new checkboxes, second checked");
-					}), 50);
+					}), 500);
 					
 					return d;
 				},
@@ -394,7 +402,7 @@
 						doh.is(1, calls, "exactly one watch(value) call");
 						doh.is(2, oldVal.r, "old selected radio button");
 						doh.is(3, newVal.r, "new selected radio button");
-					}), 50);
+					}), 500);
 
 					return d;
 				},
@@ -411,7 +419,7 @@
 						doh.is(1, calls, "exactly one watch(value) call");
 						doh.is(3, oldVal.r, "old selected radio button");
 						doh.is(1, newVal.r, "new selected radio button");
-					}), 50);
+					}), 500);
 					
 					return d;
 				},
@@ -427,7 +435,7 @@
 						doh.is(1, calls, "one watch(value) call");
 						doh.t(dojo.getObject("foo.bar.baz.quux", false, oldVal) !== undefined, "attribute used to exist");
 						doh.t(dojo.getObject("foo.bar.baz.quux", false, newVal) === undefined, "attribute no longer exists");
-					}), 50);
+					}), 500);
 					
 					return d;
 				},
@@ -443,7 +451,7 @@
 						doh.is(1, calls, "one watch(value) call");
 						doh.t(dojo.getObject("foo.bar.baz.quux", false, oldVal) === undefined, "attribute didn't used to exist");
 						doh.t(dojo.getObject("foo.bar.baz.quux", false, newVal) !== undefined, "attribute now exists");
-					}), 50);
+					}), 500);
 					
 					return d;
 				},
@@ -596,9 +604,16 @@
 				formWidget.validate();
 				
 				doh.t(dojo.hasClass(dojo.byId("widget_rw"), "dijitValidationTextBoxError"), "required but empty marked as error");
-				doh.is("dtb2", dijit._curFocus.id, "focused on first invalid DateTextBox");
+				doh.is("dtb2", dijit.focus.curNode.id, "focused on first invalid DateTextBox");
 			});
 
+			if(dojo.isFF >= 4 || dojo.isIE >= 10 || dojo.isWebKit){
+				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");
+				});
+			}
+
 			doh.run();
 		});
 
@@ -874,5 +889,7 @@ simple line 2</textarea>
 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>
 </body>
 </html>
diff --git a/dijit/tests/form/RadioButtonMixin.html b/dijit/tests/form/RadioButtonMixin.html
new file mode 100644
index 0000000..9689cd7
--- /dev/null
+++ b/dijit/tests/form/RadioButtonMixin.html
@@ -0,0 +1,187 @@
+<!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>_RadioButtonMixin tests</title>
+
+	<style type="text/css">
+		@import "../../themes/claro/document.css";
+		@import "../../themes/dijit.css";
+
+		#table {
+			margin: 0;
+			padding: 2px;
+		}
+		#table, .dijit, BUTTON {
+			font-family: monospace;
+			font-size: 12pt;
+		}
+		#table .layout {
+			padding: 2px;
+			font-size: 100%;
+			margin: 0;
+		}
+	</style>
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
+
+	<script type="text/javascript">
+		dojo.require("doh.runner");
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.form.RadioButton");
+		dojo.require("dojox.mobile.RadioButton");
+
+		dojo.ready(function(){
+
+			doh.register("attributes", [
+				{
+					name: "dijit",
+					runTest: function(){
+						var dijit_attributes = dijit.byId('dijit_attributes');
+						doh.is("something", dijit_attributes.focusNode.value, 'dijit HTML element original value');
+						doh.t(dijit_attributes.get('checked'), "dijit original get('checked')");
+						doh.t(!!dijit_attributes.focusNode.checked, 'dijit HTML element originally checked');
+						doh.t(dojo.hasClass(dijit_attributes.domNode, dijit_attributes.baseClass+"Checked"), "dijit baseClass checked");
+						dijit_attributes.set('value', "something else");
+						dijit.byId('dijit_attributes2').set('checked', true);
+						doh.f(dijit_attributes.get('checked'), "dijit get('checked')");
+						doh.t(!dijit_attributes.focusNode.checked, 'dijit HTML element unchecked');
+						doh.f(dojo.hasClass(dijit_attributes.domNode, dijit_attributes.baseClass+"Checked"), "dijit baseClass not checked");
+						doh.t(dojo.hasClass(dijit_attributes.domNode, dijit_attributes.baseClass), "dijit baseClass");
+						doh.t(dojo.hasClass(dijit_attributes.domNode, "mblRedButton"), "dijit original class");
+						doh.is("something else", dijit_attributes.focusNode.value, 'dijit HTML element value');
+					}
+	 			},
+				{
+					name: "mobile",
+					runTest: function(){
+						var mobile_attributes = dijit.byId('mobile_attributes');
+						doh.is("something", mobile_attributes.focusNode.value, 'mobile HTML element original value');
+						doh.t(mobile_attributes.get('checked'), "mobile original get('checked')");
+						doh.t(!!mobile_attributes.focusNode.checked, 'mobile HTML element originally checked');
+						doh.t(dojo.hasClass(mobile_attributes.domNode, mobile_attributes.baseClass+"Checked"), "mobile baseClass checked");
+						dijit.byId('mobile_attributes2').set('checked', true);
+						mobile_attributes.set('value', "something else");
+						doh.f(mobile_attributes.get('checked'), "mobile get('checked')");
+						doh.t(!mobile_attributes.focusNode.checked, 'mobile HTML element unchecked');
+						doh.f(dojo.hasClass(mobile_attributes.domNode, mobile_attributes.baseClass+"Checked"), "mobile baseClass not checked");
+						doh.t(dojo.hasClass(mobile_attributes.domNode, mobile_attributes.baseClass), "mobile baseClass");
+						doh.t(dojo.hasClass(mobile_attributes.domNode, "mblRedButton"), "mobile original class");
+						doh.is("something else", mobile_attributes.focusNode.value, 'mobile HTML element value');
+					}
+	 			}
+			]);
+
+			doh.register("events", [
+				{
+					name: "dijit",
+					timeout: 2000,
+					runTest: function(){
+						var
+							d = new doh.Deferred(),
+							dijit_events = dijit.byId('dijit_events'),
+							calledOnClick = false,
+							nop = function(){ return false; };
+
+						function onChange(v){
+							dijit_events.set('onChange', nop);
+							d.callback(true);
+						}
+						dijit_events.set('onChange', onChange);
+						dijit_events._onClick({ preventDefault: nop });
+
+						return d;
+					}
+	 			},
+				{
+					name: "mobile",
+					timeout: 2000,
+					runTest: function(){
+						var
+							d = new doh.Deferred(),
+							mobile_events = dijit.byId('mobile_events'),
+							nop = function(){ return false; };
+
+						function onChange(){
+							mobile_events.set('onChange', nop);
+							d.callback(true);
+						}
+						mobile_events.set("onChange", onChange);
+						setTimeout(function(){ mobile_events.focusNode.click({ preventDefault: nop }); }, 0);
+
+						return d;
+					}
+	 			}
+			]);
+
+			doh.register("programmatic", [
+				{
+					name: "dijit",
+					timeout: 2000,
+					runTest: function(){
+						new dijit.form.RadioButton({name:"dijit_programmatic", id:"dijit_programmatic", checked:true}).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');
+						doh.t(dijit_programmatic.get('checked'), 'dijit widget checked');
+						doh.t(!!dijit_programmatic.focusNode.checked, 'dijit HTML element checked');
+					}
+	 			},
+				{
+					name: "mobile",
+					timeout: 2000,
+					runTest: function(){
+						new dojox.mobile.RadioButton({name:"mobile_programmatic", id:"mobile_programmatic", checked:true}).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);
+						}
+						var pos = dojo.position(mobile_programmatic.domNode, true);
+						doh.t(pos.w > 0 && pos.h > 0 && pos.x > 0 && pos.y > 0, 'mobile position');
+						doh.t(!!mobile_programmatic.focusNode.checked, 'mobile HTML element checked');
+						doh.t(mobile_programmatic.get('checked'), 'mobile widget checked');
+					}
+	 			}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+	<h1 class="testTitle">_RadioButtonMixin (dijit and mobile) non-robot tests</h1>
+
+	<table id="table">
+		<tr>
+			<th class="layout"> </th>
+			<th class="layout" colspan=2>dijit</th>
+			<th class="layout" colspan=2>mobile</th>
+		</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">
+		</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">
+		</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" id="mobile_programmatic_container"></td>
+			<td class="layout"><input name="mobile_programmatic" type="radio" value="other" dojoType="dojox.mobile.RadioButton">
+		</tr>
+	</table>
+</body>
+</html>
diff --git a/dijit/tests/form/TextBoxMixin.html b/dijit/tests/form/TextBoxMixin.html
new file mode 100644
index 0000000..cdf1bbf
--- /dev/null
+++ b/dijit/tests/form/TextBoxMixin.html
@@ -0,0 +1,264 @@
+<!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>_TextBoxMixin tests</title>
+
+	<style type="text/css">
+		@import "../../themes/claro/document.css";
+		@import "../../themes/dijit.css";
+
+		#table {
+			margin: 0;
+			padding: 2px;
+		}
+		#table, INPUT {
+			font-family: monospace;
+			font-size: 12pt;
+		}
+		#table .layout {
+			padding: 2px;
+			font-size: 100%;
+			margin: 0;
+		}
+	</style>
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
+
+	<script type="text/javascript">
+		dojo.require("doh.runner");
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.form.TextBox");
+		dojo.require("dojox.mobile.TextBox");
+
+		dojo.ready(function(){
+
+			doh.register("DOM attributes", [
+				{
+					name: "dijit",
+					runTest: function(){
+						var dijit_DOMattr = dijit.byId('dijit_DOMattr');
+						doh.is("original", dijit_DOMattr.get('placeHolder'), "dijit original get('placeHolder')");
+						dijit_DOMattr.set('placeHolder', "place holder");
+						doh.is("", dijit_DOMattr.textbox.value, "dijit original value");
+						doh.is("", dijit_DOMattr.get('value'), "dijit original get('value')");
+						doh.is("place holder", dijit_DOMattr.get('placeHolder'), "dijit get('placeHolder')");
+						doh.is("20", dijit_DOMattr.textbox.getAttribute("maxlength"), "dijit original maxLength");
+						doh.is("20", dijit_DOMattr.get('maxLength'), "dijit original get('maxLength')");
+						dijit_DOMattr.set('maxLength', "9");
+						doh.is("", dijit_DOMattr.textbox.value, "dijit value");
+						doh.is("", dijit_DOMattr.get('value'), "dijit get('value')");
+						doh.is("9", dijit_DOMattr.textbox.getAttribute("maxlength"), "dijit maxLength");
+						doh.is("9", dijit_DOMattr.get('maxLength'), "dijit get('maxLength')");
+					}
+	 			},
+				{
+					name: "mobile",
+					runTest: function(){
+						var mobile_DOMattr = dijit.byId('mobile_DOMattr');
+						doh.is("original", mobile_DOMattr.textbox.getAttribute("placeholder"), "mobile original placeholder");
+						doh.is("original", mobile_DOMattr.get('placeHolder'), "mobile original get('placeHolder')");
+						mobile_DOMattr.set('placeHolder', "place holder");
+						doh.is("", mobile_DOMattr.textbox.value, "mobile original value");
+						doh.is("", mobile_DOMattr.get('value'), "mobile original get('value')");
+						doh.is("place holder", mobile_DOMattr.textbox.getAttribute("placeholder"), "mobile placeholder");
+						doh.is("place holder", mobile_DOMattr.get('placeHolder'), "mobile get('placeHolder')");
+						doh.is("20", mobile_DOMattr.textbox.getAttribute("maxlength"), "mobile original maxLength");
+						doh.is("20", mobile_DOMattr.get('maxLength'), "mobile original get('maxLength')");
+						mobile_DOMattr.set('maxLength', "9");
+						doh.is("", mobile_DOMattr.textbox.value, "mobile value");
+						doh.is("", mobile_DOMattr.get('value'), "mobile get('value')");
+						doh.is("9", mobile_DOMattr.textbox.getAttribute("maxlength"), "mobile maxLength");
+						doh.is("9", mobile_DOMattr.get('maxLength'), "mobile get('maxLength')");
+					}
+	 			}
+			]);
+
+			doh.register("widget attributes", [
+				{
+					name: "dijit",
+					runTest: function(){
+						var dijit_WidgetAttr = dijit.byId('dijit_WidgetAttr');
+						doh.is(false, dijit_WidgetAttr.get('propercase'), "dijit original get('propercase')");
+						dijit_WidgetAttr.set('propercase', true);
+						doh.is(true, dijit_WidgetAttr.get('propercase'), "dijit get('propercase')");
+						dijit_WidgetAttr.set('displayedValue', "proper cased");
+						dijit_WidgetAttr._onBlur();
+						doh.is("Proper Cased", dijit_WidgetAttr.textbox.value, "dijit value");
+						doh.is("Proper Cased", dijit_WidgetAttr.get('value'), "dijit get('value')");
+					}
+	 			},
+				{
+					name: "mobile",
+					runTest: function(){
+						var mobile_WidgetAttr = dijit.byId('mobile_WidgetAttr');
+						doh.is(false, mobile_WidgetAttr.get('propercase'), "mobile original get('propercase')");
+						mobile_WidgetAttr.set('propercase', true);
+						doh.is(true, mobile_WidgetAttr.get('propercase'), "get('propercase')");
+						mobile_WidgetAttr.set('displayedValue', "proper cased");
+						mobile_WidgetAttr._onBlur();
+						doh.is("Proper Cased", mobile_WidgetAttr.textbox.value, "mobile value");
+						doh.is("Proper Cased", mobile_WidgetAttr.get('value'), "mobile get('value')");
+					}
+	 			}
+			]);
+
+			doh.register("events", [
+				{
+					name: "dijit",
+					timeout: 2000,
+					runTest: function(){
+						var
+							d = new doh.Deferred(),
+							dijit_events = dijit.byId('dijit_events'),
+							nop = function(){ return false; };
+
+						function onFocus(){
+							dijit_events.set('onFocus', nop);
+							dijit_events.textbox.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";
+						}
+						function onChange(){
+							dijit_events.set('onChange', nop);
+							dijit_events.textbox.value = "Change";
+							dijit_events.focus();
+							d.callback(true);
+						}
+						doh.is(nop.toString(), dijit_events.get('onFocus').toString(), "get('onFocus')");
+						doh.is(nop.toString(), dijit_events.get('onBlur').toString(), "get('onBlur')");
+						doh.is(nop.toString(), dijit_events.get('onChange').toString(), "get('onChange')");
+						dijit_events.set('onFocus', onFocus);
+						setTimeout(dojo.hitch(dijit_events, "focus"), 0);
+
+						return d;
+					}
+	 			},
+				{
+					name: "mobile",
+					timeout: 2000,
+					runTest: function(){
+						var
+							d = new doh.Deferred(),
+							mobile_events = dijit.byId('mobile_events'),
+							focusHandle, blurhandle,
+							nop = function(){ return false; };
+
+						function onFocus(){
+							mobile_events.disconnect(focusHandle);
+							mobile_events.textbox.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";
+						}
+						function onChange(){
+							mobile_events.set('onChange', nop);
+							mobile_events.textbox.value = "Change";
+							mobile_events.focus();
+							d.callback(true);
+						}
+						doh.is(nop.toString(), mobile_events.get('onChange').toString(), "get('onChange')");
+						mobile_events.textbox.value = "changing";
+						focusHandle = mobile_events.connect(mobile_events, '_onFocus', onFocus);
+						setTimeout(dojo.hitch(mobile_events, "focus"), 0);
+
+						return d;
+					}
+	 			}
+			]);
+
+			doh.register("programmatic", [
+				{
+					name: "dijit",
+					timeout: 2000,
+					runTest: function(){
+						new dijit.form.TextBox({id:"dijit_programmatic", selectOnClick:true, value:"No srcNodeRef"}).placeAt("dijit_programmatic_container", "first");
+						var dijit_programmatic = dijit.byId('dijit_programmatic');
+						var focushandle = dijit_programmatic.connect(dijit_programmatic, '_onFocus',
+							function(){
+								d.getTestCallback(function(){
+									dijit_programmatic.disconnect(focushandle);
+									var pos = dojo.position(dijit_programmatic.domNode, true);
+									doh.t(pos.w > 0 && pos.h > 0 && pos.x > 0 && pos.y > 0, 'dijit position');
+									doh.is("No srcNodeRef", dijit_programmatic.textbox.value, 'dijit textbox value');
+									doh.is("No srcNodeRef", dijit_programmatic.get('value'), 'dijit widget value');
+								})();
+							}
+						);
+						var d = new doh.Deferred();
+						setTimeout(dojo.hitch(dijit_programmatic, "focus"), 0);
+						return d;
+					}
+	 			},
+				{
+					name: "mobile",
+					timeout: 2000,
+					runTest: function(){
+						new dojox.mobile.TextBox({id:"mobile_programmatic", selectOnClick:true, value:"No srcNodeRef"}).placeAt("mobile_programmatic_container", "first");
+						var mobile_programmatic = dijit.byId('mobile_programmatic');
+						var focushandle = mobile_programmatic.connect(mobile_programmatic, '_onFocus',
+							function(){
+								d.getTestCallback(function(){
+									mobile_programmatic.disconnect(focushandle);
+									var pos = dojo.position(mobile_programmatic.domNode, true);
+									doh.t(pos.w > 0 && pos.h > 0 && pos.x > 0 && pos.y > 0, 'mobile position');
+									doh.is("No srcNodeRef", mobile_programmatic.textbox.value, 'mobile textbox value');
+									doh.is("No srcNodeRef", mobile_programmatic.get('value'), 'mobile widget value');
+								})();
+							}
+						);
+						var d = new doh.Deferred();
+						setTimeout(dojo.hitch(mobile_programmatic, "focus"), 0);
+						return d;
+					}
+	 			}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+	<h1 class="testTitle">_TextBoxMixin (dijit and mobile) non-robot tests</h1>
+
+	<table id="table">
+		<tr>
+			<th class="layout"> </th>
+			<th class="layout">dijit</th>
+			<th class="layout">mobile</th>
+		</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>
+		</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>
+		</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>
+		</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>
+</body>
+</html>
diff --git a/dijit/tests/form/TextBox_sizes.html b/dijit/tests/form/TextBox_sizes.html
index 1ddb1fc..329c545 100644
--- a/dijit/tests/form/TextBox_sizes.html
+++ b/dijit/tests/form/TextBox_sizes.html
@@ -9,41 +9,32 @@
 		@import "../../themes/dijit.css";
 		@import "../../themes/dijit_rtl.css";
 		@import "../../themes/tundra/Common.css";
-		@import "../../themes/tundra/Common_rtl.css";
 		@import "../../themes/tundra/form/Button.css";
-		@import "../../themes/tundra/form/Button_rtl.css";
 		@import "../../themes/tundra/form/Common.css";
-		@import "../../themes/tundra/form/Common_rtl.css";
 		@import "../../themes/claro/Common.css";
-		@import "../../themes/claro/Common_rtl.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/NumberSpinner_rtl.css";
 		@import "../../themes/soria/Common.css";
-		@import "../../themes/soria/Common_rtl.css";
 		@import "../../themes/soria/form/Button.css";
 		@import "../../themes/soria/form/Button_rtl.css";
 		@import "../../themes/soria/form/Common.css";
-		@import "../../themes/soria/form/Common_rtl.css";
 		@import "../../themes/nihilo/Common.css";
-		@import "../../themes/nihilo/Common_rtl.css";
 		@import "../../themes/nihilo/form/Button.css";
 		@import "../../themes/nihilo/form/Button_rtl.css";
 		@import "../../themes/nihilo/form/Common.css";
-		@import "../../themes/nihilo/form/Common_rtl.css";
 
 		#table TD {
 			background-color: pink;
 			font-size: 100%;
-			padding: 0px;
-			margin: 0px;
+			padding: 0;
+			margin: 0;
 		}
 		TABLE#table, #table TD, #table .dijit {
 			border-color: black !important;
-			margin: 0px !important;
+			margin: 0 !important;
 		}
 		.dj_ie8 #table .dijit {
 			vertical-align: top; /* needed for IE8 strict */
@@ -55,10 +46,10 @@
 			padding: 10px !important;
 		}
 		.unPadded .dijitInputField {
-			padding: 0px !important;
+			padding: 0 !important;
 		}
 		#table {
-			padding: 0px;
+			padding: 0;
 			border:1px solid black;
 			background-color: pink;
 		}
@@ -81,7 +72,7 @@
 		dojo.require("dijit.form.NumberSpinner");
 		dojo.require("dijit.form.Button");
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 
 			var padding = "padded";
 			var theme = "tundra";
diff --git a/dijit/tests/form/TextBox_sizes.js b/dijit/tests/form/TextBox_sizes.js
index a051c6a..35541ef 100644
--- a/dijit/tests/form/TextBox_sizes.js
+++ b/dijit/tests/form/TextBox_sizes.js
@@ -1,7 +1,9 @@
 dojo.provide("dijit.tests.form.TextBox_sizes");
 
+var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?");
+
+
 try{
-	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?");
 
 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);
@@ -150,10 +152,8 @@ doh.registerUrl('t.system.2em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/
 }catch(e){
 	doh.debug(e);
 }
-dojo.provide("dijit.tests.form.TextBox_sizes");
 
 try{
-	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?");
 
 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);
@@ -302,10 +302,8 @@ doh.registerUrl('t.system.2em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/
 }catch(e){
 	doh.debug(e);
 }
-dojo.provide("dijit.tests.form.TextBox_sizes");
 
 try{
-	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?");
 
 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);
diff --git a/dijit/tests/form/TextBox_types.html b/dijit/tests/form/TextBox_types.html
new file mode 100644
index 0000000..6d4a484
--- /dev/null
+++ b/dijit/tests/form/TextBox_types.html
@@ -0,0 +1,87 @@
+<!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>TextBox type Tests</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="parseOnLoad: true, isDebug: true"></script>
+
+	<!-- only needed for alternate theme testing: -->
+	<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.TextBox");
+		dojo.require("dijit.form.CurrencyTextBox");
+		dojo.require("dijit.form.DateTextBox");
+		dojo.require("dijit.form.TimeTextBox");
+		dojo.require("dijit.form.NumberTextBox");
+		dojo.require("dijit.form.RangeBoundTextBox");
+
+		dojo.ready(function(){
+
+			doh.register("types", [
+				{
+					name: "HTML4",
+					runTest: function(){
+						doh.is(dojo.byId('hn').type, dijit.byId('dr').focusNode.type, "dr");
+						doh.is(dojo.byId('hp').type, dijit.byId('dp').focusNode.type, "dp");
+						doh.is("text", dijit.byId('dn').focusNode.type, "dn");
+						doh.is("text", dijit.byId('dc').focusNode.type, "dc");
+						doh.is("text", dijit.byId('dd').focusNode.type, "dd");
+						doh.is("text", dijit.byId('dt').focusNode.type, "dt");
+					}
+				},
+				{
+					name: "HTML5",
+					runTest: function(){
+						doh.is(dojo.byId('hn').type, dijit.byId('wr').focusNode.type, "wr");
+						doh.is(dojo.byId('hp').type, dijit.byId('wp').focusNode.type, "wp");
+						doh.is("text", dijit.byId('wn').focusNode.type, "wn");
+						doh.is("text", dijit.byId('wc').focusNode.type, "wc");
+						doh.is("text", dijit.byId('wd').focusNode.type, "wd");
+						doh.is("text", dijit.byId('wt').focusNode.type, "wt");
+					}
+				}
+			]);
+
+			doh.run();
+		});
+
+	</script>
+</head>
+<body class="claro">
+	<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>
+<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>
+<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>
+</body>
+</html>
diff --git a/dijit/tests/form/ToggleButtonMixin.html b/dijit/tests/form/ToggleButtonMixin.html
new file mode 100644
index 0000000..95f39c5
--- /dev/null
+++ b/dijit/tests/form/ToggleButtonMixin.html
@@ -0,0 +1,169 @@
+<!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>_ToggleButtonMixin tests</title>
+
+	<style type="text/css">
+		@import "../../themes/claro/document.css";
+		@import "../../themes/dijit.css";
+
+		#table {
+			margin: 0;
+			padding: 2px;
+		}
+		#table, .dijit, BUTTON {
+			font-family: monospace;
+			font-size: 12pt;
+		}
+		#table .layout {
+			padding: 2px;
+			font-size: 100%;
+			margin: 0;
+		}
+		.mblRedButtonChecked {
+			border-style: inset;
+		}
+	</style>
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
+
+	<script type="text/javascript">
+		dojo.require("doh.runner");
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.form.ToggleButton");
+		dojo.require("dojox.mobile.ToggleButton");
+
+		dojo.ready(function(){
+
+			doh.register("attributes", [
+				{
+					name: "dijit",
+					runTest: function(){
+						var dijit_attributes = dijit.byId('dijit_attributes');
+						doh.t(dijit_attributes.get('checked'), "dijit original get('checked')");
+						doh.t(dojo.hasClass(dijit_attributes.domNode, dijit_attributes.baseClass+"Checked"), "dijit baseClass checked");
+						dijit_attributes.set('checked', false);
+						doh.f(dijit_attributes.get('checked'), "dijit get('checked')");
+						doh.f(dojo.hasClass(dijit_attributes.domNode, dijit_attributes.baseClass+"Checked"), "dijit baseClass not checked");
+						doh.t(dojo.hasClass(dijit_attributes.domNode, dijit_attributes.baseClass), "dijit baseClass");
+						doh.t(dojo.hasClass(dijit_attributes.domNode, "mblRedButton"), "dijit original class");
+					}
+	 			},
+				{
+					name: "mobile",
+					runTest: function(){
+						var mobile_attributes = dijit.byId('mobile_attributes');
+						doh.t(mobile_attributes.get('checked'), "mobile original get('checked')");
+						doh.t(dojo.hasClass(mobile_attributes.domNode, mobile_attributes.baseClass+"Checked"), "mobile baseClass checked");
+						mobile_attributes.set('checked', false);
+						doh.f(mobile_attributes.get('checked'), "mobile get('checked')");
+						doh.f(dojo.hasClass(mobile_attributes.domNode, mobile_attributes.baseClass+"Checked"), "mobile baseClass not checked");
+						doh.t(dojo.hasClass(mobile_attributes.domNode, mobile_attributes.baseClass), "mobile baseClass");
+						doh.t(dojo.hasClass(mobile_attributes.domNode, "mblRedButton"), "mobile original class");
+					}
+	 			}
+			]);
+
+			doh.register("events", [
+				{
+					name: "dijit",
+					timeout: 2000,
+					runTest: function(){
+						var
+							d = new doh.Deferred(),
+							dijit_events = dijit.byId('dijit_events'),
+							calledOnClick = false,
+							nop = function(){ return false; };
+
+						function onChange(v){
+							dijit_events.set('onChange', nop);
+							d.callback(true);
+						}
+						dijit_events.set('onChange', onChange);
+						dijit_events._onClick({ preventDefault: nop });
+
+						return d;
+					}
+	 			},
+				{
+					name: "mobile",
+					timeout: 2000,
+					runTest: function(){
+						var
+							d = new doh.Deferred(),
+							mobile_events = dijit.byId('mobile_events'),
+							nop = function(){ return false; };
+
+						function onChange(){
+							mobile_events.set('onChange', nop);
+							d.callback(true);
+						}
+						mobile_events.set("onChange", onChange);
+						setTimeout(function(){ mobile_events.focusNode.click({ preventDefault: nop }); }, 0);
+
+						return d;
+					}
+	 			}
+			]);
+
+			doh.register("programmatic", [
+				{
+					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");
+						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');
+						doh.t(dijit_programmatic.get('checked'), 'dijit widget checked');
+					}
+	 			},
+				{
+					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");
+						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');
+						doh.t(mobile_programmatic.get('checked'), 'mobile widget checked');
+					}
+	 			}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+	<h1 class="testTitle">_ToggleButtonMixin (dijit and mobile) non-robot tests</h1>
+
+	<table id="table">
+		<tr>
+			<th class="layout"> </th>
+			<th class="layout">dijit</th>
+			<th class="layout">mobile</th>
+		</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"><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 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>
+			<td class="layout">Programmatic</td>
+			<td class="layout" id="dijit_programmatic_container"></td>
+			<td class="layout" id="mobile_programmatic_container"></td>
+		</tr>
+	</table>
+</body>
+</html>
diff --git a/dijit/tests/form/_autoComplete.html b/dijit/tests/form/_autoComplete.html
index 365a8c5..79c152f 100644
--- a/dijit/tests/form/_autoComplete.html
+++ b/dijit/tests/form/_autoComplete.html
@@ -94,7 +94,7 @@
 				fetchProperties: {sort:[{attribute: 'name', descending: true}]}
 			}, dojo.byId("progCombo3"));
 		}
-		dojo.addOnLoad(init);
+		dojo.ready(init);
 
 		function toggleDisabled(button, widget){
 			widget = dijit.byId(widget);
@@ -103,12 +103,12 @@
 			button.innerHTML= widget.disabled ? "Enable" : "Disable";
 		}
 
-		function getValue() {
+		function getValue(){
 			var f = document.getElementById("form1");
 			var s = "";
-			for (var i = 0; i < f.elements.length; i++) {
+			for(var i = 0; i < f.elements.length; i++){
 				var elem = f.elements[i];
-				if (elem.nodeName.toLowerCase() == "button" || elem.type=="submit" || elem.type=="button")  { continue; }
+				if(elem.nodeName.toLowerCase() == "button" || elem.type=="submit" || elem.type=="button")  { continue; }
 				s += elem.name + ": " + elem.value + "\n";
 			}
 			return s;
@@ -146,7 +146,6 @@
 		<script type="text/javascript">
 			function setValueTestOnChange(newValue){
 				if(this.lastlabelFuncMsg){
-					console.info(this.lastlabelFuncMsg);
 					this.lastlabelFuncMsg = '';
 				}
 				dojo.byId('oc1').value = newValue;
@@ -162,13 +161,13 @@
 					console.error(this.id + ' has an undefined item, onChange value = ' + newValue + ', widget value = ' + this.value + ', displayed Value = ' + this.textbox.value);
 					this.itemError = true;
 				}else{
-					itemLabel = this.store.getValue(this.item, this.searchAttr).toString();
+					itemLabel = this.item[this.searchAttr].toString();
 				}
 				dojo.byId('i1').value = itemLabel;
 			}
 			function setValueTestLabelFunc(item, store){
-				var label = store.getValue(item, this.searchAttr);
-				var value = store.getValue(item, 'value');
+				var label = item[this.searchAttr];
+				var value = item.value;
 				if(!this.labelFuncCount){ this.labelFuncCount = 0; }
 				if(!this.labelFuncCounts){ this.labelFuncCounts = []; }
 				if(!this.labelFuncCounts[value]){ this.labelFuncCounts[value] = 0; }
@@ -501,7 +500,7 @@
 				selectOnClick:true,
 				value:"h1",
 				labelType:"html",
-				labelFunc:function(node){ var txt = node.innerHTML; return "<"+txt+">"+txt+"</"+txt+">"; }
+				labelFunc:function(item){ var txt = item.value; return "<"+txt+">"+txt+"</"+txt+">"; }
 		'>
 			<option value="h1">h1</option>
 			<option value="h2">h2</option>
diff --git a/dijit/tests/form/mobile.html b/dijit/tests/form/mobile.html
new file mode 100644
index 0000000..55092d5
--- /dev/null
+++ b/dijit/tests/form/mobile.html
@@ -0,0 +1,201 @@
+<!DOCTYPE>
+<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 widgets mobile test page</title>
+		<link href="../../themes/claro/claro.css" rel="stylesheet"/>
+		<link href="../../icons/commonIcons.css" rel="stylesheet"/>
+		<link href="../css/dijitTests.css" rel="stylesheet"/>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			require([
+				"dojo/_base/kernel",
+				"dijit",
+				"dojo/parser",
+
+				"dijit/form/Button",
+				"dijit/form/DropDownButton",
+				"dijit/form/ComboButton",
+				"dijit/form/ToggleButton",
+				"dijit/DropDownMenu",
+				"dijit/MenuItem",
+
+				"dijit/form/CheckBox",
+				"dijit/form/RadioButton",
+
+				"dijit/form/NumberTextBox",
+				"dijit/form/DateTextBox",
+				"dijit/form/TimeTextBox",
+				"dijit/form/NumberSpinner",
+
+				"dijit/form/FilteringSelect",
+				"dijit/form/Select",
+
+				"dijit/form/HorizontalSlider",
+				"dijit/form/HorizontalRule",
+				"dijit/form/HorizontalRuleLabels",
+				"dojo/domReady!"
+			], function(dojo, dijit){
+				dojo.parser.parse();
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<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
+		</button>
+		<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>
+		</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") },
+				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",
+					onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Create blank</span>
+				<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"
+			data-dojo-props='onChange:function(val){ console.log("toggled button checked="+val); }, iconClass:"dijitRadioIcon"'>
+			Toggle me
+		</button>
+
+		<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="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") }'/>
+		</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") }'/>
+			<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") }'/>
+		</fieldset>
+
+		<h1>TextBoxes</h1>
+		<label for="q03">NumberSpinner:</label>
+		<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",
+			maxLength:"3",
+			constraints:{places:0,min:0,max:120},
+			onChange:function(val){ console.log(val); },
+			tooltipPosition:["above", "below"]
+		'/>
+		<label for="locald">Date:</label>
+		<input id="local" 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"
+			   name="time" value="T17:45:00" onChange="console.log(arguments[0]);"
+		/>
+
+		<h1>Selects</h1>
+		<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">
+			<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" selected>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>
+
+		<h1>HorizontalSlider</h1>
+		<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:"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%"}'>
+					<li>lowest</li>
+					<li>normal</li>
+					<li>highest</li>
+				</ol>
+		</div>
+	</body>
+</html>
diff --git a/dijit/tests/form/module.js b/dijit/tests/form/module.js
index f98c692..ecdd953 100644
--- a/dijit/tests/form/module.js
+++ b/dijit/tests/form/module.js
@@ -3,15 +3,21 @@ dojo.provide("dijit.tests.form.module");
 try{
 	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?");
 
+	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.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.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);
 
@@ -22,9 +28,9 @@ try{
 	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.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);
 
@@ -38,14 +44,15 @@ try{
 	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.DateTextBox", dojo.moduleUrl("dijit","tests/form/DateTextBox.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);
diff --git a/dijit/tests/form/robot/Button_a11y.html b/dijit/tests/form/robot/Button_a11y.html
index c0a21f1..1c56b73 100644
--- a/dijit/tests/form/robot/Button_a11y.html
+++ b/dijit/tests/form/robot/Button_a11y.html
@@ -9,15 +9,14 @@
 		</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"></script>
 
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Button.html');
 
 				var submitCount = 0, resetCount = 0;
@@ -36,22 +35,32 @@
 
 				doh.register("dijit.form.Button", [
 					{
+						name: "label",
+						timeout: 1000,
+						runTest: function(){
+							var label = dijit.byId("T1465").containerNode.innerHTML;
+							doh.is('Create', dojo.trim(label), "source.innerHTML label " + label);
+							var label2 = dijit.byId("T1466").containerNode.innerHTML;
+							doh.is('View', label2, "subclass label " + label2);
+						}
+					},
+					{
 						name: "enabled",
-						timeout: 15000,
+						timeout: 5000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.sequence(function(){ dojo.byId("input").focus(); });
+							dojo.byId("input").focus();
 
 							var clicks = 0;
-							dijit.byId("1465").set("onClick", function(){ clicks++; });
+							dijit.byId("T1465").set("onClick", function(){ clicks++; });
 
 
 							// tab into button to get focus
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							doh.robot.keyPress(dojo.keys.TAB, 1000, {});
 
 							// and activate	with space / enter
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+							doh.robot.keyPress(dojo.keys.SPACE, 1000, {});
 							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -62,21 +71,21 @@
 					},
 					{
 						name: "disabled no focus",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.is("1465", dijit.getEnclosingWidget(dojo.global.dijit._curFocus).id, "focus starting on 1465");
+							doh.is("T1465", dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode).id, "focus starting on 1465");
 
-							dijit.byId("1466").set("disabled", true);
+							dijit.byId("T1466").set("disabled", true);
 
 							// tab over disabled "View" button to "Create" combo-button
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								console.log("current focus is ", dojo.global.dijit._curFocus);
-								doh.is("comboCreate", dijit.getEnclosingWidget(dojo.global.dijit._curFocus).id, "focus jumped to combo create (left part of button)");
-							}), 500);
+								console.log("current focus is ", dojo.global.dijit.focus.curNode);
+								doh.is("comboCreate", dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode).id, "focus jumped to combo create (left part of button)");
+							}), 1000);
 							return d;
 						}
 					}
@@ -85,7 +94,7 @@
 				doh.register("dijit.form.DropDownButton", [
 					{
 						name: "down arrow opens menu",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -94,7 +103,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isVisible("editMenu"), "edit menu is visible: " + dijit.byId("editMenu").domNode.style.cssText);
-								doh.is("cut", dojo.global.dijit._curFocus.id, "focus is on menu");
+								doh.is("cut", dojo.global.dijit.focus.curNode.id, "focus is on menu");
 							}), 500);
 							return d;
 						}
@@ -102,7 +111,7 @@
 
 					{
 						name: "esc closes menu",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -110,14 +119,14 @@
 
 							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._curFocus.id, "focus is back on button");
+								doh.is("edit", dojo.global.dijit.focus.curNode.id, "focus is back on button");
 							}), 1000);
 							return d;
 						}
 					},
 					{
 						name: "space opens menu",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -133,7 +142,7 @@
 
 					{
 						name: "space executes menu",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -141,14 +150,14 @@
 
 							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._curFocus.id, "focus is back on button");
+								doh.is("edit", dojo.global.dijit.focus.curNode.id, "focus is back on button");
 							}), 1000);
 							return d;
 						}
 					},
 					{
 						name: "enter opens menu",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -164,7 +173,7 @@
 
 					{
 						name: "tab key closes popup, goes back to button",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -172,14 +181,14 @@
 
 							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._curFocus.id, "focus is back on button");
+								doh.is("edit", dojo.global.dijit.focus.curNode.id, "focus is back on button");
 							}), 1000);
 							return d;
 						}
 					},
 					{
 						name: "enter opens menu again",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -195,7 +204,7 @@
 
 					{
 						name: "enter closes menu (#4772)",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -203,7 +212,7 @@
 
 							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._curFocus.id, "focus is back on button");
+								doh.is("edit", dojo.global.dijit.focus.curNode.id, "focus is back on button");
 							}), 1000);
 							return d;
 						}
@@ -214,22 +223,20 @@
 				doh.register("dijit.form.ComboButton", [
 					{
 						name: "tab to button",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.sequence(function(){
-								dijit.byId("color").focus();
-							});
+							dijit.byId("color").focus();
 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							doh.robot.keyPress(dojo.keys.TAB, 1000, {});
 
 							var leftPart = dojo.query(".dijitButtonContents", dojo.byId("save"))[0];
 							doh.t(leftPart, "found left part of button");
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(leftPart, dojo.global.dijit._curFocus, "focused on left part");
-								console.log("cur focus: ",  dojo.global.dijit._curFocus);
+								doh.is(leftPart, dojo.global.dijit.focus.curNode, "focused on left part");
+								console.log("cur focus: ",  dojo.global.dijit.focus.curNode);
 							}), 1000);
 							return d;
 						}
@@ -237,7 +244,7 @@
 
 					{
 						name: "click button",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -255,7 +262,7 @@
 
 					{
 						name: "tab to drop down arrow",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -265,7 +272,7 @@
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(rightPart, dojo.global.dijit._curFocus, "focused on right part of combo");
+								doh.is(rightPart, dojo.global.dijit.focus.curNode, "focused on right part of combo");
 							}), 1000);
 							return d;
 						}
@@ -273,7 +280,7 @@
 
 					{
 						name: "down arrow opens menu",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -291,7 +298,7 @@
 
 					{
 						name: "esc closes menu",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -302,7 +309,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isHidden("saveMenu"), "save menu was closed: " + dijit.byId("saveMenu").domNode.style.cssText);
-								doh.is(rightPart, dojo.global.dijit._curFocus, "refocused on right part of combo");
+								doh.is(rightPart, dojo.global.dijit.focus.curNode, "refocused on right part of combo");
 							}), 1000);
 							return d;
 						}
@@ -310,7 +317,7 @@
 
 					{
 						name: "enter key opens menu",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -325,7 +332,7 @@
 
 					{
 						name: "tab closes menu",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -336,7 +343,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isHidden("saveMenu"), "save menu was closed: " + dijit.byId("saveMenu").domNode.style.cssText);
-								doh.is(rightPart, dojo.global.dijit._curFocus, "refocused on right part of combo");
+								doh.is(rightPart, dojo.global.dijit.focus.curNode, "refocused on right part of combo");
 							}), 1000);
 							return d;
 						}
@@ -344,25 +351,22 @@
 
 					{
 						name: "tab closes menu",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.sequence(function(){
-								// Focus element before "save" ComboButton
-								dijit.byId("color").focus();
-
-								// And disable the ComboButton
-								dijit.byId("save").set("disabled", true);
-							});
+							// Focus element before "save" ComboButton
+							dijit.byId("color").focus();
+							// And disable the ComboButton
+							dijit.byId("save").set("disabled", true);
 
 							// Tab should skip over the ComboButton entirely
-							doh.robot.keyPress(dojo.keys.TAB, 100, {});
+							doh.robot.keyPress(dojo.keys.TAB, 1000, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								var focusedWidget = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
+								var focusedWidget = dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode);
 								doh.isNot("save", focusedWidget && focusedWidget.id, "didn't focus on combo");
-							}), 500);
+							}), 1000);
 							return d;
 						}
 					}
@@ -371,12 +375,13 @@
 				doh.register("dijit.form.ToggleButton", [
 					{
 						name: "uncheck",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							var checked = dijit.byId("toggle1").get("checked");
 							doh.t(checked, "toggle1 initially checked");
+							doh.is("true", dojo.byId('toggle1').getAttribute("aria-pressed"), "aria-pressed 1");
 
 							var watchOld, watchNew;
 							dijit.byId("toggle1").set("onChange", function(v){ checked = v; });
@@ -385,13 +390,12 @@
 								watchNew = n;
 							});
 
-							doh.robot.sequence(function(){
-								dijit.byId("toggle1").focus();
-							});
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+							dijit.byId("toggle1").focus();
+							doh.robot.keyPress(dojo.keys.SPACE, 1000, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.f(checked, "toggle1 unchecked");
+								doh.is("false", dojo.byId('toggle1').getAttribute("aria-pressed"), "aria-pressed 2");
 								doh.t(watchOld, "watch: previous == checked");
 								doh.f(watchNew, "watch: new == unchecked");
 							}), 1000);
@@ -400,12 +404,13 @@
 					},
 					{
 						name: "check",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							var checked = dijit.byId("toggle1").get("checked");
 							doh.f(checked, "toggle1 unchecked");
+							doh.is("false", dojo.byId('toggle1').getAttribute("aria-pressed"), "aria-pressed 1");
 
 							var watchOld, watchNew;
 							dijit.byId("toggle1").set("onChange", function(v){ checked = v; });
@@ -414,13 +419,12 @@
 								watchNew = n;
 							});
 
-							doh.robot.sequence(function(){
-								dijit.byId("toggle1").focus();
-							});
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+							dijit.byId("toggle1").focus();
+							doh.robot.keyPress(dojo.keys.SPACE, 1000, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(checked, "toggle1 checked");
+								doh.is("true", dojo.byId('toggle1').getAttribute("aria-pressed"), "aria-pressed 2");
 								doh.f(watchOld, "watch: previous == unchecked");
 								doh.t(watchNew, "watch: new == checked");
 							}), 1000);
@@ -438,10 +442,8 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							submitCount = 0;
-							doh.robot.sequence(function(){
-								dijit.byId("bSubmit").focus();
-							});
-							doh.robot.keyPress(dojo.keys[key], 500, {});
+							dijit.byId("bSubmit").focus();
+							doh.robot.keyPress(dojo.keys[key], 1000, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.is(1, submitCount, (key + ": # of times submit invoked " + submitCount));
@@ -459,16 +461,13 @@
 							resetCount = 0;
 							dijit.byId("testName").value = "";
 
-
-							doh.robot.sequence(function(){
-								dijit.byId("testName").focus();
-							},500);
-							doh.robot.typeKeys("test", 500, 2000);
+							dijit.byId("testName").focus();
+							doh.robot.typeKeys("test", 1000, 2000);
 
 							doh.robot.sequence(function(){
 								dijit.byId("bReset").focus();
-							},500);
-							doh.robot.keyPress(dojo.keys[key], 500, {});
+							}, 500);
+							doh.robot.keyPress(dojo.keys[key], 1000, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.is(1, resetCount, (key + ": reset should be invoked 1 time. actual count = " + resetCount));
@@ -486,10 +485,8 @@
 					runTest: function(){
 						var d = new doh.Deferred();
 						submitCount = 0;
-						doh.robot.sequence(function(){
-							dijit.byId("testName").focus();
-						});
-						doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+						dijit.byId("testName").focus();
+						doh.robot.keyPress(dojo.keys.ENTER, 1000, {});
 
 						doh.robot.sequence(d.getTestCallback(function(){
 							doh.is(1, submitCount, "submitted via enter key on input");
diff --git a/dijit/tests/form/robot/Button_mouse.html b/dijit/tests/form/robot/Button_mouse.html
index 7cb35cd..a94526a 100644
--- a/dijit/tests/form/robot/Button_mouse.html
+++ b/dijit/tests/form/robot/Button_mouse.html
@@ -9,28 +9,27 @@
 		</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"></script>
 
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Button.html');
 
 				doh.register("dijit.form.Button", [
 					{
 						name: "enabled",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							var clicked = false;
-							dijit.byId("1466").set("onClick", function(){ clicked = true; });
+							dijit.byId("T1466").set("onClick", function(){ clicked = true; });
 
-							doh.robot.mouseMoveAt("1466", 500);
+							doh.robot.mouseMoveAt("T1466", 500);
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -41,7 +40,7 @@
 					},
 					{
 						name: "disabled",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -53,7 +52,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								if(!dojo.isWebKit){		// webkit bug, see #11064
-									doh.f(dojo.isDescendant(dojo.global.dijit._curFocus, dijit.byId("disabled").domNode), "not focused on button")
+									doh.f(dojo.isDescendant(dojo.global.dijit.focus.curNode, dijit.byId("disabled").domNode), "not focused on button")
 								}
 								doh.f(clicked, "click event wasn't fired");
 							}), 1000);
@@ -65,7 +64,7 @@
 				doh.register("dijit.form.DropDownButton", [
 					{
 						name: "click button",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -81,7 +80,7 @@
 
 					{
 						name: "click menu",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -100,7 +99,7 @@
 				doh.register("dijit.form.ComboButton", [
 					{
 						name: "click button",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -122,7 +121,7 @@
 
 					{
 						name: "click drop down button",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -141,7 +140,7 @@
 
 					{
 						name: "click menu",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -157,7 +156,7 @@
 
 					{
 						name: "disabled click button",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -174,7 +173,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								if(!dojo.isWebKit){ // webkit bug, see #11064
-									doh.f(dojo.isDescendant(dojo.global.dijit._curFocus, dijit.byId("save").domNode), "not focused on button")
+									doh.f(dojo.isDescendant(dojo.global.dijit.focus.curNode, dijit.byId("save").domNode), "not focused on button")
 								}
 								doh.f(clicked, "click event wasn't fired");
 							}), 1000);
@@ -184,7 +183,7 @@
 
 					{
 						name: "disabled click drop down button",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -196,19 +195,38 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								if(!dojo.isWebKit){		// webkit bug, see #11064
-									doh.f(dojo.isDescendant(dojo.global.dijit._curFocus, dijit.byId("save").domNode), "not focused on button")
+									doh.f(dojo.isDescendant(dojo.global.dijit.focus.curNode, dijit.byId("save").domNode), "not focused on button")
 								}
 								doh.t(isHidden("saveMenu"), "save menu is still hidden: " + dijit.byId("saveMenu").domNode.style.cssText);
 							}), 1000);
 							return d;
 						}
+					},
+					{
+						name: "tabIndex",
+						timeout: 1000,
+						runTest: function(){
+							var btn = dijit.byId("save"),
+								focusNode = btn.focusNode,
+								titleNode = btn.titleNode;
+
+							btn.set("disabled", true);
+							doh.t(btn.get("disabled"), "save button is disabled");
+							doh.f(dojo.hasAttr(focusNode, "tabIndex") && dojo.attr(focusNode, "tabIndex") >= 0, "disabled focusNode tabIndex");
+							doh.f(dojo.hasAttr(titleNode, "tabIndex") && dojo.attr(titleNode, "tabIndex") >= 0, "disabled titleNode tabIndex");
+
+							btn.set("disabled", false);
+							doh.f(btn.get("disabled"), "save button is enabled");
+							doh.is(0, dojo.attr(focusNode, "tabIndex"), "enabled focusNode tabIndex");
+							doh.is(0, dojo.attr(titleNode, "tabIndex"), "enabled titleNode tabIndex");
+						}
 					}
 				]);
 
 				doh.register("dijit.form.ToggleButton", [
 					{
 						name: "initially checked",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -227,7 +245,7 @@
 					},
 					{
 						name: "initially unchecked",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -246,7 +264,7 @@
 					},
 					{
 						name: "disabled",
-						timeout: 15000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -260,7 +278,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								if(!dojo.isWebKit){		// webkit bug, see #11064
-									doh.f(dojo.isDescendant(dojo.global.dijit._curFocus, dijit.byId("toggle1").domNode), "not focused on button")
+									doh.f(dojo.isDescendant(dojo.global.dijit.focus.curNode, dijit.byId("toggle1").domNode), "not focused on button")
 								}
 								doh.f(changed, "value didn't change");
 							}), 1000);
@@ -281,26 +299,38 @@
 					{
 						name: "icon",
 						runTest: function(){
-							doh.f(dojo.hasClass(dijit.byId("1466").iconNode, "plusIcon"), "doesn't plus icon class");
-							dijit.byId("1466").set("iconClass", "plusIcon");
-							doh.t(dojo.hasClass(dijit.byId("1466").iconNode, "plusIcon"), "has plus icon class");
+							// initial condition: no icon
+							doh.f(dojo.hasClass(dijit.byId("T1466").iconNode, "plusIcon"), "doesn't have plusIcon class");
+							doh.is("none", dojo.style(dijit.byId("T1466").iconNode, "display"), "initially hidden");
+
+							// no icon --> icon
+							dijit.byId("T1466").set("iconClass", "plusIcon");
+							doh.t(dojo.hasClass(dijit.byId("T1466").iconNode, "plusIcon"), "plusIcon class added");
+							doh.isNot("none", dojo.style(dijit.byId("T1466").iconNode, "display"), "became visible");
 
-							// switching icon erases old one
-							dijit.byId("1466").set("iconClass", "noteIcon");
-							doh.f(dojo.hasClass(dijit.byId("1466").iconNode, "plusIcon"), "doesn't plus icon class");
+							// switching icon
+							dijit.byId("T1466").set("iconClass", "noteIcon");
+							doh.f(dojo.hasClass(dijit.byId("T1466").iconNode, "plusIcon"), "plusIcon cleared");
+							doh.t(dojo.hasClass(dijit.byId("T1466").iconNode, "noteIcon"), "noteIcon added");
+
+							// initial conditions for buttons with icon
+							doh.t(dojo.hasClass(dijit.byId("dropDownNoLabel").iconNode, "noteIcon"),
+									"dropDownNoLabel: noteIcon set");
+							doh.t(dojo.hasClass(dijit.byId("comboNoLabel").iconNode, "plusBlockIcon"),
+									"comboNoLabel: plusBlockIcon set");
+							doh.t(isVisible(dijit.byId("comboNoLabel").iconNode),
+									"comboNoLabel: initially visible");
 						}
 					},
 
 					{
 						name: "disable",
-						timeout: 15000,
+						timeout: 6000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							dijit.byId("save").set("disabled", true);
 
-							var d = new doh.Deferred();
-
 							// click left side of button
 							var leftPart = dojo.query(".dijitButtonContents", dojo.byId("save"))[0];
 							doh.t(leftPart, "found left part of button");
@@ -341,13 +371,13 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt('Plain', 500, 1);
+							doh.robot.mouseMoveAt('SubmitPlain', 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(nameBox.value, "Plain", "Plain name");
-								doh.is(valueBox.value, "Plain Submit", "Plain value");
-							}), 1000);
+								doh.is("Plain", nameBox.value, "Plain name");
+								doh.is("Plain Submit", valueBox.value, "Plain value");
+							}), 1500);
 
 							return d;
 						}
@@ -359,13 +389,13 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt('Combo', 500, 1);
+							doh.robot.mouseMoveAt('SubmitCombo', 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(nameBox.value, "Combo", "Combo name");
-								doh.is(valueBox.value, "Combo Submit", "Combo value");
-							}), 1000);
+								doh.is("Combo", nameBox.value, "Combo name");
+								doh.is("Combo Submit", valueBox.value, "Combo value");
+							}), 1500);
 
 							return d;
 						}
@@ -377,15 +407,15 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var downArrowNode = dojo.query(".dijitDownArrowButton", dojo.byId("Combo"))[0];
+							var downArrowNode = dojo.query(".dijitDownArrowButton", dojo.byId("SubmitCombo"))[0];
 
 							doh.robot.mouseMoveAt(downArrowNode, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(nameBox.value, "INIT", "Combo Down Arrow name");
-								doh.is(valueBox.value, "INIT", "Combo Down Arrow value");
-							}), 1000);
+								doh.is("INIT", nameBox.value, "Combo Down Arrow name");
+								doh.is("INIT", valueBox.value, "Combo Down Arrow value");
+							}), 1500);
 
 							return d;
 						}
@@ -397,13 +427,13 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt("ComboMenuItem", 500, 1);
+							doh.robot.mouseMoveAt("SubmitComboMenuItem", 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(nameBox.value, "", "Combo Arrow name");
-								doh.is(valueBox.value, "", "Combo Arrow value");
-							}), 1000);
+								doh.is("", nameBox.value, "Combo Arrow name");
+								doh.is("", valueBox.value, "Combo Arrow value");
+							}), 1500);
 
 							return d;
 						}
@@ -415,13 +445,13 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt('DropDown', 500, 1);
+							doh.robot.mouseMoveAt('SubmitDropDown', 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(nameBox.value, "DropDown", "DropDown name");
-								doh.is(valueBox.value, "DropDown Submit", "DropDown value");
-							}), 1000);
+								doh.is("DropDown", nameBox.value, "DropDown name");
+								doh.is("DropDown Submit", valueBox.value, "DropDown value");
+							}), 1500);
 
 							return d;
 						}
@@ -433,13 +463,13 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt("DropDownMenuItem", 500, 1);
+							doh.robot.mouseMoveAt("SubmitDropDownMenuItem", 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(nameBox.value, "", "DropDown Arrow name");
-								doh.is(valueBox.value, "", "DropDown Arrow value");
-							}), 1000);
+								doh.is("", nameBox.value, "DropDown Arrow name");
+								doh.is("", valueBox.value, "DropDown Arrow value");
+							}), 1500);
 
 							return d;
 						}
@@ -451,12 +481,12 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt('Disabled', 500, 1);
+							doh.robot.mouseMoveAt('SubmitDisabled', 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(nameBox.value, "INIT", "Disabled name");
-								doh.is(valueBox.value, "INIT", "Disabled value");
+								doh.is("INIT", nameBox.value, "Disabled name");
+								doh.is("INIT", valueBox.value, "Disabled value");
 							}), 1000);
 
 							return d;
@@ -477,8 +507,8 @@
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(dojo.byId('onClickName').value, "RESET");
-							}), 500);
+								doh.is("RESET", dojo.byId('onClickName').value);
+							}), 1000);
 
 							return d;
 						}
@@ -495,8 +525,8 @@
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(dojo.byId('onClickName').value, "RESET");
-							}), 500);
+								doh.is("RESET", dojo.byId('onClickName').value);
+							}), 1000);
 
 							return d;
 						}
@@ -513,8 +543,8 @@
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(dojo.byId('onClickName').value, "2");
-							}), 500);
+								doh.is("2", dojo.byId('onClickName').value);
+							}), 1000);
 
 							return d;
 						}
@@ -531,8 +561,8 @@
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(dojo.byId('onClickName').value, "2");
-							}), 500);
+								doh.is("2", dojo.byId('onClickName').value);
+							}), 1000);
 
 							return d;
 						}
@@ -549,8 +579,8 @@
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(dojo.byId('onClickName').value, "RESET");
-							}), 500);
+								doh.is("RESET", dojo.byId('onClickName').value);
+							}), 1000);
 
 							return d;
 						}
@@ -567,8 +597,8 @@
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(dojo.byId('onClickName').value, "RESET");
-							}), 500);
+								doh.is("RESET", dojo.byId('onClickName').value);
+							}), 1000);
 
 							return d;
 						}
@@ -585,8 +615,8 @@
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(dojo.byId('onClickName').value, "RESET");
-							}), 500);
+								doh.is("RESET", dojo.byId('onClickName').value);
+							}), 1000);
 
 							return d;
 						}
@@ -603,8 +633,8 @@
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(dojo.byId('onClickName').value, "RESET");
-							}), 500);
+								doh.is("RESET", dojo.byId('onClickName').value);
+							}), 1000);
 
 							return d;
 						}
@@ -621,8 +651,8 @@
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(dojo.byId('onClickName').value, "RESET");
-							}), 500);
+								doh.is("RESET", dojo.byId('onClickName').value);
+							}), 1000);
 
 							return d;
 						}
@@ -639,8 +669,8 @@
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(dojo.byId('onClickName').value, "RESET");
-							}), 500);
+								doh.is("RESET", dojo.byId('onClickName').value);
+							}), 1000);
 
 							return d;
 						}
diff --git a/dijit/tests/form/robot/CheckBox_a11y.html b/dijit/tests/form/robot/CheckBox_a11y.html
index e7e809e..af203a0 100644
--- a/dijit/tests/form/robot/CheckBox_a11y.html
+++ b/dijit/tests/form/robot/CheckBox_a11y.html
@@ -9,16 +9,15 @@
 		</style>
 
 		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			data-dojo-config="isDebug: true, parseOnLoad: true"></script>
+		<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.addOnLoad(function(){
-				doh.robot.initRobot('../test_Checkbox.html');
+			dojo.ready(function(){
+				doh.robot.initRobot('../test_CheckBox.html');
 
 				doh.register("Checkbox a11y",[
 					{
@@ -51,6 +50,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(dijit.byId('cb1').checked, "cb1 was not checked");
+								doh.is("true", dojo.byId('cb1').getAttribute("aria-checked"), "aria-checked");
 							}), 1000);
 
 							return d;
@@ -68,6 +68,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.f(dijit.byId('cb2').checked, "cb2 was checked");
+								doh.is("false", dojo.byId('cb2').getAttribute("aria-checked"), "aria-checked");
 							}), 1000);
 
 							return d;
@@ -85,6 +86,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(dijit.byId('cb4').checked, "cb4 was not checked");
+								doh.is("true", dojo.byId('cb4').getAttribute("aria-checked"), "aria-checked");
 							}), 1000);
 
 							return d;
@@ -103,6 +105,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.f(dijit.byId('cb6').checked, "cb6 was checked");
+								doh.is("false", dojo.byId('cb6').getAttribute("aria-checked"), "aria-checked");
 							}), 1000);
 
 							return d;
@@ -118,6 +121,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(dijit.byId('cb6').checked, "cb6 was not checked");
+								doh.is("true", dojo.byId('cb6').getAttribute("aria-checked"), "aria-checked");
 							}), 1000);
 
 							return d;
@@ -133,15 +137,16 @@
 							var d = new doh.Deferred();
  
 							dijit.byId("g1rb2").focus();
-							doh.robot.sequence(function(){
-								dijit.byId("g1rb3").set("disabled",false);
-							}, 1000); 
+							dijit.byId("g1rb3").set("disabled",false);
 							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000);
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.f(dijit.byId('g1rb1').checked, "news was checked");
 								doh.f(dijit.byId('g1rb2').checked, "talk was checked");
 								doh.t(dijit.byId('g1rb3').checked, "weather was not checked");
+								doh.is("false", dojo.byId('g1rb1').getAttribute("aria-checked")||"false", "aria-checked 1");
+								doh.is("false", dojo.byId('g1rb2').getAttribute("aria-checked")||"false", "aria-checked 2");
+								doh.is("true", dojo.byId('g1rb3').getAttribute("aria-checked"), "aria-checked 3");
 							}), 1000);
 
 							return d;
@@ -162,6 +167,9 @@
 								doh.t(dijit.byId('g2rb3').checked, "country was not checked");
 								doh.f(dijit.byId('g2rb2').checked, "oldies was checked");
 								doh.f(dijit.byId('g2rb1').checked, "top 40 was checked");
+								doh.is("false", dojo.byId('g2rb1').getAttribute("aria-checked")||"false", "aria-checked 1");
+								doh.is("false", dojo.byId('g2rb2').getAttribute("aria-checked")||"false", "aria-checked 2");
+								doh.is("true", dojo.byId('g2rb3').getAttribute("aria-checked"), "aria-checked 3");
 							}), 1000);
 
 							return d;
@@ -180,6 +188,9 @@
 								doh.f(dijit.byId('g2rb3').checked, "country was checked");
 								doh.f(dijit.byId('g2rb2').checked, "oldies was checked");
 								doh.t(dijit.byId('g2rb1').checked, "top 40 was not checked");
+								doh.is("true", dojo.byId('g2rb1').getAttribute("aria-checked"), "aria-checked 1");
+								doh.is("false", dojo.byId('g2rb2').getAttribute("aria-checked")||"false", "aria-checked 2");
+								doh.is("false", dojo.byId('g2rb3').getAttribute("aria-checked")||"false", "aria-checked 3");
 							}), 1000);
 
 							return d;
diff --git a/dijit/tests/form/robot/CheckBox_mouse.html b/dijit/tests/form/robot/CheckBox_mouse.html
index 6043f5d..144a791 100644
--- a/dijit/tests/form/robot/CheckBox_mouse.html
+++ b/dijit/tests/form/robot/CheckBox_mouse.html
@@ -9,8 +9,7 @@
 		</style>
 
 		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			data-dojo-config="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
 		<script type="text/javascript" src="../../helpers.js"></script>
 
@@ -67,8 +66,8 @@
 				g2: "country"
 			};
 		
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot('../test_Checkbox.html');
+			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", [
diff --git a/dijit/tests/form/robot/DateTextBox.html b/dijit/tests/form/robot/DateTextBox.html
index 5ea63d4..f6dcd26 100644
--- a/dijit/tests/form/robot/DateTextBox.html
+++ b/dijit/tests/form/robot/DateTextBox.html
@@ -10,15 +10,14 @@
 		</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"></script>
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 			dojo.require("dojo.date");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_DateTextBox.html');
 
 				// refs to DateTextBox widgets
@@ -27,6 +26,10 @@
 				// log of calls to onChange handler, and watch(value)
 				var changes = [], watches = [];
 
+				// ctrl-page-down / page-up will go forward/barck a year, except on chrome where
+				// it switches browser tabs.   use alt instead
+				var yearModifierKey = dojo.isChrome ? {alt: true} : {ctrl: true};
+
 				doh.register("setup",
 					function setUp(){
 						// refs to DateTextBox widgets
@@ -240,7 +243,7 @@
 								doh.is("10", innerText(selectedDays[0]), "correct day is selected");
 
 								// focus moved to the calendar
-								doh.is(10, innerText(dojo.global.dijit._curFocus), "focus on selected calendar cell")
+								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");
@@ -271,7 +274,7 @@
 								doh.is(10, innerText(selectedDays[0]), "correct day is selected");
 
 								// focus still on the calendar, moved forward 2 days
-								doh.is(12, innerText(dojo.global.dijit._curFocus), "focus")
+								doh.is(12, innerText(dojo.global.dijit.focus.curNode), "focus");
 
 								doh.is(0, changes.length, "no onchange events yet");
 								doh.is(0, watches.length, "no watch(value) events yet");
@@ -296,7 +299,7 @@
 								doh.t(isVisible(calendar), "calendar is visible");
 
 								// focus still on the calendar, moved back 1 day
-								doh.is(11, innerText(dojo.global.dijit._curFocus), "focus")
+								doh.is(11, innerText(dojo.global.dijit.focus.curNode), "focus");
 
 								doh.is(0, changes.length, "no onchange events yet");
 								doh.is(0, watches.length, "no watch(value) events yet");
@@ -327,7 +330,7 @@
 								doh.is("June", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "month changed");
 
 								// and focused day changed
-								doh.is(8, innerText(dojo.global.dijit._curFocus), "focus")
+								doh.is(8, innerText(dojo.global.dijit.focus.curNode), "focus");
 
 								doh.is(0, changes.length, "no onchange events yet");
 								doh.is(0, watches.length, "no watch(value) events yet");
@@ -357,7 +360,7 @@
 								doh.is("May", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "month changed");
 
 								// focused day still the same
-								doh.is(18, innerText(dojo.global.dijit._curFocus), "focus")
+								doh.is(18, innerText(dojo.global.dijit.focus.curNode), "focus");
 
 								doh.is(0, changes.length, "no onchange events yet");
 								doh.is(0, watches.length, "no watch(value) events yet");
@@ -383,7 +386,7 @@
 								doh.t(isVisible(calendar), "calendar is visible");
 
 								// focused day still the same
-								doh.is(18, innerText(dojo.global.dijit._curFocus), "focus")
+								doh.is(18, innerText(dojo.global.dijit.focus.curNode), "focus");
 
 								// month changed
 								doh.is("July", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "month changed");
@@ -411,7 +414,7 @@
 								doh.t(isVisible(calendar), "calendar is visible");
 
 								// focused day still the same
-								doh.is(18, innerText(dojo.global.dijit._curFocus), "focus")
+								doh.is(18, innerText(dojo.global.dijit.focus.curNode), "focus");
 
 								// month changed
 								doh.is("June", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "month changed");
@@ -431,8 +434,8 @@
 							var d = new doh.Deferred();
 							var calendar = dijit.byId("american_popup");
 
-							doh.robot.keyPress(dojo.keys.PAGE_DOWN, 750, {ctrl: true});
-							doh.robot.keyPress(dojo.keys.PAGE_DOWN, 750, {ctrl: true});
+							doh.robot.keyPress(dojo.keys.PAGE_DOWN, 750, yearModifierKey);
+							doh.robot.keyPress(dojo.keys.PAGE_DOWN, 750, yearModifierKey);
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								// calendar still exists and is shown
@@ -440,7 +443,7 @@
 								doh.t(isVisible(calendar), "calendar is visible");
 
 								// focused day still the same (focused even though disabled)
-								doh.is(18, innerText(dojo.global.dijit._curFocus), "focus")
+								doh.is(18, innerText(dojo.global.dijit.focus.curNode), "focus");
 
 								// same month
 								doh.is("June", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "same month");
@@ -465,7 +468,7 @@
 							var d = new doh.Deferred();
 							var calendar = dijit.byId("american_popup");
 
-							doh.robot.keyPress(dojo.keys.PAGE_UP, 750, {ctrl: true});
+							doh.robot.keyPress(dojo.keys.PAGE_UP, 750, yearModifierKey);
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								// calendar still exists and is shown
@@ -473,7 +476,7 @@
 								doh.t(isVisible(calendar), "calendar is visible");
 
 								// focused day still the same
-								doh.is(18, innerText(dojo.global.dijit._curFocus), "focus")
+								doh.is(18, innerText(dojo.global.dijit.focus.curNode), "focus");
 
 								// same month
 								doh.is("June", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "same month");
@@ -506,7 +509,7 @@
 								doh.t(isVisible(calendar), "calendar is visible");
 
 								// focused on first day of month
-								doh.is(1, innerText(dojo.global.dijit._curFocus), "focus")
+								doh.is(1, innerText(dojo.global.dijit.focus.curNode), "focus");
 
 								doh.is(0, changes.length, "no onchange events yet");
 								doh.is(0, watches.length, "no watch(value) events yet");
@@ -531,7 +534,7 @@
 								doh.t(isVisible(calendar), "calendar is visible");
 
 								// focused on last day of month
-								doh.is(30, innerText(dojo.global.dijit._curFocus), "focus")
+								doh.is(30, innerText(dojo.global.dijit.focus.curNode), "focus");
 
 								doh.is(0, changes.length, "no onchange events yet");
 								doh.is(0, watches.length, "no watch(value) events yet");
@@ -562,7 +565,7 @@
 								doh.is(0, dojo.date.compare(expectedVal, watches[0]), 'watch(value) of american: ' + watches[0]);
 
 								// focus moved back to <input>
-								doh.is("american", dojo.global.dijit._curFocus.id, "focus on <input>")
+								doh.is("american", dojo.global.dijit.focus.curNode.id, "focus on <input>")
 							}), 1000);
 
 							return d;
@@ -580,7 +583,7 @@
 							doh.robot.sequence(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._curFocus.id, "tabbed from american to german")
+								doh.is("german", dojo.global.dijit.focus.curNode.id, "tabbed from american to german")
 							}), 1000);
 							return d;
 						}
@@ -705,14 +708,14 @@
 							var calendar = dijit.byId("american_popup");
 
 							doh.is(1, dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode).length, "found month label");
-							doh.t(calendar.monthDropDownButton.dropDown, "month dropdown exists");
-							doh.f(isVisible(calendar.monthDropDownButton.dropDown), "month dropdown is not visible");
+							doh.t(calendar.monthWidget.dropDown, "month dropdown exists");
+							doh.f(isVisible(calendar.monthWidget.dropDown), "month dropdown is not visible");
 
 							doh.robot.mouseMoveAt(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0], 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							
 							doh.robot.mouseMoveAt(function(){
-								return dojo.query("[month=6]", calendar.monthDropDownButton.dropDown.domNode)[0];
+								return dojo.query("[month=6]", calendar.monthWidget.dropDown.domNode)[0];
 							}, 1000, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
@@ -919,14 +922,13 @@
 						name: "today",
 						timeout: 6000,
 						setUp: function(){
-							german.closeDropDown();
+							german.closeDropDown(true);	// close drop down and focus widget
 							german.set('value', null);
 							german.set("dropDownDefaultValue", null);
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							german.focus();
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -942,21 +944,20 @@
 							return d;
 						},
 						tearDown: function(){
-							german.closeDropDown();
+							german.closeDropDown(true);
 						}
 					},
 					{
 						name: "dropDownDefaultValue",
 						timeout: 6000,
 						setUp: function(){
-							german.closeDropDown();
+							german.closeDropDown(true);
 							german.set('value', null);
 							german.set("dropDownDefaultValue", new Date(2000,11,21));
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							german.focus();
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -966,13 +967,13 @@
 								var selectedDates = dojo.query(".dijitCalendarSelectedDate", german.dropDown.domNode);
 								doh.is(0, selectedDates.length, "no selected date");
 	
-								doh.is("21", innerText(dojo.global.dijit._curFocus), "but focused on the 21st");
+								doh.is("21", innerText(dojo.global.dijit.focus.curNode), "but focused on the 21st");
 							}), 500);
 
 							return d;
 						},
 						tearDown: function(){
-							german.closeDropDown();
+							german.closeDropDown(true);
 						}
 					},
 
@@ -981,14 +982,13 @@
 						name: "textbox value",
 						timeout: 6000,
 						setUp: function(){
-							german.closeDropDown();
+							german.closeDropDown(true);
 							german.set("dropDownDefaultValue", new Date(2000,11,21));
 							german.set('value', new Date(1900,10,25));
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							german.focus();
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -999,13 +999,13 @@
 								doh.is(1, selectedDates.length, "one selected date");
 								doh.is("25", innerText(selectedDates[0]), "25th is selected");
 	
-								doh.is("25", innerText(dojo.global.dijit._curFocus), "and also focused on the 25th");
+								doh.is("25", innerText(dojo.global.dijit.focus.curNode), "and also focused on the 25th");
 							}), 500);
 
 							return d;
 						},
 						tearDown: function(){
-							german.closeDropDown();
+							german.closeDropDown(true);
 						}
 					}
 				]);
@@ -1073,7 +1073,7 @@
 								doh.is("2010", innerText(selectedYearButtons[0]), "current year");
 
 								// and the currently focused date is the 31'st
-								doh.is("31", innerText(dojo.global.dijit._curFocus), "correct day is focused");
+								doh.is("31", innerText(dojo.global.dijit.focus.curNode), "correct day is focused");
 							}), 1000);
 
 							return d;
@@ -1089,14 +1089,14 @@
 							var calendar = dijit.byId("american_popup");
 
 							doh.is(1, dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode).length, "found month label");
-							doh.t(calendar.monthDropDownButton.dropDown, "month dropdown exists");
-							doh.f(isVisible(calendar.monthDropDownButton.dropDown), "month dropdown is not visible");
+							doh.t(calendar.monthWidget.dropDown, "month dropdown exists");
+							doh.f(isVisible(calendar.monthWidget.dropDown), "month dropdown is not visible");
 
 							doh.robot.mouseMoveAt(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0], 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.mouseMoveAt(function(){
-								return dojo.query("[month=1]", calendar.monthDropDownButton.dropDown.domNode)[0];
+								return dojo.query("[month=1]", calendar.monthWidget.dropDown.domNode)[0];
 							}, 1000, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
@@ -1125,14 +1125,14 @@
 							var calendar = dijit.byId("american_popup");
 
 							doh.is(1, dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode).length, "found month label");
-							doh.t(calendar.monthDropDownButton.dropDown, "month dropdown exists");
-							doh.f(isVisible(calendar.monthDropDownButton.dropDown), "month dropdown is not visible");
+							doh.t(calendar.monthWidget.dropDown, "month dropdown exists");
+							doh.f(isVisible(calendar.monthWidget.dropDown), "month dropdown is not visible");
 
 							doh.robot.mouseMoveAt(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0], 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.mouseMoveAt(function(){
-								return dojo.query("[month=11]", calendar.monthDropDownButton.dropDown.domNode)[0];
+								return dojo.query("[month=11]", calendar.monthWidget.dropDown.domNode)[0];
 							}, 1000, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
@@ -1181,7 +1181,7 @@
 							doh.robot.sequence(d.getTestErrback(function(){
 								var calendar = dijit.byId("localLong_popup");
 								doh.f(calendar && isVisible(calendar), "calendar isn't visible");
-								doh.is(localLong.focusNode, dojo.global.dijit._curFocus, "focused on input");
+								doh.is(localLong.focusNode, dojo.global.dijit.focus.curNode, "focused on input");
 							}), 1000);
 
 							doh.robot.mouseMoveAt(localLong._buttonNode, 0, 1);
diff --git a/dijit/tests/form/robot/Form_onsubmit.html b/dijit/tests/form/robot/Form_onsubmit.html
index 47a83a4..2ce2878 100644
--- a/dijit/tests/form/robot/Form_onsubmit.html
+++ b/dijit/tests/form/robot/Form_onsubmit.html
@@ -9,85 +9,114 @@
 		</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"></script>
 
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Form_onsubmit.html');
 
+				var textbox;
+				var handler;
 				doh.register("onsubmit", [
 					{
 						name: "submit1",
-						timeout: 9000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
+
+							textbox = dijit.byId("textbox");
+							//reset the submit textbox
+							textbox.set('value', "", false);
+							handler = textbox.connect(textbox, 'onChange', function(){
+								d.errback('onChange should not have fired');
+							});
 							
-							doh.robot.mouseMoveAt("submit1", 500, 0);
+							doh.robot.mouseMoveAt("submit1", 1000, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("", dijit.byId("textbox").get('value'));
+								doh.is("", textbox.get('value'));
 							}), 1000);
+
 							return d;
+						},
+						tearDown: function(){
+							textbox.disconnect(handler);
 						}
 					},
 					{
 						name: "submit2",
-						timeout: 9000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							//reset the submit textbox
-							dijit.byId("textbox").set('value',"");
+							textbox.set('value', "", false);
+							handler = textbox.connect(textbox, 'onChange', function(){
+								d.errback('onChange should not have fired');
+							});
 														
-							doh.robot.mouseMoveAt("submit2", 500, 0);
+							doh.robot.mouseMoveAt("submit2", 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("", dijit.byId("textbox").get('value'));
+								doh.is("", textbox.get('value'));
 							}), 1000);
+
 							return d;
+						},
+						tearDown: function(){
+							textbox.disconnect(handler);
 						}
 					},
 					{
 						name: "submit3",
-						timeout: 9000,
+						timeout: 5000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							
+
 							//reset the submit textbox
-							dijit.byId("textbox").set('value',"");
+							textbox.set('value', "", false);
 
-							doh.robot.mouseMoveAt("submit3", 500, 0);
+							handler = textbox.connect(textbox, 'onChange',
+								d.getTestCallback(function(){
+									doh.is("one", textbox.get('value'));
+								})
+							);
+							doh.robot.mouseMoveAt("submit3", 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("one", dijit.byId("textbox").get('value'));
-							}), 1000);
+
 							return d;
+						},
+						tearDown: function(){
+							textbox.disconnect(handler);
 						}
 					},
 					{
 						name: "submit4",
-						timeout: 9000,
+						timeout: 5000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							//reset the submit textbox
-							dijit.byId("textbox").set('value',"");
+							textbox.set('value', "", false);
 							
-							doh.robot.mouseMoveAt("submit4", 500, 0);
+							handler = textbox.connect(textbox, 'onChange',
+								d.getTestCallback(function(){
+									doh.is("one", textbox.get('value'));
+								})
+							);
+							doh.robot.mouseMoveAt("submit4", 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("one", dijit.byId("textbox").get('value'));
-							}), 1000);
 							return d;
+						},
+						tearDown: function(){
+							textbox.disconnect(handler);
 						}
 					},
 					{
@@ -96,7 +125,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt("combo1", 500, 0);
+							doh.robot.mouseMoveAt("combo1", 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
@@ -117,7 +146,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt("combo2", 500, 0);
+							doh.robot.mouseMoveAt("combo2", 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
@@ -140,9 +169,9 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt("combo3", 500, 0);
+							doh.robot.mouseMoveAt("combo3", 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
 							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
@@ -161,7 +190,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt("combo4", 500, 0);
+							doh.robot.mouseMoveAt("combo4", 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
diff --git a/dijit/tests/form/robot/Form_state.html b/dijit/tests/form/robot/Form_state.html
index 0ab8501..5ae48db 100644
--- a/dijit/tests/form/robot/Form_state.html
+++ b/dijit/tests/form/robot/Form_state.html
@@ -9,8 +9,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"></script>
 
 		<script type="text/javascript" src="../../helpers.js"></script>
 
@@ -20,8 +19,8 @@
 			// Some of these tests are duplicated in Form.html, maybe the Form.html watch(state) and validate()
 			// tests groups should be moved here.
 
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot('../test_Form_State.html');
+			dojo.ready(function(){
+				doh.robot.initRobot('../test_Form_state.html');
 
 				doh.register("FormValidationState", [
 					{
diff --git a/dijit/tests/form/robot/MultiSelect.html b/dijit/tests/form/robot/MultiSelect.html
index d2b60c9..16c4f86 100644
--- a/dijit/tests/form/robot/MultiSelect.html
+++ b/dijit/tests/form/robot/MultiSelect.html
@@ -9,31 +9,31 @@
 		</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"></script>
 
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			function testInverted(allOptions, selected, newSelected) {
+			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
 				dojo.forEach(allOptions, function(option){ //verify the selections were inverted
-					if(option.selected) {
+					var found;
+					if(option.selected){
 						//it must be in the newSelectedList
-						var found=false;
+						found=false;
 						dojo.forEach(newSelected, function(ns){
-							if(option.value===ns) {
+							if(option.value===ns){
 								found=true;
 							}
 						});
 						doh.t(found);
-					} else {
+					}else{
 						//it better be in the origional selected list
-						var found=false;
+						found=false;
 						dojo.forEach(selected, function(s){
-							if(option.value===s) {
+							if(option.value===s){
 								found=true;
 							}
 						});
@@ -42,7 +42,7 @@
 				});
 			}
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_MultiSelect.html');
 
 				doh.register("dijit.form.MultiSelect", [
@@ -86,6 +86,7 @@
 							doh.robot.sequence(function(){ selectedValue2 = dijit.byId('select2').get('value');}, 1000); 
 
 							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("16", dijit.byId('select2').value.toString());
 								doh.is("16", selectedValue2[0]);
 							}), 1000);
 							return d;
@@ -112,6 +113,7 @@
 								doh.is("7", selectedValue[1]);
 								doh.is("19", selectedValue[2]);
 								doh.is("47", selectedValue[3]);
+								doh.is("3 7 19 47", dijit.byId('select').value.join(' '));
 							}), 1000);
 							return d;
 						}
@@ -235,6 +237,7 @@
 								doh.is(2, selected.length);
 								doh.is(selected[0], 'VA');
 								doh.is(selected[1], 'WA');
+								doh.is("VA WA", dijit.byId('select3').value.join(' '));
 							}), 1000);
 							return d;
 						}
diff --git a/dijit/tests/form/robot/Select.html b/dijit/tests/form/robot/Select.html
index 5e871af..05ee051 100644
--- a/dijit/tests/form/robot/Select.html
+++ b/dijit/tests/form/robot/Select.html
@@ -10,15 +10,14 @@
 		</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"></script>
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 			dojo.require("dojo.date");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Select.html');
 
 				// refs to parts of s1 Select
@@ -41,6 +40,12 @@
 						s8b_menu = dijit.byId('s8b_menu');
 						s3 = dijit.byId('s3');
 						s3_menu = dijit.byId('s3_menu');
+						s13 = dijit.byId('s13');
+						s13_menu = dijit.byId('s13_menu');
+						s14 = dijit.byId('s14');
+						s14_menu = dijit.byId('s14_menu');
+
+						form = dijit.byId('form');
 
 						// preload menus since first load can take a while
 						var doNothing = function(){};
@@ -64,7 +69,7 @@
 							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(5, dojo.query("tr", s1_menu.domNode).length, "5 options in menu")
+								doh.is(5, dojo.query("tr", s1_menu.domNode).length, "5 options in menu");
 								
 								var selectedOptions = dojo.query(".dijitSelectSelectedOption .dijitMenuItemLabel", s1_menu.domNode);
 								doh.is(1, selectedOptions.length, "one selected option");
@@ -99,7 +104,7 @@
 							}), 1000);
 
 							// clicking away should close the drop down
-							doh.robot.mouseMove(10, 10, 500)
+							doh.robot.mouseMove(10, 10, 500);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isHidden(s1_menu), "clicking away hides menu");
@@ -123,7 +128,7 @@
 							doh.robot.mousePress({left:true}, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isVisible(s1_menu), "drop down menu displayed after mouse down");
-								doh.is(5, dojo.query("tr", s1_menu.domNode).length, "5 options in menu")
+								doh.is(5, dojo.query("tr", s1_menu.domNode).length, "5 options in menu");
 								
 								var selectedOptions = dojo.query(".dijitSelectSelectedOption .dijitMenuItemLabel", s1_menu.domNode);
 								doh.is(1, selectedOptions.length, "one selected option");
@@ -158,7 +163,7 @@
 							}), 1000);
 
 							// mouse up away from node should leave drop down open
-							doh.robot.mouseMove(10, 10, 500)
+							doh.robot.mouseMove(10, 10, 500);
 							doh.robot.mouseRelease({left:true}, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isVisible(s1_menu), "mouse up away from menu leaves menu open");
@@ -191,7 +196,7 @@
 							}), 1000);
 
 							// close drop down
-							doh.robot.mouseMove(10, 10, 500, 1)
+							doh.robot.mouseMove(10, 10, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isHidden(s8a_menu), "clicking on blank screen hides menu");
@@ -253,19 +258,19 @@
 							// tab to s1
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("s1", dojo.global.dijit._curFocus.id)
+								doh.is("s1", dojo.global.dijit.focus.curNode.id)
 							}), 1000);
 
 							// tab to button after s1
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("s1button", dojo.global.dijit._curFocus.id)
+								doh.is("s1button", dojo.global.dijit.focus.curNode.id)
 							}), 1000);
 
 							// tab again should skip disabled s2, and go to s3
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("s3", dojo.global.dijit._curFocus.id)
+								doh.is("s3", dojo.global.dijit.focus.curNode.id)
 							}), 1000);
 
 							return d;
@@ -286,7 +291,7 @@
 							// tab to s1
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("s1", dojo.global.dijit._curFocus.id)
+								doh.is("s1", dojo.global.dijit.focus.curNode.id)
 							}), 1000);
 
 							// down arrow to open drop down and focus first item
@@ -294,7 +299,7 @@
 							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._curFocus, "focused on first menu item")
+								doh.is(Tenessee, dojo.global.dijit.focus.curNode, "focused on first menu item")
 							}), 1000);
 
 							// down arrow to next menu choice
@@ -302,7 +307,7 @@
 							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._curFocus, "focused on second menu item")
+								doh.is(Virginia, dojo.global.dijit.focus.curNode, "focused on second menu item")
 							}), 1000);
 
 							// ENTER to select option
@@ -330,7 +335,7 @@
 							// tab to s1
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("s1", dojo.global.dijit._curFocus.id)
+								doh.is("s1", dojo.global.dijit.focus.curNode.id)
 							}), 1000);
 
 							// down arrow to open drop down and focus first item
@@ -338,7 +343,7 @@
 							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._curFocus, "focused on first menu item")
+								doh.is(Tenessee, dojo.global.dijit.focus.curNode, "focused on first menu item")
 							}), 1000);
 
 							// ESC to close menu
@@ -498,6 +503,88 @@
 					}
 				]);
 
+				doh.register("form submit", [
+					{
+						name: "first validate",
+						timeout: 5000,
+						runTest: function(){
+							// First validate() should focus s13 and display a tooltip.
+							// (s13 is also required, but has a value from previous tests)
+							var d = new doh.Deferred();
+
+							 var handle = dijit.focus.watch("curNode", d.getTestErrback(function(name, oval, nval){
+								if(!nval){ return; }	// ignore spurious event on IE
+								console.log("focused on", nval && (nval.id || nval.innerHTML));
+								doh.is("s13", nval.id, "focused on first required select");
+								handle.unwatch();
+								setTimeout(d.getTestCallback(function(){
+									// Tooltip should appear with error message
+									masterTT = dojo.global.dijit._masterTT;
+									doh.t(masterTT && isVisible(masterTT.domNode), "visible");
+									doh.is("s13", masterTT.aroundNode.id, "tooltip for s13");
+									doh.is("This value is required.", dojo.trim(innerText(masterTT.domNode)));
+								}), 750);
+							}));
+
+							// Validate the form programatically
+							dijit.byId("form").validate();
+
+							return d;
+						}
+					},
+					{
+						name: "select non-blank option for s13",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Open drop down menu
+							doh.robot.mouseMoveAt(s13.domNode, 0, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							// Select 4th option
+							doh.robot.mouseMoveAt(function(){
+								return dojo.query("tr", s13_menu.domNode)[4];
+							}, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isHidden(s13_menu), "drop down menu closes after selection");
+								doh.is("AZ", s13.get('value'), "Arizona");
+								doh.t(s13.isValid(), "should be valid");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "revalidate",
+						timeout: 5000,
+						runTest: function(){
+							// Second validate() should focus s14 and display a tooltip
+							var d = new doh.Deferred();
+
+							var handle = dijit.focus.watch("curNode", d.getTestErrback(function(name, oval, nval){
+								if(!nval){ return; }	// ignore spurious event on IE
+								if(nval.id == "submit"){ return; }	// ignore focus onto submit button
+								doh.is("s14", nval.id, "focused on second required select");
+								handle.unwatch();
+								setTimeout(d.getTestCallback(function(){
+									// Tooltip should appear with error message
+									masterTT = dojo.global.dijit._masterTT;
+									doh.t(masterTT && isVisible(masterTT.domNode), "visible");
+									doh.is("s14", masterTT.aroundNode.id, "tooltip for s14");
+									doh.is("This value is required.", dojo.trim(innerText(masterTT.domNode)));
+								}), 750);
+							}));
+
+							// Press button to submit the form
+							doh.robot.mouseMoveAt("submit", 0, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							return d;
+						}
+					}
+				]);
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/form/robot/SimpleTextarea.html b/dijit/tests/form/robot/SimpleTextarea.html
index 9874104..157f2d6 100644
--- a/dijit/tests/form/robot/SimpleTextarea.html
+++ b/dijit/tests/form/robot/SimpleTextarea.html
@@ -9,15 +9,14 @@
 		</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"></script>
 
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_SimpleTextarea.html');
 
 				doh.register("dijit.form.SimpleTextarea", [
diff --git a/dijit/tests/form/robot/Slider_a11y.html b/dijit/tests/form/robot/Slider_a11y.html
index 5b447d9..49a4de3 100644
--- a/dijit/tests/form/robot/Slider_a11y.html
+++ b/dijit/tests/form/robot/Slider_a11y.html
@@ -9,25 +9,18 @@
 	</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"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.robotx");
 
-		// These are the sliders with arrow buttons
-		// (not sure why that's important for an a11y test???)
-		var arrowSliders = ['slider1','slider2','programaticSlider'];
-		var arrowSliderInit_min = [0.2,10,1200];		// One value above the minimum value
-		var arrowSliderInit_max = [99.8,90,2800];		// One value below the maximum value
-
 		// These are all the sliders
 		var accessibleSliders = ['slider1','slider2','slider3','programaticSlider'];
 		var accessibleSliderInit_min = [0.2,10,2,1200];
 		var accessibleSliderInit_max = [99.8,90,2,2800];
 		var sliderIds = ["slider1", "slider2", "slider3", "sliderH2", "programaticSlider"];
 		var sliderNames = ["horizontal1","vertical1","horizontal2","horizontalH2","programaticSlider"];
-		onChange = {slider1: 'slider1input', slider2: 'slider2input', programaticSlider: 'sliderProgInput'};
+		var onChange = {slider1: 'slider1input', slider2: 'slider2input', programaticSlider: 'sliderProgInput'};
 
 		var a11yBoundaryTest = function(slider, initValue, finalValue){
 			// summary:
@@ -49,20 +42,20 @@
 			// First key press moves to either min or max
 			doh.robot.keyPress(key, 500);
 			doh.robot.sequence(d.getTestErrback(function(){
-				doh.is(finalValue, new Number(slider.get('value')).toFixed(1),
+				doh.is(Number(finalValue).toFixed(1), Number(slider.get('value')).toFixed(1),
 						"value after first " + (key == dojo.keys.RIGHT_ARROW ? "right arrow" : "left arrow"));
 				if(onChange[slider.id]){
-					doh.is(finalValue,parseFloat(dojo.byId(onChange[slider.id]).value),
+					doh.is(Number(finalValue).toFixed(1), Number(parseFloat(dojo.byId(onChange[slider.id]).value)).toFixed(1),
 						"onchange after first " + (key == dojo.keys.RIGHT_ARROW ? "right arrow" : "left arrow"));
 				}
 
 				// Second key press should have no effect, but confirm it
 				doh.robot.keyPress(key, 500);
 				doh.robot.sequence(d.getTestCallback(function(){
-					doh.is(finalValue, new Number(slider.get('value')).toFixed(1),
+					doh.is(Number(finalValue).toFixed(1), Number(slider.get('value')).toFixed(1),
 						"value after second " + (key == dojo.keys.RIGHT_ARROW ? "right arrow" : "left arrow"));
 					if(onChange[slider.id]){
-						doh.is(finalValue, parseFloat(dojo.byId(onChange[slider.id]).value),
+						doh.is(Number(finalValue).toFixed(1), Number(parseFloat(dojo.byId(onChange[slider.id]).value)).toFixed(1),
 						"onchange after second " + (key == dojo.keys.RIGHT_ARROW ? "right arrow" : "left arrow"));
 					}
 				}), 500);
@@ -86,7 +79,7 @@
 			noteChanges = dojo.global.dojo.connect(slider, "onChange", function(){
 				eaVals[strokeIndex++].actual = slider.get('value');
 			});
-		}
+		};
 
 		var populateExpected = function(/*Slider Widget*/inSlider){
 			// summary:
@@ -118,13 +111,13 @@
 			eVals.push({stroke: "DOWN", expected: inSlider.get('value')});
 			inSlider._bumpValue(-1, false);
 			eVals.push({stroke: "LEFT", expected: inSlider.get('value')});
-			inSlider.set('value', inSlider.maximum, false)
+			inSlider.set('value', inSlider.maximum, false);
 			eVals.push({stroke: "END", expected: inSlider.get('value')});
 
 			// reset <inSlider> back to its initial value, and return
 			inSlider.set('value', initVal, false);
 			return eVals;
-		}
+		};
 
 		var a11yTabFocusTest = function(inSliderId){
 			var d = new doh.Deferred();
@@ -133,10 +126,10 @@
 			var blurCount = 0;
 			var gotFocus = function(){
 				focusCount++;
-			}
+			};
 			var lostFocus = function(){
 				blurCount++;
-			}
+			};
 			var focusFunc = dojo.global.dojo.connect(slider.focusNode, "onfocus", gotFocus);
 			var blurFunc = dojo.global.dojo.connect(slider.focusNode, "onblur", lostFocus);
 
@@ -160,7 +153,7 @@
 			};
 			doh.robot.sequence(d.getTestCallback(checkGotFocus), 1000, 500);
 			return d;
-		}
+		};
 
 		var a11yKeystrokeTest = function(inSliderId){
 			var d = new doh.Deferred();
@@ -168,7 +161,9 @@
 			var initVal = slider.get('value');
 			// get focus on slider thumb before pressing keys.
 			slider.focus();
-			doh.robot.sequence(function(){ strokeIndex = 0; }, 1000); // insure onChange events have stopped
+			doh.robot.sequence(function(){
+				strokeIndex = 0;
+			}, 1000); // insure onChange events have stopped
 			doh.robot.keyPress(dojo.keys.HOME, 200);
 			doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000);
 			doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 200);
@@ -192,16 +187,20 @@
 			};
 			doh.robot.sequence(d.getTestCallback(testPresses), 1000, 500);
 			return d;
-		}
+		};
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			doh.robot.initRobot('../test_Slider.html');
 
 			// This tests that Slider is structured so that dojo.query can find the hidden input.
 			doh.register("dojo.query() by name",
 				function slider1(){
 					var slider = dijit.byId("slider1"),
-						queried = dojo.query("input[name=horizontal1]");
+						queried = dojo.query("input[name=horizontal1]"),
+						bar = slider.valueNode.parentNode,
+						barWidth = bar.offsetWidth;
+					accessibleSliderInit_min[0] = 100 / (barWidth-1); // discover slider smallest non min value
+					accessibleSliderInit_max[0] = 100 - accessibleSliderInit_min[0]; // discover slider largest non max value
 					doh.is(1, queried.length, "Expected 1 slider with name horizontal1");
 					doh.is(slider.valueNode, queried[0], "Slider's valueNode did not match the one found by dojo.query.");
 				}
@@ -211,14 +210,14 @@
 			// TODO: this doesn't make sense, should just be testing that slider can't get
 			// focus.  (And if it doesn't have focus then testing keystrokes is meaningless)
 			doh.register("disabledTest",{
-				name: arrowSliders[0]+'_a11y_min',
-				slider: arrowSliders[0],
-				value: arrowSliderInit_min[0],
+				name: accessibleSliders[0]+'_a11y_min',
+				slider: accessibleSliders[0],
 				timeout: 30000,
 				runTest: function(){
 					this.slider = dijit.byId(this.slider);
 					this.slider.set('disabled', true);
-					return a11yBoundaryTest(this.slider, this.value, this.value);
+					var value = accessibleSliderInit_min[0];
+					return a11yBoundaryTest(this.slider, value, value);
 				}
 			});
 
@@ -226,22 +225,20 @@
 			doh.register("a11yBoundaryTest - min", {
 				name: accessibleSliders[0]+'_a11y_min',
 				slider: accessibleSliders[0],
-				value: accessibleSliderInit_min[0],
 				timeout: 30000,
 				runTest: function(){
 					this.slider = dijit.byId(this.slider);
 					this.slider.set('disabled', false);
-					return a11yBoundaryTest(this.slider, this.value, this.slider.minimum);
+					return a11yBoundaryTest(this.slider, accessibleSliderInit_min[0], this.slider.minimum);
 				}
 			});
 			doh.register("a11yBoundaryTest",{
 				name: accessibleSliders[0]+'_a11y_max',
 				slider: accessibleSliders[0],
-				value: accessibleSliderInit_max[0],
 				timeout: 30000,
 				runTest: function(){
 					this.slider = dijit.byId(this.slider);
-					return a11yBoundaryTest(this.slider, this.value, this.slider.maximum);
+					return a11yBoundaryTest(this.slider, accessibleSliderInit_max[0], this.slider.maximum);
 				}
 			});
 
@@ -250,15 +247,15 @@
 			[
 				function ariaRole(){
 					var slider = dijit.byId(sliderIds[0]);
-					doh.is(dijit.getWaiRole(slider.focusNode), "slider", "aria role (slider)");
+					doh.is(slider.focusNode.getAttribute("role"), "slider", "aria role (slider)");
 				},
 
 				// test aria valuemin, valuemax, valuenow.
 				function ariaValue(){
 					var slider = dijit.byId(sliderIds[0]);
-					doh.is(dijit.getWaiState(slider.focusNode, "valuemin"), slider.minimum, "aria-valuemin");
-					doh.is(dijit.getWaiState(slider.focusNode, "valuemax"), slider.maximum, "aria-valuemax");
-					doh.is(dijit.getWaiState(slider.focusNode, "valuenow"), slider.get('value'), "aria-valuenow");
+					doh.is(slider.focusNode.getAttribute("aria-valuemin"), slider.minimum, "aria-valuemin");
+					doh.is(slider.focusNode.getAttribute("aria-valuemax"), slider.maximum, "aria-valuemax");
+					doh.is(slider.focusNode.getAttribute("aria-valuenow"), slider.get('value'), "aria-valuenow");
 				}
 			]);
 
diff --git a/dijit/tests/form/robot/Slider_mouse.html b/dijit/tests/form/robot/Slider_mouse.html
index d7bec43..09764f6 100644
--- a/dijit/tests/form/robot/Slider_mouse.html
+++ b/dijit/tests/form/robot/Slider_mouse.html
@@ -9,8 +9,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"></script>
 
 	<script type="text/javascript">
 		dojo.require("dojo.window");
@@ -19,12 +18,9 @@
 		var arrowSliders = ['slider1','slider2','programaticSlider'];
 		var arrowSliderInit_min = [0.2,10,1200];
 		var arrowSliderInit_max = [99.8,90,2800];
-		var accessibleSliders = ['slider1','slider2','slider3','programaticSlider']
-		var accessibleSliderInit_min = [0.2,10,2,1200];
-		var accessibleSliderInit_max = [99.8,90,2,2800];
 		var sliderIds = ["slider1", "slider2", "slider3", "sliderH2", "programaticSlider"];
 
-		onChange = {slider1: 'slider1input', slider2: 'slider2input', programaticSlider: 'sliderProgInput'};
+		var onChange = {slider1: 'slider1input', slider2: 'slider2input', programaticSlider: 'sliderProgInput'};
 
 		var boundaryTest = function(slider, initValue, finalValue){
 			// summary:
@@ -44,16 +40,16 @@
 			doh.robot.mouseMoveAt(button, 500);
 			doh.robot.mouseClick({left: true}, 500);
 			doh.robot.sequence(d.getTestErrback(function(){
-				doh.is(finalValue, new Number(slider.get('value')).toFixed(1));
+				doh.is(Number(finalValue).toFixed(2), Number(slider.get('value')).toFixed(2));
 				if(onChange[slider.id]){
-					doh.is(finalValue, parseFloat(dojo.byId(onChange[slider.id]).value));
+					doh.is(Number(finalValue).toFixed(1), Number(parseFloat(dojo.byId(onChange[slider.id]).value)).toFixed(1));
 				}
 				doh.robot.mouseMoveAt(button, 500);
 				doh.robot.mouseClick({left: true}, 500);
 				doh.robot.sequence(d.getTestCallback(function(){
-					doh.is(finalValue, new Number(slider.get('value')).toFixed(1));
+					doh.is(Number(finalValue).toFixed(2), Number(slider.get('value')).toFixed(2));
 					if(onChange[slider.id]){
-						doh.is(finalValue, parseFloat(dojo.byId(onChange[slider.id]).value));
+						doh.is(Number(finalValue).toFixed(1), Number(parseFloat(dojo.byId(onChange[slider.id]).value)).toFixed(1));
 					}
 				}), 500);
 			}), 500);
@@ -101,11 +97,16 @@
 			}
 		};
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			doh.robot.initRobot('../test_Slider.html');
 
 			// Test initial values
 			doh.register("initial values", function initialValues(){
+				var slider = dijit.byId(arrowSliders[0]),
+					bar = slider.valueNode.parentNode,
+					barWidth = bar.offsetWidth;
+				arrowSliderInit_min[0] = 100 / (barWidth-1); // discover slider smallest non min value
+				arrowSliderInit_max[0] = 100 - arrowSliderInit_min[0]; // discover slider largest non max value
 				doh.is(10, dijit.byId("slider1").get("value"), "horizontal1");
 				doh.is(10, dijit.byId("slider2").get("value"), "vertical1");
 				doh.is(2, dijit.byId("slider3").get("value"), "horizontal2");
@@ -159,11 +160,11 @@
 				{
 					name: arrowSliders[0]+'_min',
 					slider: arrowSliders[0],
-					value: arrowSliderInit_min[0],
 					timeout: 30000,
 					runTest: function(){
 						this.slider = dijit.byId(this.slider);
-						return boundaryTest(this.slider, this.value, this.value);
+						var value = arrowSliderInit_min[0];
+						return boundaryTest(this.slider, value, value);
 					}
 				},
 				{
@@ -184,21 +185,19 @@
 				{
 					name: arrowSliders[0]+'_min',
 					slider: arrowSliders[0],
-					value: arrowSliderInit_min[0],
 					timeout: 30000,
 					runTest: function(){
 						this.slider = dijit.byId(this.slider);
-						return boundaryTest(this.slider, this.value, this.slider.minimum);
+						return boundaryTest(this.slider, arrowSliderInit_min[0], this.slider.minimum);
 					}
 				},
 				{
 					name: arrowSliders[0]+'_max',
 					slider: arrowSliders[0],
-					value: arrowSliderInit_max[0],
 					timeout: 30000,
 					runTest: function(){
 						this.slider = dijit.byId(this.slider);
-						return boundaryTest(this.slider, this.value, this.slider.maximum);
+						return boundaryTest(this.slider, arrowSliderInit_max[0], this.slider.maximum);
 					}
 				}
 			]);
@@ -226,8 +225,8 @@
 
 			doh.register("mouseWheelTest", [
 				{
-					name: accessibleSliders[1]+'_minToMax',
-					slider: accessibleSliders[1],
+					name: arrowSliders[1]+'_minToMax',
+					slider: arrowSliders[1],
 					timeout: 30000,
 					runTest: function(){
 						this.slider = dijit.byId(this.slider);
@@ -235,8 +234,8 @@
 					}
 				},
 				{
-					name: accessibleSliders[1]+'_maxToMin',
-					slider: accessibleSliders[1],
+					name: arrowSliders[1]+'_maxToMin',
+					slider: arrowSliders[1],
 					timeout: 30000,
 					runTest: function(){
 						this.slider = dijit.byId(this.slider);
@@ -313,6 +312,29 @@
 				}
 			]);
 
+			doh.register("drag tests", [
+				{
+					name: "horizontal",
+					timeout: 5000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						var slider = dijit.byId("slider1");
+						slider.set('value', 50);
+						dojo.window.scrollIntoView(slider.domNode);
+						doh.robot.mouseMoveAt(slider.focusNode, 1, 0);
+						doh.robot.mousePress({left: true}, 500);
+						doh.robot.mouseMoveAt(slider.incrementButton, 1000, 0);
+						doh.robot.mouseRelease({left: true}, 500);
+						doh.robot.mouseMoveAt(slider.decrementButton, 1000, 0);
+						doh.robot.sequence(d.getTestCallback(function(){
+							var value = slider.get('value');
+							doh.is(value, 100, "Expected max value of 100, got "+value);
+						}), 1000);
+						return d;
+					}
+				}
+			]);
+
 			doh.run();
 		});
 	</script>
diff --git a/dijit/tests/form/robot/Spinner_a11y.html b/dijit/tests/form/robot/Spinner_a11y.html
index 155a6c7..8957268 100644
--- a/dijit/tests/form/robot/Spinner_a11y.html
+++ b/dijit/tests/form/robot/Spinner_a11y.html
@@ -9,13 +9,12 @@
 		</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"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				var spin1;
 				var spin2;
 				var spin3;
@@ -27,10 +26,10 @@
 				var blurCountZ = 0;
 				var countFocus = function(){
 					focusCountZ++;
-				}
+				};
 				var countBlur = function(){
 					blurCountZ++;
-				}
+				};
 				var focusConnect;
 				var blurConnect;
 				var tabFocusSetup = function(inSpinnerId){
@@ -40,7 +39,7 @@
 					blurCountZ = 0;
 					focusConnect = spinner.connect(spinner.focusNode, "onfocus", countFocus);
 					blurConnect = spinner.connect(spinner.focusNode, "onblur", countBlur);
-				}
+				};
 
 				// Setup to test manipulation of spinner via keystrokes.
 				var results;	// array holding both expected value and actual value after each keypress
@@ -66,6 +65,7 @@
 					var initVal = inSpinner.get('value');
 					var eVals = [];
 					var newVal;
+					var i;
 
 					// The values expected by pressing HOME, right arrow five times,
 					// PgUp twice, PgDn, up arrow twice, down arrow once,
@@ -76,14 +76,14 @@
 					newVal = inSpinner.get('value');
 					eVals.push({stroke: "HOME", expected: newVal});
 					// UP 5 times
-					for(var i = 0; i < 5; i++){
+					for(i = 0; i < 5; i++){
 						newVal = inSpinner.adjust(newVal, inSpinner.smallDelta);
 						inSpinner.set('value', newVal);
 						newVal = inSpinner.get('value');
 						eVals.push({stroke: "UP", expected: newVal});
 					}
 					// PgUp twice
-					for(var i = 0; i < 2; i++){
+					for(i = 0; i < 2; i++){
 						newVal = inSpinner.adjust(newVal, inSpinner.largeDelta);
 						inSpinner.set('value', newVal);
 						newVal = inSpinner.get('value');
@@ -109,11 +109,11 @@
 					// reset <inSpinner> back to its initial value, and return
 					inSpinner.set('value', initVal);
 					return eVals;
-				}
+				};
 
 				// execute some test as soon as the widget gets focus
 				var focusThenRun = function(widget, fcn){
-					if(!widget._focused){
+					if(!widget.focused){
 						var handler = widget.connect(widget, '_onFocus', function(){
 							widget.disconnect(handler);
 							setTimeout(fcn, 1);
@@ -159,7 +159,7 @@
 						doh.robot.keyPress(dojo.keys.TAB, 1, {shift:true}); // blur
 					});
 					return d;
-				}
+				};
 
 				// common robot keystroke test function.
 				var a11yKeystrokeTest = function(inSpinnerId){
@@ -184,7 +184,7 @@
 							spinner.set('value', initVal);
 							for(var i = 0; i < results.length; i++){
 								var aResult = results[i];
-								if(!(isNaN(aResult.expected) && isNaN(aResult.actual))) {
+								if(!(isNaN(aResult.expected) && isNaN(aResult.actual))){
 									doh.is(aResult.expected, aResult.actual, aResult.stroke);
 								}
 							}
@@ -192,7 +192,7 @@
 						doh.robot.sequence(d.getTestCallback(testPresses), 1000, 1000);
 					});
 					return d;
-				}
+				};
 
 				doh.register("setUp",{
 					name: "setUp",
@@ -331,7 +331,7 @@
 					function spinnerRole(){
 						var spinner = dijit.byId("integerspinner1");
 						doh.isNot(spinner, null, "can't find 'integerspinner1'");
-						doh.is(dijit.getWaiRole(spinner.focusNode), "spinbutton", spinner.id + ": aria role (spinbutton)");
+						doh.is(dojo.attr(spinner.focusNode, "role"), "spinbutton", spinner.id + ": aria role (spinbutton)");
 					}
 				);
 
@@ -345,41 +345,41 @@
 						function minAndMax(){
 							var spinner = dijit.byId("integerspinner2");
 							doh.isNot(spinner, null, "can't find 'integerspinner2'");
-							doh.is(dijit.getWaiState(spinner.focusNode, "valuemin"), spinner.constraints.min, spinner.id + ": aria-valuemin");
-							doh.is(dijit.getWaiState(spinner.focusNode, "valuemax"), spinner.constraints.max, spinner.id + ": aria-valuemax");
+							doh.is(spinner.focusNode.getAttribute("aria-valuemin"), spinner.constraints.min, spinner.id + ": aria-valuemin");
+							doh.is(spinner.focusNode.getAttribute("aria-valuemax"), spinner.constraints.max, spinner.id + ": aria-valuemax");
 						},
 						function minOnly(){
 							var spinner = dijit.byId("spinnerMinOnly");
 							doh.isNot(spinner, null, "can't find 'spinnerMinOnly'");
-							doh.is(dijit.getWaiState(spinner.focusNode, "valuemin"), spinner.constraints.min, spinner.id + ": aria-valuemin");
+							doh.is(spinner.focusNode.getAttribute("aria-valuemin"), spinner.constraints.min, spinner.id + ": aria-valuemin");
 							if(spinner.constraints.max){
-								doh.is(dijit.getWaiState(spinner.focusNode, "valuemax"), spinner.constraints.max, spinner.id + ": aria-valuemax");
-							} else {
-								doh.f(dijit.hasWaiState(spinner.focusNode, "valuemax"), spinner.id + ": aria-valuemax");
+								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");
 							}
 						},
 						function maxOnly(){
 							var spinner = dijit.byId("integertextbox3");
 							doh.isNot(spinner, null, "can't find 'integertextbox3'");
-							doh.is(dijit.getWaiState(spinner.focusNode, "valuemax"), spinner.constraints.max, spinner.id + ": aria-valuemax");
+							doh.is(spinner.focusNode.getAttribute("aria-valuemax"), spinner.constraints.max, spinner.id + ": aria-valuemax");
 							if(spinner.constraints.min){
-								doh.is(dijit.getWaiState(spinner.focusNode, "valuemin"), spinner.constraints.min, spinner.id + ": aria-valuemin");
-							} else {
-								doh.f(dijit.hasWaiState(spinner.focusNode, "valuemin"), spinner.id + ": aria-valuemin");
+								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");
 							}
 						},
 						function neitherMinNorMax(){
 							var spinner = dijit.byId("integertextbox3");
 							doh.isNot(spinner, null, "can't find 'integertextbox3'");
 							if(spinner.constraints.min){
-								doh.is(dijit.getWaiState(spinner.focusNode, "valuemin"), spinner.constraints.min, spinner.id + ": aria-valuemin");
-							} else {
-								doh.f(dijit.hasWaiState(spinner.focusNode, "valuemin"), spinner.id + ": aria-valuemin");
+								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.constraints.max){
-								doh.is(dijit.getWaiState(spinner.focusNode, "valuemax"), spinner.constraints.max, spinner.id + ": aria-valuemax");
-							} else {
-								doh.f(dijit.hasWaiState(spinner.focusNode, "valuemax"), spinner.id + ": aria-valuemax");
+								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");
 							}
 						}
 					]
@@ -398,7 +398,7 @@
 							runTest:function(){
 								var spinner = dijit.byId(this.spinnerId);
 								spinner.set('value', 100);
-								var ariaVal = dijit.getWaiState(spinner.focusNode, "valuenow");
+								var ariaVal = spinner.focusNode.getAttribute("aria-valuenow");
 								doh.is(100, ariaVal, spinner.id + ": aria-valuenow");
 							}
 						};
@@ -416,8 +416,8 @@
 							var initVal = spinner.get('value');
 							spinner.set('value', null);
 							var spinnerVal = spinner.get('value');
-							var nowVal = dijit.getWaiState(spinner.focusNode, "valuenow");
-							var invalid = dijit.getWaiState(spinner.focusNode, "invalid");
+							var nowVal = spinner.focusNode.getAttribute("aria-valuenow");
+							var invalid = spinner.focusNode.getAttribute("aria-invalid");
 							spinner.set('value', initVal);
 							doh.t(invalid, spinner.id + ": aria-invalid");
 							if(!(isNaN(spinnerVal) && isNaN(nowVal))){
diff --git a/dijit/tests/form/robot/Spinner_mouse.html b/dijit/tests/form/robot/Spinner_mouse.html
index 0547f3c..efbee57 100644
--- a/dijit/tests/form/robot/Spinner_mouse.html
+++ b/dijit/tests/form/robot/Spinner_mouse.html
@@ -9,13 +9,12 @@
 		</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"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				var spin1;
 				var spin2;
 				var spin3;
@@ -307,7 +306,7 @@
 							doh.robot.mouseWheel(-10, 1000, 1000);
 							doh.robot.sequence(d.getTestCallback(function(){
 								var v = spin3.get('value');
-								doh.is(v, (1.0+1.0*delta), "spinner 3: wrong value, expected "+(1.0+1.0*delta)+", got "+v);
+								doh.is(v, (1.0+delta), "spinner 3: wrong value, expected "+(1.0+delta)+", got "+v);
 							}), 1000);
 							return d;
 						}
diff --git a/dijit/tests/form/robot/Textarea.html b/dijit/tests/form/robot/Textarea.html
index c161edf..cb22dda 100644
--- a/dijit/tests/form/robot/Textarea.html
+++ b/dijit/tests/form/robot/Textarea.html
@@ -10,18 +10,17 @@
 		</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"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Textarea.html');
 
 				// execute some test as soon as the widget gets focus
 				var focusThenRun = function(widget, fcn){
-					if(!widget._focused){
+					if(!widget.focused){
 						var handler = widget.connect(widget, '_onFocus', function(){
 							widget.disconnect(handler);
 							setTimeout(fcn, 1);
@@ -144,17 +143,19 @@
 								d = new doh.Deferred(),
 								modifier = dojo.isMac ? {meta: true} : {ctrl: true},
 								w = dijit.byId("blank"),
-								height1 = dojo.marginBox(w.domNode).h,
-								height2,
-								height3;
+								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;
-								}, 1000);
+								}, 500);
 
 								// Paste text, height should increase
 								doh.robot.keyPress("v", 500, modifier);
@@ -163,7 +164,7 @@
 									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);
-								}), 1000);
+								}), 500);
 							});
 
 							return d;
@@ -210,6 +211,25 @@
 
 							return d;
 						}
+					},
+					{
+						name: "#13166",
+						timeout: 5000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								w = dijit.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");
+								}), 500);
+							});
+
+							return d;
+						}
 					}
 
 				]);
diff --git a/dijit/tests/form/robot/TimeTextBox.html b/dijit/tests/form/robot/TimeTextBox.html
index f46ef96..7454c19 100644
--- a/dijit/tests/form/robot/TimeTextBox.html
+++ b/dijit/tests/form/robot/TimeTextBox.html
@@ -10,15 +10,15 @@
 		</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"></script>
+
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 			dojo.require("dojo.date.stamp");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_TimeTextBox.html');
 
 				doh.register("keyboard", [
@@ -182,8 +182,7 @@
 
 								// drop down list should be filtered to times starting with 12:,
 								// and they should appear in chronological order
-								var popup = dijit.byId("q2_popup"),
-									children = dojo.query(".dijitTimePickerItem", popup.domNode);
+								var children = dojo.query(".dijitTimePickerItem", popup.domNode);
 								doh.is(8, children.length, "# of items in drop down");
 								doh.is("12:00 AM", innerText(children[0]));
 								doh.is("12:15 AM", innerText(children[1]));
@@ -201,7 +200,7 @@
 								var popup = dijit.byId('q2_popup');
 								doh.t(!popup || isHidden(popup), "popup hidden");
 								
-								doh.is("q3", dojo.global.dijit._curFocus.id, "tab moved to next input widget");
+								doh.is("q3", dojo.global.dijit.focus.curNode.id, "tab moved to next input widget");
 							}), 1000);
 
 							return d;
@@ -267,6 +266,62 @@
 					}
 				]);
 
+				var q20;
+				doh.register("disabled", [
+					{
+						name: "disable",
+						timeout: 6000,
+						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);
+							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");
+							}), 1000);
+							return d;
+						},
+						tearDown: function(){
+							q20.set('disabled',false);
+							q20.closeDropDown();
+						}
+					},
+					{
+						name: "readOnly",
+						timeout: 6000,
+						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);
+							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");
+							}), 1000);
+							return d;
+						},
+						tearDown: function(){
+							q20.set('readOnly',false);
+							q20.closeDropDown();
+						}
+					}
+				]);
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/form/robot/ValidationTextBox.html b/dijit/tests/form/robot/ValidationTextBox.html
index 07c5e24..c0cd782 100644
--- a/dijit/tests/form/robot/ValidationTextBox.html
+++ b/dijit/tests/form/robot/ValidationTextBox.html
@@ -11,7 +11,9 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
+			djConfig="isDebug: true"></script>
+
+		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
@@ -20,7 +22,7 @@
 				return typeof val == "string" ? val.replace(/\xA0/g, " ") : val;
 			}
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_validate.html');
 
 				// Test initial conditions
@@ -127,14 +129,14 @@
 								// 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(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(expectedState[attr], fixNbsp(textbox.get(attr)), "get(" + attr + ")");
 									doh.is(typeof expectedState[attr], typeof textbox.get(attr), "typeof get(" + attr + ")")
 								}
 
@@ -615,7 +617,7 @@
 								doh.is('123.000', this.textbox.focusNode.value, "focusNode.value");
 								doh.is(undefined, this.textbox.get('value'), "get('value')");
 								doh.f(this.textbox.isValid(), "!isValid()");
-							})), 1000);
+							})), 1500);
 							return d;
 						}
 					},
@@ -636,7 +638,7 @@
 								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()");
-							})), 1000);
+							})), 1500);
 							return d;
 						}
 					},
@@ -657,7 +659,7 @@
 								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()");
-							})), 1000);
+							})), 1500);
 							return d;
 						}
 					},
@@ -845,7 +847,7 @@
 							doh.robot.typeKeys('abc', 1000, 600);
 
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is("q24", (dojo.global.dijit._curFocus||{}).id, "did focus");
+								doh.is("q24", (dojo.global.dijit.focus.curNode||{}).id, "did focus");
 								doh.is('cannot type here', this.textbox.focusNode.value, "focusNode.value");
 								doh.is('cannot type here', this.textbox.get('value'), "get('value')");
 							})), 1000);
@@ -897,7 +899,7 @@
 							doh.robot.mouseClick({left: true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.isNot("q24", (dojo.global.dijit._curFocus||{}).id, "didn't focus");
+								doh.isNot("q24", (dojo.global.dijit.focus.curNode||{}).id, "didn't focus");
 							})), 500);
 							return d;
 						}
@@ -918,7 +920,7 @@
 							doh.robot.keyPress(dojo.keys.TAB, 500);
 
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is("q26", dojo.global.dijit._curFocus.id,
+								doh.is("q26", dojo.global.dijit.focus.curNode.id,
 										"tabbed past input, to the button after it");
 							})), 500);
 							return d;
@@ -1234,6 +1236,126 @@
 					}
 				]);
 
+				function testOn(evt, widget, deferred, callback, delay){
+					var handler = widget.connect(widget.focusNode, "on"+evt,
+						function(){
+							widget.disconnect(handler);
+							setTimeout(deferred.getTestCallback(callback), delay||250);
+						});
+				}
+
+				// Supplementary test from validationMessages.html, to make sure tooltip doesn't flash
+				// on typing multiple invalid characters
+				doh.register("validation", [
+					{
+						name: "first focus, empty value",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							textbox = dijit.byId("q03");
+							textbox.focusNode.scrollIntoView();
+							textbox.set("value", "");
+							textbox.focus();
+							setTimeout(d.getTestCallback(function(){
+								// Tooltip should appear with information message
+								masterTT = dojo.global.dijit._masterTT;
+								doh.t(masterTT && isVisible(masterTT.domNode), "visible");
+								doh.is("(optional) Enter an age between 0 and 120", dojo.trim(innerText(masterTT.domNode)));
+							}), 750);
+						}
+					},
+					{
+						name: "first invalid character",
+						timeout: 2000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							testOn('keyup', textbox, d, function(){
+								masterTT = dojo.global.dijit._masterTT;
+								doh.t(masterTT && isVisible(masterTT.domNode), "visible");
+								doh.is("The value entered is not valid.", dojo.trim(innerText(masterTT.domNode)),
+									"message changed from info message to error message");
+							});
+							doh.robot.typeKeys("a", 0, 0);
+							return d;
+						}
+					},
+					{
+						name: "second invalid character",
+						timeout: 2000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var tooltipHidden = false;
+							testOn('keyup', textbox, d, function(){
+								masterTT = dojo.global.dijit._masterTT;
+								doh.f(tooltipHidden, "tooltip didn't blink or disappear");
+								doh.is("The value entered is not valid.", dojo.trim(innerText(masterTT.domNode)),
+									"same message");
+							});
+							dojo.connect(dijit, "hideTooltip", function(){ tooltipHidden = true; });
+							doh.robot.typeKeys("a", 0, 0);
+							return d;
+						}
+					},
+					{
+						name: "tab away",
+						timeout: 2000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							testOn('blur', textbox, d, function(){
+								masterTT = dojo.global.dijit._masterTT;
+								doh.t(masterTT && isHidden(masterTT.domNode), "hidden");
+							});
+							doh.robot.keyPress(dojo.keys.TAB, 0);
+							return d;
+						}
+					},
+					{
+						name: "tab back",
+						timeout: 2000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							testOn('focus', textbox, d, function(){
+								masterTT = dojo.global.dijit._masterTT;
+								doh.t(masterTT && isVisible(masterTT.domNode), "visible again");
+								doh.is("The value entered is not valid.", dojo.trim(innerText(masterTT.domNode)),
+									"same message");
+							});
+							doh.robot.keyPress(dojo.keys.TAB, 0, { shift:true });
+							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.
+						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 8a438df..5ae5f58 100644
--- a/dijit/tests/form/robot/_autoComplete_a11y.html
+++ b/dijit/tests/form/robot/_autoComplete_a11y.html
@@ -9,12 +9,13 @@
 	</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"></script>
+
 	<script type="text/javascript" src="../../helpers.js"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.robotx");
+		dojo.require("dojo.aspect");
 
 		// TODO: provide URL toggle for FilteringSelect
 		var testWidget = "dijit.form.ComboBox";
@@ -29,7 +30,7 @@
 		        }
 		}
 		isComboBox = testWidget=="dijit.form.ComboBox";
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 
 			doh.robot.initRobot('../_autoComplete.html?testWidget='+testWidget);
 
@@ -74,7 +75,7 @@
 					node = node.nextSibling;
 				}
 				return node;
-			}
+			};
 
 			// Select a value from the drop down using the keyboard, using "more choices" button to page as necessary
 			var robot_a11ySelectValue = function(combo, text, value, expectedText){
@@ -116,7 +117,7 @@
 							// watch() tests
 							doh.is(expectedText, dv, "watch of displayedValue");
 							doh.is(value, v, "watch of value");
-							doh.is(value, isComboBox ? combo.store.getValue(i, combo.searchAttr) : combo.store.getIdentity(i), "watch of item");
+							doh.is(value, isComboBox ? i[combo.searchAttr] : combo.store.getIdentity(i), "watch of item");
 							h1.unwatch();
 							h2.unwatch();
 							h3.unwatch();
@@ -222,7 +223,7 @@
 							if(!isComboBox){
 								doh.t(combo.isValid(), "isValid()");
 							}
-							doh.is(isComboBox ? "Kentucky" : "KY", v, "watch of value")
+							doh.is(isComboBox ? "Kentucky" : "KY", v, "watch of value");
 							doh.is("Kentucky", dv, "watch of displayedValue")
 						}), 900);
 						return d;
@@ -276,6 +277,87 @@
 				// TODO: test some other set("value") calls
 			]);
 
+			doh.register("back compat", [
+				function fetch_optionTags(){
+					// Make sure that myComboBox.store.fetch() still works even though
+					// ComboBox is using the new dojo.store API
+					var d = new doh.Deferred();
+					doh.t(dijit.byId("setvaluetest").store, "store exists");
+					doh.t(dojo.isFunction(dijit.byId("setvaluetest").store.fetch), "fetch exists");
+					dijit.byId("setvaluetest").store.fetch({
+						onBegin: d.getTestCallback(function(total){
+							doh.is(61, total, "# records");
+						})
+					});
+					return d;
+				},
+				function fetch_externalStore(){
+					// Make sure that myComboBox.store.fetch() still works even though
+					// ComboBox is using the new dojo.store API
+					var d = new doh.Deferred();
+					doh.t(dijit.byId("datatest").store, "store exists");
+					doh.t(dojo.isFunction(dijit.byId("datatest").store.fetch), "fetch exists");
+					dijit.byId("datatest").store.fetch({
+						onBegin: d.getTestCallback(function(total){
+							doh.is(61, total, "# records");
+						})
+					});
+					return d;
+				},
+				{
+					timeout:60000,
+					name:"fetch() called with string",
+					runTest:function(){
+						// Make sure typing into a ComboBox connected to an
+						// old dojo.data store calls store.fetch() with a String argument rather than a Regex
+
+						var d = new doh.Deferred();
+						combo = dijit.byId("datatest");
+
+						doh.t("fetch" in combo.store,
+								"combo.store has fetch() method (i.e. it's the old dojo.data API)");
+
+						combo.focusNode.focus();
+						doh.robot.sequence(function(){ combo.set("value", null); }, 500);
+
+						// Keypress (below) will trigger a call to store.fetch, which will then call this code.
+						doh.robot.sequence(function(){
+							var handle = dojo.aspect.after(combo.store, "fetch", d.getTestErrback(function(args){
+								handle.remove();
+								doh.isNot(null, args && args.query && args.query.name,
+										"args.query.name set");
+								doh.is("string", typeof args.query.name, "typeof searchAttr");
+							}), true);
+						}, 500);
+						doh.robot.keyPress("k", 500);
+
+						// Code below merely to let ComboBox finish any pending requests, so "datatest" ComboBox
+						// doesn't grab focus in the middle of with the "direct input" test below.
+						doh.robot.keyPress(dojo.keys.ENTER, 500);
+						doh.robot.sequence(function(){
+							d.callback(true);
+						}, 500);
+
+						return d;
+					}
+				}
+			]);
+
+			!isComboBox && doh.register("FilteringSelect back-compat", [
+				function setDisplayedValue(){
+					// Make sure that set("displayedValue", ...) on a FilteringSelect connected to an
+					// old dojo.data store calls store.fetch() with a String argument rather than a Regex
+					var combo = dijit.byId("datatest");
+					doh.t("fetch" in combo.store, "combo.store has fetch() method (i.e. it's the old dojo.data API)");
+					var handle = dojo.aspect.after(combo.store, "fetch", function(args){
+						handle.remove();
+						doh.isNot(null, args && args.query && args.query.name, "args.query.name set");
+						doh.is("string", typeof args.query.name, "typeof searchAttr");
+					}, true);
+					combo.set("displayedValue", "Kentucky");
+				}
+			]);
+
 			doh.register("direct input", [
 				// Type a valid value and press Enter
 				{
@@ -296,7 +378,7 @@
 						return robot_typeValue((this.combo = dijit.byId(this.combo)), "zxcxarax", isComboBox?"zxcxarax":"");
 					}
 				},
-				
+
 				// Check on the invalid value from the previous test
 				{
 					timeout:60000,
@@ -326,7 +408,7 @@
 				runTest:function(){
 					dojo.global.formSubmitted = false;
 					var d = new doh.Deferred();
-					var combo = dijit.byId("setvaluetest");	
+					var combo = dijit.byId("setvaluetest");
 					combo.focus();
 
 					// Initial conditions:
@@ -397,7 +479,7 @@
 							doh.t(list, "drop down exists");
 							doh.t(isVisible(list), "drop down is visible");
 
-							var entries = dojo.query("li", list).filter(isVisible);
+							var entries = dojo.query(".dijitMenuItem", list).filter(isVisible);
 							doh.is(3, entries.length, "three entries in drop down: " + list.innerHTML);
 							doh.is("California (CA)", innerText(entries[0]), "list #1");
 							doh.is("Colorado (CO)", innerText(entries[1]), "list #2");
@@ -429,7 +511,7 @@
 							doh.t(list, "drop down exists");
 							doh.t(isVisible(list), "drop down is visible");
 
-							var entries = dojo.query("li", list).filter(isVisible);
+							var entries = dojo.query(".dijitMenuItem", list).filter(isVisible);
 							doh.is(2, entries.length, "three entries in drop down: " + list.innerHTML);
 							doh.is("Colorado (CO)", innerText(entries[0]), "list #1");
 							doh.is("Connecticut (CT)", innerText(entries[1]), "list #2");
@@ -455,7 +537,7 @@
 							doh.t(list, "drop down exists");
 							doh.t(isVisible(list), "drop down is visible");
 
-							var entries = dojo.query("li", list).filter(isVisible);
+							var entries = dojo.query(".dijitMenuItem", list).filter(isVisible);
 							doh.is(3, entries.length, "three entries in drop down: " + list.innerHTML);
 							doh.is("California (CA)", innerText(entries[0]), "list #1");
 							doh.is("Colorado (CO)", innerText(entries[1]), "list #2");
@@ -614,7 +696,7 @@
 							doh.t(list, "drop down exists");
 							doh.t(isVisible(list), "drop down is visible");
 
-							var entries = dojo.query("li", list).filter(isVisible);
+							var entries = dojo.query(".dijitMenuItem", list).filter(isVisible);
 							doh.is(2, entries.length, "two entries in drop down: " + list.innerHTML);
 							doh.is("Colorado", innerText(entries[0]), "list #1");
 							doh.is("Connecticut", innerText(entries[1]), "list #2");
@@ -656,7 +738,7 @@
 								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");
@@ -699,13 +781,13 @@
 						var d = new doh.Deferred();
 
 						dojo.byId("datatestDijit").focus();
-						doh.is("datatestDijit", dojo.global.dijit._curFocus.id, "focused on elem before disabled combo");
+						doh.is("datatestDijit", dojo.global.dijit.focus.curNode.id, "focused on elem before disabled combo");
 
 						// Tab over the disabled ComboBox
 						doh.robot.keyPress(dojo.keys.TAB, 1000);
 
 						doh.robot.sequence(d.getTestCallback(function(){
-							doh.is("combobox4", dojo.global.dijit._curFocus.id, "focused on 'enable' button after disabled combo");
+							doh.is("combobox4", dojo.global.dijit.focus.curNode.id, "focused on 'enable' button after disabled combo");
 						}), 1000);
 
 						return d;
@@ -813,8 +895,7 @@
 					name:"labelFunc_type",
 					combo:"labelFunc",
 					runTest:function(){
-						var d = robot_typeValue((this.combo = dijit.byId(this.combo)), "Alabama", isComboBox? "Alabama" : "AL", "Alabama");
-						return d;
+						return robot_typeValue((this.combo = dijit.byId(this.combo)), "Alabama", isComboBox ? "Alabama" : "AL", "Alabama");
 					}
 				},
 
@@ -831,7 +912,7 @@
 						doh.is("h2", w.focusNode.value, "set() focus value");
 
 						w.focus();
-						
+
 						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 100);
 
 						doh.robot.sequence(d.getTestCallback(function(){
@@ -839,7 +920,7 @@
 							doh.t(list, "drop down exists");
 							doh.t(isVisible(list), "drop down is visible");
 
-							var entries = dojo.query("li", list).filter(isVisible);
+							var entries = dojo.query(".dijitMenuItem", list).filter(isVisible);
 							doh.is("<h1>h1</h1>", dojo.trim(entries[0].innerHTML).toLowerCase(), "list #1 is rich text");
 						}), 500);
 
@@ -868,7 +949,7 @@
 							doh.t(list, "drop down exists");
 							doh.t(isVisible(list), "drop down is visible");
 
-							var entries = dojo.query("li", list).filter(isVisible);
+							var entries = dojo.query(".dijitMenuItem", list).filter(isVisible);
 							doh.is("United States of America", innerText(entries[0]), "list #1");
 						}), 900);
 
@@ -892,7 +973,7 @@
 							doh.t(list, "drop down exists");
 							doh.t(isVisible(list), "drop down is visible");
 
-							var entries = dojo.query("li", list).filter(isVisible);
+							var entries = dojo.query(".dijitMenuItem", list).filter(isVisible);
 							doh.is(2, entries.length, "two countries (but no continents) in drop down: " + list.innerHTML);
 							doh.is("Australia", innerText(entries[0]), "list #1");
 							doh.is("Argentina", innerText(entries[1]), "list #2");
@@ -1057,7 +1138,7 @@
 							doh.t(list && isVisible(list), "drop down is visible");
 							doh.is(combo.dropDown.getHighlightedOption(), findMenuItem(combo, "Alaska"), "Alaska is selected");
 
-							doh.t(combo._focused, "widget is focused");
+							doh.t(combo.focused, "widget is focused");
 
 							// Since the user down arrowed thru the choices, the value should be the current selection
 							doh.is('Alaska', combo.focusNode.value);
@@ -1098,7 +1179,7 @@
 							doh.t(list && isVisible(list), "drop down is visible");
 							doh.is(combo.dropDown.getHighlightedOption(), findMenuItem(combo, "Alaska"), "Alaska is selected");
 
-							doh.t(combo._focused, "widget is focused");
+							doh.t(combo.focused, "widget is focused");
 
 							// Since the user down arrowed thru the choices, the value should be the current selection
 							doh.is('Alaska', combo.focusNode.value);
@@ -1366,7 +1447,7 @@
 										var item = findMenuItem(combo, idx);
 										if(idx in test.results){
 											var expected = test.results[idx];
-											var actual = item.innerHTML.replace(/\/?span\s*[^>]*/ig, "");
+											var actual = item.innerHTML.replace(/\/?span\s*[^>]*@?/ig, "");
 											doh.is(expected, actual, idx);
 										}else{
 											doh.t(item == combo.dropDown.nextButton, "too many menu items: " + idx);
diff --git a/dijit/tests/form/robot/_autoComplete_mouse.html b/dijit/tests/form/robot/_autoComplete_mouse.html
index b5c0e32..f766c48 100644
--- a/dijit/tests/form/robot/_autoComplete_mouse.html
+++ b/dijit/tests/form/robot/_autoComplete_mouse.html
@@ -9,12 +9,13 @@
 	</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"></script>
+
 	<script type="text/javascript" src="../../helpers.js"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.robotx");
+		dojo.require("dojo.window");
 
 		// TODO: provide URL toggle for FilteringSelect
 		var testWidget = "dijit.form.ComboBox";
@@ -29,16 +30,16 @@
 		        }
 		}
 		isComboBox = testWidget=="dijit.form.ComboBox";
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			var pageSize, combo;
 
 			var findMenuItem = function(combo, text){
 				var node = combo.dropDown.domNode.firstChild;
-				while(((node.innerText || node.textContent).indexOf(text)<0) && node.nextSibling){
+				while(((node.innerText || node.textContent).indexOf(text) < 0) && node.nextSibling){
 					node = node.nextSibling;
 				}
 				return node;
-			}
+			};
 
 			doh.robot.initRobot('../_autoComplete.html?testWidget='+testWidget);
 
@@ -79,7 +80,7 @@
 
 						doh.robot.sequence(d.getTestCallback(function(){
 							var list = combo.dropDown.domNode,
-								entries = dojo.query("li", list).filter(isVisible);
+								entries = dojo.query(".dijitMenuItem", list).filter(isVisible);
 							doh.t(isVisible(list), "list is visible");
 							doh.is(31, entries.length, "30 elements plus next button");
 							doh.is("California", combo.focusNode.value, "displayed value hasn't changed");
@@ -105,7 +106,7 @@
 						doh.robot.mouseClick({left:true}, 1000);
 
 						doh.robot.sequence(d.getTestCallback(function(){
-							var entries = dojo.query("li", list).filter(isVisible);
+							var entries = dojo.query(".dijitMenuItem", list).filter(isVisible);
 							doh.is("Minnesota (MN)", innerText(entries[1]), "first entry on second page of drop down");
 							doh.is("California", combo.focusNode.value, "displayed value hasn't changed");
 						}), 1500, 1000);
@@ -127,7 +128,7 @@
 
 						doh.robot.sequence(d.getTestCallback(function(){
 							var list = combo.dropDown.domNode,
-								entries = dojo.query("li", list).filter(isVisible);
+								entries = dojo.query(".dijitMenuItem", list).filter(isVisible);
 							doh.is(2, entries.length, "previous choices + wyoming");
 							doh.is("Wyoming (WY)", innerText(entries[1]));
 						}), 1500, 1000);
@@ -149,7 +150,7 @@
 
 						doh.robot.sequence(d.getTestCallback(function(){
 							var list = combo.dropDown.domNode,
-								entries = dojo.query("li", list);
+								entries = dojo.query(".dijitMenuItem", list);
 							doh.is(32, entries.length, "30 states, plus next and previous button");
 							doh.is("Minnesota (MN)", innerText(entries[1]));
 							doh.is("Wisconsin (WI)", innerText(entries[30]));
@@ -222,12 +223,12 @@
 						var d = new doh.Deferred();
 
 						combo = dijit.byId("setvaluetest");
-						handle = dojo.connect(combo, "onClick", d.getTestCallback(function(){
+						handle = dojo.global.dojo.connect(combo, "onClick", d.getTestCallback(function(){
 							// If we hit here it's OK, if no click event then fail with timeout
 							console.log("hit onClick callback");
 						}));
 
-						dijit.scrollIntoView(combo.domNode);
+						dojo.window.scrollIntoView(combo.domNode);
 
 						doh.robot.mouseMoveAt(combo._buttonNode, 1000, 0);
 						doh.robot.mouseClick({left:true}, 500);
@@ -246,12 +247,12 @@
 						var d = new doh.Deferred();
 
 						combo = dijit.byId("setvaluetest");
-						handle = dojo.connect(combo, "onClick", d.getTestCallback(function(){
+						handle = dojo.global.dojo.connect(combo, "onClick", d.getTestCallback(function(){
 							// If we hit here it's OK, if no click event then fail with timeout
 							console.log("hit onClick callback");
 						}));
 
-						dijit.scrollIntoView(combo.domNode);
+						dojo.window.scrollIntoView(combo.domNode);
 
 						doh.robot.mouseMoveAt(combo.focusNode, 1000, 0);
 						doh.robot.mouseClick({left:true}, 500);
@@ -313,7 +314,7 @@
 								doh.t(list && isVisible(list), "drop down is visible");
 								doh.is(findMenuItem(combo, "Alaska"), combo.dropDown.getHighlightedOption(), "Alaska is highlighted");
 	
-								doh.t(combo._focused, "widget is focused");
+								doh.t(combo.focused, "widget is focused");
 							}), 0);
 						});
 
@@ -344,7 +345,7 @@
 
 						doh.robot.sequence(d.getTestCallback(function(){
 							if(!dojo.isWebKit){		// webkit bug, see #11064 - TODO: verify this is fixed now
-								doh.isNot(combo, dijit.getEnclosingWidget(dojo.global.dijit._curFocus), "click doesn't focus disabled combo");
+								doh.isNot(combo, dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode), "click doesn't focus disabled combo");
 							}
 						}), 1000, 500);
 
@@ -367,7 +368,7 @@
 							doh.f(combo.dropDown, "User was able to open the menu on a disabled ComboBox!");
 
 							// Testcase for #8923, uncomment when that bug is fixed
-							//doh.isNot(combo, dijit.getEnclosingWidget(dojo.global.dijit._curFocus), "button-click doesn't focus disabled combo");
+							//doh.isNot(combo, dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode), "button-click doesn't focus disabled combo");
 						}), 1000, 500);
 						return d;
 					}
@@ -407,7 +408,7 @@
 							}
 						);
 						doh.robot.mouseMoveAt(combo._buttonNode, 1000, 0);
-						doh.robot.mousePress({left:true}, 500) // mousedown on the arrow image
+						doh.robot.mousePress({left:true}, 500); // mousedown on the arrow image
 
 						return d;
 					},
diff --git a/dijit/tests/form/robot/validationMessages.html b/dijit/tests/form/robot/validationMessages.html
index cd9c504..89e3bb9 100644
--- a/dijit/tests/form/robot/validationMessages.html
+++ b/dijit/tests/form/robot/validationMessages.html
@@ -13,18 +13,21 @@
 
 		<!-- 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>
 
 		<script type="text/javascript">
+			dojo.require("dojo.parser");
+
 			dojo.require("dijit.form.NumberTextBox");
+			dojo.require("dijit.Tooltip");
 			dojo.require("dijit.robot");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 
 			// track tooltip currently being displayed (if any)
 			var tooltip;
-			dojo.connect(dijit, "showTooltip", function(msg){ tooltip = msg; });
-			dojo.connect(dijit, "hideTooltip", function(msg){ tooltip = ""; });
+			dojo.connect(dijit.Tooltip, "show", function(msg){ tooltip = msg; });
+			dojo.connect(dijit.Tooltip, "hide", function(msg){ tooltip = ""; });
 
 			function testOn(evt, widget, deferred, callback, delay){
 				var handler = widget.connect(widget.focusNode, "on"+evt,
@@ -34,19 +37,24 @@
 					});
 			}
 
+			doh.register("parse", function parse(){
+				dojo.parser.parse();
+			});
+
 			dojo.forEach([false, true], function(rangeBound){
 				dojo.forEach([false, true], function(required){
 					dojo.forEach(["", "p"], function(promptMessage){
 						dojo.forEach(["", "i"], function(invalidMessage){
 							dojo.forEach(["", "m"], function(missingMessage){
 								var name = "t" + (rangeBound?1:0) + (required?1:0) + (promptMessage?1:0) + (invalidMessage?1:0) + (missingMessage?1:0);
-								var textbox = dijit.byId(name);
+								var textbox;
 
 								doh.register(name, [
 								{
 									name: name + " first focus, empty value",
 									timeout: 5000,
 									setUp:function(){
+										textbox = dijit.byId(name);
 										textbox.focusNode.scrollIntoView();
 									},
 									runTest: function(){
@@ -347,131 +355,131 @@
 	<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 style="border:0px;" size="6" value="t00000"/><br>
+		<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 style="border:0px;" size="6" value="t00001"/><br>
+		<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 style="border:0px;" size="6" value="t00010"/><br>
+		<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 style="border:0px;" size="6" value="t00011"/><br>
+		<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 style="border:0px;" size="6" value="t00100"/><br>
+		<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 style="border:0px;" size="6" value="t00101"/><br>
+		<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 style="border:0px;" size="6" value="t00110"/><br>
+		<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 style="border:0px;" size="6" value="t00111"/><br>
+		<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 style="border:0px;" size="6" value="t01000"/><br>
+		<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 style="border:0px;" size="6" value="t01001"/><br>
+		<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 style="border:0px;" size="6" value="t01010"/><br>
+		<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 style="border:0px;" size="6" value="t01011"/><br>
+		<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 style="border:0px;" size="6" value="t01100"/><br>
+		<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 style="border:0px;" size="6" value="t01101"/><br>
+		<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 style="border:0px;" size="6" value="t01110"/><br>
+		<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 style="border:0px;" size="6" value="t01111"/><br>
+		<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 style="border:0px;" size="6" value="t10000"/><br>
+		<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 style="border:0px;" size="6" value="t10001"/><br>
+		<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 style="border:0px;" size="6" value="t10010"/><br>
+		<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 style="border:0px;" size="6" value="t10011"/><br>
+		<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 style="border:0px;" size="6" value="t10100"/><br>
+		<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 style="border:0px;" size="6" value="t10101"/><br>
+		<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 style="border:0px;" size="6" value="t10110"/><br>
+		<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 style="border:0px;" size="6" value="t10111"/><br>
+		<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 style="border:0px;" size="6" value="t11000"/><br>
+		<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 style="border:0px;" size="6" value="t11001"/><br>
+		<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 style="border:0px;" size="6" value="t11010"/><br>
+		<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 style="border:0px;" size="6" value="t11011"/><br>
+		<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 style="border:0px;" size="6" value="t11100"/><br>
+		<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 style="border:0px;" size="6" value="t11101"/><br>
+		<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 style="border:0px;" size="6" value="t11110"/><br>
+		<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 style="border:0px;" size="6" value="t11111"/><br>
+		<input style="border:0;" size="6" value="t11111"/><br>
 
 	</body>
 </html>
diff --git a/dijit/tests/form/test_Button.html b/dijit/tests/form/test_Button.html
index c791ea1..7c8e221 100644
--- a/dijit/tests/form/test_Button.html
+++ b/dijit/tests/form/test_Button.html
@@ -53,13 +53,30 @@
 
 		<script type="text/javascript">
 			dojo.require("dijit.dijit"); // optimize: load dijit layer
+
 			dojo.require("dijit.ColorPalette");
-			dojo.require("dijit.Menu");
 			dojo.require("dijit.Tooltip");
+
+			dojo.require("dijit.Menu");
+			dojo.require("dijit.MenuItem");
+			dojo.require("dijit.PopupMenuItem");
+			dojo.require("dijit.MenuSeparator");
+
 			dojo.require("dijit.form.Button");
+			dojo.require("dijit.form.DropDownButton");
+			dojo.require("dijit.form.ComboButton");
+			dojo.require("dijit.form.ToggleButton");
+
 			dojo.require("dijit.form.Form");
 			dojo.require("dijit.form.TextBox");
+
 			dojo.require("dojo.parser");
+
+			dojo.ready(99, function(){
+				dijit.form.ViewButton = dojo.declare([dijit.form.Button], {
+					label: "View"
+				});
+			});
 		</script>
 	</head>
 <body class="claro">
@@ -71,24 +88,23 @@
 	<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" data-dojo-props='id:"1465", 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.Button" data-dojo-props='id:"1466", title:"view title", onClick:function(){ console.log("clicked simple"); }'>
-			View
+		<button data-dojo-type="dijit.form.ViewButton" id="T1466" title="view title" data-dojo-props='onClick:function(){ console.log("clicked simple"); }'>
 		</button>
-		<button id="comboCreate" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options", onClick:function(){ console.log("clicked combo save") },
-				iconClass:"plusIcon", title:"creative title"'>
+		<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 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"
 					data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Create from template</span>
 			</span>
 		</button>
-		<button id="edit" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"noteIcon", title:"edit title", value:"Edit"'>
+		<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",
@@ -128,28 +144,28 @@
 				<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" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, disabled:true, 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" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"noteIcon", value:"color"'>
+	<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"
 			data-dojo-props='palette:"3x4", onChange:function(val){ console.log(val); }'></span>
 	</button>
-	<button id="dropdown_up" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='dropDownPosition:["above"], iconClass:"noteIcon", value:"color"'>
+	<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"
 			data-dojo-props='palette:"3x4", onChange:function(val){ console.log(val); }'></span>
 	</button>
-	<button id="dropdown_before" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='dropDownPosition:["before"], iconClass:"noteIcon", value:"color"'>
+	<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"
 			data-dojo-props='palette:"3x4", onChange:function(val){ console.log(val); }'></span>
 	</button>
-	<button id="dropdown_after" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='dropDownPosition:["after"], iconClass:"noteIcon", value:"color"'>
+	<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"
 			data-dojo-props='palette:"3x4", onChange:function(val){ console.log(val); }'></span>
@@ -198,17 +214,17 @@
 	<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 data-dojo-type="dijit.form.Button" data-dojo-props='id:"1467", title:"title attrib rather than label", 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>
+			<span><b>Rich</b><i> Text</i> Test!</span>
 		</button>
-				<div data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"noteIcon", showLabel:false, title:"color title"'>
+		<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"
 				data-dojo-props='palette:"3x4", onChange:function(val){ console.log(val); }'>
 			</div>
-	</div>
-	<div data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options", title:"save title", onClick:function(){ console.log("clicked combo save"); },
+		</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"); },
 				iconClass:"plusBlockIcon", showLabel:false'>
 			<span>Save</span>
 			<div id="saveMenu2" data-dojo-type="dijit.Menu">
@@ -223,7 +239,7 @@
 	<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" data-dojo-type="dijit.form.ToggleButton" data-dojo-props='checked:true,
+		<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");
@@ -304,7 +320,7 @@
 			dojo.byId("toggle").innerHTML= disabled ? "Enable all" : "Disable all";
 		}
 		var labels=["<img src='../images/note.gif' width='20' height='20'/>All", "<i>work</i>", "and no", "<span style='font-size: 40pt;'>play</span>",
-					 "<span style='color: red'>makes</span>", "Jack", "<span style='font-size: 20pt;'>a</a>", "dull",
+					 "<span style='color: red'>makes</span>", "Jack", "<span style='font-size: 20pt;'>a</span>", "dull",
 					 "<img src='../images/plus.gif' width='16' height='16'/>boy"];
 		var idx = 0;
 		function changeLabels(){
@@ -328,7 +344,7 @@
 	<p id="buttonContainer" style="display: none;"></p>
 	<script type="text/javascript">
 		// See if we can make a button in script and attach it to the DOM ourselves.
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			var widget = new dijit.form.Button({
 				label: "hello!",
 				name: "programmatic"
@@ -389,8 +405,7 @@
 	<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" data-dojo-type="dijit.form.Form" data-dojo-props='name:"testForm",
-		encType:"multipart/form-data", action:"../formAction.html", method:"" '>
+	<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>
@@ -408,15 +423,15 @@
 	</div>
 	<form>
 		<label for="onClickName">Value: </label><input id="onClickName" name="onClickName" value="RESET"/><br>
-		<button id="reset1" data-dojo-type="dijit.form.Button" data-dojo-props='type:"reset" '>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" data-dojo-type="dijit.form.Button" data-dojo-props='type:"reset", 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" data-dojo-type="dijit.form.Button" data-dojo-props='type:"reset", 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" data-dojo-type="dijit.form.Button" data-dojo-props='type:"reset", 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" data-dojo-type="dijit.form.Button" data-dojo-props='type:"reset", 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>
 
@@ -429,19 +444,23 @@
 			}
 		};
 	</script>
-	<form id="myForm" data-dojo-type="dijit.form.Form" data-dojo-props='encType:"multipart/form-data", action:"../formAction.html", method:"", target:"formSubmitIframe"'>
-		<button id="Plain" data-dojo-type="dijit.form.Button" data-dojo-props='name:"Plain", type:"submit", value:"Plain Submit", label:"Plain Submit"'></button>
-		<button id="Combo" data-dojo-type="dijit.form.ComboButton" data-dojo-props='name:"Combo", type:"submit", value:"Combo Submit", label:"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="ComboMenuItem" data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ dijit.byId("myForm").submit(); }'>Combo MenuItem Submit</span>
+				<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="DropDown" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='name:"DropDown", type:"submit", value:"DropDown Submit", label:"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="DropDownMenuItem" data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ dijit.byId("myForm").submit(); }'>DropDown MenuItem Submit</span>
+				<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="Disabled" data-dojo-type="dijit.form.Button" data-dojo-props='name:"Disabled", type:"submit", disabled:true, value:"Disabled Submit", label:"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>
diff --git a/dijit/tests/form/test_CheckBox.html b/dijit/tests/form/test_CheckBox.html
index 7f3afda..feb2f09 100644
--- a/dijit/tests/form/test_CheckBox.html
+++ b/dijit/tests/form/test_CheckBox.html
@@ -34,15 +34,15 @@
 		}
 		submittedValues = defaultSubmitHandler;
 
-		function reportChecked(checked) {
+		function reportChecked(checked){
 			dojo.byId("oncheckedoutput").innerHTML = checked;
 		}
 
-		function reportValueChanged(value) {
+		function reportValueChanged(value){
 			dojo.byId("onvaluechangedoutput").innerHTML = value;
 		}
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			var params = {id: "cb6", name: "cb6", checked: true };
 			new dijit.form.CheckBox(params, "cb6");
 			
diff --git a/dijit/tests/form/test_DateTextBox.html b/dijit/tests/form/test_DateTextBox.html
index 068ed54..16b95a3 100644
--- a/dijit/tests/form/test_DateTextBox.html
+++ b/dijit/tests/form/test_DateTextBox.html
@@ -48,7 +48,7 @@
 				// mouseleave/enter map to mouseout/over in all browsers except IE
 				console.log(this.domNode.getAttribute('widgetId') + ' ' + e.type);
 			}
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				dijit.byId("localLong").parse = function(value,constraints){
 					return this.dateLocaleModule.parse(value, (constraints.formatLength="long") && constraints) ||
 						 this.dateLocaleModule.parse(value, (constraints.formatLength="short") && constraints) ||
@@ -161,7 +161,7 @@
 
 			<script>
 			// See if we can make a widget in script and attach it to the DOM ourselves.
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				dojo.connect(dijit.byId('pattern'), "onMouseEnter", eventHandler);
 				dojo.connect(dijit.byId('pattern'), "onMouseLeave", eventHandler);
 				dojo.connect(dijit.byId('pattern'), "onKeyDown", eventHandler);
@@ -184,12 +184,12 @@
 			</script>
 
 			<script>
-				function displayData() {
+				function displayData(){
 					var f = document.getElementById("form1");
 					var s = "";
-					for (var i = 0; i < f.elements.length; i++) {
+					for(var i = 0; i < f.elements.length; i++){
 						var elem = f.elements[i];
-						if (elem.name == "button")  { continue; }
+						if(elem.name == "button")  { continue; }
 						s += elem.name + ": " + elem.value + "\n";
 					}
 					alert(s);
diff --git a/dijit/tests/form/test_Form_onsubmit.html b/dijit/tests/form/test_Form_onsubmit.html
index 345da16..6149409 100644
--- a/dijit/tests/form/test_Form_onsubmit.html
+++ b/dijit/tests/form/test_Form_onsubmit.html
@@ -24,21 +24,13 @@
 		dojo.require("dojo.date");
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dijit.form.Form");
-		dojo.require("dijit.layout.LayoutContainer");
-		dojo.require("dijit.layout.ContentPane");
 		dojo.require("dijit.form.ComboBox");
-		dojo.require("dijit.form.CheckBox");
-		dojo.require("dijit.form.DateTextBox");
 		dojo.require("dijit.form.Button");
-		dojo.require("dijit.form.MultiSelect");
-		dojo.require("dijit.form.Textarea");
-		dojo.require("dijit.form.SimpleTextarea");
-		dojo.require("dijit.Editor");
 		dojo.require("dijit.form.TextBox");
 		
 		function submittedValues(values){
 			console.log('actual submitted values: ' + dojo.toJson(values));
-			dijit.byId("textbox").set('value',dojo.fromJson(dojo.toJson(values)).plopcombo);
+			dijit.byId("textbox").set('value', dojo.fromJson(dojo.toJson(values)).plopcombo, true);
 		}
 	</script>
 
@@ -100,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"'/>
 	
 	<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 bf23b3e..8c3e4f7 100644
--- a/dijit/tests/form/test_Form_state.html
+++ b/dijit/tests/form/test_Form_state.html
@@ -36,6 +36,14 @@
 			according to child widget state.
 		</p>
 		<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
+				submitButton.set("disabled", !this.isValid());
+				this.connect(this, "onValidStateChange", function(state){
+						submitButton.set("disabled", !state);
+				});
+			</script>
 			<table>
 				<tr>
 					<td><label for="name">Name:</label></td>
@@ -73,14 +81,6 @@
 				<script type="dojo/method" data-dojo-event="onClick">
 					console.dir(dijit.byId("form1").get('value'));
 				</script>
-				<script type="dojo/method" data-dojo-event="startup">
-					var form = dijit.byId("form1");
-					//  set initial state
-					this.set("disabled", !form.isValid());
-					this.connect(form, "onValidStateChange", function(state){
-							this.set("disabled", !state);
-					});
-				</script>
 				Submit
 			</button>
 			<button id="addMoreFields" data-dojo-type="dijit.form.Button" >
diff --git a/dijit/tests/form/test_MultiSelect.html b/dijit/tests/form/test_MultiSelect.html
index 35d95b4..cd9d70b 100644
--- a/dijit/tests/form/test_MultiSelect.html
+++ b/dijit/tests/form/test_MultiSelect.html
@@ -42,14 +42,14 @@
 		dojo.require("dijit.form.Button");
 		dojo.require("dijit.layout.SplitContainer");
 
-		dojo.addOnLoad(function(){
+		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 ? "select":"select2" ));
-			}
+				return dojo.byId((++l % 2 == 0 ? "select" : "select2" ));
+			};
 			// based on the the 'dijit' object
 			var count=0;
 			for(var i in dijit){
@@ -86,9 +86,9 @@
 
 			// there is only one debug button
 			dojo.query(".debug").connect("onclick",function(e){
-				console.log('select value:',dijit.byId("select").get('value'));
-				console.log('select2 value:',dijit.byId("select2").get('value'));
-				console.log('select3 value:',dijit.byId("select3").get('value'));
+				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);
 			});
 
 			dojo.connect(dojo.byId("formSubmit"), "onclick", function(e){
diff --git a/dijit/tests/form/test_Select.html b/dijit/tests/form/test_Select.html
index 3a761c2..447a19c 100644
--- a/dijit/tests/form/test_Select.html
+++ b/dijit/tests/form/test_Select.html
@@ -9,6 +9,10 @@
 			@import url(../../themes/claro/claro.css);
 			@import url(../css/dijitTests.css);
 			.ark { text-decoration: underline; }
+			form {
+				margin:  10px 0px;
+				border:  solid gray 2px;
+			}
 		</style>
 
 		<!-- required: the default dijit theme: -->
@@ -30,6 +34,7 @@
 			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;
@@ -76,7 +81,7 @@
 				return ("<span class=\"dijitReset dijitInline dijitSelectLabel\">" + expected + "</span>").toLowerCase().replace(/ */g, "");
 			}
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				dojo.connect(s1, "onChange", function(val){
 					console.log("First Select Changed to " + val);
 					numChanges++;
@@ -245,6 +250,111 @@
 							t.is(7, s12.getOptions().length);
 						}
 					]);
+
+					doh.register("validation", [
+						function required(){
+							var s3 = dijit.byId("s3");
+							doh.is("Incomplete", s3.get("state"), "incomplete because required but no value");
+
+							var stateWatch = "no notification";
+							s3.watch("state", function(name, oval, nval){
+								stateWatch = nval;
+							});
+
+							s3.set("required", false);
+							doh.is("", stateWatch, "watch fired after set requried=true");
+
+							s3.set("required", true);
+							doh.is("Incomplete", stateWatch, "watch fired after set required=false''");
+
+							s3.set("value", "AK");
+							doh.is("", stateWatch, "watch fired after set value=AK''");
+						}
+					]);
+					doh.register("validation in dialog1", [
+						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();
+						},
+						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();
+							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");
+							}), 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(){
+								setTimeout(d.getTestCallback(function(){
+									doh.t(isHidden(masterTT.domNode), "tooltip hidden");
+								}), 300);
+							});
+							return d;
+						},
+						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();
+						},
+						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();
+							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");
+							}), 300);
+							return d;
+						},
+						function tearDown(){
+							return dijit.byId("dlg1").hide();
+						}
+					]);
+
+					doh.register("validation in dialog2", [
+						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();
+						},
+						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();
+							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");
+							}), 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(){
+								setTimeout(d.getTestCallback(function(){
+									doh.t(isHidden(masterTT.domNode), "tooltip hidden");
+								}), 300);
+							});
+							return d;
+						}
+					]);
 				}
 
 				if(testPerformance){			
@@ -322,8 +432,8 @@
 			<a href="test_Select.html?mode=benchmark">test_Select.html?mode=benchmark</a> to run performance tests.
 		</p>
 
-		<h2>HTML select for comparison</h2>
 		<form method="get" id="htmlForm" action="get">
+			<h2>HTML select for comparison</h2>
 			<label for="htmlSelect">Four options:</label>
 			<select id="htmlSelect">
 				<option value="one">one</option>
@@ -335,8 +445,9 @@
 			<select id="htmlSelect2">
 			</select>
 		</form>
-		<h2>dijit.form.Select</h2>
-		<form data-dojo-id="form" data-dojo-type="dijit.form.Form" data-dojo-props='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>
 			<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" '>
@@ -357,7 +468,7 @@
 				<option value="AR">Arkansas</option>
 				<option value="CA">California</option>
 			</select>
-			<label for="s3">Test Three: </label>
+			<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"},
 					required:true,
 					onChange: function(){
@@ -546,13 +657,41 @@
 				<option value="SEL" selected="selected">Select</option>
 				<option value="OTHER">Other</option>
 			</select>
+
+			<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"
+					name="s13" style="width: 150px;" required="true">
+				<option> </option>
+				<option value="AL">Alabama</option>
+				<option value="AK">Alaska</option>
+				<option></option>
+				<option value="AZ">Arizona</option>
+				<option value="AR">Arkansas</option>
+				<option></option>
+				<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"
+					name="s14" style="width: 150px;" required="true">
+				<option> </option>
+				<option value="AL">Alabama</option>
+				<option value="AK">Alaska</option>
+				<option></option>
+				<option value="AZ">Arizona</option>
+				<option value="AR">Arkansas</option>
+				<option></option>
+				<option value="CA">California</option>
+			</select>
+
 			<hr>
 			<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='type:"submit"'>Submit</button>
+			<button data-dojo-type="dijit.form.Button" data-dojo-props='id:"submit", type:"submit"'>Submit</button>
 		</form>
-		<hr>
+
 		<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" '>
@@ -562,5 +701,37 @@
 		<hr>
 		<h4 class="testSubtitle">Programmatic and other tests</h4>
 		<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");
+					if(dlg1.validate()){
+						dlg1.hide();
+					}
+				</script>
+				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");
+					if(dlg2.validate()){
+						dlg2.hide();
+					}
+				</script>
+				validate and close
+			</div>
+		</div>
+		<button dojoType="dijit.form.Button" id="dlg2OpenBtn"
+				onclick="dijit.byId('dlg2').show();">show two select dialog</button>
 	</body>
 </html>
diff --git a/dijit/tests/form/test_SimpleTextarea.html b/dijit/tests/form/test_SimpleTextarea.html
index 4ed94fa..834c9f4 100644
--- a/dijit/tests/form/test_SimpleTextarea.html
+++ b/dijit/tests/form/test_SimpleTextarea.html
@@ -85,7 +85,7 @@
 			}
 		</script>
 		<input type="button" onclick="setAttr('readOnly', false);" value="Remove readOnly"/>
-		<input type="button" onclick="setAttr('readOnly', false);" value="Set readOnly"/>
+		<input type="button" onclick="setAttr('readOnly', true);" value="Set readOnly"/>
 		<input type="button" onclick="setAttr('disabled', true);" value="Disable"/>
 		<input type="button" onclick="setAttr('disabled', false);" value="Enable"/>
 </body>
diff --git a/dijit/tests/form/test_Slider.html b/dijit/tests/form/test_Slider.html
index 74c2db7..d63e578 100644
--- a/dijit/tests/form/test_Slider.html
+++ b/dijit/tests/form/test_Slider.html
@@ -13,7 +13,7 @@
 				height:12px;
 				border: none;
 				font-size:11px;
-				padding:0px;
+				padding:0;
 			}
 		</style>
 
@@ -59,9 +59,6 @@
 					// and setup the slider
 					var theSlider = new dijit.form.VerticalSlider({
 						value:1400,
-						onChange: function(){
-                                                    console.log(arguments);
-						},
 						name:"programaticSlider",
 						slideDuration:0,
 						onChange:function(val){ dojo.byId('sliderProgInput').value=val; },
@@ -78,7 +75,7 @@
         				sliderRules.startup();
 
 				};
-				dojo.addOnLoad(programaticExample);
+				dojo.ready(programaticExample);
 		</script>
 	</head>
 
@@ -100,7 +97,7 @@
 			showButtons:true,
 			intermediateChanges:true,
 			slideDuration:500,
-			style:{width:"500px", height:"20px"}
+			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>
@@ -201,12 +198,12 @@
 
 		        <script>
 				// so robot can get to it easily
-				document.displayData=function() {
+				document.displayData=function(){
 					var f = document.getElementById("form1");
 					var s = "";
-					for (var i = 0; i < f.elements.length; i++) {
+					for(var i = 0; i < f.elements.length; i++){
 						var elem = f.elements[i];
-						if (elem.nodeName.toLowerCase() == "button" || elem.type=="submit" || elem.type=="button")  { continue; }
+						if(elem.nodeName.toLowerCase() == "button" || elem.type=="submit" || elem.type=="button")  { continue; }
 						s += elem.name + ": " + elem.value + "\n";
 					}
 					return s;
diff --git a/dijit/tests/form/test_Spinner.html b/dijit/tests/form/test_Spinner.html
index 7ccbf4d..915955e 100644
--- a/dijit/tests/form/test_Spinner.html
+++ b/dijit/tests/form/test_Spinner.html
@@ -107,12 +107,12 @@
 			<p>
 			<script type="text/javascript">
 				// so robot can get to it easily
-				document.displayData=function() {
+				document.displayData=function(){
 					var f = document.getElementById("form1");
 					var s = "";
-					for (var i = 0; i < f.elements.length; i++) {
+					for(var i = 0; i < f.elements.length; i++){
 						var elem = f.elements[i];
-						if (elem.nodeName.toLowerCase() == "button" || elem.type=="submit" || elem.type=="button")  { continue; }
+						if(elem.nodeName.toLowerCase() == "button" || elem.type=="submit" || elem.type=="button")  { continue; }
 						s += elem.name + ": " + elem.value + "\n";
 					}
 					return s;
diff --git a/dijit/tests/form/test_Textarea.html b/dijit/tests/form/test_Textarea.html
index 1c94093..5036980 100644
--- a/dijit/tests/form/test_Textarea.html
+++ b/dijit/tests/form/test_Textarea.html
@@ -70,13 +70,13 @@
 			</div>
 			<script type="text/javascript">
 				// See if we can make a widget in script
-				dojo.addOnLoad(function(){
+				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"}
+						style: {border:"5px solid gray", padding:"11px", margin:"7px", minHeight:"2em"}
 					}, "programmatic");
 				});
 			</script>
@@ -126,7 +126,7 @@ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
 				<input type="submit" name="submit" />
 			</div>
 			<script type="text/javascript">
-				function displayData() {
+				function displayData(){
 					var f = dojo.byId("form1");
 					var s = "";
 					for(var i = 0; i < f.elements.length; i++){
diff --git a/dijit/tests/form/test_TimeTextBox.html b/dijit/tests/form/test_TimeTextBox.html
index 9a633dc..817e455 100644
--- a/dijit/tests/form/test_TimeTextBox.html
+++ b/dijit/tests/form/test_TimeTextBox.html
@@ -50,12 +50,12 @@
 
 			formValue = null;
 	
-			function displayData() {
+			function displayData(){
 				var f = document.getElementById("form1");
 				var s = "";
-				for (var i = 0; i < f.elements.length; i++) {
+				for(var i = 0; i < f.elements.length; i++){
 						var elem = f.elements[i];
-						if (elem.name == "button")  { continue; }
+						if(elem.name == "button")  { continue; }
 						s += elem.name + ": " + elem.value + "\n";
 				}
 				console.log(s);
@@ -172,7 +172,10 @@
 					required:true,
 					invalidMessage:"" '/>
 			</div>
-
 		</form>
+		<input id="ro" type="button" onclick="dijit.byId('q20').set('readOnly',true);" value="Set readOnly" tabIndex="-1"/>
+		<input id="rw" type="button" onclick="dijit.byId('q20').set('readOnly',false);" value="Clear readOnly" tabIndex="-1"/>
+		<input id="disable" type="button" onclick="dijit.byId('q20').set('disabled',true);" value="Disable" tabIndex="-1"/>
+		<input id="enable" type="button" onclick="dijit.byId('q20').set('disabled',false);" value="Enable" tabIndex="-1"/>
 	</body>
 </html>
diff --git a/dijit/tests/form/test_validStatePerformance.html b/dijit/tests/form/test_validStatePerformance.html
index 72e1561..2438d18 100644
--- a/dijit/tests/form/test_validStatePerformance.html
+++ b/dijit/tests/form/test_validStatePerformance.html
@@ -32,7 +32,7 @@
 
   <body class="claro">
     <script>
-      function performancetest() {
+      function performancetest(){
         console.log("Dojo version " + dojo.version);
         var startTime1 = (new Date()).getTime();
         dijit.byId("form1").reset();
@@ -43,26 +43,27 @@
         console.log("Time 2: Reset form with ValidationTextBox-fields: " + ((new Date()).getTime() - startTime2) + " millis");
 
         var startTime3 = (new Date()).getTime();
-        for (var i = 1; i <= 20; i++) {
-			    var w = dijit.byId("input1_" + i);
-			    if(dojo.version.major == 1 && dojo.version.minor == 2) {
-			      w.set("value", i);
-			    } else {
-			      w.set("value", i);
-			    }
-			  }
-        console.log("Time 3: Inserting value into NumberTextBox-fields: " + ((new Date()).getTime() - startTime3) + " millis");
+		var i, w;
+        for(i = 1; i <= 20; i++){
+			w = dijit.byId("input1_" + i);
+			if(dojo.version.major == 1 && dojo.version.minor == 2){
+			  w.set("value", i);
+			}else{
+			  w.set("value", i);
+			}
+		}
+		console.log("Time 3: Inserting value into NumberTextBox-fields: " + ((new Date()).getTime() - startTime3) + " millis");
 
         var startTime4 = (new Date()).getTime();
-        for (var i = 1; i <= 20; i++) {
-			    var w = dijit.byId("input2_" + i);
-			    if(dojo.version.major == 1 && dojo.version.minor == 2) {
-			      w.set("value", i);
-			    } else {
-			      w.set("value", i);
-			    }
-			  }
-        console.log("Time 4: Inserting value into ValidationTextBox-fields: " + ((new Date()).getTime() - startTime4) + " millis");
+        for(i = 1; i <= 20; i++){
+			w = dijit.byId("input2_" + i);
+			if(dojo.version.major == 1 && dojo.version.minor == 2){
+			  w.set("value", i);
+			}else{
+			  w.set("value", i);
+			}
+		}
+		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:""'>
diff --git a/dijit/tests/form/test_validate.html b/dijit/tests/form/test_validate.html
index bcb7739..7c39dc9 100644
--- a/dijit/tests/form/test_validate.html
+++ b/dijit/tests/form/test_validate.html
@@ -51,7 +51,7 @@
 		</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"
@@ -62,15 +62,19 @@
 
 		<script type="text/javascript">
 			dojo.require("doh.runner");
-			dojo.require("dijit.dijit"); // optimize: load dijit layer
+
 			dojo.require("dijit.form.TextBox");
 			dojo.require("dijit.form.ValidationTextBox");
 			dojo.require("dijit.form.NumberTextBox");
 			dojo.require("dijit.form.CurrencyTextBox");
+
+			dojo.require("dijit.Dialog");
+			dojo.require("dijit.form.Button");
+
 			dojo.require("dojo.currency");
 			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 
-			dojo.addOnLoad(function(){
+			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');
@@ -139,7 +143,8 @@
 			</div>
 			<div class="testExample">
 				<input id="q01" data-dojo-type="dijit.form.TextBox"
-					data-dojo-props='name:"firstname", value:"testing testing", style:{width:"700px"}, tabIndex:"2",
+					name="firstname" value="testing testing" style="width:700px" tabIndex="2"
+					data-dojo-props='
 					trim:true,
 					selectOnClick:true,
 					onFocus:function(){ console.log("user onfocus handler"); },
@@ -158,9 +163,8 @@
 			</div>
 			<div class="testExample">
 				<input id="q02" data-dojo-type="dijit.form.TextBox"
-					data-dojo-props='name:"lastname", value:"testing testing", "class":"verylong",
-					trim:true,
-					uppercase:true '/>
+					name="lastname" value="testing testing" class="verylong"
+					data-dojo-props='trim:true, uppercase:true '/>
 			</div>
 
 			<div class="dojoTitlePaneLabel">
@@ -169,10 +173,10 @@
 			</div>
 			<div class="testExample">
 				<input id="q03" data-dojo-type="dijit.form.NumberTextBox"
-					data-dojo-props='name:"age", tabIndex:"1",
+					name="age" tabIndex="1" class="small"
+					data-dojo-props='
 					promptMessage:"(optional) Enter an age between 0 and 120",
 					maxLength:"3",
-					"class":"small",
 					constraints:{places:0,min:0,max:120},
 					onChange:function(val){ dojo.byId("oc3").value=""+val; },
 					tooltipPosition:["above", "below"]
@@ -194,11 +198,8 @@
 			</div>
 			<div class="testExample">
 				<input id="fav" data-dojo-type="dijit.form.NumberTextBox"
-					data-dojo-props='name:"fav", "class":"small",
-					maxLength:"3",
-					constraints:{places:0,min:1,max:100},
-					regExpGen:function(){ return "\\d+" },
-					required:true'/>
+					name="fav" class="small" required
+					data-dojo-props='maxLength:"3",constraints:{places:0,min:1,max:100},regExpGen:function(){ return "\\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,10 +211,8 @@
 			</div>
 			<div class="testExample">
 				<input id="q04" data-dojo-type="dijit.form.ValidationTextBox"
-					data-dojo-props='name:"occupation", "class":"verylong", style:{fontSize:"15pt"},
-					lowercase:true,
-					required:true,
-					promptMessage:"Enter an occupation" '/>
+					name="occupation" class="verylong" style="fontSize:15pt" required="true"
+					data-dojo-props='lowercase:true, promptMessage:"Enter an occupation" '/>
 			</div>
 
 			<div class="dojoTitlePaneLabel">
@@ -228,7 +227,7 @@
 			</div>
 <script>
 	// See if we can make a widget in script and attach it to the DOM ourselves.
-	dojo.addOnLoad(function(){
+	dojo.ready(function(){
 		var props = {
 			name: "elevation",
 			value: 3000,
@@ -255,7 +254,7 @@
 
 			<script>
 				// See if we can make a widget in script and attach it to the DOM ourselves.
-				dojo.addOnLoad(function(){
+				dojo.ready(function(){
 					var props = {
 						name: "population",
 						value: "1,500,000",
@@ -306,23 +305,19 @@
 
 			<div class="testExample">
 				<input id="q08" data-dojo-type="dijit.form.CurrencyTextBox"
-					data-dojo-props='name:"income1", "class":"medium", value:54775.53,
-					required:true,
-					constraints:{fractional:true},
-					currency:"USD",
-					onChange:function(val){ dojo.byId("oc8").value = val; },
-					invalidMessage:"Invalid amount.  Cents are MANDATORY." '/>USD
+					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"/>
 			</div>
 
 			<div class="testExample">
 				euro currency (local format) fractional part is optional:
 				<input id="q08eur" data-dojo-type="dijit.form.CurrencyTextBox"
-					data-dojo-props='name:"income2",
-					"class":"medium", value:54775.53,
-					required:true,
-					currency:"EUR",
-					invalidMessage:"Invalid amount.  Include cents." '/>EUR
+					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>
 				<button onclick="dijit.byId('q08eur').set('disabled',false); return false;">Enable</button>
 				<button onclick="dijit.byId('q08eur').reset(); return false;">Reset</button>
@@ -340,7 +335,7 @@
 			<script>
 				// See if we can make a widget in script and attach it
 				// to the DOM ourselves.
-				dojo.addOnLoad(function(){
+				dojo.ready(function(){
 					var example = dojo.currency.format(54775.53, {locale: 'de-de', currency: "EUR"});
 					var props = {
 						name: "income3",
@@ -455,10 +450,8 @@
 			</div>
 			<div class="testExample">
 				<input id="q22" data-dojo-type="dijit.form.ValidationTextBox"
-					data-dojo-props='name:"phone", "class":"medium", value:"someTestString",
-					regExp:"[\\w]+",
-					required:true,
-					invalidMessage:"Invalid Non-Space Text."'/>
+					name="phone" class="medium" value="someTestString" required
+					data-dojo-props='regExp:"[\\w]+", invalidMessage:"Invalid Non-Space Text."'/>
 			</div>
 
 			<div class="dojoTitlePaneLabel">
@@ -466,8 +459,7 @@
 				<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" data-dojo-props='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">
@@ -480,12 +472,12 @@
 
 			<script>
 				// See if we can make a widget in script and attach it to the DOM ourselves.
-				dojo.addOnLoad(function(){
+				dojo.ready(function(){
 					var props = {
 							name: "ticket1651",
 							id: "mname",
 							templateString: null, // #11493
-							templatePath: dojo.moduleUrl('dijit.form', 'templates/TextBox.html'),
+							templatePath: dojo.moduleUrl('dijit.form.templates', 'TextBox.html'),
 							value: null
 					};
 					var w = new dijit.form.TextBox(props, "ticket1651");
@@ -498,7 +490,7 @@
 			</div>
 			<div class="testExample">
 				<input id="q24" data-dojo-type="dijit.form.TextBox"
-					data-dojo-props='name: "readOnly", "class": "medium", readOnly: true, value: "cannot type here", title: "hint text" '/>
+					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"/>
 				<input type="button" id="removedisabled" onclick="dijit.byId('q24').set('disabled',false);" value="Remove disabled" tabIndex="-1"/>
@@ -510,7 +502,7 @@
 			</div>
 			<div class="testExample">
 				<input id="q25" data-dojo-type="dijit.form.ValidationTextBox"
-					data-dojo-props='name: "disabled", "class": "medium", disabled: true, value: "cannot type here" '/>
+					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"/>
 				<input type="button" onclick="dijit.byId('q25').set('disabled',false);" value="Remove disabled" tabIndex="-1"/>
@@ -519,12 +511,12 @@
 
 			<script>
 				// so robot can get to it easily
-				document.displayData=function() {
+				document.displayData=function(){
 					var f = document.getElementById("form1");
 					var s = "";
-					for (var i = 0; i < f.elements.length; i++) {
+					for(var i = 0; i < f.elements.length; i++){
 						var elem = f.elements[i];
-						if (elem.nodeName.toLowerCase() == "button" || elem.type=="submit" || elem.type=="button")  { continue; }
+						if(elem.nodeName.toLowerCase() == "button" || elem.type=="submit" || elem.type=="button")  { continue; }
 						s += elem.name + ": " + elem.value + "\n";
 					}
 					return s;
@@ -542,8 +534,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" data-dojo-props='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>
@@ -560,5 +551,13 @@
 		<div class="sans">
 			<input id="sans1"/>
 		</div>
+
+		<h2>Validation tooltips inside of dialogs:</h2>
+		<div dojoType="dijit.Dialog" id="dlg">
+			<label for="dlgNTB">NumberTextBox:</label>
+			<div dojoType="dijit.form.NumberTextBox" id="dlgNTB"></div>
+		</div>
+		<button dojoType="dijit.form.Button" id="dlgOpenBtn" onclick="dijit.byId('dlg').show();">show dialog</button>
+
 	</body>
 </html>
diff --git a/dijit/tests/form/test_verticalAlign.html b/dijit/tests/form/test_verticalAlign.html
index ed3fd18..8d7e2a7 100644
--- a/dijit/tests/form/test_verticalAlign.html
+++ b/dijit/tests/form/test_verticalAlign.html
@@ -36,7 +36,7 @@
 		dojo.require("dijit.form.NumberTextBox");
 		dojo.require("dojo.parser");
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 
 			function test_all(pre){
 				function compare2native(className){
diff --git a/dijit/tests/helpers.js b/dijit/tests/helpers.js
index 4aea33e..b624deb 100644
--- a/dijit/tests/helpers.js
+++ b/dijit/tests/helpers.js
@@ -7,7 +7,7 @@ function isVisible(/*dijit._Widget || DomNode*/ node){
 	if(node.domNode){ node = node.domNode; }
 	return (dojo.style(node, "display") != "none") &&
 		(dojo.style(node, "visibility") != "hidden") &&
-		(p = dojo.position(node), p.y + p.h >= 0 && p.x + p.w >= 0 && p.h && p.w);
+		(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){
@@ -17,7 +17,7 @@ function isHidden(/*dijit._Widget || DomNode*/ node){
 	if(node.domNode){ node = node.domNode; }
 	return (dojo.style(node, "display") == "none") ||
 		(dojo.style(node, "visibility") == "hidden") ||
-		(p = dojo.position(node), p.y + p.h < 0 || p.x + p.w < 0 || p.h <= 0 || p.w <= 0);
+		(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){
@@ -52,7 +52,7 @@ function tabOrder(/*DomNode?*/ root){
 				walkTree(child);
 			}
 		});
-	};
+	}
 
 	walkTree(root || dojo.body());
 
@@ -71,4 +71,4 @@ function onFocus(func){
 		dojo.unsubscribe(handle);
 		setTimeout(function(){ func(node); }, 0);
 	});
-}
\ No newline at end of file
+}
diff --git a/dijit/tests/i18n/currency.html b/dijit/tests/i18n/currency.html
index 697da59..4da4ca2 100644
--- a/dijit/tests/i18n/currency.html
+++ b/dijit/tests/i18n/currency.html
@@ -22,7 +22,7 @@
 		</script>
 		<script src="test_i18n.js"></script>
 		<script type="text/javascript">
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.register("t", getAllTestCases());
 				doh.run();
 			});
@@ -67,7 +67,7 @@
 		</p>
 
 		<script>
-		(function() {
+		(function(){
 			genFormatTestCases("Currency Format", "dijit.form.CurrencyTextBox", [
 
 				{ attrs: {Currency: "CNY", lang: "zh-cn"},
diff --git a/dijit/tests/i18n/date.html b/dijit/tests/i18n/date.html
index 1e982c6..46960f1 100644
--- a/dijit/tests/i18n/date.html
+++ b/dijit/tests/i18n/date.html
@@ -22,7 +22,7 @@
 		</script>
 		<script src="test_i18n.js"></script>
 		<script type="text/javascript">
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.register("t", getAllTestCases());
 				doh.run();
 			});
@@ -55,7 +55,7 @@
 			td {white-space:nowrap}
 		</style>
 		<script>
-			function gen4DateFormat(testCases, language, locale, date, short, shortCmt, medium, mediumCmt, long, longCmt, full, fullCmt) {
+			function gen4DateFormat(testCases, language, locale, date, short, shortCmt, medium, mediumCmt, long, longCmt, full, fullCmt){
 				testCases.push({
 				  attrs: {constraints: "{formatLength:'short'}", lang: language},
 				  desc: "Locale: <b>" + locale + "</b> Format: <b>Short</b>",
@@ -98,7 +98,7 @@
 		</p>
 
 		<script>
-		(function() {
+		(function(){
 			var testCases = [];
 			gen4DateFormat(testCases, "ru-ru", "ru_RU", "2005-07-31",
 				"31.07.05", "", "31.07.2005", "", "31 июля 2005 г.", "Failed in Firefox. <a href='currency.html#cmt_1'>See #1 (currency.html).</a>", "31 июля 2005 г.", "Failed in Firefox. <a href='currency.html#cmt_1'>See #1 (currency.html).</a>");
diff --git a/dijit/tests/i18n/digit.html b/dijit/tests/i18n/digit.html
index 9b421d7..6527d9e 100644
--- a/dijit/tests/i18n/digit.html
+++ b/dijit/tests/i18n/digit.html
@@ -22,14 +22,14 @@
 		</script>
 		<script src="test_i18n.js"></script>
 		<script type="text/javascript">
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				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, short, shortCmt, medium, mediumCmt, long, longCmt, full, 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>",
@@ -98,7 +98,7 @@
 		</p>
 
 		<script>
-		(function() {
+		(function(){
 
 			genFormatTestCases("Number Format", "dijit.form.NumberTextBox", [
 				{ attrs: {lang: "ar-eg"},
diff --git a/dijit/tests/i18n/number.html b/dijit/tests/i18n/number.html
index 000366f..e05c297 100644
--- a/dijit/tests/i18n/number.html
+++ b/dijit/tests/i18n/number.html
@@ -22,7 +22,7 @@
 		</script>
 		<script src="test_i18n.js"></script>
 		<script type="text/javascript">
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.register("t", getAllTestCases());
 				doh.run();
 			});
@@ -66,7 +66,7 @@
 		</p>
 
 		<script>
-		(function() {
+		(function(){
 
 			genFormatTestCases("Number Format", "dijit.form.NumberTextBox", [
 
diff --git a/dijit/tests/i18n/textbox.html b/dijit/tests/i18n/textbox.html
index 01087c0..97ebe2d 100644
--- a/dijit/tests/i18n/textbox.html
+++ b/dijit/tests/i18n/textbox.html
@@ -22,7 +22,7 @@
 		</script>
 		<script src="test_i18n.js"></script>
 		<script type="text/javascript">
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.register("t", getAllTestCases());
 				doh.run();
 			});
@@ -63,7 +63,7 @@
 		<button id="startButton" onclick="startTest()">Start Test</button>-->
 
 		<script>
-		(function() {
+		(function(){
 			genFormatTestCases("Natural Language Casing Mapping", "dijit.form.TextBox", [
 
 				{ attrs: {uppercase: "true"},
diff --git a/dijit/tests/i18n/time.html b/dijit/tests/i18n/time.html
index 99c0de6..207fe88 100644
--- a/dijit/tests/i18n/time.html
+++ b/dijit/tests/i18n/time.html
@@ -46,7 +46,7 @@
 			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 			dojo.require("doh.runner");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				dojo.declare(
 					"dijit.form.TimeTextBox",
 					dijit.form.ValidationTextBox,
@@ -59,7 +59,7 @@
 				);
 	
 				var tz_s = dojo.date.getTimezoneName(new Date());
-				if (!tz_s) {
+				if(!tz_s){
 					var offset = new Date().getTimezoneOffset();
 					var tz = [
 						(offset <= 0 ? "+" : "-"),
@@ -71,7 +71,7 @@
 					tz_s = tz.join("");
 				}
 	
-				function gen4DateFormat(testCases, language, locale, date, shortFmt, shortCmt, mediumFmt, mediumCmt, longFmt, longCmt, full, fullCmt) {
+				function gen4DateFormat(testCases, language, locale, date, shortFmt, shortCmt, mediumFmt, mediumCmt, longFmt, longCmt, full, fullCmt){
 					var tz_l = language.indexOf("hi") == 0 && dojo.number.normalizeDigitChars ?
 						dojo.number.normalizeDigitChars(tz_s, language) : tz_s;
 	
@@ -115,10 +115,10 @@
 					  comment: fullCmt
 					});
 	
-					date.processValue = function (value) {
+					date.processValue = function(value){
 						return value ? new Date(1970, 0, 1, value.getHours(), value.getMinutes(), value.getSeconds()) : value;
 					};
-					if (shortDate) {
+					if(shortDate){
 						shortDate.processValue = date.processValue;
 					}
 				}
diff --git a/dijit/tests/infrastructure-module.js b/dijit/tests/infrastructure-module.js
index 870cb8a..276a4bb 100644
--- a/dijit/tests/infrastructure-module.js
+++ b/dijit/tests/infrastructure-module.js
@@ -6,14 +6,14 @@ try{
 	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);
 
 	// _Templated and other mixins
-	doh.registerUrl("dijit.tests._Templated", dojo.moduleUrl("dijit", "tests/_Templated.html"), 999999);
-	doh.registerUrl("dijit.tests._Templated-widgetsInTemplate", dojo.moduleUrl("dijit", "tests/_Templated-widgetsInTemplate.html"), 999999);
+	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);
 
diff --git a/dijit/tests/layout/AccordionContainer.html b/dijit/tests/layout/AccordionContainer.html
index 8aa732c..4324766 100644
--- a/dijit/tests/layout/AccordionContainer.html
+++ b/dijit/tests/layout/AccordionContainer.html
@@ -25,13 +25,15 @@
 
 	<script type="text/javascript">
 		dojo.require("doh.runner");
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		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;
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			doh.register("basic",
 				[
 					{
@@ -414,6 +416,39 @@
 				}
 			]);
 
+			doh.register("markup", [
+				{
+					name: "create",
+					runTest: function(t){
+						dojo.parser.parse();
+
+						accordion = dijit.byId("markupAccordion");
+
+						var titles = dojo.query(".dijitAccordionText", accordion.domNode);
+						t.is(3, titles.length, "number of titles");
+						t.is("Other Lazy Load Pane", titles[2].innerHTML);
+
+						var children = accordion.getChildren();
+						t.is(3, children.length, "number of children (ie, contentpanes)");
+					}
+				},
+				{
+					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"});
+						accordion.addChild(pane1half, 1);
+
+						var titles = dojo.query(".dijitAccordionText", accordion.domNode);
+						t.is(4, titles.length, "number of titles");
+						t.is("pane 1.5", titles[1].innerHTML);
+
+						var children = accordion.getChildren();
+						t.is(4, children.length, "number of children (ie, contentpanes)");
+						t.is(pane1half, children[1], "second child is the newly inserted one");
+					}
+				}
+			]);
+
 			doh.run();
 		});
 	</script>
@@ -422,5 +457,54 @@
 
 	<h1 class="testTitle">AccordionContainer Automated Tests</h1>
 
+	<h2 class="testTitle">Markup Accordion</h2>
+	<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>
+
+		<!-- test lazy loading.   margin style for testing size calculations. -->
+		<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"
+			 data-dojo-props='title:"Other Lazy Load Pane", href:"doc1.html"'></div>
+
+	</div>
+
+	<h2 class="testTitle">Programmatic Accordions</h2>
+
 </body>
 </html>
diff --git a/dijit/tests/layout/BorderContainer.html b/dijit/tests/layout/BorderContainer.html
index 0d6f758..e49658b 100644
--- a/dijit/tests/layout/BorderContainer.html
+++ b/dijit/tests/layout/BorderContainer.html
@@ -28,10 +28,16 @@
 		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.addOnLoad(function(){
+        dojo.ready(function(){
 
 			doh.register("markup", [
 				function parse(){
@@ -40,6 +46,9 @@
 				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(){
@@ -97,9 +106,9 @@
 
 					// 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")
+					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")),
@@ -139,7 +148,8 @@
 				function createProgramatically(){
 					originalWidgetCnt = dijit.registry.length;
 
-					bc = new dijit.layout.BorderContainer({style:'height:400px;width:500px;border:1px solid black'}, dojo.byId('main'));
+					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";
@@ -191,6 +201,33 @@
 				}
 			]);
 
+			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();
         });
 
@@ -252,8 +289,36 @@
 		</div>
 	</div>
 
-	<p>Programatically created</p>
+	<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>
+			<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>
+			</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-remote.html b/dijit/tests/layout/ContentPane-remote.html
index d8766b4..4bcbca9 100644
--- a/dijit/tests/layout/ContentPane-remote.html
+++ b/dijit/tests/layout/ContentPane-remote.html
@@ -24,16 +24,22 @@
 
 	<script type="text/javascript">
 		dojo.require("doh.runner");
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.layout.AccordionContainer");
+
+		dojo.require("dojo.parser");
+
+		dojo.require("dijit._Widget");
+		dojo.require("dijit._TemplatedMixin");
+
 		dojo.require("dijit.Tooltip");
 		dojo.require("dijit.TooltipDialog");
-		dojo.require("dijit.layout.LinkPane");
+
 		dojo.require("dijit.form.Button");
 		dojo.require("dijit.form.DropDownButton");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+
+		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){
@@ -66,10 +72,10 @@
 			return domNode.firstChild.innerHTML == "Loading...";
 		}
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			// create a do nothing, only for test widget
 			dojo.declare("dijit.TestWidget",
-				[dijit._Widget, dijit._Templated], {
+				[dijit._Widget, dijit._TemplatedMixin], {
 				templateString: "<span class='dijitTestWidget'></span>"
 			});
 
@@ -184,7 +190,7 @@
 						var d = new doh.Deferred();
 
 						setTimeout(d.getTestErrback(function(){
-							var msg = 'refreshed load'
+							var msg = 'refreshed load';
 							cp.href = "getResponse.php?message="+encodeURI(msg);
 							cp.refresh().then(d.getTestCallback(function(){
 								doh.is(msg, cp.domNode.innerHTML);
@@ -272,7 +278,7 @@
 
 						cp.onDownloadError = function(){
 							return msg;
-						}
+						};
 
 						var d = new doh.Deferred();
 
diff --git a/dijit/tests/layout/ContentPane.html b/dijit/tests/layout/ContentPane.html
index 997c540..8446de4 100644
--- a/dijit/tests/layout/ContentPane.html
+++ b/dijit/tests/layout/ContentPane.html
@@ -23,20 +23,24 @@
 		data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
 		dojo.require("doh.runner");
-		dojo.require("dijit.layout.ContentPane");
+
+		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._Templated");
 		dojo.require("dijit.layout.StackContainer");
-		dojo.require("dojo.parser");
+		dojo.require("dijit.layout.ContentPane");
 		dojo.require("dijit.Dialog");
 
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			// create a do nothing, only for test widget
 			dojo.declare("dijit.TestWidget",
-				[dijit._Widget, dijit._Templated], {
+				[dijit._Widget, dijit._TemplatedMixin], {
 				templateString: "<span class='dijitTestWidget'></span>"
 			});
 
@@ -53,7 +57,7 @@
 				]
 			);
 
-			var pane2;
+			var pane2, MyWidget;
 
 			doh.registerGroup("pane2",
 				[
@@ -156,6 +160,25 @@
 							// 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 = 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;
+						}
 					}
 				]
 			);
@@ -460,10 +483,10 @@
 					// even non-widgets inside of ContentPane (like dojo.dnd.Source) should have
 					// startup called on them
 					dojo.parser.parse(dojo.byId("nonWidgetTest"));
-					doh.t(1, nwStartupCalls, "startup() on non-widgets called on parse");
+					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.t(2, nwStartupCalls, "startup() called on non-widgets via set(content, ...)");
+					doh.is(2, nwStartupCalls, "startup() called on non-widgets via set(content, ...)");
 				}
 			]);
 
diff --git a/dijit/tests/layout/ContentPaneLayout.html b/dijit/tests/layout/ContentPaneLayout.html
index e3ced12..bd5c205 100644
--- a/dijit/tests/layout/ContentPaneLayout.html
+++ b/dijit/tests/layout/ContentPaneLayout.html
@@ -22,7 +22,7 @@
 		dojo.require("dojo.parser");
 
 		dojo.require("dijit._Widget");
-		dojo.require("dijit._Templated");
+		dojo.require("dijit._TemplatedMixin");
 		dojo.require("dijit.layout.ContentPane");
 		dojo.require("dijit.layout.TabContainer");
 		dojo.require("dijit.layout.BorderContainer");
@@ -43,11 +43,11 @@
 			loadEvents[this.id] = (loadEvents[this.id] || 0) + 1;
 		}
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 
 			// create a do nothing, only for test widget
 			dojo.declare("ResizableWidget",
-				[dijit._Widget, dijit._Templated], {
+				[dijit._Widget, dijit._TemplatedMixin], {
 				templateString: "<span class='dijitInline resizableWidget'>resizable widget</span>",
 				_resized: 0,
 				_resizeArgs: null,
@@ -243,10 +243,10 @@
 							var child = dijit.byId("singleChildResizable");
 							doh.is(0, child._resized, "hasn't been shown yet so no resize events");
 
-							dijit.byId("resizeTC").selectChild(dijit.byId("singleChildPane"))
+							dijit.byId("resizeTC").selectChild(dijit.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")
+							doh.t(child._resizeArgs && child._resizeArgs.length, "got size specified");
 
 							var size = child._resizeArgs[0];
 							doh.t(size && size.h, "non-0 height specified");
@@ -265,10 +265,10 @@
 							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"))
+							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.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")
 						}
@@ -281,15 +281,15 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 
-							dijit.byId("resizeTC").selectChild(dijit.byId("singleChildHref"))
+							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(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")
+								doh.t(layoutResizes["singleChildHrefBorderContainer"][0].length, "got size specified");
 
 								var size = layoutResizes["singleChildHrefBorderContainer"][0][0];
 								doh.t(size && size.h, "non-0 height specified");
@@ -297,7 +297,7 @@
 
 								// Check that resize() events also trickled down to inner TabContainer
 								var child2 = dijit.byId("singleChildHrefInnerTabContainer");
-								doh.t(child2, "inner TabContainer was created")
+								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);
@@ -312,13 +312,13 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 
-							dijit.byId("resizeTC").selectChild(dijit.byId("multipleChildHref"))
+							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(child, "TabContainer was created");
 								doh.t(layoutResizes["multipleChildHrefTabContainer"], "got resize event");
 								doh.is(0, layoutResizes["multipleChildHrefTabContainer"][0].length, "no size specified")
 							}), 4000);
@@ -342,10 +342,10 @@
 							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"))
+							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.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")
 						}
@@ -360,7 +360,7 @@
 							doh.is(1, child.history.length, "child # of history events (before show)");
 							doh.is("started", child.history[0], "child history");
 
-							dijit.byId("resizeTC").selectChild(dijit.byId("singleResizableInForm"))
+							dijit.byId("resizeTC").selectChild(dijit.byId("singleResizableInForm"));
 
 							doh.t(child._resized, "got resize event for child");
 							doh.is(1, child._resizeArgs && child._resizeArgs.length, "size specified")
@@ -385,7 +385,7 @@
 								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.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")
 						}
@@ -408,7 +408,7 @@
 								child2 = dijit.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.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")
 						}
diff --git a/dijit/tests/layout/LayoutContainer.html b/dijit/tests/layout/LayoutContainer.html
index fae7ff6..05493a4 100644
--- a/dijit/tests/layout/LayoutContainer.html
+++ b/dijit/tests/layout/LayoutContainer.html
@@ -63,7 +63,7 @@
 			);
 		}
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			doh.register("parse", function(){
 				dojo.parser.parse();
 			});
@@ -78,7 +78,6 @@
 					var left = dijit.byId("leftcp_layout1"),
 						top = dijit.byId("topcp_layout1"),
 						right = dijit.byId("rightcp_layout1"),
-						top = dijit.byId("topcp_layout1"),
 						center = dijit.byId("centercp_layout1"),
 						bottom = dijit.byId("bottomcp_layout1");
 
@@ -108,7 +107,6 @@
 					var left = dijit.byId("leftcp_layout2"),
 						top = dijit.byId("topcp_layout2"),
 						right = dijit.byId("rightcp_layout2"),
-						top = dijit.byId("topcp_layout2"),
 						centerLeft = dijit.byId("centerLeftcp_layout2"),
 						center = dijit.byId("centercp_layout2"),
 						centerRight = dijit.byId("centerRightcp_layout2"),
diff --git a/dijit/tests/layout/StackContainer.html b/dijit/tests/layout/StackContainer.html
new file mode 100644
index 0000000..71e4c69
--- /dev/null
+++ b/dijit/tests/layout/StackContainer.html
@@ -0,0 +1,373 @@
+<!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";
+		.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(){
+			// track resize events
+			dojo.connect(dijit.layout._LayoutWidget.prototype, "resize", function(){
+				resizes[this.id] = arguments;
+			});
+
+			function click(/*String*/ id){
+				// Click dijit widget w/specified id
+				dijit.byId(id)._onClick({preventDefault: function(){}});
+			}
+
+			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 [...]
+					}));
+					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 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 [...]
+					}));
+
+					// make the controller
+					var controller = new dijit.layout.StackController({containerId: "sc"}, "holder");
+
+					// start 'em up
+					controller.startup();
+					container.startup();
+				}
+			]);
+
+			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");
+				},
+				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");
+				},
+				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");
+				},
+				function clickTwice(){
+					click("dijit_layout_StackController_0_page1");
+					click("dijit_layout_StackController_0_page1");
+					var button = dijit.byId("dijit_layout_StackController_0_page1");
+					doh.t(button.checked, "Page 1 button is still checked");
+				}
+			]);
+
+			doh.register("nested layout widgets", [
+				function nestedLayout(){
+					click("nextPR");
+					var bcPos = dojo.position("bc"),
+						tcPos = dojo.position("tc");
+
+					doh.t("bc" in resizes, "BorderContainer got resize");
+					doh.is(300, 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.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.register("removeChild", function removeChild(){
+				var container = new dijit.layout.StackContainer({ id: "sc2" });
+				container.addChild(new dijit.layout.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({
+						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({
+						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.startup();
+				container.selectChild(page3);
+
+				var resizes = 0;
+				dojo.connect(page3, "resize", function(){
+					resizes++;
+				});
+				container.removeChild(page3);
+				doh.is(0, resizes, "removing selected child doesn't call resize on it");
+				doh.is(2, container.getChildren().length, "2 children");
+			});
+
+			doh.register("childless startup", function childlessStartup(){
+				// make and start the container without children
+				var container = new dijit.layout.StackContainer({ id: "nssc" },"noChildrenStackContainer");
+				container.startup();
+
+				// monitor _showChild() calls
+				var showChildCalls = {};
+				dojo.connect(container, "_showChild", function(child){
+					showChildCalls[child.id] = (showChildCalls[child.id] || 0) + 1;
+				});
+
+				// Create and add child
+				var child1 = new dijit.layout.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(){
+					resizes++;
+				});
+				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({
+					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."
+				}));
+				doh.f("ncsc2" in showChildCalls, "StackContainer._showChild(child2) not called when child added");
+				doh.is(1, showChildCalls["ncsc1"], "StackContainer._showChild(child1) not called when second child added");
+
+				// addChild() unfortunately triggers child1.resize() to be called, in anticipation that the new
+				// child may have caused the tab labels to overflow to 2 lines, thus reducing content size
+				// doh.is(1, resizes, "child1 not resized when child2 added");
+				var resizesBeforeContainerResize = resizes;	// in 1.7 this is 2, in 2.0 will hopefully be 1
+
+				// Resize the StackContainer.
+				container.resize();
+				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.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">
+	<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>
+
+	<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>
+
+	<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>
+
+
+	<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>
+
+	<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"'>
+			<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;"'>
+			<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'>
+					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
+					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.
+				</div>
+				<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
+					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.
+				</div>
+			</div>
+			<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"'>
+					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
+					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.
+				</div>
+				<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
+					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.
+				</div>
+			</div>
+			<p>
+				That's it!
+			</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>
+
+	<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">
+                    hello world
+                </div>
+            </div>
+        </div>
+    </div>
+
+
+	<h1>Programmatic test</h1>
+
+	Links: <span id="holder"></span>
+
+	<div id="myStackContainer2" style="width: 90%; border: 1px solid #9b9b9b; height: 20em; margin: 0.5em 0 0.5em 0; padding: 0.5em;">
+	</div>
+
+	<div id="noChildrenStackContainer" style="width: 90%; border: 1px solid #9b9b9b; height: 20em;"></div>
+</body>
+</html>
diff --git a/dijit/tests/layout/TabContainer.html b/dijit/tests/layout/TabContainer.html
index 943e7e8..9dfee31 100644
--- a/dijit/tests/layout/TabContainer.html
+++ b/dijit/tests/layout/TabContainer.html
@@ -29,7 +29,7 @@
 		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 
 		// create a do nothing, only for test widget
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 
 			doh.register("parse", function(){
 				dojo.parser.parse();
@@ -38,23 +38,77 @@
 			doh.register("creationAndDestruction", [
 
 				// Test that destroyRecursive removes all supporting widgets, including the list-of-tabs menu
-				// and the close menu
+				// and the close menu.  Also test that the second tab doesn't get selected
+				// for a split second as the TabContainer is being destroyed.
 				{
 					name: 'destroyRecursive',
 					runTest: function(t){
 						var num = dijit.registry.length;
 	
-						var tc = new dijit.layout.TabContainer({ id:"creationAndDestruction", useMenu:true }).placeAt(dojo.body());
-						tc.addChild(new dijit.layout.ContentPane({title: "test pane 1", closable: true}));
-						tc.addChild(new dijit.layout.ContentPane({title: "test pane 2"}));
+						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({
+								id:"creationAndDestruction",
+								useMenu:true
+							}).placeAt(dojo.body());
+
+						var cp2selected = false;
+						cp2.watch("selected", function(){
+							cp2selected = true;
+						});
+
+						tc.addChild(cp1);
+						tc.addChild(cp2);
 						tc.startup();
-	
+
 						tc.destroyRecursive();
 	
-						t.is(dijit.registry.length, num);
+						t.is(dijit.registry.length, num, "registry length");
+						t.f(cp2selected, "second pane wasn't temporarily selected");
 					}
 				},
 				
+				// Test that on destroyDescendants(), the second tab doesn't get selected
+				// for a split second as the TabContainer is being destroyed.
+				{
+					name: 'destroyDescendants',
+					runTest: function(t){
+						var cp1 = new dijit.layout.ContentPane({
+								id: "destroyDescendants_pane1",
+								title: "test pane 1",
+								closable: true
+							}),
+							cp2 = new dijit.layout.ContentPane({
+								id: "destroyDescendants_pane2",
+								title: "test pane 2",
+								href: "doc0.html"
+							}),
+							tc = new dijit.layout.TabContainer({
+								id:"destroyDescendants",
+								useMenu:true
+							}).placeAt(dojo.body());
+
+						var cp2selected = false;
+						cp2.watch("selected", function(){
+							cp2selected = true;
+						});
+						var downloadStarted = false;
+						dojo.connect(cp2, "onDownloadStart", function(){
+							downloadStarted = true;
+						});
+
+						tc.addChild(cp1);
+						tc.addChild(cp2);
+						tc.startup();
+
+						tc.destroyDescendants();
+
+						t.f(cp2selected, "second pane wasn't temporarily selected");
+						t.f(downloadStarted, "second pane never started downloading");
+						t.is(undefined, tc._selectedChildWidget, "no selected child widget");
+					}
+				},
+
 				// Check that tab labels for initial tabs are created
 				{
 					name: 'checkTabLabels',
@@ -203,8 +257,15 @@
 						var tc1 = dijit.byId("tc1");
 						var cp = dijit.byId("cpTitle");
 						
-						tc1.removeChild(cp);
+
+						// track resizes to cp, removing it from tc1 shouldn't cause a resize call
+						var cpResizes = 0;
+						dojo.connect(cp, "resize", function(){
+							cpResizes++;
+						});
 						
+						tc1.removeChild(cp);
+
 						var childPanes = tc1.getChildren();
 						
 						t.is(5, childPanes.length, "verify there are now only 4 tabs instead of 5");
@@ -212,6 +273,8 @@
 
 						var label = dojo.byId("#tc1_tablist_cpTitle");
 						t.f(label, "verify that deleted tab's label does not exist");
+
+						t.is(0, cpResizes, "no resize");
 					}
 				},
 				
@@ -463,6 +526,34 @@
 				}
 			]);			
 
+			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");
+					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 +
+							") < labelPos.x " + labelPos.x + " + labelPos.w + (" + labelPos.w + ")");
+				},
+				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"));
+					setTimeout(d.getTestCallback(function(){
+						var tcPos = dojo.position("scroll");
+							labelPos = dojo.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 +
+								") < labelPos.x " + labelPos.x + " + labelPos.w + (" + labelPos.w + ")");
+					}), 500);
+
+					return d;
+				}
+			]);
 			doh.run();
 
 		});
@@ -598,5 +689,17 @@
 		</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>
+
 </body>
 </html>
diff --git a/dijit/tests/layout/TabContainerTitlePane.html b/dijit/tests/layout/TabContainerTitlePane.html
index 48b256b..2cc6766 100644
--- a/dijit/tests/layout/TabContainerTitlePane.html
+++ b/dijit/tests/layout/TabContainerTitlePane.html
@@ -27,7 +27,7 @@
 
 		var resized = {};
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			dojo.connect(dijit.layout.TabContainer.prototype, "resize", function(){
 				resized[this.id] = true;
 			});
diff --git a/dijit/tests/layout/borderContainer.php b/dijit/tests/layout/borderContainer.php
index 25d8995..661af12 100644
--- a/dijit/tests/layout/borderContainer.php
+++ b/dijit/tests/layout/borderContainer.php
@@ -3,7 +3,7 @@
 
 	// If you call this file like borderContainer.php?id=foo then the id's of the created widgets
 	// will be based on the string "foo"
-	$id = $_GET['id'];
+	$id = htmlspecialchars($_GET['id']);
 
 	// sized=true means that it will add a width/height to the BorderContainer
 ?>
@@ -31,4 +31,4 @@
 			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>inner border container</div>
 		</div>
 	</div>
-</div>
\ No newline at end of file
+</div>
diff --git a/dijit/tests/layout/mobile.html b/dijit/tests/layout/mobile.html
new file mode 100644
index 0000000..de48775
--- /dev/null
+++ b/dijit/tests/layout/mobile.html
@@ -0,0 +1,142 @@
+<!DOCTYPE>
+<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 widgets mobile test page</title>
+		<link href="../../themes/claro/claro.css" rel="stylesheet"/>
+		<link href="../../icons/commonIcons.css" rel="stylesheet"/>
+		<link href="../css/dijitTests.css" rel="stylesheet"/>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			require([
+				"dojo/_base/kernel",
+				"dijit",
+				"dojo/parser",
+
+				"dijit/layout/ContentPane",
+				"dijit/layout/AccordionContainer",
+				"dijit/layout/BorderContainer",
+				"dijit/layout/TabContainer",
+				"dojo/domReady!"
+			], function(dojo, dijit){
+				dojo.parser.parse();
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<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,
+				title:"Pane 1", iconClass:"dijitEditorIcon dijitEditorIconSave", tooltip:"tooltip for simple pane" '>
+				<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>
+			</div>
+			<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.
+					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>
+		</div>
+
+
+		<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'>
+				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
+				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.
+			</div>
+			<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
+				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.
+			</div>
+		</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"'>
+				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
+				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.
+			</div>
+			<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
+				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.
+			</div>
+			<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>
+				Tab 4 contents
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 5"' closable=true>
+				Tab 5 contents
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dijit/tests/layout/module.js b/dijit/tests/layout/module.js
index 2f739b2..2fc2acc 100644
--- a/dijit/tests/layout/module.js
+++ b/dijit/tests/layout/module.js
@@ -10,8 +10,8 @@ try{
 
 	doh.registerUrl("dijit.tests.layout.LayoutContainer", dojo.moduleUrl("dijit", "tests/layout/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.registerUrl("dijit.tests.layout.robot.StackContainer_mouse", dojo.moduleUrl("dijit", "tests/layout/robot/StackContainer_mouse.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);
diff --git a/dijit/tests/layout/multipleLayoutWidgets.php b/dijit/tests/layout/multipleLayoutWidgets.php
index 890d30f..c899dd0 100644
--- a/dijit/tests/layout/multipleLayoutWidgets.php
+++ b/dijit/tests/layout/multipleLayoutWidgets.php
@@ -1,7 +1,7 @@
 <?php
 	// If you call this file like multipleLayoutWidgets.php?id=foo then the id's of the created widgets
 	// will be based on the string "foo"
-	$id = $_GET['id'];
+	$id = htmlspecialchars($_GET['id']);
 ?>
 This file has some nested layout widgets, and when this file is loaded the TabContainer and
 BorderContainer below should get resize() called on them
@@ -11,4 +11,4 @@ BorderContainer below should get resize() called on them
 </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>
\ No newline at end of file
+</div>
diff --git a/dijit/tests/layout/nestedStack.html b/dijit/tests/layout/nestedStack.html
index 24e733b..0f9f248 100644
--- a/dijit/tests/layout/nestedStack.html
+++ b/dijit/tests/layout/nestedStack.html
@@ -34,7 +34,7 @@
 			resizeCnt[widget.id] = (resizeCnt[widget.id] || 0) + 1;
 		}
 	
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			dojo.declare("dijit.TestLayoutContained",
 				dijit.layout._LayoutWidget, {
 					startup: function(){
diff --git a/dijit/tests/layout/robot/AccordionContainer_a11y.html b/dijit/tests/layout/robot/AccordionContainer_a11y.html
index bce55e8..4e626b2 100644
--- a/dijit/tests/layout/robot/AccordionContainer_a11y.html
+++ b/dijit/tests/layout/robot/AccordionContainer_a11y.html
@@ -18,7 +18,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_AccordionContainer.html');
 				doh.register("Accordion A11Y tests", [
 					{
@@ -33,14 +33,14 @@
 							// 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._curFocus)), "tabbed to first pane's title");
+								doh.t(/A Simple Pane/.test(innerText(dojo.global.dijit.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._curFocus)), "moved away from first pane's title");
-								doh.t(/Lazy Load Pane/.test(innerText(dojo.global.dijit._curFocus)), "moved to second pane's title");
+								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");
 							}), 500);
 
@@ -54,13 +54,13 @@
 							// 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._curFocus), "tabbed into second pane");
+								doh.is("WebA11y", innerText(dojo.global.dijit.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._curFocus.id, "tabbed out of accordion");
+								doh.is("afterMarkupAccordion", dojo.global.dijit.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 5fee52c..9a93c73 100644
--- a/dijit/tests/layout/robot/AccordionContainer_mouse.html
+++ b/dijit/tests/layout/robot/AccordionContainer_mouse.html
@@ -18,7 +18,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 			
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_AccordionContainer.html');
 				doh.register("Accordion Mouse tests",[
 					{
diff --git a/dijit/tests/layout/robot/BorderContainer.html b/dijit/tests/layout/robot/BorderContainer.html
index a20f2c1..1860e7a 100644
--- a/dijit/tests/layout/robot/BorderContainer.html
+++ b/dijit/tests/layout/robot/BorderContainer.html
@@ -19,7 +19,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_BorderContainer.html');
 
 				doh.register("mouse", [
@@ -110,26 +110,26 @@
 							// 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._curFocus), "tabbed to link");
+								doh.is("a link", innerText(dojo.global.dijit.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._curFocus.id, "focus on bottom splitter");
+								doh.is("border2-bottom_splitter", dojo.global.dijit.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._curFocus.id, "focus on bottom splitter");
+								doh.is("border2-trailing_splitter", dojo.global.dijit.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._curFocus), "tabbed to link in next BC");
+								doh.is("a link", innerText(dojo.global.dijit.focus.curNode), "tabbed to link in next BC");
 							}), 500);
 
 							return d;
diff --git a/dijit/tests/layout/robot/BorderContainer_complex.html b/dijit/tests/layout/robot/BorderContainer_complex.html
index 6e99b31..2132579 100644
--- a/dijit/tests/layout/robot/BorderContainer_complex.html
+++ b/dijit/tests/layout/robot/BorderContainer_complex.html
@@ -19,7 +19,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_BorderContainer_complex.html');
 
 				doh.register("API", [
@@ -51,7 +51,7 @@
 							doh.robot.mouseClick({left:true}, 500);
 							
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("mainTabContainer_tablist_tab1", dojo.global.dijit._curFocus.id, "current focus was not tab1");
+								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");
@@ -68,7 +68,7 @@
 							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("mainTabContainer_tablist_tab2", dojo.global.dijit._curFocus.id, "current focus was not tab2");
+								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");
@@ -85,7 +85,7 @@
 							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000, {});
 							
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("mainTabContainer_tablist_tab3", dojo.global.dijit._curFocus.id, "current focus was not tab3");
+								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");
@@ -102,7 +102,7 @@
 							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000, {});
 							
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("mainTabContainer_tablist_tab4", dojo.global.dijit._curFocus.id, "current focus was not tab4");
+								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");
@@ -119,7 +119,7 @@
 							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("mainTabContainer_tablist_tab5", dojo.global.dijit._curFocus.id, "current focus was not tab5");
+								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");
@@ -136,7 +136,7 @@
 							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("mainTabContainer_tablist_tab6", dojo.global.dijit._curFocus.id, "current focus was not tab6");
+								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");
@@ -174,7 +174,7 @@
 							// Connect to _hideChild() as a trick to tell when animation is finished
 							handle = dojo.connect(dijit.byId("ac1"), "_hideChild", function(){
 								setTimeout(d.getTestCallback(function(){
-									doh.is("ap2_button", dojo.global.dijit._curFocus.parentNode.id, "current focus was not ap2");
+									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");
@@ -198,7 +198,7 @@
 							// Connect to _hideChild() as a trick to tell when animation is finished
 							handle = dojo.connect(dijit.byId("ac1"), "_hideChild", function(){
 								setTimeout(d.getTestCallback(function(){
-									doh.is("ap3_button", dojo.global.dijit._curFocus.parentNode.id, "current focus was not ap3");
+									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");
@@ -221,29 +221,42 @@
 
 							var accordion = dojo.position(dojo.byId("ac1"));
 							var centerPane = dojo.position(dojo.byId("mainCP"));
+							var centerPaneRight = centerPane.x + centerPane.w;
+							var filteringSelectWidth = dojo.position(dijit.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", 500, 1);
+							doh.robot.mouseMoveAt("ac1_splitter", 0, 1);
 							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt("ac1_splitter", 500, 500, size.w/2+30, size.h/2);
-							doh.robot.mouseRelease({left: true}, 1000);
-							
-							doh.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+30);
-								
-								// test that the center content got smaller by the same size that the splitter moved
+							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"));
-								doh.is(newCenterPane.w, centerPane.w-30);
-							}), 1000);
+								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);
+								move += move2;
+							
+								doh.robot.mouseRelease({left: true}, 500);
+								doh.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);
+									
+									// test that the center content got smaller by the same size that the splitter moved
+									var newCenterPane = dojo.position(dojo.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);
+								}), 500);
+							}, 500);
 
 							return d;
 						}
 					}
 				]);
 				
+				var filteringSelect, handler;
 				doh.register("filteringSelect", [
 					{
 						name: "changeValue",
@@ -251,16 +264,21 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							dijit.byId("filteringSelect").connect(dijit.byId("filteringSelect"), "onChange", function(e){d.callback(true); });
+							filteringSelect = dijit.byId("filteringSelect");
+							handler = filteringSelect.connect(filteringSelect, "onChange", function(e){
+								d.callback(true);
+							});
 							
-							doh.robot.mouseMoveAt("filteringSelect", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
+							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, {});
 							
 							return d;
+						},
+						tearDown: function(t){
+							filteringSelect.disconnect(handler);
 						}
 					}
 				]); 
diff --git a/dijit/tests/layout/robot/BorderContainer_full.html b/dijit/tests/layout/robot/BorderContainer_full.html
index 3dff857..770851c 100644
--- a/dijit/tests/layout/robot/BorderContainer_full.html
+++ b/dijit/tests/layout/robot/BorderContainer_full.html
@@ -19,7 +19,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_BorderContainer_full.html');
 
 				doh.register("API", [
@@ -29,7 +29,7 @@
 						doh.t(bc.getChildren().length==5);
 					},
 					
-					function testFullScreen() {
+					function testFullScreen(){
 						var borderContainerPos = dojo.position(dojo.byId("main"));
 						var view = dojo.window.getBox();
 						doh.t( borderContainerPos.h-view.h < 3);
diff --git a/dijit/tests/layout/robot/BorderContainer_nested.html b/dijit/tests/layout/robot/BorderContainer_nested.html
index 5d47af6..a2779b3 100644
--- a/dijit/tests/layout/robot/BorderContainer_nested.html
+++ b/dijit/tests/layout/robot/BorderContainer_nested.html
@@ -33,7 +33,7 @@
 				checkAbove("second bottom bar above bottom bar", "bottom2", "bottom1");
 			}
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_BorderContainer_nested.html');
 
 				doh.register("initial layout", [
diff --git a/dijit/tests/layout/robot/GUI.html b/dijit/tests/layout/robot/GUI.html
index 40acb12..5b5efc8 100644
--- a/dijit/tests/layout/robot/GUI.html
+++ b/dijit/tests/layout/robot/GUI.html
@@ -19,7 +19,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Gui.html');
 
 				doh.register("API", [
diff --git a/dijit/tests/layout/robot/StackContainer_mouse.html b/dijit/tests/layout/robot/StackContainer_mouse.html
deleted file mode 100644
index 29b1a91..0000000
--- a/dijit/tests/layout/robot/StackContainer_mouse.html
+++ /dev/null
@@ -1,372 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<title>doh.robot StackContainer 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.addOnLoad(function(){
-				doh.robot.initRobot('../test_StackContainer.html');
-				
-				doh.register("test stackcontainer 1", [
-					{
-						name: "forward",
-						timeout: 3000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("next", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								isHidden(dojo.byId("page1"));
-								isVisible(dojo.byId("page2"));
-								isHidden(dojo.byId("page3"));
-							}), 500);
-
-							return d;
-						}
-					},
-					{
-						name: "forward2",
-						timeout: 3000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("next", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								isHidden(dojo.byId("page1"));
-								isHidden(dojo.byId("page2"));
-								isVisible(dojo.byId("page3"));
-							}), 500);
-
-							return d;
-						}
-					},
-					{
-						name: "forward3",
-						timeout: 4000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("next", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dijit.byId("next").disabled);
-								isHidden(dojo.byId("page1"));
-								isHidden(dojo.byId("page2"));
-								isVisible(dojo.byId("page3"));
-							}), 500);
-
-							return d;
-						}
-					},
-					{
-						name: "previous",
-						timeout: 3000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("previous", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								isHidden(dojo.byId("page1"));
-								isVisible(dojo.byId("page2"));
-								isHidden(dojo.byId("page3"));
-							}), 500);
-
-							return d;
-						}
-					},
-					{
-						name: "previous2",
-						timeout: 3000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("previous", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dijit.byId("previous").disabled);
-								isVisible(dojo.byId("page1"));
-								isHidden(dojo.byId("page2"));
-								isHidden(dojo.byId("page3"));
-							}), 500);
-
-							return d;
-						}
-					},
-					{
-						name: "page2",
-						timeout: 3000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("dijit_layout_StackController_0_page2", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								isHidden(dojo.byId("page1"));
-								isVisible(dojo.byId("page2"));
-								isHidden(dojo.byId("page3"));
-							}), 500);
-
-							return d;
-						}
-					},
-					{
-						name: "page3",
-						timeout: 3000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("dijit_layout_StackController_0_page3", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dijit.byId("next").disabled);
-								isHidden(dojo.byId("page1"));
-								isHidden(dojo.byId("page2"));
-								isVisible(dojo.byId("page3"));
-							}), 500);
-
-							return d;
-						}
-					},
-					{
-						name: "page1",
-						timeout: 3000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("dijit_layout_StackController_0_page1", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dijit.byId("previous").disabled);
-								isVisible(dojo.byId("page1"));
-								isHidden(dojo.byId("page2"));
-								isHidden(dojo.byId("page3"));
-							}), 500);
-
-							return d;
-						}
-					}
-				]);
-				
-				doh.register("test stackcontainer 2", [
-					{
-						name: "forward_sc2",
-						timeout: 3000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("nextPR", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								isHidden(dojo.byId("page1PR"));
-								isVisible(dojo.byId("page2PR"));
-								isVisible(dojo.byId("bc"));
-								isVisible(dojo.byId("tc"));
-							}), 500);
-
-							return d;
-						}
-					},
-					{
-						name: "forward2_sc2",
-						timeout: 3000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("nextPR", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								isVisible(dojo.byId("page1PR"));
-								isHidden(dojo.byId("page2PR"));
-								isHidden(dojo.byId("bc"));
-								isHidden(dojo.byId("tc"));
-							}), 500);
-
-							return d;
-						}
-					},
-					{
-						name: "forward3_sc2",
-						timeout: 3000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("nextPR", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								isHidden(dojo.byId("page1PR"));
-								isVisible(dojo.byId("page2PR"));
-								isVisible(dojo.byId("bc"));
-								isVisible(dojo.byId("tc"));
-							}), 500);
-
-							return d;
-						}
-					},
-					{
-						name: "previous_sc2",
-						timeout: 3000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("previousPR", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								isVisible(dojo.byId("page1PR"));
-								isHidden(dojo.byId("page2PR"));
-								isHidden(dojo.byId("bc"));
-								isHidden(dojo.byId("tc"));
-							}), 500);
-
-							return d;
-						}
-					},
-					{
-						name: "previous2_sc2",
-						timeout: 3000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("previousPR", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								isHidden(dojo.byId("page1PR"));
-								isVisible(dojo.byId("page2PR"));
-								isVisible(dojo.byId("bc"));
-								isVisible(dojo.byId("tc"));
-							}), 500);
-
-							return d;
-						}
-					},
-					{
-						name: "page1_sc2",
-						timeout: 3000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("dijit_layout_StackController_2_page1PR", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								isVisible(dojo.byId("page1PR"));
-								isHidden(dojo.byId("page2PR"));
-								isHidden(dojo.byId("bc"));
-								isHidden(dojo.byId("tc"));
-							}), 500);
-
-							return d;
-						}
-					},
-					{
-						name: "page2_sc2",
-						timeout: 3000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("dijit_layout_StackController_2_page2PR", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								isHidden(dojo.byId("page1PR"));
-								isVisible(dojo.byId("page2PR"));
-								isVisible(dojo.byId("bc"));
-								isVisible(dojo.byId("tc"));
-							}), 500);
-
-							return d;
-						}
-					}
-				]);
-
-				doh.register("test stackcontainer prog", [
-					{
-						name: "page2_sc_prog",
-						timeout: 3000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("holder_page1Prog", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								isHidden(dojo.byId("page1Prog"));
-								isVisible(dojo.byId("page2Prog"));
-								isHidden(dojo.byId("page3Prog"));
-							}), 500);
-
-							return d;
-						}
-					},
-					{
-						name: "page3_sc_prog",
-						timeout: 3000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("holder_page2Prog", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								isHidden(dojo.byId("page1Prog"));
-								isHidden(dojo.byId("page2Prog"));
-								isVisible(dojo.byId("page3Prog"));
-							}), 500);
-
-							return d;
-						}
-					},
-					{
-						name: "page1_sc_prog",
-						timeout: 3000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("holder_page3Prog", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								isVisible(dojo.byId("page1Prog"));
-								isHidden(dojo.byId("page2Prog"));
-								isHidden(dojo.byId("page3Prog"));
-							}), 500);
-
-							return d;
-						}
-					}
-				]);
-				
-				doh.run();
-			});
-		</script>
-	</head>
-</html>
diff --git a/dijit/tests/layout/robot/TabContainer_a11y.html b/dijit/tests/layout/robot/TabContainer_a11y.html
index e1365ca..f5ce433 100644
--- a/dijit/tests/layout/robot/TabContainer_a11y.html
+++ b/dijit/tests/layout/robot/TabContainer_a11y.html
@@ -18,7 +18,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_TabContainer.html');
 				doh.register("basic navigation",[
 					{
diff --git a/dijit/tests/layout/robot/TabContainer_mouse.html b/dijit/tests/layout/robot/TabContainer_mouse.html
index daa04e9..d65a113 100644
--- a/dijit/tests/layout/robot/TabContainer_mouse.html
+++ b/dijit/tests/layout/robot/TabContainer_mouse.html
@@ -18,7 +18,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_TabContainer.html');
 				doh.register("mouse tests",[
 					
@@ -55,7 +55,7 @@
 							
 							doh.robot.sequence(d.getTestCallback(function(){
 								// verify tab button is selected
-								doh.is('mainTabContainer_tablist_tab3', dojo.global.dijit._curFocus.id, "verify chosen tab is in its chosen state and focused");
+								doh.is('mainTabContainer_tablist_tab3', dojo.global.dijit.focus.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");
@@ -166,7 +166,7 @@
 	
 								var isTabVisible = (tablistLeft < tabLeft && tablistRight > tabRight);
 
-								doh.t(isTabVisible, "verify tab is in display area")
+								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");
diff --git a/dijit/tests/layout/robot/TabContainer_noLayout.html b/dijit/tests/layout/robot/TabContainer_noLayout.html
index 0c5c81f..83dfaf7 100644
--- a/dijit/tests/layout/robot/TabContainer_noLayout.html
+++ b/dijit/tests/layout/robot/TabContainer_noLayout.html
@@ -29,135 +29,171 @@
 				);
 			}
 
-			var oldPos;
+			var oldPos, tab, handler;
 			
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_TabContainer_noLayout.html');
 				doh.register("plain TabContainer",[
 					{
 						name: "tab1",
-						timeout: 3000,
+						timeout: 4000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt('plainTabContainer_tablist_tab1', 500);
-							doh.robot.mouseClick({left: true}, 500);
-							
-							doh.robot.sequence(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];
+							tab = dijit.byId('tab1');
+							handler = tab.connect(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];
 								
-								checkInside(h1, dijit.byId("plainTabContainer").domNode);
-								checkInside(p1, dijit.byId("plainTabContainer").domNode);
-								checkInside(div1, dijit.byId("plainTabContainer").domNode);
+									checkInside(h1, dijit.byId("plainTabContainer").domNode);
+									checkInside(p1, dijit.byId("plainTabContainer").domNode);
+									checkInside(div1, dijit.byId("plainTabContainer").domNode);
 								
-								oldPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
-							}), 500);
+									oldPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
+								}), 500);
+							});
+							
+							doh.robot.mouseMoveAt('plainTabContainer_tablist_tab1', 0, 1);
+							doh.robot.mouseClick({left: true}, 500);
 							
 							return d;
+						},
+						tearDown: function(t){
+							tab.disconnect(handler);
 						}
 					},
 					{
 						name: "tab2",
-						timeout: 3000,
+						timeout: 4000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt('plainTabContainer_tablist_tab2', 500);
-							doh.robot.mouseClick({left: true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								var h2 = dojo.query('h1', dojo.byId('tab2'))[0];
-								var p2 = dojo.query('p', dojo.byId('tab2'))[0];
+							tab = dijit.byId('tab2');
+							handler = tab.connect(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];
 								
-								checkInside(h2, dijit.byId("plainTabContainer").domNode);
-								checkInside(p2, dijit.byId("plainTabContainer").domNode);
+									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;
-							}), 500);
+									var newPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
+									doh.f(oldPos.y == newPos.y);
+									oldPos = newPos;
+								}), 1000);
+							});
+							
+							doh.robot.mouseMoveAt('plainTabContainer_tablist_tab2', 0, 1);
+							doh.robot.mouseClick({left: true}, 500);
 							
 							return d;
+						},
+						tearDown: function(t){
+							tab.disconnect(handler);
 						}
 					},
 					{
 						name: "tab3",
-						timeout: 3000,
+						timeout: 4000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt('plainTabContainer_tablist_tab3', 500);
-							doh.robot.mouseClick({left: true}, 500);
-							
-							doh.robot.sequence(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);
+							tab = dijit.byId('tab3');
+							handler = tab.connect(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);
 								
-								var newPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
-								doh.f(oldPos.y == newPos.y);
-								oldPos = newPos;
-							}), 500);
+									var newPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
+									doh.f(oldPos.y == newPos.y);
+									oldPos = newPos;
+								}), 1000);
+							});
+							
+							doh.robot.mouseMoveAt('plainTabContainer_tablist_tab3', 0, 1);
+							doh.robot.mouseClick({left: true}, 500);
 							
 							return d;
+						},
+						tearDown: function(t){
+							tab.disconnect(handler);
 						}
 					},
 					{
 						name: "tab4_innerTab1",
-						timeout: 4000,
+						timeout: 6000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt('plainTabContainer_tablist_tab4', 500);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.mouseMoveAt('tab4_tablist_dijit_layout_LinkPane_0', 1000);
-							doh.robot.mouseClick({left: true}, 500);
-							
-							doh.robot.sequence(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];
+							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(){
+										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];
 								
-								checkInside(h1, dijit.byId("plainTabContainer").domNode);
-								checkInside(p1, dijit.byId("plainTabContainer").domNode);
-								checkInside(div1, dijit.byId("plainTabContainer").domNode);
+											checkInside(h1, dijit.byId("plainTabContainer").domNode);
+											checkInside(p1, dijit.byId("plainTabContainer").domNode);
+											checkInside(div1, dijit.byId("plainTabContainer").domNode);
 								
-								var newPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
-								doh.f(oldPos.y == newPos.y);
-								oldPos = newPos;
-							}), 500);
+											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_0', 0, 1);
+									doh.robot.mouseClick({left: true}, 500);
+								}, 1000);
+							});
+
+							doh.robot.mouseMoveAt('plainTabContainer_tablist_tab4', 0, 1);
+							doh.robot.mouseClick({left: true}, 500);
 							
 							return d;
+						},
+						tearDown: function(t){
+							tab.disconnect(handler);
 						}
 					},
 					{
 						name: "tab4_innerTab2",
-						timeout: 3000,
+						timeout: 4000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt('tab4_tablist_dijit_layout_LinkPane_1', 500);
-							doh.robot.mouseClick({left: true}, 1000);
-							
-							doh.robot.sequence(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];
+							tab = dijit.byId('dijit_layout_LinkPane_1');
+							handler = tab.connect(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];
 
-								checkInside(h2, dijit.byId("plainTabContainer").domNode);
-								checkInside(p2, dijit.byId("plainTabContainer").domNode);
+									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;
-							}), 500);
+									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);
 						}
 					},
 					{
@@ -166,83 +202,101 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt('plainTabContainer_tablist_tab5', 500);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.mouseMoveAt('dijit_layout_TabContainer_0_tablist_dijit_layout_ContentPane_0', 3500);
+							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);
 							
-							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);
-							
 							return d;
+						},
+						tearDown: function(t){
+							tab.disconnect(handler);
 						}
 					},
 					{
 						name: "tab5_innerTab2",
-						timeout: 3000,
+						timeout: 4000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt('dijit_layout_TabContainer_0_tablist_dijit_layout_ContentPane_1', 500);
-							doh.robot.mouseClick({left: true}, 500);
-							
-							doh.robot.sequence(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);
+							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);
 								
-								var newPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
-								doh.f(oldPos.y == newPos.y);
-								oldPos = newPos;
-							}), 500);
+									var newPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
+									doh.f(oldPos.y == 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);
 							
 							return d;
+						},
+						tearDown: function(t){
+							tab.disconnect(handler);
 						}
 					},
 					{
 						name: "addTab",
-						timeout: 6000,
+						timeout: 8000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt('addTab', 500);
+							tab = dijit.byId('plainTabContainer');
+							handler = tab.connect(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");
+										doh.is("Contents of Tab 6", newTab.innerHTML);
+										checkInside(newTab, dijit.byId("plainTabContainer").domNode);
+
+										var newPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
+										doh.f(oldPos.y == newPos.y);
+									}), 1000);
+								}, 1000)
+							});
+							doh.robot.mouseMoveAt('addTab', 0, 1);
 							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.mouseMoveAt('plainTabContainer_tablist_newTab6', 3000);
-							doh.robot.mouseClick({left: true}, 1000);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								var newTab = dojo.byId("newTab6");
-								doh.is("Contents of Tab 6", newTab.innerHTML);
-								checkInside(newTab, dijit.byId("plainTabContainer").domNode);
-								
-								var newPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
-								doh.f(oldPos.y == newPos.y);
-							}), 500);
 							
 							return d;
+						},
+						tearDown: function(t){
+							tab.disconnect(handler);
 						}
 					},
 					{
-						timeout: 3000,
+						timeout: 4000,
 						name: "destroy",
 						runTest: function(){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt('destroyTabContainer', 500);
+							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');
-							}), 1000);
+							}), 2000);
 							return d;
 						}
 					}
@@ -255,175 +309,223 @@
 					},
 					{
 						name: "tab1_t2",
-						timeout: 3000,
+						timeout: 4000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt('tableTabContainer_tablist_atab1', 500);
-							doh.robot.mouseClick({left: true}, 500);
-							
-							doh.robot.sequence(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];
+							tab = dijit.byId('atab1');
+							handler = tab.connect(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);
+									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);
-							}), 500);
+									oldPos = dojo.position(dojo.byId("textAfterTabContainer2"), true);
+								}), 500);
+							});
+							
+							doh.robot.mouseMoveAt('tableTabContainer_tablist_atab1', 0, 1);
+							doh.robot.mouseClick({left: true}, 500);
 							
 							return d;
+						},
+						tearDown: function(t){
+							tab.disconnect(handler);
 						}
 					},
 					{
 						name: "tab2_t2",
-						timeout: 3000,
+						timeout: 4000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt('tableTabContainer_tablist_atab2', 500);
-							doh.robot.mouseClick({left: true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								var h2 = dojo.query('h1', dojo.byId('atab2'))[0];
-								var p2 = dojo.query('p', dojo.byId('atab2'))[0];
+							tab = dijit.byId('atab2');
+							handler = tab.connect(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);
+									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);
-								oldPos = newPos;
-							}), 500);
+									var newPos = dojo.position(dojo.byId("textAfterTabContainer2"), true);
+									doh.f(oldPos.y == newPos.y);
+									oldPos = newPos;
+								}), 1000);
+							});
+							
+							doh.robot.mouseMoveAt('tableTabContainer_tablist_atab2', 0, 1);
+							doh.robot.mouseClick({left: true}, 500);
 							
 							return d;
+						},
+						tearDown: function(t){
+							tab.disconnect(handler);
 						}
 					},
 					{
 						name: "tab3_t2",
-						timeout: 3000,
+						timeout: 4000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt('tableTabContainer_tablist_atab3', 500);
-							doh.robot.mouseClick({left: true}, 500);
-							
-							doh.robot.sequence(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);
+							tab = dijit.byId('atab3');
+							handler = tab.connect(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);
-								oldPos = newPos;
-							}), 500);
+									var newPos = dojo.position(dojo.byId("textAfterTabContainer2"), true);
+									doh.f(oldPos.y == newPos.y);
+									oldPos = newPos;
+								}), 1000);
+							});
+							
+							doh.robot.mouseMoveAt('tableTabContainer_tablist_atab3', 0, 1);
+							doh.robot.mouseClick({left: true}, 500);
 							
 							return d;
+						},
+						tearDown: function(t){
+							tab.disconnect(handler);
 						}
 					},
 					{
 						name: "tab4_innerTab1_t2",
-						timeout: 5000,
+						timeout: 6000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt('tableTabContainer_tablist_atab4', 500);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.mouseMoveAt('atab4_tablist_dijit_layout_LinkPane_2', 2000);
-							doh.robot.mouseClick({left: true}, 500);
-							
-							doh.robot.sequence(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];
+							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(){
+										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);
+											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);
-								oldPos = newPos;
-							}), 500);
+											var newPos = dojo.position(dojo.byId("textAfterTabContainer2"), true);
+											doh.f(oldPos.y == newPos.y);
+											oldPos = newPos;
+										}), 1000);
+									});
+									doh.robot.mouseMoveAt('atab4_tablist_dijit_layout_LinkPane_2', 0, 1);
+									doh.robot.mouseClick({left: true}, 500);
+								}, 1000);
+							});
+
+							doh.robot.mouseMoveAt('tableTabContainer_tablist_atab4', 0, 1);
+							doh.robot.mouseClick({left: true}, 500);
 							
 							return d;
+						},
+						tearDown: function(t){
+							tab.disconnect(handler);
 						}
 					},
 					{
 						name: "tab4_innerTab2_t2",
-						timeout: 3000,
+						timeout: 4000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt('atab4_tablist_dijit_layout_LinkPane_3', 500);
-							doh.robot.mouseClick({left: true}, 1000);
-							
-							doh.robot.sequence(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];
+							tab = dijit.byId('dijit_layout_LinkPane_3');
+							handler = tab.connect(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];
 
-								checkInside(h2, dijit.byId("tableTabContainer").domNode);
-								checkInside(p2, dijit.byId("tableTabContainer").domNode);
+									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);
-								oldPos = newPos;
-							}), 500);
+									var newPos = dojo.position(dojo.byId("textAfterTabContainer2"), true);
+									doh.f(oldPos.y == newPos.y);
+									oldPos = newPos;
+								}), 1000);
+							});
+							
+							doh.robot.mouseMoveAt('atab4_tablist_dijit_layout_LinkPane_3', 0, 1);
+							doh.robot.mouseClick({left: true}, 500);
 							
 							return d;
+						},
+						tearDown: function(t){
+							tab.disconnect(handler);
 						}
 					},
 					{
 						name: "tab5_innerTab1_t2",
-						timeout: 6000,
+						timeout: 7000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt('tableTabContainer_tablist_atab5', 500);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.mouseMoveAt('dijit_layout_TabContainer_1_tablist_dijit_layout_ContentPane_2', 3500);
+							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);
+									oldPos = newPos;
+								}), 1000);
+							});
+							doh.robot.mouseMoveAt('tableTabContainer_tablist_atab5', 0, 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);
-								oldPos = newPos;
-							}), 500);
-							
 							return d;
+						},
+						tearDown: function(t){
+							tab.disconnect(handler);
 						}
 					},
 					{
 						name: "tab5_innerTab2_t2",
-						timeout: 3000,
+						timeout: 4000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt('dijit_layout_TabContainer_1_tablist_dijit_layout_ContentPane_3', 500);
-							doh.robot.mouseClick({left: true}, 500);
-							
-							doh.robot.sequence(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);
+							tab = dijit.byId('dijit_layout_ContentPane_3');
+							handler = tab.connect(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);
-							}), 500);
+									var newPos = dojo.position(dojo.byId("textAfterTabContainer2"), true);
+									doh.f(oldPos.y == 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);
 							
 							return d;
+						},
+						tearDown: function(t){
+							tab.disconnect(handler);
 						}
 					}
 				]);
diff --git a/dijit/tests/layout/test_AccordionContainer.html b/dijit/tests/layout/test_AccordionContainer.html
index 9f94e99..f2fbb42 100644
--- a/dijit/tests/layout/test_AccordionContainer.html
+++ b/dijit/tests/layout/test_AccordionContainer.html
@@ -30,13 +30,14 @@
 	<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.addOnLoad(function(){
+		dojo.ready(function(){
 			dojo.subscribe("focusNode", function(node){ console.log("focused on " + (node?(node.id||node.tagName):"nothing"));});
 		});
 		
@@ -280,8 +281,8 @@
 				ut eros sit amet ante pharetra interdum.
 			</p>
 		</div>
-		<div data-dojo-type="dijit.layout.AccordionPane" data-dojo-props='"class":"extremePadding", title:"Extreme Padding"'>
-			<p>(Leaving one to test deprecation)</p>
+		<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>
 			<p>
 				Nunc consequat nisi vitae quam. Suspendisse sed nunc. Proin
 				suscipit porta magna. Duis accumsan nunc in velit. Nam et nibh.
diff --git a/dijit/tests/layout/test_BorderContainer.html b/dijit/tests/layout/test_BorderContainer.html
index 6ef574e..45a7678 100644
--- a/dijit/tests/layout/test_BorderContainer.html
+++ b/dijit/tests/layout/test_BorderContainer.html
@@ -19,7 +19,7 @@
 		#mondrian .dijitSplitterActive { background-color: blue }
 		.dj_webkit #mondrian .dijitSplitter:focus {
 			/* override orange focus border w/something easier to see (response to a11y bug report) */
-			outline: auto 5px blue;
+			outline: 5px blue;
 		}
 		#mondrian SPAN { display: none }
 		#mondrian:hover SPAN { display: inline }
@@ -60,16 +60,16 @@
 			}
 		}
 
-		function watchSplitters(bc) {
+		function watchSplitters(bc){
 			var out = dojo.byId("watchedOutput");
 			var moveConnects = {};
-			dojo.forEach(["top", "left"], function(region) {
+			dojo.forEach(["top", "left"], function(region){
 				var spl = bc.getSplitter(region);
 
-				dojo.connect(spl, "_startDrag", function() {
+				dojo.connect(spl, "_startDrag", function(){
 
 					dojo.style(spl.child.domNode, "opacity", "0.4");
-					moveConnects[spl.widgetId] = dojo.connect(spl.domNode, "onmousemove", function(evt) {
+					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,
@@ -78,7 +78,7 @@
 					})
 
 				});
-				dojo.connect(spl, "_stopDrag", function(evt) {
+				dojo.connect(spl, "_stopDrag", function(evt){
 					dojo.style(spl.child.domNode, "opacity", 1);
 					dojo.disconnect(moveConnects[spl.widgetId]);
 					delete moveConnects[spl.widgetId];
@@ -87,7 +87,7 @@
 		}
 
 		var bc, cp1, cp2, cp3;
-        dojo.addOnLoad(function(){
+        dojo.ready(function(){
 			watchSplitters( dijit.byId("watchedBC") );
 				
 			bc = new dijit.layout.BorderContainer({style:'height:400px;width:500px;border:1px solid black'}, dojo.byId('main'));
diff --git a/dijit/tests/layout/test_BorderContainer_experimental.html b/dijit/tests/layout/test_BorderContainer_experimental.html
index b51de94..1422707 100644
--- a/dijit/tests/layout/test_BorderContainer_experimental.html
+++ b/dijit/tests/layout/test_BorderContainer_experimental.html
@@ -41,7 +41,7 @@
 
 			var open = false;
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				dojo.declare("my.BorderContainer",dijit.layout.BorderContainer,{
 	
 					opts: {
diff --git a/dijit/tests/layout/test_ContentPane.html b/dijit/tests/layout/test_ContentPane.html
index a8140d5..76298e1 100644
--- a/dijit/tests/layout/test_ContentPane.html
+++ b/dijit/tests/layout/test_ContentPane.html
@@ -30,19 +30,22 @@
 
 	<script type="text/javascript">
 		dojo.require('doh.runner');
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.Dialog");
+
+		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 		dojo.require("dojo.data.ItemFileReadStore");
-		dojo.require("dijit.form.ComboBox");
+
+		dojo.require("dijit._Widget");
+		dojo.require("dijit._TemplatedMixin");
+		dojo.require("dijit.Dialog");
 		dojo.require("dijit.InlineEditBox");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		dojo.require("dijit.form.ComboBox");
+		dojo.require("dijit.layout.ContentPane");
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 
 			// create a do nothing, only for test widget
 			dojo.declare("dijit.TestWidget",
-				[dijit._Widget, dijit._Templated], {
+				[dijit._Widget, dijit._TemplatedMixin], {
 				templateString: "<span class='dojoxTestWidget'></span>"
 			});
 
@@ -105,7 +108,7 @@
 			},
 			{
 				name: 'reuse',
-				runTest: function(t) {
+				runTest: function(t){
 					console.log("basicChecks: " + this.name);
 					// do the same thing over again - we should be error free
 					dialogCtrPane.set(
@@ -123,7 +126,7 @@
 			},
 			{
 				name: 'destroy',
-				runTest: function(t) {
+				runTest: function(t){
 					console.log("basicChecks: " + this.name);
 
 					// manually stick a widget into the ContentPane
diff --git a/dijit/tests/layout/test_Gui.html b/dijit/tests/layout/test_Gui.html
index 175215c..0014ba4 100644
--- a/dijit/tests/layout/test_Gui.html
+++ b/dijit/tests/layout/test_Gui.html
@@ -12,8 +12,8 @@
 		html, body {
 			height: 100%;
 			width: 100%;
-			padding: 0px;
-			margin: 0px;
+			padding: 0;
+			margin: 0;
 			border: 0;
 			background: #fff;
 		}
@@ -22,7 +22,7 @@
 			height: 100%;
 			width: 100%;
 			padding: 5px;
-			margin: 0px;
+			margin: 0;
 		}
 
 		/* initial sizing */
diff --git a/dijit/tests/layout/test_SplitContainer.html b/dijit/tests/layout/test_SplitContainer.html
index 2070780..5ac84a3 100644
--- a/dijit/tests/layout/test_SplitContainer.html
+++ b/dijit/tests/layout/test_SplitContainer.html
@@ -60,7 +60,7 @@
 			},rootNode).startup();
 
 		};
-		dojo.addOnLoad(programaticExample);
+		dojo.ready(programaticExample);
 
 	</script>
 </head>
diff --git a/dijit/tests/layout/test_StackContainer.html b/dijit/tests/layout/test_StackContainer.html
deleted file mode 100644
index 87b4e5b..0000000
--- a/dijit/tests/layout/test_StackContainer.html
+++ /dev/null
@@ -1,200 +0,0 @@
-<!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";
-		.dijitStackController .dijitToggleButtonChecked button {
-			background-color: white;
-			background-image: none;
-		}
-		.dijit_a11y .dijitStackController .dijitToggleButtonChecked button {
-			border-style: dashed !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>
-
-	<!-- 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.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.addOnLoad(function(){
-			// make the container
-			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,  [...]
-			}));
-			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 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 years [...]
-			}));
-
-			// make the controller
-			var controller = new dijit.layout.StackController({containerId: "sc"}, "holder");
-
-			// start 'em up
- 			controller.startup();
- 			container.startup();
-		});
-		
-		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">
-	<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>
-
-	<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>
-
-	<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>
-
-
-	<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>
-
-	<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"'>
-			<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;"'>
-			<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'>
-					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
-					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.
-				</div>
-				<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
-					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.
-				</div>
-			</div>
-			<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"'>
-					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
-					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.
-				</div>
-				<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
-					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.
-				</div>
-			</div>
-			<p>
-				That's it!
-			</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>
-
-	<h1>Programmatic test</h1>
-
-	Links: <span id="holder"></span>
-
-	<div id="myStackContainer2" style="width: 90%; border: 1px solid #9b9b9b; height: 20em; margin: 0.5em 0 0.5em 0; padding: 0.5em;">
-	</div>
-</body>
-</html>
diff --git a/dijit/tests/layout/test_TabContainer.html b/dijit/tests/layout/test_TabContainer.html
index 851d48b..e6c771e 100644
--- a/dijit/tests/layout/test_TabContainer.html
+++ b/dijit/tests/layout/test_TabContainer.html
@@ -46,7 +46,7 @@
 		}
 
 		startTime = new Date();
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			var elapsed = new Date().getTime() - startTime;
 			var p = document.createElement("p");
 			p.appendChild(document.createTextNode("Widgets loaded in " + elapsed + "ms"));
diff --git a/dijit/tests/mobile.html b/dijit/tests/mobile.html
new file mode 100644
index 0000000..5d1cc47
--- /dev/null
+++ b/dijit/tests/mobile.html
@@ -0,0 +1,183 @@
+<!DOCTYPE>
+<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>General widgets mobile test page</title>
+		<link href="../themes/claro/claro.css" rel="stylesheet"/>
+		<link href="../icons/commonIcons.css" rel="stylesheet"/>
+		<script type="text/javascript" src="../../dojo/dojo.js" data-dojo-config="async: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			require([
+				"dojo/_base/kernel",
+				"dojo/_base/json",
+				"dijit",
+				"dojo/parser",
+
+				"dijit/MenuBar",
+				"dijit/PopupMenuBarItem",
+				"dijit/DropDownMenu",
+				"dijit/MenuItem",
+				"dijit/MenuSeparator",
+				"dijit/PopupMenuItem",
+				"dijit/Menu",
+
+				"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",
+				"dijit/InlineEditBox",
+				"dijit/TitlePane",
+
+				"dijit/Tree",
+				"dojo/data/ItemFileReadStore",
+				"dijit/tree/ForestStoreModel",
+				"dojo/domReady!"
+			], function(dojo, dijit){
+				dojo.parser.parse();
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<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>
+			</div>
+			<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",
+						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>
+			</div>
+			<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">
+						<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>
+					</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'>
+				<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)); }'>
+					<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>
+						</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>
+						</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>
+						</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
+			><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",
+						onClick:function(){ console.log("not actually saving anything, just a test!") }'>Save</div>
+					<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();"
+				 data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCreateLink"'>Dialog</div>
+		</div>
+
+		<div 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)); }'>
+			<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>
+			</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(); }
+						'>Cancel</button>
+			</div>
+		</div>
+
+		<br>
+		<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>
+				<button>Submit</button><br>
+			</form>
+		</div>
+
+		<br>
+		<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"},
+			rootId:"continentRoot", rootLabel:"Continents", childrenAttrs:["children"]'></div>
+
+		<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>
+
+	</body>
+</html>
diff --git a/dijit/tests/module.js b/dijit/tests/module.js
index f370ce5..0a99dc2 100644
--- a/dijit/tests/module.js
+++ b/dijit/tests/module.js
@@ -9,6 +9,8 @@ try{
 	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);
 }
diff --git a/dijit/tests/robot/BgIframe.html b/dijit/tests/robot/BgIframe.html
index 8c01f9b..105d1d6 100644
--- a/dijit/tests/robot/BgIframe.html
+++ b/dijit/tests/robot/BgIframe.html
@@ -9,15 +9,14 @@
 		</style>
 
 		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../dojo/dojo.js"
-			data-dojo-config="parseOnLoad: true, isDebug: true"></script>
+		<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.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_bgIframe.html');
 	
 				dojo.forEach(["applet", "xapp"], function(xId){
diff --git a/dijit/tests/robot/Calendar_a11y.html b/dijit/tests/robot/Calendar_a11y.html
index 0088665..15e9a61 100644
--- a/dijit/tests/robot/Calendar_a11y.html
+++ b/dijit/tests/robot/Calendar_a11y.html
@@ -16,10 +16,12 @@
 		<script type="text/javascript" src="../helpers.js"></script>
 
 		<script type="text/javascript">
+			dojo.require("doh.runner");
 			dojo.require("dijit.robotx");
 			dojo.require("dojo.date");
+			dojo.require("dojo.date.locale");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Calendar.html');
 
 				// refs to Calendar widget
@@ -28,14 +30,80 @@
 				// log of calls to onChange handler
 				var changes = [];
 
+				doh.register("API",[
+					function noValue(){
+						// refs to Calendar widget
+						cal1 = dijit.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');
+
+						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');
+
+						cal1.set("value", null);
+						doh.is(null, cal1.get("value"), 'get("value") after set to null');
+					}
+				]);
+				
+				// 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){
+						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){
+						if(c.isDisabledDate){
+							c.isDisabledDate = dojo.date.locale.isWeekend;
+							c._populateGrid();
+						}
+					});
+					
+					//select a day
+					dijit.byId("calendar1").set("value",  new Date(2009, 8, 15));
+					
+					dojo.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));
+						(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){
+						if(c.isDisabledDate){
+							c.isDisabledDate = function(){return false;};
+							c._populateGrid();
+						}
+					});
+					
+					//select a different day
+					dijit.byId("calendar1").set("value",  new Date(2009, 8, 17));
+					
+					dojo.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));
+						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",[
 					{
 						name: "forward",
 						timeout: 10000,
 						setUp: function(){
-							// refs to Calendar widget
-						    	cal1 = dijit.byId('calendar1');
 							cal1.set("value", new Date(2009, 8, 16));
 
 							dojo.byId("before").focus();
@@ -46,20 +114,20 @@
 							// 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._curFocus), "first tab goes to selected day");
+								doh.is(16, innerText(dojo.global.dijit.focus.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._curFocus), "move around some");
+								doh.is(24, innerText(dojo.global.dijit.focus.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._curFocus.id, "next tab leaves calendar");
+								doh.is("after", dojo.global.dijit.focus.curNode.id, "next tab leaves calendar");
 							})), 500);
 
 							return d;
@@ -74,13 +142,13 @@
 							// 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._curFocus), "shift-tab returns to previously focused day");
+								doh.is(24, innerText(dojo.global.dijit.focus.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._curFocus.id, "next shift-tab leaves calendar");
+								doh.is("before", dojo.global.dijit.focus.curNode.id, "next shift-tab leaves calendar");
 							})), 500);
 
 							return d;
@@ -95,19 +163,19 @@
 							// 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._curFocus), "first tab goes to selected day");
+								doh.is(24, innerText(dojo.global.dijit.focus.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._curFocus), "moved to same day, but new month");
+								doh.is(24, innerText(dojo.global.dijit.focus.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._curFocus.id, "next tab leaves calendar");
+								doh.is("after", dojo.global.dijit.focus.curNode.id, "next tab leaves calendar");
 							})), 500);
 
 							return d;
@@ -122,13 +190,13 @@
 							// 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._curFocus), "shift-tab returns to previously focused day");
+								doh.is(24, innerText(dojo.global.dijit.focus.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._curFocus.id, "next shift-tab leaves calendar");
+								doh.is("before", dojo.global.dijit.focus.curNode.id, "next shift-tab leaves calendar");
 							})), 500);
 
 							return d;
@@ -169,7 +237,7 @@
 								doh.is("16", innerText(selected[0]));
 
 								// initial focus is on selected value
-								doh.is("16", innerText(dojo.global.dijit._curFocus));
+								doh.is("16", innerText(dojo.global.dijit.focus.curNode));
 
 								// and get("value") working
 								doh.is(0, dojo.date.compare(new Date(2009, 8, 16), cal1.get('value')), 'get("value")');
@@ -179,7 +247,7 @@
 							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
 							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
 								// focus moved from 16 to 17
-								doh.is(17, innerText(dojo.global.dijit._curFocus));
+								doh.is(17, innerText(dojo.global.dijit.focus.curNode));
 
 								doh.is(0, dojo.date.compare(new Date(2009, 8, 16), cal1.get('value')), 'value unchanged');
 								
@@ -190,23 +258,23 @@
 							})), 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._curFocus));
+								doh.is(18, innerText(dojo.global.dijit.focus.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._curFocus));
+								doh.is(25, innerText(dojo.global.dijit.focus.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._curFocus));
+								doh.is(24, innerText(dojo.global.dijit.focus.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._curFocus));
+								doh.is(17, innerText(dojo.global.dijit.focus.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._curFocus));
+								doh.is(10, innerText(dojo.global.dijit.focus.curNode));
 							})), 500);
 							doh.robot.keyPress(dojo.keys.ENTER, 0, {});
 
@@ -239,7 +307,7 @@
 							doh.robot.keyPress(dojo.keys.PAGE_DOWN, 1000, {});
 							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
 								// focus moved from jan 31 to feb 29
-								doh.is(29, innerText(dojo.global.dijit._curFocus));
+								doh.is(29, innerText(dojo.global.dijit.focus.curNode));
 
 								doh.is(0, dojo.date.compare(new Date(2008, 0, 31), cal1.get('value')), 'value unchanged (first page down)');
 
@@ -256,7 +324,7 @@
 							doh.robot.keyPress(dojo.keys.PAGE_DOWN, 500, {});
 							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
 								// focus moved from jan 31 to feb 29
-								doh.is(29, innerText(dojo.global.dijit._curFocus));
+								doh.is(29, innerText(dojo.global.dijit.focus.curNode));
 
 								doh.is(0, dojo.date.compare(new Date(2008, 0, 31), cal1.get('value')), 'value unchanged (second page down)');
 								
@@ -265,7 +333,7 @@
 								doh.is(0, selected.length, "no selected node");
 							})), 500);
 
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
 								var value = cal1.get('value');
 								doh.is(0, dojo.date.compare(new Date(2008, 2, 29), value), 'actual value is ' + value);
diff --git a/dijit/tests/robot/ColorPalette.html b/dijit/tests/robot/ColorPalette.html
index d5f8a1c..465892e 100644
--- a/dijit/tests/robot/ColorPalette.html
+++ b/dijit/tests/robot/ColorPalette.html
@@ -15,7 +15,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_ColorPalette.html');
 
 				var big, small, prog;
@@ -60,9 +60,9 @@
 								doh.is(0, changes.length, "no onchange events yet");
 								
 								// test that focus is on top left cell
-								var focus = dojo.global.dijit._curFocus;
+								var focus = dojo.global.dijit.focus.curNode;
 								doh.t(focus, "something is focused");
-								var imgNode = focus.getElementsByTagName("img")[0]
+								var imgNode = focus.getElementsByTagName("img")[0];
 								doh.t(imgNode, "found image node");
                                 //
                                 var dye = big._getDye(focus);                                
@@ -88,10 +88,10 @@
 							
 							// 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._curFocus;
+								var focus = dojo.global.dijit.focus.curNode;
 								doh.t(focus, "something is focused");
 								
-								var imgNode = focus.getElementsByTagName("img")[0]
+								var imgNode = focus.getElementsByTagName("img")[0];
 								doh.t(imgNode, "found image node");
                                 //
                                 var dye = big._getDye(focus);
@@ -139,22 +139,22 @@
 							dojo.byId("beforeBig").focus();
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("pink", dojo.global.dijit._curFocus.title, "tab into colorpalette, focus goes to pink (last focused cell)")
+								doh.is("pink", dojo.global.dijit.focus.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._curFocus.id, "another tab, went to input after ColorPalette")
+								doh.is("afterBig", dojo.global.dijit.focus.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._curFocus.title, "shift-tab back into colorpalette")
+								doh.is("pink", dojo.global.dijit.focus.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._curFocus.id, "another shift-tab, to input before ColorPalette")
+								doh.is("beforeBig", dojo.global.dijit.focus.curNode.id, "another shift-tab, to input before ColorPalette")
 							}), 1000);
 
 							return d;
@@ -217,9 +217,9 @@
 								doh.is("#008000", value, "value");
 								
 								// test that focus also got set
-								var focus = dojo.global.dijit._curFocus;
+								var focus = dojo.global.dijit.focus.curNode;
 								doh.t(focus, "something is focused");
-								var imgNode = focus.getElementsByTagName("img")[0]
+								var imgNode = focus.getElementsByTagName("img")[0];
 								doh.t(imgNode, "found image node");
 								var dye = small._getDye(focus);
 								doh.is("#008000", dye.getValue(), "focused");
@@ -234,6 +234,11 @@
 							
 							return d;
 						}
+					},
+					function valuePreselected(){
+						var cp = dijit.byId("valuePreselected");
+						doh.is("#0000ff", cp.get("value"), "get('value')");
+						doh.is("blue", dojo.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 17920ad..3774837 100644
--- a/dijit/tests/robot/Dialog_a11y.html
+++ b/dijit/tests/robot/Dialog_a11y.html
@@ -18,7 +18,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Dialog.html');
 
 				doh.register("keyboard tests (cancel)",[
@@ -37,7 +37,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isVisible("dialog1"), "dialog 1 has been made visible");
-								doh.is("name", dojo.global.dijit._curFocus.id, "focus is on the first field");
+								doh.is("name", dojo.global.dijit.focus.curNode.id, "focus is on the first field");
 							}), 500);
 
 							return d;
@@ -55,7 +55,7 @@
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("date", dojo.global.dijit._curFocus.id, "focus is on the date field");
+								doh.is("date", dojo.global.dijit.focus.curNode.id, "focus is on the date field");
 							}), 1000);
 
 							return d;
@@ -72,7 +72,7 @@
 							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("date", dojo.global.dijit._curFocus.id, "focus is still on the date field");
+								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");
 							}), 1000);
 
@@ -92,7 +92,7 @@
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("name", dojo.global.dijit._curFocus.id, "focus looped back to name field");
+								doh.is("name", dojo.global.dijit.focus.curNode.id, "focus looped back to name field");
 							}), 1000);
 
 							return d;
@@ -108,7 +108,7 @@
 							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("ok", dojo.global.dijit._curFocus.id, "focus looped back to submit button");
+								doh.is("ok", dojo.global.dijit.focus.curNode.id, "focus looped back to submit button");
 							}), 1000);
 
 							return d;
@@ -125,7 +125,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isHidden("dialog1"), "dialog 1 was closed");
-								doh.is("dialog1button", dojo.global.dijit._curFocus.id, "focus returned to button");
+								doh.is("dialog1button", dojo.global.dijit.focus.curNode.id, "focus returned to button");
 							}), 1000);
 
 							return d;
@@ -241,40 +241,40 @@
 							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
 
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(dojo.global.dijit._curFocus, "focus is somewhere #1");
-								doh.t(dojo.hasClass(dojo.global.dijit._curFocus, "dijitDialogCloseIcon"), "focus is on the close button #1");
+								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");
 							}), 1000);
 
 							// Tab key shouldn't change the focus
 							doh.robot.keyPress(dojo.keys.TAB, 500);
 
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(dojo.global.dijit._curFocus, "focus is somewhere #2");
-								doh.t(dojo.hasClass(dojo.global.dijit._curFocus, "dijitDialogCloseIcon"), "focus is on the close button #2");
+								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");
 							}), 500);
 
 							// Space key should close the dialog
 							doh.robot.keyPress(dojo.keys.SPACE, 500);
 
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(dojo.global.dijit._curFocus, "focus is somewhere #3");
-								doh.is("unmovablebutton", dojo.global.dijit._curFocus.id, "focus is back on the button that opened the dialog #1");
+								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");
 							}), 500);
 
 							// Open the dialog again
 							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
 
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(dojo.global.dijit._curFocus, "focus is somewhere #4");
-								doh.t(dojo.hasClass(dojo.global.dijit._curFocus, "dijitDialogCloseIcon"), "focus is on the close button #4");
+								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");
 							}), 500);
 
 							// Esc key should also close the dialog
 							doh.robot.keyPress(dojo.keys.ESCAPE, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dojo.global.dijit._curFocus, "focus is somewhere #5");
-								doh.is("unmovablebutton", dojo.global.dijit._curFocus.id, "focus is back on the button that opened the dialog #2");
+								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");
 							}), 500);
 
 							return d;
@@ -294,16 +294,16 @@
 							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
 
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(dojo.global.dijit._curFocus, "focus is somewhere #1");
-								doh.is("afile", dojo.global.dijit._curFocus.id, "focus is on the input type=file");
+								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");
 							}), 1000);
 
 							// Esc key should close the dialog
 							doh.robot.keyPress(dojo.keys.ESCAPE, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dojo.global.dijit._curFocus, "focus is somewhere #2");
-								doh.is("filebutton", dojo.global.dijit._curFocus.id, "focus is back on the button that opened the dialog");
+								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");
 							}), 500);
 
 							return d;
@@ -323,24 +323,24 @@
 							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
 
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(dojo.global.dijit._curFocus, "focus is somewhere #1");
-								doh.is("textarea-radio-test", dojo.global.dijit._curFocus.id, "focus is on the textarea");
+								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");
 							}), 1000);
 
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(dojo.global.dijit._curFocus, "focus is somewhere #2");
-								doh.is("textarea-radio-test", dojo.global.dijit._curFocus.id, "focus wraps around back to the textarea");
+								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");
 							}), 500);
 
 							// Esc key should close the dialog
 							doh.robot.keyPress(dojo.keys.ESCAPE, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dojo.global.dijit._curFocus, "focus is somewhere #3");
-								doh.is("RadioButtonDlgBtn", dojo.global.dijit._curFocus.id, "focus is back on the button that opened the dialog");
+								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");
 							}), 500);
 
 							return d;
@@ -377,7 +377,7 @@
 								doh.t(dialog1Z > underlayZ, "dialog1 (zIndex=" + dialog1Z +
 									") above underlay (zIndex=" + underlayZ + ")");
 
-								doh.is("loc", dojo.global.dijit._curFocus.id, "focus is on the second field");
+								doh.is("loc", dojo.global.dijit.focus.curNode.id, "focus is on the second field");
 							}), 1000);
 
 							return d;
@@ -428,7 +428,7 @@
 								doh.t(dialog1Z > underlayZ, "dialog1 (zIndex=" + dialog1Z +
 									") above underlay (zIndex=" + underlayZ + ")");
 
-								doh.is("loc", dojo.global.dijit._curFocus.id, "focus is on the second field");
+								doh.is("loc", dojo.global.dijit.focus.curNode.id, "focus is on the second field");
 							}), 2000);
 
 							return d;
@@ -445,7 +445,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isHidden("dialog1"), "dialog 1 was closed");
-								doh.is("dialog1button", dojo.global.dijit._curFocus.id, "focus returned to button");
+								doh.is("dialog1button", dojo.global.dijit.focus.curNode.id, "focus returned to button");
 							}), 2000);
 
 							return d;
diff --git a/dijit/tests/robot/Dialog_focusDestroy.html b/dijit/tests/robot/Dialog_focusDestroy.html
index 983ffa8..cbd1f8c 100644
--- a/dijit/tests/robot/Dialog_focusDestroy.html
+++ b/dijit/tests/robot/Dialog_focusDestroy.html
@@ -15,7 +15,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Dialog_focusDestroy.html');
 					
 				doh.register("TestDestroy",[
diff --git a/dijit/tests/robot/Dialog_mouse.html b/dijit/tests/robot/Dialog_mouse.html
index 764c870..93e8d0b 100644
--- a/dijit/tests/robot/Dialog_mouse.html
+++ b/dijit/tests/robot/Dialog_mouse.html
@@ -19,7 +19,7 @@
 			dojo.require("dijit.robotx");
 
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Dialog.html');
 
 				doh.register("dijit.Dialog mouse tests (cancel)",[
@@ -33,7 +33,7 @@
 							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._curFocus.id, "focus is on the first field");
+									doh.is("name", dojo.global.dijit.focus.curNode.id, "focus is on the first field");
 								}));
 								dijit.byId("dialog1button").onClick = oldOnClick;
 							};
@@ -57,7 +57,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isVisible("dialog1"), "dialog 1 still visible");
-								doh.isNot("plainInput", dojo.global.dijit._curFocus && dojo.global.dijit._curFocus.id, "plain input wasn't focused");
+								doh.isNot("plainInput", dojo.global.dijit.focus.curNode && dojo.global.dijit.focus.curNode.id, "plain input wasn't focused");
 							}), 1000);
 
 							return d;
@@ -75,7 +75,7 @@
 								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._curFocus, calDomNode[0]), "focus is on the calendar ");
+									doh.t(dojo.isDescendant(dojo.global.dijit.focus.curNode, calDomNode[0]), "focus is on the calendar ");
 								}), 500);
 							});
 
@@ -170,6 +170,84 @@
 					}
 				]);
 
+				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>
diff --git a/dijit/tests/robot/InlineEditBox.html b/dijit/tests/robot/InlineEditBox.html
index c429105..b1766fd 100644
--- a/dijit/tests/robot/InlineEditBox.html
+++ b/dijit/tests/robot/InlineEditBox.html
@@ -19,10 +19,10 @@
 			dojo.require("dojo.date.locale");
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_InlineEditBox.html');
 
-				function moveAndClick(node) {
+				function moveAndClick(node){
 					doh.robot.mouseMoveAt(node, 500, 1);
 					doh.robot.mouseClick({left: true}, 500);
 				}
@@ -226,12 +226,13 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							var inlineBox = dijit.byId(test.id);
-							var handler = inlineBox.connect(inlineBox, 'edit',
-								function(){
-									inlineBox.disconnect(handler);
+							var handler = inlineBox.connect(inlineBox, 'edit', function(){
+								inlineBox.disconnect(handler);
+								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");
-										var editWidget = inlineBox.wrapperWidget.editWidget;
 										doh.t(isVisible(editWidget), "editor widget should visible");
 										var expected = test.widgetValue,
 											actual = editWidget.get("value");
@@ -246,8 +247,9 @@
 											});
 										var buttons = dojo.query(".cancelButton", inlineBox.domNode.parentNode);
 										moveAndClick(buttons[buttons.length-1]);
-									}), 1000);
+									}), 1500);
 								});
+							});
 							moveAndClick(inlineBox.domNode);
 							return d;
 						}
diff --git a/dijit/tests/robot/Menu_a11y.html b/dijit/tests/robot/Menu_a11y.html
index 80ce436..832922e 100644
--- a/dijit/tests/robot/Menu_a11y.html
+++ b/dijit/tests/robot/Menu_a11y.html
@@ -9,8 +9,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"></script>
 
 		<!-- functions to help test -->
 		<script type="text/javascript" src="../helpers.js"></script>
@@ -18,7 +17,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Menu.html');
 
 				doh.register("dijit.MenuBar general keyboard tests",[
@@ -34,8 +33,8 @@
 							}, 500, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dojo.global.dijit._curFocus, "something has focus");
-								doh.is("random link", dojo.global.dijit._curFocus.innerHTML, "check that focus is on the link");
+								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");
 							}), 1000);
 
 							return d;
@@ -52,7 +51,7 @@
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("File", dojo.trim(dojo.global.dijit._curFocus.innerText || dojo.global.dijit._curFocus.textContent),
+								doh.is("File", dojo.trim(dojo.global.dijit.focus.curNode.innerText || dojo.global.dijit.focus.curNode.textContent),
 										"check that focus is on File menu");
 							}), 1000);
 
@@ -69,7 +68,7 @@
 							doh.robot.keyPress(dojo.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._curFocus.innerText || dojo.global.dijit._curFocus.textContent),
+								doh.is("Edit", dojo.trim(dojo.global.dijit.focus.curNode.innerText || dojo.global.dijit.focus.curNode.textContent),
 										"check that focus is on Edit MenuItem");
 							}), 1000);
 
@@ -86,7 +85,7 @@
 							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("random link", dojo.trim(dojo.global.dijit._curFocus.innerText || dojo.global.dijit._curFocus.textContent),
+								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");
 							}), 1000);
 
@@ -112,7 +111,7 @@
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t((dojo.global.dijit._curFocus.innerText || dojo.global.dijit._curFocus.textContent).indexOf("New") >= 0,
+								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)");
 							}), 1000);
 
@@ -170,7 +169,7 @@
 							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t( (dojo.global.dijit._curFocus.innerText || dojo.global.dijit._curFocus.textContent).indexOf("50%") >= 0,
+								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
 							}), 1000, 500);
@@ -194,8 +193,8 @@
 							}, 500, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dojo.global.dijit._curFocus, "something has focus");
-								doh.is("random link", dojo.global.dijit._curFocus.innerHTML, "check that focus is on the link");
+								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");
 							}), 1000);
 
 							return d;
@@ -212,7 +211,7 @@
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("File", dijit.getEnclosingWidget(dojo.global.dijit._curFocus).label,
+								doh.is("File", dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode).label,
 										"check that focus is on File MenuItem");
 							}), 1000);
 
@@ -230,7 +229,7 @@
 							doh.robot.keyPress(dojo.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._curFocus.innerText || dojo.global.dijit._curFocus.textContent),
+								doh.is("View", dojo.trim(dojo.global.dijit.focus.curNode.innerText || dojo.global.dijit.focus.curNode.textContent),
 										"check that focus is on View MenuItem");
 							}), 1000);
 
@@ -249,7 +248,7 @@
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});	// focuses "Zoom", third menu item
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Zoom", dijit.getEnclosingWidget(dojo.global.dijit._curFocus).label,
+								doh.is("Zoom", dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode).label,
 										"check that focus is on Zoom MenuItem");
 							}), 1000);
 
@@ -266,7 +265,7 @@
 							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("50%", dijit.getEnclosingWidget(dojo.global.dijit._curFocus).label,
+								doh.is("50%", dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode).label,
 										"check that focus is on Zoom MenuItem");
 							}), 1000);
 
@@ -283,7 +282,7 @@
 							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Zoom", dijit.getEnclosingWidget(dojo.global.dijit._curFocus).label,
+								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,
@@ -305,7 +304,7 @@
 							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Cut", dijit.getEnclosingWidget(dojo.global.dijit._curFocus).label,
+								doh.is("Cut", dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode).label,
 										"check that focus is on first MenuItem in Edit Menu");
 
 								doh.is(0, dojo.query("#viewMenu .dijitMenuItemSelected").length,
@@ -317,9 +316,122 @@
 					}
 				]);
 
+				doh.register("dijit.MenuBar nested click focus test",[
+					{
+						name: "start focus on the link, outside of menubar",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Start at the link
+							doh.robot.sequence(function(){
+								dojo.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");
+							}), 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,
+							doh.robot.keyPress(dojo.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");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "arrow to the view menu",
+						timeout: 5000,
+						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
+
+							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");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "down to the zoom menuitem",
+						timeout: 5000,
+						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
+
+							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);
+
+							return d;
+						}
+					},
+
+					{
+						name: "open the zoom menu",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.keyPress(dojo.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");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "click to close Zoom menu, focus back to MenuBar",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// 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, {});
+
+							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");
+							}), 1000);
+
+							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(!dojo.isMac || !dojo.isWebKit){
 					doh.register("Context menu keyboard tests", [{
 						name: "open global context menu (keyboard)",
 						timeout: 5000,
diff --git a/dijit/tests/robot/Menu_iframe.html b/dijit/tests/robot/Menu_iframe.html
index 6baeb77..f3a8b5a 100644
--- a/dijit/tests/robot/Menu_iframe.html
+++ b/dijit/tests/robot/Menu_iframe.html
@@ -18,7 +18,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Menu_iframe.html');
 					
 				var handler, menu;
@@ -40,7 +40,7 @@
 							doh.robot.mouseClick({right:true}, 500);
 							
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.f(isVisible(menu.domNode));
+								doh.f(isVisible(menu.domNode), "menu hidden");
 							})), 1000);
 
 							return d;
@@ -65,7 +65,7 @@
 							
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
 								var menu = dijit.byId("menu");
-								doh.t(isVisible(menu.domNode));
+								doh.t(isVisible(menu.domNode), "menu visible");
 							})), 1000);
 
 							return d;
@@ -85,11 +85,11 @@
 							
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
 								var menu = dijit.byId("menu");
-								doh.t(isVisible(menu.domNode));
+								doh.t(isVisible(menu.domNode), "menu visible");
 
 								var iframe = dojo.byId("iframe");
 								var heading = dojo.withGlobal(iframe.contentWindow,'query', dojo, ["h1"])[0];
-								doh.is("Document 0", heading.innerHTML);
+								doh.is("Document 0", heading.innerHTML, "heading.innerHTML");
 							})), 1000);
 
 							return d;
@@ -112,7 +112,7 @@
 							doh.robot.mouseClick({right:true}, 500);
 							
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.f(isVisible(menu.domNode));
+								doh.f(isVisible(menu.domNode), "menu hidden");
 							})), 1000);
 
 							return d;
@@ -137,7 +137,7 @@
 							
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
 								var menu = dijit.byId("menu");
-								doh.t(isVisible(menu.domNode));
+								doh.t(isVisible(menu.domNode), "menu visible");
 							})), 1000);
 
 							return d;
@@ -157,11 +157,11 @@
 							
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
 								var menu = dijit.byId("menu");
-								doh.t(isVisible(menu.domNode));
+								doh.t(isVisible(menu.domNode), "menu visible");
 
 								var iframe = dojo.byId("iframe");
 								var div = dojo.withGlobal(iframe.contentWindow,'query', dojo, ["div"])[0];
-								doh.is("bill was here", div.innerHTML);
+								doh.is("bill was here", div.innerHTML, "div.innerHTML");
 							})), 1000);
 
 							return d;
@@ -184,7 +184,7 @@
 							doh.robot.mouseClick({right:true}, 500);
 							
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.f(isVisible(menu.domNode));
+								doh.f(isVisible(menu.domNode), "menu hidden");
 							})), 1000);
 
 							return d;
@@ -209,7 +209,7 @@
 							
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
 								var menu = dijit.byId("menu");
-								doh.t(isVisible(menu.domNode));
+								doh.t(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 0563d47..d989af6 100644
--- a/dijit/tests/robot/Menu_mouse.html
+++ b/dijit/tests/robot/Menu_mouse.html
@@ -9,8 +9,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"></script>
 
 		<!-- functions to help test -->
 		<script type="text/javascript" src="../helpers.js"></script>
@@ -18,7 +17,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Menu.html');
 
 				doh.register("dijit.MenuBar mouse tests", [
diff --git a/dijit/tests/robot/TitlePane.html b/dijit/tests/robot/TitlePane.html
index 4809a9a..b0bc360 100644
--- a/dijit/tests/robot/TitlePane.html
+++ b/dijit/tests/robot/TitlePane.html
@@ -19,7 +19,7 @@
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_TitlePane.html');
 
 				var pane1, pane2, pane3, href1, href2;
@@ -82,21 +82,21 @@
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is(pane1.focusNode, dojo.global.dijit._curFocus,"focused on pane1 title")
+								doh.is(pane1.focusNode, dojo.global.dijit.focus.curNode,"focused on pane1 title")
 							}), 500);
 
 							// should skip hidden content and go to button
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is(dojo.byId("titleButton"), dojo.global.dijit._curFocus,"focused on title button after pane")
+								doh.is(dojo.byId("titleButton"), dojo.global.dijit.focus.curNode,"focused on title button after pane")
 							}), 500);
 
 							// go back to title bar
 							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(pane1.focusNode, dojo.global.dijit._curFocus,"focused on pane1 title")
+								doh.is(pane1.focusNode, dojo.global.dijit.focus.curNode,"focused on pane1 title")
 							}), 500);
 
 							return d;
diff --git a/dijit/tests/robot/Toolbar.html b/dijit/tests/robot/Toolbar.html
index 3618eac..8a1dd8b 100644
--- a/dijit/tests/robot/Toolbar.html
+++ b/dijit/tests/robot/Toolbar.html
@@ -15,7 +15,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Toolbar.html');
 
 				var toolbar1Before, toolbar1After, toolbar1, toolbar2, toolbar3, toolbar4;
@@ -38,7 +38,7 @@
 							doh.t(toolbar3, "toolbar 3");
 							doh.t(toolbar4, "toolbar 4");
 							
-							// and that labels are shown except when showLabel=true
+							// and that labels are shown except when showLabel==false
 							var cutText = dojo.query(".dijitButtonText", dojo.byId("toolbar1.cut"))[0];
 							doh.is(0, cutText.offsetWidth, "cut button - text hidden");						
 
@@ -61,22 +61,22 @@
 
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is("toolbar1.cut", dojo.global.dijit._curFocus.id, "cut, first visit");
+								doh.is("toolbar1.cut", dojo.global.dijit.focus.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._curFocus.id);
+								doh.is("toolbar1After", dojo.global.dijit.focus.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._curFocus.id, "cut, second visit");
+								doh.is("toolbar1.cut", dojo.global.dijit.focus.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._curFocus.id, "back before toolbar1");
+								doh.is("toolbar1Before", dojo.global.dijit.focus.curNode.id, "back before toolbar1");
 							})), 1000);
 
 							return d;
@@ -101,17 +101,17 @@
 							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._curFocus.id, "cut, first visit");
+								doh.is("toolbar1.italic", dojo.global.dijit.focus.curNode.id, "italic, first visit");
 							})), 1000);
 
-							// Remaining enabled positons that left/right arrow should navigate to (not including the initial leftmost button),
+							// 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._curFocus.id, str + ", first visit");
+									doh.is(str, dojo.global.dijit.focus.curNode.id, str + ", first visit");
 								})), 1000);
 							});
 
@@ -121,7 +121,7 @@
 							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._curFocus.id, str + ", second visit");
+									doh.is(str, dojo.global.dijit.focus.curNode.id, str + ", second visit");
 								})), 1000);
 							});
 
@@ -132,18 +132,18 @@
 							// 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._curFocus.id, "first time past toolbar1");
+								doh.is("toolbar1After", dojo.global.dijit.focus.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._curFocus.id, "cut, after shift-tab back into toolbar");
+								doh.is("toolbar1.italic", dojo.global.dijit.focus.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._curFocus.id, "back before toolbar1");
+								doh.is("toolbar1Before", dojo.global.dijit.focus.curNode.id, "back before toolbar1");
 							})), 1000);
 
 							return d;
@@ -161,20 +161,20 @@
 							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._curFocus.id, "first button");
+								doh.is("toolbar1.italic", dojo.global.dijit.focus.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._curFocus.id, "last button");
+								doh.is("toolbar1.insertorderedlist", dojo.global.dijit.focus.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._curFocus.id, "first button again");
+								doh.is("toolbar1.italic", dojo.global.dijit.focus.curNode.id, "first button again");
 							})), 1000);
 
 							return d;
@@ -202,25 +202,25 @@
 							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
 
 							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is("toolbar1.dialog", dojo.global.dijit._curFocus.id, "dialog button, first visit");
+								doh.is("toolbar1.dialog", dojo.global.dijit.focus.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._curFocus.id);
+								doh.is("user", dojo.global.dijit.focus.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._curFocus.id, "dialog button, second visit");
+								doh.is("toolbar1.dialog", dojo.global.dijit.focus.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._curFocus.id, "user, again");
+								doh.is("user", dojo.global.dijit.focus.curNode.id, "user, again");
 							})), 1000);
 
 							// Submit should also restore focus to toolbar dialog button, assuming that it
@@ -229,29 +229,29 @@
 							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._curFocus.id, "dialog button, third visit");
+								doh.is("toolbar1.dialog", dojo.global.dijit.focus.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._curFocus, dijit.byId("toolbar1.colorPalette").domNode),
-									"focus inside colorpalette, actual focus is: " + (dojo.global.dijit._curFocus ? 
-										(dojo.global.dijit._curFocus.id||"no id") : "no focus"));
+								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"));
 							})), 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._curFocus, dijit.byId("toolbar1.colorPalette").domNode),
-									"focus still inside colorpalette, actual focus is: " + (dojo.global.dijit._curFocus ? 
-										(dojo.global.dijit._curFocus.id||"no id") : "no focus"));
+								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"));
 							})), 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._curFocus.id, "back on colorpalette button");
+								doh.is("toolbar1.backcolor", dojo.global.dijit.focus.curNode.id, "back on colorpalette button");
 							})), 1000);
 
 							// try the ComboButton
diff --git a/dijit/tests/robot/TooltipDialog_a11y.html b/dijit/tests/robot/TooltipDialog_a11y.html
index c84261f..d44a3d1 100644
--- a/dijit/tests/robot/TooltipDialog_a11y.html
+++ b/dijit/tests/robot/TooltipDialog_a11y.html
@@ -18,7 +18,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_TooltipDialog.html');
 
 				doh.register("TooltipDialog normal operation", [
@@ -41,13 +41,13 @@
 							// 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._curFocus.id, "focused on button");
+								doh.is("submit", dojo.global.dijit.focus.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._curFocus.id, "focused on InlineEditBox");
+								doh.is("inline", dojo.global.dijit.focus.curNode.id, "focused on InlineEditBox");
 							}), 1000);
 
 							// close TooltipDialog
@@ -79,7 +79,7 @@
 
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(button._opened, "TooltipDialog should be showing");
-								doh.is("combo", dojo.global.dijit._curFocus.id, "focused on combo");
+								doh.is("combo", dojo.global.dijit.focus.curNode.id, "focused on combo");
 							}), 1000);
 
 							// pick second option
@@ -262,7 +262,7 @@
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var button = dijit.byId("tooltipDlgButton")
+							var button = dijit.byId("tooltipDlgButton");
 								inlineEditBox = dijit.byId("inline");
 
 							// open TooltipDialog
@@ -360,6 +360,32 @@
 							}), 2000);
 							return d;
 						}
+					},
+					{
+						name: "href",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var button = dijit.byId("slowLoadButton"),
+								dialog = dijit.byId("slowLoad");
+
+							// open TooltipDialog
+							doh.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);
+
+							// 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;
+						}
 					}
 				]);
 
diff --git a/dijit/tests/robot/TooltipDialog_mouse.html b/dijit/tests/robot/TooltipDialog_mouse.html
index 69a1106..c2592ce 100644
--- a/dijit/tests/robot/TooltipDialog_mouse.html
+++ b/dijit/tests/robot/TooltipDialog_mouse.html
@@ -18,7 +18,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_TooltipDialog.html');
 
 				doh.register("Select", [
@@ -32,7 +32,7 @@
 							doh.robot.mouseClick({left: true}, 1000);
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isVisible("tooltipDlg"), "TooltipDialog visible");
-								doh.is("inline", dojo.global.dijit._curFocus.id, "focus on InlineEditBox (first field in TooltipDialog)")
+								doh.is("inline", dojo.global.dijit.focus.curNode.id, "focus on InlineEditBox (first field in TooltipDialog)")
 							}), 1000);
 						}
 					},
@@ -114,13 +114,13 @@
 							}), 1000);
 							
 							// click TextBox to get select to close
-							doh.robot.mouseMoveAt("text", 0)
+							doh.robot.mouseMoveAt("text", 0);
 							doh.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._curFocus && dijit._curFocus.id, "focused on textbox")
+								doh.is("text", dijit.focus.curNode && dijit.focus.curNode.id, "focused on textbox")
 							}), 1000);
 						}
 					},
@@ -191,6 +191,80 @@
 					}
 				]);
 
+				doh.register("DateTextBox", [
+					{
+						name: "open TooltipDialog",
+						timeout: 10000,
+						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)")
+							}), 1000);
+						}
+					},
+
+					{
+						name: "open DateTextBox by clicking arrow",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred(),
+								date = dijit.byId("date2");
+
+							// click arrow to open
+							doh.robot.mouseMoveAt(function(){
+								return dojo.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");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "close DateTextBox by clicking arrow",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred(),
+								date = dijit.byId("date2");
+
+							// click arrow to open
+							doh.robot.mouseMoveAt(function(){
+								return dojo.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");
+							}), 1000);
+						}
+					},
+
+					{
+						name: "close TooltipDialog",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMove(10, 10, 0);
+							doh.robot.mouseClick({left: true}, 1000);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isHidden("tooltipDlg"), "Tooltip dialog closed");
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
 				doh.register("Menu", [
 					{
 						name: "open outer TooltipDialog",
@@ -277,13 +351,13 @@
 							var d = new doh.Deferred();
 							
 							// click TextBox to get submenu to close
-							doh.robot.mouseMoveAt("name", 0)
+							doh.robot.mouseMoveAt("name", 0);
 							doh.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._curFocus && dijit._curFocus.id, "focused on textbox")
+								doh.is("name", dijit.focus.curNode && dijit.focus.curNode.id, "focused on textbox")
 							}), 1000);
 						}
 					},
diff --git a/dijit/tests/robot/Tooltip_a11y.html b/dijit/tests/robot/Tooltip_a11y.html
index 1689033..a68d4f6 100644
--- a/dijit/tests/robot/Tooltip_a11y.html
+++ b/dijit/tests/robot/Tooltip_a11y.html
@@ -19,7 +19,7 @@
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Tooltip.html');
 
 				// Pointer to master tooltip.  This gets set in the first test when the
@@ -57,7 +57,8 @@
 								// left of the right depending on page BIDI setting)
 								var aroundCoords = dojo.position(around),
 									tooltipCoords = dojo.position(masterTT.domNode);
-								doh.is(aroundCoords.y + aroundCoords.h, tooltipCoords.y + Math.round(tooltipCoords.h), "aligned");
+								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");
diff --git a/dijit/tests/robot/Tooltip_mouse.html b/dijit/tests/robot/Tooltip_mouse.html
index f5c3b87..d71fd69 100644
--- a/dijit/tests/robot/Tooltip_mouse.html
+++ b/dijit/tests/robot/Tooltip_mouse.html
@@ -18,7 +18,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Tooltip.html');
 
 				// Pointer to master tooltip.  This gets set in the first test when the
@@ -48,13 +48,12 @@
 					},
 
 					{
-						name: "hide on defocus",
+						name: "hide on unhover",
 						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							// Tab off of the "button w/tooltip" to the "remove button",
-							// which doesn't have a tooltip
+							// Move off of the "button w/tooltip" to node which doesn't have a tooltip
 							doh.robot.mouseMoveAt(dojo.query("h1")[0], 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -63,6 +62,91 @@
 
 							return d;
 						}
+					},
+
+					{
+						name: "click to focus, then mouse away",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt("id1", 500);
+							doh.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");
+							}), 2000);
+
+							// Move off of the focused node to node which doesn't have a tooltip
+							doh.robot.mouseMoveAt(dojo.query("h1")[0], 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && isHidden(masterTT.domNode), "tooltip hidden");
+							}), 2000);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("Tooltip on Menu", [
+					{
+						name: "show tooltip on MenuItem",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Click the DropDownButton to open the Menu
+							doh.robot.mouseMoveAt("ddb", 500);
+							doh.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");
+							}), 750);
+
+							return d;
+						}
+					},
+
+					{
+						name: "hide Tooltip on Menu close",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Click the MenuItem to close the menu
+							doh.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");
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("Tooltip in TitlePane", [
+					{
+						name: "show tooltip on span in TitlePane",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt("tpTooltipTarget", 500);
+
+							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");
+							}), 500);
+
+							return d;
+						}
 					}
 				]);
 
diff --git a/dijit/tests/robot/Tooltip_mouse_quirks.html b/dijit/tests/robot/Tooltip_mouse_quirks.html
index 0fba813..c205b0b 100644
--- a/dijit/tests/robot/Tooltip_mouse_quirks.html
+++ b/dijit/tests/robot/Tooltip_mouse_quirks.html
@@ -18,7 +18,7 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot("../quirks.html?file=test_Tooltip.html");
 
 				doh.register("dijit.Tooltip mouse quirks tests", [
diff --git a/dijit/tests/robot/_Widget-deferredConnect.html b/dijit/tests/robot/_Widget-deferredConnect.html
index 779b891..36c8342 100644
--- a/dijit/tests/robot/_Widget-deferredConnect.html
+++ b/dijit/tests/robot/_Widget-deferredConnect.html
@@ -5,7 +5,7 @@
 	<title>doh.robot deferred connect tests</title>
 
 	<style>
-		@import "../../../../util/doh/robot/robot.css";
+		@import "../../../util/doh/robot/robot.css";
 	</style>
 
 	<!-- required: dojo.js -->
@@ -18,7 +18,7 @@
 	<script type="text/javascript">
 		dojo.require("dijit.robotx");
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 
 			doh.robot.initRobot('../_Widget-deferredConnect.html');
 
diff --git a/dijit/tests/robot/_Widget-ondijitclick_a11y.html b/dijit/tests/robot/_Widget-ondijitclick_a11y.html
index a591af6..9ab7420 100644
--- a/dijit/tests/robot/_Widget-ondijitclick_a11y.html
+++ b/dijit/tests/robot/_Widget-ondijitclick_a11y.html
@@ -9,7 +9,7 @@
 	<script type="text/javascript">
 		dojo.require("dijit.robotx");
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			doh.robot.initRobot('../_Widget-ondijitclick.html');
 
 			// Event monitoring
@@ -25,7 +25,7 @@
 					dojo.connect(dojo.byId("plainbutton"), "onclick", function(){
 						buttonClicks++;
 					});
-					dojo.connect(dojo.byId("button2"), "onclick", function(){
+					dojo.connect(dojo.byId("plainbutton2"), "onclick", function(){
 						button2Clicks++;
 					});
 					dojo.connect(dojo.byId("third"), "onclick", function(){
@@ -132,7 +132,7 @@
 							button2Clicks = thirdClicks = 0;
 
 							var d = new doh.Deferred(),
-								button = dojo.byId("button2");
+								button = dojo.byId("plainbutton2");
 
 							// Keyboard-click the native button
 							doh.robot.sequence(function(){
@@ -152,6 +152,39 @@
 				]);
 			});
 
+			// 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){
+
+				doh.register("click ondijitclick button by " + key, [
+					{
+						name: "click by " + key,
+						timeout: 5000,
+						runTest: function(){
+
+							var d = new doh.Deferred(),
+								buttonWidget = dijit.byId("widgetbutton"),
+								buttonNode = dojo.byId("widgetbutton");
+
+							buttonWidget.clickCount = 0;
+
+							// Keyboard-click the widget button
+							doh.robot.sequence(function(){
+								buttonNode.focus();
+							}, 500);
+							doh.robot.keyPress(dojo.keys[key], 500, {});
+
+							// Check that ondijitclick fired exactly once
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(1, buttonWidget.clickCount, "one click event");
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+			});
+
 			doh.run();
 		});
 
diff --git a/dijit/tests/robot/_Widget-ondijitclick_mouse.html b/dijit/tests/robot/_Widget-ondijitclick_mouse.html
index 80bd6aa..9ddaebe 100644
--- a/dijit/tests/robot/_Widget-ondijitclick_mouse.html
+++ b/dijit/tests/robot/_Widget-ondijitclick_mouse.html
@@ -9,7 +9,7 @@
 	<script type="text/javascript">
 		dojo.require("dijit.robotx");
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			doh.robot.initRobot('../_Widget-ondijitclick.html');
 
 			// Event monitoring
@@ -26,9 +26,9 @@
 						dojo.connect(w, "_onClick", function(){
 							widgetClicks++;
 						}),
-						dojo.connect(dojo.byId("plainbutton"), "onclick", function(){
-							buttonClicks++;
-						})
+								dojo.connect(dojo.byId("plainbutton"), "onclick", function(){
+									buttonClicks++;
+								});
 						w.domNode.focus();
 					}, 100);
 
@@ -44,6 +44,31 @@
 				}
 			});
 
+			// Test clicking on a <button> with an ondijitclick handler.
+			doh.register("click ondijitclick button", [
+				{
+					name: "click",
+					timeout: 5000,
+					runTest: function(){
+
+						var d = new doh.Deferred(),
+							buttonWidget = dijit.byId("widgetbutton");
+
+						buttonWidget.clickCount = 0;
+
+						doh.robot.mouseMoveAt("widgetbutton", 500);
+						doh.robot.mouseClick({left: true}, 500);
+
+						// Check that ondijitclick fired exactly once
+						doh.robot.sequence(d.getTestCallback(function(){
+							doh.is(1, buttonWidget.clickCount, "one click event");
+						}), 500);
+
+						return d;
+					}
+				}
+			]);
+
 			doh.run();
 		});
 
diff --git a/dijit/tests/test_Calendar.html b/dijit/tests/test_Calendar.html
index 5ebab83..2e4deb6 100644
--- a/dijit/tests/test_Calendar.html
+++ b/dijit/tests/test_Calendar.html
@@ -35,7 +35,7 @@
 			dojo.require("dojo.date.locale");
 			dojo.require("dojo.parser"); // scan page for widgets
 
-			dojo.addOnLoad(function(){
+			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
@@ -69,16 +69,18 @@
 		<p>
 			<a href="#"
 			   onClick="dijit.registry.forEach(function(c){
-					c.isDisabledDate = dojo.date.locale.isWeekend;
-					c._populateGrid();
+			   		if(c.isDisabledDate){
+						c.isDisabledDate = dojo.date.locale.isWeekend;
+						c._populateGrid();
+					}
 				});">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.addOnLoad block. -->
-			<input id="calendar5" data-dojo-props='dayWidth:"abbr", value:"2008-03-14"'/>
+			<!-- 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>
 	</body>
 </html>
diff --git a/dijit/tests/test_CalendarLite.html b/dijit/tests/test_CalendarLite.html
new file mode 100644
index 0000000..ab5eb65
--- /dev/null
+++ b/dijit/tests/test_CalendarLite.html
@@ -0,0 +1,43 @@
+<!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 b78bfdb..e836756 100644
--- a/dijit/tests/test_ColorPalette.html
+++ b/dijit/tests/test_ColorPalette.html
@@ -14,34 +14,35 @@
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true, extraLocale: ['en-us', 'es-mx']"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true, async:0, extraLocale: ['en-us', 'es-mx']"></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.ColorPalette");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-
-    //-sie
-    // this test requires one or both of the "es-mx" and "en-us" localizations for
-    // dojo/colors be loaded, depending upon the default locale. Recall, in the sie version,
-    // i18n bundles are loaded asynchronously
-    dojo.req && dojo.req("i18n!dojo/nls/en-us/colors", "i18n!dojo/nls/es-mx/colors");
-
 		var palette;
-		dojo.addOnLoad(function(){
-            var date0 = new Date();
-            palette = new dijit.ColorPalette({palette: "7x10", id: "prog"}, dojo.byId("programPalette"));
-            console.log("creation time for 7x10 palette: " + (new Date() - date0) );
-        });
+	
+		function programatic(){ 
+			var date0 = new Date();
+			palette = new dijit.ColorPalette({palette: "7x10", id: "prog"}, dojo.byId("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>
 
@@ -51,7 +52,7 @@
 
 	<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"'></div>
+	<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>.
 	<input id="afterBig" value="for tabIndex testing"/>
 
@@ -63,5 +64,9 @@
 	<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"/>
 </body>
 </html>
diff --git a/dijit/tests/test_Declaration.html b/dijit/tests/test_Declaration.html
index b287bdf..2a39802 100644
--- a/dijit/tests/test_Declaration.html
+++ b/dijit/tests/test_Declaration.html
@@ -25,9 +25,10 @@
 		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.addOnLoad(function(){
+		dojo.ready(function(){
 			doh.register("dijit.Declaration", [
 				function parse(){
 					// run parser inside of DOH so we can tell if there are any exceptions
@@ -55,6 +56,18 @@
 					// test <script type="dojo/connect">
 					doh.t(foo1, "foo1 exists");
 					doh.t(/modified by dojo\/connect event=startup/.test(foo1.domNode.innerHTML), "dojo/connect fired");
+				},
+
+				function events(){
+					doh.t(button1, "button created");
+					doh.t(button1.onButtonClick, "onButtonClick exists");
+
+					var clicked = false;
+					button1.on("ButtonClick", function(){
+						clicked = true;
+					});
+					dojo.on.emit(button1.domNode, "click", {});
+					doh.t(clicked, "clicked");
 				}
 			]);
 
@@ -128,5 +141,16 @@
 	<div data-dojo-id="foo1" data-dojo-type="foo" data-dojo-props='foo:"blah", progress:50'></div>
 	<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"
+		 	data-dojo-props='widgetClass:"button"'
+			data-dojo-attach-event="onclick: onButtonClick">
+		<script type='dojo/method' data-dojo-event='onButtonClick'>
+			console.log("in onButtonClicked");
+		</script>
+		click me
+	</div>
+
+	<button data-dojo-id="button1" data-dojo-type="button">click me</button>
 </body>
 </html>
diff --git a/dijit/tests/test_Declaration_1.x.html b/dijit/tests/test_Declaration_1.x.html
index ee5493b..464f9da 100644
--- a/dijit/tests/test_Declaration_1.x.html
+++ b/dijit/tests/test_Declaration_1.x.html
@@ -26,7 +26,7 @@
 		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 		dojo.require("doh.runner");
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			doh.register("dijit.Declaration_1.x", [
 				function parse(){
 					// run parser inside of DOH so we can tell if there are any exceptions
diff --git a/dijit/tests/test_Dialog.html b/dijit/tests/test_Dialog.html
index 852ccbf..133dfe7 100644
--- a/dijit/tests/test_Dialog.html
+++ b/dijit/tests/test_Dialog.html
@@ -44,7 +44,7 @@
 		Date.prototype.json = function(){ return dojo.date.stamp.toISOString(this, {selector: 'date'});};
 
 		var thirdDlg;
-		function createDialog() {
+		function createDialog(){
 			if(!thirdDlg){
 				var pane = dojo.byId('thirdDialog');
 				// should specify a width on dialogs with <p> tags, otherwise they get too wide
@@ -61,6 +61,19 @@
 			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();
+				}
+			});
+			dlg.show();
+		}
 	</script>
 </head>
 <body class="claro">
@@ -213,7 +226,7 @@
 	<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("embedded").show() }'>Dialog w/embedded layout widgets</button> |
 
 	<div id="embedded" data-dojo-type="dijit.Dialog" data-dojo-props='title:"Embedded layout widgets",
-		onShow:function(){ dojo.attr(this.domNode, "aria-describedby", "describe"); } '>
+		onShow:function(){ this.domNode.setAttribute("aria-describedby", "describe"); } '>
 		<p id="describe">
 			The pane has some text, plus two embedded layout widgets, which should
 			appear correctly even though the pane is initially hidden.
@@ -363,14 +376,19 @@
 	    <textarea id="textarea-radio-test" width="400" height="200"></textarea>
 	    <fieldset>
 	      <legend>Best Pet</legend>
-	      <input id="dograd" type="radio" name="pet" checked="checked"></input>
+	      <input id="dograd" type="radio" name="pet" checked="checked"/>
 	      <label for="dograd">Dog</label> -
-	      <input id="catrad" type="radio" name="pet"></input>
+	      <input id="catrad" type="radio" name="pet"/>
 	      <label for="catrad">Cat</label>
 	    </fieldset>
 	  </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 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> |
+
 	<p><b><i>(scroll down to see more links to click, for testing positioning / scroll handling)</i></b></p>
 
 	<p>
diff --git a/dijit/tests/test_Dialog_focusDestroy.html b/dijit/tests/test_Dialog_focusDestroy.html
index cfe7c43..955023b 100644
--- a/dijit/tests/test_Dialog_focusDestroy.html
+++ b/dijit/tests/test_Dialog_focusDestroy.html
@@ -31,10 +31,10 @@
 
     //-sie
     //the dojo.required code might not be here yet!
-    dojo.addOnLoad(function() {
+    dojo.ready(function(){
 
 		// make dojo.toJson() print dates correctly (this feels a bit dirty)
-		createAndShow= function() {
+		createAndShow= function(){
 			var node = document.createElement("div");
 			dojo.body().appendChild(node);
 			var dlg = new dijit.Dialog({ title: "test input focus" }, node);
diff --git a/dijit/tests/test_InlineEditBox.html b/dijit/tests/test_InlineEditBox.html
index 1312280..f7ae1e9 100644
--- a/dijit/tests/test_InlineEditBox.html
+++ b/dijit/tests/test_InlineEditBox.html
@@ -232,7 +232,7 @@ tortor pharetra congue. Suspendisse pulvinar.
 		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.addOnLoad(function(){
+			dojo.ready(function(){
 				var inlineWidget = new dijit.InlineEditBox({ renderAsHtml: true, onChange:myHandler }, 'programmatic');
  			});
 		</script>
diff --git a/dijit/tests/test_Menu.html b/dijit/tests/test_Menu.html
index b669bba..d74d7fb 100644
--- a/dijit/tests/test_Menu.html
+++ b/dijit/tests/test_Menu.html
@@ -14,8 +14,8 @@
 
 		/* styling for left-hand-side navigation menu to become a column equal to length of page */
 		#formattingTable {
-			border: 0px;
-			border-spacing: 0px;
+			border: 0;
+			border-spacing: 0;
 		}
 		#contentContainer { padding: 2em; }
 
@@ -37,22 +37,27 @@
 
 	<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.MenuSeparator");
+
 		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() {
+        function createMenu(){
             // create a menu programmatically
-            function fClick() {console.log("clicked!")};
+            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}));
@@ -97,7 +102,7 @@
             dojo.byId("createButton").disabled = created;
             dojo.byId("destroyButton").disabled = !created;
 	}
-	dojo.addOnLoad(function(){
+	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
@@ -207,7 +212,7 @@
 
 	<table id="formattingTable">
 		<tr>
-			<td style="width:0%;">
+			<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
@@ -279,7 +284,7 @@
 			</td>
 		</tr>
 		<tr>
-			<td id="navMenuContainer" class="dijitMenu" style="vertical-align:top; width:0%;">
+			<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" >
diff --git a/dijit/tests/test_Menu_iframe.html b/dijit/tests/test_Menu_iframe.html
index d916b7e..0e840cf 100644
--- a/dijit/tests/test_Menu_iframe.html
+++ b/dijit/tests/test_Menu_iframe.html
@@ -9,7 +9,10 @@
 	<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.Menu");
+		dojo.require("dijit.MenuItem");
 
 		function setContents(str){
 			dojo.byId('iframe').src = "javascript:'" + str.replace("'", "\\'") + "'";
diff --git a/dijit/tests/test_TitlePane.html b/dijit/tests/test_TitlePane.html
index db9292b..2383a11 100644
--- a/dijit/tests/test_TitlePane.html
+++ b/dijit/tests/test_TitlePane.html
@@ -35,21 +35,21 @@
 			return Math.floor(Math.random() * 3) + 3;
 		}
 
-	    dojo.addOnLoad(function() {
+	    dojo.ready(function(){
 	
 			dojo.declare("dijit.TestTitlePane", dijit.TitlePane, {
 				templateString: '<div class="dijitTitlePane">' +
-								'    <div class="dijitTitlePaneTitle" dojoAttachPoint="titleBarNode" style="cursor: default;">' +
-								        '<span dojoAttachEvent="onclick:toggle,onkeypress: _onTitleKey" tabindex="0"' +
-								                'role="button" dojoAttachPoint="focusNode,arrowNode" style="cursor: pointer;">' +
+								'    <div class="dijitTitlePaneTitle" data-dojo-attach-point="titleBarNode" style="cursor: default;">' +
+								        '<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"/>' +
-											'<span dojoAttachPoint="arrowNodeInner" class="dijitArrowNodeInner"></span>' +
+											'<span data-dojo-attach-point="arrowNodeInner" class="dijitArrowNodeInner"></span>' +
 										 '</span>' +
-								        '<span dojoAttachPoint="titleNode" class="dijitTitlePaneTextNode"></span>' +
+								        '<span data-dojo-attach-point="titleNode" class="dijitTitlePaneTextNode"></span>' +
 								    '</div>' +
-								    '<div class="dijitTitlePaneContentOuter" dojoAttachPoint="hideNode">' +
-								        '<div class="dijitReset" dojoAttachPoint="wipeNode">' +
-								            '<div class="dijitTitlePaneContentInner" dojoAttachPoint="containerNode" role="region" tabindex="-1">' +
+								    '<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>' +
 								        '</div>' +
 								    '</div>' +
diff --git a/dijit/tests/test_Toolbar.html b/dijit/tests/test_Toolbar.html
index a601fc0..3d780d8 100644
--- a/dijit/tests/test_Toolbar.html
+++ b/dijit/tests/test_Toolbar.html
@@ -34,11 +34,13 @@
 		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.addOnLoad(function(){
+		dojo.ready(function(){
 			// programatic creation
 			dojo.forEach(["toolbar2", "toolbar3", "toolbar4"], function(toolbarId){
 				var toolbar = new dijit.Toolbar({}, dojo.byId(toolbarId));
@@ -48,7 +50,7 @@
                         // note: should always specify a label, for accessibility reasons.
                         // Just set showLabel=false if you don't want it to be displayed normally
                         label: label,
-                        showLabel: (toolbarId == "toolbar2" ? false : true),
+                        showLabel: (toolbarId != "toolbar2"),
                         iconClass: toolbarId == "toolbar4" ? "" : "dijitEditorIcon dijitEditorIcon"+label
                     });
                     toolbar.addChild(button);
diff --git a/dijit/tests/test_Tooltip.html b/dijit/tests/test_Tooltip.html
index 2a04d7e..88c84f3 100644
--- a/dijit/tests/test_Tooltip.html
+++ b/dijit/tests/test_Tooltip.html
@@ -22,11 +22,18 @@
 	<script type="text/javascript" src="_testCommon.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dojo.parser");
+
 		dojo.require("dijit.Tooltip");
 		dojo.require("dijit.ColorPalette");
 		dojo.require("dijit.form.DateTextBox");
-		dojo.addOnLoad(function(){
+
+		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"]});
 			console.log("created", tt, tt.id);
@@ -76,7 +83,7 @@
 		</tr>
 		<tr>
 			<td>
-				<button onclick="dijit.Tooltip.defaultPosition=['above', 'below']; dojo.byId('current').innerHTML='Current: ' + dijit.Tooltip.defaultPosition;">above, below</button>
+				<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>
 				<div id=current>
 					Current: default (unchanged)
@@ -90,6 +97,28 @@
 			</td>
 		</tr>
 	</table>
+
+	<label for="ddb">Drop down menu items have tooltips:</label>
+	<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",
+				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",
+				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",
+				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>
+
+	<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"/>
 	<div>
 		<span id="one" class="tt" tabindex="0"> focusable text </span>
diff --git a/dijit/tests/test_TooltipDialog.html b/dijit/tests/test_TooltipDialog.html
index ea068e7..af1f9c8 100644
--- a/dijit/tests/test_TooltipDialog.html
+++ b/dijit/tests/test_TooltipDialog.html
@@ -41,26 +41,35 @@
 	<script type="text/javascript" src="_testCommon.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		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");
+
 		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.addOnLoad(function(){
+		dojo.ready(function(){
 			// create a do nothing, only for test widget
 			dojo.declare("dijit.TestWidget",
-				[dijit._Widget, dijit._Templated], {
+				[dijit._Widget, dijit._TemplatedMixin], {
 				templateString: "<div style='margin: 10px; border: inset #700 4px; padding: 5px;' dojoAttachPoint='containerNode'></div>"
 			});
 
@@ -195,7 +204,7 @@
 		</div>
 	</div> |
 
-	<div 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",
 			title:"tooltip dialog with no focusable items"'></div>
diff --git a/dijit/tests/test_UIWindowIssue_child.html b/dijit/tests/test_UIWindowIssue_child.html
new file mode 100644
index 0000000..a4b5dd9
--- /dev/null
+++ b/dijit/tests/test_UIWindowIssue_child.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Focus Issue Child</title>
+	<script>
+	// open the parent, if user tries to open the child directly
+	if (parent == window)
+		location.href = './test_UIWindowIssue_main.html';
+	</script>
+	<script type="text/javascript" src="../../dojo/dojo.js"
+		data-dojo-config="parseOnLoad:false, isDebug:true"></script>
+	<script type="text/javascript">
+		dojo.require("dojo.parser");
+		dojo.require("dijit.Menu");
+		dojo.require("dijit.MenuItem");
+		dojo.require("dijit.PopupMenuItem");
+		dojo.require("dijit.CheckedMenuItem");
+		dojo.require("dijit.MenuSeparator");
+
+		// set objects in parent
+		for (var v in {'dijit':true, 'dojo':true, 'dojox':true})
+			parent[v] = window[v];
+
+		// set context
+		dojo.setContext(window, parent.document);
+		
+		// fix focus issue
+		dojo.ready(function(){
+			var handle = dijit.registerWin(dojo.doc.parentWindow || dojo.doc.defaultView);
+			if(dojo.isIE){
+				dojo.addOnWindowUnload(function(){
+					dijit.unregisterWin(handle);
+					handle = null;
+				})
+			}
+		});
+
+		// parse the UI frame
+		dojo.parser.parse();
+
+	</script>
+</head>
+<body bgcolor="#e0e0e0">
+	this frame is for loading script only
+</body>
+</html>
diff --git a/dijit/tests/test_UIWindowIssue_main.html b/dijit/tests/test_UIWindowIssue_main.html
new file mode 100644
index 0000000..e34f053
--- /dev/null
+++ b/dijit/tests/test_UIWindowIssue_main.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Focus Issue</title>
+	<style type="text/css">
+		@import "../themes/claro/claro.css";
+	</style>
+</head>
+<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",
+			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",
+			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",
+			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" >
+			<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" >
+					<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>
+				</div>
+			</div>
+		</div>
+		<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>
+		</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">
+			<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>
+		</div>
+	</div>
+
+	<p>To test:
+	<ul>
+	<li>Right mouse click anywhere on the page to see the context menu</li>
+	<li>Mouse-over "Enabled Submenu"</li>
+	<li>Make sure the submenu is positioned properly</li>
+	</ul>
+	</p>
+</body>
+</html>
diff --git a/dijit/tests/tree/CustomLabel.html b/dijit/tests/tree/CustomLabel.html
index a006f20..c669260 100644
--- a/dijit/tests/tree/CustomLabel.html
+++ b/dijit/tests/tree/CustomLabel.html
@@ -27,7 +27,7 @@
 		dojo.require("dijit.tree.ForestStoreModel");
 		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 		
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			doh.register("Test custom label",
 				[
 					{
diff --git a/dijit/tests/tree/Tree.html b/dijit/tests/tree/Tree.html
index aac5dcd..410f282 100644
--- a/dijit/tests/tree/Tree.html
+++ b/dijit/tests/tree/Tree.html
@@ -33,16 +33,16 @@
 		dojo.require("dijit.tree.TreeStoreModel");
 		dojo.require("dijit.tree.dndSource");
 		
-		function getRowClass(item, isExpanded) {
-			if (!item
+		function getRowClass(item, isExpanded){
+			if(!item
 					|| !treeStore.isItem(item)
-					|| treeStore.getValue(item, "type") != "header") {
+					|| treeStore.getValue(item, "type") != "header"){
 				return null;
 			}
 			return "headerRow";
 		}
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			doh.register("parse", function(){
 				dojo.parser.parse();
 			});
@@ -277,7 +277,7 @@
 							// but this is enough for testing
 							myStore.setValue(item, 'type', 'country');
 						}
-					})
+					});
 
 					var children = myTree.rootNode.getChildren();
 					doh.is(5, children.length, "five children again");
@@ -294,7 +294,7 @@
 							// but this is enough for testing
 							myStore.setValue(item, 'type', 'continent');
 						}
-					})
+					});
 
 					var children = myTree.rootNode.getChildren();
 					doh.is(6, children.length, "six children again");
@@ -339,6 +339,49 @@
 				}
 			]);
 
+			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>
diff --git a/dijit/tests/tree/Tree_with_JRS.html b/dijit/tests/tree/Tree_with_JRS.html
index ab26006..39d7655 100644
--- a/dijit/tests/tree/Tree_with_JRS.html
+++ b/dijit/tests/tree/Tree_with_JRS.html
@@ -32,7 +32,7 @@
 		dojo.require("dijit.tree.ForestStoreModel");
 		dojo.require("dijit.tree.dndSource");
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			var handler, myTree;
 
 			doh.register("parse", function(){
diff --git a/dijit/tests/tree/module.js b/dijit/tests/tree/module.js
index 5ce348e..44f1d38 100644
--- a/dijit/tests/tree/module.js
+++ b/dijit/tests/tree/module.js
@@ -6,8 +6,6 @@ try{
 
 	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);
-	
-	// comment out until #11621 is fixed
 	doh.registerUrl("dijit.tests.tree.Tree_with_JRS", dojo.moduleUrl("dijit", "tests/tree/Tree_with_JRS.html"), 999999);
 
 	if(test_robot){
@@ -21,4 +19,4 @@ try{
 	}
 }catch(e){
 	doh.debug(e);
-}
\ No newline at end of file
+}
diff --git a/dijit/tests/tree/robot/Tree_a11y.html b/dijit/tests/tree/robot/Tree_a11y.html
index 2da2f45..824bf21 100644
--- a/dijit/tests/tree/robot/Tree_a11y.html
+++ b/dijit/tests/tree/robot/Tree_a11y.html
@@ -9,8 +9,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"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.robotx");
@@ -35,7 +34,7 @@
 			that.testTreeItemRole = function(/*dijit._TreeNode*/inRoot, /*dijit.Tree*/inTree){
 				if(inRoot){
 					var expectedrole = inTree.showRoot || inRoot!==inTree.rootNode ? 'treeitem' : 'presentation';
-					doh.is(expectedrole, dijit.getWaiRole(inRoot.labelNode), inRoot.label + "[" + inTree.id + "]: aria role (" + expectedrole + ")");
+					doh.is(expectedrole, inRoot.labelNode.getAttribute("role"), inRoot.label + "[" + inTree.id + "]: aria role (" + expectedrole + ")");
 					//recurse
 					forceLoadChildItems(inRoot, inTree);
 					var children = inRoot.getChildren();
@@ -50,16 +49,16 @@
 					if(inItem.isExpandable){
 						var wasExpanded = inItem.isExpanded;
 						inTree._expandNode(inItem);
-						var nowExpanded = dijit.getWaiState(inItem.labelNode, "expanded");
+						var nowExpanded = inItem.labelNode.getAttribute("aria-expanded");
 						inTree._collapseNode(inItem);
-						var nowCollapsed = dijit.getWaiState(inItem.labelNode, "expanded");
+						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("", dijit.getWaiState(inItem.labelNode, "expanded"), inItem.label + "[" + inTree.id + "]: aria state expanded=false");
+						doh.is(null, inItem.labelNode.getAttribute("aria-expanded"), inItem.label + "[" + inTree.id + "]: aria state expanded=false");
 					}
 				}
 			};
@@ -105,7 +104,7 @@
 
 			var walkTreeToLeaf = function(inTree, inRootNode, /*array, optional*/ioPath){
 				var leaf = inRootNode;
-				if (ioPath){ ioPath.push(inRootNode); }
+				if(ioPath){ ioPath.push(inRootNode); }
 				if(inRootNode.isExpandable){
 					forceLoadChildItems(inRootNode, inTree);
 					inTree._expandNode(inRootNode);
@@ -267,7 +266,7 @@
 				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++) {
+				for(var i = 0; i < arrowDownCount; i++){
 					doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);
 				}
 				for(i = 0; i < arrowRightCount; i++){
@@ -315,7 +314,7 @@
 				var checkAtHomeEnd = function(){
 					tree.disconnect(focusConnect);
 					doh.is(expectedNode.label, actualNode.innerHTML);
-				}
+				};
 				doh.robot.sequence(d.getTestCallback(checkAtHomeEnd), 500);
 				return d;
 			};
@@ -323,7 +322,7 @@
 			return that;
 		}
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			doh.robot.initRobot('../test_Tree.html');
 			var treeTest = treeTests();
 
@@ -331,7 +330,7 @@
 				timeout:20000,
 				runTest:function(){
 					var d = new doh.Deferred();
-					var store = dojo.global.dijit.byId('mytree3').get('store');
+					var store = dijit.byId('mytree3').get('store');
 					store.fetch({query:{id:'*'}, onComplete:function(){
 						d.callback(true);
 					}});
@@ -345,7 +344,7 @@
 				function ariaTreeRole(){
 					for(i=0; i<treeIds.length; i++){
 						var tree = dijit.byId(treeIds[i]), expectedrole = tree.showRoot?'tree':'presentation';
-						doh.is(expectedrole, dijit.getWaiRole(tree.domNode), tree.id + ": aria role (" + expectedrole + ")");
+						doh.is(expectedrole, tree.domNode.getAttribute("role"), tree.id + ": aria role (" + expectedrole + ")");
 					}
 				},
 
@@ -354,9 +353,9 @@
 						var tree = dijit.byId(treeIds[i]);
 						var wasExpanded = tree.rootNode.isExpanded;
 						tree.rootNode.expand();
-						var nowExpanded = dijit.getWaiState(tree.domNode, "expanded");
+						var nowExpanded = tree.domNode.getAttribute("aria-expanded");
 						tree.rootNode.collapse();
-						var nowCollapsed = dijit.getWaiState(tree.domNode, "expanded");
+						var nowCollapsed = tree.domNode.getAttribute("aria-expanded");
 						if(wasExpanded){
 							tree.rootNode.expand();
 						}
@@ -571,7 +570,7 @@
 						tree.focusNode(tree.rootNode);
 
 						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dojo.global.dijit._curFocus;
+							var focus = dojo.global.dijit.focus.curNode;
 							doh.t(tree.rootNode.labelNode, "focused on continents");
 						}), 500);
 
@@ -587,7 +586,7 @@
 						// 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._curFocus);
+							var focus = dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode);
 							doh.t(focus, "there is a focused widget");
 							doh.is("Africa", focus.label);
 						}), 500);
@@ -604,7 +603,7 @@
 						// 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._curFocus);
+							var focus = dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode);
 							doh.t(focus, "there is a focused widget");
 							doh.is("Asia", focus.label);
 						}), 500);
@@ -624,7 +623,7 @@
 
 						doh.robot.keyPress("a", 100);
 						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
+							var focus = dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode);
 							doh.t(focus, "there is a focused widget");
 							doh.is("Australia", focus.label);
 						}), 500);
@@ -640,7 +639,7 @@
 
 						doh.robot.keyPress("a", 100);
 						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
+							var focus = dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode);
 							doh.t(focus, "there is a focused widget");
 							doh.is("Africa", focus.label);
 						}), 500);
@@ -657,7 +656,7 @@
 						// 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._curFocus);
+							var focus = dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode);
 							doh.t(focus, "there is a focused widget");
 							doh.is("Continents", focus.label);
 						}), 500);
@@ -674,7 +673,7 @@
 						// 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._curFocus);
+							var focus = dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode);
 							doh.t(focus, "there is a focused widget");
 							doh.is("Asia", focus.label);
 						}), 500);
@@ -692,7 +691,7 @@
 						// start a new search
 						doh.robot.typeKeys("n", 100);
 						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
+							var focus = dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode);
 							doh.t(focus, "there is a focused widget");
 							doh.is("North America", focus.label);
 						}), 500);
diff --git a/dijit/tests/tree/robot/Tree_dnd.html b/dijit/tests/tree/robot/Tree_dnd.html
index de67c46..ee6517b 100644
--- a/dijit/tests/tree/robot/Tree_dnd.html
+++ b/dijit/tests/tree/robot/Tree_dnd.html
@@ -9,8 +9,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"></script>
 
 		<!-- functions to help test -->
 		<script type="text/javascript" src="../../helpers.js"></script>
@@ -20,7 +19,7 @@
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Tree_DnD.html');
 
 				setup();
@@ -82,7 +81,7 @@
 
 								doh.t(fruitsTreeNode.isExpanded, "drop caused the node to expand");
 								var treeNodeChildren = fruitsTreeNode.getChildren();
-								doh.is(2, treeNodeChildren.length, "2 TreeNode children")
+								doh.is(2, treeNodeChildren.length, "2 TreeNode children");
 								doh.is("Apple", innerText(treeNodeChildren[0].labelNode));
 								doh.is("Citrus", innerText(treeNodeChildren[1].labelNode));
 							}), 1000);	// 1000ms to wait for 'Fruits' node to expand and show 'Apple' node
@@ -103,7 +102,7 @@
 								fruitsTreeNode = findTreeNode("itemTree", "Fruits"),
 								appleTreeNode = findTreeNode("itemTree", "Apple"),
 								citrusTreeNode = findTreeNode("itemTree", "Citrus");
-							dijit.scrollIntoView("itemTree");
+							dojo.window.scrollIntoView("itemTree");
 							// Drag "Apple" into "Citrus".
 							doh.robot.mouseMoveAt(appleTreeNode.labelNode, 500, 1);
 							doh.robot.mousePress({left: true}, 500);
@@ -122,7 +121,7 @@
 								var fruitsTreeNode = findTreeNode("itemTree", "Fruits");
 
 								var fruitsTreeNodeChildren = fruitsTreeNode.getChildren();
-								doh.is(1, fruitsTreeNodeChildren.length, "1 TreeNode children")
+								doh.is(1, fruitsTreeNodeChildren.length, "1 TreeNode children");
 								doh.is("Citrus", innerText(fruitsTreeNodeChildren[0].labelNode));
 
 								// ... and parented to Citrus item
@@ -135,7 +134,7 @@
 								var citrusTreeNode = findTreeNode("itemTree", "Citrus");
 
 								var citrusTreeNodeChildren = citrusTreeNode.getChildren();
-								doh.is(2, citrusTreeNodeChildren.length, "2 TreeNode children for Citrus")
+								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");
 							}), 2000);
@@ -179,7 +178,7 @@
 								var
 									foodsTreeNode = findTreeNode("collectionsTree", "Foods (1)"),
 									foodsTreeNodeChildren = foodsTreeNode.getChildren();
-								doh.is(3, foodsTreeNodeChildren.length, "3 TreeNode children")
+								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));
@@ -248,13 +247,13 @@
 								var
 									foodsTreeNode = findTreeNode("collectionsTree", "Foods (1)"),
 									foodsTreeNodeChildren = foodsTreeNode.getChildren();
-								doh.is(2, foodsTreeNodeChildren.length, "2 TreeNode children for foods")
+								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));
 
 								var fruitsTreeNode = findTreeNode("collectionsTree", "Fruits (2)"),
 								fruitsTreeNodeChildren = fruitsTreeNode.getChildren();
-								doh.is(2, fruitsTreeNodeChildren.length, "2 TreeNode children for fruits")
+								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));
 							}), 500);
@@ -367,7 +366,7 @@
 								// Check that data store update was reflected in the tree
 								var citrusTreeNode = findTreeNode("itemTree", "Citrus");
 								var treeNodeChildren = citrusTreeNode.getChildren();
-								doh.is(3, treeNodeChildren.length, "3 TreeNode children")
+								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));
@@ -396,7 +395,7 @@
 								// Check that data store update was reflected in the tree
 								var citrusTreeNode = findTreeNode("itemTree", "Citrus");
 								var treeNodeChildren = citrusTreeNode.getChildren();
-								doh.is(4, treeNodeChildren.length, "4 TreeNode children")
+								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));
@@ -427,7 +426,7 @@
 								// Check that data store update was reflected in the tree
 								var citrusTreeNode = findTreeNode("itemTree", "Citrus");
 								var treeNodeChildren = citrusTreeNode.getChildren();
-								doh.is(5, treeNodeChildren.length, "5 TreeNode children")
+								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));
@@ -460,7 +459,7 @@
 								// Check that data store update was reflected in the tree
 								var citrusTreeNode = findTreeNode("itemTree", "Citrus");
 								var treeNodeChildren = citrusTreeNode.getChildren();
-								doh.is(6, treeNodeChildren.length, "6 TreeNode children")
+								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));
@@ -495,7 +494,7 @@
 								// Check that data store update was reflected in the tree
 								var citrusTreeNode = findTreeNode("itemTree", "Citrus");
 								var treeNodeChildren = citrusTreeNode.getChildren();
-								doh.is(7, treeNodeChildren.length, "7 TreeNode children")
+								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));
@@ -532,7 +531,7 @@
 								// Check that data store update was reflected in the tree
 								var citrusTreeNode = findTreeNode("itemTree", "Citrus");
 								var treeNodeChildren = citrusTreeNode.getChildren();
-								doh.is(8, treeNodeChildren.length, "8 TreeNode children")
+								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));
@@ -695,7 +694,6 @@
 						}
 					}
 				]);
-				// TODO: test icon and highlighting when valid drop target and invalid target (another item)
 
 				doh.run();
 			});
diff --git a/dijit/tests/tree/robot/Tree_dnd_multiParent.html b/dijit/tests/tree/robot/Tree_dnd_multiParent.html
index e582b8d..f3b6a81 100644
--- a/dijit/tests/tree/robot/Tree_dnd_multiParent.html
+++ b/dijit/tests/tree/robot/Tree_dnd_multiParent.html
@@ -9,8 +9,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"></script>
 
 		<!-- functions to help test -->
 		<script type="text/javascript" src="../../helpers.js"></script>
@@ -20,7 +19,7 @@
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Tree_DnD.html');
 
 				setup();
@@ -69,10 +68,10 @@
 								doh.is("Cereals", children.categories[2]);
 
 								// Check that Vegetables added as child of Fruits
-								var children = getNamesOfChildrenOfItem("Fruits");
-								doh.is(2, children.categories.length, "foods category child");
-								doh.is("Citrus", children.categories[0]);
-								doh.is("Vegetables", children.categories[1]);
+								var children2 = 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;
@@ -84,7 +83,7 @@
 								// Check that data store update was reflected in the tree
 								doh.t(fruitsTreeNode.isExpanded, "drop caused the node to expand");
 								var treeNodeChildren = fruitsTreeNode.getChildren();
-								doh.is(2, treeNodeChildren.length, "2 TreeNode children")
+								doh.is(2, treeNodeChildren.length, "2 TreeNode children");
 								doh.is("Citrus", innerText(treeNodeChildren[0].labelNode));
 								doh.is("Vegetables", innerText(treeNodeChildren[1].labelNode));
 							}), 1000);	// 1000ms to wait for 'Fruits' node to expand and show 'Apple' node
@@ -247,10 +246,10 @@
 								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 children = getChildrenOfItem("Fruits");
-								doh.is(1, children.items.length, "banana still a child of fruits");
-								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");
+								var children2 = 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({
 									query: { name: "Banana" },
@@ -265,6 +264,52 @@
 					}
 				]);
 
+				doh.register("illegal drop", [
+					// This tests dropping a node onto another node when both nodes represent the same item.
+					{
+						name: "try to drop Vegetables as child of Vegetables",
+						timeout: 10000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								drag = findTreeNodeByPath("itemTree", ["Cereals", "Vegetables"]),
+								aboveDrop = findTreeNodeByPath("itemTree", ["Fruits", "Citrus"]);
+								drop = 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);
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								var avatar = dojo.query(".dojoDndAvatar");
+								doh.t(avatar && avatar[0], "avatar found");
+								doh.t(dojo.hasClass(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");
+								doh.t(avatar && avatar[0], "avatar found");
+								doh.f(dojo.hasClass(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(){
+								doh.is(0, drop.getChildren().length, "drop node has no children");
+								doh.t(drag == findTreeNodeByPath("itemTree", ["Cereals", "Vegetables"]),
+										"drag node still in same place");
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/tree/robot/Tree_selector.html b/dijit/tests/tree/robot/Tree_selector.html
index 58c68de..b44b4a2 100644
--- a/dijit/tests/tree/robot/Tree_selector.html
+++ b/dijit/tests/tree/robot/Tree_selector.html
@@ -9,8 +9,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"></script>
 
 		<!-- functions to help test -->
 		<script type="text/javascript" src="../../helpers.js"></script>
@@ -31,7 +30,7 @@
 				}
 			}
 
-			function pressEnter(modifiers) {
+			function pressEnter(modifiers){
 				var i;
 				for(i = 0; i < modifiers.length; i++){
 					doh.robot.keyDown(modifiers[i], 250);
@@ -46,14 +45,14 @@
 					doh.robot.keyUp(modifiers[i], 250);
 				}
 			}
-			function mouseSelect(tree, item, modifiers, k) {
+			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) {
+			function keyboardSelect(tree, item, modifiers, k){
 				var focused = dojo.query("#itemTree .dijitTreeLabelFocused");
-				if(!(focused.length > 0)) {
+				if(!(focused.length > 0)){
 					doh.robot.keyPress(dojo.keys.TAB, 250);
 					doh.robot.sequence(function(){ keyboardSelect(tree, item, modifiers, k); }, 250);
 					return;
@@ -61,19 +60,18 @@
 				
 				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) {
+				if(diff != 0){
+					if(diff > 0){
 						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
-					} else {
+					}else{
 						doh.robot.keyPress(dojo.keys.UP_ARROW, 500);
 					}
-				} else {
+				}else{
 					pressEnter(modifiers);
 					doh.robot.sequence(k);
 					return;
 				}
 				doh.robot.sequence(function(){ keyboardSelect(tree, item, modifiers, k); }, 500);
-				return;
             }
 			
 			function getSelected(tree){
@@ -111,7 +109,7 @@
 				});
 				return d;
 			}
-			function testCtrlSelect(selector, clicker) {
+			function testCtrlSelect(selector, clicker){
 				var d = new doh.Deferred();
 				
 				// Find the fruitsTreeNode category
@@ -121,7 +119,7 @@
 				// select fruit item
 				selector(tree, fruitsTreeNode, [], function(){
 					doh.robot.sequence(function(){
-						dijit.scrollIntoView("itemTree");
+						dojo.window.scrollIntoView("itemTree");
 					}, 500);
 					
 					// ctrl-click Cereals item
@@ -152,7 +150,7 @@
 					// select fruit item (no modifiers)
 					selector(tree, fruitsTreeNode, [], atFruits);
 
-					function atFruits() {
+					function atFruits(){
 						// shift-select Cereals item
                         selector(tree, cerealsTreeNode, keys, atCereals);
 					}
@@ -184,7 +182,7 @@
 					return d;
 				};
 			}
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				var controller = '', ind=window.location.href.indexOf("?controller=");
 				
 				if(ind > -1){
diff --git a/dijit/tests/tree/robot/Tree_v1.html b/dijit/tests/tree/robot/Tree_v1.html
index cbb77cb..1512512 100644
--- a/dijit/tests/tree/robot/Tree_v1.html
+++ b/dijit/tests/tree/robot/Tree_v1.html
@@ -9,15 +9,14 @@
 		</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"></script>
 
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_Tree_v1.html');
 
 				doh.register("setup",{
@@ -244,11 +243,14 @@
 							
 							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);
 
diff --git a/dijit/tests/tree/test_Tree.html b/dijit/tests/tree/test_Tree.html
index 3d3efd6..3ecaeac 100644
--- a/dijit/tests/tree/test_Tree.html
+++ b/dijit/tests/tree/test_Tree.html
@@ -22,10 +22,16 @@
 	<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
 	</script>
 
@@ -151,7 +157,7 @@
 			}
 		</script>
 		<script type="dojo/method" data-dojo-event="getIconClass" data-dojo-args="item, opened">
-	       if (!item || continentStore.getValue(item, "type") != "continent")
+	       if(!item || continentStore.getValue(item, "type") != "continent")
 				return (!item || this.model.mayHaveChildren(item)) ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "dijitLeaf"
 	       	else
 	       		return "";
diff --git a/dijit/tests/tree/test_Tree_DnD.html b/dijit/tests/tree/test_Tree_DnD.html
index fa9b2fc..b924716 100644
--- a/dijit/tests/tree/test_Tree_DnD.html
+++ b/dijit/tests/tree/test_Tree_DnD.html
@@ -48,7 +48,7 @@
 		globalId=1000;
 		lastSelected=null;
 
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 
 			//record the selection from tree 1
 			dojo.subscribe("myTree", null, function(message){
@@ -80,7 +80,7 @@
 			//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){
 				var p = pInfo && pInfo.item;
-				if (p) {
+				if(p){
 					var currentTotal = myStore.getValues(p, "numberOfItems")[0];
 					myStore.setValue(p, "numberOfItems", ++currentTotal);
 				}
@@ -97,37 +97,29 @@
 		}
 
 		//on item tree , we want to drop on containers, the root node itself, or between items in the containers
-		function itemTreeCheckItemAcceptance(node,source,position) {
+		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"))){
+			if(item && (item.root || myStore.hasAttribute(item,"numberOfItems"))){
 				return true;
 			}
-			if (position != "over") {
-				return true;
-			}
-			return false;
+			return position != "over";
+
 		}
 
 		//on collection tree, only accept itself as the source tree
-		function collectionTreeCheckItemAcceptance(node,source,position) {
-			if(source.tree && source.tree.id == "collectionsTree"){
-				return true;
-			}
-			return false;
+		function collectionTreeCheckItemAcceptance(node,source,position){
+			return source.tree && source.tree.id == "collectionsTree";
 		}
 
 		function dndAccept(source,nodes){
-			if (this.tree.id=="myTree"){
-				return false;
-			}
-			return true;
+			return this.tree.id != "myTree";
 		}
 
-		function getIcon(item) {
-			if (!item || myStore.hasAttribute(item, "numberOfItems")) {
+		function getIcon(item){
+			if(!item || myStore.hasAttribute(item, "numberOfItems")){
 				return "myFolder";
 			}
 			return "myItem"
@@ -155,7 +147,7 @@
 
 	<div data-dojo-id="myStore" data-dojo-type="dojo.data.ItemFileWriteStore" data-dojo-props='url:"../_data/categories.json"'></div>
 
-	<table style="margin:5px solid gray;width:100%;" >
+	<table style="margin:5px; width:100%;" >
 
 	<tr style="width:100%">
 		<td style="width: 50%">
diff --git a/dijit/tests/tree/test_Tree_v1.html b/dijit/tests/tree/test_Tree_v1.html
index c9178c2..78a6fc7 100644
--- a/dijit/tests/tree/test_Tree_v1.html
+++ b/dijit/tests/tree/test_Tree_v1.html
@@ -26,6 +26,8 @@
 		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>
diff --git a/dijit/themes/claro/Calendar.css b/dijit/themes/claro/Calendar.css
index ff8e64f..a0f9597 100644
--- a/dijit/themes/claro/Calendar.css
+++ b/dijit/themes/claro/Calendar.css
@@ -41,6 +41,7 @@
   padding: 6px 5px 3px 5px;
   -moz-border-radius: 4px;
   border-radius: 4px;
+  border-collapse: separate;
 }
 .dj_ie6 .claro .dijitCalendar {
   background-image: none;
@@ -48,13 +49,13 @@
 .claro .dijitCalendar img {
   border: none;
 }
-.claro .dijitCalendarHover, .claro .dijitCalendarActive {
+.claro .dijitCalendarHover, .claro .dijitCalendar:hover, .claro .dijitCalendarActive {
   /* treat dijitCalenderActive like hover since there's
 	 * no concept of clicking a Calendar as a whole (although you can click things inside the calendar)
 	 */
 
   background-color: #abd6ff;
-  border: solid 1px #769dc0;
+  border: solid 1px #759dc0;
 }
 .claro .dijitCalendarMonthContainer th {
   text-align: center;
@@ -79,16 +80,16 @@
 .claro .dijitCalendarIncrease {
   background-position: -18px 0;
 }
-.claro .dijitCalendarArrowHover .dijitCalendarDecrease {
+.claro .dijitCalendarArrowHover .dijitCalendarDecrease, .claro .dijitCalendarArrow:hover .dijitCalendarDecrease {
   background-position: -36px 0;
 }
-.claro .dijitCalendarArrowHover .dijitCalendarIncrease {
+.claro .dijitCalendarArrowHover .dijitCalendarIncrease, .claro .dijitCalendarArrow:hover .dijitCalendarIncrease {
   background-position: -55px 0;
 }
-.claro .dijitCalendarArrowActive .dijitCalendarDecrease {
+.claro .dijitCalendarArrowActive .dijitCalendarDecrease, .claro .dijitCalendarArrow:active .dijitCalendarDecrease {
   background-position: -72px 0;
 }
-.claro .dijitCalendarArrowActive .dijitCalendarIncrease {
+.claro .dijitCalendarArrowActive .dijitCalendarIncrease, .claro .dijitCalendarArrow:active .dijitCalendarIncrease {
   background-position: -91px 0;
 }
 .claro .dijitA11ySideArrow {
@@ -96,18 +97,19 @@
 
   display: none;
 }
-.claro .dijitDayLabels th {
-  padding: 0 4px 0 4px;
-  font-weight: bold;
-  text-align: center;
-}
 .claro .dijitCalendarDayLabelTemplate {
   padding-bottom: 0;
   text-align: center;
   border-bottom: 1px solid #b5bcc7;
-  font-size: 0.909em;
   padding: 0 3px 2px;
 }
+.claro .dijitCalendarDayLabel {
+  padding: 0 4px 0 4px;
+  font-weight: bold;
+  font-size: 0.909em;
+  text-align: center;
+  color: #000000;
+}
 .claro .dijitCalendarDateTemplate {
   text-align: center;
   background-color: #ffffff;
@@ -121,12 +123,13 @@
   font-weight: bold;
   letter-spacing: .05em;
   text-align: center;
+  color: #000000;
 }
 .dj_ie6 .claro .dijitCalendarDateTemplate {
   background-image: none;
 }
 .claro .dijitCalendarPreviousMonth, .claro .dijitCalendarNextMonth {
-  background-color: #e9f4fe;
+  background-color: #e5f2fe;
   background-image: none;
   border-bottom: solid 1px #d3d3d3;
   /* todo: redundant with above .dijitCalendarDateTemplate rule */
@@ -149,8 +152,8 @@
   transition-duration: 0.35s;
 }
 .claro .dijitCalendarPreviousMonth .dijitCalendarDateLabel, .claro .dijitCalendarNextMonth .dijitCalendarDateLabel {
-  color: #769dc0;
-  border-color: #e9f4fe;
+  color: #759dc0;
+  border-color: #e5f2fe;
   /* intentionally matches background-color, no visible border until hover/selection */
 
 }
@@ -163,6 +166,7 @@
 .claro .dijitCalendarYearLabel {
   padding: 2px 0 0 0;
   margin: 0;
+  font-size: 1.17em;
 }
 .claro .dijitCalendarYearLabel span {
   /* trying to center next/current/previous year vertically, doesn't work on IE6/7 though */
@@ -182,35 +186,38 @@
 }
 /* End Normal Calendar Style */
 /* Hovered Calendar Style */
-.claro .dijitCalendarHoveredDate .dijitCalendarDateLabel {
+.claro .dijitCalendarHoveredDate .dijitCalendarDateLabel, .claro .dijitCalendarEnabledDate:hover .dijitCalendarDateLabel {
   background-color: #abd6ff;
-  border: solid 1px #769dc0;
+  border: solid 1px #759dc0;
   color: #000000;
   -webkit-transition-duration: 0.2s;
   -moz-transition-duration: 0.2s;
   transition-duration: 0.2s;
 }
-.claro .dijitCalendarNextYearHover, .claro .dijitCalendarPreviousYearHover {
+.claro .dijitCalendarNextYearHover,
+.claro .dijitCalendarNextYear:hover,
+.claro .dijitCalendarPreviousYearHover,
+.claro .dijitCalendarPreviousYear:hover {
   color: #000000;
   border: solid 1px #ffffff;
   padding: 0 5px 0 5px;
   /* reduced by 1 to make room for border */
 
-  background-color: #e9f4fe;
+  background-color: #e5f2fe;
 }
 /* End Hovered Calendar Style */
 /* Active Calendar Style */
-.claro .dijitCalendarNextYearActive, .claro .dijitCalendarPreviousYearActive {
-  border: solid 1px #769dc0;
+.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: #cfe5fa;
+  background-color: #7dbdfa;
 }
-.claro .dijitCalendarActiveDate .dijitCalendarDateLabel {
+.claro .dijitCalendarActiveDate .dijitCalendarDateLabel, .claro .dijitCalendarEnabledDate:active .dijitCalendarDateLabel {
   background-image: url("images/calendarContainerImages.png");
   background-position: 0 -300px;
-  background-color: #7dbefa;
+  background-color: #7dbdfa;
   border: solid 1px #ffffff;
   -webkit-transition-duration: 0.1s;
   -moz-transition-duration: 0.1s;
@@ -224,18 +231,13 @@
 .claro .dijitCalendarSelectedDate .dijitCalendarDateLabel {
   color: #000000;
   background-color: #abd6ff;
-  border-color: #769dc0;
+  border-color: #759dc0;
 }
 /* End Selected Calendar Style */
 /* Disabled Calendar Style*/
 .claro .dijitCalendarDisabledDate .dijitCalendarDateLabel {
-  text-decoration: line-through;
-  /* override hover effects above, hover and click on disabled date should have no effect */
-
-  background-color: transparent;
-  border-width: 0;
-  padding: 4px 6px 4px 5px;
   color: #818181;
+  text-decoration: line-through;
 }
 /* End Disabled Calendar Style */
 /* Styling for month DropDownButton */
@@ -255,13 +257,13 @@
   -moz-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
   box-shadow: 0 0 0 rgba(0, 0, 0, 0);
 }
-.claro .dijitCalendar .dijitDropDownButtonHover .dijitButtonNode {
-  background-color: #e9f4fe;
+.claro .dijitCalendar .dijitDropDownButtonHover .dijitButtonNode, .claro .dijitCalendar .dijitDropDownButton:hover .dijitButtonNode {
+  background-color: #e5f2fe;
   border: solid 1px #ffffff;
 }
 /* Styling for month drop down list */
 .claro .dijitCalendarMonthMenu {
-  border-color: #769dc0;
+  border-color: #759dc0;
   background-color: #ffffff;
   text-align: center;
   background-image: none;
@@ -273,9 +275,9 @@
   border-bottom: solid 1px #ffffff;
   padding: 2px 0;
 }
-.claro .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover {
+.claro .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover, .claro .dijitCalendarMonthMenu .dijitCalendarMonthLabel:hover {
   background-color: #abd6ff;
-  border-color: #769dc0;
+  border-color: #759dc0;
   border-width: 1px 0;
   background-image: url("images/commonHighlight.png");
   background-repeat: repeat-x;
diff --git a/dijit/themes/claro/Calendar.less b/dijit/themes/claro/Calendar.less
index ec6aa46..55decd3 100644
--- a/dijit/themes/claro/Calendar.less
+++ b/dijit/themes/claro/Calendar.less
@@ -37,12 +37,13 @@
 .claro .dijitCalendar {
 	border:solid 1px @border-color;
 	background-color: @calendar-background-color;
-	background-image:url("images/calendarContainerImages.png");
+	background-image:url(@image-calendar-container);
 	background-position:0 -448px;
 	background-repeat:repeat-x;
 	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;
@@ -50,7 +51,7 @@
 .claro .dijitCalendar img {
 	border:none;
 }
-.claro .dijitCalendarHover,
+.claro .dijitCalendarHover, .claro .dijitCalendar:hover,
 .claro .dijitCalendarActive {
 	/* treat dijitCalenderActive like hover since there's
 	 * no concept of clicking a Calendar as a whole (although you can click things inside the calendar)
@@ -73,25 +74,29 @@
 .claro .dijitCalendarIncrementControl {
 	width:18px;
 	height:16px;
-	background-image: url("images/calendarArrows.png");
+	background-image: url(@image-calendar-arrows);
 	background-repeat: no-repeat;
 }
 .dj_ie6 .claro .dijitCalendarIncrementControl {
-	background-image: url("images/calendarArrows8bit.png");
+	background-image: url(@image-calendar-arrows-ie6);
 }
 .claro .dijitCalendarIncrease {
 	background-position:-18px 0;
 }
-.claro .dijitCalendarArrowHover .dijitCalendarDecrease {
+.claro .dijitCalendarArrowHover .dijitCalendarDecrease,
+.claro .dijitCalendarArrow:hover .dijitCalendarDecrease {
 	background-position:-36px 0;
 }
-.claro .dijitCalendarArrowHover .dijitCalendarIncrease {
+.claro .dijitCalendarArrowHover .dijitCalendarIncrease,
+.claro .dijitCalendarArrow:hover .dijitCalendarIncrease {
 	background-position:-55px 0;
 }
-.claro .dijitCalendarArrowActive .dijitCalendarDecrease {
+.claro .dijitCalendarArrowActive .dijitCalendarDecrease,
+.claro .dijitCalendarArrow:active .dijitCalendarDecrease {
 	background-position:-72px 0;
 }
-.claro .dijitCalendarArrowActive .dijitCalendarIncrease {
+.claro .dijitCalendarArrowActive .dijitCalendarIncrease,
+.claro .dijitCalendarArrow:active .dijitCalendarIncrease {
 	background-position:-91px 0;
 }
 .claro .dijitA11ySideArrow {
@@ -99,23 +104,23 @@
 	display: none;
 }
 
-
-.claro .dijitDayLabels th {
-	padding:0 4px 0 4px;
-	font-weight:bold;
-	text-align:center;
-}
 .claro .dijitCalendarDayLabelTemplate {
 	padding-bottom:0;
 	text-align:center;
 	border-bottom:1px solid @border-color;
-	font-size:0.909em;
 	padding:0 3px 2px;
 }
+.claro .dijitCalendarDayLabel {
+	padding:0 4px 0 4px;
+	font-weight:bold;
+	font-size:0.909em;
+	text-align:center;
+	color: @text-color;
+}
 .claro .dijitCalendarDateTemplate {
 	text-align:center;
 	background-color:@calendar-currentmonth-background-color;
-	background-image:url("images/calendarContainerImages.png");
+	background-image:url(@image-calendar-container);
 	background-position:0 0;
 	background-repeat:repeat-x;
 	border-bottom: 1px solid @minor-border-color;
@@ -125,6 +130,7 @@
 	font-weight:bold;
 	letter-spacing:.05em;
 	text-align:center;
+	color: @text-color;
 }
 .dj_ie6 .claro .dijitCalendarDateTemplate {
 	background-image: none;
@@ -157,8 +163,9 @@
 	padding: 1px 2px 2px 2px;
 }
 .claro .dijitCalendarYearLabel {
-	padding:2px 0 0 0;
-	margin:0;
+	padding: 2px 0 0 0;
+	margin: 0;
+	font-size: 1.17em;
 }
 .claro .dijitCalendarYearLabel span {
 	/* trying to center next/current/previous year vertically, doesn't work on IE6/7 though */
@@ -178,14 +185,15 @@
 }
 /* End Normal Calendar Style */
 /* Hovered Calendar Style */
-.claro .dijitCalendarHoveredDate .dijitCalendarDateLabel{
+.claro .dijitCalendarHoveredDate .dijitCalendarDateLabel,
+.claro .dijitCalendarEnabledDate:hover .dijitCalendarDateLabel {
 	background-color:@hovered-background-color;
 	border:solid 1px @hovered-border-color;
 	color:@hovered-text-color;
 	.transition-duration(.2s);
 }
-.claro .dijitCalendarNextYearHover,
-.claro .dijitCalendarPreviousYearHover {
+.claro .dijitCalendarNextYearHover, .claro .dijitCalendarNextYear:hover,
+.claro .dijitCalendarPreviousYearHover, .claro .dijitCalendarPreviousYear:hover {
 	color:@hovered-text-color;
 	border:solid 1px @calendar-button-hovered-border-color;
 	padding: 0 5px 0 5px;	/* reduced by 1 to make room for border */
@@ -193,14 +201,15 @@
 }
 /* End Hovered Calendar Style */
 /* Active Calendar Style */
-.claro .dijitCalendarNextYearActive,
-.claro .dijitCalendarPreviousYearActive {
+.claro .dijitCalendarNextYearActive, .claro .dijitCalendarNextYear:active
+.claro .dijitCalendarPreviousYearActive, .claro .dijitCalendarPreviousYear:active {
 	border: solid 1px @calendar-button-pressed-border-color;
 	padding: 0 5px 0 5px;	/* reduced by 1 to make room for border */
 	background-color:@calendar-button-pressed-background-color;
 }
-.claro .dijitCalendarActiveDate .dijitCalendarDateLabel {
-	background-image:url("images/calendarContainerImages.png");
+.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;
@@ -219,13 +228,8 @@
 /* End Selected Calendar Style */
 /* Disabled Calendar Style*/
 .claro .dijitCalendarDisabledDate .dijitCalendarDateLabel {
-	text-decoration:line-through;
-	
-	/* override hover effects above, hover and click on disabled date should have no effect */
-	background-color: transparent;
-	border-width: 0;
-	padding: 4px 6px 4px 5px;
 	color: @disabled-text-color;
+	text-decoration:line-through;
 }
 
 /* End Disabled Calendar Style */
@@ -246,7 +250,8 @@
 	border:solid 1px @border-color;
 	.box-shadow(0 0 0 rgba(0,0,0,0));
 }
-.claro .dijitCalendar .dijitDropDownButtonHover .dijitButtonNode {
+.claro .dijitCalendar .dijitDropDownButtonHover .dijitButtonNode,
+.claro .dijitCalendar .dijitDropDownButton:hover .dijitButtonNode {
 	background-color: @calendar-button-hovered-background-color;
 	border:solid 1px @calendar-button-hovered-border-color;
 }
@@ -264,10 +269,11 @@
 	border-bottom: solid 1px @menu-background-color;
 	padding: 2px 0;
 }
-.claro .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover {
+.claro .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover,
+.claro .dijitCalendarMonthMenu .dijitCalendarMonthLabel:hover {
 	background-color: @hovered-background-color;
 	border-color: @hovered-border-color;
 	border-width:1px 0;
-	background-image: url("images/commonHighlight.png");
+	background-image: url(@image-common-highlight);
 	background-repeat:repeat-x;
 }
diff --git a/dijit/themes/claro/ColorPalette.css b/dijit/themes/claro/ColorPalette.css
index 34d1c72..a23b2df 100644
--- a/dijit/themes/claro/ColorPalette.css
+++ b/dijit/themes/claro/ColorPalette.css
@@ -12,11 +12,11 @@
  *		displays border around a color swatch
  *
  * 3. hovered swatch
- * 		.dijitColorPalette .dijitPaletteCellHover .dijitPaletteImg
+ * 		.dijitColorPalette .dijitPaletteCell:hover .dijitPaletteImg
  *		the hovered state of the color swatch - adds border
  * 	
  * 4. active and selected swatch
- * 		.dijitColorPalette .dijitPaletteCellActive .dijitPaletteImg
+ * 		.dijitColorPalette .dijitPaletteCell:active .dijitPaletteImg
  *		.dijitColorPalette .dijitPaletteCellSelected .dijitPaletteImg
  *		adds border for active or selected state
  */
@@ -33,9 +33,9 @@
 
   border: 1px solid #d3d3d3;
 }
-.claro .dijitColorPalette .dijitPaletteCellHover .dijitPaletteImg {
+.claro .dijitColorPalette .dijitPaletteCell:hover .dijitPaletteImg {
   border: 1px solid #000000;
 }
-.claro .dijitColorPalette .dijitPaletteCellActive .dijitPaletteImg, .claro .dijitColorPalette .dijitPaletteCellSelected .dijitPaletteImg {
+.claro .dijitColorPalette .dijitPaletteCell:active .dijitPaletteImg, .claro .dijitColorPalette .dijitPaletteTable .dijitPaletteCellSelected .dijitPaletteImg {
   border: 2px solid #000000;
 }
diff --git a/dijit/themes/claro/ColorPalette.less b/dijit/themes/claro/ColorPalette.less
index e032733..ffa3ac0 100644
--- a/dijit/themes/claro/ColorPalette.less
+++ b/dijit/themes/claro/ColorPalette.less
@@ -12,11 +12,11 @@
  *		displays border around a color swatch
  *
  * 3. hovered swatch
- * 		.dijitColorPalette .dijitPaletteCellHover .dijitPaletteImg
+ * 		.dijitColorPalette .dijitPaletteCell:hover .dijitPaletteImg
  *		the hovered state of the color swatch - adds border
  * 	
  * 4. active and selected swatch
- * 		.dijitColorPalette .dijitPaletteCellActive .dijitPaletteImg
+ * 		.dijitColorPalette .dijitPaletteCell:active .dijitPaletteImg
  *		.dijitColorPalette .dijitPaletteCellSelected .dijitPaletteImg
  *		adds border for active or selected state
  */
@@ -35,10 +35,10 @@
 	 * overrides border color in dijit.css */
 	border: 1px solid @minor-border-color;
 }
-.claro .dijitColorPalette .dijitPaletteCellHover .dijitPaletteImg {
+.claro .dijitColorPalette .dijitPaletteCell:hover .dijitPaletteImg {
 	border: 1px solid @swatch-hovered-border-color;
 }
-.claro .dijitColorPalette .dijitPaletteCellActive .dijitPaletteImg,
-.claro .dijitColorPalette .dijitPaletteCellSelected .dijitPaletteImg {
+.claro .dijitColorPalette .dijitPaletteCell:active .dijitPaletteImg,
+.claro .dijitColorPalette .dijitPaletteTable .dijitPaletteCellSelected .dijitPaletteImg {
 	border: 2px solid @swatch-selected-border-color;
 }
diff --git a/dijit/themes/claro/Common.css b/dijit/themes/claro/Common.css
index 110b303..83f6128 100644
--- a/dijit/themes/claro/Common.css
+++ b/dijit/themes/claro/Common.css
@@ -18,21 +18,11 @@
 .claro .dijitFocusedLabel {
   /* for checkboxes or radio buttons, hatch border around the corresponding label, to indicate focus */
 
-  outline: 1px dotted #4a4a4a;
-}
-.claro .dijitContentPaneLoading {
-  background: url('images/loadingAnimation.gif') no-repeat left center;
-  padding-left: 25px;
-}
-/* .dijitContentPaneError icon renders in a dialog box with the error messsage when  there is an error in a HREF url */
-.claro .dijitContentPaneError {
-  background: url('../../icons/images/commonIconsObjActEnabled.png') no-repeat left center;
-  background-position: -496px;
-  padding-left: 25px;
+  outline: 1px dotted #494949;
 }
 /* Drag and Drop */
 .claro .dojoDndItemBefore, .claro .dojoDndItemAfter {
-  border-top: 1px solid #769dc0;
+  border-top: 1px solid #759dc0;
 }
 .claro .dojoDndItemOver {
   cursor: pointer;
@@ -50,7 +40,7 @@
   padding-left: 21px;
 }
 .claro.dojoDndMove .dojoDndAvatarHeader, .claro.dojoDndCopy .dojoDndAvatarHeader {
-  background-image: url(images/dnd.png);
+  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 872cf89..248fc1a 100644
--- a/dijit/themes/claro/Common.less
+++ b/dijit/themes/claro/Common.less
@@ -20,18 +20,6 @@
 	outline: 1px dotted @focus-outline-color;
 }
 
-.claro .dijitContentPaneLoading {
-	background:url('images/loadingAnimation.gif') no-repeat left center;
-	padding-left:25px;
-}
-
-/* .dijitContentPaneError icon renders in a dialog box with the error messsage when  there is an error in a HREF url */
-.claro .dijitContentPaneError {
-    background:url('../../icons/images/commonIconsObjActEnabled.png') no-repeat left center;
-    background-position: -496px; 
-	padding-left:25px;
-}
-
 /* Drag and Drop */
 .claro .dojoDndItemBefore,
 .claro .dojoDndItemAfter{
@@ -51,7 +39,7 @@
 	padding-left:21px;
 }
 .claro.dojoDndMove .dojoDndAvatarHeader, .claro.dojoDndCopy .dojoDndAvatarHeader {
-	background-image: url(images/dnd.png);
+	background-image: url(@image-dnd);
 	background-repeat: no-repeat;
 	background-position:2px -122px;
 }
diff --git a/dijit/themes/claro/Dialog.css b/dijit/themes/claro/Dialog.css
index 119900e..ae0b18d 100644
--- a/dijit/themes/claro/Dialog.css
+++ b/dijit/themes/claro/Dialog.css
@@ -29,14 +29,14 @@
  * 		.dijitTooltipConnector - tooltip anchor includes 4 direction(up, down, left, right)
  */
 .claro .dijitDialog {
-  border: 1px solid #769dc0;
+  border: 1px solid #759dc0;
   -webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);
   -moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);
   box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);
 }
 .claro .dijitDialogPaneContent {
   background: #ffffff repeat-x top left;
-  border-top: 1px solid #769dc0;
+  border-top: 1px solid #759dc0;
   padding: 10px 8px;
   position: relative;
 }
@@ -74,6 +74,7 @@
 
   padding: 0 1px;
   font-size: 1.091em;
+  color: #000000;
 }
 .claro .dijitDialogCloseIcon {
   /* the default close icon for the dialog */
@@ -123,7 +124,7 @@
   background-image: url("images/tooltipGradient.png");
   background-repeat: repeat-x;
   background-position: bottom;
-  border: 1px solid #769dc0;
+  border: 1px solid #759dc0;
   padding: 6px 8px;
   -moz-border-radius: 4px;
   border-radius: 4px;
@@ -131,6 +132,7 @@
   -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
   box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
   font-size: 1em;
+  color: #000000;
 }
 .dj_ie6 .claro .dijitTooltipContainer {
   background-image: none;
diff --git a/dijit/themes/claro/Dialog.less b/dijit/themes/claro/Dialog.less
index ff5c1e6..5e74be7 100644
--- a/dijit/themes/claro/Dialog.less
+++ b/dijit/themes/claro/Dialog.less
@@ -68,7 +68,7 @@
 	border: 1px solid @dialog-titlebar-border-color;
 	border-top:none;
 	background-color: @dialog-titlebar-background-color;
-	background-image: url("images/titlebar.png");
+	background-image: url(@image-titlebar);
 	background-repeat:repeat-x;
 	padding: 5px 7px 4px 7px;
 }
@@ -77,11 +77,12 @@
 	/* typography and styling of the dialog title */
 	padding: 0 1px;
 	font-size:1.091em;
+	color: @text-color;
 }
 
 .claro .dijitDialogCloseIcon {
 	/* the default close icon for the dialog */
-	background: url("images/dialogCloseIcon.png");
+	background: url(@image-dialog-close);
 	background-repeat:no-repeat;
 	position: absolute;
 	right: 5px;
@@ -89,7 +90,7 @@
 	width: 21px;
 }
 .dj_ie6 .claro .dijitDialogCloseIcon {
-	background-image: url("images/dialogCloseIcon8bit.png");
+	background-image: url(@image-dialog-close-ie6);
 }
 .claro .dijitDialogCloseIconHover {
 	background-position:-21px;
@@ -122,7 +123,7 @@
 .claro .dijitTooltipContainer {
 	/* the part with the text */
 	background-color:@popup-background-color;
-	background-image:url("images/tooltipGradient.png");
+	background-image:url(@image-tooltip-gradient);
 	background-repeat:repeat-x;
 	background-position:bottom;
 	border:1px solid @popup-border-color;
@@ -130,6 +131,7 @@
 	.border-radius(4px);
 	.box-shadow(0 1px 3px rgba(0,0,0,0.25));
 	font-size: 1em;
+	color: @text-color;
 } 
 
 .dj_ie6 .claro .dijitTooltipContainer {
@@ -139,13 +141,13 @@
 	/* the arrow piece */
 	border: 0;
 	z-index: 2;
-	background-image:url("images/tooltip.png");
+	background-image:url(@image-tooltip);
 	background-repeat:no-repeat;
 	width:16px;
 	height:14px;
 }
 .dj_ie6 .claro .dijitTooltipConnector {
-	background-image:url("images/tooltip8bit.png");
+	background-image:url(@image-tooltip-ie6);
 }
 .claro .dijitTooltipABRight .dijitTooltipConnector {
 	/* above or below tooltip, but the arrow appears on the right,
diff --git a/dijit/themes/claro/Editor.css b/dijit/themes/claro/Editor.css
index 641990a..9f167f9 100644
--- a/dijit/themes/claro/Editor.css
+++ b/dijit/themes/claro/Editor.css
@@ -25,14 +25,14 @@
 }
 .claro .dijitEditor .dijitEditorIFrameContainer {
   background-color: #ffffff;
-  background-image: url('form/images/textBox_back.png');
+  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 {
-  background-color: #e9f4fe;
+  background-color: #e5f2fe;
 }
 .claro .dijitEditorFocused .dijitEditorIFrameContainer, .claro .dijitEditorFocused .dijitEditorIFrameContainer .dijitEditorIFrame {
   /* TODO: contradicts rule above, which background-color do you want? */
diff --git a/dijit/themes/claro/Editor.less b/dijit/themes/claro/Editor.less
index 43e6d39..f74a5d4 100644
--- a/dijit/themes/claro/Editor.less
+++ b/dijit/themes/claro/Editor.less
@@ -28,7 +28,7 @@
 }
 .claro .dijitEditor .dijitEditorIFrameContainer{
 	background-color: @textbox-background-color;
-	background-image: url('form/images/textBox_back.png');
+	background-image: url(@image-form-textbox-background);
 	background-repeat:repeat-x;
 }
 .dj_ie6 .claro .dijitEditor .dijitEditorIFrameContainer{
@@ -56,4 +56,4 @@
 .claro .dijitDisabled .dijitEditorIFrameContainer .dijitEditorIFrame {
 	background-color: @textbox-disabled-background-color;
 	background-image: none;
-}
\ No newline at end of file
+}
diff --git a/dijit/themes/claro/InlineEditBox.css b/dijit/themes/claro/InlineEditBox.css
index e6058f7..0cd1457 100644
--- a/dijit/themes/claro/InlineEditBox.css
+++ b/dijit/themes/claro/InlineEditBox.css
@@ -12,8 +12,8 @@
   border: 1px solid transparent;
 }
 .claro .dijitInlineEditBoxDisplayModeHover {
-  background-color: #e9f4fe;
-  border: solid 1px #769dc0;
+  background-color: #e5f2fe;
+  border: solid 1px #759dc0;
 }
 .dj_ie6 .claro .dijitInlineEditBoxDisplayMode {
   border: none;
diff --git a/dijit/themes/claro/Menu.css b/dijit/themes/claro/Menu.css
index c55176d..e1c1562 100644
--- a/dijit/themes/claro/Menu.css
+++ b/dijit/themes/claro/Menu.css
@@ -44,7 +44,7 @@ There are three areas of styling for the Menu:
 .claro .dijitMenu {
   background-repeat: repeat-y;
   background-color: #ffffff;
-  border: 1px solid #769dc0;
+  border: 1px solid #759dc0;
   /* so adjoining borders of MenuBar/ComboBox and Menu overlap, avoiding double border */
 
   margin: -1px 0;
@@ -57,13 +57,13 @@ There are three areas of styling for the Menu:
 .claro .dijitMenuBar .dijitMenuItem {
   padding: 6px 10px 7px;
   background-position: 0 100px;
-  color: #4a4a4a;
   margin: -1px;
 }
 .claro .dijitMenuItem {
   background-image: url("images/menuHighlight.png");
   background-position: 0 -40px;
   background-repeat: repeat-x;
+  color: #000000;
 }
 /* this prevents jiggling upon hover of a menu item */
 .claro .dijitMenuTable {
@@ -77,7 +77,7 @@ There are three areas of styling for the Menu:
 /* hover over a MenuBarItem */
 .claro .dijitMenuPassive .dijitMenuItemHover, .claro .dijitMenuPassive .dijitMenuItemSelected {
   background-color: #abd6ff;
-  border: solid 1px #769dc0;
+  border: solid 1px #759dc0;
   background-position: 0 0;
   color: #000000;
   padding: 5px 9px 6px;
@@ -90,7 +90,7 @@ There are three areas of styling for the Menu:
 }
 /* MenuBarItem that has been selected and menu drops down from it */
 .claro .dijitMenuActive .dijitMenuItemHover, .claro .dijitMenuActive .dijitMenuItemSelected {
-  border: solid 1px #769dc0;
+  border: solid 1px #759dc0;
   padding: 5px 9px 6px;
   background-color: #abd6ff;
   background-position: 0 0;
@@ -105,7 +105,7 @@ There are three areas of styling for the Menu:
   margin-top: -3px;
 }
 .claro .dijitMenuActive .dijitMenuItemActive {
-  background-color: #7dbefa;
+  background-color: #7dbdfa;
   background-position: 0 -177px;
 }
 .claro .dijitMenuItemActive {
@@ -122,7 +122,7 @@ There are three areas of styling for the Menu:
 .claro .dijitMenuExpand {
   width: 7px;
   height: 7px;
-  background-image: url('images/spriteArrows.png');
+  background-image: url("images/spriteArrows.png");
   background-position: -14px 0;
   margin-right: 3px;
 }
@@ -145,14 +145,14 @@ There are three areas of styling for the Menu:
   display: none;
 }
 .claro .dijitCheckedMenuItemIcon {
-  background-image: url('form/images/checkboxRadioButtonStates.png');
+  background-image: url("form/images/checkboxRadioButtonStates.png");
   background-repeat: no-repeat;
   background-position: -15px 50%;
   width: 15px;
   height: 16px;
 }
 .dj_ie6 .claro .dijitCheckedMenuItemIcon {
-  background-image: url('form/images/checkboxAndRadioButtons_IE6.png');
+  background-image: url("form/images/checkboxAndRadioButtons_IE6.png");
 }
 .claro .dijitCheckedMenuItemChecked .dijitCheckedMenuItemIcon {
   background-position: 0 50%;
@@ -170,12 +170,18 @@ There are three areas of styling for the Menu:
 }
 .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: #7dbefa;
+  background-color: #7dbdfa;
   /* TODO: why is this a different color than normal .dijitMenuItemSelected? */
 
 }
diff --git a/dijit/themes/claro/Menu.less b/dijit/themes/claro/Menu.less
index 1528df4..80467a5 100644
--- a/dijit/themes/claro/Menu.less
+++ b/dijit/themes/claro/Menu.less
@@ -37,7 +37,7 @@ There are three areas of styling for the Menu:
 	margin: 0;
 	padding: 0;
 	background-color: @bar-background-color;
-	background-image: url("images/commonHighlight.png");
+	background-image: url(@image-common-highlight);
 	background-position:0 0;
 	background-repeat:repeat-x;
 }
@@ -58,13 +58,13 @@ There are three areas of styling for the Menu:
 .claro .dijitMenuBar .dijitMenuItem {  
 	padding: 6px 10px 7px;
 	background-position:0 100px;
-	color:@unselected-text-color;
 	margin:-1px;
 }	
 .claro .dijitMenuItem {
-	background-image: url("images/menuHighlight.png");
+	background-image: url(@image-menu-highlight);
 	background-position:0 -40px;
 	background-repeat:repeat-x;
+	color: @text-color;
 }
 
 /* this prevents jiggling upon hover of a menu item */
@@ -128,7 +128,7 @@ There are three areas of styling for the Menu:
 .claro .dijitMenuExpand {
 	width: 7px;
 	height: 7px;
-	background-image: url('images/spriteArrows.png');
+	background-image: url(@image-arrow-sprite);
 	background-position: -14px 0;
 	margin-right:3px;
 }
@@ -149,14 +149,14 @@ There are three areas of styling for the Menu:
 	display: none;
 }
 .claro .dijitCheckedMenuItemIcon {
-	background-image: url('form/images/checkboxRadioButtonStates.png');
+	background-image: url(@image-form-checkbox-and-radios);
 	background-repeat:no-repeat;
 	background-position: -15px 50%;
 	width:15px;
 	height:16px;
 }
 .dj_ie6 .claro .dijitCheckedMenuItemIcon {
-	background-image: url('form/images/checkboxAndRadioButtons_IE6.png');
+	background-image: url(@image-form-checkbox-and-radios-ie6);
 }
 .claro .dijitCheckedMenuItemChecked .dijitCheckedMenuItemIcon {
 	background-position: 0 50%;
@@ -179,6 +179,12 @@ There are three areas of styling for the Menu:
 	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? */
diff --git a/dijit/themes/claro/ProgressBar.css b/dijit/themes/claro/ProgressBar.css
index c735e5c..925021f 100644
--- a/dijit/themes/claro/ProgressBar.css
+++ b/dijit/themes/claro/ProgressBar.css
@@ -30,8 +30,8 @@
 .claro .dijitProgressBarEmpty {
   /* outer container and background of the bar that's not finished yet*/
 
-  background: #ffffff url("images/progressBarEmpty.png") repeat-none left;
-  border-color: #769dc0;
+  background: #ffffff url("images/progressBarEmpty.png") no-repeat left;
+  border-color: #759dc0;
 }
 .claro .dijitProgressBarTile {
   /* inner container for finished portion when in 'tile' (image) mode */
@@ -42,7 +42,13 @@
   background-image: none;
 }
 .claro .dijitProgressBarFull {
-  border-right: 1px solid #769dc0;
+  border-right: 1px solid #759dc0;
+  -webkit-transition-property: width;
+  -moz-transition-property: width;
+  transition-property: width;
+  -webkit-transition-duration: 0.25s;
+  -moz-transition-duration: 0.25s;
+  transition-duration: 0.25s;
 }
 .claro .dijitProgressBarLabel {
   /* Set to a color that contrasts with both the "Empty" and "Full" parts. */
diff --git a/dijit/themes/claro/ProgressBar.less b/dijit/themes/claro/ProgressBar.less
index d361952..8edf426 100644
--- a/dijit/themes/claro/ProgressBar.less
+++ b/dijit/themes/claro/ProgressBar.less
@@ -32,18 +32,20 @@
 }
 .claro .dijitProgressBarEmpty {
 	/* outer container and background of the bar that's not finished yet*/
-	background: @progressbar-empty-background-color url("images/progressBarEmpty.png") repeat-none left;
+	background: @progressbar-empty-background-color url(@image-progressbar-empty) no-repeat left;
 	border-color: @progressbar-border-color;
 }
 .claro .dijitProgressBarTile {
 	/* inner container for finished portion when in 'tile' (image) mode */
-	background: @progressbar-full-background-color url("images/progressBarFull.png") repeat-x top;	
+	background: @progressbar-full-background-color url(@image-progressbar-full) repeat-x top;	
 }
 .dj_ie6 .claro .dijitProgressBarTile {
 	background-image: none;
 } 
 .claro .dijitProgressBarFull {
 	border-right:1px solid @progressbar-border-color;
+	.transition-property(width);
+	.transition-duration(.25s);
 }
 .claro .dijitProgressBarLabel {
 	/* Set to a color that contrasts with both the "Empty" and "Full" parts. */
@@ -52,5 +54,5 @@
 .claro .dijitProgressBarIndeterminate .dijitProgressBarTile {
 	/* use an animated gif for the progress bar in 'indeterminate' mode;
 		background-color won't appear unless user has turned off background images */
-	background: @bar-background-color url("images/progressBarAnim.gif") repeat-x top;
-} 
\ No newline at end of file
+	background: @bar-background-color url(@image-progressbar-anim) repeat-x top;
+} 
diff --git a/dijit/themes/claro/README b/dijit/themes/claro/README
index 5ef4714..3b4b4aa 100644
--- a/dijit/themes/claro/README
+++ b/dijit/themes/claro/README
@@ -7,22 +7,13 @@ Installing and running on Windows:
     a) Go to https://github.com/ajaxorg/node-builds, press download button, and select "download zip"
     b) unzip the file into C:\
 
-2. Install less:
-
-	a) Go to https://github.com/cloudhead/less.js/archives/master, press download button, and select "download zip"
-	b) unzip the file into C:\
-
-2. Add node and lessc environment variables:
+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;C:\cloudhead-less.js-7fb09f\bin
-	
-	d) add new environment variable NODE_PATH with value like this (depending on exact download name):
-
-		C:\cloudhead-less.js-7fb09f\lib
+	;C:\ajaxorg-node-builds-0fcee7d\win32
 
 4. To compile all the files:
 
@@ -34,31 +25,17 @@ To install/run less version 2 on mac:
 
 1. Install Node.js
 	Download a built copy from https://github.com/ajaxorg/node-builds.
-	Alternately, o to http://nodejs.org/#download   (./configure, make, make install).
+	Alternately, go to http://nodejs.org/#download   (./configure, make, make install).
 	
-2. Download less from https://github.com/cloudhead/less.js/archives/master
-
-3. Edit .bash_profile etc. to add node to your path, and lessc to NODE_PATH:
+2. Edit .bash_profile etc. to add node to your path
 
 	export PATH=$PATH:/opt/less/bin
-	export NODE_PATH=$NODE_PATH:/opt/less/lib
 
 To compile all the files:
 
   $ cd dijit/themes/claro
   $ node compile.js
 
-
--------
-Alternately, you can install less version 1, but I'd rather not use it for checked in files
-since it breaks a part a lot of rules into multiple rules, causing spurious diffs.
-
-To install on a mac:
-  $ sudo gem install less
-  
-On Windows or Linux, make sure you have ruby and ruby-gems installed first.
-If you need help installing ruby please check out ruby-lang.org for more details.
-
 -----
 
 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 fb8bf5e..c8d6bb2 100644
--- a/dijit/themes/claro/TimePicker.css
+++ b/dijit/themes/claro/TimePicker.css
@@ -58,7 +58,7 @@
 .claro .dijitTimePickerMarker {
   /* major value - 1:00, 2:00, times on the hour */
 
-  background-color: #e9f4fe;
+  background-color: #e5f2fe;
   font-size: 1em;
   white-space: nowrap;
 }
@@ -66,7 +66,7 @@
 .claro .dijitTimePickerMarkerHover,
 .claro .dijitTimePickerMarkerSelected,
 .claro .dijitTimePickerTickSelected {
-  background-color: #7dbefa;
+  background-color: #7dbdfa;
   border: solid 1px #b5bcc7;
   margin-left: -7px;
   margin-right: -7px;
diff --git a/dijit/themes/claro/TimePicker.less b/dijit/themes/claro/TimePicker.less
index cd07a63..a6253f7 100644
--- a/dijit/themes/claro/TimePicker.less
+++ b/dijit/themes/claro/TimePicker.less
@@ -34,7 +34,7 @@
 }
 .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-image: url(@image-common-highlight);
 	background-position:0 -1px;
 	background-repeat:repeat-x;
 	border-top:solid 1px @border-color;
@@ -95,7 +95,7 @@
 	border-right:none;
 	border-color:@border-color;
 	background-color: @unselected-background-color;
-	background-image: url("images/commonHighlight.png");
+	background-image: url(@image-common-highlight);
 	background-position:0 -1px;
 	background-repeat:repeat-x;
 }
@@ -104,7 +104,7 @@
 }
 .claro .dijitTimePicker .dijitArrowButtonInner{
 	height: 100%; /* hack claro.button.css */
-	background-image: url("form/images/commonFormArrows.png");
+	background-image: url(@image-form-common-arrows);
 	background-repeat: no-repeat;
 	background-position:-140px 45%;
 }
diff --git a/dijit/themes/claro/TitlePane.css b/dijit/themes/claro/TitlePane.css
index 7f0cdbf..1415615 100644
--- a/dijit/themes/claro/TitlePane.css
+++ b/dijit/themes/claro/TitlePane.css
@@ -30,11 +30,11 @@
 }
 .claro .dijitTitlePaneTitleHover {
   background-color: #abd6ff;
-  border-color: #769dc0;
+  border-color: #759dc0;
 }
 .claro .dijitTitlePaneTitleActive {
-  background-color: #7dbefa;
-  border-color: #769dc0;
+  background-color: #7dbdfa;
+  border-color: #759dc0;
   background-position: 0 -136px;
 }
 .claro .dijitTitlePaneTitleFocus {
@@ -42,7 +42,7 @@
   padding-bottom: 2px;
 }
 .claro .dijitTitlePane .dijitArrowNode {
-  background-image: url('images/spriteArrows.png');
+  background-image: url("images/spriteArrows.png");
   background-repeat: no-repeat;
   height: 8px;
   width: 7px;
@@ -53,10 +53,8 @@
 .claro .dijitTitlePane .dijitClosed .dijitArrowNode {
   background-position: -14px 0;
 }
-.claro .dijitTitlePaneFocused .dijitTitlePaneTextNode {
+.claro .dijitTitlePane .dijitTitlePaneTextNode {
   color: #000000;
-  /* TODO: do we need this?   we usually don't change text color on focus */
-
 }
 .claro .dijitTitlePaneContentOuter {
   background: #ffffff;
diff --git a/dijit/themes/claro/TitlePane.less b/dijit/themes/claro/TitlePane.less
index 22bacca..89da9f3 100644
--- a/dijit/themes/claro/TitlePane.less
+++ b/dijit/themes/claro/TitlePane.less
@@ -22,7 +22,7 @@
 
 .claro .dijitTitlePaneTitle {
 	background-color: @unselected-background-color;	// TODO: Mailed Jason, shouldn't this toggle to @selected-background-color when pane opened?
-	background-image: url("images/titlebar.png");
+	background-image: url(@image-titlebar);
 	background-repeat:repeat-x;
 	border:1px solid @border-color;
 	padding: 0 7px 3px 7px;
@@ -45,7 +45,7 @@
 	padding-bottom:2px;
 }
 .claro .dijitTitlePane .dijitArrowNode {
-	background-image: url('images/spriteArrows.png');
+	background-image: url(@image-arrow-sprite);
 	background-repeat: no-repeat;
 	height: 8px;
 	width: 7px;
@@ -56,8 +56,8 @@
 .claro .dijitTitlePane .dijitClosed .dijitArrowNode {
 	background-position: -14px 0;
 }
-.claro .dijitTitlePaneFocused .dijitTitlePaneTextNode {
-	color:@text-color;	/* TODO: do we need this?   we usually don't change text color on focus */
+.claro .dijitTitlePane .dijitTitlePaneTextNode {
+	color:@text-color;
 }
 .claro .dijitTitlePaneContentOuter {
 	background: @pane-background-color;
@@ -71,4 +71,4 @@
 	margin-left: 4px;
 	margin-right: 4px;
 	vertical-align:text-top;
-}
\ No newline at end of file
+}
diff --git a/dijit/themes/claro/Toolbar.css b/dijit/themes/claro/Toolbar.css
index a9e6f4f..18c605c 100644
--- a/dijit/themes/claro/Toolbar.css
+++ b/dijit/themes/claro/Toolbar.css
@@ -29,8 +29,12 @@
 .claro .dijitToolbar label {
   padding: 0 3px 0 6px;
 }
-/** override claro/form/Button.css **/
-.claro .dijitToolbar .dijitButtonNode {
+/** override claro/form/Button.css, and also ComboBox down arrow **/
+.claro .dijitToolbar .dijitButton .dijitButtonNode,
+.claro .dijitToolbar .dijitDropDownButton .dijitButtonNode,
+.claro .dijitToolbar .dijitComboButton .dijitButtonNode,
+.claro .dijitToolbar .dijitToggleButton .dijitButtonNode,
+.claro .dijitToolbar .dijitComboBox .dijitButtonNode {
   border-width: 0;
   /* on hover/active, border-->1px, padding-->1px */
 
@@ -51,16 +55,43 @@
   background-repeat: repeat-x;
   background-color: rgba(171, 214, 255, 0);
 }
-.dj_ie .claro .dijitToolbar .dijitButtonNode {
+.dj_ie .claro .dijitToolbar .dijitButton .dijitButtonNode,
+.dj_ie .claro .dijitToolbar .dijitDropDownButton .dijitButtonNode,
+.dj_ie .claro .dijitToolbar .dijitComboButton .dijitButtonNode,
+.dj_ie .claro .dijitToolbar .dijitToggleButton .dijitButtonNode,
+.dj_ie .claro .dijitToolbar .dijitComboBox .dijitButtonNode {
   background-color: transparent;
   /* for IE, which doesn't understand rgba(...) */
 
 }
-.dj_ie6 .claro .dijitToolbar .dijitButtonNode {
+.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 */
+  /* because background-color: transparent above doesn't work on IE*/
 
 }
+/* hover status */
+.dj_ie .claro .dijitToolbar .dijitButtonHover .dijitButtonNode,
+.dj_ie .claro .dijitToolbar .dijitDropDownButtonHover .dijitButtonNode,
+.dj_ie .claro .dijitToolbar .dijitComboButton .dijitButtonNodeHover,
+.dj_ie .claro .dijitToolbar .dijitComboButton .dijitDownArrowButtonHover,
+.dj_ie .claro .dijitToolbar .dijitToggleButtonHover .dijitButtonNode {
+  /* button should still turn blue on hover, so need to override .dj_ie rules above */
+
+  background-color: #abd6ff;
+}
+/* active status */
+.dj_ie .claro .dijitToolbar .dijitButtonActive .dijitButtonNode,
+.dj_ie .claro .dijitToolbar .dijitDropDownButtonActive .dijitButtonNode,
+.dj_ie .claro .dijitToolbar .dijitComboButtonActive .dijitButtonNode,
+.dj_ie .claro .dijitToolbar .dijitToggleButtonActive .dijitButtonNode {
+  /* button should still turn blue on press, so need to override .dj_ie rules above */
+
+  background-color: #abd6ff;
+}
 .claro .dijitToolbar .dijitComboButton .dijitStretch {
   /* no rounded border on side adjacent to arrow */
 
@@ -88,7 +119,7 @@
 }
 .claro .dijitToolbar .dijitComboButtonHover .dijitButtonNode, .claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton {
   background-position: 0 0;
-  background-color: #f4ffff;
+  background-color: #f3ffff;
 }
 .claro .dijitToolbar .dijitComboButtonHover .dijitButtonNodeHover, .claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButtonHover {
   background-color: #abd6ff;
@@ -96,7 +127,7 @@
 /* active status */
 .claro .dijitToolbar .dijitButtonActive .dijitButtonNode, .claro .dijitToolbar .dijitDropDownButtonActive .dijitButtonNode, .claro .dijitToolbar .dijitToggleButtonActive .dijitButtonNode {
   border-width: 1px;
-  background-color: #7dbefa;
+  background-color: #7dbdfa;
   background-position: 0 -177px;
   padding: 1px;
 }
@@ -108,15 +139,15 @@
   padding: 0;
 }
 .claro .dijitToolbar .dijitComboButtonActive .dijitButtonNode, .claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButton {
-  background-color: #f4ffff;
+  background-color: #f3ffff;
   background-position: 0 -177px;
   padding: 2px;
 }
 .claro .dijitToolbar .dijitComboButtonActive .dijitButtonNodeActive {
-  background-color: #7dbefa;
+  background-color: #7dbdfa;
 }
 .claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButtonActive {
-  background-color: #7dbefa;
+  background-color: #7dbdfa;
 }
 /* Avoid double border between button and arrow */
 .claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton, .claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButton {
@@ -135,7 +166,7 @@
   border-width: 1px;
   border-style: solid;
   background-image: none;
-  border-color: #769dc0;
+  border-color: #759dc0;
   background-color: #ffffff;
   padding: 1px;
 }
@@ -145,7 +176,7 @@
 .claro .dijitToolbarSeparator {
   /* separator icon in the editor sprite */
 
-  background: url('../../icons/images/editorIconsEnabled.png');
+  background: url("../../icons/images/editorIconsEnabled.png");
 }
 /* Toolbar inside of disabled Editor */
 .claro .dijitDisabled .dijitToolbar {
diff --git a/dijit/themes/claro/Toolbar.less b/dijit/themes/claro/Toolbar.less
index eb99f2f..b61e819 100644
--- a/dijit/themes/claro/Toolbar.less
+++ b/dijit/themes/claro/Toolbar.less
@@ -23,7 +23,7 @@
 .claro .dijitToolbar {
 	border-bottom: 1px solid @border-color;
 	background-color: @bar-background-color;
-	background-image: url("images/commonHighlight.png");
+	background-image: url(@image-common-highlight);
 	background-position:0 0;
 	background-repeat:repeat-x;
 	padding: 2px 0 2px 4px;
@@ -34,8 +34,12 @@
 	padding: 0 3px 0 6px;
 }
 
-/** override claro/form/Button.css **/
-.claro .dijitToolbar .dijitButtonNode {
+/** override claro/form/Button.css, and also ComboBox down arrow **/
+.claro .dijitToolbar .dijitButton .dijitButtonNode,
+.claro .dijitToolbar .dijitDropDownButton .dijitButtonNode,
+.claro .dijitToolbar .dijitComboButton .dijitButtonNode,
+.claro .dijitToolbar .dijitToggleButton .dijitButtonNode,
+.claro .dijitToolbar .dijitComboBox .dijitButtonNode {
 	border-width: 0;	/* on hover/active, border-->1px, padding-->1px */
 	padding: 2px;
 	.border-radius(@toolbar-button-border-radius);
@@ -43,16 +47,42 @@
 	.transition-property(background-color);
 	.transition-duration(.3s, .35s);
 
-	background-image: url("images/commonHighlight.png");
+	background-image: url(@image-common-highlight);
 	background-position:0 -30px;
 	background-repeat:repeat-x;
 	background-color:rgba(171,214,255,0);
 }
-.dj_ie .claro .dijitToolbar .dijitButtonNode {
+.dj_ie .claro .dijitToolbar .dijitButton .dijitButtonNode,
+.dj_ie .claro .dijitToolbar .dijitDropDownButton .dijitButtonNode,
+.dj_ie .claro .dijitToolbar .dijitComboButton .dijitButtonNode,
+.dj_ie .claro .dijitToolbar .dijitToggleButton .dijitButtonNode,
+.dj_ie .claro .dijitToolbar .dijitComboBox .dijitButtonNode {
 	background-color: transparent;   /* for IE, which doesn't understand rgba(...) */
 }
-.dj_ie6 .claro .dijitToolbar .dijitButtonNode {
-	background: none;	/* because background-color: transparent above doesn't work */
+.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,
+.dj_ie .claro .dijitToolbar .dijitComboButton .dijitButtonNodeHover,
+.dj_ie .claro .dijitToolbar .dijitComboButton .dijitDownArrowButtonHover,
+.dj_ie .claro .dijitToolbar .dijitToggleButtonHover .dijitButtonNode {
+    /* button should still turn blue on hover, so need to override .dj_ie rules above */
+	background-color: @button-hovered-background-color;
+}
+
+/* active status */
+.dj_ie .claro .dijitToolbar .dijitButtonActive .dijitButtonNode,
+.dj_ie .claro .dijitToolbar .dijitDropDownButtonActive .dijitButtonNode,
+.dj_ie .claro .dijitToolbar .dijitComboButtonActive .dijitButtonNode,
+.dj_ie .claro .dijitToolbar .dijitToggleButtonActive .dijitButtonNode {
+    /* button should still turn blue on press, so need to override .dj_ie rules above */
+	background-color: @button-pressed-background-color;
 }
 
 .claro .dijitToolbar .dijitComboButton .dijitStretch {
@@ -141,7 +171,7 @@
 
 .claro .dijitToolbarSeparator {
 	/* separator icon in the editor sprite */
-	background: url('../../icons/images/editorIconsEnabled.png');
+	background: url(@image-editor-icons-enabled);
 }
 
 /* Toolbar inside of disabled Editor */
diff --git a/dijit/themes/claro/Tree.css b/dijit/themes/claro/Tree.css
index 069deb8..738bb33 100644
--- a/dijit/themes/claro/Tree.css
+++ b/dijit/themes/claro/Tree.css
@@ -44,11 +44,11 @@
   background-color: none;
   background-color: transparent;
   background-color: rgba(171, 214, 255, 0);
-  background-image: url("images/commonHighlight.png");
   background-position: 0 0;
   background-repeat: repeat-x;
   border-color: rgba(118, 157, 192, 0);
   border-width: 0;
+  color: #000000;
   -webkit-transition-property: background-color, border-color;
   -moz-transition-property: background-color, border-color;
   transition-property: background-color, border-color;
@@ -59,36 +59,36 @@
   -moz-transition-timing-function: ease-out;
   transition-timing-function: ease-out;
 }
-.dj_ie6 .claro .dijitTreeRow {
-  background-image: none;
-}
 .claro .dijitTreeRowSelected {
   background-repeat: repeat-x;
   background-color: #cfe5fa;
+  background-image: url("images/commonHighlight.png");
   padding: 3px 0 1px;
   margin: 0;
-  border: solid 1px #769dc0;
+  border: solid 1px #759dc0;
   color: #000000;
 }
 .claro .dijitTreeRowHover {
   background-color: #abd6ff;
+  background-image: url("images/commonHighlight.png");
   padding: 3px 0 1px;
   margin: 0;
-  border: solid 1px #769dc0;
+  border: solid 1px #759dc0;
   color: #000000;
   -webkit-transition-duration: 0.25s;
   -moz-transition-duration: 0.25s;
   transition-duration: 0.25s;
 }
 .claro .dijitTreeRowActive {
-  background-color: #7dbefa;
+  background-color: #7dbdfa;
+  background-image: url("images/commonHighlight.png");
   background-position: 0 -177px;
   padding: 3px 0 1px;
   margin-left: 0;
-  border: solid 1px #769dc0;
+  border: solid 1px #759dc0;
   color: #000000;
 }
-.dj_ie6 .claro .dijitTreeRowActive {
+.dj_ie6 .claro .dijitTreeRow {
   background-image: none;
 }
 .claro .dijitTreeRowFocused {
@@ -96,7 +96,7 @@
 }
 /* expando (open/closed) icon */
 .claro .dijitTreeExpando {
-  background-image: url('images/treeExpandImages.png');
+  background-image: url("images/treeExpandImages.png");
   width: 16px;
   height: 16px;
   background-position: -35px 0;
@@ -104,7 +104,7 @@
 
 }
 .dj_ie6 .claro .dijitTreeExpando {
-  background-image: url('images/treeExpandImages8bit.png');
+  background-image: url("images/treeExpandImages8bit.png");
 }
 .claro .dijitTreeRowHover .dijitTreeExpandoOpened {
   background-position: -53px 0;
@@ -119,7 +119,7 @@
   background-image: none;
 }
 .claro .dijitTreeExpandoLoading {
-  background-image: url('images/loadingAnimation.gif');
+  background-image: url("images/loadingAnimation.gif");
 }
 /* Drag and Drop on TreeNodes
  * Put insert line on dijitTreeContent node so it's aligned w/
@@ -127,8 +127,8 @@
  * though dijitTreeRowNode is the actual "drag object"
  */
 .claro .dijitTreeNode .dojoDndItemBefore .dijitTreeContent {
-  border-top: 2px solid #769dc0;
+  border-top: 2px solid #759dc0;
 }
 .claro .dijitTreeNode .dojoDndItemAfter .dijitTreeContent {
-  border-bottom: 2px solid #769dc0;
+  border-bottom: 2px solid #759dc0;
 }
diff --git a/dijit/themes/claro/Tree.less b/dijit/themes/claro/Tree.less
index 4e639ca..ff6cd5a 100644
--- a/dijit/themes/claro/Tree.less
+++ b/dijit/themes/claro/Tree.less
@@ -46,24 +46,23 @@
 	background-color: none;	// IE6 doesn't understand rgba() or transparent below
 	background-color: transparent;	// IE8 doesn't understand rgba() below
 	background-color: rgba(171,214,255,0);	// rgba() instead of transparent to prevent flash on hover fade-in
-	background-image: url("images/commonHighlight.png");
 	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;
 
+	color: @text-color;
+
 	.transition-property(background-color, border-color);
 	.transition-duration(.25s);
 	.transition-timing-function(ease-out);
 }
-.dj_ie6 .claro .dijitTreeRow {
-	background-image: none;
-}
 
 .claro .dijitTreeRowSelected {
 	background-repeat:repeat-x;
 	background-color:@selected-background-color;
+	background-image: url(@image-common-highlight);
 	padding: 3px 0 1px;
 	margin: 0;
 	border:solid 1px @selected-border-color;
@@ -71,6 +70,7 @@
 }
 .claro .dijitTreeRowHover {
 	background-color:@hovered-background-color;
+	background-image: url(@image-common-highlight);
 	padding: 3px 0 1px;
 	margin: 0;
 	border:solid 1px @hovered-border-color;
@@ -79,13 +79,14 @@
 }
 .claro .dijitTreeRowActive {
 	background-color:@pressed-background-color;
+	background-image: url(@image-common-highlight);
 	background-position:0 -177px;
 	padding: 3px 0 1px;
 	margin-left: 0;
 	border:solid 1px @pressed-border-color;
 	color:@selected-text-color;
 }
-.dj_ie6 .claro .dijitTreeRowActive {
+.dj_ie6 .claro .dijitTreeRow {
 	background-image: none;
 }
 .claro .dijitTreeRowFocused {
@@ -95,13 +96,13 @@
 /* expando (open/closed) icon */
 
 .claro .dijitTreeExpando {
-	background-image: url('images/treeExpandImages.png');
+	background-image: url(@image-tree-expand);
     width: 16px;
     height: 16px;
 	background-position: -35px 0;		/* for dijitTreeExpandoOpened */
 }
 .dj_ie6 .claro .dijitTreeExpando {
-	background-image: url('images/treeExpandImages8bit.png');
+	background-image: url(@image-tree-expand-ie6);
 }
 .claro .dijitTreeRowHover .dijitTreeExpandoOpened {
 	background-position: -53px 0;
@@ -117,7 +118,7 @@
 	background-image:none;
 }
 .claro .dijitTreeExpandoLoading {
-	background-image: url('images/loadingAnimation.gif');
+	background-image: url(@image-loading-animation);
 }
 
 /* Drag and Drop on TreeNodes
diff --git a/dijit/themes/claro/compile.js b/dijit/themes/claro/compile.js
index 9edbe7e..08e6375 100644
--- a/dijit/themes/claro/compile.js
+++ b/dijit/themes/claro/compile.js
@@ -3,12 +3,9 @@
 //
 //	$ node compile.js
 
-// Some guesses for where to find less
-require.paths.unshift('/opt/less/lib', 'C:/less/lib');
-
 var fs = require('fs'),		// file system access
 	path = require('path'),	// get directory from file name
-	less = require('less');	// less processor
+	less = require('../../../util/less');	// less processor
 
 var options = {
 	compress: false,
@@ -25,7 +22,7 @@ var allFiles = [].concat(
 
 lessFiles.forEach(function(fname){
 	console.log("=== " + fname);
-	fs.readFile(fname, 'utf-8', function (e, data){
+	fs.readFile(fname, 'utf-8', function(e, data){
 		if(e){
 			console.error("lessc: " + e.message);
 			process.exit(1);
@@ -43,7 +40,7 @@ lessFiles.forEach(function(fname){
 				try{
 					var css = tree.toCSS({ compress: options.compress }),
 						outputFname = fname.replace('.less', '.css');
-					fd = fs.openSync(outputFname, "w");
+					var fd = fs.openSync(outputFname, "w");
 					fs.writeSync(fd, css, 0, "utf8");
 				}catch(e){
 					less.writeError(e, options);
diff --git a/dijit/themes/claro/form/Button.css b/dijit/themes/claro/form/Button.css
index e01a1d3..bc7c3dc 100644
--- a/dijit/themes/claro/form/Button.css
+++ b/dijit/themes/claro/form/Button.css
@@ -41,12 +41,13 @@
 .claro .dijitToggleButton .dijitButtonNode {
   /* rules for the dijit.form.*Button widgets (see also ComboButton section below) */
 
-  border: 1px solid #769dc0;
+  border: 1px solid #759dc0;
   padding: 2px 4px 4px 4px;
-  background-image: url("images/button.png");
+  background-image: url("../form/images/button.png");
   background-position: center top;
   background-repeat: repeat-x;
-  background-color: #e9f4fe;
+  background-color: #e5f2fe;
+  color: #000000;
   -moz-border-radius: 4px;
   border-radius: 4px;
   -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
@@ -64,7 +65,7 @@
   width: 15px;
   height: 15px;
   margin: 0 auto;
-  background-image: url("images/buttonArrows.png");
+  background-image: url("../form/images/buttonArrows.png");
   background-repeat: no-repeat;
   background-position: -51px 53%;
 }
@@ -105,11 +106,12 @@
   -moz-transition-duration: 0.2s;
   transition-duration: 0.2s;
 }
-/* checked status */
+/* active, checked status */
 .claro .dijitButtonActive .dijitButtonNode,
 .claro .dijitDropDownButtonActive .dijitButtonNode,
 .claro .dijitComboButtonActive .dijitButtonNode,
-.claro .dijitToggleButtonActive .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);
diff --git a/dijit/themes/claro/form/Button.less b/dijit/themes/claro/form/Button.less
index b076d2a..208e4de 100644
--- a/dijit/themes/claro/form/Button.less
+++ b/dijit/themes/claro/form/Button.less
@@ -41,10 +41,11 @@
 	/* 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("images/button.png");
+	background-image: url("../@{image-form-button}");
 	background-position: center top;
 	background-repeat: repeat-x;
 	background-color: @button-background-color;
+	color: @text-color;
 	.border-radius(@button-border-radius);
 	.box-shadow(0 1px 1px rgba(0,0,0,0.15));
 }
@@ -59,7 +60,7 @@
 	width: 15px;
 	height: 15px;
 	margin: 0 auto;
-	background-image:url("images/buttonArrows.png");
+	background-image:url("../@{image-form-button-arrows}");
 	background-repeat:no-repeat;
 	background-position:-51px 53%;
 }
@@ -105,11 +106,12 @@
  	.transition-duration(.2s);
 }
 
-/* checked status */
+/* active, checked status */
 .claro .dijitButtonActive .dijitButtonNode, 
 .claro .dijitDropDownButtonActive .dijitButtonNode,
 .claro .dijitComboButtonActive .dijitButtonNode,
-.claro .dijitToggleButtonActive .dijitButtonNode {
+.claro .dijitToggleButtonActive .dijitButtonNode,
+.claro .dijitStackController .dijitToggleButtonChecked .dijitButtonNode {
 	background-color: @button-pressed-background-color;
 	.box-shadow(0 0 0 rgba(0,0,0,0));
  	.transition-duration(.1s);
diff --git a/dijit/themes/claro/form/Checkbox.css b/dijit/themes/claro/form/Checkbox.css
index 5765bb3..1c1a3c4 100644
--- a/dijit/themes/claro/form/Checkbox.css
+++ b/dijit/themes/claro/form/Checkbox.css
@@ -19,13 +19,13 @@
  * 		.dijitCheckBoxDisabled|.dijitCheckBoxCheckedDisabled - for background image
  */
 .claro .dijitToggleButton .dijitCheckBoxIcon {
-  background-image: url('../images/checkmarkNoBorder.png');
+  background-image: url("../images/checkmarkNoBorder.png");
 }
 .dj_ie6 .claro .dijitToggleButton .dijitCheckBoxIcon {
-  background-image: url('../images/checkmarkNoBorder.gif');
+  background-image: url("../images/checkmarkNoBorder.gif");
 }
 .claro .dijitCheckBox, .claro .dijitCheckBoxIcon {
-  background-image: url('images/checkboxRadioButtonStates.png');
+  background-image: url("../form/images/checkboxRadioButtonStates.png");
   /* checkbox sprite image */
 
   background-repeat: no-repeat;
@@ -35,7 +35,7 @@
   padding: 0;
 }
 .dj_ie6 .claro .dijitCheckBox, .dj_ie6 .claro .dijitCheckBoxIcon {
-  background-image: url('images/checkboxAndRadioButtons_IE6.png');
+  background-image: url("../form/images/checkboxAndRadioButtons_IE6.png");
   /* checkbox sprite image */
 
 }
diff --git a/dijit/themes/claro/form/Checkbox.less b/dijit/themes/claro/form/Checkbox.less
index 21769dc..6ce4448 100644
--- a/dijit/themes/claro/form/Checkbox.less
+++ b/dijit/themes/claro/form/Checkbox.less
@@ -22,16 +22,16 @@
 @import "../variables";
 
 .claro .dijitToggleButton .dijitCheckBoxIcon {
-	background-image: url('../images/checkmarkNoBorder.png');
+	background-image: url("../@{image-checkmark}");
 }
 
 .dj_ie6 .claro .dijitToggleButton .dijitCheckBoxIcon {
-	background-image: url('../images/checkmarkNoBorder.gif');
+	background-image: url("../@{image-checkmark-ie6}");
 }
 
 .claro .dijitCheckBox,
 .claro .dijitCheckBoxIcon		/* inside a toggle button */	{
-	background-image: url('images/checkboxRadioButtonStates.png'); /* checkbox sprite image */
+	background-image: url("../@{image-form-checkbox-and-radios}"); /* checkbox sprite image */
 	background-repeat: no-repeat;
 	width: 15px;
 	height: 16px;
@@ -41,7 +41,7 @@
 
 .dj_ie6 .claro .dijitCheckBox,
 .dj_ie6 .claro .dijitCheckBoxIcon		/* inside a toggle button */	{
-	background-image: url('images/checkboxAndRadioButtons_IE6.png'); /* checkbox sprite image */
+	background-image: url("../@{image-form-checkbox-and-radios-ie6}"); /* checkbox sprite image */
 }
 
 .claro .dijitCheckBox,
diff --git a/dijit/themes/claro/form/Common.css b/dijit/themes/claro/form/Common.css
index ab8bb5c..ce108c1 100644
--- a/dijit/themes/claro/form/Common.css
+++ b/dijit/themes/claro/form/Common.css
@@ -1,9 +1,12 @@
 /* claro/form/Common.css */
 /*========================= common css =========================*/
 /* 'dijitTextBox' refers to 'dijit(TextBox|DateTextBox|CurrencyTextBox|...)' */
+.claro .dijitTextBox, .claro .dijitInputInner {
+  color: #000000;
+}
 .claro .dijitTextBoxError .dijitValidationContainer {
   background-color: #d46464;
-  background-image: url('images/error.png');
+  background-image: url("../form/images/error.png");
   background-position: top center;
   border: solid #d46464 0;
   border-left-width: 1px;
@@ -45,14 +48,14 @@
 }
 /* hover */
 .claro .dijitTextBoxHover, .claro .dijitTextBoxHover .dijitButtonNode {
-  border-color: #769dc0;
+  border-color: #759dc0;
   -webkit-transition-duration: 0.25s;
   -moz-transition-duration: 0.25s;
   transition-duration: 0.25s;
 }
 .claro .dijitTextBoxHover {
-  background-color: #e9f4fe;
-  background-image: url('images/textBox_back.png');
+  background-color: #e5f2fe;
+  background-image: url("../form/images/textBox_back.png");
   background-repeat: repeat-x;
 }
 /* error state */
@@ -64,21 +67,21 @@
 }
 /* focused state */
 .claro .dijitTextBoxFocused, .claro .dijitTextBoxFocused .dijitButtonNode {
-  border-color: #769dc0;
+  border-color: #759dc0;
   -webkit-transition-duration: 0.1s;
   -moz-transition-duration: 0.1s;
   transition-duration: 0.1s;
 }
 .claro .dijitTextBoxFocused {
   background-color: #ffffff;
-  background-image: url('images/textBox_back.png');
+  background-image: url("../form/images/textBox_back.png");
   background-repeat: repeat-x;
 }
 .claro .dijitTextBoxFocused .dijitInputContainer {
   background: #ffffff;
 }
 .claro .dijitTextBoxErrorFocused, .claro .dijitTextBoxErrorFocused .dijitButtonNode {
-  border-color: #ce4f4f;
+  border-color: #ce5050;
 }
 /* disabled state */
 .claro .dijitTextBoxDisabled, .claro .dijitTextBoxDisabled .dijitButtonNode {
@@ -87,12 +90,24 @@
 .claro .dijitTextBoxDisabled, .claro .dijitTextBoxDisabled .dijitInputContainer {
   background-color: #efefef;
   background-image: none;
+}
+.claro .dijitTextBoxDisabled, .claro .dijitTextBoxDisabled .dijitInputInner {
   color: #818181;
 }
+.dj_webkit .claro .dijitTextBoxDisabled input {
+  /* because WebKit lightens disabled input/textarea no matter what color you specify */
+
+  color: #757575;
+}
+.dj_webkit .claro textarea.dijitTextAreaDisabled {
+  /* because WebKit lightens disabled input/textarea no matter what color you specify */
+
+  color: #1b1b1b;
+}
 /*========================= for special widgets =========================*/
 /* Input boxes with an arrow (for a drop down) */
 .claro .dijitComboBox .dijitArrowButtonInner {
-  background-image: url("images/commonFormArrows.png");
+  background-image: url("../form/images/commonFormArrows.png");
   background-position: -35px 53%;
   background-repeat: no-repeat;
   margin: 0;
@@ -112,7 +127,7 @@
 }
 .claro .dijitComboBox .dijitButtonNode {
   background-color: #efefef;
-  background-image: url("images/formHighlight.png");
+  background-image: url("../form/images/formHighlight.png");
   background-repeat: repeat-x;
 }
 /* Arrow "hover" effect:
@@ -128,7 +143,7 @@
 }
 /* Arrow Button change when drop down is open */
 .claro .dijitComboBox .dijitHasDropDownOpen {
-  background-color: #7dbefa;
+  background-color: #7dbdfa;
   background-position: 0 -177px;
   padding: 1px;
 }
diff --git a/dijit/themes/claro/form/Common.less b/dijit/themes/claro/form/Common.less
index 729867a..742a43f 100644
--- a/dijit/themes/claro/form/Common.less
+++ b/dijit/themes/claro/form/Common.less
@@ -6,9 +6,16 @@
 
 /* 'dijitTextBox' refers to 'dijit(TextBox|DateTextBox|CurrencyTextBox|...)' */
 
+.claro .dijitTextBox,
+.claro .dijitInputInner {
+    // .dijitInputInner selector needed for ValidationTextBox on IE6 because <input> doesn't inherit
+    // the color setting from the ancestor div.dijitTextBox
+	color: @text-color;
+}
+
 .claro .dijitTextBoxError .dijitValidationContainer {
 	background-color: @erroricon-background-color;
-	background-image: url('images/error.png');
+	background-image: url("../@{image-form-error}");
 	background-position: top center;
 	border: solid @erroricon-background-color 0;
 	border-left-width: 1px;
@@ -60,7 +67,7 @@
 }
 .claro .dijitTextBoxHover {
 	background-color: @textbox-hovered-background-color;
-	background-image: url('images/textBox_back.png');
+	background-image: url("../@{image-form-textbox-background}");
 	background-repeat: repeat-x;
 }
 
@@ -82,7 +89,7 @@
 }
 .claro .dijitTextBoxFocused {
 	background-color: @textbox-focused-background-color;
-	background-image: url('images/textBox_back.png');
+	background-image: url("../@{image-form-textbox-background}");
 	background-repeat: repeat-x;
 }
 .claro .dijitTextBoxFocused .dijitInputContainer {
@@ -103,15 +110,26 @@
 .claro .dijitTextBoxDisabled .dijitInputContainer {
 	background-color: @textbox-disabled-background-color;
 	background-image: none;
+}
+.claro .dijitTextBoxDisabled,
+.claro .dijitTextBoxDisabled .dijitInputInner {
 	color: @disabled-text-color;
 }
+.dj_webkit .claro .dijitTextBoxDisabled 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%)
+}
 
 /*========================= for special widgets =========================*/
 
 /* Input boxes with an arrow (for a drop down) */
 
 .claro .dijitComboBox .dijitArrowButtonInner {
-	background-image: url("images/commonFormArrows.png");
+	background-image: url("../@{image-form-common-arrows}");
 	background-position:-35px 53%;
 	background-repeat: no-repeat;
 	margin: 0;
@@ -136,7 +154,7 @@
 
 .claro .dijitComboBox .dijitButtonNode {
 	background-color: @arrowbutton-background-color;
-	background-image: url("images/formHighlight.png");
+	background-image: url("../@{image-form-highlight}");
 	background-repeat:repeat-x;
 }
 
@@ -191,4 +209,4 @@
 }
 .dj_borderbox .claro .dijitComboBoxFocused .dijitHasDropDownOpen .dijitArrowButtonInner {
 	width:16px;				// when no border, then back to 16px just like content-box sizing
-}
\ No newline at end of file
+}
diff --git a/dijit/themes/claro/form/NumberSpinner.css b/dijit/themes/claro/form/NumberSpinner.css
index bc6e1ae..fcc8049 100644
--- a/dijit/themes/claro/form/NumberSpinner.css
+++ b/dijit/themes/claro/form/NumberSpinner.css
@@ -35,7 +35,7 @@
 .claro .dijitSpinner .dijitArrowButton {
   width: auto;
   background-color: #efefef;
-  background-image: url("images/formHighlight.png");
+  background-image: url("../form/images/formHighlight.png");
   background-position: 0 0;
   background-repeat: repeat-x;
   overflow: hidden;
@@ -54,7 +54,7 @@
   border-bottom-width: 0;
   /* 2 top borders = 1 top+bottom border in ComboBox */
 
-  background-image: url("images/commonFormArrows.png");
+  background-image: url("../form/images/commonFormArrows.png");
   background-repeat: no-repeat;
   height: 100%;
   width: 15px;
diff --git a/dijit/themes/claro/form/NumberSpinner.less b/dijit/themes/claro/form/NumberSpinner.less
index ca78afb..1c79d3a 100644
--- a/dijit/themes/claro/form/NumberSpinner.less
+++ b/dijit/themes/claro/form/NumberSpinner.less
@@ -37,7 +37,7 @@
 .claro .dijitSpinner .dijitArrowButton {
 	width:auto;
 	background-color: @arrowbutton-background-color;
-	background-image: url("images/formHighlight.png");
+	background-image: url("../@{image-form-highlight}");
 	background-position:0 0;
 	background-repeat:repeat-x;
 	overflow: hidden;
@@ -53,7 +53,7 @@
 .claro .dijitSpinner .dijitArrowButtonInner {
 	border:solid 1px @arrowbutton-inner-border-color;
 	border-bottom-width: 0; /* 2 top borders = 1 top+bottom border in ComboBox */
-	background-image: url("images/commonFormArrows.png");
+	background-image: url("../@{image-form-common-arrows}");
 	background-repeat: no-repeat;
 	height: 100%;
 	width:15px;
@@ -147,4 +147,4 @@
  * should be no empty space between dijitInputLayoutContainer and dijitSpinner*/
 .dj_ie7 .claro .dijitSpinner {
 	overflow:visible;
-} 
\ No newline at end of file
+} 
diff --git a/dijit/themes/claro/form/RadioButton.css b/dijit/themes/claro/form/RadioButton.css
index 4dc3ad4..bad1854 100644
--- a/dijit/themes/claro/form/RadioButton.css
+++ b/dijit/themes/claro/form/RadioButton.css
@@ -19,15 +19,15 @@
  * 		.dijitRadioDisabled|.dijitRadioCheckedDisabled - for background image
  */
 .claro .dijitToggleButton .dijitRadio, .claro .dijitToggleButton .dijitRadioIcon {
-  background-image: url('images/checkboxRadioButtonStates.png');
+  background-image: url("../form/images/checkboxRadioButtonStates.png");
 }
 .dj_ie6 .claro .dijitToggleButton .dijitRadio, .dj_ie6 .claro .dijitToggleButton .dijitRadioIcon {
-  background-image: url('images/checkboxAndRadioButtons_IE6.png');
+  background-image: url("../form/images/checkboxAndRadioButtons_IE6.png");
 }
 .claro .dijitRadio, .claro .dijitRadioIcon {
   /* inside a toggle button */
 
-  background-image: url('images/checkboxRadioButtonStates.png');
+  background-image: url("../form/images/checkboxRadioButtonStates.png");
   /* checkbox sprite image */
 
   background-repeat: no-repeat;
@@ -39,7 +39,7 @@
 .dj_ie6 .claro .dijitRadio, .dj_ie6 .claro .dijitRadioIcon {
   /* inside a toggle button */
 
-  background-image: url('images/checkboxAndRadioButtons_IE6.png');
+  background-image: url("../form/images/checkboxAndRadioButtons_IE6.png");
   /* checkbox sprite image */
 
 }
diff --git a/dijit/themes/claro/form/RadioButton.less b/dijit/themes/claro/form/RadioButton.less
index 18f1cc1..f48cb67 100644
--- a/dijit/themes/claro/form/RadioButton.less
+++ b/dijit/themes/claro/form/RadioButton.less
@@ -23,17 +23,17 @@
 
 .claro .dijitToggleButton .dijitRadio,
 .claro .dijitToggleButton .dijitRadioIcon {
-	background-image: url('images/checkboxRadioButtonStates.png');
+	background-image: url("../@{image-form-checkbox-and-radios}");
 }
 
 .dj_ie6 .claro .dijitToggleButton .dijitRadio,
 .dj_ie6 .claro .dijitToggleButton .dijitRadioIcon {
-	background-image: url('images/checkboxAndRadioButtons_IE6.png');
+	background-image: url("../@{image-form-checkbox-and-radios-ie6}");
 }
 
 .claro .dijitRadio,
 .claro .dijitRadioIcon	{		/* inside a toggle button */
-	background-image: url('images/checkboxRadioButtonStates.png'); /* checkbox sprite image */
+	background-image: url("../@{image-form-checkbox-and-radios}"); /* checkbox sprite image */
 	background-repeat: no-repeat;
 	width: 15px;
 	height: 15px;
@@ -43,7 +43,7 @@
 
 .dj_ie6 .claro .dijitRadio,
 .dj_ie6 .claro .dijitRadioIcon	{		/* inside a toggle button */
-	background-image: url('images/checkboxAndRadioButtons_IE6.png'); /* checkbox sprite image */
+	background-image: url("../@{image-form-checkbox-and-radios-ie6}"); /* checkbox sprite image */
 }
 
 .claro .dijitRadio{
diff --git a/dijit/themes/claro/form/Select.css b/dijit/themes/claro/form/Select.css
index a30ede6..bfbca4e 100644
--- a/dijit/themes/claro/form/Select.css
+++ b/dijit/themes/claro/form/Select.css
@@ -37,11 +37,11 @@
   border: 1px solid #ffffff;
   border-top: none;
   background-color: #efefef;
-  background-image: url("images/formHighlight.png");
+  background-image: url("../form/images/formHighlight.png");
   background-repeat: repeat-x;
 }
 .claro .dijitSelect .dijitArrowButton .dijitArrowButtonInner {
-  background-image: url("images/commonFormArrows.png");
+  background-image: url("../form/images/commonFormArrows.png");
   background-position: -35px 70%;
   background-repeat: no-repeat;
   width: 16px;
@@ -49,13 +49,13 @@
 }
 /* hover status */
 .claro .dijitSelectHover {
-  border: 1px solid #769dc0;
-  background-color: #e9f4fe;
-  background-image: url('images/textBox_back.png');
+  border: 1px solid #759dc0;
+  background-color: #e5f2fe;
+  background-image: url("../form/images/textBox_back.png");
   background-repeat: repeat-x;
 }
 .claro .dijitSelectHover .dijitButtonContents {
-  border-color: #769dc0;
+  border-color: #759dc0;
 }
 .claro .dijitSelectHover .dijitArrowButton {
   background-color: #abd6ff;
@@ -65,10 +65,10 @@
 }
 /* focused status */
 .claro .dijitSelectFocused {
-  border: 1px solid #769dc0;
+  border: 1px solid #759dc0;
 }
 .claro .dijitSelectFocused .dijitButtonContents {
-  border-color: #769dc0;
+  border-color: #759dc0;
 }
 .claro .dijitSelectFocused .dijitArrowButton {
   background-color: #7dbefa;
@@ -105,5 +105,5 @@
   padding: 2px;
 }
 .claro .dijitSelectMenu .dijitMenuSeparatorTop {
-  border-bottom: 1px solid #769dc0;
+  border-bottom: 1px solid #759dc0;
 }
diff --git a/dijit/themes/claro/form/Select.less b/dijit/themes/claro/form/Select.less
index c429b2e..0e74261 100644
--- a/dijit/themes/claro/form/Select.less
+++ b/dijit/themes/claro/form/Select.less
@@ -44,12 +44,12 @@
 	border: 1px solid @arrowbutton-inner-border-color;
 	border-top:none;
 	background-color: @arrowbutton-background-color;
-	background-image: url("images/formHighlight.png");
+	background-image: url("../@{image-form-highlight}");
 	background-repeat:repeat-x;
 }
 
 .claro .dijitSelect .dijitArrowButton .dijitArrowButtonInner {
-	background-image: url("images/commonFormArrows.png");
+	background-image: url("../@{image-form-common-arrows}");
 	background-position:-35px 70%;
 	background-repeat: no-repeat;
 	width:16px;
@@ -60,7 +60,7 @@
 .claro .dijitSelectHover {
 	border: 1px solid @hovered-border-color;
 	background-color: @textbox-hovered-background-color;
-	background-image: url('images/textBox_back.png');
+	background-image: url("../@{image-form-textbox-background}");
 	background-repeat: repeat-x;
 }
 
diff --git a/dijit/themes/claro/form/Slider.css b/dijit/themes/claro/form/Slider.css
index 5694e8c..eb82e17 100644
--- a/dijit/themes/claro/form/Slider.css
+++ b/dijit/themes/claro/form/Slider.css
@@ -54,28 +54,31 @@
   outline: 1px;
 }
 .claro .dijitSliderFocused .dijitSliderBar {
-  border-color: #769dc0;
+  border-color: #759dc0;
 }
 .claro .dijitSliderHover .dijitSliderBar {
-  border-color: #769dc0;
+  border-color: #759dc0;
 }
 .claro .dijitSliderDisabled .dijitSliderBar {
   background-image: none;
   border-color: #d3d3d3;
 }
+.claro .dijitRuleLabel {
+  color: #000000;
+}
 /* Horizontal Slider */
 .claro .dijitRuleLabelsContainerH {
   padding: 2px 0;
 }
 .claro .dijitSlider .dijitSliderProgressBarH, .claro .dijitSlider .dijitSliderLeftBumper {
-  background-image: url("images/sliderHorizontal.png");
+  background-image: url("../form/images/sliderHorizontal.png");
   background-repeat: repeat-x;
   background-position: 0 -20px;
   border-color: #b5bcc7;
   background-color: #cfe5fa;
 }
 .claro .dijitSlider .dijitSliderRemainingBarH, .claro .dijitSlider .dijitSliderRightBumper {
-  background-image: url("images/sliderHorizontal.png");
+  background-image: url("../form/images/sliderHorizontal.png");
   background-repeat: repeat-x;
   background-position: 0 -11px;
   border-color: #b5bcc7;
@@ -90,22 +93,22 @@
 .claro .dijitSliderHover .dijitSliderProgressBarH, .claro .dijitSliderHover .dijitSliderLeftBumper {
   background-position: 0 -20px;
   background-color: #abd6ff;
-  border-color: #769dc0;
+  border-color: #759dc0;
 }
 .claro .dijitSliderHover .dijitSliderRemainingBarH, .claro .dijitSliderHover .dijitSliderRightBumper {
   background-position: 0 0;
   background-color: #ffffff;
-  border-color: #769dc0;
+  border-color: #759dc0;
 }
 .claro .dijitSliderFocused .dijitSliderProgressBarH, .claro .dijitSliderFocused .dijitSliderLeftBumper {
   background-position: 0 -30px;
   background-color: #abd6ff;
-  border-color: #769dc0;
+  border-color: #759dc0;
 }
 .claro .dijitSliderFocused .dijitSliderRemainingBarH, .claro .dijitSliderFocused .dijitSliderRightBumper {
   background-position: 0 -9px;
   background-color: #ffffff;
-  border-color: #769dc0;
+  border-color: #759dc0;
 }
 .claro .dijitSliderDisabled .dijitSliderProgressBarH, .claro .dijitSliderDisabled .dijitSliderLeftBumper {
   background-color: #d3d3d3;
@@ -121,14 +124,14 @@
   padding: 0 2px;
 }
 .claro .dijitSlider .dijitSliderProgressBarV, .claro .dijitSlider .dijitSliderBottomBumper {
-  background-image: url("images/sliderVertical.png");
+  background-image: url("../form/images/sliderVertical.png");
   background-repeat: repeat-y;
   background-position: -36px 0;
   border-color: #b5bcc7;
   background-color: #cfe5fa;
 }
 .claro .dijitSlider .dijitSliderRemainingBarV, .claro .dijitSlider .dijitSliderTopBumper {
-  background-image: url("images/sliderVertical.png");
+  background-image: url("../form/images/sliderVertical.png");
   background-repeat: repeat-y;
   background-position: -3px 0;
   border-color: #b5bcc7;
@@ -169,7 +172,7 @@
   border: 0;
   width: 18px;
   height: 16px;
-  background-image: url("images/sliderThumbs.png");
+  background-image: url("../form/images/sliderThumbs.png");
   background-repeat: no-repeat;
   background-position: 0 0;
 }
@@ -192,7 +195,7 @@
   border: 0;
   width: 18px;
   height: 16px;
-  background-image: url("images/sliderThumbs.png");
+  background-image: url("../form/images/sliderThumbs.png");
   background-repeat: no-repeat;
   background-position: -289px 0;
 }
@@ -222,7 +225,7 @@
 .claro .dijitSliderIncrementIconH,
 .claro .dijitSliderDecrementIconV,
 .claro .dijitSliderIncrementIconV {
-  background-image: url('images/commonFormArrows.png');
+  background-image: url("../form/images/commonFormArrows.png");
   background-repeat: no-repeat;
   background-color: #efefef;
   -moz-border-radius: 2px;
@@ -248,7 +251,7 @@
 .claro .dijitSliderHover .dijitSliderIncrementIconV {
   /* dijitSliderActive should be treated as dijitSliderHover since "clicking the slider" has no meaning */
 
-  border: solid 1px #769dc0;
+  border: solid 1px #759dc0;
   background-color: #ffffff;
 }
 .claro .dijitSliderDecrementIconH {
@@ -286,7 +289,7 @@
 .claro .dijitSliderButtonContainerV .dijitSliderIncrementButtonActive,
 .claro .dijitSliderButtonContainerH .dijitSliderIncrementButtonActive {
   background-color: #abd6ff;
-  border-color: #769dc0;
+  border-color: #759dc0;
 }
 .claro .dijitSliderButtonInner {
   visibility: hidden;
diff --git a/dijit/themes/claro/form/Slider.less b/dijit/themes/claro/form/Slider.less
index 82451b5..db0f8cb 100644
--- a/dijit/themes/claro/form/Slider.less
+++ b/dijit/themes/claro/form/Slider.less
@@ -66,6 +66,9 @@
 	background-image: none;
 	border-color: @disabled-border-color;
 }
+.claro .dijitRuleLabel {
+	color: @text-color;
+}
 
 /* Horizontal Slider */
 
@@ -74,7 +77,7 @@
 }
 .claro .dijitSlider .dijitSliderProgressBarH,
 .claro .dijitSlider .dijitSliderLeftBumper{
-	background-image: url("images/sliderHorizontal.png");
+	background-image: url("../@{image-form-slider-horizontal}");
 	background-repeat:repeat-x;
 	background-position:0 -20px;
 	border-color: @border-color;
@@ -82,7 +85,7 @@
 }
 .claro .dijitSlider .dijitSliderRemainingBarH,
 .claro .dijitSlider .dijitSliderRightBumper{
-	background-image: url("images/sliderHorizontal.png");
+	background-image: url("../@{image-form-slider-horizontal}");
 	background-repeat:repeat-x;
 	background-position:0 -11px;
 	border-color: @border-color;
@@ -135,7 +138,7 @@
 }
 .claro .dijitSlider .dijitSliderProgressBarV,
 .claro .dijitSlider .dijitSliderBottomBumper{
-	background-image: url("images/sliderVertical.png");
+	background-image: url("../@{image-form-slider-vertical}");
 	background-repeat:repeat-y;
 	background-position:-36px 0;
 	border-color: @border-color;
@@ -143,7 +146,7 @@
 }
 .claro .dijitSlider .dijitSliderRemainingBarV,
 .claro .dijitSlider .dijitSliderTopBumper{
-	background-image: url("images/sliderVertical.png");
+	background-image: url("../@{image-form-slider-vertical}");
 	background-repeat:repeat-y;
 	background-position:-3px 0;
 	border-color: @border-color;
@@ -191,7 +194,7 @@
 	border: 0;
 	width: 18px;
 	height: 16px;
-	background-image: url("images/sliderThumbs.png");
+	background-image: url("../@{image-form-slider-thumbs}");
 	background-repeat:no-repeat;
 	background-position:0 0;
 }
@@ -215,7 +218,7 @@
 	border: 0;
 	width: 18px;
 	height: 16px;
-	background-image: url("images/sliderThumbs.png");
+	background-image: url("../@{image-form-slider-thumbs}");
 	background-repeat:no-repeat;
 	background-position:-289px 0;
 }
@@ -248,7 +251,7 @@
 .claro .dijitSliderIncrementIconH,
 .claro .dijitSliderDecrementIconV,
 .claro .dijitSliderIncrementIconV {
-	background-image: url('images/commonFormArrows.png');
+	background-image: url("../@{image-form-common-arrows}");
 	background-repeat:no-repeat;
 	background-color: @arrowbutton-background-color;
 	.border-radius(2px);
diff --git a/dijit/themes/claro/layout/AccordionContainer.css b/dijit/themes/claro/layout/AccordionContainer.css
index f769479..3483176 100644
--- a/dijit/themes/claro/layout/AccordionContainer.css
+++ b/dijit/themes/claro/layout/AccordionContainer.css
@@ -50,15 +50,12 @@
   background-color: transparent;
   /* pick up color from dijitAccordionInnerContainer */
 
-  background-image: url("images/accordion.png");
+  background-image: url("../layout/images/accordion.png");
   background-position: 0 0;
   background-repeat: repeat-x;
   padding: 5px 7px 2px 7px;
   min-height: 17px;
-  color: #4a4a4a;
-}
-.claro .dijitAccordionTitleHover {
-  color: #000000;
+  color: #494949;
 }
 .dj_ie6 .claro .dijitAccordionTitle {
   background-image: none;
@@ -69,7 +66,7 @@
 	 */
 
   background-color: #ffffff;
-  border: 1px solid #769dc0;
+  border: 1px solid #759dc0;
   margin: 0 2px 2px;
 }
 .claro .dijitAccordionContainer .dijitAccordionContainer-child {
@@ -79,8 +76,8 @@
 }
 /* Active state for closed pane */
 .claro .dijitAccordionInnerContainerActive {
-  border: 1px solid #769dc0;
-  background-color: #7dbefa;
+  border: 1px solid #759dc0;
+  background-color: #7dbdfa;
   -webkit-transition-duration: 0.1s;
   -moz-transition-duration: 0.1s;
   transition-duration: 0.1s;
@@ -91,7 +88,7 @@
 }
 /* Open (a.k.a. selected) pane */
 .claro .dijitAccordionInnerContainerSelected {
-  border-color: #769dc0;
+  border-color: #759dc0;
   background-color: #cfe5fa;
 }
 .claro .dijitAccordionInnerContainerSelected .dijitAccordionTitle {
@@ -101,7 +98,7 @@
 
 }
 /* Hovering open or closed pane */
-.claro .dijitAccordionInnerContainerHover dijitAccordionTitle {
+.claro .dijitAccordionInnerContainerHover .dijitAccordionTitle {
   /* both open and closed */
 
   color: #000000;
@@ -109,7 +106,7 @@
 .claro .dijitAccordionInnerContainerHover, .claro .dijitAccordionInnerContainerSelectedActive {
   /* note: clicking the currently selected Accordion pane should have no effect, so treating same as hover. */
 
-  border: 1px solid #769dc0;
+  border: 1px solid #759dc0;
   background-color: #abd6ff;
   -webkit-transition-duration: 0.2s;
   -moz-transition-duration: 0.2s;
@@ -117,7 +114,7 @@
 }
 .claro .dijitAccordionInnerContainerSelectedHover .dijitAccordionChildWrapper, .claro .dijitAccordionInnerContainerSelectedActive .dijitAccordionChildWrapper {
   background-color: #ffffff;
-  border: 1px solid #769dc0 !important;
+  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 01f4427..b3aa622 100644
--- a/dijit/themes/claro/layout/AccordionContainer.less
+++ b/dijit/themes/claro/layout/AccordionContainer.less
@@ -43,16 +43,13 @@
 }
 .claro .dijitAccordionTitle {
 	background-color: transparent;	/* pick up color from dijitAccordionInnerContainer */
-	background-image: url("images/accordion.png");
+	background-image: url("../@{image-layout-accordion}");
 	background-position:0 0;
 	background-repeat:repeat-x;
 	padding: 5px 7px 2px 7px;
 	min-height:17px;
 	color:@unselected-text-color;
 }
-.claro .dijitAccordionTitleHover {
-	color:@hovered-text-color;
-}
 .dj_ie6 .claro .dijitAccordionTitle {
 	background-image: none;
 }
@@ -95,7 +92,7 @@
 
 /* Hovering open or closed pane */
 
-.claro .dijitAccordionInnerContainerHover dijitAccordionTitle {
+.claro .dijitAccordionInnerContainerHover .dijitAccordionTitle {
 	/* both open and closed */
 	color:@hovered-text-color;
 }
diff --git a/dijit/themes/claro/layout/BorderContainer.css b/dijit/themes/claro/layout/BorderContainer.css
index ede2a56..8c0a5fa 100644
--- a/dijit/themes/claro/layout/BorderContainer.css
+++ b/dijit/themes/claro/layout/BorderContainer.css
@@ -86,17 +86,17 @@ Splitters and gutters:
 /* hovered splitter */
 .claro .dijitSplitterHHover {
   font-size: 1px;
-  background: url("images/splitterHorizontalHover.png") no-repeat center top;
+  background: url("../layout/images/splitterHorizontalHover.png") no-repeat center top;
 }
 .claro .dijitSplitterHHover .dijitSplitterThumb {
-  background: #769dc0 none;
+  background: #759dc0 none;
 }
 .claro .dijitSplitterVHover {
   font-size: 1px;
-  background: url("images/splitterVerticalHover.png") no-repeat center left;
+  background: url("../layout/images/splitterVerticalHover.png") no-repeat center left;
 }
 .claro .dijitSplitterVHover .dijitSplitterThumb {
-  background: #769dc0 none;
+  background: #759dc0 none;
 }
 .dj_ie6 .dijitSplitterHHover, .dj_ie6 .claro .dijitSplitterVHover {
   background-color: #cfe5fa;
diff --git a/dijit/themes/claro/layout/BorderContainer.less b/dijit/themes/claro/layout/BorderContainer.less
index 17c4b63..b7c672e 100644
--- a/dijit/themes/claro/layout/BorderContainer.less
+++ b/dijit/themes/claro/layout/BorderContainer.less
@@ -97,7 +97,7 @@ Splitters and gutters:
 /* hovered splitter */
 .claro .dijitSplitterHHover {
 	font-size: 1px;
-	background: url("images/splitterHorizontalHover.png") no-repeat center top;
+	background: url("../@{image-layout-splitter-horizontal-hover}") no-repeat center top;
 }
 
 
@@ -107,7 +107,7 @@ Splitters and gutters:
 
 .claro .dijitSplitterVHover {
 	font-size: 1px;
-	background: url("images/splitterVerticalHover.png") no-repeat center left;
+	background: url("../@{image-layout-splitter-vertical-hover}") no-repeat center left;
 }
 
 .claro .dijitSplitterVHover .dijitSplitterThumb {
diff --git a/dijit/themes/claro/layout/TabContainer.css b/dijit/themes/claro/layout/TabContainer.css
index 030e4b7..641b921 100644
--- a/dijit/themes/claro/layout/TabContainer.css
+++ b/dijit/themes/claro/layout/TabContainer.css
@@ -60,7 +60,7 @@
   border-color: #b5bcc7;
 }
 .claro .dijitTabCloseButton {
-  background: url("images/tabClose.png") no-repeat;
+  background: url("../layout/images/tabClose.png") no-repeat;
   width: 14px;
   height: 14px;
   margin-left: 5px;
@@ -85,7 +85,7 @@
   -webkit-transition-duration: 0.35s;
   -moz-transition-duration: 0.35s;
   transition-duration: 0.35s;
-  color: #4a4a4a;
+  color: #494949;
 }
 .claro .dijitTabHover .dijitTabInnerDiv {
   background-color: #abd6ff;
@@ -95,7 +95,7 @@
   color: #000000;
 }
 .claro .dijitTabActive .dijitTabInnerDiv {
-  background-color: #7dbefa;
+  background-color: #7dbdfa;
   color: #000000;
   -webkit-transition-duration: 0.1s;
   -moz-transition-duration: 0.1s;
@@ -109,10 +109,10 @@
   border: 1px solid #b5bcc7;
 }
 .claro .dijitTabHover .dijitTabContent {
-  border-color: #769dc0;
+  border-color: #759dc0;
 }
 .claro .dijitTabActive .dijitTabContent {
-  border-color: #769dc0;
+  border-color: #759dc0;
 }
 .claro .dijitTabChecked .dijitTabContent {
   color: #000000;
@@ -140,7 +140,7 @@
 .claro .dijitTabContainerTop-tabs .dijitTabContent {
   padding: 3px 6px;
   border-bottom-width: 0;
-  background-image: url("images/tabTop.png");
+  background-image: url("../layout/images/tabTop.png");
   background-position: 0 0;
   background-repeat: repeat-x;
   min-width: 60px;
@@ -152,7 +152,7 @@
 }
 /* normal status */
 .claro .dijitTabContainerTop-tabs .dijitTabInnerDiv {
-  background-image: url("images/tabTop.png");
+  background-image: url("../layout/images/tabTop.png");
   background-position: 0 -248px;
   background-position: bottom;
   background-repeat: repeat-x;
@@ -183,7 +183,7 @@
 .claro .dijitTabContainerBottom-tabs .dijitTabContent {
   padding: 3px 6px;
   border-top-width: 0;
-  background-image: url("images/tabBottom.png");
+  background-image: url("../layout/images/tabBottom.png");
   background-position: 0 -249px;
   background-repeat: repeat-x;
   background-position: bottom;
@@ -195,7 +195,7 @@
 }
 /* normal status */
 .claro .dijitTabContainerBottom-tabs .dijitTabInnerDiv {
-  background-image: url("images/tabBottom.png");
+  background-image: url("../layout/images/tabBottom.png");
   background-position: top;
   background-repeat: repeat-x;
   -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
@@ -228,13 +228,13 @@
 }
 /* normal status */
 .claro .dijitTabContainerLeft-tabs .dijitTabInnerDiv {
-  background-image: url("images/tabLeft.png");
+  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("images/tabLeft.png");
+  background-image: url("../layout/images/tabLeft.png");
   background-repeat: repeat-y;
   background-position: 0 0;
 }
@@ -262,13 +262,13 @@
 }
 /* normal status */
 .claro .dijitTabContainerRight-tabs .dijitTabInnerDiv {
-  background-image: url("images/tabRight.png");
+  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("images/tabRight.png");
+  background-image: url("../layout/images/tabRight.png");
   background-position: right top;
   background-repeat: repeat-y;
 }
@@ -304,19 +304,19 @@
 }
 /************ left/right scroll buttons + menu button ************/
 .claro .tabStripButton {
-  background-color: #e9f4fe;
+  background-color: #e5f2fe;
   border: 1px solid #b5bcc7;
 }
 .claro .dijitTabListContainer-top .tabStripButton {
   padding: 4px 3px;
   margin-top: 7px;
-  background-image: url("images/tabTop.png");
+  background-image: url("../layout/images/tabTop.png");
   background-position: 0 0;
 }
 .claro .dijitTabListContainer-bottom .tabStripButton {
   padding: 5px 3px;
   margin-bottom: 4px;
-  background-image: url("images/tabTop.png");
+  background-image: url("../layout/images/tabTop.png");
   background-position: 0 -248px;
   background-position: bottom;
 }
@@ -324,7 +324,7 @@
   background-color: #abd6ff;
 }
 .claro .tabStripButtonActive {
-  background-color: #7dbefa;
+  background-color: #7dbdfa;
 }
 .claro .dijitTabStripIcon {
   height: 15px;
@@ -393,7 +393,7 @@
   box-shadow: none;
 }
 .claro .dijitTabContainerTabListNested .dijitTabHover .dijitTabContent {
-  background-color: #e9f4fe;
+  background-color: #e5f2fe;
   border: solid 1px #cfe5fa;
   padding: 3px;
   -webkit-transition-duration: 0.2s;
@@ -404,16 +404,16 @@
   text-decoration: none;
 }
 .claro .dijitTabContainerTabListNested .dijitTabActive .dijitTabContent {
-  border: solid 1px #769dc0;
+  border: solid 1px #759dc0;
   padding: 3px;
-  background: #abd6ff url("images/tabNested.png") repeat-x;
+  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 {
   padding: 3px;
-  border: solid 1px #769dc0;
+  border: solid 1px #759dc0;
   background-position: 0 105px;
   background-color: #cfe5fa;
 }
diff --git a/dijit/themes/claro/layout/TabContainer.less b/dijit/themes/claro/layout/TabContainer.less
index 691900e..16947ff 100644
--- a/dijit/themes/claro/layout/TabContainer.less
+++ b/dijit/themes/claro/layout/TabContainer.less
@@ -62,7 +62,7 @@
 	border-color: @border-color;
 }
 .claro .dijitTabCloseButton {
-	background: url("images/tabClose.png") no-repeat;
+	background: url("../@{image-layout-tab-close}") no-repeat;
 	width: 14px;
 	height: 14px;
 	margin-left: 5px;
@@ -135,7 +135,7 @@
 .claro .dijitTabContainerTop-tabs .dijitTabContent {
 	padding:3px 6px;
 	border-bottom-width: 0;
-	background-image:url("images/tabTop.png");
+	background-image:url("../@{image-layout-tab-top}");
 	background-position:0 0;
 	background-repeat:repeat-x;
 	min-width: 60px;
@@ -148,7 +148,7 @@
 
 /* normal status */
 .claro .dijitTabContainerTop-tabs .dijitTabInnerDiv {
-	background-image:url("images/tabTop.png");
+	background-image:url("../@{image-layout-tab-top}");
 	background-position:0 -248px;
 	background-position:bottom;
 	background-repeat:repeat-x;
@@ -176,7 +176,7 @@
 .claro .dijitTabContainerBottom-tabs .dijitTabContent {
 	padding:3px 6px;
 	border-top-width: 0;
-	background-image: url("images/tabBottom.png");
+	background-image: url("../@{image-layout-tab-bottom}");
 	background-position:0 -249px;
 	background-repeat: repeat-x;
 	background-position:bottom;
@@ -188,7 +188,7 @@
 }
 /* normal status */
 .claro .dijitTabContainerBottom-tabs .dijitTabInnerDiv {
-	background-image: url("images/tabBottom.png");
+	background-image: url("../@{image-layout-tab-bottom}");
 	background-position: top;
 	background-repeat: repeat-x;
 	.box-shadow(0 1px 1px rgba(0, 0, 0, 0.04));
@@ -218,13 +218,13 @@
 }
 /* normal status */
 .claro .dijitTabContainerLeft-tabs .dijitTabInnerDiv {
-	background-image: url("images/tabLeft.png");
+	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("images/tabLeft.png");
+	background-image: url("../@{image-layout-tab-left}");
 	background-repeat: repeat-y;
 	background-position:0 0;
 }
@@ -249,13 +249,13 @@
 }
 /* normal status */
 .claro .dijitTabContainerRight-tabs .dijitTabInnerDiv {
-	background-image: url("images/tabRight.png");
+	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("images/tabRight.png");
+	background-image: url("../@{image-layout-tab-right}");
 	background-position:right top;
 	background-repeat: repeat-y;
 }
@@ -298,13 +298,13 @@
 .claro .dijitTabListContainer-top .tabStripButton {
 	padding: 4px 3px;
 	margin-top:7px;
-	background-image: url("images/tabTop.png");
+	background-image: url("../@{image-layout-tab-top}");
 	background-position:0 0;
 }
 .claro .dijitTabListContainer-bottom .tabStripButton {
 	padding:5px 3px;
 	margin-bottom:4px;
-	background-image: url("images/tabTop.png");
+	background-image: url("../@{image-layout-tab-top}");
 	background-position:0 -248px;
 	background-position:bottom;
 }
@@ -318,7 +318,7 @@
 	height:15px;
 	width:15px;
 	margin: 0 auto;
-	background:url("../form/images/buttonArrows.png") no-repeat -75px 50%;
+	background:url("../@{image-form-button-arrows}") no-repeat -75px 50%;
 	background-color: transparent;
 }
 .claro .dijitTabStripSlideRightIcon{
@@ -382,7 +382,7 @@
 .claro .dijitTabContainerTabListNested .dijitTabActive .dijitTabContent {
 	border:solid 1px @nestedtab-selected-border-color;
 	padding: 3px;
-	background: @nestedtab-selected-background-color url("images/tabNested.png") repeat-x;
+	background: @nestedtab-selected-background-color url("../@{image-layout-tab-nested}") repeat-x;
 	.transition-duration(.1s);
 }
 .claro .dijitTabContainerTabListNested .dijitTabChecked .dijitTabContent {
diff --git a/dijit/themes/claro/variables.less b/dijit/themes/claro/variables.less
index 8d09c25..ca7d677 100644
--- a/dijit/themes/claro/variables.less
+++ b/dijit/themes/claro/variables.less
@@ -1,149 +1,204 @@
 // General
- at text-color: #000000;				// Text color for enabled widgets
 
- at border-color: #b5bcc7;				// Border color for (enabled, unhovered) TextBox, Slider, Accordion, BorderContainer, TabContainer
- at popup-border-color: #769dc0;		// Border for Dialog, Menu, Tooltip.   Must also update tooltip.png (the arrow image file) to match
- at minor-border-color: #d3d3d3;		// Color of borders inside widgets: horizontal line in Calendar between weeks, around color swatches in ColorPalette, above Dialog action bar
+ at primary-color: #cfe5fa;													// Base color for entire theme
+ at secondary-color: #efefef;												// Base color for bar-backgrounds
+ at text-color: #000;													// Text color for enabled widgets
+ at disabled-color: #d3d3d3;												// Base for disabled backgrounds and borders
+ at error-color: #d46464;
 
- at disabled-border-color: #d3d3d3;	// Border color for disabled/readonly Button, TextBox etc. widgets
- at disabled-background-color: #efefef;// Disabled button, textbox, etc.
- at disabled-text-color: #818181;		// Text color for disabled/readonly widgets
+ at container-background-color:#fff;										// Backgrounds for various content areas such as TitlePane, ContentPane and Inputs
 
- at unselected-background-color: #efefef;// Background color for unselected/unopened tab button, accordion pane, TitlePane, Menu items
- at unselected-text-color: #4a4a4a;	// Text color for unselected/unopened tab button, accordion pane, TitlePane, Menu items
+ at minor-selected-color: spin(saturate(darken(@primary-color, 6), 19), 0);						// Color for various arrows and buttons
+ at base-border-color: spin(desaturate(darken(@primary-color, 29), 44), -1);		// Augmented and used directly by variables to create border colors for various widgets
+ at unfocused-clickable-color: spin(saturate(lighten(@primary-color, 5), 10), 0);				// Background color for enabled buttons, text inputs
+ at border-color: spin(desaturate(darken(@primary-color, 15), 67), 8);						// Border color for (enabled, unhovered) TextBox, Slider, Accordion, BorderContainer, TabContainer
+ at minor-border-color: @disabled-color;									// Color of borders inside widgets: horizontal line in Calendar between weeks, around color swatches in ColorPalette, above Dialog action bar
+ at popup-border-color: @base-border-color;								// Border for Dialog, Menu, Tooltip.   Must also update tooltip.png (the arrow image file) to match
 
- at hovered-border-color: #769dc0;		// Hover of textbox, tab label, BorderContainer splitter, Calendar, etc.
- at hovered-background-color: #abd6ff;	// Background color for hover of Button, MenuBar, Accordion pane, Calendar... anything that has a (non-white) color to start with and gets darker on hover
- at hovered-text-color: @text-color;	// Used for title of select Accordion pane, label of select tab, hovered Menu item, etc.
 
- at pressed-border-color: #769dc0;		// During click on Calendar day, Slider up/down buttons, tab button, etc.
- at pressed-background-color: #7dbefa;	// Background color while clicking on Accordion/TitlePane title bar, tab button, Calendar day, Toolbar button, Tree row.
+ at disabled-border-color: @disabled-color;								// Border color for disabled/readonly Button, TextBox etc. widgets
+ at disabled-background-color: @secondary-color;							// Disabled button, textbox, etc.
+ at disabled-text-color: darken(@secondary-color, 43);											// Text color for disabled/readonly widgets
 
- at selected-border-color: #769dc0;	// Selected AccordionPane, tab of nested TabContainer (but plain TabContainer is special)
- at selected-background-color: #cfe5fa;// Selected Accordion pane, nested tab label, Tree row
- at selected-text-color: @text-color;	// title of selected Accordion pane, label of selected tab, hovered Menu item, etc.
+ at unselected-background-color: @secondary-color;							// Background color for unselected/unopened tab button, accordion pane, TitlePane, Menu items
+ at unselected-text-color: darken(@secondary-color, 65);										// Text color for unselected/unopened tab button, accordion pane, TitlePane, Menu items
 
- at bar-background-color: #efefef;		// MenuBar, Toolbar, action bar at bottom of dialog
- at pane-background-color: #fff;		// Background color of Accordion panes, Dialogs, etc.
- at popup-background-color: #fff;		// Background for Dialog.   TODO: currently use for ColorPalette, maybe should change.
+ at hovered-border-color: @base-border-color;								// Hover of textbox, tab label, BorderContainer splitter, Calendar, etc.
+ at hovered-background-color: @minor-selected-color;	// Background color for hover of Button, MenuBar, Accordion pane, Calendar... anything that has a (non-white) color to start with and gets darker on hover
+ at hovered-text-color: @text-color;										// Used for title of select Accordion pane, label of select tab, hovered Menu item, etc.
+
+ at pressed-border-color:  @base-border-color;								// During click on Calendar day, Slider up/down buttons, tab button, etc.
+ at pressed-background-color: spin(saturate(darken(@primary-color, 16), 12), 0);					// Background color while clicking on Accordion/TitlePane title bar, tab button, Calendar day, Toolbar button, Tree row.
+
+ at selected-border-color: @base-border-color;  							// Selected AccordionPane, tab of nested TabContainer (but plain TabContainer is special)
+ at selected-background-color: @primary-color;								// Selected Accordion pane, nested tab label, Tree row
+ at selected-text-color: @text-color;										// title of selected Accordion pane, label of selected tab, hovered Menu item, etc.
+
+ at bar-background-color: @secondary-color;								// MenuBar, Toolbar, action bar at bottom of dialog
+ at pane-background-color: @container-background-color;					// Background color of Accordion panes, Dialogs, etc.
+ at popup-background-color: @container-background-color;					// Background for Dialog.   TODO: currently use for ColorPalette, maybe should change.
 
 
 
 // Buttons
- at button-border-color: #769dc0;				// Border for (stand-alone) buttons in normal, hovered, or active state
- at button-background-color: #e9f4fe;			// Background color for (unhovered) buttons
- at button-hovered-background-color: #abd6ff;	// Background color for hovered buttons
- at button-pressed-background-color: #abd6ff;	// Background color for active buttons
- at button-border-radius: 4px;					// Rounded corner radius for buttons (except in toolbar)
+ at button-border-color:  @base-border-color;								// Border for (stand-alone) buttons in normal, hovered, or active state
+ at button-background-color: @unfocused-clickable-color;					// Background color for (unhovered) buttons
+ at button-hovered-background-color: @minor-selected-color;	// Background color for hovered buttons
+ at button-pressed-background-color: @minor-selected-color;				// Background color for active buttons
+ at button-border-radius: 4px;												// Rounded corner radius for buttons (except in toolbar)
 
 // Input widgets
- at focused-border-color: #769dc0;				// Focused textbox, editor, select, etc.
- at error-border-color: #d46464;				// Border for textbox in error state
- at error-focused-border-color: #ce4f4f;		// Border of textbox in error state, and focused
- at erroricon-background-color: #d46464;		// Background color for exclamation point validation icon (for TextBox in error state)
- at textbox-background-color: #fff;			// Default background color of TextBox based widgets
- at textbox-hovered-background-color: #e9f4fe;	// Background color when hovering a unfocused TextBox, Select, Editor, or other input widget
+ at focused-border-color: @base-border-color;								// Focused textbox, editor, select, etc.
+ at error-border-color: @error-color;											// Border for textbox in error state
+ at error-focused-border-color: darken(@error-color, 5);									// Border of textbox in error state, and focused
+ at erroricon-background-color: @error-color;									// Background color for exclamation point validation icon (for TextBox in error state)
+ at textbox-background-color: @container-background-color;					// Default background color of TextBox based widgets
+ at textbox-hovered-background-color: @unfocused-clickable-color;			// Background color when hovering a unfocused TextBox, Select, Editor, or other input widget
 @textbox-focused-background-color: @textbox-background-color;
 @textbox-error-background-color: @textbox-background-color;
 @textbox-disabled-background-color: @disabled-background-color;
 
- at textbox-padding: 2px;						// Padding for Textbox, Textarea, etc.
+ at textbox-padding: 2px;	// Padding for Textbox, Textarea, etc.
 
 // CheckBox, RadioButton
- at focus-outline-color: #4a4a4a;				// Color for artificial focus outline around labels of checkboxes
+ at focus-outline-color: darken(@secondary-color, 65);											// Color for artificial focus outline around labels of checkboxes
 
 // TabContainer
- at nestedtab-hovered-background-color: @textbox-hovered-background-color;
- at nestedtab-hovered-border-color: #cfe5fa;
+ at nestedtab-hovered-background-color: @unfocused-clickable-color;
+ at nestedtab-hovered-border-color: @primary-color;
 @nestedtab-selected-border-color: @selected-border-color;
- at nestedtab-selected-background-color: #abd6ff;
- at tab-disabled-background-color: #d3d3d3;		// For disabled tabs of a TabContainer (not officially supported)
+ at nestedtab-selected-background-color: @minor-selected-color;
+ at tab-disabled-background-color: @disabled-color;						// For disabled tabs of a TabContainer (not officially supported)
 
 // Arrow buttons (stand alone, or inside ComboBox / ComboButton / Spinner / etc.
- at arrowbutton-background-color: #efefef;
- at arrowbutton-hovered-background-color: #abd6ff;	// Color of arrow when hovering ComboBox.   But hovering Spinner doesn't change arrow color (TODO)
- at arrowbutton-pressed-background-color: #abd6ff;
- at arrowbutton-inner-border-color: #fff;			// Typically the arrows have an inner white border (a.k.a. padding) and then an outer black-ish border
+ at arrowbutton-background-color: @secondary-color;
+ at arrowbutton-hovered-background-color: @minor-selected-color;			// Color of arrow when hovering ComboBox.   But hovering Spinner doesn't change arrow color (TODO)
+ at arrowbutton-pressed-background-color: @minor-selected-color;
+ at arrowbutton-inner-border-color: @container-background-color;									// Typically the arrows have an inner white border (a.k.a. padding) and then an outer black-ish border
 
 // Slider
 // Note: any changes here require corresponding changes in form/images/sliderThumbs.png
- at slider-fullbar-background-color: #cfe5fa;			// Background color for part of slider bar before (to the left or below) the handle
- at slider-remainingbar-background-color: #fff;		// Background color for part of slider bar after (to the right or above) the handle
- at slider-hovered-fullbar-background-color: #abd6ff;	// Background color for part of bar of hovered slider before (to the left or below) the handle
- at slider-hovered-remainingbar-background-color: #fff;// Background color for part of bar of hovered slider after (to the right or above) the handle
- at slider-hoveredButton-background-color: #fff;		// Background color of slider increment/decrement buttons when mouse is over slider but not over the buttons
- at slider-focused-fullbar-background-color: #abd6ff;	// Background color for part of bar of focused slider before (to the left or below) the handle
- at slider-focused-remainingbar-background-color: #fff;// Background color for part of bar of focused slider after (to the right or above) the handle
- at slider-button-hovered-background-color: #cfe5fa;	// Background color of slider increment/decrement buttons when mouse is over the buttons
- at slider-button-pressed-background-color: #abd6ff;	// Background color of slider increment/decrement buttons while button is depressed
+ at slider-fullbar-background-color: @primary-color;							// Background color for part of slider bar before (to the left or below) the handle
+ at slider-remainingbar-background-color: @container-background-color;			// Background color for part of slider bar after (to the right or above) the handle
+ at slider-hovered-fullbar-background-color: @minor-selected-color;			// Background color for part of bar of hovered slider before (to the left or below) the handle
+ at slider-hovered-remainingbar-background-color: @container-background-color;	// Background color for part of bar of hovered slider after (to the right or above) the handle
+ at slider-hoveredButton-background-color: @container-background-color;		// Background color of slider increment/decrement buttons when mouse is over slider but not over the buttons
+ at slider-focused-fullbar-background-color: @minor-selected-color;			// Background color for part of bar of focused slider before (to the left or below) the handle
+ at slider-focused-remainingbar-background-color: @container-background-color;	// Background color for part of bar of focused slider after (to the right or above) the handle
+ at slider-button-hovered-background-color: @primary-color;					// Background color of slider increment/decrement buttons when mouse is over the buttons
+ at slider-button-pressed-background-color: @minor-selected-color;				// Background color of slider increment/decrement buttons while button is depressed
 
 // Select, ComboBox
- at select-dropdownitem-background-color: #fff;			// Background color for items in the drop down list of a ComboBox/Select
- at select-dropdownitem-hovered-background-color: #7dbefa;	// Background color for the hovered item in the drop down list of a ComboBox/Select
- at select-matchedtext-background-color: #abd6ff;			// Background color of text in ComboBox drop down that matches typed in phrase
+ at select-dropdownitem-background-color: @container-background-color;			// Background color for items in the drop down list of a ComboBox/Select
+ at select-dropdownitem-hovered-background-color: @pressed-background-color;	// Background color for the hovered item in the drop down list of a ComboBox/Select
+ at select-matchedtext-background-color: @minor-selected-color;				// Background color of text in ComboBox drop down that matches typed in phrase
 
 // Menus
 @menu-background-color: @popup-background-color;
 
 // Calendar
- at calendar-background-color: #cfe5fa;
- at calendar-currentmonth-background-color: #fff;		// Background color for days of the current month
- at calendar-adjacentmonth-background-color: #e9f4fe;	// Background color used for days from previous or next month
- at calendar-adjacentmonth-text-color: #769dc0;		// Text color used for days from previous or next month
- at calendar-date-pressed-border-color: #fff;			// For some reason pressing a day of the month (as opposed to hovering it) makes the border go away, is this intentional?
+ at calendar-background-color: @primary-color;
+ at calendar-currentmonth-background-color: @container-background-color;		// Background color for days of the current month
+ at calendar-adjacentmonth-background-color: @unfocused-clickable-color;		// Background color used for days from previous or next month
+ at calendar-adjacentmonth-text-color: @base-border-color;						// Text color used for days from previous or next month
+ at calendar-date-pressed-border-color: @container-background-color;			// For some reason pressing a day of the month (as opposed to hovering it) makes the border go away, is this intentional?
 @calendar-date-pressed-background-color: @pressed-background-color;
 @calendar-date-selected-border-color: @selected-border-color;
- at calendar-date-selected-background-color: #abd6ff;
- at calendar-button-hovered-background-color: #e9f4fe;	// for hover or next/previous year, and month drop down (TODO: border and background are built in to calendarArrows.png, can't control from here)
- at calendar-button-hovered-border-color: #fff;		// for hover or next/previous year, and month drop down
- at calendar-button-pressed-background-color: #cfe5fa;
+ at calendar-date-selected-background-color: @minor-selected-color;
+ at calendar-button-hovered-background-color: @unfocused-clickable-color;		// for hover or next/previous year, and month drop down (TODO: border and background are built in to calendarArrows.png, can't control from here)
+ at calendar-button-hovered-border-color: @container-background-color;			// for hover or next/previous year, and month drop down
+ at calendar-button-pressed-background-color: @pressed-background-color;
 @calendar-button-pressed-border-color: @pressed-border-color;
 
 
 // ProgressBar
- at progressbar-border-color: @popup-border-color;	// Border color of progress bar
- at progressbar-full-background-color:#abd6ff;		// Background color for part of progress bar indicating amount completed
- at progressbar-empty-background-color: #fff;		// Background color for part of progress bar indicating amount remaining
- at progressbar-text-color: @text-color;			// Color of progress bar text (ex: "35%").  Must contrast with both empty and full background colors.
+ at progressbar-border-color: @popup-border-color;								// Border color of progress bar
+ at progressbar-full-background-color:@minor-selected-color;					// Background color for part of progress bar indicating amount completed
+ at progressbar-empty-background-color: @container-background-color;			// Background color for part of progress bar indicating amount remaining
+ at progressbar-text-color: @text-color;										// Color of progress bar text (ex: "35%").  Must contrast with both empty and full background colors.
 
 // TimePicker
- at timepicker-minorvalue-background-color: #efefef;	// For 3:15, 3:30, 3:45 but not 3:00 or 4:00
- at timepicker-minorvalue-text-color: #818181;
- at timepicker-majorvalue-background-color: #e9f4fe;	// For 3:00, 4:00, 5:00, etc.
- at timepicker-value-hovered-background-color: #7dbefa;
+ at timepicker-minorvalue-background-color: @secondary-color;	// For 3:15, 3:30, 3:45 but not 3:00 or 4:00
+ at timepicker-minorvalue-text-color: darken(@secondary-color, 43);
+ at timepicker-majorvalue-background-color: @unfocused-clickable-color;	// For 3:00, 4:00, 5:00, etc.
+ at timepicker-value-hovered-background-color: @pressed-background-color;
 @timepicker-value-hovered-text-color: @hovered-text-color;
- at timepicker-arrow-hovered-background-color: #abd6ff;
+ at timepicker-arrow-hovered-background-color: @minor-selected-color;
 
 // ColorPalette
- at colorpalette-background-color: #fff;
+ at colorpalette-background-color: @container-background-color;
 @swatch-border-color: @minor-border-color;
 @swatch-hovered-border-color: #000;
 @swatch-selected-border-color: #000;
 
 // Dialog
- at dialog-underlay-color: #fff;			// the thing that grays out the screen when a dialog is shown
- at dialog-titlebar-border-color: #fff;	// Inner border around the title sectionof a Dialog, inside the main border of the Dialog and the border between title and content
- at dialog-titlebar-background-color: #abd6ff;
+ at dialog-underlay-color: @container-background-color;			// the thing that grays out the screen when a dialog is shown
+ at 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
+ at dialog-titlebar-background-color: @minor-selected-color;
 
 // BorderContainer
- at splitter-hovered-background-color: #cfe5fa;	// Color of splitter when user hovers it, before mouse down
- at splitter-dragged-background-color: #abd6ff;	// Color of splitter while it's being dragged
+ at splitter-hovered-background-color: @primary-color;	// Color of splitter when user hovers it, before mouse down
+ at splitter-dragged-background-color: @minor-selected-color;	// Color of splitter while it's being dragged
 
 // Toolbar
- at toolbar-button-checked-background-color: #fff;								// a toggled-on button in the toolbar
- at toolbar-combobutton-hovered-unhoveredsection-background-color: #f4ffff;	// when user hovers a ComboButton in a Toolbar, the other half of the button turns this color
+ at toolbar-button-checked-background-color: @container-background-color;								// a toggled-on button in the toolbar
+ at toolbar-combobutton-hovered-unhoveredsection-background-color: spin(saturate(lighten(@primary-color, 8), 19), -29);	// when user hovers a ComboButton in a Toolbar, the other half of the button turns this color
 @toolbar-button-border-radius: 2px;			// Rounded corner radius for buttons for buttons in toolbar
 
 // DnD
- at dnd-avatar-background-color: #fff;					// Background color of little Dialog-type box indicating dragged items
+ at dnd-avatar-background-color: @container-background-color;					// Background color of little Dialog-type box indicating dragged items
 @dnd-avatar-header-background-color: #f58383;		// Title bar for dragged items
 @dnd-avatar-candrop-header-background-color: #97e68d;// Title bar for dragged items when they can be dropped
- at dnd-dropseparator-color: #769dc0;					// Color of line indicating that user is about to drop between items A & B
+ at dnd-dropseparator-color: @base-border-color;					// Color of line indicating that user is about to drop between items A & B
 
 // Document level
- at document-text-color: #131313;									// Text color for document itself (text outside of widgets)
+ at document-text-color: #131313;								// Text color for document itself (text outside of widgets)
 @document-shadedsection-background-color: @bar-background-color;// background color used for <pre>, <code>, and table header rows
- at document-border-color: #d3d3d3;								// Border for <pre>, <code>, tables, etc.
+ at document-border-color: @disabled-color;								// Border for <pre>, <code>, tables, etc.
+
+// Images
+ at image-arrow-sprite: "images/spriteArrows.png";
+ at image-calendar-container: "images/calendarContainerImages.png";
+ at image-calendar-arrows: "images/calendarArrows.png";
+ at image-calendar-arrows-ie6: "images/calendarArrows8bit.png";
+ at image-checkmark: "images/checkmarkNoBorder.png";
+ at image-checkmark-ie6: "images/checkmarkNoBorder.gif";
+ at image-common-highlight: "images/commonHighlight.png";
+ at image-dialog-close: "images/dialogCloseIcon.png";
+ at image-dialog-close-ie6: "images/dialogCloseIcon8bit.png";
+ at image-dnd: "images/dnd.png";
+ at image-editor-icons-enabled: "../../icons/images/editorIconsEnabled.png";
+ at image-form-button: "form/images/button.png";
+ at image-form-button-arrows: "form/images/buttonArrows.png";
+ at image-form-checkbox-and-radios: "form/images/checkboxRadioButtonStates.png";
+ at image-form-checkbox-and-radios-ie6: "form/images/checkboxAndRadioButtons_IE6.png";
+ at image-form-common-arrows: "form/images/commonFormArrows.png";
+ at image-form-error: "form/images/error.png";
+ at image-form-highlight: "form/images/formHighlight.png";
+ at image-form-slider-horizontal: "form/images/sliderHorizontal.png";
+ at 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-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-tree-expand: "images/treeExpandImages.png";
+ at image-tree-expand-ie6: "images/treeExpandImages8bit.png";
 
 // Mixins
 
diff --git a/dijit/themes/dijit.css b/dijit/themes/dijit.css
index b6d57dc..4c60bf3 100644
--- a/dijit/themes/dijit.css
+++ b/dijit/themes/dijit.css
@@ -39,6 +39,12 @@
 	#vertical-align: auto;	/* makes TextBox,Button line up w/native counterparts on IE6 */
 }
 
+table.dijitInline {
+	/* To inline tables with a given width set */
+	display:inline-table;
+	box-sizing: content-box; -moz-box-sizing: content-box;
+}
+
 .dijitHidden {
 	/* To hide unselected panes in StackContainer etc. */
 	display: none !important;
@@ -60,8 +66,8 @@
 	#display: inline;
 }
 
-.dj_ie INPUT.dijitTextBox,
-.dj_ie .dijitTextBox INPUT {
+.dj_ie input.dijitTextBox,
+.dj_ie .dijitTextBox input {
 	font-size: 100%;
 }
 .dijitTextBox .dijitSpinnerButtonContainer,
@@ -70,7 +76,7 @@
 	float: right;
 	text-align: center;
 }
-.dijitTextBox INPUT.dijitInputField {
+.dijitTextBox input.dijitInputField {
 	/* override unreasonable user styling of buttons and icons */
 	padding-left: 0 !important;
 	padding-right: 0 !important;
@@ -78,16 +84,6 @@
 .dijitTextBox .dijitValidationContainer {
 	display: none;
 }
-.dijitInlineTable {
-	/* To inline tables with a given width set (otherwise, use dijitInline above) */
-	display:inline-table;
-	display:inline-block;		/* webkit and FF3 */
-	#zoom: 1; /* set hasLayout:true to mimic inline-block */
-	#display:inline; /* don't use .dj_ie since that increases the priority */
-	box-sizing: content-box; -moz-box-sizing: content-box;
-	border:0;
-	padding:0;
-}
 
 .dijitTeeny {
 	font-size:1px;
@@ -157,16 +153,16 @@
 		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 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 {
 	/* 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 */
+	 * exception for input.dijitArrowButtonInner, because the icon and character are controlled by the same node */
 	display: none;
 }
-.dijitSpinner DIV.dijitArrowButtonInner {
+.dijitSpinner div.dijitArrowButtonInner {
 	display: block; /* override previous rule */
 }
 
@@ -183,14 +179,16 @@
  */
 .dijit_a11y .dijitCalendarDateLabel {
 	padding: 1px;
+	border: 0px !important;
 }
 .dijit_a11y .dijitCalendarSelectedDate .dijitCalendarDateLabel {
-	border-style: dotted !important;
-	border-width: 1px;
+	border-style: solid !important;
+	border-width: 1px !important;
 	padding: 0;
 }
 .dijit_a11y .dijitCalendarDateTemplate {
 	padding-bottom: 0.1em !important;	/* otherwise bottom border doesn't appear on IE */
+	border: 0px !important;
 }
 .dijit_a11y .dijitButtonNode {
 	border: black outset medium !important;
@@ -201,6 +199,10 @@
 	padding: 0 !important;
 }
 
+.dijit_a11y .dijitButtonContents{
+	margin: 0.15em; /* Margin needed to make focus outline visible */
+}
+
 .dijit_a11y .dijitTextBoxReadOnly .dijitInputField,
 .dijit_a11y .dijitTextBoxReadOnly .dijitButtonNode {
 	border-style: outset!important;
@@ -246,6 +248,9 @@
 }
 
 /* Buttons */
+.dj_gecko .dijit_a11y .dijitButtonDisabled .dijitButtonNode {
+	opacity: 0.5;
+}
 
 .dijitToggleButton,
 .dijitButton,
@@ -263,7 +268,7 @@ td.dijitButtonContents {
 	display: table-cell;	/* but don't affect Select, ComboButton */
 }
 
-.dijitButtonNode IMG {
+.dijitButtonNode img {
 	/* make text and images line up cleanly */
 	vertical-align:middle;
 	/*margin-bottom:.2em;*/
@@ -331,7 +336,7 @@ td.dijitButtonContents {
 	overflow: visible;
 }
 
-DIV.dijitArrowButton {
+div.dijitArrowButton {
 	float: right;
 }
 
@@ -351,14 +356,14 @@ DIV.dijitArrowButton {
 .dijitTextBoxDisabled {
 	color: gray;
 }
-.dj_webkit .dijitTextBoxDisabled INPUT {
+.dj_webkit .dijitTextBoxDisabled input {
 	color: #eee; /* because WebKit lightens disabled input/textarea no matter what color you specify */
 }
-.dj_webkit TEXTAREA.dijitTextAreaDisabled {
+.dj_webkit textarea.dijitTextAreaDisabled {
 	color: #333; /* because WebKit 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 {
+.dj_gecko .dijitTextBoxReadOnly input.dijitInputField, /* disable arrow and validation presentation inputs but allow real input for text selection */
+.dj_gecko .dijitTextBoxDisabled input {
 	-moz-user-input: none; /* prevent focus of disabled textbox buttons */
 }
 
@@ -377,14 +382,14 @@ DIV.dijitArrowButton {
 }
 
 /* rules for webkit to deal with fuzzy blue focus border */
-.dijitTextBox INPUT:focus {
+.dijitTextBox input:focus {
 	outline: none;	/* blue fuzzy line looks wrong on combobox or something w/validation icon showing */
 }
 .dijitTextBoxFocused {
-	outline: auto 5px -webkit-focus-ring-color;
+	outline: 5px -webkit-focus-ring-color;
 }
 
-.dijitTextBox INPUT {
+.dijitTextBox input {
 	float: left; /* needed by IE to remove secret margin */
 }
 .dijitInputInner {
@@ -399,11 +404,11 @@ DIV.dijitArrowButton {
 	margin-left: 0 !important;
 	margin-right: 0 !important;
 }
-.dijit_a11y .dijitTextBox INPUT {
+.dijit_a11y .dijitTextBox input {
 	margin: 0 !important;
 }
-.dijitTextBoxError INPUT.dijitValidationInner,
-.dijitTextBox INPUT.dijitArrowButtonInner {
+.dijitTextBoxError input.dijitValidationInner,
+.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
 	 */
@@ -415,26 +420,26 @@ DIV.dijitArrowButton {
 	#letter-spacing: -5em !important;
 	#text-align: right !important;
 }
-.dj_ie .dijitTextBox INPUT,
-.dj_ie INPUT.dijitTextBox {
-	overflow-y: visible; /* INPUTs need help expanding when padding is added or line-height is adjusted */
+.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 {
+.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 */
 }
-.dj_ie6 .dijitTextBox INPUT,
-.dj_ie6 INPUT.dijitTextBox,
-.dj_iequirks .dijitTextBox INPUT.dijitValidationInner,
-.dj_iequirks .dijitTextBox INPUT.dijitArrowButtonInner,
-.dj_iequirks .dijitTextBox INPUT.dijitSpinnerButtonInner,
-.dj_iequirks .dijitTextBox INPUT.dijitInputInner,
-.dj_iequirks INPUT.dijitTextBox {
+.dj_ie6 .dijitTextBox input,
+.dj_ie6 input.dijitTextBox,
+.dj_iequirks .dijitTextBox input.dijitValidationInner,
+.dj_iequirks .dijitTextBox input.dijitArrowButtonInner,
+.dj_iequirks .dijitTextBox input.dijitSpinnerButtonInner,
+.dj_iequirks .dijitTextBox input.dijitInputInner,
+.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 {
+.dijit_a11y input.dijitValidationInner,
+.dijit_a11y input.dijitArrowButtonInner {
 	/* (in high contrast mode) revert rules from above so character displays */
 	text-indent: 0 !important;
 	width: 1em !important;
@@ -495,7 +500,7 @@ DIV.dijitArrowButton {
 }
 .dijit_a11y .dijitTextBox .dijitSpinnerButtonContainer,
 .dijit_a11y .dijitSpinner .dijitArrowButtonInner,
-.dijit_a11y .dijitSpinnerButtonContainer INPUT {
+.dijit_a11y .dijitSpinnerButtonContainer input {
 	width: 1em !important;
 }
 .dijit_a11y .dijitSpinner .dijitArrowButtonInner {
@@ -620,8 +625,8 @@ DIV.dijitArrowButton {
 	overflow: hidden;
 }
 
-.dijitCheckBox INPUT,
-.dijitRadio INPUT {
+.dijitCheckBox input,
+.dijitRadio input {
 	margin: 0;
 	padding: 0;
 	display: block;
@@ -649,6 +654,11 @@ DIV.dijitArrowButton {
 	height: auto;
 }
 
+.dijit_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;
+}
 
 /****
 		dijit.ProgressBar
@@ -683,7 +693,7 @@ DIV.dijitArrowButton {
 	right:0;
 	margin:0;
 	padding:0;
-	width:auto;
+	width: 100%;    /* needed for IE/quirks */
 	height:auto;
 	background-color:#aaa;
 	background-attachment: fixed;
@@ -775,10 +785,10 @@ DIV.dijitArrowButton {
 	overflow: hidden;
 }
 
-body .dijitAlignTop,
-body .dijitAlignBottom,
-body .dijitAlignLeft,
-body .dijitAlignRight {
+.dijitAlignTop,
+.dijitAlignBottom,
+.dijitAlignLeft,
+.dijitAlignRight {
 	position: absolute;
 	overflow: hidden;
 }
@@ -786,7 +796,7 @@ body .dijitAlignRight {
 body .dijitAlignClient { position: absolute; }
 
 /*
- * BorderContaienr
+ * BorderContainer
  *
  * .dijitBorderContainer is a stylized layout where panes have border and margin.
  * .dijitBorderContainerNoGutter is a raw layout.
@@ -860,13 +870,13 @@ body .dijitAlignClient { position: absolute; }
 	height: 7px;
 	border-top:1px;
 	border-bottom:1px;
-	cursor: ns-resize;
+	cursor: row-resize;
 }
 .dijitSplitterV {
 	width: 7px;
 	border-left:1px;
 	border-right:1px;
-	cursor: ew-resize;
+	cursor: col-resize;
 }
 .dijitSplitContainer {
 	position: relative;
@@ -886,8 +896,6 @@ body .dijitAlignClient { position: absolute; }
 .dijitSplitContainerSizerV {
 	position:absolute;
 	font-size: 1px;
-	cursor: move;
-	cursor: w-resize;
 	background-color: ThreeDFace;
 	border: 1px solid;
 	border-color: ThreeDHighlight ThreeDShadow ThreeDShadow ThreeDHighlight;
@@ -916,11 +924,12 @@ body .dijitAlignClient { position: absolute; }
 	margin: 0;
 }
 
-.dj_ie .dijitSplitterV, .dijitSplitContainerVirtualSizerH {
-	cursor: w-resize;
+.dijitSplitContainerSizerH, .dijitSplitContainerVirtualSizerH {
+	cursor: col-resize;
 }
-.dj_ie .dijitSplitterH, .dijitSplitContainerSizerV, .dijitSplitContainerVirtualSizerV {
-	cursor: n-resize;
+
+.dijitSplitContainerSizerV, .dijitSplitContainerVirtualSizerV {
+	cursor: row-resize;
 }
 
 .dijit_a11y .dijitSplitterH {
@@ -947,6 +956,11 @@ body .dijitAlignClient { position: absolute; }
 	overflow: hidden;
 }
 
+.dijitContentPaneLoading .dijitIconLoading,
+.dijitContentPaneError .dijitIconError {
+	margin-right: 9px;
+}
+
 /* TitlePane */
 
 .dijitTitlePane {
@@ -1040,13 +1054,13 @@ body .dijitAlignClient { position: absolute; }
 .dijitPaletteTable td {
 		padding: 0;
 }
-.dijitColorPalette .dijitPaletteCellHover .dijitPaletteImg {
+.dijitColorPalette .dijitPaletteCell:hover .dijitPaletteImg {
 	/* hovered color swatch */
 	border: 1px solid #000;
 }
 
-.dijitColorPalette .dijitPaletteCellActive .dijitPaletteImg,
-.dijitColorPalette .dijitPaletteCellSelected .dijitPaletteImg {
+.dijitColorPalette .dijitPaletteCell:active .dijitPaletteImg,
+.dijitColorPalette .dijitPaletteTable .dijitPaletteCellSelected .dijitPaletteImg {
 	border: 2px solid #000;
 	margin: 1px 0;	/* reduce margin to compensate for increased border */
 }
@@ -1103,6 +1117,10 @@ body .dijitAlignClient { position: absolute; }
 	vertical-align: middle;
 }
 
+.dijitCalendarYearLabel {
+    white-space: nowrap;    /* make sure previous, current, and next year appear on same row */
+}
+
 .dijitCalendarNextYear {
 	margin:0 0 0 0.55em;
 }
@@ -1206,7 +1224,7 @@ body .dijitAlignClient { position: absolute; }
 	border: 1px dotted black !important;
 }
 .dj_ff3 .dijit_a11y .dijitMenuItem td {
-	padding: none !important;
+	padding: 0 !important;
 	background:none !important;
 }
 .dijit_a11y .dijitMenuItemSelected .dijitMenuItemLabel {
@@ -1294,6 +1312,7 @@ body .dijitAlignClient { position: absolute; }
 	width: 50000px;
 	display: block;
 	position: relative;
+    text-align: left;  /* just in case ancestor has non-standard setting */
 }
 .dijitTabListWrapper {
 	overflow: hidden;
@@ -1334,7 +1353,7 @@ body .dijitAlignClient { position: absolute; }
 	border-right: 0;
 }
 
-DIV.dijitTabDisabled, .dj_ie DIV.dijitTabDisabled {
+div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 	cursor: auto;
 }
 
@@ -1568,7 +1587,7 @@ DIV.dijitTabDisabled, .dj_ie DIV.dijitTabDisabled {
 	right:50%;
 }
 
-.dijit_a11y DIV.dijitSliderImageHandle,
+.dijit_a11y div.dijitSliderImageHandle,
 .dijitSliderImageHandle {
 	margin:0;
 	padding:0;
@@ -1816,7 +1835,7 @@ DIV.dijitTabDisabled, .dj_ie DIV.dijitTabDisabled {
 }
 
 /* + and - Slider buttons: override theme settings to display icons */
-.dijit_a11y .dijitSlider .dijitSliderButtonContainer DIV {
+.dijit_a11y .dijitSlider .dijitSliderButtonContainer div {
 	font-family: monospace; /* otherwise hyphen is larger and more vertically centered */
 	font-size: 1em;
 	line-height: 1em;
diff --git a/dijit/themes/dijit_rtl.css b/dijit/themes/dijit_rtl.css
index 8ef3a28..9c1b69c 100644
--- a/dijit/themes/dijit_rtl.css
+++ b/dijit/themes/dijit_rtl.css
@@ -11,7 +11,7 @@
 
 /* Button */
 
-.dj_iequirks .dijitComboButtonRtl BUTTON {
+.dj_iequirks .dijitComboButtonRtl button {
 	/* workaround bug where label invisible (themeTesterQuirk.html?dir=rtl) */
 	float:left;
 }
@@ -31,6 +31,11 @@
 	left: auto;
 }
 
+.dj_ie7 .dijitInputContainer {
+	/* to fix wrong text alignment in rtl text box in IE */
+	display: inline-block;
+}
+
 .dijitTextBoxRtl .dijitSpinnerButtonContainer,
 .dijitTextBoxRtl .dijitValidationContainer,
 .dijitTextBoxRtl .dijitArrowButtonContainer {
@@ -87,13 +92,18 @@
 }
 
 /* ContentPane*/
-.dijitRtl .dijitContentPaneLoading, .dijitRtl .dijitContentPaneError {
-	background-position:right;
-	padding-right:25px;
+
+.dijitRtl .dijitContentPaneLoading .dijitIconLoading,
+.dijitRtl .dijitContentPaneError .dijitIconError {
+	margin-right: 0;
+	margin-left: 9px;
 }
 
 /* TabContainer */
 
+.dijitTabControllerRtl .nowrapTabStrip {
+    text-align: right;  /* just in case ancestor has non-standard setting */
+}
 .dijitTabRtl .dijitTabCloseButton {
 	margin-left: 0;
 	margin-right: 1em;
@@ -115,4 +125,4 @@
 /* Select */
 .dijitSelectRtl .dijitButtonContents {
 	text-align: right;
-}
\ No newline at end of file
+}
diff --git a/dijit/themes/nihilo/Calendar.css b/dijit/themes/nihilo/Calendar.css
index 2c9248b..55bb2cc 100644
--- a/dijit/themes/nihilo/Calendar.css
+++ b/dijit/themes/nihilo/Calendar.css
@@ -119,10 +119,12 @@
 	margin:0;
 	padding:0.4em 0 0.25em 0;
 	text-align:center;
+	font-size: 1.17em;
 }
 
 .nihilo .dijitCalendarSelectedYear {
 	/* label for selected year */
+	font-weight:bolder;
 	color:black;
 	padding:0.2em;
 	padding-bottom:0.1em;
@@ -156,4 +158,4 @@
 .nihilo .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover {
 	background-color: #ffe284;
 	color: #243C5F;
-}
\ No newline at end of file
+}
diff --git a/dijit/themes/nihilo/form/Button.css b/dijit/themes/nihilo/form/Button.css
index 0be9ea4..90e1ee2 100644
--- a/dijit/themes/nihilo/form/Button.css
+++ b/dijit/themes/nihilo/form/Button.css
@@ -52,8 +52,8 @@
 	background:#fafafa url("../images/buttonDisabled.png") top repeat-x;
 	opacity: 0.60;
 }
-.dj_ie6 .nihilo .dijitReadOnly INPUT,
-.dj_ie7 .nihilo .dijitReadOnly INPUT,
+.dj_ie6 .nihilo .dijitReadOnly input,
+.dj_ie7 .nihilo .dijitReadOnly input,
 .dj_ie6 .nihilo .dijitComboButtonDisabled .dijitButtonText,
 .dj_ie7 .nihilo .dijitComboButtonDisabled .dijitButtonText {
 	/* opacity doesn't work on table node in IE, work around here */
diff --git a/dijit/themes/nihilo/form/Common.css b/dijit/themes/nihilo/form/Common.css
index 65dddc6..b67195f 100644
--- a/dijit/themes/nihilo/form/Common.css
+++ b/dijit/themes/nihilo/form/Common.css
@@ -10,7 +10,7 @@
 		dijit.form.ComboBox (partial)
  ****/
 
-.nihilo .dijitInputContainer INPUT,
+.nihilo .dijitInputContainer input,
 .nihilo .dijitTextBox {
 	margin: 0 0.1em;
 }
diff --git a/dijit/themes/nihilo/images/tooltipConnectorRight.png b/dijit/themes/nihilo/images/tooltipConnectorRight.png
index ed6efc4..3d62dcd 100644
Binary files a/dijit/themes/nihilo/images/tooltipConnectorRight.png and b/dijit/themes/nihilo/images/tooltipConnectorRight.png differ
diff --git a/dijit/themes/soria/Calendar.css b/dijit/themes/soria/Calendar.css
index 78572da..f77acd2 100644
--- a/dijit/themes/soria/Calendar.css
+++ b/dijit/themes/soria/Calendar.css
@@ -119,10 +119,12 @@
 	margin:0;
 	padding:0.4em 0 0.25em 0;
 	text-align:center;
+	font-size: 1.17em;
 }
 
 .soria .dijitCalendarSelectedYear {
 	/* label for selected year */
+	font-weight:bolder;
 	color:black;
 	padding:0.2em;
 	padding-bottom:0.1em;
@@ -156,4 +158,4 @@
 .soria .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover {
 	background-color: #d9e6f9;
 	color: #243C5F;
-}
\ No newline at end of file
+}
diff --git a/dijit/themes/soria/form/Button.css b/dijit/themes/soria/form/Button.css
index 6b813a6..9efe7ea 100644
--- a/dijit/themes/soria/form/Button.css
+++ b/dijit/themes/soria/form/Button.css
@@ -44,8 +44,8 @@
 	background:#c3d3e5 url("../images/buttonDisabled.png") top repeat-x;
 	opacity: 0.60;
 }
-.dj_ie6 .soria .dijitReadOnly INPUT,
-.dj_ie7 .soria .dijitReadOnly INPUT,
+.dj_ie6 .soria .dijitReadOnly input,
+.dj_ie7 .soria .dijitReadOnly input,
 .dj_ie6 .soria .dijitComboButtonDisabled .dijitButtonText,
 .dj_ie7 .soria .dijitComboButtonDisabled .dijitButtonText {
 	/* opacity doesn't work on table node in IE, work around here */
diff --git a/dijit/themes/soria/form/Common.css b/dijit/themes/soria/form/Common.css
index 8e3688e..42dfefa 100644
--- a/dijit/themes/soria/form/Common.css
+++ b/dijit/themes/soria/form/Common.css
@@ -10,7 +10,7 @@
 		dijit.form.ComboBox (partial)
  ****/
 
-.soria .dijitInputContainer INPUT,
+.soria .dijitInputContainer input,
 .soria .dijitTextBox {
 	margin: 0 0.1em;
 }
diff --git a/dijit/themes/soria/images/tooltipConnectorRight.png b/dijit/themes/soria/images/tooltipConnectorRight.png
index 64190ee..3d62dcd 100644
Binary files a/dijit/themes/soria/images/tooltipConnectorRight.png and b/dijit/themes/soria/images/tooltipConnectorRight.png differ
diff --git a/dijit/themes/themeTester-orig.html b/dijit/themes/themeTester-orig.html
index f5274ae..ece749f 100644
--- a/dijit/themes/themeTester-orig.html
+++ b/dijit/themes/themeTester-orig.html
@@ -13,7 +13,7 @@
 
 		html, body { height: 100%; width: 100%; padding: 0; border: 0; }
 		#main { height: 100%; width: 100%; border: 0; }
-		#header { margin: 0px; }
+		#header { margin: 0; }
 		#leftAccordion { width: 25%; }
 		#bottomTabs { height: 40%; }
 
@@ -41,7 +41,7 @@
 		hr.spacer { border:0; background-color:#ededed; width:80%; height:1px; }
 
 		/* rules used to test custom setting of TextBox padding */
-		.inputPadding0 .dijitInputField { padding: 0px !important; }
+		.inputPadding0 .dijitInputField { padding: 0 !important; }
 		.inputPadding1 .dijitInputField { padding: 1px !important; }
 		.inputPadding2 .dijitInputField { padding: 2px !important; }
 		.inputPadding3 .dijitInputField { padding: 3px !important; }
@@ -66,15 +66,14 @@
 	<!--
 	<script type="text/javascript" src="http://prototypejs.org/assets/2007/10/16/prototype.js"></script>
 	-->
-	<script type="text/javascript" src="../dijit.js"></script>
-	<script type="text/javascript" src="../dijit-all.js" charset="utf-8"></script>
-
 
 	<script type="text/javascript"> // dojo.requires()
 
 		dojo.require("dijit.Menu");
 		dojo.require("dijit.MenuItem");
 		dojo.require("dijit.PopupMenuItem");
+		dojo.require("dijit.CheckedMenuItem");
+		dojo.require("dijit.MenuSeparator");
 
 		dojo.require("dijit.Calendar");
 		dojo.require("dijit.ColorPalette");
@@ -87,6 +86,8 @@
 		dojo.require("dijit.MenuBarItem");
 		dojo.require("dijit.PopupMenuBarItem");
 
+		dojo.require("dijit.InlineEditBox");
+
 		// editor:
 		dojo.require("dijit.Editor");
 		dojo.require("dijit._editor.plugins.FontChoice");
@@ -97,6 +98,8 @@
 
 		// various Form elements
 		dojo.require("dijit.form.CheckBox");
+		dojo.require("dijit.form.RadioButton");
+
 		dojo.require("dijit.form.Textarea");
 		dojo.require("dijit.form.SimpleTextarea");
 		dojo.require("dijit.form.FilteringSelect");
@@ -104,10 +107,13 @@
 		dojo.require("dijit.form.DateTextBox");
 		dojo.require("dijit.form.TimeTextBox");
 		dojo.require("dijit.form.CurrencyTextBox");
-		dojo.require("dijit.form.Button");
-		dojo.require("dijit.InlineEditBox");
 		dojo.require("dijit.form.NumberSpinner");
 
+		dojo.require("dijit.form.Button");
+		dojo.require("dijit.form.DropDownButton");
+		dojo.require("dijit.form.ComboButton");
+		dojo.require("dijit.form.ToggleButton");
+
 		dojo.require("dijit.form.VerticalSlider");
 		dojo.require("dijit.form.VerticalRuleLabels");
 		dojo.require("dijit.form.VerticalRule");
@@ -178,7 +184,7 @@
 			}, this);
 		}
 
-		dojo.addOnLoad(function() {
+		dojo.addOnLoad(function(){
 
 			var start = new Date().getTime();
 			dojo.parser.parse(dojo.byId('container'));
diff --git a/dijit/themes/themeTester.html b/dijit/themes/themeTester.html
index 4ae622c..7bfa6bb 100644
--- a/dijit/themes/themeTester.html
+++ b/dijit/themes/themeTester.html
@@ -54,7 +54,7 @@
 		hr.spacer { border:0; background-color:#ededed; width:80%; height:1px; }
 
 		/* rules used to test custom setting of TextBox padding */
-		.inputPadding0 .dijitInputField { padding: 0px !important; }
+		.inputPadding0 .dijitInputField { padding: 0 !important; }
 		.inputPadding1 .dijitInputField { padding: 1px !important; }
 		.inputPadding2 .dijitInputField { padding: 2px !important; }
 		.inputPadding3 .dijitInputField { padding: 3px !important; }
@@ -72,228 +72,172 @@
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: false, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: false, async:true"></script>
 
-	<!-- do not use: only for debugging / testing themes -->
+	<!-- only needed for alternate theme testing: -->
 	<script type="text/javascript" src="../tests/_testCommon.js"></script>
 
-	<!-- in nightly (or standard-profile builds), these files are layers -->
-	<script type="text/javascript" src="../dijit.js"></script>
-	<script type="text/javascript" src="../dijit-all.js" charset="utf-8"></script>
-
-	<script type="text/javascript"> // dojo.requires(), explicitly. 
-
-		dojo.require("dijit.Menu");
-		dojo.require("dijit.MenuItem");
-		dojo.require("dijit.PopupMenuItem");
-
-		dojo.require("dijit.Calendar");
-		dojo.require("dijit.ColorPalette");
-		dojo.require("dijit.ProgressBar");
-		dojo.require("dijit.TitlePane");
-		dojo.require("dijit.Tooltip");
-
-		dojo.require("dijit.Tree");
-		dojo.require("dijit.tree.ForestStoreModel");
-
-		dojo.require("dijit.MenuBar");
-		dojo.require("dijit.MenuBarItem");
-		dojo.require("dijit.PopupMenuBarItem");
-
-		// editor:
-		dojo.require("dijit.Editor");
-		dojo.require("dijit._editor.plugins.FontChoice");
-		dojo.require("dijit._editor.plugins.LinkDialog");
-
-		// dnd:
-		dojo.require("dojo.dnd.Source");
-
-		// various Form elements
-		dojo.require("dijit.form.CheckBox");
-		dojo.require("dijit.form.Textarea");
-		dojo.require("dijit.form.SimpleTextarea");
-		dojo.require("dijit.form.FilteringSelect");
-		dojo.require("dijit.form.TextBox");
-		dojo.require("dijit.form.DateTextBox");
-		dojo.require("dijit.form.TimeTextBox");
-		dojo.require("dijit.form.CurrencyTextBox");
-		dojo.require("dijit.form.Button");
-		dojo.require("dijit.InlineEditBox");
-		dojo.require("dijit.form.NumberSpinner");
-
-		dojo.require("dijit.form.VerticalSlider");
-		dojo.require("dijit.form.VerticalRuleLabels");
-		dojo.require("dijit.form.VerticalRule");
-		dojo.require("dijit.form.HorizontalSlider");
-		dojo.require("dijit.form.HorizontalRuleLabels");
-		dojo.require("dijit.form.HorizontalRule");
-
-		// 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.layout.LinkPane");
-		dojo.require("dijit.Dialog");
-
-		dojo.require("dojo.parser");
-
-		dojo.require("dojo.date.locale");
-
-		dojo.require("dojo.data.ItemFileReadStore");
-
-		// various function ripped out of inline script type=dojo/* blocks
-		function showDialog(){
-			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");
-		}
-		
-		function showDialogAb(){
-			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;
-		(function(){
-			// 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");
+	<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");
+				};
 				
-				// 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);
-				}
-	
-				// Clear previously checked MenuItem (radio-button effect).
-				dojo.forEach(this.getParent().getChildren(), function(mi){
-					if(mi != this){
-						mi.set("checked", false);
+				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);
 					}
-				}, this);
-			}
-		})();
 
-		dojo.addOnLoad(function() {
+					// val will be "theme default", "0px", "1px", ..., "5px"
+					var val = this.get("label");
 
-			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";
+					// 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);
 					}
-				}).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;
-		});
-
-		function logStrayGlobals(){
-			// 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(", "));
-			}
-		}
-
-		function logWidgets(){
-			// summary:
-			//		Print all the widgets to console
-			console.log("Widgets in registry:");
-			dijit.registry.forEach(function(w){
-				console.log(w);
-			});
-		}
-
-		function tearDown(){
-			// summary:
-			//		Destroy all widgets, top down, and then check for any orphaned widgets
-			dijit._destroyAll();
-			logWidgets();
-		}
 
-		dojo.addOnLoad(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.addOnLoad(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 + "})");
+					// 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);
+						}
+					}
+					if(strayGlobals.length){
+						console.warn("Stray globals: " + strayGlobals.join(", "));
+					}
+				};
+		
+				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>
 </head>
 <body class="claro">
diff --git a/dijit/themes/tundra/Calendar.css b/dijit/themes/tundra/Calendar.css
index 5fef68e..d650d4f 100644
--- a/dijit/themes/tundra/Calendar.css
+++ b/dijit/themes/tundra/Calendar.css
@@ -120,10 +120,12 @@
 	margin:0;
 	padding:0.4em 0 0.25em 0;
 	text-align:center;
+	font-size: 1.17em;
 }
 
 .tundra .dijitCalendarSelectedYear {
 	/* label for selected year */
+	font-weight:bolder;
 	color:black;
 	padding:0.2em;
 	padding-bottom:0.1em;
@@ -156,4 +158,4 @@
 .tundra .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover {
 	background-color: #3559ac;
 	color:#fff;
-}
\ No newline at end of file
+}
diff --git a/dijit/themes/tundra/Common.css b/dijit/themes/tundra/Common.css
index c339263..eb3e341 100644
--- a/dijit/themes/tundra/Common.css
+++ b/dijit/themes/tundra/Common.css
@@ -22,12 +22,13 @@
 .tundra.dojoDndMove .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{background-color: #97e68d; background-image: url(images/dndMove.png); background-repeat: no-repeat; background-position: 2px center;}
 .tundra.dojoDndCopy .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{background-color: #97e68d; background-image: url(images/dndCopy.png); background-repeat: no-repeat; background-position: 2px center;}
 
-.tundra .dijitContentPaneLoading {
+.tundra .dijitIconLoading {
 	background:url('images/loading.gif') no-repeat left center;
-	padding-left:25px;
+	width: 24px;
+	height: 24px;
 }
-
-.tundra .dijitContentPaneError {
+.tundra .dijitIconError {
 	background:url('images/warning.png') no-repeat left center;
-	padding-left:25px;
+	width: 16px;
+	height: 16px;
 }
diff --git a/dijit/themes/tundra/form/Common.css b/dijit/themes/tundra/form/Common.css
index 2013686..96899e1 100644
--- a/dijit/themes/tundra/form/Common.css
+++ b/dijit/themes/tundra/form/Common.css
@@ -10,7 +10,7 @@
 		dijit.form.ComboBox (partial)
  ****/
 
-.tundra .dijitInputContainer INPUT,
+.tundra .dijitInputContainer input,
 .tundra .dijitTextBox {
 	margin: 0 0.1em;
 }
diff --git a/dijit/tree/ForestStoreModel.js b/dijit/tree/ForestStoreModel.js
index 9fa8011..ca96361 100644
--- a/dijit/tree/ForestStoreModel.js
+++ b/dijit/tree/ForestStoreModel.js
@@ -1,6 +1,22 @@
-define("dijit/tree/ForestStoreModel", ["dojo", "dijit", "dijit/tree/TreeStoreModel"], function(dojo, dijit) {
-
-dojo.declare("dijit.tree.ForestStoreModel", dijit.tree.TreeStoreModel, {
+define([
+	"dojo/_base/array", // array.indexOf array.some
+	"dojo/_base/declare", // declare
+	"dojo/_base/lang", // lang.hitch
+	"dojo/_base/window", // win.global
+	"./TreeStoreModel"
+], function(array, declare, lang, win, TreeStoreModel){
+
+/*=====
+var TreeStoreModel = dijit.tree.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.
@@ -77,7 +93,7 @@ dojo.declare("dijit.tree.ForestStoreModel", dijit.tree.TreeStoreModel, {
 			}else{
 				this.store.fetch({
 					query: this.query,
-					onComplete: dojo.hitch(this, function(items){
+					onComplete: lang.hitch(this, function(items){
 						this.root.children = items;
 						callback(items);
 					}),
@@ -98,7 +114,7 @@ dojo.declare("dijit.tree.ForestStoreModel", dijit.tree.TreeStoreModel, {
 
 	fetchItemByIdentity: function(/* object */ keywordArgs){
 		if(keywordArgs.identity == this.root.id){
-			var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+			var scope = keywordArgs.scope?keywordArgs.scope:win.global;
 			if(keywordArgs.onItem){
 				keywordArgs.onItem.call(scope, this.root);
 			}
@@ -130,7 +146,7 @@ dojo.declare("dijit.tree.ForestStoreModel", dijit.tree.TreeStoreModel, {
 		}
 	},
 
-	onNewRootItem: function(args){
+	onNewRootItem: function(/* dojo.dnd.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
@@ -148,12 +164,12 @@ dojo.declare("dijit.tree.ForestStoreModel", dijit.tree.TreeStoreModel, {
 				this.onLeaveRoot(childItem);
 			}
 		}
-		dijit.tree.TreeStoreModel.prototype.pasteItem.call(this, childItem,
+		this.inherited(arguments, [childItem,
 			oldParentItem === this.root ? null : oldParentItem,
 			newParentItem === this.root ? null : newParentItem,
 			bCopy,
 			insertIndex
-		);
+		]);
 		if(newParentItem === this.root){
 			// It's onAddToRoot()'s responsibility to modify the item so it matches
 			// this.query... thus triggering an onChildrenChange() event to notify the Tree
@@ -196,12 +212,12 @@ dojo.declare("dijit.tree.ForestStoreModel", dijit.tree.TreeStoreModel, {
 		var oldChildren = this.root.children || [];
 		this.store.fetch({
 			query: this.query,
-			onComplete: dojo.hitch(this, function(newChildren){
+			onComplete: lang.hitch(this, function(newChildren){
 				this.root.children = newChildren;
 
 				// If the list of children or the order of children has changed...
 				if(oldChildren.length != newChildren.length ||
-					dojo.some(oldChildren, function(item, idx){ return newChildren[idx] != item;})){
+					array.some(oldChildren, function(item, idx){ return newChildren[idx] != item;})){
 					this.onChildrenChange(this.root, newChildren);
 				}
 			})
@@ -234,7 +250,7 @@ dojo.declare("dijit.tree.ForestStoreModel", dijit.tree.TreeStoreModel, {
 
 		// check if this was a child of root, and if so send notification that root's children
 		// have changed
-		if(dojo.indexOf(this.root.children, item) != -1){
+		if(array.indexOf(this.root.children, item) != -1){
 			this._requeryTop();
 		}
 
@@ -266,6 +282,4 @@ dojo.declare("dijit.tree.ForestStoreModel", dijit.tree.TreeStoreModel, {
 
 });
 
-
-return dijit.tree.ForestStoreModel;
 });
diff --git a/dijit/tree/TreeStoreModel.js b/dijit/tree/TreeStoreModel.js
index e188b58..ca08cf7 100644
--- a/dijit/tree/TreeStoreModel.js
+++ b/dijit/tree/TreeStoreModel.js
@@ -1,11 +1,20 @@
-define("dijit/tree/TreeStoreModel", ["dojo", "dijit"], function(dojo, dijit) {
-
-dojo.declare(
-		"dijit.tree.TreeStoreModel",
-		null,
-	{
+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){
+
+	// 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 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.
 
@@ -59,7 +68,7 @@ dojo.declare(
 			// tags:
 			//		private
 
-			dojo.mixin(this, args);
+			lang.mixin(this, args);
 
 			this.connects = [];
 
@@ -71,15 +80,16 @@ dojo.declare(
 			// if the store supports Notification, subscribe to the notification events
 			if(store.getFeatures()['dojo.data.api.Notification']){
 				this.connects = this.connects.concat([
-					dojo.connect(store, "onNew", this, "onNewItem"),
-					dojo.connect(store, "onDelete", this, "onDeleteItem"),
-					dojo.connect(store, "onSet", this, "onSetItem")
+					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)
 				]);
 			}
 		},
 
 		destroy: function(){
-			dojo.forEach(this.connects, dojo.disconnect);
+			var h;
+			while(h = this.connects.pop()){ h.remove(); }
 			// TODO: should cancel any in-progress processing of getRoot(), getChildren()
 		},
 
@@ -95,9 +105,9 @@ dojo.declare(
 			}else{
 				this.store.fetch({
 					query: this.query,
-					onComplete: dojo.hitch(this, function(items){
+					onComplete: lang.hitch(this, function(items){
 						if(items.length != 1){
-							throw new Error(this.declaredClass + ": query " + dojo.toJson(this.query) + " returned " + items.length +
+							throw new Error(this.declaredClass + ": query " + json.stringify(this.query) + " returned " + items.length +
 							 	" items, but must return exactly one item");
 						}
 						this.root = items[0];
@@ -114,7 +124,7 @@ dojo.declare(
 			//		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)
-			return dojo.some(this.childrenAttrs, function(attr){
+			return array.some(this.childrenAttrs, function(attr){
 				return this.store.hasAttribute(item, attr);
 			}, this);
 		},
@@ -128,7 +138,7 @@ dojo.declare(
 				// The parent is not loaded yet, we must be in deferItemLoadingUntilExpand
 				// mode, so we will load it and just return the children (without loading each
 				// child item)
-				var getChildren = dojo.hitch(this, arguments.callee);
+				var getChildren = lang.hitch(this, arguments.callee);
 				store.loadItem({
 					item: parentItem,
 					onItem: function(parentItem){
@@ -148,7 +158,7 @@ dojo.declare(
 			// count how many items need to be loaded
 			var _waitCount = 0;
 			if(!this.deferItemLoadingUntilExpand){
-				dojo.forEach(childItems, function(item){ if(!store.isItemLoaded(item)){ _waitCount++; } });
+				array.forEach(childItems, function(item){ if(!store.isItemLoaded(item)){ _waitCount++; } });
 			}
 
 			if(_waitCount == 0){
@@ -156,7 +166,7 @@ dojo.declare(
 				onComplete(childItems);
 			}else{
 				// still waiting for some or all of the items to load
-				dojo.forEach(childItems, function(item, idx){
+				array.forEach(childItems, function(item, idx){
 					if(!store.isItemLoaded(item)){
 						store.loadItem({
 							item: item,
@@ -222,7 +232,7 @@ dojo.declare(
 					}else{
 						// Create new item in the tree, based on the drag source.
 						LnewItem=this.store.newItem(args, pInfo);
-						if (LnewItem && (insertIndex!=undefined)){
+						if(LnewItem && (insertIndex!=undefined)){
 							// Move new item to desired position
 							this.pasteItem(LnewItem, parent, parent, false, insertIndex);
 						}
@@ -231,7 +241,7 @@ dojo.declare(
 			}else{
 				// [as far as we know] there is no id so we must assume this is a new item
 				LnewItem=this.store.newItem(args, pInfo);
-				if (LnewItem && (insertIndex!=undefined)){
+				if(LnewItem && (insertIndex!=undefined)){
 					// Move new item to desired position
 					this.pasteItem(LnewItem, parent, parent, false, insertIndex);
 				}
@@ -247,10 +257,10 @@ dojo.declare(
 
 			// remove child from source item, and record the attribute that child occurred in
 			if(oldParentItem){
-				dojo.forEach(this.childrenAttrs, function(attr){
+				array.forEach(this.childrenAttrs, function(attr){
 					if(store.containsValue(oldParentItem, attr, childItem)){
 						if(!bCopy){
-							var values = dojo.filter(store.getValues(oldParentItem, attr), function(x){
+							var values = array.filter(store.getValues(oldParentItem, attr), function(x){
 								return x != childItem;
 							});
 							store.setValues(oldParentItem, attr, values);
@@ -277,7 +287,7 @@ dojo.declare(
 		// =======================================================================
 		// 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
@@ -287,14 +297,16 @@ dojo.declare(
 			//		callback
 		},
 
-		onChildrenChange: function(/*dojo.data.Item*/ parent, /*dojo.data.Item[]*/ newChildrenList){
+		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
 		},
 
-		onDelete: function(/*dojo.data.Item*/ parent, /*dojo.data.Item[]*/ newChildrenList){
+		onDelete: function(/*dojo.data.Item*/ /*===== item =====*/){
 			// summary:
 			//		Callback when an item has been deleted.
 			// description:
@@ -330,7 +342,7 @@ dojo.declare(
 			// [ parentInfo.newValue ], although if items in the store has multiple
 			// child attributes (see `childrenAttr`), then it's a superset of parentInfo.newValue,
 			// so call getChildren() to be sure to get right answer.
-			this.getChildren(parentInfo.item, dojo.hitch(this, function(children){
+			this.getChildren(parentInfo.item, lang.hitch(this, function(children){
 				this.onChildrenChange(parentInfo.item, children);
 			}));
 		},
@@ -341,10 +353,7 @@ dojo.declare(
 			this.onDelete(item);
 		},
 
-		onSetItem: function(/* item */ item,
-						/* attribute-name-string */ attribute,
-						/* object | array */ oldValue,
-						/* object | array */ newValue){
+		onSetItem: function(item, attribute /*===== , oldValue, newValue =====*/){
 			// summary:
 			//		Updates the tree view according to changes in the data store.
 			// description:
@@ -352,12 +361,16 @@ dojo.declare(
 			//		other updates to an item by calling onChange().
 			//
 			//		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
 			// tags:
 			//		extension
 
-			if(dojo.indexOf(this.childrenAttrs, attribute) != -1){
+			if(array.indexOf(this.childrenAttrs, attribute) != -1){
 				// item's children list changed
-				this.getChildren(item, dojo.hitch(this, function(children){
+				this.getChildren(item, lang.hitch(this, function(children){
 					// See comments in onNewItem() about calling getChildren()
 					this.onChildrenChange(item, children);
 				}));
@@ -367,7 +380,4 @@ dojo.declare(
 			}
 		}
 	});
-
-
-return dijit.tree.TreeStoreModel;
 });
diff --git a/dijit/tree/_dndContainer.js b/dijit/tree/_dndContainer.js
index 4b50340..c5c0157 100644
--- a/dijit/tree/_dndContainer.js
+++ b/dijit/tree/_dndContainer.js
@@ -1,33 +1,20 @@
-define("dijit/tree/_dndContainer", ["dojo", "dijit", "dojo/dnd/common", "dojo/dnd/Container"], function(dojo, dijit) {
-
-dojo.getObject("tree", true, dojo);
-
-dijit.tree._compareNodes = function(n1, n2){
-	if(n1 === n2){
-		return 0;
-	}
-	
-	if('sourceIndex' in document.documentElement){ //IE
-		//TODO: does not yet work if n1 and/or n2 is a text node
-		return n1.sourceIndex - n2.sourceIndex;
-	}else if('compareDocumentPosition' in document.documentElement){ //FF, Opera
-		return n1.compareDocumentPosition(n2) & 2 ? 1: -1;
-	}else if(document.createRange){ //Webkit
-		var r1 = doc.createRange();
-		r1.setStartBefore(n1);
-
-		var r2 = doc.createRange();
-		r2.setStartBefore(n2);
-
-		return r1.compareBoundaryPoints(r1.END_TO_END, r2);
-	}else{
-		throw Error("dijit.tree._compareNodes don't know how to compare two different nodes in this browser");
-	}
-};
-
-dojo.declare("dijit.tree._dndContainer",
-	null,
-	{
+define([
+	"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){
+
+	// 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`.
+
+	return declare("dijit.tree._dndContainer", null, {
 
 		// summary:
 		//		This is a base class for `dijit.tree._dndSelector`, and isn't meant to be used directly.
@@ -53,69 +40,58 @@ dojo.declare("dijit.tree._dndContainer",
 			//		private
 			this.tree = tree;
 			this.node = tree.domNode;	// TODO: rename; it's not a TreeNode but the whole Tree
-			dojo.mixin(this, params);
+			lang.mixin(this, params);
 
 			// class-specific variables
-			this.map = {};
 			this.current = null;	// current TreeNode's DOM node
 
 			// states
 			this.containerState = "";
-			dojo.addClass(this.node, "dojoDndContainer");
+			domClass.add(this.node, "dojoDndContainer");
 
 			// set up events
 			this.events = [
 				// container level events
-				dojo.connect(this.node, "onmouseenter", this, "onOverEvent"),
-				dojo.connect(this.node, "onmouseleave",	this, "onOutEvent"),
+				on(this.node, mouse.enter, lang.hitch(this, "onOverEvent")),
+				on(this.node, mouse.leave,	lang.hitch(this, "onOutEvent")),
 
 				// switching between TreeNodes
-				dojo.connect(this.tree, "_onNodeMouseEnter", this, "onMouseOver"),
-				dojo.connect(this.tree, "_onNodeMouseLeave", this, "onMouseOut"),
+				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
-				dojo.connect(this.node, "ondragstart", dojo, "stopEvent"),
-				dojo.connect(this.node, "onselectstart", dojo, "stopEvent")
+				on(this.node, "dragstart", lang.hitch(event, "stop")),
+				on(this.node, "selectstart", lang.hitch(event, "stop"))
 			];
 		},
 
-		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().
-			// tags:
-			//		protected
-
-			var widget = this.selection[key],
-				ret = {
-					data: widget,
-					type: ["treeNode"]
-				};
-
-			return ret;	// dojo.dnd.Item
-		},
-
 		destroy: function(){
 			// summary:
 			//		Prepares this object to be garbage-collected
 
-			dojo.forEach(this.events, dojo.disconnect);
+			var h;
+			while(h = this.events.pop()){ h.remove(); }
+
 			// this.clearItems();
 			this.node = this.parent = null;
 		},
 
 		// mouse events
-		onMouseOver: function(/*TreeNode*/ widget, /*Event*/ evt){
+		onMouseOver: function(widget /*===== , evt =====*/){
 			// summary:
 			//		Called when mouse is moved over a TreeNode
+			// widget: TreeNode
+			// evt: Event
 			// tags:
 			//		protected
 			this.current = widget;
 		},
 
-		onMouseOut: function(/*TreeNode*/ widget, /*Event*/ evt){
+		onMouseOut: function(/*===== widget, evt =====*/){
 			// summary:
 			//		Called when mouse is moved away from a TreeNode
+			// widget: TreeNode
+			// evt: Event
 			// tags:
 			//		protected
 			this.current = null;
@@ -130,8 +106,8 @@ dojo.declare("dijit.tree._dndContainer",
 			//		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;
 		},
 
@@ -142,7 +118,7 @@ dojo.declare("dijit.tree._dndContainer",
 			//		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){
@@ -152,7 +128,7 @@ dojo.declare("dijit.tree._dndContainer",
 			//		A node
 			// type: String
 			//		A variable suffix for a class name
-			dojo.removeClass(node, "dojoDndItem" + type);
+			domClass.remove(node, "dojoDndItem" + type);
 		},
 
 		onOverEvent: function(){
@@ -170,8 +146,5 @@ dojo.declare("dijit.tree._dndContainer",
 			//		protected
 			this._changeState("Container", "");
 		}
-});
-
-
-return dijit.tree._dndContainer;
+	});
 });
diff --git a/dijit/tree/_dndSelector.js b/dijit/tree/_dndSelector.js
index 91f850d..99fc52e 100644
--- a/dijit/tree/_dndSelector.js
+++ b/dijit/tree/_dndSelector.js
@@ -1,8 +1,23 @@
-define("dijit/tree/_dndSelector", ["dojo", "dijit", "dojo/dnd/common", "dijit/tree/_dndContainer"], function(dojo, dijit) {
+define([
+	"dojo/_base/array", // array.filter array.forEach array.map
+	"dojo/_base/connect", // connect.isCopyKey
+	"dojo/_base/declare", // declare
+	"dojo/_base/lang", // lang.hitch
+	"dojo/mouse", // mouse.isLeft
+	"dojo/on",
+	"dojo/touch",
+	"dojo/_base/window", // win.global
+	"./_dndContainer"
+], function(array, connect, declare, lang, mouse, on, touch, win, _dndContainer){
 
-dojo.declare("dijit.tree._dndSelector",
-	dijit.tree._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`.
@@ -16,7 +31,7 @@ dojo.declare("dijit.tree._dndSelector",
 		selection: {},
 		=====*/
 
-		constructor: function(tree, params){
+		constructor: function(){
 			// summary:
 			//		Initialization
 			// tags:
@@ -25,12 +40,12 @@ dojo.declare("dijit.tree._dndSelector",
 			this.selection={};
 			this.anchor = null;
 
-			dijit.setWaiState(this.tree.domNode, "multiselect", !this.singular);
+			this.tree.domNode.setAttribute("aria-multiselect", !this.singular);
 
 			this.events.push(
-				dojo.connect(this.tree.domNode, "onmousedown", this,"onMouseDown"),
-				dojo.connect(this.tree.domNode, "onmouseup", this,"onMouseUp"),
-				dojo.connect(this.tree.domNode, "onmousemove", this,"onMouseMove")
+				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"))
 			);
 		},
 
@@ -70,7 +85,7 @@ dojo.declare("dijit.tree._dndSelector",
 			this.selection = this.anchor = null;
 		},
 		addTreeNode: function(/*dijit._TreeNode*/node, /*Boolean?*/isAnchor){
-			// summary
+			// summary:
 			//		add node to current selection
 			// node: Node
 			//		node to add
@@ -82,15 +97,15 @@ dojo.declare("dijit.tree._dndSelector",
 			return node;
 		},
 		removeTreeNode: function(/*dijit._TreeNode*/node){
-			// summary
+			// summary:
 			//		remove node from current selection
 			// node: Node
 			//		node to remove
-			this.setSelection(this._setDifference(this.getSelectedTreeNodes(), [node]))
+			this.setSelection(this._setDifference(this.getSelectedTreeNodes(), [node]));
 			return node;
 		},
 		isTreeNodeSelected: function(/*dijit._TreeNode*/node){
-			// summary
+			// summary:
 			//		return true if node is currently selected
 			// node: Node
 			//		the node to check whether it's in the current selection
@@ -98,53 +113,53 @@ dojo.declare("dijit.tree._dndSelector",
 			return node.id && !!this.selection[node.id];
 		},
 		setSelection: function(/*dijit._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
-			//      attributes are kept up to date. Anchor will be deleted if it has been removed
-			//      from the selection, but no new anchor will be added by this function.
+			// 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
+			//		attributes are kept up to date. Anchor will be deleted if it has been removed
+			//		from the selection, but no new anchor will be added by this function.
 			// newSelection: Node[]
-			//      list of tree nodes to make selected
+			//		list of tree nodes to make selected
 			var oldSelection = this.getSelectedTreeNodes();
-			dojo.forEach(this._setDifference(oldSelection, newSelection), dojo.hitch(this, function(node){
+			array.forEach(this._setDifference(oldSelection, newSelection), lang.hitch(this, function(node){
 				node.setSelected(false);
 				if(this.anchor == node){
 					delete this.anchor;
 				}
 				delete this.selection[node.id];
 			}));
-			dojo.forEach(this._setDifference(newSelection, oldSelection), dojo.hitch(this, function(node){
+			array.forEach(this._setDifference(newSelection, oldSelection), lang.hitch(this, function(node){
 				node.setSelected(true);
 				this.selection[node.id] = node;
 			}));
 			this._updateSelectionProperties();
 		},
 		_setDifference: function(xs,ys){
-			// summary
-			//      Returns a copy of xs which lacks any objects
-			//      occurring in ys. Checks for membership by
-			//      modifying and then reading the object, so it will
-			//      not properly handle sets of numbers or strings.
-			
-			dojo.forEach(ys, function(y){ y.__exclude__ = true; });
-			var ret = dojo.filter(xs, function(x){ return !x.__exclude__; });
+			// summary:
+			//		Returns a copy of xs which lacks any objects
+			//		occurring in ys. Checks for membership by
+			//		modifying and then reading the object, so it will
+			//		not properly handle sets of numbers or strings.
+
+			array.forEach(ys, function(y){ y.__exclude__ = true; });
+			var ret = array.filter(xs, function(x){ return !x.__exclude__; });
 
 			// clean up after ourselves.
-			dojo.forEach(ys, function(y){ delete y['__exclude__'] });
+			array.forEach(ys, function(y){ delete y['__exclude__'] });
 			return ret;
 		},
-		_updateSelectionProperties: function() {
-			// summary
-			//      Update the following tree properties from the current selection:
-			//      path[s], selectedItem[s], selectedNode[s]
-			
+		_updateSelectionProperties: function(){
+			// summary:
+			//		Update the following tree properties from the current selection:
+			//		path[s], selectedItem[s], selectedNode[s]
+
 			var selected = this.getSelectedTreeNodes();
 			var paths = [], nodes = [];
-			dojo.forEach(selected, function(node) {
+			array.forEach(selected, function(node){
 				nodes.push(node);
 				paths.push(node.getTreePath());
 			});
-			var items = dojo.map(nodes,function(node) { return node.item; });
+			var items = array.map(nodes,function(node){ return node.item; });
 			this.tree._set("paths", paths);
 			this.tree._set("path", paths[0] || []);
 			this.tree._set("selectedNodes", nodes);
@@ -155,21 +170,21 @@ dojo.declare("dijit.tree._dndSelector",
 		// mouse events
 		onMouseDown: function(e){
 			// summary:
-			//		Event processor for onmousedown
+			//		Event processor for onmousedown/ontouchstart
 			// e: Event
-			//		mouse event
+			//		onmousedown/ontouchstart event
 			// tags:
 			//		protected
 
 			// ignore click on expando node
-			if(!this.current || this.tree.isExpandoNode( e.target, this.current)){ return; }
+			if(!this.current || this.tree.isExpandoNode(e.target, this.current)){ return; }
 
-			if(e.button == dojo.mouseButtons.RIGHT){ return; }	// ignore right-click
+			if(!mouse.isLeft(e)){ return; } // ignore right-click
 
-			dojo.stopEvent(e);
+			e.preventDefault();
 
 			var treeNode = this.current,
-			  copy = dojo.isCopyKey(e), id = treeNode.id;
+			  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
@@ -185,9 +200,9 @@ dojo.declare("dijit.tree._dndSelector",
 
 		onMouseUp: function(e){
 			// summary:
-			//		Event processor for onmouseup
+			//		Event processor for onmouseup/ontouchend
 			// e: Event
-			//		mouse event
+			//		onmouseup/ontouchend event
 			// tags:
 			//		protected
 
@@ -198,20 +213,43 @@ dojo.declare("dijit.tree._dndSelector",
 			// the deselection logic here, the user can drags an already selected item.
 			if(!this._doDeselect){ return; }
 			this._doDeselect = false;
-			this.userSelect(this.current, dojo.isCopyKey( e ), e.shiftKey);
+			this.userSelect(this.current, connect.isCopyKey(e), e.shiftKey);
 		},
-		onMouseMove: function(e){
-			// summary
-			//		event processor for onmousemove
+		onMouseMove: function(/*===== e =====*/){
+			// summary:
+			//		event processor for onmousemove/ontouchmove
 			// e: Event
-			//		mouse event
+			//		onmousemove/ontouchmove event
 			this._doDeselect = false;
 		},
 
+		_compareNodes: function(n1, n2){
+			if(n1 === n2){
+				return 0;
+			}
+
+			if('sourceIndex' in document.documentElement){ //IE
+				//TODO: does not yet work if n1 and/or n2 is a text node
+				return n1.sourceIndex - n2.sourceIndex;
+			}else if('compareDocumentPosition' in document.documentElement){ //FF, Opera
+				return n1.compareDocumentPosition(n2) & 2 ? 1: -1;
+			}else if(document.createRange){ //Webkit
+				var r1 = doc.createRange();
+				r1.setStartBefore(n1);
+
+				var r2 = doc.createRange();
+				r2.setStartBefore(n2);
+
+				return r1.compareBoundaryPoints(r1.END_TO_END, r2);
+			}else{
+				throw Error("dijit.tree._compareNodes don't know how to compare two different nodes in this browser");
+			}
+		},
+
 		userSelect: function(node, multi, range){
 			// summary:
 			//		Add or remove the given node from selection, responding
-			//      to a user action such as a click or keypress.
+			//		to a user action such as a click or keypress.
 			// multi: Boolean
 			//		Indicates whether this is meant to be a multi-select action (e.g. ctrl-click)
 			// range: Boolean
@@ -228,9 +266,9 @@ dojo.declare("dijit.tree._dndSelector",
 				}
 			}else{
 				if(range && this.anchor){
-					var cr = dijit.tree._compareNodes(this.anchor.rowNode, node.rowNode),
+					var cr = this._compareNodes(this.anchor.rowNode, node.rowNode),
 					begin, end, anchor = this.anchor;
-					
+
 					if(cr < 0){ //current is after anchor
 						begin = anchor;
 						end = node;
@@ -238,40 +276,51 @@ dojo.declare("dijit.tree._dndSelector",
 						begin = node;
 						end = anchor;
 					}
-					nodes = [];
+					var nodes = [];
 					//add everything betweeen begin and end inclusively
-					while(begin != end) {
-						nodes.push(begin)
+					while(begin != end){
+						nodes.push(begin);
 						begin = this.tree._getNextNode(begin);
 					}
-					nodes.push(end)
+					nodes.push(end);
 
 					this.setSelection(nodes);
 				}else{
-				    if( this.selection[ node.id ] && multi ) {
+					if( this.selection[ node.id ] && multi ){
 						this.removeTreeNode( node );
-				    } else if(multi) {
+					}else if(multi){
 						this.addTreeNode(node, true);
-					} else {
+					}else{
 						this.setSelection([node]);
 						this.anchor = node;
-				    }
+					}
 				}
 			}
 		},
 
+		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().
+			// tags:
+			//		protected
+
+			var widget = this.selection[key];
+			return {
+				data: widget,
+				type: ["treeNode"]
+			}; // dojo.dnd.Item
+		},
+
 		forInSelectedItems: function(/*Function*/ f, /*Object?*/ o){
 			// summary:
 			//		Iterates over selected items;
 			//		see `dojo.dnd.Container.forInItems()` for details
-			o = o || dojo.global;
+			o = o || win.global;
 			for(var id in this.selection){
 				// console.log("selected item id: " + id);
 				f.call(o, this.getItem(id), id, this);
 			}
 		}
-});
-
-
-return dijit.tree._dndSelector;
+	});
 });
diff --git a/dijit/tree/dndSource.js b/dijit/tree/dndSource.js
index 45c4165..2e10e2e 100644
--- a/dijit/tree/dndSource.js
+++ b/dijit/tree/dndSource.js
@@ -1,4 +1,21 @@
-define("dijit/tree/dndSource", ["dojo", "dijit", "dijit/tree/_dndSelector", "dojo/dnd/Manager"], function(dojo, dijit) {
+define([
+	"dojo/_base/array", // array.forEach array.indexOf array.map
+	"dojo/_base/connect", // isCopyKey
+	"dojo/_base/declare", // declare
+	"dojo/dom-class", // domClass.add
+	"dojo/dom-geometry", // domGeometry.position
+	"dojo/_base/lang", // lang.mixin lang.hitch
+	"dojo/on", // subscribe
+	"dojo/touch",
+	"dojo/topic",
+	"dojo/dnd/Manager", // DNDManager.manager
+	"./_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(){
@@ -24,7 +41,7 @@ dijit.tree.__SourceArgs = function(){
 }
 =====*/
 
-dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
+return declare("dijit.tree.dndSource", _dndSelector, {
 	// summary:
 	//		Handles drag and drop operations (as a source or a target) for `dijit.Tree`
 
@@ -55,7 +72,7 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 		// tags:
 		//		private
 		if(!params){ params = {}; }
-		dojo.mixin(this, 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;
@@ -78,24 +95,24 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 		// 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");
 		}
 
 		// 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"))
 		];
 	},
 
 	// methods
-	checkAcceptance: function(source, nodes){
+	checkAcceptance: function(/*===== source, nodes =====*/){
 		// summary:
 		//		Checks if the target can accept nodes from this source
 		// source: dijit.tree.dndSource
@@ -121,8 +138,9 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 	destroy: function(){
 		// summary:
 		//		Prepares the object to be garbage-collected.
-		this.inherited("destroy",arguments);
-		dojo.forEach(this.topics, dojo.unsubscribe);
+		this.inherited(arguments);
+		var h;
+		while(h = this.topics.pop()){ h.remove(); }
 		this.targetAnchor = null;
 	},
 
@@ -131,7 +149,7 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 		//		Helper method for processing onmousemove/onmouseover events while drag is in progress.
 		//		Keeps track of current drop target.
 
-		var m = dojo.dnd.manager(),
+		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)
@@ -142,7 +160,7 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 		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 = dojo.position(newTarget.rowNode, true);
+				this.targetBox = domGeometry.position(newTarget.rowNode, true);
 			}
 			if((e.pageY - this.targetBox.y) <= this.betweenThreshold){
 				newDropPosition = "Before";
@@ -165,14 +183,27 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 			}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 if(m.source == this && (newTarget.id in this.selection)){
-				// Guard against dropping onto yourself (TODO: guard against dropping onto your descendant, #7140)
-				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);
+				// 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;
+						}
+					}
+				}
+				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;
@@ -182,14 +213,14 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 
 	onMouseMove: function(e){
 		// summary:
-		//		Called for any onmousemove events over the Tree
+		//		Called for any onmousemove/ontouchmove events over the Tree
 		// e: Event
-		//		onmousemouse event
+		//		onmousemouse/ontouchmove event
 		// tags:
 		//		private
 		if(this.isDragging && this.targetState == "Disabled"){ return; }
 		this.inherited(arguments);
-		var m = dojo.dnd.manager();
+		var m = DNDManager.manager();
 		if(this.isDragging){
 			this._onDragMouse(e);
 		}else{
@@ -211,8 +242,8 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 						}
 						nodes = r;
 					}
-					nodes = dojo.map(nodes, function(n){return n.domNode});
-					m.startDrag(this, nodes, this.copyState(dojo.isCopyKey(e)));
+					nodes = array.map(nodes, function(n){return n.domNode});
+					m.startDrag(this, nodes, this.copyState(connect.isCopyKey(e)));
 				}
 			}
 		}
@@ -220,9 +251,9 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 
 	onMouseDown: function(e){
 		// summary:
-		//		Event processor for onmousedown
+		//		Event processor for onmousedown/ontouchstart
 		// e: Event
-		//		onmousedown event
+		//		onmousedown/ontouchend event
 		// tags:
 		//		private
 		this.mouseDown = true;
@@ -234,9 +265,9 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 
 	onMouseUp: function(e){
 		// summary:
-		//		Event processor for onmouseup
+		//		Event processor for onmouseup/ontouchend
 		// e: Event
-		//		onmouseup event
+		//		onmouseup/ontouchend event
 		// tags:
 		//		private
 		if(this.mouseDown){
@@ -254,7 +285,7 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 		this._unmarkTargetAnchor();
 	},
 
-	checkItemAcceptance: function(target, source, position){
+	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:
@@ -285,7 +316,7 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 			this.mouseDown = false;
 			this._unmarkTargetAnchor();
 		}else if(this.isDragging){
-			var m = dojo.dnd.manager();
+			var m = DNDManager.manager();
 			m.canDrop(false);
 		}
 	},
@@ -309,13 +340,13 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 		this._changeState("Target", accepted ? "" : "Disabled");
 
 		if(this == source){
-			dojo.dnd.manager().overSource(this);
+			DNDManager.manager().overSource(this);
 		}
 
 		this.isDragging = true;
 	},
 
-	itemCreator: function(/*DomNode[]*/ nodes, target, /*dojo.dnd.Source*/ source){
+	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
@@ -324,6 +355,9 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 		// 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:
 		// |	[
@@ -336,7 +370,7 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 		// TODO: for 2.0 refactor so itemCreator() is called once per drag node, and
 		// make signature itemCreator(sourceItem, node, target) (or similar).
 
-		return dojo.map(nodes, function(node){
+		return array.map(nodes, function(node){
 			return {
 				"id": node.id,
 				"name": node.textContent || node.innerText || ""
@@ -361,34 +395,32 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 		if(this.containerState == "Over"){
 			var tree = this.tree,
 				model = tree.model,
-				target = this.targetAnchor,
-				requeryRoot = false;	// set to true iff top level items change
+				target = this.targetAnchor;
 
 			this.isDragging = false;
 
 			// Compute the new parent item
-			var targetWidget = target;
 			var newParentItem;
 			var insertIndex;
-			newParentItem = (targetWidget && targetWidget.item) || tree.item;
+			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 = (targetWidget.getParent() && targetWidget.getParent().item) || tree.item;
+				newParentItem = (target.getParent() && target.getParent().item) || tree.item;
 				// Compute the insert index for reordering
-				insertIndex = targetWidget.getIndexInParent();
+				insertIndex = target.getIndexInParent();
 				if(this.dropPosition == "After"){
-					insertIndex = targetWidget.getIndexInParent() + 1;
+					insertIndex = target.getIndexInParent() + 1;
 				}
 			}else{
-				newParentItem = (targetWidget && targetWidget.item) || tree.item;
+				newParentItem = (target && target.item) || tree.item;
 			}
 
 			// 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;
 
-			dojo.forEach(nodes, function(node, idx){
+			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.
@@ -397,7 +429,7 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 				// 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(dojo.indexOf(sourceItem.type, "treeNode") != -1){
+				if(array.indexOf(sourceItem.type, "treeNode") != -1){
 					var childTreeNode = sourceItem.data,
 						childItem = childTreeNode.item,
 						oldParentItem = childTreeNode.getParent().item;
@@ -433,7 +465,7 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 
 			// 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(targetWidget);
+			this.tree._expandNode(target);
 		}
 		this.onDndCancel();
 	},
@@ -458,7 +490,7 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 		// tags:
 		//		private
 		this.inherited(arguments);
-		dojo.dnd.manager().overSource(this);
+		DNDManager.manager().overSource(this);
 	},
 	onOutEvent: function(){
 		// summary:
@@ -466,7 +498,7 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 		// tags:
 		//		private
 		this._unmarkTargetAnchor();
-		var m = dojo.dnd.manager();
+		var m = DNDManager.manager();
 		if(this.isDragging){
 			m.canDrop(false);
 		}
@@ -529,6 +561,4 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 	}
 });
 
-
-return dijit.tree.dndSource;
 });
diff --git a/dijit/tree/model.js b/dijit/tree/model.js
index 5791a2e..9345825 100644
--- a/dijit/tree/model.js
+++ b/dijit/tree/model.js
@@ -1,5 +1,6 @@
 
-dojo.declare(
+/*=====
+declare(
 	"dijit.tree.model",
 	null,
 {
@@ -30,20 +31,23 @@ dojo.declare(
 		//		extension
 	},
 
-	mayHaveChildren: function(/*dojo.data.Item*/ item){
+	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(/*dojo.data.Item*/ parentItem, /*function(items)*/ onComplete){
+	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
 	},
@@ -51,7 +55,7 @@ dojo.declare(
 	// =======================================================================
 	// Inspecting items
 
-	isItem: function(/* anything */ something){
+	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,
@@ -60,7 +64,7 @@ dojo.declare(
 		//		extension
 	},
 
-	fetchItemByIdentity: function(/* object */ keywordArgs){
+	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
@@ -71,14 +75,14 @@ dojo.declare(
 		//		extension
 	},
 
-	getIdentity: function(/* item */ item){
+	getIdentity: function(item){
 		// summary:
 		//		Returns identity for an item
 		// tags:
 		//		extension
 	},
 
-	getLabel: function(/*dojo.data.Item*/ item){
+	getLabel: function(item){
 		// summary:
 		//		Get the label for an item
 		// tags:
@@ -88,19 +92,26 @@ dojo.declare(
 	// =======================================================================
 	// Write interface
 
-	newItem: function(/* dojo.dnd.Item */ args, /*Item*/ parent, /*int?*/ insertIndex){
+	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(/*Item*/ childItem, /*Item*/ oldParentItem, /*Item*/ newParentItem, /*Boolean*/ bCopy){
+	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
 	},
@@ -108,21 +119,24 @@ dojo.declare(
 	// =======================================================================
 	// Callbacks
 
-	onChange: function(/*dojo.data.Item*/ item){
+	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(/*dojo.data.Item*/ parent, /*dojo.data.Item[]*/ newChildrenList){
+	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
new file mode 100644
index 0000000..504ba26
--- /dev/null
+++ b/dijit/typematic.js
@@ -0,0 +1,206 @@
+define([
+	"dojo/_base/array", // array.forEach
+	"dojo/_base/connect", // connect.connect
+	"dojo/_base/event", // event.stop
+	"dojo/_base/kernel", // kernel.deprecated
+	"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){
+
+// 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.
+
+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){
+		// 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);
+		}
+	},
+
+	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:
+		// 		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(); }); } };
+	},
+
+	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);
+				}
+			}))
+		];
+		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 b906954..b82adee 100644
--- a/dojo/AdapterRegistry.js
+++ b/dojo/AdapterRegistry.js
@@ -1,6 +1,10 @@
-define("dojo/AdapterRegistry", ["dojo"], function(dojo) {
+define(["./_base/kernel", "./_base/lang"], function(dojo, lang) {
+	// module:
+	//		dojo/AdapterRegistry
+	// summary:
+	//		TODOC
 
-dojo.AdapterRegistry = function(/*Boolean?*/ returnWrappers){
+var AdapterRegistry = dojo.AdapterRegistry = function(/*Boolean?*/ returnWrappers){
 	//	summary:
 	//		A registry to make contextual calling/searching easier.
 	//	description:
@@ -33,7 +37,12 @@ dojo.AdapterRegistry = function(/*Boolean?*/ returnWrappers){
 	this.returnWrappers = returnWrappers || false; // Boolean
 };
 
-dojo.extend(dojo.AdapterRegistry, {
+/*=====
+// doc alias helpers:
+AdapterRegistry = dojo.AdapterRegistry;
+=====*/
+
+lang.extend(AdapterRegistry, {
 	register: function(/*String*/ name, /*Function*/ check, /*Function*/ wrap, /*Boolean?*/ directReturn, /*Boolean?*/ override){
 		//	summary:
 		//		register a check function to determine if the wrap function or
@@ -78,8 +87,14 @@ dojo.extend(dojo.AdapterRegistry, {
 	},
 
 	unregister: function(name){
-		// summary: Remove a named adapter from the registry
-
+		// summary:
+		//		Remove a named adapter from the registry
+		// name: String
+		//		The name of the adapter.
+		// returns: Boolean
+		//		Returns true if operation is successful.
+		//		Returns false if operation fails.
+	
 		// FIXME: this is kind of a dumb way to handle this. On a large
 		// registry this will be slow-ish and we can use the name as a lookup
 		// should we choose to trade memory for speed.
@@ -94,5 +109,5 @@ dojo.extend(dojo.AdapterRegistry, {
 	}
 });
 
-return dojo.AdapterRegistry;
+return AdapterRegistry;
 });
diff --git a/dojo/DeferredList.js b/dojo/DeferredList.js
index 232ee43..5071dfc 100644
--- a/dojo/DeferredList.js
+++ b/dojo/DeferredList.js
@@ -1,4 +1,9 @@
-define("dojo/DeferredList", ["dojo"], function(dojo) {
+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:
@@ -9,24 +14,24 @@ dojo.DeferredList = function(/*Array*/ list, /*Boolean?*/ fireOnOneCallback, /*B
 	//		the given list have fired their own deferreds.  The parameters `fireOnOneCallback` and
 	//		fireOnOneErrback, will fire before all the deferreds as appropriate
 	//
-	//	list:
+	// list:
 	//		The list of deferreds to be synchronizied with this DeferredList
-	//	fireOnOneCallback:
+	// fireOnOneCallback:
 	//		Will cause the DeferredLists callback to be fired as soon as any
 	//		of the deferreds in its list have been fired instead of waiting until
 	//		the entire list has finished
-	//	fireonOneErrback:
+	// fireonOneErrback:
 	//		Will cause the errback to fire upon any of the deferreds errback
-	//	canceller:
+	// canceller:
 	//		A deferred canceller function, see dojo.Deferred
 	var resultList = [];
-	dojo.Deferred.call(this);
+	Deferred.call(this);
 	var self = this;
 	if(list.length === 0 && !fireOnOneCallback){
 		this.resolve([0, []]);
 	}
 	var finished = 0;
-	dojo.forEach(list, function(item, i){
+	darray.forEach(list, function(item, i){
 		item.then(function(result){
 			if(fireOnOneCallback){
 				self.resolve([i, result]);
@@ -50,21 +55,26 @@ dojo.DeferredList = function(/*Array*/ list, /*Boolean?*/ fireOnOneCallback, /*B
 			if(finished === list.length){
 				self.resolve(resultList);
 			}
-			
+
 		}
 	});
 };
-dojo.DeferredList.prototype = new dojo.Deferred();
+dojo.DeferredList.prototype = new Deferred();
 
-dojo.DeferredList.prototype.gatherResults= function(deferredList){
+dojo.DeferredList.prototype.gatherResults = function(deferredList){
 	// summary:
-	//	Gathers the results of the deferreds for packaging
-	//	as the parameters to the Deferred Lists' callback
+	//		Gathers the results of the deferreds for packaging
+	//		as the parameters to the Deferred Lists' callback
+	// deferredList: dojo.DeferredList
+	//		The deferred list from which this function gathers results.
+	// returns: dojo.DeferredList
+	//		The newly created deferred list which packs results as
+	//		parameters to its callback.
 
 	var d = new dojo.DeferredList(deferredList, false, true, false);
 	d.addCallback(function(results){
 		var ret = [];
-		dojo.forEach(results, function(result){
+		darray.forEach(results, function(result){
 			ret.push(result[1]);
 		});
 		return ret;
diff --git a/dojo/Evented.js b/dojo/Evented.js
new file mode 100644
index 0000000..420dfca
--- /dev/null
+++ b/dojo/Evented.js
@@ -0,0 +1,32 @@
+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", ...});
+
+ 	"use strict";
+ 	var after = aspect.after;
+	function Evented(){
+	}
+	Evented.prototype = {
+		on: function(type, listener){
+			return on.parse(this, type, listener, function(target, type){
+				return after(target, 'on' + type, listener, true);
+			});
+		},
+		emit: function(type, event){
+			var args = [this];
+			args.push.apply(args, arguments);
+			return on.emit.apply(on, args);
+		}
+	};
+	return Evented;
+});
diff --git a/dojo/NodeList-data.js b/dojo/NodeList-data.js
index ee5fe69..2df736d 100644
--- a/dojo/NodeList-data.js
+++ b/dojo/NodeList-data.js
@@ -1,7 +1,16 @@
-define("dojo/NodeList-data", ["dojo"], function(dojo) {
-(function(d){
-
+define([
+	"./_base/kernel", "./query", "./_base/lang", "./_base/array", "./dom-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.
 		//
@@ -58,33 +67,42 @@ define("dojo/NodeList-data", ["dojo"], function(dojo) {
 		//		If passed, remove the data item found at `key`
 	};
 
-	dojo._nodeDataCache = {
-		// summary: 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.
-	};
-
 =====*/
 
-	var dataCache = {}, x = 0, dataattr = "data-dojo-dataid", nl = d.NodeList,
+	var dataCache = {}, x = 0, dataattr = "data-dojo-dataid",
 		dopid = function(node){
 			// summary: Return a uniqueish ID for the passed node reference
-			var pid = d.attr(node, dataattr);
+			var pid = attr.get(node, dataattr);
 			if(!pid){
 				pid = "pid" + (x++);
-				d.attr(node, dataattr, pid);
+				attr.set(node, dataattr, pid);
 			}
 			return pid;
 		}
 	;
 
 	//>>excludeStart("debugging", true);
-	// exposed for unit tests:
-	d._nodeDataCache = dataCache;
+	// 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;
 	//>>excludeEnd("debugging");
 
-	var dodata = d._nodeData = function(node, key, value){
-
+	var dodata = dojo._nodeData = function(node, key, value){
+		// 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?
+		//		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)
+		//
 		var pid = dopid(node), r;
 		if(!dataCache[pid]){ dataCache[pid] = {}; }
 
@@ -100,13 +118,13 @@ define("dojo/NodeList-data", ["dojo"], function(dojo) {
 		}else{
 			// must be a setter, mix `value` into data hash
 			// API discrepency: using object as setter works here
-			r = d._mixin(dataCache[pid], key);
+			r = lang.mixin(dataCache[pid], key);
 		}
 
 		return r; // Object|Anything|Nothing
 	};
 
-	var removeData = d._removeNodeData = function(node, key){
+	var removeData = dojo._removeNodeData = function(node, key){
 		// summary: Remove some data from this node
 		// node: String|DomNode
 		//		The node reference to remove data from
@@ -123,7 +141,7 @@ define("dojo/NodeList-data", ["dojo"], function(dojo) {
 		}
 	};
 
-	d._gcNodeData = function(){
+	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.
@@ -132,24 +150,24 @@ define("dojo/NodeList-data", ["dojo"], function(dojo) {
 		//		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 = dojo.query("[" + dataattr + "]").map(dopid);
+		var livePids = query("[" + dataattr + "]").map(dopid);
 		for(var i in dataCache){
-			if(dojo.indexOf(livePids, i) < 0){ delete dataCache[i]; }
+			if(array.indexOf(livePids, i) < 0){ delete dataCache[i]; }
 		}
 	};
 
 	// make nodeData and removeNodeData public on dojo.NodeList:
-	d.extend(nl, {
-		data: nl._adaptWithCondition(dodata, function(a){
+	lang.extend(NodeList, {
+		data: NodeList._adaptWithCondition(dodata, function(a){
 			return a.length === 0 || a.length == 1 && (typeof a[0] == "string");
 		}),
-		removeData: nl._adaptAsForEach(removeData)
+		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:
 //
-//	nl.prototype.data = function(key, value){
+//	NodeList.prototype.data = function(key, value){
 //		var a = arguments, r;
 //		if(a.length === 0 || a.length == 1 && (typeof a[0] == "string")){
 //			r = this.map(function(node){
@@ -164,7 +182,6 @@ define("dojo/NodeList-data", ["dojo"], function(dojo) {
 //		return r; // dojo.NodeList|Array|SingleItem
 //	};
 
-})(dojo);
+	return NodeList;
 
-return dojo.NodeList;
 });
diff --git a/dojo/NodeList-dom.js b/dojo/NodeList-dom.js
new file mode 100644
index 0000000..fdf11c7
--- /dev/null
+++ b/dojo/NodeList-dom.js
@@ -0,0 +1,454 @@
+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; =====*/
+	var magicGuard = function(a){
+		// summary:
+		//		the guard function for dojo.attr() and dojo.style()
+		return a.length == 1 && (typeof a[0] == "string"); // inline'd type check
+	};
+
+	var orphan = function(node){
+		// summary:
+		//		function to orphan nodes
+		var p = node.parentNode;
+		if(p){
+			p.removeChild(node);
+		}
+	};
+	// FIXME: should we move orphan() to dojo.html?
+
+	var NodeList = query.NodeList,
+		awc = NodeList._adaptWithCondition,
+		aafe = NodeList._adaptAsForEach,
+		aam = NodeList._adaptAsMap;
+
+	function getSet(module){
+		return function(node, name, value){
+			if(arguments.length == 2){
+				return module[typeof name == "string" ? "get" : "set"](node, name);
+			}
+			// setter
+			return module.set(node, name, value);
+		};
+	}
+
+	lang.extend(NodeList, {
+		_normalize: function(/*String||Element||Object||NodeList*/content, /*DOMNode?*/refNode){
+			// summary:
+			//		normalizes data to an array of items to insert.
+			// 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),
+			//		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.
+			//		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).
+
+			//Wanted to just use a DocumentFragment, but for the array/NodeList
+			//case that meant using cloneNode, but we may not want that.
+			//Cloning should only happen if the node operations span
+			//multiple refNodes. Also, need a real array, not a NodeList from the
+			//DOM since the node movements could change those NodeLists.
+
+			var parse = content.parse === true;
+
+			//Do we have an object that needs to be run through a template?
+			if(typeof content.template == "string"){
+				var templateFunc = content.templateFunc || (dojo.string && dojo.string.substitute);
+				content = templateFunc ? templateFunc(content.template, content) : content;
+			}
+
+			var type = (typeof content);
+			if(type == "string" || type == "number"){
+				content = domCtr.toDom(content, (refNode && refNode.ownerDocument));
+				if(content.nodeType == 11){
+					//DocumentFragment. It cannot handle cloneNode calls, so pull out the children.
+					content = lang._toArray(content.childNodes);
+				}else{
+					content = [content];
+				}
+			}else if(!lang.isArrayLike(content)){
+				content = [content];
+			}else if(!lang.isArray(content)){
+				//To get to this point, content is array-like, but
+				//not an array, which likely means a DOM NodeList. Convert it now.
+				content = lang._toArray(content);
+			}
+
+			//Pass around the parse info
+			if(parse){
+				content._runParse = true;
+			}
+			return content; //Array
+		},
+
+		_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
+			//		clone event handlers if that is derivable from the node.
+			return node.cloneNode(true);
+		},
+
+		_place: function(/*Array*/ary, /*DOMNode*/refNode, /*String*/position, /*Boolean*/useClone){
+			// summary:
+			//		private utility to handle placing an array of nodes relative to another node.
+			// description:
+			//		Allows for cloning the nodes in the array, and for
+			//		optionally parsing widgets, if ary._runParse is true.
+
+			//Avoid a disallowed operation if trying to do an innerHTML on a non-element node.
+			if(refNode.nodeType != 1 && position == "only"){
+				return;
+			}
+			var rNode = refNode, tempNode;
+
+			//Always cycle backwards in case the array is really a
+			//DOM NodeList and the DOM operations take it out of the live collection.
+			var length = ary.length;
+			for(var i = length - 1; i >= 0; i--){
+				var node = (useClone ? this._cloneNode(ary[i]) : ary[i]);
+
+				//If need widget parsing, use a temp node, instead of waiting after inserting into
+				//real DOM because we need to start widget parsing at one node up from current node,
+				//which could cause some already parsed widgets to be parsed again.
+				if(ary._runParse && dojo.parser && dojo.parser.parse){
+					if(!tempNode){
+						tempNode = rNode.ownerDocument.createElement("div");
+					}
+					tempNode.appendChild(node);
+					dojo.parser.parse(tempNode);
+					node = tempNode.firstChild;
+					while(tempNode.firstChild){
+						tempNode.removeChild(tempNode.firstChild);
+					}
+				}
+
+				if(i == length - 1){
+					domCtr.place(node, rNode, position);
+				}else{
+					rNode.parentNode.insertBefore(node, rNode);
+				}
+				rNode = node;
+			}
+		},
+
+		/*=====
+		position: function(){
+			// summary:
+			//		Returns border-box objects (x/y/w/h) of all elements in a node list
+			//		as an Array (*not* a NodeList). Acts like `dojo.position`, though
+			//		assumes the node passed is each node in this list.
+
+			return dojo.map(this, dojo.position); // Array
+		},
+
+		attr: function(property, value){
+			// summary:
+			//		gets or sets the DOM attribute for every element in the
+			//		NodeList. See also `dojo.attr`
+			// property: String
+			//		the attribute to get/set
+			// value: String?
+			//		optional. The value to set the property to
+			// returns:
+			//		if no value is passed, the result is an array of attribute values
+			//		If a value is passed, the return is this NodeList
+			// example:
+			//		Make all nodes with a particular class focusable:
+			//	|	dojo.query(".focusable").attr("tabIndex", -1);
+			// example:
+			//		Disable a group of buttons:
+			//	|	dojo.query("button.group").attr("disabled", true);
+			// example:
+			//		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
+		},
+
+		style: function(property, value){
+			// summary:
+			//		gets or sets the CSS property for every element in the NodeList
+			// property: String
+			//		the CSS property to get/set, in JavaScript notation
+			//		("lineHieght" instead of "line-height")
+			// value: String?
+			//		optional. The value to set the property to
+			// 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; // Array
+		},
+
+		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
+		},
+
+		removeClass: function(className){
+			// summary:
+			//		removes the specified class from every node in the list
+			// className: 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.
+			// returns:
+			//		dojo.NodeList, this list
+			return; // dojo.NodeList
+		},
+
+		toggleClass: function(className, 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.
+			// condition: Boolean?
+			//		If passed, true means to add the class, false means to remove.
+			// className: String
+			//		the CSS class to add
+			return; // dojo.NodeList
+		},
+
+		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
+			// 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),
+
+		position: aam(domGeom.position),
+		marginBox: aam(domGeom.getMarginBox),
+
+		// FIXME: connectPublisher()? connectRunOnce()?
+
+		/*
+		destroy: function(){
+			// summary:
+			//		destroys every item in the list.
+			this.forEach(d.destroy);
+			// FIXME: should we be checking for and/or disposing of widgets below these nodes?
+		},
+		*/
+
+		place: function(/*String||Node*/ queryOrNode, /*String*/ position){
+			// summary:
+			//		places elements of this node list relative to the first element matched
+			//		by queryOrNode. Returns the original NodeList. See: `dojo.place`
+			// queryOrNode:
+			//		may be a string representing any valid CSS3 selector or a DOM node.
+			//		In the selector case, only the first matching element will be used
+			//		for relative positioning.
+			// position:
+			//		can be one of:
+			//		|	"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
+		},
+
+		orphan: function(/*String?*/ filter){
+			// summary:
+			//		removes elements in this list that match the filter
+			//		from their parents and returns them as a new NodeList.
+			// 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
+		},
+
+		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.
+			// 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"
+			//		or an offset in the childNodes property
+			return query(queryOrListOrNode).place(this[0], position)._stash(this);	// dojo.NodeList
+		},
+
+		// FIXME: do we need this?
+		query: function(/*String*/ queryStr){
+			// summary:
+			//		Returns a new list whose members match the passed query,
+			//		assuming elements of the current NodeList as the root for
+			//		each search.
+			// example:
+			//		assume a DOM created by this markup:
+			//	|	<div id="foo">
+			//	|		<p>
+			//	|			bacon is tasty, <span>dontcha think?</span>
+			//	|		</p>
+			//	|	</div>
+			//	|	<div id="bar">
+			//	|		<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"));
+			//		it's possible to find all span elements under paragraphs
+			//		contained by these elements with this sub-query:
+			//	|	var spans = l.query("p span");
+
+			// FIXME: probably slow
+			if(!queryStr){ return this; }
+			var ret = new NodeList;
+			this.map(function(node){
+				// FIXME: why would we ever get undefined here?
+				query(queryStr, node).forEach(function(subNode){
+					if(subNode !== undefined){
+						ret.push(subNode);
+					}
+				});
+			});
+			return ret._stash(this);	// dojo.NodeList
+		},
+
+		filter: function(/*String|Function*/ filter){
+			// summary:
+			//		"masks" the built-in javascript filter() method (supported
+			//		in Dojo via `dojo.filter`) to support passing a simple
+			//		string filter in addition to supporting filtering function
+			//		objects.
+			// filter:
+			//		If a string, a CSS rule like ".thinger" or "div > span".
+			// example:
+			//		"regular" JS filter syntax as exposed in dojo.filter:
+			//		|	dojo.query("*").filter(function(item){
+			//		|		// highlight every paragraph
+			//		|		return (item.nodeName == "p");
+			//		|	}).style("backgroundColor", "yellow");
+			// example:
+			//		the same filtering using a CSS selector
+			//		|	dojo.query("*").filter("p").styles("backgroundColor", "yellow");
+
+			var a = arguments, items = this, start = 0;
+			if(typeof filter == "string"){ // inline'd type check
+				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
+				}
+				// 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
+		},
+
+		/*
+		// FIXME: should this be "copyTo" and include parenting info?
+		clone: function(){
+			// summary:
+			//		creates node clones of each element of this list
+			//		and returns a new list containing the clones
+		},
+		*/
+
+		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.
+			// description:
+			//		a copy of the HTML content is added to each item in the
+			//		list, with an optional position argument. If no position
+			//		argument is provided, the content is appended to the end of
+			//		each item.
+			// content:
+			//		DOM node, HTML in string format, a NodeList or an Object. If a DOM node or
+			//		NodeList, the content will be cloned if the current NodeList has more than one
+			//		element. Only the DOM nodes are cloned, no event handlers. If it is an Object,
+			//		it should be an object with at "template" String property that has the HTML string
+			//		to insert. If dojo.string has already been dojo.required, then dojo.string.substitute
+			//		will be used on the "template" to generate the final HTML string. Other allowed
+			//		properties on the object are: "parse" if the HTML
+			//		string should be parsed for widgets (dojo.require("dojo.parser") to get that
+			//		option to work), and "templateFunc" if a template function besides dojo.string.substitute
+			//		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)
+			//		or an offset in the childNodes property
+			// example:
+			//		appends content to the end if the position is omitted
+			//	|	dojo.query("h3 > p").addContent("hey there!");
+			// example:
+			//		add something to the front of each element that has a
+			//		"thinger" property:
+			//	|	dojo.query("[thinger]").addContent("...", "first");
+			// example:
+			//		adds a header before each element of the list
+			//	|	dojo.query(".note").addContent("<h4>NOTE:</h4>", "before");
+			// example:
+			//		add a clone of a DOM node to the end of every element in
+			//		the list, removing it from its existing parent.
+			//	|	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"
+			//		});
+			// 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"
+			//		});
+			content = this._normalize(content, this[0]);
+			for(var i = 0, node; (node = this[i]); i++){
+				this._place(content, node, position, i > 0);
+			}
+			return this; //dojo.NodeList
+		}
+	});
+
+	/*===== return dojo.NodeList; =====*/
+	return NodeList;
+});
diff --git a/dojo/NodeList-fx.js b/dojo/NodeList-fx.js
index c784100..2a50df3 100644
--- a/dojo/NodeList-fx.js
+++ b/dojo/NodeList-fx.js
@@ -1,18 +1,27 @@
-define("dojo/NodeList-fx", ["dojo", "dojo/fx"], function(dojo) {
+define(["dojo/_base/NodeList", "./_base/lang", "./_base/connect", "./_base/fx", "./fx"], 
+  function(NodeList, lang, connectLib, baseFx, coreFx) {
+	// module:
+	//		dojo/NodeList-fx
+	// summary:
+	//		TODOC
 
 /*=====
 dojo["NodeList-fx"] = {
-	// summary: Adds dojo.fx animation support to dojo.query()
+	// 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;
 =====*/
 
-dojo.extend(dojo.NodeList, {
+lang.extend(NodeList, {
 	_anim: function(obj, method, args){
 		args = args||{};
-		var a = dojo.fx.combine(
+		var a = coreFx.combine(
 			this.map(function(item){
 				var tmpArgs = { node: item };
-				dojo.mixin(tmpArgs, args);
+				lang.mixin(tmpArgs, args);
 				return obj[method](tmpArgs);
 			})
 		);
@@ -20,129 +29,133 @@ dojo.extend(dojo.NodeList, {
 	},
 
 	wipeIn: function(args){
-		//	summary:
+		// summary:
 		//		wipe in all elements of this NodeList via `dojo.fx.wipeIn`
 		//
-		//	args: Object?
+		// args: Object?
 		//		Additional dojo.Animation arguments to mix into this set with the addition of
 		//		an `auto` parameter.
 		//
-		//	returns: dojo.Animation|dojo.NodeList
+		// returns: dojo.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
 		//
-		//	example:
+		// example:
 		//		Fade in all tables with class "blah":
 		//		|	dojo.query("table.blah").wipeIn().play();
 		//
-		//	example:
+		// example:
 		//		Utilizing `auto` to get the NodeList back:
 		//		|	dojo.query(".titles").wipeIn({ auto:true }).onclick(someFunction);
 		//
-		return this._anim(dojo.fx, "wipeIn", args); // dojo.Animation|dojo.NodeList
+		return this._anim(coreFx, "wipeIn", args); // dojo.Animation|dojo.NodeList
 	},
 
 	wipeOut: function(args){
-		//	summary:
+		// summary:
 		//		wipe out all elements of this NodeList via `dojo.fx.wipeOut`
 		//
-		//	args: Object?
+		// args: Object?
 		//		Additional dojo.Animation arguments to mix into this set with the addition of
 		//		an `auto` parameter.
 		//
-		//	returns: dojo.Animation|dojo.NodeList
+		// returns: dojo.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
 		//
-		//	example:
+		// example:
 		//		Wipe out all tables with class "blah":
 		//		|	dojo.query("table.blah").wipeOut().play();
-		return this._anim(dojo.fx, "wipeOut", args); // dojo.Animation|dojo.NodeList
+		return this._anim(coreFx, "wipeOut", args); // dojo.Animation|dojo.NodeList
 	},
 
 	slideTo: function(args){
-		//	summary:
+		// summary:
 		//		slide all elements of the node list to the specified place via `dojo.fx.slideTo`
 		//
-		//	args: Object?
+		// args: Object?
 		//		Additional dojo.Animation arguments to mix into this set with the addition of
 		//		an `auto` parameter.
 		//
-		//	returns: dojo.Animation|dojo.NodeList
+		// returns: dojo.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
 		//
-		//	example:
+		// example:
 		//		|	Move all tables with class "blah" to 300/300:
 		//		|	dojo.query("table.blah").slideTo({
 		//		|		left: 40,
 		//		|		top: 50
 		//		|	}).play();
-		return this._anim(dojo.fx, "slideTo", args); // dojo.Animation|dojo.NodeList
+		return this._anim(coreFx, "slideTo", args); // dojo.Animation|dojo.NodeList
 	},
 
 
 	fadeIn: function(args){
-		//	summary:
+		// summary:
 		//		fade in all elements of this NodeList via `dojo.fadeIn`
 		//
-		//	args: Object?
+		// args: Object?
 		//		Additional dojo.Animation arguments to mix into this set with the addition of
 		//		an `auto` parameter.
 		//
-		//	returns: dojo.Animation|dojo.NodeList
+		// returns: dojo.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
 		//
-		//	example:
+		// example:
 		//		Fade in all tables with class "blah":
 		//		|	dojo.query("table.blah").fadeIn().play();
-		return this._anim(dojo, "fadeIn", args); // dojo.Animation|dojo.NodeList
+		return this._anim(baseFx, "fadeIn", args); // dojo.Animation|dojo.NodeList
 	},
 
 	fadeOut: function(args){
-		//	summary:
+		// summary:
 		//		fade out all elements of this NodeList via `dojo.fadeOut`
 		//
-		//	args: Object?
+		// args: Object?
 		//		Additional dojo.Animation arguments to mix into this set with the addition of
 		//		an `auto` parameter.
 		//
-		//	returns: dojo.Animation|dojo.NodeList
+		// returns: dojo.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
 		//
-		//	example:
+		// example:
 		//		Fade out all elements with class "zork":
 		//		|	dojo.query(".zork").fadeOut().play();
-		//	example:
+		// example:
 		//		Fade them on a delay and do something at the end:
 		//		|	var fo = dojo.query(".zork").fadeOut();
 		//		|	dojo.connect(fo, "onEnd", function(){ /*...*/ });
 		//		|	fo.play();
-		//	example:
+		// example:
 		//		Using `auto`:
 		//		|	dojo.query("li").fadeOut({ auto:true }).filter(filterFn).forEach(doit);
 		//
-		return this._anim(dojo, "fadeOut", args); // dojo.Animation|dojo.NodeList
+		return this._anim(baseFx, "fadeOut", args); // dojo.Animation|dojo.NodeList
 	},
 
 	animateProperty: function(args){
-		//	summary:
+		// summary:
 		//		Animate all elements of this NodeList across the properties specified.
 		//		syntax identical to `dojo.animateProperty`
 		//
+		// args: Object?
+		//		Additional dojo.Animation arguments to mix into this set with the addition of
+		//		an `auto` parameter.
+		//
 		// returns: dojo.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
 		//
-		//	example:
+		// example:
 		//	|	dojo.query(".zork").animateProperty({
 		//	|		duration: 500,
 		//	|		properties: {
@@ -158,7 +171,7 @@ dojo.extend(dojo.NodeList, {
 		//	|			height:240
 		//	|		}
 		//	|	}).onclick(handler);
-		return this._anim(dojo, "animateProperty", args); // dojo.Animation|dojo.NodeList
+		return this._anim(baseFx, "animateProperty", args); // dojo.Animation|dojo.NodeList
 	},
 
 	anim: function( /*Object*/			properties,
@@ -166,31 +179,31 @@ dojo.extend(dojo.NodeList, {
 					/*Function?*/		easing,
 					/*Function?*/		onEnd,
 					/*Integer?*/		delay){
-		//	summary:
+		// summary:
 		//		Animate one or more CSS properties for all nodes in this list.
 		//		The returned animation object will already be playing when it
 		//		is returned. See the docs for `dojo.anim` for full details.
-		//	properties: Object
+		// properties: Object
 		//		the properties to animate. does NOT support the `auto` parameter like other
 		//		NodeList-fx methods.
-		//	duration: Integer?
+		// duration: Integer?
 		//		Optional. The time to run the animations for
-		//	easing: Function?
+		// easing: Function?
 		//		Optional. The easing function to use.
-		//	onEnd: Function?
+		// onEnd: Function?
 		//		A function to be called when the animation ends
-		//	delay:
+		// delay:
 		//		how long to delay playing the returned animation
-		//	example:
+		// example:
 		//		Another way to fade out:
 		//	|	dojo.query(".thinger").anim({ opacity: 0 });
-		//	example:
+		// example:
 		//		animate all elements with the "thigner" class to a width of 500
 		//		pixels over half a second
 		//	|	dojo.query(".thinger").anim({ width: 500 }, 700);
-		var canim = dojo.fx.combine(
+		var canim = coreFx.combine(
 			this.map(function(item){
-				return dojo.animateProperty({
+				return baseFx.animateProperty({
 					node: item,
 					properties: properties,
 					duration: duration||350,
@@ -199,11 +212,11 @@ dojo.extend(dojo.NodeList, {
 			})
 		);
 		if(onEnd){
-			dojo.connect(canim, "onEnd", onEnd);
+			connectLib.connect(canim, "onEnd", onEnd);
 		}
 		return canim.play(delay||0); // dojo.Animation
 	}
 });
 
-return dojo.NodeList;
+return NodeList;
 });
diff --git a/dojo/NodeList-html.js b/dojo/NodeList-html.js
index 22826c1..3c841da 100644
--- a/dojo/NodeList-html.js
+++ b/dojo/NodeList-html.js
@@ -1,17 +1,32 @@
-define("dojo/NodeList-html", ["dojo", "dojo/html"], function(dojo) {
+define(["./query", "./_base/lang", "./html"], function(query, lang, html) {
+	// module:
+	//		dojo/NodeList-html
+	// summary:
+	//		TODOC
+
+var NodeList = query.NodeList;
 
 /*=====
 dojo["NodeList-html"] = {
 	// summary: Adds a chainable html method to dojo.query() / Nodelist instances for setting/replacing node content
 };
+
+// doc helper aliases:
+NodeList = dojo.NodeList;
 =====*/
 
-dojo.extend(dojo.NodeList, {
-	html: function(content, /* Object? */params){
+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
 		//
-		// description:
+		//	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
+		//
+		//	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.
@@ -26,7 +41,7 @@ dojo.extend(dojo.NodeList, {
 		//	| 	}
 		//	| }).removeClass("notdone").addClass("done");
 
-		var dhs = new dojo.html._ContentSetter(params || {});
+		var dhs = new html._ContentSetter(params || {});
 		this.forEach(function(elm){
 			dhs.node = elm;
 			dhs.set(content);
@@ -36,5 +51,5 @@ dojo.extend(dojo.NodeList, {
 	}
 });
 
-return dojo.NodeList;
+return NodeList;
 });
diff --git a/dojo/NodeList-manipulate.js b/dojo/NodeList-manipulate.js
index a8923e9..42f6dc7 100644
--- a/dojo/NodeList-manipulate.js
+++ b/dojo/NodeList-manipulate.js
@@ -1,15 +1,23 @@
-define("dojo/NodeList-manipulate", ["dojo"], function(dojo) {
+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.
 };
+
+// doc alias helpers:
+NodeList = dojo.NodeList;
 =====*/
 
 //TODO: add a way to parse for widgets in the injected markup?
 
-(function(){
 	function getText(/*DOMNode*/node){
 		// summary:
 		// 		recursion method for text() to use. Gets text value for a node.
@@ -45,7 +53,7 @@ dojo["NodeList-manipulate"] = {
 		// summary:
 		// 		convert HTML into nodes if it is not already a node.
 		if(typeof html == "string"){
-			html = dojo._toDom(html, (refNode && refNode.ownerDocument));
+			html = construct.toDom(html, (refNode && refNode.ownerDocument));
 			if(html.nodeType == 11){
 				//DocumentFragment cannot handle cloneNode, so choose first child.
 				html = html.childNodes[0];
@@ -57,13 +65,13 @@ dojo["NodeList-manipulate"] = {
 		return html; /*DOMNode*/
 	}
 
-	dojo.extend(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.
-			var nl2 = typeof query == "string" || query.nodeType ? dojo.query(query) : query;
+			var nl2 = typeof query == "string" || query.nodeType ? dquery(query) : query;
 			var toAdd = [];
 			for(var i = 0; i < nl2.length; i++){
 				//Go backwards in DOM to make dom insertions easier via insertBefore
@@ -78,7 +86,7 @@ dojo["NodeList-manipulate"] = {
 						toAdd.unshift(item);
 					}
 					if(j == length - 1){
-						dojo.place(item, refNode, position);
+						construct.place(item, refNode, position);
 					}else{
 						refNode.parentNode.insertBefore(item, refNode);
 					}
@@ -180,7 +188,7 @@ dojo["NodeList-manipulate"] = {
 			if(arguments.length){
 				for(var i = 0, node; node = this[i]; i++){
 					if(node.nodeType == 1){
-						dojo.empty(node);
+						construct.empty(node);
 						node.appendChild(node.ownerDocument.createTextNode(value));
 					}
 				}
@@ -220,18 +228,18 @@ dojo["NodeList-manipulate"] = {
 
 			//Special work for input elements.
 			if(arguments.length){
-				var isArray = dojo.isArray(value);
+				var isArray = lang.isArray(value);
 				for(var index = 0, node; node = this[index]; index++){
 					var name = node.nodeName.toUpperCase();
 					var type = node.type;
 					var newValue = isArray ? value[index] : value;
-	
+
 					if(name == "SELECT"){
 						var opts = node.options;
 						for(var i = 0; i < opts.length; i++){
 							var opt = opts[i];
 							if(node.multiple){
-								opt.selected = (dojo.indexOf(value, opt.value) != -1);
+								opt.selected = (array.indexOf(value, opt.value) != -1);
 							}else{
 								opt.selected = (opt.value == newValue);
 							}
@@ -470,7 +478,7 @@ dojo["NodeList-manipulate"] = {
 			return; // dojo.NodeList
 		},
 		=====*/
-		remove: dojo.NodeList.prototype.orphan,
+		remove: NodeList.prototype.orphan,
 
 		wrap: function(/*String||DOMNode*/html){
 			// summary:
@@ -587,10 +595,10 @@ dojo["NodeList-manipulate"] = {
 					//the "this" nodes, then on the clone of html it will contain
 					//that "this" node, and that would be bad.
 					var clone = this._cloneNode(html);
-					
+
 					//Need to convert the childNodes to an array since wrapAll modifies the
 					//DOM and can change the live childNodes NodeList.
-					this._wrap(dojo._toArray(this[i].childNodes), null, this._NodeListCtor).wrapAll(clone);
+					this._wrap(lang._toArray(this[i].childNodes), null, this._NodeListCtor).wrapAll(clone);
 				}
 			}
 			return this; //dojo.NodeList
@@ -668,7 +676,7 @@ dojo["NodeList-manipulate"] = {
 			// 	|		<div class="red">Red One</div>
 			// 	|		<div class="red">Red Two</div>
 			//	|	</div>
-			var nl = dojo.query(query);
+			var nl = dquery(query);
 			var content = this._normalize(this, this[0]);
 			for(var i = 0, node; node = nl[i]; i++){
 				this._place(content, node, "before", i > 0);
@@ -714,10 +722,9 @@ dojo["NodeList-manipulate"] = {
 	});
 
 	//set up html method if one does not exist
-	if(!dojo.NodeList.prototype.html){
-		dojo.NodeList.prototype.html = dojo.NodeList.prototype.innerHTML;
+	if(!NodeList.prototype.html){
+		NodeList.prototype.html = NodeList.prototype.innerHTML;
 	}
-})();
 
-return dojo.NodeList;
+return NodeList;
 });
diff --git a/dojo/NodeList-traverse.js b/dojo/NodeList-traverse.js
index c4e570f..c609849 100644
--- a/dojo/NodeList-traverse.js
+++ b/dojo/NodeList-traverse.js
@@ -1,12 +1,21 @@
-define("dojo/NodeList-traverse", ["dojo"], function(dojo) {
+define(["./query", "./_base/lang", "./_base/array"], function(dquery, lang, array) {
+	// module:
+	//		dojo/NodeList-traverse
+	// summary:
+	//		TODOC
+
+var NodeList = dquery.NodeList;
 
 /*=====
 dojo["NodeList-traverse"] = {
 	// summary: Adds a chainable methods to dojo.query() / Nodelist instances for traversing the DOM
 };
+
+// doc alias helpers:
+NodeList = dojo.NodeList;
 =====*/
 
-dojo.extend(dojo.NodeList, {
+lang.extend(NodeList, {
 	_buildArrayFromCallback: function(/*Function*/callback){
 		// summary:
 		// 		builds a new array of possibly differing size based on the input list.
@@ -19,10 +28,10 @@ dojo.extend(dojo.NodeList, {
 				ary = ary.concat(items);
 			}
 		}
-		return ary;
+		return ary;	//Array
 	},
 
-	_getUniqueAsNodeList: function(nodes){
+	_getUniqueAsNodeList: function(/*Array*/ nodes){
 		// summary:
 		// 		given a list of nodes, make sure only unique
 		// 		elements are returned as our NodeList object.
@@ -33,23 +42,23 @@ dojo.extend(dojo.NodeList, {
 			//Should be a faster way to do this. dojo.query has a private
 			//_zip function that may be inspirational, but there are pathways
 			//in query that force nozip?
-			if(node.nodeType == 1 && dojo.indexOf(ary, node) == -1){
+			if(node.nodeType == 1 && array.indexOf(ary, node) == -1){
 				ary.push(node);
 			}
 		}
 		return this._wrap(ary, null, this._NodeListCtor);	 //dojo.NodeList
 	},
 
-	_getUniqueNodeListWithParent: function(nodes, query){
+	_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.
 		var ary = this._getUniqueAsNodeList(nodes);
-		ary = (query ? dojo._filterQueryResult(ary, query) : ary);
+		ary = (query ? dquery._filterResult(ary, query) : ary);
 		return ary._stash(this);  //dojo.NodeList
 	},
 
-	_getRelatedUniqueNodes: function(/*String?*/query, /*Function*/callback){
+	_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.
@@ -58,7 +67,7 @@ dojo.extend(dojo.NodeList, {
 		return this._getUniqueNodeListWithParent(this._buildArrayFromCallback(callback), query);  //dojo.NodeList
 	},
 
-	children: function(/*String?*/query){
+	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.
@@ -85,39 +94,39 @@ dojo.extend(dojo.NodeList, {
 		//	|	dojo.query(".container").children(".red");
 		//		returns the two divs that have the class "red".
 		return this._getRelatedUniqueNodes(query, function(node, ary){
-			return dojo._toArray(node.childNodes);
+			return lang._toArray(node.childNodes);
 		}); //dojo.NodeList
 	},
 
-	closest: function(/*String*/query, /*String|DOMNode?*/ root){
+	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.
 		// description:
 		// 		.end() can be used on the returned dojo.NodeList to get back to the
 		// 		original dojo.NodeList.
-		//	query:
+		// 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.
-		//	example:
+		// example:
 		//		assume a DOM created by this markup:
 		//	|	<div class="container">
-		// 	|		<div class="red">Red One</div>
-		// 	|		Some Text
-		// 	|		<div class="blue">Blue One</div>
-		// 	|		<div class="red">Red Two</div>
-		// 	|		<div class="blue">Blue Two</div>
+		//	|		<div class="red">Red One</div>
+		//	|		Some Text
+		//	|		<div class="blue">Blue One</div>
+		//	|		<div class="red">Red Two</div>
+		//	|		<div class="blue">Blue Two</div>
 		//	|	</div>
 		//		Running this code:
 		//	|	dojo.query(".red").closest(".container");
 		//		returns the div with class "container".
 		return this._getRelatedUniqueNodes(null, function(node, ary){
 			do{
-				if(dojo._filterQueryResult([node], query, root).length){
+				if(dquery._filterResult([node], query, root).length){
 					return node;
 				}
 			}while(node != root && (node = node.parentNode) && node.nodeType == 1);
@@ -125,7 +134,7 @@ dojo.extend(dojo.NodeList, {
 		}); //dojo.NodeList
 	},
 
-	parent: function(/*String?*/query){
+	parent: function(/*String?*/ query){
 		// summary:
 		// 		Returns immediate parent elements for nodes in this dojo.NodeList.
 		// 		Optionally takes a query to filter the parent elements.
@@ -155,7 +164,7 @@ dojo.extend(dojo.NodeList, {
 		}); //dojo.NodeList
 	},
 
-	parents: function(/*String?*/query){
+	parents: function(/*String?*/ query){
 		// summary:
 		// 		Returns all parent elements for nodes in this dojo.NodeList.
 		// 		Optionally takes a query to filter the child elements.
@@ -182,7 +191,7 @@ dojo.extend(dojo.NodeList, {
 		//	|	dojo.query(".text").parents(".container");
 		//		returns the one div with class "container".
 		return this._getRelatedUniqueNodes(query, function(node, ary){
-			var pary = []
+			var pary = [];
 			while(node.parentNode){
 				node = node.parentNode;
 				pary.push(node);
@@ -191,7 +200,7 @@ dojo.extend(dojo.NodeList, {
 		}); //dojo.NodeList
 	},
 
-	siblings: function(/*String?*/query){
+	siblings: function(/*String?*/ query){
 		// summary:
 		// 		Returns all sibling elements for nodes in this dojo.NodeList.
 		// 		Optionally takes a query to filter the sibling elements.
@@ -219,7 +228,7 @@ dojo.extend(dojo.NodeList, {
 		//	|	dojo.query(".first").siblings(".red");
 		//		returns the two div with class "red".
 		return this._getRelatedUniqueNodes(query, function(node, ary){
-			var pary = []
+			var pary = [];
 			var nodes = (node.parentNode && node.parentNode.childNodes);
 			for(var i = 0; i < nodes.length; i++){
 				if(nodes[i] != node){
@@ -230,7 +239,7 @@ dojo.extend(dojo.NodeList, {
 		}); //dojo.NodeList
 	},
 
-	next: function(/*String?*/query){
+	next: function(/*String?*/ query){
 		// summary:
 		// 		Returns the next element for nodes in this dojo.NodeList.
 		// 		Optionally takes a query to filter the next elements.
@@ -265,7 +274,7 @@ dojo.extend(dojo.NodeList, {
 		}); //dojo.NodeList
 	},
 
-	nextAll: function(/*String?*/query){
+	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.
@@ -292,7 +301,7 @@ dojo.extend(dojo.NodeList, {
 		//	|	dojo.query(".first").nextAll(".red");
 		//		returns the one div with class "red" and innerHTML "Red Two".
 		return this._getRelatedUniqueNodes(query, function(node, ary){
-			var pary = []
+			var pary = [];
 			var next = node;
 			while((next = next.nextSibling)){
 				if(next.nodeType == 1){
@@ -303,7 +312,7 @@ dojo.extend(dojo.NodeList, {
 		}); //dojo.NodeList
 	},
 
-	prev: function(/*String?*/query){
+	prev: function(/*String?*/ query){
 		// summary:
 		// 		Returns the previous element for nodes in this dojo.NodeList.
 		// 		Optionally takes a query to filter the previous elements.
@@ -338,7 +347,7 @@ dojo.extend(dojo.NodeList, {
 		}); //dojo.NodeList
 	},
 
-	prevAll: function(/*String?*/query){
+	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.
@@ -367,7 +376,7 @@ dojo.extend(dojo.NodeList, {
 		//	|	dojo.query(".first").prevAll(".red");
 		//		returns the one div with class "red prev" and innerHTML "Red One".
 		return this._getRelatedUniqueNodes(query, function(node, ary){
-			var pary = []
+			var pary = [];
 			var prev = node;
 			while((prev = prev.previousSibling)){
 				if(prev.nodeType == 1){
@@ -398,7 +407,7 @@ dojo.extend(dojo.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);
+		return this.concat(this._parent);	//dojo.NodeList
 	},
 
 	//Alternate methods for the :first/:last/:even/:odd pseudos.
@@ -495,5 +504,5 @@ dojo.extend(dojo.NodeList, {
 	}
 });
 
-return dojo.NodeList;
+return NodeList;
 });
diff --git a/dojo/OpenAjax.js b/dojo/OpenAjax.js
index 03c810f..0733641 100644
--- a/dojo/OpenAjax.js
+++ b/dojo/OpenAjax.js
@@ -47,11 +47,11 @@ if(!window["OpenAjax"]){
 				extraData: extra
 			};
 			this.publish(ooh+"registerLibrary", libs[prefix]);
-		}
+		};
 		h.unregisterLibrary = function(prefix){
 			this.publish(ooh+"unregisterLibrary", libs[prefix]);
 			delete libs[prefix];
-		}
+		};
 
 		h._subscriptions = { c:{}, s:[] };
 		h._cleanup = [];
@@ -67,7 +67,7 @@ if(!window["OpenAjax"]){
 			var path = name.split(".");
 	 		this._subscribe(this._subscriptions, path, 0, sub);
 			return handle;
-		}
+		};
 
 		h.publish = function(name, message){
 			var path = name.split(".");
@@ -81,13 +81,13 @@ if(!window["OpenAjax"]){
 				delete(this._cleanup);
 				this._cleanup = [];
 			}
-		}
+		};
 
 		h.unsubscribe = function(sub){
 			var path = sub.split(".");
 			var sid = path.pop();
 			this._unsubscribe(this._subscriptions, path, 0, sid);
-		}
+		};
 		
 		h._subscribe = function(tree, path, index, sub){
 			var token = path[index];
@@ -95,21 +95,21 @@ if(!window["OpenAjax"]){
 				tree.s.push(sub);
 			}else{
 				if(typeof tree.c == "undefined"){
-					 tree.c = {};
+					tree.c = {};
 				}
 				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);
 				}
 			}
-		}
+		};
 
 		h._publish = function(tree, path, index, name, msg){
 			if(typeof tree != "undefined"){
 				var node;
-				if(index == path.length) {
+				if(index == path.length){
 					node = tree;
 				}else{
 					this._publish(tree.c[path[index]], path, index + 1, name, msg);
@@ -134,33 +134,33 @@ if(!window["OpenAjax"]){
 								fcb = sc[fcb];
 							}
 							if((!fcb) ||
-							   (fcb.call(sc, name, msg, d))) {
+								(fcb.call(sc, name, msg, d))){
 								cb.call(sc, name, msg, d);
 							}
 						}
 					}
 				}
 			}
-		}
+		};
 			
-		h._unsubscribe = function(tree, path, index, sid) {
-			if(typeof tree != "undefined") {
-				if(index < path.length) {
+		h._unsubscribe = function(tree, path, index, sid){
+			if(typeof tree != "undefined"){
+				if(index < path.length){
 					var childNode = tree.c[path[index]];
 					this._unsubscribe(childNode, path, index + 1, sid);
-					if(childNode.s.length == 0) {
+					if(childNode.s.length == 0){
 						for(var x in childNode.c)
-					 		return;
+							return;
 						delete tree.c[path[index]];
 					}
 					return;
 				}
-				else {
+				else{
 					var callbacks = tree.s;
 					var max = callbacks.length;
 					for(var i = 0; i < max; i++)
-						if(sid == callbacks[i].sid) {
-							if(this._pubDepth > 0) {
+						if(sid == callbacks[i].sid){
+							if(this._pubDepth > 0){
 								callbacks[i].cb = null;
 								this._cleanup.push(callbacks[i]);
 							}
@@ -170,7 +170,7 @@ if(!window["OpenAjax"]){
 						}
 				}
 			}
-		}
+		};
 		// 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()
diff --git a/dojo/Stateful.js b/dojo/Stateful.js
index 603e4cb..eb5afa9 100644
--- a/dojo/Stateful.js
+++ b/dojo/Stateful.js
@@ -1,6 +1,10 @@
-define("dojo/Stateful", ["dojo"], function(dojo) {
+define(["./_base/kernel", "./_base/declare", "./_base/lang", "./_base/array"], function(dojo, declare, lang, array) {
+	// module:
+	//		dojo/Stateful
+	// summary:
+	//		TODOC
 
-dojo.declare("dojo.Stateful", null, {
+return dojo.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
@@ -12,15 +16,17 @@ dojo.declare("dojo.Stateful", null, {
 	//	|	obj.set("foo","bar");
 	postscript: function(mixin){
 		if(mixin){
-			dojo.mixin(this, mixin);
+			lang.mixin(this, mixin);
 		}
 	},
-	
+
 	get: function(/*String*/name){
 		// summary:
 		//		Get a property on a Stateful instance.
 		//	name:
 		//		The property to get.
+		//	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
@@ -29,8 +35,8 @@ dojo.declare("dojo.Stateful", null, {
 		//	|	stateful = new dojo.Stateful({foo: 3});
 		//	|	stateful.get("foo") // returns 3
 		//	|	stateful.foo // returns 3
-		
-		return this[name];
+
+		return this[name]; //Any
 	},
 	set: function(/*String*/name, /*Object*/value){
 		// summary:
@@ -39,6 +45,8 @@ dojo.declare("dojo.Stateful", null, {
 		//		The property to set.
 		//	value:
 		//		The value to set in the property.
+		//	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.
@@ -66,7 +74,7 @@ dojo.declare("dojo.Stateful", null, {
 		if(this._watchCallbacks){
 			this._watchCallbacks(name, oldValue, value);
 		}
-		return this;
+		return this; //dojo.Stateful
 	},
 	watch: function(/*String?*/name, /*Function*/callback){
 		// summary:
@@ -84,7 +92,7 @@ dojo.declare("dojo.Stateful", null, {
 		//		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.
-		
+
 		var callbacks = this._watchCallbacks;
 		if(!callbacks){
 			var self = this;
@@ -121,12 +129,11 @@ dojo.declare("dojo.Stateful", null, {
 		propertyCallbacks.push(callback);
 		return {
 			unwatch: function(){
-				propertyCallbacks.splice(dojo.indexOf(propertyCallbacks, callback), 1);
+				propertyCallbacks.splice(array.indexOf(propertyCallbacks, callback), 1);
 			}
-		};
+		}; //Object
 	}
-	
+
 });
 
-return dojo.Stateful;
 });
diff --git a/dojo/_base.js b/dojo/_base.js
deleted file mode 100644
index 04a496c..0000000
--- a/dojo/_base.js
+++ /dev/null
@@ -1,11 +0,0 @@
-define("dojo/_base",[
-"dojo/_base/lang",
-"dojo/_base/array",
-"dojo/_base/declare",
-"dojo/_base/connect",
-"dojo/_base/Deferred",
-"dojo/_base/json",
-"dojo/_base/Color",
-dojo.isBrowser? "dojo/_base/browser" : "dojo/_base/lang"], function(){
-	return dojo;
-});
diff --git a/dojo/_base/Color.js b/dojo/_base/Color.js
index 2319025..d20db59 100644
--- a/dojo/_base/Color.js
+++ b/dojo/_base/Color.js
@@ -1,14 +1,10 @@
-define("dojo/_base/Color", ["dojo/lib/kernel", "dojo/_base/array", "dojo/_base/lang"], function(dojo){
+define(["./kernel", "./lang", "./array", "./config"], function(dojo, lang, ArrayUtil, config){
 
-(function(){
-
-	var d = dojo;
-
-	dojo.Color = function(/*Array|String|Object*/ color){
+	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
-		//	 	and creates a new Color instance to work from.
+		//		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
+		//		and creates a new Color instance to work from.
 		//
 		// example:
 		//		Work with a Color instance:
@@ -26,30 +22,38 @@ define("dojo/_base/Color", ["dojo/lib/kernel", "dojo/_base/array", "dojo/_base/l
 		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?
-	dojo.Color.named = {
-		black:      [0,0,0],
-		silver:     [192,192,192],
-		gray:       [128,128,128],
-		white:      [255,255,255],
-		maroon:		[128,0,0],
-		red:        [255,0,0],
-		purple:		[128,0,128],
-		fuchsia:	[255,0,255],
-		green:	    [0,128,0],
-		lime:	    [0,255,0],
-		olive:		[128,128,0],
-		yellow:		[255,255,0],
-		navy:       [0,0,128],
-		blue:       [0,0,255],
-		teal:		[0,128,128],
-		aqua:		[0,255,255],
-		transparent: d.config.transparentColor || [255,255,255]
+	// there's got to be a more space-efficient way to encode or discover
+	// these!! Use hex?
+	Color.named = {
+		"black":  [0,0,0],
+		"silver": [192,192,192],
+		"gray":	  [128,128,128],
+		"white":  [255,255,255],
+		"maroon": [128,0,0],
+		"red":	  [255,0,0],
+		"purple": [128,0,128],
+		"fuchsia":[255,0,255],
+		"green":  [0,128,0],
+		"lime":	  [0,255,0],
+		"olive":  [128,128,0],
+		"yellow": [255,255,0],
+		"navy":	  [0,0,128],
+		"blue":	  [0,0,255],
+		"teal":	  [0,128,128],
+		"aqua":	  [0,255,255],
+		"transparent": config.transparentColor || [0,0,0,0]
 	};
 
-	dojo.extend(dojo.Color, {
+	lang.extend(Color, {
 		r: 255, g: 255, b: 255, a: 1,
 		_set: function(r, g, b, a){
 			var t = this; t.r = r; t.g = g; t.b = b; t.a = a;
@@ -63,13 +67,13 @@ define("dojo/_base/Color", ["dojo/lib/kernel", "dojo/_base/array", "dojo/_base/l
 			// example:
 			//	|	var c = new dojo.Color(); // no color
 			//	|	c.setColor("#ededed"); // greyish
-			if(d.isString(color)){
-				d.colorFromString(color, this);
-			}else if(d.isArray(color)){
-				d.colorFromArray(color, this);
+			if(lang.isString(color)){
+				Color.fromString(color, this);
+			}else if(lang.isArray(color)){
+				Color.fromArray(color, this);
 			}else{
 				this._set(color.r, color.g, color.b, color.a);
-				if(!(color instanceof d.Color)){ this.sanitize(); }
+				if(!(color instanceof Color)){ this.sanitize(); }
 			}
 			return this;	// dojo.Color
 		},
@@ -86,9 +90,9 @@ define("dojo/_base/Color", ["dojo/lib/kernel", "dojo/_base/array", "dojo/_base/l
 			//		Returns 3 component array of rgb values
 			// example:
 			//	|	var c = new dojo.Color("#000000");
-			//	| 	console.log(c.toRgb()); // [0,0,0]
+			//	|	console.log(c.toRgb()); // [0,0,0]
 			var t = this;
-			return [t.r, t.g, t.b];	// Array
+			return [t.r, t.g, t.b]; // Array
 		},
 		toRgba: function(){
 			// summary:
@@ -101,8 +105,8 @@ define("dojo/_base/Color", ["dojo/lib/kernel", "dojo/_base/array", "dojo/_base/l
 			// summary:
 			//		Returns a CSS color string in hexadecimal representation
 			// example:
-			//	| 	console.log(new dojo.Color([0,0,0]).toHex()); // #000000
-			var arr = d.map(["r", "g", "b"], function(x){
+			//	|	console.log(new dojo.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;
 			}, this);
@@ -124,7 +128,7 @@ define("dojo/_base/Color", ["dojo/lib/kernel", "dojo/_base/array", "dojo/_base/l
 		}
 	});
 
-	dojo.blendColors = function(
+	Color.blendColors = dojo.blendColors = function(
 		/*dojo.Color*/ start,
 		/*dojo.Color*/ end,
 		/*Number*/ weight,
@@ -133,15 +137,15 @@ define("dojo/_base/Color", ["dojo/lib/kernel", "dojo/_base/array", "dojo/_base/l
 		// 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
-		var t = obj || new d.Color();
-		d.forEach(["r", "g", "b", "a"], function(x){
+		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
 	};
 
-	dojo.colorFromRgb = function(/*String*/ color, /*dojo.Color?*/ obj){
+	Color.fromRgb = dojo.colorFromRgb = function(/*String*/ color, /*dojo.Color?*/ obj){
 		// summary:
 		//		Returns a `dojo.Color` instance from a string of the form
 		//		"rgb(...)" or "rgba(...)". Optionally accepts a `dojo.Color`
@@ -150,10 +154,10 @@ define("dojo/_base/Color", ["dojo/lib/kernel", "dojo/_base/array", "dojo/_base/l
 		// returns:
 		//		A dojo.Color object. If obj is passed, it will be the return value.
 		var m = color.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/);
-		return m && dojo.colorFromArray(m[1].split(/\s*,\s*/), obj);	// dojo.Color
+		return m && Color.fromArray(m[1].split(/\s*,\s*/), obj);	// dojo.Color
 	};
 
-	dojo.colorFromHex = function(/*String*/ color, /*dojo.Color?*/ obj){
+	Color.fromHex = dojo.colorFromHex = function(/*String*/ color, /*dojo.Color?*/ obj){
 		// summary:
 		//		Converts a hex string with a '#' prefix to a color object.
 		//		Supports 12-bit #rgb shorthand. Optionally accepts a
@@ -167,14 +171,14 @@ define("dojo/_base/Color", ["dojo/lib/kernel", "dojo/_base/array", "dojo/_base/l
 		//
 		// example:
 		//	| var thing = dojo.colorFromHex("#000"); // black, shorthand
-		var t = obj || new d.Color(),
+		var t = obj || new Color(),
 			bits = (color.length == 4) ? 4 : 8,
 			mask = (1 << bits) - 1;
 		color = Number("0x" + color.substr(1));
 		if(isNaN(color)){
 			return null; // dojo.Color
 		}
-		d.forEach(["b", "g", "r"], function(x){
+		ArrayUtil.forEach(["b", "g", "r"], function(x){
 			var c = color & mask;
 			color >>= bits;
 			t[x] = bits == 4 ? 17 * c : c;
@@ -183,7 +187,7 @@ define("dojo/_base/Color", ["dojo/lib/kernel", "dojo/_base/array", "dojo/_base/l
 		return t;	// dojo.Color
 	};
 
-	dojo.colorFromArray = function(/*Array*/ a, /*dojo.Color?*/ obj){
+	Color.fromArray = dojo.colorFromArray = function(/*Array*/ a, /*dojo.Color?*/ obj){
 		// summary:
 		//		Builds a `dojo.Color` from a 3 or 4 element array, mapping each
 		//		element in sequence to the rgb(a) values of the color.
@@ -191,13 +195,13 @@ define("dojo/_base/Color", ["dojo/lib/kernel", "dojo/_base/array", "dojo/_base/l
 		//		| 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.
-		var t = obj || new d.Color();
+		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
 	};
 
-	dojo.colorFromString = function(/*String*/ str, /*dojo.Color?*/ obj){
+	Color.fromString = dojo.colorFromString = function(/*String*/ str, /*dojo.Color?*/ obj){
 		// summary:
 		//		Parses `str` for a color value. Accepts hex, rgb, and rgba
 		//		style color values.
@@ -208,10 +212,9 @@ define("dojo/_base/Color", ["dojo/lib/kernel", "dojo/_base/array", "dojo/_base/l
 		//		10, 50)"
 		// returns:
 		//		A dojo.Color object. If obj is passed, it will be the return value.
-		var a = d.Color.named[str];
-		return a && d.colorFromArray(a, obj) || d.colorFromRgb(str, obj) || d.colorFromHex(str, obj);
+		var a = Color.named[str];
+		return a && Color.fromArray(a, obj) || Color.fromRgb(str, obj) || Color.fromHex(str, obj);	// dojo.Color
 	};
-})();
 
-return dojo.Color;
+	return Color;
 });
diff --git a/dojo/_base/Deferred.js b/dojo/_base/Deferred.js
index 00a09b4..81a074e 100644
--- a/dojo/_base/Deferred.js
+++ b/dojo/_base/Deferred.js
@@ -1,154 +1,158 @@
-define("dojo/_base/Deferred", ["dojo/lib/kernel", "dojo/_base/lang"], function(dojo){
+define(["./kernel", "./lang"], function(dojo, lang){
+	// module:
+	//		dojo/_base/Deferred
+	// summary:
+	//		This module defines dojo.Deferred.
 
-(function(){
 	var mutator = function(){};
 	var freeze = Object.freeze || function(){};
 	// A deferred provides an API for creating and resolving a promise.
-	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.
-	// description:
-	//		The dojo.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
-	//		call patterns and logical data flow in asynchronous code as can be
-	//		achieved in synchronous code. Promises allows one
-	//		to be able to call a function purely with arguments needed for
-	//		execution, without conflating the call with concerns of whether it is
-	//		sync or async. One shouldn't need to alter a call's arguments if the
-	//		implementation switches from sync to async (or vice versa). By having
-	//		async functions return promises, the concerns of making the call are
-	//		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
-	// 		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:
-	//
-	//		| 	var resultingPromise = someAsyncOperation.then(function(result){
-	//		|		... handle result ...
-	//		|	},
-	//		|	function(error){
-	//		|		... handle error ...
-	//		|	});
-	//
-	//		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:
-	//
-	//			* 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.
-	//
-	//		The creator of the Deferred may specify a canceller.  The canceller
-	//		is a function that will be called if Deferred.cancel is called
-	//		before the Deferred fires. You can use this to implement clean
-	//		aborting of an XMLHttpRequest, etc. Note that cancel will fire the
-	//		deferred with a CancelledError (unless your canceller returns
-	//		another kind of error), so the errbacks should be prepared to
-	//		handle that error for cancellable Deferreds.
-	// example:
-	//	|	var deferred = new dojo.Deferred();
-	//	|	setTimeout(function(){ deferred.callback({success: true}); }, 1000);
-	//	|	return deferred;
-	// example:
-	//		Deferred objects are often used when making code asynchronous. It
-	//		may be easiest to write functions in a synchronous manner and then
-	//		split code using a deferred to trigger a response to a long-lived
-	//		operation. For example, instead of register a callback function to
-	//		denote when a rendering operation completes, the function can
-	//		simply return a deferred:
-	//
-	//		|	// callback style:
-	//		|	function renderLotsOfData(data, callback){
-	//		|		var success = false
-	//		|		try{
-	//		|			for(var x in data){
-	//		|				renderDataitem(data[x]);
-	//		|			}
-	//		|			success = true;
-	//		|		}catch(e){ }
-	//		|		if(callback){
-	//		|			callback(success);
-	//		|		}
-	//		|	}
-	//
-	//		|	// using callback style
-	//		|	renderLotsOfData(someDataObj, function(success){
-	//		|		// handles success or failure
-	//		|		if(!success){
-	//		|			promptUserToRecover();
-	//		|		}
-	//		|	});
-	//		|	// NOTE: no way to add another callback here!!
-	// example:
-	//		Using a Deferred doesn't simplify the sending code any, but it
-	//		provides a standard interface for callers and senders alike,
-	//		providing both with a simple way to service multiple callbacks for
-	//		an operation and freeing both sides from worrying about details
-	//		such as "did this get called already?". With Deferreds, new
-	//		callbacks can be added at any time.
-	//
-	//		|	// Deferred style:
-	//		|	function renderLotsOfData(data){
-	//		|		var d = new dojo.Deferred();
-	//		|		try{
-	//		|			for(var x in data){
-	//		|				renderDataitem(data[x]);
-	//		|			}
-	//		|			d.callback(true);
-	//		|		}catch(e){
-	//		|			d.errback(new Error("rendering failed"));
-	//		|		}
-	//		|		return d;
-	//		|	}
-	//
-	//		|	// using Deferred style
-	//		|	renderLotsOfData(someDataObj).then(null, function(){
-	//		|		promptUserToRecover();
-	//		|	});
-	//		|	// NOTE: addErrback and addCallback both return the Deferred
-	//		|	// again, so we could chain adding callbacks or save the
-	//		|	// deferred for later should we need to be notified again.
-	// example:
-	//		In this example, renderLotsOfData is synchronous and so both
-	//		versions are pretty artificial. Putting the data display on a
-	//		timeout helps show why Deferreds rock:
-	//
-	//		|	// Deferred style and async func
-	//		|	function renderLotsOfData(data){
-	//		|		var d = new dojo.Deferred();
-	//		|		setTimeout(function(){
-	//		|			try{
-	//		|				for(var x in data){
-	//		|					renderDataitem(data[x]);
-	//		|				}
-	//		|				d.callback(true);
-	//		|			}catch(e){
-	//		|				d.errback(new Error("rendering failed"));
-	//		|			}
-	//		|		}, 100);
-	//		|		return d;
-	//		|	}
-	//
-	//		|	// using Deferred style
-	//		|	renderLotsOfData(someDataObj).then(null, function(){
-	//		|		promptUserToRecover();
-	//		|	});
-	//
-	//		Note that the caller doesn't have to change his code at all to
-	//		handle the asynchronous case.
+	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.
+		// description:
+		//		The dojo.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
+		//		call patterns and logical data flow in asynchronous code as can be
+		//		achieved in synchronous code. Promises allows one
+		//		to be able to call a function purely with arguments needed for
+		//		execution, without conflating the call with concerns of whether it is
+		//		sync or async. One shouldn't need to alter a call's arguments if the
+		//		implementation switches from sync to async (or vice versa). By having
+		//		async functions return promises, the concerns of making the call are
+		//		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
+		//		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:
+		//
+		//		|	var resultingPromise = someAsyncOperation.then(function(result){
+		//		|		... handle result ...
+		//		|	},
+		//		|	function(error){
+		//		|		... handle error ...
+		//		|	});
+		//
+		//		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:
+		//
+		//			* 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.
+		//
+		//		The creator of the Deferred may specify a canceller.  The canceller
+		//		is a function that will be called if Deferred.cancel is called
+		//		before the Deferred fires. You can use this to implement clean
+		//		aborting of an XMLHttpRequest, etc. Note that cancel will fire the
+		//		deferred with a CancelledError (unless your canceller returns
+		//		another kind of error), so the errbacks should be prepared to
+		//		handle that error for cancellable Deferreds.
+		// example:
+		//	|	var deferred = new dojo.Deferred();
+		//	|	setTimeout(function(){ deferred.callback({success: true}); }, 1000);
+		//	|	return deferred;
+		// example:
+		//		Deferred objects are often used when making code asynchronous. It
+		//		may be easiest to write functions in a synchronous manner and then
+		//		split code using a deferred to trigger a response to a long-lived
+		//		operation. For example, instead of register a callback function to
+		//		denote when a rendering operation completes, the function can
+		//		simply return a deferred:
+		//
+		//		|	// callback style:
+		//		|	function renderLotsOfData(data, callback){
+		//		|		var success = false
+		//		|		try{
+		//		|			for(var x in data){
+		//		|				renderDataitem(data[x]);
+		//		|			}
+		//		|			success = true;
+		//		|		}catch(e){ }
+		//		|		if(callback){
+		//		|			callback(success);
+		//		|		}
+		//		|	}
+		//
+		//		|	// using callback style
+		//		|	renderLotsOfData(someDataObj, function(success){
+		//		|		// handles success or failure
+		//		|		if(!success){
+		//		|			promptUserToRecover();
+		//		|		}
+		//		|	});
+		//		|	// NOTE: no way to add another callback here!!
+		// example:
+		//		Using a Deferred doesn't simplify the sending code any, but it
+		//		provides a standard interface for callers and senders alike,
+		//		providing both with a simple way to service multiple callbacks for
+		//		an operation and freeing both sides from worrying about details
+		//		such as "did this get called already?". With Deferreds, new
+		//		callbacks can be added at any time.
+		//
+		//		|	// Deferred style:
+		//		|	function renderLotsOfData(data){
+		//		|		var d = new dojo.Deferred();
+		//		|		try{
+		//		|			for(var x in data){
+		//		|				renderDataitem(data[x]);
+		//		|			}
+		//		|			d.callback(true);
+		//		|		}catch(e){
+		//		|			d.errback(new Error("rendering failed"));
+		//		|		}
+		//		|		return d;
+		//		|	}
+		//
+		//		|	// using Deferred style
+		//		|	renderLotsOfData(someDataObj).then(null, function(){
+		//		|		promptUserToRecover();
+		//		|	});
+		//		|	// NOTE: addErrback and addCallback both return the Deferred
+		//		|	// again, so we could chain adding callbacks or save the
+		//		|	// deferred for later should we need to be notified again.
+		// example:
+		//		In this example, renderLotsOfData is synchronous and so both
+		//		versions are pretty artificial. Putting the data display on a
+		//		timeout helps show why Deferreds rock:
+		//
+		//		|	// Deferred style and async func
+		//		|	function renderLotsOfData(data){
+		//		|		var d = new dojo.Deferred();
+		//		|		setTimeout(function(){
+		//		|			try{
+		//		|				for(var x in data){
+		//		|					renderDataitem(data[x]);
+		//		|				}
+		//		|				d.callback(true);
+		//		|			}catch(e){
+		//		|				d.errback(new Error("rendering failed"));
+		//		|			}
+		//		|		}, 100);
+		//		|		return d;
+		//		|	}
+		//
+		//		|	// using Deferred style
+		//		|	renderLotsOfData(someDataObj).then(null, function(){
+		//		|		promptUserToRecover();
+		//		|	});
+		//
+		//		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 = {});
-		
+
 		function complete(value){
 			if(finished){
 				throw new Error("This deferred has already been resolved");
@@ -166,11 +170,11 @@ define("dojo/_base/Deferred", ["dojo/lib/kernel", "dojo/_base/lang"], function(d
 					finished = false;
 				}
 				var func = (isError ? listener.error : listener.resolved);
-				if (func) {
-					try {
+				if(func){
+					try{
 						var newResult = func(result);
-						if (newResult && typeof newResult.then === "function") {
-							newResult.then(dojo.hitch(listener.deferred, "resolve"), dojo.hitch(listener.deferred, "reject"));
+						if (newResult && typeof newResult.then === "function"){
+							newResult.then(lang.hitch(listener.deferred, "resolve"), lang.hitch(listener.deferred, "reject"), lang.hitch(listener.deferred, "progress"));
 							continue;
 						}
 						var unchanged = mutated && newResult === undefined;
@@ -178,11 +182,10 @@ define("dojo/_base/Deferred", ["dojo/lib/kernel", "dojo/_base/lang"], function(d
 							isError = newResult instanceof Error;
 						}
 						listener.deferred[unchanged && isError ? "reject" : "resolve"](unchanged ? result : newResult);
-					}
-					catch (e) {
+					}catch(e){
 						listener.deferred.reject(e);
 					}
-				}else {
+				}else{
 					if(isError){
 						listener.deferred.reject(result);
 					}else{
@@ -199,8 +202,8 @@ define("dojo/_base/Deferred", ["dojo/lib/kernel", "dojo/_base/lang"], function(d
 			this.results = [value, null];
 			complete(value);
 		};
-		
-		
+
+
 		// calling error will indicate that the promise failed
 		this.reject = this.errback = function(error){
 			// summary:
@@ -215,7 +218,7 @@ define("dojo/_base/Deferred", ["dojo/lib/kernel", "dojo/_base/lang"], function(d
 		};
 		// call progress to provide updates on the progress on the completion of the promise
 		this.progress = function(update){
-			// summary
+			// summary:
 			//		Send progress events to all listeners
 			var listener = nextListener;
 			while(listener){
@@ -224,33 +227,44 @@ define("dojo/_base/Deferred", ["dojo/lib/kernel", "dojo/_base/lang"], function(d
 				listener = listener.next;
 			}
 		};
-		this.addCallbacks = function(/*Function?*/callback, /*Function?*/errback){
+		this.addCallbacks = function(callback, errback){
+			// summary:
+			//		Adds callback and error callback for this deferred instance.
+			// callback: Function?
+			// 		The callback attached to this deferred object.
+			// errback: Function?
+			// 		The error callback attached to this deferred object.
+			// returns:
+			// 		Returns this deferred object.
 			this.then(callback, errback, mutator);
-			return this;
+			return this;	// dojo.Deferred
 		};
 		// provide the implementation of the promise
-		this.then = promise.then = function(/*Function?*/resolvedCallback, /*Function?*/errorCallback, /*Function?*/progressCallback){
+		promise.then = this.then = function(/*Function?*/resolvedCallback, /*Function?*/errorCallback, /*Function?*/progressCallback){
 			// summary:
-			// 		Adds a fulfilledHandler, errorHandler, and progressHandler to be called for
-			// 		completion of a promise. The fulfilledHandler is called when the promise
-			// 		is fulfilled. The errorHandler is called when a promise fails. The
-			// 		progressHandler is called for progress events. All arguments are optional
-			// 		and non-function values are ignored. The progressHandler is not only an
-			// 		optional argument, but progress events are purely optional. Promise
-			// 		providers are not required to ever create progress events.
+			//		Adds a fulfilledHandler, errorHandler, and progressHandler to be called for
+			//		completion of a promise. The fulfilledHandler is called when the promise
+			//		is fulfilled. The errorHandler is called when a promise fails. The
+			//		progressHandler is called for progress events. All arguments are optional
+			//		and non-function values are ignored. The progressHandler is not only an
+			//		optional argument, but progress events are purely optional. Promise
+			//		providers are not required to ever create progress events.
 			//
-			// 		This function will return a new promise that is fulfilled when the given
-			// 		fulfilledHandler or errorHandler callback is finished. This allows promise
-			// 		operations to be chained together. The value returned from the callback
-			// 		handler is the fulfillment value for the returned promise. If the callback
-			// 		throws an error, the returned promise will be moved to failed state.
+			//		This function will return a new promise that is fulfilled when the given
+			//		fulfilledHandler or errorHandler callback is finished. This allows promise
+			//		operations to be chained together. The value returned from the callback
+			//		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 a new promise that represents the result of the
+			//		execution of the callback. The callbacks will never affect the original promises value.
 			// example:
-			// 		An example of using a CommonJS compliant promise:
-  			//		|	asyncComputeTheAnswerToEverything().
+			//		An example of using a CommonJS compliant promise:
+			//		|	asyncComputeTheAnswerToEverything().
 			//		|		then(addTwo).
 			//		|		then(printResult, onError);
-  			//		|	>44
+			//		|	>44
 			//
 			var returnDeferred = progressCallback == mutator ? this : new dojo.Deferred(promise.cancel);
 			var listener = {
@@ -268,16 +282,16 @@ define("dojo/_base/Deferred", ["dojo/lib/kernel", "dojo/_base/lang"], function(d
 			if(finished){
 				notify();
 			}
-			return returnDeferred.promise;
+			return returnDeferred.promise; // Promise
 		};
 		var deferred = this;
-		this.cancel = promise.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)) {
+					if (!(error instanceof Error)){
 						error = new Error(error);
 					}
 					error.log = false;
@@ -287,50 +301,66 @@ define("dojo/_base/Deferred", ["dojo/lib/kernel", "dojo/_base/lang"], function(d
 		};
 		freeze(promise);
 	};
-	dojo.extend(dojo.Deferred, {
-		addCallback: function (/*Function*/callback) {
-			return this.addCallbacks(dojo.hitch.apply(dojo, arguments));
+	lang.extend(dojo.Deferred, {
+		addCallback: function (/*Function*/ callback){
+			// summary:
+			// 		Adds successful callback for this deferred instance.
+			// returns:
+			// 		Returns this deferred object.
+			return this.addCallbacks(lang.hitch.apply(dojo, arguments));	// dojo.Deferred
 		},
-	
-		addErrback: function (/*Function*/errback) {
-			return this.addCallbacks(null, dojo.hitch.apply(dojo, arguments));
+
+		addErrback: function (/*Function*/ errback){
+			// summary:
+			// 		Adds error callback for this deferred instance.
+			// returns:
+			// 		Returns this deferred object.
+			return this.addCallbacks(null, lang.hitch.apply(dojo, arguments));	// dojo.Deferred
 		},
-	
-		addBoth: function (/*Function*/callback) {
-			var enclosed = dojo.hitch.apply(dojo, arguments);
-			return this.addCallbacks(enclosed, enclosed);
+
+		addBoth: function (/*Function*/ callback){
+			// summary:
+			// 		Add handler as both successful callback and error callback for this deferred instance.
+			// returns:
+			// 		Returns this deferred object.
+			var enclosed = lang.hitch.apply(dojo, arguments);
+			return this.addCallbacks(enclosed, enclosed);	// dojo.Deferred
 		},
 		fired: -1
 	});
-})();
-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
-	//	example:
-	//		|	function printFirstAndList(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];
-	//		|		});
-	//		|	}
-	//		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(promiseOrValue);
-};
 
-return dojo.Deferred;
+	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
+	};
+
+	return dojo.Deferred;
 });
diff --git a/dojo/_base/NodeList.js b/dojo/_base/NodeList.js
index 2f4a63d..abf8219 100644
--- a/dojo/_base/NodeList.js
+++ b/dojo/_base/NodeList.js
@@ -1,684 +1,30 @@
-define("dojo/_base/NodeList", ["dojo/lib/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/connect", "dojo/_base/html"], function(dojo){
-
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-(function(){
-
-	var d = dojo;
-//>>excludeEnd("webkitMobile");
-
-	var ap = Array.prototype, aps = ap.slice, apc = ap.concat;
-
-	var tnl = function(/*Array*/ a, /*dojo.NodeList?*/ parent, /*Function?*/ NodeListCtor){
-		// summary:
-		// 		decorate an array to make it look like a `dojo.NodeList`.
-		// a:
-		// 		Array of nodes to decorate.
-		// parent:
-		// 		An optional parent NodeList that generated the current
-		// 		list of nodes. Used to call _stash() so the parent NodeList
-		// 		can be accessed via end() later.
-		// 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.
-		if(!a.sort){
-			// make sure it's a real array before we pass it on to be wrapped
-			a = aps.call(a, 0);
-		}
-		var ctor = NodeListCtor || this._NodeListCtor || d._NodeListCtor;
-		a.constructor = ctor;
-		dojo._mixin(a, ctor.prototype);
-		a._NodeListCtor = ctor;
-		return parent ? a._stash(parent) : a;
-	};
-
-	var loopBody = function(f, a, o){
-		a = [0].concat(aps.call(a, 0));
-		o = o || d.global;
-		return function(node){
-			a[0] = node;
-			return f.apply(o, a);
-		};
-	};
-
-	// adapters
-
-	var adaptAsForEach = function(f, o){
-		//	summary:
-		//		adapts a single node function to be used in the forEach-type
-		//		actions. The initial object is returned from the specialized
-		//		function.
-		//	f: Function
-		//		a function to adapt
-		//	o: Object?
-		//		an optional context for f
-		return function(){
-			this.forEach(loopBody(f, arguments, o));
-			return this;	// Object
-		};
-	};
-
-	var adaptAsMap = function(f, o){
-		//	summary:
-		//		adapts a single node function to be used in the map-type
-		//		actions. The return is a new array of values, as via `dojo.map`
-		//	f: Function
-		//		a function to adapt
-		//	o: Object?
-		//		an optional context for f
-		return function(){
-			return this.map(loopBody(f, arguments, o));
-		};
-	};
-
-	var adaptAsFilter = function(f, o){
-		//	summary:
-		//		adapts a single node function to be used in the filter-type actions
-		//	f: Function
-		//		a function to adapt
-		//	o: Object?
-		//		an optional context for f
-		return function(){
-			return this.filter(loopBody(f, arguments, o));
-		};
-	};
-
-	var adaptWithCondition = function(f, g, o){
-		//	summary:
-		//		adapts a single node function to be used in the map-type
-		//		actions, behaves like forEach() or map() depending on arguments
-		//	f: Function
-		//		a function to adapt
-		//	g: Function
-		//		a condition function, if true runs as map(), otherwise runs as forEach()
-		//	o: Object?
-		//		an optional context for f and g
-		return function(){
-			var a = arguments, body = loopBody(f, a, o);
-			if(g.call(o || d.global, a)){
-				return this.map(body);	// self
-			}
-			this.forEach(body);
-			return this;	// self
-		};
-	};
-
-	var magicGuard = function(a){
-		//	summary:
-		//		the guard function for dojo.attr() and dojo.style()
-		return a.length == 1 && (typeof a[0] == "string"); // inline'd type check
-	};
-
-	var orphan = function(node){
-		//	summary:
-		//		function to orphan nodes
-		var p = node.parentNode;
-		if(p){
-			p.removeChild(node);
-		}
-	};
-	// FIXME: should we move orphan() to dojo.html?
-
-	dojo.NodeList = function(){
-		//	summary:
-		//		dojo.NodeList is an of Array subclass 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
-		//		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
-		//		full power of Dojo available for DOM manipulation tasks in a
-		//		simple, chainable way.
-		//	example:
-		//		create a node list from a node
-		//		|	new dojo.NodeList(dojo.byId("foo"));
-		//	example:
-		//		get a NodeList from a CSS query and iterate on it
-		//		|	var l = dojo.query(".thinger");
-		//		|	l.forEach(function(node, index, nodeList){
-		//		|		console.log(index, node.innerHTML);
-		//		|	});
-		//	example:
-		//		use native and Dojo-provided array methods to manipulate a
-		//		NodeList without needing to use dojo.* functions explicitly:
-		//		|	var l = dojo.query(".thinger");
-		//		|	// since NodeLists are real arrays, they have a length
-		//		|	// property that is both readable and writable and
-		//		|	// push/pop/shift/unshift methods
-		//		|	console.log(l.length);
-		//		|	l.push(dojo.create("span"));
-		//		|
-		//		|	// dojo's normalized array methods work too:
-		//		|	console.log( l.indexOf(dojo.byId("foo")) );
-		//		|	// ...including the special "function as string" shorthand
-		//		|	console.log( l.every("item.nodeType == 1") );
-		//		|
-		//		|	// NodeLists can be [..] indexed, or you can use the at()
-		//		|	// function to get specific items wrapped in a new NodeList:
-		//		|	var node = l[3]; // the 4th element
-		//		|	var newList = l.at(1, 3); // the 2nd and 4th elements
-		//	example:
-		//		the style functions you expect are all there too:
-		//		|	// style() as a getter...
-		//		|	var borders = dojo.query(".thinger").style("border");
-		//		|	// ...and as a setter:
-		//		|	dojo.query(".thinger").style("border", "1px solid black");
-		//		|	// class manipulation
-		//		|	dojo.query("li:nth-child(even)").addClass("even");
-		//		|	// 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:
-		//		|	// remove all of the elements in the list from their
-		//		|	// parents (akin to "deleting" them from the document)
-		//		|	dojo.query(".thinger").orphan();
-		//		|	// place all elements in the list at the front of #foo
-		//		|	dojo.query(".thinger").place("foo", "first");
-		//	example:
-		//		Event handling couldn't be easier. `dojo.connect` is mapped in,
-		//		and shortcut handlers are provided for most DOM events:
-		//		|	// like dojo.connect(), but with implicit scope
-		//		|	dojo.query("li").connect("onclick", console, "log");
-		//		|
-		//		|	// many common event handlers are already available directly:
-		//		|	dojo.query("li").onclick(console, "log");
-		//		|	var toggleHovered = dojo.hitch(dojo, "toggleClass", "hovered");
-		//		|	dojo.query("p")
-		//		|		.onmouseenter(toggleHovered)
-		//		|		.onmouseleave(toggleHovered);
-		//	example:
-		//		chainability is a key advantage of NodeLists:
-		//		|	dojo.query(".thinger")
-		//		|		.onclick(function(e){ /* ... */ })
-		//		|		.at(1, 3, 8) // get a subset
-		//		|			.style("padding", "5px")
-		//		|			.forEach(console.log);
-
-		return tnl(Array.apply(null, arguments));
-	};
-
-	//Allow things that new up a NodeList to use a delegated or alternate NodeList implementation.
-	d._NodeListCtor = d.NodeList;
-
-	var nl = d.NodeList, nlp = nl.prototype;
-
-	// expose adapters and the wrapper as private functions
-
-	nl._wrap = nlp._wrap = tnl;
-	nl._adaptAsMap = adaptAsMap;
-	nl._adaptAsForEach = adaptAsForEach;
-	nl._adaptAsFilter  = adaptAsFilter;
-	nl._adaptWithCondition = adaptWithCondition;
-
-	// mass assignment
-
-	// add array redirectors
-	d.forEach(["slice", "splice"], function(name){
-		var f = ap[name];
-		//Use a copy of the this array via this.slice() to allow .end() to work right in the splice case.
-		// CANNOT apply ._stash()/end() to splice since it currently modifies
-		// the existing this array -- it would break backward compatibility if we copy the array before
-		// the splice so that we can use .end(). So only doing the stash option to this._wrap for slice.
-		nlp[name] = function(){ return this._wrap(f.apply(this, arguments), name == "slice" ? this : null); };
-	});
-	// concat should be here but some browsers with native NodeList have problems with it
-
-	// add array.js redirectors
-	d.forEach(["indexOf", "lastIndexOf", "every", "some"], function(name){
-		var f = d[name];
-		nlp[name] = function(){ return f.apply(d, [this].concat(aps.call(arguments, 0))); };
-	});
-
-	// add conditional methods
-	d.forEach(["attr", "style"], function(name){
-		nlp[name] = adaptWithCondition(d[name], magicGuard);
-	});
-
-	// add forEach actions
-	d.forEach(["connect", "addClass", "removeClass", "replaceClass", "toggleClass", "empty", "removeAttr"], function(name){
-		nlp[name] = adaptAsForEach(d[name]);
-	});
-
+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;
+
+	/*=====
 	dojo.extend(dojo.NodeList, {
-		_normalize: function(/*String||Element||Object||NodeList*/content, /*DOMNode?*/refNode){
-			// summary:
-			// 		normalizes data to an array of items to insert.
-			// 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),
-			// 		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.
-			// 		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).
-
-			//Wanted to just use a DocumentFragment, but for the array/NodeList
-			//case that meant  using cloneNode, but we may not want that.
-			//Cloning should only happen if the node operations span
-			//multiple refNodes. Also, need a real array, not a NodeList from the
-			//DOM since the node movements could change those NodeLists.
-
-			var parse = content.parse === true ? true : false;
-
-			//Do we have an object that needs to be run through a template?
-			if(typeof content.template == "string"){
-				var templateFunc = content.templateFunc || (dojo.string && dojo.string.substitute);
-				content = templateFunc ? templateFunc(content.template, content) : content;
-			}
-
-			var type = (typeof content);
-			if(type == "string" || type == "number"){
-				content = dojo._toDom(content, (refNode && refNode.ownerDocument));
-				if(content.nodeType == 11){
-					//DocumentFragment. It cannot handle cloneNode calls, so pull out the children.
-					content = dojo._toArray(content.childNodes);
-				}else{
-					content = [content];
-				}
-			}else if(!dojo.isArrayLike(content)){
-				content = [content];
-			}else if(!dojo.isArray(content)){
-				//To get to this point, content is array-like, but
-				//not an array, which likely means a DOM NodeList. Convert it now.
-				content = dojo._toArray(content);
-			}
-
-			//Pass around the parse info
-			if(parse){
-				content._runParse = true;
-			}
-			return content; //Array
-		},
-
-		_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
-			// 		clone event handlers if that is derivable from the node.
-			return node.cloneNode(true);
-		},
-
-		_place: function(/*Array*/ary, /*DOMNode*/refNode, /*String*/position, /*Boolean*/useClone){
-			// summary:
-			// 		private utility to handle placing an array of nodes relative to another node.
-			// description:
-			// 		Allows for cloning the nodes in the array, and for
-			// 		optionally parsing widgets, if ary._runParse is true.
-
-			//Avoid a disallowed operation if trying to do an innerHTML on a non-element node.
-			if(refNode.nodeType != 1 && position == "only"){
-				return;
-			}
-			var rNode = refNode, tempNode;
-
-			//Always cycle backwards in case the array is really a
-			//DOM NodeList and the DOM operations take it out of the live collection.
-			var length = ary.length;
-			for(var i = length - 1; i >= 0; i--){
-				var node = (useClone ? this._cloneNode(ary[i]) : ary[i]);
-
-				//If need widget parsing, use a temp node, instead of waiting after inserting into
-				//real DOM because we need to start widget parsing at one node up from current node,
-				//which could cause some already parsed widgets to be parsed again.
-				if(ary._runParse && dojo.parser && dojo.parser.parse){
-					if(!tempNode){
-						tempNode = rNode.ownerDocument.createElement("div");
-					}
-					tempNode.appendChild(node);
-					dojo.parser.parse(tempNode);
-					node = tempNode.firstChild;
-					while(tempNode.firstChild){
-						tempNode.removeChild(tempNode.firstChild);
-					}
-				}
-
-				if(i == length - 1){
-					dojo.place(node, rNode, position);
-				}else{
-					rNode.parentNode.insertBefore(node, rNode);
-				}
-				rNode = node;
-			}
-		},
-
-		_stash: function(parent){
-			// summary:
-			// 		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, {
-			//	|		third: function(){
-			//  |			var newNodeList = dojo.NodeList(this[2]);
-			//	|			return newNodeList._stash(this);
-			//	|		}
-			//	|	});
-			//	|	// then see how _stash applies a sub-list, to be .end()'ed out of
-			//	|	dojo.query(".foo")
-			//	|		.third()
-			//	|			.addClass("thirdFoo")
-			//	|		.end()
-			//	|		// access to the orig .foo list
-			//	|		.removeClass("foo")
-			//	|
-			//
-			this._parent = parent;
-			return this; //dojo.NodeList
-		},
-
-		end: function(){
-			// summary:
-			// 		Ends use of the current `dojo.NodeList` by returning the previous dojo.NodeList
-			// 		that generated the current dojo.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.
-			// example:
-			//	|	dojo.query("a")
-			//	|		.filter(".disabled")
-			//	|			// operate on the anchors that only have a disabled class
-			//	|			.style("color", "grey")
-			//	|		.end()
-			//	|		// jump back to the list of anchors
-			//	|		.style(...)
-			//
-			if(this._parent){
-				return this._parent;
-			}else{
-				//Just return empty list.
-				return new this._NodeListCtor();
-			}
-		},
-
-		// http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array#Methods
-
-		// FIXME: handle return values for #3244
-		//		http://trac.dojotoolkit.org/ticket/3244
-
-		// FIXME:
-		//		need to wrap or implement:
-		//			join (perhaps w/ innerHTML/outerHTML overload for toString() of items?)
-		//			reduce
-		//			reduceRight
-
-		/*=====
-		slice: function(begin, end){
-			// summary:
-			//		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]
-			// begin: Integer
-			//		Can be a positive or negative integer, with positive
-			//		integers noting the offset to begin at, and negative
-			//		integers denoting an offset from the end (i.e., to the left
-			//		of the end)
-			// end: Integer?
-			//		Optional parameter to describe what position relative to
-			//		the NodeList's zero index to end the slice at. Like begin,
-			//		can be positive or negative.
-			return this._wrap(a.slice.apply(this, arguments));
-		},
-
-		splice: function(index, howmany, item){
-			// summary:
-			//		Returns a new NodeList, manipulating this NodeList based on
-			//		the arguments passed, potentially splicing in new elements
-			//		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]
-			// 		For backwards compatibility, calling .end() on the spliced NodeList
-			// 		does not return the original NodeList -- splice alters the NodeList in place.
-			// index: Integer
-			//		begin can be a positive or negative integer, with positive
-			//		integers noting the offset to begin at, and negative
-			//		integers denoting an offset from the end (i.e., to the left
-			//		of the end)
-			// howmany: Integer?
-			//		Optional parameter to describe what position relative to
-			//		the NodeList's zero index to end the slice at. Like begin,
-			//		can be positive or negative.
-			// 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));
-		},
-
-		indexOf: function(value, fromIndex){
-			//	summary:
-			//		see dojo.indexOf(). The primary difference is that the acted-on
-			//		array is implicitly this NodeList
-			// value: Object:
-			//		The value to search for.
-			// 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]
-			//	returns:
-			//		Positive Integer or 0 for a match, -1 of not found.
-			return d.indexOf(this, value, fromIndex); // Integer
-		},
-
-		lastIndexOf: function(value, fromIndex){
-			// summary:
-			//		see dojo.lastIndexOf(). The primary difference is that the
-			//		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]
-			// value: Object
-			//		The value to search for.
-			// fromIndex: Integer?
-			//		The location to start searching from. Optional. Defaults to 0.
-			// returns:
-			//		Positive Integer or 0 for a match, -1 of not found.
-			return d.lastIndexOf(this, value, fromIndex); // Integer
-		},
-
-		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].
-			//		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
-			return d.every(this, callback, thisObject); // Boolean
-		},
-
-		some: function(callback, thisObject){
-			//	summary:
-			//		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
-			return d.some(this, callback, thisObject); // Boolean
-		},
-		=====*/
-
-		concat: function(item){
-			// summary:
-			//		Returns a new NodeList comprised of items in this NodeList
-			//		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]
-			// 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 :-(
-
-			// 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 = d.isArray(this) ? this : aps.call(this, 0),
-				m = d.map(arguments, function(a){
-					return a && !d.isArray(a) &&
-						(typeof NodeList != "undefined" && a.constructor === NodeList || a.constructor === this._NodeListCtor) ?
-							aps.call(a, 0) : a;
-				});
-			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(d.map(this, func, obj), this); // dojo.NodeList
-		},
-
-		forEach: function(callback, thisObj){
-			//	summary:
-			//		see `dojo.forEach()`. The primary difference is that the acted-on
-			//		array is implicitly this NodeList. If you want the option to break out
-			//		of the forEach loop, use every() or some() instead.
-			d.forEach(this, callback, thisObj);
-			// non-standard return to allow easier chaining
-			return this; // dojo.NodeList
-		},
-
-		/*=====
-		coords: function(){
-			//	summary:
-			//		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 d.map(this, d.coords); // Array
-		},
-
-		position: function(){
-			//	summary:
-			//		Returns border-box objects (x/y/w/h) of all elements in a node list
-			//		as an Array (*not* a NodeList). Acts like `dojo.position`, though
-			//		assumes the node passed is each node in this list.
-
-			return d.map(this, d.position); // Array
-		},
-
-		attr: function(property, value){
-			//	summary:
-			//		gets or sets the DOM attribute for every element in the
-			//		NodeList. See also `dojo.attr`
-			//	property: String
-			//		the attribute to get/set
-			//	value: String?
-			//		optional. The value to set the property to
-			//	returns:
-			//		if no value is passed, the result is an array of attribute values
-			//		If a value is passed, the return is this NodeList
-			//	example:
-			//		Make all nodes with a particular class focusable:
-			//	|	dojo.query(".focusable").attr("tabIndex", -1);
-			//	example:
-			//		Disable a group of buttons:
-			//	|	dojo.query("button.group").attr("disabled", true);
-			//	example:
-			//		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
-		},
-
-		style: function(property, value){
-			//	summary:
-			//		gets or sets the CSS property for every element in the NodeList
-			//	property: String
-			//		the CSS property to get/set, in JavaScript notation
-			//		("lineHieght" instead of "line-height")
-			//	value: String?
-			//		optional. The value to set the property to
-			//	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; // Array
-		},
-
-		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
-		},
-
-		removeClass: function(className){
-			//	summary:
-			//		removes the specified class from every node in the list
-			//	className: 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.
-			//	returns:
-			//		dojo.NodeList, this list
-			return; // dojo.NodeList
-		},
-
-		toggleClass: function(className, 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.
-			//	condition: Boolean?
-			//		If passed, true means to add the class, false means to remove.
-			//	className: String
-			//		the CSS class to add
-			return; // dojo.NodeList
-		},
-
 		connect: function(methodName, objOrFunc, funcName){
-			//	summary:
+			// summary:
 			//		attach event handlers to every item of the NodeList. Uses dojo.connect()
 			//		so event properties are normalized
-			//	methodName: String
+			// 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
+			// 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?
+			// funcName: String?
 			//		optional. A string naming the function in objOrFunc to bind to the
 			//		event. May also be a function reference.
-			//	example:
+			// example:
 			//		add an onclick handler to every button on the page
 			//		|	dojo.query("div:nth-child(odd)").connect("onclick", function(e){
 			//		|		console.log("clicked!");
@@ -687,287 +33,40 @@ define("dojo/_base/NodeList", ["dojo/lib/kernel", "dojo/_base/lang", "dojo/_base
 			//		attach foo.bar() to every odd div's onmouseover
 			//		|	dojo.query("div:nth-child(odd)").connect("onmouseover", foo, "bar");
 		},
-
-		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
-			// FIXME: should we be checking for and/or disposing of widgets below these nodes?
-		},
-		=====*/
-
-		// useful html methods
-		coords:	adaptAsMap(d.coords),
-		position: adaptAsMap(d.position),
-
-		// FIXME: connectPublisher()? connectRunOnce()?
-
-		/*
-		destroy: function(){
-			//	summary:
-			//		destroys every item in 	the list.
-			this.forEach(d.destroy);
-			// FIXME: should we be checking for and/or disposing of widgets below these nodes?
-		},
-		*/
-
-		place: function(/*String||Node*/ queryOrNode, /*String*/ position){
-			//	summary:
-			//		places elements of this node list relative to the first element matched
-			//		by queryOrNode. Returns the original NodeList. See: `dojo.place`
-			//	queryOrNode:
-			//		may be a string representing any valid CSS3 selector or a DOM node.
-			//		In the selector case, only the first matching element will be used
-			//		for relative positioning.
-			//	position:
-			//		can be one of:
-			//		|	"last" (default)
-			//		|	"first"
-			//		|	"before"
-			//		|	"after"
-			//		|	"only"
-			//		|	"replace"
-			// 		or an offset in the childNodes property
-			var item = d.query(queryOrNode)[0];
-			return this.forEach(function(node){ d.place(node, item, position); }); // dojo.NodeList
-		},
-
-		orphan: function(/*String?*/ filter){
-			//	summary:
-			//		removes elements in this list that match the filter
-			//		from their parents and returns them as a new NodeList.
-			//	filter:
-			//		CSS selector like ".foo" or "div > span"
-			//	returns:
-			//		`dojo.NodeList` containing the orphaned elements
-			return (filter ? d._filterQueryResult(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.
-			//	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"
-			// 		or an offset in the childNodes property
-			return d.query(queryOrListOrNode).place(this[0], position)._stash(this);	// dojo.NodeList
-		},
-
-		// FIXME: do we need this?
-		query: function(/*String*/ queryStr){
-			//	summary:
-			//		Returns a new list whose members match the passed query,
-			//		assuming elements of the current NodeList as the root for
-			//		each search.
-			//	example:
-			//		assume a DOM created by this markup:
-			//	|	<div id="foo">
-			//	|		<p>
-			//	|			bacon is tasty, <span>dontcha think?</span>
-			//	|		</p>
-			//	|	</div>
-			//	|	<div id="bar">
-			//	|		<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"));
-			//		it's possible to find all span elements under paragraphs
-			//		contained by these elements with this sub-query:
-			//	| 	var spans = l.query("p span");
-
-			// FIXME: probably slow
-			if(!queryStr){ return this; }
-			var ret = this.map(function(node){
-				// FIXME: why would we ever get undefined here?
-				return d.query(queryStr, node).filter(function(subNode){ return subNode !== undefined; });
-			});
-			return this._wrap(apc.apply([], ret), this);	// dojo.NodeList
-		},
-
-		filter: function(/*String|Function*/ filter){
-			//	summary:
-			// 		"masks" the built-in javascript filter() method (supported
-			// 		in Dojo via `dojo.filter`) to support passing a simple
-			// 		string filter in addition to supporting filtering function
-			// 		objects.
-			//	filter:
-			//		If a string, a CSS rule like ".thinger" or "div > span".
-			//	example:
-			//		"regular" JS filter syntax as exposed in dojo.filter:
-			//		|	dojo.query("*").filter(function(item){
-			//		|		// highlight every paragraph
-			//		|		return (item.nodeName == "p");
-			//		|	}).style("backgroundColor", "yellow");
-			// example:
-			//		the same filtering using a CSS selector
-			//		|	dojo.query("*").filter("p").styles("backgroundColor", "yellow");
-
-			var a = arguments, items = this, start = 0;
-			if(typeof filter == "string"){ // inline'd type check
-				items = d._filterQueryResult(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
-				}
-				// if we got a callback, run it over the filtered items
-				start = 1;
-			}
-			return this._wrap(d.filter(items, a[start], a[start + 1]), this);	// dojo.NodeList
-		},
-
-		/*
-		// FIXME: should this be "copyTo" and include parenting info?
-		clone: function(){
+		coords: function(){
 			// summary:
-			//		creates node clones of each element of this list
-			//		and returns a new list containing the clones
-		},
-		*/
-
-		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.
-			//	description:
-			//		a copy of the HTML content is added to each item in the
-			//		list, with an optional position argument. If no position
-			//		argument is provided, the content is appended to the end of
-			//		each item.
-			//	content:
-			//		DOM node, HTML in string format, a NodeList or an Object. If a DOM node or
-			// 		NodeList, the content will be cloned if the current NodeList has more than one
-			// 		element. Only the DOM nodes are cloned, no event handlers. If it is an Object,
-			// 		it should be an object with at "template" String property that has the HTML string
-			// 		to insert. If dojo.string has already been dojo.required, then dojo.string.substitute
-			// 		will be used on the "template" to generate the final HTML string. Other allowed
-			// 		properties on the object are: "parse" if the HTML
-			// 		string should be parsed for widgets (dojo.require("dojo.parser") to get that
-			// 		option to work), and "templateFunc" if a template function besides dojo.string.substitute
-			// 		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)
-			// 		or an offset in the childNodes property
-			//	example:
-			//		appends content to the end if the position is omitted
-			//	|	dojo.query("h3 > p").addContent("hey there!");
-			//	example:
-			//		add something to the front of each element that has a
-			//		"thinger" property:
-			//	|	dojo.query("[thinger]").addContent("...", "first");
-			//	example:
-			//		adds a header before each element of the list
-			//	|	dojo.query(".note").addContent("<h4>NOTE:</h4>", "before");
-			//	example:
-			//		add a clone of a DOM node to the end of every element in
-			//		the list, removing it from its existing parent.
-			//	|	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"
-			//  	});
-			//  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"
-			//  	});
-			content = this._normalize(content, this[0]);
-			for(var i = 0, node; (node = this[i]); i++){
-				this._place(content, node, position, i > 0);
-			}
-			return 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
-			//		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});
-			var c = d.isFunction(declaredClass) ? declaredClass : d.getObject(declaredClass);
-			properties = properties || {};
-			return this.forEach(function(node){
-				new c(properties, node);
-			});	// dojo.NodeList
-		},
+			//		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.
 
-		at: function(/*===== index =====*/){
-			//	summary:
-			//		Returns a new NodeList comprised of items in this NodeList
-			//		at the given index or indices.
-			//
-			//	index: Integer...
-			//		One or more 0-based indices of items in the current
-			//		NodeList. A negative index will start at the end of the
-			//		list and go backwards.
-			//
-			//	example:
-			//	Shorten the list to the first, second, and third elements
-			//	|	dojo.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);
-			//
-			//	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){
-			//	|		console.log(n); // all anchors on the page.
-			//	|	})
-			//
-			//	returns:
-			//		dojo.NodeList
-			var t = new this._NodeListCtor();
-			d.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 dojo.map(this, dojo.coords); // Array
 		}
+	 });
+
+	 var NodeList = dojo.NodeList;
+	=====*/
+	var nlp = NodeList.prototype;
 
+	// don't bind early to dojo.connect since we no longer explicitly depend on it
+	nlp.connect = NodeList._adaptAsForEach(function(){
+		return dojo.connect.apply(this, arguments);
 	});
+	nlp.coords = NodeList._adaptAsMap(dojo.coords);
 
-	nl.events = [
+	NodeList.events = [
 		// summary:
 		//		list of all DOM events used in NodeList
 		"blur", "focus", "change", "click", "error", "keydown", "keypress",
 		"keyup", "load", "mousedown", "mouseenter", "mouseleave", "mousemove",
 		"mouseout", "mouseover", "mouseup", "submit"
 	];
-	
+
 	// FIXME: pseudo-doc the above automatically generated on-event functions
 
 	// syntactic sugar for DOM events
-	d.forEach(nl.events, function(evt){
+	array.forEach(NodeList.events, function(evt){
 			var _oe = "on" + evt;
 			nlp[_oe] = function(a, b){
 				return this.connect(_oe, a, b);
@@ -996,9 +95,6 @@ define("dojo/_base/NodeList", ["dojo/lib/kernel", "dojo/_base/lang", "dojo/_base
 		}
 	);
 
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-})();
-//>>excludeEnd("webkitMobile");
-
-return dojo.NodeList;
+	dojo.NodeList = NodeList;
+	return dojo.NodeList;
 });
diff --git a/dojo/_base/_loader/bootstrap.js b/dojo/_base/_loader/bootstrap.js
deleted file mode 100644
index 5789def..0000000
--- a/dojo/_base/_loader/bootstrap.js
+++ /dev/null
@@ -1,568 +0,0 @@
-//>>includeStart("amdLoader", kwArgs.asynchLoader);
-(function(){
-
-function bootstrapDojo(dojo, dijit, dojox){
-
-//>>includeEnd("amdLoader");
-/*=====
-// note:
-//		'djConfig' 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.
-
-djConfig = {
-	// summary:
-	//		Application code can set the global 'djConfig' prior to loading
-	//		the library to override 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
-	//		on your platform, setting `isDebug` to `true` will force Dojo to
-	//		pull in (and display) the version of Firebug Lite which is
-	//		integrated into the Dojo distribution, thereby always providing a
-	//		debugging/logging console when `isDebug` is enabled. Note that
-	//		Firebug's `console.*` methods are ALWAYS defined by Dojo. If
-	//		`isDebug` is false and you are on a platform without Firebug, these
-	//		methods will be defined as no-ops.
-	isDebug: false,
-	// debugAtAllCosts: Boolean
-	//		Defaults to `false`. If set to `true`, this triggers an alternate
-	//		mode of the package system in which dependencies are detected and
-	//		only then are resources evaluated in dependency order via
-	//		`<script>` tag inclusion. This may double-request resources and
-	//		cause problems with scripts which expect `dojo.require()` to
-	//		preform synchronously. `debugAtAllCosts` can be an invaluable
-	//		debugging aid, but when using it, ensure that all code which
-	//		depends on Dojo modules is wrapped in `dojo.addOnLoad()` handlers.
-	//		Due to the somewhat unpredictable side-effects of using
-	//		`debugAtAllCosts`, it is strongly recommended that you enable this
-	//		flag as a last resort. `debugAtAllCosts` has no effect when loading
-	//		resources across domains. For usage information, see the
-	//		[Dojo Book](http://dojotoolkit.org/book/book-dojo/part-4-meta-dojo-making-your-dojo-code-run-faster-and-better/debugging-facilities/deb)
-	debugAtAllCosts: 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).
-	//		Must be specified entirely in lowercase, e.g. `en-us` and `zh-cn`.
-	//		See the documentation for `dojo.i18n` and `dojo.requireLocalization`
-	//		for details on loading localized resources. If no locale is specified,
-	//		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
-	//		was loaded. You may need to manually configure `baseUrl` in cases
-	//		where you have renamed `dojo.js` or in which `<base>` tags confuse
-	//		some browsers (e.g. IE 6). The variable `dojo.baseUrl` is assigned
-	//		either the value of `djConfig.baseUrl` if one is provided or the
-	//		auto-detected root if not. Other modules are located relative to
-	//		this path. The path should end in a slash.
-	baseUrl: undefined,
-	// modulePaths: 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
-	//		`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
-	//		the page loads and djConfig.afterOnLoad is true. Supports the same
-	//		arguments as dojo.addOnLoad. 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
-	//		An array of module names to be loaded immediately after dojo.js has been included
-	//		in a page.
-	require: [],
-	// defaultDuration: Array
-	//		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
-	//		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?
-	//		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
-	// 		of topics that are published.
-	ioPublish: false,
-	//  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
-}
-=====*/
-
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-(function(){
-//>>excludeEnd("webkitMobile");
-	// firebug stubs
-
-	if(typeof this["loadFirebugConsole"] == "function"){
-		// for Firebug 1.2
-		this["loadFirebugConsole"]();
-	}else{
-		this.console = this.console || {};
-
-		//	Be careful to leave 'log' always at the end
-		var cn = [
-			"assert", "count", "debug", "dir", "dirxml", "error", "group",
-			"groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
-			"trace", "warn", "log"
-		];
-		var i = 0, tn;
-		while((tn=cn[i++])){
-			if(!console[tn]){
-				(function(){
-					var tcn = tn+"";
-					console[tcn] = ('log' in console) ? function(){
-						var a = Array.apply({}, arguments);
-						a.unshift(tcn+":");
-						console["log"](a.join(" "));
-					} : function(){}
-					console[tcn]._fake = true;
-				})();
-			}
-		}
-	}
-
-	//TODOC:  HOW TO DOC THIS?
-	// dojo is the root variable of (almost all) our public symbols -- make sure it is defined.
-	if(typeof dojo == "undefined"){
-		dojo = {
-			_scopeName: "dojo",
-			_scopePrefix: "",
-			_scopePrefixArgs: "",
-			_scopeSuffix: "",
-			_scopeMap: {},
-			_scopeMapRev: {}
-		};
-	}
-
-	var d = dojo;
-
-	//Need placeholders for dijit and dojox for scoping code.
-	if(typeof dijit == "undefined"){
-		dijit = {_scopeName: "dijit"};
-	}
-	if(typeof dojox == "undefined"){
-		dojox = {_scopeName: "dojox"};
-	}
-
-	if(!d._scopeArgs){
-		d._scopeArgs = [dojo, dijit, dojox];
-	}
-
-/*=====
-dojo.global = {
-	//	summary:
-	//		Alias for the global scope
-	//		(e.g. the window object in a browser).
-	//	description:
-	//		Refer to 'dojo.global' rather than referring to window to ensure your
-	//		code runs correctly in contexts other than web browsers (e.g. Rhino on a server).
-}
-=====*/
-	d.global = this;
-
-	d.config =/*===== djConfig = =====*/{
-		isDebug: false,
-		debugAtAllCosts: false
-	};
-
-	// FIXME: 2.0, drop djConfig support. Use dojoConfig exclusively for global config.
-	var cfg = typeof djConfig != "undefined" ? djConfig :
-		typeof dojoConfig != "undefined" ? dojoConfig : null;
-		
-	if(cfg){
-		for(var c in cfg){
-			d.config[c] = cfg[c];
-		}
-	}
-
-/*=====
-	// Override locale setting, if specified
-	dojo.locale = {
-		// summary: the locale as defined by Dojo (read-only)
-	};
-=====*/
-	dojo.locale = d.config.locale;
-
-	var rev = "$Rev: 24595 $".match(/\d+/);
-
-/*=====
-	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;
-	}
-=====*/
-	dojo.version = {
-		major: 1, minor: 6, patch: 1, flag: "",
-		revision: rev ? +rev[0] : NaN,
-		toString: function(){
-			with(d.version){
-				return major + "." + minor + "." + patch + flag + " (" + revision + ")";	// String
-			}
-		}
-	}
-
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	// Register with the OpenAjax hub
-	if(typeof OpenAjax != "undefined"){
-		OpenAjax.hub.registerLibrary(dojo._scopeName, "http://dojotoolkit.org", d.version.toString());
-	}
-	//>>excludeEnd("webkitMobile");
-
-	var extraNames, extraLen, empty = {};
-	for(var i in {toString: 1}){ extraNames = []; break; }
-	dojo._extraNames = extraNames = extraNames || ["hasOwnProperty", "valueOf", "isPrototypeOf",
-		"propertyIsEnumerable", "toLocaleString", "toString", "constructor"];
-	extraLen = extraNames.length;
-
-	dojo._mixin = function(/*Object*/ target, /*Object*/ source){
-		// summary:
-		//		Adds all properties and methods of source to target. This addition
-		//		is "prototype extension safe", so that instances of objects
-		//		will not pass along prototype defaults.
-		var name, s, i;
-		for(name in source){
-			// the "tobj" condition avoid copying properties in "source"
-			// inherited from Object.prototype.  For example, if target has a custom
-			// toString() method, don't overwrite it with the toString() method
-			// that source inherited from Object.prototype
-			s = source[name];
-			if(!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))){
-				target[name] = s;
-			}
-		}
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		// IE doesn't recognize some custom functions in for..in
-		if(extraLen && source){
-			for(i = 0; i < extraLen; ++i){
-				name = extraNames[i];
-				s = source[name];
-				if(!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))){
-					target[name] = s;
-				}
-			}
-		}
-		//>>excludeEnd("webkitMobile");
-		return target; // Object
-	}
-
-	dojo.mixin = function(/*Object*/obj, /*Object...*/props){
-		// summary:
-		//		Adds all properties and methods of props to obj and returns the
-		//		(now modified) obj.
-		//	description:
-		//		`dojo.mixin` can mix multiple source objects into a
-		//		destination object which is then returned. Unlike regular
-		//		`for...in` iteration, `dojo.mixin` is also smart about avoiding
-		//		extensions which other toolkits may unwisely add to the root
-		//		object prototype
-		//	obj:
-		//		The object to mix properties into. Also the return value.
-		//	props:
-		//		One or more objects whose values are successively copied into
-		//		obj. If more than one of these objects contain the same value,
-		//		the one specified last in the function call will "win".
-		//	example:
-		//		make a shallow copy of an object
-		//	|	var copy = dojo.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 `dojo.mixin` on the `this` object:
-		//	|	dojo.declare("acme.Base", null, {
-		//	|		constructor: function(properties){
-		//	|			// property configuration:
-		//	|			dojo.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 = dojo.mixin(
-		//	|		{
-		//	|			name: "Frylock",
-		//	|			braces: true
-		//	|		},
-		//	|		{
-		//	|			name: "Carl Brutanananadilewski"
-		//	|		}
-		//	|	);
-		//	|
-		//	|	// will print "Carl Brutanananadilewski"
-		//	|	console.log(flattened.name);
-		//	|	// will print "true"
-		//	|	console.log(flattened.braces);
-		if(!obj){ obj = {}; }
-		for(var i=1, l=arguments.length; i<l; i++){
-			d._mixin(obj, arguments[i]);
-		}
-		return obj; // Object
-	}
-
-	dojo._getProp = function(/*Array*/parts, /*Boolean*/create, /*Object*/context){
-		var obj=context || d.global;
-		for(var i=0, p; obj && (p=parts[i]); i++){
-			if(i == 0 && d._scopeMap[p]){
-				p = d._scopeMap[p];
-			}
-			obj = (p in obj ? obj[p] : (create ? obj[p]={} : undefined));
-		}
-		return obj; // mixed
-	}
-
-	dojo.setObject = function(/*String*/name, /*Object*/value, /*Object?*/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:
-		//		Path to a property, in the form "A.B.C".
-		//	context:
-		//		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:
-		//	|	dojo.setObject("foo.bar.baz", value);
-		//	example:
-		//		without `dojo.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";
-		//		wheras with `dojo.setObject`, we can shorten that to:
-		//	|	dojo.setObject("parent.child.prop", "some value", obj);
-		var parts=name.split("."), p=parts.pop(), obj=d._getProp(parts, true, context);
-		return obj && p ? (obj[p]=value) : undefined; // Object
-	}
-
-	dojo.getObject = function(/*String*/name, /*Boolean?*/create, /*Object?*/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:
-		//		Path to an property, in the form "A.B.C".
-		//	create:
-		//		Optional. Defaults to `false`. If `true`, Objects will be
-		//		created at any point along the 'path' that is undefined.
-		//	context:
-		//		Optional. Object to use as root of path. Defaults to
-		//		'dojo.global'. Null may be passed.
-		return d._getProp(name.split("."), create, context); // Object
-	}
-
-	dojo.exists = function(/*String*/name, /*Object?*/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:
-		//		Path to an object, in the form "A.B.C".
-		//	obj:
-		//		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
-		//	|	dojo.exists("foo.bar"); // true
-		//	|	dojo.exists("foo.bar.baz"); // false
-		//	|
-		//	|	// search from a particular scope
-		//	|	dojo.exists("bar", foo); // true
-		//	|	dojo.exists("bar.baz", foo); // false
-		return d.getObject(name, false, obj) !== undefined; // Boolean
-	}
-
-	dojo["eval"] = function(/*String*/ scriptFragment){
-		//	summary:
-		//		A legacy method created for use exclusively by internal Dojo methods. Do not use
-		//		this method directly, the behavior of this eval will differ from the normal
-		//		browser eval.
-		//	description:
-		//		Placed in a separate function to minimize size of trapped
-		//		exceptions. Calling eval() directly from some other scope may
-		//		complicate tracebacks on some platforms.
-		//	returns:
-		//		The result of the evaluation. Often `undefined`
-		return d.global.eval ? d.global.eval(scriptFragment) : eval(scriptFragment); 	// Object
-	}
-
-	/*=====
-		dojo.deprecated = function(behaviour, extra, removal){
-			//	summary:
-			//		Log a debug message to indicate that a behavior has been
-			//		deprecated.
-			//	behaviour: String
-			//		The API or behavior being deprecated. Usually in the form
-			//		of "myApp.someFunction()".
-			//	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?
-			//		Text to indicate when in the future the behavior will be
-			//		removed. Usually a version number.
-			//	example:
-			//	|	dojo.deprecated("myApp.getTemp()", "use myApp.getLocaleTemp() instead", "1.0");
-		}
-
-		dojo.experimental = function(moduleName, extra){
-			//	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
-			//	 	The name of a module, or the name of a module file or a specific
-			//	 	function
-			//	extra: String?
-			//	 	some additional message for the user
-			//	example:
-			//	|	dojo.experimental("dojo.data.Result");
-			//	example:
-			//	|	dojo.experimental("dojo.weather.toKelvin()", "PENDING approval from NOAA");
-		}
-	=====*/
-
-	//Real functions declared in dojo._firebug.firebug.
-	d.deprecated = d.experimental = function(){};
-
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-})();
-//>>excludeEnd("webkitMobile");
-// vim:ai:ts=4:noet
-//>>includeStart("amdLoader", kwArgs.asynchLoader);
-
-return {dojo:dojo, dijit:dijit, dojox:dojox};
-}
-
-// This resource ("bootstrap") is responsible for creating and starting to populate the
-// dojo, dijit, and dojox objects. With the introduction of AMD loading, there are
-// several ways bootstrap could be evaluated:
-//
-// 1. Consequent to dojo.js script-injecting it. In this case it is expected to be
-//    evaluated immediately and dojo, dijit, and dojox are expected to be located
-//    in the global namespace. Note that if bootstrap is injected by dojo.js, then
-//    an AMD loader is *not* being used.
-//
-// 2. Consequent to an AMD loader script-injecting it. In this case, it is expected
-//    to delay evaluation, and instead publish a factory function to be executed under
-//    the control of the AMD loader. IAW AMD loader design, the global space should
-//    not be polluted; therefore dojo, dijit, and dojox are not be published into
-//    the global space.
-//
-// 3. Consequent to a built version of dojo (sync or xdomain loader).
-//
-// For [1], a bootstrap version of define is provided below. the v1.6 sync loader
-// will replace this with a better AMD simulation. The bootstrap version ensures bootstrap
-// is executed immediately--just as with all dojo versions prior to v1.6.
-//
-// For [2], a factory function is provided to the loader that executes the bootstrap
-// without polluting the global namespace. The factory returns the dojo object, and the
-// dijit and dojox objects are stuffed into the dojo object (at _dijit and _dojox) so
-// that dojo, dijit, and dojox bootstraps used with AMD can retrieve and control these
-// objects.
-//
-// For [3], the build util with v1.6 strips *all* AMD artifacts from this resource and reverts it
-// to look like v1.5. This ensures the built version, with either the sync or xdomain loader, work
-// *exactly* as in v1.5. While it may be possible to do more, any solution that does not
-// include significant work on the build util is likely to introduce edge cases that fail. Therefore
-// this work is delayed for 1.7 when a AMD-capable built util will be provided.
-
-if(!this.define){
-	// bootstrapping dojo with sync loader; dojo, dijit, and dojox go into the global space
-	var result = bootstrapDojo();
-	dojo = result.dojo;
-	dijit = result.dijit;
-	dojox = result.dojox;
-}else{
-	// bootstrapping dojo with an AMD loader
-	define([], function(){
-		var result= bootstrapDojo();
-		result.dojo._dijit= result.dijit;
-		result.dojo._dojox= result.dojox;
-		return result.dojo;
-	});
-}
-
-})();
-//>>includeEnd("amdLoader");
diff --git a/dojo/_base/_loader/hostenv_browser.js b/dojo/_base/_loader/hostenv_browser.js
deleted file mode 100644
index d092a92..0000000
--- a/dojo/_base/_loader/hostenv_browser.js
+++ /dev/null
@@ -1,505 +0,0 @@
-//>>includeStart("amdLoader", kwArgs.asynchLoader);
-define(["dojo/lib/backCompat"], function(dojo){
-// Note: if this resource is being loaded *without* an AMD loader, then
-// it is loaded by dojo.js which injects it into the doc with a script element. The simulated
-// AMD define function in _loader.js will cause the factory to be executed.
-//
-// The build util with v1.6 strips all AMD artifacts from this resource and reverts it
-// to look like v1.5. This ensures the built version, with either the sync or xdomain loader, work
-// *exactly* as in v1.5.
-
-//>>includeEnd("amdLoader");
-/*=====
-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 = {
-	// isBrowser: Boolean
-	//		True if the client is a web-browser
-	isBrowser: true,
-	//	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
-	//		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
-	//		Version as a Number if client is a KHTML browser. undefined otherwise. Corresponds to major
-	//		detected version.
-	isKhtml: 0,
-	//	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
-	//		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
-	//		Version as a Number if client is Opera. undefined otherwise. Corresponds to
-	//		major detected version.
-	isOpera: 0,
-	//	isSafari: Number | undefined
-	//		Version as a Number if client is Safari or iPhone. undefined otherwise.
-	isSafari: 0,
-	//	isChrome: Number | undefined
-	//		Version as a Number if client is Chrome browser. undefined otherwise.
-	isChrome: 0
-	//	isMac: Boolean
-	//		True if the client runs on Mac
-}
-=====*/
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-if(typeof window != 'undefined'){
-//>>excludeEnd("webkitMobile");
-	dojo.isBrowser = true;
-	dojo._name = "browser";
-
-
-	// attempt to figure out the path to dojo if it isn't set in the config
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	(function(){
-		var d = dojo;
-//>>excludeEnd("webkitMobile");
-
-		// this is a scope protection closure. We set browser versions and grab
-		// the URL we were loaded from here.
-
-		// grab the node we were loaded from
-		if(document && document.getElementsByTagName){
-			var scripts = document.getElementsByTagName("script");
-			var rePkg = /dojo(\.xd)?\.js(\W|$)/i;
-			for(var i = 0; i < scripts.length; i++){
-				var src = scripts[i].getAttribute("src");
-				if(!src){ continue; }
-				var m = src.match(rePkg);
-				if(m){
-					// find out where we came from
-					if(!d.config.baseUrl){
-						d.config.baseUrl = src.substring(0, m.index);
-					}
-					// and find out if we need to modify our behavior
-					var cfg = (scripts[i].getAttribute("djConfig") || scripts[i].getAttribute("data-dojo-config"));
-					if(cfg){
-						var cfgo = eval("({ "+cfg+" })");
-						for(var x in cfgo){
-							dojo.config[x] = cfgo[x];
-						}
-					}
-					break; // "first Dojo wins"
-				}
-			}
-		}
-		d.baseUrl = d.config.baseUrl;
-
-		// fill in the rendering support information in dojo.render.*
-		var n = navigator;
-		var dua = n.userAgent,
-			dav = n.appVersion,
-			tv = parseFloat(dav);
-
-		if(dua.indexOf("Opera") >= 0){ d.isOpera = tv; }
-		if(dua.indexOf("AdobeAIR") >= 0){ d.isAIR = 1; }
-		d.isKhtml = (dav.indexOf("Konqueror") >= 0) ? tv : 0;
-		d.isWebKit = parseFloat(dua.split("WebKit/")[1]) || undefined;
-		d.isChrome = parseFloat(dua.split("Chrome/")[1]) || undefined;
-		d.isMac = dav.indexOf("Macintosh") >= 0;
-
-		// 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 && !dojo.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".
-			d.isSafari = parseFloat(dav.split("Version/")[1]);
-			if(!d.isSafari || parseFloat(dav.substr(index + 7)) <= 419.3){
-				d.isSafari = 2;
-			}
-		}
-
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		if(dua.indexOf("Gecko") >= 0 && !d.isKhtml && !d.isWebKit){ d.isMozilla = d.isMoz = tv; }
-		if(d.isMoz){
-			//We really need to get away from this. Consider a sane isGecko approach for the future.
-			d.isFF = parseFloat(dua.split("Firefox/")[1] || dua.split("Minefield/")[1]) || undefined;
-		}
-		if(document.all && !d.isOpera){
-			d.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(d.isIE) != mode){
-				d.isIE = mode;
-			}
-		}
-
-		//Workaround to get local file loads of dojo to work on IE 7
-		//by forcing to not use native xhr.
-		if(dojo.isIE && window.location.protocol === "file:"){
-			dojo.config.ieForceActiveXXhr=true;
-		}
-		//>>excludeEnd("webkitMobile");
-
-		d.isQuirks = document.compatMode == "BackCompat";
-
-		// TODO: is the HTML LANG attribute relevant?
-		d.locale = dojo.config.locale || (d.isIE ? n.userLanguage : n.language).toLowerCase();
-
-		// These are in order of decreasing likelihood; this will change in time.
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		d._XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'];
-		//>>excludeEnd("webkitMobile");
-
-		d._xhrObj = function(){
-			// summary:
-			//		does the work of portably generating a new XMLHTTPRequest object.
-			var http, last_e;
-			//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-			if(!dojo.isIE || !dojo.config.ieForceActiveXXhr){
-			//>>excludeEnd("webkitMobile");
-				try{ http = new XMLHttpRequest(); }catch(e){}
-			//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-			}
-			if(!http){
-				for(var i=0; i<3; ++i){
-					var progid = d._XMLHTTP_PROGIDS[i];
-					try{
-						http = new ActiveXObject(progid);
-					}catch(e){
-						last_e = e;
-					}
-
-					if(http){
-						d._XMLHTTP_PROGIDS = [progid];  // so faster next time
-						break;
-					}
-				}
-			}
-			//>>excludeEnd("webkitMobile");
-
-			if(!http){
-				throw new Error("XMLHTTP not available: "+last_e);
-			}
-
-			return http; // XMLHTTPRequest instance
-		}
-
-		d._isDocumentOk = function(http){
-			var stat = http.status || 0,
-				lp = location.protocol;
-			return (stat >= 200 && stat < 300) || 	// Boolean
-				stat == 304 ||			// allow any 2XX response code
-				stat == 1223 ||			// get it out of the cache
-								// Internet Explorer mangled the status code
-				// Internet Explorer mangled the status code OR we're Titanium/browser chrome/chrome extension requesting a local file
-				(!stat && (lp == "file:" || lp == "chrome:" || lp == "chrome-extension:" || lp == "app:"));
-		}
-
-		//See if base tag is in use.
-		//This is to fix http://trac.dojotoolkit.org/ticket/3973,
-		//but really, we need to find out how to get rid of the dojo._Url reference
-		//below and still have DOH work with the dojo.i18n test following some other
-		//test that uses the test frame to load a document (trac #2757).
-		//Opera still has problems, but perhaps a larger issue of base tag support
-		//with XHR requests (hasBase is true, but the request is still made to document
-		//path, not base path).
-		var owloc = window.location+"";
-		var base = document.getElementsByTagName("base");
-		var hasBase = (base && base.length > 0);
-
-		d._getText = function(/*URI*/ uri, /*Boolean*/ fail_ok){
-			// 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
-			//		failure and failure is okay (an exception otherwise)
-
-			// NOTE: must be declared before scope switches ie. this._xhrObj()
-			var http = d._xhrObj();
-
-			if(!hasBase && dojo._Url){
-				uri = (new dojo._Url(owloc, uri)).toString();
-			}
-
-			if(d.config.cacheBust){
-				//Make sure we have a string before string methods are used on uri
-				uri += "";
-				uri += (uri.indexOf("?") == -1 ? "?" : "&") + String(d.config.cacheBust).replace(/\W+/g,"");
-			}
-
-			http.open('GET', uri, false);
-			try{
-				http.send(null);
-				if(!d._isDocumentOk(http)){
-					var err = Error("Unable to load "+uri+" status:"+ http.status);
-					err.status = http.status;
-					err.responseText = http.responseText;
-					throw err;
-				}
-			}catch(e){
-				if(fail_ok){ return null; } // null
-				// rethrow the exception
-				throw e;
-			}
-			return http.responseText; // String
-		}
-		
-
-		var _w = window;
-		var _handleNodeEvent = function(/*String*/evtName, /*Function*/fp){
-			// summary:
-			//		non-destructively adds the specified function to the node's
-			//		evtName handler.
-			// evtName: should be in the form "onclick" for "onclick" handlers.
-			// Make sure you pass in the "on" part.
-			var _a = _w.attachEvent || _w.addEventListener;
-			evtName = _w.attachEvent ? evtName : evtName.substring(2);
-			_a(evtName, function(){
-				fp.apply(_w, arguments);
-			}, false);
-		};
-
-
-		d._windowUnloaders = [];
-		
-		d.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 mll = d._windowUnloaders;
-			while(mll.length){
-				(mll.pop())();
-			}
-			d = null;
-		};
-
-		var _onWindowUnloadAttached = 0;
-		d.addOnWindowUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
-			// summary:
-			//		registers a function to be triggered when window.onunload
-			//		fires.
-			//	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
-			//		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
-			//		the page's "onbeforeunload" event.
-			// example:
-			//	|	dojo.addOnWindowUnload(functionPointer)
-			//	|	dojo.addOnWindowUnload(object, "functionName");
-			//	|	dojo.addOnWindowUnload(object, function(){ /* ... */});
-
-			d._onto(d._windowUnloaders, obj, functionName);
-			if(!_onWindowUnloadAttached){
-				_onWindowUnloadAttached = 1;
-				_handleNodeEvent("onunload", d.windowUnloaded);
-			}
-		};
-
-		var _onUnloadAttached = 0;
-		d.addOnUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
-			// summary:
-			//		registers a function to be triggered when the page unloads.
-			//	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
-			//		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
-			//		the link is a javascript: link. In these cases, the
-			//		onbeforeunload event fires, but the document is not
-			//		actually destroyed. So be careful about doing destructive
-			//		operations in a dojo.addOnUnload callback.
-			//
-			//		Further note that calling dojo.addOnUnload will prevent
-			//		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(){ /* ... */});
-
-			d._onto(d._unloaders, obj, functionName);
-			if(!_onUnloadAttached){
-				_onUnloadAttached = 1;
-				_handleNodeEvent("onbeforeunload", dojo.unloaded);
-			}
-		};
-
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	})();
-//>>excludeEnd("webkitMobile");
-
-	//START DOMContentLoaded
-	dojo._initFired = false;
-	dojo._loadInit = function(e){
-		if(dojo._scrollIntervalId){
-			clearInterval(dojo._scrollIntervalId);
-			dojo._scrollIntervalId = 0;
-		}
-
-		if(!dojo._initFired){
-			dojo._initFired = true;
-
-			//Help out IE to avoid memory leak.
-			if(!dojo.config.afterOnLoad && window.detachEvent){
-				window.detachEvent("onload", dojo._loadInit);
-			}
-
-			if(dojo._inFlightCount == 0){
-				dojo._modulesLoaded();
-			}
-		}
-	}
-
-	if(!dojo.config.afterOnLoad){
-		if(document.addEventListener){
-			//Standards. Hooray! Assumption here that if standards based,
-			//it knows about DOMContentLoaded. It is OK if it does not, the fall through
-			//to window onload should be good enough.
-			document.addEventListener("DOMContentLoaded", dojo._loadInit, false);
-			window.addEventListener("load", dojo._loadInit, false);
-		}else if(window.attachEvent){
-			window.attachEvent("onload", dojo._loadInit);
-
-			//DOMContentLoaded approximation. Diego Perini found this MSDN article
-			//that indicates doScroll is available after DOM ready, so do a setTimeout
-			//to check when it is available.
-			//http://msdn.microsoft.com/en-us/library/ms531426.aspx
-			if(!dojo.config.skipIeDomLoaded && self === self.top){
-				dojo._scrollIntervalId = setInterval(function (){
-					try{
-						//When dojo is loaded into an iframe in an IE HTML Application
-						//(HTA), such as in a selenium test, javascript in the iframe
-						//can't see anything outside of it, so self===self.top is true,
-						//but the iframe is not the top window and doScroll will be
-						//available before document.body is set. Test document.body
-						//before trying the doScroll trick
-						if(document.body){
-							document.documentElement.doScroll("left");
-							dojo._loadInit();
-						}
-					}catch (e){}
-				}, 30);
-			}
-		}
-	}
-
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	if(dojo.isIE){
-		try{
-			(function(){
-				document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
-				var vmlElems = ["*", "group", "roundrect", "oval", "shape", "rect", "imagedata", "path", "textpath", "text"],
-					i = 0, l = 1, s = document.createStyleSheet();
-				if(dojo.isIE >= 8){
-					i = 1;
-					l = vmlElems.length;
-				}
-				for(; i < l; ++i){
-					s.addRule("v\\:" + vmlElems[i], "behavior:url(#default#VML); display:inline-block");
-				}
-			})();
-		}catch(e){}
-	}
-	//>>excludeEnd("webkitMobile");
-	//END DOMContentLoaded
-
-
-	/*
-	OpenAjax.subscribe("OpenAjax", "onload", function(){
-		if(dojo._inFlightCount == 0){
-			dojo._modulesLoaded();
-		}
-	});
-
-	OpenAjax.subscribe("OpenAjax", "onunload", function(){
-		dojo.unloaded();
-	});
-	*/
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-} //if (typeof window != 'undefined')
-
-//Register any module paths set up in djConfig. Need to do this
-//in the hostenvs since hostenv_browser can read djConfig from a
-//script tag's attribute.
-(function(){
-//>>excludeEnd("webkitMobile");
-	var mp = dojo.config["modulePaths"];
-	if(mp){
-		for(var param in mp){
-			dojo.registerModulePath(param, mp[param]);
-		}
-	}
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-})();
-//>>excludeEnd("webkitMobile");
-
-//Load debug code if necessary.
-if(dojo.config.isDebug){
-	dojo.require("dojo._firebug.firebug");
-}
-
-if(dojo.config.debugAtAllCosts){
-	// this breaks the new AMD based module loader. The XDomain won't be necessary
-	// anyway if you switch to the asynchronous loader
-	//dojo.config.useXDomain = true;
-	//dojo.require("dojo._base._loader.loader_xd");
-	dojo.require("dojo._base._loader.loader_debug");
-	dojo.require("dojo.i18n");
-}
-
-//>>includeStart("amdLoader", kwArgs.asynchLoader);
-return dojo;
-});
-//>>includeEnd("amdLoader");
diff --git a/dojo/_base/_loader/hostenv_ff_ext.js b/dojo/_base/_loader/hostenv_ff_ext.js
deleted file mode 100644
index a360a4c..0000000
--- a/dojo/_base/_loader/hostenv_ff_ext.js
+++ /dev/null
@@ -1,331 +0,0 @@
-// a host environment specifically built for Mozilla extensions, but derived
-// from the browser host environment
-if(typeof window != 'undefined'){
-	dojo.isBrowser = true;
-	dojo._name = "browser";
-
-
-	// FIXME: PORTME
-	//	http://developer.mozilla.org/en/mozIJSSubScriptLoader
-
-
-	// attempt to figure out the path to dojo if it isn't set in the config
-	(function(){
-		var d = dojo;
-		// this is a scope protection closure. We set browser versions and grab
-		// the URL we were loaded from here.
-
-		// FIXME: need to probably use a different reference to "document" to get the hosting XUL environment
-
-		d.baseUrl = d.config.baseUrl;
-
-		// fill in the rendering support information in dojo.render.*
-		var n = navigator;
-		var dua = n.userAgent;
-		var dav = n.appVersion;
-		var tv = parseFloat(dav);
-
-		d.isMozilla = d.isMoz = tv;
-		if(d.isMoz){
-			d.isFF = parseFloat(dua.split("Firefox/")[1]) || undefined;
-		}
-
-		// FIXME
-		d.isQuirks = document.compatMode == "BackCompat";
-
-		// FIXME
-		// TODO: is the HTML LANG attribute relevant?
-		d.locale = dojo.config.locale || n.language.toLowerCase();
-
-		d._xhrObj = function(){
-			return new XMLHttpRequest();
-		}
-
-		// monkey-patch _loadUri to handle file://, chrome://, and resource:// url's
-		var oldLoadUri = d._loadUri;
-		d._loadUri = function(uri, cb){
-			var handleLocal = ["file:", "chrome:", "resource:"].some(function(prefix){
-				return String(uri).indexOf(prefix) == 0;
-			});
-			if(handleLocal){
-				// see:
-				//		http://developer.mozilla.org/en/mozIJSSubScriptLoader
-				var l = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
-					.getService(Components.interfaces.mozIJSSubScriptLoader);
-				var value = l.loadSubScript(uri, d.global)
-				if(cb){ cb(value); }
-				return true;
-			}else{
-				// otherwise, call the pre-existing version
-				return oldLoadUri.apply(d, arguments);
-			}
-		}
-
-		// FIXME: PORTME
-		d._isDocumentOk = function(http){
-			var stat = http.status || 0;
-			return (stat >= 200 && stat < 300) || 	// Boolean
-				stat == 304 || 						// allow any 2XX response code
-				stat == 1223 || 						// get it out of the cache
-				(!stat && (location.protocol=="file:" || location.protocol=="chrome:") );
-		}
-
-		// FIXME: PORTME
-		// var owloc = window.location+"";
-		// var base = document.getElementsByTagName("base");
-		// var hasBase = (base && base.length > 0);
-		var hasBase = false;
-
-		d._getText = function(/*URI*/ uri, /*Boolean*/ fail_ok){
-			// 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
-			//		failure and failure is okay (an exception otherwise)
-
-			// alert("_getText: " + uri);
-
-			// NOTE: must be declared before scope switches ie. this._xhrObj()
-			var http = d._xhrObj();
-
-			if(!hasBase && dojo._Url){
-				uri = (new dojo._Url(uri)).toString();
-			}
-			if(d.config.cacheBust){
-				//Make sure we have a string before string methods are used on uri
-				uri += "";
-				uri += (uri.indexOf("?") == -1 ? "?" : "&") + String(d.config.cacheBust).replace(/\W+/g,"");
-			}
-			var handleLocal = ["file:", "chrome:", "resource:"].some(function(prefix){
-				return String(uri).indexOf(prefix) == 0;
-			});
-			if(handleLocal){
-				// see:
-				//		http://forums.mozillazine.org/viewtopic.php?p=921150#921150
-				var ioService = Components.classes["@mozilla.org/network/io-service;1"]
-					.getService(Components.interfaces.nsIIOService);
-				var scriptableStream=Components
-					.classes["@mozilla.org/scriptableinputstream;1"]
-					.getService(Components.interfaces.nsIScriptableInputStream);
-
-				var channel = ioService.newChannel(uri, null, null);
-				var input = channel.open();
-				scriptableStream.init(input);
-				var str = scriptableStream.read(input.available());
-				scriptableStream.close();
-				input.close();
-				return str;
-			}else{
-				http.open('GET', uri, false);
-				try{
-					http.send(null);
-					// alert(http);
-					if(!d._isDocumentOk(http)){
-						var err = Error("Unable to load "+uri+" status:"+ http.status);
-						err.status = http.status;
-						err.responseText = http.responseText;
-						throw err;
-					}
-				}catch(e){
-					if(fail_ok){ return null; } // null
-					// rethrow the exception
-					throw e;
-				}
-				return http.responseText; // String
-			}
-		}
-		
-		d._windowUnloaders = [];
-		
-		// FIXME: PORTME
-		d.windowUnloaded = function(){
-			// summary:
-			//		signal fired by impending window destruction. You may use
-			//		dojo.addOnWIndowUnload() or dojo.connect() to this method to perform
-			//		page/application cleanup methods. See dojo.addOnWindowUnload for more info.
-			var mll = d._windowUnloaders;
-			while(mll.length){
-				(mll.pop())();
-			}
-		}
-
-		// FIXME: PORTME
-		d.addOnWindowUnload = function(/*Object?*/obj, /*String|Function?*/functionName){
-			// summary:
-			//		registers a function to be triggered when window.onunload fires.
-			//		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.
-			// example:
-			//	|	dojo.addOnWindowUnload(functionPointer)
-			//	|	dojo.addOnWindowUnload(object, "functionName")
-			//	|	dojo.addOnWindowUnload(object, function(){ /* ... */});
-	
-			d._onto(d._windowUnloaders, obj, functionName);
-		}
-
-		// XUL specific APIs
-		var contexts = [];
-		var current = null;
-		dojo._defaultContext = [ window, document ];
-
-		dojo.pushContext = function(/*Object|String?*/g, /*MDocumentElement?*/d){
-			//	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:
-			//		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
-			//		"return" to a previous context, whereas the
-			//		dojo.pushContext and dojo.popContext methods provide a more
-			//		natural way to augment blocks of code to ensure that they
-			//		execute in a different window or frame without issue. If
-			//		called without any arguments, the default context (the
-			//		context when Dojo is first loaded) is instead pushed into
-			//		the stack. If only a single string is passed, a node in the
-			//		intitial context's document is looked up and its
-			//		contextWindow and contextDocument properties are used as
-			//		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:
-			//		The global context. If a string, the id of the frame to
-			//		search for a context and document.
-			//	d:
-			//		The document element to execute subsequent code with.
-			var old = [dojo.global, dojo.doc];
-			contexts.push(old);
-			var n;
-			if(!g && !d){
-				n = dojo._defaultContext;
-			}else{
-				n = [ g, d ];
-				if(!d && dojo.isString(g)){
-					var t = document.getElementById(g);
-					if(t.contentDocument){
-						n = [t.contentWindow, t.contentDocument];
-					}
-				}
-			}
-			current = n;
-			dojo.setContext.apply(dojo, n);
-			return old; // Array
-		};
-
-		dojo.popContext = function(){
-			//	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,
-			//		document]) is returned.
-			var oc = current;
-			if(!contexts.length){
-				return oc;
-			}
-			dojo.setContext.apply(dojo, contexts.pop());
-			return oc;
-		};
-
-		// FIXME:
-		//		don't really like the current arguments and order to
-		//		_inContext, so don't make it public until it's right!
-		dojo._inContext = function(g, d, f){
-			var a = dojo._toArray(arguments);
-			f = a.pop();
-			if(a.length == 1){
-				d = null;
-			}
-			dojo.pushContext(g, d);
-			var r = f();
-			dojo.popContext();
-			return r;
-		};
-
-	})();
-
-	dojo._initFired = false;
-	//	BEGIN DOMContentLoaded, from Dean Edwards (http://dean.edwards.name/weblog/2006/06/again/)
-	dojo._loadInit = function(e){
-		dojo._initFired = true;
-		// allow multiple calls, only first one will take effect
-		// A bug in khtml calls events callbacks for document for event which isnt supported
-		// for example a created contextmenu event calls DOMContentLoaded, workaround
-		var type = (e && e.type) ? e.type.toLowerCase() : "load";
-		if(arguments.callee.initialized || (type != "domcontentloaded" && type != "load")){ return; }
-		arguments.callee.initialized = true;
-		if(dojo._inFlightCount == 0){
-			dojo._modulesLoaded();
-		}
-	}
-
-	/*
-	(function(){
-		var _w = window;
-		var _handleNodeEvent = function(evtName, fp){
-			// summary:
-			//		non-destructively adds the specified function to the node's
-			//		evtName handler.
-			// evtName: should be in the form "onclick" for "onclick" handlers.
-			// Make sure you pass in the "on" part.
-			var oldHandler = _w[evtName] || function(){};
-			_w[evtName] = function(){
-				fp.apply(_w, arguments);
-				oldHandler.apply(_w, arguments);
-			};
-		};
-		// FIXME: PORT
-		// FIXME: dojo.unloaded requires dojo scope, so using anon function wrapper.
-		_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
-	if(!dojo.config.afterOnLoad){
-		window.addEventListener("DOMContentLoaded",function(e){
-			dojo._loadInit(e);
-			// console.log("DOM content loaded", e);
-		}, false);
-	}
-
-} //if (typeof window != 'undefined')
-
-//Register any module paths set up in djConfig. Need to do this
-//in the hostenvs since hostenv_browser can read djConfig from a
-//script tag's attribute.
-(function(){
-	var mp = dojo.config["modulePaths"];
-	if(mp){
-		for(var param in mp){
-			dojo.registerModulePath(param, mp[param]);
-		}
-	}
-})();
-
-//Load debug code if necessary.
-if(dojo.config.isDebug){
-	// logging stub for extension logging
-	console.log = function(m){
-		var s = Components.classes["@mozilla.org/consoleservice;1"].getService(
-			Components.interfaces.nsIConsoleService
-		);
-		s.logStringMessage(m);
-	}
-	console.debug = function(){
-		console.log(dojo._toArray(arguments).join(" "));
-	}
-	// FIXME: what about the rest of the console.* methods? And is there any way to reach into firebug and log into it directly?
-}
diff --git a/dojo/_base/_loader/hostenv_rhino.js b/dojo/_base/_loader/hostenv_rhino.js
deleted file mode 100644
index 205a9d9..0000000
--- a/dojo/_base/_loader/hostenv_rhino.js
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
-* Rhino host environment
-*/
-
-if(dojo.config["baseUrl"]){
-	dojo.baseUrl = dojo.config["baseUrl"];
-}else{
-	dojo.baseUrl = "./";
-}
-
-dojo.locale = dojo.locale || String(java.util.Locale.getDefault().toString().replace('_','-').toLowerCase());
-dojo._name = 'rhino';
-dojo.isRhino = true;
-
-if(typeof print == "function"){
-	console.debug = print;
-}
-
-if(!("byId" in dojo)){
-	dojo.byId = function(id, doc){
-		if(id && (typeof id == "string" || id instanceof String)){
-			if(!doc){ doc = document; }
-			return doc.getElementById(id);
-		}
-		return id; // assume it's a node
-	}
-}
-
-dojo._isLocalUrl = function(/*String*/ uri) {
-	// summary:
-	// 		determines if URI is local or not.
-
-	var local = (new java.io.File(uri)).exists();
-	if(!local){
-		var stream;
-		//Try remote URL. Allow this method to throw,
-		//but still do cleanup.
-		try{
-			// try it as a file first, URL second
-			stream = (new java.net.URL(uri)).openStream();
-			// close the stream so we don't leak resources
-			stream.close();
-		}finally{
-			if(stream && stream.close){
-				stream.close();
-			}
-		}
-	}
-	return local;
-}
-
-// see comments in spidermonkey loadUri
-dojo._loadUri = function(uri, cb){
-	if(dojo._loadedUrls[uri]){
-		return true; // Boolean
-	}
-	try{
-		var local;
-		try{
-			local = dojo._isLocalUrl(uri);
-		}catch(e){
-			// no debug output; this failure just means the uri was not found.
-			return false;
-		}
-
-		dojo._loadedUrls[uri] = true;
-		//FIXME: Use Rhino 1.6 native readFile/readUrl if available?
-		if(cb){
-			var contents = (local ? readText : readUri)(uri, "UTF-8");
-
-			// patch up the input to eval until https://bugzilla.mozilla.org/show_bug.cgi?id=471005 is fixed.
-			if(!eval("'\u200f'").length){
-				contents = String(contents).replace(/[\u200E\u200F\u202A-\u202E]/g, function(match){
-					return "\\u" + match.charCodeAt(0).toString(16);
-				})
-			}
-			contents = /^define\(/.test(contents) ? contents : '('+contents+')';
-			cb(eval(contents));
-		}else{
-			load(uri);
-		}
-		dojo._loadedUrls.push(uri);
-		return true;
-	}catch(e){
-		dojo._loadedUrls[uri] = false;
-		console.debug("rhino load('" + uri + "') failed. Exception: " + e);
-		return false;
-	}
-}
-
-dojo.exit = function(exitcode){
-	quit(exitcode);
-}
-
-// reading a file from disk in Java is a humiliating experience by any measure.
-// Lets avoid that and just get the freaking text
-function readText(path, encoding){
-	encoding = encoding || "utf-8";
-	// NOTE: we intentionally avoid handling exceptions, since the caller will
-	// want to know
-	var jf = new java.io.File(path);
-	var is = new java.io.FileInputStream(jf);
-	return dj_readInputStream(is, encoding);
-}
-
-function readUri(uri, encoding){
-	var conn = (new java.net.URL(uri)).openConnection();
-	encoding = encoding || conn.getContentEncoding() || "utf-8";
-	var is = conn.getInputStream();
-	return dj_readInputStream(is, encoding);
-}
-
-function dj_readInputStream(is, encoding){
-	var input = new java.io.BufferedReader(new java.io.InputStreamReader(is, encoding));
-	try {
-		var sb = new java.lang.StringBuffer();
-		var line = "";
-		while((line = input.readLine()) !== null){
-			sb.append(line);
-			sb.append(java.lang.System.getProperty("line.separator"));
-		}
-		return sb.toString();
-	} finally {
-		input.close();
-	}
-}
-
-dojo._getText = function(/*URI*/ uri, /*Boolean*/ fail_ok){
-	// summary: Read the contents of the specified uri and return those contents.
-	// uri:
-	//		A relative or absolute uri.
-	// 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
-	//		failure and failure is okay (an exception otherwise)
-	try{
-		var local = dojo._isLocalUrl(uri);
-		var text = (local ? readText : readUri)(uri, "UTF-8");
-		if(text !== null){
-			//Force JavaScript string.
-			text += "";
-		}
-		return text;
-	}catch(e){
-		if(fail_ok){
-			return null;
-		}else{
-			throw e;
-		}
-	}
-}
-
-// summary:
-//		return the document object associated with the dojo.global
-dojo.doc = typeof document != "undefined" ? document : null;
-
-dojo.body = function(){
-	return document.body;
-}
-
-// Supply setTimeout/clearTimeout implementations if they aren't already there
-// Note: this assumes that we define both if one is not provided... there might
-// be a better way to do this if there is a use case where one is defined but
-// not the other
-if(typeof setTimeout == "undefined" || typeof clearTimeout == "undefined"){
-	dojo._timeouts = [];
-	clearTimeout = function(idx){
-		if(!dojo._timeouts[idx]){ return; }
-		dojo._timeouts[idx].stop();
-	}
-
-	setTimeout = function(func, delay){
-		// summary: provides timed callbacks using Java threads
-
-		var def={
-			sleepTime:delay,
-			hasSlept:false,
-		
-			run:function(){
-				if(!this.hasSlept){
-					this.hasSlept=true;
-					java.lang.Thread.currentThread().sleep(this.sleepTime);
-				}
-				try{
-					func();
-				}catch(e){
-					console.debug("Error running setTimeout thread:" + e);
-				}
-			}
-		};
-	
-		var runnable = new java.lang.Runnable(def);
-		var thread = new java.lang.Thread(runnable);
-		thread.start();
-		return dojo._timeouts.push(thread)-1;
-	}
-}
-
-//Register any module paths set up in djConfig. Need to do this
-//in the hostenvs since hostenv_browser can read djConfig from a
-//script tag's attribute.
-if(dojo.config["modulePaths"]){
-	for(var param in dojo.config["modulePaths"]){
-		dojo.registerModulePath(param, dojo.config["modulePaths"][param]);
-	}
-}
diff --git a/dojo/_base/_loader/hostenv_spidermonkey.js b/dojo/_base/_loader/hostenv_spidermonkey.js
deleted file mode 100644
index 649f40e..0000000
--- a/dojo/_base/_loader/hostenv_spidermonkey.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * SpiderMonkey host environment
- */
-
-if(dojo.config["baseUrl"]){
-	dojo.baseUrl = dojo.config["baseUrl"];
-}else{
-	dojo.baseUrl = "./";
-}
-
-dojo._name = 'spidermonkey';
-
-/*=====
-dojo.isSpidermonkey = {
-	// summary: Detect spidermonkey
-};
-=====*/
-
-dojo.isSpidermonkey = true;
-dojo.exit = function(exitcode){
-	quit(exitcode);
-}
-
-if(typeof print == "function"){
-	console.debug = print;
-}
-
-if(typeof line2pc == 'undefined'){
-	throw new Error("attempt to use SpiderMonkey host environment when no 'line2pc' global");
-}
-
-dojo._spidermonkeyCurrentFile = function(depth){
-	//
-	//	This is a hack that determines the current script file by parsing a
-	//	generated stack trace (relying on the non-standard "stack" member variable
-	//	of the SpiderMonkey Error object).
-	//
-	//	If param depth is passed in, it'll return the script file which is that far down
-	//	the stack, but that does require that you know how deep your stack is when you are
-	//	calling.
-	//
-    var s = '';
-    try{
-		throw Error("whatever");
-	}catch(e){
-		s = e.stack;
-	}
-    // lines are like: bu_getCurrentScriptURI_spidermonkey("ScriptLoader.js")@burst/Runtime.js:101
-    var matches = s.match(/[^@]*\.js/gi);
-    if(!matches){
-		throw Error("could not parse stack string: '" + s + "'");
-	}
-    var fname = (typeof depth != 'undefined' && depth) ? matches[depth + 1] : matches[matches.length - 1];
-    if(!fname){
-		throw Error("could not find file name in stack string '" + s + "'");
-	}
-    //print("SpiderMonkeyRuntime got fname '" + fname + "' from stack string '" + s + "'");
-    return fname;
-}
-
-// print(dojo._spidermonkeyCurrentFile(0));
-
-dojo._loadUri = function(uri){
-	// spidermonkey load() evaluates the contents into the global scope (which
-	// is what we want).
-	// TODO: sigh, load() does not return a useful value.
-	// Perhaps it is returning the value of the last thing evaluated?
-	var ok = load(uri);
-	// console.log("spidermonkey load(", uri, ") returned ", ok);
-	return 1;
-}
-
-//Register any module paths set up in djConfig. Need to do this
-//in the hostenvs since hostenv_browser can read djConfig from a
-//script tag's attribute.
-if(dojo.config["modulePaths"]){
-	for(var param in dojo.config["modulePaths"]){
-		dojo.registerModulePath(param, dojo.config["modulePaths"][param]);
-	}
-}
diff --git a/dojo/_base/_loader/loader.js b/dojo/_base/_loader/loader.js
deleted file mode 100644
index ec15a03..0000000
--- a/dojo/_base/_loader/loader.js
+++ /dev/null
@@ -1,904 +0,0 @@
-/*
- * loader.js - A bootstrap module.  Runs before the hostenv_*.js file. Contains
- * all of the package loading methods.
- */
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-(function(){
-	var d = dojo, currentModule;
-//>>excludeEnd("webkitMobile");
-
-	d.mixin(d, {
-		_loadedModules: {},
-		_inFlightCount: 0,
-		_hasResource: {},
-
-		_modulePrefixes: {
-			dojo: 	{	name: "dojo", value: "." },
-			// dojox: 	{	name: "dojox", value: "../dojox" },
-			// dijit: 	{	name: "dijit", value: "../dijit" },
-			doh: 	{	name: "doh", value: "../util/doh" },
-			tests: 	{	name: "tests", value: "tests" }
-		},
-
-		_moduleHasPrefix: function(/*String*/module){
-			// summary: checks to see if module has been established
-			var mp = d._modulePrefixes;
-			return !!(mp[module] && mp[module].value); // Boolean
-		},
-
-		_getModulePrefix: function(/*String*/module){
-			// summary: gets the prefix associated with module
-			var mp = d._modulePrefixes;
-			if(d._moduleHasPrefix(module)){
-				return mp[module].value; // String
-			}
-			return module; // String
-		},
-
-		_loadedUrls: [],
-
-		//WARNING:
-		//		This variable is referenced by packages outside of bootstrap:
-		//		FloatingPane.js and undo/browser.js
-		_postLoad: false,
-
-		//Egad! Lots of test files push on this directly instead of using dojo.addOnLoad.
-		_loaders: [],
-		_unloaders: [],
-		_loadNotifying: false
-	});
-
-
-	//>>excludeStart("xdomainExclude", fileName.indexOf("dojo.xd.js") != -1 && kwArgs.loader == "xdomain");
-	dojo._loadPath = function(/*String*/relpath, /*String?*/module, /*Function?*/cb){
-		// 	summary:
-		//		Load a Javascript module given a relative path
-		//
-		//	description:
-		//		Loads and interprets the script located at relpath, which is
-		//		relative to the script root directory.  If the script is found but
-		//		its interpretation causes a runtime exception, that exception is
-		//		not caught by us, so the caller will see it.  We return a true
-		//		value if and only if the script is found.
-		//
-		// relpath:
-		//		A relative path to a script (no leading '/', and typically ending
-		//		in '.js').
-		// module:
-		//		A module whose existance to check for after loading a path.  Can be
-		//		used to determine success or failure of the load.
-		// cb:
-		//		a callback function to pass the result of evaluating the script
-
-		var uri = ((relpath.charAt(0) == '/' || relpath.match(/^\w+:/)) ? "" : d.baseUrl) + relpath;
-		try{
-			currentModule = module;
-			return !module ? d._loadUri(uri, cb) : d._loadUriAndCheck(uri, module, cb); // Boolean
-		}catch(e){
-			console.error(e);
-			return false; // Boolean
-		}finally{
-			currentModule = null;
-		}
-	}
-
-	dojo._loadUri = function(/*String*/uri, /*Function?*/cb){
-		//	summary:
-		//		Loads JavaScript from a URI
-		//	description:
-		//		Reads the contents of the URI, and evaluates the contents.  This is
-		//		used to load modules as well as resource bundles. Returns true if
-		//		it succeeded. Returns false if the URI reading failed.  Throws if
-		//		the evaluation throws.
-		//	uri: a uri which points at the script to be loaded
-		//	cb:
-		//		a callback function to process the result of evaluating the script
-		//		as an expression, typically used by the resource bundle loader to
-		//		load JSON-style resources
-
-		if(d._loadedUrls[uri]){
-			return true; // Boolean
-		}
-		d._inFlightCount++; // block addOnLoad calls that arrive while we're busy downloading
-		var contents = d._getText(uri, true);
-		if(contents){ // not 404, et al
-			d._loadedUrls[uri] = true;
-			d._loadedUrls.push(uri);
-			if(cb){
-				//conditional to support script-inject i18n bundle format
-				contents = /^define\(/.test(contents) ? contents : '('+contents+')';
-			}else{
-				//Only do the scoping if no callback. If a callback is specified,
-				//it is most likely the i18n bundle stuff.
-				contents = d._scopePrefix + contents + d._scopeSuffix;
-			}
-			if(!d.isIE){ contents += "\r\n//@ sourceURL=" + uri; } // debugging assist for Firebug
-			var value = d["eval"](contents);
-			if(cb){ cb(value); }
-		}
-		// Check to see if we need to call _callLoaded() due to an addOnLoad() that arrived while we were busy downloading
-		if(--d._inFlightCount == 0 && d._postLoad && d._loaders.length){
-			// We shouldn't be allowed to get here but Firefox allows an event
-			// (mouse, keybd, async xhrGet) to interrupt a synchronous xhrGet.
-			// If the current script block contains multiple require() statements, then after each
-			// require() returns, inFlightCount == 0, but we want to hold the _callLoaded() until
-			// all require()s are done since the out-of-sequence addOnLoad() presumably needs them all.
-			// setTimeout allows the next require() to start (if needed), and then we check this again.
-			setTimeout(function(){
-				// If inFlightCount > 0, then multiple require()s are running sequentially and
-				// the next require() started after setTimeout() was executed but before we got here.
-				if(d._inFlightCount == 0){
-					d._callLoaded();
-				}
-			}, 0);
-		}
-		return !!contents; // Boolean: contents? true : false
-	}
-	//>>excludeEnd("xdomainExclude");
-
-	// FIXME: probably need to add logging to this method
-	dojo._loadUriAndCheck = function(/*String*/uri, /*String*/moduleName, /*Function?*/cb){
-		// summary: calls loadUri then findModule and returns true if both succeed
-		var ok = false;
-		try{
-			ok = d._loadUri(uri, cb);
-		}catch(e){
-			console.error("failed loading " + uri + " with error: " + e);
-		}
-		return !!(ok && d._loadedModules[moduleName]); // Boolean
-	}
-
-	dojo.loaded = function(){
-		// summary:
-		//		signal fired when initial environment and package loading is
-		//		complete. You should use dojo.addOnLoad() instead of doing a
-		//		direct dojo.connect() to this method in order to handle
-		//		initialization tasks that require the environment to be
-		//		initialized. In a browser host,	declarative widgets will
-		//		be constructed when this function finishes runing.
-		d._loadNotifying = true;
-		d._postLoad = true;
-		var mll = d._loaders;
-
-		//Clear listeners so new ones can be added
-		//For other xdomain package loads after the initial load.
-		d._loaders = [];
-
-		for(var x = 0; x < mll.length; x++){
-			mll[x]();
-		}
-
-		d._loadNotifying = false;
-		
-		//Make sure nothing else got added to the onload queue
-		//after this first run. If something did, and we are not waiting for any
-		//more inflight resources, run again.
-		if(d._postLoad && d._inFlightCount == 0 && mll.length){
-			d._callLoaded();
-		}
-	}
-
-	dojo.unloaded = function(){
-		// summary:
-		//		signal fired by impending environment destruction. You should use
-		//		dojo.addOnUnload() instead of doing a direct dojo.connect() to this
-		//		method to perform page/application cleanup methods. See
-		//		dojo.addOnUnload for more info.
-		var mll = d._unloaders;
-		while(mll.length){
-			(mll.pop())();
-		}
-	}
-
-	d._onto = function(arr, obj, fn){
-		if(!fn){
-			arr.push(obj);
-		}else if(fn){
-			var func = (typeof fn == "string") ? obj[fn] : fn;
-			arr.push(function(){ func.call(obj); });
-		}
-	}
-
-	dojo.ready = dojo.addOnLoad = function(/*Object*/obj, /*String|Function?*/functionName){
-		// summary:
-		//		Registers a function to be triggered after the DOM and dojo.require() calls
-		//		have finished loading.
-		//
-		// description:
-		//		Registers a function to be triggered after the DOM has finished
-		//		loading and `dojo.require` modules have loaded. Widgets declared in markup
-		//		have been instantiated if `djConfig.parseOnLoad` is true when this fires.
-		//
-		//		Images and CSS files may or may not have finished downloading when
-		//		the specified function is called.  (Note that widgets' CSS and HTML
-		//		code is guaranteed to be downloaded before said widgets are
-		//		instantiated, though including css resouces BEFORE any script elements
-		//		is highly recommended).
-		//
-		// example:
-		//	Register an anonymous function to run when everything is ready
-		//	|	dojo.addOnLoad(function(){ doStuff(); });
-		//
-		// example:
-		//	Register a function to run when everything is ready by pointer:
-		//	|	var init = function(){ doStuff(); }
-		//	|	dojo.addOnLoad(init);
-		//
-		// example:
-		//	Register a function to run scoped to `object`, either by name or anonymously:
-		//	|	dojo.addOnLoad(object, "functionName");
-		//	|	dojo.addOnLoad(object, function(){ doStuff(); });
-
-		d._onto(d._loaders, obj, functionName);
-
-		//Added for xdomain loading. dojo.addOnLoad is used to
-		//indicate callbacks after doing some dojo.require() statements.
-		//In the xdomain case, if all the requires are loaded (after initial
-		//page load), then immediately call any listeners.
-		if(d._postLoad && d._inFlightCount == 0 && !d._loadNotifying){
-			d._callLoaded();
-		}
-	}
-
-	//Support calling dojo.addOnLoad via djConfig.addOnLoad. Support all the
-	//call permutations of dojo.addOnLoad. Mainly useful when dojo is added
-	//to the page after the page has loaded.
-	var dca = d.config.addOnLoad;
-	if(dca){
-		d.addOnLoad[(dca instanceof Array ? "apply" : "call")](d, dca);
-	}
-
-	dojo._modulesLoaded = function(){
-		if(d._postLoad){ return; }
-		if(d._inFlightCount > 0){
-			console.warn("files still in flight!");
-			return;
-		}
-		d._callLoaded();
-	}
-
-	dojo._callLoaded = function(){
-
-		// The "object" check is for IE, and the other opera check fixes an
-		// issue in Opera where it could not find the body element in some
-		// widget test cases.  For 0.9, maybe route all browsers through the
-		// setTimeout (need protection still for non-browser environments
-		// though). This might also help the issue with FF 2.0 and freezing
-		// issues where we try to do sync xhr while background css images are
-		// being loaded (trac #2572)? Consider for 0.9.
-		if(typeof setTimeout == "object" || (d.config.useXDomain && d.isOpera)){
-			setTimeout(
-				d.isAIR ? function(){ d.loaded(); } : d._scopeName + ".loaded();",
-				0);
-		}else{
-			d.loaded();
-		}
-	}
-
-	dojo._getModuleSymbols = function(/*String*/modulename){
-		// summary:
-		//		Converts a module name in dotted JS notation to an array
-		//		representing the path in the source tree
-		var syms = modulename.split(".");
-		for(var i = syms.length; i>0; i--){
-			var parentModule = syms.slice(0, i).join(".");
-			if(i == 1 && !d._moduleHasPrefix(parentModule)){
-				// Support default module directory (sibling of dojo) for top-level modules
-				syms[0] = "../" + syms[0];
-			}else{
-				var parentModulePath = d._getModulePrefix(parentModule);
-				if(parentModulePath != parentModule){
-					syms.splice(0, i, parentModulePath);
-					break;
-				}
-			}
-		}
-		return syms; // Array
-	}
-
-	dojo._global_omit_module_check = false;
-
-	dojo.loadInit = function(/*Function*/init){
-		//	summary:
-		//		Executes a function that needs to be executed for the loader's dojo.requireIf
-		//		resolutions to work. This is needed mostly for the xdomain loader case where
-		//		a function needs to be executed to set up the possible values for a dojo.requireIf
-		//		call.
-		//	init:
-		//		a function reference. Executed immediately.
-		//	description: This function is mainly a marker for the xdomain loader to know parts of
-		//		code that needs be executed outside the function wrappper that is placed around modules.
-		//		The init function could be executed more than once, and it should make no assumptions
-		//		on what is loaded, or what modules are available. Only the functionality in Dojo Base
-		//		is allowed to be used. Avoid using this method. For a valid use case,
-		//		see the source for dojox.gfx.
-		init();
-	}
-
-	dojo._loadModule = dojo.require = function(/*String*/moduleName, /*Boolean?*/omitModuleCheck){
-		//	summary:
-		//		loads a Javascript module from the appropriate URI
-		//
-		//	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?
-		//		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
-		//		file located at `a/b/c.js` does not define an object `a.b.c`,
-		//		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.
-		//
-		// 		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.
-		//
-		// 		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.
-		//
-		// 		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
-		//		`dojo.require("A.B")` first checks to see if symbol A.B is
-		//		defined. If it is, it is simply returned (nothing to do).
-		//
-		//		If it is not defined, it will look for `A/B.js` in the script root
-		//		directory.
-		//
-		//		`dojo.require` throws an exception if it cannot find a file
-		//		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.
-		//
-		//		`dojo.require()` does nothing about importing symbols into
-		//		the current namespace.  It is presumed that the caller will
-		//		take care of that.
-		//
-		// 	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
-		//	   	|	});
-		//
-		//	example:
-		//		For example, to import all symbols into a local block, you might write:
-		//
-		//		|	with (dojo.require("A.B")) {
-		//		|		...
-		//		|	}
-		//
-		//		And to import just the leaf symbol to a local variable:
-		//
-		//		|	var B = dojo.require("A.B");
-		//	   	|	...
-		//
-		//	returns:
-		//		the required namespace object
-		omitModuleCheck = d._global_omit_module_check || omitModuleCheck;
-
-		//Check if it is already loaded.
-		var module = d._loadedModules[moduleName];
-		if(module){
-			return module;
-		}
-
-		// convert periods to slashes
-		var relpath = d._getModuleSymbols(moduleName).join("/") + '.js';
-		var modArg = !omitModuleCheck ? moduleName : null;
-		var ok = d._loadPath(relpath, modArg);
-		if(!ok && !omitModuleCheck){
-			throw new Error("Could not load '" + moduleName + "'; last tried '" + relpath + "'");
-		}
-
-		// check that the symbol was defined
-		// Don't bother if we're doing xdomain (asynchronous) loading.
-		if(!omitModuleCheck && !d._isXDomain){
-			// pass in false so we can give better error
-			module = d._loadedModules[moduleName];
-			if(!module){
-				throw new Error("symbol '" + moduleName + "' is not defined after loading '" + relpath + "'");
-			}
-		}
-
-		return module;
-	}
-
-	dojo.provide = function(/*String*/ resourceName){
-		//	summary:
-		//		Register a resource with the package system. Works in conjunction with `dojo.require`
-		//
-		//	description:
-		//		Each javascript source file is called a resource.  When a
-		//		resource is loaded by the browser, `dojo.provide()` registers
-		//		that it has been loaded.
-		//
-		//		Each javascript source file must have at least one
-		//		`dojo.provide()` call at the top of the file, corresponding to
-		//		the file name.  For example, `js/dojo/foo.js` must have
-		//		`dojo.provide("dojo.foo");` before any calls to
-		//		`dojo.require()` are made.
-		//
-		//		For backwards compatibility reasons, in addition to registering
-		//		the resource, `dojo.provide()` also ensures that the javascript
-		//		object for the module exists.  For example,
-		//		`dojo.provide("dojox.data.FlickrStore")`, in addition to
-		//		registering that `FlickrStore.js` is a resource for the
-		//		`dojox.data` module, will ensure that the `dojox.data`
-		//		javascript object exists, so that calls like
-		//		`dojo.data.foo = function(){ ... }` don't fail.
-		//
-		//		In the case of a build where multiple javascript source files
-		//		are combined into one bigger file (similar to a .lib or .jar
-		//		file), that file may contain multiple dojo.provide() calls, to
-		//		note that it includes multiple resources.
-		//
-		// resourceName: String
-		//		A dot-sperated string identifying a resource.
-		//
-		// example:
-		//	Safely create a `my` object, and make dojo.require("my.CustomModule") work
-		//	|	dojo.provide("my.CustomModule");
-
-		//Make sure we have a string.
-		resourceName = resourceName + "";
-		return (d._loadedModules[resourceName] = d.getObject(resourceName, true)); // Object
-	}
-
-	//Start of old bootstrap2:
-
-	dojo.platformRequire = function(/*Object*/modMap){
-		//	summary:
-		//		require one or more modules based on which host environment
-		//		Dojo is currently operating in
-		//	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:
-		//		"default" and "common". The items in the "default" array will
-		//		be loaded if none of the other items have been choosen based on
-		//		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({
-		//		|		browser: [
-		//		|			"foo.sample", // simple module
-		//		|			"foo.test",
-		//		|			["foo.bar.baz", true] // skip object check in _loadModule (dojo.require)
-		//		|		],
-		//		|		default: [ "foo.sample._base" ],
-		//		|		common: [ "important.module.common" ]
-		//		|	});
-
-		var common = modMap.common || [];
-		var result = common.concat(modMap[d._name] || modMap["default"] || []);
-
-		for(var x=0; x<result.length; x++){
-			var curr = result[x];
-			if(curr.constructor == Array){
-				d._loadModule.apply(d, curr);
-			}else{
-				d._loadModule(curr);
-			}
-		}
-	}
-
-	dojo.requireIf = function(/*Boolean*/ condition, /*String*/ resourceName){
-		// summary:
-		//		If the condition is true then call `dojo.require()` for the specified
-		//		resource
-		//
-		// example:
-		//	|	dojo.requireIf(dojo.isBrowser, "my.special.Module");
-		
-		if(condition === true){
-			// FIXME: why do we support chained require()'s here? does the build system?
-			var args = [];
-			for(var i = 1; i < arguments.length; i++){
-				args.push(arguments[i]);
-			}
-			d.require.apply(d, args);
-		}
-	}
-
-	dojo.requireAfterIf = d.requireIf;
-
-	dojo.registerModulePath = function(/*String*/module, /*String*/prefix){
-		//	summary:
-		//		Maps a module name to a path
-		//	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:
-		//		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:
-		//	|	/myapp/js/foo/bar.js
-		//	|	/myapp/js/foo/baz.js
-		//	|	/myapp/js/foo/thud/xyzzy.js
-		//		Your application can tell Dojo to locate the "foo" namespace by calling:
-		//	|	dojo.registerModulePath("foo", "../../foo");
-		//		At which point you can then use dojo.require() to load the
-		//		modules (assuming they provide() the same things which are
-		//		required). The full code might be:
-		//	|	<script type="text/javascript"
-		//	|		src="/myapp/js/dojo/dojo/dojo.js"></script>
-		//	|	<script type="text/javascript">
-		//	|		dojo.registerModulePath("foo", "../../foo");
-		//	|		dojo.require("foo.bar");
-		//	|		dojo.require("foo.baz");
-		//	|		dojo.require("foo.thud.xyzzy");
-		//	|	</script>
-		d._modulePrefixes[module] = { name: module, value: prefix };
-	};
-	
-	dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String?*/availableFlatLocales){
-		// summary:
-		//		Declares translated resources and loads them if necessary, in the
-		//		same style as dojo.require.  Contents of the resource bundle are
-		//		typically strings, but may be any name/value pair, represented in
-		//		JSON format.  See also `dojo.i18n.getLocalization`.
-		//
-		// description:
-		//		Load translated resource bundles provided underneath the "nls"
-		//		directory within a package.  Translated resources may be located in
-		//		different packages throughout the source tree.
-		//
-		//		Each directory is named for a locale as specified by RFC 3066,
-		//		(http://www.ietf.org/rfc/rfc3066.txt), normalized in lowercase.
-		//		Note that the two bundles in the example do not define all the
-		//		same variants.  For a given locale, bundles will be loaded for
-		//		that locale and all more general locales above it, including a
-		//		fallback at the root directory.  For example, a declaration for
-		//		the "de-at" locale will first load `nls/de-at/bundleone.js`,
-		//		then `nls/de/bundleone.js` and finally `nls/bundleone.js`.  The
-		//		data will be flattened into a single Object so that lookups
-		//		will follow this cascading pattern.  An optional build step can
-		//		preload the bundles to avoid data redundancy and the multiple
-		//		network hits normally required to load these resources.
-		//
-		// moduleName:
-		//		name of the package containing the "nls" directory in which the
-		//		bundle is found
-		//
-		// bundleName:
-		//		bundle name, i.e. the filename without the '.js' suffix. Using "nls" as a
-		//		a bundle name is not supported, since "nls" is the name of the folder
-		//		that holds bundles. Using "nls" as the bundle name will cause problems
-		//		with the custom build.
-		//
-		// locale:
-		//		the locale to load (optional)  By default, the browser's user
-		//		locale as defined by dojo.locale
-		//
-		// availableFlatLocales:
-		//		A comma-separated list of the available, flattened locales for this
-		//		bundle. This argument should only be set by the build process.
-		//
-		//	example:
-		//		A particular widget may define one or more resource bundles,
-		//		structured in a program as follows, where moduleName is
-		//		mycode.mywidget and bundleNames available include bundleone and
-		//		bundletwo:
-		//	|		...
-		//	|	mycode/
-		//	|		mywidget/
-		//	|			nls/
-		//	|				bundleone.js (the fallback translation, English in this example)
-		//	|				bundletwo.js (also a fallback translation)
-		//	|				de/
-		//	|					bundleone.js
-		//	|					bundletwo.js
-		//	|				de-at/
-		//	|					bundleone.js
-		//	|				en/
-		//	|					(empty; use the fallback translation)
-		//	|				en-us/
-		//	|					bundleone.js
-		//	|				en-gb/
-		//	|					bundleone.js
-		//	|				es/
-		//	|					bundleone.js
-		//	|					bundletwo.js
-		//	|				  ...etc
-		//	|				...
-		//
-
-		d.require("dojo.i18n");
-		d.i18n._requireLocalization.apply(d.hostenv, arguments);
-	};
-
-
-	var ore = new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"),
-		ire = new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$");
-
-	dojo._Url = function(/*dojo._Url|String...*/){
-		// summary:
-		//		Constructor to create an object representing a URL.
-		//		It is marked as private, since we might consider removing
-		//		or simplifying it.
-		// description:
-		//		Each argument is evaluated in order relative to the next until
-		//		a canonical uri is produced. To get an absolute Uri relative to
-		//		the current document use:
-		//      	new dojo._Url(document.baseURI, url)
-
-		var n = null,
-			_a = arguments,
-			uri = [_a[0]];
-		// resolve uri components relative to each other
-		for(var i = 1; i<_a.length; i++){
-			if(!_a[i]){ continue; }
-
-			// Safari doesn't support this.constructor so we have to be explicit
-			// FIXME: Tracked (and fixed) in Webkit bug 3537.
-			//		http://bugs.webkit.org/show_bug.cgi?id=3537
-			var relobj = new d._Url(_a[i]+""),
-				uriobj = new d._Url(uri[0]+"");
-
-			if(
-				relobj.path == "" &&
-				!relobj.scheme &&
-				!relobj.authority &&
-				!relobj.query
-			){
-				if(relobj.fragment != n){
-					uriobj.fragment = relobj.fragment;
-				}
-				relobj = uriobj;
-			}else if(!relobj.scheme){
-				relobj.scheme = uriobj.scheme;
-
-				if(!relobj.authority){
-					relobj.authority = uriobj.authority;
-
-					if(relobj.path.charAt(0) != "/"){
-						var path = uriobj.path.substring(0,
-							uriobj.path.lastIndexOf("/") + 1) + relobj.path;
-
-						var segs = path.split("/");
-						for(var j = 0; j < segs.length; j++){
-							if(segs[j] == "."){
-								// flatten "./" references
-								if(j == segs.length - 1){
-									segs[j] = "";
-								}else{
-									segs.splice(j, 1);
-									j--;
-								}
-							}else if(j > 0 && !(j == 1 && segs[0] == "") &&
-								segs[j] == ".." && segs[j-1] != ".."){
-								// flatten "../" references
-								if(j == (segs.length - 1)){
-									segs.splice(j, 1);
-									segs[j - 1] = "";
-								}else{
-									segs.splice(j - 1, 2);
-									j -= 2;
-								}
-							}
-						}
-						relobj.path = segs.join("/");
-					}
-				}
-			}
-
-			uri = [];
-			if(relobj.scheme){
-				uri.push(relobj.scheme, ":");
-			}
-			if(relobj.authority){
-				uri.push("//", relobj.authority);
-			}
-			uri.push(relobj.path);
-			if(relobj.query){
-				uri.push("?", relobj.query);
-			}
-			if(relobj.fragment){
-				uri.push("#", relobj.fragment);
-			}
-		}
-
-		this.uri = uri.join("");
-
-		// break the uri into its main components
-		var r = this.uri.match(ore);
-
-		this.scheme = r[2] || (r[1] ? "" : n);
-		this.authority = r[4] || (r[3] ? "" : n);
-		this.path = r[5]; // can never be undefined
-		this.query = r[7] || (r[6] ? "" : n);
-		this.fragment  = r[9] || (r[8] ? "" : n);
-
-		if(this.authority != n){
-			// server based naming authority
-			r = this.authority.match(ire);
-
-			this.user = r[3] || n;
-			this.password = r[4] || n;
-			this.host = r[6] || r[7]; // ipv6 || ipv4
-			this.port = r[9] || n;
-		}
-	}
-
-	dojo._Url.prototype.toString = function(){ return this.uri; };
-
-	dojo.moduleUrl = function(/*String*/module, /*dojo._Url||String*/url){
-		//	summary:
-		//		Returns a `dojo._Url` object relative to a module.
-		//	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:
-		//	|	var img = document.createElement("img");
-		// 	|	// NOTE: we assign the string representation of the url object
-		//	|	img.src = pngPath.toString();
-		//	|	// add our image to the document
-		//	|	dojo.body().appendChild(img);
-		//	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,
-		//		the `acme.widget` and `acme.util` directories may be located
-		//		under different roots (see `dojo.registerModulePath`) but the
-		//		the modules which reference them can be unaware of their
-		//		relative locations on the filesystem:
-		//	|	// somewhere in a configuration block
-		//	|	dojo.registerModulePath("acme.widget", "../../acme/widget");
-		//	|	dojo.registerModulePath("acme.util", "../../util");
-		//	|
-		//	|	// ...
-		//	|
-		//	|	// code in a module using acme resources
-		//	|	var tmpltPath = dojo.moduleUrl("acme.widget","templates/template.html");
-		//	|	var dataPath = dojo.moduleUrl("acme.util","resources/data.json");
-
-		var loc = d._getModuleSymbols(module).join('/');
-		if(!loc){ return null; }
-		if(loc.lastIndexOf("/") != loc.length-1){
-			loc += "/";
-		}
-		
-		//If the path is an absolute path (starts with a / or is on another
-		//domain/xdomain) then don't add the baseUrl.
-		var colonIndex = loc.indexOf(":");
-		if(loc.charAt(0) != "/" && (colonIndex == -1 || colonIndex > loc.indexOf("/"))){
-			loc = d.baseUrl + loc;
-		}
-
-		return new d._Url(loc, url); // dojo._Url
-	};
-
-//>>includeStart("amdLoader", kwArgs.asynchLoader);
-	// addition to support AMD module format
-	// replace the bootstrap define function (defined in _base/boostrap.js) with the dojo v1.x simulated AMD loader...
-	define= function(name, deps, def){
-		if(!def){
-			// less than 3 args
-			if(deps){
-				// 2 args
-				def = deps;
-				deps = name;
-			}else{
-				// one arg
-				def = name;
-				deps = typeof def == "function" ? ["require", "exports", "module"].slice(0, def.length) : [];
-			}
-			name = currentModule ? currentModule.replace(/\./g,'/') : "anon";
-		}
-		var dottedName = name.replace(/\//g, ".");
-		var exports = dojo.provide(dottedName);
-
-		function resolvePath(relativeId){
-			// do relative path resolution
-			if(relativeId.charAt(0) === '.'){
-				relativeId = name.substring(0, name.lastIndexOf('/') + 1) + relativeId;
-				while(lastId !== relativeId){
-					var lastId = relativeId;
-					relativeId = relativeId.replace(/\/[^\/]*\/\.\.\//,'/');
-				}
-				relativeId = relativeId.replace(/\/\.\//g,'/');
-			}
-			return relativeId.replace(/\//g, ".");
-		}
-		if(typeof def == "function"){
-			for(var args= [], depName, i= 0; i<deps.length; i++){
-				depName= resolvePath(deps[i]);
-				// look for i18n! followed by anything followed by "/nls/" followed by anything without "/" followed by eos.
-				var exclamationIndex = depName.indexOf("!");
-				if(exclamationIndex > -1){
-					//fool the build system
-					if(depName.substring(0, exclamationIndex) == "i18n"){
-						var match = depName.match(/^i18n\!(.+)\.nls\.([^\.]+)$/);
-						dojo["requireLocalization"](match[1], match[2]);
-					}
-					arg = null;
-				}else{
-					var arg;
-					switch(depName){
-						case "require":
-							arg = function(relativeId){
-								return dojo.require(resolvePath(relativeId));
-							};
-							break;
-						case "exports":
-							arg = exports;
-							break;
-						case "module":
-							var module = arg = {exports: exports};
-							break;
-						case "dojox":
-							arg = dojo.getObject(depName);
-							break;
-						case "dojo/lib/kernel":
-						case "dojo/lib/backCompat":
-							arg = dojo;
-							break;
-						default:
-							arg = dojo.require(depName);
-					}
-				}
-				args.push(arg);
-			}
-			var returned = def.apply(null, args);
-		}else{
-			returned = def;
-		}
-		
-		if(returned){
-			dojo._loadedModules[dottedName] = returned;
-			dojo.setObject(dottedName, returned);
-		}
-		if(module){
-			dojo._loadedModules[dottedName] = module.exports;
-		}
-		return returned;
-		
-	};
-	define.vendor = "dojotoolkit.org";
-	define.version = dojo.version;
-	define("dojo/lib/kernel", [], dojo);
-	define("dojo/lib/backCompat", [], dojo);
-	define("dojo", [], dojo);
-	define("dijit", [], this.dijit || (this.dijit = {}));
-//>>includeEnd("amdLoader");
-
-
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-})();
-//>>excludeEnd("webkitMobile");
diff --git a/dojo/_base/_loader/loader_debug.js b/dojo/_base/_loader/loader_debug.js
deleted file mode 100644
index b85ee0b..0000000
--- a/dojo/_base/_loader/loader_debug.js
+++ /dev/null
@@ -1,75 +0,0 @@
-dojo.provide("dojo._base._loader.loader_debug");
-
-//Override dojo.provide, so we can trigger the next
-//script tag for the next local module. We can only add one
-//at a time because there are browsers that execute script tags
-//in the order that the code is received, and not in the DOM order.
-dojo.nonDebugProvide = dojo.provide;
-
-dojo.provide = function(resourceName){
-	var dbgQueue = dojo["_xdDebugQueue"];
-	if(dbgQueue && dbgQueue.length > 0 && resourceName == dbgQueue["currentResourceName"]){
-		//Set a timeout so the module can be executed into existence. Normally the
-		//dojo.provide call in a module is the first line. Don't want to risk attaching
-		//another script tag until the current one finishes executing.
-		if(dojo.isAIR){
-			window.setTimeout(function(){dojo._xdDebugFileLoaded(resourceName);}, 1);
-		}else{
-			window.setTimeout(dojo._scopeName + "._xdDebugFileLoaded('" + resourceName + "')", 1);
-		}
-	}
-
-	return dojo.nonDebugProvide.apply(dojo, arguments);
-}
-
-dojo._xdDebugFileLoaded = function(resourceName){
-
-	if(!dojo._xdDebugScopeChecked){
-		//If using a scoped dojo, we need to expose dojo as a real global
-		//for the debugAtAllCosts stuff to work.
-		if(dojo._scopeName != "dojo"){
-			window.dojo = window[dojo.config.scopeMap[0][1]];
-			window.dijit = window[dojo.config.scopeMap[1][1]];
-			window.dojox = window[dojo.config.scopeMap[2][1]];
-		}
-
-		dojo._xdDebugScopeChecked = true;
-	}
-	
-	var dbgQueue = dojo._xdDebugQueue;
-	
-	if(resourceName && resourceName == dbgQueue.currentResourceName){
-		dbgQueue.shift();
-	}
-
-	if(dbgQueue.length == 0){
-		//Check for more modules that need debug loading.
-		//dojo._xdWatchInFlight will add more things to the debug
-		//queue if they just recently loaded but it was not detected
-		//between the dojo._xdWatchInFlight intervals.
-		dojo._xdWatchInFlight();
-	}
-
-	if(dbgQueue.length == 0){
-		dbgQueue.currentResourceName = null;
-
-		//Make sure nothing else is in flight.
-		//If something is still in flight, then it still
-		//needs to be added to debug queue after it loads.
-		for(var param in dojo._xdInFlight){
-			if(dojo._xdInFlight[param] === true){
-				return;
-			}
-		}
-
-		dojo._xdNotifyLoaded();
-	}else{
-		if(resourceName == dbgQueue.currentResourceName){
-			dbgQueue.currentResourceName = dbgQueue[0].resourceName;
-			var element = document.createElement("script");
-			element.type = "text/javascript";
-			element.src = dbgQueue[0].resourcePath;
-			document.getElementsByTagName("head")[0].appendChild(element);
-		}
-	}
-}
diff --git a/dojo/_base/_loader/loader_xd.js b/dojo/_base/_loader/loader_xd.js
deleted file mode 100644
index 7f8f728..0000000
--- a/dojo/_base/_loader/loader_xd.js
+++ /dev/null
@@ -1,716 +0,0 @@
-//Cross-domain resource loader.
-dojo.provide("dojo._base._loader.loader_xd");
-
-dojo._xdReset = function(){
-	//summary: Internal xd loader function. Resets the xd state.
-
-	//This flag indicates where or not we have crossed into xdomain territory. Once any resource says
-	//it is cross domain, then the rest of the resources have to be treated as xdomain because we need
-	//to evaluate resources in order. If there is a xdomain resource followed by a xhr resource, we can't load
-	//the xhr resource until the one before it finishes loading. The text of the xhr resource will be converted
-	//to match the format for a xd resource and put in the xd load queue.
-	dojo._isXDomain = dojo.config.useXDomain || false;
-
-	dojo._xdClearInterval();
-	dojo._xdInFlight = {};
-	dojo._xdOrderedReqs = [];
-	dojo._xdDepMap = {};
-	dojo._xdContents = [];
-	dojo._xdDefList = [];
-}
-
-dojo._xdClearInterval = function(){
-	//summary: Internal xd loader function.
-	//Clears the interval timer used to check on the
-	//status of in-flight xd module resource requests.
-	if(dojo._xdTimer){
-		clearInterval(dojo._xdTimer);
-		dojo._xdTimer = 0;
-	}
-}
-
-
-//Call reset immediately to set the state.
-dojo._xdReset();
-
-dojo._xdCreateResource = function(/*String*/contents, /*String*/resourceName, /*String*/resourcePath){
-	//summary: Internal xd loader function. Creates an xd module source given an
-	//non-xd module contents.
-
-	//Remove comments. Not perfect, but good enough for dependency resolution.
-	var depContents = contents.replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg , "");
-
-	//Find dependencies.
-	var deps = [];
-    var depRegExp = /dojo.(require|requireIf|provide|requireAfterIf|platformRequire|requireLocalization)\s*\(([\w\W]*?)\)/mg;
-    var match;
-	while((match = depRegExp.exec(depContents)) != null){
-		if(match[1] == "requireLocalization"){
-			//Need to load the local bundles asap, since they are not
-			//part of the list of modules watched for loading.
-			eval(match[0]);
-		}else{
-			deps.push('"' + match[1] + '", ' + match[2]);
-		}
-	}
-
-	//Create resource object and the call to _xdResourceLoaded.
-	var output = [];
-	output.push(dojo._scopeName + "._xdResourceLoaded(function(" + dojo._scopePrefixArgs + "){\n");
-
-	//See if there are any dojo.loadInit calls
-	var loadInitCalls = dojo._xdExtractLoadInits(contents);
-	if(loadInitCalls){
-		//Adjust fileContents since extractLoadInits removed something.
-		contents = loadInitCalls[0];
-		
-		//Add any loadInit calls to the top of the xd file.
-		for(var i = 1; i < loadInitCalls.length; i++){
-			output.push(loadInitCalls[i] + ";\n");
-		}
-	}
-
-	output.push("return {");
-
-	//Add dependencies
-	if(deps.length > 0){
-		output.push("depends: [");
-		for(i = 0; i < deps.length; i++){
-			if(i > 0){
-				output.push(",\n");
-			}
-			output.push("[" + deps[i] + "]");
-		}
-		output.push("],");
-	}
-
-	//Add the contents of the file inside a function.
-	//Pass in scope arguments so we can support multiple versions of the
-	//same module on a page.
-	output.push("\ndefineResource: function(" + dojo._scopePrefixArgs + "){");
-
-	//Don't put in the contents in the debugAtAllCosts case
-	//since the contents may have syntax errors. Let those
-	//get pushed up when the script tags are added to the page
-	//in the debugAtAllCosts case.
-	if(!dojo.config["debugAtAllCosts"] || resourceName == "dojo._base._loader.loader_debug"){
-		output.push(contents);
-	}
-	//Add isLocal property so we know if we have to do something different
-	//in debugAtAllCosts situations.
-	output.push("\n}, resourceName: '" + resourceName + "', resourcePath: '" + resourcePath + "'};});");
-	
-	return output.join(""); //String
-}
-
-dojo._xdExtractLoadInits = function(/*String*/fileContents){
-	//Extracts
-	var regexp = /dojo.loadInit\s*\(/g;
-	regexp.lastIndex = 0;
-
-	var parenRe = /[\(\)]/g;
-	parenRe.lastIndex = 0;
-
-	var results = [];
-	var matches;
-	while((matches = regexp.exec(fileContents))){
-		//Find end of the call by finding the matching end paren
-		parenRe.lastIndex = regexp.lastIndex;
-		var matchCount = 1;
-		var parenMatch;
-		while((parenMatch = parenRe.exec(fileContents))){
-			if(parenMatch[0] == ")"){
-				matchCount -= 1;
-			}else{
-				matchCount += 1;
-			}
-			if(matchCount == 0){
-				break;
-			}
-		}
-		
-		if(matchCount != 0){
-			throw "unmatched paren around character " + parenRe.lastIndex + " in: " + fileContents;
-		}
-
-		//Put the master matching string in the results.
-		var startIndex = regexp.lastIndex - matches[0].length;
-		results.push(fileContents.substring(startIndex, parenRe.lastIndex));
-
-		//Remove the matching section.
-		var remLength = parenRe.lastIndex - startIndex;
-		fileContents = fileContents.substring(0, startIndex) + fileContents.substring(parenRe.lastIndex, fileContents.length);
-
-		//Move the master regexp past the last matching paren point.
-		regexp.lastIndex = parenRe.lastIndex - remLength;
-
-		regexp.lastIndex = parenRe.lastIndex;
-	}
-
-	if(results.length > 0){
-		results.unshift(fileContents);
-	}
-
-	return (results.length ? results : null);
-}
-
-dojo._xdIsXDomainPath = function(/*string*/relpath) {
-    //summary: Figure out whether the path is local or x-domain
-	//If there is a colon before the first / then, we have a URL with a protocol.
-    
-	var colonIndex = relpath.indexOf(":");
-	var slashIndex = relpath.indexOf("/");
-
-	if(colonIndex > 0 && colonIndex < slashIndex || relpath.indexOf("//") === 0){
-		return true;
-	}else{
-		//Is the base script URI-based URL a cross domain URL?
-		//If so, then the relpath will be evaluated relative to
-		//baseUrl, and therefore qualify as xdomain.
-		//Only treat it as xdomain if the page does not have a
-		//host (file:// url), if the baseUrl does not match the
-		//current window's domain, or if the baseUrl starts with //.
-		//If baseUrl starts with // then it probably means that xdomain
-		//is wanted since it is such a specific path request. This is not completely robust,
-		//but something more robust would require normalizing the protocol on baseUrl and on the location
-		//to see if they differ. However, that requires more code, and // as a start path is unusual.
-		var url = dojo.baseUrl;
-		colonIndex = url.indexOf(":");
-		slashIndex = url.indexOf("/");
-		if(url.indexOf("//") === 0 || (colonIndex > 0 && colonIndex < slashIndex && (!location.host || url.indexOf("http://" + location.host) != 0))){
-			return true;
-		}
-	}
-    return false;
-}
-
-dojo._loadPath = function(/*String*/relpath, /*String?*/module, /*Function?*/cb){
-	//summary: Internal xd loader function. Overrides loadPath() from loader.js.
-	//xd loading requires slightly different behavior from loadPath().
-
-	var currentIsXDomain = dojo._xdIsXDomainPath(relpath);
-    dojo._isXDomain |= currentIsXDomain;
-
-	var uri = ((relpath.charAt(0) == '/' || relpath.match(/^\w+:/)) ? "" : dojo.baseUrl) + relpath;
-
-	try{
-		return ((!module || dojo._isXDomain) ? dojo._loadUri(uri, cb, currentIsXDomain, module) : dojo._loadUriAndCheck(uri, module, cb)); //Boolean
-	}catch(e){
-		console.error(e);
-		return false; //Boolean
-	}
-}
-
-dojo._xdCharSet = "utf-8";
-
-dojo._loadUri = function(/*String*/uri, /*Function?*/cb, /*boolean*/currentIsXDomain, /*String?*/module){
-	//summary: Internal xd loader function. Overrides loadUri() from loader.js.
-	//		xd loading requires slightly different behavior from loadPath().
-	//description: Wanted to override getText(), but it is used by
-	//		the widget code in too many, synchronous ways right now.
-	if(dojo._loadedUrls[uri]){
-		return 1; //Boolean
-	}
-
-	//Add the module (resource) to the list of modules.
-	//Only do this work if we have a modlue name. Otherwise,
-	//it is a non-xd i18n bundle, which can load immediately and does not
-	//need to be tracked. Also, don't track dojo.i18n, since it is a prerequisite
-	//and will be loaded correctly if we load it right away: it has no dependencies.
-	if(dojo._isXDomain && module && module != "dojo.i18n"){
-		dojo._xdOrderedReqs.push(module);
-
-		//Add to waiting resources if it is an xdomain resource.
-		//Don't add non-xdomain i18n bundles, those get evaled immediately.
-		if(currentIsXDomain || uri.indexOf("/nls/") == -1){
-			dojo._xdInFlight[module] = true;
-
-			//Increment inFlightCount
-			//This will stop the modulesLoaded from firing all the way.
-			dojo._inFlightCount++;
-		}
-
-		//Start timer
-		if(!dojo._xdTimer){
-			if(dojo.isAIR){
-				dojo._xdTimer = setInterval(function(){dojo._xdWatchInFlight();}, 100);
-			}else{
-				dojo._xdTimer = setInterval(dojo._scopeName + "._xdWatchInFlight();", 100);
-			}
-		}
-		dojo._xdStartTime = (new Date()).getTime();
-	}
-
-	if (currentIsXDomain){
-		//Fix name to be a .xd.fileextension name.
-		var lastIndex = uri.lastIndexOf('.');
-		if(lastIndex <= 0){
-			lastIndex = uri.length - 1;
-		}
-
-		var xdUri = uri.substring(0, lastIndex) + ".xd";
-		if(lastIndex != uri.length - 1){
-			xdUri += uri.substring(lastIndex, uri.length);
-		}
-
-		if (dojo.isAIR){
-			xdUri = xdUri.replace("app:/", "/");
-		}
-
-		//Add to script src
-		var element = document.createElement("script");
-		element.type = "text/javascript";
-		if(dojo._xdCharSet){
-			element.charset = dojo._xdCharSet;
-		}
-		element.src = xdUri;
-		if(!dojo.headElement){
-			dojo._headElement = document.getElementsByTagName("head")[0];
-
-			//Head element may not exist, particularly in html
-			//html 4 or tag soup cases where the page does not
-			//have a head tag in it. Use html element, since that will exist.
-			//Seems to be an issue mostly with Opera 9 and to lesser extent Safari 2
-			if(!dojo._headElement){
-				dojo._headElement = document.getElementsByTagName("html")[0];
-			}
-		}
-		dojo._headElement.appendChild(element);
-	}else{
-		var contents = dojo._getText(uri, null, true);
-		if(contents == null){ return 0; /*boolean*/}
-		
-		//If this is not xdomain, or if loading a i18n resource bundle, then send it down
-		//the normal eval/callback path.
-		if(dojo._isXDomain
-			&& uri.indexOf("/nls/") == -1
-			&& module != "dojo.i18n"){
-			var res = dojo._xdCreateResource(contents, module, uri);
-			dojo.eval(res);
-		}else{
-			if(cb){
-				contents = '('+contents+')';
-			}else{
-				//Only do the scoping if no callback. If a callback is specified,
-				//it is most likely the i18n bundle stuff.
-				contents = dojo._scopePrefix + contents + dojo._scopeSuffix;
-			}
-			var value = dojo["eval"](contents+"\r\n//@ sourceURL="+uri);
-			if(cb){
-				cb(value);
-			}
-		}
-	}
-
-	//These steps are done in the non-xd loader version of this function.
-	//Maintain these steps to fit in with the existing system.
-	dojo._loadedUrls[uri] = true;
-	dojo._loadedUrls.push(uri);
-	return true; //Boolean
-}
-
-dojo._xdResourceLoaded = function(/*Object*/res){
-	//summary: Internal xd loader function. Called by an xd module resource when
-	//it has been loaded via a script tag.
-	
-	//Evaluate the function with scopeArgs for multiversion support.
-	res = res.apply(dojo.global, dojo._scopeArgs);
-
-	//Work through dependencies.
-	var deps = res.depends;
-	var requireList = null;
-	var requireAfterList = null;
-	var provideList = [];
-	if(deps && deps.length > 0){
-		var dep = null;
-		var insertHint = 0;
-		var attachedResource = false;
-		for(var i = 0; i < deps.length; i++){
-			dep = deps[i];
-
-			//Look for specific dependency indicators.
-			if (dep[0] == "provide"){
-				provideList.push(dep[1]);
-			}else{
-				if(!requireList){
-					requireList = [];
-				}
-				if(!requireAfterList){
-					requireAfterList = [];
-				}
-
-				var unpackedDeps = dojo._xdUnpackDependency(dep);
-				if(unpackedDeps.requires){
-					requireList = requireList.concat(unpackedDeps.requires);
-				}
-				if(unpackedDeps.requiresAfter){
-					requireAfterList = requireAfterList.concat(unpackedDeps.requiresAfter);
-				}
-			}
-
-			//Call the dependency indicator to allow for the normal dojo setup.
-			//Only allow for one dot reference, for the i18n._preloadLocalizations calls
-			//(and maybe future, one-dot things).
-			var depType = dep[0];
-			var objPath = depType.split(".");
-			if(objPath.length == 2){
-				dojo[objPath[0]][objPath[1]].apply(dojo[objPath[0]], dep.slice(1));
-			}else{
-				dojo[depType].apply(dojo, dep.slice(1));
-			}
-		}
-
-
-		//If loading the debugAtAllCosts module, eval it right away since we need
-		//its functions to properly load the other modules.
-		if(provideList.length == 1 && provideList[0] == "dojo._base._loader.loader_debug"){
-			res.defineResource(dojo);
-		}else{
-			//Save off the resource contents for definition later.
-			var contentIndex = dojo._xdContents.push({
-					content: res.defineResource,
-					resourceName: res["resourceName"],
-					resourcePath: res["resourcePath"],
-					isDefined: false
-				}) - 1;
-	
-			//Add provide/requires to dependency map.
-			for(i = 0; i < provideList.length; i++){
-				dojo._xdDepMap[provideList[i]] = { requires: requireList, requiresAfter: requireAfterList, contentIndex: contentIndex };
-			}
-		}
-
-		//Now update the inflight status for any provided resources in this loaded resource.
-		//Do this at the very end (in a *separate* for loop) to avoid shutting down the
-		//inflight timer check too soon.
-		for(i = 0; i < provideList.length; i++){
-			dojo._xdInFlight[provideList[i]] = false;
-		}
-	}
-}
-
-dojo._xdLoadFlattenedBundle = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*Object*/bundleData){
-	//summary: Internal xd loader function. Used when loading
-	//a flattened localized bundle via a script tag.
-	locale = locale || "root";
-	var jsLoc = dojo.i18n.normalizeLocale(locale).replace('-', '_');
- 	var bundleResource = [moduleName, "nls", bundleName].join(".");
-	var bundle = dojo["provide"](bundleResource);
-	bundle[jsLoc] = bundleData;
-	
-	//Assign the bundle for the original locale(s) we wanted.
-	var mapName = [moduleName, jsLoc, bundleName].join(".");
-	var bundleMap = dojo._xdBundleMap[mapName];
-	if(bundleMap){
-		for(var param in bundleMap){
-			bundle[param] = bundleData;
-		}
-	}
-};
-
-
-dojo._xdInitExtraLocales = function(){
-	// Simulate the extra locale work that dojo.requireLocalization does.
-
-	var extra = dojo.config.extraLocale;
-	if(extra){
-		if(!extra instanceof Array){
-			extra = [extra];
-		}
-
-		dojo._xdReqLoc = dojo.xdRequireLocalization;
-		dojo.xdRequireLocalization = function(m, b, locale, fLocales){
-			dojo._xdReqLoc(m,b,locale, fLocales);
-			if(locale){return;}
-			for(var i=0; i<extra.length; i++){
-				dojo._xdReqLoc(m,b,extra[i], fLocales);
-			}
-		};
-	}
-}
-
-dojo._xdBundleMap = {};
-
-dojo.xdRequireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String*/availableFlatLocales){
-	//summary: Internal xd loader function. The xd version of dojo.requireLocalization.
-	
-
-	//Account for allowing multiple extra locales. Do this here inside the function
-	//since dojo._xdInitExtraLocales() depends on djConfig being set up, but that only
-	//happens after hostenv_browser runs. loader_xd has to come before hostenv_browser
-	//though since hostenv_browser can do a dojo.require for the debug module.
-	if(dojo._xdInitExtraLocales){
-		dojo._xdInitExtraLocales();
-		dojo._xdInitExtraLocales = null;
-		dojo.xdRequireLocalization.apply(dojo, arguments);
-		return;
-	}
-
-	var locales = availableFlatLocales.split(",");
-	
-	//Find the best-match locale to load.
-	//Assumes dojo.i18n has already been loaded. This is true for xdomain builds,
-	//since it is included in dojo.xd.js.
-	var jsLoc = dojo.i18n.normalizeLocale(locale);
-
-	var bestLocale = "";
-	for(var i = 0; i < locales.length; i++){
-		//Locale must match from start of string.
-		if(jsLoc.indexOf(locales[i]) == 0){
-			if(locales[i].length > bestLocale.length){
-				bestLocale = locales[i];
-			}
-		}
-	}
-
-	var fixedBestLocale = bestLocale.replace('-', '_');
-	//See if the bundle we are going to use is already loaded.
- 	var bundleResource = dojo.getObject([moduleName, "nls", bundleName].join("."));
-	if(!bundleResource || !bundleResource[fixedBestLocale]){
-		//Need to remember what locale we wanted and which one we actually use.
-		//Then when we load the one we are actually using, use that bundle for the one
-		//we originally wanted.
-		var mapName = [moduleName, (fixedBestLocale||"root"), bundleName].join(".");
-		var bundleMap = dojo._xdBundleMap[mapName];
-		if(!bundleMap){
-			bundleMap = dojo._xdBundleMap[mapName] = {};
-		}
-		bundleMap[jsLoc.replace('-', '_')] = true;
-		
-		//Do just a normal dojo.require so the resource tracking stuff works as usual.
-		dojo.require(moduleName + ".nls" + (bestLocale ? "." + bestLocale : "") + "." + bundleName);
-	}
-}
-
-// Replace dojo.requireLocalization with a wrapper
-dojo._xdRealRequireLocalization = dojo.requireLocalization;
-dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String*/availableFlatLocales){
-    // summary: loads a bundle intelligently based on whether the module is
-    // local or xd. Overrides the local-case implementation.
-    
-    var modulePath = dojo.moduleUrl(moduleName).toString();
-    if (dojo._xdIsXDomainPath(modulePath)) {
-        // call cross-domain loader
-        return dojo.xdRequireLocalization.apply(dojo, arguments);
-    } else {
-        // call local-loader
-        return dojo._xdRealRequireLocalization.apply(dojo, arguments);
-    }
-}
-
-//This is a bit brittle: it has to know about the dojo methods that deal with dependencies
-//It would be ideal to intercept the actual methods and do something fancy at that point,
-//but I have concern about knowing which provide to match to the dependency in that case,
-//since scripts can load whenever they want, and trigger new calls to dojo._xdResourceLoaded().
-dojo._xdUnpackDependency = function(/*Array*/dep){
-	//summary: Internal xd loader function. Determines what to do with a dependency
-	//that was listed in an xd version of a module contents.
-
-	//Extract the dependency(ies).
-	var newDeps = null;
-	var newAfterDeps = null;
-	switch(dep[0]){
-		case "requireIf":
-		case "requireAfterIf":
-			//First arg (dep[1]) is the test. Depedency is dep[2].
-			if(dep[1] === true){
-				newDeps = [{name: dep[2], content: null}];
-			}
-			break;
-		case "platformRequire":
-			var modMap = dep[1];
-			var common = modMap["common"]||[];
-			newDeps = (modMap[dojo.hostenv.name_]) ? common.concat(modMap[dojo.hostenv.name_]||[]) : common.concat(modMap["default"]||[]);
-			//Flatten the array of arrays into a one-level deep array.
-			//Each result could be an array of 3 elements  (the 3 arguments to dojo.require).
-			//We only need the first one.
-			if(newDeps){
-				for(var i = 0; i < newDeps.length; i++){
-					if(newDeps[i] instanceof Array){
-						newDeps[i] = {name: newDeps[i][0], content: null};
-					}else{
-						newDeps[i] = {name: newDeps[i], content: null};
-					}
-				}
-			}
-			break;
-		case "require":
-			//Just worry about dep[1]
-			newDeps = [{name: dep[1], content: null}];
-			break;
-		case "i18n._preloadLocalizations":
-			//We can eval these immediately, since they load i18n bundles.
-			//Since i18n bundles have no dependencies, whenever they are loaded
-			//in a script tag, they are evaluated immediately, so we do not have to
-			//treat them has an explicit dependency for the dependency mapping.
-			//We can call it immediately since dojo.i18n is part of dojo.xd.js.
-			dojo.i18n._preloadLocalizations.apply(dojo.i18n._preloadLocalizations, dep.slice(1));
-			break;
-	}
-
-	//The requireIf and requireAfterIf needs to be evaluated after the current resource is evaluated.
-	if(dep[0] == "requireAfterIf" || dep[0] == "requireIf"){
-		newAfterDeps = newDeps;
-		newDeps = null;
-	}
-	return {requires: newDeps, requiresAfter: newAfterDeps}; //Object
-}
-
-dojo._xdWalkReqs = function(){
-	//summary: Internal xd loader function.
-	//Walks the requires and evaluates module resource contents in
-	//the right order.
-	var reqChain = null;
-	var req;
-	for(var i = 0; i < dojo._xdOrderedReqs.length; i++){
-		req = dojo._xdOrderedReqs[i];
-		if(dojo._xdDepMap[req]){
-			reqChain = [req];
-			reqChain[req] = true; //Allow for fast lookup of the req in the array
-			dojo._xdEvalReqs(reqChain);
-		}
-	}
-}
-
-dojo._xdEvalReqs = function(/*Array*/reqChain){
-	//summary: Internal xd loader function.
-	//Does a depth first, breadth second search and eval of required modules.
-	while(reqChain.length > 0){
-		var req = reqChain[reqChain.length - 1];
-		var res = dojo._xdDepMap[req];
-		var i, reqs, nextReq;
-		if(res){
-			//Trace down any requires for this resource.
-			//START dojo._xdTraceReqs() inlining for small Safari 2.0 call stack
-			reqs = res.requires;
-			if(reqs && reqs.length > 0){
-				for(i = 0; i < reqs.length; i++){
-					nextReq = reqs[i].name;
-					if(nextReq && !reqChain[nextReq]){
-						//New req depedency. Follow it down.
-						reqChain.push(nextReq);
-						reqChain[nextReq] = true;
-						dojo._xdEvalReqs(reqChain);
-					}
-				}
-			}
-			//END dojo._xdTraceReqs() inlining for small Safari 2.0 call stack
-
-			//Evaluate the resource.
-			var contents = dojo._xdContents[res.contentIndex];
-			if(!contents.isDefined){
-				var content = contents.content;
-				content["resourceName"] = contents["resourceName"];
-				content["resourcePath"] = contents["resourcePath"];
-				dojo._xdDefList.push(content);
-				contents.isDefined = true;
-			}
-			dojo._xdDepMap[req] = null;
-
-			//Trace down any requireAfters for this resource.
-			//START dojo._xdTraceReqs() inlining for small Safari 2.0 call stack
-			reqs = res.requiresAfter;
-			if(reqs && reqs.length > 0){
-				for(i = 0; i < reqs.length; i++){
-					nextReq = reqs[i].name;
-					if(nextReq && !reqChain[nextReq]){
-						//New req depedency. Follow it down.
-						reqChain.push(nextReq);
-						reqChain[nextReq] = true;
-						dojo._xdEvalReqs(reqChain);
-					}
-				}
-			}
-			//END dojo._xdTraceReqs() inlining for small Safari 2.0 call stack
-		}
-
-		//Done with that require. Remove it and go to the next one.
-		reqChain.pop();
-	}
-}
-
-dojo._xdWatchInFlight = function(){
-	//summary: Internal xd loader function.
-	//Monitors in-flight requests for xd module resources.
-
-	var noLoads = "";
-	var waitInterval = (dojo.config.xdWaitSeconds || 15) * 1000;
-	var expired = (dojo._xdStartTime + waitInterval) < (new Date()).getTime();
-
-	//If any xdInFlight are true, then still waiting for something to load.
-	//Come back later. If we timed out, report the things that did not load.
-	for(var param in dojo._xdInFlight){
-		if(dojo._xdInFlight[param] === true){
-			if(expired){
-				noLoads += param + " ";
-			}else{
-				return;
-			}
-		}
-	}
-
-	//All done. Clean up and notify.
-	dojo._xdClearInterval();
-
-	if(expired){
-		throw "Could not load cross-domain resources: " + noLoads;
-	}
-
-	dojo._xdWalkReqs();
-	
-	var defLength = dojo._xdDefList.length;
-	for(var i= 0; i < defLength; i++){
-		var content = dojo._xdDefList[i];
-		if(dojo.config["debugAtAllCosts"] && content["resourceName"]){
-			if(!dojo["_xdDebugQueue"]){
-				dojo._xdDebugQueue = [];
-			}
-			dojo._xdDebugQueue.push({resourceName: content.resourceName, resourcePath: content.resourcePath});
-		}else{
-			//Evaluate the resource to bring it into being.
-			//Pass in scope args to allow multiple versions of modules in a page.
-			content.apply(dojo.global, dojo._scopeArgs);
-		}
-	}
-
-	//Evaluate any resources that were not evaled before.
-	//This normally shouldn't happen with proper dojo.provide and dojo.require
-	//usage, but providing it just in case. Note that these may not be executed
-	//in the original order that the developer intended.
-	for(i = 0; i < dojo._xdContents.length; i++){
-		var current = dojo._xdContents[i];
-		if(current.content && !current.isDefined){
-			//Pass in scope args to allow multiple versions of modules in a page.
-			current.content.apply(dojo.global, dojo._scopeArgs);
-		}
-	}
-
-	//Clean up for the next round of xd loading.
-	dojo._xdReset();
-
-	if(dojo["_xdDebugQueue"] && dojo._xdDebugQueue.length > 0){
-		dojo._xdDebugFileLoaded();
-	}else{
-		dojo._xdNotifyLoaded();
-	}
-}
-
-dojo._xdNotifyLoaded = function(){
-	//Clear inflight count so we will finally do finish work.
-
-	//Just having a legitimate status (true or false) for an inflight item
-	//means that it is still being processed. Do the typeof test
-	//to avoid bad JavaScript that might tinker with Object.prototype.
-	for(var prop in dojo._xdInFlight){
-		if(typeof dojo._xdInFlight[prop] == "boolean"){
-			return;
-		}
-	}
-
-	dojo._inFlightCount = 0;
-
-	//Only trigger call loaded if dj_load_init has run.
-	if(dojo._initFired && !dojo._loadNotifying){
-		dojo._callLoaded();
-	}
-}
diff --git a/dojo/_base/array.js b/dojo/_base/array.js
index 7b70349..dc27094 100644
--- a/dojo/_base/array.js
+++ b/dojo/_base/array.js
@@ -1,271 +1,343 @@
-define("dojo/_base/array", ["dojo/lib/kernel", "dojo/_base/lang"], function(dojo){
+define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
+	// module:
+	//		dojo/_base/array
+	// summary:
+	//		This module defines the Javascript v1.6 array extensions.
 
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-(function(){
-	var _getParts = function(arr, obj, cb){
-		return [
-			(typeof arr == "string") ? arr.split("") : arr,
-			obj || dojo.global,
-			// FIXME: cache the anonymous functions we create here?
-			(typeof cb == "string") ? new Function("item", "index", "array", cb) : cb
-		];
+	/*=====
+	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
 	};
-
-	var everyOrSome = function(/*Boolean*/every, /*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
-		var _p = _getParts(arr, thisObject, callback); arr = _p[0];
-		for(var i=0,l=arr.length; i<l; ++i){
-			var result = !!_p[2].call(_p[1], arr[i], i, arr);
-			if(every ^ result){
-				return result; // Boolean
-			}
-		}
-		return every; // Boolean
+	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; });
+	};
+	=====*/
 
-	dojo.mixin(dojo, {
-		indexOf: function(	/*Array*/		array,
-							/*Object*/		value,
-							/*Integer?*/	fromIndex,
-							/*Boolean?*/	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
-
-			var step = 1, end = array.length || 0, i = 0;
-			if(findLast){
-				i = end - 1;
-				step = end = -1;
-			}
-			if(fromIndex != undefined){ i = fromIndex; }
-			if((findLast && i > end) || i < end){
-				for(; i != end; i += step){
-					if(array[i] == value){ return i; }
-				}
-			}
-			return -1;	// Number
-		},
+	// our old simple function builder stuff
+	var cache = {}, u, array; // the export object
 
-		lastIndexOf: function(/*Array*/array, /*Object*/value, /*Integer?*/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
-			return dojo.indexOf(array, value, fromIndex, true); // Number
-		},
+	function clearCache(){
+		cache = {};
+	}
 
-		forEach: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/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 implemenation 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")
-			//	|	);
+	function buildFn(fn){
+		return cache[fn] = new Function("item", "index", "array", fn); // Function
+	}
+	// magic snippet: if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
 
-			// match the behavior of the built-in forEach WRT empty arrs
-			if(!arr || !arr.length){ return; }
+	// every & some
 
-			// FIXME: there are several ways of handilng thisObject. Is
-			// dojo.global always the default context?
-			var _p = _getParts(arr, thisObject, callback); arr = _p[0];
-			for(var i=0,l=arr.length; i<l; ++i){
-				_p[2].call(_p[1], arr[i], i, arr);
+	function everyOrSome(some){
+		var every = !some;
+		return function(a, fn, o){
+			var i = 0, l = a && a.length || 0, result;
+			if(l && typeof a == "string") a = a.split("");
+			if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
+			if(o){
+				for(; i < l; ++i){
+					result = !fn.call(o, a[i], i, a);
+					if(some ^ result){
+						return !result;
+					}
+				}
+			}else{
+				for(; i < l; ++i){
+					result = !fn(a[i], i, a);
+					if(some ^ result){
+						return !result;
+					}
+				}
 			}
-		},
-
-		every: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
-			// summary:
-			//		Determines whether or not every item in arr satisfies the
-			//		condition implemented by callback.
-			// arr:
-			//		the array to iterate on. If a string, operates on individual characters.
-			// callback:
-			//		a function is invoked with three arguments: item, index,
-			//		and array and returns true if the condition is met.
-			// thisObject:
-			//		may be used to scope the call to callback
-			// description:
-			//		This function corresponds to the JavaScript 1.6 Array.every() method, with one difference: when
-			//		run over sparse arrays, this implemenation 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; });
-			return everyOrSome(true, arr, callback, thisObject); // Boolean
-		},
+			return every; // Boolean
+		}
+	}
+	// var every = everyOrSome(false), some = everyOrSome(true);
 
-		some: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
-			// summary:
-			//		Determines whether or not any item in arr satisfies the
-			//		condition implemented by callback.
-			// 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 and returns true if the condition is met.
-			// thisObject:
-			//		may be used to scope the call to callback
-			// description:
-			//		This function corresponds to the JavaScript 1.6 Array.some() method, with one difference: when
-			//		run over sparse arrays, this implemenation 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; });
-			return everyOrSome(false, arr, callback, thisObject); // Boolean
-		},
+	// indexOf, lastIndexOf
 
-		map: function(/*Array|String*/arr, /*Function|String*/callback, /*Function?*/thisObject){
-			// summary:
-			//		applies callback to each element of arr and returns
-			//		an Array with the results
-			// arr:
-			//		the array to iterate on. If a string, operates on
-			//		individual characters.
-			// callback:
-			//		a function is invoked with three arguments, (item, index,
-			//		array),  and returns a value
-			// thisObject:
-			//		may be used to scope the call to callback
-			// description:
-			//		This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when
-			//		run over sparse arrays, this implemenation 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 });
+	function index(up){
+		var delta = 1, lOver = 0, uOver = 0;
+		if(!up){
+			delta = lOver = uOver = -1;
+		}
+		return function(a, x, from, last){
+			if(last && delta > 0){
+				// TODO: why do we use a non-standard signature? why do we need "last"?
+				return array.lastIndexOf(a, x, from);
+			}
+			var l = a && a.length || 0, end = up ? l + uOver : lOver, i;
+			if(from === u){
+				i = up ? lOver : l + uOver;
+			}else{
+				if(from < 0){
+					i = l + from;
+					if(i < 0){
+						i = lOver;
+					}
+				}else{
+					i = from >= l ? l + uOver : from;
+				}
+			}
+			if(l && typeof a == "string") a = a.split("");
+			for(; i != end; i += delta){
+				if(a[i] == x){
+					return i; // Number
+				}
+			}
+			return -1; // Number
+		}
+	}
+	// var indexOf = index(true), lastIndexOf = index(false);
 
-			var _p = _getParts(arr, thisObject, callback); arr = _p[0];
-			var outArr = (arguments[3] ? (new arguments[3]()) : []);
-			for(var i=0,l=arr.length; i<l; ++i){
-				outArr.push(_p[2].call(_p[1], arr[i], i, arr));
+	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);
 			}
-			return outArr; // Array
-		},
+		}
+	}
 
-		filter: function(/*Array*/arr, /*Function|String*/callback, /*Object?*/thisObject){
-			// summary:
-			//		Returns a new Array with those items from arr that match the
-			//		condition implemented by callback.
-			// arr:
-			//		the array to iterate over.
-			// callback:
-			//		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:
-			//		may be used to scope the call to callback
-			// description:
-			//		This function corresponds to the JavaScript 1.6 Array.filter() method, with one difference: when
-			//		run over sparse arrays, this implemenation 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; });
+	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);
+			}
+		}
+		return out; // Array
+	}
 
-			var _p = _getParts(arr, thisObject, callback); arr = _p[0];
-			var outArr = [];
-			for(var i=0,l=arr.length; i<l; ++i){
-				if(_p[2].call(_p[1], arr[i], i, arr)){
-					outArr.push(arr[i]);
+	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);
 				}
 			}
-			return outArr; // Array
-		}
-	});
-})();
-//>>excludeEnd("webkitMobile");
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-/*
-//>>excludeEnd("webkitMobile");
-//>>includeStart("webkitMobile", kwArgs.webkitMobile);
-["indexOf", "lastIndexOf", "forEach", "map", "some", "every", "filter"].forEach(
-	function(name, idx){
-		dojo[name] = function(arr, callback, thisObj){
-			if((idx > 1) && (typeof callback == "string")){
-				callback = new Function("item", "index", "array", callback);
+		}else{
+			for(; i < l; ++i){
+				value = a[i];
+				if(fn(value, i, a)){
+					out.push(value);
+				}
 			}
-			return Array.prototype[name].call(arr, callback, thisObj);
 		}
+		return out; // Array
 	}
-);
-//>>includeEnd("webkitMobile");
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-*/
-//>>excludeEnd("webkitMobile");
 
-return dojo;
+	array = {
+		every:       everyOrSome(false),
+		some:        everyOrSome(true),
+		indexOf:     index(true),
+		lastIndexOf: index(false),
+		forEach:     forEach,
+		map:         map,
+		filter:      filter,
+		clearCache:  clearCache
+	};
+
+	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 0d22201..c367db7 100644
--- a/dojo/_base/browser.js
+++ b/dojo/_base/browser.js
@@ -1,20 +1,21 @@
-define("dojo/_base/browser",[
-
-"dojo/_base/window",
-"dojo/_base/connect",
-"dojo/_base/event",
-"dojo/_base/html",
-"dojo/_base/NodeList",
-"dojo/_base/query",
-"dojo/_base/xhr",
-"dojo/_base/fx"
-], function(){
-	//Need this to be the last code segment in base, so do not place any
-	//dojo/requireIf calls in this file/ Otherwise, due to how the build system
-	//puts all requireIf dependencies after the current file, the require calls
-	//could be called before all of base is defined/
-	dojo.forEach(dojo.config.require, function(i){
-		dojo["require"](i);
-	});
+if(require.has){
+	require.has.add("config-selectorEngine", "acme");
+}
+define([
+	"../ready",
+	"./kernel",
+	"./connect", // until we decide if connect is going back into non-browser environments
+	"./unload",
+	"./window",
+	"./event",
+	"./html",
+	"./NodeList",
+	"../query",
+	"./xhr",
+	"./fx"], function(dojo) {
+	// module:
+	//		dojo/_base/browser
+	// 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
new file mode 100644
index 0000000..aa0cb9b
--- /dev/null
+++ b/dojo/_base/config.js
@@ -0,0 +1,174 @@
+define(["../has", "require"], function(has, require){
+	// module:
+	//		dojo/_base/config
+	// 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
+	//		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
+	//		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
+	//		|	define("myDojo/config", {
+	//		|		// normal configuration variables go here, e.g.,
+	//		|		locale:"fr-ca"
+	//		|	});
+	//		|
+	//		|	// load and use the new instance of 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
+	//		on your platform, setting `isDebug` to `true` will force Dojo to
+	//		pull in (and display) the version of Firebug Lite which is
+	//		integrated into the Dojo distribution, thereby always providing a
+	//		debugging/logging console when `isDebug` is enabled. Note that
+	//		Firebug's `console.*` methods are ALWAYS defined by Dojo. If
+	//		`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).
+	//		Must be specified entirely in lowercase, e.g. `en-us` and `zh-cn`.
+	//		See the documentation for `dojo.i18n` and `dojo.requireLocalization`
+	//		for details on loading localized resources. If no locale is specified,
+	//		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
+	//		was loaded. You may need to manually configure `baseUrl` in cases
+	//		where you have renamed `dojo.js` or in which `<base>` tags confuse
+	//		some browsers (e.g. IE 6). The variable `dojo.baseUrl` is assigned
+	//		either the value of `djConfig.baseUrl` if one is provided or the
+	//		auto-detected root if not. Other modules are located relative to
+	//		this path. The path should end in a slash.
+	baseUrl: undefined,
+	// modulePaths: 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
+	//		`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
+	//		the page loads and djConfig.afterOnLoad is true. Supports the same
+	//		arguments as dojo.addOnLoad. 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
+	//		An array of module names to be loaded immediately after dojo.js has been included
+	//		in a page.
+	require: [],
+	// defaultDuration: Array
+	//		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
+	//		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?
+	//		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
+	//		of topics that are published.
+	ioPublish: false,
+	//	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
+}
+=====*/
+});
+
diff --git a/dojo/_base/configFirefoxExtension.js b/dojo/_base/configFirefoxExtension.js
new file mode 100644
index 0000000..ce30c91
--- /dev/null
+++ b/dojo/_base/configFirefoxExtension.js
@@ -0,0 +1,334 @@
+// TODO: this file needs to be converted to the v1.7 loader
+
+// a host environment specifically built for Mozilla extensions, but derived
+// from the browser host environment
+if(typeof window != 'undefined'){
+	dojo.isBrowser = true;
+	dojo._name = "browser";
+
+
+	// FIXME: PORTME
+	//	http://developer.mozilla.org/en/mozIJSSubScriptLoader
+
+
+	// attempt to figure out the path to dojo if it isn't set in the config
+	(function(){
+		// this is a scope protection closure. We set browser versions and grab
+		// the URL we were loaded from here.
+
+		// FIXME: need to probably use a different reference to "document" to get the hosting XUL environment
+
+		dojo.baseUrl = dojo.config.baseUrl;
+
+		// fill in the rendering support information in dojo.render.*
+		var n = navigator;
+		var dua = n.userAgent;
+		var dav = n.appVersion;
+		var tv = parseFloat(dav);
+
+		dojo.isMozilla = dojo.isMoz = tv;
+		if(dojo.isMoz){
+			dojo.isFF = parseFloat(dua.split("Firefox/")[1]) || undefined;
+		}
+
+		// FIXME
+		dojo.isQuirks = document.compatMode == "BackCompat";
+
+		// FIXME
+		// TODO: is the HTML LANG attribute relevant?
+		dojo.locale = dojo.config.locale || n.language.toLowerCase();
+
+		dojo._xhrObj = function(){
+			return new XMLHttpRequest();
+		};
+
+		// monkey-patch _loadUri to handle file://, chrome://, and resource:// url's
+		var oldLoadUri = dojo._loadUri;
+		dojo._loadUri = function(uri, cb){
+			var handleLocal = ["file:", "chrome:", "resource:"].some(function(prefix){
+				return String(uri).indexOf(prefix) == 0;
+			});
+			if(handleLocal){
+				// see:
+				//		http://developer.mozilla.org/en/mozIJSSubScriptLoader
+				var l = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
+					.getService(Components.interfaces.mozIJSSubScriptLoader);
+				var value = l.loadSubScript(uri, dojo.global);
+				if(cb){ cb(value); }
+				return true;
+			}else{
+				// otherwise, call the pre-existing version
+				return oldLoadUri.apply(dojo, arguments);
+			}
+		};
+
+		// FIXME: PORTME
+		dojo._isDocumentOk = function(http){
+			var stat = http.status || 0;
+			return (stat >= 200 && stat < 300) || 	// Boolean
+				stat == 304 || 						// allow any 2XX response code
+				stat == 1223 || 						// get it out of the cache
+				(!stat && (location.protocol == "file:" || location.protocol == "chrome:") );
+		};
+
+		// FIXME: PORTME
+		// var owloc = window.location+"";
+		// var base = document.getElementsByTagName("base");
+		// var hasBase = (base && base.length > 0);
+		var hasBase = false;
+
+		dojo._getText = function(/*URI*/ uri, /*Boolean*/ fail_ok){
+			// 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
+			//		failure and failure is okay (an exception otherwise)
+
+			// alert("_getText: " + uri);
+
+			// NOTE: must be declared before scope switches ie. this._xhrObj()
+			var http = dojo._xhrObj();
+
+			if(!hasBase && dojo._Url){
+				uri = (new dojo._Url(uri)).toString();
+			}
+			if(dojo.config.cacheBust){
+				//Make sure we have a string before string methods are used on uri
+				uri += "";
+				uri += (uri.indexOf("?") == -1 ? "?" : "&") + String(dojo.config.cacheBust).replace(/\W+/g, "");
+			}
+			var handleLocal = ["file:", "chrome:", "resource:"].some(function(prefix){
+				return String(uri).indexOf(prefix) == 0;
+			});
+			if(handleLocal){
+				// see:
+				//		http://forums.mozillazine.org/viewtopic.php?p=921150#921150
+				var ioService = Components.classes["@mozilla.org/network/io-service;1"]
+					.getService(Components.interfaces.nsIIOService);
+				var scriptableStream = Components
+					.classes["@mozilla.org/scriptableinputstream;1"]
+					.getService(Components.interfaces.nsIScriptableInputStream);
+
+				var channel = ioService.newChannel(uri, null, null);
+				var input = channel.open();
+				scriptableStream.init(input);
+				var str = scriptableStream.read(input.available());
+				scriptableStream.close();
+				input.close();
+				return str;
+			}else{
+				http.open('GET', uri, false);
+				try{
+					http.send(null);
+					// alert(http);
+					if(!dojo._isDocumentOk(http)){
+						var err = Error("Unable to load " + uri + " status:" + http.status);
+						err.status = http.status;
+						err.responseText = http.responseText;
+						throw err;
+					}
+				}catch(e){
+					if(fail_ok){
+						return null;
+					} // null
+					// rethrow the exception
+					throw e;
+				}
+				return http.responseText; // String
+			}
+		};
+
+		dojo._windowUnloaders = [];
+
+		// FIXME: PORTME
+		dojo.windowUnloaded = function(){
+			// summary:
+			//		signal fired by impending window destruction. You may use
+			//		dojo.addOnWIndowUnload() or dojo.connect() to this method to perform
+			//		page/application cleanup methods. See dojo.addOnWindowUnload for more info.
+			var mll = dojo._windowUnloaders;
+			while(mll.length){
+				(mll.pop())();
+			}
+		};
+
+		// FIXME: PORTME
+		dojo.addOnWindowUnload = function(/*Object?*/obj, /*String|Function?*/functionName){
+			// summary:
+			//		registers a function to be triggered when window.onunload fires.
+			//		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.
+			// example:
+			//	|	dojo.addOnWindowUnload(functionPointer)
+			//	|	dojo.addOnWindowUnload(object, "functionName")
+			//	|	dojo.addOnWindowUnload(object, function(){ /* ... */});
+
+			dojo._onto(dojo._windowUnloaders, obj, functionName);
+		};
+
+		// XUL specific APIs
+		var contexts = [];
+		var current = null;
+		dojo._defaultContext = [ window, document ];
+
+		dojo.pushContext = function(/*Object|String?*/g, /*MDocumentElement?*/d){
+			//	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:
+			//		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
+			//		"return" to a previous context, whereas the
+			//		dojo.pushContext and dojo.popContext methods provide a more
+			//		natural way to augment blocks of code to ensure that they
+			//		execute in a different window or frame without issue. If
+			//		called without any arguments, the default context (the
+			//		context when Dojo is first loaded) is instead pushed into
+			//		the stack. If only a single string is passed, a node in the
+			//		intitial context's document is looked up and its
+			//		contextWindow and contextDocument properties are used as
+			//		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:
+			//		The global context. If a string, the id of the frame to
+			//		search for a context and document.
+			//	d:
+			//		The document element to execute subsequent code with.
+			var old = [dojo.global, dojo.doc];
+			contexts.push(old);
+			var n;
+			if(!g && !d){
+				n = dojo._defaultContext;
+			}else{
+				n = [ g, d ];
+				if(!d && dojo.isString(g)){
+					var t = document.getElementById(g);
+					if(t.contentDocument){
+						n = [t.contentWindow, t.contentDocument];
+					}
+				}
+			}
+			current = n;
+			dojo.setContext.apply(dojo, n);
+			return old; // Array
+		};
+
+		dojo.popContext = function(){
+			//	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,
+			//		document]) is returned.
+			var oc = current;
+			if(!contexts.length){
+				return oc;
+			}
+			dojo.setContext.apply(dojo, contexts.pop());
+			return oc;
+		};
+
+		// FIXME:
+		//		don't really like the current arguments and order to
+		//		_inContext, so don't make it public until it's right!
+		dojo._inContext = function(g, d, f){
+			var a = dojo._toArray(arguments);
+			f = a.pop();
+			if(a.length == 1){
+				d = null;
+			}
+			dojo.pushContext(g, d);
+			var r = f();
+			dojo.popContext();
+			return r;
+		};
+
+	})();
+
+	dojo._initFired = false;
+	//	BEGIN DOMContentLoaded, from Dean Edwards (http://dean.edwards.name/weblog/2006/06/again/)
+	dojo._loadInit = function(e){
+		dojo._initFired = true;
+		// allow multiple calls, only first one will take effect
+		// A bug in khtml calls events callbacks for document for event which isnt supported
+		// for example a created contextmenu event calls DOMContentLoaded, workaround
+		var type = (e && e.type) ? e.type.toLowerCase() : "load";
+		if(arguments.callee.initialized || (type != "domcontentloaded" && type != "load")){ return; }
+		arguments.callee.initialized = true;
+		if(dojo._inFlightCount == 0){
+			dojo._modulesLoaded();
+		}
+	};
+
+	/*
+	(function(){
+		var _w = window;
+		var _handleNodeEvent = function(evtName, fp){
+			// summary:
+			//		non-destructively adds the specified function to the node's
+			//		evtName handler.
+			// evtName: should be in the form "onclick" for "onclick" handlers.
+			// Make sure you pass in the "on" part.
+			var oldHandler = _w[evtName] || function(){};
+			_w[evtName] = function(){
+				fp.apply(_w, arguments);
+				oldHandler.apply(_w, arguments);
+			};
+		};
+		// FIXME: PORT
+		// FIXME: dojo.unloaded requires dojo scope, so using anon function wrapper.
+		_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
+	if(!dojo.config.afterOnLoad){
+		window.addEventListener("DOMContentLoaded", function(e){
+			dojo._loadInit(e);
+			// console.log("DOM content loaded", e);
+		}, false);
+	}
+
+} //if (typeof window != 'undefined')
+
+//Register any module paths set up in djConfig. Need to do this
+//in the hostenvs since hostenv_browser can read djConfig from a
+//script tag's attribute.
+(function(){
+	var mp = dojo.config["modulePaths"];
+	if(mp){
+		for(var param in mp){
+			dojo.registerModulePath(param, mp[param]);
+		}
+	}
+})();
+
+//Load debug code if necessary.
+if(dojo.config.isDebug){
+	// logging stub for extension logging
+	console.log = function(m){
+		var s = Components.classes["@mozilla.org/consoleservice;1"].getService(
+			Components.interfaces.nsIConsoleService
+			);
+		s.logStringMessage(m);
+	};
+	console.debug = function(){
+		console.log(dojo._toArray(arguments).join(" "));
+	};
+	// FIXME: what about the rest of the console.* methods? And is there any way to reach into firebug and log into it directly?
+}
diff --git a/dojo/_base/configNode.js b/dojo/_base/configNode.js
new file mode 100644
index 0000000..7cd6f14
--- /dev/null
+++ b/dojo/_base/configNode.js
@@ -0,0 +1,87 @@
+exports.config = function(config){
+	//	summary:
+	//		This module provides bootstrap configuration for running dojo in node.js
+
+	// any command line arguments with the load flag are pushed into deps
+	for(var deps = [], args = [], i = 0; i < process.argv.length; i++){
+		var arg = (process.argv[i] + "").split("=");
+		if(arg[0] == "load"){
+			deps.push(arg[1]);
+		}else{
+			args.push(arg);
+		}
+	}
+
+	var fs = require("fs");
+
+	// make sure global require exists
+	//if (typeof global.require=="undefined") {
+	//	global.require= {};
+	//}
+
+	// reset the has cache with node-appropriate values;
+	var hasCache = {
+		"host-node":1,
+		"host-browser":0,
+		"dom":0,
+		"dojo-has-api":1,
+		"dojo-xhr-factory":0,
+		"dojo-inject-api":1,
+		"dojo-timeout-api":0,
+		"dojo-trace-api":1,
+		"dojo-dom-ready-api":0,
+		"dojo-publish-privates":1,
+		"dojo-sniff":0,
+		"dojo-loader":1,
+		"dojo-test-xd":0,
+		"dojo-test-sniff":0
+	};
+	for(var p in hasCache){
+		config.hasCache[p] = hasCache[p];
+	}
+
+	var vm = require('vm');
+
+
+	// reset some configuration switches with node-appropriate values
+	var nodeConfig = {
+		baseUrl: __dirname.match(/(.+)[\/\\]_base$/)[1],
+		commandLineArgs:args,
+		deps:deps,
+		timeout:0,
+
+		// TODO: really get the locale
+		locale:"en-us",
+
+		loaderPatch: {
+			log:function(item){
+				// define debug for console messages during dev instead of console.log
+				// (node's heavy async makes console.log confusing sometimes)
+				var util = require("util");
+				util.debug(util.inspect(item));
+			},
+
+			eval: function(__text, __urlHint){
+				return vm.runInThisContext(__text, __urlHint);
+			},
+
+			injectUrl: function(url, callback){
+				try{
+					vm.runInThisContext(fs.readFileSync(url, "utf8"), url);
+					callback();
+				}catch(e){
+					this.log("failed to load resource (" + url + ")");
+					this.log(e);
+				}
+			},
+
+			getText: function(url, sync, onLoad){
+				// TODO: implement async and http/https handling
+				onLoad(fs.readFileSync(url, "utf8"));
+			}
+		}
+	};
+	for(p in nodeConfig){
+		config[p] = nodeConfig[p];
+	}
+};
diff --git a/dojo/_base/configRhino.js b/dojo/_base/configRhino.js
new file mode 100644
index 0000000..ec64759
--- /dev/null
+++ b/dojo/_base/configRhino.js
@@ -0,0 +1,121 @@
+function rhinoDojoConfig(config, baseUrl, rhinoArgs){
+	//	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?
+
+	// get a minimal console up
+	var log = function(hint, args){
+		print((hint ? hint + ":" : "") + args[0]);
+		for(var i = 1; i < args.length; i++){
+			print(", " + args[i]);
+		}
+	};
+	// intentionally define console in the global namespace
+	console= {
+		log: function(){ log(0, arguments); },
+		error: function(){ log("ERROR", arguments); },
+		warn: function(){ log("WARN", arguments); }
+	};
+
+	// any command line arguments with the load flag are pushed into deps
+	for(var deps = [], i = 0; i < rhinoArgs.length; i++){
+		var arg = (rhinoArgs[i] + "").split("=");
+		if(arg[0] == "load"){
+			deps.push(arg[1]);
+		}
+	}
+
+	// provides timed callbacks using Java threads
+	if(typeof setTimeout == "undefined" || typeof clearTimeout == "undefined"){
+		var timeouts = [];
+		clearTimeout = function(idx){
+			if(!timeouts[idx]){ return; }
+			timeouts[idx].stop();
+		};
+
+		setTimeout = function(func, delay){
+			var def = {
+				sleepTime:delay,
+				hasSlept:false,
+
+				run:function(){
+					if(!this.hasSlept){
+						this.hasSlept = true;
+						java.lang.Thread.currentThread().sleep(this.sleepTime);
+					}
+					try{
+						func();
+					}catch(e){
+						console.debug("Error running setTimeout thread:" + e);
+					}
+				}
+			};
+
+			var runnable = new java.lang.Runnable(def);
+			var thread = new java.lang.Thread(runnable);
+			thread.start();
+			return timeouts.push(thread) - 1;
+		};
+	}
+
+	var isLocal = function(url){
+		return (new java.io.File(url)).exists();
+	};
+
+	// reset the has cache with node-appropriate values;
+	var hasCache = {
+		"host-rhino":1,
+		"host-browser":0,
+		"dom":0,
+		"dojo-has-api":1,
+		"dojo-xhr-factory":0,
+		"dojo-inject-api":1,
+		"dojo-timeout-api":0,
+		"dojo-trace-api":1,
+		"dojo-loader-catches":1,
+		"dojo-dom-ready-api":0,
+		"dojo-publish-privates":1,
+		"dojo-sniff":0,
+		"dojo-loader":1,
+		"dojo-test-xd":0,
+		"dojo-test-sniff":0
+	};
+	for(var p in hasCache){
+		config.hasCache[p] = hasCache[p];
+	}
+
+	// reset some configuration switches with rhino-appropriate values
+	var rhinoConfig = {
+		baseUrl:baseUrl,
+		commandLineArgs:rhinoArgs,
+		deps:deps,
+		timeout:0,
+		locale:String(java.util.Locale.getDefault().toString().replace('_', '-').toLowerCase()),
+
+		loaderPatch:{
+			injectUrl: function(url, callback){
+				try{
+					if(isLocal(url)){
+						load(url);
+					}else{
+						require.eval(readUrl(url, "UTF-8"));
+					}
+					callback();
+				}catch(e){
+					console.log("failed to load resource (" + url + ")");
+					console.log(e);
+				}
+			},
+
+			getText: function(url, sync, onLoad){
+				// TODO: test https://bugzilla.mozilla.org/show_bug.cgi?id=471005; see v1.6 hostenv_rhino
+				// note: async mode not supported in rhino
+				onLoad(isLocal(url) ? readFile(url, "UTF-8") : readUrl(url, "UTF-8"));
+			}
+		}
+	};
+	for(p in rhinoConfig){
+		config[p] = rhinoConfig[p];
+	}
+}
diff --git a/dojo/_base/configSpidermonkey.js b/dojo/_base/configSpidermonkey.js
new file mode 100644
index 0000000..0da0d71
--- /dev/null
+++ b/dojo/_base/configSpidermonkey.js
@@ -0,0 +1,84 @@
+// TODO: this file needs to be converted to the v1.7 loader
+
+
+/*
+ * SpiderMonkey host environment
+ */
+
+if(dojo.config["baseUrl"]){
+	dojo.baseUrl = dojo.config["baseUrl"];
+}else{
+	dojo.baseUrl = "./";
+}
+
+dojo._name = 'spidermonkey';
+
+/*=====
+dojo.isSpidermonkey = {
+	// summary: Detect spidermonkey
+};
+=====*/
+
+dojo.isSpidermonkey = true;
+dojo.exit = function(exitcode){
+	quit(exitcode);
+};
+
+if(typeof print == "function"){
+	console.debug = print;
+}
+
+if(typeof line2pc == 'undefined'){
+	throw new Error("attempt to use SpiderMonkey host environment when no 'line2pc' global");
+}
+
+dojo._spidermonkeyCurrentFile = function(depth){
+	//
+	//	This is a hack that determines the current script file by parsing a
+	//	generated stack trace (relying on the non-standard "stack" member variable
+	//	of the SpiderMonkey Error object).
+	//
+	//	If param depth is passed in, it'll return the script file which is that far down
+	//	the stack, but that does require that you know how deep your stack is when you are
+	//	calling.
+	//
+	var s = '';
+	try{
+		throw Error("whatever");
+	}catch(e){
+		s = e.stack;
+	}
+	// lines are like: bu_getCurrentScriptURI_spidermonkey("ScriptLoader.js")@burst/Runtime.js:101
+	var matches = s.match(/[^@]*\.js/gi);
+	if(!matches){
+		throw Error("could not parse stack string: '" + s + "'");
+	}
+	var fname = (typeof depth != 'undefined' && depth) ? matches[depth + 1] : matches[matches.length - 1];
+	if(!fname){
+		throw Error("could not find file name in stack string '" + s + "'");
+	}
+	//print("SpiderMonkeyRuntime got fname '" + fname + "' from stack string '" + s + "'");
+	return fname;
+};
+
+// print(dojo._spidermonkeyCurrentFile(0));
+
+dojo._loadUri = function(uri){
+	// spidermonkey load() evaluates the contents into the global scope (which
+	// is what we want).
+	// TODO: sigh, load() does not return a useful value.
+	// Perhaps it is returning the value of the last thing evaluated?
+	// var ok =
+	load(uri);
+	// console.log("spidermonkey load(", uri, ") returned ", ok);
+	return 1;
+};
+
+//Register any module paths set up in djConfig. Need to do this
+//in the hostenvs since hostenv_browser can read djConfig from a
+//script tag's attribute.
+if(dojo.config["modulePaths"]){
+	for(var param in dojo.config["modulePaths"]){
+		dojo.registerModulePath(param, dojo.config["modulePaths"][param]);
+	}
+}
diff --git a/dojo/_base/connect.js b/dojo/_base/connect.js
index 81d97a1..fba6770 100644
--- a/dojo/_base/connect.js
+++ b/dojo/_base/connect.js
@@ -1,89 +1,214 @@
-define("dojo/_base/connect", ["dojo/lib/kernel", "dojo/_base/lang"], function(dojo){
+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.
+has.add("events-keypress-typed", function(){ // keypresses should only occur a printable character is hit
+	var testKeyEvent = {charCode: 0};
+	try{
+		testKeyEvent = document.createEvent("KeyboardEvent");
+		(testKeyEvent.initKeyboardEvent || testKeyEvent.initKeyEvent).call(testKeyEvent, "keypress", true, true, null, false, false, false, false, 9, 3);
+	}catch(e){}
+	return testKeyEvent.charCode == 0 && !has("opera");
+});
 
-// this file courtesy of the TurboAjax Group, licensed under a Dojo CLA
+function connect_(obj, event, context, method, dontFix){
+	method = lang.hitch(context, method);
+	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);
+	}
+	if(typeof event == "string" && event.substring(0, 2) == "on"){
+		event = event.substring(2);
+	}
+	if(!obj){
+		obj = kernel.global;
+	}
+	if(!dontFix){
+		switch(event){
+			// dojo.connect has special handling for these event types
+			case "keypress":
+				event = keypress;
+				break;
+			case "mouseenter":
+				event = mouse.enter;
+				break;
+			case "mouseleave":
+				event = mouse.leave;
+				break;
+		}
+	}
+	return on(obj, event, method, dontFix);
+}
 
-// low-level delegation machinery
-dojo._listener = {
-	// create a dispatcher function
-	getDispatcher: function(){
-		// following comments pulled out-of-line to prevent cloning them
-		// in the returned function.
-		// - indices (i) that are really in the array of listeners (ls) will
-		//   not be in Array.prototype. This is the 'sparse array' trick
-		//   that keeps us safe from libs that take liberties with built-in
-		//   objects
-		// - listener is invoked with current scope (this)
-		return function(){
-			var ap = Array.prototype, c = arguments.callee, ls = c._listeners, t = c.target,
-			// return value comes from original target function
-				r = t && t.apply(this, arguments),
-			// make local copy of listener array so it is immutable during processing
-				i, lls = [].concat(ls)
-			;
+var _punctMap = {
+	106:42,
+	111:47,
+	186:59,
+	187:43,
+	188:44,
+	189:45,
+	190:46,
+	191:47,
+	192:96,
+	219:91,
+	220:92,
+	221:93,
+	222:39,
+	229:113
+};
+var evtCopyKey = has("mac") ? "metaKey" : "ctrlKey";
 
-			// invoke listeners after target function
-			for(i in lls){
-				if(!(i in ap)){
-					lls[i].apply(this, arguments);
+
+var _synthesizeEvent = function(evt, props){
+	var faux = lang.mixin({}, evt, props);
+	setKeyChar(faux);
+	// FIXME: would prefer to use lang.hitch: lang.hitch(evt, evt.preventDefault);
+	// but it throws an error when preventDefault is invoked on Safari
+	// does Event.preventDefault not support "apply" on Safari?
+	faux.preventDefault = function(){ evt.preventDefault(); };
+	faux.stopPropagation = function(){ evt.stopPropagation(); };
+	return faux;
+};
+function setKeyChar(evt){
+	evt.keyChar = evt.charCode ? String.fromCharCode(evt.charCode) : '';
+	evt.charOrCode = evt.keyChar || evt.keyCode;
+}
+var keypress;
+if(has("events-keypress-typed")){
+	// this emulates Firefox's keypress behavior where every keydown can correspond to a keypress
+	var _trySetKeyCode = function(e, code){
+		try{
+			// squelch errors when keyCode is read-only
+			// (e.g. if keyCode is ctrl or shift)
+			return (e.keyCode = code);
+		}catch(e){
+			return 0;
+		}
+	};
+	keypress = function(object, listener){
+		var keydownSignal = on(object, "keydown", function(evt){
+			// munge key/charCode
+			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;
+			// synthesize keypress for most unprintables and CTRL-keys
+			if(unprintable||evt.ctrlKey){
+				var c = unprintable ? 0 : k;
+				if(evt.ctrlKey){
+					if(k==3 || k==13){
+						return listener.call(evt.currentTarget, evt); // IE will post CTRL-BREAK, CTRL-ENTER as keypress natively
+					}else if(c>95 && c<106){
+						c -= 48; // map CTRL-[numpad 0-9] to ASCII
+					}else if((!evt.shiftKey)&&(c>=65&&c<=90)){
+						c += 32; // map CTRL-[A-Z] to lowercase
+					}else{
+						c = _punctMap[c] || c; // map other problematic CTRL combinations to ASCII
+					}
 				}
+				// simulate a keypress event
+				var faux = _synthesizeEvent(evt, {type: 'keypress', faux: true, charCode: c});
+				listener.call(evt.currentTarget, faux);
+				if(has("ie")){
+					_trySetKeyCode(evt, faux.keyCode);
+				}
+			}
+		});
+		var keypressSignal = on(object, "keypress", function(evt){
+			var c = evt.charCode;
+			c = c>=32 ? c : 0;
+			evt = _synthesizeEvent(evt, {charCode: c, faux: true});
+			return listener.call(this, evt);
+		});
+		return {
+			remove: function(){
+				keydownSignal.remove();
+				keypressSignal.remove();
 			}
-			// return value comes from original target function
-			return r;
 		};
+	};
+}else{
+	if(has("opera")){
+		keypress = function(object, listener){
+			return on(object, "keypress", function(evt){
+				var c = evt.which;
+				if(c==3){
+					c=99; // Mozilla maps CTRL-BREAK to CTRL-c
+				}
+				// can't trap some keys at all, like INSERT and DELETE
+				// there is no differentiating info between DELETE and ".", or INSERT and "-"
+				c = c<32 && !evt.shiftKey ? 0 : c;
+				if(evt.ctrlKey && !evt.shiftKey && c>=65 && c<=90){
+					// lowercase CTRL-[A-Z] keys
+					c += 32;
+				}
+				return listener.call(this, _synthesizeEvent(evt, { charCode: c }));
+			});
+		};
+	}else{
+		keypress = function(object, listener){
+			return on(object, "keypress", function(evt){
+				setKeyChar(evt);
+				return listener.call(this, evt);
+			});
+		};
+	}
+}
+
+var connect = {
+	_keypress:keypress,
+
+	connect:function(obj, event, context, method, dontFix){
+		// normalize arguments
+		var a=arguments, args=[], i=0;
+		// if a[0] is a String, obj was omitted
+		args.push(typeof a[0] == "string" ? null : a[i++], a[i++]);
+		// if the arg-after-next is a String or Function, context was NOT omitted
+		var a1 = a[i+1];
+		args.push(typeof a1 == "string" || typeof a1 == "function" ? a[i++] : null, a[i++]);
+		// absorb any additional arguments
+		for(var l=a.length; i<l; i++){	args.push(a[i]); }
+		return connect_.apply(this, args);
 	},
-	// add a listener to an object
-	add: function(/*Object*/ source, /*String*/ method, /*Function*/ listener){
-		// Whenever 'method' is invoked, 'listener' will have the same scope.
-		// Trying to supporting a context object for the listener led to
-		// complexity.
-		// Non trivial to provide 'once' functionality here
-		// because listener could be the result of a dojo.hitch call,
-		// in which case two references to the same hitch target would not
-		// be equivalent.
-		source = source || dojo.global;
-		// The source method is either null, a dispatcher, or some other function
-		var f = source[method];
-		// Ensure a dispatcher
-		if(!f || !f._listeners){
-			var d = dojo._listener.getDispatcher();
-			// original target function is special
-			d.target = f;
-			// dispatcher holds a list of listeners
-			d._listeners = [];
-			// redirect source to dispatcher
-			f = source[method] = d;
+
+	disconnect:function(handle){
+		if(handle){
+			handle.remove();
 		}
-		// The contract is that a handle is returned that can
-		// identify this listener for disconnect.
-		//
-		// The type of the handle is private. Here is it implemented as Integer.
-		// DOM event code has this same contract but handle is Function
-		// in non-IE browsers.
-		//
-		// We could have separate lists of before and after listeners.
-		return f._listeners.push(listener); /*Handle*/
 	},
-	// remove a listener from an object
-	remove: function(/*Object*/ source, /*String*/ method, /*Handle*/ handle){
-		var f = (source || dojo.global)[method];
-		// remember that handle is the index+1 (0 is not a valid handle)
-		if(f && f._listeners && handle--){
-			delete f._listeners[handle];
-		}
+
+	subscribe:function(topic, context, method){
+		return hub.subscribe(topic, lang.hitch(context, method));
+	},
+
+	publish:function(topic, args){
+		return hub.publish.apply(hub, [topic].concat(args));
+	},
+
+	connectPublisher:function(topic, obj, event){
+		var pf = function(){ connect.publish(topic, arguments); };
+		return event ? connect.connect(obj, event, pf) : connect.connect(obj, pf); //Handle
+	},
+
+	isCopyKey: function(e){
+		return e[evtCopyKey];	// Boolean
 	}
 };
+connect.unsubscribe = connect.disconnect;
 
-// Multiple delegation for arbitrary methods.
-
-// This unit knows nothing about DOM, but we include DOM aware documentation
-// and dontFix argument here to help the autodocs. Actual DOM aware code is in
-// event.js.
+has("extend-dojo") && lang.mixin(kernel, connect);
+return connect;
 
-dojo.connect = function(/*Object|null*/ obj,
-						/*String*/ event,
-						/*Object|null*/ context,
-						/*String|Function*/ method,
-						/*Boolean?*/ dontFix){
+/*=====
+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
@@ -105,7 +230,7 @@ dojo.connect = function(/*Object|null*/ obj,
 	//
 	//		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, `dojo.global` is assumed, meaning that connections
+	//		`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.
@@ -119,17 +244,17 @@ dojo.connect = function(/*Object|null*/ obj,
 	//		The return value is a handle that is needed to
 	//		remove this connection with `dojo.disconnect`.
 	//
-	// obj:
+	// obj: Object|null:
 	//		The source object for the event function.
-	//		Defaults to `dojo.global` if null.
+	//		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:
+	// event: String:
 	//		String name of the event function in obj.
 	//		I.e. identifies a property `obj[event]`.
 	//
-	// context:
+	// context: Object|null
 	//		The object that method will receive as "this".
 	//
 	//		If context is null and method is a function, then method
@@ -137,15 +262,15 @@ dojo.connect = function(/*Object|null*/ obj,
 	//
 	//		If method is a string then context must be the source
 	//		object object for method (context[method]). If context is null,
-	//		dojo.global is used.
+	//		kernel.global is used.
 	//
-	// method:
+	// 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:
+	// dontFix: Boolean?
 	//		If obj is a DOM node, set dontFix to true to prevent delegation
 	//		of this connection to the DOM event manager.
 	//
@@ -180,122 +305,96 @@ dojo.connect = function(/*Object|null*/ obj,
 	//		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
-	args.push(dojo.isString(a[0]) ? null : a[i++], a[i++]);
-	// if the arg-after-next is a String or Function, context was NOT omitted
-	var a1 = a[i+1];
-	args.push(dojo.isString(a1)||dojo.isFunction(a1) ? a[i++] : null, a[i++]);
-	// absorb any additional arguments
-	for(var l=a.length; i<l; i++){	args.push(a[i]); }
-	// do the actual work
-	return dojo._connect.apply(this, args); /*Handle*/
 }
+=====*/
 
-// used by non-browser hostenvs. always overriden by event.js
-dojo._connect = function(obj, event, context, method){
-	var l=dojo._listener, h=l.add(obj, event, dojo.hitch(context, method));
-	return [obj, event, h, l]; // Handle
-};
-
-dojo.disconnect = function(/*Handle*/ handle){
+/*=====
+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: Handle:
 	//		the return value of the dojo.connect call that created the connection.
-	if(handle && handle[0] !== undefined){
-		dojo._disconnect.apply(this, handle);
-		// let's not keep this reference
-		delete handle[0];
-	}
-};
-
-dojo._disconnect = function(obj, event, handle, listener){
-	listener.remove(obj, event, handle);
-};
-
-// topic publish/subscribe
-
-dojo._topics = {};
+}
+=====*/
 
-dojo.subscribe = function(/*String*/ topic, /*Object|null*/ context, /*String|Function*/ method){
+/*=====
+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.
-	//	context:
+	//	topic: String:
+	//		The topic to which to subscribe.
+	//	context: Object|null:
 	//		Scope in which method will be invoked, or null for default scope.
-	//	method:
+	//	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" ]);
+}
+=====*/
 
-	// support for 2 argument invocation (omitting context) depends on hitch
-	return [topic, dojo._listener.add(dojo._topics, topic, dojo.hitch(context, method))]; /*Handle*/
-};
-
-dojo.unsubscribe = function(/*Handle*/ handle){
+/*=====
+dojo.unsubscribe = function(handle){
 	//	summary:
-	//	 	Remove a topic listener.
-	//	handle:
-	//	 	The handle returned from a call to subscribe.
+	//		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);
-	if(handle){
-		dojo._listener.remove(dojo._topics, handle[0], handle[1]);
-	}
-};
+}
+=====*/
 
-dojo.publish = function(/*String*/ topic, /*Array*/ args){
+/*=====
+dojo.publish = function(topic, args){
 	//	summary:
-	//	 	Invoke all listener method subscribed to topic.
-	//	topic:
-	//	 	The name of the topic to publish.
-	//	args:
-	//	 	An array of arguments. The arguments will be applied
-	//	 	to each topic subscriber (as first class parameters, via apply).
+	//		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" ]);
+}
+=====*/
 
-	// Note that args is an array, which is more efficient vs variable length
-	// argument list.  Ideally, var args would be implemented via Array
-	// throughout the APIs.
-	var f = dojo._topics[topic];
-	if(f){
-		f.apply(this, args||[]);
-	}
-};
-
-dojo.connectPublisher = function(	/*String*/ topic,
-									/*Object|null*/ obj,
-									/*String*/ event){
+/*=====
+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:
-	//	 	The name of the topic to publish.
-	//	obj:
-	//	 	The source object for the event function. Defaults to dojo.global
-	//	 	if null.
-	//	event:
-	//	 	The name of the event function in obj.
-	//	 	I.e. identifies a property obj[event].
+	//		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");
-	var pf = function(){ dojo.publish(topic, arguments); }
-	return event ? dojo.connect(obj, event, pf) : dojo.connect(obj, pf); //Handle
-};
+}
+=====*/
+
+/*=====
+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
+}
+=====*/
 
-return dojo.connect;
 });
+
+
diff --git a/dojo/_base/declare.js b/dojo/_base/declare.js
index 1b17377..91cc265 100644
--- a/dojo/_base/declare.js
+++ b/dojo/_base/declare.js
@@ -1,7 +1,10 @@
-define("dojo/_base/declare", ["dojo/lib/kernel", "dojo/_base/lang", "dojo/_base/array"], function(dojo){
+define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
+	// module:
+	//		dojo/_base/declare
+	// summary:
+	//		This module defines dojo.declare.
 
-(function(){
-	var d = dojo, mix = d._mixin, op = Object.prototype, opts = op.toString,
+	var mix = lang.mixin, op = Object.prototype, opts = op.toString,
 		xtor = new Function, counter = 0, cname = "constructor";
 
 	function err(msg, cls){ throw new Error("declare" + (cls ? " " + cls : "") + ": " + msg); }
@@ -187,16 +190,24 @@ define("dojo/_base/declare", ["dojo/lib/kernel", "dojo/_base/lang", "dojo/_base/
 		if(f){
 			return a === true ? f : f.apply(this, a || args);
 		}
-		// intentionally if a super method was not found
+		// intentionally no return if a super method was not found
 	}
 
 	function getInherited(name, args){
 		if(typeof name == "string"){
-			return this.inherited(name, args, true);
+			return this.__inherited(name, args, true);
 		}
-		return this.inherited(name, true);
+		return this.__inherited(name, true);
 	}
 
+	function inherited__debug(args, a1, a2){
+		var f = this.getInherited(args, a1);
+		if(f){ return f.apply(this, a2 || a1 || args); }
+		// intentionally no return if a super method was not found
+	}
+
+	var inheritedImpl = dojo.config.isDebug ? inherited__debug : inherited;
+
 	// emulation of "instanceof"
 	function isInstanceOf(cls){
 		var bases = this.constructor._meta.bases;
@@ -209,25 +220,25 @@ define("dojo/_base/declare", ["dojo/lib/kernel", "dojo/_base/lang", "dojo/_base/
 	}
 
 	function mixOwn(target, source){
-		var name, i = 0, l = d._extraNames.length;
 		// add props adding metadata for incoming functions skipping a constructor
-		for(name in source){
+		for(var name in source){
 			if(name != cname && source.hasOwnProperty(name)){
 				target[name] = source[name];
 			}
 		}
-		// process unenumerable methods on IE
-		for(; i < l; ++i){
-			name = d._extraNames[i];
-			if(name != cname && source.hasOwnProperty(name)){
-				target[name] = source[name];
+		if(has("bug-for-in-skips-shadowed")){
+			for(var extraNames= lang._extraNames, i= extraNames.length; i;){
+				name = extraNames[--i];
+				if(name != cname && source.hasOwnProperty(name)){
+					  target[name] = source[name];
+				}
 			}
 		}
 	}
 
 	// implementation of safe mixin function
 	function safeMixin(target, source){
-		var name, t, i = 0, l = d._extraNames.length;
+		var name, t;
 		// add props adding metadata for incoming functions skipping a constructor
 		for(name in source){
 			t = source[name];
@@ -239,23 +250,24 @@ define("dojo/_base/declare", ["dojo/lib/kernel", "dojo/_base/lang", "dojo/_base/
 				target[name] = t;
 			}
 		}
-		// process unenumerable methods on IE
-		for(; i < l; ++i){
-			name = d._extraNames[i];
-			t = source[name];
-			if((t !== op[name] || !(name in op)) && name != cname){
-				if(opts.call(t) == "[object Function]"){
-					// non-trivial function method => attach its name
-					t.nom = name;
+		if(has("bug-for-in-skips-shadowed")){
+			for(var extraNames= lang._extraNames, i= extraNames.length; i;){
+				name = extraNames[--i];
+				t = source[name];
+				if((t !== op[name] || !(name in op)) && name != cname){
+					if(opts.call(t) == "[object Function]"){
+						// non-trivial function method => attach its name
+						  t.nom = name;
+					}
+					target[name] = t;
 				}
-				target[name] = t;
 			}
 		}
 		return target;
 	}
 
 	function extend(source){
-		safeMixin(this.prototype, source);
+		declare.safeMixin(this.prototype, source);
 		return this;
 	}
 
@@ -438,7 +450,7 @@ define("dojo/_base/declare", ["dojo/lib/kernel", "dojo/_base/lang", "dojo/_base/
 		return t;
 	}
 
-	d.declare = function(className, superclass, props){
+	function declare(className, superclass, props){
 		// crack parameters
 		if(typeof className != "string"){
 			props = superclass;
@@ -489,7 +501,7 @@ define("dojo/_base/declare", ["dojo/lib/kernel", "dojo/_base/lang", "dojo/_base/
 			proto = {};
 		}
 		// add all properties
-		safeMixin(proto, props);
+		declare.safeMixin(proto, props);
 		// add constructor
 		t = props.constructor;
 		if(t !== op.constructor){
@@ -523,13 +535,14 @@ define("dojo/_base/declare", ["dojo/lib/kernel", "dojo/_base/lang", "dojo/_base/
 
 		// add "standard" methods to the prototype
 		proto.getInherited = getInherited;
-		proto.inherited = inherited;
 		proto.isInstanceOf = isInstanceOf;
+		proto.inherited    = inheritedImpl;
+		proto.__inherited  = inherited;
 
 		// add name if specified
 		if(className){
 			proto.declaredClass = className;
-			d.setObject(className, ctor);
+			lang.setObject(className, ctor);
 		}
 
 		// build chains and add them to the prototype
@@ -545,9 +558,7 @@ define("dojo/_base/declare", ["dojo/lib/kernel", "dojo/_base/lang", "dojo/_base/
 		// no need to chain "invisible" functions
 
 		return ctor;	// Function
-	};
-
-	d.safeMixin = safeMixin;
+	}
 
 	/*=====
 	dojo.declare = function(className, superclass, props){
@@ -779,7 +790,7 @@ define("dojo/_base/declare", ["dojo/lib/kernel", "dojo/_base/lang", "dojo/_base/
 		//	source: Object
 		//		Source object for new properties.
 		//	description:
-		//		This function is used to mix in properties like dojo._mixin does,
+		//		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.
 		//
@@ -1031,7 +1042,9 @@ define("dojo/_base/declare", ["dojo/lib/kernel", "dojo/_base/lang", "dojo/_base/
 		//	|	});
 	};
 	=====*/
-})();
 
-return dojo.declare;
+	dojo.safeMixin = declare.safeMixin = safeMixin;
+	dojo.declare = declare;
+
+	return declare;
 });
diff --git a/dojo/_base/event.js b/dojo/_base/event.js
index c0a6405..1447679 100644
--- a/dojo/_base/event.js
+++ b/dojo/_base/event.js
@@ -1,103 +1,19 @@
-define("dojo/_base/event", ["dojo/lib/kernel", "dojo/_base/connect"], function(dojo){
-
-// this file courtesy of the TurboAjax Group, licensed under a Dojo CLA
-
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-(function(){
-//>>excludeEnd("webkitMobile");
-	// DOM event listener machinery
-	var del = (dojo._event_listener = {
-		add: function(/*DOMNode*/ node, /*String*/ name, /*Function*/ fp){
-			if(!node){return;}
-			name = del._normalizeEventName(name);
-			fp = del._fixCallback(name, fp);
-			if(
-				//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-				!dojo.isIE &&
-				//>>excludeEnd("webkitMobile");
-				(name == "mouseenter" || name == "mouseleave")
-			){
-				var ofp = fp;
-				name = (name == "mouseenter") ? "mouseover" : "mouseout";
-				fp = function(e){
-					if(!dojo.isDescendant(e.relatedTarget, node)){
-						// e.type = oname; // FIXME: doesn't take? SJM: event.type is generally immutable.
-						return ofp.call(this, e);
-					}
-				}
-			}
-			node.addEventListener(name, fp, false);
-			return fp; /*Handle*/
-		},
-		remove: function(/*DOMNode*/ node, /*String*/ event, /*Handle*/ handle){
-			// summary:
-			//		clobbers the listener from the node
-			// node:
-			//		DOM node to attach the event to
-			// event:
-			//		the name of the handler to remove the function from
-			// handle:
-			//		the handle returned from add
-			if(node){
-				event = del._normalizeEventName(event);
-				if(!dojo.isIE && (event == "mouseenter" || event == "mouseleave")){
-					event = (event == "mouseenter") ? "mouseover" : "mouseout";
-				}
-
-				node.removeEventListener(event, handle, false);
-			}
-		},
-		_normalizeEventName: function(/*String*/ name){
-			// Generally, name should be lower case, unless it is special
-			// somehow (e.g. a Mozilla DOM event).
-			// Remove 'on'.
-			return name.slice(0,2) =="on" ? name.slice(2) : name;
-		},
-		_fixCallback: function(/*String*/ name, fp){
-			// By default, we only invoke _fixEvent for 'keypress'
-			// If code is added to _fixEvent for other events, we have
-			// to revisit this optimization.
-			// This also applies to _fixEvent overrides for Safari and Opera
-			// below.
-			return name != "keypress" ? fp : function(e){ return fp.call(this, del._fixEvent(e, this)); };
-		},
-		_fixEvent: function(evt, sender){
-			// _fixCallback only attaches us to keypress.
-			// Switch on evt.type anyway because we might
-			// be called directly from dojo.fixEvent.
-			switch(evt.type){
-				case "keypress":
-					del._setKeyChar(evt);
-					break;
+define(["./kernel", "../on", "../has", "../dom-geometry"], function(dojo, on, has, dom){
+  //  module:
+  //    dojo/_base/event
+  //  summary:
+  //    This module defines dojo DOM event API.
+	if(on._fixEvent){
+		var fixEvent = on._fixEvent;
+		on._fixEvent = function(evt, se){
+			// add some additional normalization for back-compat, this isn't in on.js because it is somewhat more expensive
+			evt = fixEvent(evt, se);
+			if(evt){
+				dom.normalizeEvent(evt);
 			}
 			return evt;
-		},
-		_setKeyChar: function(evt){
-			evt.keyChar = evt.charCode >= 32 ? String.fromCharCode(evt.charCode) : '';
-			evt.charOrCode = evt.keyChar || evt.keyCode;
-		},
-		// For IE and Safari: some ctrl-key combinations (mostly w/punctuation) do not emit a char code in IE
-		// we map those virtual key codes to ascii here
-		// not valid for all (non-US) keyboards, so maybe we shouldn't bother
-		_punctMap: {
-			106:42,
-			111:47,
-			186:59,
-			187:43,
-			188:44,
-			189:45,
-			190:46,
-			191:47,
-			192:96,
-			219:91,
-			220:92,
-			221:93,
-			222:39
-		}
-	});
-
-	// DOM events
-	
+		};		
+	}
 	dojo.fixEvent = function(/*Event*/ evt, /*DOMNode*/ sender){
 		// summary:
 		//		normalizes properties on the event object including event
@@ -106,554 +22,30 @@ define("dojo/_base/event", ["dojo/lib/kernel", "dojo/_base/connect"], function(d
 		//		native event object
 		// sender: DOMNode
 		//		node to treat as "currentTarget"
-		return del._fixEvent(evt, sender);
+		if(on._fixEvent){
+			return on._fixEvent(evt, sender);
+		}
+		return evt;	// Event
 	};
-
+	
 	dojo.stopEvent = 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.
-		evt.preventDefault();
-		evt.stopPropagation();
-		// NOTE: below, this method is overridden for IE
-	};
-
-	// the default listener to use on dontFix nodes, overriden for IE
-	var node_listener = dojo._listener;
-	
-	// Unify connect and event listeners
-	dojo._connect = function(obj, event, context, method, dontFix){
-		// FIXME: need a more strict test
-		var isNode = obj && (obj.nodeType||obj.attachEvent||obj.addEventListener);
-		// choose one of three listener options: raw (connect.js), DOM event on a Node, custom event on a Node
-		// we need the third option to provide leak prevention on broken browsers (IE)
-		var lid = isNode ? (dontFix ? 2 : 1) : 0, l = [dojo._listener, del, node_listener][lid];
-		// create a listener
-		var h = l.add(obj, event, dojo.hitch(context, method));
-		// formerly, the disconnect package contained "l" directly, but if client code
-		// leaks the disconnect package (by connecting it to a node), referencing "l"
-		// compounds the problem.
-		// instead we return a listener id, which requires custom _disconnect below.
-		// return disconnect package
-		return [ obj, event, h, lid ];
-	};
-
-	dojo._disconnect = function(obj, event, handle, listener){
-		([dojo._listener, del, node_listener][listener]).remove(obj, event, handle);
-	};
-
-	// Constants
-
-	// Public: client code should test
-	// keyCode against these named constants, as the
-	// actual codes can vary by browser.
-	dojo.keys = {
-		// summary:
-		//		Definitions for common key values
-		BACKSPACE: 8,
-		TAB: 9,
-		CLEAR: 12,
-		ENTER: 13,
-		SHIFT: 16,
-		CTRL: 17,
-		ALT: 18,
-		META: dojo.isSafari ? 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,
-		// virtual key mapping
-		copyKey: dojo.isMac && !dojo.isAIR ? (dojo.isSafari ? 91 : 224 ) : 17
-	};
-	
-	var evtCopyKey = dojo.isMac ? "metaKey" : "ctrlKey";
-	
-	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
-		return e[evtCopyKey];	// Boolean
-	};
-
-	// Public: decoding mouse buttons from events
-
-/*=====
-	dojo.mouseButtons = {
-		// LEFT: Number
-		//		Numeric value of the left mouse button for the platform.
-		LEFT:   0,
-		// MIDDLE: Number
-		//		Numeric value of the middle mouse button for the platform.
-		MIDDLE: 1,
-		// RIGHT: Number
-		//		Numeric value of the right mouse button for the platform.
-		RIGHT:  2,
-	
-		isButton: function(e, button){
-			// summary:
-			//		Checks an event object for a pressed button
-			// e: Event
-			//		Event object to examine
-			// button: Number
-			//		The button value (example: dojo.mouseButton.LEFT)
-			return e.button == button; // Boolean
-		},
-		isLeft: function(e){
-			// summary:
-			//		Checks an event object for the pressed left button
-			// e: Event
-			//		Event object to examine
-			return e.button == 0; // Boolean
-		},
-		isMiddle: function(e){
-			// summary:
-			//		Checks an event object for the pressed middle button
-			// e: Event
-			//		Event object to examine
-			return e.button == 1; // Boolean
-		},
-		isRight: function(e){
-			// summary:
-			//		Checks an event object for the pressed right button
-			// e: Event
-			//		Event object to examine
-			return e.button == 2; // Boolean
-		}
-	};
-=====*/
-
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	if(dojo.isIE < 9 || (dojo.isIE && dojo.isQuirks)){
-		dojo.mouseButtons = {
-			LEFT:   1,
-			MIDDLE: 4,
-			RIGHT:  2,
-			// helper functions
-			isButton: function(e, button){ return e.button & button; },
-			isLeft:   function(e){ return e.button & 1; },
-			isMiddle: function(e){ return e.button & 4; },
-			isRight:  function(e){ return e.button & 2; }
-		};
-	}else{
-	//>>excludeEnd("webkitMobile");
-		dojo.mouseButtons = {
-			LEFT:   0,
-			MIDDLE: 1,
-			RIGHT:  2,
-			// helper functions
-			isButton: function(e, button){ return e.button == button; },
-			isLeft:   function(e){ return e.button == 0; },
-			isMiddle: function(e){ return e.button == 1; },
-			isRight:  function(e){ return e.button == 2; }
-		};
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	}
-	//>>excludeEnd("webkitMobile");
-
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	// IE event normalization
-	if(dojo.isIE){
-		var _trySetKeyCode = function(e, code){
-			try{
-				// squelch errors when keyCode is read-only
-				// (e.g. if keyCode is ctrl or shift)
-				return (e.keyCode = code);
-			}catch(e){
-				return 0;
-			}
-		};
-
-		// by default, use the standard listener
-		var iel = dojo._listener;
-		var listenersName = (dojo._ieListenersName = "_" + dojo._scopeName + "_listeners");
-		// dispatcher tracking property
-		if(!dojo.config._allow_leaks){
-			// custom listener that handles leak protection for DOM events
-			node_listener = iel = dojo._ie_listener = {
-				// support handler indirection: event handler functions are
-				// referenced here. Event dispatchers hold only indices.
-				handlers: [],
-				// add a listener to an object
-				add: function(/*Object*/ source, /*String*/ method, /*Function*/ listener){
-					source = source || dojo.global;
-					var f = source[method];
-					if(!f||!f[listenersName]){
-						var d = dojo._getIeDispatcher();
-						// original target function is special
-						d.target = f && (ieh.push(f) - 1);
-						// dispatcher holds a list of indices into handlers table
-						d[listenersName] = [];
-						// redirect source to dispatcher
-						f = source[method] = d;
-					}
-					return f[listenersName].push(ieh.push(listener) - 1) ; /*Handle*/
-				},
-				// remove a listener from an object
-				remove: function(/*Object*/ source, /*String*/ method, /*Handle*/ handle){
-					var f = (source||dojo.global)[method], l = f && f[listenersName];
-					if(f && l && handle--){
-						delete ieh[l[handle]];
-						delete l[handle];
-					}
-				}
-			};
-			// alias used above
-			var ieh = iel.handlers;
-		}
-
-		dojo.mixin(del, {
-			add: function(/*DOMNode*/ node, /*String*/ event, /*Function*/ fp){
-				if(!node){return;} // undefined
-				event = del._normalizeEventName(event);
-				if(event=="onkeypress"){
-					// we need to listen to onkeydown to synthesize
-					// keypress events that otherwise won't fire
-					// on IE
-					var kd = node.onkeydown;
-					if(!kd || !kd[listenersName] || !kd._stealthKeydownHandle){
-						var h = del.add(node, "onkeydown", del._stealthKeyDown);
-						kd = node.onkeydown;
-						kd._stealthKeydownHandle = h;
-						kd._stealthKeydownRefs = 1;
-					}else{
-						kd._stealthKeydownRefs++;
-					}
-				}
-				return iel.add(node, event, del._fixCallback(fp));
-			},
-			remove: function(/*DOMNode*/ node, /*String*/ event, /*Handle*/ handle){
-				event = del._normalizeEventName(event);
-				iel.remove(node, event, handle);
-				if(event=="onkeypress"){
-					var kd = node.onkeydown;
-					if(--kd._stealthKeydownRefs <= 0){
-						iel.remove(node, "onkeydown", kd._stealthKeydownHandle);
-						delete kd._stealthKeydownHandle;
-					}
-				}
-			},
-			_normalizeEventName: function(/*String*/ eventName){
-				// Generally, eventName should be lower case, unless it is
-				// special somehow (e.g. a Mozilla event)
-				// ensure 'on'
-				return eventName.slice(0,2) != "on" ? "on" + eventName : eventName;
-			},
-			_nop: function(){},
-			_fixEvent: function(/*Event*/ evt, /*DOMNode*/ sender){
-				// summary:
-				//		normalizes properties on the event object including event
-				//		bubbling methods, keystroke normalization, and x/y positions
-				// evt:
-				//		native event object
-				// sender:
-				//		node to treat as "currentTarget"
-				if(!evt){
-					var w = sender && (sender.ownerDocument || sender.document || sender).parentWindow || window;
-					evt = w.event;
-				}
-				if(!evt){return(evt);}
-				evt.target = evt.srcElement;
-				evt.currentTarget = (sender || evt.srcElement);
-				evt.layerX = evt.offsetX;
-				evt.layerY = evt.offsetY;
-				// FIXME: scroll position query is duped from dojo.html to
-				// avoid dependency on that entire module. Now that HTML is in
-				// Base, we should convert back to something similar there.
-				var se = evt.srcElement, doc = (se && se.ownerDocument) || document;
-				// DO NOT replace the following to use dojo.body(), in IE, document.documentElement should be used
-				// here rather than document.body
-				var docBody = ((dojo.isIE < 6) || (doc["compatMode"] == "BackCompat")) ? doc.body : doc.documentElement;
-				var offset = dojo._getIeDocumentElementOffset();
-				evt.pageX = evt.clientX + dojo._fixIeBiDiScrollLeft(docBody.scrollLeft || 0) - offset.x;
-				evt.pageY = evt.clientY + (docBody.scrollTop || 0) - offset.y;
-				if(evt.type == "mouseover"){
-					evt.relatedTarget = evt.fromElement;
-				}
-				if(evt.type == "mouseout"){
-					evt.relatedTarget = evt.toElement;
-				}
-				if (dojo.isIE < 9 || dojo.isQuirks) {
-					evt.stopPropagation = del._stopPropagation;
-					evt.preventDefault = del._preventDefault;
-				}
-				return del._fixKeys(evt);
-			},
-			_fixKeys: function(evt){
-				switch(evt.type){
-					case "keypress":
-						var c = ("charCode" in evt ? evt.charCode : evt.keyCode);
-						if (c==10){
-							// CTRL-ENTER is CTRL-ASCII(10) on IE, but CTRL-ENTER on Mozilla
-							c=0;
-							evt.keyCode = 13;
-						}else if(c==13||c==27){
-							c=0; // Mozilla considers ENTER and ESC non-printable
-						}else if(c==3){
-							c=99; // Mozilla maps CTRL-BREAK to CTRL-c
-						}
-						// Mozilla sets keyCode to 0 when there is a charCode
-						// but that stops the event on IE.
-						evt.charCode = c;
-						del._setKeyChar(evt);
-						break;
-				}
-				return evt;
-			},
-			_stealthKeyDown: function(evt){
-				// IE doesn't fire keypress for most non-printable characters.
-				// other browsers do, we simulate it here.
-				var kp = evt.currentTarget.onkeypress;
-				// only works if kp exists and is a dispatcher
-				if(!kp || !kp[listenersName]){ return; }
-				// munge key/charCode
-				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 || (dojo.isIE >= 9 && !dojo.isQuirks)) && k!=32 && k!=27 && (k<48||k>90) && (k<96||k>111) && (k<186||k>192) && (k<219||k>222);
-
-				// synthesize keypress for most unprintables and CTRL-keys
-				if(unprintable||evt.ctrlKey){
-					var c = unprintable ? 0 : k;
-					if(evt.ctrlKey){
-						if(k==3 || k==13){
-							return; // IE will post CTRL-BREAK, CTRL-ENTER as keypress natively
-						}else if(c>95 && c<106){
-							c -= 48; // map CTRL-[numpad 0-9] to ASCII
-						}else if((!evt.shiftKey)&&(c>=65&&c<=90)){
-							c += 32; // map CTRL-[A-Z] to lowercase
-						}else{
-							c = del._punctMap[c] || c; // map other problematic CTRL combinations to ASCII
-						}
-					}
-					// simulate a keypress event
-					var faux = del._synthesizeEvent(evt, {type: 'keypress', faux: true, charCode: c});
-					kp.call(evt.currentTarget, faux);
-					if(dojo.isIE < 9 || (dojo.isIE && dojo.isQuirks)){
-						evt.cancelBubble = faux.cancelBubble;
-					}
-					evt.returnValue = faux.returnValue;
-					_trySetKeyCode(evt, faux.keyCode);
-				}
-			},
-			// Called in Event scope
-			_stopPropagation: function(){
-				this.cancelBubble = true;
-			},
-			_preventDefault: function(){
-				// Setting keyCode to 0 is the only way to prevent certain keypresses (namely
-				// ctrl-combinations that correspond to menu accelerator keys).
-				// Otoh, it prevents upstream listeners from getting this information
-				// Try to split the difference here by clobbering keyCode only for ctrl
-				// combinations. If you still need to access the key upstream, bubbledKeyCode is
-				// provided as a workaround.
-				this.bubbledKeyCode = this.keyCode;
-				if(this.ctrlKey){_trySetKeyCode(this, 0);}
-				this.returnValue = false;
-			}
-		});
-				
-		// override stopEvent for IE
-		dojo.stopEvent = (dojo.isIE < 9 || dojo.isQuirks) ? function(evt){
+		if(has("dom-addeventlistener") || (evt && evt.preventDefault)){
+			evt.preventDefault();
+			evt.stopPropagation();
+		}else{
 			evt = evt || window.event;
-			del._stopPropagation.call(evt);
-			del._preventDefault.call(evt);
-		} : dojo.stopEvent;
-	}
-	//>>excludeEnd("webkitMobile");
-
-	del._synthesizeEvent = function(evt, props){
-			var faux = dojo.mixin({}, evt, props);
-			del._setKeyChar(faux);
-			// FIXME: would prefer to use dojo.hitch: dojo.hitch(evt, evt.preventDefault);
-			// but it throws an error when preventDefault is invoked on Safari
-			// does Event.preventDefault not support "apply" on Safari?
-			faux.preventDefault = function(){ evt.preventDefault(); };
-			faux.stopPropagation = function(){ evt.stopPropagation(); };
-			return faux;
-	};
-	
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	// Opera event normalization
-	if(dojo.isOpera){
-		dojo.mixin(del, {
-			_fixEvent: function(evt, sender){
-				switch(evt.type){
-					case "keypress":
-						var c = evt.which;
-						if(c==3){
-							c=99; // Mozilla maps CTRL-BREAK to CTRL-c
-						}
-						// can't trap some keys at all, like INSERT and DELETE
-						// there is no differentiating info between DELETE and ".", or INSERT and "-"
-						c = c<41 && !evt.shiftKey ? 0 : c;
-						if(evt.ctrlKey && !evt.shiftKey && c>=65 && c<=90){
-							// lowercase CTRL-[A-Z] keys
-							c += 32;
-						}
-						return del._synthesizeEvent(evt, { charCode: c });
-				}
-				return evt;
-			}
-		});
-	}
-	//>>excludeEnd("webkitMobile");
-
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	// Webkit event normalization
-	if(dojo.isWebKit){
-		//>>excludeEnd("webkitMobile");
-		del._add = del.add;
-		del._remove = del.remove;
-
-		dojo.mixin(del, {
-			add: function(/*DOMNode*/ node, /*String*/ event, /*Function*/ fp){
-				if(!node){return;} // undefined
-				var handle = del._add(node, event, fp);
-				if(del._normalizeEventName(event) == "keypress"){
-					// we need to listen to onkeydown to synthesize
-					// keypress events that otherwise won't fire
-					// in Safari 3.1+: https://lists.webkit.org/pipermail/webkit-dev/2007-December/002992.html
-					handle._stealthKeyDownHandle = del._add(node, "keydown", function(evt){
-						//A variation on the IE _stealthKeydown function
-						//Synthesize an onkeypress event, but only for unprintable characters.
-						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 && k!=32 && (k<48 || k>90) && (k<96 || k>111) && (k<186 || k>192) && (k<219 || k>222);
-						// synthesize keypress for most unprintables and CTRL-keys
-						if(unprintable || evt.ctrlKey){
-							var c = unprintable ? 0 : k;
-							if(evt.ctrlKey){
-								if(k==3 || k==13){
-									return; // IE will post CTRL-BREAK, CTRL-ENTER as keypress natively
-								}else if(c>95 && c<106){
-									c -= 48; // map CTRL-[numpad 0-9] to ASCII
-								}else if(!evt.shiftKey && c>=65 && c<=90){
-									c += 32; // map CTRL-[A-Z] to lowercase
-								}else{
-									c = del._punctMap[c] || c; // map other problematic CTRL combinations to ASCII
-								}
-							}
-							// simulate a keypress event
-							var faux = del._synthesizeEvent(evt, {type: 'keypress', faux: true, charCode: c});
-							fp.call(evt.currentTarget, faux);
-						}
-					});
-				}
-				return handle; /*Handle*/
-			},
-
-			remove: function(/*DOMNode*/ node, /*String*/ event, /*Handle*/ handle){
-				if(node){
-					if(handle._stealthKeyDownHandle){
-						del._remove(node, "keydown", handle._stealthKeyDownHandle);
-					}
-					del._remove(node, event, handle);
-				}
-			},
-			_fixEvent: function(evt, sender){
-				switch(evt.type){
-					case "keypress":
-						if(evt.faux){ return evt; }
-						var c = evt.charCode;
-						c = c>=32 ? c : 0;
-						return del._synthesizeEvent(evt, {charCode: c, faux: true});
-				}
-				return evt;
-			}
-		});
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	}
-	//>>excludeEnd("webkitMobile");
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-})();
-//>>excludeEnd("webkitMobile");
-
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-if(dojo.isIE){
-	// keep this out of the closure
-	// closing over 'iel' or 'ieh' b0rks leak prevention
-	// ls[i] is an index into the master handler array
-	dojo._ieDispatcher = function(args, sender){
-		var ap = Array.prototype,
-			h = dojo._ie_listener.handlers,
-			c = args.callee,
-			ls = c[dojo._ieListenersName],
-			t = h[c.target];
-		// return value comes from original target function
-		var r = t && t.apply(sender, args);
-		// make local copy of listener array so it's immutable during processing
-		var lls = [].concat(ls);
-		// invoke listeners after target function
-		for(var i in lls){
-			var f = h[lls[i]];
-			if(!(i in ap) && f){
-				f.apply(sender, args);
-			}
+			evt.cancelBubble = true;
+			on._preventDefault.call(evt);
 		}
-		return r;
 	};
-	dojo._getIeDispatcher = function(){
-		// ensure the returned function closes over nothing ("new Function" apparently doesn't close)
-		return new Function(dojo._scopeName + "._ieDispatcher(arguments, this)"); // function
-	};
-	// keep this out of the closure to reduce RAM allocation
-	dojo._event_listener._fixCallback = function(fp){
-		var f = dojo._event_listener._fixEvent;
-		return function(e){ return fp.call(this, f(e, this)); };
-	};
-}
-//>>excludeEnd("webkitMobile");
 
-return dojo.connect;
+	return {
+		fix: dojo.fixEvent,
+		stop: dojo.stopEvent
+	};
 });
diff --git a/dojo/_base/fx.js b/dojo/_base/fx.js
index 55f71c8..b8a25d4 100644
--- a/dojo/_base/fx.js
+++ b/dojo/_base/fx.js
@@ -1,14 +1,13 @@
-define("dojo/_base/fx", ["dojo/lib/kernel", "dojo/_base/Color", "dojo/_base/connect", "dojo/_base/lang", "dojo/_base/html"], function(dojo){
-
-/*
-	Animation loosely package based on Dan Pupius' work, contributed under CLA:
-		http://pupius.co.uk/js/Toolkit.Drawing.js
-*/
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-(function(){
-	var d = dojo;
-//>>excludeEnd("webkitMobile");
-	var _mixin = d._mixin;
+define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "../dom", "../dom-style"], function(dojo, lang, Evented, Color, connect, 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:
@@ -44,16 +43,16 @@ define("dojo/_base/fx", ["dojo/lib/kernel", "dojo/_base/Color", "dojo/_base/conn
 		//		animation instance.
 
 		_mixin(this, args);
-		if(d.isArray(this.curve)){
-			this.curve = new d._Line(this.curve[0], this.curve[1]);
+		if(lang.isArray(this.curve)){
+			this.curve = new dojo._Line(this.curve[0], this.curve[1]);
 		}
 
 	};
-
+	dojo.Animation.prototype = new Evented();
 	// Alias to drop come 2.0:
-	d._Animation = d.Animation;
+	dojo._Animation = dojo.Animation;
 
-	d.extend(dojo.Animation, {
+	lang.extend(dojo.Animation, {
 		// duration: Integer
 		//		The time in milliseonds the animation will take to run
 		duration: 350,
@@ -139,7 +138,7 @@ define("dojo/_base/fx", ["dojo/lib/kernel", "dojo/_base/Color", "dojo/_base/conn
 			//		The arguments to pass to the event.
 			var a = args||[];
 			if(this[evt]){
-				if(d.config.debugAtAllCosts){
+				if(dojo.config.debugAtAllCosts){
 					this[evt].apply(this, a);
 				}else{
 					try{
@@ -182,14 +181,14 @@ define("dojo/_base/fx", ["dojo/lib/kernel", "dojo/_base/Color", "dojo/_base/conn
 			_t._fire("beforeBegin", [_t.node]);
 
 			var de = delay || _t.delay,
-				_p = dojo.hitch(_t, "_play", gotoStart);
+				_p = lang.hitch(_t, "_play", gotoStart);
 
 			if(de > 0){
 				_t._delayTimer = setTimeout(_p, de);
 				return _t;
 			}
 			_p();
-			return _t;
+			return _t;	// dojo.Animation
 		},
 
 		_play: function(gotoStart){
@@ -324,21 +323,21 @@ define("dojo/_base/fx", ["dojo/lib/kernel", "dojo/_base/Color", "dojo/_base/conn
 			run: function(){}
 		};
 
-	d.extend(d.Animation, {
+	lang.extend(dojo.Animation, {
 
 		_startTimer: function(){
 			if(!this._timer){
-				this._timer = d.connect(runner, "run", this, "_cycle");
+				this._timer = connect.connect(runner, "run", this, "_cycle");
 				ctr++;
 			}
 			if(!timer){
-				timer = setInterval(d.hitch(runner, "run"), this.rate);
+				timer = setInterval(lang.hitch(runner, "run"), this.rate);
 			}
 		},
 
 		_stopTimer: function(){
 			if(this._timer){
-				d.disconnect(this._timer);
+				connect.disconnect(this._timer);
 				this._timer = null;
 				ctr--;
 			}
@@ -353,13 +352,13 @@ define("dojo/_base/fx", ["dojo/lib/kernel", "dojo/_base/Color", "dojo/_base/conn
 
 	var _makeFadeable =
 		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		d.isIE ? function(node){
+		has("ie") ? function(node){
 			// only set the zoom if the "tickle" value would be the same as the
 			// default
 			var ns = node.style;
 			// don't set the width to auto if it didn't already cascade that way.
 			// We don't want to f anyones designs
-			if(!ns.width.length && d.style(node, "width") == "auto"){
+			if(!ns.width.length && style.get(node, "width") == "auto"){
 				ns.width = "auto";
 			}
 		} :
@@ -372,18 +371,18 @@ define("dojo/_base/fx", ["dojo/lib/kernel", "dojo/_base/Color", "dojo/_base/conn
 		//		args.node from the start to end values passed (args.start
 		//		args.end) (end is mandatory, start is optional)
 
-		args.node = d.byId(args.node);
+		args.node = dom.byId(args.node);
 		var fArgs = _mixin({ properties: {} }, args),
 			props = (fArgs.properties.opacity = {});
 
 		props.start = !("start" in fArgs) ?
 			function(){
-				return +d.style(fArgs.node, "opacity")||0;
+				return +style.get(fArgs.node, "opacity")||0;
 			} : fArgs.start;
 		props.end = fArgs.end;
 
-		var anim = d.animateProperty(fArgs);
-		d.connect(anim, "beforeBegin", d.partial(_makeFadeable, fArgs.node));
+		var anim = dojo.animateProperty(fArgs);
+		connect.connect(anim, "beforeBegin", lang.partial(_makeFadeable, fArgs.node));
 
 		return anim; // dojo.Animation
 	};
@@ -406,19 +405,19 @@ define("dojo/_base/fx", ["dojo/lib/kernel", "dojo/_base/Color", "dojo/_base/conn
 		// summary:
 		//		Returns an animation that will fade node defined in 'args' from
 		//		its current opacity to fully opaque.
-		return d._fade(_mixin({ end: 1 }, args)); // dojo.Animation
+		return dojo._fade(_mixin({ end: 1 }, args)); // dojo.Animation
 	};
 
-	dojo.fadeOut = function(/*dojo.__FadeArgs*/  args){
+	dojo.fadeOut = function(/*dojo.__FadeArgs*/ args){
 		// summary:
 		//		Returns an animation that will fade node defined in 'args'
 		//		from its current opacity to fully transparent.
-		return d._fade(_mixin({ end: 0 }, args)); // dojo.Animation
+		return dojo._fade(_mixin({ end: 0 }, args)); // dojo.Animation
 	};
 
 	dojo._defaultEasing = function(/*Decimal?*/ n){
 		// summary: The default easing function for dojo.Animation(s)
-		return 0.5 + ((Math.sin((n + 1.5) * Math.PI)) / 2);
+		return 0.5 + ((Math.sin((n + 1.5) * Math.PI)) / 2);	// Decimal
 	};
 
 	var PropLine = function(properties){
@@ -429,9 +428,9 @@ define("dojo/_base/fx", ["dojo/lib/kernel", "dojo/_base/Color", "dojo/_base/conn
 		this._properties = properties;
 		for(var p in properties){
 			var prop = properties[p];
-			if(prop.start instanceof d.Color){
+			if(prop.start instanceof Color){
 				// create a reusable temp color object to keep intermediate results
-				prop.tempColor = new d.Color();
+				prop.tempColor = new Color();
 			}
 		}
 	};
@@ -441,9 +440,9 @@ define("dojo/_base/fx", ["dojo/lib/kernel", "dojo/_base/Color", "dojo/_base/conn
 		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();
-			}else if(!d.isArray(start)){
+			if(start instanceof Color){
+				ret[p] = Color.blendColors(start, prop.end, r, prop.tempColor).toCss();
+			}else if(!lang.isArray(start)){
 				ret[p] = ((prop.end - start) * r) + start + (p != "opacity" ? prop.units || "px" : 0);
 			}
 		}
@@ -550,11 +549,11 @@ define("dojo/_base/fx", ["dojo/lib/kernel", "dojo/_base/Color", "dojo/_base/conn
 		//	|	}).play();
 		//
 
-		var n = args.node = d.byId(args.node);
-		if(!args.easing){ args.easing = d._defaultEasing; }
+		var n = args.node = dom.byId(args.node);
+		if(!args.easing){ args.easing = dojo._defaultEasing; }
 
-		var anim = new d.Animation(args);
-		d.connect(anim, "beforeBegin", anim, function(){
+		var anim = new dojo.Animation(args);
+		connect.connect(anim, "beforeBegin", anim, function(){
 			var pm = {};
 			for(var p in this.properties){
 				// Make shallow copy of properties into pm because we overwrite
@@ -565,15 +564,15 @@ define("dojo/_base/fx", ["dojo/lib/kernel", "dojo/_base/Color", "dojo/_base/conn
 					this.node.display = "block";
 				}
 				var prop = this.properties[p];
-				if(d.isFunction(prop)){
+				if(lang.isFunction(prop)){
 					prop = prop(n);
 				}
-				prop = pm[p] = _mixin({}, (d.isObject(prop) ? prop: { end: prop }));
+				prop = pm[p] = _mixin({}, (lang.isObject(prop) ? prop: { end: prop }));
 
-				if(d.isFunction(prop.start)){
+				if(lang.isFunction(prop.start)){
 					prop.start = prop.start(n);
 				}
-				if(d.isFunction(prop.end)){
+				if(lang.isFunction(prop.end)){
 					prop.end = prop.end(n);
 				}
 				var isColor = (p.toLowerCase().indexOf("color") >= 0);
@@ -581,7 +580,7 @@ define("dojo/_base/fx", ["dojo/lib/kernel", "dojo/_base/Color", "dojo/_base/conn
 					// dojo.style(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 = d.style(node, p);
+					v = style.get(node, p);
 					return (p == "opacity") ? +v : (isColor ? v : parseFloat(v));
 				}
 				if(!("end" in prop)){
@@ -591,15 +590,15 @@ define("dojo/_base/fx", ["dojo/lib/kernel", "dojo/_base/Color", "dojo/_base/conn
 				}
 
 				if(isColor){
-					prop.start = new d.Color(prop.start);
-					prop.end = new d.Color(prop.end);
+					prop.start = new Color(prop.start);
+					prop.end = new Color(prop.end);
 				}else{
 					prop.start = (p == "opacity") ? +prop.start : parseFloat(prop.start);
 				}
 			}
 			this.curve = new PropLine(pm);
 		});
-		d.connect(anim, "onAnimate", d.hitch(d, "style", anim.node));
+		connect.connect(anim, "onAnimate", lang.hitch(style, "set", anim.node));
 		return anim; // dojo.Animation
 	};
 
@@ -647,17 +646,23 @@ define("dojo/_base/fx", ["dojo/lib/kernel", "dojo/_base/Color", "dojo/_base/conn
 		//	example:
 		//		Fade out a node over a full second
 		//	|	dojo.anim("id", { opacity: 0 }, 1000);
-		return d.animateProperty({ // dojo.Animation
+		return dojo.animateProperty({ // dojo.Animation
 			node: node,
-			duration: duration || d.Animation.prototype.duration,
+			duration: duration || dojo.Animation.prototype.duration,
 			properties: properties,
 			easing: easing,
 			onEnd: onEnd
 		}).play(delay || 0);
 	};
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-})();
-//>>excludeEnd("webkitMobile");
 
-return dojo.animateProperty;
+	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
+	};
 });
diff --git a/dojo/_base/html.js b/dojo/_base/html.js
index b179a15..3fe6adc 100644
--- a/dojo/_base/html.js
+++ b/dojo/_base/html.js
@@ -1,998 +1,142 @@
-define("dojo/_base/html", ["dojo/lib/kernel", "dojo/_base/lang"], function(dojo){
-
-// 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"
-}
-//>>excludeEnd("webkitMobile");
-
-// =============================
-// DOM Functions
-// =============================
-
-/*=====
-dojo.byId = function(id, doc){
-	//	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
-	//	|	}
-=====*/
-
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-if(dojo.isIE){
-	dojo.byId = function(id, doc){
-		if(typeof id != "string"){
-			return id;
-		}
-		var _d = doc || dojo.doc, te = _d.getElementById(id);
-		// attributes.id.value is better than just id in case the
-		// user has a name=id inside a form
-		if(te && (te.attributes.id.value == id || te.id == id)){
-			return te;
-		}else{
-			var eles = _d.all[id];
-			if(!eles || eles.nodeName){
-				eles = [eles];
-			}
-			// if more than 1, choose first with the correct id
-			var i=0;
-			while((te=eles[i++])){
-				if((te.attributes && te.attributes.id && te.attributes.id.value == id)
-					|| te.id == id){
-					return te;
-				}
-			}
-		}
-	};
-}else{
-//>>excludeEnd("webkitMobile");
-	dojo.byId = function(id, doc){
-		// inline'd type check.
-		// be sure to return null per documentation, to match IE branch.
-		return ((typeof id == "string") ? (doc || dojo.doc).getElementById(id) : id) || null; // DomNode
-	};
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-}
-//>>excludeEnd("webkitMobile");
-/*=====
-};
-=====*/
-
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-(function(){
-	var d = dojo;
-//>>excludeEnd("webkitMobile");
-	var byId = d.byId;
-
-	var _destroyContainer = null,
-		_destroyDoc;
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	d.addOnWindowUnload(function(){
-		_destroyContainer = null; //prevent IE leak
-	});
-	//>>excludeEnd("webkitMobile");
-
-/*=====
-	dojo._destroyElement = function(node){
+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.
+
+	// mix-in dom
+	dojo.byId = dom.byId;
+	dojo.isDescendant = dom.isDescendant;
+	dojo.setSelectable = dom.setSelectable;
+
+	// mix-in dom-attr
+	dojo.getAttr = attr.get;
+	dojo.setAttr = attr.set;
+	dojo.hasAttr = attr.has;
+	dojo.removeAttr = attr.remove;
+	dojo.getNodeProp = attr.getNodeProp;
+
+	dojo.attr = function(node, name, value){
 		// summary:
-		// 		Existing alias for `dojo.destroy`. Deprecated, will be removed
-		// 		in 2.0
-	}
-=====*/
-	dojo._destroyElement = dojo.destroy = function(/*String|DomNode*/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:
-		//		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 = 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 */
-		}
-	};
-
-	dojo.isDescendant = function(/*DomNode|String*/node, /*DomNode|String*/ancestor){
-		//	summary:
-		//		Returns true if node is a descendant of ancestor
-		//	node: string id or node reference to test
-		//	ancestor: 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")){ ... }
-		try{
-			node = byId(node);
-			ancestor = byId(ancestor);
-			while(node){
-				if(node == ancestor){
-					return true; // Boolean
-				}
-				node = node.parentNode;
-			}
-		}catch(e){ /* squelch, return false */ }
-		return false; // Boolean
-	};
-
-	dojo.setSelectable = function(/*DomNode|String*/node, /*Boolean*/selectable){
-		//	summary:
-		//		Enable or disable selection on a node
-		//	node:
-		//		id or reference to node
-		//	selectable:
-		//		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);
-		node = byId(node);
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		if(d.isMozilla){
-			node.style.MozUserSelect = selectable ? "" : "none";
-		}else if(d.isKhtml || d.isWebKit){
-		//>>excludeEnd("webkitMobile");
-			node.style.KhtmlUserSelect = selectable ? "auto" : "none";
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		}else if(d.isIE){
-			var v = (node.unselectable = selectable ? "" : "on");
-			d.query("*", node).forEach("item.unselectable = '"+v+"'");
-		}
-		//>>excludeEnd("webkitMobile");
-		//FIXME: else?  Opera?
-	};
-
-	var _insertBefore = function(/*DomNode*/node, /*DomNode*/ref){
-		var parent = ref.parentNode;
-		if(parent){
-			parent.insertBefore(node, ref);
-		}
-	};
-
-	var _insertAfter = function(/*DomNode*/node, /*DomNode*/ref){
-		//	summary:
-		//		Try to insert node after ref
-		var parent = ref.parentNode;
-		if(parent){
-			if(parent.lastChild == ref){
-				parent.appendChild(node);
-			}else{
-				parent.insertBefore(node, ref.nextSibling);
-			}
-		}
-	};
-
-	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: String|DomNode
-		//		id or node reference, or HTML fragment starting with "<" to place relative to refNode
-		//
-		//	refNode: String|DomNode
-		//		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
+		//		Gets or sets an attribute on an HTML element.
+		// description:
+		//		Handles normalized getting and setting of attributes on DOM
+		//		Nodes. If 2 arguments are passed, and a the second argument is a
+		//		string, acts as a getter.
 		//
-		//	returns: DomNode
-		//		Returned values is the first argument resolved to a DOM node.
+		//		If a third argument is passed, or if the second argument is a
+		//		map of attributes, acts as a setter.
 		//
-		//		.place() is also a method of `dojo.NodeList`, allowing `dojo.query` node lookups.
+		//		When passing functions as values, note that they will not be
+		//		directly assigned to slots on the node, but rather the default
+		//		behavior will be removed and the new behavior will be added
+		//		using `dojo.connect()`, meaning that event handler properties
+		//		will be normalized and that some caveats with regards to
+		//		non-standard behaviors for onsubmit apply. Namely that you
+		//		should cancel form submission using `dojo.stopEvent()` on the
+		//		passed event object instead of returning a boolean value from
+		//		the handler itself.
+		// node: DOMNode|String
+		//		id or reference to the element to get or set the attribute on
+		// name: String|Object
+		//		the name of the attribute to get or set.
+		// value: String?
+		//		The value to set for the attribute
+		// returns:
+		//		when used as a getter, the value of the requested attribute
+		//		or null if that attribute does not have a specified or
+		//		default value;
 		//
-		// example:
-		//		Place a node by string id as the last child of another node by string id:
-		//	|	dojo.place("someNode", "anotherNode");
+		//		when used as a setter, the DOM node
 		//
 		// example:
-		//		Place a node by string id before another node by string id
-		//	|	dojo.place("someNode", "anotherNode", "before");
+		//	|	// get the current value of the "foo" attribute on a node
+		//	|	dojo.attr(dojo.byId("nodeId"), "foo");
+		//	|	// or we can just pass the id:
+		//	|	dojo.attr("nodeId", "foo");
 		//
 		// example:
-		//		Create a Node, and place it in the body element (last child):
-		//	|	dojo.place("<div></div>", dojo.body());
+		//	|	// use attr() to set the tab index
+		//	|	dojo.attr("nodeId", "tabIndex", 3);
+		//	|
 		//
 		// example:
-		//		Put a new LI as the first child of a list by id:
-		//	|	dojo.place("<li></li>", "someUl", "first");
-
-		refNode = byId(refNode);
-		if(typeof node == "string"){ // inline'd type check
-			node = /^\s*</.test(node) ? d._toDom(node, refNode.ownerDocument) : byId(node);
-		}
-		if(typeof position == "number"){ // inline'd type check
-			var cn = refNode.childNodes;
-			if(!cn.length || cn.length <= position){
-				refNode.appendChild(node);
-			}else{
-				_insertBefore(node, cn[position < 0 ? 0 : position]);
-			}
-		}else{
-			switch(position){
-				case "before":
-					_insertBefore(node, refNode);
-					break;
-				case "after":
-					_insertAfter(node, refNode);
-					break;
-				case "replace":
-					refNode.parentNode.replaceChild(node, refNode);
-					break;
-				case "only":
-					d.empty(refNode);
-					refNode.appendChild(node);
-					break;
-				case "first":
-					if(refNode.firstChild){
-						_insertBefore(node, refNode.firstChild);
-						break;
-					}
-					// else fallthrough...
-				default: // aka: last
-					refNode.appendChild(node);
-			}
-		}
-		return node; // DomNode
-	};
-
-	// Box functions will assume this model.
-	// On IE/Opera, BORDER_BOX will be set if the primary document is in quirks mode.
-	// Can be set to change behavior of box setters.
-
-	// can be either:
-	//	"border-box"
-	//	"content-box" (default)
-	dojo.boxModel = "content-box";
-
-	// We punt per-node box mode testing completely.
-	// If anybody cares, we can provide an additional (optional) unit
-	// that overrides existing code to include per-node box sensitivity.
-
-	// Opera documentation claims that Opera 9 uses border-box in BackCompat mode.
-	// but experiments (Opera 9.10.8679 on Windows Vista) indicate that it actually continues to use content-box.
-	// 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(d.isIE /*|| dojo.isOpera*/){
-		// client code may have to adjust if compatMode varies across iframes
-		d.boxModel = document.compatMode == "BackCompat" ? "border-box" : "content-box";
-	}
-	//>>excludeEnd("webkitMobile");
-
-	// =============================
-	// Style Functions
-	// =============================
-
-	// getComputedStyle drives most of the style code.
-	// Wherever possible, reuse the returned object.
-	//
-	// API functions below that need to access computed styles accept an
-	// optional computedStyle parameter.
-	// If this parameter is omitted, the functions will call getComputedStyle themselves.
-	// This way, calling code can access computedStyle once, and then pass the reference to
-	// multiple API functions.
-
-/*=====
-	dojo.getComputedStyle = function(node){
-		//	summary:
-		//		Returns a "computed style" object.
-		//
-		//	description:
-		//		Gets a "computed style" object which can be used to gather
-		//		information about the current state of the rendered node.
-		//
-		//		Note that this may behave differently on different browsers.
-		//		Values may have different formats and value encodings across
-		//		browsers.
-		//
-		//		Note also that this method is expensive.  Wherever possible,
-		//		reuse the returned object.
-		//
-		//		Use the dojo.style() method for more consistent (pixelized)
-		//		return values.
-		//
-		//	node: DOMNode
-		//		A reference to a DOM node. Does NOT support taking an
-		//		ID string for speed reasons.
-		//	example:
-		//	|	dojo.getComputedStyle(dojo.byId('foo')).borderWidth;
-		//
-		//	example:
-		//	Reusing the returned object, avoiding multiple lookups:
-		//	|	var cs = dojo.getComputedStyle(dojo.byId("someNode"));
-		//	|	var w = cs.width, h = cs.height;
-		return; // CSS2Properties
-	}
-=====*/
-
-	// 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 gcs;
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	if(d.isWebKit){
-	//>>excludeEnd("webkitMobile");
-		gcs = 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(d.isIE){
-		gcs = function(node){
-			// IE (as of 7) doesn't expose Element like sane browsers
-			return node.nodeType == 1 /* ELEMENT_NODE*/ ? node.currentStyle : {};
-		};
-	}else{
-		gcs = function(node){
-			return node.nodeType == 1 ?
-				node.ownerDocument.defaultView.getComputedStyle(node, null) : {};
-		};
-	}
-	//>>excludeEnd("webkitMobile");
-	dojo.getComputedStyle = gcs;
-
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	if(!d.isIE){
-	//>>excludeEnd("webkitMobile");
-		d._toPixelValue = 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{
-		d._toPixelValue = function(element, avalue){
-			if(!avalue){ return 0; }
-			// on IE7, medium is usually 4 pixels
-			if(avalue == "medium"){ return 4; }
-			// style values can be floats, client code may
-			// want to round this value for integer pixels.
-			if(avalue.slice && avalue.slice(-2) == 'px'){ return parseFloat(avalue); }
-			with(element){
-				var sLeft = style.left;
-				var rsLeft = runtimeStyle.left;
-				runtimeStyle.left = currentStyle.left;
-				try{
-					// 'avalue' may be incompatible with style.left, which can cause IE to throw
-					// this has been observed for border widths using "thin", "medium", "thick" constants
-					// those particular constants could be trapped by a lookup
-					// but perhaps there are more
-					style.left = avalue;
-					avalue = style.pixelLeft;
-				}catch(e){
-					avalue = 0;
-				}
-				style.left = sLeft;
-				runtimeStyle.left = rsLeft;
-			}
-			return avalue;
-		};
-	}
-	//>>excludeEnd("webkitMobile");
-	var px = d._toPixelValue;
-
-	// FIXME: there opacity quirks on FF that we haven't ported over. Hrm.
-	/*=====
-	dojo._getOpacity = function(node){
-			//	summary:
-			//		Returns the current opacity of the passed node as a
-			//		floating-point value between 0 and 1.
-			//	node: DomNode
-			//		a reference to a DOM node. Does NOT support taking an
-			//		ID string for speed reasons.
-			//	returns: Number between 0 and 1
-			return; // Number
-	}
-	=====*/
-
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	var astr = "DXImageTransform.Microsoft.Alpha";
-	var af = function(n, f){
-		try{
-			return n.filters.item(astr);
-		}catch(e){
-			return f ? {} : null;
-		}
-	};
-
-	//>>excludeEnd("webkitMobile");
-	dojo._getOpacity =
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		d.isIE < 9 ? function(node){
-			try{
-				return af(node).Opacity / 100; // Number
-			}catch(e){
-				return 1; // Number
-			}
-		} :
-	//>>excludeEnd("webkitMobile");
-		function(node){
-			return gcs(node).opacity;
-		};
-
-	/*=====
-	dojo._setOpacity = function(node, opacity){
-			//	summary:
-			//		set the opacity of the passed node portably. Returns the
-			//		new opacity of the node.
-			//	node: DOMNode
-			//		a reference to a DOM node. Does NOT support taking an
-			//		ID string for performance reasons.
-			//	opacity: Number
-			//		A Number between 0 and 1. 0 specifies transparent.
-			//	returns: Number between 0 and 1
-			return; // Number
-	}
-	=====*/
-
-	dojo._setOpacity =
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		d.isIE < 9 ? function(/*DomNode*/node, /*Number*/opacity){
-			var ov = opacity * 100, opaque = opacity == 1;
-			node.style.zoom = opaque ? "" : 1;
-
-			if(!af(node)){
-				if(opaque){
-					return opacity;
-				}
-				node.style.filter += " progid:" + astr + "(Opacity=" + ov + ")";
-			}else{
-				af(node, 1).Opacity = ov;
-			}
-
-			// 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.nodeName.toLowerCase() == "tr"){
-				d.query("> td", node).forEach(function(i){
-					d._setOpacity(i, opacity);
-				});
-			}
-			return opacity;
-		} :
-		//>>excludeEnd("webkitMobile");
-		function(node, opacity){
-			return node.style.opacity = opacity;
-		};
-
-	var _pixelNamesCache = {
-		left: true, top: true
-	};
-	var _pixelRegExp = /margin|padding|width|height|max|min|offset/;  // |border
-	var _toStyleValue = function(node, type, value){
-		type = type.toLowerCase(); // FIXME: should we really be doing string case conversion here? Should we cache it? Need to profile!
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		if(d.isIE){
-			if(value == "auto"){
-				if(type == "height"){ return node.offsetHeight; }
-				if(type == "width"){ return node.offsetWidth; }
-			}
-			if(type == "fontweight"){
-				switch(value){
-					case 700: return "bold";
-					case 400:
-					default: return "normal";
-				}
-			}
-		}
-		//>>excludeEnd("webkitMobile");
-		if(!(type in _pixelNamesCache)){
-			_pixelNamesCache[type] = _pixelRegExp.test(type);
-		}
-		return _pixelNamesCache[type] ? px(node, value) : value;
-	};
-
-	var _floatStyle = d.isIE ? "styleFloat" : "cssFloat",
-		_floatAliases = { "cssFloat": _floatStyle, "styleFloat": _floatStyle, "float": _floatStyle }
-	;
-
-	// public API
-
-	dojo.style = function(	/*DomNode|String*/ node,
-							/*String?|Object?*/ style,
-							/*String?*/ value){
-		//	summary:
-		//		Accesses styles on a node. If 2 arguments are
-		//		passed, acts as a getter. If 3 arguments are passed, acts
-		//		as a setter.
-		//	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:
-		//		id or reference to node to get/set style for
-		//	style:
-		//		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:
-		//		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 only an ID or node returns the computed style object of
-		//		the node:
-		//	|	dojo.style("thinger");
-		//	example:
-		//		Passing a node and a style property returns the current
-		//		normalized, computed value for that property:
-		//	|	dojo.style("thinger", "opacity"); // 1 by default
-		//
-		//	example:
-		//		Passing a node, a style property, and a value changes the
-		//		current display of the node and returns the new computed value
-		//	|	dojo.style("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.style("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.style("thinger",{
-		//	|		fontSize:"14pt",
-		//	|		letterSpacing:"1.2em"
+		//	Set multiple values at once, including event handlers:
+		//	|	dojo.attr("formId", {
+		//	|		"foo": "bar",
+		//	|		"tabIndex": -1,
+		//	|		"method": "POST",
+		//	|		"onsubmit": function(e){
+		//	|			// stop submitting the form. Note that the IE behavior
+		//	|			// of returning true or false will have no effect here
+		//	|			// since our handler is connect()ed to the built-in
+		//	|			// onsubmit behavior and so we need to use
+		//	|			// dojo.stopEvent() to ensure that the submission
+		//	|			// doesn't proceed.
+		//	|			dojo.stopEvent(e);
+		//	|
+		//	|			// submit the form with Ajax
+		//	|			dojo.xhrPost({ form: "formId" });
+		//	|		}
 		//	|	});
 		//
-		//	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"
+		// example:
+		//	Style is s special case: Only set with an object hash of styles
+		//	|	dojo.attr("someNode",{
+		//	|		id:"bar",
+		//	|		style:{
+		//	|			width:"200px", height:"100px", color:"#000"
+		//	|		}
 		//	|	});
-
-		var n = byId(node), args = arguments.length, op = (style == "opacity");
-		style = _floatAliases[style] || style;
-		if(args == 3){
-			return op ? d._setOpacity(n, value) : n.style[style] = value; /*Number*/
-		}
-		if(args == 2 && op){
-			return d._getOpacity(n);
-		}
-		var s = gcs(n);
-		if(args == 2 && typeof style != "string"){ // inline'd type check
-			for(var x in style){
-				d.style(node, x, style[x]);
-			}
-			return s;
-		}
-		return (args == 1) ? s : _toStyleValue(n, style, s[style] || n.style[style]); /* CSS2Properties||String||Number */
-	};
-
-	// =============================
-	// Box Functions
-	// =============================
-
-	dojo._getPadExtents = function(/*DomNode*/n, /*Object*/computedStyle){
-		//	summary:
-		// 		Returns object with special values specifically useful for node
-		// 		fitting.
-		//	description:
-		//		Returns an object with `w`, `h`, `l`, `t` properties:
-		//	|		l/t = left/top padding (respectively)
-		//	|		w = the total of the left and right padding
-		//	|		h = the total of the top and bottom padding
-		//		If 'node' has position, l/t forms the origin for child nodes.
-		//		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.
-		var
-			s = computedStyle||gcs(n),
-			l = px(n, s.paddingLeft),
-			t = px(n, s.paddingTop);
-		return {
-			l: l,
-			t: t,
-			w: l+px(n, s.paddingRight),
-			h: t+px(n, s.paddingBottom)
-		};
-	};
-
-	dojo._getBorderExtents = function(/*DomNode*/n, /*Object*/computedStyle){
-		//	summary:
-		//		returns an object with properties useful for noting the border
-		//		dimensions.
-		//	description:
-		// 		* l/t = the sum of left/top 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.
-		var
-			ne = "none",
-			s = computedStyle||gcs(n),
-			bl = (s.borderLeftStyle != ne ? px(n, s.borderLeftWidth) : 0),
-			bt = (s.borderTopStyle != ne ? px(n, s.borderTopWidth) : 0);
-		return {
-			l: bl,
-			t: bt,
-			w: bl + (s.borderRightStyle!=ne ? px(n, s.borderRightWidth) : 0),
-			h: bt + (s.borderBottomStyle!=ne ? px(n, s.borderBottomWidth) : 0)
-		};
-	};
-
-	dojo._getPadBorderExtents = function(/*DomNode*/n, /*Object*/computedStyle){
-		//	summary:
-		//		Returns object with properties useful for box fitting with
-		//		regards to padding.
-		// description:
-		//		* l/t = the sum of left/top padding and left/top 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.
-		var
-			s = computedStyle||gcs(n),
-			p = d._getPadExtents(n, s),
-			b = d._getBorderExtents(n, s);
-		return {
-			l: p.l + b.l,
-			t: p.t + b.t,
-			w: p.w + b.w,
-			h: p.h + b.h
-		};
-	};
-
-	dojo._getMarginExtents = function(n, 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.
-		var
-			s = computedStyle||gcs(n),
-			l = px(n, s.marginLeft),
-			t = px(n, s.marginTop),
-			r = px(n, s.marginRight),
-			b = px(n, s.marginBottom);
-		if(d.isWebKit && (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,
-			w: l+r,
-			h: t+b
-		};
-	};
-
-	// Box getters work in any box context because offsetWidth/clientWidth
-	// are invariant wrt box context
-	//
-	// They do *not* work for display: inline objects that have padding styles
-	// because the user agent ignores padding (it's bogus styling in any case)
-	//
-	// Be careful with IMGs because they are inline or block depending on
-	// browser and browser mode.
-
-	// Although it would be easier to read, there are not separate versions of
-	// _getMarginBox for each browser because:
-	// 1. the branching is not expensive
-	// 2. factoring the shared code wastes cycles (function call overhead)
-	// 3. duplicating the shared code wastes bytes
-
-	dojo._getMarginBox = function(/*DomNode*/node, /*Object*/computedStyle){
-		// summary:
-		//		returns an object that encodes the width, height, left and top
-		//		positions of the node's margin box.
-		var s = computedStyle || gcs(node), me = d._getMarginExtents(node, s);
-		var l = node.offsetLeft - me.l, t = node.offsetTop - me.t, p = node.parentNode;
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		if(d.isMoz){
-			// Mozilla:
-			// If offsetParent has a computed overflow != visible, the offsetLeft is decreased
-			// by the parent's border.
-			// We don't want to compute the parent's style, so instead we examine node's
-			// 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;
-			}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.
-				if(p && p.style){
-					var pcs = gcs(p);
-					if(pcs.overflow != "visible"){
-						var be = d._getBorderExtents(p, pcs);
-						l += be.l, t += be.t;
-					}
-				}
-			}
-		}else if(d.isOpera || (d.isIE > 7 && !d.isQuirks)){
-			// On Opera and IE 8, offsetLeft/Top includes the parent's border
-			if(p){
-				be = d._getBorderExtents(p);
-				l -= be.l;
-				t -= be.t;
-			}
-		}
-		//>>excludeEnd("webkitMobile");
-		return {
-			l: l,
-			t: t,
-			w: node.offsetWidth + me.w,
-			h: node.offsetHeight + me.h
-		};
-	}
-	
-	dojo._getMarginSize = function(/*DomNode*/node, /*Object*/computedStyle){
-		// summary:
-		//	returns an object that encodes the width and height of
-		//	the node's margin box
-		node = byId(node);
-		var me = d._getMarginExtents(node, computedStyle || gcs(node));
-
-		var size = node.getBoundingClientRect();
-		return {
-			w: (size.right - size.left) + me.w,
-			h: (size.bottom - size.top) + me.h
-		}
-	}
-
-	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.
-
-		// clientWidth/Height are important since the automatically account for scrollbars
-		// fallback to offsetWidth/Height for special cases (see #3378)
-		var s = computedStyle || gcs(node),
-			pe = d._getPadExtents(node, s),
-			be = d._getBorderExtents(node, s),
-			w = node.clientWidth,
-			h
-		;
-		if(!w){
-			w = node.offsetWidth, h = node.offsetHeight;
-		}else{
-			h = node.clientHeight, be.w = be.h = 0;
-		}
-		// On Opera, offsetLeft includes the parent's border
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		if(d.isOpera){ 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
-		};
-	};
-
-	dojo._getBorderBox = function(node, computedStyle){
-		var s = computedStyle || gcs(node),
-			pe = d._getPadExtents(node, s),
-			cb = d._getContentBox(node, s)
-		;
-		return {
-			l: cb.l - pe.l,
-			t: cb.t - pe.t,
-			w: cb.w + pe.w,
-			h: cb.h + pe.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.
-	//
-	// Beware of display: inline objects that have padding styles
-	// because the user agent ignores padding (it's a bogus setup anyway)
-	//
-	// Be careful with IMGs because they are inline or block depending on
-	// browser and browser mode.
-	//
-	// Elements other than DIV may have special quirks, like built-in
-	// margins or padding, or values not detectable via computedStyle.
-	// In particular, margins on TABLE do not seems to appear
-	// at all in computedStyle on Mozilla.
-
-	dojo._setBox = function(/*DomNode*/node, /*Number?*/l, /*Number?*/t, /*Number?*/w, /*Number?*/h, /*String?*/u){
-		//	summary:
-		//		sets width/height/left/top in the current (native) box-model
-		//		dimentions. Uses the unit passed in u.
-		//	node:
-		//		DOM Node reference. Id string not supported for performance
-		//		reasons.
-		//	l:
-		//		left offset from parent.
-		//	t:
-		//		top offset from parent.
-		//	w:
-		//		width in current box model.
-		//	h:
-		//		width in current box model.
-		//	u:
-		//		unit measure to use for other measures. Defaults to "px".
-		u = u || "px";
-		var s = node.style;
-		if(!isNaN(l)){ s.left = l + u; }
-		if(!isNaN(t)){ s.top = t + u; }
-		if(w >= 0){ s.width = w + u; }
-		if(h >= 0){ s.height = h + u; }
-	};
+		// example:
+		//	Again, only set style as an object hash of styles:
+		//	|	var obj = { color:"#fff", backgroundColor:"#000" };
+		//	|	dojo.attr("someNode", "style", obj);
+		//	|
+		//	|	// though shorter to use `dojo.style()` in this case:
+		//	|	dojo.style("someNode", obj);
 
-	dojo._isButtonTag = function(/*DomNode*/node) {
+		if(arguments.length == 2){
+			return attr[typeof name == "string" ? "get" : "set"](node, name);
+		}
+		return attr.set(node, name, value);
+	};
+
+	// mix-in dom-class
+	dojo.hasClass = cls.contains;
+	dojo.addClass = cls.add;
+	dojo.removeClass = cls.remove;
+	dojo.toggleClass = cls.toggle;
+	dojo.replaceClass = cls.replace;
+
+	// mix-in dom-construct
+	dojo._toDom = dojo.toDom = ctr.toDom;
+	dojo.place = ctr.place;
+	dojo.create = ctr.create;
+	dojo.empty = function(node){ ctr.empty(node); };
+	dojo._destroyElement = dojo.destroy = function(node){ ctr.destroy(node); };
+
+	// mix-in dom-geometry
+	dojo._getPadExtents = dojo.getPadExtents = geom.getPadExtents;
+	dojo._getBorderExtents = dojo.getBorderExtents = geom.getBorderExtents;
+	dojo._getPadBorderExtents = dojo.getPadBorderExtents = geom.getPadBorderExtents;
+	dojo._getMarginExtents = dojo.getMarginExtents = geom.getMarginExtents;
+	dojo._getMarginSize = dojo.getMarginSize = geom.getMarginSize;
+	dojo._getMarginBox = dojo.getMarginBox = geom.getMarginBox;
+	dojo.setMarginBox = geom.setMarginBox;
+	dojo._getContentBox = dojo.getContentBox = geom.getContentBox;
+	dojo.setContentSize = geom.setContentSize;
+	dojo._isBodyLtr = dojo.isBodyLtr = geom.isBodyLtr;
+	dojo._docScroll = dojo.docScroll = geom.docScroll;
+	dojo._getIeDocumentElementOffset = dojo.getIeDocumentElementOffset = geom.getIeDocumentElementOffset;
+	dojo._fixIeBiDiScrollLeft = dojo.fixIeBiDiScrollLeft = geom.fixIeBiDiScrollLeft;
+	dojo.position = geom.position;
+
+	dojo.marginBox = function marginBox(/*DomNode|String*/node, /*Object?*/box){
 		// summary:
-		//		True if the node is BUTTON or INPUT.type="button".
-		return node.tagName == "BUTTON"
-			|| node.tagName=="INPUT" && (node.getAttribute("type")||'').toUpperCase() == "BUTTON"; // boolean
-	};
-
-	dojo._usesBorderBox = function(/*DomNode*/node){
-		//	summary:
-		//		True if the node uses border-box layout.
-
-		// We could test the computed style of node to see if a particular box
-		// has been specified, but there are details and we choose not to bother.
-
-		// TABLE and BUTTON (and INPUT type=button) are always border-box by default.
-		// If you have assigned a different box to either one via CSS then
-		// box functions will break.
-
-		var n = node.tagName;
-		return d.boxModel=="border-box" || n=="TABLE" || d._isButtonTag(node); // boolean
-	};
-
-	dojo._setContentSize = function(/*DomNode*/node, /*Number*/widthPx, /*Number*/heightPx, /*Object*/computedStyle){
-		//	summary:
-		//		Sets the size of the node's contents, irrespective of margins,
-		//		padding, or borders.
-		if(d._usesBorderBox(node)){
-			var pb = d._getPadBorderExtents(node, computedStyle);
-			if(widthPx >= 0){ widthPx += pb.w; }
-			if(heightPx >= 0){ heightPx += pb.h; }
-		}
-		d._setBox(node, NaN, NaN, widthPx, heightPx);
-	};
-
-	dojo._setMarginBox = function(/*DomNode*/node, 	/*Number?*/leftPx, /*Number?*/topPx,
-													/*Number?*/widthPx, /*Number?*/heightPx,
-													/*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 dojo._setBox that handles box-model vagaries for
-		//		you.
-
-		var s = computedStyle || gcs(node),
-		// 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.
-			bb = d._usesBorderBox(node),
-			pb = bb ? _nilExtents : d._getPadBorderExtents(node, s)
-		;
-		if(d.isWebKit){
-			// on Safari (3.1.2), button nodes with no explicit size have a default margin
-			// setting an explicit size eliminates the margin.
-			// We have to swizzle the width to get correct margin reading.
-			if(d._isButtonTag(node)){
-				var ns = node.style;
-				if(widthPx >= 0 && !ns.width) { ns.width = "4px"; }
-				if(heightPx >= 0 && !ns.height) { ns.height = "4px"; }
-			}
-		}
-		var mb = d._getMarginExtents(node, s);
-		if(widthPx >= 0){ widthPx = Math.max(widthPx - pb.w - mb.w, 0); }
-		if(heightPx >= 0){ heightPx = Math.max(heightPx - pb.h - mb.h, 0); }
-		d._setBox(node, leftPx, topPx, widthPx, heightPx);
-	};
-
-	var _nilExtents = { l:0, t:0, w:0, h:0 };
-
-	// public API
-
-	dojo.marginBox = function(/*DomNode|String*/node, /*Object?*/box){
-		//	summary:
 		//		Getter/setter for the margin-box of node.
-		//	description:
+		// description:
 		//		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:
@@ -1000,30 +144,28 @@ if(dojo.isIE){
 		//		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.
-		//	node:
+		// node:
 		//		id or reference to DOM Node to get/set box for
-		//	box:
+		// box:
 		//		If passed, denotes that dojo.marginBox() should
 		//		update/set the margin box for node. Box is an object in the
 		//		above format. All properties are optional if passed.
-		//	example:
-		//	Retrieve the marginbox of a passed node
+		// example:
+		//		Retrieve the margin box of a passed node
 		//	|	var box = dojo.marginBox("someNodeId");
 		//	|	console.dir(box);
 		//
-		//	example:
-		//	Set a node's marginbox to the size of another node
+		// example:
+		//		Set a node's margin box to the size of another node
 		//	|	var box = dojo.marginBox("someNodeId");
 		//	|	dojo.marginBox("someOtherNode", box);
-		
-		var n = byId(node), s = gcs(n), b = box;
-		return !b ? d._getMarginBox(n, s) : d._setMarginBox(n, b.l, b.t, b.w, b.h, s); // Object
+		return box ? geom.setMarginBox(node, box) : geom.getMarginBox(node); // Object
 	};
 
-	dojo.contentBox = function(/*DomNode|String*/node, /*Object?*/box){
-		//	summary:
+	dojo.contentBox = function contentBox(/*DomNode|String*/node, /*Object?*/box){
+		// summary:
 		//		Getter/setter for the content-box of node.
-		//	description:
+		// 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 }`
@@ -1034,171 +176,23 @@ if(dojo.isIE){
 		//		CSS values set/inherited for node.
 		//		While the getter will return top and left values, the
 		//		setter only accepts setting the width and height.
-		//	node:
+		// node:
 		//		id or reference to DOM Node to get/set box for
-		//	box:
+		// box:
 		//		If passed, denotes that dojo.contentBox() should
 		//		update/set the content box for node. Box is an object in the
 		//		above format, but only w (width) and h (height) are supported.
 		//		All properties are optional if passed.
-		var n = byId(node), s = gcs(n), b = box;
-		return !b ? d._getContentBox(n, s) : d._setContentSize(n, b.w, b.h, s); // Object
-	};
-
-	// =============================
-	// Positioning
-	// =============================
-
-	var _sumAncestorProperties = function(node, prop){
-		if(!(node = (node||0).parentNode)){return 0;}
-		var val, retVal = 0, _b = d.body();
-		while(node && node.style){
-			if(gcs(node).position == "fixed"){
-				return 0;
-			}
-			val = node[prop];
-			if(val){
-				retVal += val - 0;
-				// opera and khtml #body & #html has the same values, we only
-				// need one value
-				if(node == _b){ break; }
-			}
-			node = node.parentNode;
-		}
-		return retVal;	//	integer
-	};
-
-	dojo._docScroll = function(){
-		var n = d.global;
-		return "pageXOffset" in n
-			? { x:n.pageXOffset, y:n.pageYOffset }
-			: (n = d.isQuirks? d.doc.body : d.doc.documentElement, { x:d._fixIeBiDiScrollLeft(n.scrollLeft || 0), y:n.scrollTop || 0 });
-	};
-
-	dojo._isBodyLtr = function(){
-		return "_bodyLtr" in d? d._bodyLtr :
-			d._bodyLtr = (d.body().dir || d.doc.documentElement.dir || "ltr").toLowerCase() == "ltr"; // Boolean
-	};
-
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	dojo._getIeDocumentElementOffset = function(){
-		//	summary:
-		//		returns the offset in x and y from the document body to the
-		//		visual edge of the page
-		//	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
-
-		var de = d.doc.documentElement; // only deal with HTML element here, _abs handles body/quirks
-
-		if(d.isIE < 8){
-			var r = de.getBoundingClientRect(); // works well for IE6+
-			//console.debug('rect left,top = ' + r.left+','+r.top + ', html client left/top = ' + de.clientLeft+','+de.clientTop + ', rtl = ' + (!d._isBodyLtr()) + ', quirks = ' + d.isQuirks);
-			var l = r.left,
-			    t = r.top;
-			if(d.isIE < 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
-			};
-		}
-
-	};
-	//>>excludeEnd("webkitMobile");
-
-	dojo._fixIeBiDiScrollLeft = function(/*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);
-		var ie = d.isIE;
-		if(ie && !d._isBodyLtr()){
-			var qk = d.isQuirks,
-				de = qk ? d.doc.body : d.doc.documentElement;
-			if(ie == 6 && !qk && d.global.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
-	};
-
-	// FIXME: need a setter for coords or a moveTo!!
-	dojo._abs = dojo.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 = byId(node);
-		var	db = d.body(),
-			dh = db.parentNode,
-			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(d.isIE){
-				// On IE there's a 2px offset that we need to adjust for, see _getIeDocumentElementOffset()
-				var offset = d._getIeDocumentElementOffset();
-
-				// fixes the position in IE, quirks mode
-				ret.x -= offset.x + (d.isQuirks ? db.clientLeft+db.offsetLeft : 0);
-				ret.y -= offset.y + (d.isQuirks ? db.clientTop+db.offsetTop : 0);
-			}else if(d.isFF == 3){
-				// In FF3 you have to subtract the document element margins.
-				// Fixed in FF3.5 though.
-				var cs = gcs(dh);
-				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(includeScroll){
-			var scroll = d._docScroll();
-			ret.x += scroll.x;
-			ret.y += scroll.y;
-		}
-
-		return ret; // Object
+		return box ? geom.setContentSize(node, box) : geom.getContentBox(node); // Object
 	};
 
 	dojo.coords = function(/*DomNode|String*/node, /*Boolean?*/includeScroll){
-		//	summary:
+		// 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:
+		// 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
@@ -1207,88 +201,25 @@ if(dojo.isIE){
 		//|			{ l: 50, t: 200, w: 300: h: 150, x: 100, y: 300 }
 		//		Does not act as a setter. If includeScroll is passed, the x and
 		//		y params are affected as one would expect in dojo.position().
-		var n = byId(node), s = gcs(n), mb = d._getMarginBox(n, s);
-		var abs = d.position(n, includeScroll);
+		dojo.deprecated("dojo.coords()", "Use dojo.position() or dojo.marginBox().");
+		node = dom.byId(node);
+		var s = style.getComputedStyle(node), mb = geom.getMarginBox(node, s);
+		var abs = geom.position(node, includeScroll);
 		mb.x = abs.x;
 		mb.y = abs.y;
-		return mb;
-	};
-
-	// =============================
-	// Element attribute Functions
-	// =============================
-
-	// dojo.attr() should conform to http://www.w3.org/TR/DOM-Level-2-Core/
-
-	var _propNames = {
-			// 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"
-		},
-		_attrNames = {
-			// original attribute names
-			classname: "class",
-			htmlfor:   "for",
-			// for IE
-			tabindex:  "tabIndex",
-			readonly:  "readOnly"
-		},
-		_forcePropNames = {
-			innerHTML: 1,
-			className: 1,
-			htmlFor:   d.isIE,
-			value:     1
-		};
-
-	var _fixAttrName = function(/*String*/ name){
-		return _attrNames[name.toLowerCase()] || name;
-	};
-
-	var _hasAttr = function(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.
-
-	dojo.hasAttr = function(/*DomNode|String*/node, /*String*/name){
-		//	summary:
-		//		Returns true if the requested attribute is specified on the
-		//		given element, and false otherwise.
-		//	node:
-		//		id or reference to the element to check
-		//	name:
-		//		the name of the attribute
-		//	returns:
-		//		true if the requested attribute is specified on the
-		//		given element, and false otherwise
-		var lc = name.toLowerCase();
-		return _forcePropNames[_propNames[lc] || name] || _hasAttr(byId(node), _attrNames[lc] || name);	// Boolean
+		return mb;	// Object
 	};
 
-	var _evtHdlrMap = {}, _ctr = 0,
-		_attrId = dojo._scopeName + "attrid",
-		// the next dictionary lists elements with read-only innerHTML on IE
-		_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};
+	// mix-in dom-prop
+	dojo.getProp = prop.get;
+	dojo.setProp = prop.set;
 
-	dojo.attr = function(/*DomNode|String*/node, /*String|Object*/name, /*String?*/value){
-		//	summary:
-		//		Gets or sets an attribute on an HTML element.
-		//	description:
-		//		Handles normalized getting and setting of attributes on DOM
-		//		Nodes. If 2 arguments are passed, and a the second argumnt is a
+	dojo.prop = function(/*DomNode|String*/node, /*String|Object*/name, /*String?*/value){
+		// summary:
+		//		Gets or sets a property on an HTML element.
+		// description:
+		//		Handles normalized getting and setting of properties on DOM
+		//		Nodes. If 2 arguments are passed, and a the second argument is a
 		//		string, acts as a getter.
 		//
 		//		If a third argument is passed, or if the second argument is a
@@ -1303,33 +234,33 @@ if(dojo.isIE){
 		//		should cancel form submission using `dojo.stopEvent()` on the
 		//		passed event object instead of returning a boolean value from
 		//		the handler itself.
-		//	node:
-		//		id or reference to the element to get or set the attribute on
-		//	name:
-		//		the name of the attribute to get or set.
-		//	value:
-		//		The value to set for the attribute
-		//	returns:
-		//		when used as a getter, the value of the requested attribute
+		// node:
+		//		id or reference to the element to get or set the property on
+		// name:
+		//		the name of the property to get or set.
+		// value:
+		//		The value to set for the property
+		// returns:
+		//		when used as a getter, the value of the requested property
 		//		or null if that attribute does not have a specified or
 		//		default value;
 		//
 		//		when used as a setter, the DOM node
 		//
-		//	example:
-		//	|	// get the current value of the "foo" attribute on a node
-		//	|	dojo.attr(dojo.byId("nodeId"), "foo");
+		// example:
+		//	|	// get the current value of the "foo" property on a node
+		//	|	dojo.prop(dojo.byId("nodeId"), "foo");
 		//	|	// or we can just pass the id:
-		//	|	dojo.attr("nodeId", "foo");
+		//	|	dojo.prop("nodeId", "foo");
 		//
-		//	example:
-		//	|	// use attr() to set the tab index
-		//	|	dojo.attr("nodeId", "tabIndex", 3);
+		// example:
+		//	|	// use prop() to set the tab index
+		//	|	dojo.prop("nodeId", "tabIndex", 3);
 		//	|
 		//
-		//	example:
+		// example:
 		//	Set multiple values at once, including event handlers:
-		//	|	dojo.attr("formId", {
+		//	|	dojo.prop("formId", {
 		//	|		"foo": "bar",
 		//	|		"tabIndex": -1,
 		//	|		"method": "POST",
@@ -1347,530 +278,112 @@ if(dojo.isIE){
 		//	|		}
 		//	|	});
 		//
-		//	example:
+		// example:
 		//	Style is s special case: Only set with an object hash of styles
-		//	|	dojo.attr("someNode",{
+		//	|	dojo.prop("someNode",{
 		//	|		id:"bar",
 		//	|		style:{
 		//	|			width:"200px", height:"100px", color:"#000"
 		//	|		}
 		//	|	});
 		//
-		//	example:
+		// example:
 		//	Again, only set style as an object hash of styles:
 		//	|	var obj = { color:"#fff", backgroundColor:"#000" };
-		//	|	dojo.attr("someNode", "style", obj);
+		//	|	dojo.prop("someNode", "style", obj);
 		//	|
 		//	|	// though shorter to use `dojo.style()` in this case:
 		//	|	dojo.style("someNode", obj);
 
-		node = byId(node);
-		var args = arguments.length, prop;
-		if(args == 2 && typeof name != "string"){ // inline'd type check
-			// the object form of setter: the 2nd argument is a dictionary
-			for(var x in name){
-				d.attr(node, x, name[x]);
-			}
-			return node; // DomNode
-		}
-		var lc = name.toLowerCase(),
-			propName = _propNames[lc] || name,
-			forceProp = _forcePropNames[propName],
-			attrName = _attrNames[lc] || name;
-		if(args == 3){
-			// setter
-			do{
-				if(propName == "style" && typeof value != "string"){ // inline'd type check
-					// special case: setting a style
-					d.style(node, value);
-					break;
-				}
-				if(propName == "innerHTML"){
-					// special case: assigning HTML
-					//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-					if(d.isIE && node.tagName.toLowerCase() in _roInnerHtml){
-						d.empty(node);
-						node.appendChild(d._toDom(value, node.ownerDocument));
-					}else{
-					//>>excludeEnd("webkitMobile");
-						node[propName] = value;
-					//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-					}
-					//>>excludeEnd("webkitMobile");
-					break;
-				}
-				if(d.isFunction(value)){
-					// special case: assigning an event handler
-					// clobber if we can
-					var attrId = d.attr(node, _attrId);
-					if(!attrId){
-						attrId = _ctr++;
-						d.attr(node, _attrId, attrId);
-					}
-					if(!_evtHdlrMap[attrId]){
-						_evtHdlrMap[attrId] = {};
-					}
-					var h = _evtHdlrMap[attrId][propName];
-					if(h){
-						d.disconnect(h);
-					}else{
-						try{
-							delete node[propName];
-						}catch(e){}
-					}
-					// ensure that event objects are normalized, etc.
-					_evtHdlrMap[attrId][propName] = d.connect(node, propName, value);
-					break;
-				}
-				if(forceProp || typeof value == "boolean"){
-					// special case: forcing assignment to the property
-					// special case: setting boolean to a property instead of attribute
-					node[propName] = value;
-					break;
-				}
-				// node's attribute
-				node.setAttribute(attrName, value);
-			}while(false);
-			return node; // DomNode
-		}
-		// getter
-		// 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(arguments.length == 2){
+			return prop[typeof name == "string" ? "get" : "set"](node, name);
 		}
-		if(propName != "href" && (typeof value == "boolean" || d.isFunction(value))){
-			// node's property
-			return value;	// Anything
-		}
-		// node's attribute
-		// we need _hasAttr() here to guard against IE returning a default value
-		return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
-	};
-
-	dojo.removeAttr = function(/*DomNode|String*/ node, /*String*/ name){
-		//	summary:
-		//		Removes an attribute from an HTML element.
-		//	node:
-		//		id or reference to the element to remove the attribute from
-		//	name:
-		//		the name of the attribute to remove
-		byId(node).removeAttribute(_fixAttrName(name));
+		// setter
+		return prop.set(node, name, value);
 	};
 
-	dojo.getNodeProp = function(/*DomNode|String*/ node, /*String*/ name){
-		//	summary:
-		//		Returns an effective value of a property or an attribute.
-		//	node:
-		//		id or reference to the element to remove the attribute from
-		//	name:
-		//		the name of the attribute
-		node = byId(node);
-		var lc = name.toLowerCase(),
-			propName = _propNames[lc] || name;
-		if((propName in node) && propName != "href"){
-			// node's property
-			return node[propName];	// Anything
-		}
-		// node's attribute
-		var attrName = _attrNames[lc] || name;
-		return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
-	};
+	// mix-in dom-style
+	dojo.getStyle = style.get;
+	dojo.setStyle = style.set;
+	dojo.getComputedStyle = style.getComputedStyle;
+	dojo.__toPixelValue = dojo.toPixelValue = style.toPixelValue;
 
-	dojo.create = function(tag, attrs, refNode, pos){
-		//	summary:
-		//		Create an element, allowing for optional attribute decoration
-		//		and placement.
-		//
+	dojo.style = function(node, name, value){
+		// summary:
+		//		Accesses styles on a node. If 2 arguments are
+		//		passed, acts as a getter. If 3 arguments are passed, acts
+		//		as a setter.
 		// 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.attr`.
-		//		See `dojo.attr` 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: String|DomNode
-		//		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.attr` for a description of available attributes.
-		//
-		// refNode: String?|DomNode?
-		//		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
-		//
+		//		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/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.
+		// returns:
+		//		when used as a getter, return the computed style of the node if passing in an ID or node,
+		//		or return the normalized, computed value for the property when passing in a node and a style property
 		// example:
-		//	Create a DIV:
-		//	|	var n = dojo.create("div");
-		//
+		//		Passing only an ID or node returns the computed style object of
+		//		the node:
+		//	|	dojo.style("thinger");
 		// example:
-		//	Create a DIV with content:
-		//	|	var n = dojo.create("div", { innerHTML:"<p>hi</p>" });
+		//		Passing a node and a style property returns the current
+		//		normalized, computed value for that property:
+		//	|	dojo.style("thinger", "opacity"); // 1 by default
 		//
 		// example:
-		//	Place a new DIV in the BODY, with no attributes set
-		//	|	var n = dojo.create("div", null, dojo.body());
+		//		Passing a node, a style property, and a value changes the
+		//		current display of the node and returns the new computed value
+		//	|	dojo.style("thinger", "opacity", 0.5); // == 0.5
 		//
 		// 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);
+		//		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.style("thinger", {
+		//	|		"opacity": 0.5,
+		//	|		"border": "3px solid black",
+		//	|		"height": "300px"
 		//	|	});
 		//
 		// 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.
-
-		var doc = d.doc;
-		if(refNode){
-			refNode = byId(refNode);
-			doc = refNode.ownerDocument;
-		}
-		if(typeof tag == "string"){ // inline'd type check
-			tag = doc.createElement(tag);
-		}
-		if(attrs){ d.attr(tag, attrs); }
-		if(refNode){ d.place(tag, refNode, pos); }
-		return tag; // DomNode
-	};
-
-	/*=====
-	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);
-	}
-	=====*/
-
-	d.empty =
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		d.isIE ?  function(node){
-			node = byId(node);
-			for(var c; c = node.lastChild;){ // intentional assignment
-				d.destroy(c);
-			}
-		} :
-		//>>excludeEnd("webkitMobile");
-		function(node){
-			byId(node).innerHTML = "";
-		};
-
-	/*=====
-	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>");
-	}
-	=====*/
-
-	// support stuff for dojo._toDom
-	var tagWrap = {
-			option: ["select"],
-			tbody: ["table"],
-			thead: ["table"],
-			tfoot: ["table"],
-			tr: ["table", "tbody"],
-			td: ["table", "tbody", "tr"],
-			th: ["table", "thead", "tr"],
-			legend: ["fieldset"],
-			caption: ["table"],
-			colgroup: ["table"],
-			col: ["table", "colgroup"],
-			li: ["ul"]
-		},
-		reTag = /<\s*([\w\:]+)/,
-		masterNode = {}, masterNum = 0,
-		masterName = "__" + d._scopeName + "ToDomId";
-
-	// generate start/end tag strings to use
-	// for the injection for each special tag wrap case.
-	for(var param in tagWrap){
-		if(tagWrap.hasOwnProperty(param)){
-			var tw = tagWrap[param];
-			tw.pre  = param == "option" ? '<select multiple="multiple">' : "<" + tw.join("><") + ">";
-			tw.post = "</" + tw.reverse().join("></") + ">";
-			// the last line is destructive: it reverses the array,
-			// but we don't care at this point
-		}
-	}
-
-	d._toDom = function(frag, doc){
-		//	summary:
-		// 		converts HTML string into DOM nodes.
-
-		doc = doc || d.doc;
-		var masterId = doc[masterName];
-		if(!masterId){
-			doc[masterName] = masterId = ++masterNum + "";
-			masterNode[masterId] = doc.createElement("div");
-		}
-
-		// make sure the frag is a string.
-		frag += "";
-
-		// find the starting tag, and get node wrapper
-		var match = frag.match(reTag),
-			tag = match ? match[1].toLowerCase() : "",
-			master = masterNode[masterId],
-			wrap, i, fc, df;
-		if(match && tagWrap[tag]){
-			wrap = tagWrap[tag];
-			master.innerHTML = wrap.pre + frag + wrap.post;
-			for(i = wrap.length; i; --i){
-				master = master.firstChild;
-			}
-		}else{
-			master.innerHTML = frag;
-		}
-
-		// one node shortcut => return the node itself
-		if(master.childNodes.length == 1){
-			return master.removeChild(master.firstChild); // DOMNode
-		}
-
-		// return multiple nodes as a document fragment
-		df = doc.createDocumentFragment();
-		while(fc = master.firstChild){ // intentional assignment
-			df.appendChild(fc);
-		}
-		return df; // DOMNode
-	};
-
-	// =============================
-	// (CSS) Class Functions
-	// =============================
-	var _className = "className";
-
-	dojo.hasClass = function(/*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 ID or DomNode reference to check the class for.
-		//
-		//	classStr:
-		//		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 ((" "+ byId(node)[_className] +" ").indexOf(" " + classStr + " ") >= 0);  // Boolean
-	};
-
-	var spaces = /\s+/, a1 = [""],
-		fakeNode = {},
-		str2array = function(s){
-			if(typeof s == "string" || s instanceof String){
-				if(s.indexOf(" ") < 0){
-					a1[0] = s;
-					return a1;
-				}else{
-					return s.split(spaces);
-				}
-			}
-			// assumed to be an array
-			return s || "";
-		};
-
-	dojo.addClass = function(/*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 ID or DomNode reference to add a class string too
-		//
-		//	classStr:
-		//		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");
-
-		node = byId(node);
-		classStr = str2array(classStr);
-		var cls = node[_className], oldLen;
-		cls = cls ? " " + cls + " " : " ";
-		oldLen = cls.length;
-		for(var i = 0, len = classStr.length, c; i < len; ++i){
-			c = classStr[i];
-			if(c && cls.indexOf(" " + c + " ") < 0){
-				cls += c + " ";
-			}
-		}
-		if(oldLen < cls.length){
-			node[_className] = cls.substr(1, cls.length - 2);
-		}
-	};
-
-	dojo.removeClass = function(/*DomNode|String*/node, /*String|Array?*/classStr){
-		// summary:
-		//		Removes the specified classes from node. No `dojo.hasClass`
-		//		check is required.
-		//
-		// node:
-		// 		String ID or DomNode reference to remove the class from.
-		//
-		// classStr:
-		//		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");
-
-		node = byId(node);
-		var cls;
-		if(classStr !== undefined){
-			classStr = str2array(classStr);
-			cls = " " + node[_className] + " ";
-			for(var i = 0, len = classStr.length; i < len; ++i){
-				cls = cls.replace(" " + classStr[i] + " ", " ");
-			}
-			cls = d.trim(cls);
-		}else{
-			cls = "";
-		}
-		if(node[_className] != cls){ node[_className] = cls; }
-	};
-
-	dojo.replaceClass = function(/*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 ID or DomNode reference to remove the class from.
-		// addClassStr:
-		//		A String class name to add, or several space-separated class names,
-		//		or an array of class names.
-		// removeClassStr:
-		//		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");
-
-        node = byId(node);
-		fakeNode.className = node.className;
-		dojo.removeClass(fakeNode, removeClassStr);
-		dojo.addClass(fakeNode, addClassStr);
-		if(node.className !== fakeNode.className){
-			node.className = fakeNode.className;
-		}
-	};
-
-	dojo.toggleClass = function(/*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.
-		//	condition:
-		//		If passed, true means to add the class, false means to remove.
-		//
-		// example:
-		//	|	dojo.toggleClass("someNode", "hovered");
-		//
-		// example:
-		//	Forcefully add a class
-		//	|	dojo.toggleClass("someNode", "hovered", true);
+		//		When the CSS style property is hyphenated, the JavaScript property is camelCased.
+		//		font-size becomes fontSize, and so on.
+		//	|	dojo.style("thinger",{
+		//	|		fontSize:"14pt",
+		//	|		letterSpacing:"1.2em"
+		//	|	});
 		//
 		// example:
-		//	Available in `dojo.NodeList()` for multiple toggles
-		//	|	dojo.query(".toggleMe").toggleClass("toggleMe");
+		//		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"
+		//	|	});
 
-		if(condition === undefined){
-			condition = !d.hasClass(node, classStr);
+		switch(arguments.length){
+			case 1:
+				return style.get(node);
+			case 2:
+				return style[typeof name == "string" ? "get" : "set"](node, name);
 		}
-		d[condition ? "addClass" : "removeClass"](node, classStr);
+		// setter
+		return style.set(node, name, value);
 	};
 
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-})();
-//>>excludeEnd("webkitMobile");
-
-return dojo;
+	return dojo;
 });
diff --git a/dojo/_base/json.js b/dojo/_base/json.js
index cea5b59..4a35bb8 100644
--- a/dojo/_base/json.js
+++ b/dojo/_base/json.js
@@ -1,53 +1,66 @@
-define("dojo/_base/json", ["dojo/lib/kernel"], function(dojo){
+define(["./kernel", "../json"], function(dojo, json){
+  // module:
+  //    dojo/_base/json
+  // summary:
+  //    This module defines the dojo JSON API.
 
-dojo.fromJson = function(/*String*/ json){
+dojo.fromJson = function(/*String*/ js){
 	// summary:
-	// 		Parses a [JSON](http://json.org) string to return a JavaScript object.
+	//		Parses a JavaScript expression and returns a JavaScript value.
 	// description:
-	// 		Throws for invalid JSON strings, but it does not use a strict JSON parser. It
-	// 		delegates to eval().  The content passed to this method must therefore come
+	//		Throws for invalid JavaScript expressions. It does not use a strict JSON parser. It
+	//		always delegates to eval(). The content passed to this method must therefore come
 	//		from a trusted source.
-	// json:
-	//		a string literal of a JSON item, for instance:
+	//		It is recommend that you use dojo/json's parse function for an
+	//		implementation uses the (faster) native JSON parse when available.
+	// js:
+	//		a string literal of a JavaScript expression, for instance:
 	//			`'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
 
-	return eval("(" + json + ")"); // Object
+	return eval("(" + js + ")"); // Object
 };
 
-dojo._escapeString = function(/*String*/str){
-	//summary:
+/*=====
+dojo._escapeString = function(){
+	// summary:
 	//		Adds escape sequences for non-visual characters, double quote and
 	//		backslash and surrounds with double quotes to form a valid string
 	//		literal.
-	return ('"' + str.replace(/(["\\])/g, '\\$1') + '"').
-		replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n").
-		replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string
 };
+=====*/
+dojo._escapeString = json.stringify; // just delegate to json.stringify
 
 dojo.toJsonIndentStr = "\t";
-dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint, /*String?*/ _indentStr){
-	//	summary:
+dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint){
+	// summary:
 	//		Returns a [JSON](http://json.org) serialization of an object.
-	//	description:
+	// description:
 	//		Returns a [JSON](http://json.org) serialization of an object.
 	//		Note that this doesn't check for infinite recursion, so don't do that!
-	//	it:
+	//		It is recommend that you use dojo/json's stringify function for an lighter
+	//		and faster implementation that matches the native JSON API and uses the
+	//		native JSON serializer when available.
+	// it:
 	//		an object to be serialized. Objects may define their own
 	//		serialization via a special "__json__" or "json" function
 	//		property. If a specialized serializer has been defined, it will
 	//		be used as a fallback.
-	//	prettyPrint:
+	//		Note that in 1.6, toJson would serialize undefined, but this no longer supported
+	//		since it is not supported by native JSON serializer.
+	// 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().
-	//	_indentStr:
-	//		private variable for recursive calls when pretty printing, do not use.
-	//	example:
+	//		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.
+	// example:
 	//		simple serialization of a trivial object
 	//		|	var jsonStr = dojo.toJson({ howdy: "stranger!", isStrange: true });
 	//		|	doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr);
-	//	example:
+	// example:
 	//		a custom serializer for an objects of a particular class:
 	//		|	dojo.declare("Furby", null, {
 	//		|		furbies: "are strange",
@@ -56,90 +69,16 @@ dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint, /*String?*/ _ind
 	//		|		},
 	//		|	});
 
-	if(it === undefined){
-		return "undefined";
-	}
-	var objtype = typeof it;
-	if(objtype == "number" || objtype == "boolean"){
-		return it + "";
-	}
-	if(it === null){
-		return "null";
-	}
-	if(dojo.isString(it)){
-		return dojo._escapeString(it);
-	}
-	// recurse
-	var recurse = arguments.callee;
-	// short-circuit for objects that support "json" serialization
-	// if they return "self" then just pass-through...
-	var newObj;
-	_indentStr = _indentStr || "";
-	var nextIndent = prettyPrint ? _indentStr + dojo.toJsonIndentStr : "";
-	var tf = it.__json__||it.json;
-	if(dojo.isFunction(tf)){
-		newObj = tf.call(it);
-		if(it !== newObj){
-			return recurse(newObj, prettyPrint, nextIndent);
-		}
-	}
-	if(it.nodeType && it.cloneNode){ // isNode
-		// we can't seriailize DOM nodes as regular objects because they have cycles
-		// DOM nodes could be serialized with something like outerHTML, but
-		// that can be provided by users in the form of .json or .__json__ function.
-		throw new Error("Can't serialize DOM nodes");
-	}
-
-	var sep = prettyPrint ? " " : "";
-	var newLine = prettyPrint ? "\n" : "";
-
-	// array
-	if(dojo.isArray(it)){
-		var res = dojo.map(it, function(obj){
-			var val = recurse(obj, prettyPrint, nextIndent);
-			if(typeof val != "string"){
-				val = "undefined";
+	// use dojo/json
+	return json.stringify(it, function(key, value){
+		if(value){
+			var tf = value.__json__||value.json;
+			if(typeof tf == "function"){
+				return tf.call(value);
 			}
-			return newLine + nextIndent + val;
-		});
-		return "[" + res.join("," + sep) + newLine + _indentStr + "]";
-	}
-	/*
-	// look in the registry
-	try {
-		window.o = it;
-		newObj = dojo.json.jsonRegistry.match(it);
-		return recurse(newObj, prettyPrint, nextIndent);
-	}catch(e){
-		// console.log(e);
-	}
-	// it's a function with no adapter, skip it
-	*/
-	if(objtype == "function"){
-		return null; // null
-	}
-	// generic object code path
-	var output = [], key;
-	for(key in it){
-		var keyStr, val;
-		if(typeof key == "number"){
-			keyStr = '"' + key + '"';
-		}else if(typeof key == "string"){
-			keyStr = dojo._escapeString(key);
-		}else{
-			// skip non-string or number keys
-			continue;
-		}
-		val = recurse(it[key], prettyPrint, nextIndent);
-		if(typeof val != "string"){
-			// skip non-serializable values
-			continue;
 		}
-		// FIXME: use += on Moz!!
-		//	 MOW NOTE: using += is a pain because you have to account for the dangling comma...
-		output.push(newLine + nextIndent + keyStr + ":" + sep + val);
-	}
-	return "{" + output.join("," + sep) + newLine + _indentStr + "}"; // String
+		return value;
+	}, prettyPrint && dojo.toJsonIndentStr);	// String
 };
 
 return dojo;
diff --git a/dojo/_base/kernel.js b/dojo/_base/kernel.js
new file mode 100644
index 0000000..277675c
--- /dev/null
+++ b/dojo/_base/kernel.js
@@ -0,0 +1,302 @@
+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.
+	var
+		// loop variables for this module
+		i, p,
+
+		// create dojo, dijit, and dojox
+		// FIXME: in 2.0 remove dijit, dojox being created by dojo
+		dijit = {},
+		dojox = {},
+		dojo = {
+			// notice dojo takes ownership of the value of the config module
+			config:config,
+			global:this,
+			dijit:dijit,
+			dojox:dojox
+		};
+
+
+	// Configure the scope map. For a 100% AMD application, the scope map is not needed other than to provide
+	// a _scopeName property for the dojo, dijit, and dojox root object so those packages can create
+	// unique names in the global space.
+	//
+	// 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.
+	//
+	// The following computations contort the packageMap for this dojo instance into a scopeMap.
+	var scopeMap =
+			// a map from a name used in a legacy module to the (global variable name, object addressed by that name)
+			// always map dojo, dijit, and dojox
+			{
+				dojo:["dojo", dojo],
+				dijit:["dijit", dijit],
+				dojox:["dojox", dojox]
+			},
+
+		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) || {},
+
+		item;
+
+	// process all mapped top-level names for this instance of dojo
+	for(p in packageMap){
+		if(scopeMap[p]){
+			// mapped dojo, dijit, or dojox
+			scopeMap[p][0] = packageMap[p];
+		}else{
+			// some other top-level name
+			scopeMap[p] = [packageMap[p], {}];
+		}
+	}
+
+	// publish those names to _scopeName and, optionally, the global namespace
+	for(p in scopeMap){
+		item = scopeMap[p];
+		item[1]._scopeName = item[0];
+		if(!config.noGlobals){
+			this[item[0]] = item[1];
+		}
+	}
+	dojo.scopeMap = 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+/);
+	dojo.version = {
+		major: 1, minor: 7, patch: 2, flag: "",
+		revision: rev ? +rev[0] : NaN,
+		toString: function(){
+			var v = dojo.version;
+			return v.major + "." + v.minor + "." + v.patch + v.flag + " (" + v.revision + ")";	// String
+		}
+	};
+
+
+	// 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
+	// is migrated. Absent specific advice otherwise, set extend-dojo to truthy.
+	has.add("extend-dojo", 1);
+
+
+	dojo.eval = function(scriptText){
+		//	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:
+		//		Makes an attempt to evaluate scriptText in the global scope. The function works correctly for browsers
+		//		that support indirect eval.
+		//
+		//		As usual, IE does not. On IE, the only way to implement global eval is to
+		//		use execScript. Unfortunately, execScript does not return a value and breaks some current usages of dojo.eval.
+		//		This implementation uses the technique of executing eval in the scope of a function that is a single scope
+		//		frame below the global scope; thereby coming close to the global scope. Note carefully that
+		//
+		//		dojo.eval("var pi = 3.14;");
+		//
+		//		will define global pi in non-IE environments, but define pi only in a temporary local scope for IE. If you want
+		//		to define a global variable using dojo.eval, write something like
+		//
+		//		dojo.eval("window.pi = 3.14;")
+		//	scriptText:
+		//		The text to evaluation.
+		//	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{
+		dojo.exit = function(){
+		};
+	}
+
+	has.add("dojo-guarantee-console",
+		// ensure that console.log, console.warn, etc. are defined
+		1
+	);
+	if(has("dojo-guarantee-console")){
+		typeof console != "undefined" || (console = {});
+		//	Be careful to leave 'log' always at the end
+		var cn = [
+			"assert", "count", "debug", "dir", "dirxml", "error", "group",
+			"groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
+			"trace", "warn", "log"
+		];
+		var tn;
+		i = 0;
+		while((tn = cn[i++])){
+			if(!console[tn]){
+				(function(){
+					var tcn = tn + "";
+					console[tcn] = ('log' in console) ? function(){
+						var a = Array.apply({}, arguments);
+						a.unshift(tcn + ":");
+						console["log"](a.join(" "));
+					} : function(){};
+					console[tcn]._fake = true;
+				})();
+			}
+		}
+	}
+
+	has.add("dojo-debug-messages",
+		// include dojo.deprecated/dojo.experimental implementations
+		!!config.isDebug
+	);
+	if(has("dojo-debug-messages")){
+		dojo.deprecated = function(/*String*/ behaviour, /*String?*/ extra, /*String?*/ removal){
+			//	summary:
+			//		Log a debug message to indicate that a behavior has been
+			//		deprecated.
+			//	behaviour: String
+			//		The API or behavior being deprecated. Usually in the form
+			//		of "myApp.someFunction()".
+			//	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?
+			//		Text to indicate when in the future the behavior will be
+			//		removed. Usually a version number.
+			//	example:
+			//	| dojo.deprecated("myApp.getTemp()", "use myApp.getLocaleTemp() instead", "1.0");
+
+			var message = "DEPRECATED: " + behaviour;
+			if(extra){ message += " " + extra; }
+			if(removal){ message += " -- will be removed in version: " + removal; }
+			console.warn(message);
+		};
+
+		dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
+			//	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
+			//		The name of a module, or the name of a module file or a specific
+			//		function
+			//	extra: String?
+			//		some additional message for the user
+			//	example:
+			//	| dojo.experimental("dojo.data.Result");
+			//	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",
+		// consume dojo.modulePaths processing
+		1
+	);
+	if(has("dojo-modulePaths")){
+		// notice that modulePaths won't be applied to any require's before the dojo/_base/kernel factory is run;
+		// this is the v1.6- behavior.
+		if(config.modulePaths){
+			dojo.deprecated("dojo.modulePaths", "use paths configuration");
+			var paths = {};
+			for(p in config.modulePaths){
+				paths[p.replace(/\./g, "/")] = config.modulePaths[p];
+			}
+			require({paths:paths});
+		}
+	}
+
+	has.add("dojo-moduleUrl",
+		// include dojo.moduleUrl
+		1
+	);
+	if(has("dojo-moduleUrl")){
+		dojo.moduleUrl = function(/*String*/module, /*String?*/url){
+			//	summary:
+			//		Returns a URL relative to a module.
+			//	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:
+			//	|	var img = document.createElement("img");
+			//	|	img.src = pngPath;
+			//	|	// add our image to the document
+			//	|	dojo.body().appendChild(img);
+			//	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,
+			//		the `acme.widget` and `acme.util` directories may be located
+			//		under different roots (see `dojo.registerModulePath`) but the
+			//		the modules which reference them can be unaware of their
+			//		relative locations on the filesystem:
+			//	|	// somewhere in a configuration block
+			//	|	dojo.registerModulePath("acme.widget", "../../acme/widget");
+			//	|	dojo.registerModulePath("acme.util", "../../util");
+			//	|
+			//	|	// ...
+			//	|
+			//	|	// code in a module using acme resources
+			//	|	var tmpltPath = dojo.moduleUrl("acme.widget","templates/template.html");
+			//	|	var dataPath = dojo.moduleUrl("acme.util","resources/data.json");
+
+			dojo.deprecated("dojo.moduleUrl()", "use require.toUrl", "2.0");
+
+			// require.toUrl requires a filetype; therefore, just append the suffix "/*.*" to guarantee a filetype, then
+			// remove the suffix from the result. This way clients can request a url w/out a filetype. This should be
+			// rare, but it maintains backcompat for the v1.x line (note: dojo.moduleUrl will be removed in v2.0).
+			// Notice * is an illegal filename so it won't conflict with any real path map that may exist the paths config.
+			var result = null;
+			if(module){
+				result = require.toUrl(module.replace(/\./g, "/") + (url ? ("/" + url) : "") + "/*.*").replace(/\/\*\.\*/, "") + (url ? "" : "/");
+			}
+			return result;
+		};
+	}
+
+	dojo._hasResource = {}; // for backward compatibility with layers built with 1.6 tooling
+
+	return dojo;
+});
diff --git a/dojo/_base/lang.js b/dojo/_base/lang.js
index 3389991..a71c556 100644
--- a/dojo/_base/lang.js
+++ b/dojo/_base/lang.js
@@ -1,134 +1,549 @@
-define("dojo/_base/lang", ["dojo/lib/kernel"], function(dojo){
+define(["./kernel", "../has", "./sniff"], function(dojo, has){
+	//	module:
+	//		dojo/_base/lang
+	//	summary:
+	//		This module defines Javascript language extensions.
 
-(function(){
-	var d = dojo, opts = Object.prototype.toString;
+	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 - ?)
+		for(var i in {toString: 1}){
+			return 0;
+		}
+		return 1;
+	});
 
-	// Crockford (ish) functions
+	var _extraNames =
+			has("bug-for-in-skips-shadowed") ?
+				"hasOwnProperty.valueOf.isPrototypeOf.propertyIsEnumerable.toLocaleString.toString.constructor".split(".") : [],
 
-	dojo.isString = function(/*anything*/ it){
-		//	summary:
-		//		Return true if it is a String
-		return (typeof it == "string" || it instanceof String); // Boolean
-	};
+		_extraLen = _extraNames.length,
 
-	dojo.isArray = function(/*anything*/ it){
-		//	summary:
-		//		Return true if it is an Array.
-		//		Does not work on Arrays created in other windows.
-		return it && (it instanceof Array || typeof it == "array"); // Boolean
-	};
-
-	dojo.isFunction = function(/*anything*/ it){
-		// summary:
-		//		Return true if it is a Function
-		return opts.call(it) === "[object Function]";
-	};
-
-	dojo.isObject = function(/*anything*/ it){
-		// summary:
-		//		Returns true if it is a JavaScript object (or an Array, a Function
-		//		or null)
-		return it !== undefined &&
-			(it === null || typeof it == "object" || d.isArray(it) || d.isFunction(it)); // Boolean
-	};
-
-	dojo.isArrayLike = function(/*anything*/ it){
+		_mixin = function(dest, source, copyFunc){
+			var name, s, i, empty = {};
+			for(name in source){
+				// the (!(name in empty) || empty[name] !== s) condition avoids copying properties in "source"
+				// inherited from Object.prototype.	 For example, if dest has a custom toString() method,
+				// don't overwrite it with the toString() method that source inherited from Object.prototype
+				s = source[name];
+				if(!(name in dest) || (dest[name] !== s && (!(name in empty) || empty[name] !== s))){
+					dest[name] = copyFunc ? copyFunc(s) : s;
+				}
+			}
+
+			if(has("bug-for-in-skips-shadowed")){
+				if(source){
+					for(i = 0; i < _extraLen; ++i){
+						name = _extraNames[i];
+						s = source[name];
+						if(!(name in dest) || (dest[name] !== s && (!(name in empty) || empty[name] !== s))){
+							dest[name] = copyFunc ? copyFunc(s) : s;
+						}
+					}
+				}
+			}
+
+			return dest; // Object
+		},
+
+		mixin = function(dest, sources){
+			if(!dest){ dest = {}; }
+			for(var i = 1, l = arguments.length; i < l; i++){
+				lang._mixin(dest, arguments[i]);
+			}
+			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){
+			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){
+			return getProp(name.split("."), create, context); // Object
+		},
+
+		exists = function(name, obj){
+			return lang.getObject(name, false, obj) !== undefined; // Boolean
+		},
+
+		opts = Object.prototype.toString,
+
+		// Crockford (ish) functions
+
+		isString = function(it){
+			return (typeof it == "string" || it instanceof String); // Boolean
+		},
+
+		isArray = function(it){
+			return it && (it instanceof Array || typeof it == "array"); // Boolean
+		},
+
+		isFunction = function(it){
+			return opts.call(it) === "[object Function]";
+		},
+
+		isObject = function(it){
+			return it !== undefined &&
+				(it === null || typeof it == "object" || lang.isArray(it) || lang.isFunction(it)); // Boolean
+		},
+
+		isArrayLike = function(it){
+			return it && it !== undefined && // Boolean
+				// keep out built-in constructors (Number, String, ...) which have length
+				// properties
+				!lang.isString(it) && !lang.isFunction(it) &&
+				!(it.tagName && it.tagName.toLowerCase() == 'form') &&
+				(lang.isArray(it) || isFinite(it.length));
+		},
+
+		isAlien = function(it){
+			return it && !lang.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean
+		},
+
+		extend = function(constructor, props){
+			for(var i=1, l=arguments.length; i<l; i++){
+				lang._mixin(constructor.prototype, arguments[i]);
+			}
+			return constructor; // Object
+		},
+
+		_hitchArgs = function(scope, method){
+			var pre = _toArray(arguments, 2);
+			var named = lang.isString(method);
+			return function(){
+				// arrayify arguments
+				var args = _toArray(arguments);
+				// locate our method
+				var f = named ? (scope||dojo.global)[method] : method;
+				// invoke with collected args
+				return f && f.apply(scope || this, pre.concat(args)); // mixed
+			}; // Function
+		},
+
+		hitch = function(scope, method){
+			if(arguments.length > 2){
+				return lang._hitchArgs.apply(dojo, arguments); // Function
+			}
+			if(!method){
+				method = scope;
+				scope = null;
+			}
+			if(lang.isString(method)){
+				scope = scope || dojo.global;
+				if(!scope[method]){ throw(['dojo.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(){
+			// boodman/crockford delegation w/ cornford optimization
+			function TMP(){}
+			return function(obj, props){
+				TMP.prototype = obj;
+				var tmp = new TMP();
+				TMP.prototype = null;
+				if(props){
+					lang._mixin(tmp, props);
+				}
+				return tmp; // Object
+			};
+		})(),
+
+		efficient = function(obj, offset, startWith){
+			return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0));
+		},
+
+		_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;
+					}
+					return function(obj){
+						return ((obj.item) ? slow : efficient).apply(this, arguments);
+					};
+				})() : efficient,
+
+		partial = function(/*Function|String*/method /*, ...*/){
+			var arr = [ null ];
+			return lang.hitch.apply(dojo, arr.concat(lang._toArray(arguments))); // Function
+		},
+
+		clone = function(/*anything*/ src){
+			if(!src || typeof src != "object" || lang.isFunction(src)){
+				// null, undefined, any non-object, or function
+				return src;	// anything
+			}
+			if(src.nodeType && "cloneNode" in src){
+				// DOM Node
+				return src.cloneNode(true); // Node
+			}
+			if(src instanceof Date){
+				// Date
+				return new Date(src.getTime());	// Date
+			}
+			if(src instanceof RegExp){
+				// RegExp
+				return new RegExp(src);   // RegExp
+			}
+			var r, i, l;
+			if(lang.isArray(src)){
+				// array
+				r = [];
+				for(i = 0, l = src.length; i < l; ++i){
+					if(i in src){
+						r.push(clone(src[i]));
+					}
+				}
+	// 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);
+		},
+
+
+		trim = String.prototype.trim ?
+			function(str){ return str.trim(); } :
+			function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); },
+
+
+		_pattern = /\{([^\}]+)\}/g,
+
+		replace = function(tmpl, map, pattern){
+			return tmpl.replace(pattern || _pattern, lang.isFunction(map) ?
+				map : function(_, k){ return 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;
+
+	/*=====
+	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:
-		//		similar to dojo.isArray() but more permissive
-		//	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().
+		//		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:
-		//		If it walks like a duck and quacks like a duck, return `true`
-		return it && it !== undefined && // Boolean
-			// keep out built-in constructors (Number, String, ...) which have length
-			// properties
-			!d.isString(it) && !d.isFunction(it) &&
-			!(it.tagName && it.tagName.toLowerCase() == 'form') &&
-			(d.isArray(it) || isFinite(it.length));
-	};
-
-	dojo.isAlien = function(/*anything*/ 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 && !d.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean
-	};
-
-	dojo.extend = function(/*Object*/ constructor, /*Object...*/ props){
-		// summary:
-		//		Adds all properties and methods of props to constructor's
-		//		prototype, making them available to all instances created with
-		//		constructor.
-		for(var i=1, l=arguments.length; i<l; i++){
-			d._mixin(constructor.prototype, arguments[i]);
-		}
-		return constructor; // Object
-	};
-
-	dojo._hitchArgs = function(scope, method /*,...*/){
-		var pre = d._toArray(arguments, 2);
-		var named = d.isString(method);
-		return function(){
-			// arrayify arguments
-			var args = d._toArray(arguments);
-			// locate our method
-			var f = named ? (scope||d.global)[method] : method;
-			// invoke with collected args
-			return f && f.apply(scope || this, pre.concat(args)); // mixed
-		}; // Function
-	};
-
-	dojo.hitch = function(/*Object*/scope, /*Function|String*/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:
-		//		The scope to use when method executes. If method is a string,
-		//		scope is also the object containing method.
-		//	method:
-		//		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
-		
-		if(arguments.length > 2){
-			return d._hitchArgs.apply(d, arguments); // Function
-		}
-		if(!method){
-			method = scope;
-			scope = null;
-		}
-		if(d.isString(method)){
-			scope = scope || d.global;
-			if(!scope[method]){ throw(['dojo.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
-	};
+		//		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){
@@ -143,10 +558,10 @@ define("dojo/_base/lang", ["dojo/lib/kernel"], function(dojo){
 		//		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:
+		//	obj: Object
 		//		The object to delegate to for properties not found directly on the
 		//		return object or in props.
-		//	props:
+		//	props: Object...
 		//		an object containing properties to assign to the returned object
 		//	returns:
 		//		an Object of anonymous type
@@ -161,136 +576,18 @@ define("dojo/_base/lang", ["dojo/lib/kernel"], function(dojo){
 	}
 	=====*/
 
-	dojo.delegate = dojo._delegate = (function(){
-		// boodman/crockford delegation w/ cornford optimization
-		function TMP(){}
-		return function(obj, props){
-			TMP.prototype = obj;
-			var tmp = new TMP();
-			TMP.prototype = null;
-			if(props){
-				d._mixin(tmp, props);
-			}
-			return tmp; // Object
-		};
-	})();
-
 	/*=====
-	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.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, ...);
 	}
 	=====*/
 
-	var efficient = function(obj, offset, startWith){
-		return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0));
-	};
-
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	var slow = function(obj, offset, startWith){
-		var arr = startWith||[];
-		for(var x = offset || 0; x < obj.length; x++){
-			arr.push(obj[x]);
-		}
-		return arr;
-	};
-	//>>excludeEnd("webkitMobile");
-
-	dojo._toArray =
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		d.isIE ?  function(obj){
-			return ((obj.item) ? slow : efficient).apply(this, arguments);
-		} :
-		//>>excludeEnd("webkitMobile");
-		efficient;
-
-	dojo.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 dojo.partial is the functional equivalent of calling:
-		//		|	dojo.hitch(null, funcName, ...);
-		var arr = [ null ];
-		return d.hitch.apply(d, arr.concat(d._toArray(arguments))); // Function
-	};
-
-	var extraNames = d._extraNames, extraLen = extraNames.length, empty = {};
-
-	dojo.clone = function(/*anything*/ o){
-		// summary:
-		//		Clones objects (including DOM nodes) and all children.
-		//		Warning: do not clone cyclic structures.
-		if(!o || typeof o != "object" || d.isFunction(o)){
-			// null, undefined, any non-object, or function
-			return o;	// anything
-		}
-		if(o.nodeType && "cloneNode" in o){
-			// DOM Node
-			return o.cloneNode(true); // Node
-		}
-		if(o instanceof Date){
-			// Date
-			return new Date(o.getTime());	// Date
-		}
-		if(o instanceof RegExp){
-			// RegExp
-			return new RegExp(o);   // RegExp
-		}
-		var r, i, l, s, name;
-		if(d.isArray(o)){
-			// array
-			r = [];
-			for(i = 0, l = o.length; i < l; ++i){
-				if(i in o){
-					r.push(d.clone(o[i]));
-				}
-			}
-// we don't clone functions for performance reasons
-//		}else if(d.isFunction(o)){
-//			// function
-//			r = function(){ return o.apply(this, arguments); };
-		}else{
-			// generic objects
-			r = o.constructor ? new o.constructor() : {};
-		}
-		for(name in o){
-			// the "tobj" condition avoid copying properties in "source"
-			// inherited from Object.prototype.  For example, if target has a custom
-			// toString() method, don't overwrite it with the toString() method
-			// that source inherited from Object.prototype
-			s = o[name];
-			if(!(name in r) || (r[name] !== s && (!(name in empty) || empty[name] !== s))){
-				r[name] = d.clone(s);
-			}
-		}
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		// IE doesn't recognize some custom functions in for..in
-		if(extraLen){
-			for(i = 0; i < extraLen; ++i){
-				name = extraNames[i];
-				s = o[name];
-				if(!(name in r) || (r[name] !== s && (!(name in empty) || empty[name] !== s))){
-					r[name] = s; // functions only, we don't clone them
-				}
-			}
-		}
-		//>>excludeEnd("webkitMobile");
-		return r; // Object
-	};
-
 	/*=====
 	dojo.trim = function(str){
 		//	summary:
@@ -306,13 +603,37 @@ define("dojo/_base/lang", ["dojo/lib/kernel"], function(dojo){
 		//		Uses String.prototype.trim instead, if available.
 		//		The fastest but longest version of this function is located at
 		//		dojo.string.trim()
-		return "";	// String
 	}
 	=====*/
 
-	dojo.trim = String.prototype.trim ?
-		function(str){ return str.trim(); } :
-		function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); };
+	/*=====
+	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){
@@ -337,58 +658,50 @@ define("dojo/_base/lang", ["dojo/lib/kernel"], function(dojo){
 		//	example:
 		//	|	// uses a dictionary for substitutions:
 		//	|	dojo.replace("Hello, {name.first} {name.last} AKA {nick}!",
-		//	|	  {
-		//	|	    nick: "Bob",
-		//	|	    name: {
-		//	|	      first:  "Robert",
-		//	|	      middle: "X",
-		//	|	      last:   "Cringely"
-		//	|	    }
-		//	|	  });
+		//	|		{
+		//	|			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"]);
+		//	|		["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;
+		//	|		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;
-		//	|	      }
-		//	|	    }
-		//	|	  )
+		//	|		"{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);
+		//	|		["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g);
 		//	|	// returns: Hello, Robert Cringely!
 		return "";	// String
 	}
 	=====*/
-
-	var _pattern = /\{([^\}]+)\}/g;
-	dojo.replace = function(tmpl, map, pattern){
-		return tmpl.replace(pattern || _pattern, d.isFunction(map) ?
-			map : function(_, k){ return d.getObject(k, false, map); });
-	};
-})();
-
-return dojo;
 });
+
diff --git a/dojo/_base/loader.js b/dojo/_base/loader.js
new file mode 100644
index 0000000..be64ab1
--- /dev/null
+++ b/dojo/_base/loader.js
@@ -0,0 +1,671 @@
+define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"], function(dojo, has, require, thisModule, json, lang, array) {
+	// module:
+	//		dojo/_base/lader
+	// summary:
+	//		This module defines the v1.x synchronous loader API.
+
+	// signal the loader in sync mode...
+	//>>pure-amd
+
+	if (!has("dojo-loader")){
+		console.error("cannot load the Dojo v1.x loader with a foreign loader");
+		return 0;
+	}
+
+	var makeErrorToken = function(id){
+			return {src:thisModule.id, id:id};
+		},
+
+		slashName = function(name){
+			return name.replace(/\./g, "/");
+		},
+
+		buildDetectRe = /\/\/>>built/,
+
+		dojoRequireCallbacks = [],
+		dojoRequireModuleStack = [],
+
+		dojoRequirePlugin = function(mid, require, loaded){
+			dojoRequireCallbacks.push(loaded);
+			array.forEach(mid.split(","), function(mid){
+				var module = getModule(mid, require.module);
+				dojoRequireModuleStack.push(module);
+				injectModule(module);
+			});
+			checkDojoRequirePlugin();
+		},
+
+		touched,
+
+		traverse = function(m){
+			if(touched[m.mid] || /loadInit\!/.test(m.mid)){
+				// loadInit 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
+				// 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;
+				}
+			}
+			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();
+			}
+		},
+
+		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
+			//
+			// 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
+			// and dojo/require plugins.
+			//
+			// // dojox/gfx:
+			//
+			//   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...
+			//         //
+			//
+			//         // 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");
+			//   });
+			//  })();
+			//
+			// 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
+			// execute properly (because the plugin below resolves the load init bundle.names module with respect to the module that demanded
+			// the plugin resource).
+			//
+			// Note that the relocation is specified in the runtime configuration; relocated names need not be set at build-time.
+			//
+			// Warning: this is not the best way to express dojox.gfx as and AMD module. In fact, the module has been properly converted in
+			// v1.7. However, this technique allows the builder to convert legacy modules into AMD modules and guarantee the codepath is the
+			// same in the converted AMD module.
+			require([mid], function(bundle){
+				// notice how names is resolved with respect to the module that demanded the plugin resource
+				require(bundle.names, function(){
+					// bring the bundle names into scope
+					for(var scopeText = "", args= [], i = 0; i<arguments.length; i++){
+						scopeText+= "var " + bundle.names[i] + "= arguments[" + i + "]; ";
+						args.push(arguments[i]);
+					}
+					eval(scopeText);
+
+					var callingModule = require.module,
+						deps = [],
+						hold = {},
+						requireList = [],
+						p,
+						syncLoaderApi = {
+							provide:function(moduleName){
+								// mark modules that arrive consequent to multiple provides in this module as arrived since they can't be injected
+								moduleName = slashName(moduleName);
+								var providedModule = getModule(moduleName, callingModule);
+								if(providedModule!==callingModule){
+									setArrived(providedModule);
+								}
+							},
+							require:function(moduleName, omitModuleCheck){
+								moduleName = slashName(moduleName);
+								omitModuleCheck && (getModule(moduleName, callingModule).result = nonmodule);
+								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"]);
+
+								// figure out if the bundle is xdomain; if so, add it to the depsSet
+								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);
+								}// else the bundle will be loaded synchronously when the module is evaluated
+							},
+							loadInit:function(f){
+								f();
+							}
+						};
+
+					// hijack the correct dojo and apply bundle.def
+					try{
+						for(p in syncLoaderApi){
+							hold[p] = dojo[p];
+							dojo[p] = syncLoaderApi[p];
+						}
+						bundle.def.apply(null, args);
+					}catch(e){
+						signal("error", [makeErrorToken("failedDojoLoadInit"), e]);
+					}finally{
+						for(p in syncLoaderApi){
+							dojo[p] = hold[p];
+						}
+					}
+
+					// 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(","));
+
+					dojoRequireCallbacks.push(loaded);
+					array.forEach(requireList, function(mid){
+						var module = getModule(mid, require.module);
+						dojoRequireModuleStack.push(module);
+						injectModule(module);
+					});
+					checkDojoRequirePlugin();
+				});
+			});
+		},
+
+		extractApplication = function(
+			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
+			// Warning: as usual, this will fail in the presense of unmatched right parans contained in strings, regexs, or unremoved comments
+			var parenRe = /\(|\)/g,
+				matchCount = 1,
+				match;
+			parenRe.lastIndex = startSearch;
+			while((match = parenRe.exec(text))){
+				if(match[0] == ")"){
+					matchCount -= 1;
+				}else{
+					matchCount += 1;
+				}
+				if(matchCount == 0){
+					break;
+				}
+			}
+
+			if(matchCount != 0){
+				throw "unmatched paren around character " + parenRe.lastIndex + " in: " + text;
+			}
+
+			//Put the master matching string in the results.
+			return [dojo.trim(text.substring(startApplication, parenRe.lastIndex))+";\n", parenRe.lastIndex];
+		},
+
+		// 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";
+		//
+		// 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.
+		//
+		// Alternative regex designs exist that will result in less-likely failures, but will still fail in many cases.
+		// The only solution guaranteed 100% correct is to parse the code and that seems overkill for this
+		// backcompat/unbuilt-xdomain layer. In the end, since it's been this way for a while, we won't change it.
+		// See the opening paragraphs of Chapter 7 or ECME-262 which describes the lexical abiguity further.
+		removeCommentRe = /(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg,
+
+		syncLoaderApiRe = /(^|\s)dojo\.(loadInit|require|provide|requireLocalization|requireIf|requireAfterIf|platformRequire)\s*\(/mg,
+
+		amdLoaderApiRe = /(^|\s)(require|define)\s*\(/m,
+
+		extractLegacyApiApplications = function(text, noCommentText){
+			// scan the noCommentText for any legacy loader API applications. Copy such applications into result (this is
+			// used by the builder). Move dojo.loadInit applications to loadInitApplications string. Copy all other applications
+			// 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...
+			//
+			// with
+			//
+			//   \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...
+			//
+			// WARNING: the removeCommentRe will cause an error if a detected comment removes all or part of a legacy-loader application
+			// that is not in a comment.
+
+			var match, startSearch, startApplication, application,
+				loadInitApplications = [],
+				otherApplications = [],
+				allApplications = [];
+
+			// noCommentText may be provided by a build app with comments extracted by a better method than regex (hopefully)
+			noCommentText = noCommentText || text.replace(removeCommentRe, function(match){
+				// remove iff the detected comment has text that looks like a sync loader API application; this helps by
+				// removing as little as possible, minimizing the changes the janky regex will kill the module
+				syncLoaderApiRe.lastIndex = amdLoaderApiRe.lastIndex = 0;
+				return (syncLoaderApiRe.test(match) || amdLoaderApiRe.test(match)) ? "" : match;
+			});
+
+			// find and extract all dojo.loadInit applications
+			while((match = syncLoaderApiRe.exec(noCommentText))){
+				startSearch = syncLoaderApiRe.lastIndex;
+				startApplication = startSearch  - match[0].length;
+				application = extractApplication(noCommentText, startSearch, startApplication);
+				if(match[2]=="loadInit"){
+					loadInitApplications.push(application[0]);
+				}else{
+					otherApplications.push(application[0]);
+				}
+				syncLoaderApiRe.lastIndex = application[1];
+			}
+			allApplications = loadInitApplications.concat(otherApplications);
+			if(allApplications.length || !amdLoaderApiRe.test(noCommentText)){
+				// either there were some legacy loader API applications or there were no AMD API applications
+				return [text.replace(/(^|\s)dojo\.loadInit\s*\(/g, "\n0 && dojo.loadInit("), allApplications.join(""), allApplications];
+			}else{
+				// legacy loader API *was not* detected and AMD API *was* detected; therefore, assume it's an AMD module
+				return 0;
+			}
+		},
+
+		transformToAmd = function(module, text){
+			// This is roughly the equivalent of dojo._xdCreateResource in 1.6-; however, it expresses a v1.6- dojo
+			// 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
+			//
+			// 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
+			// is rewritten as an AMD module with the single dependency of this synthetic resource. When the dojo/loadInit
+			// plugin loaded the synthetic resource, it will cause all dojo.loadInit's to be executed, find all dojo.require's
+			// (either directly consequent to dojo.require or indirectly consequent to dojo.require[After]If or
+			// dojo.platformRequire, and finally cause loading of all dojo.required modules with the dojo/require plugin. Thus,
+			// 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.
+
+			var extractResult, id, names = [], namesAsStrings = [];
+			if(buildDetectRe.test(text) || !(extractResult = extractLegacyApiApplications(text))){
+				// buildDetectRe.test(text) => a built module, always AMD
+				// extractResult==0 => no sync API
+				return 0;
+			}
+
+			// manufacture a synthetic module id that can never be a real mdule id (just like require does)
+			id = module.mid + "-*loadInit";
+
+			// construct the dojo/loadInit names vector which causes any relocated names to be defined as lexical variables under their not-relocated name
+			// the dojo/loadInit plugin assumes the first name in names is "dojo"
+
+			for(var p in getModule("dojo", module).result.scopeMap){
+				names.push(p);
+				namesAsStrings.push('"' + p + '"');
+			}
+
+			// 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" +
+				"define('" + id + "',{\n" +
+				"\tnames:" + dojo.toJson(names) + ",\n" +
+				"\tdef:function(" + names.join(",") + "){" + extractResult[1] + "}" +
+				"});\n\n" +
+			    "define(" + dojo.toJson(names.concat(["dojo/loadInit!"+id])) + ", function(" + names.join(",") + "){\n" + extractResult[0] + "});";
+		},
+
+		loaderVars = require.initSyncLoader(dojoRequirePlugin, checkDojoRequirePlugin, transformToAmd),
+
+		sync =
+			loaderVars.sync,
+
+		xd =
+			loaderVars.xd,
+
+		arrived =
+			loaderVars.arrived,
+
+		nonmodule =
+			loaderVars.nonmodule,
+
+		executing =
+			loaderVars.executing,
+
+		executed =
+			loaderVars.executed,
+
+		syncExecStack =
+			loaderVars.syncExecStack,
+
+		modules =
+			loaderVars.modules,
+
+		execQ =
+			loaderVars.execQ,
+
+		getModule =
+			loaderVars.getModule,
+
+		injectModule =
+			loaderVars.injectModule,
+
+		setArrived =
+			loaderVars.setArrived,
+
+		signal =
+			loaderVars.signal,
+
+		finishExec =
+			loaderVars.finishExec,
+
+		execModule =
+			loaderVars.execModule,
+
+		getLegacyMode =
+			loaderVars.getLegacyMode;
+
+	dojo.provide = function(mid){
+		var executingModule = syncExecStack[0],
+			module = lang.mixin(getModule(slashName(mid), require.module), {
+				executed:executing,
+				result:lang.getObject(mid, true)
+			});
+		setArrived(module);
+		if(executingModule){
+			(executingModule.provides || (executingModule.provides = [])).push(function(){
+				module.result = lang.getObject(mid);
+				delete module.provides;
+				module.executed!==executed && finishExec(module);
+			});
+		}// else dojo.provide called not consequent to loading; therefore, give up trying to publish module value to loader namespace
+		return module.result;
+	};
+
+	has.add("config-publishRequireResult", 1, 0, 0);
+
+	dojo.require = function(moduleName, omitModuleCheck) {
+		//	summary:
+		//		loads a Javascript module from the appropriate URI
+		//
+		//	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?
+		//		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
+		//		file located at `a/b/c.js` does not define an object `a.b.c`,
+		//		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.
+		//
+		// 		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.
+		//
+		// 		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.
+		//
+		// 		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
+		//		`dojo.require("A.B")` first checks to see if symbol A.B is
+		//		defined. If it is, it is simply returned (nothing to do).
+		//
+		//		If it is not defined, it will look for `A/B.js` in the script root
+		//		directory.
+		//
+		//		`dojo.require` throws an exception if it cannot find a file
+		//		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.
+		//
+		//		`dojo.require()` does nothing about importing symbols into
+		//		the current namespace.  It is presumed that the caller will
+		//		take care of that.
+		//
+		// 	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
+		//	   	|	});
+		//
+		//	example:
+		//		For example, to import all symbols into a local block, you might write:
+		//
+		//		|	with (dojo.require("A.B")) {
+		//		|		...
+		//		|	}
+		//
+		//		And to import just the leaf symbol to a local variable:
+		//
+		//		|	var B = dojo.require("A.B");
+		//	   	|	...
+		//
+		//	returns:
+		//		the required namespace object
+		function doRequire(mid, omitModuleCheck){
+			var module = getModule(slashName(mid), require.module);
+			if(syncExecStack.length && syncExecStack[0].finish){
+				// switched to async loading in the middle of evaluating a legacy module; stop
+				// applying dojo.require so the remaining dojo.requires are applied in order
+				syncExecStack[0].finish.push(mid);
+				return undefined;
+			}
+
+			// recall module.executed has values {0, executing, executed}; therefore, truthy indicates executing or executed
+			if(module.executed){
+				return module.result;
+			}
+			omitModuleCheck && (module.result = nonmodule);
+
+			var currentMode = getLegacyMode();
+
+			// recall, in sync mode to inject is to *eval* the module text
+			// if the module is a legacy module, this is the same as executing
+			// but if the module is an AMD module, this means defining, not executing
+			injectModule(module);
+			// the inject may have changed the mode
+			currentMode = getLegacyMode();
+
+			// in sync mode to dojo.require is to execute
+			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();
+			}
+			if(module.executed){
+				return module.result;
+			}
+
+			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
+				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);
+				}else{
+					// the module was a legacy module
+					syncExecStack.length && (syncExecStack[0].finish= [mid]);
+				}
+			}else{
+				// the loader wasn't in sync mode on entry; probably async mode; therefore, no expectation of getting
+				// the module value synchronously; make sure it gets executed though
+				execQ.push(module);
+			}
+			return undefined;
+		}
+
+		var result = doRequire(moduleName, omitModuleCheck);
+		if(has("config-publishRequireResult") && !lang.exists(moduleName) && result!==undefined){
+			lang.setObject(moduleName, result);
+		}
+		return result;
+	};
+
+	dojo.loadInit = function(f) {
+		f();
+	};
+
+	dojo.registerModulePath = function(/*String*/moduleName, /*String*/prefix){
+		//	summary:
+		//		Maps a module name to a path
+		//	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:
+		//		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:
+		//	|	/myapp/js/foo/bar.js
+		//	|	/myapp/js/foo/baz.js
+		//	|	/myapp/js/foo/thud/xyzzy.js
+		//		Your application can tell Dojo to locate the "foo" namespace by calling:
+		//	|	dojo.registerModulePath("foo", "../../foo");
+		//		At which point you can then use dojo.require() to load the
+		//		modules (assuming they provide() the same things which are
+		//		required). The full code might be:
+		//	|	<script type="text/javascript"
+		//	|		src="/myapp/js/dojo/dojo/dojo.js"></script>
+		//	|	<script type="text/javascript">
+		//	|		dojo.registerModulePath("foo", "../../foo");
+		//	|		dojo.require("foo.bar");
+		//	|		dojo.require("foo.baz");
+		//	|		dojo.require("foo.thud.xyzzy");
+		//	|	</script>
+
+		var paths = {};
+		paths[moduleName.replace(/\./g, "/")] = prefix;
+		require({paths:paths});
+	};
+
+	dojo.platformRequire = function(/*Object*/modMap){
+		//	summary:
+		//		require one or more modules based on which host environment
+		//		Dojo is currently operating in
+		//	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:
+		//		"default" and "common". The items in the "default" array will
+		//		be loaded if none of the other items have been choosen based on
+		//		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({
+		//		|		browser: [
+		//		|			"foo.sample", // simple module
+		//		|			"foo.test",
+		//		|			["foo.bar.baz", true] // skip object check in _loadModule (dojo.require)
+		//		|		],
+		//		|		default: [ "foo.sample._base" ],
+		//		|		common: [ "important.module.common" ]
+		//		|	});
+
+		var result = (modMap.common || []).concat(modMap[dojo._name] || modMap["default"] || []),
+			temp;
+		while(result.length){
+			if(lang.isArray(temp = result.shift())){
+				dojo.require.apply(dojo, temp);
+			}else{
+				dojo.require(temp);
+			}
+		}
+	};
+
+	dojo.requireIf = dojo.requireAfterIf = function(/*Boolean*/ condition, /*String*/ moduleName, /*Boolean?*/omitModuleCheck){
+		// summary:
+		//		If the condition is true then call `dojo.require()` for the specified
+		//		resource
+		//
+		// example:
+		//	|	dojo.requireIf(dojo.isBrowser, "my.special.Module");
+
+		if(condition){
+			dojo.require(moduleName, omitModuleCheck);
+		}
+	};
+
+	dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale){
+		require(["../i18n"], function(i18n){
+			i18n.getLocalization(moduleName, bundleName, locale);
+		});
+	};
+
+	return {
+		extractLegacyApiApplications:extractLegacyApiApplications,
+		require:loaderVars.dojoRequirePlugin,
+		loadInit:dojoLoadInitPlugin
+	};
+});
diff --git a/dojo/_base/query-sizzle.js b/dojo/_base/query-sizzle.js
deleted file mode 100644
index 9411c0c..0000000
--- a/dojo/_base/query-sizzle.js
+++ /dev/null
@@ -1,875 +0,0 @@
-/*!
- * Sizzle CSS Selector Engine - v0.9
- *  Copyright 2009, John Resig
- *  Redistributed with the Dojo Toolkit under the terms of the New BSD license.
- *  More information: http://sizzlejs.com/
- *
- *  This version from github, dated 1/23/2009, commit: e374a73bbffc12ec3b5f252e7f76e593c508dfa5
- *  Modified for dojo loader, and to fit into dojo namespace. This was done by passing
- *  dojo object to anonymous function, then assigning Sizzle to dojo.Sizzle instead of window.Sizzle.
- *  Then an alias for dojo.query and dojo._filterQueryResult(). dojo.psuedos is not mapped.
- *  Finally, dojo.provide/require added.
- */
-
-var startDojoMappings= function(dojo) {
-	//Start Dojo mappings.
-	dojo.query = function(/*String*/ query, /*String|DOMNode?*/ root, /*Function?*/listCtor){
-		listCtor = listCtor || dojo.NodeList;
-
-		if(!query){
-			return new listCtor();
-		}
-
-		if(query.constructor == listCtor){
-			return query;
-		}
-		if(!dojo.isString(query)){
-			return new listCtor(query); // dojo.NodeList
-		}
-		if(dojo.isString(root)){
-			root = dojo.byId(root);
-			if(!root){ return new listCtor(); }
-		}
-
-		return dojo.Sizzle(query, root, new listCtor());
-	};
-
-	dojo._filterQueryResult = function(nodeList, simpleFilter){
-		return dojo.Sizzle.filter(simpleFilter, nodeList);
-	};
-};
-
-//Main Sizzle code follows...
-//ns argument, added for dojo, used at the end of the file.
-var defineSizzle= function(ns){
-
-var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|[^[\]]+)+\]|\\.|[^ >+~,(\[]+)+|[>+~])(\s*,\s*)?/g,
-	done = 0,
-	toString = Object.prototype.toString;
-
-var Sizzle = function(selector, context, results, seed) {
-	results = results || [];
-	context = context || document;
-
-	if ( context.nodeType !== 1 && context.nodeType !== 9 )
-		return [];
-	
-	if ( !selector || typeof selector !== "string" ) {
-		return results;
-	}
-
-	var parts = [], m, set, checkSet, check, mode, extra, prune = true;
-	
-	// Reset the position of the chunker regexp (start from head)
-	chunker.lastIndex = 0;
-	
-	while ( (m = chunker.exec(selector)) !== null ) {
-		parts.push( m[1] );
-		
-		if ( m[2] ) {
-			extra = RegExp.rightContext;
-			break;
-		}
-	}
-
-	if ( parts.length > 1 && Expr.match.POS.exec( selector ) ) {
-		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
-			var later = "", match;
-
-			// Position selectors must be done after the filter
-			while ( (match = Expr.match.POS.exec( selector )) ) {
-				later += match[0];
-				selector = selector.replace( Expr.match.POS, "" );
-			}
-
-			set = Sizzle.filter( later, Sizzle( selector, context ) );
-		} else {
-			set = Expr.relative[ parts[0] ] ?
-				[ context ] :
-				Sizzle( parts.shift(), context );
-
-			while ( parts.length ) {
-				var tmpSet = [];
-
-				selector = parts.shift();
-				if ( Expr.relative[ selector ] )
-					selector += parts.shift();
-
-				for ( var i = 0, l = set.length; i < l; i++ ) {
-					Sizzle( selector, set[i], tmpSet );
-				}
-
-				set = tmpSet;
-			}
-		}
-	} else {
-		var ret = seed ?
-			{ expr: parts.pop(), set: makeArray(seed) } :
-			Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context );
-		set = Sizzle.filter( ret.expr, ret.set );
-
-		if ( parts.length > 0 ) {
-			checkSet = makeArray(set);
-		} else {
-			prune = false;
-		}
-
-		while ( parts.length ) {
-			var cur = parts.pop(), pop = cur;
-
-			if ( !Expr.relative[ cur ] ) {
-				cur = "";
-			} else {
-				pop = parts.pop();
-			}
-
-			if ( pop == null ) {
-				pop = context;
-			}
-
-			Expr.relative[ cur ]( checkSet, pop );
-		}
-	}
-
-	if ( !checkSet ) {
-		checkSet = set;
-	}
-
-	if ( !checkSet ) {
-		throw "Syntax error, unrecognized expression: " + (cur || selector);
-	}
-
-	if ( toString.call(checkSet) === "[object Array]" ) {
-		if ( !prune ) {
-			results.push.apply( results, checkSet );
-		} else if ( context.nodeType === 1 ) {
-			for ( var i = 0; checkSet[i] != null; i++ ) {
-				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
-					results.push( set[i] );
-				}
-			}
-		} else {
-			for ( var i = 0; checkSet[i] != null; i++ ) {
-				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
-					results.push( set[i] );
-				}
-			}
-		}
-	} else {
-		makeArray( checkSet, results );
-	}
-
-	if ( extra ) {
-		Sizzle( extra, context, results, seed );
-	}
-
-	return results;
-};
-
-Sizzle.matches = function(expr, set){
-	return Sizzle(expr, null, null, set);
-};
-
-Sizzle.find = function(expr, context){
-	var set, match;
-
-	if ( !expr ) {
-		return [];
-	}
-
-	for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
-		var type = Expr.order[i], match;
-		
-		if ( (match = Expr.match[ type ].exec( expr )) ) {
-			var left = RegExp.leftContext;
-
-			if ( left.substr( left.length - 1 ) !== "\\" ) {
-				match[1] = (match[1] || "").replace(/\\/g, "");
-				set = Expr.find[ type ]( match, context );
-				if ( set != null ) {
-					expr = expr.replace( Expr.match[ type ], "" );
-					break;
-				}
-			}
-		}
-	}
-
-	if ( !set ) {
-		set = context.getElementsByTagName("*");
-	}
-
-	return {set: set, expr: expr};
-};
-
-Sizzle.filter = function(expr, set, inplace, not){
-	var old = expr, result = [], curLoop = set, match, anyFound;
-
-	while ( expr && set.length ) {
-		for ( var type in Expr.filter ) {
-			if ( (match = Expr.match[ type ].exec( expr )) != null ) {
-				var filter = Expr.filter[ type ], goodArray = null, goodPos = 0, found, item;
-				anyFound = false;
-
-				if ( curLoop == result ) {
-					result = [];
-				}
-
-				if ( Expr.preFilter[ type ] ) {
-					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not );
-
-					if ( !match ) {
-						anyFound = found = true;
-					} else if ( match[0] === true ) {
-						goodArray = [];
-						var last = null, elem;
-						for ( var i = 0; (elem = curLoop[i]) !== undefined; i++ ) {
-							if ( elem && last !== elem ) {
-								goodArray.push( elem );
-								last = elem;
-							}
-						}
-					}
-				}
-
-				if ( match ) {
-					for ( var i = 0; (item = curLoop[i]) !== undefined; i++ ) {
-						if ( item ) {
-							if ( goodArray && item != goodArray[goodPos] ) {
-								goodPos++;
-							}
-	
-							found = filter( item, match, goodPos, goodArray );
-							var pass = not ^ !!found;
-
-							if ( inplace && found != null ) {
-								if ( pass ) {
-									anyFound = true;
-								} else {
-									curLoop[i] = false;
-								}
-							} else if ( pass ) {
-								result.push( item );
-								anyFound = true;
-							}
-						}
-					}
-				}
-
-				if ( found !== undefined ) {
-					if ( !inplace ) {
-						curLoop = result;
-					}
-
-					expr = expr.replace( Expr.match[ type ], "" );
-
-					if ( !anyFound ) {
-						return [];
-					}
-
-					break;
-				}
-			}
-		}
-
-		expr = expr.replace(/\s*,\s*/, "");
-
-		// Improper expression
-		if ( expr == old ) {
-			if ( anyFound == null ) {
-				throw "Syntax error, unrecognized expression: " + expr;
-			} else {
-				break;
-			}
-		}
-
-		old = expr;
-	}
-
-	return curLoop;
-};
-
-var Expr = Sizzle.selectors = {
-	order: [ "ID", "NAME", "TAG" ],
-	match: {
-		ID: /#((?:[\w\u0128-\uFFFF_-]|\\.)+)/,
-		CLASS: /\.((?:[\w\u0128-\uFFFF_-]|\\.)+)/,
-		NAME: /\[name=['"]*((?:[\w\u0128-\uFFFF_-]|\\.)+)['"]*\]/,
-		ATTR: /\[((?:[\w\u0128-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\]/,
-		TAG: /^((?:[\w\u0128-\uFFFF\*_-]|\\.)+)/,
-		CHILD: /:(only|nth|last|first)-child\(?(even|odd|[\dn+-]*)\)?/,
-		POS: /:(nth|eq|gt|lt|first|last|even|odd)\(?(\d*)\)?(?:[^-]|$)/,
-		PSEUDO: /:((?:[\w\u0128-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
-	},
-	attrMap: {
-		"class": "className",
-		"for": "htmlFor"
-	},
-	relative: {
-		"+": function(checkSet, part){
-			for ( var i = 0, l = checkSet.length; i < l; i++ ) {
-				var elem = checkSet[i];
-				if ( elem ) {
-					var cur = elem.previousSibling;
-					while ( cur && cur.nodeType !== 1 ) {
-						cur = cur.previousSibling;
-					}
-					checkSet[i] = typeof part === "string" ?
-						cur || false :
-						cur === part;
-				}
-			}
-
-			if ( typeof part === "string" ) {
-				Sizzle.filter( part, checkSet, true );
-			}
-		},
-		">": function(checkSet, part){
-			if ( typeof part === "string" && !/\W/.test(part) ) {
-				part = part.toUpperCase();
-
-				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
-					var elem = checkSet[i];
-					if ( elem ) {
-						var parent = elem.parentNode;
-						checkSet[i] = parent.nodeName === part ? parent : false;
-					}
-				}
-			} else {
-				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
-					var elem = checkSet[i];
-					if ( elem ) {
-						checkSet[i] = typeof part === "string" ?
-							elem.parentNode :
-							elem.parentNode === part;
-					}
-				}
-
-				if ( typeof part === "string" ) {
-					Sizzle.filter( part, checkSet, true );
-				}
-			}
-		},
-		"": function(checkSet, part){
-			var doneName = "done" + (done++), checkFn = dirCheck;
-
-			if ( !part.match(/\W/) ) {
-				var nodeCheck = part = part.toUpperCase();
-				checkFn = dirNodeCheck;
-			}
-
-			checkFn("parentNode", part, doneName, checkSet, nodeCheck);
-		},
-		"~": function(checkSet, part){
-			var doneName = "done" + (done++), checkFn = dirCheck;
-
-			if ( typeof part === "string" && !part.match(/\W/) ) {
-				var nodeCheck = part = part.toUpperCase();
-				checkFn = dirNodeCheck;
-			}
-
-			checkFn("previousSibling", part, doneName, checkSet, nodeCheck);
-		}
-	},
-	find: {
-		ID: function(match, context){
-			if ( context.getElementById ) {
-				var m = context.getElementById(match[1]);
-				return m ? [m] : [];
-			}
-		},
-		NAME: function(match, context){
-			return context.getElementsByName ? context.getElementsByName(match[1]) : null;
-		},
-		TAG: function(match, context){
-			return context.getElementsByTagName(match[1]);
-		}
-	},
-	preFilter: {
-		CLASS: function(match, curLoop, inplace, result, not){
-			match = " " + match[1].replace(/\\/g, "") + " ";
-
-			for ( var i = 0; curLoop[i]; i++ ) {
-				if ( not ^ (" " + curLoop[i].className + " ").indexOf(match) >= 0 ) {
-					if ( !inplace )
-						result.push( curLoop[i] );
-				} else if ( inplace ) {
-					curLoop[i] = false;
-				}
-			}
-
-			return false;
-		},
-		ID: function(match){
-			return match[1];
-		},
-		TAG: function(match){
-			return match[1].toUpperCase();
-		},
-		CHILD: function(match){
-			if ( match[1] == "nth" ) {
-				// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
-				var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
-					match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
-					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
-
-				// calculate the numbers (first)n+(last) including if they are negative
-				match[2] = (test[1] + (test[2] || 1)) - 0;
-				match[3] = test[3] - 0;
-			}
-
-			// TODO: Move to normal caching system
-			match[0] = "done" + (done++);
-
-			return match;
-		},
-		ATTR: function(match){
-			var name = match[1];
-			
-			if ( Expr.attrMap[name] ) {
-				match[1] = Expr.attrMap[name];
-			}
-
-			if ( match[2] === "~=" ) {
-				match[4] = " " + match[4] + " ";
-			}
-
-			return match;
-		},
-		PSEUDO: function(match, curLoop, inplace, result, not){
-			if ( match[1] === "not" ) {
-				// If we're dealing with a complex expression, or a simple one
-				if ( match[3].match(chunker).length > 1 ) {
-					match[3] = Sizzle(match[3], null, null, curLoop);
-				} else {
-					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
-					if ( !inplace ) {
-						result.push.apply( result, ret );
-					}
-					return false;
-				}
-			}
-			
-			return match;
-		},
-		POS: function(match){
-			match.unshift( true );
-			return match;
-		}
-	},
-	filters: {
-		enabled: function(elem){
-			return elem.disabled === false && elem.type !== "hidden";
-		},
-		disabled: function(elem){
-			return elem.disabled === true;
-		},
-		checked: function(elem){
-			return elem.checked === true;
-		},
-		selected: function(elem){
-			// Accessing this property makes selected-by-default
-			// options in Safari work properly
-			elem.parentNode.selectedIndex;
-			return elem.selected === true;
-		},
-		parent: function(elem){
-			return !!elem.firstChild;
-		},
-		empty: function(elem){
-			return !elem.firstChild;
-		},
-		has: function(elem, i, match){
-			return !!Sizzle( match[3], elem ).length;
-		},
-		header: function(elem){
-			return /h\d/i.test( elem.nodeName );
-		},
-		text: function(elem){
-			return "text" === elem.type;
-		},
-		radio: function(elem){
-			return "radio" === elem.type;
-		},
-		checkbox: function(elem){
-			return "checkbox" === elem.type;
-		},
-		file: function(elem){
-			return "file" === elem.type;
-		},
-		password: function(elem){
-			return "password" === elem.type;
-		},
-		submit: function(elem){
-			return "submit" === elem.type;
-		},
-		image: function(elem){
-			return "image" === elem.type;
-		},
-		reset: function(elem){
-			return "reset" === elem.type;
-		},
-		button: function(elem){
-			return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
-		},
-		input: function(elem){
-			return /input|select|textarea|button/i.test(elem.nodeName);
-		}
-	},
-	setFilters: {
-		first: function(elem, i){
-			return i === 0;
-		},
-		last: function(elem, i, match, array){
-			return i === array.length - 1;
-		},
-		even: function(elem, i){
-			return i % 2 === 0;
-		},
-		odd: function(elem, i){
-			return i % 2 === 1;
-		},
-		lt: function(elem, i, match){
-			return i < match[3] - 0;
-		},
-		gt: function(elem, i, match){
-			return i > match[3] - 0;
-		},
-		nth: function(elem, i, match){
-			return match[3] - 0 == i;
-		},
-		eq: function(elem, i, match){
-			return match[3] - 0 == i;
-		}
-	},
-	filter: {
-		CHILD: function(elem, match){
-			var type = match[1], parent = elem.parentNode;
-
-			var doneName = match[0];
-			
-			if ( parent && !parent[ doneName ] ) {
-				var count = 1;
-
-				for ( var node = parent.firstChild; node; node = node.nextSibling ) {
-					if ( node.nodeType == 1 ) {
-						node.nodeIndex = count++;
-					}
-				}
-
-				parent[ doneName ] = count - 1;
-			}
-
-			if ( type == "first" ) {
-				return elem.nodeIndex == 1;
-			} else if ( type == "last" ) {
-				return elem.nodeIndex == parent[ doneName ];
-			} else if ( type == "only" ) {
-				return parent[ doneName ] == 1;
-			} else if ( type == "nth" ) {
-				var add = false, first = match[2], last = match[3];
-
-				if ( first == 1 && last == 0 ) {
-					return true;
-				}
-
-				if ( first == 0 ) {
-					if ( elem.nodeIndex == last ) {
-						add = true;
-					}
-				} else if ( (elem.nodeIndex - last) % first == 0 && (elem.nodeIndex - last) / first >= 0 ) {
-					add = true;
-				}
-
-				return add;
-			}
-		},
-		PSEUDO: function(elem, match, i, array){
-			var name = match[1], filter = Expr.filters[ name ];
-
-			if ( filter ) {
-				return filter( elem, i, match, array );
-			} else if ( name === "contains" ) {
-				return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
-			} else if ( name === "not" ) {
-				var not = match[3];
-
-				for ( var i = 0, l = not.length; i < l; i++ ) {
-					if ( not[i] === elem ) {
-						return false;
-					}
-				}
-
-				return true;
-			}
-		},
-		ID: function(elem, match){
-			return elem.nodeType === 1 && elem.getAttribute("id") === match;
-		},
-		TAG: function(elem, match){
-			return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
-		},
-		CLASS: function(elem, match){
-			return match.test( elem.className );
-		},
-		ATTR: function(elem, match){
-			var result = elem[ match[1] ] || elem.getAttribute( match[1] ), value = result + "", type = match[2], check = match[4];
-			return result == null ?
-				false :
-				type === "=" ?
-				value === check :
-				type === "*=" ?
-				value.indexOf(check) >= 0 :
-				type === "~=" ?
-				(" " + value + " ").indexOf(check) >= 0 :
-				!match[4] ?
-				result :
-				type === "!=" ?
-				value != check :
-				type === "^=" ?
-				value.indexOf(check) === 0 :
-				type === "$=" ?
-				value.substr(value.length - check.length) === check :
-				type === "|=" ?
-				value === check || value.substr(0, check.length + 1) === check + "-" :
-				false;
-		},
-		POS: function(elem, match, i, array){
-			var name = match[2], filter = Expr.setFilters[ name ];
-
-			if ( filter ) {
-				return filter( elem, i, match, array );
-			}
-		}
-	}
-};
-
-for ( var type in Expr.match ) {
-	Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
-}
-
-var makeArray = function(array, results) {
-	array = Array.prototype.slice.call( array );
-
-	if ( results ) {
-		results.push.apply( results, array );
-		return results;
-	}
-	
-	return array;
-};
-
-// Perform a simple check to determine if the browser is capable of
-// converting a NodeList to an array using builtin methods.
-try {
-	Array.prototype.slice.call( document.documentElement.childNodes );
-
-// Provide a fallback method if it does not work
-} catch(e){
-	makeArray = function(array, results) {
-		var ret = results || [];
-
-		if ( toString.call(array) === "[object Array]" ) {
-			Array.prototype.push.apply( ret, array );
-		} else {
-			if ( typeof array.length === "number" ) {
-				for ( var i = 0, l = array.length; i < l; i++ ) {
-					ret.push( array[i] );
-				}
-			} else {
-				for ( var i = 0; array[i]; i++ ) {
-					ret.push( array[i] );
-				}
-			}
-		}
-
-		return ret;
-	};
-}
-
-// Check to see if the browser returns elements by name when
-// querying by getElementById (and provide a workaround)
-(function(){
-	// We're going to inject a fake input element with a specified name
-	var form = document.createElement("form"),
-		id = "script" + (new Date).getTime();
-	form.innerHTML = "<input name='" + id + "'/>";
-
-	// Inject it into the root element, check its status, and remove it quickly
-	var root = document.documentElement;
-	root.insertBefore( form, root.firstChild );
-
-	// The workaround has to do additional checks after a getElementById
-	// Which slows things down for other browsers (hence the branching)
-	if ( !!document.getElementById( id ) ) {
-		Expr.find.ID = function(match, context){
-			if ( context.getElementById ) {
-				var m = context.getElementById(match[1]);
-				return m ? m.id === match[1] || m.getAttributeNode && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
-			}
-		};
-
-		Expr.filter.ID = function(elem, match){
-			var node = elem.getAttributeNode && elem.getAttributeNode("id");
-			return elem.nodeType === 1 && node && node.nodeValue === match;
-		};
-	}
-
-	root.removeChild( form );
-})();
-
-// Check to see if the browser returns only elements
-// when doing getElementsByTagName("*")
-(function(){
-	// Create a fake element
-	var div = document.createElement("div");
-	div.appendChild( document.createComment("") );
-
-	// Make sure no comments are found
-	if ( div.getElementsByTagName("*").length > 0 ) {
-		Expr.find.TAG = function(match, context){
-			var results = context.getElementsByTagName(match[1]);
-
-			// Filter out possible comments
-			if ( match[1] === "*" ) {
-				var tmp = [];
-
-				for ( var i = 0; results[i]; i++ ) {
-					if ( results[i].nodeType === 1 ) {
-						tmp.push( results[i] );
-					}
-				}
-
-				results = tmp;
-			}
-
-			return results;
-		};
-	}
-})();
-
-if ( document.querySelectorAll ) (function(){
-	var oldSizzle = Sizzle;
-	
-	Sizzle = function(query, context, extra, seed){
-		context = context || document;
-
-		if ( !seed && context.nodeType === 9 ) {
-			try {
-				return makeArray( context.querySelectorAll(query), extra );
-			} catch(e){}
-		}
-		
-		return oldSizzle(query, context, extra, seed);
-	};
-
-	Sizzle.find = oldSizzle.find;
-	Sizzle.filter = oldSizzle.filter;
-	Sizzle.selectors = oldSizzle.selectors;
-	Sizzle.matches = oldSizzle.matches;
-})();
-
-if ( document.documentElement.getElementsByClassName ) {
-	Expr.order.splice(1, 0, "CLASS");
-	Expr.find.CLASS = function(match, context) {
-		return context.getElementsByClassName(match[1]);
-	};
-}
-
-function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck ) {
-	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
-		var elem = checkSet[i];
-		if ( elem ) {
-			elem = elem[dir];
-			var match = false;
-
-			while ( elem && elem.nodeType ) {
-				var done = elem[doneName];
-				if ( done ) {
-					match = checkSet[ done ];
-					break;
-				}
-
-				if ( elem.nodeType === 1 )
-					elem[doneName] = i;
-
-				if ( elem.nodeName === cur ) {
-					match = elem;
-					break;
-				}
-
-				elem = elem[dir];
-			}
-
-			checkSet[i] = match;
-		}
-	}
-}
-
-function dirCheck( dir, cur, doneName, checkSet, nodeCheck ) {
-	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
-		var elem = checkSet[i];
-		if ( elem ) {
-			elem = elem[dir];
-			var match = false;
-
-			while ( elem && elem.nodeType ) {
-				if ( elem[doneName] ) {
-					match = checkSet[ elem[doneName] ];
-					break;
-				}
-
-				if ( elem.nodeType === 1 ) {
-					elem[doneName] = i;
-
-					if ( typeof cur !== "string" ) {
-						if ( elem === cur ) {
-							match = true;
-							break;
-						}
-
-					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
-						match = elem;
-						break;
-					}
-				}
-
-				elem = elem[dir];
-			}
-
-			checkSet[i] = match;
-		}
-	}
-}
-
-var contains = document.compareDocumentPosition ?  function(a, b){
-	return a.compareDocumentPosition(b) & 16;
-} : function(a, b){
-	return a !== b && (a.contains ? a.contains(b) : true);
-};
-
-// EXPOSE
-
-ns.Sizzle = Sizzle;
-
-};
-
-if (this["dojo"]) {
-  var defined= 0;
-//>>includeStart("asyncLoader", kwArgs.asynchLoader);
-  defined= 1;
-  define("dojo/_base/query", ["dojo", "dojo/_base/NodeList"], function(dojo) {
-    startDojoMappings(dojo);
-    defineSizzle(dojo);
-  });
-//>>includeEnd("asyncLoader");
-//>>excludeStart("asyncLoader", kwArgs.asynchLoader);
-  if (!defined) {
-    // must be in a built version that stripped out the define above
-  	dojo.provide("dojo._base.query");
-    dojo.require("dojo._base.NodeList");
-    defineSizzle(dojo);
-  } // else must be in a source version (or a build that likes define)
-//>>excludeEnd("asyncLoader");
-} else {
-  defineSizzle(window);
-}
diff --git a/dojo/_base/query.js b/dojo/_base/query.js
index 0f3d55f..0520710 100644
--- a/dojo/_base/query.js
+++ b/dojo/_base/query.js
@@ -1,1667 +1,3 @@
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-(function(){
-
-/*
-	dojo.query() architectural overview:
-
-		dojo.query is a relatively full-featured CSS3 query library. It is
-		designed to take any valid CSS3 selector and return the nodes matching
-		the selector. To do this quickly, it processes queries in several
-		steps, applying caching where profitable.
-		
-		The steps (roughly in reverse order of the way they appear in the code):
-			1.) check to see if we already have a "query dispatcher"
-				- if so, use that with the given parameterization. Skip to step 4.
-			2.) attempt to determine which branch to dispatch the query to:
-				- JS (optimized DOM iteration)
-				- native (FF3.1+, Safari 3.1+, IE 8+)
-			3.) tokenize and convert to executable "query dispatcher"
-				- this is where the lion's share of the complexity in the
-				  system lies. In the DOM version, the query dispatcher is
-				  assembled as a chain of "yes/no" test functions pertaining to
-				  a section of a simple query statement (".blah:nth-child(odd)"
-				  but not "div div", which is 2 simple statements). Individual
-				  statement dispatchers are cached (to prevent re-definition)
-				  as are entire dispatch chains (to make re-execution of the
-				  same query fast)
-			4.) the resulting query dispatcher is called in the passed scope
-			    (by default the top-level document)
-				- for DOM queries, this results in a recursive, top-down
-				  evaluation of nodes based on each simple query section
-				- for native implementations, this may mean working around spec
-				  bugs. So be it.
-			5.) matched nodes are pruned to ensure they are unique (if necessary)
-*/
-
-var defineQuery= function(d){
-	// define everything in a closure for compressability reasons. "d" is an
-	// alias to "dojo" (or the toolkit alias object, e.g., "acme").
-
-	////////////////////////////////////////////////////////////////////////
-	// Toolkit aliases
-	////////////////////////////////////////////////////////////////////////
-
-	// if you are extracting dojo.query 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 = 			d.trim;
-	var each = 			d.forEach;
-	// 					d.isIE; // float
-	// 					d.isSafari; // float
-	// 					d.isOpera; // float
-	// 					d.isWebKit; // float
-	// 					d.doc ; // document element
-	var qlc = (d._NodeListCtor = 		d.NodeList);
-
-	var getDoc = function(){ return d.doc; };
-	// NOTE(alex): the spec is idiotic. CSS queries should ALWAYS be case-sensitive, but nooooooo
-	var cssCaseBug = ((d.isWebKit||d.isMozilla) && ((getDoc().compatMode) == "BackCompat"));
-
-	////////////////////////////////////////////////////////////////////////
-	// Global utilities
-	////////////////////////////////////////////////////////////////////////
-
-
-	// on browsers that support the "children" collection we can avoid a lot of
-	// iteration on chaff (non-element) nodes.
-	// why.
-	var childNodesName = !!getDoc().firstChild["children"] ? "children" : "childNodes";
-
-	var specials = ">~+";
-
-	// global thunk to determine whether we should treat the current query as
-	// case sensitive or not. This switch is flipped by the query evaluator
-	// based on the document passed as the context to search.
-	var caseSensitive = false;
-
-	// how high?
-	var yesman = function(){ return true; };
-
-	////////////////////////////////////////////////////////////////////////
-	// Tokenizer
-	////////////////////////////////////////////////////////////////////////
-
-	var getQueryParts = function(query){
-		//	summary:
-		//		state machine for query tokenization
-		//	description:
-		//		instead of using a brittle and slow regex-based CSS parser,
-		//		dojo.query implements an AST-style query representation. This
-		//		representation is only generated once per query. For example,
-		//		the same query run multiple times or under different root nodes
-		//		does not re-parse the selector expression but instead uses the
-		//		cached data structure. The state machine implemented here
-		//		terminates on the last " " (space) character and returns an
-		//		ordered array of query component structures (or "parts"). Each
-		//		part represents an operator or a simple CSS filtering
-		//		expression. The structure for parts is documented in the code
-		//		below.
-
-
-		// NOTE:
-		//		this code is designed to run fast and compress well. Sacrifices
-		//		to readability and maintainability have been made.  Your best
-		//		bet when hacking the tokenizer is to put The Donnas on *really*
-		//		loud (may we recommend their "Spend The Night" release?) and
-		//		just assume you're gonna make mistakes. Keep the unit tests
-		//		open and run them frequently. Knowing is half the battle ;-)
-		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 += " * "
-		}else{
-			// if you have not provided a terminator, one will be provided for
-			// you...
-			query += " ";
-		}
-
-		var ts = function(/*Integer*/ s, /*Integer*/ e){
-			// trim and slice.
-
-			// take an index to start a string slice from and an end position
-			// and return a trimmed copy of that sub-string
-			return trim(query.slice(s, e));
-		}
-
-		// the overall data graph of the full query, as represented by queryPart objects
-		var queryParts = [];
-
-
-		// state keeping vars
-		var inBrackets = -1, inParens = -1, inMatchFor = -1,
-			inPseudo = -1, inClass = -1, inId = -1, inTag = -1,
-			lc = "", cc = "", pStart;
-
-		// iteration vars
-		var x = 0, // index in the query
-			ql = query.length,
-			currentPart = null, // data structure representing the entire clause
-			_cp = null; // the current pseudo or attr matcher
-
-		// several temporary variables are assigned to this structure during a
-		// potential sub-expression match:
-		//		attr:
-		//			a string representing the current full attribute match in a
-		//			bracket expression
-		//		type:
-		//			if there's an operator in a bracket expression, this is
-		//			used to keep track of it
-		//		value:
-		//			the internals of parenthetical expression for a pseudo. for
-		//			:nth-child(2n+1), value might be "2n+1"
-
-		var endTag = function(){
-			// called when the tokenizer hits the end of a particular tag name.
-			// Re-sets state variables for tag matching and sets up the matcher
-			// to handle the next type of token (tag or operator).
-			if(inTag >= 0){
-				var tv = (inTag == x) ? null : ts(inTag, x); // .toLowerCase();
-				currentPart[ (specials.indexOf(tv) < 0) ? "tag" : "oper" ] = tv;
-				inTag = -1;
-			}
-		}
-
-		var endId = function(){
-			// called when the tokenizer might be at the end of an ID portion of a match
-			if(inId >= 0){
-				currentPart.id = ts(inId, x).replace(/\\/g, "");
-				inId = -1;
-			}
-		}
-
-		var endClass = function(){
-			// called when the tokenizer might be at the end of a class name
-			// match. CSS allows for multiple classes, so we augment the
-			// current item with another class in its list
-			if(inClass >= 0){
-				currentPart.classes.push(ts(inClass+1, x).replace(/\\/g, ""));
-				inClass = -1;
-			}
-		}
-
-		var endAll = function(){
-			// at the end of a simple fragment, so wall off the matches
-			endId(); endTag(); endClass();
-		}
-
-		var endPart = function(){
-			endAll();
-			if(inPseudo >= 0){
-				currentPart.pseudos.push({ name: ts(inPseudo+1, x) });
-			}
-			// hint to the selector engine to tell it whether or not it
-			// needs to do any iteration. Many simple selectors don't, and
-			// we can avoid significant construction-time work by advising
-			// the system to skip them
-			currentPart.loops = (
-					currentPart.pseudos.length ||
-					currentPart.attrs.length ||
-					currentPart.classes.length	);
-
-			currentPart.oquery = currentPart.query = ts(pStart, x); // save the full expression as a string
-
-
-			// otag/tag are hints to suggest to the system whether or not
-			// it's an operator or a tag. We save a copy of otag since the
-			// tag name is cast to upper-case in regular HTML matches. The
-			// system has a global switch to figure out if the current
-			// expression needs to be case sensitive or not and it will use
-			// otag or tag accordingly
-			currentPart.otag = currentPart.tag = (currentPart["oper"]) ? null : (currentPart.tag || "*");
-
-			if(currentPart.tag){
-				// if we're in a case-insensitive HTML doc, we likely want
-				// the toUpperCase when matching on element.tagName. If we
-				// do it here, we can skip the string op per node
-				// comparison
-				currentPart.tag = currentPart.tag.toUpperCase();
-			}
-
-			// add the part to the list
-			if(queryParts.length && (queryParts[queryParts.length-1].oper)){
-				// operators are always infix, so we remove them from the
-				// list and attach them to the next match. The evaluator is
-				// responsible for sorting out how to handle them.
-				currentPart.infixOper = queryParts.pop();
-				currentPart.query = currentPart.infixOper.query + " " + currentPart.query;
-				/*
-				console.debug(	"swapping out the infix",
-								currentPart.infixOper,
-								"and attaching it to",
-								currentPart);
-				*/
-			}
-			queryParts.push(currentPart);
-
-			currentPart = null;
-		}
-
-		// iterate over the query, character by character, building up a
-		// list of query part objects
-		for(; lc=cc, cc=query.charAt(x), x < ql; x++){
-			//		cc: the current character in the match
-			//		lc: the last character (if any)
-
-			// someone is trying to escape something, so don't try to match any
-			// fragments. We assume we're inside a literal.
-			if(lc == "\\"){ continue; }
-			if(!currentPart){ // a part was just ended or none has yet been created
-				// NOTE: I hate all this alloc, but it's shorter than writing tons of if's
-				pStart = x;
-				//	rules describe full CSS sub-expressions, like:
-				//		#someId
-				//		.className:first-child
-				//	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:
-				//		[
-				//			{
-				//				query: "thinger",
-				//				tag: "thinger",
-				//			},
-				//			{
-				//				query: "div.howdy[type=thinger]",
-				//				classes: ["howdy"],
-				//				infixOper: {
-				//					query: ">",
-				//					oper: ">",
-				//				}
-				//			},
-				//		]
-				currentPart = {
-					query: null, // the full text of the part's rule
-					pseudos: [], // CSS supports multiple pseud-class matches in a single rule
-					attrs: [], 	// CSS supports multi-attribute match, so we need an array
-					classes: [], // class matches may be additive, e.g.: .thinger.blah.howdy
-					tag: null, 	// only one tag...
-					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;
-					}
-				};
-
-				// if we don't have a part, we assume we're going to start at
-				// the beginning of a match, which should be a tag name. This
-				// might fault a little later on, but we detect that and this
-				// iteration will still be fine.
-				inTag = x;
-			}
-
-			if(inBrackets >= 0){
-				// look for a the close first
-				if(cc == "]"){ // if we're in a [...] clause and we end, do assignment
-					if(!_cp.attr){
-						// no attribute match was previously begun, so we
-						// assume this is an attribute existence match in the
-						// form of [someAttributeName]
-						_cp.attr = ts(inBrackets+1, x);
-					}else{
-						// we had an attribute already, so we know that we're
-						// matching some sort of value, as in [attrName=howdy]
-						_cp.matchFor = ts((inMatchFor||inBrackets+1), x);
-					}
-					var cmf = _cp.matchFor;
-					if(cmf){
-						// try to strip quotes from the matchFor value. We want
-						// [attrName=howdy] to match the same
-						//	as [attrName = 'howdy' ]
-						if(	(cmf.charAt(0) == '"') || (cmf.charAt(0)  == "'") ){
-							_cp.matchFor = cmf.slice(1, -1);
-						}
-					}
-					// end the attribute by adding it to the list of attributes.
-					currentPart.attrs.push(_cp);
-					_cp = null; // necessary?
-					inBrackets = inMatchFor = -1;
-				}else if(cc == "="){
-					// if the last char was an operator prefix, make sure we
-					// record it along with the "=" operator.
-					var addToCc = ("|~^$*".indexOf(lc) >=0 ) ? lc : "";
-					_cp.type = addToCc+cc;
-					_cp.attr = ts(inBrackets+1, x-addToCc.length);
-					inMatchFor = x+1;
-				}
-				// now look for other clause parts
-			}else if(inParens >= 0){
-				// if we're in a parenthetical expression, we need to figure
-				// out if it's attached to a pseudo-selector rule like
-				// :nth-child(1)
-				if(cc == ")"){
-					if(inPseudo >= 0){
-						_cp.value = ts(inParens+1, x);
-					}
-					inPseudo = inParens = -1;
-				}
-			}else if(cc == "#"){
-				// start of an ID match
-				endAll();
-				inId = x+1;
-			}else if(cc == "."){
-				// start of a class match
-				endAll();
-				inClass = x;
-			}else if(cc == ":"){
-				// start of a pseudo-selector match
-				endAll();
-				inPseudo = x;
-			}else if(cc == "["){
-				// start of an attribute match.
-				endAll();
-				inBrackets = x;
-				// provide a new structure for the attribute match to fill-in
-				_cp = {
-					/*=====
-					attr: null, type: null, matchFor: null
-					=====*/
-				};
-			}else if(cc == "("){
-				// we really only care if we've entered a parenthetical
-				// expression if we're already inside a pseudo-selector match
-				if(inPseudo >= 0){
-					// provide a new structure for the pseudo match to fill-in
-					_cp = {
-						name: ts(inPseudo+1, x),
-						value: null
-					}
-					currentPart.pseudos.push(_cp);
-				}
-				inParens = x;
-			}else if(
-				(cc == " ") &&
-				// if it's a space char and the last char is too, consume the
-				// current one without doing more work
-				(lc != cc)
-			){
-				endPart();
-			}
-		}
-		return queryParts;
-	};
-	
-
-	////////////////////////////////////////////////////////////////////////
-	// DOM query infrastructure
-	////////////////////////////////////////////////////////////////////////
-
-	var agree = function(first, second){
-		// the basic building block of the yes/no chaining system. agree(f1,
-		// f2) generates a new function which returns the boolean results of
-		// both of the passed functions to a single logical-anded result. If
-		// either are not passed, the other is used exclusively.
-		if(!first){ return second; }
-		if(!second){ return first; }
-
-		return function(){
-			return first.apply(window, arguments) && second.apply(window, arguments);
-		}
-	};
-
-	var getArr = function(i, arr){
-		// helps us avoid array alloc when we don't need it
-		var r = arr||[]; // FIXME: should this be 'new d._NodeListCtor()' ?
-		if(i){ r.push(i); }
-		return r;
-	};
-
-	var _isElement = function(n){ return (1 == n.nodeType); };
-
-	// FIXME: need to coalesce _getAttr with defaultGetter
-	var blank = "";
-	var _getAttr = function(elem, attr){
-		if(!elem){ return blank; }
-		if(attr == "class"){
-			return elem.className || blank;
-		}
-		if(attr == "for"){
-			return elem.htmlFor || blank;
-		}
-		if(attr == "style"){
-			return elem.style.cssText || blank;
-		}
-		return (caseSensitive ? elem.getAttribute(attr) : elem.getAttribute(attr, 2)) || blank;
-	};
-
-	var attrs = {
-		"*=": function(attr, value){
-			return function(elem){
-				// E[foo*="bar"]
-				//		an E element whose "foo" attribute value contains
-				//		the substring "bar"
-				return (_getAttr(elem, attr).indexOf(value)>=0);
-			}
-		},
-		"^=": function(attr, value){
-			// E[foo^="bar"]
-			//		an E element whose "foo" attribute value begins exactly
-			//		with the string "bar"
-			return function(elem){
-				return (_getAttr(elem, attr).indexOf(value)==0);
-			}
-		},
-		"$=": function(attr, value){
-			// E[foo$="bar"]
-			//		an E element whose "foo" attribute value ends exactly
-			//		with the string "bar"
-			var tval = " "+value;
-			return function(elem){
-				var ea = " "+_getAttr(elem, attr);
-				return (ea.lastIndexOf(value)==(ea.length-value.length));
-			}
-		},
-		"~=": function(attr, value){
-			// E[foo~="bar"]
-			//		an E element whose "foo" attribute value is a list of
-			//		space-separated values, one of which is exactly equal
-			//		to "bar"
-
-			// return "[contains(concat(' ',@"+attr+",' '), ' "+ value +" ')]";
-			var tval = " "+value+" ";
-			return function(elem){
-				var ea = " "+_getAttr(elem, attr)+" ";
-				return (ea.indexOf(tval)>=0);
-			}
-		},
-		"|=": function(attr, value){
-			// E[hreflang|="en"]
-			//		an E element whose "hreflang" attribute has a
-			//		hyphen-separated list of values beginning (from the
-			//		left) with "en"
-			var valueDash = " "+value+"-";
-			return function(elem){
-				var ea = " "+_getAttr(elem, attr);
-				return (
-					(ea == value) ||
-					(ea.indexOf(valueDash)==0)
-				);
-			}
-		},
-		"=": function(attr, value){
-			return function(elem){
-				return (_getAttr(elem, attr) == value);
-			}
-		}
-	};
-
-	// avoid testing for node type if we can. Defining this in the negative
-	// here to avoid negation in the fast path.
-	var _noNES = (typeof getDoc().firstChild.nextElementSibling == "undefined");
-	var _ns = !_noNES ? "nextElementSibling" : "nextSibling";
-	var _ps = !_noNES ? "previousElementSibling" : "previousSibling";
-	var _simpleNodeTest = (_noNES ? _isElement : yesman);
-
-	var _lookLeft = function(node){
-		// look left
-		while(node = node[_ps]){
-			if(_simpleNodeTest(node)){ return false; }
-		}
-		return true;
-	};
-
-	var _lookRight = function(node){
-		// look right
-		while(node = node[_ns]){
-			if(_simpleNodeTest(node)){ return false; }
-		}
-		return true;
-	};
-
-	var getNodeIndex = function(node){
-		var root = node.parentNode;
-		var i = 0,
-			tret = root[childNodesName],
-			ci = (node["_i"]||-1),
-			cl = (root["_l"]||-1);
-
-		if(!tret){ return -1; }
-		var l = tret.length;
-
-		// we calculate the parent length as a cheap way to invalidate the
-		// cache. It's not 100% accurate, but it's much more honest than what
-		// other libraries do
-		if( cl == l && ci >= 0 && cl >= 0 ){
-			// if it's legit, tag and release
-			return ci;
-		}
-
-		// else re-key things
-		root["_l"] = l;
-		ci = -1;
-		for(var te = root["firstElementChild"]||root["firstChild"]; te; te = te[_ns]){
-			if(_simpleNodeTest(te)){
-				te["_i"] = ++i;
-				if(node === te){
-					// NOTE:
-					// 	shortcutting the return at this step in indexing works
-					// 	very well for benchmarking but we avoid it here since
-					// 	it leads to potential O(n^2) behavior in sequential
-					// 	getNodexIndex operations on a previously un-indexed
-					// 	parent. We may revisit this at a later time, but for
-					// 	now we just want to get the right answer more often
-					// 	than not.
-					ci = i;
-				}
-			}
-		}
-		return ci;
-	};
-
-	var isEven = function(elem){
-		return !((getNodeIndex(elem)) % 2);
-	};
-
-	var isOdd = function(elem){
-		return ((getNodeIndex(elem)) % 2);
-	};
-
-	var pseudos = {
-		"checked": function(name, condition){
-			return function(elem){
-				return !!("checked" in elem ? elem.checked : elem.selected);
-			}
-		},
-		"first-child": function(){ return _lookLeft; },
-		"last-child": function(){ return _lookRight; },
-		"only-child": function(name, condition){
-			return function(node){
-				if(!_lookLeft(node)){ return false; }
-				if(!_lookRight(node)){ return false; }
-				return true;
-			};
-		},
-		"empty": function(name, condition){
-			return function(elem){
-				// DomQuery and jQuery get this wrong, oddly enough.
-				// The CSS 3 selectors spec is pretty explicit about it, too.
-				var cn = elem.childNodes;
-				var cnl = elem.childNodes.length;
-				// if(!cnl){ return true; }
-				for(var x=cnl-1; x >= 0; x--){
-					var nt = cn[x].nodeType;
-					if((nt === 1)||(nt == 3)){ return false; }
-				}
-				return true;
-			}
-		},
-		"contains": function(name, condition){
-			var cz = condition.charAt(0);
-			if( cz == '"' || cz == "'" ){ //remove quote
-				condition = condition.slice(1, -1);
-			}
-			return function(elem){
-				return (elem.innerHTML.indexOf(condition) >= 0);
-			}
-		},
-		"not": function(name, condition){
-			var p = getQueryParts(condition)[0];
-			var ignores = { el: 1 };
-			if(p.tag != "*"){
-				ignores.tag = 1;
-			}
-			if(!p.classes.length){
-				ignores.classes = 1;
-			}
-			var ntf = getSimpleFilterFunc(p, ignores);
-			return function(elem){
-				return (!ntf(elem));
-			}
-		},
-		"nth-child": function(name, condition){
-			var pi = parseInt;
-			// avoid re-defining function objects if we can
-			if(condition == "odd"){
-				return isOdd;
-			}else if(condition == "even"){
-				return isEven;
-			}
-			// FIXME: can we shorten this?
-			if(condition.indexOf("n") != -1){
-				var tparts = condition.split("n", 2);
-				var pred = tparts[0] ? ((tparts[0] == '-') ? -1 : pi(tparts[0])) : 1;
-				var idx = tparts[1] ? pi(tparts[1]) : 0;
-				var lb = 0, ub = -1;
-				if(pred > 0){
-					if(idx < 0){
-						idx = (idx % pred) && (pred + (idx % pred));
-					}else if(idx>0){
-						if(idx >= pred){
-							lb = idx - idx % pred;
-						}
-						idx = idx % pred;
-					}
-				}else if(pred<0){
-					pred *= -1;
-					// idx has to be greater than 0 when pred is negative;
-					// shall we throw an error here?
-					if(idx > 0){
-						ub = idx;
-						idx = idx % pred;
-					}
-				}
-				if(pred > 0){
-					return function(elem){
-						var i = getNodeIndex(elem);
-						return (i>=lb) && (ub<0 || i<=ub) && ((i % pred) == idx);
-					}
-				}else{
-					condition = idx;
-				}
-			}
-			var ncount = pi(condition);
-			return function(elem){
-				return (getNodeIndex(elem) == ncount);
-			}
-		}
-	};
-
-	var defaultGetter = (d.isIE < 9 || (dojo.isIE && dojo.isQuirks)) ? 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){
-		// generates a node tester function based on the passed query part. The
-		// query part is one of the structures generated by the query parser
-		// when it creates the query AST. The "ignores" object specifies which
-		// (if any) tests to skip, allowing the system to avoid duplicating
-		// work where it may have already been taken into account by other
-		// factors such as how the nodes to test were fetched in the first
-		// place
-		if(!query){ return yesman; }
-		ignores = ignores||{};
-
-		var ff = null;
-
-		if(!("el" in ignores)){
-			ff = agree(ff, _isElement);
-		}
-
-		if(!("tag" in ignores)){
-			if(query.tag != "*"){
-				ff = agree(ff, function(elem){
-					return (elem && (elem.tagName == query.getTag()));
-				});
-			}
-		}
-
-		if(!("classes" in ignores)){
-			each(query.classes, function(cname, idx, arr){
-				// get the class name
-				/*
-				var isWildcard = cname.charAt(cname.length-1) == "*";
-				if(isWildcard){
-					cname = cname.substr(0, cname.length-1);
-				}
-				// I dislike the regex thing, even if memoized in a cache, but it's VERY short
-				var re = new RegExp("(?:^|\\s)" + cname + (isWildcard ? ".*" : "") + "(?:\\s|$)");
-				*/
-				var re = new RegExp("(?:^|\\s)" + cname + "(?:\\s|$)");
-				ff = agree(ff, function(elem){
-					return re.test(elem.className);
-				});
-				ff.count = idx;
-			});
-		}
-
-		if(!("pseudos" in ignores)){
-			each(query.pseudos, function(pseudo){
-				var pn = pseudo.name;
-				if(pseudos[pn]){
-					ff = agree(ff, pseudos[pn](pn, pseudo.value));
-				}
-			});
-		}
-
-		if(!("attrs" in ignores)){
-			each(query.attrs, function(attr){
-				var matcher;
-				var a = attr.attr;
-				// type, attr, matchFor
-				if(attr.type && attrs[attr.type]){
-					matcher = attrs[attr.type](a, attr.matchFor);
-				}else if(a.length){
-					matcher = defaultGetter(a);
-				}
-				if(matcher){
-					ff = agree(ff, matcher);
-				}
-			});
-		}
-
-		if(!("id" in ignores)){
-			if(query.id){
-				ff = agree(ff, function(elem){
-					return (!!elem && (elem.id == query.id));
-				});
-			}
-		}
-
-		if(!ff){
-			if(!("default" in ignores)){
-				ff = yesman;
-			}
-		}
-		return ff;
-	};
-
-	var _nextSibling = function(filterFunc){
-		return function(node, ret, bag){
-			while(node = node[_ns]){
-				if(_noNES && (!_isElement(node))){ continue; }
-				if(
-					(!bag || _isUnique(node, bag)) &&
-					filterFunc(node)
-				){
-					ret.push(node);
-				}
-				break;
-			}
-			return ret;
-		}
-	};
-
-	var _nextSiblings = function(filterFunc){
-		return function(root, ret, bag){
-			var te = root[_ns];
-			while(te){
-				if(_simpleNodeTest(te)){
-					if(bag && !_isUnique(te, bag)){
-						break;
-					}
-					if(filterFunc(te)){
-						ret.push(te);
-					}
-				}
-				te = te[_ns];
-			}
-			return ret;
-		}
-	};
-
-	// get an array of child *elements*, skipping text and comment nodes
-	var _childElements = function(filterFunc){
-		filterFunc = filterFunc||yesman;
-		return function(root, ret, bag){
-			// get an array of child elements, skipping text and comment nodes
-			var te, x = 0, tret = root[childNodesName];
-			while(te = tret[x++]){
-				if(
-					_simpleNodeTest(te) &&
-					(!bag || _isUnique(te, bag)) &&
-					(filterFunc(te, x))
-				){
-					ret.push(te);
-				}
-			}
-			return ret;
-		};
-	};
-	
-	/*
-	// 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;
-		while(pn){
-			if(pn == root){
-				break;
-			}
-			pn = pn.parentNode;
-		}
-		return !!pn;
-	};
-
-	var _getElementsFuncCache = {};
-
-	var getElementsFunc = function(query){
-		var retFunc = _getElementsFuncCache[query.query];
-		// if we've got a cached dispatcher, just use that
-		if(retFunc){ return retFunc; }
-		// else, generate a new on
-
-		// NOTE:
-		//		this function returns a function that searches for nodes and
-		//		filters them.  The search may be specialized by infix operators
-		//		(">", "~", or "+") else it will default to searching all
-		//		descendants (the " " selector). Once a group of children is
-		//		found, a test function is applied to weed out the ones we
-		//		don't want. Many common cases can be fast-pathed. We spend a
-		//		lot of cycles to create a dispatcher that doesn't do more work
-		//		than necessary at any point since, unlike this function, the
-		//		dispatchers will be called every time. The logic of generating
-		//		efficient dispatchers looks like this in pseudo code:
-		//
-		//		# if it's a purely descendant query (no ">", "+", or "~" modifiers)
-		//		if infixOperator == " ":
-		//			if only(id):
-		//				return def(root):
-		//					return d.byId(id, root);
-		//
-		//			elif id:
-		//				return def(root):
-		//					return filter(d.byId(id, root));
-		//
-		//			elif cssClass && getElementsByClassName:
-		//				return def(root):
-		//					return filter(root.getElementsByClassName(cssClass));
-		//
-		//			elif only(tag):
-		//				return def(root):
-		//					return root.getElementsByTagName(tagName);
-		//
-		//			else:
-		//				# search by tag name, then filter
-		//				return def(root):
-		//					return filter(root.getElementsByTagName(tagName||"*"));
-		//
-		//		elif infixOperator == ">":
-		//			# search direct children
-		//			return def(root):
-		//				return filter(root.children);
-		//
-		//		elif infixOperator == "+":
-		//			# search next sibling
-		//			return def(root):
-		//				return filter(root.nextElementSibling);
-		//
-		//		elif infixOperator == "~":
-		//			# search rightward siblings
-		//			return def(root):
-		//				return filter(nextSiblings(root));
-
-		var io = query.infixOper;
-		var oper = (io ? io.oper : "");
-		// the default filter func which tests for all conditions in the query
-		// part. This is potentially inefficient, so some optimized paths may
-		// re-define it to test fewer things.
-		var filterFunc = getSimpleFilterFunc(query, { el: 1 });
-		var qt = query.tag;
-		var wildcardTag = ("*" == qt);
-		var ecs = getDoc()["getElementsByClassName"];
-
-		if(!oper){
-			// if there's no infix operator, then it's a descendant query. ID
-			// and "elements by class name" variants can be accelerated so we
-			// call them out explicitly:
-			if(query.id){
-				// testing shows that the overhead of yesman() is acceptable
-				// and can save us some bytes vs. re-defining the function
-				// everywhere.
-				filterFunc = (!query.loops && wildcardTag) ?
-					yesman :
-					getSimpleFilterFunc(query, { el: 1, id: 1 });
-
-				retFunc = function(root, arr){
-					var te = d.byId(query.id, (root.ownerDocument||root));
-					if(!te || !filterFunc(te)){ return; }
-					if(9 == root.nodeType){ // if root's a doc, we just return directly
-						return getArr(te, arr);
-					}else{ // otherwise check ancestry
-						if(_isDescendant(te, root)){
-							return getArr(te, arr);
-						}
-					}
-				}
-			}else if(
-				ecs &&
-				// isAlien check. Workaround for Prototype.js being totally evil/dumb.
-				/\{\s*\[native code\]\s*\}/.test(String(ecs)) &&
-				query.classes.length &&
-				!cssCaseBug
-			){
-				// it's a class-based query and we've got a fast way to run it.
-
-				// ignore class and ID filters since we will have handled both
-				filterFunc = getSimpleFilterFunc(query, { el: 1, classes: 1, id: 1 });
-				var classesString = query.classes.join(" ");
-				retFunc = function(root, arr, bag){
-					var ret = getArr(0, arr), te, x=0;
-					var tret = root.getElementsByClassName(classesString);
-					while((te = tret[x++])){
-						if(filterFunc(te, root) && _isUnique(te, bag)){
-							ret.push(te);
-						}
-					}
-					return ret;
-				};
-
-			}else if(!wildcardTag && !query.loops){
-				// 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());
-					while((te = tret[x++])){
-						if(_isUnique(te, bag)){
-							ret.push(te);
-						}
-					}
-					return ret;
-				};
-			}else{
-				// the common case:
-				//		a descendant selector without a fast path. By now it's got
-				//		to have a tag selector, even if it's just "*" so we query
-				//		by that and filter
-				filterFunc = getSimpleFilterFunc(query, { el: 1, tag: 1, id: 1 });
-				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());
-					while((te = tret[x++])){
-						if(filterFunc(te, root) && _isUnique(te, bag)){
-							ret.push(te);
-						}
-					}
-					return ret;
-				};
-			}
-		}else{
-			// the query is scoped in some way. Instead of querying by tag we
-			// use some other collection to find candidate nodes
-			var skipFilters = { el: 1 };
-			if(wildcardTag){
-				skipFilters.tag = 1;
-			}
-			filterFunc = getSimpleFilterFunc(query, skipFilters);
-			if("+" == oper){
-				retFunc = _nextSibling(filterFunc);
-			}else if("~" == oper){
-				retFunc = _nextSiblings(filterFunc);
-			}else if(">" == oper){
-				retFunc = _childElements(filterFunc);
-			}
-		}
-		// cache it and return
-		return _getElementsFuncCache[query.query] = retFunc;
-	};
-
-	var filterDown = function(root, queryParts){
-		// NOTE:
-		//		this is the guts of the DOM query system. It takes a list of
-		//		parsed query parts and a root and finds children which match
-		//		the selector represented by the parts
-		var candidates = getArr(root), qp, x, te, qpl = queryParts.length, bag, ret;
-
-		for(var i = 0; i < qpl; i++){
-			ret = [];
-			qp = queryParts[i];
-			x = candidates.length - 1;
-			if(x > 0){
-				// 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
-				bag = {};
-				ret.nozip = true;
-			}
-			var gef = getElementsFunc(qp);
-			for(var j = 0; (te = candidates[j]); j++){
-				// for every root, get the elements that match the descendant
-				// selector, adding them to the "ret" array and filtering them
-				// via membership in this level's bag. If there are more query
-				// parts, then this level's return will be used as the next
-				// level's candidates
-				gef(te, ret, bag);
-			}
-			if(!ret.length){ break; }
-			candidates = ret;
-		}
-		return ret;
-	};
-
-	////////////////////////////////////////////////////////////////////////
-	// the query runner
-	////////////////////////////////////////////////////////////////////////
-
-	// these are the primary caches for full-query results. The query
-	// dispatcher functions are generated then stored here for hash lookup in
-	// the future
-	var _queryFuncCacheDOM = {},
-		_queryFuncCacheQSA = {};
-
-	// this is the second level of spliting, from full-length queries (e.g.,
-	// "div.foo .bar") into simple query expressions (e.g., ["div.foo",
-	// ".bar"])
-	var getStepQueryFunc = function(query){
-		var qparts = getQueryParts(trim(query));
-
-		// if it's trivial, avoid iteration and zipping costs
-		if(qparts.length == 1){
-			// we optimize this case here to prevent dispatch further down the
-			// chain, potentially slowing things down. We could more elegantly
-			// handle this in filterDown(), but it's slower for simple things
-			// that need to be fast (e.g., "#someId").
-			var tef = getElementsFunc(qparts[0]);
-			return function(root){
-				var r = tef(root, new qlc());
-				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:
-	//	* we can't trust QSA for anything but document-rooted queries, so
-	//	  caching is split into DOM query evaluators and QSA query evaluators
-	//	* caching query results is dirty and leak-prone (or, at a minimum,
-	//	  prone to unbounded growth). Other toolkits may go this route, but
-	//	  they totally destroy their own ability to manage their memory
-	//	  footprint. If we implement it, it should only ever be with a fixed
-	//	  total element reference # limit and an LRU-style algorithm since JS
-	//	  has no weakref support. Caching compiled query evaluators is also
-	//	  potentially problematic, but even on large documents the size of the
-	//	  query evaluators is often < 100 function objects per evaluator (and
-	//	  LRU can be applied if it's ever shown to be an issue).
-	//	* since IE's QSA support is currently only for HTML documents and even
-	//	  then only in IE 8's "standards mode", we have to detect our dispatch
-	//	  route at query time and keep 2 separate caches. Ugg.
-
-	// 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
-	// 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 = (
-		d.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 = d.isIE ? "commentStrip" : "nozip";
-
-	var qsa = "querySelectorAll";
-	var qsaAvail = (
-		!!getDoc()[qsa] &&
-		// see #5832
-		(!d.isSafari || (d.isSafari > 3.1) || is525 )
-	);
-
-	//Don't bother with n+3 type of matches, IE complains if we modify those.
-	var infixSpaceRe = /n\+\d|([^ ])?([>~+])([^ =])?/g;
-	var infixSpaceFunc = function(match, pre, ch, post) {
-		return ch ? (pre ? pre + " " : "") + ch + (post ? " " + post : "") : /*n+3*/ match;
-	};
-
-	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);
-
-		if(qsaAvail){
-			// if we've got a cached variant and we think we can do it, run it!
-			var qsaCached = _queryFuncCacheQSA[query];
-			if(qsaCached && !forceDOM){ return qsaCached; }
-		}
-
-		// else if we've got a DOM cached variant, assume that we already know
-		// all we need to and use it
-		var domCached = _queryFuncCacheDOM[query];
-		if(domCached){ return domCached; }
-
-		// TODO:
-		//		today we're caching DOM and QSA branches separately so we
-		//		recalc useQSA every time. If we had a way to tag root+query
-		//		efficiently, we'd be in good shape to do a global cache.
-
-		var qcz = query.charAt(0);
-		var nospace = (-1 == query.indexOf(" "));
-
-		// byId searches are wicked fast compared to QSA, even when filtering
-		// is required
-		if( (query.indexOf("#") >= 0) && (nospace) ){
-			forceDOM = true;
-		}
-
-		var useQSA = (
-			qsaAvail && (!forceDOM) &&
-			// as per CSS 3, we can't currently start w/ combinator:
-			//		http://www.w3.org/TR/css3-selectors/#w3cselgrammar
-			(specials.indexOf(qcz) == -1) &&
-			// IE's QSA impl sucks on pseudos
-			(!d.isIE || (query.indexOf(":") == -1)) &&
-
-			(!(cssCaseBug && (query.indexOf(".") >= 0))) &&
-
-			// FIXME:
-			//		need to tighten up browser rules on ":contains" and "|=" to
-			//		figure out which aren't good
-			//		Latest webkit (around 531.21.8) does not seem to do well with :checked on option
-			//		elements, even though according to spec, selected options should
-			//		match :checked. So go nonQSA for it:
-			//		http://bugs.dojotoolkit.org/ticket/5179
-			(query.indexOf(":contains") == -1) && (query.indexOf(":checked") == -1) &&
-			(query.indexOf("|=") == -1) // some browsers don't grok it
-		);
-
-		// TODO:
-		//		if we've got a descendant query (e.g., "> .thinger" instead of
-		//		just ".thinger") in a QSA-able doc, but are passed a child as a
-		//		root, it should be possible to give the item a synthetic ID and
-		//		trivially rewrite the query to the form "#synid > .thinger" to
-		//		use the QSA branch
-
-
-		if(useQSA){
-			var tq = (specials.indexOf(query.charAt(query.length-1)) >= 0) ?
-						(query + " *") : query;
-			return _queryFuncCacheQSA[query] = function(root){
-				try{
-					// the QSA system contains an egregious spec bug which
-					// limits us, effectively, to only running QSA queries over
-					// entire documents.  See:
-					//		http://ejohn.org/blog/thoughts-on-queryselectorall/
-					//	despite this, we can also handle QSA runs on simple
-					//	selectors, but we don't want detection to be expensive
-					//	so we're just checking for the presence of a space char
-					//	right now. Not elegant, but it's cheaper than running
-					//	the query parser when we might not need to
-					if(!((9 == root.nodeType) || nospace)){ throw ""; }
-					var r = root[qsa](tq);
-					// skip expensive duplication checks and just wrap in a NodeList
-					r[noZip] = true;
-					return r;
-				}catch(e){
-					// else run the DOM branch on this query, ensuring that we
-					// default that way in the future
-					return getQueryFunc(query, true)(root);
-				}
-			}
-		}else{
-			// DOM branch
-			var parts = query.split(/\s*,\s*/);
-			return _queryFuncCacheDOM[query] = ((parts.length < 2) ?
-				// if not a compound query (e.g., ".foo, .bar"), cache and return a dispatcher
-				getStepQueryFunc(query) :
-				// if it *is* a complex query, break it up into its
-				// constituent parts and return a dispatcher that will
-				// merge the parts when run
-				function(root){
-					var pindex = 0, // avoid array alloc for every invocation
-						ret = [],
-						tp;
-					while((tp = parts[pindex++])){
-						ret = ret.concat(getStepQueryFunc(tp)(root));
-					}
-					return ret;
-				}
-			);
-		}
-	};
-
-	var _zipIdx = 0;
-
-	// NOTE:
-	//		this function is Moo inspired, but our own impl to deal correctly
-	//		with XML in IE
-	var _nodeUID = d.isIE ? function(node){
-		if(caseSensitive){
-			// XML docs don't have uniqueID on their nodes
-			return (node.getAttribute("_uid") || node.setAttribute("_uid", ++_zipIdx) || _zipIdx);
-
-		}else{
-			return node.uniqueID;
-		}
-	} :
-	function(node){
-		return (node._uid || (node._uid = ++_zipIdx));
-	};
-
-	// determine if a node in is unique in a "bag". In this case we don't want
-	// to flatten a list of unique items, but rather just tell if the item in
-	// question is already in the bag. Normally we'd just use hash lookup to do
-	// this for us but IE's DOM is busted so we can't really count on that. On
-	// the upside, it gives us a built in unique ID function.
-	var _isUnique = function(node, bag){
-		if(!bag){ return 1; }
-		var id = _nodeUID(node);
-		if(!bag[id]){ return bag[id] = 1; }
-		return 0;
-	};
-
-	// attempt to efficiently determine if an item in a list is a dupe,
-	// returning a list of "uniques", hopefully in doucment order
-	var _zipIdxName = "_zipIdx";
-	var _zip = function(arr){
-		if(arr && arr.nozip){
-			return (qlc._wrap) ? qlc._wrap(arr) : arr;
-		}
-		// var ret = new d._NodeListCtor();
-		var ret = new qlc();
-		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(d.isIE && caseSensitive){
-			var szidx = _zipIdx+"";
-			arr[0].setAttribute(_zipIdxName, szidx);
-			for(var x = 1, te; te = arr[x]; x++){
-				if(arr[x].getAttribute(_zipIdxName) != szidx){
-					ret.push(te);
-				}
-				te.setAttribute(_zipIdxName, szidx);
-			}
-		}else if(d.isIE && arr.commentStrip){
-			try{
-				for(var x = 1, te; te = arr[x]; x++){
-					if(_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){
-					ret.push(te);
-				}
-				te[_zipIdxName] = _zipIdx;
-			}
-		}
-		return ret;
-	};
-
-	// the main executor
-	d.query = function(/*String*/ query, /*String|DOMNode?*/ root){
-		//	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 instance of dojo.NodeList.
-		//	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
-		//		CSS-based node selector support with the option of scoping searches
-		//		to a particular sub-tree of a document.
-		//
-		//		Supported Selectors:
-		//		--------------------
-		//
-		//		dojo.query() 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
-		//
-		//		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 operations become very straightforward.
-		//
-		//		Unsupported Selectors:
-		//		----------------------
-		//
-		//		While dojo.query handles many CSS3 selectors, some fall outside of
-		//		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`,
-		//				  `:enabled`, `:disabled`
-		//			* `:*-of-type` pseudo selectors
-		//
-		//		dojo.query and XML Documents:
-		//		-----------------------------
-		//
-		//		`dojo.query` (as of dojo 1.2) supports searching XML documents
-		//		in a case-sensitive manner. If an HTML document is served with
-		//		a doctype that forces case-sensitivity (e.g., XHTML 1.1
-		//		Strict), dojo.query() will detect this and "do the right
-		//		thing". Case sensitivity is dependent upon the document being
-		//		searched and not the query used. It is therefore possible to
-		//		use case-sensitive queries on strict sub-documents (iframes,
-		//		etc.) or XML documents while still assuming case-insensitivity
-		//		for a host/root document.
-		//
-		//		Non-selector Queries:
-		//		---------------------
-		//
-		//		If something other than a String is passed for the query,
-		//		`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:
-		//		The CSS3 expression to match against. For details on the syntax of
-		//		CSS3 selectors, see <http://www.w3.org/TR/css3-selectors/#selectors>
-		//	root:
-		//		A DOMNode (or node id) to scope the search from. Optional.
-		//	returns: dojo.NodeList
-		//		An instance of `dojo.NodeList`. Many methods are available on
-		//		NodeLists for searching, iterating, manipulating, and handling
-		//		events on the matched nodes in the returned list.
-		//	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:
-		//		search the entire document for elements with the classes "foo" *and* "bar":
-		//	|	dojo.query(".foo.bar");
-		//		these elements will match:
-		//	|	<span class="foo bar"></span>
-		//		while these will not:
-		//	|	<span class="foo"></span>
-		//	|	<p class="thud foo"></p>
-		//	example:
-		//		find `<span>` elements which are descendants of paragraphs and
-		//		which have a "highlighted" class:
-		//	|	dojo.query("p span.highlighted");
-		//		the innermost span in this fragment matches:
-		//	|	<p class="foo">
-		//	|		<span>...
-		//	|			<span class="highlighted foo bar">...</span>
-		//	|		</span>
-		//	|	</p>
-		//	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:
-		//		remove all elements with the class "error" from the document
-		//		and store them in a list:
-		//	|	var errors = dojo.query(".error").orphan();
-		//	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){
-		//	|		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");
-		//	|			}
-		//	|		});
-		//	|	});
-
-		//Set list constructor to desired value. This can change
-		//between calls, so always re-assign here.
-		qlc = d._NodeListCtor;
-
-		if(!query){
-			return new qlc();
-		}
-
-		if(query.constructor == qlc){
-			return query;
-		}
-		if(typeof query != "string"){ // inline'd type check
-			return new qlc(query); // dojo.NodeList
-		}
-		if(typeof root == "string"){ // inline'd type check
-			root = d.byId(root);
-			if(!root){ return new qlc(); }
-		}
-
-		root = root||getDoc();
-		var od = root.ownerDocument||root.documentElement;
-
-		// 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") ||
-						(d.isOpera && (root.doctype || od.toString() == "[object XMLDocument]")) ||
-						(!!od) &&
-						(d.isIE ? od.xml : (root.xmlVersion||od.xmlVersion));
-
-		// NOTE:
-		//		adding "true" as the 2nd argument to getQueryFunc is useful for
-		//		testing the DOM branch without worrying about the
-		//		behavior/performance of the QSA branch.
-		var r = getQueryFunc(query)(root);
-
-		// FIXME:
-		//		need to investigate this branch WRT #8074 and #8075
-		if(r && r.nozip && !qlc._wrap){
-			return r;
-		}
-		return _zip(r); // dojo.NodeList
-	}
-
-	// FIXME: need to add infrastructure for post-filtering pseudos, ala :last
-	d.query.pseudos = pseudos;
-
-	// function for filtering a NodeList based on a selector, optimized for simple selectors
-	d._filterQueryResult = function(/*NodeList*/ nodeList, /*String*/ filter, /*String|DOMNode?*/ root){
-		var tmpNodeList = new d._NodeListCtor(),
-			parts = getQueryParts(filter),
-			filterFunc =
-				(parts.length == 1 && !/[^\w#\.]/.test(filter)) ?
-				getSimpleFilterFunc(parts[0]) :
-				function(node) {
-					return dojo.query(filter, root).indexOf(node) != -1;
-				};
-		for(var x = 0, te; te = nodeList[x]; x++){
-			if(filterFunc(te)){ tmpNodeList.push(te); }
-		}
-		return tmpNodeList;
-	}
-};//end defineQuery
-
-var defineAcme= function(){
-	// a self-sufficient query impl
-	acme = {
-		trim: function(/*String*/ str){
-			// summary:
-			//		trims whitespaces from both sides of the string
-			str = str.replace(/^\s+/, '');
-			for(var i = str.length - 1; i >= 0; i--){
-				if(/\S/.test(str.charAt(i))){
-					str = str.substring(0, i + 1);
-					break;
-				}
-			}
-			return str;	// String
-		},
-		forEach: function(/*String*/ arr, /*Function*/ callback, /*Object?*/ thisObject){
-			//	summary:
-			// 		an iterator function that passes items, indexes,
-			// 		and the array to a callback
-			if(!arr || !arr.length){ return; }
-			for(var i=0,l=arr.length; i<l; ++i){
-				callback.call(thisObject||window, arr[i], i, arr);
-			}
-		},
-		byId: function(id, doc){
-			// 	summary:
-			//		a function that return an element by ID, but also
-			//		accepts nodes safely
-			if(typeof id == "string"){
-				return (doc||document).getElementById(id); // DomNode
-			}else{
-				return id; // DomNode
-			}
-		},
-		// the default document to search
-		doc: document,
-		// the constructor for node list objects returned from query()
-		NodeList: Array
-	};
-
-	// define acme.isIE, acme.isSafari, acme.isOpera, etc.
-	var n = navigator;
-	var dua = n.userAgent;
-	var dav = n.appVersion;
-	var tv = parseFloat(dav);
-	acme.isOpera = (dua.indexOf("Opera") >= 0) ? tv: undefined;
-	acme.isKhtml = (dav.indexOf("Konqueror") >= 0) ? tv : undefined;
-	acme.isWebKit = parseFloat(dua.split("WebKit/")[1]) || undefined;
-	acme.isChrome = parseFloat(dua.split("Chrome/")[1]) || undefined;
-	var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);
-	if(index && !acme.isChrome){
-		acme.isSafari = parseFloat(dav.split("Version/")[1]);
-		if(!acme.isSafari || parseFloat(dav.substr(index + 7)) <= 419.3){
-			acme.isSafari = 2;
-		}
-	}
-	if(document.all && !acme.isOpera){
-		acme.isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
-	}
-
-	Array._wrap = function(arr){ return arr; };
-  return acme;
-};
-
-//>>includeStart("amdLoader", kwArgs.asynchLoader);
-if (typeof define == "function"){
-	define("dojo/_base/query", ["dojo/lib/kernel", "dojo/_base/NodeList", "dojo/_base/lang", "dojo/_base/window"], function(dojo){
-		defineQuery(this["queryPortability"]||this["acme"]||dojo);
-	});
-}
-if (typeof define != "function"){
-//>>includeEnd("amdLoader");
-	//prefers queryPortability, then acme, then dojo
-	if(this["dojo"]){
-		dojo.provide("dojo._base.query");
-		dojo.require("dojo._base.NodeList");
-		dojo.require("dojo._base.lang");
-		defineQuery(this["queryPortability"]||this["acme"]||dojo);
-	}else{
-		defineQuery(this["queryPortability"]||this["acme"]||defineAcme());
-	}
-//>>includeStart("amdLoader", kwArgs.asynchLoader);
-}
-//>>includeEnd("amdLoader");
-
-})();
-//>>excludeEnd("webkitMobile");
-
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-/*
-//>>excludeEnd("webkitMobile");
-//>>includeStart("webkitMobile", kwArgs.webkitMobile);
-(function() {
-  function qdef() {
-    if (dojo.query) {
-      return;
-    }
-		var ctr = 0;
-		// QSA-only for webkit mobile. Welcome to the future.
-		dojo.query = function(query, root){
-			d._NodeListCtor = dojo.NodeList;
-			if(!query){
-				return new d._NodeListCtor();
-			}
-
-			if(query.constructor == d._NodeListCtor){
-				return query;
-			}
-
-			if(typeof query != "string"){ // inline'd type check
-				return new d._NodeListCtor(query); // dojo.NodeList
-			}
-
-			if(typeof root == "string"){ // inline'd type check
-				root = dojo.byId(root);
-				if(!root){ return new d._NodeListCtor(); }
-			}
-
-			root = root||dojo.doc;
-			var rootIsDoc = (root.nodeType == 9);
-			var doc = rootIsDoc ? root : (root.ownerDocument||dojo.doc);
-			// rewrite the query to be ID rooted
-			if(!rootIsDoc || (">~+".indexOf(query.charAt(0)) >= 0)){
-				root.id = root.id||("qUnique"+(ctr++));
-				query = "#"+root.id+" "+query;
-			}
-			// rewrite the query to not choke on something like ".yada.yada >"
-			// by adding a final descendant component
-
-			if(">~+".indexOf(query.slice(-1)) >= 0){
-				query += " *";
-			}
-			return d._NodeListCtor._wrap(
-				Array.prototype.slice.call(
-					doc.querySelectorAll(query)
-				)
-			);
-		};
-	}
-
-  if (typeof define != "undefined") {
-    define("dojo/_base/query", ["dojo", "dojo/_base/NodeList", "dojo/_base/lang"], qdef);
-  } else {
-    dojo.provide("dojo._base.query");
-	  dojo.require("dojo._base.NodeList");
-	  dojo.require("dojo._base.lang");
-    qdef();
-  }
-})();
-
-//>>includeEnd("webkitMobile");
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-*/
-//>>excludeEnd("webkitMobile");
+define(["./kernel", "../query", "./NodeList"], function(dojo){
+	return dojo.query;
+});
diff --git a/dojo/_base/sniff.js b/dojo/_base/sniff.js
new file mode 100644
index 0000000..948efbf
--- /dev/null
+++ b/dojo/_base/sniff.js
@@ -0,0 +1,187 @@
+define(["./kernel", "../has"], function(dojo, has){
+	// module:
+	//		dojo/sniff
+	// summary:
+	//		This module populates the dojo browser version sniffing properties.
+
+	if(!has("host-browser")){
+		return has;
+	}
+
+	dojo.isBrowser = true,
+	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, {
+		// isBrowser: Boolean
+		//		True if the client is a web-browser
+		isBrowser: true,
+		//	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
+		//		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
+		//		Version as a Number if client is a KHTML browser. undefined otherwise. Corresponds to major
+		//		detected version.
+		isKhtml: 0,
+		//	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
+		//		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
+		//		Version as a Number if client is Opera. undefined otherwise. Corresponds to
+		//		major detected version.
+		isOpera: 0,
+		//	isSafari: Number | undefined
+		//		Version as a Number if client is Safari or iPhone. undefined otherwise.
+		isSafari: 0,
+		//	isChrome: Number | undefined
+		//		Version as a Number if client is Chrome browser. undefined otherwise.
+		isChrome: 0,
+		//	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
+		//		Version as a Number if client is android browser. undefined otherwise.
+		isAndroid: 0,
+		// isWii: Boolean
+		//		True if client is Wii
+		isWii: 0
+	});
+	=====*/
+
+	// 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 = 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();
+
+	return has;
+});
diff --git a/dojo/_base/unload.js b/dojo/_base/unload.js
new file mode 100644
index 0000000..26f00df
--- /dev/null
+++ b/dojo/_base/unload.js
@@ -0,0 +1,81 @@
+define(["./kernel", "./connect"], function(dojo, connect) {
+	// module:
+	//		dojo/unload
+	// summary:
+	//		This module contains the document and window unload detection API.
+
+	var win = window;
+
+	/*=====
+		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.
+		};
+	=====*/
+
+	dojo.addOnWindowUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
+		// summary:
+		//		registers a function to be triggered when window.onunload
+		//		fires.
+		//	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
+		//		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
+		//		the page's "onbeforeunload" event.
+		// example:
+		//	| dojo.addOnWindowUnload(functionPointer)
+		//	| dojo.addOnWindowUnload(object, "functionName");
+		//	| dojo.addOnWindowUnload(object, function(){ /* ... */});
+
+		if (!dojo.windowUnloaded) {
+			connect.connect(win, "unload", (dojo.windowUnloaded= function(){}));
+		}
+		connect.connect(win, "unload", obj, functionName);
+	};
+
+	dojo.addOnUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
+		// summary:
+		//		registers a function to be triggered when the page unloads.
+		//	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
+		//		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
+		//		the link is a javascript: link. In these cases, the
+		//		onbeforeunload event fires, but the document is not
+		//		actually destroyed. So be careful about doing destructive
+		//		operations in a dojo.addOnUnload callback.
+		//
+		//		Further note that calling dojo.addOnUnload will prevent
+		//		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(){ /* ... */});
+
+		connect.connect(win, "beforeunload", obj, functionName);
+	};
+
+	return {
+		addOnWindowUnload: dojo.addOnWindowUnload,
+		addOnUnload: dojo.addOnUnload
+	};
+});
diff --git a/dojo/_base/url.js b/dojo/_base/url.js
new file mode 100644
index 0000000..74ada72
--- /dev/null
+++ b/dojo/_base/url.js
@@ -0,0 +1,111 @@
+define(["./kernel"], function(dojo) {
+	// module:
+	//		dojo/url
+	// summary:
+	//		This module contains dojo._Url
+
+	var
+		ore = new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"),
+		ire = new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$"),
+		_Url = function(){
+			var n = null,
+				_a = arguments,
+				uri = [_a[0]];
+			// resolve uri components relative to each other
+			for(var i = 1; i<_a.length; i++){
+				if(!_a[i]){ continue; }
+
+				// Safari doesn't support this.constructor so we have to be explicit
+				// FIXME: Tracked (and fixed) in Webkit bug 3537.
+				//		http://bugs.webkit.org/show_bug.cgi?id=3537
+				var relobj = new _Url(_a[i]+""),
+					uriobj = new _Url(uri[0]+"");
+
+				if(
+					relobj.path == "" &&
+					!relobj.scheme &&
+					!relobj.authority &&
+					!relobj.query
+				){
+					if(relobj.fragment != n){
+						uriobj.fragment = relobj.fragment;
+					}
+					relobj = uriobj;
+				}else if(!relobj.scheme){
+					relobj.scheme = uriobj.scheme;
+
+					if(!relobj.authority){
+						relobj.authority = uriobj.authority;
+
+						if(relobj.path.charAt(0) != "/"){
+							var path = uriobj.path.substring(0,
+								uriobj.path.lastIndexOf("/") + 1) + relobj.path;
+
+							var segs = path.split("/");
+							for(var j = 0; j < segs.length; j++){
+								if(segs[j] == "."){
+									// flatten "./" references
+									if(j == segs.length - 1){
+										segs[j] = "";
+									}else{
+										segs.splice(j, 1);
+										j--;
+									}
+								}else if(j > 0 && !(j == 1 && segs[0] == "") &&
+									segs[j] == ".." && segs[j-1] != ".."){
+									// flatten "../" references
+									if(j == (segs.length - 1)){
+										segs.splice(j, 1);
+										segs[j - 1] = "";
+									}else{
+										segs.splice(j - 1, 2);
+										j -= 2;
+									}
+								}
+							}
+							relobj.path = segs.join("/");
+						}
+					}
+				}
+
+				uri = [];
+				if(relobj.scheme){
+					uri.push(relobj.scheme, ":");
+				}
+				if(relobj.authority){
+					uri.push("//", relobj.authority);
+				}
+				uri.push(relobj.path);
+				if(relobj.query){
+					uri.push("?", relobj.query);
+				}
+				if(relobj.fragment){
+					uri.push("#", relobj.fragment);
+				}
+			}
+
+			this.uri = uri.join("");
+
+			// break the uri into its main components
+			var r = this.uri.match(ore);
+
+			this.scheme = r[2] || (r[1] ? "" : n);
+			this.authority = r[4] || (r[3] ? "" : n);
+			this.path = r[5]; // can never be undefined
+			this.query = r[7] || (r[6] ? "" : n);
+			this.fragment	 = r[9] || (r[8] ? "" : n);
+
+			if(this.authority != n){
+				// server based naming authority
+				r = this.authority.match(ire);
+
+				this.user = r[3] || n;
+				this.password = r[4] || n;
+				this.host = r[6] || r[7]; // ipv6 || ipv4
+				this.port = r[9] || n;
+			}
+		};
+	_Url.prototype.toString = function(){ return this.uri; };
+
+	return dojo._Url = _Url;
+});
diff --git a/dojo/_base/window.js b/dojo/_base/window.js
index 7908969..06092e8 100644
--- a/dojo/_base/window.js
+++ b/dojo/_base/window.js
@@ -1,4 +1,8 @@
-define("dojo/_base/window", ["dojo/lib/kernel"], function(dojo){
+define(["./kernel", "../has", "./sniff"], function(dojo, has){
+	// module:
+	//		dojo/window
+	// summary:
+	//		This module provides an API to save/set/restore the global/document scope.
 
 /*=====
 dojo.doc = {
@@ -6,21 +10,21 @@ dojo.doc = {
 	//		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.
+	//		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'));
+	//	|	n.appendChild(dojo.doc.createElement('div'));
 }
 =====*/
-dojo.doc = window["document"] || null;
+dojo.doc = this["document"] || null;
 
 dojo.body = function(){
 	// summary:
 	//		Return the body element of the document
 	//		return the body object associated with dojo.doc
 	// example:
-	// 	|	dojo.body().appendChild(dojo.doc.createElement('div'));
+	//	|	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().
@@ -34,8 +38,8 @@ dojo.setContext = function(/*Object*/globalObject, /*DocumentElement*/globalDocu
 	//		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 = globalObject;
-	dojo.doc = globalDocument;
+	dojo.global = ret.global = globalObject;
+	dojo.doc = ret.doc = globalDocument;
 };
 
 dojo.withGlobal = function(	/*Object*/globalObject,
@@ -54,10 +58,10 @@ dojo.withGlobal = function(	/*Object*/globalObject,
 
 	var oldGlob = dojo.global;
 	try{
-		dojo.global = globalObject;
+		dojo.global = ret.global = globalObject;
 		return dojo.withDoc.call(null, globalObject.document, callback, thisObject, cbArguments);
 	}finally{
-		dojo.global = oldGlob;
+		dojo.global = ret.global = oldGlob;
 	}
 };
 
@@ -74,13 +78,27 @@ dojo.withDoc = function(	/*DocumentElement*/documentObject,
 	//		be restored to its previous state.
 
 	var oldDoc = dojo.doc,
-		oldLtr = dojo._bodyLtr,
-		oldQ = dojo.isQuirks;
+		oldQ = dojo.isQuirks,
+		oldIE = dojo.isIE, isIE, mode, pwin;
 
 	try{
-		dojo.doc = documentObject;
-		delete dojo._bodyLtr; // uncache
-		dojo.isQuirks = dojo.doc.compatMode == "BackCompat"; // no need to check for QuirksMode which was Opera 7 only
+		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;
+				}
+				dojo.isIE = has.add("ie", isIE, true, true);
+			}
+		}
 
 		if(thisObject && typeof callback == "string"){
 			callback = thisObject[callback];
@@ -88,12 +106,21 @@ dojo.withDoc = function(	/*DocumentElement*/documentObject,
 
 		return callback.apply(thisObject, cbArguments || []);
 	}finally{
-		dojo.doc = oldDoc;
-		delete dojo._bodyLtr; // in case it was undefined originally, and set to true/false by the alternate document
-		if(oldLtr !== undefined){ dojo._bodyLtr = oldLtr; }
-		dojo.isQuirks = oldQ;
+		dojo.doc = ret.doc = oldDoc;
+		dojo.isQuirks = has.add("quirks", oldQ, true, true);
+		dojo.isIE = has.add("ie", oldIE, true, true);
 	}
 };
 
-return dojo;
+var ret = {
+	global: dojo.global,
+	doc: dojo.doc,
+	body: dojo.body,
+	setContext: dojo.setContext,
+	withGlobal: dojo.withGlobal,
+	withDoc: dojo.withDoc
+};
+
+return ret;
+
 });
diff --git a/dojo/_base/xhr.js b/dojo/_base/xhr.js
index fc3c04e..8a8a8ad 100644
--- a/dojo/_base/xhr.js
+++ b/dojo/_base/xhr.js
@@ -1,207 +1,57 @@
-define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/json", "dojo/_base/lang", "dojo/_base/query"], function(dojo){
-
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-(function(){
-//>>excludeEnd("webkitMobile");
-	var _d = dojo, cfg = _d.config;
-
-	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
-		//		array of values.
-
-		//Skip it if there is no value
-		if(value === null){
-			return;
-		}
-
-		var val = obj[name];
-		if(typeof val == "string"){ // inline'd type check
-			obj[name] = [val, value];
-		}else if(_d.isArray(val)){
-			val.push(value);
-		}else{
-			obj[name] = value;
-		}
-	}
-	
-	dojo.fieldToObject = function(/*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.
-		var ret = null;
-		var item = _d.byId(inputNode);
-		if(item){
-			var _in = item.name;
-			var type = (item.type||"").toLowerCase();
-			if(_in && type && !item.disabled){
-				if(type == "radio" || type == "checkbox"){
-					if(item.checked){ ret = item.value; }
-				}else if(item.multiple){
-					ret = [];
-					_d.query("option", item).forEach(function(opt){
-						if(opt.selected){
-							ret.push(opt.value);
-						}
-					});
-				}else{
-					ret = item.value;
-				}
-			}
-		}
-		return ret; // Object
-	};
+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';
+	});
 
-	dojo.formToObject = function(/*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.
-		//
-		// 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 = {};
-		var exclude = "file|submit|image|reset|button|";
-		_d.forEach(dojo.byId(formNode).elements, function(item){
-			var _in = item.name;
-			var type = (item.type||"").toLowerCase();
-			if(_in && type && exclude.indexOf(type) == -1 && !item.disabled){
-				setValue(ret, _in, _d.fieldToObject(item));
-				if(type == "image"){
-					ret[_in+".x"] = ret[_in+".y"] = ret[_in].x = ret[_in].y = 0;
-				}
+	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);
 			}
-		});
-		return ret; // Object
-	};
-
-	dojo.objectToQuery = function(/*Object*/ map){
-		//	summary:
-		//		takes a name/value mapping object and returns a string representing
-		//		a URL-encoded version of that object.
-		//	example:
-		//		this object:
-		//
-		//		|	{
-		//		|		blah: "blah",
-		//		|		multi: [
-		//		|			"thud",
-		//		|			"thonk"
-		//		|		]
-		//		|	};
-		//
-		//	yields the following query string:
-		//
-		//	|	"blah=blah&multi=thud&multi=thonk"
-
-		// FIXME: need to implement encodeAscii!!
-		var enc = encodeURIComponent;
-		var pairs = [];
-		var backstop = {};
-		for(var name in map){
-			var value = map[name];
-			if(value != backstop[name]){
-				var assign = enc(name) + "=";
-				if(_d.isArray(value)){
-					for(var i=0; i < value.length; i++){
-						pairs.push(assign + enc(value[i]));
-					}
-				}else{
-					pairs.push(assign + enc(value));
+		};
+	}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
 			}
 		}
-		return pairs.join("&"); // String
-	};
-
-	dojo.formToQuery = function(/*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
-		return _d.objectToQuery(_d.formToObject(formNode)); // String
-	};
-
-	dojo.formToJson = function(/*DOMNode||String*/ formNode, /*Boolean?*/prettyPrint){
-		// summary:
-		//		Create a serialized JSON string from a form node or string
-		//		ID identifying the form to serialize
-		return _d.toJson(_d.formToObject(formNode), prettyPrint); // String
-	};
-
-	dojo.queryToObject = function(/*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.
-		//
-		// example:
-		//		This string:
-		//
-		//	|		"foo=bar&foo=baz&thinger=%20spaces%20=blah&zonk=blarg&"
-		//
-		//		results in this object structure:
-		//
-		//	|		{
-		//	|			foo: [ "bar", "baz" ],
-		//	|			thinger: " spaces =blah",
-		//	|			zonk: "blarg"
-		//	|		}
-		//
-		//		Note that spaces and other urlencoded entities are correctly
-		//		handled.
+		dojo._xhrObj= function() {
+			return new ActiveXObject(progid);
+		};
+	}
 
-		// FIXME: should we grab the URL string if we're not passed one?
-		var ret = {};
-		var qp = str.split("&");
-		var dec = decodeURIComponent;
-		_d.forEach(qp, function(item){
-			if(item.length){
-				var parts = item.split("=");
-				var name = dec(parts.shift());
-				var val = dec(parts.join("="));
-				if(typeof ret[name] == "string"){ // inline'd type check
-					ret[name] = [ret[name]];
-				}
+	var cfg = dojo.config;
 
-				if(_d.isArray(ret[name])){
-					ret[name].push(val);
-				}else{
-					ret[name] = val;
-				}
-			}
-		});
-		return ret; // Object
-	};
+	// mix in io-query and dom-form
+	dojo.objectToQuery = ioq.objectToQuery;
+	dojo.queryToObject = ioq.queryToObject;
+	dojo.fieldToObject = domForm.fieldToObject;
+	dojo.formToObject = domForm.toObject;
+	dojo.formToQuery = domForm.toQuery;
+	dojo.formToJson = domForm.toJson;
 
 	// need to block async callbacks from snatching this thread as the result
 	// of an async callback might call another sync XHR, this hangs khtml forever
@@ -210,7 +60,7 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 	dojo._blockAsync = false;
 
 	// MOW: remove dojo._contentHandlers alias in 2.0
-	var handlers = _d._contentHandlers = dojo.contentHandlers = {
+	var handlers = dojo._contentHandlers = dojo.contentHandlers = {
 		// summary:
 		//		A map of availble XHR transport handle types. Name matches the
 		//		`handleAs` attribute passed to XHR calls.
@@ -234,13 +84,13 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 		//	|		load: function(data){ /* data is a toUpper version of foo.txt */ }
 		//	|	});
 
-		text: function(xhr){
+		"text": function(xhr){
 			// summary: A contentHandler which simply returns the plaintext response data
 			return xhr.responseText;
 		},
-		json: function(xhr){
+		"json": function(xhr){
 			// summary: A contentHandler which returns a JavaScript object created from the response data
-			return _d.fromJson(xhr.responseText || null);
+			return json.fromJson(xhr.responseText || null);
 		},
 		"json-comment-filtered": function(xhr){
 			// summary: A contentHandler which expects comment-filtered JSON.
@@ -269,34 +119,35 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 			if(cStartIdx == -1 || cEndIdx == -1){
 				throw new Error("JSON was not comment filtered");
 			}
-			return _d.fromJson(value.substring(cStartIdx+2, cEndIdx));
+			return json.fromJson(value.substring(cStartIdx+2, cEndIdx));
 		},
-		javascript: function(xhr){
+		"javascript": function(xhr){
 			// summary: A contentHandler which evaluates the response data, expecting it to be valid JavaScript
 
 			// FIXME: try Moz and IE specific eval variants?
-			return _d.eval(xhr.responseText);
+			return dojo.eval(xhr.responseText);
 		},
-		xml: function(xhr){
+		"xml": function(xhr){
 			// summary: A contentHandler returning an XML Document parsed from the response data
 			var result = xhr.responseXML;
-			//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-			if(_d.isIE && (!result || !result.documentElement)){
-				//WARNING: this branch used by the xml handling in dojo.io.iframe,
-				//so be sure to test dojo.io.iframe if making changes below.
-				var ms = function(n){ return "MSXML" + n + ".DOMDocument"; };
-				var dp = ["Microsoft.XMLDOM", ms(6), ms(4), ms(3), ms(2)];
-				_d.some(dp, function(p){
-					try{
-						var dom = new ActiveXObject(p);
-						dom.async = false;
-						dom.loadXML(xhr.responseText);
-						result = dom;
-					}catch(e){ return false; }
-					return true;
-				});
-			}
-			//>>excludeEnd("webkitMobile");
+
+			if(has("ie")){
+				if((!result || !result.documentElement)){
+					//WARNING: this branch used by the xml handling in dojo.io.iframe,
+					//so be sure to test dojo.io.iframe if making changes below.
+					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(xhr.responseText);
+							result = dom;
+						}catch(e){ return false; }
+						return true;
+					});
+				}
+		 }
 			return result; // DOMDocument
 		},
 		"json-comment-optional": function(xhr){
@@ -333,15 +184,15 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 		//		Acceptable values depend on the type of IO
 		//		transport (see specific IO calls for more information).
 		//	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.
+		//		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?
 		//		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.
+		//		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.
@@ -349,7 +200,7 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 		//		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
+		//		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?
@@ -435,34 +286,34 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 
 	/*=====
 	dojo.__IoPublish = function(){
-		// 	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.
+		//	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
 		//		"/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.
+		//		requests, and a new IO request is started. No arguments
+		//		are passed with this topic.
 		//	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.
+		//		It passes the dojo.Deferred for the request with the topic.
 		//	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.
+		//		successfully. It passes the response and the dojo.Deferred
+		//		for the request with the topic.
 		//	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.
+		//		It passes the error and the dojo.Deferred
+		//		for the request with the topic.
 		//	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.
+		//		either by loading or by erroring. It passes the error and
+		//		the dojo.Deferred for the request with the topic.
 		//	stop: String
 		//		"/dojo/io/stop" is sent when all outstanding IO requests have
-		// 		finished. No arguments are passed with this topic.
+		//		finished. No arguments are passed with this topic.
 		this.start = "/dojo/io/start";
 		this.send = "/dojo/io/send";
 		this.load = "/dojo/io/load";
@@ -501,17 +352,17 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 		//Get values from form if requestd.
 		var formObject = null;
 		if(args.form){
-			var form = _d.byId(args.form);
+			var form = dom.byId(args.form);
 			//IE requires going through getAttributeNode instead of just getAttribute in some form cases,
-			//so use it for all.  See #2844
+			//so use it for all. See #2844
 			var actnNode = form.getAttributeNode("action");
 			ioArgs.url = ioArgs.url || (actnNode ? actnNode.value : null);
-			formObject = _d.formToObject(form);
+			formObject = domForm.toObject(form);
 		}
 
 		// set up the query params
 		var miArgs = [{}];
-	
+
 		if(formObject){
 			// potentially over-ride url-provided params w/ form values
 			miArgs.push(formObject);
@@ -523,11 +374,11 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 		if(args.preventCache){
 			miArgs.push({"dojo.preventCache": new Date().valueOf()});
 		}
-		ioArgs.query = _d.objectToQuery(_d.mixin.apply(null, miArgs));
-	
+		ioArgs.query = ioq.objectToQuery(lang.mixin.apply(null, miArgs));
+
 		// .. and the real work of getting the deferred in order, etc.
 		ioArgs.handleAs = args.handleAs || "text";
-		var d = new _d.Deferred(canceller);
+		var d = new deferred(canceller);
 		d.addCallbacks(okHandler, function(error){
 			return errHandler(error, d);
 		});
@@ -537,44 +388,44 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 		//The callbacks will get the deferred result value as the
 		//first argument and the ioArgs object as the second argument.
 		var ld = args.load;
-		if(ld && _d.isFunction(ld)){
+		if(ld && lang.isFunction(ld)){
 			d.addCallback(function(value){
 				return ld.call(args, value, ioArgs);
 			});
 		}
 		var err = args.error;
-		if(err && _d.isFunction(err)){
+		if(err && lang.isFunction(err)){
 			d.addErrback(function(value){
 				return err.call(args, value, ioArgs);
 			});
 		}
 		var handle = args.handle;
-		if(handle && _d.isFunction(handle)){
+		if(handle && lang.isFunction(handle)){
 			d.addBoth(function(value){
 				return handle.call(args, value, ioArgs);
 			});
 		}
 
 		//Plug in topic publishing, if dojo.publish is loaded.
-		if(cfg.ioPublish && _d.publish && ioArgs.args.ioPublish !== false){
+		if(cfg.ioPublish && dojo.publish && ioArgs.args.ioPublish !== false){
 			d.addCallbacks(
 				function(res){
-					_d.publish("/dojo/io/load", [d, res]);
+					dojo.publish("/dojo/io/load", [d, res]);
 					return res;
 				},
 				function(res){
-					_d.publish("/dojo/io/error", [d, res]);
+					dojo.publish("/dojo/io/error", [d, res]);
 					return res;
 				}
 			);
 			d.addBoth(function(res){
-				_d.publish("/dojo/io/done", [d, res]);
+				dojo.publish("/dojo/io/done", [d, res]);
 				return res;
 			});
 		}
 
 		d.ioArgs = ioArgs;
-	
+
 		// FIXME: need to wire up the xhr object's abort method to something
 		// analagous in the Deferred
 		return d;
@@ -582,7 +433,7 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 
 	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;
@@ -615,8 +466,8 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 	// 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
@@ -626,8 +477,8 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 	var _checkPubCount = function(dfd){
 		if(_pubCount <= 0){
 			_pubCount = 0;
-			if(cfg.ioPublish && _d.publish && (!dfd || dfd && dfd.ioArgs.args.ioPublish !== false)){
-				_d.publish("/dojo/io/stop");
+			if(cfg.ioPublish && dojo.publish && (!dfd || dfd && dfd.ioArgs.args.ioPublish !== false)){
+				dojo.publish("/dojo/io/stop");
 			}
 		}
 	};
@@ -636,12 +487,12 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 		//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(!_d._blockAsync){
+		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++){
@@ -670,11 +521,11 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 				if(dojo.config.debugAtAllCosts){
 					func.call(this);
 				}else{
-					try{
+//					try{
 						func.call(this);
-					}catch(e){
+	/*				}catch(e){
 						dfd.errback(e);
-					}
+					}*/
 				}
 			}
 		}
@@ -684,7 +535,6 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 		if(!_inFlight.length){
 			clearInterval(_inFlightIntvl);
 			_inFlightIntvl = null;
-			return;
 		}
 	};
 
@@ -692,7 +542,7 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 		//summary: Cancels all pending IO requests, regardless of IO type
 		//(xhr, script, iframe).
 		try{
-			_d.forEach(_inFlight, function(i){
+			array.forEach(_inFlight, function(i){
 				try{
 					i.dfd.cancel();
 				}catch(e){/*squelch*/}
@@ -702,30 +552,28 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 
 	//Automatically call cancel all io calls on unload
 	//in IE for trac issue #2357.
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	if(_d.isIE){
-		_d.addOnWindowUnload(_d._ioCancelAll);
+	if(has("ie")){
+		on(window, "unload", dojo._ioCancelAll);
 	}
-	//>>excludeEnd("webkitMobile");
 
-	_d._ioNotifyStart = function(/*Deferred*/dfd){
+	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.
+		//		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 && _d.publish && dfd.ioArgs.args.ioPublish !== false){
+		//		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){
 			if(!_pubCount){
-				_d.publish("/dojo/io/start");
+				dojo.publish("/dojo/io/start");
 			}
 			_pubCount += 1;
-			_d.publish("/dojo/io/send", [dfd]);
+			dojo.publish("/dojo/io/send", [dfd]);
 		}
 	};
 
-	_d._ioWatch = function(dfd, validCheck, ioCheck, resHandle){
+	dojo._ioWatch = function(dfd, validCheck, ioCheck, resHandle){
 		// summary:
 		//		Watches the io request represented by dfd to see if it completes.
 		// dfd: Deferred
@@ -743,7 +591,7 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 		if(args.timeout){
 			dfd.startTime = (new Date()).getTime();
 		}
-		
+
 		_inFlight.push({dfd: dfd, validCheck: validCheck, ioCheck: ioCheck, resHandle: resHandle});
 		if(!_inFlightIntvl){
 			_inFlightIntvl = setInterval(_watchInFlight, 50);
@@ -768,12 +616,13 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 	};
 	var _resHandle = function(/*Deferred*/dfd){
 		var xhr = dfd.ioArgs.xhr;
-		if(_d._isDocumentOk(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);
 		}
 	};
@@ -805,6 +654,10 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 			//		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;
@@ -822,17 +675,17 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 		//		for those HTTP methods. There are also methods for "raw" PUT and POST methods
 		//		via dojo.rawXhrPut() and dojo.rawXhrPost() respectively.
 		//	method:
-		//		HTTP method to be used, such as GET, POST, PUT, DELETE.  Should be uppercase.
+		//		HTTP method to be used, such as GET, POST, PUT, DELETE. Should be uppercase.
 		//	hasBody:
 		//		If the request has an HTTP body, then pass true for hasBody.
 
 		//Make the Deferred object for this xhr request.
-		var dfd = _d._ioSetArgs(args, _deferredCancel, _deferredOk, _deferError);
+		var dfd = dojo._ioSetArgs(args, _deferredCancel, _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 = _d._xhrObj(ioArgs.args);
+		var xhr = ioArgs.xhr = dojo._xhrObj(ioArgs.args);
 		//If XHR factory fails, cancel the deferred.
 		if(!xhr){
 			dfd.cancel();
@@ -849,7 +702,7 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 		}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.
-			_d._ioAddQueryToUrl(ioArgs);
+			dojo._ioAddQueryToUrl(ioArgs);
 		}
 
 		// IE 6 is a steaming pile. It won't let you call apply() on the native function (xhr.open).
@@ -867,12 +720,14 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 			}
 		}
 		// FIXME: is this appropriate for all content types?
-		xhr.setRequestHeader("Content-Type", args.contentType || _defaultContentType);
+		if(args.contentType !== false){
+			xhr.setRequestHeader("Content-Type", args.contentType || _defaultContentType);
+		}
 		if(!args.headers || !("X-Requested-With" in args.headers)){
 			xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
 		}
 		// FIXME: set other headers here!
-		_d._ioNotifyStart(dfd);
+		dojo._ioNotifyStart(dfd);
 		if(dojo.config.debugAtAllCosts){
 			xhr.send(ioArgs.query);
 		}else{
@@ -883,7 +738,7 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 				dfd.cancel();
 			}
 		}
-		_d._ioWatch(dfd, _validCheck, _ioCheck, _resHandle);
+		dojo._ioWatch(dfd, _validCheck, _ioCheck, _resHandle);
 		xhr = null;
 		return dfd; // dojo.Deferred
 	};
@@ -891,7 +746,7 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 	dojo.xhrGet = function(/*dojo.__XhrArgs*/ args){
 		//	summary:
 		//		Sends an HTTP GET request to the server.
-		return _d.xhr("GET", args); // dojo.Deferred
+		return dojo.xhr("GET", args); // dojo.Deferred
 	};
 
 	dojo.rawXhrPost = dojo.xhrPost = function(/*dojo.__XhrArgs*/ args){
@@ -900,7 +755,7 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 		//		listed for the dojo.__XhrArgs type, the following property is allowed:
 		//	postData:
 		//		String. Send raw data in the body of the POST request.
-		return _d.xhr("POST", args, true); // dojo.Deferred
+		return dojo.xhr("POST", args, true); // dojo.Deferred
 	};
 
 	dojo.rawXhrPut = dojo.xhrPut = function(/*dojo.__XhrArgs*/ args){
@@ -909,13 +764,13 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 		//		listed for the dojo.__XhrArgs type, the following property is allowed:
 		//	putData:
 		//		String. Send raw data in the body of the PUT request.
-		return _d.xhr("PUT", args, true); // dojo.Deferred
+		return dojo.xhr("PUT", args, true); // dojo.Deferred
 	};
 
 	dojo.xhrDelete = function(/*dojo.__XhrArgs*/ args){
 		//	summary:
 		//		Sends an HTTP DELETE request to the server.
-		return _d.xhr("DELETE", args); //dojo.Deferred
+		return dojo.xhr("DELETE", args); //dojo.Deferred
 	};
 
 	/*
@@ -929,9 +784,47 @@ define("dojo/_base/xhr", ["dojo/lib/kernel", "dojo/_base/Deferred", "dojo/_base/
 		throw new Error("dojo.wrapForm not yet implemented");
 	}
 	*/
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-})();
-//>>excludeEnd("webkitMobile");
 
-return dojo.xhr;
+	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._getText = function(url){
+		var result;
+		dojo.xhrGet({url:url, sync:true, load:function(text){
+			result = text;
+		}});
+		return result;
+	};
+
+	// Add aliases for static functions to dojo.xhr since dojo.xhr is what's returned from this module
+	lang.mixin(dojo.xhr, {
+		_xhrObj: dojo._xhrObj,
+		fieldToObject: domForm.fieldToObject,
+		formToObject: domForm.toObject,
+		objectToQuery: ioq.objectToQuery,
+		formToQuery: domForm.toQuery,
+		formToJson: domForm.toJson,
+		queryToObject: ioq.queryToObject,
+		contentHandlers: handlers,
+		_ioSetArgs: dojo._ioSetArgs,
+		_ioCancelAll: dojo._ioCancelAll,
+		_ioNotifyStart: dojo._ioNotifyStart,
+		_ioWatch: dojo._ioWatch,
+		_ioAddQueryToUrl: dojo._ioAddQueryToUrl,
+		_isDocumentOk: dojo._isDocumentOk,
+		_getText: dojo._getText,
+		get: dojo.xhrGet,
+		post: dojo.xhrPost,
+		put: dojo.xhrPut,
+		del: dojo.xhrDelete	// because "delete" is a reserved word
+	});
+
+	return dojo.xhr;
 });
diff --git a/dojo/_firebug/firebug.css b/dojo/_firebug/firebug.css
index 27657ef..2012e06 100644
--- a/dojo/_firebug/firebug.css
+++ b/dojo/_firebug/firebug.css
@@ -208,4 +208,4 @@
 	text-decoration:none;
 	background:transparent url(tab_rgt_over.png) no-repeat right;
 	color:#FFFFFF;
-}
\ No newline at end of file
+}
diff --git a/dojo/_firebug/firebug.js b/dojo/_firebug/firebug.js
index dad6329..0934498 100644
--- a/dojo/_firebug/firebug.js
+++ b/dojo/_firebug/firebug.js
@@ -1,39 +1,7 @@
-define("dojo/_firebug/firebug", ["dojo"], function(dojo) {
-	
-dojo.deprecated = function(/*String*/ behaviour, /*String?*/ extra, /*String?*/ removal){
+define(["../_base/kernel", "require", "../_base/html", "../_base/sniff", "../_base/array", "../_base/lang", "../_base/event", "../_base/unload"], function(dojo, require) {
+	// module:
+	//		dojo/_firebug/firebug
 	// summary:
-	//		Log a debug message to indicate that a behavior has been
-	//		deprecated.
-	// extra: Text to append to the message.
-	// removal:
-	//		Text to indicate when in the future the behavior will be removed.
-	var message = "DEPRECATED: " + behaviour;
-	if(extra){ message += " " + extra; }
-	if(removal){ message += " -- will be removed in version: " + removal; }
-	console.warn(message);
-};
-
-dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
-	// 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:
-	//		The name of a module, or the name of a module file or a specific
-	//		function
-	// extra:
-	//		some additional message for the user
-	// example:
-	//	|	dojo.experimental("dojo.data.Result");
-	// 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);
-};
 
 // FIREBUG LITE
 	// summary: Firebug Lite, the baby brother to Joe Hewitt's Firebug for Mozilla Firefox
@@ -61,9 +29,6 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 	//		|	var djConfig = {isDebug: true, debugHeight:100 }
 
 
-
-(function(){
-
 	var isNewIE = (/Trident/.test(window.navigator.userAgent));
 	if(isNewIE){
 		// Fixing IE's console
@@ -71,12 +36,16 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		var calls = ["log", "info", "debug", "warn", "error"];
 		for(var i=0;i<calls.length;i++){
 			var m = calls[i];
+			if(!console[m] ||console[m]._fake){
+				// IE9 doesn't have console.debug method, a fake one is added later
+				continue;
+			}
 			var n = "_"+calls[i];
 			console[n] = console[m];
 			console[m] = (function(){
 				var type = n;
 				return function(){
-					console[type](Array.prototype.slice.call(arguments).join(" "));
+					console[type](Array.prototype.join.call(arguments, " "));
 				};
 			})();
 		}
@@ -84,19 +53,20 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		// If closed it throws an error
 		try{ console.clear(); }catch(e){}
 	}
-	
+
 	if(
-		!dojo.isFF &&								// Firefox has Firebug
-		!dojo.isChrome &&							// Chrome 3+ has a console
-		!dojo.isSafari &&							// Safari 4 has a console
-		!isNewIE &&									// Has the new IE console
-		!window.firebug &&							// Testing for mozilla firebug lite
-		(typeof console != "undefined" && !console.firebug) && //A console that is not firebug's
-		!dojo.config.useCustomLogger &&				// Allow custom loggers
-		!dojo.isAIR									// isDebug triggers AIRInsector, not Firebug
+		dojo.isFF ||								// Firefox has Firebug
+		dojo.isChrome ||							// Chrome 3+ has a console
+		dojo.isSafari ||							// 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
 	){
-	
-	
+		return;
+	}
+
 	// don't build firebug in iframes
 	try{
 		if(window != window.parent){
@@ -111,33 +81,33 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 	// ***************************************************************************
 	// Placing these variables before the functions that use them to avoid a
 	// shrinksafe bug where variable renaming does not happen correctly otherwise.
-	
+
 	// most of the objects in this script are run anonomously
 	var _firebugDoc = document;
 	var _firebugWin = window;
 	var __consoleAnchorId__ = 0;
-	
+
 	var consoleFrame = null;
 	var consoleBody = null;
 	var consoleObjectInspector = null;
 	var fireBugTabs = null;
 	var commandLine = null;
 	var consoleToolbar = null;
-	
+
 	var frameVisible = false;
 	var messageQueue = [];
 	var groupStack = [];
 	var timeMap = {};
 	var countMap = {};
-	
+
 	var consoleDomInspector = null;
 	var _inspectionMoveConnection;
 	var _inspectionClickConnection;
 	var _inspectionEnabled = false;
 	var _inspectionTimer = null;
 	var _inspectTempNode = document.createElement("div");
-			
-			
+
+
 	var _inspectCurrentNode;
 	var _restoreBorderStyle;
 
@@ -150,32 +120,32 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			//		Sends arguments to console.
 			logFormatted(arguments, "");
 		},
-		
+
 		debug: function(){
 			// summary:
 			//		Sends arguments to console. Missing finctionality to show script line of trace.
 			logFormatted(arguments, "debug");
 		},
-		
+
 		info: function(){
 			// summary:
 			//		Sends arguments to console, highlighted with (I) icon.
 			logFormatted(arguments, "info");
 		},
-		
+
 		warn: function(){
 			// summary:
 			//		Sends warning arguments to console, highlighted with (!) icon and blue style.
 			logFormatted(arguments, "warning");
 		},
-		
+
 		error: function(){
 			// summary:
 			//		Sends error arguments (object) to console, highlighted with (X) icon and yellow style
 			//			NEW: error object now displays in object inspector
 			logFormatted(arguments, "error");
 		},
-		
+
 		assert: function(truth, message){
 			// summary:
 			//		Tests for true. Throws exception if false.
@@ -184,19 +154,19 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 				for(var i = 1; i < arguments.length; ++i){
 					args.push(arguments[i]);
 				}
-				
+
 				logFormatted(args.length ? args : ["Assertion Failure"], "error");
 				throw message ? message : "Assertion Failure";
 			}
 		},
-		
+
 		dir: function(obj){
 			var str = printObject( obj );
 			str = str.replace(/\n/g, "<br />");
 			str = str.replace(/\t/g, "    ");
 			logRow([str], "dir");
 		},
-		
+
 		dirxml: function(node){
 			// summary:
 			//
@@ -204,20 +174,20 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			appendNode(node, html);
 			logRow(html, "dirxml");
 		},
-		
+
 		group: function(){
 			// summary:
 			//		collects log messages into a group, starting with this call and ending with
 			//			groupEnd(). Missing collapse functionality
 			logRow(arguments, "group", pushGroup);
 		},
-		
+
 		groupEnd: function(){
 			// summary:
 			//		Closes group. See above
 			logRow(arguments, "", popGroup);
 		},
-		
+
 		time: function(name){
 			// summary:
 			//		Starts timers assigned to name given in argument. Timer stops and displays on timeEnd(title);
@@ -228,7 +198,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			//	|	console.timeEnd("myFunction");
 			timeMap[name] = new Date().getTime();
 		},
-		
+
 		timeEnd: function(name){
 			// summary:
 			//		See above.
@@ -238,7 +208,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 				delete timeMap[name];
 			}
 		},
-		
+
 		count: function(name){
 			// summary:
 			//		Not supported
@@ -246,7 +216,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			countMap[name]++;
 			logFormatted([name+": "+countMap[name]]);
 		},
-		
+
 		trace: function(_value){
 			var stackAmt = _value || 3;
 			var f = console.trace.caller; //function that called trace
@@ -262,17 +232,17 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 				}else{
 					console.dir({"function":func});
 				}
-				
+
 				f = f.caller;
 			}
 		},
-		
+
 		profile: function(){
 			// summary:
 			//		Not supported
 			this.warn(["profile() not supported."]);
 		},
-		
+
 		profileEnd: function(){ },
 
 		clear: function(){
@@ -291,7 +261,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			//		Opens message console. Do not call this directly
 			toggleConsole(true);
 		},
-		
+
 		close: function(){
 			// summary:
 			//		Closes message console. Do not call this directly
@@ -320,12 +290,12 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 				var node = evt.target;
 				if(node && (_inspectCurrentNode !== node)){
 					var parent = true;
-					
+
 					console._restoreBorder();
 					var html = [];
 					appendNode(node, html);
 					consoleDomInspector.innerHTML = html.join("");
-						
+
 					_inspectCurrentNode = node;
 					_restoreBorderStyle = _inspectCurrentNode.style.border;
 					_inspectCurrentNode.style.border = "#0000FF 1px solid";
@@ -391,7 +361,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			commandLine.focus();
 		}
 	}
-	
+
 	function openWin(x,y,w,h){
 		var win = window.open("","_firebug","status=0,menubar=0,resizable=1,top="+y+",left="+x+",width="+w+",height="+h+",scrollbars=1,addressbar=0");
 		if(!win){
@@ -406,24 +376,24 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 					'<body bgColor="#ccc" style="height:97%;" onresize="opener.onFirebugResize()">\n' +
 					'<div id="fb"></div>' +
 					'</body></html>';
-	
+
 		newDoc.write(HTMLstring);
 		newDoc.close();
 		return win;
 	}
 
 	function createResizeHandler(wn){
-		// summary
+		// summary:
 		//		Creates handle for onresize window. Called from script in popup's body tag (so that it will work with IE).
 		//
-		
+
 		var d = new Date();
 			d.setTime(d.getTime()+(60*24*60*60*1000)); // 60 days
 			d = d.toUTCString();
-			
+
 			var dc = wn.document,
 				getViewport;
-				
+
 			if (wn.innerWidth){
 				getViewport = function(){
 					return{w:wn.innerWidth, h:wn.innerHeight};
@@ -437,36 +407,36 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 					return{w:dc.body.clientWidth, h:dc.body.clientHeight};
 				};
 			}
-			
+
 
 		window.onFirebugResize = function(){
-			
+
 			//resize the height of the console log body
 			layout(getViewport().h);
-			
+
 			clearInterval(wn._firebugWin_resize);
 			wn._firebugWin_resize = setTimeout(function(){
 				var x = wn.screenLeft,
 					y = wn.screenTop,
 					w = wn.outerWidth  || wn.document.body.offsetWidth,
 					h = wn.outerHeight || wn.document.body.offsetHeight;
-				
+
 				document.cookie = "_firebugPosition=" + [x,y,w,h].join(",") + "; expires="+d+"; path=/";
-					 
+
 			 }, 5000); //can't capture window.onMove - long timeout gives better chance of capturing a resize, then the move
-		
+
 		};
 	}
-	
-	
+
+
 	/*****************************************************************************/
-	
-	
+
+
 	function createFrame(){
 		if(consoleFrame){
 			return;
 		}
-		
+		toggleConsole(true);
 		if(dojo.config.popup){
 			var containerHeight = "100%";
 			var cookieMatch = document.cookie.match(/(?:^|; )_firebugPosition=([^;]*)/);
@@ -476,7 +446,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			_firebugDoc = _firebugWin.document;			// global
 
 			dojo.config.debugContainerId = 'fb';
-		
+
 			// connecting popup
 			_firebugWin.console = window.console;
 			_firebugWin.dojo = window.dojo;
@@ -484,9 +454,9 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			_firebugDoc = document;
 			containerHeight = (dojo.config.debugHeight || 300) + "px";
 		}
-		
+
 		var styleElement = _firebugDoc.createElement("link");
-		styleElement.href = dojo.moduleUrl("dojo._firebug", "firebug.css");
+		styleElement.href = require.toUrl("./firebug.css");
 		styleElement.rel = "stylesheet";
 		styleElement.type = "text/css";
 		var styleParent = _firebugDoc.getElementsByTagName("head");
@@ -501,7 +471,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		}else{
 			styleParent.appendChild(styleElement);
 		}
-		
+
 		if(dojo.config.debugContainerId){
 			consoleFrame = _firebugDoc.getElementById(dojo.config.debugContainerId);
 		}
@@ -512,22 +482,22 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		consoleFrame.className += " firebug";
 		consoleFrame.style.height = containerHeight;
 		consoleFrame.style.display = (frameVisible ? "block" : "none");
-		
+
 		var buildLink = function(label, title, method, _class){
 			return '<li class="'+_class+'"><a href="javascript:void(0);" onclick="console.'+ method +'(); return false;" title="'+title+'">'+label+'</a></li>';
 		};
 		consoleFrame.innerHTML =
 			  '<div id="firebugToolbar">'
 			+ '  <ul id="fireBugTabs" class="tabs">'
-			
+
 			+ buildLink("Clear", "Remove All Console Logs", "clear", "")
 			+ buildLink("ReCSS", "Refresh CSS without reloading page", "recss", "")
-			
+
 			+ buildLink("Console", "Show Console Logs", "openConsole", "gap")
 			+ buildLink("DOM", "Show DOM Inspector", "openDomInspector", "")
 			+ buildLink("Object", "Show Object Inspector", "openObjectInspector", "")
 			+ ((dojo.config.popup) ? "" : buildLink("Close", "Close the console", "close", "gap"))
-			
+
 			+ '	</ul>'
 			+ '</div>'
 			+ '<input type="text" id="firebugCommandLine" />'
@@ -542,7 +512,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		addEvent(commandLine, "keydown", onCommandLineKeyDown);
 
 		addEvent(_firebugDoc, dojo.isIE || dojo.isSafari ? "keydown" : "keypress", onKeyDown);
-		
+
 		consoleBody = _firebugDoc.getElementById("firebugLog");
 		consoleObjectInspector = _firebugDoc.getElementById("objectLog");
 		consoleDomInspector = _firebugDoc.getElementById("domInspect");
@@ -555,7 +525,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 
 	function clearFrame(){
 		_firebugDoc = null;
-		
+
 		if(_firebugWin.console){
 			_firebugWin.console.clear();
 		}
@@ -569,14 +539,14 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		groupStack = [];
 		timeMap = {};
 	}
-	
+
 
 	function evalCommandLine(){
 		var text = commandLine.value;
 		commandLine.value = "";
 
 		logRow([">  ", text], "command");
-		
+
 		var value;
 		try{
 			value = eval(text);
@@ -586,13 +556,13 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 
 		console.log(value);
 	}
-	
+
 	function layout(h){
 		var tHeight = 25; //consoleToolbar.offsetHeight; // tab style not ready on load - throws off layout
 		var height = h ?
 			h  - (tHeight + commandLine.offsetHeight +25 + (h*.01)) + "px" :
 			(consoleFrame.offsetHeight - tHeight - commandLine.offsetHeight) + "px";
-		
+
 		consoleBody.style.top = tHeight + "px";
 		consoleBody.style.height = height;
 		consoleObjectInspector.style.height = height;
@@ -600,10 +570,10 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		consoleDomInspector.style.height = height;
 		consoleDomInspector.style.top = tHeight + "px";
 		commandLine.style.bottom = 0;
-		
+
 		dojo.addOnWindowUnload(clearFrame);
 	}
-	
+
 	function logRow(message, className, handler){
 		if(consoleBody){
 			writeMessage(message, className, handler);
@@ -611,11 +581,11 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			messageQueue.push([message, className, handler]);
 		}
 	}
-	
+
 	function flush(){
 		var queue = messageQueue;
 		messageQueue = [];
-		
+
 		for(var i = 0; i < queue.length; ++i){
 			writeMessage(queue[i][0], queue[i][1], queue[i][2]);
 		}
@@ -626,14 +596,14 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			consoleBody.scrollTop + consoleBody.offsetHeight >= consoleBody.scrollHeight;
 
 		handler = handler||writeRow;
-		
+
 		handler(message, className);
-		
+
 		if(isScrolledToBottom){
 			consoleBody.scrollTop = consoleBody.scrollHeight - consoleBody.offsetHeight;
 		}
 	}
-	
+
 	function appendRow(row){
 		var container = groupStack.length ? groupStack[groupStack.length-1] : consoleBody;
 		container.appendChild(row);
@@ -661,12 +631,12 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 	function popGroup(){
 		groupStack.pop();
 	}
-	
+
 	// ***************************************************************************
 
 	function logFormatted(objects, className){
 		var html = [];
-		
+
 		var format = objects[0];
 		var objIndex = 0;
 
@@ -676,7 +646,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		}
 
 		var parts = parseFormat(format);
-		
+
 		for(var i = 0; i < parts.length; ++i){
 			var part = parts[i];
 			if(part && typeof part == "object"){
@@ -685,23 +655,23 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 				appendText(part, html);
 			}
 		}
-		
-		
+
+
 		var ids = [];
 		var obs = [];
 		for(i = objIndex+1; i < objects.length; ++i){
 			appendText(" ", html);
-			
+
 			var object = objects[i];
 			if(object === undefined || object === null ){
 				appendNull(object, html);
 
 			}else if(typeof(object) == "string"){
 				appendText(object, html);
-			
+
 			}else if(object instanceof Date){
 				appendText(object.toString(), html);
-				
+
 			}else if(object.nodeType == 9){
 				appendText("[ XmlDoc ]", html);
 
@@ -713,26 +683,26 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 				// need to save the object, so the arrays line up
 				obs.push(object);
 				var str = '<a id="'+id+'" href="javascript:void(0);">'+getObjectAbbr(object)+'</a>';
-				
+
 				appendLink( str , html);
 			}
 		}
-		
+
 		logRow(html, className);
-		
+
 		// Now that the row is inserted in the DOM, loop through all of the links that were just created
 		for(i=0; i<ids.length; i++){
 			var btn = _firebugDoc.getElementById(ids[i]);
 			if(!btn){ continue; }
-	
+
 			// store the object in the dom btn for reference later
 			// avoid parsing these objects unless necessary
 			btn.obj = obs[i];
-	
+
 			_firebugWin.console._connects.push(dojo.connect(btn, "onclick", function(){
-				
+
 				console.openObjectInspector();
-				
+
 				try{
 					printObject(this.obj);
 				}catch(e){
@@ -797,7 +767,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		// needed for object links - no HTML escaping
 		html.push( objectToString(object) );
 	}
-	
+
 	function appendText(object, html){
 		html.push(escapeHTML(objectToString(object)));
 	}
@@ -822,7 +792,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 	function appendFunction(object, html){
 		html.push('<span class="objectBox-function">', getObjectAbbr(object), '</span>');
 	}
-	
+
 	function appendObject(object, html){
 		try{
 			if(object === undefined){
@@ -846,7 +816,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			/* squelch */
 		}
 	}
-		
+
 	function appendObjectFormatted(object, html){
 		var text = objectToString(object);
 		var reObject = /\[object (.*?)\]/;
@@ -854,7 +824,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		var m = reObject.exec(text);
 		html.push('<span class="objectBox-object">', m ? m[1] : text, '</span>');
 	}
-	
+
 	function appendSelector(object, html){
 		html.push('<span class="objectBox-selector">');
 
@@ -878,7 +848,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			for(var i = 0; i < node.attributes.length; ++i){
 				var attr = node.attributes[i];
 				if(!attr.specified){ continue; }
-				
+
 				html.push(' <span class="nodeName">', attr.nodeName.toLowerCase(),
 					'</span>="<span class="nodeValue">', escapeHTML(attr.nodeValue),
 					'</span>"');
@@ -890,7 +860,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 				for(var child = node.firstChild; child; child = child.nextSibling){
 					appendNode(child, html);
 				}
-					
+
 				html.push('</div><div class="objectBox-element"></<span class="nodeTag">',
 					node.nodeName.toLowerCase(), '></span></div>');
 			}else{
@@ -903,7 +873,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 	}
 
 	// ***************************************************************************
-	
+
 	function addEvent(object, name, handler){
 		if(document.all){
 			object.attachEvent("on"+name, handler);
@@ -911,7 +881,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			object.addEventListener(name, handler, false);
 		}
 	}
-	
+
 	function removeEvent(object, name, handler){
 		if(document.all){
 			object.detachEvent("on"+name, handler);
@@ -919,7 +889,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			object.removeEventListener(name, handler, false);
 		}
 	}
-	
+
 	function cancelEvent(event){
 		if(document.all){
 			event.cancelBubble = true;
@@ -1052,7 +1022,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			d.setMonth(d.getMonth()+1);
 			document.cookie = name + "=" + encodeURIComponent(value) + ((d.toUtcString) ? "; expires=" + d.toUTCString() : "");
 		}
-	};
+	}
 
 	function isArray(it){
 		return it && it instanceof Array || typeof it == "array";
@@ -1067,7 +1037,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		}
 		return cnt;
 	}
-	
+
 	function printObject(o, i, txt, used){
 		// Recursively trace object, indenting to represent depth for display in object inspector
 		var ind = " \t";
@@ -1075,15 +1045,15 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		i = i || ind;
 		used = used || [];
 		var opnCls;
-		
+
 		if(o && o.nodeType == 1){
 			var html = [];
 			appendNode(o, html);
 			return html.join("");
 		}
-		
+
 		var br=",\n", cnt = 0, length = objectLength(o);
-		
+
 		if(o instanceof Date){
 			return i + o.toString() + br;
 		}
@@ -1092,7 +1062,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			cnt++;
 			if(cnt==length){br = "\n";}
 			if(o[nm] === window || o[nm] === document){
-				continue;
+				// do nothing
 			}else if(o[nm] === null){
 				txt += i+nm + " : NULL" + br;
 			}else if(o[nm] && o[nm].nodeType){
@@ -1101,13 +1071,13 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 				}else if(o[nm].nodeType == 3){
 					txt += i+nm + " : [ TextNode "+o[nm].data + " ]" + br;
 				}
-			
+
 			}else if(typeof o[nm] == "object" && (o[nm] instanceof String || o[nm] instanceof Number || o[nm] instanceof Boolean)){
 				txt += i+nm + " : " + o[nm] + "," + br;
-			
+
 			}else if(o[nm] instanceof Date){
 				txt += i+nm + " : " + o[nm].toString() + br;
-				
+
 			}else if(typeof(o[nm]) == "object" && o[nm]){
 				for(var j = 0, seen; seen = used[j]; j++){
 					if(o[nm] === seen){
@@ -1116,12 +1086,12 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 					}
 				}
 				used.push(o[nm]);
-				
+
 				opnCls = (isArray(o[nm]))?["[","]"]:["{","}"];
 				txt += i+nm +" : " + opnCls[0] + "\n";//non-standard break, (no comma)
 				txt += printObject(o[nm], i+ind, "", used);
 				txt += i + opnCls[1] + br;
-			
+
 			}else if(typeof o[nm] == "undefined"){
 				txt += i+nm + " : undefined" + br;
 			}else if(nm == "toString" && typeof o[nm] == "function"){
@@ -1187,16 +1157,16 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			}
 			nm+="}";
 		}
-		
+
 		return nm;
 	}
-		
+
 	//*************************************************************************************
-	
+
 	//window.onerror = onError;
-	
+
 	addEvent(document, dojo.isIE || dojo.isSafari ? "keydown" : "keypress", onKeyDown);
-	
+
 	if(	(document.documentElement.getAttribute("debug") == "true")||
 		(dojo.config.isDebug)
 	){
@@ -1209,9 +1179,5 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		window.onFirebugResize = null;
 		window.console = null;
 	});
-}
-
-})();
 
-return dojo;
 });
diff --git a/dojo/aspect.js b/dojo/aspect.js
new file mode 100644
index 0000000..38be8bd
--- /dev/null
+++ b/dojo/aspect.js
@@ -0,0 +1,207 @@
+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
+		}
+
+	};
+=====*/
+
+	"use strict";
+	var nextId = 0;
+	function advise(dispatcher, type, advice, receiveArguments){
+		var previous = dispatcher[type];
+		var around = type == "around";
+		var signal;
+		if(around){
+			var advised = advice(function(){
+				return previous.advice(this, arguments);
+			});
+			signal = {
+				remove: function(){
+					signal.cancelled = true;
+				},
+				advice: function(target, args){
+					return signal.cancelled ?
+						previous.advice(target, args) : // cancelled, skip to next one
+						advised.apply(target, args);	// called the advised function
+				}
+			};
+		}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;
+						}else{
+							dispatcher[type] = next;
+						}
+						if(next){
+							next.previous = previous;
+						}
+					}
+				},
+				id: nextId++,
+				advice: advice,
+				receiveArguments: receiveArguments
+			};
+		}
+		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;
+				}
+				previous.next = signal;
+				signal.previous = previous;
+			}else if(type == "before"){
+				// add to beginning
+				dispatcher[type] = signal;
+				signal.next = previous;
+				previous.previous = signal;
+			}
+		}else{
+			// around or first one just replaces
+			dispatcher[type] = signal;
+		}
+		return signal;
+	}
+	function aspect(type){
+		return function(target, methodName, advice, receiveArguments){
+			var existing = target[methodName], dispatcher;
+			if(!existing || existing.target != target){
+				// no dispatcher in place
+				target[methodName] = dispatcher = function(){
+					var executionId = nextId;
+					// before advice
+					var args = arguments;
+					var before = dispatcher.before;
+					while(before){
+						args = before.advice.apply(this, args) || args;
+						before = before.next;
+					}
+					// around advice
+					if(dispatcher.around){
+						var results = dispatcher.around.advice(this, args);
+					}
+					// 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);
+						after = after.next;
+					}
+					return results;
+				};
+				if(existing){
+					dispatcher.around = {advice: function(target, args){
+						return existing.apply(target, args);
+					}};
+				}
+				dispatcher.target = target;
+			}
+			var results = advise((dispatcher || existing), type, advice, receiveArguments);
+			advice = null;
+			return results;
+		};
+	}
+	return {
+		before: aspect("before"),
+		around: aspect("around"),
+		after: aspect("after")
+	};
+});
diff --git a/dojo/back.js b/dojo/back.js
index ee0c9e7..f4ca4f7 100644
--- a/dojo/back.js
+++ b/dojo/back.js
@@ -1,25 +1,28 @@
-define("dojo/back", ["dojo"], function(dojo) {
-dojo.getObject("back", true, dojo);
+define(["./_base/kernel", "./_base/lang", "./_base/sniff", "./dom", "./dom-construct", "./_base/window", "require"], function(dojo, lang, sniff, dom, domConstruct, baseWindow, require) {
+	// module:
+	//		dojo/back
+	// summary:
+	//		TODOC
+
+	lang.getObject("back", true, dojo);
 
 /*=====
 dojo.back = {
 	// summary: Browser history management resources
-}
+};
 =====*/
 
-
-(function(){
 	var back = dojo.back,
 
 	// everyone deals with encoding the hash slightly differently
 
-	getHash= back.getHash= function(){
+	getHash = back.getHash = function(){
 		var h = window.location.hash;
 		if(h.charAt(0) == "#"){ h = h.substring(1); }
-		return dojo.isMozilla ? h : decodeURIComponent(h);
+		return sniff("mozilla") ? h : decodeURIComponent(h);
 	},
-	
-	setHash= back.setHash= function(h){
+
+	setHash = back.setHash = function(h){
 		if(!h){ h = ""; }
 		window.location.hash = encodeURIComponent(h);
 		historyCounter = history.length;
@@ -93,23 +96,23 @@ dojo.back = {
 			return segments[1]; //String
 		}
 	}
-	
+
 	function loadIframeHistory(){
 		//summary: private method. Do not call this directly.
-		var url = (dojo.config["dojoIframeHistoryUrl"] || dojo.moduleUrl("dojo", "resources/iframe_history.html")) + "?" + (new Date()).getTime();
+		var url = (dojo.config["dojoIframeHistoryUrl"] || require.toUrl("./resources/iframe_history.html")) + "?" + (new Date()).getTime();
 		moveForward = true;
-        if(historyIframe){
-		    dojo.isWebKit ? 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.");
-        }
+		if(historyIframe){
+			sniff("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.");
+		}
 		return url; //String
 	}
 
 	function checkLocation(){
 		if(!changingUrl){
 			var hsl = historyStack.length;
-			
+
 			var hash = getHash();
 
 			if((hash === initialHash||window.location.href == initialHref)&&(hsl == 1)){
@@ -119,7 +122,7 @@ dojo.back = {
 				handleBackButton();
 				return;
 			}
-			
+
 			// first check to see if we could have gone forward. We always halt on
 			// a no-hash item.
 			if(forwardStack.length > 0){
@@ -128,30 +131,32 @@ dojo.back = {
 					return;
 				}
 			}
-	
+
 			// ok, that didn't work, try someplace back in the history stack
 			if((hsl >= 2)&&(historyStack[hsl-2])){
 				if(historyStack[hsl-2].urlHash === hash){
 					handleBackButton();
-					return;
 				}
 			}
 		}
-	};
-	
+	}
+
 	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.
+		//		   block that lives inside the <body> tag to prevent bugs on IE.
 		// description:
-		// 		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.
-		if(dojo.byId("dj_history")){ return; } // prevent reinit
-		var src = dojo.config["dojoIframeHistoryUrl"] || dojo.moduleUrl("dojo", "resources/iframe_history.html");
+		//		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.
+
+		// 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.");
+						+ "If using xdomain loading or djConfig.debugAtAllCosts, 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>');
 		}
@@ -172,9 +177,9 @@ dojo.back = {
 	//FIXME: Make these doc comments not be awful. At least they're not wrong.
 	//FIXME: Would like to support arbitrary back/forward jumps. Have to rework iframeLoaded among other things.
 	//FIXME: is there a slight race condition in moz using change URL with the timer check and when
-	//       the hash gets set? I think I have seen a back/forward call in quick succession, but not consistent.
+	//		 the hash gets set? I think I have seen a back/forward call in quick succession, but not consistent.
+
 
-	
 	/*=====
 	dojo.__backArgs = function(kwArgs){
 		// back: Function?
@@ -194,6 +199,8 @@ dojo.back = {
 	back.addToHistory = function(/*dojo.__backArgs*/ args){
 		//	summary:
 		//		adds a state object (args) to the history list.
+		//	args: dojo.__backArgs
+		//		The state object that will be added to the history list.
 		//	description:
 		//		To support getting back button notifications, the object
 		//		argument should implement a function called either "back",
@@ -218,7 +225,7 @@ dojo.back = {
 		//		for example). If you want to detect hash changes using semantic fragment IDs, then
 		//		consider using dojo.hash instead (in Dojo 1.4+).
 		//
-	 	//	example:
+		//	example:
 		//		|	dojo.back.addToHistory({
 		//		|		back: function(){ console.log('back pressed'); },
 		//		|		forward: function(){ console.log('forward pressed'); },
@@ -226,7 +233,7 @@ dojo.back = {
 		//		|	});
 
 		//	BROWSER NOTES:
-		//  Safari 1.2:
+		//	Safari 1.2:
 		//	back button "works" fine, however it's not possible to actually
 		//	DETECT that you've moved backwards by inspecting window.location.
 		//	Unless there is some other means of locating.
@@ -268,11 +275,11 @@ dojo.back = {
 			historyIframe = window.frames["dj_history"];
 		}
 		if(!bookmarkAnchor){
-			bookmarkAnchor = dojo.create("a", {style: {display: "none"}}, dojo.body());
+			bookmarkAnchor = domConstruct.create("a", {style: {display: "none"}}, baseWindow.body());
 		}
 		if(args["changeUrl"]){
 			hash = ""+ ((args["changeUrl"]!==true) ? args["changeUrl"] : (new Date()).getTime());
-			
+
 			//If the current hash matches the new one, just replace the history object with
 			//this new one. It doesn't make sense to track different state objects for the same
 			//logical URL. This matches the browser behavior of only putting in one history
@@ -294,8 +301,8 @@ dojo.back = {
 					changingUrl = false;
 				}, 1);
 			bookmarkAnchor.href = hash;
-			
-			if(dojo.isIE){
+
+			if(sniff("ie")){
 				url = loadIframeHistory();
 
 				var oldCB = args["back"]||args["backButton"]||args["handle"];
@@ -310,7 +317,7 @@ dojo.back = {
 					//Use apply to set "this" to args, and to try to avoid memory leaks.
 					oldCB.apply(this, [handleName]);
 				};
-		
+
 				//Set interceptor function in the right place.
 				if(args["back"]){
 					args.back = tcb;
@@ -319,9 +326,9 @@ dojo.back = {
 				}else if(args["handle"]){
 					args.handle = tcb;
 				}
-		
+
 				var oldFW = args["forward"]||args["forwardButton"]||args["handle"];
-		
+
 				//The function takes handleName as a parameter, in case the
 				//callback we are overriding was "handle". In that case,
 				//we will need to pass the handle name to handle.
@@ -344,12 +351,12 @@ dojo.back = {
 					args.handle = tfw;
 				}
 
-			}else if(!dojo.isIE){
+			}else if(!sniff("ie")){
 				// start the timer
 				if(!locationTimer){
 					locationTimer = setInterval(checkLocation, 200);
 				}
-				
+
 			}
 		}else{
 			url = loadIframeHistory();
@@ -375,7 +382,7 @@ dojo.back = {
 			moveForward = false;
 			return;
 		}
-	
+
 		//Check the back stack first, since it is more likely.
 		//Note that only one step back or forward is supported.
 		if(historyStack.length >= 2 && query == getUrlQuery(historyStack[historyStack.length-2].url)){
@@ -384,7 +391,7 @@ dojo.back = {
 			handleForwardButton();
 		}
 	};
- })();
 
-return dojo.back;
+	return dojo.back;
+	
 });
diff --git a/dojo/behavior.js b/dojo/behavior.js
index 3bc022b..8312408 100644
--- a/dojo/behavior.js
+++ b/dojo/behavior.js
@@ -1,4 +1,9 @@
-define("dojo/behavior", ["dojo"], function(dojo) {
+define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/connect", "./query", "./ready"], function(dojo, lang, darray, connect, query, ready) {
+	// module:
+	//		dojo/behavior
+	// summary:
+	//		TODOC
+
 
 dojo.behavior = new function(){
 	// summary:
@@ -40,11 +45,13 @@ dojo.behavior = new function(){
 	// FIXME: need a better test so we don't exclude nightly Safari's!
 	this._behaviors = {};
 	this.add = function(/* Object */behaviorObj){
-		//	summary:
+		// summary:
 		//		Add the specified behavior to the list of behaviors, ignoring existing
 		//		matches.
-		//
-		//	description:
+		// behaviorObj: Object
+		//		The behavior object that will be added to behaviors list. The behaviors
+		//		in the list will be applied the next time apply() is called.
+		// description:
 		//		Add the specified behavior to the list of behaviors which will
 		//		be applied the next time apply() is called. Calls to add() for
 		//		an already existing behavior do not replace the previous rules,
@@ -68,7 +75,7 @@ dojo.behavior = new function(){
 		//
 		//		There are a variety of formats permitted in the behaviorObject
 		//
-		//	example:
+		// example:
 		//		Simple list of properties. "found" is special. "Found" is assumed if
 		//		no property object for a given selector, and property is a function.
 		//
@@ -86,7 +93,7 @@ dojo.behavior = new function(){
 		//	|		}
 		//	|	});
 		//
-		//	example:
+		// example:
 		//		 If property is a string, a dojo.publish will be issued on the channel:
 		//
 		//	|	dojo.behavior.add({
@@ -101,7 +108,7 @@ dojo.behavior = new function(){
 		//	|		// provided a newly matched node is found.
 		//	|	});
 		//
-		//	example:
+		// example:
 		//		Scoping can be accomplished by passing an object as a property to
 		//		a connection handle (on*):
 		//
@@ -113,7 +120,7 @@ dojo.behavior = new function(){
 		//	|			}
 		//	|	});
 		//
-		//	example:
+		// example:
 		//		Bahaviors match on CSS3 Selectors, powered by dojo.query. Example selectors:
 		//
 		//	|	dojo.behavior.add({
@@ -147,7 +154,6 @@ dojo.behavior = new function(){
 		//	|	});
 		//
 
-		var tmpObj = {};
 		forIn(behaviorObj, this, function(behavior, name){
 			var tBehavior = arrIn(this._behaviors, name);
 			if(typeof tBehavior["id"] != "number"){
@@ -155,7 +161,7 @@ dojo.behavior = new function(){
 			}
 			var cversion = [];
 			tBehavior.push(cversion);
-			if((dojo.isString(behavior))||(dojo.isFunction(behavior))){
+			if((lang.isString(behavior))||(lang.isFunction(behavior))){
 				behavior = { found: behavior };
 			}
 			forIn(behavior, function(rule, ruleName){
@@ -165,19 +171,19 @@ dojo.behavior = new function(){
 	};
 
 	var _applyToNode = function(node, action, ruleSetName){
-		if(dojo.isString(action)){
+		if(lang.isString(action)){
 			if(ruleSetName == "found"){
-				dojo.publish(action, [ node ]);
+				connect.publish(action, [ node ]);
 			}else{
-				dojo.connect(node, ruleSetName, function(){
-					dojo.publish(action, arguments);
+				connect.connect(node, ruleSetName, function(){
+					connect.publish(action, arguments);
 				});
 			}
-		}else if(dojo.isFunction(action)){
+		}else if(lang.isFunction(action)){
 			if(ruleSetName == "found"){
 				action(node);
 			}else{
-				dojo.connect(node, ruleSetName, action);
+				connect.connect(node, ruleSetName, action);
 			}
 		}
 	};
@@ -206,7 +212,7 @@ dojo.behavior = new function(){
 		//		the DOM.
 		//
 		forIn(this._behaviors, function(tBehavior, id){
-			dojo.query(id).forEach(
+			query(id).forEach(
 				function(elem){
 					var runFrom = 0;
 					var bid = "_dj_behavior_"+tBehavior.id;
@@ -220,8 +226,8 @@ dojo.behavior = new function(){
 
 					for(var x=runFrom, tver; tver = tBehavior[x]; x++){
 						forIn(tver, function(ruleSet, ruleSetName){
-							if(dojo.isArray(ruleSet)){
-								dojo.forEach(ruleSet, function(action){
+							if(lang.isArray(ruleSet)){
+								darray.forEach(ruleSet, function(action){
 									_applyToNode(elem, action, ruleSetName);
 								});
 							}
@@ -236,7 +242,7 @@ dojo.behavior = new function(){
 	};
 };
 
-dojo.addOnLoad(dojo.behavior, "apply");
+ready(dojo.behavior, "apply"); // FIXME: should this use a priority? before/after parser priority?
 
 return dojo.behavior;
 });
diff --git a/dojo/cache.js b/dojo/cache.js
index 6a9fd4f..3f839f5 100644
--- a/dojo/cache.js
+++ b/dojo/cache.js
@@ -1,116 +1,9 @@
-define("dojo/cache", ["dojo"], function(dojo){
-
-/*=====
-dojo.cache = {
+define(["./_base/kernel", "./text"], function(dojo, text){
+	// module:
+	//		dojo/cache
 	// summary:
-	// 		A way to cache string content that is fetchable via `dojo.moduleUrl`.
-};
-=====*/
-
-	var cache = {};
-	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:
-		// 		module and url are used to call `dojo.moduleUrl()` to generate a module URL.
-		// 		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, 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});
-
-		//Module could be a string, or an object that has a toString() method
-		//that will return a useful path. If it is an object, then the "url" argument
-		//will actually be the value argument.
-		if(typeof module == "string"){
-			var pathObj = dojo.moduleUrl(module, url);
-		}else{
-			pathObj = module;
-			value = url;
-		}
-		var key = pathObj.toString();
-
-		var val = value;
-		if(value != undefined && !dojo.isString(value)){
-			val = ("value" in value ? value.value : undefined);
-		}
-
-		var sanitize = value && value.sanitize ? true : false;
-
-		if(typeof val == "string"){
-			//We have a string, set cache value
-			val = cache[key] = sanitize ? dojo.cache._sanitize(val) : val;
-		}else if(val === null){
-			//Remove cached value
-			delete cache[key];
-		}else{
-			//Allow cache values to be empty strings. If key property does
-			//not exist, fetch it.
-			if(!(key in cache)){
-				val = dojo._getText(key);
-				cache[key] = sanitize ? dojo.cache._sanitize(val) : val;
-			}
-			val = cache[key];
-		}
-		return val; //String
-	};
+	//		The module defines dojo.cache by loading dojo/text.
 
-	dojo.cache._sanitize = function(/*String*/val){
-		// summary:
-		//		Strips <?xml ...?> declarations so that external SVG and XML
-		// 		documents can be added to a document without worry. Also, if the string
-		//		is an HTML document, only the part inside the body tag is returned.
-		// description:
-		// 		Copied from dijit._Templated._sanitizeTemplateString.
-		if(val){
-			val = val.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, "");
-			var matches = val.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
-			if(matches){
-				val = matches[1];
-			}
-		}else{
-			val = "";
-		}
-		return val; //String
-	};
+	//dojo.cache is defined in dojo/text
 	return dojo.cache;
 });
diff --git a/dojo/cldr/monetary.js b/dojo/cldr/monetary.js
index ffb6cb7..d3bf17a 100644
--- a/dojo/cldr/monetary.js
+++ b/dojo/cldr/monetary.js
@@ -1,4 +1,9 @@
-define("dojo/cldr/monetary", ["dojo"], function(dojo) {
+define(["../main"], function(dojo) {
+	// module:
+	//		dojo/cldr/monetary
+	// summary:
+	//		TODOC
+
 dojo.getObject("cldr.monetary", true, dojo);
 
 dojo.cldr.monetary.getData = function(/*String*/code){
diff --git a/dojo/cldr/nls/ar/hebrew.js b/dojo/cldr/nls/ar/hebrew.js
index 156edb5..e82dd6c 100644
--- a/dojo/cldr/nls/ar/hebrew.js
+++ b/dojo/cldr/nls/ar/hebrew.js
@@ -1,11 +1,11 @@
 define(
 //begin v1.x content
 {
-	"dateFormat-medium": "dd‏/MM‏/yyyy",
+	"dateFormat-medium": "dd/MM/yyyy",
 	"dateFormatItem-MMMEd": "E d MMM",
-	"dateFormatItem-yMEd": "EEE، d/‏M/‏yyyy",
+	"dateFormatItem-yMEd": "EEE، d/M/yyyy",
 	"timeFormat-full": "zzzz h:mm:ss a",
-	"dateFormatItem-Md": "d/‏M",
+	"dateFormatItem-Md": "d/M",
 	"months-standAlone-wide": [
 		"تشري",
 		"مرحشوان",
@@ -56,7 +56,7 @@ define(
 	],
 	"timeFormat-medium": "h:mm:ss a",
 	"dateFormat-long": "d MMMM، y",
-	"dateFormat-short": "d‏/M‏/yyyy",
+	"dateFormat-short": "d/M/yyyy",
 	"dateFormatItem-yMMMEd": "EEE، d MMMM y",
 	"months-format-wide": [
 		"تشري",
@@ -73,7 +73,7 @@ define(
 		"آب",
 		"أيلول"
 	],
-	"dateFormatItem-yM": "M‏/yyyy",
+	"dateFormatItem-yM": "M/yyyy",
 	"timeFormat-short": "h:mm a",
 	"months-format-abbr": [
 		"تشري",
diff --git a/dojo/cldr/nls/ar/islamic-civil.js b/dojo/cldr/nls/ar/islamic-civil.js
deleted file mode 100644
index 3eb14e5..0000000
--- a/dojo/cldr/nls/ar/islamic-civil.js
+++ /dev/null
@@ -1,225 +0,0 @@
-define(
-//begin v1.x content
-({
-	"dateFormatItem-yM": "M‏/yyyy",
-	"dateFormatItem-yQ": "yyyy Q",
-	"dayPeriods-format-wide-pm": "م",
-	"eraNames": [
-		"ه"
-	],
-	"dateFormatItem-MMMEd": "E d MMM",
-	"days-standAlone-wide": [
-		"الأحد",
-		"الإثنين",
-		"الثلاثاء",
-		"الأربعاء",
-		"الخميس",
-		"الجمعة",
-		"السبت"
-	],
-	"patternChars": "GanjkHmsSEDFwWxhKzAeugXZvcL",
-	"months-standAlone-narrow": [
-		"م",
-		"ص",
-		"ر",
-		"ر",
-		"ج",
-		"ج",
-		"ر",
-		"ش",
-		"ر",
-		"ش",
-		"ذ",
-		"ذ"
-	],
-	"dayPeriods-format-wide-am": "ص",
-	"dayPeriods-am-format-wide": "ص",
-	"quarters-standAlone-abbr": [
-		"الربع الأول",
-		"الربع الثاني",
-		"الربع الثالث",
-		"الربع الرابع"
-	],
-	"timeFormat-full": "zzzz h:mm:ss a",
-	"dayPeriods-pm-format-wide": "م",
-	"dayPeriods-format-wide": [
-		"ص",
-		"م"
-	],
-	"months-standAlone-abbr": [
-		"محرم",
-		"صفر",
-		"ربيع الأول",
-		"ربيع الآخر",
-		"جمادى الأولى",
-		"جمادى الآخرة",
-		"رجب",
-		"شعبان",
-		"رمضان",
-		"شوال",
-		"ذو القعدة",
-		"ذو الحجة"
-	],
-	"dateFormatItem-yMMM": "MMM y",
-	"days-standAlone-narrow": [
-		"ح",
-		"ن",
-		"ث",
-		"ر",
-		"خ",
-		"ج",
-		"س"
-	],
-	"eraAbbr": [
-		"ه"
-	],
-	"dateFormat-long": "d MMMM، y",
-	"timeFormat-medium": "h:mm:ss a",
-	"dateFormat-medium": "dd‏/MM‏/yyyy",
-	"dayPeriods-format-narrow": [
-		"ص",
-		"م"
-	],
-	"quarters-standAlone-wide": [
-		"الربع الأول",
-		"الربع الثاني",
-		"الربع الثالث",
-		"الربع الرابع"
-	],
-	"dateFormatItem-yMMMM": "MMMM y",
-	"quarters-standAlone-narrow": [
-		"١",
-		"٢",
-		"٣",
-		"٤"
-	],
-	"months-standAlone-wide": [
-		"محرم",
-		"صفر",
-		"ربيع الأول",
-		"ربيع الآخر",
-		"جمادى الأولى",
-		"جمادى الآخرة",
-		"رجب",
-		"شعبان",
-		"رمضان",
-		"شوال",
-		"ذو القعدة",
-		"ذو الحجة"
-	],
-	"dateFormatItem-MMMMEd": "E d MMMM",
-	"dateFormatItem-MMMd": "d MMM",
-	"quarters-format-narrow": [
-		"١",
-		"٢",
-		"٣",
-		"٤"
-	],
-	"timeFormat-long": "z h:mm:ss a",
-	"months-format-abbr": [
-		"محرم",
-		"صفر",
-		"ربيع الأول",
-		"ربيع الآخر",
-		"جمادى الأولى",
-		"جمادى الآخرة",
-		"رجب",
-		"شعبان",
-		"رمضان",
-		"شوال",
-		"ذو القعدة",
-		"ذو الحجة"
-	],
-	"timeFormat-short": "h:mm a",
-	"dateFormatItem-MMMMd": "d MMMM",
-	"quarters-format-abbr": [
-		"الربع الأول",
-		"الربع الثاني",
-		"الربع الثالث",
-		"الربع الرابع"
-	],
-	"days-format-abbr": [
-		"أحد",
-		"إثنين",
-		"ثلاثاء",
-		"أربعاء",
-		"خميس",
-		"جمعة",
-		"سبت"
-	],
-	"days-format-narrow": [
-		"ح",
-		"ن",
-		"ث",
-		"ر",
-		"خ",
-		"ج",
-		"س"
-	],
-	"months-format-narrow": [
-		"م",
-		"ص",
-		"ر",
-		"ر",
-		"ج",
-		"ج",
-		"ر",
-		"ش",
-		"ر",
-		"ش",
-		"ذ",
-		"ذ"
-	],
-	"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": [
-		"محرم",
-		"صفر",
-		"ربيع الأول",
-		"ربيع الآخر",
-		"جمادى الأولى",
-		"جمادى الآخرة",
-		"رجب",
-		"شعبان",
-		"رمضان",
-		"شوال",
-		"ذو القعدة",
-		"ذو الحجة"
-	],
-	"dayPeriods-format-abbr": [
-		"ص",
-		"م"
-	],
-	"quarters-format-wide": [
-		"الربع الأول",
-		"الربع الثاني",
-		"الربع الثالث",
-		"الربع الرابع"
-	],
-	"days-format-wide": [
-		"الأحد",
-		"الإثنين",
-		"الثلاثاء",
-		"الأربعاء",
-		"الخميس",
-		"الجمعة",
-		"السبت"
-	],
-	"eraNarrow": [
-		"ه"
-	]
-})
-//end v1.x content
-);
diff --git a/dojo/cldr/nls/ar/islamic.js b/dojo/cldr/nls/ar/islamic.js
index 4a67656..c1b55f3 100644
--- a/dojo/cldr/nls/ar/islamic.js
+++ b/dojo/cldr/nls/ar/islamic.js
@@ -1,9 +1,9 @@
 define(
 //begin v1.x content
 {
-	"dateFormat-medium": "dd‏/MM‏/yyyy",
+	"dateFormat-medium": "dd/MM/yyyy",
 	"dateFormatItem-MMMEd": "E d MMM",
-	"dateFormatItem-yMEd": "EEE، d/‏M/‏yyyy",
+	"dateFormatItem-yMEd": "EEE، d/M/yyyy",
 	"eraNarrow": [
 		"هـ"
 	],
@@ -22,7 +22,7 @@ define(
 		"ذ"
 	],
 	"timeFormat-full": "zzzz h:mm:ss a",
-	"dateFormatItem-Md": "d/‏M",
+	"dateFormatItem-Md": "d/M",
 	"months-standAlone-narrow": [
 		"م",
 		"ص",
@@ -87,7 +87,7 @@ define(
 	],
 	"timeFormat-medium": "h:mm:ss a",
 	"dateFormat-long": "d MMMM، y",
-	"dateFormat-short": "d‏/M‏/yyyy",
+	"dateFormat-short": "d/M/yyyy",
 	"dateFormatItem-yMMMEd": "EEE، d MMMM y",
 	"months-format-wide": [
 		"محرم",
@@ -103,7 +103,7 @@ define(
 		"ذو القعدة",
 		"ذو الحجة"
 	],
-	"dateFormatItem-yM": "M‏/yyyy",
+	"dateFormatItem-yM": "M/yyyy",
 	"timeFormat-short": "h:mm a",
 	"months-format-abbr": [
 		"محرم",
diff --git a/dojo/cldr/supplemental.js b/dojo/cldr/supplemental.js
index 5b7ca3b..83088ae 100644
--- a/dojo/cldr/supplemental.js
+++ b/dojo/cldr/supplemental.js
@@ -1,5 +1,10 @@
-define("dojo/cldr/supplemental", ["dojo", "dojo/i18n"], function(dojo) {
-dojo.getObject("cldr.supplemental", true, dojo);
+define(["../_base/kernel", "../_base/lang", "../i18n"], function(dojo, lang) {
+	// module:
+	//		dojo/cldr/supplemental
+	// summary:
+	//		TODOC
+
+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
diff --git a/dojo/colors.js b/dojo/colors.js
index 14d5283..4111e69 100644
--- a/dojo/colors.js
+++ b/dojo/colors.js
@@ -1,15 +1,21 @@
-define("dojo/colors", ["dojo"], function(dojo) {
-dojo.getObject("colors", true, dojo);
+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);
 
 //TODO: this module appears to break naming conventions
 
 /*=====
-dojo.colors = {
-	// summary: Color utilities
-}
+	lang.mixin(dojo, {
+		colors: {
+			// summary: Color utilities, extending Base dojo.Color
+		}
+	});
 =====*/
 
-(function(){
 	// this is a standard conversion prescribed by the CSS3 Color Module
 	var hue2rgb = function(m1, m2, h){
 		if(h < 0){ ++h; }
@@ -20,8 +26,8 @@ dojo.colors = {
 		if(3 * h < 2){ return m1 + (m2 - m1) * (2 / 3 - h) * 6; }
 		return m1;
 	};
-	
-	dojo.colorFromRgb = function(/*String*/ color, /*dojo.Color?*/ obj){
+	// Override base Color.fromRgb with the impl in this module
+	dojo.colorFromRgb = Color.fromRgb = function(/*String*/ color, /*dojo.Color?*/ obj){
 		// summary:
 		//		get rgb(a) array from css-style color declarations
 		// description:
@@ -34,13 +40,13 @@ dojo.colors = {
 				var r = c[0];
 				if(r.charAt(r.length - 1) == "%"){
 					// 3 rgb percentage values
-					a = dojo.map(c, function(x){
+					a = ArrayUtil.map(c, function(x){
 						return parseFloat(x) * 2.56;
 					});
 					if(l == 4){ a[3] = c[3]; }
-					return dojo.colorFromArray(a, obj);	// dojo.Color
+					return Color.fromArray(a, obj); // dojo.Color
 				}
-				return dojo.colorFromArray(c, obj);	// dojo.Color
+				return Color.fromArray(c, obj); // dojo.Color
 			}
 			if((t == "hsl" && l == 3) || (t == "hsla" && l == 4)){
 				// normalize hsl values
@@ -58,12 +64,12 @@ dojo.colors = {
 					1
 				];
 				if(l == 4){ a[3] = c[3]; }
-				return dojo.colorFromArray(a, obj);	// dojo.Color
+				return Color.fromArray(a, obj); // dojo.Color
 			}
 		}
 		return null;	// dojo.Color
 	};
-	
+
 	var confine = function(c, low, high){
 		// summary:
 		//		sanitize a color component by making sure it is a number,
@@ -71,8 +77,8 @@ dojo.colors = {
 		c = Number(c);
 		return isNaN(c) ? high : c < low ? low : c > high ? high : c;	// Number
 	};
-	
-	dojo.Color.prototype.sanitize = function(){
+
+	Color.prototype.sanitize = function(){
 		// summary: makes sure that the object has correct attributes
 		var t = this;
 		t.r = Math.round(confine(t.r, 0, 255));
@@ -81,149 +87,146 @@ dojo.colors = {
 		t.a = confine(t.a, 0, 1);
 		return this;	// dojo.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
+	};
 
-dojo.colors.makeGrey = function(/*Number*/ g, /*Number?*/ a){
-	// summary: creates a greyscale color with an optional alpha
-	return dojo.colorFromArray([g, g, g, a]);
-};
-
-// mixin all CSS3 named colors not already in _base, along with SVG 1.0 variant spellings
-dojo.mixin(dojo.Color.named, {
-	aliceblue:	[240,248,255],
-	antiquewhite:	[250,235,215],
-	aquamarine:	[127,255,212],
-	azure:	[240,255,255],
-	beige:	[245,245,220],
-	bisque:	[255,228,196],
-	blanchedalmond:	[255,235,205],
-	blueviolet:	[138,43,226],
-	brown:	[165,42,42],
-	burlywood:	[222,184,135],
-	cadetblue:	[95,158,160],
-	chartreuse:	[127,255,0],
-	chocolate:	[210,105,30],
-	coral:	[255,127,80],
-	cornflowerblue:	[100,149,237],
-	cornsilk:	[255,248,220],
-	crimson:	[220,20,60],
-	cyan:	[0,255,255],
-	darkblue:	[0,0,139],
-	darkcyan:	[0,139,139],
-	darkgoldenrod:	[184,134,11],
-	darkgray:	[169,169,169],
-	darkgreen:	[0,100,0],
-	darkgrey:	[169,169,169],
-	darkkhaki:	[189,183,107],
-	darkmagenta:	[139,0,139],
-	darkolivegreen:	[85,107,47],
-	darkorange:	[255,140,0],
-	darkorchid:	[153,50,204],
-	darkred:	[139,0,0],
-	darksalmon:	[233,150,122],
-	darkseagreen:	[143,188,143],
-	darkslateblue:	[72,61,139],
-	darkslategray:	[47,79,79],
-	darkslategrey:	[47,79,79],
-	darkturquoise:	[0,206,209],
-	darkviolet:	[148,0,211],
-	deeppink:	[255,20,147],
-	deepskyblue:	[0,191,255],
-	dimgray:	[105,105,105],
-	dimgrey:	[105,105,105],
-	dodgerblue:	[30,144,255],
-	firebrick:	[178,34,34],
-	floralwhite:	[255,250,240],
-	forestgreen:	[34,139,34],
-	gainsboro:	[220,220,220],
-	ghostwhite:	[248,248,255],
-	gold:	[255,215,0],
-	goldenrod:	[218,165,32],
-	greenyellow:	[173,255,47],
-	grey:	[128,128,128],
-	honeydew:	[240,255,240],
-	hotpink:	[255,105,180],
-	indianred:	[205,92,92],
-	indigo:	[75,0,130],
-	ivory:	[255,255,240],
-	khaki:	[240,230,140],
-	lavender:	[230,230,250],
-	lavenderblush:	[255,240,245],
-	lawngreen:	[124,252,0],
-	lemonchiffon:	[255,250,205],
-	lightblue:	[173,216,230],
-	lightcoral:	[240,128,128],
-	lightcyan:	[224,255,255],
-	lightgoldenrodyellow:	[250,250,210],
-	lightgray:	[211,211,211],
-	lightgreen:	[144,238,144],
-	lightgrey:	[211,211,211],
-	lightpink:	[255,182,193],
-	lightsalmon:	[255,160,122],
-	lightseagreen:	[32,178,170],
-	lightskyblue:	[135,206,250],
-	lightslategray:	[119,136,153],
-	lightslategrey:	[119,136,153],
-	lightsteelblue:	[176,196,222],
-	lightyellow:	[255,255,224],
-	limegreen:	[50,205,50],
-	linen:	[250,240,230],
-	magenta:	[255,0,255],
-	mediumaquamarine:	[102,205,170],
-	mediumblue:	[0,0,205],
-	mediumorchid:	[186,85,211],
-	mediumpurple:	[147,112,219],
-	mediumseagreen:	[60,179,113],
-	mediumslateblue:	[123,104,238],
-	mediumspringgreen:	[0,250,154],
-	mediumturquoise:	[72,209,204],
-	mediumvioletred:	[199,21,133],
-	midnightblue:	[25,25,112],
-	mintcream:	[245,255,250],
-	mistyrose:	[255,228,225],
-	moccasin:	[255,228,181],
-	navajowhite:	[255,222,173],
-	oldlace:	[253,245,230],
-	olivedrab:	[107,142,35],
-	orange:	[255,165,0],
-	orangered:	[255,69,0],
-	orchid:	[218,112,214],
-	palegoldenrod:	[238,232,170],
-	palegreen:	[152,251,152],
-	paleturquoise:	[175,238,238],
-	palevioletred:	[219,112,147],
-	papayawhip:	[255,239,213],
-	peachpuff:	[255,218,185],
-	peru:	[205,133,63],
-	pink:	[255,192,203],
-	plum:	[221,160,221],
-	powderblue:	[176,224,230],
-	rosybrown:	[188,143,143],
-	royalblue:	[65,105,225],
-	saddlebrown:	[139,69,19],
-	salmon:	[250,128,114],
-	sandybrown:	[244,164,96],
-	seagreen:	[46,139,87],
-	seashell:	[255,245,238],
-	sienna:	[160,82,45],
-	skyblue:	[135,206,235],
-	slateblue:	[106,90,205],
-	slategray:	[112,128,144],
-	slategrey:	[112,128,144],
-	snow:	[255,250,250],
-	springgreen:	[0,255,127],
-	steelblue:	[70,130,180],
-	tan:	[210,180,140],
-	thistle:	[216,191,216],
-	tomato:	[255,99,71],
-	transparent: [0, 0, 0, 0],
-	turquoise:	[64,224,208],
-	violet:	[238,130,238],
-	wheat:	[245,222,179],
-	whitesmoke:	[245,245,245],
-	yellowgreen:	[154,205,50]
-});
+	// mixin all CSS3 named colors not already in _base, along with SVG 1.0 variant spellings
+	lang.mixin(Color.named, {
+		"aliceblue":	[240,248,255],
+		"antiquewhite": [250,235,215],
+		"aquamarine":	[127,255,212],
+		"azure":	[240,255,255],
+		"beige":	[245,245,220],
+		"bisque":	[255,228,196],
+		"blanchedalmond":	[255,235,205],
+		"blueviolet":	[138,43,226],
+		"brown":	[165,42,42],
+		"burlywood":	[222,184,135],
+		"cadetblue":	[95,158,160],
+		"chartreuse":	[127,255,0],
+		"chocolate":	[210,105,30],
+		"coral":	[255,127,80],
+		"cornflowerblue":	[100,149,237],
+		"cornsilk": [255,248,220],
+		"crimson":	[220,20,60],
+		"cyan": [0,255,255],
+		"darkblue": [0,0,139],
+		"darkcyan": [0,139,139],
+		"darkgoldenrod":	[184,134,11],
+		"darkgray": [169,169,169],
+		"darkgreen":	[0,100,0],
+		"darkgrey": [169,169,169],
+		"darkkhaki":	[189,183,107],
+		"darkmagenta":	[139,0,139],
+		"darkolivegreen":	[85,107,47],
+		"darkorange":	[255,140,0],
+		"darkorchid":	[153,50,204],
+		"darkred":	[139,0,0],
+		"darksalmon":	[233,150,122],
+		"darkseagreen": [143,188,143],
+		"darkslateblue":	[72,61,139],
+		"darkslategray":	[47,79,79],
+		"darkslategrey":	[47,79,79],
+		"darkturquoise":	[0,206,209],
+		"darkviolet":	[148,0,211],
+		"deeppink": [255,20,147],
+		"deepskyblue":	[0,191,255],
+		"dimgray":	[105,105,105],
+		"dimgrey":	[105,105,105],
+		"dodgerblue":	[30,144,255],
+		"firebrick":	[178,34,34],
+		"floralwhite":	[255,250,240],
+		"forestgreen":	[34,139,34],
+		"gainsboro":	[220,220,220],
+		"ghostwhite":	[248,248,255],
+		"gold": [255,215,0],
+		"goldenrod":	[218,165,32],
+		"greenyellow":	[173,255,47],
+		"grey": [128,128,128],
+		"honeydew": [240,255,240],
+		"hotpink":	[255,105,180],
+		"indianred":	[205,92,92],
+		"indigo":	[75,0,130],
+		"ivory":	[255,255,240],
+		"khaki":	[240,230,140],
+		"lavender": [230,230,250],
+		"lavenderblush":	[255,240,245],
+		"lawngreen":	[124,252,0],
+		"lemonchiffon": [255,250,205],
+		"lightblue":	[173,216,230],
+		"lightcoral":	[240,128,128],
+		"lightcyan":	[224,255,255],
+		"lightgoldenrodyellow": [250,250,210],
+		"lightgray":	[211,211,211],
+		"lightgreen":	[144,238,144],
+		"lightgrey":	[211,211,211],
+		"lightpink":	[255,182,193],
+		"lightsalmon":	[255,160,122],
+		"lightseagreen":	[32,178,170],
+		"lightskyblue": [135,206,250],
+		"lightslategray":	[119,136,153],
+		"lightslategrey":	[119,136,153],
+		"lightsteelblue":	[176,196,222],
+		"lightyellow":	[255,255,224],
+		"limegreen":	[50,205,50],
+		"linen":	[250,240,230],
+		"magenta":	[255,0,255],
+		"mediumaquamarine": [102,205,170],
+		"mediumblue":	[0,0,205],
+		"mediumorchid": [186,85,211],
+		"mediumpurple": [147,112,219],
+		"mediumseagreen":	[60,179,113],
+		"mediumslateblue":	[123,104,238],
+		"mediumspringgreen":	[0,250,154],
+		"mediumturquoise":	[72,209,204],
+		"mediumvioletred":	[199,21,133],
+		"midnightblue": [25,25,112],
+		"mintcream":	[245,255,250],
+		"mistyrose":	[255,228,225],
+		"moccasin": [255,228,181],
+		"navajowhite":	[255,222,173],
+		"oldlace":	[253,245,230],
+		"olivedrab":	[107,142,35],
+		"orange":	[255,165,0],
+		"orangered":	[255,69,0],
+		"orchid":	[218,112,214],
+		"palegoldenrod":	[238,232,170],
+		"palegreen":	[152,251,152],
+		"paleturquoise":	[175,238,238],
+		"palevioletred":	[219,112,147],
+		"papayawhip":	[255,239,213],
+		"peachpuff":	[255,218,185],
+		"peru": [205,133,63],
+		"pink": [255,192,203],
+		"plum": [221,160,221],
+		"powderblue":	[176,224,230],
+		"rosybrown":	[188,143,143],
+		"royalblue":	[65,105,225],
+		"saddlebrown":	[139,69,19],
+		"salmon":	[250,128,114],
+		"sandybrown":	[244,164,96],
+		"seagreen": [46,139,87],
+		"seashell": [255,245,238],
+		"sienna":	[160,82,45],
+		"skyblue":	[135,206,235],
+		"slateblue":	[106,90,205],
+		"slategray":	[112,128,144],
+		"slategrey":	[112,128,144],
+		"snow": [255,250,250],
+		"springgreen":	[0,255,127],
+		"steelblue":	[70,130,180],
+		"tan":	[210,180,140],
+		"thistle":	[216,191,216],
+		"tomato":	[255,99,71],
+		"turquoise":	[64,224,208],
+		"violet":	[238,130,238],
+		"wheat":	[245,222,179],
+		"whitesmoke":	[245,245,245],
+		"yellowgreen":	[154,205,50]
+	});
 
-return dojo.colors;
+	return Color;
 });
diff --git a/dojo/cookie.js b/dojo/cookie.js
index 0c30f2c..ac1e0f2 100644
--- a/dojo/cookie.js
+++ b/dojo/cookie.js
@@ -1,4 +1,9 @@
-define("dojo/cookie", ["dojo", "dojo/regexp"], function(dojo) {
+define(["./_base/kernel", "./regexp"], function(dojo, regexp) {
+	// module:
+	//		dojo/cookie
+	// summary:
+	//		TODOC
+
 
 /*=====
 dojo.__cookieProps = function(){
@@ -6,7 +11,7 @@ dojo.__cookieProps = function(){
 	//		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. << FIXME: 0 seems to disappear right away? FF3.
+	//		If expires is omitted or is 0, the cookie will expire when the browser closes.
 	//	path: String?
 	//		The path to use for the cookie.
 	//	domain: String?
@@ -45,10 +50,10 @@ dojo.cookie = function(/*String*/name, /*String?*/value, /*dojo.__cookieProps?*/
 	//	example:
 	//		delete a cookie:
 	//	|	dojo.cookie("configObj", null, {expires: -1});
-	var c = document.cookie;
+	var c = document.cookie, ret;
 	if(arguments.length == 1){
-		var matches = c.match(new RegExp("(?:^|; )" + dojo.regexp.escapeString(name) + "=([^;]*)"));
-		return matches ? decodeURIComponent(matches[1]) : undefined; // String or undefined
+		var matches = c.match(new RegExp("(?:^|; )" + regexp.escapeString(name) + "=([^;]*)"));
+		ret = matches ? decodeURIComponent(matches[1]) : undefined; 
 	}else{
 		props = props || {};
 // FIXME: expires=0 seems to disappear right away, not on close? (FF3)  Change docs?
@@ -69,6 +74,7 @@ dojo.cookie = function(/*String*/name, /*String?*/value, /*dojo.__cookieProps?*/
 		}
 		document.cookie = updatedCookie;
 	}
+	return ret; // String|undefined
 };
 
 dojo.cookie.isSupported = function(){
diff --git a/dojo/currency.js b/dojo/currency.js
index eefbeab..30306ac 100644
--- a/dojo/currency.js
+++ b/dojo/currency.js
@@ -1,5 +1,10 @@
-define("dojo/currency", ["dojo", "dojo/number", "dojo/i18n", "i18n!dojo/cldr/nls/currency", "dojo/cldr/monetary"], function(dojo) {
-dojo.getObject("currency", true, dojo);
+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
+	// summary:
+	//		TODOC
+
+lang.getObject("currency", true, dojo);
 
 /*=====
 dojo.currency = {
@@ -20,20 +25,20 @@ dojo.currency._mixInDefaults = function(options){
 	options.type = "currency";
 
 	// Get locale-dependent currency data, like the symbol
-	var bundle = dojo.i18n.getLocalization("dojo.cldr", "currency", options.locale) || {};
+	var bundle = i18n.getLocalization("dojo.cldr", "currency", options.locale) || {};
 
 	// Mixin locale-independent currency data, like # of places
 	var iso = options.currency;
-	var data = dojo.cldr.monetary.getData(iso);
+	var data = cldrMonetary.getData(iso);
 
-	dojo.forEach(["displayName","symbol","group","decimal"], function(prop){
+	darray.forEach(["displayName","symbol","group","decimal"], function(prop){
 		data[prop] = bundle[iso+"_"+prop];
 	});
 
 	data.fractional = [true, false];
 
 	// Mixin with provided options
-	return dojo.mixin(data, options);
+	return lang.mixin(data, options);
 };
 
 /*=====
@@ -68,7 +73,7 @@ dojo.currency.format = function(/*Number*/value, /*dojo.currency.__FormatOptions
 // value:
 //		the number to be formatted.
 
-	return dojo.number.format(value, dojo.currency._mixInDefaults(options));
+	return dnumber.format(value, dojo.currency._mixInDefaults(options));
 };
 
 dojo.currency.regexp = function(/*dojo.number.__RegexpOptions?*/options){
@@ -79,7 +84,7 @@ dojo.currency.regexp = function(/*dojo.number.__RegexpOptions?*/options){
 // 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 dojo.number.regexp(dojo.currency._mixInDefaults(options)); // String
+	return dnumber.regexp(dojo.currency._mixInDefaults(options)); // String
 };
 
 /*=====
@@ -120,7 +125,7 @@ dojo.currency.parse = function(/*String*/expression, /*dojo.currency.__ParseOpti
 	//
 	// expression: A string representation of a currency value
 
-	return dojo.number.parse(expression, dojo.currency._mixInDefaults(options));
+	return dnumber.parse(expression, dojo.currency._mixInDefaults(options));
 };
 
 return dojo.currency;
diff --git a/dojo/data/ItemFileReadStore.js b/dojo/data/ItemFileReadStore.js
index 3454a35..3c5df8f 100644
--- a/dojo/data/ItemFileReadStore.js
+++ b/dojo/data/ItemFileReadStore.js
@@ -1,6 +1,13 @@
-define("dojo/data/ItemFileReadStore", ["dojo", "dojo/data/util/filter", "dojo/data/util/simpleFetch", "dojo/date/stamp"], function(dojo) {
+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
 
-dojo.declare("dojo.data.ItemFileReadStore", null,{
+
+var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 	//	summary:
 	//		The ItemFileReadStore implements the dojo.data.api.Read API and reads
 	//		data from JSON files that have contents in this format --
@@ -31,7 +38,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 		//			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;
@@ -48,7 +55,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 			this._datatypeMap['Date'] = {
 											type: Date,
 											deserialize: function(value){
-												return dojo.date.stamp.fromISOString(value);
+												return dateStamp.fromISOString(value);
 											}
 										};
 		}
@@ -73,7 +80,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 			this.failOk = keywordParameters.failOk?true:false;
 		}
 	},
-	
+
 	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
@@ -83,7 +90,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 	data: null,	// define this so that the parser can populate it
 
 	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,
@@ -94,7 +101,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 	//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: false,
 
@@ -175,7 +182,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 		//		See dojo.data.api.Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
-			regexp = dojo.data.util.filter.patternToRegExp(value, false);
+			regexp = filterUtil.patternToRegExp(value, false);
 		}
 		return this._containsValue(item, attribute, value, regexp); //boolean.
 	},
@@ -200,8 +207,8 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 		//	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 dojo.some(this.getValues(item, attribute), function(possibleValue){
-			if(possibleValue !== null && !dojo.isObject(possibleValue) && regexp){
+		return array.some(this.getValues(item, attribute), function(possibleValue){
+			if(possibleValue !== null && !lang.isObject(possibleValue) && regexp){
 				if(possibleValue.toString().match(regexp)){
 					return true; // Boolean
 				}
@@ -277,7 +284,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 				for(key in requestArgs.query){
 					value = requestArgs.query[key];
 					if(typeof value === "string"){
-						regexpList[key] = dojo.data.util.filter.patternToRegExp(value, ignoreCase);
+						regexpList[key] = filterUtil.patternToRegExp(value, ignoreCase);
 					}else if(value instanceof RegExp){
 						regexpList[key] = value;
 					}
@@ -326,7 +333,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 			//compatibility.  People use _jsonFileUrl (even though officially
 			//private.
 			if(this._jsonFileUrl !== this._ccUrl){
-				dojo.deprecated("dojo.data.ItemFileReadStore: ",
+				kernel.deprecated("dojo.data.ItemFileReadStore: ",
 					"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;
@@ -356,13 +363,13 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 							preventCache: this.urlPreventCache,
 							failOk: this.failOk
 						};
-					var getHandler = dojo.xhrGet(getArgs);
+					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){
@@ -478,11 +485,11 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 		//
 		// 	returns: array
 		//		Array of items in store item format.
-		
+
 		// First, we define a couple little utility functions...
 		var addingArrays = false,
 		    self = this;
-		
+
 		function valueIsAnItem(/* anything */ aValue){
 			// summary:
 			//		Given any sort of value that could be in the raw json data,
@@ -497,26 +504,23 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 			// 	|	true == valueIsAnItem({name:'Kermit', color:'green'});
 			// 	|	true == valueIsAnItem({iggy:'pop'});
 			// 	|	true == valueIsAnItem({foo:42});
-			var isItem = (
-				(aValue !== null) &&
+			return (aValue !== null) &&
 				(typeof aValue === "object") &&
-				(!dojo.isArray(aValue) || addingArrays) &&
-				(!dojo.isFunction(aValue)) &&
-				(aValue.constructor == Object || dojo.isArray(aValue)) &&
+				(!lang.isArray(aValue) || addingArrays) &&
+				(!lang.isFunction(aValue)) &&
+				(aValue.constructor == Object || lang.isArray(aValue)) &&
 				(typeof aValue._reference === "undefined") &&
 				(typeof aValue._type === "undefined") &&
 				(typeof aValue._value === "undefined") &&
-				self.hierarchical
-			);
-			return isItem;
+				self.hierarchical;
 		}
-		
+
 		function addItemAndSubItemsToArrayOfAllItems(/* Item */ anItem){
 			self._arrayOfAllItems.push(anItem);
 			for(var attribute in anItem){
 				var valueForAttribute = anItem[attribute];
 				if(valueForAttribute){
-					if(dojo.isArray(valueForAttribute)){
+					if(lang.isArray(valueForAttribute)){
 						var valueArray = valueForAttribute;
 						for(var k = 0; k < valueArray.length; ++k){
 							var singleValue = valueArray[k];
@@ -547,7 +551,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 
 		for(i = 0; i < this._arrayOfTopLevelItems.length; ++i){
 			item = this._arrayOfTopLevelItems[i];
-			if(dojo.isArray(item)){
+			if(lang.isArray(item)){
 				addingArrays = true;
 			}
 			addItemAndSubItemsToArrayOfAllItems(item);
@@ -571,7 +575,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 				if(key !== this._rootItemPropName){
 					var value = item[key];
 					if(value !== null){
-						if(!dojo.isArray(value)){
+						if(!lang.isArray(value)){
 							item[key] = [value];
 						}
 					}else{
@@ -657,9 +661,9 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 							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("dojo.data.ItemFileReadStore: in the typeMap constructor arg, no object class was specified for the datatype '" + type + "'");
-							}else if(dojo.isFunction(mappingObj)){
+							}else if(lang.isFunction(mappingObj)){
 								arrayOfValues[j] = new mappingObj(value._value);
-							}else if(dojo.isFunction(mappingObj.deserialize)){
+							}else if(lang.isFunction(mappingObj.deserialize)){
 								arrayOfValues[j] = mappingObj.deserialize(value._value);
 							}else{
 								throw new Error("dojo.data.ItemFileReadStore: Value provided in typeMap was neither a constructor, nor a an object with a deserialize function");
@@ -667,7 +671,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 						}
 						if(value._reference){
 							var referenceDescription = value._reference; // example: {name:'Miss Piggy'}
-							if(!dojo.isObject(referenceDescription)){
+							if(!lang.isObject(referenceDescription)){
 								// example: 'Miss Piggy'
 								// from an item like: { name:['Kermit'], friends:[{_reference:'Miss Piggy'}]}
 								arrayOfValues[j] = this._getItemByIdentity(referenceDescription);
@@ -718,7 +722,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 		 //		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.
 	},
 
@@ -753,7 +757,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 			//compatibility.  People use _jsonFileUrl (even though officially
 			//private.
 			if(this._jsonFileUrl !== this._ccUrl){
-				dojo.deprecated("dojo.data.ItemFileReadStore: ",
+				kernel.deprecated("dojo.data.ItemFileReadStore: ",
 					"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;
@@ -762,7 +766,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 				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;
@@ -781,9 +785,9 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 							preventCache: this.urlPreventCache,
 							failOk: this.failOk
 					};
-					var getHandler = dojo.xhrGet(getArgs);
+					var getHandler = xhr.get(getArgs);
 					getHandler.addCallback(function(data){
-						var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+						var scope = keywordArgs.scope?keywordArgs.scope:window.global;
 						try{
 							self._getItemsFromLoadedData(data);
 							self._loadFinished = true;
@@ -803,7 +807,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 					getHandler.addErrback(function(error){
 						self._loadInProgress = false;
 						if(keywordArgs.onError){
-							var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+							var scope = keywordArgs.scope?keywordArgs.scope:window.global;
 							keywordArgs.onError.call(scope, error);
 						}
 					});
@@ -816,7 +820,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 				self._loadFinished = true;
 				item = self._getItemByIdentity(keywordArgs.identity);
 				if(keywordArgs.onItem){
-					scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+					scope = keywordArgs.scope?keywordArgs.scope:window.global;
 					keywordArgs.onItem.call(scope, item);
 				}
 			}
@@ -824,7 +828,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 			// Already loaded.  We can just look it up and call back.
 			item = this._getItemByIdentity(keywordArgs.identity);
 			if(keywordArgs.onItem){
-				scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+				scope = keywordArgs.scope?keywordArgs.scope:window.global;
 				keywordArgs.onItem.call(scope, item);
 			}
 		}
@@ -834,9 +838,12 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 		//	summary:
 		//		Internal function to look an item up by its identity map.
 		var item = null;
-		if(this._itemsByIdentity &&
-		   Object.hasOwnProperty.call(this._itemsByIdentity, identity)){
-			item = this._itemsByIdentity[identity];
+		if(this._itemsByIdentity){
+			// If this map is defined, we need to just try to get it.  If it fails
+			// the item does not exist.
+			if(Object.hasOwnProperty.call(this._itemsByIdentity, identity)){
+				item = this._itemsByIdentity[identity];
+			}
 		}else if (Object.hasOwnProperty.call(this._arrayOfAllItems, identity)){
 			item = this._arrayOfAllItems[identity];
 		}
@@ -849,7 +856,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 	getIdentityAttributes: function(/* 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
@@ -861,7 +868,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 			return [identifier]; // Array
 		}
 	},
-	
+
 	_forceLoad: function(){
 		//	summary:
 		//		Internal function to force a load of the store if it hasn't occurred yet.  This is required
@@ -874,7 +881,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 		//compatibility.  People use _jsonFileUrl (even though officially
 		//private.
 		if(this._jsonFileUrl !== this._ccUrl){
-			dojo.deprecated("dojo.data.ItemFileReadStore: ",
+			kernel.deprecated("dojo.data.ItemFileReadStore: ",
 				"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;
@@ -898,7 +905,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 					failOk: this.failOk,
 					sync: true
 				};
-			var getHandler = dojo.xhrGet(getArgs);
+			var getHandler = xhr.get(getArgs);
 			getHandler.addCallback(function(data){
 				try{
 					//Check to be sure there wasn't another load going on concurrently
@@ -932,7 +939,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 	}
 });
 //Mix in the simple fetch implementation to this class.
-dojo.extend(dojo.data.ItemFileReadStore,dojo.data.util.simpleFetch);
+lang.extend(ItemFileReadStore,simpleFetch);
 
-return dojo.data.ItemFileReadStore;
+return ItemFileReadStore;
 });
diff --git a/dojo/data/ItemFileWriteStore.js b/dojo/data/ItemFileWriteStore.js
index 12ac71b..2bfadcf 100644
--- a/dojo/data/ItemFileWriteStore.js
+++ b/dojo/data/ItemFileWriteStore.js
@@ -1,6 +1,13 @@
-define("dojo/data/ItemFileWriteStore", ["dojo", "dojo/data/ItemFileReadStore"], function(dojo) {
-
-dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
+define(["../_base/lang", "../_base/declare", "../_base/array", "../_base/json", "../_base/window", 
+	"./ItemFileReadStore", "../date/stamp"
+], function(lang, declare, arrayUtil, jsonUtil, window, ItemFileReadStore, dateStamp) {
+	// module:
+	//		dojo/data/ItemFileWriteStore
+	// summary:
+	//		TODOC
+
+/*===== var ItemFileReadStore = dojo.data.ItemFileReadStore; =====*/
+return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 	constructor: function(/* object */ keywordParameters){
 		//	keywordParameters: {typeMap: object)
 		//		The structure of the typeMap object is as follows:
@@ -23,7 +30,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		// 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:{},
@@ -33,7 +40,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 
 		if(!this._datatypeMap['Date'].serialize){
 			this._datatypeMap['Date'].serialize = function(obj){
-				return dojo.date.stamp.toISOString(obj, {zulu:true});
+				return dateStamp.toISOString(obj, {zulu:true});
 			};
 		}
 		//Disable only if explicitly set to false.
@@ -54,12 +61,11 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 	},
 
 	_getIdentifierAttribute: function(){
-		var identifierAttribute = this.getFeatures()['dojo.data.api.Identity'];
 		// this._assert((identifierAttribute === Number) || (dojo.isString(identifierAttribute)));
-		return identifierAttribute;
+		return this.getFeatures()['dojo.data.api.Identity'];
 	},
-	
-	
+
+
 /* dojo.data.api.Write */
 
 	newItem: function(/* Object? */ keywordArgs, /* Object? */ parentInfo){
@@ -85,11 +91,11 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 			if(typeof newIdentity === "undefined"){
 				throw new Error("newItem() was not passed an identity for the new item");
 			}
-			if(dojo.isArray(newIdentity)){
+			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.
@@ -98,7 +104,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		}
 		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;
@@ -112,7 +118,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 
 		//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 = {
@@ -144,9 +150,9 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 			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){
@@ -165,7 +171,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 				throw new Error("encountered bug in ItemFileWriteStore.newItem");
 			}
 			var value = keywordArgs[key];
-			if(!dojo.isArray(value)){
+			if(!lang.isArray(value)){
 				value = [value];
 			}
 			newItem[key] = value;
@@ -181,16 +187,16 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		this.onNew(newItem, pInfo); // dojo.data.api.Notification call
 		return newItem; // item
 	},
-	
+
 	_removeArrayElement: function(/* Array */ array, /* anything */ element){
-		var index = dojo.indexOf(array, 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);
@@ -213,15 +219,15 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 
 			//Backup the map, we'll have to restore it potentially, in a revert.
 			if(item[this._reverseRefMap]){
-				item["backup_" + this._reverseRefMap] = dojo.clone(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.
-			dojo.forEach(attributes, function(attribute){
-				dojo.forEach(this.getValues(item, attribute), function(value){
+			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]){
@@ -249,7 +255,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 					if(containingItem){
 						for(var attribute in references[itemId]){
 							var oldValues = this.getValues(containingItem, attribute) || [];
-							var newValues = dojo.filter(oldValues, function(possibleItem){
+							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.
@@ -270,7 +276,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 			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);
@@ -283,23 +289,23 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		// 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(dojo.isString(attribute));
+		this._assert(lang.isString(attribute));
 		this._assert(typeof newValueOrValues !== "undefined");
 
 		// Make sure the user isn't trying to change the item's identity
@@ -325,7 +331,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 				if((key === this._storeRefPropName) || (key === this._itemNumPropName) || (key === this._rootItemPropName)){
 					copyOfItemState[key] = item[key];
 				}else if(key === this._reverseRefMap){
-					copyOfItemState[key] = dojo.clone(item[key]);
+					copyOfItemState[key] = lang.clone(item[key]);
 				}else{
 					copyOfItemState[key] = item[key].slice(0, item[key].length);
 				}
@@ -333,12 +339,12 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 			// 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(dojo.isArray(newValueOrValues) && newValueOrValues.length === 0){
-			
+
+		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.
@@ -347,7 +353,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 
 			if(this.referenceIntegrity && oldValueOrValues){
 				var oldValues = oldValueOrValues;
-				if(!dojo.isArray(oldValues)){
+				if(!lang.isArray(oldValues)){
 					oldValues = [oldValues];
 				}
 				for(var i = 0; i < oldValues.length; i++){
@@ -359,10 +365,9 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 			}
 		}else{
 			var newValueArray;
-			if(dojo.isArray(newValueOrValues)){
-				var newValues = newValueOrValues;
+			if(lang.isArray(newValueOrValues)){
 				// Unfortunately, it's not safe to just do this:
-				//    newValueArray = newValues;
+				//    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*
@@ -378,7 +383,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 			if(this.referenceIntegrity){
 				if(oldValueOrValues){
 					var oldValues = oldValueOrValues;
-					if(!dojo.isArray(oldValues)){
+					if(!lang.isArray(oldValues)){
 						oldValues = [oldValues];
 					}
 					//Use an associative map to determine what was added/removed from the list.
@@ -387,13 +392,13 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 					//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 = {};
-					dojo.forEach(oldValues, function(possibleItem){
+					arrayUtil.forEach(oldValues, function(possibleItem){
 						if(this.isItem(possibleItem)){
 							var id = this.getIdentity(possibleItem);
 							map[id.toString()] = true;
 						}
 					}, this);
-					dojo.forEach(newValueArray, function(possibleItem){
+					arrayUtil.forEach(newValueArray, function(possibleItem){
 						if(this.isItem(possibleItem)){
 							var id = this.getIdentity(possibleItem);
 							if(map[id.toString()]){
@@ -434,7 +439,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		return success; // boolean
 	},
 
-	_addReferenceToMap: function(/*item*/ refItem, /*item*/ parentItem, /*string*/ attribute){
+	_addReferenceToMap: function(/* item */ refItem, /* item */ parentItem, /* string */ attribute){
 		//	summary:
 		//		Method to add an reference map entry for an item and attribute.
 		//	description:
@@ -445,7 +450,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		//		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];
 
@@ -459,7 +464,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		itemRef[attribute] = true;
 	},
 
-	_removeReferenceFromMap: function(/* item */ refItem, /* item */ parentItem, /*strin*/ attribute){
+	_removeReferenceFromMap: function(/* item */ refItem, /* item */ parentItem, /* string */ attribute){
 		//	summary:
 		//		Method to remove an reference map entry for an item and attribute.
 		//	description:
@@ -500,11 +505,11 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		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: " + dojo.toJson(item[this._reverseRefMap]));
+				console.log("Item: [" + this.getIdentity(item) + "] is referenced by: " + jsonUtil.toJson(item[this._reverseRefMap]));
 			}
 		}
 	},
-	
+
 	_getValueOrValues: function(/* item */ item, /* attribute-name-string */ attribute){
 		var valueOrValues = undefined;
 		if(this.hasAttribute(item, attribute)){
@@ -517,24 +522,21 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		}
 		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;
+			return {_reference: this.getIdentity(value)};
 		}else{
 			if(typeof value === "object"){
 				for(var type in this._datatypeMap){
 					var typeMap = this._datatypeMap[type];
-					if(dojo.isObject(typeMap) && !dojo.isFunction(typeMap)){
+					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 + "]");
@@ -550,14 +552,14 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 			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;
@@ -572,15 +574,14 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 				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);
+						var valueArray = this.getValues(item, key);
 						if(valueArray.length == 1){
-							serializableItem[attribute] = this._flatten(valueArray[0]);
+							serializableItem[key] = this._flatten(valueArray[0]);
 						}else{
 							var serializableArray = [];
 							for(var j = 0; j < valueArray.length; ++j){
 								serializableArray.push(this._flatten(valueArray[j]));
-								serializableItem[attribute] = serializableArray;
+								serializableItem[key] = serializableArray;
 							}
 						}
 					}
@@ -589,7 +590,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 			}
 		}
 		var prettyPrint = true;
-		return dojo.toJson(serializableStructure, prettyPrint);
+		return jsonUtil.toJson(serializableStructure, prettyPrint);
 	},
 
 	_isEmpty: function(something){
@@ -598,27 +599,27 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		//	something:
 		//		The array or object to examine.
 		var empty = true;
-		if(dojo.isObject(something)){
+		if(lang.isObject(something)){
 			var i;
 			for(i in something){
 				empty = false;
 				break;
 			}
-		}else if(dojo.isArray(something)){
+		}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 = {
@@ -629,18 +630,18 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 
 			self._saveInProgress = false; // must come after this._pending is cleared, but before any callbacks
 			if(keywordArgs && keywordArgs.onComplete){
-				var scope = keywordArgs.scope || dojo.global;
+				var scope = keywordArgs.scope || window.global;
 				keywordArgs.onComplete.call(scope);
 			}
 		};
 		var saveFailedCallback = function(err){
 			self._saveInProgress = false;
 			if(keywordArgs && keywordArgs.onError){
-				var scope = keywordArgs.scope || dojo.global;
+				var scope = keywordArgs.scope || window.global;
 				keywordArgs.onError.call(scope, err);
 			}
 		};
-		
+
 		if(this._saveEverything){
 			var newFileContentString = this._getNewFileContentString();
 			this._saveEverything(saveCompleteCallback, saveFailedCallback, newFileContentString);
@@ -655,7 +656,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 			saveCompleteCallback();
 		}
 	},
-	
+
 	revert: function(){
 		// summary: See dojo.data.api.Write.revert()
 		this._assert(!this._saveInProgress);
@@ -670,14 +671,14 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 			}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){
+			for(var key in modifiedItem){
 				delete modifiedItem[key];
 			}
-			dojo.mixin(modifiedItem, copyOfItemState);
+			lang.mixin(modifiedItem, copyOfItemState);
 		}
 		var deletedItem;
 		for(identity in this._pending._deletedItems){
@@ -703,7 +704,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		for(identity in this._pending._deletedItems){
 			deletedItem = this._pending._deletedItems[identity];
 			if(deletedItem["backupRefs_" + this._reverseRefMap]){
-				dojo.forEach(deletedItem["backupRefs_" + this._reverseRefMap], function(reference){
+				arrayUtil.forEach(deletedItem["backupRefs_" + this._reverseRefMap], function(reference){
 					var refItem;
 					if(this._itemsByIdentity){
 						refItem = this._itemsByIdentity[reference.id];
@@ -737,7 +738,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		};
 		return true; // boolean
 	},
-	
+
 	isDirty: function(/* item? */ item){
 		// summary: See dojo.data.api.Write.isDirty()
 		if(item){
@@ -749,12 +750,9 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		}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) ||
+			return !this._isEmpty(this._pending._newItems) ||
 				!this._isEmpty(this._pending._modifiedItems) ||
-				!this._isEmpty(this._pending._deletedItems)){
-				return true;
-			}
-			return false; // boolean
+				!this._isEmpty(this._pending._deletedItems); // boolean
 		}
 	},
 
@@ -762,24 +760,24 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 
 	onSet: function(/* item */ item,
 					/*attribute-name-string*/ attribute,
-					/*object | array*/ oldValue,
-					/*object | array*/ newValue){
+					/*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.
 	},
@@ -804,5 +802,4 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 	}
 });
 
-return dojo.data.ItemFileWriteStore;
 });
diff --git a/dojo/data/ObjectStore.js b/dojo/data/ObjectStore.js
index f675769..20be74c 100644
--- a/dojo/data/ObjectStore.js
+++ b/dojo/data/ObjectStore.js
@@ -1,7 +1,13 @@
-define("dojo/data/ObjectStore", ["dojo", "dojo/regexp"], function(dojo) {
+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
 
 
-dojo.declare("dojo.data.ObjectStore", null,{
+return declare("dojo.data.ObjectStore", [Evented],{
 		objectStore: null,
 		constructor: function(options){
 			// summary:
@@ -11,7 +17,7 @@ dojo.declare("dojo.data.ObjectStore", null,{
 			//		The configuration information to pass into the data store.
 			//	options.objectStore:
 			//		The object store to use as the source provider for this data store
-			dojo.mixin(this, options);
+			lang.mixin(this, options);
 		},
 		labelProperty: "label",
 
@@ -25,7 +31,7 @@ dojo.declare("dojo.data.ObjectStore", null,{
 			//		property to look up value for
 			//	defaultValue:
 			//		the default value
-			
+
 			return typeof item.get === "function" ? item.get(property) :
 				property in item ?
 					item[property] : defaultValue;
@@ -33,7 +39,7 @@ dojo.declare("dojo.data.ObjectStore", null,{
 		getValues: function(item, property){
 			// summary:
 			//		Gets the value of an item's 'property' and returns
-			//		it.	If this value is an array it is just returned,
+			//		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 */
@@ -76,7 +82,7 @@ dojo.declare("dojo.data.ObjectStore", null,{
 			//	item: /* object */
 			//	attribute: /* string */
 			//	value: /* anything */
-			return dojo.indexOf(this.getValues(item,attribute),value) > -1;
+			return array.indexOf(this.getValues(item,attribute),value) > -1;
 		},
 
 
@@ -88,7 +94,7 @@ dojo.declare("dojo.data.ObjectStore", null,{
 			//	attribute: /* string */
 
 			// 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);
 		},
 
@@ -103,23 +109,23 @@ dojo.declare("dojo.data.ObjectStore", null,{
 
 		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).
+			//		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
+			//				// do something with the item
 			//			}
 			//		});
 
 			var item;
 			if(typeof args.item.load === "function"){
-				dojo.when(args.item.load(), function(result){
+				Deferred.when(args.item.load(), function(result){
 					item = result; // in synchronous mode this can allow loadItem to return the value
 					var func = result instanceof Error ? args.onError : args.onItem;
 					if(func){
@@ -140,18 +146,18 @@ dojo.declare("dojo.data.ObjectStore", null,{
 			// summary:
 			//		See dojo.data.api.Read.fetch
 			//
-			
-			args = args || {};
+
+			args = lang.delegate(args, args && args.queryOptions);
 			var self = this;
 			var scope = args.scope || self;
 			var query = args.query;
 			if(typeof query == "object"){ // can be null, but that is ignore by for-in
-				query = dojo.delegate(query); // don't modify the original
+				query = lang.delegate(query); // don't modify the original
 				for(var i in query){
 					// find any strings and convert them to regular expressions for wildcard support
 					var required = query[i];
 					if(typeof required == "string"){
-						query[i] = RegExp("^" + dojo.regexp.escapeString(required, "*?").replace(/\*/g, '.*').replace(/\?/g, '.') + "$", args.queryOptions && args.queryOptions.ignoreCase ? "mi" : "m");
+						query[i] = RegExp("^" + regexp.escapeString(required, "*?").replace(/\*/g, '.*').replace(/\?/g, '.') + "$", args.ignoreCase ? "mi" : "m");
 						query[i].toString = (function(original){
 							return function(){
 								return original;
@@ -160,10 +166,10 @@ dojo.declare("dojo.data.ObjectStore", null,{
 					}
 				}
 			}
-			
+
 			var results = this.objectStore.query(query, args);
-			dojo.when(results.total, function(totalCount){
-				dojo.when(results, function(results){
+			Deferred.when(results.total, function(totalCount){
+				Deferred.when(results, function(results){
 					if(args.onBegin){
 						args.onBegin.call(scope, totalCount || results.length, args);
 					}
@@ -189,12 +195,36 @@ dojo.declare("dojo.data.ObjectStore", null,{
 					results.cancel();
 				}
 			};
+			if(results.observe){
+				if(this.observing){
+					// if we were previously observing, cancel the last time to avoid multiple notifications. Just the best we can do for the impedance mismatch between APIs
+					this.observing.cancel();
+				}
+				this.observing = results.observe(function(object, removedFrom, insertedInto){
+					if(array.indexOf(self._dirtyObjects, object) == -1){
+						if(removedFrom == -1){
+							self.onNew(object);
+						}
+						else if(insertedInto == -1){
+							self.onDelete(object);
+						}
+						else{
+							for(var i in object){
+								if(i != self.objectStore.idProperty){
+									self.onSet(object, i, null, object[i]);
+								}
+							}
+						}
+					}
+				}, true);
+			}
+			this.onFetch(results);
 			args.store = this;
 			return args;
 		},
 		getFeatures: function(){
 			// summary:
-			// 		return the store feature set
+			//		return the store feature set
 
 			return {
 				"dojo.data.api.Read": !!this.objectStore.get,
@@ -223,7 +253,7 @@ dojo.declare("dojo.data.ObjectStore", null,{
 
 
 		getIdentity: function(item){
-			return item.getId ? item.getId() : item[this.objectStore.idProperty || "id"];
+			return this.objectStore.getIdentity ? this.objectStore.getIdentity(item) : item[this.objectStore.idProperty || "id"];
 		},
 
 		getIdentityAttributes: function(item){
@@ -238,7 +268,7 @@ dojo.declare("dojo.data.ObjectStore", null,{
 			// summary:
 			//		fetch an item by its identity, by looking in our index of what we have loaded
 			var item;
-			dojo.when(this.objectStore.get(args.identity),
+			Deferred.when(this.objectStore.get(args.identity),
 				function(result){
 					item = result;
 					args.onItem.call(args.scope, result);
@@ -249,14 +279,16 @@ dojo.declare("dojo.data.ObjectStore", null,{
 			);
 			return item;
 		},
-		
+
 		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.
+			
+			// TODOC: parentInfo
 			if(parentInfo){
 				// get the previous value or any empty array
 				var values = this.getValue(parentInfo.parent,parentInfo.attribute,[]);
@@ -297,8 +329,7 @@ dojo.declare("dojo.data.ObjectStore", null,{
 			//	sets 'attribute' on 'item' to 'value' value
 			//	must be an array.
 
-
-			if(!dojo.isArray(values)){
+			if(!lang.isArray(values)){
 				throw new Error("setValues expects to be passed an Array object as its value");
 			}
 			this.setValue(item,attribute,values);
@@ -313,9 +344,9 @@ dojo.declare("dojo.data.ObjectStore", null,{
 			delete item[attribute];
 			this.onSet(item,attribute,old,undefined);
 		},
-		
+
 		_dirtyObjects: [],
-		
+
 		changing: function(object,_deleting){
 			// summary:
 			//		adds an object to the list of dirty objects.  This object
@@ -346,38 +377,37 @@ dojo.declare("dojo.data.ObjectStore", null,{
 			}
 			this._dirtyObjects.push({object: !_deleting && object, old: old, save: !this._saveNotNeeded});
 		},
-		
+
 		save: function(kwArgs){
 			// summary:
 			//		Saves the dirty data using object store provider. See dojo.data.api.Write for API.
 			//
 			//	kwArgs.global:
 			//		This will cause the save to commit the dirty data for all
-			// 		ObjectStores as a single transaction.
+			//		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.
 
+			// TODOC: kwArgs pseudo
 			kwArgs = kwArgs || {};
 			var result, actions = [];
-			var alreadyRecorded = {};
 			var savingObjects = [];
-			var self;
+			var self = this;
 			var dirtyObjects = this._dirtyObjects;
 			var left = dirtyObjects.length;// this is how many changes are remaining to be received from the server
 			try{
-				dojo.connect(kwArgs,"onError",function(){
+				connect.connect(kwArgs,"onError",function(){
 					if(kwArgs.revertOnError !== false){
 						var postCommitDirtyObjects = dirtyObjects;
 						dirtyObjects = savingObjects;
-						var numDirty = 0; // make sure this does't do anything if it is called again
-						jr.revert(); // revert if there was an error
+						self.revert(); // revert if there was an error
 						self._dirtyObjects = postCommitDirtyObjects;
 					}
 					else{
-						self._dirtyObjects = dirtyObject.concat(savingObjects);
+						self._dirtyObjects = dirtyObjects.concat(savingObjects);
 					}
 				});
 				if(this.objectStore.transaction){
@@ -391,24 +421,24 @@ dojo.declare("dojo.data.ObjectStore", null,{
 					if(object){
 						result = this.objectStore.put(object, {overwrite: !!old});
 					}
-					else{
+					else if(typeof old != "undefined"){
 						result = this.objectStore.remove(this.getIdentity(old));
 					}
 					savingObjects.push(dirty);
 					dirtyObjects.splice(i--,1);
-					dojo.when(result, function(value){
+					Deferred.when(result, function(value){
 						if(!(--left)){
 							if(kwArgs.onComplete){
 								kwArgs.onComplete.call(kwArgs.scope, actions);
 							}
 						}
 					},function(value){
-						
+
 						// on an error we want to revert, first we want to separate any changes that were made since the commit
 						left = -1; // first make sure that success isn't called
 						kwArgs.onError.call(kwArgs.scope, value);
 					});
-					
+
 				}
 				if(transaction){
 					transaction.commit();
@@ -416,12 +446,10 @@ dojo.declare("dojo.data.ObjectStore", null,{
 			}catch(e){
 				kwArgs.onError.call(kwArgs.scope, value);
 			}
-			
-			
 		},
 
 		revert: function(kwArgs){
-			// summary
+			// summary:
 			//		returns any modified data to its original state prior to a save();
 			//
 			var dirtyObjects = this._dirtyObjects;
@@ -454,11 +482,10 @@ dojo.declare("dojo.data.ObjectStore", null,{
 				delete (object || old).__isDirty;
 				dirtyObjects.splice(i, 1);
 			}
-			
-			
+
 		},
 		isDirty: function(item){
-			// summary
+			// summary:
 			//		returns true if the item is marked as dirty or true if there are any dirty items
 			if(!item){
 				return !!this._dirtyObjects.length;
@@ -469,9 +496,10 @@ dojo.declare("dojo.data.ObjectStore", null,{
 
 		onSet: function(){},
 		onNew: function(){},
-		onDelete: 	function(){}
+		onDelete:	function(){},
+		// an extra to get result sets
+		onFetch: function(results){}
+
 	}
 );
-
-return dojo.data.ObjectStore;
 });
diff --git a/dojo/data/api/Identity.js b/dojo/data/api/Identity.js
index cae4c30..af074ea 100644
--- a/dojo/data/api/Identity.js
+++ b/dojo/data/api/Identity.js
@@ -1,4 +1,9 @@
-define("dojo/data/api/Identity", ["dojo", "dojo/data/api/Read"], function(dojo) {
+define(["../..", "./Read"], function(dojo) {
+	// module:
+	//		dojo/data/api/Identity
+	// summary:
+	//		TODOC
+
 
 dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
 	//	summary:
@@ -29,8 +34,6 @@ dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
 		//	|	var itemId = store.getIdentity(kermit);
 		//	|	assert(kermit === store.findByIdentity(store.getIdentity(kermit)));
 		throw new Error('Unimplemented API: dojo.data.api.Identity.getIdentity');
-		var itemIdentityString = null;
-		return itemIdentityString; // string
 	},
 
 	getIdentityAttributes: function(/* item */ item){
@@ -51,7 +54,6 @@ dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
 		//	|	var identifiers = store.getIdentityAttributes(itemId);
 		//	|	assert(typeof identifiers === "array" || identifiers === null);
 		throw new Error('Unimplemented API: dojo.data.api.Identity.getIdentityAttributes');
-		return null; // string
 	},
 
 
diff --git a/dojo/data/api/Notification.js b/dojo/data/api/Notification.js
index 4621095..0e814e3 100644
--- a/dojo/data/api/Notification.js
+++ b/dojo/data/api/Notification.js
@@ -1,4 +1,9 @@
-define("dojo/data/api/Notification", ["dojo", "dojo/data/api/Read"], function(dojo) {
+define(["../..", "./Read"], function(dojo) {
+	// module:
+	//		dojo/data/api/Notification
+	// summary:
+	//		TODOC
+
 
 dojo.declare("dojo.data.api.Notification", dojo.data.api.Read, {
 	//	summary:
@@ -36,8 +41,8 @@ dojo.declare("dojo.data.api.Notification", dojo.data.api.Read, {
 
 	onSet: function(/* item */ item,
 					/* attribute-name-string */ attribute,
-					/* object | array */ oldValue,
-					/* object | array */ newValue){
+					/* object|array */ oldValue,
+					/* object|array */ newValue){
 		//	summary:
 		//		This function is called any time an item is modified via setValue, setValues, unsetAttribute, etc.
 		//	description:
diff --git a/dojo/data/api/Read.js b/dojo/data/api/Read.js
index 9af377f..359dafa 100644
--- a/dojo/data/api/Read.js
+++ b/dojo/data/api/Read.js
@@ -1,7 +1,12 @@
-define("dojo/data/api/Read", ["dojo", "dojo/data/api/Request"], function(dojo) {
+define(["../..", "./Request"], function(dojo) {
+	// module:
+	//		dojo/data/api/Read
+	// summary:
+	//		TODOC
+
 
 dojo.declare("dojo.data.api.Read", null, {
-	//	summary:
+	// 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,
@@ -10,7 +15,7 @@ dojo.declare("dojo.data.api.Read", null, {
 	getValue: function(	/* item */ item,
 						/* attribute-name-string */ attribute,
 						/* value? */ defaultValue){
-		//	summary:
+		// summary:
 		//		Returns a single attribute value.
 		//		Returns defaultValue if and only if *item* does not have a value for *attribute*.
 		//		Returns null if and only if null was explicitly set as the attribute value.
@@ -23,26 +28,24 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		or "the item has that attribute but does not have any attribute values".
 		//		If store.hasAttribute(item, attribute) returns false, then
 		//		store.getValue(item, attribute) will return undefined.
-		//
-		//	item:
+		// item:
 		//		The item to access values on.
-		//	attribute:
+		// attribute:
 		//		The attribute to access represented as a string.
-		//	defaultValue:
+		// defaultValue:
 		//		Optional.  A default value to use for the getValue return in the attribute does not exist or has no value.
-		//
-		//	exceptions:
+		// returns:
+		//		a literal, an item, null, or undefined (never an array)
+		// exceptions:
 		//		Throws an exception if *item* is not an item, or *attribute* is not a string
-		//	example:
+		// example:
 		//	|	var darthVader = store.getValue(lukeSkywalker, "father");
-		var attributeValue = null;
 		throw new Error('Unimplemented API: dojo.data.api.Read.getValue');
-		return attributeValue; // a literal, an item, null, or undefined (never an array)
 	},
 
 	getValues: function(/* item */ item,
 						/* attribute-name-string */ attribute){
-		//	summary:
+		// summary:
 		// 		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
@@ -50,114 +53,96 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		If the item does not have a value for the given attribute, then getValues()
 		//		will return an empty array: [].  (So, if store.hasAttribute(item, attribute)
 		//		has a return of false, then store.getValues(item, attribute) will return [].)
-		//
-		//	item:
+		// item:
 		//		The item to access values on.
-		//	attribute:
+		// attribute:
 		//		The attribute to access represented as a string.
-		//
-		//	exceptions:
+		// returns:
+		//		an array that may contain literals and items
+		// exceptions:
 		//		Throws an exception if *item* is not an item, or *attribute* is not a string
-		//	example:
+		// example:
 		//	|	var friendsOfLuke = store.getValues(lukeSkywalker, "friends");
-		var array = [];
 		throw new Error('Unimplemented API: dojo.data.api.Read.getValues');
-		return array; // an array that may contain literals and items
 	},
 
 	getAttributes: function(/* item */ item){
-		//	summary:
+		// 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
 		//		at all, getAttributes() will return an empty array: [].
-		//
-		//	item:
+		// item:
 		//		The item to access attributes on.
-		//
-		//	exceptions:
+		// exceptions:
 		//		Throws an exception if *item* is not an item, or *attribute* is not a string
-		//	example:
+		// example:
 		//	|	var array = store.getAttributes(kermit);
-		var array = [];
 		throw new Error('Unimplemented API: dojo.data.api.Read.getAttributes');
-		return array; // array
 	},
 
 	hasAttribute: function(	/* item */ item,
 							/* attribute-name-string */ attribute){
-		//	summary:
+		// summary:
 		//		Returns true if the given *item* has a value for the given *attribute*.
-		//
-		//	item:
+		// item:
 		//		The item to access attributes on.
-		//	attribute:
+		// attribute:
 		//		The attribute to access represented as a string.
-		//
-		//	exceptions:
+		// exceptions:
 		//		Throws an exception if *item* is not an item, or *attribute* is not a string
-		//	example:
+		// example:
 		//	|	var trueOrFalse = store.hasAttribute(kermit, "color");
 		throw new Error('Unimplemented API: dojo.data.api.Read.hasAttribute');
-		return false; // boolean
 	},
 
 	containsValue: function(/* item */ item,
 							/* attribute-name-string */ attribute,
 							/* anything */ value){
-		//	summary:
+		// summary:
 		//		Returns true if the given *value* is one of the values that getValues()
 		//		would return.
-		//
-		//	item:
+		// item:
 		//		The item to access values on.
-		//	attribute:
+		// attribute:
 		//		The attribute to access represented as a string.
-		//	value:
+		// value:
 		//		The value to match as a value for the attribute.
-		//
-		//	exceptions:
+		// exceptions:
 		//		Throws an exception if *item* is not an item, or *attribute* is not a string
-		//	example:
+		// example:
 		//	|	var trueOrFalse = store.containsValue(kermit, "color", "green");
 		throw new Error('Unimplemented API: dojo.data.api.Read.containsValue');
-		return false; // boolean
 	},
 
 	isItem: function(/* anything */ something){
-		//	summary:
+		// summary:
 		//		Returns true if *something* is an item and came from the store instance.
 		//		Returns false if *something* is a literal, an item from another store instance,
 		//		or is any object other than an item.
-		//
-		//	something:
+		// something:
 		//		Can be anything.
-		//
-		//	example:
+		// example:
 		//	|	var yes = store.isItem(store.newItem());
 		//	|	var no  = store.isItem("green");
 		throw new Error('Unimplemented API: dojo.data.api.Read.isItem');
-		return false; // boolean
 	},
 
 	isItemLoaded: function(/* anything */ something){
-		//	summary:
+		// summary:
 		//		Returns false if isItem(something) is false.  Returns false if
 		//		if isItem(something) is true but the the item is not yet loaded
 		//		in local memory (for example, if the item has not yet been read
 		//		from the server).
-		//
-		//	something:
+		// something:
 		//		Can be anything.
-		//
-		//	example:
+		// example:
 		//	|	var yes = store.isItemLoaded(store.newItem());
 		//	|	var no  = store.isItemLoaded("green");
 		throw new Error('Unimplemented API: dojo.data.api.Read.isItemLoaded');
-		return false; // boolean
 	},
 
 	loadItem: function(/* object */ keywordArgs){
-		//	summary:
+		// 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
 		//		isItemLoaded() returns true before loadItem() is even called,
@@ -176,7 +161,7 @@ dojo.declare("dojo.data.api.Read", null, {
 		//	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.
 		//		Function(item)
 		//		The onItem parameter is the callback to invoke when the item has been loaded.  It takes only one
@@ -201,13 +186,13 @@ dojo.declare("dojo.data.api.Read", null, {
 	},
 
 	fetch: function(/* Object */ keywordArgs){
-		//	summary:
+		// summary:
 		//		Given a query and set of defined options, such as a start and count of items to return,
 		//		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:
+		// 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
 		//		an additional function attached, abort().  The returned request object may then be used
@@ -218,7 +203,7 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		returned, only that the API does not require it.  For more info about the Request API,
 		//		see dojo.data.api.Request
 		//
-		//	keywordArgs:
+		// keywordArgs:
 		//		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:
@@ -318,7 +303,7 @@ dojo.declare("dojo.data.api.Read", null, {
 		//	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 withh 'count', the store should be able
+		//		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
 		//
@@ -340,7 +325,7 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		(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:
+		// 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
 		//		object returned with the required functions in Request.js attached.
@@ -351,39 +336,39 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		such as request.store property, which is a pointer to the datastore object that
 		//		fetch() is a method of.
 		//
-		//	exceptions:
+		// exceptions:
 		//		Throws an exception if the query is not valid, or if the query
 		//		is required but was not supplied.
 		//
-		//	example:
+		// example:
 		//		Fetch all books identified by the query and call 'showBooks' when complete
 		//		|	var request = store.fetch({query:"all books", onComplete: showBooks});
-		//	example:
+		// example:
 		//		Fetch all items in the story and call 'showEverything' when complete.
 		//		|	var request = store.fetch(onComplete: showEverything);
-		//	example:
+		// example:
 		//		Fetch only 10 books that match the query 'all books', starting at the fifth book found during the search.
 		//		This demonstrates how paging can be done for specific queries.
 		//		|	var request = store.fetch({query:"all books", start: 4, count: 10, onComplete: showBooks});
-		//	example:
+		// example:
 		//		Fetch all items that match the query, calling 'callback' each time an item is located.
 		//		|	var request = store.fetch({query:"foo/bar", onItem:callback});
-		//	example:
+		// example:
 		//		Fetch the first 100 books by author King, call showKing when up to 100 items have been located.
 		//		|	var request = store.fetch({query:{author:"King"}, start: 0, count:100, onComplete: showKing});
-		//	example:
+		// example:
 		//		Locate the books written by Author King, sort it on title and publisher, then return the first 100 items from the sorted items.
 		//		|	var request = store.fetch({query:{author:"King"}, sort: [{ attribute: "title", descending: true}, {attribute: "publisher"}], ,start: 0, count:100, onComplete: 'showKing'});
-		//	example:
+		// example:
 		//		Fetch the first 100 books by authors starting with the name King, then call showKing when up to 100 items have been located.
 		//		|	var request = store.fetch({query:{author:"King*"}, start: 0, count:100, onComplete: showKing});
-		//	example:
+		// example:
 		//		Fetch the first 100 books by authors ending with 'ing', but only have one character before it (King, Bing, Ling, Sing, etc.), then call showBooks when up to 100 items have been located.
 		//		|	var request = store.fetch({query:{author:"?ing"}, start: 0, count:100, onComplete: showBooks});
-		//	example:
+		// example:
 		//		Fetch the first 100 books by author King, where the name may appear as King, king, KING, kInG, and so on, then call showKing when up to 100 items have been located.
 		//		|	var request = store.fetch({query:{author:"King"}, queryOptions:(ignoreCase: true}, start: 0, count:100, onComplete: showKing});
-		//	example:
+		// example:
 		//		Paging
 		//		|	var store = new dojo.data.LargeRdbmsStore({url:"jdbc:odbc:foobar"});
 		//		|	var fetchArgs = {
@@ -402,13 +387,11 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		and then when the user presses the "Next Page" button...
 		//		|	fetchArgs.start += 20;
 		//		|	store.fetch(fetchArgs);  // get the next 20 items
-		var request = null;
 		throw new Error('Unimplemented API: dojo.data.api.Read.fetch');
-		return request; // an object conforming to the dojo.data.api.Request API
 	},
 
 	getFeatures: function(){
-		//	summary:
+		// summary:
 		//		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
@@ -424,11 +407,11 @@ dojo.declare("dojo.data.api.Read", null, {
 	},
 
 	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-		//	summary:
+		// summary:
 		//		The close() method is intended for instructing the store to 'close' out
 		//		any information associated with a particular request.
 		//
-		//	description:
+		// 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.
@@ -436,14 +419,14 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		clearing any internal datastore caches and closing any 'open' connections.
 		//		For some store implementations, this call may be a no-op.
 		//
-		//	request:
+		// 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:
+		// example:
 		//	|	var request = store.fetch({onComplete: doSomething});
 		//	|	...
 		//	|	store.close(request);
@@ -451,11 +434,11 @@ dojo.declare("dojo.data.api.Read", null, {
 	},
 
 	getLabel: function(/* item */ item){
-		//	summary:
+		// 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:
+		// 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
 		//		most labels will be a specific attribute value or collection of the attribute
@@ -467,36 +450,34 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		their instance of the store, or extend the store and replace the function in
 		//		the extension class.
 		//
-		//	item:
+		// item:
 		//		The item to return the label for.
 		//
-		//	returns:
+		// 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');
-		return undefined;
 	},
 
 	getLabelAttributes: function(/* item */ item){
-		//	summary:
+		// 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:
+		// 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:
+		// item:
 		//		The item to return the list of label attributes for.
 		//
-		//	returns:
+		// 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.
 		throw new Error('Unimplemented API: dojo.data.api.Read.getLabelAttributes');
-		return null;
 	}
 });
 
diff --git a/dojo/data/api/Request.js b/dojo/data/api/Request.js
index 504b4e7..1c6af9f 100644
--- a/dojo/data/api/Request.js
+++ b/dojo/data/api/Request.js
@@ -1,4 +1,9 @@
-define("dojo/data/api/Request", ["dojo"], function(dojo) {
+define(["../.."], function(dojo) {
+	// module:
+	//		dojo/data/api/Request
+	// summary:
+	//		TODOC
+
 
 dojo.declare("dojo.data.api.Request", null, {
 	//	summary:
diff --git a/dojo/data/api/Write.js b/dojo/data/api/Write.js
index 05e50d2..a793cdd 100644
--- a/dojo/data/api/Write.js
+++ b/dojo/data/api/Write.js
@@ -1,13 +1,18 @@
-define("dojo/data/api/Write", ["dojo", "dojo/data/api/Read"], function(dojo) {
+define(["../..", "./Read"], function(dojo) {
+	// module:
+	//		dojo/data/api/Write
+	// summary:
+	//		TODOC
+
 
 dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
-	//	summary:
+	// summary:
 	//		This is an abstract API that data provider implementations conform to.
 	//		This file defines function signatures and intentionally leaves all the
 	//		functionss unimplemented.
 
 	getFeatures: function(){
-		//	summary:
+		// summary:
 		//		See dojo.data.api.Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true,
@@ -16,7 +21,7 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 	},
 
 	newItem: function(/* Object? */ keywordArgs, /*Object?*/ parentInfo){
-		//	summary:
+		// summary:
 		//		Returns a newly created item.  Sets the attributes of the new
 		//		item based on the *keywordArgs* provided.  In general, the attribute
 		//		names in the keywords become the attributes in the new item and as for
@@ -27,9 +32,9 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		//		In general, this will assume that the attribute targetted is multi-valued and a new item
 		//		is appended onto the list of values for that attribute.
 		//
-		//	keywordArgs:
+		// keywordArgs:
 		//		A javascript object defining the initial content of the item as a set of JavaScript 'property name: value' pairs.
-		//	parentInfo:
+		// parentInfo:
 		//		An optional javascript object defining what item is the parent of this item (in a hierarchical store.  Not all stores do hierarchical items),
 		//		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
@@ -39,115 +44,109 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		//			attribute: "attribute-name-string"
 		//		}
 		//
-		//	exceptions:
+		// exceptions:
 		//		Throws an exception if *keywordArgs* is a string or a number or
 		//		anything other than a simple anonymous object.
 		//		Throws an exception if the item in parentInfo is not an item from the store
 		//		or if the attribute isn't an attribute name string.
-		//	example:
+		// example:
 		//	|	var kermit = store.newItem({name: "Kermit", color:[blue, green]});
 
-		var newItem;
 		throw new Error('Unimplemented API: dojo.data.api.Write.newItem');
-		return newItem; // item
 	},
 
 	deleteItem: function(/* item */ item){
-		//	summary:
+		// summary:
 		//		Deletes an item from the store.
 		//
-		//	item:
+		// item:
 		//		The item to delete.
 		//
-		//	exceptions:
+		// exceptions:
 		//		Throws an exception if the argument *item* is not an item
 		//		(if store.isItem(item) returns false).
-		//	example:
+		// example:
 		//	|	var success = store.deleteItem(kermit);
 		throw new Error('Unimplemented API: dojo.data.api.Write.deleteItem');
-		return false; // boolean
 	},
 
 	setValue: function(	/* item */ item,
 						/* string */ attribute,
 						/* almost anything */ value){
-		//	summary:
+		// summary:
 		//		Sets the value of an attribute on an item.
 		//		Replaces any previous value or values.
 		//
-		//	item:
+		// item:
 		//		The item to modify.
-		//	attribute:
+		// attribute:
 		//		The attribute of the item to change represented as a string name.
-		//	value:
+		// value:
 		//		The value to assign to the item.
 		//
-		//	exceptions:
+		// exceptions:
 		//		Throws an exception if *item* is not an item, or if *attribute*
 		//		is neither an attribute object or a string.
 		//		Throws an exception if *value* is undefined.
-		//	example:
+		// example:
 		//	|	var success = store.set(kermit, "color", "green");
 		throw new Error('Unimplemented API: dojo.data.api.Write.setValue');
-		return false; // boolean
 	},
 
 	setValues: function(/* item */ item,
 						/* string */ attribute,
 						/* array */ values){
-		//	summary:
+		// summary:
 		//		Adds each value in the *values* array as a value of the given
 		//		attribute on the given item.
 		//		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:
+		// item:
 		//		The item to modify.
-		//	attribute:
+		// attribute:
 		//		The attribute of the item to change represented as a string name.
-		//	values:
+		// values:
 		//		An array of values to assign to the attribute..
 		//
-		//	exceptions:
+		// 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:
+		// example:
 		//	|	var success = store.setValues(kermit, "color", ["green", "aqua"]);
 		//	|	success = store.setValues(kermit, "color", []);
 		//	|	if (success) {assert(!store.hasAttribute(kermit, "color"));}
 		throw new Error('Unimplemented API: dojo.data.api.Write.setValues');
-		return false; // boolean
 	},
 
 	unsetAttribute: function(	/* item */ item,
 								/* string */ attribute){
-		//	summary:
+		// summary:
 		//		Deletes all the values of an attribute on an item.
 		//
-		//	item:
+		// item:
 		//		The item to modify.
-		//	attribute:
+		// attribute:
 		//		The attribute of the item to unset represented as a string.
 		//
-		//	exceptions:
+		// exceptions:
 		//		Throws an exception if *item* is not an item, or if *attribute*
 		//		is neither an attribute object or a string.
-		//	example:
+		// example:
 		//	|	var success = store.unsetAttribute(kermit, "color");
 		//	|	if (success) {assert(!store.hasAttribute(kermit, "color"));}
 		throw new Error('Unimplemented API: dojo.data.api.Write.clear');
-		return false; // boolean
 	},
 
 	save: function(/* object */ keywordArgs){
-		//	summary:
+		// summary:
 		//		Saves to the server all the changes that have been made locally.
 		//		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:
+		// keywordArgs:
 		//		{
 		//			onComplete: function
 		//			onError: function
@@ -178,45 +177,43 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		//		For example, onComplete.call(scope) vs.
 		//		onComplete.call(dojo.global)
 		//
-		//	returns:
+		// returns:
 		//		Nothing.  Since the saves are generally asynchronous, there is
 		//		no need to return anything.  All results are passed via callbacks.
-		//	example:
+		// example:
 		//	|	store.save({onComplete: onSave});
 		//	|	store.save({scope: fooObj, onComplete: onSave, onError: saveFailed});
 		throw new Error('Unimplemented API: dojo.data.api.Write.save');
 	},
 
 	revert: function(){
-		//	summary:
+		// summary:
 		//		Discards any unsaved changes.
-		//	description:
+		// description:
 		//		Discards any unsaved changes.
 		//
-		//	example:
+		// example:
 		//	|	var success = store.revert();
 		throw new Error('Unimplemented API: dojo.data.api.Write.revert');
-		return false; // boolean
 	},
 
 	isDirty: function(/* item? */ item){
-		//	summary:
+		// summary:
 		//		Given an item, isDirty() returns true if the item has been modified
 		//		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:
+		// item:
 		//		The item to check.
 		//
-		//	exceptions:
+		// exceptions:
 		//		Throws an exception if isDirty() is passed an argument and the
 		//		argument is not an item.
-		//	example:
+		// example:
 		//	|	var trueOrFalse = store.isDirty(kermit); // true if kermit is dirty
 		//	|	var trueOrFalse = store.isDirty();       // true if any item is dirty
 		throw new Error('Unimplemented API: dojo.data.api.Write.isDirty');
-		return false; // boolean
 	}
 });
 
diff --git a/dojo/data/util/filter.js b/dojo/data/util/filter.js
index f618d80..49a5295 100644
--- a/dojo/data/util/filter.js
+++ b/dojo/data/util/filter.js
@@ -1,7 +1,12 @@
-define("dojo/data/util/filter", ["dojo"], function(dojo) {
-dojo.getObject("data.util.filter", true, dojo);
+define(["dojo/_base/lang"], function(lang) {
+	// module:
+	//		dojo/data/util/filter
+	// summary:
+	//		TODOC
 
-dojo.data.util.filter.patternToRegExp = function(/*String*/pattern, /*boolean?*/ ignoreCase){
+var filter = lang.getObject("dojo.data.util.filter", true);
+
+filter.patternToRegExp = function(/*String*/pattern, /*boolean?*/ ignoreCase){
 	//	summary:
 	//		Helper function to convert a simple pattern to a regular expression for matching.
 	//	description:
@@ -62,8 +67,8 @@ dojo.data.util.filter.patternToRegExp = function(/*String*/pattern, /*boolean?*/
 	}else{
 		return new RegExp(rxp,"m"); //RegExp
 	}
-	
+
 };
 
-return dojo.data.util.filter;
+return filter;
 });
diff --git a/dojo/data/util/simpleFetch.js b/dojo/data/util/simpleFetch.js
index 82b2670..40d0d22 100644
--- a/dojo/data/util/simpleFetch.js
+++ b/dojo/data/util/simpleFetch.js
@@ -1,7 +1,13 @@
-define("dojo/data/util/simpleFetch", ["dojo", "dojo/data/util/sorter"], function(dojo) {
-dojo.getObject("data.util.simpleFetch", true, dojo);
+define(["dojo/_base/lang", "dojo/_base/window", "./sorter"], 
+  function(lang, winUtil, sorter) {
+	// module:
+	//		dojo/data/util/simpleFetch
+	// summary:
+	//		TODOC
 
-dojo.data.util.simpleFetch.fetch = function(/* Object? */ request){
+var simpleFetch = lang.getObject("dojo.data.util.simpleFetch", true);
+
+simpleFetch.fetch = function(/* Object? */ request){
 	//	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.
@@ -36,7 +42,7 @@ dojo.data.util.simpleFetch.fetch = function(/* Object? */ request){
 
 	var _errorHandler = function(errorData, requestObject){
 		if(requestObject.onError){
-			var scope = requestObject.scope || dojo.global;
+			var scope = requestObject.scope || winUtil.global;
 			requestObject.onError.call(scope, errorData, requestObject);
 		}
 	};
@@ -55,7 +61,7 @@ dojo.data.util.simpleFetch.fetch = function(/* Object? */ request){
 			}
 		};
 
-		var scope = requestObject.scope || dojo.global;
+		var scope = requestObject.scope || winUtil.global;
 		if(!requestObject.store){
 			requestObject.store = self;
 		}
@@ -63,7 +69,7 @@ dojo.data.util.simpleFetch.fetch = function(/* Object? */ request){
 			requestObject.onBegin.call(scope, items.length, requestObject);
 		}
 		if(requestObject.sort){
-			items.sort(dojo.data.util.sorter.createSortFunction(requestObject.sort, self));
+			items.sort(sorter.createSortFunction(requestObject.sort, self));
 		}
 		if(requestObject.onItem){
 			for(var i = startIndex; (i < items.length) && (i < endIndex); ++i){
@@ -85,5 +91,5 @@ dojo.data.util.simpleFetch.fetch = function(/* Object? */ request){
 	return request;	// Object
 };
 
-return dojo.data.util.simpleFetch;
+return simpleFetch;
 });
diff --git a/dojo/data/util/sorter.js b/dojo/data/util/sorter.js
index f367b81..617fb47 100644
--- a/dojo/data/util/sorter.js
+++ b/dojo/data/util/sorter.js
@@ -1,7 +1,12 @@
-define("dojo/data/util/sorter", ["dojo"], function(dojo) {
-dojo.getObject("data.util.sorter", true, dojo);
+define(["dojo/_base/lang"], function(lang) {
+	// module:
+	//		dojo/data/util/sorter
+	// summary:
+	//		TODOC
 
-dojo.data.util.sorter.basicComparator = function(	/*anything*/ a,
+var sorter = lang.getObject("dojo.data.util.sorter", true);
+
+sorter.basicComparator = function(	/*anything*/ a,
 													/*anything*/ b){
 	//	summary:
 	//		Basic comparision function that compares if an item is greater or less than another item
@@ -9,7 +14,7 @@ dojo.data.util.sorter.basicComparator = function(	/*anything*/ a,
 	//		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.
-	
+
 	//null is a problematic compare, so if null, we set to undefined.
 	//Makes the check logic simple, compact, and consistent
 	//And (null == undefined) === true, so the check later against null
@@ -29,8 +34,7 @@ dojo.data.util.sorter.basicComparator = function(	/*anything*/ a,
 	return r; //int {-1,0,1}
 };
 
-dojo.data.util.sorter.createSortFunction = function(	/* attributes array */sortSpec,
-														/*dojo.data.core.Read*/ store){
+sorter.createSortFunction = function(	/* attributes array */sortSpec, /*dojo.data.core.Read*/ store){
 	//	summary:
 	//		Helper function to generate the sorting function based off the list of sort attributes.
 	//	description:
@@ -62,7 +66,7 @@ dojo.data.util.sorter.createSortFunction = function(	/* attributes array */sortS
 	}
 	var sortAttribute;
 	var map = store.comparatorMap;
-	var bc = dojo.data.util.sorter.basicComparator;
+	var bc = sorter.basicComparator;
 	for(var i = 0; i < sortSpec.length; i++){
 		sortAttribute = sortSpec[i];
 		var attr = sortAttribute.attribute;
@@ -91,5 +95,5 @@ dojo.data.util.sorter.createSortFunction = function(	/* attributes array */sortS
 	}; // Function
 };
 
-return dojo.data.util.sorter;
+return sorter;
 });
diff --git a/dojo/date.js b/dojo/date.js
index 532d7d9..f3571e8 100644
--- a/dojo/date.js
+++ b/dojo/date.js
@@ -1,5 +1,10 @@
-define("dojo/date", ["dojo"], function(dojo) {
-dojo.getObject("date", true, dojo);
+define(["./_base/kernel", "./_base/lang"], function(dojo, lang) {
+	// module:
+	//		dojo/date
+	// summary:
+	//		TODOC
+
+lang.getObject("date", true, dojo);
 
 /*=====
 dojo.date = {
@@ -104,7 +109,7 @@ dojo.date.compare = function(/*Date*/date1, /*Date?*/date2, /*String?*/portion){
 		date1.setFullYear(0, 0, 0);
 		date2.setFullYear(0, 0, 0);
 	}
-	
+
 	if(date1 > date2){ return 1; } // int
 	if(date1 < date2){ return -1; } // int
 	return 0; // int
diff --git a/dojo/date/locale.js b/dojo/date/locale.js
index 5d670e2..7acacfa 100644
--- a/dojo/date/locale.js
+++ b/dojo/date/locale.js
@@ -1,8 +1,21 @@
-define("dojo/date/locale", ["dojo", "dojo/date", "dojo/cldr/supplemental", "dojo/regexp", "dojo/string", "dojo/i18n", "i18n!dojo/cldr/nls/gregorian"], function(dojo) {
-dojo.getObject("date.locale", true, dojo);
+define([
+	"../_base/kernel",
+	"../_base/lang",
+	"../_base/array",
+	"../date",
+	"../cldr/supplemental",
+	"../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.
 
-// Localization methods for Date.   Honor local customs using locale-dependent dojo.cldr data.
+lang.getObject("date.locale", true, dojo);
 
+// Localization methods for Date.   Honor local customs using locale-dependent dojo.cldr data.
 
 // Load the bundles containing localization information for
 // names and formats
@@ -10,7 +23,6 @@ dojo.getObject("date.locale", true, dojo);
 //NOTE: Everything in this module assumes Gregorian calendars.
 // Other calendars will be implemented in separate modules.
 
-(function(){
 	// Format a pattern without literals
 	function formatPattern(dateObject, bundle, options, pattern){
 		return pattern.replace(/([a-z])\1*/ig, function(match){
@@ -121,8 +133,8 @@ dojo.getObject("date.locale", true, dojo);
 					var offset = dojo.date.locale._getZone(dateObject, false, options);
 					var tz = [
 						(offset<=0 ? "+" : "-"),
-						dojo.string.pad(Math.floor(Math.abs(offset)/60), 2),
-						dojo.string.pad(Math.abs(offset)% 60, 2)
+						string.pad(Math.floor(Math.abs(offset)/60), 2),
+						string.pad(Math.abs(offset)% 60, 2)
 					];
 					if(l==4){
 						tz.splice(0, 0, "GMT");
@@ -135,7 +147,7 @@ dojo.getObject("date.locale", true, dojo);
 				default:
 					throw new Error("dojo.date.locale.format: invalid pattern char: "+pattern);
 			}
-			if(pad){ s = dojo.string.pad(s, l); }
+			if(pad){ s = string.pad(s, l); }
 			return s;
 		});
 	}
@@ -187,7 +199,7 @@ dojo.date.locale._getZone = function(/*Date*/dateObject, /*boolean*/getName, /*d
 	// options:
 	//		The options being used for formatting
 	if(getName){
-		return dojo.date.getTimezoneName(dateObject);
+		return date.getTimezoneName(dateObject);
 	}else{
 		return dateObject.getTimezoneOffset();
 	}
@@ -219,7 +231,7 @@ dojo.date.locale.format = function(/*Date*/dateObject, /*dojo.date.locale.__Form
 		formatLength = options.formatLength || 'short',
 		bundle = dojo.date.locale._getGregorianBundle(locale),
 		str = [],
-		sauce = dojo.hitch(this, formatPattern, dateObject, bundle, options);
+		sauce = lang.hitch(this, formatPattern, dateObject, bundle, options);
 	if(options.selector == "year"){
 		return _processPattern(bundle["dateFormatItem-yyyy"] || "yyyy", sauce);
 	}
@@ -262,7 +274,7 @@ dojo.date.locale._parseInfo = function(/*dojo.date.locale.__FormatOptions?*/opti
 	}
 
 	var tokens = [],
-		re = _processPattern(pattern, dojo.hitch(this, _buildDateTimeRE, tokens, bundle, options));
+		re = _processPattern(pattern, lang.hitch(this, _buildDateTimeRE, tokens, bundle, options));
 	return {regexp: re, tokens: tokens, bundle: bundle};
 };
 
@@ -317,9 +329,8 @@ dojo.date.locale.parse = function(/*String*/value, /*dojo.date.locale.__FormatOp
 						//of 80 years before and 20 years after present year
 						var year = '' + new Date().getFullYear(),
 							century = year.substring(0, 2) * 100,
-							cutoff = Math.min(Number(year.substring(2, 4)) + 20, 99),
-							num = (v < cutoff) ? century + v : century - 100 + v;
-						result[0] = num;
+							cutoff = Math.min(Number(year.substring(2, 4)) + 20, 99);
+						result[0] = (v < cutoff) ? century + v : century - 100 + v;
 					}else{
 						//we expected 2 digits and got more...
 						if(options.strict){
@@ -458,7 +469,7 @@ dojo.date.locale.parse = function(/*String*/value, /*dojo.date.locale.__FormatOp
 	// We could compare the timezone offset after the shift and add the difference instead.
 	if((monthToken && dateObject.getMonth() < result[1]) ||
 		(dateToken && dateObject.getDate() < result[2])){
-		dateObject = dojo.date.add(dateObject, "hour", 1);
+		dateObject = date.add(dateObject, "hour", 1);
 	}
 
 	return dateObject; // Date
@@ -490,7 +501,7 @@ function _processPattern(pattern, applyPattern, applyLiteral, applyAll){
 }
 
 function _buildDateTimeRE(tokens, bundle, options, pattern){
-	pattern = dojo.regexp.escapeString(pattern);
+	pattern = regexp.escapeString(pattern);
 	if(!options.strict){ pattern = pattern.replace(" a", " ?a"); } // kludge to tolerate no space before am/pm
 	return pattern.replace(/([a-z])\1*/ig, function(match){
 		// Build a simple regexp.  Avoid captures, which would ruin the tokens list
@@ -512,7 +523,7 @@ function _buildDateTimeRE(tokens, bundle, options, pattern){
 				s = (l>2) ? '\\S+?' : '1[0-2]|'+p2+'[1-9]';
 				break;
 			case 'D':
-				s = '[12][0-9][0-9]|3[0-5][0-9]|36[0-6]|'+p3+'[1-9][0-9]|'+p2+'[1-9]';
+				s = '[12][0-9][0-9]|3[0-5][0-9]|36[0-6]|'+p2+'[1-9][0-9]|'+p3+'[1-9]';
 				break;
 			case 'd':
 				s = '3[01]|[12]\\d|'+p2+'[1-9]';
@@ -545,7 +556,7 @@ function _buildDateTimeRE(tokens, bundle, options, pattern){
 			case 'a':
 				var am = options.am || bundle['dayPeriods-format-wide-am'],
 					pm = options.pm || bundle['dayPeriods-format-wide-pm'];
-				s = am + '|' + pm;
+					s = am + '|' + pm;
 				if(!options.strict){
 					if(am != am.toLowerCase()){ s += '|' + am.toLowerCase(); }
 					if(pm != pm.toLowerCase()){ s += '|' + pm.toLowerCase(); }
@@ -566,9 +577,7 @@ function _buildDateTimeRE(tokens, bundle, options, pattern){
 		return "(" + s + ")"; // add capture
 	}).replace(/[\xa0 ]/g, "[\\s\\xa0]"); // normalize whitespace.  Need explicit handling of \xa0 for IE.
 }
-})();
 
-(function(){
 var _customFormats = [];
 dojo.date.locale.addCustomFormats = function(/*String*/packageName, /*String*/bundleName){
 	// summary:
@@ -589,11 +598,10 @@ dojo.date.locale._getGregorianBundle = function(/*String*/locale){
 	var gregorian = {};
 	dojo.forEach(_customFormats, function(desc){
 		var bundle = dojo.i18n.getLocalization(desc.pkg, desc.name, locale);
-		gregorian = dojo.mixin(gregorian, bundle);
+		gregorian = lang.mixin(gregorian, bundle);
 	}, this);
 	return gregorian; /*Object*/
 };
-})();
 
 dojo.date.locale.addCustomFormats("dojo.cldr","gregorian");
 
@@ -604,7 +612,7 @@ dojo.date.locale.getNames = function(/*String*/item, /*String*/type, /*String?*/
 	// item:
 	//	'months' || 'days'
 	// type:
-	//	'wide' || 'narrow' || 'abbr' (e.g. "Monday", "Mon", or "M" respectively, in English)
+	//	'wide' || 'abbr' || 'narrow' (e.g. "Monday", "Mon", or "M" respectively, in English)
 	// context:
 	//	'standAlone' || 'format' (default)
 	// locale:
@@ -629,7 +637,7 @@ dojo.date.locale.isWeekend = function(/*Date?*/dateObject, /*String?*/locale){
 	// summary:
 	//	Determines if the date falls on a weekend, according to local custom.
 
-	var weekend = dojo.cldr.supplemental.getWeekend(locale),
+	var weekend = cldr.getWeekend(locale),
 		day = (dateObject || new Date()).getDay();
 	if(weekend.end < weekend.start){
 		weekend.end += 7;
@@ -642,7 +650,7 @@ dojo.date.locale.isWeekend = function(/*Date?*/dateObject, /*String?*/locale){
 
 dojo.date.locale._getDayOfYear = function(/*Date*/dateObject){
 	// summary: gets the day of the year as represented by dateObject
-	return dojo.date.difference(new Date(dateObject.getFullYear(), 0, 1, dateObject.getHours()), dateObject) + 1; // Number
+	return date.difference(new Date(dateObject.getFullYear(), 0, 1, dateObject.getHours()), dateObject) + 1; // Number
 };
 
 dojo.date.locale._getWeekOfYear = function(/*Date*/dateObject, /*Number*/firstDayOfWeek){
diff --git a/dojo/date/stamp.js b/dojo/date/stamp.js
index ece3e6b..5513f9e 100644
--- a/dojo/date/stamp.js
+++ b/dojo/date/stamp.js
@@ -1,5 +1,10 @@
-define("dojo/date/stamp", ["dojo"], function(dojo) {
-dojo.getObject("date.stamp", true, dojo);
+define(["../_base/kernel", "../_base/lang", "../_base/array"], function(dojo, lang, array) {
+	// module:
+	//		dojo/date/stamp
+	// summary:
+	//		TODOC
+
+lang.getObject("date.stamp", true, dojo);
 
 // Methods to convert dates to or from a wire (string) format using well-known conventions
 
@@ -53,7 +58,7 @@ dojo.date.stamp.fromISOString = function(/*String*/formattedString, /*Number?*/d
 		if(defaultTime){
 			// mix in defaultTime.  Relatively expensive, so use || operators for the fast path of defaultTime === 0
 			defaultTime = new Date(defaultTime);
-			dojo.forEach(dojo.map(["FullYear", "Month", "Date", "Hours", "Minutes", "Seconds", "Milliseconds"], function(prop){
+			array.forEach(array.map(["FullYear", "Month", "Date", "Hours", "Minutes", "Seconds", "Milliseconds"], function(prop){
 				return defaultTime["get" + prop]();
 			}), function(value, index){
 				match[index] = match[index] || value;
diff --git a/dojo/dnd/AutoSource.js b/dojo/dnd/AutoSource.js
new file mode 100644
index 0000000..1c2f4fc
--- /dev/null
+++ b/dojo/dnd/AutoSource.js
@@ -0,0 +1,13 @@
+define([ "./Source" ], function(Source){
+	/*===== Source = dojo.dnd.Source =====*/
+	return dojo.declare("dojo.dnd.AutoSource", Source, {
+		// summary:
+		//		a source that syncs its DnD nodes by default
+
+		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 5d75762..bd06393 100644
--- a/dojo/dnd/Avatar.js
+++ b/dojo/dnd/Avatar.js
@@ -1,4 +1,9 @@
-define("dojo/dnd/Avatar", ["dojo", "dojo/dnd/common"], function(dojo) {
+define(["../main", "./common"], function(dojo) {
+	// module:
+	//		dojo/dnd/Avatar
+	// summary:
+	//		TODOC
+
 
 dojo.declare("dojo.dnd.Avatar", null, {
 	// summary:
diff --git a/dojo/dnd/Container.js b/dojo/dnd/Container.js
index d9b43a0..9e832bc 100644
--- a/dojo/dnd/Container.js
+++ b/dojo/dnd/Container.js
@@ -1,4 +1,9 @@
-define("dojo/dnd/Container", ["dojo", "dojo/dnd/common", "dojo/parser"], function(dojo) {
+define(["../main", "../Evented", "./common", "../parser"], function(dojo, Evented) {
+	// module:
+	//		dojo/dnd/Container
+	// summary:
+	//		TODOC
+
 
 /*
 	Container states:
@@ -43,31 +48,31 @@ dojo.dnd.Item = function(){
 	//		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", null, {
+dojo.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,
-	
+
 	/*=====
 	// current: DomNode
 	//		The DOM node the mouse is currently hovered over
 	current: null,
-	
+
 	// map: Hash<String, dojo.dnd.Item>
 	//		Map from an item's id (which is also the DOMNode's id) to
 	//		the dojo.dnd.Item itself.
 	map: {},
 	=====*/
-	
+
 	constructor: function(node, params){
 		// summary:
 		//		a constructor of the Container
@@ -80,7 +85,7 @@ dojo.declare("dojo.dnd.Container", null, {
 		this.creator = params.creator || null;
 		this.skipForm = params.skipForm;
 		this.parent = params.dropParent && dojo.byId(params.dropParent);
-		
+
 		// class-specific variables
 		this.map = {};
 		this.current = null;
@@ -88,7 +93,7 @@ dojo.declare("dojo.dnd.Container", null, {
 		// states
 		this.containerState = "";
 		dojo.addClass(this.node, "dojoDndContainer");
-		
+
 		// mark up children
 		if(!(params && params._skipStartup)){
 			this.startup();
@@ -103,13 +108,13 @@ dojo.declare("dojo.dnd.Container", null, {
 			dojo.connect(this.node, "onselectstart", this, "onSelectStart")
 		];
 	},
-	
+
 	// object attributes (for markup)
 	creator: function(){
 		// summary:
 		//		creator function, dummy at the moment
 	},
-	
+
 	// abstract access to the map
 	getItem: function(/*String*/ key){
 		// summary:
@@ -143,7 +148,7 @@ dojo.declare("dojo.dnd.Container", null, {
 		//		removes all data items from the map
 		this.map = {};
 	},
-	
+
 	// methods
 	getAllNodes: function(){
 		// summary:
@@ -218,14 +223,14 @@ dojo.declare("dojo.dnd.Container", null, {
 	},
 
 	// markup methods
-	markupFactory: function(params, node){
+	markupFactory: function(params, node, ctor){
 		params._skipStartup = true;
-		return new dojo.dnd.Container(node, params);
+		return new ctor(node, params);
 	},
 	startup: function(){
 		// summary:
 		//		collects valid child items and populate the map
-		
+
 		// set up the real parent node
 		if(!this.parent){
 			// use the standard algorithm, if not assigned
@@ -295,7 +300,7 @@ dojo.declare("dojo.dnd.Container", null, {
 			dojo.stopEvent(e);
 		}
 	},
-	
+
 	// utilities
 	onOverEvent: function(){
 		// summary:
diff --git a/dojo/dnd/Manager.js b/dojo/dnd/Manager.js
index 6ce56c4..9884e80 100644
--- a/dojo/dnd/Manager.js
+++ b/dojo/dnd/Manager.js
@@ -1,6 +1,11 @@
-define("dojo/dnd/Manager", ["dojo", "dojo/dnd/common", "dojo/dnd/autoscroll", "dojo/dnd/Avatar"], function(dojo) {
+define(["../main", "../Evented", "./common", "./autoscroll", "./Avatar"], function(dojo, Evented) {
+	// module:
+	//		dojo/dnd/Manager
+	// summary:
+	//		TODOC
+
 
-dojo.declare("dojo.dnd.Manager", null, {
+var Manager = dojo.declare("dojo.dnd.Manager", [Evented], {
 	// summary:
 	//		the manager of DnD operations (usually a singleton)
 	constructor: function(){
@@ -16,7 +21,7 @@ dojo.declare("dojo.dnd.Manager", null, {
 	// avatar's offset from the mouse
 	OFFSET_X: 16,
 	OFFSET_Y: 16,
-	
+
 	// methods
 	overSource: function(source){
 		// summary:
@@ -103,7 +108,7 @@ dojo.declare("dojo.dnd.Manager", null, {
 		//		updates the avatar; it is separate to be overwritten dynamically, if needed
 		this.avatar.update();
 	},
-	
+
 	// mouse event processors
 	onMouseMove: function(e){
 		// summary:
@@ -140,7 +145,7 @@ dojo.declare("dojo.dnd.Manager", null, {
 			this.stopDrag();
 		}
 	},
-	
+
 	// keyboard event processors
 	onKeyDown: function(e){
 		// summary:
@@ -175,7 +180,7 @@ dojo.declare("dojo.dnd.Manager", null, {
 			}
 		}
 	},
-	
+
 	// utilities
 	_setCopyStatus: function(copy){
 		// summary:
@@ -195,7 +200,7 @@ dojo.declare("dojo.dnd.Manager", null, {
 //		The manager singleton variable. Can be overwritten if needed.
 dojo.dnd._manager = null;
 
-dojo.dnd.manager = function(){
+Manager.manager = dojo.dnd.manager = function(){
 	// summary:
 	//		Returns the current DnD manager.  Creates one if it is not created yet.
 	if(!dojo.dnd._manager){
@@ -204,5 +209,5 @@ dojo.dnd.manager = function(){
 	return dojo.dnd._manager;	// Object
 };
 
-return dojo.dnd.Manager;
+return Manager;
 });
diff --git a/dojo/dnd/Moveable.js b/dojo/dnd/Moveable.js
index 9674883..e7b9cbe 100644
--- a/dojo/dnd/Moveable.js
+++ b/dojo/dnd/Moveable.js
@@ -1,4 +1,9 @@
-define("dojo/dnd/Moveable", ["dojo", "dojo/dnd/Mover"], function(dojo) {
+define(["../main", "../Evented", "../touch", "./Mover"], function(dojo, Evented, touch) {
+	// module:
+	//		dojo/dnd/Moveable
+	// summary:
+	//		TODOC
+
 
 /*=====
 dojo.declare("dojo.dnd.__MoveableArgs", [], {
@@ -21,12 +26,12 @@ dojo.declare("dojo.dnd.__MoveableArgs", [], {
 });
 =====*/
 
-dojo.declare("dojo.dnd.Moveable", null, {
+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
@@ -42,8 +47,7 @@ dojo.declare("dojo.dnd.Moveable", null, {
 		this.skip  = params.skip;
 		this.mover = params.mover ? params.mover : dojo.dnd.Mover;
 		this.events = [
-			dojo.connect(this.handle, "onmousedown", this, "onMouseDown"),
-			dojo.connect(this.handle, "ontouchstart", this, "onMouseDown"),
+			dojo.connect(this.handle, touch.press, this, "onMouseDown"),
 			// cancel text selection and text dragging
 			dojo.connect(this.handle, "ondragstart",   this, "onSelectStart"),
 			dojo.connect(this.handle, "onselectstart", this, "onSelectStart")
@@ -51,8 +55,8 @@ dojo.declare("dojo.dnd.Moveable", null, {
 	},
 
 	// markup methods
-	markupFactory: function(params, node){
-		return new dojo.dnd.Moveable(node, params);
+	markupFactory: function(params, node, ctor){
+		return new ctor(node, params);
 	},
 
 	// methods
@@ -62,7 +66,7 @@ dojo.declare("dojo.dnd.Moveable", null, {
 		dojo.forEach(this.events, dojo.disconnect);
 		this.events = this.node = this.handle = null;
 	},
-	
+
 	// mouse event processors
 	onMouseDown: function(e){
 		// summary:
@@ -72,14 +76,11 @@ dojo.declare("dojo.dnd.Moveable", null, {
 		if(this.skip && dojo.dnd.isFormElement(e)){ return; }
 		if(this.delay){
 			this.events.push(
-				dojo.connect(this.handle, "onmousemove", this, "onMouseMove"),
-				dojo.connect(this.handle, "ontouchmove", this, "onMouseMove"),
-				dojo.connect(this.handle, "onmouseup", this, "onMouseUp"),
-				dojo.connect(this.handle, "ontouchend", this, "onMouseUp")
+				dojo.connect(this.handle, touch.move, this, "onMouseMove"),
+				dojo.connect(this.handle, touch.release, this, "onMouseUp")
 			);
-			var pos = e.touches ? e.touches[0] : e;
-			this._lastX = pos.pageX;
-			this._lastY = pos.pageY;
+			this._lastX = e.pageX;
+			this._lastY = e.pageY;
 		}else{
 			this.onDragDetected(e);
 		}
@@ -90,8 +91,7 @@ dojo.declare("dojo.dnd.Moveable", null, {
 		//		event processor for onmousemove/ontouchmove, used only for delayed drags
 		// e: Event
 		//		mouse/touch event
-		var pos = e.touches ? e.touches[0] : e;
-		if(Math.abs(pos.pageX - this._lastX) > this.delay || Math.abs(pos.pageY - this._lastY) > this.delay){
+		if(Math.abs(e.pageX - this._lastX) > this.delay || Math.abs(e.pageY - this._lastY) > this.delay){
 			this.onMouseUp(e);
 			this.onDragDetected(e);
 		}
@@ -116,7 +116,7 @@ dojo.declare("dojo.dnd.Moveable", null, {
 			dojo.stopEvent(e);
 		}
 	},
-	
+
 	// local events
 	onDragDetected: function(/* Event */ e){
 		// summary:
@@ -142,7 +142,7 @@ dojo.declare("dojo.dnd.Moveable", null, {
 		// summary:
 		//		called during the very first move notification;
 		//		can be used to initialize coordinates, can be overwritten.
-		
+
 		// default implementation does nothing
 	},
 	onMove: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop, /* Event */ e){
@@ -158,13 +158,13 @@ dojo.declare("dojo.dnd.Moveable", null, {
 	onMoving: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
 		// summary:
 		//		called before every incremental move; can be overwritten.
-		
+
 		// default implementation does nothing
 	},
 	onMoved: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
 		// summary:
 		//		called after every incremental move; can be overwritten.
-		
+
 		// default implementation does nothing
 	}
 });
diff --git a/dojo/dnd/Mover.js b/dojo/dnd/Mover.js
index 790821b..e74d770 100644
--- a/dojo/dnd/Mover.js
+++ b/dojo/dnd/Mover.js
@@ -1,6 +1,11 @@
-define("dojo/dnd/Mover", ["dojo", "dojo/dnd/common", "dojo/dnd/autoscroll"], function(dojo) {
+define(["../main", "../Evented", "../touch", "./common", "./autoscroll"], function(dojo, Evented, touch) {
+	// module:
+	//		dojo/dnd/Mover
+	// summary:
+	//		TODOC
 
-dojo.declare("dojo.dnd.Mover", null, {
+
+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.
@@ -14,23 +19,19 @@ dojo.declare("dojo.dnd.Mover", null, {
 		//		object which implements the functionality of the move,
 		//	 	and defines proper events (onMoveStart and onMoveStop)
 		this.node = dojo.byId(node);
-		var pos = e.touches ? e.touches[0] : e;
-		this.marginBox = {l: pos.pageX, t: pos.pageY};
+		this.marginBox = {l: e.pageX, t: e.pageY};
 		this.mouseButton = e.button;
 		var h = (this.host = host), d = node.ownerDocument;
 		this.events = [
 			// At the start of a drag, onFirstMove is called, and then the following two
 			// connects are disconnected
-			dojo.connect(d, "onmousemove", this, "onFirstMove"),
-			dojo.connect(d, "ontouchmove", this, "onFirstMove"),
+			dojo.connect(d, touch.move, this, "onFirstMove"),
 
 			// These are called continually during the drag
-			dojo.connect(d, "onmousemove", this, "onMouseMove"),
-			dojo.connect(d, "ontouchmove", this, "onMouseMove"),
+			dojo.connect(d, touch.move, this, "onMouseMove"),
 
 			// And these are called at the end of the drag
-			dojo.connect(d, "onmouseup",   this, "onMouseUp"),
-			dojo.connect(d, "ontouchend", this, "onMouseUp"),
+			dojo.connect(d, touch.release,   this, "onMouseUp"),
 
 			// cancel text selection and text dragging
 			dojo.connect(d, "ondragstart",   dojo.stopEvent),
@@ -48,9 +49,8 @@ dojo.declare("dojo.dnd.Mover", null, {
 		// e: Event
 		//		mouse/touch event
 		dojo.dnd.autoScroll(e);
-		var m = this.marginBox,
-			pos = e.touches ? e.touches[0] : e;
-		this.host.onMove(this, {l: m.l + pos.pageX, t: m.t + pos.pageY}, e);
+		var m = this.marginBox;
+		this.host.onMove(this, {l: m.l + e.pageX, t: m.t + e.pageY}, e);
 		dojo.stopEvent(e);
 	},
 	onMouseUp: function(e){
@@ -97,10 +97,9 @@ dojo.declare("dojo.dnd.Mover", null, {
 		if(h && h.onFirstMove){
 			h.onFirstMove(this, e);
 		}
-		
+
 		// Disconnect onmousemove and ontouchmove events that call this function
 		dojo.disconnect(this.events.shift());
-		dojo.disconnect(this.events.shift());
 	},
 	destroy: function(){
 		// summary:
diff --git a/dojo/dnd/Selector.js b/dojo/dnd/Selector.js
index dc83950..a4d9606 100644
--- a/dojo/dnd/Selector.js
+++ b/dojo/dnd/Selector.js
@@ -1,4 +1,9 @@
-define("dojo/dnd/Selector", ["dojo", "dojo/dnd/common", "dojo/dnd/Container"], function(dojo) {
+define(["../main", "./common", "./Container"], function(dojo) {
+	// module:
+	//		dojo/dnd/Selector
+	// summary:
+	//		TODOC
+
 
 /*
 	Container item states:
@@ -22,7 +27,7 @@ dojo.declare("dojo.dnd.__SelectorArgs", [dojo.dnd.__ContainerArgs], {
 dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 	// summary:
 	//		a Selector object, which knows how to select its children
-	
+
 	/*=====
 	// selection: Set<String>
 	//		The set of id's that are currently selected, such that this.selection[id] == 1
@@ -50,10 +55,10 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 			dojo.connect(this.node, "onmousedown", this, "onMouseDown"),
 			dojo.connect(this.node, "onmouseup",   this, "onMouseUp"));
 	},
-	
+
 	// object attributes (for markup)
 	singular: false,	// is singular property
-	
+
 	// methods
 	getSelectedNodes: function(){
 		// summary:
@@ -108,16 +113,16 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 	sync: function(){
 		// summary:
 		//		sync up the node list with the data map
-		
+
 		dojo.dnd.Selector.superclass.sync.call(this);
-		
+
 		// fix the anchor
 		if(this.anchor){
 			if(!this.getItem(this.anchor.id)){
 				this.anchor = null;
 			}
 		}
-		
+
 		// fix the selection
 		var t = [], e = dojo.dnd._empty;
 		for(var i in this.selection){
@@ -129,7 +134,7 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 		dojo.forEach(t, function(i){
 			delete this.selection[i];
 		}, this);
-		
+
 		return this;	// self
 	},
 	insertNodes: function(addSelected, data, before, anchor){
@@ -173,12 +178,6 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 		this.selection = this.anchor = null;
 	},
 
-	// markup methods
-	markupFactory: function(params, node){
-		params._skipStartup = true;
-		return new dojo.dnd.Selector(node, params);
-	},
-
 	// mouse events
 	onMouseDown: function(e){
 		// summary:
@@ -281,13 +280,13 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 		}
 	},
 	onMouseMove: function(e){
-		// summary
+		// summary:
 		//		event processor for onmousemove
 		// e: Event
 		//		mouse event
 		this.simpleSelection = false;
 	},
-	
+
 	// utilities
 	onOverEvent: function(){
 		// summary:
diff --git a/dojo/dnd/Source.js b/dojo/dnd/Source.js
index ce03d2c..05bb3ce 100644
--- a/dojo/dnd/Source.js
+++ b/dojo/dnd/Source.js
@@ -1,4 +1,12 @@
-define("dojo/dnd/Source", ["dojo", "dojo/dnd/Selector", "dojo/dnd/Manager"], function(dojo) {
+define(["../main", "./Selector", "./Manager"], function(dojo, Selector, Manager) {
+	// module:
+	//		dojo/dnd/Source
+	// summary:
+	//		TODOC
+
+/*=====
+Selector = dojo.dnd.Selector;
+=====*/
 
 /*
 	Container property:
@@ -59,10 +67,18 @@ dojo.dnd.__SourceArgs = function(){
 }
 =====*/
 
-dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
+// For back-compat, remove in 2.0.
+if(!dojo.isAsync){
+	dojo.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, {
 	// summary:
 	//		a Source object, which can be used as a DnD source, or a DnD target
-	
+
 	// object attributes (for markup)
 	isSource: true,
 	horizontal: false,
@@ -75,7 +91,7 @@ dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
 	delay: 0, // pixels
 	accept: ["text"],
 	generateText: true,
-	
+
 	constructor: function(/*DOMNode|String*/node, /*dojo.dnd.__SourceArgs?*/params){
 		// summary:
 		//		a constructor of the Source
@@ -120,7 +136,7 @@ dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
 			dojo.subscribe("/dnd/cancel", this, "onDndCancel")
 		];
 	},
-	
+
 	// methods
 	checkAcceptance: function(source, nodes){
 		// summary:
@@ -156,10 +172,10 @@ dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
 		//		the "copy" key was pressed
 		// self: Boolean?
 		//		optional flag that means that we are about to drop on itself
-		
+
 		if(keyPressed){ return true; }
 		if(arguments.length < 2){
-			self = this == dojo.dnd.manager().target;
+			self = this == Manager.manager().target;
 		}
 		if(self){
 			if(this.copyOnly){
@@ -178,12 +194,6 @@ dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
 		this.targetAnchor = null;
 	},
 
-	// markup methods
-	markupFactory: function(params, node){
-		params._skipStartup = true;
-		return new dojo.dnd.Source(node, params);
-	},
-
 	// mouse event processors
 	onMouseMove: function(e){
 		// summary:
@@ -192,7 +202,7 @@ dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
 		//		mouse event
 		if(this.isDragging && this.targetState == "Disabled"){ return; }
 		dojo.dnd.Source.superclass.onMouseMove.call(this, e);
-		var m = dojo.dnd.manager();
+		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)){
@@ -243,7 +253,7 @@ dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
 			dojo.dnd.Source.superclass.onMouseUp.call(this, e);
 		}
 	},
-	
+
 	// topic event processors
 	onDndSourceOver: function(source){
 		// summary:
@@ -256,7 +266,7 @@ dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
 				this._unmarkTargetAnchor();
 			}
 		}else if(this.isDragging){
-			var m = dojo.dnd.manager();
+			var m = Manager.manager();
 			m.canDrop(this.targetState != "Disabled" && (!this.current || m.source != this || !(this.current.id in this.selection)));
 		}
 	},
@@ -276,7 +286,7 @@ dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
 		var accepted = this.accept && this.checkAcceptance(source, nodes);
 		this._changeState("Target", accepted ? "" : "Disabled");
 		if(this == source){
-			dojo.dnd.manager().overSource(this);
+			Manager.manager().overSource(this);
 		}
 		this.isDragging = true;
 	},
@@ -310,7 +320,7 @@ dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
 		this._changeState("Source", "");
 		this._changeState("Target", "");
 	},
-	
+
 	// local events
 	onDrop: function(source, nodes, copy){
 		// summary:
@@ -321,7 +331,7 @@ dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
 		//		the list of transferred items
 		// copy: Boolean
 		//		copy items, if true, move items otherwise
-		
+
 		if(this != source){
 			this.onDropExternal(source, nodes, copy);
 		}else{
@@ -338,7 +348,7 @@ dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
 		//		the list of transferred items
 		// copy: Boolean
 		//		copy items, if true, move items otherwise
-		
+
 		var oldCreator = this._normalizedCreator;
 		// transferring nodes from the source to the target
 		if(this.creator){
@@ -383,7 +393,7 @@ dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
 		//		the list of transferred items
 		// copy: Boolean
 		//		copy items, if true, move items otherwise
-		
+
 		var oldCreator = this._normalizedCreator;
 		// transferring nodes within the single source
 		if(this.current && this.current.id in this.selection){
@@ -430,13 +440,13 @@ dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
 		//		called during the active DnD operation, when items
 		//		are dragged away from this target, and it is not disabled
 	},
-	
+
 	// utilities
 	onOverEvent: function(){
 		// summary:
 		//		this function is called once, when mouse is over our container
 		dojo.dnd.Source.superclass.onOverEvent.call(this);
-		dojo.dnd.manager().overSource(this);
+		Manager.manager().overSource(this);
 		if(this.isDragging && this.targetState != "Disabled"){
 			this.onDraggingOver();
 		}
@@ -445,7 +455,7 @@ dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
 		// summary:
 		//		this function is called once, when mouse is out of our container
 		dojo.dnd.Source.superclass.onOutEvent.call(this);
-		dojo.dnd.manager().outSource(this);
+		Manager.manager().outSource(this);
 		if(this.isDragging && this.targetState != "Disabled"){
 			this.onDraggingOut();
 		}
@@ -485,12 +495,12 @@ dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
 		//		checks if user clicked on "approved" items
 		// e: Event
 		//		mouse event
-		
+
 		// accept only the left mouse button
 		if(!dojo.mouseButtons.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; }
@@ -500,39 +510,4 @@ dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
 	}
 });
 
-dojo.declare("dojo.dnd.Target", dojo.dnd.Source, {
-	// summary: a Target object, which can be used as a DnD target
-	
-	constructor: function(node, params){
-		// summary:
-		//		a constructor of the Target --- see the `dojo.dnd.Source.constructor` for details
-		this.isSource = false;
-		dojo.removeClass(this.node, "dojoDndSource");
-	},
-
-	// markup methods
-	markupFactory: function(params, node){
-		params._skipStartup = true;
-		return new dojo.dnd.Target(node, params);
-	}
-});
-
-dojo.declare("dojo.dnd.AutoSource", dojo.dnd.Source, {
-	// summary:
-	//		a source that syncs its DnD nodes by default
-	
-	constructor: function(node, params){
-		// summary:
-		//		constructor of the AutoSource --- see the Source constructor for details
-		this.autoSync = true;
-	},
-
-	// markup methods
-	markupFactory: function(params, node){
-		params._skipStartup = true;
-		return new dojo.dnd.AutoSource(node, params);
-	}
-});
-
-return dojo.dnd.Source;
 });
diff --git a/dojo/dnd/Target.js b/dojo/dnd/Target.js
new file mode 100644
index 0000000..353ae2f
--- /dev/null
+++ b/dojo/dnd/Target.js
@@ -0,0 +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
+
+		constructor: function(node, params){
+			// summary:
+			//		a constructor of the Target --- see the `dojo.dnd.Source.constructor` for details
+			this.isSource = false;
+			dojo.removeClass(this.node, "dojoDndSource");
+		}
+	});
+});
diff --git a/dojo/dnd/TimedMoveable.js b/dojo/dnd/TimedMoveable.js
index 178aaf2..9a3d2f4 100644
--- a/dojo/dnd/TimedMoveable.js
+++ b/dojo/dnd/TimedMoveable.js
@@ -1,28 +1,31 @@
-define("dojo/dnd/TimedMoveable", ["dojo", "dojo/dnd/Moveable"], function(dojo) {
+define(["../main", "./Moveable"], function(dojo) {
+	// module:
+	//		dojo/dnd/TimedMoveable
+	// summary:
+	//		TODOC
 
-/*=====
-dojo.declare("dojo.dnd.__TimedMoveableArgs", [dojo.dnd.__MoveableArgs], {
-	// timeout: Number
-	//		delay move by this number of ms,
-	//		accumulating position changes during the timeout
-	timeout: 0
-});
-=====*/
+	/*=====
+	dojo.declare("dojo.dnd.__TimedMoveableArgs", [dojo.dnd.__MoveableArgs], {
+		// timeout: Number
+		//		delay move by this number of ms,
+		//		accumulating position changes during the timeout
+		timeout: 0
+	});
+	=====*/
 
-(function(){
 	// precalculate long expressions
 	var oldOnMove = dojo.dnd.Moveable.prototype.onMove;
-		
+
 	dojo.declare("dojo.dnd.TimedMoveable", dojo.dnd.Moveable, {
 		// summary:
 		//		A specialized version of Moveable to support an FPS throttling.
 		//		This class puts an upper restriction on FPS, which may reduce
 		//		the CPU load. The additional parameter "timeout" regulates
 		//		the delay before actually moving the moveable object.
-		
+
 		// object attributes (for markup)
 		timeout: 40,	// in ms, 40ms corresponds to 25 fps
-	
+
 		constructor: function(node, params){
 			// summary:
 			//		an object that makes a node moveable with a timer
@@ -30,23 +33,18 @@ dojo.declare("dojo.dnd.__TimedMoveableArgs", [dojo.dnd.__MoveableArgs], {
 			//		a node (or node's id) to be moved
 			// params: dojo.dnd.__TimedMoveableArgs
 			//		object with additional parameters.
-			
+
 			// sanitize parameters
 			if(!params){ params = {}; }
 			if(params.timeout && typeof params.timeout == "number" && params.timeout >= 0){
 				this.timeout = params.timeout;
 			}
 		},
-	
-		// markup methods
-		markupFactory: function(params, node){
-			return new dojo.dnd.TimedMoveable(node, params);
-		},
-	
+
 		onMoveStop: function(/* dojo.dnd.Mover */ mover){
 			if(mover._timer){
 				// stop timer
-				clearTimeout(mover._timer)
+				clearTimeout(mover._timer);
 				// reflect the last received position
 				oldOnMove.call(this, mover, mover._leftTop)
 			}
@@ -65,7 +63,7 @@ dojo.declare("dojo.dnd.__TimedMoveableArgs", [dojo.dnd.__MoveableArgs], {
 			}
 		}
 	});
-})();
 
-return dojo.dnd.TimedMoveable;
+	return dojo.dnd.TimedMoveable;
+	
 });
diff --git a/dojo/dnd/autoscroll.js b/dojo/dnd/autoscroll.js
index 8c96947..ffc612e 100644
--- a/dojo/dnd/autoscroll.js
+++ b/dojo/dnd/autoscroll.js
@@ -1,4 +1,9 @@
-define("dojo/dnd/autoscroll", ["dojo", "dojo/window"], function(dojo) {
+define(["../main", "../window"], function(dojo) {
+	// module:
+	//		dojo/dnd/autoscroll
+	// summary:
+	//		TODOC
+
 dojo.getObject("dnd", true, dojo);
 
 dojo.dnd.getViewport = dojo.window.getBox;
@@ -42,42 +47,63 @@ dojo.dnd.autoScrollNodes = function(e){
 	//		onmousemove 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);
-			if(s.overflow.toLowerCase() in dojo.dnd._validOverflow){
-				var b = dojo._getContentBox(n, s), t = dojo.position(n, true);
-				//console.log(b.l, b.t, t.x, t.y, n.scrollLeft, n.scrollTop);
-				var w = Math.min(dojo.dnd.H_TRIGGER_AUTOSCROLL, b.w / 2),
-					h = Math.min(dojo.dnd.V_TRIGGER_AUTOSCROLL, b.h / 2),
-					rx = e.pageX - t.x, ry = e.pageY - t.y, dx = 0, dy = 0;
+			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(overflow || overflowX || overflowY){
+				b = dojo._getContentBox(n, s);
+				t = dojo.position(n, true);
+			}
+			// overflow-x
+			if(overflow || overflowX){
+				w = Math.min(dojo.dnd.H_TRIGGER_AUTOSCROLL, b.w / 2);
+				rx = e.pageX - t.x;
 				if(dojo.isWebKit || dojo.isOpera){
 					// FIXME: this code should not be here, it should be taken into account
 					// either by the event fixing code, or the dojo.position()
 					// FIXME: this code doesn't work on Opera 9.5 Beta
 					rx += dojo.body().scrollLeft;
-					ry += dojo.body().scrollTop;
 				}
+				dx = 0;
 				if(rx > 0 && rx < b.w){
 					if(rx < w){
 						dx = -w;
 					}else if(rx > b.w - w){
 						dx = w;
 					}
+					oldLeft = n.scrollLeft;
+					n.scrollLeft = n.scrollLeft + dx;
+				}
+			}
+			// 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);
+				ry = e.pageY - t.y;
+				if(dojo.isWebKit || dojo.isOpera){
+					// FIXME: this code should not be here, it should be taken into account
+					// either by the event fixing code, or the dojo.position()
+					// FIXME: this code doesn't work on Opera 9.5 Beta
+					ry += dojo.body().scrollTop;
 				}
-				//console.log("ry =", ry, "b.h =", b.h, "h =", h);
+				dy = 0;
 				if(ry > 0 && ry < b.h){
 					if(ry < h){
 						dy = -h;
 					}else if(ry > b.h - h){
 						dy = h;
 					}
+					oldTop = n.scrollTop;
+					n.scrollTop  = n.scrollTop  + dy;
 				}
-				var oldLeft = n.scrollLeft, oldTop = n.scrollTop;
-				n.scrollLeft = n.scrollLeft + dx;
-				n.scrollTop  = n.scrollTop  + dy;
-				if(oldLeft != n.scrollLeft || oldTop != n.scrollTop){ return; }
 			}
+			if(dx || dy){ return; }
 		}
 		try{
 			n = n.parentNode;
@@ -88,5 +114,5 @@ dojo.dnd.autoScrollNodes = function(e){
 	dojo.dnd.autoScroll(e);
 };
 
-return dojo.dnd;
+	return dojo.dnd;
 });
diff --git a/dojo/dnd/common.js b/dojo/dnd/common.js
index 969a60d..0feba28 100644
--- a/dojo/dnd/common.js
+++ b/dojo/dnd/common.js
@@ -1,4 +1,9 @@
-define("dojo/dnd/common", ["dojo"], function(dojo) {
+define(["../main"], function(dojo) {
+	// module:
+	//		dojo/dnd/common
+	// summary:
+	//		TODOC
+
 dojo.getObject("dnd", true, dojo);
 
 dojo.dnd.getCopyKeyState = dojo.isCopyKey;
diff --git a/dojo/dnd/move.js b/dojo/dnd/move.js
index b0216cc..811216c 100644
--- a/dojo/dnd/move.js
+++ b/dojo/dnd/move.js
@@ -1,4 +1,9 @@
-define("dojo/dnd/move", ["dojo", "dojo/dnd/Mover", "dojo/dnd/Moveable"], function(dojo) {
+define(["../main", "./Mover", "./Moveable"], function(dojo) {
+	// module:
+	//		dojo/dnd/move
+	// summary:
+	//		TODOC
+
 
 /*=====
 dojo.declare("dojo.dnd.move.__constrainedMoveableArgs", [dojo.dnd.__MoveableArgs], {
@@ -17,11 +22,6 @@ dojo.declare("dojo.dnd.move.constrainedMoveable", dojo.dnd.Moveable, {
 	// object attributes (for markup)
 	constraints: function(){},
 	within: false,
-	
-	// markup methods
-	markupFactory: function(params, node){
-		return new dojo.dnd.move.constrainedMoveable(node, params);
-	},
 
 	constructor: function(node, params){
 		// summary:
@@ -74,11 +74,6 @@ dojo.declare("dojo.dnd.move.boxConstrainedMoveable", dojo.dnd.move.constrainedMo
 	// box:
 	//		object attributes (for markup)
 	box: {},
-	
-	// markup methods
-	markupFactory: function(params, node){
-		return new dojo.dnd.move.boxConstrainedMoveable(node, params);
-	},
 
 	constructor: function(node, params){
 		// summary:
@@ -106,11 +101,6 @@ dojo.declare("dojo.dnd.move.parentConstrainedMoveable", dojo.dnd.move.constraine
 	//		object attributes (for markup)
 	area: "content",
 
-	// markup methods
-	markupFactory: function(params, node){
-		return new dojo.dnd.move.parentConstrainedMoveable(node, params);
-	},
-
 	constructor: function(node, params){
 		// summary:
 		//		an object, which makes a node moveable
diff --git a/dojo/dojo.js b/dojo/dojo.js
index 55da409..698183b 100644
--- a/dojo/dojo.js
+++ b/dojo/dojo.js
@@ -1,211 +1,1854 @@
-// summary:
-//		This is the "source loader" for Dojo. This dojo.js ensures that all
-//		Base APIs are available once its execution is complete and attempts to
-//		automatically determine the correct host environment to use.
-// description:
-//		"dojo.js" is the basic entry point into the toolkit for all uses and
-//		users. The "source loader" is replaced by environment-specific builds
-//		and so you should not assume that built versions of the toolkit will
-//		function in all supported platforms (Browsers, Rhino, Spidermonkey,
-//		etc.). In most cases, users will receive pre-built dojo.js files which
-//		contain all of the Base APIs in a single file and which specialize for
-//		the Browser platform. After loading dojo.js, you will be able to do the
-//		following with the toolkit:
-//			All platforms:
-//				- load other packages (dojo core, dijit, dojox, and custom
-//				  modules) to better structure your code and take advantage of
-//				  the inventive capabilities developed by the broad Dojo
-//				  community
-//				- perform basic network I/O
-//				- use Dojo's powerful language supplementing APIs
-//				- take advantage of the Dojo event system to better structure
-//				  your application
-//			Browser only:
-//				- use Dojo's powerful and blisteringly-fast CSS query engine to
-//				  upgrade and active your web pages without embedding
-//				  JavaScript in your markup
-//				- get and set accurate information about element style
-//				- shorten the time it takes to build and manipulate DOM
-//				  structures with Dojo's HTML handling APIs
-//				- create more fluid UI transitions with Dojo's robust and
-//				  battle-tested animation facilities
-
-// NOTE:
-//		If you are reading this file, you have received a "source" build of
-//		Dojo. Unless you are a Dojo developer, it is very unlikely that this is
-//		what you want. While functionally identical to builds, source versions
-//		of Dojo load more slowly than pre-processed builds.
-//
-//		We strongly recommend that your applications always use a build of
-//		Dojo. To download such a build or find out how you can create
-//		customized, high-performance packages of Dojo suitable for use with
-//		your application, please visit:
-//
-//			http://dojotoolkit.org
-//
-//		Regards,
-//		The Dojo Team
-
-if(typeof dojo == "undefined"){
-	// only try to load Dojo if we don't already have one. Dojo always follows
-	// a "first Dojo wins" policy.
-	(function(){
-		var getRootNode = function(){
-			// attempt to figure out the path to dojo if it isn't set in the config
-			if(this["document"] && this["document"]["getElementsByTagName"]){
-				var scripts = document.getElementsByTagName("script");
-				var rePkg = /dojo\.js(\W|$)/i;
-				for(var i = 0; i < scripts.length; i++){
-					var src = scripts[i].getAttribute("src");
-					if(!src){ continue; }
-					var m = src.match(rePkg);
-					if(m){
-						return {
-							node: scripts[i],
-							root: src.substring(0, m.index)
-						};
-						/*
-						root = src.substring(0, m.index);
-						if(!this["djConfig"]){ djConfig = {}; }
-						djConfig["baseUrl"] = root;
-						break;
-						*/
-					}
+(function(
+	userConfig,
+	defaultConfig
+){
+	// summary:
+	//		This is the "source loader" and is the entry point for Dojo during development. You may also load Dojo with
+	//		any AMD-compliant loader via the package main module dojo/main.
+	// description:
+	//		This is the "source loader" for Dojo. It provides an AMD-compliant loader that can be configured
+	//		to operate in either synchronous or asynchronous modes. After the loader is defined, dojo is loaded
+	//		IAW the package main module dojo/main. In the event you wish to use a foreign loader, you may load dojo as a package
+	//		via the package main module dojo/main and this loader is not required; see dojo/package.json for details.
+	//
+	//		In order to keep compatibility with the v1.x line, this loader includes additional machinery that enables
+	//		the dojo.provide, dojo.require et al API. This machinery is loaded by default, but may be dynamically removed
+	//		via the has.js API and statically removed via the build system.
+	//
+	//		This loader includes sniffing machinery to determine the environment; the following environments are supported:
+	//
+	//			* 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.
+
+	// Design and Implementation Notes
+	//
+	// This is a dojo-specific adaption of bdLoad, donated to the dojo foundation by Altoviso LLC.
+	//
+	// This function defines an AMD-compliant (http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition)
+	// loader that can be configured to operate in either synchronous or asynchronous modes.
+	//
+	// Since this machinery implements a loader, it does not have the luxury of using a load system and/or
+	// leveraging a utility library. This results in an unpleasantly long file; here is a road map of the contents:
+	//
+	//	 1. Small library for use implementing the loader.
+	//	 2. Define the has.js API; this is used throughout the loader to bracket features.
+	//	 3. Define the node.js and rhino sniffs and sniff.
+	//	 4. Define the loader's data.
+	//	 5. Define the configuration machinery.
+	//	 6. Define the script element sniffing machinery and sniff for configuration data.
+	//	 7. Configure the loader IAW the provided user, default, and sniffing data.
+	//	 8. Define the global require function.
+	//	 9. Define the module resolution machinery.
+	//	10. Define the module and plugin module definition machinery
+	//	11. Define the script injection machinery.
+	//	12. Define the window load detection.
+	//	13. Define the logging API.
+	//	14. Define the tracing API.
+	//	16. Define the AMD define function.
+	//	17. Define the dojo v1.x provide/require machinery--so called "legacy" modes.
+	//	18. Publish global variables.
+	//
+	// Language and Acronyms and Idioms
+	//
+	// moduleId: a CJS module identifier, (used for public APIs)
+	// mid: moduleId (used internally)
+	// packageId: a package identifier (used for public APIs)
+	// pid: packageId (used internally); the implied system or default package has pid===""
+	// pack: package is used internally to reference a package object (since javascript has reserved words including "package")
+	// prid: plugin resource identifier
+	// The integer constant 1 is used in place of true and 0 in place of false.
+
+	// define a minimal library to help build the loader
+	var	noop = function(){
+		},
+
+		isEmpty = function(it){
+			for(var p in it){
+				return 0;
+			}
+			return 1;
+		},
+
+		toString = {}.toString,
+
+		isFunction = function(it){
+			return toString.call(it) == "[object Function]";
+		},
+
+		isString = function(it){
+			return toString.call(it) == "[object String]";
+		},
+
+		isArray = function(it){
+			return toString.call(it) == "[object Array]";
+		},
+
+		forEach = function(vector, callback){
+			if(vector){
+				for(var i = 0; i < vector.length;){
+					callback(vector[i++]);
 				}
 			}
+		},
+
+		mix = function(dest, src){
+			for(var p in src){
+				dest[p] = src[p];
+			}
+			return dest;
+		},
+
+		makeError = function(error, info){
+			return mix(new Error(error), {src:"dojoLoader", info:info});
+		},
+
+		uidSeed = 1,
+
+		uid = function(){
+			// Returns a unique indentifier (within the lifetime of the document) of the form /_d+/.
+			return "_" + uidSeed++;
+		},
+
+		// FIXME: how to doc window.require() api
+
+		// 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
+			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
+		){
+			return contextRequire(config, dependencies, callback, 0, req);
+		},
+
+		// the loader uses the has.js API to control feature inclusion/exclusion; define then use throughout
+		global = this,
+
+		doc = global.document,
+
+		element = doc && doc.createElement("DiV"),
+
+		has = req.has = function(name){
+			return isFunction(hasCache[name]) ? (hasCache[name] = hasCache[name](global, doc, element)) : hasCache[name];
+		},
+
+		hasCache = has.cache = defaultConfig.hasCache;
+
+	has.add = function(name, test, now, force){
+		(hasCache[name]===undefined || force) && (hasCache[name] = test);
+		return now && has(name);
+	};
+
+	has.add("host-node", typeof process == "object" && /node(\.exe)?$/.test(process.execPath));
+	if(has("host-node")){
+		// fixup the default config for node.js environment
+		require("./_base/configNode.js").config(defaultConfig);
+		// remember node's require (with respect to baseUrl==dojo's root)
+		defaultConfig.loaderPatch.nodeRequire = require;
+	}
+
+	has.add("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;){
+			arg = (rhinoArgs[i++] + "").split("=");
+			if(arg[0] == "baseUrl"){
+				baseUrl = arg[1];
+				break;
+			}
 		}
+		load(baseUrl + "/_base/configRhino.js");
+		rhinoDojoConfig(defaultConfig, baseUrl, rhinoArgs);
+	}
+
+	// userConfig has tests override defaultConfig has tests; do this after the environment detection because
+	// the environment detection usually sets some has feature values in the hasCache.
+	for(var p in userConfig.has){
+		has.add(p, userConfig.has[p], 0, 1);
+	}
+
+	//
+	// define the loader data
+	//
 
-		// we default to a browser environment if we can't figure it out
-		var hostEnv = "browser", cfg = "dojoConfig";
-		
-		 // FIXME, 2.0: remove backwards compat djConfig global
-		if(typeof this[cfg] === "undefined" && typeof djConfig !== "undefined"){
-			this[cfg] = djConfig;
+	// the loader will use these like symbols if the loader has the traceApi; otherwise
+	// define magic numbers so that modules can be provided as part of defaultConfig
+	var	requested = 1,
+		arrived = 2,
+		nonmodule = 3,
+		executing = 4,
+		executed = 5;
+
+	if(has("dojo-trace-api")){
+		// these make debugging nice; but using strings for symbols is a gross rookie error; don't do it for production code
+		requested = "requested";
+		arrived = "arrived";
+		nonmodule = "not-a-module";
+		executing = "executing";
+		executed = "executed";
+	}
+
+	var legacyMode = 0,
+		sync = "sync",
+		xd = "xd",
+		syncExecStack = [],
+		dojoRequirePlugin = 0,
+		checkDojoRequirePlugin = noop,
+		transformToAmd = noop,
+		getXhr;
+	if(has("dojo-sync-loader")){
+		req.isXdUrl = noop;
+
+		req.initSyncLoader = function(dojoRequirePlugin_, checkDojoRequirePlugin_, transformToAmd_){
+			if(!dojoRequirePlugin){
+				dojoRequirePlugin = dojoRequirePlugin_;
+				checkDojoRequirePlugin = checkDojoRequirePlugin_;
+				transformToAmd = transformToAmd_;
+			}
+			return {
+				sync:sync,
+				xd:xd,
+				arrived:arrived,
+				nonmodule:nonmodule,
+				executing:executing,
+				executed:executed,
+				syncExecStack:syncExecStack,
+				modules:modules,
+				execQ:execQ,
+				getModule:getModule,
+				injectModule:injectModule,
+				setArrived:setArrived,
+				signal:signal,
+				finishExec:finishExec,
+				execModule:execModule,
+				dojoRequirePlugin:dojoRequirePlugin,
+				getLegacyMode:function(){return legacyMode;},
+				holdIdle:function(){checkCompleteGuard++;},
+				releaseIdle:function(){checkIdle();}
+			};
+		};
+
+		if(has("dom")){
+			// in legacy sync mode, the loader needs a minimal XHR library to load dojo/_base/loader and dojo/_base/xhr
+
+			var locationProtocol = location.protocol,
+				locationHost = location.host,
+				fileProtocol = !locationHost;
+			req.isXdUrl = function(url){
+				if(fileProtocol || /^\./.test(url)){
+					// begins with a dot is always relative to page URL; therefore not xdomain
+					return false;
+				}
+				if(/^\/\//.test(url)){
+					// for v1.6- backcompat, url starting with // indicates xdomain
+					return true;
+				}
+				// get protocol and host
+				var match = url.match(/^([^\/\:]+\:)\/\/([^\/]+)/);
+				return match && (match[1] != locationProtocol || 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:");
+			has.add("native-xhr", typeof XMLHttpRequest != "undefined");
+			if(has("native-xhr") && !has("dojo-force-activex-xhr")){
+				getXhr = function(){
+					return new XMLHttpRequest();
+				};
+			}else{
+				// if in the browser an old IE; find an xhr
+				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
+					}
+				}
+				getXhr = function(){
+					return new ActiveXObject(progid);
+				};
+			}
+			req.getXhr = getXhr;
+
+			has.add("dojo-gettext-api", 1);
+			req.getText = function(url, async, onLoad){
+				var xhr = getXhr();
+				xhr.open('GET', fixupUrl(url), false);
+				xhr.send(null);
+				if(xhr.status == 200 || (!location.host && !xhr.status)){
+					if(onLoad){
+						onLoad(xhr.responseText, async);
+					}
+				}else{
+					throw makeError("xhrFailed", xhr.status);
+				}
+				return xhr.responseText;
+			};
 		}
-		if(typeof dojoConfig !== "undefined" && dojoConfig.hostEnv){
-			hostEnv = dojoConfig.hostEnv;
-		}else if(
-			typeof this["load"] == "function" &&
-			(
-				typeof this["Packages"] == "function" ||
-				typeof this["Packages"] == "object"
-			)
-		){
-			// Rhino environments make Java code available via the Packages
-			// object. Obviously, this check could be "juiced" if someone
-			// creates a "Packages" object and a "load" function, but we've
-			// never seen this happen in the wild yet.
-			hostEnv = "rhino";
-		}else if(typeof this["load"] == "function"){
-			// Spidermonkey has a very spartan environment. The only thing we
-			// can count on from it is a "load" function.
-			hostEnv = "spidermonkey";
+	}else{
+		req.async = 1;
+	}
+
+	//
+	// loader eval
+	//
+	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);');
+
+	req.eval =
+		function(text, hint){
+			return eval_(text + "\r\n////@ sourceURL=" + hint);
+		};
+
+	//
+	// loader micro events API
+	//
+	var listenerQueues = {},
+		error = "error",
+		signal = req.signal = function(type, args){
+			var queue = listenerQueues[type];
+			// notice we run a copy of the queue; this allows listeners to add/remove
+			// other listeners without affecting this particular signal
+			forEach(queue && queue.slice(0), function(listener){
+				listener.apply(null, isArray(args) ? args : [args]);
+			});
+		},
+		on = req.on = function(type, listener){
+			// notice a queue is not created until a client actually connects
+			var queue = listenerQueues[type] || (listenerQueues[type] = []);
+			queue.push(listener);
+			return {
+				remove:function(){
+					for(var i = 0; i<queue.length; i++){
+						if(queue[i]===listener){
+							queue.splice(i, 1);
+							return;
+						}
+					}
+				}
+			};
+		};
+
+	// configuration machinery; with an optimized/built defaultConfig, all configuration machinery can be discarded
+	// lexical variables hold key loader data structures to help with minification; these may be completely,
+	// one-time initialized by defaultConfig for optimized/built versions
+	var
+		aliases
+			// a vector of pairs of [regexs or string, replacement] => (alias, actual)
+			= [],
+
+		paths
+			// CommonJS paths
+			= {},
+
+		pathsMapProg
+			// list of (from-path, to-path, regex, length) derived from paths;
+			// a "program" to apply paths; see computeMapProg
+			= [],
+
+		packs
+			// a map from packageId to package configuration object; see fixupPackageInfo
+			= {},
+
+		packageMap
+			// map from package name to local-installed package name
+			= {},
+
+		packageMapProg
+			// list of (from-package, to-package, regex, length) derived from packageMap;
+			// a "program" to apply paths; see computeMapProg
+			= [],
+
+		modules
+			// A hash:(mid) --> (module-object) the module namespace
+			//
+			// pid: the package identifier to which the module belongs (e.g., "dojo"); "" indicates the system or default package
+			// 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
+			// 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
+			// 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.
+			//
+			// 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.
+			//
+			// 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
+			//
+			// 5. Evaluated: the module was defined via define and the loader has evaluated the factory and computed a result.
+			= {},
+
+		cacheBust
+			// query string to append to module URLs to bust browser cache
+			= "",
+
+		cache
+			// hash:(mid)-->(function)
+			//
+			// 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
+			 = {},
+
+		pendingCacheInsert
+			// hash:(mid)-->(function)
+			//
+			// Gives a set of cache modules pending entry into cache. When cached modules are published to the loader, they are
+			// entered into pendingCacheInsert; modules are then pressed into cache upon (1) AMD define or (2) upon receiving another
+			// independent set of cached modules. (1) is the usual case, and this case allows normalizing mids given in the pending
+			// cache for the local configuration, possibly relocating modules.
+			 = {},
+
+		dojoSniffConfig
+			// map of configuration variables
+			// give the data-dojo-config as sniffed from the document (if any)
+			= {};
+
+	if(has("dojo-config-api")){
+		var consumePendingCacheInsert = function(referenceModule){
+				for(var p in pendingCacheInsert){
+					var match = p.match(/^url\:(.+)/);
+					if(match){
+						cache[toUrl(match[1], referenceModule)] =  pendingCacheInsert[p];
+					}else if(p!="*noref"){
+						cache[getModuleInfo(p, referenceModule).mid] = pendingCacheInsert[p];
+					}
+				}
+				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.
+				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;
+					}
+				}
+				dest.sort(function(lhs, rhs){
+					return rhs[0].length - lhs[0].length;
+				});
+				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
+				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);
+
+				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){
+				for(var p in config){
+					if(p=="waitSeconds"){
+						req.waitms = (config[p] || 0) * 1000;
+					}
+					if(p=="cacheBust"){
+						cacheBust = config[p] ? (isString(config[p]) ? config[p] : (new Date()).getTime() + "") : "";
+					}
+					if(p=="baseUrl" || p=="combo"){
+						req[p] = config[p];
+					}
+					if(has("dojo-sync-loader") && p=="async"){
+						// falsy or "sync" => legacy sync loader
+						// "xd" => sync but loading xdomain tree and therefore loading asynchronously (not configurable, set automatically by the loader)
+						// "legacyAsync" => permanently in "xd" by choice
+						// "debugAtAllCosts" => trying to load everything via script injection (not implemented)
+						// 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.async = !legacyMode;
+					}
+					if(config[p]!==hasCache){
+						// accumulate raw config info for client apps which can use this to pass their own config
+						req.rawConfig[p] = config[p];
+						p!="has" && has.add("config-"+p, config[p], 0, booting);
+					}
+				}
+
+				// make sure baseUrl exists
+				if(!req.baseUrl){
+					req.baseUrl = "./";
+				}
+				// make sure baseUrl ends with a slash
+				if(!/\/$/.test(req.baseUrl)){
+					req.baseUrl += "/";
+				}
+
+				// now do the special work for has, packages, packagePaths, paths, aliases, and cache
+
+				for(p in config.has){
+					has.add(p, config.has[p], 0, booting);
+				}
+
+				// 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(baseUrl in config.packagePaths){
+					forEach(config.packagePaths[baseUrl], function(packageInfo){
+						fixupPackageInfo(packageInfo, baseUrl + "/");
+					});
+				}
+
+				// 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);
+				});
+
+				// mix any packageMap config item and recompute the internal packageMapProg
+				computeMapProg(mix(packageMap, config.packageMap), packageMapProg);
+
+				// push in any new cache values
+				if(config.cache){
+					consumePendingCacheInsert();
+					pendingCacheInsert = config.cache;
+					if(config.cache["*noref"]){
+						consumePendingCacheInsert();
+					}
+				}
+
+				signal("config", [config, req.rawConfig]);
+			};
+
+		//
+		// execute the various sniffs
+		//
+
+		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];
+						}
+					}
+				}
+			}
 		}
-		var tmps = ["bootstrap.js", "loader.js", "hostenv_"+hostEnv+".js"];
-		if (this.Jaxer && this.Jaxer.isOnServer) {
-			this.load = Jaxer.load;
+
+		if(has("dojo-test-sniff")){
+			// pass down doh.testConfig from parent as if it were a data-dojo-config
+			try{
+				if(window.parent != window && window.parent.require){
+					var doh = window.parent.require("doh");
+					doh && mix(dojoSniffConfig, doh.testConfig);
+				}
+			}catch(e){}
 		}
-	
-		if(
-			this[cfg]&&
-			(
-				dojoConfig["forceXDomain"] ||
-				dojoConfig["useXDomain"]
-			)
-		){
-			tmps.push("loader_xd.js");
+
+		// configure the loader; let the user override defaults
+		req.rawConfig = {};
+		config(defaultConfig, 1);
+		config(userConfig, 1);
+		config(dojoSniffConfig, 1);
+
+		if(has("dojo-cdn")){
+			packs.dojo.location = dojoDir;
+			packs.dijit.location = dojoDir + "../dijit/";
+			packs.dojox.location = dojoDir + "../dojox/";
 		}
-	
-		if(this[cfg] && dojoConfig["baseUrl"]){
-			// if the user explicitly tells us where Dojo has been loaded from
-			// (or should be loaded from) via djConfig, skip the auto-detection
-			// routines.
-			var root = dojoConfig["baseUrl"];
-		}else{
-			var root = "./";
-			if(hostEnv === "spidermonkey"){
-				// auto-detect the base path via an exception. Hack!
+
+	}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;
+		modules = defaultConfig.modules;
+		cache = defaultConfig.cache;
+		cacheBust = defaultConfig.cacheBust;
+
+		// remember the default config for other processes (e.g., dojo/config)
+		req.rawConfig = defaultConfig;
+	}
+
+
+	if(has("dojo-combo-api")){
+		req.combo = req.combo || {add:noop};
+		var	comboPending = 0,
+			combosPending = [],
+			comboPendingTimer = null;
+	}
+
+
+	// 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();
+		},
+
+		contextRequire = function(a1, a2, a3, referenceModule, contextRequire){
+			var module, syntheticMid;
+			if(isString(a1)){
+				// signature is (moduleId)
+				module = getModule(a1, referenceModule, true);
+				if(module && module.executed){
+					return module.result;
+				}
+				throw makeError("undefinedModule", a1);
+			}
+			if(!isArray(a1)){
+				// a1 is a configuration
+				config(a1);
+
+				// juggle args; (a2, a3) may be (dependencies, callback)
+				a1 = a2;
+				a2 = a3;
+			}
+			if(isArray(a1)){
+				// signature is (requestList [,callback])
+				if(!a1.length){
+					a2 && a2();
+				}else{
+					syntheticMid = "require*" + uid();
+
+					// 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));
+					}
+
+					// construct a synthetic module to control execution of the requestList, and, optionally, callback
+					module = mix(makeModuleInfo("", syntheticMid, 0, ""), {
+						injected: arrived,
+						deps: deps,
+						def: a2 || noop,
+						require: referenceModule ? referenceModule.require : req
+					});
+					modules[module.mid] = module;
+
+					// checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies
+					injectDependencies(module);
+
+					// try to immediately execute
+					// 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();
+					if(!module.executed){
+						// some deps weren't on board or circular dependency detected and strict; therefore, push into the execQ
+						execQ.push(module);
+					}
+					checkComplete();
+				}
+			}
+			return contextRequire;
+		},
+
+		createRequire = function(module){
+			if(!module){
+				return req;
+			}
+			var result = module.require;
+			if(!result){
+				result = function(a1, a2, a3){
+					return contextRequire(a1, a2, a3, module, result);
+				};
+				module.require = mix(result, req);
+				result.module = module;
+				result.toUrl = function(name){
+					return toUrl(name, module);
+				};
+				result.toAbsMid = function(mid){
+					return toAbsMid(mid, module);
+				};
+				if(has("dojo-undef-api")){
+					result.undef = function(mid){
+						req.undef(mid, module);
+					};
+				}
+			}
+			return result;
+		},
+
+		execQ =
+			// The list of modules that need to be evaluated.
+			[],
+
+		defQ =
+			// The queue of define arguments sent to loader.
+			[],
+
+		waiting =
+			// The set of modules upon which the loader is waiting for definition to arrive
+			{},
+
+		setRequested = function(module){
+			module.injected = requested;
+			waiting[module.mid] = 1;
+			if(module.url){
+				waiting[module.url] = module.pack || 1;
+			}
+		},
+
+		setArrived = function(module){
+			module.injected = arrived;
+			delete waiting[module.mid];
+			if(module.url){
+				delete waiting[module.url];
+			}
+			if(isEmpty(waiting)){
+				clearTimer();
+				has("dojo-sync-loader") && legacyMode==xd && (legacyMode = sync);
+			}
+		},
+
+		execComplete = req.idle =
+			// says the loader has completed (or not) its work
+			function(){
+				return !defQ.length && isEmpty(waiting) && !execQ.length && !checkCompleteGuard;
+			},
+
+		runMapProg = function(targetMid, map){
+			// search for targetMid in map; return the map item if found; falsy otherwise
+			for(var i = 0; i < map.length; i++){
+				if(map[i][2].test(targetMid)){
+					return map[i];
+				}
+			}
+			return 0;
+		},
+
+		compactPath = function(path){
+			var result = [],
+				segment, lastSegment;
+			path = path.replace(/\\/g, '/').split('/');
+			while(path.length){
+				segment = path.shift();
+				if(segment==".." && result.length && lastSegment!=".."){
+					result.pop();
+					lastSegment = result[result.length - 1];
+				}else if(segment!="."){
+					result.push(lastSegment= segment);
+				} // else ignore "."
+			}
+			return result.join("/");
+		},
+
+		makeModuleInfo = function(pid, mid, pack, url, cacheId){
+			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};
+			}else{
+				return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0, cacheId:cacheId};
+			}
+		},
+
+		getModuleInfo_ = function(mid, referenceModule, packs, modules, baseUrl, packageMapProg, pathsMapProg, 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;
+			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
+				return makeModuleInfo(0, mid, 0, mid);
+			}else{
+				// relative module ids are relative to the referenceModule; get rid of any dots
+				mid = compactPath(isRelative ? (referenceModule.mid + "/../" + mid) : mid);
+				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);
+				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;
+					}
+					midInPackage = mid;
+					cacheId = pack.reverseName + "/" + mid;
+					mid = pid + "/" + mid;
+				}else{
+					pid = "";
+				}
+
+				// search aliases
+				var candidateLength = 0,
+					candidate = 0;
+				forEach(aliases, function(pair){
+					var match = mid.match(pair[0]);
+					if(match && match.length>candidateLength){
+						candidate = isFunction(pair[1]) ? mid.replace(pair[0], pair[1]) : pair[1];
+					}
+				});
+				if(candidate){
+					return getModuleInfo_(candidate, 0, packs, modules, baseUrl, packageMapProg, pathsMapProg, alwaysCreate);
+				}
+
+				result = modules[mid];
+				if(result){
+					return alwaysCreate ? makeModuleInfo(result.pid, result.mid, result.pack, result.url, cacheId) : 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
+
+			mapItem = runMapProg(mid, pathsMapProg);
+			if(mapItem){
+				url = mapItem[1] + mid.substring(mapItem[3] - 1);
+			}else if(pid){
+				url = pack.location + "/" + midInPackage;
+			}else if(has("config-tlmSiblingOfDojo")){
+				url = "../" + mid;
+			}else{
+				url = mid;
+			}
+			// if result is not absolute, add baseUrl
+			if(!(/(^\/)|(\:)/.test(url))){
+				url = baseUrl + url;
+			}
+			url += ".js";
+			return makeModuleInfo(pid, mid, pack, compactPath(url), cacheId);
+		},
+
+		getModuleInfo = function(mid, referenceModule){
+			return getModuleInfo_(mid, referenceModule, packs, modules, req.baseUrl, packageMapProg, pathsMapProg);
+		},
+
+		resolvePluginResourceId = function(plugin, prid, referenceModule){
+			return plugin.normalize ? plugin.normalize(prid, function(mid){return toAbsMid(mid, referenceModule);}) : toAbsMid(prid, referenceModule);
+		},
+
+		dynamicPluginUidGenerator = 0,
+
+		getModule = function(mid, referenceModule, immediate){
+			// compute and optionally construct (if necessary) the module implied by the mid with respect to referenceModule
+			var match, plugin, prid, result;
+			match = mid.match(/^(.+?)\!(.*)$/);
+			if(match){
+				// name was <plugin-module>!<plugin-resource-id>
+				plugin = getModule(match[1], referenceModule, immediate);
+
+				if(has("dojo-sync-loader") && legacyMode == sync && !plugin.executed){
+					injectModule(plugin);
+					if(plugin.injected===arrived && !plugin.executed){
+						checkCompleteGuard++;
+						execModule(plugin);
+						checkIdle();
+					}
+					if(plugin.executed){
+						promoteModuleToPlugin(plugin);
+					}else{
+						// we are in xdomain mode for some reason
+						execQ.unshift(plugin);
+					}
+				}
+
+
+
+				if(plugin.executed === executed && !plugin.load){
+					// executed the module not knowing it was a plugin
+					promoteModuleToPlugin(plugin);
+				}
+
+				// if the plugin has not been loaded, then can't resolve the prid and  must assume this plugin is dynamic until we find out otherwise
+				if(plugin.load){
+					prid = resolvePluginResourceId(plugin, match[2], referenceModule);
+					mid = (plugin.mid + "!" + (plugin.dynamic ? ++dynamicPluginUidGenerator + "!" : "") + prid);
+				}else{
+					prid = match[2];
+					mid = plugin.mid + "!" + (++dynamicPluginUidGenerator) + "!waitingForPlugin";
+				}
+				result = {plugin:plugin, mid:mid, req:createRequire(referenceModule), prid:prid};
+			}else{
+				result = getModuleInfo(mid, referenceModule);
+			}
+			return modules[result.mid] || (!immediate && (modules[result.mid] = result));
+		},
+
+		toAbsMid = req.toAbsMid = function(mid, referenceModule){
+			return getModuleInfo(mid, referenceModule).mid;
+		},
+
+		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),
+				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);
+		},
+
+		nonModuleProps = {
+			injected: arrived,
+			executed: executed,
+			def: nonmodule,
+			result: nonmodule
+		},
+
+		makeCjs = function(mid){
+			return modules[mid] = mix({mid:mid}, nonModuleProps);
+		},
+
+		cjsRequireModule = makeCjs("require"),
+		cjsExportsModule = makeCjs("exports"),
+		cjsModuleModule = makeCjs("module"),
+
+		runFactory = function(module, args){
+			req.trace("loader-run-factory", [module.mid]);
+			var factory = module.def,
+				result;
+			has("dojo-sync-loader") && syncExecStack.unshift(module);
+			if(has("config-dojo-loader-catches")){
 				try{
-					throw new Error("");
+					result= isFunction(factory) ? factory.apply(null, args) : factory;
 				}catch(e){
-					root = String(e.fileName || e.sourceURL).split("dojo.js")[0];
+					signal(error, module.result = makeError("factoryThrew", [module, e]));
 				}
+			}else{
+				result= isFunction(factory) ? factory.apply(null, args) : factory;
 			}
-			if(!this[cfg]){
-				dojoConfig = { baseUrl: root };
+			module.result = result===undefined && module.cjs ? module.cjs.exports : result;
+			has("dojo-sync-loader") && syncExecStack.shift(module);
+		},
+
+		abortExec = {},
+
+		defOrder = 0,
+
+		promoteModuleToPlugin = function(pluginModule){
+			var plugin = pluginModule.result;
+			pluginModule.dynamic = plugin.dynamic;
+			pluginModule.normalize = plugin.normalize;
+			pluginModule.load = plugin.load;
+			return pluginModule;
+		},
+
+		resolvePluginLoadQ = function(plugin){
+			// plugins is a newly executed module that has a loadQ waiting to run
+
+			// step 1: traverse the loadQ and fixup the mid and prid; remember the map from original mid to new mid
+			// recall the original mid was created before the plugin was on board and therefore it was impossible to
+			// compute the final mid; accordingly, prid may or may not change, but the mid will definitely change
+			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),
+					mid = plugin.dynamic ? pseudoPluginResource.mid.replace(/waitingForPlugin$/, prid) : (plugin.mid + "!" + prid),
+					pluginResource = mix(mix({}, pseudoPluginResource), {mid:mid, prid:prid, injected:0});
+				if(!modules[mid]){
+					// create a new (the real) plugin resource and inject it normally now that the plugin is on board
+					injectPlugin(modules[mid] = pluginResource);
+				} // else this was a duplicate request for the same (plugin, rid) for a nondynamic plugin
+
+				// pluginResource is really just a placeholder with the wrong mid (because we couldn't calculate it until the plugin was on board)
+				// mark is as arrived and delete it from modules; the real module was requested above
+				map[pseudoPluginResource.mid] = modules[mid];
+				setArrived(pseudoPluginResource);
+				delete modules[pseudoPluginResource.mid];
+			});
+			plugin.loadQ = 0;
+
+			// step2: replace all references to any placeholder modules with real modules
+			var substituteModules = function(module){
+				for(var replacement, deps = module.deps || [], i = 0; i<deps.length; i++){
+					replacement = map[deps[i].mid];
+					if(replacement){
+						deps[i] = replacement;
+					}
+				}
+			};
+			for(var p in modules){
+				substituteModules(modules[p]);
 			}
-	
-			// attempt to figure out the path to dojo if it isn't set in the config
-			if(this["document"] && this["document"]["getElementsByTagName"]){
-				var root = getRootNode().root;
-				if(!this[cfg]){ dojoConfig = {}; }
-				dojoConfig["baseUrl"] = root;
+			forEach(execQ, substituteModules);
+		},
+
+		finishExec = function(module){
+			req.trace("loader-finish-exec", [module.mid]);
+			module.executed = executed;
+			module.defOrder = defOrder++;
+			has("dojo-sync-loader") && forEach(module.provides, function(cb){ cb(); });
+			if(module.loadQ){
+				// the module was a plugin
+				promoteModuleToPlugin(module);
+				resolvePluginLoadQ(module);
 			}
+			// remove all occurences of this module from the execQ
+			for(i = 0; i < execQ.length;){
+				if(execQ[i] === module){
+					execQ.splice(i, 1);
+				}else{
+					i++;
+				}
+			}
+		},
+
+		circleTrace = [],
+
+		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("->")]);
+				return (!module.def || strict) ? abortExec :  (module.cjs && module.cjs.exports);
+			}
+			// at this point the module is either not executed or fully executed
+
+
+			if(!module.executed){
+				if(!module.def){
+					return abortExec;
+				}
+				var mid = module.mid,
+					deps = module.deps || [],
+					arg, argResult,
+					args = [],
+					i = 0;
+
+				if(has("dojo-trace-api")){
+					circleTrace.push(mid);
+					req.trace("loader-exec-module", ["exec", circleTrace.length, mid]);
+				}
+
+				// 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
+				// 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++];
+					argResult = ((arg === cjsRequireModule) ? createRequire(module) :
+									((arg === cjsExportsModule) ? module.cjs.exports :
+										((arg === cjsModuleModule) ? module.cjs :
+											execModule(arg, strict))));
+					if(argResult === abortExec){
+						module.executed = 0;
+						req.trace("loader-exec-module", ["abort", mid]);
+						has("dojo-trace-api") && circleTrace.pop();
+						return abortExec;
+					}
+					args.push(argResult);
+				}
+				runFactory(module, args);
+				finishExec(module);
+			}
+			// at this point the module is guaranteed fully executed
+
+			has("dojo-trace-api") && circleTrace.pop();
+			return module.result;
+		},
+
+
+		checkCompleteGuard =  0,
+
+		checkComplete = function(){
+			// keep going through the execQ as long as at least one factory is executed
+			// plugins, recursion, cached modules all make for many execution path possibilities
+			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++;
+				}
+			}
+			checkIdle();
+		},
+
+		checkIdle = function(){
+			checkCompleteGuard--;
+			if(execComplete()){
+				signal("idle", []);
+			}
+		};
+
+
+	if(has("dojo-undef-api")){
+		req.undef = function(moduleId, referenceModule){
+			// In order to reload a module, it must be undefined (this routine) and then re-requested.
+			// This is useful for testing frameworks (at least).
+			var module = getModule(moduleId, referenceModule);
+			setArrived(module);
+			delete modules[module.mid];
+		};
+	}
+
+	if(has("dojo-inject-api")){
+		if(has("dojo-loader-eval-hint-url")===undefined){
+			has.add("dojo-loader-eval-hint-url", 1);
 		}
-		// FIXME: should we be adding the lang stuff here so we can count on it
-		// before the bootstrap stuff?
-		for(var x=0; x < tmps.length; x++){
-			tmps[x] = root+"_base/_loader/"+tmps[x];
-		}
-		// the "_base.js" file ensures that the rest of Dojo Base is available.
-		// It counts on the package system functioning in order to work, so add
-		// it last
-		tmps.push(root+"_base.js");
 
-		var lastRoot;
-		var isOpera = 0;
-		var isWebKit = 0;
+		var fixupUrl= function(url){
+				url += ""; // make sure url is a Javascript string (some paths may be a Java string)
+				return url + (cacheBust ? ((/\?/.test(url) ? "&" : "?") + cacheBust) : "");
+			},
 
-		if(hostEnv == "browser"){
-			try{
-				lastRoot = getRootNode().node;
-				var ua = navigator.userAgent;
-				isOpera = (ua.indexOf("Opera") >= 0);
-				isWebKit = (ua.indexOf("WebKit") >= 0);
-			}catch(e){ /* squelch */ }
+			injectPlugin = function(
+				module
+			){
+				// injects the plugin module given by module; may have to inject the plugin itself
+				var plugin = module.plugin;
+
+				if(plugin.executed === executed && !plugin.load){
+					// executed the module not knowing it was a plugin
+					promoteModuleToPlugin(plugin);
+				}
+
+				var onLoad = function(def){
+						module.result = def;
+						setArrived(module);
+						finishExec(module);
+						checkComplete();
+					};
+
+				setRequested(module);
+				if(plugin.load){
+					plugin.load(module.prid, module.req, onLoad);
+				}else if(plugin.loadQ){
+					plugin.loadQ.push(module);
+				}else{
+					// the unshift instead of push is important: we don't want plugins to execute as
+					// 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
+					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];
+					}
+				}
+			},
+
+			// for IE, injecting a module may result in a recursive execution if the module is in the cache
+
+			cached = 0,
+
+			injectingModule = 0,
+
+			injectingCachedModule = 0,
+
+			evalModuleText = function(text, module){
+				// see def() for the injectingCachedModule bracket; it simply causes a short, safe curcuit
+				injectingCachedModule = 1;
+				if(has("config-dojo-loader-catches")){
+					try{
+						if(text===cached){
+							cached.call(null);
+						}else{
+							req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid);
+						}
+					}catch(e){
+						signal(error, makeError("evalModuleThrew", module));
+					}
+				}else{
+					if(text===cached){
+						cached.call(null);
+					}else{
+						req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid);
+					}
+				}
+				injectingCachedModule = 0;
+			},
+
+			injectModule = function(module){
+				// Inject the module. In the browser environment, this means appending a script element into
+				// the document; in other environments, it means loading a file.
+				//
+				// If in synchronous mode, then get the module synchronously if it's not xdomainLoading.
+
+				var mid = module.mid,
+					url = module.url;
+				if(module.executed || module.injected || waiting[mid] || (module.url && ((module.pack && waiting[module.url]===module.pack) || waiting[module.url]==1))){
+					return;
+				}
+
+				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
+						// to the conversion; therefore the third argument is zero
+						req.combo.add(module.plugin.mid, module.prid, 0, req);
+						viaCombo = 1;
+					}else if(!module.plugin){
+						viaCombo = req.combo.add(0, module.mid, module.url, req);
+					}
+					if(viaCombo){
+						setRequested(module);
+						comboPending= 1;
+						return;
+					}
+				}
+
+				if(module.plugin){
+					injectPlugin(module);
+					return;
+				} // else a normal module (not a plugin)
+
+				setRequested(module);
+
+				var onLoadCallback = function(){
+					runDefQ(module);
+					if(module.injected !== arrived){
+						// the script that contained the module arrived and has been executed yet
+						// 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
+						setArrived(module);
+						mix(module, nonModuleProps);
+					}
+
+					if(has("dojo-sync-loader") && legacyMode){
+						// must call checkComplete even in for sync loader because we may be in xdomainLoading mode;
+						// but, if xd loading, then don't call checkComplete until out of the current sync traversal
+						// in order to preserve order of execution of the dojo.required modules
+						!syncExecStack.length && checkComplete();
+					}else{
+						checkComplete();
+					}
+				};
+				cached = cache[mid] || cache[module.cacheId];
+				if(cached){
+					req.trace("loader-inject", ["cache", module.mid, url]);
+					evalModuleText(cached, module);
+					onLoadCallback();
+					return;
+				}
+				if(has("dojo-sync-loader") && legacyMode){
+					if(module.isXd){
+						// switch to async mode temporarily; if current legacyMode!=sync, then is must be one of {legacyAsync, xd, false}
+						legacyMode==sync && (legacyMode = xd);
+						// fall through and load via script injection
+					}else if(module.isAmd && legacyMode!=sync){
+						// fall through and load via script injection
+					}else{
+						// mode may be sync, xd/legacyAsync, or async; module may be AMD or legacy; but module is always located on the same domain
+						var xhrCallback = function(text){
+							if(legacyMode==sync){
+								// the top of syncExecStack gives the current synchronously executing module; the loader needs
+								// to know this if it has to switch to async loading in the middle of evaluating a legacy module
+								// this happens when a modules dojo.require's a module that must be loaded async because it's xdomain
+								// (using unshift/shift because there is no back() methods for Javascript arrays)
+								syncExecStack.unshift(module);
+								evalModuleText(text, module);
+								syncExecStack.shift();
+
+								// maybe the module was an AMD module
+								runDefQ(module);
+
+								// legacy modules never get to defineModule() => cjs and injected never set; also evaluation implies executing
+								if(!module.cjs){
+									setArrived(module);
+									finishExec(module);
+								}
+
+								if(module.finish){
+									// while synchronously evaluating this module, dojo.require was applied referencing a module
+									// that had to be loaded async; therefore, the loader stopped answering all dojo.require
+									// requests so they could be answered completely in the correct sequence; module.finish gives
+									// 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
+									// TODO: can we just leave the module.finish...what's it hurting?
+									var finishMid = mid + "*finish",
+										finish = module.finish;
+									delete module.finish;
+
+									def(finishMid, ["dojo", ("dojo/require!" + finish.join(",")).replace(/\./g, "/")], function(dojo){
+										forEach(finish, function(mid){ dojo.require(mid); });
+									});
+									// unshift, not push, which causes the current traversal to be reattempted from the top
+									execQ.unshift(getModule(finishMid));
+								}
+								onLoadCallback();
+							}else{
+								text = transformToAmd(module, text);
+								if(text){
+									evalModuleText(text, module);
+									onLoadCallback();
+								}else{
+									// if transformToAmd returned falsy, then the module was already AMD and it can be script-injected
+									// do so to improve debugability(even though it means another download...which probably won't happen with a good browser cache)
+									injectingModule = module;
+									req.injectUrl(fixupUrl(url), onLoadCallback, module);
+									injectingModule = 0;
+								}
+							}
+						};
+
+						req.trace("loader-inject", ["xhr", module.mid, url, legacyMode!=sync]);
+						if(has("config-dojo-loader-catches")){
+							try{
+								req.getText(url, legacyMode!=sync, xhrCallback);
+							}catch(e){
+								signal(error, makeError("xhrInjectFailed", [module, e]));
+							}
+						}else{
+							req.getText(url, legacyMode!=sync, xhrCallback);
+						}
+						return;
+					}
+				} // else async mode or fell through in xdomain loading mode; either way, load by script injection
+				req.trace("loader-inject", ["script", module.mid, url]);
+				injectingModule = module;
+				req.injectUrl(fixupUrl(url), onLoadCallback, module);
+				injectingModule = 0;
+			},
+
+			defineModule = function(module, deps, def){
+				req.trace("loader-define-module", [module.mid, deps]);
+
+				if(has("dojo-combo-api") && module.plugin && module.plugin.isCombo){
+					// the module is a plugin resource loaded by the combo service
+					// note: check for module.plugin should be enough since normal plugin resources should
+					// not follow this path; module.plugin.isCombo is future-proofing belt and suspenders
+					module.result = isFunction(def) ? def() : def;
+					setArrived(module);
+					finishExec(module);
+					return module;
+				};
+
+				var mid = module.mid;
+				if(module.injected === arrived){
+					signal(error, makeError("multipleDefine", module));
+					return module;
+				}
+				mix(module, {
+					deps: deps,
+					def: def,
+					cjs: {
+						id: module.mid,
+						uri: module.url,
+						exports: (module.result = {}),
+						setExports: function(exports){
+							module.cjs.exports = exports;
+						}
+					}
+				});
+
+				// resolve deps with respect to this module
+				for(var i = 0; i < deps.length; i++){
+					deps[i] = getModule(deps[i], module);
+				}
+
+				if(has("dojo-sync-loader") && legacyMode && !waiting[mid]){
+					// the module showed up without being asked for; it was probably in a <script> element
+					injectDependencies(module);
+					execQ.push(module);
+					checkComplete();
+				}
+				setArrived(module);
+
+				if(!isFunction(def) && !deps.length){
+					module.result = def;
+					finishExec(module);
+				}
+
+				return module;
+			},
+
+			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){
+					args = defQ.shift();
+					mids && (args[0]= mids.shift());
+					// 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]));
+				}
+				forEach(definedModules, injectDependencies);
+			};
+	}
+
+	var timerId = 0,
+		clearTimer = noop,
+		startTimer = noop;
+	if(has("dojo-timeout-api")){
+		// Timer machinery that monitors how long the loader is waiting and signals an error when the timer runs out.
+		clearTimer = function(){
+			timerId && clearTimeout(timerId);
+			timerId = 0;
+		},
+
+		startTimer = function(){
+			clearTimer();
+			req.waitms && (timerId = setTimeout(function(){
+					clearTimer();
+					signal(error, makeError("timeout", waiting));
+			}, req.waitms));
+		};
+	}
+
+	if(has("dom")){
+		has.add("ie-event-behavior", doc.attachEvent && (typeof opera === "undefined" || opera.toString() != "[object Opera]"));
+	}
+
+	if(has("dom") && (has("dojo-inject-api") || has("dojo-dom-ready-api"))){
+		var domOn = function(node, eventName, ieEventName, handler){
+				// Add an event listener to a DOM node using the API appropriate for the current browser;
+				// return a function that will disconnect the listener.
+				if(!has("ie-event-behavior")){
+					node.addEventListener(eventName, handler, false);
+					return function(){
+						node.removeEventListener(eventName, handler, false);
+					};
+				}else{
+					node.attachEvent(ieEventName, handler);
+					return function(){
+						node.detachEvent(ieEventName, handler);
+					};
+				}
+			},
+			windowOnLoadListener = domOn(window, "load", "onload", function(){
+				req.pageLoaded = 1;
+				doc.readyState!="complete" && (doc.readyState = "complete");
+				windowOnLoadListener();
+			});
+
+		if(has("dojo-inject-api")){
+			// if the loader is on the page, there must be at least one script element
+			// 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;
+			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();
+							callback && callback();
+						}
+					},
+					disconnector = domOn(node, "load", "onreadystatechange", onLoad);
+				node.type = "text/javascript";
+				node.charset = "utf-8";
+				node.src = url;
+				insertPoint.insertBefore(node, sibling);
+				return node;
+			};
 		}
+	}
+
+	if(has("dojo-log-api")){
+		req.log = function(){
+			try{
+				for(var i = 0; i < arguments.length; i++){
+					console.log(arguments[i]);
+				}
+			}catch(e){}
+		};
+	}else{
+		req.log = noop;
+	}
+
+	if(has("dojo-trace-api")){
+		var trace = req.trace = function(
+			group,	// the trace group to which this application belongs
+			args	// the contents of the trace
+		){
+			///
+			// Tracing interface by group.
+			//
+			// Sends the contents of args to the console iff (req.trace.on && req.trace[group])
 
-		// Opera and Safari don't handle injected script tags in the right
-		// order, so we resort to XHR to make things work there when we find
-		// ourselves in a strict XHTML environment (e.g., document.write bombs
-		// out)
-		var injectXHRCode = function(src){
-			var xhr = new XMLHttpRequest();
-			xhr.open("GET", src, false);
-			xhr.send();
-			eval(xhr.responseText);
+			if(trace.on && trace.group[group]){
+				signal("trace", [group, args]);
+				for(var arg, dump = [], text= "trace:" + group + (args.length ? (":" + args[0]) : ""), i= 1; i<args.length;){
+					arg = args[i++];
+					if(isString(arg)){
+						text += ", " + arg;
+					}else{
+						dump.push(arg);
+					}
+				}
+				req.log(text);
+				dump.length && dump.push(".");
+				req.log.apply(req, dump);
+			}
+		};
+		mix(trace, {
+			on:1,
+			group:{},
+			set:function(group, value){
+				if(isString(group)){
+					trace.group[group]= value;
+				}else{
+					mix(trace.group, group);
+				}
+			}
+		});
+		trace.set(mix(mix(mix({}, defaultConfig.trace), userConfig.trace), dojoSniffConfig.trace));
+		on("config", function(config){
+			config.trace && trace.set(config.trace);
+		});
+	}else{
+		req.trace = noop;
+	}
+
+	var def = function(
+		mid,		  //(commonjs.moduleId, optional) list of modules to be loaded before running factory
+		dependencies, //(array of commonjs.moduleId, optional)
+		factory		  //(any)
+	){
+		///
+		// Advises the loader of a module factory. //Implements http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition.
+		///
+		//note
+		// 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];
+			}
+		}
+		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]);
 		}
-	
-		var injectScriptNode = function(src){
-			if(isWebKit){ return injectXHRCode(src); }
-			var head = document.getElementsByTagName("head")[0];
-			var script = document.createElement("script");
-			script.setAttribute("type", "text/javascript");
-			if(head.lastChild === lastRoot){
-				head.appendChild(script);
+		req.trace("loader-define", args.slice(0, 2));
+		var targetModule = args[0] && getModule(args[0]),
+			module;
+		if(targetModule && !waiting[targetModule.mid]){
+			// given a mid that hasn't been requested; therefore, defined through means other than injecting
+			// consequent to a require() or define() application; examples include defining modules on-the-fly
+			// due to some code path or including a module in a script element. In any case,
+			// there is no callback waiting to finish processing and nothing to trigger the defQ and the
+			// dependencies are never requested; therefore, do it here.
+			injectDependencies(defineModule(targetModule, args[1], args[2]));
+		}else if(!has("ie-event-behavior") || !has("host-browser") || injectingCachedModule){
+			// not IE path: anonymous module and therefore must have been injected; therefore, onLoad will fire immediately
+			// after script finishes being evaluated and the defQ can be run from that callback to detect the module id
+			defQ.push(args);
+		}else{
+			// IE path: possibly anonymous module and therefore injected; therefore, cannot depend on 1-to-1,
+			// in-order exec of onLoad with script eval (since it's IE) and must manually detect here
+			targetModule = targetModule || injectingModule;
+			if(!targetModule){
+				for(mid in waiting){
+					module = modules[mid];
+					if(module && module.node && module.node.readyState === 'interactive'){
+						targetModule = module;
+						break;
+					}
+				}
+				if(has("dojo-combo-api") && !targetModule){
+					for(var i = 0; i<combosPending.length; i++){
+						targetModule = combosPending[i];
+						if(targetModule.node && targetModule.node.readyState === 'interactive'){
+							break;
+						}
+						targetModule= 0;
+					}
+				}
+			}
+			if(has("dojo-combo-api") && isArray(targetModule)){
+				injectDependencies(defineModule(getModule(targetModule.shift()), args[1], args[2]));
+				if(!targetModule.length){
+					combosPending.splice(i, 1);
+				}
+			}else if(targetModule){
+				consumePendingCacheInsert(targetModule);
+				injectDependencies(defineModule(targetModule, args[1], args[2]));
 			}else{
-				lastRoot.parentNode.insertBefore(script, lastRoot.nextSibling);
+				signal(error, makeError("ieDefineFailed", args[0]));
 			}
-			script.src = src;
-			lastRoot = script;
+			checkComplete();
 		}
-		for(var x=0; x < tmps.length; x++){
-			if(hostEnv === "rhino" || hostEnv === "spidermonkey" || (this.Jaxer && this.Jaxer.isOnServer)){
-				load(tmps[x]);
-			}else if(hostEnv === "ff_ext"){
-				var l = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
-					.getService(Components.interfaces.mozIJSSubScriptLoader);
-				l.loadSubScript(tmps[x], this)
-			}else if(isOpera){ // opera fails silently!!
-				injectXHRCode(tmps[x]);
-			}else{
-				try{
-					document.write("<scr"+"ipt type='text/javascript' src='"+tmps[x]+"'></scr"+"ipt>");
-				}catch(e){
-					// strict XHTML mode, no document.write
-					injectScriptNode(tmps[x]);
+	};
+	def.amd = {
+		vendor:"dojotoolkit.org"
+	};
+
+	if(has("dojo-requirejs-api")){
+		req.def = def;
+	}
+
+	// allow config to override default implemention 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);
+
+	// now that req is fully initialized and won't change, we can hook it up to the error signal
+	on(error, function(arg){
+		try{
+			console.error(arg);
+			if(arg instanceof Error){
+				for(var p in arg){
+					console.log(p + ":", arg[p]);
 				}
+				console.log(".");
 			}
+		}catch(e){}
+	});
+
+	// always publish these
+	mix(req, {
+		uid:uid,
+		cache:cache,
+		packs:packs
+	});
+
+
+	if(has("dojo-publish-privates")){
+		mix(req, {
+			// these may be interesting to look at when debugging
+			paths:paths,
+			aliases:aliases,
+			packageMap:packageMap,
+			modules:modules,
+			legacyMode:legacyMode,
+			execQ:execQ,
+			defQ:defQ,
+			waiting:waiting,
+
+			// these are used for testing
+			// TODO: move testing infrastructure to a different has feature
+			pathsMapProg:pathsMapProg,
+			packageMapProg:packageMapProg,
+			listenerQueues:listenerQueues,
+
+			// these are used by the builder (at least)
+			computeMapProg:computeMapProg,
+			runMapProg:runMapProg,
+			compactPath:compactPath,
+			getModuleInfo:getModuleInfo_
+		});
+	}
+
+	// the loader can be defined exactly once; look for global define which is the symbol AMD loaders are
+	// *required* to define (as opposed to require, which is optional)
+	if(global.define){
+		if(has("dojo-log-api")){
+			signal(error, makeError("defineAlreadyDefined", 0));
 		}
-	})();
-};
+	}else{
+		global.define = def;
+		global.require = req;
+	}
+
+	if(has("dojo-combo-api") && req.combo && req.combo.plugins){
+		var plugins = req.combo.plugins,
+			pluginName;
+		for(pluginName in plugins){
+			mix(mix(getModule(pluginName), plugins[pluginName]), {isCombo:1, executed:"executed", load:1});
+		}
+	}
+
+	if(has("dojo-config-api")){
+		var bootDeps = defaultConfig.deps || userConfig.deps || dojoSniffConfig.deps,
+			bootCallback = defaultConfig.callback || userConfig.callback || dojoSniffConfig.callback;
+		req.boot = (bootDeps || bootCallback) ? [bootDeps || [], bootCallback] : 0;
+	}
+	if(!has("dojo-built")){
+		!req.async && req(["dojo"]);
+		req.boot && req.apply(null, req.boot);
+	}
+})
+//>>excludeStart("replaceLoaderConfig", kwArgs.replaceLoaderConfig);
+(
+	// userConfig
+	(function(){
+		// make sure we're looking at global dojoConfig etc.
+		return this.dojoConfig || this.djConfig || this.require || {};
+	})(),
+
+	// defaultConfig
+	{
+		// the default configuration for a browser; this will be modified by other environments
+		hasCache:{
+			"host-browser":1,
+			"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
+		},
+		packages:[{
+			// note: like v1.6-, this bootstrap computes baseUrl to be the dojo directory
+			name:'dojo',
+			location:'.'
+		},{
+			name:'tests',
+			location:'./tests'
+		},{
+			name:'dijit',
+			location:'../dijit'
+		},{
+			name:'build',
+			location:'../util/build'
+		},{
+			name:'doh',
+			location:'../util/doh'
+		},{
+			name:'dojox',
+			location:'../dojox'
+		},{
+			name:'demos',
+			location:'../demos'
+		}],
+		trace:{
+			// these are listed so it's simple to turn them on/off while debugging loading
+			"loader-inject":0,
+			"loader-define":0,
+			"loader-exec-module":0,
+			"loader-run-factory":0,
+			"loader-finish-exec":0,
+			"loader-define-module":0,
+			"loader-circular-dependency":0
+		},
+		async:0,
+		waitSeconds:15
+	}
+);
+//>>excludeEnd("replaceLoaderConfig")
diff --git a/dojo/dojo.profile.js b/dojo/dojo.profile.js
new file mode 100644
index 0000000..40e45f9
--- /dev/null
+++ b/dojo/dojo.profile.js
@@ -0,0 +1,40 @@
+var profile = (function(){
+	var testResourceRe = /^dojo\/tests\//,
+
+		copyOnly = function(filename, mid){
+			var list = {
+				"dojo/dojo.profile":1,
+				"dojo/package.json":1,
+				"dojo/OpenAjax":1,
+				"dojo/tests":1,
+				// these are test modules that are not intended to ever be built
+				"dojo/tests/_base/loader/requirejs/requirejs-setup":1,
+				"dojo/tests/_base/loader/requirejs/dataMain":1,
+				"dojo/tests/_base/loader/requirejs/depoverlap":1,
+				"dojo/tests/_base/loader/requirejs/simple-tests":1,
+				"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 {
+		resourceTags:{
+			test: function(filename, mid){
+				return testResourceRe.test(mid) || mid=="dojo/tests" || mid=="dojo/robot" || mid=="dojo/robotx";
+			},
+
+			copyOnly: function(filename, mid){
+				return copyOnly(filename, mid);
+			},
+
+			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
new file mode 100644
index 0000000..d9032df
--- /dev/null
+++ b/dojo/dom-attr.js
@@ -0,0 +1,238 @@
+define(["exports", "./_base/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.
+
+	// =============================
+	// Element attribute Functions
+	// =============================
+
+	// 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){
+		// summary:
+		//		Returns true if the requested attribute is specified on the
+		//		given element, and false otherwise.
+		// node: DOMNode|String
+		//		id or reference to the element to check
+		// name: String
+		//		the name of the attribute
+		// returns: Boolean
+		//		true if the requested attribute is specified on the
+		//		given element, and false otherwise
+	};
+	=====*/
+
+	/*=====
+	dojo.getAttr = function(node, name){
+		// summary:
+		//		Gets an attribute on an HTML element.
+		// description:
+		//		Handles normalized getting of attributes on DOM Nodes.
+		// node: DOMNode|String
+		//		id or reference to the element to get the attribute on
+		// name: String
+		//		the name of the attribute to get.
+		// returns:
+		//		the value of the requested attribute or null if that attribute does not have a specified or
+		//		default value;
+		//
+		// example:
+		//	|	// get the current value of the "foo" attribute on a node
+		//	|	dojo.getAttr(dojo.byId("nodeId"), "foo");
+		//	|	// or we can just pass the id:
+		//	|	dojo.getAttr("nodeId", "foo");
+	};
+	=====*/
+
+	/*=====
+	dojo.setAttr = function(node, name, value){
+		// summary:
+		//		Sets an attribute on an HTML element.
+		// description:
+		//		Handles normalized setting of attributes on DOM Nodes.
+		//
+		//		When passing functions as values, note that they will not be
+		//		directly assigned to slots on the node, but rather the default
+		//		behavior will be removed and the new behavior will be added
+		//		using `dojo.connect()`, meaning that event handler properties
+		//		will be normalized and that some caveats with regards to
+		//		non-standard behaviors for onsubmit apply. Namely that you
+		//		should cancel form submission using `dojo.stopEvent()` on the
+		//		passed event object instead of returning a boolean value from
+		//		the handler itself.
+		// node: DOMNode|String
+		//		id or reference to the element to set the attribute on
+		// name: String|Object
+		//		the name of the attribute to set, or a hash of key-value pairs to set.
+		// value: String?
+		//		the value to set for the attribute, if the name is a string.
+		// returns:
+		//		the DOM node
+		//
+		// example:
+		//	|	// use attr() to set the tab index
+		//	|	dojo.setAttr("nodeId", "tabIndex", 3);
+		//
+		// example:
+		//	Set multiple values at once, including event handlers:
+		//	|	dojo.setAttr("formId", {
+		//	|		"foo": "bar",
+		//	|		"tabIndex": -1,
+		//	|		"method": "POST",
+		//	|		"onsubmit": function(e){
+		//	|			// stop submitting the form. Note that the IE behavior
+		//	|			// of returning true or false will have no effect here
+		//	|			// since our handler is connect()ed to the built-in
+		//	|			// onsubmit behavior and so we need to use
+		//	|			// dojo.stopEvent() to ensure that the submission
+		//	|			// doesn't proceed.
+		//	|			dojo.stopEvent(e);
+		//	|
+		//	|			// submit the form with Ajax
+		//	|			dojo.xhrPost({ form: "formId" });
+		//	|		}
+		//	|	});
+		//
+		// example:
+		//	Style is s special case: Only set with an object hash of styles
+		//	|	dojo.setAttr("someNode",{
+		//	|		id:"bar",
+		//	|		style:{
+		//	|			width:"200px", height:"100px", color:"#000"
+		//	|		}
+		//	|	});
+		//
+		// example:
+		//	Again, only set style as an object hash of styles:
+		//	|	var obj = { color:"#fff", backgroundColor:"#000" };
+		//	|	dojo.setAttr("someNode", "style", obj);
+		//	|
+		//	|	// 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
+			for(var x in name){
+				exports.set(node, x, name[x]);
+			}
+			return node; // DomNode
+		}
+		var lc = name.toLowerCase(),
+			propName = prop.names[lc] || name,
+			forceProp = forcePropNames[propName];
+		if(propName == "style" && typeof value != "string"){ // inline'd type check
+			// special case: setting a style
+			style.set(node, value);
+			return node; // DomNode
+		}
+		if(forceProp || typeof value == "boolean" || lang.isFunction(value)){
+			return prop.set(node, name, value)
+		}
+		// node's attribute
+		node.setAttribute(attrNames[lc] || name, value);
+		return node; // DomNode
+	};
+
+	exports.remove = function removeAttr(/*DOMNode|String*/ node, /*String*/ name){
+		dom.byId(node).removeAttribute(attrNames[name.toLowerCase()] || name);
+	};
+
+	exports.getNodeProp = function getNodeProp(/*DomNode|String*/ node, /*String*/ name){
+		node = dom.byId(node);
+		var lc = name.toLowerCase(), propName = prop.names[lc] || name;
+		if((propName in node) && propName != "href"){
+			// node's property
+			return node[propName];	// Anything
+		}
+		// node's attribute
+		var attrName = attrNames[lc] || name;
+		return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
+	};
+});
diff --git a/dojo/dom-class.js b/dojo/dom-class.js
new file mode 100644
index 0000000..4c4cb7d
--- /dev/null
+++ b/dojo/dom-class.js
@@ -0,0 +1,320 @@
+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";
+
+	/* Part I of classList-based implementation is preserved here for posterity
+	var classList = "classList";
+	has.add("dom-classList", function(){
+		return classList in document.createElement("p");
+	});
+	*/
+
+	// =============================
+	// (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 = [""];
+
+	function str2array(s){
+		if(typeof s == "string" || s instanceof String){
+			if(s && !spaces.test(s)){
+				a1[0] = s;
+				return a1;
+			}
+			var a = s.split(spaces);
+			if(a.length && !a[0]){
+				a.shift();
+			}
+			if(a.length && !a[a.length - 1]){
+				a.pop();
+			}
+			return a;
+		}
+		// assumed to be an array
+		if(!s){
+			return [];
+		}
+		return array.filter(s, function(x){ return x; });
+	}
+
+	/* Part II of classList-based implementation is preserved here for posterity
+	if(has("dom-classList")){
+		// new classList version
+		cls = {
+			contains: function containsClass(node, classStr){
+				var clslst = classStr && dom.byId(node)[classList];
+				return clslst && clslst.contains(classStr); // Boolean
+			},
+
+			add: function addClass(node, classStr){
+				node = dom.byId(node);
+				classStr = str2array(classStr);
+				for(var i = 0, len = classStr.length; i < len; ++i){
+					node[classList].add(classStr[i]);
+				}
+			},
+
+			remove: function removeClass(node, classStr){
+				node = dom.byId(node);
+				if(classStr === undefined){
+					node[className] = "";
+				}else{
+					classStr = str2array(classStr);
+					for(var i = 0, len = classStr.length; i < len; ++i){
+						node[classList].remove(classStr[i]);
+					}
+				}
+			},
+
+			replace: function replaceClass(node, addClassStr, removeClassStr){
+				node = dom.byId(node);
+				if(removeClassStr === undefined){
+					node[className] = "";
+				}else{
+					removeClassStr = str2array(removeClassStr);
+					for(var i = 0, len = removeClassStr.length; i < len; ++i){
+						node[classList].remove(removeClassStr[i]);
+					}
+				}
+				addClassStr = str2array(addClassStr);
+				for(i = 0, len = addClassStr.length; i < len; ++i){
+					node[classList].add(addClassStr[i]);
+				}
+			},
+
+			toggle: function toggleClass(node, classStr, condition){
+				node = dom.byId(node);
+				if(condition === undefined){
+					classStr = str2array(classStr);
+					for(var i = 0, len = classStr.length; i < len; ++i){
+						node[classList].toggle(classStr[i]);
+					}
+				}else{
+					cls[condition ? "add" : "remove"](node, classStr);
+				}
+				return condition;   // Boolean
+			}
+		}
+	}
+	*/
+
+	// regular DOM version
+	var fakeNode = {};  // for effective replacement
+	cls = {
+		contains: function containsClass(/*DomNode|String*/node, /*String*/classStr){
+			return ((" " + dom.byId(node)[className] + " ").indexOf(" " + classStr + " ") >= 0); // Boolean
+		},
+
+		add: function addClass(/*DomNode|String*/node, /*String|Array*/classStr){
+			node = dom.byId(node);
+			classStr = str2array(classStr);
+			var cls = node[className], oldLen;
+			cls = cls ? " " + cls + " " : " ";
+			oldLen = cls.length;
+			for(var i = 0, len = classStr.length, c; i < len; ++i){
+				c = classStr[i];
+				if(c && cls.indexOf(" " + c + " ") < 0){
+					cls += c + " ";
+				}
+			}
+			if(oldLen < cls.length){
+				node[className] = cls.substr(1, cls.length - 2);
+			}
+		},
+
+		remove: function removeClass(/*DomNode|String*/node, /*String|Array?*/classStr){
+			node = dom.byId(node);
+			var cls;
+			if(classStr !== undefined){
+				classStr = str2array(classStr);
+				cls = " " + node[className] + " ";
+				for(var i = 0, len = classStr.length; i < len; ++i){
+					cls = cls.replace(" " + classStr[i] + " ", " ");
+				}
+				cls = lang.trim(cls);
+			}else{
+				cls = "";
+			}
+			if(node[className] != cls){ node[className] = cls; }
+		},
+
+		replace: function replaceClass(/*DomNode|String*/node, /*String|Array*/addClassStr, /*String|Array?*/removeClassStr){
+			node = dom.byId(node);
+			fakeNode[className] = node[className];
+			cls.remove(fakeNode, removeClassStr);
+			cls.add(fakeNode, addClassStr);
+			if(node[className] !== fakeNode[className]){
+				node[className] = fakeNode[className];
+			}
+		},
+
+		toggle: function toggleClass(/*DomNode|String*/node, /*String|Array*/classStr, /*Boolean?*/condition){
+			node = dom.byId(node);
+			if(condition === undefined){
+				classStr = str2array(classStr);
+				for(var i = 0, len = classStr.length, c; i < len; ++i){
+					c = classStr[i];
+					cls[cls.contains(node, c) ? "remove" : "add"](node, c);
+				}
+			}else{
+				cls[condition ? "add" : "remove"](node, classStr);
+			}
+			return condition;   // Boolean
+		}
+	};
+
+	return cls;
+});
diff --git a/dojo/dom-construct.js b/dojo/dom-construct.js
new file mode 100644
index 0000000..b3ccc0e
--- /dev/null
+++ b/dojo/dom-construct.js
@@ -0,0 +1,380 @@
+define(["exports", "./_base/kernel", "./_base/sniff", "./_base/window", "./dom", "./dom-attr", "./on"],
+		function(exports, dojo, has, win, dom, attr, on){
+	// 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.
+	};
+	=====*/
+
+	// support stuff for dojo.toDom
+	var tagWrap = {
+			option: ["select"],
+			tbody: ["table"],
+			thead: ["table"],
+			tfoot: ["table"],
+			tr: ["table", "tbody"],
+			td: ["table", "tbody", "tr"],
+			th: ["table", "thead", "tr"],
+			legend: ["fieldset"],
+			caption: ["table"],
+			colgroup: ["table"],
+			col: ["table", "colgroup"],
+			li: ["ul"]
+		},
+		reTag = /<\s*([\w\:]+)/,
+		masterNode = {}, masterNum = 0,
+		masterName = "__" + dojo._scopeName + "ToDomId";
+
+	// generate start/end tag strings to use
+	// for the injection for each special tag wrap case.
+	for(var param in tagWrap){
+		if(tagWrap.hasOwnProperty(param)){
+			var tw = tagWrap[param];
+			tw.pre = param == "option" ? '<select multiple="multiple">' : "<" + tw.join("><") + ">";
+			tw.post = "</" + tw.reverse().join("></") + ">";
+			// the last line is destructive: it reverses the array,
+			// but we don't care at this point
+		}
+	}
+
+	function _insertBefore(/*DomNode*/node, /*DomNode*/ref){
+		var parent = ref.parentNode;
+		if(parent){
+			parent.insertBefore(node, ref);
+		}
+	}
+
+	function _insertAfter(/*DomNode*/node, /*DomNode*/ref){
+		// summary:
+		//		Try to insert node after ref
+		var parent = ref.parentNode;
+		if(parent){
+			if(parent.lastChild == ref){
+				parent.appendChild(node);
+			}else{
+				parent.insertBefore(node, ref.nextSibling);
+			}
+		}
+	}
+
+	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){
+		doc = doc || win.doc;
+		var masterId = doc[masterName];
+		if(!masterId){
+			doc[masterName] = masterId = ++masterNum + "";
+			masterNode[masterId] = doc.createElement("div");
+		}
+
+		// make sure the frag is a string.
+		frag += "";
+
+		// find the starting tag, and get node wrapper
+		var match = frag.match(reTag),
+			tag = match ? match[1].toLowerCase() : "",
+			master = masterNode[masterId],
+			wrap, i, fc, df;
+		if(match && tagWrap[tag]){
+			wrap = tagWrap[tag];
+			master.innerHTML = wrap.pre + frag + wrap.post;
+			for(i = wrap.length; i; --i){
+				master = master.firstChild;
+			}
+		}else{
+			master.innerHTML = frag;
+		}
+
+		// one node shortcut => return the node itself
+		if(master.childNodes.length == 1){
+			return master.removeChild(master.firstChild); // DOMNode
+		}
+
+		// return multiple nodes as a document fragment
+		df = doc.createDocumentFragment();
+		while(fc = master.firstChild){ // intentional assignment
+			df.appendChild(fc);
+		}
+		return df; // DOMNode
+	};
+
+	exports.place = function place(/*DOMNode|String*/node, /*DOMNode|String*/refNode, /*String|Number?*/position){
+		refNode = dom.byId(refNode);
+		if(typeof node == "string"){ // inline'd type check
+			node = /^\s*</.test(node) ? exports.toDom(node, refNode.ownerDocument) : dom.byId(node);
+		}
+		if(typeof position == "number"){ // inline'd type check
+			var cn = refNode.childNodes;
+			if(!cn.length || cn.length <= position){
+				refNode.appendChild(node);
+			}else{
+				_insertBefore(node, cn[position < 0 ? 0 : position]);
+			}
+		}else{
+			switch(position){
+				case "before":
+					_insertBefore(node, refNode);
+					break;
+				case "after":
+					_insertAfter(node, refNode);
+					break;
+				case "replace":
+					refNode.parentNode.replaceChild(node, refNode);
+					break;
+				case "only":
+					exports.empty(refNode);
+					refNode.appendChild(node);
+					break;
+				case "first":
+					if(refNode.firstChild){
+						_insertBefore(node, refNode.firstChild);
+						break;
+					}
+					// else fallthrough...
+				default: // aka: last
+					refNode.appendChild(node);
+			}
+		}
+		return node; // DomNode
+	};
+
+	exports.create = function create(/*DOMNode|String*/tag, /*Object*/attrs, /*DOMNode?|String?*/refNode, /*String?*/pos){
+		var doc = win.doc;
+		if(refNode){
+			refNode = dom.byId(refNode);
+			doc = refNode.ownerDocument;
+		}
+		if(typeof tag == "string"){ // inline'd type check
+			tag = doc.createElement(tag);
+		}
+		if(attrs){ attr.set(tag, attrs); }
+		if(refNode){ exports.place(tag, refNode, pos); }
+		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);
+			}
+		} :
+		//>>excludeEnd("webkitMobile");
+		function(node){
+			dom.byId(node).innerHTML = "";
+		};
+
+	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 */
+		}
+	};
+});
diff --git a/dojo/dom-form.js b/dojo/dom-form.js
new file mode 100644
index 0000000..68cf78b
--- /dev/null
+++ b/dojo/dom-form.js
@@ -0,0 +1,166 @@
+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){
+        // 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
+        //		array of values.
+
+        // Skip it if there is no value
+        if(value === null){
+            return;
+        }
+
+        var val = obj[name];
+        if(typeof val == "string"){ // inline'd type check
+            obj[name] = [val, value];
+        }else if(lang.isArray(val)){
+            val.push(value);
+        }else{
+            obj[name] = value;
+        }
+    }
+
+	var exclude = "file|submit|image|reset|button";
+
+	var form = {
+		fieldToObject: function fieldToObject(/*DOMNode|String*/ inputNode){
+			var ret = null;
+			inputNode = dom.byId(inputNode);
+			if(inputNode){
+				var _in = inputNode.name, type = (inputNode.type || "").toLowerCase();
+				if(_in && type && !inputNode.disabled){
+					if(type == "radio" || type == "checkbox"){
+						if(inputNode.checked){
+							ret = inputNode.value;
+						}
+					}else if(inputNode.multiple){
+						ret = [];
+						var nodes = [inputNode.firstChild];
+						while(nodes.length){
+							for(var node = nodes.pop(); node; node = node.nextSibling){
+								if(node.nodeType == 1 && node.tagName.toLowerCase() == "option"){
+									if(node.selected){
+										ret.push(node.value);
+									}
+								}else{
+									if(node.nextSibling){
+										nodes.push(node.nextSibling);
+									}
+									if(node.firstChild){
+										nodes.push(node.firstChild);
+									}
+									break;
+								}
+							}
+						}
+					}else{
+						ret = inputNode.value;
+					}
+				}
+			}
+			return ret; // Object
+		},
+
+		toObject: function formToObject(/*DOMNode|String*/ formNode){
+			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();
+				if(_in && type && exclude.indexOf(type) < 0 && !item.disabled){
+					setValue(ret, _in, form.fieldToObject(item));
+					if(type == "image"){
+						ret[_in + ".x"] = ret[_in + ".y"] = ret[_in].x = ret[_in].y = 0;
+					}
+				}
+			}
+			return ret; // Object
+		},
+
+		toQuery: function formToQuery(/*DOMNode|String*/ formNode){
+			return ioq.objectToQuery(form.toObject(formNode)); // String
+		},
+
+		toJson: function formToJson(/*DOMNode|String*/ formNode, /*Boolean?*/prettyPrint){
+			return json.stringify(form.toObject(formNode), null, prettyPrint ? 4 : 0); // String
+		}
+	};
+
+    return form;
+});
diff --git a/dojo/dom-geometry.js b/dojo/dom-geometry.js
new file mode 100644
index 0000000..f553ec0
--- /dev/null
+++ b/dojo/dom-geometry.js
@@ -0,0 +1,763 @@
+define(["./_base/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
+
+	// Box functions will assume this model.
+	// On IE/Opera, BORDER_BOX will be set if the primary document is in quirks mode.
+	// Can be set to change behavior of box setters.
+
+	// can be either:
+	//	"border-box"
+	//	"content-box" (default)
+	geom.boxModel = "content-box";
+
+	// We punt per-node box mode testing completely.
+	// If anybody cares, we can provide an additional (optional) unit
+	// that overrides existing code to include per-node box sensitivity.
+
+	// Opera documentation claims that Opera 9 uses border-box in BackCompat mode.
+	// but experiments (Opera 9.10.8679 on Windows Vista) indicate that it actually continues to use content-box.
+	// 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){
+		// summary:
+		//		Returns object with special values specifically useful for node
+		//		fitting.
+		// description:
+		//		Returns an object with `w`, `h`, `l`, `t` properties:
+		//	|		l/t/r/b = left/top/right/bottom padding (respectively)
+		//	|		w = the total of the left and right padding
+		//	|		h = the total of the top and bottom padding
+		//		If 'node' has position, l/t forms the origin for child nodes.
+		//		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._getPadExtents = function(node, computedStyle){
+		// summary:
+		//		Existing alias for `dojo.getPadExtents`. Deprecated, will be removed in 2.0.
+	};
+	=====*/
+
+	/*=====
+	dojo.getBorderExtents = function(node, 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
+		//
+		//		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._getBorderExtents = function(node, computedStyle){
+		// summary:
+		//		Existing alias for `dojo.getBorderExtents`. Deprecated, will be removed in 2.0.
+	};
+	=====*/
+
+	/*=====
+	dojo.getPadBorderExtents = function(node, 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
+		//
+		//		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";
+
+	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),
+			b = geom.getBorderExtents(node, s);
+		return {
+			l: p.l + b.l,
+			t: p.t + b.t,
+			r: p.r + b.r,
+			b: p.b + b.b,
+			w: p.w + b.w,
+			h: p.h + b.h
+		};
+	};
+
+	geom.getMarginExtents = function getMarginExtents(node, computedStyle){
+		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};
+	};
+
+	// Box getters work in any box context because offsetWidth/clientWidth
+	// are invariant wrt box context
+	//
+	// They do *not* work for display: inline objects that have padding styles
+	// because the user agent ignores padding (it's bogus styling in any case)
+	//
+	// Be careful with IMGs because they are inline or block depending on
+	// browser and browser mode.
+
+	// Although it would be easier to read, there are not separate versions of
+	// _getMarginBox for each browser because:
+	// 1. the branching is not expensive
+	// 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){
+		// summary:
+		//		returns an object that encodes the width, height, left and top
+		//		positions of the node's margin box.
+		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
+			// by the parent's border.
+			// We don't want to compute the parent's style, so instead we examine node's
+			// 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;
+			}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.
+				if(p && p.style){
+					pcs = style.getComputedStyle(p);
+					if(pcs.overflow != "visible"){
+						l += pcs.borderLeftStyle != none ? px(node, pcs.borderLeftWidth) : 0;
+						t += pcs.borderTopStyle != none ? px(node, pcs.borderTopWidth) : 0;
+					}
+				}
+			}
+		}else if(has("opera") || (has("ie") == 8 && !has("quirks"))){
+			// On Opera and IE 8, offsetLeft/Top includes the parent's border
+			if(p){
+				pcs = style.getComputedStyle(p);
+				l -= pcs.borderLeftStyle != none ? px(node, pcs.borderLeftWidth) : 0;
+				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){
+		// clientWidth/Height are important since the automatically account for scrollbars
+		// fallback to offsetWidth/Height for special cases (see #3378)
+		node = dom.byId(node);
+		var s = computedStyle || style.getComputedStyle(node), w = node.clientWidth, h,
+			pe = geom.getPadExtents(node, s), be = geom.getBorderExtents(node, s);
+		if(!w){
+			w = node.offsetWidth;
+			h = node.offsetHeight;
+		}else{
+			h = node.clientHeight;
+			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.
+	//
+	// Beware of display: inline objects that have padding styles
+	// because the user agent ignores padding (it's a bogus setup anyway)
+	//
+	// Be careful with IMGs because they are inline or block depending on
+	// browser and browser mode.
+	//
+	// Elements other than DIV may have special quirks, like built-in
+	// margins or padding, or values not detectable via computedStyle.
+	// 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){
+		// summary:
+		//		sets width/height/left/top in the current (native) box-model
+		//		dimensions. Uses the unit passed in u.
+		// node:
+		//		DOM Node reference. Id string not supported for performance
+		//		reasons.
+		// l:
+		//		left offset from parent.
+		// t:
+		//		top offset from parent.
+		// w:
+		//		width in current box model.
+		// h:
+		//		width in current box model.
+		// u:
+		//		unit measure to use for other measures. Defaults to "px".
+		u = u || "px";
+		var s = node.style;
+		if(!isNaN(l)){
+			s.left = l + u;
+		}
+		if(!isNaN(t)){
+			s.top = t + u;
+		}
+		if(w >= 0){
+			s.width = w + u;
+		}
+		if(h >= 0){
+			s.height = h + u;
+		}
+	}
+
+	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){
+		// summary:
+		//		True if the node uses border-box layout.
+
+		// We could test the computed style of node to see if a particular box
+		// has been specified, but there are details and we choose not to bother.
+
+		// TABLE and BUTTON (and INPUT type=button) are always border-box by default.
+		// If you have assigned a different box to either one via CSS then
+		// box functions will break.
+
+		return geom.boxModel == "border-box" || node.tagName.toLowerCase() == "table" || isButtonTag(node); // boolean
+	}
+
+	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 = dom.byId(node);
+		var w = box.w, h = box.h;
+		if(usesBorderBox(node)){
+			var pb = geom.getPadBorderExtents(node, computedStyle);
+			if(w >= 0){
+				w += pb.w;
+			}
+			if(h >= 0){
+				h += pb.h;
+			}
+		}
+		setBox(node, NaN, NaN, w, h);
+	};
+
+	var nilExtents = {l: 0, t: 0, w: 0, h: 0};
+
+	geom.setMarginBox = function setMarginBox(/*DomNode*/node, /*Object*/box, /*Object*/computedStyle){
+		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.
+			pb = usesBorderBox(node) ? nilExtents : geom.getPadBorderExtents(node, s),
+			mb = geom.getMarginExtents(node, s);
+		if(has("webkit")){
+			// on Safari (3.1.2), button nodes with no explicit size have a default margin
+			// setting an explicit size eliminates the margin.
+			// We have to swizzle the width to get correct margin reading.
+			if(isButtonTag(node)){
+				var ns = node.style;
+				if(w >= 0 && !ns.width){
+					ns.width = "4px";
+				}
+				if(h >= 0 && !ns.height){
+					ns.height = "4px";
+				}
+			}
+		}
+		if(w >= 0){
+			w = Math.max(w - pb.w - mb.w, 0);
+		}
+		if(h >= 0){
+			h = Math.max(h - pb.h - mb.h, 0);
+		}
+		setBox(node, box.l, box.t, w, h);
+	};
+
+	// =============================
+	// Positioning
+	// =============================
+
+	geom.isBodyLtr = function isBodyLtr(){
+		return (win.body().dir || win.doc.documentElement.dir || "ltr").toLowerCase() == "ltr"; // 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 });
+	};
+
+	//>>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
+
+		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
+			};
+		}
+	};
+	//>>excludeEnd("webkitMobile");
+
+	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);
+		var ie = has("ie");
+		if(ie && !geom.isBodyLtr()){
+			var qk = has("quirks"),
+				de = qk ? win.body() : win.doc.documentElement;
+			if(ie == 6 && !qk && win.global.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){
+		node = dom.byId(node);
+		var	db = win.body(),
+			dh = db.parentNode,
+			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();
+
+			// 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();
+			ret.x += scroll.x;
+			ret.y += scroll.y;
+		}
+
+		return ret; // Object
+	};
+
+	// random "private" functions wildly used throughout the toolkit
+
+	geom.getMarginSize = function getMarginSize(/*DomNode*/node, /*Object*/computedStyle){
+		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
+		// event: Object
+		if(!("layerX" in event)){
+			event.layerX = event.offsetX;
+			event.layerY = event.offsetY;
+		}
+		if(!has("dom-addeventlistener")){
+			// old IE version
+			// FIXME: scroll position query is duped from dojo.html to
+			// avoid dependency on that entire module. Now that HTML is in
+			// Base, we should convert back to something similar there.
+			var se = event.target;
+			var doc = (se && se.ownerDocument) || document;
+			// 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;
+			event.pageY = event.clientY + (docBody.scrollTop || 0) - offset.y;
+		}
+	};
+
+	// TODO: evaluate separate getters/setters for position and sizes?
+
+	return geom;
+});
diff --git a/dojo/dom-prop.js b/dojo/dom-prop.js
new file mode 100644
index 0000000..cd932ae
--- /dev/null
+++ b/dojo/dom-prop.js
@@ -0,0 +1,196 @@
+define(["exports", "./_base/kernel", "./_base/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().
+
+	// =============================
+	// Element properties Functions
+	// =============================
+
+	/*=====
+	prop.get = function(node, name){
+		// summary:
+		//		Gets a property on an HTML element.
+		// description:
+		//		Handles normalized getting of properties on DOM nodes.
+		//
+		// node: DOMNode|String
+		//		id or reference to the element to get the property on
+		// name: String
+		//		the name of the property to get.
+		// returns:
+		//		the value of the requested property or its default value
+		//
+		// example:
+		//	|	// get the current value of the "foo" property on a node
+		//	|	dojo.getProp(dojo.byId("nodeId"), "foo");
+		//	|	// or we can just pass the id:
+		//	|	dojo.getProp("nodeId", "foo");
+	};
+	=====*/
+
+	/*=====
+	prop.set = function(node, name, value){
+		// summary:
+		//		Sets a property on an HTML element.
+		// description:
+		//		Handles normalized setting of properties on DOM nodes.
+		//
+		//		When passing functions as values, note that they will not be
+		//		directly assigned to slots on the node, but rather the default
+		//		behavior will be removed and the new behavior will be added
+		//		using `dojo.connect()`, meaning that event handler properties
+		//		will be normalized and that some caveats with regards to
+		//		non-standard behaviors for onsubmit apply. Namely that you
+		//		should cancel form submission using `dojo.stopEvent()` on the
+		//		passed event object instead of returning a boolean value from
+		//		the handler itself.
+		// node: DOMNode|String
+		//		id or reference to the element to set the property on
+		// name: String|Object
+		//		the name of the property to set, or a hash object to set
+		//		multiple properties at once.
+		// value: String?
+		//		The value to set for the property
+		// returns:
+		//		the DOM node
+		//
+		// example:
+		//	|	// use prop() to set the tab index
+		//	|	dojo.setProp("nodeId", "tabIndex", 3);
+		//	|
+		//
+		// example:
+		//	Set multiple values at once, including event handlers:
+		//	|	dojo.setProp("formId", {
+		//	|		"foo": "bar",
+		//	|		"tabIndex": -1,
+		//	|		"method": "POST",
+		//	|		"onsubmit": function(e){
+		//	|			// stop submitting the form. Note that the IE behavior
+		//	|			// of returning true or false will have no effect here
+		//	|			// since our handler is connect()ed to the built-in
+		//	|			// onsubmit behavior and so we need to use
+		//	|			// dojo.stopEvent() to ensure that the submission
+		//	|			// doesn't proceed.
+		//	|			dojo.stopEvent(e);
+		//	|
+		//	|			// submit the form with Ajax
+		//	|			dojo.xhrPost({ form: "formId" });
+		//	|		}
+		//	|	});
+		//
+		// example:
+		//	Style is s special case: Only set with an object hash of styles
+		//	|	dojo.setProp("someNode",{
+		//	|		id:"bar",
+		//	|		style:{
+		//	|			width:"200px", height:"100px", color:"#000"
+		//	|		}
+		//	|	});
+		//
+		// example:
+		//	Again, only set style as an object hash of styles:
+		//	|	var obj = { color:"#fff", backgroundColor:"#000" };
+		//	|	dojo.setProp("someNode", "style", obj);
+		//	|
+		//	|	// 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
+			// the object form of setter: the 2nd argument is a dictionary
+			for(var x in name){
+				exports.set(node, x, name[x]);
+			}
+			return node; // DomNode
+		}
+		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);
+			return node; // DomNode
+		}
+		if(propName == "innerHTML"){
+			// special case: assigning HTML
+			//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
+			if(has("ie") && node.tagName.toLowerCase() in _roInnerHtml){
+				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)){
+			// special case: assigning an event handler
+			// clobber if we can
+			var attrId = node[_attrId];
+			if(!attrId){
+				attrId = _ctr++;
+				node[_attrId] = attrId;
+			}
+			if(!_evtHdlrMap[attrId]){
+				_evtHdlrMap[attrId] = {};
+			}
+			var h = _evtHdlrMap[attrId][propName];
+			if(h){
+				//h.remove();
+				conn.disconnect(h);
+			}else{
+				try{
+					delete node[propName];
+				}catch(e){}
+			}
+			// ensure that event objects are normalized, etc.
+			if(value){
+				//_evtHdlrMap[attrId][propName] = on(node, propName, value);
+				_evtHdlrMap[attrId][propName] = conn.connect(node, propName, value);
+			}else{
+				node[propName] = null;
+			}
+			return node; // DomNode
+		}
+		node[propName] = value;
+		return node;	// DomNode
+	};
+});
diff --git a/dojo/dom-style.js b/dojo/dom-style.js
new file mode 100644
index 0000000..3ceec84
--- /dev/null
+++ b/dojo/dom-style.js
@@ -0,0 +1,337 @@
+define(["./_base/sniff", "./dom"], function(has, dom){
+	// module:
+	//		dojo/dom-style
+	// summary:
+	//		This module defines the core dojo DOM style API.
+
+	// =============================
+	// Style Functions
+	// =============================
+
+	// getComputedStyle drives most of the style code.
+	// Wherever possible, reuse the returned object.
+	//
+	// API functions below that need to access computed styles accept an
+	// optional computedStyle parameter.
+	// If this parameter is omitted, the functions will call getComputedStyle themselves.
+	// This way, calling code can access computedStyle once, and then pass the reference to
+	// multiple API functions.
+
+	/*=====
+	dojo.getComputedStyle = function(node){
+		// summary:
+		//		Returns a "computed style" object.
+		//
+		// description:
+		//		Gets a "computed style" object which can be used to gather
+		//		information about the current state of the rendered node.
+		//
+		//		Note that this may behave differently on different browsers.
+		//		Values may have different formats and value encodings across
+		//		browsers.
+		//
+		//		Note also that this method is expensive.  Wherever possible,
+		//		reuse the returned object.
+		//
+		//		Use the dojo.style() method for more consistent (pixelized)
+		//		return values.
+		//
+		// node: DOMNode
+		//		A reference to a DOM node. Does NOT support taking an
+		//		ID string for speed reasons.
+		// example:
+		//	|	dojo.getComputedStyle(dojo.byId('foo')).borderWidth;
+		//
+		// example:
+		//		Reusing the returned object, avoiding multiple lookups:
+		//	|	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; }
+			// on IE7, medium is usually 4 pixels
+			if(avalue == "medium"){ return 4; }
+			// style values can be floats, client code may
+			// want to round this value for integer pixels.
+			if(avalue.slice && avalue.slice(-2) == 'px'){ return parseFloat(avalue); }
+			var s = element.style, rs = element.runtimeStyle, cs = element.currentStyle,
+				sLeft = s.left, rsLeft = rs.left;
+			rs.left = cs.left;
+			try{
+				// 'avalue' may be incompatible with style.left, which can cause IE to throw
+				// this has been observed for border widths using "thin", "medium", "thick" constants
+				// those particular constants could be trapped by a lookup
+				// but perhaps there are more
+				s.left = avalue;
+				avalue = s.pixelLeft;
+			}catch(e){
+				avalue = 0;
+			}
+			s.left = sLeft;
+			rs.left = rsLeft;
+			return avalue;
+		}
+	}
+	//>>excludeEnd("webkitMobile");
+	style.toPixelValue = toPixel;
+
+	// 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{
+			return n.filters.item(astr);
+		}catch(e){
+			return f ? {} : null;
+		}
+	};
+
+	//>>excludeEnd("webkitMobile");
+	var _getOpacity =
+	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
+		has("ie") < 9 || (has("ie") && 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;
+
+			if(!af(node)){
+				if(opaque){
+					return opacity;
+				}
+				node.style.filter += " progid:" + astr + "(Opacity=" + ov + ")";
+			}else{
+				af(node, 1).Opacity = ov;
+			}
+
+			// 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"){
+						_setOpacity(td, opacity);
+					}
+				}
+			}
+			return opacity;
+		} :
+		//>>excludeEnd("webkitMobile");
+		function(node, opacity){
+			return node.style.opacity = opacity;
+		};
+
+	var _pixelNamesCache = {
+		left: true, top: true
+	};
+	var _pixelRegExp = /margin|padding|width|height|max|min|offset/; // |border
+	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; }
+				if(type == "width"){ return node.offsetWidth; }
+			}
+			if(type == "fontweight"){
+				switch(value){
+					case 700: return "bold";
+					case 400:
+					default: return "normal";
+				}
+			}
+		}
+		//>>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};
+
+	// public API
+
+	style.get = function getStyle(/*DOMNode|String*/ node, /*String?*/ name){
+		var n = dom.byId(node), l = arguments.length, op = (name == "opacity");
+		if(l == 2 && op){
+			return _getOpacity(n);
+		}
+		name = _floatAliases[name] || 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){
+		var n = dom.byId(node), l = arguments.length, op = (name == "opacity");
+		name = _floatAliases[name] || name;
+		if(l == 3){
+			return op ? _setOpacity(n, value) : n.style[name] = value; // Number
+		}
+		for(var x in name){
+			style.set(node, x, name[x]);
+		}
+		return style.getComputedStyle(n);
+	};
+
+	return style;
+});
diff --git a/dojo/dom.js b/dojo/dom.js
new file mode 100644
index 0000000..a6696a7
--- /dev/null
+++ b/dojo/dom.js
@@ -0,0 +1,166 @@
+define(["./_base/sniff", "./_base/lang", "./_base/window"],
+		function(has, lang, 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"
+	}
+	//>>excludeEnd("webkitMobile");
+
+	// =============================
+	// DOM Functions
+	// =============================
+
+	/*=====
+	dojo.byId = function(id, doc){
+		// 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);
+	};
+	=====*/
+
+	var dom = {};   // the result object
+
+	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
+	if(has("ie")){
+		dom.byId = function(id, doc){
+			if(typeof id != "string"){
+				return id;
+			}
+			var _d = doc || win.doc, te = id && _d.getElementById(id);
+			// attributes.id.value is better than just id in case the
+			// user has a name=id inside a form
+			if(te && (te.attributes.id.value == id || te.id == id)){
+				return te;
+			}else{
+				var eles = _d.all[id];
+				if(!eles || eles.nodeName){
+					eles = [eles];
+				}
+				// if more than 1, choose first with the correct id
+				var i = 0;
+				while((te = eles[i++])){
+					if((te.attributes && te.attributes.id && te.attributes.id.value == id) || te.id == id){
+						return te;
+					}
+				}
+			}
+		};
+	}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.isDescendant = function(/*DOMNode|String*/node, /*DOMNode|String*/ancestor){
+		try{
+			node = dom.byId(node);
+			ancestor = dom.byId(ancestor);
+			while(node){
+				if(node == ancestor){
+					return true; // Boolean
+				}
+				node = node.parentNode;
+			}
+		}catch(e){ /* squelch, return false */ }
+		return false; // Boolean
+	};
+
+	// TODO: do we need this function in the base?
+
+	dom.setSelectable = function(/*DOMNode|String*/node, /*Boolean*/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;
+			}
+		}
+		//>>excludeEnd("webkitMobile");
+		//FIXME: else?  Opera?
+	};
+
+	return dom;
+});
diff --git a/dojo/domReady.js b/dojo/domReady.js
new file mode 100644
index 0000000..64ea1c0
--- /dev/null
+++ b/dojo/domReady.js
@@ -0,0 +1,95 @@
+define(['./has'], function(has){
+	var global = this,
+		doc = document,
+		readyStates = { 'loaded': 1, 'complete': 1 },
+		fixReadyState = typeof doc.readyState != "string",
+		ready = !!readyStates[doc.readyState];
+
+	// For FF <= 3.5
+	if(fixReadyState){ doc.readyState = "loading"; }
+
+	if(!ready){
+		var readyQ = [], 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())();
+				}
+			},
+			on = function(node, event){
+				node.addEventListener(event, detectReady, false);
+				readyQ.push(function(){ node.removeEventListener(event, detectReady, false); });
+			};
+
+		if(!has("dom-addeventlistener")){
+			on = function(node, event){
+				event = "on" + event;
+				node.attachEvent(event, detectReady);
+				readyQ.push(function(){ node.detachEvent(event, detectReady); });
+			};
+
+			var div = doc.createElement("div");
+			try{
+				if(div.doScroll && global.frameElement === null){
+					// the doScroll test is only useful if we're in the top-most frame
+					tests.push(function(){
+						// Derived with permission from Diego Perini's IEContentLoaded
+						// http://javascript.nwbox.com/IEContentLoaded/
+						try{
+							div.doScroll("left");
+							return 1;
+						}catch(e){}
+					});
+				}
+			}catch(e){}
+		}
+
+		on(doc, "DOMContentLoaded");
+		on(global, "load");
+
+		if("onreadystatechange" in doc){
+			on(doc, "readystatechange");
+		}else if(!fixReadyState){
+			// if the ready state property exists and there's
+			// no readystatechange event, poll for the state
+			// to change
+			tests.push(function(){
+				return readyStates[doc.readyState];
+			});
+		}
+
+		if(tests.length){
+			var poller = function(){
+				if(ready){ return; }
+				var i = tests.length;
+				while(i--){
+					if(tests[i]()){
+						detectReady("poller");
+						return;
+					}
+				}
+				setTimeout(poller, 30);
+			};
+			poller();
+		}
+	}
+
+	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/fx.js b/dojo/fx.js
index bf56136..55160ff 100644
--- a/dojo/fx.js
+++ b/dojo/fx.js
@@ -1,14 +1,41 @@
-define("dojo/fx", ["dojo", "dojo/fx/Toggler"], function(dojo) {
+define([
+	"./_base/lang",
+	"./Evented",
+	"./_base/kernel",
+	"./_base/array",
+	"./_base/connect",
+	"./_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) {
 
-/*=====
-dojo.fx = {
-	// summary: Effects library on top of Base animations
-};
-=====*/
-(function(){
+	// module:
+	//		dojo/fx
+	// summary:
+	//		TODOC
+
+
+	/*=====
+	dojo.fx = {
+		// summary: Effects library on top of Base animations
+	};
+	var coreFx = dojo.fx;
+	=====*/
 	
-	var d = dojo,
-		_baseObj = {
+// 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 _baseObj = {
 			_fire: function(evt, args){
 				if(this[evt]){
 					this[evt].apply(this, args||[]);
@@ -23,60 +50,61 @@ dojo.fx = {
 		this._current = this._onAnimateCtx = this._onEndCtx = null;
 
 		this.duration = 0;
-		d.forEach(this._animations, function(a){
+		arrayUtil.forEach(this._animations, function(a){
 			this.duration += a.duration;
 			if(a.delay){ this.duration += a.delay; }
 		}, this);
 	};
-	d.extend(_chain, {
+	_chain.prototype = new Evented();
+	lang.extend(_chain, {
 		_onAnimate: function(){
 			this._fire("onAnimate", arguments);
 		},
 		_onEnd: function(){
-			d.disconnect(this._onAnimateCtx);
-			d.disconnect(this._onEndCtx);
+			connect.disconnect(this._onAnimateCtx);
+			connect.disconnect(this._onEndCtx);
 			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 = d.connect(this._current, "onAnimate", this, "_onAnimate");
-				this._onEndCtx = d.connect(this._current, "onEnd", this, "_onEnd");
+				this._onAnimateCtx = connect.connect(this._current, "onAnimate", this, "_onAnimate");
+				this._onEndCtx = connect.connect(this._current, "onEnd", this, "_onEnd");
 				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 = d.connect(this._current, "beforeBegin", this, function(){
+			var beforeBegin = connect.connect(this._current, "beforeBegin", this, function(){
 					this._fire("beforeBegin");
 				}),
-				onBegin = d.connect(this._current, "onBegin", this, function(arg){
+				onBegin = connect.connect(this._current, "onBegin", this, function(arg){
 					this._fire("onBegin", arguments);
 				}),
-				onPlay = d.connect(this._current, "onPlay", this, function(arg){
+				onPlay = connect.connect(this._current, "onPlay", this, function(arg){
 					this._fire("onPlay", arguments);
-					d.disconnect(beforeBegin);
-					d.disconnect(onBegin);
-					d.disconnect(onPlay);
+					connect.disconnect(beforeBegin);
+					connect.disconnect(onBegin);
+					connect.disconnect(onPlay);
 				});
 			if(this._onAnimateCtx){
-				d.disconnect(this._onAnimateCtx);
+				connect.disconnect(this._onAnimateCtx);
 			}
-			this._onAnimateCtx = d.connect(this._current, "onAnimate", this, "_onAnimate");
+			this._onAnimateCtx = connect.connect(this._current, "onAnimate", this, "_onAnimate");
 			if(this._onEndCtx){
-				d.disconnect(this._onEndCtx);
+				connect.disconnect(this._onEndCtx);
 			}
-			this._onEndCtx = d.connect(this._current, "onEnd", this, "_onEnd");
+			this._onEndCtx = connect.connect(this._current, "onEnd", this, "_onEnd");
 			this._current.play.apply(this._current, arguments);
 			return this;
 		},
 		pause: function(){
 			if(this._current){
-				var e = d.connect(this._current, "onPause", this, function(arg){
+				var e = connect.connect(this._current, "onPause", this, function(arg){
 						this._fire("onPause", arguments);
-						d.disconnect(e);
+						connect.disconnect(e);
 					});
 				this._current.pause();
 			}
@@ -86,7 +114,7 @@ dojo.fx = {
 			this.pause();
 			var offset = this.duration * percent;
 			this._current = null;
-			d.some(this._animations, function(a){
+			arrayUtil.some(this._animations, function(a){
 				if(a.duration <= offset){
 					this._current = a;
 					return true;
@@ -107,9 +135,9 @@ dojo.fx = {
 					}
 					this._current = this._animations[this._index];
 				}
-				var e = d.connect(this._current, "onStop", this, function(arg){
+				var e = connect.connect(this._current, "onStop", this, function(arg){
 						this._fire("onStop", arguments);
-						d.disconnect(e);
+						connect.disconnect(e);
 					});
 				this._current.stop();
 			}
@@ -119,13 +147,13 @@ dojo.fx = {
 			return this._current ? this._current.status() : "stopped";
 		},
 		destroy: function(){
-			if(this._onAnimateCtx){ d.disconnect(this._onAnimateCtx); }
-			if(this._onEndCtx){ d.disconnect(this._onEndCtx); }
+			if(this._onAnimateCtx){ connect.disconnect(this._onAnimateCtx); }
+			if(this._onEndCtx){ connect.disconnect(this._onEndCtx); }
 		}
 	});
-	d.extend(_chain, _baseObj);
+	lang.extend(_chain, _baseObj);
 
-	dojo.fx.chain = function(/*dojo.Animation[]*/ animations){
+	coreFx.chain = /*===== dojo.fx.chain = =====*/ function(/*dojo.Animation[]*/ animations){
 		// summary:
 		//		Chain a list of `dojo.Animation`s to run in sequence
 		//
@@ -143,7 +171,7 @@ dojo.fx = {
 		//	|		dojo.fadeOut({ node:otherNode })
 		//	|	]).play();
 		//
-		return new _chain(animations) // dojo.Animation
+		return new _chain(animations); // dojo.Animation
 	};
 
 	var _combine = function(animations){
@@ -152,26 +180,26 @@ dojo.fx = {
 		this._finished = 0;
 
 		this.duration = 0;
-		d.forEach(animations, function(a){
+		arrayUtil.forEach(animations, function(a){
 			var duration = a.duration;
 			if(a.delay){ duration += a.delay; }
 			if(this.duration < duration){ this.duration = duration; }
-			this._connects.push(d.connect(a, "onEnd", this, "_onEnd"));
+			this._connects.push(connect.connect(a, "onEnd", this, "_onEnd"));
 		}, this);
-		
-		this._pseudoAnimation = new d.Animation({curve: [0, 1], duration: this.duration});
+
+		this._pseudoAnimation = new baseFx.Animation({curve: [0, 1], duration: this.duration});
 		var self = this;
-		d.forEach(["beforeBegin", "onBegin", "onPlay", "onAnimate", "onPause", "onStop", "onEnd"],
+		arrayUtil.forEach(["beforeBegin", "onBegin", "onPlay", "onAnimate", "onPause", "onStop", "onEnd"],
 			function(evt){
-				self._connects.push(d.connect(self._pseudoAnimation, evt,
+				self._connects.push(connect.connect(self._pseudoAnimation, evt,
 					function(){ self._fire(evt, arguments); }
 				));
 			}
 		);
 	};
-	d.extend(_combine, {
+	lang.extend(_combine, {
 		_doAction: function(action, args){
-			d.forEach(this._animations, function(a){
+			arrayUtil.forEach(this._animations, function(a){
 				a[action].apply(a, args);
 			});
 			return this;
@@ -198,7 +226,7 @@ dojo.fx = {
 		},
 		gotoPercent: function(/*Decimal*/percent, /*Boolean?*/ andPlay){
 			var ms = this.duration * percent;
-			d.forEach(this._animations, function(a){
+			arrayUtil.forEach(this._animations, function(a){
 				a.gotoPercent(a.duration < ms ? 1 : (ms / a.duration), andPlay);
 			});
 			this._call("gotoPercent", arguments);
@@ -213,12 +241,12 @@ dojo.fx = {
 			return this._pseudoAnimation.status();
 		},
 		destroy: function(){
-			d.forEach(this._connects, dojo.disconnect);
+			arrayUtil.forEach(this._connects, connect.disconnect);
 		}
 	});
-	d.extend(_combine, _baseObj);
+	lang.extend(_combine, _baseObj);
 
-	dojo.fx.combine = function(/*dojo.Animation[]*/ animations){
+	coreFx.combine = /*===== dojo.fx.combine = =====*/ function(/*dojo.Animation[]*/ animations){
 		// summary:
 		//		Combine a list of `dojo.Animation`s to run in parallel
 		//
@@ -248,7 +276,7 @@ dojo.fx = {
 		return new _combine(animations); // dojo.Animation
 	};
 
-	dojo.fx.wipeIn = function(/*Object*/ args){
+	coreFx.wipeIn = /*===== dojo.fx.wipeIn = =====*/ function(/*Object*/ args){
 		// summary:
 		//		Expand a node to it's natural height.
 		//
@@ -266,9 +294,9 @@ dojo.fx = {
 		//	|	dojo.fx.wipeIn({
 		//	|		node:"someId"
 		//	|	}).play()
-		var node = args.node = d.byId(args.node), s = node.style, o;
+		var node = args.node = dom.byId(args.node), s = node.style, o;
 
-		var anim = d.animateProperty(d.mixin({
+		var anim = baseFx.animateProperty(lang.mixin({
 			properties: {
 				height: {
 					// wrapped in functions so we wait till the last second to query (in case value has changed)
@@ -283,7 +311,7 @@ dojo.fx = {
 							s.visibility = "";
 							return 1;
 						}else{
-							var height = d.style(node, "height");
+							var height = domStyle.get(node, "height");
 							return Math.max(height, 1);
 						}
 					},
@@ -294,15 +322,17 @@ dojo.fx = {
 			}
 		}, args));
 
-		d.connect(anim, "onEnd", function(){
+		var fini = function(){
 			s.height = "auto";
 			s.overflow = o;
-		});
+		};
+		connect.connect(anim, "onStop", fini);
+		connect.connect(anim, "onEnd", fini);
 
 		return anim; // dojo.Animation
 	};
 
-	dojo.fx.wipeOut = function(/*Object*/ args){
+	coreFx.wipeOut = /*===== dojo.fx.wipeOut = =====*/ function(/*Object*/ args){
 		// summary:
 		//		Shrink a node to nothing and hide it.
 		//
@@ -316,10 +346,10 @@ dojo.fx = {
 		//
 		// example:
 		//	|	dojo.fx.wipeOut({ node:"someId" }).play()
-		
-		var node = args.node = d.byId(args.node), s = node.style, o;
-		
-		var anim = d.animateProperty(d.mixin({
+
+		var node = args.node = dom.byId(args.node), s = node.style, o;
+
+		var anim = baseFx.animateProperty(lang.mixin({
 			properties: {
 				height: {
 					end: 1 // 0 causes IE to display the whole panel
@@ -327,21 +357,23 @@ dojo.fx = {
 			}
 		}, args));
 
-		d.connect(anim, "beforeBegin", function(){
+		connect.connect(anim, "beforeBegin", function(){
 			o = s.overflow;
 			s.overflow = "hidden";
 			s.display = "";
 		});
-		d.connect(anim, "onEnd", function(){
+		var fini = function(){
 			s.overflow = o;
 			s.height = "auto";
 			s.display = "none";
-		});
+		};
+		connect.connect(anim, "onStop", fini);
+		connect.connect(anim, "onEnd", fini);
 
 		return anim; // dojo.Animation
 	};
 
-	dojo.fx.slideTo = function(/*Object*/ args){
+	coreFx.slideTo = /*===== dojo.fx.slideTo = =====*/ function(/*Object*/ args){
 		// summary:
 		//		Slide a node to a new top/left position
 		//
@@ -356,19 +388,19 @@ dojo.fx = {
 		//		are `top` and `left`, which indicate the new position to slide to.
 		//
 		// example:
-		//	|	dojo.fx.slideTo({ node: node, left:"40", top:"50", units:"px" }).play()
+		//	|	.slideTo({ node: node, left:"40", top:"50", units:"px" }).play()
 
-		var node = args.node = d.byId(args.node),
+		var node = args.node = dom.byId(args.node),
 			top = null, left = null;
 
 		var init = (function(n){
 			return function(){
-				var cs = d.getComputedStyle(n);
+				var cs = domStyle.getComputedStyle(n);
 				var pos = cs.position;
 				top = (pos == 'absolute' ? n.offsetTop : parseInt(cs.top) || 0);
 				left = (pos == 'absolute' ? n.offsetLeft : parseInt(cs.left) || 0);
 				if(pos != 'absolute' && pos != 'relative'){
-					var ret = d.position(n, true);
+					var ret = geom.position(n, true);
 					top = ret.y;
 					left = ret.x;
 					n.style.position="absolute";
@@ -379,18 +411,16 @@ dojo.fx = {
 		})(node);
 		init();
 
-		var anim = d.animateProperty(d.mixin({
+		var anim = baseFx.animateProperty(lang.mixin({
 			properties: {
 				top: args.top || 0,
 				left: args.left || 0
 			}
 		}, args));
-		d.connect(anim, "beforeBegin", anim, init);
+		connect.connect(anim, "beforeBegin", anim, init);
 
 		return anim; // dojo.Animation
 	};
 
-})();
-
-return dojo.fx;
+	return coreFx;
 });
diff --git a/dojo/fx/Toggler.js b/dojo/fx/Toggler.js
index 775dc8b..9fa5824 100644
--- a/dojo/fx/Toggler.js
+++ b/dojo/fx/Toggler.js
@@ -1,6 +1,11 @@
-define("dojo/fx/Toggler", ["dojo"], function(dojo) {
+define(["../_base/lang","../_base/declare","../_base/fx", "../_base/connect"], 
+  function(lang, declare, baseFx, connectUtil) {
+	// module:
+	//		dojo/fx/Toggler
+	// summary:
+	//		TODOC
 
-dojo.declare("dojo.fx.Toggler", null, {
+return declare("dojo.fx.Toggler", null, {
 	// summary:
 	//		A simple `dojo.Animation` toggler API.
 	//
@@ -29,11 +34,11 @@ dojo.declare("dojo.fx.Toggler", null, {
 
 	// showFunc: Function
 	//		The function that returns the `dojo.Animation` to show the node
-	showFunc: dojo.fadeIn,
+	showFunc: baseFx.fadeIn,
 
 	// hideFunc: Function
 	//		The function that returns the `dojo.Animation` to hide the node
-	hideFunc: dojo.fadeOut,
+	hideFunc: baseFx.fadeOut,
 
 	// showDuration:
 	//		Time in milliseconds to run the show Animation
@@ -64,20 +69,20 @@ dojo.declare("dojo.fx.Toggler", null, {
 	constructor: function(args){
 		var _t = this;
 
-		dojo.mixin(_t, args);
+		lang.mixin(_t, args);
 		_t.node = args.node;
-		_t._showArgs = dojo.mixin({}, args);
+		_t._showArgs = lang.mixin({}, args);
 		_t._showArgs.node = _t.node;
 		_t._showArgs.duration = _t.showDuration;
 		_t.showAnim = _t.showFunc(_t._showArgs);
 
-		_t._hideArgs = dojo.mixin({}, args);
+		_t._hideArgs = lang.mixin({}, args);
 		_t._hideArgs.node = _t.node;
 		_t._hideArgs.duration = _t.hideDuration;
 		_t.hideAnim = _t.hideFunc(_t._hideArgs);
 
-		dojo.connect(_t.showAnim, "beforeBegin", dojo.hitch(_t.hideAnim, "stop", true));
-		dojo.connect(_t.hideAnim, "beforeBegin", dojo.hitch(_t.showAnim, "stop", true));
+		connectUtil.connect(_t.showAnim, "beforeBegin", lang.hitch(_t.hideAnim, "stop", true));
+		connectUtil.connect(_t.hideAnim, "beforeBegin", lang.hitch(_t.showAnim, "stop", true));
 	},
 
 	show: function(delay){
@@ -95,5 +100,4 @@ dojo.declare("dojo.fx.Toggler", null, {
 	}
 });
 
-return dojo.fx.Toggler;
 });
diff --git a/dojo/fx/easing.js b/dojo/fx/easing.js
index c71411a..33d3c65 100644
--- a/dojo/fx/easing.js
+++ b/dojo/fx/easing.js
@@ -1,7 +1,10 @@
-define("dojo/fx/easing", ["dojo"], function(dojo) {
-dojo.getObject("fx.easing", true, dojo);
+define(["../_base/lang"], function(lang) {
+// module:
+//		dojo/fx/easing
+// summary:
+//		This module defines standard easing functions that are useful for animations.
 
-dojo.fx.easing = {
+var easingFuncs = /*===== dojo.fx.easing= =====*/ {
 	// summary:
 	//		Collection of easing functions to use beyond the default
 	//		`dojo._defaultEasing` function.
@@ -32,7 +35,7 @@ dojo.fx.easing = {
 	//	|		easing: dojo.fx.easing.quadIn
 	//	|	}).play();
 	//
-	
+
 	linear: function(/* Decimal? */n){
 		// summary: A linear easing function
 		return n;
@@ -92,7 +95,7 @@ dojo.fx.easing = {
 
 	quintInOut: function(/* Decimal? */n){
 		n = n * 2;
-		if(n < 1){ return Math.pow(n, 5) / 2; };
+		if(n < 1){ return Math.pow(n, 5) / 2; }
 		n -= 2;
 		return (Math.pow(n, 5) + 2) / 2;
 	},
@@ -162,7 +165,7 @@ dojo.fx.easing = {
 		//
 		//		Use caution when the easing will cause values to become negative as some
 		//		properties cannot be set to negative values.
-		
+
 		n = n - 1;
 		var s = 1.70158;
 		return Math.pow(n, 2) * ((s + 1) * n + s) + 1;
@@ -243,7 +246,7 @@ dojo.fx.easing = {
 	bounceIn: function(/* Decimal? */n){
 		// summary:
 		//		An easing function that 'bounces' near the beginning of an Animation
-		return (1 - dojo.fx.easing.bounceOut(1 - n)); // Decimal
+		return (1 - easingFuncs.bounceOut(1 - n)); // Decimal
 	},
 
 	bounceOut: function(/* Decimal? */n){
@@ -270,10 +273,12 @@ dojo.fx.easing = {
 	bounceInOut: function(/* Decimal? */n){
 		// summary:
 		//		An easing function that 'bounces' at the beginning and end of the Animation
-		if(n < 0.5){ return dojo.fx.easing.bounceIn(n * 2) / 2; }
-		return (dojo.fx.easing.bounceOut(n * 2 - 1) / 2) + 0.5; // Decimal
+		if(n < 0.5){ return easingFuncs.bounceIn(n * 2) / 2; }
+		return (easingFuncs.bounceOut(n * 2 - 1) / 2) + 0.5; // Decimal
 	}
 };
 
-return dojo.fx.easing;
+lang.setObject("dojo.fx.easing", easingFuncs);
+
+return easingFuncs;
 });
diff --git a/dojo/gears.js b/dojo/gears.js
index 213f259..bae1eb8 100644
--- a/dojo/gears.js
+++ b/dojo/gears.js
@@ -1,20 +1,25 @@
-define("dojo/gears", ["dojo"], function(dojo) {
-dojo.getObject("gears", true, dojo);
+define(["./_base/kernel", "./_base/lang", "./_base/sniff"],
+	function(dojo, lang, has) {
+	// module:
+	//		dojo/gears
+	// summary:
+	//		TODOC
+
+lang.getObject("gears", true, dojo);
 
 dojo.gears._gearsObject = function(){
 	// summary:
 	//		factory method to get a Google Gears plugin instance to
 	//		expose in the browser runtime environment, if present
 	var factory;
-	var results;
-	
-	var gearsObj = dojo.getObject("google.gears");
+
+	var gearsObj = lang.getObject("google.gears");
 	if(gearsObj){ return gearsObj; } // already defined elsewhere
-	
+
 	if(typeof GearsFactory != "undefined"){ // Firefox
 		factory = new GearsFactory();
 	}else{
-		if(dojo.isIE){
+		if(has("ie")){
 			// IE
 			try{
 				factory = new ActiveXObject("Gears.Factory");
@@ -34,12 +39,12 @@ dojo.gears._gearsObject = function(){
 
 	// still nothing?
 	if(!factory){ return null; }
-	
+
 	// define the global objects now; don't overwrite them though if they
 	// were somehow set internally by the Gears plugin, which is on their
 	// dev roadmap for the future
-	dojo.setObject("google.gears.factory", factory);
-	return dojo.getObject("google.gears");
+	lang.setObject("google.gears.factory", factory);
+	return lang.getObject("google.gears");
 };
 
 /*=====
diff --git a/dojo/has.js b/dojo/has.js
new file mode 100644
index 0000000..d219ff0
--- /dev/null
+++ b/dojo/has.js
@@ -0,0 +1,178 @@
+define(["require"], function(require) {
+	// module:
+	//		dojo/has
+	// summary:
+	//		Defines the has.js API and several feature tests used by dojo.
+	// 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.
+	//
+	//		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
+	// 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?
+				typeof window != "undefined" &&
+				typeof location != "undefined" &&
+				typeof document != "undefined" &&
+				window.location == location && window.document == document,
+
+			// has API variables
+			global = this,
+			doc = isBrowser && document,
+			element = doc && doc.createElement("DiV"),
+			cache = {};
+
+		has = /*===== dojo.has= =====*/ function(name){
+			//	summary:
+			//		Return the current value of the named feature.
+			//
+			//	name: String|Integer
+			//		The name (if a string) or identifier (if an integer) of the feature to test.
+			//
+			//	description:
+			//		Returns the value of the feature named by name. The feature must have been
+			//		previously added to the cache by has.add.
+
+			return typeof cache[name] == "function" ? (cache[name] = cache[name](global, doc, element)) : cache[name]; // Boolean
+		};
+
+		has.cache = cache;
+
+		has.add = /*====== dojo.has.add= ======*/ function(name, test, now, force){
+			// summary:
+			//	 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.
+			//
+			// 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.
+			//
+			// now: Boolean?
+			//	 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).
+			//
+			// example:
+			//			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);
+			//
+			// 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
+			//	|				});
+
+			(typeof cache[name]=="undefined" || force) && (cache[name]= test);
+			return now && has(name);
+		};
+
+		// since we're operating under a loader that doesn't provide a has API, we must explicitly initialize
+		// has as it would have otherwise been initialized by the dojo loader; use has.add to the builder
+		// can optimize these away iff desired
+		has.add("host-browser", isBrowser);
+		has.add("dom", isBrowser);
+		has.add("dojo-dom-ready-api", 1);
+		has.add("dojo-sniff", 1);
+	}
+
+	if(has("host-browser")){
+		var agent = navigator.userAgent;
+		// Common application level tests
+		has.add("dom-addeventlistener", !!document.addEventListener);
+		has.add("touch", "ontouchstart" in document);
+		// 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);
+	}
+
+	has.clearElement = /*===== dojo.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){
+		// summary:
+		//	 Resolves id into a module id based on possibly-nested tenary expression that branches on has feature test value(s).
+		//
+		// toAbsMid: Function
+		//	 Resolves a relative module id into an absolute module id
+		var
+			tokens = id.match(/[\?:]|[^:\?]*/g), i = 0,
+			get = function(skip){
+				var term = tokens[i++];
+				if(term == ":"){
+					// empty string module name, resolves to 0
+					return 0;
+				}else{
+					// postfixed with a ? means it is a feature to branch on, the term is the name of the feature
+					if(tokens[i++] == "?"){
+						if(!skip && has(term)){
+							// matched the feature, get the first value from the options
+							return get();
+						}else{
+							// did not match, get the second value, passing over the first
+							get(true);
+							return get(skip);
+						}
+					}
+					// a module
+					return term || 0;
+				}
+			};
+		id = get();
+		return id && toAbsMid(id);
+	};
+
+	has.load = /*===== dojo.has.load= ======*/ function(id, parentRequire, loaded){
+		// summary:
+		//	 Conditional loading of AMD modules based on a has feature test value.
+		//
+		// id: String
+		//	 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.
+		//
+		// loaded: Function
+		//	 Callback to loader that consumes result of plugin demand.
+
+		if(id){
+			parentRequire([id], loaded);
+		}else{
+			loaded();
+		}
+	};
+
+	return has;
+});
diff --git a/dojo/hash.js b/dojo/hash.js
index 0395309..643f5d1 100644
--- a/dojo/hash.js
+++ b/dojo/hash.js
@@ -1,4 +1,10 @@
-define("dojo/hash", ["dojo"], function(dojo) {
+define(["./_base/kernel", "require", "./_base/connect", "./_base/lang", "./ready", "./_base/sniff"],
+	function(dojo, require, connect, lang, ready, has) {
+	// module:
+	//		dojo/hash
+	// summary:
+	//		TODOC
+
 
 //TODOC: where does this go?
 // summary:
@@ -9,9 +15,8 @@ define("dojo/hash", ["dojo"], function(dojo) {
 //
 //		function callback (hashValue){
 //			// do something based on the hash value.
-// 		}
+//		}
 
-(function(){
 	dojo.hash = function(/* String? */ hash, /* Boolean? */ replace){
 		//	summary:
 		//		Gets or sets the hash string.
@@ -27,7 +32,7 @@ define("dojo/hash", ["dojo"], function(dojo) {
 		//	returns:
 		//		when used as a getter, returns the current hash string.
 		//		when used as a setter, returns the new hash string.
-		
+
 		// getter
 		if(!arguments.length){
 			return _getHash();
@@ -53,13 +58,13 @@ define("dojo/hash", ["dojo"], function(dojo) {
 		var i = str.indexOf(delimiter);
 		return (i >= 0) ? str.substring(i+1) : "";
 	}
-	
+
 	function _getHash(){
 		return _getSegment(location.href, "#");
 	}
 
 	function _dispatchEvent(){
-		dojo.publish("/dojo/hashchange", [_getHash()]);
+		connect.publish("/dojo/hashchange", [_getHash()]);
 	}
 
 	function _pollLocation(){
@@ -69,11 +74,11 @@ define("dojo/hash", ["dojo"], function(dojo) {
 		_recentHash = _getHash();
 		_dispatchEvent();
 	}
-	
+
 	function _replace(hash){
 		if(_ieUriMonitor){
 			if(_ieUriMonitor.isTransitioning()){
-				setTimeout(dojo.hitch(null,_replace,hash), _pollFrequency);
+				setTimeout(lang.hitch(null,_replace,hash), _pollFrequency);
 				return;
 			}
 			var href = _ieUriMonitor.iframe.location.href;
@@ -94,7 +99,7 @@ define("dojo/hash", ["dojo"], function(dojo) {
 		//	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
+		//		this IE difference, we use a background IFrame to maintain a back-forward
 		//		history, by updating the IFrame's query string to correspond to the
 		//		value of the main browser location's hash value.
 		//
@@ -126,7 +131,7 @@ define("dojo/hash", ["dojo"], function(dojo) {
 		//			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
+		//		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
@@ -137,7 +142,7 @@ define("dojo/hash", ["dojo"], function(dojo) {
 		// create and append iframe
 		var ifr = document.createElement("iframe"),
 			IFRAME_ID = "dojo-hash-iframe",
-			ifrSrc = dojo.config.dojoBlankHtmlUrl || dojo.moduleUrl("dojo", "resources/blank.html");
+			ifrSrc = dojo.config.dojoBlankHtmlUrl || require.toUrl("./resources/blank.html");
 
 		if(dojo.config.useXDomain && !dojo.config.dojoBlankHtmlUrl){
 			console.warn("dojo.hash: When using cross-domain Dojo builds,"
@@ -164,7 +169,7 @@ define("dojo/hash", ["dojo"], function(dojo) {
 		this.isTransitioning = function(){
 			return transitioning;
 		};
-		
+
 		this.pollLocation = function(){
 			if(!ifrOffline) {
 				try{
@@ -189,7 +194,7 @@ define("dojo/hash", ["dojo"], function(dojo) {
 					_dispatchEvent();
 				}else{
 					// s4 (waiting for iframe to catch up to main window)
-					setTimeout(dojo.hitch(this,this.pollLocation),0);
+					setTimeout(lang.hitch(this,this.pollLocation),0);
 					return;
 				}
 			}else if(_recentHash === hash && (ifrOffline || recentIframeQuery === iframeSearch)){
@@ -203,8 +208,8 @@ define("dojo/hash", ["dojo"], function(dojo) {
 					transitioning = true;
 					expectedIFrameQuery = hash;
 					ifr.src = ifrSrc + "?" + expectedIFrameQuery;
-					ifrOffline = false;	//we're updating the iframe src - set offline to false so we can check again on next poll.
-					setTimeout(dojo.hitch(this,this.pollLocation),0); //yielded transition to s4 while iframe reloads.
+					ifrOffline = false; //we're updating the iframe src - set offline to false so we can check again on next poll.
+					setTimeout(lang.hitch(this,this.pollLocation),0); //yielded transition to s4 while iframe reloads.
 					return;
 				}else if(!ifrOffline){
 					// s3 (iframe location changed via back/forward button), set main window url and transition to s1.
@@ -213,14 +218,14 @@ define("dojo/hash", ["dojo"], function(dojo) {
 					_dispatchEvent();
 				}
 			}
-			setTimeout(dojo.hitch(this,this.pollLocation), _pollFrequency);
+			setTimeout(lang.hitch(this,this.pollLocation), _pollFrequency);
 		};
 		resetState(); // initialize state (transition to s1)
-		setTimeout(dojo.hitch(this,this.pollLocation), _pollFrequency);
+		setTimeout(lang.hitch(this,this.pollLocation), _pollFrequency);
 	}
-	dojo.addOnLoad(function(){
-		if("onhashchange" in dojo.global && (!dojo.isIE || (dojo.isIE >= 8 && document.compatMode != "BackCompat"))){	//need this IE browser test because "onhashchange" exists in IE8 in IE7 mode
-			_connect = dojo.connect(dojo.global,"onhashchange",_dispatchEvent);
+	ready(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);
 		}else{
 			if(document.addEventListener){ // Non-IE
 				_recentHash = _getHash();
@@ -232,7 +237,7 @@ define("dojo/hash", ["dojo"], function(dojo) {
 			// else non-supported browser, do nothing.
 		}
 	});
-})();
 
-  return dojo.hash;
+	return dojo.hash;
+
 });
diff --git a/dojo/html.js b/dojo/html.js
index 03519d0..69ed136 100644
--- a/dojo/html.js
+++ b/dojo/html.js
@@ -1,13 +1,16 @@
-define("dojo/html", ["dojo", "dojo/parser"], function(dojo) {
-dojo.getObject("html", true, dojo);
+define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/declare", "./dom", "./dom-construct", "./parser"], function(dojo, lang, darray, declare, dom, domConstruct, parser) {
+	// module:
+	//		dojo/html
+	// summary:
+	//		TODOC
 
-// the parser might be needed..
-(function(){ // private scope, sort of a namespace
+	lang.getObject("html", true, dojo);
+
+	// the parser might be needed..
 
 	// idCounter is incremented with each instantiation to allow asignment of a unique id for tracking, logging purposes
-	var idCounter = 0,
-		d = dojo;
-	
+	var idCounter = 0;
+
 	dojo.html._secureForInnerHtml = function(/*String*/ cont){
 		// summary:
 		//		removes !DOCTYPE and title elements from the html string.
@@ -28,7 +31,7 @@ dojo.getObject("html", true, dojo);
 		//		the parent element
 	};
 =====*/
-	dojo.html._emptyNode = dojo.empty;
+	dojo.html._emptyNode = domConstruct.empty;
 
 	dojo.html._setNodeContent = function(/* DomNode */ node, /* String|DomNode|NodeList */ cont){
 		// summary:
@@ -38,22 +41,22 @@ dojo.getObject("html", true, dojo);
 		//	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
-		
+
 		// always empty
-		d.empty(node);
+		domConstruct.empty(node);
 
 		if(cont) {
 			if(typeof cont == "string") {
-				cont = d._toDom(cont, node.ownerDocument);
+				cont = domConstruct.toDom(cont, node.ownerDocument);
 			}
-			if(!cont.nodeType && d.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) {
-					d.place( cont[i], node, "last");
+					domConstruct.place( cont[i], node, "last");
 				}
 			} else {
 				// pass nodes, documentFragments and unknowns through to dojo.place
-				d.place(cont, node, "last");
+				domConstruct.place(cont, node, "last");
 			}
 		}
 
@@ -62,7 +65,7 @@ dojo.getObject("html", true, dojo);
 	};
 
 	// we wrap up the content-setting operation in a object
-	dojo.declare("dojo.html._ContentSetter", null,
+	declare("dojo.html._ContentSetter", null,
 		{
 			// node: DomNode|String
 			//		An node which will be the parent element that we set content into
@@ -71,7 +74,7 @@ dojo.getObject("html", true, dojo);
 			// content: String|DomNode|DomNode[]
 			//		The content to be placed in the node. Can be an HTML string, a node reference, or a enumerable list of nodes
 			content: "",
-			
+
 			// id: String?
 			//		Usually only used internally, and auto-generated with each instance
 			id: "",
@@ -80,7 +83,7 @@ dojo.getObject("html", true, dojo);
 			//		Should the content be treated as a full html document,
 			//		and the real content stripped of <html>, <body> wrapper before injection
 			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
 			extractContent: false,
@@ -90,29 +93,29 @@ dojo.getObject("html", true, dojo);
 			parseContent: false,
 
 			// parserScope: String
-			//		Flag passed to parser.  Root for attribute names to search for.   If scopeName is dojo,
+			//		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: dojo._scopeName,
 
 			// startup: Boolean
-			//		Start the child widgets after parsing them.   Only obeyed if parseContent is true.
+			//		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:
 				//		Provides a configurable, extensible object to wrap the setting on content on a node
 				//		call the set() method to actually set the content..
- 
+
 				// the original params are mixed directly into the instance "this"
-				dojo.mixin(this, params || {});
+				lang.mixin(this, params || {});
 
 				// give precedence to params.node vs. the node argument
 				// and ensure its a node, not an id string
-				node = this.node = dojo.byId( this.node || node );
-	
+				node = this.node = dom.byId( this.node || node );
+
 				if(!this.id){
 					this.id = [
 						"Setter",
@@ -147,7 +150,7 @@ dojo.getObject("html", true, dojo);
 
 				var node = this.node;
 				if(!node) {
-				    // can't proceed
+					// can't proceed
 					throw new Error(this.declaredClass + ": setContent given no node");
 				}
 				try{
@@ -155,7 +158,7 @@ dojo.getObject("html", true, dojo);
 				}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
-	
+
 					// FIXME: need to allow the user to provide a content error message string
 					var errMess = this.onContentError(e);
 					try{
@@ -167,7 +170,7 @@ dojo.getObject("html", true, dojo);
 				// always put back the node for the next method
 				this.node = node; // DomNode
 			},
-			
+
 			empty: function() {
 				// summary
 				//	cleanly empty out existing content
@@ -176,7 +179,7 @@ dojo.getObject("html", true, dojo);
 				// 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) {
-					dojo.forEach(this.parseResults, function(w) {
+					darray.forEach(this.parseResults, function(w) {
 						if(w.destroy){
 							w.destroy();
 						}
@@ -187,7 +190,7 @@ dojo.getObject("html", true, dojo);
 				// override empty to skip this step
 				dojo.html._emptyNode(this.node);
 			},
-	
+
 			onBegin: function(){
 				// summary
 				//		Called after instantiation, but before set();
@@ -196,12 +199,12 @@ dojo.getObject("html", true, dojo);
 				//		This default implementation checks for cleanContent and extractContent flags to
 				//		optionally pre-process html string content
 				var cont = this.content;
-	
-				if(dojo.isString(cont)){
+
+				if(lang.isString(cont)){
 					if(this.cleanContent){
 						cont = dojo.html._secureForInnerHtml(cont);
 					}
-  
+
 					if(this.extractContent){
 						var match = cont.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
 						if(match){ cont = match[1]; }
@@ -210,11 +213,11 @@ dojo.getObject("html", true, dojo);
 
 				// clean out the node and any cruft associated with it - like widgets
 				this.empty();
-				
+
 				this.content = cont;
 				return this.node; /* DomNode */
 			},
-	
+
 			onEnd: function(){
 				// summary
 				//		Called after set(), when the new content has been pushed into the node
@@ -226,7 +229,7 @@ dojo.getObject("html", true, dojo);
 				}
 				return this.node; /* DomNode */
 			},
-	
+
 			tearDown: function(){
 				// summary
 				//		manually reset the Setter instance if its being re-used for example for another set()
@@ -238,11 +241,11 @@ dojo.getObject("html", true, dojo);
 				delete this.node;
 				delete this.content;
 			},
-  
+
 			onContentError: function(err){
 				return "Error occured setting content: " + err;
 			},
-			
+
 			_mixin: function(params){
 				// mix properties/methods into the instance
 				// TODO: the intention with tearDown is to put the Setter's state
@@ -265,12 +268,12 @@ dojo.getObject("html", true, dojo);
 				try{
 					// store the results (widgets, whatever) for potential retrieval
 					var inherited = {};
-					dojo.forEach(["dir", "lang", "textDir"], function(name){
+					darray.forEach(["dir", "lang", "textDir"], function(name){
 						if(this[name]){
 							inherited[name] = this[name];
 						}
 					}, this);
-					this.parseResults = dojo.parser.parse({
+					this.parseResults = parser.parse({
 						rootNode: rootNode,
 						noStart: !this.startup,
 						inherited: inherited,
@@ -280,7 +283,7 @@ dojo.getObject("html", true, dojo);
 					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
@@ -327,14 +330,13 @@ dojo.getObject("html", true, dojo);
 		}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(dojo.mixin(
+			var op = new dojo.html._ContentSetter(lang.mixin(
 					params,
 					{ content: cont, node: node }
 			));
 			return op.set();
 		}
 	};
-})();
 
-return dojo.html;
+	return dojo.html;
 });
diff --git a/dojo/i18n.js b/dojo/i18n.js
index b6ca244..e916486 100644
--- a/dojo/i18n.js
+++ b/dojo/i18n.js
@@ -1,260 +1,301 @@
-define("dojo/i18n", ["require", "dojo"], function(require, dojo){
-dojo.getObject("i18n", true, dojo);
-
-/*=====
-dojo.i18n = {
-	// summary: Utility classes to enable loading of resources for internationalization (i18n)
-};
-=====*/
-
-// when using a real AMD loader, dojo.i18n.getLocalization is already defined by dojo/lib/backCompat
-dojo.i18n.getLocalization = dojo.i18n.getLocalization || function(/*String*/packageName, /*String*/bundleName, /*String?*/locale){
-	//	summary:
-	//		Returns an Object containing the localization for a given resource
-	//		bundle in a package, matching the specified locale.
-	//	description:
-	//		Returns a hash containing name/value pairs in its prototypesuch
-	//		that values can be easily overridden.  Throws an exception if the
-	//		bundle is not found.  Bundle must have already been loaded by
-	//		`dojo.requireLocalization()` or by a build optimization step.  NOTE:
-	//		try not to call this method as part of an object property
-	//		definition (`var foo = { bar: dojo.i18n.getLocalization() }`).  In
-	//		some loading situations, the bundle may not be available in time
-	//		for the object definition.  Instead, call this method inside a
-	//		function that is run after all modules load or the page loads (like
-	//		in `dojo.addOnLoad()`), or in a widget lifecycle method.
-	//	packageName:
-	//		package which is associated with this resource
-	//	bundleName:
-	//		the base filename of the resource bundle (without the ".js" suffix)
-	//	locale:
-	//		the variant to load (optional).  By default, the locale defined by
-	//		the host environment: dojo.locale
-
-	locale = dojo.i18n.normalizeLocale(locale);
-
-	// look for nearest locale match
-	var elements = locale.split('-');
-	var module = [packageName,"nls",bundleName].join('.');
-	//>>includeStart("asyncLoader", kwArgs.asynchLoader);
-	if (typeof dojo.global.require !== "undefined") {
-		// XXX: this only works for the default locale
-		var obj = require("i18n!" + [packageName.replace(/\./g, '/'), "nls", bundleName].join('/'));
-		(dojo._loadedModules[module] = dojo._loadedModules[module] || {})[elements.join('_')] = (obj.root || obj);
-	}
-	//>>includeEnd("asyncLoader");
-	var bundle = dojo._loadedModules[module];
-	if(bundle){
-		var localization;
-		for(var i = elements.length; i > 0; i--){
-			var loc = elements.slice(0, i).join('_');
-			if(bundle[loc]){
-				localization = bundle[loc];
-				break;
-			}
-		}
-		if(!localization){
-			localization = bundle.ROOT;
-		}
+define(["./_base/kernel", "require", "./has", "./_base/array", "./_base/config", "./_base/lang", "./_base/xhr"],
+	function(dojo, require, has, array, config, lang, xhr) {
+	// 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.
+	var
+		thisModule= dojo.i18n=
+			// the dojo.i18n module
+			{},
 
-		// make a singleton prototype so that the caller won't accidentally change the values globally
-		if(localization){
-			var clazz = function(){};
-			clazz.prototype = localization;
-			return new clazz(); // Object
-		}
-	}
+		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)(\/|$)([^\/]*)\/?([^\/]*)/,
 
-	throw new Error("Bundle not found: " + bundleName + " in " + packageName+" , locale=" + locale);
-};
-
-dojo.i18n.normalizeLocale = function(/*String?*/locale){
-	//	summary:
-	//		Returns canonical form of locale, as used by Dojo.
-	//
-	//  description:
-	//		All variants are case-insensitive and are separated by '-' as specified in [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt).
-	//		If no locale is specified, the dojo.locale is returned.  dojo.locale is defined by
-	//		the user agent's locale unless overridden by djConfig.
-
-	var result = locale ? locale.toLowerCase() : dojo.locale;
-	if(result == "root"){
-		result = "ROOT";
-	}
-	return result; // String
-};
-
-dojo.i18n._requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String?*/availableFlatLocales){
-	//	summary:
-	//		See dojo.requireLocalization()
-	//	description:
-	// 		Called by the bootstrap, but factored out so that it is only
-	// 		included in the build when needed.
-
-	var targetLocale = dojo.i18n.normalizeLocale(locale);
- 	var bundlePackage = [moduleName, "nls", bundleName].join(".");
-	// NOTE:
-	//		When loading these resources, the packaging does not match what is
-	//		on disk.  This is an implementation detail, as this is just a
-	//		private data structure to hold the loaded resources.  e.g.
-	//		`tests/hello/nls/en-us/salutations.js` is loaded as the object
-	//		`tests.hello.nls.salutations.en_us={...}` The structure on disk is
-	//		intended to be most convenient for developers and translators, but
-	//		in memory it is more logical and efficient to store in a different
-	//		order.  Locales cannot use dashes, since the resulting path will
-	//		not evaluate as valid JS, so we translate them to underscores.
-
-	//Find the best-match locale to load if we have available flat locales.
-	var bestLocale = "";
-	if(availableFlatLocales){
-		var flatLocales = availableFlatLocales.split(",");
-		for(var i = 0; i < flatLocales.length; i++){
-			//Locale must match from start of string.
-			//Using ["indexOf"] so customBase builds do not see
-			//this as a dojo._base.array dependency.
-			if(targetLocale["indexOf"](flatLocales[i]) == 0){
-				if(flatLocales[i].length > bestLocale.length){
-					bestLocale = flatLocales[i];
+		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.
+			//
+			// 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];
+				if(!root || root[current]){
+					result.push(bundlePath + current + "/" + bundleName);
 				}
 			}
-		}
-		if(!bestLocale){
-			bestLocale = "ROOT";
-		}
-	}
+			return result;
+		},
+
+		cache= {},
+
+		getL10nName= dojo.getL10nName = function(moduleName, bundleName, locale){
+			locale = locale ? locale.toLowerCase() : dojo.locale;
+			moduleName = "dojo/i18n!" + moduleName.replace(/\./g, "/");
+			bundleName = bundleName.replace(/\./g, "/");
+			return (/root/i.test(locale)) ?
+				(moduleName + "/nls/" + bundleName) :
+				(moduleName + "/nls/" + locale + "/" + bundleName);
+		},
+
+		doLoad = function(require, bundlePathAndName, bundlePath, bundleName, locale, load){
+			// 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);
+				require(availableLocales, function(){
+					for (var i= 1; i<availableLocales.length; i++){
+						cache[availableLocales[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));
+				});
+			});
+		},
 
-	//See if the desired locale is already loaded.
-	var tempLocale = availableFlatLocales ? bestLocale : targetLocale;
-	var bundle = dojo._loadedModules[bundlePackage];
-	var localizedBundle = null;
-	if(bundle){
-		if(dojo.config.localizationComplete && bundle._built){return;}
-		var jsLoc = tempLocale.replace(/-/g, '_');
-		var translationPackage = bundlePackage+"."+jsLoc;
-		localizedBundle = dojo._loadedModules[translationPackage];
+		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;
+		},
+
+		checkForLegacyModules = function(){},
+
+		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;
+					}
+					if(!--remaining){
+						load(targetBundle);
+					}
+				});
+			});
+		};
+
+	if(has("dojo-unit-tests")){
+		var unitTests = thisModule.unitTests = [];
 	}
 
-	if(!localizedBundle){
-		bundle = dojo["provide"](bundlePackage);
-		var syms = dojo._getModuleSymbols(moduleName);
-		var modpath = syms.concat("nls").join("/");
-		var parent;
-
-		dojo.i18n._searchLocalePath(tempLocale, availableFlatLocales, function(loc){
-			var jsLoc = loc.replace(/-/g, '_');
-			var translationPackage = bundlePackage + "." + jsLoc;
-			var loaded = false;
-			if(!dojo._loadedModules[translationPackage]){
-				// Mark loaded whether it's found or not, so that further load attempts will not be made
-				dojo["provide"](translationPackage);
-				var module = [modpath];
-				if(loc != "ROOT"){module.push(loc);}
-				module.push(bundleName);
-				var filespec = module.join("/") + '.js';
-				loaded = dojo._loadPath(filespec, null, function(hash){
-					hash = hash.root || hash;
-					// Use singleton with prototype to point to parent bundle, then mix-in result from loadPath
-					var clazz = function(){};
-					clazz.prototype = parent;
-					bundle[jsLoc] = new clazz();
-					for(var j in hash){ bundle[jsLoc][j] = hash[j]; }
+	has.add("dojo-v1x-i18n-Api",
+		// if true, define the v1.x i18n functions
+		1
+	);
+
+	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];"
+				),
+
+			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 {};
+				}
+				return preAmdResult ? (/nls\/[^\/]+\/[^\/]+$/.test(url) ? preAmdResult : {root:preAmdResult, _v1x:1}) : amdResult;
+			},
+
+			syncRequire= function(deps, callback){
+				var results= [];
+				array.forEach(deps, function(mid){
+					var url= require.toUrl(mid + ".js");
+					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]= {});
+							}
+						});
+					}
 				});
-			}else{
-				loaded = true;
-			}
-			if(loaded && bundle[jsLoc]){
-				parent = bundle[jsLoc];
-			}else{
-				bundle[jsLoc] = parent;
-			}
+				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");
+			};
 
-			if(availableFlatLocales){
-				//Stop the locale path searching if we know the availableFlatLocales, since
-				//the first call to this function will load the only bundle that is needed.
-				return true;
+		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++]]){}
+			if(object){
+				cache[target] = object;
 			}
-		});
-	}
+		};
 
-	//Save the best locale bundle as the target locale bundle when we know the
-	//the available bundles.
-	if(availableFlatLocales && targetLocale != bestLocale){
-		bundle[targetLocale.replace(/-/g, '_')] = bundle[bestLocale.replace(/-/g, '_')];
-	}
-};
-
-(function(){
-	// If other locales are used, dojo.requireLocalization should load them as
-	// well, by default.
-	//
-	// Override dojo.requireLocalization to do load the default bundle, then
-	// iterate through the extraLocale list and load those translations as
-	// well, unless a particular locale was requested.
-
-	var extra = dojo.config.extraLocale;
-	if(extra){
-		if(!extra instanceof Array){
-			extra = [extra];
-		}
+		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;
+		};
+
+		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
 
-		var req = dojo.i18n._requireLocalization;
-		dojo.i18n._requireLocalization = function(m, b, locale, availableFlatLocales){
-			req(m,b,locale, availableFlatLocales);
-			if(locale){return;}
+			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++){
-				req(m,b,extra[i], availableFlatLocales);
+				preload(extra[i]);
 			}
 		};
-	}
-})();
 
-dojo.i18n._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".
+		if(has("dojo-unit-tests")){
+			unitTests.push(function(doh){
+				doh.register("tests.i18n.unit", function(t){
+					var check;
 
-	locale = dojo.i18n.normalizeLocale(locale);
+					check = evalBundle("{prop:1}", __evalError);
+					t.is({prop:1}, check[0]); t.is(undefined, check[1]);
 
-	var elements = locale.split('-');
-	var searchlist = [];
-	for(var i = elements.length; i > 0; i--){
-		searchlist.push(elements.slice(0, i).join('-'));
-	}
-	searchlist.push(false);
-	if(down){searchlist.reverse();}
+					check = evalBundle("({prop:1})", __evalError);
+					t.is({prop:1}, check[0]); t.is(undefined, check[1]);
 
-	for(var j = searchlist.length - 1; j >= 0; j--){
-		var loc = searchlist[j] || "ROOT";
-		var stop = searchFunc(loc);
-		if(stop){ break; }
-	}
-};
-
-dojo.i18n._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.
-
-	function preload(locale){
-		locale = dojo.i18n.normalizeLocale(locale);
-		dojo.i18n._searchLocalePath(locale, true, function(loc){
-			for(var i=0; i<localesGenerated.length;i++){
-				if(localesGenerated[i] == loc){
-					dojo["require"](bundlePrefix+"_"+loc);
-					return true; // Boolean
-				}
-			}
-			return false; // Boolean
-		});
-	}
-	preload();
-	var extra = dojo.config.extraLocale||[];
-	for(var i=0; i<extra.length; i++){
-		preload(extra[i]);
+					check = evalBundle("{'prop-x':1}", __evalError);
+					t.is({'prop-x':1}, check[0]); 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("define({'prop-x':1})", __evalError);
+					t.is(0, check[0]); t.is({'prop-x':1}, check[1]);
+
+					check = evalBundle("define({'prop-x':1});", __evalError);
+					t.is(0, check[0]); t.is({'prop-x':1}, check[1]);
+
+					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]));
+				});
+			});
+		}
 	}
-};
 
-return dojo.i18n;
-});
\ No newline at end of file
+	return lang.mixin(thisModule, {
+		dynamic:true,
+		normalize:normalize,
+		load:load,
+		cache:function(mid, value){
+			cache[mid] = value;
+		}
+	});
+});
diff --git a/dojo/io-query.js b/dojo/io-query.js
new file mode 100644
index 0000000..2fa6be5
--- /dev/null
+++ b/dojo/io-query.js
@@ -0,0 +1,98 @@
+define(["./_base/lang"], function(lang){
+	// module:
+	//		dojo/io-query
+	// summary:
+	//		This module defines query string processing functions.
+
+    var backstop = {};
+
+    function objectToQuery(/*Object*/ map){
+        // summary:
+        //		takes a name/value mapping object and returns a string representing
+        //		a URL-encoded version of that object.
+        // example:
+        //		this object:
+        //
+        //	|	{
+        //	|		blah: "blah",
+        //	|		multi: [
+        //	|			"thud",
+        //	|			"thonk"
+        //	|		]
+        //	|	};
+        //
+        // yields the following query string:
+        //
+        //	|	"blah=blah&multi=thud&multi=thonk"
+
+        // FIXME: need to implement encodeAscii!!
+        var enc = encodeURIComponent, pairs = [];
+        for(var name in map){
+            var value = map[name];
+            if(value != backstop[name]){
+                var assign = enc(name) + "=";
+                if(lang.isArray(value)){
+                    for(var i = 0, l = value.length; i < l; ++i){
+                        pairs.push(assign + enc(value[i]));
+                    }
+                }else{
+                    pairs.push(assign + enc(value));
+                }
+            }
+        }
+        return pairs.join("&"); // String
+    }
+
+    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.
+        //
+        // example:
+        //		This string:
+        //
+        //	|		"foo=bar&foo=baz&thinger=%20spaces%20=blah&zonk=blarg&"
+        //
+        //		results in this object structure:
+        //
+        //	|		{
+        //	|			foo: [ "bar", "baz" ],
+        //	|			thinger: " spaces =blah",
+        //	|			zonk: "blarg"
+        //	|		}
+        //
+        //		Note that spaces and other urlencoded entities are correctly
+        //		handled.
+
+        // FIXME: should we grab the URL string if we're not passed one?
+        var dec = decodeURIComponent, qp = str.split("&"), ret = {}, name, val;
+        for(var i = 0, l = qp.length, item; i < l; ++i){
+            item = qp[i];
+            if(item.length){
+                var s = item.indexOf("=");
+                if(s < 0){
+                    name = dec(item);
+                    val = "";
+                }else{
+                    name = dec(item.slice(0, s));
+                    val  = dec(item.slice(s + 1));
+                }
+                if(typeof ret[name] == "string"){ // inline'd type check
+                    ret[name] = [ret[name]];
+                }
+
+                if(lang.isArray(ret[name])){
+                    ret[name].push(val);
+                }else{
+                    ret[name] = val;
+                }
+            }
+        }
+        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 050e6ad..ac5fdde 100644
--- a/dojo/io/iframe.js
+++ b/dojo/io/iframe.js
@@ -1,4 +1,9 @@
-define("dojo/io/iframe", ["dojo"], function(dojo) {
+define(["../main", "require"], function(dojo, require) {
+	// module:
+	//		dojo/io/iframe
+	// summary:
+	//		TODOC
+
 dojo.getObject("io", true, dojo);
 
 /*=====
@@ -43,7 +48,7 @@ dojo.declare("dojo.io.iframe.__ioArgs", dojo.__IoArgs, {
 dojo.io.iframe = {
 	// summary:
 	//		Sends an Ajax I/O call using and Iframe (for instance, to upload files)
-	
+
 	create: function(/*String*/fname, /*String*/onloadstr, /*String?*/uri){
 		//	summary:
 		//		Creates a hidden iframe in the page. Used mostly for IO
@@ -61,7 +66,6 @@ dojo.io.iframe = {
 		//		used.
 		if(window[fname]){ return window[fname]; }
 		if(window.frames[fname]){ return window.frames[fname]; }
-		var cframe = null;
 		var turi = uri;
 		if(!turi){
 			if(dojo.config["useXDomain"] && !dojo.config["dojoBlankHtmlUrl"]){
@@ -69,7 +73,7 @@ dojo.io.iframe = {
 					+ " 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"]||dojo.moduleUrl("dojo", "resources/blank.html"));
+			turi = (dojo.config["dojoBlankHtmlUrl"]||require.toUrl("../resources/blank.html"));
 		}
 		var cframe = dojo.place(
 			'<iframe id="'+fname+'" name="'+fname+'" src="'+turi+'" onload="'+onloadstr+
@@ -101,14 +105,13 @@ dojo.io.iframe = {
 				}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;
-					return;
 				}else{
 					idoc.location.replace(src);
 				}
@@ -120,7 +123,7 @@ dojo.io.iframe = {
 
 	doc: function(/*DOMNode*/iframeNode){
 		//summary: Returns the document object associated with the iframe DOM Node argument.
-		var doc = iframeNode.contentDocument || // W3
+		return iframeNode.contentDocument || // W3
 			(
 				(
 					(iframeNode.name) && (iframeNode.document) &&
@@ -132,7 +135,6 @@ dojo.io.iframe = {
 				(iframeNode.name)&&(dojo.doc.frames[iframeNode.name])&&
 				(dojo.doc.frames[iframeNode.name].document)
 			) || null;
-		return doc;
 	},
 
 	send: function(/*dojo.io.iframe.__ioArgs*/args){
@@ -213,7 +215,7 @@ dojo.io.iframe = {
 
 		this._dfdQueue.push(dfd);
 		this._fireNextRequest();
-		
+
 		//Add it the IO watch queue, to get things like timeout support.
 		dojo._ioWatch(
 			dfd,
@@ -338,7 +340,7 @@ dojo.io.iframe = {
 		var ioArgs = dfd.ioArgs;
 		var args = ioArgs.args;
 		var fNode = dojo.byId(args.form);
-	
+
 		if(fNode){
 			// remove all the hidden content inputs
 			var toClean = ioArgs._contentToClean;
diff --git a/dojo/io/script.js b/dojo/io/script.js
index fc2675d..58e1edc 100644
--- a/dojo/io/script.js
+++ b/dojo/io/script.js
@@ -1,5 +1,10 @@
-define("dojo/io/script", ["dojo"], function(dojo) {
-dojo.getObject("io", true, dojo);
+define(["../main"], function(dojo) {
+	// module:
+	//		dojo/io/script
+	// summary:
+	//		TODOC
+
+	dojo.getObject("io", true, dojo);
 
 /*=====
 dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
@@ -13,7 +18,7 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 		//		the body of the script that was attached.
 		//	callbackParamName: String
 		//		Deprecated as of Dojo 1.4 in favor of "jsonp", but still supported for
-		// 		legacy code. See notes for jsonp property.
+		//		legacy code. See notes for jsonp property.
 		//	jsonp: String
 		//		The URL parameter name that indicates the JSONP callback string.
 		//		For instance, when using Yahoo JSONP calls it is normally,
@@ -35,7 +40,7 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 	}
 });
 =====*/
-(function(){
+
 	var loadEvent = dojo.isIE ? "onreadystatechange" : "load",
 		readyRegExp = /complete|loaded/;
 
@@ -46,7 +51,7 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 			var dfd = this._makeScriptDeferred(args);
 			var ioArgs = dfd.ioArgs;
 			dojo._ioAddQueryToUrl(ioArgs);
-	
+
 			dojo._ioNotifyStart(dfd);
 
 			if(this._canAttach(ioArgs)){
@@ -67,13 +72,13 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 			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
+			//		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);
@@ -81,30 +86,31 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 			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));
-			
+
 			//Remove the jsonp callback on dojo.io.script, if it exists.
 			if(this["jsonp_" + id]){
 				delete this["jsonp_" + id];
 			}
 		},
-	
+
 		_makeScriptDeferred: function(/*Object*/args){
 			//summary:
 			//		sets up a Deferred object for an IO request.
 			var dfd = dojo._ioSetArgs(args, this._deferredCancel, this._deferredOk, this._deferredError);
-	
+
 			var ioArgs = dfd.ioArgs;
 			ioArgs.id = dojo._scopeName + "IoScript" + (this._counter++);
 			ioArgs.canDelete = false;
-	
+
 			//Special setup for jsonp case
 			ioArgs.jsonp = args.callbackParamName || args.jsonp;
 			if(ioArgs.jsonp){
@@ -117,9 +123,9 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 					+ "="
 					+ (args.frameDoc ? "parent." : "")
 					+ dojo._scopeName + ".io.script.jsonp_" + ioArgs.id + "._jsonpCallback";
-	
+
 				ioArgs.frameDoc = args.frameDoc;
-	
+
 				//Setup the Deferred to have the jsonp callback.
 				ioArgs.canDelete = true;
 				dfd._jsonpCallback = this._jsonpCallback;
@@ -127,38 +133,38 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 			}
 			return dfd; // dojo.Deferred
 		},
-		
+
 		_deferredCancel: function(/*Deferred*/dfd){
 			//summary: canceller function for dojo._ioSetArgs call.
-	
+
 			//DO NOT use "this" and expect it to be dojo.io.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.
-	
+
 			//DO NOT use "this" and expect it to be dojo.io.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
 			//in that case, probably a checkString case.
 			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"){
@@ -172,20 +178,20 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 			console.log("dojo.io.script error", error);
 			return error;
 		},
-	
+
 		_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});
 			//Being extra paranoid about leaks:
 			ioArgs.frameDoc = null;
 		},
-	
+
 		_validCheck: function(/*Deferred*/dfd){
 			//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
 			//tag that is part of the call chain (IE 6 has been known to
@@ -200,10 +206,10 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 				}
 				dojo.io.script._deadScripts = [];
 			}
-	
+
 			return true;
 		},
-	
+
 		_ioCheck: function(/*Deferred*/dfd){
 			//summary: inflight check function to see if IO finished.
 			var ioArgs = dfd.ioArgs;
@@ -211,16 +217,14 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 			if(ioArgs.json || (ioArgs.scriptLoaded && !ioArgs.args.checkString)){
 				return true;
 			}
-	
+
 			//Check for finished "checkString" case.
 			var checkString = ioArgs.args.checkString;
-			if(checkString && eval("typeof(" + checkString + ") != 'undefined'")){
-				return true;
-			}
-	
-			return false;
+			return checkString && eval("typeof(" + checkString + ") != 'undefined'");
+
+
 		},
-	
+
 		_resHandle: function(/*Deferred*/dfd){
 			//summary: inflight function to handle a completed response.
 			if(dojo.io.script._ioCheck(dfd)){
@@ -231,13 +235,13 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 				dfd.errback(new Error("inconceivable dojo.io.script._resHandle error"));
 			}
 		},
-	
+
 		_canAttach: function(/*Object*/ioArgs){
 			//summary: A method that can be overridden by other modules
 			//to control when the script attachment occurs.
 			return true;
 		},
-		
+
 		_jsonpCallback: function(/*JSON Object*/json){
 			//summary:
 			//		generic handler for jsonp callback. A pointer to this function
@@ -247,7 +251,6 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 			this.ioArgs.json = json;
 		}
 	};
-})();
 
-return dojo.io.script;
+	return dojo.io.script;
 });
diff --git a/dojo/jaxer.js b/dojo/jaxer.js
index 42de56a..638956e 100644
--- a/dojo/jaxer.js
+++ b/dojo/jaxer.js
@@ -1,4 +1,9 @@
-define("dojo/jaxer", ["dojo"], function(dojo) {
+define(["./main"], function(dojo) {
+	// module:
+	//		dojo/jaxer
+	// summary:
+	//		TODOC
+
 
 if(typeof print == "function"){
 	console.debug = Jaxer.Log.debug;
diff --git a/dojo/json.js b/dojo/json.js
new file mode 100644
index 0000000..b975b29
--- /dev/null
+++ b/dojo/json.js
@@ -0,0 +1,149 @@
+define(["./has"], function(has){
+	"use strict";
+	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}'); 
+	if(has("json-stringify")){
+		return JSON;
+	}
+	else{
+		var escapeString = function(/*String*/str){
+			//summary:
+			//		Adds escape sequences for non-visual characters, double quote and
+			//		backslash and surrounds with double quotes to form a valid string
+			//		literal.
+			return ('"' + str.replace(/(["\\])/g, '\\$1') + '"').
+				replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n").
+				replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string
+		};
+		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)){
+					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;
+					replacer = null;
+				}
+				function stringify(it, indent, key){
+					if(replacer){
+						it = replacer(key, it);
+					}
+					var val, objtype = typeof it;
+					if(objtype == "number"){
+						return isFinite(it) ? it + "" : "null";
+					}
+					if(objtype == "boolean"){
+						return it + "";
+					}
+					if(it === null){
+						return "null";
+					}
+					if(typeof it == "string"){
+						return escapeString(it);
+					}
+					if(objtype == "function" || objtype == "undefined"){
+						return undef; // undefined
+					}
+					// short-circuit for objects that support "json" serialization
+					// if they return "self" then just pass-through...
+					if(typeof it.toJSON == "function"){
+						return stringify(it.toJSON(key), indent, key);
+					}
+					if(it instanceof Date){
+						return '"{FullYear}-{Month+}-{Date}T{Hours}:{Minutes}:{Seconds}Z"'.replace(/\{(\w+)(\+)?\}/g, function(t, prop, plus){
+							var num = it["getUTC" + prop]() + (plus ? 1 : 0);
+							return num < 10 ? "0" + num : num;
+						});
+					}
+					if(it.valueOf() !== it){
+						// primitive wrapper, try again unwrapped:
+						return stringify(it.valueOf(), indent, key);
+					}
+					var nextIndent= spacer ? (indent + spacer) : "";
+					/* we used to test for DOM nodes and throw, but FF serializes them as {}, so cross-browser consistency is probably not efficiently attainable */ 
+				
+					var sep = spacer ? " " : "";
+					var newLine = spacer ? "\n" : "";
+				
+					// array
+					if(it instanceof Array){
+						var itl = it.length, res = [];
+						for(key = 0; key < itl; key++){
+							var obj = it[key];
+							val = stringify(obj, nextIndent, key);
+							if(typeof val != "string"){
+								val = "null";
+							}
+							res.push(newLine + nextIndent + val);
+						}
+						return "[" + res.join(",") + newLine + indent + "]";
+					}
+					// generic object code path
+					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;
+						}
+						// 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
+				}
+				return stringify(value, "", "");
+			}
+		};
+	}
+});
diff --git a/dojo/keys.js b/dojo/keys.js
new file mode 100644
index 0000000..3347e74
--- /dev/null
+++ b/dojo/keys.js
@@ -0,0 +1,80 @@
+define(["./_base/kernel", "./_base/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
+};
+});
diff --git a/dojo/lib/backCompat.js b/dojo/lib/backCompat.js
deleted file mode 100644
index 0779018..0000000
--- a/dojo/lib/backCompat.js
+++ /dev/null
@@ -1,276 +0,0 @@
-// AMD module id = dojo/lib/backCompat
-//
-// This module defines those dojo properties/methods that are defined by
-// dojo/_base/_loader/loader and are still needed when loading with and
-// AMD loader (when loading with an AMD loader, dojo/_base/_loader/loader
-// is never loaded).
-//
-// note: this module is relevant only when loading dojo with an AMD loader;
-// it is never evaluated otherwise.
-
-define(["require", "dojo/_base/_loader/bootstrap"], function(require, dojo){
-	// the following dojo properties do not exist in the AMD-loaded version of dojo 1.x:
-	var names= [
-		"_moduleHasPrefix",
-		"_loadPath",
-		"_loadUri",
-		"_loadUriAndCheck",
-		"loaded",
-		"_callLoaded",
-		"_getModuleSymbols",
-		"_loadModule",
-		"require",
-		"provide",
-		"platformRequire",
-		"requireIf",
-		"requireAfterIf",
-		"registerModulePath"
-	], i, name;
-	for(i = 0; i<names.length;){
-		name = names[i++];
-		dojo[name] = (function(name) {
-			return function(){
-				console.warn("dojo." + name + " not available when using an AMD loader.");
-			};
-		})(name);
-	}
-
-	// define dojo.addOnLoad in terms of the DOMContentLoaded detection available from the AMD loaders
-	// (requirejs and bdBuild). Note that the behavior of this feature is slightly different compared to the dojo
-	// v1.x sync loader. There, the onload queue is fired upon detecting both DOMContentLoaded *and* all
-	// demanded modules have arrived. It is impossible to simulate this behavior with requirejs since it does
-	// not publish its internal status (it is possible with bdLoad).
-	// TODO: consider taking ownership of this API back from the loader.
-	// TODO: consider requesting requirejs publish more enough internal state to determine if all demanded
-	// modules have been defined.
-	var
-		argsToArray = function(args) {
-			var result = [], i;
-			for(i = 0; i<args.length;){
-				result.push(args[i++]);
-			}
-			return result;
-		},
-
-		simpleHitch = function(context, callback){
-			if(callback){
-				return (typeof callback=="string") ?
-					function(){context[callback]();} :
-					function(){callback.call(context);};
-			}else{
-				return context;
-			}
-		};
-	dojo.ready = dojo.addOnLoad = function(context, callback){
-		require.ready(callback ? simpleHitch(context, callback) : context);
-	};
-	dojo.addOnLoad(function() {
-		dojo.postLoad = dojo.config.afterOnLoad = true;
-	});
-	var dca = dojo.config.addOnLoad;
-	if(dca){
-		dojo.addOnLoad[(dca instanceof Array ? "apply" : "call")](dojo, dca);
-	}
-
-	// TODO: in the dojo 1.x sync loader the array dojo._loaders holds the queue of callbacks to be executed
-	// upon DOMContentLoaded. This queue is manipulated directly by dojo/uacss, dojo/parser, dijit/_base/wia
-	// and others (at least in dojox). This is also impossible to simulate universally across all AMD loaders.
-	// The following will at least accept client code accessing dojo._loaders , dojo._loaders.unshift, and
-	// dojo._loaders.splice--which is all that exists in the current dojo/dijit code stacks.
-	var
-		loaders = dojo._loaders = [],
-		runLoaders = function(){
-			var temp= loaders.slice(0);
-			Array.prototype.splice.apply(loaders, [0, loaders.length]);
-			while(temp.length){
-				temp.shift().call();
-			};
-		};
-	loaders.unshift = function() {
-		Array.prototype.unshift.apply(loaders, argsToArray(arguments));
-		require.ready(runLoaders);
-	};
-	loaders.splice = function() {
-		Array.prototype.splice.apply(loaders, argsToArray(arguments));
-		require.ready(runLoaders);
-	};
-
-	//TODO: put unload handling in a separate module
-	var unloaders = dojo._unloaders = [];
-	dojo.unloaded = function(){
-		while(unloaders.length){
-			unloaders.pop().call();
-		}
-	};
-
-	//TODO: kill this low-value function when it is exorcised from dojo
-	dojo._onto = function(arr, obj, fn){
-		arr.push(fn ? simpleHitch(obj, fn) : obj);
-	};
-
-	//TODO: kill this when the bootstrap is rewritten to not include DOMContentLoaded detection
-	// (it should probably be just a module) for now, just sink the detection; leverage the
-	// AMD loaders to handle DOMContentLoaded detection
-	dojo._modulesLoaded = function(){};
-
-	//TODO: kill this when we understand its purpose relative to AMD
-	dojo.loadInit = function(init){
-		init();
-	};
-
-	var amdModuleName= function(moduleName){
-		return moduleName.replace(/\./g, "/");
-	};
-
-	dojo.getL10nName = function(moduleName, bundleName, locale){
-		locale = locale ? locale.toLowerCase() : dojo.locale;
-		moduleName = "i18n!" + amdModuleName(moduleName);
-		return (/root/i.test(locale)) ?
-			(moduleName + "/nls/" + bundleName) :
-			(moduleName + "/nls/"	 + locale + "/" + bundleName);
-	};
-
-	dojo.requireLocalization = function(moduleName, bundleName, locale){
-		// NOTE: locales other than the locale specified in dojo.locale need to be specifically
-		// declared as a module dependency when using AMD.
-		if(require.vendor!="altoviso.com"){
-			locale = !locale || locale.toLowerCase() === dojo.locale ? "root" :  locale;
-		}
-		return require(dojo.getL10nName(moduleName, bundleName, locale));
-	};
-
-	dojo.i18n= {
-		getLocalization: dojo.requireLocalization,
-		normalizeLocale: function(locale){
-			var result = locale ? locale.toLowerCase() : dojo.locale;
-			if(result == "root"){
-				result = "ROOT";
-			}
-			return result;
-		}
-	};
-
-	//TODO: dojo._Url seems rarely used and long to be part of the boostrap; consider moving
-	//note: this routine cut and paste from dojo/_base/_loader/loader
-	var
-		ore = new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"),
-		ire = new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$");
-	dojo._Url = function(){
-		var n = null,
-			_a = arguments,
-			uri = [_a[0]];
-		// resolve uri components relative to each other
-		for(var i = 1; i<_a.length; i++){
-			if(!_a[i]){ continue; }
-
-			// Safari doesn't support this.constructor so we have to be explicit
-			// FIXME: Tracked (and fixed) in Webkit bug 3537.
-			//		http://bugs.webkit.org/show_bug.cgi?id=3537
-			var relobj = new dojo._Url(_a[i]+""),
-				uriobj = new dojo._Url(uri[0]+"");
-
-			if(
-				relobj.path == "" &&
-				!relobj.scheme &&
-				!relobj.authority &&
-				!relobj.query
-			){
-				if(relobj.fragment != n){
-					uriobj.fragment = relobj.fragment;
-				}
-				relobj = uriobj;
-			}else if(!relobj.scheme){
-				relobj.scheme = uriobj.scheme;
-
-				if(!relobj.authority){
-					relobj.authority = uriobj.authority;
-
-					if(relobj.path.charAt(0) != "/"){
-						var path = uriobj.path.substring(0,
-							uriobj.path.lastIndexOf("/") + 1) + relobj.path;
-
-						var segs = path.split("/");
-						for(var j = 0; j < segs.length; j++){
-							if(segs[j] == "."){
-								// flatten "./" references
-								if(j == segs.length - 1){
-									segs[j] = "";
-								}else{
-									segs.splice(j, 1);
-									j--;
-								}
-							}else if(j > 0 && !(j == 1 && segs[0] == "") &&
-								segs[j] == ".." && segs[j-1] != ".."){
-								// flatten "../" references
-								if(j == (segs.length - 1)){
-									segs.splice(j, 1);
-									segs[j - 1] = "";
-								}else{
-									segs.splice(j - 1, 2);
-									j -= 2;
-								}
-							}
-						}
-						relobj.path = segs.join("/");
-					}
-				}
-			}
-
-			uri = [];
-			if(relobj.scheme){
-				uri.push(relobj.scheme, ":");
-			}
-			if(relobj.authority){
-				uri.push("//", relobj.authority);
-			}
-			uri.push(relobj.path);
-			if(relobj.query){
-				uri.push("?", relobj.query);
-			}
-			if(relobj.fragment){
-				uri.push("#", relobj.fragment);
-			}
-		}
-
-		this.uri = uri.join("");
-
-		// break the uri into its main components
-		var r = this.uri.match(ore);
-
-		this.scheme = r[2] || (r[1] ? "" : n);
-		this.authority = r[4] || (r[3] ? "" : n);
-		this.path = r[5]; // can never be undefined
-		this.query = r[7] || (r[6] ? "" : n);
-		this.fragment	 = r[9] || (r[8] ? "" : n);
-
-		if(this.authority != n){
-			// server based naming authority
-			r = this.authority.match(ire);
-
-			this.user = r[3] || n;
-			this.password = r[4] || n;
-			this.host = r[6] || r[7]; // ipv6 || ipv4
-			this.port = r[9] || n;
-		}
-	};
-
-	dojo._Url.prototype.toString = function(){ return this.uri; };
-
-	dojo.moduleUrl = function(module, url){
-		if(!module){
-		 //TODO: don't understand why this would ever be so, but that's the logic in loader
-		 return null;
-		}
-		module = amdModuleName(module) + (url ? ("/" + url) : "");
-		var
-			type= "",
-			match= module.match(/(.+)(\.[^\/]*)$/);
-		if (match) {
-			module= match[1];
-			type= match[2];
-		}
-		return new dojo._Url(require.nameToUrl(module, type)); // dojo._Url
-	};
-
-	return dojo;
-});
diff --git a/dojo/lib/kernel.js b/dojo/lib/kernel.js
deleted file mode 100644
index e31eb2d..0000000
--- a/dojo/lib/kernel.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// AMD module id = dojo/lib/kernel
-//
-// This module ensures the dojo object is initialized by...
-//
-//	 * dojo/_base/_loader/bootstrap
-//	 * dojo/lib/backCompat
-//	 * dojo/_base/_loader/hostenv_browser
-//
-// This is roughly equivalent to the work that dojo.js does by injecting
-// bootstrap, loader, and hostenv_browser.
-//
-// note: this module is relevant only when loading dojo with an AMD loader;
-// it is never evaluated otherwise.
-
-// for now, we publish dojo into the global namespace because so many tests and apps expect it.
-define(["dojo/_base/_loader/hostenv_browser"], function(dojo_){
-	dojo= dojo_;
-	return dojo_;
-});
diff --git a/dojo/lib/main-browser.js b/dojo/lib/main-browser.js
deleted file mode 100644
index 4ee63cf..0000000
--- a/dojo/lib/main-browser.js
+++ /dev/null
@@ -1,54 +0,0 @@
-// AMD module id = dojo
-//
-// This is a package main module for the dojo package implemented so that the *absolute minimal*
-// changes are made to the dojo 1.x code. It is by no means optimal and should/will be replaced with
-// a less naive design--particularly as dojo v2.0 evolves.
-//
-// There are a few key design weaknesses in this implementation:
-//
-//	 * generally, v1.x bootstrap, tests, and apps assume dojo is global
-//
-//	 * the v1.x dojo/_base modules assume dojo is defined before they are defined
-//     and their factory functions go about populating dojo--which is really part of defining
-//     dojo. This leads to the appearance of a circular dependency and is a somewhat obtuse
-//     design since the dojo object must be delivered to them under a different module
-//     name (dojo/lib/kernel).
-//
-//   * bootstrap modules tend to incorporate unrelated features (e.g., hostenv_browser includes
-//     DOMContentLoad detection, thereby making it impossible to build out this feature if a
-//     particular app does not need it).
-//
-//   * The back compatibility layer requires/contains some non-optimal code that needs to be improved.
-//
-// As 1.7 and 2.0 evolve, these items will be addressed with more robust implementation.
-//
-// The boot sequence is as follows:
-//
-// dojo (this module) depends on...
-// dojo/lib/kernel which depends on...
-// dojo/_base/_loader/hostenv_browser which depends on...
-// dojo/lib/backCompat which depends on...
-// dojo/_base/_loader/bootstrap which depends on nothing
-//
-// This module further depends on the fairly ordinary modules in dojo/_base; each of these
-// modules depends on dojo/lib/kernel (at least) which provide the dojo object for them to augment.
-
-define("dojo", [
-	"dojo/lib/kernel",
-	"dojo/_base/lang",
-	"dojo/_base/array",
-	"dojo/_base/declare",
-	"dojo/_base/connect",
-	"dojo/_base/Deferred",
-	"dojo/_base/json",
-	"dojo/_base/Color",
-	"dojo/_base/window",
-	"dojo/_base/event",
-	"dojo/_base/html",
-	"dojo/_base/NodeList",
-	"dojo/_base/query",
-	"dojo/_base/xhr",
-	"dojo/_base/fx"
-], function(dojo){
-	return dojo;
-});
diff --git a/dojo/lib/plugins/i18n.js b/dojo/lib/plugins/i18n.js
deleted file mode 100644
index 77c996d..0000000
--- a/dojo/lib/plugins/i18n.js
+++ /dev/null
@@ -1,87 +0,0 @@
-//
-// dojo i18n! plugin
-//
-// We choose to include our own plugin in hopes of leveraging functionality already contained in dojo
-// and thereby reducing the size of the plugin compared to various loader implementations. Naturally, this
-// allows AMD loaders to be used without their plugins.
-
-// CAUTION, this module may return improper results if the AMD loader does not support toAbsMid and client
-// code passes relative plugin resource module ids. In that case, you should consider using the i18n! plugin
-// that comes with your loader.
-
-define(["dojo"], function(dojo) {
-	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
-		){
-			// 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.
-
-			for(var result= [bundlePath + bundleName], localeParts= locale.split("-"), current= "", i= 0; i<localeParts.length; i++){
-				current+= localeParts[i];
-				if(root[current]){
-					result.push(bundlePath + current + "/" + bundleName);
-				}
-			}
-			return result;
-		},
-
-		cache= {};
-
-	return {
-		load: function(id, require, load){
-			// note: id may be relative
-			var
-				match= nlsRe.exec(id),
-				bundlePath= (require.toAbsMid && require.toAbsMid(match[1])) || match[1],
-				bundleName= match[5] || match[4],
-				bundlePathAndName= bundlePath + bundleName,
-				locale= (match[5] && match[4]) || dojo.locale,
-				target= bundlePathAndName + "/" + locale;
-
-			// if we've already resolved this request, just return it
-			if (cache[target]) {
-				load(cache[target]);
-				return;
-			}
-
-			// get the root bundle which instructs which other bundles are required to contruct the localized bundle
-			require([bundlePathAndName], function(root){
-				var
-					current= cache[bundlePathAndName + "/"]= dojo.clone(root.root),
-					availableLocales= getAvailableLocales(root, locale, bundlePath, bundleName);
-				require(availableLocales, function(){
-					for (var i= 1; i<availableLocales.length; i++){
-						cache[bundlePathAndName + "/" + availableLocales[i]]= current= dojo.mixin(dojo.clone(current), arguments[i]);
-					}
-					// target may not have been resolve (e.g., maybe only "fr" exists when "fr-ca" was requested)
-					cache[target]= current;
-					load(current);
-				});
-			});
-		},
-
-		cache: function(mid, value){
-			cache[mid]= value;
-		}
-	};
-});
diff --git a/dojo/lib/plugins/text.js b/dojo/lib/plugins/text.js
deleted file mode 100644
index 2bded2d..0000000
--- a/dojo/lib/plugins/text.js
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// dojo text! plugin
-//
-// We choose to include our own plugin in hopes of leveraging functionality already contained in dojo
-// and thereby reducing the size of the plugin compared to various loader implementations. Naturally, this
-// allows AMD loaders to be used without their plugins.
-
-// CAUTION, this module may return improper results if the AMD loader does not support toAbsMid and client
-// code passes relative plugin resource module ids. In that case, you should consider using the text! plugin
-// that comes with your loader.
-
-define(["dojo", "dojo/cache"], function(dojo){
-	var
-		cached= {},
-
-		cache= function(cacheId, url, value){
-			cached[cacheId]= value;
-			dojo.cache({toString:function(){return url;}}, value);
-		},
-
-		strip= function(text){
-			//note: this function courtesy of James Burke (https://github.com/jrburke/requirejs)
-			//Strips <?xml ...?> declarations so that external SVG and XML
-			//documents can be added to a document without worry. Also, if the string
-			//is an HTML document, only the part inside the body tag is returned.
-			if(text){
-				text= text.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, "");
-				var matches= text.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
-				if(matches){
-					text= matches[1];
-				}
-			}else{
-				text = "";
-			}
-			return text;
-		};
-
-	return {
-		load:function(id, require, load){
-			var match, cacheId, url, parts= id.split("!");
-			if(require.toAbsMid){
-				match= parts[0].match(/(.+)(\.[^\/]*)$/);
-				cacheId= match ? require.toAbsMid(match[1]) + match[2] : require.toAbsMid(parts[0]);
-				if(cacheId in cached){
-					load(parts[1]=="strip" ? strip(cached[cacheId]) : cached[cacheId]);
-					return;
-				}
-			}
-			url= require.toUrl(parts[0]);
-			dojo.xhrGet({
-				url:url,
-				load:function(text){
-					cacheId && cache(cacheId, url, text);
-					load(parts[1]=="strip" ? strip(text) : text);
-				}
-			});
-		},
-
-		cache:function(cacheId, mid, type, value) {
-			cache(cacheId, require.nameToUrl(mid) + type, value);
-		}
-	};
-});
diff --git a/dojo/loadInit.js b/dojo/loadInit.js
new file mode 100644
index 0000000..8ef581a
--- /dev/null
+++ b/dojo/loadInit.js
@@ -0,0 +1,7 @@
+define(["./_base/loader"], function(loader){
+	return {
+		dynamic:0,
+		normalize:function(id){return id;},
+		load:loader.loadInit
+	};
+});
diff --git a/dojo/main.js b/dojo/main.js
new file mode 100644
index 0000000..dee4002
--- /dev/null
+++ b/dojo/main.js
@@ -0,0 +1,50 @@
+define([
+	"./_base/kernel",
+	"./has",
+	"require",
+	"./_base/sniff",
+	"./_base/lang",
+	"./_base/array",
+	"./ready",
+	"./_base/declare",
+	"./_base/connect",
+	"./_base/Deferred",
+	"./_base/json",
+	"./_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){
+	// module:
+	//		dojo/main
+	// summary:
+	//		This is the package main module for the dojo package; it loads dojo base appropriate for the execution environment.
+
+	// 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
+	// loading dojo.js or explicitly include dojo/_firebug/firebug in a dependency list.
+	if(dojo.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;
+		if(deps){
+			// dojo.config.require may be dot notation
+			deps= array.map(lang.isArray(deps) ? deps : [deps], function(item){ return item.replace(/\./g, "/"); });
+			if(dojo.isAsync){
+				require(deps);
+			}else{
+				// this is a bit janky; in 1.6- dojo is defined before these requires are applied; but in 1.7+
+				// dojo isn't defined until returning from this module; this is only a problem in sync mode
+				// since we're in sync mode, we know we've got our loader with its priority ready queue
+				ready(1, function(){require(deps);});
+			}
+		}
+	}
+
+	return dojo;
+});
diff --git a/dojo/mouse.js b/dojo/mouse.js
new file mode 100644
index 0000000..9d47f82
--- /dev/null
+++ b/dojo/mouse.js
@@ -0,0 +1,127 @@
+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");
+	//		|		});
+	};
+	======*/
+
+    has.add("dom-quirks", win.doc && win.doc.compatMode == "BackCompat");
+ 	has.add("events-mouseenter", win.doc && "onmouseenter" in win.doc.createElement("div"));
+
+	var mouseButtons;
+	if(has("dom-quirks") || !has("dom-addeventlistener")){
+		mouseButtons = {
+			LEFT:   1,
+			MIDDLE: 4,
+			RIGHT:  2,
+			// helper functions
+			isButton: function(e, button){ return e.button & button; },
+			isLeft:   function(e){ return e.button & 1; },
+			isMiddle: function(e){ return e.button & 4; },
+			isRight:  function(e){ return e.button & 2; }
+		};
+	}else{
+		mouseButtons = {
+			LEFT:   0,
+			MIDDLE: 1,
+			RIGHT:  2,
+			// helper functions
+			isButton: function(e, button){ return e.button == button; },
+			isLeft:   function(e){ return e.button == 0; },
+			isMiddle: function(e){ return e.button == 1; },
+			isRight:  function(e){ return e.button == 2; }
+		};
+	}
+	dojo.mouseButtons = mouseButtons;
+
+/*=====
+	dojo.mouseButtons = {
+		// LEFT: Number
+		//		Numeric value of the left mouse button for the platform.
+		LEFT:   0,
+		// MIDDLE: Number
+		//		Numeric value of the middle mouse button for the platform.
+		MIDDLE: 1,
+		// RIGHT: Number
+		//		Numeric value of the right mouse button for the platform.
+		RIGHT:  2,
+
+		isButton: function(e, button){
+			// summary:
+			//		Checks an event object for a pressed button
+			// e: Event
+			//		Event object to examine
+			// button: Number
+			//		The button value (example: dojo.mouseButton.LEFT)
+			return e.button == button; // Boolean
+		},
+		isLeft: function(e){
+			// summary:
+			//		Checks an event object for the pressed left button
+			// e: Event
+			//		Event object to examine
+			return e.button == 0; // Boolean
+		},
+		isMiddle: function(e){
+			// summary:
+			//		Checks an event object for the pressed middle button
+			// e: Event
+			//		Event object to examine
+			return e.button == 1; // Boolean
+		},
+		isRight: function(e){
+			// summary:
+			//		Checks an event object for the pressed right button
+			// e: Event
+			//		Event object to examine
+			return e.button == 2; // Boolean
+		}
+	};
+=====*/
+
+	function eventHandler(type, mustBubble){
+		// 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)){
+					return listener.call(this, evt);
+				}
+			});
+		};
+		if(!mustBubble){
+			handler.bubble = eventHandler(type, true);
+		}
+		return handler;
+	}
+	return {
+		enter: eventHandler("mouseover"),
+		leave: eventHandler("mouseout"),
+		isLeft: mouseButtons.isLeft,
+		isMiddle: mouseButtons.isMiddle,
+		isRight: mouseButtons.isRight
+	};
+});
diff --git a/dojo/nls/az/colors.js b/dojo/nls/az/colors.js
new file mode 100644
index 0000000..f69753e
--- /dev/null
+++ b/dojo/nls/az/colors.js
@@ -0,0 +1,153 @@
+define(
+//begin v1.x content
+({
+	"lightsteelblue":"açıq metal mavi",
+	"orangered" :"narıncı qırmızı",
+	"midnightblue" :"gecə mavisi",
+	"cadetblue" :"dəniz mavisi" ,
+	"seashell" :"dəniz səthi",
+	"slategrey" :"boz şifer rəngi",
+	"coral" :"mərcan",
+	"darkturquoise" :"tünd firuzəyi",
+	"antiquewhite" :"antik ağ",
+	"mediumspringgreen" :"orta bahar yaşılı",
+	"salmon" :"somon",
+	"darkgrey" :"tünd boz",
+	"ivory" :"fil dişi",
+	"greenyellow" :"yaşıl-sarı",
+	"mistyrose" :"gül qurusu",
+	"lightsalmon" :"açıq somon",
+	"silver" :"gümüşü",
+	"dimgrey" :"açıq boz",
+	"orange" :"narıncı",
+	"white" :"ağ",
+	"navajowhite" :"navajo ağı",
+	"royalblue" :"parlaq tünd mavi" ,
+	"deeppink" :"tünd çəhrayı",
+	"lime" :"lomon yaşılı",
+	"oldlace" :"köhnə krujeva",
+	"chartreuse" :"chartreuse",
+	"darkcyan" :"tünd firuzəyi",
+	"yellow" :"sarı",
+	"linen" :"kətan",
+	"olive" :"zeytun",
+	"gold" :"qızıl",
+	"lawngreen" :"çəmən yaşılı",
+	"lightyellow" :"açıq sarı",
+	"tan" :"günəş yanığı",
+	"darkviolet" :"tünd bənövşəyi",
+	"lightslategrey" :"tünd şifer bozu",
+	"grey" :"boz",
+	"darkkhaki" :"tünd haki",
+	"green" :"yaşıl",
+	"deepskyblue" :"tünd səma mavisi",
+	"aqua" :"dəniz mavisi",
+	"sienna" :"tünd qəhvəyi",
+	"mintcream" :"nanəli krem",
+	"rosybrown" :"çəhrayımsı qəhvəyi",
+	"mediumslateblue" :"orta şıfer bozu",
+	"magenta" :"magenta",
+	"lightseagreen" :"açıq dəniz yaşılı",
+	"cyan" :"firuzəyi",
+	"olivedrab" :"əsgər yaşılı",
+	"darkgoldenrod" :"tünd sarı",
+	"slateblue" :"şifer mavisi",
+	"mediumaquamarine" :"orta akvamarin",
+	"lavender" :"lavanta",
+	"mediumseagreen" :"orta dəniz yaşılı",
+	"maroon" :"tünd qırmızı",
+	"darkslategray" :"tünd şifer bozu",
+	"mediumturquoise" :"orta firuzəyi",
+	"ghostwhite" :"ala",
+	"darkblue" :"tünd mavi",
+	"mediumvioletred" :"orta bənövşəyi-qırmızı",
+	"brown" :"qəhvəyi",
+	"lightgray" :"açıq boz",
+	"sandybrown" :"qum rəngi",
+	"pink" :"çəhrayı",
+	"firebrick" :"yanmış kərpic rəngi",
+	"indigo" :"indigo",
+	"snow" :"qar",
+	"darkorchid" :"tünd orkide",
+	"turquoise" :"firuzəyi",
+	"chocolate" :"şokolad",
+	"springgreen" :"bahar yaşılı",
+	"moccasin" :"mokosen",
+	"navy" :"tünd göy",
+	"lemonchiffon" :"limon rəngi",
+	"teal" :"teal mavi",
+	"floralwhite" :"çiçək ağı",
+	"cornflowerblue" :"peyğəmbər çiçək mavisi",
+	"paleturquoise" :"solğun firuzəyi",
+	"purple" :"tünd qırmızı",
+	"gainsboro" :"gainsboro",
+	"plum" :"gavalı",
+	"red" :"qırmızı",
+	"blue" :"göy",
+	"forestgreen" :"tünd dəniz yaşılı",
+	"darkgreen" :"tünd yaşıl",
+	"honeydew" :"bal saqqızı",
+	"darkseagreen" :"tünd dəniz yaşılı",
+	"lightcoral" :"açıq mərcan",
+	"palevioletred" :"solğun bənövşəyi-qırmızı",
+	"mediumpurple" :"orta tünd qırmızı",
+	"saddlebrown" :"açıq qəhvəyi",
+	"darkmagenta" :"tünd magenta",
+	"thistle" :"dəvə tikanı",
+	"whitesmoke" :"ağ duman",
+	"wheat" :"buğdayı",
+	"violet" :"bənövşəyi",
+	"lightskyblue" :"açıq səma mavisi" ,
+	"goldenrod" :"sapsarı",
+	"mediumblue" :"orta göy",
+	"skyblue" :"göy mavisi",
+	"crimson" :"crimson",
+	"darksalmon" :"tünd somon",
+	"darkred" :"tünd qırmızı",
+	"darkslategrey" :"tünd şifer bozu",
+	"peru" :"peru",
+	"lightgrey" :"açıq boz",
+	"lightgoldenrodyellow" :"açıq qızılı",
+	"blanchedalmond" :"solğun badamı",
+	"aliceblue" :"alice mavisi",
+	"bisque" :"biskvit",
+	"slategray" :"şifer bozu",
+	"palegoldenrod" :"açıq qızılı",
+	"darkorange" :"tünd narıncı",
+	"aquamarine" :"akvamarin",
+	"lightgreen" :"açıq yaşıl",
+	"burlywood" :"sarımsı qəhvə rəngi",
+	"dodgerblue" :"toz mavisi",
+	"darkgray" :"tünd boz",
+	"lightcyan" :"açıq firuzəyi",
+	"powderblue" :"pudra mavisi",
+	"blueviolet" :"mavi-bənövşəyi",
+	"orchid" :"orkide",
+	"dimgray" :"solğun boz",
+	"beige" :"bej",
+	"fuchsia" :"fuşya",
+	"lavenderblush" :"lavanta tünd qırmızısı",
+	"hotpink" :"tünd çəhrayı",
+	"steelblue" :"metal mavisi",
+	"tomato" :"pomidor",
+	"lightpink" :"açıq çəhrayı",
+	"limegreen" :"əhəng yaşılı",
+	"indianred" :"qızıldərili qırmızısı",
+	"papayawhip" :"papaya qamçısı",
+	"lightslategray" :"açıq şifer bozu",
+	"gray" :"boz",
+	"mediumorchid" :"orta orkide",
+	"cornsilk" :"qarğıdalı rəngi",
+	"black" :"qara",
+	"seagreen" :"dəniz yaşılı",
+	"darkslateblue" :"tünd şifer bozu",
+	"khaki" :"haki",
+	"lightblue" :"açıq mavi",
+	"palegreen" :"solğun yaşıl",
+	"azure" :"azur mavisi",
+	"peachpuff" :"açıq şaftalı",
+	"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/ca/colors.js b/dojo/nls/ca/colors.js
index 2539d8a..c0516bf 100644
--- a/dojo/nls/ca/colors.js
+++ b/dojo/nls/ca/colors.js
@@ -146,6 +146,7 @@ tan: "tan",
 teal: "verd blavós",
 thistle: "card",
 tomato: "tomàquet",
+transparent: "transparent",
 turquoise: "turquesa",
 violet: "violeta",
 wheat: "blat",
diff --git a/dojo/nls/colors.js b/dojo/nls/colors.js
index 2ce7469..9808141 100644
--- a/dojo/nls/colors.js
+++ b/dojo/nls/colors.js
@@ -146,6 +146,7 @@ tan: "tan",
 teal: "teal",
 thistle: "thistle",
 tomato: "tomato",
+transparent: "transparent",
 turquoise: "turquoise",
 violet: "violet",
 wheat: "wheat",
@@ -175,6 +176,7 @@ yellowgreen: "yellow green"
 "ja": true,
 "it": true,
 "hu": true,
+"hr": true,
 "he": true,
 "fr": true,
 "fi": true,
@@ -184,5 +186,6 @@ yellowgreen: "yellow green"
 "da": true,
 "cs": true,
 "ca": true,
+"az": true,
 "ar": true
 });
diff --git a/dojo/nls/cs/colors.js b/dojo/nls/cs/colors.js
index c642555..affd7f3 100644
--- a/dojo/nls/cs/colors.js
+++ b/dojo/nls/cs/colors.js
@@ -146,6 +146,7 @@ tan: "šedobéžová",
 teal: "šedozelená",
 thistle: "bodláková",
 tomato: "tomatová",
+transparent: "průhledná",
 turquoise: "tyrkysová",
 violet: "fialová",
 wheat: "zlatohnědá",
diff --git a/dojo/nls/da/colors.js b/dojo/nls/da/colors.js
index 45ddba4..84b25a6 100644
--- a/dojo/nls/da/colors.js
+++ b/dojo/nls/da/colors.js
@@ -146,6 +146,7 @@ tan: "tan",
 teal: "blågrøn",
 thistle: "tidsel",
 tomato: "tomat",
+transparent: "transparent",
 turquoise: "turkis",
 violet: "lilla",
 wheat: "korngul",
diff --git a/dojo/nls/de/colors.js b/dojo/nls/de/colors.js
index 24bfc87..cc7ca92 100644
--- a/dojo/nls/de/colors.js
+++ b/dojo/nls/de/colors.js
@@ -146,6 +146,7 @@ tan: "Hautfarben",
 teal: "Smaragdgrün",
 thistle: "Distel",
 tomato: "Tomatenrot",
+transparent: "Transparent",
 turquoise: "Türkis",
 violet: "Violett",
 wheat: "Weizen",
diff --git a/dojo/nls/el/colors.js b/dojo/nls/el/colors.js
index 277cf65..141e777 100644
--- a/dojo/nls/el/colors.js
+++ b/dojo/nls/el/colors.js
@@ -146,6 +146,7 @@ tan: "ώχρα",
 teal: "πετρόλ",
 thistle: "μωβ βιολετί",
 tomato: "κόκκινο της ντομάτας",
+transparent: "διαφανές",
 turquoise: "τυρκουάζ",
 violet: "βιολετί",
 wheat: "σταρένιο",
diff --git a/dojo/nls/es/colors.js b/dojo/nls/es/colors.js
index 0366f56..54d78f2 100644
--- a/dojo/nls/es/colors.js
+++ b/dojo/nls/es/colors.js
@@ -146,6 +146,7 @@ tan: "canela",
 teal: "verde azulado",
 thistle: "cardo",
 tomato: "tomate",
+transparent: "transparente",
 turquoise: "turquesa",
 violet: "violeta",
 wheat: "trigo",
diff --git a/dojo/nls/fi/colors.js b/dojo/nls/fi/colors.js
index 08c796b..754b9dd 100644
--- a/dojo/nls/fi/colors.js
+++ b/dojo/nls/fi/colors.js
@@ -146,6 +146,7 @@ tan: "kellanruskea",
 teal: "sinivihreä",
 thistle: "ohdake",
 tomato: "tomaatinpunainen",
+transparent: "läpinäkyvä",
 turquoise: "turkoosi",
 violet: "violetti",
 wheat: "vehnänkeltainen",
diff --git a/dojo/nls/fr/colors.js b/dojo/nls/fr/colors.js
index e7a48bb..5c77724 100644
--- a/dojo/nls/fr/colors.js
+++ b/dojo/nls/fr/colors.js
@@ -146,6 +146,7 @@ tan: "grège",
 teal: "sarcelle",
 thistle: "chardon",
 tomato: "tomate",
+transparent: "transparent",
 turquoise: "turquoise",
 violet: "violet",
 wheat: "blé",
diff --git a/dojo/nls/hr/colors.js b/dojo/nls/hr/colors.js
new file mode 100644
index 0000000..51dbdeb
--- /dev/null
+++ b/dojo/nls/hr/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 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 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"
+})
+);
diff --git a/dojo/nls/hu/colors.js b/dojo/nls/hu/colors.js
index d34dcc0..9321871 100644
--- a/dojo/nls/hu/colors.js
+++ b/dojo/nls/hu/colors.js
@@ -146,6 +146,7 @@ tan: "rozsdabarna",
 teal: "pávakék",
 thistle: "bogáncs",
 tomato: "paradicsom",
+transparent: "átlátszó",
 turquoise: "türkizkék",
 violet: "ibolyaszín",
 wheat: "búza",
diff --git a/dojo/nls/it/colors.js b/dojo/nls/it/colors.js
index 89729dd..3a03eeb 100644
--- a/dojo/nls/it/colors.js
+++ b/dojo/nls/it/colors.js
@@ -146,6 +146,7 @@ tan: "grigio bruno",
 teal: "verde turchese",
 thistle: "rosa cenere",
 tomato: "pomodoro",
+transparent: "trasparente",
 turquoise: "turchese",
 violet: "viola",
 wheat: "sabbia",
diff --git a/dojo/nls/ja/colors.js b/dojo/nls/ja/colors.js
index 166bde5..a4a3949 100644
--- a/dojo/nls/ja/colors.js
+++ b/dojo/nls/ja/colors.js
@@ -146,6 +146,7 @@ tan: "茶褐色",
 teal: "ティール",
 thistle: "シスル",
 tomato: "トマト色",
+transparent: "透明",
 turquoise: "ターコイズ",
 violet: "すみれ色",
 wheat: "小麦色",
diff --git a/dojo/nls/kk/colors.js b/dojo/nls/kk/colors.js
index edd06d5..2f929cb 100644
--- a/dojo/nls/kk/colors.js
+++ b/dojo/nls/kk/colors.js
@@ -146,6 +146,7 @@ tan: "сарғыш қоңыр",
 teal: "шүрегей",
 thistle: "артишок",
 tomato: "қызанақ",
+transparent: "мөлдір",
 turquoise: "көгілдір",
 violet: "күлгін",
 wheat: "бидай",
@@ -156,4 +157,3 @@ yellowgreen: "сарғыш жасыл"
 })
 //end v1.x content
 );
-
diff --git a/dojo/nls/ko/colors.js b/dojo/nls/ko/colors.js
index 3fd26f7..94f295d 100644
--- a/dojo/nls/ko/colors.js
+++ b/dojo/nls/ko/colors.js
@@ -146,6 +146,7 @@ tan: "탠(tan)",
 teal: "틸(teal)",
 thistle: "시슬(thistle)",
 tomato: "토마토(tomato)",
+transparent: "투명(transparent)",
 turquoise: "터콰즈(turquoise)",
 violet: "바이올렛(violet)",
 wheat: "휘트(wheat)",
diff --git a/dojo/nls/nb/colors.js b/dojo/nls/nb/colors.js
index ad32efc..79aa9fc 100644
--- a/dojo/nls/nb/colors.js
+++ b/dojo/nls/nb/colors.js
@@ -146,6 +146,7 @@ tan: "matt mellombrun",
 teal: "mørk grønnblå",
 thistle: "lys grålilla",
 tomato: "tomatrød",
+transparent: "gjennomsiktig",
 turquoise: "turkis",
 violet: "fiolett",
 wheat: "varm sienna",
diff --git a/dojo/nls/nl/colors.js b/dojo/nls/nl/colors.js
index 221f41a..618b07f 100644
--- a/dojo/nls/nl/colors.js
+++ b/dojo/nls/nl/colors.js
@@ -146,6 +146,7 @@ tan: "geelbruin",
 teal: "grijsblauw",
 thistle: "distel",
 tomato: "tomaat",
+transparent: "transparant",
 turquoise: "turquoise",
 violet: "violet",
 wheat: "tarwebruin",
diff --git a/dojo/nls/pl/colors.js b/dojo/nls/pl/colors.js
index b8ce369..8ff7af0 100644
--- a/dojo/nls/pl/colors.js
+++ b/dojo/nls/pl/colors.js
@@ -146,6 +146,7 @@ tan: "śniady",
 teal: "zielonomodry",
 thistle: "bladofioletowy",
 tomato: "pomidorowy",
+transparent: "przezroczysty",
 turquoise: "turkusowy",
 violet: "fiołkowy",
 wheat: "pszeniczny",
diff --git a/dojo/nls/pt/colors.js b/dojo/nls/pt/colors.js
index e58d51b..388cde4 100644
--- a/dojo/nls/pt/colors.js
+++ b/dojo/nls/pt/colors.js
@@ -146,6 +146,7 @@ tan: "tan",
 teal: "azul esverdeado",
 thistle: "thistle",
 tomato: "tomate",
+transparent: "transparente",
 turquoise: "turquesa",
 violet: "violeta",
 wheat: "trigo",
diff --git a/dojo/nls/ro/colors.js b/dojo/nls/ro/colors.js
index 6b27c40..2286643 100644
--- a/dojo/nls/ro/colors.js
+++ b/dojo/nls/ro/colors.js
@@ -146,6 +146,7 @@ tan: "tan",
 teal: "lişiţă",
 thistle: "ciulin",
 tomato: "roşie",
+transparent: "transparent",
 turquoise: "turquoise",
 violet: "violet",
 wheat: "grâu",
diff --git a/dojo/nls/ru/colors.js b/dojo/nls/ru/colors.js
index 019b2ef..7be5743 100644
--- a/dojo/nls/ru/colors.js
+++ b/dojo/nls/ru/colors.js
@@ -146,6 +146,7 @@ tan: "рыжевато-коричневый",
 teal: "чирок",
 thistle: "чертополох",
 tomato: "помидор",
+transparent: "прозрачный",
 turquoise: "бирюзовый",
 violet: "фиолетовый",
 wheat: "пшеница",
diff --git a/dojo/nls/sk/colors.js b/dojo/nls/sk/colors.js
index f362f8e..5e279f3 100644
--- a/dojo/nls/sk/colors.js
+++ b/dojo/nls/sk/colors.js
@@ -146,6 +146,7 @@ tan: "žltohnedá",
 teal: "tyrkysová",
 thistle: "bodliaková fialová",
 tomato: "paradajková červená",
+transparent: "priesvitná",
 turquoise: "tyrkysová",
 violet: "fialová",
 wheat: "pšeničná",
diff --git a/dojo/nls/sl/colors.js b/dojo/nls/sl/colors.js
index dd4d805..8a8b668 100644
--- a/dojo/nls/sl/colors.js
+++ b/dojo/nls/sl/colors.js
@@ -146,6 +146,7 @@ tan: "rumeno-rjava",
 teal: "modrozelena",
 thistle: "osatna",
 tomato: "paradižnikova",
+transparent: "prosojno",
 turquoise: "turkizna",
 violet: "vijolična",
 wheat: "pšenična",
diff --git a/dojo/nls/sv/colors.js b/dojo/nls/sv/colors.js
index 7041399..3131845 100644
--- a/dojo/nls/sv/colors.js
+++ b/dojo/nls/sv/colors.js
@@ -146,6 +146,7 @@ tan: "mellanbrunt",
 teal: "blågrönt",
 thistle: "tistel",
 tomato: "tomatrött",
+transparent: "transparent",
 turquoise: "turkost",
 violet: "violett",
 wheat: "vete",
diff --git a/dojo/nls/th/colors.js b/dojo/nls/th/colors.js
index 71576d3..314f41d 100644
--- a/dojo/nls/th/colors.js
+++ b/dojo/nls/th/colors.js
@@ -146,6 +146,7 @@ tan: "tan",
 teal: "teal",
 thistle: "thistle",
 tomato: "tomato",
+transparent: "สีใส",
 turquoise: "turquoise",
 violet: "ม่วง",
 wheat: "wheat",
diff --git a/dojo/nls/tr/colors.js b/dojo/nls/tr/colors.js
index 9c422eb..27df167 100644
--- a/dojo/nls/tr/colors.js
+++ b/dojo/nls/tr/colors.js
@@ -146,6 +146,7 @@ tan: "güneş yanığı",
 teal: "Teal mavi",
 thistle: "devedikeni",
 tomato: "domates",
+transparent: "saydam",
 turquoise: "turkuaz",
 violet: "eflatun",
 wheat: "buğday",
diff --git a/dojo/nls/zh-tw/colors.js b/dojo/nls/zh-tw/colors.js
index aaba93b..61f2f6f 100644
--- a/dojo/nls/zh-tw/colors.js
+++ b/dojo/nls/zh-tw/colors.js
@@ -146,6 +146,7 @@ tan: "皮革色",
 teal: "深藍綠色",
 thistle: "薊色",
 tomato: "蕃茄紅",
+transparent: "透明",
 turquoise: "松石綠",
 violet: "紫羅蘭色",
 wheat: "小麥色",
diff --git a/dojo/nls/zh/colors.js b/dojo/nls/zh/colors.js
index acea325..3aabe7b 100644
--- a/dojo/nls/zh/colors.js
+++ b/dojo/nls/zh/colors.js
@@ -146,6 +146,7 @@ tan: "茶色",
 teal: "青色",
 thistle: "蓟色",
 tomato: "番茄色",
+transparent: "透明的",
 turquoise: "青绿色",
 violet: "紫罗兰色",
 wheat: "淡黄色",
diff --git a/dojo/number.js b/dojo/number.js
index b0a09af..eba7616 100644
--- a/dojo/number.js
+++ b/dojo/number.js
@@ -1,5 +1,12 @@
-define("dojo/number", ["dojo", "dojo/i18n", "i18n!dojo/cldr/nls/number", "dojo/string", "dojo/regexp"], function(dojo) {
-dojo.getObject("number", true, dojo);
+define(["./_base/kernel", "./_base/lang", "./i18n", "./i18n!./cldr/nls/number", "./string", "./regexp"],
+	function(dojo, lang, i18n, nlsNumber, dstring, dregexp) {
+
+	// module:
+	//		dojo/number
+	// summary:
+	//		TODOC
+
+lang.getObject("number", true, dojo);
 
 /*=====
 dojo.number = {
@@ -45,9 +52,9 @@ dojo.number.format = function(/*Number*/value, /*dojo.number.__FormatOptions?*/o
 	// value:
 	//		the number to be formatted
 
-	options = dojo.mixin({}, options || {});
-	var locale = dojo.i18n.normalizeLocale(options.locale),
-		bundle = dojo.i18n.getLocalization("dojo.cldr", "number", locale);
+	options = lang.mixin({}, options || {});
+	var locale = i18n.normalizeLocale(options.locale),
+		bundle = i18n.getLocalization("dojo.cldr", "number", locale);
 	options.customs = bundle;
 	var pattern = options.pattern || bundle[(options.type || "decimal") + "Format"];
 	if(isNaN(value) || Math.abs(value) == Infinity){ return null; } // null
@@ -94,7 +101,7 @@ dojo.number._applyPattern = function(/*Number*/value, /*String*/pattern, /*dojo.
 	}else if(pattern.indexOf('E') != -1){
 		throw new Error("exponential notation not supported");
 	}
-	
+
 	//TODO: support @ sig figs?
 	var numberPatternRE = dojo.number._numberPatternRE;
 	var numberPattern = positivePattern.match(numberPatternRE);
@@ -135,16 +142,14 @@ 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
-	(function(){
-		var round = dojo.number.round;
-		dojo.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){
-				d = 0;
-			}
-			return round(v, p, m) + (v > 0 ? d : -d);
-		};
-	})();
+	var round = dojo.number.round;
+	dojo.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){
+			d = 0;
+		}
+		return round(v, p, m) + (v > 0 ? d : -d);
+	};
 }
 
 /*=====
@@ -198,7 +203,7 @@ dojo.number._formatAbsolute = function(/*Number*/value, /*String*/pattern, /*doj
 		// Pad fractional with trailing zeros
 		var pad = options.places !== undefined ? options.places : (patternParts[1] && patternParts[1].lastIndexOf("0") + 1);
 		if(pad > fractional.length){
-			valueParts[1] = dojo.string.pad(fractional, pad, '0', true);
+			valueParts[1] = dstring.pad(fractional, pad, '0', true);
 		}
 
 		// Truncate fractional
@@ -215,7 +220,7 @@ dojo.number._formatAbsolute = function(/*Number*/value, /*String*/pattern, /*doj
 	if(pad != -1){
 		pad = patternDigits.length - pad;
 		if(pad > valueParts[0].length){
-			valueParts[0] = dojo.string.pad(valueParts[0], pad);
+			valueParts[0] = dstring.pad(valueParts[0], pad);
 		}
 
 		// Truncate whole
@@ -285,8 +290,8 @@ dojo.number.regexp = function(/*dojo.number.__RegexpOptions?*/options){
 
 dojo.number._parseInfo = function(/*Object?*/options){
 	options = options || {};
-	var locale = dojo.i18n.normalizeLocale(options.locale),
-		bundle = dojo.i18n.getLocalization("dojo.cldr", "number", locale),
+	var locale = i18n.normalizeLocale(options.locale),
+		bundle = i18n.getLocalization("dojo.cldr", "number", locale),
 		pattern = options.pattern || bundle[(options.type || "decimal") + "Format"],
 //TODO: memoize?
 		group = bundle.group,
@@ -311,8 +316,8 @@ dojo.number._parseInfo = function(/*Object?*/options){
 		patternList.push("-" + patternList[0]);
 	}
 
-	var re = dojo.regexp.buildGroupRE(patternList, function(pattern){
-		pattern = "(?:"+dojo.regexp.escapeString(pattern, '.')+")";
+	var re = dregexp.buildGroupRE(patternList, function(pattern){
+		pattern = "(?:"+dregexp.escapeString(pattern, '.')+")";
 		return pattern.replace(dojo.number._numberPatternRE, function(format){
 			var flags = {
 				signed: false,
@@ -353,7 +358,7 @@ dojo.number._parseInfo = function(/*Object?*/options){
 		// substitute the currency symbol for the placeholder in the pattern
 		re = re.replace(/([\s\xa0]*)(\u00a4{1,3})([\s\xa0]*)/g, function(match, before, target, after){
 			var prop = ["symbol", "currency", "displayName"][target.length-1],
-				symbol = dojo.regexp.escapeString(options[prop] || options.currency || "");
+				symbol = dregexp.escapeString(options[prop] || options.currency || "");
 			before = before ? "[\\s\\xa0]" : "";
 			after = after ? "[\\s\\xa0]" : "";
 			if(!options.strict){
@@ -475,7 +480,7 @@ dojo.number._realNumberRegexp = function(/*dojo.number.__RealNumberRegexpFlags?*
 	if(!("eSigned" in flags)){ flags.eSigned = [true, false]; }
 
 	var integerRE = dojo.number._integerRegexp(flags),
-		decimalRE = dojo.regexp.buildGroupRE(flags.fractional,
+		decimalRE = dregexp.buildGroupRE(flags.fractional,
 		function(q){
 			var re = "";
 			if(q && (flags.places!==0)){
@@ -491,7 +496,7 @@ dojo.number._realNumberRegexp = function(/*dojo.number.__RealNumberRegexpFlags?*
 		true
 	);
 
-	var exponentRE = dojo.regexp.buildGroupRE(flags.exponent,
+	var exponentRE = dregexp.buildGroupRE(flags.exponent,
 		function(q){
 			if(q){ return "([eE]" + dojo.number._integerRegexp({ signed: flags.eSigned}) + ")"; }
 			return "";
@@ -538,18 +543,18 @@ dojo.number._integerRegexp = function(/*dojo.number.__IntegerRegexpFlags?*/flags
 		flags.groupSize = 3;
 	}
 
-	var signRE = dojo.regexp.buildGroupRE(flags.signed,
+	var signRE = dregexp.buildGroupRE(flags.signed,
 		function(q){ return q ? "[-+]" : ""; },
 		true
 	);
 
-	var numberRE = dojo.regexp.buildGroupRE(flags.separator,
+	var numberRE = dregexp.buildGroupRE(flags.separator,
 		function(sep){
 			if(!sep){
 				return "(?:\\d+)";
 			}
 
-			sep = dojo.regexp.escapeString(sep);
+			sep = dregexp.escapeString(sep);
 			if(sep == " "){ sep = "\\s"; }
 			else if(sep == "\xa0"){ sep = "\\s\\xa0"; }
 
diff --git a/dojo/on.js b/dojo/on.js
new file mode 100644
index 0000000..e233209
--- /dev/null
+++ b/dojo/on.js
@@ -0,0 +1,474 @@
+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.
+
+ 	"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?
+	}
+	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
+			return target.on(type, listener);
+		}
+		// delegate to main listener code
+		return on.parse(target, type, listener, addListener, dontFix, this);
+	};
+	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
+		//		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;
+		var signal = on(target, type, function(){
+			if(!paused){
+				return listener.apply(this, arguments);
+			}
+		}, dontFix);
+		signal.pause = function(){
+			paused = true;
+		};
+		signal.resume = function(){
+			paused = false;
+		};
+		return signal;
+	};
+	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
+		//		event that takes place and then listener will automatically be removed.
+		var signal = on(target, type, function(){
+			// remove this listener
+			signal.remove();
+			// proceed to call the listener
+			return listener.apply(this, arguments);
+		});
+		return signal;
+	};
+	on.parse = function(target, type, listener, addListener, dontFix, matchesTarget){
+		if(type.call){
+			// event handler function
+			// on(node, dojo.touch.press, touchListener);
+			return type.call(matchesTarget, target, listener);
+		}
+
+		if(type.indexOf(",") > -1){
+			// we allow comma delimited event names, so you can register for multiple events at once
+			var events = type.split(/\s*,\s*/);
+			var handles = [];
+			var i = 0;
+			var eventName;
+			while(eventName = events[i++]){
+				handles.push(addListener(target, eventName, listener, dontFix, matchesTarget));
+			}
+			handles.remove = function(){
+				for(var i = 0; i < handles.length; i++){
+					handles[i].remove();
+				}
+			};
+			return handles;
+		}
+		return addListener(target, type, listener, dontFix, matchesTarget)
+	};
+	var touchEvents = /^touch/;
+	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
+		if(selector){
+			type = selector[2];
+			selector = selector[1];
+			// create the extension event for selectors and directly call it
+			return on.selector(selector, type).call(matchesTarget, target, listener);
+		}
+		// test to see if it a touch event right now, so we don't have to do it every time it fires
+		if(has("touch")){
+			if(touchEvents.test(type)){
+				// touch event, fix it
+				listener = fixTouchListener(listener);
+			}
+			if(!has("event-orientationchange") && (type == "orientationchange")){
+				//"orientationchange" not supported <= Android 2.1, 
+				//but works through "resize" on window
+				type = "resize"; 
+				target = window;
+				listener = fixTouchListener(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);
+			// create and return the signal
+			return {
+				remove: function(){
+					target.removeEventListener(type, listener, capture);
+				}
+			};
+		}
+		type = "on" + type;
+		if(fixAttach && target.attachEvent){
+			return fixAttach(target, type, listener);
+		}
+	 	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 CSS selector to use for filter events and determine the |this| of the event listener.
+		//	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);
+		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;
+				// 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
+						return;
+					}
+				}
+				return listener.call(eventTarget, event);
+			});
+		};
+	};
+
+	function syntheticPreventDefault(){
+		this.cancelable = false;
+	}
+	function syntheticStopPropagation(){
+		this.bubbles = false;
+	}
+	var slice = [].slice,
+		syntheticDispatch = on.emit = function(target, type, event){
+		// summary:
+		//		Fires an event on the target object.
+		//	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
+		//		are used when possible.
+		//	type:
+		//		The event type name. You can emulate standard native events like "click" and 
+		// 		"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.
+		//		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
+		//		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:
+		//		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:
+		//		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:
+		//		To fire our own click event
+		//	|	on.emit(dojo.byId("button"), "click", {
+		//	|		cancelable: true,
+		//	|		bubbles: true,
+		//	|		screenX: 33,
+		//	|		screenY: 44
+		//	|	});
+		//		We can also fire our own custom events:
+		//	|	on.emit(dojo.byId("slider"), "slide", {
+		//	|		cancelable: true,
+		//	|		bubbles: true,
+		//	|		direction: "left-to-right"
+		//	|	});
+		var args = slice.call(arguments, 2);
+		var method = "on" + type;
+		if("parentNode" in target){
+			// node (or node-like), create event controller methods
+			var newEvent = args[0] = {};
+			for(var i in event){
+				newEvent[i] = event[i];
+			}
+			newEvent.preventDefault = syntheticPreventDefault;
+			newEvent.stopPropagation = syntheticStopPropagation;
+			newEvent.target = target;
+			newEvent.type = type;
+			event = newEvent;
+		}
+		do{
+			// call any node which has a handler (note that ideally we would try/catch to simulate normal event propagation but that causes too much pain for debugging)
+			target[method] && target[method].apply(target, args);
+			// and then continue up the parent node chain if it is still bubbling (if started as bubbles and stopPropagation hasn't been called)
+		}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"
+		};
+		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)
+		}
+
+		// emiter 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
+				// 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");
+				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];
+					}
+				}
+				return target.dispatchEvent(nativeEvent) && nativeEvent;
+			}
+			return syntheticDispatch.apply(on, arguments); // emit for a non-node
+		};
+	}else{
+		// no addEventListener, basically old IE event normalization
+		on._fixEvent = function(evt, sender){
+			// summary:
+			//		normalizes properties on the event object including event
+			//		bubbling methods, keystroke normalization, and x/y positions
+			// evt:
+			//		native event object
+			// sender:
+			//		node to treat as "currentTarget"
+			if(!evt){
+				var w = sender && (sender.ownerDocument || sender.document || sender).parentWindow || window;
+				evt = w.event;
+			}
+			if(!evt){return(evt);}
+			if(!evt.target){ // check to see if it has been fixed yet
+				evt.target = evt.srcElement;
+				evt.currentTarget = (sender || evt.srcElement);
+				if(evt.type == "mouseover"){
+					evt.relatedTarget = evt.fromElement;
+				}
+				if(evt.type == "mouseout"){
+					evt.relatedTarget = evt.toElement;
+				}
+				if(!evt.stopPropagation){
+					evt.stopPropagation = stopPropagation;
+					evt.preventDefault = preventDefault;
+				}
+				switch(evt.type){
+					case "keypress":
+						var c = ("charCode" in evt ? evt.charCode : evt.keyCode);
+						if (c==10){
+							// CTRL-ENTER is CTRL-ASCII(10) on IE, but CTRL-ENTER on Mozilla
+							c=0;
+							evt.keyCode = 13;
+						}else if(c==13||c==27){
+							c=0; // Mozilla considers ENTER and ESC non-printable
+						}else if(c==3){
+							c=99; // Mozilla maps CTRL-BREAK to CTRL-c
+						}
+						// Mozilla sets keyCode to 0 when there is a charCode
+						// but that stops the event on IE.
+						evt.charCode = c;
+						_setKeyChar(evt);
+						break;
+				}
+			}
+			return evt;
+		};
+		var IESignal = function(handle){
+			this.handle = handle;
+		};
+		IESignal.prototype.remove = function(){
+			delete _dojoIEListeners_[this.handle];
+		};
+		var fixListener = function(listener){
+			// 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 fixAttach = function(target, type, listener){
+			listener = fixListener(listener);
+			if(((target.ownerDocument ? target.ownerDocument.parentWindow : target.parentWindow || target.window || window) != top || 
+						has("jscript") < 5.8) && 
+					!has("config-_allow_leaks")){
+				// IE will leak memory on certain handlers in frames (IE8 and earlier) and in unattached DOM nodes for JScript 5.7 and below.
+				// Here we use global redirection to solve the memory leaks
+				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;
+					if(oldListener){
+						emiter.listeners.push(_dojoIEListeners_.push(oldListener) - 1);
+					}
+				}
+				var handle;
+				emiter.listeners.push(handle = (emiter.global._dojoIEListeners_.push(listener) - 1));
+				return new IESignal(handle);
+			}
+			return aspect.after(target, type, listener, true);
+		};
+
+		var _setKeyChar = function(evt){
+			evt.keyChar = evt.charCode ? String.fromCharCode(evt.charCode) : '';
+			evt.charOrCode = evt.keyChar || evt.keyCode;
+		};
+		// Called in Event scope
+		var stopPropagation = function(){
+			this.cancelBubble = true;
+		};
+		var preventDefault = on._preventDefault = function(){
+			// Setting keyCode to 0 is the only way to prevent certain keypresses (namely
+			// ctrl-combinations that correspond to menu accelerator keys).
+			// Otoh, it prevents upstream listeners from getting this information
+			// Try to split the difference here by clobbering keyCode only for ctrl
+			// combinations. If you still need to access the key upstream, bubbledKeyCode is
+			// provided as a workaround.
+			this.bubbledKeyCode = this.keyCode;
+			if(this.ctrlKey){
+				try{
+					// squelch errors when keyCode is read-only
+					// (e.g. if keyCode is ctrl or shift)
+					this.keyCode = 0;
+				}catch(e){
+				}
+			}
+			this.returnValue = false;
+		};
+	}
+	if(has("touch")){ 
+		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
+				//3.More TBD e.g. force | screenX | screenX | clientX | clientY | radiusX | radiusY
+
+				// see if it has already been corrected
+				var event = originalEvent.corrected;
+				if(!event){
+					var type = originalEvent.type;
+					try{
+						delete originalEvent.type; // on some JS engines (android), deleting properties make them mutable
+					}catch(e){} 
+					if(originalEvent.type){
+						// deleting properties doesn't work (older iOS), have to use delegation
+						Event.prototype = originalEvent;
+						var event = new Event;
+						// have to delegate methods to make them work
+						event.preventDefault = function(){
+							originalEvent.preventDefault();
+						};
+						event.stopPropagation = function(){
+							originalEvent.stopPropagation();
+						};
+					}else{
+						// deletion worked, use property as is
+						event = originalEvent;
+						event.type = type;
+					}
+					originalEvent.corrected = event;
+					if(type == 'resize'){
+						if(windowOrientation == window.orientation){ 
+							return null;//double tap causes an unexpected 'resize' in Andriod 
+						} 
+						windowOrientation = window.orientation;
+						event.type = "orientationchange"; 
+						return listener.call(this, event);
+					}
+					// We use the original event and augment, rather than doing an expensive mixin operation
+					if(!("rotation" in event)){ // test to see if it has rotation
+						event.rotation = 0; 
+						event.scale = 1;
+					}
+					//use event.changedTouches[0].pageX|pageY|screenX|screenY|clientX|clientY|target
+					var firstChangeTouch = event.changedTouches[0];
+					for(var i in firstChangeTouch){ // use for-in, we don't need to have dependency on dojo/_base/lang here
+						delete event[i]; // delete it first to make it mutable
+						event[i] = firstChangeTouch[i];
+					}
+				}
+				return listener.call(this, event); 
+			}; 
+		}; 
+	}
+	return on;
+});
diff --git a/dojo/package.json b/dojo/package.json
index 5855be5..7618c4d 100644
--- a/dojo/package.json
+++ b/dojo/package.json
@@ -1,21 +1,23 @@
 {
-  "name": "dojo",
-  "directories": {
-    "lib": "."
-  },
-  "main":"./lib/main-browser",
-  "description": "Dojo core is a powerful, lightweight library that makes common tasks quicker and easier. Animate elements, manipulate the DOM, and query with easy CSS syntax, all without sacrificing performance.",
-  "licenses": [
-     {
-         "type": "AFLv2.1",
-         "url": "http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L43"
-     },
-     {
-         "type": "BSD",
-         "url": "http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L13"
-     }
-  ],
-  "bugs": "http://bugs.dojotoolkit.org/",
-  "keywords": ["JavaScript", "Dojo", "Toolkit"],
-  "homepage": "http://dojotoolkit.org/"
-}
\ No newline at end of file
+	"name": "dojo",
+	"version":"1.7.2",
+	"directories": {
+		"lib": "."
+	},
+	"main": "main",
+	"description": "Dojo core is a powerful, lightweight library that makes common tasks quicker and easier. Animate elements, manipulate the DOM, and query with easy CSS syntax, all without sacrificing performance.",
+	"licenses": [
+		 {
+				 "type": "AFLv2.1",
+				 "url": "http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L43"
+		 },
+		 {
+				 "type": "BSD",
+				 "url": "http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L13"
+		 }
+	],
+	"bugs": "http://bugs.dojotoolkit.org/",
+	"keywords": ["JavaScript", "Dojo", "Toolkit"],
+	"homepage": "http://dojotoolkit.org/",
+	"dojoBuild": "dojo.profile.js"
+}
diff --git a/dojo/parser.js b/dojo/parser.js
index b151c2a..4c849a1 100644
--- a/dojo/parser.js
+++ b/dojo/parser.js
@@ -1,130 +1,56 @@
-define("dojo/parser", ["dojo", "dojo/date/stamp"], function(dojo) {
+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 d = dojo;
-
-	function val2type(/*Object*/ value){
-		// summary:
-		//		Returns name of type of given value.
-
-		if(d.isString(value)){ return "string"; }
-		if(typeof value == "number"){ return "number"; }
-		if(typeof value == "boolean"){ return "boolean"; }
-		if(d.isFunction(value)){ return "function"; }
-		if(d.isArray(value)){ return "array"; } // typeof [] == "object"
-		if(value instanceof Date) { return "date"; } // assume timestamp
-		if(value instanceof d._Url){ return "url"; }
-		return "object";
-	}
-
-	function str2obj(/*String*/ value, /*String*/ type){
+	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:
-		//		Convert given string value to given type
-		switch(type){
-			case "string":
-				return value;
-			case "number":
-				return value.length ? Number(value) : NaN;
-			case "boolean":
-				// for checked/disabled value might be "" or "checked".	 interpret as true.
-				return typeof value == "boolean" ? value : !(value.toLowerCase()=="false");
-			case "function":
-				if(d.isFunction(value)){
-					// IE gives us a function, even when we say something like onClick="foo"
-					// (in which case it gives us an invalid function "function(){ foo }").
-					//	Therefore, convert to string
-					value=value.toString();
-					value=d.trim(value.substring(value.indexOf('{')+1, value.length-1));
-				}
-				try{
-					if(value === "" || value.search(/[^\w\.]+/i) != -1){
-						// The user has specified some text for a function like "return x+5"
-						return new Function(value);
-					}else{
-						// The user has specified the name of a function like "myOnClick"
-						// or a single word function "return"
-						return d.getObject(value, false) || new Function(value);
-					}
-				}catch(e){ return new Function(); }
-			case "array":
-				return value ? value.split(/\s*,\s*/) : [];
-			case "date":
-				switch(value){
-					case "": return new Date("");	// the NaN of dates
-					case "now": return new Date();	// current date
-					default: return d.date.stamp.fromISOString(value);
-				}
-			case "url":
-				return d.baseUrl + value;
-			default:
-				return d.fromJson(value);
+		//		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;
 	}
-
-	var dummyClass = {}, instanceClasses = {
-		// map from fully qualified name (like "dijit.Button") to structure like
-		// { cls: dijit.Button, params: {label: "string", disabled: "boolean"} }
-	};
-
 	// 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).
-	// TODO: remove this in 2.0, when we stop caching parameters.
-	d.connect(d, "extend", function(){
-		instanceClasses = {};
-	});
-
-	function getProtoInfo(cls, params){
-		// cls: A prototype
-		//		The prototype of the class to check props on
-		// params: Object
-		//		The parameters object to mix found parameters onto.
-		for(var name in cls){
-			if(name.charAt(0)=="_"){ continue; }	// skip internal properties
-			if(name in dummyClass){ continue; }		// skip "constructor" and "toString"
-			params[name] = val2type(cls[name]);
-		}
-		return params;
-	}
+	aspect.after(dlang, "extend", function(){
+		_nameMap = {};
+	}, true);
 
-	function getClassInfo(/*String*/ className, /*Boolean*/ skipParamsLookup){
-		// summary:
-		//		Maps a widget name string like "dijit.form.Button" to the widget constructor itself,
-		//		and a list of that widget's parameters and their types
-		// className:
-		//		fully qualified name (like "dijit.form.Button")
-		// returns:
-		//		structure like
-		//			{
-		//				cls: dijit.Button,
-		//				params: { label: "string", disabled: "boolean"}
-		//			}
-
-		var c = instanceClasses[className];
-		if(!c){
-			// get pointer to widget class
-			var cls = d.getObject(className), params = null;
-			if(!cls){ return null; }		// class not defined [yet]
-			if(!skipParamsLookup){ // from fastpath, we don't need to lookup the attrs on the proto because they are explicit
-				params = getProtoInfo(cls.prototype, {})
-			}
-			c = { cls: cls, params: params };
-			
-		}else if(!skipParamsLookup && !c.params){
-			// if we're calling getClassInfo and have a cls proto, but no params info, scan that cls for params now
-			// and update the pointer in instanceClasses[className]. This happens when a widget appears in another
-			// widget's template which still uses dojoType, but an instance of the widget appears prior with a data-dojo-type,
-			// skipping this lookup the first time.
-			c.params = getProtoInfo(c.cls.prototype, {});
-		}
-		
-		return c;
-	}
+	// Map from widget name (ex: "dijit.form.Button") to constructor
+	var _ctorMap = {};
 
 	this._functionFromScript = function(script, attrData){
 		// summary:
@@ -139,13 +65,13 @@ dojo.parser = new function(){
 		var suffix = "";
 		var argsStr = (script.getAttribute(attrData + "args") || script.getAttribute("args"));
 		if(argsStr){
-			d.forEach(argsStr.split(/\s*,\s*/), function(part, idx){
+			darray.forEach(argsStr.split(/\s*,\s*/), function(part, idx){
 				preamble += "var "+part+" = arguments["+idx+"]; ";
 			});
 		}
 		var withStr = script.getAttribute("with");
 		if(withStr && withStr.length){
-			d.forEach(withStr.split(/\s*,\s*/), function(part){
+			darray.forEach(withStr.split(/\s*,\s*/), function(part){
 				preamble += "with("+part+"){";
 				suffix += "}";
 			});
@@ -153,7 +79,7 @@ dojo.parser = new function(){
 		return new Function(preamble+script.innerHTML+suffix);
 	};
 
-	this.instantiate = function(/* Array */nodes, /* Object? */mixin, /* Object? */args){
+	this.instantiate = /*====== dojo.parser.instantiate= ======*/function(nodes, mixin, args){
 		// summary:
 		//		Takes array of nodes, and turns them into class instances and
 		//		potentially calls a startup method to allow them to connect with
@@ -178,33 +104,31 @@ dojo.parser = new function(){
 		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 attrName = (args.scope || d._scopeName) + "Type",	// typically "dojoType"
-			attrData = "data-" + (args.scope || d._scopeName) + "-";	// typically "data-dojo-"
+		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");
+		});
 
-		d.forEach(nodes, function(obj){
+		darray.forEach(nodes, function(obj){
 			if(!obj){ return; }
 
-			// Get pointers to DOMNode, dojoType string, and clsInfo (metadata about the dojoType), etc.
-			var node, type, clsInfo, clazz, scripts, fastpath;
-			if(obj.node){
-				// new format of nodes[] array, object w/lots of properties pre-computed for me
-				node = obj.node;
-				type = obj.type;
-				fastpath = obj.fastpath;
-				clsInfo = obj.clsInfo || (type && getClassInfo(type, fastpath));
-				clazz = clsInfo && clsInfo.cls;
-				scripts = obj.scripts;
-			}else{
-				// old (backwards compatible) format of nodes[] array, simple array of DOMNodes. no fastpath/data-dojo-type support here.
-				node = obj;
-				type = attrName in mixin ? mixin[attrName] : node.getAttribute(attrName);
-				clsInfo = type && getClassInfo(type);
-				clazz = clsInfo && clsInfo.cls;
-				scripts = (clazz && (clazz._noScript || clazz.prototype._noScript) ? [] :
-							d.query("> script[type^='dojo/']", node));
-			}
-			if(!clsInfo){
+			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);
 			}
 
@@ -212,130 +136,221 @@ dojo.parser = new function(){
 			// settings inherited from ancestors ("dir" and "lang").
 			// Inherited setting may later be overridden by explicit settings on node itself.
 			var params = {};
-				
+
 			if(args.defaults){
 				// settings for the document itself (or whatever subtree is being parsed)
-				d._mixin(params, args.defaults);
+				dlang.mixin(params, args.defaults);
 			}
 			if(obj.inherited){
 				// settings from dir=rtl or lang=... on a node above this node
-				d._mixin(params, obj.inherited);
+				dlang.mixin(params, obj.inherited);
 			}
-			
-			// mix things found in data-dojo-props into the params
-			if(fastpath){
-				var extra = node.getAttribute(attrData + "props");
-				if(extra && extra.length){
-					try{
-						extra = d.fromJson.call(args.propsThis, "{" + extra + "}");
-						d._mixin(params, extra);
-					}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 + "'");
-					}
-				}
 
-				// For the benefit of _Templated, check if node has data-dojo-attach-point/data-dojo-attach-event
-				// and mix those in as though they were parameters
-				var attachPoint = node.getAttribute(attrData + "attach-point");
-				if(attachPoint){
-					params.dojoAttachPoint = attachPoint;
-				}
-				var attachEvent = node.getAttribute(attrData + "attach-event");
-				if(attachEvent){
-					params.dojoAttachEvent = attachEvent;
-				}
-				dojo.mixin(params, mixin);
+			// Get list of attributes explicitly listed in the markup
+			var attributes;
+			if(has("dom-attributes-explicit")){
+				// Standard path to get list of user specified attributes
+				attributes = node.attributes;
 			}else{
-				// FIXME: we need something like "deprecateOnce()" to throw dojo.deprecation for something.
-				// remove this logic in 2.0
-				// read parameters (ie, attributes) specified on DOMNode
-
-				var attributes = node.attributes;
-
-				// clsInfo.params lists expected params like {"checked": "boolean", "n": "number"}
-				for(var name in clsInfo.params){
-					var item = name in mixin ? { value:mixin[name], specified:true } : attributes.getNamedItem(name);
-					if(!item || (!item.specified && (!dojo.isIE || name.toLowerCase()!="value"))){ continue; }
-					var value = item.value;
-					// Deal with IE quirks for 'class' and 'style'
-					switch(name){
+				// Special path for IE, 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(/>.*$/, "");
+
+				attributes = darray.map(attrs.split(/\s+/), function(name){
+					var lcName = name.toLowerCase();
+					return {
+						name: name,
+						// 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
+					};
+				});
+			}
+
+			// 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;
+			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]){
+
+					// 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-id or jsId. TODO: drop jsId in 2.0
+					case "data-dojo-id":
+					case "jsId":
+						var 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;
+
+					// Special parameter handling needed for IE
 					case "class":
-						value = "className" in mixin ? mixin.className : node.className;
+						params["class"] = node.className;
 						break;
 					case "style":
-						value = "style" in mixin ? mixin.style : (node.style && node.style.cssText); // FIXME: Opera?
+						params["style"] = node.style && node.style.cssText;
+						break;
 					}
-					var _type = clsInfo.params[name];
-					if(typeof value == "string"){
-						params[name] = str2obj(value, _type);
+				}else{
+					// 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)));
+						name = map[lcName] || name;
+					}
+
+					// Set params[name] to value, doing type conversion
+					if(name in proto){
+						switch(typeof proto[name]){
+						case "string":
+							params[name] = value;
+							break;
+						case "number":
+							params[name] = value.length ? Number(value) : NaN;
+							break;
+						case "boolean":
+							// for checked/disabled value might be "" or "checked".	 interpret as true.
+							params[name] = value.toLowerCase() != "false";
+							break;
+						case "function":
+							if(value === "" || value.search(/[^\w\.]+/i) != -1){
+								// 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"
+								// or a single word function "return"
+								params[name] = dlang.getObject(value, false) || new Function(value);
+							}
+							break;
+						default:
+							var pVal = proto[name];
+							params[name] =
+								(pVal && "length" in pVal) ? (value ? value.split(/\s*,\s*/) : []) :	// array
+									(pVal instanceof Date) ?
+										(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);
+						}
 					}else{
 						params[name] = value;
 					}
 				}
 			}
 
+			// Mix things found in data-dojo-props into the params, overriding any direct settings
+			if(extra){
+				try{
+					extra = djson.fromJson.call(args.propsThis, "{" + extra + "}");
+					dlang.mixin(params, extra);
+				}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 + "'");
+				}
+			}
+
+			// 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));
+
 			// Process <script type="dojo/*"> script tags
 			// <script type="dojo/method" 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" event="foo"> tags are dojo.connected after instantiation
+			// <script type="dojo/connect" data-dojo-event="foo"> tags are dojo.connected after instantiation
+			// <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
-				calls = [];		// functions to call after instantiation
-
-			d.forEach(scripts, function(script){
-				node.removeChild(script);
-				// FIXME: drop event="" support in 2.0. use data-dojo-event="" instead
-				var event = (script.getAttribute(attrData + "event") || script.getAttribute("event")),
-					type = script.getAttribute("type"),
-					nf = d.parser._functionFromScript(script, attrData);
-				if(event){
-					if(type == "dojo/connect"){
-						connects.push({event: event, func: nf});
+				calls = [],		// functions to call after instantiation
+				watch = [],  //functions to watch after instantiation
+				on = []; //functions to on after instantiation
+
+			if(scripts){
+				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"),
+						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});
+						}else{
+							params[event] = nf;
+						}
+					}else if(type == "dojo/watch"){
+						watch.push({prop: prop, func: nf});
 					}else{
-						params[event] = nf;
+						calls.push(nf);
 					}
-				}else{
-					calls.push(nf);
 				}
-			});
+			}
 
-			var markupFactory = clazz.markupFactory || clazz.prototype && clazz.prototype.markupFactory;
 			// create the instance
-			var instance = markupFactory ? markupFactory(params, node, clazz) : new clazz(params, node);
+			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
-			// FIXME: in 2.0, drop jsId support. use data-dojo-id instead
-			var jsname = (node.getAttribute(attrData + "id") || node.getAttribute("jsId"));
 			if(jsname){
-				d.setObject(jsname, instance);
+				dlang.setObject(jsname, instance);
 			}
 
 			// process connections and startup functions
-			d.forEach(connects, function(connect){
-				d.connect(instance, connect.event, null, connect.func);
-			});
-			d.forEach(calls, function(func){
-				func.call(instance);
-			});
-		});
+			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){
-			// TODO: for 2.0, when old instantiate() API is desupported, store parent-child
-			// relationships in the nodes[] array so that no getParent() call is needed.
-			// Note that will  require a parse() call from ContentPane setting a param that the
-			// ContentPane is the parent widget (so that the parse doesn't call startup() on the
-			// ContentPane's children)
-			d.forEach(thelist, function(instance){
+			darray.forEach(thelist, function(instance){
 				if( !args.noStart && instance  &&
-					dojo.isFunction(instance.startup) &&
-					!instance._started &&
-					(!instance.getParent || !instance.getParent())
+					dlang.isFunction(instance.startup) &&
+					!instance._started
 				){
 					instance.startup();
 				}
@@ -344,7 +359,7 @@ dojo.parser = new function(){
 		return thelist;
 	};
 
-	this.parse = function(rootNode, args){
+	this.parse = /*====== dojo.parser.parse= ======*/ function(rootNode, args){
 		// summary:
 		//		Scan the DOM for class instances, and instantiate them.
 		//
@@ -355,7 +370,7 @@ dojo.parser = new function(){
 		//		like `dijit.form.Button`
 		//
 		//		Using `data-dojo-type`:
-		//		Attributes using can be mixed into the parameters used to instantitate the
+		//		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.
 		//
@@ -394,7 +409,7 @@ dojo.parser = new function(){
 		//				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._Templated`
+		//				Intended for use from the widgets-in-template feature of `dijit._WidgetsInTemplateMixin`
 		//
 		// example:
 		//		Parse all widgets on a page:
@@ -423,106 +438,144 @@ dojo.parser = new function(){
 		}else{
 			root = rootNode;
 		}
-		root = root ? dojo.byId(root) : dojo.body();
+		root = root ? dhtml.byId(root) : dwindow.body();
 		args = args || {};
 
-		var attrName = (args.scope || d._scopeName) + "Type",		// typically "dojoType"
-			attrData = "data-" + (args.scope || d._scopeName) + "-";	// typically "data-dojo-"
+		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"
 
-		function scan(parent, list){
-			// summary:
-			//		Parent is an Object representing a DOMNode, with or without a dojoType specified.
-			//		Scan parent's children looking for nodes with dojoType specified, storing in list[].
-			//		If parent has a dojoType, also collects <script type=dojo/*> children and stores in parent.scripts[].
-			// parent: Object
-			//		Object representing the parent node, like
-			//	|	{
-			//	|		node: DomNode,			// scan children of this node
-			//	|		inherited: {dir: "rtl"},	// dir/lang setting inherited from above node
-			//	|
-			//	|		// attributes only set if node has dojoType specified
-			//	|		scripts: [],			// empty array, put <script type=dojo/*> in here
-			//	|		clsInfo: { cls: dijit.form.Button, ...}
-			//	|	}
-			// list: DomNode[]
-			//		Output array of objects (same format as parent) representing nodes to be turned into widgets
-
-			// Effective dir and lang settings on parent node, either set directly or inherited from grandparent
-			var inherited = dojo.clone(parent.inherited);
-			dojo.forEach(["dir", "lang"], function(name){
-				// TODO: what if this is a widget and dir/lang are declared in data-dojo-props?
-				var val = parent.node.getAttribute(name);
-				if(val){
-					inherited[name] = val;
-				}
-			});
+		// List of all nodes on page w/dojoType specified
+		var list = [];
 
-			// if parent is a widget, then search for <script type=dojo/*> tags and put them in scripts[].
-			var scripts = parent.clsInfo && !parent.clsInfo.cls.prototype._noScript ? parent.scripts : null;
+		// 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);
+			}
+			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
+		};
 
-			// unless parent is a widget with the stopParser flag set, continue search for dojoType, recursively
-			var recurse = (!parent.clsInfo || !parent.clsInfo.cls.prototype.stopParser) || (args && args.template);
+		// For collecting <script type="dojo/..."> type nodes (when null, we don't need to collect)
+		var scripts;
 
-			// scan parent's children looking for dojoType and <script type=dojo/*>
-			for(var child = parent.node.firstChild; child; child = child.nextSibling){
-				if(child.nodeType == 1){
-					// FIXME: desupport dojoType in 2.0. use data-dojo-type instead
-					var type, html5 = recurse && child.getAttribute(attrData + "type");
-					if(html5){
-						type = html5;
-					}else{
-						// fallback to backward compatible mode, using dojoType. remove in 2.0
-						type = recurse && child.getAttribute(attrName);
-					}
-					
-					var fastpath = html5 == type;
-
-					if(type){
-						// if dojoType/data-dojo-type specified, add to output array of nodes to instantiate
-						var params = {
-							"type": type,
-							fastpath: fastpath,
-							clsInfo: getClassInfo(type, fastpath), // note: won't find classes declared via dojo.Declaration
-							node: child,
-							scripts: [], // <script> nodes that are parent's children
-							inherited: inherited // dir & lang attributes inherited from parent
-						};
-						list.push(params);
-
-						// Recurse, collecting <script type="dojo/..."> children, and also looking for
-						// descendant nodes with dojoType specified (unless the widget has the stopParser flag),
-						scan(params, list);
-					}else if(scripts && child.nodeName.toLowerCase() == "script"){
-						// if <script type="dojo/...">, save in scripts[]
-						type = child.getAttribute("type");
-						if (type && /^dojo\/\w/i.test(type)) {
-							scripts.push(child);
-						}
-					}else if(recurse){
-						// Recurse, looking for grandchild nodes with dojoType specified
-						scan({
-							node: child,
-							inherited: inherited
-						}, list);
+		// 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];
 					}
 				}
 			}
+			return parent.inherited;
 		}
 
-		// Ignore bogus entries in inherited hash like {dir: ""}
-		var inherited = {};
-		if(args && args.inherited){
-			for(var key in args.inherited){
-				if(args.inherited[key]){ inherited[key] = args.inherited[key]; }
+		// 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;
+				scripts = parent.scripts;
+				scriptsOnly = false;
+				parent = parent.parent;
+				continue;
 			}
-		}
 
-		// Make list of all nodes on page w/dojoType specified
-		var list = [];
-		scan({
-			node: root,
-			inherited: inherited
-		}, list);
+			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){
+				node = node.nextSibling;
+				continue;
+			}
+
+			// Check for data-dojo-type attribute, fallback to backward compatible dojoType
+			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;
+			}
+
+			// 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
+			};
+
+			// 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
+				});
+			}
+
+			// 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;
+
+		}
 
 		// go build the object instances
 		var mixin = args && args.template ? {template: true} : null;
@@ -530,23 +583,12 @@ dojo.parser = new function(){
 	};
 }();
 
+
 //Register the parser callback. It should be the first callback
 //after the a11y test.
-
-(function(){
-	var parseRunner = function(){
-		if(dojo.config.parseOnLoad){
-			dojo.parser.parse();
-		}
-	};
-
-	// FIXME: need to clobber cross-dependency!!
-	if(dojo.getObject("dijit.wai.onload") === dojo._loaders[0]){
-		dojo._loaders.splice(1, 0, parseRunner);
-	}else{
-		dojo._loaders.unshift(parseRunner);
-	}
-})();
+if(dojo.config.parseOnLoad){
+	dojo.ready(100, dojo.parser, "parse");
+}
 
 return dojo.parser;
 });
diff --git a/dojo/query.js b/dojo/query.js
new file mode 100644
index 0000000..4685e81
--- /dev/null
+++ b/dojo/query.js
@@ -0,0 +1,713 @@
+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";
+
+	has.add("array-extensible", function(){
+		// test to see if we can extend an array (not supported in old IE)
+		return lang.delegate([], {length: 1}).length == 1 && !has("bug-for-in-skips-shadowed");
+	});
+	
+	var ap = Array.prototype, aps = ap.slice, apc = ap.concat, forEach = array.forEach;
+
+	var tnl = function(/*Array*/ a, /*dojo.NodeList?*/ parent, /*Function?*/ NodeListCtor){
+		// summary:
+		//		decorate an array to make it look like a `dojo.NodeList`.
+		// a:
+		//		Array of nodes to decorate.
+		// parent:
+		//		An optional parent NodeList that generated the current
+		//		list of nodes. Used to call _stash() so the parent NodeList
+		//		can be accessed via end() later.
+		// 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.
+		var nodeList = new (NodeListCtor || this._NodeListCtor || nl)(a);
+		return parent ? nodeList._stash(parent) : nodeList;
+	};
+
+	var loopBody = function(f, a, o){
+		a = [0].concat(aps.call(a, 0));
+		o = o || dojo.global;
+		return function(node){
+			a[0] = node;
+			return f.apply(o, a);
+		};
+	};
+
+	// adapters
+
+	var adaptAsForEach = function(f, o){
+		// summary:
+		//		adapts a single node function to be used in the forEach-type
+		//		actions. The initial object is returned from the specialized
+		//		function.
+		// f: Function
+		//		a function to adapt
+		// o: Object?
+		//		an optional context for f
+		return function(){
+			this.forEach(loopBody(f, arguments, o));
+			return this;	// Object
+		};
+	};
+
+	var adaptAsMap = function(f, o){
+		// summary:
+		//		adapts a single node function to be used in the map-type
+		//		actions. The return is a new array of values, as via `dojo.map`
+		// f: Function
+		//		a function to adapt
+		// o: Object?
+		//		an optional context for f
+		return function(){
+			return this.map(loopBody(f, arguments, o));
+		};
+	};
+
+	var adaptAsFilter = function(f, o){
+		// summary:
+		//		adapts a single node function to be used in the filter-type actions
+		// f: Function
+		//		a function to adapt
+		// o: Object?
+		//		an optional context for f
+		return function(){
+			return this.filter(loopBody(f, arguments, o));
+		};
+	};
+
+	var adaptWithCondition = function(f, g, o){
+		// summary:
+		//		adapts a single node function to be used in the map-type
+		//		actions, behaves like forEach() or map() depending on arguments
+		// f: Function
+		//		a function to adapt
+		// g: Function
+		//		a condition function, if true runs as map(), otherwise runs as forEach()
+		// o: Object?
+		//		an optional context for f and g
+		return function(){
+			var a = arguments, body = loopBody(f, a, o);
+			if(g.call(o || dojo.global, a)){
+				return this.map(body);	// self
+			}
+			this.forEach(body);
+			return this;	// self
+		};
+	};
+
+	var NodeList = function(array){
+		// summary:
+		//		dojo.NodeList is an of 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
+		//		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
+		//		full power of Dojo available for DOM manipulation tasks in a
+		//		simple, chainable way.
+		// example:
+		//		create a node list from a node
+		//		|	new dojo.NodeList(dojo.byId("foo"));
+		// example:
+		//		get a NodeList from a CSS query and iterate on it
+		//		|	var l = dojo.query(".thinger");
+		//		|	l.forEach(function(node, index, nodeList){
+		//		|		console.log(index, node.innerHTML);
+		//		|	});
+		// example:
+		//		use native and Dojo-provided array methods to manipulate a
+		//		NodeList without needing to use dojo.* functions explicitly:
+		//		|	var l = dojo.query(".thinger");
+		//		|	// since NodeLists are real arrays, they have a length
+		//		|	// property that is both readable and writable and
+		//		|	// push/pop/shift/unshift methods
+		//		|	console.log(l.length);
+		//		|	l.push(dojo.create("span"));
+		//		|
+		//		|	// dojo's normalized array methods work too:
+		//		|	console.log( l.indexOf(dojo.byId("foo")) );
+		//		|	// ...including the special "function as string" shorthand
+		//		|	console.log( l.every("item.nodeType == 1") );
+		//		|
+		//		|	// NodeLists can be [..] indexed, or you can use the at()
+		//		|	// function to get specific items wrapped in a new NodeList:
+		//		|	var node = l[3]; // the 4th element
+		//		|	var newList = l.at(1, 3); // the 2nd and 4th elements
+		// example:
+		//		the style functions you expect are all there too:
+		//		|	// style() as a getter...
+		//		|	var borders = dojo.query(".thinger").style("border");
+		//		|	// ...and as a setter:
+		//		|	dojo.query(".thinger").style("border", "1px solid black");
+		//		|	// class manipulation
+		//		|	dojo.query("li:nth-child(even)").addClass("even");
+		//		|	// 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:
+		//		|	// remove all of the elements in the list from their
+		//		|	// parents (akin to "deleting" them from the document)
+		//		|	dojo.query(".thinger").orphan();
+		//		|	// place all elements in the list at the front of #foo
+		//		|	dojo.query(".thinger").place("foo", "first");
+		// example:
+		//		Event handling couldn't be easier. `dojo.connect` is mapped in,
+		//		and shortcut handlers are provided for most DOM events:
+		//		|	// like dojo.connect(), but with implicit scope
+		//		|	dojo.query("li").connect("onclick", console, "log");
+		//		|
+		//		|	// many common event handlers are already available directly:
+		//		|	dojo.query("li").onclick(console, "log");
+		//		|	var toggleHovered = dojo.hitch(dojo, "toggleClass", "hovered");
+		//		|	dojo.query("p")
+		//		|		.onmouseenter(toggleHovered)
+		//		|		.onmouseleave(toggleHovered);
+		// example:
+		//		chainability is a key advantage of NodeLists:
+		//		|	dojo.query(".thinger")
+		//		|		.onclick(function(e){ /* ... */ })
+		//		|		.at(1, 3, 8) // get a subset
+		//		|			.style("padding", "5px")
+		//		|			.forEach(console.log);
+		var isNew = this instanceof nl && has("array-extensible");
+		if(typeof array == "number"){
+			array = Array(array);
+		}
+		var nodeArray = (array && "length" in array) ? array : arguments;
+		if(isNew || !nodeArray.sort){
+			// make sure it's a real array before we pass it on to be wrapped 
+			var target = isNew ? this : [],
+				l = target.length = nodeArray.length;
+			for(var i = 0; i < l; i++){
+				target[i] = nodeArray[i];
+			}
+			if(isNew){
+				// called with new operator, this means we are going to use this instance and push
+				// the nodes on to it. This is usually much faster since the NodeList properties
+				//	don't need to be copied (unless the list of nodes is extremely large).
+				return target;
+			}
+			nodeArray = target;
+		}
+		// called without new operator, use a real array and copy prototype properties,
+		// this is slower and exists for back-compat. Should be removed in 2.0.
+		lang._mixin(nodeArray, nlp);
+		nodeArray._NodeListCtor = function(array){
+			// call without new operator to preserve back-compat behavior
+			return nl(array);
+		};
+		return nodeArray;
+	};
+	
+	var nl = NodeList, nlp = nl.prototype = 
+		has("array-extensible") ? [] : {};// extend an array if it is extensible
+
+	// expose adapters and the wrapper as private functions
+
+	nl._wrap = nlp._wrap = tnl;
+	nl._adaptAsMap = adaptAsMap;
+	nl._adaptAsForEach = adaptAsForEach;
+	nl._adaptAsFilter  = adaptAsFilter;
+	nl._adaptWithCondition = adaptWithCondition;
+
+	// mass assignment
+
+	// add array redirectors
+	forEach(["slice", "splice"], function(name){
+		var f = ap[name];
+		//Use a copy of the this array via this.slice() to allow .end() to work right in the splice case.
+		// CANNOT apply ._stash()/end() to splice since it currently modifies
+		// the existing this array -- it would break backward compatibility if we copy the array before
+		// the splice so that we can use .end(). So only doing the stash option to this._wrap for slice.
+		nlp[name] = function(){ return this._wrap(f.apply(this, arguments), name == "slice" ? this : null); };
+	});
+	// concat should be here but some browsers with native NodeList have problems with it
+
+	// add array.js redirectors
+	forEach(["indexOf", "lastIndexOf", "every", "some"], function(name){
+		var f = array[name];
+		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,
+		_NodeListCtor: nl,
+		toString: function(){
+			// Array.prototype.toString can't be applied to objects, so we use join
+			return this.join(",");
+		},
+		_stash: function(parent){
+			// summary:
+			//		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, {
+			//	|		third: function(){
+			//	|			var newNodeList = dojo.NodeList(this[2]);
+			//	|			return newNodeList._stash(this);
+			//	|		}
+			//	|	});
+			//	|	// then see how _stash applies a sub-list, to be .end()'ed out of
+			//	|	dojo.query(".foo")
+			//	|		.third()
+			//	|			.addClass("thirdFoo")
+			//	|		.end()
+			//	|		// access to the orig .foo list
+			//	|		.removeClass("foo")
+			//	|
+			//
+			this._parent = parent;
+			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
+			//		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.
+			//		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){
+				return on(node, eventName, listener); // TODO: apply to the NodeList so the same selector engine is used for matches
+			});
+			handles.remove = function(){
+				for(var i = 0; i < handles.length; i++){
+					handles[i].remove();
+				}
+			};
+			return handles;
+		},
+
+		end: function(){
+			// summary:
+			//		Ends use of the current `dojo.NodeList` by returning the previous dojo.NodeList
+			//		that generated the current dojo.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.
+			// example:
+			//	|	dojo.query("a")
+			//	|		.filter(".disabled")
+			//	|			// operate on the anchors that only have a disabled class
+			//	|			.style("color", "grey")
+			//	|		.end()
+			//	|		// jump back to the list of anchors
+			//	|		.style(...)
+			//
+			if(this._parent){
+				return this._parent;
+			}else{
+				//Just return empty list.
+				return new this._NodeListCtor(0);
+			}
+		},
+
+		// http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array#Methods
+
+		// FIXME: handle return values for #3244
+		//		http://trac.dojotoolkit.org/ticket/3244
+
+		// FIXME:
+		//		need to wrap or implement:
+		//			join (perhaps w/ innerHTML/outerHTML overload for toString() of items?)
+		//			reduce
+		//			reduceRight
+
+		/*=====
+		slice: function(begin, end){
+			// summary:
+			//		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]
+			// begin: Integer
+			//		Can be a positive or negative integer, with positive
+			//		integers noting the offset to begin at, and negative
+			//		integers denoting an offset from the end (i.e., to the left
+			//		of the end)
+			// end: Integer?
+			//		Optional parameter to describe what position relative to
+			//		the NodeList's zero index to end the slice at. Like begin,
+			//		can be positive or negative.
+			return this._wrap(a.slice.apply(this, arguments));
+		},
+
+		splice: function(index, howmany, item){
+			// summary:
+			//		Returns a new NodeList, manipulating this NodeList based on
+			//		the arguments passed, potentially splicing in new elements
+			//		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]
+			//		For backwards compatibility, calling .end() on the spliced NodeList
+			//		does not return the original NodeList -- splice alters the NodeList in place.
+			// index: Integer
+			//		begin can be a positive or negative integer, with positive
+			//		integers noting the offset to begin at, and negative
+			//		integers denoting an offset from the end (i.e., to the left
+			//		of the end)
+			// howmany: Integer?
+			//		Optional parameter to describe what position relative to
+			//		the NodeList's zero index to end the slice at. Like begin,
+			//		can be positive or negative.
+			// 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));
+		},
+
+		indexOf: function(value, fromIndex){
+			// summary:
+			//		see dojo.indexOf(). The primary difference is that the acted-on
+			//		array is implicitly this NodeList
+			// value: Object:
+			//		The value to search for.
+			// 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]
+			// returns:
+			//		Positive Integer or 0 for a match, -1 of not found.
+			return d.indexOf(this, value, fromIndex); // Integer
+		},
+
+		lastIndexOf: function(value, fromIndex){
+			// summary:
+			//		see dojo.lastIndexOf(). The primary difference is that the
+			//		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]
+			// value: Object
+			//		The value to search for.
+			// fromIndex: Integer?
+			//		The location to start searching from. Optional. Defaults to 0.
+			// returns:
+			//		Positive Integer or 0 for a match, -1 of not found.
+			return d.lastIndexOf(this, value, fromIndex); // Integer
+		},
+
+		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].
+			//		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
+			return d.every(this, callback, thisObject); // Boolean
+		},
+
+		some: function(callback, thisObject){
+			// summary:
+			//		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
+			return d.some(this, callback, thisObject); // Boolean
+		},
+		=====*/
+
+		concat: function(item){
+			// summary:
+			//		Returns a new NodeList comprised of items in this NodeList
+			//		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]
+			// 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 :-(
+
+			// 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),
+				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 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
+		},
+
+		forEach: function(callback, thisObj){
+			// summary:
+			//		see `dojo.forEach()`. The primary difference is that the acted-on
+			//		array is implicitly this NodeList. If you want the option to break out
+			//		of the forEach loop, use every() or some() instead.
+			forEach(this, callback, thisObj);
+			// non-standard return to allow easier chaining
+			return this; // dojo.NodeList
+		},
+		filter: function(/*String|Function*/ filter){
+			// summary:
+			//		"masks" the built-in javascript filter() method (supported
+			//		in Dojo via `dojo.filter`) to support passing a simple
+			//		string filter in addition to supporting filtering function
+			//		objects.
+			// filter:
+			//		If a string, a CSS rule like ".thinger" or "div > span".
+			// example:
+			//		"regular" JS filter syntax as exposed in dojo.filter:
+			//		|	dojo.query("*").filter(function(item){
+			//		|		// highlight every paragraph
+			//		|		return (item.nodeName == "p");
+			//		|	}).style("backgroundColor", "yellow");
+			// example:
+			//		the same filtering using a CSS selector
+			//		|	dojo.query("*").filter("p").styles("backgroundColor", "yellow");
+
+			var a = arguments, items = this, start = 0;
+			if(typeof filter == "string"){ // inline'd type check
+				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
+				}
+				// 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
+		},
+		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
+			//		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});
+			var c = lang.isFunction(declaredClass) ? declaredClass : lang.getObject(declaredClass);
+			properties = properties || {};
+			return this.forEach(function(node){
+				new c(properties, node);
+			});	// dojo.NodeList
+		},
+		at: function(/*===== index =====*/){
+			// summary:
+			//		Returns a new NodeList comprised of items in this NodeList
+			//		at the given index or indices.
+			//
+			// index: Integer...
+			//		One or more 0-based indices of items in the current
+			//		NodeList. A negative index will start at the end of the
+			//		list and go backwards.
+			//
+			// example:
+			//	Shorten the list to the first, second, and third elements
+			//	|	dojo.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);
+			//
+			// 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){
+			//	|		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
+		}
+	});
+
+
+/*===== 
+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([]);
+			}
+		}
+		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){
+		// 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 dojo.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);
+		};
+	}
+	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;
+});
diff --git a/dojo/ready.js b/dojo/ready.js
new file mode 100644
index 0000000..3e1bd38
--- /dev/null
+++ b/dojo/ready.js
@@ -0,0 +1,138 @@
+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 = [],
+
+		// prevent recursion in onLoad
+		onLoadRecursiveGuard = 0,
+
+		handleDomReady = function(){
+			isDomReady = 1;
+			dojo._postLoad = dojo.config.afterOnLoad = true;
+			if(loadQ.length){
+				requestCompleteSignal(onLoad);
+			}
+		},
+
+		// run the next function queued with dojo.ready
+		onLoad = function(){
+			if(isDomReady && !onLoadRecursiveGuard && loadQ.length){
+				//guard against recursions into this function
+				onLoadRecursiveGuard = 1;
+				var f = loadQ.shift();
+					try{
+						f();
+					}
+						// 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);
+		};
+	}
+
+	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.
+		// priority: Integer?
+		//		The order in which to exec this callback relative to other callbacks, defaults to 1000
+		// context: Object?|Function
+		//		The context in which to run execute callback, or a callback if not using context
+		// callback: Function?
+		//		The function to execute.
+		//
+		// example:
+		//	Simple DOM and Modules ready syntax
+		//	|	dojo.ready(function(){ alert("Dom ready!"); });
+		//
+		// example:
+		//	Using a priority
+		//	|	dojo.ready(2, function(){ alert("low priority ready!"); })
+		//
+		// example:
+		//	Using context
+		//	|	dojo.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");
+
+		var hitchArgs = lang._toArray(arguments);
+		if(typeof priority != "number"){
+			callback = context;
+			context = priority;
+			priority = 1000;
+		}else{
+			hitchArgs.shift();
+		}
+		callback = callback ?
+			lang.hitch.apply(dojo, hitchArgs) :
+			function(){
+				context();
+			};
+		callback.priority = priority;
+		for(var i = 0; i < loadQ.length && priority >= loadQ[i].priority; i++){}
+		loadQ.splice(i, 0, callback);
+		requestCompleteSignal();
+	};
+
+	has.add("dojo-config-addOnLoad", 1);
+	if(has("dojo-config-addOnLoad")){
+		var dca = dojo.config.addOnLoad;
+		if(dca){
+			ready[(lang.isArray(dca) ? "apply" : "call")](dojo, dca);
+		}
+	}
+
+	if(has("dojo-sync-loader") && dojo.config.parseOnLoad && !dojo.isAsync){
+		ready(99, function(){
+			if(!dojo.parser){
+				dojo.deprecated("Add explicit require(['dojo/parser']);", "", "2.0");
+				require(["dojo/parser"]);
+			}
+		});
+	}
+
+	if(has("host-browser")){
+		domReady(handleDomReady);
+	}else{
+		handleDomReady();
+	}
+
+	return ready;
+});
diff --git a/dojo/regexp.js b/dojo/regexp.js
index 6159649..ba5b7b8 100644
--- a/dojo/regexp.js
+++ b/dojo/regexp.js
@@ -1,5 +1,10 @@
-define("dojo/regexp", ["dojo"], function(dojo) {
-dojo.getObject("regexp", true, dojo);
+define(["./_base/kernel", "./_base/lang"], function(dojo, lang) {
+	// module:
+	//		dojo/regexp
+	// summary:
+	//		TODOC
+
+lang.getObject("regexp", true, dojo);
 
 /*=====
 dojo.regexp = {
diff --git a/dojo/require.js b/dojo/require.js
new file mode 100644
index 0000000..3f02bca
--- /dev/null
+++ b/dojo/require.js
@@ -0,0 +1,7 @@
+define(["./_base/loader"], function(loader){
+	return {
+		dynamic:0,
+		normalize:function(id){return id;},
+		load:loader.require
+	};
+});
diff --git a/dojo/resources/dnd.css b/dojo/resources/dnd.css
index b7f1651..fb06118 100644
--- a/dojo/resources/dnd.css
+++ b/dojo/resources/dnd.css
@@ -1,6 +1,6 @@
 /* DnD avatar-specific settings */
 .dojoDndAvatar			{font-size: 75%; color: black;}
-.dojoDndAvatarHeader td	{padding-left: 20px; padding-right: 4px;}
+.dojoDndAvatarHeader td	{padding-left: 20px; padding-right: 4px;  height: 16px;}
 .dojoDndAvatarHeader	{background: #ccc;}
 .dojoDndAvatarItem		{background: #eee;}
 .dojoDndMove .dojoDndAvatarHeader	{background-image: url(images/dndNoMove.png); background-repeat: no-repeat;}
diff --git a/dojo/robot.js b/dojo/robot.js
index c442ac5..3fb9ea0 100644
--- a/dojo/robot.js
+++ b/dojo/robot.js
@@ -1,8 +1,7 @@
-define("dojo/robot", ["dojo", "doh/robot", "dojo/window"], function(dojo) {
+define(["dojo", "doh/_browserRunner", "doh/robot", "dojo/window"], function(dojo, doh) {
 
 dojo.experimental("dojo.robot");
 
-(function(){
 // users who use doh+dojo get the added convenience of dojo.mouseMoveAt,
 // instead of computing the absolute coordinates of their elements themselves
 dojo.mixin(doh.robot,{
@@ -18,15 +17,14 @@ dojo.mixin(doh.robot,{
 	_scrollIntoView: function(/*Node*/ n){
 		// scrolls the passed node into view, scrolling all ancester frames/windows as well.
 		// Assumes parent iframes can be made fully visible given the current browser window size
-		var d = dojo,
-			dr = doh.robot,
+		var dr = doh.robot,
 			p = null;
-		d.forEach(dr._getWindowChain(n), function(w){
-			d.withGlobal(w, function(){
+		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 = d.position(n, false),
-					b = d._getPadBorderExtents(n),
+				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
@@ -43,7 +41,7 @@ dojo.mixin(doh.robot,{
 				// 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 = d.position(n, false);
+				p2 = dojo.position(n, false);
 				if(!oldp){
 					p = p2;
 				}else{
@@ -62,20 +60,20 @@ dojo.mixin(doh.robot,{
 		// Returns the dojo.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 d = dojo, p = null, M = Math.max, m = Math.min;
+		var p = null, M = Math.max, m = Math.min;
 		// p: the returned position of the node
-		d.forEach(doh.robot._getWindowChain(n), function(w){
-			d.withGlobal(w, function(){
+		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 = d.position(n, false), b = d._getPadBorderExtents(n);
+				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;
-					d.withGlobal(n.contentWindow,function(){
+					dojo.withGlobal(n.contentWindow,function(){
 						view=dojo.window.getBox();
 					});
 					p2.r = p2.x+view.w;
@@ -170,7 +168,5 @@ dojo.mixin(doh.robot,{
 	}
 });
 
-})();
-
 return doh.robot;
 });
diff --git a/dojo/robotx.js b/dojo/robotx.js
index 649e061..9f519c8 100644
--- a/dojo/robotx.js
+++ b/dojo/robotx.js
@@ -1,4 +1,4 @@
-define("dojo/robotx", ["dojo", "dojo/robot"], function(dojo) {
+define(["dojo", "dojo/robot"], function(dojo) {
 
 dojo.experimental("dojo.robotx");
 
@@ -6,8 +6,6 @@ dojo.experimental("dojo.robotx");
 // to use: set robotURL in djConfig to the URL you want to load
 // dojo.require this file
 
-(function(){
-
 var iframe = null;
 
 var groupStarted=dojo.connect(doh, '_groupStarted', function(){
@@ -38,14 +36,16 @@ var attachIframe = function(){
 var robotReady=false;
 var robotFrame=null;
 var _run=doh.robot._run;
-doh.robot._run=function(frame){
+doh.robot._run = function(frame){
 	// Called from robot when the robot completed its initialization.
 	robotReady = true;
 	robotFrame = frame;
-	doh.robot._run=_run;
+	doh.robot._run = _run;
 	// If initRobot was already called, then attach the iframe.
-	if(iframe.src){ attachIframe(); }
-}
+	if(iframe.src){
+		attachIframe();
+	}
+};
 
 var onIframeLoad=function(){
 	// initial load handler: update the document and start the tests
@@ -95,18 +95,17 @@ if(iframe['attachEvent'] !== undefined){
 	dojo.connect(iframe, 'onload', iframeLoad);
 }
 
-
-
-
 dojo.mixin(doh.robot,{
 	_updateDocument: function(){
 		dojo.setContext(iframe.contentWindow, iframe.contentWindow.document);
 		var win = dojo.global;
-		if(win["dojo"]){
+		if(win.dojo){
 			// allow the tests to subscribe to topics published by the iframe
-			dojo._topics = win.dojo._topics;
+			dojo.publish = win.dojo.publish;
+			dojo.subscribe = win.dojo.subscribe;
+			dojo.connectPublisher = win.dojo.connectPublisher;  
 		}
-		 
+
 	},
 
 	initRobot: function(/*String*/ url){
@@ -121,7 +120,7 @@ dojo.mixin(doh.robot,{
 		// see above note about race conditions
 		if(robotReady){
 			attachIframe();
-			
+
 		}
 	},
 
@@ -157,7 +156,6 @@ dojo.mixin(doh.robot,{
 	}
 
 });
-})();
 
 return doh.robot;
 });
diff --git a/dojo/rpc/JsonService.js b/dojo/rpc/JsonService.js
index 19c244f..c37adf8 100644
--- a/dojo/rpc/JsonService.js
+++ b/dojo/rpc/JsonService.js
@@ -1,4 +1,9 @@
-define("dojo/rpc/JsonService", ["dojo", "dojo/rpc/RpcService"], function(dojo) {
+define(["../main", "./RpcService"], function(dojo) {
+	// module:
+	//		dojo/rpc/JsonService
+	// summary:
+	//		TODOC
+
 
 dojo.declare("dojo.rpc.JsonService", dojo.rpc.RpcService, {
 		bustCache: false,
@@ -48,10 +53,9 @@ dojo.declare("dojo.rpc.JsonService", dojo.rpc.RpcService, {
 			//		The name of the method we are creating the requst for
 			//	params: array
 			//		The array of parameters for this request;
-			
+
 			var req = { "params": params, "method": method, "id": ++this.lastSubmissionId };
-			var data = dojo.toJson(req);
-			return data;
+			return dojo.toJson(req);
 		},
 
 		parseResults: function(/*anything*/obj){
diff --git a/dojo/rpc/JsonpService.js b/dojo/rpc/JsonpService.js
index 839f333..eb2ff63 100644
--- a/dojo/rpc/JsonpService.js
+++ b/dojo/rpc/JsonpService.js
@@ -1,4 +1,9 @@
-define("dojo/rpc/JsonpService", ["dojo", "dojo/rpc/RpcService", "dojo/io/script"], function(dojo) {
+define(["../main", "./RpcService", "../io/script"], function(dojo) {
+	// module:
+	//		dojo/rpc/JsonpService
+	// summary:
+	//		TODOC
+
 
 dojo.declare("dojo.rpc.JsonpService", dojo.rpc.RpcService, {
 	// summary:
diff --git a/dojo/rpc/RpcService.js b/dojo/rpc/RpcService.js
index 847c8d5..26cb1ee 100644
--- a/dojo/rpc/RpcService.js
+++ b/dojo/rpc/RpcService.js
@@ -1,4 +1,9 @@
-define("dojo/rpc/RpcService", ["dojo"], function(dojo) {
+define(["../main", "../_base/url"], function(dojo) {
+	// module:
+	//		dojo/rpc/RpcService
+	// summary:
+	//		TODOC
+
 
 dojo.declare("dojo.rpc.RpcService", null, {
 	constructor: function(args){
@@ -30,7 +35,7 @@ dojo.declare("dojo.rpc.RpcService", null, {
 					handleAs: "json-comment-optional",
 					sync: true
 				});
-				
+
 				def.addCallback(this, "processSmd");
 				def.addErrback(function() {
 					throw new Error("Unable to load SMD from " + args);
@@ -65,10 +70,10 @@ dojo.declare("dojo.rpc.RpcService", null, {
 	serviceUrl: "",
 
 	parseResults: function(obj){
-		// summary
-		// 		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
+		// summary:
+		//		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
 		//		Object that is the return results from an rpc request
 		return obj;
@@ -86,11 +91,11 @@ dojo.declare("dojo.rpc.RpcService", null, {
 
 	resultCallback: function(/* dojo.Deferred */ deferredRequestHandler){
 		// summary:
-		// 		create callback that calls the Deferred's callback method
+		//		create callback that calls the Deferred's callback method
 		//	deferredRequestHandler: Deferred
 		//		The deferred object handling a request.
 
-		var tf = dojo.hitch(this,
+		return dojo.hitch(this,
 			function(obj){
 				if(obj.error!=null){
 					var err;
@@ -109,12 +114,11 @@ dojo.declare("dojo.rpc.RpcService", null, {
 				}
 			}
 		);
-		return tf;
 	},
 
 	generateMethod: function(/*string*/ method, /*array*/ parameters, /*string*/ url){
 		// summary:
-		// 		generate the local bind methods for the remote object
+		//		generate the local bind methods for the remote object
 		//	method: string
 		//		The name of the method we are generating
 		//	parameters: array
@@ -142,8 +146,8 @@ dojo.declare("dojo.rpc.RpcService", null, {
 
 	processSmd: function(object){
 		// summary:
-		// 		callback method for reciept of a smd object.  Parse the smd
-		// 		and generate functions based on the description
+		//		callback method for reciept of a smd object.  Parse the smd
+		//		and generate functions based on the description
 		//	object:
 		//		smd object defining this service.
 
diff --git a/dojo/selector/_loader.js b/dojo/selector/_loader.js
new file mode 100644
index 0000000..e5c9094
--- /dev/null
+++ b/dojo/selector/_loader.js
@@ -0,0 +1,45 @@
+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);
+has.add("dom-qsa3", function(){
+			// test to see if we have a reasonable native selector engine available
+			try{
+				testDiv.innerHTML = "<p class='TEST'></p>"; // test kind of from sizzle
+				// Safari can't handle uppercase or unicode characters when
+				// in quirks mode, IE8 can't handle pseudos like :empty
+				return testDiv.querySelectorAll(".TEST:empty").length == 1;
+			}catch(e){}
+		});
+var fullEngine;
+var acme = "./acme", lite = "./lite";
+return {
+	load: function(id, parentRequire, loaded, config){
+		var req = require;
+		// here we implement the default logic for choosing a selector engine
+		id = id == "default" ? has("config-selectorEngine") || "css3" : id;
+		id = id == "css2" || id == "lite" ? lite :
+				id == "css2.1" ? has("dom-qsa2.1") ? lite : acme :
+				id == "css3" ? has("dom-qsa3") ? lite : acme :
+				id == "acme" ? acme : (req = parentRequire) && id;
+		if(id.charAt(id.length-1) == '?'){
+			id = id.substring(0,id.length - 1);
+			var optionalLoad = true;
+		}
+		// the query engine is optional, only load it if a native one is not available or existing one has not been loaded
+		if(optionalLoad && (has("dom-compliant-qsa") || fullEngine)){
+			return loaded(fullEngine);
+		}
+		// load the referenced selector engine
+		req([id], function(engine){
+			if(id != "./lite"){
+				fullEngine = engine;
+			}
+			loaded(engine);
+		});
+	}
+};
+});
diff --git a/dojo/selector/acme.js b/dojo/selector/acme.js
new file mode 100644
index 0000000..d90dc72
--- /dev/null
+++ b/dojo/selector/acme.js
@@ -0,0 +1,1480 @@
+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
+
+/*
+	acme architectural overview:
+
+		acme is a relatively full-featured CSS3 query library. It is
+		designed to take any valid CSS3 selector and return the nodes matching
+		the selector. To do this quickly, it processes queries in several
+		steps, applying caching where profitable.
+
+		The steps (roughly in reverse order of the way they appear in the code):
+			1.) check to see if we already have a "query dispatcher"
+				- if so, use that with the given parameterization. Skip to step 4.
+			2.) attempt to determine which branch to dispatch the query to:
+				- JS (optimized DOM iteration)
+				- native (FF3.1+, Safari 3.1+, IE 8+)
+			3.) tokenize and convert to executable "query dispatcher"
+				- this is where the lion's share of the complexity in the
+					system lies. In the DOM version, the query dispatcher is
+					assembled as a chain of "yes/no" test functions pertaining to
+					a section of a simple query statement (".blah:nth-child(odd)"
+					but not "div div", which is 2 simple statements). Individual
+					statement dispatchers are cached (to prevent re-definition)
+					as are entire dispatch chains (to make re-execution of the
+					same query fast)
+			4.) the resulting query dispatcher is called in the passed scope
+					(by default the top-level document)
+				- for DOM queries, this results in a recursive, top-down
+					evaluation of nodes based on each simple query section
+				- for native implementations, this may mean working around spec
+					bugs. So be it.
+			5.) matched nodes are pruned to ensure they are unique (if necessary)
+*/
+
+
+	////////////////////////////////////////////////////////////////////////
+	// Toolkit aliases
+	////////////////////////////////////////////////////////////////////////
+
+	// 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; };
+	// NOTE(alex): the spec is idiotic. CSS queries should ALWAYS be case-sensitive, but nooooooo
+	var cssCaseBug = ((dojo.isWebKit||dojo.isMozilla) && ((getDoc().compatMode) == "BackCompat"));
+
+	////////////////////////////////////////////////////////////////////////
+	// Global utilities
+	////////////////////////////////////////////////////////////////////////
+
+
+	var specials = ">~+";
+
+	// global thunk to determine whether we should treat the current query as
+	// case sensitive or not. This switch is flipped by the query evaluator
+	// based on the document passed as the context to search.
+	var caseSensitive = false;
+
+	// how high?
+	var yesman = function(){ return true; };
+
+	////////////////////////////////////////////////////////////////////////
+	// Tokenizer
+	////////////////////////////////////////////////////////////////////////
+
+	var getQueryParts = function(query){
+		//	summary:
+		//		state machine for query tokenization
+		//	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,
+		//		the same query run multiple times or under different root nodes
+		//		does not re-parse the selector expression but instead uses the
+		//		cached data structure. The state machine implemented here
+		//		terminates on the last " " (space) character and returns an
+		//		ordered array of query component structures (or "parts"). Each
+		//		part represents an operator or a simple CSS filtering
+		//		expression. The structure for parts is documented in the code
+		//		below.
+
+
+		// NOTE:
+		//		this code is designed to run fast and compress well. Sacrifices
+		//		to readability and maintainability have been made.  Your best
+		//		bet when hacking the tokenizer is to put The Donnas on *really*
+		//		loud (may we recommend their "Spend The Night" release?) and
+		//		just assume you're gonna make mistakes. Keep the unit tests
+		//		open and run them frequently. Knowing is half the battle ;-)
+		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 += " * "
+		}else{
+			// if you have not provided a terminator, one will be provided for
+			// you...
+			query += " ";
+		}
+
+		var ts = function(/*Integer*/ s, /*Integer*/ e){
+			// trim and slice.
+
+			// take an index to start a string slice from and an end position
+			// and return a trimmed copy of that sub-string
+			return trim(query.slice(s, e));
+		};
+
+		// the overall data graph of the full query, as represented by queryPart objects
+		var queryParts = [];
+
+
+		// state keeping vars
+		var inBrackets = -1, inParens = -1, inMatchFor = -1,
+			inPseudo = -1, inClass = -1, inId = -1, inTag = -1,
+			lc = "", cc = "", pStart;
+
+		// iteration vars
+		var x = 0, // index in the query
+			ql = query.length,
+			currentPart = null, // data structure representing the entire clause
+			_cp = null; // the current pseudo or attr matcher
+
+		// several temporary variables are assigned to this structure during a
+		// potential sub-expression match:
+		//		attr:
+		//			a string representing the current full attribute match in a
+		//			bracket expression
+		//		type:
+		//			if there's an operator in a bracket expression, this is
+		//			used to keep track of it
+		//		value:
+		//			the internals of parenthetical expression for a pseudo. for
+		//			:nth-child(2n+1), value might be "2n+1"
+
+		var endTag = function(){
+			// called when the tokenizer hits the end of a particular tag name.
+			// Re-sets state variables for tag matching and sets up the matcher
+			// to handle the next type of token (tag or operator).
+			if(inTag >= 0){
+				var tv = (inTag == x) ? null : ts(inTag, x); // .toLowerCase();
+				currentPart[ (specials.indexOf(tv) < 0) ? "tag" : "oper" ] = tv;
+				inTag = -1;
+			}
+		};
+
+		var endId = function(){
+			// called when the tokenizer might be at the end of an ID portion of a match
+			if(inId >= 0){
+				currentPart.id = ts(inId, x).replace(/\\/g, "");
+				inId = -1;
+			}
+		};
+
+		var endClass = function(){
+			// called when the tokenizer might be at the end of a class name
+			// match. CSS allows for multiple classes, so we augment the
+			// current item with another class in its list
+			if(inClass >= 0){
+				currentPart.classes.push(ts(inClass + 1, x).replace(/\\/g, ""));
+				inClass = -1;
+			}
+		};
+
+		var endAll = function(){
+			// at the end of a simple fragment, so wall off the matches
+			endId();
+			endTag();
+			endClass();
+		};
+
+		var endPart = function(){
+			endAll();
+			if(inPseudo >= 0){
+				currentPart.pseudos.push({ name: ts(inPseudo + 1, x) });
+			}
+			// hint to the selector engine to tell it whether or not it
+			// needs to do any iteration. Many simple selectors don't, and
+			// we can avoid significant construction-time work by advising
+			// the system to skip them
+			currentPart.loops = (
+					currentPart.pseudos.length ||
+					currentPart.attrs.length ||
+					currentPart.classes.length	);
+
+			currentPart.oquery = currentPart.query = ts(pStart, x); // save the full expression as a string
+
+
+			// otag/tag are hints to suggest to the system whether or not
+			// it's an operator or a tag. We save a copy of otag since the
+			// tag name is cast to upper-case in regular HTML matches. The
+			// system has a global switch to figure out if the current
+			// expression needs to be case sensitive or not and it will use
+			// otag or tag accordingly
+			currentPart.otag = currentPart.tag = (currentPart["oper"]) ? null : (currentPart.tag || "*");
+
+			if(currentPart.tag){
+				// if we're in a case-insensitive HTML doc, we likely want
+				// the toUpperCase when matching on element.tagName. If we
+				// do it here, we can skip the string op per node
+				// comparison
+				currentPart.tag = currentPart.tag.toUpperCase();
+			}
+
+			// add the part to the list
+			if(queryParts.length && (queryParts[queryParts.length-1].oper)){
+				// operators are always infix, so we remove them from the
+				// list and attach them to the next match. The evaluator is
+				// responsible for sorting out how to handle them.
+				currentPart.infixOper = queryParts.pop();
+				currentPart.query = currentPart.infixOper.query + " " + currentPart.query;
+				/*
+				console.debug(	"swapping out the infix",
+								currentPart.infixOper,
+								"and attaching it to",
+								currentPart);
+				*/
+			}
+			queryParts.push(currentPart);
+
+			currentPart = null;
+		};
+
+		// iterate over the query, character by character, building up a
+		// list of query part objects
+		for(; lc=cc, cc=query.charAt(x), x < ql; x++){
+			//		cc: the current character in the match
+			//		lc: the last character (if any)
+
+			// someone is trying to escape something, so don't try to match any
+			// fragments. We assume we're inside a literal.
+			if(lc == "\\"){ continue; }
+			if(!currentPart){ // a part was just ended or none has yet been created
+				// NOTE: I hate all this alloc, but it's shorter than writing tons of if's
+				pStart = x;
+				//	rules describe full CSS sub-expressions, like:
+				//		#someId
+				//		.className:first-child
+				//	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:
+				//		[
+				//			{
+				//				query: "thinger",
+				//				tag: "thinger",
+				//			},
+				//			{
+				//				query: "div.howdy[type=thinger]",
+				//				classes: ["howdy"],
+				//				infixOper: {
+				//					query: ">",
+				//					oper: ">",
+				//				}
+				//			},
+				//		]
+				currentPart = {
+					query: null, // the full text of the part's rule
+					pseudos: [], // CSS supports multiple pseud-class matches in a single rule
+					attrs: [],	// CSS supports multi-attribute match, so we need an array
+					classes: [], // class matches may be additive, e.g.: .thinger.blah.howdy
+					tag: null,	// only one tag...
+					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;
+					}
+				};
+
+				// if we don't have a part, we assume we're going to start at
+				// the beginning of a match, which should be a tag name. This
+				// might fault a little later on, but we detect that and this
+				// iteration will still be fine.
+				inTag = x;
+			}
+
+			if(inBrackets >= 0){
+				// look for a the close first
+				if(cc == "]"){ // if we're in a [...] clause and we end, do assignment
+					if(!_cp.attr){
+						// no attribute match was previously begun, so we
+						// assume this is an attribute existence match in the
+						// form of [someAttributeName]
+						_cp.attr = ts(inBrackets+1, x);
+					}else{
+						// we had an attribute already, so we know that we're
+						// matching some sort of value, as in [attrName=howdy]
+						_cp.matchFor = ts((inMatchFor||inBrackets+1), x);
+					}
+					var cmf = _cp.matchFor;
+					if(cmf){
+						// try to strip quotes from the matchFor value. We want
+						// [attrName=howdy] to match the same
+						//	as [attrName = 'howdy' ]
+						if(	(cmf.charAt(0) == '"') || (cmf.charAt(0) == "'") ){
+							_cp.matchFor = cmf.slice(1, -1);
+						}
+					}
+					// end the attribute by adding it to the list of attributes.
+					currentPart.attrs.push(_cp);
+					_cp = null; // necessary?
+					inBrackets = inMatchFor = -1;
+				}else if(cc == "="){
+					// if the last char was an operator prefix, make sure we
+					// record it along with the "=" operator.
+					var addToCc = ("|~^$*".indexOf(lc) >=0 ) ? lc : "";
+					_cp.type = addToCc+cc;
+					_cp.attr = ts(inBrackets+1, x-addToCc.length);
+					inMatchFor = x+1;
+				}
+				// now look for other clause parts
+			}else if(inParens >= 0){
+				// if we're in a parenthetical expression, we need to figure
+				// out if it's attached to a pseudo-selector rule like
+				// :nth-child(1)
+				if(cc == ")"){
+					if(inPseudo >= 0){
+						_cp.value = ts(inParens+1, x);
+					}
+					inPseudo = inParens = -1;
+				}
+			}else if(cc == "#"){
+				// start of an ID match
+				endAll();
+				inId = x+1;
+			}else if(cc == "."){
+				// start of a class match
+				endAll();
+				inClass = x;
+			}else if(cc == ":"){
+				// start of a pseudo-selector match
+				endAll();
+				inPseudo = x;
+			}else if(cc == "["){
+				// start of an attribute match.
+				endAll();
+				inBrackets = x;
+				// provide a new structure for the attribute match to fill-in
+				_cp = {
+					/*=====
+					attr: null, type: null, matchFor: null
+					=====*/
+				};
+			}else if(cc == "("){
+				// we really only care if we've entered a parenthetical
+				// expression if we're already inside a pseudo-selector match
+				if(inPseudo >= 0){
+					// provide a new structure for the pseudo match to fill-in
+					_cp = {
+						name: ts(inPseudo+1, x),
+						value: null
+					};
+					currentPart.pseudos.push(_cp);
+				}
+				inParens = x;
+			}else if(
+				(cc == " ") &&
+				// if it's a space char and the last char is too, consume the
+				// current one without doing more work
+				(lc != cc)
+			){
+				endPart();
+			}
+		}
+		return queryParts;
+	};
+
+
+	////////////////////////////////////////////////////////////////////////
+	// DOM query infrastructure
+	////////////////////////////////////////////////////////////////////////
+
+	var agree = function(first, second){
+		// the basic building block of the yes/no chaining system. agree(f1,
+		// f2) generates a new function which returns the boolean results of
+		// both of the passed functions to a single logical-anded result. If
+		// either are not passed, the other is used exclusively.
+		if(!first){ return second; }
+		if(!second){ return first; }
+
+		return function(){
+			return first.apply(window, arguments) && second.apply(window, arguments);
+		}
+	};
+
+	var getArr = function(i, arr){
+		// helps us avoid array alloc when we don't need it
+		var r = arr||[]; // FIXME: should this be 'new d._NodeListCtor()' ?
+		if(i){ r.push(i); }
+		return r;
+	};
+
+	var _isElement = function(n){ return (1 == n.nodeType); };
+
+	// FIXME: need to coalesce _getAttr with defaultGetter
+	var blank = "";
+	var _getAttr = function(elem, attr){
+		if(!elem){ return blank; }
+		if(attr == "class"){
+			return elem.className || blank;
+		}
+		if(attr == "for"){
+			return elem.htmlFor || blank;
+		}
+		if(attr == "style"){
+			return elem.style.cssText || blank;
+		}
+		return (caseSensitive ? elem.getAttribute(attr) : elem.getAttribute(attr, 2)) || blank;
+	};
+
+	var attrs = {
+		"*=": function(attr, value){
+			return function(elem){
+				// E[foo*="bar"]
+				//		an E element whose "foo" attribute value contains
+				//		the substring "bar"
+				return (_getAttr(elem, attr).indexOf(value)>=0);
+			}
+		},
+		"^=": function(attr, value){
+			// E[foo^="bar"]
+			//		an E element whose "foo" attribute value begins exactly
+			//		with the string "bar"
+			return function(elem){
+				return (_getAttr(elem, attr).indexOf(value)==0);
+			}
+		},
+		"$=": function(attr, value){
+			// E[foo$="bar"]
+			//		an E element whose "foo" attribute value ends exactly
+			//		with the string "bar"
+			return function(elem){
+				var ea = " "+_getAttr(elem, attr);
+				return (ea.lastIndexOf(value)==(ea.length-value.length));
+			}
+		},
+		"~=": function(attr, value){
+			// E[foo~="bar"]
+			//		an E element whose "foo" attribute value is a list of
+			//		space-separated values, one of which is exactly equal
+			//		to "bar"
+
+			// return "[contains(concat(' ',@"+attr+",' '), ' "+ value +" ')]";
+			var tval = " "+value+" ";
+			return function(elem){
+				var ea = " "+_getAttr(elem, attr)+" ";
+				return (ea.indexOf(tval)>=0);
+			}
+		},
+		"|=": function(attr, value){
+			// E[hreflang|="en"]
+			//		an E element whose "hreflang" attribute has a
+			//		hyphen-separated list of values beginning (from the
+			//		left) with "en"
+			var valueDash = value+"-";
+			return function(elem){
+				var ea = _getAttr(elem, attr);
+				return (
+					(ea == value) ||
+					(ea.indexOf(valueDash)==0)
+				);
+			}
+		},
+		"=": function(attr, value){
+			return function(elem){
+				return (_getAttr(elem, attr) == value);
+			}
+		}
+	};
+
+	// avoid testing for node type if we can. Defining this in the negative
+	// here to avoid negation in the fast path.
+	var _noNES = (typeof getDoc().firstChild.nextElementSibling == "undefined");
+	var _ns = !_noNES ? "nextElementSibling" : "nextSibling";
+	var _ps = !_noNES ? "previousElementSibling" : "previousSibling";
+	var _simpleNodeTest = (_noNES ? _isElement : yesman);
+
+	var _lookLeft = function(node){
+		// look left
+		while(node = node[_ps]){
+			if(_simpleNodeTest(node)){ return false; }
+		}
+		return true;
+	};
+
+	var _lookRight = function(node){
+		// look right
+		while(node = node[_ns]){
+			if(_simpleNodeTest(node)){ return false; }
+		}
+		return true;
+	};
+
+	var getNodeIndex = function(node){
+		var root = node.parentNode;
+		var i = 0,
+			tret = root.children || root.childNodes,
+			ci = (node["_i"]||-1),
+			cl = (root["_l"]||-1);
+
+		if(!tret){ return -1; }
+		var l = tret.length;
+
+		// we calculate the parent length as a cheap way to invalidate the
+		// cache. It's not 100% accurate, but it's much more honest than what
+		// other libraries do
+		if( cl == l && ci >= 0 && cl >= 0 ){
+			// if it's legit, tag and release
+			return ci;
+		}
+
+		// else re-key things
+		root["_l"] = l;
+		ci = -1;
+		for(var te = root["firstElementChild"]||root["firstChild"]; te; te = te[_ns]){
+			if(_simpleNodeTest(te)){
+				te["_i"] = ++i;
+				if(node === te){
+					// NOTE:
+					//	shortcutting the return at this step in indexing works
+					//	very well for benchmarking but we avoid it here since
+					//	it leads to potential O(n^2) behavior in sequential
+					//	getNodexIndex operations on a previously un-indexed
+					//	parent. We may revisit this at a later time, but for
+					//	now we just want to get the right answer more often
+					//	than not.
+					ci = i;
+				}
+			}
+		}
+		return ci;
+	};
+
+	var isEven = function(elem){
+		return !((getNodeIndex(elem)) % 2);
+	};
+
+	var isOdd = function(elem){
+		return ((getNodeIndex(elem)) % 2);
+	};
+
+	var pseudos = {
+		"checked": function(name, condition){
+			return function(elem){
+				return !!("checked" in elem ? elem.checked : elem.selected);
+			}
+		},
+		"first-child": function(){ return _lookLeft; },
+		"last-child": function(){ return _lookRight; },
+		"only-child": function(name, condition){
+			return function(node){
+				return _lookLeft(node) && _lookRight(node);
+			};
+		},
+		"empty": function(name, condition){
+			return function(elem){
+				// DomQuery and jQuery get this wrong, oddly enough.
+				// The CSS 3 selectors spec is pretty explicit about it, too.
+				var cn = elem.childNodes;
+				var cnl = elem.childNodes.length;
+				// if(!cnl){ return true; }
+				for(var x=cnl-1; x >= 0; x--){
+					var nt = cn[x].nodeType;
+					if((nt === 1)||(nt == 3)){ return false; }
+				}
+				return true;
+			}
+		},
+		"contains": function(name, condition){
+			var cz = condition.charAt(0);
+			if( cz == '"' || cz == "'" ){ //remove quote
+				condition = condition.slice(1, -1);
+			}
+			return function(elem){
+				return (elem.innerHTML.indexOf(condition) >= 0);
+			}
+		},
+		"not": function(name, condition){
+			var p = getQueryParts(condition)[0];
+			var ignores = { el: 1 };
+			if(p.tag != "*"){
+				ignores.tag = 1;
+			}
+			if(!p.classes.length){
+				ignores.classes = 1;
+			}
+			var ntf = getSimpleFilterFunc(p, ignores);
+			return function(elem){
+				return (!ntf(elem));
+			}
+		},
+		"nth-child": function(name, condition){
+			var pi = parseInt;
+			// avoid re-defining function objects if we can
+			if(condition == "odd"){
+				return isOdd;
+			}else if(condition == "even"){
+				return isEven;
+			}
+			// FIXME: can we shorten this?
+			if(condition.indexOf("n") != -1){
+				var tparts = condition.split("n", 2);
+				var pred = tparts[0] ? ((tparts[0] == '-') ? -1 : pi(tparts[0])) : 1;
+				var idx = tparts[1] ? pi(tparts[1]) : 0;
+				var lb = 0, ub = -1;
+				if(pred > 0){
+					if(idx < 0){
+						idx = (idx % pred) && (pred + (idx % pred));
+					}else if(idx>0){
+						if(idx >= pred){
+							lb = idx - idx % pred;
+						}
+						idx = idx % pred;
+					}
+				}else if(pred<0){
+					pred *= -1;
+					// idx has to be greater than 0 when pred is negative;
+					// shall we throw an error here?
+					if(idx > 0){
+						ub = idx;
+						idx = idx % pred;
+					}
+				}
+				if(pred > 0){
+					return function(elem){
+						var i = getNodeIndex(elem);
+						return (i>=lb) && (ub<0 || i<=ub) && ((i % pred) == idx);
+					}
+				}else{
+					condition = idx;
+				}
+			}
+			var ncount = pi(condition);
+			return function(elem){
+				return (getNodeIndex(elem) == ncount);
+			}
+		}
+	};
+
+	var defaultGetter = (dojo.isIE && (dojo.isIE < 9 || dojo.isQuirks)) ? 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){
+		// generates a node tester function based on the passed query part. The
+		// query part is one of the structures generated by the query parser
+		// when it creates the query AST. The "ignores" object specifies which
+		// (if any) tests to skip, allowing the system to avoid duplicating
+		// work where it may have already been taken into account by other
+		// factors such as how the nodes to test were fetched in the first
+		// place
+		if(!query){ return yesman; }
+		ignores = ignores||{};
+
+		var ff = null;
+
+		if(!("el" in ignores)){
+			ff = agree(ff, _isElement);
+		}
+
+		if(!("tag" in ignores)){
+			if(query.tag != "*"){
+				ff = agree(ff, function(elem){
+					return (elem && (elem.tagName == query.getTag()));
+				});
+			}
+		}
+
+		if(!("classes" in ignores)){
+			each(query.classes, function(cname, idx, arr){
+				// get the class name
+				/*
+				var isWildcard = cname.charAt(cname.length-1) == "*";
+				if(isWildcard){
+					cname = cname.substr(0, cname.length-1);
+				}
+				// I dislike the regex thing, even if memoized in a cache, but it's VERY short
+				var re = new RegExp("(?:^|\\s)" + cname + (isWildcard ? ".*" : "") + "(?:\\s|$)");
+				*/
+				var re = new RegExp("(?:^|\\s)" + cname + "(?:\\s|$)");
+				ff = agree(ff, function(elem){
+					return re.test(elem.className);
+				});
+				ff.count = idx;
+			});
+		}
+
+		if(!("pseudos" in ignores)){
+			each(query.pseudos, function(pseudo){
+				var pn = pseudo.name;
+				if(pseudos[pn]){
+					ff = agree(ff, pseudos[pn](pn, pseudo.value));
+				}
+			});
+		}
+
+		if(!("attrs" in ignores)){
+			each(query.attrs, function(attr){
+				var matcher;
+				var a = attr.attr;
+				// type, attr, matchFor
+				if(attr.type && attrs[attr.type]){
+					matcher = attrs[attr.type](a, attr.matchFor);
+				}else if(a.length){
+					matcher = defaultGetter(a);
+				}
+				if(matcher){
+					ff = agree(ff, matcher);
+				}
+			});
+		}
+
+		if(!("id" in ignores)){
+			if(query.id){
+				ff = agree(ff, function(elem){
+					return (!!elem && (elem.id == query.id));
+				});
+			}
+		}
+
+		if(!ff){
+			if(!("default" in ignores)){
+				ff = yesman;
+			}
+		}
+		return ff;
+	};
+
+	var _nextSibling = function(filterFunc){
+		return function(node, ret, bag){
+			while(node = node[_ns]){
+				if(_noNES && (!_isElement(node))){ continue; }
+				if(
+					(!bag || _isUnique(node, bag)) &&
+					filterFunc(node)
+				){
+					ret.push(node);
+				}
+				break;
+			}
+			return ret;
+		}
+	};
+
+	var _nextSiblings = function(filterFunc){
+		return function(root, ret, bag){
+			var te = root[_ns];
+			while(te){
+				if(_simpleNodeTest(te)){
+					if(bag && !_isUnique(te, bag)){
+						break;
+					}
+					if(filterFunc(te)){
+						ret.push(te);
+					}
+				}
+				te = te[_ns];
+			}
+			return ret;
+		}
+	};
+
+	// get an array of child *elements*, skipping text and comment nodes
+	var _childElements = function(filterFunc){
+		filterFunc = filterFunc||yesman;
+		return function(root, ret, bag){
+			// get an array of child elements, skipping text and comment nodes
+			var te, x = 0, tret = root.children || root.childNodes;
+			while(te = tret[x++]){
+				if(
+					_simpleNodeTest(te) &&
+					(!bag || _isUnique(te, bag)) &&
+					(filterFunc(te, x))
+				){
+					ret.push(te);
+				}
+			}
+			return ret;
+		};
+	};
+
+	/*
+	// 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;
+		while(pn){
+			if(pn == root){
+				break;
+			}
+			pn = pn.parentNode;
+		}
+		return !!pn;
+	};
+
+	var _getElementsFuncCache = {};
+
+	var getElementsFunc = function(query){
+		var retFunc = _getElementsFuncCache[query.query];
+		// if we've got a cached dispatcher, just use that
+		if(retFunc){ return retFunc; }
+		// else, generate a new on
+
+		// NOTE:
+		//		this function returns a function that searches for nodes and
+		//		filters them.  The search may be specialized by infix operators
+		//		(">", "~", or "+") else it will default to searching all
+		//		descendants (the " " selector). Once a group of children is
+		//		found, a test function is applied to weed out the ones we
+		//		don't want. Many common cases can be fast-pathed. We spend a
+		//		lot of cycles to create a dispatcher that doesn't do more work
+		//		than necessary at any point since, unlike this function, the
+		//		dispatchers will be called every time. The logic of generating
+		//		efficient dispatchers looks like this in pseudo code:
+		//
+		//		# if it's a purely descendant query (no ">", "+", or "~" modifiers)
+		//		if infixOperator == " ":
+		//			if only(id):
+		//				return def(root):
+		//					return d.byId(id, root);
+		//
+		//			elif id:
+		//				return def(root):
+		//					return filter(d.byId(id, root));
+		//
+		//			elif cssClass && getElementsByClassName:
+		//				return def(root):
+		//					return filter(root.getElementsByClassName(cssClass));
+		//
+		//			elif only(tag):
+		//				return def(root):
+		//					return root.getElementsByTagName(tagName);
+		//
+		//			else:
+		//				# search by tag name, then filter
+		//				return def(root):
+		//					return filter(root.getElementsByTagName(tagName||"*"));
+		//
+		//		elif infixOperator == ">":
+		//			# search direct children
+		//			return def(root):
+		//				return filter(root.children);
+		//
+		//		elif infixOperator == "+":
+		//			# search next sibling
+		//			return def(root):
+		//				return filter(root.nextElementSibling);
+		//
+		//		elif infixOperator == "~":
+		//			# search rightward siblings
+		//			return def(root):
+		//				return filter(nextSiblings(root));
+
+		var io = query.infixOper;
+		var oper = (io ? io.oper : "");
+		// the default filter func which tests for all conditions in the query
+		// part. This is potentially inefficient, so some optimized paths may
+		// re-define it to test fewer things.
+		var filterFunc = getSimpleFilterFunc(query, { el: 1 });
+		var qt = query.tag;
+		var wildcardTag = ("*" == qt);
+		var ecs = getDoc()["getElementsByClassName"];
+
+		if(!oper){
+			// if there's no infix operator, then it's a descendant query. ID
+			// and "elements by class name" variants can be accelerated so we
+			// call them out explicitly:
+			if(query.id){
+				// testing shows that the overhead of yesman() is acceptable
+				// and can save us some bytes vs. re-defining the function
+				// everywhere.
+				filterFunc = (!query.loops && wildcardTag) ?
+					yesman :
+					getSimpleFilterFunc(query, { el: 1, id: 1 });
+
+				retFunc = function(root, arr){
+					var te = dom.byId(query.id, (root.ownerDocument||root));
+					if(!te || !filterFunc(te)){ return; }
+					if(9 == root.nodeType){ // if root's a doc, we just return directly
+						return getArr(te, arr);
+					}else{ // otherwise check ancestry
+						if(_isDescendant(te, root)){
+							return getArr(te, arr);
+						}
+					}
+				}
+			}else if(
+				ecs &&
+				// isAlien check. Workaround for Prototype.js being totally evil/dumb.
+				/\{\s*\[native code\]\s*\}/.test(String(ecs)) &&
+				query.classes.length &&
+				!cssCaseBug
+			){
+				// it's a class-based query and we've got a fast way to run it.
+
+				// ignore class and ID filters since we will have handled both
+				filterFunc = getSimpleFilterFunc(query, { el: 1, classes: 1, id: 1 });
+				var classesString = query.classes.join(" ");
+				retFunc = function(root, arr, bag){
+					var ret = getArr(0, arr), te, x=0;
+					var tret = root.getElementsByClassName(classesString);
+					while((te = tret[x++])){
+						if(filterFunc(te, root) && _isUnique(te, bag)){
+							ret.push(te);
+						}
+					}
+					return ret;
+				};
+
+			}else if(!wildcardTag && !query.loops){
+				// 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());
+					while((te = tret[x++])){
+						if(_isUnique(te, bag)){
+							ret.push(te);
+						}
+					}
+					return ret;
+				};
+			}else{
+				// the common case:
+				//		a descendant selector without a fast path. By now it's got
+				//		to have a tag selector, even if it's just "*" so we query
+				//		by that and filter
+				filterFunc = getSimpleFilterFunc(query, { el: 1, tag: 1, id: 1 });
+				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());
+					while((te = tret[x++])){
+						if(filterFunc(te, root) && _isUnique(te, bag)){
+							ret.push(te);
+						}
+					}
+					return ret;
+				};
+			}
+		}else{
+			// the query is scoped in some way. Instead of querying by tag we
+			// use some other collection to find candidate nodes
+			var skipFilters = { el: 1 };
+			if(wildcardTag){
+				skipFilters.tag = 1;
+			}
+			filterFunc = getSimpleFilterFunc(query, skipFilters);
+			if("+" == oper){
+				retFunc = _nextSibling(filterFunc);
+			}else if("~" == oper){
+				retFunc = _nextSiblings(filterFunc);
+			}else if(">" == oper){
+				retFunc = _childElements(filterFunc);
+			}
+		}
+		// cache it and return
+		return _getElementsFuncCache[query.query] = retFunc;
+	};
+
+	var filterDown = function(root, queryParts){
+		// NOTE:
+		//		this is the guts of the DOM query system. It takes a list of
+		//		parsed query parts and a root and finds children which match
+		//		the selector represented by the parts
+		var candidates = getArr(root), qp, x, te, qpl = queryParts.length, bag, ret;
+
+		for(var i = 0; i < qpl; i++){
+			ret = [];
+			qp = queryParts[i];
+			x = candidates.length - 1;
+			if(x > 0){
+				// 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
+				bag = {};
+				ret.nozip = true;
+			}
+			var gef = getElementsFunc(qp);
+			for(var j = 0; (te = candidates[j]); j++){
+				// for every root, get the elements that match the descendant
+				// selector, adding them to the "ret" array and filtering them
+				// via membership in this level's bag. If there are more query
+				// parts, then this level's return will be used as the next
+				// level's candidates
+				gef(te, ret, bag);
+			}
+			if(!ret.length){ break; }
+			candidates = ret;
+		}
+		return ret;
+	};
+
+	////////////////////////////////////////////////////////////////////////
+	// the query runner
+	////////////////////////////////////////////////////////////////////////
+
+	// these are the primary caches for full-query results. The query
+	// dispatcher functions are generated then stored here for hash lookup in
+	// the future
+	var _queryFuncCacheDOM = {},
+		_queryFuncCacheQSA = {};
+
+	// this is the second level of spliting, from full-length queries (e.g.,
+	// "div.foo .bar") into simple query expressions (e.g., ["div.foo",
+	// ".bar"])
+	var getStepQueryFunc = function(query){
+		var qparts = getQueryParts(trim(query));
+
+		// if it's trivial, avoid iteration and zipping costs
+		if(qparts.length == 1){
+			// we optimize this case here to prevent dispatch further down the
+			// chain, potentially slowing things down. We could more elegantly
+			// handle this in filterDown(), but it's slower for simple things
+			// that need to be fast (e.g., "#someId").
+			var tef = getElementsFunc(qparts[0]);
+			return function(root){
+				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:
+	//	* we can't trust QSA for anything but document-rooted queries, so
+	//	  caching is split into DOM query evaluators and QSA query evaluators
+	//	* caching query results is dirty and leak-prone (or, at a minimum,
+	//	  prone to unbounded growth). Other toolkits may go this route, but
+	//	  they totally destroy their own ability to manage their memory
+	//	  footprint. If we implement it, it should only ever be with a fixed
+	//	  total element reference # limit and an LRU-style algorithm since JS
+	//	  has no weakref support. Caching compiled query evaluators is also
+	//	  potentially problematic, but even on large documents the size of the
+	//	  query evaluators is often < 100 function objects per evaluator (and
+	//	  LRU can be applied if it's ever shown to be an issue).
+	//	* since IE's QSA support is currently only for HTML documents and even
+	//	  then only in IE 8's "standards mode", we have to detect our dispatch
+	//	  route at query time and keep 2 separate caches. Ugg.
+
+	// 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
+	// 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 qsa = "querySelectorAll";
+	var qsaAvail = (
+		!!getDoc()[qsa] &&
+		// see #5832
+		(!dojo.isSafari || (dojo.isSafari > 3.1) || is525 )
+	);
+
+	//Don't bother with n+3 type of matches, IE complains if we modify those.
+	var infixSpaceRe = /n\+\d|([^ ])?([>~+])([^ =])?/g;
+	var infixSpaceFunc = function(match, pre, ch, post){
+		return ch ? (pre ? pre + " " : "") + ch + (post ? " " + post : "") : /*n+3*/ match;
+	};
+
+	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);
+
+		if(qsaAvail){
+			// if we've got a cached variant and we think we can do it, run it!
+			var qsaCached = _queryFuncCacheQSA[query];
+			if(qsaCached && !forceDOM){ return qsaCached; }
+		}
+
+		// else if we've got a DOM cached variant, assume that we already know
+		// all we need to and use it
+		var domCached = _queryFuncCacheDOM[query];
+		if(domCached){ return domCached; }
+
+		// TODO:
+		//		today we're caching DOM and QSA branches separately so we
+		//		recalc useQSA every time. If we had a way to tag root+query
+		//		efficiently, we'd be in good shape to do a global cache.
+
+		var qcz = query.charAt(0);
+		var nospace = (-1 == query.indexOf(" "));
+
+		// byId searches are wicked fast compared to QSA, even when filtering
+		// is required
+		if( (query.indexOf("#") >= 0) && (nospace) ){
+			forceDOM = true;
+		}
+
+		var useQSA = (
+			qsaAvail && (!forceDOM) &&
+			// as per CSS 3, we can't currently start w/ combinator:
+			//		http://www.w3.org/TR/css3-selectors/#w3cselgrammar
+			(specials.indexOf(qcz) == -1) &&
+			// IE's QSA impl sucks on pseudos
+			(!dojo.isIE || (query.indexOf(":") == -1)) &&
+
+			(!(cssCaseBug && (query.indexOf(".") >= 0))) &&
+
+			// FIXME:
+			//		need to tighten up browser rules on ":contains" and "|=" to
+			//		figure out which aren't good
+			//		Latest webkit (around 531.21.8) does not seem to do well with :checked on option
+			//		elements, even though according to spec, selected options should
+			//		match :checked. So go nonQSA for it:
+			//		http://bugs.dojotoolkit.org/ticket/5179
+			(query.indexOf(":contains") == -1) && (query.indexOf(":checked") == -1) &&
+			(query.indexOf("|=") == -1) // some browsers don't grok it
+		);
+
+		// TODO:
+		//		if we've got a descendant query (e.g., "> .thinger" instead of
+		//		just ".thinger") in a QSA-able doc, but are passed a child as a
+		//		root, it should be possible to give the item a synthetic ID and
+		//		trivially rewrite the query to the form "#synid > .thinger" to
+		//		use the QSA branch
+
+
+		if(useQSA){
+			var tq = (specials.indexOf(query.charAt(query.length-1)) >= 0) ?
+						(query + " *") : query;
+			return _queryFuncCacheQSA[query] = function(root){
+				try{
+					// the QSA system contains an egregious spec bug which
+					// limits us, effectively, to only running QSA queries over
+					// entire documents.  See:
+					//		http://ejohn.org/blog/thoughts-on-queryselectorall/
+					//	despite this, we can also handle QSA runs on simple
+					//	selectors, but we don't want detection to be expensive
+					//	so we're just checking for the presence of a space char
+					//	right now. Not elegant, but it's cheaper than running
+					//	the query parser when we might not need to
+					if(!((9 == root.nodeType) || nospace)){ throw ""; }
+					var r = root[qsa](tq);
+					// skip expensive duplication checks and just wrap in a NodeList
+					r[noZip] = true;
+					return r;
+				}catch(e){
+					// else run the DOM branch on this query, ensuring that we
+					// default that way in the future
+					return getQueryFunc(query, true)(root);
+				}
+			}
+		}else{
+			// DOM branch
+			var parts = query.split(/\s*,\s*/);
+			return _queryFuncCacheDOM[query] = ((parts.length < 2) ?
+				// if not a compound query (e.g., ".foo, .bar"), cache and return a dispatcher
+				getStepQueryFunc(query) :
+				// if it *is* a complex query, break it up into its
+				// constituent parts and return a dispatcher that will
+				// merge the parts when run
+				function(root){
+					var pindex = 0, // avoid array alloc for every invocation
+						ret = [],
+						tp;
+					while((tp = parts[pindex++])){
+						ret = ret.concat(getStepQueryFunc(tp)(root));
+					}
+					return ret;
+				}
+			);
+		}
+	};
+
+	var _zipIdx = 0;
+
+	// NOTE:
+	//		this function is Moo inspired, but our own impl to deal correctly
+	//		with XML in IE
+	var _nodeUID = dojo.isIE ? function(node){
+		if(caseSensitive){
+			// XML docs don't have uniqueID on their nodes
+			return (node.getAttribute("_uid") || node.setAttribute("_uid", ++_zipIdx) || _zipIdx);
+
+		}else{
+			return node.uniqueID;
+		}
+	} :
+	function(node){
+		return (node._uid || (node._uid = ++_zipIdx));
+	};
+
+	// determine if a node in is unique in a "bag". In this case we don't want
+	// to flatten a list of unique items, but rather just tell if the item in
+	// question is already in the bag. Normally we'd just use hash lookup to do
+	// this for us but IE's DOM is busted so we can't really count on that. On
+	// the upside, it gives us a built in unique ID function.
+	var _isUnique = function(node, bag){
+		if(!bag){ return 1; }
+		var id = _nodeUID(node);
+		if(!bag[id]){ return bag[id] = 1; }
+		return 0;
+	};
+
+	// attempt to efficiently determine if an item in a list is a dupe,
+	// returning a list of "uniques", hopefully in doucment order
+	var _zipIdxName = "_zipIdx";
+	var _zip = function(arr){
+		if(arr && arr.nozip){
+			return arr;
+		}
+		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 szidx = _zipIdx+"";
+			arr[0].setAttribute(_zipIdxName, szidx);
+			for(var x = 1, te; te = arr[x]; x++){
+				if(arr[x].getAttribute(_zipIdxName) != szidx){
+					ret.push(te);
+				}
+				te.setAttribute(_zipIdxName, szidx);
+			}
+		}else if(dojo.isIE && arr.commentStrip){
+			try{
+				for(var x = 1, te; te = arr[x]; x++){
+					if(_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){
+					ret.push(te);
+				}
+				te[_zipIdxName] = _zipIdx;
+			}
+		}
+		return ret;
+	};
+
+	// the main executor
+	var query = function(/*String*/ query, /*String|DOMNode?*/ root){
+		//	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:
+		//		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
+		//		CSS-based node selector support with the option of scoping searches
+		//		to a particular sub-tree of a document.
+		//
+		//		Supported Selectors:
+		//		--------------------
+		//
+		//		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
+		//
+		//		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 operations become very straightforward.
+		//
+		//		Unsupported Selectors:
+		//		----------------------
+		//
+		//		While dojo.query handles many CSS3 selectors, some fall outside of
+		//		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`,
+		//				  `:enabled`, `:disabled`
+		//			* `:*-of-type` pseudo selectors
+		//
+		//		dojo.query and XML Documents:
+		//		-----------------------------
+		//
+		//		`dojo.query` (as of dojo 1.2) supports searching XML documents
+		//		in a case-sensitive manner. If an HTML document is served with
+		//		a doctype that forces case-sensitivity (e.g., XHTML 1.1
+		//		Strict), dojo.query() will detect this and "do the right
+		//		thing". Case sensitivity is dependent upon the document being
+		//		searched and not the query used. It is therefore possible to
+		//		use case-sensitive queries on strict sub-documents (iframes,
+		//		etc.) or XML documents while still assuming case-insensitivity
+		//		for a host/root document.
+		//
+		//		Non-selector Queries:
+		//		---------------------
+		//
+		//		If something other than a String is passed for the query,
+		//		`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:
+		//		The CSS3 expression to match against. For details on the syntax of
+		//		CSS3 selectors, see <http://www.w3.org/TR/css3-selectors/#selectors>
+		//	root:
+		//		A DOMNode (or node id) to scope the search from. Optional.
+		//	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:
+		//		search the entire document for elements with the classes "foo" *and* "bar":
+		//	|	dojo.query(".foo.bar");
+		//		these elements will match:
+		//	|	<span class="foo bar"></span>
+		//		while these will not:
+		//	|	<span class="foo"></span>
+		//	|	<p class="thud foo"></p>
+		//	example:
+		//		find `<span>` elements which are descendants of paragraphs and
+		//		which have a "highlighted" class:
+		//	|	dojo.query("p span.highlighted");
+		//		the innermost span in this fragment matches:
+		//	|	<p class="foo">
+		//	|		<span>...
+		//	|			<span class="highlighted foo bar">...</span>
+		//	|		</span>
+		//	|	</p>
+		//	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:
+		//		remove all elements with the class "error" from the document
+		//		and store them in a list:
+		//	|	var errors = dojo.query(".error").orphan();
+		//	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){
+		//	|		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");
+		//	|			}
+		//	|		});
+		//	|	});
+
+		root = root||getDoc();
+		var od = root.ownerDocument||root.documentElement;
+
+		// 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));
+
+		// NOTE:
+		//		adding "true" as the 2nd argument to getQueryFunc is useful for
+		//		testing the DOM branch without worrying about the
+		//		behavior/performance of the QSA branch.
+		var r = getQueryFunc(query)(root);
+
+		// FIXME:
+		//		need to investigate this branch WRT #8074 and #8075
+		if(r && r.nozip){
+			return r;
+		}
+		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
+		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;
+				};
+		for(var x = 0, te; te = nodeList[x]; x++){
+			if(filterFunc(te)){ tmpNodeList.push(te); }
+		}
+		return tmpNodeList;
+	};
+	return query;
+});//end defineQuery
diff --git a/dojo/selector/lite.js b/dojo/selector/lite.js
new file mode 100644
index 0000000..8228828
--- /dev/null
+++ b/dojo/selector/lite.js
@@ -0,0 +1,264 @@
+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;
+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){
+	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
+			.exec(selector);
+	root = root || document;
+	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]);
+			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){
+				// there is a root element, make sure we are a child of it
+				var parent = found;
+				while(parent != root){
+					parent = parent.parentNode;
+					if(!parent){
+						return [];
+					}
+				}
+			}
+			return match[3] ?
+					liteEngine(match[3], found) 
+					: [found];
+		}
+		if(match[3] && root.getElementsByClassName){
+			// a .class
+			return root.getElementsByClassName(match[4]);
+		}
+		var found;
+		if(match[5]){
+			// a tag
+			found = root.getElementsByTagName(match[5]);
+			if(match[4] || match[6]){
+				selector = (match[4] || "") + match[6];
+			}else{
+				// that was the entirety of the query, return results
+				return found;
+			}
+		}
+	}
+	if(querySelectorAll){
+		// qSA works strangely on Element-rooted queries
+		// We can work around this by specifying an extra ID on the root
+		// and working up from there (Thanks to Andrew Dupont for the technique)
+		// IE 8 doesn't work on object elements
+		if (root.nodeType === 1 && root.nodeName.toLowerCase() !== "object"){				
+			return useRoot(root, selector, root.querySelectorAll);
+		}else{
+			// we can use the native qSA
+			return root.querySelectorAll(selector);
+		}
+	}else if(!found){
+		// search all children and then filter
+		found = root.getElementsByTagName("*");
+	}
+	// now we filter the nodes that were found using the matchesSelector
+	var results = [];
+	for(var i = 0, l = found.length; i < l; i++){
+		var node = found[i];
+		if(node.nodeType == 1 && jsMatchesSelector(node, selector, root)){
+			// keep the nodes that match the selector
+			results.push(node);
+		}
+	}
+	return results;
+};
+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" ),
+		nid = old || "__dojo__",
+		hasParent = context.parentNode,
+		relativeHierarchySelector = /^\s*[+~]/.test( query );
+
+	if(relativeHierarchySelector && !hasParent){
+		return [];
+	}
+	if(!old){
+		context.setAttribute("id", nid);
+	}else{
+		nid = nid.replace(/'/g, "\\$&");
+	}
+	if(relativeHierarchySelector && hasParent){
+		context = context.parentNode;
+	}
+
+	try {
+		return method.call(context, "[id='" + nid + "'] " + query );
+	} finally {
+		if ( !old ) {
+			oldContext.removeAttribute( "id" );
+		}
+	}
+};
+
+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 attrComparators = {
+			"^=": function(attrValue, value){
+				return attrValue.indexOf(value) == 0;
+			},
+			"*=": function(attrValue, value){
+				return attrValue.indexOf(value) > -1;
+			},
+			"$=": function(attrValue, value){
+				return attrValue.substring(attrValue.length - value.length, attrValue.length) == value;
+			},
+			"~=": function(attrValue, value){
+				return (' ' + attrValue + ' ').indexOf(' ' + value + ' ') > -1;
+			},
+			"|=": function(attrValue, value){
+				return (attrValue + '-').indexOf(value + '-') == 0;
+			},
+			"=": function(attrValue, value){
+				return attrValue == value;
+			},
+			"": function(attrValue, value){
+				return true;
+			}
+		};
+		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 comparator = attrComparators[type || ""];
+			return function(node){
+				var attrValue = node.getAttribute(name);
+				return attrValue && comparator(attrValue, value);
+			}
+		}
+		function ancestor(matcher){
+			return function(node, root){
+				while((node = node.parentNode) != root){
+					if(matcher(node, root)){
+						return true;
+					}
+				}
+			};
+		}
+		function parent(matcher){
+			return function(node, root){
+				node = node.parentNode;
+				return matcher ? 
+					node != root && matcher(node, root)
+					: node == root;
+			};
+		}
+		var cache = {};
+		function and(matcher, next){
+			return matcher ?
+				function(node, root){
+					return next(node) && matcher(node, root);
+				}
+				: next;
+		}
+		return function(node, selector, root){
+			// this returns true or false based on if the node matches the selector (optionally within the given root)
+			var matcher = cache[selector]; // check to see if we have created a matcher function for the given 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(value){
+						if(type == "."){
+							matcher = and(matcher, className(value));
+						}
+						else{
+							matcher = and(matcher, tag(value));
+						}
+					}
+					else if(combinator){
+						matcher = (combinator == " " ? ancestor : parent)(matcher);
+					}
+					else if(attrName){
+						matcher = and(matcher, attr(attrName, attrValue, attrType));
+					}
+					return "";
+				})){
+					throw new Error("Syntax error in query");
+				}
+				if(!matcher){
+					return true;
+				}
+				cache[selector] = matcher;
+			}
+			// now run the matcher function on the node
+			return matcher(node, root);
+		};
+	})();
+}
+if(!has("dom-qsa")){
+	var combine = function(selector, root){
+		// combined queries
+		selector = selector.split(/\s*,\s*/);
+		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 j = 0, l = results.length; j < l; j++){
+				var node = results[j];
+				indexed[node.sourceIndex] = node;
+			}
+		}
+		// now convert from a sparse array to a dense array
+		var totalResults = [];
+		for(i in indexed){
+			totalResults.push(indexed[i]);
+		}
+		return totalResults;
+	};
+}
+
+liteEngine.match = matchesSelector ? function(node, selector, root){
+	if(root){
+		// doesn't support three args, use rooted id trick
+		return useRoot(root, selector, function(query){
+			return matchesSelector.call(node, query);
+		});
+	}
+	// we have a native matchesSelector, use that
+	return matchesSelector.call(node, selector);
+} : jsMatchesSelector; // otherwise use the JS matches impl
+
+return liteEngine;
+});
diff --git a/dojo/store/Cache.js b/dojo/store/Cache.js
index 4897ecb..bc3cf4f 100644
--- a/dojo/store/Cache.js
+++ b/dojo/store/Cache.js
@@ -1,5 +1,11 @@
-define("dojo/store/Cache", ["dojo"], function(dojo) {
-dojo.getObject("store", true, dojo);
+define(["../_base/lang","../_base/Deferred"
+],function(lang, Deferred) {
+	// module:
+	//		dojo/store/Cache
+	// summary:
+	//		TODOC
+
+var store = lang.getObject("dojo.store", true);
 
 /*=====
 dojo.declare("dojo.store.__CacheArgs", null, {
@@ -14,7 +20,7 @@ dojo.declare("dojo.store.__CacheArgs", null, {
 	}
 });
 =====*/
-dojo.store.Cache = function(masterStore, cachingStore, /*dojo.store.__CacheArgs*/ options){
+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
@@ -29,7 +35,7 @@ dojo.store.Cache = function(masterStore, cachingStore, /*dojo.store.__CacheArgs*
 	// options:
 	//		These are additional options for how caching is handled.
 	options = options || {};
-	return dojo.delegate(masterStore, {
+	return lang.delegate(masterStore, {
 		query: function(query, directives){
 			var results = masterStore.query(query, directives);
 			results.forEach(function(object){
@@ -42,8 +48,8 @@ dojo.store.Cache = function(masterStore, cachingStore, /*dojo.store.__CacheArgs*
 		// look for a queryEngine in either store
 		queryEngine: masterStore.queryEngine || cachingStore.queryEngine,
 		get: function(id, directives){
-			return dojo.when(cachingStore.get(id), function(result){
-				return result || dojo.when(masterStore.get(id, directives), function(result){
+			return Deferred.when(cachingStore.get(id), function(result){
+				return result || Deferred.when(masterStore.get(id, directives), function(result){
 					if(result){
 						cachingStore.put(result, {id: id});
 					}
@@ -52,24 +58,24 @@ dojo.store.Cache = function(masterStore, cachingStore, /*dojo.store.__CacheArgs*
 			});
 		},
 		add: function(object, directives){
-            return dojo.when(masterStore.add(object, directives), function(result){
-            	// now put result in cache
-                return cachingStore.add(typeof result == "object" ? result : object, directives);
-            });
-        },
+			return Deferred.when(masterStore.add(object, directives), function(result){
+				// now put result in cache
+				return cachingStore.add(typeof result == "object" ? result : object, directives);
+			});
+		},
 		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 dojo.when(masterStore.put(object, directives), function(result){
-            	// now put result in cache
-                return cachingStore.put(typeof result == "object" ? result : object, directives);
-            });
-        },
+			cachingStore.remove((directives && directives.id) || this.getIdentity(object));
+			return Deferred.when(masterStore.put(object, directives), function(result){
+				// now put result in cache
+				return cachingStore.put(typeof result == "object" ? result : object, directives);
+			});
+		},
 		remove: function(id, directives){
-            return dojo.when(masterStore.remove(id, directives), function(result){
-                return cachingStore.remove(id, directives);
-            });
-        },
+			return Deferred.when(masterStore.remove(id, directives), function(result){
+				return cachingStore.remove(id, directives);
+			});
+		},
 		evict: function(id){
 			return cachingStore.remove(id);
 		}
@@ -138,5 +144,5 @@ dojo.declare("dojo.store.Cache", null, {
 	}
 });
 =====*/
-return dojo.store.Cache;
+return store.Cache;
 });
diff --git a/dojo/store/DataStore.js b/dojo/store/DataStore.js
index f682d10..fac842f 100644
--- a/dojo/store/DataStore.js
+++ b/dojo/store/DataStore.js
@@ -1,6 +1,12 @@
-define("dojo/store/DataStore", ["dojo", "dojo/store/util/QueryResults"], function(dojo) {
+define(["../_base/lang", "../_base/declare", "../_base/Deferred", "../_base/array", "./util/QueryResults"
+], function(lang,declare,Deferred,array,QueryResults) {
+	// module:
+	//		dojo/store/DataStore
+	// summary:
+	//		TODOC
 
-dojo.declare("dojo.store.DataStore", null, {
+
+return declare("dojo.store.DataStore", null, {
 	target: "",
 	constructor: function(options){
 		// summary:
@@ -10,16 +16,48 @@ dojo.declare("dojo.store.DataStore", null, {
 		// 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".
-		dojo.mixin(this, options);
+		lang.mixin(this, options);
+ 		if(!"idProperty" in options){
+			var idAttribute; 
+			try{
+				idAttribute = this.store.getIdentityAttributes(); 
+			}catch(e){ 
+	 		// some store are not requiring an item instance to give us the ID attributes 
+	 		// but some other do and throw errors in that case. 
+			} 
+			// if no idAttribute we have implicit id 
+			this.idProperty = (!idAttribute || !idAttributes[0]) || this.idProperty; 
+		}
+		var features = this.store.getFeatures();
+		// check the feature set and null out any methods that shouldn't be available
+		if(!features["dojo.data.api.Read"]){
+			this.get = null;
+		}
+		if(!features["dojo.data.api.Identity"]){
+			this.getIdentity = null;
+		}
+		if(!features["dojo.data.api.Write"]){
+			this.put = this.add = null;
+		}
 	},
+	// idProperty: String
+	//		The object property to use to store the identity of the store items.
+	idProperty: "id",
+	// store:
+	//		The object store to convert to a data store
+	store: null,
 	_objectConverter: function(callback){
 		var store = this.store;
+		var idProperty = this.idProperty;
 		return function(item){
 			var object = {};
 			var attributes = store.getAttributes(item);
 			for(var i = 0; i < attributes.length; i++){
 				object[attributes[i]] = store.getValue(item, attributes[i]);
 			}
+			if(!(idProperty in object)){
+				object[idProperty] = store.getIdentity(item);
+			}
 			return callback(object);
 		};
 	},
@@ -29,7 +67,7 @@ dojo.declare("dojo.store.DataStore", null, {
 		// id: Object?
 		//		The identity to use to lookup the object
 		var returnedObject, returnedError;
-		var deferred = new dojo.Deferred();
+		var deferred = new Deferred();
 		this.store.fetchItemByIdentity({
 			identity: id,
 			onItem: this._objectConverter(function(object){
@@ -58,6 +96,7 @@ dojo.declare("dojo.store.DataStore", null, {
 		//		that the object may be stored with (i.e. { id: "foo" }).
 		var id = options && typeof options.id != "undefined" || this.getIdentity(object);
 		var store = this.store;
+		var idProperty = this.idProperty;
 		if(typeof id == "undefined"){
 			store.newItem(object);
 		}else{
@@ -66,7 +105,8 @@ dojo.declare("dojo.store.DataStore", null, {
 				onItem: function(item){
 					if(item){
 						for(var i in object){
-							if(store.getValue(item, i) != object[i]){
+							if(i != idProperty && // don't copy id properties since they are immutable and should be omitted for implicit ids 
+									store.getValue(item, i) != object[i]){
 								store.setValue(item, i, object[i]);
 							}
 						}
@@ -99,23 +139,23 @@ dojo.declare("dojo.store.DataStore", null, {
 		//		Optional options object as used by the underlying dojo.data Store.
 		// returns: dojo.store.util.QueryResults
 		//		A query results object that can be used to iterate over results.
-		var returnedObject, returnedError;
-		var deferred = new dojo.Deferred();
-		deferred.total = new dojo.Deferred();
+		var fetchHandle;
+		var deferred = new Deferred(function(){ fetchHandle.abort && fetchHandle.abort(); });
+		deferred.total = new Deferred();
 		var converter = this._objectConverter(function(object){return object;});
-		this.store.fetch(dojo.mixin({
+		fetchHandle = this.store.fetch(lang.mixin({
 			query: query,
 			onBegin: function(count){
 				deferred.total.resolve(count);
 			},
 			onComplete: function(results){
-				deferred.resolve(dojo.map(results, converter));
+				deferred.resolve(array.map(results, converter));
 			},
 			onError: function(error){
 				deferred.reject(error);
 			}
 		}, options));
-		return dojo.store.util.QueryResults(deferred);
+		return QueryResults(deferred);
 	},
 	getIdentity: function(object){
 		// summary:
@@ -124,9 +164,7 @@ dojo.declare("dojo.store.DataStore", null, {
 		//		The data object to get the identity from.
 		// returns: Number
 		//		The id of the given object.
-		return object[this.idProperty || this.store.getIdentityAttributes()[0]];
+		return object[this.idProperty];
 	}
 });
-
-return dojo.store.DataStore;
 });
diff --git a/dojo/store/JsonRest.js b/dojo/store/JsonRest.js
index 05723fe..e2082f4 100644
--- a/dojo/store/JsonRest.js
+++ b/dojo/store/JsonRest.js
@@ -1,13 +1,22 @@
-define("dojo/store/JsonRest", ["dojo", "dojo/store/util/QueryResults"], function(dojo) {
+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, {
+	// summary:
+	//		This is a basic store for RESTful communicating with a server through JSON
+	//		formatted data. It implements dojo.store.api.Store.
 
-dojo.declare("dojo.store.JsonRest", null, {
 	constructor: function(/*dojo.store.JsonRest*/ options){
 		// summary:
 		//		This is a basic store for RESTful communicating with a server through JSON
 		//		formatted data.
 		// options:
 		//		This provides any configuration information that will be mixed into the store
-		dojo.mixin(this, options);
+		declare.safeMixin(this, options);
 	},
 	// target: String
 	//		The target base URL to use for all requests to the server. This string will be
@@ -18,7 +27,11 @@ dojo.declare("dojo.store.JsonRest", null, {
 	//		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.
+	
 	get: function(id, options){
 		//	summary:
 		//		Retrieves an object by its identity. This will trigger a GET request to the server using
@@ -28,13 +41,16 @@ dojo.declare("dojo.store.JsonRest", null, {
 		//	returns: Object
 		//		The object in the store that matches the given id.
 		var headers = options || {};
-		headers.Accept = "application/javascript, application/json";
-		return dojo.xhrGet({
+		headers.Accept = this.accepts;
+		return xhr("GET", {
 			url:this.target + id,
 			handleAs: "json",
 			headers: headers
 		});
 	},
+	// accepts: String
+	//		Defines the Accept header to use on HTTP requests
+	accepts: "application/javascript, application/json", 
 	getIdentity: function(object){
 		// summary:
 		//		Returns an object's identity
@@ -56,12 +72,13 @@ dojo.declare("dojo.store.JsonRest", null, {
 		options = options || {};
 		var id = ("id" in options) ? options.id : this.getIdentity(object);
 		var hasId = typeof id != "undefined";
-		return dojo.xhr(hasId && !options.incremental ? "PUT" : "POST", {
+		return xhr(hasId && !options.incremental ? "PUT" : "POST", {
 				url: hasId ? this.target + id : this.target,
-				postData: dojo.toJson(object),
+				postData: JSON.stringify(object),
 				handleAs: "json",
 				headers:{
 					"Content-Type": "application/json",
+					Accept: this.accepts,
 					"If-Match": options.overwrite === true ? "*" : null,
 					"If-None-Match": options.overwrite === false ? "*" : null
 				}
@@ -85,7 +102,7 @@ dojo.declare("dojo.store.JsonRest", null, {
 		//		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 dojo.xhrDelete({
+		return xhr("DELETE",{
 			url:this.target + id
 		});
 	},
@@ -95,11 +112,11 @@ dojo.declare("dojo.store.JsonRest", null, {
 		//		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: 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.
-		var headers = {Accept: "application/javascript, application/json"};
+		var headers = {Accept: this.accepts};
 		options = options || {};
 
 		if(options.start >= 0 || options.count >= 0){
@@ -107,19 +124,22 @@ dojo.declare("dojo.store.JsonRest", null, {
 				(("count" in options && options.count != Infinity) ?
 					(options.count + (options.start || 0) - 1) : '');
 		}
-		if(dojo.isObject(query)){
-			query = dojo.objectToQuery(query);
+		if(query && typeof query == "object"){
+			query = xhr.objectToQuery(query);
 			query = query ? "?" + query: "";
 		}
 		if(options && options.sort){
-			query += (query ? "&" : "?") + "sort(";
+			var sortParam = this.sortParam;
+			query += (query ? "&" : "?") + (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 += ")";
+			if(!sortParam){
+				query += ")";
+			}
 		}
-		var results = dojo.xhrGet({
+		var results = xhr("GET", {
 			url: this.target + (query || ""),
 			handleAs: "json",
 			headers: headers
@@ -128,9 +148,8 @@ dojo.declare("dojo.store.JsonRest", null, {
 			var range = results.ioArgs.xhr.getResponseHeader("Content-Range");
 			return range && (range=range.match(/\/(.*)/)) && +range[1];
 		});
-		return dojo.store.util.QueryResults(results);
+		return QueryResults(results);
 	}
 });
 
-return dojo.store.JsonRest;
 });
\ No newline at end of file
diff --git a/dojo/store/Memory.js b/dojo/store/Memory.js
index 87e57cb..6824d5f 100644
--- a/dojo/store/Memory.js
+++ b/dojo/store/Memory.js
@@ -1,6 +1,11 @@
-define("dojo/store/Memory", ["dojo", "dojo/store/util/QueryResults", "dojo/store/util/SimpleQueryEngine"], function(dojo) {
+define(["../_base/declare", "./util/QueryResults", "./util/SimpleQueryEngine"], function(declare, QueryResults, SimpleQueryEngine) {
+  //  module:
+  //    dojo/store/Memory
+  //  summary:
+  //    The module defines an in-memory object store.
 
-dojo.declare("dojo.store.Memory", null, {
+
+return declare("dojo.store.Memory", null, {
 	// summary:
 	//		This is a basic in-memory object store. It implements dojo.store.api.Store.
 	constructor: function(/*dojo.store.Memory*/ options){
@@ -9,8 +14,9 @@ dojo.declare("dojo.store.Memory", null, {
 		// options:
 		//		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.index = {};
-		dojo.mixin(this, options);
+		for(var i in options){
+			this[i] = options[i];
+		}
 		this.setData(this.data || []);
 	},
 	// data: Array
@@ -23,12 +29,12 @@ dojo.declare("dojo.store.Memory", null, {
 	idProperty: "id",
 
 	// index: Object
-	//		An index of data by id
+	//		An index of data indices into the data array by id
 	index:null,
 
 	// queryEngine: Function
 	//		Defines the query engine to use for querying the data store
-	queryEngine: dojo.store.util.SimpleQueryEngine,
+	queryEngine: SimpleQueryEngine,
 	get: function(id){
 		//	summary:
 		//		Retrieves an object by its identity
@@ -36,7 +42,7 @@ dojo.declare("dojo.store.Memory", null, {
 		//		The identity to use to lookup the object
 		//	returns: Object
 		//		The object in the store that matches the given id.
-		return this.index[id];
+		return this.data[this.index[id]];
 	},
 	getIdentity: function(object){
 		// 	summary:
@@ -55,17 +61,21 @@ dojo.declare("dojo.store.Memory", null, {
 		//		Additional metadata for storing the data.  Includes an "id"
 		//		property if a specific id is to be used.
 		//	returns: Number
-		var id = options && options.id || object[this.idProperty] || Math.random();
-		this.index[id] = object;
 		var data = this.data,
+			index = this.index,
 			idProperty = this.idProperty;
-		for(var i = 0, l = data.length; i < l; i++){
-			if(data[i][idProperty] == id){
-				data[i] = object;
-				return id;
+		var id = (options && "id" in options) ? options.id : idProperty in object ? object[idProperty] : Math.random();
+		if(id in index){
+			// object exists
+			if(options && options.overwrite === false){
+				throw new Error("Object already exists");
 			}
+			// replace the entry in data
+			data[index[id]] = object;
+		}else{
+			// add the new object
+			index[id] = data.push(object) - 1;
 		}
-		this.data.push(object);
 		return id;
 	},
 	add: function(object, options){
@@ -77,9 +87,8 @@ dojo.declare("dojo.store.Memory", null, {
 		//		Additional metadata for storing the data.  Includes an "id"
 		//		property if a specific id is to be used.
 		//	returns: Number
-		if(this.index[options && options.id || object[this.idProperty]]){
-			throw new Error("Object already exists");
-		}
+		(options = options || {}).overwrite = false;
+		// call put with overwrite being false
 		return this.put(object, options);
 	},
 	remove: function(id){
@@ -87,14 +96,15 @@ dojo.declare("dojo.store.Memory", null, {
 		//		Deletes an object by its identity
 		// 	id: Number
 		//		The identity to use to delete the object
-		delete this.index[id];
-		var data = this.data,
-			idProperty = this.idProperty;
-		for(var i = 0, l = data.length; i < l; i++){
-			if(data[i][idProperty] == id){
-				data.splice(i, 1);
-				return;
-			}
+		// returns: Boolean
+		// 		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){
+			data.splice(index[id], 1);
+			// now we have to reindex
+			this.setData(data);
+			return true;
 		}
 	},
 	query: function(query, options){
@@ -127,7 +137,7 @@ dojo.declare("dojo.store.Memory", null, {
 		//	...or find all items where "even" is true:
 		//
 		//	|	var results = store.query({ even: true });
-		return dojo.store.util.QueryResults(this.queryEngine(query, options)(this.data));
+		return QueryResults(this.queryEngine(query, options)(this.data));
 	},
 	setData: function(data){
 		// 	summary:
@@ -141,13 +151,11 @@ dojo.declare("dojo.store.Memory", null, {
 		}else{
 			this.data = data;
 		}
-
+		this.index = {};
 		for(var i = 0, l = data.length; i < l; i++){
-			var object = data[i];
-			this.index[object[this.idProperty]] = object;
+			this.index[data[i][this.idProperty]] = i;
 		}
 	}
 });
 
-return dojo.store.Memory;
 });
diff --git a/dojo/store/Observable.js b/dojo/store/Observable.js
index c3d23b0..4517353 100644
--- a/dojo/store/Observable.js
+++ b/dojo/store/Observable.js
@@ -1,7 +1,13 @@
-define("dojo/store/Observable", ["dojo"], function(dojo) {
-dojo.getObject("store", true, dojo);
+define(["../_base/kernel", "../_base/lang", "../_base/Deferred", "../_base/array"
+], function(kernel, lang, Deferred, array) {
+	// module:
+	//		dojo/store/Observable
+	// summary:
+	//		TODOC
+
+var ds = lang.getObject("dojo.store", true);
 
-dojo.store.Observable = function(store){
+return ds.Observable = function(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.
@@ -30,7 +36,7 @@ dojo.store.Observable = function(store){
 	//
 	//		See the Observable tests for more information.
 
-	var queryUpdaters = [], revision = 0;
+	var undef, queryUpdaters = [], revision = 0;
 	// a Comet driven store could directly call notify to notify observers when data has
 	// changed on the backend
 	store.notify = function(object, existingId){
@@ -45,7 +51,7 @@ dojo.store.Observable = function(store){
 		options = options || {};
 		var results = originalQuery.apply(this, arguments);
 		if(results && results.forEach){
-			var nonPagedOptions = dojo.mixin({}, options);
+			var nonPagedOptions = lang.mixin({}, options);
 			delete nonPagedOptions.start;
 			delete nonPagedOptions.count;
 
@@ -56,14 +62,14 @@ dojo.store.Observable = function(store){
 				if(listeners.push(listener) == 1){
 					// first listener was added, create the query checker and updater
 					queryUpdaters.push(queryUpdater = function(changed, existingId){
-						dojo.when(results, function(resultsArray){
+						Deferred.when(results, function(resultsArray){
 							var atEnd = resultsArray.length != options.count;
-							var i;
+							var i, l, listener;
 							if(++queryRevision != revision){
 								throw new Error("Query is out of date, you must observe() the query prior to any data modifications");
 							}
 							var removedObject, removedFrom = -1, insertedInto = -1;
-							if(existingId){
+							if(existingId !== undef){
 								// remove the old one
 								for(i = 0, l = resultsArray.length; i < l; i++){
 									var object = resultsArray[i];
@@ -83,20 +89,23 @@ dojo.store.Observable = function(store){
 										// if a matches function exists, use that (probably more efficient)
 										(queryExecutor.matches ? queryExecutor.matches(changed) : queryExecutor([changed]).length)){
 
-									if(removedFrom > -1){
-										// put back in the original slot so it doesn't move unless it needs to (relying on a stable sort below)
-										resultsArray.splice(removedFrom, 0, changed);
-									}else{
-										resultsArray.push(changed);
-									}
-									insertedInto = dojo.indexOf(queryExecutor(resultsArray), changed);
+									var firstInsertedInto = removedFrom > -1 ? 
+										removedFrom : // put back in the original slot so it doesn't move unless it needs to (relying on a stable sort below)
+										resultsArray.length;
+									resultsArray.splice(firstInsertedInto, 0, changed); // add the new item
+									insertedInto = array.indexOf(queryExecutor(resultsArray), changed); // sort it
+									// we now need to push the chagne back into the original results array
+									resultsArray.splice(firstInsertedInto, 1); // remove the inserted item from the previous index
+									
 									if((options.start && insertedInto == 0) ||
-										(!atEnd && insertedInto == resultsArray.length -1)){
+										(!atEnd && insertedInto == resultsArray.length)){
 										// if it is at the end of the page, assume it goes into the prev or next page
 										insertedInto = -1;
+									}else{
+										resultsArray.splice(insertedInto, 0, changed); // and insert into the results array with the correct index
 									}
 								}
-							}else if(changed){
+							}else if(changed && !options.start){
 								// 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);
@@ -114,11 +123,14 @@ dojo.store.Observable = function(store){
 				return {
 					cancel: function(){
 						// remove this listener
-						listeners.splice(dojo.indexOf(listeners, listener), 1);
-						if(!listeners.length){
-							// no more listeners, remove the query updater too
-							queryUpdaters.splice(dojo.indexOf(queryUpdaters, queryUpdater), 1);
-						}
+						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);
+							}
+						}						
 					}
 				};
 			};
@@ -136,10 +148,11 @@ dojo.store.Observable = function(store){
 				}
 				inMethod = true;
 				try{
-					return dojo.when(original.apply(this, arguments), function(results){
+					var results = original.apply(this, arguments);
+					Deferred.when(results, function(results){
 						action((typeof results == "object" && results) || value);
-						return results;
 					});
+					return results;
 				}finally{
 					inMethod = false;
 				}
@@ -159,6 +172,4 @@ dojo.store.Observable = function(store){
 
 	return store;
 };
-
-return dojo.store.Observable;
 });
diff --git a/dojo/store/api/Store.js b/dojo/store/api/Store.js
index f48f821..f16a836 100644
--- a/dojo/store/api/Store.js
+++ b/dojo/store/api/Store.js
@@ -1,297 +1,297 @@
-define([], function() {
-  //  module:
-  //    dojo/store/api/Store
-  //  summary:
-  //    The module defines the Dojo object store interface.
-
-dojo.declare("dojo.store.api.Store", 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,
-	//		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.
-	//		Every method may return a promise for the specified return value if the 
-	// 		execution of the operation is asynchronous (except
-	//		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 
-	// 		identity property. The values of this property should be unique.
-	idProperty: "id",
-
-	// queryEngine: Function
-	//		If the store can be queried locally (on the client side in JS), this defines 
-	// 		the query engine to use for querying the data store. 
-	//		This takes a query and query options and returns a function that can execute 
-	// 		the provided query on a JavaScript array. The queryEngine may be replace to 
-	// 		provide more sophisticated querying capabilities. For example:
-	// 		| var query = store.queryEngine({foo:"bar"}, {count:10});
-	//		| query(someArray) -> filtered array
-	// 		The returned query function may have a "matches" property that can be 
-	// 		used to determine if an object matches the query. For example:
-	//		| query.matches({id:"some-object", foo:"bar"}) -> true
-	//		| query.matches({id:"some-object", foo:"something else"}) -> false
-	queryEngine: null,
-
-	get: function(id){
-		//	summary:
-		//		Retrieves an object by its identity
-		//	id: Number
-		//		The identity to use to lookup the object
-		//	returns: Object
-		//		The object in the store that matches the given id.
-	},
-	getIdentity: function(object){
-		// 	summary:
-		//		Returns an object's identity
-		// 	object: Object
-		//		The object to get the identity from
-		//	returns: String|Number
-	},
-	put: function(object, directives){
-		// 	summary:
-		//		Stores an object
-		// 	object: Object
-		//		The object to store.
-		// directives: dojo.store.api.Store.PutDirectives?
-		//		Additional directives for storing objects.
-		//	returns: Number|String
-	},
-	add: function(object, directives){
-		// 	summary:
-		//		Creates an object, throws an error if the object already exists
-		// 	object: Object
-		//		The object to store.
-		// directives: dojo.store.api.Store.PutDirectives?
-		//		Additional directives for creating objects.
-		//	returns: Number|String
-	},
-	remove: function(id){
-		// 	summary:
-		//		Deletes an object by its identity
-		// 	id: Number
-		//		The identity to use to delete the object
-		delete this.index[id];
-		var data = this.data,
-			idProperty = this.idProperty;
-		for(var i = 0, l = data.length; i < l; i++){
-			if(data[i][idProperty] == id){
-				data.splice(i, 1);
-				return;
-			}
-		}
-	},
-	query: function(query, options){
-		// 	summary:
-		//		Queries the store for objects. This does not alter the store, but returns a 
-		//		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
-		//		The optional arguments to apply to the resultset.
-		//	returns: dojo.store.api.Store.QueryResults
-		//		The results of the query, extended with iterative methods.
-		//
-		// 	example:
-		// 		Given the following store:
-		//
-		//	...find all items where "prime" is true:
-		//
-		//	|	store.query({ prime: true }).forEach(function(object){
-		//	|		// handle each object
-		//	|	});
-	},
-	transaction: function(){
-		// summary:
-		// 		Starts a new transaction.
-		//		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
-		//		This represents the new current transaction.
-	},
-	getChildren: function(parent, options){
-		//	summary:
-		//		Retrieves the children of an object.
-		// parent: Object
-		// 		The object to find the children of.
-		// options: dojo.store.api.Store.QueryOptions?
-		// 		Additional options to apply to the retrieval of the children.
-		// returns: dojo.store.api.Store.QueryResults
-		// 		A result set of the children of the parent object. 
-	},
-	getMetadata: function(object){
-		// summary:
-		//		Returns any metadata about the object. This may include attribution, 
-		// 		cache directives, history, or version information.
-		//	object: Object
-		//		The object to return metadata for.
-		//	returns: Object
-		//		An object containing metadata.
-	}
-});
-
-dojo.store.api.Store.PutDirectives = function(id, before, parent, overwrite){
-	// summary:
-	//		Directives passed to put() and add() handlers for guiding the update and 
-	// 		creation of stored objects.  
-	// id: String|Number?
-	// 		Indicates the identity of the object if a new object is created
-	// before: Object?
-	//		If the collection of objects in the store has a natural ordering, 
-	// 		this indicates that the created or updated object should be placed before the 
-	//		object specified by the value of this property. A value of null indicates that the 
-	//		object should be last.
-	// parent: Object?,
-	//		If the store is hierarchical (with single parenting) this property indicates the 
-	// 		new parent of the created or updated object.
-	// overwrite: Boolean?
-	//		If this is provided as a boolean it indicates that the object should or should not 
-	// 		overwrite an existing object. A value of true indicates that a new object 
-	// 		should not be created, the operation should update an existing object. A 
-	// 		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;
-};
-
-dojo.store.api.Store.SortInformation = function(attribute, descending){
-	// 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;
-};
-
-dojo.store.api.Store.QueryOptions = function(sort, start, count){
-	// summary:
-	//		Optional object with additional parameters for query results.
-	// sort: dojo.store.api.Store.SortInformation[]?
-	//		A list of attributes to sort on, as well as direction
-	//		For example: 
-	// 		| [{attribute:"price, descending: true}]. 
-	// 		If the sort parameter is omitted, then the natural order of the store may be 
-	// 		applied if there is a natural order.	
-	// start: Number?
-	//		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;
-};
-
-dojo.declare("dojo.store.api.Store.QueryResults", null, {
-	// summary:
-	//		This is an object returned from query() calls that provides access to the results 
-	// 		of a query. Queries may be executed asynchronously.
-	
-	forEach: function(callback, thisObject){
-		// summary:
-		//		Iterates over the query results, based on 
-		// 		https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach.
-		//		Note that this may executed asynchronously. The callback may be called
-		//		after this function returns.
-		//	callback:
-		//		Function that is called for each object in the query results
-		//	thisObject:
-		//		The object to use as |this| in the callback.
-		
-	},
-	filter: function(callback, thisObject){
-		// summary:
-		//		Filters the query results, based on 
-		// 		https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter.
-		//		Note that this may executed asynchronously. The callback may be called
-		//		after this function returns.
-		//	callback:
-		//		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
-	},
-	map: function(callback, thisObject){
-		// summary:
-		//		Maps the query results, based on 
-		// 		https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map.
-		//		Note that this may executed asynchronously. The callback may be called
-		//		after this function returns.
-		//	callback:
-		//		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
-	},
-	then: function(callback, errorHandler){
-		// summary:
-		//		This registers a callback for when the query is complete, if the query is asynchronous.
-		//		This is an optional method, and may not be present for synchronous queries.
-		//	callback:
-		//		This is called when the query is completed successfully, and is passed a single argument 
-		// 		that is an array representing the query results.
-		//	errorHandler:
-		//		This is called if the query failed, and is passed a single argument that is the error
-		//		for the failure.
-	},
-	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.
-		//	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: 
-		// 		| 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 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 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).
-		//	includeAllUpdates:
-		//		This indicates whether or not to include object updates that do not affect
-		//		the inclusion or order of the object in the query results. By default this is false,
-		//		which means that if any object is updated in such a way that it remains
-		//		in the result set and it's position in result sets is not affected, then the listener 
-		// 		will not be fired. 
-		
-	},
-	// total: Number|Promise?
-	//		This property should be included in if the query options included the "count" 
-	// 		property limiting the result set. This property indicates the total number of objects
-	// 		matching the query (as if "start" and "count" weren't present). This may be
-	//		a promise if the query is asynchronous.
-	total: 0 
-});
-
-dojo.declare("dojo.store.api.Store.Transaction", null, {
-	// summary:
-	//		This is an object returned from transaction() calls that represents the current
-	// 		transaction.
-	
-	commit: function(){
-		// summary:
-		//		Commits the transaction. This may throw an error if it fails. Of if the operation
-		// 		is asynchronous, it may return a promise that represents the eventual success
-		//		or failure of the commit.		
-	},
-	abort: function(callback, thisObject){
-		// summary:
-		//		Aborts the transaction. This may throw an error if it fails. Of if the operation
-		// 		is asynchronous, it may return a promise that represents the eventual success
-		//		or failure of the abort.
-	}
-});
-	
-});
+define(["dojo/_base/declare"], function(declare) {
+	// module:
+	//		dojo/store/api/Store
+	// summary:
+	//		The module defines the Dojo object store interface.
+
+var Store = declare("dojo.store.api.Store", 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,
+	//		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.
+	//		Every method may return a promise for the specified return value if the
+	//		execution of the operation is asynchronous (except
+	//		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
+	//		identity property. The values of this property should be unique.
+	idProperty: "id",
+
+	// queryEngine: Function
+	//		If the store can be queried locally (on the client side in JS), this defines
+	//		the query engine to use for querying the data store.
+	//		This takes a query and query options and returns a function that can execute
+	//		the provided query on a JavaScript array. The queryEngine may be replace to
+	//		provide more sophisticated querying capabilities. For example:
+	//		| var query = store.queryEngine({foo:"bar"}, {count:10});
+	//		| query(someArray) -> filtered array
+	//		The returned query function may have a "matches" property that can be
+	//		used to determine if an object matches the query. For example:
+	//		| query.matches({id:"some-object", foo:"bar"}) -> true
+	//		| query.matches({id:"some-object", foo:"something else"}) -> false
+	queryEngine: null,
+
+	get: function(id){
+		// summary:
+		//		Retrieves an object by its identity
+		// id: Number
+		//		The identity to use to lookup the object
+		// returns: Object
+		//		The object in the store that matches the given id.
+	},
+	getIdentity: function(object){
+		// summary:
+		//		Returns an object's identity
+		// object: Object
+		//		The object to get the identity from
+		// returns: String|Number
+	},
+	put: function(object, directives){
+		// summary:
+		//		Stores an object
+		// object: Object
+		//		The object to store.
+		// directives: dojo.store.api.Store.PutDirectives?
+		//		Additional directives for storing objects.
+		// returns: Number|String
+	},
+	add: function(object, directives){
+		// summary:
+		//		Creates an object, throws an error if the object already exists
+		// object: Object
+		//		The object to store.
+		// directives: dojo.store.api.Store.PutDirectives?
+		//		Additional directives for creating objects.
+		// returns: Number|String
+	},
+	remove: function(id){
+		// summary:
+		//		Deletes an object by its identity
+		// id: Number
+		//		The identity to use to delete the object
+		delete this.index[id];
+		var data = this.data,
+			idProperty = this.idProperty;
+		for(var i = 0, l = data.length; i < l; i++){
+			if(data[i][idProperty] == id){
+				data.splice(i, 1);
+				return;
+			}
+		}
+	},
+	query: function(query, options){
+		// summary:
+		//		Queries the store for objects. This does not alter the store, but returns a
+		//		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
+		//		The optional arguments to apply to the resultset.
+		// returns: dojo.store.api.Store.QueryResults
+		//		The results of the query, extended with iterative methods.
+		//
+		// example:
+		//		Given the following store:
+		//
+		//	...find all items where "prime" is true:
+		//
+		//	|	store.query({ prime: true }).forEach(function(object){
+		//	|		// handle each object
+		//	|	});
+	},
+	transaction: function(){
+		// summary:
+		//		Starts a new transaction.
+		//		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
+		//		This represents the new current transaction.
+	},
+	getChildren: function(parent, options){
+		// summary:
+		//		Retrieves the children of an object.
+		// parent: Object
+		//		The object to find the children of.
+		// options: dojo.store.api.Store.QueryOptions?
+		//		Additional options to apply to the retrieval of the children.
+		// returns: dojo.store.api.Store.QueryResults
+		//		A result set of the children of the parent object.
+	},
+	getMetadata: function(object){
+		// summary:
+		//		Returns any metadata about the object. This may include attribution,
+		//		cache directives, history, or version information.
+		// object: Object
+		//		The object to return metadata for.
+		// returns: Object
+		//		An object containing metadata.
+	}
+});
+
+Store.PutDirectives = function(id, before, parent, overwrite){
+	// summary:
+	//		Directives passed to put() and add() handlers for guiding the update and
+	//		creation of stored objects.
+	// id: String|Number?
+	//		Indicates the identity of the object if a new object is created
+	// before: Object?
+	//		If the collection of objects in the store has a natural ordering,
+	//		this indicates that the created or updated object should be placed before the
+	//		object specified by the value of this property. A value of null indicates that the
+	//		object should be last.
+	// parent: Object?,
+	//		If the store is hierarchical (with single parenting) this property indicates the
+	//		new parent of the created or updated object.
+	// overwrite: Boolean?
+	//		If this is provided as a boolean it indicates that the object should or should not
+	//		overwrite an existing object. A value of true indicates that a new object
+	//		should not be created, the operation should update an existing object. A
+	//		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){
+	// 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){
+	// summary:
+	//		Optional object with additional parameters for query results.
+	// sort: dojo.store.api.Store.SortInformation[]?
+	//		A list of attributes to sort on, as well as direction
+	//		For example:
+	//		| [{attribute:"price, descending: true}].
+	//		If the sort parameter is omitted, then the natural order of the store may be
+	//		applied if there is a natural order.
+	// start: Number?
+	//		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, {
+	// summary:
+	//		This is an object returned from query() calls that provides access to the results
+	//		of a query. Queries may be executed asynchronously.
+
+	forEach: function(callback, thisObject){
+		// summary:
+		//		Iterates over the query results, based on
+		//		https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach.
+		//		Note that this may executed asynchronously. The callback may be called
+		//		after this function returns.
+		// callback:
+		//		Function that is called for each object in the query results
+		// thisObject:
+		//		The object to use as |this| in the callback.
+
+	},
+	filter: function(callback, thisObject){
+		// summary:
+		//		Filters the query results, based on
+		//		https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter.
+		//		Note that this may executed asynchronously. The callback may be called
+		//		after this function returns.
+		// callback:
+		//		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
+	},
+	map: function(callback, thisObject){
+		// summary:
+		//		Maps the query results, based on
+		//		https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map.
+		//		Note that this may executed asynchronously. The callback may be called
+		//		after this function returns.
+		// callback:
+		//		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
+	},
+	then: function(callback, errorHandler){
+		// summary:
+		//		This registers a callback for when the query is complete, if the query is asynchronous.
+		//		This is an optional method, and may not be present for synchronous queries.
+		// callback:
+		//		This is called when the query is completed successfully, and is passed a single argument
+		//		that is an array representing the query results.
+		// errorHandler:
+		//		This is called if the query failed, and is passed a single argument that is the error
+		//		for the failure.
+	},
+	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.
+		// 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:
+		//		| 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 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 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).
+		// includeAllUpdates:
+		//		This indicates whether or not to include object updates that do not affect
+		//		the inclusion or order of the object in the query results. By default this is false,
+		//		which means that if any object is updated in such a way that it remains
+		//		in the result set and it's position in result sets is not affected, then the listener
+		//		will not be fired.
+
+	},
+	// total: Number|Promise?
+	//		This property should be included in if the query options included the "count"
+	//		property limiting the result set. This property indicates the total number of objects
+	//		matching the query (as if "start" and "count" weren't present). This may be
+	//		a promise if the query is asynchronous.
+	total: 0
+});
+
+declare("dojo.store.api.Store.Transaction", null, {
+	// summary:
+	//		This is an object returned from transaction() calls that represents the current
+	//		transaction.
+
+	commit: function(){
+		// summary:
+		//		Commits the transaction. This may throw an error if it fails. Of if the operation
+		//		is asynchronous, it may return a promise that represents the eventual success
+		//		or failure of the commit.
+	},
+	abort: function(callback, thisObject){
+		// summary:
+		//		Aborts the transaction. This may throw an error if it fails. Of if the operation
+		//		is asynchronous, it may return a promise that represents the eventual success
+		//		or failure of the abort.
+	}
+});
+return Store;
+});
diff --git a/dojo/store/util/QueryResults.js b/dojo/store/util/QueryResults.js
index 139152f..f1ee949 100644
--- a/dojo/store/util/QueryResults.js
+++ b/dojo/store/util/QueryResults.js
@@ -1,7 +1,13 @@
-define("dojo/store/util/QueryResults", ["dojo"], function(dojo) {
-dojo.getObject("store.util", true, dojo);
+define(["../../_base/array", "../../_base/lang", "../../_base/Deferred"
+], function(array, lang, Deferred) {
+  //  module:
+  //    dojo/store/util/QueryResults
+  //  summary:
+  //    The module defines a query results wrapper
 
-dojo.store.util.QueryResults = function(results){
+var util = lang.getObject("dojo.store.util", true);
+
+util.QueryResults = function(results){
 	// summary:
 	//		A function that wraps the results of a store query with additional
 	//		methods.
@@ -24,21 +30,21 @@ dojo.store.util.QueryResults = function(results){
 	//	|	store.query({ prime: true }).forEach(function(item){
 	//	|		//	do something
 	//	|	});
-	
+
 	if(!results){
 		return results;
 	}
 	// if it is a promise it may be frozen
 	if(results.then){
-		results = dojo.delegate(results);
+		results = lang.delegate(results);
 	}
 	function addIterativeMethod(method){
 		if(!results[method]){
 			results[method] = function(){
 				var args = arguments;
-				return dojo.when(results, function(results){
+				return Deferred.when(results, function(results){
 					Array.prototype.unshift.call(args, results);
-					return dojo.store.util.QueryResults(dojo[method].apply(dojo, args));
+					return util.QueryResults(array[method].apply(array, args));
 				});
 			};
 		}
@@ -47,12 +53,12 @@ dojo.store.util.QueryResults = function(results){
 	addIterativeMethod("filter");
 	addIterativeMethod("map");
 	if(!results.total){
-		results.total = dojo.when(results, function(results){
+		results.total = Deferred.when(results, function(results){
 			return results.length;
 		});
 	}
 	return results;
 };
 
-return dojo.store.util.QueryResults;
+return util.QueryResults;
 });
diff --git a/dojo/store/util/SimpleQueryEngine.js b/dojo/store/util/SimpleQueryEngine.js
index b747a5f..2b1c262 100644
--- a/dojo/store/util/SimpleQueryEngine.js
+++ b/dojo/store/util/SimpleQueryEngine.js
@@ -1,7 +1,10 @@
-define("dojo/store/util/SimpleQueryEngine", ["dojo"], function(dojo) {
-dojo.getObject("store.util", true, dojo);
+define(["../../_base/array"], function(arrayUtil) {
+  //  module:
+  //    dojo/store/util/SimpleQueryEngine
+  //  summary:
+  //    The module defines a simple filtering query engine for object stores. 
 
-dojo.store.util.SimpleQueryEngine = function(query, options){
+return function(query, options){
 	// summary:
 	//		Simple query engine that matches using filter functions, named filter
 	//		functions or objects by name-value on a query object hash
@@ -77,7 +80,7 @@ dojo.store.util.SimpleQueryEngine = function(query, options){
 	}
 	function execute(array){
 		// execute the whole query, first we filter
-		var results = dojo.filter(array, query);
+		var results = arrayUtil.filter(array, query);
 		// next we sort
 		if(options && options.sort){
 			results.sort(function(a, b){
@@ -102,6 +105,4 @@ dojo.store.util.SimpleQueryEngine = function(query, options){
 	execute.matches = query;
 	return execute;
 };
-
-return dojo.store.util.SimpleQueryEngine;
 });
diff --git a/dojo/string.js b/dojo/string.js
index 545a418..767c122 100644
--- a/dojo/string.js
+++ b/dojo/string.js
@@ -1,5 +1,10 @@
-define("dojo/string", ["dojo"], function(dojo) {
-dojo.getObject("string", true, dojo);
+define(["./_base/kernel", "./_base/lang"], function(dojo, lang) {
+	// module:
+	//		dojo/string
+	// summary:
+	//		TODOC
+
+lang.getObject("string", true, dojo);
 
 /*=====
 dojo.string = {
@@ -8,15 +13,15 @@ dojo.string = {
 =====*/
 
 dojo.string.rep = function(/*String*/str, /*Integer*/num){
-	//	summary:
+	// summary:
 	//		Efficiently replicate a string `n` times.
-	//	str:
+	// str:
 	//		the string to replicate
-	//	num:
+	// num:
 	//		number of times to replicate the string
-	
+
 	if(num <= 0 || !str){ return ""; }
-	
+
 	var buf = [];
 	for(;;){
 		if(num & 1){
@@ -29,19 +34,19 @@ dojo.string.rep = function(/*String*/str, /*Integer*/num){
 };
 
 dojo.string.pad = function(/*String*/text, /*Integer*/size, /*String?*/ch, /*Boolean?*/end){
-	//	summary:
+	// 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
 	//		string. Pads at the start, by default.
-	//	text:
+	// text:
 	//		the string to pad
-	//	size:
+	// size:
 	//		length to provide padding
-	//	ch:
+	// ch:
 	//		character to pad, defaults to '0'
-	//	end:
+	// end:
 	//		adds padding at the end if true, otherwise pads at start
-	//	example:
+	// example:
 	//	|	// Fill the string to length 10 with "+" characters on the right.  Yields "Dojo++++++".
 	//	|	dojo.string.pad("Dojo", 10, "+", true);
 
@@ -57,21 +62,21 @@ dojo.string.substitute = function(	/*String*/		template,
 									/*Object|Array*/map,
 									/*Function?*/	transform,
 									/*Object?*/		thisObject){
-	//	summary:
+	// summary:
 	//		Performs parameterized substitutions on a string. Throws an
 	//		exception if any parameter is unmatched.
-	//	template:
+	// template:
 	//		a string with expressions in the form `${key}` to be replaced or
 	//		`${key:format}` which specifies a format function. keys are case-sensitive.
-	//	map:
+	// map:
 	//		hash to search for substitutions
-	//	transform:
+	// transform:
 	//		a function to process all parameters before substitution takes
 	//		place, e.g. mylib.encodeXML
-	//	thisObject:
+	// thisObject:
 	//		where to look for optional format function; default to the global
 	//		namespace
-	//	example:
+	// example:
 	//		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
@@ -87,7 +92,7 @@ dojo.string.substitute = function(	/*String*/		template,
 	//	|		"File '${name}' is not found in directory '${info.dir}'.",
 	//	|		{ name: "foo.html", info: { dir: "/temp" } }
 	//	|	);
-	//	example:
+	// example:
 	//		Use a transform function to modify the values:
 	//	|	// returns "file 'foo.html' is not found in directory '/temp'."
 	//	|	dojo.string.substitute(
@@ -99,7 +104,7 @@ dojo.string.substitute = function(	/*String*/		template,
 	//	|			return prefix + " '" + str + "'";
 	//	|		}
 	//	|	);
-	//	example:
+	// example:
 	//		Use a formatter
 	//	|	// returns "thinger -- howdy"
 	//	|	dojo.string.substitute(
@@ -112,13 +117,13 @@ dojo.string.substitute = function(	/*String*/		template,
 
 	thisObject = thisObject || dojo.global;
 	transform = transform ?
-		dojo.hitch(thisObject, transform) : function(v){ return v; };
+		lang.hitch(thisObject, transform) : function(v){ return v; };
 
 	return template.replace(/\$\{([^\s\:\}]+)(?:\:([^\s\:\}]+))?\}/g,
 		function(match, key, format){
-			var value = dojo.getObject(key, false, map);
+			var value = lang.getObject(key, false, map);
 			if(format){
-				value = dojo.getObject(format, false, thisObject).call(thisObject, value, key);
+				value = lang.getObject(format, false, thisObject).call(thisObject, value, key);
 			}
 			return transform(value, key).toString();
 		}); // String
@@ -126,13 +131,13 @@ dojo.string.substitute = function(	/*String*/		template,
 
 /*=====
 dojo.string.trim = function(str){
-	//	summary:
+	// summary:
 	//		Trims whitespace from both sides of the string
-	//	str: String
+	// str: String
 	//		String to be trimmed
-	//	returns: String
+	// returns: String
 	//		Returns the trimmed string
-	//	description:
+	// 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.
@@ -141,7 +146,7 @@ dojo.string.trim = function(str){
 =====*/
 
 dojo.string.trim = String.prototype.trim ?
-	dojo.trim : // aliasing to the native function
+	lang.trim : // aliasing to the native function
 	function(str){
 		str = str.replace(/^\s+/, '');
 		for(var i = str.length - 1; i >= 0; i--){
diff --git a/dojo/tests/AdapterRegistry.js b/dojo/tests/AdapterRegistry.js
index a471db8..e8c3c28 100644
--- a/dojo/tests/AdapterRegistry.js
+++ b/dojo/tests/AdapterRegistry.js
@@ -1,5 +1,4 @@
-dojo.provide("tests.AdapterRegistry");
-dojo.require("dojo.AdapterRegistry");
+define(["../main", "doh", "../AdapterRegistry"], function(dojo, doh){
 
 doh.register("tests.AdapterRegistry",
 	[
@@ -69,3 +68,5 @@ doh.register("tests.AdapterRegistry",
 		}
 	]
 );
+
+});
\ No newline at end of file
diff --git a/dojo/tests/DeferredList.js b/dojo/tests/DeferredList.js
index 0328bf6..f14d0f4 100644
--- a/dojo/tests/DeferredList.js
+++ b/dojo/tests/DeferredList.js
@@ -1,9 +1,5 @@
-dojo.provide("tests.DeferredList");
-
-dojo.require("dojo.DeferredList");
-
-doh.register("tests.DeferredList",
-	[
+define(["../main", "doh", "../DeferredList"], function(dojo, doh){
+	doh.register("tests.DeferredList", [
 		function callback(t){
 			var d1 = new dojo.Deferred();
 			var d2 = new dojo.Deferred();
@@ -60,143 +56,138 @@ doh.register("tests.DeferredList",
 		function mixed(t){
 			var d1 = new dojo.Deferred();
 			var d2 = new dojo.Deferred();
-            var dl = new dojo.DeferredList([d1, d2]);
-            var fired = false;
-            var e = new Error("foo");
+			var dl = new dojo.DeferredList([d1, d2]);
+			var fired = false;
+			var e = new Error("foo");
 
 			dl.addCallback(function(res){
 				doh.debug("debug from dojo.DeferredList callback");
 				return res;
 			});
 			dl.addCallback(function(res){
-                t.assertTrue(res.length == 2);
-                t.assertTrue(!res[0][0]);
+				t.assertTrue(res.length == 2);
+				t.assertTrue(!res[0][0]);
 
-                t.assertEqual(res[0][1], e);
-                t.assertTrue(res[1][0]);
-                t.assertEqual(res[1][1], "bar");
-                fired = true;
+				t.assertEqual(res[0][1], e);
+				t.assertTrue(res[1][0]);
+				t.assertEqual(res[1][1], "bar");
+				fired = true;
 				return res;
 			});
 			d1.errback(e);
 			d2.callback("bar");
-            t.assertTrue(fired);
+			t.assertTrue(fired);
 		},
 
-        function gather(t){
+		function gather(t){
 			var d1 = new dojo.Deferred();
 			var d2 = new dojo.Deferred();
-            var dl = dojo.DeferredList.prototype.gatherResults([d1, d2]);
-            var fired = false;
+			var dl = dojo.DeferredList.prototype.gatherResults([d1, d2]);
+			var fired = false;
 			dl.addCallback(function(res){
-                t.assertEqual(res[0], "foo");
-                t.assertEqual(res[1], "bar");
-                fired = true;
+				t.assertEqual(res[0], "foo");
+				t.assertEqual(res[1], "bar");
+				fired = true;
 				return res;
 			});
 			d1.callback("foo");
 			d2.callback("bar");
-            t.assertTrue(fired);
-        }
-	]
-);
-dojo.provide("tests.DeferredList");
-
-dojo.require("dojo.DeferredList");
+			t.assertTrue(fired);
+		}
+	]);
 
-doh.register("tests.DeferredList",
-	[
+	doh.register("tests.DeferredList", [
 		function callback(t){
 			var d1 = new dojo.Deferred();
 			var d2 = new dojo.Deferred();
-            var dl = new dojo.DeferredList([d1, d2]);
-            var fired = false;
+			var dl = new dojo.DeferredList([d1, d2]);
+			var fired = false;
 			dl.addCallback(function(res){
 				doh.debug("debug from dojo.DeferredList callback");
 				return res;
 			});
 			dl.addCallback(function(res){
-                t.assertTrue(res.length == 2);
-                t.assertTrue(res[0][0]);
-                t.assertEqual(res[0][1], "foo");
-                t.assertTrue(res[1][0]);
-                t.assertEqual(res[1][1], "bar");
-                fired = true;
+				t.assertTrue(res.length == 2);
+				t.assertTrue(res[0][0]);
+				t.assertEqual(res[0][1], "foo");
+				t.assertTrue(res[1][0]);
+				t.assertEqual(res[1][1], "bar");
+				fired = true;
 				return res;
 			});
 			d1.callback("foo");
 			d2.callback("bar");
-            t.assertTrue(fired);
+			t.assertTrue(fired);
 		},
 
 		function errback(t){
 			var d1 = new dojo.Deferred();
 			var d2 = new dojo.Deferred();
-            var dl = new dojo.DeferredList([d1, d2]);
-            var fired = false;
-            var e1 = new Error("foo");
-            var e2 = new Error("bar");
+			var dl = new dojo.DeferredList([d1, d2]);
+			var fired = false;
+			var e1 = new Error("foo");
+			var e2 = new Error("bar");
 
 			dl.addCallback(function(res){
 				doh.debug("debug from dojo.DeferredList callback");
 				return res;
 			});
 			dl.addCallback(function(res){
-                t.assertTrue(res.length == 2);
-                t.assertTrue(!res[0][0]);
+				t.assertTrue(res.length == 2);
+				t.assertTrue(!res[0][0]);
 
-                t.assertEqual(res[0][1], e1);
-                t.assertTrue(!res[1][0]);
-                t.assertEqual(res[1][1], e2);
-                fired = true;
+				t.assertEqual(res[0][1], e1);
+				t.assertTrue(!res[1][0]);
+				t.assertEqual(res[1][1], e2);
+				fired = true;
 				return res;
 			});
 			d1.errback(e1);
 			d2.errback(e2);
-            t.assertTrue(fired);
+			t.assertTrue(fired);
 		},
 
 
 		function mixed(t){
 			var d1 = new dojo.Deferred();
 			var d2 = new dojo.Deferred();
-            var dl = new dojo.DeferredList([d1, d2]);
-            var fired = false;
-            var e = new Error("foo");
+			var dl = new dojo.DeferredList([d1, d2]);
+			var fired = false;
+			var e = new Error("foo");
 
 			dl.addCallback(function(res){
 				doh.debug("debug from dojo.DeferredList callback");
 				return res;
 			});
 			dl.addCallback(function(res){
-                t.assertTrue(res.length == 2);
-                t.assertTrue(!res[0][0]);
+				t.assertTrue(res.length == 2);
+				t.assertTrue(!res[0][0]);
 
-                t.assertEqual(res[0][1], e);
-                t.assertTrue(res[1][0]);
-                t.assertEqual(res[1][1], "bar");
-                fired = true;
+				t.assertEqual(res[0][1], e);
+				t.assertTrue(res[1][0]);
+				t.assertEqual(res[1][1], "bar");
+				fired = true;
 				return res;
 			});
 			d1.errback(e);
 			d2.callback("bar");
-            t.assertTrue(fired);
+			t.assertTrue(fired);
 		},
 
-        function gather(t){
+		function gather(t){
 			var d1 = new dojo.Deferred();
 			var d2 = new dojo.Deferred();
-            var dl = dojo.DeferredList.prototype.gatherResults([d1, d2]);
-            var fired = false;
+			var dl = dojo.DeferredList.prototype.gatherResults([d1, d2]);
+			var fired = false;
 			dl.addCallback(function(res){
-                t.assertEqual(res[0], "foo");
-                t.assertEqual(res[1], "bar");
-                fired = true;
+				t.assertEqual(res[0], "foo");
+				t.assertEqual(res[1], "bar");
+				fired = true;
 				return res;
 			});
 			d1.callback("foo");
 			d2.callback("bar");
-            t.assertTrue(fired);
-        }
-	]
-);
+			t.assertTrue(fired);
+		}
+	]);
+});
\ No newline at end of file
diff --git a/dojo/tests/NodeList-data.html b/dojo/tests/NodeList-data.html
index 9e4e425..ea652f4 100644
--- a/dojo/tests/NodeList-data.html
+++ b/dojo/tests/NodeList-data.html
@@ -3,207 +3,200 @@
 <html>
 	<head>
 		<title>Testing dojo._data / NodeList.data</title>
-		
-		<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">
-			dojo.require("doh.runner");
-			dojo.require("dojo.NodeList-data");
-			dojo.addOnLoad(function(){
-				
+			require(["dojo", "doh", "dojo/NodeList-data", "dojo/domReady!"], function(dojo, doh){
 				var $ = dojo.query;
 				var len = function(obj){
 					var x = 0;
 					for(var i in obj){ x++ }
 					return x;
 				};
-				
-				doh.register("t", 
-					[
-						
-						function sanity(t){
-							
-							var list = $("#foo");
-							var lis = $("#bar > li");
-							
-							t.is(1, list.length, "i'm not insane");
-							t.is(2, lis.length, "li's are sane, too");
-							
-							list.data("a", "b");
-							lis.data("a", "b");
-							
-							t.is("b", list.data("a")[0]);
-							t.is(["b"], list.data("a"));
-							
-							t.is(["b","b"], lis.data("a"));
-							t.is("b", lis.data("a")[0]);
-						},
-					
-						function basicdata(t){
-						
-							var list = $('#foo');
-							
-							list.data("bar", 6)
-								.data("baz", "a")
-								.data("bam", [1,2,3])
-								.data("foo", { a:"b" })
-							;
-							
-							var newlist = $("#foo");
-							
-							t.is(6, newlist.data("bar")[0]);
-							t.is("a", newlist.data("baz")[0]);
-							t.is(3, newlist.data("bam")[0].length);
-							t.is(1, newlist.data("bam")[0][0]);
-							t.is("b", newlist.data("foo")[0].a);
-							
-						},
-						
-						function hashdata(t){
-							
-							$("#foo").data({
-								bar:"baz",
-								foo:"bap"
-							});
-							
-							t.is("baz", $('#foo').data("bar")[0]);
-							t.is("bap", $('#foo').data("foo")[0]);
-							
-						},
-						
-						function butdoesitchain(t){
-							
-							$("#foo").data("bar", 42).style("color", "red");
-							t.is(42, $("#foo").data("bar")[0]);
-						},
-						
-						function getanobjectback(t){
-							
-							$("#foo").data("afoo", 1);
-							$("#foo").data("bfoo", 2);
-							
-							var obj = $("#foo").data()[0];
-							
-							t.is(1, obj.afoo);
-							t.is(2, obj.bfoo);
-							
-						},
-						
-						function plaindata(t){
-							dojo.query("#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){
-								t.t(!dojo._nodeData(n, "bar"));
-							});
-							
-							dojo.query("#bar li").data({
-								a:"b", c:"d", e:"f"
+
+				doh.register([
+					function sanity(t){
+
+						var list = $("#foo");
+						var lis = $("#bar > li");
+
+						t.is(1, list.length, "i'm not insane");
+						t.is(2, lis.length, "li's are sane, too");
+
+						list.data("a", "b");
+						lis.data("a", "b");
+
+						t.is("b", list.data("a")[0]);
+						t.is(["b"], list.data("a"));
+
+						t.is(["b","b"], lis.data("a"));
+						t.is("b", lis.data("a")[0]);
+					},
+
+					function basicdata(t){
+
+						var list = $('#foo');
+
+						list.data("bar", 6)
+							.data("baz", "a")
+							.data("bam", [1,2,3])
+							.data("foo", { a:"b" })
+						;
+
+						var newlist = $("#foo");
+
+						t.is(6, newlist.data("bar")[0]);
+						t.is("a", newlist.data("baz")[0]);
+						t.is(3, newlist.data("bam")[0].length);
+						t.is(1, newlist.data("bam")[0][0]);
+						t.is("b", newlist.data("foo")[0].a);
+
+					},
+
+					function hashdata(t){
+
+						$("#foo").data({
+							bar:"baz",
+							foo:"bap"
+						});
+
+						t.is("baz", $('#foo').data("bar")[0]);
+						t.is("bap", $('#foo').data("foo")[0]);
+
+					},
+
+					function butdoesitchain(t){
+
+						$("#foo").data("bar", 42).style("color", "red");
+						t.is(42, $("#foo").data("bar")[0]);
+					},
+
+					function getanobjectback(t){
+
+						$("#foo").data("afoo", 1);
+						$("#foo").data("bfoo", 2);
+
+						var obj = $("#foo").data()[0];
+
+						t.is(1, obj.afoo);
+						t.is(2, obj.bfoo);
+
+					},
+
+					function plaindata(t){
+						dojo.query("#bar li").data("bar", 42)
+							.forEach(function(n){
+								t.is(42, dojo._nodeData(n, "bar"));
 							});
-							
-							dojo.query("#bar li").removeData();
-							var data = dojo.query("#bar li").data()[0];
-							
-							t.f(data.a);
-							t.f(data.c);
-							t.f(data.e);
-						},
-						
-						function multidata(t){
-							
-							var ret = dojo.query("#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();
-							
-							var ret2 = dojo.query("#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");
-							
-						},
-						
-						function obj(t){
-							var x = dojo.query("#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");
-								return;
-							}
-							
-							var me = dojo.query("#bar li").data("die", "yes");
-							me.at(0).attr("id", "killme");
-							var data = me.data();
-							
-							t.is(2, me.length);
-							t.is("yes", me.data("die")[0]);
-							t.is("yes", me.data("die")[1]);
-							
-							var l = len(dojo._nodeDataCache);
-							
-							dojo.destroy("killme");
-							dojo._gcNodeData();
-							
-							t.is(l - 1, len(dojo._nodeDataCache), "one item removed because destroyed");
-							me = dojo.query("#bar li");
-							t.is(1, me.length);
-							
-						},
-						
-						function literals(t){
-							// this is an implementation detail. object literals count,
-							// but doesn't mean you should use them.
-							var x = { a:1 };
-							
-							var one = dojo.query("#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);
-							
-						},
-						
-						function clearall(t){
-
-							if(!dojo._nodeDataCache){
-								t.t("We must be testing a built Dojo. No access to dataCache");
-								return;
-							}
-							
-							var l = len(dojo._nodeDataCache);
-							t.t(l, "there is stuff in the cache");;
-							
-							dojo.query("#b > *").forEach(dojo.destroy);
-							dojo._gcNodeData();
-							t.is(0, len(dojo._nodeDataCache), "no longer stuff in the cache");
+					},
+
+					function removeData(t){
+						dojo.query("#bar li").removeData("bar");
+						dojo.query("#bar li").forEach(function(n){
+							t.t(!dojo._nodeData(n, "bar"));
+						});
+
+						dojo.query("#bar li").data({
+							a:"b", c:"d", e:"f"
+						});
+
+						dojo.query("#bar li").removeData();
+						var data = dojo.query("#bar li").data()[0];
+
+						t.f(data.a);
+						t.f(data.c);
+						t.f(data.e);
+					},
+
+					function multidata(t){
+
+						var ret = dojo.query("#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();
+
+						var ret2 = dojo.query("#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");
+
+					},
+
+					function obj(t){
+						var x = dojo.query("#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");
+							return;
 						}
-					]
-				);
-				doh.run();
+
+						var me = dojo.query("#bar li").data("die", "yes");
+						me.at(0).attr("id", "killme");
+						var data = me.data();
+
+						t.is(2, me.length);
+						t.is("yes", me.data("die")[0]);
+						t.is("yes", me.data("die")[1]);
+
+						var l = len(dojo._nodeDataCache);
+
+						dojo.destroy("killme");
+						dojo._gcNodeData();
+
+						t.is(l - 1, len(dojo._nodeDataCache), "one item removed because destroyed");
+						me = dojo.query("#bar li");
+						t.is(1, me.length);
+
+					},
+
+					function literals(t){
+						// this is an implementation detail. object literals count,
+						// but doesn't mean you should use them.
+						var x = { a:1 };
+
+						var one = dojo.query("#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);
+
+					},
+
+					function clearall(t){
+
+						if(!dojo._nodeDataCache){
+							t.t("We must be testing a built Dojo. No access to dataCache");
+							return;
+						}
+
+						var l = len(dojo._nodeDataCache);
+						t.t(l, "there is stuff in the cache");
+
+						dojo.query("#b > *").forEach(dojo.destroy);
+						dojo._gcNodeData();
+						t.is(0, len(dojo._nodeDataCache), "no longer stuff in the cache");
+					}
+				]);
+				doh.runOnLoad();
 			});
 		</script>
 	</head>
-	<body><div id="b">
-		<div id="foo">woot.</div>
-		<ul id="bar">
-			<li>baz</li>
-			<li>bam</li>
-		</ul>
-		<p id="lit"><span>hi</span><span>there</span></p>
+	<body>
+		<div id="b">
+			<div id="foo">woot.</div>
+			<ul id="bar">
+				<li>baz</li>
+				<li>bam</li>
+			</ul>
+			<p id="lit"><span>hi</span><span>there</span></p>
 		</div>
 	</body>
 </html>
diff --git a/dojo/tests/NodeList-data.js b/dojo/tests/NodeList-data.js
index d9dd148..85061af 100644
--- a/dojo/tests/NodeList-data.js
+++ b/dojo/tests/NodeList-data.js
@@ -1,4 +1,5 @@
-dojo.provide("tests.NodeList-data");
-if(dojo.isBrowser){
-	doh.registerUrl("tests.NodeList-data", dojo.moduleUrl("tests", "NodeList-data.html"));
-}
+define(["doh", "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 4b8d279..c8dc888 100644
--- a/dojo/tests/NodeList-fx.html
+++ b/dojo/tests/NodeList-fx.html
@@ -6,13 +6,9 @@
 		<style type="text/css">
 			@import "../resources/dojo.css";
 		</style>
-		<script type="text/javascript" 
-			src="../dojo.js" djConfig="isDebug: true, popup: true"></script>
+		<script type="text/javascript" src="../dojo.js" data-dojo-config="isDebug: true, popup: true"></script>
 		<script type="text/javascript">
-			dojo.require("doh.runner");
-			dojo.require("dojo.NodeList-fx");
-
-			dojo.addOnLoad(function(){
+			require(["dojo", "doh", "dojo/NodeList-fx", "dojo/domReady!"], function(dojo, doh){
 				doh.register("NodeList-fx", 
 					[
 						function fadeOut(){
diff --git a/dojo/tests/NodeList-manipulate.html b/dojo/tests/NodeList-manipulate.html
index 81a3dd9..b749c92 100644
--- a/dojo/tests/NodeList-manipulate.html
+++ b/dojo/tests/NodeList-manipulate.html
@@ -6,337 +6,327 @@
 		<style type="text/css">
 			@import "../resources/dojo.css";
 		</style>
-		<script type="text/javascript" 
-			src="../dojo.js"></script>
-		<script type="text/javascript" 
-			src="../NodeList-manipulate.js"></script>
+		<script type="text/javascript" src="../dojo.js"></script>
 		<script type="text/javascript">
-			dojo.require("doh.runner");
-			dojo.require("dojo.NodeList-manipulate");
-
-			function verify(/*dojo.NodeList*/nl, /*Array*/ids){
-				for(var i = 0, node; node = nl[i]; i++){
-					doh.is(ids[i], node.id);
+			require(["dojo", "doh", "dojo/NodeList-manipulate", "dojo/domReady!"], function(dojo, doh){
+
+				function verify(/*dojo.NodeList*/nl, /*Array*/ids){
+					for(var i = 0, node; node = nl[i]; i++){
+						doh.is(ids[i], node.id);
+					}
+					//Make sure lengths are equal.
+					doh.is(ids.length, i);
 				}
-				//Make sure lengths are equal.
-				doh.is(ids.length, i);
-			}
 
-			dojo.addOnLoad(function(){
 				var divs = dojo.query("div.testDiv");
 
-				doh.register("t", 
-					[
-						function innerHTML(t){
-							divs.innerHTML("<ul><li>Test</li></ul>");
-							dojo.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, ""));
-						},
-
-
-						function html(t){
-							divs.html("<ul><li>Test</li></ul>");
-							dojo.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.html().toLowerCase().replace(/[\r\n]/g, ""));
-						},
-
-						function text(t){
-							doh.is("TestTestTest", divs.text());
-
-							divs.text("Hello World");
-
-							dojo.forEach(divs, function(node){
-								doh.is(1, node.childNodes.length);
-								doh.is("Hello World", node.childNodes[0].nodeValue);
-							});
-
-							doh.is("Hello WorldHello WorldHello World", divs.text());
-						},
-
-						function val(t){
-							//Input text test.
-							dojo.query('[type="text"]').val("Hello");
-							doh.is("Hello", dojo.byId("inputText").value);
-							
-							//Textarea test.
-							dojo.query('textarea', "inputForm").val("World");
-							doh.is("World", dojo.byId("inputTextArea").value);
-
-							//Radio button test
-							dojo.query('[type="radio"]').val("radio2");
-							doh.f(dojo.byId("inputRadio1").checked);
-							doh.t(dojo.byId("inputRadio2").checked);
-							
-							//Checkbox test
-							dojo.query('[type="checkbox"]').val("checkbox2");
-							doh.f(dojo.byId("inputCheckBox1").checked);
-							doh.t(dojo.byId("inputCheckBox2").checked);
-							
-							var selects = dojo.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){
-								if(node.value == "two"){
-									doh.t(node.selected);
-								}else{
-									doh.f(node.selected);
-								}
-							});
-							
-							//Multiple select test.
-							selects.at(1).val(["four", "six"]);
-							dojo.query("option", "inputSelect2").forEach(function(node){
-								if(node.value == "four" || node.value == "six"){
-									doh.t(node.selected);
-								}else{
-									doh.f(node.selected);
-								}
-							});
-							
-						},
-
-						function append(t){
-							//Test string content
-							divs.append('<span class="foo">foo</span><span class="bar">bar</span>')
-								.forEach(function(node){
-									doh.is(3, node.childNodes.length);
-									doh.is("foo", node.childNodes[1].className);
-									doh.is("bar", node.childNodes[2].className);
-									
-								}
-							);
-							
-							//Test DOMNode content
-							divs.append(dojo.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");
-							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){
-								doh.is(6, node.childNodes.length);
-								doh.is("h1", node.childNodes[3].nodeName.toLowerCase());
-								doh.is("h1", node.childNodes[4].nodeName.toLowerCase());
-								doh.is("h1", node.childNodes[5].nodeName.toLowerCase());
-							});
-
-							//clean up
-							dojo.query("h1").remove();
-						},
-
-						function appendTo(t){
-							//Create some new things.
-							dojo.query("body").append('<p class="singer">bo</p><p class="singer">diddly</p>');
-
-							var ret = dojo.query(".foo").appendTo(".singer");
-							doh.is(6, ret.length);
-
-							dojo.query(".singer").forEach(function(node){
-								doh.is(4, node.childNodes.length);
+				doh.register([
+					function innerHTML(t){
+						divs.innerHTML("<ul><li>Test</li></ul>");
+						dojo.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, ""));
+					},
+
+					function html(t){
+						divs.html("<ul><li>Test</li></ul>");
+						dojo.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.html().toLowerCase().replace(/[\r\n]/g, ""));
+					},
+
+					function text(t){
+						doh.is("TestTestTest", divs.text());
+
+						divs.text("Hello World");
+
+						dojo.forEach(divs, function(node){
+							doh.is(1, node.childNodes.length);
+							doh.is("Hello World", node.childNodes[0].nodeValue);
+						});
+
+						doh.is("Hello WorldHello WorldHello World", divs.text());
+					},
+
+					function val(t){
+						//Input text test.
+						dojo.query('[type="text"]').val("Hello");
+						doh.is("Hello", dojo.byId("inputText").value);
+
+						//Textarea test.
+						dojo.query('textarea', "inputForm").val("World");
+						doh.is("World", dojo.byId("inputTextArea").value);
+
+						//Radio button test
+						dojo.query('[type="radio"]').val("radio2");
+						doh.f(dojo.byId("inputRadio1").checked);
+						doh.t(dojo.byId("inputRadio2").checked);
+
+						//Checkbox test
+						dojo.query('[type="checkbox"]').val("checkbox2");
+						doh.f(dojo.byId("inputCheckBox1").checked);
+						doh.t(dojo.byId("inputCheckBox2").checked);
+
+						var selects = dojo.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){
+							if(node.value == "two"){
+								doh.t(node.selected);
+							}else{
+								doh.f(node.selected);
+							}
+						});
+
+						//Multiple select test.
+						selects.at(1).val(["four", "six"]);
+						dojo.query("option", "inputSelect2").forEach(function(node){
+							if(node.value == "four" || node.value == "six"){
+								doh.t(node.selected);
+							}else{
+								doh.f(node.selected);
+							}
+						});
+
+					},
+
+					function append(t){
+						//Test string content
+						divs.append('<span class="foo">foo</span><span class="bar">bar</span>')
+							.forEach(function(node){
+								doh.is(3, 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);
-							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]);
-							bands.forEach(function(node){
-								doh.is(4, node.childNodes.length);
-								doh.is("guitarist", node.childNodes[2].className);
-								doh.is("guitarist", node.childNodes[3].className);								
-							});
-
-							//Get rid of bands
-							bands.remove();
-						},
-
-						function prepend(t){
-							dojo.query(".singer").prepend('<span class="fry">layla</span>')
-								.forEach(function(node){
-									doh.is(5, node.childNodes.length);
-									doh.is("fry", node.childNodes[0].className);
-								}
-							);
-						},
-
-						function prependTo(t){
-							//Create some new things.
-							dojo.query("body").append('<p class="actor">steve</p><p class="actor">martin</p>');
-
-							var ret = dojo.query(".bar").prependTo(".actor");
-							doh.is(6, ret.length);
-
-							dojo.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);
 								doh.is("bar", node.childNodes[2].className);
-							});
-							
-							//Clean up
-							dojo.query("p").remove();
-						},
-						
-						
-						function after(t){
-							divs.after('<span class="after">after</span>')
-								.forEach(function(node){
-									doh.is("after", node.nextSibling.className);
-								}
-							);
-							
-							dojo.query("form").after(dojo.query(".after")).forEach(function(node){
-								for(var i = 0; i < 3; i++){
-									doh.is("after", node.nextSibling.className);
-									node = node.nextSibling;
-								}
-							});
-						},
-
-						function insertAfter(t){
-							dojo.query("body").prepend('<h1>testing dojo.NodeList-manipulate</h1>');
-							var ret = dojo.query(".after").insertAfter("h1");
-							doh.is(3, ret.length);
-
-							dojo.query("h1").forEach(function(node){
-								for(var i = 0; i < 3; i++){
-									doh.is("after", node.nextSibling.className);
-									node = node.nextSibling;
-								}
-							});
-						},
-
-						function before(t){
-							divs.before('<span class="before">before</span>')
-								.forEach(function(node){
-									doh.is("before", node.previousSibling.className);
-								}
-							);
-							
-							dojo.query("form").before(dojo.query(".before")).forEach(function(node){
-								for(var i = 0; i < 3; i++){
-									doh.is("before", node.previousSibling.className);
-									node = node.previousSibling;
-								}
-							});
-						},
-
-						function insertBefore(t){
-							var ret = dojo.query(".before").insertBefore("h1");
-							doh.is(3, ret.length);
-
-							dojo.query("h1").forEach(function(node){
-								for(var i = 0; i < 3; i++){
-									doh.is("before", node.previousSibling.className);
-									node = node.previousSibling;
-								}
-							});
-						},
-						
-						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);
-						},
-						
-						function wrap(t){
-							dojo.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){
-								doh.is("h1", node.parentNode.nodeName.toLowerCase());
-								doh.is(4, dojo.query("h1").length);
-							});
-						},
-						
-						function wrapAll(t){
-							dojo.query("h1").wrapAll('<h4></h4>');
-							var h4s = dojo.query("h4");
-							doh.is(1, h4s.length);
-							
-							var h4 = h4s[0];
-							doh.is(4, h4.childNodes.length);
-							dojo.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");
-
-							doh.is(2, myClass.length);
-							doh.is(5, dojo.query("input", myClass[0]).length);
-							doh.is(2, dojo.query("select", myClass[1]).length);
-						},
-
-						function wrapInner(t){
-							dojo.query("h4").wrapInner('<h3></h3>');
-							var h3s = dojo.query("h3");
-							doh.is(1, h3s.length);
-							
-							var h3 = h3s[0];
-							doh.is(4, h3.childNodes.length);
-							dojo.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>');
-							
-							dojo.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());
-							});
-						},
-
-						function replaceAll(t){
-							dojo.query(".after").replaceAll("h4");
-
-							doh.is(3, dojo.query(".after").length);
-							doh.is(0, dojo.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);
-						},
-						
-						function clone(t){
-							dojo.query(".italics").clone().appendTo("body");
-							doh.is(6, dojo.query(".italics").length);
-						}
-					]
-				);
-				doh.run();
+
+							}
+						);
+
+						//Test DOMNode content
+						divs.append(dojo.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");
+						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){
+							doh.is(6, node.childNodes.length);
+							doh.is("h1", node.childNodes[3].nodeName.toLowerCase());
+							doh.is("h1", node.childNodes[4].nodeName.toLowerCase());
+							doh.is("h1", node.childNodes[5].nodeName.toLowerCase());
+						});
+
+						//clean up
+						dojo.query("h1").remove();
+					},
+
+					function appendTo(t){
+						//Create some new things.
+						dojo.query("body").append('<p class="singer">bo</p><p class="singer">diddly</p>');
+
+						var ret = dojo.query(".foo").appendTo(".singer");
+						doh.is(6, ret.length);
+
+						dojo.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);
+						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]);
+						bands.forEach(function(node){
+							doh.is(4, node.childNodes.length);
+							doh.is("guitarist", node.childNodes[2].className);
+							doh.is("guitarist", node.childNodes[3].className);                
+						});
+
+						//Get rid of bands
+						bands.remove();
+					},
+
+					function prepend(t){
+						dojo.query(".singer").prepend('<span class="fry">layla</span>')
+							.forEach(function(node){
+								doh.is(5, node.childNodes.length);
+								doh.is("fry", node.childNodes[0].className);
+							}
+						);
+					},
+
+					function prependTo(t){
+						//Create some new things.
+						dojo.query("body").append('<p class="actor">steve</p><p class="actor">martin</p>');
+
+						var ret = dojo.query(".bar").prependTo(".actor");
+						doh.is(6, ret.length);
+
+						dojo.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);
+							doh.is("bar", node.childNodes[2].className);
+						});
+
+						//Clean up
+						dojo.query("p").remove();
+					},
+
+					function after(t){
+						divs.after('<span class="after">after</span>')
+							.forEach(function(node){
+								doh.is("after", node.nextSibling.className);
+							}
+						);
+
+						dojo.query("form").after(dojo.query(".after")).forEach(function(node){
+							for(var i = 0; i < 3; i++){
+								doh.is("after", node.nextSibling.className);
+								node = node.nextSibling;
+							}
+						});
+					},
+
+					function insertAfter(t){
+						dojo.query("body").prepend('<h1>testing dojo.NodeList-manipulate</h1>');
+						var ret = dojo.query(".after").insertAfter("h1");
+						doh.is(3, ret.length);
+
+						dojo.query("h1").forEach(function(node){
+							for(var i = 0; i < 3; i++){
+								doh.is("after", node.nextSibling.className);
+								node = node.nextSibling;
+							}
+						});
+					},
+
+					function before(t){
+						divs.before('<span class="before">before</span>')
+							.forEach(function(node){
+								doh.is("before", node.previousSibling.className);
+							}
+						);
+
+						dojo.query("form").before(dojo.query(".before")).forEach(function(node){
+							for(var i = 0; i < 3; i++){
+								doh.is("before", node.previousSibling.className);
+								node = node.previousSibling;
+							}
+						});
+					},
+
+					function insertBefore(t){
+						var ret = dojo.query(".before").insertBefore("h1");
+						doh.is(3, ret.length);
+
+						dojo.query("h1").forEach(function(node){
+							for(var i = 0; i < 3; i++){
+								doh.is("before", node.previousSibling.className);
+								node = node.previousSibling;
+							}
+						});
+					},
+
+					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);
+					},
+
+					function wrap(t){
+						dojo.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){
+							doh.is("h1", node.parentNode.nodeName.toLowerCase());
+							doh.is(4, dojo.query("h1").length);
+						});
+					},
+
+					function wrapAll(t){
+						dojo.query("h1").wrapAll('<h4></h4>');
+						var h4s = dojo.query("h4");
+						doh.is(1, h4s.length);
+
+						var h4 = h4s[0];
+						doh.is(4, h4.childNodes.length);
+						dojo.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");
+
+						doh.is(2, myClass.length);
+						doh.is(5, dojo.query("input", myClass[0]).length);
+						doh.is(2, dojo.query("select", myClass[1]).length);
+					},
+
+					function wrapInner(t){
+						dojo.query("h4").wrapInner('<h3></h3>');
+						var h3s = dojo.query("h3");
+						doh.is(1, h3s.length);
+
+						var h3 = h3s[0];
+						doh.is(4, h3.childNodes.length);
+						dojo.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>');
+
+						dojo.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());
+						});
+					},
+
+					function replaceAll(t){
+						dojo.query(".after").replaceAll("h4");
+
+						doh.is(3, dojo.query(".after").length);
+						doh.is(0, dojo.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);
+					},
+
+					function clone(t){
+						dojo.query(".italics").clone().appendTo("body");
+						doh.is(6, dojo.query(".italics").length);
+					}
+				]);
+				doh.runOnLoad();
 			});
 		</script>
 	</head>
@@ -377,4 +367,3 @@
 		</form>
 	</body>
 </html>
-
diff --git a/dojo/tests/NodeList-manipulate.js b/dojo/tests/NodeList-manipulate.js
index d4ba02b..044ce4a 100644
--- a/dojo/tests/NodeList-manipulate.js
+++ b/dojo/tests/NodeList-manipulate.js
@@ -1,4 +1,5 @@
-dojo.provide("tests.NodeList-manipulate");
-if(dojo.isBrowser){
-	doh.registerUrl("tests.NodeList-manipulate", dojo.moduleUrl("tests", "NodeList-manipulate.html"));
-}
+define(["doh", "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 0955323..c12907b 100644
--- a/dojo/tests/NodeList-traverse.html
+++ b/dojo/tests/NodeList-traverse.html
@@ -1,136 +1,129 @@
 <!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 id="html">
 	<head>
 		<title>Testing dojo.NodeList-traverse extensions to dojo.NodeList</title>
 		<style type="text/css">
 			@import "../resources/dojo.css";
 		</style>
-		<script type="text/javascript" 
-			src="../dojo.js" djConfig="isDebug: true, popup: true"></script>
-		<script type="text/javascript" 
-			src="../NodeList-traverse.js"></script>
+		<script type="text/javascript" src="../dojo.js" data-dojo-config="isDebug: true, popup: true"></script>
 		<script type="text/javascript">
-			dojo.require("doh.runner");
-			dojo.require("dojo.NodeList-traverse");
-
-			function verify(/*dojo.NodeList*/nl, /*Array*/ids, /*String*/ comment){
-				comment = comment || "verify";
-				for(var i = 0, node; (node = nl[i]); i++){
-					doh.is(ids[i], node.id, comment + " " + i);
+			require(["dojo", "doh", "dojo/NodeList-traverse", "dojo/domReady!"], function(dojo, doh){
+
+				function verify(/*dojo.NodeList*/nl, /*Array*/ids, /*String*/ comment){
+					comment = comment || "verify";
+					for(var i = 0, node; (node = nl[i]); i++){
+						doh.is(ids[i], node.id, comment + " " + i);
+					}
+					//Make sure lengths are equal.
+					doh.is(ids.length, i, comment + " length");
 				}
-				//Make sure lengths are equal.
-				doh.is(ids.length, i, comment + " length");
-			}
 
-			dojo.addOnLoad(function(){
 				var divs = dojo.query("div.testDiv");
 
-				doh.register("t", 
-					[
-						function children(t){
-							verify(divs.last().children(), ["crass", "classy", "yeah"]);
-						},
-
-						function closest(t){
-							// test simple selector
-							var classy = dojo.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 closestFooBar = bang.closest(".foo > .bar");
-							verify(closestFooBar, ["level4"], ".foo > .bar");
-
-							// test descendant selector that doesn't match (".foo" alone matches nodes, but not
-							// ".bogus .foo")
-							var closestBogusFoo = bang.closest(".bogus .foo");
-							verify(closestBogusFoo, [], ".bogus .foo");
-
-							// positive test that scope argument works: .foo > .bar should match a scope
-							// of "level2" or above
-							closestFooBar = bang.closest(".foo > .bar", "level2");
-							verify(closestFooBar, ["level4"], ".foo > .bar query relative to level2");
-
-							// > .bar should match a scope of level3 or level1
-							var topBar = bang.closest("> .bar", "level3");
-							verify(topBar, ["level4"], "> .bar query relative to level3");
-
-							// negative test that scope argument works:  .foo > .bar relative to level3
-							// doesn't match since .foo is level3, rather than a child of level3
-							closestFooBar = bang.closest(".foo > .bar", "level3");
-							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,
-							// 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");
-							verify(closestFoo, ["level1", "level3"], ".foo from div");
-							
-						},
-
-						function parent(t){
-							verify(dojo.query("#classy").parent(), ["third"]);
-						},
-
-						function parents(t){
-							var classy = dojo.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"]);
-						},
-
-						function next(t){
-							verify(dojo.query("#crass").next(), ["classy"]);
-						},
-
-						function nextAll(t){
-							verify(dojo.query("#crass").nextAll(), ["classy", "yeah"]);
-							verify(dojo.query("#crass").nextAll("#yeah"), ["yeah"]);
-						},
-
-						function prev(t){
-							verify(dojo.query("#classy").prev(), ["crass"]);
-						},
-
-						function prevAll(t){
-							verify(dojo.query("#yeah").prevAll(), ["classy", "crass"]);
-							verify(dojo.query("#yeah").prevAll("#crass"), ["crass"]);
-						},
-
-						function andSelf(t){
-							verify(dojo.query("#yeah").prevAll().andSelf(), ["classy", "crass", "yeah"]);
-						},
-
-						function first(t){
-							verify(divs.first(), ["sq100"]);
-						},
-
-						function last(t){
-							verify(divs.last(), ["third"]);
-						},
-
-						function even(t){
-							var even = divs.even();
-							verify(even, ["t"]);
-							verify(even.end(), ["sq100", "t", "third"]);
-						},
-
-						function odd(t){
-							var odd = divs.odd();
-							verify(odd, ["sq100", "third"]);
-							verify(odd.end(), ["sq100", "t", "third"]);
-						}
-					]
-				);
-				doh.run();
+				doh.register([
+					function children(t){
+						verify(divs.last().children(), ["crass", "classy", "yeah"]);
+					},
+
+					function closest(t){
+						// test simple selector
+						var classy = dojo.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 closestFooBar = bang.closest(".foo > .bar");
+						verify(closestFooBar, ["level4"], ".foo > .bar");
+
+						// test descendant selector that doesn't match (".foo" alone matches nodes, but not
+						// ".bogus .foo")
+						var closestBogusFoo = bang.closest(".bogus .foo");
+						verify(closestBogusFoo, [], ".bogus .foo");
+
+						// positive test that scope argument works: .foo > .bar should match a scope
+						// of "level2" or above
+						closestFooBar = bang.closest(".foo > .bar", "level2");
+						verify(closestFooBar, ["level4"], ".foo > .bar query relative to level2");
+
+						// > .bar should match a scope of level3 or level1
+						var topBar = bang.closest("> .bar", "level3");
+						verify(topBar, ["level4"], "> .bar query relative to level3");
+
+						// negative test that scope argument works:  .foo > .bar relative to level3
+						// doesn't match since .foo is level3, rather than a child of level3
+						closestFooBar = bang.closest(".foo > .bar", "level3");
+						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,
+						// 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");
+						verify(closestFoo, ["level1", "level3"], ".foo from div");
+					 
+					},
+
+					function parent(t){
+						verify(dojo.query("#classy").parent(), ["third"]);
+					},
+
+					function parents(t){
+						var classy = dojo.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"]);
+					},
+
+					function next(t){
+						verify(dojo.query("#crass").next(), ["classy"]);
+					},
+
+					function nextAll(t){
+						verify(dojo.query("#crass").nextAll(), ["classy", "yeah"]);
+						verify(dojo.query("#crass").nextAll("#yeah"), ["yeah"]);
+					},
+
+					function prev(t){
+						verify(dojo.query("#classy").prev(), ["crass"]);
+					},
+
+					function prevAll(t){
+						verify(dojo.query("#yeah").prevAll(), ["classy", "crass"]);
+						verify(dojo.query("#yeah").prevAll("#crass"), ["crass"]);
+					},
+
+					function andSelf(t){
+						verify(dojo.query("#yeah").prevAll().andSelf(), ["classy", "crass", "yeah"]);
+					},
+
+					function first(t){
+						verify(divs.first(), ["sq100"]);
+					},
+
+					function last(t){
+						verify(divs.last(), ["third"]);
+					},
+
+					function even(t){
+						var even = divs.even();
+						verify(even, ["t"]);
+						verify(even.end(), ["sq100", "t", "third"]);
+					},
+
+					function odd(t){
+						var odd = divs.odd();
+						verify(odd, ["sq100", "third"]);
+						verify(odd.end(), ["sq100", "t", "third"]);
+					}
+				]);
+				doh.runOnLoad();
 			});
 		</script>
 	</head>
@@ -158,7 +151,7 @@
 						<div id="level5" class="bar">
 							<div id="level6" class="bang">foo bar bar bang</div>
 						</div>
-					</div>			
+					</div>
 				</div>
 			</div>
 		</div>
diff --git a/dojo/tests/NodeList-traverse.js b/dojo/tests/NodeList-traverse.js
index 810ce19..77c6ac3 100644
--- a/dojo/tests/NodeList-traverse.js
+++ b/dojo/tests/NodeList-traverse.js
@@ -1,4 +1,5 @@
-dojo.provide("tests.NodeList-traverse");
-if(dojo.isBrowser){
-	doh.registerUrl("tests.NodeList-traverse", dojo.moduleUrl("tests", "NodeList-traverse.html"));
-}
+define(["doh", "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 bb9d14c..f4b41a1 100644
--- a/dojo/tests/Stateful.js
+++ b/dojo/tests/Stateful.js
@@ -1,55 +1,51 @@
-dojo.provide("tests.Stateful");
+define(["../main", "doh", "../Stateful"], function(dojo, doh){
 
-dojo.require("dojo.Stateful");
-
-doh.register("tests.Stateful",
-	[
-		function getSetWatch(t){
-			var s = new dojo.Stateful({
-				foo: 3
-			});
-			doh.is(s.get("foo"), 3);
-			var watching = s.watch("foo", function(name, oldValue, value){
-				doh.is("foo", name);
-				doh.is(3, oldValue);
-				doh.is(4, value);
-				doh.is(4, s.get("foo"));
-			});
-			s.set("foo", 4);
+doh.register("tests.Stateful", [
+	function getSetWatch(t){
+		var s = new dojo.Stateful({
+			foo: 3
+		});
+		doh.is(s.get("foo"), 3);
+		var watching = s.watch("foo", function(name, oldValue, value){
+			doh.is("foo", name);
+			doh.is(3, oldValue);
+			doh.is(4, value);
 			doh.is(4, s.get("foo"));
-			watching.unwatch();
-			s.set("foo", 5);
-			doh.is(5, s.get("foo"));
-		},
-		function setHash(t){
-			var s = new dojo.Stateful();
-			s.set({
-				foo:3,
-				bar: 5
-			});
-			doh.is(3, s.get("foo"));
-			doh.is(5, s.get("bar"));
-		},
-		function wildcard(t){
-			var s = new dojo.Stateful();
-			s.set({
-				foo:3,
-				bar: 5
-			});
-			var wildcard = 0;
-			var foo = 0;
-			s.watch(function(){
-				wildcard++;
-			});
-			s.watch("foo", function(){
-				foo++;
-			});
-			s.set("foo", 4);
-			s.set("bar", 6);
-			doh.is(2, wildcard);
-			doh.is(1, foo);
-		}
-
+		});
+		s.set("foo", 4);
+		doh.is(4, s.get("foo"));
+		watching.unwatch();
+		s.set("foo", 5);
+		doh.is(5, s.get("foo"));
+	},
+	function setHash(t){
+		var s = new dojo.Stateful();
+		s.set({
+			foo:3,
+			bar: 5
+		});
+		doh.is(3, s.get("foo"));
+		doh.is(5, s.get("bar"));
+	},
+	function wildcard(t){
+		var s = new dojo.Stateful();
+		s.set({
+			foo:3,
+			bar: 5
+		});
+		var wildcard = 0;
+		var foo = 0;
+		s.watch(function(){
+			wildcard++;
+		});
+		s.watch("foo", function(){
+			foo++;
+		});
+		s.set("foo", 4);
+		s.set("bar", 6);
+		doh.is(2, wildcard);
+		doh.is(1, foo);
+	}
+]);
 
-	]
-);
+});
\ No newline at end of file
diff --git a/dojo/tests/_base.js b/dojo/tests/_base.js
index 263f8d8..9f6d702 100644
--- a/dojo/tests/_base.js
+++ b/dojo/tests/_base.js
@@ -1,140 +1,22 @@
-var testGlobal = this;
-try{
-	dojo.provide("tests._base");
-	testGlobal = dojo.global;
-}catch(e){ }
-
-// the test suite for the bootstrap. Requires hostenv and other base tests at
-// the end
-
-if(doh.selfTest){
-
-	doh.register("doh.smokeTest",
-		[
-			function sanityCheckHarness(t){
-				// sanity checks
-				t.assertTrue(true);
-				t.assertFalse(false);
-				t.assertFalse(0);
-				t.assertFalse(null);
-				var tObj = { w00t: false, blarg: true };
-				t.assertEqual(
-					["thinger", "blah", tObj],
-					["thinger", "blah", tObj]
-				);
-				t.assertEqual(tObj, tObj);
-			},
-			/*
-			// uncomment to tests exception handling
-			function sanityCheckassertTrue(t){
-				// should throw an error
-				t.assertTrue(false);
-			},
-			function sanityCheckassertFalse(t){
-				// should throw an error
-				t.assertFalse(true);
-			},
-			function sanityCheckassertEqual(t){
-				// should throw an error
-				t.assertEqual("foo", "bar");
-			},
-			*/
-			{
-				name: "eqTest",
-				// smoke test the fixture system
-				setUp: function(t){
-					this.foo = "blah";
-				},
-				runTest: function(t){
-					t.assertEqual("blah", this.foo);
-				},
-				tearDown: function(t){
-				}
-			}
-		]
-	);
-
-	if(testGlobal["dojo"]){
-		doh.register("tests._base",
-			[
-				function dojoIsAvailable(t){
-					t.assertTrue(testGlobal["dojo"]);
-				}
-			]
-		);
-	}
-
-	if(testGlobal["setTimeout"]){
-		// a stone-stupid async test
-		doh.register("tests.async",
-			[
-				{
-					name: "deferredSuccess",
-					runTest: function(t){
-						var d = new doh.Deferred();
-						setTimeout(d.getTestCallback(function(){
-							t.assertTrue(true);
-							t.assertFalse(false);
-						}), 50);
-						return d;
-					}
-				},
-				{
-					name: "deferredFailure",
-					runTest: function(t){
-						var d = new doh.Deferred();
-						setTimeout(function(){
-							d.errback(new Error("hrm..."));
-						}, 50);
-						return d;
-					}
-				},
-				{
-					name: "timeoutFailure",
-					timeout: 50,
-					runTest: function(t){
-						// timeout of 50
-						var d = new doh.Deferred();
-						setTimeout(function(){
-							d.callback(true);
-						}, 100);
-						return d;
-					}
-				}
-			]
-		);
-	}
-}
-
-try{
-	// go grab the others
-	dojo.require("tests._base._loader.bootstrap");
-	dojo.require("tests._base._loader.loader");
-
-	// make sure we're looking at global define
-	var global;
-	(function(){ global= this; })();
-	global.define && global.define.vendor=="dojotoolkit.org" && dojo.require("dojo.tests._base._loader.modules");
-
-	dojo.platformRequire({
-		browser: ["tests._base._loader.hostenv_browser"],
-		rhino: ["tests._base._loader.hostenv_rhino"],
-		spidermonkey: ["tests._base._loader.hostenv_spidermonkey"]
-	});
-	dojo.require("tests._base.array");
-	dojo.require("tests._base.Color");
-	dojo.require("tests._base.lang");
-	dojo.require("tests._base.declare");
-	dojo.require("tests._base.connect");
-	dojo.require("tests._base.Deferred");
-	dojo.require("tests._base.json");
-	dojo.require("tests._base.object");
-	// FIXME: add test includes for the rest of the Dojo Base groups here
-	dojo.requireIf(dojo.isBrowser, "tests._base.html");
-	dojo.requireIf(dojo.isBrowser, "tests._base.fx");
-	dojo.requireIf(dojo.isBrowser, "tests._base.query");
-	dojo.requireIf(dojo.isBrowser, "tests._base.xhr");
-	dojo.requireIf(dojo.isBrowser, "tests._base.window");
-}catch(e){
-	doh.debug(e);
-}
+define([
+	"dojo/tests/_base/loader",
+	"dojo/tests/_base/array",
+	"dojo/tests/_base/Color",
+	"dojo/tests/_base/lang",
+	"dojo/tests/_base/declare",
+	"dojo/tests/_base/connect",
+	"dojo/tests/_base/Deferred",
+	"dojo/tests/_base/json",
+	"dojo/tests/_base/object",
+	"dojo/has!host-browser?dojo/tests/_base/html",
+	"dojo/has!host-browser?dojo/tests/_base/fx",
+	"dojo/has!host-browser?dojo/tests/_base/query",
+	"dojo/has!host-browser?dojo/tests/_base/xhr",
+	"dojo/has!host-browser?dojo/tests/_base/window"], 1);
+
+	// TODO: platform boot tests
+	//dojo.platformRequire({
+	//	browser: ["tests._base._loader.hostenv_browser"],
+	//	rhino: ["tests._base._loader.hostenv_rhino"],
+	//	spidermonkey: ["tests._base._loader.hostenv_spidermonkey"]
+	//});
diff --git a/dojo/tests/_base/AMD-build-transform/t1.js b/dojo/tests/_base/AMD-build-transform/t1.js
deleted file mode 100644
index 1ad5b11..0000000
--- a/dojo/tests/_base/AMD-build-transform/t1.js
+++ /dev/null
@@ -1,38 +0,0 @@
-// test leading commentary, AMD-ID pragma, AMD-return pragmas, auto strip last return
-//
-// some commentary
-/*
- * more commentary
- *
- */
-// AMD-ID "my/module"
-define(["your/module", "his/module"], function(yours, his) {
-
-var x= 1;
-
-// AMD-return with and without spaces and additional commentary
-
-return ++x1;//AMD-return
-return ++x2;// AMD-return
-return ++x3; //AMD-return
-return ++x4; // AMD-return
-return ++x5; //AMD-return stuff
-return ++x6; // AMD-return stuff
-return ++x7; //AMD-return stuff
-return ++x8; // AMD-return stuff
-
-return ++x9;//amd-return
-return ++xa;// amd-return
-return ++xb; //amd-return
-return ++xc; // amd-return
-return ++xd; //amd-return stuff
-return ++xe; // amd-return stuff
-return ++xf; //amd-return stuff
-return ++xg; // amd-return stuff
-
-//the next return should be stripped by the build transform
-return x;
-
-
-
-});
diff --git a/dojo/tests/_base/AMD-build-transform/t2.js b/dojo/tests/_base/AMD-build-transform/t2.js
deleted file mode 100644
index 1a767dd..0000000
--- a/dojo/tests/_base/AMD-build-transform/t2.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// test lower case amd pragmas
-// amd-id "my/module"
-define(["your/module", "his/module"], function(yours, his) {
-
-var x= 1;
-
-return a.b.x; //amd-return
-
-function() {
-  return ++x;
-}
-
-return x;
-});
diff --git a/dojo/tests/_base/AMD-build-transform/t3.js b/dojo/tests/_base/AMD-build-transform/t3.js
deleted file mode 100644
index 3be57af..0000000
--- a/dojo/tests/_base/AMD-build-transform/t3.js
+++ /dev/null
@@ -1,8 +0,0 @@
-//this module will fail the AMD transform since it doesn't have a moduleId
-define(["your/module", "his/module"], function(yours, his) {
-
-var x= 1;
-
-return ++x;
-
-});
diff --git a/dojo/tests/_base/AMD-build-transform/t4.js b/dojo/tests/_base/AMD-build-transform/t4.js
deleted file mode 100644
index a046668..0000000
--- a/dojo/tests/_base/AMD-build-transform/t4.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// test define statement spread across multiple lines
-//
-// AMD-id "my/module"
-define([
-  "your/module",
-  "his/module"
-], function(yours, his) {
-
-var x= 1;
-
-return x;
-
-});
diff --git a/dojo/tests/_base/AMD-build-transform/t5.js b/dojo/tests/_base/AMD-build-transform/t5.js
deleted file mode 100644
index 59f09ee..0000000
--- a/dojo/tests/_base/AMD-build-transform/t5.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// test define statement spread across multiple lines another way
-// AMD-id "my/module" some commentary
-define(
-[
-  "your/module",
-  "his/module"
-], function(yours, his) {
-
-var x= 1;
-
-return x;
-
-});
diff --git a/dojo/tests/_base/Color.js b/dojo/tests/_base/Color.js
index b7ccbb4..95b67f4 100644
--- a/dojo/tests/_base/Color.js
+++ b/dojo/tests/_base/Color.js
@@ -1,4 +1,4 @@
-dojo.provide("tests._base.Color");
+dojo.provide("dojo.tests._base.Color");
 
 (function(){
 	var white  = dojo.colorFromString("white").toRgba();
@@ -6,8 +6,10 @@ dojo.provide("tests._base.Color");
 	var verifyColor = function(t, source, expected){
 		var color = new dojo.Color(source);
 		t.is(expected, color.toRgba());
-		dojo.forEach(color.toRgba(), function(n){ t.is("number", typeof(n)); });
-	}
+		dojo.forEach(color.toRgba(), function(n){
+			t.is("number", typeof(n));
+		});
+	};
 
 	doh.register("tests._base.Color",
 		[
diff --git a/dojo/tests/_base/Deferred.js b/dojo/tests/_base/Deferred.js
index c1117b3..e0e690b 100644
--- a/dojo/tests/_base/Deferred.js
+++ b/dojo/tests/_base/Deferred.js
@@ -1,14 +1,19 @@
-dojo.provide("tests._base.Deferred");
+dojo.provide("dojo.tests._base.Deferred");
 
 var delay = function(ms){
 	var d = new dojo.Deferred();
 	ms = ms || 20;
-	setTimeout(function(){
+	if(this.setTimeout){
+		setTimeout(function(){
+			d.progress(0.5);
+		},ms/2);
+		setTimeout(function(){
+			d.resolve();
+		},ms);
+	}else{
 		d.progress(0.5);
-	},ms/2);
-	setTimeout(function(){
 		d.resolve();
-	},ms);
+	}
 	return d.promise;
 };
 doh.register("tests._base.Deferred",
@@ -126,17 +131,23 @@ doh.register("tests._base.Deferred",
 			});
 			return td;
 		},
+		function syncWhenWithNoCallback(t){
+			t.is(dojo.when(3), 3);
+		},
 		function progress(t){
-			var td = new doh.Deferred();
-			var percentDone;
-			dojo.when(delay(), function(){
-				t.is(percentDone, 0.5);
-				td.callback(true);
-			},function(){},
-			function(completed){
-				percentDone = completed;
-			});
-			return td;
+			if(dojo.isBrowser){
+				var td = new doh.Deferred();
+				var percentDone;
+				dojo.when(delay(), function(){
+					t.is(percentDone, 0.5);
+					td.callback(true);
+				},function(){},
+				function(completed){
+					percentDone = completed;
+				});
+				return td;
+			}
+			return null;
 		},
 		function errorHandler(t){
 			var def = new dojo.Deferred();
@@ -254,6 +265,53 @@ doh.register("tests._base.Deferred",
 			def.errback(new Error);
 
 			t.assertEqual("succeed", retval);
+		},
+		function testDojoPromiseProgressBasic(t) {
+			var a = new dojo.Deferred();
+			var b = new dojo.Deferred();
+			var called = false;
+			
+			a.then(function() {
+				b.then(function(){
+					if (!called) {
+						console.log("Boo. ProgressBasic not called");
+					}
+				}, function(){
+					console.log("Unexpected");
+				}, function(){
+					called = true; 
+					console.log("Yay. ProgressBasic called");
+				});
+			});
+			
+			a.resolve();
+			b.progress();
+			b.resolve();
+			t.t(called);
+		},
+		
+		function testDojoPromiseProgressChain(t) {
+			var a = new dojo.Deferred();
+			var b = new dojo.Deferred();
+			var called = false;
+			
+			a.then(function() {
+				return b;
+			}).then(function(){
+				if (!called) {
+					console.log("Boo. ProgressChain not called");
+				}
+			}, function(){
+				console.log("Unexpected");
+			}, function(){
+				called = true; 
+				console.log("Yay. ProgressChain called");
+			});
+			
+			a.resolve();
+			b.progress();
+			b.resolve();
+			t.t(called);
 		}
  ]
 );
diff --git a/dojo/tests/_base/NodeList.html b/dojo/tests/_base/NodeList.html
index c1d3d9a..0b90cd2 100644
--- a/dojo/tests/_base/NodeList.html
+++ b/dojo/tests/_base/NodeList.html
@@ -30,18 +30,15 @@
 
 		</style>
 		<title>testing dojo.NodeList</title>
-		<script type="text/javascript" src="../../dojo.js"
-			djConfig="isDebug: false"></script>
+		<script type="text/javascript" src="../../dojo.js"></script>
 		<script type="text/javascript">
-			dojo.require("doh.runner");
-			dojo.require("dojo.string");
-			dojo.require("dojo.parser");
-
-			dojo.addOnLoad(function(){
+		require(["dojo", "doh", "dojo/query", "dojo/on", "dojo/string", "dojo/parser", "dojo/domReady!"], function(dojo, doh, query, listen){
+			function registerForNodeList(name, query, NodeList){
+				var tn;
 				var c = dojo.byId("c1");
 				var t = dojo.byId("t");
 				var s = dojo.byId("sq100");
-				var fourElementNL = new dojo.NodeList(c, t, c, t);
+				var fourElementNL = new NodeList(c, t, c, t);
 
 				function verify(/*dojo.NodeList*/nl, /*Array*/ids){
 					for(var i = 0, node; node = nl[i]; i++){
@@ -51,21 +48,21 @@
 					doh.is(ids.length, i);
 				}
 
-				doh.register("t",
+				doh.register(name,
 					[
 						// constructor tests
 						function ctor(){
-							var nl = new dojo.NodeList();
+							var nl = new NodeList();
 							nl.push(c);
 							doh.is(1, nl.length);
 						},
 						function ctorArgs(){
-							var nl = new dojo.NodeList(4);
+							var nl = new NodeList(4);
 							nl.push(c);
 							doh.is(5, nl.length);
 						},
 						function ctorArgs2(){
-							var nl = new dojo.NodeList(c, t);
+							var nl = new NodeList(c, t);
 							doh.is(2, nl.length);
 							doh.is(c, nl[0]);
 							doh.is(t, nl[1]);
@@ -73,7 +70,7 @@
 						// iteration and array tests
 						function forEach(){
 							var lastItem;
-							var nl = new dojo.NodeList(c, t);
+							var nl = new NodeList(c, t);
 							nl.forEach(function(i){ lastItem = i; });
 							doh.is(t, lastItem);
 
@@ -151,7 +148,7 @@
 						},
 
 						function slice(){
-							var pnl = new dojo.NodeList(t, t, c);
+							var pnl = new NodeList(t, t, c);
 							doh.is(2, pnl.slice(1).length);
 							doh.is(3, pnl.length);
 							doh.is(c, pnl.slice(-1)[0]);
@@ -160,29 +157,29 @@
 						},
 
 						function splice(){
-							var pnl = new dojo.NodeList(t, t, c);
+							var pnl = new NodeList(t, t, c);
 							console.debug(pnl.splice(1));
 
 							/*
 							doh.is(2, pnl.splice(1).length);
 							doh.is(1, pnl.length);
-							pnl = new dojo.NodeList(t, t, c);
+							pnl = new NodeList(t, t, c);
 							doh.is(c, pnl.splice(-1)[0]);
 							doh.is(2, pnl.length);
-							pnl = new dojo.NodeList(t, t, c);
+							pnl = new NodeList(t, t, c);
 							doh.is(2, pnl.splice(-2).length);
 							*/
 						},
 
 						function spliceInsert(){
 							// insert 1
-							var pnl = new dojo.NodeList(t, t, c);
+							var pnl = new NodeList(t, t, c);
 							pnl.splice(0, 0, c);
 							doh.is(4, pnl.length);
 							doh.is(c, pnl[0]);
 
 							// insert multiple
-							pnl = new dojo.NodeList(t, t, c);
+							pnl = new NodeList(t, t, c);
 							pnl.splice(0, 0, c, s);
 							doh.is(5, pnl.length);
 							doh.is(c, pnl[0]);
@@ -190,7 +187,7 @@
 							doh.is(t, pnl[2]);
 
 							// insert multiple at offset
-							pnl = new dojo.NodeList(t, t, c);
+							pnl = new NodeList(t, t, c);
 							pnl.splice(1, 0, c, s);
 							doh.is(5, pnl.length);
 							doh.is(t, pnl[0]);
@@ -201,19 +198,19 @@
 
 						function spliceDel(){
 							// clobbery 1
-							var pnl = new dojo.NodeList(c, t, s);
+							var pnl = new NodeList(c, t, s);
 							pnl.splice(0, 1);
 							doh.is(2, pnl.length);
 							doh.is(t, pnl[0]);
 
 							// clobber multiple
-							pnl = new dojo.NodeList(c, t, s);
+							pnl = new NodeList(c, t, s);
 							pnl.splice(0, 2);
 							doh.is(1, pnl.length);
 							doh.is(s, pnl[0]);
 
 							// ...at an offset
-							pnl = new dojo.NodeList(c, t, s);
+							pnl = new NodeList(c, t, s);
 							pnl.splice(1, 1);
 							doh.is(2, pnl.length);
 							doh.is(c, pnl[0]);
@@ -223,56 +220,62 @@
 
 						function spliceInsertDel(){
 							// clobbery 1
-							var pnl = new dojo.NodeList(c, t, s);
+							var pnl = new NodeList(c, t, s);
 							pnl.splice(1, 1, s);
 							doh.is(3, pnl.length);
-							doh.is(dojo.NodeList(c, s, s), pnl);
+							doh.is(new NodeList(c, s, s), pnl);
 
-							pnl = new dojo.NodeList(c, t, s);
+							pnl = new NodeList(c, t, s);
 							pnl.splice(1, 2, s);
 							doh.is(2, pnl.length);
-							doh.is(dojo.NodeList(c, s), pnl);
+							doh.is(new NodeList(c, s), pnl);
 						},
 
 						// sub-search
-						function query(){
-							var pnl = new dojo.NodeList(t);
+						function queryTest(){
+							var pnl = new NodeList(t);
 							doh.is(c, pnl.query("span")[0]);
-							doh.is(t, dojo.query("body").query(":last-child")[0]);
-							doh.is(c, dojo.query("body").query(":last-child")[1]);
-							doh.is(1, pnl.query().length);
-							verify(pnl.query("span").end(), ["t"]);
+							if(name != "t"){
+							// this gets messed up by new DOM nodes the second time around
+								doh.is(t, query("body").query(":last-child")[0]);
+								doh.is(c, query("body").query(":last-child")[1]);
+								doh.is(1, pnl.query().length);
+								verify(pnl.query("span").end(), ["t"]);
+							}
 						},
 
 						function filter(){
-							doh.is(dojo.query("body :first-child").filter(":last-child")[0], c);
-							doh.is(1, dojo.query("*").filter(function(n){ return (n.nodeName.toLowerCase() == "span"); }).length);
-
-							var filterObj = {
-								filterFunc: function(n){
-									return (n.nodeName.toLowerCase() == "span");
-								}
-							};
-							doh.is(1, dojo.query("*").filter(filterObj.filterFunc).length);
-							doh.is(1, dojo.query("*").filter(filterObj.filterFunc, filterObj).length);
-							verify((new dojo.NodeList(t)).filter("span").end(), ["t"]);
+							if(name != "t"){
+							// this gets messed up by new DOM nodes the second time around
+								doh.is(query("body :first-child").filter(":last-child")[0], c);
+								doh.is(1, query("*").filter(function(n){ return (n.nodeName.toLowerCase() == "span"); }).length);
+	
+								var filterObj = {
+									filterFunc: function(n){
+										return (n.nodeName.toLowerCase() == "span");
+									}
+								};
+								doh.is(1, query("*").filter(filterObj.filterFunc).length);
+								doh.is(1, query("*").filter(filterObj.filterFunc, filterObj).length);
+								verify((new NodeList(t)).filter("span").end(), ["t"]);
+							}
 						},
 
 						// layout DOM functions
 						function coords(){
-							var tnl = new dojo.NodeList(dojo.byId('sq100'))
+							var tnl = new NodeList(dojo.byId('sq100'));
 							doh.t(dojo.isArray(tnl));
 							doh.is(100, tnl.coords()[0].w);
 							doh.is(100, tnl.coords()[0].h);
 							doh.is(100, tnl.position()[0].w);
 							doh.is(100, tnl.position()[0].h);
-							doh.is(document.body.getElementsByTagName("*").length, dojo.query("body *").coords().length);
-							doh.is(document.body.getElementsByTagName("*").length, dojo.query("body *").position().length);
+							doh.is(document.body.getElementsByTagName("*").length, query("body *").coords().length);
+							doh.is(document.body.getElementsByTagName("*").length, query("body *").position().length);
 						},
 
 						function styleGet(){
 							// test getting
-							var tnl = new dojo.NodeList(s);
+							var tnl = new NodeList(s);
 							doh.is(1, tnl.style("opacity")[0]);
 							tnl.push(t);
 							dojo.style(t, "opacity", 0.5);
@@ -282,7 +285,7 @@
 
 						function styleSet(){
 							// test setting
-							var tnl = new dojo.NodeList(s, t);
+							var tnl = new NodeList(s, t);
 							tnl.style("opacity", 0.5);
 							doh.is(0.5, dojo.style(tnl[0], "opacity"));
 							doh.is(0.5, dojo.style(tnl[1], "opacity"));
@@ -291,7 +294,7 @@
 						},
 
 						function style(){
-							var tnl = new dojo.NodeList(s, t);
+							var tnl = new NodeList(s, t);
 							tnl.style("opacity", 1);
 							doh.is(1, tnl.style("opacity")[0]);
 							dojo.style(t, "opacity", 0.5);
@@ -302,7 +305,7 @@
 						},
 
 						function addRemoveClass(){
-							var tnl = new dojo.NodeList(s, t);
+							var tnl = new NodeList(s, t);
 							tnl.addClass("a");
 							doh.is("a", s.className);
 							doh.is("a", t.className);
@@ -349,27 +352,30 @@
 						},
 
 						function concat(){
-							var spans = dojo.query("span");
-							var divs = dojo.query("div");
-							var cat = spans.concat(divs);
-							console.debug(cat);
-							doh.t(cat.constructor == dojo.NodeList || cat.constructor == NodeList);
-							doh.is((divs.length + spans.length), cat.length);
-							verify(cat.end(), ["c1"]);
+							if(name != "t"){
+								// this isn't supported in the new query method
+								var spans = query("span");
+								var divs = query("div");
+								var cat = spans.concat(divs);
+								console.debug(cat);
+								doh.t(cat.constructor == dojo.NodeList || cat.constructor == dojo.NodeList);
+								doh.is((divs.length + spans.length), cat.length);
+								verify(cat.end(), ["c1"]);
+							}
 						},
 
 						function concat2(){
-							var spans = dojo.query("span");
-							var divs = dojo.query("div");
+							var spans = query("span");
+							var divs = query("div");
 							doh.is(spans.concat([]).constructor, dojo.NodeList);
 						},
 
 						function concat3(){
-							var spans = dojo.query("span");
-							var divs = dojo.query("div");
+							var spans = query("span");
+							var divs = query("div");
 							var cat = spans.concat(divs);
 
-							doh.t(typeof NodeList != "undefined" && cat.constructor === NodeList
+							doh.t(typeof NodeList != "undefined" && cat.constructor === dojo.NodeList
 								|| cat.constructor === dojo.NodeList);
 						},
 
@@ -379,8 +385,8 @@
 							var tn = document.createElement("div");
 							tn.innerHTML = ih;
 							dojo.body().appendChild(tn);
-							var nl = dojo.query("b", tn).place(tn, "first");
-							doh.t(nl.constructor == dojo.NodeList || nl.constructor == NodeList);
+							var nl = query("b", tn).place(tn, "first");
+							doh.t(nl.constructor == dojo.NodeList || nl.constructor == dojo.NodeList);
 							doh.is(1, nl.length);
 							doh.is("b", nl[0].nodeName.toLowerCase());
 							doh.is(tn, nl[0].parentNode);
@@ -393,23 +399,23 @@
 							var tn = document.createElement("div");
 							tn.innerHTML = ih;
 							dojo.body().appendChild(tn);
-							var nl = dojo.query("span", tn).orphan();
-							doh.t(nl.constructor == dojo.NodeList || nl.constructor == NodeList);
+							var nl = query("span", tn).orphan();
+							doh.t(nl.constructor == dojo.NodeList || nl.constructor == dojo.NodeList);
 
 							doh.is(2, nl.length);
 							doh.is(1, tn.getElementsByTagName("*").length);
 
 							tn.innerHTML = ih;
-							var nl = dojo.query("*", tn).orphan("b");
+							var nl = query("*", tn).orphan("b");
 							doh.is(1, nl.length);
 							doh.is("blah", nl[0].innerHTML);
 						},
 
 						function adopt(){
-							var div = dojo.query(dojo.create("div"));
+							var div = query(dojo.create("div"));
 							div.adopt(dojo.create("span"));
 							div.adopt(dojo.create("em"), "first");
-							doh.is(2, dojo.query("*", div[0]).length);
+							doh.is(2, query("*", div[0]).length);
 							doh.is("em", div[0].firstChild.tagName.toLowerCase());
 							doh.is("span", div[0].lastChild.tagName.toLowerCase());
 						},
@@ -417,7 +423,7 @@
 						function addContent(){
 							//text content
 							var tn = document.createElement("div");
-							var nl = dojo.query(tn).addContent("some text content");
+							var nl = query(tn).addContent("some text content");
 
 							doh.is(1, nl[0].childNodes.length);
 							doh.is("some text content", nl[0].firstChild.nodeValue);
@@ -434,9 +440,8 @@
 							doh.is("addContent1", nl[0].lastChild.id);
 
 							//put in multiple content/clone node
-							tn.innerHTML = '<select><option name="second"  value="second" selected>second</option></select>'
-							               '<select><option name="second"  value="second" selected>second</option></select>';
-							nl = dojo.query("select", tn).addContent('<option name="first" value="first">first</option>', "first");
+							tn.innerHTML = '<select><option name="second"  value="second" selected>second</option></select>';
+							nl = query("select", tn).addContent('<option name="first" value="first">first</option>', "first");
 							nl.forEach(function(node){
 								doh.is("first", node.options[0].value);
 								doh.f(node.options[0].selected);
@@ -445,7 +450,7 @@
 							//Some divs to use for addContent template actions.
 							var templs = dojo._toDom('<div class="multitemplate"></div><div class="multitemplate"></div>');
 							dojo.body().appendChild(templs);
-							templs = dojo.query(".multitemplate");
+							templs = query(".multitemplate");
 
 							//templateFunc test
 							templs.addContent({
@@ -502,12 +507,12 @@
 						function connect(){
 							var ih = "<div><span></span></div><span class='thud'><button>blah</button></span>";
 
-							var tn = document.createElement("div");
+							tn = document.createElement("div");
 							tn.innerHTML = ih;
 							dojo.body().appendChild(tn);
 
 							var ctr = 0;
-							var nl = dojo.query("button", tn).connect("onclick", function(){
+							var nl = query("button", tn).connect("onclick", function(){
 								ctr++;
 							});
 							nl[0].click();
@@ -516,37 +521,108 @@
 							nl[0].click();
 							doh.is(3, ctr);
 						},
+						function on(){
+							var ctr = 0;
+							dojo.body().appendChild(tn);
+							var nl = query("button", tn);
+							var handle = nl.on("click", function(){
+								ctr++;
+							});
+							nl[0].click();
+							doh.is(1, ctr);
+							var inButton = nl[0].appendChild(document.createElement("span"));
+							listen.emit(nl[0], "click", {
+							});
+							listen.emit(inButton, "click", {
+								bubbles: true
+							});
+							listen.emit(inButton, "click", {
+								bubbles: false
+							});
+							doh.is(3, ctr);
+							handle.remove();
+							listen.emit(nl[0], "click", {
+							});
+							doh.is(3, ctr);
+						},
+						function onDelegate(){
+							var ctr = 0;
+							dojo.body().appendChild(tn);
+							var nl = query(".thud", tn);
+							var bl = query("button", tn);
+							var handle = nl.on("button:click", function(){
+								doh.is(this, bl[0]);
+								ctr++;
+							});
+							doh.is(0, ctr);
+							listen.emit(nl[0], "click", {
+							});
+							listen.emit(bl[0], "click", {
+								bubbles: true
+							});
+							doh.is(1, ctr);
+							handle.remove();
+							listen.emit(bl[0], "click", {
+								bubbles: true
+							});
+							doh.is(1, ctr);
+							// listen and on should behave the same
+							query(tn).on(".thud:click, .thud button:custom", function(){
+								ctr++;
+							});
+							listen.emit(bl[0], "click", {
+								bubbles: true
+							});
+							doh.is(2, ctr);
+							listen.emit(bl[0], "click", {
+								bubbles: false
+							});
+							doh.is(2, ctr);
+							listen.emit(bl[0], "custom", {
+								bubbles: true
+							});
+							doh.is(3, ctr);
+							listen.emit(bl[0], "mouseout", {
+								bubbles: true
+							});
+							doh.is(3, ctr);
+							bl[0].click();
+							doh.is(4, ctr);
+						},
 
 						function at(){
-							var divs = dojo.query("body div");
+							var divs = query("body div");
 							var at0 = divs.at(0);
 							doh.is(divs[0], at0[0]);
-
-							var at1 = divs.at(1,3,5);
-							doh.is(divs[1], at1[0]);
-							doh.is(divs[3], at1[1]);
-							doh.is(divs[5], at1[2]);
-
-							var at2 = divs.at(3,6,9);
-							doh.is(at2.length, 2);
-
-							var at3 = divs.at(3,6).at(1);
-							doh.is(divs[6], at3[0]);
-
-							var ending = divs.at(0).end();
-							verify([ending[0], ending[1]], ["sq100", "t"]);
-							
-							var at4 = divs.at(-1);
-							doh.is(divs[divs.length - 1], at4[0]);
-							
-							var at5 = divs.at(1, -1);
-							doh.is(at5[0], divs[1]);
-							doh.is(at5[1], divs[divs.length - 1]);
+							if(name != "t"){
+								// this gets messed up by new DOM nodes the second time around
+								
+								var at1 = divs.at(1,3,5);
+								doh.is(divs[1], at1[0]);
+								doh.is(divs[3], at1[1]);
+								doh.is(divs[5], at1[2]);
+	
+								var at2 = divs.at(3,6,9);
+								doh.is(at2.length, 2);
+	
+								var at3 = divs.at(3,6).at(1);
+								doh.is(divs[6], at3[0]);
+	
+								var ending = divs.at(0).end();
+								verify([ending[0], ending[1]], ["sq100", "t"]);
+								
+								var at4 = divs.at(-1);
+								doh.is(divs[divs.length - 1], at4[0]);
+								
+								var at5 = divs.at(1, -1);
+								doh.is(at5[0], divs[1]);
+								doh.is(at5[1], divs[divs.length - 1]);
+							}
 							
 						},
 
 						function attr(){
-							var divs = dojo.query("div");
+							var divs = query("div");
 							var ids = divs.attr("id");
 						},
 
@@ -560,7 +636,7 @@
 								}
 							};
 							dojo.NodeList.prototype.setTrue = dojo.NodeList._adaptAsForEach(i.setTrue, i);
-							var divs = dojo.query("div").setTrue();
+							var divs = query("div").setTrue();
 							doh.t(passes);
 							doh.is(count, divs.length);
 						},
@@ -578,26 +654,25 @@
 								}
 							});
 
-							dojo.query("#thinger").instantiate(tests._base.NodeList.some.Thing, {
+							query("#thinger").instantiate(tests._base.NodeList.some.Thing, {
 								foo:"bar"
 							});
 
-							dojo.query("#thinger2").instantiate("tests._base.NodeList.some.Thing", {
+							query("#thinger2").instantiate("tests._base.NodeList.some.Thing", {
 								foo:"bar"
 							});
 
 							doh.is(2, test);
 
 							//clean up the divs inserted for the test.
-							dojo.query("#thinger, #thinger2").orphan();
+							query("#thinger, #thinger2").orphan();
 						},
 						
 						function removeAttr(){
-							
 							// buildup
 							dojo.place('<p id="attr" title="Foobar">Hi</p>', dojo.body());
 							
-							var n = dojo.query("#attr");
+							var n = query("#attr");
 							
 							doh.t(dojo.hasAttr(n[0], "title"));
 							
@@ -614,8 +689,14 @@
 						}
 					]
 				);
-				doh.run();
+			}
+			registerForNodeList("t-backcompat", dojo.query, function(){
+				return dojo.NodeList.apply(dojo.NodeList, arguments);
 			});
+			registerForNodeList("t", query, dojo.NodeList);
+			
+			doh.run();
+		});
 		</script>
 	</head>
 	<body>
diff --git a/dojo/tests/_base/_loader/afterOnLoad.html b/dojo/tests/_base/_loader/afterOnLoad.html
deleted file mode 100644
index ed4c7a0..0000000
--- a/dojo/tests/_base/_loader/afterOnLoad.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>
-		<title>Testing afterOnLoad</title>
-
-		<link rel="stylesheet" type="text/css" href="../../../resources/dojo.css"/>
-		<link rel="stylesheet" type="text/css" href="../../../../dijit/tests/css/dijitTests.css"/>
-		<link rel="stylesheet" type="text/css" href="../../../../dijit/themes/tundra/tundra.css"/>
-
-		<script type="text/javascript">
-			function init(){
-				//Create global djConfig object first. We cannot use the djConfig attribute
-				//on the script tag since it may not be visible in some browsers at the time
-				//dojo.js executes. This causes problems when the "require" property is used
-				//as part of djConfig. Also note that you have to set baseUrl directly, since
-				//it cannot be detected as part of script tag.
-				djConfig = {
-					baseUrl: "../../../",
-					parseOnLoad: true,
-					afterOnLoad:true,
-					addOnLoad: function(){
-						//This function is registered with
-						//dojo.addOnLoad as Dojo is defined after
-						//being added to the DOM.
-						console.log("djConfig.addOnLoad callback fired OK: dojo.parser.parse is a "
-							+ (typeof dojo.parser.parse));
-					},
-					require: [
-						'dojo.parser',
-						'dijit.Calendar'
-					],
-					isDebug: true
-				};
-
-				var script = document.createElement("script");
-				script.type = "text/javascript";
-				script.src = "../../../dojo.js";
-				
-				document.getElementsByTagName("head")[0].appendChild(script);
-			}
-
-			function myHandler(id,newValue){
-				console.debug("onChange for id = " + id + ", value: " + newValue);
-			}
-			
-			//Register onload init function that will add Dojo to the page.
-			if(window.addEventListener){
-				window.addEventListener("load", init, false);
-			}else{
-				window.attachEvent("onload", init);
-			}
-
-		</script>
-	</head>
-	<body>
-		<h1>Testing afterOnLoad</h1>
-
-		<p><b>This page only works with a dojo build</b>. It will not work properly if you run it directly from the subversion source.</p>
-
-		<p>This page tests loading dojo after the page is loaded. </p>
-		
-		<p>When the window.onload fires, the dojo script tag will be added to the DOM 
-		and configured to fire the onload callbacks. If everything works, you should
-		see a Calendar below.</p>
-		
-		<p class="tundra">
-			<input id="calendar1" dojoType="dijit.Calendar" onChange="myHandler(this.id,arguments[0])">
-		</p>
-	</body>
-</html>
diff --git a/dojo/tests/_base/_loader/bootstrap.js b/dojo/tests/_base/_loader/bootstrap.js
deleted file mode 100644
index 1e6ef9b..0000000
--- a/dojo/tests/_base/_loader/bootstrap.js
+++ /dev/null
@@ -1,134 +0,0 @@
-dojo.provide("tests._base._loader.bootstrap");
-
-tests.register("tests._base._loader.bootstrap",
-	[
-
-		function hasConsole(t){
-			t.assertTrue("console" in dojo.global);
-			t.assertTrue("assert" in console);
-			t.assertEqual("function", typeof console.assert);
-		},
-
-		{
-			name: "getObject",
-			setUp: function(){
-				//Set an object in global scope.
-				dojo.global.globalValue = {
-					color: "blue",
-					size: 20
-				};
-				
-				//Set up an object in a specific scope.
-				this.foo = {
-					bar: {
-						color: "red",
-						size: 100
-					}
-				};
-			},
-			runTest: function(t){
-				//Test for existing object using global as root path.
-				var globalVar = dojo.getObject("globalValue");
-				t.is("object", (typeof globalVar));
-				t.assertEqual("blue", globalVar.color);
-				t.assertEqual(20, globalVar.size);
-				t.assertEqual("blue", dojo.getObject("globalValue.color"));
-				
-				//Test for non-existent object using global as root path.
-				//Then create it.
-				t.assertFalse(dojo.getObject("something.thatisNew"));
-				t.assertTrue(typeof(dojo.getObject("something.thatisNew", true)) == "object");
-				
-				//Test for existing object using another object as root path.
-				var scopedVar = dojo.getObject("foo.bar", false, this);
-				t.assertTrue(typeof(scopedVar) == "object");
-				t.assertEqual("red", scopedVar.color);
-				t.assertEqual(100, scopedVar.size);
-				t.assertEqual("red", dojo.getObject("foo.bar.color", true, this));
-				
-				//Test for existing object using another object as root path.
-				//Then create it.
-				t.assertFalse(dojo.getObject("something.thatisNew", false, this));
-				t.assertTrue(typeof(dojo.getObject("something.thatisNew", true, this)) == "object");
-			},
-			tearDown: function(){
-				//Clean up global object that should not exist if
-				//the test is re-run.
-				try{
-					delete dojo.global.something;
-					delete this.something;
-				}catch(e){}
-			}
-		},
-		
-		{
-			name: "exists",
-			setUp: function(){
-				this.foo = {
-					bar: {},
-					baz: 0,
-					bam: false,
-					bal: "",
-					ban: null
-				};
-			},
-			runTest: function(t){
-				t.assertTrue(dojo.exists("foo.bar", this));
-				t.assertFalse(dojo.exists("foo.bar"));
-				t.assertTrue(dojo.exists("foo.baz", this));
-				t.assertTrue(dojo.exists("foo.bal", this));
-				t.assertTrue(dojo.exists("foo.ban", this));
-				t.assertTrue(dojo.exists("foo.bam", this));
-				t.assertFalse(dojo.exists("foo.bat", this));
-				t.assertTrue(dojo.exists("a.b", { a:{ b:0 }}));
-				t.assertFalse(dojo.exists("foo.bar.baz.bam.bap", this));
-			}
-		},
-
-		function evalWorks(t){
-			t.assertTrue(dojo.eval("(true)"));
-			t.assertFalse(dojo.eval("(false)"));
-		},
-		
-		function _mixin(t){
-			var a = {
-				x: 1,
-				y: function(){ return 2; },
-				z1: 99,
-				w: 2,
-				v: undefined
-			};
-			var b = {
-				x: 11,
-				y: function(){ return 12; },
-				z2: 33,
-				toString: function(){ return "bark!"; },
-				toLocaleString: function(){ return "le bark-s!"; },
-				w: undefined,
-				v: undefined,
-				u: undefined
-			};
-			t.is(1, a.x);
-			t.is(2, a.y());
-			t.is(99, a.z1);
-			t.t("w" in a);
-			t.is(2, a.w);
-			t.t("v" in a);
-			t.is(undefined, a.v);
-			t.f("u" in a);
-			dojo._mixin(a, b);
-			t.is(11, a.x);
-			t.is(12, a.y());
-			t.is("bark!", a.toString());
-			t.is("le bark-s!", a.toLocaleString());
-			t.is(99, a.z1);
-			t.is(33, a.z2);
-			t.t("w" in a);
-			t.is(undefined, a.w);
-			t.t("v" in a);
-			t.is(undefined, a.v);
-			t.t("u" in a);
-			t.is(undefined, a.u);
-		}
-	]
-);
diff --git a/dojo/tests/_base/_loader/config-data-global.html b/dojo/tests/_base/_loader/config-data-global.html
deleted file mode 100644
index 611ce8b..0000000
--- a/dojo/tests/_base/_loader/config-data-global.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<title>testing dojo.config</title>
-		<script>
-			var dojoConfig = {
-				isDebug:true,
-				cats:'dogs',
-				a:2, b:[1,2,3]
-			};
-		</script>
-		<script type="text/javascript" src="../../../dojo.js"></script>
-		<script type="text/javascript">
-			dojo.require("doh.runner");
-			dojo.ready(function(){
-				doh.register("t", [
-					function gotConfig(t){
-						t.is("dogs", dojo.config.cats);
-						t.is(2, dojo.config.a);
-						t.is(3, dojo.config.b.length);
-					}
-				]);
-				doh.run();
-			})
-		</script>
-	</head>
-	<body>
-		<h2>Test data-dojo-config Param</h2>
-	</body>
-</html>
-
diff --git a/dojo/tests/_base/_loader/config-data.html b/dojo/tests/_base/_loader/config-data.html
deleted file mode 100644
index 641a90b..0000000
--- a/dojo/tests/_base/_loader/config-data.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<title>testing dojo.config</title>
-		<script type="text/javascript" src="../../../dojo.js" data-dojo-config="isDebug: true, cats:'dogs', a:2, b:[1,2,3]"></script>
-		<script type="text/javascript">
-			dojo.require("doh.runner");
-			dojo.ready(function(){
-				doh.register("t", [
-					function gotConfig(t){
-						t.is("dogs", dojo.config.cats);
-						t.is(2, dojo.config.a);
-						t.is(3, dojo.config.b.length);
-					}
-				]);
-				doh.run();
-			})
-		</script>
-	</head>
-	<body>
-		<h2>Test data-dojo-config Param</h2>
-	</body>
-</html>
-
diff --git a/dojo/tests/_base/_loader/config-dj-elemt.html b/dojo/tests/_base/_loader/config-dj-elemt.html
deleted file mode 100644
index af3cc53..0000000
--- a/dojo/tests/_base/_loader/config-dj-elemt.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<title>testing dojo.config</title>
-		<script type="text/javascript" src="../../../dojo.js" djConfig="isDebug: true, cats:'dogs', a:2, b:[1,2,3]"></script>
-		<script type="text/javascript">
-			dojo.require("doh.runner");
-			dojo.ready(function(){
-				doh.register("t", [
-					function gotConfig(t){
-						t.is("dogs", dojo.config.cats);
-						t.is(2, dojo.config.a);
-						t.is(3, dojo.config.b.length);
-					}
-				]);
-				doh.run();
-			})
-		</script>
-	</head>
-	<body>
-		<h2>Test data-dojo-config Param</h2>
-	</body>
-</html>
-
diff --git a/dojo/tests/_base/_loader/config-dj-global.html b/dojo/tests/_base/_loader/config-dj-global.html
deleted file mode 100644
index bd08b62..0000000
--- a/dojo/tests/_base/_loader/config-dj-global.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<title>testing dojo.config</title>
-		<script>
-			var djConfig = {
-				isDebug:true, cats:"dogs", a:2, b:[1,2,3]
-			};
-		</script>
-		<script type="text/javascript" src="../../../dojo.js"></script>
-		<script type="text/javascript">
-			dojo.require("doh.runner");
-			dojo.ready(function(){
-				doh.register("t", [
-					function gotConfig(t){
-						t.is("dogs", dojo.config.cats);
-						t.is(2, dojo.config.a);
-						t.is(3, dojo.config.b.length);
-					}
-				]);
-				doh.run();
-			})
-		</script>
-	</head>
-	<body>
-		<h2>Test data-dojo-config Param</h2>
-	</body>
-</html>
-
diff --git a/dojo/tests/_base/_loader/debugConsole.html b/dojo/tests/_base/_loader/debugConsole.html
deleted file mode 100644
index d9018cf..0000000
--- a/dojo/tests/_base/_loader/debugConsole.html
+++ /dev/null
@@ -1,51 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<title>testing debugging and logging functions</title>
-		<script type="text/javascript">
-			djConfig = {};
-			if( document.location.href.match(/\?ON/)) {
-				djConfig.isDebug = true;
-			} else {
-				djConfig.isDebug = false;
-			}
-		</script>
-		<script type="text/javascript" src="../../../dojo.js"></script>
-		<script type="text/javascript">
-			dojo.addOnLoad(function(){
-				var toggle = document.getElementById("toggle").innerHTML = djConfig.isDebug?"ON":"OFF";
-			});
-			
-			var aString = "this is my test string";
-			var anObject = {
-				aProperty: "aValue",
-				anotherProperty: "anotherValue",
-				aNumber: 1234
-			};
-			
-			var cn = ["debug","log",
-				"assert", "count", "dir", "dirxml", "error", "group",
-				"groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
-				"trace", "warn"
-			];
-			for(var i=0;i<cn.length;i++) {
-				console[cn[i]]( cn[i] + ": " + aString);
-				console[cn[i]]( cn[i] + ": " + anObject);
-			}
-		</script>
-	</head>
-	<body>
-		<p>
-			Testing console.* methods with djConfig.isDebug turned <span id="toggle"></span>
-		</p>
-		<p>
-			Append '?ON' to URL to try with djConfig.isDebug turned ON. Remove it to test djConfig.isDebug turned OFF
-		</p>
-		<p>
-			If isDebug is off (false), then make sure console functions go to a simple empty function. You may see 
-			errors in the console, since console.error is being tested as part of this test.
-		</p>
-	</body>
-</html>
-
diff --git a/dojo/tests/_base/_loader/hostenv_browser.js b/dojo/tests/_base/_loader/hostenv_browser.js
deleted file mode 100644
index 2699d43..0000000
--- a/dojo/tests/_base/_loader/hostenv_browser.js
+++ /dev/null
@@ -1,17 +0,0 @@
-dojo.provide("tests._base._loader.hostenv_browser");
-
-tests.register("tests._base._loader.hostenv_browser",
-	[
-		function getText(t){
-			var filePath = dojo.moduleUrl("tests._base._loader", "getText.txt");
-			var text = dojo._getText(filePath);
-			t.assertEqual("dojo._getText() test data", text);
-		}
-	]
-);
-
-tests.registerUrl("tests._base._loader.data-config", dojo.moduleUrl("tests._base._loader", "config-data-global.html"));
-tests.registerUrl("tests._base._loader.data-elem-config", dojo.moduleUrl("tests._base._loader", "config-data.html"));
-tests.registerUrl("tests._base._loader.dj-config", dojo.moduleUrl("tests._base._loader", "config-dj-global.html"));
-tests.registerUrl("tests._base._loader.dj-elem-config", dojo.moduleUrl("tests._base._loader", "config-dj-elemt.html"));
-
diff --git a/dojo/tests/_base/_loader/hostenv_rhino.js b/dojo/tests/_base/_loader/hostenv_rhino.js
deleted file mode 100644
index 6648c16..0000000
--- a/dojo/tests/_base/_loader/hostenv_rhino.js
+++ /dev/null
@@ -1,13 +0,0 @@
-dojo.provide("tests._base._loader.hostenv_rhino");
-
-tests.register("tests._base._loader.hostenv_rhino",
-	[
-		function getText(t){
-			var filePath = dojo.moduleUrl("tests._base._loader", "getText.txt");
-			var text = (new String(readText(filePath)));
-			//The Java file read seems to add a line return.
-			text = text.replace(/[\r\n]+$/, "");
-			t.assertEqual("dojo._getText() test data", text);
-		}
-	]
-);
diff --git a/dojo/tests/_base/_loader/hostenv_spidermonkey.js b/dojo/tests/_base/_loader/hostenv_spidermonkey.js
deleted file mode 100644
index 599df2d..0000000
--- a/dojo/tests/_base/_loader/hostenv_spidermonkey.js
+++ /dev/null
@@ -1,11 +0,0 @@
-dojo.provide("tests._base._loader.hostenv_spidermonkey");
-
-tests.register("tests._base._loader.hostenv_spidermonkey",
-	[
-		function getText(t){
-			var filePath = dojo.moduleUrl("tests._base._loader", "getText.txt");
-			var text = readText(filePath);
-			t.assertEqual("dojo._getText() test data", text);
-		}
-	]
-);
diff --git a/dojo/tests/_base/_loader/loader.js b/dojo/tests/_base/_loader/loader.js
deleted file mode 100644
index 693dc35..0000000
--- a/dojo/tests/_base/_loader/loader.js
+++ /dev/null
@@ -1,115 +0,0 @@
-dojo.provide("tests._base._loader.loader");
-
-tests.register("tests._base._loader.loader",
-	[
-		function baseUrl(t){
-			var originalBaseUrl = dojo.config["baseUrl"] || "./";
-
-			t.assertEqual(originalBaseUrl, dojo.baseUrl);
-		},
-		
-		function modulePaths(t){
-			dojo.registerModulePath("mycoolmod", "../some/path/mycoolpath");
-			dojo.registerModulePath("mycoolmod.widget", "http://some.domain.com/another/path/mycoolpath/widget");
-
-			t.assertEqual("../some/path/mycoolpath/util", dojo._getModuleSymbols("mycoolmod.util").join("/"));
-			t.assertEqual("http://some.domain.com/another/path/mycoolpath/widget", dojo._getModuleSymbols("mycoolmod.widget").join("/"));
-			t.assertEqual("http://some.domain.com/another/path/mycoolpath/widget/thingy", dojo._getModuleSymbols("mycoolmod.widget.thingy").join("/"));
-		},
-		
-		function moduleUrls(t){
-			dojo.registerModulePath("mycoolmod", "some/path/mycoolpath");
-			dojo.registerModulePath("mycoolmod2", "/some/path/mycoolpath2");
-			dojo.registerModulePath("mycoolmod.widget", "http://some.domain.com/another/path/mycoolpath/widget");
-			dojo.registerModulePath("ipv4.widget", "http://ipv4user:ipv4passwd@some.domain.com:2357/another/path/ipv4/widget");
-			dojo.registerModulePath("ipv6.widget", "ftp://ipv6user:ipv6passwd@[::2001:0db8:3c4d:0015:0:0:abcd:ef12]:1113/another/path/ipv6/widget");
-			dojo.registerModulePath("ipv6.widget2", "https://[0:0:0:0:0:1]/another/path/ipv6/widget2");
-
-
-			var basePrefix = dojo.baseUrl;
-			//dojo._Uri will strip off "./" characters, so do the same here
-			if(basePrefix == "./"){
-				basePrefix = "";
-			}
-			
-			t.assertEqual(basePrefix + "some/path/mycoolpath/my/favorite.html",
-				dojo.moduleUrl("mycoolmod", "my/favorite.html").toString());
-			t.assertEqual(basePrefix + "some/path/mycoolpath/my/favorite.html",
-				dojo.moduleUrl("mycoolmod.my", "favorite.html").toString());
-
-			t.assertEqual("/some/path/mycoolpath2/my/favorite.html",
-				dojo.moduleUrl("mycoolmod2", "my/favorite.html").toString());
-			t.assertEqual("/some/path/mycoolpath2/my/favorite.html",
-				dojo.moduleUrl("mycoolmod2.my", "favorite.html").toString());
-
-			t.assertEqual("http://some.domain.com/another/path/mycoolpath/widget/my/favorite.html",
-				dojo.moduleUrl("mycoolmod.widget", "my/favorite.html").toString());
-			t.assertEqual("http://some.domain.com/another/path/mycoolpath/widget/my/favorite.html",
-				dojo.moduleUrl("mycoolmod.widget.my", "favorite.html").toString());
-
-			// individual component testing
-			t.assertEqual("http://ipv4user:ipv4passwd@some.domain.com:2357/another/path/ipv4/widget/components.html",
-				dojo.moduleUrl("ipv4.widget", "components.html").uri);
-			t.assertEqual("http",
-				dojo.moduleUrl("ipv4.widget", "components.html").scheme);
-			t.assertEqual("ipv4user:ipv4passwd at some.domain.com:2357",
-				dojo.moduleUrl("ipv4.widget", "components.html").authority);
-			t.assertEqual("ipv4user",
-				dojo.moduleUrl("ipv4.widget", "components.html").user);
-			t.assertEqual("ipv4passwd",
-				dojo.moduleUrl("ipv4.widget", "components.html").password);
-			t.assertEqual("some.domain.com",
-				dojo.moduleUrl("ipv4.widget", "components.html").host);
-			t.assertEqual("2357",
-				dojo.moduleUrl("ipv4.widget", "components.html").port);
-			t.assertEqual("/another/path/ipv4/widget/components.html",
-				dojo.moduleUrl("ipv4.widget", "components.html?query").path);
-			t.assertEqual("q=somequery",
-				dojo.moduleUrl("ipv4.widget", "components.html?q=somequery").query);
-			t.assertEqual("fragment",
-				dojo.moduleUrl("ipv4.widget", "components.html#fragment").fragment);
-
-			t.assertEqual("ftp://ipv6user:ipv6passwd@[::2001:0db8:3c4d:0015:0:0:abcd:ef12]:1113/another/path/ipv6/widget/components.html",
-				dojo.moduleUrl("ipv6.widget", "components.html").uri);
-			t.assertEqual("ftp",
-				dojo.moduleUrl("ipv6.widget", "components.html").scheme);
-			t.assertEqual("ipv6user:ipv6passwd@[::2001:0db8:3c4d:0015:0:0:abcd:ef12]:1113",
-				dojo.moduleUrl("ipv6.widget", "components.html").authority);
-			t.assertEqual("ipv6user",
-				dojo.moduleUrl("ipv6.widget", "components.html").user);
-			t.assertEqual("ipv6passwd",
-				dojo.moduleUrl("ipv6.widget", "components.html").password);
-			t.assertEqual("::2001:0db8:3c4d:0015:0:0:abcd:ef12",
-				dojo.moduleUrl("ipv6.widget", "components.html").host);
-			t.assertEqual("1113",
-				dojo.moduleUrl("ipv6.widget", "components.html").port);
-			t.assertEqual("/another/path/ipv6/widget/components.html",
-				dojo.moduleUrl("ipv6.widget", "components.html?query").path);
-			t.assertEqual("somequery",
-				dojo.moduleUrl("ipv6.widget", "components.html?somequery").query);
-			t.assertEqual("somefragment",
-				dojo.moduleUrl("ipv6.widget", "components.html?somequery#somefragment").fragment);
-
-			t.assertEqual("https://[0:0:0:0:0:1]/another/path/ipv6/widget2/components.html",
-				dojo.moduleUrl("ipv6.widget2", "components.html").uri);
-			t.assertEqual("https",
-				dojo.moduleUrl("ipv6.widget2", "components.html").scheme);
-			t.assertEqual("[0:0:0:0:0:1]",
-				dojo.moduleUrl("ipv6.widget2", "components.html").authority);
-			t.assertEqual(null,
-				dojo.moduleUrl("ipv6.widget2", "components.html").user);
-			t.assertEqual(null,
-				dojo.moduleUrl("ipv6.widget2", "components.html").password);
-			t.assertEqual("0:0:0:0:0:1",
-				dojo.moduleUrl("ipv6.widget2", "components.html").host);
-			t.assertEqual(null,
-				dojo.moduleUrl("ipv6.widget2", "components.html").port);
-			t.assertEqual("/another/path/ipv6/widget2/components.html",
-				dojo.moduleUrl("ipv6.widget2", "components.html").path);
-			t.assertEqual(null,
-				dojo.moduleUrl("ipv6.widget2", "components.html").query);
-			t.assertEqual(null,
-				dojo.moduleUrl("ipv6.widget2", "components.html").fragment);
-		}
-	]
-);
diff --git a/dojo/tests/_base/_loader/modules.js b/dojo/tests/_base/_loader/modules.js
deleted file mode 100644
index 9385af4..0000000
--- a/dojo/tests/_base/_loader/modules.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// this module should not be transformed by the build inverse AMD-transform;
-// keeping define from the first line of the file and not providing an AMD-ID pragma prevents this module from being transformed
-define("dojo/tests/_base/_loader/modules", ["require", "dojo/_base/connect", "./modules/anon","./modules/wrapped","dojo/tests/_base/_loader/modules/full","./modules/data",".modules/factoryArity"], function(require, connect, anon, wrapped, factoryArity){
-
-tests.register("dojo.tests._base._loader.modules",
-	[
-		function testAMD(t){
-			// test AMD module API
-			t.assertEqual(anon.theAnswer, 42);
-			t.assertEqual(require('./modules/anon').five, 5);
-			t.assertEqual(wrapped.five, 5);
-			t.assertEqual(dojo.require('dojo.tests._base._loader.modules.wrapped').exports, require('./modules/wrapped'));
-			t.assertEqual(require('./modules/full').twiceTheAnswer, 84);
-			t.assertEqual(require('./modules/data').five, 5);
-			t.assertEqual(require('./modules/factoryArity').i, 5);
-			t.assertEqual(connect, dojo.connect);
-		}
-	]
-);
-});
-
diff --git a/dojo/tests/_base/_loader/modules/full.js b/dojo/tests/_base/_loader/modules/full.js
deleted file mode 100644
index 7ff222b..0000000
--- a/dojo/tests/_base/_loader/modules/full.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// this module should not be transformed by the build inverse AMD-transform;
-// keeping define from the first line of the file and not providing an AMD-ID pragma prevents this module from being transformed
-define("dojo/tests/_base/_loader/modules/full", ["./anon", "../a", "./wrapped", "require"], function (anon, a, wrapped, require) {
-	return {
-		twiceTheAnswer: a.number + require("../a").number
-	};
-});
\ No newline at end of file
diff --git a/dojo/tests/_base/_loader/modules/wrapped.js b/dojo/tests/_base/_loader/modules/wrapped.js
deleted file mode 100644
index 626a508..0000000
--- a/dojo/tests/_base/_loader/modules/wrapped.js
+++ /dev/null
@@ -1,4 +0,0 @@
-define(function (require, exports, module) {
-	exports.five = require("./data").five;
-	exports.exports = module.exports;
-});
\ No newline at end of file
diff --git a/dojo/tests/_base/_loader/scope/scope04.html b/dojo/tests/_base/_loader/scope/scope04.html
deleted file mode 100644
index c3a5bb1..0000000
--- a/dojo/tests/_base/_loader/scope/scope04.html
+++ /dev/null
@@ -1,80 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<title>Multiversion Dojo: 0.4.3 and 1.0</title>
-
-		<link rel="stylesheet" type="text/css" href="../../../../resources/dojo.css"/>
-		<link rel="stylesheet" type="text/css" href="../../../../../dijit/tests/css/dijitTests.css"/>
-		<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/tundra/tundra.css"/>
-		
-		<script type="text/javascript">
-			//djConfig for 0.4.3 setup.
-			djConfig = {
-				isDebug: true
-			};
-		</script>
-		<script type="text/javascript" src="http://o.aolcdn.com/dojo/0.4.3/dojo.js"></script>
-		
-		<script type="text/javascript">
-			//Need scope map defined in a script block. It will not work as part of the
-			//djConfig attribute on the script that loads Dojo.
-			//Also, just adding properties instead of redefining djConfig, since that
-			//will wipe out djConfig values set up by the 0.4.3 dojo.
-			djConfig.parseOnLoad = true;
-			djConfig.baseUrl = "../../../../";
-			djConfig.scopeMap = [
-				["dojo", "dojo10"],
-				["dijit", "dijit10"],
-				["dojox", "dojox10"]					
-			];
-		</script>
-		<script type="text/javascript" src="../../../../dojo.js"></script>
-		<script type="text/javascript">
-			dojo.require("dojo.widget.DropdownDatePicker");
-			dojo10.require("dijit.Calendar");
-			dojo10.require("dojo.date.locale");
-			dojo10.require("dojo.parser"); // scan page for widgets
-
-			dojo.addOnLoad(function(){
-				dojo.byId("output043").innerHTML = dojo.version.toString();
-			});
-			dojo10.addOnLoad(function(){
-				dojo.byId("output10").innerHTML = dojo10.version.toString();
-			});
-
-			function myHandler(id,newValue){
-				console.debug("onChange for id = " + id + ", value: " + newValue);
-			}
-			
-			function foobar(){
-				dojo.byId("typeOut").innerHTML = (typeof dojo.addClass);
-			}
-			setTimeout(foobar, 2000);
-
-		</script>
-	</head>
-	<body>
-		<h1>Multiversion Dojo: 0.4.3 and 1.0</h1>
-	
-		<p><b>NOTE: This test only works with a built version of Dojo</b></p>
-
-		<p>This page loads Dojo 0.4.3 and Dojo 1.0.</p>
-		
-		<p>Dojo 0.4.3 version: <span id="output043"></span></p>
-		
-		<p>Dojo 1.0 version: <span id="output10"></span></p>
-		
-		<p><b>dojo.addClass should be undefined:</b> <span id="typeOut"></span></p>
-		
-		<p>
-			<input dojoType="dropdowndatepicker" value="2006-10-31" containerToggle="wipe" containerToggleDuration="300" >
-		</p>
-		
-		<p class="tundra">
-			<input id="calendar1" dojo10Type="dijit.Calendar" onChange="myHandler(this.id,arguments[0])">
-		</p>
-		
-	</body>
-</html>
-
diff --git a/dojo/tests/_base/_loader/scope/scopeContained.html b/dojo/tests/_base/_loader/scope/scopeContained.html
deleted file mode 100644
index 490087c..0000000
--- a/dojo/tests/_base/_loader/scope/scopeContained.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>
-		<title>Multiversion Dojo: 0.4.3 and 1.0</title>
-
-		<link rel="stylesheet" type="text/css" href="../../../../resources/dojo.css"/>
-		<link rel="stylesheet" type="text/css" href="../../../../../dijit/tests/css/dijitTests.css"/>
-		<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/tundra/tundra.css"/>
-		
-		<script type="text/javascript">
-			//djConfig for 0.4.3 setup.
-			djConfig = {
-				isDebug: true
-			};
-		</script>
-		<script type="text/javascript" src="http://o.aolcdn.com/dojo/0.4.3/dojo.js"></script>
-		
-		<script type="text/javascript">
-			//Scope map for this page is "burned in" via a build command (see HTML notes below).
-			//Also, just adding properties instead of redefining djConfig, since that
-			//will wipe out djConfig values set up by the 0.4.3 dojo.
-			djConfig.parseOnLoad = true;
-			djConfig.baseUrl = "../../../../";
-		</script>
-		<script type="text/javascript" src="../../../../dojo.js"></script>
-		<script type="text/javascript">
-			dojo.require("dojo.widget.DropdownDatePicker");
-
-			//Notice that dijit.Calendar is required, not jidit._Calendar.
-			//Same for the dojo resources (not jodo resources).
-			jodo.require("dijit.Calendar");
-			jodo.require("dojo.date.locale");
-			jodo.require("dojo.parser"); // scan page for widgets
-
-			dojo.addOnLoad(function(){
-				dojo.byId("output043").innerHTML = dojo.version.toString();
-			});
-			jodo.addOnLoad(function(){
-				dojo.byId("output10").innerHTML = jodo.version.toString();
-			});
-
-			function myHandler(id,newValue){
-				console.debug("onChange for id = " + id + ", value: " + newValue);
-			}
-		</script>
-	</head>
-	<body>
-		<h1>Multiversion Dojo: 0.4.3 and 1.0</h1>
-	
-		<p><b>NOTE: This test only works with a built version of Dojo, and it must be built with the scopeMap parameter (the backslashes below are required):</b></p>
-
-		<p style="color: blue; background-color: yellow">build.sh profile=standard action=release scopeMap=[[\"dojo\",\"jodo\"],[\"dijit\",\"jidit\"],[\"dojox\",\"jodox\"]]</p>
-		
-		<p>This page loads Dojo 0.4.3 and Dojo 1.0 (under the jodo scope)</p>
-		
-		<p>Dojo 0.4.3 version: <span id="output043"></span></p>
-		
-		<p>Jodo version: <span id="output10"></span></p>
-		
-		<p>
-			<input dojoType="dropdowndatepicker" value="2006-10-31" containerToggle="wipe" containerToggleDuration="300" >
-		</p>
-		
-		<p class="tundra">
-			<input id="calendar1" jodoType="dijit.Calendar" onChange="myHandler(this.id,arguments[0])">
-		</p>
-		
-	</body>
-</html>
-
diff --git a/dojo/tests/_base/_loader/scope/scopeContainedXd.html b/dojo/tests/_base/_loader/scope/scopeContainedXd.html
deleted file mode 100644
index a0a99a0..0000000
--- a/dojo/tests/_base/_loader/scope/scopeContainedXd.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>
-		<title>Multiversion Dojo: 0.4.3 and 1.0</title>
-
-		<link rel="stylesheet" type="text/css" href="../../../../resources/dojo.css"/>
-		<link rel="stylesheet" type="text/css" href="../../../../../dijit/tests/css/dijitTests.css"/>
-		<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/tundra/tundra.css"/>
-		
-		<script type="text/javascript">
-			//djConfig for 0.4.3 setup.
-			djConfig = {
-				isDebug: true
-			};
-		</script>
-		<script type="text/javascript" src="http://o.aolcdn.com/dojo/0.4.3/dojo.js"></script>
-		
-		<script type="text/javascript">
-			//Scope map for this page is "burned in" via a build command (see HTML notes below).
-			//Also, just adding properties instead of redefining djConfig, since that
-			//will wipe out djConfig values set up by the 0.4.3 dojo.
-			djConfig.parseOnLoad = true;
-			djConfig.baseUrl = "../../../../";
-			djConfig.useXDomain = true; //Technically this was set already in the 0.4.3 xd dojo.js file.
-		</script>
-		<script type="text/javascript" src="../../../../dojo.xd.js"></script>
-		<script type="text/javascript">
-			dojo.require("dojo.widget.DropdownDatePicker");
-
-			//Get base xd path
-			var xdPath = location.href;
-			var lastIndex = location.href.lastIndexOf("/");
-			xdPath = xdPath.substring(0, lastIndex + 1);
-			
-			//Set up xdomain locations for dojo/dijit/dojox.
-			jodo.registerModulePath("dojo", xdPath + "../../../../../dojo");
-			jodo.registerModulePath("dijit", xdPath + "../../../../../dijit");
-			jodo.registerModulePath("dojox", xdPath + "../../../../../dojox");
-			
-			//Notice that dijit.Calendar is required, not jidit._Calendar.
-			//Same for the dojo resources (not jodo resources).
-			jodo.require("dijit.Calendar");
-			jodo.require("dojo.date.locale");
-			jodo.require("dojo.parser"); // scan page for widgets
-
-			dojo.addOnLoad(function(){
-				dojo.byId("output043").innerHTML = dojo.version.toString();
-			});
-			jodo.addOnLoad(function(){
-				dojo.byId("output10").innerHTML = jodo.version.toString();
-			});
-
-			function myHandler(id,newValue){
-				console.debug("onChange for id = " + id + ", value: " + newValue);
-			}
-		</script>
-	</head>
-	<body>
-		<h1>XDomain Multiversion Dojo: 0.4.3 and 1.0</h1>
-	
-		<p><b>NOTE: This test only works with a built, xdomain version of Dojo, and it must be built with the scopeMap parameter (the backslashes below are required):</b></p>
-
-		<p style="color: blue; background-color: yellow">build.sh profile=standard action=release scopeMap=[[\"dojo\",\"jodo\"],[\"dijit\",\"jidit\"],[\"dojox\",\"jodox\"]] xdDojoScopeName=jodo loader=xdomain</p>
-		
-		<p><b>Only load this page from an http:// URL</b>. Otherwise, the xd loading will not happen.</p>
-
-		<p>This page xdomain loads Dojo 0.4.3 and Dojo 1.0 (under the jodo scope)</p>
-		
-		<p>Dojo 0.4.3 version: <span id="output043"></span></p>
-		
-		<p>Jodo version: <span id="output10"></span></p>
-		
-		<p>
-			<input dojoType="dropdowndatepicker" value="2006-10-31" containerToggle="wipe" containerToggleDuration="300" >
-		</p>
-		
-		<p class="tundra">
-			<input id="calendar1" jodoType="dijit.Calendar" onChange="myHandler(this.id,arguments[0])">
-		</p>
-		
-	</body>
-</html>
-
diff --git a/dojo/tests/_base/_loader/scope/scopeDjConfig.html b/dojo/tests/_base/_loader/scope/scopeDjConfig.html
deleted file mode 100644
index 58b9cf9..0000000
--- a/dojo/tests/_base/_loader/scope/scopeDjConfig.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>
-		<title>Multiversion Dojo: 0.4.3 and 1.0 (scoped djConfig)</title>
-
-		<link rel="stylesheet" type="text/css" href="../../../../resources/dojo.css"/>
-		<link rel="stylesheet" type="text/css" href="../../../../../dijit/tests/css/dijitTests.css"/>
-		<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/tundra/tundra.css"/>
-		
-		<script type="text/javascript">
-			//djConfig for 0.4.3 setup.
-			djConfig = {
-				isDebug: true
-			};
-		</script>
-		<script type="text/javascript" src="http://o.aolcdn.com/dojo/0.4.3/dojo.js"></script>
-
-		<script type="text/javascript" src="../../../../dojo.js"></script>
-		<script type="text/javascript">
-			dojo.require("dojo.widget.DropdownDatePicker");
-
-			//Notice that dijit.Calendar is required, not jidit._Calendar.
-			//Same for the dojo resources (not jodo resources).
-			jodo.require("dijit.Calendar");
-			jodo.require("dojo.date.locale");
-			jodo.require("dojo.parser"); // scan page for widgets
-
-			dojo.addOnLoad(function(){
-				dojo.byId("output043").innerHTML = djConfig.baseUrl;
-			});
-			jodo.addOnLoad(function(){
-				dojo.byId("output10").innerHTML = jodo.baseUrl;
-			});
-
-			function myHandler(id,newValue){
-				console.debug("onChange for id = " + id + ", value: " + newValue);
-			}
-		</script>
-	</head>
-	<body>
-		<h1>Multiversion Dojo: 0.4.3 and 1.0 (scoped djConfig)</h1>
-	
-		<p><b>NOTE: This test only works with a built version of Dojo, and it must be built with the scopeDjConfig parameter (the backslashes below are required):</b></p>
-
-		<p style="color: blue; background-color: yellow">build.sh profile=standard action=release scopeDjConfig=\{parseOnLoad:true,baseUrl:\"../../../../\",foo:\"bar\",scopeMap:[[\"dojo\",\"jodo\"],[\"dijit\",\"jidit\"],[\"dojox\",\"jodox\"]]\}</p>
-		
-		<p>This page loads Dojo 0.4.3 and Dojo 1.0 (under the jodo scope)</p>
-		
-		<p>djConfig.baseUrl should <b>not</b> exist: <span id="output043"></span></p>
-		
-		<p>jodo.baseUrl should be "../../../../": <span id="output10"></span></p>
-		
-		<p>
-			<input dojoType="dropdowndatepicker" value="2006-10-31" containerToggle="wipe" containerToggleDuration="300" >
-		</p>
-		
-		<p class="tundra">
-			<input id="calendar1" jodoType="dijit.Calendar" onChange="myHandler(this.id,arguments[0])">
-		</p>
-		
-	</body>
-</html>
-
diff --git a/dojo/tests/_base/_loader/scope/scopeSingle.html b/dojo/tests/_base/_loader/scope/scopeSingle.html
deleted file mode 100644
index 1268050..0000000
--- a/dojo/tests/_base/_loader/scope/scopeSingle.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>
-		<title>Using scope names inside dojo.require/dojoType</title>
-
-		<link rel="stylesheet" type="text/css" href="../../../../resources/dojo.css"/>
-		<link rel="stylesheet" type="text/css" href="../../../../../dijit/tests/css/dijitTests.css"/>
-		<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/tundra/tundra.css"/>
-		
-		<script type="text/javascript">
-			//djConfig for 0.4.3 setup.
-			djConfig = {
-				isDebug: true,
-				parseOnLoad: true,
-				baseUrl: "../../../../",
-				scopeMap: [
-					["dojo", "jodo"],
-					["dijit", "jidit"],
-					["dojox", "jodox"]					
-				]
-			};
-		</script>
-
-		<script type="text/javascript" src="../../../../dojo.js"></script>
-		<script type="text/javascript">
-
-			//Notice that dijit.Calendar is required, not jidit._Calendar.
-			//Same for the dojo resources (not jodo resources).
-			jodo.require("dijit.Calendar");
-			jodo.require("dojo.date.locale");
-			jodo.require("dojo.parser"); // scan page for widgets
-
-			jodo.addOnLoad(function(){
-				jodo.byId("output10").innerHTML = jodo.version.toString();
-			});
-
-			function myHandler(id,newValue){
-				console.debug("onChange for id = " + id + ", value: " + newValue);
-			}
-			function foobar(){
-				jodo.byId("typeOut").innerHTML = "typeof dojo: " + (typeof dojo) +  "<br>typeof dijit: " + (typeof dijit) + "<br>typeof dojox: " + (typeof dojox);
-			}
-			setTimeout(foobar, 2000);
-		</script>
-	</head>
-	<body>
-		<h1>Using scope names inside dojo.require/dojoType</h1>
-	
-		<p><b>NOTE: This test only works with a built version of Dojo.</b></p>
-
-		<p>Jodo version: <span id="output10"></span></p>
-
-		<p><b>typeof dojo, dijit and dojox should be undefined</b>: <br><span id="typeOut"></span></p>
-
-		<p class="tundra">
-			<input id="calendar1" jodoType="dijit.Calendar" onChange="myHandler(this.id,arguments[0])">
-		</p>
-		
-	</body>
-</html>
-
diff --git a/dojo/tests/_base/_loader/scope/scopeSingleDaac.html b/dojo/tests/_base/_loader/scope/scopeSingleDaac.html
deleted file mode 100644
index 9852a01..0000000
--- a/dojo/tests/_base/_loader/scope/scopeSingleDaac.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>
-		<title>Using scope names inside dojo.require/dojoType</title>
-
-		<link rel="stylesheet" type="text/css" href="../../../../resources/dojo.css"/>
-		<link rel="stylesheet" type="text/css" href="../../../../../dijit/tests/css/dijitTests.css"/>
-		<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/tundra/tundra.css"/>
-		
-		<script type="text/javascript">
-			//djConfig for 0.4.3 setup.
-			djConfig = {
-				isDebug: true,
-				debugAtAllCosts: true,
-				parseOnLoad: true,
-				baseUrl: "../../../../",
-				scopeMap: [
-					["dojo", "jodo"],
-					["dijit", "jidit"],
-					["dojox", "jodox"]					
-				]
-			};
-		</script>
-
-		<script type="text/javascript" src="../../../../dojo.js"></script>
-		<script type="text/javascript">
-
-			//Notice that dijit.Calendar is required, not jidit._Calendar.
-			//Same for the dojo resources (not jodo resources).
-			jodo.require("dijit.Calendar");
-			jodo.require("dojo.date.locale");
-			jodo.require("dojo.parser"); // scan page for widgets
-
-			jodo.addOnLoad(function(){
-				jodo.byId("output10").innerHTML = jodo.version.toString();
-			});
-
-			function myHandler(id,newValue){
-				console.debug("onChange for id = " + id + ", value: " + newValue);
-			}
-			function foobar(){
-				jodo.byId("typeOut").innerHTML = "typeof dojo: " + (typeof dojo) +  "<br>typeof dijit: " + (typeof dijit) + "<br>typeof dojox: " + (typeof dojox);
-			}
-			setTimeout(foobar, 2000);
-		</script>
-	</head>
-	<body>
-		<h1>Using scope names inside dojo.require/dojoType</h1>
-	
-		<p><b>NOTE: This test only works with a built version of Dojo.</b></p>
-
-		<p>Jodo version: <span id="output10"></span></p>
-
-		<p><b>typeof dojo, dijit and dojox should be object, since debugAtAllCosts is ON</b>: <br><span id="typeOut"></span></p>
-
-		<p class="tundra">
-			<input id="calendar1" jodoType="jidit._Calendar" onChange="myHandler(this.id,arguments[0])">
-		</p>
-		
-	</body>
-</html>
-
diff --git a/dojo/tests/_base/array.js b/dojo/tests/_base/array.js
index 18e4803..ea1cdda 100644
--- a/dojo/tests/_base/array.js
+++ b/dojo/tests/_base/array.js
@@ -1,11 +1,11 @@
-dojo.provide("tests._base.array");
+dojo.provide("dojo.tests._base.array");
 
 tests.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]));
@@ -21,10 +21,10 @@ tests.register("tests._base.array",
 		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, -1));
+			t.assertEqual(1, dojo.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));
 		},
@@ -32,7 +32,7 @@ tests.register("tests._base.array",
 		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]));
@@ -45,7 +45,7 @@ tests.register("tests._base.array",
 		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, -1));
+			t.assertEqual(-1, dojo.lastIndexOf([45, 56, 85], 85, -2));
 			t.assertEqual(0, dojo.lastIndexOf([45, 56, 45], 45, 0));
 		},
 
@@ -112,7 +112,6 @@ tests.register("tests._base.array",
 				caughtException = true;
 			}
 			t.assertTrue(caughtException);
-			return;
 		},
 
 		// FIXME: test forEach w/ a NodeList()?
@@ -190,8 +189,8 @@ tests.register("tests._base.array",
 
 			t.assertTrue(
 				dojo.some(foo, function(elt, idx, array){
-					if(idx < 1){ return true; }
-					return false;
+					return idx < 1;
+
 				})
 			);
 
diff --git a/dojo/tests/_base/connect.js b/dojo/tests/_base/connect.js
index ed5eeef..af5c392 100644
--- a/dojo/tests/_base/connect.js
+++ b/dojo/tests/_base/connect.js
@@ -1,15 +1,15 @@
-dojo.provide("tests._base.connect");
+dojo.provide("dojo.tests._base.connect");
 
 hub = function(){
-}
+};
 
 failures = 0;
 bad = function(){
 	failures++;
-}
+};
 
 good = function(){
-}
+};
 
 // make 'iterations' connections to hub
 // roughly half of which will be to 'good' and
@@ -45,7 +45,7 @@ markAndSweepTest = function(iterations){
 	hub();
 	// return number of disconnected functions that fired (should be 0)
 	return failures;
-}
+};
 
 markAndSweepSubscribersTest = function(iterations){
 	var topic = "hubbins";
@@ -76,7 +76,7 @@ markAndSweepSubscribersTest = function(iterations){
 	dojo.publish(topic);
 	// return number of unsubscribed functions that fired (should be 0)
 	return failures;
-}
+};
 
 tests.register("tests._base.connect",
 	[
@@ -196,6 +196,16 @@ tests.register("tests._base.connect",
 			t.is(true, foo.ok);
 			t.is(false, bar.ok);
 		},
+		function pubsub(t){
+			var count = 0;
+			dojo.subscribe("/test/blah", function(first, second){
+				t.is("first", first);
+				t.is("second", second);
+				count++;
+			});
+			dojo.publish("/test/blah", ["first", "second"]);
+			t.is(1, count);
+		},
 		function connectPublisher(t){
 			var foo = { inc: 0, foo: function(){ this.inc++; } };
 			var bar = { inc: 0, bar: function(){ this.inc++; } };
@@ -216,6 +226,21 @@ tests.register("tests._base.connect",
 		},
 		function publishSubscribe1000(t){
 			t.is(markAndSweepSubscribersTest(1000), 0);
+		},
+		function performanceAdd(){
+			function listener(){}
+			for(var i = 0;i < 1000; i++){
+				var foo = {};
+				dojo.connect(foo, "bar", listener);
+			}
+		},
+		function performanceFire(){
+			var foo = {};
+			function listener(){}
+			dojo.connect(foo, "bar", listener);
+			for(var i = 0;i < 100000; i++){
+				foo.bar();
+			}
 		}
 	]
 );
diff --git a/dojo/tests/_base/connectLeaks.html b/dojo/tests/_base/connectLeaks.html
new file mode 100644
index 0000000..e1ef1b5
--- /dev/null
+++ b/dojo/tests/_base/connectLeaks.html
@@ -0,0 +1,93 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<script type="text/javascript" src="../../dojo.js"></script>
+
+<script type="text/javascript">
+
+	var w, start;
+	dojo.addOnLoad(function(){
+		 w = dojo.byId('ipt');
+	});
+
+	function repeat(/*String*/ testName, /*Function*/ func, /*Number*/ iters, /*Date?*/ start){
+		// summary:
+		//		Call func() for iters times
+
+		start = start || new Date();
+
+		while(iters-- > 0){
+			func();
+			if(iters % 1000 == 0){
+				// avoid locking up browser or getting "script hung" warning dialog
+				dojo.byId("log").innerHTML = "Running " + testName + " (" + iters + ")";
+				setTimeout(function(){ repeat(testName, func, iters, start)}, 0);
+				return;
+			}
+		}
+		if(typeof CollectGarbage != "undefined"){
+			CollectGarbage(); // collect garbage in IE to make it easy to read the memory levels
+		}
+		dojo.byId("log").innerHTML = "Finished " + testName + ", elapsed time = " + ((new Date()) - start)/1000 + "s";
+	}
+
+	var cc = [];
+	function disconnectTest(){
+		//console.log("repeating");		
+		dojo.forEach(cc, function(c, i, conns){
+			dojo.disconnect(c);
+		});
+		cc = [
+			dojo.connect(w, "onblur", func),
+			dojo.connect(w, "onclick", func),
+			dojo.connect(w, "onchange",func)
+		];
+	}
+
+	function func(){
+		console.log('callback triggered')
+	}
+	function destroyTest(){
+		var button = dojo.place("<button>test button</button>", dojo.body());
+		dojo.connect(button, "onclick", func);
+		dojo.destroy(button);
+	}
+	function removeTest(){
+		var button = dojo.place("<button>test button</button>", dojo.body());
+		dojo.connect(button, "onclick", func);
+		button.parentNode.removeChild(button);
+	}
+	function iframeTest(){
+		var iframe = dojo.place("<iframe style='display:none' src='connectLeaks.html?inframe'></iframe>", dojo.body());
+		setTimeout(function(){
+			dojo.destroy(iframe);
+		}, 1000);
+	}
+	if(location.search == "?inframe"){
+	
+		dojo.ready(function(){
+			var a  = [];
+			for(var i = 0; i < 100000;i++){
+				a.push({a:4});
+			}
+			dojo.connect(document.body, "unload", function(){
+				a.push(4);
+				parent.console.log("a " + a.length);
+			});
+		});
+	}
+</script>
+</head>
+
+<body class="tundra">
+	<h1>Memory leak tests</h1>
+	<p>Monitor memory usage in IE6/7 (or any browser) before/after pressing buttons below</p>
+	<button onclick="repeat('disconnect test', disconnectTest, 10000);">dojo.disconnect() test</button>
+	<button onclick="repeat('destroy test', destroyTest, 10000);">dojo.destroy() test</button>
+	<button onclick="repeat('remove test', removeTest, 10000);">remove node test</button>
+	<button onclick="repeat('iframe test', iframeTest, 10);">iframe test</button>
+	<button onclick="CollectGarbage()">Collect Garbage</button>
+	<div id="log"></div>
+	<input id='ipt' value='connect target' type=button />
+</body>
+</html>
\ No newline at end of file
diff --git a/dojo/tests/_base/declare.js b/dojo/tests/_base/declare.js
index 2963fc0..ce2fd0b 100644
--- a/dojo/tests/_base/declare.js
+++ b/dojo/tests/_base/declare.js
@@ -1,12 +1,13 @@
-dojo.provide("tests._base.declare");
+// FIXME: this test assumes the existence of the global object "tests"
+tests= typeof tests=="undefined" ? {} : tests;
 
-tests.register("tests._base.declare",
-	[
+define(["../..", "doh"], function(dojo, doh){
+	doh.register("tests._base.declare", [
 		function smokeTest(t){
 			dojo.declare("tests._base.declare.tmp", null);
 			var tmp = new tests._base.declare.tmp();
 			dojo.declare("testsFoo", null);
-			var tmp = new testsFoo();
+			tmp = new testsFoo();
 		},
 		function smokeTest2(t){
 			dojo.declare("tests._base.declare.foo", null, {
@@ -194,11 +195,11 @@ tests.register("tests._base.declare",
 
 			var Thing = function(args){
 				dojo.mixin(this, args);
-			}
+			};
 			Thing.prototype.method = function(){
 				t.t(true);
 				d.callback(true);
-			}
+			};
 
 			dojo.declare("Thinger", Thing, {
 				method: function(){
@@ -247,7 +248,7 @@ tests.register("tests._base.declare",
 				a = 1;
 				++this.flag;
 				old.call(this);
-			}
+			};
 			x.bar();
 			t.is(3, x.flag);
 			t.is(1, a);
@@ -258,7 +259,7 @@ tests.register("tests._base.declare",
 				a = 1;
 				++this.flag;
 				this.inherited("baz", arguments);
-			}
+			};
 			x.baz();
 			t.is(2, x.flag);
 			t.is(1, a);
@@ -400,13 +401,13 @@ tests.register("tests._base.declare",
 			}
 			t.t(flag);
 		},
-		
+
 		function noNew(t){
 			// all of the classes I create will use this as their
 			// pseudo-constructor function
 			function noNewConstructor(){
 				this.noNew_Value = 'instance value';
-			};
+			}
 
 			var g = dojo.global;
 			// this value will remain unchanged if the code for
@@ -419,7 +420,7 @@ tests.register("tests._base.declare",
 				var obj = cls('instance value');
 				t.is(obj.noNew_Value, 'instance value');
 				t.is(g.noNew_Value, 'global value');
-			};
+			}
 
 			// There are three different functions that might be
 			// created by dojo.declare(), so I need to test all
@@ -466,5 +467,5 @@ tests.register("tests._base.declare",
 		// FIXME: there are still some permutations to test like:
 		//	- ctor arguments
 		//	- multi-level inheritance + L/R conflict checks
-	]
-);
+	]);
+});
diff --git a/dojo/tests/_base/eventKeyPress.html b/dojo/tests/_base/eventKeyPress.html
index 1da1e5e..18939f2 100644
--- a/dojo/tests/_base/eventKeyPress.html
+++ b/dojo/tests/_base/eventKeyPress.html
@@ -3,7 +3,7 @@
 <html>
 <head>
 	<style type="text/css">
-		@import "../../dojo/resources/dojo.css";
+		@import "../../resources/dojo.css";
 	</style>
 	
 	<script type="text/javascript" djConfig="isDebug: true" src="../../dojo.js"></script>
@@ -16,21 +16,21 @@
 			kp1 = dojo.connect(dojo.byId("typer"), "onkeypress", function(evt){
 
 				// Keep log of events on <input>, skipping pressing of the control/shift/meta, since that's
-				// browsser dependent
+				// browser dependent
 				if(evt.keyCode == dojo.keys.CTRL || evt.keyCode == dojo.keys.SHIFT || evt.keyCode == dojo.keys.META){
 					return;
 				}
 				events.push(evt);
 
-				console.log("1 onkeypress triggered: charOrCode: " + evt.charOrCode + ", keyChar: " + evt.keyChar + ", keyCode: " + evt.keyCode + ", charCode: " + evt.charCode +
-				(evt.ctrlKey ? " ctrl" : "") + (evt.shiftKey ? " shift" : ""), evt);
+				console.log("1 onkeypress triggered: charOrCode: " + evt.charOrCode + ", keyChar: " + evt.keyChar + ", keyCode:" + evt.keyCode + ", charCode: " + evt.charCode +
+				(evt.ctrlKey ? " ctrl" : "") + (evt.shiftKey ? " shift" : ""));
 
 				// Use this because many keystrokes, like CTRL-B or F5, make the browser do things like refreshing the page
 				dojo.stopEvent(evt);
 			});
 
 			kp2 = dojo.connect(dojo.byId("typer"), "onkeypress", function(evt){
-				console.log("2 onkeypress triggered: keyCode: " + evt.keyCode + ", charCode: " + evt.charCode);
+				console.log("2 onkeypress triggered: keyCode: " + evt.keyCode + ", charCode: " + evt.charCode + " return: " + evt.returnValue);
 			});
 
 			kd1 = dojo.connect(dojo.byId("typer"), "onkeydown", function(evt){
diff --git a/dojo/tests/_base/eventKeyPressRobot.html b/dojo/tests/_base/eventKeyPressRobot.html
index 28541b1..48e74a4 100644
--- a/dojo/tests/_base/eventKeyPressRobot.html
+++ b/dojo/tests/_base/eventKeyPressRobot.html
@@ -16,44 +16,44 @@
 			dojo.require("dojo.robotx");
 
 			var navigation = [
-					"BACKSPACE",
-					"TAB",
-					"ENTER",
-					"ESCAPE",
-					"PAGE_UP",
-					"PAGE_DOWN",
-					"END",
-					"HOME",
-					"LEFT_ARROW",
-					"UP_ARROW",
-					"RIGHT_ARROW",
-					"DOWN_ARROW"
-					
-					/*
-						F1 to F10 are just too problematic to test; they have special meanings
-						on the browsers.
-						
-					// "F1",	// brings up help
-					"F2",
-					// "F3",	// brings up search
-					// "F4",	// address bar access on IE,
-					// "F5",	// refreshes the page
-					// "F6",	// address bar access on IE
-					// "F7",	// affects "caret browsing" on FF
-					"F8",
-					"F9",
-					// "F10",	// access File menu on IE
-					// "F11",	// full screen mode
-					// "F12"	// opens firebug console
-					*/
-				];
-
-				// Test a few normal keystrokes, but be careful about testing things
-				// that are entered using the SHIFT key as that produces two onkeypress
-				// events on IE (one for the SHIFT key and one for the character)
-				var printables = [" ", "n", "7"];
-
-				dojo.addOnLoad(function(){
+				"BACKSPACE",
+				"TAB",
+				"ENTER",
+				"ESCAPE",
+				"PAGE_UP",
+				"PAGE_DOWN",
+				"END",
+				"HOME",
+				"LEFT_ARROW",
+				"UP_ARROW",
+				"RIGHT_ARROW",
+				"DOWN_ARROW"
+
+				/*
+					F1 to F10 are just too problematic to test; they have special meanings
+					on the browsers.
+
+				// "F1",	// brings up help
+				"F2",
+				// "F3",	// brings up search
+				// "F4",	// address bar access on IE,
+				// "F5",	// refreshes the page
+				// "F6",	// address bar access on IE
+				// "F7",	// affects "caret browsing" on FF
+				"F8",
+				"F9",
+				// "F10",	// access File menu on IE
+				// "F11",	// full screen mode
+				// "F12"	// opens firebug console
+				*/
+			];
+
+			// Test a few normal keystrokes, but be careful about testing things
+			// that are entered using the SHIFT key as that produces two onkeypress
+			// events on IE (one for the SHIFT key and one for the character)
+			var printables = [" ", "n", "7"];
+
+			dojo.addOnLoad(function(){
 				doh.robot.initRobot('eventKeyPress.html');
 
 				var typer, 	// <input> that will receive keyboard events
@@ -126,7 +126,9 @@
 					222:39 
 				*/
 
-				doh.register("ctrl-alphabetic", dojo.map("abcdefghijklmnopqrstuvwxyz", function(c){
+				// Ctrl-alphabetic tests.
+				// Skip ctrl-o and ctrl-p which cause open and print dialogs on IE, even with the dojo.stopEvent()
+				doh.register("ctrl-alphabetic", dojo.map("abcdefghijklmnqrstuvwxyz", function(c){
 					return {
 						name: "ctrl-" + c,
 						timeout: 1000,
diff --git a/dojo/tests/_base/eventMouse.html b/dojo/tests/_base/eventMouse.html
new file mode 100644
index 0000000..91c448e
--- /dev/null
+++ b/dojo/tests/_base/eventMouse.html
@@ -0,0 +1,114 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+
+<html>
+<head>
+	<title>mouse events test</title>
+	<style type="text/css">
+		@import "../../resources/dojo.css";
+
+		div {
+			margin: 10px;
+			padding: 10px;
+			border: medium inset gray;
+		}
+
+		/* highlight on hover so it's clear where robot has moved the mouse */
+		div, h1 {
+			background-color: white;
+     	}
+		div:hover, h1:hover {
+			background-color: cyan;
+		}
+
+		/* apply width to top level nodes, not using body > * since it doesn't work on IE6 */
+		.top {
+			width: 500px;
+		}
+	</style>
+	
+	<script type="text/javascript" djConfig="isDebug: true" src="../../dojo.js"></script>
+	
+	<script type="text/javascript">
+		dojo.addOnLoad(function() {
+			// Log of events, used by automated test harness
+			moveEvents = [];
+			clickEvents = [];
+			downEvents = [];
+
+			dojo.connect(dojo.byId("outer"), "onmouseenter", function(evt){
+				moveEvents.push({target: evt.target.id, event: "mouseenter"});
+				console.log(dojo.toJson(moveEvents[moveEvents.length-1]));
+			});
+			dojo.connect(dojo.byId("outer"), "onmouseleave", function(evt){
+				moveEvents.push({target: evt.target.id, event: "mouseleave"});
+				console.log(dojo.toJson(moveEvents[moveEvents.length-1]));
+			});
+
+			handles = dojo.map(["outer", "middle", "inner1", "inner2"], function(id){
+				var node = dojo.byId(id);
+				return [
+					dojo.connect(node, "onclick", function(evt){
+						clickEvents.push({
+							target: evt.target.id,
+							currentTarget: evt.currentTarget.id,
+							event: "click"
+						});
+						console.log(dojo.toJson(clickEvents[clickEvents.length-1]));
+						if(evt.currentTarget.id == "middle" || evt.currentTarget.id == "outer"){
+							dojo.stopEvent(evt);
+						}
+					}),						/*
+
+					dojo.connect(node, "onclick", function(evt){
+						// repeated click event just to make sure that 2 events work
+						clickEvents.push({
+							target: evt.target.id,
+							currentTarget: evt.currentTarget.id,
+							event: "click"
+						});
+						console.log("repeated click event: " + dojo.toJson(clickEvents[clickEvents.length-1]));
+						if(evt.currentTarget.id == "middle" || evt.currentTarget.id == "outer"){
+							dojo.stopEvent(evt);
+						}
+					}),
+					*/
+					dojo.connect(node, "onmousedown", function(evt){
+						if(evt.type == "unload"){
+							console.error("onmousedown handler got onunload event");
+							debugger;
+							return;
+						}
+						downEvents.push({
+							target: evt.target.id,
+							currentTarget: evt.currentTarget.id,
+							event: "mousedown",
+							isLeft: dojo.mouseButtons.isLeft(evt),
+							isMiddle: dojo.mouseButtons.isMiddle(evt),
+							isRight: dojo.mouseButtons.isRight(evt)
+						});
+						console.log(dojo.toJson(downEvents[downEvents.length-1]));
+						if(evt.currentTarget.id == "middle" || evt.currentTarget.id == "outer"){
+							dojo.stopEvent(evt);
+						}
+					})
+				];
+			});
+		});
+	</script>
+</head>
+<body>
+	<h1 id="header" class="top">mouse events test</h1>
+
+	<div id="outer" class="top">
+		<span id="outerLabel">outer</span>
+		<div id="middle">
+			<span id="middleLabel">middle</span>
+			<div id="inner1">inner 1</div>
+			<div id="labelBetweenInners">between inner 1 and inner 2</div>
+			<div id="inner2">inner 2</div>
+		</div>
+	</div>
+
+	<div id="afterOuter" class="top">after outer</div>
+</body>
+</html>
diff --git a/dojo/tests/_base/eventMouseRobot.html b/dojo/tests/_base/eventMouseRobot.html
new file mode 100644
index 0000000..342694d
--- /dev/null
+++ b/dojo/tests/_base/eventMouseRobot.html
@@ -0,0 +1,160 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot mouse events tests</title>
+
+		<style>
+			@import "../../../util/doh/robot/robot.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../dojo/dojo.js"
+			djConfig="isDebug: true"></script>
+			
+		<script type="text/javascript">
+			dojo.require("dojo.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('eventMouse.html');
+
+				var moveEvents, clickEvents;
+				var outer = dojo.byId("outer"),
+					middle = dojo.byId("middle");
+
+				doh.register("mouseenter/mouseleave", [
+					{
+						name: "setup",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt("header", 500, 500);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+							}), 250);
+
+							return d;
+						}
+					},
+					{
+						name: "enter middle",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							moveEvents = dojo.global.moveEvents = [];
+
+							doh.robot.mouseMoveAt("middleLabel", 500, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(1, moveEvents.length, "one event");
+								doh.is("mouseenter", moveEvents[0].event);
+								doh.is("outer", moveEvents[0].target);
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "enter inner1",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							moveEvents = dojo.global.moveEvents = [];
+
+							doh.robot.mouseMoveAt("inner1", 500, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(0, moveEvents.length, "no events");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "after outer",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							moveEvents = dojo.global.moveEvents = [];
+
+							doh.robot.mouseMoveAt("afterOuter", 500, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(1, moveEvents.length, "one event");
+								doh.is("mouseleave", moveEvents[0].event);
+								doh.is("outer", moveEvents[0].target);
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("mousedown, stopEvent", [
+					{
+						name: "mousedown inner1 div",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							downEvents = dojo.global.downEvents = [];
+
+							doh.robot.mouseMoveAt("inner1", 500, 500);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(2, downEvents.length, "two mousedown events");
+								doh.is("mousedown", downEvents[0].event, "downEvents[0].event");
+								doh.is("inner1", downEvents[0].target, "downEvents[0].target");
+								doh.t(downEvents[0].isLeft, "downEvents[0].isLeft");
+								doh.f(downEvents[0].isRight, "downEvents[0].isRight");
+
+								doh.is("mousedown", downEvents[1].event, "downEvents[1].event");
+								doh.is("middle", downEvents[1].currentTarget, "downEvents[1].currentTarget");
+								doh.is("inner1", downEvents[1].target, "downEvents[1].target");
+								doh.t(downEvents[1].isLeft, "downEvents[1].isLeft");
+								doh.f(downEvents[1].isRight, "downEvents[1].isRight");
+
+								// mousedown event shouldn't reach outer because of middle's stopEvent()
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "mousedown outer div",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							downEvents = dojo.global.downEvents = [];
+
+							doh.robot.mouseMoveAt("outerLabel", 500, 500);
+							doh.robot.mouseClick({middle: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(1, downEvents.length, "one event");
+								doh.is("mousedown", downEvents[0].event);
+								doh.is("outerLabel", downEvents[0].target);
+								doh.is("outer", downEvents[0].currentTarget);
+								doh.f(downEvents[0].isLeft, "downEvents[0].isLeft");
+								doh.t(downEvents[0].isMiddle, "downEvents[0].isMiddle");
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
+				// TODO: evt.relatedTarget
+				// TODO: evt.pageX, evt.pageY
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dojo/tests/_base/fx.html b/dojo/tests/_base/fx.html
index 5cadb61..7361855 100644
--- a/dojo/tests/_base/fx.html
+++ b/dojo/tests/_base/fx.html
@@ -4,463 +4,455 @@
 		<style type="text/css">
 			@import "../../resources/dojo.css";
 		</style>
-		<script type="text/javascript" 
-			src="../../dojo.js" 
-			djConfig="isDebug: true"></script>
-		<script type="text/javascript" src="../../_base/fx.js"></script>
+		<script type="text/javascript" src="../../dojo.js"></script>
 		<script type="text/javascript">
-			var duration = 500;
-			var timeout = 750;
-			dojo.require("doh.runner");
-			dojo.addOnLoad(function(){
-				doh.register("t", 
-					[
-						{
-							name: "fadeOut",
-							timeout: timeout,
-							runTest: function(){
-								var opacity = dojo.style('foo', 'opacity');
-								doh.is(1, opacity);
-								var anim = dojo.fadeOut({ node: 'foo', duration: duration });
-								var d = new doh.Deferred();
-								dojo.connect(anim, "onEnd", d.getTestCallback(function(){
-									var opacity = dojo.style('foo', 'opacity');
-									var elapsed = (new Date()) - anim._start;
-									doh.is(0, opacity);
-									doh.t(elapsed >= duration);
-								}));
-								anim._start = new Date();
-								anim.play();
-								return d;
-							}
-						},
-						{
-							name: "fadeIn",
-							timeout: timeout,
-							runTest: function(){
+			require(["dojo", "doh", "dojo/domReady!"], function(dojo, doh){
+				var duration = 500;
+				var timeout = 750;
+				doh.register("t", [
+					{
+						name: "fadeOut",
+						timeout: timeout,
+						runTest: function(){
+							var opacity = dojo.style('foo', 'opacity');
+							doh.is(1, opacity);
+							var anim = dojo.fadeOut({ node: 'foo', duration: duration });
+							var d = new doh.Deferred();
+							dojo.connect(anim, "onEnd", d.getTestCallback(function(){
 								var opacity = dojo.style('foo', 'opacity');
+								var elapsed = (new Date()) - anim._start;
 								doh.is(0, opacity);
-								var anim = dojo.fadeIn({ node: 'foo', duration: duration });
-								var d = new doh.Deferred();
-								dojo.connect(anim, "onEnd", d.getTestCallback(function(){
-									var opacity = dojo.style('foo', 'opacity');
-									var elapsed = (new Date()) - anim._start;
-									doh.is(1, opacity);
-									doh.t(elapsed >= duration);
-								}));
-								anim._start = new Date();
-								anim.play();
-								return d;
-							}
-						},
-						{
-							name: "animateColor",
-							timeout: timeout,
-							runTest: function(){
-								var d = new doh.Deferred();
-								var anim = dojo.animateProperty({ 
-									node: "foo", 
-									duration: duration,
-									properties: { 
-										color: 				{ start: "black", end: "white" },
-										backgroundColor: 	{ start: "white", end: "black" } 
-									} 
-								});
-								dojo.connect(anim, "onEnd", anim, function(){
-									d.callback(true);
-								});
-								anim.play();
-								return d;
-							}
-						},
-						{
-							name: "animateColorBack",
-							timeout: timeout,
-							runTest: function(){
-								var d = new doh.Deferred();
-								var anim = dojo.animateProperty({ 
-									node: "foo", 
-									duration: duration,
-									properties: { 
-										color: 				{ end: "black" },
-										backgroundColor: 	{ end: "#5d81b4" }, 
-										letterSpacing: 		{ start: 0, end: 10 } 
-									} 
-								});
-								dojo.connect(anim, "onEnd", anim, function(){
-									d.callback(true);
-								});
-								anim.play();
-								return d;
-							}
-						},
-						{
-							name: "animateHeight",
-							timeout: timeout,
-							runTest: function(t){
-								dojo.byId("foo").style.height = "";
-								var startHeight = dojo.marginBox("foo").h; 
-								var endHeight = Math.round(startHeight / 2);
-								
-								var anim = dojo.animateProperty({
-									node: "foo",
-									properties: { height: { end: endHeight } },
-									duration: duration
-								});
+								doh.t(elapsed >= duration);
+							}));
+							anim._start = new Date();
+							anim.play();
+							return d;
+						}
+					},
+					{
+						name: "fadeIn",
+						timeout: timeout,
+						runTest: function(){
+							var opacity = dojo.style('foo', 'opacity');
+							doh.is(0, opacity);
+							var anim = dojo.fadeIn({ node: 'foo', duration: duration });
+							var d = new doh.Deferred();
+							dojo.connect(anim, "onEnd", d.getTestCallback(function(){
+								var opacity = dojo.style('foo', 'opacity');
+								var elapsed = (new Date()) - anim._start;
+								doh.is(1, opacity);
+								doh.t(elapsed >= duration);
+							}));
+							anim._start = new Date();
+							anim.play();
+							return d;
+						}
+					},
+					{
+						name: "animateColor",
+						timeout: timeout,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var anim = dojo.animateProperty({ 
+								node: "foo", 
+								duration: duration,
+								properties: { 
+									color: 				{ start: "black", end: "white" },
+									backgroundColor: 	{ start: "white", end: "black" } 
+								} 
+							});
+							dojo.connect(anim, "onEnd", anim, function(){
+								d.callback(true);
+							});
+							anim.play();
+							return d;
+						}
+					},
+					{
+						name: "animateColorBack",
+						timeout: timeout,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var anim = dojo.animateProperty({ 
+								node: "foo", 
+								duration: duration,
+								properties: { 
+									color: 				{ end: "black" },
+									backgroundColor: 	{ end: "#5d81b4" }, 
+									letterSpacing: 		{ start: 0, end: 10 } 
+								} 
+							});
+							dojo.connect(anim, "onEnd", anim, function(){
+								d.callback(true);
+							});
+							anim.play();
+							return d;
+						}
+					},
+					{
+						name: "animateHeight",
+						timeout: timeout,
+						runTest: function(t){
+							dojo.byId("foo").style.height = "";
+							var startHeight = dojo.marginBox("foo").h; 
+							var endHeight = Math.round(startHeight / 2);
+							
+							var anim = dojo.animateProperty({
+								node: "foo",
+								properties: { height: { end: endHeight } },
+								duration: duration
+							});
 
-								var d = new doh.Deferred();
+							var d = new doh.Deferred();
 
-								dojo.connect(anim, "onEnd", anim, d.getTestCallback(function(){
-									var elapsed = (new Date().valueOf()) - anim._startTime;
-									doh.t(elapsed >= duration);
-									var height = dojo.marginBox("foo").h; 
-									doh.is(height, endHeight);
-								}));
-								
-								anim.play();
-								return d;
-							}
-						},
-						{
-							name: "animateHeight_defaults_syntax",
-							timeout: timeout,
-							runTest: function(){
-								dojo.byId("foo").style.height = "";
-								var startHeight = dojo.marginBox("foo").h; 
-								var endHeight = Math.round(startHeight / 2);
-								
-								var anim = dojo.animateProperty({
-									node: "foo",
-									properties: { height: endHeight },
-									duration: duration
-								});
+							dojo.connect(anim, "onEnd", anim, d.getTestCallback(function(){
+								var elapsed = (new Date().valueOf()) - anim._startTime;
+								doh.t(elapsed >= duration);
+								var height = dojo.marginBox("foo").h; 
+								doh.is(height, endHeight);
+							}));
+							
+							anim.play();
+							return d;
+						}
+					},
+					{
+						name: "animateHeight_defaults_syntax",
+						timeout: timeout,
+						runTest: function(){
+							dojo.byId("foo").style.height = "";
+							var startHeight = dojo.marginBox("foo").h; 
+							var endHeight = Math.round(startHeight / 2);
+							
+							var anim = dojo.animateProperty({
+								node: "foo",
+								properties: { height: endHeight },
+								duration: duration
+							});
 
-								var d = new doh.Deferred();
+							var d = new doh.Deferred();
 
-								dojo.connect(anim, "onEnd", anim, d.getTestCallback(function(){
-									var elapsed = (new Date().valueOf()) - anim._startTime;
-									doh.t(elapsed >= duration);
-									var height = dojo.marginBox("foo").h; 
-									doh.is(height, endHeight);
-								}));
-								
-								anim.play();
-								return d;
-							}
-						},
-						{
-							name: "inlineWidth",
-							timeout: timeout,
-							runTest: function(){
-								dojo.style("foo", "display", "none");
-								dojo.style("bar", "display", "");
-								var startWidth = dojo.marginBox("bar").w; 
-								var endWidth = Math.round(startWidth / 2);
-								
-								var anim = dojo.animateProperty({
-									node: "bar",
-									properties: { width: endWidth },
-									duration: duration
-								});
+							dojo.connect(anim, "onEnd", anim, d.getTestCallback(function(){
+								var elapsed = (new Date().valueOf()) - anim._startTime;
+								doh.t(elapsed >= duration);
+								var height = dojo.marginBox("foo").h; 
+								doh.is(height, endHeight);
+							}));
+							
+							anim.play();
+							return d;
+						}
+					},
+					{
+						name: "inlineWidth",
+						timeout: timeout,
+						runTest: function(){
+							dojo.style("foo", "display", "none");
+							dojo.style("bar", "display", "");
+							var startWidth = dojo.marginBox("bar").w; 
+							var endWidth = Math.round(startWidth / 2);
+							
+							var anim = dojo.animateProperty({
+								node: "bar",
+								properties: { width: endWidth },
+								duration: duration
+							});
 
-								var d = new doh.Deferred();
+							var d = new doh.Deferred();
 
-								dojo.connect(anim, "onEnd", anim, d.getTestCallback(function(){
-									var elapsed = (new Date().valueOf()) - anim._startTime;
-									doh.t(elapsed >= duration);
-									doh.is(dojo.marginBox("bar").w, endWidth);
-								}));
-								
-								anim.play();
-								return d;
-							}
-						},
-						{
-							name: "anim",
-							timeout: timeout+500,
-							runTest: function(){
-								var id = "baz";
-								dojo.style("bar", "display", "none");
-								dojo.style(id, "display", "");
-								var kickoff = new Date().valueOf();
-								var startWidth = dojo.marginBox(id).w; 
-								var endWidth = Math.round(startWidth / 2);
+							dojo.connect(anim, "onEnd", anim, d.getTestCallback(function(){
+								var elapsed = (new Date().valueOf()) - anim._startTime;
+								doh.t(elapsed >= duration);
+								doh.is(dojo.marginBox("bar").w, endWidth);
+							}));
+							
+							anim.play();
+							return d;
+						}
+					},
+					{
+						name: "anim",
+						timeout: timeout+500,
+						runTest: function(){
+							var id = "baz";
+							dojo.style("bar", "display", "none");
+							dojo.style(id, "display", "");
+							var kickoff = new Date().valueOf();
+							var startWidth = dojo.marginBox(id).w; 
+							var endWidth = Math.round(startWidth / 2);
 
-								var d = new doh.Deferred();
-								var anim = dojo.anim(
-									id, 
-									{ 
-										width: endWidth,
-										opacity: 0
-									}, 
-									duration, 
-									null, 
-									d.getTestCallback(function(){
-										var curTime = (new Date().valueOf()),
-											elapsed = curTime - anim._startTime;
-										doh.t(elapsed >= duration, "test elapsed " + elapsed + " > duration " + duration);
-										
-										// -5 because on FF a setTimeout(foo, x) may fire a little before x
-										doh.t(curTime >= (kickoff+duration+500-5),
-											"curTime >= (kickoff+duration+500-5): " + curTime + " >= (" + kickoff + "+" + duration + "+500-5)");
+							var d = new doh.Deferred();
+							var anim = dojo.anim(
+								id, 
+								{ 
+									width: endWidth,
+									opacity: 0
+								}, 
+								duration, 
+								null, 
+								d.getTestCallback(function(){
+									var curTime = (new Date().valueOf()),
+										elapsed = curTime - anim._startTime;
+									doh.t(elapsed >= duration, "test elapsed " + elapsed + " > duration " + duration);
+									
+									// -5 because on FF a setTimeout(foo, x) may fire a little before x
+									doh.t(curTime >= (kickoff+duration+500-5),
+										"curTime >= (kickoff+duration+500-5): " + curTime + " >= (" + kickoff + "+" + duration + "+500-5)");
 
-										doh.is(dojo.marginBox(id).w, endWidth, 
-											"width matches endWidth ");
+									doh.is(dojo.marginBox(id).w, endWidth, 
+										"width matches endWidth ");
 
-										doh.is(0, dojo.style(id, "opacity"), "opacity");
-									}),
-									500
-								);
-								return d;
-							}
-						},
-						{
-							name: "anim_defaults",
-							timeout: 1000,
-							runTest: function(){
-								var id = "thud";
-								dojo.style("baz", "display", "none");
-								dojo.style(id, "display", "");
-								var startWidth = dojo.marginBox(id).w; 
-								var endWidth = Math.round(startWidth / 2);
+									doh.is(0, dojo.style(id, "opacity"), "opacity");
+								}),
+								500
+							);
+							return d;
+						}
+					},
+					{
+						name: "anim_defaults",
+						timeout: 1000,
+						runTest: function(){
+							var id = "thud";
+							dojo.style("baz", "display", "none");
+							dojo.style(id, "display", "");
+							var startWidth = dojo.marginBox(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 elapsed = (new Date().valueOf()) - anim._startTime;
-									doh.t(elapsed >= dojo.Animation.prototype.duration); // the default
-									doh.is(dojo.marginBox(id).w, endWidth);
-								}));
-								anim.play();
-								return d;
-							}
-						},
-						{
-							// basic testing of a function for a property
-							name:"anim-fn-property",
-							timeout:1000,
-							runTest: function(){
-								
-								var d = new doh.Deferred();
-								dojo.animateProperty({
-									node: "thud",
-									properties:{
-										// also testing node passed to property function
-										padding: function(node){
+							var d = new doh.Deferred();
+							var anim = dojo.anim(id, { width: endWidth });
+							dojo.connect(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);
+							}));
+							anim.play();
+							return d;
+						}
+					},
+					{
+						// basic testing of a function for a property
+						name:"anim-fn-property",
+						timeout:1000,
+						runTest: function(){
+							
+							var d = new doh.Deferred();
+							dojo.animateProperty({
+								node: "thud",
+								properties:{
+									// also testing node passed to property function
+									padding: function(node){
+										d.getTestErrback(function(){
+											doh.is("thud", node.id);
+										});
+										return { end:15, start:22 };
+									}
+								},
+								duration:350,
+								onEnd: d.getTestCallback(function(){})
+							}).play();
+							return d;	
+						}
+					},
+					{
+						// just testing a property function which returns two other functions
+						name:"anim-fn-property-return-fn",
+						timeout:1000,
+						runTest: function(){
+							
+							var d = new doh.Deferred();
+							dojo.animateProperty({
+								node: "thud",
+								properties:{
+									// also testing node passed to property function
+									height: function(node){
+										d.getTestErrback(function(){
+											doh.is("thud", node.id);
+										});
+										return {
+											start: function(){ return 50; },
+											end: function(){ return 100; }
+										};
+									}
+								},
+								duration:350,
+								onEnd: d.getTestCallback(function(){})
+							}).play();
+							return d;	
+						}
+					},
+					{
+						// ensuring the end property can be a function
+						name:"anim-fn-prop-end",
+						timeout:1000,
+						runTest: function(){
+							
+							var d = new doh.Deferred();
+							dojo.animateProperty({
+								node: "thud",
+								properties:{
+									width: { 
+										// also testing node passed to end function
+										end: function(node){
 											d.getTestErrback(function(){
 												doh.is("thud", node.id);
 											});
-											return { end:15, start:22 };
+											return 100;
 										}
-									},
-									duration:350,
-									onEnd: d.getTestCallback(function(){})
-								}).play();
-								return d;	
-							}
-						},
-						{
-							// just testing a property function which returns two other functions
-							name:"anim-fn-property-return-fn",
-							timeout:1000,
-							runTest: function(){
-								
-								var d = new doh.Deferred();
-								dojo.animateProperty({
-									node: "thud",
-									properties:{
-										// also testing node passed to property function
-										height: function(node){
+									}
+								},
+								duration:50,
+								onEnd: d.getTestCallback(function(){})
+							}).play();
+							
+							return d;	
+						}
+					},
+					{
+						// ensuring the start property can be a function
+						name:"anim-fn-prop-start",
+						timeout:1000,
+						runTest: function(){
+							
+							var d = new doh.Deferred();
+							dojo.animateProperty({
+								node: "thud",
+								properties:{
+									width: { 
+										// also testing node passed to start function
+										start: function(node){
 											d.getTestErrback(function(){
 												doh.is("thud", node.id);
 											});
-											return {
-												start: function(){ return 50; },
-												end: function(){ return 100; }
-											};
-										}
-									},
-									duration:350,
-									onEnd: d.getTestCallback(function(){})
-								}).play();
-								return d;	
-							}
-						},
-						{
-							// ensuring the end property can be a function
-							name:"anim-fn-prop-end",
-							timeout:1000,
-							runTest: function(){
-								
-								var d = new doh.Deferred();
-								dojo.animateProperty({
-									node: "thud",
-									properties:{
-										width: { 
-											// also testing node passed to end function
-											end: function(node){
-												d.getTestErrback(function(){
-													doh.is("thud", node.id);
-												});
-												return 100;
-											}
-										}
-									},
-									duration:50,
-									onEnd: d.getTestCallback(function(){})
-								}).play();
-								
-								return d;	
-							}
-						},
-						{
-							// ensuring the start property can be a function
-							name:"anim-fn-prop-start",
-							timeout:1000,
-							runTest: function(){
-								
-								var d = new doh.Deferred();
-								dojo.animateProperty({
-									node: "thud",
-									properties:{
-										width: { 
-											// also testing node passed to start function
-											start: function(node){
-												d.getTestErrback(function(){
-													doh.is("thud", node.id);
-												});
-												return 100;
-											},
-											end: 200
-										}
-									},
-									duration:50,
-									onEnd: d.getTestCallback(function(){})
-								}).play();
-								
-								return d;
-							}
-						},
-						{
-							// ensuring our node ref is passed onEnd:
-							name:"anim-onend-node",
-							timeout:1000,
-							runTest: function(){
-								
-								var d = new doh.Deferred();
-								dojo.animateProperty({
-									node: "thud",
-									properties:{
-										width: 200
-									},
-									duration:150,
-									onEnd:d.getTestCallback(function(node){
-										if(node){
-											doh.is("thud", node.id);
-										}
-									})
-								}).play();
-								
-								return d;	
-							}
-						},
-						{
-							// ensuring our node ref is passed to beforeBegin:
-							name:"anim-beforebegin-node",
-							timeout:1000,
-							runTest: function(){
-
-								var d = new doh.Deferred();
-								dojo.animateProperty({
-									node: "thud",
-									properties:{
-										width: 200
-									},
-									duration:50,
-									beforeBegin:d.getTestErrback(function(node){
-										doh.is("thud", node.id);
-									}),
-									onEnd:d.getTestCallback(function(node){})
-								}).play();
-
-								return d;	
-							}
-						},
-						{
-							name:"anim-onend-scope",
-							timeout:1000,
-							runTest: function(){
-								var d = new doh.Deferred();
-								dojo.declare("fx.Thinger", null, {
-									constructor: function(a){
-										this.bar = 10;
-									},
-									method: function(e){
-										d.callback(true);
+											return 100;
+										},
+										end: 200
 									}
-								});
-								
-								dojo.declare("fx.ThingerToo", fx.Thinger, {
-									method: function(){
-										var a = arguments;
-										dojo.fadeIn({
-											node:"thud",
-											onEnd: dojo.hitch(this, function(){
-												// to call inherited in a callback, stash the orig 'arguments'
-												this.inherited(a);
-											}),
-											duration:100
-										}).play()
+								},
+								duration:50,
+								onEnd: d.getTestCallback(function(){})
+							}).play();
+							
+							return d;
+						}
+					},
+					{
+						// ensuring our node ref is passed onEnd:
+						name:"anim-onend-node",
+						timeout:1000,
+						runTest: function(){
+							
+							var d = new doh.Deferred();
+							dojo.animateProperty({
+								node: "thud",
+								properties:{
+									width: 200
+								},
+								duration:150,
+								onEnd:d.getTestCallback(function(node){
+									if(node){
+										doh.is("thud", node.id);
 									}
-								});
-								
-								var x = new fx.ThingerToo();
-								x.method();
-								
-								return d;
-							}
-						},
-						{
-							name:"anim-onend-scope-natural",
-							timeout:1000,
-							runTest: function(){
-								var d = new doh.Deferred();
+								})
+							}).play();
+							
+							return d;	
+						}
+					},
+					{
+						// ensuring our node ref is passed to beforeBegin:
+						name:"anim-beforebegin-node",
+						timeout:1000,
+						runTest: function(){
 
-								// testing vanilla inheritance
-								fx.NThinger = function(args){
-									dojo.mixin(this, args);
-								}
-								fx.NThinger.prototype.method = function(){
+							var d = new doh.Deferred();
+							dojo.animateProperty({
+								node: "thud",
+								properties:{
+									width: 200
+								},
+								duration:50,
+								beforeBegin:d.getTestErrback(function(node){
+									doh.is("thud", node.id);
+								}),
+								onEnd:d.getTestCallback(function(node){})
+							}).play();
+
+							return d;	
+						}
+					},
+					{
+						name:"anim-onend-scope",
+						timeout:1000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							dojo.declare("fx.Thinger", null, {
+								constructor: function(a){
+									this.bar = 10;
+								},
+								method: function(e){
 									d.callback(true);
 								}
-								
-								
-								dojo.declare("fx.ThingerThree", fx.NThinger, {
-									method: function(){
-										var x = dojo.fadeOut({
-											node:"thud",
-											duration:100
-										});
-										
-										// to use with connect, pass a newArgs (arguements again) to override any 
-										// possible references passed from the orig function.
-										dojo.connect(x, "onEnd", dojo.hitch(this, "inherited", arguments, arguments));
-										
-										x.play();
-									}
-								});
-								
-								var x = new fx.ThingerThree();
-								x.method();
-								
-								return d;
-							}
+							});
+							
+							dojo.declare("fx.ThingerToo", fx.Thinger, {
+								method: function(){
+									var a = arguments;
+									dojo.fadeIn({
+										node:"thud",
+										onEnd: dojo.hitch(this, function(){
+											// to call inherited in a callback, stash the orig 'arguments'
+											this.inherited(a);
+										}),
+										duration:100
+									}).play()
+								}
+							});
+							
+							var x = new fx.ThingerToo();
+							x.method();
+							
+							return d;
 						}
-						
-					
-						
-					]
-				);
+					},
+					{
+						name:"anim-onend-scope-natural",
+						timeout:1000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// testing vanilla inheritance
+							fx.NThinger = function(args){
+								dojo.mixin(this, args);
+							};
+							fx.NThinger.prototype.method = function(){
+								d.callback(true);
+							};
+							
+							
+							dojo.declare("fx.ThingerThree", fx.NThinger, {
+								method: function(){
+									var x = dojo.fadeOut({
+										node:"thud",
+										duration:100
+									});
+									
+									// to use with connect, pass a newArgs (arguements again) to override any 
+									// possible references passed from the orig function.
+									dojo.connect(x, "onEnd", dojo.hitch(this, "inherited", arguments, arguments));
+									
+									x.play();
+								}
+							});
+							
+							var x = new fx.ThingerThree();
+							x.method();
+							
+							return d;
+						}
+					}
+				]);
+
 				doh.run();
 			});
 		</script>
@@ -498,8 +490,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>
-		<input type="button" onClick="dojo.fadeIn({ node: 'foo', duration: 1000 }).play()" value="fade in"></input>
+		<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"/>
 		</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 7b1174e..6fd377c 100644
--- a/dojo/tests/_base/fx.js
+++ b/dojo/tests/_base/fx.js
@@ -1,4 +1,5 @@
-dojo.provide("tests._base.fx");
-if(dojo.isBrowser){
-	doh.registerUrl("tests._base.fx", dojo.moduleUrl("tests", "_base/fx.html"), 15000);
-}
+define(["doh", "require"], function(doh, require){
+	if(doh.isBrowser){
+		doh.register("tests._base.fx", require.toUrl("./fx.html"), 15000);
+	}
+});
diff --git a/dojo/tests/_base/html.html b/dojo/tests/_base/html.html
index 4a38dff..b26906b 100644
--- a/dojo/tests/_base/html.html
+++ b/dojo/tests/_base/html.html
@@ -10,27 +10,23 @@
 		<style type="text/css">
 			@import "../../resources/dojo.css";
 		</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">
-			dojo.require("doh.runner");
-
-			function getIframeDocument(/*DOMNode*/iframeNode){
-				//summary: Returns the document object associated with the iframe DOM Node argument.
-				var doc = iframeNode.contentDocument || // W3
-					(
-						(iframeNode.contentWindow)&&(iframeNode.contentWindow.document)
-					) ||  // IE
-					(
-						(iframeNode.name)&&(document.frames[iframeNode.name])&&
-						(documendoh.frames[iframeNode.name].document)
-					) || null;
-				return doc;
-			}
-
+			require(["dojo", "doh", "dojo/domReady!"], function(dojo, doh){
+
+				function getIframeDocument(/*DOMNode*/iframeNode){
+					//summary: Returns the document object associated with the iframe DOM Node argument.
+					var doc = iframeNode.contentDocument || // W3
+						(
+							(iframeNode.contentWindow)&&(iframeNode.contentWindow.document)
+						) ||  // IE
+						(
+							(iframeNode.name)&&(document.frames[iframeNode.name])&&
+							(documendoh.frames[iframeNode.name].document)
+						) || null;
+					return doc;
+				}
 
-			dojo.addOnLoad(function(){
 				// IE gets confused by the iframe when you press Refresh so load them dynamically
 				var iframe_div = dojo.byId('iframe_div');
 				dojo.addOnWindowUnload(function(){
@@ -172,8 +168,8 @@
 								overflow = 'scroll';
 								border = "10px solid black";
 							}
-							dojo._setMarginBox(s, x, y, 100, 100);
-							dojo._setMarginBox(c, 0, 0, 500, 500);
+							dojo.marginBox(s, {l: x, t: y, w: 100, h: 100});
+							dojo.marginBox(c, {l: 0, t: 0, w: 500, h: 500});
 							s.scrollTop = 200;
 							var pos = dojo.position(s, true);
 							doh.is(x, pos.x);
@@ -190,7 +186,7 @@
 									dojo.withGlobal(dojo.byId('iframe_quirks').win, function(){
 										doh.t(dojo.isQuirks, "isQuirks == true in quirks/iframe");
 										doh.f(dojo._isBodyLtr(), "isBodyLtr == false in RTL/iframe");
-									        var pos = dojo.position('iframe_00_quirks');
+										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+")");
 										doh.t(pos.y===0, "quirks iframe element y == 0 (x,y,w,h="+pos.x+","+pos.y+","+pos.w+","+pos.h+")");
 										doh.t(pos.w>0, "quirks iframe element w > 0 (x,y,w,h="+pos.x+","+pos.y+","+pos.w+","+pos.h+")");
@@ -199,7 +195,7 @@
 									dojo.withGlobal(dojo.byId('iframe_strict').win, function(){
 										doh.f(dojo.isQuirks, "isQuirks == false in strict/ifraee");
 										doh.f(dojo._isBodyLtr(), "isBodyLtr == false in RTL/iframe");
-									        var pos = dojo.position('iframe_00_strict');
+										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+")");
 										doh.t(pos.y===0, "strict iframe element y == 0 (x,y,w,h="+pos.x+","+pos.y+","+pos.w+","+pos.h+")");
 										doh.t(pos.w>0, "strict iframe element w > 0 (x,y,w,h="+pos.x+","+pos.y+","+pos.w+","+pos.h+")");
@@ -213,14 +209,17 @@
 							}
 						},
 						"doh.is(1, dojo.style('sq100nopos', 'opacity'));",
-						"doh.is(0.1, dojo.style('sq100nopos', 'opacity', 0.1));",
-						"doh.is(0.8, dojo.style('sq100nopos', 'opacity', 0.8));",
+
+						// never compare floating numbers directly!
+						"doh.is((0.1).toFixed(4), Number(dojo.style('sq100nopos', 'opacity', 0.1)).toFixed(4));",
+						"doh.is((0.8).toFixed(4), Number(dojo.style('sq100nopos', 'opacity', 0.8)).toFixed(4));",
 						function styleObject(){
 							dojo.style('sq100nopos', { 'opacity': 0.1 });
-							doh.is(0.1, dojo.style('sq100nopos', 'opacity'));
+							doh.is((0.1).toFixed(4), Number(dojo.style('sq100nopos', 'opacity')).toFixed(4));
 							dojo.style('sq100nopos', { 'opacity': 0.8 });
-							doh.is(0.8, dojo.style('sq100nopos', 'opacity'));
+							doh.is((0.8).toFixed(4), Number(dojo.style('sq100nopos', 'opacity')).toFixed(4));
 						},
+
 						"doh.is('static', dojo.style('sq100nopos', 'position'));",
 						function getBgcolor(t){
 							var bgc = dojo.style('sq100nopos', 'backgroundColor');
@@ -296,6 +295,7 @@
 							t.is("b a c", node.className, 
 								"The className is  is 'b a c' after using an empty string in replaceClass");
 							
+							t.f(dojo.hasClass(document, "ab"), "hasClass on document should not throw error");
 						},
 						function testAddRemoveClassMultiple(t){
 							var node = dojo.byId("sq100");
@@ -455,15 +455,14 @@
 							doh.t(dojo.hasClass(input, "blah"), "hasClass of blah");
 							var def = new doh.Deferred();
 							input.focus();
-							setTimeout(function(){
+							setTimeout(def.getTestErrback(function(){
 								doh.is(1, ctr, "onfocus ctr == 1");
 								input.blur();
 								input.focus();
-								setTimeout(function(){
+								setTimeout(def.getTestCallback(function(){
 									doh.is(2, ctr, "onfocus ctr == 2");
-									def.callback(true);
-								}, 10);
-							}, 10);
+								}), 10);
+							}), 10);
 							return def;
 						},
 						function attr_reconnect(t){
@@ -482,15 +481,14 @@
 							doh.is(0, ctr);
 							var def = new doh.Deferred();
 							input.focus();
-							setTimeout(function(){
+							setTimeout(def.getTestErrback(function(){
 								doh.is(1, ctr);
 								input.blur();
 								input.focus();
-								setTimeout(function(){
+								setTimeout(def.getTestCallback(function(){
 									doh.is(2, ctr);
-									def.callback(true);
-								}, 10);
-							}, 10);
+								}), 10);
+							}), 10);
 							return def;
 						},
 						function attrSpecials(){
@@ -588,17 +586,20 @@
 						function testIframeDestroy10095(t){
 							var iframeWin = dojo.byId('10095_iframe').win;
 							doh.t(!iframeWin.document.getElementById('10095_textbox'), "reloaded iframe element destroyed");
+						},
+						function testGCSsvg(t){
+							var s = dojo.getComputedStyle(dojo.byId("rect1"));
+							doh.t(typeof s != "undefined", "dojo.getComputedStyle succeeded on an svg shape");
 						}
 					]
 				);
-				
 				// test to make sure position() works with a variety of scrollbars
 				dojo.forEach(["None", "Vert", "Both"], function(scroll){
 					dojo.forEach(["Quirks", "Strict"], function(doctype){
 						var id = "scrolling" + doctype + "Iframe" + scroll;
 						doh.register(id, {
 							name: "test_" + id,
-							timeout: 3000,
+							timeout: 4000,
 							runTest: function(t){
 								var d = new doh.Deferred(),
 									s = document.createElement('SPAN');
@@ -617,7 +618,7 @@
 					});
 				});
 
-				doh.run();
+				doh.runOnLoad();
 			});
 		</script>
 		<style type="text/css">
@@ -815,15 +816,17 @@
 		<script type="text/javascript">
 		var reloaded = false;
 		function iframe10095loaded() {
-			var iframeWin = dojo.byId('10095_iframe').win;
-			dojo.withGlobal(iframeWin, function(){ dojo.destroy(dojo.byId('10095_textbox')) });
-			if(!reloaded){
-				reloaded = true;
-				dojo.byId('10095_iframe').src=iframeWin.frameElement.src;
-			}
+			require(["dojo", "dojo/domReady!"], function(dojo) {
+				var iframeWin = dojo.byId('10095_iframe').win;
+				dojo.withGlobal(iframeWin, function(){ dojo.destroy(dojo.byId('10095_textbox')) });
+				if(!reloaded){
+					reloaded = true;
+					dojo.byId('10095_iframe').src=iframeWin.frameElement.src;
+				}
+			});
 		}
 		</script>
-		<iframe id="10095_iframe" style="display:none;" src="javascript:'<html><head><script>frameElement.win=window</script></head><body><input id=10095_textbox></body></html>'" onload="dojo.addOnLoad(iframe10095loaded)"></iframe>
+		<iframe id="10095_iframe" style="display:none;" src="javascript:'<html><head><script>frameElement.win=window</script></head><body><input id=10095_textbox></body></html>'" onload="iframe10095loaded()"></iframe>
 
 		<div id='iframe_div' style="position:absolute;top:0;left:500px;"></div>
 
@@ -850,5 +853,10 @@
 		</div>
 
 		<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>
 	</body>
 </html>
diff --git a/dojo/tests/_base/html.js b/dojo/tests/_base/html.js
index 11fe36b..bc95808 100644
--- a/dojo/tests/_base/html.js
+++ b/dojo/tests/_base/html.js
@@ -1,12 +1,13 @@
-dojo.provide("tests._base.html");
-if(dojo.isBrowser){
-	doh.registerUrl("tests._base.html", dojo.moduleUrl("tests", "_base/html.html"), 15000);
-	doh.registerUrl("tests._base.html_id", dojo.moduleUrl("tests", "_base/html_id.html"), 15000);
-	doh.registerUrl("tests._base.html_element", dojo.moduleUrl("tests", "_base/html_element.html"), 15000);
-	doh.registerUrl("tests._base.html_rtl", dojo.moduleUrl("tests", "_base/html_rtl.html"), 15000);
-	doh.registerUrl("tests._base.html_quirks", dojo.moduleUrl("tests", "_base/html_quirks.html"), 15000);
-	doh.registerUrl("tests._base.html_box", dojo.moduleUrl("tests", "_base/html_box.html"), 35000);
-	doh.registerUrl("tests._base.html_box_quirks", dojo.moduleUrl("tests", "_base/html_box_quirks.html"), 35000);
-	doh.registerUrl("tests._base.html_isBodyLtr", dojo.moduleUrl("tests", "_base/html_isBodyLtr.html"), 35000);
-	doh.registerUrl("tests._base.html_docScroll", dojo.moduleUrl("tests", "_base/html_docScroll.html"), 35000);
-}
+define(["doh", "require"], function(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);
+		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);
+		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_box.html b/dojo/tests/_base/html_box.html
index 6d34f9c..6048e2c 100644
--- a/dojo/tests/_base/html_box.html
+++ b/dojo/tests/_base/html_box.html
@@ -9,11 +9,9 @@
 		<style type="text/css">
 			/*@import "../../resources/dojo.css";*/
 		</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">
-			dojo.require("doh.runner");
+			require(["dojo", "doh", "dojo/domReady!"], function(dojo, doh){
 			
 			var margin = '1px';
 			var border = '3px solid black';
@@ -29,7 +27,7 @@
 				height: '20px',
 				width: '20px',
 				backgroundColor: 'blue'
-			}
+			};
 			
 			var testStyles = [
 				{},
@@ -39,8 +37,8 @@
 				{margin: margin, border: border},
 				{margin: margin, padding: padding},
 				{border: border, padding: padding},
-				{margin: margin, border: border, padding: padding}			
-			]
+				{margin: margin, border: border, padding: padding}
+			];
 			
 			
 			function sameBox(inBox1, inBox2) {
@@ -95,8 +93,8 @@
 				_testTopInc--;
 			}
 			
-			function testAndCallback(inTest, inAssert, inComment, inOk, inErr) {
-				inTest.assertTrue('/* ' + inComment +  '*/' + inAssert);
+			function testAndCallback(inTest, inAssert, inOk, inErr) {
+				inTest.assertTrue(inAssert);
 				if (inAssert)
 					inOk&&inOk();
 				else
@@ -114,10 +112,10 @@
 				if (inMix.length > 1)
 					args[1] = inMix[1];
 				args[2] = inArgs[2];
-				args[3] = inArgs[3]	
-				return args;	
-			};
-			
+				args[3] = inArgs[3];
+				return args;
+			}
+
 			function createStyledNodes(inArgs, inFunc) {
 				for (var i=0, n; (s=testStyles[i]); i++) {
 					n = createStyledElement.apply(this, mixCreateElementArgs([styleIncTop(s)], inArgs));
@@ -151,46 +149,45 @@
 			
 			function runFitTest(inTest, inParentStyles, inChildStyles) {
 				createStyledParentChildren([inParentStyles], [inChildStyles], function(p, c) {
-					testAndCallback(inTest, fitTest(p, c), '', function() {removeTestNode(p); });
+					testAndCallback(inTest, fitTest(p, c), function() {removeTestNode(p); });
 				});
 			}
 			
-			dojo.addOnLoad(function(){
-				doh.register("t", 
-					[
-						function reciprocalTests(t) {
-							createStyledNodes([], function(n) {
-								testAndCallback(t, reciprocalMarginBoxTest(n), '', function() {removeTestNode(n); });
-							});
-						},
-						function fitTests(t) {
-							runFitTest(t, null, dojo.mixin({}, defaultChildStyles));
-						},
-						function fitTestsOverflow(t) {
-							runFitTest(t, null, dojo.mixin({overflow:'hidden'}, defaultChildStyles));
-							runFitTest(t, {overflow: 'hidden'}, dojo.mixin({}, defaultChildStyles));
-							runFitTest(t, {overflow: 'hidden'}, dojo.mixin({overflow:'hidden'}, defaultChildStyles));
-						},
-						function fitTestsFloat(t) {
-							runFitTest(t, null, dojo.mixin({float: 'left'}, defaultChildStyles));
-							runFitTest(t, {float: 'left'}, dojo.mixin({}, defaultChildStyles));
-							runFitTest(t, {float: 'left'}, dojo.mixin({float: 'left'}, defaultChildStyles));
-						},
-						function reciprocalTestsInline(t) {
-							createStyledParentChild([], [{}, null, 'span'], function(p, c) {
-								c.innerHTML = 'Hello World';
-								testAndCallback(t, reciprocalMarginBoxTest(c), '', function() {removeTestNode(c); });
-							});
-						},
-						function reciprocalTestsButtonChild(t) {
-							createStyledParentChild([], [{}, null, 'button'], function(p, c) {
-								c.innerHTML = 'Hello World';
-								testAndCallback(t, reciprocalMarginBoxTest(c), '', function() {removeTestNode(c); });
-							});
-						}
-					]
-				);
-				doh.run();
+			doh.register("t", 
+				[
+					function reciprocalTests(t) {
+						createStyledNodes([], function(n) {
+							testAndCallback(t, reciprocalMarginBoxTest(n), function() {removeTestNode(n); });
+						});
+					},
+					function fitTests(t) {
+						runFitTest(t, null, dojo.mixin({}, defaultChildStyles));
+					},
+					function fitTestsOverflow(t) {
+						runFitTest(t, null, dojo.mixin({overflow:'hidden'}, defaultChildStyles));
+						runFitTest(t, {overflow: 'hidden'}, dojo.mixin({}, defaultChildStyles));
+						runFitTest(t, {overflow: 'hidden'}, dojo.mixin({overflow:'hidden'}, defaultChildStyles));
+					},
+					function fitTestsFloat(t) {
+						runFitTest(t, null, dojo.mixin({float: 'left'}, defaultChildStyles));
+						runFitTest(t, {float: 'left'}, dojo.mixin({}, defaultChildStyles));
+						runFitTest(t, {float: 'left'}, dojo.mixin({float: 'left'}, defaultChildStyles));
+					},
+					function reciprocalTestsInline(t) {
+						createStyledParentChild([], [{}, null, 'span'], function(p, c) {
+							c.innerHTML = 'Hello World';
+							testAndCallback(t, reciprocalMarginBoxTest(c), function() {removeTestNode(c); });
+						});
+					},
+					function reciprocalTestsButtonChild(t) {
+						createStyledParentChild([], [{}, null, 'button'], function(p, c) {
+							c.innerHTML = 'Hello World';
+							testAndCallback(t, reciprocalMarginBoxTest(c), function() {removeTestNode(c); });
+						});
+					}
+				]
+			);
+			doh.runOnLoad();
 			});
 		</script>
 		<style type="text/css">
diff --git a/dojo/tests/_base/html_box_quirks.html b/dojo/tests/_base/html_box_quirks.html
index 34324a6..656d3b5 100644
--- a/dojo/tests/_base/html_box_quirks.html
+++ b/dojo/tests/_base/html_box_quirks.html
@@ -7,11 +7,9 @@
 		<style type="text/css">
 			/*@import "../../resources/dojo.css";*/
 		</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">
-			dojo.require("doh.runner");
+			require(["dojo", "doh", "dojo/domReady!"], function(dojo, doh){
 			
 			var margin = '1px';
 			var border = '3px solid black';
@@ -27,7 +25,7 @@
 				height: '20px',
 				width: '20px',
 				backgroundColor: 'blue'
-			}
+			};
 			
 			var testStyles = [
 				{},
@@ -37,8 +35,8 @@
 				{margin: margin, border: border},
 				{margin: margin, padding: padding},
 				{border: border, padding: padding},
-				{margin: margin, border: border, padding: padding}			
-			]
+				{margin: margin, border: border, padding: padding}
+			];
 			
 			
 			function sameBox(inBox1, inBox2) {
@@ -112,10 +110,10 @@
 				if (inMix.length > 1)
 					args[1] = inMix[1];
 				args[2] = inArgs[2];
-				args[3] = inArgs[3]	
-				return args;	
-			};
-			
+				args[3] = inArgs[3];
+				return args;
+			}
+
 			function createStyledNodes(inArgs, inFunc) {
 				for (var i=0, n; (s=testStyles[i]); i++) {
 					n = createStyledElement.apply(this, mixCreateElementArgs([styleIncTop(s)], inArgs));
@@ -153,42 +151,41 @@
 				});
 			}
 			
-			dojo.addOnLoad(function(){
-				doh.register("t", 
-					[
-						function reciprocalTests(t) {
-							createStyledNodes([], function(n) {
-								testAndCallback(t, reciprocalMarginBoxTest(n), '', function() {removeTestNode(n); });
-							});
-						},
-						function fitTests(t) {
-							runFitTest(t, null, dojo.mixin({}, defaultChildStyles));
-						},
-						function fitTestsOverflow(t) {
-							runFitTest(t, null, dojo.mixin({overflow:'hidden'}, defaultChildStyles));
-							runFitTest(t, {overflow: 'hidden'}, dojo.mixin({}, defaultChildStyles));
-							runFitTest(t, {overflow: 'hidden'}, dojo.mixin({overflow:'hidden'}, defaultChildStyles));
-						},
-						function fitTestsFloat(t) {
-							runFitTest(t, null, dojo.mixin({float: 'left'}, defaultChildStyles));
-							runFitTest(t, {float: 'left'}, dojo.mixin({}, defaultChildStyles));
-							runFitTest(t, {float: 'left'}, dojo.mixin({float: 'left'}, defaultChildStyles));
-						},
-						function reciprocalTestsInline(t) {
-							createStyledParentChild([], [{}, null, 'span'], function(p, c) {
-								c.innerHTML = 'Hello World';
-								testAndCallback(t, reciprocalMarginBoxTest(c), '', function() {removeTestNode(c); });
-							});
-						},
-						function reciprocalTestsButtonChild(t) {
-							createStyledParentChild([], [{}, null, 'button'], function(p, c) {
-								c.innerHTML = 'Hello World';
-								testAndCallback(t, reciprocalMarginBoxTest(c), '', function() {removeTestNode(c); });
-							});
-						}
-					]
-				);
-				doh.run();
+			doh.register("t", 
+				[
+					function reciprocalTests(t) {
+						createStyledNodes([], function(n) {
+							testAndCallback(t, reciprocalMarginBoxTest(n), '', function() {removeTestNode(n); });
+						});
+					},
+					function fitTests(t) {
+						runFitTest(t, null, dojo.mixin({}, defaultChildStyles));
+					},
+					function fitTestsOverflow(t) {
+						runFitTest(t, null, dojo.mixin({overflow:'hidden'}, defaultChildStyles));
+						runFitTest(t, {overflow: 'hidden'}, dojo.mixin({}, defaultChildStyles));
+						runFitTest(t, {overflow: 'hidden'}, dojo.mixin({overflow:'hidden'}, defaultChildStyles));
+					},
+					function fitTestsFloat(t) {
+						runFitTest(t, null, dojo.mixin({float: 'left'}, defaultChildStyles));
+						runFitTest(t, {float: 'left'}, dojo.mixin({}, defaultChildStyles));
+						runFitTest(t, {float: 'left'}, dojo.mixin({float: 'left'}, defaultChildStyles));
+					},
+					function reciprocalTestsInline(t) {
+						createStyledParentChild([], [{}, null, 'span'], function(p, c) {
+							c.innerHTML = 'Hello World';
+							testAndCallback(t, reciprocalMarginBoxTest(c), '', function() {removeTestNode(c); });
+						});
+					},
+					function reciprocalTestsButtonChild(t) {
+						createStyledParentChild([], [{}, null, 'button'], function(p, c) {
+							c.innerHTML = 'Hello World';
+							testAndCallback(t, reciprocalMarginBoxTest(c), '', function() {removeTestNode(c); });
+						});
+					}
+				]
+			);
+			doh.runOnLoad();
 			});
 		</script>
 		<style type="text/css">
diff --git a/dojo/tests/_base/html_docScroll.html b/dojo/tests/_base/html_docScroll.html
index cf3247b..effc2fe 100644
--- a/dojo/tests/_base/html_docScroll.html
+++ b/dojo/tests/_base/html_docScroll.html
@@ -3,13 +3,10 @@
 <html>
 	<head>
 		<title>testing Core _docScroll function</title>
-		<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">
-			dojo.require("doh.runner");
+			require(["dojo", "doh", "dojo/domReady!"], function(dojo, doh){
 			
-			dojo.addOnLoad(function(){
 				doh.register("t", 
 					[
 						function testNonScrolled(t){
@@ -42,23 +39,23 @@
 							t.is(10, s.x);
 							t.is(20, s.y);
 						},
+
 						function testSpeed(t){
-							var d = dojo;
 							var old_docScroll = function(){
-							        var
-							                _b = d.body(),
-							                _w = d.global,
-							                de = d.doc.documentElement;
-							        return {
-							                y: (_w.pageYOffset || de.scrollTop || _b.scrollTop || 0),
-							                x: (_w.pageXOffset || d._fixIeBiDiScrollLeft(de.scrollLeft) || _b.scrollLeft || 0)
-							        };
+								var
+									_b = dojo.body(),
+									_w = dojo.global,
+									de = dojo.doc.documentElement;
+								return {
+									y: (_w.pageYOffset || de.scrollTop || _b.scrollTop || 0),
+									x: (_w.pageXOffset || dojo._fixIeBiDiScrollLeft(de.scrollLeft) || _b.scrollLeft || 0)
+								};
 							};
 							var count = 10000; // initial guess
 							var new_docScroll = dojo._docScroll;
 							var t0 = new Date().getTime();
 							for (var i=0; i < count; i++){
-							        var j = new_docScroll();
+											var j = new_docScroll();
 							}
 							t0 = new Date().getTime() - t0;
 							// modify guess to get about 1 second of CPU crunching
@@ -69,12 +66,12 @@
 							}
 							t0 = new Date().getTime();
 							for (i=0; i < count; i++){
-							        j = new_docScroll();
+											j = new_docScroll();
 							}
 							t0 = new Date().getTime() - t0;
 							var t1 = new Date().getTime();
 							for (var i=0; i < count; i++){
-							        j = old_docScroll();
+											j = old_docScroll();
 							}
 							t1 = new Date().getTime() - t1;
 							console.log(Math.floor(100*(t1-t0)/t1)+"% speed improvement");
@@ -82,7 +79,7 @@
 						}
 					]
 				);
-				doh.run();
+				doh.runOnLoad();
 			});
 		</script>
 	</head>
@@ -93,9 +90,11 @@
 		</div>
 		<script type="text/javascript">
 			// make sure div is too big to display
-			var div = dojo.byId('div');
-			div.style.height = (dojo.doc.documentElement.clientHeight + 2) + "px";
-			div.style.width = (dojo.doc.documentElement.clientWidth + 1) + "px";
+      require(["dojo"], function(dojo) {
+  			var div = dojo.byId('div');
+	  		div.style.height = (dojo.doc.documentElement.clientHeight + 2) + "px";
+		  	div.style.width = (dojo.doc.documentElement.clientWidth + 1) + "px";
+      });
 		</script>
 	</body>
 </html>
diff --git a/dojo/tests/_base/html_element.html b/dojo/tests/_base/html_element.html
index a0dd3c8..0282d8a 100644
--- a/dojo/tests/_base/html_element.html
+++ b/dojo/tests/_base/html_element.html
@@ -10,13 +10,10 @@
 		<style type="text/css">
 			@import "../../resources/dojo.css";
 		</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">
-			dojo.require("doh.runner");
+			require(["dojo", "doh", "dojo/domReady!"], function(dojo, doh){
 			
-			dojo.addOnLoad(function(){
 				doh.register("t", 
 					[
 					
@@ -125,7 +122,7 @@
 								return dojo.query("body >").filter(function(n){
 									return !dojo.hasClass(n, "firebug");
 								})
-							}
+							};
 							c().forEach(dojo.destroy);
 
 							// check for deepest embeeded id
@@ -281,7 +278,7 @@
 						}
 					]
 				);
-				doh.run();
+				doh.runOnLoad();
 			});
 		</script>
 	</head>
diff --git a/dojo/tests/_base/html_id.html b/dojo/tests/_base/html_id.html
index 320f07f..474c2c5 100644
--- a/dojo/tests/_base/html_id.html
+++ b/dojo/tests/_base/html_id.html
@@ -10,13 +10,10 @@
 		<style type="text/css">
 			@import "../../resources/dojo.css";
 		</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">
-			dojo.require("doh.runner");
+			require(["dojo", "doh", "dojo/domReady!"], function(dojo, doh){
 			
-			dojo.addOnLoad(function(){
 				doh.register("t", 
 					[
 						function byId(t){
@@ -47,7 +44,8 @@
 						}
 					]
 				);
-				doh.run();
+				doh.runOnLoad();
+
 			});
 		</script>
 	</head>
diff --git a/dojo/tests/_base/html_isBodyLtr.html b/dojo/tests/_base/html_isBodyLtr.html
index bcb7cd8..79d8310 100644
--- a/dojo/tests/_base/html_isBodyLtr.html
+++ b/dojo/tests/_base/html_isBodyLtr.html
@@ -3,42 +3,32 @@
 <html dir="LTR">
 	<head>
 		<title>testing Core _isBodyLtr function</title>
-		<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">
-			dojo.require("doh.runner");
-			
-			dojo.addOnLoad(function(){
+			require(["dojo", "doh", "dojo/domReady!"], function(dojo, doh){
 				doh.register("t", 
 					[
 						function testRtl(t){
 							t.is(false, dojo._isBodyLtr());
 						},
 						function testCache(t){
-							dojo.body().setAttribute("dir", "ltr");
 							t.is(false, dojo._isBodyLtr());
-							delete dojo._bodyLtr; // clear cache
+							dojo.body().setAttribute("dir", "ltr");
 							t.is(true, dojo._isBodyLtr());
 						},
 						function testHtmlValue(t){
-							delete dojo._bodyLtr; // clear cache
 							dojo.body().setAttribute("dir", "RTL");
 							t.is(false, dojo._isBodyLtr());
-							delete dojo._bodyLtr; // clear cache
 							dojo.body().removeAttribute("dir");
 							t.is(true, dojo._isBodyLtr());
 						},
 						function testDefaultValue(t){
-							delete dojo._bodyLtr; // clear cache
 							dojo.doc.documentElement.setAttribute("dir", "rtl");
 							t.is(false, dojo._isBodyLtr());
-							delete dojo._bodyLtr; // clear cache
 							dojo.doc.documentElement.removeAttribute("dir");
 							t.is(true, dojo._isBodyLtr());
 						},
 						function testHiddenIframe(t){
-							delete dojo._bodyLtr; // clear cache
 							dojo.doc.documentElement.setAttribute("dir", "rtl");
 							t.is(false, dojo._isBodyLtr());
 							t.is(true, dojo.withGlobal(dojo.byId('iframe').iframeContentWindow, "_isBodyLtr", dojo));
@@ -46,7 +36,7 @@
 						}
 					]
 				);
-				doh.run();
+				doh.runOnLoad();
 			});
 		</script>
 	</head>
diff --git a/dojo/tests/_base/html_quirks.html b/dojo/tests/_base/html_quirks.html
index c33284b..097cf98 100644
--- a/dojo/tests/_base/html_quirks.html
+++ b/dojo/tests/_base/html_quirks.html
@@ -7,12 +7,9 @@
 		<style type="text/css">
 			@import "../../resources/dojo.css";
 		</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">
-			dojo.require("doh.runner");
-			dojo.addOnLoad(function(){
+			require(["dojo", "doh", "dojo/domReady!"], function(dojo, doh){
 				doh.register("t", 
 					[
 						"t.is(100, dojo.marginBox('sq100').w);",
@@ -138,7 +135,7 @@
 					);
 				}
 
-				doh.run();
+				doh.runOnLoad();
 			});
 		</script>
 		<style type="text/css">
diff --git a/dojo/tests/_base/html_rtl.html b/dojo/tests/_base/html_rtl.html
index e5d3214..a33e8b6 100644
--- a/dojo/tests/_base/html_rtl.html
+++ b/dojo/tests/_base/html_rtl.html
@@ -6,13 +6,10 @@
 		<style type="text/css">
 			@import "../../resources/dojo.css";
 		</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">
-			dojo.require("doh.runner");
+			require(["dojo", "doh", "dojo/domReady!"], function(dojo, doh){
 			
-			dojo.addOnLoad(function(){
 				doh.register("rtl", 
 					[
 						{
@@ -20,7 +17,7 @@
 							timeout: 1000,
 							runTest: function(t){
 								var d = new doh.Deferred();
-								setTimeout(function(){ // allow browsers time to return the scroll point back to the last position
+								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
 									setTimeout(d.getTestCallback(function(){ // time to scroll
@@ -28,7 +25,7 @@
 										t.is(100, pos.y, "y pos should be 100 after vertical scroll");
 										t.is(100, pos.x, "x pos should be 100 after horizontal scroll");
 									}), 100);
-								}, 100);
+								}), 100);
 								return d;
 							}
 						},
@@ -42,29 +39,40 @@
 								var
 								d = new doh.Deferred(),
 								rect = dojo.byId("rect100"),
-								handler = dojo.connect(dojo.body(), "onclick", null,
-									function(e){
+								handler = dojo.connect(rect.offsetParent, "onclick", null,
+									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,
-											function(){
-												var offsetX = event.offsetX,
-													offsetY = event.offsetY;
+											d.getTestCallback(function(e){
+												var offsetX = (event||e).offsetX,
+													offsetY = (event||e).offsetY;
 												dojo.disconnect(handler);
-												d.getTestCallback(function(){
-													t.is(0, offsetX);
-													t.is(0, offsetY);
-												})();
-											});
-										setTimeout(function(){
-											rect.fireEvent('ondblclick');
-										}, 100); // time to move rect to cursor position
-									});
-								setTimeout(function(){
-									dojo.body().fireEvent('onclick');
-								}, 100); // time to finish any pre-scrolling
+												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
+									}));
+								setTimeout(d.getTestErrback(function(){
+									if(!document.createEvent){
+										rect.offsetParent.fireEvent('onclick');
+									}else{
+										var clickEvent = document.createEvent("MouseEvent");
+										clickEvent.initMouseEvent("click", true, true, window, 0,0,0,0,0,0,0,0,0,0,null);
+										rect.offsetParent.dispatchEvent(clickEvent);
+									}
+
+								}), 100); // time to finish any pre-scrolling
 								return d;
 							}
 						},
@@ -84,7 +92,7 @@
 						}
 					]
 				);
-				
+
 				// test to make sure position() works with a variety of scrollbars
 				dojo.forEach(["None", "Horz", "Vert", "Both"], function(scroll){
 					dojo.forEach(["Quirks", "Strict"], function(doctype){
@@ -92,7 +100,7 @@
 							var id = "scrolling" + doctype + "Iframe" + scroll + size;
 							doh.register(id, {
 								name: "test_" + id,
-								timeout: 3000,
+								timeout: 4000,
 								runTest: function(t){
 									var d = new doh.Deferred(),
 										s = document.createElement('SPAN');
@@ -112,7 +120,7 @@
 					});
 				});
 
-				doh.run();
+				doh.runOnLoad();
 			});
 		</script>
 		<style type="text/css">
diff --git a/dojo/tests/_base/json.js b/dojo/tests/_base/json.js
index 687622c..eff0365 100644
--- a/dojo/tests/_base/json.js
+++ b/dojo/tests/_base/json.js
@@ -1,4 +1,4 @@
-dojo.provide("tests._base.json");
+dojo.provide("dojo.tests._base.json");
 
 tests.register("tests._base.json",
 	[
@@ -7,7 +7,7 @@ tests.register("tests._base.json",
 
 		// take a json-compatible object, convert it to a json string, then put it back into json.
 		function toAndFromJson(t){
-			var testObj = {a:"a", b:1, c:"c", d:"d", e:{e1:"e1", e2:2}, f:[1,2,3], g:"g",h:{h1:{h2:{h3:"h3"}}}};
+			var testObj = {a:"a", b:1, c:"c", d:"d", e:{e1:"e1", e2:2}, f:[1,2,3], g:"g",h:{h1:{h2:{h3:"h3"}}},i:[[0,1,2],[3],[4]]};
 
 			var mirrorObj = dojo.fromJson(dojo.toJson(testObj));
 			t.assertEqual("a", mirrorObj.a);
@@ -27,6 +27,33 @@ tests.register("tests._base.json",
 			}catch(e){
 			}
 			t.assertEqual(undefined,badJson);
+			t.assertEqual(3, mirrorObj.i[0].length);
+			t.assertEqual(1, mirrorObj.i[1].length);
+			t.assertEqual(1, mirrorObj.i[2].length);
+		},
+		// 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 testStr = dojo.toJson(testObj);
+			t.assertEqual('{"ex1":"json3","ex2":"__json__4"}', testStr);
+		},
+		// pretty print
+		function prettyPrintJson(t){
+			if(typeof JSON == "undefined"){ // only test our JSON stringifier
+				var testObj = {array:[1,2,{a:4,b:4}]};
+				var testStr = dojo.toJson(testObj, true);
+				t.assertEqual('{\n\t\"array\": [\n\t\t1,\n\t\t2,\n\t\t{\n\t\t\t\"a\": 4,\n\t\t\t\"b\": 4\n\t\t}\n\t]\n}', testStr);
+			}
+		},
+		// have to verify that we still support any JS expression
+		function evalJson(t){
+			var testStr = '{func: function(){}, number: Infinity}';
+			var testObj = dojo.fromJson(testStr);
+			t.is("function", typeof testObj.func);
+			t.is("number", typeof testObj.number);
+		},
+		function toJsonStringObject(t){
+			t.is('"hello"', dojo.toJson(new String("hello")));
 		}
 	]
 );
diff --git a/dojo/tests/_base/lang.js b/dojo/tests/_base/lang.js
index 3f526a8..1d6288b 100644
--- a/dojo/tests/_base/lang.js
+++ b/dojo/tests/_base/lang.js
@@ -1,7 +1,6 @@
-dojo.provide("tests._base.lang");
+define(["dojo", "doh"], function(dojo, doh){
 
-tests.register("tests._base.lang",
-	[
+  doh.register("tests._base.lang", [
 		function mixin(t){
 			t.assertEqual("object", typeof dojo.mixin());
 			t.assertEqual("object", typeof dojo.mixin(undefined));
@@ -276,4 +275,5 @@ tests.register("tests._base.lang",
 			t.is("Hello, Robert Cringely!", s4);
 		}
 	]
-);
\ No newline at end of file
+  );
+});
\ No newline at end of file
diff --git a/dojo/tests/_base/loader.js b/dojo/tests/_base/loader.js
new file mode 100644
index 0000000..3a148cc
--- /dev/null
+++ b/dojo/tests/_base/loader.js
@@ -0,0 +1,135 @@
+define([
+	"dojo",
+	"doh",
+	"require",
+	"./loader/core",
+	"dojo/has!dojo-amd-factory-scan?./loader/modules",
+	"./loader/moduleIds",
+	"./loader/bootstrap"], function(dojo, doh, require){
+	if(doh.isBrowser){
+		doh.register("tests._base.loader.asyncWithDojoRequire", require.toUrl("./loader/asyncWithDojoRequire.html"));
+
+		doh.register("tests._base.loader.config?dojoConfig-djConfig-require", require.toUrl("./loader/config.html")+"?dojoConfig-djConfig-require");
+		doh.register("tests._base.loader.config?dojoConfig-require", require.toUrl("./loader/config.html")+"?dojoConfig-require");
+		doh.register("tests._base.loader.config?dojoConfig-djConfig", require.toUrl("./loader/config.html")+"?dojoConfig-djConfig");
+		doh.register("tests._base.loader.config?dojoConfig", require.toUrl("./loader/config.html")+"?dojoConfig");
+		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"));
+		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"));
+		//TODO: doh.register("tests._base.loader.cdn-load", require.toUrl("./loader/cdnTest.html"));
+		doh.register("tests._base.loader.loader-declareStepsOnProvide", require.toUrl("./loader/declareStepsOnProvide.html"));
+
+		doh.register("tests._base.loader.publish-require-result", require.toUrl("./loader/publishRequireResult.html"));
+		doh.register("tests._base.loader.no-publish-require-result", require.toUrl("./loader/publishRequireResult.html")+"?do-not-publish");
+
+		doh.register("tests._base.loader.top-level-module-by-paths", require.toUrl("./loader/paths.html"));
+		doh.register("tests._base.loader.xdomin-sync-1", require.toUrl("./loader/xdomain/xdomain.html"), {async:0, variation:1});
+		doh.register("tests._base.loader.xdomin-sync-2", require.toUrl("./loader/xdomain/xdomain.html"), {async:0, variation:2});
+		doh.register("tests._base.loader.xdomin-async-1", require.toUrl("./loader/xdomain/xdomain.html"), {async:"legacyAsync", variation:1});
+		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
+        //
+		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});
+
+		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});
+
+		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});
+
+		function compactPath(path){
+			var
+				result= [],
+				segment, lastSegment;
+		    path= path.split("/");
+			while(path.length){
+				segment= path.shift();
+				if(segment==".." && result.length && lastSegment!=".."){
+					result.pop();
+				}else if(segment!="."){
+					result.push(lastSegment= segment);
+				} // else ignore "."
+			}
+			return result.join("/");
+		}
+		var
+			qstart= location.href.indexOf(location.search),
+		    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){
+			doh.register("tests._base.loader.requirejs-simple-badbase-sync", require.toUrl("./loader/requirejs/simple-badbase.html"), {
+				async:0,
+				baseUrl:baseUrl,
+				setup:setup,
+				dojo:compactPath(root + "/../" + require.toUrl("../../dojo.js"))
+			});
+		}
+		doh.register("tests._base.loader.requirejs-simple-badbase-async", require.toUrl("./loader/requirejs/simple-badbase.html"), {
+			async:1,
+			baseUrl:baseUrl,
+			setup:setup,
+			dojo:compactPath(root + "/../" + require.toUrl("../../dojo.js"))
+		});
+
+		//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});
+
+		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});
+
+		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});
+
+		doh.register("tests._base.loader.requirejs-i18n-sync", require.toUrl("./loader/requirejs/i18n/i18n.html"), {async:0});
+		doh.register("tests._base.loader.requirejs-i18n-async", require.toUrl("./loader/requirejs/i18n/i18n.html"), {async:1});
+
+		doh.register("tests._base.loader.requirejs-i18nlocale-sync", require.toUrl("./loader/requirejs/i18n/i18n.html")+"?locale=en-us-surfer", {async:0});
+		doh.register("tests._base.loader.requirejs-i18nlocale-async", require.toUrl("./loader/requirejs/i18n/i18n.html")+"?locale=en-us-surfer", {async:1});
+
+		doh.register("tests._base.loader.requirejs-i18nbundle-sync", require.toUrl("./loader/requirejs/i18n/i18n.html")+"?bundle=i18n!nls/en-us-surfer/colors", {async:0});
+		doh.register("tests._base.loader.requirejs-i18nbundle-async", require.toUrl("./loader/requirejs/i18n/i18n.html")+"?bundle=i18n!nls/en-us-surfer/colors", {async:1});
+
+		doh.register("tests._base.loader.requirejs-i18ncommon-sync", require.toUrl("./loader/requirejs/i18n/common.html"), {async:0});
+		doh.register("tests._base.loader.requirejs-i18ncommon-async", require.toUrl("./loader/requirejs/i18n/common.html"), {async:1});
+
+		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});
+
+		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});
+
+		doh.register("tests._base.loader.requirejs-relative-sync", require.toUrl("./loader/requirejs/relative/relative.html"), {async:0});
+		doh.register("tests._base.loader.requirejs-relative-async", require.toUrl("./loader/requirejs/relative/relative.html"), {async:1});
+
+		doh.register("tests._base.loader.requirejs-text-sync", require.toUrl("./loader/requirejs/text/text.html"), {async:0});
+		doh.register("tests._base.loader.requirejs-text-async", require.toUrl("./loader/requirejs/text/text.html"), {async:1});
+		doh.register("tests._base.loader.requirejs-text-sync", require.toUrl("./loader/requirejs/text/text.html"), {async:0, aliasTest:1});
+		doh.register("tests._base.loader.requirejs-text-async", require.toUrl("./loader/requirejs/text/text.html"), {async:1, aliasTest:1});
+
+		doh.register("tests._base.loader.requirejs-textOnly-sync", require.toUrl("./loader/requirejs/text/textOnly.html"), {async:0});
+		doh.register("tests._base.loader.requirejs-textOnly-async", require.toUrl("./loader/requirejs/text/textOnly.html"), {async:1});
+
+		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});
+	}
+});
diff --git a/dojo/tests/_base/_loader/8976.html b/dojo/tests/_base/loader/8976.html
similarity index 100%
rename from dojo/tests/_base/_loader/8976.html
rename to dojo/tests/_base/loader/8976.html
diff --git a/dojo/tests/_base/_loader/a.js b/dojo/tests/_base/loader/a.js
similarity index 100%
rename from dojo/tests/_base/_loader/a.js
rename to dojo/tests/_base/loader/a.js
diff --git a/dojo/tests/_base/_loader/addLoadEvents.html b/dojo/tests/_base/loader/addLoadEvents.html
similarity index 100%
rename from dojo/tests/_base/_loader/addLoadEvents.html
rename to dojo/tests/_base/loader/addLoadEvents.html
diff --git a/dojo/tests/_base/loader/afterOnLoad.html b/dojo/tests/_base/loader/afterOnLoad.html
new file mode 100644
index 0000000..4a83c33
--- /dev/null
+++ b/dojo/tests/_base/loader/afterOnLoad.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>Testing afterOnLoad</title>
+
+		<link rel="stylesheet" type="text/css" href="../../../resources/dojo.css"/>
+		<link rel="stylesheet" type="text/css" href="../../../../dijit/tests/css/dijitTests.css"/>
+		<link rel="stylesheet" type="text/css" href="../../../../dijit/themes/tundra/tundra.css"/>
+
+		<script type="text/javascript">
+			function init(){
+				//Create global dojoConfig object first. We cannot use the dojoConfig attribute
+				//on the script tag since it may not be visible in some browsers at the time
+				//dojo.js executes. This causes problems when the "require" property is used
+				//as part of djConfig. 
+
+				//Previous versions of this test stated that baseUrl must be set explicitly because
+				//the sniffing code would not work. As of 1.7, this seems to be unnecessary
+
+				var startTime = (new Date()).getTime();
+
+				var async = /async/.test(location.search);
+				dojoConfig = {
+					async:async,
+					parseOnLoad:true,
+					afterOnLoad:true,
+					isDebug: true
+				};
+				var callback = function(){
+					dojo.byId("status").innerHTML = 
+						"dojo.ready callback executed OK.<br>" +
+						"total load time: " + (((new Date()).getTime() - startTime) / 1000) + "s";
+				}
+				if(async){
+					dojoConfig.deps = ["dojo", "dojo/parser", "dijit/Calendar"]
+					dojoConfig.callback = callback;
+				}else{
+					dojoConfig.addOnLoad = callback;
+					dojoConfig.require = ['dojo.parser', 'dijit.Calendar'];
+				};
+
+				var script = document.createElement("script");
+				script.type = "text/javascript";
+				script.src = "../../../dojo.js";
+				document.getElementsByTagName("head")[0].appendChild(script);
+			}
+
+			function myHandler(id,newValue){
+				console.debug("onChange for id = " + id + ", value: " + newValue);
+			}
+			
+			//Register onload init function that will add Dojo to the page.
+			if(window.addEventListener){
+				window.addEventListener("load", init, false);
+			}else{
+				window.attachEvent("onload", init);
+			}
+		</script>
+	</head>
+	<body>
+		<h1>Testing afterOnLoad</h1>
+
+		<p>This page tests loading dojo after the page is loaded. </p>
+
+		<p>Add the query string "?async" to the URL to test asynchronous operation; an empty query string results in
+		synchronous loading.</p>
+		
+		<p>When the window.onload fires, the dojo script tag will be added to the DOM 
+		and configured to fire the onload callbacks. If everything works, you should
+		see a Calendar below.</p>
+
+		<p id="status"></p>
+		
+		<p class="tundra">
+			<input id="calendar1" data-dojo-type="dijit.Calendar" onChange="myHandler(this.id,arguments[0])">
+		</p>
+	</body>
+</html>
diff --git a/dojo/tests/_base/loader/amdModule.js b/dojo/tests/_base/loader/amdModule.js
new file mode 100644
index 0000000..93ae6eb
--- /dev/null
+++ b/dojo/tests/_base/loader/amdModule.js
@@ -0,0 +1,5 @@
+dojoCdnTestLog.push("defining-dojo.tests._base.loader.amdModule");
+define(["./amdModuleDep"], function(){
+	dojoCdnTestLog.push("factory-dojo.tests._base.loader.amdModule");
+	return {status:"OK"};
+});
diff --git a/dojo/tests/_base/loader/amdModule1.js b/dojo/tests/_base/loader/amdModule1.js
new file mode 100644
index 0000000..80fe367
--- /dev/null
+++ b/dojo/tests/_base/loader/amdModule1.js
@@ -0,0 +1,5 @@
+dojoCdnTestLog.push("defining-dojo.tests._base.loader.amdModule1");
+define(["./amdModuleDep1"], function(){
+	dojoCdnTestLog.push("factory-dojo.tests._base.loader.amdModule1");
+	return {status:"OK"};
+});
diff --git a/dojo/tests/_base/loader/amdModule2.js b/dojo/tests/_base/loader/amdModule2.js
new file mode 100644
index 0000000..696e246
--- /dev/null
+++ b/dojo/tests/_base/loader/amdModule2.js
@@ -0,0 +1,5 @@
+dojoCdnTestLog.push("defining-dojo.tests._base.loader.amdModule2");
+define(["./amdModuleDep"], function(){
+	dojoCdnTestLog.push("factory-dojo.tests._base.loader.amdModule2");
+	return {status:"OK"};
+});
diff --git a/dojo/tests/_base/loader/amdModuleDep.js b/dojo/tests/_base/loader/amdModuleDep.js
new file mode 100644
index 0000000..ed1b33c
--- /dev/null
+++ b/dojo/tests/_base/loader/amdModuleDep.js
@@ -0,0 +1,5 @@
+dojoCdnTestLog.push("defining-dojo.tests._base.loader.amdModuleDep");
+define([], function(){
+	dojoCdnTestLog.push("factory-dojo.tests._base.loader.amdModuleDep");
+	return {status:"OK"};
+});
diff --git a/dojo/tests/_base/loader/amdModuleDep1.js b/dojo/tests/_base/loader/amdModuleDep1.js
new file mode 100644
index 0000000..14ec771
--- /dev/null
+++ b/dojo/tests/_base/loader/amdModuleDep1.js
@@ -0,0 +1,5 @@
+dojoCdnTestLog.push("defining-dojo.tests._base.loader.amdModuleDep1");
+define([], function(){
+	dojoCdnTestLog.push("factory-dojo.tests._base.loader.amdModuleDep1");
+	return {status:"OK"};
+});
diff --git a/dojo/tests/_base/loader/amdModuleDep2.js b/dojo/tests/_base/loader/amdModuleDep2.js
new file mode 100644
index 0000000..b19c279
--- /dev/null
+++ b/dojo/tests/_base/loader/amdModuleDep2.js
@@ -0,0 +1,5 @@
+dojoCdnTestLog.push("defining-dojo.tests._base.loader.amdModuleDep2");
+define([], function(){
+	dojoCdnTestLog.push("factory-dojo.tests._base.loader.amdModuleDep2");
+	return {status:"OK"};
+});
diff --git a/dojo/tests/_base/loader/asyncWithDojoRequire.html b/dojo/tests/_base/loader/asyncWithDojoRequire.html
new file mode 100644
index 0000000..1a36904
--- /dev/null
+++ b/dojo/tests/_base/loader/asyncWithDojoRequire.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>loader-only</title>
+    <script type="text/javascript" data-dojo-config="async:true" src="../../../dojo.js"></script>
+    <script type="text/javascript">
+	function loadProvidePlugin(){
+		define("dojo/provide", ["dojo", "./text"], function(dojo, textPlugin){
+			// summary:
+			//		Plugin for loading legacy dojo modules (that use dojo.provide/dojo.require)
+			//		with the async loader. For example:
+			//		|	define(["dojo/dojo-require!dojox.cometd"], function(){
+			//		|		dojox.cometd.init("/cometd");
+			//		|		...
+			//		|	});
+			//		This will load dojox.cometd and all it's dependencies asynchronously. 
+			dojo.require = function(id){
+				// this is mainly for top level, it should be do nothing once a module is loaded
+				var loadedModule; 
+				require(["dojo/provide!" + id], function(module){
+					loadedModule = module;
+				});
+				return loadedModule; // return the loaded module if it is synchronously available 
+			};
+			dojo.provide = function(id){
+				dojo.getObject(id, true);
+			};
+			return {
+				load: function(id, parentRequire, loaded, config){
+					id = id.replace(/\//g, '.');
+					var existing = dojo.getObject(id); 
+					if(existing){
+						return loaded(existing);
+					}
+					textPlugin.load(id.replace(/\./g, '/') + ".js", parentRequire, function(text){
+						var deps = 0, done;
+						var commentFree = text.replace(/\/\*[\s\S]*?\*\//g, '');
+						if(!/dojo\.provide\s*\(\s*['"]([^'"]*)['"]\s*\)/.test(commentFree)){
+							// doesn't look like a dojo module after all, revert back to script loading (hopefully the request should be cached)
+							return parentRequire([id.replace(/\./g, '/')], function(module){
+								loaded(module);
+							});
+						}
+						addDependencies(/dojo\.require\s*\(\s*['"]([^'"]*)['"]\s*\)/g, function(moduleId, loaded){
+							parentRequire(["dojo/provide!" + moduleId], loaded);
+						});
+						addDependencies(/dojo\.cache\s*\(\s*['"]([^'"]*['"]\s*,\s*['"][^'"]*)['"]\s*\)/g, function(moduleId, loaded){
+							var parts = moduleId.split(/['"]\s*,\s*['"]/);
+							parts[0] = parts[0].replace(/\./g, '/');
+							textPlugin.load(parts.join('/'), require, loaded, config);
+						});
+						done = true;
+						if(deps == 0){
+							ready();
+						}
+						function addDependencies(regex, handler){
+							commentFree.replace(regex, function(t, moduleId){
+								deps++;
+								handler(moduleId, function(){
+									deps--;
+									if(done && deps == 0){
+										ready();
+									}
+								});
+							});					
+						}
+						function ready(){
+							eval(text + "\r\n//@ sourceURL=" + id);
+							loaded(dojo.getObject(id));
+						}
+					});
+				}
+			};
+		});
+	}
+	</script>
+    <script type="text/javascript">
+		var mid = "dojo/tests/_base/loader/syncFromAsyncModule"
+		if(location.search=="?provide!"){
+			// this just keeps the plugin out of the repo until we decide which way to go
+			loadProvidePlugin();
+			mid = "dojo/provide!" + mid;
+		}else{
+			// dojo must be loaded for legacy modes to work
+			require({async:"sync"}, ["dojo"]);
+			// now we can switch to legacy async mode
+			require({async:"legacyAsync"});
+		}
+		require(["dojo", "doh", mid], function(dojo, doh, syncModule) {
+			dojo.ready(function() {
+				doh.register("asyncWithDojoRequire", [function loadSyncModule(t){
+					t.is(syncModule.status, "OK");
+				}]);
+				doh.runOnLoad();
+			});
+		});
+    </script>
+  </head>
+  <body>
+    <h1>Description: Async Dojo loading 1.6 module</h1>
+  </body>
+</html>
diff --git a/dojo/tests/_base/loader/bootstrap.js b/dojo/tests/_base/loader/bootstrap.js
new file mode 100644
index 0000000..616554c
--- /dev/null
+++ b/dojo/tests/_base/loader/bootstrap.js
@@ -0,0 +1,157 @@
+define(["dojo", "doh", "../../../_base/sniff", "require"], function(dojo, doh, has, require){
+	doh.register("tests._base._loader.bootstrap", [
+		function hasConsole(t){
+			t.assertTrue("console" in dojo.global);
+			t.assertTrue("assert" in console);
+			t.assertEqual("function", typeof console.assert);
+		},
+
+		function getText(t){
+			if(require.getText){
+				var text = require.getText(require.toUrl("dojo/tests/_base/loader/getText.txt")).replace(/\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, "");
+					t.assertEqual("dojo._getText() test data", text);
+				}
+			}
+		},
+
+		{
+			name: "getObject",
+			setUp: function(){
+				//Set an object in global scope.
+				dojo.global.globalValue = {
+					color: "blue",
+					size: 20
+				};
+
+				//Set up an object in a specific scope.
+				this.foo = {
+					bar: {
+						color: "red",
+						size: 100
+					}
+				};
+			},
+			runTest: function(t){
+				//Test for existing object using global as root path.
+				var globalVar = dojo.getObject("globalValue");
+				t.is("object", (typeof globalVar));
+				t.assertEqual("blue", globalVar.color);
+				t.assertEqual(20, globalVar.size);
+				t.assertEqual("blue", dojo.getObject("globalValue.color"));
+
+				//Test for non-existent object using global as root path.
+				//Then create it.
+				t.assertFalse(dojo.getObject("something.thatisNew"));
+				t.assertTrue(typeof(dojo.getObject("something.thatisNew", true)) == "object");
+
+				//Test for existing object using another object as root path.
+				var scopedVar = dojo.getObject("foo.bar", false, this);
+				t.assertTrue(typeof(scopedVar) == "object");
+				t.assertEqual("red", scopedVar.color);
+				t.assertEqual(100, scopedVar.size);
+				t.assertEqual("red", dojo.getObject("foo.bar.color", true, this));
+
+				//Test for existing object using another object as root path.
+				//Then create it.
+				t.assertFalse(dojo.getObject("something.thatisNew", false, this));
+				t.assertTrue(typeof(dojo.getObject("something.thatisNew", true, this)) == "object");
+			},
+			tearDown: function(){
+				//Clean up global object that should not exist if
+				//the test is re-run.
+				try{
+					delete dojo.global.something;
+					delete this.something;
+				}catch(e){}
+			}
+		},
+
+		{
+			name: "exists",
+			setUp: function(){
+				this.foo = {
+					bar: {},
+					baz: 0,
+					bam: false,
+					bal: "",
+					ban: null
+				};
+			},
+			runTest: function(t){
+				t.assertTrue(dojo.exists("foo.bar", this));
+				t.assertFalse(dojo.exists("foo.bar"));
+				t.assertTrue(dojo.exists("foo.baz", this));
+				t.assertTrue(dojo.exists("foo.bal", this));
+				t.assertTrue(dojo.exists("foo.ban", this));
+				t.assertTrue(dojo.exists("foo.bam", this));
+				t.assertFalse(dojo.exists("foo.bat", this));
+				t.assertTrue(dojo.exists("a.b", { a:{ b:0 }}));
+				t.assertFalse(dojo.exists("foo.bar.baz.bam.bap", this));
+			}
+		},
+
+		function evalWorks(t){
+			t.assertTrue(dojo.eval("(true)"));
+			t.assertFalse(dojo.eval("(false)"));
+			if(!has("ie")){
+				// eval truly executes in global scope for non IE
+				t.is(window.rawld, undefined);
+				dojo.eval("var rawld = 3.14;");
+				t.assertEqual(rawld, 3.14);
+				t.assertEqual(window.rawld, 3.14);
+				window.rawld = undefined;
+			}else{
+				// example of how to compensate for IE
+				t.is(window.rawld, undefined);
+				dojo.eval("window.rawld = 3.14;");
+				t.assertEqual(rawld, 3.14);
+				t.assertEqual(window.rawld, 3.14);
+				window.rawld = undefined;
+			}
+		},
+
+		function _mixin(t){
+			var a = {
+				x: 1,
+				y: function(){ return 2; },
+				z1: 99,
+				w: 2,
+				v: undefined
+			};
+			var b = {
+				x: 11,
+				y: function(){ return 12; },
+				z2: 33,
+				toString: function(){ return "bark!"; },
+				toLocaleString: function(){ return "le bark-s!"; },
+				w: undefined,
+				v: undefined,
+				u: undefined
+			};
+			t.is(1, a.x);
+			t.is(2, a.y());
+			t.is(99, a.z1);
+			t.t("w" in a);
+			t.is(2, a.w);
+			t.t("v" in a);
+			t.is(undefined, a.v);
+			t.f("u" in a);
+			dojo._mixin(a, b);
+			t.is(11, a.x);
+			t.is(12, a.y());
+			t.is("bark!", a.toString());
+			t.is("le bark-s!", a.toLocaleString());
+			t.is(99, a.z1);
+			t.is(33, a.z2);
+			t.t("w" in a);
+			t.is(undefined, a.w);
+			t.t("v" in a);
+			t.is(undefined, a.v);
+			t.t("u" in a);
+			t.is(undefined, a.u);
+		}
+	]);
+});
diff --git a/dojo/tests/_base/loader/cdnTest.html b/dojo/tests/_base/loader/cdnTest.html
new file mode 100644
index 0000000..5a5abe8
--- /dev/null
+++ b/dojo/tests/_base/loader/cdnTest.html
@@ -0,0 +1,74 @@
+<html>
+<head>
+  <script src="../../../dojo.js"></script>
+  <script>
+	// dojo.i18n is always loaded as part of base on the xdomain build
+	dojo.require("dojo.i18n");
+
+    // now put the loader in xdomain mode; anything with amd will be detected to be xdomain
+	require.xdomainTest(function(name){
+		return /amd/.test(name);
+	});
+
+    // load the module that exercises all the load paths; keep a log of what happened
+	var dojoCdnTestLog= [];
+	dojo.require("dojo.tests._base.loader.cdnTest");
+	dojoCdnTestLog.push("after dojo.require(dojo.tests._base.loader.cdnTest)");
+	require(["dojo", "doh"], function(dojo, doh){
+		doh.register("cdn-test", [
+			function(t){
+				var expected= [
+					"loadInit in cdnTest",
+					"defining-dojo.tests._base.loader.amdModule1",
+					"defining-dojo.tests._base.loader.amdModuleDep1",
+					"in-dojo.tests._base.loader.syncModuleDep",
+					"out-dojo.tests._base.loader.syncModuleDep",
+					"in-dojo.tests._base.loader.syncModule",
+					"out-dojo.tests._base.loader.syncModule",
+					"after dojo.require(dojo.tests._base.loader.cdnTest)",
+					"defining-dojo.tests._base.loader.amdModule",
+					"defining-dojo.tests._base.loader.amdModuleDep",
+					"factory-dojo.tests._base.loader.amdModuleDep",
+					"factory-dojo.tests._base.loader.amdModule",
+					"in-dojo.tests._base.loader.cdnTest",
+					"in-dojo.tests._base.loader.syncModuleDep1",
+					"out-dojo.tests._base.loader.syncModuleDep1",
+					"in-dojo.tests._base.loader.syncModule1",
+					"out-dojo.tests._base.loader.syncModule1",
+					"factory-dojo.tests._base.loader.amdModuleDep1",
+					"factory-dojo.tests._base.loader.amdModule1",
+					"out-dojo.tests._base.loader.cdnTest"];
+				t.is(dojoCdnTestLog, expected);
+				t.is(dojo.tests._base.loader.syncModule.status, "OK");
+				t.is(dojo.tests._base.loader.syncModuleDep.status, "OK");
+				t.is(dojo.tests._base.loader.syncModule1.status, "OK");
+				t.is(dojo.tests._base.loader.syncModuleDep1.status, "OK");
+				t.is(require("dojo/tests/_base/loader/amdModule").status, "OK");
+				t.is(require("dojo/tests/_base/loader/amdModuleDep").status, "OK");
+				t.is(require("dojo/tests/_base/loader/amdModule1").status, "OK");
+				t.is(require("dojo/tests/_base/loader/amdModuleDep1").status, "OK");	
+
+				t.is(dojo.tests._base.loader.syncModule2, undefined);
+				t.is(dojo.tests._base.loader.syncModuleDep2, undefined);
+				t.is(require("dojo/tests/_base/loader/amdModule2"), undefined);
+				t.is(require("dojo/tests/_base/loader/amdModuleDep2"), undefined);
+				t.is(dojo.i18n.getLocalization("dojo.tests._base.loader", "syncBundle").syncBundle, "syncBundle");
+				t.is(dojo.i18n.getLocalization("dojo.tests._base.loader", "syncBundle", "ab-cd-ef").syncBundle, "syncBundle-ab-cd-ef");
+				t.is(dojo.i18n.getLocalization("dojo.tests._base.loader", "amdBundle").amdBundle, "amdBundle");
+				t.is(dojo.i18n.getLocalization("dojo.tests._base.loader", "amdBundle", "ab-cd-ef").amdBundle, "amdBundle-ab-cd-ef");
+			}
+		]);
+		doh.runOnLoad();
+		dojo.ready(function(){
+			dojo.byId("done").innerHTML= dojoCdnTestLog.join("<br>");
+
+		});
+
+
+	});
+  </script>
+</head>
+<body>
+  <div id="done"></div>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/cdnTest.js b/dojo/tests/_base/loader/cdnTest.js
new file mode 100644
index 0000000..706cdfe
--- /dev/null
+++ b/dojo/tests/_base/loader/cdnTest.js
@@ -0,0 +1,39 @@
+dojo.loadInit(function(){
+	// this function is evaluated first and only once
+	dojoCdnTestLog.push("loadInit in cdnTest");
+	// define a global variable
+	dojoCdnTest= 1;
+});
+
+dojoCdnTestLog.push("in-dojo.tests._base.loader.cdnTest");
+dojo.provide("dojo.tests._base.loader.cdnTest");
+dojo.provide("dojo.tests._base.loader.cdnTest2");
+dojo.tests._base.loader.cdnTest.status= "OK";
+dojo.tests._base.loader.cdnTest2.status= "OK";
+dojo.require("dojo.tests._base.loader.syncModule");
+dojo.require("dojo.tests._base.loader.amdModule");
+dojo.requireLocalization("dojo.tests._base.loader", "syncBundle", "ab-cd-ef");
+dojo.requireLocalization("dojo.tests._base.loader", "amdBundle", "ab-cd-ef");
+
+(function(){
+var t1= dojo.i18n.getLocalization("dojo.tests._base.loader", "syncBundle");
+var t2= dojo.i18n.getLocalization("dojo.tests._base.loader", "syncBundle", "ab-cd-ef");
+var t3= dojo.i18n.getLocalization("dojo.tests._base.loader", "amdBundle");
+var t4= dojo.i18n.getLocalization("dojo.tests._base.loader", "amdBundle", "ab-cd-ef");
+
+require(["doh"], function(doh){
+	doh.register("test-i18n-inline", function(t){
+		t.is(t1.syncBundle, "syncBundle");
+		t.is(t2.syncBundle, "syncBundle-ab-cd-ef");
+		t.is(t3.amdBundle, "amdBundle");
+		t.is(t4.amdBundle, "amdBundle-ab-cd-ef");
+	});
+});
+})();
+
+
+dojo.requireIf(dojoCdnTest==1, "dojo.tests._base.loader.syncModule1");
+dojo.requireAfterIf(dojoCdnTest==1, "dojo.tests._base.loader.amdModule1");
+dojo.requireIf(dojoCdnTest==2, "dojo.tests._base.loader.syncModule2");
+dojo.requireAfterIf(dojoCdnTest==2, "dojo.tests._base.loader.amdModule2");
+dojoCdnTestLog.push("out-dojo.tests._base.loader.cdnTest");
diff --git a/dojo/tests/_base/loader/config-has.html b/dojo/tests/_base/loader/config-has.html
new file mode 100644
index 0000000..179eada
--- /dev/null
+++ b/dojo/tests/_base/loader/config-has.html
@@ -0,0 +1,59 @@
+<html>
+<head>
+	<script type="text/javascript">
+		dojoConfig= {
+			someConfigSwitch:0,
+			isDebug:1,
+			has:{
+				"some-has-feature":5
+			}
+		}
+	</script>
+	<script type="text/javascript" src="../../../dojo.js" data-dojo-config="anotherConfigSwitch:2"></script>
+	<script type="text/javascript">
+		require(["doh", "dojo/has"], function(doh, has) {
+			doh.register("config-has", [
+				function check1(t) {
+					t.is(require.rawConfig.someConfigSwitch, 0);
+					t.is(require.rawConfig.isDebug, 1);
+					t.is(require.rawConfig.anotherConfigSwitch, 2);
+
+					t.is(has("config-someConfigSwitch"), 0);
+					t.is(has("config-isDebug"), 1);
+					t.is(has("config-anotherConfigSwitch"), 2);
+					t.is(has("some-has-feature"), 5);
+
+					// setting an existing config variable after boot does *not* affect the has cache
+					require({someConfigSwitch:3});
+					t.is(require.rawConfig.someConfigSwitch, 3);
+					t.is(has("config-someConfigSwitch"), 0);
+
+					// but, we can add new configfeatures any time
+					require({someNewConfigSwitch:4});
+					t.is(require.rawConfig.someNewConfigSwitch, 4);
+					t.is(has("config-someNewConfigSwitch"), 4);
+
+					// setting an existing has feature via config after boot does *not* affect the has cache
+					require({has:{"some-has-feature":6}});
+					t.is(has("some-has-feature"), 5);
+
+					// setting an existing has feature via has.add does *not* affect the has cache...
+					has.add("some-has-feature", 6);
+					t.is(has("some-has-feature"), 5);
+
+					// ...*unless* you use force...
+					has.add("some-has-feature", 6, 0, 1);
+					t.is(has("some-has-feature"), 6);
+
+					// but, we can add new has features any time
+					require({has:{"some-new-has-feature":7}});
+					t.is(has("some-new-has-feature"), 7);
+				}
+			]);
+			doh.runOnLoad();
+		});
+	</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/config-sniff-djConfig.html b/dojo/tests/_base/loader/config-sniff-djConfig.html
new file mode 100644
index 0000000..b99a745
--- /dev/null
+++ b/dojo/tests/_base/loader/config-sniff-djConfig.html
@@ -0,0 +1,50 @@
+<html>
+<head>
+    <!--
+		NOTE: this test is exactly the same as config-sniff except the attribute is renamed to djConfig
+	-->
+	<script type="text/javascript">
+		var hasAlias;
+		var dojoConfig= {
+			async:1,
+			waitSeconds:5
+		};
+	</script>
+	<script 
+		type="text/javascript" 
+		src="../../../dojo.js"
+		djConfig="isDebug:1, async:1, waitSeconds:6, baseUrl:'../../../../dojo', cats:'dojo-config-dogs', a:2, b:[3,4,5]"></script>
+	<script type="text/javascript">
+		require(["dojo", "doh", "dojo/has"], function(dojo, doh, has) {
+			dojo.ready(function() {
+				hasAlias= has;
+				doh.register("dojoConfig-sniff-test", [
+					function expectDojoConfig(t) {
+						// show that sniff overrides dojoConfig
+						t.is(require.rawConfig.async, true);
+						t.is(require.rawConfig.baseUrl, "../../../../dojo");
+						t.is(require.rawConfig.waitSeconds, 6);
+						t.is(require.rawConfig.cats, 'dojo-config-dogs');
+						t.is(require.rawConfig.a, 2);
+						t.is(require.rawConfig.b, [3,4,5]);
+
+						t.is(require.async, true);
+						t.is(require.baseUrl, "../../../../dojo/");
+						t.is(require.cats, undefined);
+						t.is(require.a, undefined);
+						t.is(require.b, undefined);
+
+						t.is(dojo.config.baseUrl, "../../../../dojo/");
+						t.is(dojo.config.cats, 'dojo-config-dogs');
+						t.is(dojo.config.a, 2);
+						t.is(dojo.config.b, [3,4,5]);			
+					}
+				]);
+				doh.runOnLoad();
+			});
+		});
+	</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/config-sniff.html b/dojo/tests/_base/loader/config-sniff.html
new file mode 100644
index 0000000..06b1244
--- /dev/null
+++ b/dojo/tests/_base/loader/config-sniff.html
@@ -0,0 +1,48 @@
+<html>
+<head>
+	<script type="text/javascript">
+		var hasAlias;
+		var dojoConfig= {
+			async:1,
+			waitSeconds:5
+		};
+	</script>
+	<script 
+		type="text/javascript" 
+		src="../../../dojo.js"
+		data-dojo-config="isDebug:1, async:1, waitSeconds:6, baseUrl:'../../../../dojo', cats:'dojo-config-dogs', a:2, b:[3,4,5]"></script>
+	<script type="text/javascript">
+		require(["dojo", "doh", "dojo/has"], function(dojo, doh, has) {
+			dojo.ready(function() {
+				hasAlias= has;
+				doh.register("dojoConfig-sniff-test", [
+					function expectDojoConfig(t) {
+						// show that sniff overrides dojoConfig
+						t.is(require.rawConfig.async, true);
+						t.is(require.rawConfig.baseUrl, "../../../../dojo");
+						t.is(require.rawConfig.waitSeconds, 6);
+						t.is(require.rawConfig.cats, 'dojo-config-dogs');
+						t.is(require.rawConfig.a, 2);
+						t.is(require.rawConfig.b, [3,4,5]);
+
+						t.is(require.async, true);
+						t.is(require.baseUrl, "../../../../dojo/");
+						t.is(require.cats, undefined);
+						t.is(require.a, undefined);
+						t.is(require.b, undefined);
+
+						t.is(dojo.config.baseUrl, "../../../../dojo/");
+						t.is(dojo.config.cats, 'dojo-config-dogs');
+						t.is(dojo.config.a, 2);
+						t.is(dojo.config.b, [3,4,5]);			
+					}
+				]);
+				doh.runOnLoad();
+			});
+		});
+	</script>
+</head>
+<body>
+</body>
+</html>
+
diff --git a/dojo/tests/_base/loader/config.html b/dojo/tests/_base/loader/config.html
new file mode 100644
index 0000000..d4fae3b
--- /dev/null
+++ b/dojo/tests/_base/loader/config.html
@@ -0,0 +1,156 @@
+<html>
+<head>
+	<script type="text/javascript">
+		var hasAlias, dojoAlias;
+		var _dojoConfig= {
+			baseUrl:"../../../../dojo",
+			waitSeconds:5,
+			locale:"us-en1",
+			has:{
+				configTestHas1:1
+			},
+			cats:'dojo-config-dogs',
+			a:2, 
+			b:[3,4,5]
+		};
+		function expectDojoConfig(t) {
+			t.is(require.rawConfig.baseUrl, "../../../../dojo");
+			t.is(require.rawConfig.waitSeconds, 5);
+			t.is(require.rawConfig.locale,"us-en1");
+			t.is(require.rawConfig.has, _dojoConfig.has);
+			t.is(require.rawConfig.cats, 'dojo-config-dogs');
+			t.is(require.rawConfig.a, 2);
+			t.is(require.rawConfig.b, [3,4,5]);
+
+			t.is(require.baseUrl, "../../../../dojo/");
+			t.t(hasAlias("configTestHas1"));
+			t.is(require.cats, undefined);
+			t.is(require.a, undefined);
+			t.is(require.b, undefined);
+
+			t.is(dojo.config.baseUrl, "../../../../dojo/");
+			t.is(dojo.config.waitSeconds, 5);
+			t.is(dojo.config.locale,"us-en1");
+			t.is(dojo.config.cats, 'dojo-config-dogs');
+			t.is(dojo.config.a, 2);
+			t.is(dojo.config.b, [3,4,5]);			
+		}
+
+		var _djConfig= {
+			baseUrl:"../../../../dojo",
+			waitSeconds:6,
+			locale:"us-en2",
+			has:{
+				configTestHas2:1
+			},
+			cats:'dj-config-dogs',
+			a:6, 
+			b:[7,8,9]
+		};
+		function expectDjConfig(t) {
+			t.is(require.rawConfig.baseUrl, "../../../../dojo");
+			t.is(require.rawConfig.waitSeconds, 6);
+			t.is(require.rawConfig.locale,"us-en2");
+			t.is(require.rawConfig.has, _djConfig.has);
+			t.is(require.rawConfig.cats, 'dj-config-dogs');
+			t.is(require.rawConfig.a, 6);
+			t.is(require.rawConfig.b, [7,8,9]);
+
+			t.is(require.baseUrl, "../../../../dojo/");
+			t.t(hasAlias("configTestHas2"));
+			t.is(require.cats, undefined);
+			t.is(require.a, undefined);
+			t.is(require.b, undefined);
+
+			t.is(dojo.config.baseUrl, "../../../../dojo/");
+			t.is(dojo.config.waitSeconds, 6);
+			t.is(dojo.config.locale,"us-en2");
+			t.is(dojo.config.cats, 'dj-config-dogs');
+			t.is(dojo.config.a, 6);
+			t.is(dojo.config.b, [7,8,9]);			
+		}
+
+		var _require= {
+			baseUrl:"../../../../dojo",
+			waitSeconds:7,
+			locale:"us-en3",
+			has:{
+				configTestHas3:1
+			},
+			cats:'require-config-dogs',
+			a:10, 
+			b:[11,12,13]
+		};
+		function expectRequireConfig(t) {
+			t.is(require.rawConfig.baseUrl, "../../../../dojo");
+			t.is(require.rawConfig.waitSeconds, 7);
+			t.is(require.rawConfig.locale,"us-en3");
+			t.is(require.rawConfig.has, _require.has);
+			t.is(require.rawConfig.cats, 'require-config-dogs');
+			t.is(require.rawConfig.a, 10);
+			t.is(require.rawConfig.b, [11,12,13]);
+
+			t.is(require.baseUrl, "../../../../dojo/");
+			t.t(hasAlias("configTestHas3"));
+			t.is(require.cats, undefined);
+			t.is(require.a, undefined);
+			t.is(require.b, undefined);
+
+			t.is(dojo.config.baseUrl, "../../../../dojo/");
+			t.is(dojo.config.waitSeconds, 7);
+			t.is(dojo.config.locale,"us-en3");
+			t.is(dojo.config.cats, 'require-config-dogs');
+			t.is(dojo.config.a, 10);
+			t.is(dojo.config.b, [11,12,13]);			
+		}
+		switch(location.search){
+			case "?dojoConfig-djConfig-require":
+				dojoConfig= _dojoConfig;
+				djConfig= _djConfig;
+				require= _require;
+				expect= expectDojoConfig;
+				break;
+			case "?dojoConfig-djConfig":
+				dojoConfig= _dojoConfig;
+				djConfig= _djConfig;
+				expect= expectDojoConfig;
+				break;
+			case "?dojoConfig-require":
+				dojoConfig= _dojoConfig;
+				require= _require;
+				expect= expectDojoConfig;
+				break;
+			case "?djConfig-require":
+				djConfig= _djConfig;
+				require= _require;
+				expect= expectDjConfig;
+				break;
+			case "?djConfig":
+				djConfig= _djConfig;
+				expect= expectDjConfig;
+				break;
+			case "?require":
+				require= _require;
+				expect= expectRequireConfig;
+				break;
+			case "?dojoConfig":
+				dojoConfig= _dojoConfig;
+				expect= expectDojoConfig;
+				break;
+		}
+	</script>
+	<script type="text/javascript" src="../../../dojo.js" data-dojo-config="isDebug:1, async:1"></script>
+	<script type="text/javascript">
+		require(["dojo", "doh", "dojo/has"], function(dojo, doh, has) {
+			dojo.ready(function() {
+				dojoAlias= dojo;
+				hasAlias= has;
+				doh.register("dojoConfig-test", [expect]);
+				doh.runOnLoad();
+			});
+		});
+	</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/configApi.html b/dojo/tests/_base/loader/configApi.html
new file mode 100644
index 0000000..7fa3063
--- /dev/null
+++ b/dojo/tests/_base/loader/configApi.html
@@ -0,0 +1,94 @@
+<html>
+<head>
+	<script type="text/javascript" src="../../../dojo.js" data-dojo-config="isDebug:1, async:1"></script>
+	<script type="text/javascript">
+		require(["dojo", "doh"], function(dojo, doh) {
+			dojo.ready(function(){
+				doh.register("config-event", [
+					function expectDojoConfig(t) {
+						var 
+							expectedConfig1, expectedConfig2,
+							called1, called2,
+							savedRawConfig,
+							configListener1= function(config, rawConfig){
+								called1= true;
+								savedRawConfig= rawConfig;
+								t.is(config, expectedConfig1);
+							},
+							configListener2= function(config, rawConfig){
+								called2= true;
+								savedRawConfig= rawConfig;
+								t.is(config, expectedConfig2);
+							};
+						var 
+							configListeners = require.listenerQueues.config;
+							listenerCount= configListeners.length,
+							h1= require.on("config", configListener1),
+							h2= require.on("config", configListener2);
+						t.is(configListeners.length, listenerCount+2);
+						t.is(configListeners[listenerCount], configListener1);
+						t.is(configListeners[listenerCount+1], configListener2);
+						expectedConfig1= expectedConfig2= {
+							someFeature:1
+						};						
+						called1= called2= 0;
+						require(expectedConfig1);
+						t.t(called1);
+						t.t(called2);
+
+						h1.remove();
+						t.is(configListeners.length, listenerCount+1);
+						t.is(configListeners[listenerCount], configListener2);
+						expectedConfig1= expectedConfig2= {
+							someFeature:0,
+							someOtherFeature:1
+						};						
+						called1= called2= 0;
+						require(expectedConfig1);
+						t.is(called1, 0);
+						t.t(called2);
+						t.is(savedRawConfig.someFeature, 0);
+						t.is(savedRawConfig.someOtherFeature, 1);
+						h2.remove();
+
+						require({async:1});
+						t.is(require.async, true);
+						t.is(require.legacyMode, false);
+
+						require({async:true});
+						t.is(require.async, true);
+						t.is(require.legacyMode, false);
+
+						require({async:2});
+						t.is(require.async, true);
+						t.is(require.legacyMode, false);
+
+						require({async:"nonsense"});
+						t.is(require.async, true);
+						t.is(require.legacyMode, false);
+
+						require({async:0});
+						t.is(require.async, false);
+						t.is(require.legacyMode, "sync");
+
+						require({async:false});
+						t.is(require.async, false);
+						t.is(require.legacyMode, "sync");
+
+						require({async:"sync"});
+						t.is(require.async, false);
+						t.is(require.legacyMode, "sync");
+
+						require({async:"legacyAsync"});
+						t.is(require.async, false);
+						t.is(require.legacyMode, "legacyAsync");
+					}
+				]);
+				doh.runOnLoad();
+			});
+		});
+	</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/coolio/calendar-amd.js b/dojo/tests/_base/loader/coolio/calendar-amd.js
new file mode 100644
index 0000000..47b6a07
--- /dev/null
+++ b/dojo/tests/_base/loader/coolio/calendar-amd.js
@@ -0,0 +1,7 @@
+define(["dojo", "dijit/Calendar"], function(dojo, calendar){
+	// a coolio/calendarAsync-created calendar will be created in the cdojo and cdijit instances
+	// but, during dev, this is a detail we can ignore...the config makes in just work
+	return function(id){
+		return new calendar({}, dojo.byId(id));
+	};
+});
diff --git a/dojo/tests/_base/loader/coolio/calendar.js b/dojo/tests/_base/loader/coolio/calendar.js
new file mode 100644
index 0000000..9645f46
--- /dev/null
+++ b/dojo/tests/_base/loader/coolio/calendar.js
@@ -0,0 +1,6 @@
+dojo.provide("coolio.calendar");
+dojo.require("dijit.Calendar");
+
+coolio.calendar= function(id){
+	return new dijit.Calendar({}, dojo.byId(id));
+};
diff --git a/dojo/tests/_base/loader/coolio/calendar1.js b/dojo/tests/_base/loader/coolio/calendar1.js
new file mode 100644
index 0000000..74fed9d
--- /dev/null
+++ b/dojo/tests/_base/loader/coolio/calendar1.js
@@ -0,0 +1,6 @@
+dojo.provide("coolio.calendar1");
+dojo.require("dijit.Calendar");
+
+coolio.calendar1= function(id){
+	return new dijit.Calendar({}, dojo.byId(id));
+};
diff --git a/dojo/tests/_base/loader/coolio/coolio-built.html b/dojo/tests/_base/loader/coolio/coolio-built.html
new file mode 100644
index 0000000..d977f9a
--- /dev/null
+++ b/dojo/tests/_base/loader/coolio/coolio-built.html
@@ -0,0 +1,60 @@
+<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 = {
+				async:/async/.test(location.search),
+				baseUrl:".",
+				packages:[{
+					name:"dojo",
+					location:"../coolioBuilt/dojo",
+				},{
+					name:"dijit",
+					location:"../coolioBuilt/dijit",
+				},{
+					name:"dojox",
+					location:"../coolioBuilt/dojox",
+				},{
+					name:"cdojo",
+					location:"../coolioBuilt/dojo",
+					packageMap:{dojo:"cdojo", dijit:"cdijit"}
+				},{
+					name:"cdijit",
+					location:"../coolioBuilt/dijit",
+					packageMap:{dojo:"cdojo", dijit:"cdijit"}
+			    },{
+					name:"coolio",
+					location:"../coolioBuilt/coolio",
+					packageMap:{dojo:"cdojo", dijit:"cdijit"}
+				}],
+			};
+		</script>
+		<script type="text/javascript" src="../coolioBuilt/dojo/dojo.js"></script>
+		<script type="text/javascript">
+			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(){
+					parser.parse();
+					calendar("c1");
+					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 ">
+		<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-async.html b/dojo/tests/_base/loader/coolio/coolio-dev-async.html
new file mode 100644
index 0000000..463bed5
--- /dev/null
+++ b/dojo/tests/_base/loader/coolio/coolio-dev-async.html
@@ -0,0 +1,70 @@
+<html>
+	<head>
+		<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/claro/claro.css" />
+
+		<!-- configure the loader to create two instance of dojo and dijit, the second instances relocated to cdojo and- cdijit, repsectively-->
+		<script type="text/javascript">
+			var startTime = (new Date()).getTime();
+			var dojoConfig = {
+				// this is an example of developing with AMD modules
+				async:1,
+
+				// 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",
+				},{
+					// 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 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"}
+			    },{
+					// 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>
+
+		<script type="text/javascript" src="../../../../dojo.js"></script>
+		<script type="text/javascript">
+			require(["coolio/calendar-amd", "dojo/parser", "dijit/Calendar", "dojo/domReady!"], function(calendar, parser){
+				calendar("c1");
+				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
new file mode 100644
index 0000000..13c004f
--- /dev/null
+++ b/dojo/tests/_base/loader/coolio/coolio-dev-legacy-async.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 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"}
+			    },{
+					// 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 loadn 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.html b/dojo/tests/_base/loader/coolio/coolio-dev-legacy.html
new file mode 100644
index 0000000..77862fe
--- /dev/null
+++ b/dojo/tests/_base/loader/coolio/coolio-dev-legacy.html
@@ -0,0 +1,46 @@
+<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 = {
+				// 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",
+			    },{
+					name:"coolio",
+					location:"."
+				}]
+			};
+		</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("dijit.Calendar");
+			dojo.require("dojo.parser");
+			dojo.require("coolio.calendar");
+			dojo.ready(function(){
+				coolio.calendar("c1");
+				dojo.parser.parse();
+				console.log("total load time: " + ((new Date()).getTime() - startTime) / 1000 + "s");
+			});
+		</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.js b/dojo/tests/_base/loader/coolio/coolio.js
new file mode 100644
index 0000000..d7de313
--- /dev/null
+++ b/dojo/tests/_base/loader/coolio/coolio.js
@@ -0,0 +1,17 @@
+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
new file mode 100644
index 0000000..f57e005
--- /dev/null
+++ b/dojo/tests/_base/loader/coolio/coolio.profile.js
@@ -0,0 +1,34 @@
+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"
+			]
+		},{
+			customBase:1,
+			name: "main.js"
+		},{
+			name: "../dijit/Calendar.js",
+			dependencies: [
+				"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
new file mode 100644
index 0000000..14b1880
--- /dev/null
+++ b/dojo/tests/_base/loader/coolio/test.html
@@ -0,0 +1,45 @@
+<html>
+	<head>
+	</head>
+	<body>
+		<h1>Relocating Demonstrations</h1>
+		<p>(AKA multi-version support or rescoping)</p>
+
+		<h3><a href="coolio-dev-legacy.html">Developing a component with the legacy API</a></h3>
+		<p>Just develop as if you have full control and ownership over the dojo and dijit on the
+		page. Later, the component can be built into a distributable package that includes its own, private instance of dojo
+		and dijit (see below).</p>
+
+		<h3><a href="coolio-dev-async.html">Developing a component with the AMD API</a></h3>
+		<p>Again, just develop as if you have full control and ownership over the dojo and dijit on the
+		page. But with the AMD API you can set up your dev environment so that you actually have multiple instances of
+		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-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
+		and dijit (or any other module trees) on the page while developing--no build require. Notice the console
+		when you load this example: multiple instance, but it's the slowest of the bunch.</p>
+		<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>
+
+		<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
+		anticipates relocating dojo and dijit (the builder needs to know which modules may be relocated when it converts
+		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
+		</pre>
+		<p> There are four demonstrations of the built code<p>
+		<p><b>Remember to do a build before you try these!</b></p>
+		<ul>
+		  <li>The <a href="coolio-built.html?">coolio calendar</a> as a built-AMD module loaded in <b>synchronous legacy</b> mode.</a></li>
+		  <li>The <a href="coolio-built.html?async">coolio calendar</a> as a built-AMD module loaded in <b>AMD</b> mode.</a></li>
+		  <li>The <a href="coolio-built.html?legacy">coolio calendar</a> as a built-legacy module loaded in <b>synchronous legacy</b> mode.</a></li>
+		  <li>The <a href="coolio-built.html?legacy,async">coolio calendar</a> as a built-legacy module loaded in <b>AMD</b> mode.</a></li>
+		 </ul>
+	</body>
+</html>
diff --git a/dojo/tests/_base/loader/core.js b/dojo/tests/_base/loader/core.js
new file mode 100644
index 0000000..cea3b8b
--- /dev/null
+++ b/dojo/tests/_base/loader/core.js
@@ -0,0 +1,18 @@
+define(["doh"], function(doh){
+	doh.register("dojo.tests._base._loader.internals", [
+		function compactPath(t){
+			var compactPath = require.compactPath;
+			t.is(compactPath("../../dojo/../../mytests"), "../../../mytests");
+			t.is(compactPath("module"), "module");
+			t.is(compactPath("a/./b"), "a/b");
+			t.is(compactPath("a/../b"), "b");
+			t.is(compactPath("a/./b/./c/./d"), "a/b/c/d");
+			t.is(compactPath("a/../b/../c/../d"), "d");
+			t.is(compactPath("a/b/c/../../d"), "a/d");
+			t.is(compactPath("a/b/c/././d"), "a/b/c/d");
+			t.is(compactPath("./a/b"), "a/b");
+			t.is(compactPath("../a/b"), "../a/b");
+			t.is(compactPath(""), "");
+		}
+	]);
+});
diff --git a/dojo/tests/_base/loader/debugConsole.html b/dojo/tests/_base/loader/debugConsole.html
new file mode 100644
index 0000000..7b7995c
--- /dev/null
+++ b/dojo/tests/_base/loader/debugConsole.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>testing debugging and logging functions</title>
+		<script type="text/javascript">
+			djConfig = {};
+			djConfig.isDebug = document.location.href.match(/\?ON/);
+		</script>
+		<script type="text/javascript" src="../../../dojo.js"></script>
+		<script type="text/javascript">
+			dojo.addOnLoad(function(){
+				var toggle = document.getElementById("toggle").innerHTML = djConfig.isDebug?"ON":"OFF";
+			});
+			
+			var aString = "this is my test string";
+			var anObject = {
+				aProperty: "aValue",
+				anotherProperty: "anotherValue",
+				aNumber: 1234
+			};
+			
+			var cn = ["debug","log",
+				"assert", "count", "dir", "dirxml", "error", "group",
+				"groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
+				"trace", "warn"
+			];
+			for(var i=0;i<cn.length;i++) {
+				console[cn[i]]( cn[i] + ": " + aString);
+				console[cn[i]]( cn[i] + ": " + anObject);
+			}
+		</script>
+	</head>
+	<body>
+		<p>
+			Testing console.* methods with djConfig.isDebug turned <span id="toggle"></span>
+		</p>
+		<p>
+			Append '?ON' to URL to try with djConfig.isDebug turned ON. Remove it to test djConfig.isDebug turned OFF
+		</p>
+		<p>
+			If isDebug is off (false), then make sure console functions go to a simple empty function. You may see 
+			errors in the console, since console.error is being tested as part of this test.
+		</p>
+	</body>
+</html>
+
diff --git a/dojo/tests/_base/loader/declareStepsOnProvide.html b/dojo/tests/_base/loader/declareStepsOnProvide.html
new file mode 100644
index 0000000..1d43c5d
--- /dev/null
+++ b/dojo/tests/_base/loader/declareStepsOnProvide.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+	<script type="text/javascript" src="../../../dojo.js"></script>
+	<script type="text/javascript">
+		require(["dojo", "doh", "dojo/tests/_base/loader/declareStepsOnProvideAmd"], 
+			function(dojo, doh, declareStepsOnProvide, declareStepsOnProvide1) {
+			doh.register("loader.declareStepsOnProvide", function(t){
+				var instance= new declareStepsOnProvide();
+				t.is(instance.status(), "OK");
+				// requiring dojo/tests/_base/loader/declareStepsOnProvideAmd caused
+				// dojo/tests/_base/loader/declareStepsOnProvide to load which loaded *two* modules 
+				// and dojo.declare stepped on both of them
+				var instance= new (require("dojo/tests/_base/loader/declareStepsOnProvide1"))();
+				t.is(instance.status(), "OK-1");
+			});
+			doh.runOnLoad();
+		});
+	</script>
+</head>
+<body>
+  <h1>check console</h1>
+  <p>This tests a legacy module that has two dojo.provides and both are stepped on by dojo.declare.</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/declareStepsOnProvide.js b/dojo/tests/_base/loader/declareStepsOnProvide.js
new file mode 100644
index 0000000..fbbd885
--- /dev/null
+++ b/dojo/tests/_base/loader/declareStepsOnProvide.js
@@ -0,0 +1,14 @@
+dojo.provide("dojo.tests._base.loader.declareStepsOnProvide");
+dojo.provide("dojo.tests._base.loader.declareStepsOnProvide1");
+
+dojo.declare("dojo.tests._base.loader.declareStepsOnProvide", [], {
+	status:function(){
+		return "OK";
+	}
+});
+
+dojo.declare("dojo.tests._base.loader.declareStepsOnProvide1", [], {
+	status:function(){
+		return "OK-1";
+	}
+});
diff --git a/dojo/tests/_base/loader/declareStepsOnProvideAmd.js b/dojo/tests/_base/loader/declareStepsOnProvideAmd.js
new file mode 100644
index 0000000..ecce602
--- /dev/null
+++ b/dojo/tests/_base/loader/declareStepsOnProvideAmd.js
@@ -0,0 +1,3 @@
+define(["./declareStepsOnProvide"], function(result){
+	return result;
+});
diff --git a/dojo/tests/_base/_loader/fastbackTest.html b/dojo/tests/_base/loader/fastbackTest.html
similarity index 100%
rename from dojo/tests/_base/_loader/fastbackTest.html
rename to dojo/tests/_base/loader/fastbackTest.html
diff --git a/dojo/tests/_base/_loader/getText.txt b/dojo/tests/_base/loader/getText.txt
similarity index 100%
rename from dojo/tests/_base/_loader/getText.txt
rename to dojo/tests/_base/loader/getText.txt
diff --git a/dojo/tests/_base/loader/hostenv_rhino.js b/dojo/tests/_base/loader/hostenv_rhino.js
new file mode 100644
index 0000000..37377c6
--- /dev/null
+++ b/dojo/tests/_base/loader/hostenv_rhino.js
@@ -0,0 +1,13 @@
+dojo.provide("dojo.tests._base._loader.hostenv_rhino");
+
+tests.register("tests._base._loader.hostenv_rhino",
+	[
+		function getText(t){
+			var filePath = dojo.moduleUrl("tests._base._loader", "getText.txt");
+			var text = (new String(readText(filePath)));
+			//The Java file read seems to add a line return.
+			text = text.replace(/[\r\n]+$/, "");
+			t.assertEqual("dojo._getText() test data", text);
+		}
+	]
+);
diff --git a/dojo/tests/_base/loader/hostenv_spidermonkey.js b/dojo/tests/_base/loader/hostenv_spidermonkey.js
new file mode 100644
index 0000000..8ff7670
--- /dev/null
+++ b/dojo/tests/_base/loader/hostenv_spidermonkey.js
@@ -0,0 +1,11 @@
+dojo.provide("dojo.tests._base._loader.hostenv_spidermonkey");
+
+tests.register("tests._base._loader.hostenv_spidermonkey",
+	[
+		function getText(t){
+			var filePath = dojo.moduleUrl("tests._base._loader", "getText.txt");
+			var text = readText(filePath);
+			t.assertEqual("dojo._getText() test data", text);
+		}
+	]
+);
diff --git a/dojo/tests/_base/loader/moduleIds.js b/dojo/tests/_base/loader/moduleIds.js
new file mode 100644
index 0000000..52cd2a6
--- /dev/null
+++ b/dojo/tests/_base/loader/moduleIds.js
@@ -0,0 +1,210 @@
+define(["doh", "dojo", "dojo/_base/url"], function(doh, dojo){
+
+	var compactPath = function(path){
+		var
+			result= [],
+			segment, lastSegment;
+	    path= path.split("/");
+		while(path.length){
+			segment= path.shift();
+			if(segment==".." && result.length && lastSegment!=".."){
+				result.pop();
+			}else if(segment!="."){
+				result.push(lastSegment= segment);
+			} // else ignore "."
+		}
+		return result.join("/");
+	};
+
+	doh.register("dojo.tests._base._loader.modulesIds", [
+		function compactPath(t){
+			var compactPath = require.compactPath;
+			t.is(compactPath("../../dojo/../../mytests"), "../../../mytests");
+			t.is(compactPath("module"), "module");
+			t.is(compactPath("a/./b"), "a/b");
+			t.is(compactPath("a/../b"), "b");
+			t.is(compactPath("a/./b/./c/./d"), "a/b/c/d");
+			t.is(compactPath("a/../b/../c/../d"), "d");
+			t.is(compactPath("a/b/c/../../d"), "a/d");
+			t.is(compactPath("a/b/c/././d"), "a/b/c/d");
+			t.is(compactPath("./a/b"), "a/b");
+			t.is(compactPath("../a/b"), "../a/b");
+			t.is(compactPath(""), "");
+		},
+
+		function testModuleIds(t){
+			require({
+				packages:[{
+					// canonical...
+					name:"pack1",
+					location:"../packages/pack1Root"
+				}, {
+					// nonstandard main
+					name:"pack2",
+					main:"pack2Main",
+					location:"/pack2Root"
+				}, {
+					// nonstandard main
+					name:"pack3",
+					main:"public/main",
+					location:"/pack3Root"
+				}]
+			});
+
+			function get(mid, refmod){
+				return require.getModuleInfo(mid, refmod, require.packs, require.modules, "../../dojo/", require.packageMapProg, require.pathsMapProg, 1);
+			}
+
+			function check(result, expectedPid, expectedMidSansPid, expectedUrl){
+				t.is(result.pid, expectedPid);
+				t.is(result.mid, expectedPid + "/" + expectedMidSansPid);
+				t.is(result.url, expectedUrl + ".js");
+			}
+
+            // non-relative module id resolution...
+
+			var pack1Root= "../../packages/pack1Root/";
+
+			// the various mains...
+			check(get("pack1"), "pack1", "main", pack1Root + "main");
+			check(get("pack2"), "pack2", "pack2Main", "/pack2Root/pack2Main");
+			check(get("pack3"), "pack3", "public/main", "/pack3Root/public/main");
+
+			// modules...
+			check(get("pack1/myModule"), "pack1", "myModule", pack1Root + "myModule");
+			check(get("pack2/myModule"), "pack2", "myModule", "/pack2Root/myModule");
+			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};
+			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};
+			check(get(".", refmod), "pack1", "sub", pack1Root + "sub");
+			check(get("./myModule", refmod), "pack1", "sub/myModule", pack1Root + "sub/myModule");
+			check(get("..", refmod), "pack1", "main", pack1Root + "main");
+			check(get("../myModule", refmod), "pack1", "myModule", pack1Root + "myModule");
+			check(get("../util/myModule", refmod), "pack1", "util/myModule", pack1Root + "util/myModule");
+		},
+
+		function baseUrl(t){
+			var originalBaseUrl = dojo.config["baseUrl"] || "./";
+
+			t.assertEqual(originalBaseUrl, dojo.baseUrl);
+		},
+
+		function moduleUrl(t){
+			var expected = require.toUrl("dojo/tests/myTest.html");
+			t.is(null, dojo.moduleUrl());
+			t.is(null, dojo.moduleUrl(null));
+			t.is(null, dojo.moduleUrl(null, "myTest.html"));
+			// note we expect a trailing slash
+			t.is(expected.substring(0, expected.length - 11), dojo.moduleUrl("dojo.tests"));
+			t.is(expected, dojo.moduleUrl("dojo.tests", "myTest.html"));
+		},
+
+		function modulePaths(t){
+			dojo.registerModulePath("mycoolmod", "../some/path/mycoolpath");
+			dojo.registerModulePath("mycoolmod.widget", "http://some.domain.com/another/path/mycoolpath/widget");
+
+			t.assertEqual(compactPath(require.baseUrl + "../some/path/mycoolpath/util/"), dojo.moduleUrl("mycoolmod.util"));
+			t.assertEqual("http://some.domain.com/another/path/mycoolpath/widget/", dojo.moduleUrl("mycoolmod.widget"));
+			t.assertEqual("http://some.domain.com/another/path/mycoolpath/widget/thingy/", dojo.moduleUrl("mycoolmod.widget.thingy"));
+		},
+
+		function moduleUrls(t){
+			dojo.registerModulePath("mycoolmod", "some/path/mycoolpath");
+			dojo.registerModulePath("mycoolmod2", "/some/path/mycoolpath2");
+			dojo.registerModulePath("mycoolmod.widget", "http://some.domain.com/another/path/mycoolpath/widget");
+			dojo.registerModulePath("ipv4.widget", "http://ipv4user:ipv4passwd@some.domain.com:2357/another/path/ipv4/widget");
+			dojo.registerModulePath("ipv6.widget", "ftp://ipv6user:ipv6passwd@[::2001:0db8:3c4d:0015:0:0:abcd:ef12]:1113/another/path/ipv6/widget");
+			dojo.registerModulePath("ipv6.widget2", "https://[0:0:0:0:0:1]/another/path/ipv6/widget2");
+
+
+			var basePrefix = require.baseUrl;
+
+			t.assertEqual(compactPath(basePrefix + "some/path/mycoolpath/my/favorite.html"),
+				dojo.moduleUrl("mycoolmod", "my/favorite.html"));
+			t.assertEqual(compactPath(basePrefix + "some/path/mycoolpath/my/favorite.html"),
+				dojo.moduleUrl("mycoolmod.my", "favorite.html"));
+
+			t.assertEqual("/some/path/mycoolpath2/my/favorite.html",
+				dojo.moduleUrl("mycoolmod2", "my/favorite.html"));
+			t.assertEqual("/some/path/mycoolpath2/my/favorite.html",
+				dojo.moduleUrl("mycoolmod2.my", "favorite.html"));
+
+			t.assertEqual("http://some.domain.com/another/path/mycoolpath/widget/my/favorite.html",
+				dojo.moduleUrl("mycoolmod.widget", "my/favorite.html"));
+			t.assertEqual("http://some.domain.com/another/path/mycoolpath/widget/my/favorite.html",
+				dojo.moduleUrl("mycoolmod.widget.my", "favorite.html"));
+
+			// individual component testing
+			t.assertEqual("http://ipv4user:ipv4passwd@some.domain.com:2357/another/path/ipv4/widget/components.html",
+				(new dojo._Url(dojo.moduleUrl("ipv4.widget", "components.html"))).uri);
+			t.assertEqual("http",
+				(new dojo._Url(dojo.moduleUrl("ipv4.widget", "components.html"))).scheme);
+			t.assertEqual("ipv4user:ipv4passwd at some.domain.com:2357",
+				(new dojo._Url(dojo.moduleUrl("ipv4.widget", "components.html"))).authority);
+			t.assertEqual("ipv4user",
+				(new dojo._Url(dojo.moduleUrl("ipv4.widget", "components.html"))).user);
+			t.assertEqual("ipv4passwd",
+				(new dojo._Url(dojo.moduleUrl("ipv4.widget", "components.html"))).password);
+			t.assertEqual("some.domain.com",
+				(new dojo._Url(dojo.moduleUrl("ipv4.widget", "components.html"))).host);
+			t.assertEqual("2357",
+				(new dojo._Url(dojo.moduleUrl("ipv4.widget", "components.html"))).port);
+			t.assertEqual("/another/path/ipv4/widget/components.html",
+				(new dojo._Url(dojo.moduleUrl("ipv4.widget", "components.html?query"))).path);
+			t.assertEqual("q=somequery",
+				(new dojo._Url(dojo.moduleUrl("ipv4.widget", "components.html?q=somequery"))).query);
+			t.assertEqual("fragment",
+				(new dojo._Url(dojo.moduleUrl("ipv4.widget", "components.html#fragment"))).fragment);
+
+			t.assertEqual("ftp://ipv6user:ipv6passwd@[::2001:0db8:3c4d:0015:0:0:abcd:ef12]:1113/another/path/ipv6/widget/components.html",
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget", "components.html"))).uri);
+			t.assertEqual("ftp",
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget", "components.html"))).scheme);
+			t.assertEqual("ipv6user:ipv6passwd@[::2001:0db8:3c4d:0015:0:0:abcd:ef12]:1113",
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget", "components.html"))).authority);
+			t.assertEqual("ipv6user",
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget", "components.html"))).user);
+			t.assertEqual("ipv6passwd",
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget", "components.html"))).password);
+			t.assertEqual("::2001:0db8:3c4d:0015:0:0:abcd:ef12",
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget", "components.html"))).host);
+			t.assertEqual("1113",
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget", "components.html"))).port);
+			t.assertEqual("/another/path/ipv6/widget/components.html",
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget", "components.html?query"))).path);
+			t.assertEqual("somequery",
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget", "components.html?somequery"))).query);
+			t.assertEqual("somefragment",
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget", "components.html?somequery#somefragment"))).fragment);
+
+			t.assertEqual("https://[0:0:0:0:0:1]/another/path/ipv6/widget2/components.html",
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget2", "components.html"))).uri);
+			t.assertEqual("https",
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget2", "components.html"))).scheme);
+			t.assertEqual("[0:0:0:0:0:1]",
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget2", "components.html"))).authority);
+			t.assertEqual(null,
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget2", "components.html"))).user);
+			t.assertEqual(null,
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget2", "components.html"))).password);
+			t.assertEqual("0:0:0:0:0:1",
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget2", "components.html"))).host);
+			t.assertEqual(null,
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget2", "components.html"))).port);
+			t.assertEqual("/another/path/ipv6/widget2/components.html",
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget2", "components.html"))).path);
+			t.assertEqual(null,
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget2", "components.html"))).query);
+			t.assertEqual(null,
+				(new dojo._Url(dojo.moduleUrl("ipv6.widget2", "components.html"))).fragment);
+		}
+	]);
+});
+
diff --git a/dojo/tests/_base/loader/modulePaths.html b/dojo/tests/_base/loader/modulePaths.html
new file mode 100644
index 0000000..26f8c9f
--- /dev/null
+++ b/dojo/tests/_base/loader/modulePaths.html
@@ -0,0 +1,37 @@
+<html>
+<head>
+	<script>
+		var dojoConfig= {
+			modulePaths: {
+				"foo":"../foo/bar",
+				"abs":"http://myHost/myPath",
+				"some.multiSegment.path":"../someOther/path"
+			}
+		};
+	</script>
+	<script type="text/javascript" src="../../../dojo.js"></script>
+	<script type="text/javascript">
+		// TODO: make these DOH tests and add to unit test modules
+		require(["dojo"], function(dojo) {
+			console.log(dojo.moduleUrl("notFoo")+"");
+			console.log(dojo.moduleUrl("notFoo/someModule")+"");
+			console.log(dojo.moduleUrl("foo")+"");
+			console.log(dojo.moduleUrl("foo/someModule")+"");
+			console.log(dojo.moduleUrl("abs")+"");
+			console.log(dojo.moduleUrl("abs/someModule")+"");
+			console.log(dojo.moduleUrl("some/multiSegment/notPath")+"");
+			console.log(dojo.moduleUrl("some/multiSegment/path")+"");
+			console.log(dojo.moduleUrl("some/multiSegment/path/someModule")+"");
+
+			dojo.registerModulePath("foo", "./foo2/bar");
+			dojo.registerModulePath("yet/another/foo", "./yetAnotherFoo");
+			console.log(dojo.moduleUrl("foo")+"");
+			console.log(dojo.moduleUrl("foo/someModule")+"");
+			console.log(dojo.moduleUrl("yet/another/foo")+"");
+			console.log(dojo.moduleUrl("yet/another/foo/someModule")+"");
+		});
+	</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/modules.js b/dojo/tests/_base/loader/modules.js
new file mode 100644
index 0000000..108ffa3
--- /dev/null
+++ b/dojo/tests/_base/loader/modules.js
@@ -0,0 +1,24 @@
+define([
+	"doh",
+	"dojo",
+	"require",
+	"./modules/anon",
+	"./modules/wrapped",
+	"dojo/tests/_base/loader/modules/full",
+	"./modules/data",
+	"./modules/factoryArity"], function(doh, dojo, require, anon, wrapped){
+
+	doh.register("dojo.tests._base._loader.modules", [
+		function testAMD(t){
+			// test AMD module API
+			t.is(anon.theAnswer, 42);
+			t.is(require('./modules/anon').five, 5);
+			t.is(wrapped.five, 5);
+			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);
+		}
+	]);
+});
+
diff --git a/dojo/tests/_base/_loader/modules/anon.js b/dojo/tests/_base/loader/modules/anon.js
similarity index 100%
rename from dojo/tests/_base/_loader/modules/anon.js
rename to dojo/tests/_base/loader/modules/anon.js
diff --git a/dojo/tests/_base/_loader/modules/data.js b/dojo/tests/_base/loader/modules/data.js
similarity index 100%
rename from dojo/tests/_base/_loader/modules/data.js
rename to dojo/tests/_base/loader/modules/data.js
diff --git a/dojo/tests/_base/_loader/modules/factoryArity.js b/dojo/tests/_base/loader/modules/factoryArity.js
similarity index 100%
rename from dojo/tests/_base/_loader/modules/factoryArity.js
rename to dojo/tests/_base/loader/modules/factoryArity.js
diff --git a/dojo/tests/_base/loader/modules/full.js b/dojo/tests/_base/loader/modules/full.js
new file mode 100644
index 0000000..1263724
--- /dev/null
+++ b/dojo/tests/_base/loader/modules/full.js
@@ -0,0 +1,5 @@
+define("dojo/tests/_base/loader/modules/full", ["./anon", "../a", "./wrapped", "require"], function (anon, a, wrapped, require) {
+	return {
+		twiceTheAnswer: a.number + require("../a").number
+	};
+});
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/modules/wrapped.js b/dojo/tests/_base/loader/modules/wrapped.js
new file mode 100644
index 0000000..a98c602
--- /dev/null
+++ b/dojo/tests/_base/loader/modules/wrapped.js
@@ -0,0 +1,15 @@
+if(require.has("dojo-amd-factory-scan")){
+
+define(function (require, exports, module) {
+	exports.five = require("./data").five;
+	exports.exports = module.exports;
+});
+
+}else{
+
+define(["require", "exports", "module"], function (require, exports, module) {
+	exports.five = require("./data").five;
+	exports.exports = module.exports;
+});
+
+}
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/myTopLevelModule.js b/dojo/tests/_base/loader/myTopLevelModule.js
new file mode 100644
index 0000000..46c1bcb
--- /dev/null
+++ b/dojo/tests/_base/loader/myTopLevelModule.js
@@ -0,0 +1,3 @@
+dojo.provide("myTopLevelModule");
+dojo.require("myTopLevelModule.myModule");
+myTopLevelModule.name= "myTopLevelModule";
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/myTopLevelModule/myModule.js b/dojo/tests/_base/loader/myTopLevelModule/myModule.js
new file mode 100644
index 0000000..66d69e5
--- /dev/null
+++ b/dojo/tests/_base/loader/myTopLevelModule/myModule.js
@@ -0,0 +1,2 @@
+dojo.provide("myTopLevelModule.myModule");
+myTopLevelModule.myModule.name= "myTopLevelModule.myModule";
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/nls/ab-cd-ef/amdBundle.js b/dojo/tests/_base/loader/nls/ab-cd-ef/amdBundle.js
new file mode 100644
index 0000000..3b24dfe
--- /dev/null
+++ b/dojo/tests/_base/loader/nls/ab-cd-ef/amdBundle.js
@@ -0,0 +1,3 @@
+define({
+	amdBundle:"amdBundle-ab-cd-ef"
+});
diff --git a/dojo/tests/_base/loader/nls/ab-cd-ef/syncBundle.js b/dojo/tests/_base/loader/nls/ab-cd-ef/syncBundle.js
new file mode 100644
index 0000000..90efbe3
--- /dev/null
+++ b/dojo/tests/_base/loader/nls/ab-cd-ef/syncBundle.js
@@ -0,0 +1,3 @@
+({
+	syncBundle:"syncBundle-ab-cd-ef"
+})
diff --git a/dojo/tests/_base/loader/nls/ab/amdBundle.js b/dojo/tests/_base/loader/nls/ab/amdBundle.js
new file mode 100644
index 0000000..2d7b704
--- /dev/null
+++ b/dojo/tests/_base/loader/nls/ab/amdBundle.js
@@ -0,0 +1,3 @@
+define({
+	amdBundle:"amdBundle-ab"
+});
diff --git a/dojo/tests/_base/loader/nls/ab/syncBundle.js b/dojo/tests/_base/loader/nls/ab/syncBundle.js
new file mode 100644
index 0000000..94f4dd8
--- /dev/null
+++ b/dojo/tests/_base/loader/nls/ab/syncBundle.js
@@ -0,0 +1,3 @@
+({
+	syncBundle:"syncBundle-ab"
+})
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/nls/amdBundle.js b/dojo/tests/_base/loader/nls/amdBundle.js
new file mode 100644
index 0000000..c1a15e4
--- /dev/null
+++ b/dojo/tests/_base/loader/nls/amdBundle.js
@@ -0,0 +1,7 @@
+define({
+	root:{
+		amdBundle:"amdBundle"
+	},
+	ab:1,
+	"ab-cd-ef":1
+});
diff --git a/dojo/tests/_base/loader/nls/syncBundle.js b/dojo/tests/_base/loader/nls/syncBundle.js
new file mode 100644
index 0000000..6d13173
--- /dev/null
+++ b/dojo/tests/_base/loader/nls/syncBundle.js
@@ -0,0 +1,3 @@
+({
+	syncBundle:"syncBundle"
+})
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/package.html b/dojo/tests/_base/loader/package.html
new file mode 100644
index 0000000..8b53637
--- /dev/null
+++ b/dojo/tests/_base/loader/package.html
@@ -0,0 +1,11 @@
+<html>
+<head>
+	<script type="text/javascript" src="../../../dojo.js" djConfig='async:1'></script>
+	<script type="text/javascript">
+		require({"packages":[{"name":"pkg","location":"/pkg", "lib":"lib", "main":"./lib/main"}]});
+		require(["pkg"]);
+	</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/paths.html b/dojo/tests/_base/loader/paths.html
new file mode 100644
index 0000000..c71ae92
--- /dev/null
+++ b/dojo/tests/_base/loader/paths.html
@@ -0,0 +1,52 @@
+<html>
+<head>
+	<script type="text/javascript" src="../../../dojo.js"></script>
+	<script type="text/javascript">
+	    var myModule1Value = {}, myModule2Value = {};
+		define("myModule1", [], myModule1Value);
+		define("myModule2", [], myModule2Value);
+		require({
+			aliases:[
+				// yourModule --> myModule1
+				["yourModule", "myModule1"],
+	
+				// yourOtherModule --> myModule1						
+				[/yourOtherModule/, "myModule1"],
+	
+				// yourModule/*/special --> yourModule/common/special
+				// this will result in a resubmission to finally resolve in the next one
+				[/yourOtherModule\/([^\/]+)\/special/, "yourOtherModule/common/special"],
+	
+				// yourModule/common/special --> myModule2
+				// notice the regex above also finds yourOtherModule/common/special; 
+				// the extra parenthesized subexprs make this have priority
+				[/(yourOtherModule\/(common))\/special/, "myModule2"]
+			],
+			paths:{myTopLevelModule:"./tests/_base/loader/myTopLevelModule"}							   
+		});
+			
+
+		require(["myTopLevelModule", "doh", "myModule1", "myModule2", "yourModule", "yourOtherModule", "yourOtherModule/stuff/special"],
+			function(myModule, doh, myModule1, myModule2, myModule1_1, myModule1_2, myModule2_1){
+			doh.register("aliases", [
+				function(t){
+					t.is(myModule1Value, myModule1);
+					t.is(myModule1Value, myModule1_1);
+					t.is(myModule1Value, myModule1_2);
+					t.is(myModule2Value, myModule2);
+					t.is(myModule2Value, myModule2_1);
+				}
+			]);
+			doh.register("top-level-module-via-paths", [
+				function(t){
+					t.is(myTopLevelModule.name, "myTopLevelModule");
+					t.is(myTopLevelModule.myModule.name, "myTopLevelModule.myModule");
+				}
+			]);
+			doh.runOnLoad();
+		});
+	</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/pub1.js b/dojo/tests/_base/loader/pub1.js
new file mode 100644
index 0000000..3ed06ca
--- /dev/null
+++ b/dojo/tests/_base/loader/pub1.js
@@ -0,0 +1,3 @@
+define([], function(){
+  return {status:"ok"};
+});
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/pub2.js b/dojo/tests/_base/loader/pub2.js
new file mode 100644
index 0000000..3ed06ca
--- /dev/null
+++ b/dojo/tests/_base/loader/pub2.js
@@ -0,0 +1,3 @@
+define([], function(){
+  return {status:"ok"};
+});
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/publishRequireResult.html b/dojo/tests/_base/loader/publishRequireResult.html
new file mode 100644
index 0000000..ac3601e
--- /dev/null
+++ b/dojo/tests/_base/loader/publishRequireResult.html
@@ -0,0 +1,34 @@
+<html>
+<head>
+	<script type="text/javascript">
+		var publishing= location.query!="?do-not-publish";
+		if(!publishing){
+			var dojoConfig = {
+				publishRequireResult:0
+			}
+		}
+	</script>
+	<script type="text/javascript" src="../../../dojo.js"></script>
+	<script type="text/javascript">
+	    dojo.setObject("dojo.tests._base.loader.pub1", "do-not-mess-with-me");
+		dojo.require("dojo.tests._base.loader.pub1");
+		dojo.require("dojo.tests._base.loader.pub2");
+		require(["doh", "dojo/has"], function(doh, has) {
+			doh.register("config-publish-require-result", function(t){
+				t.is(dojo.tests._base.loader.pub1, "do-not-mess-with-me");
+				if(publishing){
+				    t.t(has("config-publishRequireResult"));
+					t.is(dojo.tests._base.loader.pub2.status, "ok");
+				}else{
+				    t.t(!has("config-publishRequireResult"));
+					t.t(!dojo.config.publishRequireResult);
+					t.is(dojo.tests._base.loader.pub2.status, undefined);
+				}
+			});
+			doh.runOnLoad();
+		});
+	</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/ready.html b/dojo/tests/_base/loader/ready.html
new file mode 100644
index 0000000..82f428f
--- /dev/null
+++ b/dojo/tests/_base/loader/ready.html
@@ -0,0 +1,32 @@
+<html>
+<head>
+	<script type="text/javascript" src="../../../dojo.js"></script>
+	<script type="text/javascript">
+		// TODO: add tests to check dojo.ready, dojo.config.addOnLoad, require.ready, and priority queue
+		require(["dojo/ready"], function(ready){
+			var 
+				check1, check2, check3,
+				someObject = {},
+				someInstance = {
+					someMethod:function() { check3 = 2;}
+				};
+			ready(function() { check1= 1; });
+			ready(someObject, function() { check2= this; });
+			ready(someInstance, "someMethod");
+			require(["dojo", "doh"], function(dojo, doh) {
+				dojo.ready(function() {
+					doh.register("t", [
+						function(t){
+							t.is(check1, 1);
+							t.is(check2, someObject);
+							t.is(check3, 2);
+						}
+					]);
+					doh.runOnLoad();
+				});
+			});
+	</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/bar b/dojo/tests/_base/loader/requirejs/bar
new file mode 100644
index 0000000..6f020ce
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/bar
@@ -0,0 +1,5 @@
+//A test for loading a file with a protocol-less URL via require()
+
+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
new file mode 100644
index 0000000..625c4af
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/circular-tests.js
@@ -0,0 +1,29 @@
+require(
+    ["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) {
+                    t.is("small", args.size);
+                    t.is("redtwo", args.color);
+                }
+            ]
+        );
+        doh.run();
+
+        doh.register(
+            "circularFunc",
+            [
+                function circularFunc(t) {
+                    t.is("TWO", twoInst.name);
+                    t.is("ONE-NESTED", twoInst.oneName());
+                    t.is("THREE-THREE_SUFFIX", funcThree("THREE"));
+                }
+            ]
+        );
+        doh.run();
+    }
+);
diff --git a/dojo/tests/_base/loader/requirejs/circular.html b/dojo/tests/_base/loader/requirejs/circular.html
new file mode 100644
index 0000000..da171f2
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/circular.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>require.js: Circular Test</title>
+    <script type="text/javascript" src="requirejs-setup.js"></script>
+    <script type="text/javascript" src="../../../../dojo.js"></script>
+    <script type="text/javascript" src="circular-tests.js"></script>
+</head>
+<body>
+    <h1>require.js: Circular Test</h1>
+    <p>Check console for messages</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/config.html b/dojo/tests/_base/loader/requirejs/config.html
new file mode 100644
index 0000000..dcca116
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/config.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>require.js: Config Test</title>
+    <script>
+        function done() {
+			doh= require("doh");
+            doh.register(
+                        "config", 
+                        [
+                            function config(t){
+                                t.is("blue", s.color);
+                                t.is("dimple-blue", d.color);
+                                t.is("You called a function", f());
+                            }
+                        ]
+                    );
+            doh.run();
+        }
+
+        var s, d, f,
+            require = {
+                baseUrl: "./",
+                deps: ["require", "simple", "dimple", "func", "doh"],
+                callback: function (require, simple, dimple, func) {
+                    s = simple;
+                    d = dimple;
+                    f = func;
+					done();
+                }
+            };
+    </script>
+    <script type="text/javascript" src="requirejs-setup.js"></script>
+    <script type="text/javascript" src="../../../../dojo.js"></script>
+</head>
+<body>
+    <h1>require.js: Config Test</h1>
+    <p>Tests require being defined as an object with init and ready configuration.</p>
+    <p>Check console for messages.</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/dataMain.html b/dojo/tests/_base/loader/requirejs/dataMain.html
new file mode 100644
index 0000000..6f29258
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/dataMain.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>require.js: data-main Test</title>
+    <script type="text/javascript" src="requirejs-setup.js"></script>
+    <script type="text/javascript" data-main="dataMain.js" src="../../../../dojo.js"></script>
+</head>
+<body>
+    <h1>require.js: data-main Test</h1>
+    <p>Check console for messages</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/dataMain.js b/dojo/tests/_base/loader/requirejs/dataMain.js
new file mode 100644
index 0000000..c2f6ed2
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/dataMain.js
@@ -0,0 +1,16 @@
+require({
+        baseUrl: "./"
+    },
+    ["require", "simple", "doh"],
+    function(require, simple, doh) {
+        doh.register(
+            "dataMain",
+            [
+                function dataMain(t){
+                    t.is("blue", simple.color);
+                }
+            ]
+        );
+        doh.run();
+    }
+);
diff --git a/dojo/tests/_base/loader/requirejs/depoverlap.html b/dojo/tests/_base/loader/requirejs/depoverlap.html
new file mode 100644
index 0000000..3214cda
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/depoverlap.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>require.js: Dependency Overlap Test</title>
+    <script type="text/javascript" src="requirejs-setup.js"></script>
+    <script type="text/javascript" data-main="depoverlap" src="../../../../dojo.js"></script>
+</head>
+<body>
+    <h1>require.js: Dependency Overlap Test</h1>
+    <p>uno requires dos and tres, but tres also requires dos. Make sure
+    dos is only added once, and that all are defined correctly.</p>
+    <p>Check console for messages</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/depoverlap.js b/dojo/tests/_base/loader/requirejs/depoverlap.js
new file mode 100644
index 0000000..6af8756
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/depoverlap.js
@@ -0,0 +1,35 @@
+require(["require", "uno", "doh"],
+function (require, uno, doh) {
+    doh.register(
+        "depoverlap",
+        [
+            function depoverlap(t){
+                //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--) {
+                    modName = scripts[i].getAttribute("data-requiremodule");
+                    if (modName) {
+                        if (!(modName in counts)) {
+                            counts[modName] = 0;
+                        }
+                        counts[modName] += 1;
+                    }
+                }
+
+                //Now that we counted all the modules make sure count
+                //is always one.
+                for (prop in counts) {
+                    t.is(1, counts[prop]);
+                }
+
+                t.is("uno", uno.name);
+                something = uno.doSomething();
+                t.is("dos", something.dosName);
+                t.is("tres", something.tresName);
+            }
+        ]
+    );
+    doh.run();
+});
diff --git a/dojo/tests/_base/loader/requirejs/dimple.js b/dojo/tests/_base/loader/requirejs/dimple.js
new file mode 100644
index 0000000..9ab8f2c
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/dimple.js
@@ -0,0 +1,5 @@
+define("dimple",
+    {
+      color: "dimple-blue"
+    }
+);
diff --git a/dojo/tests/_base/loader/requirejs/dos.js b/dojo/tests/_base/loader/requirejs/dos.js
new file mode 100644
index 0000000..1a28c65
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/dos.js
@@ -0,0 +1,13 @@
+define("dos",
+  ["tres"],
+  function(tres) {
+    return {
+      name: "dos",
+      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
new file mode 100644
index 0000000..d260a90
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/exports/assign.js
@@ -0,0 +1,5 @@
+define("assign",
+            ["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
new file mode 100644
index 0000000..c6cd0c8
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/exports/assign2.js
@@ -0,0 +1,4 @@
+define(["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
new file mode 100644
index 0000000..b31acf5
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/exports/exports-tests.js
@@ -0,0 +1,24 @@
+require({
+        baseUrl: require.has("host-browser") ? "./" : "./exports/"
+    },
+    ["require", "vanilla", "funcSet", "assign", "assign2", "usethis",
+     "implicitModule", "simpleReturn", "doh"],
+    function(require, vanilla, funcSet, assign, assign2, usethis,
+      implicitModule, simpleReturn, doh) {
+        doh.register(
+            "exports",
+            [
+                function exports(t){
+                    t.is("vanilla", vanilla.name);
+                    t.is("funcSet", funcSet);
+                    t.is("assign", assign);
+                    t.is("assign2", assign2);
+                    //TODO: not implemented in dojo t.is("usethis", usethis.name);
+                    t.is("implicitModule", implicitModule());
+                    t.is("simpleReturn", simpleReturn());
+                }
+            ]
+        );
+        doh.run();
+    }
+);
diff --git a/dojo/tests/_base/loader/requirejs/exports/exports.html b/dojo/tests/_base/loader/requirejs/exports/exports.html
new file mode 100644
index 0000000..8b935a1
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/exports/exports.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>require.js: Exports Test</title>
+    <script type="text/javascript">
+		requirejsArgs= {
+			dojoLocation:"../../../../.."
+		};
+	</script>
+    <script type="text/javascript" src="../requirejs-setup.js"></script>
+    <script type="text/javascript" src="../../../../../dojo.js"></script>
+    <script type="text/javascript" src="exports-tests.js"></script>
+</head>
+<body>
+    <h1>require.js: Exports Test</h1>
+    <p>Check console for messages</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/exports/funcSet.js b/dojo/tests/_base/loader/requirejs/exports/funcSet.js
new file mode 100644
index 0000000..5f10a31
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/exports/funcSet.js
@@ -0,0 +1,5 @@
+define("funcSet",
+            ["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
new file mode 100644
index 0000000..4c021d3
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/exports/implicitModule.js
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000..7b5e7f0
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/exports/simpleReturn.js
@@ -0,0 +1,10 @@
+//This file does not use exports, just
+//return, but need to test that it does not
+//automatically get an exports object assigned
+define(
+    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
new file mode 100644
index 0000000..1c19f05
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/exports/usethis.js
@@ -0,0 +1,3 @@
+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
new file mode 100644
index 0000000..2168e47
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/exports/vanilla.js
@@ -0,0 +1,5 @@
+define("vanilla",
+            ["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
new file mode 100644
index 0000000..d6a4cde
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/foo
@@ -0,0 +1,5 @@
+//A test for loading a file with a protocol URL via require()
+
+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
new file mode 100644
index 0000000..6e4775f
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/func.js
@@ -0,0 +1,7 @@
+define("func",
+    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
new file mode 100644
index 0000000..12db975
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/funcFour.js
@@ -0,0 +1,14 @@
+define("funcFour",
+    ["require", "funcThree"],
+    function (require) {
+        var four = function (arg) {
+            return "FOUR called with " + arg;
+        };
+
+        four.suffix = function () {
+            return require("funcThree").suffix();
+        };
+
+        return four;
+    }
+);
diff --git a/dojo/tests/_base/loader/requirejs/funcOne.js b/dojo/tests/_base/loader/requirejs/funcOne.js
new file mode 100644
index 0000000..4620592
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/funcOne.js
@@ -0,0 +1,15 @@
+define("funcOne",
+    ["require", "funcTwo"],
+    function (require) {
+        var one = function (name) {
+            this.name = name;
+        };
+
+        one.prototype.getName = function () {
+            var inst = new (require("funcTwo"))("-NESTED");
+            return this.name + inst.name;
+        };
+
+        return one;
+    }
+);
diff --git a/dojo/tests/_base/loader/requirejs/funcThree.js b/dojo/tests/_base/loader/requirejs/funcThree.js
new file mode 100644
index 0000000..b02bf89
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/funcThree.js
@@ -0,0 +1,14 @@
+define("funcThree",
+    ["funcFour"],
+    function (four) {
+        var three = function (arg) {
+            return arg + "-" + require("funcFour").suffix();
+        };
+
+        three.suffix = function () {
+            return "THREE_SUFFIX";
+        };
+
+        return three;
+    }
+);
diff --git a/dojo/tests/_base/loader/requirejs/funcTwo.js b/dojo/tests/_base/loader/requirejs/funcTwo.js
new file mode 100644
index 0000000..38afc0e
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/funcTwo.js
@@ -0,0 +1,15 @@
+define("funcTwo",
+    ["require", "funcOne"],
+    function (require) {
+        var two = function (name) {
+            this.name = name;
+            this.one = new (require("funcOne"))("ONE");
+        };
+    
+        two.prototype.oneName = function () {
+            return this.one.getName();
+        };
+
+        return two;
+    }
+);
diff --git a/dojo/tests/_base/loader/requirejs/i18n/common.html b/dojo/tests/_base/loader/requirejs/i18n/common.html
new file mode 100644
index 0000000..b394c6d
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/i18n/common.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>require.js: Common I18N Test</title>
+    <script type="text/javascript">
+		requirejsArgs= {
+			dojoLocation:"../../../../.."
+		};
+	</script>
+    <script type="text/javascript" src="../requirejs-setup.js"></script>
+    <script type="text/javascript" src="../../../../../dojo.js"></script>
+    <script type="text/javascript">
+        //Allow locale to be set via query args.
+        var locale = null;
+        var query = location.href.split("#")[0].split("?")[1];
+        var match = query && query.match(/locale=([\w-]+)/);
+        if (match) {
+            locale = match[1];
+        }
+
+        var red = "red";
+        var blue = "blue";
+        if (locale && locale.indexOf("en-us-surfer") != -1) {
+            red = "red, dude";
+        } else if ((locale && locale.indexOf("fr-") != -1)) {
+            red = "rouge";
+            blue = "bleu";
+        }
+		require(["dojo"], function(dojo){
+			// dojo/i18n! looks at dojo.locale
+			locale && (dojo.locale= locale);
+	        require(
+	        ["commonA", "commonB", "doh"],
+	        function(commonA, commonB, doh) {
+	            doh.register(
+	                "commoni18n",
+	                [
+	                    function commoni18n(t) {
+	                        t.is(red, commonA);
+	                        t.is(blue, commonB);
+	                    }
+	                ]
+	            );
+	            doh.run();
+	        });
+        });
+    </script>
+</head>
+<body>
+    <h1>Common i18n bundle test</h1>
+    <p>This page tests for an i18n plugin resource that is specified by two different modules.</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/i18n/commonA.js b/dojo/tests/_base/loader/requirejs/i18n/commonA.js
new file mode 100644
index 0000000..fcdf974
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/i18n/commonA.js
@@ -0,0 +1,3 @@
+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
new file mode 100644
index 0000000..3e7c43e
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/i18n/commonB.js
@@ -0,0 +1,3 @@
+define(['i18n!nls/colors'], function (colors) {
+   return colors.blue;
+});
diff --git a/dojo/tests/_base/loader/requirejs/i18n/i18n.html b/dojo/tests/_base/loader/requirejs/i18n/i18n.html
new file mode 100644
index 0000000..128b90d
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/i18n/i18n.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>require.js: I18N Test</title>
+    <script type="text/javascript">
+		requirejsArgs= {
+			dojoLocation:"../../../../.."
+		};
+	</script>
+    <script type="text/javascript" src="../requirejs-setup.js"></script>
+    <script type="text/javascript" src="../../../../../dojo.js"></script>
+    <script type="text/javascript">
+        //Allow locale to be set via query args.
+        var locale = null;
+        var query = location.href.split("#")[0].split("?")[1];
+        var match = query && query.match(/locale=([\w-]+)/);
+        if (match) {
+            locale = match[1];
+        }
+
+        //Allow bundle name to be loaded via query args.
+        var bundle = "i18n!nls/colors";
+        match = query && query.match(/bundle=([^\&]+)/);
+        if (match) {
+            bundle = match[1];
+        }
+
+        var red = "red";
+        var blue = "blue";
+        var green = "green";
+        if (locale && locale.indexOf("en-us-surfer") != -1 || bundle.indexOf("nls/en-us-surfer/colors") != -1) {
+            red = "red, dude";
+        } else if ((locale && locale.indexOf("fr-") != -1) || bundle.indexOf("fr-") != -1) {
+            red = "rouge";
+            blue = "bleu";
+        }
+		require(["dojo"], function(dojo){
+			// dojo/i18n! looks at dojo.locale
+			locale && (dojo.locale= locale);
+	        require(
+	        [bundle, "doh"],
+	        function(colors, doh) {
+	            doh.register(
+	                "i18n",
+	                [
+	                    function i18n(t) {
+	                        t.is(red, colors.red);
+	                        t.is(blue, colors.blue);
+	                        t.is(green, colors.green);
+	                    }
+	                ]
+	            );
+	            doh.run();
+	        });
+		});
+    </script>
+</head>
+<body>
+    <h1>i18n bundle test</h1>
+    <p>This page tests the i18n bundling in require.js. You can change the locale to use by passing locale= or bundle=</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/i18n/i18n.js b/dojo/tests/_base/loader/requirejs/i18n/i18n.js
new file mode 100644
index 0000000..637089c
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/i18n/i18n.js
@@ -0,0 +1,4 @@
+// alias i18n to dojo/i18n
+define(["dojo/i18n"], function(i18n){
+  return i18n;
+});
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/requirejs/i18n/nls/colors.js b/dojo/tests/_base/loader/requirejs/i18n/nls/colors.js
new file mode 100644
index 0000000..8021cd5
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/i18n/nls/colors.js
@@ -0,0 +1,9 @@
+define({
+    "root": {
+        red: "red",
+        blue: "blue",
+        green: "green"
+    },
+    "en-us-surfer": true,
+    "fr": true
+});
diff --git a/dojo/tests/_base/loader/requirejs/i18n/nls/en-us-surfer/colors.js b/dojo/tests/_base/loader/requirejs/i18n/nls/en-us-surfer/colors.js
new file mode 100644
index 0000000..e122d28
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/i18n/nls/en-us-surfer/colors.js
@@ -0,0 +1,3 @@
+define({
+    red: "red, dude"
+});
diff --git a/dojo/tests/_base/loader/requirejs/i18n/nls/fr/colors.js b/dojo/tests/_base/loader/requirejs/i18n/nls/fr/colors.js
new file mode 100644
index 0000000..c5392fc
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/i18n/nls/fr/colors.js
@@ -0,0 +1,4 @@
+define({
+    red: "rouge",
+    blue: "bleu"
+});
diff --git a/dojo/tests/_base/loader/requirejs/i18n/testModule.js b/dojo/tests/_base/loader/requirejs/i18n/testModule.js
new file mode 100644
index 0000000..7bafb5c
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/i18n/testModule.js
@@ -0,0 +1,4 @@
+//A sample module to use in the i18n build test.
+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/allplugins-text.html b/dojo/tests/_base/loader/requirejs/layers/allplugins-text.html
new file mode 100644
index 0000000..2379a7d
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/layers/allplugins-text.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>require.js: allplugins-text Test</title>
+    <script type="text/javascript" src="allplugins-require.js"></script>
+    <script type="text/javascript" src="../doh/runner.js"></script>
+    <script type="text/javascript" src="../doh/_browserRunner.js"></script>
+    <script type="text/javascript">
+    require(
+        {
+            baseUrl: "./"
+        },
+        ["require", "text!helloWorld.txt"],
+        function(require, helloWorld) {
+            doh.register(
+                        "allplugins-text",
+                        [
+                            function allpluginsText(t){
+                                t.is("hello world", helloWorld);
+                            }
+                        ]
+                    );
+            doh.run();
+        }
+    );
+    </script>
+</head>
+<body>
+    <h1>require.js: allplugins-text Test</h1>
+    <p><b>REQUIRES a built allplugins-require.js file built from build.sh in this directory</b></p>
+    <p>Check console for messages</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/layers/build.sh b/dojo/tests/_base/loader/requirejs/layers/build.sh
new file mode 100755
index 0000000..f5d556e
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/layers/build.sh
@@ -0,0 +1 @@
+../../build/build.sh baseUrl=../.. name=require include=i18n,text,order, out=allplugins-require.js optimize=none
diff --git a/dojo/tests/_base/loader/requirejs/layers/epsilon.js b/dojo/tests/_base/loader/requirejs/layers/epsilon.js
new file mode 100644
index 0000000..7a66e57
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/layers/epsilon.js
@@ -0,0 +1,5 @@
+define("epsilon",
+    {
+        name: "epsilon"
+    }
+);
diff --git a/dojo/tests/_base/loader/requirejs/layers/helloWorld.txt b/dojo/tests/_base/loader/requirejs/layers/helloWorld.txt
new file mode 100644
index 0000000..95d09f2
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/layers/helloWorld.txt
@@ -0,0 +1 @@
+hello world
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/requirejs/layers/layer1.js b/dojo/tests/_base/loader/requirejs/layers/layer1.js
new file mode 100644
index 0000000..963ab00
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/layers/layer1.js
@@ -0,0 +1,31 @@
+//Example layer file.
+
+define("alpha",
+    ["beta", "gamma"],
+    function (beta, gamma) {
+        return {
+            name: "alpha",
+            betaName: beta.name
+        };
+    }
+);
+
+define("beta",
+    ["gamma"],
+    function (gamma) {
+        return {
+            name: "beta",
+            gammaName: gamma.name
+        };
+    }
+);
+
+define("gamma",
+    ["epsilon"],
+    function (epsilon) {
+        return {
+            name: "gamma",
+            epsilonName: epsilon.name
+        };
+    }
+);
diff --git a/dojo/tests/_base/loader/requirejs/layers/layers.html b/dojo/tests/_base/loader/requirejs/layers/layers.html
new file mode 100644
index 0000000..a621a7d
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/layers/layers.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>require.js: Layers Test</title>
+    <script type="text/javascript">
+		requirejsArgs= {
+			dojoLocation:"../../../../.."
+		};
+	</script>
+    <script type="text/javascript" src="../requirejs-setup.js"></script>
+    <script type="text/javascript" src="../../../../../dojo.js"></script>
+    <script type="text/javascript">
+	  require(["doh"], function(doh){
+	    var master = new doh.Deferred();
+	    doh.register(
+	        "layers",
+	        [
+	            {
+	                name: "layers",
+	                timeout: 5000,
+	                runTest: function() {
+	                    return master;
+	                }
+	            }
+	        ]
+	    );
+	    doh.run();
+	
+	    require(
+	        {
+	            baseUrl: "./"
+	        },
+	        ["require", "layer1"],
+	        function(require) {
+	            require(["alpha", "beta", "gamma", "epsilon"],
+	                function(alpha, beta, gamma, epsilon) {
+	                    doh.is("alpha", alpha.name);
+	                    doh.is("beta", alpha.betaName);
+	                    doh.is("beta", beta.name);
+	                    doh.is("gamma", beta.gammaName);
+	                    doh.is("gamma", gamma.name);
+	                    doh.is("epsilon", gamma.epsilonName);
+	                    doh.is("epsilon", epsilon.name);
+	                }
+	            );
+	
+	            var verifyFunc = function () {
+	                var regExp = /alpha|beta|gamma/,
+	                    i,
+	                    scripts = document.getElementsByTagName("script");
+	                for (var i = scripts.length - 1; i > -1; i--) {
+	                    doh.f(regExp.test(scripts[i].src));
+	                }
+	                master.callback(true);
+	            };
+	
+                setTimeout(verifyFunc, 3000);
+	        }
+	    );
+	  });
+    </script>
+</head>
+<body>
+    <h1>require.js: Layers Test</h1>
+    <p>Check console for messages</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/map.js b/dojo/tests/_base/loader/requirejs/map.js
new file mode 100644
index 0000000..3e07574
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/map.js
@@ -0,0 +1,7 @@
+define("map",
+  function() {
+    return {
+      name: "map"
+    };
+  }
+);
diff --git a/dojo/tests/_base/loader/requirejs/one.js b/dojo/tests/_base/loader/requirejs/one.js
new file mode 100644
index 0000000..469a75f
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/one.js
@@ -0,0 +1,13 @@
+define("one",
+  ["require", "two"],
+  function(require) {
+    var one = {
+      size: "large",
+      doSomething: function() {
+        return require("two");
+      }
+    };
+
+    return one;
+  }
+);
diff --git a/dojo/tests/_base/loader/requirejs/paths/first.js/first.js b/dojo/tests/_base/loader/requirejs/paths/first.js/first.js
new file mode 100644
index 0000000..72b6a94
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/paths/first.js/first.js
@@ -0,0 +1,8 @@
+globalCounter += 1;
+
+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
new file mode 100644
index 0000000..9ebcda1
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/paths/first.js/second.js
@@ -0,0 +1,8 @@
+define(['./first'], function () {
+    return function (id, parentRequire, loaded) {
+        loaded({
+            name: 'first',
+            secondName: 'second'
+        });
+    };
+});
diff --git a/dojo/tests/_base/loader/requirejs/paths/paths.html b/dojo/tests/_base/loader/requirejs/paths/paths.html
new file mode 100644
index 0000000..03cd742
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/paths/paths.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>require.js: paths Test</title>
+    <script type="text/javascript">
+		requirejsArgs= {
+			dojoLocation:"../../../../.."
+		};
+	</script>
+    <script type="text/javascript" src="../requirejs-setup.js"></script>
+    <script type="text/javascript" src="../../../../../dojo.js"></script>
+    <script type="text/javascript">
+    var globalCounter = 0,
+        scriptCounter = 0;
+    require({
+            baseUrl: "./",
+            packages: [
+                {
+                    name:"first",
+                    location:"first.js",
+                    main:"./first"
+                }
+            ]
+        },
+        ["require", "first!whatever", "doh"],
+        function(require, first, doh) {
+            doh.register(
+                "paths",
+                [
+                    function paths(t){
+                        //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--) {
+                            modName = scripts[i].getAttribute("src");
+                            if (/first\.js$/.test(modName)) {
+                                scriptCounter += 1;
+                            }
+                        }
+						if(require.async){
+							t.is(1, scriptCounter);
+						}
+                        t.is(2, globalCounter);
+                        t.is("first", first.name);
+                        t.is("second", first.secondName);
+                    }
+                ]
+            );
+            doh.run();
+        }
+    );
+    </script>
+</head>
+<body>
+    <h1>require.js: paths Test</h1>
+    <p>Check console for messages</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/relative/foo/bar/message.txt b/dojo/tests/_base/loader/requirejs/relative/foo/bar/message.txt
new file mode 100644
index 0000000..95d09f2
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/relative/foo/bar/message.txt
@@ -0,0 +1 @@
+hello world
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/requirejs/relative/foo/bar/one.js b/dojo/tests/_base/loader/requirejs/relative/foo/bar/one.js
new file mode 100644
index 0000000..e62290a
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/relative/foo/bar/one.js
@@ -0,0 +1,10 @@
+define("foo/bar/one",
+            ["require", "./two", "../three", "text!./message.txt"],
+            function (require, two, three, message) {
+    return {
+        name: "one",
+        twoName: two.name,
+        threeName: three.name,
+        message: message
+    };
+});
diff --git a/dojo/tests/_base/loader/requirejs/relative/foo/bar/two.js b/dojo/tests/_base/loader/requirejs/relative/foo/bar/two.js
new file mode 100644
index 0000000..521822a
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/relative/foo/bar/two.js
@@ -0,0 +1,3 @@
+define("foo/bar/two", {
+    name: "two"
+});
diff --git a/dojo/tests/_base/loader/requirejs/relative/foo/three.js b/dojo/tests/_base/loader/requirejs/relative/foo/three.js
new file mode 100644
index 0000000..36aa2fc
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/relative/foo/three.js
@@ -0,0 +1,3 @@
+define("foo/three", {
+    name: "three"
+});
diff --git a/dojo/tests/_base/loader/requirejs/relative/relative-tests.js b/dojo/tests/_base/loader/requirejs/relative/relative-tests.js
new file mode 100644
index 0000000..21684e2
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/relative/relative-tests.js
@@ -0,0 +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, ""));
+                }
+            ]
+        );
+
+        doh.run();
+    }
+);
diff --git a/dojo/tests/_base/loader/requirejs/relative/relative.html b/dojo/tests/_base/loader/requirejs/relative/relative.html
new file mode 100644
index 0000000..e232440
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/relative/relative.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>require.js: Relative Module Names Test</title>
+    <script type="text/javascript">
+		requirejsArgs= {
+			dojoLocation:"../../../../.."
+		};
+	</script>
+    <script type="text/javascript" src="../requirejs-setup.js"></script>
+    <script type="text/javascript" src="../../../../../dojo.js"></script>
+    <script type="text/javascript">
+	    // alias dojo's text module to text!
+		define("text", ["dojo/text"], function(text){ return text; });
+	</script>
+    <script type="text/javascript" src="relative-tests.js"></script>
+</head>
+<body>
+    <h1>require.js: Relative Module Names Test</h1>
+    <p>Check console for messages</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/requirejs-setup.js b/dojo/tests/_base/loader/requirejs/requirejs-setup.js
new file mode 100644
index 0000000..d4fb1ff
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/requirejs-setup.js
@@ -0,0 +1,32 @@
+var dohArgs= (window.parent.doh && window.parent.doh.dohArgs) || dohArgs || {
+	async:1,
+	baseUrl:"."
+};
+var requirejsArgs= requirejsArgs || {
+	dojoLocation:"../../../.."
+};
+var dojoConfig= {
+	async:dohArgs.async,
+	baseUrl:dohArgs.baseUrl || ".",
+	packages:[{
+		name:'dojo',
+		location:requirejsArgs.dojoLocation
+	},{
+		name:'doh',
+		location:requirejsArgs.dojoLocation + '/../util/doh'
+	},{
+		name:'dojox',
+		location:requirejsArgs.dojoLocation + '/../dojox'
+	}],
+	has:{
+		"dojo-requirejs-api":1,
+		"config-tlmSiblingOfDojo":0
+	}
+};
+if(typeof require!="undefined"){
+	(function(){
+		for(var p in require){
+			dojoConfig[p]= require[p];
+		}
+	})();
+}
diff --git a/dojo/tests/_base/loader/requirejs/simple-badbase.html b/dojo/tests/_base/loader/requirejs/simple-badbase.html
new file mode 100644
index 0000000..8cf08e2
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/simple-badbase.html
@@ -0,0 +1,55 @@
+<html>
+<head>
+    <title>require.js: Simple Bad Base Test</title>
+    <base href="http://some.example.com/path/" />
+	<script type="text/javascript">
+	  document.write('<scr' + 'ipt type="text/javascript" src="' + window.parent.doh.dohArgs.setup + '"></scr' + 'ipt>' );
+	  document.write('<scr' + 'ipt type="text/javascript" src="' + window.parent.doh.dohArgs.dojo + '"></scr' + 'ipt>' );
+	</script>
+    <script type="text/javascript">
+        require(
+			// the set up script sets the base URL
+            ["require", "simple", "dimple", "func", "doh"],
+            function(require, simple, dimple, func) {
+                doh.register(
+                    "simple", 
+                    [
+                        function colors(t){
+                            t.is("blue", simple.color);
+                            t.is("dimple-blue", dimple.color);
+                            t.is("You called a function", func());
+                        }
+                    ]
+                );
+                doh.run();
+            }
+        );
+    </script>
+    <script type="text/javascript">
+        //This test is only in the HTML since it uses an URL for a require
+        //argument. It will not work well in say, the Rhino tests.
+        var path = location.href.replace(/simple-badbase\.html$/, "foo"),
+            index = path.indexOf(":"),
+            noProtocolPath = path.substring(index + 1, path.length).replace(/foo/, "bar");
+
+        require([path, noProtocolPath, "doh"], function() {
+            doh.register(
+                        "fooBar", 
+                        [
+                            function fooBar(t){
+                                t.is("foo", foo.name); 
+                                t.is("bar", bar.name); 
+                            }
+                        ]
+                    );
+            doh.run();
+            
+        });
+    </script>
+</head>
+<body>
+    <h1>require.js: Simple Test</h1>
+    <p>You may need to change the IP address used for this test for it to work correctly.</p>
+    <p>Check console for messages</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/simple-nohead.html b/dojo/tests/_base/loader/requirejs/simple-nohead.html
new file mode 100644
index 0000000..1772e78
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/simple-nohead.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+
+<h1>require.js: Simple Test, no head tag</h1>
+<p>Check console for messages</p>
+
+<script type="text/javascript" src="requirejs-setup.js"></script>
+<script type="text/javascript" data-main="dataMain.js" src="../../../../dojo.js"></script>
+<script type="text/javascript">
+require(["require", "simple", "dimple", "func", "doh"],
+    function(require, simple, dimple, func) {
+        doh.register(
+            "simple-nohead", 
+            [
+                function colors(t){
+                    t.is("blue", simple.color);
+                    t.is("dimple-blue", dimple.color);
+                    t.is("You called a function", func());
+                }
+            ]
+        );
+        doh.run();
+    }
+);
+</script>
diff --git a/dojo/tests/_base/loader/requirejs/simple-tests.js b/dojo/tests/_base/loader/requirejs/simple-tests.js
new file mode 100644
index 0000000..7cfc856
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/simple-tests.js
@@ -0,0 +1,23 @@
+require({
+        baseUrl: "./"
+    },
+    ["require", "map", "simple", "dimple", "func", "doh"],
+    function(require, map, simple, dimple, func, doh) {
+        doh.register(
+            "simple",
+            [
+                function colors(t){
+                    t.is("map", map.name);
+                    t.is("blue", simple.color);
+                    t.is("dimple-blue", dimple.color);
+                    t.is("You called a function", func());
+                }
+            ]
+        );
+
+        //In rhino there is no more simple tests, but in web browser there is.
+        if (typeof moreSimpleTests === 'undefined') {
+            doh.run();
+        }
+    }
+);
diff --git a/dojo/tests/_base/loader/requirejs/simple.html b/dojo/tests/_base/loader/requirejs/simple.html
new file mode 100644
index 0000000..07e1b50
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/simple.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>require.js: Simple Test</title>
+    <script type="text/javascript" src="requirejs-setup.js"></script>
+    <script type="text/javascript" src="../../../../dojo.js"></script>
+    <script>moreSimpleTests = true</script>
+    <script type="text/javascript" src="simple-tests.js"></script>
+    <script type="text/javascript">
+        //This test is only in the HTML since it uses an URL for a require
+        //argument. It will not work well in say, the Rhino tests.
+        var path = location.href.replace(/simple\.html$/, "foo"),
+            index = path.indexOf(":"),
+            noProtocolPath = path.substring(index + 1, path.length).replace(/foo/, "bar");
+
+        require(["doh", path, noProtocolPath], function() {
+            doh.register(
+                        "fooBar", 
+                        [
+                            function fooBar(t){
+                                t.is("foo", foo.name); 
+                                t.is("bar", bar.name); 
+                            }
+                        ]
+                    );
+            doh.run();
+            
+        });
+    </script>
+</head>
+<body>
+    <h1>require.js: Simple Test</h1>
+    <p>Check console for messages</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/simple.js b/dojo/tests/_base/loader/requirejs/simple.js
new file mode 100644
index 0000000..79552cf
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/simple.js
@@ -0,0 +1,7 @@
+define("simple",
+  function() {
+    return {
+      color: "blue"
+    };
+  }
+);
diff --git a/dojo/tests/_base/loader/requirejs/text/local.js b/dojo/tests/_base/loader/requirejs/text/local.js
new file mode 100644
index 0000000..d25af0f
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/text/local.js
@@ -0,0 +1,5 @@
+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
new file mode 100644
index 0000000..f62ec62
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/text/resources/local.html
@@ -0,0 +1 @@
+<h1>Local</h1>
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/requirejs/text/resources/sample.html b/dojo/tests/_base/loader/requirejs/text/resources/sample.html
new file mode 100644
index 0000000..0583261
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/text/resources/sample.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>sample.html</title>
+    <script type="text/javascript" src="../require.js"></script>
+</head>
+<body class="foo" onload="alert('hello')"><span>Hello World!</span></body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/text/subwidget.html b/dojo/tests/_base/loader/requirejs/text/subwidget.html
new file mode 100644
index 0000000..3fd9b9d
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/text/subwidget.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>sample.html</title>
+    <script type="text/javascript" src="../require.js"></script>
+</head>
+<body class="foo" onload="alert('hello')"><div data-type="subwidget"><h1>This is a subwidget</h1></div></body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/text/subwidget.js b/dojo/tests/_base/loader/requirejs/text/subwidget.js
new file mode 100644
index 0000000..9fd0822
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/text/subwidget.js
@@ -0,0 +1,10 @@
+define("subwidget",
+  ["text!subwidget.html!strip", "text!subwidget2.html"],
+  function(template, template2) {
+    return {
+      name: "subwidget",
+      template: template,
+      template2: template2
+    };
+  }
+);
diff --git a/dojo/tests/_base/loader/requirejs/text/subwidget2.html b/dojo/tests/_base/loader/requirejs/text/subwidget2.html
new file mode 100644
index 0000000..13a0a03
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/text/subwidget2.html
@@ -0,0 +1 @@
+<span>This! is template2</span>
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/requirejs/text/text.html b/dojo/tests/_base/loader/requirejs/text/text.html
new file mode 100644
index 0000000..e396f3e
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/text/text.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>require.js: Text Test</title>
+    <script type="text/javascript">
+		requirejsArgs= {
+			dojoLocation:"../../../../.."
+		};
+	</script>
+    <script type="text/javascript" src="../requirejs-setup.js"></script>
+    <script type="text/javascript" src="../../../../../dojo.js"></script>
+    <script type="text/javascript">
+	  // alias dojo's text module to text!
+	  if(dohArgs.aliasTest){
+		require({aliases:[
+			["text", "dojo/text"]
+		]});
+	  }else{
+		define("text", ["dojo/text"], function(text){ return text; });
+	  }
+
+	  require(["doh"], function(doh){
+	    require({
+	            baseUrl: "./",
+	            paths: {
+	                text: "../../text"
+	            } //, priority: ['widgetlayer']
+	        },
+	        ["require", "widget", "local", "text!resources/sample.html!strip"],
+	        function(require, widget, local, sampleText) {
+	            doh.register(
+	                "text",
+	                [
+	                    function text(t){
+							function check(expected, actual){
+								t.is(expected, actual.replace(/\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);
+	                        check('subwidget', widget.subWidgetName);
+	                        check('<div data-type="subwidget"><h1>This is a subwidget</h1></div>', widget.subWidgetTemplate);
+	                        check('<span>This! is template2</span>', widget.subWidgetTemplate2);
+	                        check('<h1>Local</h1>', local.localHtml);
+	                    }
+	                ]
+	            );
+	            doh.run();
+	        }
+	    );
+	  });
+    </script>
+</head>
+<body>
+    <h1>require.js: Text Test</h1>
+    <p>Test for usage of text! require plugin.
+    <p>Check console for messages</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/text/textOnly.html b/dojo/tests/_base/loader/requirejs/text/textOnly.html
new file mode 100644
index 0000000..6ab65d1
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/text/textOnly.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>require.js: Text Test</title>
+    <script type="text/javascript">
+		requirejsArgs= {
+			dojoLocation:"../../../../.."
+		};
+	</script>
+    <script type="text/javascript" src="../requirejs-setup.js"></script>
+    <script type="text/javascript" src="../../../../../dojo.js"></script>
+    <script type="text/javascript">
+    // alias dojo's text module to text!
+	define("text", ["dojo/text"], function(text){ return text; });
+
+    require({
+            baseUrl: "./",
+            paths: {
+                text: "../../text"
+            }
+        },
+        ["text!resources/sample.html!strip", "doh"],
+        function(sampleText, doh) {
+            doh.register(
+                "textOnly",
+                [
+                    function textOnly(t){
+                        t.is("<span>Hello World!</span>", sampleText);
+                    }
+                ]
+            );
+            doh.run();
+        }
+    );
+    </script>
+</head>
+<body>
+    <h1>require.js: Text Test</h1>
+    <p>Test for usage of text! require plugin.
+    <p>Check console for messages</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/text/widget.html b/dojo/tests/_base/loader/requirejs/text/widget.html
new file mode 100644
index 0000000..c11c453
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/text/widget.html
@@ -0,0 +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
diff --git a/dojo/tests/_base/loader/requirejs/text/widget.js b/dojo/tests/_base/loader/requirejs/text/widget.js
new file mode 100644
index 0000000..4075369
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/text/widget.js
@@ -0,0 +1,11 @@
+define("widget",
+  ["subwidget", "text!widget.html"],
+  function(subwidget, template) {
+    return {
+      subWidgetName: subwidget.name,
+      subWidgetTemplate: subwidget.template,
+      subWidgetTemplate2: subwidget.template2,
+      template: template
+    };
+  }
+);
diff --git a/dojo/tests/_base/loader/requirejs/tres.js b/dojo/tests/_base/loader/requirejs/tres.js
new file mode 100644
index 0000000..e3eba93
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/tres.js
@@ -0,0 +1,7 @@
+define("tres",
+  function() {
+    return {
+      name: "tres"
+    };
+  }
+);
diff --git a/dojo/tests/_base/loader/requirejs/two.js b/dojo/tests/_base/loader/requirejs/two.js
new file mode 100644
index 0000000..8c4c055
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/two.js
@@ -0,0 +1,12 @@
+define("two",
+  ["require", "one"],
+  function(require, one) {
+    return {
+      size: "small",
+      color: "redtwo",
+      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
new file mode 100644
index 0000000..ccaa684
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/uniques/one.js
@@ -0,0 +1,8 @@
+define(function (require) {
+    return {
+       name: "one",
+       threeName: require("three").name,
+       threeName2: require("three").name
+    };
+});
+
diff --git a/dojo/tests/_base/loader/requirejs/uniques/three.js b/dojo/tests/_base/loader/requirejs/uniques/three.js
new file mode 100644
index 0000000..3d52f9e
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/uniques/three.js
@@ -0,0 +1,3 @@
+define("three", {
+    name: "three"
+});
diff --git a/dojo/tests/_base/loader/requirejs/uniques/two.js b/dojo/tests/_base/loader/requirejs/uniques/two.js
new file mode 100644
index 0000000..f272edb
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/uniques/two.js
@@ -0,0 +1,8 @@
+define("two", ["one", "three", "one"], function (one, three, one2) {
+    return {
+        name: "two",
+        oneName: one.name,
+        oneName2: one2.name,
+        threeName: three.name
+    };
+});
diff --git a/dojo/tests/_base/loader/requirejs/uniques/uniques.html b/dojo/tests/_base/loader/requirejs/uniques/uniques.html
new file mode 100644
index 0000000..7099900
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/uniques/uniques.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>require.js: Unique Dependency Test</title>
+    <script type="text/javascript">
+		requirejsArgs= {
+			dojoLocation:"../../../../.."
+		};
+	</script>
+    <script type="text/javascript" src="../requirejs-setup.js"></script>
+    <script type="text/javascript" src="../../../../../dojo.js"></script>
+    <script type="text/javascript">
+    require({
+            baseUrl: "./"
+        },
+        ["require", "one", "two", "three", "doh"],
+        function(require, one, two, three, doh) {
+            doh.register(
+                "uniques",
+                [
+                    function uniques(t){
+                        t.is("one", one.name);
+                        t.is("three", one.threeName);
+                        t.is("three", one.threeName2);
+                        t.is("one", two.oneName);
+                        t.is("one", two.oneName2);
+                        t.is("two", two.name);
+                        t.is("three", two.threeName);
+                        t.is("three", three.name);
+                    }
+                ]
+            );
+            doh.run();
+        }
+    );
+    </script>
+</head>
+<body>
+    <h1>require.js: Unique Dependency Test</h1>
+    <p>Make sure if a dependency is listed more than once code still operates correctly.</p>
+    <p>Check console for messages</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/requirejs/uno.js b/dojo/tests/_base/loader/requirejs/uno.js
new file mode 100644
index 0000000..dcc57dc
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/uno.js
@@ -0,0 +1,14 @@
+define("uno",
+  ["dos", "tres"],
+  function(dos, tres) {
+    return {
+      name: "uno",
+      doSomething: function() {
+        return {
+          dosName: dos.name,
+          tresName: tres.name
+        };
+      }
+    };
+  }
+);
diff --git a/dojo/tests/_base/loader/requirejs/urlfetch/one.js b/dojo/tests/_base/loader/requirejs/urlfetch/one.js
new file mode 100644
index 0000000..92184ae
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/urlfetch/one.js
@@ -0,0 +1,3 @@
+var one = {
+    name: "one"
+};
diff --git a/dojo/tests/_base/loader/requirejs/urlfetch/three.js b/dojo/tests/_base/loader/requirejs/urlfetch/three.js
new file mode 100644
index 0000000..d78a542
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/urlfetch/three.js
@@ -0,0 +1,10 @@
+define("three", {
+    name: "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
new file mode 100644
index 0000000..8617a31
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/urlfetch/two.js
@@ -0,0 +1,10 @@
+define("one", {
+    name: "one"
+});
+
+define("two", ["one"], function (one) {
+    return {
+        name: "two",
+        oneName: "one"
+    };
+});
diff --git a/dojo/tests/_base/loader/requirejs/urlfetch/urlfetch.html b/dojo/tests/_base/loader/requirejs/urlfetch/urlfetch.html
new file mode 100644
index 0000000..328c843
--- /dev/null
+++ b/dojo/tests/_base/loader/requirejs/urlfetch/urlfetch.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>require.js: urlFetch Mapping Test</title>
+    <script type="text/javascript">
+		var dohArgs = {async:0};
+		requirejsArgs= {
+			dojoLocation:"../../../../.."
+		};
+	</script>
+    <script type="text/javascript" src="../requirejs-setup.js"></script>
+    <script type="text/javascript" src="../../../../../dojo.js"></script>
+    <script type="text/javascript">
+    require({
+            baseUrl: "./",
+            paths: {
+                'one' : 'two',
+                'two' : 'two',
+                'three': 'three',
+                'four': 'three'
+            }
+        },
+        ["require", "one", "two", "three", "four", "doh"],
+        function(require, one, two, three, four, doh) {
+            doh.register(
+                "urlfetch", 
+                [
+                    function urlfetch(t){
+                        //First confirm there is only one script tag for each
+                        //module:
+                        var scripts = document.getElementsByTagName("script"),
+                            i, counts = {}, url, props, something;
+                        for (var i = scripts.length - 1; i > -1; i--) {
+                            url = scripts[i].src;
+                            if (url) {
+                                if (!(url in counts)) {
+                                    counts[url] = 0;
+                                }
+                                counts[url] += 1;
+                            }
+                        }
+
+						if(require.async){
+						    for (prop in counts) {
+								t.is(1, counts[prop]);
+	                        }
+						}
+
+                        t.is("one", one.name);
+                        t.is("one", two.oneName);
+                        t.is("two", two.name);
+                        t.is("three", three.name);
+                        t.is("three", four.threeName);
+                        t.is("four", four.name);
+                    }
+                ]
+            );
+            doh.run();
+        }
+    );
+    </script>
+</head>
+<body>
+    <h1>require.js: urlFetch Mapping Test</h1>
+    <p>Make sure that multiple modules mapped to the same URL only get
+    the URL fetched once.</p>
+    <p>Check console for messages</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/scope04.html b/dojo/tests/_base/loader/scope04.html
new file mode 100644
index 0000000..f6d2571
--- /dev/null
+++ b/dojo/tests/_base/loader/scope04.html
@@ -0,0 +1,80 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Multiversion Dojo: 0.4.3 and 1.0</title>
+
+		<link rel="stylesheet" type="text/css" href="../../../resources/dojo.css"/>
+		<link rel="stylesheet" type="text/css" href="../../../../dijit/tests/css/dijitTests.css"/>
+		<link rel="stylesheet" type="text/css" href="../../../../dijit/themes/tundra/tundra.css"/>
+		
+		<script type="text/javascript">
+			//djConfig for 0.4.3 setup.
+			djConfig = {
+				isDebug: true
+			};
+		</script>
+		<script type="text/javascript" src="http://o.aolcdn.com/dojo/0.4.3/dojo.js"></script>
+		
+		<script type="text/javascript">
+			//Need scope map defined in a script block. It will not work as part of the
+			//djConfig attribute on the script that loads Dojo.
+			//Also, just adding properties instead of redefining djConfig, since that
+			//will wipe out djConfig values set up by the 0.4.3 dojo.
+			djConfig.parseOnLoad = true;
+			djConfig.baseUrl = "../../../";
+			djConfig.scopeMap = [
+				["dojo", "dojo10"],
+				["dijit", "dijit10"],
+				["dojox", "dojox10"]					
+			];
+		</script>
+		<script type="text/javascript" src="../../../dojo.js"></script>
+		<script type="text/javascript">
+			dojo.require("dojo.widget.DropdownDatePicker");
+			dojo10.require("dijit.Calendar");
+			dojo10.require("dojo.date.locale");
+			dojo10.require("dojo.parser"); // scan page for widgets
+
+			dojo.addOnLoad(function(){
+				dojo.byId("output043").innerHTML = dojo.version.toString();
+			});
+			dojo10.addOnLoad(function(){
+				dojo.byId("output10").innerHTML = dojo10.version.toString();
+			});
+
+			function myHandler(id,newValue){
+				console.debug("onChange for id = " + id + ", value: " + newValue);
+			}
+			
+			function foobar(){
+				dojo.byId("typeOut").innerHTML = (typeof dojo.addClass);
+			}
+			setTimeout(foobar, 2000);
+
+		</script>
+	</head>
+	<body>
+		<h1>Multiversion Dojo: 0.4.3 and 1.0</h1>
+	
+		<p><b>NOTE: This test only works with a built version of Dojo</b></p>
+
+		<p>This page loads Dojo 0.4.3 and Dojo 1.0.</p>
+		
+		<p>Dojo 0.4.3 version: <span id="output043"></span></p>
+		
+		<p>Dojo 1.0 version: <span id="output10"></span></p>
+		
+		<p><b>dojo.addClass should be undefined:</b> <span id="typeOut"></span></p>
+		
+		<p>
+			<input dojoType="dropdowndatepicker" value="2006-10-31" containerToggle="wipe" containerToggleDuration="300" >
+		</p>
+		
+		<p class="tundra">
+			<input id="calendar1" dojo10Type="dijit.Calendar" onChange="myHandler(this.id,arguments[0])">
+		</p>
+		
+	</body>
+</html>
+
diff --git a/dojo/tests/_base/loader/syncFromAsyncModule.js b/dojo/tests/_base/loader/syncFromAsyncModule.js
new file mode 100644
index 0000000..dfa725e
--- /dev/null
+++ b/dojo/tests/_base/loader/syncFromAsyncModule.js
@@ -0,0 +1,4 @@
+dojo.provide("dojo.tests._base.loader.syncFromAsyncModule");
+dojo.declare("dojo.tests._base.loader.syncFromAsyncModule", null, {});
+dojo.tests._base.loader.syncFromAsyncModule.status= "OK";
+dojo.require("dojo.tests._base.loader.syncFromAsyncModuleDep");
diff --git a/dojo/tests/_base/loader/syncFromAsyncModuleDep.js b/dojo/tests/_base/loader/syncFromAsyncModuleDep.js
new file mode 100644
index 0000000..e61fbba
--- /dev/null
+++ b/dojo/tests/_base/loader/syncFromAsyncModuleDep.js
@@ -0,0 +1,2 @@
+dojo.provide("dojo.tests._base.loader.syncFromAsyncModuleDep");
+dojo.tests._base.loader.syncFromAsyncModuleDep.status= "OK";
diff --git a/dojo/tests/_base/loader/syncModule.js b/dojo/tests/_base/loader/syncModule.js
new file mode 100644
index 0000000..bf3212d
--- /dev/null
+++ b/dojo/tests/_base/loader/syncModule.js
@@ -0,0 +1,9 @@
+if (typeof dojoCdnTestLog=="undefined"){
+	dojoCdnTestLog= [];
+}
+dojoCdnTestLog.push("in-dojo.tests._base.loader.syncModule");
+dojo.provide("dojo.tests._base.loader.syncModule");
+dojo.declare("dojo.tests._base.loader.syncModule", null, {});
+dojo.tests._base.loader.syncModule.status= "OK";
+dojo.require("dojo.tests._base.loader.syncModuleDep");
+dojoCdnTestLog.push("out-dojo.tests._base.loader.syncModule");
diff --git a/dojo/tests/_base/loader/syncModule1.js b/dojo/tests/_base/loader/syncModule1.js
new file mode 100644
index 0000000..39e8ce7
--- /dev/null
+++ b/dojo/tests/_base/loader/syncModule1.js
@@ -0,0 +1,5 @@
+dojoCdnTestLog.push("in-dojo.tests._base.loader.syncModule1");
+dojo.provide("dojo.tests._base.loader.syncModule1");
+dojo.tests._base.loader.syncModule1.status= "OK";
+dojo.require("dojo.tests._base.loader.syncModuleDep1");
+dojoCdnTestLog.push("out-dojo.tests._base.loader.syncModule1");
diff --git a/dojo/tests/_base/loader/syncModule2.js b/dojo/tests/_base/loader/syncModule2.js
new file mode 100644
index 0000000..b2e1430
--- /dev/null
+++ b/dojo/tests/_base/loader/syncModule2.js
@@ -0,0 +1,5 @@
+dojoCdnTestLog.push("in-dojo.tests._base.loader.syncModule2");
+dojo.provide("dojo.tests._base.loader.syncModule");
+dojo.tests._base.loader.syncModule.status= "OK";
+dojo.require("dojo.tests._base.loader.syncModuleDep");
+dojoCdnTestLog.push("out-dojo.tests._base.loader.syncModule2");
diff --git a/dojo/tests/_base/loader/syncModuleDep.js b/dojo/tests/_base/loader/syncModuleDep.js
new file mode 100644
index 0000000..496041a
--- /dev/null
+++ b/dojo/tests/_base/loader/syncModuleDep.js
@@ -0,0 +1,4 @@
+dojoCdnTestLog.push("in-dojo.tests._base.loader.syncModuleDep");
+dojo.provide("dojo.tests._base.loader.syncModuleDep");
+dojo.tests._base.loader.syncModuleDep.status= "OK";
+dojoCdnTestLog.push("out-dojo.tests._base.loader.syncModuleDep");
diff --git a/dojo/tests/_base/loader/syncModuleDep1.js b/dojo/tests/_base/loader/syncModuleDep1.js
new file mode 100644
index 0000000..82d11e7
--- /dev/null
+++ b/dojo/tests/_base/loader/syncModuleDep1.js
@@ -0,0 +1,4 @@
+dojoCdnTestLog.push("in-dojo.tests._base.loader.syncModuleDep1");
+dojo.provide("dojo.tests._base.loader.syncModuleDep1");
+dojo.tests._base.loader.syncModuleDep1.status= "OK";
+dojoCdnTestLog.push("out-dojo.tests._base.loader.syncModuleDep1");
diff --git a/dojo/tests/_base/loader/syncModuleDep2.js b/dojo/tests/_base/loader/syncModuleDep2.js
new file mode 100644
index 0000000..0d7f6b6
--- /dev/null
+++ b/dojo/tests/_base/loader/syncModuleDep2.js
@@ -0,0 +1,4 @@
+dojoCdnTestLog.push("in-dojo.tests._base.loader.syncModuleDep2");
+dojo.provide("dojo.tests._base.loader.syncModuleDep");
+dojo.tests._base.loader.syncModuleDep.status= "OK";
+dojoCdnTestLog.push("out-dojo.tests._base.loader.syncModuleDep2");
diff --git a/dojo/tests/_base/loader/traceApi.html b/dojo/tests/_base/loader/traceApi.html
new file mode 100644
index 0000000..9f82823
--- /dev/null
+++ b/dojo/tests/_base/loader/traceApi.html
@@ -0,0 +1,21 @@
+<html>
+<head>
+	<script type="text/javascript" src="../../../dojo.js" data-dojo-config="isDebug:1, async:1, trace:{'loader-run-factory':1}"></script>
+	<script type="text/javascript">
+		dojo.ready(function(){
+			console.log("in ready");
+			require.trace.set("loader-run-factory", 0);
+			require.trace.set("loader-define", 1);
+			require(["doh"], function(){
+				console.log("done loading DOH; turn tracing all off");
+				require.trace.set({"loader-define":0});
+				require(["dijit"], function(){
+					console.log("done loading dijit");
+				});
+			});
+		});
+	</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/xdomain/local1-browser-skip.js b/dojo/tests/_base/loader/xdomain/local1-browser-skip.js
new file mode 100644
index 0000000..32cb335
--- /dev/null
+++ b/dojo/tests/_base/loader/xdomain/local1-browser-skip.js
@@ -0,0 +1 @@
+xdomainExecSequence.push("dojo.tests._base.loader.xdomain.local1-browser-skip-1");
diff --git a/dojo/tests/_base/loader/xdomain/local1-browser.js b/dojo/tests/_base/loader/xdomain/local1-browser.js
new file mode 100644
index 0000000..bb1fd4b
--- /dev/null
+++ b/dojo/tests/_base/loader/xdomain/local1-browser.js
@@ -0,0 +1,4 @@
+xdomainExecSequence.push("dojo.tests._base.loader.xdomain.local1-browser-1");
+var x1= dojo.provide("dojo.tests._base.loader.xdomain.local1-browser");
+dojo.getObject("dojo.tests._base.loader.xdomain.local1-browser").status= "dojo.tests._base.loader.xdomain.local1-browser-ok";
+xdomainExecSequence.push("dojo.tests._base.loader.xdomain.local1-browser-2");
diff --git a/dojo/tests/_base/loader/xdomain/local1-dep.js b/dojo/tests/_base/loader/xdomain/local1-dep.js
new file mode 100644
index 0000000..08a2b03
--- /dev/null
+++ b/dojo/tests/_base/loader/xdomain/local1-dep.js
@@ -0,0 +1,4 @@
+xdomainExecSequence.push("local1-dep-1");
+var x1= dojo.provide("dojo.tests._base.loader.xdomain.local1-dep");
+dojo.getObject("dojo.tests._base.loader.xdomain.local1-dep").status= "dojo.tests._base.loader.xdomain.local1-dep-ok";
+xdomainExecSequence.push("local1-dep-2");
diff --git a/dojo/tests/_base/loader/xdomain/local1-runtimeDependent1.js b/dojo/tests/_base/loader/xdomain/local1-runtimeDependent1.js
new file mode 100644
index 0000000..d52720d
--- /dev/null
+++ b/dojo/tests/_base/loader/xdomain/local1-runtimeDependent1.js
@@ -0,0 +1,4 @@
+xdomainExecSequence.push("dojo.tests._base.loader.xdomain.local1-runtimeDependent1-1");
+var x1= dojo.provide("dojo.tests._base.loader.xdomain.local1-runtimeDependent1");
+dojo.getObject("dojo.tests._base.loader.xdomain.local1-runtimeDependent1").status= "dojo.tests._base.loader.xdomain.local1-runtimeDependent1-ok";
+xdomainExecSequence.push("dojo.tests._base.loader.xdomain.local1-runtimeDependent1-2");
diff --git a/dojo/tests/_base/loader/xdomain/local1.js b/dojo/tests/_base/loader/xdomain/local1.js
new file mode 100644
index 0000000..a0a3168
--- /dev/null
+++ b/dojo/tests/_base/loader/xdomain/local1.js
@@ -0,0 +1,82 @@
+xdomainExecSequence.push("local1-1");
+
+// multiple dojo.provides should define multiple modules
+var x1= dojo.provide("dojo.tests._base.loader.xdomain.local1");
+var x2= dojo.provide("dojo.tests._base.loader.xdomain.local1SteppedOn");
+var x3= dojo.provide("dojo.tests._base.loader.xdomain.local1NotSteppedOn");
+xdomainExecSequence.push("local1-2");
+
+// this puts the loader in xd loading mode
+dojo.require("dojo.cookie");
+xdomainExecSequence.push("local1-3");
+
+// load a not xd module while in xd loading mode
+dojo.require("dojo.tests._base.loader.xdomain.local1-dep");
+xdomainExecSequence.push("local1-4");
+
+// a loadInit that makes a calculation a later requireIf depends upon
+dojo.loadInit(function(){
+	xdomainExecSequence.push("local1-5");
+	var dependentModule= dojo.getObject("dojo.tests._base.loader.xdomain.local1-runtimeDependent", true);
+	dependentModule.choice = 1;
+});
+xdomainExecSequence.push("local1-6");
+
+// a couple of requireIf's, only one of which should result in a module being loaded
+dojo.requireIf(dojo.getObject("dojo.tests._base.loader.xdomain.local1-runtimeDependent").choice==1, "dojo.tests._base.loader.xdomain.local1-runtimeDependent1");
+xdomainExecSequence.push("local1-7");
+dojo.requireIf(dojo.getObject("dojo.tests._base.loader.xdomain.local1-runtimeDependent").choice==2, "dojo.tests._base.loader.xdomain.local1-runtimeDependent2");
+xdomainExecSequence.push("local1-8");
+
+// platformRequire test
+dojo.platformRequire({
+	browser:[
+		"dojo.tests._base.loader.xdomain.local1-browser",
+		["dojo.tests._base.loader.xdomain.local1-browser-skip", true]
+	]
+});
+
+// these are xd bundles which should be loaded async
+xdomainExecSequence.push("local1-9");
+dojo.requireLocalization("dojo", "colors");
+xdomainExecSequence.push("local1-10");
+dojo.requireLocalization("dojo", "colors", "fr");
+xdomainExecSequence.push("local1-11");
+dojo.requireLocalization("dojo", "colors");
+xdomainExecSequence.push("local1-12");
+
+// these are not xd bundles which should be loaded sync
+dojo.requireLocalization("dojo.tests._base.loader", "amdBundle");
+xdomainExecSequence.push("local1-13");
+dojo.requireLocalization("dojo.tests._base.loader", "amdBundle", "ab");
+xdomainExecSequence.push("local1-14");
+dojo.requireLocalization("dojo.tests._base.loader", "syncBundle");
+xdomainExecSequence.push("local1-15");
+dojo.requireLocalization("dojo.tests._base.loader", "syncBundle", "ab");
+xdomainExecSequence.push("local1-16");
+
+// another loadInit; it should be executed immediately after the first load init
+dojo.loadInit(function(){
+	xdomainExecSequence.push("local1-17");
+	var dependentModule= dojo.getObject("dojo.tests._base.loader.xdomain.local1-runtimeDependent");
+	dependentModule.status = "ok";
+});
+xdomainExecSequence.push("local1-18");
+
+xdomainLog.push(
+1, (x1===dojo.tests._base.loader.xdomain.local1),
+2, (x1===dojo.getObject("dojo.tests._base.loader.xdomain.local1")),
+3, (x2===dojo.tests._base.loader.xdomain.local1SteppedOn),
+4, (x2===dojo.getObject("dojo.tests._base.loader.xdomain.local1SteppedOn")),
+5, (x3===dojo.tests._base.loader.xdomain.local1NotSteppedOn),
+6, (x3===dojo.getObject("dojo.tests._base.loader.xdomain.local1NotSteppedOn")));
+
+x3.status = "local1NotSteppedOn";
+dojo.tests._base.loader.xdomain.local1= "stepOnLocal1";
+dojo.tests._base.loader.xdomain.local1SteppedOn= "stepOn1SteppedOn";
+
+xdomainLog.push(
+7, ("stepOnLocal1"===dojo.tests._base.loader.xdomain.local1),
+8, ("stepOnLocal1"===dojo.getObject("dojo.tests._base.loader.xdomain.local1")),
+9, ("stepOn1SteppedOn"===dojo.tests._base.loader.xdomain.local1SteppedOn),
+10, ("stepOn1SteppedOn"===dojo.getObject("dojo.tests._base.loader.xdomain.local1SteppedOn")));
diff --git a/dojo/tests/_base/loader/xdomain/local2.js b/dojo/tests/_base/loader/xdomain/local2.js
new file mode 100644
index 0000000..7b8770c
--- /dev/null
+++ b/dojo/tests/_base/loader/xdomain/local2.js
@@ -0,0 +1,13 @@
+xdomainExecSequence.push("local2-1");
+dojo.provide("dojo.tests._base.loader.xdomain.local2");
+xdomainExecSequence.push("local2-2");
+
+// put the loader in xdomain loading mode
+dojo.require("dojo.hash");
+xdomainExecSequence.push("local2-3");
+
+// load a local module that will have to be transformed
+dojo.require("dojo.tests._base.loader.xdomain.local3");
+xdomainExecSequence.push("local2-4");
+
+dojo.tests._base.loader.xdomain.local2.status = "local2-loaded";
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/xdomain/local3.js b/dojo/tests/_base/loader/xdomain/local3.js
new file mode 100644
index 0000000..940aaf5
--- /dev/null
+++ b/dojo/tests/_base/loader/xdomain/local3.js
@@ -0,0 +1,10 @@
+xdomainExecSequence.push("local3-1");
+dojo.provide("dojo.tests._base.loader.xdomain.local3");
+xdomainExecSequence.push("local3-2");
+
+// load a local module that will have to be transformed
+//debugger;
+dojo.require("dojo.tests._base.loader.xdomain.local1");
+xdomainExecSequence.push("local3-3");
+
+dojo.tests._base.loader.xdomain.local3.status = "local3-loaded";
diff --git a/dojo/tests/_base/loader/xdomain/xdomain.html b/dojo/tests/_base/loader/xdomain/xdomain.html
new file mode 100644
index 0000000..cf19527
--- /dev/null
+++ b/dojo/tests/_base/loader/xdomain/xdomain.html
@@ -0,0 +1,290 @@
+<html>
+<head>
+	<script type="text/javascript">
+	  var dohArgs= (window.parent.doh && window.parent.doh.dohArgs) || {async:0, variation:2};
+
+	  // for test debuggin...
+	  //dohArgs = {async:0, variation:1}
+	  //dohArgs = {async:"legacyAsync", variation:1}
+	  //dohArgs = {async:0, variation:2}
+	  //dohArgs = {async:"legacyAsync", variation:2}
+
+	  var dojoConfig = {
+		async:dohArgs.async
+	  }
+	  var expectedSequence;
+	  
+	  var built = 1;
+	  //>>excludeStart("srcVersion", kwArgs.copyTests=="build");
+	  built = 0;
+	  //>>excludeEnd("srcVersion");
+	  if((dohArgs.async=="legacyAsync" || built) && dohArgs.variation==2){
+		expectedSequence = [
+			"local1-5",
+			"local1-17",
+			"local2-1",
+			"local2-2",
+			"local2-3",
+			"local3-1",
+			"local3-2",
+			"local1-1",
+			"local1-2",
+			"local1-3",
+			"local1-dep-1",
+			"local1-dep-2",
+			"local1-4",
+			"local1-6",
+			"dojo.tests._base.loader.xdomain.local1-runtimeDependent1-1",
+			"dojo.tests._base.loader.xdomain.local1-runtimeDependent1-2",
+			"local1-7",
+			"local1-8",
+			"dojo.tests._base.loader.xdomain.local1-browser-1",
+			"dojo.tests._base.loader.xdomain.local1-browser-2",
+			"dojo.tests._base.loader.xdomain.local1-browser-skip-1",
+			"local1-9",
+			"local1-10",
+			"local1-11",
+			"local1-12",
+			"local1-13",
+			"local1-14",
+			"local1-15",
+			"local1-16",
+			"local1-18",
+			"local3-3",
+			"local2-4"].join(";");
+	  }else if(dohArgs.async==0 && dohArgs.variation==2){
+		expectedSequence = [
+			"local2-1",
+			"local2-2",
+			"local2-3",
+			"local2-4",
+			"local1-5",
+			"local1-17",
+			"local3-1",
+			"local3-2",
+			"local1-1",
+			"local1-2",
+			"local1-3",
+			"local1-dep-1",
+			"local1-dep-2",
+			"local1-4",
+			"local1-6",
+			"dojo.tests._base.loader.xdomain.local1-runtimeDependent1-1",
+			"dojo.tests._base.loader.xdomain.local1-runtimeDependent1-2",
+			"local1-7",
+			"local1-8",
+			"dojo.tests._base.loader.xdomain.local1-browser-1",
+			"dojo.tests._base.loader.xdomain.local1-browser-2",
+			"dojo.tests._base.loader.xdomain.local1-browser-skip-1",
+			"local1-9",
+			"local1-10",
+			"local1-11",
+			"local1-12",
+			"local1-13",
+			"local1-14",
+			"local1-15",
+			"local1-16",
+			"local1-18",
+			"local3-3"].join(";");
+	  }else if((dohArgs.async=="legacyAsync" || built) && dohArgs.variation==1){
+		expectedSequence = [
+			"local1-5",
+			"local1-17",
+			"local1-1",
+			"local1-2",
+			"local1-3",
+			"local1-dep-1",
+			"local1-dep-2",
+			"local1-4",
+			"local1-6",
+			"dojo.tests._base.loader.xdomain.local1-runtimeDependent1-1",
+			"dojo.tests._base.loader.xdomain.local1-runtimeDependent1-2",
+			"local1-7",
+			"local1-8",
+			"dojo.tests._base.loader.xdomain.local1-browser-1",
+			"dojo.tests._base.loader.xdomain.local1-browser-2",
+			"dojo.tests._base.loader.xdomain.local1-browser-skip-1",
+			"local1-9",
+			"local1-10",
+			"local1-11",
+			"local1-12",
+			"local1-13",
+			"local1-14",
+			"local1-15",
+			"local1-16",
+			"local1-18"].join(";");
+	  }else if(dohArgs.async==0 && dohArgs.variation==1){
+		expectedSequence = [
+			"local1-1",
+			"local1-2",
+			"local1-3",
+			"local1-4",
+			"local1-5",
+			"local1-6",
+			"local1-7",
+			"local1-8",
+			"local1-9",
+			"local1-10",
+			"local1-11",
+			"local1-12",
+			"local1-13",
+			"local1-14",
+			"local1-15",
+			"local1-16",
+			"local1-17",
+			"local1-18",
+			"local1-dep-1",
+			"local1-dep-2",
+			"dojo.tests._base.loader.xdomain.local1-runtimeDependent1-1",
+			"dojo.tests._base.loader.xdomain.local1-runtimeDependent1-2",
+			"dojo.tests._base.loader.xdomain.local1-browser-1",
+			"dojo.tests._base.loader.xdomain.local1-browser-2",
+			"dojo.tests._base.loader.xdomain.local1-browser-skip-1"].join(";");
+	  }
+	</script>
+	<script type="text/javascript" src="../../../../dojo.js"></script>
+	<script type="text/javascript">
+	    define("dijit", ["dojo"], function(dojo){ return dojo.dijit; });
+	    define("dojox", ["dojo"], function(dojo){ return dojo.dojox; });
+
+
+
+		var xdomainLog= [], xdomainExecSequence= [];
+
+		require(["dojo", "doh", "dojo/has"], function(dojo, doh, has){ 
+			if(!("legacyMode" in require)){
+				doh.register("xdomain", function(t){
+					t.is("dojotoolkit.org", define.vendor);
+					t.is(true, "legacyMode" in require);
+				});
+				doh.runOnLoad();
+				return;
+		    }
+
+			// pretend that everything except the stuff in dojo/tests/_base/loader/xdomain is xdomain
+			require.isXdUrl = function(url){
+				return !/loader\/xdomain/.test(url);
+			};
+
+			// each of these dojo.requires a xdomain module which puts the loader in xdomain loading mode,
+		    // then dojo.requires a local tree of modules with various loading challenges. Many of the loading
+			// challenges are in local1; therefore we test when that module causes the xdomain shift and when
+			// the loader is already in xdomain when that module is demanded
+			if(dohArgs.variation==1){
+				dojo.require("dojo.tests._base.loader.xdomain.local1");
+				//>>excludeStart("srcVersion", kwArgs.copyTests=="build");
+				if(dohArgs.async==0){
+					// can't stop the local module from completely executing...
+					xdomainLog.push(11, dojo.tests._base.loader.xdomain.local1==="stepOnLocal1");
+					xdomainLog.push(12, dojo.require("dojo.tests._base.loader.xdomain.local1")==="stepOnLocal1");
+					xdomainLog.push(13, require("dojo/tests/_base/loader/xdomain/local1")==="stepOnLocal1");
+				}else{
+					xdomainLog.push(11, dojo.getObject("dojo.tests._base.loader.xdomain.local1")===undefined);
+				}
+				//>>excludeEnd("srcVersion");
+			}else{
+				dojo.require("dojo.tests._base.loader.xdomain.local2");
+				//>>excludeStart("srcVersion", kwArgs.copyTests=="build");
+				if(dohArgs.async==0){
+					// can't stop the local module from completely executing...
+					xdomainLog.push(11, dojo.tests._base.loader.xdomain.local2.status==="local2-loaded");
+					xdomainLog.push(12, dojo.require("dojo.tests._base.loader.xdomain.local2").status==="local2-loaded");
+					xdomainLog.push(13, require("dojo/tests/_base/loader/xdomain/local2").status==="local2-loaded");
+				}else{
+					xdomainLog.push(11, dojo.getObject("dojo.tests._base.loader.xdomain.local2")===undefined);
+				}
+				xdomainLog.push(16,	dojo.getObject("dojo.tests._base.loader.xdomain.local1")===undefined);
+				if(dojo.isIE!=6){
+					try{
+						require("dojo/tests/_base/loader/xdomain/local1");
+						xdomainLog.push(19, false);
+					}catch(e){
+						xdomainLog.push(19, true);
+					}
+				}
+				//>>excludeEnd("srcVersion");
+			}
+
+
+			// but none of the modules after going into xdomain loading should be executed
+			// (WARNING: ie might look different because of its strange caching behavior)
+			xdomainLog.push(14, (dojo.hash===undefined));
+			xdomainLog.push(15, (dojo.cookie===undefined));
+			xdomainLog.push(17, dojo.getObject("dojo.tests._base.loader.xdomain.local3")===undefined);
+			if(dojo.isIE!=6){
+				try{
+					require("dojo/tests/_base/loader/xdomain/local3");
+					xdomainLog.push(18, false);
+				}catch(e){
+					xdomainLog.push(18, true);
+				}
+			}
+
+			doh.register("xdomain", function(t){
+				//console.log(xdomainExecSequence.join(";"));
+				for(var i= 0; i<xdomainLog.length; i+= 2){
+					t.is(true, xdomainLog[i+1], "failed at id="+xdomainLog[i]);
+				}
+
+				t.is(expectedSequence, xdomainExecSequence.join(";"));
+
+				t.is("stepOnLocal1", dojo.tests._base.loader.xdomain.local1);
+				t.is("stepOnLocal1", dojo.getObject("dojo.tests._base.loader.xdomain.local1"));
+				t.is("stepOnLocal1", dojo.require("dojo.tests._base.loader.xdomain.local1"));
+				t.is("stepOnLocal1", require("dojo/tests/_base/loader/xdomain/local1"));
+
+				t.is("stepOn1SteppedOn", dojo.tests._base.loader.xdomain.local1SteppedOn);
+				t.is("stepOn1SteppedOn", dojo.getObject("dojo.tests._base.loader.xdomain.local1SteppedOn"));
+				t.is("stepOn1SteppedOn", dojo.require("dojo.tests._base.loader.xdomain.local1SteppedOn"));
+				t.is("stepOn1SteppedOn", require("dojo/tests/_base/loader/xdomain/local1SteppedOn"));
+
+				t.is("local1NotSteppedOn", dojo.tests._base.loader.xdomain.local1NotSteppedOn.status);
+				t.is("local1NotSteppedOn", dojo.getObject("dojo.tests._base.loader.xdomain.local1NotSteppedOn.status"));
+				t.is("local1NotSteppedOn", dojo.require("dojo.tests._base.loader.xdomain.local1NotSteppedOn").status);
+				t.is("local1NotSteppedOn", require("dojo/tests/_base/loader/xdomain/local1NotSteppedOn").status);
+
+				t.is("dojo.tests._base.loader.xdomain.local1-dep-ok", dojo.tests._base.loader.xdomain["local1-dep"].status);
+				t.is("dojo.tests._base.loader.xdomain.local1-dep-ok", dojo.getObject("dojo.tests._base.loader.xdomain.local1-dep.status"));
+				t.is("dojo.tests._base.loader.xdomain.local1-dep-ok", dojo.require("dojo.tests._base.loader.xdomain.local1-dep").status);
+				t.is("dojo.tests._base.loader.xdomain.local1-dep-ok", require("dojo/tests/_base/loader/xdomain/local1-dep").status);
+
+				t.is("dojo.tests._base.loader.xdomain.local1-runtimeDependent1-ok", dojo.tests._base.loader.xdomain["local1-runtimeDependent1"].status);
+				t.is("dojo.tests._base.loader.xdomain.local1-runtimeDependent1-ok", dojo.getObject("dojo.tests._base.loader.xdomain.local1-runtimeDependent1.status"));
+				t.is("dojo.tests._base.loader.xdomain.local1-runtimeDependent1-ok", dojo.require("dojo.tests._base.loader.xdomain.local1-runtimeDependent1").status);
+				t.is("dojo.tests._base.loader.xdomain.local1-runtimeDependent1-ok", require("dojo/tests/_base/loader/xdomain/local1-runtimeDependent1").status);
+
+				t.is("ok", dojo.getObject("dojo.tests._base.loader.xdomain.local1-runtimeDependent").status);
+
+				t.is(undefined, dojo.tests._base.loader.xdomain["local1-runtimeDependent2"]);
+				t.is(undefined, dojo.getObject("dojo.tests._base.loader.xdomain.local1-runtimeDependent2"));
+			    try{
+    				require("dojo/tests/_base/loader/xdomain/local1/runtimeDependent2");
+		            t.is(1, 0);
+    			}catch(e){
+		            t.is(1, 1);
+    			}
+
+				t.is("dojo.tests._base.loader.xdomain.local1-browser-ok", dojo.tests._base.loader.xdomain["local1-browser"].status);
+				t.is("dojo.tests._base.loader.xdomain.local1-browser-ok", dojo.getObject("dojo.tests._base.loader.xdomain.local1-browser.status"));
+				t.is("dojo.tests._base.loader.xdomain.local1-browser-ok", dojo.require("dojo.tests._base.loader.xdomain.local1-browser").status);
+				t.is("dojo.tests._base.loader.xdomain.local1-browser-ok", require("dojo/tests/_base/loader/xdomain/local1-browser").status);
+
+				t.isNot(undefined, dojo.cookie);
+				t.is(dojo.cookie, dojo.getObject("dojo.cookie"));
+				t.is(dojo.cookie, require("dojo/cookie"));
+												   
+				if(dohArgs.variation!=1){
+					t.isNot(undefined, dojo.hash);
+					t.is(dojo.hash, dojo.getObject("dojo.hash"));
+					t.is(dojo.hash, require("dojo/hash"));
+				}
+			});
+			doh.runOnLoad();
+		});
+	</script>
+</head>
+<body>
+  <h1>check console</h1>
+  <p>This test loads a not-xdomain module that contains a xdomain and a not-xdomain module</p>
+</body>
+</html>
diff --git a/dojo/tests/_base/object.js b/dojo/tests/_base/object.js
index bc0cea2..16cb38c 100644
--- a/dojo/tests/_base/object.js
+++ b/dojo/tests/_base/object.js
@@ -1,37 +1,37 @@
-dojo.provide("tests._base.object");
+dojo.provide("dojo.tests._base.object");
 
 // setup the test object
 dojo.zoo = { a:1, c: { d:1 } };
 
 tests.register("tests._base.object",
 	[
-	
+
 		function getBasic(t){
 			var x = dojo.getObject('dojo.zoo.a');
 			t.is(1, x);
 		},
-			
+
 		function setObject2(t){
 			dojo.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);
 			t.is("foo!", dojo.zoo.c.x);
 		},
-				
+
 		function getUndefined(t){
 			var x = dojo.getObject('dojo.zoo.b');
 			t.is(undefined, x);
 		},
-				
+
 		function setDeep(t){
 			dojo.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);
 			dojo.zoo.bar.baz.bam.x = 10;
diff --git a/dojo/tests/_base/query.html b/dojo/tests/_base/query.html
index 86bc09b..ce4f208 100644
--- a/dojo/tests/_base/query.html
+++ b/dojo/tests/_base/query.html
@@ -4,29 +4,98 @@
 		<style type="text/css">
 			@import "../../resources/dojo.css";
 		</style>
-		<script type="text/javascript" src="../../dojo.js" 
-			djConfig="isDebug: true, debugAtAllCosts: false, popup: false, noFirebugLite: true"></script>
-		<!--
-		<script type="text/javascript" src="../_base/query.js"></script>
-		-->
-		<script type="text/javascript" src="../../../util/doh/runner.js"></script>
+		<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript">
-			dojo.require("doh.runner");
-			dojo.require("dojo.io.iframe");
-
-			function createDocument(xml){
-				var fauxXhr = { responseText: xml };
-				if("DOMParser" in dojo.global){
-					var parser = new DOMParser();
-					fauxXhr.responseXML = parser.parseFromString(xml, "text/xml");
+			require(["dojo", "doh", "dojo/query!lite", "dojo/io/iframe", "dojo/domReady!"], function(dojo, doh, query){
+				queryLite = query; // 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
 				}
-				// kludge: use dojo.xhr contentHandler for XML to process IE XMLDOC as needed
-				return dojo._contentHandlers["xml"](fauxXhr); // DOMDocument
-			}
 
-			dojo.addOnLoad(function(){
 				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(); })",
@@ -36,7 +105,7 @@
 						"doh.is(1, (dojo.query('h1:first-child')).length);",
 						"doh.is(2, (dojo.query('h3:first-child')).length);",
 						"doh.is(1, (dojo.query('#t')).length);",
-						"doh.is(1, (dojo.query('#bug')).length);",
+						//"doh.is(1, (dojo.query('#bug')).length);",
 						"doh.is(4, (dojo.query('#t h3')).length);",
 						"doh.is(1, (dojo.query('div#t')).length);",
 						"doh.is(4, (dojo.query('div#t h3')).length);",
@@ -90,7 +159,7 @@
 						"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);",
-						"doh.is(1, (dojo.query('[foo|=\"bar\"]')).length);",
+						"doh.is(2, (dojo.query('[foo|=\"bar\"]')).length);",
 						"doh.is(1, (dojo.query('[foo|=\"bar-baz\"]')).length);",
 						"doh.is(0, (dojo.query('[foo|=\"baz\"]')).length);",
 						"doh.is(dojo.byId('_foo'), dojo.query('.foo:nth-child(2)')[0]);",
@@ -98,6 +167,7 @@
 
 						// descendant selectors
 						"doh.is(3, dojo.query('>', 'container').length);",
+						"doh.is(0, dojo.query('> .not-there').length);",
 						"doh.is(3, dojo.query('> *', 'container').length);",
 						"doh.is(2, dojo.query('> [qux]', 'container').length);",
 						"doh.is('child1', dojo.query('> [qux]', 'container')[0].id);",
@@ -249,8 +319,8 @@
 						function xml_attrs(){
 							var doc = createDocument([
 								"<ResultSet>",
-									"<RESULT thinger='blah'>Two</RESULT>",
-									"<RESULT thinger='gadzooks'>Two</RESULT>",
+									"<RESULT thinger='blah'>ONE</RESULT>",
+									"<RESULT thinger='gadzooks'><CHILD>Two</CHILD></RESULT>",
 								"</ResultSet>"
 							].join(""));
 							var de = doc.documentElement;
@@ -259,15 +329,21 @@
 							doh.is(0, dojo.query("RESULT[THINGER]", de).length, "result elements with attrs (wrong)");
 							doh.is(2, dojo.query("RESULT[thinger]", de).length, "result elements with attrs");
 							doh.is(1, dojo.query("RESULT[thinger=blah]", de).length, "result elements with attr value");
+							doh.is(1, dojo.query("RESULT > CHILD", de).length, "Using child operator");
 						},
 						function sort(){
 							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');
+							}
 						}
 					]
 				);
-				doh.run();
+				doh.runOnLoad();
 			});
 		</script>
 	</head>
diff --git a/dojo/tests/_base/query.js b/dojo/tests/_base/query.js
index 1cc3f16..5a4b135 100644
--- a/dojo/tests/_base/query.js
+++ b/dojo/tests/_base/query.js
@@ -1,5 +1,6 @@
-dojo.provide("tests._base.query");
-if(dojo.isBrowser){
-	doh.registerUrl("tests._base.query", dojo.moduleUrl("tests", "_base/query.html"), 60000);
-	doh.registerUrl("tests._base.NodeList", dojo.moduleUrl("tests", "_base/NodeList.html"), 60000);
-}
+define(["doh", "require"], function(doh, require){
+	if(doh.isBrowser){
+		doh.register("tests._base.query", require.toUrl("./query.html"), 60000);
+		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 8a2cac8..7882e28 100644
--- a/dojo/tests/_base/scrollingIframe.js
+++ b/dojo/tests/_base/scrollingIframe.js
@@ -9,7 +9,6 @@ function runScrollingTest(resultNode){
 		dojo = win.dojo;
 	}
 	var isLtr = dojo.hitch(dojo, "withGlobal")(window, "_isBodyLtr", dojo, []);
-	document.getElementById("mode").innerHTML = (isQuirks ? "quirks " : "strict ") + (isLtr ? "ltr" : "rtl");
 	var root = isQuirks? document.body : document.documentElement;
 	var control = document.getElementById("control");
 	var clientWidth = document.getElementById("clientWidth");
@@ -25,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 && root.clientWidth - cw.w == cw.x)){
 				if(abs1.offsetLeft == control.offsetLeft){
 					if(abs1.offsetTop == control.offsetTop){
 						resultNode.testResult = "EQUAL";
@@ -36,7 +35,7 @@ function runScrollingTest(resultNode){
 					resultNode.testResult = "abs1.offsetLeft="+abs1.offsetLeft + " control.offsetLeft="+control.offsetLeft;
 				}
 			}else{
-				resultNode.testResult = "100% width element start/size=" + cw.x+'/'+cw.w + " frame client width="+root.clientWidth;
+				resultNode.testResult = "100% width element start/size=" + cw.x+'/'+cw.w + " frame client left/width="+root.clientLeft+'/'+root.clientWidth;
 			}
 			if(resultNode.resultReady){ resultNode.resultReady(); }
 		}, 100);
@@ -45,9 +44,7 @@ function runScrollingTest(resultNode){
 
 function genScrollingTestNodes(hScroll, vScroll, large){
 	document.write(
-		'<DIV id="clientWidth" style="background-color:black;"> </DIV>' +
 		'<DIV id="abs1" style="position:absolute;background-color:red;left:0;top:0;width:1em;font-family:monospace;font-size:16px;"> </DIV>' +
-		'<CENTER id="mode"></CENTER>' +
 		'<DIV id="control" style="width:2em;height:2em;font-family:monospace;font-size:16px;background-color:cyan;margin:0 1em;border:0;padding:0;">  </DIV>' +
 		( large
 			? (
@@ -91,7 +88,8 @@ function genScrollingTestBody(){
 	}else if(!isQuirks && !options.large){
 		html.style.overflowY = scroll;
 	}
-	document.write('<BODY style="position:relative;margin:0;padding:0;border:0;background-color:white;overflow-x:' + (options.horz ? (isQuirks ? scroll : '') : 'hidden') + ';overflow-y:' + (isQuirks ? (options.vert ? scroll : 'hidden') : '') + ';">');
+	document.write('<BODY style="height:100%;margin:0;padding:0;border:0;background-color:white;overflow-x:' + (options.horz ? (isQuirks ? scroll : '') : 'hidden') + ';overflow-y:' + (isQuirks ? (options.vert ? scroll : 'hidden') : '') + ';">');
+	document.write('<DIV id="clientWidth"><CENTER>'+(isQuirks?'quirks ':'strict ')+(options.horz?'horiz ':'')+(options.vert?'vert ':'')+(options.large?'scrolling ':'')+options.dir+'</CENTER></DIV>');
 	genScrollingTestNodes(options.horz, options.vert, options.large);
 	document.write('</BODY>');
 }
@@ -100,5 +98,6 @@ if(!document.body){
 	frameElement.runScrollingTest = runScrollingTest;
 	genScrollingTestBody();
 }else{
+	document.write('<DIV id="clientWidth" style="background-color:transparent;"> </DIV>');
 	genScrollingTestNodes();
 }
diff --git a/dojo/tests/_base/timeout.php b/dojo/tests/_base/timeout.php
index 560b0d3..4eeb35c 100644
--- a/dojo/tests/_base/timeout.php
+++ b/dojo/tests/_base/timeout.php
@@ -1,6 +1,6 @@
 <?php
 
-$callbackName = $_REQUEST["callback"];
+$callbackName = htmlspecialchars($_REQUEST["callback"]);
 sleep(5);
 print "SuperXFooBarVariable = 'Oh no! SuperXFooBarVariable is defined (should not be for timeout case).'; {$callbackName}({Status: 'good'});";
 
diff --git a/dojo/tests/_base/window.html b/dojo/tests/_base/window.html
new file mode 100644
index 0000000..ce6ee80
--- /dev/null
+++ b/dojo/tests/_base/window.html
@@ -0,0 +1,104 @@
+<html>
+	<head>
+		<title>withDoc test</title>
+		<style type="text/css">
+iframe {
+	width: 100%;
+	height: 120px;
+}
+		</style>
+	<body>
+		<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"],
+function(dojo, doh, domConstruct, has, win){
+	var
+		fStandards, fQuirks, // iframes used for tests
+		tests, numFrames = 2, framesLoaded = 0;
+	
+	frameLoaded = function(){
+		// Called by each child frame.
+		// Tests start running when all iframes are loaded.
+		if(++framesLoaded == numFrames){
+			doh.run();
+		}
+	};
+	
+	tests = [
+		function withDoc(t){
+			var d = fQuirks.contentWindow.document, finished,
+				thisObj = {test: "myThis"};
+			
+			dojo.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");
+				finished = true;
+			}, thisObj, [1, 2]);
+			
+			t.t(finished, "Did withDoc test function complete?");
+			t.is(document, dojo.doc, "dojo.doc should be restored");
+		},
+		function withGlobal(t){
+			var w = fQuirks.contentWindow, finished,
+				thisObj = {test: "myThis"};
+			
+			dojo.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");
+				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");
+		},
+		function isQuirks(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(origQuirks === dojo.isQuirks && origQuirks === has("quirks"),
+				"dojo.isQuirks / 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.t(origQuirks === dojo.isQuirks && origQuirks === has("quirks"),
+				"dojo.isQuirks / 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){
+			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");
+			});
+			t.t(origIE === dojo.isIE && origIE === has("ie"),
+				"dojo.isIE / has('ie') should be reset to initial value");
+		});
+	}
+
+	doh.register("_base/window", tests);
+	
+	// Add iframe to page w/ document in standards mode
+	fStandards = domConstruct.create("iframe", {
+		src: "window_iframe_standards.html"
+	}, document.body);
+	// Add iframe to page w/ document in quirks mode
+	fQuirks = domConstruct.create("iframe", {
+		src: "window_iframe_quirks.html"
+	}, document.body);
+});
+		</script>
+	</body>
+</html>
diff --git a/dojo/tests/_base/window.js b/dojo/tests/_base/window.js
index c0f6941..cd4ea2b 100644
--- a/dojo/tests/_base/window.js
+++ b/dojo/tests/_base/window.js
@@ -1,52 +1,5 @@
-dojo.provide("tests._base.window");
-
-tests.register("tests._base.window",
-	[
-		function withGlobal(t){
-			var arg1, arg2, innerThis, innerGlobal, innerDoc, finished,
-				globalObj = {test: "myGlobal", document: {test: "myDoc"}},
-				thisObj = {test: "myThis"};
-
-			try {
-				dojo.withGlobal(globalObj, function(a1, a2){
-					arg1 = a1;
-					arg2 = a2;
-					innerThis = this.test;
-					innerGlobal = dojo.global.test;
-					innerDoc = dojo.doc.test
-					finished = true;
-				}, thisObj, [1, 2])
-			}catch(e){}
-
-			t.assertTrue(finished);
-			t.assertEqual(1, arg1);
-			t.assertEqual(2, arg2);
-			t.assertEqual("myThis", innerThis);
-			t.assertEqual("myGlobal", innerGlobal);
-			t.assertEqual("myDoc", innerDoc);
-		},
-
-		function withDoc(t){
-			var arg1, arg2, innerThis, innerGlobal, innerDoc, finished,
-				docObj = {test: "myDoc"},
-				thisObj = {test: "myThis"};
-
-			try {
-				dojo.withDoc(docObj, function(a1, a2){
-					arg1 = a1;
-					arg2 = a2;
-					innerThis = this.test;
-					innerDoc = dojo.doc.test
-					finished = true;
-				}, thisObj, [1, 2])
-			}catch(e){}
-
-			t.assertTrue(finished);
-			t.assertEqual(1, arg1);
-			t.assertEqual(2, arg2);
-			t.assertEqual("myThis", innerThis);
-			t.assertEqual("myDoc", innerDoc);
-		}
-	]
-);
-
+define(["doh", "require"], function(doh, require){
+	if(doh.isBrowser){
+		doh.register("tests._base.window", require.toUrl("./window.html"), 15000);
+	}
+});
diff --git a/dojo/tests/_base/window_iframe_quirks.html b/dojo/tests/_base/window_iframe_quirks.html
new file mode 100644
index 0000000..3d5ea5c
--- /dev/null
+++ b/dojo/tests/_base/window_iframe_quirks.html
@@ -0,0 +1,11 @@
+<html>
+<body onload="parent.frameLoaded && parent.frameLoaded();">
+	Quirks mode frame
+	<script type="text/javascript">
+var answer = 42;
+var div = document.createElement("div");
+div.innerHTML = "appVersion: " + navigator.appVersion +
+	"<br>documentMode: " + document.documentMode;
+document.body.appendChild(div);
+	</script>
+</body></html>
diff --git a/dojo/tests/_base/window_iframe_standards.html b/dojo/tests/_base/window_iframe_standards.html
new file mode 100644
index 0000000..88abebc
--- /dev/null
+++ b/dojo/tests/_base/window_iframe_standards.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>Standards mode frame</title>
+	<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+</head>
+<body onload="parent.frameLoaded && parent.frameLoaded();">
+	Standards mode frame
+	<script type="text/javascript">
+var div = document.createElement("div");
+div.innerHTML = "appVersion: " + navigator.appVersion +
+	"<br>documentMode: " + document.documentMode;
+document.body.appendChild(div);
+	</script>
+</body></html>
diff --git a/dojo/tests/_base/xhr.html b/dojo/tests/_base/xhr.html
index 6d275d1..027ed56 100644
--- a/dojo/tests/_base/xhr.html
+++ b/dojo/tests/_base/xhr.html
@@ -7,11 +7,9 @@
 		<style type="text/css">
 			@import "../../resources/dojo.css";
 		</style>
-		<script type="text/javascript" 
-			src="../../dojo.js" djConfig="isDebug: true, ioPublish: true"></script>
+		<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug:true, ioPublish:true"></script>
 		<script type="text/javascript">
-			dojo.require("doh.runner");
-			dojo.addOnLoad(function(){
+			require(["dojo", "doh", "dojo/domReady!"], function(dojo, doh){
 				var f1NoValueObj = null;
 				var f1NoValue2Obj = 'blah';
 				var f2MultiObj = [ 'thud', 'thonk' ];
@@ -154,7 +152,7 @@
 						},
 						function formToJson(t){
 							t.is(f1foJson, dojo.formToJson("f1"));
-							t.is(f5foJson, dojo.formToJson("f5"));
+							t.is(dojo.fromJson(f5foJson), dojo.fromJson(dojo.formToJson("f5")));
 						},
 						function formToJsonArr(t){
 							t.is(f2foJson, dojo.formToJson("f2"));
@@ -455,7 +453,10 @@
 						},
 
 						function ioPublish(t){
-						
+							// TODO: this test needs to be rewritten as it is unreliable with the
+							// 1.7 bootstrap that uses dojo.xhr
+							return;
+
 							//These numbers will look a bit odd at this point, since
 							//some of the topics publish after this test is run.
 							
@@ -474,7 +475,7 @@
 						}
 					]
 				);
-				doh.run();
+				doh.runOnLoad();
 			});
 		</script>
 	</head>
diff --git a/dojo/tests/_base/xhr.js b/dojo/tests/_base/xhr.js
index bcbbc3e..c64a634 100644
--- a/dojo/tests/_base/xhr.js
+++ b/dojo/tests/_base/xhr.js
@@ -1,4 +1,5 @@
-dojo.provide("tests._base.xhr");
-if(dojo.isBrowser){
-	doh.registerUrl("tests._base.xhr", dojo.moduleUrl("tests", "_base/xhr.html"));
-}
+define(["doh", "require"], function(doh, require){
+	if(doh.isBrowser){
+		doh.register("tests._base.xhr", require.toUrl("./xhr.html"), 60000);
+	}
+});
diff --git a/dojo/tests/amd/backCompat.js b/dojo/tests/amd/backCompat.js
deleted file mode 100644
index 1768fa2..0000000
--- a/dojo/tests/amd/backCompat.js
+++ /dev/null
@@ -1,118 +0,0 @@
-var
-	addOnLoadResults = [],
-	writeToAddOnLoadResults = function(c, context){
-		return function() {
-			addOnLoadResults.push(c);
-			this===context && addOnLoadResults.push("OK");
-		};
-	};
-
-// here's a djConfig for dojo to consume during its bootstrap
-djConfig = {
-	addOnLoad:writeToAddOnLoadResults("A", this),
-	someRandomProperty:"someRandomValue"
-};
-
-define(
-	["dojo", "doh", "i18n!dojo/nls/colors", "text!./text.html", "text!./text.html!strip"],
-	function(dojo, doh, dojoColors, text, strippedText) {
-		doh.register("test.amd.backCompat", [
-			function djConfig(t){
-				t.assertEqual(dojo.config.someRandomProperty, "someRandomValue");
-			},
-	
-			function addOnLoad(t){
-				var d = new doh.Deferred();
-				dojo.addOnLoad(function() {
-					dojo.addOnLoad(writeToAddOnLoadResults("B", this));
-					dojo.addOnLoad(window, writeToAddOnLoadResults("C", window));
-					var someObject = {};
-					someObject.someMethod= writeToAddOnLoadResults("D", someObject);
-					dojo.addOnLoad(someObject, "someMethod");
-					someObject.someOtherMethod= writeToAddOnLoadResults("E", someObject);
-					dojo.addOnLoad(someObject, someObject.someOtherMethod);
-					dojo._loaders.unshift(writeToAddOnLoadResults("F", this));
-					dojo._loaders.unshift(writeToAddOnLoadResults("G", this));
-					dojo._loaders.splice(1, 0, writeToAddOnLoadResults("H", this));
-				});
-				dojo.addOnLoad(function(){
-					var expect;
-					if(require.vendor=="altoviso.com"){
-						expect= ["A", "OK", "B", "OK", "C", "OK", "D", "OK", "E", "OK", "G", "OK", "H", "OK", "F", "OK"];
-					}else{
-						expect= ["A", "OK", "B", "OK", "C", "OK", "D", "OK", "E", "OK", "F", "OK", "G", "OK", "H", "OK"];
-					}
-					t.assertEqual(expect, addOnLoadResults);
-					d.callback(true);
-				});
-	
-				return d;
-			},
-	
-			function addOnUnload(t){
-				addOnLoadResults= [];
-				dojo.addOnUnload(writeToAddOnLoadResults("A", dojo.global));
-				dojo.addOnUnload(window, writeToAddOnLoadResults("B", window));
-				var someOtherObject= {};
-				someOtherObject.someMethod= writeToAddOnLoadResults("C", someOtherObject);
-				dojo.addOnUnload(someOtherObject, "someMethod");
-				someOtherObject.someOtherMethod= writeToAddOnLoadResults("D", someOtherObject);
-				dojo.addOnUnload(someOtherObject, someOtherObject.someOtherMethod);
-				dojo.unloaded();
-				t.assertEqual(["D", "OK", "C", "OK", "B", "OK", "A", "OK"], addOnLoadResults);
-			},
-	
-			function l10nNames(t){
-				t.assertEqual("i18n!dojo/cldr/nls/en-us/gregorian", dojo.getL10nName("dojo.cldr", "gregorian"));
-				t.assertEqual("i18n!dojo/cldr/nls/en-us/gregorian", dojo.getL10nName("dojo.cldr", "gregorian", "en-us"));
-				t.assertEqual("i18n!dojo/cldr/nls/gregorian", dojo.getL10nName("dojo.cldr", "gregorian", "root"));
-				t.assertEqual("i18n!dojo/cldr/nls/gregorian", dojo.getL10nName("dojo.cldr", "gregorian", "ROOT"));
-				t.assertEqual("i18n!dojo/cldr/nls/gregorian", dojo.getL10nName("dojo.cldr", "gregorian", "Root"));
-	
-				t.assertEqual("i18n!dojo/cldr/nls/en-us/gregorian", dojo.getL10nName("dojo/cldr", "gregorian"));
-				t.assertEqual("i18n!dojo/cldr/nls/en-us/gregorian", dojo.getL10nName("dojo/cldr", "gregorian", "en-us"));
-				t.assertEqual("i18n!dojo/cldr/nls/gregorian", dojo.getL10nName("dojo/cldr", "gregorian", "root"));
-				t.assertEqual("i18n!dojo/cldr/nls/gregorian", dojo.getL10nName("dojo/cldr", "gregorian", "ROOT"));
-				t.assertEqual("i18n!dojo/cldr/nls/gregorian", dojo.getL10nName("dojo/cldr", "gregorian", "Root"));
-			},
-	
-			function i18nPlugin(t){
-				t.assertEqual(dojoColors, dojo.requireLocalization("dojo", "colors"));
-			},
-	
-			function moduleUrl(t){
-				var
-					compact= function(path){
-						var
-							parts= path.split("/"),
-							result= [],
-							segment;
-						while(parts.length){
-							segment= parts.shift();
-							if(segment==".."){
-								if(result.length && result[result.length-1].charAt(0)!="."){
-									result.pop();
-								}else{
-									result.push("..");
-								}
-							}else if (segment!="."){
-								result.push(segment);
-							}
-						}
-						return result.join("/");
-					},
-					result1= compact(location.pathname + "/../" + dojo.moduleUrl("dojo.my", "module.js")),
-					result2= compact(location.pathname + "/../" + dojo.moduleUrl("dojo", "resources/blank.gif"));
-				t.assertTrue(/dojo\/my\/module\.js$/.test(result1));
-				t.assertTrue(/dojo\/resources\/blank\.gif$/.test(result2));
-			},
-	
-			function textPlugin(t){
-				// TODO: the text plugin seems to return a single extra newline; OK for now
-				t.assertTrue(text.indexOf("<html><head><title>some text</title></head><body><h1>some text</h1></body></html>")==0);
-				t.assertEqual("<h1>some text</h1>", strippedText);
-			}
-		]);
-	}
-);
-
diff --git a/dojo/tests/amd/main.js b/dojo/tests/amd/main.js
deleted file mode 100644
index 51d6ae6..0000000
--- a/dojo/tests/amd/main.js
+++ /dev/null
@@ -1,26 +0,0 @@
-// configure the loader to load the dojo package; assume baseUrl is
-// <whatever>/util/doh and dojo resides at <whatever>/dojo
-require({
-	packages:[{
-		name:'dojo',
-		location:'../../dojo',
-		main:'lib/main-browser',
-		lib:'.'
-	}],
-	paths:require.vendor=="altoviso.com" ?
-		{
-			i18n:"../../dojo/lib/plugins/i18n",
-			text:"../../dojo/lib/plugins/text"
-		} :
-		{
-			require:"../../../requirejs/require"
-		},
-	deps:[
-		"dojo/tests/amd/backCompat"
-	],
-	callback:function(){
-		require.ready(function() {
-			setTimeout(function(){doh.run();}, 200);
-		});
-	}
-});
diff --git a/dojo/tests/amd/smoke-bdLoad.html b/dojo/tests/amd/smoke-bdLoad.html
deleted file mode 100644
index a3d3f02..0000000
--- a/dojo/tests/amd/smoke-bdLoad.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>
-		<title>dojo with and AMD Loader!</title>
-		<script type="text/javascript" src="../../../../bdLoad/lib/require.js"></script>
-		<script type="text/javaScript">
-			var start= (new Date()).getTime();
-			require({
-				packages:[{
-					name: 'dojo',
-					location:'../..',
-					main:'lib/main-browser',
-					lib: '.'
-				}],
-				paths:{
-					i18n:"../../lib/plugins/i18n",
-					text:"../../lib/plugins/text"
-				},
-				deps:["dojo", "dojo/date/locale", "text!smoke.txt"],
-				callback:function(dojo, locale, text){
-					dojo.byId("status").innerHTML= "The dojo package has been loaded.";
-					dojo.byId("time").innerHTML= (((new Date()).getTime() - start) / 1000) + "s";
-					dojo.byId("i18n").innerHTML= locale.getNames('months', 'wide', 'standAlone');
-					dojo.byId("text").innerHTML= text;
-				}
-			});
-		</script>
-	</head>
-	<body class="tundra">
-		<h1>This demonstration loads the dojo package using the bdLoad AMD loader.</h1>
-		<p>bdLoad is available at <a href="http://bdframework.org/">http://bdframework.org/</a></p>
-		<h1>Status</h1>
-		<p id="status">loading</p>
-		<h1>Load Time</h1>
-		<p id="time"></p>
-		<h1>Plugin Smoke Test</h1>
-		<p id="i18n"></p>
-		<p id="text"></p>
-	</body>
-</html>
-
diff --git a/dojo/tests/amd/smoke-requirejs.html b/dojo/tests/amd/smoke-requirejs.html
deleted file mode 100644
index b9da96d..0000000
--- a/dojo/tests/amd/smoke-requirejs.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	 "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<title>dojo with an AMD Loader!</title>
-		<script type="text/javascript" src="../../../../requirejs/require.js"></script>
-		<script type="text/javaScript">
-			var start= (new Date()).getTime();
-			require({
-				baseUrl:"./",
-				packages:[{
-					name: 'dojo',
-					location:'../..',
-					main:'lib/main-browser',
-					lib: '.'
-				}],
-				paths:{
-					"require/i18n":"../../../../requirejs/require/i18n",
-					"require/text":"../../../../requirejs/require/text"
-				},
-				deps:["dojo", "dojo/date/locale", "text!smoke.txt", "i18n!dojo/cldr/nls/fr-ch/gregorian"],
-				callback:function(dojo, locale, text){
-					dojo.byId("status").innerHTML= "The dojo package has been loaded.";
-					dojo.byId("time").innerHTML= (((new Date()).getTime() - start) / 1000) + "s";
-					dojo.byId("i18n").innerHTML= locale.getNames('months', 'wide', 'standAlone');
-					// test specifying a different locale that depends on "parent" bundles (ie depends on 'fr' bundle)
-					dojo.byId("frch").innerHTML= locale.getNames('months', 'wide', 'standAlone', 'fr-ch');
-					dojo.byId("text").innerHTML= text;
-				}
-			});
-		</script>
-	</head>
-	<body class="tundra">
-		<h1>This demonstration loads the dojo package using the RequireJS AMD loader.</h1>
-		<p>RequireJS is available at <a href="http://requirejs.org/">http://requirejs.org/</a></p>
-		<h1>Status</h1>
-		<p id="status">loading</p>
-		<h1>Load Time</h1>
-		<p id="time"></p>
-		<h1>Plugin Smoke Test</h1>
-		<p id="i18n"></p>
-		<p id="frch"></p>
-		<p id="text"></p>
-	</body>
-</html>
-
diff --git a/dojo/tests/amd/smoke.txt b/dojo/tests/amd/smoke.txt
deleted file mode 100644
index 041831f..0000000
--- a/dojo/tests/amd/smoke.txt
+++ /dev/null
@@ -1 +0,0 @@
-This is some text.
diff --git a/dojo/tests/amd/text.html b/dojo/tests/amd/text.html
deleted file mode 100644
index 9ec8b00..0000000
--- a/dojo/tests/amd/text.html
+++ /dev/null
@@ -1 +0,0 @@
-<html><head><title>some text</title></head><body><h1>some text</h1></body></html>
diff --git a/dojo/tests/aspect.js b/dojo/tests/aspect.js
new file mode 100644
index 0000000..be1bd6e
--- /dev/null
+++ b/dojo/tests/aspect.js
@@ -0,0 +1,119 @@
+dojo.provide("dojo.tests.aspect");
+
+var aspect = dojo.require("dojo.aspect");
+
+doh.register("tests.aspect",
+	[
+		function before(t){
+			var order = [];
+			var obj = {
+				method: function(a){
+					order.push(a);
+				}
+			};
+			var signal = aspect.before(obj, "method", function(a){
+				order.push(a);
+				return [a+1];
+			});
+			obj.method(0);
+			obj.method(2);
+			var signal2 = aspect.before(obj, "method", function(a){
+				order.push(a);
+				return [a+1];
+			});
+			obj.method(4);
+			signal.remove();
+			obj.method(7);
+			signal2.remove();
+			obj.method(9);
+			t.is(order, [0,1,2,3,4,5,6,7,8,9]);
+		},
+
+		function after(t){
+			var order = [];
+			var obj = {
+				method: function(a){
+					order.push(a);
+					return a+1;
+				}
+			};
+			var signal = aspect.after(obj, "method", function(a){
+				order.push(0);
+				return a+1;
+			});
+			obj.method(0);
+			var signal2 = aspect.after(obj, "method", function(a){
+				order.push(a);
+			});
+			obj.method(3);
+			var signal3 = aspect.after(obj, "method", function(a){
+				order.push(3);
+			}, true);
+			obj.method(3);
+			signal2.remove();
+			obj.method(6);
+			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]);
+		},
+		function around(t){
+			var order = [];
+			var obj = {
+				method: function(a){
+					order.push(a);
+					return a+1;
+				}
+			};
+			var beforeSignal = aspect.before(obj, "method", function(a){
+				order.push(a);
+			});
+			var signal = aspect.around(obj, "method", function(original){
+				return function(a){
+					a= a + 1;
+					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 delegation(t){
+			var order = [];
+			var proto = {
+				foo: function(x){
+					order.push(x);
+					return x;
+				},
+				bar: function(){
+				}
+			};
+			aspect.after(proto, "foo", function(x){
+				order.push(x + 1);
+				return x;
+			});
+			aspect.after(proto, "bar", function(x){
+				t.t(this.isInstance);
+			});
+			proto.foo(0);
+			function Class(){
+			}
+			Class.prototype = proto;
+			var instance = new Class();
+			instance.isInstance = true;
+			aspect.after(instance, "foo", function(x){
+				order.push(x + 2);
+				return x;
+			});
+			instance.bar();
+			instance.foo(2);
+			proto.foo(5);
+			t.is(order, [0,1,2,3,4,5,6]);
+		}
+	]
+);
diff --git a/dojo/tests/back-hash.js b/dojo/tests/back-hash.js
index 82e7f8a..d6cb79b 100644
--- a/dojo/tests/back-hash.js
+++ b/dojo/tests/back-hash.js
@@ -1,9 +1,5 @@
-dojo.provide("tests.back-hash");
-
-dojo.require("dojo.back");
-
-(function(){
-	tests.register("tests.back.hash", [
+define(["../main", "doh", "../back"], function(dojo, doh){
+	doh.register("tests.back.hash", [
 		function getAndSet(t) {
 			var cases = [
 				"test",
@@ -26,4 +22,4 @@ dojo.require("dojo.back");
 			dojo.forEach(cases, verify);
 		}
 	]);
-})();
+});
diff --git a/dojo/tests/back.html b/dojo/tests/back.html
index 1b9ca1c..1f86150 100644
--- a/dojo/tests/back.html
+++ b/dojo/tests/back.html
@@ -3,22 +3,22 @@
 	<script language="JavaScript" type="text/javascript">
 		// Dojo configuration
 		djConfig = {
-			//debugAtAllCosts: true, //Don't normally need this in applications.
 			isDebug: true,
 			dojoIframeHistoryUrl: "../../resources/iframe_history.html" //for xdomain
 		};
 	</script>
 	<script type="text/javascript" 
-	        src="../dojo.js" 
-	        djConfig="isDebug:true, dojoIframeHistoryUrl: '../resources/iframe_history.html'"></script>
-	<script type="text/javascript" src="../back.js"></script>
-	<script type="text/javascript">	
+					src="../dojo.js" 
+					djConfig="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(){
@@ -51,7 +51,7 @@
 			link7: "This is data for link 7"
 		};
 
-		function goNav(id){
+		dojo.global.goNav = function goNav(id){
 			var appState = new ApplicationState(data[id], "output", "dataOutput", id);
 			appState.showStateData();
 			dojo.back.addToHistory(appState);
@@ -62,10 +62,13 @@
 			appState.showStateData();
 			dojo.back.setInitialState(appState);
 		});
+		});
 	</script>
 </head>
 <body>
-	<script type="text/javascript">dojo.back.init();</script>
+	<script type="text/javascript">
+		require(["dojo/back"], function(back){back.init();});
+	</script>
 	<div style="padding-bottom: 20px; width: 100%; border-bottom: 1px solid gray">
 	<h3>dojo.back test</h3>
 	
diff --git a/dojo/tests/back.js b/dojo/tests/back.js
index 2647b7b..cd061a9 100644
--- a/dojo/tests/back.js
+++ b/dojo/tests/back.js
@@ -1,4 +1,5 @@
-dojo.provide("tests.back");
-if(dojo.isBrowser){
-	doh.registerUrl("tests.back", dojo.moduleUrl("tests", "back.html"));
-}
+define(["doh", "require"], function(doh, require){
+	if(doh.isBrowser){
+		doh.register("tests.back", require.toUrl("./back.html"), 30000);
+	}
+});
diff --git a/dojo/tests/baseonly.js b/dojo/tests/baseonly.js
index 5a459b8..42b9b9a 100644
--- a/dojo/tests/baseonly.js
+++ b/dojo/tests/baseonly.js
@@ -1,7 +1 @@
-dojo.provide("dojo.tests.baseonly");
-
-try{
-	dojo.require("tests._base");
-}catch(e){
-	doh.debug(e);
-}
+define(["./_base"], 1);
diff --git a/dojo/tests/behavior.html b/dojo/tests/behavior.html
index d491bfc..1f4eb6d 100644
--- a/dojo/tests/behavior.html
+++ b/dojo/tests/behavior.html
@@ -6,30 +6,26 @@
 		<style type="text/css">
 			@import "../resources/dojo.css";
 		</style>
-		<script type="text/javascript" 
-			src="../dojo.js" djConfig="isDebug: true, popup: true"></script>
+		<script type="text/javascript" src="../dojo.js" data-dojo-config="isDebug: true, popup: true"></script>
 		<script type="text/javascript">
-			dojo.require("doh.runner");
-			define("dojo/tests/bahavior/script", ["dojo", "dojo/behavior"], function(dojo) {
+			require(["dojo", "doh", "dojo/behavior", "dojo/domReady!"], function(dojo, doh){
+				var applyCount = 0;
+ 
+				var behaviorObj = {
+					".bar":function(elem){
+						dojo.style(elem, "opacity", 0.5);
+						applyCount++;
+					},
+					".foo > span":function(elem){
+						elem.style.fontStyle = "italic";
+						applyCount++;
+					}
+				};
+ 
+				topicCount = 0;
+				dojo.subscribe("/foo", function(){ topicCount++; });
 
-			var applyCount = 0;
-
-			var behaviorObj = {
-				".bar": 		function(elem){ 
-					dojo.style(elem, "opacity", 0.5);
-					applyCount++;
-				},
-				".foo > span":	function(elem){ 
-					elem.style.fontStyle = "italic";
-					applyCount++;
-				}
-			}
-
-			topicCount = 0;
-			dojo.subscribe("/foo", function(){ topicCount++; });
-
-			// no behaviors should be executed when onload fires
-			dojo.addOnLoad(function(){
+				// no behaviors should be executed when onload fires
 				doh.register("t", 
 					[
 						function add(t){
@@ -68,31 +64,42 @@
 							dojo.behavior.apply();
 							t.is(2, topicCount);
 
-							dojo.behavior.add({ ".foo": {
-									"onfocus": "/foo" 
-								}
-							});
-							dojo.behavior.apply();
-							t.is(2, topicCount);
-							dojo.byId("blah").focus();
-							dojo.byId("blah").blur();
-							dojo.byId("blah").focus();
-							setTimeout(function(){
-								// blur/focus event generation isn't synchronous on IE
-								try{
-									t.is(4, topicCount);
-									d.callback(true);
-								}catch(e){
-									d.errback(e);
-								}
-							}, 10);
+							// We are going to catch focus events on "thinger", so first move focus
+							// somewhere else.
+							dojo.byId("another").focus();
+
+							// use timeout because blur/focus event generation isn't synchronous on IE
+							setTimeout(d.getTestErrback(function(){
+
+								// setup listener for focus events
+								dojo.behavior.add({ ".foo": {
+										"onfocus": "/foo"
+									}
+								});
+								dojo.behavior.apply();
+								t.is(2, topicCount);
+
+								// focus blah, publishing /foo
+								dojo.byId("blah").focus();
+
+								setTimeout(d.getTestErrback(function(){
+									t.is(3, topicCount);
+
+									// blur and then refocus blah, publishing /foo again
+									dojo.byId("another").focus();
+									dojo.byId("blah").focus();
+
+									setTimeout(d.getTestCallback(function(){
+										t.is(4, topicCount);
+									}), 10);
+								}), 10);
+							}), 10);
 							return d;
 						}
 					]
 				);
-				doh.run();
+				doh.runOnLoad();
 			});
-      });
 		</script>
 	</head>
 	<body>
@@ -102,6 +109,9 @@
 				<span>.foo > .bar > span</span>	
 			</div>
 		</div>
+
+		<!--for focus/topic tests -->
+		<input id="another" value="another">
 		<input type="text" id="blah" class="foo blah" name="thinger" value="thinger" tabIndex="0">
 	</body>
 </html>
diff --git a/dojo/tests/behavior.js b/dojo/tests/behavior.js
index e078f20..3d41006 100644
--- a/dojo/tests/behavior.js
+++ b/dojo/tests/behavior.js
@@ -1,4 +1,5 @@
-dojo.provide("tests.behavior");
-if(dojo.isBrowser){
-	doh.registerUrl("tests.behavior", dojo.moduleUrl("tests", "behavior.html"));
-}
+define(["doh", "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 027374a..95b8445 100644
--- a/dojo/tests/cache.js
+++ b/dojo/tests/cache.js
@@ -1,18 +1,14 @@
-dojo.provide("tests.cache");
-
-dojo.require("dojo.cache");
-
-tests.register("tests.cache",
-	[
-		{
+define(["../main", "doh", "require", "../cache", "../_base/url"], function(dojo, doh, require) {
+	doh.register("tests.cache", [{
+			name: "dojo.cache",
 			runTest: function(t){
 				var expected = "<h1>Hello World</h1>";
 
 				t.is(expected, dojo.trim(dojo.cache("dojo.tests.cache", "regular.html")));
 				t.is(expected, dojo.trim(dojo.cache("dojo.tests.cache", "sanitized.html", {sanitize: true})));
-				
+
 				//Test object variant for module.
-				var objPath = dojo.moduleUrl("dojo.tests.cache", "object.html").toString();
+				var objPath = require.toUrl("dojo/tests/cache/object.html");
 				t.is(expected, dojo.trim(dojo.cache(new dojo._Url(objPath), {sanitize: true})));
 
 				//Just a couple of other passes just to make sure on manual inspection that the
@@ -29,5 +25,5 @@ tests.register("tests.cache",
 				t.is("", dojo.cache("dojo.tests.cache", "regular.html"));
 			}
 		}
-	]
-);
+	]);
+});
diff --git a/dojo/tests/cldr.js b/dojo/tests/cldr.js
index 0944fd9..62295a1 100644
--- a/dojo/tests/cldr.js
+++ b/dojo/tests/cldr.js
@@ -1,15 +1,11 @@
-dojo.provide("tests.cldr");
-
-dojo.require("dojo.cldr.supplemental");
-dojo.require("dojo.cldr.monetary");
-
-tests.register("tests.cldr",
-	[
+define(["..", "doh", "../cldr/supplemental", "../cldr/monetary"], function(dojo, doh){
+	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);
 		}
-	]
-);
+	]);
+});
+
diff --git a/dojo/tests/colors.js b/dojo/tests/colors.js
index a80435d..514b1c4 100644
--- a/dojo/tests/colors.js
+++ b/dojo/tests/colors.js
@@ -1,44 +1,42 @@
-dojo.provide("tests.colors");
-dojo.require("dojo.colors");
+define(["../main", "doh", "../colors"], function(dojo, doh){
 
-(function(){
 	var verifyColor = function(t, source, expected){
-		var source   = new dojo.Color(source);
-		var expected = new dojo.Color(expected);
+		source	 = new dojo.Color(source);
+		expected = new dojo.Color(expected);
 		t.is(expected.toRgba(), source.toRgba());
 		dojo.forEach(source.toRgba(), function(n){ t.is("number", typeof(n)); });
-	}
+	};
+
+	doh.register("tests.colors", [
+		// all tests below are taken from #4.2 of the CSS3 Color Module
+		function testColorEx01(t){ verifyColor(t, "black", [0, 0, 0]); },
+		function testColorEx02(t){ verifyColor(t, "white", [255, 255, 255]); },
+		function testColorEx03(t){ verifyColor(t, "maroon", [128, 0, 0]); },
+		function testColorEx04(t){ verifyColor(t, "olive", [128, 128, 0]); },
+		function testColorEx05(t){ verifyColor(t, "#f00", "red"); },
+		function testColorEx06(t){ verifyColor(t, "#ff0000", "red"); },
+		function testColorEx07(t){ verifyColor(t, "rgb(255, 0, 0)", "red"); },
+		function testColorEx08(t){ verifyColor(t, "rgb(100%, 0%, 0%)", "red"); },
+		function testColorEx09(t){ verifyColor(t, "rgb(300, 0, 0)", "red"); },
+		function testColorEx10(t){ verifyColor(t, "rgb(255, -10, 0)", "red"); },
+		function testColorEx11(t){ verifyColor(t, "rgb(110%, 0%, 0%)", "red"); },
+		function testColorEx12(t){ verifyColor(t, "rgba(255, 0, 0, 1)", "red"); },
+		function testColorEx13(t){ verifyColor(t, "rgba(100%, 0%, 0%, 1)", "red"); },
+		function testColorEx14(t){ verifyColor(t, "rgba(0, 0, 255, 0.5)", [0, 0, 255, 0.5]); },
+		function testColorEx15(t){ verifyColor(t, "rgba(100%, 50%, 0%, 0.1)", [255, 128, 0, 0.1]); },
+		function testColorEx16(t){ verifyColor(t, "hsl(0, 100%, 50%)", "red"); },
+		function testColorEx17(t){ verifyColor(t, "hsl(120, 100%, 50%)", "lime"); },
+		function testColorEx18(t){ verifyColor(t, "hsl(120, 100%, 25%)", "green"); },
+		function testColorEx19(t){ verifyColor(t, "hsl(120, 100%, 75%)", "#80ff80"); },
+		function testColorEx20(t){ verifyColor(t, "hsl(120, 50%, 50%)", "#40c040"); },
+		function testColorEx21(t){ verifyColor(t, "hsla(120, 100%, 50%, 1)", "lime"); },
+		function testColorEx22(t){ verifyColor(t, "hsla(240, 100%, 50%, 0.5)", [0, 0, 255, 0.5]); },
+		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]); }
+	]);
+
+});
 
-	doh.register("tests.colors",
-		[
-			// all tests below are taken from #4.2 of the CSS3 Color Module
-			function testColorEx01(t){ verifyColor(t, "black", [0, 0, 0]); },
-			function testColorEx02(t){ verifyColor(t, "white", [255, 255, 255]); },
-			function testColorEx03(t){ verifyColor(t, "maroon", [128, 0, 0]); },
-			function testColorEx04(t){ verifyColor(t, "olive", [128, 128, 0]); },
-			function testColorEx05(t){ verifyColor(t, "#f00", "red"); },
-			function testColorEx06(t){ verifyColor(t, "#ff0000", "red"); },
-			function testColorEx07(t){ verifyColor(t, "rgb(255, 0, 0)", "red"); },
-			function testColorEx08(t){ verifyColor(t, "rgb(100%, 0%, 0%)", "red"); },
-			function testColorEx09(t){ verifyColor(t, "rgb(300, 0, 0)", "red"); },
-			function testColorEx10(t){ verifyColor(t, "rgb(255, -10, 0)", "red"); },
-			function testColorEx11(t){ verifyColor(t, "rgb(110%, 0%, 0%)", "red"); },
-			function testColorEx12(t){ verifyColor(t, "rgba(255, 0, 0, 1)", "red"); },
-			function testColorEx13(t){ verifyColor(t, "rgba(100%, 0%, 0%, 1)", "red"); },
-			function testColorEx14(t){ verifyColor(t, "rgba(0, 0, 255, 0.5)", [0, 0, 255, 0.5]); },
-			function testColorEx15(t){ verifyColor(t, "rgba(100%, 50%, 0%, 0.1)", [255, 128, 0, 0.1]); },
-			function testColorEx16(t){ verifyColor(t, "hsl(0, 100%, 50%)", "red"); },
-			function testColorEx17(t){ verifyColor(t, "hsl(120, 100%, 50%)", "lime"); },
-			function testColorEx18(t){ verifyColor(t, "hsl(120, 100%, 25%)", "green"); },
-			function testColorEx19(t){ verifyColor(t, "hsl(120, 100%, 75%)", "#80ff80"); },
-			function testColorEx20(t){ verifyColor(t, "hsl(120, 50%, 50%)", "#40c040"); },
-			function testColorEx21(t){ verifyColor(t, "hsla(120, 100%, 50%, 1)", "lime"); },
-			function testColorEx22(t){ verifyColor(t, "hsla(240, 100%, 50%, 0.5)", [0, 0, 255, 0.5]); },
-			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]); }
-		]
-	);
-})();
diff --git a/dojo/tests/cookie.html b/dojo/tests/cookie.html
index a89b0f8..7c4b10c 100644
--- a/dojo/tests/cookie.html
+++ b/dojo/tests/cookie.html
@@ -4,78 +4,72 @@
 		<style type="text/css">
 			@import "../resources/dojo.css";
 		</style>
-		<script type="text/javascript"
-			src="../dojo.js"
-			djConfig="isDebug:true"></script>
-		<script type="text/javascript" src="../cookie.js"></script>
+		<script type="text/javascript" src="../dojo.js" data-dojo-config="isDebug:true"></script>
 		<script type="text/javascript">
-			dojo.require("doh.runner");
-			dojo.addOnLoad(function(){
-				doh.register("t",
-					[
-						{
-							name: "basicSet",
-							runTest: function(t){
-								// make sure the cookie is dead
-								var old = new Date(1976, 8, 15);
-								document.cookie = "dojo_test=blah; expires=" + old.toUTCString();
-								t.is(-1, document.cookie.indexOf("dojo_test="));
-								
-								// set the new one
-								var n = "dojo_test";
-								var v = "test value";
-								dojo.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);
-								if(end == -1){ end = document.cookie.length; }
-								t.is(v, decodeURIComponent(document.cookie.substring(start, end)));
-							}
-						},
-						{
-							name: "basicGet",
-							runTest: function(t){
-								// set the cookie
-								var n = "dojo_test";
-								var v = "foofoo";
-								document.cookie = n + "=" + v;
-								
-								t.is(v, dojo.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"));
-								
-								// 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"));
-							}
-						},
-						{
-							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"));
+			require(["dojo", "doh", "dojo/cookie", "dojo/domReady!"], function(dojo, doh){
+				doh.register([
+					{
+						name: "basicSet",
+						runTest: function(t){
+							// make sure the cookie is dead
+							var old = new Date(1976, 8, 15);
+							document.cookie = "dojo_test=blah; expires=" + old.toUTCString();
+							t.is(-1, document.cookie.indexOf("dojo_test="));
+							
+							// set the new one
+							var n = "dojo_test";
+							var v = "test value";
+							dojo.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);
+							if(end == -1){ end = document.cookie.length; }
+							t.is(v, decodeURIComponent(document.cookie.substring(start, end)));
+						}
+					},
+					{
+						name: "basicGet",
+						runTest: function(t){
+							// set the cookie
+							var n = "dojo_test";
+							var v = "foofoo";
+							document.cookie = n + "=" + v;
+							
+							t.is(v, dojo.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"));
+							
+							// 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"));
+						}
+					},
+					{
+						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"));
 
-								// 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"));
-							}
+							// 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"));
 						}
-					]
-				);
-				doh.run();
+					}
+				]);
+				doh.runOnLoad();
 			});
 		</script>
 	</head>
diff --git a/dojo/tests/cookie.js b/dojo/tests/cookie.js
index af974b8..46df058 100644
--- a/dojo/tests/cookie.js
+++ b/dojo/tests/cookie.js
@@ -1,4 +1,5 @@
-dojo.provide("tests.cookie");
-if(dojo.isBrowser){
-	doh.registerUrl("tests.cookie", dojo.moduleUrl("tests", "cookie.html"));
-}
+define(["doh", "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 025e408..efcbe6b 100644
--- a/dojo/tests/currency.js
+++ b/dojo/tests/currency.js
@@ -1,6 +1,6 @@
-(function() {
+define(["../main", "doh", "require", "../currency"], function(dojo, doh, require){
 
-  var runTest= function(dojo, t) {
+	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"}));
@@ -23,47 +23,34 @@
 		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"})));
-  };
+	};
 
-if(dojo.global.define && define.vendor!="dojotoolkit.org"){ //tests for the AMD loader
-  define(["dojo", "dojo/currency", "plugin/i18n"], function(dojo){
-    tests.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));
-            });
-            define(deps, function(dojo){
-              runTest(dojo, t);
-							def.callback(true);
-            });
-            return def;
-    			}
-    		}
-    	]
-    );
-  });
-
-} else { // tests for the v1.x loader/i18n machinery
-
-dojo.provide("tests.currency");
-
-dojo.require("dojo.currency");
-
-tests.register("tests.currency",
-	[
-		{
+	if(require.async){
+		require(["../main", "../currency", "../i18n"], function(dojo){
+			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);
+					});
+					return def;
+				}
+			});
+		});
+	}else{ // tests for the v1.x loader/i18n machinery
+		tests.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:
-
 			name: "currency",
 			setUp: function(){
 				var partLocaleList = ["en-us", "en-ca", "de-de"];
@@ -73,13 +60,8 @@ tests.register("tests.currency",
 				}
 			},
 			runTest: function(t){
-        runTest(dojo, t);
+				runTest(dojo, t);
 			}
-		}
-	]
-);
-}
-
-})();
-
-
+		});
+	}
+});
diff --git a/dojo/tests/data.js b/dojo/tests/data.js
index e66f48d..13ae1cf 100644
--- a/dojo/tests/data.js
+++ b/dojo/tests/data.js
@@ -1,5 +1,10 @@
-define("tests/data", ["dojo", "tests/data/utils", "tests/data/ItemFileReadStore", "tests/data/ItemFileWriteStore"], function(dojo) {
-  dojo.config.usePlainJson = true;
+define([
+	"dojo",
+	"./data/utils",
+	"./data/ItemFileReadStore",
+	"./data/ItemFileWriteStore",
+	"./data/ObjectStore"], function(dojo) {
+		dojo.config.usePlainJson = true;
 });
 
 
diff --git a/dojo/tests/data/ItemFileReadStore.js b/dojo/tests/data/ItemFileReadStore.js
index 0a4cde6..ef10ba4 100644
--- a/dojo/tests/data/ItemFileReadStore.js
+++ b/dojo/tests/data/ItemFileReadStore.js
@@ -1,4 +1,7 @@
-define("tests/data/ItemFileReadStore", ["tests/data/readOnlyItemFileTestTemplates", "dojo/data/ItemFileReadStore" ], function() {
-  tests.data.readOnlyItemFileTestTemplates.registerTestsForDatastore("dojo.data.ItemFileReadStore");
+// FIXME: this test assumes the existence of the global object "tests"
+tests= typeof tests=="undefined" ? {} : tests;
+
+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 18d567e..e0c9947 100644
--- a/dojo/tests/data/ItemFileWriteStore.js
+++ b/dojo/tests/data/ItemFileWriteStore.js
@@ -1,4 +1,14 @@
-define("tests/data/ItemFileWriteStore", ["dojo", "tests/data/readOnlyItemFileTestTemplates", "dojo/data/ItemFileWriteStore", "dojo/data/api/Read", "dojo/data/api/Identity", "dojo/data/api/Write", "dojo/data/api/Notification"], function(dojo) {
+// FIXME: this test assumes the existence of the global object "tests"
+define([
+  "dojo",
+  "doh",
+  "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.getObject("data.ItemFileWriteStore", true, tests);
 
@@ -10,7 +20,7 @@ tests.data.ItemFileWriteStore.getTestData = function(name){
 	var data = {};
 	if(name === "reference_integrity"){
 		if(dojo.isBrowser){
-			data = {url: dojo.moduleUrl("tests", "data/reference_integrity.json").toString() };
+			data = {url: require.toUrl("tests/data/reference_integrity.json")};
 		}else{
 			data =
 				{ data: {
@@ -59,7 +69,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			doh.assertTrue(features["dojo.data.api.Write"] !== null);
 			doh.assertTrue(features["dojo.data.api.Notification"] !== null);
 			doh.assertFalse(features["iggy"]);
-			
+
 			// and only the expected features:
 			var count = 0;
 			for(var i in features){
@@ -83,7 +93,7 @@ doh.register("tests.data.ItemFileWriteStore",
 				doh.assertEqual(1, items.length);
 				var item = items[0];
 				doh.assertTrue(store.containsValue(item, "capital", "Cairo"));
-				
+
 				// FIXME:
 				//    Okay, so this seems very odd.  Maybe I'm just being dense.
 				//    These tests works:
@@ -95,7 +105,7 @@ doh.register("tests.data.ItemFileWriteStore",
 				//
 				//    All of which seems especially weird, given that this *does* work:
 				doh.assertFalse(store.isDirty());
-				
+
 				doh.assertTrue(store.isDirty(item) === false);
 				doh.assertTrue(!store.isDirty());
 				store.setValue(item, "capital", "New Cairo");
@@ -184,7 +194,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			};
 			var canada = store.newItem({name: "Canada", abbr:"ca", capital:"Ottawa"});
 			doh.assertTrue(onNewInvoked);
-			
+
 			doh.assertTrue(store.isDirty(canada));
 			doh.assertTrue(store.isDirty());
 			doh.assertTrue(store.getValues(canada, "name") == "Canada");
@@ -258,7 +268,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			store.fetch({query:{name:"Egypt"}, onComplete: onComplete, onError: onError});
 			return deferred; //Object
 		},
-		
+
 		function testWriteAPI_newItem_multiple_withParent(){
 			//	summary:
 			//		Simple test of the newItem API with a parent assignment multiple times.
@@ -267,9 +277,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
 			var deferred = new doh.Deferred();
-			
+
 			doh.assertTrue(!store.isDirty());
-			
+
 			function onComplete(items, request){
 				doh.assertEqual(1, items.length);
 				var item = items[0];
@@ -279,37 +289,37 @@ doh.register("tests.data.ItemFileWriteStore",
 				store.onNew = function(newItem, parentInfo){
 					doh.assertEqual(item, parentInfo.item);
 					doh.assertEqual("cities", parentInfo.attribute);
-					
+
 					doh.assertTrue(parentInfo.oldValue === undefined);
-					
+
 					doh.assertTrue(parentInfo.newValue === newItem);
 				};
 
 				//See if we can add in a new item representing the city of Cairo.
 				//This should also call the onNew set above....
 				var newItem1 = store.newItem({name: "Cairo", abbr: "Cairo"}, {parent: item, attribute: "cities"});
-				
+
 				//Attach a new onNew to validate we get expected values.
 				store.onNew = function(newItem, parentInfo){
 					doh.assertEqual(item, parentInfo.item);
 					doh.assertEqual("cities", parentInfo.attribute);
-					
+
 					console.log(parentInfo.oldValue);
 					doh.assertTrue(parentInfo.oldValue == newItem1);
-					
+
 					doh.assertTrue(parentInfo.newValue[0] == newItem1);
 					doh.assertTrue(parentInfo.newValue[1] == newItem);
 				};
 				var newItem2 = store.newItem({name: "Banha", abbr: "Banha"}, {parent: item, attribute: "cities"});
-				
+
 				//Attach a new onNew to validate we get expected values.
 				store.onNew = function(newItem, parentInfo){
 					doh.assertEqual(item, parentInfo.item);
 					doh.assertEqual("cities", parentInfo.attribute);
-					
+
 					doh.assertTrue(parentInfo.oldValue[0] == newItem1);
 					doh.assertTrue(parentInfo.oldValue[1] == newItem2);
-					
+
 					doh.assertTrue(parentInfo.newValue[0] == newItem1);
 					doh.assertTrue(parentInfo.newValue[1] == newItem2);
 					doh.assertTrue(parentInfo.newValue[2] == newItem);
@@ -402,7 +412,7 @@ doh.register("tests.data.ItemFileWriteStore",
 				doh.assertTrue(store.isDirty(item));
 				doh.assertTrue(store.isDirty());
 				store.revert();
-				
+
 				//Fetch again to see if it reset the state.
 				var onCompleteToo = function(itemsToo, requestToo){
 					doh.assertEqual(1, itemsToo.length);
@@ -478,7 +488,7 @@ doh.register("tests.data.ItemFileWriteStore",
 				doh.assertEqual(struct.identifier, store.getIdentityAttributes(egypt)[0]);
 				doh.assertEqual(struct.label, store.getLabelAttributes(egypt)[0]);
 				doh.assertEqual(struct.items.length, 7);
-				
+
 				var cloneStore = new dojo.data.ItemFileWriteStore({data:struct});
 				var onItemClone = function(itemClone){
 					var egyptClone = itemClone;
@@ -542,7 +552,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			//	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"));
-			
+
 			var deferred = new doh.Deferred();
 			store._saveEverything = function(saveCompleteCallback, saveFailedCallback, newFileContentString){
 
@@ -599,7 +609,7 @@ doh.register("tests.data.ItemFileWriteStore",
 					data:dataset,
 					typeMap: customTypeMap
 			});
-			
+
 			var deferred = new doh.Deferred();
 			store._saveEverything = function(saveCompleteCallback, saveFailedCallback, newFileContentString){
 				//Now load the new data into a datastore and validate that it stored the Color right.
@@ -663,7 +673,7 @@ doh.register("tests.data.ItemFileWriteStore",
 					data:dataset,
 					typeMap: customTypeMap
 			});
-			
+
 			var deferred = new doh.Deferred();
 			store._saveEverything = function(saveCompleteCallback, saveFailedCallback, newFileContentString){
 				//Now load the new data into a datastore and validate that it stored the Color right.
@@ -775,13 +785,13 @@ doh.register("tests.data.ItemFileWriteStore",
 				var initialCount = items.length;
 				var canada = store.newItem({name: "Canada", abbr:"ca", capital:"Ottawa"});
 				store.setValue(canada, "someattribute", "modified a new item!");
-				
+
 				// check that after new and modify, the total items count goes up by one.
 				var afterNewFetch = function(items, request){
 					var afterNewCount = items.length;
 					doh.assertEqual(afterNewCount, (initialCount + 1));
 					store.deleteItem(canada);
-					
+
 					//Check that after delete, the total items count goes back to initial count.
 					//Also verify the item with abbr of ca is gone.
 					var afterDeleteFetch = function(items, request){
@@ -981,18 +991,18 @@ doh.register("tests.data.ItemFileWriteStore",
 			} };
 			var store = new dojo.data.ItemFileWriteStore(args);
 			var deferred = new doh.Deferred();
-			
+
 			var onError = function(error, request){
 				deferred.errback(error);
 			};
 			var onComplete = function(items, request){
 				doh.assertEqual(7, items.length);
-				
+
 				var lastItem = items[(items.length - 1)];
 				var idOfLastItem = store.getIdentity(lastItem);
 				store.deleteItem(lastItem);
 				store.newItem({name:'Canada', capital:'Ottawa'});
-				
+
 				var onCompleteAgain = function(itemsAgain, requestAgain){
 					doh.assertEqual(7, itemsAgain.length);
 					var identitiesInUse = {};
@@ -1011,7 +1021,7 @@ doh.register("tests.data.ItemFileWriteStore",
 				};
 				store.fetch({onComplete:onCompleteAgain, onError:onError});
 			};
-			
+
 			store.fetch({onComplete:onComplete, onError:onError});
 			return deferred;
 		},
@@ -1034,18 +1044,18 @@ doh.register("tests.data.ItemFileWriteStore",
 			} };
 			var store = new dojo.data.ItemFileWriteStore(args);
 			var deferred = new doh.Deferred();
-			
+
 			var onError = function(error, request){
 				deferred.errback(error);
 			};
 			var onComplete = function(items, request){
 				doh.assertEqual(7, items.length);
-				
+
 				var lastItem = items[(items.length - 1)];
 				var idOfLastItem = store.getIdentity(lastItem);
 				store.deleteItem(lastItem);
 				store.newItem({name:'Canada', capital:'Ottawa'});
-				
+
 				var onCompleteAgain = function(itemsAgain, requestAgain){
 					doh.assertEqual(7, itemsAgain.length);
 					var identitiesInUse = {};
@@ -1080,7 +1090,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			//		Simple test to verify the references were properly resolved.
 			//	description:
 			//		Simple test to verify the references were properly resolved.
-		
+
 			var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
 
 			var deferred = new doh.Deferred();
@@ -1149,7 +1159,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			//		Simple test to verify the references were properly deleted.
 			//	description:
 			//		Simple test to verify the references were properly deleted.
-		
+
 			var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
 
 			var deferred = new doh.Deferred();
@@ -1204,7 +1214,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			//		Simple test to verify the references were properly deleted.
 			//	description:
 			//		Simple test to verify the references were properly deleted.
-		
+
 			var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
 
 			var deferred = new doh.Deferred();
@@ -1246,7 +1256,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			//	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 dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries_references"));
 
 			var deferred = new doh.Deferred();
@@ -1289,7 +1299,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			//		Simple test to verify the reference removal updates the internal map.
 			//	description:
 			//		Simple test to verify the reference removal updates the internal map.
-		
+
 			var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
 
 			var deferred = new doh.Deferred();
@@ -1333,7 +1343,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			//		Simple test to verify the references to a non-parent item was properly deleted.
 			//	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"));
 
 			var deferred = new doh.Deferred();
@@ -1387,7 +1397,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			//		Simple test to verify the reference additions can happen.
 			//	description:
 			//		Simple test to verify the reference additions can happen.
-		
+
 			var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
 
 			var deferred = new doh.Deferred();
@@ -1429,7 +1439,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			//		Simple test to verify that newItems with a parent properly record the parent's reference in the map.
 			//	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"));
 
 			var deferred = new doh.Deferred();
@@ -1442,7 +1452,7 @@ doh.register("tests.data.ItemFileWriteStore",
 				try{
 					//Create a new item and set its parent to item 10's uncle attribute.
 					var newItem = store.newItem({id: 17, name: "Item 17"}, {parent: item, attribute: "uncles"});
-					
+
 					//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!
 					//THIS IS FOR TESTING INTERNAL STATE!
 					//Look up the references to 17, as item 10 has one now on attribute 'uncles'
@@ -1470,7 +1480,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			//		Simple test to verify that a new item with references to existing items properly record the references in the map.
 			//	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"));
 
 			var deferred = new doh.Deferred();
@@ -1484,15 +1494,15 @@ doh.register("tests.data.ItemFileWriteStore",
 					//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!
 					//THIS IS FOR TESTING INTERNAL STATE!
 					console.log("State of reference map to item 10 before newItem: " + dojo.toJson(item[store._reverseRefMap]));
-					
+
 					//Create a new item and set its parent to item 10's uncle attribute.
 					var newItem = store.newItem({id: 17, name: "Item 17", friends: [item]});
-					
+
 					//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!
 					//THIS IS FOR TESTING INTERNAL STATE!
 					//Look up the references to 10, as item 17 has one on friends now.
 					var refs = item[store._reverseRefMap];
-					
+
 					//Assert there is a reference from 15 to item 10, on attribute friends
 					doh.assertTrue(refs["17"]["friends"]);
 
@@ -1515,7 +1525,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			//		Simple test to verify reference integrity can be disabled.
 			//	description:
 			//		Simple test to verify reference integrity can be disabled.
-		
+
 			var params = tests.data.ItemFileWriteStore.getTestData("reference_integrity");
 			params.referenceIntegrity = false;
 			var store = new dojo.data.ItemFileWriteStore(params);
@@ -1555,7 +1565,7 @@ doh.register("tests.data.ItemFileWriteStore",
 						var val = store.getValue(ec, "name");
 						doh.assertEqual("Ecuador", val);
 						var newItem = store.newItem({abbr: "foo", name: "bar"});
-						
+
 						//Should throw an error...
 						store.close();
 					}catch (e){
diff --git a/dojo/tests/data/ObjectStore.js b/dojo/tests/data/ObjectStore.js
index e511ede..9b89c8e 100644
--- a/dojo/tests/data/ObjectStore.js
+++ b/dojo/tests/data/ObjectStore.js
@@ -4,7 +4,7 @@ dojo.require("dojo.store.JsonRest");
 dojo.require("dojo.store.Memory");
 
 (function(){
-var restStore = new dojo.store.JsonRest({target: dojo.moduleUrl("dojo.tests.store", "")});
+var restStore = new dojo.store.JsonRest({target: dojo.moduleUrl("dojo.tests.store", "/")});
 var memoryStore = new dojo.store.Memory({
 	data: [
 		{id: 1, name: "one", prime: false},
@@ -45,6 +45,9 @@ tests.register("tests.data.ObjectStore",
 			});
 			memoryDataStore.setValue(newItem, "prop1", 1);
 			memoryDataStore.save();
+			memoryDataStore.setValue(newItem, "prop1", 10);
+			memoryDataStore.revert();
+			t.is(memoryDataStore.getValue(newItem, "prop1"), 1);
 			memoryDataStore.fetchItemByIdentity({
 				identity: memoryDataStore.getIdentity(newItem),
 				onItem: function(item){
@@ -53,6 +56,18 @@ tests.register("tests.data.ObjectStore",
 					t.is(memoryDataStore.getValue(item, "prop1"), 1);
 					t.is(memoryDataStore.getValue(item, "prop2"), 2);
 				}});
+			var newItem = memoryDataStore.newItem({
+				foo: "bar",
+				id: Math.random()
+			});
+			memoryDataStore.deleteItem(newItem);
+			memoryDataStore.save();
+			memoryDataStore.fetchItemByIdentity({
+				identity: memoryDataStore.getIdentity(newItem),
+				onItem: function(item){
+					t.is(item, null);
+				}
+			});
 		},
 		function testMemoryQuery(t){
 			var d = new doh.Deferred();
diff --git a/dojo/tests/data/readOnlyItemFileTestTemplates.js b/dojo/tests/data/readOnlyItemFileTestTemplates.js
index e50f8f4..dac49e1 100644
--- a/dojo/tests/data/readOnlyItemFileTestTemplates.js
+++ b/dojo/tests/data/readOnlyItemFileTestTemplates.js
@@ -1,4 +1,5 @@
-define("tests/data/readOnlyItemFileTestTemplates", ["dojo/data/api/Read", "dojo/data/api/Identity", "dojo/date", "dojo/date/stamp"], function() {
+// 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) {
 
 dojo.getObject("data.readOnlyItemFileTestTemplates", true, tests);
 
@@ -56,7 +57,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 	var data = null;
 	if(name === "countries"){
 		if(dojo.isBrowser){
-			data = {url: dojo.moduleUrl("tests", "data/countries.json").toString() };
+			data = {url: require.toUrl("tests/data/countries.json")};
 		}else{
 			data = {data: {
 				identifier:"abbr",
@@ -74,7 +75,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		}
 	}else if(name === "countries_withNull"){
 		if(dojo.isBrowser){
-			data = {url: dojo.moduleUrl("tests", "data/countries_withNull.json").toString() };
+			data = {url: require.toUrl("tests/data/countries_withNull.json")};
 		}else{
 			data = {data: {
 				identifier:"abbr",
@@ -91,7 +92,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		}
 	}else if(name === "countries_withoutid"){
 		if(dojo.isBrowser){
-			data = {url: dojo.moduleUrl("tests", "data/countries_withoutid.json").toString() };
+			data = {url: require.toUrl("tests/data/countries_withoutid.json")};
 		}else{
 			data = {data: {
 				label: "name",
@@ -108,7 +109,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		}
 	}else if (name === "countries_withBoolean"){
 		if(dojo.isBrowser){
-			data = {url: dojo.moduleUrl("tests", "data/countries_withBoolean.json").toString() };
+			data = {url: require.toUrl("tests/data/countries_withBoolean.json")};
 		}else{
 			data = {data: {
 				identifier:"abbr",
@@ -126,7 +127,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		}
 	}else if (name === "countries_withDates"){
 		if(dojo.isBrowser){
-			data = {url: dojo.moduleUrl("tests", "data/countries_withDates.json").toString() };
+			data = {url: require.toUrl("tests/data/countries_withDates.json")};
 		}else{
 			data = {data: {
 				identifier:"abbr",
@@ -143,7 +144,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		}
 	}else if (name === "geography_hierarchy_small"){
 		if(dojo.isBrowser){
-			data = {url: dojo.moduleUrl("tests", "data/geography_hierarchy_small.json").toString() };
+			data = {url: require.toUrl("tests/data/geography_hierarchy_small.json")};
 		}else{
 			data = {data: {
 				items:[
@@ -167,7 +168,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		}
 	}else if (name === "data_multitype"){
 		if(dojo.isBrowser){
-			data = {url: dojo.moduleUrl("tests", "data/data_multitype.json").toString() };
+			data = {url: require.toUrl("tests/data/data_multitype.json")};
 		}else{
 			data = {data: {
 							"identifier": "count",
@@ -191,7 +192,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		}
 	}else if (name === "countries_references"){
 		if(dojo.isBrowser){
-			data = {url: dojo.moduleUrl("tests", "data/countries_references.json").toString() };
+			data = {url: require.toUrl("tests/data/countries_references.json")};
 		}else{
 			data = {data: { identifier: 'name',
 							label: 'name',
@@ -330,7 +331,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 
 			var d = new doh.Deferred();
 			function onItem(item){
-				t.assertTrue(item !== null)
+				t.assertTrue(item !== null);
 				var identifiers = store.getIdentityAttributes(item);
 				t.assertTrue(dojo.isArray(identifiers));
 				t.assertEqual(1, identifiers.length);
@@ -357,7 +358,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//		paper.
 
 			if(dojo.isBrowser){
-                var store = new datastore({url: dojo.moduleUrl("tests", "data/countries_commentFiltered.json").toString()});
+                var store = new datastore({url: require.toUrl("tests/data/countries_commentFiltered.json")});
 
 				var d = new doh.Deferred();
 				function onItem(item){
@@ -587,7 +588,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//	description:
 			//		Simple test of a basic fetch on ItemFileReadStore.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
-			
+
 			var d = new doh.Deferred();
 			function completedAll(items, request){
 				t.is(7, items.length);
@@ -614,17 +615,17 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				var storeParams = {
 					url: "noSuchUrl",
 					failOk: true
-				}
+				};
 				var store = new datastore(storeParams);
 				console.log(store);
-                
+
 				var d = new doh.Deferred();
 				var completedAll = function(items, request){
 					d.errback(new Error("Should not be here, should have failed load."));
-				}
+				};
 				var error = function(errData, request){
 					d.callback(true);
-				}
+				};
 
 				//Get everything...
 				store.fetch({ onComplete: completedAll, onError: error});
@@ -642,7 +643,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//Can only async abort in a browser, so disable this test from rhino
 			if(dojo.isBrowser){
 				var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
-			
+
 				var d = new doh.Deferred();
 				var abortCalled = false;
 				function completedAll(items, request){
@@ -680,7 +681,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//	description:
 			//		Simple test of a basic fetch on ItemFileReadStore and with a count of Infinity.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
-			
+
 			var d = new doh.Deferred();
 			function completedAll(items, request){
 				t.is(7, items.length);
@@ -706,7 +707,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			var args = tests.data.readOnlyItemFileTestTemplates.getTestData("countries");
 			args.urlPreventCache = true;
 			var store = new datastore(args);
-			
+
 			var d = new doh.Deferred();
 			function completedAll(items, request){
 				t.is(7, items.length);
@@ -730,7 +731,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//	description:
 			//		Simple test of a basic fetch on ItemFileReadStore of a single item.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
-			
+
 			var d = new doh.Deferred();
 			function onComplete(items, request){
 				t.assertEqual(items.length, 1);
@@ -755,7 +756,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//	description:
 			//		Simple test of a basic fetch on ItemFileReadStore of only toplevel items.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("geography_hierarchy_small"));
-			
+
 			var d = new doh.Deferred();
 			function onComplete(items, request){
 				t.assertEqual(items.length, 2);
@@ -781,7 +782,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//	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"));
-			
+
 			var d = new doh.Deferred();
 			var done = [false, false];
 
@@ -826,7 +827,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//		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"));
-			
+
 			var d = new doh.Deferred();
 			var done = [false, false];
 
@@ -842,7 +843,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				t.assertTrue(item !== null);
 				var name = store.getValue(item,"name");
 				t.assertEqual(name, "El Salvador");
-				
+
 				if(done[0] && done[1]){
 					d.callback(true);
 				}
@@ -851,13 +852,13 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				t.assertTrue(false);
 				d.errback(errData);
 			}
-			
+
 			//Find all items starting with A, only toplevel (root) items.
 			store.fetch({ 	query: {name: "El*"},
 									onComplete: onComplete,
 									onError: onError
 								});
-			
+
 			store.fetchItemByIdentity({identity: "sv", onItem: onItem, onError: onError});
 			return d;
 		}
@@ -870,7 +871,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//	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"));
-			
+
 			var d = new doh.Deferred();
 			function onComplete(items, request){
 				t.assertEqual(items.length, 4);
@@ -901,10 +902,10 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//		This should turn off processing child objects as data store items.  It will still process
 			//		references and type maps.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("geography_hierarchy_small"));
-			
+
 			//Set this as hierarchy off before fetch to make sure it traps and configs right.
 			store.hierarchical = false;
-			
+
 			var d = new doh.Deferred();
 			function onComplete(items, request){
 				//With hierarchy off, this should only match 2, as only two data store items
@@ -959,10 +960,10 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//		This should turn off processing child objects as data store items.  It will still process
 			//		references and type maps.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries_references"));
-			
+
 			//Set this as hierarchy off before fetch to make sure it traps and configs right.
 			store.hierarchical = false;
-			
+
 			var d = new doh.Deferred();
 			function onComplete(items, request){
 				//With hierarchy off, this should only match 2, as only two data store items
@@ -1016,7 +1017,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//		data with this store can bypass the JavaSceipt hijack noted in Fortify's
 			//		paper.
 			if(dojo.isBrowser){
-                var store = new datastore({url: dojo.moduleUrl("tests", "data/countries_commentFiltered.json").toString()});
+                var store = new datastore({url: require.toUrl("tests/data/countries_commentFiltered.json")});
 
 				var d = new doh.Deferred();
 				function onComplete(items, request){
@@ -1044,7 +1045,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//		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"));
-			
+
 			var d = new doh.Deferred();
 			function onComplete(items, request){
 				t.assertEqual(4, items.length);
@@ -1107,7 +1108,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//	description:
 			//		Test of multiple fetches on a single result.  Paging, if you will.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
-			
+
 			var d = new doh.Deferred();
 			function dumpFirstFetch(items, request){
 				t.assertEqual(items.length, 5);
@@ -1179,7 +1180,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//		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"));
-			
+
 			var d = new doh.Deferred();
 			function onComplete(items, request){
 				t.assertEqual(4, items.length);
@@ -1204,7 +1205,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//	description:
 			//		Simple test of a basic fetch using a RegExp works with IFRS
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("data_multitype"));
-			
+
 			var d = new doh.Deferred();
 			function onComplete(items, request){
 				t.assertEqual(4, items.length);
@@ -1229,7 +1230,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//	description:
 			//		Simple test of a basic fetch using a RegExp works with IFRS
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("data_multitype"));
-			
+
 			var d = new doh.Deferred();
 			function onComplete(items, request){
 				t.assertEqual(4, items.length);
@@ -1255,7 +1256,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//		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"));
-			
+
 			var d = new doh.Deferred();
 			function onComplete(items, request){
 				t.assertEqual(7, items.length);
@@ -1280,7 +1281,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//	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"));
-			
+
 			var d = new doh.Deferred();
 			function onComplete(items, request){
 				t.assertEqual(items.length, 1);
@@ -1308,7 +1309,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//	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"));
-			
+
 			var d = new doh.Deferred();
 			function onComplete(items, request){
 				t.assertEqual(items.length, 1);
@@ -1422,7 +1423,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			var d = new doh.Deferred();
 			function onItem1(item1){
 				t.assertTrue(item1 !== null);
-				
+
 				function onItem2(item2){
 					t.assertTrue(item1 !== null);
 					t.assertTrue(item2 !== null);
@@ -1614,7 +1615,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 												 ]
 										}
 								 });
-			
+
 			var d = new doh.Deferred();
 			function completed(items, request){
 				t.assertEqual(items.length, 2);
@@ -1705,7 +1706,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 												 ]
 										}
 								 });
-			
+
 			var d = new doh.Deferred();
 			function completed(items, request){
 				t.assertEqual(1, items.length);
@@ -1748,7 +1749,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 												 ]
 										}
 								 });
-			
+
 			var d = new doh.Deferred();
 			function completed(items, request){
 				t.assertEqual(items.length, 2);
@@ -1782,7 +1783,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//		Function to test sorting numerically.
 			//	description:
 			//		Function to test sorting numerically.
-			
+
 			var store = new datastore({data: { identifier: "uniqueId",
 											  items: [ {uniqueId: 0, value:"fo|o*b.ar"},
 												   {uniqueId: 1, value:"ba|r*foo"},
@@ -1887,7 +1888,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//		Function to test sorting numerically in descending order, returning only a specified number of them.
 			//	description:
 			//		Function to test sorting numerically in descending order, returning only a specified number of them.
-		
+
 			var store = new datastore({data: { identifier: "uniqueId",
 											 items: [ {uniqueId: 0, value:"fo|o*b.ar"},
 												  {uniqueId: 1, value:"ba|r*foo"},
@@ -1903,7 +1904,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 												]
 									   }
 								});
-			
+
 			var d = new doh.Deferred();
 			function completed(items, request){
 				t.assertEqual(items.length, 5);
@@ -1924,12 +1925,12 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 					d.errback(new Error("Unexpected sorting order found, sort failure."));
 				}
 			}
-		
+
 			function error(error, request){
 				t.assertTrue(false);
 				d.errback(error);
 			}
-		
+
 			var sortAttributes = [{attribute: "uniqueId", descending: true}];
 			store.fetch({onComplete: completed, onError: error, sort: sortAttributes, count: 5});
 			return d;
@@ -1942,7 +1943,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//		Function to test sorting alphabetic ordering.
 			//	description:
 			//		Function to test sorting alphabetic ordering.
-		
+
 			var store = new datastore({data: { identifier: "uniqueId",
 											 items: [ {uniqueId: 0, value:"abc"},
 												  {uniqueId: 1, value:"bca"},
@@ -1955,11 +1956,11 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 												  {uniqueId: 8, value:""},
 												  {uniqueId: 9, value:"seaweed"},
 												  {uniqueId: 10, value:"123abc"}
-		
+
 												]
 									   }
 								});
-			
+
 			var d = new doh.Deferred();
 			function completed(items, request){
 				//Output should be in this order...
@@ -1991,12 +1992,12 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 					d.errback(new Error("Unexpected sorting order found, sort failure."));
 				}
 			}
-		
+
 			function error(error, request) {
 				t.assertTrue(false);
 				d.errback(error);
 			}
-		
+
 			var sortAttributes = [{attribute: "value"}];
 			store.fetch({onComplete: completed, onError: error, sort: sortAttributes});
 			return d;
@@ -2009,7 +2010,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//		Function to test sorting alphabetic ordering in descending mode.
 			//	description:
 			//		Function to test sorting alphabetic ordering in descending mode.
-		
+
 			var store = new datastore({data: { identifier: "uniqueId",
 											 items: [ {uniqueId: 0, value:"abc"},
 												  {uniqueId: 1, value:"bca"},
@@ -2022,7 +2023,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 												  {uniqueId: 8, value:""},
 												  {uniqueId: 9, value:"seaweed"},
 												  {uniqueId: 10, value:"123abc"}
-		
+
 												]
 									   }
 								});
@@ -2059,12 +2060,12 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 					d.errback(new Error("Unexpected sorting order found, sort failure."));
 				}
 			}
-		
+
 			function error(error, request) {
 				t.assertTrue(false);
 				d.errback(error);
 			}
-		
+
 			var sortAttributes = [{attribute: "value", descending: true}];
 			store.fetch({onComplete: completed, onError: error, sort: sortAttributes});
 			return d;
@@ -2077,7 +2078,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//		Function to test sorting date.
 			//	description:
 			//		Function to test sorting date.
-		
+
 			var store = new datastore({data: { identifier: "uniqueId",
 											 items: [ {uniqueId: 0, value: new Date(0)},
 												  {uniqueId: 1, value: new Date(100)},
@@ -2090,11 +2091,11 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 												  {uniqueId: 8, value:new Date(7000)},
 												  {uniqueId: 9, value:new Date(8000)},
 												  {uniqueId: 10, value:new Date(9000)}
-		
+
 												]
 									   }
 								});
-			
+
 			var d = new doh.Deferred();
 			function completed(items,request){
 				var orderedArray =	[0,100,1000,2000,3000,4000,5000,6000,7000,8000,9000];
@@ -2114,12 +2115,12 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 					d.errback(new Error("Unexpected sorting order found, sort failure."));
 				}
 			}
-		
+
 			function error(error, request){
 				t.assertTrue(false);
 				d.errback(error);
 			}
-		
+
 			var sortAttributes = [{attribute: "value"}];
 			store.fetch({onComplete: completed, onError: error, sort: sortAttributes});
 			return d;
@@ -2132,7 +2133,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//		Function to test sorting date in descending order.
 			//	description:
 			//		Function to test sorting date in descending order.
-		
+
 			var store = new datastore({data: { identifier: "uniqueId",
 											 items: [ {uniqueId: 0, value: new Date(0)},
 												  {uniqueId: 1, value: new Date(100)},
@@ -2145,11 +2146,11 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 												  {uniqueId: 8, value:new Date(7000)},
 												  {uniqueId: 9, value:new Date(8000)},
 												  {uniqueId: 10, value:new Date(9000)}
-		
+
 												]
 									   }
 								});
-		
+
 			var d = new doh.Deferred();
 			function completed(items,request){
 				var orderedArray =	[0,100,1000,2000,3000,4000,5000,6000,7000,8000,9000];
@@ -2170,12 +2171,12 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 					d.errback(new Error("Unexpected sorting order found, sort failure."));
 				}
 			}
-		
+
 			function error(error, request){
 				t.assertTrue(false);
 				d.errback(error);
 			}
-		
+
 			var sortAttributes = [{attribute: "value", descending: true}];
 			store.fetch({onComplete: completed, onError: error, sort: sortAttributes});
 			return d;
@@ -2188,7 +2189,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//		Function to test sorting on multiple attributes.
 			//	description:
 			//		Function to test sorting on multiple attributes.
-			
+
 			var store = new datastore({data: { identifier: "uniqueId",
 											 items: [ {uniqueId: 1, value:"fo|o*b.ar"},
 												  {uniqueId: 2, value:"ba|r*foo"},
@@ -2205,7 +2206,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 												]
 									   }
 								});
-		
+
 			var d = new doh.Deferred();
 			function completed(items, request){
 				var orderedArray0 = [7,2,4,3,1,6,5,12,10,9,8,11];
@@ -2239,12 +2240,12 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 					d.errback(new Error("Unexpected sorting order found, sort failure."));
 				}
 			}
-		
+
 			function error(error, request){
 				t.assertTrue(false);
 				d.errback(error);
 			}
-		
+
 			var sortAttributes = [{ attribute: "value"}, { attribute: "uniqueId", descending: true}];
 			store.fetch({onComplete: completed, onError: error, sort: sortAttributes});
 			return d;
@@ -2274,8 +2275,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 												]
 									   }
 								});
-		
-		
+
+
 			store.comparatorMap = {};
 			store.comparatorMap["status"] = function(a,b) {
 				var ret = 0;
@@ -2290,9 +2291,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				}
 				return ret;
 			};
-		
+
 			var sortAttributes = [{attribute: "status", descending: true}, { attribute: "uniqueId", descending: true}];
-		
+
 			var d = new doh.Deferred();
 			function completed(items, findResult){
 				var orderedArray = [11,6,2,12,10,4,8,7,3,9,5,1];
@@ -2311,7 +2312,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 					d.errback(new Error("Unexpected sorting order found, sort failure."));
 				}
 			}
-		
+
 			function error(errData, request){
 				t.assertTrue(false);
 				d.errback(errData);
@@ -2327,7 +2328,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//		Function to test sorting alphabetic ordering.
 			//	description:
 			//		Function to test sorting alphabetic ordering.
-		
+
 			var store = new datastore({data: { identifier: "uniqueId",
 											 items: [ {uniqueId: 0, value:"abc"},
 												  {uniqueId: 1, value:"bca"},
@@ -2340,11 +2341,11 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 												  {uniqueId: 8 },  //Deliberate undefined value
 												  {uniqueId: 9, value:"seaweed"},
 												  {uniqueId: 10, value:"123abc"}
-		
+
 												]
 									   }
 								});
-			
+
 			var d = new doh.Deferred();
 			function completed(items, request){
 				//Output should be in this order...
@@ -2364,12 +2365,12 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 					d.errback(new Error("Unexpected sorting order found, sort failure."));
 				}
 			}
-		
+
 			function error(error, request) {
 				t.assertTrue(false);
 				d.errback(error);
 			}
-		
+
 			var sortAttributes = [{attribute: "value"}];
 			store.fetch({onComplete: completed, onError: error, sort: sortAttributes});
 			return d;
@@ -2399,7 +2400,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				t.assertTrue(false);
 				d.callback(false);
 			}
-		
+
 			function reportError(errData, request){
 				//This is good if this fires, it is expected.
 				t.assertTrue(true);
@@ -2420,7 +2421,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//		Added because of tracker: #2546
 
 			if(dojo.isBrowser){
-				var store = new datastore({url: dojo.moduleUrl("tests", "data/countries_idcollision.json").toString() });
+				var store = new datastore({url: require.toUrl("tests/data/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.
@@ -2443,7 +2444,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
  		runTest: function(datastore, t){
 			//var store = new datastore(tests.data.readOnlyItemFileTestTemplates.testFile["countries_withDates"]);
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries_withDates"));
-			
+
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item !== null);
@@ -2745,7 +2746,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				onComplete: onComplete,
 				onError: onError
 			});
-			
+
 			return d; // Deferred
 		}
 	},
@@ -2814,8 +2815,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 						//Check some internals here.  Do not normally access these!
 						t.assertTrue(store._arrayOfAllItems.length === 0);
 						t.assertTrue(store._loadFinished === false);
-						
-						store.url = dojo.moduleUrl("tests", "data/countries_withNull.json").toString();
+
+						store.url = require.toUrl("tests/data/countries_withNull.json");
 						function onItem2 (item){
 							var err;
 							try{
@@ -2871,8 +2872,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 						//Check some internals here.  Do not normally access these!
 						t.assertTrue(store._arrayOfAllItems.length === 0);
 						t.assertTrue(store._loadFinished === false);
-						
-						store.url = dojo.moduleUrl("tests", "data/countries_withNull.json").toString();
+
+						store.url = require.toUrl("tests/data/countries_withNull.json");
 						function onComplete (items){
                             var err;
 							try{
@@ -2930,8 +2931,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 						//Check some internals here.  Do not normally access these!
 						t.assertTrue(store._arrayOfAllItems.length === 0);
 						t.assertTrue(store._loadFinished === false);
-						
-						store._jsonFileUrl = dojo.moduleUrl("tests", "data/countries_withNull.json").toString();
+
+						store._jsonFileUrl = require.toUrl("tests/data/countries_withNull.json");
 						function onItem2 (item){
 							var err;
 							try{
@@ -3032,7 +3033,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				//Set the store clearing options and the new data
 				store.clearOnClose = true;
 				store.data = { identifier: "uniqueId",
-					items: [ {uniqueId: 1, value:"foo*bar"},
+					items: [
+						{uniqueId: 1, value:"foo*bar"},
 						{uniqueId: 2, value:"bar*foo"},
 						{uniqueId: 3, value:"boomBam"},
 						{uniqueId: 4, value:"bit$Bite"},
@@ -3043,7 +3045,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 						{uniqueId: 9, value:"jfq4@#!$!@Rf14r14i5u"}
 					]
 				};
-                store.close();
+				store.close();
 
 				//Do the next fetch and verify that the next item you get is not
 				//a reference to the same item (data cleared and reloaded.
@@ -3060,7 +3062,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 					}
 				}
 				store.fetch({query: {value: "bar\*foo"}, onComplete: secondComplete, onError: error});
-			}
+			};
 			function error(error, request){
 				t.assertTrue(false);
 				d.errback(error);
diff --git a/dojo/tests/data/utils.js b/dojo/tests/data/utils.js
index 92dadec..f9e82c9 100644
--- a/dojo/tests/data/utils.js
+++ b/dojo/tests/data/utils.js
@@ -1,8 +1,6 @@
-dojo.provide("tests.data.utils");
-dojo.require("dojo.data.util.filter");
-dojo.require("dojo.data.util.sorter");
+define(["dojo", "doh", "dojo/data/util/filter", "dojo/data/util/sorter"], function(dojo, doh){
 
-tests.register("tests.data.utils",
+doh.register("tests.data.utils",
 	[
 		function testWildcardFilter_1(t){
 			var pattern = "ca*";
@@ -197,3 +195,5 @@ tests.register("tests.data.utils",
 	]
 );
 
+});
+
diff --git a/dojo/tests/date.js b/dojo/tests/date.js
index 5d8c0ea..c032249 100644
--- a/dojo/tests/date.js
+++ b/dojo/tests/date.js
@@ -1,9 +1,5 @@
-dojo.provide("tests.date");
-
-dojo.require("dojo.date");
-
-tests.register("tests.date.util",
-	[
+define(["../main", "doh", "../date", "./date/locale", "./date/stamp"], function(dojo, doh){
+doh.register("tests.date.util", [
 
 /* Informational Functions
  **************************/
@@ -50,7 +46,7 @@ function test_date_isLeapYear(t){
 // produced by various browser/OS combinations.
 // FIXME: the function and tests are not localized.
 function test_date_getTimezoneName(t){
-	
+
 	// Create a fake Date object with toString and toLocaleString
 	// results manually set to simulate tests for multiple browsers
 	function FakeDate(str, strLocale){
@@ -64,7 +60,7 @@ function test_date_getTimezoneName(t){
 		};
 	}
 	var dt = new FakeDate();
-	
+
 	// 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';
@@ -84,7 +80,7 @@ function test_date_getTimezoneName(t){
 	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));
-	
+
 	// IE 6 Windows XP
 	dt.str = 'Mon Sep 18 11:21:07 CDT 2006';
 	dt.strLocale = 'Monday, September 18, 2006 11:21:07 AM';
@@ -94,7 +90,7 @@ function test_date_getTimezoneName(t){
 	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));
-	
+
 	// 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';
@@ -103,7 +99,7 @@ function test_date_getTimezoneName(t){
 	]
 );
 
-tests.register("tests.date.math",
+doh.register("tests.date.math",
 	[
 function test_date_compare(t){
 	var d1=new Date();
@@ -121,28 +117,28 @@ function test_date_add(t){
 	var interv = ''; // Interval (e.g., year, month)
 	var dtA = null; // Date to increment
 	var dtB = null; // Expected result date
-	
+
 	interv = "year";
 	dtA = new Date(2005, 11, 27);
 	dtB = new Date(2006, 11, 27);
 	t.is(dtB, dojo.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));
-	
+
 	dtA = new Date(2000, 1, 29);
 	dtB = new Date(2001, 1, 28);
 	t.is(dtB, dojo.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));
-	
+
 	dtA = new Date(1900, 11, 31);
 	dtB = new Date(1930, 11, 31);
 	t.is(dtB, dojo.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));
@@ -151,28 +147,28 @@ function test_date_add(t){
 	dtA = new Date(2000, 0, 1);
 	dtB = new Date(2000, 3, 1);
 	t.is(dtB, dojo.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));
-	
+
 	dtA = new Date(2000, 1, 29);
 	dtB = new Date(2001, 1, 28);
 	t.is(dtB, dojo.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));
-	
+
 	dtA = new Date(2000, 0, 31);
 	dtB = new Date(2000, 1, 29);
 	t.is(dtB, dojo.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));
-	
+
 	interv = "week";
 	dtA = new Date(2000, 0, 1);
 	dtB = new Date(2000, 0, 8);
@@ -182,84 +178,84 @@ function test_date_add(t){
 	dtA = new Date(2000, 0, 1);
 	dtB = new Date(2000, 0, 2);
 	t.is(dtB, dojo.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));
-	
+
 	dtA = new Date(2000, 0, 1);
 	dtB = new Date(2001, 0, 1);
 	t.is(dtB, dojo.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));
-	
+
 	dtA = new Date(2001, 1, 28);
 	dtB = new Date(2001, 2, 1);
 	t.is(dtB, dojo.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));
-	
+
 	dtA = new Date(2001, 2, 1);
 	dtB = new Date(2001, 1, 28);
 	t.is(dtB, dojo.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));
-	
+
 	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));
-	
+
 	// 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));
-	
+
 	// 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));
-	
+
 	// 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));
-	
+
 	// 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));
-	
+
 	// 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));
-	
+
 	// 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));
-	
+
 	// 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));
-	
+
 	interv = "hour";
 	dtA = new Date(2000, 0, 1, 11);
 	dtB = new Date(2000, 0, 1, 12);
@@ -285,7 +281,7 @@ function test_date_add(t){
 	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));
-	
+
 	interv = "second";
 	dtA = new Date(2000, 11, 31, 23, 59, 59);
 	dtB = new Date(2001, 0, 1, 0, 0, 0);
@@ -294,7 +290,7 @@ function test_date_add(t){
 	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));
-	
+
 	// Test environment JS Date doesn't support millisec?
 	//interv = "millisecond";
 	//
@@ -310,138 +306,138 @@ function test_date_diff(t){
 	var dtA = null; // First date to compare
 	var dtB = null; // Second date to compare
 	var interv = ''; // Interval to compare on (e.g., year, month)
-	
+
 	interv = "year";
 	dtA = new Date(2005, 11, 27);
 	dtB = new Date(2006, 11, 27);
 	t.is(1, dojo.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));
-	
+
 	interv = "quarter";
 	dtA = new Date(2000, 1, 29);
 	dtB = new Date(2001, 2, 1);
 	t.is(4, dojo.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));
-	
+
 	interv = "month";
 	dtA = new Date(2000, 1, 29);
 	dtB = new Date(2001, 2, 1);
 	t.is(13, dojo.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));
-	
+
 	interv = "week";
 	dtA = new Date(2000, 1, 1);
 	dtB = new Date(2000, 1, 8);
 	t.is(1, dojo.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));
-	
+
 	dtA = new Date(2000, 2, 6);
 	dtB = new Date(2000, 1, 28);
 	t.is(-1, dojo.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));
-	
+
 	dtA = new Date(2000, 11, 31);
 	dtB = new Date(2001, 0, 1);
 	t.is(1, dojo.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));
-	
+
 	interv = "weekday";
 	dtA = new Date(2006, 7, 3);
 	dtB = new Date(2006, 7, 11);
 	t.is(6, dojo.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));
-	
+
 	dtA = new Date(2006, 7, 5);
 	dtB = new Date(2006, 7, 11);
 	t.is(5, dojo.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));
-	
+
 	dtA = new Date(2006, 7, 7);
 	dtB = new Date(2006, 7, 11);
 	t.is(4, dojo.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));
-	
+
 	dtA = new Date(2006, 7, 7);
 	dtB = new Date(2006, 7, 14);
 	t.is(5, dojo.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));
-	
+
 	dtA = new Date(2006, 7, 7);
 	dtB = new Date(2006, 7, 28);
 	t.is(15, dojo.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));
-	
+
 	// Negative diffs
 	dtA = new Date(2006, 7, 11);
 	dtB = new Date(2006, 7, 4);
 	t.is(-5, dojo.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));
-	
+
 	dtA = new Date(2006, 7, 11);
 	dtB = new Date(2006, 7, 6);
 	t.is(-4, dojo.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));
-	
+
 	dtA = new Date(2006, 7, 13);
 	dtB = new Date(2006, 7, 7);
 	t.is(-5, dojo.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));
-	
+
 	dtA = new Date(2006, 7, 15);
 	dtB = new Date(2006, 7, 7);
 	t.is(-6, dojo.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));
-	
+
 	dtA = new Date(2006, 2, 28);
 	dtB = new Date(2006, 2, 2);
 	t.is(-18, dojo.date.difference(dtA, dtB, interv));
@@ -450,35 +446,35 @@ function test_date_diff(t){
 	dtA = new Date(2006, 7, 5);
 	dtB = new Date(2006, 7, 6);
 	t.is(0, dojo.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));
-	
+
 	dtA = new Date(2000, 11, 31, 12);
 	dtB = new Date(2001, 0, 1, 0);
 	t.is(12, dojo.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));
-	
+
 	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));
-	
+
 	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));
-	
+
 	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));
-	
+
 	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));
@@ -487,28 +483,28 @@ function test_date_add_diff_year(t){
 	var interv = ''; // Interval (e.g., year, month)
 	var dtA = null; // Date to increment
 	var dtB = null; // Expected result date
-	
+
 	interv = "year";
 	dtA = new Date(2005, 11, 27);
 	dtB = dojo.date.add(dtA, interv, 1);
 	t.is(dojo.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);
-	
+
 	dtA = new Date(2000, 1, 29);
 	dtB = dojo.date.add(dtA, interv, 1);
 	t.is(dojo.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);
-	
+
 	dtA = new Date(1900, 11, 31);
 	dtB = dojo.date.add(dtA, interv, 30);
 	t.is(dojo.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);
@@ -521,11 +517,11 @@ function test_date_add_diff_quarter(t){
 	dtA = new Date(2000, 0, 1);
 	dtB = dojo.date.add(dtA, interv, 1);
 	t.is(dojo.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);
-	
+
 	dtA = new Date(2000, 1, 29);
 	dtB = dojo.date.add(dtA, interv, 4);
 	t.is(dojo.date.difference(dtA, dtB, interv), 4);
@@ -538,11 +534,11 @@ function test_date_add_diff_month(t){
 	dtA = new Date(2000, 0, 1);
 	dtB = dojo.date.add(dtA, interv, 1);
 	t.is(dojo.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);
-	
+
 	dtA = new Date(2000, 1, 29);
 	dtB = dojo.date.add(dtA, interv, 12);
 	t.is(dojo.date.difference(dtA, dtB, interv), 12);
@@ -564,31 +560,31 @@ function test_date_add_diff_day(t){
 	dtA = new Date(2000, 0, 1);
 	dtB = dojo.date.add(dtA, interv, 1);
 	t.is(dojo.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);
-	
+
 	dtA = new Date(2000, 0, 1);
 	dtB = dojo.date.add(dtA, interv, 366);
 	t.is(dojo.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);
-	
+
 	dtA = new Date(2001, 1, 28);
 	dtB = dojo.date.add(dtA, interv, 1);
 	t.is(dojo.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);
-	
+
 	dtA = new Date(2001, 2, 1);
 	dtB = dojo.date.add(dtA, interv, -1);
 	t.is(dojo.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);
@@ -603,43 +599,43 @@ function test_date_add_diff_weekday(t){
 	// Should be Mon, Jan 3
 	dtB = dojo.date.add(dtA, interv, 1);
 	t.is(dojo.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);
-	
+
 	// 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);
-	
+
 	// 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);
-	
+
 	// 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);
-	
+
 	// 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);
-	
+
 	// 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);
-	
+
 	// Sun, Jan 23
 	dtA = new Date(2000, 0, 23);
 	// Should be Fri, Jan 7
@@ -693,7 +689,7 @@ function test_date_add_diff_second(t){
 	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);
-	
+
 	// Test environment JS Date doesn't support millisec?
 	//interv = "millisecond";
 	//
@@ -707,6 +703,4 @@ function test_date_add_diff_second(t){
 }
 	]
 );
-
-dojo.require("tests.date.locale");
-dojo.require("tests.date.stamp");
+});
diff --git a/dojo/tests/date/locale.js b/dojo/tests/date/locale.js
index cb37e92..d6d6532 100644
--- a/dojo/tests/date/locale.js
+++ b/dojo/tests/date/locale.js
@@ -1,4 +1,4 @@
-dojo.provide("tests.date.locale");
+dojo.provide("dojo.tests.date.locale");
 
 dojo.require("dojo.date.locale");
 
@@ -12,22 +12,20 @@ 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.global.define && define.vendor!="dojotoolkit.org"){ //tests for the AMD loader
-            var
-              def = new doh.Deferred(),
-              deps = [];
-            dojo.forEach(partLocaleList, function(locale){
-              deps.push(dojo.getL10nName("dojo/cldr", "gregorian", locale));
-            });
-            define(deps, function(){
-							def.callback(true);
-            });
-            return def;
-        }else{ // tests for the v1.x loader/i18n machinery
-  				dojo.forEach(partLocaleList, function(locale){
-	  				dojo.requireLocalization("dojo.cldr", "gregorian", locale);
-		  		});
-        }
+				if(dojo.isAsync){
+					var def = new doh.Deferred(),
+						deps = dojo.map(partLocaleList, function(locale){
+							return dojo.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){
+						dojo.requireLocalization("dojo.cldr", "gregorian", locale);
+					});
+				}
 			},
 			tearDown: function(){
 				//Clean up bundles that should not exist if
@@ -187,7 +185,7 @@ tests.register("tests.date.locale",
 	//nichi (day): \u65e5
 	//kinyoubi (Friday): \u91d1\u66dc\u65e5
 	//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'}));
@@ -248,7 +246,11 @@ tests.register("tests.date.locale",
 
 	t.is( new Date(2006, 7, 11), dojo.date.locale.parse("11082006", {datePattern:"ddMMyyyy", selector:"date"}));
 
-	t.is( new Date(2006, 7, 31), dojo.date.locale.parse("31Aug2006", {datePattern:"ddMMMyyyy", selector:"date"}));
+	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), 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'}));
 
 			}
 		},
@@ -257,7 +259,7 @@ 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: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());
 			}
@@ -397,7 +399,7 @@ function test_validate_datetime_is24HourTime(){
 }
 
 function test_validate_datetime_isValidDate(){
-	
+
 	// Month date year
 	jum.assertTrue("test1", dojo_validate_isValidDate("08/06/2005", "MM/dd/yyyy"));
 	jum.assertTrue("test2", dojo_validate_isValidDate("08.06.2005", "MM.dd.yyyy"));
diff --git a/dojo/tests/date/stamp.js b/dojo/tests/date/stamp.js
index d3c6036..04c4044 100644
--- a/dojo/tests/date/stamp.js
+++ b/dojo/tests/date/stamp.js
@@ -1,4 +1,4 @@
-dojo.provide("tests.date.stamp");
+dojo.provide("dojo.tests.date.stamp");
 
 dojo.require("dojo.date.stamp");
 
diff --git a/dojo/tests/dnd/flickr_viewer.html b/dojo/tests/dnd/flickr_viewer.html
index 4ede297..4520f35 100644
--- a/dojo/tests/dnd/flickr_viewer.html
+++ b/dojo/tests/dnd/flickr_viewer.html
@@ -40,6 +40,7 @@
 		.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>
@@ -47,6 +48,7 @@
 	<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">
 		dojo.require("dojo.parser");
 		dojo.require("dojo.io.script");
diff --git a/dojo/tests/dnd/test_box_constraints.html b/dojo/tests/dnd/test_box_constraints.html
index b45097c..5217562 100644
--- a/dojo/tests/dnd/test_box_constraints.html
+++ b/dojo/tests/dnd/test_box_constraints.html
@@ -20,7 +20,9 @@
 		}
 	</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">
 		dojo.require("dojo.parser");
 		dojo.require("dojo.dnd.move");
diff --git a/dojo/tests/dnd/test_container.html b/dojo/tests/dnd/test_container.html
index 352aa7a..a8b2cc4 100644
--- a/dojo/tests/dnd/test_container.html
+++ b/dojo/tests/dnd/test_container.html
@@ -12,9 +12,11 @@
 
 	</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">
-		// dojo.require("dojo.dnd.Container");
+		dojo.require("dojo.dnd.Container");
 		var c1, c2, c3, c4, c5;
 		var init = function(){
 			c1 = new dojo.dnd.Container(dojo.byId("container1"));
diff --git a/dojo/tests/dnd/test_container_markup.html b/dojo/tests/dnd/test_container_markup.html
index 4bde544..415ad28 100644
--- a/dojo/tests/dnd/test_container_markup.html
+++ b/dojo/tests/dnd/test_container_markup.html
@@ -12,7 +12,9 @@
 
 	</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">
 		dojo.require("dojo.parser");
 		dojo.require("dojo.dnd.Container");
diff --git a/dojo/tests/dnd/test_custom_constraints.html b/dojo/tests/dnd/test_custom_constraints.html
index ec71844..efece52 100644
--- a/dojo/tests/dnd/test_custom_constraints.html
+++ b/dojo/tests/dnd/test_custom_constraints.html
@@ -19,7 +19,9 @@
 		}
 	</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">
 		dojo.require("dojo.dnd.move");
 		
diff --git a/dojo/tests/dnd/test_dnd.html b/dojo/tests/dnd/test_dnd.html
index 5729b97..7865233 100644
--- a/dojo/tests/dnd/test_dnd.html
+++ b/dojo/tests/dnd/test_dnd.html
@@ -24,14 +24,14 @@
 	</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");
@@ -64,7 +64,7 @@
 					console.debug(copy ? "Copying from" : "Moving from", source);
 				}
 			});
-		};
+		}
 
 		dojo.addOnLoad(init);
 
diff --git a/dojo/tests/dnd/test_dnd_handles.html b/dojo/tests/dnd/test_dnd_handles.html
index 9ab99bd..44b1d96 100644
--- a/dojo/tests/dnd/test_dnd_handles.html
+++ b/dojo/tests/dnd/test_dnd_handles.html
@@ -15,13 +15,13 @@
 	</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">
 		dojo.require("dojo.parser");
 		dojo.require("dojo.dnd.Source");
diff --git a/dojo/tests/dnd/test_form.html b/dojo/tests/dnd/test_form.html
index cac46c0..0b0ad70 100644
--- a/dojo/tests/dnd/test_form.html
+++ b/dojo/tests/dnd/test_form.html
@@ -18,22 +18,13 @@
 	</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">
 		dojo.require("dojo.parser");
-		//dojo.require("dojo.dnd.Source");
-		//dojo.require("dojo.dnd.Manager");
-	
+		dojo.require("dojo.dnd.Source");
+
 		var c1, c2;
 	
-		function init(){
-
+		dojo.ready(function(){
 			c1 = new dojo.dnd.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"]});
@@ -42,9 +33,7 @@
 			dojo.subscribe("/dnd/start",function(foo){
 				console.debug(foo);
 			});
-
-		};
-		dojo.addOnLoad(init);
+		});
 	</script>
 </head>
 <body>
diff --git a/dojo/tests/dnd/test_moveable.html b/dojo/tests/dnd/test_moveable.html
index 2ed8620..336a95b 100644
--- a/dojo/tests/dnd/test_moveable.html
+++ b/dojo/tests/dnd/test_moveable.html
@@ -48,9 +48,11 @@
 		}
 	</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">
 		dojo.require("dojo.dnd.move");
 		var m1, m2;
@@ -59,18 +61,18 @@
 			m2 = new dojo.dnd.Moveable("moveable2");
 			m3 = new dojo.dnd.Moveable("moveable3");
 
-			dojo.subscribe("/dnd/move/start", function(mover){ 
-				console.debug("Start move", mover); 	
+			dojo.subscribe("/dnd/move/start", function(mover){
+				console.debug("Start move", mover, mover.node);
 			});
-			dojo.subscribe("/dnd/move/stop", function(mover){ 
-				console.debug("Stop move", mover); 	
+			dojo.subscribe("/dnd/move/stop", function(mover){
+				console.debug("Stop move", mover, mover.node);
 			});
 			
 			dojo.connect(m1, "onMoveStart", function(mover){
-				console.debug("Start moving m1", mover); 	
+				console.debug("Start moving m1", mover, mover.node);
 			});
 			dojo.connect(m1, "onMoveStop", function(mover){
-				console.debug("Stop moving m1", mover); 	
+				console.debug("Stop moving m1", mover, mover.node);
 			});
 		};
 		dojo.addOnLoad(init);
diff --git a/dojo/tests/dnd/test_moveable_markup.html b/dojo/tests/dnd/test_moveable_markup.html
index 9691f4c..96be17f 100644
--- a/dojo/tests/dnd/test_moveable_markup.html
+++ b/dojo/tests/dnd/test_moveable_markup.html
@@ -40,7 +40,9 @@
 		}
 	</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">
 		dojo.require("dojo.parser");
 		dojo.require("dojo.dnd.move");
diff --git a/dojo/tests/dnd/test_params.html b/dojo/tests/dnd/test_params.html
index 8d5531b..a4049df 100644
--- a/dojo/tests/dnd/test_params.html
+++ b/dojo/tests/dnd/test_params.html
@@ -18,7 +18,9 @@
 		}
 	</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">
 		dojo.require("dojo.dnd.move");
 		var m1, m2, m3, m4;
diff --git a/dojo/tests/dnd/test_parent_constraints.html b/dojo/tests/dnd/test_parent_constraints.html
index 31c2661..03abd75 100644
--- a/dojo/tests/dnd/test_parent_constraints.html
+++ b/dojo/tests/dnd/test_parent_constraints.html
@@ -27,7 +27,9 @@
 		}
 	</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">
 		dojo.require("dojo.dnd.move");
 		var m1, m2, m3, m4;
diff --git a/dojo/tests/dnd/test_parent_constraints_margins.html b/dojo/tests/dnd/test_parent_constraints_margins.html
index 0e92422..fa5ec05 100644
--- a/dojo/tests/dnd/test_parent_constraints_margins.html
+++ b/dojo/tests/dnd/test_parent_constraints_margins.html
@@ -28,7 +28,9 @@
 		}
 	</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">
 		dojo.require("dojo.dnd.move");
 		var m7, m8;
diff --git a/dojo/tests/dnd/test_selector.html b/dojo/tests/dnd/test_selector.html
index bebdca9..90be71e 100644
--- a/dojo/tests/dnd/test_selector.html
+++ b/dojo/tests/dnd/test_selector.html
@@ -9,11 +9,13 @@
 		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">
-		//dojo.require("dojo.dnd.Selector");
+		dojo.require("dojo.dnd.Selector");
 		var c1, c2, c3, c4, c5;
 		var init = function(){
 			c1 = new dojo.dnd.Selector(dojo.byId("container1"), {singular: true});
diff --git a/dojo/tests/dnd/test_selector_markup.html b/dojo/tests/dnd/test_selector_markup.html
index 43c8e9c..9c42159 100644
--- a/dojo/tests/dnd/test_selector_markup.html
+++ b/dojo/tests/dnd/test_selector_markup.html
@@ -9,7 +9,9 @@
 		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">
 		dojo.require("dojo.parser");
 		dojo.require("dojo.dnd.Selector");
diff --git a/dojo/tests/dnd/test_timed_moveable.html b/dojo/tests/dnd/test_timed_moveable.html
index fa9da06..f6c921f 100644
--- a/dojo/tests/dnd/test_timed_moveable.html
+++ b/dojo/tests/dnd/test_timed_moveable.html
@@ -54,10 +54,12 @@
 		}
 	</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">
 		dojo.require("dojo.dnd.TimedMoveable");
 		var m1, m2;
diff --git a/dojo/tests/fx.html b/dojo/tests/fx.html
index d8992d6..770393e 100644
--- a/dojo/tests/fx.html
+++ b/dojo/tests/fx.html
@@ -3,13 +3,9 @@
 <html>
 	<head>
 		<title>Testing dojo.fx</title>
-		<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">
-			dojo.require("doh.runner");
-			dojo.require("dojo.fx");
-			dojo.require("dojo.fx.easing");
-
-			dojo.addOnLoad(function(){
+			require(["dojo", "doh", "dojo/fx", "dojo/fx/easing", "dojo/domReady!"], function(dojo, doh){
 				doh.register("t", 
 					[
 						function slideTo(t){
@@ -52,7 +48,7 @@
 									node: "foo", 
 									onEnd: function(){
 										console.debug(dojo.style("foo", "height"));
-										doh.t(dojo.style("foo", "height") >  10);
+										doh.t(dojo.style("foo", "height") > 10);
 										d.callback(true);
 									}
 								}).play();
@@ -259,8 +255,8 @@
 						function Toggler(){
 							var d = new doh.Deferred();
 							var t = new dojo.fx.Toggler({
-							    node: "foo",
-							    hideDuration: 100,
+								node: "foo",
+								hideDuration: 100,
 								hideFunc: dojo.fx.wipeOut,
 								showFunc: dojo.fx.wipeIn 
 							});
@@ -365,6 +361,46 @@
 								anim.play();
 								return d;
 							}
+						},
+						{
+							name: "wipeOut onStop",
+							timeout: 1500,
+							runTest: function(t){
+								dojo.byId("foo").style.height = "auto";
+								dojo.byId("foo").style.overflow = "visible";
+								var d = new doh.Deferred();
+								var w = dojo.fx.wipeOut({
+									node: "foo",
+									duration: 1000
+								});
+								dojo.connect(w, "onStop", function(){
+									doh.t(dojo.byId("foo").style.overflow == "visible");
+									d.callback(true);
+								});
+								w.play();
+								setTimeout(function(){ w.stop(); }, 100);
+								return d;
+							}
+						},
+						{
+							name: "wipeIn onStop",
+							timeout: 1500,
+							runTest: function(t){
+								dojo.byId("foo").style.height = "0px";
+								dojo.byId("foo").style.overflow = "visible";
+								var d = new doh.Deferred();
+								var w = dojo.fx.wipeIn({
+									node: "foo",
+									duration: 1000
+								});
+								dojo.connect(w, "onStop", function(){
+									doh.t(dojo.byId("foo").style.overflow == "visible");
+									d.callback(true);
+								});
+								w.play();
+								setTimeout(function(){ w.stop(); }, 100);
+								return d;
+							}
 						}
 					]
 				);
@@ -416,8 +452,8 @@
 			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
+			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>
diff --git a/dojo/tests/fx.js b/dojo/tests/fx.js
index 9d17b05..e6d942e 100644
--- a/dojo/tests/fx.js
+++ b/dojo/tests/fx.js
@@ -1,5 +1,7 @@
-dojo.provide("tests.fx");
-if(dojo.isBrowser){
-	doh.registerUrl("tests.fx", dojo.moduleUrl("tests", "fx.html"), 30000);
-	doh.registerUrl("tests.NodeList-fx", dojo.moduleUrl("tests", "NodeList-fx.html"));
-}
+define(["doh", "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 b0d361d..fc9055b 100644
--- a/dojo/tests/hash.js
+++ b/dojo/tests/hash.js
@@ -1,20 +1,17 @@
-dojo.provide("tests.hash");
-dojo.require("dojo.hash");
+define(["../main", "doh", "../hash"], function(dojo, doh){
 
-(function(){
-
-// utilities for the tests:
+	// utilities for the tests:
 	function setHash(h){
 		h = h || "";
 		location.replace('#'+h);
 	}
-	
+
 	function getHash(){
 		var h = location.href, i = h.indexOf("#");
 		return (i >= 0) ? h.substring(i + 1) : "";
 	}
 
-	tests.register("tests.hash", [
+	doh.register("tests.hash", [
 		// hash as an empty string.
 		{
 			name: "Getting an empty hash",
@@ -159,7 +156,7 @@ dojo.require("dojo.hash");
 				setHash();
 			}
 		},
-		
+
 		// hash with trailing space:
 		{
 			name: "Getting the hash of 'trailingSpace%20'",
@@ -296,7 +293,7 @@ dojo.require("dojo.hash");
 		},
 		{
 			_s: null, // used for the subscriber.
-		
+
 			name: "Hash change publishes to '/dojo/hashchange'",
 			setUp: function(t){
 				setHash();
@@ -311,7 +308,7 @@ dojo.require("dojo.hash");
 						d.errback(e);
 					}
 				});
-				
+
 				dojo.hash('test');
 				return d;
 			},
@@ -321,4 +318,4 @@ dojo.require("dojo.hash");
 			}
 		}
 	]);
-})();
+});
diff --git a/dojo/tests/html.js b/dojo/tests/html.js
index 4652004..8bbb712 100644
--- a/dojo/tests/html.js
+++ b/dojo/tests/html.js
@@ -1,4 +1,5 @@
-dojo.provide("tests.html");
-if(dojo.isBrowser){
-	doh.registerUrl("tests.html", dojo.moduleUrl("tests", "html/test_set.html"));
-}
+define(["doh", "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 aeb48f9..e23ad5d 100644
--- a/dojo/tests/html/test_set.html
+++ b/dojo/tests/html/test_set.html
@@ -5,12 +5,8 @@
 	<title>dojo.html.set test</title>
 
 	<script src='../../dojo.js' djConfig='isDebug:true, parseOnLoad:false'></script>
-	<script src='../../html.js'></script>
-	<script src='../../../util/doh/runner.js'></script>
 	<script>
-		dojo.require('doh.runner');
-		dojo.require('dojo.html');
-		dojo.require('dojo.NodeList-html');
+		require(["dojo", "doh", "dojo/html", "dojo/NodeList-html"], function(dojo, doh){
 
 		/* test goals
 		 * injecting content as string, node, nodelist. 
@@ -231,7 +227,7 @@
 							{
 								"testname": "basicChecks setNodeList"
 							});
-						var res = dojo.query("li", dojo.byId("pane1")).length
+						var res = dojo.query("li", dojo.byId("pane1")).length;
 						doh.is(2, res);
 					},
 					tearDown: function(){
@@ -461,12 +457,14 @@
 							{
 								dir: "rtl",
 								lang: "it_it",
+								textDir: "ltr",
 								parseContent: true
 							}
 						);
 						doh.t(parserCalled, "parser was called");
 						doh.is("rtl", inherited.dir, "dir");
 						doh.is("it_it", inherited.lang, "lang");
+						doh.is("ltr", inherited.textDir, "textdir");
 					},
 					tearDown: function(){
 						dojo.disconnect(handle);
@@ -476,7 +474,8 @@
 			]);
 
 			doh.run();
-		}); 
+		});
+		});
 	</script>
 	<style>
 		@import "../../../dojo/resources/dojo.css";
diff --git a/dojo/tests/i18n.html b/dojo/tests/i18n.html
new file mode 100644
index 0000000..41a93ac
--- /dev/null
+++ b/dojo/tests/i18n.html
@@ -0,0 +1,71 @@
+<html>
+	<head>
+		<title>testing i18n extra locales</title>
+		<!-- gotta do this in a separate page since clearing all the caches in the loader and dojo/i18n is too error-prone -->
+
+		<script type="text/javascript">
+			var dohArgs= (window.parent.doh && window.parent.doh.dohArgs) || {async:0};
+			var dojoConfig = {
+				async:dohArgs.async,
+				extraLocale:['en-us-hawaii', 'en-us-new_york-brooklyn'],
+				has:{
+					"dojo-unit-tests":1
+				}
+			};
+		</script>
+
+		<script type="text/javascript" src="../dojo.js" data-dojo-config=""></script>
+
+		<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){
+			if(dohArgs.async){
+				doh.register(function extraLocalesAsync(t){
+					// the following should load synchronously...at least with the dojo loader
+					var hawaii, ny;
+					require(["dojo/i18n!dojo/tests/nls/en-us-hawaii/salutations"], function(bundle){ hawaii = bundle;});
+					require(["dojo/i18n!dojo/tests/nls/en-us-new_york-brooklyn/salutations"], function(bundle){ ny = bundle;});
+					t.is(hawaii.hello, "Aloha");
+					t.is(ny.hello, "Yo");
+					try{
+						var result = require("dojo/i18n!dojo/tests/nls/ar/salutations");
+						t.f(true, "should have thrown");
+					}catch(e){
+						t.t(true);
+					}
+				});
+			}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");
+					try{
+						t.is(dojo.i18n.getLocalization("dojo/tests", "salutations", "en-au").hello, "G'day");
+					}catch(e){
+						t.f("synchronous get should work if not xdomain");
+					}
+				});
+			}
+
+
+		if(has("dojo-unit-tests")){
+			console.log("here");
+			dojo.forEach(i18n.unitTests, function(item){item(doh);});
+		}
+
+
+			doh.runOnLoad();
+		});
+		if(!require.async){
+			dojo.requireLocalization("dojo.tests._base.loader", "syncBundle", "ab-cd-ef");
+			dojo.requireLocalization("dojo.tests._base.loader", "amdBundle", "ab-cd-ef");
+			doh.register(function oldAndNewBundleStyles(t){
+				t.is(dojo.i18n.getLocalization("dojo.tests._base.loader", "syncBundle", "ab-cd-ef").syncBundle, "syncBundle-ab-cd-ef");
+				t.is(dojo.i18n.getLocalization("dojo.tests._base.loader", "amdBundle", "ab-cd-ef").amdBundle, "amdBundle-ab-cd-ef");
+			});
+		}
+
+		</script>
+	</head>
+	<body>
+	</body>
+</html>
diff --git a/dojo/tests/i18n.js b/dojo/tests/i18n.js
index f24a5fc..f3e84bb 100644
--- a/dojo/tests/i18n.js
+++ b/dojo/tests/i18n.js
@@ -1,137 +1,51 @@
-if(this.define && define.vendor!="dojotoolkit.org"){ //tests for the AMD loader
-
-// notice the module name is more precise with async tests; to wit, "dojo/tests/ compared to "tests"
-// "tests" could be used, but the accompanying change must be made in each of the i18n resources in
-// dojo/tests/nls.
-
-  define(["dojo", "plugin/i18n"], function(dojo) {
-    var
-      getTest = function(value, locale){
-        return function(){
-          var def = new doh.Deferred();
-          define([dojo.getL10nName("dojo/tests", "salutations", locale)], function(bundle){
-            doh.assertEqual(value, dojo.getL10n("dojo/tests", "salutations", locale).hello);
- 					  def.callback(true);
-          });
-          return def;
-        };
-      },
-
-      getFixture = function(locale, value){
-        return {
-          name: "salutations-"+locale,
-          timeout: 2000,
-          runTest: getTest(value, locale)
-        };
-      },
-
-      testSet = [
-        // Locale which overrides root translation
-        getFixture("de", "Hallo"),
-        // Locale which does not override root translation
-        getFixture("en", "Hello"),
-        // Locale which overrides its parent
-        getFixture("en-au", "G'day"),
-        // Locale which does not override its parent
-        getFixture("en-us", "Hello"),
-        // Locale which overrides its parent
-        getFixture("en-us-texas", "Howdy"),
-        // 3rd level variant which overrides its parent
-        getFixture("en-us-new_york", "Hello"),
-        // Locale which overrides its grandparent
-        getFixture("en-us-new_york-brooklyn", "Yo"),
-        // Locale which does not have any translation available
-        getFixture("xx", "Hello"),
-        // A double-byte string.  Everything should be read in as UTF-8 and treated as unicode within Javascript.
-        getFixture("zh-cn", "\u4f60\u597d")
-      ];
-    tests.register("tests.i18n", testSet);
-  });
-} else { // tests for the v1.x loader/i18n machinery
-
-dojo.provide("tests.i18n");
-
-dojo.require("dojo.i18n");
-
-(function(){
-	var setUp = function(locale){
-		return function(){
-			dojo.requireLocalization("tests","salutations",locale);
-		}
-	}
-
-	var getTest = function(value, locale){
-		return function(){
-			doh.assertEqual(value, dojo.i18n.getLocalization("tests", "salutations", locale).hello);
-		}
-	}
-
-	var getFixture = function(locale, value){
-		return {
-			name: "salutations-"+locale,
-			setUp: setUp(locale),
-			runTest: getTest(value, locale)
-		};
-	}
-
-	var testSet = [
-	/* needs dojo.string,
-		// This doesn't actually test anything, it just gives an impressive list of translated output to the console
-		// See the 'salutations' test for something verifyable
-		function fun(t){
-			var salutations_default = dojo.i18n.getLocalization("tests", "salutations");
-			console.debug("In the local language: "+salutations_default.hello);
-
-			var salutations_en = dojo.i18n.getLocalization("tests", "salutations", "en");
-
-			for (i in tests.nls.salutations) {
-				var loc = i.replace('_', '-');
-				var salutations = dojo.i18n.getLocalization("tests", "salutations", loc);
-				var language_as_english = salutations_en[loc];
-				var language_as_native = salutations[loc];
-				var hello_dojo = dojo.string.substitute(salutations.hello_dojo, salutations);
-				if (!dojo.i18n.isLeftToRight(loc)) {
-					var RLE = "\u202b";
-					var PDF = "\u202c";
-					hello_dojo = RLE + hello_dojo + PDF;
-				}
-				hello_dojo += "\t[" + loc + "]";
-				if(language_as_english){hello_dojo += " " + language_as_english;}
-				if(language_as_native){hello_dojo += " (" + language_as_native + ")";}
-				console.debug(hello_dojo);
-			}
-
-			t.assertTrue(true);
+define(["../main", "doh", "require", "../i18n"], function(dojo, doh, require){
+	var
+		getAsyncTest = function(value, locale){
+			return function(){
+				var def = new doh.Deferred();
+				require([dojo.getL10nName("dojo/tests", "salutations", locale)], function(bundle){
+					doh.assertEqual(value, bundle.hello);
+					def.callback(true);
+				});
+				return def;
+			};
 		},
-	*/
 
-		// Test on-the-fly loading of localized string bundles from different locales, and
-		// the expected inheritance behavior
+		getSyncTest = function(value, locale){
+			return function(){
+				doh.assertEqual(value, dojo.i18n.getLocalization("dojo/tests", "salutations", locale).hello);
+			};
+		},
 
-		// Locale which overrides root translation
-		getFixture("de", "Hallo"),
-		// Locale which does not override root translation
-		getFixture("en", "Hello"),
-		// Locale which overrides its parent
-		getFixture("en-au", "G'day"),
-		// Locale which does not override its parent
-		getFixture("en-us", "Hello"),
-		// Locale which overrides its parent
-		getFixture("en-us-texas", "Howdy"),
-		// 3rd level variant which overrides its parent
-		getFixture("en-us-new_york", "Hello"),
-		// Locale which overrides its grandparent
-		getFixture("en-us-new_york-brooklyn", "Yo"),
-		// Locale which does not have any translation available
-		getFixture("xx", "Hello"),
-		// A double-byte string.  Everything should be read in as UTF-8 and treated as unicode within Javascript.
-		getFixture("zh-cn", "\u4f60\u597d")
-	];
-	testSet[testSet.length-1].tearDown = function(){
-		// Clean up bundles that should not exist if the test is re-run.
-		delete tests.nls.salutations;
-	};
-	tests.register("tests.i18n", testSet);
-})();
+		getFixture = function(locale, value){
+			return {
+				name: "salutations-"+locale,
+				timeout: 2000,
+				runTest: (require.async ? getAsyncTest : getSyncTest)(value, locale)
+			};
+		},
 
-}
+		testSet = [
+			// Locale which overrides root translation
+			getFixture("de", "Hallo"),
+			// Locale which does not override root translation
+			getFixture("en", "Hello"),
+			// Locale which overrides its parent
+			getFixture("en-au", "G'day"),
+			// Locale which does not override its parent
+			getFixture("en-us", "Hello"),
+			// Locale which overrides its parent
+			getFixture("en-us-texas", "Howdy"),
+			// 3rd level variant which overrides its parent
+			getFixture("en-us-new_york", "Hello"),
+			// Locale which overrides its grandparent
+			getFixture("en-us-new_york-brooklyn", "Yo"),
+			// Locale which does not have any translation available
+			getFixture("xx", "Hello"),
+			// 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});
+});
diff --git a/dojo/tests/io/iframe.html b/dojo/tests/io/iframe.html
index 7e465ad..c87c404 100644
--- a/dojo/tests/io/iframe.html
+++ b/dojo/tests/io/iframe.html
@@ -6,158 +6,152 @@
 		<style type="text/css">
 			@import "../../resources/dojo.css";
 		</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">
-			dojo.require("doh.runner");
-			dojo.require("dojo.io.iframe");
-
-			dojo.addOnLoad(function(){
-				doh.register("t", 
-					[
-						function ioIframeGetText(t){
-							var d = new doh.Deferred();
-							var td = dojo.io.iframe.send({
-								url: "iframeResponse.text.html",
-								method: "GET",
-								timeoutSeconds: 5,
-								preventCache: true,
-								handle: function(res, ioArgs){
-									if(!(res instanceof Error) && 
-										t.is("iframe succeeded", res)){
-										d.callback(true);
-									}else{
-										d.errback(false);
-									}								
+			require(["dojo", "doh", "dojo/io/iframe"], function(dojo, doh){
+				doh.register([
+					function ioIframeGetText(t){
+						var d = new doh.Deferred();
+						var td = dojo.io.iframe.send({
+							url: "iframeResponse.text.html",
+							method: "GET",
+							timeoutSeconds: 5,
+							preventCache: true,
+							handle: function(res, ioArgs){
+								if(!(res instanceof Error) &&
+									t.is("iframe succeeded", res)){
+									d.callback(true);
+								}else{
+									d.errback(false);
 								}
-							});
-							return d;							
-						},
+							}
+						});
+						return d;
+					},
 
-						function ioIframeGetJson(t){
-							var d = new doh.Deferred();
-							var td = dojo.io.iframe.send({
-								url: "iframeResponse.json.html",
-								method: "GET",
-								timeoutSeconds: 5,
-								preventCache: true,
-								handleAs: "json",
-								handle: function(res, ioArgs){
-									if(!(res instanceof Error) && 
-										t.is("blue", res.color)){
-										d.callback(true);
-									}else{
-										d.errback(false);
-									}								
+					function ioIframeGetJson(t){
+						var d = new doh.Deferred();
+						var td = dojo.io.iframe.send({
+							url: "iframeResponse.json.html",
+							method: "GET",
+							timeoutSeconds: 5,
+							preventCache: true,
+							handleAs: "json",
+							handle: function(res, ioArgs){
+								if(!(res instanceof Error) &&
+									t.is("blue", res.color)){
+									d.callback(true);
+								}else{
+									d.errback(false);
 								}
-							});
-							return d;							
-						},
+							}
+						});
+						return d;
+					},
 
-						function ioIframeGetJavascript(t){
-							var d = new doh.Deferred();
-							var td = dojo.io.iframe.send({
-								url: "iframeResponse.js.html",
-								method: "GET",
-								timeoutSeconds: 5,
-								preventCache: true,
-								handleAs: "javascript",
-								handle: function(res, ioArgs){
-									console.log("RES: ", res);
-									if(!(res instanceof Error) && 
-										t.is(42, window.iframeTestingFunction())){
-										d.callback(true);
-									}else{
-										d.errback(false);
-									}								
+					function ioIframeGetJavascript(t){
+						var d = new doh.Deferred();
+						var td = dojo.io.iframe.send({
+							url: "iframeResponse.js.html",
+							method: "GET",
+							timeoutSeconds: 5,
+							preventCache: true,
+							handleAs: "javascript",
+							handle: function(res, ioArgs){
+								console.log("RES: ", res);
+								if(!(res instanceof Error) &&
+									t.is(42, window.iframeTestingFunction())){
+									d.callback(true);
+								}else{
+									d.errback(false);
 								}
-							});
-							return d;							
-						},
+							}
+						});
+						return d;
+					},
 
-						function ioIframeGetHtml(t){
-							var d = new doh.Deferred();
-							var td = dojo.io.iframe.send({
-								url: "iframeResponse.html",
-								method: "GET",
-								timeoutSeconds: 5,
-								preventCache: true,
-								handleAs: "html",
-								handle: function(res, ioArgs){
-									if(!(res instanceof Error) && 
-										t.is("SUCCESSFUL HTML response", res.getElementsByTagName("h1")[0].innerHTML)){
-										d.callback(true);
-									}else{
-										d.errback(false);
-									}								
+					function ioIframeGetHtml(t){
+						var d = new doh.Deferred();
+						var td = dojo.io.iframe.send({
+							url: "iframeResponse.html",
+							method: "GET",
+							timeoutSeconds: 5,
+							preventCache: true,
+							handleAs: "html",
+							handle: function(res, ioArgs){
+								if(!(res instanceof Error) &&
+									t.is("SUCCESSFUL HTML response", res.getElementsByTagName("h1")[0].innerHTML)){
+									d.callback(true);
+								}else{
+									d.errback(false);
 								}
-							});
-							return d;							
-						},
+							}
+						});
+						return d;
+					},
 
-						function ioIframeGetXml(t){
-							var d = new doh.Deferred();
-							var td = dojo.io.iframe.send({
-								url: "iframeResponse.xml",
-								method: "GET",
-								timeoutSeconds: 5,
-								preventCache: true,
-								handleAs: "xml",
-								handle: function(res, ioArgs){
-									if(!(res instanceof Error) 
-										&& t.is(4, res.documentElement.getElementsByTagName("child").length)
-									){
-										d.callback(true);
-									} else {
-										d.errback(false);
-									}
+					function ioIframeGetXml(t){
+						var d = new doh.Deferred();
+						var td = dojo.io.iframe.send({
+							url: "iframeResponse.xml",
+							method: "GET",
+							timeoutSeconds: 5,
+							preventCache: true,
+							handleAs: "xml",
+							handle: function(res, ioArgs){
+								if(!(res instanceof Error)
+									&& t.is(4, res.documentElement.getElementsByTagName("child").length)
+								){
+									d.callback(true);
+								} else {
+									d.errback(false);
 								}
-							});
-							return d;
-						},
-						function ioIframeContentArray(t){
-							//Tests if an array passed in content causes as an error on cleanup.
-							var d = new doh.Deferred();
-							var td = dojo.io.iframe.send({
-								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);
-									}
+							}
+						});
+						return d;
+					},
+					function ioIframeContentArray(t){
+						//Tests if an array passed in content causes as an error on cleanup.
+						var d = new doh.Deferred();
+						var td = dojo.io.iframe.send({
+							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);
 								}
-							});
-							return d;
+							}
+						});
+						return d;
+					}
+				]);
+				doh.runOnLoad();
+/*
+				// for watching in the debugger...
+				dojo.addOnLoad(function(){
+					var td = dojo.io.iframe.get({
+						url: "iframeResponse.text.html",
+						timeoutSeconds: 5,
+						preventCache: true,
+						handle: function(res, ioArgs){
+							if(!(res instanceof Error) &&
+								"iframe succeeded" == res){
+								console.debug("OK");
+							}else{
+								console.debug("Error", res);
+							}
 						}
-					]
-				);
-				doh.run();
+					});
+				});
+*/
 			});
 
-/*
-dojo.addOnLoad(function(){
-	var td = dojo.io.iframe.get({
-		url: "iframeResponse.text.html",
-		timeoutSeconds: 5,
-		preventCache: true,
-		handle: function(res, ioArgs){
-			if(!(res instanceof Error) && 
-				"iframe succeeded" == res){
-				console.debug("OK");
-			}else{
-				console.debug("Error", res);
-			}								
-		}
-	});
-});
-*/
 		</script>
 	</head>
 	<body>
-
 		<form id="contentArrayTest" method="get" enctype="multipart/form-data">
 		</form>
 	</body>
diff --git a/dojo/tests/io/iframe.js b/dojo/tests/io/iframe.js
index 7f880ef..fab619c 100644
--- a/dojo/tests/io/iframe.js
+++ b/dojo/tests/io/iframe.js
@@ -1,4 +1,5 @@
-dojo.provide("tests.io.iframe");
-if(dojo.isBrowser){
-	doh.registerUrl("tests.io.iframe", dojo.moduleUrl("tests.io", "iframe.html"));
-}
+define(["doh", "require"], function(doh, require){
+	if(doh.isBrowser){
+		doh.register("tests.io.iframe", require.toUrl("./iframe.html"));
+	}
+});
diff --git a/dojo/tests/io/script.html b/dojo/tests/io/script.html
index e806000..24e89ac 100644
--- a/dojo/tests/io/script.html
+++ b/dojo/tests/io/script.html
@@ -6,114 +6,105 @@
 		<style type="text/css">
 			@import "../../resources/dojo.css";
 		</style>
-		<script type="text/javascript" 
-			src="../../dojo.js" djConfig="isDebug: true"></script>
-		<script type="text/javascript" 
-			src="../../io/script.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug:true"></script>
 		<script type="text/javascript">
-			dojo.require("doh.runner");
-			dojo.require("dojo.io.script");
-
-			dojo.addOnLoad(function(){
-				doh.register("t", 
-					[
-						function ioScriptLoad(t){
-							//t.is("undefined", typeof(scriptLoad));
-							var d = new doh.Deferred();
-							var td = dojo.io.script.get({
-								url: "scriptLoad.js"
-							});
-							td.addBoth(function(res){
-								if(typeof(scriptLoad) != "undefined"
-									&& t.is("loaded", scriptLoad)){
+			require(["dojo", "doh", "dojo/io/script"], function(dojo, doh){
+				doh.register("t", [
+					function ioScriptLoad(t){
+						//t.is("undefined", typeof(scriptLoad));
+						var d = new doh.Deferred();
+						var td = dojo.io.script.get({
+							url: "scriptLoad.js"
+						});
+						td.addBoth(function(res){
+							if(typeof(scriptLoad) != "undefined"
+								&& t.is("loaded", scriptLoad)){
+								d.callback(true);
+							}else{
+								d.errback(false);
+							}
+						});
+						return d;
+					},
+					function ioScriptSimple(t){
+						var d = new doh.Deferred();
+						var td = dojo.io.script.get({
+							url: "scriptSimple.js",
+							checkString: "myTasks"
+						});
+						td.addBoth(function(res){
+							if(typeof(myTasks) != "undefined"
+								&& t.is("Do dishes.", myTasks[1])){
+								d.callback(true);
+							}else{
+								d.errback(false);
+							}
+						});
+						return d;
+					},
+					function ioScriptJsonp(t){
+						var d = new doh.Deferred();
+						var td = dojo.io.script.get({
+							url: "scriptJsonp.js",
+							content: { foo: "bar" },
+							jsonp: "callback"
+						});
+						td.addBoth(function(res){
+							if(!(res instanceof Error) && 
+								t.is("mammal", res.animalType)){
+								d.callback(true);
+							}else{
+								d.errback(false);
+							}
+						});
+						return d;							
+					},
+					function ioScriptJsonpTimeout(t){
+						var d = new doh.Deferred();
+						var td = dojo.io.script.get({
+							url: "../_base/timeout.php",
+							callbackParamName: "callback",
+							content: {Foo: 'Bar'},
+							timeout: 500,
+							handleAs: "json",
+							preventCache: true,
+							handle: function(response, ioArgs){
+								if(response instanceof Error && response.dojoType == "timeout"){
+									console.debug("FOO OK TEST");
 									d.callback(true);
 								}else{
+									console.debug("FOO FAIL TEST");
 									d.errback(false);
 								}
-							});
-							return d;
-						},
-						function ioScriptSimple(t){
-							var d = new doh.Deferred();
-							var td = dojo.io.script.get({
-								url: "scriptSimple.js",
-								checkString: "myTasks"
-							});
-							td.addBoth(function(res){
-								if(typeof(myTasks) != "undefined"
-									&& t.is("Do dishes.", myTasks[1])){
-									d.callback(true);
-								}else{
-									d.errback(false);
-								}
-							});
-							return d;
-						},
-						function ioScriptJsonp(t){
-							var d = new doh.Deferred();
-							var td = dojo.io.script.get({
-								url: "scriptJsonp.js",
-								content: { foo: "bar" },
-								jsonp: "callback"
-							});
-							td.addBoth(function(res){
-								if(!(res instanceof Error) && 
-									t.is("mammal", res.animalType)){
-									d.callback(true);
-								}else{
-									d.errback(false);
-								}
-							});
-							return d;							
-						},
-						function ioScriptJsonpTimeout(t){
-							var d = new doh.Deferred();
-							var td = dojo.io.script.get({
-								url: "../_base/timeout.php",
-								callbackParamName: "callback",
-								content: {Foo: 'Bar'},
-								timeout: 500,
-								handleAs: "json",
-								preventCache: true,
-								handle: function(response, ioArgs){
-									if(response instanceof Error && response.dojoType == "timeout"){
-										console.debug("FOO OK TEST");
-										d.callback(true);
-									}else{
-										console.debug("FOO FAIL TEST");
-										d.errback(false);
-									}
-								}
-							});
-							return d;
-						}
-					]
-				);
-				doh.run();
-			});
-
-/*
-			dojo.addOnLoad(function(){
-				td = dojo.io.script.get({
-					url: "scriptSimple.js",
-					checkString: "myTasks"
-				});
-				td.addCallback(function(res){
-					alert(myTasks);
-					alert(myTasks[1]);
-					if(typeof(myTasks) != "undefined"
-						&& "Do dishes." == myTasks[1]){
-						alert("yeah");
-					}else{
-						alert("boo");
+							}
+						});
+						return d;
 					}
+				]);
+				doh.runOnLoad();
+/*
+				// for watching in the debugger...
+				dojo.addOnLoad(function(){
+					td = dojo.io.script.get({
+						url: "scriptSimple.js",
+						checkString: "myTasks"
+					});
+					td.addCallback(function(res){
+						alert(myTasks);
+						alert(myTasks[1]);
+						if(typeof(myTasks) != "undefined"
+							&& "Do dishes." == myTasks[1]){
+							alert("yeah");
+						}else{
+							alert("boo");
+						}
+					});
 				});
-			});
 */
-
+			});
 		</script>
 	</head>
 	<body>
-
+		<h1>dojo.io.script test</h1>
 	</body>
 </html>
diff --git a/dojo/tests/io/script.js b/dojo/tests/io/script.js
index 77bd580..ded51a0 100644
--- a/dojo/tests/io/script.js
+++ b/dojo/tests/io/script.js
@@ -1,4 +1,5 @@
-dojo.provide("tests.io.script");
-if(dojo.isBrowser){
-	doh.registerUrl("tests.io.script", dojo.moduleUrl("tests.io", "script.html"));
-}
+define(["doh", "require"], function(doh, require){
+	if(doh.isBrowser){
+		doh.register("tests.io.script", require.toUrl("./script.html"));
+	}
+});
diff --git a/dojo/tests/json.js b/dojo/tests/json.js
new file mode 100644
index 0000000..ee777a7
--- /dev/null
+++ b/dojo/tests/json.js
@@ -0,0 +1,166 @@
+define(["../main", "doh", "../json"], function(dojo, doh, JSON){
+
+	var mustThrow = function(json){
+		try{
+			JSON.parse(json, true);
+		}catch(e){
+			return;
+		}
+		throw new Error("Invalid JSON " + json + " should have been rejected");
+	};
+
+	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 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}))},
+		// 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");
+
+		},
+		/*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"};}}}))}
+	]);
+
+var smallDataSet = {
+	prop1: null,
+	prop2: true,
+	prop3: [],
+	prop4: 3.4325222223332266,
+	prop5: 10003,
+	prop6: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean semper",
+	prop7: "sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin porta rutrum",
+	prop8: "lacus. Etiam consequat scelerisque quam. Nulla facilisi. Maecenas luctus",
+	prop9: "venenatis nulla. In sit amet dui non mi semper iaculis. Sed molestie",
+	prop10: "tortor at ipsum. Morbi dictum rutrum magna. Sed vitae risus." +
+		"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."
+};
+var smallJson = JSON.stringify(smallDataSet);
+
+var i, mediumDataSet = [];
+for(i = 0; i < 20; i++){
+	mediumDataSet.push({
+		prop1: null,
+		prop2: true,
+		prop3: false,
+		prop4: 3.4325222223332266 - i,
+		prop5: 10003 + i,
+		prop6: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean semper",
+		prop7: "sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin porta rutrum",
+		prop8: "lacus. Etiam consequat scelerisque quam. Nulla facilisi. Maecenas luctus",
+		prop9: "venenatis nulla. In sit amet dui non mi semper iaculis. Sed molestie",
+		prop10: "tortor at ipsum. Morbi dictum rutrum magna. Sed vitae risus." +
+			"Aliquam vitae enim."
+	});
+}
+var mediumJson = JSON.stringify(mediumDataSet);
+
+var largeDataSet = [];
+for(i = 0; i < 100; i++){
+	largeDataSet.push({
+		prop1: null,
+		prop2: true,
+		prop3: false,
+		prop4: 3.4325222223332266 - i,
+		prop5: ["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."
+		],
+		prop6: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean semper",
+		prop7: "sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin porta rutrum",
+		prop8: "lacus. Etiam consequat scelerisque quam. Nulla facilisi. Maecenas luctus",
+		prop9: "venenatis nulla. In sit amet dui non mi semper iaculis. Sed molestie",
+	prop10: "tortor at ipsum. Morbi dictum rutrum magna. Sed vitae risus." +
+		"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."
+	});
+}
+var largeJson = JSON.stringify(largeDataSet);
+
+doh.register("tests.json.performance", [
+		// all tests below are taken from #4.2 of the CSS3 Color Module
+		function small(){
+			var i = 10000;
+			while(i-->0){
+				var result = JSON.parse(smallJson);
+			}
+		},
+		function strictSmall(){
+			var i = 10000;
+			while(i-->0){
+				var result = JSON.parse(smallJson, true);
+			}
+		},
+		function medium(){
+			var i = 1000;
+			while(i-->0){
+				var result = JSON.parse(mediumJson);
+			}
+		},
+		function strictMedium(){
+			var i = 1000;
+			while(i-->0){
+				var result = JSON.parse(mediumJson, true);
+			}
+		},
+		function large(){
+			var i = 100;
+			while(i-->0){
+				var result = JSON.parse(largeJson);
+			}
+		},
+		function strictLarge(){
+			var i = 100;
+			while(i-->0){
+				var result = JSON.parse(largeJson, true);
+			}
+		}
+	]);
+
+});
+
diff --git a/dojo/tests/module.js b/dojo/tests/module.js
index 579b85c..c2f88b8 100644
--- a/dojo/tests/module.js
+++ b/dojo/tests/module.js
@@ -1,36 +1,37 @@
-dojo.provide("dojo.tests.module");
-
-try{
-	dojo.require("tests._base");
-	dojo.require("tests.i18n");
-	dojo.requireIf(dojo.isBrowser, "tests.back-hash");
-	dojo.requireIf(dojo.isBrowser, "tests.hash");
-	dojo.require("tests.cldr");
-	dojo.require("dojo.tests.store");
-	dojo.require("tests.data");
-	dojo.require("tests.date");
-	dojo.require("tests.number");
-	dojo.require("tests.currency");
-	dojo.require("tests.AdapterRegistry");
-	dojo.require("tests.io.script");
-	dojo.require("tests.io.iframe");
-	dojo.requireIf(dojo.isBrowser, "tests.rpc");
-	dojo.require("tests.regexp");
-	dojo.require("tests.string");
-	dojo.require("tests.behavior");
-	dojo.require("tests.parser");
-	dojo.require("tests.colors");
-	dojo.requireIf(dojo.isBrowser,"tests.cookie");
-	dojo.require("tests.fx");
-	dojo.require("tests.DeferredList");
-	dojo.require("tests.Stateful");
-	dojo.require("tests.html");
-	dojo.requireIf(dojo.isBrowser,"tests.NodeList-traverse");
-	dojo.requireIf(dojo.isBrowser,"tests.NodeList-manipulate");
-	dojo.requireIf(dojo.isBrowser,"tests.NodeList-data");
-	dojo.require("tests.cache");
-	dojo.requireIf(dojo.isBrowser, "tests.uacss");
-	dojo.requireIf(dojo.isBrowser, "tests.window");
-}catch(e){
-	doh.debug(e);
-}
+define([
+	"dojo/tests/_base",
+	"dojo/tests/cache",
+	"dojo/tests/i18n",
+	"dojo/tests/cldr",
+	"dojo/tests/store",
+	"dojo/tests/data",
+	"dojo/tests/date",
+	"dojo/tests/on",
+	"dojo/tests/json",
+	"dojo/tests/aspect",
+	"dojo/tests/number",
+	"dojo/tests/currency",
+	"dojo/tests/AdapterRegistry",
+	"dojo/tests/regexp",
+	"dojo/tests/store",
+	"dojo/tests/string",
+	"dojo/tests/colors",
+	"dojo/tests/DeferredList",
+	"dojo/tests/Stateful",
+	"dojo/has!host-browser?dojo/tests/behavior",
+	"dojo/has!host-browser?dojo/tests/parser",
+	"dojo/has!host-browser?dojo/tests/html",
+	"dojo/has!host-browser?dojo/tests/fx",
+	"dojo/has!host-browser?dojo/tests/io/script",
+	"dojo/has!host-browser?dojo/tests/io/iframe",
+	"dojo/has!host-browser?dojo/tests/back-hash",
+	"dojo/has!host-browser?dojo/tests/hash",
+	"dojo/has!host-browser?dojo/tests/rpc",
+	"dojo/has!host-browser?dojo/tests/cookie",
+	"dojo/has!host-browser?dojo/tests/NodeList-traverse",
+	"dojo/has!host-browser?dojo/tests/NodeList-manipulate",
+	"dojo/has!host-browser?dojo/tests/NodeList-data",
+	"dojo/has!host-browser?dojo/tests/uacss",
+	"dojo/has!host-browser?dojo/tests/window",
+	"dojo/has!host-browser?dojo/tests/touch"
+], 1);
diff --git a/dojo/tests/number.js b/dojo/tests/number.js
index 4393b51..d30bcbe 100644
--- a/dojo/tests/number.js
+++ b/dojo/tests/number.js
@@ -1,14 +1,12 @@
-dojo.provide("tests.number");
-
-dojo.require("dojo.number");
-
+define(["../main", "doh", "../number", "../i18n"], function(dojo, doh){
+var tests= {number:{}};
 /**
  * Refer to ICU4J's NumberFormatTest.expect(...)
  */
 tests.number.check=function(t,options,sourceInput,expectResult){
 	tests.number.checkFormatParseCycle(t, t,options,sourceInput,expectResult,false);
 	tests.number.checkParse(t, t,options,expectResult,sourceInput);
-}
+};
 
 /**
  * Perform a single formatting check or a backward check
@@ -22,7 +20,7 @@ tests.number.checkFormatParseCycle=function(t,options,sourceInput,expectResult,
 		var locale = options.locale;
 		//TODO: add more fields
 	}
-	
+
 	//print("\n");
 	var str = null==pattern?"default":pattern;
 	//print("pattern:" + str + "| locale:" + locale);
@@ -44,7 +42,7 @@ tests.number.checkFormatParseCycle=function(t,options,sourceInput,expectResult,
 			t.is(result,resultParsedReformatted);
 		}
 	}
-}
+};
 
 /**
  * Perform a single parsing check
@@ -60,7 +58,7 @@ tests.number.checkParse=function(t,options,sourceInput,expectResult){
 	if(null != expectResult){
 	    t.is(expectResult,result);
 	}
-}
+};
 
 /**
  * //TODO:Round a given number
@@ -70,7 +68,7 @@ tests.number.rounding = function(t,number,maxFractionDigits,expected){
 	for(var i=0; i<maxFractionDigits; i++){pattern += "#";}
 	var result = dojo.number.format(number,{locale:tests.number.locale, pattern:pattern});
 	t.is(expected,result);
-}
+};
 
 /**
  * Run a batch parsing
@@ -80,7 +78,7 @@ function runBatchParse(options,dataArray/*array*/,pass/*boolean*/){
 	var result;
 	var i=0;
 	var str = (null==options.pattern)?"default":options.pattern;
-	
+
 	//print("\n");
 	for(; i<dataArray.length; i++){
 		try{
@@ -95,7 +93,7 @@ function runBatchParse(options,dataArray/*array*/,pass/*boolean*/){
 			break;
 		}
 	}
-		
+
 	if(!pass && (exception == null)) {
 		throw "runBatchParse() - stric parse failed, no exception when parsing illegal data";
 	}else if(exception != null){
@@ -126,9 +124,9 @@ tests.number._decimalNumberDiff = function(num1,num2){
 		return (new Number(s[1])< diffBound);
 	}
 	return false;
-}
+};
 
-tests.register("tests.number",
+doh.register("tests.number",
 	[
 		{
 			// Test formatting and parsing of currencies in various locales pre-built in dojo.cldr
@@ -139,22 +137,22 @@ tests.register("tests.number",
 			runTest: function(t){
 				var partLocaleList = ["en-us", "fr-fr", "de-de"];
 				tests.number.locale = "en-us";
-        if(dojo.global.define && define.vendor!="dojotoolkit.org"){ //tests for the asynchronous loader machinery
-            var
-              def = new doh.Deferred(),
-              deps= [];
-            dojo.forEach(partLocaleList, function(locale){
-              deps.push(dojo.getL10nName("dojo/cldr", "number", locale));
-            });
-            define(deps, function(){
-							def.callback(true);
-            });
-            return def;
-        }else{ // tests for the v1.x loader/i18n machinery
-  				for(var i = 0 ; i < partLocaleList.length; i ++){
-	  				dojo.requireLocalization("dojo.cldr","number",partLocaleList[i]);
-		  		}
-        }
+				if(require.async){
+					var
+						def = new doh.Deferred(),
+						deps = [];
+					dojo.forEach(partLocaleList, function(locale){
+						deps.push(dojo.getL10nName("dojo/cldr", "number", locale));
+					});
+					require(deps, function(){
+						def.callback(true);
+					});
+					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]);
+					}
+				}
 			}
 		},
 		{
@@ -215,7 +213,7 @@ tests.register("tests.number",
 				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");
@@ -226,7 +224,7 @@ tests.register("tests.number",
 				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");
-				
+
 				//negatives
 				t.is(-12345, dojo.number.round(-12345 + -0.1), "rsux200");
 				t.is(-12345, dojo.number.round(-12345 + -0.01), "rsux201");
@@ -242,11 +240,11 @@ tests.register("tests.number",
 				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");
@@ -257,7 +255,7 @@ tests.register("tests.number",
 				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");
@@ -385,7 +383,7 @@ tests.register("tests.number",
 	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'}));
@@ -425,12 +423,12 @@ tests.register("tests.number",
 	var expectResult = "1,234,567,890,987,654,321,234,567,890,987,654,321";
 	tests.number.checkFormatParseCycle(t, null,bigNum,expectResult,false);
 	*/
-	
+
 	//in icu4j should throw out an exception when formatting a string,
 	//but it seems dojo.number.format can deal with strings
 	//return 123,456,789
 	dojo.number.format("123456789");
-	
+
 	//!!Failed case, \u00a4 and ' are not replaced
 	/*
 	var options = {pattern:"'*&'' '\u00a4' ''&*' #,##0.00",locale:"en-us"};
@@ -463,7 +461,7 @@ tests.register("tests.number",
 		options = {pattern:patterns[i], locale: 'en-us'};
 		tests.number.checkFormatParseCycle(t, options,0,num[i],false);
 	}
-	
+
 	//!!Failed case
 	//In ICU4J:
 	//        unquoted special characters in the suffix are illegal
@@ -471,7 +469,7 @@ tests.register("tests.number",
 	//dojo.number.format:
 	//        when formatting 1.2 with illegal pattern "000.000|###"
 	//		  no exception was thrown but got "001.200|###" instead.
-	
+
 	/*
 	patterns = (["000.000|###","000.000'|###'"]);
 	var exception = false;
@@ -512,7 +510,7 @@ tests.register("tests.number",
  */
 	//print("test_number_format_Quotes() start..............");
 	//TODO: add more locales
-	
+
 	//TODO:!!Failed case
 	//Pattern "s'aa''s'c#" should format 6666 to "saa'sc6666", but got s'aa''s'c6666 instead
 	// is this case necessary?
@@ -537,9 +535,9 @@ tests.register("tests.number",
 	tests.number.rounding(t,17.6995, 3, "17.7");
 	tests.number.rounding(t,15.3999, 0, "15");
 	tests.number.rounding(t,-29.6, 0, "-30");
-	
+
 	//TODO refer to NumberFormatTest.TestRounding()
-	
+
 	//print("test_number_format_rounding() end..............");
 			}
 		},
@@ -565,7 +563,7 @@ tests.register("tests.number",
 	var pattern;
 	var result;
 	var expectResult;
-	
+
     //TODO: !!Failed case - ###.###\u2030(\u2030 is ‰)
 	//Pattern ###.###\u2030 should format 0.4857 as 485.7\u2030,but got 485.700\u2030 instead
 	pattern = "###.###\u2030";
@@ -600,10 +598,10 @@ tests.register("tests.number",
 	//step1: 123456789 formated=> 12,34,56,789
 	//step2:12,34,56,789 parsed=> 123456789 => formated => 12,34,56,789
 	tests.number.checkFormatParseCycle(t, options,sourceInput,expectResult,true);
-						  
+
 	//TODO: sencondary grouping not implemented yet ?
 	//Pattern "#,###" and secondaryGroupingSize=4 should format 123456789 to "12,3456,789"
-	
+
 	//Special case for "en-in" locale
 	//1876543210 should be formated as 1,87,65,43,210 in "en-in" (India)
 /*
@@ -657,17 +655,17 @@ function test_number_format_pad(){
 
 	tests.number.check(t, options,0,"^^^^0");
 	tests.number.check(t, options,-1.3,"^-1.3");
-	
-	
+
+
 	options = {pattern:"##0.0####*_ 'g-m/s^2'",locale:locale};
 	tests.number.check(t, options,0,"0.0______ g-m/s^2");
 	tests.number.checkFormatParseCycle(t, options,1.0/3,"0.33333__ g-m/s^2",true);
-	
+
 	//exponent not implemented
 	//options = {pattern:"##0.0####E0*_ 'g-m/s^2'",locale:locale};
 	//tests.number.check(t, options,0,"0.0E0______ g-m/s^2");
 	//tests.number.checkFormatParseCycle(t, options,1.0/3,"333.333E-3_ g-m/s^2",true);
-	
+
 	// Test padding before a sign
 	options = {pattern:"*x#,###,###,##0.0#;*x(###,###,##0.0#)",locale:locale};
 
@@ -709,7 +707,7 @@ function test_number_format_pad(){
 	tests.number.check(t, options, 1120456.37, "1,120,456.37xxxx");
 	tests.number.check(t, options, 112045600.37, "112,045,600.37xx");
 	tests.number.check(t, options, 10252045600.37, "10,252,045,600.37");
-	
+
 	//Not implemented yet,refer to NumberFormatTest.TestPatterns2()
 	//For future use - maily test pad patterns
 	print("test_number_format_Pad() end..............");
@@ -761,7 +759,7 @@ function test_number_format_pad(){
         //,"0E"         //[12]not implemented yet,an exponnent not followed by zero or digits is not an exponent
          ]);
 	runBatchParse(options,passData,true/*tolerant parse*/);
-	
+
 	/*
 	 * TODO:!!Failed case,should all pass,
 	 * but the following failed,
@@ -786,11 +784,11 @@ function test_number_format_pad(){
         "1,23,456,7890" //[14] wrong number of digits in primary and secondary groups
 		]);
 	runBatchParse(options,failData,false);
-	
+
 	 options = {pattern:"#,##,##0.#",locale:"en-us"};
 	/*
 	 * TODO:!!Failed case,shoudl all pass.
-	 
+
 	 * but [1] [2] and [3] failed
 	 * should be parsed to 1234567,but NaN instead
 	 */
@@ -801,7 +799,7 @@ function test_number_format_pad(){
         //"12,34,567 that"	//[3]
 		]);
 	runBatchParse(options,mixedPassData,true/*tolerant parse*/);
-	
+
 	/*
 	 * TODO:!!Failed case,should all pass,
 	 * but actually mixedFailData[2] and mixedFailData[3] passed.
@@ -814,7 +812,7 @@ function test_number_format_pad(){
         //"12,34,56 that",	//[3]
 		]);
 	runBatchParse(options,mixedFailData,false);
-	
+
 
 	/**************************************** strict parse ******************************************
 	 * TODO:May need to test strict parsing in the future?
@@ -831,7 +829,7 @@ function test_number_format_pad(){
 	//options={locale:"en",strict:true};
 	//runBatchParse(options,passData,false/*strict parse*/);
 	//runBatchParse(options,failData,false/*strict parse*/);
-	
+
 	//options = {pattern:"#,##,##0.#",locale:"en-us",strict:true};
 	//runBatchParse(options,mixedPassData,false/*strict parse*/);
 	//runBatchParse(options,mixedFailData,false/*strict parse*/);
@@ -904,7 +902,7 @@ function test_number_format_pad(){
                  -1, 0,  1,
                  1,  1,  2,
                  3,  10, 255]);
-	
+
 	for(var i =0; i < data.length; i++){
 		tests.number.checkParse(t, options,data[i],expected[i]);
 	}
@@ -923,7 +921,7 @@ function test_number_format_pad(){
 	tests.number.checkParse(t, {pattern:"#0.#####", locale: 'en-us'},123.55456,123.55456);
 //!! fails because default pattern only has 3 decimal places
 //	tests.number.checkParse(t, null,123.55456,123.55456);
-	
+
 	//See whether it fails first format 0.0 ,parse "99.99",and then reformat 0.0
 	tests.number.checkFormatParseCycle(t, {pattern:"#.#"},0.0,"0",false);
 	tests.number.checkParse(t, {locale: 'en-us'},"99.99",99.99);
@@ -941,10 +939,10 @@ function test_number_format_pad(){
  * Refer to ICU4J's NumberRegression.Test4088503() and Test4106658()
  */
 	tests.number.checkFormatParseCycle(t, {places:0},123,"123",false);
-	
+
 	//TODO: differernt from ICU where -0.0 is formatted to "-0"
 	tests.number.checkFormatParseCycle(t, {locale:"en-us"},-0.0,"0",false);
-	
+
 	//TODO: differernt from ICU where -0.0001 is formatted to "-0"
 	tests.number.checkFormatParseCycle(t, {locale:"en-us",places:6},-0.0001,"-0.000100",false);
 			}
@@ -969,11 +967,11 @@ function test_number_format_pad(){
 	var pattern = "###.00;(###.00)";
 	var locale = "fr";
 	var options = {pattern:pattern,locale:locale};
-	
+
 	//no group separator
 	tests.number.checkFormatParseCycle(t, options,1234,"1234,00",false);
 	tests.number.checkFormatParseCycle(t, options,-1234,"(1234,00)",false);
-	
+
 	//space as group separator
 	pattern = "#,###.00;(#,###.00)";
 	options = {pattern:pattern,locale:locale};
@@ -1009,12 +1007,12 @@ function test_number_format_pad(){
  */
 	var patterns = (["#0000","#000","#00","#0","#"]);
 	var expect = (["0042","042","42","42","42"]);
-	
+
 	for(var i =0; i < patterns.length; i ++){
 		tests.number.checkFormatParseCycle(t, {pattern:patterns[i]},42,expect[i],false);
 		tests.number.checkFormatParseCycle(t, {pattern:patterns[i]},-42,"-"+expect[i],false);
 	}
-	
+
 	tests.number.checkFormatParseCycle(t, {pattern:"#,#00.00;-#.#", locale: 'en-us'},3456.78,"3,456.78",false);
 	//!!Failed case
 	//tests.number.checkFormatParseCycle(t, {pattern:"#,#00.00 p''ieces;-#,#00.00 p''ieces"},3456.78,"3,456.78 p'ieces",false);
@@ -1031,11 +1029,11 @@ function test_number_format_pad(){
  */
 	//TODO:only got NaN,need an illegal pattern exception?
 	tests.number.checkParse(t, {pattern:"#,#00.00"},"abc3");
-	
+
 	//TODO: got NaN instead of 1.222, is it ok?
 	//tests.number.checkParse(t, {pattern:"#,##0.###",locale:"en-us"},"1.222,111",1.222);
 	//tests.number.checkParse(t, {pattern:"#,##0.###",locale:"en-us"},"1.222x111",1.222);
-	
+
 	//got NaN for illeal input,ok
 	tests.number.checkParse(t, null,"hello: ,.#$@^&**10x");
 			}
@@ -1049,7 +1047,7 @@ function test_number_format_pad(){
 	tests.number.checkFormatParseCycle(t, {pattern:"000.00", locale: 'en-us'},12.34,"012.34",false);
 	tests.number.checkFormatParseCycle(t, {pattern:"+000.00%;-000.00%", locale: 'en-us'},0.1234,"+012.34%",false);
 	tests.number.checkFormatParseCycle(t, {pattern:"##,###,###.00", locale: 'en-us'},9.02,"9.02",false);
-	
+
 	var patterns =(["#.00", "0.00", "00.00", "#0.0#", "#0.00"]);
 	var expect =  (["1.20", "1.20", "01.20", "1.2",   "1.20" ]);
 	for(var i =0 ; i < patterns.length; i ++){
@@ -1086,7 +1084,7 @@ function test_number_format_pad(){
 	var specials = ([ '0', ',', '.', '\u2030', '%', '#',';', 'E', '*', '+', '-']);
 	var pattern;
 	var expect;
-	
+
 	for(var i=0; i < specials.length; i ++){
 		pattern = "'" + specials[i] + "'#0'" + specials[i] + "'";
 		expect = "" +  specials[i] + "123" +  specials[i];
@@ -1128,3 +1126,4 @@ function test_number_format_pad(){
 		}
 	]
 );
+});
\ No newline at end of file
diff --git a/dojo/tests/on.js b/dojo/tests/on.js
new file mode 100644
index 0000000..73adabb
--- /dev/null
+++ b/dojo/tests/on.js
@@ -0,0 +1,229 @@
+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}]});
+			}
+		}
+	]
+);
diff --git a/dojo/tests/parser.html b/dojo/tests/parser.html
index 7b19b20..9f24d76 100644
--- a/dojo/tests/parser.html
+++ b/dojo/tests/parser.html
@@ -5,22 +5,26 @@
 		<style type="text/css">     
 			@import "../resources/dojo.css";
 		</style>
-		<script type="text/javascript"
-			src="../dojo.js"
-			data-dojo-config="isDebug: true, parseOnLoad: false"></script>
+		<script type="text/javascript" src="../dojo.js" data-dojo-config="isDebug:true, async:true"></script>
 		<script type="text/javascript">
-		define("dojo/tests/parser/script", ["dojo", "dojo/parser", "doh/runner"], function(dojo) {
+		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){
 
-			dojo.declare("tests.parser.Widget", null, {
+			var mixin = dojo.mixin,
+				extend = dojo.extend,
+				exists = dojo.exists;
+
+			declare("tests.parser.Widget", null, {
 				constructor: function(args, node){
 					this.params = args;
 				}
 			});
 
-			dojo.declare("tests.parser.Class1", null, {
+			declare("tests.parser.Class1", null, {
 				constructor: function(args, node){
 					this.params = args;
-					dojo.mixin(this, args);
+					mixin(this, args);
 				}, 
 				preambleTestProp: 1,
 				preamble: function(){
@@ -38,9 +42,9 @@
 				boolProp2: true,
 				boolProp3: false,
 				boolProp4: true,
-				dateProp1: dojo.date.stamp.fromISOString('2007-01-01'),
-				dateProp2: dojo.date.stamp.fromISOString('2007-01-01'),
-				dateProp3: dojo.date.stamp.fromISOString('2007-01-01'),
+				dateProp1: dstamp.fromISOString('2007-01-01'),
+				dateProp2: dstamp.fromISOString('2007-01-01'),
+				dateProp3: dstamp.fromISOString('2007-01-01'),
 				funcProp: function(){},
 				funcProp2: function(){},
 				funcProp3: function(){},
@@ -49,7 +53,7 @@
 				// FIXME: need to test the args property!!
 			});
 
-			dojo.declare("tests.parser.Class2", null, {
+			declare("tests.parser.Class2", null, {
 				constructor: function(){
 					this.fromMarkup = false;
 				}, 
@@ -61,8 +65,7 @@
 				}
 			});
 
-
-			dojo.declare("tests.parser.Class3", tests.parser.Class2, {
+			declare("tests.parser.Class3", tests.parser.Class2, {
 				fromMarkup: false,
 				markupFactory: function(args, node, classCtor){
 					var i = new classCtor();
@@ -71,36 +74,51 @@
 					return i;
 				}
 			});
-			
-			dojo.declare("tests.parser.inputClass", null, {
-				constructor: function(args, node){ dojo.mixin(this, args); },
+
+			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,
-				checked: 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. attribute can be inherited from ancestor node
-			dojo.declare("tests.parser.BidiClass", tests.parser.Widget, {
-				constructor: function(args, node){ dojo.mixin(this, args); },
+			// 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
-			dojo.declare("tests.parser.NormalContainer", null, {
-				constructor: function(args, node){ dojo.mixin(this, args); }
+			declare("tests.parser.NormalContainer", null, {
+				constructor: function(args, node){ mixin(this, args); }
 			});
-			dojo.declare("tests.parser.ShieldedContainer", null, {
-				constructor: function(args, node){ dojo.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
 			});
 
-			dojo.declare("tests.parser.HTML5Props", null, {
-				constructor: function(args, node){ dojo.mixin(this, args); },
+			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,
@@ -108,14 +126,14 @@
 					return this.a * 2;
 				}
 			});
-			
+
 			// not on .prototype:
 			tests.parser.HTML5Props._aDefaultObj = {
 				a:1, b:2, simple:true
 			};
 
-			dojo.declare("tests.parser.HTML5withMethod", null, {
-				constructor: function(args, node){ dojo.mixin(this, args); },
+			declare("tests.parser.HTML5withMethod", null, {
+				constructor: function(args, node){ mixin(this, args); },
 				baseValue: 10,
 				someMethod: function(a, b){
 					return this.baseValue; 
@@ -123,8 +141,15 @@
 				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: {
@@ -132,261 +157,273 @@
 				}
 			};
 
-			dojo.addOnLoad(function(){
-				doh.register("basic",
-					[
-						function parse(){
-							// Running the parser here so that failures appear in test log
-							dojo.parser.parse("main");
-						},
+			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){
-							// console.debug(obj);
-							t.t(typeof obj == "object");
+							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);
 
-						// Attribute parsing tests
-						function testStrProp(t){
-							// normal string parameter
-							t.t(dojo.isString(obj.strProp1));
-							t.is("text", obj.strProp1);
-							
-							// make sure that you override a string value like "foo" to a blank value
-							t.t(dojo.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
 
-							// 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", dojo.date.stamp.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(dojo.date.stamp.toISOString(new Date(), {selector: 'date'}),
-								dojo.date.stamp.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(dojo.indexOf(
-									["strProp1", "strProp2",
-									"intProp",
-									"arrProp", "arrProp2",
-									"boolProp1", "boolProp2",
-									"dateProp1", "dateProp2", "dateProp3",
-									"funcProp2", "funcProp3",
-									"preamble",
-									"callInc1", "callInc2", "dir", "lang"],
-									param) >= 0, param);
-							}
-						},
-						function testDisabledFlag(t){
-							t.is("boolean", (typeof disabledObj.disabled));
-							t.t(disabledObj.disabled);
-							t.f(disabledObj.checked);
-						},
-						function testCheckedFlag(t){
-							t.is("boolean", (typeof checkedObj.checked));
-							t.f(checkedObj.disabled);
-							t.t(checkedObj.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);
-						},
+						// boolProp1 specified at true
+						t.is("boolean", (typeof obj.boolProp1));
+						t.t(obj.boolProp1);
 
-						// 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(dojo.exists("obj2"));
-							var toParse = dojo.byId("toParse");
-							toParse.setAttribute("dojoType", toParse.getAttribute("type"));
-							dojo.parser.parse(toParse.parentNode);
-							t.t(dojo.exists("obj2"));
-							t.is("tests.parser.Class1", obj2.declaredClass);
-						},
-						function testMarkupFactory(t){
-							t.t(dojo.exists("obj3"));
-							t.t(obj3.fromMarkup);
-						},
-						function testMarkupFactoryClass(t){
-							t.t(dojo.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;
-							dojo.declare("SampleThinger", null, {
-								startup: function(){
-									started = true;
-								}
-							});
-						  
-							dojo.create("div", { dojoType:"SampleThinger" }, "parsertest");
-							dojo.parser.parse("parsertest", { noStart:true });
-							
-							t.f(started);
-
-							dojo.empty("parsertest");
-							
-							started = false;
-							
-							dojo.create("div", { dojoType:"SampleThinger" }, "parsertest");
-							dojo.parser.parse({ noStart:true, rootNode:"parsertest" });
-			  				
-							t.f(started);
-						},
-						
-						// test the various iterations of parser test
-						function rootTest(t){
-						  
-							var handle = function(sel, root){
-								t.is("parsertest2", root);
+						// 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;
 							}
-							var tmp = dojo.connect(dojo, "query", handle);
-							
-							dojo.parser.parse("parsertest2");
-							dojo.parser.parse({ rootNode: "parsertest2" });
-							dojo.parser.parse("parsertest2", { noStart:true });
-							
-							dojo.disconnect(tmp);
-							
-						},
+						});
 
-						// 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 = dojo.place("<div><div dojoType='tests.parser.Class3' newParam=12345>hi</div></div>", dojo.body(), "last");
-							
-							// Modify Class3's superclass widget to have new parameter (thus Class3 inherits it)
-							dojo.extend(tests.parser.Class2, {
-								newParam: 0
-							});
-							
-							// Run the parser and see if it reads in newParam
-							var widgets = dojo.parser.parse({rootNode: wrapper});
-							doh.is(1, widgets.length, "parsed newly inserted parserTest widget");
-							doh.is(12345, widgets[0].params.newParam, "new parameter parsed");
-						},
+						dhtml.create("div", { dojoType:"SampleThinger" }, "parsertest");
+						parser.parse("parsertest", { noStart:true });
 
-						// 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(dojo.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")
-						},
+						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");
 						
-						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");
-						}
-					]
-				);
+						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(){
-						dojo.parser.parse("dirSection1");
-						dojo.parser.parse("dirSection2");
+						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)");
@@ -394,13 +431,154 @@
 						doh.is("ltr", setLtr.dir, "direct setting of dir=ltr overrides inherited RTL");
 					},
 					function lang(){
-						dojo.parser.parse("langSection");
+						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();
 			})
 		});
@@ -409,7 +587,7 @@
 	<body>
 		<h1>Parser Unit Test</h1>
 
-		<div id="main">
+		<div id=main>
 			<script>
 				function foo(){ this.fooCalled=true; }
 			</script>
@@ -444,8 +622,8 @@
 			</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>
+			<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>
@@ -481,6 +659,7 @@
 				</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"
@@ -508,6 +687,7 @@
 						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">
@@ -515,7 +695,20 @@
 					</script>
 				</div>
 			</div>
-		</div> <!-- close <div id=main> -->
+			
+			<!-- 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">
@@ -549,5 +742,48 @@
 		<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 02cb856..51bf615 100644
--- a/dojo/tests/parser.js
+++ b/dojo/tests/parser.js
@@ -1,4 +1,5 @@
-dojo.provide("tests.parser");
-if(dojo.isBrowser){
-	doh.registerUrl("tests.parser", dojo.moduleUrl("tests", "parser.html"));
-}
+define(["doh", "require"], function(doh, require){
+	if(doh.isBrowser){
+		doh.register("tests.parser", require.toUrl("./parser.html"), 30000);
+	}
+});
diff --git a/dojo/tests/regexp.js b/dojo/tests/regexp.js
index 47aea23..1b7d793 100644
--- a/dojo/tests/regexp.js
+++ b/dojo/tests/regexp.js
@@ -1,12 +1,11 @@
-dojo.provide("tests.regexp");
+define(["../main", "doh", "../regexp"], function(dojo, doh){
 
-dojo.require("dojo.regexp");
-
-tests.register("tests.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"));
 		}
-	]
 );
+
+
+});
diff --git a/dojo/tests/resources/ApplicationState.js b/dojo/tests/resources/ApplicationState.js
index a25e7ff..109830a 100644
--- a/dojo/tests/resources/ApplicationState.js
+++ b/dojo/tests/resources/ApplicationState.js
@@ -7,22 +7,22 @@ ApplicationState = function(stateData, outputDivId, backForwardOutputDivId, book
 	this.outputDivId = outputDivId;
 	this.backForwardOutputDivId = backForwardOutputDivId;
 	this.changeUrl = bookmarkValue;
-}
+};
 
 ApplicationState.prototype.back = function(){
 	this.showBackForwardMessage("BACK for State Data: " + this.stateData);
 	this.showStateData();
-}
+};
 
 ApplicationState.prototype.forward = function(){
 	this.showBackForwardMessage("FORWARD for State Data: " + this.stateData);
 	this.showStateData();
-}
+};
 
 ApplicationState.prototype.showStateData = function(){
 	dojo.byId(this.outputDivId).innerHTML += this.stateData + '<br />';
-}
+};
 
 ApplicationState.prototype.showBackForwardMessage = function(message){
 	dojo.byId(this.backForwardOutputDivId).innerHTML += message + '<br />';
-}
+};
diff --git a/dojo/tests/rpc.js b/dojo/tests/rpc.js
index 0336b36..ef6e477 100644
--- a/dojo/tests/rpc.js
+++ b/dojo/tests/rpc.js
@@ -1,12 +1,6 @@
-dojo.provide("tests.rpc");
-
-dojo.require("dojo.rpc.RpcService");
-dojo.require("dojo.rpc.JsonService");
-dojo.require("dojo.rpc.JsonpService");
-
-doh.register("tests.rpc",
-	[
+define(["../main", "doh", "require", "../rpc/RpcService", "../rpc/JsonService", "../rpc/JsonpService"], function(dojo, doh, require){
 
+	doh.register("tests.rpc", [
 		{
 			name: "JsonRPC-EchoTest",
 			timeout: 2000,
@@ -25,8 +19,8 @@ doh.register("tests.rpc",
 							]
 						}
 					]
-				}
-			
+				};
+
 				this.svc = new dojo.rpc.JsonService(testSmd);
 			},
 			runTest: function(){
@@ -63,8 +57,8 @@ doh.register("tests.rpc",
 				var testSmd={
 					serviceURL:"../../dojo/tests/resources/test_JsonRPCMediator.php",
 					methods:[ { name:"contentB" } ]
-				}
-			
+				};
+
 				this.svc = new dojo.rpc.JsonService(testSmd);
 			},
 			runTest: function(){
@@ -112,7 +106,7 @@ doh.register("tests.rpc",
 			name: "JsonP_test",
 			timeout: 10000,
 			setUp: function(){
-				this.svc = new dojo.rpc.JsonpService(dojo.moduleUrl("dojo.tests.resources","yahoo_smd_v1.smd"), {appid: "foo"});
+				this.svc = new dojo.rpc.JsonpService(require.toUrl("dojo/tests/resources/yahoo_smd_v1.smd"), {appid: "foo"});
 			},
 			runTest: function(){
 				var d = new doh.Deferred();
@@ -141,7 +135,6 @@ doh.register("tests.rpc",
 				return d;
 			}
 		}
-	]
-);
-
+	]);
 
+});
diff --git a/dojo/tests/runTests.html b/dojo/tests/runTests.html
index a83f534..a51d1a6 100644
--- a/dojo/tests/runTests.html
+++ b/dojo/tests/runTests.html
@@ -2,7 +2,7 @@
 <html>
     <head>
     <title>Dojo CORE and BASE D.O.H. Unit Test Runner</title>
-    <meta http-equiv="REFRESH" content="0;url=../../util/doh/runner.html?testModule=dojo.tests.module"></HEAD>
+    <meta http-equiv="REFRESH" content="0;url=../../util/doh/runner.html?test=dojo/tests/module"></HEAD>
     <BODY>
         Redirecting to D.O.H runner.
     </BODY>
diff --git a/dojo/tests/sie/all.js b/dojo/tests/sie/all.js
deleted file mode 100644
index ae33603..0000000
--- a/dojo/tests/sie/all.js
+++ /dev/null
@@ -1,22 +0,0 @@
-define("tests/sie/all", ["doh/runner"], function() {
-
-// we use dojo.require instead of dojo.req because we want this
-// module to work with the v1.5 loader and bootstrap which does
-// not define dojo.req
-dojo.require("tests._base.array");
-dojo.require("tests._base.Color");
-dojo.require("tests._base.lang");
-dojo.require("tests._base.declare");
-dojo.require("tests._base.connect");
-dojo.require("tests._base.Deferred");
-dojo.require("tests._base.json");
-dojo.require("tests._base.object");
-if (dojo.isBrowser) {
-  dojo.require("tests._base.html", true);
-  dojo.require("tests._base.fx", true);
-  dojo.require("tests._base.query", true);
-  dojo.require("tests._base.xhr", true);
-  dojo.require("tests._base.window", true);
-}
-
-});
\ No newline at end of file
diff --git a/dojo/tests/sie/smoke-v15.html b/dojo/tests/sie/smoke-v15.html
deleted file mode 100644
index d1c3441..0000000
--- a/dojo/tests/sie/smoke-v15.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-   "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-  <head>
-    <title>hello dojo-sie</title>
-    <script type="text/javaScript">
-      var start= (new Date()).getTime();
-    </script>
-    <script type="text/javascript" src="../../dojo.js"></script>
-    <script type="text/javaScript">
-      dojo.addOnLoad(function() {
-        dojo.byId("status").innerHTML= "dojo-sie v15 synchronous loader fired onLoad queue."
-        dojo.byId("time").innerHTML= (((new Date()).getTime() - start) / 1000) + "s";
-        var moduleList= [];
-        for (var p in dojo._loadedModules) moduleList.push(p);
-        moduleList.sort();
-        dojo.byId("modules").innerHTML= moduleList.join("<br/>");
-      });
-    </script>
-  </head>
-  <body class="tundra">
-    <h1>Status</h1>
-    <p id="status">loading</p>
-    <h1>Load Time</h1>
-    <p id="time"></p>
-    <h1>Module Loaded</h1>
-    <p id="modules"></p>
-  </body>
-</html>
diff --git a/dojo/tests/sie/smoke.html b/dojo/tests/sie/smoke.html
deleted file mode 100644
index 1b20af7..0000000
--- a/dojo/tests/sie/smoke.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-   "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-  <head>
-    <title>hello dojo-sie</title>
-    <script type="text/javaScript">
-      var start= (new Date()).getTime();
-    </script>
-    <script type="text/javascript" src="../../dojo-sie.js"></script>
-    <script type="text/javaScript">
-      require.addOnLoad(function() {
-        dojo.byId("status").innerHTML= (require.onError.log.length==0) ? 
-          "dojo-sie asynchronous loader and bootstrap loaded without errors." :
-          "dojo-sie asynchronous loader and bootstrap caused errors during bootstrapping.";
-        dojo.byId("time").innerHTML= (((new Date()).getTime() - start) / 1000) + "s";
-        var moduleList= [];
-        for (var p in require.modules) moduleList.push(p);
-        moduleList.sort();
-        dojo.byId("modules").innerHTML= moduleList.join("<br/>");
-      });
-    </script>
-  </head>
-  <body class="tundra">
-    <h1>Status</h1>
-    <p id="status">loading</p>
-    <h1>Load Time</h1>
-    <p id="time"></p>
-    <h1>Module Loaded</h1>
-    <p id="modules"></p>
-  </body>
-</html>
diff --git a/dojo/tests/store.js b/dojo/tests/store.js
index a8cf179..b5f23d9 100644
--- a/dojo/tests/store.js
+++ b/dojo/tests/store.js
@@ -1,4 +1,8 @@
-define("dojo/tests/store", ["dojo", "dojo/tests/store/Memory", "dojo/tests/store/DataStore", "dojo/tests/store/Observable", "dojo/tests/store/Cache"].concat(dojo.isBrowser ? ["dojo/tests/store/JsonRest"] : []), function(dojo) {
-});
+define([
+	"dojo/tests/store/Memory", 
+	"dojo/tests/store/DataStore", 
+	"dojo/tests/store/Observable", 
+	"dojo/tests/store/Cache",
+	"dojo/has!host-browser?dojo/tests/store/JsonRest"], 1);
 
 
diff --git a/dojo/tests/store/DataStore.js b/dojo/tests/store/DataStore.js
index 5bf43bb..fc0ec85 100644
--- a/dojo/tests/store/DataStore.js
+++ b/dojo/tests/store/DataStore.js
@@ -1,14 +1,16 @@
 dojo.provide("dojo.tests.store.DataStore");
 dojo.require("dojo.store.DataStore");
-dojo.require("dojo.data.ItemFileWriteStore")
+dojo.require("dojo.data.ItemFileWriteStore");
 var temp = function(){
-	var two, four;
+	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:{
 		items: [
 			{id: 1, name: "one", prime: false},
-			two = {id: 2, name: "two", even: true, prime: true},
+			{id: 2, name: "two", even: true, prime: true},
 			{id: 3, name: "three", prime: true},
-			four = {id: 4, name: "four", even: true, prime: false},
+			{id: 4, name: "four", even: true, prime: false},
 			{id: 5, name: "five", prime: true}
 		],
 		identifier:"id"
@@ -22,17 +24,25 @@ var temp = function(){
 				t.is(store.get(4).name, "four");
 				t.t(store.get(5).prime);
 			},
-			function testQuery(t){
-				store.query({prime: true}).then(function(results){
+			function testQuery1(t){
+				var d = new doh.Deferred();
+				store.query({prime: true}).then(d.getTestCallback(function(results){
 					t.is(results.length, 3);
-				});
-				store.query({even: true}).map(function(object){
+				}));
+				return d;
+			},
+			function testQuery2(t){
+				var d = new doh.Deferred();
+				var result = store.query({even: true});
+				result.map(d.getTestErrback(function(object){
 					for(var i in object){
-						t.is(object[i], (object.id == 2 ? two : four)[i]);
+						t.is(object[i], (object.id == 2 ? two : four)[i], "map of " + i);
 					}
-				}).then(function(results){
-					t.is(results[1].name, "four");
-				});
+				}));
+				result.then(d.getTestCallback(function(results){
+					t.is("four", results[1].name, "then");
+				}));
+				return d;
 			},
 			function testPutUpdate(t){
 				var four = store.get(4);
@@ -47,6 +57,10 @@ var temp = function(){
 					perfect: true
 				});
 				t.t(store.get(6).perfect);
+			},
+			function testNoWriteFeature(t){
+				var readOnlyStore = new dojo.store.DataStore({store:new dojo.data.ItemFileReadStore({})});
+				t.f(readOnlyStore.put);
 			}
 		]
 	);
diff --git a/dojo/tests/store/JsonRest.js b/dojo/tests/store/JsonRest.js
index df28b90..c9e41e1 100644
--- a/dojo/tests/store/JsonRest.js
+++ b/dojo/tests/store/JsonRest.js
@@ -1,8 +1,6 @@
-dojo.provide("dojo.tests.store.JsonRest");
-dojo.require("dojo.store.JsonRest");
-(function(){
-	var store = new dojo.store.JsonRest({target: dojo.moduleUrl("dojo.tests.store", "")});
-	tests.register("tests.store.JsonRest",
+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]});
+	doh.register("tests.store.JsonRest",
 		[
 			function testGet(t){
 				var d = new doh.Deferred();
@@ -37,4 +35,4 @@ dojo.require("dojo.store.JsonRest");
 			}
 		]
 	);
-})();
+});
diff --git a/dojo/tests/store/Memory.js b/dojo/tests/store/Memory.js
index 38f8087..edf8081 100644
--- a/dojo/tests/store/Memory.js
+++ b/dojo/tests/store/Memory.js
@@ -73,9 +73,14 @@ dojo.require("dojo.store.Memory");
 				t.t(store.get(7).prime);
 			},
 			function testRemove(t){
-				store.remove(7);
+				t.t(store.remove(7));
 				t.is(store.get(7), undefined);
 			},
+			function testRemoveMissing(t){
+				t.f(store.remove(77));
+				// make sure nothing changed
+				t.is(store.get(1).id, 1);
+			},
 			function testQueryAfterChanges(t){
 				t.is(store.query({prime: true}).length, 3);
 				t.is(store.query({perfect: true}).length, 1);
diff --git a/dojo/tests/store/Observable.js b/dojo/tests/store/Observable.js
index f287a5a..f607d71 100644
--- a/dojo/tests/store/Observable.js
+++ b/dojo/tests/store/Observable.js
@@ -4,6 +4,7 @@ dojo.require("dojo.store.Observable");
 (function(){
 	var store = dojo.store.Observable(new dojo.store.Memory({
 		data: [
+			{id: 0, name: "zero", even: true, prime: false},
 			{id: 1, name: "one", prime: false},
 			{id: 2, name: "two", even: true, prime: true},
 			{id: 3, name: "three", prime: true},
@@ -86,7 +87,19 @@ dojo.require("dojo.store.Observable");
 					id:11, name:"eleven", prime:true
 				});
 				t.is(changes, expectedChanges);
-			}
+			},
+			function testQueryWithZeroId(t){
+                var results = store.query({});
+                t.is(results.length, 8);
+                var observer = results.observe(function(object, previousIndex, newIndex){
+                        // we only do puts so previous & new indices must always been the same
+                        // unfortunately if id = 0, the previousIndex
+                        console.log("called with: "+previousIndex+", "+newIndex);
+                        t.is(previousIndex, newIndex);
+                }, true);
+                store.put({id: 5, name: "-FIVE-", prime: true});
+                store.put({id: 0, name: "-ZERO-", prime: false});
+            }			
 		]
 	);
 })();
diff --git a/dojo/tests/string.js b/dojo/tests/string.js
index 0d4b423..2fa1dda 100644
--- a/dojo/tests/string.js
+++ b/dojo/tests/string.js
@@ -1,8 +1,6 @@
-dojo.provide("tests.string");
+define(["../main", "doh", "../string"], function(dojo, doh){
 
-dojo.require("dojo.string");
-
-tests.register("tests.string",
+doh.register("tests.string",
 	[
 		function test_string_pad(t){
 			t.is("00001", dojo.string.pad("1", 5));
@@ -29,7 +27,7 @@ tests.register("tests.string",
 			// Verify that an error is thrown!
 			t.assertError(Error, dojo.string, "substitute", ["${x}", {y:1}]);
 		},
-		
+
 		function test_string_substitute_transform(t){
 			var getPrefix = function(str){
 				// try to figure out the type
@@ -38,7 +36,7 @@ tests.register("tests.string",
 					prefix = this.____prefix + prefix;
 				}
 				return prefix + " '" + str + "'";
-			}
+			};
 
 			var obj = {
 				____prefix: "...",
@@ -73,7 +71,7 @@ tests.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                            "));
@@ -81,7 +79,7 @@ tests.register("tests.string",
 			t.is("astoria", dojo.string.trim("astoria"));
 			t.is("a", dojo.string.trim("   a   "));
 		},
-		
+
 		function test_string_rep(t){
 			t.is("aaaaa", dojo.string.rep("a", 5));
 			t.is("abababab", dojo.string.rep("ab", 4));
@@ -90,3 +88,5 @@ tests.register("tests.string",
 		}
 	]
 );
+
+});
\ No newline at end of file
diff --git a/dojo/tests/test_FirebugLite.html b/dojo/tests/test_FirebugLite.html
index f87f01b..4a85202 100644
--- a/dojo/tests/test_FirebugLite.html
+++ b/dojo/tests/test_FirebugLite.html
@@ -27,56 +27,57 @@
 			bbb:22,
 			ccc:[10,18],
 			idDeedYee:"MyCoolObjectie"
-		}
+		};
 		
 		obj2 = {
 			a:"Dojo",
 			b:2,
 			c:[0,8],
 			id:"MyCoolObject"
-		}
+		};
 		
 		obj3 = {
 			a:"Dojo",
 			b:2,
 			c:[0,8]
-		}
+		};
 		
 		outputText = function(){
-			for ( var i = 0; i < 20 ; i++){
-				console.log (i+":: foo");
+			for(var i = 0; i < 20; i++){
+				console.log(i + ":: foo");
 			}
-		}
+		};
 		doStuff = function(){
 			console.log("FOO! More FOO! Gotta have some FOO MAN!")
-		}
+		};
 		
 		doStuffLots = function(){
-			for ( var i = 0; i < 5 ; i++){
+			for(var i = 0; i < 5; i++){
 				console.log("xxxxxxxx")
 				doStuff();
-			}}
+			}
+		};
 		dojo.addOnLoad(function(){
 			console.time("foo time")
 			// test objects
 			console.log(obj3, "::", [1,2,3,4,5,6,7,8,9,0]);
 			console.log("Dojo was here", obj, "object over", obj2);
-			
+
 			// test that tracing dom node does not break (due to lack of support)
 			console.log(dojo.byId("foo"))
-			
+
 			// test error functionality
-			console.error( new Error("There was a dummy error") );
-			
+			console.error(new Error("There was a dummy error"));
+
 			//throws exception:
 			//console.assert(true == false)
-			
+
 			console.group("myGroup");
 			console.log("group me 1");
 			console.log("group me 2");
 			console.log("group me 3");
 			console.groupEnd();
-			
+
 			// testing log styling
 			console.log("foo");
 			console.debug("foo");
@@ -85,7 +86,7 @@
 			console.error("foo");
 			//timer end
 			console.timeEnd("foo time")
-		})
+		});
 		
 		function doCon(){
 		}
diff --git a/dojo/tests/test_FirebugLitePopup.html b/dojo/tests/test_FirebugLitePopup.html
index 926713e..04db5a7 100644
--- a/dojo/tests/test_FirebugLitePopup.html
+++ b/dojo/tests/test_FirebugLitePopup.html
@@ -27,56 +27,57 @@
 			bbb:22,
 			ccc:[10,18],
 			idDeedYee:"MyCoolObjectie"
-		}
+		};
 		
 		obj2 = {
 			a:"Dojo",
 			b:2,
 			c:[0,8],
 			id:"MyCoolObject"
-		}
+		};
 		
 		obj3 = {
 			a:"Dojo",
 			b:2,
 			c:[0,8]
-		}
+		};
 		
 		outputText = function(){
-			for ( var i = 0; i < 20 ; i++){
-				console.log (i+":: foo");
+			for(var i = 0; i < 20; i++){
+				console.log(i + ":: foo");
 			}
-		}
+		};
 		doStuff = function(){
 			console.log("FOO! More FOO! Gotta have some FOO MAN!")
-		}
+		};
 		
 		doStuffLots = function(){
-			for ( var i = 0; i < 5 ; i++){
+			for(var i = 0; i < 5; i++){
 				console.log("xxxxxxxx")
 				doStuff();
-			}}
+			}
+		};
 		dojo.addOnLoad(function(){
 			console.time("foo time")
 			// test objects
 			console.log(obj3, "::", [1,2,3,4,5,6,7,8,9,0]);
 			console.log("Dojo was here", obj, "object over", obj2);
-			
+
 			// test that tracing dom node does not break (due to lack of support)
 			console.log(dojo.byId("foo"))
-			
+
 			// test error functionality
-			console.error( new Error("There was a dummy error") );
-			
+			console.error(new Error("There was a dummy error"));
+
 			//throws exception:
 			//console.assert(true == false)
-			
+
 			console.group("myGroup");
 			console.log("group me 1");
 			console.log("group me 2");
 			console.log("group me 3");
 			console.groupEnd();
-			
+
 			// testing log styling
 			console.log("foo");
 			console.debug("foo");
@@ -85,7 +86,7 @@
 			console.error("foo");
 			//timer end
 			console.timeEnd("foo time")
-		})
+		});
 		
 		function doCon(){
 		}
diff --git a/dojo/tests/test_fx.html b/dojo/tests/test_fx.html
index 4e6b586..4f4fd28 100644
--- a/dojo/tests/test_fx.html
+++ b/dojo/tests/test_fx.html
@@ -40,11 +40,10 @@
 				/* position: absolute; */
 			}
 		</style>
-		<script type="text/javascript" src="../dojo.js" djConfig="isDebug: true"></script>
-		<script type="text/javascript" src="../fx.js"></script>
+
+		<script type="text/javascript" src="../dojo.js" data-dojo-config="isDebug:true"></script>
 		<script type="text/javascript">
-			dojo.require("dojo.fx");
-			dojo.addOnLoad(function(){
+			require(["dojo", "doh", "dojo/fx", "dojo/domReady!"], function(dojo, doh){
 				dojo.byId("foo").style.height = "0px";
 				var w1 = dojo.fx.wipeIn({
 					node: "foo",
@@ -105,4 +104,4 @@
 			</p>
 		</div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/dojo/tests/test_touch.html b/dojo/tests/test_touch.html
new file mode 100644
index 0000000..5a2b510
--- /dev/null
+++ b/dojo/tests/test_touch.html
@@ -0,0 +1,144 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<meta name="viewport" content="width=device-width,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+		<title>Dojo Touch Testing</title>
+		<style type="text/css">
+			#test {
+				width: 300px;
+				height: 150px;
+				border: 1px solid #7FB0DB;
+				background-color: #7FB0DB;			
+			}
+			#log {
+				width: 300px;
+				height: 200px;
+			}
+			#dohDiv{
+				display: none;
+			}			
+		</style>
+		<script type="text/javascript" src="../dojo.js" djConfig="parseOnLoad: true"></script>
+		<script>
+			require([
+				"dojo/_base/html",
+				"dojo/_base/event",
+				"dojo/ready",
+				"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");
+				
+					//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);
+
+					
+//					//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');
+					domStyle.set(dohDiv, {display: 'block'});
+					
+					function setObj(obj, e){
+						obj.type = e.type;
+						obj.target = e.target;
+					}
+					function assert(obj, type, target){
+						doh.assertEqual(type, obj.type);
+						doh.assertEqual(target, obj.target);
+					}
+
+					doh.register("dojo.touch", [
+						function press(){
+							var executed, obj = {};
+							on(dohDiv, touch.press, function(e){
+								//console.log(e.type);
+								executed = true;
+								setObj(obj, e);
+							});
+							on.emit(dohDiv, 'mousedown', {});
+							doh.assertTrue(executed, 'dojo.touch.press not fired');
+							assert(obj, 'mousedown', dohDiv);							
+						},
+						function move(){
+							var executed, obj = {};
+							on(dohDiv, touch.move, function(e){
+								//console.log(e.type);
+								executed = true;
+								setObj(obj, e);
+							});
+							on.emit(dohDiv, 'mousemove', {});
+							doh.assertTrue(executed, 'dojo.touch.move not fired');
+							assert(obj, 'mousemove', dohDiv);
+						},
+						function release(){
+							var executed, obj = {};
+							on(dohDiv, touch.release, function(e){
+								//console.log(e.type);
+								executed = true;
+								setObj(obj, e);
+							});
+							on.emit(dohDiv, 'mouseup',  {screenX: 0, screenY: 50});
+							doh.assertTrue(executed, 'dojo.touch.release not fired');
+							assert(obj, 'mouseup', dohDiv);
+						},
+						function cancel(){
+							var executed, obj = {};
+							on(dohDiv, touch.cancel, function(e){
+								executed = true;
+								setObj(obj, e);
+							});
+							on.emit(dohDiv, 'mouseout',  {screenX: 0, screenY: 50});
+							doh.assertTrue(executed, 'dojo.touch.cancel not fired');
+							assert(obj, 'mouseout', dohDiv);
+						}
+					]);
+					doh.run();
+				});
+			});
+		</script>
+	</head>
+	<body>
+		<div id="test"></div>
+		<div id="log"></div>
+		<br/>
+		<div id="dohDiv">doh</div>
+	</body>
+</html>
\ No newline at end of file
diff --git a/dojo/tests/touch.js b/dojo/tests/touch.js
new file mode 100644
index 0000000..5f5dc59
--- /dev/null
+++ b/dojo/tests/touch.js
@@ -0,0 +1,6 @@
+define(["doh", "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 644e06b..2e3bb57 100644
--- a/dojo/tests/uacss.js
+++ b/dojo/tests/uacss.js
@@ -1,10 +1,7 @@
-dojo.provide("tests.uacss");
+define(["doh", "require"], function(doh, require){
 
-// Run tests for sniffer browser and setting corresponding class name on <html>
+	doh.register("tests.uacss.sniffQuirks", require.toUrl("./uacss/sniffQuirks.html"));
+	doh.register("tests.uacss.sniffStandards", require.toUrl("./uacss/sniffStandards.html"));
+
+});
 
-try{
-	doh.registerUrl("tests.uacss.sniffQuirks", dojo.moduleUrl("dojo", "tests/uacss/sniffQuirks.html"));
-	doh.registerUrl("tests.uacss.sniffStandards", dojo.moduleUrl("dojo", "tests/uacss/sniffStandards.html"));
-}catch(e){
-	doh.debug(e);
-}
diff --git a/dojo/tests/uacss/sniffQuirks.html b/dojo/tests/uacss/sniffQuirks.html
index f6d0b92..ca070ef 100644
--- a/dojo/tests/uacss/sniffQuirks.html
+++ b/dojo/tests/uacss/sniffQuirks.html
@@ -23,14 +23,11 @@
 			height: 60px;
 		}
 	</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">
-		dojo.require("doh.runner");
-		dojo.require("dojo.uacss");
-
-		dojo.addOnLoad(function() {
+		require(["dojo", "doh", "dojo/uacss", "dojo/domReady!"], function(dojo, doh){
 			var node = dojo.byId("box1");
-			var reportNode = dojo.byId("log")
+			var reportNode = dojo.byId("log");
 			var inner = (reportNode.textContent) ? "textContent": "innerText";
 			reportNode.innerHTML = dojo.toJson({
 				boxModel: dojo.boxModel,
@@ -43,7 +40,7 @@
 				function test_boxModel(t) {
 					// ensure the box-model correction in the stylesheet have been correctly applied
 					// we measure the node - it should be 100px
-				    t.is(100, node.offsetWidth);
+					t.is(100, node.offsetWidth);
 				}
 			]);
 			doh.run();
diff --git a/dojo/tests/uacss/sniffStandards.html b/dojo/tests/uacss/sniffStandards.html
index 94e21f1..a0ed84f 100644
--- a/dojo/tests/uacss/sniffStandards.html
+++ b/dojo/tests/uacss/sniffStandards.html
@@ -22,13 +22,11 @@
 			height: 60px;
 		}
 	</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">
-		dojo.require("doh.runner");
-		dojo.require("dojo.uacss");
-		dojo.addOnLoad(function() {
+		require(["dojo", "doh", "dojo/uacss", "dojo/domReady!"], function(dojo, doh){
 			var node = dojo.byId("box1");
-			var reportNode = dojo.byId("log")
+			var reportNode = dojo.byId("log");
 			var inner = (reportNode.textContent) ? "textContent": "innerText";
 			reportNode.innerHTML = dojo.toJson({
 				boxModel: dojo.boxModel,
@@ -41,7 +39,7 @@
 				function test_boxModel(t) {
 					// ensure the box-model correction in the stylesheet have been correctly applied
 					// we measure the node - it should be 100px
-				    t.is(100, node.offsetWidth);
+					t.is(100, node.offsetWidth);
 				}
 			]);
 			doh.run();
diff --git a/dojo/tests/window.js b/dojo/tests/window.js
index 1365bf3..40e4b09 100755
--- a/dojo/tests/window.js
+++ b/dojo/tests/window.js
@@ -1,11 +1,5 @@
-dojo.provide("tests.window");
-
-// Run viewport related functions test
-
-try{
-	doh.registerUrl("tests.window.viewport", dojo.moduleUrl("dojo", "tests/window/viewport.html"));
-	doh.registerUrl("tests.window.viewportQuirks", dojo.moduleUrl("dojo", "tests/window/viewportQuirks.html"));
-	doh.registerUrl("tests.window.scroll", dojo.moduleUrl("dojo", "tests/window/test_scroll.html"), 99999999);
-}catch(e){
-	doh.debug(e);
-}
+define(["doh", "require"], function(doh, require){
+	doh.register("tests.window.viewport", require.toUrl("./window/viewport.html"));
+	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 c5d8fc6..2875eca 100644
--- a/dojo/tests/window/test_scroll.html
+++ b/dojo/tests/window/test_scroll.html
@@ -2,7 +2,7 @@
                 "http://www.w3.org/TR/html4/strict.dtd">
 <html style="overflow-y:scroll;border:0px none;padding:0;margin:0;">
 <head>
-        <title>dojo.window.scrollIntoView Test</title>
+	<title>dojo.window.scrollIntoView Test</title>
 
 	<style type="text/css">
 		@import "../../resources/dojo.css";
@@ -13,19 +13,21 @@
 		djConfig="isDebug: true"></script>
 
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dojo.window");
+		var loading; //global
+		require(["doh"], function(doh){
+			loading = new doh.Deferred();
+		});
+
+		require(["dojo", "doh", "dojo/window", "dojo/domReady!"], function(dojo, doh) {
+
+			var usingNative = !(dojo.isMoz || dojo.isIE || dojo.isWebKit || dojo.isOpera);
+			var count = 0;
 
-		var usingNative = !(dojo.isMoz || dojo.isIE || dojo.isWebKit || dojo.isOpera);
-		var loading = new doh.Deferred();
-		var count = 0;
-		dojo.addOnLoad(function(){
 			innerScrollBarSize = dojo.byId("nonscroll").clientWidth - dojo.byId("withscroll").clientWidth;
 			console.debug('inner scrollbar size = ' + innerScrollBarSize);
 			outerScrollBarSize = (dojo.isIE >= 9) ? ((dojo.position(document.documentElement).w - document.documentElement.clientWidth) || innerScrollBarSize) : innerScrollBarSize;
 			console.debug('outer scrollbar size = ' + outerScrollBarSize);
-		        doh.register("dojo.window.scroll",
-	                [
+			doh.register("dojo.window.scroll",[
 				{
 					name: "wait for iframes to load",
 					timeout: 20000,
@@ -124,7 +126,7 @@
 					}else if(dojo.isIE == 7){
 						scroll = 46;
 					}else if(dojo.isIE >= 8 || dojo.isOpera){
-						scroll = "+0";
+						scroll = "0";
 					}else if(dojo.isWebKit){
 						scroll = "-0";
 					}else{
@@ -226,35 +228,35 @@
 					generateTest('htmlPadding_quirks_rtl', "(0,-"+(maxScroll-fudge)+")", "(0,+"+(minScroll-fudge)+")");
 				}
 			]);
-		        doh.run();
-		});
-		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 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+")");
-		}
+			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+")");
+			}
+			doh.run();
+		});
 	</script>
 </head>
 <body>
@@ -468,7 +470,20 @@
 			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 += '('+(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;
 		}
diff --git a/dojo/tests/window/viewport.html b/dojo/tests/window/viewport.html
index 10b2c0f..f0089c4 100644
--- a/dojo/tests/window/viewport.html
+++ b/dojo/tests/window/viewport.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>dojo.window.getBox() test</title>
@@ -7,36 +7,31 @@
 		@import "../../../dojo/resources/dojo.css";
 		html, body { margin: 0px; padding: 0px; }
 	</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"></script>
 
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dojo.window");
-
-		function compute(){
-			var d = dojo.marginBox(dojo.byId("documentBorder")),
-				v = dojo.window.getBox();
-			dojo.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>";
-			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>");
+		require(["dojo", "doh", "dojo/window", "dojo/domReady!"], function(dojo, doh){
+			function compute(){
+				var d = dojo.marginBox(dojo.byId("documentBorder")),
+					v = dojo.window.getBox();
+				dojo.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>";
+				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");
 			}
-			dojo.byId("documentBorder").innerHTML += text.join("\n");
-		}
 
-		dojo.addOnLoad(function(){
-			doh.register("dojo.window.viewport",
-				[
+			doh.register("dojo.window.viewport", [
 					function initial(t){
 						console.log("calling compute");
 						compute();
@@ -56,11 +51,9 @@
 						doh.t(v2.h+20 >= v.h, "test that viewport didn't shrink, except for space taken by scrollbars");
 						console.log("end");
 					}
-				]
-			);
+			]);
 			doh.run();
 		});
-
 	</script>
 </head>
 <body>
diff --git a/dojo/text.js b/dojo/text.js
new file mode 100644
index 0000000..f5deb51
--- /dev/null
+++ b/dojo/text.js
@@ -0,0 +1,212 @@
+define(["./_base/kernel", "require", "./has", "./has!host-browser?./_base/xhr"], function(dojo, require, has, xhr){
+	// 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});
+		};
+	}else{
+		// TODOC: only works for dojo AMD loader
+		if(require.getText){
+			getText= require.getText;
+		}else{
+			console.error("dojo/text plugin failed to load because loader does not support getText");
+		}
+	}
+
+	var
+		theCache= {},
+
+		strip= function(text){
+			//Strips <?xml ...?> declarations so that external SVG and XML
+			//documents can be added to a document without worry. Also, if the string
+			//is an HTML document, only the part inside the body tag is returned.
+			if(text){
+				text= text.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, "");
+				var matches= text.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
+				if(matches){
+					text= matches[1];
+				}
+			}else{
+				text = "";
+			}
+			return text;
+		},
+
+		notFound = {},
+
+		pending = {},
+
+		result= {
+			dynamic:
+				// the dojo/text caches it's own resources because of dojo.cache
+				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 ""
+		//
+		//	 * if module is an object, then it must be convertable to a string
+		//	 * (module, url) module + (url ? ("/" + url) : "") must be a legal argument to require.toUrl
+		//	 * value may be a string or an object; if an object then may have the properties "value" and/or "sanitize"
+		var key;
+		if(typeof module=="string"){
+			if(/\//.test(module)){
+				// module is a version 1.7+ resolved path
+				key = module;
+				value = url;
+			}else{
+				// module is a version 1.6- argument to dojo.moduleUrl
+				key = require.toUrl(module.replace(/\./g, "/") + (url ? ("/" + url) : ""));
+			}
+		}else{
+			key = module + "";
+			value = url;
+		}
+		var
+			val = (value != undefined && typeof value != "string") ? value.value : value,
+			sanitize = value && value.sanitize;
+
+		if(typeof val == "string"){
+			//We have a string, set cache value
+			theCache[key] = val;
+			return sanitize ? strip(val) : val;
+		}else if(val === null){
+			//Remove cached value
+			delete theCache[key];
+			return null;
+		}else{
+			//Allow cache values to be empty strings. If key property does
+			//not exist, fetch it.
+			if(!(key in theCache)){
+				getText(key, true, function(text){
+					theCache[key]= text;
+				});
+			}
+			return sanitize ? strip(theCache[key]) : theCache[key];
+		}
+	};
+
+	return result;
+
+/*=====
+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
new file mode 100644
index 0000000..b29cfa3
--- /dev/null
+++ b/dojo/topic.js
@@ -0,0 +1,33 @@
+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", ...});
+
+	var hub = new Evented;
+	return {
+		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).
+			// 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
+			// topic: String
+			//		The topic to subscribe to
+			//	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
new file mode 100644
index 0000000..328ae1f
--- /dev/null
+++ b/dojo/touch.js
@@ -0,0 +1,89 @@
+define(["./_base/kernel", "./on", "./has", "./mouse"], function(dojo, on, has, mouse){
+// module:
+//		dojo/touch
+
+/*=====
+	dojo.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
+		//
+		// 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
+		//		|	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){});
+		
+		press: function(node, listener){
+			// summary:
+			//		Register a listener to 'touchstart'|'mousedown' 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()
+		},
+		move: function(node, listener){
+			// summary:
+			//		Register a listener to 'touchmove'|'mousemove' 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()
+		},
+		release: function(node, listener){
+			// summary:
+			//		Register a listener to 'touchend'|'mouseup' 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()
+		},
+		cancel: function(node, listener){
+			// summary:
+			//		Register a listener to 'touchcancel'|'mouseleave' 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
diff --git a/dojo/uacss.js b/dojo/uacss.js
index 811ce44..8591a1b 100644
--- a/dojo/uacss.js
+++ b/dojo/uacss.js
@@ -1,44 +1,45 @@
-define("dojo/uacss", ["dojo"], function(dojo) {
-
-(function(){
+define(["./dom-geometry", "./_base/lang", "./ready", "./_base/sniff", "./_base/window"],
+	function(geometry, lang, ready, has, baseWindow){
+	// module:
+	//		dojo/uacss
 	// summary:
 	//		Applies pre-set CSS classes to the top-level HTML node, based on:
-	// 			- browser (ex: dj_ie)
+	//			- 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.
+	//		combined with an RTL flag when browser text is RTL. ex: dj_ie-rtl.
 
-	var d = dojo,
-		html = d.doc.documentElement,
-		ie = d.isIE,
-		opera = d.isOpera,
+	var
+		html = baseWindow.doc.documentElement,
+		ie = has("ie"),
+		opera = has("opera"),
 		maj = Math.floor,
-		ff = d.isFF,
-		boxModel = d.boxModel.replace(/-/,''),
+		ff = has("ff"),
+		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: d.isQuirks,
-			dj_iequirks: ie && d.isQuirks,
+			"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,
+			"dj_opera": opera,
 
-			dj_khtml: d.isKhtml,
+			"dj_khtml": has("khtml"),
 
-			dj_webkit: d.isWebKit,
-			dj_safari: d.isSafari,
-			dj_chrome: d.isChrome,
+			"dj_webkit": has("webkit"),
+			"dj_safari": has("safari"),
+			"dj_chrome": has("chrome"),
 
-			dj_gecko: d.isMozilla,
-			dj_ff3: maj(ff) == 3
+			"dj_gecko": has("mozilla"),
+			"dj_ff3": maj(ff) == 3
 		}; // no dojo unsupported browsers
 
 	classes["dj_" + boxModel] = true;
@@ -50,18 +51,16 @@ define("dojo/uacss", ["dojo"], function(dojo) {
 			classStr += clz + " ";
 		}
 	}
-	html.className = d.trim(html.className + " " + classStr);
+	html.className = lang.trim(html.className + " " + classStr);
 
 	// 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).
-	// Unshift() is to run sniff code before the parser.
-	dojo._loaders.unshift(function(){
-		if(!dojo._isBodyLtr()){
-			var rtlClassStr = "dj_rtl dijitRtl " + classStr.replace(/ /g, "-rtl ")
-			html.className = d.trim(html.className + " " + rtlClassStr);
+	// priority is 90 to run ahead of parser priority of 100
+	ready(90, 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 "));
 		}
 	});
-})();
-
-  return dojo;
+	return has;
 });
diff --git a/dojo/window.js b/dojo/window.js
index 97cc3d5..25b0fda 100644
--- a/dojo/window.js
+++ b/dojo/window.js
@@ -1,18 +1,51 @@
-define("dojo/window", ["dojo"], function(dojo) {
-dojo.getObject("window", true, dojo);
+define(["./_base/lang", "./_base/sniff", "./_base/window", "./dom", "./dom-geometry", "./dom-style"],
+	function(lang, has, baseWindow, dom, geom, style) {
 
-dojo.window.getBox = function(){
+// 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 = (dojo.doc.compatMode == 'BackCompat') ? dojo.body() : dojo.doc.documentElement;
+	var
+		scrollRoot = (baseWindow.doc.compatMode == 'BackCompat') ? baseWindow.body() : baseWindow.doc.documentElement,
+		// get scroll position
+		scroll = geom.docScroll(), // scrollRoot.scrollTop/Left should work
+		w, h;
 
-	// get scroll position
-	var scroll = dojo._docScroll(); // scrollRoot.scrollTop/Left should work
-	return { w: scrollRoot.clientWidth, h: scrollRoot.clientHeight, l: scroll.x, t: scroll.y };
+	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
+	};
 };
 
-dojo.window.get = function(doc){
+window.get = function(doc){
 	// summary:
 	// 		Get window object associated with document doc
 
@@ -20,7 +53,7 @@ dojo.window.get = function(doc){
 	// 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(dojo.isIE && window !== document.parentWindow){
+	if(has("ie") && window !== document.parentWindow){
 		/*
 		In IE 6, only the variable "window" can be used to connect events (others
 		may be only copies).
@@ -36,20 +69,20 @@ dojo.window.get = function(doc){
 	return doc.parentWindow || doc.defaultView;	//	Window
 };
 
-dojo.window.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
+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 = dojo.byId(node);
-		var doc = node.ownerDocument || dojo.doc,
-			body = doc.body || dojo.body(),
+		node = dom.byId(node);
+		var doc = node.ownerDocument || baseWindow.doc,
+			body = doc.body || baseWindow.body(),
 			html = doc.documentElement || body.parentNode,
-			isIE = dojo.isIE, isWK = dojo.isWebKit;
+			isIE = has("ie"), isWK = has("webkit");
 		// if an untested browser, then use the native method
-		if((!(dojo.isMoz || isIE || isWK || dojo.isOpera) || node == body || node == html) && (typeof node.scrollIntoView != "undefined")){
+		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;
 		}
@@ -60,26 +93,26 @@ dojo.window.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
 			scrollRoot = isWK ? body : clientAreaRoot,
 			rootWidth = clientAreaRoot.clientWidth,
 			rootHeight = clientAreaRoot.clientHeight,
-			rtl = !dojo._isBodyLtr(),
-			nodePos = pos || dojo.position(node),
+			rtl = !geom.isBodyLtr(),
+			nodePos = pos || geom.position(node),
 			el = node.parentNode,
 			isFixed = function(el){
-				return ((isIE <= 6 || (isIE && backCompat))? false : (dojo.style(el, 'position').toLowerCase() == "fixed"));
+				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 = dojo.position(el),
+			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; }
 			}else{
-				var pb = dojo._getPadBorderExtents(el);
+				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;
@@ -132,5 +165,5 @@ dojo.window.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
 	}
 };
 
-return dojo.window;
+return window;
 });
diff --git a/dojox/NodeList/README b/dojox/NodeList/README
index 4f5af63..039c37d 100755
--- a/dojox/NodeList/README
+++ b/dojox/NodeList/README
@@ -20,7 +20,7 @@ Dependencies:
 		dojo.NodeList-traverse
 -------------------------------------------------------------------------------
 Documentation
-        Documentatation will reside at:
+        Documentation resides at:
         http://api.dojotoolkit.org/NodeList
 
 -------------------------------------------------------------------------------
diff --git a/dojox/NodeList/delegate.js b/dojox/NodeList/delegate.js
index 5c7dfbb..dfdb332 100644
--- a/dojox/NodeList/delegate.js
+++ b/dojox/NodeList/delegate.js
@@ -1,8 +1,15 @@
-dojo.provide("dojox.NodeList.delegate");
+define(["dojo/_base/lang", "dojo/query", "dojo/_base/NodeList", "dojo/NodeList-traverse"], function(lang, query, NodeList) {
+	// module:
+	//		dojox/NodeList/delegate
+	// summary:
+	//		TODOC
 
-dojo.require("dojo.NodeList-traverse");
+/*=====
+// doc alias helpers:
+NodeList = dojo.NodeList;
+=====*/
 
-dojo.extend(dojo.NodeList, {
+lang.extend(NodeList, {
 	delegate: function(/*String*/ selector, /*String*/ eventName, /*Function*/ fn){
 		// summary:
 		//		Monitor nodes in this NodeList for [bubbled] events on nodes that match selector.
@@ -46,7 +53,7 @@ dojo.extend(dojo.NodeList, {
 		//	- single node version
 
 		return this.connect(eventName, function(evt){
-			var closest = dojo.query(evt.target).closest(selector, this);
+			var closest = query(evt.target).closest(selector, this);
 			if(closest.length){
 				fn.call(closest[0], evt);
 			}
@@ -54,3 +61,5 @@ dojo.extend(dojo.NodeList, {
 	}
 });
 
+return NodeList;
+});
diff --git a/dojox/NodeList/tests/delegate-async.html b/dojox/NodeList/tests/delegate-async.html
new file mode 100644
index 0000000..1f60791
--- /dev/null
+++ b/dojox/NodeList/tests/delegate-async.html
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html id="html">
+	<head>
+		<title>NodeList.delegate() test</title>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+		</style>
+		<script type="text/javascript" 
+			src="../../../dojo/dojo.js" data-dojo-config="async: true, isDebug: true, popup: true"></script>
+		<script type="text/javascript">
+            require(
+                ["dojo/query", "dojo/dom-class", "dojo/dom-construct", "dojo/dom-style", "dojox/NodeList/delegate", "dojo/domReady!"],
+
+                function (query, domClass, domConstruct, domStyle) {
+                // Monitor onclick events on div.blue nodes, or that bubble up to div.blue nodes
+				query("div.delegator").delegate("div.blue", "onclick", function(evt){
+					// "this" points to the div.blue node
+					domStyle.set(this, "backgroundColor", "#aaf");
+				});
+
+				query("div.delegator").delegate("input", "onfocus", function(evt){
+					// "this" points to the input node
+					console.log("bubbled input event");
+					domStyle.set(this, "backgroundColor", "black");
+				});
+
+				// Generate div.blue nodes inside each wrapper div.
+				// Runs after the delegate() call to demonstrate that delegate() catches events on "future nodes"
+				query("div.wrapper").forEach(function(div){
+					for(var i=0; i<4; i++){
+						domConstruct.place(
+							"<div class=" + (i%2?"blue":"red") + ">" +
+								(i%2 && domClass.contains(div, "delegator") ? "click me to turn me blue" : "click will have no effect" )+
+								"<span>" + (i%2  && domClass.contains(div, "delegator") ? "or click me to turn parent blue" : "nor will a click here") + "</span>"+
+								"focus input to turn it black (not working yet): <input />" +
+							"</div>",
+							div
+						);
+					}
+				});
+            });
+		</script>
+		<style>
+			div, a { padding: 5px; margin: 5px; display: block; }
+			div.blue { border: blue solid 2px; }
+			div.red { border: red solid 2px; }
+			div.wrapper { border: solid gray 4px; background: #eee; }
+			div.delegator { background: #ccc; }
+			span { display: block; border: yellow solid 2px; }
+		</style>
+	</head>
+	<body id="body" class="classy">
+		<h1>Test of NodeList.delegate() method</h1>
+		<div class=blue style="border: 2px dotted black;">
+			<h3>
+				This DIV has class=blue but it shouldn't matter because the delegate() connections are on
+			sub node inside of me.
+			</h3>
+			<div class="wrapper delegator">
+				<h3>This div has a delegate handler on it so clicking the blue DIV's below will have an effect.</h3>
+			</div>
+			<div class="wrapper delegator">
+				<h3>This div has a delegate handler on it so clicking the blue DIV's below will have an effect.</h3>
+			</div>
+			<div class="wrapper">
+				<h3>This div doesn't have a delegate handler on it so clicking the blue DIV's below will have no effect.</h3>
+			</div>
+		</div>
+	</body>
+</html>
+
diff --git a/dojox/analytics.js b/dojox/analytics.js
index 3367412..fbd71e6 100644
--- a/dojox/analytics.js
+++ b/dojox/analytics.js
@@ -1,3 +1,3 @@
-dojo.provide("dojox.analytics");
-dojo.require("dojox.analytics._base");
-
+define(["./analytics/_base"], function(analytics) {
+	return analytics;
+});
diff --git a/dojox/analytics/Urchin.js b/dojox/analytics/Urchin.js
index 7ebda80..2fb4707 100644
--- a/dojox/analytics/Urchin.js
+++ b/dojox/analytics/Urchin.js
@@ -1,130 +1,133 @@
-dojo.provide("dojox.analytics.Urchin");
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
+        "dojo/_base/config", "dojo/dom-construct"
+], function(lang, declare, window, config, construct){
 
-/*=====
-dojo.mixin(djConfig,{
-	// 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:""
-	//		parameter to the constructor a la: new dojox.analytics.Urchin({ acct:"UA-123456-7" });
-	urchin: ""
-});
-=====*/
-
-dojo.declare("dojox.analytics.Urchin", null, {
-	// 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
-	//		via a synchronous script tag in the body, which causes `dojo.addOnLoad` to
-	//		stall until the external API has been completely loaded. The Urchin helper
-	//		will load the API on the fly, and provide a convenient API to use, wrapping
-	//		Analytics for Ajaxy or single page applications.
-	//
-	//		The class can be instantiated two ways: Programatically, by passing an
-	//		`acct:` parameter, or via Markup / dojoType and defining a djConfig
-	//		parameter `urchin:`
-	//
-	//		IMPORTANT:
-	//		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:
-	//	|	// create the tracker programatically:
-	//	|	var tracker = new dojox.analytics.Urchin({ acct:"UA-123456-7" });
-	//
-	//	example:
-	//	|	// define the urchin djConfig option:
-	//	|	var djConfig = { urchin: "UA-123456-7" };
-	//	|
-	//	|	// and in markup:
-	//	|	<div dojoType="dojox.analytics.Urchin"></div>
-	//	|	// or code:
-	//	|	new dojox.analytics.Urchin();
-	//
-	//	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: "",
-
-	constructor: function(args){
-		// summary:
-		//		Initialize this Urchin instance. Immediately starts the load
-		//		sequence, so defer construction until (ideally) after onLoad and
-		//		potentially widget parsing.
-		this.tracker = null;
-		dojo.mixin(this, args);
-		this.acct = this.acct || dojo.config.urchin;
-
-		var re = /loaded|complete/,
-			gaHost = ("https:" == dojo.doc.location.protocol) ? "https://ssl." : "http://www.",
-			h = dojo.doc.getElementsByTagName("head")[0],
-			n = dojo.create('script', {
-				src: gaHost + "google-analytics.com/ga.js"
-			}, h);
-
-		n.onload = n.onreadystatechange = dojo.hitch(this, function(e){
-			if(e && e.type == "load" || re.test(n.readyState)){
-				n.onload = n.onreadystatechange = null;
-				this._gotGA();
-				h.removeChild(n);
-			}
-		});
+	/*=====
+	dojo.mixin(djConfig,{
+		// 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:""
+		//		parameter to the constructor a la: new dojox.analytics.Urchin({ acct:"UA-123456-7" });
+		urchin: ""
+	});
+	=====*/
 
-	},
-
-	_gotGA: function(){
-		// summary: initialize the tracker
-		this.tracker = _gat._getTracker(this.acct);
-		this.GAonLoad.apply(this, arguments);
-	},
-	
-	GAonLoad: function(){
-		// summary:
-		//		Stub function to fire when urchin is complete
-		//	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.
+	return declare("dojox.analytics.Urchin", null, {
+		// 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
+		//		via a synchronous script tag in the body, which causes `dojo.addOnLoad` to
+		//		stall until the external API has been completely loaded. The Urchin helper
+		//		will load the API on the fly, and provide a convenient API to use, wrapping
+		//		Analytics for Ajaxy or single page applications.
+		//
+		//		The class can be instantiated two ways: Programatically, by passing an
+		//		`acct:` parameter, or via Markup / dojoType and defining a djConfig
+		//		parameter `urchin:`
+		//
+		//		IMPORTANT:
+		//		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:
-		//	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",
-		//	|			GAonLoad: function(){
-		//	|				this.trackPageView("/custom-page");
-		//	|			}
-		//	|		});
-		//	|	});
-		
-		this.trackPageView();
-	},
-	
-	trackPageView: function(/* string */url){
-		// summary: A public API attached to this widget instance, allowing you
-		//		Ajax-like notification of updates.
+		//	|	// create the tracker programatically:
+		//	|	var tracker = new dojox.analytics.Urchin({ acct:"UA-123456-7" });
 		//
-		//	url: String
-		//		A location to tell the tracker to track, eg: "/my-ajaxy-endpoint"
+		//	example:
+		//	|	// define the urchin djConfig option:
+		//	|	var djConfig = { urchin: "UA-123456-7" };
+		//	|
+		//	|	// and in markup:
+		//	|	<div dojoType="dojox.analytics.Urchin"></div>
+		//	|	// or code:
+		//	|	new dojox.analytics.Urchin();
 		//
 		//	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");
-		//	|		tracker.trackPageView(ref);
-		//	|		pane.attr("href", ref);
-		//	|	});
-		
-		this.tracker._trackPageview.apply(this, arguments);
-	}
-	
+		//	|	// 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: "",
+
+		constructor: function(args){
+			// summary:
+			//		Initialize this Urchin instance. Immediately starts the load
+			//		sequence, so defer construction until (ideally) after onLoad and
+			//		potentially widget parsing.
+			this.tracker = null;
+			lang.mixin(this, args);
+			this.acct = this.acct || config.urchin;
+
+			var re = /loaded|complete/,
+				gaHost = ("https:" == window.doc.location.protocol) ? "https://ssl." : "http://www.",
+				h = window.doc.getElementsByTagName("head")[0],
+				n = construct.create('script', {
+					src: gaHost + "google-analytics.com/ga.js"
+				}, h);
+
+			n.onload = n.onreadystatechange = lang.hitch(this, function(e){
+				if(e && e.type == "load" || re.test(n.readyState)){
+					n.onload = n.onreadystatechange = null;
+					this._gotGA();
+					h.removeChild(n);
+				}
+			});
+
+		},
+
+		_gotGA: function(){
+			// summary: initialize the tracker
+			this.tracker = _gat._getTracker(this.acct);
+			this.GAonLoad.apply(this, arguments);
+		},
+
+		GAonLoad: function(){
+			// summary:
+			//		Stub function to fire when urchin is complete
+			//	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)
+			//	|	dojo.addOnLoad(function(){
+			//	|		new dojox.ananlytics.Urchin({
+			//	|			acct:"UA-12345-67",
+			//	|			GAonLoad: function(){
+			//	|				this.trackPageView("/custom-page");
+			//	|			}
+			//	|		});
+			//	|	});
+			
+			this.trackPageView();
+		},
+
+		trackPageView: function(/* string */url){
+			// summary: A public API attached to this widget instance, allowing you
+			//		Ajax-like notification of updates.
+			//
+			//	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`
+			//	|	// 'tracker' is our `Urchin` instance, pane is the `ContentPane` ref.
+			//	|	dojo.connect(container, "onclick", function(e){
+			//	|		var ref = dojo.attr(e.target, "href");
+			//	|		tracker.trackPageView(ref);
+			//	|		pane.attr("href", ref);
+			//	|	});
+			
+			this.tracker._trackPageview.apply(this.tracker, arguments);
+		}
+
+	});
 });
diff --git a/dojox/analytics/_base.js b/dojox/analytics/_base.js
index 6d0effb..33a0074 100644
--- a/dojox/analytics/_base.js
+++ b/dojox/analytics/_base.js
@@ -1,132 +1,140 @@
-dojo.provide("dojox.analytics._base");
+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;
+	=====*/
 
-dojox.analytics = function(){
-	// summary: TODOC
-	//		where we store data until we're ready to send it off.
-	//
-	//the data queue;
-	this._data = [];
+	var Analytics = function(){
+		// summary: TODOC
+		//		where we store data until we're ready to send it off.
+		//
+		//the data queue;
+		this._data = [];
 
-	//id of messages for this session/page
-	this._id = 1;
+		//id of messages for this session/page
+		this._id = 1;
 
-	//some default values
-	this.sendInterval = dojo.config["sendInterval"] || 5000;
-	this.inTransitRetry = dojo.config["inTransitRetry"] || 200;
-	this.dataUrl = dojo.config["analyticsUrl"] || dojo.moduleUrl("dojox.analytics.logger", "dojoxAnalytics.php");
-	this.sendMethod = dojo.config["sendMethod"] || "xhrPost";
-	this.maxRequestSize = dojo.isIE ? 2000 : dojo.config["maxRequestSize"] || 4000;
+		//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
-	dojo.addOnLoad(this, "schedulePusher");
-	dojo.addOnUnload(this, "pushData", true);
-};
+		//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);
+	};
 
-dojo.extend(dojox.analytics, {
-	schedulePusher: function(/* Int */interval){
-		// summary: Schedule the data pushing routines to happen in interval ms
-		setTimeout(dojo.hitch(this, "checkData"), interval || this.sendInterval);
-	},
+	lang.extend(Analytics, {
+		schedulePusher: function(/* Int */interval){
+			// 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
+		addData: function(dataType, data){
+			// summary:
+			//	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]);
+			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 = c;
-		}
 
-		this._data.push({ plugin: dataType, data: data });
-	},
+			this._data.push({ plugin: dataType, data: data });
+		},
 
-	checkData: function(){
-		// summary: TODOC?
-		if(this._inTransit){
-			this.schedulePusher(this.inTransitRetry);
-			return;
-		}
-		
-		if(this.pushData()){ return; }
-		this.schedulePusher();
-	},
+		checkData: function(){
+			// 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;
-		if(this._data.length){
-			//clear the queue
-			this._inTransit = this._data;
-			this._data = [];
-			var def;
-			switch(this.sendMethod){
-				case "script":
-					def = dojo.io.script.get({
-						url: this.getQueryPacket(),
-						preventCache: 1,
-						callbackParamName: "callback"
-					});
-					break;
-				case "xhrPost":
-				default:
-					def = dojo.xhrPost({
-						url:this.dataUrl,
-						content:{
-							id: this._id++,
-							data: dojo.toJson(this._inTransit)
-						}
-					});
-					break;
+		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;
+			if(this._data.length){
+				//clear the queue
+				this._inTransit = this._data;
+				this._data = [];
+				var def;
+				switch(this.sendMethod){
+					case "script":
+						def = scriptIO.get({
+							url: this.getQueryPacket(),
+							preventCache: 1,
+							callbackParamName: "callback"
+						});
+						break;
+					case "xhrPost":
+					default:
+						def = xhr.post({
+							url:this.dataUrl,
+							content:{
+								id: this._id++,
+								data: json.toJson(this._inTransit)
+							}
+						});
+						break;
+				}
+				def.addCallback(this, "onPushComplete");
+				return def;
 			}
-			def.addCallback(this, "onPushComplete");
-			return def;
-		}
-		return false;
-	},
+			return false;
+		},
 
-	getQueryPacket: function(){
-		// summary: TODOC
-		while(true){
-			var content = {
-				id: this._id++,
-				data: dojo.toJson(this._inTransit)
-			};
-			
-			//FIXME would like a much better way to get the query down to lenght
-			var query = this.dataUrl + '?' + dojo.objectToQuery(content);
-			if(query.length > this.maxRequestSize){
-				this._data.unshift(this._inTransit.pop());
-				this._split = 1;
-			}else{
-				return query;
+		getQueryPacket: function(){
+			// summary: TODOC
+			while(true){
+				var content = {
+					id: this._id++,
+					data: json.toJson(this._inTransit)
+				};
+				
+				//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());
+					this._split = 1;
+				}else{
+					return query;
+				}
 			}
-		}
-	},
+		},
 
-	onPushComplete: function(results){
-		// summary:
-		//	If our data push was successfully, remove the _inTransit data and schedule the next
-		//	parser run.
-		if(this._inTransit){
-			delete this._inTransit;
-		}
+		onPushComplete: function(results){
+			// summary:
+			//	If our data push was successfully, remove the _inTransit data and schedule the next
+			//	parser run.
+			if(this._inTransit){
+				delete this._inTransit;
+			}
 
-		if(this._data.length > 0){
-			this.schedulePusher(this.inTransitRetry);
-		}else{
-			this.schedulePusher();
+			if(this._data.length > 0){
+				this.schedulePusher(this.inTransitRetry);
+			}else{
+				this.schedulePusher();
+			}
 		}
-	}
-});
+	});
 
-//create the analytics  singleton
-dojox.analytics = new dojox.analytics();
+	//create the analytics  singleton
+	return lang.setObject("dojox.analytics",new Analytics());
+});
diff --git a/dojox/analytics/plugins/consoleMessages.js b/dojox/analytics/plugins/consoleMessages.js
index 7d21f61..19602cd 100644
--- a/dojox/analytics/plugins/consoleMessages.js
+++ b/dojox/analytics/plugins/consoleMessages.js
@@ -1,21 +1,26 @@
-dojo.require("dojox.analytics._base");
-dojo.provide("dojox.analytics.plugins.consoleMessages");
+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);
 
-dojox.analytics.plugins.consoleMessages = new (function(){
-	// summary:
-	//	plugin to have analyitcs return the base info dojo collects
-	this.addData = dojo.hitch(dojox.analytics, "addData", "consoleMessages");
+		// summary:
+		//	plugin to have analyitcs return the base info dojo collects
+		this.addData = lang.hitch(dxa, "addData", "consoleMessages");
 
-	var lvls = dojo.config["consoleLogFuncs"] || ["error", "warn", "info", "rlog"];
-	if(!console){
-		console = {};
-	}
+		var lvls = config["consoleLogFuncs"] || ["error", "warn", "info", "rlog"];
+		if(!console){
+			console = {};
+		}
 
-	for(var i=0; i < lvls.length; i++){
-		if(console[lvls[i]]){
-			dojo.connect(console, lvls[i], dojo.hitch(this, "addData", lvls[i]));
-		}else{
-			console[lvls[i]] = dojo.hitch(this, "addData", lvls[i]);
+		for(var i=0; i < lvls.length; i++){
+			if(console[lvls[i]]){
+				aspect.after(console, lvls[i], lang.hitch(this, "addData", lvls[i]),true);
+			}else{
+				console[lvls[i]] = lang.hitch(this, "addData", lvls[i]);
+			}
 		}
-	}
-})();
+	return consoleMessages;
+});
diff --git a/dojox/analytics/plugins/dojo.js b/dojox/analytics/plugins/dojo.js
index 04990ae..75f367d 100644
--- a/dojox/analytics/plugins/dojo.js
+++ b/dojox/analytics/plugins/dojo.js
@@ -1,19 +1,27 @@
-dojo.require("dojox.analytics._base");
-dojo.provide("dojox.analytics.plugins.dojo");
+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;
+	=====*/	
 
-dojox.analytics.plugins.dojo = new (function(){
-	// summary:
-	//	plugin to have analyitcs return the base info dojo collects
-	this.addData = dojo.hitch(dojox.analytics, "addData", "dojo");
-	dojo.addOnLoad(dojo.hitch(this, function(){
-		var data = {};
-		for(var i in dojo){
-			if ((i=="version") || ((!dojo.isObject(dojo[i]))&&(i[0]!="_"))){
-				data[i]=dojo[i];
+	return (plugins.dojo = new (function(){
+		// summary:
+		//	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 (dojo.config){data.djConfig=dojo.config}
-		this.addData(data);
-	}));
-})();
+			if (config){data.djConfig=config}
+			this.addData(data);
+		}));
+	})());
+});
diff --git a/dojox/analytics/plugins/idle.js b/dojox/analytics/plugins/idle.js
index 1917546..236d455 100644
--- a/dojox/analytics/plugins/idle.js
+++ b/dojox/analytics/plugins/idle.js
@@ -1,31 +1,38 @@
-dojo.require("dojox.analytics._base");
-dojo.provide("dojox.analytics.plugins.idle");
+define(["dojo/_base/lang", "../_base", "dojo/_base/config", "dojo/ready", 
+        "dojo/aspect", "dojo/_base/window"
+], function(lang, dxa, config, ready, aspect, window){
+	/*=====
+		dxa = dojox.analytics;
+		ready = dojo.ready;
+		aspect = dojo/aspect;
+	=====*/
 
-// window startup data
-dojox.analytics.plugins.idle = new (function(){
-	this.addData = dojo.hitch(dojox.analytics, "addData", "idle");
-	this.idleTime=dojo.config["idleTime"] || 60000;
-	this.idle=true;
-
-	this.setIdle = function(){
-		this.addData("isIdle");
+	// window startup data
+	return (dxa.plugins.idle = new (function(){
+		this.addData = lang.hitch(dxa, "addData", "idle");
+		this.idleTime=config["idleTime"] || 60000;
 		this.idle=true;
 
-	}
-	
-	dojo.addOnLoad(dojo.hitch(this, function(){
-		var idleResets=["onmousemove","onkeydown","onclick","onscroll"];
-		for (var i=0;i<idleResets.length;i++){
-			dojo.connect(dojo.doc,idleResets[i],this, function(e){
-				if (this.idle){
-					this.idle=false;
-					this.addData("isActive");
-					this.idleTimer=setTimeout(dojo.hitch(this,"setIdle"), this.idleTime);
-				}else{
-					clearTimeout(this.idleTimer);
-					this.idleTimer=setTimeout(dojo.hitch(this,"setIdle"), this.idleTime);
-				}
-			});
+		this.setIdle = function(){
+			this.addData("isIdle");
+			this.idle=true;
+
 		}
-	}));
-})();
+
+		ready(lang.hitch(this, function(){
+			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;
+						this.addData("isActive");
+						this.idleTimer=setTimeout(lang.hitch(this,"setIdle"), this.idleTime);
+					}else{
+						clearTimeout(this.idleTimer);
+						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 52ba1f5..02c0bc8 100644
--- a/dojox/analytics/plugins/mouseClick.js
+++ b/dojox/analytics/plugins/mouseClick.js
@@ -1,46 +1,51 @@
-dojo.require("dojox.analytics._base");
-dojo.provide("dojox.analytics.plugins.mouseClick");
+define(["dojo/_base/lang","../_base", "dojo/_base/window", "dojo/on"
+], function(lang, dxa, window, on){
+	/*=====
+		dxa = dojox.analytics;
+		on = dojo.on;
+	=====*/	
 
-// window startup data
-dojox.analytics.plugins.mouseClick = new (function(){
-	this.addData = dojo.hitch(dojox.analytics, "addData", "mouseClick");
+	// window startup data
+	return (dxa.plugins.mouseClick = new (function(){
+		this.addData = lang.hitch(dxa, "addData", "mouseClick");
 
-	this.onClick=function(e){
-		this.addData(this.trimEvent(e));
-	}
-	dojo.connect(dojo.doc, "onclick", this, "onClick");
+		this.onClick=function(e){
+			this.addData(this.trimEvent(e));
+		}
+		on(window.doc, "click", lang.hitch(this, "onClick"));
 
-	this.trimEvent=function(e){
-		var t = {};
-		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++){
-						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);
+		this.trimEvent=function(e){
+			var t = {};
+			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++){
+							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);
+									}
+								}else{
+									t[i][props[j]]=e[i][props[j]];
 								}
-							}else{
-								t[i][props[j]]=e[i][props[j]];
 							}
 						}
-					}
-					break;
-				case "clientX":
-				case "clientY":
-				case "pageX":
-				case "pageY":
-				case "screenX":
-				case "screenY":
-					t[i]=e[i];
-					break;
+						break;
+					case "clientX":
+					case "clientY":
+					case "pageX":
+					case "pageY":
+					case "screenX":
+					case "screenY":
+						t[i]=e[i];
+						break;
+				}
 			}
+			return t;
 		}
-		return t;
-	}
-})();
+	})());
+});
\ No newline at end of file
diff --git a/dojox/analytics/plugins/mouseOver.js b/dojox/analytics/plugins/mouseOver.js
index ff68020..f8c024c 100644
--- a/dojox/analytics/plugins/mouseOver.js
+++ b/dojox/analytics/plugins/mouseOver.js
@@ -1,87 +1,92 @@
-dojo.require("dojox.analytics._base");
-dojo.provide("dojox.analytics.plugins.mouseOver");
+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;
+	=====*/	
 
-dojox.analytics.plugins.mouseOver = new (function(){
-	this.watchMouse = dojo.config["watchMouseOver"] || true;
-	this.mouseSampleDelay = dojo.config["sampleDelay"] || 2500;
-	this.addData = dojo.hitch(dojox.analytics, "addData", "mouseOver");
-	this.targetProps = dojo.config["targetProps"] || ["id","className","localName","href", "spellcheck", "lang", "textContent", "value" ];
+	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.toggleWatchMouse=function(){
-		if (this._watchingMouse){
-			dojo.disconnect(this._watchingMouse);
-			delete this._watchingMouse;
-			return;
+		this.toggleWatchMouse=function(){
+			if (this._watchingMouse){
+				this._watchingMouse.remove();
+				delete this._watchingMouse;
+				return;
+			}
+			on(window.doc, "mousemove", lang.hitch(this, "sampleMouse"));
 		}
-		dojo.connect(dojo.doc, "onmousemove", this, "sampleMouse");
-	}
 
-	if (this.watchMouse){
-		dojo.connect(dojo.doc, "onmouseover", this, "toggleWatchMouse");
-		dojo.connect(dojo.doc, "onmouseout", this, "toggleWatchMouse");
-	}
+		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.addData("sample",this.trimMouseEvent(e));
-			this._rateLimited=true;
-			setTimeout(dojo.hitch(this, function(){
-				if (this._rateLimited){
-					//this.addData("sample", this.trimMouseEvent(this._lastMouseEvent));
-					this.trimMouseEvent(this._lastMouseEvent);
-					delete this._lastMouseEvent;
-					delete this._rateLimited;
-				}
-			}), this.mouseSampleDelay);
+		this.sampleMouse=function(e){
+			if (!this._rateLimited){
+				this.addData("sample",this.trimMouseEvent(e));
+				this._rateLimited=true;
+				setTimeout(lang.hitch(this, function(){
+					if (this._rateLimited){
+						//this.addData("sample", this.trimMouseEvent(this._lastMouseEvent));
+						this.trimMouseEvent(this._lastMouseEvent);
+						delete this._lastMouseEvent;
+						delete this._rateLimited;
+					}
+				}), this.mouseSampleDelay);
+			}
+			this._lastMouseEvent = e;
+			return e;
 		}
-		this._lastMouseEvent = e;
-		return e;
-	}
 
-	this.trimMouseEvent=function(e){
-		var t = {};
-		for (var i in e){
-			switch(i){
-				//case "currentTarget":
-				case "target":
-				//case "originalTarget":
-				//case "explicitOriginalTarget":
-					var props=this.targetProps;
-					t[i]={};
-					//console.log(e, i, e[i]);
-					for(var j=0;j<props.length;j++){
-						if(dojo.isObject(e[i]) && 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);
+		this.trimMouseEvent=function(e){
+			var t = {};
+			for (var i in e){
+				switch(i){
+					//case "currentTarget":
+					case "target":
+					//case "originalTarget":
+					//case "explicitOriginalTarget":
+						var props=this.targetProps;
+						t[i]={};
+						//console.log(e, i, e[i]);
+						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);
+									}
+								}else{
+									t[i][props[j]]=e[i][props[j]];
 								}
-							}else{
-								t[i][props[j]]=e[i][props[j]];
 							}
 						}
-					}
-					break;
-				//case "clientX":
-				//case "clientY":
-				//case "pageX":
-				//case "pageY":
-				//case "screenX":
-				//case "screenY":
-				case "x":
-				case "y":
-					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 + '';
-					}
-					break;
-				default:
-					//console.log("Skipping: ", i);
-					break;
+						break;
+					//case "clientX":
+					//case "clientY":
+					//case "pageX":
+					//case "pageY":
+					//case "screenX":
+					//case "screenY":
+					case "x":
+					case "y":
+						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 + '';
+						}
+						break;
+					default:
+						//console.log("Skipping: ", i);
+						break;
+				}
 			}
+			return t;
 		}
-		return t;
-	}
-})();
+	})());
+});
\ No newline at end of file
diff --git a/dojox/analytics/plugins/window.js b/dojox/analytics/plugins/window.js
index 487339b..38c8dfa 100644
--- a/dojox/analytics/plugins/window.js
+++ b/dojox/analytics/plugins/window.js
@@ -1,31 +1,37 @@
-dojo.require("dojox.analytics._base");
-dojo.provide("dojox.analytics.plugins.window");
+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
-dojox.analytics.plugins.window = new (function(){
-	this.addData = dojo.hitch(dojox.analytics, "addData", "window");
-	this.windowConnects = dojo.config["windowConnects"] || ["open", "onerror"];
+	// 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++){
-		dojo.connect(window, this.windowConnects[i], dojo.hitch(this, "addData", this.windowConnects[i]));
-	}
+		for(var i=0; i<this.windowConnects.length;i++){
+			aspect.after(window, this.windowConnects[i], lang.hitch(this, "addData", this.windowConnects[i]),true);
+		}
 
-	dojo.addOnLoad(dojo.hitch(this, function(){
-		var data = {};
-		for(var i in window){
-			if (dojo.isObject(window[i])){
-				switch(i){
-					case "location":
-					case "console":
-						data[i]=window[i];
-						break;
-					default:
-						break;
+		ready(lang.hitch(this, function(){
+			var data = {};
+			for(var i in window){
+				if (typeof window[i] == "object" || typeof window[i] == "function"){
+					switch(i){
+						case "location":
+						case "console":
+							data[i]=window[i];
+							break;
+						default:
+							break;
+					}
+				}else{
+					data[i]=window[i];
 				}
-			}else{
-				data[i]=window[i];
 			}
-		}
-		this.addData(data);
-	}));
-})();
+			this.addData(data);
+		}));
+	})());
+});
\ No newline at end of file
diff --git a/dojox/analytics/tests/test_GoogleAnalytics.html b/dojox/analytics/tests/test_GoogleAnalytics.html
index dab18fa..53cce99 100644
--- a/dojox/analytics/tests/test_GoogleAnalytics.html
+++ b/dojox/analytics/tests/test_GoogleAnalytics.html
@@ -18,8 +18,6 @@
 
 	<!-- do not use: only for testing alternate themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
-	<script type="text/javascript" src="../Urchin.js"></script>
-	
 
 	<script language="JavaScript" type="text/javascript">
 		// include the analytics system
diff --git a/dojox/analytics/tests/test_GoogleAnalyticsMarkup.html b/dojox/analytics/tests/test_GoogleAnalyticsMarkup.html
index 96a95d3..6979163 100644
--- a/dojox/analytics/tests/test_GoogleAnalyticsMarkup.html
+++ b/dojox/analytics/tests/test_GoogleAnalyticsMarkup.html
@@ -23,8 +23,7 @@
 
 	<!-- do not use: only for testing alternate themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
-	<script type="text/javascript" src="../Urchin.js"></script>
-	
+
 	<script language="JavaScript" type="text/javascript">
 		// include the analytics system
 		dojo.require("dojo.parser");
diff --git a/dojox/analytics/tests/test_analytics-async.html b/dojox/analytics/tests/test_analytics-async.html
new file mode 100644
index 0000000..69cb559
--- /dev/null
+++ b/dojox/analytics/tests/test_analytics-async.html
@@ -0,0 +1,121 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<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"
+		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>
+
+	<!-- 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");
+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>
+</html>
diff --git a/dojox/analytics/tests/test_analytics.html b/dojox/analytics/tests/test_analytics.html
index 42ef027..eb08e8b 100644
--- a/dojox/analytics/tests/test_analytics.html
+++ b/dojox/analytics/tests/test_analytics.html
@@ -12,9 +12,10 @@
 	<!-- required: a default theme file -->
 	<link rel="stylesheet" id="themeStyles" href="../../../dijit/themes/tundra/tundra.css">
 	
-	<!-- required: dojo.js -->
+	<!-- 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, analyticsUrl: 'http://dojotoolkit.org/~dmachi/dojo-1.0/dojox/analytics/logger/dojoxAnalytics.php'"></script>
+		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>
 
 	<!-- do not use: only for testing alternate themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -55,7 +56,9 @@
 		dojo.require("dijit.form.Button");
 		dojo.require("dijit.form.ComboBox");
 
-		dojo.addOnLoad(function(){console.info("Page Loaded Sample Message");});
+		dojo.addOnLoad(function(){
+			console.info("Page Loaded Sample Message");
+		});
 	</script>
 
 </head>
diff --git a/dojox/app/README.txt b/dojox/app/README.txt
new file mode 100644
index 0000000..1849006
--- /dev/null
+++ b/dojox/app/README.txt
@@ -0,0 +1,174 @@
+-------------------------------------------------------------------------------
+DojoX app 
+-------------------------------------------------------------------------------
+Version 0.1
+Release date: 05/08/2011
+-------------------------------------------------------------------------------
+Project state: EXPERIMENTAL / Under Construction
+
+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
+-------------------------------------------------------------------------------
+Project authors
+	Dustin Machi
+	Stephen Zhang
+-------------------------------------------------------------------------------
+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 [...]
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core (dijit, dojox/mobile).
+-------------------------------------------------------------------------------
+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.  
+
+Example Config:
+<code>
+{
+	/* global application dependencies */
+	"dependencies": [
+		"dojox/mobile/Heading",
+		"dojo/mobile/RoundRect",
+		"my/custom/module"
+	],
+
+	/* Application Modules.  These are implicitly added to the above set of dependencies */
+	modules: [
+		"dojox/app/module/history",
+		"my/custom/appModule"
+	],
+
+	/* The html template for the application itself */
+	template: "example.html",
+
+	/* the view to start on by default */
+	"defaultView": "home",
+
+	/* transition to use if none has been provided */
+	"defaultTransition": "slide",
+
+	/* Views and Scenes */
+	"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",
+				"dojox/mobile/EdgeToEdgeCategory"
+			],
+
+			/* template to use for this view */
+			template: "views/home.html"
+		},
+	
+		/* tabscene is a dojox.app.scene, and it contains three child views */
+
+		"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 */	
+			"defaultView": "tab1",
+
+			/* when transitioning between tabs, use a flip animation by default */
+			"defaultTransition": "flip",
+
+			//the views available to this scene
+			"views": { 
+				"tab1":{
+					"template": "views/tabs/tab1.html" 
+				},
+				"tab2":{
+					"template": "views/tabs/tab2.html" 
+				},
+				"tab3":{
+					"template": "views/tabs/tab3.html" 
+				}
+			},
+
+			/* dependencies specific to this scene */
+			"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.  
+
+	- 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.
+
+	- 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.  
+
+	- defaultView - The default view defines the starting view for the application when loaded to its root. 
+
+	- 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.
+
+	- 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.
+
+Some additional properties, such as models, stores, id, name, and description are reserved for future use, but their exact use is still under development.  
+
+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>
+
+
+The Scene Class:
+
+	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.
+
+	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:
+
+<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>
+
+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.  
+
+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).
+
+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.
+
+The View Class:
+
+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.
+
+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 [...]
+
+TODO:
+
+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
+
+- 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.
+
+- 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.  
+
+- 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.
diff --git a/dojox/app/animation.js b/dojox/app/animation.js
new file mode 100644
index 0000000..a2d168c
--- /dev/null
+++ b/dojox/app/animation.js
@@ -0,0 +1,346 @@
+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
new file mode 100644
index 0000000..3bb43c2
--- /dev/null
+++ b/dojox/app/bind.js
@@ -0,0 +1,39 @@
+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/main.js b/dojox/app/main.js
new file mode 100644
index 0000000..cc0880f
--- /dev/null
+++ b/dojox/app/main.js
@@ -0,0 +1,115 @@
+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={};
+			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);
+			        }
+			    }
+			}
+
+		},
+
+		// 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());
+			}
+			this.inherited(arguments);
+		}
+	});
+	
+	function generateApp(config,node,appSchema,validate){
+
+		//console.log("config.modules: ", config.modules);
+		var modules = config.modules.concat(config.dependencies);
+
+		if (config.template){
+			//console.log("config.template: ", config.template);
+			modules.push("dojo/text!" + "app/" + config.template);
+		}
+		//console.log("modules: ", modules);	
+
+		require(modules, function(){
+			var modules=[Application];
+			for(var i=0;i<config.modules.length;i++){
+				modules.push(arguments[i]);
+			}
+
+			if (config.template){
+				var ext = {
+					templateString: arguments[arguments.length-1] 
+				}	
+			}
+			App = declare(modules,ext);
+
+			ready(function(){
+				app = App(config,node || baseWindow.body());
+                app.setStatus(app.lifecycle.STARTING);
+                app.start();
+			});
+		});
+	}
+
+
+	return function(config,node){
+		if (!config){
+			throw 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);
+				}	
+			});
+		
+
+		}else{
+			generateApp(config,node);
+		}
+	}
+});
diff --git a/dojox/app/model.js b/dojox/app/model.js
new file mode 100644
index 0000000..db5fbfd
--- /dev/null
+++ b/dojox/app/model.js
@@ -0,0 +1,26 @@
+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/env.js b/dojox/app/module/env.js
new file mode 100644
index 0000000..d08abfc
--- /dev/null
+++ b/dojox/app/module/env.js
@@ -0,0 +1,21 @@
+define(["dojo/_base/declare"], function(declare){
+	return declare(null, {
+		mode: "",
+		init: function(){
+
+			//TODO BROADLY categorize the mode of the app...mobile,desktop
+			//     This should be done with UA sniffing, but remember
+			//	very broadly, this is for purposes of deciding
+			//	which ui to render, NOT feature detection	
+			/*
+			this.mode="mobile";
+			var def = this.inherited(arguments);
+
+			//just an example
+			return def.then(function(){
+				console.log("env init after inherited inits");
+			});	
+			*/
+		}
+	});
+});
diff --git a/dojox/app/module/history.js b/dojox/app/module/history.js
new file mode 100644
index 0000000..09e754c
--- /dev/null
+++ b/dojox/app/module/history.js
@@ -0,0 +1,90 @@
+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
new file mode 100644
index 0000000..8029baf
--- /dev/null
+++ b/dojox/app/module/lifecycle.js
@@ -0,0 +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]);
+        }
+    });
+});
diff --git a/dojox/app/scene.js b/dojox/app/scene.js
new file mode 100644
index 0000000..76d3afd
--- /dev/null
+++ b/dojox/app/scene.js
@@ -0,0 +1,588 @@
+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/README b/dojox/app/schema/README
new file mode 100644
index 0000000..7e514bb
--- /dev/null
+++ b/dojox/app/schema/README
@@ -0,0 +1 @@
+Schemas to validate application configs, not fully in sync with what is being accepted just yet
diff --git a/dojox/app/schema/application.json b/dojox/app/schema/application.json
new file mode 100644
index 0000000..7f8fdd4
--- /dev/null
+++ b/dojox/app/schema/application.json
@@ -0,0 +1,55 @@
+define({
+	"description":"A representation of an Application",
+	"type": "object",
+	"properties":{
+		"author": {"$ref": "http://json-schema.org/card"},
+
+		"description": {
+			"description": "Description of the application represented here",
+			"type": "string"
+		},
+
+		"modules": {
+			"type": "array",
+			"description": "Modules this application requires ",
+			"default": [],
+			"items":{
+				"type": "string",
+				"description": "Module to be loaded and mixed into the application"
+			}
+		},
+
+
+		"defaultScene": {
+			"type": "string"
+			"description": "id of scene to load for this application at startup"
+		},
+
+		"scenes": {
+			"type": "object",
+			"description": "This object contains references to scene objects, which are collections of views and models making up a closely related set of the ui",
+			"additionalProperties":{"$ref":"/jdoe/test/schema/scene.json"}
+		},
+
+		"stores": { 
+			"type": "object",
+			"description":"This object contains references to store instances that the rest of the application will use.",
+			"additionalProperties": {"$ref":"/jdoe/test/schema/scene.json"},
+			"default": {}
+		},
+
+		"models": { 
+			"type": "object",
+			"description": "This object contains references to model instances the application uses",
+			"additionalProperties":{"$ref":"/jdoe/test/schema/model.json"},
+			"default": {}
+		},
+
+		"views": { 
+			"type": "object",
+			"description": "This object contains references to view instances the application uses",
+			"additionalProperties":{"$ref":"/jdoe/test/schema/view.json"},
+			"default": {}
+		}
+	}
+});
diff --git a/dojox/app/schema/model.json b/dojox/app/schema/model.json
new file mode 100644
index 0000000..a630516
--- /dev/null
+++ b/dojox/app/schema/model.json
@@ -0,0 +1,11 @@
+{
+	"description":"An applications model declaration", 
+	"type": "object",
+	"properties":{
+		"type": {
+			"type": "string",
+			"description": "Model Instance Type (Class)"
+		},
+	},
+	"additionalProperties": true
+}
diff --git a/dojox/app/schema/scene.json b/dojox/app/schema/scene.json
new file mode 100644
index 0000000..412ce90
--- /dev/null
+++ b/dojox/app/schema/scene.json
@@ -0,0 +1,29 @@
+{
+	"description":"An application's scene instance declarations", 
+	"type": "object",
+	"properties":{
+		"type": {
+			"type": "string",
+			"description": "Scene Instance Type (Class)"
+		},
+		"models": {
+			"type": "array",
+			"items": {"$ref": "/jdoe/test/schema/model"}
+		},
+		"views": {
+			"type": "array",
+			"items": {
+				"type": "object",
+				"properties" : {
+					"id": {
+						"type": "string"
+					},
+					"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
new file mode 100644
index 0000000..924f5e1
--- /dev/null
+++ b/dojox/app/schema/store.json
@@ -0,0 +1,11 @@
+{
+	"description":"An applications store instance declarations", 
+	"type": "object",
+	"properties":{
+		"type": {
+			"type": "string",
+			"description": "Store Instance Type (Class)"
+		},
+	},
+	"additionalProperties": true
+}
diff --git a/dojox/app/schema/view.json b/dojox/app/schema/view.json
new file mode 100644
index 0000000..b6c1c54
--- /dev/null
+++ b/dojox/app/schema/view.json
@@ -0,0 +1,30 @@
+{
+	"description": "Base View Schema for defining View Instances in an application",	
+	"type": "object",
+	"properties": {
+		"type": {
+			"type":"string",
+			"description": "The Name of the Class to be used for this view"		
+		},
+
+		"models": {
+			"type": "array",
+			"items": {
+				"type":"string",
+				"description": "Models that this view requires. These should reference one of the available #models",
+				"dependences":{}
+			}
+		},
+
+		"persist": {
+			"type": "boolean",
+			"description":"Keep this view loaded on the dom or memory, but not necessarily visible"
+		},
+
+		"template": {
+			"type": "string",
+			"description": "Template to be used with this view"
+		}
+	}
+}
+
diff --git a/dojox/app/tests/images/a-icon-1-41x41.png b/dojox/app/tests/images/a-icon-1-41x41.png
new file mode 100755
index 0000000..0e94b75
Binary files /dev/null and b/dojox/app/tests/images/a-icon-1-41x41.png differ
diff --git a/dojox/app/tests/images/a-icon-1.png b/dojox/app/tests/images/a-icon-1.png
new file mode 100755
index 0000000..5f28394
Binary files /dev/null and b/dojox/app/tests/images/a-icon-1.png differ
diff --git a/dojox/app/tests/images/a-icon-10.png b/dojox/app/tests/images/a-icon-10.png
new file mode 100644
index 0000000..b3df995
Binary files /dev/null and b/dojox/app/tests/images/a-icon-10.png differ
diff --git a/dojox/app/tests/images/a-icon-11.png b/dojox/app/tests/images/a-icon-11.png
new file mode 100644
index 0000000..307b8e3
Binary files /dev/null and b/dojox/app/tests/images/a-icon-11.png differ
diff --git a/dojox/app/tests/images/a-icon-12.png b/dojox/app/tests/images/a-icon-12.png
new file mode 100644
index 0000000..425cadb
Binary files /dev/null and b/dojox/app/tests/images/a-icon-12.png differ
diff --git a/dojox/app/tests/images/a-icon-13.png b/dojox/app/tests/images/a-icon-13.png
new file mode 100644
index 0000000..7244dbe
Binary files /dev/null and b/dojox/app/tests/images/a-icon-13.png differ
diff --git a/dojox/app/tests/images/a-icon-14.png b/dojox/app/tests/images/a-icon-14.png
new file mode 100644
index 0000000..c8afcec
Binary files /dev/null and b/dojox/app/tests/images/a-icon-14.png differ
diff --git a/dojox/app/tests/images/a-icon-15.png b/dojox/app/tests/images/a-icon-15.png
new file mode 100644
index 0000000..49812a3
Binary files /dev/null and b/dojox/app/tests/images/a-icon-15.png differ
diff --git a/dojox/app/tests/images/a-icon-16.png b/dojox/app/tests/images/a-icon-16.png
new file mode 100644
index 0000000..8208beb
Binary files /dev/null and b/dojox/app/tests/images/a-icon-16.png differ
diff --git a/dojox/app/tests/images/a-icon-17.png b/dojox/app/tests/images/a-icon-17.png
new file mode 100644
index 0000000..533870e
Binary files /dev/null and b/dojox/app/tests/images/a-icon-17.png differ
diff --git a/dojox/app/tests/images/a-icon-18.png b/dojox/app/tests/images/a-icon-18.png
new file mode 100644
index 0000000..d52419a
Binary files /dev/null and b/dojox/app/tests/images/a-icon-18.png differ
diff --git a/dojox/app/tests/images/a-icon-2-41x41.png b/dojox/app/tests/images/a-icon-2-41x41.png
new file mode 100755
index 0000000..df8aaaf
Binary files /dev/null and b/dojox/app/tests/images/a-icon-2-41x41.png differ
diff --git a/dojox/app/tests/images/a-icon-2.png b/dojox/app/tests/images/a-icon-2.png
new file mode 100755
index 0000000..c457062
Binary files /dev/null and b/dojox/app/tests/images/a-icon-2.png differ
diff --git a/dojox/app/tests/images/a-icon-3.png b/dojox/app/tests/images/a-icon-3.png
new file mode 100755
index 0000000..dc3941f
Binary files /dev/null and b/dojox/app/tests/images/a-icon-3.png differ
diff --git a/dojox/app/tests/images/a-icon-4.png b/dojox/app/tests/images/a-icon-4.png
new file mode 100755
index 0000000..c7df122
Binary files /dev/null and b/dojox/app/tests/images/a-icon-4.png differ
diff --git a/dojox/app/tests/images/b-app-icon-1.png b/dojox/app/tests/images/b-app-icon-1.png
new file mode 100644
index 0000000..e6c072c
Binary files /dev/null and b/dojox/app/tests/images/b-app-icon-1.png differ
diff --git a/dojox/app/tests/images/b-app-icon-2.png b/dojox/app/tests/images/b-app-icon-2.png
new file mode 100644
index 0000000..1252683
Binary files /dev/null and b/dojox/app/tests/images/b-app-icon-2.png differ
diff --git a/dojox/app/tests/images/b-app-icon-3.png b/dojox/app/tests/images/b-app-icon-3.png
new file mode 100644
index 0000000..0d239a8
Binary files /dev/null and b/dojox/app/tests/images/b-app-icon-3.png differ
diff --git a/dojox/app/tests/images/b-app-icon-4.png b/dojox/app/tests/images/b-app-icon-4.png
new file mode 100644
index 0000000..16eb0d7
Binary files /dev/null and b/dojox/app/tests/images/b-app-icon-4.png differ
diff --git a/dojox/app/tests/images/b-app-icon-5.png b/dojox/app/tests/images/b-app-icon-5.png
new file mode 100644
index 0000000..38e69cc
Binary files /dev/null and b/dojox/app/tests/images/b-app-icon-5.png differ
diff --git a/dojox/app/tests/images/b-app-icon-6.png b/dojox/app/tests/images/b-app-icon-6.png
new file mode 100644
index 0000000..04bf53c
Binary files /dev/null and b/dojox/app/tests/images/b-app-icon-6.png differ
diff --git a/dojox/app/tests/images/b-app-icon-7.png b/dojox/app/tests/images/b-app-icon-7.png
new file mode 100644
index 0000000..0a92e0c
Binary files /dev/null and b/dojox/app/tests/images/b-app-icon-7.png differ
diff --git a/dojox/app/tests/images/b-app-icon-8.png b/dojox/app/tests/images/b-app-icon-8.png
new file mode 100644
index 0000000..9beadfe
Binary files /dev/null and b/dojox/app/tests/images/b-app-icon-8.png differ
diff --git a/dojox/app/tests/images/b-icon-1.png b/dojox/app/tests/images/b-icon-1.png
new file mode 100644
index 0000000..3dee072
Binary files /dev/null and b/dojox/app/tests/images/b-icon-1.png differ
diff --git a/dojox/app/tests/images/b-icon-2.png b/dojox/app/tests/images/b-icon-2.png
new file mode 100644
index 0000000..4b5ab9c
Binary files /dev/null and b/dojox/app/tests/images/b-icon-2.png differ
diff --git a/dojox/app/tests/images/b-icon-3.png b/dojox/app/tests/images/b-icon-3.png
new file mode 100644
index 0000000..bfbf682
Binary files /dev/null and b/dojox/app/tests/images/b-icon-3.png differ
diff --git a/dojox/app/tests/images/b-icon-4.png b/dojox/app/tests/images/b-icon-4.png
new file mode 100644
index 0000000..18e26a6
Binary files /dev/null and b/dojox/app/tests/images/b-icon-4.png differ
diff --git a/dojox/app/tests/images/b-icon-5.png b/dojox/app/tests/images/b-icon-5.png
new file mode 100644
index 0000000..52befc8
Binary files /dev/null and b/dojox/app/tests/images/b-icon-5.png differ
diff --git a/dojox/app/tests/images/b-icon-6.png b/dojox/app/tests/images/b-icon-6.png
new file mode 100644
index 0000000..59ed1d9
Binary files /dev/null and b/dojox/app/tests/images/b-icon-6.png differ
diff --git a/dojox/app/tests/images/b-icon-7.png b/dojox/app/tests/images/b-icon-7.png
new file mode 100644
index 0000000..026e3f0
Binary files /dev/null and b/dojox/app/tests/images/b-icon-7.png differ
diff --git a/dojox/app/tests/images/b-icon-8.png b/dojox/app/tests/images/b-icon-8.png
new file mode 100644
index 0000000..f7190f4
Binary files /dev/null and b/dojox/app/tests/images/b-icon-8.png differ
diff --git a/dojox/app/tests/images/chart.png b/dojox/app/tests/images/chart.png
new file mode 100644
index 0000000..3887ba8
Binary files /dev/null and b/dojox/app/tests/images/chart.png differ
diff --git a/dojox/app/tests/images/checkboxRadioButtonStates.png b/dojox/app/tests/images/checkboxRadioButtonStates.png
new file mode 100644
index 0000000..2d06a82
Binary files /dev/null and b/dojox/app/tests/images/checkboxRadioButtonStates.png differ
diff --git a/dojox/app/tests/images/dish1.jpg b/dojox/app/tests/images/dish1.jpg
new file mode 100644
index 0000000..2b147ef
Binary files /dev/null and b/dojox/app/tests/images/dish1.jpg differ
diff --git a/dojox/app/tests/images/dish2.jpg b/dojox/app/tests/images/dish2.jpg
new file mode 100644
index 0000000..32cac74
Binary files /dev/null and b/dojox/app/tests/images/dish2.jpg differ
diff --git a/dojox/app/tests/images/dish3.jpg b/dojox/app/tests/images/dish3.jpg
new file mode 100644
index 0000000..d57cc3e
Binary files /dev/null and b/dojox/app/tests/images/dish3.jpg differ
diff --git a/dojox/app/tests/images/dish4.jpg b/dojox/app/tests/images/dish4.jpg
new file mode 100644
index 0000000..342569c
Binary files /dev/null and b/dojox/app/tests/images/dish4.jpg differ
diff --git a/dojox/app/tests/images/dish5.jpg b/dojox/app/tests/images/dish5.jpg
new file mode 100644
index 0000000..ab97da6
Binary files /dev/null and b/dojox/app/tests/images/dish5.jpg differ
diff --git a/dojox/app/tests/images/dish6.jpg b/dojox/app/tests/images/dish6.jpg
new file mode 100644
index 0000000..c954329
Binary files /dev/null and b/dojox/app/tests/images/dish6.jpg differ
diff --git a/dojox/app/tests/images/dish7.jpg b/dojox/app/tests/images/dish7.jpg
new file mode 100644
index 0000000..ce51f3a
Binary files /dev/null and b/dojox/app/tests/images/dish7.jpg differ
diff --git a/dojox/app/tests/images/dish8.jpg b/dojox/app/tests/images/dish8.jpg
new file mode 100644
index 0000000..73a4d6c
Binary files /dev/null and b/dojox/app/tests/images/dish8.jpg differ
diff --git a/dojox/app/tests/images/dish9.jpg b/dojox/app/tests/images/dish9.jpg
new file mode 100644
index 0000000..4cc815c
Binary files /dev/null and b/dojox/app/tests/images/dish9.jpg differ
diff --git a/dojox/app/tests/images/glass1.jpg b/dojox/app/tests/images/glass1.jpg
new file mode 100644
index 0000000..65edf8d
Binary files /dev/null and b/dojox/app/tests/images/glass1.jpg differ
diff --git a/dojox/app/tests/images/glass10.jpg b/dojox/app/tests/images/glass10.jpg
new file mode 100644
index 0000000..be890a2
Binary files /dev/null and b/dojox/app/tests/images/glass10.jpg differ
diff --git a/dojox/app/tests/images/glass11.jpg b/dojox/app/tests/images/glass11.jpg
new file mode 100644
index 0000000..c51a991
Binary files /dev/null and b/dojox/app/tests/images/glass11.jpg differ
diff --git a/dojox/app/tests/images/glass12.jpg b/dojox/app/tests/images/glass12.jpg
new file mode 100644
index 0000000..0d03c6b
Binary files /dev/null and b/dojox/app/tests/images/glass12.jpg differ
diff --git a/dojox/app/tests/images/glass13.jpg b/dojox/app/tests/images/glass13.jpg
new file mode 100644
index 0000000..afa1ab6
Binary files /dev/null and b/dojox/app/tests/images/glass13.jpg differ
diff --git a/dojox/app/tests/images/glass14.jpg b/dojox/app/tests/images/glass14.jpg
new file mode 100644
index 0000000..9b3f904
Binary files /dev/null and b/dojox/app/tests/images/glass14.jpg differ
diff --git a/dojox/app/tests/images/glass15.jpg b/dojox/app/tests/images/glass15.jpg
new file mode 100644
index 0000000..6ca4e4c
Binary files /dev/null and b/dojox/app/tests/images/glass15.jpg differ
diff --git a/dojox/app/tests/images/glass16.jpg b/dojox/app/tests/images/glass16.jpg
new file mode 100644
index 0000000..e695221
Binary files /dev/null and b/dojox/app/tests/images/glass16.jpg differ
diff --git a/dojox/app/tests/images/glass2.jpg b/dojox/app/tests/images/glass2.jpg
new file mode 100644
index 0000000..2ff3476
Binary files /dev/null and b/dojox/app/tests/images/glass2.jpg differ
diff --git a/dojox/app/tests/images/glass3.jpg b/dojox/app/tests/images/glass3.jpg
new file mode 100644
index 0000000..eebaf31
Binary files /dev/null and b/dojox/app/tests/images/glass3.jpg differ
diff --git a/dojox/app/tests/images/glass4.jpg b/dojox/app/tests/images/glass4.jpg
new file mode 100644
index 0000000..c1e34a1
Binary files /dev/null and b/dojox/app/tests/images/glass4.jpg differ
diff --git a/dojox/app/tests/images/glass5.jpg b/dojox/app/tests/images/glass5.jpg
new file mode 100644
index 0000000..30520c4
Binary files /dev/null and b/dojox/app/tests/images/glass5.jpg differ
diff --git a/dojox/app/tests/images/glass6.jpg b/dojox/app/tests/images/glass6.jpg
new file mode 100644
index 0000000..444f9f4
Binary files /dev/null and b/dojox/app/tests/images/glass6.jpg differ
diff --git a/dojox/app/tests/images/glass7.jpg b/dojox/app/tests/images/glass7.jpg
new file mode 100644
index 0000000..1672ab2
Binary files /dev/null and b/dojox/app/tests/images/glass7.jpg differ
diff --git a/dojox/app/tests/images/glass8.jpg b/dojox/app/tests/images/glass8.jpg
new file mode 100644
index 0000000..a4d1e4d
Binary files /dev/null and b/dojox/app/tests/images/glass8.jpg differ
diff --git a/dojox/app/tests/images/glass9.jpg b/dojox/app/tests/images/glass9.jpg
new file mode 100644
index 0000000..ff98ce0
Binary files /dev/null and b/dojox/app/tests/images/glass9.jpg differ
diff --git a/dojox/app/tests/images/i-icon-1.png b/dojox/app/tests/images/i-icon-1.png
new file mode 100755
index 0000000..8cbf494
Binary files /dev/null and b/dojox/app/tests/images/i-icon-1.png differ
diff --git a/dojox/app/tests/images/i-icon-10.png b/dojox/app/tests/images/i-icon-10.png
new file mode 100755
index 0000000..65a7909
Binary files /dev/null and b/dojox/app/tests/images/i-icon-10.png differ
diff --git a/dojox/app/tests/images/i-icon-2.png b/dojox/app/tests/images/i-icon-2.png
new file mode 100755
index 0000000..1965b3e
Binary files /dev/null and b/dojox/app/tests/images/i-icon-2.png differ
diff --git a/dojox/app/tests/images/i-icon-3.png b/dojox/app/tests/images/i-icon-3.png
new file mode 100755
index 0000000..3450131
Binary files /dev/null and b/dojox/app/tests/images/i-icon-3.png differ
diff --git a/dojox/app/tests/images/i-icon-4.png b/dojox/app/tests/images/i-icon-4.png
new file mode 100755
index 0000000..403990b
Binary files /dev/null and b/dojox/app/tests/images/i-icon-4.png differ
diff --git a/dojox/app/tests/images/i-icon-5.png b/dojox/app/tests/images/i-icon-5.png
new file mode 100755
index 0000000..afd1199
Binary files /dev/null and b/dojox/app/tests/images/i-icon-5.png differ
diff --git a/dojox/app/tests/images/i-icon-6.png b/dojox/app/tests/images/i-icon-6.png
new file mode 100755
index 0000000..24d141b
Binary files /dev/null and b/dojox/app/tests/images/i-icon-6.png differ
diff --git a/dojox/app/tests/images/i-icon-7.png b/dojox/app/tests/images/i-icon-7.png
new file mode 100755
index 0000000..48b239f
Binary files /dev/null and b/dojox/app/tests/images/i-icon-7.png differ
diff --git a/dojox/app/tests/images/i-icon-8.png b/dojox/app/tests/images/i-icon-8.png
new file mode 100755
index 0000000..0880428
Binary files /dev/null and b/dojox/app/tests/images/i-icon-8.png differ
diff --git a/dojox/app/tests/images/i-icon-9.png b/dojox/app/tests/images/i-icon-9.png
new file mode 100755
index 0000000..e709a42
Binary files /dev/null and b/dojox/app/tests/images/i-icon-9.png differ
diff --git a/dojox/app/tests/images/i-icon-all.png b/dojox/app/tests/images/i-icon-all.png
new file mode 100755
index 0000000..d891dbd
Binary files /dev/null and b/dojox/app/tests/images/i-icon-all.png differ
diff --git a/dojox/app/tests/images/icon-1.png b/dojox/app/tests/images/icon-1.png
new file mode 100755
index 0000000..26dde5d
Binary files /dev/null and b/dojox/app/tests/images/icon-1.png differ
diff --git a/dojox/app/tests/images/not-images.png b/dojox/app/tests/images/not-images.png
new file mode 100755
index 0000000..7aee19a
Binary files /dev/null and b/dojox/app/tests/images/not-images.png differ
diff --git a/dojox/app/tests/images/pic1.jpg b/dojox/app/tests/images/pic1.jpg
new file mode 100644
index 0000000..a8ef25f
Binary files /dev/null and b/dojox/app/tests/images/pic1.jpg differ
diff --git a/dojox/app/tests/images/pic10.jpg b/dojox/app/tests/images/pic10.jpg
new file mode 100644
index 0000000..eed3321
Binary files /dev/null and b/dojox/app/tests/images/pic10.jpg differ
diff --git a/dojox/app/tests/images/pic2.jpg b/dojox/app/tests/images/pic2.jpg
new file mode 100644
index 0000000..5998cec
Binary files /dev/null and b/dojox/app/tests/images/pic2.jpg differ
diff --git a/dojox/app/tests/images/pic3.jpg b/dojox/app/tests/images/pic3.jpg
new file mode 100644
index 0000000..10c593b
Binary files /dev/null and b/dojox/app/tests/images/pic3.jpg differ
diff --git a/dojox/app/tests/images/pic4.jpg b/dojox/app/tests/images/pic4.jpg
new file mode 100644
index 0000000..7abbaa9
Binary files /dev/null and b/dojox/app/tests/images/pic4.jpg differ
diff --git a/dojox/app/tests/images/pic5.jpg b/dojox/app/tests/images/pic5.jpg
new file mode 100644
index 0000000..7c02ed7
Binary files /dev/null and b/dojox/app/tests/images/pic5.jpg differ
diff --git a/dojox/app/tests/images/pic6.jpg b/dojox/app/tests/images/pic6.jpg
new file mode 100644
index 0000000..a3045f2
Binary files /dev/null and b/dojox/app/tests/images/pic6.jpg differ
diff --git a/dojox/app/tests/images/pic7.jpg b/dojox/app/tests/images/pic7.jpg
new file mode 100644
index 0000000..c182569
Binary files /dev/null and b/dojox/app/tests/images/pic7.jpg differ
diff --git a/dojox/app/tests/images/pic8.jpg b/dojox/app/tests/images/pic8.jpg
new file mode 100644
index 0000000..d83c21d
Binary files /dev/null and b/dojox/app/tests/images/pic8.jpg differ
diff --git a/dojox/app/tests/images/pic9.jpg b/dojox/app/tests/images/pic9.jpg
new file mode 100644
index 0000000..663ae58
Binary files /dev/null and b/dojox/app/tests/images/pic9.jpg differ
diff --git a/dojox/app/tests/images/red-button-bg.png b/dojox/app/tests/images/red-button-bg.png
new file mode 100755
index 0000000..5749018
Binary files /dev/null and b/dojox/app/tests/images/red-button-bg.png differ
diff --git a/dojox/app/tests/images/red-button-sel-bg.png b/dojox/app/tests/images/red-button-sel-bg.png
new file mode 100755
index 0000000..c5ba62a
Binary files /dev/null and b/dojox/app/tests/images/red-button-sel-bg.png differ
diff --git a/dojox/app/tests/images/shell1.jpg b/dojox/app/tests/images/shell1.jpg
new file mode 100644
index 0000000..7f236d3
Binary files /dev/null and b/dojox/app/tests/images/shell1.jpg differ
diff --git a/dojox/app/tests/images/shell10.jpg b/dojox/app/tests/images/shell10.jpg
new file mode 100644
index 0000000..a4ddf98
Binary files /dev/null and b/dojox/app/tests/images/shell10.jpg differ
diff --git a/dojox/app/tests/images/shell11.jpg b/dojox/app/tests/images/shell11.jpg
new file mode 100644
index 0000000..ff212e5
Binary files /dev/null and b/dojox/app/tests/images/shell11.jpg differ
diff --git a/dojox/app/tests/images/shell2.jpg b/dojox/app/tests/images/shell2.jpg
new file mode 100644
index 0000000..8a13ade
Binary files /dev/null and b/dojox/app/tests/images/shell2.jpg differ
diff --git a/dojox/app/tests/images/shell3.jpg b/dojox/app/tests/images/shell3.jpg
new file mode 100644
index 0000000..7e88f8c
Binary files /dev/null and b/dojox/app/tests/images/shell3.jpg differ
diff --git a/dojox/app/tests/images/shell4.jpg b/dojox/app/tests/images/shell4.jpg
new file mode 100644
index 0000000..04e70d4
Binary files /dev/null and b/dojox/app/tests/images/shell4.jpg differ
diff --git a/dojox/app/tests/images/shell5.jpg b/dojox/app/tests/images/shell5.jpg
new file mode 100644
index 0000000..c252082
Binary files /dev/null and b/dojox/app/tests/images/shell5.jpg differ
diff --git a/dojox/app/tests/images/shell6.jpg b/dojox/app/tests/images/shell6.jpg
new file mode 100644
index 0000000..92a19eb
Binary files /dev/null and b/dojox/app/tests/images/shell6.jpg differ
diff --git a/dojox/app/tests/images/shell7.jpg b/dojox/app/tests/images/shell7.jpg
new file mode 100644
index 0000000..4750752
Binary files /dev/null and b/dojox/app/tests/images/shell7.jpg differ
diff --git a/dojox/app/tests/images/shell8.jpg b/dojox/app/tests/images/shell8.jpg
new file mode 100644
index 0000000..cc568f3
Binary files /dev/null and b/dojox/app/tests/images/shell8.jpg differ
diff --git a/dojox/app/tests/images/shell9.jpg b/dojox/app/tests/images/shell9.jpg
new file mode 100644
index 0000000..9b5b029
Binary files /dev/null and b/dojox/app/tests/images/shell9.jpg differ
diff --git a/dojox/app/tests/images/stone1.jpg b/dojox/app/tests/images/stone1.jpg
new file mode 100644
index 0000000..a012158
Binary files /dev/null and b/dojox/app/tests/images/stone1.jpg differ
diff --git a/dojox/app/tests/images/stone10.jpg b/dojox/app/tests/images/stone10.jpg
new file mode 100644
index 0000000..b25e375
Binary files /dev/null and b/dojox/app/tests/images/stone10.jpg differ
diff --git a/dojox/app/tests/images/stone2.jpg b/dojox/app/tests/images/stone2.jpg
new file mode 100644
index 0000000..596b64a
Binary files /dev/null and b/dojox/app/tests/images/stone2.jpg differ
diff --git a/dojox/app/tests/images/stone3.jpg b/dojox/app/tests/images/stone3.jpg
new file mode 100644
index 0000000..8c2424b
Binary files /dev/null and b/dojox/app/tests/images/stone3.jpg differ
diff --git a/dojox/app/tests/images/stone4.jpg b/dojox/app/tests/images/stone4.jpg
new file mode 100644
index 0000000..bab8eac
Binary files /dev/null and b/dojox/app/tests/images/stone4.jpg differ
diff --git a/dojox/app/tests/images/stone5.jpg b/dojox/app/tests/images/stone5.jpg
new file mode 100644
index 0000000..3a65c85
Binary files /dev/null and b/dojox/app/tests/images/stone5.jpg differ
diff --git a/dojox/app/tests/images/stone6.jpg b/dojox/app/tests/images/stone6.jpg
new file mode 100644
index 0000000..c1cd4aa
Binary files /dev/null and b/dojox/app/tests/images/stone6.jpg differ
diff --git a/dojox/app/tests/images/stone7.jpg b/dojox/app/tests/images/stone7.jpg
new file mode 100644
index 0000000..2d20a5f
Binary files /dev/null and b/dojox/app/tests/images/stone7.jpg differ
diff --git a/dojox/app/tests/images/stone8.jpg b/dojox/app/tests/images/stone8.jpg
new file mode 100644
index 0000000..03c2fe4
Binary files /dev/null and b/dojox/app/tests/images/stone8.jpg differ
diff --git a/dojox/app/tests/images/stone9.jpg b/dojox/app/tests/images/stone9.jpg
new file mode 100644
index 0000000..6b8d588
Binary files /dev/null and b/dojox/app/tests/images/stone9.jpg differ
diff --git a/dojox/app/tests/images/tab-icon-10.png b/dojox/app/tests/images/tab-icon-10.png
new file mode 100644
index 0000000..5266c1e
Binary files /dev/null and b/dojox/app/tests/images/tab-icon-10.png differ
diff --git a/dojox/app/tests/images/tab-icon-10h.png b/dojox/app/tests/images/tab-icon-10h.png
new file mode 100644
index 0000000..9b12683
Binary files /dev/null and b/dojox/app/tests/images/tab-icon-10h.png differ
diff --git a/dojox/app/tests/images/tab-icon-11.png b/dojox/app/tests/images/tab-icon-11.png
new file mode 100644
index 0000000..57740eb
Binary files /dev/null and b/dojox/app/tests/images/tab-icon-11.png differ
diff --git a/dojox/app/tests/images/tab-icon-11h.png b/dojox/app/tests/images/tab-icon-11h.png
new file mode 100644
index 0000000..0f3592d
Binary files /dev/null and b/dojox/app/tests/images/tab-icon-11h.png differ
diff --git a/dojox/app/tests/images/tab-icon-12.png b/dojox/app/tests/images/tab-icon-12.png
new file mode 100644
index 0000000..8b6dc5f
Binary files /dev/null and b/dojox/app/tests/images/tab-icon-12.png differ
diff --git a/dojox/app/tests/images/tab-icon-12h.png b/dojox/app/tests/images/tab-icon-12h.png
new file mode 100644
index 0000000..e230a38
Binary files /dev/null and b/dojox/app/tests/images/tab-icon-12h.png differ
diff --git a/dojox/app/tests/images/tab-icon-13.png b/dojox/app/tests/images/tab-icon-13.png
new file mode 100644
index 0000000..57f21cc
Binary files /dev/null and b/dojox/app/tests/images/tab-icon-13.png differ
diff --git a/dojox/app/tests/images/tab-icon-13h.png b/dojox/app/tests/images/tab-icon-13h.png
new file mode 100644
index 0000000..ec87db0
Binary files /dev/null and b/dojox/app/tests/images/tab-icon-13h.png differ
diff --git a/dojox/app/tests/images/tab-icon-14.png b/dojox/app/tests/images/tab-icon-14.png
new file mode 100644
index 0000000..cea484a
Binary files /dev/null and b/dojox/app/tests/images/tab-icon-14.png differ
diff --git a/dojox/app/tests/images/tab-icon-14h.png b/dojox/app/tests/images/tab-icon-14h.png
new file mode 100644
index 0000000..0e602c4
Binary files /dev/null and b/dojox/app/tests/images/tab-icon-14h.png differ
diff --git a/dojox/app/tests/images/tab-icon-15.png b/dojox/app/tests/images/tab-icon-15.png
new file mode 100644
index 0000000..09368cf
Binary files /dev/null and b/dojox/app/tests/images/tab-icon-15.png differ
diff --git a/dojox/app/tests/images/tab-icon-15h.png b/dojox/app/tests/images/tab-icon-15h.png
new file mode 100644
index 0000000..bd0daee
Binary files /dev/null and b/dojox/app/tests/images/tab-icon-15h.png differ
diff --git a/dojox/app/tests/images/tab-icon-16.png b/dojox/app/tests/images/tab-icon-16.png
new file mode 100644
index 0000000..ee58ce6
Binary files /dev/null and b/dojox/app/tests/images/tab-icon-16.png differ
diff --git a/dojox/app/tests/images/tab-icon-16h.png b/dojox/app/tests/images/tab-icon-16h.png
new file mode 100644
index 0000000..1ca2c06
Binary files /dev/null and b/dojox/app/tests/images/tab-icon-16h.png differ
diff --git a/dojox/app/tests/images/tab-icon-17.png b/dojox/app/tests/images/tab-icon-17.png
new file mode 100644
index 0000000..0387855
Binary files /dev/null and b/dojox/app/tests/images/tab-icon-17.png differ
diff --git a/dojox/app/tests/images/tab-icon-17h.png b/dojox/app/tests/images/tab-icon-17h.png
new file mode 100644
index 0000000..06c894e
Binary files /dev/null and b/dojox/app/tests/images/tab-icon-17h.png differ
diff --git a/dojox/app/tests/images/tab-icon-18.png b/dojox/app/tests/images/tab-icon-18.png
new file mode 100644
index 0000000..ac8fa6d
Binary files /dev/null and b/dojox/app/tests/images/tab-icon-18.png differ
diff --git a/dojox/app/tests/images/tab-icon-18h.png b/dojox/app/tests/images/tab-icon-18h.png
new file mode 100644
index 0000000..6fa5a1f
Binary files /dev/null and b/dojox/app/tests/images/tab-icon-18h.png differ
diff --git a/dojox/app/tests/images/tab-icons.png b/dojox/app/tests/images/tab-icons.png
new file mode 100644
index 0000000..93f50d0
Binary files /dev/null and b/dojox/app/tests/images/tab-icons.png differ
diff --git a/dojox/app/tests/images/welcomeLogo.png b/dojox/app/tests/images/welcomeLogo.png
new file mode 100644
index 0000000..42341e4
Binary files /dev/null and b/dojox/app/tests/images/welcomeLogo.png differ
diff --git a/dojox/app/tests/images/widget-bg.png b/dojox/app/tests/images/widget-bg.png
new file mode 100755
index 0000000..144dd00
Binary files /dev/null and b/dojox/app/tests/images/widget-bg.png differ
diff --git a/dojox/app/tests/modelApp/config.json b/dojox/app/tests/modelApp/config.json
new file mode 100644
index 0000000..e3d7383
--- /dev/null
+++ b/dojox/app/tests/modelApp/config.json
@@ -0,0 +1,97 @@
+{
+	"id": "modelApp",
+	"name": "Model App",
+	"description": "A modelApp",
+	"splash": "splash",
+
+	"dependencies": [
+		"dojox/mobile/_base",
+		"dojox/mobile/TabBar",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile/Button",
+		"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"
+	],
+	// 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"
+	],
+
+	//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": {
+	       "params":{
+		      "store": {"$ref":"#stores.namesStore"}
+		   }	       
+	   }
+	}, 
+
+	//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": { 
+			"type": "dojox.app.view",
+			"dependencies":["dojox/mobile/ListItem","dojox/mobile/RoundRectList","dojox/mobile/RoundRectCategory","dojox/mobile/Heading"],
+			"template": "views/main.html"
+		},
+
+		"simple":{
+			"type": "dojox.app.view",
+			"template": "views/simple.html",			
+			"dependencies":["dojox/mobile/TextBox"],
+		},
+
+		"repeat": {
+            "type": "dojox.app.view",
+            "models": {
+                "repeatmodels": {
+                    "params":{
+                        "store": {"$ref":"#stores.repeatStore"}
+                    }           
+                }
+            },
+            "template": "views/repeat.html",
+            "dependencies":["dojox/mobile/TextBox"],
+		},
+
+		"generate": {
+            "type": "dojox.app.view",
+            "template": "views/generate.html",
+            "dependencies":["dojox/mobile/TextBox", "dojox/mobile/TextArea", "dojox/mvc/Generate"],
+		}
+	}	
+}
diff --git a/dojox/app/tests/modelApp/index.html b/dojox/app/tests/modelApp/index.html
new file mode 100644
index 0000000..c2469fd
--- /dev/null
+++ b/dojox/app/tests/modelApp/index.html
@@ -0,0 +1,60 @@
+<!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>Model App Test</title> 
+		<link href="../../../mobile/themes/iphone/base.css" rel="stylesheet"></link>
+		<style>
+			html,body {
+				width: 100%;
+				height: 100%;
+				background: #eee;
+				font-family: arial;
+				color: #333;
+				overflow: hidden;
+				margin: 0px;
+				padding: 0px;
+				visibility: visible;
+			}
+
+			#splash {
+				width: 90%;
+				height: 90%;
+				margin: auto;
+				overflow: hidden;
+				border: 2px solid green;
+				font-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
+			}
+		</script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
+
+		<script>
+            console.log("post dojo");
+            // the actual  launcher
+            require(["./modelApp.js"], function(){});
+        </script>
+
+	</head>
+	<body>
+	</body>
+</html>
diff --git a/dojox/app/tests/modelApp/modelApp.js b/dojox/app/tests/modelApp/modelApp.js
new file mode 100644
index 0000000..78809ea
--- /dev/null
+++ b/dojox/app/tests/modelApp/modelApp.js
@@ -0,0 +1,98 @@
+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);
+
+    // 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/views/generate.html b/dojox/app/tests/modelApp/views/generate.html
new file mode 100644
index 0000000..738091e
--- /dev/null
+++ b/dojox/app/tests/modelApp/views/generate.html
@@ -0,0 +1,68 @@
+    <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
new file mode 100644
index 0000000..f81f51c
--- /dev/null
+++ b/dojox/app/tests/modelApp/views/main.html
@@ -0,0 +1,15 @@
+<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
new file mode 100644
index 0000000..28a238c
--- /dev/null
+++ b/dojox/app/tests/modelApp/views/repeat.html
@@ -0,0 +1,89 @@
+<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
new file mode 100644
index 0000000..bfe3b2c
--- /dev/null
+++ b/dojox/app/tests/modelApp/views/simple.html
@@ -0,0 +1,59 @@
+<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
new file mode 100644
index 0000000..dad92c8
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/application.html
@@ -0,0 +1,7 @@
+<div>
+	<ul region="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> 
+	</ul> 
+</div>
diff --git a/dojox/app/tests/multiSceneApp/config.json b/dojox/app/tests/multiSceneApp/config.json
new file mode 100644
index 0000000..609a379
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/config.json
@@ -0,0 +1,167 @@
+{
+	"id": "multiSceneApp",
+	"name": "Multi Scene App",
+	"description": "A multiSceneApp",
+	"splash": "splash",
+
+	"dependencies": [
+        "dojox/mobile/View", //Temporary work around for getting a null when calling getParent
+		"dojox/mobile/TabBar",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile/Button",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/Heading"
+	],
+	// Modules for the app.  The are basically used as the second
+	// array of mixins in a dojo.declare().  Modify the top level behavior
+	// 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/phonegap",
+		//"dojox/app/module/somePlugin"
+	],
+
+	//stores we are using 
+	"stores": {},
+
+	"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
+	"models": {}, 
+
+	//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": {
+
+		//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"
+		},
+
+		"main":{
+			//all views in the main scene will be bound to the user model
+			"models": [],
+			"type": "dojox.app.scene",
+			"template": "simple.html",	
+			"defaultView": "main",
+			"defaultTransition": "slide",
+			//the views available to this scene
+			"views": { 
+				"main":{
+					"template": "views/simple/main.html"
+				},
+				"second":{
+					"template": "views/simple/second.html" 
+				},
+				"third":{
+					"template": "views/simple/third.html" 
+				}
+			},
+			"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",	
+			"defaultView": "tab1",
+			"defaultTransition": "flip",
+			"type": "dojox.app.scene",
+			//the views available to this scene
+			"views": { 
+				"tab1":{
+					"template": "views/tabs/tab1.html" 
+				},
+				"tab2":{
+					"template": "views/tabs/tab2.html" 
+				},
+				"tab3":{
+					"template": "views/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"
+			]
+		}
+	}	
+}
diff --git a/dojox/app/tests/multiSceneApp/gallery.html b/dojox/app/tests/multiSceneApp/gallery.html
new file mode 100644
index 0000000..57d8d51
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/gallery.html
@@ -0,0 +1,3 @@
+<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
new file mode 100644
index 0000000..d7c0761
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/index.html
@@ -0,0 +1,77 @@
+<!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>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> 
+
+		<style>
+			html,body {
+				width: 100%;
+				height: 100%;
+				background: #eee;
+				font-family: arial;
+				color: #333;
+				overflow: hidden;
+				margin: 0px;
+				padding: 0px;
+				visibility: visible;
+			}
+
+			#splash {
+				width: 90%;
+				height: 90%;
+				margin: auto;
+				overflow: hidden;
+				border: 2px solid green;
+				font-color: #333;
+				text-align: center;
+			}
+
+			.mblListItemIcon {
+				top: 7px;
+				-webkit-transform: none;
+			}
+
+		</style>
+		<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
+				},
+				async:1
+			}
+			console.log("pre dojo");
+		</script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
+		<script>
+			console.log("post dojo");
+            // the actual  launcher
+            require(["./multiSceneApp.js"], function(){});
+		</script>
+		
+		<!--script type="text/javascript" src="multiSceneApp.js"></script-->
+	
+	</head>
+	<body>
+		<!-- <div style="width: 100%; height: 100%" id="app1"><div> -->
+	</body>
+</html>
diff --git a/dojox/app/tests/multiSceneApp/multiSceneApp.js b/dojox/app/tests/multiSceneApp/multiSceneApp.js
new file mode 100644
index 0000000..a8f4214
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/multiSceneApp.js
@@ -0,0 +1,15 @@
+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 + ")"));
+    });
+});
diff --git a/dojox/app/tests/multiSceneApp/simple.html b/dojox/app/tests/multiSceneApp/simple.html
new file mode 100644
index 0000000..4e97f2c
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/simple.html
@@ -0,0 +1,3 @@
+<div style="background:#c5ccd3;" class="view simpleView"> 
+	<h1 region="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
new file mode 100644
index 0000000..2d49dfb
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/tabScene.html
@@ -0,0 +1,8 @@
+<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>
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/ajax.html b/dojox/app/tests/multiSceneApp/views/gallery/ajax.html
new file mode 100644
index 0000000..61799df
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/gallery/ajax.html
@@ -0,0 +1,10 @@
+<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
new file mode 100644
index 0000000..8326af1
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/gallery/ajaxLoad.html
@@ -0,0 +1,7 @@
+<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
new file mode 100644
index 0000000..60c9e82
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/gallery/animations.html
@@ -0,0 +1,24 @@
+<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
new file mode 100644
index 0000000..2d5b1ac
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/gallery/buttonScene.html
@@ -0,0 +1,8 @@
+<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
new file mode 100644
index 0000000..453c2dd
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/gallery/buttons/tab1.html
@@ -0,0 +1,9 @@
+<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
new file mode 100644
index 0000000..e3dbd88
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/gallery/buttons/tab2.html
@@ -0,0 +1,8 @@
+<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
new file mode 100644
index 0000000..d205a80
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/gallery/buttons/tab3.html
@@ -0,0 +1,6 @@
+<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
new file mode 100644
index 0000000..ea1ddda
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/gallery/flippableViews.html
@@ -0,0 +1,19 @@
+<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
new file mode 100644
index 0000000..ac914a1
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/gallery/forms.html
@@ -0,0 +1,110 @@
+<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
new file mode 100644
index 0000000..9a59b1c
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/gallery/headings.html
@@ -0,0 +1,23 @@
+<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
new file mode 100644
index 0000000..5dc8b26
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/gallery/icons.html
@@ -0,0 +1,18 @@
+<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
new file mode 100644
index 0000000..95d0add
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/gallery/jsonp.html
@@ -0,0 +1,10 @@
+<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
new file mode 100644
index 0000000..76d3cdb
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/gallery/list.html
@@ -0,0 +1,143 @@
+<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
new file mode 100644
index 0000000..eb2f526
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/gallery/map.html
@@ -0,0 +1,5 @@
+<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
new file mode 100644
index 0000000..c2999b3
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/gallery/navigation.html
@@ -0,0 +1,51 @@
+<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
new file mode 100644
index 0000000..89b9b1c
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/gallery/rowTemplate.html
@@ -0,0 +1 @@
+<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
new file mode 100644
index 0000000..0812865
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/gallery/tabbar.html
@@ -0,0 +1,27 @@
+<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
new file mode 100644
index 0000000..b591b23
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/gallery/welcome.html
@@ -0,0 +1,5 @@
+<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/home.html b/dojox/app/tests/multiSceneApp/views/simple/home.html
new file mode 100644
index 0000000..5317179
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/simple/home.html
@@ -0,0 +1,5 @@
+<div style="background:#c5ccd3;width: 100%; height: 100%;"  class="view mblView"> 
+	<div dojoType="dojox.mobile.RoundRect" shadow="true">
+	  This is the content of the home scene. Hello World.
+	</div>
+</div>
diff --git a/dojox/app/tests/multiSceneApp/views/simple/main.html b/dojox/app/tests/multiSceneApp/views/simple/main.html
new file mode 100644
index 0000000..a8b1235
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/simple/main.html
@@ -0,0 +1,92 @@
+<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
new file mode 100644
index 0000000..08429f5
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/simple/second.html
@@ -0,0 +1,13 @@
+<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
new file mode 100644
index 0000000..7d84ff4
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/simple/third.html
@@ -0,0 +1,38 @@
+<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/multiSceneApp/views/tabs/tab1.html b/dojox/app/tests/multiSceneApp/views/tabs/tab1.html
new file mode 100644
index 0000000..6406d1f
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/tabs/tab1.html
@@ -0,0 +1,5 @@
+<div  style="background:#c5ccd3;" class="view mblView"> 
+	<div dojoType="dojox.mobile.RoundRect" shadow="true">
+		Tab 1 Contents.
+	</div>
+</div>
diff --git a/dojox/app/tests/multiSceneApp/views/tabs/tab2.html b/dojox/app/tests/multiSceneApp/views/tabs/tab2.html
new file mode 100644
index 0000000..3d6e1b1
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/tabs/tab2.html
@@ -0,0 +1,5 @@
+<div  style="background:#c5ccd3;" class="view mblView"> 
+	<div dojoType="dojox.mobile.RoundRect" shadow="true">
+		Tab 2 Contents
+	</div>
+</div>
diff --git a/dojox/app/tests/multiSceneApp/views/tabs/tab3.html b/dojox/app/tests/multiSceneApp/views/tabs/tab3.html
new file mode 100644
index 0000000..ed164e7
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/views/tabs/tab3.html
@@ -0,0 +1,5 @@
+<div  style="background:#c5ccd3;" class="view mblView"> 
+	<div dojoType="dojox.mobile.RoundRect" shadow="true">
+		Tab 3 Contents
+	</div>
+</div>
diff --git a/dojox/app/transition.js b/dojox/app/transition.js
new file mode 100644
index 0000000..39e2ed0
--- /dev/null
+++ b/dojox/app/transition.js
@@ -0,0 +1,60 @@
+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/view.js b/dojox/app/view.js
new file mode 100644
index 0000000..74202d4
--- /dev/null
+++ b/dojox/app/view.js
@@ -0,0 +1,15 @@
+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/atom/README b/dojox/atom/README
index 2e4936a..d5e447c 100644
--- a/dojox/atom/README
+++ b/dojox/atom/README
@@ -26,11 +26,11 @@ framework.
 Documentation:
 
 See the Dojo API tool (http://dojotoolkit.org/api)
-as well as dojocampus (http://docs.dojocampus.org/dojox/atom)
+as well as the reference guide (http://dojotoolkit.org/reference-guide/dojox/atom.html)
 -------------------------------------------------------------------------------
 Contributions:
 
-Constributions of documentation, examples, and fixes are always welcome.
+Contributions of documentation, examples, and fixes are always welcome.
 
 -------------------------------------------------------------------------------
 Installation instructions
diff --git a/dojox/atom/io/Connection.js b/dojox/atom/io/Connection.js
index 5ec6a9a..0eeb3bc 100755
--- a/dojox/atom/io/Connection.js
+++ b/dojox/atom/io/Connection.js
@@ -1,7 +1,10 @@
-dojo.provide('dojox.atom.io.Connection');
-dojo.require('dojox.atom.io.model');
-
-dojo.declare("dojox.atom.io.Connection",null,{
+define([
+	"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
@@ -37,7 +40,7 @@ dojo.declare("dojox.atom.io.Connection",null,{
 		//
 		//	returns:
 		//		Nothing. The return is handled through the callback handler.
-		this._getXmlDoc(url, "feed", new dojox.atom.io.model.Feed(), dojox.atom.io.model._Constants.ATOM_NS, callback, /*handleDocumentRetrieved,*/ errorCallback, scope);
+		this._getXmlDoc(url, "feed", new model.Feed(), model._Constants.ATOM_NS, callback, /*handleDocumentRetrieved,*/ errorCallback, scope);
 	},
 	
 	getService: function(url, callback, errorCallback, scope){
@@ -57,7 +60,7 @@ dojo.declare("dojox.atom.io.Connection",null,{
 		//
 		//	returns:
 		//		Nothing. The return is handled through the callback handler.
-		this._getXmlDoc(url, "service", new dojox.atom.io.model.Service(url), dojox.atom.io.model._Constants.APP_NS, callback, errorCallback, scope);
+		this._getXmlDoc(url, "service", new model.Service(url), model._Constants.APP_NS, callback, errorCallback, scope);
 	},
 	
 	getEntry: function(url, callback, errorCallback, scope){
@@ -77,7 +80,7 @@ dojo.declare("dojox.atom.io.Connection",null,{
 		//
 		//	returns:
 		//		Nothing. The return is handled through the callback handler.
-		this._getXmlDoc(url, "entry", new dojox.atom.io.model.Entry(), dojox.atom.io.model._Constants.ATOM_NS, callback, errorCallback, scope);
+		this._getXmlDoc(url, "entry", new model.Entry(), model._Constants.ATOM_NS, callback, errorCallback, scope);
 	},
 
 	_getXmlDoc: function(url, nodeName, newNode, namespace, callback, errorCallback, scope){
@@ -98,7 +101,7 @@ dojo.declare("dojox.atom.io.Connection",null,{
 		//	returns:
 		//		Nothing. The return is handled through the callback handler.
 		if(!scope){
-			scope = dojo.global;
+			scope = windowUtil.global;
 		}
 		var ae = this.alertsEnabled;
 		var xhrArgs = {
@@ -167,7 +170,7 @@ dojo.declare("dojox.atom.io.Connection",null,{
 				throw new Error("The URL requested cannot be accessed");
 			};
 		}
-		dojo.xhrGet(xhrArgs);
+		xhrUtil.get(xhrArgs);
 	},
 
 	updateEntry: function(entry, callback, errorCallback, retrieveUpdated, xmethod, scope){
@@ -200,7 +203,7 @@ dojo.declare("dojox.atom.io.Connection",null,{
 		//	returns:
 		//		Nothing. The return is handled through the callback handler.
 		if(!scope){
-			scope = dojo.global;
+			scope = windowUtil.global;
 		}
 		entry.updated = new Date();
 		var url = entry.getEditHref();
@@ -261,10 +264,10 @@ dojo.declare("dojox.atom.io.Connection",null,{
 		if(xmethod){
 			xhrArgs.postData = entry.toString(true); //Set the content to send.
 			xhrArgs.headers = {"X-Method-Override": "PUT"};
-			dojo.rawXhrPost(xhrArgs);
+			xhrUtil.post(xhrArgs);
 		}else{
 			xhrArgs.putData = entry.toString(true); //Set the content to send.
-			var xhr = dojo.rawXhrPut(xhrArgs);
+			var xhr = xhrUtil.put(xhrArgs);
 		}
 	},
 
@@ -294,7 +297,7 @@ dojo.declare("dojox.atom.io.Connection",null,{
 		//	returns:
 		//		Nothing. The return is handled through the callback handler.
 		if(!scope){
-			scope = dojo.global;
+			scope = windowUtil.global;
 		}
 
 		entry.published = new Date();
@@ -361,7 +364,7 @@ dojo.declare("dojox.atom.io.Connection",null,{
 				throw new Error("The URL requested cannot be accessed");
 			};
 		}
-		dojo.rawXhrPost(xhrArgs);
+		xhrUtil.post(xhrArgs);
 	},
 
 	deleteEntry: function(entry,callback,errorCallback,xmethod,scope){
@@ -383,7 +386,7 @@ dojo.declare("dojox.atom.io.Connection",null,{
 		//	returns:
 		//		Nothing. The return is handled through the callback handler.
 		if(!scope){
-			scope = dojo.global;
+			scope = windowUtil.global;
 		}
 
 		var url = null;
@@ -424,9 +427,10 @@ dojo.declare("dojox.atom.io.Connection",null,{
 		}
 		if(xmethod){
 			xhrArgs.headers = {"X-Method-Override": "DELETE"};
-			dojo.xhrPost(xhrArgs);
+			dhxr.post(xhrArgs);
 		}else{
-			dojo.xhrDelete(xhrArgs);
+			xhrUtil.del(xhrArgs);
 		}
 	}
 });
+});
\ No newline at end of file
diff --git a/dojox/atom/io/model.js b/dojox/atom/io/model.js
index fe3e139..4f375f9 100644
--- a/dojox/atom/io/model.js
+++ b/dojox/atom/io/model.js
@@ -1,10 +1,14 @@
-dojo.provide("dojox.atom.io.model");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare", // dojo.declare
+	 "dojo/_base/lang",
+	"dojo/date/stamp",
+	"dojox/xml/parser"
+], function (dojo, declare, lang, stamp, parser) {
 
-dojo.require("dojox.xml.parser");
-dojo.require("dojo.string");
-dojo.require("dojo.date.stamp");
+var model = dojo.getObject("dojox.atom.io.model", true);
 
-dojox.atom.io.model._Constants = {
+model._Constants = {
 	//	summary:
 	//		Container for general constants.
 	//	description:
@@ -15,7 +19,7 @@ dojox.atom.io.model._Constants = {
 	"APP_NS": "http://www.w3.org/2007/app"
 };
 
-dojox.atom.io.model._actions = {
+model._actions = {
 	//	summary:
 	//		Container for tag handling functions.
 	//	description:
@@ -27,95 +31,95 @@ dojox.atom.io.model._actions = {
 	//		  The dom node containing the data
 	"link": function(obj,node){
 		if(obj.links === null){obj.links = [];}
-		var link = new dojox.atom.io.model.Link();
+		var link = new model.Link();
 		link.buildFromDom(node);
 		obj.links.push(link);
 	},
 	"author": function(obj,node){
 		if(obj.authors === null){obj.authors = [];}
-		var person = new dojox.atom.io.model.Person("author");
+		var person = new model.Person("author");
 		person.buildFromDom(node);
 		obj.authors.push(person);
 	},
 	"contributor": function(obj,node){
 		if(obj.contributors === null){obj.contributors = [];}
-		var person = new dojox.atom.io.model.Person("contributor");
+		var person = new model.Person("contributor");
 		person.buildFromDom(node);
 		obj.contributors.push(person);
 	},
 	"category": function(obj,node){
 		if(obj.categories === null){obj.categories = [];}
-		var cat = new dojox.atom.io.model.Category();
+		var cat = new model.Category();
 		cat.buildFromDom(node);
 		obj.categories.push(cat);
 	},
 	"icon": function(obj,node){
-		obj.icon = dojox.xml.parser.textContent(node);
+		obj.icon = parser.textContent(node);
 	},
 	"id": function(obj,node){
-		obj.id = dojox.xml.parser.textContent(node);
+		obj.id = parser.textContent(node);
 	},
 	"rights": function(obj,node){
-		obj.rights = dojox.xml.parser.textContent(node);
+		obj.rights = parser.textContent(node);
 	},
 	"subtitle": function(obj,node){
-		var cnt = new dojox.atom.io.model.Content("subtitle");
+		var cnt = new model.Content("subtitle");
 		cnt.buildFromDom(node);
 		obj.subtitle = cnt;
 	},
 	"title": function(obj,node){
-		var cnt = new dojox.atom.io.model.Content("title");
+		var cnt = new model.Content("title");
 		cnt.buildFromDom(node);
 		obj.title = cnt;
 	},
 	"updated": function(obj,node){
-		obj.updated = dojox.atom.io.model.util.createDate(node);
+		obj.updated = model.util.createDate(node);
 	},
 	// Google news
 	"issued": function(obj,node){
-		obj.issued = dojox.atom.io.model.util.createDate(node);
+		obj.issued = model.util.createDate(node);
 	},
 	// Google news
 	"modified": function(obj,node){
-		obj.modified = dojox.atom.io.model.util.createDate(node);
+		obj.modified = model.util.createDate(node);
 	},
 	"published": function(obj,node){
-		obj.published = dojox.atom.io.model.util.createDate(node);
+		obj.published = model.util.createDate(node);
 	},
 	"entry": function(obj,node){
 		if(obj.entries === null){obj.entries = [];}
 		//The object passed in should be a Feed object, since only feeds can contain Entries
-		var entry = obj.createEntry ? obj.createEntry() : new dojox.atom.io.model.Entry();
+		var entry = obj.createEntry ? obj.createEntry() : new model.Entry();
 		entry.buildFromDom(node);
 		obj.entries.push(entry);
 	},
 	"content": function(obj, node){
-		var cnt = new dojox.atom.io.model.Content("content");
+		var cnt = new model.Content("content");
 		cnt.buildFromDom(node);
 		obj.content = cnt;
 	},
 	"summary": function(obj, node){
-		var summary = new dojox.atom.io.model.Content("summary");
+		var summary = new model.Content("summary");
 		summary.buildFromDom(node);
 		obj.summary = summary;
 	},
 
 	"name": function(obj,node){
-		obj.name = dojox.xml.parser.textContent(node);
+		obj.name = parser.textContent(node);
 	},
 	"email" : function(obj,node){
-		obj.email = dojox.xml.parser.textContent(node);
+		obj.email = parser.textContent(node);
 	},
 	"uri" : function(obj,node){
-		obj.uri = dojox.xml.parser.textContent(node);
+		obj.uri = parser.textContent(node);
 	},
 	"generator" : function(obj,node){
-		obj.generator = new dojox.atom.io.model.Generator();
+		obj.generator = new model.Generator();
 		obj.generator.buildFromDom(node);
 	}
 };
 
-dojox.atom.io.model.util = {
+model.util = {
 	createDate: function(/*DOM node*/node){
 		//	summary:
 		//		Utility function to create a date from a DOM node's text content.
@@ -126,9 +130,9 @@ dojox.atom.io.model.util = {
 		//		The DOM node to inspect.
 		//	returns:
 		//		Date object from a DOM Node containing a ISO-8610 string.
-		var textContent = dojox.xml.parser.textContent(node);
+		var textContent = parser.textContent(node);
 		if(textContent){
-			return dojo.date.stamp.fromISOString(dojo.trim(textContent));
+			return stamp.fromISOString(lang.trim(textContent));
 		}
 		return null;
 	},
@@ -185,7 +189,7 @@ dojox.atom.io.model.util = {
 	}
 };
 
-dojo.declare('dojox.atom.io.model.Node', null, {
+model.Node = dojo.declare(/*===== 'dojox.atom.io.model.Node', =====*/ null, {
 	constructor: function(name_space,name, attributes,content, shortNs){
 		this.name_space = name_space;
 		this.name = name;
@@ -201,24 +205,25 @@ dojo.declare('dojox.atom.io.model.Node', null, {
 		}
 		this.shortNs = shortNs;
 		this._objName = "Node";//for debugging purposes
+		this.nodeType = "Node";
 	},
 	buildFromDom: function(node){
 		this._saveAttributes(node);
 		this.name_space = node.namespaceURI;
 		this.shortNs = node.prefix;
-		this.name = dojox.atom.io.model.util.getNodename(node);
+		this.name = model.util.getNodename(node);
 		for(var x=0; x < node.childNodes.length; x++){
 			var c = node.childNodes[x];
-			if(dojox.atom.io.model.util.getNodename(c) != "#text" ){
+			if(model.util.getNodename(c) != "#text" ){
 				this.rawNodes.push(c);
-				var n = new dojox.atom.io.model.Node();
+				var n = new model.Node();
 				n.buildFromDom(c, true);
 				this.content.push(n);
 			}else{
 				this.content.push(c.nodeValue);
 			}
 		}
-		this.textContent = dojox.xml.parser.textContent(node);
+		this.textContent = parser.textContent(node);
 	},
 	_saveAttributes: function(node){
 		if(!this.attributes){this.attributes = [];}
@@ -292,9 +297,9 @@ 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
-dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
+model.AtomItem = dojo.declare(/*===== "dojox.atom.io.model.AtomItem", =====*/ model.Node,{
 	 constructor: function(args){
-		this.ATOM_URI = dojox.atom.io.model._Constants.ATOM_URI;
+		this.ATOM_URI = model._Constants.ATOM_URI;
 		this.links = null;						//Array of Link
 		this.authors = null;					//Array of Person
 		this.categories = null;					//Array of Category
@@ -309,6 +314,7 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 		this.entries = null;					//Array of Entry
 		this.name_spaces = {};
 		this._objName = "AtomItem";			 //for debugging purposes
+		this.nodeType = "AtomItem";
 	},
 	// summary: Class container for generic Atom items.
 	// description: Class container for generic Atom items.
@@ -320,7 +326,7 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 		var i, c, n;
 		for(i=0; i<node.attributes.length; i++){
 			c = node.attributes.item(i);
-			n = dojox.atom.io.model.util.getNodename(c);
+			n = model.util.getNodename(c);
 			if(c.prefix == "xmlns" && c.prefix != n){
 				this.addNamespace(c.nodeValue, n);
 			}
@@ -328,18 +334,18 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 		c = node.childNodes;
 		for(i = 0; i< c.length; i++){
 			if(c[i].nodeType == 1) {
-				var name = dojox.atom.io.model.util.getNodename(c[i]);
+				var name = model.util.getNodename(c[i]);
 				if(!name){continue;}
-				if(c[i].namespaceURI != dojox.atom.io.model._Constants.ATOM_NS && name != "#text"){
+				if(c[i].namespaceURI != model._Constants.ATOM_NS && name != "#text"){
 					if(!this.extensions){this.extensions = [];}
-					var extensionNode = new dojox.atom.io.model.Node();
+					var extensionNode = new model.Node();
 					extensionNode.buildFromDom(c[i]);
 					this.extensions.push(extensionNode);
 				}
 				if(!this.accept(name.toLowerCase())){
 					continue;
 				}
-				var fn = dojox.atom.io.model._actions[name];
+				var fn = model._actions[name];
 				if(fn) {
 					fn(this,c[i]);
 				}
@@ -366,7 +372,7 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 		//	uri:
 		//		A URI associated with the author.
 		if(!this.authors){this.authors = [];}
-		this.authors.push(new dojox.atom.io.model.Person("author",name,email,uri));
+		this.authors.push(new model.Person("author",name,email,uri));
 	},
 	addContributor: function(/*String*/name, /*String*/email, /*String*/uri){
 		//	summary:
@@ -381,7 +387,7 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 		//	uri:
 		//		A URI associated with the author.
 		if(!this.contributors){this.contributors = [];}
-		this.contributors.push(new dojox.atom.io.model.Person("contributor",name,email,uri));
+		this.contributors.push(new model.Person("contributor",name,email,uri));
 	},
 	addLink: function(/*String*/href,/*String*/rel,/*String*/hrefLang,/*String*/title,/*String*/type){
 		//	summary:
@@ -400,7 +406,7 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 		//	type:
 		//		The type of link is is.
 		if(!this.links){this.links=[];}
-		this.links.push(new dojox.atom.io.model.Link(href,rel,hrefLang,title,type));
+		this.links.push(new model.Link(href,rel,hrefLang,title,type));
 	},
 	removeLink: function(/*String*/href, /*String*/rel){
 		//	summary:
@@ -412,7 +418,7 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 		//		The href.
 		//	rel:
 		//		String
-		if(!this.links || !dojo.isArray(this.links)){return;}
+		if(!this.links || !lang.isArray(this.links)){return;}
 		var count = 0;
 		for(var i = 0; i < this.links.length; i++){
 			if((!href || this.links[i].href === href) && (!rel || this.links[i].rel === rel)){
@@ -446,7 +452,7 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 		//	label:
 		//		String
 		if(!this.categories){this.categories = [];}
-		this.categories.push(new dojox.atom.io.model.Category(scheme,term,label));
+		this.categories.push(new model.Category(scheme,term,label));
 	},
 	getCategories: function(/*String*/scheme){
 		//	summary:
@@ -495,7 +501,7 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 		//	type:
 		//		The type of title format, text, xml, xhtml, etc.
 		if(!str){return;}
-		this.title = new dojox.atom.io.model.Content("title");
+		this.title = new model.Content("title");
 		this.title.value = str;
 		if(type){this.title.type = type;}
 	},
@@ -514,7 +520,7 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 		//	content:
 		//		The content of the extension.
 		if(!this.extensions){this.extensions=[];}
-		this.extensions.push(new dojox.atom.io.model.Node(name_space,name,attributes,content, shortNS || "ns"+this.extensions.length));
+		this.extensions.push(new model.Node(name_space,name,attributes,content, shortNS || "ns"+this.extensions.length));
 	},
 	getExtensions: function(/*String*/name_space, /*String*/name){
 		//	summary:
@@ -569,7 +575,7 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 	}
 });
 
-dojo.declare("dojox.atom.io.model.Category",dojox.atom.io.model.Node,{
+model.Category = dojo.declare(/*===== "dojox.atom.io.model.Category", =====*/ model.Node,{
 	//	summary:
 	//		Class container for 'Category' types.
 	//	description:
@@ -577,6 +583,7 @@ dojo.declare("dojox.atom.io.model.Category",dojox.atom.io.model.Node,{
 	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";
 	},
 	_postBuild: function(){},
 	_getAttributeNames: function(){
@@ -611,7 +618,7 @@ dojo.declare("dojox.atom.io.model.Category",dojox.atom.io.model.Node,{
 	}
 });
 
-dojo.declare("dojox.atom.io.model.Content",dojox.atom.io.model.Node,{
+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:
@@ -620,6 +627,7 @@ dojo.declare("dojox.atom.io.model.Content",dojox.atom.io.model.Node,{
 		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";
 		this._useTextContent = "true";
+		this.nodeType = "Content";
 	},
 	_getAttributeNames: function(){return ["type","src"];},
 	_postBuild: function(){},
@@ -648,14 +656,14 @@ dojo.declare("dojox.atom.io.model.Content",dojox.atom.io.model.Node,{
 				for(i = 0; i < node.childNodes.length; i++){
 					var c = node.childNodes[i];
 					if(c){
-						this.value += dojox.xml.parser.innerXML(c);
+						this.value += parser.innerXML(c);
 					}
 				}
 			}
 		} else if(node.innerHTML){
 			this.value = node.innerHTML;
 		}else{
-			this.value = dojox.xml.parser.textContent(node);
+			this.value = parser.textContent(node);
 		}
 
 		this._saveAttributes(node);
@@ -670,7 +678,7 @@ dojo.declare("dojox.atom.io.model.Content",dojox.atom.io.model.Node,{
 		//We need to unescape the HTML content here so that it can be displayed correctly when the value is fetched.
 		var lowerType = this.type.toLowerCase();
 		if(lowerType === "html" || lowerType === "text/html" || lowerType === "xhtml" || lowerType === "text/xhtml"){
-			this.value = this.value?dojox.atom.io.model.util.unEscapeHtml(this.value):"";
+			this.value = this.value?model.util.unEscapeHtml(this.value):"";
 		}
 
 		if(this._postBuild){this._postBuild();}
@@ -689,7 +697,7 @@ dojo.declare("dojox.atom.io.model.Content",dojox.atom.io.model.Node,{
 		
 		//all HTML must be escaped
 		if(this.type.toLowerCase() == this.HTML){
-			s.push('>'+dojox.atom.io.model.util.escapeHtml(this.value)+'</'+this.tagName+'>\n');
+			s.push('>'+model.util.escapeHtml(this.value)+'</'+this.tagName+'>\n');
 		}else{
 			s.push('>'+this.value+'</'+this.tagName+'>\n');
 		}
@@ -698,13 +706,14 @@ dojo.declare("dojox.atom.io.model.Content",dojox.atom.io.model.Node,{
 	}
 });
 
-dojo.declare("dojox.atom.io.model.Link",dojox.atom.io.model.Node,{
+model.Link = dojo.declare(/*===== "dojox.atom.io.model.Link", =====*/ model.Node,{
 	//	summary:
 	//		Class container for 'link' types.
 	//	description:
 	//		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";
 	},
 	_getAttributeNames: function(){return ["href","jrefLang","rel","title","type"];},
 	_postBuild: function(){},
@@ -741,7 +750,7 @@ dojo.declare("dojox.atom.io.model.Link",dojox.atom.io.model.Node,{
 	}
 });
 
-dojo.declare("dojox.atom.io.model.Person",dojox.atom.io.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:
@@ -757,6 +766,7 @@ dojo.declare("dojox.atom.io.model.Person",dojox.atom.io.model.Node,{
 		this.email = email || '';
 		this.uri = uri || '';
 		this._objName = "Person";//for debugging
+		this.nodeType = "Person";
 	},
 	_getAttributeNames: function(){return null;},
 	_postBuild: function(){},
@@ -771,20 +781,20 @@ dojo.declare("dojox.atom.io.model.Person",dojox.atom.io.model.Node,{
 		//		The DOM node to process for person data.
 		var c = node.childNodes;
 		for(var i = 0; i< c.length; i++){
-			var name = dojox.atom.io.model.util.getNodename(c[i]);
+			var name = model.util.getNodename(c[i]);
 			
 			if(!name){continue;}
 
-			if(c[i].namespaceURI != dojox.atom.io.model._Constants.ATOM_NS && name != "#text"){
+			if(c[i].namespaceURI != model._Constants.ATOM_NS && name != "#text"){
 				if(!this.extensions){this.extensions = [];}
-				var extensionNode = new dojox.atom.io.model.Node();
+				var extensionNode = new model.Node();
 				extensionNode.buildFromDom(c[i]);
 				this.extensions.push(extensionNode);
 			}
 			if(!this.accept(name.toLowerCase())){
 				continue;
 			}
-			var fn = dojox.atom.io.model._actions[name];
+			var fn = model._actions[name];
 			if(fn) {
 				fn(this,c[i]);
 			}
@@ -812,7 +822,7 @@ dojo.declare("dojox.atom.io.model.Person",dojox.atom.io.model.Node,{
 	}
 });
 
-dojo.declare("dojox.atom.io.model.Generator",dojox.atom.io.model.Node,{
+model.Generator = dojo.declare(/*===== "dojox.atom.io.model.Generator", =====*/ model.Node,{
 	//	summary:
 	//		Class container for 'Generator' types.
 	//	description:
@@ -832,7 +842,7 @@ dojo.declare("dojox.atom.io.model.Generator",dojox.atom.io.model.Node,{
 		//	node:
 		//		The DOM node to process for link data.
 
-		this.value = dojox.xml.parser.textContent(node);
+		this.value = parser.textContent(node);
 		this._saveAttributes(node);
 
 		this.uri = this.attributes.uri;
@@ -855,7 +865,7 @@ dojo.declare("dojox.atom.io.model.Generator",dojox.atom.io.model.Node,{
 	}
 });
 
-dojo.declare("dojox.atom.io.model.Entry",dojox.atom.io.model.AtomItem,{
+model.Entry = dojo.declare(/*===== "dojox.atom.io.model.Entry", =====*/ model.AtomItem,{
 	//	summary:
 	//		Class container for 'Entry' types.
 	//	description:
@@ -890,23 +900,23 @@ dojo.declare("dojox.atom.io.model.Entry",dojox.atom.io.model.AtomItem,{
 		var i;
 		if(amPrimary){
 			s.push("<?xml version='1.0' encoding='UTF-8'?>");
-			s.push("<entry xmlns='"+dojox.atom.io.model._Constants.ATOM_URI+"'");
+			s.push("<entry xmlns='"+model._Constants.ATOM_URI+"'");
 		}else{s.push("<entry");}
 		if(this.xmlBase){s.push(' xml:base="'+this.xmlBase+'" ');}
 		for(i in this.name_spaces){s.push(' xmlns:'+i+'="'+this.name_spaces[i]+'"');}
 		s.push('>\n');
 		s.push('<id>' + (this.id ? this.id: '') + '</id>\n');
 		if(this.issued && !this.published){this.published = this.issued;}
-		if(this.published){s.push('<published>'+dojo.date.stamp.toISOString(this.published)+'</published>\n');}
-		if(this.created){s.push('<created>'+dojo.date.stamp.toISOString(this.created)+'</created>\n');}
+		if(this.published){s.push('<published>'+stamp.toISOString(this.published)+'</published>\n');}
+		if(this.created){s.push('<created>'+stamp.toISOString(this.created)+'</created>\n');}
 		//Google News
-		if(this.issued){s.push('<issued>'+dojo.date.stamp.toISOString(this.issued)+'</issued>\n');}
+		if(this.issued){s.push('<issued>'+stamp.toISOString(this.issued)+'</issued>\n');}
 
 		//Google News
-		if(this.modified){s.push('<modified>'+dojo.date.stamp.toISOString(this.modified)+'</modified>\n');}
+		if(this.modified){s.push('<modified>'+stamp.toISOString(this.modified)+'</modified>\n');}
 
 		if(this.modified && !this.updated){this.updated = this.modified;}
-		if(this.updated){s.push('<updated>'+dojo.date.stamp.toISOString(this.updated)+'</updated>\n');}
+		if(this.updated){s.push('<updated>'+stamp.toISOString(this.updated)+'</updated>\n');}
 		if(this.rights){s.push('<rights>'+this.rights+'</rights>\n');}
 		if(this.title){s.push(this.title.toString());}
 		if(this.summary){s.push(this.summary.toString());}
@@ -954,7 +964,7 @@ dojo.declare("dojox.atom.io.model.Entry",dojox.atom.io.model.AtomItem,{
 	}
 });
 
-dojo.declare("dojox.atom.io.model.Feed",dojox.atom.io.model.AtomItem,{
+model.Feed = dojo.declare(/*===== "dojox.atom.io.model.Feed", =====*/ model.AtomItem,{
 	//	summary:
 	//		Class container for 'Feed' types.
 	//	description:
@@ -1059,7 +1069,7 @@ dojo.declare("dojox.atom.io.model.Feed",dojox.atom.io.model.AtomItem,{
 		var s = [];
 		var i;
 		s.push('<?xml version="1.0" encoding="utf-8"?>\n');
-		s.push('<feed xmlns="'+dojox.atom.io.model._Constants.ATOM_URI+'"');
+		s.push('<feed xmlns="'+model._Constants.ATOM_URI+'"');
 		if(this.xmlBase){s.push(' xml:base="'+this.xmlBase+'"');}
 		for(i in this.name_spaces){s.push(' xmlns:'+i+'="'+this.name_spaces[i]+'"');}
 		s.push('>\n');
@@ -1069,12 +1079,12 @@ dojo.declare("dojox.atom.io.model.Feed",dojox.atom.io.model.AtomItem,{
 		if(this.rights){s.push('<rights>' + this.rights + '</rights>\n');}
 		
 		// Google news
-		if(this.issued){s.push('<issued>'+dojo.date.stamp.toISOString(this.issued)+'</issued>\n');}
-		if(this.modified){s.push('<modified>'+dojo.date.stamp.toISOString(this.modified)+'</modified>\n');}
+		if(this.issued){s.push('<issued>'+stamp.toISOString(this.issued)+'</issued>\n');}
+		if(this.modified){s.push('<modified>'+stamp.toISOString(this.modified)+'</modified>\n');}
 
 		if(this.modified && !this.updated){this.updated=this.modified;}
-		if(this.updated){s.push('<updated>'+dojo.date.stamp.toISOString(this.updated)+'</updated>\n');}
-		if(this.published){s.push('<published>'+dojo.date.stamp.toISOString(this.published)+'</published>\n');}
+		if(this.updated){s.push('<updated>'+stamp.toISOString(this.updated)+'</updated>\n');}
+		if(this.published){s.push('<published>'+stamp.toISOString(this.published)+'</published>\n');}
 		if(this.icon){s.push('<icon>'+this.icon+'</icon>\n');}
 		if(this.language){s.push('<language>'+this.language+'</language>\n');}
 		if(this.logo){s.push('<logo>'+this.logo+'</logo>\n');}
@@ -1099,7 +1109,7 @@ dojo.declare("dojox.atom.io.model.Feed",dojox.atom.io.model.AtomItem,{
 		//		Function to Create a new entry object in the feed.
 		//	returns:
 		//		An empty entry object in the feed.
-		var entry = new dojox.atom.io.model.Entry();
+		var entry = new model.Entry();
 		entry.feedUrl = this.getSelfHref();
 		return entry; //object
 	},
@@ -1122,7 +1132,7 @@ dojo.declare("dojox.atom.io.model.Feed",dojox.atom.io.model.AtomItem,{
 	}
 });
 
-dojo.declare("dojox.atom.io.model.Service",dojox.atom.io.model.AtomItem,{
+model.Service = dojo.declare(/*===== "dojox.atom.io.model.Service", =====*/ model.AtomItem,{
 	//	summary:
 	//		Class container for 'Feed' types.
 	//	description:
@@ -1149,7 +1159,7 @@ dojo.declare("dojox.atom.io.model.Service",dojox.atom.io.model.AtomItem,{
 			//if(!node){return;}
 			return;
 		}
-		if(node.namespaceURI != dojox.atom.io.model._Constants.PURL_NS && node.namespaceURI != dojox.atom.io.model._Constants.APP_NS){return;}
+		if(node.namespaceURI != model._Constants.PURL_NS && node.namespaceURI != model._Constants.APP_NS){return;}
 		var ns = node.namespaceURI;
 		this.name_space = node.namespaceURI;
 		//find all workspaces, and create them
@@ -1171,7 +1181,7 @@ dojo.declare("dojox.atom.io.model.Service",dojox.atom.io.model.AtomItem,{
 			var workspace;
 			for(i = 0; i< workspaces.length; i++){
 				workspace = (typeof(workspaces.item)==="undefined"?workspaces[i]:workspaces.item(i));
-				var wkspace = new dojox.atom.io.model.Workspace();
+				var wkspace = new model.Workspace();
 				wkspace.buildFromDom(workspace);
 				this.workspaces[wkLen++] = wkspace;
 			}
@@ -1197,7 +1207,7 @@ dojo.declare("dojox.atom.io.model.Service",dojox.atom.io.model.AtomItem,{
 	}
 });
 
-dojo.declare("dojox.atom.io.model.Workspace",dojox.atom.io.model.AtomItem,{
+model.Workspace = dojo.declare(/*===== "dojox.atom.io.model.Workspace", =====*/ model.AtomItem,{
 	//	summary:
 	//		Class container for 'Workspace' types.
 	//	description:
@@ -1215,23 +1225,23 @@ dojo.declare("dojox.atom.io.model.Workspace",dojox.atom.io.model.AtomItem,{
 		//
 		//	node:
 		//		The DOM node to process for content.
-		var name = dojox.atom.io.model.util.getNodename(node);
+		var name = model.util.getNodename(node);
 		if(name != "workspace"){return;}
 		var c = node.childNodes;
 		var len = 0;
 		for(var i = 0; i< c.length; i++){
 			var child = c[i];
 			if(child.nodeType === 1){
-				name = dojox.atom.io.model.util.getNodename(child);
-				if(child.namespaceURI == dojox.atom.io.model._Constants.PURL_NS || child.namespaceURI == dojox.atom.io.model._Constants.APP_NS){
+				name = model.util.getNodename(child);
+				if(child.namespaceURI == model._Constants.PURL_NS || child.namespaceURI == model._Constants.APP_NS){
 					if(name === "collection"){
-						var coll = new dojox.atom.io.model.Collection();
+						var coll = new model.Collection();
 						coll.buildFromDom(child);
 						this.collections[len++] = coll;
 					}
-				}else if(child.namespaceURI === dojox.atom.io.model._Constants.ATOM_NS){
+				}else if(child.namespaceURI === model._Constants.ATOM_NS){
 					if(name === "title"){
-						this.title = dojox.xml.parser.textContent(child);
+						this.title = parser.textContent(child);
 					}
 				}
 				//FIXME: Add an extension point so others can impl different namespaces.  For now just
@@ -1241,7 +1251,7 @@ dojo.declare("dojox.atom.io.model.Workspace",dojox.atom.io.model.AtomItem,{
 	}
 });
 
-dojo.declare("dojox.atom.io.model.Collection",dojox.atom.io.model.AtomItem,{
+model.Collection = dojo.declare(/*===== "dojox.atom.io.model.Collection", =====*/ model.AtomItem,{
 	//	summary:
 	//		Class container for 'Collection' types.
 	//	description:
@@ -1269,25 +1279,28 @@ dojo.declare("dojox.atom.io.model.Collection",dojox.atom.io.model.AtomItem,{
 		for(var i = 0; i< c.length; i++){
 			var child = c[i];
 			if(child.nodeType === 1){
-				var name = dojox.atom.io.model.util.getNodename(child);
-				if(child.namespaceURI == dojox.atom.io.model._Constants.PURL_NS || child.namespaceURI == dojox.atom.io.model._Constants.APP_NS){
+				var name = model.util.getNodename(child);
+				if(child.namespaceURI == model._Constants.PURL_NS || child.namespaceURI == model._Constants.APP_NS){
 					if(name === "member-type"){
-						this.memberType = dojox.xml.parser.textContent(child);
+						this.memberType = parser.textContent(child);
 					}else if(name == "feature"){//this IF stmt might need some more work
 						if(child.getAttribute("id")){this.features.push(child.getAttribute("id"));}
 					}else{
-						var unknownTypeChild = new dojox.atom.io.model.Node();
+						var unknownTypeChild = new model.Node();
 						unknownTypeChild.buildFromDom(child);
 						this.children.push(unknownTypeChild);
 					}
-				}else if(child.namespaceURI === dojox.atom.io.model._Constants.ATOM_NS){
+				}else if(child.namespaceURI === model._Constants.ATOM_NS){
 					if(name === "id"){
-						this.id = dojox.xml.parser.textContent(child);
+						this.id = parser.textContent(child);
 					}else if(name === "title"){
-						this.title = dojox.xml.parser.textContent(child);
+						this.title = parser.textContent(child);
 					}
 				}
 			}
 		}
 	}
 });
+
+return model;
+});
diff --git a/dojox/atom/widget/FeedEntryEditor.js b/dojox/atom/widget/FeedEntryEditor.js
index c96e579..6f04828 100644
--- a/dojox/atom/widget/FeedEntryEditor.js
+++ b/dojox/atom/widget/FeedEntryEditor.js
@@ -1,18 +1,32 @@
-dojo.provide("dojox.atom.widget.FeedEntryEditor");
-
-dojo.require("dojox.atom.widget.FeedEntryViewer");
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._Container");
-dojo.require("dijit.Editor");
-dojo.require("dijit.form.TextBox");
-dojo.require("dijit.form.SimpleTextarea");
-dojo.requireLocalization("dojox.atom.widget", "FeedEntryEditor");
-dojo.requireLocalization("dojox.atom.widget", "PeopleEditor");
-
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/connect",
+	"dojo/_base/fx",
+	"dojo/_base/sniff",
+	"dojo/dom",
+	"dojo/dom-style",
+	"dojo/dom-construct",
+	"dijit/_Widget",
+	"dijit/_Templated",
+	"dijit/_Container",
+	"dijit/Editor",
+	"dijit/form/TextBox",
+	"dijit/form/SimpleTextarea",
+	"./FeedEntryViewer",
+	"../io/model",
+	"dojo/text!./templates/FeedEntryEditor.html",
+	"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.experimental("dojox.atom.widget.FeedEntryEditor");
 
-dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryViewer,{
+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:
@@ -27,13 +41,13 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	_editable: false,		//Flag denoting if the current entry is editable or not.
 
 	//Templates for the HTML rendering.  Need to figure these out better, admittedly.
-	templateString: dojo.cache("dojox.atom", "widget/templates/FeedEntryEditor.html"),
+	templateString: template,
 
 	postCreate: function(){
 		if(this.entrySelectionTopic !== ""){
 			this._subscriptions = [dojo.subscribe(this.entrySelectionTopic, this, "_handleEvent")];
 		}
-		var _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedEntryViewer");
+		var _nlsResources = i18nViewer;
 		this.displayOptions.innerHTML = _nlsResources.displayOptions;
 		this.feedEntryCheckBoxLabelTitle.innerHTML = _nlsResources.title;
 		this.feedEntryCheckBoxLabelAuthors.innerHTML = _nlsResources.authors;
@@ -44,7 +58,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		this.feedEntryCheckBoxLabelSummary.innerHTML = _nlsResources.summary;
 		this.feedEntryCheckBoxLabelContent.innerHTML = _nlsResources.content;
 
-		_nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedEntryEditor");
+		_nlsResources = i18nEditor;
 		this.doNew.innerHTML = _nlsResources.doNew;
 		this.edit.innerHTML = _nlsResources.edit;
 		this.save.innerHTML = _nlsResources.save;
@@ -66,18 +80,18 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		}else{
 			leaveMenuState = true;
 		}
-		dojox.atom.widget.FeedEntryEditor.superclass.setEntry.call(this, entry, feed);
+		widget.FeedEntryEditor.superclass.setEntry.call(this, entry, feed);
 		this._editable = this._isEditable(entry);
 		if(!leaveMenuState && !this._editable){
-			dojo.style(this.entryEditButton, 'display', 'none');
-			dojo.style(this.entrySaveCancelButtons, 'display', 'none');
+			domStyle.set(this.entryEditButton, 'display', 'none');
+			domStyle.set(this.entrySaveCancelButtons, 'display', 'none');
 		}
 		if(this._editable && this.enableEdit){
 			if(!leaveMenuState){
-				dojo.style(this.entryEditButton, 'display', '');
+				domStyle.set(this.entryEditButton, 'display', '');
 				//TODO double check this &&...
 				if(this.enableMenuFade && this.entrySaveCancelButton){
-					dojo.fadeOut({node: this.entrySaveCancelButton,duration: 250}).play();
+					fx.fadeOut({node: this.entrySaveCancelButton,duration: 250}).play();
 				}
 			}
 		}
@@ -92,8 +106,8 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		//	returns:
 		//		Nothing.
 		if(this._editable && this.enableEdit){
-			dojo.style(this.entryEditButton, 'display', 'none');
-			dojo.style(this.entrySaveCancelButtons, 'display', '');
+			domStyle.set(this.entryEditButton, 'display', 'none');
+			domStyle.set(this.entrySaveCancelButtons, 'display', '');
 			this._editMode = true;
 
 			//Rebuild the view using the same entry and feed.
@@ -114,9 +128,9 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		//		Nothing.
 		if(entrySelectionEvent.source != this && entrySelectionEvent.action == "delete" &&
 			entrySelectionEvent.entry && entrySelectionEvent.entry == this._entry){
-				dojo.style(this.entryEditButton, 'display', 'none');
+				domStyle.set(this.entryEditButton, 'display', 'none');
 		}
-		dojox.atom.widget.FeedEntryEditor.superclass._handleEvent.call(this, entrySelectionEvent);
+		widget.FeedEntryEditor.superclass._handleEvent.call(this, entrySelectionEvent);
 	},
 
 	_isEditable: function(/*object*/entry){
@@ -160,7 +174,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		//		The Feed Entry to work with.
 		//
 		if(!editMode){
-			dojox.atom.widget.FeedEntryEditor.superclass.setTitle.call(this, titleAnchorNode, editMode, entry);
+			widget.FeedEntryEditor.superclass.setTitle.call(this, titleAnchorNode, editMode, entry);
 			if(entry.title && entry.title.value && entry.title.value !== null){
 				this.setFieldValidity("title", true);
 			}
@@ -194,7 +208,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		//	entry:
 		// 		The Feed Entry to work with.
 		if(!editMode){
-			dojox.atom.widget.FeedEntryEditor.superclass.setAuthors.call(this, authorsAnchorNode, editMode, entry);
+			widget.FeedEntryEditor.superclass.setAuthors.call(this, authorsAnchorNode, editMode, entry);
 			if(entry.authors && entry.authors.length > 0){
 				this.setFieldValidity("authors", true);
 			}
@@ -221,7 +235,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		//	entry:
 		//		The Feed Entry to work with.
 		if(!editMode){
-			dojox.atom.widget.FeedEntryEditor.superclass.setContributors.call(this, contributorsAnchorNode, editMode, entry);
+			widget.FeedEntryEditor.superclass.setContributors.call(this, contributorsAnchorNode, editMode, entry);
 			if(entry.contributors && entry.contributors.length > 0){
 				this.setFieldValidity("contributors", true);
 			}
@@ -248,7 +262,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		//	entry:
 		//		The Feed Entry to work with.
 		if(!editMode){
-			dojox.atom.widget.FeedEntryEditor.superclass.setId.call(this, idAnchorNode, editMode, entry);
+			widget.FeedEntryEditor.superclass.setId.call(this, idAnchorNode, editMode, entry);
 			if(entry.id && entry.id !== null){
 				this.setFieldValidity("id", true);
 			}
@@ -274,7 +288,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		//	entry:
 		//		The Feed Entry to work with.
 		if(!editMode){
-			dojox.atom.widget.FeedEntryEditor.superclass.setUpdated.call(this, updatedAnchorNode, editMode, entry);
+			widget.FeedEntryEditor.superclass.setUpdated.call(this, updatedAnchorNode, editMode, entry);
 			if(entry.updated && entry.updated !== null){
 				this.setFieldValidity("updated", true);
 			}
@@ -301,7 +315,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		//	entry:
 		//		The Feed Entry to work with.
 		if(!editMode){
-			dojox.atom.widget.FeedEntryEditor.superclass.setSummary.call(this, summaryAnchorNode, editMode, entry);
+			widget.FeedEntryEditor.superclass.setSummary.call(this, summaryAnchorNode, editMode, entry);
 			if(entry.summary && entry.summary.value && entry.summary.value !== null){
 				this.setFieldValidity("summary", true);
 			}
@@ -335,7 +349,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		// 	entry:
 		//		The Feed Entry to work with.
 		if(!editMode){
-			dojox.atom.widget.FeedEntryEditor.superclass.setContent.call(this, contentAnchorNode, editMode, entry);
+			widget.FeedEntryEditor.superclass.setContent.call(this, contentAnchorNode, editMode, entry);
 			if(entry.content && entry.content.value && entry.content.value !== null){
 				this.setFieldValidity("content",true);
 			}
@@ -390,7 +404,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 							var node = document.createElement("div");
 							node.innerHTML = this.entryValue;
 							this.anchorNode.appendChild(node);
-							var _editor = new dijit.Editor({}, node);
+							var _editor = new Editor({}, node);
 							this.editor = _editor;
 							return _editor;
 						}
@@ -400,14 +414,14 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 				// If multiline, create a textarea
 				viewNode = document.createElement("textarea");
 				anchorNode.appendChild(viewNode);
-				dojo.style(viewNode, 'width', '90%');
-				box = new dijit.form.SimpleTextarea({},viewNode);
+				domStyle.set(viewNode, 'width', '90%');
+				box = new SimpleTextarea({},viewNode);
 			}else{
 				// If single line, create a textbox.
 				viewNode = document.createElement("input");
 				anchorNode.appendChild(viewNode);
-				dojo.style(viewNode, 'width', '95%');
-				box = new dijit.form.TextBox({},viewNode);
+				domStyle.set(viewNode, 'width', '95%');
+				box = new TextBox({},viewNode);
 			}
 			box.attr('value', '');
 			return box;
@@ -438,7 +452,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 						var node = document.createElement("div");
 						node.innerHTML = this.entryValue;
 						this.anchorNode.appendChild(node);
-						var _editor = new dijit.Editor({}, node);
+						var _editor = new Editor({}, node);
 						this.editor = _editor;
 						return _editor;
 					}
@@ -448,14 +462,14 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 			// If multiline, create a textarea
 			viewNode = document.createElement("textarea");
 			anchorNode.appendChild(viewNode);
-			dojo.style(viewNode, 'width', '90%');
-			box = new dijit.form.SimpleTextarea({},viewNode);
+			domStyle.set(viewNode, 'width', '90%');
+			box = new SimpleTextarea({},viewNode);
 		}else{
 			// If single line, create a textbox.
 			viewNode = document.createElement("input");
 			anchorNode.appendChild(viewNode);
-			dojo.style(viewNode, 'width', '95%');
-			box = new dijit.form.TextBox({},viewNode);
+			domStyle.set(viewNode, 'width', '95%');
+			box = new TextBox({},viewNode);
 		}
 		box.attr('value', value);
 		return box;
@@ -475,7 +489,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		var parent = null;
 		
 		// Determine the source/target of this event (to determine which editor we're switching)
-		if(dojo.isIE){
+		if(has("ie")){
 			target = event.srcElement;
 		}else{
 			target = event.target;
@@ -499,29 +513,29 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		var value;
 		
 		if(target.value === "text"){
-			if(editor.declaredClass === "dijit.Editor"){
+			if(editor.isInstanceOf(Editor)){
 				// If we're changing the type to text and our existing editor is a rich text editor, we need to destroy
 				// it and switch to a multiline editor.
 				value = editor.attr('value', false);
 				editor.close(false,true);
 				editor.destroy();
 				while(parent.firstChild){
-					dojo.destroy(parent.firstChild);
+					domConstruct.destroy(parent.firstChild);
 				}
 				newEditor = this._createEditor(parent, {value: value}, true, false);
 				this._editors[type] = newEditor;
 			}
 		}else{
-			if(editor.declaredClass != "dijit.Editor"){
+			if(!editor.isInstanceOf(Editor)){
 				// Otherwise, we're switching to a html or xhtml type, but we currently have a textarea widget.  We need
 				// to destroy the existing RTE and create a multiline textarea widget.
 				value = editor.attr('value');
 				editor.destroy();
 				while(parent.firstChild){
-					dojo.destroy(parent.firstChild);
+					domConstruct.destroy(parent.firstChild);
 				}
 				newEditor = this._createEditor(parent, {value: value}, true, true);
-				newEditor = dojo.hitch(newEditor, newEditor.generateEditor)();
+				newEditor = lang.hitch(newEditor, newEditor.generateEditor)();
 				this._editors[type] = newEditor;
 			}
 		}
@@ -542,7 +556,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		// returns: A new People Editor object.
 		var viewNode = document.createElement("div");
 		anchorNode.appendChild(viewNode);
-		return new dojox.atom.widget.PeopleEditor(node,viewNode);
+		return new widget.PeopleEditor(node,viewNode);
 	},
 
 	saveEdits: function(){
@@ -555,9 +569,9 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		//
 		//	returns:
 		//		Nothing.
-		dojo.style(this.entrySaveCancelButtons, 'display', 'none');
-		dojo.style(this.entryEditButton, 'display', '');
-		dojo.style(this.entryNewButton, 'display', '');
+		domStyle.set(this.entrySaveCancelButtons, 'display', 'none');
+		domStyle.set(this.entryEditButton, 'display', '');
+		domStyle.set(this.entryNewButton, 'display', '');
 		var modifiedEntry = false;
 		var value;
 		var i;
@@ -575,7 +589,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 						value = '<div xmlns="http://www.w3.org/1999/xhtml">' + value + '</div>';
 					}
 				}
-				entry.title = new dojox.atom.io.model.Content("title", value, null, this.entryTitleSelect.value);
+				entry.title = new model.Content("title", value, null, this.entryTitleSelect.value);
 				modifiedEntry = true;
 			}
 			
@@ -592,7 +606,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 						value = '<div xmlns="http://www.w3.org/1999/xhtml">' + value + '</div>';
 					}
 				}
-				entry.summary = new dojox.atom.io.model.Content("summary", value, null, this.entrySummarySelect.value);
+				entry.summary = new model.Content("summary", value, null, this.entrySummarySelect.value);
 				modifiedEntry = true;
 			}
 			
@@ -604,7 +618,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 						value = '<div xmlns="http://www.w3.org/1999/xhtml">' + value + '</div>';
 					}
 				}
-				entry.content = new dojox.atom.io.model.Content("content", value, null, this.entryContentSelect.value);
+				entry.content = new model.Content("content", value, null, this.entryContentSelect.value);
 				modifiedEntry = true;
 			}
 			
@@ -697,7 +711,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 			}
 		}else{
 			this._new = false;
-			entry = new dojox.atom.io.model.Entry();
+			entry = new model.Entry();
 			
 			value = this._editors.title.attr('value');
 			if(this.entryTitleSelect.value === "xhtml"){
@@ -727,16 +741,16 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 				value = this._enforceXhtml(value);
 				value = '<div xmlns="http://www.w3.org/1999/xhtml">' + value + '</div>';
 			}
-			entry.summary = new dojox.atom.io.model.Content("summary", value, null, this.entrySummarySelect.value);
+			entry.summary = new model.Content("summary", value, null, this.entrySummarySelect.value);
 
 			value = this._editors.content.attr('value');
 			if(this.entryContentSelect.value === "xhtml"){
 				value = this._enforceXhtml(value);
 				value = '<div xmlns="http://www.w3.org/1999/xhtml">' + value + '</div>';
 			}
-			entry.content = new dojox.atom.io.model.Content("content", value, null, this.entryContentSelect.value);
+			entry.content = new model.Content("content", value, null, this.entryContentSelect.value);
 
-			dojo.style(this.entryNewButton, 'display', '');
+			domStyle.set(this.entryNewButton, 'display', '');
 			dojo.publish(this.entrySelectionTopic, [{action: "post", source: this, entry: entry }]);
 		}
 		this._editMode = false;
@@ -774,11 +788,11 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		//	returns:
 		//		Nothing.
 		this._new = false;
-		dojo.style(this.entrySaveCancelButtons, 'display', 'none');
+		domStyle.set(this.entrySaveCancelButtons, 'display', 'none');
 		if(this._editable){
-			dojo.style(this.entryEditButton, 'display', '');
+			domStyle.set(this.entryEditButton, 'display', '');
 		}
-		dojo.style(this.entryNewButton, 'display', '');
+		domStyle.set(this.entryNewButton, 'display', '');
 		this._editMode = false;
 		
 		//Rebuild the view using the same entry and feed.
@@ -793,7 +807,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		//		Clears the editor, destorys all editors, leaving the editor completely clear
 		this._editable=false;
 		this.clearEditors();
-		dojox.atom.widget.FeedEntryEditor.superclass.clear.apply(this);
+		widget.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.
@@ -804,7 +818,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	
 	clearEditors: function(){
 		for(var key in this._editors){
-			if(this._editors[key].declaredClass === "dijit.Editor"){
+			if(this._editors[key].isInstanceOf(Editor)){
 				this._editors[key].close(false, true);
 			}
 			this._editors[key].destroy();
@@ -886,9 +900,9 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		//		Function to put the editor into a state to create a new entry.
 		
 		// Hide the edit/new buttons and show the save/cancel buttons.
-		dojo.style(this.entryNewButton, 'display', 'none');
-		dojo.style(this.entryEditButton, 'display', 'none');
-		dojo.style(this.entrySaveCancelButtons, 'display', '');
+		domStyle.set(this.entryNewButton, 'display', 'none');
+		domStyle.set(this.entryEditButton, 'display', 'none');
+		domStyle.set(this.entrySaveCancelButtons, 'display', '');
 		
 		// Reset the type select boxes to text.
 		this.entrySummarySelect.value = "text";
@@ -899,46 +913,46 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		this.clearNodes();
 		this._new = true;
 		
-		var _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedEntryViewer");
+		var _nlsResources = i18nViewer;
 		// Create all headers and editors.
-		var titleHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.title});
+		var titleHeader = new widget.EntryHeader({title: _nlsResources.title});
 		this.entryTitleHeader.appendChild(titleHeader.domNode);
 		
 		this._editors.title = this._createEditor(this.entryTitleNode, null);
 		this.setFieldValidity("title",true);
 		
-		var authorHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.authors});
+		var authorHeader = new widget.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 dojox.atom.widget.EntryHeader({title: _nlsResources.contributors});
+		var contributorHeader = new widget.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 dojox.atom.widget.EntryHeader({title: _nlsResources.id});
+		var idHeader = new widget.EntryHeader({title: _nlsResources.id});
 		this.entryIdHeader.appendChild(idHeader.domNode);
 		
 		this._editors.id = this._createEditor(this.entryIdNode, null);
 		this.setFieldValidity("id",true);
 
-		var updatedHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.updated});
+		var updatedHeader = new widget.EntryHeader({title: _nlsResources.updated});
 		this.entryUpdatedHeader.appendChild(updatedHeader.domNode);
 		
 		this._editors.updated = this._createEditor(this.entryUpdatedNode, null);
 		this.setFieldValidity("updated",true);
 
-		var summaryHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.summary});
+		var summaryHeader = new widget.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 dojox.atom.widget.EntryHeader({title: _nlsResources.content});
+		var contentHeader = new widget.EntryHeader({title: _nlsResources.content});
 		this.entryContentHeader.appendChild(contentHeader.domNode);
 		
 		this._editors.content = this._createEditor(this.entryContentNode, null, true);
@@ -954,29 +968,29 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		// description: Function to display the appropriate sections based on validity.
 		
 		// Hide select boxes.
-		dojo.style(this.entrySummarySelect, 'display', 'none');
-		dojo.style(this.entryContentSelect, 'display', 'none');
-		dojo.style(this.entryTitleSelect, 'display', 'none');
+		domStyle.set(this.entrySummarySelect, 'display', 'none');
+		domStyle.set(this.entryContentSelect, 'display', 'none');
+		domStyle.set(this.entryTitleSelect, 'display', 'none');
 
 		// Show select boxes if the flags are set.
 		if(this.isFieldValid("contentedit")){
-			dojo.style(this.entryContentSelect, 'display', '');
+			domStyle.set(this.entryContentSelect, 'display', '');
 		}
 		if(this.isFieldValid("summaryedit")){
-			dojo.style(this.entrySummarySelect, 'display', '');
+			domStyle.set(this.entrySummarySelect, 'display', '');
 		}
 		if(this.isFieldValid("titleedit")){
-			dojo.style(this.entryTitleSelect, 'display', '');
+			domStyle.set(this.entryTitleSelect, 'display', '');
 		}
 		// Call super's _displaySections.
-		dojox.atom.widget.FeedEntryEditor.superclass._displaySections.apply(this);
+		widget.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){
 			for(var i in this._toLoad){
 				var editor;
 				if(this._toLoad[i].generateEditor){
-					editor = dojo.hitch(this._toLoad[i], this._toLoad[i].generateEditor)();
+					editor = lang.hitch(this._toLoad[i], this._toLoad[i].generateEditor)();
 				}else{
 					editor = this._toLoad[i];
 				}
@@ -988,13 +1002,13 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	}
 });
 
-dojo.declare("dojox.atom.widget.PeopleEditor",[dijit._Widget, dijit._Templated, dijit._Container],{
+widget.PeopleEditor = dojo.declare(/*===== "dojox.atom.widget.PeopleEditor", =====*/ [_Widget, _Templated, _Container],{
 		//	summary:
 		//		An editor for dojox.atom.io.model.Person objects.
 		//	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: dojo.cache("dojox.atom", "widget/templates/PeopleEditor.html"),
+		templateString: peopleEditorTemplate,
 
 		_rows: [],
 		_editors: [],
@@ -1003,7 +1017,7 @@ dojo.declare("dojox.atom.widget.PeopleEditor",[dijit._Widget, dijit._Templated,
 		
 		postCreate: function(){
 			// Initializer function for the PeopleEditor widget.
-			var _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "PeopleEditor");
+			var _nlsResources = i18nPeople;
 			if(this.name){
 				if(this.name == "Author"){
 					this.peopleEditorButton.appendChild(document.createTextNode("["+_nlsResources.addAuthor+"]"));
@@ -1068,8 +1082,8 @@ dojo.declare("dojox.atom.widget.PeopleEditor",[dijit._Widget, dijit._Templated,
 			row = document.createElement("span");
 			node.appendChild(row);
 			row.className = "peopleEditorButton";
-			dojo.style(row, 'font-size', 'x-small');
-			dojo.connect(row, "onclick", this, "_removeEditor");
+			domStyle.set(row, 'font-size', 'x-small');
+			connect.connect(row, "onclick", this, "_removeEditor");
 			row.id = "remove"+index;
 			
 			node = document.createTextNode("[X]");
@@ -1081,21 +1095,21 @@ dojo.declare("dojox.atom.widget.PeopleEditor",[dijit._Widget, dijit._Templated,
 			
 			var labelNode = document.createElement("td");
 			row.appendChild(labelNode);
-			dojo.style(labelNode, 'width', '20%');
+			domStyle.set(labelNode, 'width', '20%');
 			
 			node = document.createElement("td");
 			row.appendChild(node);
 			
 			row = document.createElement("table");
 			labelNode.appendChild(row);
-			dojo.style(row, 'width', '100%');
+			domStyle.set(row, 'width', '100%');
 			
 			labelNode = document.createElement("tbody");
 			row.appendChild(labelNode);
 			
 			row = document.createElement("table");
 			node.appendChild(row);
-			dojo.style(row, 'width', '100%');
+			domStyle.set(row, 'width', '100%');
 			
 			node = document.createElement("tbody");
 			row.appendChild(node);
@@ -1144,9 +1158,9 @@ dojo.declare("dojox.atom.widget.PeopleEditor",[dijit._Widget, dijit._Templated,
 			var viewNode = document.createElement("input");
 			viewNode.setAttribute('id', id);
 			node.appendChild(viewNode);
-			dojo.style(viewNode, 'width', '95%');
+			domStyle.set(viewNode, 'width', '95%');
 			
-			var box = new dijit.form.TextBox({},viewNode);
+			var box = new TextBox({},viewNode);
 			box.attr('value', value);
 			return box;
 		},
@@ -1162,7 +1176,7 @@ dojo.declare("dojox.atom.widget.PeopleEditor",[dijit._Widget, dijit._Templated,
 			//		The event generated when the remove button is pressed on the page.
 			var target = null;
 		
-			if(dojo.isIE){
+			if(has("ie")){
 				target = event.srcElement;
 			}else{
 				target = event.target;
@@ -1174,11 +1188,11 @@ dojo.declare("dojox.atom.widget.PeopleEditor",[dijit._Widget, dijit._Templated,
 				this._editors[id][key].destroy();
 			}
 			
-			var node = dojo.byId("editorsRow"+id);
+			var node = domUtil.byId("editorsRow"+id);
 			var parent = node.parentNode;
 			parent.removeChild(node);
 			
-			node = dojo.byId("removeRow"+id);
+			node = domUtil.byId("removeRow"+id);
 			parent = node.parentNode;
 			parent.removeChild(node);
 
@@ -1217,3 +1231,5 @@ dojo.declare("dojox.atom.widget.PeopleEditor",[dijit._Widget, dijit._Templated,
 			return values;
 		}
 });
+return widget.FeedEntryEditor;
+});
diff --git a/dojox/atom/widget/FeedEntryViewer.js b/dojox/atom/widget/FeedEntryViewer.js
index 6a3656d..d3c98f5 100644
--- a/dojox/atom/widget/FeedEntryViewer.js
+++ b/dojox/atom/widget/FeedEntryViewer.js
@@ -1,16 +1,26 @@
-dojo.provide("dojox.atom.widget.FeedEntryViewer");
-
-dojo.require("dojo.fx");
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._Container");
-dojo.require("dijit.layout.ContentPane");
-dojo.require("dojox.atom.io.Connection");
-dojo.requireLocalization("dojox.atom.widget", "FeedEntryViewer");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/_base/fx",
+	"dojo/_base/array",
+	"dojo/dom-style",
+	"dojo/dom-construct",
+	"dijit/_Widget",
+	"dijit/_Templated",
+	"dijit/_Container",
+	"dijit/layout/ContentPane",
+	"../io/Connection",
+	"dojo/text!./templates/FeedEntryViewer.html",
+	"dojo/text!./templates/EntryHeader.html",
+	"dojo/i18n!./nls/FeedEntryViewer"
+], function (dojo, connect, declare, fx, arrayUtil, domStyle, domConstruct, _Widget, _Templated, _Container, ContentPane, Connection, template, headerTemplate, i18nViewer) {
 
 dojo.experimental("dojox.atom.widget.FeedEntryViewer");
 
-dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Templated, dijit._Container],{
+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:
@@ -28,7 +38,7 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 	_optionButtonDisplayed: true,
 
 	//Templates for the HTML rendering.  Need to figure these out better, admittedly.
-	templateString: dojo.cache("dojox.atom", "widget/templates/FeedEntryViewer.html"),
+	templateString: template,
 	
 	_entry: null, //The entry that is being viewed/edited.
 	_feed: null, //The feed the entry came from.
@@ -39,7 +49,7 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 		if(this.entrySelectionTopic !== ""){
 			this._subscriptions = [dojo.subscribe(this.entrySelectionTopic, this, "_handleEvent")];
 		}
-		var _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedEntryViewer");
+		var _nlsResources = i18nViewer;
 		this.displayOptions.innerHTML = _nlsResources.displayOptions;
 		this.feedEntryCheckBoxLabelTitle.innerHTML = _nlsResources.title;
 		this.feedEntryCheckBoxLabelAuthors.innerHTML = _nlsResources.authors;
@@ -60,11 +70,11 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 		this._setDisplaySectionsCheckboxes();
 
 		if(this.enableMenu){
-			dojo.style(this.feedEntryViewerMenu, 'display', '');
+			domStyle.set(this.feedEntryViewerMenu, 'display', '');
 			if(this.entryCheckBoxRow && this.entryCheckBoxRow2){
 				if(this.enableMenuFade){
-					dojo.fadeOut({node: this.entryCheckBoxRow,duration: 250}).play();
-					dojo.fadeOut({node: this.entryCheckBoxRow2,duration: 250}).play();
+					fx.fadeOut({node: this.entryCheckBoxRow,duration: 250}).play();
+					fx.fadeOut({node: this.entryCheckBoxRow2,duration: 250}).play();
 				}
 			}
 		}
@@ -87,20 +97,20 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 		//	description:
 		//		Function to clear all the display nodes for the ATOM entry from the viewer.
 
-		dojo.forEach([
+		arrayUtil.forEach([
 			"entryTitleRow", "entryAuthorRow", "entryContributorRow", "entrySummaryRow", "entryContentRow",
 			"entryIdRow", "entryUpdatedRow"
 			], function(node){
-				dojo.style(this[node], "display", "none");
+				domStyle.set(this[node], "display", "none");
 			}, this);
 
-		dojo.forEach([
+		arrayUtil.forEach([
 			"entryTitleNode", "entryTitleHeader", "entryAuthorHeader", "entryContributorHeader",
 			"entryContributorNode", "entrySummaryHeader", "entrySummaryNode", "entryContentHeader",
 			"entryContentNode", "entryIdNode", "entryIdHeader", "entryUpdatedHeader", "entryUpdatedNode"
 			], function(part){
 				while(this[part].firstChild){
-					dojo.destroy(this[part].firstChild);
+					domConstruct.destroy(this[part].firstChild);
 				}
 			}
 		,this);
@@ -196,8 +206,8 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 		//		The Feed Entry to work with.
 		//
 		if(entry.title && entry.title.value && entry.title.value !== null){
-			var _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedEntryViewer");
-			var titleHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.title});
+			var _nlsResources = i18nViewer;
+			var titleHeader = new widget.EntryHeader({title: _nlsResources.title});
 			titleHeaderNode.appendChild(titleHeader.domNode);
 		}
 	},
@@ -221,7 +231,7 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 				titleAnchorNode.appendChild(titleNode);
 			}else{
 				var titleViewNode = document.createElement("span");
-				var titleView = new dijit.layout.ContentPane({refreshOnShow: true, executeScripts: false}, titleViewNode);
+				var titleView = new ContentPane({refreshOnShow: true, executeScripts: false}, titleViewNode);
 				titleView.attr('content', entry.title.value);
 				titleAnchorNode.appendChild(titleView.domNode);
 			}
@@ -241,8 +251,8 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 		//	entry:
 		//		The Feed Entry to work with.
 		if(entry.authors && entry.authors.length > 0){
-			var _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedEntryViewer");
-			var authorHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.authors});
+			var _nlsResources = i18nViewer;
+			var authorHeader = new widget.EntryHeader({title: _nlsResources.authors});
 			authorHeaderNode.appendChild(authorHeader.domNode);
 		}
 	},
@@ -297,8 +307,8 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 		//	entry:
 		//		The Feed Entry to work with.
 		if(entry.contributors && entry.contributors.length > 0){
-			var _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedEntryViewer");
-			var contributorHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.contributors});
+			var _nlsResources = i18nViewer;
+			var contributorHeader = new widget.EntryHeader({title: _nlsResources.contributors});
 			contributorsHeaderNode.appendChild(contributorHeader.domNode);
 		}
 	},
@@ -341,8 +351,8 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 		//	entry:
 		//		The Feed Entry to work with.
 		if(entry.id && entry.id !== null){
-			var _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedEntryViewer");
-			var idHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.id});
+			var _nlsResources = i18nViewer;
+			var idHeader = new widget.EntryHeader({title: _nlsResources.id});
 			idHeaderNode.appendChild(idHeader.domNode);
 		}
 	},
@@ -380,8 +390,8 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 		//	entry:
 		//		The Feed Entry to work with.
 		if(entry.updated && entry.updated !== null){
-			var _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedEntryViewer");
-			var updatedHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.updated});
+			var _nlsResources = i18nViewer;
+			var updatedHeader = new widget.EntryHeader({title: _nlsResources.updated});
 			updatedHeaderNode.appendChild(updatedHeader.domNode);
 		}
 	},
@@ -418,8 +428,8 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 		//	entry:
 		//		The Feed Entry to work with.
 		if(entry.summary && entry.summary.value && entry.summary.value !== null){
-			var _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedEntryViewer");
-			var summaryHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.summary});
+			var _nlsResources = i18nViewer;
+			var summaryHeader = new widget.EntryHeader({title: _nlsResources.summary});
 			summaryHeaderNode.appendChild(summaryHeader.domNode);
 		}
 	},
@@ -440,7 +450,7 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 		//		The Feed Entry to work with.
 		if(entry.summary && entry.summary.value && entry.summary.value !== null){
 			var summaryViewNode = document.createElement("span");
-			var summaryView = new dijit.layout.ContentPane({refreshOnShow: true, executeScripts: false}, summaryViewNode);
+			var summaryView = new ContentPane({refreshOnShow: true, executeScripts: false}, summaryViewNode);
 			summaryView.attr('content', entry.summary.value);
 			summaryAnchorNode.appendChild(summaryView.domNode);
 			this.setFieldValidity("summary", true);
@@ -459,8 +469,8 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 		//	entry:
 		//		The Feed Entry to work with.
 		if(entry.content && entry.content.value && entry.content.value !== null){
-			var _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedEntryViewer");
-			var contentHeader = new dojox.atom.widget.EntryHeader({title: _nlsResources.content});
+			var _nlsResources = i18nViewer;
+			var contentHeader = new widget.EntryHeader({title: _nlsResources.content});
 			contentHeaderNode.appendChild(contentHeader.domNode);
 		}
 	},
@@ -480,7 +490,7 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 		//		The Feed Entry to work with.
 		if(entry.content && entry.content.value && entry.content.value !== null){
 			var contentViewNode = document.createElement("span");
-			var contentView = new dijit.layout.ContentPane({refreshOnShow: true, executeScripts: false},contentViewNode);
+			var contentView = new ContentPane({refreshOnShow: true, executeScripts: false},contentViewNode);
 			contentView.attr('content', entry.content.value);
 			contentAnchorNode.appendChild(contentView.domNode);
 			this.setFieldValidity("content", true);
@@ -496,36 +506,36 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 		//
 		//	returns:
 		//		Nothing.
-		dojo.style(this.entryTitleRow, 'display', 'none');
-		dojo.style(this.entryAuthorRow, 'display', 'none');
-		dojo.style(this.entryContributorRow, 'display', 'none');
-		dojo.style(this.entrySummaryRow, 'display', 'none');
-		dojo.style(this.entryContentRow, 'display', 'none');
-		dojo.style(this.entryIdRow, 'display', 'none');
-		dojo.style(this.entryUpdatedRow, 'display', 'none');
+		domStyle.set(this.entryTitleRow, 'display', 'none');
+		domStyle.set(this.entryAuthorRow, 'display', 'none');
+		domStyle.set(this.entryContributorRow, 'display', 'none');
+		domStyle.set(this.entrySummaryRow, 'display', 'none');
+		domStyle.set(this.entryContentRow, 'display', 'none');
+		domStyle.set(this.entryIdRow, 'display', 'none');
+		domStyle.set(this.entryUpdatedRow, 'display', 'none');
 
 		for(var i in this._displayEntrySections){
 			var section = this._displayEntrySections[i].toLowerCase();
 			if(section === "title" && this.isFieldValid("title")){
-				dojo.style(this.entryTitleRow, 'display', '');
+				domStyle.set(this.entryTitleRow, 'display', '');
 			}
 			if(section === "authors" && this.isFieldValid("authors")){
-				dojo.style(this.entryAuthorRow, 'display', '');
+				domStyle.set(this.entryAuthorRow, 'display', '');
 			}
 			if(section === "contributors" && this.isFieldValid("contributors")){
-				dojo.style(this.entryContributorRow, 'display', '');
+				domStyle.set(this.entryContributorRow, 'display', '');
 			}
 			if(section === "summary" && this.isFieldValid("summary")){
-				dojo.style(this.entrySummaryRow, 'display', '');
+				domStyle.set(this.entrySummaryRow, 'display', '');
 			}
 			if(section === "content" && this.isFieldValid("content")){
-				dojo.style(this.entryContentRow, 'display', '');
+				domStyle.set(this.entryContentRow, 'display', '');
 			}
 			if(section === "id" && this.isFieldValid("id")){
-				dojo.style(this.entryIdRow, 'display', '');
+				domStyle.set(this.entryIdRow, 'display', '');
 			}
 			if(section === "updated" && this.isFieldValid("updated")){
-				dojo.style(this.entryUpdatedRow, 'display', '');
+				domStyle.set(this.entryUpdatedRow, 'display', '');
 			}
 
 		}
@@ -560,8 +570,8 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 		//		Nothing.
 		var items = ["title","authors","contributors","summary","content","id","updated"];
 		for(var i in items){
-			if(dojo.indexOf(this._displayEntrySections, items[i]) == -1){
-				dojo.style(this["feedEntryCell"+items[i]], 'display', 'none');
+			if(arrayUtil.indexOf(this._displayEntrySections, items[i]) == -1){
+				domStyle.set(this["feedEntryCell"+items[i]], 'display', 'none');
 			}else{
 				this["feedEntryCheckBox"+items[i].substring(0,1).toUpperCase()+items[i].substring(1)].checked=true;
 			}
@@ -641,37 +651,37 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 			var anim2;
 			if(this._optionButtonDisplayed){
 				if(this.enableMenuFade){
-					anim = dojo.fadeOut({node: this.entryCheckBoxDisplayOptions,duration: 250});
-					dojo.connect(anim, "onEnd", this, function(){
-						dojo.style(this.entryCheckBoxDisplayOptions, 'display', 'none');
-						dojo.style(this.entryCheckBoxRow, 'display', '');
-						dojo.style(this.entryCheckBoxRow2, 'display', '');
-						dojo.fadeIn({node: this.entryCheckBoxRow, duration: 250}).play();
-						dojo.fadeIn({node: this.entryCheckBoxRow2, duration: 250}).play();
+					anim = fx.fadeOut({node: this.entryCheckBoxDisplayOptions,duration: 250});
+					connect.connect(anim, "onEnd", this, function(){
+						domStyle.set(this.entryCheckBoxDisplayOptions, 'display', 'none');
+						domStyle.set(this.entryCheckBoxRow, 'display', '');
+						domStyle.set(this.entryCheckBoxRow2, 'display', '');
+						fx.fadeIn({node: this.entryCheckBoxRow, duration: 250}).play();
+						fx.fadeIn({node: this.entryCheckBoxRow2, duration: 250}).play();
 					});
 					anim.play();
 				}else{
-					dojo.style(this.entryCheckBoxDisplayOptions, 'display', 'none');
-					dojo.style(this.entryCheckBoxRow, 'display', '');
-					dojo.style(this.entryCheckBoxRow2, 'display', '');
+					domStyle.set(this.entryCheckBoxDisplayOptions, 'display', 'none');
+					domStyle.set(this.entryCheckBoxRow, 'display', '');
+					domStyle.set(this.entryCheckBoxRow2, 'display', '');
 				}
 				this._optionButtonDisplayed=false;
 			}else{
 				if(this.enableMenuFade){
-					anim = dojo.fadeOut({node: this.entryCheckBoxRow,duration: 250});
-					anim2 = dojo.fadeOut({node: this.entryCheckBoxRow2,duration: 250});
-					dojo.connect(anim, "onEnd", this, function(){
-						dojo.style(this.entryCheckBoxRow, 'display', 'none');
-						dojo.style(this.entryCheckBoxRow2, 'display', 'none');
-						dojo.style(this.entryCheckBoxDisplayOptions, 'display', '');
-						dojo.fadeIn({node: this.entryCheckBoxDisplayOptions, duration: 250}).play();
+					anim = fx.fadeOut({node: this.entryCheckBoxRow,duration: 250});
+					anim2 = fx.fadeOut({node: this.entryCheckBoxRow2,duration: 250});
+					connect.connect(anim, "onEnd", this, function(){
+						domStyle.set(this.entryCheckBoxRow, 'display', 'none');
+						domStyle.set(this.entryCheckBoxRow2, 'display', 'none');
+						domStyle.set(this.entryCheckBoxDisplayOptions, 'display', '');
+						fx.fadeIn({node: this.entryCheckBoxDisplayOptions, duration: 250}).play();
 					});
 					anim.play();
 					anim2.play();
 				}else{
-					dojo.style(this.entryCheckBoxRow, 'display', 'none');
-					dojo.style(this.entryCheckBoxRow2, 'display', 'none');
-					dojo.style(this.entryCheckBoxDisplayOptions, 'display', '');
+					domStyle.set(this.entryCheckBoxRow, 'display', 'none');
+					domStyle.set(this.entryCheckBoxRow2, 'display', 'none');
+					domStyle.set(this.entryCheckBoxDisplayOptions, 'display', '');
 				}
 				this._optionButtonDisplayed=true;
 			}
@@ -743,17 +753,17 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 
 	destroy: function(){
 		this.clear();
-		dojo.forEach(this._subscriptions, dojo.unsubscribe);
+		arrayUtil.forEach(this._subscriptions, dojo.unsubscribe);
 	}
 });
 
-dojo.declare("dojox.atom.widget.EntryHeader",[dijit._Widget, dijit._Templated, dijit._Container],{
+widget.EntryHeader = dojo.declare(/*===== "dojox.atom.widget.EntryHeader", =====*/ [_Widget, _Templated, _Container],{
 	//	summary:
 	//		Widget representing a header in a FeedEntryViewer/Editor
 	//	description:
 	//		Widget representing a header in a FeedEntryViewer/Editor
 	title: "",
-	templateString: dojo.cache("dojox.atom", "widget/templates/EntryHeader.html"),
+	templateString: headerTemplate,
 
 	postCreate: function(){
 		this.setListHeader();
@@ -781,3 +791,6 @@ dojo.declare("dojox.atom.widget.EntryHeader",[dijit._Widget, dijit._Templated, d
 		this.clear();
 	}
 });
+
+return widget.FeedEntryViewer;
+});
diff --git a/dojox/atom/widget/FeedViewer.js b/dojox/atom/widget/FeedViewer.js
index dc5dfe3..c591360 100644
--- a/dojox/atom/widget/FeedViewer.js
+++ b/dojox/atom/widget/FeedViewer.js
@@ -1,14 +1,24 @@
-dojo.provide("dojox.atom.widget.FeedViewer");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._Container");
-dojo.require("dojox.atom.io.Connection");
-dojo.requireLocalization("dojox.atom.widget", "FeedViewerEntry");
-
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/dom-class",
+	"dijit/_Widget",
+	"dijit/_Templated",
+	"dijit/_Container",
+	"../io/Connection",
+	"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.experimental("dojox.atom.widget.FeedViewer");
 
-dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, dijit._Container],{
+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:
@@ -21,7 +31,7 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	localSaveOnly: false,
 
 	//Templates for the HTML rendering.  Need to figure these out better, admittedly.
-	templateString: dojo.cache("dojox.atom", "widget/templates/FeedViewer.html"),
+	templateString: template,
 
 	_feed: null,
 	_currentSelection: null, // Currently selected entry
@@ -41,7 +51,7 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 		if(this.entrySelectionTopic !== ""){
 			this._subscriptions = [dojo.subscribe(this.entrySelectionTopic, this, "_handleEvent")];
 		}
-		this.atomIO = new dojox.atom.io.Connection();
+		this.atomIO = new Connection();
 		this.childWidgets = [];
 	},
 	
@@ -55,7 +65,7 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 		for(var i in children){
 			var child = children[i];
 			if(child && child.isFilter){
-				this._includeFilters.push(new dojox.atom.widget.FeedViewer.CategoryIncludeFilter(child.scheme, child.term, child.label));
+				this._includeFilters.push(new widget.FeedViewer.CategoryIncludeFilter(child.scheme, child.term, child.label));
 				child.destroy();
 			}
 		}
@@ -98,7 +108,7 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 				this.url = baseUrl + url;
 			}
 
-			this.atomIO.getFeed(url,dojo.hitch(this,this.setFeed));
+			this.atomIO.getFeed(url,lang.hitch(this,this.setFeed));
 		}
 	},
 
@@ -131,7 +141,7 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 			dpts.pop(); // remove year and time
 			return dpts.join(",");
 		};
-		var sortedEntries = feed.entries.sort(dojo.hitch(this,entrySorter));
+		var sortedEntries = feed.entries.sort(lang.hitch(this,entrySorter));
 		if(feed){
 			var lastSectionTitle = null;
 			for(var i=0;i<sortedEntries.length;i++){
@@ -187,7 +197,7 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 		//
 		//	returns:
 		//		Nothing.
-		var entryWidget = new dojox.atom.widget.FeedViewerGrouping({});
+		var entryWidget = new widget.FeedViewerGrouping({});
 		entryWidget.setText(titleText);
 		this.addChild(entryWidget);
 		this.childWidgets.push(entryWidget);
@@ -204,7 +214,7 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 		//
 		//	returns:
 		//		Nothing.
-		var entryWidget = new dojox.atom.widget.FeedViewerEntry({"xmethod": this.xmethod});
+		var entryWidget = new widget.FeedViewerEntry({"xmethod": this.xmethod});
 		entryWidget.setTitle(entry.title.value);
 		entryWidget.setTime(this._displayDateForEntry(entry).toLocaleTimeString());
 		entryWidget.entrySelectionTopic = this.entrySelectionTopic;
@@ -225,7 +235,7 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 		//	description:
 		//		Function for deleting a row from the view
 		if(!this.localSaveOnly){
-			this.atomIO.deleteEntry(entryRow.entry, dojo.hitch(this, this._removeEntry, entryRow), null, this.xmethod);
+			this.atomIO.deleteEntry(entryRow.entry, lang.hitch(this, this._removeEntry, entryRow), null, this.xmethod);
 		}else{
 			this._removeEntry(entryRow, true);
 		}
@@ -239,11 +249,11 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 		//		callback for when an entry is deleted from a feed.
 		if(success){
 			/* Check if this is the last Entry beneath the given date */
-			var idx = dojo.indexOf(this.childWidgets, entry);
+			var idx = arrayUtil.indexOf(this.childWidgets, entry);
 			var before = this.childWidgets[idx-1];
 			var after = this.childWidgets[idx+1];
-			if( before.declaredClass === 'dojox.atom.widget.FeedViewerGrouping' &&
-				(after === undefined || after.declaredClass === 'dojox.atom.widget.FeedViewerGrouping')){
+			if( before.isInstanceOf(widget.FeedViewerGrouping) &&
+				(after === undefined || after.isInstanceOf(widget.FeedViewerGrouping))){
 				before.destroy();
 			}
 			
@@ -265,11 +275,8 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 		//		Nothing.
 		var selectedNode = evt.target;
 		while(selectedNode){
-			if(selectedNode.attributes){
-				var widgetid = selectedNode.attributes.getNamedItem("widgetid");
-				if(widgetid && widgetid.value.indexOf("FeedViewerEntry") != -1){
-					break;
-				}
+			if(domClass.contains(selectedNode, 'feedViewerEntry')) {
+				break;
 			}
 			selectedNode = selectedNode.parentNode;
 		}
@@ -278,9 +285,9 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 			var entry = this._feed.entries[i];
 			if( (selectedNode === entry.domNode) && (this._currentSelection !== entry) ){
 				//Found it and it isn't already selected.
-				dojo.addClass(entry.domNode, "feedViewerEntrySelected");
-				dojo.removeClass(entry._entryWidget.timeNode, "feedViewerEntryUpdated");
-				dojo.addClass(entry._entryWidget.timeNode, "feedViewerEntryUpdatedSelected");
+				domClass.add(entry.domNode, "feedViewerEntrySelected");
+				domClass.remove(entry._entryWidget.timeNode, "feedViewerEntryUpdated");
+				domClass.add(entry._entryWidget.timeNode, "feedViewerEntryUpdatedSelected");
 
 				this.onEntrySelected(entry);
 				if(this.entrySelectionTopic !== ""){
@@ -311,9 +318,9 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 		//	returns:
 		//		Nothing.
 		if(this._currentSelection){
-			dojo.addClass(this._currentSelection._entryWidget.timeNode, "feedViewerEntryUpdated");
-			dojo.removeClass(this._currentSelection.domNode, "feedViewerEntrySelected");
-			dojo.removeClass(this._currentSelection._entryWidget.timeNode, "feedViewerEntryUpdatedSelected");
+			domClass.add(this._currentSelection._entryWidget.timeNode, "feedViewerEntryUpdated");
+			domClass.remove(this._currentSelection.domNode, "feedViewerEntrySelected");
+			domClass.remove(this._currentSelection._entryWidget.timeNode, "feedViewerEntryUpdatedSelected");
 			this._currentSelection._entryWidget.disableDelete();
 			this._currentSelection = null;
 		}
@@ -511,7 +518,7 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 			}
 
 			if (addIt) {
-				this._includeFilters.push(dojox.atom.widget.FeedViewer.CategoryIncludeFilter(scheme, term, label));
+				this._includeFilters.push(widget.FeedViewer.CategoryIncludeFilter(scheme, term, label));
 			}
 		}
 	},
@@ -572,13 +579,13 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 			if(entrySelectionEvent.action == "update" && entrySelectionEvent.entry) {
                 var evt = entrySelectionEvent;
 				if(!this.localSaveOnly){
-					this.atomIO.updateEntry(evt.entry, dojo.hitch(evt.source,evt.callback), null, true);
+					this.atomIO.updateEntry(evt.entry, lang.hitch(evt.source,evt.callback), null, true);
 				}
 				this._currentSelection._entryWidget.setTime(this._displayDateForEntry(evt.entry).toLocaleTimeString());
 				this._currentSelection._entryWidget.setTitle(evt.entry.title.value);
 			} else if(entrySelectionEvent.action == "post" && entrySelectionEvent.entry) {
 				if(!this.localSaveOnly){
-					this.atomIO.addEntry(entrySelectionEvent.entry, this.url, dojo.hitch(this,this._addEntry));
+					this.atomIO.addEntry(entrySelectionEvent.entry, this.url, lang.hitch(this,this._addEntry));
 				}else{
 					this._addEntry(entrySelectionEvent.entry);
 				}
@@ -603,16 +610,16 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 		//	description:
 		//		Destroys this widget, including all descendants and subscriptions.
 		this.clear();
-		dojo.forEach(this._subscriptions, dojo.unsubscribe);
+		arrayUtil.forEach(this._subscriptions, dojo.unsubscribe);
 	}
 });
 
-dojo.declare("dojox.atom.widget.FeedViewerEntry",[dijit._Widget, dijit._Templated],{
+widget.FeedViewerEntry = dojo.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: dojo.cache("dojox.atom", "widget/templates/FeedViewerEntry.html"),
+	templateString: entryTemplate,
 
 	entryNode: null,
 	timeNode: null,
@@ -621,7 +628,7 @@ dojo.declare("dojox.atom.widget.FeedViewerEntry",[dijit._Widget, dijit._Template
 	feed: null,
 
 	postCreate: function(){
-		var _nlsResources = dojo.i18n.getLocalization("dojox.atom.widget", "FeedViewerEntry");
+		var _nlsResources = i18nViewer;
 		this.deleteButton.innerHTML = _nlsResources.deleteButton;
 	},
 
@@ -710,12 +717,12 @@ dojo.declare("dojox.atom.widget.FeedViewerEntry",[dijit._Widget, dijit._Template
 	}
 });
 
-dojo.declare("dojox.atom.widget.FeedViewerGrouping",[dijit._Widget, dijit._Templated],{
+widget.FeedViewerGrouping = dojo.declare(/*===== "dojox.atom.widget.FeedViewerGrouping", =====*/ [_Widget, _Templated],{
 	//	summary:
 	//		Grouping of feed entries.
 	//	description:
 	//		Grouping of feed entries.
-	templateString: dojo.cache("dojox.atom", "widget/templates/FeedViewerGrouping.html"),
+	templateString: groupingTemplate,
 	
 	groupingNode: null,
 	titleNode: null,
@@ -734,7 +741,7 @@ dojo.declare("dojox.atom.widget.FeedViewerGrouping",[dijit._Widget, dijit._Templ
 	}
 });
 
-dojo.declare("dojox.atom.widget.AtomEntryCategoryFilter",[dijit._Widget, dijit._Templated],{
+widget.AtomEntryCategoryFilter = dojo.declare(/*===== "dojox.atom.widget.AtomEntryCategoryFilter", =====*/ [_Widget, _Templated],{
 	//	summary:
 	//		A filter to be applied to the list of entries.
 	//	description:
@@ -745,7 +752,7 @@ dojo.declare("dojox.atom.widget.AtomEntryCategoryFilter",[dijit._Widget, dijit._
 	isFilter: true
 });
 
-dojo.declare("dojox.atom.widget.FeedViewer.CategoryIncludeFilter",null,{
+widget.FeedViewer.CategoryIncludeFilter = dojo.declare(/*===== "dojox.atom.widget.FeedViewer.CategoryIncludeFilter", =====*/ null,{
 	constructor: function(scheme, term, label){
 		//	summary:
 		//		The initializer function.
@@ -796,3 +803,5 @@ dojo.declare("dojox.atom.widget.FeedViewer.CategoryIncludeFilter",null,{
 		return matched;
 	}
 });
+return widget.FeedViewer;
+});
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/FeedEntryEditor.js b/dojox/atom/widget/nls/FeedEntryEditor.js
index 934e7a0..b4140c3 100644
--- a/dojox/atom/widget/nls/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/FeedEntryEditor.js
@@ -1,6 +1,42 @@
+define({ root:
+//begin v1.x content
 ({
 	doNew: "[new]",
 	edit: "[edit]",
 	save: "[save]",
 	cancel: "[cancel]"
-})
\ No newline at end of file
+})
+//end v1.x content
+,
+"ar": true,
+"az": true,
+"ca": true,
+"cs": true,
+"da": true,
+"de": true,
+"el": true,
+"es": true,
+"fi": true,
+"fr": true,
+"he": true,
+"hu": true,
+"hr": true,
+"it": true,
+"ja": true,
+"kk": true,
+"ko": true,
+"nb": true,
+"nl": true,
+"pl": true,
+"pt-pt": true,
+"pt": true,
+"ro": true,
+"ru": true,
+"sk": true,
+"sl": true,
+"sv": true,
+"th": true,
+"tr": true,
+"zh": true,
+"zh-tw": true
+})
diff --git a/dojox/atom/widget/nls/FeedEntryViewer.js b/dojox/atom/widget/nls/FeedEntryViewer.js
index 3346210..0b05018 100644
--- a/dojox/atom/widget/nls/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define({ root:
+//begin v1.x content
 ({
 	displayOptions: "[display options]",
 	title: "Title",
@@ -8,4 +10,38 @@
 	updated: "Updated",
 	summary: "Summary",
 	content: "Content"
-})
\ No newline at end of file
+})
+//end v1.x content
+,
+"ar": true,
+"az": true,
+"ca": true,
+"cs": true,
+"da": true,
+"de": true,
+"el": true,
+"es": true,
+"fi": true,
+"fr": true,
+"he": true,
+"hu": true,
+"hr": true,
+"it": true,
+"ja": true,
+"kk": true,
+"ko": true,
+"nb": true,
+"nl": true,
+"pl": true,
+"pt-pt": true,
+"pt": true,
+"ro": true,
+"ru": true,
+"sk": true,
+"sl": true,
+"sv": true,
+"th": true,
+"tr": true,
+"zh": true,
+"zh-tw": true
+});
diff --git a/dojox/atom/widget/nls/FeedViewerEntry.js b/dojox/atom/widget/nls/FeedViewerEntry.js
index f84abba..f4817b6 100644
--- a/dojox/atom/widget/nls/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/FeedViewerEntry.js
@@ -1,3 +1,39 @@
+define({ root:
+//begin v1.x content
 ({
 	deleteButton: "[Delete]"
-})
\ No newline at end of file
+})
+//end v1.x content
+,
+"ar": true,
+"az": true,
+"ca": true,
+"cs": true,
+"da": true,
+"de": true,
+"el": true,
+"es": true,
+"fi": true,
+"fr": true,
+"he": true,
+"hu": true,
+"hr": true,
+"it": true,
+"ja": true,
+"kk": true,
+"ko": true,
+"nb": true,
+"nl": true,
+"pl": true,
+"pt-pt": true,
+"pt": true,
+"ro": true,
+"ru": true,
+"sk": true,
+"sl": true,
+"sv": true,
+"th": true,
+"tr": true,
+"zh": true,
+"zh-tw": true
+});
diff --git a/dojox/atom/widget/nls/PeopleEditor.js b/dojox/atom/widget/nls/PeopleEditor.js
index e51cbd1..b1072d4 100644
--- a/dojox/atom/widget/nls/PeopleEditor.js
+++ b/dojox/atom/widget/nls/PeopleEditor.js
@@ -1,5 +1,41 @@
+define({ root:
+//begin v1.x content
 ({
 	add: "Add",
 	addAuthor: "Add Author",
 	addContributor: "Add Contributor"
-})
\ No newline at end of file
+})
+//end v1.x content
+,
+"ar": true,
+"az": true,
+"ca": true,
+"cs": true,
+"da": true,
+"de": true,
+"el": true,
+"es": true,
+"fi": true,
+"fr": true,
+"he": true,
+"hu": true,
+"hr": true,
+"it": true,
+"ja": true,
+"kk": true,
+"ko": true,
+"nb": true,
+"nl": true,
+"pl": true,
+"pt-pt": true,
+"pt": true,
+"ro": true,
+"ru": true,
+"sk": true,
+"sl": true,
+"sv": true,
+"th": true,
+"tr": 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 e88af28..794cfc3 100644
--- a/dojox/atom/widget/nls/ar/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/ar/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+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 a509fa9..b12f468 100644
--- a/dojox/atom/widget/nls/ar/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/ar/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[اختيارات العرض]",
 	title: "العنوان",
@@ -9,3 +11,5 @@
 	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 6a569fc..1b4beb3 100644
--- a/dojox/atom/widget/nls/ar/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/ar/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+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 83b4ce3..cc9eed1 100644
--- a/dojox/atom/widget/nls/ar/PeopleEditor.js
+++ b/dojox/atom/widget/nls/ar/PeopleEditor.js
@@ -1,6 +1,9 @@
+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
new file mode 100644
index 0000000..94453d4
--- /dev/null
+++ b/dojox/atom/widget/nls/az/FeedEntryEditor.js
@@ -0,0 +1,10 @@
+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
new file mode 100644
index 0000000..3d94dc4
--- /dev/null
+++ b/dojox/atom/widget/nls/az/FeedEntryViewer.js
@@ -0,0 +1,15 @@
+define(
+//begin v1.x content
+({
+	"close" : "[çıx]",
+	"title" : "Başlıq",
+	"authors" : "Yazıçılar",
+	"summary" : "Məzmun",
+	"content" : "Tərkib",
+	"contributors" : "Əməyi keçənlər",
+	"updated" : "Yeniləndi",
+	"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
new file mode 100644
index 0000000..f92f842
--- /dev/null
+++ b/dojox/atom/widget/nls/az/FeedViewerEntry.js
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 0000000..470ea80
--- /dev/null
+++ b/dojox/atom/widget/nls/az/PeopleEditor.js
@@ -0,0 +1,9 @@
+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/ca/FeedEntryEditor.js b/dojox/atom/widget/nls/ca/FeedEntryEditor.js
index 8e866c5..d4e2e5e 100644
--- a/dojox/atom/widget/nls/ca/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/ca/FeedEntryEditor.js
@@ -1,7 +1,10 @@
+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 c9a2b54..e8e069f 100644
--- a/dojox/atom/widget/nls/ca/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/ca/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[mostra opcions]",
 	title: "Títol",
@@ -9,4 +11,5 @@
 	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 8d918ba..09d0637 100644
--- a/dojox/atom/widget/nls/ca/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/ca/FeedViewerEntry.js
@@ -1,4 +1,7 @@
+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 7362731..5812a77 100644
--- a/dojox/atom/widget/nls/ca/PeopleEditor.js
+++ b/dojox/atom/widget/nls/ca/PeopleEditor.js
@@ -1,6 +1,9 @@
+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 6929359..4cdca82 100644
--- a/dojox/atom/widget/nls/cs/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/cs/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	doNew: "[nové]",
 	edit: "[upravit]",
 	save: "[uložit]",
 	cancel: "[storno]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/cs/FeedEntryViewer.js b/dojox/atom/widget/nls/cs/FeedEntryViewer.js
index 25ed64f..3001df4 100644
--- a/dojox/atom/widget/nls/cs/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/cs/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[volby zobrazení]",
 	title: "Název",
@@ -8,4 +10,6 @@
 	updated: "Aktualizováno",
 	summary: "Souhrn",
 	content: "Obsah"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/cs/FeedViewerEntry.js b/dojox/atom/widget/nls/cs/FeedViewerEntry.js
index 61ba923..ef49dff 100644
--- a/dojox/atom/widget/nls/cs/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/cs/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 ({
 	deleteButton: "[Odstranit]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/cs/PeopleEditor.js b/dojox/atom/widget/nls/cs/PeopleEditor.js
index 3aa2fb3..902299d 100644
--- a/dojox/atom/widget/nls/cs/PeopleEditor.js
+++ b/dojox/atom/widget/nls/cs/PeopleEditor.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	add: "Přidat",
 	addAuthor: "Přidat autora",
 	addContributor: "Přidat přispěvatele"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/da/FeedEntryEditor.js b/dojox/atom/widget/nls/da/FeedEntryEditor.js
index b3d88f9..2c384b1 100644
--- a/dojox/atom/widget/nls/da/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/da/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+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 ec18a7e..e423bbe 100644
--- a/dojox/atom/widget/nls/da/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/da/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[fremvisningsvalg]",
 	title: "Titel",
@@ -9,4 +11,5 @@
 	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 5506efa..70f46db 100644
--- a/dojox/atom/widget/nls/da/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/da/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+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 13e9be1..a3be0e0 100644
--- a/dojox/atom/widget/nls/da/PeopleEditor.js
+++ b/dojox/atom/widget/nls/da/PeopleEditor.js
@@ -1,5 +1,9 @@
+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 b2a39b2..5f99cd6 100644
--- a/dojox/atom/widget/nls/de/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/de/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	doNew: "[Neu]",
 	edit: "[Bearbeiten]",
 	save: "[Speichern]",
 	cancel: "[Abbrechen]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/de/FeedEntryViewer.js b/dojox/atom/widget/nls/de/FeedEntryViewer.js
index dbb1ce7..964ca9b 100644
--- a/dojox/atom/widget/nls/de/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/de/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[Anzeigeoptionen]",
 	title: "Titel",
@@ -8,4 +10,6 @@
 	updated: "Aktualisiert",
 	summary: "Zusammenfassung",
 	content: "Inhalt"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/de/FeedViewerEntry.js b/dojox/atom/widget/nls/de/FeedViewerEntry.js
index 0128ad1..3d31af6 100644
--- a/dojox/atom/widget/nls/de/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/de/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 ({
 	deleteButton: "[Löschen]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/de/PeopleEditor.js b/dojox/atom/widget/nls/de/PeopleEditor.js
index 1fd8057..0d8ae2c 100644
--- a/dojox/atom/widget/nls/de/PeopleEditor.js
+++ b/dojox/atom/widget/nls/de/PeopleEditor.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	add: "Hinzufügen",
 	addAuthor: "Autor hinzufügen",
 	addContributor: "Mitwirkenden hinzufügen"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/el/FeedEntryEditor.js b/dojox/atom/widget/nls/el/FeedEntryEditor.js
index a4cbefd..dfbc26a 100644
--- a/dojox/atom/widget/nls/el/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/el/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+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 a5200dc..9fe5927 100644
--- a/dojox/atom/widget/nls/el/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/el/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[επιλογές παρουσίασης]",
 	title: "Τίτλος",
@@ -9,3 +11,5 @@
 	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 8345e30..26ff04a 100644
--- a/dojox/atom/widget/nls/el/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/el/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+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 726d426..f77bccd 100644
--- a/dojox/atom/widget/nls/el/PeopleEditor.js
+++ b/dojox/atom/widget/nls/el/PeopleEditor.js
@@ -1,5 +1,9 @@
+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 6b08c6d..9875ea9 100644
--- a/dojox/atom/widget/nls/es/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/es/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	doNew: "[nuevo]",
 	edit: "[editar]",
 	save: "[guardar]",
 	cancel: "[cancelar]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/es/FeedEntryViewer.js b/dojox/atom/widget/nls/es/FeedEntryViewer.js
index cb63dda..183d3c2 100644
--- a/dojox/atom/widget/nls/es/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/es/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[opciones de visualización]",
 	title: "Título",
@@ -8,4 +10,6 @@
 	updated: "Actualizado",
 	summary: "Resumen",
 	content: "Contenido"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/es/FeedViewerEntry.js b/dojox/atom/widget/nls/es/FeedViewerEntry.js
index ef2b449..5a4bbab 100644
--- a/dojox/atom/widget/nls/es/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/es/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 ({
 	deleteButton: "[Suprimir]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/es/PeopleEditor.js b/dojox/atom/widget/nls/es/PeopleEditor.js
index ee1427a..e44cd21 100644
--- a/dojox/atom/widget/nls/es/PeopleEditor.js
+++ b/dojox/atom/widget/nls/es/PeopleEditor.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	add: "Añadir",
 	addAuthor: "Añadir autor",
 	addContributor: "Añadir colaborador"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/fi/FeedEntryEditor.js b/dojox/atom/widget/nls/fi/FeedEntryEditor.js
index 812b604..ff67f18 100644
--- a/dojox/atom/widget/nls/fi/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/fi/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+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 a2b5378..5fe38a7 100644
--- a/dojox/atom/widget/nls/fi/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/fi/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[näyttöasetukset]",
 	title: "Otsikko",
@@ -9,4 +11,5 @@
 	summary: "Tiivistelmä",
 	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 0ce2a17..b105b9a 100644
--- a/dojox/atom/widget/nls/fi/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/fi/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+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 973d352..9788510 100644
--- a/dojox/atom/widget/nls/fi/PeopleEditor.js
+++ b/dojox/atom/widget/nls/fi/PeopleEditor.js
@@ -1,6 +1,9 @@
+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 8e68668..75207e9 100644
--- a/dojox/atom/widget/nls/fr/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/fr/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	doNew: "[nouveau]",
 	edit: "[éditer]",
 	save: "[sauvegarder]",
 	cancel: "[annuler]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/fr/FeedEntryViewer.js b/dojox/atom/widget/nls/fr/FeedEntryViewer.js
index 41462dd..6cfa5ba 100644
--- a/dojox/atom/widget/nls/fr/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/fr/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[options d'affichage]",
 	title: "Titre",
@@ -8,4 +10,6 @@
 	updated: "Mis à jour",
 	summary: "Récapitulatif",
 	content: "Contenu"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/fr/FeedViewerEntry.js b/dojox/atom/widget/nls/fr/FeedViewerEntry.js
index a051693..e59ee80 100644
--- a/dojox/atom/widget/nls/fr/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/fr/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 ({
 	deleteButton: "[Supprimer]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/fr/PeopleEditor.js b/dojox/atom/widget/nls/fr/PeopleEditor.js
index 7bf8b0f..467c093 100644
--- a/dojox/atom/widget/nls/fr/PeopleEditor.js
+++ b/dojox/atom/widget/nls/fr/PeopleEditor.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	add: "Ajouter",
 	addAuthor: "Ajouter un auteur",
 	addContributor: "Ajouter un collaborateur"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/he/FeedEntryEditor.js b/dojox/atom/widget/nls/he/FeedEntryEditor.js
index 5cb7f4d..ee70d5f 100644
--- a/dojox/atom/widget/nls/he/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/he/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+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 3dbd2c8..ebc1fef 100644
--- a/dojox/atom/widget/nls/he/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/he/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[אפשרויות הצגה]",
 	title: "כותרת",
@@ -9,4 +11,5 @@
 	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 ccff392..f4a105c 100644
--- a/dojox/atom/widget/nls/he/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/he/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+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 3fe44b7..ed16c78 100644
--- a/dojox/atom/widget/nls/he/PeopleEditor.js
+++ b/dojox/atom/widget/nls/he/PeopleEditor.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	add: "הוספה",
 	addAuthor: "הוספת מחבר",
 	addContributor: "הוספת תורם"
 })
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/hr/FeedEntryEditor.js b/dojox/atom/widget/nls/hr/FeedEntryEditor.js
new file mode 100644
index 0000000..220f3e6
--- /dev/null
+++ b/dojox/atom/widget/nls/hr/FeedEntryEditor.js
@@ -0,0 +1,8 @@
+define(
+({
+	doNew: "[novo]",
+	edit: "[uredi]",
+	save: "[spremi]",
+	cancel: "[opoziv]"
+})
+);
diff --git a/dojox/atom/widget/nls/hr/FeedEntryViewer.js b/dojox/atom/widget/nls/hr/FeedEntryViewer.js
new file mode 100644
index 0000000..97b5633
--- /dev/null
+++ b/dojox/atom/widget/nls/hr/FeedEntryViewer.js
@@ -0,0 +1,13 @@
+define(
+({
+	displayOptions: "[opcije prikaza]",
+	title: "Naslov",
+	authors: "Autori",
+	contributors: "Doprinositelji",
+	id: "ID",
+	close: "[zatvori]",
+	updated: "Ažurirano",
+	summary: "Sažetak",
+	content: "Sadržaj"
+})
+);
diff --git a/dojox/atom/widget/nls/hr/FeedViewerEntry.js b/dojox/atom/widget/nls/hr/FeedViewerEntry.js
new file mode 100644
index 0000000..ae50ee3
--- /dev/null
+++ b/dojox/atom/widget/nls/hr/FeedViewerEntry.js
@@ -0,0 +1,5 @@
+define(
+({
+	deleteButton: "[Izbriši]"
+})
+);
diff --git a/dojox/atom/widget/nls/hr/PeopleEditor.js b/dojox/atom/widget/nls/hr/PeopleEditor.js
new file mode 100644
index 0000000..f581335
--- /dev/null
+++ b/dojox/atom/widget/nls/hr/PeopleEditor.js
@@ -0,0 +1,7 @@
+define(
+({
+	add: "Dodaj",
+	addAuthor: "Dodaj autora",
+	addContributor: "Dodaj doprinositelja"
+})
+);
diff --git a/dojox/atom/widget/nls/hu/FeedEntryEditor.js b/dojox/atom/widget/nls/hu/FeedEntryEditor.js
index d8dcb23..7f1df74 100644
--- a/dojox/atom/widget/nls/hu/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/hu/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	doNew: "[új]",
 	edit: "[szerkesztés]",
 	save: "[mentés]",
 	cancel: "[mégse]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/hu/FeedEntryViewer.js b/dojox/atom/widget/nls/hu/FeedEntryViewer.js
index 36e40af..606763a 100644
--- a/dojox/atom/widget/nls/hu/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/hu/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[megjelenítési beállítások]",
 	title: "Cím",
@@ -8,4 +10,6 @@
 	updated: "Frissítve",
 	summary: "Összegzés",
 	content: "Tartalom"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/hu/FeedViewerEntry.js b/dojox/atom/widget/nls/hu/FeedViewerEntry.js
index 6997454..d33877c 100644
--- a/dojox/atom/widget/nls/hu/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/hu/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 ({
 	deleteButton: "[Törlés]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/hu/PeopleEditor.js b/dojox/atom/widget/nls/hu/PeopleEditor.js
index b0244f9..ed930e6 100644
--- a/dojox/atom/widget/nls/hu/PeopleEditor.js
+++ b/dojox/atom/widget/nls/hu/PeopleEditor.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	add: "Hozzáadás",
 	addAuthor: "Szerző hozzáadása",
 	addContributor: "Közreműködő hozzáadása"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/it/FeedEntryEditor.js b/dojox/atom/widget/nls/it/FeedEntryEditor.js
index c01d49d..eb86b7e 100644
--- a/dojox/atom/widget/nls/it/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/it/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	doNew: "[nuovo]",
 	edit: "[modifica]",
 	save: "[salva]",
 	cancel: "[annulla]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/it/FeedEntryViewer.js b/dojox/atom/widget/nls/it/FeedEntryViewer.js
index 28d09cb..b336fa8 100644
--- a/dojox/atom/widget/nls/it/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/it/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[visualizza opzioni]",
 	title: "Titolo",
@@ -8,4 +10,6 @@
 	updated: "Aggiornato",
 	summary: "Riepilogo",
 	content: "Indice"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/it/FeedViewerEntry.js b/dojox/atom/widget/nls/it/FeedViewerEntry.js
index 7521930..65838d0 100644
--- a/dojox/atom/widget/nls/it/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/it/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 ({
 	deleteButton: "[Cancella]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/it/PeopleEditor.js b/dojox/atom/widget/nls/it/PeopleEditor.js
index b5bd262..82f0b58 100644
--- a/dojox/atom/widget/nls/it/PeopleEditor.js
+++ b/dojox/atom/widget/nls/it/PeopleEditor.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	add: "Aggiungi",
 	addAuthor: "Aggiungi autore",
 	addContributor: "Aggiungi collaboratori"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/ja/FeedEntryEditor.js b/dojox/atom/widget/nls/ja/FeedEntryEditor.js
index 95666e2..c416414 100644
--- a/dojox/atom/widget/nls/ja/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/ja/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	doNew: "[新規]",
 	edit: "[編集]",
 	save: "[保存]",
 	cancel: "[キャンセル]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/ja/FeedEntryViewer.js b/dojox/atom/widget/nls/ja/FeedEntryViewer.js
index c4b39f4..7529c46 100644
--- a/dojox/atom/widget/nls/ja/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/ja/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[表示オプション]",
 	title: "タイトル",
@@ -8,4 +10,6 @@
 	updated: "更新",
 	summary: "要約",
 	content: "内容"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/ja/FeedViewerEntry.js b/dojox/atom/widget/nls/ja/FeedViewerEntry.js
index bad586b..eb1dcd5 100644
--- a/dojox/atom/widget/nls/ja/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/ja/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 ({
 	deleteButton: "[削除]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/ja/PeopleEditor.js b/dojox/atom/widget/nls/ja/PeopleEditor.js
index ba4a2b6..6e9ed94 100644
--- a/dojox/atom/widget/nls/ja/PeopleEditor.js
+++ b/dojox/atom/widget/nls/ja/PeopleEditor.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	add: "追加",
 	addAuthor: "作成者の追加",
 	addContributor: "貢献者の追加"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/kk/FeedEntryEditor.js b/dojox/atom/widget/nls/kk/FeedEntryEditor.js
index 4b9cd45..e639c51 100644
--- a/dojox/atom/widget/nls/kk/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/kk/FeedEntryEditor.js
@@ -1,7 +1,10 @@
+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 4d85bde..aba4117 100644
--- a/dojox/atom/widget/nls/kk/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/kk/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[көрсету параметрлері]",
 	title: "Тақырып",
@@ -9,4 +11,5 @@
 	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 386f242..29e37cd 100644
--- a/dojox/atom/widget/nls/kk/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/kk/FeedViewerEntry.js
@@ -1,4 +1,7 @@
+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 c83fc47..e6a5d51 100644
--- a/dojox/atom/widget/nls/kk/PeopleEditor.js
+++ b/dojox/atom/widget/nls/kk/PeopleEditor.js
@@ -1,6 +1,9 @@
+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 2254b9c..96d7121 100644
--- a/dojox/atom/widget/nls/ko/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/ko/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	doNew: "[새로 작성]",
 	edit: "[편집]",
 	save: "[저장]",
 	cancel: "[취소]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/ko/FeedEntryViewer.js b/dojox/atom/widget/nls/ko/FeedEntryViewer.js
index 32e7013..c09eeec 100644
--- a/dojox/atom/widget/nls/ko/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/ko/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[옵션 표시]",
 	title: "제목",
@@ -9,3 +11,5 @@
 	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 72bf740..3ed9505 100644
--- a/dojox/atom/widget/nls/ko/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/ko/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 ({
 	deleteButton: "[삭제]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/ko/PeopleEditor.js b/dojox/atom/widget/nls/ko/PeopleEditor.js
index 269e032..4d13a0b 100644
--- a/dojox/atom/widget/nls/ko/PeopleEditor.js
+++ b/dojox/atom/widget/nls/ko/PeopleEditor.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	add: "추가",
 	addAuthor: "작성자 추가",
 	addContributor: "제공자 추가"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/nb/FeedEntryEditor.js b/dojox/atom/widget/nls/nb/FeedEntryEditor.js
index 0d4d8cd..47276a8 100644
--- a/dojox/atom/widget/nls/nb/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/nb/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+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 574f7bc..b866294 100644
--- a/dojox/atom/widget/nls/nb/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/nb/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[visningsalternativer]",
 	title: "Tittel",
@@ -9,3 +11,5 @@
 	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 057ebf7..012ba64 100644
--- a/dojox/atom/widget/nls/nb/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/nb/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+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 0a725d4..4557df9 100644
--- a/dojox/atom/widget/nls/nb/PeopleEditor.js
+++ b/dojox/atom/widget/nls/nb/PeopleEditor.js
@@ -1,5 +1,9 @@
+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 4263173..3b2be53 100644
--- a/dojox/atom/widget/nls/nl/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/nl/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+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 f6a5552..088876f 100644
--- a/dojox/atom/widget/nls/nl/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/nl/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[weergaveopties]",
 	title: "Titel",
@@ -9,3 +11,5 @@
 	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 4ec7dc6..e44093c 100644
--- a/dojox/atom/widget/nls/nl/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/nl/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+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 5a9521f..74324dc 100644
--- a/dojox/atom/widget/nls/nl/PeopleEditor.js
+++ b/dojox/atom/widget/nls/nl/PeopleEditor.js
@@ -1,5 +1,9 @@
+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 9fd4973..4f0a243 100644
--- a/dojox/atom/widget/nls/pl/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/pl/FeedEntryEditor.js
@@ -1,7 +1,10 @@
+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 312e10c..48799aa 100644
--- a/dojox/atom/widget/nls/pl/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/pl/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[opcje wyświetlania]",
 	title: "Tytuł",
@@ -9,4 +11,5 @@
 	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 e0fca80..c95c641 100644
--- a/dojox/atom/widget/nls/pl/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/pl/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 ({
 	deleteButton: "[Usuń]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/pl/PeopleEditor.js b/dojox/atom/widget/nls/pl/PeopleEditor.js
index dd58dbc..56ffe89 100644
--- a/dojox/atom/widget/nls/pl/PeopleEditor.js
+++ b/dojox/atom/widget/nls/pl/PeopleEditor.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	add: "Dodaj",
 	addAuthor: "Dodaj autora",
 	addContributor: "Dodaj kontrybutora"
-})
\ No newline at end of file
+})
+//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 1ef0598..f134efc 100644
--- a/dojox/atom/widget/nls/pt-pt/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/pt-pt/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+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 81b3509..12732fd 100644
--- a/dojox/atom/widget/nls/pt-pt/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/pt-pt/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[opções de visualização]",
 	title: "Título",
@@ -9,3 +11,5 @@
 	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 690bdfe..bff7222 100644
--- a/dojox/atom/widget/nls/pt-pt/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/pt-pt/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+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 ee90a8e..601c753 100644
--- a/dojox/atom/widget/nls/pt-pt/PeopleEditor.js
+++ b/dojox/atom/widget/nls/pt-pt/PeopleEditor.js
@@ -1,5 +1,9 @@
+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 48526dd..26c3f10 100644
--- a/dojox/atom/widget/nls/pt/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/pt/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	doNew: "[novo]",
 	edit: "[editar]",
 	save: "[salvar]",
 	cancel: "[cancelar]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/pt/FeedEntryViewer.js b/dojox/atom/widget/nls/pt/FeedEntryViewer.js
index b4d531f..4dc46e0 100644
--- a/dojox/atom/widget/nls/pt/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/pt/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[exibir opções]",
 	title: "Título",
@@ -8,4 +10,6 @@
 	updated: "Atualizado",
 	summary: "Resumo",
 	content: "Conteúdo"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/pt/FeedViewerEntry.js b/dojox/atom/widget/nls/pt/FeedViewerEntry.js
index 7240c20..8bb50b6 100644
--- a/dojox/atom/widget/nls/pt/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/pt/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 ({
 	deleteButton: "[Excluir]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/pt/PeopleEditor.js b/dojox/atom/widget/nls/pt/PeopleEditor.js
index c572661..b5e50e3 100644
--- a/dojox/atom/widget/nls/pt/PeopleEditor.js
+++ b/dojox/atom/widget/nls/pt/PeopleEditor.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	add: "Adicionar",
 	addAuthor: "Adicionar Autor",
 	addContributor: "Adicionar Contribuidor"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/ro/FeedEntryEditor.js b/dojox/atom/widget/nls/ro/FeedEntryEditor.js
index e54a345..a105010 100644
--- a/dojox/atom/widget/nls/ro/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/ro/FeedEntryEditor.js
@@ -1,7 +1,10 @@
+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 8840053..cf2973b 100644
--- a/dojox/atom/widget/nls/ro/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/ro/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[opţiuni afişare]",
 	title: "Titlu",
@@ -9,4 +11,5 @@
 	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 98786b8..5121ce8 100644
--- a/dojox/atom/widget/nls/ro/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/ro/FeedViewerEntry.js
@@ -1,4 +1,7 @@
+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 3f06c05..29a6dcf 100644
--- a/dojox/atom/widget/nls/ro/PeopleEditor.js
+++ b/dojox/atom/widget/nls/ro/PeopleEditor.js
@@ -1,6 +1,9 @@
+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 8a5838c..9e4df1e 100644
--- a/dojox/atom/widget/nls/ru/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/ru/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	doNew: "[создать]",
 	edit: "[изменить]",
 	save: "[сохранить]",
 	cancel: "[отмена]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/ru/FeedEntryViewer.js b/dojox/atom/widget/nls/ru/FeedEntryViewer.js
index 7eb06e5..32db5f1 100644
--- a/dojox/atom/widget/nls/ru/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/ru/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[показать опции]",
 	title: "Название",
@@ -8,4 +10,6 @@
 	updated: "Обновлено",
 	summary: "Сводка",
 	content: "Информационное наполнение"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/ru/FeedViewerEntry.js b/dojox/atom/widget/nls/ru/FeedViewerEntry.js
index 0800cfa..93347a1 100644
--- a/dojox/atom/widget/nls/ru/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/ru/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 ({
 	deleteButton: "[Удалить]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/ru/PeopleEditor.js b/dojox/atom/widget/nls/ru/PeopleEditor.js
index a7e0faa..56e7b87 100644
--- a/dojox/atom/widget/nls/ru/PeopleEditor.js
+++ b/dojox/atom/widget/nls/ru/PeopleEditor.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	add: "Добавить",
 	addAuthor: "Добавить автора",
 	addContributor: "Добавить участника"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/sk/FeedEntryEditor.js b/dojox/atom/widget/nls/sk/FeedEntryEditor.js
index fa60ba9..1c5625e 100644
--- a/dojox/atom/widget/nls/sk/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/sk/FeedEntryEditor.js
@@ -1,7 +1,10 @@
+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 bf47a34..9021643 100644
--- a/dojox/atom/widget/nls/sk/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/sk/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[zobraziť voľby]",
 	title: "Nadpis",
@@ -9,4 +11,5 @@
 	summary: "Súhrn",
 	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 6838279..04f781b 100644
--- a/dojox/atom/widget/nls/sk/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/sk/FeedViewerEntry.js
@@ -1,4 +1,7 @@
+define(
+//begin v1.x content
 ({
 	deleteButton: "[Vymazať]"
 })
-
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/sk/PeopleEditor.js b/dojox/atom/widget/nls/sk/PeopleEditor.js
index 08f96c0..a87e12d 100644
--- a/dojox/atom/widget/nls/sk/PeopleEditor.js
+++ b/dojox/atom/widget/nls/sk/PeopleEditor.js
@@ -1,6 +1,9 @@
+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 ff71162..600a46b 100644
--- a/dojox/atom/widget/nls/sl/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/sl/FeedEntryEditor.js
@@ -1,7 +1,10 @@
+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 2fb1081..7233447 100644
--- a/dojox/atom/widget/nls/sl/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/sl/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[možnosti prikaza]",
 	title: "Naslov",
@@ -9,4 +11,5 @@
 	summary: "Povzetek",
 	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 a668341..57deaff 100644
--- a/dojox/atom/widget/nls/sl/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/sl/FeedViewerEntry.js
@@ -1,4 +1,7 @@
+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 fb52910..398504d 100644
--- a/dojox/atom/widget/nls/sl/PeopleEditor.js
+++ b/dojox/atom/widget/nls/sl/PeopleEditor.js
@@ -1,6 +1,9 @@
+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 1b8edcc..1119de5 100644
--- a/dojox/atom/widget/nls/sv/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/sv/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	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 e2ccfed..d7bd22d 100644
--- a/dojox/atom/widget/nls/sv/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/sv/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[Visningsalternativ]",
 	title: "Rubrik",
@@ -9,3 +11,5 @@
 	summary: "Sammanfattning",
 	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 7efab23..220dc3b 100644
--- a/dojox/atom/widget/nls/sv/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/sv/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+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 83a7320..79eee2b 100644
--- a/dojox/atom/widget/nls/sv/PeopleEditor.js
+++ b/dojox/atom/widget/nls/sv/PeopleEditor.js
@@ -1,5 +1,9 @@
+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 d02b7b5..2386f0e 100644
--- a/dojox/atom/widget/nls/th/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/th/FeedEntryEditor.js
@@ -1,7 +1,10 @@
+define(
+//begin v1.x content
 ({
 	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 ed3b078..7f6fa5e 100644
--- a/dojox/atom/widget/nls/th/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/th/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[อ็อพชันการแสดงผล]",
 	title: "ชื่อเรื่อง",
@@ -9,4 +11,5 @@
 	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 b773a9e..2e2ce0b 100644
--- a/dojox/atom/widget/nls/th/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/th/FeedViewerEntry.js
@@ -1,4 +1,7 @@
+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 3d88781..4acc14d 100644
--- a/dojox/atom/widget/nls/th/PeopleEditor.js
+++ b/dojox/atom/widget/nls/th/PeopleEditor.js
@@ -1,6 +1,9 @@
+define(
+//begin v1.x content
 ({
 	add: "เพิ่ม",
 	addAuthor: "เพิ่มผู้เขียน",
 	addContributor: "เพิ่มผู้อนุเคราะห์"
 })
-
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/tr/FeedEntryEditor.js b/dojox/atom/widget/nls/tr/FeedEntryEditor.js
index d77ca45..afc61bb 100644
--- a/dojox/atom/widget/nls/tr/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/tr/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+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 3ce5abf..bed8901 100644
--- a/dojox/atom/widget/nls/tr/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/tr/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[görüntüleme seçenekleri]",
 	title: "Başlık",
@@ -9,3 +11,5 @@
 	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 fe7dd85..7b6071c 100644
--- a/dojox/atom/widget/nls/tr/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/tr/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+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 4bd2f04..dd78561 100644
--- a/dojox/atom/widget/nls/tr/PeopleEditor.js
+++ b/dojox/atom/widget/nls/tr/PeopleEditor.js
@@ -1,5 +1,9 @@
+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/zh-tw/FeedEntryEditor.js b/dojox/atom/widget/nls/zh-tw/FeedEntryEditor.js
index 1f8e5e4..b87c26c 100644
--- a/dojox/atom/widget/nls/zh-tw/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/zh-tw/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	doNew: "[新建]",
 	edit: "[編輯]",
 	save: "[儲存]",
 	cancel: "[取消]"
-})
\ No newline at end of file
+})
+//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 9da61f8..e903d76 100644
--- a/dojox/atom/widget/nls/zh-tw/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/zh-tw/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[顯示選項]",
 	title: "標題",
@@ -9,3 +11,5 @@
 	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 070cb0e..c2336df 100644
--- a/dojox/atom/widget/nls/zh-tw/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/zh-tw/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 ({
 	deleteButton: "[刪除]"
-})
\ No newline at end of file
+})
+//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 e4c675d..41ea811 100644
--- a/dojox/atom/widget/nls/zh-tw/PeopleEditor.js
+++ b/dojox/atom/widget/nls/zh-tw/PeopleEditor.js
@@ -1,5 +1,9 @@
+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 4c95c26..ac9f053 100644
--- a/dojox/atom/widget/nls/zh/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/zh/FeedEntryEditor.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	doNew: "[新建]",
 	edit: "[编辑]",
 	save: "[保存]",
 	cancel: "[取消]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/zh/FeedEntryViewer.js b/dojox/atom/widget/nls/zh/FeedEntryViewer.js
index 0ada9c3..7d59651 100644
--- a/dojox/atom/widget/nls/zh/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/zh/FeedEntryViewer.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	displayOptions: "[显示选项]",
 	title: "标题",
@@ -8,4 +10,6 @@
 	updated: "更新时间",
 	summary: "摘要",
 	content: "内容"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/zh/FeedViewerEntry.js b/dojox/atom/widget/nls/zh/FeedViewerEntry.js
index 2eff4e3..7ebd582 100644
--- a/dojox/atom/widget/nls/zh/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/zh/FeedViewerEntry.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 ({
 	deleteButton: "[删除]"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/atom/widget/nls/zh/PeopleEditor.js b/dojox/atom/widget/nls/zh/PeopleEditor.js
index 069e327..7eb3533 100644
--- a/dojox/atom/widget/nls/zh/PeopleEditor.js
+++ b/dojox/atom/widget/nls/zh/PeopleEditor.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	add: "添加",
 	addAuthor: "添加作者",
 	addContributor: "添加内容添加者"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojox/calc/FuncGen.js b/dojox/calc/FuncGen.js
index a7634fe..376fcfc 100644
--- a/dojox/calc/FuncGen.js
+++ b/dojox/calc/FuncGen.js
@@ -1,139 +1,154 @@
-define("dojox/calc/FuncGen", ["dojo", "dijit/_Templated", "dojox/math/_base", "dijit/dijit", "dijit/form/ComboBox", "dijit/form/SimpleTextarea", "dijit/form/Button", "dojo/data/ItemFileWriteStore"], function(dojo) {
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/dom-style",
+	"dijit/_WidgetBase",
+	"dijit/_WidgetsInTemplateMixin",
+	"dijit/_TemplatedMixin",
+	"dojox/math/_base",
+	"dijit/registry",
+	"dojo/text!./templates/FuncGen.html",
+	"dojox/calc/_Executor",
+	"dijit/form/ComboBox", // template
+	"dijit/form/SimpleTextarea", // template
+	"dijit/form/Button", // template
+	"dijit/form/TextBox" // template
+], function(declare, lang, domStyle, WidgetBase, WidgetsInTemplateMixin, TemplatedMixin, math, registry, template, calc){
 
-dojo.experimental("dojox.calc.FuncGen");
+	/*=====
+		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,
 
-dojo.declare(
-	"dojox.calc.FuncGen",
-	[dijit._Widget, dijit._Templated],
-{
-	// summary:
-	//		The dialog layout for making functions
-	//
-	templateString: dojo.cache("dojox.calc", "templates/FuncGen.html"),
-
-	widgetsInTemplate:true,
-
-	onSelect: function(){
-		// 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
-		var answer = confirm("Do you want to clear the name, argument, and body text?");
-		if(answer){
-			this.clear();
-		}
-	},
-	saveFunction: function(name, args, body){
-		// override me
-	},
-	onSaved: function(){
-		// this on save needs to be overriden if you want Executor parsing support
-		//console.log("Save was pressed");
-	},
-	clear: function(){
-		// 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
-		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
-		//console.log("Reset was pressed");
-		if(this.combo.get("value") in this.functions){
-			var answer = confirm("Do you want to reset this function?");
+		onSelect: function(){
+			// 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
+			var answer = confirm("Do you want to clear the name, argument, and body text?");
 			if(answer){
-				this.reset();
-				this.status.set("value", "The function has been reset to its last save point.");
+				this.clear();
 			}
-		}
-	},
-	deleteThing: function(item){
-		// summary
-		//	delete an item in the writestore
-		if (this.writeStore.isItem(item)){
-			// delete it
-			//console.log("Found item "+item);
-			this.writeStore.deleteItem(item);
-			this.writeStore.save();
-		}else{
-			//console.log("Unable to locate the item");
-		}
-	},
-	deleteFunction: function(name){
-		// override me
-	},
-	onDelete: function(){
-		// summary
-		//	(Delete button on click event) delete a function if the user clicks yes
+		},
+		saveFunction: function(name, args, body){
+			// override me
+		},
+		onSaved: function(){
+			// this on save needs to be overriden if you want Executor parsing support
+			//console.log("Save was pressed");
+		},
+		clear: function(){
+			// 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
+			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
+			//console.log("Reset was pressed");
+			if(this.combo.get("value") in this.functions){
+				var answer = confirm("Do you want to reset this function?");
+				if(answer){
+					this.reset();
+					this.status.set("value", "The function has been reset to its last save point.");
+				}
+			}
+		},
+		deleteThing: function(item){
+			// summary
+			//	delete an item in the writestore
+			if(this.writeStore.isItem(item)){
+				// delete it
+				//console.log("Found item "+item);
+				this.writeStore.deleteItem(item);
+				this.writeStore.save();
+			}else{
+				//console.log("Unable to locate the item");
+			}
+		},
+		deleteFunction: function(name){
+			// override me
+		},
+		onDelete: function(){
+			// summary
+			//	(Delete button on click event) delete a function if the user clicks yes
 
-		//console.log("Delete was pressed");
+			//console.log("Delete was pressed");
 
-		var name;
-		if((name = this.combo.get("value")) in this.functions){
-			var answer = confirm("Do you want to delete this function?");
-			if(answer){
-				var item = this.combo.item;
+			var name;
+			if((name = this.combo.get("value")) in this.functions){
+				var answer = confirm("Do you want to delete this function?");
+				if(answer){
+					var item = this.combo.item;
 
-				//this.writeStore.fetchItemByIdentity({identity:name, onItem: this.deleteThing, onError:null});
+					//this.writeStore.fetchItemByIdentity({identity:name, onItem: this.deleteThing, onError:null});
 
-				this.writeStore.deleteItem(item);
-				this.writeStore.save();
+					this.writeStore.deleteItem(item);
+					this.writeStore.save();
 
-				this.deleteFunction(name);
-				delete this.functions[name];
-				this.clear();
+					this.deleteFunction(name);
+					delete this.functions[name];
+					this.clear();
+				}
+			}else{
+				this.status.set("value", "Function cannot be deleted, it isn't saved.");
 			}
-		}else{
-			this.status.set("value", "Function cannot be deleted, it isn't saved.");
-		}
-	},
-	readyStatus: function(){
-		// summary
-		//	set the status in the template to ready
-		this.status.set("value", "Ready");
-	},
-	writeStore:null, //the user can save functions to the writestore
-	readStore:null, // users cannot edit the read store contents, but they can use them
-	functions:null, // use the names to get to the function
+		},
+		readyStatus: function(){
+			// summary
+			//	set the status in the template to ready
+			this.status.set("value", "Ready");
+		},
+		writeStore:null, //the user can save functions to the writestore
+		readStore:null, // users cannot edit the read store contents, but they can use them
+		functions:null, // use the names to get to the function
 
-	/*postCreate: function(){
-		this.functions = []; // use the names to get to the function
-		this.writeStore = new dojo.data.ItemFileWriteStore({data: {identifier: 'name', items:[]}});
+		/*postCreate: function(){
+			this.functions = []; // use the names to get to the function
+			this.writeStore = new dojo.data.ItemFileWriteStore({data: {identifier: 'name', items:[]}});
 
-		this.combo.set("store", this.writeStore);
-	},*/
+			this.combo.set("store", this.writeStore);
+		},*/
 
-	startup: function(){
-		// 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);
+		startup: function(){
+			// 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
-		// close is only valid if the parent is a widget with a close function
-		var parent = dijit.getEnclosingWidget(this.domNode.parentNode);
-		if(parent && typeof parent.close == "function"){
-			this.closeButton.set("onClick", dojo.hitch(parent, 'close'));
-		}else{
-			dojo.style(this.closeButton.domNode, "display", "none"); // hide the button
+			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);
+			if(parent && typeof parent.close == "function"){
+				this.closeButton.set("onClick", lang.hitch(parent, 'close'));
+			}else{
+				domStyle.set(this.closeButton.domNode, { display: "none" }); // hide the button
+			}
 		}
-	}
-});
-
+	});
 
-return dojox.calc.FuncGen;
+	return lang.mixin(calc, { FuncGen: FuncGen });
 });
diff --git a/dojox/calc/GraphPro.js b/dojox/calc/GraphPro.js
index c8deb12..cee505c 100644
--- a/dojox/calc/GraphPro.js
+++ b/dojox/calc/GraphPro.js
@@ -1,136 +1,151 @@
-define("dojox/calc/GraphPro", ["dojo", "dojox/calc/Standard", "dijit/dijit", "dijit/form/ComboBox", "dijit/form/Select", "dijit/form/CheckBox", "dijit/ColorPalette", "dojox/charting/Chart2D", "dojox/calc/Grapher", "dojox/layout/FloatingPane", "dojox/charting/themes/Tufte", "dojo/colors"], function(dojo) {
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/dom-style",
+	"dojo/dom-construct",
+	"dojo/dom-geometry",
+	"dojo/ready",
+	"dojox/calc/Standard",
+	"dojox/calc/Grapher",
+	"dojox/layout/FloatingPane",
+	"dojo/text!./templates/GraphPro.html",
+	"dojox/calc/_Executor", // template
+	"dijit/Menu", // template
+	"dijit/MenuItem", // template
+	"dijit/form/ComboButton", // template
+	"dijit/form/Button", // template
+	"dijit/form/TextBox" // template
+], function(declare, lang, win, domStyle, domConstruct, domGeometry, ready, Standard, calc, FloatingPane, template){
 
-dojo.experimental("dojox.calc.GraphPro");
+	/*=====
+		Standard = dojox.calc.Standard;
+	=====*/
+	return declare(
+		"dojox.calc.GraphPro",
+		Standard,
+	{
+		// summary:
+		//		The dialog widget for a graphing, scientific calculator
+		//
+		templateString: template,
 
-dojo.declare(
-	"dojox.calc.GraphPro",
-	dojox.calc.Standard,
-{
-	// summary:
-	//		The dialog widget for a graphing, scientific calculator
-	//
-	templateString: dojo.cache("dojox.calc", "templates/GraphPro.html"),
+		grapher:null,
+		funcMaker:null,
+		aFloatingPane: null,
 
-	grapher:null,
-	funcMaker:null,
-	aFloatingPane: null,
-
-	executorLoaded: function(){
-		// summary
-		//	when executor loads check to see if the writestore is there
-		this.inherited(arguments);
-		dojo.addOnLoad(dojo.hitch(this, function(){
-			if(this.writeStore == null && "functionMakerButton" in this){
-				dojo.style(this.functionMakerButton.domNode, { visibility: "hidden" });
-			}
-		}));
-	},
-	makeFunctionWindow: function(){
-		// summary
-		//	use this function to create a function window (with the button on the layout)
-		var body = dojo.body();
+		executorLoaded: function(){
+			// 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){
+					domStyle.set(this.functionMakerButton.domNode, { visibility: "hidden" });
+				}
+			}));
+		},
+		makeFunctionWindow: function(){
+			// summary
+			//	use this function to create a function window (with the button on the layout)
+			var body = win.body();
 
-		var pane = dojo.create('div');
-		body.appendChild(pane);
+			var pane = domConstruct.create('div');
+			body.appendChild(pane);
 
-		this.aFloatingPane = new dojox.layout.FloatingPane({resizable:false, dockable:true, maxable:false, closable:true, duration:300, title:"Function Window", style:"position:absolute;left:10em;top:10em;width:50em;"}, pane);
-		var that = this;
-		var d = dojo.create("div");
-		this.funcMaker = new dojox.calc.FuncGen({
-			writeStore:that.writeStore,
-			readStore:that.readStore,
-			functions:that.functions,
-			deleteFunction: that.executor.deleteFunction,
-			onSaved:function(){
-				var	name,
-					body;
-				if((name = this.combo.get("value")) == ""){
-					this.status.set("value", "The function needs a name");
-				}else if ((body = this.textarea.get("value")) == ""){
-					// i don't think users need empty functions for math
-					this.status.set("value", "The function needs a body");
-				}else{
-					var args = this.args.get("value");
-					if(!(name in this.functions)){
-						this.combo.item = this.writeStore.newItem({name: name, args: args, body: body});
-						this.writeStore.save();
+			this.aFloatingPane = new dojox.layout.FloatingPane({resizable:false, dockable:true, maxable:false, closable:true, duration:300, title:"Function Window", style:"position:absolute;left:10em;top:10em;width:50em;"}, pane);
+			var that = this;
+			var d = domConstruct.create("div");
+			this.funcMaker = new calc.FuncGen({
+				writeStore:that.writeStore,
+				readStore:that.readStore,
+				functions:that.functions,
+				deleteFunction: that.executor.deleteFunction,
+				onSaved:function(){
+					var	name,
+						body;
+					if((name = this.combo.get("value")) == ""){
+						this.status.set("value", "The function needs a name");
+					}else if((body = this.textarea.get("value")) == ""){
+						// i don't think users need empty functions for math
+						this.status.set("value", "The function needs a body");
+					}else{
+						var args = this.args.get("value");
+						if(!(name in this.functions)){
+							this.combo.item = this.writeStore.put({name: name, args: args, body: body});
+						}
+						this.saveFunction(name, args, body);
+						this.status.set("value", "Function "+name+" was saved");
 					}
-					this.saveFunction(name, args, body);
-					this.status.set("value", "Function "+name+" was saved");
-				}
-			},
-			saveFunction: dojo.hitch(that, that.saveFunction)
-		}, d);
-		this.aFloatingPane.set('content', this.funcMaker);
-		this.aFloatingPane.startup();
-		this.aFloatingPane.bringToTop();
-	},
-	makeGrapherWindow: function(){
-		// summary
-		//	use this to make a Grapher window appear with a button
-		var body = dojo.body();
+				},
+				saveFunction: lang.hitch(that, that.saveFunction)
+			}, d);
+			this.aFloatingPane.set('content', this.funcMaker);
+			this.aFloatingPane.startup();
+			this.aFloatingPane.bringToTop();
+		},
+		makeGrapherWindow: function(){
+			// summary
+			//	use this to make a Grapher window appear with a button
+			var body = win.body();
 
-		var pane = dojo.create('div');
-		body.appendChild(pane);
+			var pane = domConstruct.create('div');
+			body.appendChild(pane);
 
-		this.aFloatingPane = new dojox.layout.FloatingPane({resizable:false, dockable:true, maxable:false, closable:true, duration:300, title:"Graph Window", style:"position:absolute;left:10em;top:5em;width:50em;"}, pane);
-		var that = this;
+			this.aFloatingPane = new dojox.layout.FloatingPane({resizable:false, dockable:true, maxable:false, closable:true, duration:300, title:"Graph Window", style:"position:absolute;left:10em;top:5em;width:50em;"}, pane);
+			var that = this;
 
-		var d = dojo.create("div");
-		this.grapher = new dojox.calc.Grapher({
-			myPane: this.aFloatingPane,
-			drawOne: function(i){
-				this.array[i][this.chartIndex].resize(this.graphWidth.get("value"), this.graphHeight.get("value"));
-				this.array[i][this.chartIndex].axes["x"].max = this.graphMaxX.get('value');
-				if(this.array[i][this.expressionIndex].get("value")==""){
-					this.setStatus(i, "Error");
-					return;
-				}
-				var func;
-				var yEquals = (this.array[i][this.functionMode]=="y=");
-				if(this.array[i][this.expressionIndex].get("value")!=this.array[i][this.evaluatedExpression]){
-					var args = 'x';
-					if(!yEquals){
-						args = 'y';
+			var d = domConstruct.create("div");
+			this.grapher = new calc.Grapher({
+				myPane: this.aFloatingPane,
+				drawOne: function(i){
+					this.array[i][this.chartIndex].resize(this.graphWidth.get("value"), this.graphHeight.get("value"));
+					this.array[i][this.chartIndex].axes["x"].max = this.graphMaxX.get('value');
+					if(this.array[i][this.expressionIndex].get("value")==""){
+						this.setStatus(i, "Error");
+						return;
 					}
-					func = that.executor.Function('', args, "return "+this.array[i][this.expressionIndex].get('value'));
-					this.array[i][this.evaluatedExpression] = this.array[i][this.expressionIndex].value;
-					this.array[i][this.functionRef] = func;
-				}
-				else{
-					func = this.array[i][this.functionRef];
-				}
-				var pickedColor = this.array[i][this.colorIndex].get("value");
-				if(!pickedColor){
-					pickedColor = 'black';
-				}
-				dojox.calc.Grapher.draw(this.array[i][this.chartIndex], func, {graphNumber:this.array[i][this.funcNumberIndex], fOfX:yEquals, color:{stroke:{color:pickedColor}}});
-				this.setStatus(i, "Drawn");
-			},
-			onDraw:function(){
-				for(var i = 0; i < this.rowCount; i++){
-					if((!this.dirty && this.array[i][this.checkboxIndex].get("checked")) || (this.dirty && this.array[i][this.statusIndex].innerHTML=="Drawn")){
-						this.drawOne(i);
-					}else{
-						this.array[i][this.chartIndex].resize(this.graphWidth.get("value"), this.graphHeight.get("value"));
-						this.array[i][this.chartIndex].axes["x"].max = this.graphMaxX.get('value');
+					var func;
+					var yEquals = (this.array[i][this.functionMode]=="y=");
+					if(this.array[i][this.expressionIndex].get("value")!=this.array[i][this.evaluatedExpression]){
+						var args = 'x';
+						if(!yEquals){
+							args = 'y';
+						}
+						func = that.executor.Function('', args, "return "+this.array[i][this.expressionIndex].get('value'));
+						this.array[i][this.evaluatedExpression] = this.array[i][this.expressionIndex].value;
+						this.array[i][this.functionRef] = func;
+					}
+					else{
+						func = this.array[i][this.functionRef];
+					}
+					var pickedColor = this.array[i][this.colorIndex].get("value");
+					if(!pickedColor){
+						pickedColor = 'black';
+					}
+					calc.draw(this.array[i][this.chartIndex], func, {graphNumber:this.array[i][this.funcNumberIndex], fOfX:yEquals, color:{stroke:{color:pickedColor}}});
+					this.setStatus(i, "Drawn");
+				},
+				onDraw:function(){
+					for(var i = 0; i < this.rowCount; i++){
+						if((!this.dirty && this.array[i][this.checkboxIndex].get("checked")) || (this.dirty && this.array[i][this.statusIndex].innerHTML=="Drawn")){
+							this.drawOne(i);
+						}else{
+							this.array[i][this.chartIndex].resize(this.graphWidth.get("value"), this.graphHeight.get("value"));
+							this.array[i][this.chartIndex].axes["x"].max = this.graphMaxX.get('value');
+						}
 					}
-				}
-
-				var bufferY = dojo.position(this.outerDiv).y-dojo.position(this.myPane.domNode).y;
-				bufferY*=2;
-				bufferY=Math.abs(bufferY);
-				var height = "" + Math.max(parseInt(this.graphHeight.get('value'))+50, this.outerDiv.scrollHeight+bufferY);
-				var width = "" + (parseInt(this.graphWidth.get('value')) + this.outerDiv.scrollWidth);
-				this.myPane.resize({w:width, h:height});
-			}
-		}, d);
-		this.aFloatingPane.set('content', this.grapher);
-		this.aFloatingPane.startup();
-		this.aFloatingPane.bringToTop();
-	}
-});
-
 
-return dojox.calc.GraphPro;
+					var bufferY = domGeometry.position(this.outerDiv).y-domGeometry.position(this.myPane.domNode).y;
+					bufferY*=2;
+					bufferY=Math.abs(bufferY);
+					var height = "" + Math.max(parseInt(this.graphHeight.get('value'))+50, this.outerDiv.scrollHeight+bufferY);
+					var width = "" + (parseInt(this.graphWidth.get('value')) + this.outerDiv.scrollWidth);
+					this.myPane.resize({w:width, h:height});
+				}
+			}, d);
+			this.aFloatingPane.set('content', this.grapher);
+			this.aFloatingPane.startup();
+			this.aFloatingPane.bringToTop();
+		}
+	});
 });
diff --git a/dojox/calc/Grapher.js b/dojox/calc/Grapher.js
index ff270b0..9ada5bd 100644
--- a/dojox/calc/Grapher.js
+++ b/dojox/calc/Grapher.js
@@ -1,315 +1,32 @@
-define("dojox/calc/Grapher", ["dojo", "dijit/_Templated", "dojox/math/_base", "dijit/dijit", "dijit/form/DropDownButton", "dijit/TooltipDialog", "dijit/form/TextBox", "dijit/form/Button", "dijit/form/ComboBox", "dijit/form/Select", "dijit/form/CheckBox", "dijit/ColorPalette", "dojox/charting/Chart2D", "dojox/charting/themes/Tufte", "dojo/colors"], function(dojo) {
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/dom-construct",
+	"dojo/dom-class",
+	"dojo/dom-style",
+	"dijit/_WidgetBase",
+	"dijit/_WidgetsInTemplateMixin",
+	"dijit/_TemplatedMixin",
+	"dojox/math/_base",
+	"dijit/registry",
+	"dijit/form/DropDownButton",
+	"dijit/TooltipDialog",
+	"dijit/form/TextBox",
+	"dijit/form/CheckBox",
+	"dijit/ColorPalette",
+	"dojox/charting/Chart",
+	"dojox/charting/axis2d/Default",
+	"dojox/charting/plot2d/Default",
+	"dojox/charting/plot2d/Lines",
+	"dojox/charting/themes/Tufte",
+	"dojo/colors",
+	"dojo/text!./templates/Grapher.html",
+	"dojox/calc/_Executor",
+	"dijit/form/Button", // template
+	"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){
 
-dojo.experimental("dojox.calc.Grapher");
-
-dojo.declare(
-	"dojox.calc.Grapher",
-	[dijit._Widget, dijit._Templated],
-{
-	// summary:
-	//		The dialog layout for making graphs
-	//
-	templateString: dojo.cache("dojox.calc", "templates/Grapher.html"),
-
-	widgetsInTemplate:true,
-
-	addXYAxes: function(chart){
-		// summary:
-		//		add or re-add the default x/y axes to the Chart2D provided
-		// params:
-		//	chart is an instance of dojox.charting.Chart2D
-
-		return chart.addAxis("x", {
-			max: parseInt(this.graphMaxX.get("value")),
-			min: parseInt(this.graphMinX.get("value")),
-			majorLabels: true,
-			minorLabels: true,
-			//includeZero: true,
-			minorTicks: false,
-			microTicks: false,
-			//majorTickStep: 1,
-			htmlLabels: true,
-			labelFunc: function(value){
-				return value;
-			},
-			maxLabelSize: 30,
-			fixUpper: "major", fixLower: "major",
-			majorTick: { length: 3 }
-		}).
-		addAxis("y", {
-			max: parseInt(this.graphMaxY.get("value")),
-			min: parseInt(this.graphMinY.get("value")),
-			labelFunc: function(value){
-				return value;
-			},
-			maxLabelSize: 50,
-			vertical: true,
-			// htmlLabels: false,
-			microTicks: false,
-			minorTicks: true,
-			majorTick: { stroke: "black", length: 3 }
-		});
-	},
-	selectAll: function(){
-		// 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
-		for(var i = 0; i < this.rowCount; i++){
-			this.array[i][this.checkboxIndex].set("checked", false);
-		}
-	},
-	drawOne: function(i){
-		// i is a the index to this.array
-		// override me
-	},
-	onDraw: function(){
-		console.log("Draw was pressed");
-		// override me
-	},
-	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
-		var nameNum = 0;
-		var name = "Series "+this.array[i][this.funcNumberIndex]+"_"+nameNum;
-		while(name in this.array[i][this.chartIndex].runs){
-			this.array[i][this.chartIndex].removeSeries(name);
-			nameNum++;
-			name = "Series "+this.array[i][this.funcNumberIndex]+"_"+nameNum;
-		}
-		this.array[i][this.chartIndex].render();
-		this.setStatus(i, "Hidden");
-	},
-	onErase: function(){
-		// summary:
-		//	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);
-			}
-		}
-	},
-	onDelete: function(){
-		// summary:
-		//	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);
-				for(var k = 0; k < this.functionRef; k++){
-					if(this.array[i][k] && this.array[i][k]["destroy"]){
-						this.array[i][k].destroy();
-					}
-				}
-				this.graphTable.deleteRow(i);
-				this.array.splice(i, 1);
-				this.rowCount--;
-				i--;
-			}
-		}
-	},
-	// attributes to name the indices of this.array
-	checkboxIndex:		0,
-	functionMode:		1,
-	expressionIndex:	2,
-	colorIndex:		3,
-	dropDownIndex:		4,
-	tooltipIndex:		5,
-	colorBoxFieldsetIndex:	6,
-	statusIndex:		7,
-	chartIndex:		8,
-	funcNumberIndex:	9,
-	evaluatedExpression:	10,
-	functionRef:		11,
-
-	createFunction: function(){
-		// summary:
-		//	create a new row in the table with all of the dojo objects.
-
-		var tr = this.graphTable.insertRow(-1);
-		this.array[tr.rowIndex] = [];
-		var td = tr.insertCell(-1);
-		var d = dojo.create('div');
-		td.appendChild(d);
-		var checkBox = new dijit.form.CheckBox({}, d);
-		this.array[tr.rowIndex][this.checkboxIndex] = checkBox;
-		dojo.addClass(d, "dojoxCalcCheckBox");
-
-		td = tr.insertCell(-1);
-		var funcMode = this.funcMode.get("value");
-		d = dojo.doc.createTextNode(funcMode);
-		td.appendChild(d);
-		this.array[tr.rowIndex][this.functionMode] = funcMode;
-		//dojo.addClass(d, "dojoxCalcFunctionMode");// cannot use text nodes
-
-		td = tr.insertCell(-1);
-		d = dojo.create('div');
-		td.appendChild(d);
-		var expression = new dijit.form.TextBox({}, d);
-		this.array[tr.rowIndex][this.expressionIndex] = expression;
-		dojo.addClass(d, "dojoxCalcExpressionBox");
-
-		var b = dojo.create('div');
-		var color = new dijit.ColorPalette({changedColor:this.changedColor}, b);
-		dojo.addClass(b, "dojoxCalcColorPalette");
-
-		this.array[tr.rowIndex][this.colorIndex] = color;
-
-		var c = dojo.create('div');
-		var dialog = new dijit.TooltipDialog({content:color}, c);
-		this.array[tr.rowIndex][this.tooltipIndex] = dialog;
-		dojo.addClass(c, "dojoxCalcContainerOfColor");
-
-		td = tr.insertCell(-1);
-		d = dojo.create('div');
-		td.appendChild(d);
-
-		var colorBoxFieldset = dojo.create('fieldset');
-		dojo.style(colorBoxFieldset, {backgroundColor: "black", width: "1em", height: "1em", display: "inline"});
-		this.array[tr.rowIndex][this.colorBoxFieldsetIndex] = colorBoxFieldset;
-
-		var drop = new dijit.form.DropDownButton({label:"Color ", dropDown:dialog}, d);
-		drop.containerNode.appendChild(colorBoxFieldset);
-		this.array[tr.rowIndex][this.dropDownIndex] = drop;
-		dojo.addClass(d, "dojoxCalcDropDownForColor");
-
-		/*td = tr.insertCell(-1);
-		d = dojo.create('div');
-		td.appendChild(d);
-		var status = new dijit.form.TextBox({style:"width:50px", value:"Hidden", readOnly:true}, d);//hidden, drawn, or error
-		this.array[tr.rowIndex][this.statusIndex] = status;
-		dojo.addClass(d, "dojoxCalcStatusBox");*/
-
-		td = tr.insertCell(-1);
-		d = dojo.create('fieldset');
-		d.innerHTML = "Hidden";
-		this.array[tr.rowIndex][this.statusIndex] = d;
-		dojo.addClass(d, "dojoxCalcStatusBox");
-		td.appendChild(d);
-
-		d = dojo.create('div');
-		dojo.style(d, {position:"absolute", left:"0px", top:"0px"})
-		this.chartsParent.appendChild(d);
-		this.array[tr.rowIndex][this.chartNodeIndex] = d;
-		dojo.addClass(d, "dojoxCalcChart");
-		var chart = new dojox.charting.Chart2D(d).setTheme(dojox.charting.themes.Tufte).
-			addPlot("default", { type: "Lines", shadow:  {dx: 1, dy: 1, width: 2, color: [0, 0, 0, 0.3]} });
-		this.addXYAxes(chart);
-		this.array[tr.rowIndex][this.chartIndex] = chart;
-		color.set("chart", chart);
-		color.set("colorBox", colorBoxFieldset);
-		color.set("onChange", dojo.hitch(color, 'changedColor'));
-
-		this.array[tr.rowIndex][this.funcNumberIndex] = this.funcNumber++;
-		this.rowCount++;
-	},
-	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
-		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
-		var chart = this.get("chart");
-		var colorBoxFieldset = this.get("colorBox");
-		for(var i = 0; i < chart.series.length; i++){
-			if(chart.series[i]["stroke"]){
-				if(chart.series[i].stroke["color"]){
-					chart.series[i]["stroke"].color = this.get("value");
-					chart.dirty = true;
-				}
-			}
-		}
-		chart.render();
-		dojo.style(colorBoxFieldset, {backgroundColor:this.get("value")});
-	},
-	makeDirty: function(){
-		// summary:
-		//	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
-		setTimeout(dojo.hitch(this, 'checkDirty'), 0);
-	},
-	checkDirty: function(){
-		// summary:
-		//	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++){
-				this.array[i][this.chartIndex].removeAxis("x");
-				this.array[i][this.chartIndex].removeAxis("y");
-				this.addXYAxes(this.array[i][this.chartIndex]);
-			}
-			this.onDraw();
-		}
-		this.dirty = false;
-	},
-	postCreate: function(){
-		// summary
-		//	add Event handlers, some additional attributes, etc
-		this.inherited(arguments);// this is super class postCreate
-		this.createFunc.set("onClick", dojo.hitch(this, 'createFunction'));
-
-		this.selectAllButton.set("onClick", dojo.hitch(this, 'selectAll'));
-		this.deselectAllButton.set("onClick", dojo.hitch(this, 'deselectAll'));
-
-		this.drawButton.set("onClick", dojo.hitch(this, 'onDraw'));
-		this.eraseButton.set("onClick", dojo.hitch(this, 'onErase'));
-		this.deleteButton.set("onClick", dojo.hitch(this, 'onDelete'));
-
-		this.dirty = false;
-		this.graphWidth.set("onChange", dojo.hitch(this, 'makeDirty'));
-		this.graphHeight.set("onChange", dojo.hitch(this, 'makeDirty'));
-		this.graphMaxX.set("onChange", dojo.hitch(this, 'makeDirty'));
-		this.graphMinX.set("onChange", dojo.hitch(this, 'makeDirty'));
-		this.graphMaxY.set("onChange", dojo.hitch(this, 'makeDirty'));
-		this.graphMinY.set("onChange", dojo.hitch(this, 'makeDirty'));
-		this.windowOptionsInside.set("onClose", dojo.hitch(this, 'checkDirty1'));
-
-		this.funcNumber = 0;
-		this.rowCount = 0;
-		this.array = [];
-
-	},
-	startup: function(){
-		// 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 = dijit.getEnclosingWidget(this.domNode.parentNode);
-		if(parent && typeof parent.close == "function"){
-			this.closeButton.set("onClick", dojo.hitch(parent, 'close'));
-		}else{
-			dojo.style(this.closeButton.domNode, "display", "none"); // hide the button
-		}
-		// add one row at the start
-		this.createFunction();
-
-		// make the graph bounds appear initially
-		this.array[0][this.checkboxIndex].set("checked", true);
-		this.onDraw();
-		this.erase(0);
-		this.array[0][this.expressionIndex].value = "";
-	}
-});
-
-(function(){
 	// summary
 	//	provide static functions for Grapher
 	var
@@ -318,306 +35,616 @@ dojo.declare(
 		log2 = Math.log(2),
 		defaultParams = {graphNumber:0, fOfX:true, color:{stroke:"black"}};
 
-	dojox.calc.Grapher.draw = function(/*Chart2D*/ chart, /*Function*/ functionToGraph, params){
-		// summary
-		//	graph a chart with the given function.
-		// params
-		//	chart is a dojox.charting.Chart2D 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"}
-
-		params = dojo.mixin({}, defaultParams, params);
-		chart.fullGeometry();
-		var x;
-		var y;
-		var points;
-		if(params.fOfX==true){
-			x = 'x';
-			y = 'y';
-			points = dojox.calc.Grapher.generatePoints(functionToGraph, x, y, chart.axes.x.scaler.bounds.span, chart.axes.x.scaler.bounds.lower, chart.axes.x.scaler.bounds.upper, chart.axes.y.scaler.bounds.lower, chart.axes.y.scaler.bounds.upper);
-		}else{
-			x = 'y';
-			y = 'x';
-			points = dojox.calc.Grapher.generatePoints(functionToGraph, x, y, chart.axes.y.scaler.bounds.span, chart.axes.y.scaler.bounds.lower, chart.axes.y.scaler.bounds.upper, chart.axes.x.scaler.bounds.lower, chart.axes.x.scaler.bounds.upper);
-		}
-
-		var i = 0;
-
-		if(points.length > 0){
-			for(; i < points.length; i++){
-				if(points[i].length>0){
-					chart.addSeries("Series "+params.graphNumber+"_"+i, points[i], params.color);
-				}
-			}
-		}
-		// you only need to remove the excess i's
-		var name = "Series "+params.graphNumber+"_"+i;
-		while(name in chart.runs){
-			chart.removeSeries(name);
-			i++;
-			name = "Series "+params.graphNumber+"_"+i;
-		}
-		chart.render();
-		return points;
-	}
 
-	dojox.calc.Grapher.generatePoints = function(/*Function*/ funcToGraph, /*String*/ x, /*String*/ y, /*Number*/ width, /*Number*/ minX, /*Number*/ maxX, /*Number*/ minY, /*Number*/ maxY){
+	/*=====
+		WidgetBase = dijit._WidgetBase;
+		WidgetsInTemplateMixin = dijit._WidgetsInTemplateMixin;
+		TemplatedMixin = dijit._TemplatedMixin;
+	=====*/
+	var Grapher = declare(
+		"dojox.calc.Grapher",
+		[WidgetBase, TemplatedMixin, WidgetsInTemplateMixin],
+	{
 		// 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
-		// output:
-		//	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
-			points = [], // [{x:value, y:value2},...]
-			series = 0,
-			slopeTrend,
-			slopeTrendTemp;
-
-		points[series] = [];
-
-		var i = minX, k, p;
-		for(var counter = 0; counter <= pow2; i += dx, counter++){
-			p = {};
-			p[x] = i;
-			p[y] = funcToGraph({_name:x, _value:i, _graphing:true});//funcToGraph(i);
-			if(p[x] == null || p[y] == null){
-				return {};// someone pushed cancel in the val code
+		//		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
+
+			return chart.addAxis("x", {
+				max: parseInt(this.graphMaxX.get("value")),
+				min: parseInt(this.graphMinX.get("value")),
+				majorLabels: true,
+				minorLabels: true,
+				//includeZero: true,
+				minorTicks: false,
+				microTicks: false,
+				//majorTickStep: 1,
+				htmlLabels: true,
+				labelFunc: function(value){
+					return value;
+				},
+				maxLabelSize: 30,
+				fixUpper: "major", fixLower: "major",
+				majorTick: { length: 3 }
+			}).
+			addAxis("y", {
+				max: parseInt(this.graphMaxY.get("value")),
+				min: parseInt(this.graphMinY.get("value")),
+				labelFunc: function(value){
+					return value;
+				},
+				maxLabelSize: 50,
+				vertical: true,
+				// htmlLabels: false,
+				microTicks: false,
+				minorTicks: true,
+				majorTick: { stroke: "black", length: 3 }
+			});
+		},
+		selectAll: function(){
+			// summary
+			//	select all checkboxes inside the function table
+			for(var i = 0; i < this.rowCount; i++){
+				this.array[i][this.checkboxIndex].set("checked", true);
 			}
-			if(isNaN(p[y]) || isNaN(p[x])){
-				continue;
+		},
+		deselectAll: function(){
+			// summary
+			//	deselect all checkboxes inside the function table
+			for(var i = 0; i < this.rowCount; i++){
+				this.array[i][this.checkboxIndex].set("checked", false);
 			}
-			points[series].push(p);
-
-			if(points[series].length == 3){
-				slopeTrend = getSlopePairTrend(slope(points[series][points[series].length - 3], points[series][points[series].length-2]), slope(points[series][points[series].length-2], points[series][points[series].length-1]));
-				continue;
+		},
+		drawOne: function(i){
+			// i is a the index to this.array
+			// override me
+		},
+		onDraw: function(){
+			console.log("Draw was pressed");
+			// override me
+		},
+		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
+			var nameNum = 0;
+			var name = "Series "+this.array[i][this.funcNumberIndex]+"_"+nameNum;
+			while(name in this.array[i][this.chartIndex].runs){
+				this.array[i][this.chartIndex].removeSeries(name);
+				nameNum++;
+				name = "Series "+this.array[i][this.funcNumberIndex]+"_"+nameNum;
 			}
-			if(points[series].length < 4){
-				continue;
+			this.array[i][this.chartIndex].render();
+			this.setStatus(i, "Hidden");
+		},
+		onErase: function(){
+			// summary:
+			//	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);
+				}
 			}
-
-			slopeTrendTemp = getSlopePairTrend(slope(points[series][points[series].length - 3], points[series][points[series].length-2]), slope(points[series][points[series].length-2], points[series][points[series].length-1]));
-			if(slopeTrend.inc != slopeTrendTemp.inc || slopeTrend.pos != slopeTrendTemp.pos){
-				// var a = asymptoteSearch(funcToGraph, points[series][points[series].length - 2], points[series][points[series].length-1]);
-				var a = asymptoteSearch(funcToGraph, points[series][points[series].length - 3], points[series][points[series].length-1]);
-				p = points[series].pop();
-				// this pop was added after changing the var a line above
-				points[series].pop();
-				for(var j = 0; j < a[0].length; j++){
-					points[series].push(a[0][j]);
+		},
+		onDelete: function(){
+			// summary:
+			//	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);
+					for(var k = 0; k < this.functionRef; k++){
+						if(this.array[i][k] && this.array[i][k]["destroy"]){
+							this.array[i][k].destroy();
+						}
+					}
+					this.graphTable.deleteRow(i);
+					this.array.splice(i, 1);
+					this.rowCount--;
+					i--;
 				}
-				for(k = 1; k < a.length; k++){
-					points[++series] = a.pop();
+			}
+		},
+		// attributes to name the indices of this.array
+		checkboxIndex:		0,
+		functionMode:		1,
+		expressionIndex:	2,
+		colorIndex:		3,
+		dropDownIndex:		4,
+		tooltipIndex:		5,
+		colorBoxFieldsetIndex:	6,
+		statusIndex:		7,
+		chartIndex:		8,
+		funcNumberIndex:	9,
+		evaluatedExpression:	10,
+		functionRef:		11,
+
+		createFunction: function(){
+			// summary:
+			//	create a new row in the table with all of the dojo objects.
+
+			var tr = this.graphTable.insertRow(-1);
+			this.array[tr.rowIndex] = [];
+			var td = tr.insertCell(-1);
+			var d = domConstruct.create('div');
+			td.appendChild(d);
+			var checkBox = new CheckBox({}, d);
+			this.array[tr.rowIndex][this.checkboxIndex] = checkBox;
+			domClass.add(d, "dojoxCalcCheckBox");
+
+			td = tr.insertCell(-1);
+			var funcMode = this.funcMode.get("value");
+			d = win.doc.createTextNode(funcMode);
+			td.appendChild(d);
+			this.array[tr.rowIndex][this.functionMode] = funcMode;
+			//domClass.add(d, "dojoxCalcFunctionMode");// cannot use text nodes
+
+			td = tr.insertCell(-1);
+			d = domConstruct.create('div');
+			td.appendChild(d);
+			var expression = new TextBox({}, d);
+			this.array[tr.rowIndex][this.expressionIndex] = expression;
+			domClass.add(d, "dojoxCalcExpressionBox");
+
+			var b = domConstruct.create('div');
+			var color = new ColorPalette({changedColor:this.changedColor}, b);
+			domClass.add(b, "dojoxCalcColorPalette");
+
+			this.array[tr.rowIndex][this.colorIndex] = color;
+
+			var c = domConstruct.create('div');
+			var dialog = new TooltipDialog({content:color}, c);
+			this.array[tr.rowIndex][this.tooltipIndex] = dialog;
+			domClass.add(c, "dojoxCalcContainerOfColor");
+
+			td = tr.insertCell(-1);
+			d = domConstruct.create('div');
+			td.appendChild(d);
+
+			var colorBoxFieldset = domConstruct.create('fieldset');
+			domStyle.set(colorBoxFieldset, { backgroundColor: "black", width: "1em", height: "1em", display: "inline" });
+			this.array[tr.rowIndex][this.colorBoxFieldsetIndex] = colorBoxFieldset;
+
+			var drop = new DropDownButton({label:"Color ", dropDown:dialog}, d);
+			drop.containerNode.appendChild(colorBoxFieldset);
+			this.array[tr.rowIndex][this.dropDownIndex] = drop;
+			domClass.add(d, "dojoxCalcDropDownForColor");
+
+			/*td = tr.insertCell(-1);
+			d = domConstruct.create('div');
+			td.appendChild(d);
+			var status = new TextBox({style:"width:50px", value:"Hidden", readOnly:true}, d);//hidden, drawn, or error
+			this.array[tr.rowIndex][this.statusIndex] = status;
+			domClass.add(d, "dojoxCalcStatusBox");*/
+
+			td = tr.insertCell(-1);
+			d = domConstruct.create('fieldset');
+			d.innerHTML = "Hidden";
+			this.array[tr.rowIndex][this.statusIndex] = d;
+			domClass.add(d, "dojoxCalcStatusBox");
+			td.appendChild(d);
+
+			d = domConstruct.create('div');
+			domStyle.set(d, { position: "absolute", left: "0px", top: "0px" })
+			this.chartsParent.appendChild(d);
+			this.array[tr.rowIndex][this.chartNodeIndex] = d;
+			domClass.add(d, "dojoxCalcChart");
+			var chart = new dojox.charting.Chart(d).setTheme(dojox.charting.themes.Tufte).
+				addPlot("default", { type: "Lines", shadow:  {dx: 1, dy: 1, width: 2, color: [0, 0, 0, 0.3]} });
+			this.addXYAxes(chart);
+			this.array[tr.rowIndex][this.chartIndex] = chart;
+			color.set("chart", chart);
+			color.set("colorBox", colorBoxFieldset);
+			color.set("onChange", lang.hitch(color, 'changedColor'));
+
+			this.array[tr.rowIndex][this.funcNumberIndex] = this.funcNumber++;
+			this.rowCount++;
+		},
+		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
+			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
+			var chart = this.get("chart");
+			var colorBoxFieldset = this.get("colorBox");
+			for(var i = 0; i < chart.series.length; i++){
+				if(chart.series[i]["stroke"]){
+					if(chart.series[i].stroke["color"]){
+						chart.series[i]["stroke"].color = this.get("value");
+						chart.dirty = true;
+					}
 				}
-				points[series].push(p);
-				slopeTrend = slopeTrendTemp;
 			}
-		}
-		while(points.length > 1){
-			for(k = 0; k < points[1].length; k++){
-				if(points[0][points[0].length - 1][x] == points[1][k][x]){
-					continue;
+			chart.render();
+			domStyle.set(colorBoxFieldset, { backgroundColor: this.get("value") });
+		},
+		makeDirty: function(){
+			// summary:
+			//	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
+			setTimeout(lang.hitch(this, 'checkDirty'), 0);
+		},
+		checkDirty: function(){
+			// summary:
+			//	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++){
+					this.array[i][this.chartIndex].removeAxis("x");
+					this.array[i][this.chartIndex].removeAxis("y");
+					this.addXYAxes(this.array[i][this.chartIndex]);
 				}
-				points[0].push(points[1][k]);
+				this.onDraw();
 			}
-			points.splice(1, 1);
+			this.dirty = false;
+		},
+		postCreate: function(){
+			// summary
+			//	add Event handlers, some additional attributes, etc
+			this.inherited(arguments);// this is super class postCreate
+			this.createFunc.set("onClick", lang.hitch(this, 'createFunction'));
+
+			this.selectAllButton.set("onClick", lang.hitch(this, 'selectAll'));
+			this.deselectAllButton.set("onClick", lang.hitch(this, 'deselectAll'));
+
+			this.drawButton.set("onClick", lang.hitch(this, 'onDraw'));
+			this.eraseButton.set("onClick", lang.hitch(this, 'onErase'));
+			this.deleteButton.set("onClick", lang.hitch(this, 'onDelete'));
+
+			this.dirty = false;
+			this.graphWidth.set("onChange", lang.hitch(this, 'makeDirty'));
+			this.graphHeight.set("onChange", lang.hitch(this, 'makeDirty'));
+			this.graphMaxX.set("onChange", lang.hitch(this, 'makeDirty'));
+			this.graphMinX.set("onChange", lang.hitch(this, 'makeDirty'));
+			this.graphMaxY.set("onChange", lang.hitch(this, 'makeDirty'));
+			this.graphMinY.set("onChange", lang.hitch(this, 'makeDirty'));
+			this.windowOptionsInside.set("onClose", lang.hitch(this, 'checkDirty1'));
+
+			this.funcNumber = 0;
+			this.rowCount = 0;
+			this.array = [];
+
+		},
+		startup: function(){
+			// 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);
+			if(parent && typeof parent.close == "function"){
+				this.closeButton.set("onClick", lang.hitch(parent, 'close'));
+			}else{
+				domStyle.set(this.closeButton.domNode, { display: "none" }); // hide the button
+			}
+			// add one row at the start
+			this.createFunction();
+
+			// make the graph bounds appear initially
+			this.array[0][this.checkboxIndex].set("checked", true);
+			this.onDraw();
+			this.erase(0);
+			this.array[0][this.expressionIndex].value = "";
 		}
-		points = points[0];
-
-		// make new series when it goes off the graph
-		var s = 0;
-		var points2 = [ [] ];
-		for(k = 0; k < points.length; k++){
-			var x1, y1, b, slope1;
-			if(isNaN(points[k][y]) || isNaN(points[k][x])){
-				while(isNaN(points[k][y]) || isNaN(points[k][x])){
-					points.splice(k, 1);
-				}
-				points2[++s] = [];
-				k--;
-			}else if(points[k][y] > maxY || points[k][y] < minY){
-				// make the last point's y equal maxY and find a matching x
-				if(k > 0 && points[k - 1].y!=minY && points[k - 1].y!=maxY){
-					slope1 = slope(points[k - 1], points[k]);
-					if(slope1 > bigNumber){
-						slope1 = bigNumber;
-					}else if(slope1 < -bigNumber){
-						slope1 = -bigNumber;
-					}
-					if(points[k][y] > maxY){
-						y1 = maxY;
-					}else{
-						y1 = minY;
-					}
-					b = points[k][y] - slope1 * points[k][x];
-					x1 = (y1 - b) / slope1;
+	});
+
+	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"}
+
+			params = lang.mixin({}, defaultParams, params);
+			chart.fullGeometry();
+			var x;
+			var y;
+			var points;
+			if(params.fOfX==true){
+				x = 'x';
+				y = 'y';
+				points = calc.generatePoints(functionToGraph, x, y, chart.axes.x.scaler.bounds.span, chart.axes.x.scaler.bounds.lower, chart.axes.x.scaler.bounds.upper, chart.axes.y.scaler.bounds.lower, chart.axes.y.scaler.bounds.upper);
+			}else{
+				x = 'y';
+				y = 'x';
+				points = calc.generatePoints(functionToGraph, x, y, chart.axes.y.scaler.bounds.span, chart.axes.y.scaler.bounds.lower, chart.axes.y.scaler.bounds.upper, chart.axes.x.scaler.bounds.lower, chart.axes.x.scaler.bounds.upper);
+			}
 
-					p = {};
-					p[x] = x1;
-					p[y] = funcToGraph(x1);//y1;//
+			var i = 0;
 
-					if(p[y]!=y1){
-						p = findMinOrMaxY(funcToGraph, points[k - 1], points[k], y1);
+			if(points.length > 0){
+				for(; i < points.length; i++){
+					if(points[i].length>0){
+						chart.addSeries("Series "+params.graphNumber+"_"+i, points[i], params.color);
 					}
+				}
+			}
+			// you only need to remove the excess i's
+			var name = "Series "+params.graphNumber+"_"+i;
+			while(name in chart.runs){
+				chart.removeSeries(name);
+				i++;
+				name = "Series "+params.graphNumber+"_"+i;
+			}
+			chart.render();
+			return points;
+		},
+
+		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
+			// output:
+			//	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
+				points = [], // [{x:value, y:value2},...]
+				series = 0,
+				slopeTrend,
+				slopeTrendTemp;
+
+			points[series] = [];
+
+			var i = minX, k, p;
+			for(var counter = 0; counter <= pow2; i += dx, counter++){
+				p = {};
+				p[x] = i;
+				p[y] = funcToGraph({_name:x, _value:i, _graphing:true});//funcToGraph(i);
+				if(p[x] == null || p[y] == null){
+					return {};// someone pushed cancel in the val code
+				}
+				if(isNaN(p[y]) || isNaN(p[x])){
+					continue;
+				}
+				points[series].push(p);
 
-					points2[s].push(p);
-					// setup the next series
-					points2[++s] = []
+				if(points[series].length == 3){
+					slopeTrend = getSlopePairTrend(slope(points[series][points[series].length - 3], points[series][points[series].length-2]), slope(points[series][points[series].length-2], points[series][points[series].length-1]));
+					continue;
 				}
-				var startK = k;
-				while(k < points.length && (points[k][y] > maxY || points[k][y] < minY)){
-					k++;
+				if(points[series].length < 4){
+					continue;
 				}
-				if(k >= points.length){
-					if(points2[s].length == 0){
-						points2.splice(s, 1);
+
+				slopeTrendTemp = getSlopePairTrend(slope(points[series][points[series].length - 3], points[series][points[series].length-2]), slope(points[series][points[series].length-2], points[series][points[series].length-1]));
+				if(slopeTrend.inc != slopeTrendTemp.inc || slopeTrend.pos != slopeTrendTemp.pos){
+					// var a = asymptoteSearch(funcToGraph, points[series][points[series].length - 2], points[series][points[series].length-1]);
+					var a = asymptoteSearch(funcToGraph, points[series][points[series].length - 3], points[series][points[series].length-1]);
+					p = points[series].pop();
+					// this pop was added after changing the var a line above
+					points[series].pop();
+					for(var j = 0; j < a[0].length; j++){
+						points[series].push(a[0][j]);
 					}
-					break;
+					for(k = 1; k < a.length; k++){
+						points[++series] = a.pop();
+					}
+					points[series].push(p);
+					slopeTrend = slopeTrendTemp;
 				}
-				// connect the end graph
-				if(k > 0 && points[k].y != minY && points[k].y != maxY){
-					slope1 = slope(points[k - 1], points[k]);
-					if(slope1 > bigNumber){
-						slope1 = bigNumber;
-					}else if(slope1 < -bigNumber){
-						slope1 = -bigNumber;
+			}
+			while(points.length > 1){
+				for(k = 0; k < points[1].length; k++){
+					if(points[0][points[0].length - 1][x] == points[1][k][x]){
+						continue;
 					}
-					if(points[k - 1][y] > maxY){
-						y1 = maxY;
-					}else{
-						y1 = minY;
+					points[0].push(points[1][k]);
+				}
+				points.splice(1, 1);
+			}
+			points = points[0];
+
+			// make new series when it goes off the graph
+			var s = 0;
+			var points2 = [ [] ];
+			for(k = 0; k < points.length; k++){
+				var x1, y1, b, slope1;
+				if(isNaN(points[k][y]) || isNaN(points[k][x])){
+					while(isNaN(points[k][y]) || isNaN(points[k][x])){
+						points.splice(k, 1);
+					}
+					points2[++s] = [];
+					k--;
+				}else if(points[k][y] > maxY || points[k][y] < minY){
+					// make the last point's y equal maxY and find a matching x
+					if(k > 0 && points[k - 1].y!=minY && points[k - 1].y!=maxY){
+						slope1 = slope(points[k - 1], points[k]);
+						if(slope1 > bigNumber){
+							slope1 = bigNumber;
+						}else if(slope1 < -bigNumber){
+							slope1 = -bigNumber;
+						}
+						if(points[k][y] > maxY){
+							y1 = maxY;
+						}else{
+							y1 = minY;
+						}
+						b = points[k][y] - slope1 * points[k][x];
+						x1 = (y1 - b) / slope1;
+
+						p = {};
+						p[x] = x1;
+						p[y] = funcToGraph(x1);//y1;//
+
+						if(p[y]!=y1){
+							p = findMinOrMaxY(funcToGraph, points[k - 1], points[k], y1);
+						}
+
+						points2[s].push(p);
+						// setup the next series
+						points2[++s] = []
+					}
+					var startK = k;
+					while(k < points.length && (points[k][y] > maxY || points[k][y] < minY)){
+						k++;
+					}
+					if(k >= points.length){
+						if(points2[s].length == 0){
+							points2.splice(s, 1);
+						}
+						break;
 					}
-					b = points[k][y] - slope1 * points[k][x];
-					x1 = (y1 - b) / slope1;
-
-					p = {};
-					p[x] = x1;
-					p[y] = funcToGraph(x1);//y1;//
-					if(p[y]!=y1){
-						p = findMinOrMaxY(funcToGraph, points[k - 1], points[k], y1);
+					// connect the end graph
+					if(k > 0 && points[k].y != minY && points[k].y != maxY){
+						slope1 = slope(points[k - 1], points[k]);
+						if(slope1 > bigNumber){
+							slope1 = bigNumber;
+						}else if(slope1 < -bigNumber){
+							slope1 = -bigNumber;
+						}
+						if(points[k - 1][y] > maxY){
+							y1 = maxY;
+						}else{
+							y1 = minY;
+						}
+						b = points[k][y] - slope1 * points[k][x];
+						x1 = (y1 - b) / slope1;
+
+						p = {};
+						p[x] = x1;
+						p[y] = funcToGraph(x1);//y1;//
+						if(p[y]!=y1){
+							p = findMinOrMaxY(funcToGraph, points[k - 1], points[k], y1);
+						}
+						points2[s].push(p);
+						points2[s].push(points[k]);
 					}
-					points2[s].push(p);
+				}else{
 					points2[s].push(points[k]);
 				}
-			}else{
-				points2[s].push(points[k]);
 			}
-		}
-		return points2;
+			return points2;
 
-		function findMinOrMaxY(funcToGraph, left, right, minMaxY){
+			function findMinOrMaxY(funcToGraph, left, right, minMaxY){
 
-			while(left<=right){
-				var midX = (left[x]+right[x])/2;
-				var mid = {};
-				mid[x] = midX;
-				mid[y] = funcToGraph(mid[x]);
+				while(left<=right){
+					var midX = (left[x]+right[x])/2;
+					var mid = {};
+					mid[x] = midX;
+					mid[y] = funcToGraph(mid[x]);
 
-				if(minMaxY==mid[y]||mid[x]==right[x]||mid[x]==left[x]){
-					return mid;
-				}
-
-				var moveTowardsLarger = true;
-				if(minMaxY<mid[y]){
-					moveTowardsLarger = false;
-				}
+					if(minMaxY==mid[y]||mid[x]==right[x]||mid[x]==left[x]){
+						return mid;
+					}
 
-				if(mid[y]<right[y]){
-					if(moveTowardsLarger){
-						left = mid;
-					}else{
-						right = mid;
+					var moveTowardsLarger = true;
+					if(minMaxY<mid[y]){
+						moveTowardsLarger = false;
 					}
-				}else if(mid[y]<left[y]){
-					if(!moveTowardsLarger){
-						left = mid;
-					}else{
-						right = mid;
+
+					if(mid[y]<right[y]){
+						if(moveTowardsLarger){
+							left = mid;
+						}else{
+							right = mid;
+						}
+					}else if(mid[y]<left[y]){
+						if(!moveTowardsLarger){
+							left = mid;
+						}else{
+							right = mid;
+						}
 					}
 				}
+				return NaN;
 			}
-			return NaN;
-		}
 
-		function asymptoteSearch(funcToGraph, pointStart, pointStop){
-			var
-				pointTemp = [ [], [] ],
-				left = pointStart,
-				right = pointStop,
-				midpoint;
+			function asymptoteSearch(funcToGraph, pointStart, pointStop){
+				var
+					pointTemp = [ [], [] ],
+					left = pointStart,
+					right = pointStop,
+					midpoint;
 
 
-			while(left[x] <= right[x]){
-				var midX = (left[x] + right[x]) / 2;
+				while(left[x] <= right[x]){
+					var midX = (left[x] + right[x]) / 2;
 
-				midpoint = {};
-				midpoint[x] = midX;
-				midpoint[y] = funcToGraph(midX);
+					midpoint = {};
+					midpoint[x] = midX;
+					midpoint[y] = funcToGraph(midX);
 
-				var rx = nextNumber(midpoint[x]);
-				var rightPoint = {};
-				rightPoint[x] = rx;
-				rightPoint[y] = funcToGraph(rx);
+					var rx = nextNumber(midpoint[x]);
+					var rightPoint = {};
+					rightPoint[x] = rx;
+					rightPoint[y] = funcToGraph(rx);
 
-				if(Math.abs(rightPoint[y]) >= Math.abs(midpoint[y])){
-					pointTemp[0].push(midpoint);
-					left = rightPoint;
-				}else{
-					pointTemp[1].unshift(midpoint);
-					if(right[x] == midpoint[x]){
-						break;
+					if(Math.abs(rightPoint[y]) >= Math.abs(midpoint[y])){
+						pointTemp[0].push(midpoint);
+						left = rightPoint;
+					}else{
+						pointTemp[1].unshift(midpoint);
+						if(right[x] == midpoint[x]){
+							break;
+						}
+						right = midpoint;
 					}
-					right = midpoint;
+						
 				}
-					
+				return pointTemp;
 			}
-			return pointTemp;
-		}
 
-		function getSlopePairTrend(slope1, slope2){
-			var
-				isInc = false,
-				isPos = false;
+			function getSlopePairTrend(slope1, slope2){
+				var
+					isInc = false,
+					isPos = false;
 
-			if (slope1 < slope2){
-				isInc = true;
-			}
-			if (slope2 > 0){
-				isPos = true;
+				if(slope1 < slope2){
+					isInc = true;
+				}
+				if(slope2 > 0){
+					isPos = true;
+				}
+				return { inc: isInc, pos: isPos };
 			}
-			return { inc: isInc, pos: isPos };
-		}
 
-		function nextNumber(v){
-			var delta;
-			if(v > -1 && v < 1){
-				if(v < 0){ // special handling as we approach 0
-					if(v >= -epsilon){
-						delta = -v; // always stop at 0
+			function nextNumber(v){
+				var delta;
+				if(v > -1 && v < 1){
+					if(v < 0){ // special handling as we approach 0
+						if(v >= -epsilon){
+							delta = -v; // always stop at 0
+						}else{
+							delta = v / Math.ceil(v / epsilon); // divide distance to 0 into equal tiny chunks
+						}
 					}else{
-						delta = v / Math.ceil(v / epsilon); // divide distance to 0 into equal tiny chunks
+						delta = epsilon;
 					}
 				}else{
-					delta = epsilon;
+					delta = Math.abs(v) * epsilon;
 				}
-			}else{
-				delta = Math.abs(v) * epsilon;
+				return v + delta;
 			}
-			return v + delta;
-		}
-
-		function slope(p1, p2){
-			return (p2[y] - p1[y]) / (p2[x] - p1[x]);
-		}
-	};
-})();
-
 
-return dojox.calc.Grapher;
+			function slope(p1, p2){
+				return (p2[y] - p1[y]) / (p2[x] - p1[x]);
+			}
+		},
+		Grapher: Grapher
+	});
 });
diff --git a/dojox/calc/Standard.js b/dojox/calc/Standard.js
index 30be807..bb3fe72 100644
--- a/dojox/calc/Standard.js
+++ b/dojox/calc/Standard.js
@@ -1,170 +1,156 @@
-define("dojox/calc/Standard", ["dojo", "dijit/_Templated", "dojox/math/_base", "dijit/dijit", "dijit/Menu", "dijit/form/DropDownButton", "dijit/TooltipDialog", "dijit/form/TextBox", "dijit/form/Button", "dojox/calc/_Executor"], function(dojo) {
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/sniff",
+	"dojo/_base/window",
+	"dojo/_base/event",
+	"dojo/dom-style",
+	"dojo/ready",
+	"dojo/keys",
+	"dijit/registry",
+	"dijit/typematic",
+	"dijit/_WidgetBase",
+	"dijit/_WidgetsInTemplateMixin",
+	"dijit/_TemplatedMixin",
+	"dijit/form/_TextBoxMixin",
+	"dojox/math/_base",
+	"dijit/TooltipDialog",
+	"dojo/text!./templates/Standard.html",
+	"dojox/calc/_Executor", // template
+	"dijit/Menu", // template
+	"dijit/MenuItem", // template
+	"dijit/form/ComboButton", // template
+	"dijit/form/Button", // template
+	"dijit/form/TextBox" // template
+], function(declare, lang, has, win, event, domStyle, ready, keys, registry, typematic, WidgetBase, WidgetsInTemplateMixin, TemplatedMixin, _TextBoxMixin, math, TooltipDialog, template, calc){
 
-dojo.experimental("dojox.calc.Standard");
-
-dojo.declare(
-	"dojox.calc.Standard",
-	[dijit._Widget, dijit._Templated],
-{
-	// summary:
-	//		The dialog layout for a standard 4 function/algebraic calculator
-	//
-	templateString: dojo.cache("dojox.calc", "templates/Standard.html"),
+	/*=====
+		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,
-	writeStore:null,
-	functions: [],
+		readStore:null,
+		writeStore:null,
+		functions: [],
 
-	widgetsInTemplate:true,
-	executorLoaded: function(){
-		// summary
-		//	load in the stores after executor is loaded (the stores need executor to be loaded because it parses them)
-		dojo.addOnLoad(dojo.hitch(this, function(){
-			this.loadStore(this.readStore, true);
-			this.loadStore(this.writeStore);
-		}));
-	},
+		executorLoaded: function(){
+			// 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);
+			}));
+		},
 
-	saveFunction: function(name, args, body){
-		// 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;
-	},
+		saveFunction: function(name, args, body){
+			// 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
-		function saveFunctions(items){
-			for(var i = 0; i < items.length; i++){
-				this.saveFunction(items[i].name[0], items[i].args[0], items[i].body[0]);
-			}
-		}
-		function saveReadOnlyFunctions(items){
-			// make the function
-			for(var i = 0; i < items.length; i++){
-				this.executor.normalizedFunction(items[i].name[0], items[i].args[0], items[i].body[0]);
+		loadStore: function(store, isReadOnly){
+			// summary
+			//	load an entire store, and make it publicly editable/viewable based on isReadOnly
+			if(!store){
+				return;
 			}
-		}
-		if(store==null){
-			return;
-		}
-		if(isReadOnly){
-			store.fetch({
-				onComplete: dojo.hitch(this, saveReadOnlyFunctions),
-				onError: function(text){console.error(text)}
-			});
-		}else{
-			store.fetch({
-				onComplete: dojo.hitch(this, saveFunctions),
-				onError: function(text){console.error(text)}
-			});
-		}
-	},
+			store.query({}).forEach(lang.hitch(this, function(item){
+				lang.hitch(this, isReadOnly ? this.executor.normalizedFunction : this.saveFunction)(item.name, item.args, item.body);
+			}));
+		},
 
-	parseTextbox: function(){
-		// 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]);
-			text = this.textboxWidget.textbox.value;
-		}
-		if(text!=""){
-			var ans = this.executor.eval(text);
+		parseTextbox: function(){
+			// 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]);
+				text = this.textboxWidget.textbox.value;
+			}
+			if(text!=""){
+				var ans = this.executor.eval(text);
 
-			if((typeof ans == "number" && isNaN(ans))){
-				if(this.commandList.length == 0 || this.commandList[this.commandList.length - 1] != text){
-					this.commandList.push(text);
+				if((typeof ans == "number" && isNaN(ans))){
+					if(this.commandList.length == 0 || this.commandList[this.commandList.length - 1] != text){
+						this.commandList.push(text);
+					}
+					this.print(text, false);
+					this.print("Not a Number", true);
+				}else if(((typeof ans == "object" && "length" in ans) || typeof ans != "object") && typeof ans != "function" && ans != null){
+					this.executor.eval("Ans="+ans);
+					// add it to the command list as well
+					if(this.commandList.length == 0 || this.commandList[this.commandList.length - 1] != text){
+						this.commandList.push(text);
+					}
+					this.print(text, false);
+					this.print(ans, true);
 				}
-				this.print(text, false);
-				this.print("Not a Number", true);
-			}else if(((typeof ans == "object" && "length" in ans) || typeof ans != "object") && typeof ans != "function" && ans != null){
-				this.executor.eval("Ans="+ans);
-				// add it to the command list as well
-				if(this.commandList.length == 0 || this.commandList[this.commandList.length - 1] != text){
-					this.commandList.push(text);
+				this.commandIndex = this.commandList.length-1;
+				//this.displayBox.textbox.scrollTop=this.displayBox.textbox.scrollHeight;
+				if(this.hasDisplay){
+					this.displayBox.scrollTop=this.displayBox.scrollHeight;
 				}
-				this.print(text, false);
-				this.print(ans, true);
+				//this.clearText();
+				//this.textboxWidget.focus();
+				_TextBoxMixin.selectInputText(this.textboxWidget.textbox);
+
+			}else{
+				this.textboxWidget.focus();
 			}
-			this.commandIndex = this.commandList.length-1;
-			//this.displayBox.textbox.scrollTop=this.displayBox.textbox.scrollHeight;
-			if(this.hasDisplay){
-				this.displayBox.scrollTop=this.displayBox.scrollHeight;
+		},
+		cycleCommands: function(count, node, event){
+			// summary
+			//	cycle through the commands that the user has entered
+			//	it does not wrap around
+			if(count == -1 || this.commandList.length==0){
+				return;
+			}
+			var keyNum = event.charOrCode;
+			//up arrow
+			if(keyNum == keys.UP_ARROW){
+				this.cycleCommandUp();
+			}else if(keyNum == keys.DOWN_ARROW){
+				this.cycleCommandDown();
+			}
+		},
+		cycleCommandUp: function(){
+			// summary
+			//	cycle up through the list of commands the user has entered already
+			if(this.commandIndex-1<0){
+				this.commandIndex=0;
+			}else{
+				this.commandIndex--;
 			}
-			//this.clearText();
-			//this.textboxWidget.focus();
-			dijit.selectInputText(this.textboxWidget.textbox);
-
-		}else{
-			this.textboxWidget.focus();
-		}
-	},
-	cycleCommands: function(count, node, event){
-		// summary
-		//	cycle through the commands that the user has entered
-		//	it does not wrap around
-		if(count == -1 || this.commandList.length==0){
-			return;
-		}
-		var keyNum = event.charOrCode;
-		//up arrow
-		if(keyNum == dojo.keys.UP_ARROW){
-			this.cycleCommandUp();
-		}else if(keyNum == dojo.keys.DOWN_ARROW){
-			this.cycleCommandDown();
-		}
-	},
-	cycleCommandUp: function(){
-		// summary
-		//	cycle up through the list of commands the user has entered already
-		if(this.commandIndex-1<0){
-			this.commandIndex=0;
-		}else{
-			this.commandIndex--;
-		}
-		this.setTextboxValue(this.textboxWidget, this.commandList[this.commandIndex]);
-	},
-	cycleCommandDown: function(){
-		// 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, "");
-		}else{
-			this.commandIndex++;
 			this.setTextboxValue(this.textboxWidget, this.commandList[this.commandIndex]);
-		}
-
-	},
-	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
-		if(dojo.isIE){
-			var tr = dojo.doc.selection.createRange().duplicate();
-			var selectedText = tr.text || '';
-			var ntr = this.textboxWidget.textbox.createTextRange();
-			tr.move("character",0);
-			ntr.move("character",0);
-			try{
-				ntr.setEndPoint("EndToEnd", tr);
-				this.textboxWidget.textbox.selectionEnd = (this.textboxWidget.textbox.selectionStart = String(ntr.text).replace(/\r/g,"").length) + selectedText.length;
+		},
+		cycleCommandDown: function(){
+			// 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, "");
+			}else{
+				this.commandIndex++;
+				this.setTextboxValue(this.textboxWidget, this.commandList[this.commandIndex]);
+			}
 
-			}catch(e){}
-		}
-	},
-	onKeyPress: function(event){
-		// summary
-		// handle key input for Enter and operators
-		if(event.charOrCode == dojo.keys.ENTER){
-			this.parseTextbox();
-			// stop form submissions
-			dojo.stopEvent(event);
-		}else if(event.charOrCode == '!' || event.charOrCode == '^' || event.charOrCode == '*' || event.charOrCode == '/' || event.charOrCode == '-' || event.charOrCode == '+'){
-			if(dojo.isIE){
-				var tr = dojo.doc.selection.createRange().duplicate();
+		},
+		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
+			if(has('ie')){
+				var tr = win.doc.selection.createRange().duplicate();
 				var selectedText = tr.text || '';
 				var ntr = this.textboxWidget.textbox.createTextRange();
 				tr.move("character",0);
@@ -175,182 +161,201 @@ dojo.declare(
 
 				}catch(e){}
 			}
+		},
+		onKeyPress: function(e){
+			// summary
+			// handle key input for Enter and operators
+			if(e.charOrCode == keys.ENTER){
+				this.parseTextbox();
+				// stop form submissions
+				event.stop(e);
+			}else if(e.charOrCode == '!' || e.charOrCode == '^' || e.charOrCode == '*' || e.charOrCode == '/' || e.charOrCode == '-' || e.charOrCode == '+'){
+				if(has('ie')){
+					var tr = win.doc.selection.createRange().duplicate();
+					var selectedText = tr.text || '';
+					var ntr = this.textboxWidget.textbox.createTextRange();
+					tr.move("character",0);
+					ntr.move("character",0);
+					try{
+						ntr.setEndPoint("EndToEnd", tr);
+						this.textboxWidget.textbox.selectionEnd = (this.textboxWidget.textbox.selectionStart = String(ntr.text).replace(/\r/g,"").length) + selectedText.length;
 
-			if(this.textboxWidget.get("value")==""){
-				this.setTextboxValue(this.textboxWidget, "Ans");
-			}else if(this.putInAnsIfTextboxIsHighlighted(this.textboxWidget.textbox, event.charOrCode)){
-				this.setTextboxValue(this.textboxWidget, "Ans");//this.insertText("Ans");
-				// move the cursor to the end of "Ans"
-				dijit.selectInputText(this.textboxWidget.textbox, this.textboxWidget.textbox.value.length, this.textboxWidget.textbox.value.length);
+					}catch(e){}
+				}
+
+				if(this.textboxWidget.get("value")==""){
+					this.setTextboxValue(this.textboxWidget, "Ans");
+				}else if(this.putInAnsIfTextboxIsHighlighted(this.textboxWidget.textbox, event.charOrCode)){
+					this.setTextboxValue(this.textboxWidget, "Ans");//this.insertText("Ans");
+					// move the cursor to the end of "Ans"
+					_TextBoxMixin.selectInputText(this.textboxWidget.textbox, this.textboxWidget.textbox.value.length, this.textboxWidget.textbox.value.length);
+				}
 			}
-		}
-	},
-	insertMinus: function(){
-		// 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
-		var t = "<span style='display:block;";
-		if(isRight){
-			t += "text-align:right;'>";
-		}else{
-			t += "text-align:left;'>";
-		}
-		t += text+"<br></span>";
-		if(this.hasDisplay){
-			this.displayBox.innerHTML += t;
-		}else{// if there is not a display box, put the answer in the input box
-			this.setTextboxValue(this.textboxWidget, text);
-		}
-		//this.setTextboxValue(this.displayBox, this.displayBox.get('value')+'\n'+text);
-	},
-	setTextboxValue: function(widget, val){
-		// 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 +
-		//console.log("Entered "+node.selectionStart + " "+ node.selectionEnd);
-		if(typeof node.selectionStart == "number"){ // not-IE
-			if(node.selectionStart==0 && node.selectionEnd == node.value.length){
-				//node.value = "Ans";
-				//dijit.selectInputText(node, node.value.length, node.value.length);
-				return true;
+		},
+		insertMinus: function(){
+			// 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
+			var t = "<span style='display:block;";
+			if(isRight){
+				t += "text-align:right;'>";
+			}else{
+				t += "text-align:left;'>";
 			}
-		}else if(document.selection){ // IE
-			//console.log("Entered 2");
-			var range = document.selection.createRange();
-			//console.log("Range: "+range.text +" Node: "+node.value);
-			if(node.value == range.text){
-				//this.insertText("Ans");
-				return true;
+			t += text+"<br></span>";
+			if(this.hasDisplay){
+				this.displayBox.innerHTML += t;
+			}else{// if there is not a display box, put the answer in the input box
+				this.setTextboxValue(this.textboxWidget, text);
 			}
-		}
-		return false;
-	},
-	clearText: function(){
-		// 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{
-			this.setTextboxValue(this.textboxWidget, "");
-		}
-		this.textboxWidget.focus();
-	},
-	/*insertMinusSign: function(){
-		//
-		var v = this.subtract.get('label');
-		if(v != '(-)' && this.putInAnsIfTextboxIsHighlighted(this.textboxWidget.textbox)){
-			this.insertText("Ans-");
-			return;
-		}
-		this.insertText('-');
-	},*/
-	insertOperator: function(newText){
-		// summary
-		//	insert an operator with a button
-		if(typeof newText == "object"){
-			newText = newText = dijit.getEnclosingWidget(newText["target"]).value;
-		}
-		if(this.textboxWidget.get("value") == "" || this.putInAnsIfTextboxIsHighlighted(this.textboxWidget.textbox)){
-			newText = "Ans"+newText;
-		}
-		this.insertText(newText);
-	},
-	insertText: function(newText){//(node, newText){
-		// summary
-		//	insert text to the textboxWidget node
-		setTimeout(dojo.hitch(this, function(){
-
-		var node = this.textboxWidget.textbox;
-		if(node.value==""){
-			node.selectionStart = 0;
-			node.selectionEnd = 0;
-		}
-		if(typeof newText == "object"){
-			newText = newText = dijit.getEnclosingWidget(newText["target"]).value;
-		}
+			//this.setTextboxValue(this.displayBox, this.displayBox.get('value')+'\n'+text);
+		},
+		setTextboxValue: function(widget, val){
+			// 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 +
+			//console.log("Entered "+node.selectionStart + " "+ node.selectionEnd);
+			if(typeof node.selectionStart == "number"){ // not-IE
+				if(node.selectionStart==0 && node.selectionEnd == node.value.length){
+					//node.value = "Ans";
+					//dijit.selectInputText(node, node.value.length, node.value.length);
+					return true;
+				}
+			}else if(document.selection){ // IE
+				//console.log("Entered 2");
+				var range = document.selection.createRange();
+				//console.log("Range: "+range.text +" Node: "+node.value);
+				if(node.value == range.text){
+					//this.insertText("Ans");
+					return true;
+				}
+			}
+			return false;
+		},
+		clearText: function(){
+			// 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{
+				this.setTextboxValue(this.textboxWidget, "");
+			}
+			this.textboxWidget.focus();
+		},
+		/*insertMinusSign: function(){
+			//
+			var v = this.subtract.get('label');
+			if(v != '(-)' && this.putInAnsIfTextboxIsHighlighted(this.textboxWidget.textbox)){
+				this.insertText("Ans-");
+				return;
+			}
+			this.insertText('-');
+		},*/
+		insertOperator: function(newText){
+			// summary
+			//	insert an operator with a button
+			if(typeof newText == "object"){
+				newText = newText = registry.getEnclosingWidget(newText["target"]).value;
+			}
+			if(this.textboxWidget.get("value") == "" || this.putInAnsIfTextboxIsHighlighted(this.textboxWidget.textbox)){
+				newText = "Ans"+newText;
+			}
+			this.insertText(newText);
+		},
+		insertText: function(newText){//(node, newText){
+			// summary
+			//	insert text to the textboxWidget node
+			setTimeout(lang.hitch(this, function(){
 
-		var value = node.value.replace(/\r/g,'');
-		if(typeof node.selectionStart == "number"){ // not-IE
-		        var pos = node.selectionStart;
-		        var cr = 0;
-	        	if(navigator.userAgent.indexOf("Opera") != -1){ // if(dojo.isOpera){
-	                	cr = (node.value.substring(0,pos).match(/\r/g) || []).length;
-		        }
-		        node.value = value.substring(0, node.selectionStart-cr) + newText + value.substring(node.selectionEnd-cr);
-			node.focus();
-			pos += newText.length;
-		        //node.setSelectionRange(pos, pos);
-			dijit.selectInputText(this.textboxWidget.textbox, pos, pos);
-		}else if(document.selection){ // IE
-			if(this.handle){
-				clearTimeout(this.handle);
-				this.handle = null;
+			var node = this.textboxWidget.textbox;
+			if(node.value==""){
+				node.selectionStart = 0;
+				node.selectionEnd = 0;
+			}
+			if(typeof newText == "object"){
+				newText = newText = registry.getEnclosingWidget(newText["target"]).value;
 			}
-			node.focus();
-			this.handle = setTimeout(function(){
-		        	var range = document.selection.createRange();
-			        range.text = newText;
-			        // show cursor
-	        		range.select();
-				this.handle = null;
-			}, 0);
 
-		}
-		}), 0);
-	},
-	hasDisplay: false,
-	postCreate: function(){
-		// summary
-		//	run startup, see if there is an upper display box, etc
-		this.handle = null;
-		this.commandList = [];
-		this.commandIndex = 0;
+			var value = node.value.replace(/\r/g,'');
+			if(typeof node.selectionStart == "number"){ // not-IE
+			        var pos = node.selectionStart;
+			        var cr = 0;
+		        	if(has('opera')){
+		                	cr = (node.value.substring(0,pos).match(/\r/g) || []).length;
+			        }
+			        node.value = value.substring(0, node.selectionStart-cr) + newText + value.substring(node.selectionEnd-cr);
+				node.focus();
+				pos += newText.length;
+			        //node.setSelectionRange(pos, pos);
+				_TextBoxMixin.selectInputText(this.textboxWidget.textbox, pos, pos);
+			}else if(document.selection){ // IE
+				if(this.handle){
+					clearTimeout(this.handle);
+					this.handle = null;
+				}
+				node.focus();
+				this.handle = setTimeout(function(){
+			        	var range = document.selection.createRange();
+				        range.text = newText;
+				        // show cursor
+		        		range.select();
+					this.handle = null;
+				}, 0);
 
-		if(this.displayBox){
-			this.hasDisplay = true;
-		}
-		if(this.toFracButton && !dojox.calc.toFrac){
-			dojo.style(this.toFracButton.domNode, { visibility: "hidden" });
-		}
-		if(this.functionMakerButton && !dojox.calc.FuncGen){
-			dojo.style(this.functionMakerButton.domNode, { visibility: "hidden" });
-		}
-		if(this.grapherMakerButton && !dojox.calc.Grapher){
-			dojo.style(this.grapherMakerButton.domNode, { visibility: "hidden" });
-		}
-		this._connects.push(dijit.typematic.addKeyListener(this.textboxWidget.textbox,
-				{
-					charOrCode:dojo.keys.UP_ARROW,
-					shiftKey:false,
-					metaKey:false,
-					ctrlKey:false // ALT is optional since its unspecified
-				},
-				this, this.cycleCommands, 200, 200));
-		this._connects.push(dijit.typematic.addKeyListener(this.textboxWidget.textbox,
-				{
-					charOrCode:dojo.keys.DOWN_ARROW,
-					shiftKey:false,
-					metaKey:false,
-					ctrlKey:false // ALT is optional since its unspecified
-				},
-				this, this.cycleCommands, 200, 200));
+			}
+			}), 0);
+		},
+		hasDisplay: false,
+		postCreate: function(){
+			// summary
+			//	run startup, see if there is an upper display box, etc
+			this.handle = null;
+			this.commandList = [];
+			this.commandIndex = 0;
 
+			if(this.displayBox){
+				this.hasDisplay = true;
+			}
+			if(this.toFracButton && !calc.toFrac){
+				domStyle.set(this.toFracButton.domNode, { visibility: "hidden" });
+			}
+			if(this.functionMakerButton && !calc.FuncGen){
+				domStyle.set(this.functionMakerButton.domNode, { visibility: "hidden" });
+			}
+			if(this.grapherMakerButton && !calc.Grapher){
+				domStyle.set(this.grapherMakerButton.domNode, { visibility: "hidden" });
+			}
+			this._connects.push(typematic.addKeyListener(this.textboxWidget.textbox,
+					{
+						charOrCode:keys.UP_ARROW,
+						shiftKey:false,
+						metaKey:false,
+						ctrlKey:false // ALT is optional since its unspecified
+					},
+					this, this.cycleCommands, 200, 200));
+			this._connects.push(typematic.addKeyListener(this.textboxWidget.textbox,
+					{
+						charOrCode:keys.DOWN_ARROW,
+						shiftKey:false,
+						metaKey:false,
+						ctrlKey:false // ALT is optional since its unspecified
+					},
+					this, this.cycleCommands, 200, 200));
 
-		//onClick="this.insertText(document.getElementById('textbox'), '\u221A')"
-		//this.sqrt.set("onClick", dojo.hitch(this, "insertText", this.textboxWidget, '\u221A'));
-		//this.pi.set("onClick", dojo.hitch(this, "insertText", this.textboxWidget, '\u03C0'));
-		this.startup()
-	}
-});
 
+			//onClick="this.insertText(document.getElementById('textbox'), '\u221A')"
+			//this.sqrt.set("onClick", lang.hitch(this, "insertText", this.textboxWidget, '\u221A'));
+			//this.pi.set("onClick", lang.hitch(this, "insertText", this.textboxWidget, '\u03C0'));
+			this.startup()
+		}
+	});
 
-return dojox.calc.Standard;
 });
diff --git a/dojox/calc/_Executor.js b/dojox/calc/_Executor.js
index eb487ef..8a4abf6 100644
--- a/dojox/calc/_Executor.js
+++ b/dojox/calc/_Executor.js
@@ -1,146 +1,148 @@
-define("dojox/calc/_Executor", ["dojo", "dijit/_Templated", "dojox/math/_base"], function(dojo) {
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/number",
+	"dijit/_base/manager",
+	"dijit/_WidgetBase",
+	"dijit/_TemplatedMixin",
+	"dojox/math/_base"
+], function(kernel, declare, lang, number, dijit, WidgetBase, TemplatedMixin, math){
 
-dojo.experimental("dojox.calc._Executor");
+	kernel.experimental("dojox.calc");
 
-(function(){
-var calcEnv; // private
+	var calcEnv, calc; // private
 
-// do not override toFrac's pow function if it won the race
-if(!("pow" in dojox.calc)){
-	dojox.calc.pow = function(/*Number*/ base, /*Number*/ exponent){
-		// summary:
-		//		Computes base ^ exponent
-		//		Wrapper to Math.pow(base, exponent) to handle (-27) ^ (1/3)
-
-		function isInt(n){
-			return Math.floor(n) == n;
-		}
-
-		if(base >= 0 || isInt(exponent)){
-			return Math.pow(base, exponent);
-		}else{ // e.g. (1/3) root of -27 = -3
-			var inv = 1 / exponent;
-			// e.g. 1 / (1/3) must be an odd integer
-			return (isInt(inv) && (inv & 1)) ? -Math.pow(-base, exponent) : NaN;
-		}
-	};
-}
-
-
-dojo.declare(
-	"dojox.calc._Executor",
-	[dijit._Widget, dijit._Templated],
-{
-	// summary:
-	//		A graphing, scientific calculator
-	//
-	
-	templateString: '<iframe src="' +
-		dojo.moduleUrl("dojox.calc","_ExecutorIframe.html") +
-		'" style="display:none;" onload="if(arguments[0] && arguments[0].Function)'+dijit._scopeName+'.byNode(this)._onLoad(arguments[0])"></iframe>',
+	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
 
-	_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
+	/*=====
+		WidgetBase = dijit._WidgetBase;
+		TemplatedMixin = dijit._TemplatedMixin;
+	=====*/
+	var Executor = declare(
+		"dojox.calc._Executor",
+		[WidgetBase, TemplatedMixin],
+	{
+		// summary:
+		//		A graphing, scientific calculator
 		//
-		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
-		env.dojox = {math: {}};
-		for(var f in dojox.math){ env.dojox.math[f] = dojo.hitch(dojox.math, f); }
-		if("toFrac" in dojox.calc){
-			env.toFracCall = dojo.hitch(dojox.calc, 'toFrac');
-			this.Function('toFrac', 'x', "return toFracCall(x)");
-		}
-
-		env.isJavaScriptLanguage = dojo.number.format(1.5, {pattern:'#.#'}) == "1.5";
-		env.Ans = 0;
-		env.pi = Math.PI;
-		env.eps = Math.E;
-
-		env.powCall = dojo.hitch(dojox.calc, 'pow');
-
-		// TODO add Degrees support to trig functions
-
+		
+		templateString: '<iframe src="' + require.toUrl("dojox/calc/_ExecutorIframe.html") +
+			'" 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
+			//
+			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
+			env.dojox = {math: {}};
+			for(var f in math){ env.dojox.math[f] = lang.hitch(math, f); }
+			if("toFrac" in calc){
+				env.toFracCall = lang.hitch(calc, 'toFrac');
+				this.Function('toFrac', 'x', "return toFracCall(x)");
+			}
 
-		//this.normalizedFunction('toString', 'number, radix', "return number.toString(radix)");
-		this.normalizedFunction('sqrt', 'x', "return Math.sqrt(x)");
-		this.normalizedFunction('sin', 'x', "return Math.sin(x)");
-		this.normalizedFunction('cos', 'x', "return Math.cos(x)");
-		this.normalizedFunction('tan', 'x', "return Math.tan(x)");
-		this.normalizedFunction('asin', 'x', "return Math.asin(x)");
-		this.normalizedFunction('acos', 'x', "return Math.acos(x)");
-		this.normalizedFunction('atan', 'x', "return Math.atan(x)");
-		this.normalizedFunction('atan2', 'y, x', "return Math.atan2(y, x)");
-		this.normalizedFunction('Round', 'x', "return Math.round(x)");
-		this.normalizedFunction('Int', 'x', "return Math.floor(x)");
-		this.normalizedFunction('Ceil', 'x', "return Math.ceil(x)");
-		this.normalizedFunction('ln', 'x', "return Math.log(x)");
-		this.normalizedFunction('log', 'x', "return Math.log(x)/Math.log(10)");
-		this.normalizedFunction('pow', 'x, y', "return powCall(x,y)");
-		this.normalizedFunction('permutations', 'n, r', "return dojox.math.permutations(n, r);");
-		this.normalizedFunction('P', 'n, r', "return dojox.math.permutations(n, r);");
-		this.normalizedFunction('combinations', 'n, r', "return dojox.math.combinations(n, r);");
-		this.normalizedFunction('C', 'n, r', "return dojox.math.combinations(n, r)");
+			env.isJavaScriptLanguage = number.format(1.5, {pattern:'#.#'}) == "1.5";
+			env.Ans = 0;
+			env.pi = Math.PI;
+			env.eps = Math.E;
+
+			env.powCall = lang.hitch(calc, 'pow');
+
+			// TODO add Degrees support to trig functions
+
+
+			//this.normalizedFunction('toString', 'number, radix', "return number.toString(radix)");
+			this.normalizedFunction('sqrt', 'x', "return Math.sqrt(x)");
+			this.normalizedFunction('sin', 'x', "return Math.sin(x)");
+			this.normalizedFunction('cos', 'x', "return Math.cos(x)");
+			this.normalizedFunction('tan', 'x', "return Math.tan(x)");
+			this.normalizedFunction('asin', 'x', "return Math.asin(x)");
+			this.normalizedFunction('acos', 'x', "return Math.acos(x)");
+			this.normalizedFunction('atan', 'x', "return Math.atan(x)");
+			this.normalizedFunction('atan2', 'y, x', "return Math.atan2(y, x)");
+			this.normalizedFunction('Round', 'x', "return Math.round(x)");
+			this.normalizedFunction('Int', 'x', "return Math.floor(x)");
+			this.normalizedFunction('Ceil', 'x', "return Math.ceil(x)");
+			this.normalizedFunction('ln', 'x', "return Math.log(x)");
+			this.normalizedFunction('log', 'x', "return Math.log(x)/Math.log(10)");
+			this.normalizedFunction('pow', 'x, y', "return powCall(x,y)");
+			this.normalizedFunction('permutations', 'n, r', "return dojox.math.permutations(n, r);");
+			this.normalizedFunction('P', 'n, r', "return dojox.math.permutations(n, r);");
+			this.normalizedFunction('combinations', 'n, r', "return dojox.math.combinations(n, r);");
+			this.normalizedFunction('C', 'n, r', "return dojox.math.combinations(n, r)");
+
+			this.normalizedFunction('toRadix', 'number, baseOut', "if(!baseOut){ baseOut = 10; } if(typeof number == 'string'){ number = parseFloat(number); }return number.toString(baseOut);");
+			this.normalizedFunction('toBin', 'number', "return toRadix(number, 2)");
+			this.normalizedFunction('toOct', 'number', "return toRadix(number, 8)");
+			this.normalizedFunction('toHex', 'number', "return toRadix(number, 16)");
+			this.onLoad();
+		},
+
+		onLoad: function(){
+			// summary:
+			//	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
+			//
+			return lang.hitch(calcEnv, calcEnv.Function.apply(calcEnv, arguments));
+		},
+		normalizedFunction: function(name, args, body){
+			return lang.hitch(calcEnv, calcEnv.normalizedFunction.apply(calcEnv, arguments));
+		},
+		deleteFunction: function(name){
+			calcEnv[name] = undefined;
+			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
+			//
+			return calcEnv.eval.apply(calcEnv, arguments);
+		},
+		destroy: function(){
+			this.inherited(arguments);
+			calcEnv = null; // assist garbage collection
+		}
+	});
 
-		this.normalizedFunction('toRadix', 'number, baseOut', "if(!baseOut){ baseOut = 10; } if(typeof number == 'string'){ number = parseFloat(number); }return number.toString(baseOut);");
-		this.normalizedFunction('toBin', 'number', "return toRadix(number, 2)");
-		this.normalizedFunction('toOct', 'number', "return toRadix(number, 8)");
-		this.normalizedFunction('toHex', 'number', "return toRadix(number, 16)");
-		this.onLoad();
-	},
+	return calc = {
+		pow: function(/*Number*/ base, /*Number*/ exponent){
+			// summary:
+			//		Computes base ^ exponent
+			//		Wrapper to Math.pow(base, exponent) to handle (-27) ^ (1/3)
 
-	onLoad: function(){
-		// summary:
-		//	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
-		//
-		return dojo.hitch(calcEnv, calcEnv.Function.apply(calcEnv, arguments));
-	},
-	normalizedFunction: function(name, args, body){
-		return dojo.hitch(calcEnv, calcEnv.normalizedFunction.apply(calcEnv, arguments));
-	},
-	deleteFunction: function(name){
-		calcEnv[name] = undefined;
-		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
-		//
-		return calcEnv.eval.apply(calcEnv, arguments);
-	},
-	destroy: function(){
-		this.inherited(arguments);
-		calcEnv = null; // assist garbage collection
-	}
-});
-})();
+			function isInt(n){
+				return Math.floor(n) == n;
+			}
 
-(function(){
-	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
-	dojo.mixin(dojox.calc, {
-		approx: function(r){
+			if(base >= 0 || isInt(exponent)){
+				return Math.pow(base, exponent);
+			}else{ // e.g. (1/3) root of -27 = -3
+				var inv = 1 / exponent;
+				// e.g. 1 / (1/3) must be an odd integer
+				return (isInt(inv) && (inv & 1)) ? -Math.pow(-base, exponent) : NaN;
+			}
+		},
+		approx: function(/*Number*/ r){
 			// summary:
 			//	Return a less exact approximation of r such that approx(r * (1 +- eps)) == approx(r)
 			if(typeof r == "number"){
 				return Math.round(r * magicBigInt) / magicBigInt;
 			}
 			return r;
-		}
-	});
-})();
-
-
-return dojox.calc._Executor;
+		},
+		_Executor: Executor
+	};
 });
diff --git a/dojox/calc/_ExecutorIframe.html b/dojox/calc/_ExecutorIframe.html
index d17d326..0d2cac5 100644
--- a/dojox/calc/_ExecutorIframe.html
+++ b/dojox/calc/_ExecutorIframe.html
@@ -1,5 +1,5 @@
 <html><head>
-<script>
+<script type="text/javascript">
 Array.prototype._toString = Array.prototype.toString;
 Array.prototype.toString = function(){ return "[" + this._toString() + "]"; };
 
@@ -519,7 +519,7 @@ Number.prototype.toString = function(radix){ if(!radix || radix==10){ return ""+
 })();
 </script>
 </head><body>
-<script>
+<script type="text/javascript">
 	document.documentElement.removeChild(document.documentElement.firstChild); // remove HEAD to remove debugger access for extra security
 </script>
 </body></html>
diff --git a/dojox/calc/templates/FuncGen.html b/dojox/calc/templates/FuncGen.html
index a669f17..dcc883e 100644
--- a/dojox/calc/templates/FuncGen.html
+++ b/dojox/calc/templates/FuncGen.html
@@ -1,17 +1,15 @@
 <div style="border:1px solid black;">
-
-	<select dojoType="dijit.form.ComboBox" placeholder="functionName" dojoAttachPoint='combo' style="width:45%;" class="dojoxCalcFuncGenNameBox" dojoAttachEvent='onChange:onSelect'></select>
-
-	<input dojoType="dijit.form.TextBox" placeholder="arguments" class="dojoxCalcFuncGenTextBox" style="width:50%;" dojoAttachPoint='args' />
+	<select data-dojo-type="dijit.form.ComboBox" placeholder="functionName" data-dojo-attach-point='combo' style="width:45%;" class="dojoxCalcFuncGenNameBox" data-dojo-attach-event='onChange:onSelect'></select>
+	<input data-dojo-type="dijit.form.TextBox" placeholder="arguments" class="dojoxCalcFuncGenTextBox" style="width:50%;" data-dojo-attach-point='args' />
 	<BR>
-	<TEXTAREA dojoType="dijit.form.SimpleTextarea" placeholder="function body" class="dojoxCalcFuncGenTextArea" style="text-align:left;width:95%;" rows=10 dojoAttachPoint='textarea' value="" dojoAttachEvent='onClick:readyStatus'></TEXTAREA>
+	<TEXTAREA data-dojo-type="dijit.form.SimpleTextarea" placeholder="function body" class="dojoxCalcFuncGenTextArea" style="text-align:left;width:95%;" rows=10 data-dojo-attach-point='textarea' value="" data-dojo-attach-event='onClick:readyStatus'></TEXTAREA>
 	<BR>
-	<input dojoType="dijit.form.Button" class="dojoxCalcFuncGenSave" dojoAttachPoint='saveButton' label="Save" dojoAttachEvent='onClick:onSaved' />
-	<input dojoType="dijit.form.Button" class="dojoxCalcFuncGenReset" dojoAttachPoint='resetButton' label="Reset" dojoAttachEvent='onClick:onReset' />
-	<input dojoType="dijit.form.Button" class="dojoxCalcFuncGenClear" dojoAttachPoint='clearButton' label="Clear" dojoAttachEvent='onClick:onClear' />
-	<input dojoType="dijit.form.Button" class="dojoxCalcFuncGenClose" dojoAttachPoint='closeButton' label="Close" />
+	<input data-dojo-type="dijit.form.Button" class="dojoxCalcFuncGenSave" data-dojo-attach-point='saveButton' label="Save" data-dojo-attach-event='onClick:onSaved' />
+	<input data-dojo-type="dijit.form.Button" class="dojoxCalcFuncGenReset" data-dojo-attach-point='resetButton' label="Reset" data-dojo-attach-event='onClick:onReset' />
+	<input data-dojo-type="dijit.form.Button" class="dojoxCalcFuncGenClear" data-dojo-attach-point='clearButton' label="Clear" data-dojo-attach-event='onClick:onClear' />
+	<input data-dojo-type="dijit.form.Button" class="dojoxCalcFuncGenClose" data-dojo-attach-point='closeButton' label="Close" />
 	<BR><BR>
-	<input dojoType="dijit.form.Button" class="dojoxCalcFuncGenDelete" dojoAttachPoint='deleteButton' label="Delete" dojoAttachEvent='onClick:onDelete' />
+	<input data-dojo-type="dijit.form.Button" class="dojoxCalcFuncGenDelete" data-dojo-attach-point='deleteButton' label="Delete" data-dojo-attach-event='onClick:onDelete' />
 	<BR>
-	<input dojoType="dijit.form.TextBox" style="width:45%;" dojoAttachPoint='status' class="dojoxCalcFuncGenStatusTextBox" readonly value="Ready" />
+	<input data-dojo-type="dijit.form.TextBox" style="width:45%;" data-dojo-attach-point='status' class="dojoxCalcFuncGenStatusTextBox" readonly value="Ready" />
 </div>
diff --git a/dojox/calc/templates/GraphPro.html b/dojox/calc/templates/GraphPro.html
index c76ec0c..a28b0e7 100644
--- a/dojox/calc/templates/GraphPro.html
+++ b/dojox/calc/templates/GraphPro.html
@@ -1,24 +1,24 @@
 <div class="dijitReset dijitInline dojoxCalc"
-><table class="dijitReset dijitInline dojoxCalcLayout" dojoAttachPoint="calcTable" rules="none" cellspacing=0 cellpadding=0 border=0>
+><table class="dijitReset dijitInline dojoxCalcLayout" data-dojo-attach-point="calcTable" rules="none" cellspacing=0 cellpadding=0 border=0>
 	<tr
 		><td colspan="4" class="dojoxCalcTextAreaContainer"
-			><div class="dijitTextBox dijitTextArea" style="height:10em;width:auto;max-width:15.3em;border-width:0px;" dojoAttachPoint='displayBox'></div
+			><div class="dijitTextBox dijitTextArea" style="height:10em;width:auto;max-width:15.3em;border-width:0px;" data-dojo-attach-point='displayBox'></div
 		></td
 	></tr>
 	<tr
 		><td colspan="4" class="dojoxCalcInputContainer"
-			><input dojoType="dijit.form.TextBox" dojoAttachEvent="onBlur:onBlur,onKeyPress:onKeyPress" dojoAttachPoint='textboxWidget'
+			><input data-dojo-type="dijit.form.TextBox" data-dojo-attach-event="onBlur:onBlur,onKeyPress:onKeyPress" data-dojo-attach-point='textboxWidget'
 		/></td
 	></tr>
 	<tr>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="grapherMakerButton" label="Graph" dojoAttachEvent='onClick:makeGrapherWindow' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="grapherMakerButton" label="Graph" data-dojo-attach-event='onClick:makeGrapherWindow' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="functionMakerButton" label="Func" dojoAttachEvent='onClick:makeFunctionWindow' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="functionMakerButton" label="Func" data-dojo-attach-event='onClick:makeFunctionWindow' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="toFracButton" label="toFrac" value="toFrac(" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="toFracButton" label="toFrac" value="toFrac(" data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td colspan="1" class="dojoxCalcButtonContainer">
 		</td>
@@ -26,61 +26,61 @@
 	</tr>
 	<tr>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="seven" label="7" value='7' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="seven" label="7" value='7' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="eight" label="8" value='8' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="eight" label="8" value='8' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="nine" label="9" value='9' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="nine" label="9" value='9' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="divide" label="/" value='/' dojoAttachEvent='onClick:insertOperator' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="divide" label="/" value='/' data-dojo-attach-event='onClick:insertOperator' />
 		</td>
 	</tr>
 	<tr>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="four" label="4" value='4' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="four" label="4" value='4' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="five" label="5" value='5' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="five" label="5" value='5' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="six" label="6" value='6' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="six" label="6" value='6' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="multiply" label="*" value='*' dojoAttachEvent='onClick:insertOperator' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="multiply" label="*" value='*' data-dojo-attach-event='onClick:insertOperator' />
 		</td>
 	</tr>
 	<tr>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="one" label="1" value='1' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="one" label="1" value='1' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="two" label="2" value='2' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="two" label="2" value='2' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="three" label="3" value='3' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="three" label="3" value='3' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="add" label="+" value='+' dojoAttachEvent='onClick:insertOperator' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="add" label="+" value='+' data-dojo-attach-event='onClick:insertOperator' />
 		</td>
 	</tr>
 	<tr>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="decimal" label="." value='.' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="decimal" label="." value='.' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="zero" label="0" value='0' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="zero" label="0" value='0' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="equals" label="x=y" value='=' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="equals" label="x=y" value='=' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcMinusButtonContainer">
-			<span dojoType="dijit.form.ComboButton" dojoAttachPoint="subtract" label='-' value='-' dojoAttachEvent='onClick:insertOperator'>
+			<span data-dojo-type="dijit.form.ComboButton" data-dojo-attach-point="subtract" label='-' value='-' data-dojo-attach-event='onClick:insertOperator'>
 
-				<div dojoType="dijit.Menu" style="display:none;">
-					<div dojoType="dijit.MenuItem" dojoAttachEvent="onClick:insertMinus">
+				<div data-dojo-type="dijit.Menu" style="display:none;">
+					<div data-dojo-type="dijit.MenuItem" data-dojo-attach-event="onClick:insertMinus">
 						(-)
 					</div>
 				</div>
@@ -89,77 +89,77 @@
 	</tr>
 	<tr>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="clear" label="Clear" dojoAttachEvent='onClick:clearText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="clear" label="Clear" data-dojo-attach-event='onClick:clearText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="sqrt" label="&#x221A;" value="&#x221A;" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="sqrt" label="&#x221A;" value="&#x221A;" data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="power" label="^" value="^" dojoAttachEvent='onClick:insertOperator' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="power" label="^" value="^" data-dojo-attach-event='onClick:insertOperator' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="factorialButton" label="!" value="!" dojoAttachEvent='onClick:insertOperator' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="factorialButton" label="!" value="!" data-dojo-attach-event='onClick:insertOperator' />
 		</td>
 	</tr>
 	<tr>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="pi" label="&#x03C0;" value="&#x03C0;" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="pi" label="&#x03C0;" value="&#x03C0;" data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="sin" label="sin" value="sin(" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="sin" label="sin" value="sin(" data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="cos" label="cos" value="cos(" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="cos" label="cos" value="cos(" data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="tan" label="tan" value="tan(" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="tan" label="tan" value="tan(" data-dojo-attach-event='onClick:insertText' />
 		</td>
 
 	</tr>
 	<tr>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="e" label="&#x03F5;" value="&#x03F5;" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="e" label="&#x03F5;" value="&#x03F5;" data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="log10" label="log" value="log(" value="log(" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="log10" label="log" value="log(" value="log(" data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="lnE" label="ln" value="ln(" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="lnE" label="ln" value="ln(" data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="round" label="Round" value="Round(" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="round" label="Round" value="Round(" data-dojo-attach-event='onClick:insertText' />
 		</td>
 
 	</tr>
 	<tr>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="intButton" label="Int" value="Int(" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="intButton" label="Int" value="Int(" data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="PermutationButton" label="P" value="P(" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="PermutationButton" label="P" value="P(" data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="CombinationButton" label="C" value="C(" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="CombinationButton" label="C" value="C(" data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="comma" label="," value=',' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="comma" label="," value=',' data-dojo-attach-event='onClick:insertText' />
 		</td>
 
 	</tr>
 	<tr>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="AnsButton" label="Ans" value="Ans" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="AnsButton" label="Ans" value="Ans" data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="LeftParenButton" label="(" value="(" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="LeftParenButton" label="(" value="(" data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="RightParenButton" label=")" value=")" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="RightParenButton" label=")" value=")" data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="enter" label="Enter" dojoAttachEvent='onClick:parseTextbox' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="enter" label="Enter" data-dojo-attach-event='onClick:parseTextbox' />
 		</td>
 	</tr>
 </table>
-<span dojoAttachPoint="executor" dojoType="dojox.calc._Executor" dojoAttachEvent="onLoad:executorLoaded"></span>
+<span data-dojo-attach-point="executor" data-dojo-type="dojox.calc._Executor" data-dojo-attach-event="onLoad:executorLoaded"></span>
 </div>
diff --git a/dojox/calc/templates/Grapher.html b/dojox/calc/templates/Grapher.html
index 7323f3d..91fd002 100644
--- a/dojox/calc/templates/Grapher.html
+++ b/dojox/calc/templates/Grapher.html
@@ -1,22 +1,22 @@
 <div>
-<div dojoAttachPoint="chartsParent" class="dojoxCalcChartHolder"></div>
-<span dojoAttachPoint="outerDiv">
-<div dojoType="dijit.form.DropDownButton" dojoAttachPoint="windowOptions" class="dojoxCalcDropDownForWindowOptions" title="Window Options">
+<div data-dojo-attach-point="chartsParent" class="dojoxCalcChartHolder"></div>
+<div data-dojo-attach-point="outerDiv">
+<div data-dojo-type="dijit.form.DropDownButton" data-dojo-attach-point="windowOptions" class="dojoxCalcDropDownForWindowOptions" title="Window Options">
 	<div>Window Options</div>
-	<div dojoType="dijit.TooltipDialog" dojoAttachPoint="windowOptionsInside" class="dojoxCalcTooltipDialogForWindowOptions" title="">
+	<div data-dojo-type="dijit.TooltipDialog" data-dojo-attach-point="windowOptionsInside" class="dojoxCalcTooltipDialogForWindowOptions" title="">
 		<table class="dojoxCalcGraphOptionTable">
 			<tr>
 				<td>
 					Width:
 				</td>
 				<td>
-					<input dojoType="dijit.form.TextBox" dojoAttachPoint="graphWidth" class="dojoxCalcGraphWidth" value="500" />
+					<input data-dojo-type="dijit.form.TextBox" data-dojo-attach-point="graphWidth" class="dojoxCalcGraphWidth" value="500" />
 				</td>
 				<td>
 					Height:
 				</td>
 				<td>
-					<input dojoType="dijit.form.TextBox" dojoAttachPoint="graphHeight" class="dojoxCalcGraphHeight" value="500" />
+					<input data-dojo-type="dijit.form.TextBox" data-dojo-attach-point="graphHeight" class="dojoxCalcGraphHeight" value="500" />
 				</td>
 			</tr>
 			<tr>
@@ -24,14 +24,14 @@
 					X >=
 				</td>
 				<td>
-					<input dojoType="dijit.form.TextBox" dojoAttachPoint="graphMinX" class="dojoxCalcGraphMinX" value="-10" />
+					<input data-dojo-type="dijit.form.TextBox" data-dojo-attach-point="graphMinX" class="dojoxCalcGraphMinX" value="-10" />
 				</td>
 
 				<td>
 					X <=
 				</td>
 				<td>
-					<input dojoType="dijit.form.TextBox" dojoAttachPoint="graphMaxX" class="dojoxCalcGraphMaxX" value="10" />
+					<input data-dojo-type="dijit.form.TextBox" data-dojo-attach-point="graphMaxX" class="dojoxCalcGraphMaxX" value="10" />
 				</td>
 			</tr>
 			<tr>
@@ -39,14 +39,14 @@
 					Y >=
 				</td>
 				<td>
-					<input dojoType="dijit.form.TextBox" dojoAttachPoint="graphMinY" class="dojoxCalcGraphMinY" value="-10" />
+					<input data-dojo-type="dijit.form.TextBox" data-dojo-attach-point="graphMinY" class="dojoxCalcGraphMinY" value="-10" />
 				</td>
 
 				<td>
 					Y <=
 				</td>
 				<td>
-					<input dojoType="dijit.form.TextBox" dojoAttachPoint="graphMaxY" class="dojoxCalcGraphMaxY" value="10" />
+					<input data-dojo-type="dijit.form.TextBox" data-dojo-attach-point="graphMaxY" class="dojoxCalcGraphMaxY" value="10" />
 				</td>
 			</tr>
 		</table>
@@ -56,20 +56,20 @@
 <BR>
 
 <div class="dojoxCalcGrapherFuncOuterDiv">
-	<table class="dojoxCalcGrapherFuncTable" dojoAttachPoint="graphTable">
+	<table class="dojoxCalcGrapherFuncTable" data-dojo-attach-point="graphTable">
 	</table>
 </div>
 
-<div dojoType="dijit.form.DropDownButton" dojoAttachPoint='addFuncButton' class="dojoxCalcDropDownAddingFunction">
+<div data-dojo-type="dijit.form.DropDownButton" data-dojo-attach-point='addFuncButton' class="dojoxCalcDropDownAddingFunction">
 	<div>Add Function</div>
-	<div dojoType="dijit.TooltipDialog" dojoAttachPoint="addFuncInside" class="dojoxCalcTooltipDialogAddingFunction" title="">
+	<div data-dojo-type="dijit.TooltipDialog" data-dojo-attach-point="addFuncInside" class="dojoxCalcTooltipDialogAddingFunction" title="">
 		<table class="dojoxCalcGrapherModeTable">
 			<tr>
 				<td>
 					Mode:
 				</td>
 				<td>
-					<select dojoType="dijit.form.Select" dojoAttachPoint="funcMode" class="dojoxCalcFunctionModeSelector">
+					<select data-dojo-type="dijit.form.Select" data-dojo-attach-point="funcMode" class="dojoxCalcFunctionModeSelector">
 						<option value="y=" selected="selected">y=</option>
 						<option value="x=">x=</option>
 					</select>
@@ -79,7 +79,7 @@
 	
 			<tr>
 				<td>
-					<input dojoType="dijit.form.Button" dojoAttachPoint="createFunc" class="dojoxCalcAddFunctionButton" label="Create" />
+					<input data-dojo-type="dijit.form.Button" data-dojo-attach-point="createFunc" class="dojoxCalcAddFunctionButton" label="Create" />
 				</td>
 			</tr>
 		</table>
@@ -90,28 +90,28 @@
 <table class="dijitInline dojoxCalcGrapherLayout">
 	<tr>
 		<td class="dojoxCalcGrapherButtonContainer">
-			<input dojoType="dijit.form.Button" class="dojoxCalcGrapherButton" dojoAttachPoint='selectAllButton' label="Select All" />
+			<input data-dojo-type="dijit.form.Button" class="dojoxCalcGrapherButton" data-dojo-attach-point='selectAllButton' label="Select All" />
 		</td>
 		<td class="dojoxCalcGrapherButtonContainer">
-			<input dojoType="dijit.form.Button" class="dojoxCalcGrapherButton" dojoAttachPoint='deselectAllButton' label="Deselect All" />
+			<input data-dojo-type="dijit.form.Button" class="dojoxCalcGrapherButton" data-dojo-attach-point='deselectAllButton' label="Deselect All" />
 		</td>
 	</tr>
 	<tr>
 		<td class="dojoxCalcGrapherButtonContainer">
-			<input dojoType="dijit.form.Button" class="dojoxCalcGrapherButton" dojoAttachPoint='drawButton'label="Draw Selected" />
+			<input data-dojo-type="dijit.form.Button" class="dojoxCalcGrapherButton" data-dojo-attach-point='drawButton'label="Draw Selected" />
 		</td>
 		<td class="dojoxCalcGrapherButtonContainer">
-			<input dojoType="dijit.form.Button" class="dojoxCalcGrapherButton" dojoAttachPoint='eraseButton' label="Erase Selected" />
+			<input data-dojo-type="dijit.form.Button" class="dojoxCalcGrapherButton" data-dojo-attach-point='eraseButton' label="Erase Selected" />
 		</td>
 	</tr>
 	<tr>
 		<td class="dojoxCalcGrapherButtonContainer">
-			<input dojoType="dijit.form.Button" class="dojoxCalcGrapherButton" dojoAttachPoint='deleteButton' label="Delete Selected" />
+			<input data-dojo-type="dijit.form.Button" class="dojoxCalcGrapherButton" data-dojo-attach-point='deleteButton' label="Delete Selected" />
 		</td>
 		<td class="dojoxCalcGrapherButtonContainer">
-			<input dojoType="dijit.form.Button" class="dojoxCalcGrapherButton" dojoAttachPoint='closeButton' label="Close" />
+			<input data-dojo-type="dijit.form.Button" class="dojoxCalcGrapherButton" data-dojo-attach-point='closeButton' label="Close" />
 		</td>
 	</tr>
 </table>
-</span>
+</div>
 </div>
diff --git a/dojox/calc/templates/Standard.html b/dojox/calc/templates/Standard.html
index 5d95c86..87ed826 100644
--- a/dojox/calc/templates/Standard.html
+++ b/dojox/calc/templates/Standard.html
@@ -1,67 +1,67 @@
 <div class="dijitReset dijitInline dojoxCalc"
-><table class="dijitReset dijitInline dojoxCalcLayout" dojoAttachPoint="calcTable" rules="none" cellspacing=0 cellpadding=0 border=0>
+><table class="dijitReset dijitInline dojoxCalcLayout" data-dojo-attach-point="calcTable" rules="none" cellspacing=0 cellpadding=0 border=0>
 	<tr
 		><td colspan="4" class="dojoxCalcInputContainer"
-			><input dojoType="dijit.form.TextBox" dojoAttachEvent="onBlur:onBlur,onKeyPress:onKeyPress" dojoAttachPoint='textboxWidget'
+			><input data-dojo-type="dijit.form.TextBox" data-dojo-attach-event="onBlur:onBlur,onKeyPress:onKeyPress" data-dojo-attach-point='textboxWidget'
 		/></td
 	></tr>
 	<tr>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="seven" label="7" value='7' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="seven" label="7" value='7' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="eight" label="8" value='8' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="eight" label="8" value='8' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="nine" label="9" value='9' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="nine" label="9" value='9' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="divide" label="/" value='/' dojoAttachEvent='onClick:insertOperator' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="divide" label="/" value='/' data-dojo-attach-event='onClick:insertOperator' />
 		</td>
 	</tr>
 	<tr>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="four" label="4" value='4' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="four" label="4" value='4' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="five" label="5" value='5' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="five" label="5" value='5' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="six" label="6" value='6' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="six" label="6" value='6' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="multiply" label="*" value='*' dojoAttachEvent='onClick:insertOperator' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="multiply" label="*" value='*' data-dojo-attach-event='onClick:insertOperator' />
 		</td>
 	</tr>
 	<tr>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="one" label="1" value='1' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="one" label="1" value='1' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="two" label="2" value='2' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="two" label="2" value='2' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="three" label="3" value='3' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="three" label="3" value='3' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="add" label="+" value='+' dojoAttachEvent='onClick:insertOperator' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="add" label="+" value='+' data-dojo-attach-event='onClick:insertOperator' />
 		</td>
 	</tr>
 	<tr>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="decimal" label="." value='.' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="decimal" label="." value='.' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="zero" label="0" value='0' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="zero" label="0" value='0' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="equals" label="x=y" value='=' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="equals" label="x=y" value='=' data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcMinusButtonContainer">
-			<span dojoType="dijit.form.ComboButton" dojoAttachPoint="subtract" label='-' value='-' dojoAttachEvent='onClick:insertOperator'>
+			<span data-dojo-type="dijit.form.ComboButton" data-dojo-attach-point="subtract" label='-' value='-' data-dojo-attach-event='onClick:insertOperator'>
 
-				<div dojoType="dijit.Menu" style="display:none;">
-					<div dojoType="dijit.MenuItem" dojoAttachEvent="onClick:insertMinus">
+				<div data-dojo-type="dijit.Menu" style="display:none;">
+					<div data-dojo-type="dijit.MenuItem" data-dojo-attach-event="onClick:insertMinus">
 						(-)
 					</div>
 				</div>
@@ -70,32 +70,32 @@
 	</tr>
 	<tr>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="clear" label="Clear" dojoAttachEvent='onClick:clearText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="clear" label="Clear" data-dojo-attach-event='onClick:clearText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="sqrt" label="&#x221A;" value="&#x221A;" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="sqrt" label="&#x221A;" value="&#x221A;" data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="power" label="^" value="^" dojoAttachEvent='onClick:insertOperator' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="power" label="^" value="^" data-dojo-attach-event='onClick:insertOperator' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="comma" label="," value=',' dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="comma" label="," value=',' data-dojo-attach-event='onClick:insertText' />
 		</td>
 	</tr>
 	<tr>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="AnsButton" label="Ans" value="Ans" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="AnsButton" label="Ans" value="Ans" data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="LeftParenButton" label="(" value="(" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="LeftParenButton" label="(" value="(" data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="RightParenButton" label=")" value=")" dojoAttachEvent='onClick:insertText' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="RightParenButton" label=")" value=")" data-dojo-attach-event='onClick:insertText' />
 		</td>
 		<td class="dojoxCalcButtonContainer">
-			<button dojoType="dijit.form.Button" dojoAttachPoint="enter" label="Enter" dojoAttachEvent='onClick:parseTextbox' />
+			<button data-dojo-type="dijit.form.Button" data-dojo-attach-point="enter" label="Enter" data-dojo-attach-event='onClick:parseTextbox' />
 		</td>
 	</tr>
 </table>
-<span dojoAttachPoint="executor" dojoType="dojox.calc._Executor" dojoAttachEvent="onLoad:executorLoaded"></span>
+<span data-dojo-attach-point="executor" data-dojo-type="dojox.calc._Executor" data-dojo-attach-event="onLoad:executorLoaded"></span>
 </div>
diff --git a/dojox/calc/tests/test_Executor.html b/dojox/calc/tests/test_Executor.html
index 9a428b1..2043937 100644
--- a/dojox/calc/tests/test_Executor.html
+++ b/dojox/calc/tests/test_Executor.html
@@ -7,27 +7,25 @@
 	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dojox.calc._Executor");
-		dojo.require("dojo.number");
+	var executor;
+	var waitForLoad;
+	function executorLoaded(){
+		executor = dijit.byId('executor');
+		waitForLoad.callback(true);
+	}
+	require(["dojox/calc/_Executor", "doh/runner", "dojo/number", "dojo/ready", "dojo/parser", "dojox/math/_base"],
+	function(calc, runner, number, ready, parser, math){
+
+		waitForLoad = new doh.Deferred();
 
-		var executor;
-		var waitForLoad = new doh.Deferred();
-		function executorLoaded(){
-			executor = dijit.byId('executor');
-			waitForLoad.callback(true);
-		}
 		function test(text, ans){
 			if (ans!=true&&ans!=false)
-				ans = dojox.calc.approx(ans);
+				ans = calc.approx(ans);
 			console.log("text is "+text);
-			doh.is(ans, dojox.calc.approx(executor.eval(text)), text);
+			doh.is(ans, calc.approx(executor.eval(text)), text);
 		}
-		/*function approx(r){
-			return Math.round(r * (1 << 30)) / (1 << 30);
-		}*/
 		var status = "Error(s) on page";
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			function allTests(){
 				dojo.byId("status").innerHTML = "Testing...";
 				func = executor.Function("fcn1", "i,j","k=i+j+1;return k;");
@@ -99,9 +97,9 @@
 				test("y=(x!!=6)", false);// factorial(x) != 6
 				test("5", 5);
 				test("3!", 6);
-				test("\u221A(3!)", Math.sqrt(dojox.math.factorial(3))); // 2.4494897427831780981972840747059);
+				test("\u221A(3!)", Math.sqrt(math.factorial(3))); // 2.4494897427831780981972840747059);
 				// factorial goes first, 2^3! = 2^6
-				test("\u221A3!", Math.sqrt(dojox.math.factorial(3))); // 2.4494897427831780981972840747059);
+				test("\u221A3!", Math.sqrt(math.factorial(3))); // 2.4494897427831780981972840747059);
 				test("\u221A(3!^2)", 6);
 				test("3\u221A(3!^3)", 6);
 				test("4\u221A(4^4)", 4);
@@ -124,16 +122,16 @@
 
 
 				test("2^Math.sin((\u03C0))", 1);
-				test("2^Math.sin(3!!)", dojox.calc.pow(2, Math.sin(dojox.math.factorial(dojox.math.factorial(3)))));
-				test("2^Math.sin((3!)!)", dojox.calc.pow(2, Math.sin(dojox.math.factorial(dojox.math.factorial(3)))));
-				test("2^Math.sin((3!+3!)-1)", dojox.calc.pow(2, Math.sin((dojox.math.factorial(3)+dojox.math.factorial(3))-1)));
-				test("2^\u221A-Math.sin(3!+3!-1)", dojox.calc.pow(2, Math.sqrt(-Math.sin(dojox.math.factorial(3)+dojox.math.factorial(3)-1))));
+				test("2^Math.sin(3!!)", calc.pow(2, Math.sin(math.factorial(math.factorial(3)))));
+				test("2^Math.sin((3!)!)", calc.pow(2, Math.sin(math.factorial(math.factorial(3)))));
+				test("2^Math.sin((3!+3!)-1)", calc.pow(2, Math.sin((math.factorial(3)+math.factorial(3))-1)));
+				test("2^\u221A-Math.sin(3!+3!-1)", calc.pow(2, Math.sqrt(-Math.sin(math.factorial(3)+math.factorial(3)-1))));
 				test("2^-\u221A+4", 1/4);
 				test("2^-2\u221A+4", 1/4);
 				test("2^(-2)\u221A+4", 256);
 				test("2^2\u221A+4", Math.sqrt(2));
 				test("2^\u221A+4", 4);
-				test("2^-(-2)\u221A+4", dojox.calc.pow(2, (-1/2)));
+				test("2^-(-2)\u221A+4", calc.pow(2, (-1/2)));
 				test("2^--2\u221A+4", 4);
 				test("-\u221A4", -2);
 				test("2^-2", 1/4);
@@ -148,7 +146,7 @@
 				// floating poMath.floor tests
 				test("--4.56443*2", 4.56443*2);
 				test("\u221A--\u221A4.56443*2", Math.sqrt(Math.sqrt(4.56443))*2);//2.923321855);
-				test("\u221A--\u221A4.56443!*2", Math.sqrt(Math.sqrt(dojox.math.factorial(4.56443)))*2);
+				test("\u221A--\u221A4.56443!*2", Math.sqrt(Math.sqrt(math.factorial(4.56443)))*2);
 				test("--4.56443*2-4.56443", 4.56443);
 				// more arithmetic
 				test("4*2-(5+2*3-2)*6/-2", 35);
@@ -163,12 +161,12 @@
 				// with \u221A (radicals)
 				test("\u221A10e10*2", Math.sqrt(10e10)*2);
 				test("\u221A10e-10*2", Math.sqrt(10e-10)*2);
-				test("5\u221A10e-10*2", dojox.calc.pow(10e-10, 1/5)*2);
-				test("5\u221A10e-10*2+5\u221A10e-10*2", dojox.calc.pow(10e-10, 1/5)*2*2);
+				test("5\u221A10e-10*2", calc.pow(10e-10, 1/5)*2);
+				test("5\u221A10e-10*2+5\u221A10e-10*2", calc.pow(10e-10, 1/5)*2*2);
 
-				test("2^3!\u221A3", dojox.calc.pow(3, 1/dojox.calc.pow(2, 6)));
-				test("2^-3!\u221A3", dojox.calc.pow(2, -dojox.calc.pow(3, 1/dojox.math.factorial(3))));
-				test("2^(-3!)\u221A3", dojox.calc.pow(3, 1/dojox.calc.pow(2, -dojox.math.factorial(3))));
+				test("2^3!\u221A3", calc.pow(3, 1/calc.pow(2, 6)));
+				test("2^-3!\u221A3", calc.pow(2, -calc.pow(3, 1/math.factorial(3))));
+				test("2^(-3!)\u221A3", calc.pow(3, 1/calc.pow(2, -math.factorial(3))));
 
 				// full space tests
 				test(" x = 5 ", 5);
@@ -180,9 +178,9 @@
 				test(" x == 5 ", true);
 				test(" 5 ", 5);
 				test(" 3 !", 6);
-				test(" \u221A ( 3 ! )", Math.sqrt(dojox.math.factorial(3))); //2.4494897427831780981972840747059);
+				test(" \u221A ( 3 ! )", Math.sqrt(math.factorial(3))); //2.4494897427831780981972840747059);
 				// factorial goes first, 2^3! = 2^6
-				test(" \u221A 3 !", Math.sqrt(dojox.math.factorial(3))); //2.4494897427831780981972840747059);
+				test(" \u221A 3 !", Math.sqrt(math.factorial(3))); //2.4494897427831780981972840747059);
 				test(" \u221A ( 3 ! ^ 2 ) ", 6);
 				test(" 3 \u221A ( 3 ! ^ 3 ) ", 6);
 				test(" 4 \u221A ( 4 ^ 4 ) ", 4);
@@ -197,16 +195,16 @@
 				test(" \u221A Math.sqrt ( 16 , 2 ) ", 2);
 
 				test(" 2 ^ Math.sin ( ( \u03C0 ) ) ", 1);
-				test(" 2 ^ Math.sin ( 3 ! ! ) ", dojox.calc.pow(2, Math.sin(dojox.math.factorial(dojox.math.factorial(3)))));
-				test(" 2 ^ Math.sin( ( 3 ! ) ! ) ", dojox.calc.pow(2, Math.sin(dojox.math.factorial(dojox.math.factorial(3)))));
-				test(" 2 ^ Math.sin ( ( 3 ! + 3 ! ) - 1 ) ", dojox.calc.pow(2, Math.sin((dojox.math.factorial(3)+dojox.math.factorial(3))-1)));
-				test(" 2 ^ \u221A - Math.sin ( 3 ! + 3 ! - 1 ) ", dojox.calc.pow(2, Math.sqrt(-Math.sin(dojox.math.factorial(3)+dojox.math.factorial(3)-1))));
+				test(" 2 ^ Math.sin ( 3 ! ! ) ", calc.pow(2, Math.sin(math.factorial(math.factorial(3)))));
+				test(" 2 ^ Math.sin( ( 3 ! ) ! ) ", calc.pow(2, Math.sin(math.factorial(math.factorial(3)))));
+				test(" 2 ^ Math.sin ( ( 3 ! + 3 ! ) - 1 ) ", calc.pow(2, Math.sin((math.factorial(3)+math.factorial(3))-1)));
+				test(" 2 ^ \u221A - Math.sin ( 3 ! + 3 ! - 1 ) ", calc.pow(2, Math.sqrt(-Math.sin(math.factorial(3)+math.factorial(3)-1))));
 				test(" 2 ^ - \u221A + 4 ", 1/4);
 				test(" 2 ^ - 2 \u221A + 4 ", 1/4);
 				test(" 2 ^ ( - 2 ) \u221A + 4 ", 256);
 				test(" 2 ^ 2 \u221A + 4 ", Math.sqrt(2));
 				test(" 2 ^ \u221A + 4 ", 4);
-				test(" 2 ^ - ( - 2 ) \u221A + 4 ", dojox.calc.pow(2, (-1/2)));
+				test(" 2 ^ - ( - 2 ) \u221A + 4 ", calc.pow(2, (-1/2)));
 				test(" 2 ^ - - 2 \u221A + 4 ", 4);
 				test(" - \u221A 4 " , -2);
 				test(" 2 ^ - 2 ", 1/4);
@@ -222,7 +220,7 @@
 				// floating point tests
 				test(" - - 4.56443 * 2 ", 4.56443*2);
 				test(" \u221A - - \u221A 4.56443 * 2 ", Math.sqrt(Math.sqrt(4.56443))*2);
-				test(" \u221A - - \u221A 4.56443 ! * 2 ", Math.sqrt(Math.sqrt(dojox.math.factorial(4.56443)))*2);
+				test(" \u221A - - \u221A 4.56443 ! * 2 ", Math.sqrt(Math.sqrt(math.factorial(4.56443)))*2);
 				test(" - - 4.56443 * 2 - 4.56443 ", 4.56443);
 				// more arithmetic
 				test(" 4 * 2 - ( 5 + 2 * 3 - 2 ) * 6 / - 2 ", 35);
@@ -233,12 +231,12 @@
 				// with \u221A (radicals)
 				test(" \u221A 10e10 * 2 ", Math.sqrt(10e10)*2);
 				test(" \u221A 10e-10 * 2 ", Math.sqrt(10e-10)*2);
-				test(" 5 \u221A 10e-10 * 2 ", dojox.calc.pow(10e-10, 1/5)*2);
-				test(" 5 \u221A 10e-10 * 2 + 5 \u221A 10e-10 * 2 ", dojox.calc.pow(10e-10, 1/5)*2*2);
+				test(" 5 \u221A 10e-10 * 2 ", calc.pow(10e-10, 1/5)*2);
+				test(" 5 \u221A 10e-10 * 2 + 5 \u221A 10e-10 * 2 ", calc.pow(10e-10, 1/5)*2*2);
 
-				test(" 2 ^ 3 ! \u221A 3 ", dojox.calc.pow(3, 1/dojox.calc.pow(2, 6)));
-				test(" 2 ^ - 3 ! \u221A 3 ", dojox.calc.pow(2, -dojox.calc.pow(3, 1/dojox.math.factorial(3))));
-				test(" 2 ^ ( - 3 ! ) \u221A 3 ", dojox.calc.pow(3, 1/dojox.calc.pow(2, -dojox.math.factorial(3))));
+				test(" 2 ^ 3 ! \u221A 3 ", calc.pow(3, 1/calc.pow(2, 6)));
+				test(" 2 ^ - 3 ! \u221A 3 ", calc.pow(2, -calc.pow(3, 1/math.factorial(3))));
+				test(" 2 ^ ( - 3 ! ) \u221A 3 ", calc.pow(3, 1/calc.pow(2, -math.factorial(3))));
 
 				test("3!=6", true);
 				test("3!==6", true);
@@ -261,7 +259,7 @@
 
 				status = "Completed without errors";
 			}
-			doh.register("dojox.calc._Executor", [
+			doh.register("calc._Executor", [
 				{
 					name: "wait for Executor to load",
 					timeout: 5000,
@@ -279,6 +277,7 @@
 			]);
 			doh.run();
 		});
+	});
 	</script>
 </head>
 <body>
diff --git a/dojox/calc/tests/test_GraphPro.html b/dojox/calc/tests/test_GraphPro.html
index b6c8547..52bda2b 100644
--- a/dojox/calc/tests/test_GraphPro.html
+++ b/dojox/calc/tests/test_GraphPro.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>GraphPro Calculator Test</title>
@@ -15,28 +15,27 @@
 
 	<script type="text/javascript">
 		//TODO make the graphing window textboxes respond to the input buttons on the layout
-
-		dojo.require("dojox.calc.GraphPro");
-
-		dojo.require("dojo.data.ItemFileReadStore");
-		dojo.require("dojo.data.ItemFileWriteStore");
-		dojo.require("dojox.calc.toFrac");
-		dojo.require("dojox.calc.FuncGen");
-		// dojo.require("dojox.calc.Grapher"); // already required in GraphPro
-		dojo.require("dojo.number");
-
-		dojo.addOnLoad(function(){
-			new dojox.calc.GraphPro(
-			{
-				readStore: new dojo.data.ItemFileReadStore({data: {identifier: 'name', items:[{name:"test2", args:"a, b", body:"return a/b;"}]}}),
-				writeStore: new dojo.data.ItemFileWriteStore({data: {identifier: 'name', items:[{name:"test", args:"a, b", body:"return a/b;"}, {name:"newFunc", args:"", body:"var a,b; return test(b=8,a=4);"}, {name:"exampleFunction", args:"x", body:"return 2*x;"}]}})
-			}, "calculator");
-
-		});
-
+		require([
+			"dojox/calc/GraphPro",
+			"dojo/ready",
+			"dojo/store/Memory",
+			"dojox/calc/toFrac", // optional add-ons
+			"dojox/calc/FuncGen", // optional add-ons
+			"dojo/parser"
+		]);
 	</script>
 </head>
 <body class=claro>
-	<div id="calculator"></div>
+	<div id="calculator" data-dojo-type="dojox.calc.GraphPro" data-dojo-props='
+		readStore: new dojo.store.Memory({ idProperty: "name", data: [
+			{ name: "test2", args: "a, b", body: "return a/b;"}
+		]}),
+		writeStore: new dojo.store.Memory({ idProperty: "name", data: [
+			{ name: "test", args: "a, b", body: "return a/b;" },
+			{ name: "newFunc", args: "", body: "var a,b; return test(b=8,a=4);" },
+			{ name: "exampleFunction", args:"x", body:"return 2*x;" }
+		]})'
+	>
+	</div>
 </body>
 </html>
diff --git a/dojox/calc/tests/test_Standard.html b/dojox/calc/tests/test_Standard.html
index fa71851..f722702 100644
--- a/dojox/calc/tests/test_Standard.html
+++ b/dojox/calc/tests/test_Standard.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>Standard Calculator Test</title>
@@ -11,23 +11,27 @@
 		@import "../../../dojox/calc/resources/Standard.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: false"></script>
 
 	<script type="text/javascript">
-		//TODO make the graphing window textboxes respond to the input buttons on the layout
-
-		dojo.require("dojox.calc.Standard");
-		dojo.require("dojo.data.ItemFileReadStore");
-		dojo.require("dojo.data.ItemFileWriteStore");
-		dojo.require("dojo.number");
-
-		dojo.addOnLoad(function(){
-			new dojox.calc.Standard(
-			{
-				readStore: new dojo.data.ItemFileReadStore({data: {identifier: 'name', items:[{name:"test2", args:"a, b", body:"return a/b;"}]}}),
-				writeStore: new dojo.data.ItemFileWriteStore({data: {identifier: 'name', items:[{name:"test", args:"a, b", body:"for(var i = 0;i<1;i++)return a/b;"}, {name:"newFunc", args:"", body:"var a,b; return test(b=8,a=4);"}, {name:"exampleFunction", args:"x", body:"return 2*x;"}]}})
-			}, "calculator");
-
+		require([
+			"dojox/calc/Standard",
+			"dojo/ready",
+			"dojo/store/Memory"
+		], function(Standard, ready, Memory){
+			ready(function(){
+				new Standard(
+				{
+					readStore: new Memory({ idProperty: "name", data: [
+						{ name: "test2", args: "a, b", body: "return a/b;"}
+					]}),
+					writeStore: new Memory({ idProperty: "name", data: [
+						{ name: "test", args: "a, b", body: "for(var i = 0;i<1;i++)return a/b;" },
+						{ name: "newFunc", args: "", body: "var a,b; return test(b=8,a=4);" },
+						{ name: "exampleFunction", args:"x", body:"return 2*x;" }
+					]})
+				}, "calculator");
+			});
 		});
 
 	</script>
diff --git a/dojox/calc/toFrac.js b/dojox/calc/toFrac.js
index 403915d..8871edc 100644
--- a/dojox/calc/toFrac.js
+++ b/dojox/calc/toFrac.js
@@ -1,137 +1,142 @@
-define("dojox/calc/toFrac", ["dojo"], function(dojo) {
+define([
+	"dojo/_base/lang",
+	"dojox/calc/_Executor"
+], function(lang, calc) {
 
-(function(){
+	var multiples;
 
-	var a = [];
-	var sqrts = [2,3,5,6,7,10,11,13,14,15,17,19,21,22,23,26,29,
-		30,31,33,34,35,37,38,39,41,42,43,46,47,51,53,55,57,58,59,
-		61,62,65,66,67,69,70,71,73,74,77,78,79,82,83,85,86,87,89,91,93,94,95,97];
-	var _fracHashInitialized = false;
-	var i = -3;
-	var d = 2;
-	var epsilon = 1e-15 / 9;
-
-function _fracHashInit(searchNumber){
-	// summary
-	//	make a fairly large hash table of some fractions, sqrts, etc
-	var m, mt;
-	while(i < sqrts.length){
-		switch(i){
-			case -3:
-				m = 1;
-				mt = '';
-				break;
-			case -2:
-				m = Math.PI;
-				mt = 'pi';
-				break;
-			case -1:
-				m = Math.sqrt(Math.PI);
-				mt = '\u221A(pi)';
-				break;
-			default:
-				m = Math.sqrt(sqrts[i]);
-				mt = "\u221A(" + sqrts[i] + ")";
+	function _fracHashInit(){
+		var sqrts = [
+			5,6,7,10,11,13,14,15,17,19,21,22,23,26,29,
+			30,31,33,34,35,37,38,39,41,42,43,46,47,51,53,55,57,58,59,
+			61,62,65,66,67,69,70,71,73,74,77,78,79,82,83,85,86,87,89,91,93,94,95,97
+		];
+		multiples = { "1":1, "\u221A(2)":Math.sqrt(2), "\u221A(3)":Math.sqrt(3), "pi":Math.PI };
+		// populate the rest of the multiples array
+		for(var i in sqrts){
+			var n = sqrts[i];
+			multiples["\u221A("+n+")"] = Math.sqrt(n);
 		}
-		while(d <= 100){
-			for(n = 1; n < (m == 1 ? d : 100); n++){
-				var r = m * n / d;
-				var f = dojox.calc.approx(r);
-				if(!(f in a)){
-					// make sure that it is simplified so that toFrac(pi) doesn't get 2*pi/2
-					if(n==d){
-						n=1;
-						d=1;
-					}
-					a[f] = {n:n, d:d, m:m, mt:mt};
-					if(f == searchNumber){ searchNumber = undefined; } // found number, so return and finish hash in nbackground
+		multiples["\u221A(pi)"] = Math.sqrt(Math.PI);
+	}
+
+	function _fracLookup(number){
+		function findSimpleFraction(fraction){
+			var denom1Low = Math.floor(1 / fraction);
+			// fraction <= 1/denom1Low 
+			var quotient = calc.approx(1 / denom1Low);
+			if(quotient == fraction){ return { n:1, d:denom1Low }; }
+			var denom1High = denom1Low + 1;
+			// 1/denom1High <= fraction < 1/denom1Low 
+			quotient = calc.approx(1 / denom1High);
+			if(quotient == fraction){ return { n:1, d:denom1High }; }
+			if(denom1Low >= 50){ return null; } // only 1's in the numerator beyond this point
+			// 1/denom1High < fraction < 1/denom1Low 
+			var denom2 = denom1Low + denom1High;
+			quotient = calc.approx(2 / denom2);
+			// 1/denom1High < 2/(denom1Low+denom1High) < 1/denom1Low 
+			if(quotient == fraction){ return { n:2, d:denom2 }; }
+			if(denom1Low >= 34){ return null; } // only 1's and 2's in the numerator beyond this point
+			var less2 = fraction < quotient;
+			// if less2
+			//	1/denom1High < fraction < 2/(denom1Low+denom1High)
+			// else
+			//	2/(denom1Low+denom1High) < fraction < 1/denom1Low
+			var denom4 = denom2 * 2 + (less2 ? 1 : -1);
+			quotient = calc.approx(4 / denom4);
+			// 1/denom1High < 4/(2*denom1Low+2*denom1High+1) < 2/(denom1Low+denom1High) < 4/(2*denom1Low+2*denom1High-1) < 1/denom1Low 
+			if(quotient == fraction){ return { n:4, d:denom4 }; }
+			var less4 = fraction < quotient;
+			// we've already checked for 1, 2 and 4, but now see if we need to check for 3 in the numerator
+			if((less2 && !less4) || (!less2 && less4)){
+				var denom3 = (denom2 + denom4) >> 1;
+				quotient = calc.approx(3 / denom3);
+				// 1/denom1High < 4/(2*denom1Low+2*denom1High+1) < 3/((3*denom1Low+3*denom1High+1)/2) < 2/(denom1Low+denom1High) < 3/((3*denom1Low+3*denom1High-1)/2) < 4/(2*denom1Low+2*denom1High-1) < 1/denom1Low 
+				if(quotient == fraction){ return { n:3, d:denom3 }; }
+			}
+			if(denom1Low >= 20){ return null; } // only 1's, 2's, 3's, and 4's in the numerator beyond this point
+			// if less2
+			// 	if less4
+			//		1/denom1High < fraction < 4/(2*denom1Low+2*denom1High+1)
+			//	else
+			//		4/(2*denom1Low+2*denom1High+1) < fraction < 2/(denom1Low+denom1High)
+			// else
+			// 	if less4
+			//		2/(denom1Low+denom1High) < fraction < 4/(2*denom1Low+2*denom1High-1)
+			//	else
+			//		4/(2*denom1Low+2*denom1High-1) < fraction < 1/denom1Low
+			var smallestDenom = denom2 + denom1Low * 2;
+			var largestDenom = smallestDenom + 2;
+			for(var numerator = 5; smallestDenom <= 100; numerator++){ // start with 5 in the numerator
+				smallestDenom += denom1Low;
+				largestDenom += denom1High;
+				var startDenom = less2 ? ((largestDenom + smallestDenom + 1) >> 1) : smallestDenom;
+				var stopDenom = less2 ? largestDenom : ((largestDenom + smallestDenom - 1) >> 1);
+				startDenom = less4 ? ((startDenom + stopDenom) >> 1) : startDenom;
+				stopDenom = less4 ? stopDenom : ((startDenom + stopDenom) >> 1);
+				for(var thisDenom = startDenom; thisDenom <= stopDenom; thisDenom++){
+					if(numerator & 1 == 0 && thisDenom & 1 == 0){ continue; } // skip where n and d are both even
+					quotient = calc.approx(numerator / thisDenom);
+					if(quotient == fraction){ return { n:numerator, d:thisDenom }; }
+					if(quotient < fraction){ break; } // stop since the values will just get smaller
 				}
 			}
-			d++;
-			if(searchNumber == undefined){
-				setTimeout(function(){ _fracHashInit() }, 1);
-				return;
+			return null;
+		}
+		number = Math.abs(number);
+		for(var mt in multiples){
+			var multiple = multiples[mt];
+			var simpleFraction = number / multiple;
+			var wholeNumber = Math.floor(simpleFraction);
+			simpleFraction = calc.approx(simpleFraction - wholeNumber);
+			if(simpleFraction == 0){
+				return { mt:mt, m:multiple, n:wholeNumber, d:1 };
+			}else{
+				var a = findSimpleFraction(simpleFraction);
+				if(!a){ continue; }
+				return { mt:mt, m:multiple, n:(wholeNumber * a.d + a.n), d:a.d };
 			}
 		}
-		d = 2;
-		i++;
+		return null;
 	}
-	_fracHashInitialized = true;
-}
 
-// this 1 is standard and the other is advanced and could be a
-// separate dojo.require if the user wants the function (and slow init)
-function isInt(n){
-	return Math.floor(n) == n;
-}
+	// make the hash
+	_fracHashInit();
 
-// make the hash
-_fracHashInit();
+	// add toFrac to the calculator
+	return lang.mixin(calc, {
+		toFrac: function(number){// get a string fraction for a decimal with a set range of numbers, based on the hash
+			var f = _fracLookup(number);
+			return f ? ((number < 0 ? '-' : '') + (f.m == 1 ? '' : (f.n == 1 ? '' : (f.n + '*'))) + (f.m == 1 ? f.n : f.mt) + ((f.d == 1 ? '' : '/' + f.d))) : number;
+			//return f ? ((number < 0 ? '-' : '') + (f.m == 1 ? '' : (f.n == 1 ? '' : (f.n + '*'))) + (f.m == 1 ? f.n : f.mt) + '/' + f.d) : number;
+		},
+		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
+			//	Wrapper to Math.pow(base, exponent) to handle (-27) ^ (1/3)
+			function isInt(n){
+				return Math.floor(n) == n;
+			}
 
-// advanced _fracLookup
-function _fracLookup(number){
-	function retryWhenInitialized(){
-		_fracHashInit(number);
-		return _fracLookup(number);
-	}
-	number = Math.abs(number);
-	var f = a[dojox.calc.approx(number)];
-	if(!f && !_fracHashInitialized){
-		return retryWhenInitialized();
-	}
-	if(!f){
-		var i = Math.floor(number);
-		if(i == 0) { return _fracHashInitialized ? null : retryWhenInitialized(); }
-		var n = number % 1;
-		if(n == 0){
-			return { m: 1, mt: 1, n: number, d: 1 }
-		}
-		f = a[dojox.calc.approx(n)];
-		if(!f || f.m != 1){
-			var inv = dojox.calc.approx(1 / n);
-			return isInt(inv) ? { m: 1, mt: 1, n: 1, d: inv } : (_fracHashInitialized ? null : retryWhenInitialized());
-		}else{
-			return { m: 1, mt: 1, n: (i * f.d + f.n), d: f.d };
+			if(base>0||isInt(exponent)){
+				return Math.pow(base, exponent);
+			}else{
+				var f = _fracLookup(exponent);
+				if(base >= 0){
+					return (f && f.m == 1)
+						? Math.pow(Math.pow(base, 1 / f.d), exponent < 0 ? -f.n : f.n) // 32 ^ (2/5) is much more accurate if done as (32 ^ (1/5)) ^ 2
+						: Math.pow(base, exponent);
+				}else{	// e.g. (1/3) root of -27 = -3, 1 / exponent must be an odd integer for a negative base
+					return (f && f.d & 1) ? Math.pow(Math.pow(-Math.pow(-base, 1 / f.d), exponent < 0 ? -f.n : f.n), f.m) : NaN;
+				}
+			}
 		}
-	}
-	return f;
-}
-
-// add toFrac to the calculator
-dojo.mixin(dojox.calc, {
-	toFrac: function(number){// get a string fraction for a decimal with a set range of numbers, based on the hash
+	});
+/*
+	function reduceError(number){
 		var f = _fracLookup(number);
-		return f ? ((number < 0 ? '-' : '') + (f.m == 1 ? '' : (f.n == 1 ? '' : (f.n + '*'))) + (f.m == 1 ? f.n : f.mt) + ((f.d == 1 ? '' : '/' + f.d))) : number;
-		//return f ? ((number < 0 ? '-' : '') + (f.m == 1 ? '' : (f.n == 1 ? '' : (f.n + '*'))) + (f.m == 1 ? f.n : f.mt) + '/' + f.d) : number;
-	},
-	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
-	//	Wrapper to Math.pow(base, exponent) to handle (-27) ^ (1/3)
-
-	if(base>0||isInt(exponent)){
-		return Math.pow(base, exponent);
-	}else{
-		var f = _fracLookup(exponent);
-		if(base >= 0){
-			return (f && f.m == 1)
-				? Math.pow(Math.pow(base, 1 / f.d), exponent < 0 ? -f.n : f.n) // 32 ^ (2/5) is much more accurate if done as (32 ^ (1/5)) ^ 2
-				: Math.pow(base, exponent);
-		}else{	// e.g. (1/3) root of -27 = -3, 1 / exponent must be an odd integer for a negative base
-			return (f && f.d & 1) ? Math.pow(Math.pow(-Math.pow(-base, 1 / f.d), exponent < 0 ? -f.n : f.n), f.m) : NaN;
-		}
+		if(!f){ f = _fracLookup(number); }
+		return f ? ((number < 0 ? -1 : 1) * f.n * f.m / f.d) : number;
 	}
-}
-});
-/*
-function reduceError(number){
-	var f = _fracLookup(number);
-	if(!f){ f = _fracLookup(number); }
-	return f ? ((number < 0 ? -1 : 1) * f.n * f.m / f.d) : number;
-}
 */
-})();
-
-
-return dojox.calc.toFrac;
 });
diff --git a/dojox/charting/BidiSupport.js b/dojox/charting/BidiSupport.js
new file mode 100644
index 0000000..fd99ddd
--- /dev/null
+++ b/dojox/charting/BidiSupport.js
@@ -0,0 +1,264 @@
+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;
+	}
+		
+});
diff --git a/dojox/charting/Chart.js b/dojox/charting/Chart.js
index 161d4b9..afe0c4b 100644
--- a/dojox/charting/Chart.js
+++ b/dojox/charting/Chart.js
@@ -1,44 +1,39 @@
-dojo.provide("dojox.charting.Chart");
-
-dojo.require("dojox.gfx");
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.functional.fold");
-dojo.require("dojox.lang.functional.reversed");
-
-dojo.require("dojox.charting.Element");
-dojo.require("dojox.charting.Theme");
-dojo.require("dojox.charting.Series");
-dojo.require("dojox.charting.axis2d.common");
-
-/*=====
-dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
-	//	summary:
-	//		The keyword arguments that can be passed in a Chart constructor.
-	//
-	//	margins: Object?
-	//		Optional margins for the chart, in the form of { l, t, r, b}.
-	//	stroke: dojox.gfx.Stroke?
-	//		An optional outline/stroke for the chart.
-	//	fill: dojox.gfx.Fill?
-	//		An optional fill for the chart.
-	//	delayInMs: Number
-	//		Delay in ms for delayedRender(). Default: 200.
-	this.margins = margins;
-	this.stroke = stroke;
-	this.fill = fill;
-	this.delayInMs = delayInMs;
-}
- =====*/
-(function(){
-	var df = dojox.lang.functional, dc = dojox.charting, g = dojox.gfx,
-		clear = df.lambda("item.clear()"),
-		purge = df.lambda("item.purgeGroup()"),
-		destroy = df.lambda("item.destroy()"),
-		makeClean = df.lambda("item.dirty = false"),
-		makeDirty = df.lambda("item.dirty = true"),
-		getName = df.lambda("item.name");
+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, 
+	 		 dom, domGeom, domConstruct, Color, has,
+	 		 Element, Theme, Series, common, 
+	 		 g, func, funcFold, funcReversed){
+	/*=====
+	dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
+		//	summary:
+		//		The keyword arguments that can be passed in a Chart constructor.
+		//
+		//	margins: Object?
+		//		Optional margins for the chart, in the form of { l, t, r, b}.
+		//	stroke: dojox.gfx.Stroke?
+		//		An optional outline/stroke for the chart.
+		//	fill: dojox.gfx.Fill?
+		//		An optional fill for the chart.
+		//	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,
+		clear = func.lambda("item.clear()"),
+		purge = func.lambda("item.purgeGroup()"),
+		destroy = func.lambda("item.destroy()"),
+		makeClean = func.lambda("item.dirty = false"),
+		makeDirty = func.lambda("item.dirty = true"),
+		getName = func.lambda("item.name");
 
-	dojo.declare("dojox.charting.Chart", null, {
+	declare("dojox.charting.Chart", null, {
 		//	summary:
 		//		The main chart object in dojox.charting.  This will create a two dimensional
 		//		chart based on dojox.gfx.
@@ -104,7 +99,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 		//	|			{ stroke: { color: "green" }, fill: "lightgreen" }
 		//	|		)
 		//	|		.render();
-		//
+		
 		//	theme: dojox.charting.Theme?
 		//		An optional theme to use for styling the chart.
 		//	axes: dojox.charting.Axis{}?
@@ -162,21 +157,21 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			this.coords = null;
 
 			// create a surface
-			this.node = dojo.byId(node);
-			var box = dojo.marginBox(node);
+			this.node = dom.byId(node);
+			var box = domGeom.getMarginBox(node);
 			this.surface = g.createSurface(this.node, box.w || 400, box.h || 300);
 		},
 		destroy: function(){
 			//	summary:
 			//		Cleanup when a chart is to be destroyed.
 			//	returns: void
-			dojo.forEach(this.series, destroy);
-			dojo.forEach(this.stack,  destroy);
-			df.forIn(this.axes, destroy);
-            if(this.chartTitle && this.chartTitle.tagName){
-                // destroy title if it is a DOM node
-			    dojo.destroy(this.chartTitle);
-            }
+			arr.forEach(this.series, destroy);
+			arr.forEach(this.stack,  destroy);
+			func.forIn(this.axes, destroy);
+			if(this.chartTitle && this.chartTitle.tagName){
+				// destroy title if it is a DOM node
+				domConstruct.destroy(this.chartTitle);
+			}
 			this.surface.destroy();
 		},
 		getCoords: function(){
@@ -185,10 +180,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			//		returned by dojo.coords.
 			//	returns: Object
 			//		The resulting coordinates of the chart.  See dojo.coords for details.
-			if(!this.coords){
-				this.coords = dojo.coords(this.node, true);
-			}
-			return this.coords;	//	Object
+			return html.coords(this.node, true); // Object
 		},
 		setTheme: function(theme){
 			//	summary:
@@ -210,15 +202,15 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			//		An optional keyword arguments object for use in defining details of an axis.
 			//	returns: dojox.charting.Chart
 			//		A reference to the current chart for functional chaining.
-            var axis, axisType = kwArgs && kwArgs.type || "Default";
-            if(typeof axisType == "string"){
-                if(!dc.axis2d || !dc.axis2d[axisType]){
-                    throw Error("Can't find axis: " + axisType + " - didn't you forget to dojo" + ".require() it?");
-                }
-                axis = new dc.axis2d[axisType](this, kwArgs);
-            }else{
-                axis = new axisType(this, kwArgs);
-            }
+			var axis, axisType = kwArgs && kwArgs.type || "Default";
+			if(typeof axisType == "string"){
+				if(!dc.axis2d || !dc.axis2d[axisType]){
+					throw Error("Can't find axis: " + axisType + " - Check " + "require() dependencies.");
+				}
+				axis = new dc.axis2d[axisType](this, kwArgs);
+			}else{
+				axis = new axisType(this, kwArgs);
+			}
 			axis.name = name;
 			axis.dirty = true;
 			if(name in this.axes){
@@ -266,14 +258,14 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			//	returns: dojox.charting.Chart
 			//		A reference to the current chart for functional chaining.
 			var plot, plotType = kwArgs && kwArgs.type || "Default";
-            if(typeof plotType == "string"){
-                if(!dc.plot2d || !dc.plot2d[plotType]){
-                    throw Error("Can't find plot: " + plotType + " - didn't you forget to dojo" + ".require() it?");
-                }
-                plot = new dc.plot2d[plotType](this, kwArgs);
-            }else{
-                plot = new plotType(this, kwArgs);
-            }
+			if(typeof plotType == "string"){
+				if(!dc.plot2d || !dc.plot2d[plotType]){
+					throw Error("Can't find plot: " + plotType + " - didn't you forget to dojo" + ".require() it?");
+				}
+				plot = new dc.plot2d[plotType](this, kwArgs);
+			}else{
+				plot = new plotType(this, kwArgs);
+			}
 			plot.name = name;
 			plot.dirty = true;
 			if(name in this.plots){
@@ -286,6 +278,15 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			this.dirty = true;
 			return this;	//	dojox.charting.Chart
 		},
+		getPlot: function(name){
+			//	summary:
+			//		Get the given plot, by name.
+			//	name: String
+			//		The name the plot was defined by.
+			//	returns: dojox.charting.plot2d.Base
+			//		The plot.
+			return this.stack[this.plots[name]];
+		},
 		removePlot: function(name){
 			//	summary:
 			//		Remove the plot defined using name from the chart's plot stack.
@@ -302,27 +303,27 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 				// remove the plot from the stack
 				this.stack.splice(index, 1);
 				// update indices to reflect the shift
-				df.forIn(this.plots, function(idx, name, plots){
+				func.forIn(this.plots, function(idx, name, plots){
 					if(idx > index){
 						plots[name] = idx - 1;
 					}
 				});
-                // remove all related series
-                var ns = dojo.filter(this.series, function(run){ return run.plot != name; });
-                if(ns.length < this.series.length){
-                    // kill all removed series
-                    dojo.forEach(this.series, function(run){
-                        if(run.plot == name){
-                            run.destroy();
-                        }
-                    });
-                    // rebuild all necessary data structures
-                    this.runs = {};
-                    dojo.forEach(ns, function(run, index){
-                        this.runs[run.plot] = index;
-                    }, this);
-                    this.series = ns;
-                }
+				// remove all related series
+				var ns = arr.filter(this.series, function(run){ return run.plot != name; });
+				if(ns.length < this.series.length){
+					// kill all removed series
+					arr.forEach(this.series, function(run){
+						if(run.plot == name){
+							run.destroy();
+						}
+					});
+					// rebuild all necessary data structures
+					this.runs = {};
+					arr.forEach(ns, function(run, index){
+						this.runs[run.plot] = index;
+					}, this);
+					this.series = ns;
+				}
 				// mark the chart as dirty
 				this.dirty = true;
 			}
@@ -333,7 +334,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			//		Returns an array of plot names in the current order
 			//		(the top-most plot is the first).
 			//	returns: Array
-			return df.map(this.stack, getName); // Array
+			return func.map(this.stack, getName); // Array
 		},
 		setPlotOrder: function(newOrder){
 			//	summary:
@@ -344,7 +345,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			//	returns: dojox.charting.Chart
 			//		A reference to the current chart for functional chaining.
 			var names = {},
-				order = df.filter(newOrder, function(name){
+				order = func.filter(newOrder, function(name){
 					if(!(name in this.plots) || (name in names)){
 						return false;
 					}
@@ -352,17 +353,17 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 					return true;
 				}, this);
 			if(order.length < this.stack.length){
-				df.forEach(this.stack, function(plot){
+				func.forEach(this.stack, function(plot){
 					var name = plot.name;
 					if(!(name in names)){
 						order.push(name);
 					}
 				});
 			}
-			var newStack = df.map(order, function(name){
+			var newStack = func.map(order, function(name){
 					return this.stack[this.plots[name]];
 				}, this);
-			df.forEach(newStack, function(plot, i){
+			func.forEach(newStack, function(plot, i){
 				this.plots[plot.name] = i;
 			}, this);
 			this.stack = newStack;
@@ -420,7 +421,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			//		the resultant series object.
 			//	returns: dojox.charting.Chart:
 			//		A reference to the current chart for functional chaining.
-			var run = new dc.Series(this, data, kwArgs);
+			var run = new Series(this, data, kwArgs);
 			run.name = name;
 			if(name in this.runs){
 				this.series[this.runs[name]].destroy();
@@ -435,6 +436,15 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			if(!("ymax" in run) && "max" in run){ run.ymax = run.max; }
 			return this;	//	dojox.charting.Chart
 		},
+		getSeries: function(name){
+			//	summary:
+			//		Get the given series, by name.
+			//	name: String
+			//		The name the series was defined by.
+			//	returns: dojox.charting.Series
+			//		The series.
+			return this.series[this.runs[name]];
+		},
 		removeSeries: function(name){
 			//	summary:
 			//		Remove the series defined by name from the chart.
@@ -451,7 +461,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 				// remove the run from the stack of series
 				this.series.splice(index, 1);
 				// update indices to reflect the shift
-				df.forIn(this.runs, function(idx, name, runs){
+				func.forIn(this.runs, function(idx, name, runs){
 					if(idx > index){
 						runs[name] = idx - 1;
 					}
@@ -487,7 +497,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			//	plotName: String:
 			//		Plot's name.
 			//	returns: Array
-			return df.map(df.filter(this.series, function(run){
+			return func.map(func.filter(this.series, function(run){
 					return run.plot == plotName;
 				}), getName);
 		},
@@ -501,7 +511,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			//	returns: dojox.charting.Chart
 			//		A reference to the current chart for functional chaining.
 			var plotName, names = {},
-				order = df.filter(newOrder, function(name){
+				order = func.filter(newOrder, function(name){
 					if(!(name in this.runs) || (name in names)){
 						return false;
 					}
@@ -516,19 +526,19 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 					names[name] = 1;
 					return true;
 				}, this);
-			df.forEach(this.series, function(run){
+			func.forEach(this.series, function(run){
 				var name = run.name;
 				if(!(name in names) && run.plot == plotName){
 					order.push(name);
 				}
 			});
-			var newSeries = df.map(order, function(name){
+			var newSeries = func.map(order, function(name){
 					return this.series[this.runs[name]];
 				}, this);
-			this.series = newSeries.concat(df.filter(this.series, function(run){
+			this.series = newSeries.concat(func.filter(this.series, function(run){
 				return run.plot != plotName;
 			}));
-			df.forEach(this.series, function(run, i){
+			func.forEach(this.series, function(run, i){
 				this.runs[run.name] = i;
 			}, this);
 			this.dirty = true;
@@ -587,22 +597,26 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 				// case 0, do not resize the div, just the surface
 				case 1:
 					// argument, override node box
-					box = dojo.mixin({}, width);
-					dojo.marginBox(this.node, box);
+					box = lang.mixin({}, width);
+					domGeom.setMarginBox(this.node, box);
 					break;
 				case 2:
 					box = {w: width, h: height};
 					// argument, override node box
-					dojo.marginBox(this.node, box);
+					domGeom.setMarginBox(this.node, box);
 					break;
 			}
 			// in all cases take back the computed box
-			box = dojo.marginBox(this.node);
-			// and set it on the surface
-			this.surface.setDimensions(box.w, box.h);
-			this.dirty = true;
-			this.coords = null;
-			return this.render();	//	dojox.charting.Chart
+			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
+			}else{
+				return this;
+			}
 		},
 		getGeometry: function(){
 			//	summary:
@@ -611,7 +625,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			//	returns: Object
 			//		An map of geometry objects, a one-to-one mapping of axes.
 			var ret = {};
-			df.forIn(this.axes, function(axis){
+			func.forIn(this.axes, function(axis){
 				if(axis.initialized()){
 					ret[axis.name] = {
 						name:		axis.name,
@@ -640,11 +654,11 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			var axis = this.axes[name];
 			if(axis){
 				axis.setWindow(scale, offset);
-				dojo.forEach(this.stack,function(plot){
+				arr.forEach(this.stack,function(plot){
 					if(plot.hAxis == name || plot.vAxis == name){
 						plot.zoom = zoom;
 					}
-				})
+				});
 			}
 			return this;	//	dojox.charting.Chart
 		},
@@ -667,7 +681,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			if(!("plotArea" in this)){
 				this.calculateGeometry();
 			}
-			df.forIn(this.axes, function(axis){
+			func.forIn(this.axes, function(axis){
 				var scale, offset, bounds = axis.getScaler().bounds,
 					s = bounds.span / (bounds.upper - bounds.lower);
 				if(axis.vertical){
@@ -679,7 +693,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 				}
 				axis.setWindow(scale, offset);
 			});
-			dojo.forEach(this.stack, function(plot){ plot.zoom = zoom; });
+			arr.forEach(this.stack, function(plot){ plot.zoom = zoom; });
 			return this;	//	dojox.charting.Chart
 		},
 		zoomIn:	function(name, range){
@@ -714,7 +728,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			}
 
 			// calculate geometry
-			var dirty = dojo.filter(this.stack, function(plot){
+			var dirty = arr.filter(this.stack, function(plot){
 					return plot.dirty ||
 						(plot.hAxis && this.axes[plot.hAxis].dirty) ||
 						(plot.vAxis && this.axes[plot.vAxis].dirty);
@@ -733,21 +747,21 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			this._makeDirty();
 
 			// clear old values
-			dojo.forEach(this.stack, clear);
+			arr.forEach(this.stack, clear);
 
 			// rebuild new connections, and add defaults
 
 			// set up a theme
 			if(!this.theme){
-				this.setTheme(new dojox.charting.Theme(dojox.charting._def));
+				this.setTheme(new Theme(dojox.charting._def));
 			}
 
 			// assign series
-			dojo.forEach(this.series, function(run){
+			arr.forEach(this.series, function(run){
 				if(!(run.plot in this.plots)){
-                    if(!dc.plot2d || !dc.plot2d.Default){
-                        throw Error("Can't find plot: Default - didn't you forget to dojo" + ".require() it?");
-                    }
+					if(!dc.plot2d || !dc.plot2d.Default){
+						throw Error("Can't find plot: Default - didn't you forget to dojo" + ".require() it?");
+					}
 					var plot = new dc.plot2d.Default(this, {});
 					plot.name = run.plot;
 					this.plots[run.plot] = this.stack.length;
@@ -756,7 +770,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 				this.stack[this.plots[run.plot]].addSeries(run);
 			}, this);
 			// assign axes
-			dojo.forEach(this.stack, function(plot){
+			arr.forEach(this.stack, function(plot){
 				if(plot.hAxis){
 					plot.setAxis(this.axes[plot.hAxis]);
 				}
@@ -771,13 +785,13 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			var dim = this.dim = this.surface.getDimensions();
 			dim.width  = g.normalizedLength(dim.width);
 			dim.height = g.normalizedLength(dim.height);
-			df.forIn(this.axes, clear);
+			func.forIn(this.axes, clear);
 			calculateAxes(this.stack, dim);
 
 			// assumption: we don't have stacked axes yet
 			var offsets = this.offsets = { l: 0, r: 0, t: 0, b: 0 };
-			df.forIn(this.axes, function(axis){
-				df.forIn(axis.getOffsets(), function(o, i){ offsets[i] += o; });
+			func.forIn(this.axes, function(axis){
+				func.forIn(axis.getOffsets(), function(o, i){ offsets[i] += o; });
 			});
 			// add title area
 			if(this.title){
@@ -789,14 +803,14 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 				offsets[this.titlePos=="top" ? "t":"b"] += (tsize + this.titleGap);
 			}
 			// add margins
-			df.forIn(this.margins, function(o, i){ offsets[i] += o; });
+			func.forIn(this.margins, function(o, i){ offsets[i] += o; });
 
 			// 2nd pass with realistic dimensions
 			this.plotArea = {
 				width: dim.width - offsets.l - offsets.r,
 				height: dim.height - offsets.t - offsets.b
 			};
-			df.forIn(this.axes, clear);
+			func.forIn(this.axes, clear);
 			calculateAxes(this.stack, this.plotArea);
 
 			return this;	//	dojox.charting.Chart
@@ -819,10 +833,10 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			this.calculateGeometry();
 
 			// go over the stack backwards
-			df.forEachRev(this.stack, function(plot){ plot.render(this.dim, this.offsets); }, this);
+			func.forEachRev(this.stack, function(plot){ plot.render(this.dim, this.offsets); }, this);
 
 			// go over axes
-			df.forIn(this.axes, function(axis){ axis.render(this.dim, this.offsets); }, this);
+			func.forIn(this.axes, function(axis){ axis.render(this.dim, this.offsets); }, this);
 
 			this._makeClean();
 
@@ -844,19 +858,19 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			var offsets = this.offsets, dim = this.dim, rect;
 
 			// get required colors
-			//var requiredColors = df.foldl(this.stack, "z + plot.getRequiredColors()", 0);
+			//var requiredColors = func.foldl(this.stack, "z + plot.getRequiredColors()", 0);
 			//this.theme.defineColors({num: requiredColors, cache: false});
 
 			// clear old shapes
-			dojo.forEach(this.series, purge);
-			df.forIn(this.axes, purge);
-			dojo.forEach(this.stack,  purge);
-            if(this.chartTitle && this.chartTitle.tagName){
-                // destroy title if it is a DOM node
-			    dojo.destroy(this.chartTitle);
+			arr.forEach(this.series, purge);
+			func.forIn(this.axes, purge);
+			arr.forEach(this.stack,  purge);
+			if(this.chartTitle && this.chartTitle.tagName){
+				// destroy title if it is a DOM node
+			    domConstruct.destroy(this.chartTitle);
             }
 			this.surface.clear();
-            this.chartTitle = null;
+			this.chartTitle = null;
 
 			// generate shapes
 
@@ -864,25 +878,30 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			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:  dim.width  - offsets.l - offsets.r + 2,
-					height: dim.height - offsets.t - offsets.b + 2
+					width:  w + 2,
+					height: h + 2
 				};
 			if(fill){
-				fill = dc.Element.prototype._shapeFill(dc.Element.prototype._plotFill(fill, dim, offsets), rect);
+				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:  dim.width  - offsets.l - offsets.r + 1,
-					height: dim.height - offsets.t - offsets.b + 1
+					width:  w + 1,
+					height: h + 1
 				}).setStroke(stroke);
 			}
 
 			// go over the stack backwards
-			df.foldr(this.stack, function(z, plot){ return plot.render(dim, offsets), 0; }, 0);
+			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);
@@ -891,21 +910,21 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			//	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 dojo.Color(dojo.style(node, "backgroundColor"));
+				var node = this.node, fill = new Color(html.style(node, "backgroundColor"));
 				while(fill.a==0 && node!=document.documentElement){
-					fill = new dojo.Color(dojo.style(node, "backgroundColor"));
+					fill = new Color(html.style(node, "backgroundColor"));
 					node = node.parentNode;
 				}
 			}
 
 			if(fill){
-				fill = dc.Element.prototype._plotFill(fill, dim, offsets);
+				fill = Element.prototype._plotFill(fill, dim, offsets);
 				if(offsets.l){	// left
 					rect = {
 						width:  offsets.l,
 						height: dim.height + 1
 					};
-					this.surface.createRect(rect).setFill(dc.Element.prototype._shapeFill(fill, rect));
+					this.surface.createRect(rect).setFill(Element.prototype._shapeFill(fill, rect));
 				}
 				if(offsets.r){	// right
 					rect = {
@@ -913,14 +932,14 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 						width:  offsets.r + 1,
 						height: dim.height + 2
 					};
-					this.surface.createRect(rect).setFill(dc.Element.prototype._shapeFill(fill, rect));
+					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(dc.Element.prototype._shapeFill(fill, rect));
+					this.surface.createRect(rect).setFill(Element.prototype._shapeFill(fill, rect));
 				}
 				if(offsets.b){	// bottom
 					rect = {
@@ -928,7 +947,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 						width:  dim.width + 1,
 						height: offsets.b + 2
 					};
-					this.surface.createRect(rect).setFill(dc.Element.prototype._shapeFill(fill, rect));
+					this.surface.createRect(rect).setFill(Element.prototype._shapeFill(fill, rect));
 				}
 			}
 			if(stroke){
@@ -941,9 +960,9 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			//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 || !dojo.isIE && !dojo.isOpera ? "html" : "gfx",
+					labelType = forceHtmlLabels || !has("ie") && !has("opera") ? "html" : "gfx",
 					tsize = g.normalizedLength(g.splitFontString(this.titleFont).size);
-				this.chartTitle = dc.axis2d.common.createText[labelType](
+				this.chartTitle = common.createText[labelType](
 					this,
 					this.surface,
 					dim.width/2,
@@ -956,7 +975,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			}
 
 			// go over axes
-			df.forIn(this.axes, function(axis){ axis.render(dim, offsets); });
+			func.forIn(this.axes, function(axis){ axis.render(dim, offsets); });
 
 			this._makeClean();
 
@@ -975,7 +994,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 
 			if(!this._delayedRenderHandle){
 				this._delayedRenderHandle = setTimeout(
-					dojo.hitch(this, function(){
+					lang.hitch(this, function(){
 						clearTimeout(this._delayedRenderHandle);
 						this._delayedRenderHandle = null;
 						this.render();
@@ -1023,16 +1042,16 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 		},
 		_makeClean: function(){
 			// reset dirty flags
-			dojo.forEach(this.axes,   makeClean);
-			dojo.forEach(this.stack,  makeClean);
-			dojo.forEach(this.series, makeClean);
+			arr.forEach(this.axes,   makeClean);
+			arr.forEach(this.stack,  makeClean);
+			arr.forEach(this.series, makeClean);
 			this.dirty = false;
 		},
 		_makeDirty: function(){
 			// reset dirty flags
-			dojo.forEach(this.axes,   makeDirty);
-			dojo.forEach(this.stack,  makeDirty);
-			dojo.forEach(this.series, makeDirty);
+			arr.forEach(this.axes,   makeDirty);
+			arr.forEach(this.stack,  makeDirty);
+			arr.forEach(this.series, makeDirty);
 			this.dirty = true;
 		},
 		_invalidateDependentPlots: function(plotName, /* Boolean */ verticalAxis){
@@ -1044,7 +1063,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 					if(axis && axis.dependOnData()){
 						axis.dirty = true;
 						// find all plots and mark them dirty
-						dojo.forEach(this.stack, function(p){
+						arr.forEach(this.stack, function(p){
 							if(p[axisName] && p[axisName] == plot[axisName]){
 								p.dirty = true;
 							}
@@ -1085,7 +1104,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 
 	function calculateAxes(stack, plotArea){
 		var plots = {}, axes = {};
-		dojo.forEach(stack, function(plot){
+		arr.forEach(stack, function(plot){
 			var stats = plots[plot.name] = plot.getSeriesStats();
 			if(plot.hAxis){
 				axes[plot.hAxis] = combineStats(axes[plot.hAxis], hSection(stats));
@@ -1094,7 +1113,7 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 				axes[plot.vAxis] = combineStats(axes[plot.vAxis], vSection(stats));
 			}
 		});
-		dojo.forEach(stack, function(plot){
+		arr.forEach(stack, function(plot){
 			var stats = plots[plot.name];
 			if(plot.hAxis){
 				hReplace(stats, axes[plot.hAxis]);
@@ -1105,4 +1124,6 @@ dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
 			plot.initializeScalers(plotArea, stats);
 		});
 	}
-})();
+	
+	return dojox.charting.Chart;
+});
diff --git a/dojox/charting/Chart2D.js b/dojox/charting/Chart2D.js
index 438f934..f425daf 100644
--- a/dojox/charting/Chart2D.js
+++ b/dojox/charting/Chart2D.js
@@ -1,35 +1,16 @@
-dojo.provide("dojox.charting.Chart2D");
-
-dojo.deprecated("dojox.charting.Chart2D", "Use dojo.charting.Chart instead and require all other components explicitly", "2.0");
-
-// require all axes to support references by name
-dojo.require("dojox.charting.axis2d.Default");
-dojo.require("dojox.charting.axis2d.Invisible");
-
-// require all plots to support references by name
-dojo.require("dojox.charting.plot2d.Default");
-dojo.require("dojox.charting.plot2d.Lines");
-dojo.require("dojox.charting.plot2d.Areas");
-dojo.require("dojox.charting.plot2d.Markers");
-dojo.require("dojox.charting.plot2d.MarkersOnly");
-dojo.require("dojox.charting.plot2d.Scatter");
-dojo.require("dojox.charting.plot2d.Stacked");
-dojo.require("dojox.charting.plot2d.StackedLines");
-dojo.require("dojox.charting.plot2d.StackedAreas");
-dojo.require("dojox.charting.plot2d.Columns");
-dojo.require("dojox.charting.plot2d.StackedColumns");
-dojo.require("dojox.charting.plot2d.ClusteredColumns");
-dojo.require("dojox.charting.plot2d.Bars");
-dojo.require("dojox.charting.plot2d.StackedBars");
-dojo.require("dojox.charting.plot2d.ClusteredBars");
-dojo.require("dojox.charting.plot2d.Grid");
-dojo.require("dojox.charting.plot2d.Pie");
-dojo.require("dojox.charting.plot2d.Bubble");
-dojo.require("dojox.charting.plot2d.Candlesticks");
-dojo.require("dojox.charting.plot2d.OHLC");
-dojo.require("dojox.charting.plot2d.Spider");
-
-// require the main file
-dojo.require("dojox.charting.Chart");
-
-dojox.charting.Chart2D = dojox.charting.Chart;
+define(["dojo/_base/kernel", "dojox", "./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");
+	// 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;
+});
diff --git a/dojox/charting/Chart3D.js b/dojox/charting/Chart3D.js
index 1c26ab4..8bdac03 100644
--- a/dojox/charting/Chart3D.js
+++ b/dojox/charting/Chart3D.js
@@ -1,15 +1,32 @@
-dojo.provide("dojox.charting.Chart3D");
+define(["dojo/_base/array", "dojo/dom","dojo/_base/declare", "dojo/_base/html", "dojox/gfx", "dojox/gfx3d"], 
+	function(arr, dom, declare, html, gfx, gfx3d){
+	// module:
+	//		dojox/charting/Chart3D
+	// summary:
+	//		This module provides basic 3d charting capablities (using 2d vector graphics to simulate 3d.
 
-dojo.require("dojox.gfx3d");
+	/*=====
+	dojox.charting.__Chart3DCtorArgs = function(node, lights, camera, theme){
+		//	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.
+	}
+	 =====*/
+	var observerVector = {x: 0, y: 0, z: 1}, v = gfx3d.vector, n = gfx.normalizedLength;
 
-(function(){
-	var observerVector = {x: 0, y: 0, z: 1}, v = dojox.gfx3d.vector, n = dojox.gfx.normalizedLength;
-
-	dojo.declare("dojox.charting.Chart3D", null, {
+	return declare("dojox.charting.Chart3D", null, {
 		constructor: function(node, lights, camera, theme){
 			// setup a view
-			this.node = dojo.byId(node);
-			this.surface = dojox.gfx.createSurface(this.node, n(this.node.style.width), n(this.node.style.height));
+			this.node = dom.byId(node);
+			this.surface = gfx.createSurface(this.node, n(this.node.style.width), n(this.node.style.height));
 			this.view = this.surface.createViewport();
 			this.view.setLights(lights.lights, lights.ambient, lights.specular);
 			this.view.setCameraTransform(camera);
@@ -47,14 +64,14 @@ dojo.require("dojox.gfx3d");
 		
 		// internal API
 		_add: function(array, item){
-			if(!dojo.some(array, function(i){ return i == item; })){
+			if(!arr.some(array, function(i){ return i == item; })){
 				array.push(item);
 				this.view.invalidate();
 			}
 			return this;
 		},
 		_remove: function(array, item){
-			var a = dojo.filter(array, function(i){ return i != item; });
+			var a = arr.filter(array, function(i){ return i != item; });
 			return a.length < array.length ? (array = a, this.invalidate()) : this;
 		},
 		_generateWalls: function(){
@@ -66,7 +83,7 @@ dojo.require("dojox.gfx3d");
 			return this;
 		},
 		_generatePlots: function(){
-			var depth = 0, m = dojox.gfx3d.matrix, i = 0;
+			var depth = 0, m = gfx3d.matrix, i = 0;
 			for(; i < this.plots.length; ++i){
 				depth += this.plots[i].getDepth();
 			}
@@ -79,4 +96,4 @@ dojo.require("dojox.gfx3d");
 			return this;
 		}
 	});
-})();
+});
diff --git a/dojox/charting/DataChart.js b/dojox/charting/DataChart.js
index 1b357d2..80de51e 100644
--- a/dojox/charting/DataChart.js
+++ b/dojox/charting/DataChart.js
@@ -1,9 +1,8 @@
-dojo.provide("dojox.charting.DataChart");
-dojo.require("dojox.charting.Chart2D");
-dojo.require("dojox.charting.themes.PlotKit.blue");
-dojo.experimental("dojox.charting.DataChart");
-
-(function(){
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/html", "dojo/_base/connect",
+	 "dojo/_base/array", "./Chart2D", "./themes/PlotKit/blue", "dojo/dom"], 
+	 function(kernel, lang, declare, html, hub, arr, Chart, blue, dom){
+	// FIXME: This module drags in all Charting modules because of the Chart2D dependency...it is VERY heavy
+	kernel.experimental("dojox.charting.DataChart");
 
 	// Defaults for axes
 	//	to be mixed in with xaxis/yaxis custom properties
@@ -39,8 +38,10 @@ dojo.experimental("dojox.charting.DataChart");
 		tension:2,
 		gap:2
 	};
-
-	dojo.declare("dojox.charting.DataChart", [dojox.charting.Chart2D], {
+	/*=====
+	var Chart = dojox.charting.Chart;
+	=====*/
+	return declare("dojox.charting.DataChart", Chart, {
 		//	summary:
 		//		DataChart
 		//		Extension to the 2D chart that connects to a data store in
@@ -113,7 +114,7 @@ dojo.experimental("dojox.charting.DataChart");
 		//
 		//		chartTheme: dojox.charting.themes.*
 		//			The theme to style the chart. Defaults to PlotKit.blue.
-		chartTheme: dojox.charting.themes.PlotKit.blue,
+		chartTheme: blue,
 		//
 		//		displayRange: Number
 		//			The number of major ticks to show on the xaxis
@@ -164,18 +165,18 @@ dojo.experimental("dojox.charting.DataChart");
 			//			chartPlot: Object
 			//				Options for chart elements (lines, bars, etc)
 
-			this.domNode = dojo.byId(node);
+			this.domNode = dom.byId(node);
 
-			dojo.mixin(this, kwArgs);
+			lang.mixin(this, kwArgs);
 
-			this.xaxis = dojo.mixin(dojo.mixin({}, _xaxis), kwArgs.xaxis);
+			this.xaxis = lang.mixin(lang.mixin({}, _xaxis), kwArgs.xaxis);
 			if(this.xaxis.labelFunc == "seriesLabels"){
-				this.xaxis.labelFunc = dojo.hitch(this, "seriesLabels");
+				this.xaxis.labelFunc = lang.hitch(this, "seriesLabels");
 			}
 
-			this.yaxis = dojo.mixin(dojo.mixin({}, _yaxis), kwArgs.yaxis);
+			this.yaxis = lang.mixin(lang.mixin({}, _yaxis), kwArgs.yaxis);
 			if(this.yaxis.labelFunc == "seriesLabels"){
-				this.yaxis.labelFunc = dojo.hitch(this, "seriesLabels");
+				this.yaxis.labelFunc = lang.hitch(this, "seriesLabels");
 			}
 
 			// potential event's collector
@@ -208,9 +209,9 @@ dojo.experimental("dojox.charting.DataChart");
 			this.addAxis("x", this.xaxis);
 			this.addAxis("y", this.yaxis);
 			chartPlot.type = kwArgs.type || "Markers"
-			this.addPlot("default", dojo.mixin(chartPlot, kwArgs.chartPlot));
+			this.addPlot("default", lang.mixin(chartPlot, kwArgs.chartPlot));
 
-			this.addPlot("grid", dojo.mixin(kwArgs.grid || {}, {type: "Grid", hMinorLines: true}));
+			this.addPlot("grid", lang.mixin(kwArgs.grid || {}, {type: "Grid", hMinorLines: true}));
 
 			if(this.showing){
 				this.render();
@@ -222,7 +223,7 @@ dojo.experimental("dojox.charting.DataChart");
 		},
 
 		destroy: function(){
-			dojo.forEach(this._events, dojo.disconnect);
+			arr.forEach(this._events, hub.disconnect);
 			this.inherited(arguments);
 		},
 
@@ -241,10 +242,10 @@ dojo.experimental("dojox.charting.DataChart");
 			this.label = this.store.getLabelAttributes();
 			this.queryOptions = queryOptions || queryOptions;
 
-			dojo.forEach(this._events, dojo.disconnect);
+			arr.forEach(this._events, hub.disconnect);
 			this._events = [
-				dojo.connect(this.store, "onSet", this, "onSet"),
-				dojo.connect(this.store, "onError", this, "onError")
+				hub.connect(this.store, "onSet", this, "onSet"),
+				hub.connect(this.store, "onError", this, "onError")
 			];
 			this.fetch();
 		},
@@ -253,7 +254,7 @@ dojo.experimental("dojox.charting.DataChart");
 			// summary:
 			//		If chart is hidden, show it
 			if(!this.showing){
-				dojo.style(this.domNode, "display", "");
+				html.style(this.domNode, "display", "");
 				this.showing = true;
 				this.render();
 			}
@@ -263,7 +264,7 @@ dojo.experimental("dojox.charting.DataChart");
 			//		If chart is showing, hide it
 			//		Prevents rendering while hidden
 			if(this.showing){
-				dojo.style(this.domNode, "display", "none");
+				html.style(this.domNode, "display", "none");
 				this.showing = false;
 			}
 		},
@@ -289,7 +290,7 @@ dojo.experimental("dojox.charting.DataChart");
 				if(!this.onSetItems[nm]){
 					this.onSetItems[nm] = item;
 				}
-				this.onSetInterval = setTimeout(dojo.hitch(this, function(){
+				this.onSetInterval = setTimeout(lang.hitch(this, function(){
 					clearTimeout(this.onSetInterval);
 					var items = [];
 					for(var nm in this.onSetItems){
@@ -342,9 +343,9 @@ dojo.experimental("dojox.charting.DataChart");
 			if(!items || !items.length){ return; }
 
 			if(this.items && this.items.length != items.length){
-				dojo.forEach(items, function(m){
+				arr.forEach(items, function(m){
 					var id = this.getProperty(m, "id");
-					dojo.forEach(this.items, function(m2, i){
+					arr.forEach(this.items, function(m2, i){
 						if(this.getProperty(m2, "id") == id){
 							this.items[i] = m2;
 						}
@@ -366,7 +367,7 @@ dojo.experimental("dojox.charting.DataChart");
 
 				this.seriesData[nm] = [];
 				this.seriesDataBk[nm] = [];
-				dojo.forEach(items, function(m, i){
+				arr.forEach(items, function(m, i){
 					var field = this.getProperty(m, this.fieldName);
 					this.seriesData[nm].push(field);
 				}, this);
@@ -374,7 +375,7 @@ dojo.experimental("dojox.charting.DataChart");
 			}else{
 
 				// each item is a seperate series.
-				dojo.forEach(items, function(m, i){
+				arr.forEach(items, function(m, i){
 					var nm = this.store.getLabel(m);
 					if(!this.seriesData[nm]){
 						this.seriesData[nm] = [];
@@ -383,7 +384,7 @@ dojo.experimental("dojox.charting.DataChart");
 
 					// the property in the item we are using
 					var field = this.getProperty(m, this.fieldName);
-					if(dojo.isArray(field)){
+					if(lang.isArray(field)){
 						// Data is an array, so it's a snapshot, and not
 						//	live, updating data
 						//
@@ -396,7 +397,7 @@ dojo.experimental("dojox.charting.DataChart");
 							//
 							// create empty chart elements by starting an array
 							//	with zeros until we reach our relevant data
-							var ar = dojo.map(new Array(i+1), function(){ return 0; });
+							var ar = arr.map(new Array(i+1), function(){ return 0; });
 							ar.push(Number(field));
 							this.seriesData[nm] = ar;
 
@@ -456,12 +457,12 @@ dojo.experimental("dojox.charting.DataChart");
 			//
 			if(!this.store){ return; }
 			this.store.fetch({query:this.query, queryOptions:this.queryOptions, start:this.start, count:this.count, sort:this.sort,
-				onComplete:dojo.hitch(this, function(data){
-					setTimeout(dojo.hitch(this, function(){
+				onComplete:lang.hitch(this, function(data){
+					setTimeout(lang.hitch(this, function(){
 						this.onData(data)
 					}),0);
 				}),
-				onError:dojo.hitch(this, "onError")
+				onError:lang.hitch(this, "onError")
 			});
 		},
 
@@ -470,9 +471,9 @@ dojo.experimental("dojox.charting.DataChart");
 			//		Convenience method to convert a label array of strings
 			//		into an array of objects
 			//
-			if(!axis.labels || dojo.isObject(axis.labels[0])){ return null; }
+			if(!axis.labels || lang.isObject(axis.labels[0])){ return null; }
 
-			axis.labels = dojo.map(axis.labels, function(ele, i){
+			axis.labels = arr.map(axis.labels, function(ele, i){
 				return {value:i, text:ele};
 			});
 			return null; // null
@@ -514,4 +515,4 @@ dojo.experimental("dojox.charting.DataChart");
 			this.resize(w, h);
 		}
 	});
-})();
\ No newline at end of file
+});
diff --git a/dojox/charting/DataSeries.js b/dojox/charting/DataSeries.js
index c8ef156..70dcb11 100644
--- a/dojox/charting/DataSeries.js
+++ b/dojox/charting/DataSeries.js
@@ -1,175 +1,150 @@
-dojo.provide("dojox.charting.DataSeries");
-
-dojo.require("dojox.lang.functional");
-
-dojo.declare("dojox.charting.DataSeries", null, {
-	constructor: function(store, kwArgs, value){
-		//	summary:
-		//		Series adapter for dojo.data stores.
-		//	store: Object:
-		//		A dojo.data store object.
-		//	kwArgs: Object:
-		//		A store-specific keyword parameters used for fetching items.
-		//		See dojo.data.api.Read.fetch().
-		//	value: Function|Object|String|Null:
-		//		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
-		//		an object and how to map them to an output. Or a string, which
-		//		is a numeric field name to use for plotting. If undefined, null
-		//		or empty string (the default), "value" field is extracted.
-		this.store = store;
-		this.kwArgs = kwArgs;
-
-		if(value){
-			if(dojo.isFunction(value)){
-				this.value = value;
-			}else if(dojo.isObject(value)){
-				this.value = dojo.hitch(this, "_dictValue",
-					dojox.lang.functional.keys(value), value);
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base/connect", "dojox/lang/functional"], 
+	function(Lang, declare, ArrayUtil, Hub, df){
+
+	return declare("dojox.charting.DataSeries", null, {
+		constructor: function(store, kwArgs, value){
+			//	summary:
+			//		Series adapter for dojo.data stores.
+			//	store: Object:
+			//		A dojo.data store object.
+			//	kwArgs: Object:
+			//		A store-specific keyword parameters used for fetching items.
+			//		See dojo.data.api.Read.fetch().
+			//	value: Function|Object|String|Null:
+			//		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
+			//		an object and how to map them to an output. Or a string, which
+			//		is a numeric field name to use for plotting. If undefined, null
+			//		or empty string (the default), "value" field is extracted.
+			this.store = store;
+			this.kwArgs = kwArgs;
+	
+			if(value){
+				if(Lang.isFunction(value)){
+					this.value = value;
+				}else if(Lang.isObject(value)){
+					this.value = Lang.hitch(this, "_dictValue",
+						df.keys(value), value);
+				}else{
+					this.value = Lang.hitch(this, "_fieldValue", value);
+				}
 			}else{
-				this.value = dojo.hitch(this, "_fieldValue", value);
+				this.value = Lang.hitch(this, "_defaultValue");
 			}
-		}else{
-			this.value = dojo.hitch(this, "_defaultValue");
-		}
-
-		this.data = [];
-
-		this._events = [];
-
-		if(this.store.getFeatures()["dojo.data.api.Notification"]){
-			this._events.push(
-				dojo.connect(this.store, "onNew", this, "_onStoreNew"),
-				dojo.connect(this.store, "onDelete", this, "_onStoreDelete"),
-				dojo.connect(this.store, "onSet", this, "_onStoreSet")
-			);
-		}
-
-		this.fetch();
-	},
-
-	destroy: function(){
-		//	summary:
-		//		Clean up before GC.
-		dojo.forEach(this._events, dojo.disconnect);
-	},
-
-	setSeriesObject: function(series){
-		//	summary:
-		//		Sets a dojox.charting.Series object we will be working with.
-		//	series: dojox.charting.Series:
-		//		Our interface to the chart.
-		this.series = series;
-	},
-
-	// value transformers
-
-	_dictValue: function(keys, dict, store, item){
-		var o = {};
-		dojo.forEach(keys, function(key){
-			o[key] = store.getValue(item, dict[key]);
-		});
-		return o;
-	},
-
-	_fieldValue: function(field, store, item){
-		return store.getValue(item, field);
-	},
-
-	_defaultValue: function(store, item){
-		return store.getValue(item, "value");
-	},
-
-	// store fetch loop
-
-	fetch: function(){
-		//	summary:
-		//		Fetches data from the store and updates a chart.
-		if(!this._inFlight){
-			this._inFlight = true;
-			var kwArgs = dojo.delegate(this.kwArgs);
-			kwArgs.onComplete = dojo.hitch(this, "_onFetchComplete");
-			kwArgs.onError = dojo.hitch(this, "onFetchError");
-			this.store.fetch(kwArgs);
-		}
-	},
-
-	_onFetchComplete: function(items, request){
-		this.items = items;
-		this._buildItemMap();
-		this.data = dojo.map(this.items, function(item){
-			return this.value(this.store, item);
-		}, this);
-		this._pushDataChanges();
-		this._inFlight = false;
-	},
-
-	onFetchError: function(errorData, request){
-		//	summary:
-		//		As stub to process fetch errors. Provide so user can attach to
-		//		it with dojo.connect(). See dojo.data.api.Read fetch() for
-		//		details: onError property.
-		this._inFlight = false;
-	},
-
-	_buildItemMap: function(){
-		if(this.store.getFeatures()["dojo.data.api.Identity"]){
-			var itemMap = {};
-			dojo.forEach(this.items, function(item, index){
-				itemMap[this.store.getIdentity(item)] = index;
-			}, this);
-			this.itemMap = itemMap;
-		}
-	},
-
-	_pushDataChanges: function(){
-		if(this.series){
-			this.series.chart.updateSeries(this.series.name, this);
-			this.series.chart.delayedRender();
-		}
-	},
-
-	// store notification handlers
-
-	_onStoreNew: function(){
-		// the only thing we can do is to re-fetch items
-		this.fetch();
-	},
-
-	_onStoreDelete: function(item){
-		// we cannot do anything with deleted item, the only way is to compare
-		// items for equality
-		if(this.items){
-			var flag = dojo.some(this.items, function(it, index){
-				if(it === item){
-					this.items.splice(index, 1);
-					this._buildItemMap();
-					this.data.splice(index, 1);
-					return true;
-				}
-				return false;
+	
+			this.data = [];
+	
+			this._events = [];
+	
+			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")
+				);
+			}
+	
+			this.fetch();
+		},
+	
+		destroy: function(){
+			//	summary:
+			//		Clean up before GC.
+			ArrayUtil.forEach(this._events, Hub.disconnect);
+		},
+	
+		setSeriesObject: function(series){
+			//	summary:
+			//		Sets a dojox.charting.Series object we will be working with.
+			//	series: dojox.charting.Series:
+			//		Our interface to the chart.
+			this.series = series;
+		},
+	
+		// value transformers
+	
+		_dictValue: function(keys, dict, store, item){
+			var o = {};
+			ArrayUtil.forEach(keys, function(key){
+				o[key] = store.getValue(item, dict[key]);
+			});
+			return o;
+		},
+	
+		_fieldValue: function(field, store, item){
+			return store.getValue(item, field);
+		},
+	
+		_defaultValue: function(store, item){
+			return store.getValue(item, "value");
+		},
+	
+		// store fetch loop
+	
+		fetch: function(){
+			//	summary:
+			//		Fetches data from the store and updates a chart.
+			if(!this._inFlight){
+				this._inFlight = true;
+				var kwArgs = Lang.delegate(this.kwArgs);
+				kwArgs.onComplete = Lang.hitch(this, "_onFetchComplete");
+				kwArgs.onError = Lang.hitch(this, "onFetchError");
+				this.store.fetch(kwArgs);
+			}
+		},
+	
+		_onFetchComplete: function(items, request){
+			this.items = items;
+			this._buildItemMap();
+			this.data = ArrayUtil.map(this.items, function(item){
+				return this.value(this.store, item);
 			}, this);
-			if(flag){
-				this._pushDataChanges();
+			this._pushDataChanges();
+			this._inFlight = false;
+		},
+	
+		onFetchError: function(errorData, request){
+			//	summary:
+			//		As stub to process fetch errors. Provide so user can attach to
+			//		it with dojo.connect(). See dojo.data.api.Read fetch() for
+			//		details: onError property.
+			this._inFlight = false;
+		},
+	
+		_buildItemMap: function(){
+			if(this.store.getFeatures()["dojo.data.api.Identity"]){
+				var itemMap = {};
+				ArrayUtil.forEach(this.items, function(item, index){
+					itemMap[this.store.getIdentity(item)] = index;
+				}, this);
+				this.itemMap = itemMap;
 			}
-		}
-	},
-
-	_onStoreSet: function(item){
-		if(this.itemMap){
-			// we can use our handy item map, if the store supports Identity
-			var id = this.store.getIdentity(item), index = this.itemMap[id];
-			if(typeof index == "number"){
-				this.data[index] = this.value(this.store, this.items[index]);
-				this._pushDataChanges();
+		},
+	
+		_pushDataChanges: function(){
+			if(this.series){
+				this.series.chart.updateSeries(this.series.name, this);
+				this.series.chart.delayedRender();
 			}
-		}else{
-			// otherwise we have to rely on item's equality
+		},
+	
+		// store notification handlers
+	
+		_onStoreNew: function(){
+			// the only thing we can do is to re-fetch items
+			this.fetch();
+		},
+	
+		_onStoreDelete: function(item){
+			// we cannot do anything with deleted item, the only way is to compare
+			// items for equality
 			if(this.items){
-				var flag = dojo.some(this.items, function(it, index){
+				var flag = ArrayUtil.some(this.items, function(it, index){
 					if(it === item){
-						this.data[index] = this.value(this.store, it);
+						this.items.splice(index, 1);
+						this._buildItemMap();
+						this.data.splice(index, 1);
 						return true;
 					}
 					return false;
@@ -178,6 +153,31 @@ dojo.declare("dojox.charting.DataSeries", null, {
 					this._pushDataChanges();
 				}
 			}
+		},
+	
+		_onStoreSet: function(item){
+			if(this.itemMap){
+				// we can use our handy item map, if the store supports Identity
+				var id = this.store.getIdentity(item), index = this.itemMap[id];
+				if(typeof index == "number"){
+					this.data[index] = this.value(this.store, this.items[index]);
+					this._pushDataChanges();
+				}
+			}else{
+				// otherwise we have to rely on item's equality
+				if(this.items){
+					var flag = ArrayUtil.some(this.items, function(it, index){
+						if(it === item){
+							this.data[index] = this.value(this.store, it);
+							return true;
+						}
+						return false;
+					}, this);
+					if(flag){
+						this._pushDataChanges();
+					}
+				}
+			}
 		}
-	}
+	});
 });
diff --git a/dojox/charting/Element.js b/dojox/charting/Element.js
index 9450396..fa42b3d 100644
--- a/dojox/charting/Element.js
+++ b/dojox/charting/Element.js
@@ -1,360 +1,364 @@
-dojo.provide("dojox.charting.Element");
-
-dojo.require("dojox.gfx");
-
-dojo.declare("dojox.charting.Element", null, {
-	//	summary:
-	//		A base class that is used to build other elements of a chart, such as
-	//		a series.
-	//	chart: dojox.charting.Chart2D
-	//		The parent chart for this element.
-	//	group: dojox.gfx.Group
-	//		The visual GFX group representing this element.
-	//	htmlElement: Array
-	//		Any DOMNodes used as a part of this element (such as HTML-based labels).
-	//	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){
+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){
+	
+	return declare("dojox.charting.Element", null, {
 		//	summary:
-		//		Creates a new charting element.
-		//	chart: dojox.charting.Chart2D
-		//		The chart that this element belongs to.
-		this.chart = chart;
-		this.group = null;
-		this.htmlElements = [];
-		this.dirty = true;
-		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:
-		//		Clear any elements out of our group, and destroy the group.
-		//	returns: dojox.charting.Element
-		//		A reference to this object for functional chaining.
-		this.destroyHtmlElements();
-		if(this.group){
-			this.group.clear();
-			this.group.removeShape();
+		//		A base class that is used to build other elements of a chart, such as
+		//		a series.
+		//	chart: dojox.charting.Chart
+		//		The parent chart for this element.
+		//	group: dojox.gfx.Group
+		//		The visual GFX group representing this element.
+		//	htmlElement: Array
+		//		Any DOMNodes used as a part of this element (such as HTML-based labels).
+		//	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:
+			//		Creates a new charting element.
+			//	chart: dojox.charting.Chart
+			//		The chart that this element belongs to.
+			this.chart = chart;
 			this.group = null;
-		}
-		this.dirty = true;
-		if(this._events.length){
-			dojo.forEach(this._events, function(item){
-				item.shape.disconnect(item.handle);
-			});
-			this._events = [];
-		}
-		return this;	//	dojox.charting.Element
-	},
-	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.destroyHtmlElements();
-		if(!creator){ creator = this.chart.surface; }
-		if(this.group){
-			this.group.clear();
-		}else{
-			this.group = creator.createGroup();
-		}
-		this.dirty = true;
-		return this;	//	dojox.charting.Element
-	},
-	destroyHtmlElements: function(){
-		//	summary:
-		//		Destroy any DOMNodes that may have been created as a part of this element.
-		if(this.htmlElements.length){
-			dojo.forEach(this.htmlElements, dojo.destroy);
 			this.htmlElements = [];
-		}
-	},
-	destroy: function(){
-		//	summary:
-		//		API addition to conform to the rest of the Dojo Toolkit's standard.
-		this.purgeGroup();
-	},
-	//text utilities
-	getTextWidth: function(s, font){
-		return dojox.gfx._base._getTextBox(s, {font: font}).w || 0;
-	},
-	getTextWithLimitLength: function(s, font, limitWidth, truncated){
-		//	summary:
-		//		Get the truncated string based on the limited width in px(dichotomy algorithm)
-		//	s: String?
-		//		candidate text.
-		//	font: String?
-		//		text's font style.
-		//	limitWidth: Number?
-		//		text limited width in px.
-		//	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) {
-			return {
-				text: "",
-				truncated: truncated || false
-			};
-		}
-		if(!limitWidth || limitWidth <= 0){
-			return {
-				text: s,
-				truncated: truncated || false
-			};
-		}
-		var delta = 2,
-			//golden section for dichotomy algorithm
-			trucPercentage = 0.618,
-			minStr = s.substring(0,1) + this.trailingSymbol,
-			minWidth = this.getTextWidth(minStr, font);
-		if (limitWidth <= minWidth) {
-			return {
-				text: minStr,
-				truncated: true
-			};
-		}
-		var width = this.getTextWidth(s, font);
-		if(width <= limitWidth){
-			return {
-				text: s,
-				truncated: truncated || false
-			};
-		}else{
-			var begin = 0,
-				end = s.length;
-			while(begin < end){
-				if(end - begin <= delta ){
-					while (this.getTextWidth(s.substring(0, begin) + this.trailingSymbol, font) > limitWidth) {
-						begin -= 1;
+			this.dirty = true;
+			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:
+			//		Clear any elements out of our group, and destroy the group.
+			//	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.group = null;
+			}
+			this.dirty = true;
+			if(this._events.length){
+				arr.forEach(this._events, function(item){
+					item.shape.disconnect(item.handle);
+				});
+				this._events = [];
+			}
+			return this;	//	dojox.charting.Element
+		},
+		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.destroyHtmlElements();
+			if(!creator){ creator = this.chart.surface; }
+			if(this.group){
+				this.group.clear();
+			}else{
+				this.group = creator.createGroup();
+			}
+			this.dirty = true;
+			return this;	//	dojox.charting.Element
+		},
+		destroyHtmlElements: function(){
+			//	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);
+				this.htmlElements = [];
+			}
+		},
+		destroy: function(){
+			//	summary:
+			//		API addition to conform to the rest of the Dojo Toolkit's standard.
+			this.purgeGroup();
+		},
+		//text utilities
+		getTextWidth: function(s, font){
+			return gfx._base._getTextBox(s, {font: font}).w || 0;
+		},
+		getTextWithLimitLength: function(s, font, limitWidth, truncated){
+			//	summary:
+			//		Get the truncated string based on the limited width in px(dichotomy algorithm)
+			//	s: String?
+			//		candidate text.
+			//	font: String?
+			//		text's font style.
+			//	limitWidth: Number?
+			//		text limited width in px.
+			//	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) {
+				return {
+					text: "",
+					truncated: truncated || false
+				};
+			}
+			if(!limitWidth || limitWidth <= 0){
+				return {
+					text: s,
+					truncated: truncated || false
+				};
+			}
+			var delta = 2,
+				//golden section for dichotomy algorithm
+				trucPercentage = 0.618,
+				minStr = s.substring(0,1) + this.trailingSymbol,
+				minWidth = this.getTextWidth(minStr, font);
+			if (limitWidth <= minWidth) {
+				return {
+					text: minStr,
+					truncated: true
+				};
+			}
+			var width = this.getTextWidth(s, font);
+			if(width <= limitWidth){
+				return {
+					text: s,
+					truncated: truncated || false
+				};
+			}else{
+				var begin = 0,
+					end = s.length;
+				while(begin < end){
+					if(end - begin <= delta ){
+						while (this.getTextWidth(s.substring(0, begin) + this.trailingSymbol, font) > limitWidth) {
+							begin -= 1;
+						}
+						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);
+					if(widthIntercepted < limitWidth){
+						begin = index;
+						end = end;
+					}else{
+						begin = begin;
+						end = index;
 					}
-					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);
-				if(widthIntercepted < limitWidth){
-					begin = index;
-					end = end;
-				}else{
-					begin = begin;
-					end = index;
 				}
 			}
-		}
-	},
-	getTextWithLimitCharCount: function(s, font, wcLimit, truncated){
-		//	summary:
-		//		Get the truncated string based on the limited character count(dichotomy algorithm)
-		//	s: String?
-		//		candidate text.
-		//	font: String?
-		//		text's font style.
-		//	wcLimit: Number?
-		//		text limited character count.
-		//	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) {
-			return {
-				text: "",
-				truncated: truncated || false
-			};
-		}
-		if(!wcLimit || wcLimit <= 0 || s.length <= wcLimit){
+		},
+		getTextWithLimitCharCount: function(s, font, wcLimit, truncated){
+			//	summary:
+			//		Get the truncated string based on the limited character count(dichotomy algorithm)
+			//	s: String?
+			//		candidate text.
+			//	font: String?
+			//		text's font style.
+			//	wcLimit: Number?
+			//		text limited character count.
+			//	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) {
+				return {
+					text: "",
+					truncated: truncated || false
+				};
+			}
+			if(!wcLimit || wcLimit <= 0 || s.length <= wcLimit){
+				return {
+					text: s,
+					truncated: truncated || false
+				};
+			}
 			return {
-				text: s,
-				truncated: truncated || false
+				text: s.substring(0, wcLimit) + this.trailingSymbol,
+				truncated: true
 			};
-		}
-		return {
-			text: s.substring(0, wcLimit) + this.trailingSymbol,
-			truncated: true
-		};
-	},
-	// fill utilities
-	_plotFill: function(fill, dim, offsets){
-		// process a plot-wide fill
-		if(!fill || !fill.type || !fill.space){
-			return fill;
-		}
-		var space = fill.space;
-		switch(fill.type){
-			case "linear":
-				if(space === "plot" || space === "shapeX" || space === "shapeY"){
-					// clone a fill so we can modify properly directly
-					fill = dojox.gfx.makeParameters(dojox.gfx.defaultLinearGradient, fill);
-					fill.space = space;
-					// process dimensions
-					if(space === "plot" || space === "shapeX"){
-						// process Y
-						var 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;
-						fill.x1 = offsets.l + span * fill.x1 / 100;
-						fill.x2 = offsets.l + span * fill.x2 / 100;
+		},
+		// fill utilities
+		_plotFill: function(fill, dim, offsets){
+			// process a plot-wide fill
+			if(!fill || !fill.type || !fill.space){
+				return fill;
+			}
+			var space = fill.space;
+			switch(fill.type){
+				case "linear":
+					if(space === "plot" || space === "shapeX" || space === "shapeY"){
+						// clone a fill so we can modify properly directly
+						fill = gfx.makeParameters(gfx.defaultLinearGradient, fill);
+						fill.space = space;
+						// process dimensions
+						if(space === "plot" || space === "shapeX"){
+							// process Y
+							var 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;
+							fill.x1 = offsets.l + span * fill.x1 / 100;
+							fill.x2 = offsets.l + span * fill.x2 / 100;
+						}
 					}
-				}
-				break;
-			case "radial":
-				if(space === "plot"){
-					// this one is used exclusively for scatter charts
-					// clone a fill so we can modify properly directly
-					fill = dojox.gfx.makeParameters(dojox.gfx.defaultRadialGradient, fill);
-					fill.space = space;
-					// process both dimensions
-					var spanX = dim.width  - offsets.l - offsets.r,
-						spanY = dim.height - offsets.t - offsets.b;
-					fill.cx = offsets.l + spanX * fill.cx / 100;
-					fill.cy = offsets.t + spanY * fill.cy / 100;
-					fill.r  = fill.r * Math.sqrt(spanX * spanX + spanY * spanY) / 200;
-				}
-				break;
-			case "pattern":
-				if(space === "plot" || space === "shapeX" || space === "shapeY"){
-					// clone a fill so we can modify properly directly
-					fill = dojox.gfx.makeParameters(dojox.gfx.defaultPattern, fill);
-					fill.space = space;
-					// process dimensions
-					if(space === "plot" || space === "shapeX"){
-						// process Y
-						var span = dim.height - offsets.t - offsets.b;
-						fill.y = offsets.t + span * fill.y / 100;
-						fill.height = span * fill.height / 100;
+					break;
+				case "radial":
+					if(space === "plot"){
+						// this one is used exclusively for scatter charts
+						// clone a fill so we can modify properly directly
+						fill = gfx.makeParameters(gfx.defaultRadialGradient, fill);
+						fill.space = space;
+						// process both dimensions
+						var spanX = dim.width  - offsets.l - offsets.r,
+							spanY = dim.height - offsets.t - offsets.b;
+						fill.cx = offsets.l + spanX * fill.cx / 100;
+						fill.cy = offsets.t + spanY * fill.cy / 100;
+						fill.r  = fill.r * Math.sqrt(spanX * spanX + spanY * spanY) / 200;
 					}
-					if(space === "plot" || space === "shapeY"){
-						// process X
-						var span = dim.width - offsets.l - offsets.r;
-						fill.x = offsets.l + span * fill.x / 100;
-						fill.width = span * fill.width / 100;
+					break;
+				case "pattern":
+					if(space === "plot" || space === "shapeX" || space === "shapeY"){
+						// clone a fill so we can modify properly directly
+						fill = gfx.makeParameters(gfx.defaultPattern, fill);
+						fill.space = space;
+						// process dimensions
+						if(space === "plot" || space === "shapeX"){
+							// process Y
+							var 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;
+							fill.x = offsets.l + span * fill.x / 100;
+							fill.width = span * fill.width / 100;
+						}
 					}
-				}
-				break;
-		}
-		return fill;
-	},
-	_shapeFill: function(fill, bbox){
-		// process shape-specific fill
-		if(!fill || !fill.space){
+					break;
+			}
 			return fill;
-		}
-		var space = fill.space;
-		switch(fill.type){
-			case "linear":
-				if(space === "shape" || space === "shapeX" || space === "shapeY"){
-					// clone a fill so we can modify properly directly
-					fill = dojox.gfx.makeParameters(dojox.gfx.defaultLinearGradient, fill);
-					fill.space = space;
-					// process dimensions
-					if(space === "shape" || space === "shapeX"){
-						// process X
-						var 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;
-						fill.y1 = bbox.y + span * fill.y1 / 100;
-						fill.y2 = bbox.y + span * fill.y2 / 100;
+		},
+		_shapeFill: function(fill, bbox){
+			// process shape-specific fill
+			if(!fill || !fill.space){
+				return fill;
+			}
+			var space = fill.space;
+			switch(fill.type){
+				case "linear":
+					if(space === "shape" || space === "shapeX" || space === "shapeY"){
+						// clone a fill so we can modify properly directly
+						fill = gfx.makeParameters(gfx.defaultLinearGradient, fill);
+						fill.space = space;
+						// process dimensions
+						if(space === "shape" || space === "shapeX"){
+							// process X
+							var 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;
+							fill.y1 = bbox.y + span * fill.y1 / 100;
+							fill.y2 = bbox.y + span * fill.y2 / 100;
+						}
 					}
-				}
-				break;
-			case "radial":
-				if(space === "shape"){
-					// this one is used exclusively for bubble charts and pie charts
-					// clone a fill so we can modify properly directly
-					fill = dojox.gfx.makeParameters(dojox.gfx.defaultRadialGradient, fill);
-					fill.space = space;
-					// process both dimensions
-					fill.cx = bbox.x + bbox.width  / 2;
-					fill.cy = bbox.y + bbox.height / 2;
-					fill.r  = fill.r * bbox.width  / 200;
-				}
-				break;
-			case "pattern":
-				if(space === "shape" || space === "shapeX" || space === "shapeY"){
-					// clone a fill so we can modify properly directly
-					fill = dojox.gfx.makeParameters(dojox.gfx.defaultPattern, fill);
-					fill.space = space;
-					// process dimensions
-					if(space === "shape" || space === "shapeX"){
-						// process X
-						var span = bbox.width;
-						fill.x = bbox.x + span * fill.x / 100;
-						fill.width = span * fill.width / 100;
+					break;
+				case "radial":
+					if(space === "shape"){
+						// this one is used exclusively for bubble charts and pie charts
+						// clone a fill so we can modify properly directly
+						fill = gfx.makeParameters(gfx.defaultRadialGradient, fill);
+						fill.space = space;
+						// process both dimensions
+						fill.cx = bbox.x + bbox.width  / 2;
+						fill.cy = bbox.y + bbox.height / 2;
+						fill.r  = fill.r * bbox.width  / 200;
 					}
-					if(space === "shape" || space === "shapeY"){
-						// process Y
-						var span = bbox.height;
-						fill.y = bbox.y + span * fill.y / 100;
-						fill.height = span * fill.height / 100;
+					break;
+				case "pattern":
+					if(space === "shape" || space === "shapeX" || space === "shapeY"){
+						// clone a fill so we can modify properly directly
+						fill = gfx.makeParameters(gfx.defaultPattern, fill);
+						fill.space = space;
+						// process dimensions
+						if(space === "shape" || space === "shapeX"){
+							// process X
+							var 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;
+							fill.y = bbox.y + span * fill.y / 100;
+							fill.height = span * fill.height / 100;
+						}
 					}
-				}
-				break;
-		}
-		return fill;
-	},
-	_pseudoRadialFill: function(fill, center, radius, start, end){
-		// process pseudo-radial fills
-		if(!fill || fill.type !== "radial" || fill.space !== "shape"){
+					break;
+			}
 			return fill;
-		}
-		// clone and normalize fill
-		var space = fill.space;
-		fill = dojox.gfx.makeParameters(dojox.gfx.defaultRadialGradient, fill);
-		fill.space = space;
-		if(arguments.length < 4){
-			// process both dimensions
-			fill.cx = center.x;
-			fill.cy = center.y;
-			fill.r  = fill.r * radius / 100;
+		},
+		_pseudoRadialFill: function(fill, center, radius, start, end){
+			// process pseudo-radial fills
+			if(!fill || fill.type !== "radial" || fill.space !== "shape"){
+				return fill;
+			}
+			// clone and normalize fill
+			var space = fill.space;
+			fill = gfx.makeParameters(gfx.defaultRadialGradient, fill);
+			fill.space = space;
+			if(arguments.length < 4){
+				// process both dimensions
+				fill.cx = center.x;
+				fill.cy = center.y;
+				fill.r  = fill.r * radius / 100;
+				return fill;
+			}
+			// convert to a linear gradient
+			var angle = arguments.length < 5 ? start : (end + start) / 2;
+			return {
+				type: "linear",
+				x1: center.x,
+				y1: center.y,
+				x2: center.x + fill.r * radius * Math.cos(angle) / 100,
+				y2: center.y + fill.r * radius * Math.sin(angle) / 100,
+				colors: fill.colors
+			};
 			return fill;
 		}
-		// convert to a linear gradient
-		var angle = arguments.length < 5 ? start : (end + start) / 2;
-		return {
-			type: "linear",
-			x1: center.x,
-			y1: center.y,
-			x2: center.x + fill.r * radius * Math.cos(angle) / 100,
-			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 812b29c..6ee7852 100644
--- a/dojox/charting/Series.js
+++ b/dojox/charting/Series.js
@@ -1,59 +1,62 @@
-dojo.provide("dojox.charting.Series");
-
-dojo.require("dojox.charting.Element");
-/*=====
-dojox.charting.__SeriesCtorArgs = function(plot){
-	//	summary:
-	//		An optional arguments object that can be used in the Series constructor.
-	//	plot: String?
-	//		The plot (by name) that this series belongs to.
-	this.plot = plot;
-}
-=====*/
-dojo.declare("dojox.charting.Series", dojox.charting.Element, {
-	//	summary:
-	//		An object representing a series of data for plotting on a chart.
-	constructor: function(chart, data, kwArgs){
+define(["dojo/_base/lang", "dojo/_base/declare", "./Element"], 
+	function(lang, declare, Element){ 
+	/*=====
+	dojox.charting.__SeriesCtorArgs = function(plot){
 		//	summary:
-		//		Create a new data series object for use within charting.
-		//	chart: dojox.charting.Chart2D
-		//		The chart that this series belongs to.
-		//	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?
-		//		An optional keyword arguments object to set details for this series.
-		dojo.mixin(this, kwArgs);
-		if(typeof this.plot != "string"){ this.plot = "default"; }
-		this.update(data);
-	},
+		//		An optional arguments object that can be used in the Series constructor.
+		//	plot: String?
+		//		The plot (by name) that this series belongs to.
+		this.plot = plot;
+	}
 
-	clear: function(){
+	var Element = dojox.charting.Element;
+	=====*/
+	return declare("dojox.charting.Series", Element, {
 		//	summary:
-		//		Clear the calculated additional parameters set on this series.
-		this.dyn = {};
-	},
+		//		An object representing a series of data for plotting on a chart.
+		constructor: function(chart, data, kwArgs){
+			//	summary:
+			//		Create a new data series object for use within charting.
+			//	chart: dojox.charting.Chart
+			//		The chart that this series belongs to.
+			//	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?
+			//		An optional keyword arguments object to set details for this series.
+			lang.mixin(this, kwArgs);
+			if(typeof this.plot != "string"){ this.plot = "default"; }
+			this.update(data);
+		},
 	
-	update: function(data){
-		//	summary:
-		//		Set data and make this object dirty, so it can be redrawn.
-		//	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().
-		if(dojo.isArray(data)){
-			this.data = data;
-		}else{
-			this.source = data;
-			this.data = this.source.data;
-			if(this.source.setSeriesObject){
-				this.source.setSeriesObject(this);
+		clear: function(){
+			//	summary:
+			//		Clear the calculated additional parameters set on this series.
+			this.dyn = {};
+		},
+		
+		update: function(data){
+			//	summary:
+			//		Set data and make this object dirty, so it can be redrawn.
+			//	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().
+			if(lang.isArray(data)){
+				this.data = data;
+			}else{
+				this.source = data;
+				this.data = this.source.data;
+				if(this.source.setSeriesObject){
+					this.source.setSeriesObject(this);
+				}
 			}
+			this.dirty = true;
+			this.clear();
 		}
-		this.dirty = true;
-		this.clear();
-	}
+	});
+
 });
diff --git a/dojox/charting/StoreSeries.js b/dojox/charting/StoreSeries.js
index 54d927d..98fd850 100644
--- a/dojox/charting/StoreSeries.js
+++ b/dojox/charting/StoreSeries.js
@@ -1,98 +1,100 @@
-dojo.provide("dojox.charting.StoreSeries");
-
-dojo.declare("dojox.charting.StoreSeries", null, {
-	constructor: function(store, kwArgs, value){
-		//	summary:
-		//		Series adapter for dojo object stores (dojo.store).
-		//	store: Object:
-		//		A dojo object store.
-		//	kwArgs: Object:
-		//		A store-specific keyword parameters used for querying objects.
-		//		See dojo.store docs
-		//	value: Function|Object|String|Null:
-		//		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
-		//		an object and how to map them to an output. Or a string, which
-		//		is a numeric field name to use for plotting. If undefined, null
-		//		or empty string (the default), "value" field is extracted.
-		this.store = store;
-		this.kwArgs = kwArgs;
-
-		if(value){
-			if(typeof value == "function"){
-				this.value = value;
-			}else if(typeof value == "object"){
-				this.value = function(object){
-					var o = {};
-					for(var key in value){
-						o[key] = object[value[key]];
-					}
-					return o;
-				};
+define(["dojo/_base/array", "dojo/_base/declare", "dojo/_base/Deferred"], 
+  function(arr, declare, Deferred){
+	
+	return declare("dojox.charting.StoreSeries", null, {
+		constructor: function(store, kwArgs, value){
+			//	summary:
+			//		Series adapter for dojo object stores (dojo.store).
+			//	store: Object:
+			//		A dojo object store.
+			//	kwArgs: Object:
+			//		A store-specific keyword parameters used for querying objects.
+			//		See dojo.store docs
+			//	value: Function|Object|String|Null:
+			//		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
+			//		an object and how to map them to an output. Or a string, which
+			//		is a numeric field name to use for plotting. If undefined, null
+			//		or empty string (the default), "value" field is extracted.
+			this.store = store;
+			this.kwArgs = kwArgs;
+	
+			if(value){
+				if(typeof value == "function"){
+					this.value = value;
+				}else if(typeof value == "object"){
+					this.value = function(object){
+						var o = {};
+						for(var key in value){
+							o[key] = object[value[key]];
+						}
+						return o;
+					};
+				}else{
+					this.value = function(object){
+						return object[value];
+					};
+				}
 			}else{
 				this.value = function(object){
-					return object[value];
+					return object.value;
 				};
 			}
-		}else{
-			this.value = function(object){
-				return object.value;
-			};
-		}
-
-		this.data = [];
-
-		this.fetch();
-	},
-
-	destroy: function(){
-		//	summary:
-		//		Clean up before GC.
-		if(this.observeHandle){
-			this.observeHandle.dismiss();
-		}
-	},
-
-	setSeriesObject: function(series){
-		//	summary:
-		//		Sets a dojox.charting.Series object we will be working with.
-		//	series: dojox.charting.Series:
-		//		Our interface to the chart.
-		this.series = series;
-	},
-
-	// store fetch loop
-
-	fetch: function(){
-		//	summary:
-		//		Fetches data from the store and updates a chart.
-		var objects = this.objects = [];
-		var self = this;
-		if(this.observeHandle){
-			this.observeHandle.dismiss();
-		}
-		var results = this.store.query(this.kwArgs.query, this.kwArgs);
-		dojo.when(results, function(objects){
-			self.objects = objects;
-			update();
-		});
-		if(results.observe){
-			this.observeHandle = results.observe(update, true);
-		}
-		function update(){
-			self.data = dojo.map(self.objects, function(object){
-				return self.value(object, self.store);
+	
+			this.data = [];
+	
+			this.fetch();
+		},
+	
+		destroy: function(){
+			//	summary:
+			//		Clean up before GC.
+			if(this.observeHandle){
+				this.observeHandle.dismiss();
+			}
+		},
+	
+		setSeriesObject: function(series){
+			//	summary:
+			//		Sets a dojox.charting.Series object we will be working with.
+			//	series: dojox.charting.Series:
+			//		Our interface to the chart.
+			this.series = series;
+		},
+	
+		// store fetch loop
+	
+		fetch: function(){
+			//	summary:
+			//		Fetches data from the store and updates a chart.
+			var objects = this.objects = [];
+			var self = this;
+			if(this.observeHandle){
+				this.observeHandle.dismiss();
+			}
+			var results = this.store.query(this.kwArgs.query, this.kwArgs);
+			Deferred.when(results, function(objects){
+				self.objects = objects;
+				update();
 			});
-			self._pushDataChanges();
-		}
-	},
-
-	_pushDataChanges: function(){
-		if(this.series){
-			this.series.chart.updateSeries(this.series.name, this);
-			this.series.chart.delayedRender();
+			if(results.observe){
+				this.observeHandle = results.observe(update, true);
+			}
+			function update(){
+				self.data = arr.map(self.objects, function(object){
+					return self.value(object, self.store);
+				});
+				self._pushDataChanges();
+			}
+		},
+	
+		_pushDataChanges: function(){
+			if(this.series){
+				this.series.chart.updateSeries(this.series.name, this);
+				this.series.chart.delayedRender();
+			}
 		}
-	}
-
+	
+	});
 });
diff --git a/dojox/charting/Theme.js b/dojox/charting/Theme.js
index 3747523..75de4c8 100644
--- a/dojox/charting/Theme.js
+++ b/dojox/charting/Theme.js
@@ -1,18 +1,15 @@
-dojo.provide("dojox.charting.Theme");
-
-dojo.require("dojox.color");
-dojo.require("dojox.color.Palette");
-dojo.require("dojox.lang.utils");
-dojo.require("dojox.gfx.gradutils");
-
-dojo.declare("dojox.charting.Theme", null, {
+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){ 
+	
+	var Theme = declare("dojox.charting.Theme", null, {
 	//	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.Chart2D object), a Theme simplifies this manual setup by allowing you to
+	//		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
@@ -99,6 +96,23 @@ dojo.declare("dojox.charting.Theme", null, {
 	//	|		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:
@@ -118,9 +132,9 @@ dojo.declare("dojox.charting.Theme", null, {
 		kwArgs = kwArgs || {};
 
 		// populate theme with defaults updating them if needed
-		var def = dojox.charting.Theme.defaultTheme;
-		dojo.forEach(["chart", "plotarea", "axis", "series", "marker"], function(name){
-			this[name] = dojo.delegate(def[name], kwArgs[name]);
+		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
@@ -129,13 +143,13 @@ dojo.declare("dojox.charting.Theme", null, {
 			this.seriesThemes = kwArgs.seriesThemes.slice(0);
 		}else{
 			this.seriesThemes = null;
-			this.colors = (kwArgs.colors || dojox.charting.Theme.defaultColors).slice(0);
+			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 ? dojo.clone(kwArgs.markers) : dojo.delegate(dojox.charting.Theme.defaultMarkers);
+		this.markers = kwArgs.markers ? lang.clone(kwArgs.markers) : lang.delegate(Theme.defaultMarkers);
 
 		// set flags
 		this.noGradConv = kwArgs.noGradConv;
@@ -154,7 +168,7 @@ dojo.declare("dojox.charting.Theme", null, {
 		//		Clone the current theme.
 		//	returns: dojox.charting.Theme
 		//		The cloned theme; any alterations made will not affect the original.
-		var theme = new dojox.charting.Theme({
+		var theme = new Theme({
 			// theme components
 			chart: this.chart,
 			plotarea: this.plotarea,
@@ -164,6 +178,7 @@ dojo.declare("dojox.charting.Theme", null, {
 			// individual arrays
 			colors: this.colors,
 			markers: this.markers,
+			indicator: this.indicator,
 			seriesThemes: this.seriesThemes,
 			markerThemes: this.markerThemes,
 			// flags
@@ -171,7 +186,7 @@ dojo.declare("dojox.charting.Theme", null, {
 			noRadialConv: this.noRadialConv
 		});
 		// copy custom methods
-		dojo.forEach(
+		arr.forEach(
 			["clone", "clear", "next", "skip", "addMixin", "post", "getTick"],
 			function(name){
 				if(this.hasOwnProperty(name)){
@@ -200,24 +215,24 @@ dojo.declare("dojox.charting.Theme", null, {
 		//		A flag to post-process the results.
 		//	returns: Object
 		//		An object of the structure { series, marker, symbol }
-		var merge = dojox.lang.utils.merge, series, marker;
+		var merge = dlu.merge, series, marker;
 		if(this.colors){
-			series = dojo.delegate(this.series);
-			marker = dojo.delegate(this.marker);
-			var color = new dojo.Color(this.colors[this._current % this.colors.length]), old;
+			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 = dojo.delegate(series.stroke);
-				old = new dojo.Color(series.stroke.color);
-				series.stroke.color = new dojo.Color(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 = dojo.delegate(marker.stroke);
-				old = new dojo.Color(marker.stroke.color);
-				marker.stroke.color = new dojo.Color(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};
@@ -226,15 +241,15 @@ dojo.declare("dojox.charting.Theme", null, {
 			if(!series.fill || series.fill.type){
 				series.fill = color;
 			}else{
-				old = new dojo.Color(series.fill);
-				series.fill = new dojo.Color(color);
+				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 dojo.Color(marker.fill);
-				marker.fill = new dojo.Color(color);
+				old = new Color(marker.fill);
+				marker.fill = new Color(color);
 				marker.fill.a = old.a;
 			}
 		}else{
@@ -282,37 +297,37 @@ dojo.declare("dojox.charting.Theme", null, {
 		//		If true, run the new theme through the post-processor.
 		//	returns: dojox.charting.Theme
 		//		The new theme.
-		if(dojo.isArray(mixin)){
-			dojo.forEach(mixin, function(m){
+		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"){
-					dojo.setObject("series.stroke.color", mixin.color, t);
-					dojo.setObject("marker.stroke.color", mixin.color, t);
+					lang.setObject("series.stroke.color", mixin.color, t);
+					lang.setObject("marker.stroke.color", mixin.color, t);
 				}else{
-					dojo.setObject("series.fill", mixin.color, t);
+					lang.setObject("series.fill", mixin.color, t);
 				}
 			}
-			dojo.forEach(["stroke", "outline", "shadow", "fill", "font", "fontColor", "labelWiring"], function(name){
+			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){
-					dojo.setObject("series." + name, mixin[name], t);
+					lang.setObject("series." + name, mixin[name], t);
 					if(!b){
-						dojo.setObject("marker." + name, mixin[name], t);
+						lang.setObject("marker." + name, mixin[name], t);
 					}
 				}
 				if(b){
-					dojo.setObject("marker." + name, mixin[markerName], t);
+					lang.setObject("marker." + name, mixin[markerName], t);
 				}
 			});
 			if("marker" in mixin){
 				t.symbol = mixin.marker;
 			}
-			theme = dojox.lang.utils.merge(theme, t);
+			theme = dlu.merge(theme, t);
 		}
 		if(doPost){
 			theme = this.post(theme, elementType);
@@ -349,7 +364,7 @@ dojo.declare("dojox.charting.Theme", null, {
 				};
 			}
 			if(t){
-				return dojox.lang.utils.merge(theme, {series: {fill: t}});
+				return dlu.merge(theme, {series: {fill: t}});
 			}
 		}
 		return theme;	//	dojox.charting.Theme
@@ -362,8 +377,8 @@ dojo.declare("dojox.charting.Theme", null, {
 		//		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 = dojox.lang.utils.merge;
+		var tick = this.axis.tick, tickName = name + "Tick",
+			merge = dlu.merge;
 		if(tick){
 			if(this.axis[tickName]){
 				tick = merge(tick, this.axis[tickName]);
@@ -384,21 +399,21 @@ dojo.declare("dojox.charting.Theme", null, {
 	},
 
 	inspectObjects: function(f){
-		dojo.forEach(["chart", "plotarea", "axis", "series", "marker"], function(name){
+		arr.forEach(["chart", "plotarea", "axis", "series", "marker", "indicator"], function(name){
 			f(this[name]);
 		}, this);
 		if(this.seriesThemes){
-			dojo.forEach(this.seriesThemes, f);
+			arr.forEach(this.seriesThemes, f);
 		}
 		if(this.markerThemes){
-			dojo.forEach(this.markerThemes, f);
+			arr.forEach(this.markerThemes, f);
 		}
 	},
 
 	reverseFills: function(){
 		this.inspectObjects(function(o){
 			if(o && o.fill){
-				o.fill = dojox.gfx.gradutils.reverse(o.fill);
+				o.fill = dgg.reverse(o.fill);
 			}
 		});
 	},
@@ -461,7 +476,7 @@ dojox.charting.Theme.__DefineColorArgs = function(num, colors, hue, saturation,
 	this.generator = generator;
 }
 =====*/
-dojo.mixin(dojox.charting.Theme, {
+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",
@@ -540,6 +555,23 @@ dojo.mixin(dojox.charting.Theme, {
 			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,
+			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								
 		}
 	},
 
@@ -566,10 +598,10 @@ dojo.mixin(dojox.charting.Theme, {
 		//	|		high: 80
 		//	|	});
 		kwArgs = kwArgs || {};
-		var c = [], n = kwArgs.num || 5;	// the number of colors to generate
+		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.
-			var l = kwArgs.colors.length;
+			l = kwArgs.colors.length;
 			for(var i = 0; i < n; i++){
 				c.push(kwArgs.colors[i % l]);
 			}
@@ -577,25 +609,25 @@ dojo.mixin(dojox.charting.Theme, {
 		}
 		if(kwArgs.hue){
 			// single hue, generate a set based on brightness
-			var s = kwArgs.saturation || 100;	// saturation
-			var st = kwArgs.low || 30;
-			var end = kwArgs.high || 90;
+			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.
-			var l = (end + st) / 2;
+			l = (end + st) / 2;
 			// alternately, use "shades"
-			return dojox.color.Palette.generate(
-				dojox.color.fromHsv(kwArgs.hue, s, l), "monochromatic"
+			return colorX.Palette.generate(
+				colorX.fromHsv(kwArgs.hue, s, l), "monochromatic"
 			).colors;
 		}
 		if(kwArgs.generator){
 			//	pass a base color and the name of a generator
-			return dojox.color.Palette.generate(kwArgs.base, kwArgs.generator).colors;
+			return colorX.Palette.generate(kwArgs.base, kwArgs.generator).colors;
 		}
 		return c;	//	dojo.Color[]
 	},
 	
 	generateGradient: function(fillPattern, colorFrom, colorTo){
-		var fill = dojo.delegate(fillPattern);
+		var fill = lang.delegate(fillPattern);
 		fill.colors = [
 			{offset: 0, color: colorFrom},
 			{offset: 1, color: colorTo}
@@ -604,19 +636,22 @@ dojo.mixin(dojox.charting.Theme, {
 	},
 	
 	generateHslColor: function(color, luminance){
-		color = new dojox.color.Color(color);
+		color = new Color(color);
 		var hsl    = color.toHsl(),
-			result = dojox.color.fromHsl(hsl.h, hsl.s, luminance);
+			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 dojox.color.Color(color);
+		color = new Color(color);
 		var hsl       = color.toHsl(),
-			colorFrom = dojox.color.fromHsl(hsl.h, hsl.s, lumFrom),
-			colorTo   = dojox.color.fromHsl(hsl.h, hsl.s, lumTo);
+			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 dojox.charting.Theme.generateGradient(fillPattern, colorFrom, colorTo);	// Object
+		return Theme.generateGradient(fillPattern, colorFrom, colorTo);	// Object
 	}
 });
+
+return Theme;
+});
diff --git a/dojox/charting/action2d/Base.js b/dojox/charting/action2d/Base.js
index 175d9e6..36cba66 100644
--- a/dojox/charting/action2d/Base.js
+++ b/dojox/charting/action2d/Base.js
@@ -1,80 +1,36 @@
-dojo.provide("dojox.charting.action2d.Base");
-
-dojo.require("dojo.fx.easing");
-dojo.require("dojox.lang.functional.object");
-dojo.require("dojox.gfx.fx");
-
-/*=====
-dojox.charting.action2d.__BaseCtorArgs = function(duration, easing){
- 	//	summary:
-	//		The base keyword arguments object for creating an action2d.
-	//	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.
-	this.duration = duration;
-	this.easing = easing;
-}
-=====*/
-(function(){
-	var DEFAULT_DURATION = 400,	// ms
-		DEFAULT_EASING   = dojo.fx.easing.backOut,
-		df = dojox.lang.functional;
-
-	dojo.declare("dojox.charting.action2d.Base", null, {
-
-		overOutEvents: {onmouseover: 1, onmouseout: 1},
-
-		constructor: function(chart, plot, kwargs){
+define(["dojo/_base/lang", "dojo/_base/declare"], 
+	function(lang, declare){
+
+	return declare("dojox.charting.action2d.Base", null, {
+		//	summary:
+		//		Base action class for plot and chart actions.
+	
+		constructor: function(chart, plot){
 			//	summary:
-			//		Create a new base Action.
-			//	chart: dojox.charting.Chart2D
+			//		Create a new base action.  This can either be a plot or a chart action.
+			//	chart: dojox.charting.Chart
 			//		The chart this action applies to.
-			//	plot: String?
-			//		The name of the plot this action belongs to.  If none is passed "default" is assumed.
-			//	kwargs: dojox.charting.action2d.__BaseCtorArgs?
-			//		Optional arguments for the action.
+			//	plot: String?|dojox.charting.plot2d.Base?
+			//		Optional target plot for this action.  Default is "default".
 			this.chart = chart;
-			this.plot = plot || "default";
-			this.anim = {};
-
-			// process common optional named parameters
-			if(!kwargs){ kwargs = {}; }
-			this.duration = kwargs.duration ? kwargs.duration : DEFAULT_DURATION;
-			this.easing   = kwargs.easing   ? kwargs.easing   : DEFAULT_EASING;
+			this.plot = plot ? (lang.isString(plot) ? this.chart.getPlot(plot) : plot) : this.chart.getPlot("default");
 		},
-
+	
 		connect: function(){
 			//	summary:
-			//		Connect this action to the given plot.
-			this.handle = this.chart.connectToPlot(this.plot, this, "process");
+			//		Connect this action to the plot or the chart.
 		},
-
+	
 		disconnect: function(){
 			//	summary:
-			//		Disconnect this action from the given plot, if connected.
-			if(this.handle){
-				dojo.disconnect(this.handle);
-				this.handle = null;
-			}
-		},
-
-		reset: function(){
-			//	summary:
-			//		Reset the action.
+			//		Disconnect this action from the plot or the chart.
 		},
-
+		
 		destroy: function(){
 			//	summary:
 			//		Do any cleanup needed when destroying parent elements.
 			this.disconnect();
-			df.forIn(this.anim, function(o){
-				df.forIn(o, function(anim){
-					anim.action.stop(true);
-				});
-			});
-			this.anim = {};
 		}
 	});
-})();
+
+});
diff --git a/dojox/charting/action2d/ChartAction.js b/dojox/charting/action2d/ChartAction.js
new file mode 100644
index 0000000..e438daf
--- /dev/null
+++ b/dojox/charting/action2d/ChartAction.js
@@ -0,0 +1,38 @@
+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:
+		//		Base action class for chart actions.
+	
+		constructor: function(chart, plot){
+			//	summary:
+			//		Create a new base chart action.
+			//	chart: dojox.charting.Chart
+			//		The chart this action applies to.
+			//	plot: String?|dojox.charting.plot2d.Base?
+			//		Optional target plot for this chart action.  Default is "default".
+		},
+	
+		connect: function(){
+			//	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,
+						this, this._listeners[i].methodName);
+			}
+		},
+	
+		disconnect: function(){
+			//	summary:
+			//		Disconnect this action from the chart.
+			for(var i = 0; i < this._listeners.length; ++i){
+				hub.disconnect(this._listeners[i].handle);
+				delete this._listeners[i].handle;
+			}
+		}
+});
+
+});
diff --git a/dojox/charting/action2d/Highlight.js b/dojox/charting/action2d/Highlight.js
index 776f850..acf189e 100644
--- a/dojox/charting/action2d/Highlight.js
+++ b/dojox/charting/action2d/Highlight.js
@@ -1,25 +1,22 @@
-dojo.provide("dojox.charting.action2d.Highlight");
+define(["dojo/_base/kernel", "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){
 
-dojo.require("dojox.charting.action2d.Base");
-dojo.require("dojox.color");
-
-/*=====
-dojo.declare("dojox.charting.action2d.__HighlightCtorArgs", dojox.charting.action2d.__BaseCtorArgs, {
-	//	summary:
-	//		Additional arguments for highlighting actions.
-
-	//	highlight: String|dojo.Color|Function?
-	//		Either a color or a function that creates a color when highlighting happens.
-	highlight: null
-});
-=====*/
-(function(){
+	/*=====
+	dojo.declare("dojox.charting.action2d.__HighlightCtorArgs", dojox.charting.action2d.__PlotActionCtorArgs, {
+		//	summary:
+		//		Additional arguments for highlighting actions.
+	
+		//	highlight: String|dojo.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,	// %
 		DEFAULT_LUMINOSITY1 = 75,	// %
 		DEFAULT_LUMINOSITY2 = 50,	// %
-
-		c = dojox.color,
-
 		cc = function(color){
 			return function(){ return color; };
 		},
@@ -43,7 +40,7 @@ dojo.declare("dojox.charting.action2d.__HighlightCtorArgs", dojox.charting.actio
 			return c.fromHsl(x);
 		};
 
-	dojo.declare("dojox.charting.action2d.Highlight", dojox.charting.action2d.Base, {
+	return declare("dojox.charting.action2d.Highlight", PlotAction, {
 		//	summary:
 		//		Creates a highlighting action on a plot, where an element on that plot
 		//		has a highlight on it.
@@ -51,7 +48,7 @@ dojo.declare("dojox.charting.action2d.__HighlightCtorArgs", dojox.charting.actio
 		// the data description block for the widget parser
 		defaultParams: {
 			duration: 400,	// duration of the action in ms
-			easing:   dojo.fx.easing.backOut	// easing for the action
+			easing:   dfe.backOut	// easing for the action
 		},
 		optionalParams: {
 			highlight: "red"	// name for the highlight color
@@ -61,14 +58,14 @@ dojo.declare("dojox.charting.action2d.__HighlightCtorArgs", dojox.charting.actio
 		constructor: function(chart, plot, kwArgs){
 			//	summary:
 			//		Create the highlighting action and connect it to the plot.
-			//	chart: dojox.charting.Chart2D
+			//	chart: dojox.charting.Chart
 			//		The chart this action belongs to.
 			//	plot: String?
 			//		The plot this action is attached to.  If not passed, "default" is assumed.
-			//	kwArgs: dojox.charting.action2d.__HighlightCtorArgs?
+			//	kwArgs: charting.action2d.__HighlightCtorArgs?
 			//		Optional keyword arguments object for setting parameters.
 			var a = kwArgs && kwArgs.highlight;
-			this.colorFun = a ? (dojo.isFunction(a) ? a : cc(a)) : hl;
+			this.colorFun = a ? (lang.isFunction(a) ? a : cc(a)) : hl;
 
 			this.connect();
 		},
@@ -92,7 +89,7 @@ dojo.declare("dojox.charting.action2d.__HighlightCtorArgs", dojox.charting.actio
 				anim.action.stop(true);
 			}else{
 				var color = o.shape.getFill();
-				if(!color || !(color instanceof dojo.Color)){
+				if(!color || !(color instanceof Color)){
 					return;
 				}
 				this.anim[runName][index] = anim = {
@@ -109,14 +106,14 @@ dojo.declare("dojox.charting.action2d.__HighlightCtorArgs", dojox.charting.actio
 				end = t;
 			}
 
-			anim.action = dojox.gfx.fx.animateFill({
+			anim.action = dgf.animateFill({
 				shape:    o.shape,
 				duration: this.duration,
 				easing:   this.easing,
 				color:    {start: start, end: end}
 			});
 			if(o.type == "onmouseout"){
-				dojo.connect(anim.action, "onEnd", this, function(){
+				hub.connect(anim.action, "onEnd", this, function(){
 					if(this.anim[runName]){
 						delete this.anim[runName][index];
 					}
@@ -125,4 +122,5 @@ dojo.declare("dojox.charting.action2d.__HighlightCtorArgs", dojox.charting.actio
 			anim.action.play();
 		}
 	});
-})();
+	
+});
diff --git a/dojox/charting/action2d/Magnify.js b/dojox/charting/action2d/Magnify.js
index 7044ff7..b3707a9 100644
--- a/dojox/charting/action2d/Magnify.js
+++ b/dojox/charting/action2d/Magnify.js
@@ -1,32 +1,30 @@
-dojo.provide("dojox.charting.action2d.Magnify");
+define(["dojo/_base/connect", "dojo/_base/declare", 
+	"./PlotAction", "dojox/gfx/matrix", 
+	"dojox/gfx/fx", "dojo/fx", "dojo/fx/easing"], 
+	function(Hub, declare, PlotAction, m, gf, df, dfe){
 
-dojo.require("dojox.charting.action2d.Base");
-dojo.require("dojox.gfx.matrix");
-dojo.require("dojo.fx");
-
-/*=====
-dojo.declare("dojox.charting.action2d.__MagnifyCtorArgs", dojox.charting.action2d.__BaseCtorArgs, {
-	//	summary:
-	//		Additional arguments for highlighting actions.
-
-	//	scale: Number?
-	//		The amount to magnify the given object to.  Default is 2.
-	scale: 2
-});
-=====*/
-(function(){
-	var DEFAULT_SCALE = 2,
-		m = dojox.gfx.matrix,
-		gf = dojox.gfx.fx;
+	/*=====
+	dojo.declare("dojox.charting.action2d.__MagnifyCtorArgs", dojox.charting.action2d.__PlotActionCtorArgs, {
+		//	summary:
+		//		Additional arguments for highlighting actions.
+	
+		//	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;
 
-	dojo.declare("dojox.charting.action2d.Magnify", dojox.charting.action2d.Base, {
+	return declare("dojox.charting.action2d.Magnify", PlotAction, {
 		//	summary:
 		//		Create an action that magnifies the object the action is applied to.
 
 		// the data description block for the widget parser
 		defaultParams: {
 			duration: 400,	// duration of the action in ms
-			easing:   dojo.fx.easing.backOut,	// easing for the action
+			easing:   dfe.backOut,	// easing for the action
 			scale:    DEFAULT_SCALE	// scale of magnification
 		},
 		optionalParams: {},	// no optional parameters
@@ -34,7 +32,7 @@ dojo.declare("dojox.charting.action2d.__MagnifyCtorArgs", dojox.charting.action2
 		constructor: function(chart, plot, kwArgs){
 			//	summary:
 			//		Create the magnifying action.
-			//	chart: dojox.charting.Chart2D
+			//	chart: dojox.charting.Chart
 			//		The chart this action belongs to.
 			//	plot: String?
 			//		The plot to apply the action to. If not passed, "default" is assumed.
@@ -103,9 +101,9 @@ dojo.declare("dojox.charting.action2d.__MagnifyCtorArgs", dojox.charting.action2
 				return;
 			}
 
-			anim.action = dojo.fx.combine(vector);
+			anim.action = df.combine(vector);
 			if(o.type == "onmouseout"){
-				dojo.connect(anim.action, "onEnd", this, function(){
+				Hub.connect(anim.action, "onEnd", this, function(){
 					if(this.anim[runName]){
 						delete this.anim[runName][index];
 					}
@@ -114,4 +112,5 @@ dojo.declare("dojox.charting.action2d.__MagnifyCtorArgs", dojox.charting.action2
 			anim.action.play();
 		}
 	});
-})();
+	
+});
diff --git a/dojox/charting/action2d/MouseIndicator.js b/dojox/charting/action2d/MouseIndicator.js
new file mode 100644
index 0000000..a982d2a
--- /dev/null
+++ b/dojox/charting/action2d/MouseIndicator.js
@@ -0,0 +1,221 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_base/window", "dojo/_base/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:
+		//		Additional arguments for mouse indicator.
+		
+		//	series: String
+		//		Target series name for this action.
+		series: "",
+		
+		//	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: 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.
+		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;
+	=====*/
+
+	return declare("dojox.charting.action2d.MouseIndicator", ChartAction, {
+		//	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
+		defaultParams: {
+			series: "",
+			vertical: true,
+			autoScroll: true,
+			fixed: true,
+			precision: 0
+		},
+		optionalParams: {
+			lineStroke: {},
+			outlineStroke: {},
+			shadowStroke: {},
+			stroke:		{},
+			outline:	{},
+			shadow:		{},
+			fill:		{},
+			fillFunc:  null,
+			labelFunc: null,
+			font:		"",
+			fontColor:	"",
+			markerStroke:		{},
+			markerOutline:		{},
+			markerShadow:		{},
+			markerFill:			{},
+			markerSymbol:		""
+		},	
+
+		constructor: function(chart, plot, kwArgs){
+			//	summary:
+			//		Create an mouse indicator action and connect it.
+			//	chart: dojox.charting.Chart
+			//		The chart this action applies to.
+			//	kwArgs: dojox.charting.action2d.__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._uName = "mouseIndicator"+this.opt.series;
+			this._handles = [];
+			this.connect();
+		},
+		
+		_disconnectHandles: function(){
+			if(has("ie")){
+				this.chart.node.releaseCapture();
+			}
+			arr.forEach(this._handles, hub.disconnect);
+			this._handles = [];
+		},
+
+		connect: function(){
+			//	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});
+		},
+
+		disconnect: function(){
+			//	summary:
+			//		Disconnect this action from the chart.
+			if(this._isMouseDown){
+				this.onMouseUp();
+			}
+			this.chart.removePlot(this._uName);
+			this.inherited(arguments);
+			this._disconnectHandles();
+		},
+
+		onMouseDown: function(event){
+			//	summary:
+			//		Called when mouse is down on the chart.
+			this._isMouseDown = true;
+			
+			// we now want to capture mouse move events everywhere to avoid
+			// stop scrolling when going out of the chart window
+			if(has("ie")){
+				this._handles.push(hub.connect(this.chart.node, "onmousemove", this, "onMouseMove"));
+				this._handles.push(hub.connect(this.chart.node, "onmouseup", this, "onMouseUp"));
+				this.chart.node.setCapture();
+			}else{
+				this._handles.push(hub.connect(win.doc, "onmousemove", this, "onMouseMove"));
+				this._handles.push(hub.connect(win.doc, "onmouseup", this, "onMouseUp"));
+			}	
+			
+			this._onMouseSingle(event);
+		},
+
+		onMouseMove: function(event){
+			//	summary:
+			//		Called when the mouse is moved on the chart.
+			if(this._isMouseDown){
+				this._onMouseSingle(event);
+			}
+		},
+
+		_onMouseSingle: function(event){
+			var plot = this.chart.getPlot(this._uName);
+			plot.pageCoord  = {x: event.pageX, y: event.pageY};
+			plot.dirty = true;
+			this.chart.render();
+			eventUtil.stop(event);
+		},
+
+		onMouseUp: function(event){
+			//	summary:
+			//		Called when mouse is up on the chart.
+			var plot = this.chart.getPlot(this._uName);
+			plot.stopTrack();
+			this._isMouseDown = false;
+			this._disconnectHandles();
+			plot.pageCoord = null;
+			plot.dirty = true;
+			this.chart.render();
+		}
+	});
+});
diff --git a/dojox/charting/action2d/MouseZoomAndPan.js b/dojox/charting/action2d/MouseZoomAndPan.js
new file mode 100644
index 0000000..37226d1
--- /dev/null
+++ b/dojox/charting/action2d/MouseZoomAndPan.js
@@ -0,0 +1,245 @@
+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){
+
+	/*=====
+	dojo.declare("dojox.charting.action2d.__MouseZoomAndPanCtorArgs", 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 mouse wheel zoom.  Default is 1.2.
+		scaleFactor: 1.2,
+		//	maxScale: Number?
+		//		The max scale factor accepted by this chart action.  Default is 100.
+		maxScale: 100,
+		//	enableScroll: Boolean?
+		//		Whether mouse drag gesture should scroll the chart.  Default is true.
+		enableScroll: true,
+		//	enableDoubleClickZoom: Boolean?
+		//		Whether a double click gesture should toggle between fit and zoom on the chart.  Default is true.
+		enableDoubleClickZoom: true,
+		//	enableKeyZoom: Boolean?
+		//		Whether a keyZoomModifier + + or keyZoomModifier + - key press should zoom in our out on the chart.  Default is true.
+		enableKeyZoom: true,
+		//	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 keyTests = {
+		none: function(event){
+			return !event.ctrlKey && !event.altKey && !event.shiftKey;
+		},
+		ctrl: function(event){
+			return event.ctrlKey && !event.altKey && !event.shiftKey;
+		},
+		alt: function(event){
+			return !event.ctrlKey && event.altKey && !event.shiftKey;
+		},
+		shift: function(event){
+			return !event.ctrlKey && !event.altKey && event.shiftKey;
+		}
+	};
+
+	return declare("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.
+
+		// the data description block for the widget parser
+		defaultParams: {
+			axis: "x",
+			scaleFactor: 1.2,	
+			maxScale: 100,
+			enableScroll: true,
+			enableDoubleClickZoom: true,
+			enableKeyZoom: true,
+			keyZoomModifier: "ctrl"
+		},
+		optionalParams: {}, // no optional parameters
+		
+		constructor: function(chart, plot, kwArgs){
+			//	summary:
+			//		Create an mouse zoom and pan action and connect it.
+			//	chart: dojox.charting.Chart
+			//		The chart this action applies to.
+			//	kwArgs: dojox.charting.action2d.__MouseZoomAndPanCtorArgs?
+			//		Optional arguments for the chart action.
+			this._listeners = [{eventName: !has("mozilla") ? "onmousewheel" : "DOMMouseScroll", methodName: "onMouseWheel"}];
+			if(!kwArgs){ kwArgs = {}; }
+			this.axis = kwArgs.axis ? kwArgs.axis : "x";
+			this.scaleFactor = kwArgs.scaleFactor ? kwArgs.scaleFactor : 1.2;
+			this.maxScale = kwArgs.maxScale ? kwArgs.maxScale : 100;
+			this.enableScroll = kwArgs.enableScroll != undefined ? kwArgs.enableScroll : true;
+			this.enableDoubleClickZoom = kwArgs.enableDoubleClickZoom != undefined ? kwArgs.enableDoubleClickZoom : true;
+			this.enableKeyZoom = kwArgs.enableKeyZoom != undefined ? kwArgs.enableKeyZoom : true;
+			this.keyZoomModifier = kwArgs.keyZoomModifier ? kwArgs.keyZoomModifier : "ctrl";
+			if(this.enableScroll){
+				this._listeners.push({eventName: "onmousedown", methodName: "onMouseDown"});
+			}
+			if(this.enableDoubleClickZoom){
+				this._listeners.push({eventName: "ondblclick", methodName: "onDoubleClick"});
+			}
+			if(this.enableKeyZoom){
+				this._listeners.push({eventName: "keypress", methodName: "onKeyPress"});				
+			}
+			this._handles = [];
+			this.connect();
+		},
+		
+		_disconnectHandles: function(){
+			if(has("ie")){
+				this.chart.node.releaseCapture();
+			}
+			arr.forEach(this._handles, connect.disconnect);
+			this._handles = [];
+		},
+		
+		connect: function(){
+			//	summary:
+			//		Connect this action to the chart.
+			this.inherited(arguments);
+			if(this.enableKeyZoom){
+				// we want to be able to get focus to receive key events 
+				domProp.set(this.chart.node, "tabindex", "0");
+				// if one doesn't want a focus border he can do something like
+				// dojo.style(this.chart.node, "outline", "none");
+			}
+		},
+		
+		disconnect: function(){
+			//	summary:
+			//		Disconnect this action from the chart.
+			this.inherited(arguments);
+			if(this.enableKeyZoom){
+				// we don't need anymore to be able to get focus to receive key events 
+				domProp.set(this.chart.node, "tabindex", "-1");
+			}
+			// in case we disconnect before the end of the action
+			this._disconnectHandles();
+		},
+	
+		onMouseDown: function(event){
+			//	summary:
+			//		Called when mouse is down on the chart.
+			var chart = this.chart, axis = chart.getAxis(this.axis);
+			if(!axis.vertical){
+				this._startCoord = event.pageX;
+			}else{
+				this._startCoord = event.pageY;
+			}
+			this._startOffset = axis.getWindowOffset();
+			this._isPanning = true;
+			// we now want to capture mouse move events everywhere to avoid
+			// stop scrolling when going out of the chart window
+			if(has("ie")){
+				this._handles.push(connect.connect(this.chart.node, "onmousemove", this, "onMouseMove"));
+				this._handles.push(connect.connect(this.chart.node, "onmouseup", this, "onMouseUp"));
+				this.chart.node.setCapture();
+			}else{
+				this._handles.push(connect.connect(win.doc, "onmousemove", this, "onMouseMove"));
+				this._handles.push(connect.connect(win.doc, "onmouseup", this, "onMouseUp"));
+			}
+			chart.node.focus();
+			// prevent the browser from trying the drag on the "image"
+			eventUtil.stop(event);
+		},
+	
+		onMouseMove: function(event){
+			//	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 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:
+			//		Called when mouse is up on the chart.
+			this._isPanning = false;
+			this._disconnectHandles();
+		},
+		
+		onMouseWheel: function(event){
+			//	summary:
+			//		Called when mouse wheel is used on the chart.
+			var scroll = event[(has("mozilla") ? "detail" : "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){
+				scroll = -1;
+			}else if(scroll > 0 && scroll < 1){
+				scroll = 1;
+			}
+ 			this._onZoom(scroll, event);
+		},
+		
+		onKeyPress: function(event){
+			//	summary:
+			//		Called when a key is pressed on the chart.
+			if(keyTests[this.keyZoomModifier](event)){
+				if(event.keyChar == "+" || event.keyCode == keys.NUMPAD_PLUS){
+					this._onZoom(1, event);
+				}else if(event.keyChar == "-" || event.keyCode == keys.NUMPAD_MINUS){
+					this._onZoom(-1, event);					
+				}
+			} 
+		},
+		
+		onDoubleClick: function(event){
+			//	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;
+			// 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({x: event.pageX, y: event.pageY})[this.axis], 
+				newStart = scale * (start - oldMiddle) + newMiddle, newEnd = scale * (end - oldMiddle) + newMiddle;
+				chart.zoomIn(this.axis, [newStart, newEnd]);
+			}else{
+				// non fit => fit
+				chart.setAxisWindow(this.axis, 1, 0);
+				chart.render();
+			}
+			eventUtil.stop(event);
+		},
+		
+		_onZoom: function(scroll, event){
+			var scale = (scroll < 0 ? Math.abs(scroll)*this.scaleFactor : 
+				1 / (Math.abs(scroll)*this.scaleFactor));
+			var chart = this.chart, axis = chart.getAxis(this.axis);
+			// after wheel reset event position exactly if we could start a new scroll action
+			var cscale = axis.getWindowScale();
+			if(cscale / scale > this.maxScale){
+				return;
+			}
+			var scaler = axis.getScaler(), start = scaler.bounds.from, end = scaler.bounds.to;
+			// keep mouse pointer as transformation center if available otherwise center
+			var middle = (event.type == "keypress") ? (start + end) / 2 :
+				this.plot.toData({x: event.pageX, y: event.pageY})[this.axis];
+			var newStart = scale * (start - middle) + middle, newEnd = scale * (end - middle) + middle;
+			chart.zoomIn(this.axis, [newStart, newEnd]);
+			// do not scroll browser
+			eventUtil.stop(event);
+		}
+	});		
+});
diff --git a/dojox/charting/action2d/MoveSlice.js b/dojox/charting/action2d/MoveSlice.js
index 5142ab7..8ea61d3 100644
--- a/dojox/charting/action2d/MoveSlice.js
+++ b/dojox/charting/action2d/MoveSlice.js
@@ -1,41 +1,34 @@
-dojo.provide("dojox.charting.action2d.MoveSlice");
+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){
 
-dojo.require("dojox.charting.action2d.Base");
-dojo.require("dojox.gfx.matrix");
-
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.functional.scan");
-dojo.require("dojox.lang.functional.fold");
-
-/*=====
-dojo.declare("dojox.charting.action2d.__MoveSliceCtorArgs", dojox.charting.action2d.__BaseCtorArgs, {
-	//	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
-});
-=====*/
-(function(){
+	/*=====
+	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 DEFAULT_SCALE = 1.05,
-		DEFAULT_SHIFT = 7,	// px
-		m = dojox.gfx.matrix,
-		gf = dojox.gfx.fx,
-		df = dojox.lang.functional;
+		DEFAULT_SHIFT = 7;	// px
 
-	dojo.declare("dojox.charting.action2d.MoveSlice", dojox.charting.action2d.Base, {
+	return declare("dojox.charting.action2d.MoveSlice", PlotAction, {
 		//	summary:
 		//		Create an action for a pie chart that moves and scales a pie slice.
 
 		// the data description block for the widget parser
 		defaultParams: {
 			duration: 400,	// duration of the action in ms
-			easing:   dojo.fx.easing.backOut,	// easing for the action
+			easing:   dfe.backOut,	// easing for the action
 			scale:    DEFAULT_SCALE,	// scale of magnification
 			shift:    DEFAULT_SHIFT		// shift of the slice
 		},
@@ -44,7 +37,7 @@ dojo.declare("dojox.charting.action2d.__MoveSliceCtorArgs", dojox.charting.actio
 		constructor: function(chart, plot, kwArgs){
 			//	summary:
 			//		Create the slice moving action and connect it to the plot.
-			//	chart: dojox.charting.Chart2D
+			//	chart: dojox.charting.Chart
 			//		The chart this action belongs to.
 			//	plot: String?
 			//		The plot this action is attached to.  If not passed, "default" is assumed.
@@ -101,7 +94,7 @@ dojo.declare("dojox.charting.action2d.__MoveSliceCtorArgs", dojox.charting.actio
 				endScale    = 1;
 			}
 
-			anim.action = dojox.gfx.fx.animateTransform({
+			anim.action = gf.animateTransform({
 				shape:    o.shape,
 				duration: this.duration,
 				easing:   this.easing,
@@ -114,7 +107,7 @@ dojo.declare("dojox.charting.action2d.__MoveSliceCtorArgs", dojox.charting.actio
 			});
 
 			if(o.type == "onmouseout"){
-				dojo.connect(anim.action, "onEnd", this, function(){
+				hub.connect(anim.action, "onEnd", this, function(){
 					delete this.anim[index];
 				});
 			}
@@ -125,4 +118,4 @@ dojo.declare("dojox.charting.action2d.__MoveSliceCtorArgs", dojox.charting.actio
 			delete this.angles;
 		}
 	});
-})();
+});
diff --git a/dojox/charting/action2d/PlotAction.js b/dojox/charting/action2d/PlotAction.js
new file mode 100644
index 0000000..3ac5733
--- /dev/null
+++ b/dojox/charting/action2d/PlotAction.js
@@ -0,0 +1,78 @@
+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){
+	
+	/*=====
+	dojox.charting.action2d.__PlotActionCtorArgs = function(duration, easing){
+	 	//	summary:
+		//		The base keyword arguments object for creating an action2d.
+		//	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.
+		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:
+		//		Base action class for plot actions.
+
+		overOutEvents: {onmouseover: 1, onmouseout: 1},
+
+		constructor: function(chart, plot, kwargs){
+			//	summary:
+			//		Create a new base PlotAction.
+			//	chart: dojox.charting.Chart
+			//		The chart this action applies to.
+			//	plot: String?
+			//		The name of the plot this action belongs to.  If none is passed "default" is assumed.
+			//	kwargs: dojox.charting.action2d.__PlotActionCtorArgs?
+			//		Optional arguments for the action.
+			this.anim = {};
+
+			// process common optional named parameters
+			if(!kwargs){ kwargs = {}; }
+			this.duration = kwargs.duration ? kwargs.duration : DEFAULT_DURATION;
+			this.easing   = kwargs.easing   ? kwargs.easing   : DEFAULT_EASING;
+		},
+
+		connect: function(){
+			//	summary:
+			//		Connect this action to the given plot.
+			this.handle = this.chart.connectToPlot(this.plot.name, this, "process");
+		},
+
+		disconnect: function(){
+			//	summary:
+			//		Disconnect this action from the given plot, if connected.
+			if(this.handle){
+				hub.disconnect(this.handle);
+				this.handle = null;
+			}
+		},
+
+		reset: function(){
+			//	summary:
+			//		Reset the action.
+		},
+
+		destroy: function(){
+			//	summary:
+			//		Do any cleanup needed when destroying parent elements.
+			this.inherited(arguments);
+			df.forIn(this.anim, function(o){
+				df.forIn(o, function(anim){
+					anim.action.stop(true);
+				});
+			});
+			this.anim = {};
+		}
+	});
+});
diff --git a/dojox/charting/action2d/Shake.js b/dojox/charting/action2d/Shake.js
index 089f562..3827242 100644
--- a/dojox/charting/action2d/Shake.js
+++ b/dojox/charting/action2d/Shake.js
@@ -1,32 +1,29 @@
-dojo.provide("dojox.charting.action2d.Shake");
+define(["dojo/_base/connect", "dojo/_base/declare", "./PlotAction", 
+	"dojo/fx", "dojo/fx/easing", "dojox/gfx/matrix", "dojox/gfx/fx"], 
+	function(hub, declare, PlotAction, df, dfe, m, gf){
 
-dojo.require("dojox.charting.action2d.Base");
-dojo.require("dojox.gfx.matrix");
-dojo.require("dojo.fx");
+	/*=====
+	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;
+	=====*/
 
-/*=====
-dojo.declare("dojox.charting.action2d.__ShakeCtorArgs", dojox.charting.action2d.__BaseCtorArgs, {
-	//	summary:
-	//		Additional arguments for highlighting actions.
+	var DEFAULT_SHIFT = 3;
 
-	//	shift: Number?
-	//		The amount in pixels to shift the pie slice.  Default is 3.
-	shift: 3
-});
-=====*/
-(function(){
-	var DEFAULT_SHIFT = 3,
-		m = dojox.gfx.matrix,
-		gf = dojox.gfx.fx;
-
-	dojo.declare("dojox.charting.action2d.Shake", dojox.charting.action2d.Base, {
+	return declare("dojox.charting.action2d.Shake", PlotAction, {
 		//	summary:
 		//		Create a shaking action for use on an element in a chart.
 
 		// the data description block for the widget parser
 		defaultParams: {
 			duration: 400,	// duration of the action in ms
-			easing:   dojo.fx.easing.backOut,	// easing for the action
+			easing:   dfe.backOut,	// easing for the action
 			shiftX:   DEFAULT_SHIFT,	// shift of the element along the X axis
 			shiftY:   DEFAULT_SHIFT		// shift of the element along the Y axis
 		},
@@ -35,7 +32,7 @@ dojo.declare("dojox.charting.action2d.__ShakeCtorArgs", dojox.charting.action2d.
 		constructor: function(chart, plot, kwArgs){
 			//	summary:
 			//		Create the shaking action and connect it to the plot.
-			//	chart: dojox.charting.Chart2D
+			//	chart: dojox.charting.Chart
 			//		The chart this action belongs to.
 			//	plot: String?
 			//		The plot this action is attached to.  If not passed, "default" is assumed.
@@ -97,9 +94,9 @@ dojo.declare("dojox.charting.action2d.__ShakeCtorArgs", dojox.charting.action2d.
 				return;
 			}
 
-			anim.action = dojo.fx.combine(vector);
+			anim.action = df.combine(vector);
 			if(o.type == "onmouseout"){
-				dojo.connect(anim.action, "onEnd", this, function(){
+				hub.connect(anim.action, "onEnd", this, function(){
 					if(this.anim[runName]){
 						delete this.anim[runName][index];
 					}
@@ -108,4 +105,4 @@ dojo.declare("dojox.charting.action2d.__ShakeCtorArgs", dojox.charting.action2d.
 			anim.action.play();
 		}
 	});
-})();
+});
diff --git a/dojox/charting/action2d/Tooltip.js b/dojox/charting/action2d/Tooltip.js
index b656226..b86f6f8 100644
--- a/dojox/charting/action2d/Tooltip.js
+++ b/dojox/charting/action2d/Tooltip.js
@@ -1,26 +1,20 @@
-dojo.provide("dojox.charting.action2d.Tooltip");
-
-dojo.require("dijit.Tooltip");
-
-dojo.require("dojox.charting.action2d.Base");
-dojo.require("dojox.gfx.matrix");
-
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.functional.scan");
-dojo.require("dojox.lang.functional.fold");
-
-/*=====
-dojo.declare("dojox.charting.action2d.__TooltipCtorArgs", dojox.charting.action2d.__BaseCtorArgs, {
-	//	summary:
-	//		Additional arguments for tooltip actions.
+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){
+	
+	/*=====
+	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;
+	=====*/
 
-	//	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
-});
-=====*/
-(function(){
 	var DEFAULT_TEXT = function(o){
 		var t = o.run && o.run.data && o.run.data[o.index];
 		if(t && typeof t != "number" && (t.tooltip || t.text)){
@@ -38,9 +32,9 @@ dojo.declare("dojox.charting.action2d.__TooltipCtorArgs", dojox.charting.action2
 		return o.element == "bar" ? o.x : o.y;
 	};
 
-	var df = dojox.lang.functional, m = dojox.gfx.matrix, pi4 = Math.PI / 4, pi2 = Math.PI / 2;
+	var pi4 = Math.PI / 4, pi2 = Math.PI / 2;
 	
-	dojo.declare("dojox.charting.action2d.Tooltip", dojox.charting.action2d.Base, {
+	return declare("dojox.charting.action2d.Tooltip", PlotAction, {
 		//	summary:
 		//		Create an action on a plot where a tooltip is shown when hovering over an element.
 
@@ -53,7 +47,7 @@ dojo.declare("dojox.charting.action2d.__TooltipCtorArgs", dojox.charting.action2
 		constructor: function(chart, plot, kwArgs){
 			//	summary:
 			//		Create the tooltip action and connect it to the plot.
-			//	chart: dojox.charting.Chart2D
+			//	chart: dojox.charting.Chart
 			//		The chart this action belongs to.
 			//	plot: String?
 			//		The plot this action is attached to.  If not passed, "default" is assumed.
@@ -70,7 +64,7 @@ dojo.declare("dojox.charting.action2d.__TooltipCtorArgs", dojox.charting.action2
 			//	o: dojox.gfx.Shape
 			//		The object on which to process the highlighting action.
 			if(o.type === "onplotreset" || o.type === "onmouseout"){
-                dijit.hideTooltip(this.aroundRect);
+                Tooltip.hide(this.aroundRect);
 				this.aroundRect = null;
 				if(o.type === "onplotreset"){
 					delete this.angles;
@@ -86,24 +80,26 @@ dojo.declare("dojox.charting.action2d.__TooltipCtorArgs", dojox.charting.action2
 				case "marker":
 					aroundRect.x = o.cx;
 					aroundRect.y = o.cy;
-					aroundRect.width = aroundRect.height = 1;
+					aroundRect.w = aroundRect.h = 1;
 					break;
 				case "circle":
 					aroundRect.x = o.cx - o.cr;
 					aroundRect.y = o.cy - o.cr;
-					aroundRect.width = aroundRect.height = 2 * o.cr;
+					aroundRect.w = aroundRect.h = 2 * o.cr;
 					break;
 				case "column":
 					position = ["above", "below"];
 					// intentional fall down
 				case "bar":
-					aroundRect = dojo.clone(o.shape.getShape());
+					aroundRect = lang.clone(o.shape.getShape());
+					aroundRect.w = aroundRect.width;
+					aroundRect.h = aroundRect.height;
 					break;
 				case "candlestick":
 					aroundRect.x = o.x;
 					aroundRect.y = o.y;
-					aroundRect.width = o.width;
-					aroundRect.height = o.height;
+					aroundRect.w = o.width;
+					aroundRect.h = o.height;
 					break;
 				default:
 				//case "slice":
@@ -121,7 +117,7 @@ dojo.declare("dojox.charting.action2d.__TooltipCtorArgs", dojox.charting.action2
 						angle = (this.angles[o.index] + this.angles[o.index + 1]) / 2 + startAngle;
 					aroundRect.x = o.cx + o.cr * Math.cos(angle);
 					aroundRect.y = o.cy + o.cr * Math.sin(angle);
-					aroundRect.width = aroundRect.height = 1;
+					aroundRect.w = aroundRect.h = 1;
 					// calculate the position
 					if(angle < pi4){
 						// do nothing: the position is right
@@ -141,19 +137,30 @@ dojo.declare("dojox.charting.action2d.__TooltipCtorArgs", dojox.charting.action2
 			}
 			
 			// adjust relative coordinates to absolute, and remove fractions
-			var lt = dojo.coords(this.chart.node, true);
+			var lt = this.chart.getCoords();
 			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);
+			aroundRect.w = Math.ceil(aroundRect.w);
+			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");
+			}
 			if(tooltip){
-                dijit.showTooltip(tooltip, this.aroundRect, position);
+				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);
+				}
 			}
 		}
 	});
-})();
+});
diff --git a/dojox/charting/action2d/TouchIndicator.js b/dojox/charting/action2d/TouchIndicator.js
new file mode 100644
index 0000000..f8fc594
--- /dev/null
+++ b/dojox/charting/action2d/TouchIndicator.js
@@ -0,0 +1,232 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/event", "./ChartAction", "./_IndicatorElement", "dojox/lang/utils"],
+	function(lang, declare, eventUtil, 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;
+	=====*/
+
+	return declare("dojox.charting.action2d.TouchIndicator", ChartAction, {
+		//	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
+		defaultParams: {
+			series: "",
+			dualIndicator: false,
+			vertical: true,
+			autoScroll: true,
+			fixed: true,
+			precision: 0
+		},
+		optionalParams: {
+			lineStroke: {},
+			outlineStroke: {},
+			shadowStroke: {},
+			stroke:		{},
+			outline:	{},
+			shadow:		{},
+			fill:		{},
+			fillFunc:  null,
+			labelFunc: null,
+			font:		"",
+			fontColor:	"",
+			markerStroke:		{},
+			markerOutline:		{},
+			markerShadow:		{},
+			markerFill:			{},
+			markerSymbol:		""
+		},	
+
+		constructor: function(chart, plot, kwArgs){
+			//	summary:
+			//		Create a new touch indicator action and connect it.
+			//	chart: dojox.charting.Chart
+			//		The chart this action applies to.
+			//	kwArgs: dojox.charting.action2d.__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.opt = lang.clone(this.defaultParams);
+			du.updateWithObject(this.opt, kwArgs);
+			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
+			this._uName = "touchIndicator"+this.opt.series;
+			this.connect();
+		},
+		
+		connect: function(){
+			//	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});
+		},
+
+		disconnect: function(){
+			//	summary:
+			//		Disconnect this action from the chart.
+			var plot = this.chart.getPlot(this._uName);
+			if(plot.pageCoord){
+				// we might still have something drawn on the screen
+				this.onTouchEnd();
+			}
+			this.chart.removePlot(this._uName);
+			this.inherited(arguments);
+		},
+
+		onTouchStart: function(event){
+			//	summary:
+			//		Called when touch is started on the chart.		
+			if(event.touches.length==1){
+				this._onTouchSingle(event, true);
+			}else if(this.opt.dualIndicator && event.touches.length==2){
+				this._onTouchDual(event);
+			}
+		},
+
+		onTouchMove: function(event){
+			//	summary:
+			//		Called when touch is moved on the chart.
+			if(event.touches.length==1){
+				this._onTouchSingle(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.dirty = true;
+			if(delayed){
+				this.chart.delayedRender();
+			}else{
+				this.chart.render();
+			}
+			eventUtil.stop(event);
+		},
+		
+		_onTouchDual: function(event){
+			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};
+			plot.dirty = true;
+			this.chart.render();
+			eventUtil.stop(event);
+		},
+
+		onTouchEnd: function(event){
+			//	summary:
+			//		Called when touch is ended or canceled on the chart.
+			var plot = this.chart.getPlot(this._uName);
+			plot.stopTrack();
+			plot.pageCoord = null;
+			plot.secondCoord = null;
+			plot.dirty = true;
+			this.chart.delayedRender();
+		}
+	});
+});
diff --git a/dojox/charting/action2d/TouchZoomAndPan.js b/dojox/charting/action2d/TouchZoomAndPan.js
new file mode 100644
index 0000000..f60b679
--- /dev/null
+++ b/dojox/charting/action2d/TouchZoomAndPan.js
@@ -0,0 +1,249 @@
+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:
+		//		private
+		constructor: function(chart){
+		},
+		render: function(){
+			if(!this.isDirty()){
+				return;
+			}
+			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:
+			//		Clear out any parameters set on this plot.
+			//	returns: dojox.charting.action2d._IndicatorElement
+			//		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
+		},
+		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(common.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;
+		}
+	});
+	
+	/*=====
+	
+	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;
+	=====*/
+	
+	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. 
+		//		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,	
+			maxScale: 100,
+			enableScroll: true,
+			enableZoom: true
+		},
+		optionalParams: {},	// no optional parameters
+	
+		constructor: function(chart, plot, kwArgs){
+			//	summary:
+			//		Create a new touch zoom and pan action and connect it.
+			//	chart: dojox.charting.Chart
+			//		The chart this action applies to.
+			//	kwArgs: dojox.charting.action2d.__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"}];
+			if(!kwArgs){ kwArgs = {}; }
+			this.axis = kwArgs.axis ? kwArgs.axis : "x";
+			this.scaleFactor = kwArgs.scaleFactor ? kwArgs.scaleFactor : 1.2;
+			this.maxScale = kwArgs.maxScale ? kwArgs.maxScale : 100;
+			this.enableScroll = kwArgs.enableScroll != undefined ? kwArgs.enableScroll : true;
+			this.enableZoom = kwArgs.enableScroll != undefined ? kwArgs.enableZoom : true;
+			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
+			//		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
+			// 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){
+				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){
+				this.chart.removePlot(this._uName);
+			}
+			this.inherited(arguments);
+		},
+	
+		onTouchStart: function(event){
+			//	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};
+			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){
+				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};
+				var scaler = axis.getScaler();
+				this._initScale = axis.getWindowScale();
+				var t = this._initData =  this.plot.toData();
+				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);
+			}
+		},
+	
+		onTouchMove: function(event){
+			//	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", 
+					attr = axis.vertical?"y":"x";
+			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};		
+				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]);
+				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:
+			//		Called when touch is ended on the chart.
+			var chart = this.chart, axis = chart.getAxis(this.axis);
+			if(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};
+				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); 
+		},
+	
+		onDoubleTap: function(event){
+			//	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], 
+				newStart = scale * (start - oldMiddle) + newMiddle, newEnd = scale * (end - oldMiddle) + newMiddle;
+				chart.zoomIn(this.axis, [newStart, newEnd]);
+			}else{
+				// non fit => fit
+				chart.setAxisWindow(this.axis, 1, 0);
+				chart.render();
+			}
+			eventUtil.stop(event);
+		}
+	});
+});		
diff --git a/dojox/charting/action2d/_IndicatorElement.js b/dojox/charting/action2d/_IndicatorElement.js
new file mode 100644
index 0000000..7dc5ccf
--- /dev/null
+++ b/dojox/charting/action2d/_IndicatorElement.js
@@ -0,0 +1,370 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "../Element", "../plot2d/common", 
+    "../axis2d/common", "dojox/gfx"], 
+	function(lang, declare, Element, dcpc, dcac, gfx){ 
+
+	// 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;
+		}
+		coef = coef || 1;
+		sz.y = sh.y - height*coef; // rough approximation of the ascent!...
+		return sz;
+	};
+
+	return declare("dojox.charting.action2d._IndicatorElement",[Element], {
+		//	summary:
+		//		Internal element used by indicator actions.
+		//	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 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();
+			}
+		},
+		_trackMove: function(){
+			// let's update the selector
+			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);
+			}
+		},
+		initTrack: function(){
+			this._initTrackPhase = true;
+			this._tracker = setTimeout(lang.hitch(this, this._trackMove), 500);
+		},
+		stopTrack: function(){
+			if(this._tracker){
+				if(this._initTrackPhase){
+					clearTimeout(this._tracker);					
+				}else{
+					clearInterval(this._tracker);
+				}
+				this._tracker = null;
+			}
+		},
+		render: function(){
+			if(!this.isDirty()){
+				return;
+			}
+
+			this.cleanGroup();
+
+			if (!this.pageCoord){
+				return;
+			}
+			
+			this._updateIndicator(this.pageCoord, this.secondCoord);
+		},
+		_updateIndicator: function(cp1, cp2){
+			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){
+						tmp = cp2;
+						cp2 = cp1;
+						cp1 = tmp;
+					}
+				}else{
+					if(cp1.y>cp2.y){
+						tmp = cp2;
+						cp2 = cp1;
+						cp1 = tmp;
+					}		
+				}
+			}
+
+			var cd1 = plot.toData(cp1), cd2;
+			if(cp2){
+				cd2 = plot.toData(cp2);
+			}
+			
+			var o = {};
+			o[hn] = hb.from;
+			o[vn] = vb.from;
+			var min = plot.toPage(o);
+			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){
+					this._updateVisibility(cp1, min, attr);
+					return;
+				}else{
+					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){
+					this._updateVisibility(cp1, max, attr);
+					return;
+				}else{
+					cp1[attr] = max[attr];
+				}
+				// cp1 might have changed, let's update cd1
+				cd1 = plot.toData(cp1);
+			}	
+			
+			var c1 = this._getData(cd1, attr, v), c2;
+
+			if(c1.y == null){
+				// we have no data for that point let's just return
+				return;
+			}
+
+			if(cp2){
+				if(cd2[n] < bounds.from){
+					cp2[attr] = min[attr];
+					cd2 = plot.toData(cp2);
+				}else if(cd2[n] > bounds.to){
+					cp2[attr] = max[attr];
+					cd2 = plot.toData(cp2);	
+				}
+				c2 = this._getData(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;
+				}
+			}
+			
+			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();
+		},
+		_getData: 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;
+			for (i = 0; i < l; ++i){
+				r = data[i];
+				if(r == null){
+					// move to next item
+				}else if(typeof r == "number"){
+					if(i + 1 > cd[attr]){
+						break;
+					}
+				}else if(r[attr] > cd[attr]){
+					break;
+				}
+			}
+			var x,y,px,py;
+			if(typeof r == "number"){
+				x = i+1;
+				y = r;
+				if(i>0){
+					px = i;
+					py = data[i-1];
+				}
+			}else{
+				x = r.x;
+				y = r.y;
+				if(i>0){
+					px = data[i-1].x;
+					py = data[i-1].y;
+				}
+			}
+			if(i>0){
+				var m = v?(x+px)/2:(y+py)/2;
+				if(cd[attr]<=m){
+					x = px;
+					y = py;
+				}
+			}
+			return {x: x, y: y};
+		},
+		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);
+			// 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;
+		},
+		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._noDirty && (this.dirty || this.inter.plot.isDirty());
+		}
+	});
+});
diff --git a/dojox/charting/axis2d/Base.js b/dojox/charting/axis2d/Base.js
index 53c3679..2b1c0fc 100644
--- a/dojox/charting/axis2d/Base.js
+++ b/dojox/charting/axis2d/Base.js
@@ -1,8 +1,9 @@
-dojo.provide("dojox.charting.axis2d.Base");
-
-dojo.require("dojox.charting.Element");
-
-dojo.declare("dojox.charting.axis2d.Base", dojox.charting.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
@@ -10,7 +11,7 @@ dojo.declare("dojox.charting.axis2d.Base", dojox.charting.Element, {
 	constructor: function(chart, kwArgs){
 		//	summary:
 		//		Return a new base axis.
-		//	chart: dojox.charting.Chart2D
+		//	chart: dojox.charting.Chart
 		//		The chart this axis belongs to.
 		//	kwArgs: dojox.charting.axis2d.__AxisCtorArgs?
 		//		An optional arguments object to define the axis parameters.
@@ -67,3 +68,4 @@ dojo.declare("dojox.charting.axis2d.Base", dojox.charting.Element, {
 		return this;	//	dojox.charting.axis2d.Base
 	}
 });
+});
diff --git a/dojox/charting/axis2d/Default.js b/dojox/charting/axis2d/Default.js
index 434dc05..dfef5cd 100644
--- a/dojox/charting/axis2d/Default.js
+++ b/dojox/charting/axis2d/Default.js
@@ -1,127 +1,122 @@
-dojo.provide("dojox.charting.axis2d.Default");
+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){
 
-dojo.require("dojox.charting.axis2d.Invisible");
-
-dojo.require("dojox.charting.scaler.linear");
-dojo.require("dojox.charting.axis2d.common");
-
-dojo.require("dojo.colors");
-dojo.require("dojo.string");
-dojo.require("dojox.gfx");
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.utils");
-
-/*=====
-	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:
-	//		Optional arguments used in the definition of an 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.
-	//	majorLabels: Boolean?
-	//		Flag to draw all 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?
-	//		Flag to draw micro ticks on an axis. Default is false.
-	//	htmlLabels: Boolean?
-	//		Flag to use HTML (as opposed to the native vector graphics engine) to draw labels. 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.  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[]?
-	//		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?
-	//		The maximum size, in pixels, for a label.  To be used with the optional label function.
-	//	stroke: dojox.gfx.Stroke?
-	//		An optional stroke to be used for drawing an axis.
-	//	majorTick: Object?
-	//		An object containing a dojox.gfx.Stroke, and a length (number) for a major tick.
-	//	minorTick: Object?
-	//		An object containing a dojox.gfx.Stroke, and a length (number) for a minor tick.
-	//	microTick: Object?
-	//		An object containing a dojox.gfx.Stroke, and a length (number) for a micro tick.
-	//	tick: Object?
-	//		An object containing a dojox.gfx.Stroke, and a length (number) for a tick.
-	//	font: String?
-	//		An optional font definition (as used in the CSS font property) for labels.
-	//	fontColor: String|dojo.Color?
-	//		An optional color to be used in drawing labels.
+	/*=====
+		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:
+		//		Optional arguments used in the definition of an 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.
+		//	majorLabels: Boolean?
+		//		Flag to draw all 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?
+		//		Flag to draw micro ticks on an axis. Default is false.
+		//	htmlLabels: Boolean?
+		//		Flag to use HTML (as opposed to the native vector graphics engine) to draw labels. 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.  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[]?
+		//		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?
+		//		The maximum size, in pixels, for a label.  To be used with the optional label function.
+		//	stroke: dojox.gfx.Stroke?
+		//		An optional stroke to be used for drawing an axis.
+		//	majorTick: Object?
+		//		An object containing a dojox.gfx.Stroke, and a length (number) for a major tick.
+		//	minorTick: Object?
+		//		An object containing a dojox.gfx.Stroke, and a length (number) for a minor tick.
+		//	microTick: Object?
+		//		An object containing a dojox.gfx.Stroke, and a length (number) for a micro tick.
+		//	tick: Object?
+		//		An object containing a dojox.gfx.Stroke, and a length (number) for a tick.
+		//	font: String?
+		//		An optional font definition (as used in the CSS font property) for labels.
+		//	fontColor: String|dojo.Color?
+		//		An optional color to be used in drawing labels.
+		//	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
+	=====*/
 
-	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;
-}
-=====*/
-(function(){
-	var dc = dojox.charting,
-		du = dojox.lang.utils,
-		g = dojox.gfx,
-		lin = dc.scaler.linear,
-		labelGap = 4,			// in pixels
+	var labelGap = 4,			// in pixels
 		centerAnchorLimit = 45;	// in degrees
 
-	dojo.declare("dojox.charting.axis2d.Default", dojox.charting.axis2d.Invisible, {
+	return declare("dojox.charting.axis2d.Default", Invisible, {
 		//	summary:
 		//		The default axis object used in dojox.charting.  See dojox.charting.Chart.addAxis for details.
 		//
@@ -168,7 +163,8 @@ dojo.require("dojox.lang.utils");
 			minorLabels: true,		// draw minor labels
 			microTicks:  false,		// draw micro ticks
 			rotation:    0,			// label rotation angle in degrees
-			htmlLabels:  true		// use HTML to draw labels
+			htmlLabels:  true,		// use HTML to draw labels
+			enableCache: false		// whether we cache or not
 		},
 		optionalParams: {
 			min:			0,	// minimal value on this axis
@@ -207,13 +203,19 @@ dojo.require("dojox.lang.utils");
 		constructor: function(chart, kwArgs){
 			//	summary:
 			//		The constructor for an axis.
-			//	chart: dojox.charting.Chart2D
+			//	chart: dojox.charting.Chart
 			//		The chart the axis belongs to.
 			//	kwArgs: dojox.charting.axis2d.__AxisCtorArgs?
 			//		Any optional keyword arguments to be used to define this axis.
-			this.opt = dojo.clone(this.defaultParams);
+			this.opt = lang.clone(this.defaultParams);
             du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
+			if(this.opt.enableCache){
+				this._textFreePool = [];
+				this._lineFreePool = [];
+				this._textUsePool = [];
+				this._lineUsePool = [];
+			}
 		},
 		getOffsets: function(){
 			//	summary:
@@ -225,7 +227,7 @@ dojo.require("dojox.lang.utils");
 				return offsets;
 			}
 			var o = this.opt, labelWidth = 0, a, b, c, d,
-				gl = dc.scaler.common.getNumericLabel,
+				gl = scommon.getNumericLabel,
 				offset = 0, ma = s.major, mi = s.minor,
 				ta = this.chart.theme.axis,
 				// TODO: we use one font --- of major tick, we need to use major and minor fonts
@@ -328,6 +330,67 @@ dojo.require("dojox.lang.utils");
 			}
 			return offsets;	//	Object
 		},
+		cleanGroup: function(creator){
+			if(this.opt.enableCache && this.group){
+				this._lineFreePool = this._lineFreePool.concat(this._lineUsePool);
+				this._lineUsePool = [];
+				this._textFreePool = this._textFreePool.concat(this._textUsePool);
+				this._textUsePool = [];
+			}
+			this.inherited(arguments);
+		},
+		createText: function(labelType, creator, x, y, align, textContent, font, fontColor, labelWidth){
+			if(!this.opt.enableCache || labelType=="html"){
+				return acommon.createText[labelType](
+						this.chart,
+						creator,
+						x,
+						y,
+						align,
+						textContent,
+						font,
+						fontColor,
+						labelWidth
+					);
+			}
+			var text;
+			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
+				//.setFont(font).setFill(fontColor);
+				// was cleared, add it back
+				creator.add(text);
+			}else{
+				text = acommon.createText[labelType](
+						this.chart,
+						creator,
+						x,
+						y,
+						align,
+						textContent,
+						font,
+						fontColor,
+						labelWidth
+					);			}
+			this._textUsePool.push(text);
+			return text;
+		},
+		createLine: function(creator, params){
+			var line;
+			if(this.opt.enableCache && this._lineFreePool.length > 0){
+				line = this._lineFreePool.pop();
+				line.setShape(params);
+				// was cleared, add it back
+				creator.add(line);
+			}else{
+				line = creator.createLine(params);
+			}
+			if(this.opt.enableCache){
+				this._lineUsePool.push(line);
+			}
+			return line;
+		},
 		render: function(dim, offsets){
 			//	summary:
 			//		Render/draw the axis.
@@ -517,7 +580,7 @@ dojo.require("dojox.lang.utils");
 					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 = !titleRotation && !rotation && this.opt.htmlLabels && !dojo.isIE && !dojo.isOpera ? "html" : "gfx",
+					labelType = (!o.title || !titleRotation) && !rotation && this.opt.htmlLabels && !has("ie") && !has("opera") ? "html" : "gfx",
 					dx = tickVector.x * taMajorTick.length,
 					dy = tickVector.y * taMajorTick.length;
 
@@ -530,7 +593,7 @@ dojo.require("dojox.lang.utils");
 				
 				//create axis title
 				if(o.title){
-					var axisTitle = dc.axis2d.common.createText[labelType](
+					var axisTitle = acommon.createText[labelType](
 						this.chart,
 						s,
 						titlePos.x,
@@ -548,12 +611,18 @@ dojo.require("dojox.lang.utils");
 						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;
+				}
 
-				dojo.forEach(t.major, function(tick){
+				arr.forEach(t.major, function(tick){
 					var offset = f(tick.value), elem,
 						x = start.x + axisVector.x * offset,
 						y = start.y + axisVector.y * offset;
-						s.createLine({
+						this.createLine(s, {
 							x1: x, y1: y,
 							x2: x + dx,
 							y2: y + dy
@@ -564,8 +633,7 @@ dojo.require("dojox.lang.utils");
 								truncated: false
 							};
 							label = o.maxLabelSize ? this.getTextWithLimitLength(label.text, taFont, o.maxLabelSize, label.truncated) : label;
-							elem = dc.axis2d.common.createText[labelType](
-								this.chart,
+							elem = this.createText(labelType,
 								s,
 								x + dx + anchorOffset.x + (rotation ? 0 : labelOffset.x),
 								y + dy + anchorOffset.y + (rotation ? 0 : labelOffset.y),
@@ -575,6 +643,15 @@ dojo.require("dojox.lang.utils");
 								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);
@@ -594,11 +671,11 @@ dojo.require("dojox.lang.utils");
 				dx = tickVector.x * taMinorTick.length;
 				dy = tickVector.y * taMinorTick.length;
 				canLabel = c.minMinorStep <= c.minor.tick * c.bounds.scale;
-				dojo.forEach(t.minor, function(tick){
+				arr.forEach(t.minor, function(tick){
 					var offset = f(tick.value), elem,
 						x = start.x + axisVector.x * offset,
 						y = start.y + axisVector.y * offset;
-						s.createLine({
+						this.createLine(s, {
 							x1: x, y1: y,
 							x2: x + dx,
 							y2: y + dy
@@ -609,8 +686,7 @@ dojo.require("dojox.lang.utils");
 								truncated: false
 							};
 							label = o.maxLabelSize ? this.getTextWithLimitLength(label.text, taFont, o.maxLabelSize, label.truncated) : label;
-							elem = dc.axis2d.common.createText[labelType](
-								this.chart,
+							elem = this.createText(labelType,
 								s,
 								x + dx + anchorOffset.x + (rotation ? 0 : labelOffset.x),
 								y + dy + anchorOffset.y + (rotation ? 0 : labelOffset.y),
@@ -620,6 +696,14 @@ dojo.require("dojox.lang.utils");
 								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);
@@ -638,11 +722,11 @@ dojo.require("dojox.lang.utils");
 
 				dx = tickVector.x * taMicroTick.length;
 				dy = tickVector.y * taMicroTick.length;
-				dojo.forEach(t.micro, function(tick){
+				arr.forEach(t.micro, function(tick){
 					var offset = f(tick.value), elem,
 						x = start.x + axisVector.x * offset,
 						y = start.y + axisVector.y * offset;
-						s.createLine({
+						this.createLine(s, {
 							x1: x, y1: y,
 							x2: x + dx,
 							y2: y + dy
@@ -656,34 +740,34 @@ dojo.require("dojox.lang.utils");
 			return this;	//	dojox.charting.axis2d.Default
 		},
 		labelTooltip: function(elem, chart, label, truncatedLabel, font, elemType){
-			// to avoid requiring dijit module for that feature, let's test that
-			// dynamically and return if we can't do it
-			if(!dijit || !dijit.Tooltip){
-				return;
-			}
+			var modules = ["dijit/Tooltip"];
 			var aroundRect = {type: "rect"}, position = ["above", "below"],
-				fontWidth = dojox.gfx._base._getTextBox(truncatedLabel, {font: font}).w || 0;
+				fontWidth = g._base._getTextBox(truncatedLabel, {font: font}).w || 0,
 				fontHeight = font ? g.normalizedLength(g.splitFontString(font).size) : 0;
 			if(elemType == "html"){
-				dojo.mixin(aroundRect, dojo.coords(elem.firstChild, true));
+				lang.mixin(aroundRect, html.coords(elem.firstChild, true));
 				aroundRect.width = Math.ceil(fontWidth);
 				aroundRect.height = Math.ceil(fontHeight);
 				this._events.push({
 					shape:  dojo,
-					handle: dojo.connect(elem.firstChild, "onmouseover", this, function(e){
-						dijit.showTooltip(label, aroundRect, position);
+					handle: connect.connect(elem.firstChild, "onmouseover", this, function(e){
+						require(modules, function(Tooltip){
+							Tooltip.show(label, aroundRect, position);
+						});
 					})
 				});
 				this._events.push({
 					shape:  dojo,
-					handle: dojo.connect(elem.firstChild, "onmouseout", this, function(e){
-						dijit.hideTooltip(aroundRect);
+					handle: connect.connect(elem.firstChild, "onmouseout", this, function(e){
+						require(modules, function(Tooltip){
+							Tooltip.hide(aroundRect);
+						});
 					})
 				});
 			}else{
 				var shp = elem.getShape(),
-					lt = dojo.coords(chart.node, true);
-				aroundRect = dojo.mixin(aroundRect, {
+					lt = html.coords(chart.node, true);
+				aroundRect = lang.mixin(aroundRect, {
 					x: shp.x - fontWidth / 2,
 					y: shp.y
 				});
@@ -696,16 +780,20 @@ dojo.require("dojox.lang.utils");
 				this._events.push({
 					shape:  elem,
 					handle: elem.connect("onmouseenter", this, function(e){
-						dijit.showTooltip(label, aroundRect, position);
+						require(modules, function(Tooltip){
+							Tooltip.show(label, aroundRect, position);
+						});
 					})
 				});
 				this._events.push({
 					shape:  elem,
 					handle: elem.connect("onmouseleave", this, function(e){
-						dijit.hideTooltip(aroundRect);
+						require(modules, function(Tooltip){
+							Tooltip.hide(aroundRect);
+						});
 					})
 				});
 			}
 		}
 	});
-})();
+});
diff --git a/dojox/charting/axis2d/Invisible.js b/dojox/charting/axis2d/Invisible.js
index d212cc6..b03bea0 100644
--- a/dojox/charting/axis2d/Invisible.js
+++ b/dojox/charting/axis2d/Invisible.js
@@ -1,27 +1,16 @@
-dojo.provide("dojox.charting.axis2d.Invisible");
-
-dojo.require("dojox.charting.scaler.linear");
-dojo.require("dojox.charting.axis2d.common");
-dojo.require("dojox.charting.axis2d.Base");
-
-dojo.require("dojo.string");
-dojo.require("dojox.gfx");
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.utils");
-
-(function(){
-	var dc = dojox.charting,
-		df = dojox.lang.functional,
-		du = dojox.lang.utils,
-		g = dojox.gfx,
-		lin = dc.scaler.linear,
-		merge = du.merge,
+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){
+/*=====
+var Base = dojox.charting.axis2d.Base;
+=====*/ 
+	var merge = du.merge,
 		labelGap = 4,			// in pixels
 		centerAnchorLimit = 45;	// in degrees
 
-	dojo.declare("dojox.charting.axis2d.Invisible", dojox.charting.axis2d.Base, {
+	return declare("dojox.charting.axis2d.Invisible", Base, {
 		//	summary:
-		//		The default axis object used in dojox.charting.  See dojox.charting.Chart2D.addAxis for details.
+		//		The default axis object used in dojox.charting.  See dojox.charting.Chart.addAxis for details.
 		//
 		//	defaultParams: Object
 		//		The default parameters used to define any axis.
@@ -90,11 +79,11 @@ dojo.require("dojox.lang.utils");
 		constructor: function(chart, kwArgs){
 			//	summary:
 			//		The constructor for an axis.
-			//	chart: dojox.charting.Chart2D
+			//	chart: dojox.charting.Chart
 			//		The chart the axis belongs to.
 			//	kwArgs: dojox.charting.axis2d.__AxisCtorArgs?
 			//		Any optional keyword arguments to be used to define this axis.
-			this.opt = dojo.clone(this.defaultParams);
+			this.opt = lang.clone(this.defaultParams);
             du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
 		},
@@ -147,16 +136,16 @@ dojo.require("dojox.lang.utils");
 			if(!labels.length){
 				return 0;
 			}
-			if(dojo.isObject(labels[0])){
+			if(lang.isObject(labels[0])){
 				labels = df.map(labels, function(label){ return label.text; });
 			}
 			if (wcLimit) {
 				labels = df.map(labels, function(label){
-					return dojo.trim(label).length == 0 ? "" : label.substring(0, wcLimit) + this.trailingSymbol;
+					return lang.trim(label).length == 0 ? "" : label.substring(0, wcLimit) + this.trailingSymbol;
 				}, this);
 			}
 			var s = labels.join("<br>");
-			return dojox.gfx._base._getTextBox(s, {font: font}).w || 0;
+			return g._base._getTextBox(s, {font: font}).w || 0;
 		},
 		calculate: function(min, max, span, labels){
 			//	summary:
@@ -245,15 +234,15 @@ dojo.require("dojox.lang.utils");
 						if(tsb.from < 0 || tsb.to < 0){
 							t.push("-");
 						}
-						t.push(dojo.string.rep("9", labelLength));
+						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(dojo.string.rep("9", precision));
+							t.push(dstring.rep("9", precision));
 						}
-						labelWidth = dojox.gfx._base._getTextBox(
+						labelWidth = g._base._getTextBox(
 							t.join(""),
 							{ font: taFont }
 						).w;
@@ -293,4 +282,4 @@ dojo.require("dojox.lang.utils");
 			return this.ticks;	//	Object
 		}
 	});
-})();
+});
diff --git a/dojox/charting/axis2d/common.js b/dojox/charting/axis2d/common.js
index b0153c7..6682346 100644
--- a/dojox/charting/axis2d/common.js
+++ b/dojox/charting/axis2d/common.js
@@ -1,10 +1,8 @@
-dojo.provide("dojox.charting.axis2d.common");
-
-dojo.require("dojox.gfx");
-
-(function(){
-	var g = dojox.gfx;
+define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/window", "dojo/dom-geometry", "dojox/gfx"], 
+	function(lang, html, win, domGeom, g){
 
+	var common = lang.getObject("dojox.charting.axis2d.common", true);
+	
 	var clearNode = function(s){
 		s.marginLeft   = "0px";
 		s.marginTop    = "0px";
@@ -26,18 +24,18 @@ dojo.require("dojox.gfx");
 			var bcr = n.getBoundingClientRect();
 			return bcr.width || (bcr.right - bcr.left);
 		}else{
-			return dojo.marginBox(n).w;
+			return domGeom.getMarginBox(n).w;
 		}
 	};
 
-	dojo.mixin(dojox.charting.axis2d.common, {
+	return lang.mixin(common, {
 		//	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:
 				//		Use dojox.gfx to create any text.
-				//	chart: dojox.charting.Chart2D
+				//	chart: dojox.charting.Chart
 				//		The chart to create the text into.
 				//	creator: dojox.gfx.Surface
 				//		The graphics surface to use for creating the text.
@@ -62,7 +60,7 @@ dojo.require("dojox.gfx");
 			html: function(chart, creator, x, y, align, text, font, fontColor, labelWidth){
 				//	summary:
 				//		Use the HTML DOM to create any text.
-				//	chart: dojox.charting.Chart2D
+				//	chart: dojox.charting.Chart
 				//		The chart to create the text into.
 				//	creator: dojox.gfx.Surface
 				//		The graphics surface to use for creating the text.
@@ -84,7 +82,11 @@ dojo.require("dojox.gfx");
 				//		The resultant DOMNode (a "div" element).
 
 				// setup the text node
-				var p = dojo.doc.createElement("div"), s = p.style, boxWidth;
+				var p = win.doc.createElement("div"), s = p.style, boxWidth;
+				// bidi support, if this function exists the module was loaded 
+				if(chart.getTextDir){
+					p.dir = chart.getTextDir(text);
+				}
 				clearNode(s);
 				s.font = font;
 				p.innerHTML = String(text).replace(/\s/g, " ");
@@ -92,16 +94,21 @@ dojo.require("dojox.gfx");
 				// measure the size
 				s.position = "absolute";
 				s.left = "-10000px";
-				dojo.body().appendChild(p);
+				win.body().appendChild(p);
 				var size = g.normalizedLength(g.splitFontString(font).size);
 
 				// do we need to calculate the label width?
 				if(!labelWidth){
 					boxWidth = getBoxWidth(p);
 				}
+				// when the textDir is rtl, but the UI ltr needs
+				// to recalculate the starting point
+				if(p.dir == "rtl"){
+					x += labelWidth ? labelWidth : boxWidth;
+				}
 
 				// new settings for the text node
-				dojo.body().removeChild(p);
+				win.body().removeChild(p);
 
 				s.position = "relative";
 				if(labelWidth){
@@ -140,7 +147,7 @@ dojo.require("dojox.gfx");
 				s.top = Math.floor(y - size) + "px";
 				s.whiteSpace = "nowrap";	// hack for WebKit
 				// setup the wrapper node
-				var wrap = dojo.doc.createElement("div"), w = wrap.style;
+				var wrap = win.doc.createElement("div"), w = wrap.style;
 				clearNode(w);
 				w.width = "0px";
 				w.height = "0px";
@@ -151,4 +158,4 @@ dojo.require("dojox.gfx");
 			}
 		}
 	});
-})();
+});
diff --git a/dojox/charting/plot2d/Areas.js b/dojox/charting/plot2d/Areas.js
index 365cd9d..ca9e8a8 100644
--- a/dojox/charting/plot2d/Areas.js
+++ b/dojox/charting/plot2d/Areas.js
@@ -1,12 +1,14 @@
-dojo.provide("dojox.charting.plot2d.Areas");
-
-dojo.require("dojox.charting.plot2d.Default");
-
-dojo.declare("dojox.charting.plot2d.Areas", dojox.charting.plot2d.Default, {
-	//	summary:
-	//		Represents an area chart.  See dojox.charting.plot2d.Default for details.
-	constructor: function(){
-		this.opt.lines = true;
-		this.opt.areas = true;
-	}
+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.
+		constructor: function(){
+			this.opt.lines = true;
+			this.opt.areas = true;
+		}
+	});
 });
diff --git a/dojox/charting/plot2d/Bars.js b/dojox/charting/plot2d/Bars.js
index 74f63e7..aeb9a75 100644
--- a/dojox/charting/plot2d/Bars.js
+++ b/dojox/charting/plot2d/Bars.js
@@ -1,39 +1,38 @@
-dojo.provide("dojox.charting.plot2d.Bars");
-
-dojo.require("dojox.charting.plot2d.common");
-dojo.require("dojox.charting.plot2d.Base");
-dojo.require("dojox.gfx.fx");
-
-dojo.require("dojox.lang.utils");
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.functional.reversed");
-/*=====
-dojo.declare("dojox.charting.plot2d.__BarCtorArgs", dojox.charting.plot2d.__DefaultCtorArgs, {
-	//	summary:
-	//		Additional keyword arguments for bar charts.
-
-	//	minBarSize: Number?
-	//		The minimum size for a bar in pixels.  Default is 1.
-	minBarSize: 1,
-
-	//	maxBarSize: Number?
-	//		The maximum size for a bar in pixels.  Default is 1.
-	maxBarSize: 1
-});
-=====*/
-(function(){
-	var df = dojox.lang.functional, du = dojox.lang.utils,
-		dc = dojox.charting.plot2d.common,
-		purgeGroup = df.lambda("item.purgeGroup()");
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "./Base", "./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){
+		
+	/*=====
+	dojo.declare("dojox.charting.plot2d.__BarCtorArgs", dojox.charting.plot2d.__DefaultCtorArgs, {
+		//	summary:
+		//		Additional keyword arguments for bar charts.
+	
+		//	minBarSize: Number?
+		//		The minimum size for a bar in pixels.  Default is 1.
+		minBarSize: 1,
+	
+		//	maxBarSize: Number?
+		//		The maximum size for a bar in pixels.  Default is 1.
+		maxBarSize: 1,
+		
+		//	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()");
 
-	dojo.declare("dojox.charting.plot2d.Bars", dojox.charting.plot2d.Base, {
+	return declare("dojox.charting.plot2d.Bars", Base, {
 		//	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
+			animate: null,   // animate bars into place
+			enableCache: false
 		},
 		optionalParams: {
 			minBarSize:	1,	// minimal bar width in pixels
@@ -50,11 +49,11 @@ dojo.declare("dojox.charting.plot2d.__BarCtorArgs", dojox.charting.plot2d.__Defa
 		constructor: function(chart, kwArgs){
 			//	summary:
 			//		The constructor for a bar chart.
-			//	chart: dojox.charting.Chart2D
+			//	chart: dojox.charting.Chart
 			//		The chart this plot belongs to.
 			//	kwArgs: dojox.charting.plot2d.__BarCtorArgs?
 			//		An optional keyword arguments object to help define the plot.
-			this.opt = dojo.clone(this.defaultParams);
+			this.opt = lang.clone(this.defaultParams);
 			du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
 			this.series = [];
@@ -75,6 +74,22 @@ dojo.declare("dojox.charting.plot2d.__BarCtorArgs", dojox.charting.plot2d.__Defa
 			t = stats.hmax, stats.hmax = stats.vmax, stats.vmax = t;
 			return stats;
 		},
+		
+		createRect: function(run, creator, params){
+			var rect;
+			if(this.opt.enableCache && run._rectFreePool.length > 0){
+				rect = run._rectFreePool.pop();
+				rect.setShape(params);
+				// was cleared, add it back
+				creator.add(rect);
+			}else{
+				rect = creator.createRect(params);
+			}
+			if(this.opt.enableCache){
+				run._rectUsePool.push(rect);
+			}
+			return rect;
+		},
 
 		render: function(dim, offsets){
 			//	summary:
@@ -91,7 +106,7 @@ dojo.declare("dojox.charting.plot2d.__BarCtorArgs", dojox.charting.plot2d.__Defa
 			this.dirty = this.isDirty();
 			this.resetEvents();
 			if(this.dirty){
-				dojo.forEach(this.series, purgeGroup);
+				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
 				var s = this.group;
@@ -114,6 +129,10 @@ dojo.declare("dojox.charting.plot2d.__BarCtorArgs", dojox.charting.plot2d.__Defa
 					continue;
 				}
 				run.cleanGroup();
+				if(this.opt.enableCache){
+					run._rectFreePool = (run._rectFreePool?run._rectFreePool:[]).concat(run._rectUsePool?run._rectUsePool:[]);
+					run._rectUsePool = [];
+				}
 				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){
@@ -126,7 +145,7 @@ dojo.declare("dojox.charting.plot2d.__BarCtorArgs", dojox.charting.plot2d.__Defa
 							finalTheme = typeof value != "number" ?
 								t.addMixin(theme, "bar", value, true) :
 								t.post(theme, "bar");
-						if(w >= 1 && height >= 1){
+						if(w >= 0 && height >= 1){
 							var rect = {
 								x: offsets.l + (v < baseline ? hv : baselineWidth),
 								y: dim.height - offsets.b - vt(j + 1.5) + gap,
@@ -134,7 +153,7 @@ dojo.declare("dojox.charting.plot2d.__BarCtorArgs", dojox.charting.plot2d.__Defa
 							};
 							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);
+							var shape = this.createRect(run, s, rect).setFill(specialFill).setStroke(finalTheme.series.stroke);
 							run.dyn.fill   = shape.getFill();
 							run.dyn.stroke = shape.getStroke();
 							if(events){
@@ -162,7 +181,7 @@ dojo.declare("dojox.charting.plot2d.__BarCtorArgs", dojox.charting.plot2d.__Defa
 			return this;	//	dojox.charting.plot2d.Bars
 		},
 		_animateBar: function(shape, hoffset, hsize){
-			dojox.gfx.fx.animateTransform(dojo.delegate({
+			fx.animateTransform(lang.delegate({
 				shape: shape,
 				duration: 1200,
 				transform: [
@@ -173,4 +192,4 @@ dojo.declare("dojox.charting.plot2d.__BarCtorArgs", dojox.charting.plot2d.__Defa
 			}, this.animate)).play();
 		}
 	});
-})();
+});
diff --git a/dojox/charting/plot2d/Base.js b/dojox/charting/plot2d/Base.js
index b17fffb..87e1674 100644
--- a/dojox/charting/plot2d/Base.js
+++ b/dojox/charting/plot2d/Base.js
@@ -1,11 +1,10 @@
-dojo.provide("dojox.charting.plot2d.Base");
-
-dojo.require("dojox.charting.scaler.primitive");
-dojo.require("dojox.charting.Element");
-dojo.require("dojox.charting.plot2d.common");
-dojo.require("dojox.charting.plot2d._PlotEvents");
-
+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){
 /*=====
+var Element = dojox.charting.Element;
+var PlotEvents = dojox.charting.plot2d._PlotEvents;
 dojox.charting.plot2d.__PlotCtorArgs = function(){
 	//	summary:
 	//		The base keyword arguments object for plot constructors.
@@ -14,11 +13,11 @@ dojox.charting.plot2d.__PlotCtorArgs = function(){
 	//		details).
 }
 =====*/
-dojo.declare("dojox.charting.plot2d.Base", [dojox.charting.Element, dojox.charting.plot2d._PlotEvents], {
+return declare("dojox.charting.plot2d.Base", [Element, PlotEvents], {
 	constructor: function(chart, kwArgs){
 		//	summary:
 		//		Create a base plot for charting.
-		//	chart: dojox.chart.Chart2D
+		//	chart: dojox.chart.Chart
 		//		The chart this plot belongs to.
 		//	kwArgs: dojox.charting.plot2d.__PlotCtorArgs?
 		//		An optional arguments object to help define the plot.
@@ -49,6 +48,58 @@ dojo.declare("dojox.charting.plot2d.Base", [dojox.charting.Element, dojox.charti
 		}
 		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.
@@ -64,7 +115,7 @@ dojo.declare("dojox.charting.plot2d.Base", [dojox.charting.Element, dojox.charti
 		//		Calculate the min/max on all attached series in both directions.
 		//	returns: Object
 		//		{hmin, hmax, vmin, vmax} min/max in both directions.
-		return dojox.charting.plot2d.common.collectSimpleStats(this.series);
+		return common.collectSimpleStats(this.series);
 	},
 	calculateAxes: function(dim){
 		//	summary:
@@ -88,7 +139,7 @@ dojo.declare("dojox.charting.plot2d.Base", [dojox.charting.Element, dojox.charti
 		//		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 dojo.some(this.series, function(item){ return item.dirty; });	//	Boolean
+		return arr.some(this.series, function(item){ return item.dirty; });	//	Boolean
 	},
 	performZoom: function(dim, offsets){
 		//	summary:
@@ -107,7 +158,7 @@ dojo.declare("dojox.charting.plot2d.Base", [dojox.charting.Element, dojox.charti
 			hBounds = this._hScaler.bounds,
 			xOffset = (hBounds.from - hBounds.lower) * hBounds.scale,
 			vBounds = this._vScaler.bounds,
-			yOffset = (vBounds.from - vBounds.lower) * vBounds.scale;
+			yOffset = (vBounds.from - vBounds.lower) * vBounds.scale,
 			// get incremental zooming various
 			rVScale = vs / this.lastWindow.vscale,
 			rHScale = hs / this.lastWindow.hscale,
@@ -117,7 +168,7 @@ dojo.declare("dojox.charting.plot2d.Base", [dojox.charting.Element, dojox.charti
 				((this.lastWindow.vscale == 1)? vs : this.lastWindow.vscale),
 
 			shape = this.group,
-			anim = dojox.gfx.fx.animateTransform(dojo.delegate({
+			anim = fx.animateTransform(lang.delegate({
 				shape: shape,
 				duration: 1200,
 				transform:[
@@ -127,12 +178,12 @@ dojo.declare("dojox.charting.plot2d.Base", [dojox.charting.Element, dojox.charti
 					{name:"translate", start: [0, 0], end: [rXOffset, rYOffset]}
 				]}, this.zoom));
 
-		dojo.mixin(this.lastWindow, {vscale: vs, hscale: hs, xoffset: xOffset, yoffset: yOffset});
+		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
-		dojo.connect(anim, "onEnd", this, function(){
+		hub.connect(anim, "onEnd", this, function(){
 			this.zoom = null;
 			this.zoomQueue.shift();
 			if(this.zoomQueue.length > 0){
@@ -177,7 +228,7 @@ dojo.declare("dojox.charting.plot2d.Base", [dojox.charting.Element, dojox.charti
 			}
 			this._hScaler = this._hAxis.getScaler();
 		}else{
-			this._hScaler = dojox.charting.scaler.primitive.buildScaler(stats.hmin, stats.hmax, dim.width);
+			this._hScaler = primitive.buildScaler(stats.hmin, stats.hmax, dim.width);
 		}
 		if(this._vAxis){
 			if(!this._vAxis.initialized()){
@@ -185,8 +236,9 @@ dojo.declare("dojox.charting.plot2d.Base", [dojox.charting.Element, dojox.charti
 			}
 			this._vScaler = this._vAxis.getScaler();
 		}else{
-			this._vScaler = dojox.charting.scaler.primitive.buildScaler(stats.vmin, stats.vmax, dim.height);
+			this._vScaler = primitive.buildScaler(stats.vmin, stats.vmax, dim.height);
 		}
 		return this;	//	dojox.charting.plot2d.Base
 	}
 });
+});
diff --git a/dojox/charting/plot2d/Bubble.js b/dojox/charting/plot2d/Bubble.js
index 5fa613b..ae7ce3b 100644
--- a/dojox/charting/plot2d/Bubble.js
+++ b/dojox/charting/plot2d/Bubble.js
@@ -1,14 +1,14 @@
-dojo.provide("dojox.charting.plot2d.Bubble");
+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){
+/*=====
+var Base = dojox.charting.plot2d.Base;
+=====*/
 
-dojo.require("dojox.charting.plot2d.Base");
-dojo.require("dojox.lang.functional");
+	var purgeGroup = dfr.lambda("item.purgeGroup()");
 
-(function(){
-	var df = dojox.lang.functional, du = dojox.lang.utils,
-		dc = dojox.charting.plot2d.common,
-		purgeGroup = df.lambda("item.purgeGroup()");
-
-	dojo.declare("dojox.charting.plot2d.Bubble", dojox.charting.plot2d.Base, {
+	return declare("dojox.charting.plot2d.Bubble", Base, {
 		//	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.
@@ -30,11 +30,11 @@ dojo.require("dojox.lang.functional");
 		constructor: function(chart, kwArgs){
 			//	summary:
 			//		Create a plot of bubbles.
-			//	chart: dojox.charting.Chart2D
+			//	chart: dojox.charting.Chart
 			//		The chart this plot belongs to.
 			//	kwArgs: dojox.charting.plot2d.__DefaultCtorArgs?
 			//		Optional keyword arguments object to help define plot parameters.
-			this.opt = dojo.clone(this.defaultParams);
+			this.opt = lang.clone(this.defaultParams);
             du.updateWithObject(this.opt, kwArgs);
             du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
             this.series = [];
@@ -59,7 +59,7 @@ dojo.require("dojox.lang.functional");
 			this.resetEvents();
 			this.dirty = this.isDirty();
 			if(this.dirty){
-				dojo.forEach(this.series, purgeGroup);
+				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
 				var s = this.group;
@@ -91,7 +91,7 @@ dojo.require("dojox.lang.functional");
 				}
 
 				var theme = t.next("circle", [this.opt, run]), s = run.group,
-					points = dojo.map(run.data, function(v, i){
+					points = arr.map(run.data, function(v, i){
 						return v ? {
 							x: ht(v.x) + offsets.l,
 							y: dim.height - offsets.b - vt(v.y),
@@ -103,7 +103,7 @@ dojo.require("dojox.lang.functional");
 
 				// make shadows if needed
 				if(theme.series.shadow){
-					shadowCircles = dojo.map(points, function(item){
+					shadowCircles = arr.map(points, function(item){
 						if(item !== null){
 							var finalTheme = t.addMixin(theme, "circle", item, true),
 								shadow = finalTheme.series.shadow;
@@ -124,7 +124,7 @@ dojo.require("dojox.lang.functional");
 
 				// make outlines if needed
 				if(theme.series.outline){
-					outlineCircles = dojo.map(points, function(item){
+					outlineCircles = arr.map(points, function(item){
 						if(item !== null){
 							var finalTheme = t.addMixin(theme, "circle", item, true),
 								outline = dc.makeStroke(finalTheme.series.outline);
@@ -145,7 +145,7 @@ dojo.require("dojox.lang.functional");
 				}
 
 				//	run through the data and add the circles.
-				frontCircles = dojo.map(points, function(item){
+				frontCircles = arr.map(points, function(item){
 					if(item !== null){
 						var finalTheme = t.addMixin(theme, "circle", item, true),
 							rect = {
@@ -173,7 +173,7 @@ dojo.require("dojox.lang.functional");
 
 				if(events){
 					var eventSeries = new Array(frontCircles.length);
-					dojo.forEach(frontCircles, function(s, i){
+					arr.forEach(frontCircles, function(s, i){
 						if(s !== null){
 							var o = {
 								element: "circle",
@@ -204,7 +204,7 @@ dojo.require("dojox.lang.functional");
 			return this;	//	dojox.charting.plot2d.Bubble
 		},
 		_animateBubble: function(shape, offset, size){
-			dojox.gfx.fx.animateTransform(dojo.delegate({
+			fx.animateTransform(lang.delegate({
 				shape: shape,
 				duration: 1200,
 				transform: [
@@ -215,4 +215,4 @@ dojo.require("dojox.lang.functional");
 			}, this.animate)).play();
 		}
 	});
-})();
+});
diff --git a/dojox/charting/plot2d/Candlesticks.js b/dojox/charting/plot2d/Candlesticks.js
index 8e000a6..0235679 100644
--- a/dojox/charting/plot2d/Candlesticks.js
+++ b/dojox/charting/plot2d/Candlesticks.js
@@ -1,23 +1,18 @@
-dojo.provide("dojox.charting.plot2d.Candlesticks");
+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){
+/*=====
+var Base = dojox.charting.plot2d.Base;
+=====*/
 
-dojo.require("dojox.charting.plot2d.common");
-dojo.require("dojox.charting.plot2d.Base");
-
-dojo.require("dojox.lang.utils");
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.functional.reversed");
-
-(function(){
-	var df = dojox.lang.functional, du = dojox.lang.utils,
-		dc = dojox.charting.plot2d.common,
-		purgeGroup = df.lambda("item.purgeGroup()");
+	var purgeGroup = dfr.lambda("item.purgeGroup()");
 
 	//	Candlesticks are based on the Bars plot type; we expect the following passed
 	//	as values in a series:
 	//	{ 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.
-	dojo.declare("dojox.charting.plot2d.Candlesticks", dojox.charting.plot2d.Base, {
+	return declare("dojox.charting.plot2d.Candlesticks", Base, {
 		//	summary:
 		//		A plot that represents typical candlesticks (financial reporting, primarily).
 		//		Unlike most charts, the Candlestick expects data points to be represented by
@@ -45,11 +40,11 @@ dojo.require("dojox.lang.functional.reversed");
 		constructor: function(chart, kwArgs){
 			//	summary:
 			//		The constructor for a candlestick chart.
-			//	chart: dojox.charting.Chart2D
+			//	chart: dojox.charting.Chart
 			//		The chart this plot belongs to.
 			//	kwArgs: dojox.charting.plot2d.__BarCtorArgs?
 			//		An optional keyword arguments object to help define the plot.
-			this.opt = dojo.clone(this.defaultParams);
+			this.opt = lang.clone(this.defaultParams);
 			du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
 			this.series = [];
@@ -70,13 +65,13 @@ dojo.require("dojox.lang.functional.reversed");
 
 			//	we have to roll our own, since we need to use all four passed
 			//	values to figure out our stats, and common only assumes x and y.
-			var stats = dojo.delegate(dc.defaultStats);
+			var stats = lang.delegate(dc.defaultStats);
 			for(var i=0; i<series.length; i++){
 				var run = series[i];
 				if(!run.data.length){ continue; }
 				var old_vmin = stats.vmin, old_vmax = stats.vmax;
 				if(!("ymin" in run) || !("ymax" in run)){
-					dojo.forEach(run.data, function(val, idx){
+					arr.forEach(run.data, function(val, idx){
 						if(val !== null){
 							var x = val.x || idx + 1;
 							stats.hmin = Math.min(stats.hmin, x);
@@ -118,7 +113,7 @@ dojo.require("dojox.lang.functional.reversed");
 			this.resetEvents();
 			this.dirty = this.isDirty();
 			if(this.dirty){
-				dojo.forEach(this.series, purgeGroup);
+				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
 				var s = this.group;
@@ -172,7 +167,7 @@ dojo.require("dojox.lang.functional.reversed");
 									x: 0, y: y-Math.max(open, close),
 									width: width, height: Math.max(doFill ? open-close : close-open, 1)
 								};
-							shape = s.createGroup();
+							var shape = s.createGroup();
 							shape.setTransform({dx: x, dy: 0 });
 							var inner = shape.createGroup();
 							inner.createLine(line).setStroke(finalTheme.series.stroke);
@@ -219,7 +214,7 @@ dojo.require("dojox.lang.functional.reversed");
 			return this;	//	dojox.charting.plot2d.Candlesticks
 		},
 		_animateCandlesticks: function(shape, voffset, vsize){
-			dojox.gfx.fx.animateTransform(dojo.delegate({
+			fx.animateTransform(lang.delegate({
 				shape: shape,
 				duration: 1200,
 				transform: [
@@ -230,4 +225,4 @@ dojo.require("dojox.lang.functional.reversed");
 			}, this.animate)).play();
 		}
 	});
-})();
+});
diff --git a/dojox/charting/plot2d/ClusteredBars.js b/dojox/charting/plot2d/ClusteredBars.js
index ced6f4b..2074a41 100644
--- a/dojox/charting/plot2d/ClusteredBars.js
+++ b/dojox/charting/plot2d/ClusteredBars.js
@@ -1,16 +1,13 @@
-dojo.provide("dojox.charting.plot2d.ClusteredBars");
+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;
+=====*/
 
-dojo.require("dojox.charting.plot2d.common");
-dojo.require("dojox.charting.plot2d.Bars");
+	var purgeGroup = dfr.lambda("item.purgeGroup()");
 
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.functional.reversed");
-
-(function(){
-	var df = dojox.lang.functional, dc = dojox.charting.plot2d.common,
-		purgeGroup = df.lambda("item.purgeGroup()");
-
-	dojo.declare("dojox.charting.plot2d.ClusteredBars", dojox.charting.plot2d.Bars, {
+	return declare("dojox.charting.plot2d.ClusteredBars", Bars, {
 		//	summary:
 		//		A plot representing grouped or clustered bars (horizontal bars)
 		render: function(dim, offsets){
@@ -28,7 +25,7 @@ dojo.require("dojox.lang.functional.reversed");
 			this.resetEvents();
 			this.dirty = this.isDirty();
 			if(this.dirty){
-				dojo.forEach(this.series, purgeGroup);
+				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
 				var s = this.group;
@@ -63,7 +60,7 @@ dojo.require("dojox.lang.functional.reversed");
 							finalTheme = typeof value != "number" ?
 								t.addMixin(theme, "bar", value, true) :
 								t.post(theme, "bar");
-						if(w >= 1 && height >= 1){
+						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,
@@ -99,4 +96,4 @@ dojo.require("dojox.lang.functional.reversed");
 			return this;	//	dojox.charting.plot2d.ClusteredBars
 		}
 	});
-})();
+});
diff --git a/dojox/charting/plot2d/ClusteredColumns.js b/dojox/charting/plot2d/ClusteredColumns.js
index 8c19146..a5ceadb 100644
--- a/dojox/charting/plot2d/ClusteredColumns.js
+++ b/dojox/charting/plot2d/ClusteredColumns.js
@@ -1,16 +1,13 @@
-dojo.provide("dojox.charting.plot2d.ClusteredColumns");
+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;
+=====*/
 
-dojo.require("dojox.charting.plot2d.common");
-dojo.require("dojox.charting.plot2d.Columns");
+	var purgeGroup = dfr.lambda("item.purgeGroup()");
 
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.functional.reversed");
-
-(function(){
-	var df = dojox.lang.functional, dc = dojox.charting.plot2d.common,
-		purgeGroup = df.lambda("item.purgeGroup()");
-
-	dojo.declare("dojox.charting.plot2d.ClusteredColumns", dojox.charting.plot2d.Columns, {
+	return declare("dojox.charting.plot2d.ClusteredColumns", Columns, {
 		//	summary:
 		//		A plot representing grouped or clustered columns (vertical bars).
 		render: function(dim, offsets){
@@ -28,7 +25,7 @@ dojo.require("dojox.lang.functional.reversed");
 			this.resetEvents();
 			this.dirty = this.isDirty();
 			if(this.dirty){
-				dojo.forEach(this.series, purgeGroup);
+				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
 				var s = this.group;
@@ -63,7 +60,7 @@ dojo.require("dojox.lang.functional.reversed");
 							finalTheme = typeof value != "number" ?
 								t.addMixin(theme, "column", value, true) :
 								t.post(theme, "column");
-						if(width >= 1 && h >= 1){
+						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),
@@ -99,4 +96,4 @@ dojo.require("dojox.lang.functional.reversed");
 			return this;	//	dojox.charting.plot2d.ClusteredColumns
 		}
 	});
-})();
+});
diff --git a/dojox/charting/plot2d/Columns.js b/dojox/charting/plot2d/Columns.js
index c636689..462a24c 100644
--- a/dojox/charting/plot2d/Columns.js
+++ b/dojox/charting/plot2d/Columns.js
@@ -1,26 +1,21 @@
-dojo.provide("dojox.charting.plot2d.Columns");
+define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "./Base", "./common", 
+		"dojox/lang/functional", "dojox/lang/functional/reversed", "dojox/lang/utils", "dojox/gfx/fx"], 
+	function(lang, arr, declare, Base, dc, df, dfr, du, fx){
 
-dojo.require("dojox.charting.plot2d.common");
-dojo.require("dojox.charting.plot2d.Base");
-dojo.require("dojox.gfx.fx");
+	var purgeGroup = dfr.lambda("item.purgeGroup()");
+/*=====
+var Base = dojox.charting.plot2d.Base;
+=====*/
 
-dojo.require("dojox.lang.utils");
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.functional.reversed");
-
-(function(){
-	var df = dojox.lang.functional, du = dojox.lang.utils,
-		dc = dojox.charting.plot2d.common,
-		purgeGroup = df.lambda("item.purgeGroup()");
-
-	dojo.declare("dojox.charting.plot2d.Columns", dojox.charting.plot2d.Base, {
+	return declare("dojox.charting.plot2d.Columns", Base, {
 		//	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
+			animate: null,  // animate bars into place
+			enableCache: false
 		},
 		optionalParams: {
 			minBarSize:	1,	// minimal column width in pixels
@@ -37,11 +32,11 @@ dojo.require("dojox.lang.functional.reversed");
 		constructor: function(chart, kwArgs){
 			//	summary:
 			//		The constructor for a columns chart.
-			//	chart: dojox.charting.Chart2D
+			//	chart: dojox.charting.Chart
 			//		The chart this plot belongs to.
 			//	kwArgs: dojox.charting.plot2d.__BarCtorArgs?
 			//		An optional keyword arguments object to help define the plot.
-			this.opt = dojo.clone(this.defaultParams);
+			this.opt = lang.clone(this.defaultParams);
 			du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
 			this.series = [];
@@ -60,6 +55,22 @@ dojo.require("dojox.lang.functional.reversed");
 			stats.hmax += 0.5;
 			return stats;
 		},
+		
+		createRect: function(run, creator, params){
+			var rect;
+			if(this.opt.enableCache && run._rectFreePool.length > 0){
+				rect = run._rectFreePool.pop();
+				rect.setShape(params);
+				// was cleared, add it back
+				creator.add(rect);
+			}else{
+				rect = creator.createRect(params);
+			}
+			if(this.opt.enableCache){
+				run._rectUsePool.push(rect);
+			}
+			return rect;
+		},
 
 		render: function(dim, offsets){
 			//	summary:
@@ -73,10 +84,11 @@ dojo.require("dojox.lang.functional.reversed");
 			if(this.zoom && !this.isDataDirty()){
 				return this.performZoom(dim, offsets);
 			}
+			var t = this.getSeriesStats();
 			this.resetEvents();
 			this.dirty = this.isDirty();
 			if(this.dirty){
-				dojo.forEach(this.series, purgeGroup);
+				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
 				var s = this.group;
@@ -87,6 +99,7 @@ dojo.require("dojox.lang.functional.reversed");
 				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;
@@ -99,9 +112,14 @@ dojo.require("dojox.lang.functional.reversed");
 					continue;
 				}
 				run.cleanGroup();
+				if(this.opt.enableCache){
+					run._rectFreePool = (run._rectFreePool?run._rectFreePool:[]).concat(run._rectUsePool?run._rectUsePool:[]);
+					run._rectUsePool = [];
+				}
 				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 l = Math.min(run.data.length, max);
+				for(var j = min; j < l; ++j){
 					var value = run.data[j];
 					if(value !== null){
 						var v = typeof value == "number" ? value : value.y,
@@ -111,7 +129,7 @@ dojo.require("dojox.lang.functional.reversed");
 							finalTheme = typeof value != "number" ?
 								t.addMixin(theme, "column", value, true) :
 								t.post(theme, "column");
-						if(width >= 1 && h >= 1){
+						if(width >= 1 && h >= 0){
 							var rect = {
 								x: offsets.l + ht(j + 0.5) + gap,
 								y: dim.height - offsets.b - (v > baseline ? vv : baselineHeight),
@@ -119,7 +137,7 @@ dojo.require("dojox.lang.functional.reversed");
 							};
 							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);
+							var shape = this.createRect(run, s, rect).setFill(specialFill).setStroke(finalTheme.series.stroke);
 							run.dyn.fill   = shape.getFill();
 							run.dyn.stroke = shape.getStroke();
 							if(events){
@@ -147,7 +165,7 @@ dojo.require("dojox.lang.functional.reversed");
 			return this;	//	dojox.charting.plot2d.Columns
 		},
 		_animateColumn: function(shape, voffset, vsize){
-			dojox.gfx.fx.animateTransform(dojo.delegate({
+			fx.animateTransform(lang.delegate({
 				shape: shape,
 				duration: 1200,
 				transform: [
@@ -158,4 +176,4 @@ dojo.require("dojox.lang.functional.reversed");
 			}, this.animate)).play();
 		}
 	});
-})();
+});
diff --git a/dojox/charting/plot2d/Default.js b/dojox/charting/plot2d/Default.js
index a965161..cdaedf2 100644
--- a/dojox/charting/plot2d/Default.js
+++ b/dojox/charting/plot2d/Default.js
@@ -1,106 +1,105 @@
-dojo.provide("dojox.charting.plot2d.Default");
-
-dojo.require("dojox.charting.plot2d.common");
-dojo.require("dojox.charting.plot2d.Base");
-
-dojo.require("dojox.lang.utils");
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.functional.reversed");
-dojo.require("dojox.gfx.fx");
-
-/*=====
-dojo.declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__PlotCtorArgs, {
-	//	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?
-	//		Whether or not to draw lines on this plot.  Defaults to true.
-	lines:   true,
-
-	//	areas: Boolean?
-	//		Whether or not to draw areas on this plot. Defaults to false.
-	areas:   false,
-
-	//	markers: Boolean?
-	//		Whether or not to draw markers at data points on this plot. Default is false.
-	markers: false,
-
-	//	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: false,
-
-	//	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 (such as areas).
-	fill:		{},
-
-	//	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:	"",
-
-	//	markerStroke: dojo.gfx.Stroke?
-	//		An optional stroke to use for any markers on the plot.
-	markerStroke:		{},
-
-	//	markerOutline: dojo.gfx.Stroke?
-	//		An optional outline to use for any markers on the plot.
-	markerOutline:		{},
-
-	//	markerShadow: dojo.gfx.Stroke?
-	//		An optional shadow to use for any markers on the plot.
-	markerShadow:		{},
-
-	//	markerFill: dojo.gfx.Fill?
-	//		An optional fill to use for any markers on the plot.
-	markerFill:			{},
-
-	//	markerFont: String?
-	//		An optional font definition to use for any markers on the plot.
-	markerFont:			"",
-
-	//	markerFontColor: String|dojo.Color?
-	//		An optional color to use for any marker text on the plot.
-	markerFontColor:	""
-});
+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){
+
+	/*=====
+	dojo.declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__PlotCtorArgs, {
+		//	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?
+		//		Whether or not to draw lines on this plot.  Defaults to true.
+		lines:   true,
+	
+		//	areas: Boolean?
+		//		Whether or not to draw areas on this plot. Defaults to false.
+		areas:   false,
+	
+		//	markers: Boolean?
+		//		Whether or not to draw markers at data points on this plot. Default is false.
+		markers: false,
+	
+		//	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: false,
+	
+		//	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 (such as areas).
+		fill:		{},
+	
+		//	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:	"",
+	
+		//	markerStroke: dojo.gfx.Stroke?
+		//		An optional stroke to use for any markers on the plot.
+		markerStroke:		{},
+	
+		//	markerOutline: dojo.gfx.Stroke?
+		//		An optional outline to use for any markers on the plot.
+		markerOutline:		{},
+	
+		//	markerShadow: dojo.gfx.Stroke?
+		//		An optional shadow to use for any markers on the plot.
+		markerShadow:		{},
+	
+		//	markerFill: dojo.gfx.Fill?
+		//		An optional fill to use for any markers on the plot.
+		markerFill:			{},
+	
+		//	markerFont: String?
+		//		An optional font definition to use for any markers on the plot.
+		markerFont:			"",
+	
+		//	markerFontColor: String|dojo.Color?
+		//		An optional color to use for any marker text on the plot.
+		markerFontColor:	"",
+		
+		//	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
+	});
+	
+	var Base = dojox.charting.plot2d.Base;
 =====*/
-(function(){
-	var df = dojox.lang.functional, du = dojox.lang.utils,
-		dc = dojox.charting.plot2d.common,
-		purgeGroup = df.lambda("item.purgeGroup()");
+
+	var purgeGroup = dfr.lambda("item.purgeGroup()");
 
 	var DEFAULT_ANIMATION_LENGTH = 1200;	// in ms
 
-	dojo.declare("dojox.charting.plot2d.Default", dojox.charting.plot2d.Base, {
+	return declare("dojox.charting.plot2d.Default", Base, {
 		defaultParams: {
 			hAxis: "x",		// use a horizontal axis named "x"
 			vAxis: "y",		// use a vertical axis named "y"
@@ -108,7 +107,8 @@ dojo.declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__
 			areas:   false,	// draw areas
 			markers: false,	// draw markers
 			tension: "",	// draw curved lines (tension is "X", "x", or "S")
-			animate: false	// animate chart to place
+			animate: false, // animate chart to place
+			enableCache: false 
 		},
 		optionalParams: {
 			// theme component
@@ -129,11 +129,11 @@ dojo.declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__
 		constructor: function(chart, kwArgs){
 			//	summary:
 			//		Return a new plot.
-			//	chart: dojox.charting.Chart2D
+			//	chart: dojox.charting.Chart
 			//		The chart this plot belongs to.
 			//	kwArgs: dojox.charting.plot2d.__DefaultCtorArgs?
 			//		An optional arguments object to help define this plot.
-			this.opt = dojo.clone(this.defaultParams);
+			this.opt = lang.clone(this.defaultParams);
             du.updateWithObject(this.opt, kwArgs);
             du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
 			this.series = [];
@@ -144,6 +144,22 @@ dojo.declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__
 			this.animate = this.opt.animate;
 		},
 
+		createPath: function(run, creator, params){
+			var path;
+			if(this.opt.enableCache && run._pathFreePool.length > 0){
+				path = run._pathFreePool.pop();
+				path.setShape(params);
+				// was cleared, add it back
+				creator.add(path);
+			}else{
+				path = creator.createPath(params);
+			}
+			if(this.opt.enableCache){
+				run._pathUsePool.push(path);
+			}
+			return path;
+		},
+
 		render: function(dim, offsets){
 			//	summary:
 			//		Render/draw everything on this plot.
@@ -162,7 +178,7 @@ dojo.declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__
 			this.resetEvents();
 			this.dirty = this.isDirty();
 			if(this.dirty){
-				dojo.forEach(this.series, purgeGroup);
+				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
 				this.group.setTransform(null);
@@ -179,6 +195,10 @@ dojo.declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__
 					continue;
 				}
 				run.cleanGroup();
+				if(this.opt.enableCache){
+					run._pathFreePool = (run._pathFreePool?run._pathFreePool:[]).concat(run._pathUsePool?run._pathUsePool:[]);
+					run._pathUsePool = [];
+				}
 				if(!run.data.length){
 					run.dirty = false;
 					t.skip();
@@ -190,14 +210,19 @@ dojo.declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__
 					ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
 					vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
 					eventSeries = this._eventSeries[run.name] = new Array(run.data.length);
+				
+				// 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 = 0; j < run.data.length; j++){
+                for(var j = min; j < max; j++){
                     if(run.data[j] != null){
                         if(!rseg){
                             rseg = [];
                             startindexes.push(j);
-                            rsegments.push(rseg)
+                            rsegments.push(rseg);
                         }
                         rseg.push(run.data[j]);
                     }else{
@@ -207,14 +232,14 @@ dojo.declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__
 
                 for(var seg = 0; seg < rsegments.length; seg++){
 					if(typeof rsegments[seg][0] == "number"){
-						lpoly = dojo.map(rsegments[seg], function(v, i){
+						lpoly = arr.map(rsegments[seg], function(v, i){
 							return {
 								x: ht(i + startindexes[seg] + 1) + offsets.l,
 								y: dim.height - offsets.b - vt(v)
 							};
 						}, this);
 					}else{
-						lpoly = dojo.map(rsegments[seg], function(v, i){
+						lpoly = arr.map(rsegments[seg], function(v, i){
 							return {
 								x: ht(v.x) + offsets.l,
 								y: dim.height - offsets.b - vt(v.y)
@@ -226,7 +251,7 @@ dojo.declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__
 
 					if(this.opt.areas && lpoly.length > 1){
 						var fill = theme.series.fill;
-						var apoly = dojo.clone(lpoly);
+						var 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) +
@@ -253,7 +278,7 @@ dojo.declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__
 					var frontMarkers = null, outlineMarkers = null, shadowMarkers = null;
 					if(stroke && theme.series.shadow && lpoly.length > 1){
 						var shadow = theme.series.shadow,
-							spoly = dojo.map(lpoly, function(c){
+							spoly = arr.map(lpoly, function(c){
 								return {x: c.x + shadow.dx, y: c.y + shadow.dy};
 							});
 						if(this.opt.lines){
@@ -265,8 +290,8 @@ dojo.declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__
 						}
 						if(this.opt.markers && theme.marker.shadow){
 							shadow = theme.marker.shadow;
-							shadowMarkers = dojo.map(spoly, function(c){
-								return s.createPath("M" + c.x + " " + c.y + " " + theme.symbol).
+							shadowMarkers = arr.map(spoly, function(c){
+								return this.createPath(run, s, "M" + c.x + " " + c.y + " " + theme.symbol).
 									setStroke(shadow).setFill(shadow.color);
 							}, this);
 						}
@@ -293,17 +318,17 @@ dojo.declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__
 							outline = dc.makeStroke(theme.marker.outline);
 							outline.width = 2 * outline.width + (theme.marker.stroke ? theme.marker.stroke.width : 0);
 						}
-						dojo.forEach(lpoly, function(c, i){
+						arr.forEach(lpoly, function(c, i){
 							var path = "M" + c.x + " " + c.y + " " + theme.symbol;
 							if(outline){
-								outlineMarkers[i] = s.createPath(path).setStroke(outline);
+								outlineMarkers[i] = this.createPath(run, s, path).setStroke(outline);
 							}
-							frontMarkers[i] = s.createPath(path).setStroke(theme.marker.stroke).setFill(theme.marker.fill);
+							frontMarkers[i] = this.createPath(run, s, path).setStroke(theme.marker.stroke).setFill(theme.marker.fill);
 						}, this);
 						run.dyn.markerFill = theme.marker.fill;
 						run.dyn.markerStroke = theme.marker.stroke;
 						if(events){
-							dojo.forEach(frontMarkers, function(s, i){
+							arr.forEach(frontMarkers, function(s, i){
 								var o = {
 									element: "marker",
 									index:   i + startindexes[seg],
@@ -334,7 +359,7 @@ dojo.declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__
 			if(this.animate){
 				// grow from the bottom
 				var plotGroup = this.group;
-				dojox.gfx.fx.animateTransform(dojo.delegate({
+				fx.animateTransform(lang.delegate({
 					shape: plotGroup,
 					duration: DEFAULT_ANIMATION_LENGTH,
 					transform:[
@@ -348,4 +373,4 @@ dojo.declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__
 			return this;	//	dojox.charting.plot2d.Default
 		}
 	});
-})();
+});
diff --git a/dojox/charting/plot2d/Grid.js b/dojox/charting/plot2d/Grid.js
index 928d38a..154e164 100644
--- a/dojox/charting/plot2d/Grid.js
+++ b/dojox/charting/plot2d/Grid.js
@@ -1,44 +1,45 @@
-dojo.provide("dojox.charting.plot2d.Grid");
+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){
 
-dojo.require("dojox.charting.Element");
-dojo.require("dojox.charting.plot2d.common");
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.utils");
-
-/*=====
-dojo.declare("dojox.charting.plot2d.__GridCtorArgs", dojox.charting.plot2d.__DefaultCtorArgs, {
-	//	summary:
-	//		A special keyword arguments object that is specific to a grid "plot".
-
-	//	hMajorLines: Boolean?
-	//		Whether to show lines at the major ticks along the horizontal axis. Default is true.
-	hMajorLines: true,
-
-	//	hMinorLines: Boolean?
-	//		Whether to show lines at the minor ticks along the horizontal axis. Default is false.
-	hMinorLines: false,
-
-	//	vMajorLines: Boolean?
-	//		Whether to show lines at the major ticks along the vertical axis. Default is true.
-	vMajorLines: true,
-
-	//	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"
-});
-=====*/
-(function(){
-	var du = dojox.lang.utils, dc = dojox.charting.plot2d.common;
+	/*=====
+	dojo.declare("dojox.charting.plot2d.__GridCtorArgs", dojox.charting.plot2d.__DefaultCtorArgs, {
+		//	summary:
+		//		A special keyword arguments object that is specific to a grid "plot".
+	
+		//	hMajorLines: Boolean?
+		//		Whether to show lines at the major ticks along the horizontal axis. Default is true.
+		hMajorLines: true,
+	
+		//	hMinorLines: Boolean?
+		//		Whether to show lines at the minor ticks along the horizontal axis. Default is false.
+		hMinorLines: false,
+	
+		//	vMajorLines: Boolean?
+		//		Whether to show lines at the major ticks along the vertical axis. Default is true.
+		vMajorLines: true,
+	
+		//	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?
+		//		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
+	});
+	var Element = dojox.charting.plot2d.Element;
+	=====*/
 
-	dojo.declare("dojox.charting.plot2d.Grid", dojox.charting.Element, {
+	return declare("dojox.charting.plot2d.Grid", Element, {
 		//	summary:
 		//		A "faux" plot that can be placed behind other plots to represent
 		//		a grid against which other plots can be easily measured.
@@ -51,18 +52,19 @@ dojo.declare("dojox.charting.plot2d.__GridCtorArgs", dojox.charting.plot2d.__Def
 			vMinorLines: false,	// draw vertical minor lines
 			hStripes: "none",	// TBD
 			vStripes: "none",	// TBD
-			animate: null   // animate bars into place
+			animate: null,   // animate bars into place
+			enableCache: false
 		},
 		optionalParams: {},	// no optional parameters
 
 		constructor: function(chart, kwArgs){
 			//	summary:
 			//		Create the faux Grid plot.
-			//	chart: dojox.charting.Chart2D
+			//	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 = dojo.clone(this.defaultParams);
+			this.opt = lang.clone(this.defaultParams);
 			du.updateWithObject(this.opt, kwArgs);
 			this.hAxis = this.opt.hAxis;
 			this.vAxis = this.opt.vAxis;
@@ -71,6 +73,10 @@ dojo.declare("dojox.charting.plot2d.__GridCtorArgs", dojox.charting.plot2d.__Def
 			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 = [];
+			}
 		},
 		clear: function(){
 			//	summary:
@@ -104,7 +110,7 @@ dojo.declare("dojox.charting.plot2d.__GridCtorArgs", dojox.charting.plot2d.__Def
 			//		Returns default stats (irrelevant for this type of plot).
 			//	returns: Object
 			//		{hmin, hmax, vmin, vmax} min/max in both directions.
-			return dojo.delegate(dc.defaultStats);
+			return lang.delegate(dc.defaultStats);
 		},
 		initializeScalers: function(){
 			//	summary:
@@ -135,7 +141,7 @@ dojo.declare("dojox.charting.plot2d.__GridCtorArgs", dojox.charting.plot2d.__Def
 				hBounds = this._hAxis.getScaler().bounds,
 				xOffset = (hBounds.from - hBounds.lower) * hBounds.scale,
 				vBounds = this._vAxis.getScaler().bounds,
-				yOffset = (vBounds.from - vBounds.lower) * vBounds.scale;
+				yOffset = (vBounds.from - vBounds.lower) * vBounds.scale,
 				// get incremental zooming various
 				rVScale = vs / this.lastWindow.vscale,
 				rHScale = hs / this.lastWindow.hscale,
@@ -145,7 +151,7 @@ dojo.declare("dojox.charting.plot2d.__GridCtorArgs", dojox.charting.plot2d.__Def
 					((this.lastWindow.vscale == 1)? vs : this.lastWindow.vscale),
 
 				shape = this.group,
-				anim = dojox.gfx.fx.animateTransform(dojo.delegate({
+				anim = fx.animateTransform(lang.delegate({
 					shape: shape,
 					duration: 1200,
 					transform:[
@@ -155,12 +161,12 @@ dojo.declare("dojox.charting.plot2d.__GridCtorArgs", dojox.charting.plot2d.__Def
 						{name:"translate", start: [0, 0], end: [rXOffset, rYOffset]}
 					]}, this.zoom));
 
-			dojo.mixin(this.lastWindow, {vscale: vs, hscale: hs, xoffset: xOffset, yoffset: yOffset});
+			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
-			dojo.connect(anim, "onEnd", this, function(){
+			hub.connect(anim, "onEnd", this, function(){
 				this.zoom = null;
 				this.zoomQueue.shift();
 				if(this.zoomQueue.length > 0){
@@ -179,6 +185,28 @@ dojo.declare("dojox.charting.plot2d.__GridCtorArgs", dojox.charting.plot2d.__Def
 			//		Returns 0, since there are no series associated with this plot type.
 			return 0;	//	Number
 		},
+		cleanGroup: function(){
+			this.inherited(arguments);
+			if(this.opt.enableCache){
+				this._lineFreePool = this._lineFreePool.concat(this._lineUsePool);
+				this._lineUsePool = [];
+			}
+		},
+		createLine: function(creator, params){
+			var line;
+			if(this.opt.enableCache && this._lineFreePool.length > 0){
+				line = this._lineFreePool.pop();
+				line.setShape(params);
+				// was cleared, add it back
+				creator.add(line);
+			}else{
+				line = creator.createLine(params);
+			}
+			if(this.opt.enableCache){
+				this._lineUsePool.push(line);
+			}
+			return line;
+		},
 		render: function(dim, offsets){
 			//	summary:
 			//		Render the plot on the chart.
@@ -200,33 +228,35 @@ dojo.declare("dojox.charting.plot2d.__GridCtorArgs", dojox.charting.plot2d.__Def
 				var vScaler = this._vAxis.getScaler(),
 					vt = vScaler.scaler.getTransformerFromModel(vScaler),
 					ticks = this._vAxis.getTicks();
-				if(this.opt.hMinorLines){
-					dojo.forEach(ticks.minor, function(tick){
-						var y = dim.height - offsets.b - vt(tick.value);
-						var hMinorLine = s.createLine({
-							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);
-				}
-				if(this.opt.hMajorLines){
-					dojo.forEach(ticks.major, function(tick){
-						var y = dim.height - offsets.b - vt(tick.value);
-						var hMajorLine = s.createLine({
-							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);
+				if(ticks != null){
+					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);
+					}
+					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);
+					}
 				}
 			}catch(e){
 				// squelch
@@ -236,33 +266,35 @@ dojo.declare("dojox.charting.plot2d.__GridCtorArgs", dojox.charting.plot2d.__Def
 				var hScaler = this._hAxis.getScaler(),
 					ht = hScaler.scaler.getTransformerFromModel(hScaler),
 					ticks = this._hAxis.getTicks();
-				if(ticks && this.opt.vMinorLines){
-					dojo.forEach(ticks.minor, function(tick){
-						var x = offsets.l + ht(tick.value);
-						var vMinorLine = s.createLine({
-							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);
-				}
-				if(ticks && this.opt.vMajorLines){
-					dojo.forEach(ticks.major, function(tick){
-						var x = offsets.l + ht(tick.value);
-						var vMajorLine = s.createLine({
-							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);
+				if(this != null){
+					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);
+					}
+					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);
+					}
 				}
 			}catch(e){
 				// squelch
@@ -273,7 +305,7 @@ dojo.declare("dojox.charting.plot2d.__GridCtorArgs", dojox.charting.plot2d.__Def
 		_animateGrid: function(shape, type, offset, size){
 			var transStart = type == "h" ? [offset, 0] : [0, offset];
 			var scaleStart = type == "h" ? [1/size, 1] : [1, 1/size];
-			dojox.gfx.fx.animateTransform(dojo.delegate({
+			fx.animateTransform(lang.delegate({
 				shape: shape,
 				duration: 1200,
 				transform: [
@@ -284,4 +316,4 @@ dojo.declare("dojox.charting.plot2d.__GridCtorArgs", dojox.charting.plot2d.__Def
 			}, this.animate)).play();
 		}
 	});
-})();
+});
diff --git a/dojox/charting/plot2d/Lines.js b/dojox/charting/plot2d/Lines.js
index 7d6c859..38f55a8 100644
--- a/dojox/charting/plot2d/Lines.js
+++ b/dojox/charting/plot2d/Lines.js
@@ -1,13 +1,14 @@
-dojo.provide("dojox.charting.plot2d.Lines");
-
-dojo.require("dojox.charting.plot2d.Default");
-
-dojo.declare("dojox.charting.plot2d.Lines", dojox.charting.plot2d.Default, {
-	//	summary:
-	//		A convenience constructor to create a typical line chart.
-	constructor: function(){
+define(["dojo/_base/declare", "./Default"], function(declare, Default){
+/*=====
+var Default = dojox.charting.plot2d.Default;
+=====*/
+	return declare("dojox.charting.plot2d.Lines", Default, {
 		//	summary:
-		//		Preset our default plot to be line-based.
-		this.opt.lines = true;
-	}
+		//		A convenience constructor to create a typical line chart.
+		constructor: function(){
+			//	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 b7c6c5b..1757e02 100644
--- a/dojox/charting/plot2d/Markers.js
+++ b/dojox/charting/plot2d/Markers.js
@@ -1,13 +1,14 @@
-dojo.provide("dojox.charting.plot2d.Markers");
-
-dojo.require("dojox.charting.plot2d.Default");
-
-dojo.declare("dojox.charting.plot2d.Markers", dojox.charting.plot2d.Default, {
-	//	summary:
-	//		A convenience plot to draw a line chart with markers.
-	constructor: function(){
+define(["dojo/_base/declare", "./Default"], function(declare, Default){
+/*=====
+var Default = dojox.charting.plot2d.Default
+=====*/
+	return declare("dojox.charting.plot2d.Markers", Default, {
 		//	summary:
-		//		Set up the plot for lines and markers.
-		this.opt.markers = true;
-	}
+		//		A convenience plot to draw a line chart with markers.
+		constructor: function(){
+			//	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 b5a8784..06c6052 100644
--- a/dojox/charting/plot2d/MarkersOnly.js
+++ b/dojox/charting/plot2d/MarkersOnly.js
@@ -1,14 +1,15 @@
-dojo.provide("dojox.charting.plot2d.MarkersOnly");
-
-dojo.require("dojox.charting.plot2d.Default");
-
-dojo.declare("dojox.charting.plot2d.MarkersOnly", dojox.charting.plot2d.Default, {
-	//	summary:
-	//		A convenience object to draw only markers (like a scatter but not quite).
-	constructor: function(){
+define(["dojo/_base/declare", "./Default"], function(declare, Default){
+/*=====
+var Default = dojox.charting.plot2d.Default;
+=====*/
+	return declare("dojox.charting.plot2d.MarkersOnly", Default, {
 		//	summary:
-		//		Set up our default plot to only have markers and no lines.
-		this.opt.lines   = false;
-		this.opt.markers = true;
-	}
+		//		A convenience object to draw only markers (like a scatter but not quite).
+		constructor: function(){
+			//	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 e8d81ec..6cf7936 100644
--- a/dojox/charting/plot2d/OHLC.js
+++ b/dojox/charting/plot2d/OHLC.js
@@ -1,23 +1,18 @@
-dojo.provide("dojox.charting.plot2d.OHLC");
+define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "./Base", "./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;
+=====*/
 
-dojo.require("dojox.charting.plot2d.common");
-dojo.require("dojox.charting.plot2d.Base");
-
-dojo.require("dojox.lang.utils");
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.functional.reversed");
-
-(function(){
-	var df = dojox.lang.functional, du = dojox.lang.utils,
-		dc = dojox.charting.plot2d.common,
-		purgeGroup = df.lambda("item.purgeGroup()");
+	var purgeGroup = dfr.lambda("item.purgeGroup()");
 
 	//	Candlesticks are based on the Bars plot type; we expect the following passed
 	//	as values in a series:
 	//	{ 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.
-	dojo.declare("dojox.charting.plot2d.OHLC", dojox.charting.plot2d.Base, {
+	return declare("dojox.charting.plot2d.OHLC", Base, {
 		//	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
@@ -45,11 +40,11 @@ dojo.require("dojox.lang.functional.reversed");
 		constructor: function(chart, kwArgs){
 			//	summary:
 			//		The constructor for a candlestick chart.
-			//	chart: dojox.charting.Chart2D
+			//	chart: dojox.charting.Chart
 			//		The chart this plot belongs to.
 			//	kwArgs: dojox.charting.plot2d.__BarCtorArgs?
 			//		An optional keyword arguments object to help define the plot.
-			this.opt = dojo.clone(this.defaultParams);
+			this.opt = lang.clone(this.defaultParams);
 			du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
 			this.series = [];
@@ -70,13 +65,13 @@ dojo.require("dojox.lang.functional.reversed");
 
 			//	we have to roll our own, since we need to use all four passed
 			//	values to figure out our stats, and common only assumes x and y.
-			var stats = dojo.delegate(dc.defaultStats);
+			var stats = lang.delegate(dc.defaultStats);
 			for(var i=0; i<series.length; i++){
 				var run = series[i];
 				if(!run.data.length){ continue; }
 				var old_vmin = stats.vmin, old_vmax = stats.vmax;
 				if(!("ymin" in run) || !("ymax" in run)){
-					dojo.forEach(run.data, function(val, idx){
+					arr.forEach(run.data, function(val, idx){
 						if(val !== null){
 							var x = val.x || idx + 1;
 							stats.hmin = Math.min(stats.hmin, x);
@@ -118,7 +113,7 @@ dojo.require("dojox.lang.functional.reversed");
 			this.resetEvents();
 			this.dirty = this.isDirty();
 			if(this.dirty){
-				dojo.forEach(this.series, purgeGroup);
+				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
 				var s = this.group;
@@ -165,7 +160,7 @@ dojo.require("dojox.lang.functional.reversed");
 							var hl = {x1: width/2, x2: width/2, y1: y - high, y2: y - low},
 								op = {x1: 0, x2: ((width/2) + ((finalTheme.series.stroke.width||1)/2)), y1: y-open, y2: y-open},
 								cl = {x1: ((width/2) - ((finalTheme.series.stroke.width||1)/2)), x2: width, y1: y-close, y2: y-close};
-							shape = s.createGroup();
+							var shape = s.createGroup();
 							shape.setTransform({dx: x, dy: 0});
 							var inner = shape.createGroup();
 							inner.createLine(hl).setStroke(finalTheme.series.stroke);
@@ -204,7 +199,7 @@ dojo.require("dojox.lang.functional.reversed");
 			return this;	//	dojox.charting.plot2d.OHLC
 		},
 		_animateOHLC: function(shape, voffset, vsize){
-			dojox.gfx.fx.animateTransform(dojo.delegate({
+			fx.animateTransform(lang.delegate({
 				shape: shape,
 				duration: 1200,
 				transform: [
@@ -215,4 +210,4 @@ dojo.require("dojox.lang.functional.reversed");
 			}, this.animate)).play();
 		}
 	});
-})();
+});
diff --git a/dojox/charting/plot2d/Pie.js b/dojox/charting/plot2d/Pie.js
index c455986..5608c95 100644
--- a/dojox/charting/plot2d/Pie.js
+++ b/dojox/charting/plot2d/Pie.js
@@ -1,72 +1,64 @@
-dojo.provide("dojox.charting.plot2d.Pie");
+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){
 
-dojo.require("dojox.charting.Element");
-dojo.require("dojox.charting.axis2d.common");
-dojo.require("dojox.charting.plot2d.common");
-dojo.require("dojox.charting.plot2d._PlotEvents");
-
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.utils");
-dojo.require("dojox.gfx");
-
-/*=====
-dojo.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?
-	//		Whether or not to draw labels within each pie slice.  Default is true.
-	labels:			true,
-
-	//	ticks: Boolean?
-	//		Whether or not to draw ticks to labels within each slice. Default is false.
-	ticks:			false,
-
-	//	fixed: Boolean?
-	//		TODO
-	fixed:			true,
-
-	//	precision: Number?
-	//		The precision at which to sum/add data values. Default is 1.
-	precision:		1,
-
-	//	labelOffset: Number?
-	//		The amount in pixels by which to offset labels.  Default is 20.
-	labelOffset:	20,
-
-	//	labelStyle: String?
-	//		Options as to where to draw labels.  Values include "default", "rows", and "auto". Default is "default".
-	labelStyle:		"default",	// default/rows/auto
-
-	//	htmlLabels: Boolean?
-	//		Whether or not to use HTML to render slice labels. Default is true.
-	htmlLabels:		true,
-
-	//	radGrad: String?
-	//		The type of radial gradient to use in rendering.  Default is "native".
-	radGrad:        "native",
-
-	//	fanSize: Number?
-	//		The amount for a radial gradient.  Default is 5.
-	fanSize:		5,
-
-	//	startAngle: Number?
-	//		Where to being rendering gradients in slices, in degrees.  Default is 0.
-	startAngle:     0,
+	/*=====
+	var Element = dojox.charting.Element;
+	var PlotEvents = dojox.charting.plot2d._PlotEvents;
+	dojo.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?
+		//		Whether or not to draw labels for each pie slice.  Default is true.
+		labels:			true,
+	
+		//	ticks: Boolean?
+		//		Whether or not to draw ticks to labels within each slice. Default is false.
+		ticks:			false,
+	
+		//	fixed: Boolean?
+		//		TODO
+		fixed:			true,
+	
+		//	precision: Number?
+		//		The precision at which to sum/add data values. Default is 1.
+		precision:		1,
+	
+		//	labelOffset: Number?
+		//		The amount in pixels by which to offset labels.  Default is 20.
+		labelOffset:	20,
+	
+		//	labelStyle: String?
+		//		Options as to where to draw labels.  Values include "default", and "columns".	Default is "default".
+		labelStyle:		"default",	// default/columns
+	
+		//	htmlLabels: Boolean?
+		//		Whether or not to use HTML to render slice labels. Default is true.
+		htmlLabels:		true,
+	
+		//	radGrad: String?
+		//		The type of radial gradient to use in rendering.  Default is "native".
+		radGrad:        "native",
+	
+		//	fanSize: Number?
+		//		The amount for a radial gradient.  Default is 5.
+		fanSize:		5,
+	
+		//	startAngle: Number?
+		//		Where to being rendering gradients in slices, in degrees.  Default is 0.
+		startAngle:     0,
+	
+		//	radius: Number?
+		//		The size of the radial gradient.  Default is 0.
+		radius:		0
+	});
+	=====*/
 
-	//	radius: Number?
-	//		The size of the radial gradient.  Default is 0.
-	radius:		0
-});
-=====*/
-(function(){
-	var df = dojox.lang.functional, du = dojox.lang.utils,
-		dc = dojox.charting.plot2d.common,
-		da = dojox.charting.axis2d.common,
-		g = dojox.gfx, m = g.matrix,
-		FUDGE_FACTOR = 0.2; // use to overlap fans
+	var FUDGE_FACTOR = 0.2; // use to overlap fans
 
-	dojo.declare("dojox.charting.plot2d.Pie", [dojox.charting.Element, dojox.charting.plot2d._PlotEvents], {
+	return declare("dojox.charting.plot2d.Pie", [Element, PlotEvents], {
 		//	summary:
 		//		The plot that represents a typical pie chart.
 		defaultParams: {
@@ -75,7 +67,7 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 			fixed:			true,
 			precision:		1,
 			labelOffset:	20,
-			labelStyle:		"default",	// default/rows/auto/columns
+			labelStyle:		"default",	// default/columns
 			htmlLabels:		true,		// use HTML to draw labels
 			radGrad:        "native",	// or "linear", or "fan"
 			fanSize:		5,			// maximum fan size in degrees
@@ -96,7 +88,7 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 		constructor: function(chart, kwArgs){
 			//	summary:
 			//		Create a pie plot.
-			this.opt = dojo.clone(this.defaultParams);
+			this.opt = lang.clone(this.defaultParams);
 			du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
 			this.run = null;
@@ -132,7 +124,7 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 			//		Returns default stats (irrelevant for this type of plot).
 			//	returns: Object
 			//		{hmin, hmax, vmin, vmax} min/max in both directions.
-			return dojo.delegate(dc.defaultStats);
+			return lang.delegate(dc.defaultStats);
 		},
 		initializeScalers: function(){
 			//	summary:
@@ -183,7 +175,7 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 				}
 				slices = df.map(filteredRun, "/this", df.foldl(filteredRun, "+", 0));
 				if(this.opt.labels){
-					labels = dojo.map(slices, function(x){
+					labels = arr.map(slices, function(x){
 						return x > 0 ? this._getLabel(x * 100) + "%" : "";
 					}, this);
 				}
@@ -194,7 +186,7 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 				}
 				slices = df.map(filteredRun, "/this", df.foldl(filteredRun, "+", 0));
 				if(this.opt.labels){
-					labels = dojo.map(slices, function(x, i){
+					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) + "%";
@@ -210,7 +202,7 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 			if(this.opt.labels){
 				shift = df.foldl1(df.map(labels, function(label, i){
 					var font = themes[i].series.font;
-					return dojox.gfx._base._getTextBox(label, {font: font}).w;
+					return g._base._getTextBox(label, {font: font}).w;
 				}, this), "Math.max(a, b)") / 2;
 				if(this.opt.labelOffset < 0){
 					r = Math.min(rx - 2 * shift, ry - size) + this.opt.labelOffset;
@@ -230,11 +222,15 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 			this.dyn = [];
 			// draw slices
 			var eventSeries = new Array(slices.length);
-			dojo.some(slices, function(slice, i){
-				if(slice <= 0){
+			arr.some(slices, function(slice, i){
+				if(slice < 0){
 					// degenerated slice
 					return false;	// continue
 				}
+				if(slice == 0){
+				  this.dyn.push({fill: null, stroke: null});
+				  return false;
+				}
 				var v = run[i], theme = themes[i], specialFill;
 				if(slice >= 1){
 					// whole pie
@@ -287,7 +283,7 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 							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({}).
+							fan = group.createPath().
 								moveTo(circle.cx, circle.cy).
 								lineTo(fansx, fansy).
 								arcTo(r, r, 0, delta > Math.PI, true, fanex, faney).
@@ -295,7 +291,7 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 								closePath().
 								setFill(this._pseudoRadialFill(specialFill, {x: circle.cx, y: circle.cy}, r, start + (j + 0.5) * delta, start + (j + 0.5) * delta));
 					}
-					group.createPath({}).
+					group.createPath().
 						moveTo(circle.cx, circle.cy).
 						lineTo(x1, y1).
 						arcTo(r, r, 0, step > Math.PI, true, x2, y2).
@@ -304,7 +300,7 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 						setStroke(theme.series.stroke);
 					shape = group;
 				}else{
-					shape = s.createPath({}).
+					shape = s.createPath().
 						moveTo(circle.cx, circle.cy).
 						lineTo(x1, y1).
 						arcTo(r, r, 0, step > Math.PI, true, x2, y2).
@@ -349,7 +345,7 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 			if(this.opt.labels){
 				if(this.opt.labelStyle == "default"){
 					start = startAngle;
-					dojo.some(slices, function(slice, i){
+					arr.some(slices, function(slice, i){
 						if(slice <= 0){
 							// degenerated slice
 							return false;	// continue
@@ -357,7 +353,7 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 						var theme = themes[i];
 						if(slice >= 1){
 							// whole pie
-							var v = run[i], elem = da.createText[this.opt.htmlLabels && dojox.gfx.renderer != "vml" ? "html" : "gfx"](
+							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){
@@ -374,7 +370,7 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 							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 && dojox.gfx.renderer != "vml" ? "html" : "gfx"]
+						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);
@@ -386,7 +382,7 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 					start = startAngle;
 					//calculate label angles
 					var labeledSlices = [];
-					dojo.forEach(slices, function(slice, i){
+					arr.forEach(slices, function(slice, i){
 						var end = start + slice * 2 * Math.PI;
 						if(i + 1 == slices.length){
 							end = startAngle + 2 * Math.PI;
@@ -402,14 +398,14 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 						start = end;
 					});
 					//calculate label radius to each slice
-					var labelHeight = dojox.gfx._base._getTextBox("a",{font:taFont}).h;
+					var labelHeight = g._base._getTextBox("a",{font:taFont}).h;
 					this._getProperLabelRadius(labeledSlices, labelHeight, circle.r * 1.1);
 					//draw label and wiring
-					dojo.forEach(labeledSlices, function(slice, i){
+					arr.forEach(labeledSlices, function(slice, i){
 						if (!slice.omit) {
 							var leftColumn = circle.cx - circle.r * 2,
 								rightColumn = circle.cx + circle.r * 2,
-								labelWidth = dojox.gfx._base._getTextBox(labels[i], {font: taFont}).w,
+								labelWidth = g._base._getTextBox(labels[i], {font: taFont}).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),
@@ -419,7 +415,7 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 								wiring.lineTo(x, y);
 							}
 							wiring.lineTo(jointX, y).setStroke(slice.theme.series.labelWiring);
-							var elem = da.createText[this.opt.htmlLabels && dojox.gfx.renderer != "vml" ? "html" : "gfx"](
+							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);
@@ -457,10 +453,10 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 				}
 			}
 			leftCenterSlice.labelR = rightCenterSlice.labelR = minRidius;
-			this._caculateLabelR(leftCenterSlice,slices,labelHeight);
-			this._caculateLabelR(rightCenterSlice,slices,labelHeight);
+			this._calculateLabelR(leftCenterSlice,slices,labelHeight);
+			this._calculateLabelR(rightCenterSlice,slices,labelHeight);
 		},
-		_caculateLabelR: function(firstSlice,slices,labelHeight){
+		_calculateLabelR: function(firstSlice,slices,labelHeight){
 			var i = firstSlice.index,length = slices.length,
 				currentLabelR = firstSlice.labelR;
 			while(!(slices[i%length].left ^ slices[(i+1)%length].left)){
@@ -472,7 +468,8 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 				}
 				i++;
 			}
-			i = firstSlice.index,j = (i == 0)?length-1 : i - 1;
+			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))) /
@@ -490,4 +487,4 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 			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 090d18d..d5434b7 100644
--- a/dojox/charting/plot2d/Scatter.js
+++ b/dojox/charting/plot2d/Scatter.js
@@ -1,21 +1,12 @@
-dojo.provide("dojox.charting.plot2d.Scatter");
+define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "./Base", "./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;
+=====*/
+	var purgeGroup = dfr.lambda("item.purgeGroup()");
 
-dojo.require("dojox.charting.plot2d.common");
-dojo.require("dojox.charting.plot2d.Base");
-
-dojo.require("dojox.lang.utils");
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.functional.reversed");
-
-dojo.require("dojox.gfx.gradutils");
-
-
-(function(){
-	var df = dojox.lang.functional, du = dojox.lang.utils,
-		dc = dojox.charting.plot2d.common,
-		purgeGroup = df.lambda("item.purgeGroup()");
-
-	dojo.declare("dojox.charting.plot2d.Scatter", dojox.charting.plot2d.Base, {
+	return declare("dojox.charting.plot2d.Scatter", Base, {
 		//	summary:
 		//		A plot object representing a typical scatter chart.
 		defaultParams: {
@@ -37,11 +28,11 @@ dojo.require("dojox.gfx.gradutils");
 		constructor: function(chart, kwArgs){
 			//	summary:
 			//		Create the scatter plot.
-			//	chart: dojox.charting.Chart2D
+			//	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 = dojo.clone(this.defaultParams);
+			this.opt = lang.clone(this.defaultParams);
             du.updateWithObject(this.opt, kwArgs);
             du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
 			this.series = [];
@@ -65,7 +56,7 @@ dojo.require("dojox.gfx.gradutils");
 			this.resetEvents();
 			this.dirty = this.isDirty();
 			if(this.dirty){
-				dojo.forEach(this.series, purgeGroup);
+				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
 				var s = this.group;
@@ -90,14 +81,14 @@ dojo.require("dojox.gfx.gradutils");
 					ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
 					vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler);
 				if(typeof run.data[0] == "number"){
-					lpoly = dojo.map(run.data, function(v, i){
+					lpoly = arr.map(run.data, function(v, i){
 						return {
 							x: ht(i + 1) + offsets.l,
 							y: dim.height - offsets.b - vt(v)
 						};
 					}, this);
 				}else{
-					lpoly = dojo.map(run.data, function(v, i){
+					lpoly = arr.map(run.data, function(v, i){
 						return {
 							x: ht(v.x) + offsets.l,
 							y: dim.height - offsets.b - vt(v.y)
@@ -109,7 +100,7 @@ dojo.require("dojox.gfx.gradutils");
 					frontMarkers   = new Array(lpoly.length),
 					outlineMarkers = new Array(lpoly.length);
 
-				dojo.forEach(lpoly, function(c, i){
+				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),
@@ -133,7 +124,7 @@ dojo.require("dojox.gfx.gradutils");
 					var stroke = dc.makeStroke(finalTheme.marker.stroke),
 						fill = this._plotFill(finalTheme.marker.fill, dim, offsets);
 					if(fill && (fill.type === "linear" || fill.type == "radial")){
-						var color = dojox.gfx.gradutils.getColor(fill, {x: c.x, y: c.y});
+						var color = gradutils.getColor(fill, {x: c.x, y: c.y});
 						if(stroke){
 							stroke.color = color;
 						}
@@ -152,7 +143,7 @@ dojo.require("dojox.gfx.gradutils");
 
 				if(events){
 					var eventSeries = new Array(frontMarkers.length);
-					dojo.forEach(frontMarkers, function(s, i){
+					arr.forEach(frontMarkers, function(s, i){
 						var o = {
 							element: "marker",
 							index:   i,
@@ -183,7 +174,7 @@ dojo.require("dojox.gfx.gradutils");
 			return this;	//	dojox.charting.plot2d.Scatter
 		},
 		_animateScatter: function(shape, offset){
-			dojox.gfx.fx.animateTransform(dojo.delegate({
+			fx.animateTransform(lang.delegate({
 				shape: shape,
 				duration: 1200,
 				transform: [
@@ -194,4 +185,4 @@ dojo.require("dojox.gfx.gradutils");
 			}, this.animate)).play();
 		}
 	});
-})();
+});
diff --git a/dojox/charting/plot2d/Spider.js b/dojox/charting/plot2d/Spider.js
index bfcbeab..9178e94 100644
--- a/dojox/charting/plot2d/Spider.js
+++ b/dojox/charting/plot2d/Spider.js
@@ -1,28 +1,18 @@
-dojo.provide("dojox.charting.plot2d.Spider");
+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", 
+	"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;
+=====*/
+	var FUDGE_FACTOR = 0.2; // use to overlap fans
 
-dojo.experimental("dojox.charting.plot2d.Spider");
-
-dojo.require("dojox.charting.Element");
-dojo.require("dojox.charting.plot2d._PlotEvents");
-dojo.require("dojox.charting.axis2d.common");
-dojo.require("dojox.charting.plot2d.common");
-dojo.require("dojox.charting.scaler.primitive");
-
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.utils");
-dojo.require("dojox.gfx");
-dojo.require("dojo.fx");
-dojo.require("dojo.fx.easing");
-dojo.require("dojox.gfx.fx");
-
-(function(){
-	var df = dojox.lang.functional, du = dojox.lang.utils,
-		dc = dojox.charting.plot2d.common,
-		da = dojox.charting.axis2d.common,
-		g = dojox.gfx, m = g.matrix,
-		FUDGE_FACTOR = 0.2; // use to overlap fans
-
-	dojo.declare("dojox.charting.plot2d.Spider", [dojox.charting.Element, dojox.charting.plot2d._PlotEvents], {
+	var Spider = declare("dojox.charting.plot2d.Spider", [Element, PlotEvents], {
 		//	summary:
 		//		The plot that represents a typical Spider chart.
 		defaultParams: {
@@ -44,7 +34,7 @@ dojo.require("dojox.gfx.fx");
 			spiderOrigin:	 0.16,
 			markerSize:		 3,			// radius of plot vertex (px)
 			spiderType:		 "polygon", //"circle"
-			animationType:	 dojo.fx.easing.backOut,
+			animationType:	 easing.backOut,
 			axisTickFont:		"",
 			axisTickFontColor:	"",
 			axisFont:			"",
@@ -59,7 +49,7 @@ dojo.require("dojox.gfx.fx");
 		constructor: function(chart, kwArgs){
 			//	summary:
 			//		Create a Spider plot.
-			this.opt = dojo.clone(this.defaultParams);
+			this.opt = lang.clone(this.defaultParams);
 			du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
 			this.series = [];
@@ -122,7 +112,7 @@ dojo.require("dojox.gfx.fx");
 			//		Calculate the min/max on all attached series in both directions.
 			//	returns: Object
 			//		{hmin, hmax, vmin, vmax} min/max in both directions.
-			return dojox.charting.plot2d.common.collectSimpleStats(this.series);
+			return dc.collectSimpleStats(this.series);
 		},
 		calculateAxes: function(dim){
 			//	summary:
@@ -156,7 +146,7 @@ dojo.require("dojox.gfx.fx");
 				}
 				this._hScaler = this._hAxis.getScaler();
 			}else{
-				this._hScaler = dojox.charting.scaler.primitive.buildScaler(stats.hmin, stats.hmax, dim.width);
+				this._hScaler = primitive.buildScaler(stats.hmin, stats.hmax, dim.width);
 			}
 			if(this._vAxis){
 				if(!this._vAxis.initialized()){
@@ -164,7 +154,7 @@ dojo.require("dojox.gfx.fx");
 				}
 				this._vScaler = this._vAxis.getScaler();
 			}else{
-				this._vScaler = dojox.charting.scaler.primitive.buildScaler(stats.vmin, stats.vmax, dim.height);
+				this._vScaler = primitive.buildScaler(stats.vmin, stats.vmax, dim.height);
 			}
 			return this;	//	dojox.charting.plot2d.Base
 		},
@@ -210,12 +200,12 @@ dojo.require("dojox.gfx.fx");
 				axisExtra = 0.2;
 			
 			if(o.labels){
-				labels = dojo.map(this.series, function(s){
+				labels = arr.map(this.series, function(s){
 					return s.name;
 				}, this);
 				shift = df.foldl1(df.map(labels, function(label, i){
 					var font = t.series.font;
-					return dojox.gfx._base._getTextBox(label, {
+					return g._base._getTextBox(label, {
 						font: font
 					}).w;
 				}, this), "Math.max(a, b)") / 2;
@@ -289,9 +279,9 @@ dojo.require("dojox.gfx.fx");
 			var labelGroup = s.createGroup();
 			for (var j = labelPoints.length - 1; j >= 0; --j) {
 				var point = labelPoints[j],
-					fontWidth = dojox.gfx._base._getTextBox(this.labelKey[j], {font: axisFont}).w || 0,
-					render = this.opt.htmlLabels && dojox.gfx.renderer != "vml" ? "html" : "gfx";
-					elem = da.createText[render](this.chart, labelGroup, (!dojo._isBodyLtr() && render == "html") ? (point.x + fontWidth - dim.width) : point.x, point.y,
+					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,
 							"middle", this.labelKey[j], axisFont, axisFontColor);
 				if (this.opt.htmlLabels) {
 					this.htmlElements.push(elem);
@@ -326,11 +316,11 @@ dojo.require("dojox.gfx.fx");
 				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);
 					text = this._getLabel(text);
-					var fontWidth = dojox.gfx._base._getTextBox(text, {font: axisTickFont}).w || 0,
-						render = this.opt.htmlLabels && dojox.gfx.renderer != "vml" ? "html" : "gfx";
+					var fontWidth = g._base._getTextBox(text, {font: axisTickFont}).w || 0,
+						render = this.opt.htmlLabels && g.renderer != "vml" ? "html" : "gfx";
 					if (this.opt.htmlLabels) {
 						this.htmlElements.push(da.createText[render]
-							(this.chart, textGroup, (!dojo._isBodyLtr() && render == "html") ? (point.x + fontWidth - dim.width) : point.x, point.y,
+							(this.chart, textGroup, (!domGeom.isBodyLtr() && render == "html") ? (point.x + fontWidth - dim.width) : point.x, point.y,
 								"start", text, axisTickFont, axisTickFontColor));
 					}
 				}
@@ -393,7 +383,7 @@ dojo.require("dojox.gfx.fx");
 					};
 					this._connectEvents(so);
 					
-					dojo.forEach(cs.circles, function(c, i){
+					arr.forEach(cs.circles, function(c, i){
 						var shape = c.getShape(),
 							co = {
 								element: "spider_circle",
@@ -424,16 +414,16 @@ dojo.require("dojox.gfx.fx");
 				scircle.push(circle);
 			}
 			
-			var anims = dojo.map(sps, function(np, j){
+			var anims = arr.map(sps, function(np, j){
 				// create animation
 				var sp = osps[j],
-					anim = new dojo._Animation({
+					anim = new baseFx.Animation({
 					duration: 1000,
 					easing:	  at,
 					curve:	  [sp.y, np.y]
 				});
 				var spl = spoly, sc = scircle[j];
-				dojo.connect(anim, "onAnimate", function(y){
+				hub.connect(anim, "onAnimate", function(y){
 					//apply poly
 					var pshape = spl.getShape();
 					pshape.points[j].y = y;
@@ -446,16 +436,16 @@ dojo.require("dojox.gfx.fx");
 				return anim;
 			});
 			
-			var anims1 = dojo.map(sps, function(np, j){
+			var anims1 = arr.map(sps, function(np, j){
 				// create animation
 				var sp = osps[j],
-					anim = new dojo._Animation({
+					anim = new baseFx.Animation({
 					duration: 1000,
 					easing:	  at,
 					curve:	  [sp.x, np.x]
 				});
 				var spl = spoly, sc = scircle[j];
-				dojo.connect(anim, "onAnimate", function(x){
+				hub.connect(anim, "onAnimate", function(x){
 					//apply poly
 					var pshape = spl.getShape();
 					pshape.points[j].x = x;
@@ -467,7 +457,7 @@ dojo.require("dojox.gfx.fx");
 				});
 				return anim;
 			});
-			var masterAnimation = dojo.fx.combine(anims.concat(anims1)); //dojo.fx.chain(anims);
+			var masterAnimation = coreFx.combine(anims.concat(anims1)); //dojo.fx.chain(anims);
 			masterAnimation.play();
 			return {group :ts, poly: spoly, circles: scircle};
 		},
@@ -486,7 +476,7 @@ dojo.require("dojox.gfx.fx");
 			if(o.element == "spider_poly"){
 				if(!a.color){
 					var color = o.shape.getFill();
-					if(!color || !(color instanceof dojo.Color)){
+					if(!color || !(color instanceof Color)){
 						return;
 					}
 					a.color = {
@@ -499,24 +489,24 @@ dojo.require("dojox.gfx.fx");
 					// swap colors
 					var t = start; start = end; end = t;
 				}
-				a.anim = dojox.gfx.fx.animateFill({
+				a.anim = gfxfx.animateFill({
 					shape:	  o.shape,
 					duration: 800,
-					easing:	  dojo.fx.easing.backOut,
+					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  = dojox.gfx.matrix.identity;
+					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 = dojo.coords(this.chart.node, true);
+					var lt = html.coords(this.chart.node, true);
 					aroundRect.x += lt.x;
 					aroundRect.y += lt.y;
 					aroundRect.x = Math.round(aroundRect.x);
@@ -525,32 +515,32 @@ dojo.require("dojox.gfx.fx");
 					aroundRect.height = Math.ceil(aroundRect.height);
 					this.aroundRect = aroundRect;
 					var position = ["after", "before"];
-					if(dijit && dijit.Tooltip){
-						dijit.showTooltip(o.tdata.sname + "<br/>" + o.tdata.key + "<br/>" + o.tdata.data, this.aroundRect, position);
-					}
+					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  = dojox.gfx.matrix.scaleAt(defaultScale, o.cx, o.cy);
+					init  = m.scaleAt(defaultScale, o.cx, o.cy);
 					scale = 1/defaultScale;
-					if(dijit && dijit.Tooltip){
-						this.aroundRect && dijit.hideTooltip(this.aroundRect);
-					}
+					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:	  dojo.fx.easing.backOut,
+						easing:	  easing.backOut,
 						transform: [
 							{name: "scaleAt", start: [1, cs.cx, cs.cy], end: [scale, cs.cx, cs.cy]},
 							init
 						]
 					};
-				a.anim = dojox.gfx.fx.animateTransform(kwArgs);
+				a.anim = gfxfx.animateTransform(kwArgs);
 				a.anim.play();
 			}else if(o.element == "spider_plot"){
 				//dojo gfx function "moveToFront" not work in IE
-				if (o.type == "onmouseover" && !dojo.isIE) {
+				if (o.type == "onmouseover" && !has("ie")) {
 					o.shape.moveToFront();
 				}
 			}
@@ -602,7 +592,7 @@ dojo.require("dojox.gfx.fx");
 		
 		_getObjectLength: function(obj){
 			var count = 0;
-			if(dojo.isObject(obj)){
+			if(lang.isObject(obj)){
 				for(var key in obj){
 					count++;
 				}
@@ -617,7 +607,7 @@ dojo.require("dojox.gfx.fx");
 	});
 	
 	function transColor(color){
-		var a = new dojox.color.Color(color),
+		var a = new dxcolor.Color(color),
 			x = a.toHsl();
 		if(x.s == 0){
 			x.l = x.l < 50 ? 100 : 0;
@@ -632,9 +622,10 @@ dojo.require("dojox.gfx.fx");
 					50 : 75;
 			}
 		}
-		var color = dojox.color.fromHsl(x);
+		var color = dxcolor.fromHsl(x);
 		color.a = 0.7;
 		return color;
 	}
 	
-})();
+	return Spider; // dojox.plot2d.Spider
+});
diff --git a/dojox/charting/plot2d/Stacked.js b/dojox/charting/plot2d/Stacked.js
index 3f603c5..921792a 100644
--- a/dojox/charting/plot2d/Stacked.js
+++ b/dojox/charting/plot2d/Stacked.js
@@ -1,17 +1,12 @@
-dojo.provide("dojox.charting.plot2d.Stacked");
+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()");
 
-dojo.require("dojox.charting.plot2d.common");
-dojo.require("dojox.charting.plot2d.Default");
-
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.functional.sequence");
-dojo.require("dojox.lang.functional.reversed");
-
-(function(){
-	var df = dojox.lang.functional, dc = dojox.charting.plot2d.common,
-		purgeGroup = df.lambda("item.purgeGroup()");
-
-	dojo.declare("dojox.charting.plot2d.Stacked", dojox.charting.plot2d.Default, {
+	return declare("dojox.charting.plot2d.Stacked", Default, {
 		//	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)
@@ -57,7 +52,7 @@ dojo.require("dojox.lang.functional.reversed");
 			this.resetEvents();
 			this.dirty = this.isDirty();
 			if(this.dirty){
-				dojo.forEach(this.series, purgeGroup);
+				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
 				var s = this.group;
@@ -78,7 +73,7 @@ dojo.require("dojox.lang.functional.reversed");
 				run.cleanGroup();
 				var theme = t.next(this.opt.areas ? "area" : "line", [this.opt, run], true),
 					s = run.group, outline,
-					lpoly = dojo.map(acc, function(v, i){
+					lpoly = arr.map(acc, function(v, i){
 						return {
 							x: ht(i + 1) + offsets.l,
 							y: dim.height - offsets.b - vt(v)
@@ -88,7 +83,7 @@ dojo.require("dojox.lang.functional.reversed");
 				var lpath = this.opt.tension ? dc.curve(lpoly, this.opt.tension) : "";
 
 				if(this.opt.areas){
-					var apoly = dojo.clone(lpoly);
+					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) +
@@ -114,7 +109,7 @@ dojo.require("dojox.lang.functional.reversed");
 				var frontMarkers, outlineMarkers, shadowMarkers;
 				if(theme.series.shadow && theme.series.stroke){
 					var shadow = theme.series.shadow,
-						spoly = dojo.map(lpoly, function(c){
+						spoly = arr.map(lpoly, function(c){
 							return {x: c.x + shadow.dx, y: c.y + shadow.dy};
 						});
 					if(this.opt.lines){
@@ -126,7 +121,7 @@ dojo.require("dojox.lang.functional.reversed");
 					}
 					if(this.opt.markers){
 						shadow = theme.marker.shadow;
-						shadowMarkers = dojo.map(spoly, function(c){
+						shadowMarkers = arr.map(spoly, function(c){
 							return s.createPath("M" + c.x + " " + c.y + " " + theme.symbol).
 								setStroke(shadow).setFill(shadow.color);
 						}, this);
@@ -154,7 +149,7 @@ dojo.require("dojox.lang.functional.reversed");
 						outline = dc.makeStroke(theme.marker.outline);
 						outline.width = 2 * outline.width + (theme.marker.stroke ? theme.marker.stroke.width : 0);
 					}
-					dojo.forEach(lpoly, function(c, i){
+					arr.forEach(lpoly, function(c, i){
 						var path = "M" + c.x + " " + c.y + " " + theme.symbol;
 						if(outline){
 							outlineMarkers[i] = s.createPath(path).setStroke(outline);
@@ -163,7 +158,7 @@ dojo.require("dojox.lang.functional.reversed");
 					}, this);
 					if(events){
 						var eventSeries = new Array(frontMarkers.length);
-						dojo.forEach(frontMarkers, function(s, i){
+						arr.forEach(frontMarkers, function(s, i){
 							var o = {
 								element: "marker",
 								index:   i,
@@ -198,4 +193,4 @@ dojo.require("dojox.lang.functional.reversed");
 			return this;	//	dojox.charting.plot2d.Stacked
 		}
 	});
-})();
+});
diff --git a/dojox/charting/plot2d/StackedAreas.js b/dojox/charting/plot2d/StackedAreas.js
index d5c5590..637ae49 100644
--- a/dojox/charting/plot2d/StackedAreas.js
+++ b/dojox/charting/plot2d/StackedAreas.js
@@ -1,14 +1,16 @@
-dojo.provide("dojox.charting.plot2d.StackedAreas");
-
-dojo.require("dojox.charting.plot2d.Stacked");
-
-dojo.declare("dojox.charting.plot2d.StackedAreas", dojox.charting.plot2d.Stacked, {
-	//	summary:
-	//		A convenience object to set up a stacked area plot.
-	constructor: function(){
+define(["dojo/_base/declare", "./Stacked"], function(declare, Stacked){
+/*=====
+var Stacked = dojox.charting.plot2d.Stacked;
+=====*/
+	return declare("dojox.charting.plot2d.StackedAreas", Stacked, {
 		//	summary:
-		//		Force our Stacked plotter to include both lines and areas.
-		this.opt.lines = true;
-		this.opt.areas = true;
-	}
+		//		A convenience object to set up a stacked area plot.
+		constructor: function(){
+			//	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 e3b5b63..5d3923b 100644
--- a/dojox/charting/plot2d/StackedBars.js
+++ b/dojox/charting/plot2d/StackedBars.js
@@ -1,17 +1,12 @@
-dojo.provide("dojox.charting.plot2d.StackedBars");
+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){
 
-dojo.require("dojox.charting.plot2d.common");
-dojo.require("dojox.charting.plot2d.Bars");
-
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.functional.reversed");
-dojo.require("dojox.lang.functional.sequence");
-
-(function(){
-	var df = dojox.lang.functional, dc = dojox.charting.plot2d.common,
-		purgeGroup = df.lambda("item.purgeGroup()");
-
-	dojo.declare("dojox.charting.plot2d.StackedBars", dojox.charting.plot2d.Bars, {
+	var	purgeGroup = dfr.lambda("item.purgeGroup()");
+/*=====
+var bars = dojox.charting.plot2d.Bars;
+=====*/
+	return declare("dojox.charting.plot2d.StackedBars", Bars, {
 		//	summary:
 		//		The plot object representing a stacked bar chart (horizontal bars).
 		getSeriesStats: function(){
@@ -60,7 +55,7 @@ dojo.require("dojox.lang.functional.sequence");
 			this.resetEvents();
 			this.dirty = this.isDirty();
 			if(this.dirty){
-				dojo.forEach(this.series, purgeGroup);
+				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
 				var s = this.group;
@@ -91,7 +86,7 @@ dojo.require("dojox.lang.functional.sequence");
 							finalTheme = typeof value != "number" ?
 								t.addMixin(theme, "bar", value, true) :
 								t.post(theme, "bar");
-						if(width >= 1 && height >= 1){
+						if(width >= 0 && height >= 1){
 							var rect = {
 								x: offsets.l,
 								y: dim.height - offsets.b - vt(j + 1.5) + gap,
@@ -136,4 +131,4 @@ dojo.require("dojox.lang.functional.sequence");
 			return this;	//	dojox.charting.plot2d.StackedBars
 		}
 	});
-})();
+});
diff --git a/dojox/charting/plot2d/StackedColumns.js b/dojox/charting/plot2d/StackedColumns.js
index 0de2b8d..551e99e 100644
--- a/dojox/charting/plot2d/StackedColumns.js
+++ b/dojox/charting/plot2d/StackedColumns.js
@@ -1,17 +1,12 @@
-dojo.provide("dojox.charting.plot2d.StackedColumns");
+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){
 
-dojo.require("dojox.charting.plot2d.common");
-dojo.require("dojox.charting.plot2d.Columns");
-
-dojo.require("dojox.lang.functional");
-dojo.require("dojox.lang.functional.reversed");
-dojo.require("dojox.lang.functional.sequence");
-
-(function(){
-	var df = dojox.lang.functional, dc = dojox.charting.plot2d.common,
-		purgeGroup = df.lambda("item.purgeGroup()");
-
-	dojo.declare("dojox.charting.plot2d.StackedColumns", dojox.charting.plot2d.Columns, {
+	var	purgeGroup = dfr.lambda("item.purgeGroup()");
+/*=====
+var Columns = dojox.charting.plot2d.Columns;
+=====*/
+	return declare("dojox.charting.plot2d.StackedColumns", Columns, {
 		//	summary:
 		//		The plot object representing a stacked column chart (vertical bars).
 		getSeriesStats: function(){
@@ -58,7 +53,7 @@ dojo.require("dojox.lang.functional.sequence");
 			this.resetEvents();
 			this.dirty = this.isDirty();
 			if(this.dirty){
-				dojo.forEach(this.series, purgeGroup);
+				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
 				var s = this.group;
@@ -89,7 +84,7 @@ dojo.require("dojox.lang.functional.sequence");
 							finalTheme = typeof value != "number" ?
 								t.addMixin(theme, "column", value, true) :
 								t.post(theme, "column");
-						if(width >= 1 && height >= 1){
+						if(width >= 1 && height >= 0){
 							var rect = {
 								x: offsets.l + ht(j + 0.5) + gap,
 								y: dim.height - offsets.b - vt(v),
@@ -134,4 +129,4 @@ dojo.require("dojox.lang.functional.sequence");
 			return this;	//	dojox.charting.plot2d.StackedColumns
 		}
 	});
-})();
+});
diff --git a/dojox/charting/plot2d/StackedLines.js b/dojox/charting/plot2d/StackedLines.js
index 6e42c49..03f0b4d 100644
--- a/dojox/charting/plot2d/StackedLines.js
+++ b/dojox/charting/plot2d/StackedLines.js
@@ -1,13 +1,14 @@
-dojo.provide("dojox.charting.plot2d.StackedLines");
-
-dojo.require("dojox.charting.plot2d.Stacked");
-
-dojo.declare("dojox.charting.plot2d.StackedLines", dojox.charting.plot2d.Stacked, {
-	//	summary:
-	//		A convenience object to create a stacked line chart.
-	constructor: function(){
+define(["dojo/_base/declare", "./Stacked"], function(declare, Stacked){
+/*=====
+var Stacked = dojox.charting.plot2d.Stacked;
+=====*/
+	return declare("dojox.charting.plot2d.StackedLines", Stacked, {
 		//	summary:
-		//		Force our Stacked base to be lines only.
-		this.opt.lines = true;
-	}
+		//		A convenience object to create a stacked line chart.
+		constructor: function(){
+			//	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 e1cfc67..76c7ef0 100644
--- a/dojox/charting/plot2d/_PlotEvents.js
+++ b/dojox/charting/plot2d/_PlotEvents.js
@@ -1,125 +1,120 @@
-dojo.provide("dojox.charting.plot2d._PlotEvents");
+define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "dojo/_base/connect"], 
+	function(lang, arr, declare, hub){
 
-dojo.declare("dojox.charting.plot2d._PlotEvents", null, {
-	constructor: function(){
-		this._shapeEvents = [];
-		this._eventSeries = {};
-	},
-	destroy: function(){
-		//	summary:
-		//		Destroy any internal elements and event handlers.
-		this.resetEvents();
-		this.inherited(arguments);
-	},
-	plotEvent: function(o){
-		//	summary:
-		//		Stub function for use by specific plots.
-		//	o: Object
-		//		An object intended to represent event parameters.
-	},
-	raiseEvent: function(o){
-		//	summary:
-		//		Raises events in predefined order
-		//	o: Object
-		//		An object intended to represent event parameters.
-		this.plotEvent(o);
-		var t = dojo.delegate(o);
-		t.originalEvent = o.type;
-		t.originalPlot  = o.plot;
-		t.type = "onindirect";
-		dojo.forEach(this.chart.stack, function(plot){
-			if(plot !== this && plot.plotEvent){
-				t.plot = plot;
-				plot.plotEvent(t);
-			}
-		}, this);
-	},
-	connect: function(object, method){
-		//	summary:
-		//		Helper function to connect any object's method to our plotEvent.
-		//	object: Object
-		//		The object to connect to.
-		//	method: String|Function
-		//		The method to fire when our plotEvent is fired.
-		//	returns: Array
-		//		The handle as returned from dojo.connect (see dojo.connect).
-		this.dirty = true;
-		return dojo.connect(this, "plotEvent", object, method);	//	Array
-	},
-	events: function(){
-		//	summary:
-		//		Find out if any event handlers have been connected to our plotEvent.
-		//	returns: Boolean
-		//		A flag indicating that there are handlers attached.
-		var ls = this.plotEvent._listeners;
-		if(!ls || !ls.length){ return false; }
-		for(var i in ls){
-			if(!(i in Array.prototype)){
-				return true;
+	return declare("dojox.charting.plot2d._PlotEvents", null, {
+		constructor: function(){
+			this._shapeEvents = [];
+			this._eventSeries = {};
+		},
+		destroy: function(){
+			//	summary:
+			//		Destroy any internal elements and event handlers.
+			this.resetEvents();
+			this.inherited(arguments);
+		},
+		plotEvent: function(o){
+			//	summary:
+			//		Stub function for use by specific plots.
+			//	o: Object
+			//		An object intended to represent event parameters.
+		},
+		raiseEvent: function(o){
+			//	summary:
+			//		Raises events in predefined order
+			//	o: Object
+			//		An object intended to represent event parameters.
+			this.plotEvent(o);
+			var t = lang.delegate(o);
+			t.originalEvent = o.type;
+			t.originalPlot  = o.plot;
+			t.type = "onindirect";
+			arr.forEach(this.chart.stack, function(plot){
+				if(plot !== this && plot.plotEvent){
+					t.plot = plot;
+					plot.plotEvent(t);
+				}
+			}, this);
+		},
+		connect: function(object, method){
+			//	summary:
+			//		Helper function to connect any object's method to our plotEvent.
+			//	object: Object
+			//		The object to connect to.
+			//	method: String|Function
+			//		The method to fire when our plotEvent is fired.
+			//	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:
+			//		Find out if any event handlers have been connected to our plotEvent.
+			//	returns: Boolean
+			//		A flag indicating that there are handlers attached.
+			return !!this.plotEvent.after;
+		},
+		resetEvents: function(){
+			//	summary:
+			//		Reset all events attached to our plotEvent (i.e. disconnect).
+			if(this._shapeEvents.length){
+				arr.forEach(this._shapeEvents, function(item){
+					item.shape.disconnect(item.handle);
+				});
+				this._shapeEvents = [];
 			}
-		}
-		return false;
-	},
-	resetEvents: function(){
-		//	summary:
-		//		Reset all events attached to our plotEvent (i.e. disconnect).
-		if(this._shapeEvents.length){
-			dojo.forEach(this._shapeEvents, function(item){
-				item.shape.disconnect(item.handle);
+			this.raiseEvent({type: "onplotreset", plot: this});
+		},
+		_connectSingleEvent: function(o, eventName){
+			this._shapeEvents.push({
+				shape:  o.eventMask,
+				handle: o.eventMask.connect(eventName, this, function(e){
+					o.type  = eventName;
+					o.event = e;
+					this.raiseEvent(o);
+					o.event = null;
+				})
 			});
-			this._shapeEvents = [];
-		}
-		this.raiseEvent({type: "onplotreset", plot: this});
-	},
-	_connectSingleEvent: function(o, eventName){
-		this._shapeEvents.push({
-			shape:  o.eventMask,
-			handle: o.eventMask.connect(eventName, this, function(e){
+		},
+		_connectEvents: function(o){
+			if(o){
+				o.chart = this.chart;
+				o.plot  = this;
+				o.hAxis = this.hAxis || null;
+				o.vAxis = this.vAxis || null;
+				o.eventMask = o.eventMask || o.shape;
+				this._connectSingleEvent(o, "onmouseover");
+				this._connectSingleEvent(o, "onmouseout");
+				this._connectSingleEvent(o, "onclick");
+			}
+		},
+		_reconnectEvents: function(seriesName){
+			var a = this._eventSeries[seriesName];
+			if(a){
+				arr.forEach(a, this._connectEvents, this);
+			}
+		},
+		fireEvent: function(seriesName, eventName, index, eventObject){
+			//	summary:
+			//		Emulates firing an event for a given data value (specified by
+			//		an index) of a given series.
+			//	seriesName: String:
+			//		Series name.
+			//	eventName: String:
+			//		Event name to emulate.
+			//	index:	Number:
+			//		Valid data value index used to raise an event.
+			//	eventObject: Object?:
+			//		Optional event object. Especially useful for synthetic events.
+			//		Default: null.
+			var s = this._eventSeries[seriesName];
+			if(s && s.length && index < s.length){
+				var o = s[index];
 				o.type  = eventName;
-				o.event = e;
+				o.event = eventObject || null;
 				this.raiseEvent(o);
 				o.event = null;
-			})
-		});
-	},
-	_connectEvents: function(o){
-        if(o){
-            o.chart = this.chart;
-            o.plot  = this;
-            o.hAxis = this.hAxis || null;
-            o.vAxis = this.vAxis || null;
-            o.eventMask = o.eventMask || o.shape;
-            this._connectSingleEvent(o, "onmouseover");
-            this._connectSingleEvent(o, "onmouseout");
-            this._connectSingleEvent(o, "onclick");
-        }
-	},
-	_reconnectEvents: function(seriesName){
-		var a = this._eventSeries[seriesName];
-		if(a){
-			dojo.forEach(a, this._connectEvents, this);
-		}
-	},
-	fireEvent: function(seriesName, eventName, index, eventObject){
-		//	summary:
-		//		Emulates firing an event for a given data value (specified by
-		//		an index) of a given series.
-		//	seriesName: String:
-		//		Series name.
-		//	eventName: String:
-		//		Event name to emulate.
-		//	index:	Number:
-		//		Valid data value index used to raise an event.
-		//	eventObject: Object?:
-		//		Optional event object. Especially useful for synthetic events.
-		//		Default: null.
-		var s = this._eventSeries[seriesName];
-		if(s && s.length && index < s.length){
-			var o = s[index];
-			o.type  = eventName;
-			o.event = eventObject || null;
-			this.raiseEvent(o);
-			o.event = null;
+			}
 		}
-	}
+	});
 });
diff --git a/dojox/charting/plot2d/common.js b/dojox/charting/plot2d/common.js
index d03ba93..858138f 100644
--- a/dojox/charting/plot2d/common.js
+++ b/dojox/charting/plot2d/common.js
@@ -1,37 +1,35 @@
-dojo.provide("dojox.charting.plot2d.common");
-
-dojo.require("dojo.colors");
-dojo.require("dojox.gfx");
-dojo.require("dojox.lang.functional");
-
-(function(){
-	var df = dojox.lang.functional, dc = dojox.charting.plot2d.common;
-
-	dojo.mixin(dojox.charting.plot2d.common, {
+define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/Color", 
+		"dojox/gfx", "dojox/lang/functional", "../scaler/common"], 
+	function(lang, arr, Color, g, df, sc){
+	
+	var common = lang.getObject("dojox.charting.plot2d.common", true);
+	
+	return lang.mixin(common, {	
+		doIfLoaded: sc.doIfLoaded,
 		makeStroke: function(stroke){
 			if(!stroke){ return stroke; }
-			if(typeof stroke == "string" || stroke instanceof dojo.Color){
+			if(typeof stroke == "string" || stroke instanceof Color){
 				stroke = {color: stroke};
 			}
-			return dojox.gfx.makeParameters(dojox.gfx.defaultStroke, stroke);
+			return g.makeParameters(g.defaultStroke, stroke);
 		},
 		augmentColor: function(target, color){
-			var t = new dojo.Color(target),
-				c = new dojo.Color(color);
+			var t = new Color(target),
+				c = new Color(color);
 			c.a = t.a;
 			return c;
 		},
 		augmentStroke: function(stroke, color){
-			var s = dc.makeStroke(stroke);
+			var s = common.makeStroke(stroke);
 			if(s){
-				s.color = dc.augmentColor(s.color, color);
+				s.color = common.augmentColor(s.color, color);
 			}
 			return s;
 		},
 		augmentFill: function(fill, color){
-			var fc, c = new dojo.Color(color);
-			if(typeof fill == "string" || fill instanceof dojo.Color){
-				return dc.augmentColor(fill, color);
+			var fc, c = new Color(color);
+			if(typeof fill == "string" || fill instanceof Color){
+				return common.augmentColor(fill, color);
 			}
 			return fill;
 		},
@@ -42,7 +40,7 @@ dojo.require("dojox.lang.functional");
 		},
 
 		collectSimpleStats: function(series){
-			var stats = dojo.delegate(dc.defaultStats);
+			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++){
@@ -51,7 +49,7 @@ dojo.require("dojox.lang.functional");
 							// 1D case
 							var old_vmin = stats.vmin, old_vmax = stats.vmax;
 							if(!("ymin" in run) || !("ymax" in run)){
-								dojo.forEach(run.data, function(val, i){
+								arr.forEach(run.data, function(val, i){
 									if(val !== null){
 										var x = i + 1, y = val;
 										if(isNaN(y)){ y = 0; }
@@ -69,7 +67,7 @@ dojo.require("dojox.lang.functional");
 							var old_hmin = stats.hmin, old_hmax = stats.hmax,
 								old_vmin = stats.vmin, old_vmax = stats.vmax;
 							if(!("xmin" in run) || !("xmax" in run) || !("ymin" in run) || !("ymax" in run)){
-								dojo.forEach(run.data, function(val, i){
+								arr.forEach(run.data, function(val, i){
 									if(val !== null){
 										var x = "x" in val ? val.x : i + 1, y = val.y;
 										if(isNaN(x)){ x = 0; }
@@ -112,7 +110,7 @@ dojo.require("dojox.lang.functional");
 
 		collectStackedStats: function(series){
 			// collect statistics
-			var stats = dojo.clone(dc.defaultStats);
+			var stats = lang.clone(common.defaultStats);
 			if(series.length){
 				// 1st pass: find the maximal length of runs
 				stats.hmin = Math.min(stats.hmin, 1);
@@ -139,39 +137,39 @@ dojo.require("dojox.lang.functional");
 			//	FIX for #7235, submitted by Enzo Michelangeli.
 			//	Emulates the smoothing algorithms used in a famous, unnamed spreadsheet
 			//		program ;)
-			var arr = a.slice(0);
+			var array = a.slice(0);
 			if(tension == "x") {
-				arr[arr.length] = arr[0];   // add a last element equal to the first, closing the loop
+				array[array.length] = arr[0];   // add a last element equal to the first, closing the loop
 			}
-			var p=dojo.map(arr, function(item, i){
+			var p=arr.map(array, function(item, i){
 				if(i==0){ return "M" + item.x + "," + item.y; }
 				if(!isNaN(tension)) { // use standard Dojo smoothing in tension is numeric
-					var dx=item.x-arr[i-1].x, dy=arr[i-1].y;
+					var dx=item.x-array[i-1].x, dy=array[i-1].y;
 					return "C"+(item.x-(tension-1)*(dx/tension))+","+dy+" "+(item.x-(dx/tension))+","+item.y+" "+item.x+","+item.y;
 				} else if(tension == "X" || tension == "x" || tension == "S") {
 					// use Excel "line smoothing" algorithm (http://xlrotor.com/resources/files.shtml)
-					var p0, p1 = arr[i-1], p2 = arr[i], p3;
+					var p0, p1 = array[i-1], p2 = array[i], p3;
 					var bz1x, bz1y, bz2x, bz2y;
 					var f = 1/6;
 					if(i==1) {
 						if(tension == "x") {
-							p0 = arr[arr.length-2];
+							p0 = array[array.length-2];
 						} else { // "tension == X || tension == "S"
 							p0 = p1;
 						}
 						f = 1/3;
 					} else {
-						p0 = arr[i-2];
+						p0 = array[i-2];
 					}
-					if(i==(arr.length-1)) {
+					if(i==(array.length-1)) {
 						if(tension == "x") {
-							p3 = arr[1];
+							p3 = array[1];
 						} else { // "tension == X || tension == "S"
 							p3 = p2;
 						}
 						f = 1/3;
 					} else {
-						p3 = arr[i+1];
+						p3 = array[i+1];
 					}
 					var p1p2 = Math.sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));
 					var p0p2 = Math.sqrt((p2.x-p0.x)*(p2.x-p0.x)+(p2.y-p0.y)*(p2.y-p0.y));
@@ -207,11 +205,12 @@ dojo.require("dojox.lang.functional");
 		},
 		
 		getLabel: function(/*Number*/number, /*Boolean*/fixed, /*Number*/precision){
-			if(dojo.number){
-				return (fixed ? dojo.number.format(number, {places : precision}) :
-					dojo.number.format(number)) || "";
-			}
-			return fixed ? number.toFixed(precision) : number.toString();
+			return sc.doIfLoaded("dojo/number", function(numberLib){
+				return (fixed ? numberLib.format(number, {places : precision}) :
+					numberLib.format(number)) || "";
+			}, function(){
+				return fixed ? number.toFixed(precision) : number.toString();
+			});
 		}
 	});
-})();
+});
diff --git a/dojox/charting/plot3d/Bars.js b/dojox/charting/plot3d/Bars.js
index 88efc0c..7cceece 100644
--- a/dojox/charting/plot3d/Bars.js
+++ b/dojox/charting/plot3d/Bars.js
@@ -1,20 +1,19 @@
-dojo.provide("dojox.charting.plot3d.Bars");
-
-dojo.require("dojox.charting.plot3d.Base");
-
-(function(){
+define(["dojox/gfx3d", "dojo/_base/window", "dojo/_base/declare", "dojo/_base/Color", "./Base"], 
+	function(gfx3d, win, declare, Color, 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 || dojo.global;
+		a = typeof a == "string" ? a.split("") : a; o = o || win.global;
 		var z = a[0];
 		for(var i = 1; i < a.length; z = f.call(o, z, a[i++]));
 		return z;	// Object
 	};
-
-	dojo.declare("dojox.charting.plot3d.Bars", dojox.charting.plot3d.Base, {
+	/*=====
+	var Base = dojox.charting.plot3d.Base;
+	=====*/
+	return declare("dojox.charting.plot3d.Bars", Base, {
 		constructor: function(width, height, kwArgs){
 			this.depth = "auto";
 			this.gap   = 0;
@@ -25,7 +24,7 @@ dojo.require("dojox.charting.plot3d.Base");
 				if("gap"   in kwArgs){ this.gap   = kwArgs.gap; }
 				if("material" in kwArgs){
 					var m = kwArgs.material;
-					if(typeof m == "string" || m instanceof dojo.Color){
+					if(typeof m == "string" || m instanceof Color){
 						this.material.color = m;
 					}else{
 						this.material = m;
@@ -59,4 +58,4 @@ dojo.require("dojox.charting.plot3d.Base");
 			}
 		}
 	});
-})();
+});
diff --git a/dojox/charting/plot3d/Base.js b/dojox/charting/plot3d/Base.js
index 28b2b79..ab1b536 100644
--- a/dojox/charting/plot3d/Base.js
+++ b/dojox/charting/plot3d/Base.js
@@ -1,20 +1,19 @@
-dojo.provide("dojox.charting.plot3d.Base");
-
-dojo.require("dojox.charting.Chart3D");
-
-dojo.declare("dojox.charting.plot3d.Base", null, {
-	constructor: function(width, height, kwArgs){
-		this.width  = width;
-		this.height = height;
-	},
-	setData: function(data){
-		this.data = data ? data : [];
-		return this;
-	},
-	getDepth: function(){
-		return this.depth;
-	},
-	generate: function(chart, creator){
-	}
+define(["dojo/_base/declare"], 
+  function(declare) {
+	return declare("dojox.charting.plot3d.Base", null, {
+		constructor: function(width, height, kwArgs){
+			this.width  = width;
+			this.height = height;
+		},
+		setData: function(data){
+			this.data = data ? data : [];
+			return this;
+		},
+		getDepth: function(){
+			return this.depth;
+		},
+		generate: function(chart, creator){
+		}
+	});
 });
 
diff --git a/dojox/charting/plot3d/Cylinders.js b/dojox/charting/plot3d/Cylinders.js
index 117250c..8b63668 100644
--- a/dojox/charting/plot3d/Cylinders.js
+++ b/dojox/charting/plot3d/Cylinders.js
@@ -1,20 +1,19 @@
-dojo.provide("dojox.charting.plot3d.Cylinders");
-
-dojo.require("dojox.charting.plot3d.Base");
-
-(function(){
+define(["dojox/gfx3d", "dojox/gfx3d/matrix", "dojo/_base/declare", "dojo/_base/Color", "dojo/_base/window", "./Base"], 
+	function(gfx3d, matrix3d, declare, Color, win, 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 || dojo.global;
+		a = typeof a == "string" ? a.split("") : a; o = o || win.global;
 		var z = a[0];
 		for(var i = 1; i < a.length; z = f.call(o, z, a[i++]));
 		return z;	// Object
 	};
-
-	dojo.declare("dojox.charting.plot3d.Cylinders", dojox.charting.plot3d.Base, {
+	/*=====
+	var Base = dojox.charting.plot3d.Base;
+	=====*/
+	return declare("dojox.charting.plot3d.Cylinders", Base, {
 		constructor: function(width, height, kwArgs){
 			this.depth = "auto";
 			this.gap   = 0;
@@ -26,7 +25,7 @@ dojo.require("dojox.charting.plot3d.Base");
 				if("gap"   in kwArgs){ this.gap   = kwArgs.gap; }
 				if("material" in kwArgs){
 					var m = kwArgs.material;
-					if(typeof m == "string" || m instanceof dojo.Color){
+					if(typeof m == "string" || m instanceof Color){
 						this.material.color = m;
 					}else{
 						this.material = m;
@@ -57,10 +56,10 @@ dojo.require("dojox.charting.plot3d.Base");
 						radius: step / 2 - this.gap,
 						height: this.data[i] * scale
 					})
-					.setTransform(dojox.gfx3d.matrix.rotateXg(-90))
+					.setTransform(matrix3d.rotateXg(-90))
 					.setFill(this.material).setStroke(this.outline);
 			}
 		}
 	});
-})();
+});
 
diff --git a/dojox/charting/scaler/common.js b/dojox/charting/scaler/common.js
index 72b109f..af353cb 100644
--- a/dojox/charting/scaler/common.js
+++ b/dojox/charting/scaler/common.js
@@ -1,12 +1,29 @@
-dojo.provide("dojox.charting.scaler.common");
+define(["dojo/_base/lang"], function(lang){
 
-(function(){
 	var eq = function(/*Number*/ a, /*Number*/ b){
 		// summary: compare two FP numbers for equality
 		return Math.abs(a - b) <= 1e-6 * (Math.abs(a) + Math.abs(b));	// Boolean
 	};
 	
-	dojo.mixin(dojox.charting.scaler.common, {
+	var common = lang.getObject("dojox.charting.scaler.common", true);
+	
+	var testedModules = {};
+
+	return lang.mixin(common, {
+		doIfLoaded: function(moduleName, ifloaded, ifnotloaded){
+			if(testedModules[moduleName] == undefined){
+				try{
+					testedModules[moduleName] = require(moduleName);
+				}catch(e){
+					testedModules[moduleName] = null;
+				}
+			}
+			if(testedModules[moduleName]){
+				return ifloaded(testedModules[moduleName]);
+			}else{
+				return ifnotloaded();
+			}
+		},
 		findString: function(/*String*/ val, /*Array*/ text){
 			val = val.toLowerCase();
 			for(var i = 0; i < text.length; ++i){
@@ -16,12 +33,12 @@ dojo.provide("dojox.charting.scaler.common");
 		},
 		getNumericLabel: function(/*Number*/ number, /*Number*/ precision, /*Object*/ kwArgs){
 			var def = "";
-			if(dojo.number){
-				def = (kwArgs.fixed ? dojo.number.format(number, {places : precision < 0 ? -precision : 0}) :
-					dojo.number.format(number)) || "";
-			}else{
+			common.doIfLoaded("dojo/number", function(numberLib){
+				def = (kwArgs.fixed ? numberLib.format(number, {places : precision < 0 ? -precision : 0}) :
+					numberLib.format(number)) || "";
+			}, function(){
 				def = kwArgs.fixed ? number.toFixed(precision < 0 ? -precision : 0) : number.toString();
-			}
+			});
 			if(kwArgs.labelFunc){
 				var r = kwArgs.labelFunc(def, number, precision);
 				if(r){ return r; }
@@ -55,4 +72,4 @@ dojo.provide("dojox.charting.scaler.common");
 			return def;
 		}
 	});
-})();
+});
diff --git a/dojox/charting/scaler/linear.js b/dojox/charting/scaler/linear.js
index 4a86dd4..cb22f62 100644
--- a/dojox/charting/scaler/linear.js
+++ b/dojox/charting/scaler/linear.js
@@ -1,14 +1,13 @@
-dojo.provide("dojox.charting.scaler.linear");
-dojo.require("dojox.charting.scaler.common");
-
-(function(){
+define(["dojo/_base/lang", "./common"], 
+	function(lang, common){
+	var linear = lang.getObject("dojox.charting.scaler.linear", true);
+	
 	var deltaLimit = 3,	// pixels
-		dc = dojox.charting, dcs = dc.scaler, dcsc = dcs.common,
-		findString = dcsc.findString,
-		getLabel = dcsc.getNumericLabel;
+		findString = common.findString,
+		getLabel = common.getNumericLabel;
 	
 	var calcTicks = function(min, max, kwArgs, majorTick, minorTick, microTick, span){
-		kwArgs = dojo.delegate(kwArgs);
+		kwArgs = lang.delegate(kwArgs);
 		if(!majorTick){
 			if(kwArgs.fixUpper == "major"){ kwArgs.fixUpper = "minor"; }
 			if(kwArgs.fixLower == "major"){ kwArgs.fixLower = "minor"; }
@@ -88,11 +87,11 @@ dojo.require("dojox.charting.scaler.common");
 			},
 			minorPerMajor:	minorPerMajor,
 			microPerMinor:	microPerMinor,
-			scaler:			dcs.linear
+			scaler:			linear
 		};
 	};
 	
-	dojo.mixin(dojox.charting.scaler.linear, {
+	return lang.mixin(linear, {
 		buildScaler: function(/*Number*/ min, /*Number*/ max, /*Number*/ span, /*Object*/ kwArgs){
 			var h = {fixUpper: "none", fixLower: "none", natural: false};
 			if(kwArgs){
@@ -248,4 +247,4 @@ dojo.require("dojox.charting.scaler.common");
 			return function(x){ return x / scale + offset; };	// Function
 		}
 	});
-})();
+});
diff --git a/dojox/charting/scaler/primitive.js b/dojox/charting/scaler/primitive.js
index 4828815..11ab9ad 100644
--- a/dojox/charting/scaler/primitive.js
+++ b/dojox/charting/scaler/primitive.js
@@ -1,34 +1,36 @@
-dojo.provide("dojox.charting.scaler.primitive");
-
-dojox.charting.scaler.primitive = {
-	buildScaler: function(/*Number*/ min, /*Number*/ max, /*Number*/ span, /*Object*/ kwArgs){
-		if(min == max){
-			// artificially extend bounds
-			min -= 0.5;
-			max += 0.5;
-			// now the line will be centered
+define(["dojo/_base/lang"], 
+  function(lang){
+	var primitive = lang.getObject("dojox.charting.scaler.primitive", true);
+	return lang.mixin(primitive, {
+		buildScaler: function(/*Number*/ min, /*Number*/ max, /*Number*/ span, /*Object*/ kwArgs){
+			if(min == max){
+				// artificially extend bounds
+				min -= 0.5;
+				max += 0.5;
+				// now the line will be centered
+			}
+			return {
+				bounds: {
+					lower: min,
+					upper: max,
+					from:  min,
+					to:    max,
+					scale: span / (max - min),
+					span:  span
+				},
+				scaler: primitive
+			};
+		},
+		buildTicks: function(/*Object*/ scaler, /*Object*/ kwArgs){
+			return {major: [], minor: [], micro: []};	// Object
+		},
+		getTransformerFromModel: function(/*Object*/ scaler){
+			var offset = scaler.bounds.from, scale = scaler.bounds.scale;
+			return function(x){ return (x - offset) * scale; };	// Function
+		},
+		getTransformerFromPlot: function(/*Object*/ scaler){
+			var offset = scaler.bounds.from, scale = scaler.bounds.scale;
+			return function(x){ return x / scale + offset; };	// Function
 		}
-		return {
-			bounds: {
-				lower: min,
-				upper: max,
-				from:  min,
-				to:    max,
-				scale: span / (max - min),
-				span:  span
-			},
-			scaler: dojox.charting.scaler.primitive
-		};
-	},
-	buildTicks: function(/*Object*/ scaler, /*Object*/ kwArgs){
-		return {major: [], minor: [], micro: []};	// Object
-	},
-	getTransformerFromModel: function(/*Object*/ scaler){
-		var offset = scaler.bounds.from, scale = scaler.bounds.scale;
-		return function(x){ return (x - offset) * scale; };	// Function
-	},
-	getTransformerFromPlot: function(/*Object*/ scaler){
-		var offset = scaler.bounds.from, scale = scaler.bounds.scale;
-		return function(x){ return x / scale + offset; };	// Function
-	}
-};
+	});
+});
diff --git a/dojox/charting/tests/BidiSupport/bidi_ChartAxisTitle.html b/dojox/charting/tests/BidiSupport/bidi_ChartAxisTitle.html
new file mode 100644
index 0000000..9f2a968
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/bidi_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" djConfig="isDebug: true, parseOnLoad: 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");
+
+			dojo.require("dojox.charting.BidiSupport");
+
+			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
+						}).
+						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"}).
+					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</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/bidi_DataSeries.html b/dojox/charting/tests/BidiSupport/bidi_DataSeries.html
new file mode 100644
index 0000000..afe6ff3
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/bidi_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" djConfig="isDebug: false, parseOnLoad: 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");
+			
+			dojo.require("dojox.charting.BidiSupport");	
+			dojo.require("dojox.charting.widget.BidiSupport");
+		
+			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")).
+						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"))).
+						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"})).
+						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" dir="rtl"></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/bidi_DeclerativeChart.html b/dojox/charting/tests/BidiSupport/bidi_DeclerativeChart.html
new file mode 100644
index 0000000..4029daa
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/bidi_DeclerativeChart.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]>
+		<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" djConfig="isDebug: true, parseOnLoad: 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("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];
+
+			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" jsId="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;">
+						<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/bidi_Event2d.html b/dojox/charting/tests/BidiSupport/bidi_Event2d.html
new file mode 100644
index 0000000..fcd321d
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/bidi_Event2d.html
@@ -0,0 +1,249 @@
+<!--[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" djConfig="isDebug: 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");
+
+			dojo.require("dojox.charting.BidiSupport");
+			dojo.require("dojox.charting.widget.BidiSupport");
+			
+			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.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.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.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.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.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/bidi_Label_shortening.html b/dojox/charting/tests/BidiSupport/bidi_Label_shortening.html
new file mode 100644
index 0000000..5630cfa
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/bidi_Label_shortening.html
@@ -0,0 +1,233 @@
+<!--[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" djConfig="isDebug: true, parseOnLoad: 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");
+
+			dojo.require("dojox.charting.BidiSupport");
+			dojo.require("dojox.charting.widget.BidiSupport");
+
+			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"}).
+						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"}).
+						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"}).
+						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"}).
+						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" jsId="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;">
+						<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/bidi_Pie_smart_label.html b/dojox/charting/tests/BidiSupport/bidi_Pie_smart_label.html
new file mode 100644
index 0000000..9e70b2b
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/bidi_Pie_smart_label.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]>
+        <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" djConfig="parseOnLoad: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");
+			
+			dojo.require("dojox.charting.BidiSupport");
+			dojo.require("dojox.charting.widget.BidiSupport");
+
+            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.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.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/bidi_Pies.html b/dojox/charting/tests/BidiSupport/bidi_Pies.html
new file mode 100644
index 0000000..9eedbc5
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/bidi_Pies.html
@@ -0,0 +1,123 @@
+<!--[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" djConfig="isDebug: true, parseOnLoad: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");
+
+			dojo.require("dojox.charting.BidiSupport");
+
+			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.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.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.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/bidi_RotatedLabels.html b/dojox/charting/tests/BidiSupport/bidi_RotatedLabels.html
new file mode 100644
index 0000000..3840717
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/bidi_RotatedLabels.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>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" djConfig="isDebug: true, parseOnLoad: 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");
+
+			dojo.require("dojox.charting.BidiSupport");	
+
+			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
+					}).
+					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/bidi_SelectableLegend.html b/dojox/charting/tests/BidiSupport/bidi_SelectableLegend.html
new file mode 100644
index 0000000..25a6a91
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/bidi_SelectableLegend.html
@@ -0,0 +1,208 @@
+<!--[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" djConfig="isDebug: true, parseOnLoad: 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");
+			
+			dojo.require("dojox.charting.BidiSupport");
+			dojo.require("dojox.charting.widget.BidiSupport");
+			
+			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]).
+					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"}).
+					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."
+	                }]).
+					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}]).
+					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/bidi_SetTextDir.html b/dojox/charting/tests/BidiSupport/bidi_SetTextDir.html
new file mode 100644
index 0000000..27159fc
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/bidi_SetTextDir.html
@@ -0,0 +1,356 @@
+<!--[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" djConfig="isDebug: true, parseOnLoad: 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");
+
+
+			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];
+
+			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.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."
+							}]).
+							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" jsId="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;">
+						<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/bidi_Spider2d.html b/dojox/charting/tests/BidiSupport/bidi_Spider2d.html
new file mode 100644
index 0000000..38580fe
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/bidi_Spider2d.html
@@ -0,0 +1,274 @@
+<!--[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" djConfig="isDebug: 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");
+
+			dojo.require("dojox.charting.BidiSupport");
+			dojo.require("dojox.charting.widget.BidiSupport");
+			
+			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.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>
\ No newline at end of file
diff --git a/dojox/charting/tests/BidiSupport/module.js b/dojox/charting/tests/BidiSupport/module.js
new file mode 100644
index 0000000..ccbe92b
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/module.js
@@ -0,0 +1,31 @@
+dojo.provide("dojox.charting.tests.BidiSupport.module");
+
+try{
+
+	doh.registerUrl("dojox.charting.tests.BidiSupport.bidi_ChartAxisTitle", dojo.moduleUrl("dojox", "charting/tests/BidiSupport/bidi_ChartAxisTitle.html"));
+
+	doh.registerUrl("dojox.charting.tests.BidiSupport.bidi_DataSeries", dojo.moduleUrl("dojox", "charting/tests/BidiSupport/bidi_DataSeries.html"));
+
+	doh.registerUrl("dojox.charting.tests.BidiSupport.bidi_DeclerativeChart", dojo.moduleUrl("dojox", "charting/tests/BidiSupport/bidi_DeclerativeChart.html"));
+
+	doh.registerUrl("dojox.charting.tests.BidiSupport.bidi_Event2d", dojo.moduleUrl("dojox", "charting/tests/BidiSupport/bidi_Event2d.html"));
+
+	doh.registerUrl("dojox.charting.tests.BidiSupport.bidi_Label_shortening", dojo.moduleUrl("dojox", "charting/tests/BidiSupport/bidi_Label_shortening.html"));
+
+	doh.registerUrl("dojox.charting.tests.BidiSupport.bidi_Pie_smart_label", dojo.moduleUrl("dojox", "charting/tests/BidiSupport/bidi_Pie_smart_label.html"));
+
+	doh.registerUrl("dojox.charting.tests.BidiSupport.bidi_Pies", dojo.moduleUrl("dojox", "charting/tests/BidiSupport/bidi_Pies.html"));
+
+	doh.registerUrl("dojox.charting.tests.BidiSupport.bidi_RotatedLabels", dojo.moduleUrl("dojox", "charting/tests/BidiSupport/bidi_RotatedLabels.html"));
+
+	doh.registerUrl("dojox.charting.tests.BidiSupport.bidi_SelectableLegend", dojo.moduleUrl("dojox", "charting/tests/BidiSupport/bidi_SelectableLegend.html"));
+
+	doh.registerUrl("dojox.charting.tests.BidiSupport.bidi_SetTextDir", dojo.moduleUrl("dojox", "charting/tests/BidiSupport/bidi_SetTextDir.html"));
+
+	doh.registerUrl("dojox.charting.tests.BidiSupport.bidi_Spider2d", dojo.moduleUrl("dojox", "charting/tests/BidiSupport/bidi_Spider2d.html"));
+
+}catch(e){
+
+	doh.debug(e);
+
+}
\ No newline at end of file
diff --git a/dojox/charting/tests/BidiSupport/runTests.html b/dojox/charting/tests/BidiSupport/runTests.html
new file mode 100644
index 0000000..f0b7f55
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/runTests.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+
+<html>
+	<head>
+		<title>Inheritance Unit Test Runner</title>
+		<meta http-equiv="REFRESH" content="0;url=../../../../util/doh/runner.html?testModule=dojox.charting.tests.BidiSupport.module">
+	</head>
+	<body>
+		Redirecting to D.O.H runner.
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/stockHebrew.json b/dojox/charting/tests/BidiSupport/stockHebrew.json
new file mode 100644
index 0000000..7879515
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/stockHebrew.json
@@ -0,0 +1,8 @@
+{ "identifier": "symbol", "idAttribute":"symbol", "label": "symbol","items": [
+	{ "symbol":"\u05d0\u05d7\u05d3.", "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":"\u05e9\u05ea\u05d9\u05d9\u05dd.", "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":"Three.", "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":"Hello.", "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":"\u05e9\u05de\u05d9: Tal.", "name":"\u05d0\u05d5\u05e1\u05d8\u05d9\u05df.",		"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":"My name: \u05d8\u05dc.", "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 65cac10..17c4f7b 100644
--- a/dojox/charting/tests/Theme.js
+++ b/dojox/charting/tests/Theme.js
@@ -3,12 +3,12 @@ dojo.require("dojox.charting.Theme");
 dojo.require("dojox.charting.themes.PlotKit.blue");
 
 (function(){
-	var dxc=dojox.charting;
+	var dxc=dojox.charting, Theme = dxc.Theme;
 	var blue=dxc.themes.PlotKit.blue;
 	tests.register("dojox.charting.tests.Theme", [
 		function testDefineColor(t){
 			var args={ num:16, cache:false };
-			blue.defineColors(args);
+			Theme.defineColors(args);
 			var a=blue.colors;
 			var s="<table border=1>";
 			for(var i=0; i<a.length; i++){
@@ -22,7 +22,7 @@ dojo.require("dojox.charting.themes.PlotKit.blue");
 			doh.debug(s);
 
 			var args={ num:32, cache: false };
-			blue.defineColors(args);
+			Theme.defineColors(args);
 			var a=blue.colors;
 			var s="<table border=1 style=margin-top:12px;>";
 			for(var i=0; i<a.length; i++){
@@ -36,7 +36,7 @@ dojo.require("dojox.charting.themes.PlotKit.blue");
 			doh.debug(s);
 
 			var args={ saturation:20, num:32, cache:false };
-			blue.defineColors(args);
+			Theme.defineColors(args);
 			var a=blue.colors;
 			var s="<table border=1 style=margin-top:12px;>";
 			for(var i=0; i<a.length; i++){
@@ -50,7 +50,7 @@ dojo.require("dojox.charting.themes.PlotKit.blue");
 			doh.debug(s);
 
 			var args={ low:10, high:90, num:32, cache: false };
-			blue.defineColors(args);
+			Theme.defineColors(args);
 			var a=blue.colors;
 			var s="<table border=1 style=margin-top:12px;>";
 			for(var i=0; i<a.length; i++){
diff --git a/dojox/charting/tests/gradients/test_grad_bars1.html b/dojox/charting/tests/gradients/test_grad_bars1.html
index 91b3c07..e76be3a 100644
--- a/dojox/charting/tests/gradients/test_grad_bars1.html
+++ b/dojox/charting/tests/gradients/test_grad_bars1.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Bars #1</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_bars2.html b/dojox/charting/tests/gradients/test_grad_bars2.html
index e6ea3db..d80a23c 100644
--- a/dojox/charting/tests/gradients/test_grad_bars2.html
+++ b/dojox/charting/tests/gradients/test_grad_bars2.html
@@ -1,7 +1,20 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
+<![endif]>
     <title>Gradient: Bars #2</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_bars3.html b/dojox/charting/tests/gradients/test_grad_bars3.html
index 7062f80..b141962 100644
--- a/dojox/charting/tests/gradients/test_grad_bars3.html
+++ b/dojox/charting/tests/gradients/test_grad_bars3.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Bars #3</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_bars4.html b/dojox/charting/tests/gradients/test_grad_bars4.html
index 97e3847..ff142fc 100644
--- a/dojox/charting/tests/gradients/test_grad_bars4.html
+++ b/dojox/charting/tests/gradients/test_grad_bars4.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Bars #4</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_bars5.html b/dojox/charting/tests/gradients/test_grad_bars5.html
index a026ffc..7050854 100644
--- a/dojox/charting/tests/gradients/test_grad_bars5.html
+++ b/dojox/charting/tests/gradients/test_grad_bars5.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Bars #5</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_bubble1.html b/dojox/charting/tests/gradients/test_grad_bubble1.html
index 2c1af8f..0a2970b 100644
--- a/dojox/charting/tests/gradients/test_grad_bubble1.html
+++ b/dojox/charting/tests/gradients/test_grad_bubble1.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Bubble #1</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_bubble2.html b/dojox/charting/tests/gradients/test_grad_bubble2.html
index 9c255f3..1a8e564 100644
--- a/dojox/charting/tests/gradients/test_grad_bubble2.html
+++ b/dojox/charting/tests/gradients/test_grad_bubble2.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Bubble #2</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_bubble3.html b/dojox/charting/tests/gradients/test_grad_bubble3.html
index 0270586..ad32f44 100644
--- a/dojox/charting/tests/gradients/test_grad_bubble3.html
+++ b/dojox/charting/tests/gradients/test_grad_bubble3.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Bubble #3</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_bubble4.html b/dojox/charting/tests/gradients/test_grad_bubble4.html
index b7c53d2..824cc02 100644
--- a/dojox/charting/tests/gradients/test_grad_bubble4.html
+++ b/dojox/charting/tests/gradients/test_grad_bubble4.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Bubble #4</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_bubble6.html b/dojox/charting/tests/gradients/test_grad_bubble6.html
index a7e1c92..f68daf9 100644
--- a/dojox/charting/tests/gradients/test_grad_bubble6.html
+++ b/dojox/charting/tests/gradients/test_grad_bubble6.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Bubble #6</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_columns1.html b/dojox/charting/tests/gradients/test_grad_columns1.html
index a14fb0d..32aa555 100644
--- a/dojox/charting/tests/gradients/test_grad_columns1.html
+++ b/dojox/charting/tests/gradients/test_grad_columns1.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Columns #1</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_columns2.html b/dojox/charting/tests/gradients/test_grad_columns2.html
index f1e9a9b..a0f759e 100644
--- a/dojox/charting/tests/gradients/test_grad_columns2.html
+++ b/dojox/charting/tests/gradients/test_grad_columns2.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Columns #2</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_columns3.html b/dojox/charting/tests/gradients/test_grad_columns3.html
index b8dfcd8..cf3d5e1 100644
--- a/dojox/charting/tests/gradients/test_grad_columns3.html
+++ b/dojox/charting/tests/gradients/test_grad_columns3.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Columns #3</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_columns4.html b/dojox/charting/tests/gradients/test_grad_columns4.html
index 96103ee..cf8f404 100644
--- a/dojox/charting/tests/gradients/test_grad_columns4.html
+++ b/dojox/charting/tests/gradients/test_grad_columns4.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Columns #4</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_columns5.html b/dojox/charting/tests/gradients/test_grad_columns5.html
index 3ac0366..72e0edd 100644
--- a/dojox/charting/tests/gradients/test_grad_columns5.html
+++ b/dojox/charting/tests/gradients/test_grad_columns5.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Columns #5</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_pie1.html b/dojox/charting/tests/gradients/test_grad_pie1.html
index 04b4c3c..efa2120 100644
--- a/dojox/charting/tests/gradients/test_grad_pie1.html
+++ b/dojox/charting/tests/gradients/test_grad_pie1.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Pie #1</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_pie2.html b/dojox/charting/tests/gradients/test_grad_pie2.html
index ad9aad7..accfc7c 100644
--- a/dojox/charting/tests/gradients/test_grad_pie2.html
+++ b/dojox/charting/tests/gradients/test_grad_pie2.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Pie #2</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_pie3.html b/dojox/charting/tests/gradients/test_grad_pie3.html
index d76f7aa..f6cd7b2 100644
--- a/dojox/charting/tests/gradients/test_grad_pie3.html
+++ b/dojox/charting/tests/gradients/test_grad_pie3.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Pie #3</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_pie4.html b/dojox/charting/tests/gradients/test_grad_pie4.html
index ad892e6..a39816f 100644
--- a/dojox/charting/tests/gradients/test_grad_pie4.html
+++ b/dojox/charting/tests/gradients/test_grad_pie4.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Pie #4</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_pie7.html b/dojox/charting/tests/gradients/test_grad_pie7.html
index 2c62b35..4d13781 100644
--- a/dojox/charting/tests/gradients/test_grad_pie7.html
+++ b/dojox/charting/tests/gradients/test_grad_pie7.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Pie #7</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_pie8.html b/dojox/charting/tests/gradients/test_grad_pie8.html
index 4a79d1e..8b8d2a3 100644
--- a/dojox/charting/tests/gradients/test_grad_pie8.html
+++ b/dojox/charting/tests/gradients/test_grad_pie8.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Pie #8</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_pie9.html b/dojox/charting/tests/gradients/test_grad_pie9.html
index 86f035a..1330106 100644
--- a/dojox/charting/tests/gradients/test_grad_pie9.html
+++ b/dojox/charting/tests/gradients/test_grad_pie9.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Pie #9</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_pieA.html b/dojox/charting/tests/gradients/test_grad_pieA.html
index a365569..7c84bd5 100644
--- a/dojox/charting/tests/gradients/test_grad_pieA.html
+++ b/dojox/charting/tests/gradients/test_grad_pieA.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Pie #A</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_scatter1.html b/dojox/charting/tests/gradients/test_grad_scatter1.html
index f4b018a..c74ad93 100644
--- a/dojox/charting/tests/gradients/test_grad_scatter1.html
+++ b/dojox/charting/tests/gradients/test_grad_scatter1.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Scatter #1</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_scatter2.html b/dojox/charting/tests/gradients/test_grad_scatter2.html
index bd0d76c..677773f 100644
--- a/dojox/charting/tests/gradients/test_grad_scatter2.html
+++ b/dojox/charting/tests/gradients/test_grad_scatter2.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Scatter #2</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/gradients/test_grad_scatterB.html b/dojox/charting/tests/gradients/test_grad_scatterB.html
index dcef594..07dd891 100644
--- a/dojox/charting/tests/gradients/test_grad_scatterB.html
+++ b/dojox/charting/tests/gradients/test_grad_scatterB.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
     <title>Gradient: Scatter #2</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
diff --git a/dojox/charting/tests/test_DataChart.html b/dojox/charting/tests/test_DataChart.html
index 5f054f9..d319e67 100644
--- a/dojox/charting/tests/test_DataChart.html
+++ b/dojox/charting/tests/test_DataChart.html
@@ -1,54 +1,27 @@
+<!--[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>
-<head>
+<html lang="en">
+	<head>
+<![endif]>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <title>DataChart Test</title>
-<style type="text/css">
-	@import "../../../dojo/resources/dojo.css";
-	@import "../../../dijit/tests/css/dijitTests.css";
-	@import "../../../dijit/themes/tundra/form/Button.css";
-	@import "../../../dijit/themes/tundra/form/Common.css";
-	@import "../../../dijit/themes/tundra/Common.css";
-	@import "../../../dijit/themes/dijit.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;
-	}
-	
-	
-
-</style>
+<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">
-
+dojo.require("dojo.parser");
 dojo.require("dojox.charting.DataChart");
 dojo.require("dojo.data.ItemFileWriteStore");
 dojo.require("dijit.form.NumberSpinner");
@@ -114,6 +87,7 @@ makeSpinners = function(items){
 			constraints:{min:0, max:10,places:2},
 			className:"myField"
 		});
+		w.startup();
 		dojo.place('<label>'+nm+'</label>', dojo.byId("spinners"), "last")
 		dojo.place(w.domNode, "spinners", "last")
 	});
@@ -162,7 +136,7 @@ handleSpinner = function(){
 	}
 </style>
 </head>
-<body class="tundra">
+<body class="claro">
 	<h1>DataChart</h1>
 	<p>
 		DataChart extends dojox.charting.Chart2D and allows for a simple connection to a data store. When adding a store to a chart, it is necessary to also supply which
diff --git a/dojox/charting/tests/test_DataSeries.html b/dojox/charting/tests/test_DataSeries.html
index f0a927a..6a32de6 100644
--- a/dojox/charting/tests/test_DataSeries.html
+++ b/dojox/charting/tests/test_DataSeries.html
@@ -1,48 +1,26 @@
+<!--[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>
-<head>
-
+<html lang="en">
+	<head>
+<![endif]>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <title>DataSeries 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>
-	@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}
     
@@ -194,7 +172,7 @@
 
 </head>
 
-<body class="tundra">
+<body class="claro">
 	<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.
diff --git a/dojox/charting/tests/test_StoreSeries-amd.html b/dojox/charting/tests/test_StoreSeries-amd.html
new file mode 100644
index 0000000..8ab5e45
--- /dev/null
+++ b/dojox/charting/tests/test_StoreSeries-amd.html
@@ -0,0 +1,187 @@
+<!--[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, async: true"></script>
+<script>
+	require(["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,
+		Memory, Observable, NumberSpinner,
+		lang, arr, xhr, domConstruct, aspect){
+	
+	xhr.get({
+		url: "stock.json",
+		sync: true,
+		handleAs: "json"
+	}).then(function(data){
+		store = Observable(new Memory({data:data}));
+	});
+	
+	function addLegend(chart, node){
+		var legend = new Legend({chart: chart}, node);
+		aspect.after(chart, "render", lang.hitch(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: lang.replace(
+				templates[value],
+				arr.map(["symbol", "low", "price", "high"], function(field){
+					return object[field];
+				})
+			)
+		};
+	}
+	
+	var chartL, chartC, chartP;
+	
+	makeCharts = function(){
+		chartL = new Chart("lines").
+				setTheme(ThreeD).
+				addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, majorTickStep: 5}).
+				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");
+		new Magnify(chartL);
+		new Tooltip(chartL);
+
+		chartC = new Chart("cols").
+				setTheme(ThreeD).
+				addAxis("x", {natural: true}).
+				addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true}).
+				addPlot("default", {type: Columns}).
+				addSeries("Low", new StoreSeries(
+					store, {query: {}}, lang.hitch(null, valTrans, "low"))).
+				addSeries("Price", new StoreSeries(
+					store, {query: {}}, lang.hitch(null, valTrans, "price"))).
+				addSeries("High", new StoreSeries(
+					store, {query: {}}, lang.hitch(null, valTrans, "high"))).
+				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");
+		new Tooltip(chartP);
+		new MoveSlice(chartP);
+	};
+
+	makeSpinners = function(objects){
+		arr.forEach(objects, function(m){
+			var nm = m.symbol;
+			var num = m.price;
+			console.log(nm, num);
+			var w = new 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
+			});
+			domConstruct.place('<label>'+nm+'</label>', dojo.byId("spinners"), "last")
+			domConstruct.place(w.domNode, "spinners", "last")
+		});
+		
+		var labels = arr.map(objects, function(object, index){
+				return {
+					value: index + 1,
+					text:  object.symbol
+				}
+			});
+		chartC.addAxis("x", {natural: true, labels: labels}).render();
+	};
+	
+	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/test_StoreSeries.html b/dojox/charting/tests/test_StoreSeries.html
index c875411..d96d68d 100644
--- a/dojox/charting/tests/test_StoreSeries.html
+++ b/dojox/charting/tests/test_StoreSeries.html
@@ -1,48 +1,26 @@
+<!--[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>
-<head>
-
+<html lang="en">
+	<head>
+<![endif]>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <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>
-	@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}
     
@@ -201,7 +179,7 @@
 
 </head>
 
-<body class="tundra">
+<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.
diff --git a/dojox/charting/tests/test_anim2d.html b/dojox/charting/tests/test_anim2d.html
index 8490a18..de28697 100644
--- a/dojox/charting/tests/test_anim2d.html
+++ b/dojox/charting/tests/test_anim2d.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
 	<title>Chart 2D: Animation tests</title>
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
diff --git a/dojox/charting/tests/test_axes.html b/dojox/charting/tests/test_axes.html
index c143ff6..8e04038 100644
--- a/dojox/charting/tests/test_axes.html
+++ b/dojox/charting/tests/test_axes.html
@@ -1,8 +1,20 @@
+<!--[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>
-<head>
+<html lang="en">
+	<head>
+<![endif]>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <title>Testing Axes</title>
 <style type="text/css">
 	@import "../../../dojo/resources/dojo.css";
diff --git a/dojox/charting/tests/test_axisZoomControl.html b/dojox/charting/tests/test_axisZoomControl.html
index 8e4ed13..547ed7f 100644
--- a/dojox/charting/tests/test_axisZoomControl.html
+++ b/dojox/charting/tests/test_axisZoomControl.html
@@ -1,7 +1,19 @@
+<!--[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>
+<html lang="en">
 	<head>
-	    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<![endif]>
 		<title>Axis Zoom Control</title>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 		<style type="text/css">
diff --git a/dojox/charting/tests/test_bars.html b/dojox/charting/tests/test_bars.html
index 15c212e..d4ef677 100644
--- a/dojox/charting/tests/test_bars.html
+++ b/dojox/charting/tests/test_bars.html
@@ -1,17 +1,26 @@
-<!DOCTYPE HTML>
-<html>
-<head>
+<!--[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" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <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" djConfig="isDebug: true"></script>
-<script type="text/javascript" src="../Chart3D.js"></script>
-<script type="text/javascript" src="../plot3d/Base.js"></script>
-<script type="text/javascript" src="../plot3d/Bars.js"></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
new file mode 100644
index 0000000..bf7f2e1
--- /dev/null
+++ b/dojox/charting/tests/test_chart2d-amd.html
@@ -0,0 +1,856 @@
+<!--[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"></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){
+		
+		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 ] ).
+						render();
+				}
+			},
+			{
+				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]} }).
+						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 }
+						]).
+						render();
+				}
+			},
+			{
+				description: "Lines, calculated labels",
+				makeChart: function(node){
+					(new dojox.charting.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 ]).
+						render();
+				}
+			},
+			{
+				description: "Lines, pre-computed labels",
+				makeChart: function(node){
+					(new dojox.charting.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 ]).
+						render();
+				}
+			},
+			{
+				description: "Defaults: lines, no axes.",
+				makeChart: function(node){
+					(new dojox.charting.Chart(node)).
+						addSeries("Series A", [ 1, 2, 1, 2, 1, 2, 1 ]).
+						addSeries("Series B", [ 2, 1, 2, 1, 2, 1, 2 ]).
+						render();
+				}
+			},
+			{
+				description: "Defaults: lines, no axes, and custom strokes.",
+				makeChart: function(node){
+					(new dojox.charting.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();
+				}
+			},
+			{
+				description: "Areas, Happy theme, no axes.",
+				makeChart: function(node){
+					(new dojox.charting.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();
+				}
+			},
+			{
+				description: "Areas, no axes, custom strokes and fills.",
+				makeChart: function(node){
+					(new dojox.charting.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"
+							}
+						).
+						render();
+				}
+			},
+			{
+				description: "Lines, axes, blue theme.",
+				makeChart: function(node){
+					(new dojox.charting.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]).
+						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]).
+						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]).
+						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]).
+						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"
+							}
+						).
+						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: 2, color: [0, 0, 0, 0.3]}
+						}).
+						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"
+							}
+						).
+						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"
+							}
+						).
+						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" }
+						).
+						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" }
+						).
+						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" }
+						).
+						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" }).
+						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" }).
+						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" }).
+						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" }
+						).
+						render();
+				}
+			},
+			{
+				description: "Stacked bars, no axes, custom strokes and fills.",
+				makeChart: function(node){
+					(new Chart(node)).
+						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" }).
+						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"}).
+						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" }).
+						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" }
+						).
+						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" }
+						).
+						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" }
+						).
+						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" }
+						).
+						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" }
+						).
+						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" }
+						).
+						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 }
+						}).
+						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 },
+							{ 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 }
+						]).
+						render();
+				}
+			},
+			{
+				description: "Scatter chart, custom axis, purple theme.",
+				makeChart: function(node){
+					(new Chart(node)).
+						setTheme(dojox.charting.themes.Ireland).
+						addPlot("default", {type: "Scatter"}).
+						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 },
+							{ 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 }
+						]).
+						render();
+				}
+			},
+			{
+				description: "Markers, lines, 2D data, custom axis, blue theme.",
+				makeChart: function(node){
+					(new Chart(node)).
+						setTheme(dojox.charting.themes.PlotKit.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 }
+						}).
+						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 },
+							{ 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 }
+						]).
+						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/test_chart2d.html b/dojox/charting/tests/test_chart2d.html
index ffd8a1d..e2567ad 100644
--- a/dojox/charting/tests/test_chart2d.html
+++ b/dojox/charting/tests/test_chart2d.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
 	<title>Chart 2D</title>
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
@@ -9,7 +21,6 @@
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
 	<script type="text/javascript">
-
         dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Default");
diff --git a/dojox/charting/tests/test_chart2d_dynamics.html b/dojox/charting/tests/test_chart2d_dynamics.html
index 96d6398..a7f634b 100644
--- a/dojox/charting/tests/test_chart2d_dynamics.html
+++ b/dojox/charting/tests/test_chart2d_dynamics.html
@@ -1,8 +1,20 @@
+<!--[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>
-<head>
+<html lang="en">
+	<head>
+<![endif]>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <title>Chart 2D: dynamics</title>
 <style type="text/css">
 	@import "../../../dojo/resources/dojo.css";
@@ -35,6 +47,8 @@ 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(){
@@ -148,6 +162,8 @@ addSeries = function(n){
 </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>
diff --git a/dojox/charting/tests/test_chart2d_updating.html b/dojox/charting/tests/test_chart2d_updating.html
index b74ed07..873296a 100644
--- a/dojox/charting/tests/test_chart2d_updating.html
+++ b/dojox/charting/tests/test_chart2d_updating.html
@@ -1,7 +1,19 @@
+<!--[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>
-<head>
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<html lang="en">
+	<head>
+<![endif]>
 	<title>Chart 2D</title>
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
diff --git a/dojox/charting/tests/test_chartAxisTitle.html b/dojox/charting/tests/test_chartAxisTitle.html
index 1b59dda..8038af6 100644
--- a/dojox/charting/tests/test_chartAxisTitle.html
+++ b/dojox/charting/tests/test_chartAxisTitle.html
@@ -1,8 +1,20 @@
+<!--[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>
-<head>
+<html lang="en">
+	<head>
+<![endif]>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <title>Chart2D Title</title>
 <style type="text/css">
 	@import "../../../dojo/resources/dojo.css";
@@ -44,7 +56,7 @@ 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;
 
 updateAxis = function(){
diff --git a/dojox/charting/tests/test_chartTitle.html b/dojox/charting/tests/test_chartTitle.html
index e1becad..962967e 100644
--- a/dojox/charting/tests/test_chartTitle.html
+++ b/dojox/charting/tests/test_chartTitle.html
@@ -1,8 +1,20 @@
+<!--[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>
-<head>
+<html lang="en">
+	<head>
+<![endif]>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <title>Chart2D Title</title>
 <style type="text/css">
 	@import "../../../dojo/resources/dojo.css";
@@ -24,6 +36,7 @@ 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;
 
diff --git a/dojox/charting/tests/test_chartingsize.html b/dojox/charting/tests/test_chartingsize.html
new file mode 100644
index 0000000..5c8288e
--- /dev/null
+++ b/dojox/charting/tests/test_chartingsize.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]>
+		<title>Test charting sizing</title>
+		<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>		
+		<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>
+		<div dojoType="dijit.layout.BorderContainer" design="sidebar" gutters="false"
+			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>
+				<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>
\ No newline at end of file
diff --git a/dojox/charting/tests/test_cylinders.html b/dojox/charting/tests/test_cylinders.html
index c72c71a..c8c358c 100644
--- a/dojox/charting/tests/test_cylinders.html
+++ b/dojox/charting/tests/test_cylinders.html
@@ -1,17 +1,26 @@
-<!DOCTYPE HTML>
-<html>
-<head>
+<!--[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" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <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" djConfig="isDebug: true"></script>
-<script type="text/javascript" src="../Chart3D.js"></script>
-<script type="text/javascript" src="../plot3d/Base.js"></script>
-<script type="text/javascript" src="../plot3d/Cylinders.js"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.charting.Chart3D");
diff --git a/dojox/charting/tests/test_event2d.html b/dojox/charting/tests/test_event2d.html
index 0e8a2fe..c89fd15 100644
--- a/dojox/charting/tests/test_event2d.html
+++ b/dojox/charting/tests/test_event2d.html
@@ -1,8 +1,20 @@
+<!--[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>
-<head>
+<html lang="en">
+	<head>
+<![endif]>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <title>Event 2D</title>
 <style type="text/css">
 	@import "../../../dojo/resources/dojo.css";
diff --git a/dojox/charting/tests/test_fillstroke.html b/dojox/charting/tests/test_fillstroke.html
new file mode 100644
index 0000000..c904611
--- /dev/null
+++ b/dojox/charting/tests/test_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" djConfig="isDebug: 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/test_fireEvent.html b/dojox/charting/tests/test_fireEvent.html
index e83e5a5..3cf97e6 100644
--- a/dojox/charting/tests/test_fireEvent.html
+++ b/dojox/charting/tests/test_fireEvent.html
@@ -1,8 +1,20 @@
+<!--[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>
-<head>
+<html lang="en">
+	<head>
+<![endif]>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <title>Chart 2D: fireEvent test</title>
 <style type="text/css">
 	@import "../../../dojo/resources/dojo.css";
@@ -46,6 +58,8 @@ 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>";
 
 
@@ -88,7 +102,7 @@ function getZeroes(){
 var actions = [];
 
 function addActions(chart){
-	dojox.lang.functional.forEach(actions, ".destroy()");
+	dojox.lang.functional.forEach(actions, ".disconnect()");
 	actions = [
 		new dojox.charting.action2d.Highlight(chart),
 		new dojox.charting.action2d.Magnify(chart),
diff --git a/dojox/charting/tests/test_label_shortening.html b/dojox/charting/tests/test_label_shortening.html
index 70255b2..c017740 100644
--- a/dojox/charting/tests/test_label_shortening.html
+++ b/dojox/charting/tests/test_label_shortening.html
@@ -1,8 +1,20 @@
+<!--[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>
-<head>
+<html lang="en">
+	<head>
+<![endif]>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <title>Chart 2D labels shortening</title>
 <style type="text/css">
 	@import "../../../dojo/resources/dojo.css";
@@ -18,7 +30,6 @@ 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");
 
 makeObjects = function(){
 
diff --git a/dojox/charting/tests/test_labels2d.html b/dojox/charting/tests/test_labels2d.html
index add8c03..44b1f5d 100644
--- a/dojox/charting/tests/test_labels2d.html
+++ b/dojox/charting/tests/test_labels2d.html
@@ -1,8 +1,20 @@
+<!--[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>
-<head>
+<html lang="en">
+	<head>
+<![endif]>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <title>Chart 2D labels</title>
 <style type="text/css">
 	@import "../../../dojo/resources/dojo.css";
diff --git a/dojox/charting/tests/test_mouseIndicator.html b/dojox/charting/tests/test_mouseIndicator.html
new file mode 100644
index 0000000..6ce0e79
--- /dev/null
+++ b/dojox/charting/tests/test_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"
+	djConfig="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.action2d.MouseIndicator");
+			
+			var chart;
+			makeObjects = function(){
+				chart = new dojox.charting.Chart("chart");
+				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", [
+					 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" });
+				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/test_mouseIndicator2.html b/dojox/charting/tests/test_mouseIndicator2.html
new file mode 100644
index 0000000..0bd61d4
--- /dev/null
+++ b/dojox/charting/tests/test_mouseIndicator2.html
@@ -0,0 +1,70 @@
+<!--[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" djConfig="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.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);
+			
+		</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/test_mouseZoomAndPan.html b/dojox/charting/tests/test_mouseZoomAndPan.html
new file mode 100644
index 0000000..b48edca
--- /dev/null
+++ b/dojox/charting/tests/test_mouseZoomAndPan.html
@@ -0,0 +1,80 @@
+<!--[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" djConfig="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.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: "grey", 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,
+					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",
+					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.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/test_nulls.html b/dojox/charting/tests/test_nulls.html
index f18d781..d2c8ffd 100644
--- a/dojox/charting/tests/test_nulls.html
+++ b/dojox/charting/tests/test_nulls.html
@@ -1,9 +1,21 @@
+<!--[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>
-<head>
+<html lang="en">
+	<head>
+<![endif]>
 <title>Chart 2D nulls</title>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <style>
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
diff --git a/dojox/charting/tests/test_pie2d.html b/dojox/charting/tests/test_pie2d.html
index f4125a4..6142bf4 100644
--- a/dojox/charting/tests/test_pie2d.html
+++ b/dojox/charting/tests/test_pie2d.html
@@ -1,8 +1,20 @@
+<!--[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>
-<head>
+<html lang="en">
+	<head>
+<![endif]>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <title>Pie 2D</title>
 <style type="text/css">
 	@import "../../../dojo/resources/dojo.css";
diff --git a/dojox/charting/tests/test_pie2d_zeroslice.html b/dojox/charting/tests/test_pie2d_zeroslice.html
new file mode 100644
index 0000000..3b3d20e
--- /dev/null
+++ b/dojox/charting/tests/test_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" djConfig="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: "white",
+		labelOffset: 40
+	});
+	chart1.addSeries("Series A", [4, 3, 0, 2]);
+	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/test_pie_smart_label.html b/dojox/charting/tests/test_pie_smart_label.html
index 3f96c52..0521aac 100644
--- a/dojox/charting/tests/test_pie_smart_label.html
+++ b/dojox/charting/tests/test_pie_smart_label.html
@@ -1,6 +1,19 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
+<!--[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">
diff --git a/dojox/charting/tests/test_plot_order.html b/dojox/charting/tests/test_plot_order.html
index cf27e14..a56ebbe 100644
--- a/dojox/charting/tests/test_plot_order.html
+++ b/dojox/charting/tests/test_plot_order.html
@@ -1,8 +1,20 @@
+<!--[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>
-<head>
+<html lang="en">
+	<head>
+<![endif]>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <title>Testing plot order</title>
 <style type="text/css">
 	@import "../../../dojo/resources/dojo.css";
diff --git a/dojox/charting/tests/test_rotatedLabels.html b/dojox/charting/tests/test_rotatedLabels.html
index b4a2f95..063f177 100644
--- a/dojox/charting/tests/test_rotatedLabels.html
+++ b/dojox/charting/tests/test_rotatedLabels.html
@@ -1,8 +1,20 @@
+<!--[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>
-<head>
+<html lang="en">
+	<head>
+<![endif]>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <title>Chart 2D rotated labels</title>
 <style type="text/css">
 	@import "../../../dojo/resources/dojo.css";
@@ -20,6 +32,8 @@ dojo.require("dojox.charting.axis2d.Default");
 dojo.require("dojox.charting.plot2d.Default");
 dojo.require("dojox.charting.themes.PrimaryColors");
 
+dojo.require("dojo.parser");
+
 var chart;
 
 makeObjects = function(){
diff --git a/dojox/charting/tests/test_scaler.html b/dojox/charting/tests/test_scaler.html
index 1a49f73..5402d33 100644
--- a/dojox/charting/tests/test_scaler.html
+++ b/dojox/charting/tests/test_scaler.html
@@ -1,8 +1,20 @@
-<!DOCTYPE HTML>
-<html>
-<head>
+<!--[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" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <title>Scaler/tick generator</title>
 <style type="text/css">
 	@import "../../../dojo/resources/dojo.css";
diff --git a/dojox/charting/tests/test_selectableLegend.html b/dojox/charting/tests/test_selectableLegend.html
index 2b10dcd..b3828a5 100644
--- a/dojox/charting/tests/test_selectableLegend.html
+++ b/dojox/charting/tests/test_selectableLegend.html
@@ -1,6 +1,19 @@
-<!DOCTYPE HTML>
-<html>
+<!--[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">
diff --git a/dojox/charting/tests/test_series_order.html b/dojox/charting/tests/test_series_order.html
index 702dcfd..c3cbfd3 100644
--- a/dojox/charting/tests/test_series_order.html
+++ b/dojox/charting/tests/test_series_order.html
@@ -1,8 +1,20 @@
+<!--[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>
-<head>
+<html lang="en">
+	<head>
+<![endif]>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <title>Testing series order</title>
 <style type="text/css">
 	@import "../../../dojo/resources/dojo.css";
diff --git a/dojox/charting/tests/test_sparklines.html b/dojox/charting/tests/test_sparklines.html
index e155f66..6341da4 100644
--- a/dojox/charting/tests/test_sparklines.html
+++ b/dojox/charting/tests/test_sparklines.html
@@ -1,7 +1,19 @@
+<!--[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>
+<html lang="en">
 	<head>
-	    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<![endif]>
 		<title>Chart 2D -- Sparklines Edition</title>
 		<style type="text/css">
 			@import "../../../dojo/resources/dojo.css";
@@ -16,7 +28,6 @@
 		<script type="text/javascript" src="../../../dojo/dojo.js" 
 			djConfig="isDebug: false, parseOnLoad: true"></script>
 		<script type="text/javascript">
-            dojo.require("dojox.charting.widget.Chart2D");
             dojo.require("dojox.charting.plot2d.Lines");
             dojo.require("dojox.charting.plot2d.Areas");
 			dojo.require("dojox.charting.widget.Sparkline");
@@ -55,7 +66,7 @@
 					Simple Sparkline:
 				</td>
 				<td>
-					<div dojoType="dojox.charting.widget.Chart2D" 
+					<div dojoType="dojox.charting.widget.Chart" 
 						theme="dojox.charting.themes.Tufte" 
 						margins="{ l: 0, r: 0, t: 0, b: 0 }"
 						style="width: 100px; height: 15px;">
@@ -75,7 +86,7 @@
 
 					<div dojoType="dojox.data.CsvStore" jsId="googStore" 
 						url="data/goog_prices.csv"></div>
-					<div dojoType="dojox.charting.widget.Chart2D" 
+					<div dojoType="dojox.charting.widget.Chart" 
 						theme="dojox.charting.themes.Tufte" 
 						margins="{ l: 0, r: 0, t: 0, b: 0 }"
 						style="width: 100px; height: 15px;">
@@ -114,7 +125,7 @@
 
 					<div dojoType="dojox.data.CsvStore" jsId="yahooStore" 
 						url="data/yahoo_prices.csv"></div>
-					<div dojoType="dojox.charting.widget.Chart2D" 
+					<div dojoType="dojox.charting.widget.Chart" 
 						theme="dojox.charting.themes.Tufte" 
 						margins="{ l: 0, r: 0, t: 0, b: 0 }"
 						style="width: 100px; height: 15px;">
@@ -151,7 +162,7 @@
 				<td>
 					<div dojoType="dojox.data.CsvStore" jsId="msftStore" 
 						url="data/msft_prices.csv"></div>
-					<div dojoType="dojox.charting.widget.Chart2D" 
+					<div dojoType="dojox.charting.widget.Chart" 
 						theme="dojox.charting.themes.Tufte" 
 						margins="{ l: 0, r: 0, t: 0, b: 0 }"
 						style="width: 100px; height: 15px;">
diff --git a/dojox/charting/tests/test_spider2d.html b/dojox/charting/tests/test_spider2d.html
index e48c1b6..e549cdc 100644
--- a/dojox/charting/tests/test_spider2d.html
+++ b/dojox/charting/tests/test_spider2d.html
@@ -1,8 +1,20 @@
+<!--[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>
-<head>
+<html lang="en">
+	<head>
+<![endif]>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <title>Spider 2D</title>
 <style type="text/css">
 	@import "../../../dojo/resources/dojo.css";
diff --git a/dojox/charting/tests/test_tension.html b/dojox/charting/tests/test_tension.html
index a33798f..3f95b68 100644
--- a/dojox/charting/tests/test_tension.html
+++ b/dojox/charting/tests/test_tension.html
@@ -1,8 +1,20 @@
+<!--[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>
-<head>
+<html lang="en">
+	<head>
+<![endif]>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
     <title>Tension test.</title>
     <style>
         @import "../../../dojo/resources/dojo.css";
diff --git a/dojox/charting/tests/test_themes-amd.html b/dojox/charting/tests/test_themes-amd.html
new file mode 100644
index 0000000..cab1ba7
--- /dev/null
+++ b/dojox/charting/tests/test_themes-amd.html
@@ -0,0 +1,316 @@
+<!--[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>Example Dojo Chart Types</title>
+<style>
+	@import "../../../dojo/resources/dojo.css";
+	@import "../../../dijit/tests/css/dijitTests.css";
+	#chartContainer {
+		position: relative;
+		height: 660px;
+	}
+	.chart {
+		position: absolute;
+		top:	0;
+		left:	0;
+		width:	300px;
+		height: 200px;
+	}
+	#lines, #area, #columns {
+		left: 320px;
+	}
+	#bubbles, #area, #pieLin {
+		top: 220px;
+	}
+	#pieLin, #pieFan, #ohlc {
+		left:  640px;
+	}
+	#candle, #columns, #ohlc {
+		top: 440px;
+	}
+
+</style>
+<script src="../../../dojo/dojo.js" data-dojo-config="isDebug: false, async: true, gfxRenderer: 'svg,silverlight,vml,canvas'"></script>
+<script>
+	require(["dojo/_base/window", "dojo/dom", "dojo/dom-construct", "dojo/dom-style", "dojo/ready", "dojo/on", "dojo/query", 
+		"dojox/charting/Chart", "dojox/charting/axis2d/Default", "dojox/charting/plot2d/ClusteredBars",
+		"dojox/charting/plot2d/ClusteredColumns", "dojox/charting/plot2d/Default", "dojox/charting/plot2d/StackedAreas",
+		"dojox/charting/plot2d/Bubble", "dojox/charting/plot2d/Candlesticks", "dojox/charting/plot2d/OHLC",
+		"dojox/charting/plot2d/Pie"], 
+		function(win, dom, domConstruct, domStyle, ready, on, query, Chart, Default, ClusteredBars,
+			ClusteredColumns, Lines, StackedAreas, Bubble, Candlesticks, OHLC, Pie){
+	
+		var charts = {}, backgroundImage, backgroundColor, color, lastThemeName = "";
+	
+		function update(name){
+			// change the theme based on the select change.
+			var select = dom.byId("themeChooser"),
+				usePageStyle = dom.byId("pageStyleChooser").checked;
+	
+			var test = false;
+			if(name){
+				//	make sure it's in the list first.
+				for(var i=0, l=select.options.length; i<l; i++){
+					if(select.options[i].value == name){
+						select.options[i].selected = true;
+						test = true;
+						break;
+					}
+				}
+			}
+	
+			if(!test){
+				name = select.options[select.selectedIndex].value;
+			}
+			
+			require(["dojox/charting/themes/" + name.replace(".", "/")], function(theme){
+	
+				var chartStyle = theme.chart;
+		
+				// set the suggested page style
+				if(usePageStyle && chartStyle.pageStyle){
+					domStyle.set(win.body(), chartStyle.pageStyle);
+				}else{
+					domStyle.set(win.body(), {
+						backgroundColor: backgroundColor,
+						backgroundImage: backgroundImage,
+						color: color
+					});
+				}
+				// set the theme
+				if(lastThemeName != name){
+					lastThemeName = name;
+					if(theme){
+						for(var chartName in charts){
+							charts[chartName].setTheme(theme).render();
+						}
+					}
+				}
+			});
+		}
+	
+		function init(){
+			// retrieve initial values for fg/bg
+			backgroundImage = domStyle.get(win.body(), "backgroundImage");
+			backgroundColor = domStyle.get(win.body(), "backgroundColor");
+			color = domStyle.get(win.body(), "color");
+	
+			charts.bars = new Chart("bars").
+				addAxis("y", {fixLower: "minor", fixUpper: "minor", natural: true}).
+				addAxis("x", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true}).
+				addPlot("default", {type: ClusteredBars, gap: 5}).
+				addSeries("Series A", [0.53, 0.51]).
+				addSeries("Series B", [0.84, 0.79]).
+				addSeries("Series C", [0.68, 0.95]).
+				addSeries("Series D", [0.77, 0.66]);
+	
+			charts.columns = new Chart("columns").
+				addAxis("x", {fixLower: "minor", fixUpper: "minor", natural: true}).
+				addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true}).
+				addPlot("default", {type: ClusteredColumns, gap: 5}).
+				addSeries("Series A", [0.53, 0.51]).
+				addSeries("Series B", [0.84, 0.79]).
+				addSeries("Series C", [0.68, 0.95]).
+				addSeries("Series D", [0.77, 0.66]);
+	
+			charts.lines = new Chart("lines").
+				addAxis("x", {min: 0, max: 6, fixLower: "minor", fixUpper: "minor", natural: true}).
+				addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true, max: 1}).
+				addPlot("default", {type: Lines, lines: true, markers: true, tension: "X"}).
+				addSeries("Series A", [{x: 0.5, y: 0.2}, {x: 1.5, y: 0.4}, {x: 2.0, y: 0.1}, {x: 5.0, y: 0.9}]).
+				addSeries("Series B", [{x: 0.3, y: 0.6}, {x: 3.0, y: 0.5}, {x: 4.0, y: 0.9}, {x: 5.5, y: 0.7}]).
+				addSeries("Series C", [{x: 0.8, y: 0.8}, {x: 3.4, y: 0.2}, {x: 5.3, y: 0.3}]).
+				addSeries("Series D", [{x: 0.6, y: 0.9}, {x: 3.2, y: 0.8}, {x: 5.0, y: 0.1}]);
+	
+			charts.pieFan = new Chart("pieFan").
+				addPlot("default", {type: Pie, radius: 60, labelOffset: -20, radGrad: dojox.gfx.renderer == "vml" ? "fan" : "native"}).
+				addSeries("Series A", [0.35, 0.25, 0.42, 0.53, 0.69]);
+	
+			charts.bubbles = new Chart("bubbles").
+				addAxis("x", {min: 0, max: 6, fixLower: "minor", fixUpper: "minor", natural: true}).
+				addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true}).
+				addPlot("default", {type: Bubble}).
+				addSeries("Series A", [{x: 0.5, y: 5.0, size: 1.4}, {x: 1.5, y: 1.5, size: 4.5}, {x: 2.0, y: 9.0, size: 1.5}, {x: 5.0, y: 0.3, size: 0.8}]).
+				addSeries("Series B", [{x: 0.3, y: 8.0, size: 2.5}, {x: 4.0, y: 6.0, size: 2.1}, {x: 5.5, y: 2.0, size: 3.2}]).
+				addSeries("Series C", [{x: 2.0, y: 5.5, size: 2.5}, {x: 3.5, y: 2.5, size: 3.5}, {x: 5.2, y: 7.0, size: 3.0}]).
+				addSeries("Series D", [{x: 3.2, y: 8.0, size: 2.0}]);
+	
+			charts.area = new Chart("area").
+				addAxis("x", {fixLower: "major", fixUpper: "major"}).
+				addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", min: 0}).
+				addPlot("default", {type: StackedAreas, tension: "X"}).
+				addSeries("Series A", [-2, 1.1, 1.2, 1.3, 1.4, 1.5, -1.6]).
+				addSeries("Series B", [1, 1.6, 1.3, 1.4, 1.1, 1.5, 1.1]).
+				addSeries("Series C", [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6]);
+	
+			charts.pieLin = new Chart("pieLin").
+				addPlot("default", {type: Pie, radius: 60, labelOffset: -20, radGrad: "linear"}).
+				addSeries("Series A", [0.35, 0.25, 0.42, 0.53, 0.69]);
+	
+			charts.candle = new Chart("candle").
+				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 }]);
+			charts.ohlc = new Chart("ohlc").
+				addPlot("default", {type: OHLC, 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 },
+						{ 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 }]);
+			var name;
+			if(window.location.search.indexOf("?")>-1){
+				name = window.location.search.substring(1);
+				domConstruct.create("span", {
+					style: "display: inline-block; margin-left: 1em;",
+					innerHTML: '<a href="theme_preview-amd.html">Back to the Theme Previewer »»</a>'
+				}, query("p.controls")[0]);
+			}
+	
+			update(name);
+	
+			on(dom.byId("themeChooser"), "change", update);
+			on(dom.byId("pageStyleChooser"), "click", update);
+		}
+		ready(init);
+	});
+</script>
+</head>
+<body>
+	<h1>Example Dojo Chart Types</h1>
+	<p>Choose a theme from the list below, a theme will be loaded dynamically, and the charts will be rendered using it.</p>
+	<p class="controls"><label for="themeChooser">Available themes: </label>
+		<select id="themeChooser">
+			<optgroup label="Gradients">
+				<option value="Julie" selected="selected">Julie</option>
+				<option value="ThreeD">ThreeD</option>
+				<option value="Chris">Chris</option>
+				<option value="Tom">Tom</option>
+				<option value="Claro">Claro</option>
+				<option value="PrimaryColors">PrimaryColors</option>
+				<option value="Electric">Electric</option>
+				<option value="Charged">Charged</option>
+				<option value="Renkoo">Renkoo</option>
+			</optgroup>
+			<optgroup label="Classic">
+				<option value="Adobebricks">Adobebricks</option>
+				<option value="Algae">Algae</option>
+				<option value="Bahamation">Bahamation</option>
+				<option value="BlueDusk">BlueDusk</option>
+				<option value="CubanShirts">CubanShirts</option>
+				<option value="Desert">Desert</option>
+				<option value="Distinctive">Distinctive</option>
+				<option value="Dollar">Dollar</option>
+				<option value="Grasshopper">Grasshopper</option>
+				<option value="Grasslands">Grasslands</option>
+				<option value="GreySkies">GreySkies</option>
+				<option value="Harmony">Harmony</option>
+				<option value="IndigoNation">IndigoNation</option>
+				<option value="Ireland">Ireland</option>
+				<option value="MiamiNice">MiamiNice</option>
+				<option value="Midwest">Midwest</option>
+				<option value="Minty">Minty</option>
+				<option value="PurpleRain">PurpleRain</option>
+				<option value="RoyalPurples">RoyalPurples</option>
+				<option value="SageToLime">SageToLime</option>
+				<option value="Shrooms">Shrooms</option>
+				<option value="Tufte">Tufte</option>
+				<option value="WatersEdge">WatersEdge</option>
+				<option value="Wetland">Wetland</option>
+			</optgroup>
+			<optgroup label="PlotKit">
+				<option value="PlotKit.blue">PlotKit.blue</option>
+				<option value="PlotKit.cyan">PlotKit.cyan</option>
+				<option value="PlotKit.green">PlotKit.green</option>
+				<option value="PlotKit.orange">PlotKit.orange</option>
+				<option value="PlotKit.purple">PlotKit.purple</option>
+				<option value="PlotKit.red">PlotKit.red</option>
+			</optgroup>
+		</select>
+		   
+		<input id="pageStyleChooser" type="checkbox" checked="checked" value="">
+		<label for="pageStyleChooser"> use suggested page style</label>
+	</p>
+	<div id="chartContainer">
+		<div class="chart" id="bars"></div>
+		<div class="chart" id="lines"></div>
+		<div class="chart" id="pieFan"></div>
+		<div class="chart" id="bubbles"></div>
+		<div class="chart" id="area"></div>
+		<div class="chart" id="pieLin"></div>
+		<div class="chart" id="columns"></div>
+		<div class="chart" id="candle"></div>
+		<div class="chart" id="ohlc"></div>
+		<div class="chart" id="scatter"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/charting/tests/test_themes.html b/dojox/charting/tests/test_themes.html
index 1558f33..b8ed78a 100644
--- a/dojox/charting/tests/test_themes.html
+++ b/dojox/charting/tests/test_themes.html
@@ -1,8 +1,20 @@
+<!--[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>
-<head>
+<html lang="en">
+	<head>
+<![endif]>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="chrome=1"/>
 <title>Example Dojo Chart Types</title>
 <style>
 	@import "../../../dojo/resources/dojo.css";
diff --git a/dojox/charting/tests/test_touchIndicator.html b/dojox/charting/tests/test_touchIndicator.html
new file mode 100644
index 0000000..7ed067b
--- /dev/null
+++ b/dojox/charting/tests/test_touchIndicator.html
@@ -0,0 +1,103 @@
+<!--[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>Touch 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"
+			djConfig="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.action2d.TouchZoomAndPan");
+			dojo.require("dojox.charting.action2d.TouchIndicator");
+		
+			var chart;
+			makeObjects = function() {
+				chart = new dojox.charting.Chart("chart");
+				chart.addAxis("x", {
+					type : "Default",
+					font: "normal normal normal 14pt Tahoma",
+					fixLower : "minor",
+					natural : true,
+					stroke : "grey",
+					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 : "grey",
+					majorTick : {
+						stroke : "black",
+						length : 4
+					},
+					minorTick : {
+						stroke : "gray",
+						length : 2
+					}
+				});
+				chart.addPlot("default", {
+					type : "Default",
+					markers : false,
+					areas: true
+				});
+				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 dojox.charting.action2d.TouchZoomAndPan(chart, "default", 
+						{axis: "x", enableScroll : false, enableZoom : false});
+				new dojox.charting.action2d.TouchIndicator(chart, "default",
+						{ series: "Series A", 
+							dualIndicator : true, font: "normal normal bold 16pt Tahoma", fillFunc: function(v1, v2){
+								if(v2){
+									return v2.y>v1.y?"green":"red";
+								}else{
+									return "white";
+								}
+							}
+						});
+				chart.render();
+			};
+		
+			dojo.addOnLoad(makeObjects);
+		</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_touchZoomAndPan.html b/dojox/charting/tests/test_touchZoomAndPan.html
new file mode 100644
index 0000000..fb85165
--- /dev/null
+++ b/dojox/charting/tests/test_touchZoomAndPan.html
@@ -0,0 +1,63 @@
+<!--[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>Touch Zoom And Pan</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<meta name="viewport" content="user-scalable=no, width=device-width, height=device-height" />
+		<style type="text/css">
+			@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">
+			dojo.require("dojox.mobile.parser");
+
+			dojo.require("dojox.charting.Chart");
+            dojo.require("dojox.charting.axis2d.Default");
+            dojo.require("dojox.charting.plot2d.Lines");
+			dojo.require("dojox.charting.action2d.TouchZoomAndPan");
+			
+			var chart;
+			makeObjects = function(){
+				chart = new dojox.charting.Chart("chart");
+				chart.addAxis("x", {type : "Default", fixLower: "minor", natural: true, stroke: "grey", 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",
+					majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
+				chart.addPlot("default", {type: "Default",markers: false, areas: 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
+				]);
+				new dojox.charting.action2d.TouchZoomAndPan(chart, "default", { axis: "x" });
+				chart.render();
+				chart.zoomIn("x", [40, 60]);
+			};
+			dojo.addOnLoad(makeObjects);
+		</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_widget2d-amd.html b/dojox/charting/tests/test_widget2d-amd.html
new file mode 100644
index 0000000..b51175c
--- /dev/null
+++ b/dojox/charting/tests/test_widget2d-amd.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>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];
+			require([
+			"dojox/charting/widget/Chart",
+			"dojox/charting/axis2d/Default",
+			"dojox/charting/plot2d/Areas",
+			"dojox/charting/plot2d/Grid",
+			"dojox/charting/plot2d/Pie",
+			"dojox/charting/action2d/Tooltip",
+			"dojox/charting/action2d/MoveSlice",
+			"dojox/charting/action2d/MouseZoomAndPan",
+			"dojox/charting/widget/Legend",
+			"dojox/charting/themes/PlotKit/orange",
+			"dojox/charting/themes/PlotKit/blue",
+			"dojox/charting/themes/PlotKit/green",
+			"dojox/data/HtmlStore", "dojo/parser"]);
+		</script>
+	</head>
+	<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>
+		<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 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="Areas"></div>
+						<div class="plot" name="grid" type="Grid"></div>
+						<div class="series" name="Run A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
+						<div class="series" name="Run B" array="seriesB" legend="<em>Custom</em> legend"></div>
+						<div class="series" name="Run C" store="tableStore" valueFn="Number(x)"></div>
+						<div class="action" type="MouseZoomAndPan" maxScale="40"></div>
+					</div>
+					<div data-dojo-type="dojox.charting.widget.Legend" chartRef="chart1"></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" 
+							font="italic normal bold 10pt Tahoma"></div>
+						<div class="plot" name="default" type="Areas"></div>
+						<div class="plot" name="grid" type="Grid"></div>
+						<div class="series" name="Series A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
+						<div class="series" name="Series B" array="seriesB"></div>
+						<div class="series" name="Series C" store="tableStore" valueFn="Number(x)" stroke="'#666666'" fill="'#b3b3b3'"></div>
+						<div class="action" type="MouseZoomAndPan" axis="x" scaleFactor="1.05"></div>
+						<div class="action" type="MouseZoomAndPan" axis="y" scaleFactor="1.05"></div>					
+					</div>
+					<div data-dojo-type="dojox.charting.widget.Legend" chartRef="chart2"></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"></div>
+						<div class="series" name="Series B" array="seriesB"></div>
+						<div class="action" type="Tooltip"></div>
+					</div>
+				</td>
+				<td>
+					<div data-dojo-type="dojox.charting.widget.Chart" id="chart4" theme="dojox.charting.themes.PlotKit.green"
+							 style="width: 300px; height: 300px;">
+						<div class="plot" name="default" type="Pie" radius="100" fontColor="black" labelOffset="-20"></div>
+						<div class="series" name="Series C" store="tableStore" valueFn="Number(x)"></div>
+						<div class="action" type="Tooltip"></div>
+						<div class="action" type="MoveSlice" shift="2"></div>
+					</div>
+				</td>
+			</tr>
+		</table>
+		<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/charting/tests/test_widget2d.html b/dojox/charting/tests/test_widget2d.html
index 6d09fbb..4252d13 100644
--- a/dojox/charting/tests/test_widget2d.html
+++ b/dojox/charting/tests/test_widget2d.html
@@ -1,8 +1,20 @@
+<!--[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>
+<html lang="en">
 	<head>
+<![endif]>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-	    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 		<title>Chart 2D</title>
 		<style type="text/css">
 			@import "../../../dojo/resources/dojo.css";
@@ -25,7 +37,8 @@
             dojo.require("dojox.charting.plot2d.Pie");
             dojo.require("dojox.charting.action2d.Tooltip");
             dojo.require("dojox.charting.action2d.MoveSlice");
-			dojo.require("dojox.charting.widget.Legend");
+            dojo.require("dojox.charting.action2d.MouseZoomAndPan");
+            dojo.require("dojox.charting.widget.Legend");
 			dojo.require("dojox.charting.themes.PlotKit.orange");
 			dojo.require("dojox.charting.themes.PlotKit.blue");
 			dojo.require("dojox.charting.themes.PlotKit.green");
@@ -67,6 +80,7 @@
 						<div class="series" name="Run A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
 						<div class="series" name="Run B" array="seriesB" legend="<em>Custom</em> legend"></div>
 						<div class="series" name="Run C" store="tableStore" valueFn="Number(x)"></div>
+						<div class="action" type="MouseZoomAndPan" maxScale="40"></div>
 					</div>
 					<div dojoType="dojox.charting.widget.Legend" chartRef="chart1"></div>
 				</td>
@@ -81,6 +95,8 @@
 						<div class="series" name="Series A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
 						<div class="series" name="Series B" array="seriesB"></div>
 						<div class="series" name="Series C" store="tableStore" valueFn="Number(x)" stroke="'#666666'" fill="'#b3b3b3'"></div>
+						<div class="action" type="MouseZoomAndPan" axis="x" scaleFactor="1.05"></div>
+						<div class="action" type="MouseZoomAndPan" axis="y" scaleFactor="1.05"></div>					
 					</div>
 					<div dojoType="dojox.charting.widget.Legend" chartRef="chart2"></div>
 				</td>
diff --git a/dojox/charting/tests/test_widget2d_deprecated.html b/dojox/charting/tests/test_widget2d_deprecated.html
index eda22d4..3274dee 100644
--- a/dojox/charting/tests/test_widget2d_deprecated.html
+++ b/dojox/charting/tests/test_widget2d_deprecated.html
@@ -1,8 +1,20 @@
+<!--[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>
+<html lang="en">
 	<head>
+<![endif]>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-	    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 		<title>Chart 2D</title>
 		<style type="text/css">
 			@import "../../../dojo/resources/dojo.css";
diff --git a/dojox/charting/tests/test_win2d.html b/dojox/charting/tests/test_win2d.html
index 3dbb12c..3183eb5 100644
--- a/dojox/charting/tests/test_win2d.html
+++ b/dojox/charting/tests/test_win2d.html
@@ -1,8 +1,20 @@
+<!--[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>
-<head>
+<html lang="en">
+	<head>
+<![endif]>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <title>Scaling, scrolling, and panning.</title>
 <style type="text/css">
 	@import "../../../dojo/resources/dojo.css";
@@ -41,10 +53,10 @@ var reflect = function(){
 		}
 	});
 	setTimeout(function(){
-		dijit.byId("scaleXSlider").setValue(scaleX);
-		dijit.byId("offsetXSlider").setValue(offsetX);
-		dijit.byId("scaleYSlider").setValue(scaleY);
-		dijit.byId("offsetYSlider").setValue(offsetY);
+		dijit.byId("scaleXSlider").set("value",scaleX);
+		dijit.byId("offsetXSlider").set("value",offsetX);
+		dijit.byId("scaleYSlider").set("value",scaleY);
+		dijit.byId("offsetYSlider").set("value",offsetY);
 	}, 25);
 };
 
diff --git a/dojox/charting/tests/theme_preview-amd.html b/dojox/charting/tests/theme_preview-amd.html
new file mode 100644
index 0000000..2f97fcd
--- /dev/null
+++ b/dojox/charting/tests/theme_preview-amd.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" />
+		<meta http-equiv="X-UA-Compatible" content="chrome=1"/> 
+		<title>DojoX Charting Theme Previewer</title>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			body {
+				padding: 1.5em;
+			}
+			div.container {
+				position: relative;
+				width: 180px;
+				height: 200px;
+				float: left;
+				border: 1px solid #ccc;
+				margin: 12px;
+			}
+			div.container div.chart {
+				width: 180px;
+				height: 180px;
+			}
+			div.container div.title {
+				position: absolute;
+				bottom: 4px;
+				font-size: 11px;
+				width: 180px;
+				text-align: center;
+			}
+			div.container div.title a { text-decoration: none; }
+			div.container div.title a:hover { text-decoration: underline; }
+		</style>
+<script src="../../../dojo/dojo.js" data-dojo-config="isDebug: false, async: true, gfxRenderer: 'svg,silverlight,vml,canvas'"></script>
+<script type="text/javascript">
+	require(["dojo/_base/array", "dojo/dom-construct", "dojo/ready",  
+		"dojox/charting/Chart", "dojox/charting/plot2d/Pie", "dojox/gfx/_base"], 
+		function(arr, domConstruct, ready, Chart, Pie, gfx){
+
+		var themes = [
+			"dojox/charting/themes/Julie", "dojox/charting/themes/ThreeD", "dojox/charting/themes/Chris", 
+			"dojox/charting/themes/Tom", "dojox/charting/themes/Claro", "dojox/charting/themes/PrimaryColors", 
+			"dojox/charting/themes/Electric", "dojox/charting/themes/Charged", "dojox/charting/themes/Renkoo",
+			"dojox/charting/themes/Adobebricks", "dojox/charting/themes/Algae", "dojox/charting/themes/Bahamation", 
+			"dojox/charting/themes/BlueDusk", "dojox/charting/themes/CubanShirts", "dojox/charting/themes/Desert", 
+			"dojox/charting/themes/Distinctive", "dojox/charting/themes/Dollar", "dojox/charting/themes/Grasshopper", 
+			"dojox/charting/themes/Grasslands", "dojox/charting/themes/GreySkies", "dojox/charting/themes/Harmony", 
+			"dojox/charting/themes/IndigoNation", "dojox/charting/themes/Ireland", "dojox/charting/themes/MiamiNice",
+			"dojox/charting/themes/Minty", "dojox/charting/themes/PurpleRain", "dojox/charting/themes/RoyalPurples", 
+			"dojox/charting/themes/SageToLime", "dojox/charting/themes/Shrooms", "dojox/charting/themes/Tufte", 
+			"dojox/charting/themes/WatersEdge", "dojox/charting/themes/Wetland", "dojox/charting/themes/PlotKit/blue",
+			"dojox/charting/themes/PlotKit/cyan", "dojox/charting/themes/PlotKit/green", "dojox/charting/themes/PlotKit/orange", 
+			"dojox/charting/themes/PlotKit/purple", "dojox/charting/themes/PlotKit/red"
+		];
+		
+		require(themes, function(){
+			var i = 0;
+			var themeClasses = arguments;
+			ready(function(){
+				arr.forEach(themes, function(theme){
+					// remove dojox/charting/themes from displayed name
+					theme = theme.substring(22);
+					// move / to .
+					theme = theme.replace("/", ".");
+					var container = domConstruct.create("div", { className: "container" }, "main");
+					var chart = domConstruct.create("div", { className: "chart" }, container);
+					var title = domConstruct.create("div", { 
+						className: "title", 
+						innerHTML: 'See more of "<a href="test_themes-amd.html?' + theme + '">' + theme + '</a>"' 
+					}, container);
+					var c = new Chart(chart).
+						setTheme(themeClasses[i]).
+						addPlot("default", {type: Pie, radius: 60, labelOffset: -20, radGrad: gfx.renderer == "vml" ? "fan" : "native"}).
+						addSeries("Series A", [0.35, 0.25, 0.42, 0.53, 0.69]).
+						render();
+					i++;
+				});
+			});
+		});
+	});
+</script>
+</head>
+<body>
+	<h1>DojoX Charting Theme Preview</h1>
+	<div id="main"></div>
+</body>
+</html>
diff --git a/dojox/charting/tests/theme_preview.html b/dojox/charting/tests/theme_preview.html
index 04793d6..0409e7d 100644
--- a/dojox/charting/tests/theme_preview.html
+++ b/dojox/charting/tests/theme_preview.html
@@ -1,6 +1,19 @@
+<!--[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>
+<html lang="en">
 	<head>
+<![endif]>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 		<meta http-equiv="X-UA-Compatible" content="chrome=1"/> 
 		<title>DojoX Charting Theme Previewer</title>
diff --git a/dojox/charting/themes/Adobebricks.js b/dojox/charting/themes/Adobebricks.js
index a0b7088..db3dd99 100644
--- a/dojox/charting/themes/Adobebricks.js
+++ b/dojox/charting/themes/Adobebricks.js
@@ -1,9 +1,6 @@
-dojo.provide("dojox.charting.themes.Adobebricks");
-dojo.require("dojox.charting.Theme");
+define(["../Theme", "./common"], function(Theme, themes){
 
-(function(){
-	var dxc=dojox.charting;
-	dxc.themes.Adobebricks=new dxc.Theme({
+	themes.Adobebricks=new Theme({
 		colors: [
 			"#7f2518",
 			"#3e170c",
@@ -12,4 +9,6 @@ dojo.require("dojox.charting.Theme");
 			"#8c271c"
 		]
 	});
-})();
+	
+	return themes.Adobebricks;
+});
diff --git a/dojox/charting/themes/Algae.js b/dojox/charting/themes/Algae.js
index 4b6c8fe..7a809ac 100644
--- a/dojox/charting/themes/Algae.js
+++ b/dojox/charting/themes/Algae.js
@@ -1,9 +1,5 @@
-dojo.provide("dojox.charting.themes.Algae");
-dojo.require("dojox.charting.Theme");
-
-(function(){
-	var dxc=dojox.charting;
-	dxc.themes.Algae=new dxc.Theme({
+define(["../Theme", "./common"], function(Theme, themes){
+	themes.Algae = new Theme({
 		colors: [
 			"#57808f",
 			"#506885",
@@ -12,4 +8,5 @@ dojo.require("dojox.charting.Theme");
 			"#508567"
 		]
 	});
-})();
+	return themes.Algae;
+});
diff --git a/dojox/charting/themes/Bahamation.js b/dojox/charting/themes/Bahamation.js
index 5a00ccb..6132766 100644
--- a/dojox/charting/themes/Bahamation.js
+++ b/dojox/charting/themes/Bahamation.js
@@ -1,9 +1,5 @@
-dojo.provide("dojox.charting.themes.Bahamation");
-dojo.require("dojox.charting.Theme");
-
-(function(){
-	var dxc=dojox.charting;
-	dxc.themes.Bahamation=new dxc.Theme({
+define(["../Theme", "./common"], function(Theme, themes){
+	themes.Bahamation=new Theme({
 		colors: [
 			"#3f9998",
 			"#3fc0c3",
@@ -12,4 +8,5 @@ dojo.require("dojox.charting.Theme");
 			"#c663a6"
 		]
 	});
-})();
+	return themes.Bahamation;
+});
diff --git a/dojox/charting/themes/BlueDusk.js b/dojox/charting/themes/BlueDusk.js
index 075a4ac..7762bdd 100644
--- a/dojox/charting/themes/BlueDusk.js
+++ b/dojox/charting/themes/BlueDusk.js
@@ -1,9 +1,6 @@
-dojo.provide("dojox.charting.themes.BlueDusk");
-dojo.require("dojox.charting.Theme");
+define(["../Theme", "./common"], function(Theme, themes){
 
-(function(){
-	var dxc=dojox.charting;
-	dxc.themes.BlueDusk=new dxc.Theme({
+	themes.BlueDusk=new Theme({
 		colors: [
 			"#292e76",
 			"#3e56a6",
@@ -12,4 +9,6 @@ dojo.require("dojox.charting.Theme");
 			"#798dcd"
 		]
 	});
-})();
+	
+	return themes.BlueDusk;
+});
diff --git a/dojox/charting/themes/Charged.js b/dojox/charting/themes/Charged.js
index 269c524..0e6f1c9 100644
--- a/dojox/charting/themes/Charged.js
+++ b/dojox/charting/themes/Charged.js
@@ -1,15 +1,9 @@
-dojo.provide("dojox.charting.themes.Charged");
+define(["../Theme", "dojox/gfx/gradutils", "./common"], function(Theme, gradutils, themes){
 
-dojo.require("dojox.gfx.gradutils");
-dojo.require("dojox.charting.Theme");
-
-// created by Tom Trenka
-
-(function(){
-	var dc = dojox.charting, themes = dc.themes, Theme = dc.Theme, g = Theme.generateGradient,
+	var g = Theme.generateGradient,
 		defaultFill = {type: "linear", space: "shape", x1: 0, y1: 0, x2: 0, y2: 75};
 	
-	themes.Charged = new dc.Theme({
+	themes.Charged = new Theme({
 		chart: {
 			fill: "#ededdf",
 			pageStyle: {backgroundColor: "#ededdf", backgroundImage: "none", color: "inherit"}
@@ -84,8 +78,10 @@ dojo.require("dojox.charting.Theme");
 	themes.Charged.post = function(theme, elementType){
 		theme = Theme.prototype.post.apply(this, arguments);
 		if((elementType == "slice" || elementType == "circle") && theme.series.fill && theme.series.fill.type == "radial"){
-			theme.series.fill = dojox.gfx.gradutils.reverse(theme.series.fill);
+			theme.series.fill = gradutils.reverse(theme.series.fill);
 		}
 		return theme;
 	};
-})();
+	
+	return themes.Charged;
+});
diff --git a/dojox/charting/themes/Chris.js b/dojox/charting/themes/Chris.js
index 0340ed0..c9ec04a 100644
--- a/dojox/charting/themes/Chris.js
+++ b/dojox/charting/themes/Chris.js
@@ -1,15 +1,11 @@
-dojo.provide("dojox.charting.themes.Chris");
+define(["../Theme", "dojox/gfx/gradutils", "./common"], function(Theme, gradutils, themes){
 
-dojo.require("dojox.gfx.gradutils");
-dojo.require("dojox.charting.Theme");
+	// created by Christopher Anderson
 
-// created by Christopher Anderson
-
-(function(){
-	var dc = dojox.charting, themes = dc.themes, Theme = dc.Theme, g = Theme.generateGradient,
+	var g = Theme.generateGradient,
 		defaultFill = {type: "linear", space: "shape", x1: 0, y1: 0, x2: 0, y2: 100};
 	
-	themes.Chris = new dc.Theme({
+	themes.Chris = new Theme({
 		chart: {
 			fill:   "#c1c1c1",
 			stroke: {color: "#666"}
@@ -70,8 +66,10 @@ dojo.require("dojox.charting.Theme");
 	themes.Chris.post = function(theme, elementType){
 		theme = Theme.prototype.post.apply(this, arguments);
 		if((elementType == "slice" || elementType == "circle") && theme.series.fill && theme.series.fill.type == "radial"){
-			theme.series.fill = dojox.gfx.gradutils.reverse(theme.series.fill);
+			theme.series.fill = gradutils.reverse(theme.series.fill);
 		}
 		return theme;
 	};
-})();
+	
+	return themes.Chris;
+});
diff --git a/dojox/charting/themes/Claro.js b/dojox/charting/themes/Claro.js
index 00c3ae1..e4f3e40 100644
--- a/dojox/charting/themes/Claro.js
+++ b/dojox/charting/themes/Claro.js
@@ -1,14 +1,10 @@
-dojo.provide("dojox.charting.themes.Claro");
-dojo.require("dojox.gfx.gradutils");
-dojo.require("dojox.charting.Theme");
+define(["../Theme", "dojox/gfx/gradutils", "./common"], function(Theme, gradutils, themes){
+	// created by Tom Trenka
 
-// created by Tom Trenka
-
-(function(){
-	var dc = dojox.charting, themes = dc.themes, Theme = dc.Theme, g = Theme.generateGradient,
+	var g = Theme.generateGradient,
 		defaultFill = {type: "linear", space: "shape", x1: 0, y1: 0, x2: 0, y2: 100};
 	
-	themes.Claro = new dc.Theme({
+	themes.Claro = new Theme({
 		chart: {
 			fill:	   {
 				type: "linear",
@@ -101,8 +97,10 @@ dojo.require("dojox.charting.Theme");
 	themes.Claro.post = function(theme, elementType){
 		theme = Theme.prototype.post.apply(this, arguments);
 		if((elementType == "slice" || elementType == "circle") && theme.series.fill && theme.series.fill.type == "radial"){
-			theme.series.fill = dojox.gfx.gradutils.reverse(theme.series.fill);
+			theme.series.fill = gradutils.reverse(theme.series.fill);
 		}
 		return theme;
 	};
-})();
+	
+	return themes.Claro;
+});
diff --git a/dojox/charting/themes/CubanShirts.js b/dojox/charting/themes/CubanShirts.js
index f0521af..7591e91 100644
--- a/dojox/charting/themes/CubanShirts.js
+++ b/dojox/charting/themes/CubanShirts.js
@@ -1,11 +1,8 @@
-dojo.provide("dojox.charting.themes.CubanShirts");
-dojo.require("dojox.charting.Theme");
+define(["../Theme", "./common"], function(Theme, themes){
 
-(function(){
 	//	notes: colors generated by moving in 30 degree increments around the hue circle,
 	//		at 90% saturation, using a B value of 75 (HSB model).
-	var dxc=dojox.charting;
-	dxc.themes.CubanShirts=new dxc.Theme({
+	themes.CubanShirts=new Theme({
 		colors: [
 			"#d42d2a",
 			"#004f80",
@@ -14,4 +11,6 @@ dojo.require("dojox.charting.Theme");
 			"#7f7f33"
 		]
 	});
-})();
+	
+	return themes.CubanShirts;
+});
diff --git a/dojox/charting/themes/Desert.js b/dojox/charting/themes/Desert.js
index ce99efd..cab2e75 100644
--- a/dojox/charting/themes/Desert.js
+++ b/dojox/charting/themes/Desert.js
@@ -1,11 +1,8 @@
-dojo.provide("dojox.charting.themes.Desert");
-dojo.require("dojox.charting.Theme");
+define(["../Theme", "./common"], function(Theme, themes){
 
-(function(){
 	//	notes: colors generated by moving in 30 degree increments around the hue circle,
 	//		at 90% saturation, using a B value of 75 (HSB model).
-	var dxc=dojox.charting;
-	dxc.themes.Desert=new dxc.Theme({
+	themes.Desert=new Theme({
 		colors: [
 			"#ffebd5",
 			"#806544",
@@ -14,4 +11,6 @@ dojo.require("dojox.charting.Theme");
 			"#cda26e"
 		]
 	});
-})();
+	
+	return themes.Desert;
+});
diff --git a/dojox/charting/themes/Distinctive.js b/dojox/charting/themes/Distinctive.js
index 8d8d62c..eaeb239 100644
--- a/dojox/charting/themes/Distinctive.js
+++ b/dojox/charting/themes/Distinctive.js
@@ -1,8 +1,6 @@
-dojo.provide("dojox.charting.themes.Distinctive");
-dojo.require("dojox.charting.Theme");
-(function(){
-	var dxc=dojox.charting;
-	dxc.themes.Distinctive=new dxc.Theme({
+define(["../Theme", "./common"], function(Theme, themes){
+	
+	themes.Distinctive=new Theme({
 		colors: [
 			"#497c91",
 			"#ada9d6",
@@ -39,4 +37,6 @@ dojo.require("dojox.charting.Theme");
 		
 		]
 	});
-})();
\ No newline at end of file
+	
+	return themes.Distinctive;
+});
diff --git a/dojox/charting/themes/Dollar.js b/dojox/charting/themes/Dollar.js
index 7997efc..36790c4 100644
--- a/dojox/charting/themes/Dollar.js
+++ b/dojox/charting/themes/Dollar.js
@@ -1,15 +1,14 @@
-dojo.provide("dojox.charting.themes.Dollar");
-dojo.require("dojox.charting.Theme");
-
-(function(){
-	var dxc=dojox.charting;
-	dxc.themes.Dollar=new dxc.Theme({
+define(["../Theme", "./common"], function(Theme, themes){
+	
+	themes.Dollar=new Theme({
 		colors: [
 			"#A4CE67",
-            "#739363",
-            "#6B824A",
-            "#343434",
-            "#636563"
+			"#739363",
+			"#6B824A",
+			"#343434",
+			"#636563"
 		]
 	});
-})();
+	
+	return themes.Dollar;
+});
diff --git a/dojox/charting/themes/Electric.js b/dojox/charting/themes/Electric.js
index e4929c2..1e8d8ff 100644
--- a/dojox/charting/themes/Electric.js
+++ b/dojox/charting/themes/Electric.js
@@ -1,15 +1,9 @@
-dojo.provide("dojox.charting.themes.Electric");
+define(["../Theme", "dojox/gfx/gradutils", "./common"], function(Theme, gradutils, themes){
 
-dojo.require("dojox.gfx.gradutils");
-dojo.require("dojox.charting.Theme");
-
-// created by Tom Trenka
-
-(function(){
-	var dc = dojox.charting, themes = dc.themes, Theme = dc.Theme, g = Theme.generateGradient,
+	var g = Theme.generateGradient,
 		defaultFill = {type: "linear", space: "shape", x1: 0, y1: 0, x2: 0, y2: 75};
 	
-	themes.Electric = new dc.Theme({
+	themes.Electric = new Theme({
 		chart: {
 			fill:      "#252525",
 			stroke:    {color: "#252525"},
@@ -85,8 +79,10 @@ dojo.require("dojox.charting.Theme");
 	themes.Electric.post = function(theme, elementType){
 		theme = Theme.prototype.post.apply(this, arguments);
 		if((elementType == "slice" || elementType == "circle") && theme.series.fill && theme.series.fill.type == "radial"){
-			theme.series.fill = dojox.gfx.gradutils.reverse(theme.series.fill);
+			theme.series.fill = gradutils.reverse(theme.series.fill);
 		}
 		return theme;
 	};
-})();
+	
+	return themes.Electric;
+});
diff --git a/dojox/charting/themes/Grasshopper.js b/dojox/charting/themes/Grasshopper.js
index f6b8106..a5e182d 100644
--- a/dojox/charting/themes/Grasshopper.js
+++ b/dojox/charting/themes/Grasshopper.js
@@ -1,9 +1,5 @@
-dojo.provide("dojox.charting.themes.Grasshopper");
-dojo.require("dojox.charting.Theme");
-
-(function(){
-	var dxc=dojox.charting;
-	dxc.themes.Grasshopper=new dxc.Theme({
+define(["dojo/_base/lang","../Theme", "./common"], function(lang, Theme, themes){
+	themes.Grasshopper=new Theme({
 		colors: [
 			"#208040",
 			"#40b657",
@@ -12,4 +8,5 @@ dojo.require("dojox.charting.Theme");
 			"#64bd5f"
 		]
 	});
-})();
+	return themes.Grasshopper;
+});
diff --git a/dojox/charting/themes/Grasslands.js b/dojox/charting/themes/Grasslands.js
index cf7f589..5c53dbf 100644
--- a/dojox/charting/themes/Grasslands.js
+++ b/dojox/charting/themes/Grasslands.js
@@ -1,11 +1,8 @@
-dojo.provide("dojox.charting.themes.Grasslands");
-dojo.require("dojox.charting.Theme");
-
-(function(){
+define(["../Theme", "./common"], function(Theme, 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).
-	var dxc=dojox.charting;
-	dxc.themes.Grasslands=new dxc.Theme({
+	themes.Grasslands=new Theme({
 		colors: [
 			"#70803a",
 			"#dde574",
@@ -14,4 +11,6 @@ dojo.require("dojox.charting.Theme");
 			"#eff2c2"
 		]
 	});
-})();
+	
+	return themes.Grasslands;
+});
diff --git a/dojox/charting/themes/GreySkies.js b/dojox/charting/themes/GreySkies.js
index b4f9f64..7864e99 100644
--- a/dojox/charting/themes/GreySkies.js
+++ b/dojox/charting/themes/GreySkies.js
@@ -1,7 +1,6 @@
-dojo.provide("dojox.charting.themes.GreySkies");
-dojo.require("dojox.charting.Theme");
-
-(function(){
-	var dxc=dojox.charting;
-	dxc.themes.GreySkies=new dxc.Theme(dxc.Theme._def);
-})();
+define(["../Theme", "./common"], function(Theme, themes){
+	
+	themes.GreySkies=new Theme(Theme._def);
+	
+	return themes.GreySkies;
+});
diff --git a/dojox/charting/themes/Harmony.js b/dojox/charting/themes/Harmony.js
index 7d05a1c..7fbe9a7 100644
--- a/dojox/charting/themes/Harmony.js
+++ b/dojox/charting/themes/Harmony.js
@@ -1,8 +1,6 @@
-dojo.provide("dojox.charting.themes.Harmony");
-dojo.require("dojox.charting.Theme");
-(function(){
-	var dxc=dojox.charting;
-		dxc.themes.Harmony=new dxc.Theme({
+define(["../Theme", "./common"], function(Theme, themes){
+	
+	themes.Harmony=new Theme({
 		colors: [
 			"#497c91",
 			"#59a0bd",
@@ -36,7 +34,8 @@ dojo.require("dojox.charting.Theme");
 			"#a5a5a5",
 			"#bebebe",
 			"#d8d8d8"
-			
 		]
 	});
-})();
\ No newline at end of file
+	
+	return themes.Harmony;
+});
diff --git a/dojox/charting/themes/IndigoNation.js b/dojox/charting/themes/IndigoNation.js
index 2553f7b..f3d131a 100644
--- a/dojox/charting/themes/IndigoNation.js
+++ b/dojox/charting/themes/IndigoNation.js
@@ -1,11 +1,8 @@
-dojo.provide("dojox.charting.themes.IndigoNation");
-dojo.require("dojox.charting.Theme");
-
-(function(){
+define(["../Theme", "./common"], function(Theme, 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).
-	var dxc=dojox.charting;
-	dxc.themes.IndigoNation=new dxc.Theme({
+	themes.IndigoNation=new Theme({
 		colors: [
 			"#93a4d0",
 			"#3b4152",
@@ -14,4 +11,6 @@ dojo.require("dojox.charting.Theme");
 			"#8290b8"
 		]
 	});
-})();
+	
+	return themes.IndigoNation;
+});
diff --git a/dojox/charting/themes/Ireland.js b/dojox/charting/themes/Ireland.js
index 72d2d63..82ac126 100644
--- a/dojox/charting/themes/Ireland.js
+++ b/dojox/charting/themes/Ireland.js
@@ -1,9 +1,6 @@
-dojo.provide("dojox.charting.themes.Ireland");
-dojo.require("dojox.charting.Theme");
-
-(function(){
-	var dxc=dojox.charting;
-	dxc.themes.Ireland=new dxc.Theme({
+define(["../Theme", "./common"], function(Theme, themes){
+	
+	themes.Ireland=new Theme({
 		colors: [
 			"#abdbcb",
 			"#435a51",
@@ -12,4 +9,6 @@ dojo.require("dojox.charting.Theme");
 			"#5f8074"
 		]
 	});
-})();
+	
+	return themes.Ireland;
+});
diff --git a/dojox/charting/themes/Julie.js b/dojox/charting/themes/Julie.js
index 1268521..79c4a15 100644
--- a/dojox/charting/themes/Julie.js
+++ b/dojox/charting/themes/Julie.js
@@ -1,15 +1,11 @@
-dojo.provide("dojox.charting.themes.Julie");
+define(["../Theme", "dojox/gfx/gradutils", "./common"], function(Theme, gradutils){
 
-dojo.require("dojox.gfx.gradutils");
-dojo.require("dojox.charting.Theme");
-
-// created by Julie Santilli
-
-(function(){
-	var dc = dojox.charting, themes = dc.themes, Theme = dc.Theme, g = Theme.generateGradient,
+	// created by Julie Santilli (Claro-based theme)
+	
+	var themes = dojox.charting.themes, g = Theme.generateGradient,
 		defaultFill = {type: "linear", space: "shape", x1: 0, y1: 0, x2: 0, y2: 100};
 	
-	themes.Julie = new dc.Theme({
+	themes.Julie = new Theme({
 		seriesThemes: [
 			{fill: g(defaultFill, "#59a0bd", "#497c91"), stroke: {color: "#22627d"}},	// blue
 			{fill: g(defaultFill, "#8d88c7", "#6c6d8e"), stroke: {color: "#8a84c5"}},	// purple
@@ -63,8 +59,10 @@ dojo.require("dojox.charting.Theme");
 	themes.Julie.post = function(theme, elementType){
 		theme = Theme.prototype.post.apply(this, arguments);
 		if(elementType == "slice" && theme.series.fill && theme.series.fill.type == "radial"){
-			theme.series.fill = dojox.gfx.gradutils.reverse(theme.series.fill);
+			theme.series.fill = gradutils.reverse(theme.series.fill);
 		}
 		return theme;
 	};
-})();
+	
+	return themes.Julie;
+});
diff --git a/dojox/charting/themes/MiamiNice.js b/dojox/charting/themes/MiamiNice.js
index f989ea0..1739fee 100644
--- a/dojox/charting/themes/MiamiNice.js
+++ b/dojox/charting/themes/MiamiNice.js
@@ -1,9 +1,6 @@
-dojo.provide("dojox.charting.themes.MiamiNice");
-dojo.require("dojox.charting.Theme");
-
-(function(){
-	var dxc=dojox.charting;
-	dxc.themes.MiamiNice=new dxc.Theme({
+define(["../Theme", "./common"], function(Theme, themes){
+	
+	themes.MiamiNice=new Theme({
 		colors: [
 			"#7f9599",
 			"#45b8cc",
@@ -12,4 +9,6 @@ dojo.require("dojox.charting.Theme");
 			"#cc4482"
 		]
 	});
-})();
+	
+	return themes.MiamiNice;
+});
diff --git a/dojox/charting/themes/Midwest.js b/dojox/charting/themes/Midwest.js
index 0594691..a122974 100644
--- a/dojox/charting/themes/Midwest.js
+++ b/dojox/charting/themes/Midwest.js
@@ -1,9 +1,6 @@
-dojo.provide("dojox.charting.themes.Midwest");
-dojo.require("dojox.charting.Theme");
-
-(function(){
-	var dxc=dojox.charting;
-	dxc.themes.Midwest=new dxc.Theme({
+define(["../Theme", "./common"], function(Theme, themes){
+	
+	themes.Midwest=new Theme({
 		colors: [
 			"#927b51",
 			"#a89166",
@@ -12,4 +9,6 @@ dojo.require("dojox.charting.Theme");
 			"#aebc21"
 		]
 	});
-})();
+	
+	return themes.Midwest;
+});
diff --git a/dojox/charting/themes/Minty.js b/dojox/charting/themes/Minty.js
index 9af6839..89a1dd5 100644
--- a/dojox/charting/themes/Minty.js
+++ b/dojox/charting/themes/Minty.js
@@ -1,9 +1,6 @@
-dojo.provide("dojox.charting.themes.Minty");
-dojo.require("dojox.charting.Theme");
-
-(function(){
-	var dxc=dojox.charting;
-	dxc.themes.Minty=new dxc.Theme({
+define(["../Theme", "./common"], function(Theme, themes){
+	
+	themes.Minty=new Theme({
 		colors: [
 			"#80ccbb",
 			"#539e8b",
@@ -12,4 +9,6 @@ dojo.require("dojox.charting.Theme");
 			"#68c5ad"
 		]
 	});
-})();
+	
+	return themes.Minty;
+});
diff --git a/dojox/charting/themes/PlotKit/base.js b/dojox/charting/themes/PlotKit/base.js
index 3ab91bc..ff6e700 100644
--- a/dojox/charting/themes/PlotKit/base.js
+++ b/dojox/charting/themes/PlotKit/base.js
@@ -1,12 +1,10 @@
-dojo.provide("dojox.charting.themes.PlotKit.base");
+define(["dojo/_base/kernel","dojo/_base/lang","../../Theme", "../common"], 
+	function(dojo, lang, Theme, themes){
 
-dojo.require("dojox.charting.Theme");
+	// the baseline theme for all PlotKIt themes
+	var pk = lang.getObject("PlotKit", true, themes);
 
-// the baseline theme for all PlotKIt themes
-(function(){
-	var dc = dojox.charting, pk = dc.themes.PlotKit;
-
-	pk.base = new dc.Theme({
+	pk.base = new Theme({
 		chart:{
 			stroke: null,
 			fill:   "yellow"
@@ -38,7 +36,7 @@ dojo.require("dojox.charting.Theme");
 	});
 
 	pk.base.next = function(elementType, mixin, doPost){
-		var theme = dc.Theme.prototype.next.apply(this, arguments);
+		var theme = Theme.prototype.next.apply(this, arguments);
 		if(elementType == "line"){
 			theme.marker.outline = {width: 2, color: "#fff"};
 			theme.series.stroke.width = 3.5;
@@ -50,4 +48,6 @@ dojo.require("dojox.charting.Theme");
 		}
 		return theme;
 	};
-})();
+	
+	return pk;
+});
diff --git a/dojox/charting/themes/PlotKit/blue.js b/dojox/charting/themes/PlotKit/blue.js
index b5e2f98..5159887 100644
--- a/dojox/charting/themes/PlotKit/blue.js
+++ b/dojox/charting/themes/PlotKit/blue.js
@@ -1,10 +1,7 @@
-dojo.provide("dojox.charting.themes.PlotKit.blue");
-dojo.require("dojox.charting.themes.PlotKit.base");
-
-(function(){
-	var dc = dojox.charting, pk = dc.themes.PlotKit;
-
+define(["./base", "../../Theme"], function(pk, Theme){
 	pk.blue = pk.base.clone();
 	pk.blue.chart.fill = pk.blue.plotarea.fill = "#e7eef6";
-	pk.blue.colors = dc.Theme.defineColors({hue: 217, saturation: 60, low: 40, high: 88});
-})();
+	pk.blue.colors = Theme.defineColors({hue: 217, saturation: 60, low: 40, high: 88});
+	
+	return pk.blue;
+});
diff --git a/dojox/charting/themes/PlotKit/cyan.js b/dojox/charting/themes/PlotKit/cyan.js
index 5f534ca..125278b 100644
--- a/dojox/charting/themes/PlotKit/cyan.js
+++ b/dojox/charting/themes/PlotKit/cyan.js
@@ -1,10 +1,7 @@
-dojo.provide("dojox.charting.themes.PlotKit.cyan");
-dojo.require("dojox.charting.themes.PlotKit.base");
-
-(function(){
-	var dc = dojox.charting, pk = dc.themes.PlotKit;
-
+define(["./base", "../../Theme"], function(pk, Theme){
 	pk.cyan = pk.base.clone();
 	pk.cyan.chart.fill = pk.cyan.plotarea.fill = "#e6f1f5";
-	pk.cyan.colors = dc.Theme.defineColors({hue: 194, saturation: 60, low: 40, high: 88});
-})();
+	pk.cyan.colors = Theme.defineColors({hue: 194, saturation: 60, low: 40, high: 88});
+	
+	return pk.cyan;
+});
diff --git a/dojox/charting/themes/PlotKit/green.js b/dojox/charting/themes/PlotKit/green.js
index 48269ad..74191e3 100644
--- a/dojox/charting/themes/PlotKit/green.js
+++ b/dojox/charting/themes/PlotKit/green.js
@@ -1,10 +1,7 @@
-dojo.provide("dojox.charting.themes.PlotKit.green");
-dojo.require("dojox.charting.themes.PlotKit.base");
-
-(function(){
-	var dc = dojox.charting, pk = dc.themes.PlotKit;
-
+define(["./base", "../../Theme"], function(pk, Theme){
 	pk.green = pk.base.clone();
 	pk.green.chart.fill = pk.green.plotarea.fill = "#eff5e6";
-	pk.green.colors = dc.Theme.defineColors({hue: 82, saturation: 60, low: 40, high: 88});
-})();
+	pk.green.colors = Theme.defineColors({hue: 82, saturation: 60, low: 40, high: 88});
+	
+	return pk.green;
+});
diff --git a/dojox/charting/themes/PlotKit/orange.js b/dojox/charting/themes/PlotKit/orange.js
index 294b9a4..1dda179 100644
--- a/dojox/charting/themes/PlotKit/orange.js
+++ b/dojox/charting/themes/PlotKit/orange.js
@@ -1,10 +1,7 @@
-dojo.provide("dojox.charting.themes.PlotKit.orange");
-dojo.require("dojox.charting.themes.PlotKit.base");
-
-(function(){
-	var dc = dojox.charting, pk = dc.themes.PlotKit;
-
+define(["./base", "../../Theme"], function(pk, Theme){
 	pk.orange = pk.base.clone();
 	pk.orange.chart.fill = pk.orange.plotarea.fill = "#f5eee6";
-	pk.orange.colors = dc.Theme.defineColors({hue: 31, saturation: 60, low: 40, high: 88});
-})();
+	pk.orange.colors = Theme.defineColors({hue: 31, saturation: 60, low: 40, high: 88});
+	
+	return pk.orange;
+});
diff --git a/dojox/charting/themes/PlotKit/purple.js b/dojox/charting/themes/PlotKit/purple.js
index 5d92011..2b6b641 100644
--- a/dojox/charting/themes/PlotKit/purple.js
+++ b/dojox/charting/themes/PlotKit/purple.js
@@ -1,10 +1,7 @@
-dojo.provide("dojox.charting.themes.PlotKit.purple");
-dojo.require("dojox.charting.themes.PlotKit.base");
-
-(function(){
-	var dc = dojox.charting, pk = dc.themes.PlotKit;
-
+define(["./base", "../../Theme"], function(pk, Theme){
 	pk.purple = pk.base.clone();
 	pk.purple.chart.fill = pk.purple.plotarea.fill = "#eee6f5";
-	pk.purple.colors = dc.Theme.defineColors({hue: 271, saturation: 60, low: 40, high: 88});
-})();
+	pk.purple.colors = Theme.defineColors({hue: 271, saturation: 60, low: 40, high: 88});
+	
+	return pk.purple;
+});
diff --git a/dojox/charting/themes/PlotKit/red.js b/dojox/charting/themes/PlotKit/red.js
index 7ac8169..468f745 100644
--- a/dojox/charting/themes/PlotKit/red.js
+++ b/dojox/charting/themes/PlotKit/red.js
@@ -1,10 +1,7 @@
-dojo.provide("dojox.charting.themes.PlotKit.red");
-dojo.require("dojox.charting.themes.PlotKit.base");
-
-(function(){
-	var dc = dojox.charting, pk = dc.themes.PlotKit;
-
+define(["./base", "../../Theme"], function(pk, Theme){
 	pk.red = pk.base.clone();
 	pk.red.chart.fill = pk.red.plotarea.fill = "#f5e6e6";
-	pk.red.colors = dc.Theme.defineColors({hue: 1, saturation: 60, low: 40, high: 88});
-})();
+	pk.red.colors = Theme.defineColors({hue: 1, saturation: 60, low: 40, high: 88});
+	
+	return pk.red;
+});
diff --git a/dojox/charting/themes/PrimaryColors.js b/dojox/charting/themes/PrimaryColors.js
index 5a230ec..44a2dab 100644
--- a/dojox/charting/themes/PrimaryColors.js
+++ b/dojox/charting/themes/PrimaryColors.js
@@ -1,14 +1,11 @@
-dojo.provide("dojox.charting.themes.PrimaryColors");
+define(["../Theme", "./gradientGenerator", "./common"], function(Theme, gradientGenerator, themes){
 
-dojo.require("dojox.charting.Theme");
-dojo.require("dojox.charting.themes.gradientGenerator");
-
-(function(){
-	var dc = dojox.charting, themes = dc.themes,
-		colors = ["#f00", "#0f0", "#00f", "#ff0", "#0ff", "#f0f"],
+	var colors = ["#f00", "#0f0", "#00f", "#ff0", "#0ff", "#f0f", "./common"],
 		defaultFill = {type: "linear", space: "plot", x1: 0, y1: 0, x2: 0, y2: 100};
 
-	themes.PrimaryColors = new dc.Theme({
-		seriesThemes: themes.gradientGenerator.generateMiniTheme(colors, defaultFill, 90, 40, 25)
+	themes.PrimaryColors = new Theme({
+		seriesThemes: gradientGenerator.generateMiniTheme(colors, defaultFill, 90, 40, 25)
 	});
-})();
+	
+	return themes.PrimaryColors;
+});
diff --git a/dojox/charting/themes/PurpleRain.js b/dojox/charting/themes/PurpleRain.js
index 94fcea6..2e43efb 100644
--- a/dojox/charting/themes/PurpleRain.js
+++ b/dojox/charting/themes/PurpleRain.js
@@ -1,11 +1,8 @@
-dojo.provide("dojox.charting.themes.PurpleRain");
-dojo.require("dojox.charting.Theme");
-
-(function(){
+define(["../Theme", "./common"], function(Theme, 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).
-	var dxc=dojox.charting;
-	dxc.themes.PurpleRain=new dxc.Theme({
+	themes.PurpleRain=new Theme({
 		colors: [
 			"#4879bc",
 			"#ef446f",
@@ -14,4 +11,6 @@ dojo.require("dojox.charting.Theme");
 			"#4956a6"
 		]
 	});
-})();
+	
+	return themes.PurpleRain;
+});
diff --git a/dojox/charting/themes/Renkoo.js b/dojox/charting/themes/Renkoo.js
index e6c1cea..91395e5 100644
--- a/dojox/charting/themes/Renkoo.js
+++ b/dojox/charting/themes/Renkoo.js
@@ -1,15 +1,11 @@
-dojo.provide("dojox.charting.themes.Renkoo");
+define(["../Theme", "dojox/gfx/gradutils", "./common"], function(Theme, gradutils, themes){
 
-dojo.require("dojox.gfx.gradutils");
-dojo.require("dojox.charting.Theme");
+	// created by Tom Trenka
 
-// created by Tom Trenka
-
-(function(){
-	var dc = dojox.charting, themes = dc.themes, Theme = dc.Theme, g = Theme.generateGradient,
+	var g = Theme.generateGradient,
 		defaultFill = {type: "linear", space: "shape", x1: 0, y1: 0, x2: 0, y2: 150};
 	
-	themes.Renkoo = new dc.Theme({
+	themes.Renkoo = new Theme({
 		chart: {
 			fill:      "#123666",
 			pageStyle: {backgroundColor: "#123666", backgroundImage: "none", color: "#95afdb"}
@@ -26,7 +22,7 @@ dojo.require("dojox.charting.Theme");
 				color:     "#95afdb",
 				position:  "center",
 				font:      "normal normal normal 7pt Lucida Grande, Helvetica, Arial, sans-serif",	// labels on axis
-				fontColor: "#95afdb"								// color of labels
+				fontColor: "#95afdb"	// color of labels
 			}
 		},
 		series: {
@@ -78,8 +74,10 @@ dojo.require("dojox.charting.Theme");
 	themes.Renkoo.post = function(theme, elementType){
 		theme = Theme.prototype.post.apply(this, arguments);
 		if((elementType == "slice" || elementType == "circle") && theme.series.fill && theme.series.fill.type == "radial"){
-			theme.series.fill = dojox.gfx.gradutils.reverse(theme.series.fill);
+			theme.series.fill = gradutils.reverse(theme.series.fill);
 		}
 		return theme;
 	};
-})();
+	
+	return themes.Renkoo;
+});
diff --git a/dojox/charting/themes/RoyalPurples.js b/dojox/charting/themes/RoyalPurples.js
index e09229e..c424a32 100644
--- a/dojox/charting/themes/RoyalPurples.js
+++ b/dojox/charting/themes/RoyalPurples.js
@@ -1,9 +1,6 @@
-dojo.provide("dojox.charting.themes.RoyalPurples");
-dojo.require("dojox.charting.Theme");
-
-(function(){
-	var dxc=dojox.charting;
-	dxc.themes.RoyalPurples=new dxc.Theme({
+define(["../Theme", "./common"], function(Theme, themes){
+	
+	themes.RoyalPurples=new Theme({
 		colors: [
 			"#473980",
 			"#685aa7",
@@ -12,4 +9,6 @@ dojo.require("dojox.charting.Theme");
 			"#7267ae"
 		]
 	});
-})();
+	
+	return themes.RoyalPurples;
+});
diff --git a/dojox/charting/themes/SageToLime.js b/dojox/charting/themes/SageToLime.js
index 6035f3c..e18020f 100644
--- a/dojox/charting/themes/SageToLime.js
+++ b/dojox/charting/themes/SageToLime.js
@@ -1,9 +1,6 @@
-dojo.provide("dojox.charting.themes.SageToLime");
-dojo.require("dojox.charting.Theme");
-
-(function(){
-	var dxc=dojox.charting;
-	dxc.themes.SageToLime=new dxc.Theme({
+define(["../Theme", "./common"], function(Theme, themes){
+	
+	themes.SageToLime=new Theme({
 		colors: [
 			"#abdbcb",
 			"#435a51",
@@ -17,4 +14,6 @@ dojo.require("dojox.charting.Theme");
 			"#68c5ad"
 		]
 	});
-})();
+	
+	return themes.SageToLime;
+});
diff --git a/dojox/charting/themes/Shrooms.js b/dojox/charting/themes/Shrooms.js
index f0afd32..bd43a8e 100644
--- a/dojox/charting/themes/Shrooms.js
+++ b/dojox/charting/themes/Shrooms.js
@@ -1,11 +1,7 @@
-dojo.provide("dojox.charting.themes.Shrooms");
-dojo.require("dojox.charting.Theme");
-
-(function(){
+define(["../Theme", "./common"], function(Theme, 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).
-	var dxc=dojox.charting;
-	dxc.themes.Shrooms=new dxc.Theme({
+	themes.Shrooms = new Theme({
 		colors: [
 			"#bf1313", // 0
 			"#69bf13", // 90
@@ -21,4 +17,6 @@ dojo.require("dojox.charting.Theme");
 			"#bf1369"  // 330
 		]
 	});
-})();
+	
+	return themes.Shrooms;
+});
diff --git a/dojox/charting/themes/ThreeD.js b/dojox/charting/themes/ThreeD.js
index 64368e0..a58a830 100644
--- a/dojox/charting/themes/ThreeD.js
+++ b/dojox/charting/themes/ThreeD.js
@@ -1,15 +1,7 @@
-dojo.provide("dojox.charting.themes.ThreeD");
+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){
 
-dojo.require("dojo.colors"); // for dojo.Color.sanitize()
-dojo.require("dojox.charting.Theme");
-dojo.require("dojox.charting.themes.gradientGenerator");
-
-dojo.require("dojox.charting.themes.PrimaryColors"); // as a baseline theme
-
-(function(){
-	var dc = dojox.charting, themes = dc.themes, Theme = dc.Theme,
-		gi = themes.gradientGenerator.generateGradientByIntensity,
-		colors = ["#f00", "#0f0", "#00f", "#ff0", "#0ff", "#f0f"],	// the same is in PrimaryColors
+	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},
 		// 3D cylinder map is calculated using dojox.gfx3d
 		cyl3dMap = [
@@ -18,9 +10,9 @@ dojo.require("dojox.charting.themes.PrimaryColors"); // as a baseline theme
 			{o: 0.80, i: 128}, {o: 0.90, i: 102}, {o: 1.00, i: 174}
 		],
 		hiliteIndex = 2, hiliteIntensity = 100, lumStroke = 50,
-		cyl3dFills = dojo.map(colors, function(c){
-			var fill = dojo.delegate(defaultFill),
-				colors = fill.colors = themes.gradientGenerator.generateGradientByIntensity(c, cyl3dMap),
+		cyl3dFills = ArrayUtil.map(colors, function(c){
+			var fill = lang.delegate(defaultFill),
+				colors = fill.colors = gradientGenerator.generateGradientByIntensity(c, cyl3dMap),
 				hilite = colors[hiliteIndex].color;
 			// add highlight
 			hilite.r += hiliteIntensity;
@@ -30,7 +22,7 @@ dojo.require("dojox.charting.themes.PrimaryColors"); // as a baseline theme
 			return fill;
 		});
 
-	themes.ThreeD = themes.PrimaryColors.clone();
+	themes.ThreeD = PrimaryColors.clone();
 	themes.ThreeD.series.shadow = {dx: 1, dy: 1, width: 3, color: [0, 0, 0, 0.15]};
 
 	themes.ThreeD.next = function(elementType, mixin, doPost){
@@ -46,4 +38,6 @@ dojo.require("dojox.charting.themes.PrimaryColors"); // as a baseline theme
 		}
 		return Theme.prototype.next.apply(this, arguments);
 	};
-})();
+	
+	return themes.ThreeD;
+});
diff --git a/dojox/charting/themes/Tom.js b/dojox/charting/themes/Tom.js
index a099379..1691867 100644
--- a/dojox/charting/themes/Tom.js
+++ b/dojox/charting/themes/Tom.js
@@ -1,15 +1,11 @@
-dojo.provide("dojox.charting.themes.Tom");
+define(["../Theme", "dojox/gfx/gradutils", "./common"], function(Theme, gradutils, themes){
 
-dojo.require("dojox.gfx.gradutils");
-dojo.require("dojox.charting.Theme");
-
-// created by Tom Trenka
-
-(function(){
-	var dc = dojox.charting, themes = dc.themes, Theme = dc.Theme, g = Theme.generateGradient,
+	// created by Tom Trenka
+	
+	var g = Theme.generateGradient,
 		defaultFill = {type: "linear", space: "shape", x1: 0, y1: 0, x2: 0, y2: 100};
 	
-	themes.Tom = new dc.Theme({
+	themes.Tom = new Theme({
 		chart: {
 			fill:      "#181818",
 			stroke:    {color: "#181818"},
@@ -27,7 +23,7 @@ dojo.require("dojox.charting.Theme");
 				color:     "#888c76",
 				position:  "center",
 				font:      "normal normal normal 7pt Helvetica, Arial, sans-serif",	// labels on axis
-				fontColor: "#888c76"								// color of labels
+				fontColor: "#888c76"	// color of labels
 			}
 		},
 		series: {
@@ -80,8 +76,10 @@ dojo.require("dojox.charting.Theme");
 	themes.Tom.post = function(theme, elementType){
 		theme = Theme.prototype.post.apply(this, arguments);
 		if((elementType == "slice" || elementType == "circle") && theme.series.fill && theme.series.fill.type == "radial"){
-			theme.series.fill = dojox.gfx.gradutils.reverse(theme.series.fill);
+			theme.series.fill = gradutils.reverse(theme.series.fill);
 		}
 		return theme;
 	};
-})();
+	
+	return themes.Tom;
+});
diff --git a/dojox/charting/themes/Tufte.js b/dojox/charting/themes/Tufte.js
index 1ced7cc..0792185 100644
--- a/dojox/charting/themes/Tufte.js
+++ b/dojox/charting/themes/Tufte.js
@@ -1,54 +1,54 @@
-dojo.provide("dojox.charting.themes.Tufte");
-dojo.require("dojox.charting.Theme");
-
-/*
-	A charting theme based on the principles championed by
-	Edward Tufte.  By Alex Russell, Dojo Project Lead.
-*/
-dojox.charting.themes.Tufte = new dojox.charting.Theme({
-	chart: {
-		stroke: null,
-		fill: "inherit"
-	},
-	plotarea: {
-		// stroke: { width: 0.2, color: "#666666" },
-		stroke: null,
-		fill: "transparent"
-	},
-	axis: {
-		stroke: {width: 1, color: "#ccc"},
-		majorTick:{
-			color:	"black",
-			width:	1,
-			length: 5
+define(["../Theme", "dojo/_base/Color", "./common"], function(Theme, Color, themes){
+	/*
+		A charting theme based on the principles championed by
+		Edward Tufte.  By Alex Russell, Dojo Project Lead.
+	*/
+	themes.Tufte = new Theme({
+		chart: {
+			stroke: null,
+			fill: "inherit"
 		},
-		minorTick: {
-			color:	"#666",
-			width:	1,
-			length:	2
+		plotarea: {
+			// stroke: { width: 0.2, color: "#666666" },
+			stroke: null,
+			fill: "transparent"
 		},
-		font: "normal normal normal 8pt Tahoma",
-		fontColor: "#999"
-	},
-	series: {
-		outline:   null,
-		stroke:	   {width: 1, color: "black"},
-		// fill:   "#3b444b",
-		fill:      new dojo.Color([0x3b, 0x44, 0x4b, 0.85]),
-		font: "normal normal normal 7pt Tahoma",
-		fontColor: "#717171"
-	},
-	marker: {
-		stroke:    {width: 1, color: "black"},
-		fill:      "#333",
-		font: "normal normal normal 7pt Tahoma",
-		fontColor: "black"
-	},
-	colors:[
-		dojo.colorFromHex("#8a8c8f"),
-		dojo.colorFromHex("#4b4b4b"),
-		dojo.colorFromHex("#3b444b"),
-		dojo.colorFromHex("#2e2d30"),
-		dojo.colorFromHex("#000000")
-	]
+		axis: {
+			stroke: {width: 1, color: "#ccc"},
+			majorTick:{
+				color:	"black",
+				width:	1,
+				length: 5
+			},
+			minorTick: {
+				color:	"#666",
+				width:	1,
+				length:	2
+			},
+			font: "normal normal normal 8pt Tahoma",
+			fontColor: "#999"
+		},
+		series: {
+			outline:   null,
+			stroke:	   {width: 1, color: "black"},
+			// fill:   "#3b444b",
+			fill:      new Color([0x3b, 0x44, 0x4b, 0.85]),
+			font: "normal normal normal 7pt Tahoma",
+			fontColor: "#717171"
+		},
+		marker: {
+			stroke:    {width: 1, color: "black"},
+			fill:      "#333",
+			font: "normal normal normal 7pt Tahoma",
+			fontColor: "black"
+		},
+		colors:[
+			Color.fromHex("#8a8c8f"),
+			Color.fromHex("#4b4b4b"),
+			Color.fromHex("#3b444b"),
+			Color.fromHex("#2e2d30"),
+			Color.fromHex("#000000")
+		]	
+	});
+	return themes.Tufte;
 });
diff --git a/dojox/charting/themes/WatersEdge.js b/dojox/charting/themes/WatersEdge.js
index 31e80ef..08b1fb9 100644
--- a/dojox/charting/themes/WatersEdge.js
+++ b/dojox/charting/themes/WatersEdge.js
@@ -1,9 +1,6 @@
-dojo.provide("dojox.charting.themes.WatersEdge");
-dojo.require("dojox.charting.Theme");
-
-(function(){
-	var dxc=dojox.charting;
-	dxc.themes.WatersEdge=new dxc.Theme({
+define(["../Theme", "./common"], function(Theme, themes){
+	
+	themes.WatersEdge = new Theme({
 		colors: [
 			"#437cc0",
 			"#6256a5",
@@ -12,4 +9,6 @@ dojo.require("dojox.charting.Theme");
 			"#4b66b0"
 		]
 	});
-})();
+	
+	return  themes.WatersEdge;
+});
diff --git a/dojox/charting/themes/Wetland.js b/dojox/charting/themes/Wetland.js
index 654a65b..ec1a43e 100644
--- a/dojox/charting/themes/Wetland.js
+++ b/dojox/charting/themes/Wetland.js
@@ -1,9 +1,6 @@
-dojo.provide("dojox.charting.themes.Wetland");
-dojo.require("dojox.charting.Theme");
-
-(function(){
-	var dxc=dojox.charting;
-	dxc.themes.Wetland=new dxc.Theme({
+define(["../Theme", "./common"], function(Theme, themes){
+	
+	themes.Wetland = new Theme({
 		colors: [
 			"#bfbc64",
 			"#737130",
@@ -12,4 +9,6 @@ dojo.require("dojox.charting.Theme");
 			"#8d3c42"
 		]
 	});
-})();
+	
+	return themes.Wetland;
+});
diff --git a/dojox/charting/themes/common.js b/dojox/charting/themes/common.js
new file mode 100644
index 0000000..c6c9e54
--- /dev/null
+++ b/dojox/charting/themes/common.js
@@ -0,0 +1,3 @@
+define(["dojo/_base/lang"], function(lang){
+	return lang.getObject("dojox.charting.themes", true);
+});
diff --git a/dojox/charting/themes/gradientGenerator.js b/dojox/charting/themes/gradientGenerator.js
index c86d34e..d4994f8 100644
--- a/dojox/charting/themes/gradientGenerator.js
+++ b/dojox/charting/themes/gradientGenerator.js
@@ -1,8 +1,7 @@
-dojo.provide("dojox.charting.themes.gradientGenerator");
-dojo.require("dojox.charting.Theme");
-
-(function(){
-	var gg = dojox.charting.themes.gradientGenerator;
+define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/Color", "../Theme", "dojox/color/_base", "./common"], 
+	function(lang, arr, Color, Theme, dxcolor, themes){
+	
+	var gg = lang.getObject("gradientGenerator", true, themes);
 
 	gg.generateFills = function(colors, fillPattern, lumFrom, lumTo){
 		//	summary:
@@ -15,8 +14,7 @@ dojo.require("dojox.charting.Theme");
 		//		Initial luminance value (0-100).
 		//	lumTo: Number:
 		//		Final luminance value (0-100).
-		var Theme = dojox.charting.Theme;
-		return dojo.map(colors, function(c){	// Array
+		return arr.map(colors, function(c){	// Array
 			return Theme.generateHslGradient(c, fillPattern, lumFrom, lumTo);
 		});
 	};
@@ -32,8 +30,7 @@ dojo.require("dojox.charting.Theme");
 		//		Initial luminance value (0-100).
 		//	lumTo: Number:
 		//		Final luminance value (0-100).
-		var Theme = dojox.charting.Theme;
-		dojo.forEach(themes, function(t){
+		arr.forEach(themes, function(t){
 			if(t.fill && !t.fill.type){
 				t.fill = Theme.generateHslGradient(t.fill, fillPattern, lumFrom, lumTo);
 			}
@@ -53,9 +50,8 @@ dojo.require("dojox.charting.Theme");
 		//		Final luminance value (0-100).
 		//	lumStroke: Number:
 		//		Stroke luminance value (0-100).
-		var Theme = dojox.charting.Theme;
-		return dojo.map(colors, function(c){	// Array
-			c = new dojox.color.Color(c);
+		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)}
@@ -71,13 +67,15 @@ dojo.require("dojox.charting.Theme");
 		//	intensityMap: Array:
 		//		Array of tuples {o, i}, where o is a gradient offset (0-1),
 		//		and i is an intensity (0-255).
-		color = new dojo.Color(color);
-		return dojo.map(intensityMap, function(stop){	// Array
+		color = new Color(color);
+		return arr.map(intensityMap, function(stop){	// Array
 			var s = stop.i / 255;
 			return {
 				offset: stop.o,
-				color:  new dojo.Color([color.r * s, color.g * s, color.b * s, color.a])
+				color:  new Color([color.r * s, color.g * s, color.b * s, color.a])
 			};
 		});
 	}
-})();
\ No newline at end of file
+	
+	return gg;
+});
diff --git a/dojox/charting/widget/BidiSupport.js b/dojox/charting/widget/BidiSupport.js
new file mode 100644
index 0000000..015c794
--- /dev/null
+++ b/dojox/charting/widget/BidiSupport.js
@@ -0,0 +1,92 @@
+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;
+	}
+		
+});
diff --git a/dojox/charting/widget/Chart.js b/dojox/charting/widget/Chart.js
index 72b8835..7492a4a 100644
--- a/dojox/charting/widget/Chart.js
+++ b/dojox/charting/widget/Chart.js
@@ -1,19 +1,16 @@
-dojo.provide("dojox.charting.widget.Chart");
-
-dojo.require("dijit._Widget");
-dojo.require("dojox.charting.Chart");
-dojo.require("dojox.lang.functional");
-
-(function(){
+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;
+=====*/
 	var collectParams, collectAxisParams, collectPlotParams,
 		collectActionParams, collectDataParams,
 		notNull = function(o){ return o; },
-		df = dojox.lang.functional,
-		du = dojox.lang.utils,
-		dc = dojox.charting,
-		d = dojo;
+		dc = lang.getObject("dojox.charting");
 	
-	dojo.declare("dojox.charting.widget.Chart", dijit._Widget, {
+	var ChartWidget = declare("dojox.charting.widget.Chart", Widget, {
 		// parameters for the markup
 		
 		// theme for the chart
@@ -22,27 +19,32 @@ dojo.require("dojox.lang.functional");
 		// margins for the chart: {l: 10, r: 10, t: 10, b: 10}
 		margins: null,
 		
-		// chart area
-		stroke: null,
-		fill:   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(){
-			var n = this.domNode = this.srcNodeRef;
+			this.inherited(arguments);
+			
+			n = this.domNode;
 			
 			// collect chart parameters
-			var axes    = d.query("> .axis", n).map(collectAxisParams).filter(notNull),
-				plots   = d.query("> .plot", n).map(collectPlotParams).filter(notNull),
-				actions = d.query("> .action", n).map(collectActionParams).filter(notNull),
-				series  = d.query("> .series", n).map(collectDataParams).filter(notNull);
+			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 dc.Chart(n, {
+			var c = this.chart = new Chart(n, {
 				margins: this.margins,
 				stroke:  this.stroke,
-				fill:    this.fill
+				fill:    this.fill,
+				textDir: this.textDir
 			});
 			
 			// add collected parameters
@@ -57,7 +59,7 @@ dojo.require("dojox.lang.functional");
 			});
 			
 			this.actions = actions.map(function(action){
-				return new action.action(c, action.plot, action.kwArgs)
+				return new action.action(c, action.plot, action.kwArgs);
 			});
 			
 			var render = df.foldl(series, function(render, series){
@@ -81,18 +83,18 @@ dojo.require("dojox.lang.functional");
 					);
 					if(series.kwArgs.sort){
 						// sort is a complex object type and doesn't survive coercian
-						kw.sort = dojo.clone(series.kwArgs.sort);
+						kw.sort = lang.clone(series.kwArgs.sort);
 					}
-					d.mixin(kw, {
+					lang.mixin(kw, {
 						onComplete: function(data){
 							var values;
 							if("valueFn" in series.kwArgs){
 								var fn = series.kwArgs.valueFn;
-								values = d.map(data, function(x){
+								values = arr.map(data, function(x){
 									return fn(series.data.getValue(x, series.field, 0));
 								});
 							}else{
-								values = d.map(data, function(x){
+								values = arr.map(data, function(x){
 									return series.data.getValue(x, series.field, 0);
 								});
 							}
@@ -147,12 +149,12 @@ dojo.require("dojox.lang.functional");
 		var o = {name: name, kwArgs: {}}, kw = o.kwArgs;
 		if(type){
 			if(dc.axis2d[type]){
-				type = dojox._scopeName + ".charting.axis2d." + type;
+				type = dojo._scopeName + "x.charting.axis2d." + type;
 			}
 			var axis = eval("(" + type + ")");
 			if(axis){ kw.type = axis; }
 		}else{
-			type = dojox._scopeName + ".charting.axis2d.Default";
+			type = dojo._scopeName + "x.charting.axis2d.Default";
 		}
 		collectParams(node, type, kw);
 		// compatibility conversions
@@ -177,12 +179,12 @@ dojo.require("dojox.lang.functional");
 		var o = {name: name, kwArgs: {}}, kw = o.kwArgs;
 		if(type){
 			if(dc.plot2d && dc.plot2d[type]){
-				type = dojox._scopeName + ".charting.plot2d." + type;
+				type = dojo._scopeName + "x.charting.plot2d." + type;
 			}
 			var plot = eval("(" + type + ")");
 			if(plot){ kw.type = plot; }
 		}else{
-			type = dojox._scopeName + ".charting.plot2d.Default";
+			type = dojo._scopeName + "x.charting.plot2d.Default";
 		}
 		collectParams(node, type, kw);
 		return o;
@@ -195,7 +197,7 @@ dojo.require("dojox.lang.functional");
 		var o = {plot: plot, kwArgs: {}}, kw = o.kwArgs;
 		if(type){
 			if(dc.action2d[type]){
-				type = dojox._scopeName + ".charting.action2d." + type;
+				type = dojo._scopeName + "x.charting.action2d." + type;
 			}
 			var action = eval("(" + type + ")");
 			if(!action){ return null; }
@@ -208,7 +210,7 @@ dojo.require("dojox.lang.functional");
 	};
 
 	collectDataParams = function(node){
-		var ga = d.partial(d.attr, node);
+		var ga = lang.partial(html.attr, node);
 		var name = ga("name");
 		if(!name){ return null; }
 		var o = { name: name, kwArgs: {} }, kw = o.kwArgs, t;
@@ -233,7 +235,7 @@ dojo.require("dojox.lang.functional");
 		t = ga("data");
 		if(t != null){
 			o.type = "data";
-			o.data = t ? dojo.map(String(t).split(','), Number) : [];
+			o.data = t ? arr.map(String(t).split(','), Number) : [];
 			return o;
 		}
 		t = ga("array");
@@ -259,9 +261,11 @@ dojo.require("dojox.lang.functional");
 			t = ga("sort");
 			if(!!t){ kw.sort = eval("("+t+")"); }
 			t = ga("valueFn");
-			if(!!t){ kw.valueFn = df.lambda(t); }
+			if(!!t){ kw.valueFn = dfl.lambda(t); }
 			return o;
 		}
 		return null;
 	};
-})();
+	
+	return ChartWidget;
+});
diff --git a/dojox/charting/widget/Chart2D.js b/dojox/charting/widget/Chart2D.js
index d21ebf7..2e37762 100644
--- a/dojox/charting/widget/Chart2D.js
+++ b/dojox/charting/widget/Chart2D.js
@@ -1,17 +1,6 @@
-dojo.provide("dojox.charting.widget.Chart2D");
-
-dojo.deprecated("dojox.charting.widget.Chart2D", "Use dojo.charting.widget.Chart instead and require all other components explicitly", "2.0");
-
-dojo.require("dojox.charting.widget.Chart");
-
-// require all actions to support references by name
-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");
-
-// require Chart2D to get compatibility on chart type reference by name
-dojo.require("dojox.charting.Chart2D");
-
-dojox.charting.widget.Chart2D =  dojox.charting.widget.Chart;
+define(["dojo/_base/kernel", "./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;
+});
diff --git a/dojox/charting/widget/Legend.js b/dojox/charting/widget/Legend.js
index a947248..f358749 100644
--- a/dojox/charting/widget/Legend.js
+++ b/dojox/charting/widget/Legend.js
@@ -1,167 +1,181 @@
-dojo.provide("dojox.charting.widget.Legend");
+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;
+=====*/
 
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
+	var REVERSED_SERIES = /\.(StackedColumns|StackedAreas|ClusteredBars)$/;
 
-dojo.require("dojox.lang.functional.array");
-dojo.require("dojox.lang.functional.fold");
+	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
 
-dojo.declare("dojox.charting.widget.Legend", [dijit._Widget, dijit._Templated], {
-	// 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,
-	swatchSize: 18,
-	
-	templateString: "<table dojoAttachPoint='legendNode' class='dojoxLegendNode' role='group' aria-label='chart legend'><tbody dojoAttachPoint='legendBody'></tbody></table>",
-	
-	legendNode: null,
-	legendBody: null,
-	
-	postCreate: function(){
-		if(!this.chart){
-			if(!this.chartRef){ return; }
-			this.chart = dijit.byId(this.chartRef);
+		chartRef:   "",
+		horizontal: true,
+		swatchSize: 18,
+
+		legendBody: null,
+
+		postCreate: function(){
 			if(!this.chart){
-				var node = dojo.byId(this.chartRef);
-				if(node){
-					this.chart = dijit.byNode(node);
-				}else{
-					console.log("Could not find chart instance with id: " + this.chartRef);
-					return;
+				if(!this.chartRef){ return; }
+				this.chart = widgetManager.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;
+					}
 				}
+				this.series = this.chart.chart.series;
+			}else{
+				this.series = this.chart.series;
 			}
-			this.series = this.chart.chart.series;
-		}else{
-			this.series = this.chart.series;
-		}
-		
-		this.refresh();
-	},
-	refresh: function(){
-		// summary: regenerates the legend to reflect changes to the chart
-		
-		var df = dojox.lang.functional;
 
-		// cleanup
-		if(this._surfaces){
-			dojo.forEach(this._surfaces, function(surface){
-				surface.destroy();
-			});
-		}
-		this._surfaces = [];
-		while(this.legendBody.lastChild){
-			dojo.destroy(this.legendBody.lastChild);
-		}
+			this.refresh();
+		},
+		buildRendering: function(){
+			this.domNode = domFactory.create("table",
+					{role: "group", "aria-label": "chart legend", "class": "dojoxLegendNode"});
+			this.legendBody = domFactory.create("tbody", null, this.domNode);
+			this.inherited(arguments);
+		},
+		refresh: function(){
+			// summary: regenerates the legend to reflect changes to the chart
 
-		if(this.horizontal){
-			dojo.addClass(this.legendNode, "dojoxLegendHorizontal");
-			// make a container <tr>
-			this._tr = dojo.create("tr", null, this.legendBody);
-			this._inrow = 0;
-		}
-		
-		var s = this.series;
-		if(s.length == 0){
-			return;
-		}
-		if(s[0].chart.stack[0].declaredClass == "dojox.charting.plot2d.Pie"){
-			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;
+			// cleanup
+			if(this._surfaces){
+				arrayUtil.forEach(this._surfaces, function(surface){
+					surface.destroy();
+				});
+			}
+			this._surfaces = [];
+			while(this.legendBody.lastChild){
+				domFactory.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._inrow = 0;
+			}
+
+			var s = this.series;
+			if(s.length == 0){
+				return;
+			}
+			if(s[0].chart.stack[0].declaredClass == "dojox.charting.plot2d.Pie"){
+				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){
+						this._addLabel(t.dyn[i], t._getLabel(x * 100) + "%");
+					}, this);
+				}else{
+					arrayUtil.forEach(t.run.data, function(x, i){
+						this._addLabel(t.dyn[i], x.legend || x.text || x.y);
+					}, this);
 				}
-				var slices = df.map(filteredRun, "/this", df.foldl(filteredRun, "+", 0));
-				dojo.forEach(slices, function(x, i){
-					this._addLabel(t.dyn[i], t._getLabel(x * 100) + "%");
-				}, this);
 			}else{
-				dojo.forEach(t.run.data, function(x, i){
-					this._addLabel(t.dyn[i], x.legend || x.text || x.y);
+				if(this._isReversal()){
+					s = s.slice(0).reverse();
+				}
+				arrayUtil.forEach(s, function(x){
+					this._addLabel(x.dyn, x.legend || x.name);
 				}, this);
 			}
-		}else{
-			dojo.forEach(s, function(x){
-				this._addLabel(x.dyn, x.legend || x.name);
-			}, this);
-		}
-	},
-	_addLabel: function(dyn, label){
-		// create necessary elements
-		var wrapper = dojo.create("td"),
-			icon = dojo.create("div", null, wrapper),
-			text = dojo.create("label", null, wrapper),
-			div  = dojo.create("div", {
-				style: {
-					"width": this.swatchSize + "px",
-					"height":this.swatchSize + "px",
-					"float": "left"
+		},
+		_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", {
+					style: {
+						"width": this.swatchSize + "px",
+						"height":this.swatchSize + "px",
+						"float": "left"
+					}
+				}, icon);
+			domClass.add(icon, "dojoxLegendIcon dijitInline");
+			domClass.add(text, "dojoxLegendText");
+			// create a skeleton
+			if(this._tr){
+				// horizontal
+				this._tr.appendChild(wrapper);
+				if(++this._inrow === this.horizontal){
+					// make a fresh container <tr>
+					this._tr = domFactory.create("tr", null, this.legendBody);
+					this._inrow = 0;
 				}
-			}, icon);
-		dojo.addClass(icon, "dojoxLegendIcon dijitInline");
-		dojo.addClass(text, "dojoxLegendText");
-		// create a skeleton
-		if(this._tr){
-			// horizontal
-			this._tr.appendChild(wrapper);
-			if(++this._inrow === this.horizontal){
-				// make a fresh container <tr>
-				this._tr = dojo.create("tr", null, this.legendBody);
-				this._inrow = 0;
-			}
-		}else{
-			// vertical
-			var tr = dojo.create("tr", null, this.legendBody);
-			tr.appendChild(wrapper);
-		}
-		
-		// populate the skeleton
-		this._makeIcon(div, dyn);
-		text.innerHTML = String(label);
-	},
-	_makeIcon: function(div, dyn){
-		var mb = { h: this.swatchSize, w: this.swatchSize };
-		var surface = dojox.gfx.createSurface(div, mb.w, mb.h);
-		this._surfaces.push(surface);
-		if(dyn.fill){
-			// regions
-			surface.createRect({x: 2, y: 2, width: mb.w - 4, height: mb.h - 4}).
-				setFill(dyn.fill).setStroke(dyn.stroke);
-		}else if(dyn.stroke || dyn.marker){
-			// draw line
-			var line = {x1: 0, y1: mb.h / 2, x2: mb.w, y2: mb.h / 2};
-			if(dyn.stroke){
-				surface.createLine(line).setStroke(dyn.stroke);
+			}else{
+				// vertical
+				var tr = domFactory.create("tr", null, this.legendBody);
+				tr.appendChild(wrapper);
 			}
-			if(dyn.marker){
-				// draw marker on top
-				var c = {x: mb.w / 2, y: mb.h / 2};
+
+			// populate the skeleton
+			this._makeIcon(div, dyn);
+			text.innerHTML = String(label);
+			text.dir = this.getTextDir(label, text.dir);
+		},
+		_makeIcon: function(div, dyn){
+			var mb = { h: this.swatchSize, w: this.swatchSize };
+			var surface = gfx.createSurface(div, mb.w, mb.h);
+			this._surfaces.push(surface);
+			if(dyn.fill){
+				// regions
+				surface.createRect({x: 2, y: 2, width: mb.w - 4, height: mb.h - 4}).
+					setFill(dyn.fill).setStroke(dyn.stroke);
+			}else if(dyn.stroke || dyn.marker){
+				// draw line
+				var line = {x1: 0, y1: mb.h / 2, x2: mb.w, y2: 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.createLine(line).setStroke(dyn.stroke);
 				}
+				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);
+					}
+				}
+			}else{
+				// nothing
+				surface.createRect({x: 2, y: 2, width: mb.w - 4, height: mb.h - 4}).
+					setStroke("black");
+				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");
 			}
-		}else{
-			// nothing
-			surface.createRect({x: 2, y: 2, width: mb.w - 4, height: mb.h - 4}).
-				setStroke("black");
-			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);
+			});
 		}
-	}
+	});
 });
diff --git a/dojox/charting/widget/SelectableLegend.js b/dojox/charting/widget/SelectableLegend.js
index b3ed6c8..490e189 100644
--- a/dojox/charting/widget/SelectableLegend.js
+++ b/dojox/charting/widget/SelectableLegend.js
@@ -1,13 +1,86 @@
-dojo.provide("dojox.charting.widget.SelectableLegend");
-
-dojo.require("dojox.charting.widget.Legend");
-dojo.require("dijit.form.CheckBox");
-dojo.require("dojox.charting.action2d.Highlight");
-
-(function(){
-	var df = dojox.lang.functional;
-	
-	dojo.declare("dojox.charting.widget.SelectableLegend", [dojox.charting.widget.Legend], {
+define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "dojo/query", "dojo/_base/html", 
+		"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",
+		"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;
+=====*/
+	var FocusManager = declare(null, {
+		//	summary:
+		//		It will take legend as a tab stop, and using
+		//		cursor keys to navigate labels within the legend.
+		constructor: function(legend){
+			this.legend = legend;
+			this.index = 0;
+			this.horizontalLength = this._getHrizontalLength();
+			arrayUtil.forEach(legend.legends, function(item, i){
+				if(i > 0){
+					query("input", item).attr("tabindex", -1);
+				}
+			});
+			this.firstLabel = query("input", legend.legends[0])[0];
+			hub.connect(this.firstLabel, "focus", this, function(){this.legend.active = true;});
+			hub.connect(this.legend.domNode, "keydown", this, "_onKeyEvent");
+		},
+		_getHrizontalLength: function(){
+			var horizontal = this.legend.horizontal;
+			if(typeof horizontal == "number"){
+				return Math.min(horizontal, this.legend.legends.length);
+			}else if(!horizontal){
+				return 1;
+			}else{
+				return this.legend.legends.length;
+			}
+		},
+		_onKeyEvent: function(e){
+			//	if not focused
+			if(!this.legend.active){
+				return;
+			}
+			//	lose focus
+			if(e.keyCode == keys.TAB){
+				this.legend.active = false;
+				return;
+			}
+			//	handle with arrow keys
+			var max = this.legend.legends.length;
+			switch(e.keyCode){
+				case keys.LEFT_ARROW:
+					this.index--;
+					if(this.index < 0){
+						this.index += max;
+					}
+					break;
+				case keys.RIGHT_ARROW:
+					this.index++;
+					if(this.index >= max){
+						this.index -= max;
+					}
+					break;
+				case keys.UP_ARROW:
+					if(this.index - this.horizontalLength >= 0){
+						this.index -= this.horizontalLength;
+					}
+					break;
+				case keys.DOWN_ARROW:
+					if(this.index + this.horizontalLength < max){
+						this.index += this.horizontalLength;
+					}
+					break;
+				default:
+					return;
+			}
+			this._moveToFocus();
+			Event.stop(e);
+		},
+		_moveToFocus: function(){
+			query("input", this.legend.legends[this.index])[0].focus();
+		}
+	});
+			
+	declare("dojox.charting.widget.SelectableLegend", Legend, {
 		//	summary:
 		//		An enhanced chart legend supporting interactive events on data series
 		
@@ -25,26 +98,29 @@ dojo.require("dojox.charting.action2d.Highlight");
 			this.legends = [];
 			this.inherited(arguments);
 			this._applyEvents();
-			new dojox.charting.widget._FocusManager(this);
+			new FocusManager(this);
 		},
 		_addLabel: function(dyn, label){
 			this.inherited(arguments);
 			//	create checkbox
-			var legendNodes = dojo.query("td", this.legendBody);
+			var legendNodes = query("td", this.legendBody);
 			var currentLegendNode = legendNodes[legendNodes.length - 1];
 			this.legends.push(currentLegendNode);
-			var checkbox = new dijit.form.CheckBox({checked: true});
-			dojo.place(checkbox.domNode, currentLegendNode, "first");
+			var checkbox = new CheckBox({checked: true});
+			dom.place(checkbox.domNode, currentLegendNode, "first");
 			// connect checkbox and existed label
-			var label = dojo.query("label", currentLegendNode)[0];
-			dojo.attr(label, "for", checkbox.id);
+			var label = query("label", currentLegendNode)[0];
+			domProp.set(label, "for", checkbox.id);
 		},
 		_applyEvents: function(){
 			// summary:
 			//		Apply click-event on checkbox and hover-event on legend icon,
 			//		highlight data series or toggle it.
-			
-			dojo.forEach(this.legends, function(legend, i){
+			// if the chart has not yet been refreshed it will crash here (targetData.group == null)
+			if(this.chart.dirty){
+				return;
+			}
+			arrayUtil.forEach(this.legends, function(legend, i){
 				var targetData, shapes = [], plotName, seriesName;
 				if(this._isPie()){
 					targetData = this.chart.stack[0];
@@ -62,32 +138,32 @@ dojo.require("dojox.charting.action2d.Highlight");
 					strokes: df.map(shapes, "x.getStroke()")
 				};
 				//	toggle action
-				var legendCheckBox = dojo.query(".dijitCheckBox", legend)[0];
-				dojo.connect(legendCheckBox, "onclick", this, function(e){
+				var legendCheckBox = query(".dijitCheckBox", legend)[0];
+				hub.connect(legendCheckBox, "onclick", this, function(e){
 					this._toggle(shapes, i, legend.vanished, originalDyn, seriesName, plotName);
 					legend.vanished = !legend.vanished;
 					e.stopPropagation();
 				});
 				
 				//	highlight action
-				var legendIcon = dojo.query(".dojoxLegendIcon", legend)[0],
+				var legendIcon = query(".dojoxLegendIcon", legend)[0],
 					iconShape = this._getFilledShape(this._surfaces[i].children);
-				dojo.forEach(["onmouseenter", "onmouseleave"], function(event){
-					dojo.connect(legendIcon, event, this, function(e){
+				arrayUtil.forEach(["onmouseenter", "onmouseleave"], function(event){
+					hub.connect(legendIcon, event, this, function(e){
 						this._highlight(e, iconShape, shapes, i, legend.vanished, originalDyn, seriesName, plotName);
 					});
 				}, this);
 			},this);
 		},
 		_toggle: function(shapes, index, isOff, dyn, seriesName, plotName){
-			dojo.forEach(shapes, function(shape, i){
+			arrayUtil.forEach(shapes, function(shape, i){
 				var startFill = dyn.fills[i],
 					endFill = this._getTransitionFill(plotName),
 					startStroke = dyn.strokes[i],
 					endStroke = this.transitionStroke;
 				if(startFill){
-					if(endFill && (typeof startFill == "string" || startFill instanceof dojo.Color)){
-						dojox.gfx.fx.animateFill({
+					if(endFill && (typeof startFill == "string" || startFill instanceof Color)){
+						fx.animateFill({
 							shape: shape,
 							color: {
 								start: isOff ? endFill : startFill,
@@ -117,7 +193,7 @@ dojo.require("dojox.charting.action2d.Highlight");
 				};
 				anim.process(label);
 				//	highlight the data items
-				dojo.forEach(shapes, function(shape, i){
+				arrayUtil.forEach(shapes, function(shape, i){
 					shape.setFill(dyn.fills[i]);
 					var o = {
 						shape: shape,
@@ -132,7 +208,7 @@ dojo.require("dojox.charting.action2d.Highlight");
 		},
 		_getAnim: function(plotName){
 			if(!this.legendAnim[plotName]){
-				this.legendAnim[plotName] = new dojox.charting.action2d.Highlight(this.chart, plotName);
+				this.legendAnim[plotName] = new Highlight(this.chart, plotName);
 			}
 			return this.legendAnim[plotName];
 		},
@@ -157,81 +233,12 @@ dojo.require("dojox.charting.action2d.Highlight");
 			return this.chart.stack[0].declaredClass == "dojox.charting.plot2d.Pie";
 		}
 	});
+	
 	function formatEventType(type){
 		if(type == "mouseenter")return "onmouseover";
 		if(type == "mouseleave")return "onmouseout";
 		return "on" + type;
 	}
-	dojo.declare("dojox.charting.widget._FocusManager", null, {
-		//	summary:
-		//		It will take legend as a tab stop, and using
-		//		cursor keys to navigate labels within the legend.
-		constructor: function(legend){
-			this.legend = legend;
-			this.index = 0;
-			this.horizontalLength = this._getHrizontalLength();
-			dojo.forEach(legend.legends, function(item, i){
-				if(i > 0){
-					dojo.query("input", item).attr("tabindex", -1);
-				}
-			});
-			this.firstLabel = dojo.query("input", legend.legends[0])[0];
-			dojo.connect(this.firstLabel, "focus", this, function(){this.legend.active = true;});
-			dojo.connect(this.legend.legendNode, "keydown", this, "_onKeyEvent");
-		},
-		_getHrizontalLength: function(){
-			var horizontal = this.legend.horizontal;
-			if(typeof horizontal == "number"){
-				return Math.min(horizontal, this.legend.legends.length);
-			}else if(!horizontal){
-				return 1;
-			}else{
-				return this.legend.legends.length;
-			}
-		},
-		_onKeyEvent: function(e){
-			//	if not focused
-			if(!this.legend.active){
-				return;
-			}
-			//	lose focus
-			if(e.keyCode == dojo.keys.TAB){
-				this.legend.active = false;
-				return;
-			}
-			//	handle with arrow keys
-			var max = this.legend.legends.length;
-			switch(e.keyCode){
-				case dojo.keys.LEFT_ARROW:
-					this.index--;
-					if(this.index < 0){
-						this.index += max;
-					}
-					break;
-				case dojo.keys.RIGHT_ARROW:
-					this.index++;
-					if(this.index >= max){
-						this.index -= max;
-					}
-					break;
-				case dojo.keys.UP_ARROW:
-					if(this.index - this.horizontalLength >= 0){
-						this.index -= this.horizontalLength;
-					}
-					break;
-				case dojo.keys.DOWN_ARROW:
-					if(this.index + this.horizontalLength < max){
-						this.index += this.horizontalLength;
-					}
-					break;
-				default:
-					return;
-			}
-			this._moveToFocus();
-			dojo.stopEvent(e);
-		},
-		_moveToFocus: function(){
-			dojo.query("input", this.legend.legends[this.index])[0].focus();
-		}
-	});
-})();
+
+	return dojox.charting.widget.SelectableLegend;
+});
diff --git a/dojox/charting/widget/Sparkline.js b/dojox/charting/widget/Sparkline.js
index 3c6a335..9466ccd 100644
--- a/dojox/charting/widget/Sparkline.js
+++ b/dojox/charting/widget/Sparkline.js
@@ -1,18 +1,12 @@
-dojo.provide("dojox.charting.widget.Sparkline");
+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;
+=====*/
 
-dojo.require("dojox.charting.widget.Chart2D");
-dojo.require("dojox.charting.themes.GreySkies");
-
-dojo.require("dojox.charting.plot2d.Lines");
-
-(function(){
-
-	var d = dojo;
-
-	dojo.declare("dojox.charting.widget.Sparkline",
-		dojox.charting.widget.Chart2D,
-		{
-			theme: dojox.charting.themes.GreySkies,
+	declare("dojox.charting.widget.Sparkline", Chart, {
+			theme: GreySkies,
 			margins: { l: 0, r: 0, t: 0, b: 0 },
 			type: "Lines",
 			valueFn: "Number(x)",
@@ -28,9 +22,9 @@ dojo.require("dojox.charting.plot2d.Lines");
 			buildRendering: function(){
 				var n = this.srcNodeRef;
 				if(	!n.childNodes.length || // shortcut the query
-					!d.query("> .axis, > .plot, > .action, > .series", n).length){
+					!query("> .axis, > .plot, > .action, > .series", n).length){
 					var plot = document.createElement("div");
-					d.attr(plot, {
+					domProp.set(plot, {
 						"class": "plot",
 						"name": "default",
 						"type": this.type
@@ -38,7 +32,7 @@ dojo.require("dojox.charting.plot2d.Lines");
 					n.appendChild(plot);
 
 					var series = document.createElement("div");
-					d.attr(series, {
+					domProp.set(series, {
 						"class": "series",
 						plot: "default",
 						name: this.name,
@@ -46,11 +40,11 @@ dojo.require("dojox.charting.plot2d.Lines");
 						count: this.count,
 						valueFn: this.valueFn
 					});
-					d.forEach(
+					arrayUtil.forEach(
 						["store", "field", "query", "queryOptions", "sort", "data"],
 						function(i){
 							if(this[i].length){
-								d.attr(series, i, this[i]);
+								domProp.set(series, i, this[i]);
 							}
 						},
 						this
@@ -61,5 +55,4 @@ dojo.require("dojox.charting.plot2d.Lines");
 			}
 		}
 	);
-
-})();
+});
diff --git a/dojox/collections.js b/dojox/collections.js
index 6ff7320..c7f14c5 100644
--- a/dojox/collections.js
+++ b/dojox/collections.js
@@ -1,2 +1,3 @@
-dojo.provide("dojox.collections");
-dojo.require("dojox.collections._base");
+define(["./collections/_base"], function(collections){
+	return collections;
+});
diff --git a/dojox/collections/ArrayList.js b/dojox/collections/ArrayList.js
index 578ad38..915fae7 100644
--- a/dojox/collections/ArrayList.js
+++ b/dojox/collections/ArrayList.js
@@ -1,129 +1,132 @@
-dojo.provide("dojox.collections.ArrayList");
-dojo.require("dojox.collections._base");
-
-dojox.collections.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.
-		items.push(obj);
+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
+		var items=[];
+		if(arr) items=items.concat(arr);
 		this.count=items.length;
-	};
-	this.addRange=function(/* array */a){
-		//	summary
-		//	Add a range of objects to the ArrayList
-		if(a.getIterator){
-			var e=a.getIterator();
-			while(!e.atEnd()){
-				this.add(e.get());
-			}
+		this.add=function(/* object */obj){
+			//	summary
+			//	Add an element to the collection.
+			items.push(obj);
 			this.count=items.length;
-		}else{
-			for(var i=0; i<a.length; i++){
-				items.push(a[i]);
+		};
+		this.addRange=function(/* array */a){
+			//	summary
+			//	Add a range of objects to the ArrayList
+			if(a.getIterator){
+				var e=a.getIterator();
+				while(!e.atEnd()){
+					this.add(e.get());
+				}
+				this.count=items.length;
+			}else{
+				for(var i=0; i<a.length; i++){
+					items.push(a[i]);
+				}
+				this.count=items.length;
 			}
-			this.count=items.length;
-		}
-	};
-	this.clear=function(){
-		//	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
-		return new dojox.collections.ArrayList(items);	//	dojox.collections.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
+		};
+		this.clear=function(){
+			//	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
+			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
+			for(var i=0; i < items.length; i++){
+				if(items[i] == obj) {
+					return true;	//	bool
+				}
 			}
-		}
-		return false;	//	bool
-	};
-	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
-		return new dojox.collections.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.
-		for(var i=0; i < items.length; i++){
-			if(items[i] == obj) {
-				return i;	//	int
+			return false;	//	bool
+		};
+		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
+			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.
+			for(var i=0; i < items.length; i++){
+				if(items[i] == obj) {
+					return i;	//	int
+				}
 			}
-		}
-		return -1;	// int
-	};
-	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
-		return items[i];	//	object
-	};
-	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) {
+			return -1;	// int
+		};
+		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
+			return items[i];	//	object
+		};
+		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
 			items.splice(i,1);
+			this.count=items.length;
+		};
+		this.reverse=function(){
+			//	summary
+			//	Reverse the internal array
+			items.reverse();
+		};
+		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.
+			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.
+			return [].concat(items);
 		}
-		this.count=items.length;
-	};
-	this.removeAt=function(/* int */ i){
-		//	summary
-		//	return an array with function applied to all elements
-		items.splice(i,1);
-		this.count=items.length;
-	};
-	this.reverse=function(){
-		//	summary
-		//	Reverse the internal array
-		items.reverse();
-	};
-	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.
-		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.
-		return [].concat(items);
-	}
-	this.toString=function(/* string */ delim){
-		//	summary
-		//	implementation of toString, follows [].toString();
-		return items.join((delim||","));
-	};
-};
+		this.toString=function(/* string */ delim){
+			//	summary
+			//	implementation of toString, follows [].toString();
+			return items.join((delim||","));
+		};
+	};
+	return dxc.ArrayList;
+});
diff --git a/dojox/collections/BinaryTree.js b/dojox/collections/BinaryTree.js
index 72c660d..08638d4 100644
--- a/dojox/collections/BinaryTree.js
+++ b/dojox/collections/BinaryTree.js
@@ -1,207 +1,210 @@
-dojo.provide("dojox.collections.BinaryTree");
-dojo.require("dojox.collections._base");
-
-dojox.collections.BinaryTree=function(data){
-	function node(data, rnode, lnode){
-		this.value=data||null;
-		this.right=rnode||null;
-		this.left=lnode||null;
-		this.clone=function(){
-			var c=new node();
-			if(this.value.value){
-				c.value=this.value.clone();
-			}else{
-				c.value=this.value;
+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;
+			this.right=rnode||null;
+			this.left=lnode||null;
+			this.clone=function(){
+				var c=new node();
+				if(this.value.value){
+					c.value=this.value.clone();
+				}else{
+					c.value=this.value;
+				}
+				if(this.left!=null){
+					c.left=this.left.clone();
+				}
+				if(this.right!=null){
+					c.right=this.right.clone();
+				}
+				return c;
 			}
-			if(this.left!=null){
-				c.left=this.left.clone();
+			this.compare=function(n){
+				if(this.value>n.value){ return 1; }
+				if(this.value<n.value){ return -1; }
+				return 0;
 			}
-			if(this.right!=null){
-				c.right=this.right.clone();
+			this.compareData=function(d){
+				if(this.value>d){ return 1; }
+				if(this.value<d){ return -1; }
+				return 0;
 			}
-			return c;
 		}
-		this.compare=function(n){
-			if(this.value>n.value){ return 1; }
-			if(this.value<n.value){ return -1; }
-			return 0;
-		}
-		this.compareData=function(d){
-			if(this.value>d){ return 1; }
-			if(this.value<d){ return -1; }
-			return 0;
-		}
-	}
 
-	function inorderTraversalBuildup(current, a){
-		if(current){
-			inorderTraversalBuildup(current.left, a);
-			a.push(current.value);
-			inorderTraversalBuildup(current.right, a);
+		function inorderTraversalBuildup(current, a){
+			if(current){
+				inorderTraversalBuildup(current.left, a);
+				a.push(current.value);
+				inorderTraversalBuildup(current.right, a);
+			}
 		}
-	}
 
-	function preorderTraversal(current, sep){
-		var s="";
-		if (current){
-			s=current.value.toString() + sep;
-			s+=preorderTraversal(current.left, sep);
-			s+=preorderTraversal(current.right, sep);
-		}
-		return s;
-	}
-	function inorderTraversal(current, sep){
-		var s="";
-		if (current){
-			s=inorderTraversal(current.left, sep);
-			s+=current.value.toString() + sep;
-			s+=inorderTraversal(current.right, sep);
-		}
-		return s;
-	}
-	function postorderTraversal(current, sep){
-		var s="";
-		if (current){
-			s=postorderTraversal(current.left, sep);
-			s+=postorderTraversal(current.right, sep);
-			s+=current.value.toString() + sep;
+		function preorderTraversal(current, sep){
+			var s="";
+			if (current){
+				s=current.value.toString() + sep;
+				s+=preorderTraversal(current.left, sep);
+				s+=preorderTraversal(current.right, sep);
+			}
+			return s;
 		}
-		return s;
-	}
-	
-	function searchHelper(current, data){
-		if(!current){ return null; }
-		var i=current.compareData(data);
-		if(i==0){ return current; }
-		if(i>0){ return searchHelper(current.left, data); }
-		else{ return searchHelper(current.right, data); }
-	}
-
-	this.add=function(data){
-		var n=new node(data);
-		var i;
-		var current=root;
-		var parent=null;
-		while(current){
-			i=current.compare(n);
-			if(i==0){ return; }
-			parent=current;
-			if(i>0){ current=current.left; }
-			else{ current=current.right; }
+		function inorderTraversal(current, sep){
+			var s="";
+			if (current){
+				s=inorderTraversal(current.left, sep);
+				s+=current.value.toString() + sep;
+				s+=inorderTraversal(current.right, sep);
+			}
+			return s;
 		}
-		this.count++;
-		if(!parent){
-			root=n;
-		}else{
-			i=parent.compare(n);
-			if(i>0){
-				parent.left=n;
-			}else{
-				parent.right=n;
+		function postorderTraversal(current, sep){
+			var s="";
+			if (current){
+				s=postorderTraversal(current.left, sep);
+				s+=postorderTraversal(current.right, sep);
+				s+=current.value.toString() + sep;
 			}
+			return s;
 		}
-	};
-	this.clear=function(){
-		root=null;
-		this.count=0;
-	};
-	this.clone=function(){
-		var c=new dojox.collections.BinaryTree();
-		var itr=this.getIterator();
-		while(!itr.atEnd()){
-			c.add(itr.get());
+		
+		function searchHelper(current, data){
+			if(!current){ return null; }
+			var i=current.compareData(data);
+			if(i==0){ return current; }
+			if(i>0){ return searchHelper(current.left, data); }
+			else{ return searchHelper(current.right, data); }
 		}
-		return c;
-	};
-	this.contains=function(data){
-		return this.search(data) != null;
-	};
-	this.deleteData=function(data){
-		var current=root;
-		var parent=null;
-		var i=current.compareData(data);
-		while(i!=0&&current!=null){
-			if(i>0){
-				parent=current;
-				current=current.left;
-			}else if(i<0){
+
+		this.add=function(data){
+			var n=new node(data);
+			var i;
+			var current=root;
+			var parent=null;
+			while(current){
+				i=current.compare(n);
+				if(i==0){ return; }
 				parent=current;
-				current=current.right;
+				if(i>0){ current=current.left; }
+				else{ current=current.right; }
 			}
-			i=current.compareData(data);
-		}
-		if(!current){ return; }
-		this.count--;
-		if(!current.right){
+			this.count++;
 			if(!parent){
-				root=current.left;
+				root=n;
 			}else{
-				i=parent.compare(current);
-				if(i>0){ parent.left=current.left; }
-				else if(i<0){ parent.right=current.left; }
+				i=parent.compare(n);
+				if(i>0){
+					parent.left=n;
+				}else{
+					parent.right=n;
+				}
 			}
-		}
-		else if(!current.right.left){
-			if(!parent){
-				root=current.right;
-			}else{
-				i=parent.compare(current);
-				if(i>0){ parent.left=current.right; }
-				else if(i<0){ parent.right=current.right; }
+		};
+		this.clear=function(){
+			root=null;
+			this.count=0;
+		};
+		this.clone=function(){
+			var c=new dxc.BinaryTree();
+			var itr=this.getIterator();
+			while(!itr.atEnd()){
+				c.add(itr.get());
 			}
-		}
-		else{
-			var leftmost=current.right.left;
-			var lmParent=current.right;
-			while(leftmost.left!=null){
-				lmParent=leftmost;
-				leftmost=leftmost.left;
+			return c;
+		};
+		this.contains=function(data){
+			return this.search(data) != null;
+		};
+		this.deleteData=function(data){
+			var current=root;
+			var parent=null;
+			var i=current.compareData(data);
+			while(i!=0&&current!=null){
+				if(i>0){
+					parent=current;
+					current=current.left;
+				}else if(i<0){
+					parent=current;
+					current=current.right;
+				}
+				i=current.compareData(data);
 			}
-			lmParent.left=leftmost.right;
-			leftmost.left=current.left;
-			leftmost.right=current.right;
-			if(!parent){
-				root=leftmost;
-			}else{
-				i=parent.compare(current);
-				if(i>0){ parent.left=leftmost; }
-				else if(i<0){ parent.right=leftmost; }
+			if(!current){ return; }
+			this.count--;
+			if(!current.right){
+				if(!parent){
+					root=current.left;
+				}else{
+					i=parent.compare(current);
+					if(i>0){ parent.left=current.left; }
+					else if(i<0){ parent.right=current.left; }
+				}
+			}
+			else if(!current.right.left){
+				if(!parent){
+					root=current.right;
+				}else{
+					i=parent.compare(current);
+					if(i>0){ parent.left=current.right; }
+					else if(i<0){ parent.right=current.right; }
+				}
+			}
+			else{
+				var leftmost=current.right.left;
+				var lmParent=current.right;
+				while(leftmost.left!=null){
+					lmParent=leftmost;
+					leftmost=leftmost.left;
+				}
+				lmParent.left=leftmost.right;
+				leftmost.left=current.left;
+				leftmost.right=current.right;
+				if(!parent){
+					root=leftmost;
+				}else{
+					i=parent.compare(current);
+					if(i>0){ parent.left=leftmost; }
+					else if(i<0){ parent.right=leftmost; }
+				}
 			}
-		}
-	};
-	this.getIterator=function(){
-		var a=[];
-		inorderTraversalBuildup(root, a);
-		return new dojox.collections.Iterator(a);
-	};
-	this.search=function(data){
-		return searchHelper(root, data);
-	};
-	this.toString=function(order, sep){
-		if(!order){ order=dojox.collections.BinaryTree.TraversalMethods.Inorder; }
-		if(!sep){ sep=","; }
-		var s="";
-		switch(order){
-			case dojox.collections.BinaryTree.TraversalMethods.Preorder:
-				s=preorderTraversal(root, sep);
-				break;
-			case dojox.collections.BinaryTree.TraversalMethods.Inorder:
-				s=inorderTraversal(root, sep);
-				break;
-			case dojox.collections.BinaryTree.TraversalMethods.Postorder:
-				s=postorderTraversal(root, sep);
-				break;
 		};
-		if(s.length==0){ return ""; }
-		else{ return s.substring(0, s.length - sep.length); }
-	};
+		this.getIterator=function(){
+			var a=[];
+			inorderTraversalBuildup(root, a);
+			return new dxc.Iterator(a);
+		};
+		this.search=function(data){
+			return searchHelper(root, data);
+		};
+		this.toString=function(order, sep){
+			if(!order){ order=dxc.BinaryTree.TraversalMethods.Inorder; }
+			if(!sep){ sep=","; }
+			var s="";
+			switch(order){
+				case dxc.BinaryTree.TraversalMethods.Preorder:
+					s=preorderTraversal(root, sep);
+					break;
+				case dxc.BinaryTree.TraversalMethods.Inorder:
+					s=inorderTraversal(root, sep);
+					break;
+				case dxc.BinaryTree.TraversalMethods.Postorder:
+					s=postorderTraversal(root, sep);
+					break;
+			};
+			if(s.length==0){ return ""; }
+			else{ return s.substring(0, s.length - sep.length); }
+		};
 
-	this.count=0;
-	var root=this.root=null;
-	if(data){
-		this.add(data);
+		this.count=0;
+		var root=this.root=null;
+		if(data){
+			this.add(data);
+		}
 	}
-}
-dojox.collections.BinaryTree.TraversalMethods={
-	Preorder: 1, Inorder: 2, Postorder: 3
-};
+	dxc.BinaryTree.TraversalMethods={
+		Preorder: 1, Inorder: 2, Postorder: 3
+	};
+	return dxc.BinaryTree;
+});
diff --git a/dojox/collections/Dictionary.js b/dojox/collections/Dictionary.js
index 801380e..1332a15 100644
--- a/dojox/collections/Dictionary.js
+++ b/dojox/collections/Dictionary.js
@@ -1,112 +1,115 @@
-dojo.provide("dojox.collections.Dictionary");
-dojo.require("dojox.collections._base");
-
-dojox.collections.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.
-		var b=(k in items);
-		items[k]=new dojox.collections.DictionaryEntry(k,v);
-		if(!b){
-			this.count++;
-		}
-	};
-	this.clear=function(){
+define(["dojo/_base/kernel", "dojo/_base/array", "./_base"], function(dojo, darray, dxc){
+/*=====
+var dxc = dojox.collections;
+=====*/
+	dxc.Dictionary=function(/* dojox.collections.Dictionary? */dictionary){
 		//	summary
-		//	Clears the internal dictionary.
-		items={};
+		//	Returns an object of type dojox.collections.Dictionary
+		var 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.
-		return new dojox.collections.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".
-		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".
-		var e=this.getIterator();
-		while(e.get()){
-			if(e.element.value==v){
+
+		//	comparator for property addition and access.
+		var testObject={};
+
+		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){
+				this.count++;
+			}
+		};
+		this.clear=function(){
+			//	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.
+			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".
+			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".
+			var e=this.getIterator();
+			while(e.get()){
+				if(e.element.value==v){
+					return true;	//	bool
+				}
+			}
+			return false;	//	bool
+		};
+		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.
+			var a=[];	//	Create an indexing array
+			for(var p in items) {
+				if(!testObject[p]){
+					a.push(items[p]);	//	fill it up
+				}
+			}
+			dojo.forEach(a, fn, scope);
+		};
+		this.getKeyList=function(){
+			//	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.
+			return (this.getIterator()).map(function(entry){
+				return entry.value;
+			});	//	array
+		};
+		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.
+			return new dxc.DictionaryIterator(items);	//	dojox.collections.DictionaryIterator
+		};
+		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--;
 				return true;	//	bool
 			}
-		}
-		return false;	//	bool
-	};
-	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.
-		var a=[];	//	Create an indexing array
-		for(var p in items) {
-			if(!testObject[p]){
-				a.push(items[p]);	//	fill it up
+			return false;	//	bool
+		};
+
+		if (dictionary){
+			var e=dictionary.getIterator();
+			while(e.get()) {
+				 this.add(e.element.key, e.element.value);
 			}
 		}
-		dojo.forEach(a, fn, scope);
-	};
-	this.getKeyList=function(){
-		//	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.
-		return (this.getIterator()).map(function(entry){
-			return entry.value;
-		});	//	array
-	};
-	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.
-		return new dojox.collections.DictionaryIterator(items);	//	dojox.collections.DictionaryIterator
-	};
-	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--;
-			return true;	//	bool
-		}
-		return false;	//	bool
 	};
-
-	if (dictionary){
-		var e=dictionary.getIterator();
-		while(e.get()) {
-			 this.add(e.element.key, e.element.value);
-		}
-	}
-};
+	return dxc.Dictionary;
+});
diff --git a/dojox/collections/Queue.js b/dojox/collections/Queue.js
index d8754e3..3394162 100644
--- a/dojox/collections/Queue.js
+++ b/dojox/collections/Queue.js
@@ -1,70 +1,73 @@
-dojo.provide("dojox.collections.Queue");
-dojo.require("dojox.collections._base");
-
-dojox.collections.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(){
+define(["dojo/_base/kernel", "dojo/_base/array", "./_base"], function(dojo, darray, dxc){
+/*=====
+var dxc = dojox.collections;
+=====*/
+	dxc.Queue=function(/* array? */arr){
 		//	summary
-		//	clears the internal collection
-		q=[];
-		this.count=q.length;
-	};
-	this.clone=function(){
-		//	summary
-		//	creates a new Queue based on this one
-		return new dojox.collections.Queue(q);	//	dojox.collections.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
-			}
+		//	return an object of type dojox.collections.Queue
+		var q=[];
+		if (arr){
+			q=q.concat(arr);
 		}
-		return false;	//	bool
-	};
-	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
-		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.count=q.push(o);
-	};
-	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.
-		return new dojox.collections.Iterator(q);	//	dojox.collections.Iterator
-	};
-	this.peek=function(){
-		//	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.
-		return [].concat(q);
+		this.clear=function(){
+			//	summary
+			//	clears the internal collection
+			q=[];
+			this.count=q.length;
+		};
+		this.clone=function(){
+			//	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
+			for(var i=0; i<q.length; i++){
+				if (q[i]==o){
+					return true;	//	bool
+				}
+			}
+			return false;	//	bool
+		};
+		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
+			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.count=q.push(o);
+		};
+		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.
+			return new dxc.Iterator(q);	//	dojox.collections.Iterator
+		};
+		this.peek=function(){
+			//	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.
+			return [].concat(q);
+		};
 	};
-};
+	return dxc.Queue;
+});
diff --git a/dojox/collections/Set.js b/dojox/collections/Set.js
index 1939631..66ac982 100644
--- a/dojox/collections/Set.js
+++ b/dojox/collections/Set.js
@@ -1,12 +1,11 @@
-dojo.provide("dojox.collections.Set");
-dojo.require("dojox.collections.ArrayList");
-
-(function(){
-	var dxc=dojox.collections;
+define(["./_base", "./ArrayList"], function(dxc, ArrayList){
+/*=====
+var dxc = dojox.collections;
+=====*/
 	dxc.Set=new (function(){
 		function conv(arr){
 			if(arr.constructor==Array){
-				return new dojox.collections.ArrayList(arr);	//	dojox.collections.ArrayList
+				return new ArrayList(arr);	//	dojox.collections.ArrayList
 			}
 			return arr;		//	dojox.collections.ArrayList
 		}
@@ -15,7 +14,7 @@ dojo.require("dojox.collections.ArrayList");
 			//	Return the union of the two passed sets.
 			setA=conv(setA);
 			setB=conv(setB);
-			var result = new dojox.collections.ArrayList(setA.toArray());
+			var result = new ArrayList(setA.toArray());
 			var e = setB.getIterator();
 			while(!e.atEnd()){
 				var item=e.get();
@@ -30,7 +29,7 @@ dojo.require("dojox.collections.ArrayList");
 			//	Return the intersection of the two passed sets.
 			setA=conv(setA);
 			setB=conv(setB);
-			var result = new dojox.collections.ArrayList();
+			var result = new ArrayList();
 			var e = setB.getIterator();
 			while(!e.atEnd()){
 				var item=e.get();
@@ -45,7 +44,7 @@ dojo.require("dojox.collections.ArrayList");
 			//	Returns everything in setA that is not in setB.
 			setA=conv(setA);
 			setB=conv(setB);
-			var result = new dojox.collections.ArrayList();
+			var result = new ArrayList();
 			var e=setA.getIterator();
 			while(!e.atEnd()){
 				var item=e.get();
@@ -82,4 +81,5 @@ dojo.require("dojox.collections.ArrayList");
 			return true;	//	boolean
 		};
 	})();
-})();
+	return dxc.Set;
+});
diff --git a/dojox/collections/SortedList.js b/dojox/collections/SortedList.js
index 0885204..172dedc 100644
--- a/dojox/collections/SortedList.js
+++ b/dojox/collections/SortedList.js
@@ -1,194 +1,197 @@
-dojo.provide("dojox.collections.SortedList");
-dojo.require("dojox.collections._base");
-
-dojox.collections.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=[];
-	var sorter=function(a,b){
-		if (a.key > b.key) return 1;
-		if (a.key < b.key) return -1;
-		return 0;
-	};
-	var build=function(){
-		q=[];
-		var e=_this.getIterator();
-		while (!e.atEnd()){
-			q.push(e.get());
-		}
-		q.sort(sorter);
-	};
-	var testObject={};
-
-	this.count=q.length;
-	this.add=function(/* string */ k,/* object */v){
-		//	summary
-		//	add the passed value to the dictionary at location k
-		if (!items[k]) {
-			items[k]=new dojox.collections.DictionaryEntry(k,v);
-			this.count=q.push(items[k]);
+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.
+		var _this=this;
+		var items={};
+		var q=[];
+		var sorter=function(a,b){
+			if (a.key > b.key) return 1;
+			if (a.key < b.key) return -1;
+			return 0;
+		};
+		var build=function(){
+			q=[];
+			var e=_this.getIterator();
+			while (!e.atEnd()){
+				q.push(e.get());
+			}
 			q.sort(sorter);
-		}
-	};
-	this.clear=function(){
-		//	summary
-		//	clear the internal collections
-		items={};
-		q=[];
+		};
+		var testObject={};
+
 		this.count=q.length;
-	};
-	this.clone=function(){
-		//	summary
-		//	create a clone of this sorted list
-		return new dojox.collections.SortedList(this);	//	dojox.collections.SortedList
-	};
-	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
-		var e=this.getIterator();
-		while (!e.atEnd()){
-			var item=e.get();
-			if(item.value==o){
-				return true;	//	bool
+		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]);
+				q.sort(sorter);
 			}
-		}
-		return false;	//	bool
-	};
-	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()){
-			arr.splice(idx,0,e.get());
-			idx++;
-		}
-	};
-	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.
-		dojo.forEach(q, fn, scope);
-	};
-	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
-		return new dojox.collections.DictionaryIterator(items);	//	dojox.collections.DictionaryIterator
-	};
-	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
-		var arr=[];
-		var e=this.getIterator();
-		while (!e.atEnd()){
-			arr.push(e.get().key);
-		}
-		return arr;	//	array
-	};
-	this.getValueList=function(){
-		//	summary
-		//	return an array of values in this list
-		var arr=[];
-		var e=this.getIterator();
-		while (!e.atEnd()){
-			arr.push(e.get().value);
-		}
-		return arr;	//	array
-	};
-	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
+		};
+		this.clear=function(){
+			//	summary
+			//	clear the internal collections
+			items={};
+			q=[];
+			this.count=q.length;
+		};
+		this.clone=function(){
+			//	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
+			if(testObject[k]){
+				return false;			//	bool
 			}
-		}
-		return -1;	//	int
-	};
-	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
+			return (items[k]!=null);	//	bool
+		};
+		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();
+				if(item.value==o){
+					return true;	//	bool
+				}
 			}
-		}
-		return -1;	//	int
-	};
-	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.
-		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.
-		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.
-		if (!items[k]){
-			//	we're adding a new object, return false
-			this.add(k,v);
-			return false; // bool
-		}else{
-			//	we're replacing an object, return true
-			items[k]=new dojox.collections.DictionaryEntry(k,v);
+			return false;	//	bool
+		};
+		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()){
+				arr.splice(idx,0,e.get());
+				idx++;
+			}
+		};
+		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.
+			dojo.forEach(q, fn, scope);
+		};
+		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
+			return new dxc.DictionaryIterator(items);	//	dojox.collections.DictionaryIterator
+		};
+		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
+			var arr=[];
+			var e=this.getIterator();
+			while (!e.atEnd()){
+				arr.push(e.get().key);
+			}
+			return arr;	//	array
+		};
+		this.getValueList=function(){
+			//	summary
+			//	return an array of values in this list
+			var arr=[];
+			var e=this.getIterator();
+			while (!e.atEnd()){
+				arr.push(e.get().value);
+			}
+			return arr;	//	array
+		};
+		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
+				}
+			}
+			return -1;	//	int
+		};
+		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
+				}
+			}
+			return -1;	//	int
+		};
+		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.
+			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.
+			delete items[q[i].key];
 			build();
-			return true; // bool
+			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.
+			if (!items[k]){
+				//	we're adding a new object, return false
+				this.add(k,v);
+				return false; // bool
+			}else{
+				//	we're replacing an object, return true
+				items[k]=new dxc.DictionaryEntry(k,v);
+				build();
+				return true; // bool
+			}
+		};
+		this.setByIndex=function(/* int */ i, /* object */ o){
+			//	summary
+			//	set an item by index
+			items[q[i].key].value=o;
+			build();
+			this.count=q.length;
+		};
+		if (dictionary){
+			var e=dictionary.getIterator();
+			while (!e.atEnd()){
+				var item=e.get();
+				q[q.length]=items[item.key]=new dxc.DictionaryEntry(item.key,item.value);
+			}
+			q.sort(sorter);
 		}
 	};
-	this.setByIndex=function(/* int */ i, /* object */ o){
-		//	summary
-		//	set an item by index
-		items[q[i].key].value=o;
-		build();
-		this.count=q.length;
-	};
-	if (dictionary){
-		var e=dictionary.getIterator();
-		while (!e.atEnd()){
-			var item=e.get();
-			q[q.length]=items[item.key]=new dojox.collections.DictionaryEntry(item.key,item.value);
-		}
-		q.sort(sorter);
-	}
-}
+	return dxc.SortedList;
+});
diff --git a/dojox/collections/Stack.js b/dojox/collections/Stack.js
index 447c394..e98e065 100644
--- a/dojox/collections/Stack.js
+++ b/dojox/collections/Stack.js
@@ -1,68 +1,71 @@
-dojo.provide("dojox.collections.Stack");
-dojo.require("dojox.collections._base");
-
-dojox.collections.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(){
+define(["dojo/_base/kernel", "dojo/_base/array", "./_base"], function(dojo, darray, dxc){
+/*=====
+var dxc = dojox.collections;
+=====*/
+	dxc.Stack=function(/* array? */arr){
 		//	summary
-		//	Clear the internal array and reset the count
-		q=[];
+		//	returns an object of type dojox.collections.Stack
+		var q=[];
+		if (arr) q=q.concat(arr);
 		this.count=q.length;
-	};
-	this.clone=function(){
-		//	summary
-		//	Create and return a clone of this Stack
-		return new dojox.collections.Stack(q);
-	};
-	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
+		this.clear=function(){
+			//	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
+			return new dxc.Stack(q);
+		};
+		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
+				}
 			}
-		}
-		return false;	//	bool
-	};
-	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.
-		dojo.forEach(q, fn, scope);
-	};
-	this.getIterator=function(){
-		//	summary
-		//	get an iterator for this collection
-		return new dojox.collections.Iterator(q);	//	dojox.collections.Iterator
-	};
-	this.peek=function(){
-		//	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
-		var r=q.pop();
-		this.count=q.length;
-		return r;	//	object
-	};
-	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
-		return [].concat(q);	//	array
+			return false;	//	bool
+		};
+		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.
+			dojo.forEach(q, fn, scope);
+		};
+		this.getIterator=function(){
+			//	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.
+			return q[(q.length-1)];	//	object
+		};
+		this.pop=function(){
+			//	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.count=q.push(o);
+		};
+		this.toArray=function(){
+			//	summary
+			//	create and return an array based on the internal collection
+			return [].concat(q);	//	array
+		};
 	};
-}
+	return dxc.Stack;
+});
diff --git a/dojox/collections/_base.js b/dojox/collections/_base.js
index c93e758..3e69052 100644
--- a/dojox/collections/_base.js
+++ b/dojox/collections/_base.js
@@ -1,96 +1,104 @@
-dojo.provide("dojox.collections._base");
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array"], 
+  function(dojo, lang, arr){
+	var collections = lang.getObject("dojox.collections", true);
 
-dojox.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(){
-		return this.value; 	//	object
-	};
-	this.toString=function(){
-		return String(this.value);	//	string
-	};
-}
+/*=====
+	collections = dojox.collections;
+=====*/
 
-/*	Iterators
- *	The collections.Iterators (Iterator and DictionaryIterator) are built to
- *	work with the Collections included in this module.  However, they *can*
- *	be used with arrays and objects, respectively, should one choose to do so.
- */
-dojox.collections.Iterator=function(/* array */arr){
-	//	summary
-	//	return an object of type dojox.collections.Iterator
-	var a=arr;
-	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.
-		return (position>=a.length);	//	bool
-	};
-	this.get=function(){
+	collections.DictionaryEntry=function(/* string */k, /* object */v){
 		//	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.
-		return dojo.map(a, fn, scope);
-	};
-	this.reset=function(){
-		//	summary
-		//	reset the internal cursor.
-		position=0;
-		this.element=a[position];
-	};
-}
-
-/*	Notes:
- *	The DictionaryIterator no longer supports a key and value property;
- *	the reality is that you can use this to iterate over a JS object
- *	being used as a hashtable.
- */
-dojox.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){
-		if(!testObject[p]){
-			a.push(obj[p]);	//	fill it up
-		}
+		//	return an object of type dojox.collections.DictionaryEntry
+		this.key=k;
+		this.value=v;
+		this.valueOf=function(){
+			return this.value; 	//	object
+		};
+		this.toString=function(){
+			return String(this.value);	//	string
+		};
 	}
-	var position=0;
-	this.element=a[position]||null;
-	this.atEnd=function(){
+
+	/*	Iterators
+	 *	The collections.Iterators (Iterator and DictionaryIterator) are built to
+	 *	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
-		//	Test to see if the internal cursor has reached the end of the internal collection.
-		return (position>=a.length);	//	bool
-	};
-	this.get=function(){
+		//	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.
+			return (position>=a.length);	//	bool
+		};
+		this.get=function(){
+			//	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.
+			return arr.map(a, fn, scope);
+		};
+		this.reset=function(){
+			//	summary
+			//	reset the internal cursor.
+			position=0;
+			this.element=a[position];
+		};
+	}
+
+	/*	Notes:
+	 *	The DictionaryIterator no longer supports a key and value property;
+	 *	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
-		//	Get the next member in the collection.
-		if(this.atEnd()){
-			return null;		//	object
+		//	return an object of type dojox.collections.DictionaryIterator
+		var a=[];	//	Create an indexing array
+		var testObject={};
+		for(var p in obj){
+			if(!testObject[p]){
+				a.push(obj[p]);	//	fill it up
+			}
 		}
-		this.element=a[position++];
-		return this.element;	//	object
+		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.
+			return (position>=a.length);	//	bool
+		};
+		this.get=function(){
+			//	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.
+			return arr.map(a, fn, scope);
+		};
+		this.reset=function() {
+			//	summary
+			//	reset the internal cursor.
+			position=0;
+			this.element=a[position];
+		};
 	};
-	this.map=function(/* function */fn, /* object? */scope){
-		//	summary
-		//	Functional iteration with optional scope.
-		return dojo.map(a, fn, scope);
-	};
-	this.reset=function() {
-		//	summary
-		//	reset the internal cursor.
-		position=0;
-		this.element=a[position];
-	};
-};
+
+	return collections;
+});
diff --git a/dojox/color.js b/dojox/color.js
index db080ec..12c71e1 100644
--- a/dojox/color.js
+++ b/dojox/color.js
@@ -1,2 +1,3 @@
-dojo.provide("dojox.color");
-dojo.require("dojox.color._base");
+define(["./color/_base"], function(dxcolor){
+	return dxcolor;
+});
diff --git a/dojox/color/Colorspace.js b/dojox/color/Colorspace.js
index 3422140..eb6578f 100644
--- a/dojox/color/Colorspace.js
+++ b/dojox/color/Colorspace.js
@@ -1,9 +1,7 @@
-dojo.provide("dojox.color.Colorspace");
-dojo.require("dojox.math.matrix");
+define(["dojo/_base/kernel", "../main", "dojo/_base/lang", "./_base", "dojox/math/matrix"], 
+	function(dojo, dojox, dlang, dxc, dxm){
 
 dojox.color.Colorspace=new (function(){
-	var dxc=dojox.color;
-	var dxm=dojox.math.matrix;
 	var self=this;
 	var wpMap={
 		"2":{
@@ -550,3 +548,6 @@ dojo.extend(dojox.color.Color, {
 		return { X: xyz[0][0], Y: xyz[0][1], Z: xyz[0][2] };	//	Object
 	}
 });
+
+return dojox.color.Colorspace;
+});
diff --git a/dojox/color/Palette.js b/dojox/color/Palette.js
index 74a8697..3305946 100644
--- a/dojox/color/Palette.js
+++ b/dojox/color/Palette.js
@@ -1,8 +1,6 @@
-dojo.provide("dojox.color.Palette");
-dojo.require("dojox.color");
+define(["dojo/_base/kernel", "../main", "dojo/_base/lang", "dojo/_base/array", "./_base"], 
+	function(dojo, dojox, lang, arr, dxc){
 
-(function(){
-	var dxc = dojox.color;
 	/***************************************************************
 	*	dojox.color.Palette
 	*
@@ -38,20 +36,20 @@ dojo.require("dojox.color");
 		//	colors: dojox.color.Color[]
 		//		The actual color references in this palette.
 		this.colors = [];
-		if(base instanceof dojox.color.Palette){
+		if(base instanceof dxc.Palette){
 			this.colors = base.colors.slice(0);
 		}
-		else if(base instanceof dojox.color.Color){
+		else if(base instanceof dxc.Color){
 			this.colors = [ null, null, base, null, null ];
 		}
-		else if(dojo.isArray(base)){
-			this.colors = dojo.map(base.slice(0), function(item){
-				if(dojo.isString(item)){ return new dojox.color.Color(item); }
+		else if(lang.isArray(base)){
+			this.colors = arr.map(base.slice(0), function(item){
+				if(lang.isString(item)){ return new dxc.Color(item); }
 				return item;
 			});
 		}
-		else if (dojo.isString(base)){
-			this.colors = [ null, null, new dojox.color.Color(base), null, null ];
+		else if (lang.isString(base)){
+			this.colors = [ null, null, new dxc.Color(base), null, null ];
 		}
 	}
 
@@ -59,14 +57,14 @@ dojo.require("dojox.color");
 
 	//	transformations
 	function tRGBA(p, param, val){
-		var ret = new dojox.color.Palette();
+		var ret = new dxc.Palette();
 		ret.colors = [];
-		dojo.forEach(p.colors, function(item){
+		arr.forEach(p.colors, function(item){
 			var r=(param=="dr")?item.r+val:item.r,
 				g=(param=="dg")?item.g+val:item.g,
 				b=(param=="db")?item.b+val:item.b,
 				a=(param=="da")?item.a+val:item.a
-			ret.colors.push(new dojox.color.Color({
+			ret.colors.push(new dxc.Color({
 				r: Math.min(255, Math.max(0, r)),
 				g: Math.min(255, Math.max(0, g)),
 				b: Math.min(255, Math.max(0, b)),
@@ -77,14 +75,14 @@ dojo.require("dojox.color");
 	}
 
 	function tCMY(p, param, val){
-		var ret = new dojox.color.Palette();
+		var ret = new dxc.Palette();
 		ret.colors = [];
-		dojo.forEach(p.colors, function(item){
+		arr.forEach(p.colors, function(item){
 			var o=item.toCmy(),
 				c=(param=="dc")?o.c+val:o.c,
 				m=(param=="dm")?o.m+val:o.m,
 				y=(param=="dy")?o.y+val:o.y;
-			ret.colors.push(dojox.color.fromCmy(
+			ret.colors.push(dxc.fromCmy(
 				Math.min(100, Math.max(0, c)),
 				Math.min(100, Math.max(0, m)),
 				Math.min(100, Math.max(0, y))
@@ -94,15 +92,15 @@ dojo.require("dojox.color");
 	}
 
 	function tCMYK(p, param, val){
-		var ret = new dojox.color.Palette();
+		var ret = new dxc.Palette();
 		ret.colors = [];
-		dojo.forEach(p.colors, function(item){
+		arr.forEach(p.colors, function(item){
 			var o=item.toCmyk(),
 				c=(param=="dc")?o.c+val:o.c,
 				m=(param=="dm")?o.m+val:o.m,
 				y=(param=="dy")?o.y+val:o.y,
 				k=(param=="dk")?o.b+val:o.b;
-			ret.colors.push(dojox.color.fromCmyk(
+			ret.colors.push(dxc.fromCmyk(
 				Math.min(100, Math.max(0, c)),
 				Math.min(100, Math.max(0, m)),
 				Math.min(100, Math.max(0, y)),
@@ -113,27 +111,27 @@ dojo.require("dojox.color");
 	}
 
 	function tHSL(p, param, val){
-		var ret = new dojox.color.Palette();
+		var ret = new dxc.Palette();
 		ret.colors = [];
-		dojo.forEach(p.colors, function(item){
+		arr.forEach(p.colors, function(item){
 			var o=item.toHsl(),
 				h=(param=="dh")?o.h+val:o.h,
 				s=(param=="ds")?o.s+val:o.s,
 				l=(param=="dl")?o.l+val:o.l;
-			ret.colors.push(dojox.color.fromHsl(h%360, Math.min(100, Math.max(0, s)), Math.min(100, Math.max(0, l))));
+			ret.colors.push(dxc.fromHsl(h%360, Math.min(100, Math.max(0, s)), Math.min(100, Math.max(0, l))));
 		});
 		return ret;
 	}
 
 	function tHSV(p, param, val){
-		var ret = new dojox.color.Palette();
+		var ret = new dxc.Palette();
 		ret.colors = [];
-		dojo.forEach(p.colors, function(item){
+		arr.forEach(p.colors, function(item){
 			var o=item.toHsv(),
 				h=(param=="dh")?o.h+val:o.h,
 				s=(param=="ds")?o.s+val:o.s,
 				v=(param=="dv")?o.v+val:o.v;
-			ret.colors.push(dojox.color.fromHsv(h%360, Math.min(100, Math.max(0, s)), Math.min(100, Math.max(0, v))));
+			ret.colors.push(dxc.fromHsv(h%360, Math.min(100, Math.max(0, s)), Math.min(100, Math.max(0, v))));
 		});
 		return ret;
 	}
@@ -146,7 +144,7 @@ dojo.require("dojox.color");
 	}
 
 	//	object methods ---------------------------------------------------------------
-	dojo.extend(dxc.Palette, {
+	lang.extend(dxc.Palette, {
 		transform: function(/* dojox.color.Palette.__transformArgs */kwArgs){
 			//	summary:
 			//		Transform the palette using a specific transformation function
@@ -287,7 +285,7 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 	this.da = da;
 }
 =====*/
-	dojo.mixin(dxc.Palette, {
+	lang.mixin(dxc.Palette, {
 		generators: {
 			analogous:function(/* dojox.color.Palette.__analogousArgs */args){
 				//	summary:
@@ -295,7 +293,7 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 				//		http://kuler.adobe.com.
 				var high=args.high||60, 	//	delta between base hue and highest hue (subtracted from base)
 					low=args.low||18,		//	delta between base hue and lowest hue (added to base)
-					base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
+					base = lang.isString(args.base)?new dxc.Color(args.base):args.base,
 					hsv=base.toHsv();
 
 				//	generate our hue angle differences
@@ -314,8 +312,8 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 					s=[ s1, s2, hsv.s, s1, s1 ],
 					v=[ v1, v2, hsv.v, v1, v2 ]
 
-				return new dxc.Palette(dojo.map(h, function(hue, i){
-					return dojox.color.fromHsv(hue, s[i], v[i]);
+				return new dxc.Palette(arr.map(h, function(hue, i){
+					return dxc.fromHsv(hue, s[i], v[i]);
 				}));		//	dojox.color.Palette
 			},
 
@@ -323,7 +321,7 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 				//	summary:
 				//		Create a 5 color palette based on the monochromatic rules as implemented at
 				//		http://kuler.adobe.com.
-				var base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
+				var base = lang.isString(args.base)?new dxc.Color(args.base):args.base,
 					hsv = base.toHsv();
 				
 				//	figure out the saturation and value
@@ -334,11 +332,11 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 					v3 = (hsv.v-50>20)?hsv.v-50:hsv.v+30;
 
 				return new dxc.Palette([
-					dojox.color.fromHsv(hsv.h, s1, v1),
-					dojox.color.fromHsv(hsv.h, s2, v3),
+					dxc.fromHsv(hsv.h, s1, v1),
+					dxc.fromHsv(hsv.h, s2, v3),
 					base,
-					dojox.color.fromHsv(hsv.h, s1, v3),
-					dojox.color.fromHsv(hsv.h, s2, v2)
+					dxc.fromHsv(hsv.h, s1, v3),
+					dxc.fromHsv(hsv.h, s2, v2)
 				]);		//	dojox.color.Palette
 			},
 
@@ -346,7 +344,7 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 				//	summary:
 				//		Create a 5 color palette based on the triadic rules as implemented at
 				//		http://kuler.adobe.com.
-				var base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
+				var base = lang.isString(args.base)?new dxc.Color(args.base):args.base,
 					hsv = base.toHsv();
 
 				var h1 = (hsv.h+57+360)%360,
@@ -359,11 +357,11 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 					v3 = (hsv.v-30>70)?hsv.v-30:hsv.v+30;
 
 				return new dxc.Palette([
-					dojox.color.fromHsv(h1, s1, hsv.v),
-					dojox.color.fromHsv(hsv.h, s2, v2),
+					dxc.fromHsv(h1, s1, hsv.v),
+					dxc.fromHsv(hsv.h, s2, v2),
 					base,
-					dojox.color.fromHsv(h2, s2, v1),
-					dojox.color.fromHsv(h2, s3, v3)
+					dxc.fromHsv(h2, s2, v1),
+					dxc.fromHsv(h2, s3, v3)
 				]);		//	dojox.color.Palette
 			},
 
@@ -371,7 +369,7 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 				//	summary:
 				//		Create a 5 color palette based on the complementary rules as implemented at
 				//		http://kuler.adobe.com.
-				var base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
+				var base = lang.isString(args.base)?new dxc.Color(args.base):args.base,
 					hsv = base.toHsv();
 
 				var h1 = ((hsv.h*2)+137<360)?(hsv.h*2)+137:Math.floor(hsv.h/2)-137,
@@ -382,11 +380,11 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 					v2 = (hsv.v>20)?hsv.v-30:hsv.v+30;
 
 				return new dxc.Palette([
-					dojox.color.fromHsv(hsv.h, s1, v1),
-					dojox.color.fromHsv(hsv.h, s2, v2),
+					dxc.fromHsv(hsv.h, s1, v1),
+					dxc.fromHsv(hsv.h, s2, v2),
 					base,
-					dojox.color.fromHsv(h1, s3, v2),
-					dojox.color.fromHsv(h1, hsv.s, hsv.v)
+					dxc.fromHsv(h1, s3, v2),
+					dxc.fromHsv(h1, hsv.s, hsv.v)
 				]);		//	dojox.color.Palette
 			},
 
@@ -394,7 +392,7 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 				//	summary:
 				//		Create a 5 color palette based on the split complementary rules as implemented at
 				//		http://kuler.adobe.com.
-				var base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
+				var base = lang.isString(args.base)?new dxc.Color(args.base):args.base,
 					dangle = args.da || 30,
 					hsv = base.toHsv();
 
@@ -408,11 +406,11 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 					v2 = (hsv.v>20)?hsv.v-30:hsv.v+30;
 
 				return new dxc.Palette([
-					dojox.color.fromHsv(h1, s1, v1),
-					dojox.color.fromHsv(h1, s2, v2),
+					dxc.fromHsv(h1, s1, v1),
+					dxc.fromHsv(h1, s2, v2),
 					base,
-					dojox.color.fromHsv(h2, s3, v2),
-					dojox.color.fromHsv(h2, hsv.s, hsv.v)
+					dxc.fromHsv(h2, s3, v2),
+					dxc.fromHsv(h2, hsv.s, hsv.v)
 				]);		//	dojox.color.Palette
 			},
 
@@ -420,7 +418,7 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 				//	summary:
 				//		Create a 5 color palette based on the compound rules as implemented at
 				//		http://kuler.adobe.com.
-				var base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
+				var base = lang.isString(args.base)?new dxc.Color(args.base):args.base,
 					hsv = base.toHsv();
 
 				var h1 = ((hsv.h*2)+18<360)?(hsv.h*2)+18:Math.floor(hsv.h/2)-18,
@@ -434,11 +432,11 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 					v3 = Math.max(hsv.v, 20);
 
 				return new dxc.Palette([
-					dojox.color.fromHsv(h1, s1, v1),
-					dojox.color.fromHsv(h1, s2, v2),
+					dxc.fromHsv(h1, s1, v1),
+					dxc.fromHsv(h1, s2, v2),
 					base,
-					dojox.color.fromHsv(h2, s3, v3),
-					dojox.color.fromHsv(h3, s2, v2)
+					dxc.fromHsv(h2, s3, v3),
+					dxc.fromHsv(h3, s2, v2)
 				]);		//	dojox.color.Palette
 			},
 
@@ -446,7 +444,7 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 				//	summary:
 				//		Create a 5 color palette based on the shades rules as implemented at
 				//		http://kuler.adobe.com.
-				var base = dojo.isString(args.base)?new dojox.color.Color(args.base):args.base,
+				var base = lang.isString(args.base)?new dxc.Color(args.base):args.base,
 					hsv = base.toHsv();
 
 				var s  = (hsv.s==100 && hsv.v==0)?0:hsv.s,
@@ -456,11 +454,11 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 					v4 = Math.max(hsv.v-10, 20);
 
 				return new dxc.Palette([
-					new dojox.color.fromHsv(hsv.h, s, v1),
-					new dojox.color.fromHsv(hsv.h, s, v2),
+					new dxc.fromHsv(hsv.h, s, v1),
+					new dxc.fromHsv(hsv.h, s, v2),
 					base,
-					new dojox.color.fromHsv(hsv.h, s, v3),
-					new dojox.color.fromHsv(hsv.h, s, v4)
+					new dxc.fromHsv(hsv.h, s, v3),
+					new dxc.fromHsv(hsv.h, s, v4)
 				]);		//	dojox.color.Palette
 			}
 		},
@@ -470,7 +468,7 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 			//		dojox.color.Palette.generators or an optional function definition.  Current
 			//		generators include "analogous", "monochromatic", "triadic", "complementary",
 			//		"splitComplementary", and "shades".
-			if(dojo.isFunction(type)){
+			if(lang.isFunction(type)){
 				return type({ base: base });	//	dojox.color.Palette
 			}
 			else if(dxc.Palette.generators[type]){
@@ -479,4 +477,6 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 			throw new Error("dojox.color.Palette.generate: the specified generator ('" + type + "') does not exist.");
 		}
 	});
-})();
+	
+	return dxc.Palette;
+});
diff --git a/dojox/color/_base.js b/dojox/color/_base.js
index c7eea81..a826054 100644
--- a/dojox/color/_base.js
+++ b/dojox/color/_base.js
@@ -1,43 +1,45 @@
-dojo.provide("dojox.color._base");
-dojo.require("dojo.colors");
+define(["dojo/_base/kernel", "../main", "dojo/_base/lang", "dojo/_base/Color", "dojo/colors"], 
+	function(dojo, dojox, lang, Color, colors){
 
+var cx = lang.getObject("dojox.color", true);
+/*===== cx = dojox.color =====*/
+		
 //	alias all the dojo.Color mechanisms
-dojox.color.Color=dojo.Color;
-dojox.color.blend=dojo.blendColors;
-dojox.color.fromRgb=dojo.colorFromRgb;
-dojox.color.fromHex=dojo.colorFromHex;
-dojox.color.fromArray=dojo.colorFromArray;
-dojox.color.fromString=dojo.colorFromString;
+cx.Color=Color;
+cx.blend=Color.blendColors;
+cx.fromRgb=Color.fromRgb;
+cx.fromHex=Color.fromHex;
+cx.fromArray=Color.fromArray;
+cx.fromString=Color.fromString;
 
 //	alias the dojo.colors mechanisms
-dojox.color.greyscale=dojo.colors.makeGrey;
+cx.greyscale=colors.makeGrey;
 
-//	static methods
-dojo.mixin(dojox.color, {
+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)
-
-		if(dojo.isArray(cyan)){
+	
+		if(lang.isArray(cyan)){
 			magenta=cyan[1], yellow=cyan[2], cyan=cyan[0];
-		} else if(dojo.isObject(cyan)){
+		} else if(lang.isObject(cyan)){
 			magenta=cyan.m, yellow=cyan.y, cyan=cyan.c;
 		}
 		cyan/=100, magenta/=100, yellow/=100;
-
+	
 		var r=1-cyan, g=1-magenta, b=1-yellow;
-		return new dojox.color.Color({ r:Math.round(r*255), g:Math.round(g*255), b:Math.round(b*255) });	//	dojox.color.Color
+		return new Color({ r:Math.round(r*255), g:Math.round(g*255), b:Math.round(b*255) });	//	dojox.color.Color
 	},
-
+	
 	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)
-
-		if(dojo.isArray(cyan)){
+	
+		if(lang.isArray(cyan)){
 			magenta=cyan[1], yellow=cyan[2], black=cyan[3], cyan=cyan[0];
-		} else if(dojo.isObject(cyan)){
+		} else if(lang.isObject(cyan)){
 			magenta=cyan.m, yellow=cyan.y, black=cyan.b, cyan=cyan.c;
 		}
 		cyan/=100, magenta/=100, yellow/=100, black/=100;
@@ -45,22 +47,22 @@ dojo.mixin(dojox.color, {
 		r = 1-Math.min(1, cyan*(1-black)+black);
 		g = 1-Math.min(1, magenta*(1-black)+black);
 		b = 1-Math.min(1, yellow*(1-black)+black);
-		return new dojox.color.Color({ r:Math.round(r*255), g:Math.round(g*255), b:Math.round(b*255) });	//	dojox.color.Color
+		return new Color({ r:Math.round(r*255), g:Math.round(g*255), b:Math.round(b*255) });	//	dojox.color.Color
 	},
-	
+		
 	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.
-
-		if(dojo.isArray(hue)){
+	
+		if(lang.isArray(hue)){
 			saturation=hue[1], luminosity=hue[2], hue=hue[0];
-		} else if(dojo.isObject(hue)){
+		} else if(lang.isObject(hue)){
 			saturation=hue.s, luminosity=hue.l, hue=hue.h;
 		}
 		saturation/=100;
 		luminosity/=100;
-
+	
 		while(hue<0){ hue+=360; }
 		while(hue>=360){ hue-=360; }
 		
@@ -83,54 +85,52 @@ dojo.mixin(dojox.color, {
 			g=(1-luminosity)*g+2*luminosity-1;
 			b=(1-luminosity)*b+2*luminosity-1;
 		}
-		return new dojox.color.Color({ r:Math.round(r*255), g:Math.round(g*255), b:Math.round(b*255) });	//	dojox.color.Color
-	},
+		return new Color({ r:Math.round(r*255), g:Math.round(g*255), b:Math.round(b*255) });	//	dojox.color.Color
+	}
+});
 	
-	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.
+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.
 
-		if(dojo.isArray(hue)){
-			saturation=hue[1], value=hue[2], hue=hue[0];
-		} else if (dojo.isObject(hue)){
-			saturation=hue.s, value=hue.v, hue=hue.h;
-		}
-		
-		if(hue==360){ hue=0; }
-		saturation/=100;
-		value/=100;
-		
-		var r, g, b;
-		if(saturation==0){
-			r=value, b=value, g=value;
-		}else{
-			var hTemp=hue/60, i=Math.floor(hTemp), f=hTemp-i;
-			var p=value*(1-saturation);
-			var q=value*(1-(saturation*f));
-			var t=value*(1-(saturation*(1-f)));
-			switch(i){
-				case 0:{ r=value, g=t, b=p; break; }
-				case 1:{ r=q, g=value, b=p; break; }
-				case 2:{ r=p, g=value, b=t; break; }
-				case 3:{ r=p, g=q, b=value; break; }
-				case 4:{ r=t, g=p, b=value; break; }
-				case 5:{ r=value, g=p, b=q; break; }
-			}
+	if(lang.isArray(hue)){
+		saturation=hue[1], value=hue[2], hue=hue[0];
+	} else if (lang.isObject(hue)){
+		saturation=hue.s, value=hue.v, hue=hue.h;
+	}
+	
+	if(hue==360){ hue=0; }
+	saturation/=100;
+	value/=100;
+	
+	var r, g, b;
+	if(saturation==0){
+		r=value, b=value, g=value;
+	}else{
+		var hTemp=hue/60, i=Math.floor(hTemp), f=hTemp-i;
+		var p=value*(1-saturation);
+		var q=value*(1-(saturation*f));
+		var t=value*(1-(saturation*(1-f)));
+		switch(i){
+			case 0:{ r=value, g=t, b=p; break; }
+			case 1:{ r=q, g=value, b=p; break; }
+			case 2:{ r=p, g=value, b=t; break; }
+			case 3:{ r=p, g=q, b=value; break; }
+			case 4:{ r=t, g=p, b=value; break; }
+			case 5:{ r=value, g=p, b=q; break; }
 		}
-		return new dojox.color.Color({ r:Math.round(r*255), g:Math.round(g*255), b:Math.round(b*255) });	//	dojox.color.Color
 	}
-});
-
-//	Conversions directly on dojox.color.Color
-dojo.extend(dojox.color.Color, {
+	return new Color({ r:Math.round(r*255), g:Math.round(g*255), b:Math.round(b*255) });	//	dojox.color.Color
+};
+lang.extend(Color,{
 	toCmy: function(){
 		//	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.
@@ -142,7 +142,7 @@ dojo.extend(dojox.color.Color, {
 		yellow = (1-b-black)/(1-black);
 		return { c:Math.round(cyan*100), m:Math.round(magenta*100), y:Math.round(yellow*100), b:Math.round(black*100) };	//	Object
 	},
-	
+		
 	toHsl: function(){
 		//	summary
 		//	Convert this Color to an HSL definition.
@@ -167,7 +167,7 @@ dojo.extend(dojox.color.Color, {
 		}
 		return { h:h, s:Math.round(s*100), l:Math.round(l*100) };	//	Object
 	},
-
+	
 	toHsv: function(){
 		//	summary
 		//	Convert this Color to an HSV definition.
@@ -185,9 +185,12 @@ dojo.extend(dojox.color.Color, {
 			}else{
 				h = 240 + 60*(r-g)/delta;
 			}
-
+	
 			if(h<0){ h+=360; }
 		}
 		return { h:h, s:Math.round(s*100), v:Math.round(max*100) };	//	Object
 	}
 });
+
+return cx;
+});
diff --git a/dojox/color/tests/Generator.js b/dojox/color/tests/Generator.js
deleted file mode 100644
index 7cb7253..0000000
--- a/dojox/color/tests/Generator.js
+++ /dev/null
@@ -1,150 +0,0 @@
-dojo.provide("dojox.color.tests.Generator");
-dojo.require("dojox.color.Generator");
-
-var __p__, palette=function(){
-	if(__p__) return __p__;
-	__p__=document.createElement("div");
-	var s=__p__.style;
-	s.overflow="auto";
-	s.padding="0 6px";
-	//	drop it in the test thing
-	var body=dojo.query("#testListContainer table tbody")[0];
-	if(body){
-		var tr=document.createElement("tr");
-		var td=document.createElement("td");
-		td.colSpan=4;
-		td.appendChild(__p__);
-		tr.appendChild(td);
-		body.appendChild(tr);
-	}
-	return __p__;
-}
-
-tests.register("dojox.color.tests.Generator", [
-	function testAnalogous(t){
-		//	test the defaults
-		var args={ base: new dojox.color.Color({ r:128, g:0, b:0 }) };
-		var a=dojox.color.Generator.analogous(args);
-		var s='<h3>dojox.color.Generator.analogous</h3><table cellpadding="0" cellspacing="1" border="0"><tr>';
-		var cols=5, c=0;
-		dojo.forEach(a, function(item){
-			if(c++%cols==0){ s+="</tr><tr>"; }
-			s+='<td width="32" bgcolor="'+item.toHex()+'"> </td>';
-		});
-		if(c<cols){
-			for(; c<cols; c++){
-				s+='<td width="32"> </td>';
-			}
-		}
-//		t.debug(s+'</tr></table>');
-		palette().innerHTML += s+'</tr></table>';
-	},
-
-	function testMonochromatic(t){
-		//	test the defaults
-		var a=dojox.color.Generator.monochromatic({ base:new dojox.color.Color({r:128, g:0, b:0}) });
-		var s='<h3>dojox.color.Generator.monochromatic</h3><table cellpadding="0" cellspacing="1" border="0"><tr>';
-		var cols=8, c=0;
-		dojo.forEach(a, function(item){
-			if(c++%cols==0){ s+="</tr><tr>"; }
-			s+='<td width="32" bgcolor="'+item.toHex()+'"> </td>';
-		});
-		if(c<cols){
-			for(; c<cols; c++){
-				s+='<td width="32"> </td>';
-			}
-		}
-	//	t.debug(s+'</tr></table>');
-		palette().innerHTML += s+'</tr></table>';
-	},
-
-	function testTriadic(t){
-		//	test the defaults
-		var a=dojox.color.Generator.triadic({ base:new dojox.color.Color({r:128, g:0, b:0}) });
-		var s='<h3>dojox.color.Generator.triadic</h3><table cellpadding="0" cellspacing="1" border="0"><tr>';
-		var cols=3, c=0;
-		dojo.forEach(a, function(item){
-			if(c++%cols==0){ s+="</tr><tr>"; }
-			s+='<td width="32" bgcolor="'+item.toHex()+'"> </td>';
-		});
-		if(c<cols){
-			for(; c<cols; c++){
-				s+='<td width="32"> </td>';
-			}
-		}
-	//	t.debug(s+'</tr></table>');
-		palette().innerHTML += s+'</tr></table>';
-	},
-
-	function testComplementary(t){
-		//	test the defaults
-		var a=dojox.color.Generator.complementary({ base:new dojox.color.Color({r:128, g:0, b:0}) });
-		var s='<h3>dojox.color.Generator.complementary</h3><table cellpadding="0" cellspacing="1" border="0"><tr>';
-		var cols=2, c=0;
-		dojo.forEach(a, function(item){
-			if(c++%cols==0){ s+="</tr><tr>"; }
-			s+='<td width="32" bgcolor="'+item.toHex()+'"> </td>';
-		});
-		if(c<cols){
-			for(; c<cols; c++){
-				s+='<td width="32"> </td>';
-			}
-		}
-	//	t.debug(s+'</tr></table>');
-		palette().innerHTML += s+'</tr></table>';
-	},
-
-	function testSplitComplementary(t){
-		//	test the defaults
-		var a=dojox.color.Generator.splitComplementary({ base:new dojox.color.Color({r:128, g:0, b:0}) });
-		var s='<h3>dojox.color.Generator.splitComplementary</h3><table cellpadding="0" cellspacing="1" border="0"><tr>';
-		var cols=3, c=0;
-		dojo.forEach(a, function(item){
-			if(c++%cols==0){ s+="</tr><tr>"; }
-			s+='<td width="32" bgcolor="'+item.toHex()+'"> </td>';
-		});
-		if(c<cols){
-			for(; c<cols; c++){
-				s+='<td width="32"> </td>';
-			}
-		}
-	//	t.debug(s+'</tr></table>');
-		palette().innerHTML += s+'</tr></table>';
-	},
-
-	function testCompound(t){
-		//	test the defaults
-		var a=dojox.color.Generator.compound({ base:new dojox.color.Color({r:128, g:0, b:0}) });
-		var s='<h3>dojox.color.Generator.compound</h3><table cellpadding="0" cellspacing="1" border="0"><tr>';
-		var cols=4, c=0;
-		dojo.forEach(a, function(item){
-			if(c++%cols==0){ s+="</tr><tr>"; }
-			s+='<td width="32" bgcolor="'+item.toHex()+'"> </td>';
-		});
-		if(c<cols){
-			for(; c<cols; c++){
-				s+='<td width="32"> </td>';
-			}
-		}
-	//	t.debug(s+'</tr></table>');
-		palette().innerHTML += s+'</tr></table>';
-	},
-
-	function testShades(t){
-		//	test the defaults
-		var a=dojox.color.Generator.shades({ base:new dojox.color.Color({r:128, g:0, b:0}) });
-		var s='<h3>dojox.color.Generator.shades</h3><table cellpadding="0" cellspacing="1" border="0"><tr>';
-		var cols=8, c=0;
-		dojo.forEach(a, function(item){
-			if(c++%cols==0){ s+="</tr><tr>"; }
-			s+='<td width="32" bgcolor="'+item.toHex()+'"> </td>';
-		});
-		if(c<cols){
-			for(; c<cols; c++){
-				s+='<td width="32"> </td>';
-			}
-		}
-		palette().innerHTML += s+'</tr></table>';
-//		t.debug(s+'</tr></table>');
-	}
-]);
diff --git a/dojox/color/tests/color.js b/dojox/color/tests/color.js
index 843329b..03bc4fb 100644
--- a/dojox/color/tests/color.js
+++ b/dojox/color/tests/color.js
@@ -5,7 +5,6 @@ try{
 	dojo.require("dojox.color.tests._base");
 //	dojo.require("dojox.color.tests.Colorspace");
 	dojo.require("dojox.color.tests.Palette");
-//	dojo.require("dojox.color.tests.Generator");
 }catch(e){
 	doh.debug(e);
 }
diff --git a/dojox/cometd/RestChannels.js b/dojox/cometd/RestChannels.js
index c3dcf94..c4fe799 100644
--- a/dojox/cometd/RestChannels.js
+++ b/dojox/cometd/RestChannels.js
@@ -1,6 +1,7 @@
 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
@@ -66,7 +67,7 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 							self.get(r.url,r) : // auto-subscribe
 							defaultXhrGet(r); // plain XHR request
 					};
-		
+
 					var result = defaultGet.apply(this,arguments);
 					dojo.xhrGet = defaultXhrGet;
 					return result;
@@ -157,8 +158,8 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 	  					}
 	  				}
 			  	}
-			  	
-	  			 
+
+
 				if(window.attachEvent){// IE needs a little help with cleanup
 					window.attachEvent("onunload",function(){
 						self.connected= false;
@@ -167,7 +168,7 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 						}
 					});
 				}
-				
+
 				this.connected = true;
 			}
 		},
@@ -246,7 +247,7 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 				}
 				headers["Subscribe"] = args.unsubscribe ? 'none' : '*';
 				var dfd = this._send(method,args);
-				
+
 				var self = this;
 				dfd.addBoth(function(result){
 					var xhr = dfd.ioArgs.xhr;
@@ -257,7 +258,7 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 					}
 					if(xhr && xhr.getResponseHeader("Subscribed")  == "OK"){
 						var lastMod = xhr.getResponseHeader('Last-Modified');
-						
+
 						if(xhr.responseText){
 							self.subscriptions[channel] = lastMod || new Date().toUTCString();
 						}else{
@@ -369,9 +370,9 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 				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
@@ -417,7 +418,7 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 			// 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
diff --git a/dojox/css3/README b/dojox/css3/README
new file mode 100644
index 0000000..fe72cd3
--- /dev/null
+++ b/dojox/css3/README
@@ -0,0 +1,37 @@
+-------------------------------------------------------------------------------
+dojox.css3
+-------------------------------------------------------------------------------
+Version: 0.1
+Release date: 03/06/2010
+-------------------------------------------------------------------------------
+Project state: beta
+-------------------------------------------------------------------------------
+Project author
+	Nicola Rizzo
+-------------------------------------------------------------------------------
+Project description
+Common animations (flip, bounce, puff, rotate, expand, shrink)
+using the CSS3 Transform property
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo core (package loader, connect, dom-style, fx, html)
+dojox/html/ext-dojo/style to handle transform and transform origin
+dojox/fx/ext-dojo/complex to handle animations with multiple values
+
+-------------------------------------------------------------------------------
+Documentation:
+
+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
+
+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
diff --git a/dojox/css3/fx.js b/dojox/css3/fx.js
index a128ee9..b447412 100644
--- a/dojox/css3/fx.js
+++ b/dojox/css3/fx.js
@@ -1,183 +1,191 @@
-dojo.provide("dojox.css3.fx");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/connect",	// dojo.connect
+	"dojo/dom-style",	// dojo.style
+	"dojo/_base/fx",
+	"dojo/fx",
+	"dojo/_base/html",
+	"dojox/html/ext-dojo/style",
+	"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){
+			// summary:
+			//		Returns an animation that will do a "puff" effect on the given node
+			//
+			// description:
+			//		Fades out an element and scales it to args.endScale
+			//
+			return coreFx.combine([baseFx.fadeOut(args),
+				this.expand({
+					node: args.node,
+					endScale: args.endScale || 2
+				})
+			]);
+		},
 
-dojo.require("dojo.fx");
-dojo.require("dojox.html.ext-dojo.style");
-dojo.require("dojox.fx.ext-dojo.complex");
-
-dojo.mixin(dojox.css3.fx, {
-	puff: function(args){
-		// summary:
-		//		Returns an animation that will do a "puff" effect on the given node
-		//
-		// description:
-		//		Fades out an element and scales it to args.endScale
-		//
-		return dojo.fx.combine([dojo.fadeOut(args),
-			this.expand({
+		expand: function(args){
+			// summary:
+			//		Returns an animation that expands args.node
+			//
+			// description:
+			//		Scales an element to args.endScale
+			//
+			return baseFx.animateProperty({
 				node: args.node,
-				endScale: args.endScale || 2
-			})
-		]);
-	},
-
-	expand: function(args){
-		// summary:
-		//		Returns an animation that expands args.node
-		//
-		// description:
-		//		Scales an element to args.endScale
-		//
-		return dojo.animateProperty({
-			node: args.node,
-			properties: {
-				transform: { start: "scale(1)", end: "scale(" + [args.endScale || 3] + ")" }
-			}
-		});
-	},
-
-	shrink: function(args){
-		// summary:
-		//		Returns an animation that shrinks args.node
-		//
-		// description:
-		//		Shrinks an element, same as expand({ node: node, endScale: .01 });
-		//
-		return this.expand({
-			node: args.node,
-			endScale: .01
-		});
-	},
+				properties: {
+					transform: { start: "scale(1)", end: "scale(" + [args.endScale || 3] + ")" }
+				}
+			});
+		},
 
-	rotate: function(args){
-		// summary:
-		//		Returns an animation that rotates an element
-		//
-		// description:
-		//		Rotates an element from args.startAngle to args.endAngle
-		//
-		return dojo.animateProperty({
-			node: args.node,
-			duration: args.duration || 1000,
-			properties: {
-				transform: { start: "rotate(" + (args.startAngle || "0deg") + ")", end: "rotate(" + (args.endAngle || "360deg") + ")" }
-			}
-		});
-	},
+		shrink: function(args){
+			// summary:
+			//		Returns an animation that shrinks args.node
+			//
+			// description:
+			//		Shrinks an element, same as expand({ node: node, endScale: .01 });
+			//
+			return this.expand({
+				node: args.node,
+				endScale: .01
+			});
+		},
 
-	flip: function(args){
-		// summary:
-		//		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
-		//
-		// example:
-		//	|	// half flip
-		//	|	dojox.css3.fx.flip({
-		//	|		node: domNode,
-		//	|		whichAnim: [0, 1]
-		//	|	}).play();
-		//
-		var anims = [],
-			whichAnims = args.whichAnims || [0, 1, 2, 3],
-				direction = args.direction || 1,
-			transforms = [
-				{ start: "scale(1, 1) skew(0deg,0deg)", end: "scale(0, 1) skew(0," + (direction * 30) + "deg)" },
-				{ start: "scale(0, 1) skew(0deg," + (direction * 30) + "deg)", end: "scale(-1, 1) skew(0deg,0deg)" },
-				{ start: "scale(-1, 1) skew(0deg,0deg)", end: "scale(0, 1) skew(0deg," + (-direction * 30) + "deg)" },
-				{ start: "scale(0, 1) skew(0deg," + (-direction * 30) + "deg)", end: "scale(1, 1) skew(0deg,0deg)" }
-		];
-		for(var i = 0; i < whichAnims.length; i++){
-			anims.push(dojo.animateProperty(
-				dojo.mixin({
+		rotate: function(args){
+			// summary:
+			//		Returns an animation that rotates an element
+			//
+			// description:
+			//		Rotates an element from args.startAngle to args.endAngle
+			//
+			return baseFx.animateProperty({
 				node: args.node,
-				duration: args.duration || 600,
+				duration: args.duration || 1000,
 				properties: {
-					transform: transforms[whichAnims[i]]
-				}}, args)
-			));
-		}
-		return dojo.fx.chain(anims);
-	},
-
-	bounce: function(args){
-		// summary:
-		//		Returns an animation that do a "bounce" effect on args.node
-		//
-		// description:
-		//		Vertical bounce animation, the scaleX, scaleY deformation and the
-		//		jump height (args.jumpHeight) can be specified
-		//
-		var anims = [],
-			n = args.node,
-			duration = args.duration || 1000,
-			scaleX = args.scaleX || 1.2,
-			scaleY = args.scaleY || .6,
-			ds = dojo.style,
-			oldPos = ds(n, "position"),
-			newPos = "absolute",
-			oldTop = ds(n, "top"),
-			combinedAnims = [],
-			bTime = 0,
-			round = Math.round,
-			jumpHeight = args.jumpHeight || 70
-		;
-		if(oldPos !== "absolute"){
-			newPos = "relative";
-		}
-		var a1 = dojo.animateProperty({
-			node: n,
-			duration: duration / 6,
-			properties: {
-				transform: { start: "scale(1, 1)", end: "scale(" + scaleX + ", " + scaleY + ")" }
-			}
-		});
-		dojo.connect(a1, "onBegin", function(){
-			ds(n, {
-				transformOrigin: "50% 100%",
-				position: newPos
+					transform: { start: "rotate(" + (args.startAngle || "0deg") + ")", end: "rotate(" + (args.endAngle || "360deg") + ")" }
+				}
 			});
-		});
-		anims.push(a1);
-		var a2 = dojo.animateProperty({
-			node: n,
-			duration: duration / 6,
-			properties: {
-				transform: { end: "scale(1, 1)", start: "scale(" + scaleX + ", " + scaleY + ")" }
+		},
+
+		flip: function(args){
+			// summary:
+			//		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
+			//
+			// example:
+			//	|	// half flip
+			//	|	dojox.css3.fx.flip({
+			//	|		node: domNode,
+			//	|		whichAnim: [0, 1]
+			//	|	}).play();
+			//
+			var anims = [],
+				whichAnims = args.whichAnims || [0, 1, 2, 3],
+					direction = args.direction || 1,
+				transforms = [
+					{ start: "scale(1, 1) skew(0deg,0deg)", end: "scale(0, 1) skew(0," + (direction * 30) + "deg)" },
+					{ start: "scale(0, 1) skew(0deg," + (direction * 30) + "deg)", end: "scale(-1, 1) skew(0deg,0deg)" },
+					{ start: "scale(-1, 1) skew(0deg,0deg)", end: "scale(0, 1) skew(0deg," + (-direction * 30) + "deg)" },
+					{ start: "scale(0, 1) skew(0deg," + (-direction * 30) + "deg)", end: "scale(1, 1) skew(0deg,0deg)" }
+			];
+			for(var i = 0; i < whichAnims.length; i++){
+				anims.push(baseFx.animateProperty(
+					lang.mixin({
+					node: args.node,
+					duration: args.duration || 600,
+					properties: {
+						transform: transforms[whichAnims[i]]
+					}}, args)
+				));
 			}
-		});
-		combinedAnims.push(a2);
-		combinedAnims.push(new dojo.Animation(dojo.mixin({
-			curve: [],
-			duration: duration / 3,
-			delay: duration / 12,
-			onBegin: function(){
-				bTime = (new Date).getTime();
-			},
-			onAnimate: function(){
-				var cTime = (new Date).getTime();
-				ds(n, {
-					top: parseInt(ds(n, "top")) - round(jumpHeight*((cTime-bTime)/this.duration)) + "px"
-				});
-				bTime = cTime;
+			return coreFx.chain(anims);
+		},
+
+		bounce: function(args){
+			// summary:
+			//		Returns an animation that do a "bounce" effect on args.node
+			//
+			// description:
+			//		Vertical bounce animation, the scaleX, scaleY deformation and the
+			//		jump height (args.jumpHeight) can be specified
+			//
+			var anims = [],
+				n = args.node,
+				duration = args.duration || 1000,
+				scaleX = args.scaleX || 1.2,
+				scaleY = args.scaleY || .6,
+				ds = htmlUtil.style,
+				oldPos = ds(n, "position"),
+				newPos = "absolute",
+				oldTop = ds(n, "top"),
+				combinedAnims = [],
+				bTime = 0,
+				round = Math.round,
+				jumpHeight = args.jumpHeight || 70
+			;
+			if(oldPos !== "absolute"){
+				newPos = "relative";
 			}
-		}, args)));
-		anims.push(dojo.fx.combine(combinedAnims));
-		anims.push(dojo.animateProperty(dojo.mixin({
-			duration: duration / 3,
-			onEnd: function(){
+			var a1 = baseFx.animateProperty({
+				node: n,
+				duration: duration / 6,
+				properties: {
+					transform: { start: "scale(1, 1)", end: "scale(" + scaleX + ", " + scaleY + ")" }
+				}
+			});
+			connectUtil.connect(a1, "onBegin", function(){
 				ds(n, {
-					position: oldPos
+					transformOrigin: "50% 100%",
+					position: newPos
 				});
-			},
-			properties:{
-				top: oldTop
-			}
-		}, args)));
-		anims.push(a1);
-		anims.push(a2);
+			});
+			anims.push(a1);
+			var a2 = baseFx.animateProperty({
+				node: n,
+				duration: duration / 6,
+				properties: {
+					transform: { end: "scale(1, 1)", start: "scale(" + scaleX + ", " + scaleY + ")" }
+				}
+			});
+			combinedAnims.push(a2);
+			combinedAnims.push(new baseFx.Animation(lang.mixin({
+				curve: [],
+				duration: duration / 3,
+				delay: duration / 12,
+				onBegin: function(){
+					bTime = (new Date).getTime();
+				},
+				onAnimate: function(){
+					var cTime = (new Date).getTime();
+					ds(n, {
+						top: parseInt(ds(n, "top")) - round(jumpHeight*((cTime-bTime)/this.duration)) + "px"
+					});
+					bTime = cTime;
+				}
+			}, args)));
+			anims.push(coreFx.combine(combinedAnims));
+			anims.push(baseFx.animateProperty(lang.mixin({
+				duration: duration / 3,
+				onEnd: function(){
+					ds(n, {
+						position: oldPos
+					});
+				},
+				properties:{
+					top: oldTop
+				}
+			}, args)));
+			anims.push(a1);
+			anims.push(a2);
 
-		return dojo.fx.chain(anims);
-	}
-});
\ No newline at end of file
+			return coreFx.chain(anims);
+		}
+	});
+});
diff --git a/dojox/css3/transit.js b/dojox/css3/transit.js
new file mode 100644
index 0000000..203e94e
--- /dev/null
+++ b/dojox/css3/transit.js
@@ -0,0 +1,62 @@
+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){
+		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.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;
+			}
+			domStyle.set(from, "display", ""); 
+			domStyle.set(to, "display", "");
+			if (from){
+				//create transition to transit "from" out
+				var fromTransit = transition[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 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
+			//play fromTransit and toTransit together
+			if(options.transition === "flip"){
+				transition.chainedPlay(transit);
+			}else{
+				transition.groupedPlay(transit);
+			}
+
+			return new DeferredList(defs);
+			
+		}
+	};
+	
+	return transit;
+});
diff --git a/dojox/css3/transition.js b/dojox/css3/transition.js
new file mode 100644
index 0000000..1fd9f72
--- /dev/null
+++ b/dojox/css3/transition.js
@@ -0,0 +1,344 @@
+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.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 = {
+				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.css3.transition.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.css3.transition.playing[this.node.id]===this.deferred){
+				delete dojox.css3.transition.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.css3.transition.slide = function(node, config){
+
+		//TODO create the return and set the startState, endState of the return
+		var ret = new dojox.css3.transition(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.css3.transition.fade = function(node, config){
+		
+		var ret = new dojox.css3.transition(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.css3.transition.flip = function(node, config){
+		
+		var ret = new dojox.css3.transition(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.css3.transition.playing[node.id]){
+				//TODO hook on deferred object in dojox.css3.transition.playing
+				defs.push(dojox.css3.transition.playing[node.id]);
+			}
+			
+		});
+		return new deferredList(defs);
+	};
+	
+	dojox.css3.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
+		
+		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.css3.transition.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.css3.transition.chainedPlay = function(/*Array*/args){
+		//args should be array of dojox.css3.transition
+		
+		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.css3.transition.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.css3.transition.playing = {};
+	
+	return dojox.css3.transition;
+});
diff --git a/dojox/data/AndOrReadStore.js b/dojox/data/AndOrReadStore.js
index f955fb1..e8564e4 100755
--- a/dojox/data/AndOrReadStore.js
+++ b/dojox/data/AndOrReadStore.js
@@ -1,6 +1,8 @@
-define("dojox/data/AndOrReadStore", ["dojo", "dojox", "dojo/data/util/filter", "dojo/data/util/simpleFetch", "dojo/date/stamp"], function(dojo, dojox) {
+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) {
 
-dojo.declare("dojox.data.AndOrReadStore", null,{
+var AndOrReadStore = declare("dojox.data.AndOrReadStore", null, {
 	//	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*)"
@@ -52,7 +54,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 			this._datatypeMap['Date'] = {
 											type: Date,
 											deserialize: function(value){
-												return dojo.date.stamp.fromISOString(value);
+												return dateStamp.fromISOString(value);
 											}
 										};
 		}
@@ -175,7 +177,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 		//		See dojo.data.api.Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
-			regexp = dojo.data.util.filter.patternToRegExp(value, false);
+			regexp = filterUtil.patternToRegExp(value, false);
 		}
 		return this._containsValue(item, attribute, value, regexp); //boolean.
 	},
@@ -200,13 +202,15 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 		//	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 dojo.some(this.getValues(item, attribute), function(possibleValue){
-			if(possibleValue !== null && !dojo.isObject(possibleValue) && regexp){
+		return array.some(this.getValues(item, attribute), function(possibleValue){
+			if(possibleValue !== null && !lang.isObject(possibleValue) && regexp){
 				if(possibleValue.toString().match(regexp)){
 					return true; // Boolean
 				}
-			}else if(value === possibleValue){
+			} else if(value === possibleValue){
 				return true; // Boolean
+			} else {
+				return false;
 			}
 		});
 	},
@@ -273,7 +277,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 			if(requestArgs.query){
 				//Complete copy, we may have to mess with it.
 				//Safer than clone, which does a shallow copy, I believe.
-				var query = dojo.fromJson(dojo.toJson(requestArgs.query));
+				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
@@ -296,7 +300,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 								}
 								//Make sure strings are quoted when going into complexQuery merge.
 								var v = requestArgs.query[p];
-								if(dojo.isString(v)){
+								if(lang.isString(v)){
 									v = "'" + v + "'";
 								}
 								cq += " AND " + p + ":" + v;
@@ -312,14 +316,14 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 				//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 = dojo.toJson(query);
+					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 = dojo.trim(query.replace(/{|}/g,"")); //we can handle these, too.
+				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 = dojo.trim(complexQuery.replace(/"?\s*complexQuery\s*"?:/,""));
+					complexQuery = lang.trim(complexQuery.replace(/"?\s*complexQuery\s*"?:/,""));
 					var quotes = ["'",'"'];
 					var pos1,colon;
 					var flag = false;
@@ -364,8 +368,8 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 							
 							//get/process/append one or two leading logical operators.
 							while(op && !err){ //look for leading logical operators.
-								complexQuery = dojo.trim(complexQuery.replace(op[0],""));
-								op = dojo.trim(op[0]).toUpperCase();
+								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 + " ";
@@ -380,8 +384,8 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 									err = true;
 									break;
 								}else{
-									key = dojo.trim(complexQuery.substring(0,pos).replace(/\"|\'/g,""));
-									complexQuery = dojo.trim(complexQuery.substring(pos + 1));
+									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];
@@ -395,9 +399,9 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 										if(pos2 == complexQuery.length - 1){ //quote is last character
 											complexQuery = "";
 										}else{
-											complexQuery = dojo.trim(complexQuery.substring(pos2 + 1));
+											complexQuery = lang.trim(complexQuery.substring(pos2 + 1));
 										}
-										sQuery += self._containsValue(candidateItem, key, value, dojo.data.util.filter.patternToRegExp(value, ignoreCase));
+										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|\)|,/);
@@ -412,13 +416,13 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 													pos = Math.min(pos,pos3[j]);
 												}
 											}
-											value = dojo.trim(complexQuery.substring(0,pos));
-											complexQuery = dojo.trim(complexQuery.substring(pos));
+											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 = dojo.trim(complexQuery);
+											value = lang.trim(complexQuery);
 											complexQuery = "";
 										} //end  inner if(tok) else
-										sQuery += self._containsValue(candidateItem, key, value, dojo.data.util.filter.patternToRegExp(value, ignoreCase));
+										sQuery += self._containsValue(candidateItem, key, value, filterUtil.patternToRegExp(value, ignoreCase));
 									} //end outer if(tok) else
 								} //end found ":"
 							} //end if(complexQuery.length > 0)
@@ -456,7 +460,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 			filter(keywordArgs, this._getItemsArray(keywordArgs.queryOptions));
 		}else{
 			if(this._jsonFileUrl !== this._ccUrl){
-				dojo.deprecated("dojox.data.AndOrReadStore: ",
+				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;
@@ -483,7 +487,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 							handleAs: "json-comment-optional",
 							preventCache: this.urlPreventCache
 						};
-					var getHandler = dojo.xhrGet(getArgs);
+					var getHandler = xhr.get(getArgs);
 					getHandler.addCallback(function(data){
 						try{
 							self._getItemsFromLoadedData(data);
@@ -626,8 +630,8 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 			var isItem = (
 				(aValue !== null) &&
 				(typeof aValue === "object") &&
-				(!dojo.isArray(aValue)) &&
-				(!dojo.isFunction(aValue)) &&
+				(!lang.isArray(aValue)) &&
+				(!lang.isFunction(aValue)) &&
 				(aValue.constructor == Object) &&
 				(typeof aValue._reference === "undefined") &&
 				(typeof aValue._type === "undefined") &&
@@ -642,7 +646,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 			for(var attribute in anItem){
 				var valueForAttribute = anItem[attribute];
 				if(valueForAttribute){
-					if(dojo.isArray(valueForAttribute)){
+					if(lang.isArray(valueForAttribute)){
 						var valueArray = valueForAttribute;
 						for(var k = 0; k < valueArray.length; ++k){
 							var singleValue = valueArray[k];
@@ -694,7 +698,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 				if(key !== this._rootItemPropName){
 					var value = item[key];
 					if(value !== null){
-						if(!dojo.isArray(value)){
+						if(!lang.isArray(value)){
 							item[key] = [value];
 						}
 					}else{
@@ -780,9 +784,9 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 							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(dojo.isFunction(mappingObj)){
+							}else if(lang.isFunction(mappingObj)){
 								arrayOfValues[j] = new mappingObj(value._value);
-							}else if(dojo.isFunction(mappingObj.deserialize)){
+							}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");
@@ -790,7 +794,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 						}
 						if(value._reference){
 							var referenceDescription = value._reference; // example: {name:'Miss Piggy'}
-							if(!dojo.isObject(referenceDescription)){
+							if(!lang.isObject(referenceDescription)){
 								// example: 'Miss Piggy'
 								// from an item like: { name:['Kermit'], friends:[{_reference:'Miss Piggy'}]}
 								arrayOfValues[j] = this._getItemByIdentity(referenceDescription);
@@ -868,7 +872,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 		if(!this._loadFinished){
 			var self = this;
 			if(this._jsonFileUrl !== this._ccUrl){
-				dojo.deprecated("dojox.data.AndOrReadStore: ",
+				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;
@@ -893,9 +897,9 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 							handleAs: "json-comment-optional",
 							preventCache: this.urlPreventCache
 					};
-					var getHandler = dojo.xhrGet(getArgs);
+					var getHandler = xhr.get(getArgs);
 					getHandler.addCallback(function(data){
-						var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+						var scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
 						try{
 							self._getItemsFromLoadedData(data);
 							self._loadFinished = true;
@@ -915,7 +919,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 					getHandler.addErrback(function(error){
 						self._loadInProgress = false;
 						if(keywordArgs.onError){
-							var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+							var scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
 							keywordArgs.onError.call(scope, error);
 						}
 					});
@@ -928,7 +932,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 				self._loadFinished = true;
 				var item = self._getItemByIdentity(keywordArgs.identity);
 				if(keywordArgs.onItem){
-					var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+					var scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
 					keywordArgs.onItem.call(scope, item);
 				}
 			}
@@ -936,7 +940,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 			// 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:dojo.global;
+				var scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
 				keywordArgs.onItem.call(scope, item);
 			}
 		}
@@ -979,7 +983,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 		//		for specific functions to work properly.
 		var self = this;
 		if(this._jsonFileUrl !== this._ccUrl){
-			dojo.deprecated("dojox.data.AndOrReadStore: ",
+			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;
@@ -1000,7 +1004,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 					preventCache: this.urlPreventCache,
 					sync: true
 				};
-			var getHandler = dojo.xhrGet(getArgs);
+			var getHandler = xhr.get(getArgs);
 			getHandler.addCallback(function(data){
 				try{
 					//Check to be sure there wasn't another load going on concurrently
@@ -1034,9 +1038,9 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 	}
 });
 //Mix in the simple fetch implementation to this class.
-dojo.extend(dojox.data.AndOrReadStore,dojo.data.util.simpleFetch);
+lang.extend(AndOrReadStore, simpleFetch);
 
-return dojox.data.AndOrReadStore;
+return AndOrReadStore;
 });
 
 
diff --git a/dojox/data/AndOrWriteStore.js b/dojox/data/AndOrWriteStore.js
index 363ddac..8c67bae 100755
--- a/dojox/data/AndOrWriteStore.js
+++ b/dojox/data/AndOrWriteStore.js
@@ -1,6 +1,9 @@
-define("dojox/data/AndOrWriteStore", ["dojo", "dojox", "dojox/data/AndOrReadStore"], function(dojo, dojox) {
+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; =====*/
 
-dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
+return declare("dojox.data.AndOrWriteStore", AndOrReadStore, {
 	constructor: function(/* object */ keywordParameters){
 		//	keywordParameters: {typeMap: object)
 		//		The structure of the typeMap object is as follows:
@@ -34,7 +37,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 
 		if(!this._datatypeMap['Date'].serialize){
 			this._datatypeMap['Date'].serialize = function(obj){
-				return dojo.date.stamp.toISOString(obj, {zulu:true});
+				return dateStamp.toISOString(obj, {zulu:true});
 			};
 		}
 		//Disable only if explicitly set to false.
@@ -86,7 +89,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 			if(typeof newIdentity === "undefined"){
 				throw new Error("newItem() was not passed an identity for the new item");
 			}
-			if(dojo.isArray(newIdentity)){
+			if(lang.isArray(newIdentity)){
 				throw new Error("newItem() was not passed an single-valued identity");
 			}
 		}
@@ -166,7 +169,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 				throw new Error("encountered bug in ItemFileWriteStore.newItem");
 			}
 			var value = keywordArgs[key];
-			if(!dojo.isArray(value)){
+			if(!lang.isArray(value)){
 				value = [value];
 			}
 			newItem[key] = value;
@@ -184,7 +187,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 	},
 	
 	_removeArrayElement: function(/* Array */ array, /* anything */ element){
-		var index = dojo.indexOf(array, element);
+		var index = arrayUtil.indexOf(array, element);
 		if(index != -1){
 			array.splice(index, 1);
 			return true;
@@ -214,15 +217,15 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 
 			//Backup the map, we'll have to restore it potentially, in a revert.
 			if(item[this._reverseRefMap]){
-				item["backup_" + this._reverseRefMap] = dojo.clone(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.
-			dojo.forEach(attributes, function(attribute){
-				dojo.forEach(this.getValues(item, attribute), function(value){
+			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]){
@@ -250,7 +253,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 					if(containingItem){
 						for(var attribute in references[itemId]){
 							var oldValues = this.getValues(containingItem, attribute) || [];
-							var newValues = dojo.filter(oldValues, function(possibleItem){
+							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.
@@ -300,7 +303,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 		
 		// Check for valid arguments
 		this._assertIsItem(item);
-		this._assert(dojo.isString(attribute));
+		this._assert(lang.isString(attribute));
 		this._assert(typeof newValueOrValues !== "undefined");
 
 		// Make sure the user isn't trying to change the item's identity
@@ -326,7 +329,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 				if((key === this._storeRefPropName) || (key === this._itemNumPropName) || (key === this._rootItemPropName)){
 					copyOfItemState[key] = item[key];
 				}else if(key === this._reverseRefMap){
-					copyOfItemState[key] = dojo.clone(item[key]);
+					copyOfItemState[key] = lang.clone(item[key]);
 				}else{
 					copyOfItemState[key] = item[key].slice(0, item[key].length);
 				}
@@ -338,7 +341,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 		// Okay, now we can actually change this attribute on the item
 		var success = false;
 		
-		if(dojo.isArray(newValueOrValues) && newValueOrValues.length === 0){
+		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
@@ -348,7 +351,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 
 			if(this.referenceIntegrity && oldValueOrValues){
 				var oldValues = oldValueOrValues;
-				if(!dojo.isArray(oldValues)){
+				if(!lang.isArray(oldValues)){
 					oldValues = [oldValues];
 				}
 				for(var i = 0; i < oldValues.length; i++){
@@ -360,7 +363,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 			}
 		}else{
 			var newValueArray;
-			if(dojo.isArray(newValueOrValues)){
+			if(lang.isArray(newValueOrValues)){
 				var newValues = newValueOrValues;
 				// Unfortunately, it's not safe to just do this:
 				//    newValueArray = newValues;
@@ -379,7 +382,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 			if(this.referenceIntegrity){
 				if(oldValueOrValues){
 					var oldValues = oldValueOrValues;
-					if(!dojo.isArray(oldValues)){
+					if(!lang.isArray(oldValues)){
 						oldValues = [oldValues];
 					}
 					//Use an associative map to determine what was added/removed from the list.
@@ -388,13 +391,13 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 					//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 = {};
-					dojo.forEach(oldValues, function(possibleItem){
+					arrayUtil.forEach(oldValues, function(possibleItem){
 						if(this.isItem(possibleItem)){
 							var id = this.getIdentity(possibleItem);
 							map[id.toString()] = true;
 						}
 					}, this);
-					dojo.forEach(newValueArray, function(possibleItem){
+					arrayUtil.forEach(newValueArray, function(possibleItem){
 						if(this.isItem(possibleItem)){
 							var id = this.getIdentity(possibleItem);
 							if(map[id.toString()]){
@@ -501,7 +504,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 		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: " + dojo.toJson(item[this._reverseRefMap]));
+				console.log("Item: [" + this.getIdentity(item) + "] is referenced by: " + json.toJson(item[this._reverseRefMap]));
 			}
 		}
 	},
@@ -535,7 +538,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 			if(typeof value === "object"){
 				for(var type in this._datatypeMap){
 					var typeMap = this._datatypeMap[type];
-					if(dojo.isObject(typeMap) && !dojo.isFunction(typeMap)){
+					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 + "]");
@@ -590,7 +593,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 			}
 		}
 		var prettyPrint = true;
-		return dojo.toJson(serializableStructure, prettyPrint);
+		return json.toJson(serializableStructure, prettyPrint);
 	},
 
 	_isEmpty: function(something){
@@ -599,13 +602,13 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 		//	something:
 		//		The array or object to examine.
 		var empty = true;
-		if(dojo.isObject(something)){
+		if(lang.isObject(something)){
 			var i;
 			for(i in something){
 				empty = false;
 				break;
 			}
-		}else if(dojo.isArray(something)){
+		}else if(lang.isArray(something)){
 			if(something.length > 0){
 				empty = false;
 			}
@@ -630,14 +633,14 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 
 			self._saveInProgress = false; // must come after this._pending is cleared, but before any callbacks
 			if(keywordArgs && keywordArgs.onComplete){
-				var scope = keywordArgs.scope || dojo.global;
+				var scope = keywordArgs.scope || winUtil.global;
 				keywordArgs.onComplete.call(scope);
 			}
 		};
 		var saveFailedCallback = function(){
 			self._saveInProgress = false;
 			if(keywordArgs && keywordArgs.onError){
-				var scope = keywordArgs.scope || dojo.global;
+				var scope = keywordArgs.scope || winUtil.global;
 				keywordArgs.onError.call(scope);
 			}
 		};
@@ -678,7 +681,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 			for(key in modifiedItem){
 				delete modifiedItem[key];
 			}
-			dojo.mixin(modifiedItem, copyOfItemState);
+			lang.mixin(modifiedItem, copyOfItemState);
 		}
 		var deletedItem;
 		for(identity in this._pending._deletedItems){
@@ -704,7 +707,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 		for(identity in this._pending._deletedItems){
 			deletedItem = this._pending._deletedItems[identity];
 			if(deletedItem["backupRefs_" + this._reverseRefMap]){
-				dojo.forEach(deletedItem["backupRefs_" + this._reverseRefMap], function(reference){
+				arrayUtil.forEach(deletedItem["backupRefs_" + this._reverseRefMap], function(reference){
 					var refItem;
 					if(this._itemsByIdentity){
 						refItem = this._itemsByIdentity[reference.id];
@@ -805,5 +808,4 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 	}
 });
 
-return dojox.data.AndOrWriteStore;
 });
diff --git a/dojox/data/AppStore.js b/dojox/data/AppStore.js
index 1273739..91b8d3d 100644
--- a/dojox/data/AppStore.js
+++ b/dojox/data/AppStore.js
@@ -1,4 +1,4 @@
-define("dojox/data/AppStore", ["dojo", "dojox", "dojo/data/util/simpleFetch", "dojo/data/util/filter", "dojox/atom/io/Connection"], function(dojo, dojox) {
+define(["dojo", "dojox", "dojo/data/util/simpleFetch", "dojo/data/util/filter", "dojox/atom/io/Connection"], function(dojo, dojox) {
 
 dojo.experimental("dojox.data.AppStore");
 
@@ -185,7 +185,7 @@ dojo.declare("dojox.data.AppStore",
 			}
 			if(item[attribute]){
 				item = item[attribute];
-				if(item.declaredClass == "dojox.atom.io.model.Content"){
+				if(item.nodeType == "Content"){
 					return [item.value];
 				}
 				return [item] ;
diff --git a/dojox/data/AtomReadStore.js b/dojox/data/AtomReadStore.js
index a9c03f8..4a8f85d 100644
--- a/dojox/data/AtomReadStore.js
+++ b/dojox/data/AtomReadStore.js
@@ -1,4 +1,4 @@
-define("dojox/data/AtomReadStore", ["dojo", "dojox", "dojo/data/util/filter", "dojo/data/util/simpleFetch", "dojo/date/stamp"], function(dojo, dojox) {
+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, {
diff --git a/dojox/data/CdfStore.js b/dojox/data/CdfStore.js
index 56a1af9..0d81a30 100755
--- a/dojox/data/CdfStore.js
+++ b/dojox/data/CdfStore.js
@@ -1,4 +1,4 @@
-define("dojox/data/CdfStore", ["dojo", "dojox", "dojo/data/util/sorter"], function(dojo, dojox) {
+define(["dojo", "dojox", "dojo/data/util/sorter"], function(dojo, dojox) {
 
 dojox.data.ASYNC_MODE = 0;
 dojox.data.SYNC_MODE = 1;
diff --git a/dojox/data/ClientFilter.js b/dojox/data/ClientFilter.js
index e1c0d31..0412299 100644
--- a/dojox/data/ClientFilter.js
+++ b/dojox/data/ClientFilter.js
@@ -1,8 +1,8 @@
-define("dojox/data/ClientFilter", ["dojo", "dojox", "dojo/data/util/filter"], function(dojo, dojox) {
+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
-(function(){
-	var cf;
+
 	var addUpdate = function(store,create,remove){
 		// create a handler that adds to the list of notifications
 		return function(item){
@@ -10,39 +10,37 @@ define("dojox/data/ClientFilter", ["dojo", "dojox", "dojo/data/util/filter"], fu
 					create:create && item,
 					remove:remove && item
 				});
-			cf.onUpdate();
+			ClientFilter.onUpdate();
 		}
 	};
-	cf = dojo.declare("dojox.data.ClientFilter",
-		null,
-		{
+	var ClientFilter = declare("dojox.data.ClientFilter", null, {
 			cacheByDefault: false,
 			constructor: function(){
 				// summary:
 				//		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
+				//		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:
 				//		To a update a result set after a notification (onNew, onSet, and onDelete),
-				// 		widgets can call the updateResultSet method. Widgets can use the updated
+				//		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
 				//		based on changes.
 				//
-				// 		This module will use the best available information to update result sets, using query attribute
-				// 		objects to determine if items are in a result set, and using the sort arrays to maintain sort
-				// 		information. However, queries can be opaque strings, and this module can not update
-				// 		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
+				//		This module will use the best available information to update result sets, using query attribute
+				//		objects to determine if items are in a result set, and using the sort arrays to maintain sort
+				//		information. However, queries can be opaque strings, and this module can not update
+				//		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
+				//		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.
-				// 		This can be defined in the constructor options for ServiceStore/JsonRestStore and subtypes.
+				//		cause all queries to be cached by default unless the cache queryOption is explicitly set to false.
+				//		This can be defined in the constructor options for ServiceStore/JsonRestStore and subtypes.
 				//
 				// example:
 				//		to make a updated-result-set data store from an existing data store:
@@ -90,7 +88,7 @@ define("dojox/data/ClientFilter", ["dojo", "dojox", "dojo/data/util/filter"], fu
 							}
 						}
 						if(create && this.matchesQuery(create,request) && // if there is a new/replacement item and it matches the query
-								dojo.indexOf(resultSet,create) == -1){ // and it doesn't already exist in query
+								array.indexOf(resultSet,create) == -1){ // and it doesn't already exist in query
 							resultSet.push(create); // should this go at the beginning by default instead?
 							updated = true;
 						}
@@ -114,9 +112,9 @@ define("dojox/data/ClientFilter", ["dojo", "dojox", "dojo/data/util/filter"], fu
 				//	summary:
 				//		Determines whether the provided arguments are super/sub sets of each other
 				// argsSuper:
-				// 		Dojo Data Fetch arguments
+				//		Dojo Data Fetch arguments
 				// argsSub:
-				// 		Dojo Data Fetch arguments
+				//		Dojo Data Fetch arguments
 				if(argsSuper.query == argsSub.query){
 					return {};
 				}
@@ -125,14 +123,14 @@ define("dojox/data/ClientFilter", ["dojo", "dojox", "dojo/data/util/filter"], fu
 						(!argsSuper.query || typeof argsSuper.query == 'object'))){
 					return false;
 				}
-				var clientQuery = dojo.mixin({},argsSub.query);
+				var clientQuery = lang.mixin({},argsSub.query);
 				for(var i in argsSuper.query){
 					if(clientQuery[i] == argsSuper.query[i]){
 						delete clientQuery[i];
 					}else if(!(typeof argsSuper.query[i] == 'string' &&
 							// if it is a pattern, we can test to see if it is a sub-pattern
 							// FIXME: This is not technically correct, but it will work for the majority of cases
-							dojo.data.util.filter.patternToRegExp(argsSuper.query[i]).test(clientQuery[i]))){
+							filter.patternToRegExp(argsSuper.query[i]).test(clientQuery[i]))){
 						return false;
 					}
 				}
@@ -150,11 +148,11 @@ define("dojox/data/ClientFilter", ["dojo", "dojox", "dojo/data/util/filter"], fu
 					if(clientQuery !== false){
 						var defResult = cachedArgs._loading;
 						if(!defResult){
-							defResult = new dojo.Deferred();
+							defResult = new Deferred();
 							defResult.callback(cachedArgs.cacheResults);
 						}
 						defResult.addCallback(function(results){
-							results = self.clientSideFetch(dojo.mixin(dojo.mixin({}, args),{query:clientQuery}), results);
+							results = self.clientSideFetch(lang.mixin(lang.mixin({}, args),{query:clientQuery}), results);
 							defResult.fullLength = results._fullLength;
 							return results;
 						});
@@ -163,7 +161,7 @@ define("dojox/data/ClientFilter", ["dojo", "dojox", "dojo/data/util/filter"], fu
 					}
 				}
 				if(!defResult){
-					var serverArgs = dojo.mixin({}, args);
+					var serverArgs = lang.mixin({}, args);
 					var putInCache = (args.queryOptions || 0).cache;
 					var fetchCache = this._fetchCache;
 					if(putInCache === undefined ? this.cacheByDefault : putInCache){
@@ -171,7 +169,7 @@ define("dojox/data/ClientFilter", ["dojo", "dojox", "dojo/data/util/filter"], fu
 						if(args.start || args.count){
 							delete serverArgs.start;
 							delete serverArgs.count;
-							args.clientQuery = dojo.mixin(args.clientQuery || {}, {
+							args.clientQuery = lang.mixin(args.clientQuery || {}, {
 								start: args.start,
 								count: args.count
 							});
@@ -182,7 +180,7 @@ define("dojox/data/ClientFilter", ["dojo", "dojox", "dojo/data/util/filter"], fu
 					defResult= args._loading = this._doQuery(args);
 					 
 					defResult.addErrback(function(){
-						fetchCache.splice(dojo.indexOf(fetchCache, args), 1);
+						fetchCache.splice(array.indexOf(fetchCache, args), 1);
 					});
 				}
 				var version = this.serverVersion;
@@ -254,7 +252,7 @@ define("dojox/data/ClientFilter", ["dojo", "dojox", "dojo/data/util/filter"], fu
 					var match = query[i];
 					var value = this.getValue(item,i);
 					if((typeof match == 'string' && (match.match(/[\*\.]/) || ignoreCase)) ?
-						!dojo.data.util.filter.patternToRegExp(match, ignoreCase).test(value) :
+						!filter.patternToRegExp(match, ignoreCase).test(value) :
 						value != match){
 						return false;
 					}
@@ -263,7 +261,7 @@ define("dojox/data/ClientFilter", ["dojo", "dojox", "dojo/data/util/filter"], fu
 			},
 			makeComparator: function(sort){
 				//	summary:
-				// 		returns a comparator function for the given sort order array
+				//		returns a comparator function for the given sort order array
 				//	sort:
 				//		See dojox.data.api.Read.fetch
 				var current = sort.shift();
@@ -288,8 +286,7 @@ define("dojox/data/ClientFilter", ["dojo", "dojox", "dojo/data/util/filter"], fu
 			}
 		}
 	);
-	cf.onUpdate = function(){};
-})();
+	ClientFilter.onUpdate = function(){};
 
-return dojox.data.ClientFilter;
+	return ClientFilter;
 });
diff --git a/dojox/data/CouchDBRestStore.js b/dojox/data/CouchDBRestStore.js
index 467f037..39a91e7 100644
--- a/dojox/data/CouchDBRestStore.js
+++ b/dojox/data/CouchDBRestStore.js
@@ -1,4 +1,4 @@
-define("dojox/data/CouchDBRestStore", ["dojo", "dojox", "dojox/data/JsonRestStore"], function(dojo, dojox) {
+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.
diff --git a/dojox/data/CssClassStore.js b/dojox/data/CssClassStore.js
index cedbec4..86dc71d 100755
--- a/dojox/data/CssClassStore.js
+++ b/dojox/data/CssClassStore.js
@@ -1,6 +1,9 @@
-define("dojox/data/CssClassStore", ["dojo", "dojox", "dojox/data/CssRuleStore"], function(dojo, dojox) {
+define(["dojo/_base/declare","dojox/data/CssRuleStore"], 
+  function(declare, CssRuleStore) {
 
-dojo.declare("dojox.data.CssClassStore", dojox.data.CssRuleStore, {
+/*===== var CssRuleStore = dojox.data.CssRuleStore =====*/
+
+return declare("dojox.data.CssClassStore", CssRuleStore, {
 	//	summary:
 	//		Basic store to display CSS information.
 	//	description:
@@ -113,7 +116,7 @@ dojo.declare("dojox.data.CssClassStore", dojox.data.CssRuleStore, {
 		var items = request._items;
 		// Per https://bugs.webkit.org/show_bug.cgi?id=17935 , Safari 3.x always returns the selectorText
 		// of a rule in full lowercase.
-		var item = items[(dojo.isWebKit?request.identity.toLowerCase():request.identity)];
+		var item = items[request.identity];
 		if(!this.isItem(item)){
 			item = null;
 		}
@@ -155,5 +158,4 @@ dojo.declare("dojox.data.CssClassStore", dojox.data.CssRuleStore, {
 	}
 });
 
-return dojox.data.CssClassStore;
 });
diff --git a/dojox/data/CssRuleStore.js b/dojox/data/CssRuleStore.js
index c1d740b..6d22e25 100755
--- a/dojox/data/CssRuleStore.js
+++ b/dojox/data/CssRuleStore.js
@@ -1,6 +1,7 @@
-define("dojox/data/CssRuleStore", ["dojo", "dojox", "dojo.data.util.sorter", "dojo/data/util/filter", "dojox/data/css"], function(dojo, dojox) {
+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) {
 
-dojo.declare("dojox.data.CssRuleStore", null, {
+return declare("dojox.data.CssRuleStore", null, {
 	//	summary:
 	//		Basic store to display CSS information.
 	//	description:
@@ -28,7 +29,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 	constructor: function(/* Object */ keywordParameters){
 		// Initializes this store
 		if(keywordParameters){
-			dojo.mixin(this, keywordParameters);
+			lang.mixin(this, keywordParameters);
 		}
 		this._cache = {};
 		this._allItems = null;
@@ -41,7 +42,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 			try{
 				// Funkiness here is due to css that may still be loading.  This throws an DOM Access
 				// error if css isnt completely loaded.
-				self.context = dojox.data.css.determineContext(self.context);
+				self.context = css.determineContext(self.context);
 				if(self.gatherHandle){
 					clearInterval(self.gatherHandle);
 					self.gatherHandle = null;
@@ -50,7 +51,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 				// to finish
 				while(self._waiting.length){
 					var item = self._waiting.pop();
-					dojox.data.css.rules.forEach(item.forFunc, null, self.context);
+					css.rules.forEach(item.forFunc, null, self.context);
 					item.finishFunc();
 				}
 			}catch(e){}
@@ -63,7 +64,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 		// context: Array - Array of CSS string paths to execute queries within
 		if(context){
 			this.close();
-			this.context = dojox.data.css.determineContext(context);
+			this.context = css.determineContext(context);
 		}
 	},
 
@@ -90,7 +91,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
 		var attrs = this.getAttributes(item);
-		if(dojo.indexOf(attrs, attribute) != -1){
+		if(array.indexOf(attrs, attribute) != -1){
 			return true;
 		}
 		return false;
@@ -130,7 +131,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 		var value = null;
 		if(attribute === "selector"){
 			value = item.rule["selectorText"];
-			if(value && dojo.isString(value)){
+			if(value && lang.isString(value)){
 				value = value.split(",");
 			}
 		}else if(attribute === "classes"){
@@ -140,7 +141,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 		}else if(attribute === "style"){
 			value = item.rule.style;
 		}else if(attribute === "cssText"){
-			if(dojo.isIE){
+			if(has("ie")){
 				if(item.rule.style){
 					value = item.rule.style.cssText;
 					if(value){
@@ -168,7 +169,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 			value = [];
 		}
 		if(value !== undefined){
-			if(!dojo.isArray(value)){
+			if(!lang.isArray(value)){
 				value = [value];
 			}
 		}
@@ -195,7 +196,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 		//		See dojo.data.api.Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
-			regexp = dojo.data.util.filter.patternToRegExp(value, false);
+			regexp = filter.patternToRegExp(value, false);
 		}
 		return this._containsValue(item, attribute, value, regexp); //boolean.
 	},
@@ -220,7 +221,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 			request.store = this;
 		}
 
-		var scope = request.scope || dojo.global;
+		var scope = request.scope || winUtil.global;
 		if(this._pending && this._pending.length > 0){
 			this._pending.push({request: request, fetch: true});
 		}else{
@@ -233,14 +234,14 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 	_fetch: function(request){
 		//	summary:
 		//		Populates the _allItems object with unique class names
-		var scope = request.scope || dojo.global;
+		var scope = request.scope || winUtil.global;
 		if(this._allItems === null){
 			this._allItems = {};
 			try{
 				if(this.gatherHandle){
-					this._waiting.push({'forFunc': dojo.hitch(this, this._handleRule), 'finishFunc': dojo.hitch(this, this._handleReturn)});
+					this._waiting.push({'forFunc': lang.hitch(this, this._handleRule), 'finishFunc': lang.hitch(this, this._handleReturn)});
 				}else{
-					dojox.data.css.rules.forEach(dojo.hitch(this, this._handleRule), null, this.context);
+					css.rules.forEach(lang.hitch(this, this._handleRule), null, this.context);
 					this._handleReturn();
 				}
 			}catch(e){
@@ -314,14 +315,14 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 	_handleFetchReturn: function(/*Request */ request){
 		//	summary:
 		//		Handles a fetchByIdentity request by finding the correct items.
-		var scope = request.scope || dojo.global;
+		var scope = request.scope || winUtil.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.
 		var cacheKey = "all";
 		var i;
 		if(request.query){
-			cacheKey = dojo.toJson(request.query);
+			cacheKey = jsonUtil.toJson(request.query);
 		}
 		if(this._cache[cacheKey]){
 			items = this._cache[cacheKey];
@@ -330,14 +331,14 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 				var item = request._items[i];
 				// Per https://bugs.webkit.org/show_bug.cgi?id=17935 , Safari 3.x always returns the selectorText
 				// of a rule in full lowercase.
-				var ignoreCase = dojo.isWebKit ? true : (request.queryOptions ? request.queryOptions.ignoreCase : false);
+				var ignoreCase = (request.queryOptions ? request.queryOptions.ignoreCase : false);
 				var regexpList = {};
 				var key;
 				var value;
 				for(key in request.query){
 					value = request.query[key];
 					if(typeof value === "string"){
-						regexpList[key] = dojo.data.util.filter.patternToRegExp(value, ignoreCase);
+						regexpList[key] = filter.patternToRegExp(value, ignoreCase);
 					}
 				}
 				var match = true;
@@ -361,7 +362,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 
 		//Sort it if we need to.
 		if(request.sort){
-			items.sort(dojo.data.util.sorter.createSortFunction(request.sort, this));
+			items.sort(sorter.createSortFunction(request.sort, this));
 		}
 		var start = 0;
 		var count = items.length;
@@ -382,7 +383,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 			request.onBegin.call(scope, total, request);
 		}
 		if(request.onItem){
-			if(dojo.isArray(items)){
+			if(lang.isArray(items)){
 				for(i = 0; i < items.length; i++){
 					request.onItem.call(scope, items[i], request);
 				}
@@ -445,8 +446,8 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 		//	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 dojo.some(this.getValues(item, attribute), function(possibleValue){
-			if(possibleValue !== null && !dojo.isObject(possibleValue) && regexp){
+		return array.some(this.getValues(item, attribute), function(possibleValue){
+			if(possibleValue !== null && !lang.isObject(possibleValue) && regexp){
 				if(possibleValue.toString().match(regexp)){
 					return true; // Boolean
 				}
@@ -457,7 +458,4 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 		});
 	}
 });
-
-return dojox.data.CssRuleStore;
-
 });
diff --git a/dojox/data/CsvStore.js b/dojox/data/CsvStore.js
index cc74d3c..a16f928 100644
--- a/dojox/data/CsvStore.js
+++ b/dojox/data/CsvStore.js
@@ -1,6 +1,7 @@
-define("dojox/data/CsvStore", ["dojo", "dojox", "dojo/data/util/filter", "dojo/data/util/simpleFetch"], function(dojo, dojox) {
+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) {
 
-dojo.declare("dojox.data.CsvStore", null, {
+var CsvStore = declare("dojox.data.CsvStore", null, {
 	// summary:
 	//		The CsvStore implements the dojo.data.api.Read API and reads
 	//		data from files in CSV (Comma Separated Values) format.
@@ -183,7 +184,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 		//		See dojo.data.api.Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
-			regexp = dojo.data.util.filter.patternToRegExp(value, false);
+			regexp = filterUtil.patternToRegExp(value, false);
 		}
 		return this._containsValue(item, attribute, value, regexp); //boolean.
 	},
@@ -313,7 +314,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 				for(key in requestArgs.query){
 					value = requestArgs.query[key];
 					if(typeof value === "string"){
-						regexpList[key] = dojo.data.util.filter.patternToRegExp(value, ignoreCase);
+						regexpList[key] = filterUtil.patternToRegExp(value, ignoreCase);
 					}
 				}
 
@@ -355,7 +356,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 							handleAs: "text",
 							preventCache: self.urlPreventCache
 						};
-					var getHandler = dojo.xhrGet(getArgs);
+					var getHandler = xhr.get(getArgs);
 					getHandler.addCallback(function(data){
 						try{
 							self._processData(data);
@@ -442,7 +443,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 		//			{ "Title":0, "Year":1, "Producer":2 }
 		// tags:
 		//		private
-		if(dojo.isString(csvFileContents)){
+		if(lang.isString(csvFileContents)){
 			var leadingWhiteSpaceCharacters = new RegExp("^\\s+",'g');
 			var trailingWhiteSpaceCharacters = new RegExp("\\s+$",'g');
 			var doubleQuotes = new RegExp('""','g');
@@ -611,7 +612,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 		// tags:
 		//		public
 		var item;
-		var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+		var scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
 		//Hasn't loaded yet, we have to trigger the load.
 		if(!this._loadFinished){
 			var self = this;
@@ -627,7 +628,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 							url: self.url,
 							handleAs: "text"
 						};
-					var getHandler = dojo.xhrGet(getArgs);
+					var getHandler = xhr.get(getArgs);
 					getHandler.addCallback(function(data){
 						try{
 							self._processData(data);
@@ -719,7 +720,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 	}
 });
 //Mix in the simple fetch implementation to this class.
-dojo.extend(dojox.data.CsvStore,dojo.data.util.simpleFetch);
+lang.extend(CsvStore, simpleFetch);
 
-return dojox.data.CsvStore;
+return CsvStore;
 });
diff --git a/dojox/data/FileStore.js b/dojox/data/FileStore.js
index cd860f8..566edee 100755
--- a/dojox/data/FileStore.js
+++ b/dojox/data/FileStore.js
@@ -1,6 +1,7 @@
-define("dojox/data/FileStore", ["dojo", "dojox"], function(dojo, dojox) {
+define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/window", "dojo/_base/json", "dojo/_base/xhr"], 
+  function(declare, lang, winUtil, jsonUtil, xhr) {
 
-dojo.declare("dojox.data.FileStore", null, {
+return declare("dojox.data.FileStore", null, {
 	constructor: function(/*Object*/args){
 		//	summary:
 		//		A simple store that provides a datastore interface to a filesystem.
@@ -32,10 +33,10 @@ dojo.declare("dojox.data.FileStore", null, {
 			this.url = args.url;
 		}
 		if(args && args.options){
-			if(dojo.isArray(args.options)){
+			if(lang.isArray(args.options)){
 				this.options = args.options;
 			}else{
-				if(dojo.isString(args.options)){
+				if(lang.isString(args.options)){
 					this.options = args.options.split(",");
 				}
 			}
@@ -170,12 +171,12 @@ dojo.declare("dojox.data.FileStore", null, {
 		//      See dojo.data.api.Read.loadItem()
 		var item = keywordArgs.item;
 		var self = this;
-		var scope = keywordArgs.scope || dojo.global;
+		var scope = keywordArgs.scope || winUtil.global;
 
 		var content = {};
 
 		if(this.options.length > 0){
-			content.options = dojo.toJson(this.options);
+			content.options = jsonUtil.toJson(this.options);
 		}
 
 		if(this.pathAsQueryParam){
@@ -189,7 +190,7 @@ dojo.declare("dojox.data.FileStore", null, {
 			failOk: this.failOk
 		};
 
-		var deferred = dojo.xhrGet(xhrData);
+		var deferred = xhr.get(xhrData);
 		deferred.addErrback(function(error){
 				if(keywordArgs.onError){
 					keywordArgs.onError.call(scope, error);
@@ -199,7 +200,7 @@ dojo.declare("dojox.data.FileStore", null, {
 		deferred.addCallback(function(data){
 			delete item.parentPath;
 			delete item._loaded;
-			dojo.mixin(item, data);
+			lang.mixin(item, data);
 			self._processItem(item);
 			if(keywordArgs.onItem){
 				keywordArgs.onItem.call(scope, item);
@@ -238,7 +239,7 @@ dojo.declare("dojox.data.FileStore", null, {
 		this._assertIsAttribute(attribute);
 		
 		var value = item[attribute];
-		if(typeof value !== "undefined" && !dojo.isArray(value)){
+		if(typeof value !== "undefined" && !lang.isArray(value)){
 			value = [value];
 		}else if(typeof value === "undefined"){
 			value = [];
@@ -271,20 +272,20 @@ dojo.declare("dojox.data.FileStore", null, {
 			request.store = this;
 		}
 		var self = this;
-		var scope = request.scope || dojo.global;
+		var scope = request.scope || winUtil.global;
 
 		//Generate what will be sent over.
 		var reqParams = {};
 		if(request.query){
-			reqParams.query = dojo.toJson(request.query);
+			reqParams.query = jsonUtil.toJson(request.query);
 		}
 
 		if(request.sort){
-			reqParams.sort = dojo.toJson(request.sort);
+			reqParams.sort = jsonUtil.toJson(request.sort);
 		}
 
 		if(request.queryOptions){
-			reqParams.queryOptions = dojo.toJson(request.queryOptions);
+			reqParams.queryOptions = jsonUtil.toJson(request.queryOptions);
 		}
 
 		if(typeof request.start == "number"){
@@ -295,7 +296,7 @@ dojo.declare("dojox.data.FileStore", null, {
 		}
 
 		if(this.options.length > 0){
-			reqParams.options = dojo.toJson(this.options);
+			reqParams.options = jsonUtil.toJson(this.options);
 		}
 
 		var getArgs = {
@@ -307,7 +308,7 @@ dojo.declare("dojox.data.FileStore", null, {
 		};
 
 
-		var deferred = dojo.xhrGet(getArgs);
+		var deferred = xhr.get(getArgs);
 
 		deferred.addCallback(function(data){self._processResult(data, request);});
 		deferred.addErrback(function(error){
@@ -322,12 +323,12 @@ dojo.declare("dojox.data.FileStore", null, {
 		//      See dojo.data.api.Read.loadItem()
 		var path = keywordArgs.identity;
 		var self = this;
-		var scope = keywordArgs.scope || dojo.global;
+		var scope = keywordArgs.scope || winUtil.global;
 
 		var content = {};
 
 		if(this.options.length > 0){
-			content.options = dojo.toJson(this.options);
+			content.options = jsonUtil.toJson(this.options);
 		}
 
 		if(this.pathAsQueryParam){
@@ -341,7 +342,7 @@ dojo.declare("dojox.data.FileStore", null, {
 			failOk: this.failOk
 		};
 
-		var deferred = dojo.xhrGet(xhrData);
+		var deferred = xhr.get(xhrData);
 		deferred.addErrback(function(error){
 				if(keywordArgs.onError){
 					keywordArgs.onError.call(scope, error);
@@ -357,7 +358,7 @@ dojo.declare("dojox.data.FileStore", null, {
 	},
 
 	_processResult: function(data, request){
-		 var scope = request.scope || dojo.global;
+		 var scope = request.scope || winUtil.global;
 		 try{
 			 //If the data contains a path separator, set ours
 			 if(data.pathSeparator){
@@ -407,12 +408,12 @@ dojo.declare("dojox.data.FileStore", null, {
 		if(!item){return null;}
 		item[this._storeRef] = this;
 		if(item.children && item.directory){
-			if(dojo.isArray(item.children)){
+			if(lang.isArray(item.children)){
 				var children = item.children;
 				var i;
 				for(i = 0; i < children.length; i++ ){
 					var name = children[i];
-					if(dojo.isObject(name)){
+					if(lang.isObject(name)){
 						children[i] = this._processItem(name);
 					}else{
 						children[i] = {name: name, _loaded: false, parentPath: item.path};
@@ -426,6 +427,4 @@ dojo.declare("dojox.data.FileStore", null, {
 		return item;
 	}
 });
-
-return dojox.data.FileStore;
 });
diff --git a/dojox/data/FlickrRestStore.js b/dojox/data/FlickrRestStore.js
index b139d55..325f44c 100644
--- a/dojox/data/FlickrRestStore.js
+++ b/dojox/data/FlickrRestStore.js
@@ -1,7 +1,10 @@
-define("dojox/data/FlickrRestStore", ["dojo", "dojox", "dojox/data/FlickrStore"], function(dojo, dojox) {
+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) {
 
-dojo.declare("dojox.data.FlickrRestStore",
-	dojox.data.FlickrStore, {
+/*===== var FlickrStore = dojox.data.FlickrStore; =====*/
+
+var FlickrRestStore = declare("dojox.data.FlickrRestStore",
+	FlickrStore, {
 	constructor: function(/*Object*/args){
 		// summary:
 		//	Initializer for the FlickrRestStore store.
@@ -24,7 +27,7 @@ dojo.declare("dojox.data.FlickrRestStore",
 		this._handlers = {};
 		this._prevRequestRanges = [];
 		this._maxPhotosPerUser = {};
-		this._id = dojox.data.FlickrRestStore.prototype._id++;
+		this._id = FlickrRestStore.prototype._id++;
 	},
 
 	// _id: Integer
@@ -86,7 +89,7 @@ dojo.declare("dojox.data.FlickrRestStore",
 		if(!request.query){
 			request.query = query = {};
 		} else {
-			dojo.mixin(query, request.query);
+			lang.mixin(query, request.query);
 		}
 
 		var primaryKey = [];
@@ -268,7 +271,7 @@ dojo.declare("dojox.data.FlickrRestStore",
 			callbackParamName: "jsoncallback"
 		};
 
-		var doHandle = dojo.hitch(this, function(processedData, data, handler){
+		var doHandle = lang.hitch(this, function(processedData, data, handler){
 			var onBegin = handler.request.onBegin;
 			handler.request.onBegin = null;
 			var maxPhotos;
@@ -313,9 +316,9 @@ dojo.declare("dojox.data.FlickrRestStore",
 		});
 
 		//Define a callback for the script that iterates through a list of
-		//handlers for this piece of data.  Multiple requests can come into
+		//handlers for this piece of data.	Multiple requests can come into
 		//the store for the same data.
-		var myHandler = dojo.hitch(this, function(data){
+		var myHandler = lang.hitch(this, function(data){
 			//The handler should not be called more than once, so disconnect it.
 			//if(handle !== null){ dojo.disconnect(handle); }
 			if(data.stat != "ok"){
@@ -341,7 +344,7 @@ dojo.declare("dojox.data.FlickrRestStore",
 				});
 
 				//Iterate through the array of handlers, calling each one.
-				dojo.forEach(handlers, function(i){
+				array.forEach(handlers, function(i){
 					doHandle(processedData, data, i);
 				});
 			}
@@ -361,20 +364,20 @@ dojo.declare("dojox.data.FlickrRestStore",
 			return;
 		}
 
-		var deferred = dojo.io.script.get(getArgs);
+		var deferred = scriptIO.get(getArgs);
 		deferred.addCallback(myHandler);
 
 		//We only set up the errback, because the callback isn't ever really used because we have
 		//to link to the jsonFlickrFeed function....
 		deferred.addErrback(function(error){
-			dojo.disconnect(handle);
+			connect.disconnect(handle);
 			errorHandler(error, request);
 		});
 	},
 
 	getAttributes: function(item){
 		//	summary:
-		//      See dojo.data.api.Read.getAttributes()
+		//		See dojo.data.api.Read.getAttributes()
 		return [
 			"title", "author", "imageUrl", "imageUrlSmall", "imageUrlMedium",
 			"imageUrlThumb", "imageUrlLarge", "imageUrlOriginal", "link", "dateTaken", "datePublished"
@@ -383,7 +386,7 @@ dojo.declare("dojox.data.FlickrRestStore",
 
 	getValues: function(item, attribute){
 		//	summary:
-		//      See dojo.data.api.Read.getValue()
+		//		See dojo.data.api.Read.getValue()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
 
@@ -426,9 +429,9 @@ dojo.declare("dojox.data.FlickrRestStore",
 		// If the data contains an 'item' object, it has not come from the REST
 		// services, so process it using the FlickrStore.
 		if(data.items){
-			return dojox.data.FlickrStore.prototype._processFlickrData.apply(this,arguments);
+			return FlickrStore.prototype._processFlickrData.apply(this,arguments);
 		}
-        var template = ["http://farm", null, ".static.flickr.com/", null, "/", null, "_", null];
+		var template = ["http://farm", null, ".static.flickr.com/", null, "/", null, "_", null];
 
 		var items = [];
 		var photos = (data.photoset ? data.photoset : data.photos);
@@ -439,18 +442,18 @@ dojo.declare("dojox.data.FlickrRestStore",
 			for(var i = 0; i < items.length; i++){
 				var item = items[i];
 				item[this._storeRef] = this;
-                template[1] = item.farm;
-                template[3] = item.server;
-                template[5] = item.id;
-                template[7] = item.secret;
-                
-                var base = template.join("");
+				template[1] = item.farm;
+				template[3] = item.server;
+				template[5] = item.id;
+				template[7] = item.secret;
+				
+				var base = template.join("");
 				item.media = {
-                    s: base + "_s.jpg",
-                    m: base + "_m.jpg",
-                    l: base + ".jpg",
-                    t: base + "_t.jpg",
-                    o: base + "_o.jpg"
+					s: base + "_s.jpg",
+					m: base + "_m.jpg",
+					l: base + ".jpg",
+					t: base + "_t.jpg",
+					o: base + "_o.jpg"
 				};
 				if(!item.owner && data.photoset){
 					item.owner = data.photoset.owner;
@@ -462,7 +465,7 @@ dojo.declare("dojox.data.FlickrRestStore",
 		if(!arr){
 			this._cache[cacheKey] = arr = [];
 		}
-		dojo.forEach(items, function(i, idx){
+		array.forEach(items, function(i, idx){
 			arr[idx+ start] = i;
 		});
 
@@ -472,12 +475,11 @@ dojo.declare("dojox.data.FlickrRestStore",
 	_checkPrevRanges: function(primaryKey, start, count){
 		var end = start + count;
 		var arr = this._prevRequestRanges[primaryKey];
-		return (!!arr) && dojo.some(arr, function(item){
+		return (!!arr) && array.some(arr, function(item){
 			return ((start >= item.start)&&(end <= item.end));
 		});
 	}
 });
-
-return dojox.data.FlickrRestStore;
+return FlickrRestStore;
 });
 
diff --git a/dojox/data/FlickrStore.js b/dojox/data/FlickrStore.js
index 7f804a1..104f112 100644
--- a/dojox/data/FlickrStore.js
+++ b/dojox/data/FlickrStore.js
@@ -1,6 +1,8 @@
-define("dojox/data/FlickrStore", ["dojo", "dojox", "dojo/data/util/simpleFetch", "dojo/io/script", "dojo/date/stamp", "dojo/AdapterRegistry"], function(dojo, dojox) {
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/data/util/simpleFetch", "dojo/io/script", 
+		"dojo/_base/connect", "dojo/date/stamp", "dojo/AdapterRegistry"], 
+  function(lang, declare, array, simpleFetch, scriptIO, connect, dateStamp, AdapterRegistry) {
 
-dojo.declare("dojox.data.FlickrStore", null, {
+var FlickrStore = declare("dojox.data.FlickrStore", null, {
 	constructor: function(/*Object*/args){
 		//	summary:
 		//		Initializer for the FlickrStore store.
@@ -123,8 +125,8 @@ dojo.declare("dojox.data.FlickrStore", null, {
 
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
-		var u = dojo.hitch(this, "_unescapeHtml");
-		var s = dojo.hitch(dojo.date.stamp, "fromISOString");
+		var u = lang.hitch(this, "_unescapeHtml");
+		var s = lang.hitch(dateStamp, "fromISOString");
 		switch(attribute){
 			case "title":
 				return [ u(item.title) ];
@@ -183,7 +185,7 @@ dojo.declare("dojox.data.FlickrStore", null, {
 			tagmode:"any"
 		};
 
-		dojo.forEach(
+		array.forEach(
 			[ "tags", "tagmode", "lang", "id", "ids" ],
 			function(i){
 				if(rq[i]){ content[i] = rq[i]; }
@@ -203,21 +205,21 @@ dojo.declare("dojox.data.FlickrStore", null, {
 			preventCache: this.urlPreventCache,
 			content: content
 		};
-		var myHandler = dojo.hitch(this, function(data){
+		var myHandler = lang.hitch(this, function(data){
 			if(!!handle){
-				dojo.disconnect(handle);
+				connect.disconnect(handle);
 			}
 
 			//Process the items...
 			fetchHandler(this._processFlickrData(data), request);
 		});
-		handle = dojo.connect("jsonFlickrFeed", myHandler);
-		var deferred = dojo.io.script.get(getArgs);
+		handle = connect.connect("jsonFlickrFeed", myHandler);
+		var deferred = scriptIO.get(getArgs);
 		
 		//We only set up the errback, because the callback isn't ever really used because we have
 		//to link to the jsonFlickrFeed function....
 		deferred.addErrback(function(error){
-			dojo.disconnect(handle);
+			connect.disconnect(handle);
 			errorHandler(error, request);
 		});
 	},
@@ -256,11 +258,11 @@ dojo.declare("dojox.data.FlickrStore", null, {
 	}
 });
 
-dojo.extend(dojox.data.FlickrStore, dojo.data.util.simpleFetch);
+lang.extend(FlickrStore, simpleFetch);
 
 var feedsUrl = "http://api.flickr.com/services/feeds/";
 
-var reg = dojox.data.FlickrStore.urlRegistry = new dojo.AdapterRegistry(true);
+var reg = FlickrStore.urlRegistry = new AdapterRegistry(true);
 
 reg.register("group pool",
 	function(request){ return !!request.query["groupid"]; },
@@ -278,6 +280,5 @@ if(!jsonFlickrFeed){
 	var jsonFlickrFeed = function(data){};
 }
 
-return dojox.data.FlickrStore;
-
+return FlickrStore;
 });
diff --git a/dojox/data/GoogleFeedStore.js b/dojox/data/GoogleFeedStore.js
index 077df99..b85f7f4 100644
--- a/dojox/data/GoogleFeedStore.js
+++ b/dojox/data/GoogleFeedStore.js
@@ -1,8 +1,12 @@
-define("dojox/data/GoogleFeedStore", ["dojo", "dojox", "dojox/data/GoogleSearchStore"], function(dojo, dojox) {
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojox/data/GoogleSearchStore"], 
+  function(dojo, lang, declare, GoogleSearchStore) {
 
 dojo.experimental("dojox.data.GoogleFeedStore");
 
-dojo.declare("dojox.data.GoogleFeedStore", dojox.data.GoogleSearchStore,{
+/*===== 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"
@@ -31,7 +35,7 @@ dojo.declare("dojox.data.GoogleFeedStore", dojox.data.GoogleSearchStore,{
 		//		Non-API method for retrieving values regarding the Atom feed,
 		//		rather than the Atom entries.
 		var values = this.getFeedValues(attribute, defaultValue);
-		if(dojo.isArray(values)){
+		if(lang.isArray(values)){
 			return values[0];
 		}
 		return values;
@@ -73,5 +77,4 @@ dojo.declare("dojox.data.GoogleFeedStore", dojox.data.GoogleSearchStore,{
 	}
 });
 
-return dojox.data.GoogleFeedStore;
 });
diff --git a/dojox/data/GoogleSearchStore.js b/dojox/data/GoogleSearchStore.js
index 7e36896..8fb3788 100644
--- a/dojox/data/GoogleSearchStore.js
+++ b/dojox/data/GoogleSearchStore.js
@@ -1,16 +1,10 @@
-define("dojox/data/GoogleSearchStore", ["dojo", "dojox", "dojo/io/script"], function(dojo, dojox) {
-
-dojo.provide("dojox.data.GoogleWebSearchStore");
-dojo.provide("dojox.data.GoogleBlogSearchStore");
-dojo.provide("dojox.data.GoogleLocalSearchStore");
-dojo.provide("dojox.data.GoogleVideoSearchStore");
-dojo.provide("dojox.data.GoogleNewsSearchStore");
-dojo.provide("dojox.data.GoogleBookSearchStore");
-dojo.provide("dojox.data.GoogleImageSearchStore");
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window", "dojo/_base/query", 
+		"dojo/dom-construct","dojo/io/script"], 
+  function(dojo, lang, declare, winUtil, domQuery, domConstruct, scriptIO) {
 
 dojo.experimental("dojox.data.GoogleSearchStore");
 
-dojo.declare("dojox.data.GoogleSearchStore",null,{
+var SearchStore = declare("dojox.data.GoogleSearchStore",null,{
 	//	summary:
 	//		A data store for retrieving search results from Google.
 	//		This data store acts as a base class for Google searches,
@@ -199,7 +193,7 @@ dojo.declare("dojox.data.GoogleSearchStore",null,{
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
 		var val = item[attribute];
-		if(dojo.isArray(val)) {
+		if(lang.isArray(val)) {
 			return val;
 		}else if(val !== undefined){
 			return [val];
@@ -237,7 +231,7 @@ dojo.declare("dojox.data.GoogleSearchStore",null,{
 		//		A function to call on error
 		request = request || {};
 
-		var scope = request.scope || dojo.global;
+		var scope = request.scope || winUtil.global;
 
 		if(!request.query){
 			if(request.onError){
@@ -305,7 +299,7 @@ dojo.declare("dojox.data.GoogleSearchStore",null,{
 			numRequests ++;
 			getArgs.content.context = getArgs.content.start = req.start;
 
-			var deferred = dojo.io.script.get(getArgs);
+			var deferred = scriptIO.get(getArgs);
 			scriptIds.push(deferred.ioArgs.id);
 
 			//We only set up the errback, because the callback isn't ever really used because we have
@@ -321,7 +315,7 @@ dojo.declare("dojox.data.GoogleSearchStore",null,{
 		var myHandler = function(start, data){
 			if (scriptIds.length > 0) {
 				// Delete the script node that was created.
-				dojo.query("#" + scriptIds.splice(0,1)).forEach(dojo.destroy);
+				domQuery("#" + scriptIds.splice(0,1)).forEach(domConstruct.destroy);
 			}
 			if(finished){return;}
 
@@ -375,7 +369,7 @@ dojo.declare("dojox.data.GoogleSearchStore",null,{
 					//Process the items...
 					finished = true;
 					//Clean up the function, it should never be called again
-					dojo.global[callbackFn] = null;
+					winUtil.global[callbackFn] = null;
 					if(request.onItem){
 						request.onComplete.call(scope, null, request);
 					}else{
@@ -391,13 +385,13 @@ dojo.declare("dojox.data.GoogleSearchStore",null,{
 		var lastCallback = firstRequest.start - 1;
 
 		// Attach a callback function to the global namespace, where Google can call it.
-		dojo.global[callbackFn] = function(start, data, responseCode, errorMsg){
+		winUtil.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);
 					}
-					dojo.global[callbackFn] = function(){};//an error occurred, do not return anything else.
+					winUtil.global[callbackFn] = function(){};//an error occurred, do not return anything else.
 					return;
 				}
 	
@@ -441,7 +435,7 @@ dojo.declare("dojox.data.GoogleSearchStore",null,{
 		item[this._storeRef] = this;
 		// Copy aggregated attributes from query results to the item.
 		for(var attribute in this._aggregatedAttributes) {
-			item[attribute] = dojo.getObject(this._aggregatedAttributes[attribute], false, data);
+			item[attribute] = lang.getObject(this._aggregatedAttributes[attribute], false, data);
 		}
 	},
 
@@ -464,7 +458,7 @@ dojo.declare("dojox.data.GoogleSearchStore",null,{
 	}
 });
 
-dojo.declare("dojox.data.GoogleWebSearchStore", dojox.data.GoogleSearchStore,{
+var WebSearchStore = declare("dojox.data.GoogleWebSearchStore", SearchStore,{
 	//	Summary:
 	//		A data store for retrieving search results from Google.
 	//		The following attributes are supported on each item:
@@ -481,7 +475,7 @@ dojo.declare("dojox.data.GoogleWebSearchStore", dojox.data.GoogleSearchStore,{
 	//		The query accepts one parameter: text - The string to search for
 });
 
-dojo.declare("dojox.data.GoogleBlogSearchStore", dojox.data.GoogleSearchStore,{
+var BlogSearchStore = declare("dojox.data.GoogleBlogSearchStore", SearchStore,{
 	//	Summary:
 	//		A data store for retrieving search results from Google.
 	//		The following attributes are supported on each item:
@@ -504,7 +498,7 @@ dojo.declare("dojox.data.GoogleBlogSearchStore", dojox.data.GoogleSearchStore,{
 });
 
 
-dojo.declare("dojox.data.GoogleLocalSearchStore", dojox.data.GoogleSearchStore,{
+var LocalSearchStore = declare("dojox.data.GoogleLocalSearchStore", SearchStore,{
 	//	summary:
 	//		A data store for retrieving search results from Google.
 	//		The following attributes are supported on each item:
@@ -551,7 +545,7 @@ dojo.declare("dojox.data.GoogleLocalSearchStore", dojox.data.GoogleSearchStore,{
 	}
 });
 
-dojo.declare("dojox.data.GoogleVideoSearchStore", dojox.data.GoogleSearchStore,{
+var VideoSearchStore = declare("dojox.data.GoogleVideoSearchStore", SearchStore,{
 	//	summary:
 	//		A data store for retrieving search results from Google.
 	//		The following attributes are supported on each item:
@@ -575,7 +569,7 @@ dojo.declare("dojox.data.GoogleVideoSearchStore", dojox.data.GoogleSearchStore,{
 	_aggregatedAttributes: { }
 });
 
-dojo.declare("dojox.data.GoogleNewsSearchStore", dojox.data.GoogleSearchStore,{
+var NewsSearchStore = declare("dojox.data.GoogleNewsSearchStore", SearchStore,{
 	//	summary:
 	//		A data store for retrieving search results from Google.
 	//		The following attributes are supported on each item:
@@ -601,7 +595,7 @@ dojo.declare("dojox.data.GoogleNewsSearchStore", dojox.data.GoogleSearchStore,{
 	_aggregatedAttributes: { }
 });
 
-dojo.declare("dojox.data.GoogleBookSearchStore", dojox.data.GoogleSearchStore,{
+var BookSearchStore = declare("dojox.data.GoogleBookSearchStore", SearchStore,{
 	// 	summary:
 	//		A data store for retrieving search results from Google.
 	//		The following attributes are supported on each item:
@@ -622,7 +616,7 @@ dojo.declare("dojox.data.GoogleBookSearchStore", dojox.data.GoogleSearchStore,{
 	_aggregatedAttributes: { }
 });
 
-dojo.declare("dojox.data.GoogleImageSearchStore", dojox.data.GoogleSearchStore,{
+var ImageSearchStore = declare("dojox.data.GoogleImageSearchStore", SearchStore,{
 	//	summary:
 	//		A data store for retrieving search results from Google.
 	//		The following attributes are supported on each item:
@@ -649,5 +643,14 @@ dojo.declare("dojox.data.GoogleImageSearchStore", dojox.data.GoogleSearchStore,{
 	_aggregatedAttributes: { }
 });
 
-return dojox.data.GoogleSearchStore;
+return {
+	Search: SearchStore,
+	ImageSearch: ImageSearchStore,
+	BookSearch: BookSearchStore,
+	NewsSearch: NewsSearchStore,
+	VideoSearch: VideoSearchStore,
+	LocalSearch: LocalSearchStore,
+	BlogSearch: BlogSearchStore,
+	WebSearch: WebSearchStore
+	}
 });
diff --git a/dojox/data/HtmlStore.js b/dojox/data/HtmlStore.js
index 67010a2..c769aad 100644
--- a/dojox/data/HtmlStore.js
+++ b/dojox/data/HtmlStore.js
@@ -1,6 +1,8 @@
-define("dojox/data/HtmlStore", ["dojo", "dojox", "dojo/data/util/simpleFetch", "dojo/data/util/filter", "dojox/xml/parser"], function(dojo, dojox) {
+define(["dojo/_base/declare", "dojo/_base/array", "dojo/_base/lang", "dojo/dom", "dojo/_base/xhr", "dojo/_base/window",
+		"dojo/data/util/simpleFetch", "dojo/data/util/filter", "dojox/xml/parser"], 
+  function(declare, array, lang, dom, xhr, winUtil, simpleFetch, filter, xmlParser) {
 
-dojo.declare("dojox.data.HtmlStore", null, {
+var HtmlStore = declare("dojox.data.HtmlStore", null, {
 	constructor: function(/*Object*/args){
 		//	summary:
 		//		Initializer for the HTML table store.
@@ -136,9 +138,9 @@ dojo.declare("dojox.data.HtmlStore", null, {
 		//      For list items, returns single implicit heading, ["name"]
 		this._headings = [];
 		if(this._rootNode.tHead){
-			dojo.forEach(this._rootNode.tHead.rows[0].cells, dojo.hitch(this, function(th){
-				var text = dojox.xml.parser.textContent(th);
-				this._headings.push(this.trimWhitespace?dojo.trim(text):text);
+			array.forEach(this._rootNode.tHead.rows[0].cells, lang.hitch(this, function(th){
+				var text = xmlParser.textContent(th);
+				this._headings.push(this.trimWhitespace?lang.trim(text):text);
 			}));
 		}else{
 			this._headings = ["name"];
@@ -186,7 +188,7 @@ dojo.declare("dojox.data.HtmlStore", null, {
 			throw new Error("dojo.data.HtmlStore: a function was passed an attribute argument that was not an attribute name string");
 			return -1;
 		}
-		return dojo.indexOf(this._headings, attribute); //int
+		return array.indexOf(this._headings, attribute); //int
 	},
 
 /***************************************
@@ -212,11 +214,11 @@ dojo.declare("dojox.data.HtmlStore", null, {
 		if(index>-1){
 			var text;
 			if(item.cells){
-				text = dojox.xml.parser.textContent(item.cells[index]);
+				text = xmlParser.textContent(item.cells[index]);
 			}else{//return Value for lists
-				text = dojox.xml.parser.textContent(item);
+				text = xmlParser.textContent(item);
 			}
-			return [this.trimWhitespace?dojo.trim(text):text];
+			return [this.trimWhitespace?lang.trim(text):text];
 		}
 		return []; //Array
 	},
@@ -247,7 +249,7 @@ dojo.declare("dojox.data.HtmlStore", null, {
 		//		See dojo.data.api.Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
-			regexp = dojo.data.util.filter.patternToRegExp(value, false);
+			regexp = filter.patternToRegExp(value, false);
 		}
 		return this._containsValue(item, attribute, value, regexp); //boolean.
 	},
@@ -290,7 +292,7 @@ dojo.declare("dojox.data.HtmlStore", null, {
 	isItem: function(/* anything */ something){
 		//	summary:
 		//		See dojo.data.api.Read.isItem()
-		return something && dojo.isDescendant(something, this._rootNode);
+		return something && dom.isDescendant(something, this._rootNode);
 	},
 
 	isItemLoaded: function(/* anything */ something){
@@ -328,7 +330,7 @@ dojo.declare("dojox.data.HtmlStore", null, {
 			this._finishFetchItems(request, fetchHandler, errorHandler);
 		}else{
 			if(!this.url){
-				this._rootNode = dojo.byId(this.dataId);
+				this._rootNode = dom.byId(this.dataId);
 				this._indexItems();
 				this._finishFetchItems(request, fetchHandler, errorHandler);
 			}else{
@@ -338,7 +340,7 @@ dojo.declare("dojox.data.HtmlStore", null, {
 						preventCache: this.urlPreventCache
 					};
 				var self = this;
-				var getHandler = dojo.xhrGet(getArgs);
+				var getHandler = xhr.get(getArgs);
 				getHandler.addCallback(function(data){
 					var findNode = function(node, id){
 						if(node.id == id){
@@ -385,7 +387,7 @@ dojo.declare("dojox.data.HtmlStore", null, {
 			for(key in request.query){
 				value = request.query[key]+'';
 				if(typeof value === "string"){
-					regexpList[key] = dojo.data.util.filter.patternToRegExp(value, ignoreCase);
+					regexpList[key] = filter.patternToRegExp(value, ignoreCase);
 				}
 			}
 
@@ -482,19 +484,19 @@ dojo.declare("dojox.data.HtmlStore", null, {
 		var scope = null;
 		if(!this._rootNode){
 			if(!this.url){
-				this._rootNode = dojo.byId(this.dataId);
+				this._rootNode = dom.byId(this.dataId);
 				this._indexItems();
 				if(self._rootNode.rows){ //Table
 					item = this._rootNode.rows[identity + 1];
 				}else{ //Lists
 					for(var i = 0; i < self._rootNode.childNodes.length; i++){
-						if(self._rootNode.childNodes[i].nodeType === 1 && identity === dojox.xml.parser.textContent(self._rootNode.childNodes[i])){
+						if(self._rootNode.childNodes[i].nodeType === 1 && identity === xmlParser.textContent(self._rootNode.childNodes[i])){
 							item = self._rootNode.childNodes[i];
 						}
 					}
 				}
 				if(keywordArgs.onItem){
-					scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+					scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
 					keywordArgs.onItem.call(scope, item);
 				}
 
@@ -503,7 +505,7 @@ dojo.declare("dojox.data.HtmlStore", null, {
 						url: this.url,
 						handleAs: "text"
 					};
-				var getHandler = dojo.xhrGet(getArgs);
+				var getHandler = xhr.get(getArgs);
 				getHandler.addCallback(function(data){
 					var findNode = function(node, id){
 						if(node.id == id){
@@ -527,20 +529,20 @@ dojo.declare("dojox.data.HtmlStore", null, {
 						item = self._rootNode.rows[identity-1];
 					}else{ //List
 						for(var i = 0; i < self._rootNode.childNodes.length; i++){
-							if(self._rootNode.childNodes[i].nodeType === 1 && identity === dojox.xml.parser.textContent(self._rootNode.childNodes[i])){
+							if(self._rootNode.childNodes[i].nodeType === 1 && identity === xmlParser.textContent(self._rootNode.childNodes[i])){
 									item = self._rootNode.childNodes[i];
 									break;
 							}
 						}
 					}
 					if(keywordArgs.onItem){
-						scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+						scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
 						keywordArgs.onItem.call(scope, item);
 					}
 				});
 				getHandler.addErrback(function(error){
 					if(keywordArgs.onError){
-						scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+						scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
 						keywordArgs.onError.call(scope, error);
 
 					}
@@ -550,13 +552,13 @@ dojo.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:dojo.global;
+					scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
 					keywordArgs.onItem.call(scope, item);
 				}
 			}
 		}
 	}
 });
-dojo.extend(dojox.data.HtmlStore,dojo.data.util.simpleFetch);
-return dojox.data.HtmlStore;
+lang.extend(HtmlStore, simpleFetch);
+return HtmlStore;
 });
diff --git a/dojox/data/HtmlTableStore.js b/dojox/data/HtmlTableStore.js
index 0f3a9af..96d3266 100644
--- a/dojox/data/HtmlTableStore.js
+++ b/dojox/data/HtmlTableStore.js
@@ -1,8 +1,11 @@
-define("dojox/data/HtmlTableStore", ["dojo", "dojox", "dojo/data/util/simpleFetch", "dojo/data/util/filter", "dojox/xml/parser"], function(dojo, dojox) {
+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/data/util/filter", "dojox/xml/parser"], 
+  function(kernel, declare, lang, dom, array, xhr, has, winUtil, simpleFetch, filter, xmlParser) {
 
-dojo.declare("dojox.data.HtmlTableStore", null, {
+var HtmlTableStore = declare("dojox.data.HtmlTableStore", null, {
 	constructor: function(/*Object*/args){
-		dojo.deprecated("dojox.data.HtmlTableStore", "Please use dojox.data.HtmlStore");
+		kernel.deprecated("dojox.data.HtmlTableStore", "Please use dojox.data.HtmlStore");
 		//	summary:
 		//		Initializer for the HTML table store.
 		//	description:
@@ -44,10 +47,10 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 			this.tableId = args.tableId;
 		}else{
 			if(args.tableId){
-				this._rootNode = dojo.byId(args.tableId);
+				this._rootNode = dom.byId(args.tableId);
 				this.tableId = this._rootNode.id;
 			}else{
-				this._rootNode = dojo.byId(this.tableId);
+				this._rootNode = dom.byId(this.tableId);
 			}
 			this._getHeadings();
 			for(var i=0; i<this._rootNode.rows.length; i++){
@@ -69,8 +72,8 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 		//		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 = [];
-		dojo.forEach(this._rootNode.tHead.rows[0].cells, dojo.hitch(this, function(th){
-			this._headings.push(dojox.xml.parser.textContent(th));
+		array.forEach(this._rootNode.tHead.rows[0].cells, lang.hitch(this, function(th){
+			this._headings.push(xmlParser.textContent(th));
 		}));
 	},
 	
@@ -106,7 +109,7 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 			throw new Error("dojo.data.HtmlTableStore: a function was passed an attribute argument that was not an attribute name string");
 			return -1;
 		}
-		return dojo.indexOf(this._headings, attribute); //int
+		return array.indexOf(this._headings, attribute); //int
 	},
 
 /***************************************
@@ -131,7 +134,7 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 		var index = this._assertIsAttribute(attribute);
 
 		if(index>-1){
-			return [dojox.xml.parser.textContent(item.cells[index])] ;
+			return [xmlParser.textContent(item.cells[index])] ;
 		}
 		return []; //Array
 	},
@@ -162,7 +165,7 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 		//		See dojo.data.api.Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
-			regexp = dojo.data.util.filter.patternToRegExp(value, false);
+			regexp = filter.patternToRegExp(value, false);
 		}
 		return this._containsValue(item, attribute, value, regexp); //boolean.
 	},
@@ -246,7 +249,7 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 			this._finishFetchItems(request, fetchHandler, errorHandler);
 		}else{
 			if(!this.url){
-				this._rootNode = dojo.byId(this.tableId);
+				this._rootNode = dom.byId(this.tableId);
 				this._getHeadings();
 				for(var i=0; i<this._rootNode.rows.length; i++){
 					this._rootNode.rows[i].store = this;
@@ -257,7 +260,7 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 						handleAs: "text"
 					};
 				var self = this;
-				var getHandler = dojo.xhrGet(getArgs);
+				var getHandler = xhr.get(getArgs);
 				getHandler.addCallback(function(data){
 					var findNode = function(node, id){
 						if(node.id == id){
@@ -307,7 +310,7 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 			for(key in request.query){
 				value = request.query[key]+'';
 				if(typeof value === "string"){
-					regexpList[key] = dojo.data.util.filter.patternToRegExp(value, ignoreCase);
+					regexpList[key] = filter.patternToRegExp(value, ignoreCase);
 				}
 			}
 
@@ -375,10 +378,10 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 		//Opera doesn't support the sectionRowIndex,
 		//So, have to call the indexOf to locate it.
 		//Blah.
-		if(!dojo.isOpera){
+		if(!has("opera")){
 			return item.sectionRowIndex; // int
 		}else{
-			return (dojo.indexOf(this._rootNode.rows, item) - 1) // int
+			return (array.indexOf(this._rootNode.rows, item) - 1) // int
 		}
 	},
 
@@ -399,14 +402,14 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 
 		if(!this._rootNode){
 			if(!this.url){
-				this._rootNode = dojo.byId(this.tableId);
+				this._rootNode = dom.byId(this.tableId);
 				this._getHeadings();
 				for(var i=0; i<this._rootNode.rows.length; i++){
 					this._rootNode.rows[i].store = this;
 				}
 				item = this._rootNode.rows[identity+1];
 				if(keywordArgs.onItem){
-					scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+					scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
 					keywordArgs.onItem.call(scope, item);
 				}
 
@@ -415,7 +418,7 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 						url: this.url,
 						handleAs: "text"
 					};
-				var getHandler = dojo.xhrGet(getArgs);
+				var getHandler = xhr.get(getArgs);
 				getHandler.addCallback(function(data){
 					var findNode = function(node, id){
 						if(node.id == id){
@@ -440,13 +443,13 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 					}
 					item = self._rootNode.rows[identity+1];
 					if(keywordArgs.onItem){
-						scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+						scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
 						keywordArgs.onItem.call(scope, item);
 					}
 				});
 				getHandler.addErrback(function(error){
 					if(keywordArgs.onError){
-						scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+						scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
 						keywordArgs.onError.call(scope, error);
 
 					}
@@ -456,14 +459,14 @@ dojo.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:dojo.global;
+					scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
 					keywordArgs.onItem.call(scope, item);
 				}
 			}
 		}
 	}
 });
-dojo.extend(dojox.data.HtmlTableStore,dojo.data.util.simpleFetch);
+lang.extend(HtmlTableStore,simpleFetch);
 
-return dojox.data.HtmlTableStore;
+return HtmlTableStore;
 });
diff --git a/dojox/data/ItemExplorer.js b/dojox/data/ItemExplorer.js
index 667f160..6b62fc4 100644
--- a/dojox/data/ItemExplorer.js
+++ b/dojox/data/ItemExplorer.js
@@ -5,7 +5,7 @@ dojo.require("dijit.Menu");
 dojo.require("dijit.form.ValidationTextBox");
 dojo.require("dijit.form.Textarea");
 dojo.require("dijit.form.Button");
-dojo.require("dijit.form.CheckBox");
+dojo.require("dijit.form.RadioButton");
 dojo.require("dijit.form.FilteringSelect");
 
 (function(){
@@ -24,7 +24,7 @@ dojo.declare("dojox.data.ItemExplorer", dijit.Tree, {
 		dojo.mixin(this, options);
 		var self = this;
 		var initialRootValue = {};
-		var root = this.rootModelNode = {value:initialRootValue,id:"root"};
+		var root = (this.rootModelNode = {value:initialRootValue,id:"root"});
 
 		this._modelNodeIdMap = {};
 		this._modelNodePropMap = {};
diff --git a/dojox/data/JsonQueryRestStore.js b/dojox/data/JsonQueryRestStore.js
index aedd94a..0f0e374 100644
--- a/dojox/data/JsonQueryRestStore.js
+++ b/dojox/data/JsonQueryRestStore.js
@@ -1,6 +1,4 @@
-define("dojox/data/JsonQueryRestStore", ["dojo", "dojox", "dojox/data/JsonRestStore", "dojox/data/util/JsonQuery"], function(dojo, dojox) {
-
-dojo.requireIf(!!dojox.data.ClientFilter,"dojox.json.query"); // this is so we can perform queries locally
+define(["dojo", "dojox", "dojox/data/JsonRestStore", "dojox/data/util/JsonQuery", "dojox/data/ClientFilter", "dojox/json/query"], function(dojo, dojox) {
 
 // this is an extension of JsonRestStore to convert object attribute queries to
 // JSONQuery/JSONPath syntax to be sent to the server. This also enables
diff --git a/dojox/data/JsonRestStore.js b/dojox/data/JsonRestStore.js
index 9e678eb..cd82c9b 100644
--- a/dojox/data/JsonRestStore.js
+++ b/dojox/data/JsonRestStore.js
@@ -1,7 +1,12 @@
-define("dojox/data/JsonRestStore", ["dojo", "dojox", "dojox/rpc/JsonRest", "dojox/data/ServiceStore"], function(dojo, dojox) {
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojox/rpc/Rest", 
+		"dojox/rpc/JsonRest", "dojox/json/schema", "dojox/data/ServiceStore"], 
+  function(lang, declare, connect, rpcRest, rpcJsonRest, jsonSchema, ServiceStore) {
 
-dojo.declare("dojox.data.JsonRestStore",
-	dojox.data.ServiceStore,
+/*=====
+var ServiceStore = dojox.data.ServiceStore;
+=====*/
+
+var JsonRestStore = declare("dojox.data.JsonRestStore", ServiceStore,
 	{
 		constructor: function(options){
 			//summary:
@@ -96,7 +101,7 @@ dojo.declare("dojox.data.JsonRestStore",
 			//		The object would automatically be requested from the server (with an object id of "obj2").
 			//
 
-			dojo.connect(dojox.rpc.Rest._index,"onUpdate",this,function(obj,attrName,oldValue,newValue){
+			connect.connect(rpcRest._index,"onUpdate",this,function(obj,attrName,oldValue,newValue){
 				var prefix = this.service.servicePath;
 				if(!obj.__id){
 					console.log("no id on updated object ", obj);
@@ -109,26 +114,26 @@ dojo.declare("dojox.data.JsonRestStore",
 			if(typeof options.target == 'string'){
 				options.target = options.target.match(/\/$/) || this.allowNoTrailingSlash ? options.target : (options.target + '/');
 				if(!this.service){
-					this.service = dojox.rpc.JsonRest.services[options.target] ||
-							dojox.rpc.Rest(options.target, true);
+					this.service = rpcJsonRest.services[options.target] ||
+							rpcRest(options.target, true);
 					// create a default Rest service
 				}
 			}
 
-			dojox.rpc.JsonRest.registerService(this.service, options.target, this.schema);
+			rpcJsonRest.registerService(this.service, options.target, this.schema);
 			this.schema = this.service._schema = this.schema || this.service._schema || {};
 			// wrap the service with so it goes through JsonRest manager
 			this.service._store = this;
 			this.service.idAsRef = this.idAsRef;
 			this.schema._idAttr = this.idAttribute;
-			var constructor = dojox.rpc.JsonRest.getConstructor(this.service);
+			var constructor = rpcJsonRest.getConstructor(this.service);
 			var self = this;
 			this._constructor = function(data){
 				constructor.call(this, data);
 				self.onNew(this);
 			}
 			this._constructor.prototype = constructor.prototype;
-			this._index = dojox.rpc.Rest._index;
+			this._index = rpcRest._index;
 		},
 		
 		// summary:
@@ -174,11 +179,11 @@ dojo.declare("dojox.data.JsonRestStore",
 			//	If the desire is to delete only one reference, unsetAttribute or
 			//	setValue is the way to go.
 			var checked = [];
-			var store = dojox.data._getStoreForItem(item) || this;
+			var store = dataExtCfg._getStoreForItem(item) || this;
 			if(this.referenceIntegrity){
 				// cleanup all references
-				dojox.rpc.JsonRest._saveNotNeeded = true;
-				var index = dojox.rpc.Rest._index;
+				rpcJsonRest._saveNotNeeded = true;
+				var index = rpcRest._index;
 				var fixReferences = function(parent){
 					var toSplice;
 					// keep track of the checked ones
@@ -195,7 +200,7 @@ dojo.declare("dojox.data.JsonRestStore",
 										(toSplice = toSplice || []).push(i);
 									}else{
 										// property, just delete it.
-										(dojox.data._getStoreForItem(parent) || store).unsetAttribute(parent, i);
+										(dataExtCfg._getStoreForItem(parent) || store).unsetAttribute(parent, i);
 									}
 								}
 							}else{
@@ -206,7 +211,7 @@ dojo.declare("dojox.data.JsonRestStore",
 									}
 									if(typeof value.__checked == 'object' && parent != index){
 										// if it is a modified array, we will replace it
-										(dojox.data._getStoreForItem(parent) || store).setValue(parent, i, value.__checked);
+										(dataExtCfg._getStoreForItem(parent) || store).setValue(parent, i, value.__checked);
 									}
 								}
 							}
@@ -225,14 +230,14 @@ dojo.declare("dojox.data.JsonRestStore",
 				};
 				// start with the index
 				fixReferences(index);
-				dojox.rpc.JsonRest._saveNotNeeded = false;
+				rpcJsonRest._saveNotNeeded = false;
 				var i = 0;
 				while(checked[i]){
 					// remove the checked marker
 					delete checked[i++].__checked;
 				}
 			}
-			dojox.rpc.JsonRest.deleteObject(item);
+			rpcJsonRest.deleteObject(item);
 
 			store.onDelete(item);
 		},
@@ -242,7 +247,26 @@ dojo.declare("dojox.data.JsonRestStore",
 			//		contains a reference to the item itself as well as a
 			//		cloned and trimmed version of old item for use with
 			//		revert.
-			dojox.rpc.JsonRest.changing(item,_deleting);
+			rpcJsonRest.changing(item,_deleting);
+		},
+		cancelChanging : function(object){
+			//	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:
+			//		The item to cancel changes on
+			if(!object.__id){
+				return;
+			}
+			dirtyObjects = dirty=rpcJsonRest.getDirtyObjects();
+			for(var i=0; i<dirtyObjects.length; i++){
+				var dirty = dirtyObjects[i];
+				if(object==dirty.object){
+					dirtyObjects.splice(i, 1);
+					return;
+				}
+			}
+	
 		},
 
 		setValue: function(item, attribute, value){
@@ -250,10 +274,10 @@ dojo.declare("dojox.data.JsonRestStore",
 			//		sets 'attribute' on 'item' to 'value'
 
 			var old = item[attribute];
-			var store = item.__id ? dojox.data._getStoreForItem(item) : this;
-			if(dojox.json.schema && store.schema && store.schema.properties){
+			var store = item.__id ? dataExtCfg._getStoreForItem(item) : this;
+			if(jsonSchema && store.schema && store.schema.properties){
 				// if we have a schema and schema validator available we will validate the property change
-				dojox.json.schema.mustBeValid(dojox.json.schema.checkPropertyChange(value,store.schema.properties[attribute]));
+				jsonSchema.mustBeValid(jsonSchema.checkPropertyChange(value,store.schema.properties[attribute]));
 			}
 			if(attribute == store.idAttribute){
 				throw new Error("Can not change the identity attribute for an item");
@@ -271,7 +295,7 @@ dojo.declare("dojox.data.JsonRestStore",
 			//	must be an array.
 
 
-			if(!dojo.isArray(values)){
+			if(!lang.isArray(values)){
 				throw new Error("setValues expects to be passed an Array object as its value");
 			}
 			this.setValue(item,attribute,values);
@@ -320,10 +344,10 @@ dojo.declare("dojox.data.JsonRestStore",
 				(kwArgs = kwArgs || {}).service = this.service;
 			}
 			if("syncMode" in kwArgs ? kwArgs.syncMode : this.syncMode){
-				dojox.rpc._sync = true;
+				rpcConfig._sync = true;
 			}
 
-			var actions = dojox.rpc.JsonRest.commit(kwArgs);
+			var actions = rpcJsonRest.commit(kwArgs);
 			this.serverVersion = this._updates && this._updates.length;
 			return actions;
 		},
@@ -335,13 +359,13 @@ dojo.declare("dojox.data.JsonRestStore",
 			//	kwArgs.global:
 			//		This will cause the revert to undo all the changes for all
 			// 		JsonRestStores in a single operation.
-			dojox.rpc.JsonRest.revert(kwArgs && kwArgs.global && this.service);
+			rpcJsonRest.revert(kwArgs && kwArgs.global && this.service);
 		},
 
 		isDirty: function(item){
 			// summary
 			//		returns true if the item is marked as dirty.
-			return dojox.rpc.JsonRest.isDirty(item);
+			return rpcJsonRest.isDirty(item, this);
 		},
 		isItem: function(item, anyStore){
 			//	summary:
@@ -353,11 +377,11 @@ dojo.declare("dojox.data.JsonRestStore",
 			//	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 == dojox.rpc.JsonRest.getServiceAndId(item.__id).service);
+			return item && item.__id && (anyStore || this.service == rpcJsonRest.getServiceAndId(item.__id).service);
 		},
 		_doQuery: function(args){
 			var query= typeof args.queryStr == 'string' ? args.queryStr : args.query;
-			var deferred = dojox.rpc.JsonRest.query(this.service,query, args);
+			var deferred = rpcJsonRest.query(this.service,query, args);
 			var self = this;
 			if(this.loadReferencedSchema){
 				deferred.addCallback(function(result){
@@ -369,10 +393,10 @@ dojo.declare("dojox.data.JsonRestStore",
 					}
 					schemaRef = schemaRef && schemaRef[1];
 					if(schemaRef){
-						var serviceAndId = dojox.rpc.JsonRest.getServiceAndId((self.target + schemaRef).replace(/^(.*\/)?(\w+:\/\/)|[^\/\.]+\/\.\.\/|^.*\/(\/)/,"$2$3"));
-						var schemaDeferred = dojox.rpc.JsonRest.byId(serviceAndId.service, serviceAndId.id);
+						var serviceAndId = rpcJsonRest.getServiceAndId((self.target + schemaRef).replace(/^(.*\/)?(\w+:\/\/)|[^\/\.]+\/\.\.\/|^.*\/(\/)/,"$2$3"));
+						var schemaDeferred = rpcJsonRest.byId(serviceAndId.service, serviceAndId.id);
 						schemaDeferred.addCallbacks(function(newSchema){
-							dojo.mixin(self.schema, newSchema);
+							lang.mixin(self.schema, newSchema);
 							return result;
 						}, function(error){
 							console.error(error); // log it, but don't let it cause the main request to fail
@@ -411,7 +435,7 @@ dojo.declare("dojox.data.JsonRestStore",
 			var store = this;
 			// if it is an absolute id, we want to find the right store to query
 			if(id.toString().match(/^(\w*:)?\//)){
-				var serviceAndId = dojox.rpc.JsonRest.getServiceAndId(id);
+				var serviceAndId = rpcJsonRest.getServiceAndId(id);
 				store = serviceAndId.service._store;
 				args.identity = serviceAndId.id;
 			}
@@ -445,7 +469,7 @@ dojo.declare("dojox.data.JsonRestStore",
 
 	}
 );
-dojox.data.JsonRestStore.getStore = function(options, Class){
+JsonRestStore.getStore = function(options, Class){
 	//	summary:
 	//		Will retrieve or create a store using the given options (the same options
 	//		that are passed to JsonRestStore constructor. Returns a JsonRestStore instance
@@ -457,26 +481,29 @@ dojox.data.JsonRestStore.getStore = function(options, Class){
 	if(typeof options.target == 'string'){
 		options.target = options.target.match(/\/$/) || options.allowNoTrailingSlash ?
 				options.target : (options.target + '/');
-		var store = (dojox.rpc.JsonRest.services[options.target] || {})._store;
+		var store = (rpcJsonRest.services[options.target] || {})._store;
 		if(store){
 			return store;
 		}
 	}
-	return new (Class || dojox.data.JsonRestStore)(options);
+	return new (Class || JsonRestStore)(options);
 };
-dojox.data._getStoreForItem = function(item){
+
+var dataExtCfg = lang.getObject("dojox.data",true); 
+dataExtCfg._getStoreForItem = function(item){
 	if(item.__id){
-		var serviceAndId = dojox.rpc.JsonRest.getServiceAndId(item.__id);
+		var serviceAndId = rpcJsonRest.getServiceAndId(item.__id);
 		if(serviceAndId && serviceAndId.service._store){
 			return serviceAndId.service._store;
 		}else{
 			var servicePath = item.__id.toString().match(/.*\//)[0];
-			return new dojox.data.JsonRestStore({target:servicePath});
+			return new JsonRestStore({target:servicePath});
 		}
 	}
 	return null;
 };
-dojox.json.ref._useRefs = true; // Use referencing when identifiable objects are referenced
+var jsonRefConfig = lang.getObject("dojox.json.ref", true);
+jsonRefConfig._useRefs = true; // Use referencing when identifiable objects are referenced
 
-return dojox.data.JsonRestStore;
+return JsonRestStore;
 });
diff --git a/dojox/data/KeyValueStore.js b/dojox/data/KeyValueStore.js
index 68c66ea..d41e85f 100644
--- a/dojox/data/KeyValueStore.js
+++ b/dojox/data/KeyValueStore.js
@@ -1,6 +1,8 @@
-define("dojox/data/KeyValueStore", ["dojo", "dojox", "dojo/data/util/simpleFetch", "dojo/data/util/filter"], function(dojo, dojox) {
+define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/xhr", "dojo/_base/window", 
+		"dojo/data/util/simpleFetch", "dojo/data/util/filter"], 
+  function(declare, lang, xhr, winUtil, simpleFetch, filterUtil) {
 
-dojo.declare("dojox.data.KeyValueStore", null, {
+var KeyValueStore = declare("dojox.data.KeyValueStore", null, {
 	//	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
@@ -58,7 +60,7 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 		//      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(!dojo.isString(attribute)){
+		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");
 		}
 	},
@@ -117,7 +119,7 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 		//		See dojo.data.api.Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
-			regexp = dojo.data.util.filter.patternToRegExp(value, false);
+			regexp = filterUtil.patternToRegExp(value, false);
 		}
 		return this._containsValue(item, attribute, value, regexp); //boolean.
 	},
@@ -230,7 +232,7 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 				for(var key in requestArgs.query){
 					var value = requestArgs.query[key];
 					if(typeof value === "string"){
-						regexpList[key] = dojo.data.util.filter.patternToRegExp(value, ignoreCase);
+						regexpList[key] = filterUtil.patternToRegExp(value, ignoreCase);
 					}
 				}
 
@@ -283,7 +285,7 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 							handleAs: "json-comment-filtered",
 							preventCache: this.urlPreventCache
 						};
-					var getHandler = dojo.xhrGet(getArgs);
+					var getHandler = xhr.get(getArgs);
 					getHandler.addCallback(function(data){
 						self._processData(data);
 						filter(keywordArgs, self._arrayOfAllItems);
@@ -376,7 +378,7 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 	},
 	
 	_finishFetchItemByIdentity: function(/* Array */ items, /* object */ request){
-		var scope = request.scope || dojo.global;
+		var scope = request.scope || winUtil.global;
 		if(items.length){
 			request.oldOnItem.call(scope, items[0]);
 		}else{
@@ -385,6 +387,6 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 	}
 });
 //Mix in the simple fetch implementation to this class.
-dojo.extend(dojox.data.KeyValueStore,dojo.data.util.simpleFetch);
-return dojox.data.KeyValueStore;
+lang.extend(KeyValueStore,simpleFetch);
+return KeyValueStore;
 });
diff --git a/dojox/data/OpenSearchStore.js b/dojox/data/OpenSearchStore.js
index 2a429d5..93a4e71 100644
--- a/dojox/data/OpenSearchStore.js
+++ b/dojox/data/OpenSearchStore.js
@@ -1,12 +1,16 @@
-dojo.provide("dojox.data.OpenSearchStore");
+define([
+	"dojo/_base/kernel", // dojo.experimental
+	"dojo/_base/lang", // dojo.extend
+	"dojo/_base/declare", // dojo.declare
+	"dojo/_base/xhr", // dojo.xhrGet
+	"dojo/_base/array", // dojo.forEach
+	"dojo/_base/window", // dojo.doc
+	"dojo/query",
+	"dojo/data/util/simpleFetch",
+	"dojox/xml/parser"], function (kernel, lang, declare, dxhr, array, window, query, simpleFetch, parser) {
+kernel.experimental("dojox.data.OpenSearchStore");
 
-dojo.require("dojo.data.util.simpleFetch");
-dojo.require("dojox.xml.DomParser");
-dojo.require("dojox.xml.parser");
-
-dojo.experimental("dojox.data.OpenSearchStore");
-
-dojo.declare("dojox.data.OpenSearchStore", null, {
+var OpenSearchStore = declare("dojox.data.OpenSearchStore", null, {
 	constructor: function(/*Object*/args){
 		//	summary:
 		//		Initializer for the OpenSearchStore store.
@@ -21,7 +25,7 @@ dojo.declare("dojox.data.OpenSearchStore", null, {
 				this.urlPreventCache = args.urlPreventCache?true:false;
 			}
 		}
-		var def = dojo.xhrGet({
+		var def = dxhr.get({
 			url: this.url,
 			handleAs: "xml",
 			sync: true,
@@ -185,7 +189,7 @@ dojo.declare("dojox.data.OpenSearchStore", null, {
 		var index = template.indexOf("{searchTerms}");
 		template = template.substring(0, index) + request.query.searchTerms + template.substring(index+13);
 		
-		dojo.forEach([	{'name': 'count', 'test': request.count, 'def': '10'},
+		array.forEach([	{'name': 'count', 'test': request.count, 'def': '10'},
 						{'name': 'startIndex', 'test': request.start, 'def': this.urlElement.attributes.getNamedItem("indexOffset")?this.urlElement.attributes.getNamedItem("indexOffset").nodeValue:0},
 						{'name': 'startPage', 'test': request.startPage, 'def': this.urlElement.attributes.getNamedItem("pageOffset")?this.urlElement.attributes.getNamedItem("pageOffset").nodeValue:0},
 						{'name': 'language', 'test': request.language, 'def': "*"},
@@ -221,7 +225,7 @@ dojo.declare("dojox.data.OpenSearchStore", null, {
 		};
 
 		// Change to fetch the query results.
-		var xhr = dojo.xhrGet(getArgs);
+		var xhr = dxhr.get(getArgs);
 
 		xhr.addErrback(function(error){
 			errorHandler(error, request);
@@ -242,9 +246,9 @@ dojo.declare("dojox.data.OpenSearchStore", null, {
 	},
 	
 	_processOSDxml: function(data){
-		var div = dojo.doc.createElement("div");
+		var div = window.doc.createElement("div");
 		div.innerHTML = data;
-		return dojo.query(this.itemPath, div);
+		return query(this.itemPath, div);
 	},
 	
 	_processItemxml: function(item, attribute){
@@ -364,4 +368,5 @@ dojo.declare("dojox.data.OpenSearchStore", null, {
 		}
 	}
 });
-dojo.extend(dojox.data.OpenSearchStore,dojo.data.util.simpleFetch);
+return lang.extend(OpenSearchStore,simpleFetch);
+});
\ No newline at end of file
diff --git a/dojox/data/OpmlStore.js b/dojox/data/OpmlStore.js
index f42fc64..22d8913 100644
--- a/dojox/data/OpmlStore.js
+++ b/dojox/data/OpmlStore.js
@@ -1,6 +1,8 @@
-define("dojox/data/OpmlStore", ["dojo", "dojox", "dojo/data/util/simpleFetch", "dojo/data/util/filter"], function(dojo, dojox) {
+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.declare("dojox.data.OpmlStore", null, {
+var OpmlStore = declare("dojox.data.OpmlStore", null, {
 	/* summary:
 	 *   The OpmlStore implements the dojo.data.api.Read API.
 	 */
@@ -55,7 +57,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 		//      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(!dojo.isString(attribute)){
+		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");
 		}
 	},
@@ -212,7 +214,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 		//		See dojo.data.api.Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
-			regexp = dojo.data.util.filter.patternToRegExp(value, false);
+			regexp = filterUtil.patternToRegExp(value, false);
 		}
 		return this._containsValue(item, attribute, value, regexp); //boolean.
 	},
@@ -320,7 +322,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 				for(var key in requestArgs.query){
 					var value = requestArgs.query[key];
 					if(typeof value === "string"){
-						regexpList[key] = dojo.data.util.filter.patternToRegExp(value, ignoreCase);
+						regexpList[key] = filterUtil.patternToRegExp(value, ignoreCase);
 					}
 				}
 
@@ -364,7 +366,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 							handleAs: "xml",
 							preventCache: self.urlPreventCache
 						};
-					var getHandler = dojo.xhrGet(getArgs);
+					var getHandler = xhr.get(getArgs);
 					getHandler.addCallback(function(data){
 						self._processRawXmlTree(data);
 						filter(keywordArgs, self._getItemsArray(keywordArgs.queryOptions));
@@ -430,9 +432,9 @@ dojo.declare("dojox.data.OpmlStore", null, {
 							url: self.url,
 							handleAs: "xml"
 						};
-					var getHandler = dojo.xhrGet(getArgs);
+					var getHandler = xhr.get(getArgs);
 					getHandler.addCallback(function(data){
-						var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+						var scope = keywordArgs.scope ? keywordArgs.scope : winUtil.global;
 						try{
 							self._processRawXmlTree(data);
 							var item = self._identityMap[keywordArgs.identity];
@@ -452,7 +454,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 					getHandler.addErrback(function(error){
 						this._loadInProgress = false;
 						if(keywordArgs.onError){
-							var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+							var scope = keywordArgs.scope ? keywordArgs.scope : winUtil.global;
 							keywordArgs.onError.call(scope, error);
 						}
 					});
@@ -465,7 +467,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 					item = null;
 				}
 				if(keywordArgs.onItem){
-					var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+					var scope = keywordArgs.scope ? keywordArgs.scope : winUtil.global;
 					keywordArgs.onItem.call(scope, item);
 				}
 			}
@@ -476,7 +478,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 				item = null;
 			}
 			if(keywordArgs.onItem){
-				var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
+				var scope = keywordArgs.scope ? keywordArgs.scope : winUtil.global;
 				keywordArgs.onItem.call(scope, item);
 			}
 		}
@@ -516,8 +518,8 @@ dojo.declare("dojox.data.OpmlStore", null, {
 	}
 });
 //Mix in the simple fetch implementation to this class.
-dojo.extend(dojox.data.OpmlStore,dojo.data.util.simpleFetch);
+lang.extend(OpmlStore, simpleFetch);
 
-return dojox.data.OpmlStore;
+return OpmlStore;
 });
 	
diff --git a/dojox/data/PersevereStore.js b/dojox/data/PersevereStore.js
index e64f695..eea68d7 100644
--- a/dojox/data/PersevereStore.js
+++ b/dojox/data/PersevereStore.js
@@ -1,4 +1,4 @@
-define("dojox/data/PersevereStore", ["dojo", "dojox", "dojox/data/JsonQueryRestStore", "dojox/rpc/Client"], function(dojo, dojox) {
+define(["dojo", "dojox", "require", "dojox/data/JsonQueryRestStore", "dojox/rpc/Client", "dojo/_base/url"], function(dojo, dojox, require) {
 
 // PersevereStore is an extension of JsonRestStore to handle Persevere's special features
 
@@ -8,7 +8,7 @@ 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){
 	// summary:
 	//		Creates Dojo data stores for all the table/classes on a Persevere server
@@ -25,7 +25,7 @@ dojox.data.PersevereStore.getStores = function(/*String?*/path,/*Boolean?*/sync)
 	path = (path && (path.match(/\/$/) ? path : (path + '/'))) || '/';
 	if(path.match(/^\w*:\/\//)){
 		// if it is cross-domain, we will use window.name for communication
-		dojo.require("dojox.io.xhrScriptPlugin");
+		require("dojox/io/xhrScriptPlugin");
 		dojox.io.xhrScriptPlugin(path, "callback", dojox.io.xhrPlugins.fullHttpAdapter);
 	}
 	var plainXhr = dojo.xhr;
@@ -103,7 +103,7 @@ dojox.data.PersevereStore.getStores = function(/*String?*/path,/*Boolean?*/sync)
 dojox.data.PersevereStore.addProxy = function(){
 	// summary:
 	//		Invokes the XHR proxy plugin. Call this if you will be using x-site data.
-	dojo.require("dojox.io.xhrPlugins"); // also not necessary, but we can register that Persevere supports proxying
+	require("dojox/io/xhrPlugins"); // also not necessary, but we can register that Persevere supports proxying
 	dojox.io.xhrPlugins.addProxy("/proxy/");
 };
 
diff --git a/dojox/data/PicasaStore.js b/dojox/data/PicasaStore.js
index ea7902b..ce9d892 100644
--- a/dojox/data/PicasaStore.js
+++ b/dojox/data/PicasaStore.js
@@ -1,6 +1,7 @@
-define("dojox/data/PicasaStore", ["dojo", "dojox", "dojo/io/script", "dojo/data/util/simpleFetch", "dojo/date/stamp"], function(dojo, dojox) {
+define(["dojo/_base/lang","dojo/_base/declare", "dojo/_base/connect", "dojo/io/script", "dojo/data/util/simpleFetch", "dojo/date/stamp"], 
+  function(lang, declare, connect, scriptIO, simpleFetch, dateStamp) {
 
-dojo.declare("dojox.data.PicasaStore", null, {
+var PicasaStore = declare("dojox.data.PicasaStore", null, {
 	constructor: function(/*Object*/args){
 		//	summary:
 		//		Initializer for the PicasaStore store.
@@ -33,7 +34,7 @@ dojo.declare("dojox.data.PicasaStore", null, {
 	label: "title",
 
 	//urlPreventCache: boolean
-	//Flag denoting if preventCache should be passed to dojo.io.script.
+	//Flag denoting if preventCache should be passed to io.script.
 	urlPreventCache: false,
 
 	//maxResults:  Define out how many results to return for a fetch.
@@ -141,11 +142,11 @@ dojo.declare("dojox.data.PicasaStore", null, {
 		}else if(attribute === "author"){
 			return [this._unescapeHtml(item.author[0].name)];
 		}else if(attribute === "datePublished"){
-			return [dojo.date.stamp.fromISOString(item.published)];
+			return [dateAtamp.fromISOString(item.published)];
 		}else if(attribute === "dateTaken"){
-			return [dojo.date.stamp.fromISOString(item.published)];
+			return [dateStamp.fromISOString(item.published)];
 		}else if(attribute === "updated"){
-			return [dojo.date.stamp.fromISOString(item.updated)];
+			return [dateStamp.fromISOString(item.updated)];
 		}else if(attribute === "imageUrlSmall"){
 			return [item.media.thumbnail[1].url];
 		}else if(attribute === "imageUrl"){
@@ -216,7 +217,7 @@ dojo.declare("dojox.data.PicasaStore", null, {
 		var handle = null;
 		var myHandler = function(data){
 			if(handle !== null){
-				dojo.disconnect(handle);
+				connect.disconnect(handle);
 			}
 
 			//Process the items...
@@ -229,10 +230,10 @@ dojo.declare("dojox.data.PicasaStore", null, {
 			callbackParamName: 'callback',
 			handle: myHandler
 		};
-		var deferred = dojo.io.script.get(getArgs);
+		var deferred = scriptIO.get(getArgs);
 		
 		deferred.addErrback(function(error){
-			dojo.disconnect(handle);
+			connect.disconnect(handle);
 			errorHandler(error, request);
 		});
 	},
@@ -265,8 +266,8 @@ dojo.declare("dojox.data.PicasaStore", null, {
 		return str;
 	}
 });
-dojo.extend(dojox.data.PicasaStore,dojo.data.util.simpleFetch);
+lang.extend(PicasaStore, simpleFetch);
 
-return dojox.data.PicasaStore;
+return PicasaStore;
 
 });
diff --git a/dojox/data/QueryReadStore.js b/dojox/data/QueryReadStore.js
index 1e5401f..0efa0bc 100644
--- a/dojox/data/QueryReadStore.js
+++ b/dojox/data/QueryReadStore.js
@@ -1,4 +1,4 @@
-define("dojox/data/QueryReadStore", ["dojo", "dojox", "dojo.data.util.sorter", "dojo/string"], function(dojo, dojox) {
+define(["dojo", "dojox", "dojo/data/util/sorter", "dojo/string"], function(dojo, dojox) {
 
 dojo.declare("dojox.data.QueryReadStore",
 	null,
diff --git a/dojox/data/RailsStore.js b/dojox/data/RailsStore.js
index 9516e08..b573c2e 100644
--- a/dojox/data/RailsStore.js
+++ b/dojox/data/RailsStore.js
@@ -1,4 +1,4 @@
-define("dojox/data/RailsStore", ["dojo", "dojox", "dojox/data/JsonRestStore"], function(dojo, dojox) {
+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, {
diff --git a/dojox/data/S3Store.js b/dojox/data/S3Store.js
index 1f8ecf1..10d7867 100644
--- a/dojox/data/S3Store.js
+++ b/dojox/data/S3Store.js
@@ -1,10 +1,10 @@
-define("dojox/data/S3Store", ["dojo", "dojox", "dojox/data/JsonRestStore", "dojox/rpc/ProxiedPath"], function(dojo, dojox) {
+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
-
-dojo.declare("dojox.data.S3Store",
-	dojox.data.JsonRestStore,
+/*===== var JsonRestStore = dojox.data.JsonRestStore =====*/
+return declare("dojox.data.S3Store", JsonRestStore,
 	{
 		_processResults : function(results){
 			// unfortunately, S3 returns query results in XML form
@@ -31,5 +31,4 @@ dojo.declare("dojox.data.S3Store",
 	}
 );
 
-return dojox.data.S3Store;
 });
diff --git a/dojox/data/ServiceStore.js b/dojox/data/ServiceStore.js
index 626880d..29ff049 100644
--- a/dojox/data/ServiceStore.js
+++ b/dojox/data/ServiceStore.js
@@ -1,4 +1,5 @@
-define("dojox/data/ServiceStore", ["dojo", "dojox"], function(dojo, dojox) {
+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
 
@@ -15,10 +16,10 @@ define("dojox/data/ServiceStore", ["dojo", "dojox"], function(dojo, dojox) {
 // The object would automatically be requested from the server (with an object id of "obj2").
 //
 
-dojo.declare("dojox.data.ServiceStore",
+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.
-	dojox.data.ClientFilter||null,{
+	lang.getObject("dojox.data.ClientFilter", 0)||null,{
 		service: null,
 		constructor: function(options){
 			//summary:
@@ -86,7 +87,7 @@ dojo.declare("dojox.data.ServiceStore",
 			this._index = {};
 			// if the advanced json parser is enabled, we can pass through object updates as onSet events
 			if(options){
-				dojo.mixin(this,options);
+				lang.mixin(this,options);
 			}
 			// We supply a default idAttribute for parser driven construction, but if no id attribute
 			//	is supplied, it should be null so that auto identification takes place properly
@@ -133,13 +134,6 @@ dojo.declare("dojox.data.ServiceStore",
 			//		property to look up value for
 
 			var val = this.getValue(item,property);
-			if(val instanceof Array){
-				return val;
-			}
-			if(!this.isItemLoaded(val)){
-				dojox.rpc._sync = true;
-				val = this.loadItem({item:val});
-			}
 			return val instanceof Array ? val : val === undefined ? [] : [val];
 		},
 
@@ -175,7 +169,7 @@ dojo.declare("dojox.data.ServiceStore",
 			//	item: /* object */
 			//	attribute: /* string */
 			//	value: /* anything */
-			return dojo.indexOf(this.getValues(item,attribute),value) > -1;
+			return array.indexOf(this.getValues(item,attribute),value) > -1;
 		},
 
 
@@ -257,7 +251,7 @@ dojo.declare("dojox.data.ServiceStore",
 							for(var j in existingObj){
 								delete existingObj[j]; // clear it so we can mixin
 							}
-							results = dojo.mixin(existingObj,results);
+							results = lang.mixin(existingObj,results);
 						}
 						results.__id = id;
 						this._index[id] = results;
@@ -397,6 +391,4 @@ dojo.declare("dojox.data.ServiceStore",
 
 	}
 );
-
-return dojox.data.ServiceStore;
 });
diff --git a/dojox/data/SnapLogicStore.js b/dojox/data/SnapLogicStore.js
index 570675c..b7b1da8 100644
--- a/dojox/data/SnapLogicStore.js
+++ b/dojox/data/SnapLogicStore.js
@@ -1,4 +1,4 @@
-define("dojox/data/SnapLogicStore", ["dojo", "dojox", "dojo/io/script", "dojo/data/util/sorter"], function(dojo, dojox) {
+define(["dojo", "dojox", "dojo/io/script", "dojo/data/util/sorter"], function(dojo, dojox) {
 
 dojo.declare("dojox.data.SnapLogicStore", null, {
 	Parts: {
diff --git a/dojox/data/WikipediaStore.js b/dojox/data/WikipediaStore.js
index 7ccad28..c5552c4 100644
--- a/dojox/data/WikipediaStore.js
+++ b/dojox/data/WikipediaStore.js
@@ -1,8 +1,12 @@
-define("dojox/data/WikipediaStore", ["dojo", "dojox", "dojo/io/script", "dojox/rpc/Service", "dojox/data/ServiceStore"], function(dojo, dojox) {
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/io/script", 
+		"dojo/io-query", "dojox/rpc/Service", "dojox/data/ServiceStore"], 
+  function(kernel, lang, declare, scriptIO, ioQuery, Service, ServiceStore) {
 
-dojo.experimental("dojox.data.WikipediaStore");
+kernel.experimental("dojox.data.WikipediaStore");
 
-dojo.declare("dojox.data.WikipediaStore", dojox.data.ServiceStore,{
+/*===== var ServiceStore = dojox.data.ServiceStore; =====*/
+
+return declare("dojox.data.WikipediaStore", ServiceStore, {
 	//	summary:
 	//		Initializer for the Wikipedia data store interface.
 	//	description:
@@ -22,7 +26,7 @@ dojo.declare("dojox.data.WikipediaStore", dojox.data.ServiceStore,{
 		if(options && options.service){
 			this.service = options.service;
 		}else{
-			var svc = new dojox.rpc.Service(dojo.moduleUrl("dojox.rpc.SMDLibrary", "wikipedia.smd"));
+			var svc = new Service(require.toUrl("dojox/rpc/SMDLibrary/wikipedia.smd"));
 			this.service = svc.query;
 		}
 
@@ -60,7 +64,7 @@ dojo.declare("dojox.data.WikipediaStore", dojox.data.ServiceStore,{
 		//		|		},
 		//		|		// define your handlers here
 		//		|	});
-		var rq = dojo.mixin({}, request.query);
+		var rq = lang.mixin({}, request.query);
 		if(rq && (!rq.action || rq.action === "parse")){
 			// default to a single page fetch
 			rq.action = "parse";
@@ -87,7 +91,7 @@ dojo.declare("dojox.data.WikipediaStore", dojox.data.ServiceStore,{
 	_processResults: function(results, def){
 		if(results.parse){
 			// loading a complete page
-			results.parse.title = dojo.queryToObject(def.ioArgs.url.split("?")[1]).page;
+			results.parse.title = ioQuery.queryToObject(def.ioArgs.url.split("?")[1]).page;
 			results = [results.parse];
 
 		}else if(results.query && results.query.search){
@@ -109,7 +113,5 @@ dojo.declare("dojox.data.WikipediaStore", dojox.data.ServiceStore,{
 	}
 });
 
-return dojox.data.WikipediaStore;
-
 });
 
diff --git a/dojox/data/XmlItem.js b/dojox/data/XmlItem.js
new file mode 100644
index 0000000..2aee3db
--- /dev/null
+++ b/dojox/data/XmlItem.js
@@ -0,0 +1,43 @@
+define(["dojo/_base/declare"], 
+  function(declare) {
+
+return declare("dojox.data.XmlItem", null, {
+	constructor: function(element, store, query){
+		//	summary:
+		//		Initialize with an XML element
+		//	element:
+		//		An XML element
+		//	store:
+		//		The containing store, if any.
+		//	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:
+	//		A data item of 'XmlStore'
+	//	description:
+	//		This class represents an item of 'XmlStore' holding an XML element.
+	//		'element'
+	//	element:
+	//		An XML element
+	toString: function(){
+		//	summary:
+		//		Return a value of the first text child of the element
+		// 	returns:
+		//		a value of the first text child of the element
+		var str = "";
+		if(this.element){
+			for(var i = 0; i < this.element.childNodes.length; i++){
+				var node = this.element.childNodes[i];
+				if(node.nodeType === 3 || node.nodeType === 4){
+					str += node.nodeValue;
+				}
+			}
+		}
+		return str;	//String
+	}
+});
+});
diff --git a/dojox/data/XmlStore.js b/dojox/data/XmlStore.js
index 8c32233..cca77fb 100644
--- a/dojox/data/XmlStore.js
+++ b/dojox/data/XmlStore.js
@@ -1,8 +1,9 @@
-define("dojox/data/XmlStore", ["dojo", "dojox", "dojo/data/util/simpleFetch", "dojo/data/util/filter", "dojox/xml/parser"], function(dojo, dojox) {
+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",
+		"dojox/data/XmlItem"], 
+  function(lang, declare, xhr, simpleFetch, domQuery, array, winUtil, filter, xmlParser, XmlItem) {
 
-dojo.provide("dojox.data.XmlItem");
-
-dojo.declare("dojox.data.XmlStore", null, {
+var XmlStore = declare("dojox.data.XmlStore", null, {
 	//	summary:
 	//		A data store for XML based services or documents
 	//	description:
@@ -397,9 +398,8 @@ dojo.declare("dojox.data.XmlStore", null, {
 		//	errorHandler:
 		//		A function to call on error
 		var url = this._getFetchUrl(request);
-		console.log("XmlStore._fetchItems(): url=" + url);
 		if(!url){
-			errorHandler(new Error("No URL specified."));
+			errorHandler(new Error("No URL specified."), request);
 			return;
 		}
 		var localRequest = (!this.sendQuery ? request : {}); // use request for _getItems()
@@ -410,10 +410,9 @@ dojo.declare("dojox.data.XmlStore", null, {
 				handleAs: "xml",
 				preventCache: self.urlPreventCache
 			};
-		var getHandler = dojo.xhrGet(getArgs);
+		var getHandler = xhr.get(getArgs);
 		getHandler.addCallback(function(data){
 			var items = self._getItems(data, localRequest);
-			console.log("XmlStore._fetchItems(): length=" + (items ? items.length : 0));
 			if(items && items.length > 0){
 				fetchHandler(items, request);
 			}else{
@@ -446,7 +445,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 		if(!query){
 			return this.url;
 		}
-		if(dojo.isString(query)){
+		if(lang.isString(query)){
 			return this.url + query;
 		}
 		var queryString = "";
@@ -496,7 +495,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 		var nodes = null;
 
 		if(this.rootItem !== ""){
-			nodes = dojo.query(this.rootItem, document);
+			nodes = domQuery(this.rootItem, document);
 		}else{
 			nodes = document.documentElement.childNodes;
 		}
@@ -524,7 +523,10 @@ dojo.declare("dojox.data.XmlStore", null, {
 				for(var key in query){
 					value = query[key];
 					if(typeof value === "string"){
-						regexpList[key] = dojo.data.util.filter.patternToRegExp(value, ignoreCase);
+						regexpList[key] = filter.patternToRegExp(value, ignoreCase);
+					}else if(value){
+						// It's an object, possibly regexp, so treat it as one.
+						regexpList[key] = value;
 					}
 				}
 				for(var attribute in query){
@@ -579,7 +581,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 				items.push(item);
 			}
 		}
-		dojo.forEach(items,function(item){
+		array.forEach(items,function(item){
 			if(item.element.parentNode){
 				item.element.parentNode.removeChild(item.element); // make it root
 			}
@@ -624,7 +626,6 @@ dojo.declare("dojox.data.XmlStore", null, {
 		//		An object containing initial attributes
 		//	returns:
 		//		An XML element
-		console.log("XmlStore.newItem()");
 		keywordArgs = (keywordArgs || {});
 		var tagName = keywordArgs.tagName;
 		if(!tagName){
@@ -683,7 +684,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 				this.setValues(parentInfo.parent, parentInfo.attribute, tempValues);
 				pInfo.newValue = this.getValues(parentInfo.parent, parentInfo.attribute);
 			}else{
-				this.setValues(parentInfo.parent, parentInfo.attribute, item);
+				this.setValue(parentInfo.parent, parentInfo.attribute, item);
 				pInfo.newValue = item;
 			}
 		}
@@ -697,7 +698,6 @@ dojo.declare("dojox.data.XmlStore", null, {
 		//		An XML element to delete
 		//	returns:
 		//		True
-		console.log("XmlStore.deleteItem()");
 		var element = item.element;
 		if(element.parentNode){
 			this._backupItem(item);
@@ -957,9 +957,6 @@ dojo.declare("dojox.data.XmlStore", null, {
 		//	Invalidate changes (new and/or modified elements)
 		// returns:
 		//	True
-		console.log("XmlStore.revert() _newItems=" + this._newItems.length);
-		console.log("XmlStore.revert() _deletedItems=" + this._deletedItems.length);
-		console.log("XmlStore.revert() _modifiedItems=" + this._modifiedItems.length);
 		this._newItems = [];
 		this._restoreItems(this._deletedItems);
 		this._deletedItems = [];
@@ -1005,7 +1002,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 		}
 		if(!url){
 			if(keywordArgs.onError){
-				scope = keywordArgs.scope || dojo.global;
+				scope = keywordArgs.scope || winUtil.global;
 				keywordArgs.onError.call(scope, new Error("No URL for saving content: " + this._getPostContent(item)));
 			}
 			return;
@@ -1020,14 +1017,14 @@ dojo.declare("dojox.data.XmlStore", null, {
 		var saveHandler;
 		if(method === "PUT"){
 			saveArgs.putData = this._getPutContent(item);
-			saveHandler = dojo.rawXhrPut(saveArgs);
+			saveHandler = xhr.put(saveArgs);
 		}else if(method === "DELETE"){
-			saveHandler = dojo.xhrDelete(saveArgs);
+			saveHandler = xhr.del(saveArgs);
 		}else{ // POST
 			saveArgs.postData = this._getPostContent(item);
-			saveHandler = dojo.rawXhrPost(saveArgs);
+			saveHandler = xhr.post(saveArgs);
 		}
-		scope = (keywordArgs.scope || dojo.global);
+		scope = (keywordArgs.scope || winUtil. global);
 		var self = this;
 		saveHandler.addCallback(function(data){
 			self._forgetItem(item);
@@ -1104,9 +1101,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 		//		An item to save
 		//	returns:
 		//		A post content
-		var element = item.element;
-		var declaration = "<?xml version=\"1.0\"?>"; // FIXME: encoding?
-		return declaration + dojox.xml.parser.innerXML(element); //XML string
+		return "<?xml version=\'1.0\'?>" + xmlParser.innerXML(item.element); //XML string
 	},
 
 	_getPutContent: function(item){
@@ -1121,9 +1116,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 		//		An item to save
 		//	returns:
 		//		A post content
-		var element = item.element;
-		var declaration = "<?xml version=\"1.0\"?>"; // FIXME: encoding?
-		return declaration + dojox.xml.parser.innerXML(element); //XML string
+		return "<?xml version='1.0'?>" + xmlParser.innerXML(item.element); //XML string
 	},
 
 /* internal API */
@@ -1151,7 +1144,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 			if(this.keyAttribute === ""){
 				q = this._getXPath(element);
 			}
-			return new dojox.data.XmlItem(element, this, q); //object
+			return new XmlItem(element, this, q); //object
 		}catch (e){
 			console.log(e);
 		}
@@ -1182,7 +1175,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 
 	_restoreItems: function(items){
 
-		dojo.forEach(items,function(item){
+		array.forEach(items,function(item){
 			if(item._backup){
 				item.element = item._backup;
 				item._backup = null;
@@ -1210,7 +1203,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 		if(element){
 			return element.ownerDocument; //DOMDocument
 		}else if(!this._document){
-			return dojox.xml.parser.parse(); // DOMDocument
+			return xmlParser.parse(); // DOMDocument
 		}
 		return null; //null
 	},
@@ -1331,7 +1324,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 						request.query[self.keyAttribute] = keywordArgs.identity;
 						request.queryOptions = {deep: true};
 						var items = self._getItems(data,request);
-						scope = keywordArgs.scope || dojo.global;
+						scope = keywordArgs.scope || winUtil.global;
 						if(items.length === 1){
 							if(keywordArgs.onItem){
 								keywordArgs.onItem.call(scope, items[0]);
@@ -1399,7 +1392,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 							}
 						}
 						if(keywordArgs.onItem){
-							scope = keywordArgs.scope || dojo.global;
+							scope = keywordArgs.scope || winUtil.global;
 							keywordArgs.onItem.call(scope, item);
 						}
 					}
@@ -1411,13 +1404,13 @@ dojo.declare("dojox.data.XmlStore", null, {
 				handleAs: "xml",
 				preventCache: self.urlPreventCache
 			};
-			getHandler = dojo.xhrGet(getArgs);
+			getHandler = xhr.get(getArgs);
 			
 			//Add in the callbacks for completion of data load.
 			getHandler.addCallback(handleDocument);
 			if(keywordArgs.onError){
 				getHandler.addErrback(function(error){
-					var s = keywordArgs.scope || dojo.global;
+					var s = keywordArgs.scope || winUtil.global;
 					keywordArgs.onError.call(s, error);
 				});
 			}
@@ -1436,13 +1429,13 @@ dojo.declare("dojox.data.XmlStore", null, {
 							item = items[0];
 						}else{
 							if(keywordArgs.onError){
-								var scope = keywordArgs.scope || dojo.global;
+								var scope = keywordArgs.scope || winUtil.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 || dojo.global;
+						scope = keywordArgs.scope || winUtil.global;
 						keywordArgs.onItem.call(scope, item);
 					}
 				};
@@ -1452,19 +1445,19 @@ dojo.declare("dojox.data.XmlStore", null, {
 					handleAs: "xml",
 					preventCache: self.urlPreventCache
 				};
-				getHandler = dojo.xhrGet(getArgs);
+				getHandler = xhr.get(getArgs);
 
 				//Add in the callbacks for completion of data load.
 				getHandler.addCallback(handleDocument);
 				if(keywordArgs.onError){
 					getHandler.addErrback(function(error){
-						var s = keywordArgs.scope || dojo.global;
+						var s = keywordArgs.scope || winUtil.global;
 						keywordArgs.onError.call(s, error);
 					});
 				}
 			}else{
 				if(keywordArgs.onError){
-					var s = keywordArgs.scope || dojo.global;
+					var s = keywordArgs.scope || winUtil.global;
 					keywordArgs.onError.call(s, new Error("XmlStore is not told that the server to provides identity support.  No keyAttribute specified."));
 				}
 			}
@@ -1472,46 +1465,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 	}
 });
 
-dojo.declare("dojox.data.XmlItem", null, {
-	constructor: function(element, store, query){
-		//	summary:
-		//		Initialize with an XML element
-		//	element:
-		//		An XML element
-		//	store:
-		//		The containing store, if any.
-		//	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:
-	//		A data item of 'XmlStore'
-	//	description:
-	//		This class represents an item of 'XmlStore' holding an XML element.
-	//		'element'
-	//	element:
-	//		An XML element
-	toString: function(){
-		//	summary:
-		//		Return a value of the first text child of the element
-		// 	returns:
-		//		a value of the first text child of the element
-		var str = "";
-		if(this.element){
-			for(var i = 0; i < this.element.childNodes.length; i++){
-				var node = this.element.childNodes[i];
-				if(node.nodeType === 3 || node.nodeType === 4){
-					str += node.nodeValue;
-				}
-			}
-		}
-		return str;	//String
-	}
-});
-dojo.extend(dojox.data.XmlStore,dojo.data.util.simpleFetch);
+lang.extend(XmlStore,simpleFetch);
 
-return dojox.data.XmlStore;
+return XmlStore;
 });
diff --git a/dojox/data/css.js b/dojox/data/css.js
index 9c1e248..bae0691 100755
--- a/dojox/data/css.js
+++ b/dojox/data/css.js
@@ -1,12 +1,15 @@
-define("dojox/data/css", ["dojo", "dojox"], function(dojo, dojox) {
+define(["dojo/_base/lang", "dojo/_base/array"], 
+  function(lang, array) {
 
-dojox.data.css.rules = {};
-		
-dojox.data.css.rules.forEach = function(fn,ctx,context){
+var css = lang.getObject("dojox.data.css",true) 
+
+css.rules = {};
+
+css.rules.forEach = function(fn,ctx,context){
 	if(context){
 		var _processSS = function(styleSheet){
 			//iterate across rules in the stylesheet
-			dojo.forEach(styleSheet[styleSheet.cssRules?"cssRules":"rules"], function(rule){
+			array.forEach(styleSheet[styleSheet.cssRules?"cssRules":"rules"], function(rule){
 				if(!rule.type || rule.type !== 3){// apply fn to current rule with approp ctx. rule is arg (all browsers)
 					var href = "";
 					if(styleSheet && styleSheet.href){
@@ -17,27 +20,29 @@ dojox.data.css.rules.forEach = function(fn,ctx,context){
 			});
 			//process any child stylesheets
 		};
-		dojo.forEach(context,_processSS);
+		array.forEach(context,_processSS);
 	}
 };
-dojox.data.css.findStyleSheets = function(sheets){
+
+css.findStyleSheets = function(sheets){
 	// Takes an array of stylesheet paths and finds the currently loaded StyleSheet objects matching
 	// those names
 	var sheetObjects = [];
 	var _processSS = function(styleSheet){
-		var s = dojox.data.css.findStyleSheet(styleSheet);
+		var s = css.findStyleSheet(styleSheet);
 		if(s){
-			dojo.forEach(s, function(sheet){
-				if(dojo.indexOf(sheetObjects, sheet) === -1){
+			array.forEach(s, function(sheet){
+				if(array.indexOf(sheetObjects, sheet) === -1){
 					sheetObjects.push(sheet);
 				}
 			});
 		}
 	};
-	dojo.forEach(sheets, _processSS);
+	array.forEach(sheets, _processSS);
 	return sheetObjects;
 };
-dojox.data.css.findStyleSheet = function(sheet){
+
+css.findStyleSheet = function(sheet){
 	// Takes a stylesheet path and finds the currently loaded StyleSheet objects matching
 	// those names (and it's parent(s), if it is imported from another)
 	var sheetObjects = [];
@@ -50,13 +55,13 @@ dojox.data.css.findStyleSheet = function(sheet){
 			return true;
 		}
 		if(styleSheet.imports){
-			return dojo.some(styleSheet.imports, function(importedSS){ //IE stylesheet has imports[] containing @import'ed rules
+			return array.some(styleSheet.imports, function(importedSS){ //IE stylesheet has imports[] containing @import'ed rules
 				//console.debug("Processing IE @import rule",importedSS);
 				return _processSS(importedSS);
 			});
 		}
 		//iterate across rules in the stylesheet
-		return dojo.some(styleSheet[styleSheet.cssRules?"cssRules":"rules"], function(rule){
+		return array.some(styleSheet[styleSheet.cssRules?"cssRules":"rules"], function(rule){
 			if(rule.type && rule.type === 3 && _processSS(rule.styleSheet)){// CSSImportRule (firefox)
 				//sheetObjects.push(styleSheet);
 				return true;
@@ -64,37 +69,38 @@ dojox.data.css.findStyleSheet = function(sheet){
 			return false;
 		});
 	};
-	dojo.some(document.styleSheets, _processSS);
+	array.some(document.styleSheets, _processSS);
 	return sheetObjects;
 };
-dojox.data.css.determineContext = function(initialStylesheets){
+
+css.determineContext = function(initialStylesheets){
 	// Takes an array of stylesheet paths and returns an array of all stylesheets that fall in the
 	// given context.  If no paths are given, all stylesheets are returned.
 	var ret = [];
 	if(initialStylesheets && initialStylesheets.length > 0){
-		initialStylesheets = dojox.data.css.findStyleSheets(initialStylesheets);
+		initialStylesheets = css.findStyleSheets(initialStylesheets);
 	}else{
 		initialStylesheets = document.styleSheets;
 	}
 	var _processSS = function(styleSheet){
 		ret.push(styleSheet);
 		if(styleSheet.imports){
-			dojo.forEach(styleSheet.imports, function(importedSS){ //IE stylesheet has imports[] containing @import'ed rules
+			array.forEach(styleSheet.imports, function(importedSS){ //IE stylesheet has imports[] containing @import'ed rules
 				//console.debug("Processing IE @import rule",importedSS);
 				_processSS(importedSS);
 			});
 		}
 		//iterate across rules in the stylesheet
-		dojo.forEach(styleSheet[styleSheet.cssRules?"cssRules":"rules"], function(rule){
+		array.forEach(styleSheet[styleSheet.cssRules?"cssRules":"rules"], function(rule){
 			if(rule.type && rule.type === 3){// CSSImportRule (firefox)
 				_processSS(rule.styleSheet);
 			}
 		});
 	};
-	dojo.forEach(initialStylesheets,_processSS);
+	array.forEach(initialStylesheets,_processSS);
 	return ret;
 };
 
-return dojox.data.css;
+return css;
 
 });
diff --git a/dojox/data/demos/demo_CssStores_combo_tree_grid.html b/dojox/data/demos/demo_CssStores_combo_tree_grid.html
index 165e5ed..22cf65a 100755
--- a/dojox/data/demos/demo_CssStores_combo_tree_grid.html
+++ b/dojox/data/demos/demo_CssStores_combo_tree_grid.html
@@ -17,7 +17,6 @@
 		is told that debug mode is off, and to parse all dojoType widgets when it has fully loaded.
 	-->
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: false, parseOnLoad: true"></script>
-	<script type="text/javascript" src="../../../dijit/dijit.js"></script>
 	<script>
 		dojo.require("dijit.Tree");
 		dojo.require("dijit.tree.ForestStoreModel");
diff --git a/dojox/data/demos/demo_DataDemoTable.html b/dojox/data/demos/demo_DataDemoTable.html
index 5b40e4b..9c594c1 100644
--- a/dojox/data/demos/demo_DataDemoTable.html
+++ b/dojox/data/demos/demo_DataDemoTable.html
@@ -74,7 +74,7 @@
 			}
 			var th = dojo.query("> th", this.headRow)[index];
 			th.style.paddingRight = "16px"; // space for the sort arrow
-			th.style.background = "url(\""+dojo.moduleUrl("dijit", "themes/tundra/images/arrow"+(this.query.sort[0].descending ? "Up" : "Down")+((dojo.isIE == 6) ? ".gif" : ".png")) + "\") no-repeat 98% 4px";
+			th.style.background = "url(\""+require.toUrl("dijit/themes/tundra/images/arrow"+(this.query.sort[0].descending ? "Up" : "Down")+((dojo.isIE == 6) ? ".gif" : ".png")) + "\") no-repeat 98% 4px";
 			this.runQuery();
 		</script>
 		<script type="dojo/method" event="runQuery">
diff --git a/dojox/data/demos/demo_FileStore_dojotree.html b/dojox/data/demos/demo_FileStore_dojotree.html
index 1d0b457..e134361 100755
--- a/dojox/data/demos/demo_FileStore_dojotree.html
+++ b/dojox/data/demos/demo_FileStore_dojotree.html
@@ -48,7 +48,6 @@
 		is told that debug mode is off, and to parse all dojoType widgets when it has fully loaded.
 	-->
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: false, parseOnLoad: true, useCommentedJson: true"></script>
-	<script type="text/javascript" src="../../../dijit/dijit.js"></script>
 	<script>
 		dojo.require("dijit.Tree");
 		dojo.require("dijit.tree.ForestStoreModel");
@@ -62,7 +61,8 @@
 		Demo:  Lazy Loading File Browsing Store
 	</h1>
 	<p>The tree 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>
+	<p><i><b>This demo must be run from a web-server with PHP support enabled.  Without PHP support, this demo cannot function.  The Demo also requires PHP 
+	support for json_encode and json_decode.  Please be sure to have those packages installed in your PHP environment.</b></i></p>
 	<hr>
 	<i>Clicking on a file in the tree will display the details about that file.</i>
 	<div dojoType="dojox.data.FileStore" url="stores/filestore_dojotree.php" jsId="fileStore" pathAsQueryParam="true"></div>
diff --git a/dojox/data/demos/demo_FileStore_dojoxdata_combo_grid.html b/dojox/data/demos/demo_FileStore_dojoxdata_combo_grid.html
index 9b18c8d..c4eae5a 100755
--- a/dojox/data/demos/demo_FileStore_dojoxdata_combo_grid.html
+++ b/dojox/data/demos/demo_FileStore_dojoxdata_combo_grid.html
@@ -52,7 +52,6 @@
 		is told that debug mode is off, and to parse all dojoType widgets when it has fully loaded.
 	-->
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: false, parseOnLoad: true, useCommentedJson: true"></script>
-	<script type="text/javascript" src="../../../dijit/dijit.js"></script>
 	<script>
 		dojo.require("dijit.Tree");
 		dojo.require("dijit.tree.ForestStoreModel");
@@ -78,7 +77,8 @@
 		Demo:  Lazy Loading File Browsing Store connected to multiple widgets
 	</h1>
 	<p>All the widgets used in this demo connect to the same filestore instance.  It is talking to a filestore rooted in the dojox/data/ sub-directory to make it fast handling when querying across all files.</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>
+	<p><i><b>This demo must be run from a web-server with PHP support enabled.  Without PHP support, this demo cannot function.  The Demo also requires PHP 
+	support for json_encode and json_decode.  Please be sure to have those packages installed in your PHP environment.</b></i></p>
 	<hr>
 
 	<div dojoType="dojox.data.FileStore" url="stores/filestore_dojoxdata.php" jsId="fileStore" pathAsQueryParam="true"></div>
diff --git a/dojox/data/demos/demo_GoogleFeedStore.html b/dojox/data/demos/demo_GoogleFeedStore.html
index 86c052c..6a4d115 100644
--- a/dojox/data/demos/demo_GoogleFeedStore.html
+++ b/dojox/data/demos/demo_GoogleFeedStore.html
@@ -39,13 +39,13 @@
 	<title>Google Feed Store</title>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
-	<script type="text/javascript" src="../GoogleSearchStore.js"></script>
-	<script type="text/javascript" src="../GoogleFeedStore.js"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.form.ComboBox");
 		dojo.require("dijit.form.FilteringSelect");
 		dojo.require("dojox.dtl");
 		dojo.require("dojox.dtl.ext-dojo.NodeList");
+		dojo.require("dojox.data.GoogleSearchStore");
+		dojo.require("dojox.data.GoogleFeedStore");
 		
 		dojo.addOnLoad(function(){
 			dojo.connect(dojo.byId("output"), "onclick", function(evt) {
diff --git a/dojox/data/demos/demo_GoogleSearchStore_Grid.html b/dojox/data/demos/demo_GoogleSearchStore_Grid.html
index e73ba0d..99dacaa 100644
--- a/dojox/data/demos/demo_GoogleSearchStore_Grid.html
+++ b/dojox/data/demos/demo_GoogleSearchStore_Grid.html
@@ -13,8 +13,6 @@
 	<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");
diff --git a/dojox/data/demos/stores/filestore_dojotree.php b/dojox/data/demos/stores/filestore_dojotree.php
index 24740a2..5e19385 100755
--- a/dojox/data/demos/stores/filestore_dojotree.php
+++ b/dojox/data/demos/stores/filestore_dojotree.php
@@ -113,7 +113,7 @@
 			$files = array_slice($files, 0, $count);
 		}
 
-		$result;
+		$result = new stdClass();
 		$result->total = $total;
 		$result->items = $files;
 		header("Content-Type", "text/json");
@@ -138,7 +138,7 @@
 				}
 
 				if (file_exists($fullPath)) {
-					$arr = split("/", $path);
+					$arr = explode("/", $path);
 					$size = count($arr);
 
 					if ($size > 0) {
diff --git a/dojox/data/dom.js b/dojox/data/dom.js
index 35d1d40..71385a0 100644
--- a/dojox/data/dom.js
+++ b/dojox/data/dom.js
@@ -1,4 +1,5 @@
-define("dojox/data/dom", ["dojo", "dojox", "dojox/xml/parser"], function(dojo, dojox) {
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojox/xml/parser"], 
+  function(kernel, lang, xmlParser) {
 
 //DOM type to int value for reference.
 //Ints make for more compact code than full constant names.
@@ -19,7 +20,9 @@ define("dojox/data/dom", ["dojo", "dojox", "dojox/xml/parser"], function(dojo, d
 //a better project, dojox.xml and experimental has been removed there.  Please update usage to the new package.
 dojo.deprecated("dojox.data.dom", "Use dojox.xml.parser instead.", "2.0");
 
-dojox.data.dom.createDocument = function(/*string?*/ str, /*string?*/ mimetype){
+var dataDom = lang.getObject("dojox.data.dom",true);
+
+dataDom.createDocument = function(/*string?*/ str, /*string?*/ mimetype){
 	//	summary:
 	//		cross-browser implementation of creating an XML document object.
 	//
@@ -30,14 +33,14 @@ dojox.data.dom.createDocument = function(/*string?*/ str, /*string?*/ 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{
-		return dojox.xml.parser.parse(str,mimetype); //DOMDocument.
+		return xmlParser.parse(str,mimetype); //DOMDocument.
 	}catch(e){
 		/*Squeltch errors like the old parser did.*/
 		return null;
 	}
 };
 
-dojox.data.dom.textContent = function(/*Node*/node, /*string?*/text){
+dataDom.textContent = function(/*Node*/node, /*string?*/text){
 	//	summary:
 	//		Implementation of the DOM Level 3 attribute; scan node for text
 	//	description:
@@ -50,13 +53,13 @@ dojox.data.dom.textContent = function(/*Node*/node, /*string?*/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){
-		return dojox.xml.parser.textContent(node, text); //string
+		return xmlParser.textContent(node, text); //string
 	}else{
-		return dojox.xml.parser.textContent(node); //string
+		return xmlParser.textContent(node); //string
 	}
 };
 
-dojox.data.dom.replaceChildren = function(/*Element*/node, /*Node || array*/ newChildren){
+dataDom.replaceChildren = function(/*Element*/node, /*Node || array*/ newChildren){
 	//	summary:
 	//		Removes all children of node and appends newChild. All the existing
 	//		children will be destroyed.
@@ -69,10 +72,10 @@ dojox.data.dom.replaceChildren = function(/*Element*/node, /*Node || array*/ new
 	//		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");
-	dojox.xml.parser.replaceChildren(node, newChildren);
+	xmlParser.replaceChildren(node, newChildren);
 };
 
-dojox.data.dom.removeChildren = function(/*Element*/node){
+dataDom.removeChildren = function(/*Element*/node){
 	//	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
@@ -83,16 +86,16 @@ dojox.data.dom.removeChildren = function(/*Element*/node){
 	return dojox.xml.parser.removeChildren(node); //int
 };
 
-dojox.data.dom.innerXML = function(/*Node*/node){
+dataDom.innerXML = function(/*Node*/node){
 	//	summary:
 	//		Implementation of MS's innerXML function.
 	//	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 dojox.xml.parser.innerXML(node); //string||null
+	return xmlParser.innerXML(node); //string||null
 };
 
-return dojox.data.dom;
+return dataDom;
 
 });
 
diff --git a/dojox/data/tests/stores/AndOrReadStore.js b/dojox/data/tests/stores/AndOrReadStore.js
index d4e3834..e054882 100755
--- a/dojox/data/tests/stores/AndOrReadStore.js
+++ b/dojox/data/tests/stores/AndOrReadStore.js
@@ -47,7 +47,7 @@ dojox.data.tests.stores.AndOrReadStore.getTestData = function(name){
 	var data = null;
 	if(name === "countries"){
 		if(dojo.isBrowser){
-			data = {url: dojo.moduleUrl("dojox", "data/tests/stores/countries.json").toString() };
+			data = {url: require.toUrl("dojo/tests/data/countries.json").toString() };
 		}else{
 			data = {data: {
 				identifier:'abbr',
@@ -295,7 +295,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 				//		paper.
 	
 				if(dojo.isBrowser){
-	                var store = new dojox.data.AndOrReadStore({url: dojo.moduleUrl("tests", "data/countries_commentFiltered.json").toString()});
+	                var store = new dojox.data.AndOrReadStore({url: require.toUrl("dojo/tests/data/countries_commentFiltered.json").toString()});
 	
 					var d = new doh.Deferred();
 					var onItem = function(item){
@@ -979,7 +979,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 				//		data with this store can bypass the JavaSceipt hijack noted in Fortify's
 				//		paper.
 				if(dojo.isBrowser){
-	                var store = new dojox.data.AndOrReadStore({url: dojo.moduleUrl("tests", "data/countries_commentFiltered.json").toString()});
+	                var store = new dojox.data.AndOrReadStore({url: require.toUrl("dojo/tests/data/countries_commentFiltered.json").toString()});
 	
 					var d = new doh.Deferred();
 					var onComplete = function(items, request){
@@ -1009,7 +1009,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 				//		data with this store can bypass the JavaSceipt hijack noted in Fortify's
 				//		paper.
 				if(dojo.isBrowser){
-	                var store = new dojox.data.AndOrReadStore({url: dojo.moduleUrl("tests", "data/countries_commentFiltered.json").toString()});
+	                var store = new dojox.data.AndOrReadStore({url: require.toUrl("dojo/tests/data/countries_commentFiltered.json").toString()});
 	
 					var d = new doh.Deferred();
 					var onComplete = function(items, request){
@@ -2712,7 +2712,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 				//		Added because of tracker: #2546
 	
 				if(dojo.isBrowser){
-					var store = new dojox.data.AndOrReadStore({url: dojo.moduleUrl("tests", "data/countries_idcollision.json").toString() });
+					var store = new dojox.data.AndOrReadStore({url: require.toUrl("dojo/tests/data/countries_idcollision.json").toString() });
 					var d = new doh.Deferred();
 					var onComplete = function(items, request){
 						//This is bad if this fires, this case should fail and not call onComplete.
@@ -3092,7 +3092,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 							t.assertTrue(store._arrayOfAllItems.length === 0);
 							t.assertTrue(store._loadFinished === false);
 							
-							store.url = dojo.moduleUrl("dojox", "data/tests/stores/countries_withNull.json").toString()
+							store.url = require.toUrl("dojo/tests/data/countries_withNull.json").toString()
 							function onItem2 (item){
 								var err;
 								try{
@@ -3148,7 +3148,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 							t.assertTrue(store._arrayOfAllItems.length === 0);
 							t.assertTrue(store._loadFinished === false);
 							
-							store.url = dojo.moduleUrl("dojox", "data/tests/stores/countries_withNull.json").toString()
+							store.url = require.toUrl("dojo/tests/data/countries_withNull.json").toString()
 							function onComplete (items){
 								var err;
 								try{
@@ -3206,7 +3206,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 							t.assertTrue(store._arrayOfAllItems.length === 0);
 							t.assertTrue(store._loadFinished === false);
 							
-							store._jsonFileUrl = dojo.moduleUrl("dojox", "data/tests/stores/countries_withNull.json").toString()
+							store._jsonFileUrl = require.toUrl("dojo/tests/data/countries_withNull.json").toString()
 							function onItem2 (item){
 								var err;
 								try{
diff --git a/dojox/data/tests/stores/AndOrWriteStore.js b/dojox/data/tests/stores/AndOrWriteStore.js
index a20c3f1..9a262d5 100755
--- a/dojox/data/tests/stores/AndOrWriteStore.js
+++ b/dojox/data/tests/stores/AndOrWriteStore.js
@@ -28,7 +28,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTestData = function(name){
 	var data = null;
 	if(name === "countries"){
 		if(dojo.isBrowser){
-			data = {url: dojo.moduleUrl("dojox", "data/tests/stores/countries.json").toString() };
+			data = {url: require.toUrl("dojo/tests/data/countries.json").toString() };
 		}else{
 			data = {data: {
 				identifier:'abbr',
@@ -301,7 +301,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 				//		paper.
 	
 				if(dojo.isBrowser){
-	                var store = new dojox.data.AndOrWriteStore({url: dojo.moduleUrl("tests", "data/countries_commentFiltered.json").toString()});
+	                var store = new dojox.data.AndOrWriteStore({url: require.toUrl("dojo/tests/data/countries_commentFiltered.json").toString()});
 	
 					var d = new doh.Deferred();
 					var onItem = function(item){
@@ -985,7 +985,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 				//		data with this store can bypass the JavaSceipt hijack noted in Fortify's
 				//		paper.
 				if(dojo.isBrowser){
-	                var store = new dojox.data.AndOrWriteStore({url: dojo.moduleUrl("tests", "data/countries_commentFiltered.json").toString()});
+	                var store = new dojox.data.AndOrWriteStore({url: require.toUrl("dojo/tests/data/countries_commentFiltered.json").toString()});
 	
 					var d = new doh.Deferred();
 					var onComplete = function(items, request){
@@ -1015,7 +1015,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 				//		data with this store can bypass the JavaSceipt hijack noted in Fortify's
 				//		paper.
 				if(dojo.isBrowser){
-	                var store = new dojox.data.AndOrWriteStore({url: dojo.moduleUrl("tests", "data/countries_commentFiltered.json").toString()});
+	                var store = new dojox.data.AndOrWriteStore({url: require.toUrl("dojo/tests/data/countries_commentFiltered.json").toString()});
 	
 					var d = new doh.Deferred();
 					var onComplete = function(items, request){
@@ -2718,7 +2718,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 				//		Added because of tracker: #2546
 	
 				if(dojo.isBrowser){
-					var store = new dojox.data.AndOrWriteStore({url: dojo.moduleUrl("tests", "data/countries_idcollision.json").toString() });
+					var store = new dojox.data.AndOrWriteStore({url: require.toUrl("dojo/tests/data/countries_idcollision.json").toString() });
 					var d = new doh.Deferred();
 					var onComplete = function(items, request){
 						//This is bad if this fires, this case should fail and not call onComplete.
@@ -3176,7 +3176,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 							t.assertTrue(store._arrayOfAllItems.length === 0);
 							t.assertTrue(store._loadFinished === false);
 							
-							store.url = dojo.moduleUrl("dojox", "data/tests/stores/countries_withNull.json").toString()
+							store.url = require.toUrl("dojo/tests/data/countries_withNull.json").toString()
 							function onItem2 (item){
 								var err;
 								try{
@@ -3232,7 +3232,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 							t.assertTrue(store._arrayOfAllItems.length === 0);
 							t.assertTrue(store._loadFinished === false);
 							
-							store.url = dojo.moduleUrl("dojox", "data/tests/stores/countries_withNull.json").toString()
+							store.url = require.toUrl("dojo/tests/data/countries_withNull.json").toString()
 							function onComplete (items){
 								var err;
 								try{
@@ -3290,7 +3290,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 							t.assertTrue(store._arrayOfAllItems.length === 0);
 							t.assertTrue(store._loadFinished === false);
 							
-							store._jsonFileUrl = dojo.moduleUrl("dojox", "data/tests/stores/countries_withNull.json").toString()
+							store._jsonFileUrl = require.toUrl("dojo/tests/data/countries_withNull.json").toString()
 							function onItem2 (item){
 								var err;
 								try{
diff --git a/dojox/data/tests/stores/AtomReadStore.js b/dojox/data/tests/stores/AtomReadStore.js
index 6c89ea1..06c71fe 100644
--- a/dojox/data/tests/stores/AtomReadStore.js
+++ b/dojox/data/tests/stores/AtomReadStore.js
@@ -3,7 +3,7 @@ dojo.require("dojox.data.AtomReadStore");
 dojo.require("dojo.data.api.Read");
 
 dojox.data.tests.stores.AtomReadStore.getBlog1Store = function(){
-	return new dojox.data.AtomReadStore({url: dojo.moduleUrl("dojox.data.tests", "stores/atom1.xml").toString()});
+	return new dojox.data.AtomReadStore({url: require.toUrl("dojox/data/tests/stores/atom1.xml").toString()});
 	//return new dojox.data.AtomReadStore({url: "/sos/feeds/blog.php"});
 };
 /*
@@ -263,7 +263,7 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 				var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
 				var passed = false;
 				try{
-					var value = store.getValue("NotAnItem", "foo");
+					var value = atomStore.getValue("NotAnItem", "foo");
 				}catch(e){
 					passed = true;
 				}
@@ -320,7 +320,7 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 				var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
 				var passed = false;
 				try{
-					var value = store.getValues("NotAnItem", "foo");
+					var value = atomStore.getValues("NotAnItem", "foo");
 				}catch(e){
 					passed = true;
 				}
diff --git a/dojox/data/tests/stores/CssClassStore.js b/dojox/data/tests/stores/CssClassStore.js
index d41e2b0..d5a0e60 100755
--- a/dojox/data/tests/stores/CssClassStore.js
+++ b/dojox/data/tests/stores/CssClassStore.js
@@ -13,7 +13,7 @@ dojox.data.tests.stores.CssClassStore.createStore = function(context){
 		if(!dojox.data.tests.stores.CssClassStore._loaded){
 			var head = dojo.doc.getElementsByTagName('head')[0];
 			var link = document.createElement('link');
-			link.href = dojo.moduleUrl('dojox.data.tests.stores', 'test1.css').toString();
+			link.href = require.toUrl('dojox/data/tests/stores/test1.css').toString();
 			link.rel = "stylesheet";
 			link.type = "text/css";
 			head.appendChild(link);
@@ -21,10 +21,10 @@ dojox.data.tests.stores.CssClassStore.createStore = function(context){
 			var text;
 			if(dojo.isIE){
 				style = document.createStyleSheet();
-				style.cssText = '@import "'+dojo.moduleUrl('dojox.data.tests.stores', 'test2.css').toString()+'";';
+				style.cssText = '@import "'+require.toUrl('dojox/data/tests/stores/test2.css').toString()+'";';
 			}else{
 				style = document.createElement('style');
-				text = document.createTextNode('@import "'+dojo.moduleUrl('dojox.data.tests.stores', 'test2.css').toString()+'";');
+				text = document.createTextNode('@import "'+require.toUrl('dojox/data/tests/stores/test2.css').toString()+'";');
 				style.appendChild(text);
 				head.appendChild(style);
 			}
@@ -56,7 +56,7 @@ dojox.data.tests.stores.CssClassStore.verifyItems = function(cssClassStore, item
 	if(items.length != compareArray.length){ return false; }
 	for(var i = 0; i < items.length; i++){
 		// Safari is dumb, see comment in CssClassStore about bug in selectorText
-		if(!(cssClassStore.getValue(items[i], attribute) === (dojo.isWebKit?compareArray[i].toLowerCase():compareArray[i]))){
+		if(!(cssClassStore.getValue(items[i], attribute) === compareArray[i])){
 			return false; //Boolean
 		}
 	}
@@ -292,12 +292,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			function onComplete(items, request){
 				done[0] = true;
 				t.is(1, items.length);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssClassStore about bug in selectorText
-					t.is('.linktestclass', cssClassStore.getValue(items[0], 'class'));
-				}else{
-					t.is('.linkTestClass', cssClassStore.getValue(items[0], 'class'));
-				}
+				t.is('.linkTestClass', cssClassStore.getValue(items[0], 'class'));
 				if(done[0] && done[1]){
 					d.callback(true);
 				}
@@ -306,12 +301,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			function onItem(item){
 				done[1] = true;
 				t.assertTrue(item !== null);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssClassStore about bug in selectorText
-					t.is('.embeddedtestclass', cssClassStore.getValue(item, 'class'));
-				}else{
-					t.is('.embeddedTestClass', cssClassStore.getValue(item, 'class'));
-				}
+				t.is('.embeddedTestClass', cssClassStore.getValue(item, 'class'));
 				if(done[0] && done[1]){
 					d.callback(true);
 				}
@@ -379,12 +369,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 
 			function dumpSecondFetch(items, request){
 				t.is(1, items.length);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssClassStore about bug in selectorText
-					t.is('.embeddedtestclass', cssClassStore.getValue(items[0], 'class'));
-				}else{
-					t.is('.embeddedTestClass', cssClassStore.getValue(items[0], 'class'));
-				}
+				t.is('.embeddedTestClass', cssClassStore.getValue(items[0], 'class'));
 				request.start = 0;
 				request.count = 2;
 				request.onComplete = dumpThirdFetch;
@@ -420,12 +405,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 				t.assertEqual(items.length, 1);
 				var label = cssClassStore.getLabel(items[0]);
 				t.assertTrue(label !== null);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssClassStore about bug in selectorText
-					t.assertEqual(".linktestclass", label);
-				}else{
-					t.assertEqual(".linkTestClass", label);
-				}
+				t.assertEqual(".linkTestClass", label);
 				d.callback(true);
 			}
 			cssClassStore.fetch({
@@ -467,14 +447,8 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item !== null);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssClassStore about bug in selectorText
-					t.is('.linktestclass', cssClassStore.getValue(item,'class'));
-					t.is('linktestclass', cssClassStore.getValue(item,'classSans'));
-				}else{
-					t.is('.linkTestClass', cssClassStore.getValue(item,'class'));
-					t.is('linkTestClass', cssClassStore.getValue(item,'classSans'));
-				}
+				t.is('.linkTestClass', cssClassStore.getValue(item,'class'));
+				t.is('linkTestClass', cssClassStore.getValue(item,'classSans'));
 				d.callback(true);
 			}
 			cssClassStore.fetch({
@@ -494,14 +468,8 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item !== null);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssClassStore about bug in selectorText
-					t.is('.importtestclass', cssClassStore.getValue(item,'class'));
-					t.is('importtestclass', cssClassStore.getValue(item,'classSans'));
-				}else{
-					t.is('.importTestClass', cssClassStore.getValue(item,'class'));
-					t.is('importTestClass', cssClassStore.getValue(item,'classSans'));
-				}
+				t.is('.importTestClass', cssClassStore.getValue(item,'class'));
+				t.is('importTestClass', cssClassStore.getValue(item,'classSans'));
 				d.callback(true);
 			}
 			cssClassStore.fetch({
@@ -524,12 +492,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 				var values = cssClassStore.getValues(item,'class');
 				t.assertTrue(dojo.isArray(values));
 				t.is(1, values.length);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssClassStore about bug in selectorText
-					t.is('.embeddedtestclass', values[0]);
-				}else{
-					t.is('.embeddedTestClass', values[0]);
-				}
+				t.is('.embeddedTestClass', values[0]);
 				d.callback(true);
 			}
 			cssClassStore.fetch({
@@ -605,14 +568,8 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item !== null);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssClassStore about bug in selectorText
-					t.assertTrue(cssClassStore.containsValue(item, 'class', '.embeddedtestclass'));
-					t.assertTrue(cssClassStore.containsValue(item, 'classSans', 'embeddedtestclass'));
-				}else{
-					t.assertTrue(cssClassStore.containsValue(item, 'class', '.embeddedTestClass'));
-					t.assertTrue(cssClassStore.containsValue(item, 'classSans', 'embeddedTestClass'));
-				}
+				t.assertTrue(cssClassStore.containsValue(item, 'class', '.embeddedTestClass'));
+				t.assertTrue(cssClassStore.containsValue(item, 'classSans', 'embeddedTestClass'));
 				t.assertTrue(!cssClassStore.containsValue(item, 'class', '.embeddedTestClass2'));
 				t.assertTrue(!cssClassStore.containsValue(item, 'classSans', 'embeddedTestClass	'));
 				t.assertTrue(!cssClassStore.containsValue(item, 'class', null));
@@ -705,12 +662,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			var d = new doh.Deferred();
 			function completed(items, request){
 				t.is(1, items.length);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssClassStore about bug in selectorText
-					t.assertTrue(cssClassStore.getValue(items[0], 'class') === '.linktestclass');
-				}else{
-					t.assertTrue(cssClassStore.getValue(items[0], 'class') === '.linkTestClass');
-				}
+				t.assertTrue(cssClassStore.getValue(items[0], 'class') === '.linkTestClass');
 				d.callback(true);
 			}
 
@@ -730,12 +682,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			var d = new doh.Deferred();
 			function completed(items, request){
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssClassStore about bug in selectorText
-					t.is(1, items.length);
-				}else{
-					t.is(0, items.length);
-				}
+				t.is(0, items.length);
 				d.callback(true);
 			}
 
@@ -916,16 +863,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			var d = new doh.Deferred();
 			function completed(items, request){
 				t.is(3, items.length);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssClassStore about bug in selectorText
-					t.assertTrue(cssClassStore.getIdentity(items[0]) === '.embeddedtestclass');
-					t.assertTrue(cssClassStore.getIdentity(items[1]) === '.importtestclass');
-					t.assertTrue(cssClassStore.getIdentity(items[2]) === '.linktestclass');
-				}else{
-					t.assertTrue(cssClassStore.getIdentity(items[0]) === '.embeddedTestClass');
-					t.assertTrue(cssClassStore.getIdentity(items[1]) === '.importTestClass');
-					t.assertTrue(cssClassStore.getIdentity(items[2]) === '.linkTestClass');
-				}
+				t.assertTrue(cssClassStore.getIdentity(items[0]) === '.embeddedTestClass');
+				t.assertTrue(cssClassStore.getIdentity(items[1]) === '.importTestClass');
+				t.assertTrue(cssClassStore.getIdentity(items[2]) === '.linkTestClass');
 				d.callback(true);
 			}
 			//Get everything...
diff --git a/dojox/data/tests/stores/CssRuleStore.js b/dojox/data/tests/stores/CssRuleStore.js
index 899f7f4..b56c7a7 100755
--- a/dojox/data/tests/stores/CssRuleStore.js
+++ b/dojox/data/tests/stores/CssRuleStore.js
@@ -13,7 +13,7 @@ dojox.data.tests.stores.CssRuleStore.createStore = function(context){
 		if(!dojox.data.tests.stores.CssRuleStore._loaded){
 			var head = dojo.doc.getElementsByTagName('head')[0];
 			var link = document.createElement('link');
-			link.href = dojo.moduleUrl('dojox.data.tests.stores', 'test1.css').toString();
+			link.href = require.toUrl('dojox/data/tests/stores/test1.css').toString();
 			link.rel = "stylesheet";
 			link.type = "text/css";
 			head.appendChild(link);
@@ -21,10 +21,10 @@ dojox.data.tests.stores.CssRuleStore.createStore = function(context){
 			var text;
 			if(dojo.isIE){
 				style = document.createStyleSheet();
-				style.cssText = '@import "'+dojo.moduleUrl('dojox.data.tests.stores', 'test2.css').toString()+'";';
+				style.cssText = '@import "'+require.toUrl('dojox/data/tests/stores/test2.css').toString()+'";';
 			}else{
 				style = document.createElement('style');
-				text = document.createTextNode('@import "'+dojo.moduleUrl('dojox.data.tests.stores', 'test2.css').toString()+'";');
+				text = document.createTextNode('@import "'+require.toUrl('dojox/data/tests/stores/test2.css').toString()+'";');
 				style.appendChild(text);
 				head.appendChild(style);
 			}
@@ -55,7 +55,7 @@ dojox.data.tests.stores.CssRuleStore.verifyItems = function(cssRuleStore, items,
 	//		the same as the compareArray
 	if(items.length != compareArray.length){ return false; }
 	for(var i = 0; i < items.length; i++){
-		if(!(cssRuleStore.getValue(items[i], attribute) === (dojo.isWebKit?compareArray[i].toLowerCase():compareArray[i]))){
+		if(!(cssRuleStore.getValue(items[i], attribute) === compareArray[i])){
 			return false; //Boolean
 		}
 	}
@@ -291,12 +291,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			function onComplete(items, request){
 				done[0] = true;
 				t.is(1, items.length);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssRuleStore about bug in selectorText
-					t.is('.embeddedtestclass', cssRuleStore.getValue(items[0], 'selector'));
-				}else{
-					t.is('.embeddedTestClass', cssRuleStore.getValue(items[0], 'selector'));
-				}
+				t.is('.embeddedTestClass', cssRuleStore.getValue(items[0], 'selector'));
 				if(done[0] && done[1]){
 					d.callback(true);
 				}
@@ -305,12 +300,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			function onItem(item){
 				done[1] = true;
 				t.assertTrue(item !== null);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssRuleStore about bug in selectorText
-					t.is('.linktestclass .test', cssRuleStore.getValue(item, 'selector'));
-				}else{
-					t.is('.linkTestClass .test', cssRuleStore.getValue(item, 'selector'));
-				}
+				t.is('.linkTestClass .test', cssRuleStore.getValue(item, 'selector'));
 				if(done[0] && done[1]){
 					d.callback(true);
 				}
@@ -378,12 +368,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			
 			function dumpSecondFetch(items, request){
 				t.is(1, items.length);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssRuleStore about bug in selectorText
-					t.is('.embeddedtestclass', cssRuleStore.getValue(items[0], 'selector'));
-				}else{
-					t.is('.embeddedTestClass', cssRuleStore.getValue(items[0], 'selector'));
-				}
+				t.is('.embeddedTestClass', cssRuleStore.getValue(items[0], 'selector'));
 				request.start = 0;
 				request.count = 2;
 				request.onComplete = dumpThirdFetch;
@@ -420,12 +405,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 				t.assertEqual(items.length, 1);
 				var label = cssRuleStore.getLabel(items[0]);
 				t.assertTrue(label !== null);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssRuleStore about bug in selectorText
-					t.assertEqual(".linktestclass", label);
-				}else{
-					t.assertEqual(".linkTestClass", label);
-				}
+				t.assertEqual(".linkTestClass", label);
 				d.callback(true);
 			}
 			cssRuleStore.fetch({
@@ -467,12 +447,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item !== null);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssRuleStore about bug in selectorText
-					t.is('.linktestclass', cssRuleStore.getValue(item,'selector'));
-				}else{
-					t.is('.linkTestClass', cssRuleStore.getValue(item,'selector'));
-				}
+				t.is('.linkTestClass', cssRuleStore.getValue(item,'selector'));
 				t.assertTrue(cssRuleStore.getValue(item, 'parentStyleSheetHref').match('dojox/data/tests/stores/test1.css'));
 				d.callback(true);
 			}
@@ -493,12 +468,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item !== null);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssRuleStore about bug in selectorText
-					t.is('.importtestclass', cssRuleStore.getValue(item,'selector'));
-				}else{
-					t.is('.importTestClass', cssRuleStore.getValue(item,'selector'));
-				}
+				t.is('.importTestClass', cssRuleStore.getValue(item,'selector'));
 				t.assertTrue(cssRuleStore.getValue(item, 'parentStyleSheetHref').match('dojox/data/tests/stores/test2.css'));
 				d.callback(true);
 			}
@@ -522,12 +492,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 				var values = cssRuleStore.getValues(item,'selector');
 				t.assertTrue(dojo.isArray(values));
 				t.is(1, values.length);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssRuleStore about bug in selectorText
-					t.is('.embeddedtestclass', values[0]);
-				}else{
-					t.is('.embeddedTestClass', values[0]);
-				}
+				t.is('.embeddedTestClass', values[0]);
 				d.callback(true);
 			}
 			cssRuleStore.fetch({
@@ -603,14 +568,8 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item !== null);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssRuleStore about bug in selectorText
-					t.assertTrue(cssRuleStore.containsValue(item, 'selector', '.embeddedtestclass'));
-					t.assertTrue(cssRuleStore.containsValue(item, 'classes', '.embeddedtestclass'));
-				}else{
-					t.assertTrue(cssRuleStore.containsValue(item, 'selector', '.embeddedTestClass'));
-					t.assertTrue(cssRuleStore.containsValue(item, 'classes', '.embeddedTestClass'));
-				}
+				t.assertTrue(cssRuleStore.containsValue(item, 'selector', '.embeddedTestClass'));
+				t.assertTrue(cssRuleStore.containsValue(item, 'classes', '.embeddedTestClass'));
 				t.assertTrue(!cssRuleStore.containsValue(item, 'selector', '.embeddedTestClass2'));
 				t.assertTrue(!cssRuleStore.containsValue(item, 'classes', 'embeddedTestClass	'));
 				t.assertTrue(!cssRuleStore.containsValue(item, 'selector', null));
@@ -707,12 +666,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			var d = new doh.Deferred();
 			function completed(items, request){
 				t.is(1, items.length);
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssRuleStore about bug in selectorText
-					t.assertTrue(cssRuleStore.getValue(items[0], 'selector') === '.linktestclass');
-				}else{
-					t.assertTrue(cssRuleStore.getValue(items[0], 'selector') === '.linkTestClass');
-				}
+				t.assertTrue(cssRuleStore.getValue(items[0], 'selector') === '.linkTestClass');
 				d.callback(true);
 			}
 
@@ -732,12 +686,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 			var d = new doh.Deferred();
 			function completed(items, request){
-				if(dojo.isWebKit){
-					// Safari is dumb, see comment in CssRuleStore about bug in selectorText
-					t.is(1, items.length);
-				}else{
-					t.is(0, items.length);
-				}
+				t.is(0, items.length);
 				d.callback(true);
 			}
 
diff --git a/dojox/data/tests/stores/CsvStore.js b/dojox/data/tests/stores/CsvStore.js
index d9a705d..c8f5d75 100644
--- a/dojox/data/tests/stores/CsvStore.js
+++ b/dojox/data/tests/stores/CsvStore.js
@@ -11,7 +11,7 @@ dojox.data.tests.stores.CsvStore.getDatasource = function(filepath){
 
 	var dataSource = {};
 	if(dojo.isBrowser){
-		dataSource.url = dojo.moduleUrl("dojox.data.tests", filepath).toString();
+		dataSource.url = require.toUrl("dojox/data/tests/"+filepath).toString();
 	}else{
 		// When running tests in Rhino, xhrGet is not available,
 		// so we have the file data in the code below.
diff --git a/dojox/data/tests/stores/FileStore.js b/dojox/data/tests/stores/FileStore.js
index bf4f972..eda1177 100755
--- a/dojox/data/tests/stores/FileStore.js
+++ b/dojox/data/tests/stores/FileStore.js
@@ -5,7 +5,7 @@ dojo.require("dojo.data.api.Identity");
 
 
 dojox.data.tests.stores.FileStore.getGeoStore = function(){
-	return new dojox.data.FileStore({url: dojo.moduleUrl("dojox.data.tests.stores", "filestore_dojoxdatageo.php").toString(), pathAsQueryParam: true});
+	return new dojox.data.FileStore({url: require.toUrl("dojox/data/tests/stores/filestore_dojoxdatageo.php").toString(), pathAsQueryParam: true});
 };
 
 
diff --git a/dojox/data/tests/stores/HtmlStore.js b/dojox/data/tests/stores/HtmlStore.js
index dacba8f..cabb060 100644
--- a/dojox/data/tests/stores/HtmlStore.js
+++ b/dojox/data/tests/stores/HtmlStore.js
@@ -5,27 +5,27 @@ dojo.require("dojo.data.api.Identity");
 
 
 dojox.data.tests.stores.HtmlStore.getBooks3Store = function(){
-	return new dojox.data.HtmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books3.html").toString(), dataId: "books3"});
+	return new dojox.data.HtmlStore({url: require.toUrl("dojox/data/tests/stores/books3.html").toString(), dataId: "books3"});
 };
 
 dojox.data.tests.stores.HtmlStore.getBooks3StoreOnCreate = function(){
-	return new dojox.data.HtmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books3.html").toString(), dataId: "books3", fetchOnCreate: true});
+	return new dojox.data.HtmlStore({url: require.toUrl("dojox/data/tests/stores/books3.html").toString(), dataId: "books3", fetchOnCreate: true});
 };
 
 dojox.data.tests.stores.HtmlStore.getBooks2Store = function(){
-	return new dojox.data.HtmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books2.html").toString(), dataId: "books2"});
+	return new dojox.data.HtmlStore({url: require.toUrl("dojox/data/tests/stores/books2.html").toString(), dataId: "books2"});
 };
 
 dojox.data.tests.stores.HtmlStore.getBooksStore = function(){
-	return new dojox.data.HtmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books.html").toString(), dataId: "books"});
+	return new dojox.data.HtmlStore({url: require.toUrl("dojox/data/tests/stores/books.html").toString(), dataId: "books"});
 };
 
 dojox.data.tests.stores.HtmlStore.getBooksStoreWhitespace = function(){
-	return new dojox.data.HtmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/booksWhitespace.html").toString(), dataId: "books", trimWhitespace: true});
+	return new dojox.data.HtmlStore({url: require.toUrl("dojox/data/tests/stores/booksWhitespace.html").toString(), dataId: "books", trimWhitespace: true});
 };
 
 dojox.data.tests.stores.HtmlStore.getBooks3StoreWhitespace = function(){
-	return new dojox.data.HtmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books3Whitespace.html").toString(), dataId: "books3", trimWhitespace: true});
+	return new dojox.data.HtmlStore({url: require.toUrl("dojox/data/tests/stores/books3Whitespace.html").toString(), dataId: "books3", trimWhitespace: true});
 };
 
 doh.register("dojox.data.tests.stores.HtmlStore",
diff --git a/dojox/data/tests/stores/HtmlTableStore.js b/dojox/data/tests/stores/HtmlTableStore.js
index e8234a3..84e09d2 100644
--- a/dojox/data/tests/stores/HtmlTableStore.js
+++ b/dojox/data/tests/stores/HtmlTableStore.js
@@ -5,11 +5,11 @@ dojo.require("dojo.data.api.Identity");
 
 
 dojox.data.tests.stores.HtmlTableStore.getBooks2Store = function(){
-	return new dojox.data.HtmlTableStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books2.html").toString(), tableId: "books2"});
+	return new dojox.data.HtmlTableStore({url: require.toUrl("dojox/data/tests/stores/books2.html").toString(), tableId: "books2"});
 };
 
 dojox.data.tests.stores.HtmlTableStore.getBooksStore = function(){
-	return new dojox.data.HtmlTableStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books.html").toString(), tableId: "books"});
+	return new dojox.data.HtmlTableStore({url: require.toUrl("dojox/data/tests/stores/books.html").toString(), tableId: "books"});
 };
 
 doh.register("dojox.data.tests.stores.HtmlTableStore",
diff --git a/dojox/data/tests/stores/JsonRestStore.js b/dojox/data/tests/stores/JsonRestStore.js
index 4af35aa..34e7314 100644
--- a/dojox/data/tests/stores/JsonRestStore.js
+++ b/dojox/data/tests/stores/JsonRestStore.js
@@ -10,7 +10,7 @@ dojox.data.tests.stores.JsonRestStore.error = function(t, d, errData){
 	//		The error callback function to be used for all of the tests.
 	d.errback(errData);
 }
-testServices = new dojox.rpc.Service(dojo.moduleUrl("dojox.rpc.tests.resources", "test.smd"));
+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});
 
diff --git a/dojox/data/tests/stores/KeyValueStore.js b/dojox/data/tests/stores/KeyValueStore.js
index 0365ba0..2e40324 100644
--- a/dojox/data/tests/stores/KeyValueStore.js
+++ b/dojox/data/tests/stores/KeyValueStore.js
@@ -12,7 +12,7 @@ dojox.data.tests.stores.KeyValueStore.getDatasource = function(type){
 	var dataSource = {};
 	var filepath = "stores/properties.js";
 	if(dojo.isBrowser){
-		dataSource.url = dojo.moduleUrl("dojox.data.tests", filepath).toString();
+		dataSource.url = require.toUrl("dojox/data/tests/" + filepath).toString();
 	}else{
 		// When running tests in Rhino, xhrGet is not available,
 		// so we have the file data in the code below.
diff --git a/dojox/data/tests/stores/OpenSearchStore.js b/dojox/data/tests/stores/OpenSearchStore.js
index 67bb616..c755223 100644
--- a/dojox/data/tests/stores/OpenSearchStore.js
+++ b/dojox/data/tests/stores/OpenSearchStore.js
@@ -4,23 +4,23 @@ dojo.require("dojo.data.api.Read");
 
 
 dojox.data.tests.stores.OpenSearchStore.getAtomStore = function(){
-	var store = new dojox.data.OpenSearchStore({url: dojo.moduleUrl('dojox.data.tests.stores', 'opensearch_atom.xml').toString()});
+	var store = new dojox.data.OpenSearchStore({url: require.toUrl('dojox/data/tests/stores/opensearch_atom.xml').toString()});
 	store._createSearchUrl = function(request){
-		return dojo.moduleUrl('dojox.data.tests.stores', 'atom1.xml').toString();
+		return require.toUrl('dojox/data/tests/stores/atom1.xml').toString();
 	};
 	return store;
 };
 dojox.data.tests.stores.OpenSearchStore.getRSSStore = function(){
-	var store = new dojox.data.OpenSearchStore({url: dojo.moduleUrl('dojox.data.tests.stores', 'opensearch_rss.xml').toString()});
+	var store = new dojox.data.OpenSearchStore({url: require.toUrl('dojox/data/tests/stores/opensearch_rss.xml').toString()});
 	store._createSearchUrl = function(request){
-		return dojo.moduleUrl('dojox.data.tests.stores', 'rss1.xml').toString();
+		return require.toUrl('dojox/data/tests/stores/rss1.xml').toString();
 	};
 	return store;
 };
 dojox.data.tests.stores.OpenSearchStore.getHTMLStore = function(){
-	var store = new dojox.data.OpenSearchStore({url: dojo.moduleUrl('dojox.data.tests.stores', 'opensearch_html.xml').toString(), itemPath: "table tbody tr"});
+	var store = new dojox.data.OpenSearchStore({url: require.toUrl('dojox/data/tests/stores/opensearch_html.xml').toString(), itemPath: "table tbody tr"});
 	store._createSearchUrl = function(request){
-		return dojo.moduleUrl('dojox.data.tests.stores', 'books.html').toString();
+		return require.toUrl('dojox/data/tests/stores/books.html').toString();
 	};
 	return store;
 };
diff --git a/dojox/data/tests/stores/OpmlStore.js b/dojox/data/tests/stores/OpmlStore.js
index 8580b0b..4630938 100644
--- a/dojox/data/tests/stores/OpmlStore.js
+++ b/dojox/data/tests/stores/OpmlStore.js
@@ -11,7 +11,7 @@ dojox.data.tests.stores.OpmlStore.getDatasource = function(filepath){
 	
 	var dataSource = {};
 	if(dojo.isBrowser){
-		dataSource.url = dojo.moduleUrl("dojox.data.tests", filepath).toString();
+		dataSource.url = require.toUrl("dojox/data/tests/" + filepath).toString();
 	}else{
 		// When running tests in Rhino, xhrGet is not available,
 		// so we have the file data in the code below.
diff --git a/dojox/data/tests/stores/QueryReadStore.js b/dojox/data/tests/stores/QueryReadStore.js
index 9ba6064..a01d786 100644
--- a/dojox/data/tests/stores/QueryReadStore.js
+++ b/dojox/data/tests/stores/QueryReadStore.js
@@ -6,7 +6,7 @@ dojo.require("dojo.data.api.Read");
 
 dojox.data.tests.stores.QueryReadStore.getStore = function(){
 	return new dojox.data.QueryReadStore({
-			url: dojo.moduleUrl("dojox.data.tests", "stores/QueryReadStore.php").toString()
+			url: require.toUrl("dojox/data/tests/stores/QueryReadStore.php").toString()
 		});
 };
 
diff --git a/dojox/data/tests/stores/ServiceStore.js b/dojox/data/tests/stores/ServiceStore.js
index 98728bb..c1da408 100644
--- a/dojox/data/tests/stores/ServiceStore.js
+++ b/dojox/data/tests/stores/ServiceStore.js
@@ -9,7 +9,7 @@ dojox.data.tests.stores.ServiceStore.error = function(t, d, errData){
 	//		The error callback function to be used for all of the tests.
 	d.errback(errData);
 }
-var testServices = new dojox.rpc.Service(dojo.moduleUrl("dojox.rpc.tests.resources", "test.smd"));
+var testServices = new dojox.rpc.Service(require.toUrl("dojox/rpc/tests/resources/test.smd"));
 var jsonStore = new dojox.data.ServiceStore({service:testServices.jsonRestStore});
 
 doh.register("dojox.data.tests.stores.ServiceStore",
diff --git a/dojox/data/tests/stores/SnapLogicStore.js b/dojox/data/tests/stores/SnapLogicStore.js
index 57759f8..25dfe29 100644
--- a/dojox/data/tests/stores/SnapLogicStore.js
+++ b/dojox/data/tests/stores/SnapLogicStore.js
@@ -2,7 +2,7 @@ dojo.provide("dojox.data.tests.stores.SnapLogicStore");
 dojo.require("dojox.data.SnapLogicStore");
 dojo.require("dojo.data.api.Read");
 
-dojox.data.tests.stores.SnapLogicStore.pipelineUrl = dojo.moduleUrl("dojox.data.tests", "stores/snap_pipeline.php").toString();
+dojox.data.tests.stores.SnapLogicStore.pipelineUrl = require.toUrl("dojox/data/tests/stores/snap_pipeline.php").toString();
 dojox.data.tests.stores.SnapLogicStore.pipelineSize = 14;
 dojox.data.tests.stores.SnapLogicStore.attributes = ["empno", "ename", "job", "hiredate", "sal", "comm", "deptno"];
 
diff --git a/dojox/data/tests/stores/XmlStore.js b/dojox/data/tests/stores/XmlStore.js
index e4121b4..79a589d 100644
--- a/dojox/data/tests/stores/XmlStore.js
+++ b/dojox/data/tests/stores/XmlStore.js
@@ -6,27 +6,27 @@ dojo.require("dojo.data.api.Identity");
 
 
 dojox.data.tests.stores.XmlStore.getBooks3Store = function(){
-	return new dojox.data.XmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books2.xml").toString(), label: "title", keyAttribute: "isbn"});
+	return new dojox.data.XmlStore({url: require.toUrl("dojox/data/tests/stores/books2.xml").toString(), label: "title", keyAttribute: "isbn"});
 };
 
 dojox.data.tests.stores.XmlStore.getBooks2Store = function(){
-	return new dojox.data.XmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books2.xml").toString(), label: "title"});
+	return new dojox.data.XmlStore({url: require.toUrl("dojox/data/tests/stores/books2.xml").toString(), label: "title"});
 };
 
 dojox.data.tests.stores.XmlStore.getBooks2StorePC = function(){
-	return new dojox.data.XmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books2.xml").toString(), label: "title", urlPreventCache: false});
+	return new dojox.data.XmlStore({url: require.toUrl("dojox/data/tests/stores/books2.xml").toString(), label: "title", urlPreventCache: false});
 };
 
 dojox.data.tests.stores.XmlStore.getBooksStore = function(){
-	return new dojox.data.XmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books.xml").toString(), label: "title"});
+	return new dojox.data.XmlStore({url: require.toUrl("dojox/data/tests/stores/books.xml").toString(), label: "title"});
 };
 
 dojox.data.tests.stores.XmlStore.getCDataTestStore = function(){
-	return new dojox.data.XmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/cdata_test.xml").toString(), label: "title"});
+	return new dojox.data.XmlStore({url: require.toUrl("dojox/data/tests/stores/cdata_test.xml").toString(), label: "title"});
 };
 
 dojox.data.tests.stores.XmlStore.getGeographyStore = function(){
-	return new dojox.data.XmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/geography2.xml").toString(), label: "text", keyAttribute: "text", attributeMap: {text: '@text'}, rootItem: "geography"});
+	return new dojox.data.XmlStore({url: require.toUrl("dojox/data/tests/stores/geography2.xml").toString(), label: "text", keyAttribute: "text", attributeMap: {text: '@text'}, rootItem: "geography"});
 };
 
 doh.register("dojox.data.tests.stores.XmlStore",
@@ -157,6 +157,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			store.fetch({query:{isbn:"?9B574"}, onComplete: onComplete, onError: onError});
 			return d; //Object
 		},
+		
 		function testReadAPI_fetch_pattern1(t){
 			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
@@ -278,12 +279,29 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			store.fetch({query:{isbn:"?9B574"}, queryOptions: {ignoreCase: false}, onComplete: onComplete, onError: onError});
 			return d; //Object
 		},
+		function testReadAPI_fetch_regexp(t){
+			//	summary:
+			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
+			//	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();
+			function onComplete(items, request) {
+				t.assertEqual(1, items.length);
+				d.callback(true);
+			}
+			function onError(error, request) {
+				d.errback(error);
+			}
+			store.fetch({query:{isbn: new RegExp("^.9B574$")}, onComplete: onComplete, onError: onError});
+			return d; //Object
+		},
 		function testReadAPI_fetch_all_rootItem(t){
 			//	summary:
 			//		Simple test of fetching all xml items through an XML element called isbn
 			//	description:
 			//		Simple test of fetching all xml items through an XML element called isbn
-			var store = new dojox.data.XmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books3.xml").toString(),
+			var store = new dojox.data.XmlStore({url: require.toUrl("dojox/data/tests/stores/books3.xml").toString(),
 				rootItem:"book"});
 
 			var d = new doh.Deferred();
@@ -298,7 +316,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_withAttrMap_all(t){
-			var store = new dojox.data.XmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books_isbnAttr.xml").toString(),
+			var store = new dojox.data.XmlStore({url: require.toUrl("dojox/data/tests/stores/books_isbnAttr.xml").toString(),
 				attributeMap: {"book.isbn": "@isbn"}});
 
 			var d = new doh.Deferred();
@@ -314,7 +332,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_withAttrMap_one(t){
-			var store = new dojox.data.XmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books_isbnAttr.xml").toString(),
+			var store = new dojox.data.XmlStore({url: require.toUrl("dojox/data/tests/stores/books_isbnAttr.xml").toString(),
 				attributeMap: {"book.isbn": "@isbn"}});
 
 			var d = new doh.Deferred();
@@ -334,7 +352,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
-			var store = new dojox.data.XmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books_isbnAttr2.xml").toString(),
+			var store = new dojox.data.XmlStore({url: require.toUrl("dojox/data/tests/stores/books_isbnAttr2.xml").toString(),
 				attributeMap: {"book.isbn": "@isbn"}});
 			var d = new doh.Deferred();
 			function onComplete(items, request) {
@@ -352,7 +370,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
-			var store = new dojox.data.XmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books_isbnAttr2.xml").toString(),
+			var store = new dojox.data.XmlStore({url: require.toUrl("dojox/data/tests/stores/books_isbnAttr2.xml").toString(),
 				attributeMap: {"book.isbn": "@isbn"}});
 			var d = new doh.Deferred();
 			function onComplete(items, request) {
@@ -370,7 +388,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
-			var store = new dojox.data.XmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books_isbnAttr2.xml").toString(),
+			var store = new dojox.data.XmlStore({url: require.toUrl("dojox/data/tests/stores/books_isbnAttr2.xml").toString(),
 				attributeMap: {"book.isbn": "@isbn"}});
 			var d = new doh.Deferred();
 			function onComplete(items, request) {
diff --git a/dojox/data/tests/stores/filestore_dojoxdatageo.php b/dojox/data/tests/stores/filestore_dojoxdatageo.php
index ad10449..8a8cbdc 100755
--- a/dojox/data/tests/stores/filestore_dojoxdatageo.php
+++ b/dojox/data/tests/stores/filestore_dojoxdatageo.php
@@ -112,7 +112,7 @@
 			$files = array_slice($files, 0, $count);
 		}
 
-		$result;
+		$result = new stdClass();
 		$result->total = $total;
 		$result->items = $files;
 		header("Content-Type", "text/json");
@@ -137,7 +137,7 @@
 				}
 
 				if (file_exists($fullPath)) {
-					$arr = split("/", $path);
+					$arr = explode("/", $path);
 					$size = count($arr);
 
 					if ($size > 0) {
diff --git a/dojox/data/tests/stores/filestore_funcs.php b/dojox/data/tests/stores/filestore_funcs.php
index ff61139..5d4408b 100755
--- a/dojox/data/tests/stores/filestore_funcs.php
+++ b/dojox/data/tests/stores/filestore_funcs.php
@@ -51,7 +51,7 @@
 					$rxp = $rxp.$c;
 			}
 		}
-		return "(".$rxp."$)";
+		return "/(".$rxp."$)/";
 	}
 
 	/**
@@ -350,9 +350,9 @@
 		} else {
 			if ($rExp != null && is_string($possibleValue)) {
 				if ($ignoreCase) {
-					$matched = eregi($rExp, $possibleValue);
+					$matched = preg_match($rExp . 'i', $possibleValue);
 				} else {
-					$matched = ereg($rExp, $possibleValue);
+					$matched = preg_match($rExp, $possibleValue);
 				}
 
 			} else {
diff --git a/dojox/data/tests/stores/snap_pipeline.php b/dojox/data/tests/stores/snap_pipeline.php
index 59e72cb..9a8b53b 100644
--- a/dojox/data/tests/stores/snap_pipeline.php
+++ b/dojox/data/tests/stores/snap_pipeline.php
@@ -19,7 +19,7 @@ $rows = array(array("7369", '"SMITH,CLERK"', "7902", '"1993-06-13"', "800.00", "
 
 $prefix = htmlentities($_GET["sn_stream_header"]);
 
-if($_GET["sn_count"]) {
+if(@$_GET["sn_count"]) {
     if($_GET["sn_count"] == "records"){
         echo $prefix . "([[" . count($rows) . "]])";
     } else {
@@ -28,13 +28,13 @@ if($_GET["sn_count"]) {
         exit(0);
     }
 } else {
-    if($_GET["sn_start"]) {
+    if(@$_GET["sn_start"]) {
         $start = $_GET["sn_start"];
     } else {
         $start = 1;
     }
 
-    if($_GET["sn_limit"]) {
+    if(@$_GET["sn_limit"]) {
         $limit = $_GET["sn_limit"];
     } else {
         $limit = count($rows);
diff --git a/dojox/date/buddhist.js b/dojox/date/buddhist.js
index 8a3cc80..4140c73 100644
--- a/dojox/date/buddhist.js
+++ b/dojox/date/buddhist.js
@@ -1,24 +1,22 @@
-dojo.provide("dojox.date.buddhist");
-dojo.experimental("dojox.date.buddhist");
+define(["dojo/_base/kernel", "dojo/date", "./buddhist/Date"], function(dojo, dd, buddhistDate){
+	dojo.getObject("date.buddhist", true, dojox);
+	dojo.experimental("dojox.date.buddhist");
 
-dojo.require("dojox.date.buddhist.Date");
-dojo.require("dojo.date"); // for compare
-	
 // Utility methods to do arithmetic calculations with buddhist.Dates
 
 dojox.date.buddhist.getDaysInMonth = function(/*buddhist.Date*/dateObject){
-	return dojo.date.getDaysInMonth(dateObject.toGregorian());
+	return dd.getDaysInMonth(dateObject.toGregorian());
 };
 
 dojox.date.buddhist.isLeapYear = function(/*buddhist.Date*/dateObject){
-	return dojo.date.isLeapYear(dateObject.toGregorian());
+	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:
+	//	summary:
 	//		Compare two buddhist date objects by date, time, or both.
-	return dojo.date.compare(date1,date2, portion); //FIXME
+	return dd.compare(date1,date2, portion); // int
 };
 
 
@@ -35,7 +33,7 @@ dojox.date.buddhist.add = function(/*dojox.date.buddhist.Date*/date, /*String*/i
 	//	amount:
 	//		How much to add to the date.
 
-	var newBuddDate = new dojox.date.buddhist.Date(date);
+	var newBuddDate = new buddhistDate(date);
 
 	switch(interval){
 		case "day":
@@ -88,13 +86,13 @@ dojox.date.buddhist.add = function(/*dojox.date.buddhist.Date*/date, /*String*/i
 			newBuddDate.setHours(date.getHours() + amount );
 			break;
 		case "minute":
-			newBuddDate.setMinutes(date.getMinutes() + amount );
+			newBuddDate._addMinutes(amount);
 			break;
 		case "second":
-			newBuddDate.setSeconds(date.getSeconds() + amount );
+			newBuddDate._addSeconds(amount);
 			break;
 		case "millisecond":
-			newBuddDate.setMilliseconds(date.getMilliseconds() + amount );
+			newBuddDate._addMilliseconds(amount);
 			break;
 	}
 	return newBuddDate; // dojox.date.buddhist.Date
@@ -103,7 +101,7 @@ dojox.date.buddhist.add = function(/*dojox.date.buddhist.Date*/date, /*String*/i
 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:
-	//        date1 - date2
+	//        date2 - date1
 	//	 date2 is hebrew.Date object.  If not specified, the current hebrew.Date is used.
 	//	interval:
 	//		A string representing the interval.  One of the following:
@@ -111,9 +109,9 @@ dojox.date.buddhist.difference = function(/*dojox.date.buddhist.Date*/date1, /*d
 	//			"millisecond",  "week", "weekday"
 	//		Defaults to "day".
 	
-	date2 = date2 || new dojox.date.buddhist.Date();
+	date2 = date2 || new buddhistDate();
 	interval = interval || "day";
-	var yearDiff = date1.getFullYear() - date2.getFullYear();
+	var yearDiff = date2.getFullYear() - date1.getFullYear();
 	var delta = 1; // Integer return value
 	switch(interval){
 		case "weekday":
@@ -127,14 +125,14 @@ dojox.date.buddhist.difference = function(/*dojox.date.buddhist.Date*/date1, /*d
 			}else{
 				// Weeks plus spare change (< 7 days)
 				var adj = 0;
-				var aDay = date2.getDay();
-				var bDay = date1.getDay();
+				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 dojox.date.buddhist.Date(date1);
+				var dtMark = new buddhistDate(date2);
 				dtMark.setDate(dtMark.getDate(true)+(weeks*7));
 				var dayMark = dtMark.getDay();
 	
@@ -193,8 +191,8 @@ dojox.date.buddhist.difference = function(/*dojox.date.buddhist.Date*/date1, /*d
 			delta = yearDiff;
 			break;
 		case "month":
-			var startdate =  (date1.toGregorian() > date2.toGregorian()) ? date1 : date2; // more
-			var enddate = (date1.toGregorian() > date2.toGregorian()) ? date2 : date1;
+			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();
@@ -210,7 +208,7 @@ dojox.date.buddhist.difference = function(/*dojox.date.buddhist.Date*/date1, /*d
 					delta += 12;
 				}
 			}
-			if (date1.toGregorian() < date2.toGregorian()){
+			if (date2.toGregorian() < date1.toGregorian()){
 				delta = -delta;
 			}
 			break;
@@ -232,9 +230,11 @@ dojox.date.buddhist.difference = function(/*dojox.date.buddhist.Date*/date1, /*d
 			delta /= 1000;
 			// fallthrough
 		case "millisecond":
-			delta *= date1.toGregorian().getTime()- date2.toGregorian().getTime();
+			delta *= date2.toGregorian().getTime()- date1.toGregorian().getTime();
 	}
 	
 	// Round for fractional values and DST leaps
 	return Math.round(delta); // Number (integer)
-};
\ No newline at end of file
+};
+return dojox.date.buddhist;
+});
\ No newline at end of file
diff --git a/dojox/date/buddhist/Date.js b/dojox/date/buddhist/Date.js
index f23d838..04308b5 100644
--- a/dojox/date/buddhist/Date.js
+++ b/dojox/date/buddhist/Date.js
@@ -1,9 +1,15 @@
-dojo.provide("dojox.date.buddhist.Date");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/date"
+], function(dojo, declare, dd){
+
+dojo.getObject("date.buddhist.Date", true, dojox);
 dojo.experimental("dojox.date.buddhist.Date");
 
 dojo.declare("dojox.date.buddhist.Date", null, {
 
-    _date: 0,
+	_date: 0,
 	_month: 0,
 	_year: 0,
 	_hours: 0,
@@ -200,74 +206,43 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 		}
 		this._hours = hours;
 	},
+	
+	_addMinutes: function(/*Number*/minutes){
+		minutes += this._minutes;
+		this.setMinutes(minutes);
+		this.setHours(this._hours + parseInt(minutes / 60));
+		return this;
+	},
 
-	setMinutes: function(/*number*/minutes){
-		//summary: set the Minutes  frm 0-59
-		while(minutes >= 60){
-			this._hours++;
-			if(this._hours >= 24){
-				this._date++;
-				this._hours -= 24;
-				var mdays = this._getDaysInMonth(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;
+	_addSeconds: function(/*Number*/seconds){
+		seconds += this._seconds;
+		this.setSeconds(seconds);
+		this._addMinutes(parseInt(seconds / 60));
+		return this;
 	},
 
-	setSeconds: function(/*number*/seconds){
-		//summary: set the Seconds  from 0-59
-		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._getDaysInMonth(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;
+	_addMilliseconds: function(/*Number*/milliseconds){
+		milliseconds += this._milliseconds;
+		this.setMilliseconds(milliseconds);
+		this._addSeconds(parseInt(milliseconds / 1000));
+		return this;
 	},
 
-	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._getDaysInMonth(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;
+	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(){
@@ -277,7 +252,7 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 
 //FIXME: remove this and replace usage with dojox.date.buddhist.getDaysInMonth?
 	_getDaysInMonth: function(/*number*/month, /*number*/ year){
-		return dojo.date.getDaysInMonth(new Date(year-543, month));
+		return dd.getDaysInMonth(new Date(year-543, month));
 	},
 
 	fromGregorian: function(/*Date*/gdate){
@@ -308,3 +283,6 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 dojox.date.buddhist.Date.prototype.valueOf = function(){
 	return this.toGregorian().valueOf();
 };
+
+return dojox.date.buddhist.Date;
+});
diff --git a/dojox/date/buddhist/locale.js b/dojox/date/buddhist/locale.js
index cf000c9..91b32d7 100644
--- a/dojox/date/buddhist/locale.js
+++ b/dojox/date/buddhist/locale.js
@@ -1,14 +1,9 @@
-dojo.provide("dojox.date.buddhist.locale");
-dojo.experimental("dojox.date.buddhist.locale");
+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){
 
-dojo.require("dojox.date.buddhist.Date");
-dojo.require("dojo.regexp");
-dojo.require("dojo.string");
-dojo.require("dojo.i18n");
+	dojo.getObject("date.buddhist.locale", true, dojox);
+	dojo.experimental("dojox.date.buddhist.locale");
 
-dojo.requireLocalization("dojo.cldr", "buddhist");
-
-(function(){
 	// Format a pattern without literals
 	function formatPattern(dateObject, bundle, locale, fullYear,  pattern){
 
@@ -90,8 +85,8 @@ dojo.requireLocalization("dojo.cldr", "buddhist");
 					var offset = dateObject.toGregorian().getTimezoneOffset();
 					var tz = [
 						(offset <= 0 ? "+" : "-"),
-						dojo.string.pad(Math.floor(Math.abs(offset) / 60), 2),
-						dojo.string.pad(Math.abs(offset) % 60, 2)
+						string.pad(Math.floor(Math.abs(offset) / 60), 2),
+						string.pad(Math.abs(offset) % 60, 2)
 					];
 					if(l == 4){
 						tz.splice(0, 0, "GMT");
@@ -102,317 +97,311 @@ dojo.requireLocalization("dojo.cldr", "buddhist");
 				default:
 					throw new Error("dojox.date.buddhist.locale.formatPattern: invalid pattern char: "+pattern);
 			}
-			if(pad){ s = dojo.string.pad(s, l); }
+			if(pad){ s = string.pad(s, l); }
 			return s;
 		});
 	}
 	
-dojox.date.buddhist.locale.format = function(/*buddhist.Date*/dateObject, /*object?*/options){
-	// based on and similar to dojo.date.locale.format
-	//summary:
-	//		Format a Date object as a String, using  settings.
-	options = options || {};
-
-	var locale = dojo.i18n.normalizeLocale(options.locale);
-	var formatLength = options.formatLength || 'short';
-	var bundle = dojox.date.buddhist.locale._getBuddhistBundle(locale);
-	var str = [];
-
-	var sauce = dojo.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
-};
-
-dojox.date.buddhist.locale.regexp = function(/*object?*/options){
-	//	based on and similar to dojo.date.locale.regexp
-	// summary:
-	//		Builds the regular needed to parse a buddhist.Date
-	return dojox.date.buddhist.locale._parseInfo(options).regexp; // String
-};
-
-dojox.date.buddhist.locale._parseInfo = function(/*oblect?*/options){
-/* based on and similar to dojo.date.locale._parseInfo */
-
-	options = options || {};
-	var locale = dojo.i18n.normalizeLocale(options.locale);
-	var bundle = dojox.date.buddhist.locale._getBuddhistBundle(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;
-	}
+	dojox.date.buddhist.locale.format = function(/*buddhist.Date*/dateObject, /*object?*/options){
+		// based on and similar to dojo.date.locale.format
+		// 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.buddhist.locale._getBuddhistBundle(locale);
+		var str = [];
+
+		var sauce = dojo.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
+	};
+
+	dojox.date.buddhist.locale.regexp = function(/*Object?*/options){
+		//	based on and similar to dojo.date.locale.regexp
+		// summary:
+		//		Builds the regular needed to parse a buddhist.Date
+		return dojox.date.buddhist.locale._parseInfo(options).regexp; // String
+	};
+
+	dojox.date.buddhist.locale._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 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 tokens = [];
 	
-	var re = _processPattern(pattern, dojo.hitch(this, _buildDateTimeRE, tokens, bundle, options));
-	return {regexp: re, tokens: tokens, bundle: bundle};
-};
-
-
-
-
-dojox.date.buddhist.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
-	value =  value.replace(/[\u200E\u200F\u202A-\u202E]/g, ""); //remove special chars
+		var re = _processPattern(pattern, dojo.hitch(this, _buildDateTimeRE, tokens, bundle, options));
+		return {regexp: re, tokens: tokens, bundle: bundle};
+	};
+
+	dojox.date.buddhist.locale.parse = function(/*String*/value, /*Object?*/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);
+		if(!options){options={};}
+		var info = dojox.date.buddhist.locale._parseInfo(options);
 	
-	var tokens = info.tokens, bundle = info.bundle;
-	var re = new RegExp("^" + info.regexp + "$");
+		var tokens = info.tokens, bundle = info.bundle;
+		var re = new RegExp("^" + info.regexp + "$");
 	
-	var match = re.exec(value);
+		var match = re.exec(value);
 
-	var locale = dojo.i18n.normalizeLocale(options.locale);
+		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){
+			console.debug("dojox.date.buddhist.locale.parse: value  "+value+" doesn't match pattern   " + re);
+			return null;
+		} // null
 	
-	var date, date1;
+		var date, date1;
 	
-	var result = [2513,0,1,0,0,0,0];  // buddhist 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 = dojo.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 = dojo.map(months, function(s){ return s ? s.replace(".","").toLowerCase() : s; } );
-					}
-					v = dojo.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 dojox.date.buddhist.Date(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) == "'";
-
-	dojo.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 = dojo.regexp.escapeString(pattern);
-	var locale = dojo.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){
+		var result = [2513,0,1,0,0,0,0];  // buddhist 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 = dojo.every(match, function(v, i){
+			if(!i){return true;}
+			var token=tokens[i-1];
+			var l=token.length;
+			switch(token.charAt(0)){
 				case 'y':
-					s = '\\d+';
+					result[0] = Number(v);
 					break;
 				case 'M':
-					s = (l>2) ?  '\\S+' : p2+'[1-9]|1[0-2]';
+					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 = dojo.map(months, function(s){ return s ? s.replace(".","").toLowerCase() : s; } );
+						}
+						v = dojo.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':
-					s = '[12]\\d|'+p2+'[1-9]|3[01]';
+						result[2] =  Number(v);
 					break;
-				case 'E':
-					s = '\\S+';
+				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)
-					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';
+				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 'S':
-					s = '\\d{'+l+'}';
+				case 'm': //minutes
+					result[4] = Number(v);
 					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(); }
-					}
+				case 's': //seconds
+					result[5] = Number(v);
 					break;
-				default:
-					s = ".*";
+				case 'S': //milliseconds
+					result[6] = Number(v);
 			}
-			if(tokens){ tokens.push(match); }
-			return "(" + s + ")"; // add capture
-		}).replace(/[\xa0 ]/g, "[\\s\\xa0]"); // normalize whitespace.  Need explicit handling of \xa0 for IE. */
-}
-})();
+			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 buddhistDate(result[0], result[1], result[2], result[3], result[4], result[5], result[6]);
+		return dateObject;
+	};
 
 
-(function(){
-var _customFormats = [];
-dojox.date.buddhist.locale.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});
-};
+	function _processPattern(pattern, applyPattern, applyLiteral, applyAll){
+		// summary: Process a pattern with literals in it
 
-dojox.date.buddhist.locale._getBuddhistBundle = function(/*String*/locale){
-	var buddhist = {};
-	dojo.forEach(_customFormats, function(desc){
-		var bundle = dojo.i18n.getLocalization(desc.pkg, desc.name, locale);
-		buddhist = dojo.mixin(buddhist, bundle);
-	}, this);
-	return buddhist; /*Object*/
-};
-})();
+		// 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;
 
-dojox.date.buddhist.locale.addCustomFormats("dojo.cldr","buddhist");
+		//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) == "'";
 
-dojox.date.buddhist.locale.getNames = function(/*String*/item, /*String*/type, /*String?*/context, /*String?*/locale, /*buddhist Date Object?*/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 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
+		dojo.forEach(chunks, function(chunk, i){
+			if(!chunk){
+				chunks[i]='';
+			}else{
+				chunks[i]=(literal ? applyLiteral : applyPattern)(chunk);
+				literal = !literal;
+			}
+		});
+		return applyAll(chunks.join(''));
 	}
-	props[1] = 'format';
+
+	function _buildDateTimeRE  (tokens, bundle, options, pattern){
+			// based on and similar to dojo.date.locale._buildDateTimeRE
+			//
 	
-	// return by copy so changes won't be made accidentally to the in-memory model
-	return (label || lookup[props.join('-')]).concat(); /*Array*/
-};
+		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+' : 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 = [];
+	dojox.date.buddhist.locale.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){
+		var buddhist = {};
+		dojo.forEach(_customFormats, function(desc){
+			var bundle = i18n.getLocalization(desc.pkg, desc.name, locale);
+			buddhist = dojo.mixin(buddhist, bundle);
+		}, this);
+		return buddhist; /*Object*/
+	};
+
+	dojox.date.buddhist.locale.addCustomFormats("dojo.cldr","buddhist");
+
+	dojox.date.buddhist.locale.getNames = function(/*String*/item, /*String*/type, /*String?*/context, /*String?*/locale, /*buddhist Date Object?*/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 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*/
+	};
+
+});
diff --git a/dojox/date/hebrew.js b/dojox/date/hebrew.js
index 42dea14..ab4c7b4 100644
--- a/dojox/date/hebrew.js
+++ b/dojox/date/hebrew.js
@@ -1,11 +1,11 @@
-dojo.provide("dojox.date.hebrew");
+define(["dojo/_base/kernel", "dojo/date", "./hebrew/Date"], function(dojo, dd, hebrewDate){
 
-dojo.require("dojox.date.hebrew.Date");
-dojo.require("dojo.date"); // for compare
+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
+// added for compat to date
 dojox.date.hebrew.getDaysInMonth = function(/*hebrew.Date*/month){
 	return month.getDaysInHebrewMonth(month.getMonth(), month.getFullYear());
 };
@@ -26,14 +26,14 @@ dojox.date.hebrew.compare = function(/*hebrew.Date*/dateheb1, /*hebrew.Date*/dat
 	//		Compares both "date" and "time" by default.  One of the following:
 	//		"date", "time", "datetime"
 
-	if(dateheb1 instanceof dojox.date.hebrew.Date){
+	if(dateheb1 instanceof hebrewDate){
 		dateheb1 = dateheb1.toGregorian();
 	}
-	if(dateheb2 instanceof dojox.date.hebrew.Date){
+	if(dateheb2 instanceof hebrewDate){
 		dateheb2 = dateheb2.toGregorian();
 	}
 	
-	return dojo.date.compare.apply(null, arguments);
+	return dd.compare.apply(null, arguments);
 };
 
 
@@ -50,7 +50,7 @@ dojox.date.hebrew.add = function(/*dojox.date.hebrew.Date*/date, /*String*/inter
 	//	amount:
 	//		How much to add to the date.
 
-	var newHebrDate = new dojox.date.hebrew.Date(date);
+	var newHebrDate = new hebrewDate(date);
 
 	switch(interval){
 		case "day":
@@ -81,25 +81,25 @@ dojox.date.hebrew.add = function(/*dojox.date.hebrew.Date*/date, /*String*/inter
 			newHebrDate.setDate(date.getDate() + amount);
 			break;
 		case "month":
-			var month = date.getMonth();
-			var add = month + amount;
+			var month = date.getMonth(),
+				newMonth = month + amount;
 			if(!date.isLeapYear(date.getFullYear())){
-				if(month < 5 && add >= 5){ add++;}
-				else if (month > 5 && add <= 5){ add--;}
+				if(month < 5 && newMonth >= 5){ newMonth++;}
+				else if (month > 5 && newMonth <= 5){ newMonth--;}
 			}
-			newHebrDate.setMonth(add);
+			newHebrDate.setMonth(newMonth);
 			break;
 		case "hour":
 			newHebrDate.setHours(date.getHours() + amount);
 			break;
 		case "minute":
-			newHebrDate.setMinutes(date.getMinutes() + amount);
+			newHebrDate._addMinutes(amount);
 			break;
 		case "second":
-			newHebrDate.setSeconds(date.getSeconds() + amount);
+			newHebrDate._addSeconds(amount);
 			break;
 		case "millisecond":
-			newHebrDate.setMilliseconds(date.getMilliseconds() + amount);
+			newHebrDate._addMilliseconds(amount);
 			break;
 	}
 
@@ -109,7 +109,7 @@ dojox.date.hebrew.add = function(/*dojox.date.hebrew.Date*/date, /*String*/inter
 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:
-	//        date1 - date2
+	//        date2 - date1
 	//	 date2 is hebrew.Date object.  If not specified, the current hebrew.Date is used.
 	//	interval:
 	//		A string representing the interval.  One of the following:
@@ -117,9 +117,9 @@ dojox.date.hebrew.difference = function(/*dojox.date.hebrew.Date*/date1, /*dojox
 	//			"millisecond",  "week", "weekday"
 	//		Defaults to "day".
 
-	date2 = date2 || new dojox.date.hebrew.Date();
+	date2 = date2 || new hebrewDate();
 	interval = interval || "day";
-	var yearDiff = date1.getFullYear() - date2.getFullYear();
+	var yearDiff = date2.getFullYear() - date1.getFullYear();
 	var delta = 1; // Integer return value
 	switch(interval){
 		case "weekday":
@@ -133,14 +133,14 @@ dojox.date.hebrew.difference = function(/*dojox.date.hebrew.Date*/date1, /*dojox
 			}else{
 				// Weeks plus spare change (< 7 days)
 				var adj = 0;
-				var aDay = date2.getDay();
-				var bDay = date1.getDay();
+				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 dojox.date.hebrew.Date(date2);
+				var dtMark = new hebrewDate(date1);
 				dtMark.setDate(dtMark.getDate()+(weeks*7));
 				var dayMark = dtMark.getDay();
 	
@@ -199,14 +199,14 @@ dojox.date.hebrew.difference = function(/*dojox.date.hebrew.Date*/date1, /*dojox
 			delta = yearDiff;
 			break;
 		case "month":
-			var startdate =  (date1.toGregorian() > date2.toGregorian()) ? date1 : date2; // more
-			var enddate = (date1.toGregorian() > date2.toGregorian()) ? date2 : date1;
+			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 = ( !date1.isLeapYear(date1.getFullYear())  && startdate.getMonth() > 5 && enddate.getMonth() <=5) ? (startdate.getMonth() - enddate.getMonth() - 1) :
+				delta = ( !date2.isLeapYear(date2.getFullYear())  && startdate.getMonth() > 5 && enddate.getMonth() <=5) ? (startdate.getMonth() - enddate.getMonth() - 1) :
 						(startdate.getMonth() - enddate.getMonth() );
 			}else{
 				delta = (!enddate.isLeapYear(enddate.getFullYear()) &&  month2 < 6) ? (13-month2-1) : (13-month2);
@@ -217,7 +217,7 @@ dojox.date.hebrew.difference = function(/*dojox.date.hebrew.Date*/date1, /*dojox
 					delta += enddate.isLeapYear(i) ? 13 : 12;
 				}
 			}
-			if(date1.toGregorian() < date2.toGregorian()){
+			if(date2.toGregorian() < date1.toGregorian()){
 				delta = -delta;
 			}
 			break;
@@ -239,9 +239,11 @@ dojox.date.hebrew.difference = function(/*dojox.date.hebrew.Date*/date1, /*dojox
 			delta /= 1000;
 			// fallthrough
 		case "millisecond":
-			delta *= date1.toGregorian().getTime()- date2.toGregorian().getTime();
+			delta *= date2.toGregorian().getTime()- date1.toGregorian().getTime();
 	}
 
 	// Round for fractional values and DST leaps
 	return Math.round(delta); // Number (integer)
 };
+return dojox.date.hebrew;
+});
diff --git a/dojox/date/hebrew/Date.js b/dojox/date/hebrew/Date.js
index 81766f4..de291d2 100644
--- a/dojox/date/hebrew/Date.js
+++ b/dojox/date/hebrew/Date.js
@@ -1,6 +1,11 @@
-dojo.provide("dojox.date.hebrew.Date");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"./numerals"
+], function(dojo, declare, numerals){
 
-dojo.require("dojox.date.hebrew.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
@@ -210,7 +215,7 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 		// |		console.log(date1.getDate());
 
 		return (locale || dojo.locale).match(/^he(?:-.+)?$/) ?
-			dojox.date.hebrew.numerals.getDayHebrewLetters(this._date) : this.getDate();
+			numerals.getDayHebrewLetters(this._date) : this.getDate();
 	},
 
 	getMonth: function(){
@@ -423,39 +428,48 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 		return this;
 	},
 
+	_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)
-		minutes = +minutes;
+		//summary: sets the minutes (0-59) only.
 		this._minutes = minutes % 60;
-		this.setHours(parseInt(minutes / 60));
-		this._setDay();
 		return this;
 	},
 
 	setSeconds: function(/*Number*/seconds){
-		//summary: sets the seconds (0-59)
-
-		seconds = +seconds;
+		//summary: sets the seconds (0-59) only.
 		this._seconds = seconds % 60;
-		this.setMinutes(parseInt(seconds / 60));
-		this._setDay();
 		return this;
 	},
 
 	setMilliseconds: function(/*Number*/milliseconds){
-		//summary: sets the milliseconds
-
-		milliseconds = +milliseconds;
 		this._milliseconds = milliseconds % 1000;
-		this.setSeconds(parseInt(milliseconds / 1000));
-		this._setDay();
 		return this;
 	},
 
 	_setDay: function(){
 		var day = this._startOfYear(this._year);
 		if(this._month != 0){
-			day += (this.isLeapYear(this._year) ? this._LEAP_MONTH_START : this._MONTH_START)[this._month][this._yearType(this._year)];
+			day += (this.isLeapYear(this._year) ? this._LEAP_MONTH_START : this._MONTH_START)[this._month || 0][this._yearType(this._year)];
 		}
 		day += this._date - 1;
 		this._day = (day+1) % 7;
@@ -552,15 +566,16 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 		// |		var dateHebrew = new dojox.date.hebrew.Date();
 		// |		var dateGregorian = new Date(2008,10,12);
 		// |		dateHebrew.fromGregorian(dateGregorian);
-		var result = this._computeHebrewFields(gdate);
-		this._year = result[0];
-		this._month = result[1];
-		this._date = result[2];
+
+		var result = (!isNaN(gdate)) ? this._computeHebrewFields(gdate) : NaN;
+		this._year = (!isNaN(gdate)) ? result[0] : NaN;
+		this._month = (!isNaN(gdate))? result[1] : NaN;
+		this._date = (!isNaN(gdate)) ? result[2] : NaN;
 		this._hours = gdate.getHours();
 		this._milliseconds = gdate.getMilliseconds();
 		this._minutes = gdate.getMinutes();
 		this._seconds = gdate.getSeconds();
-		this._setDay();
+		if (!isNaN(gdate)) this._setDay();
 		return this;
 	},
 
@@ -599,9 +614,10 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 		// example:
 		// |		var dateHebrew = new dojox.date.hebrew.Date(5768,11,20);
 		// |		var dateGregorian = dateHebrew.toGregorian();
-		var hYear = this._year,
-			hMonth = this._month,
-			hDate = this._date,
+		
+		var hYear = this._year || 0,
+			hMonth = this._month || 0,
+			hDate = this._date || 0,
 			day = this._startOfYear(hYear);
 
 		if(hMonth != 0){
@@ -688,7 +704,7 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 			Math.floor(y/400) + 1721426 - 1;
 		// At this point julianDay indicates the day BEFORE the first day
 		// of January 1, <eyear> of the Gregorian calendar.
-		if(month != 0){
+		if(month > 0) {
 			julianDay += this._GREGORIAN_MONTH_COUNT[month][isLeap ? 3 : 2];
 		}
 		
@@ -700,3 +716,5 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 dojox.date.hebrew.Date.prototype.valueOf = function(){
 	return this.toGregorian().valueOf();
 };
+return dojox.date.hebrew.Date;
+});
diff --git a/dojox/date/hebrew/locale.js b/dojox/date/hebrew/locale.js
index 808d80e..5b0e1db 100644
--- a/dojox/date/hebrew/locale.js
+++ b/dojox/date/hebrew/locale.js
@@ -1,18 +1,13 @@
-dojo.provide("dojox.date.hebrew.locale");
+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){
 
+	dojo.getObject("date.hebrew.locale", true, dojox);
+	dojo.experimental("dojox.date.hebrew.locale");
 
-dojo.require("dojox.date.hebrew.Date");
-dojo.require("dojox.date.hebrew.numerals");
-dojo.require("dojo.regexp");
-dojo.require("dojo.string");
-dojo.require("dojo.i18n");
+	//Load the bundles containing localization information for
+	// names and formats
+	dojo.requireLocalization("dojo.cldr", "hebrew");
 
-
-//Load the bundles containing localization information for
-// names and formats
-dojo.requireLocalization("dojo.cldr", "hebrew");
-
-(function(){
 	// Format a pattern without literals
 	function formatPattern(dateObject, bundle, locale, fullYear,  pattern){
 
@@ -25,7 +20,7 @@ dojo.requireLocalization("dojo.cldr", "hebrew");
 			switch(c){
 				case 'y':
 					if(locale.match(/^he(?:-.+)?$/)){
-						s = dojox.date.hebrew.numerals.getYearHebrewLetters(dateObject.getFullYear());
+						s = numerals.getYearHebrewLetters(dateObject.getFullYear());
 					}else{
 						s = String(dateObject.getFullYear());
 					}
@@ -35,7 +30,7 @@ dojo.requireLocalization("dojo.cldr", "hebrew");
 					if(l<3){
 						if(!dateObject.isLeapYear(dateObject.getFullYear()) && m>5){m--;}
 						if(locale.match(/^he(?:-.+)?$/)){
-							s = dojox.date.hebrew.numerals.getMonthHebrewLetters(m);
+							s = numerals.getMonthHebrewLetters(m);
 						}else{
 							s = m+1; pad = true;
 						}
@@ -101,420 +96,415 @@ dojo.requireLocalization("dojo.cldr", "hebrew");
 				default:
 					throw new Error("dojox.date.hebrew.locale.formatPattern: invalid pattern char: "+pattern);
 			}
-			if(pad){ s = dojo.string.pad(s, l); }
+			if(pad){ s = string.pad(s, l); }
 			return s;
 		});
 	}
 	
-dojox.date.hebrew.locale.format = function(/*hebrew.Date*/dateObject, /*object?*/options){
-	// based on and similar to dojo.date.locale.format
-	//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.
-
-	options = options || {};
-
-	var locale = dojo.i18n.normalizeLocale(options.locale);
-	var formatLength = options.formatLength || 'short';
-	var bundle = dojox.date.hebrew.locale._getHebrewBundle(locale);
-	var str = [];
-
-	var sauce = dojo.hitch(this, formatPattern, dateObject, bundle, locale, options.fullYear);
-	if(options.selector == "year"){
-		var year = dateObject.getFullYear();
-		return locale.match(/^he(?:-.+)?$/) ?
-			dojox.date.hebrew.numerals.getYearHebrewLetters(year) : 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
+	dojox.date.hebrew.locale.format = function(/*hebrew.Date*/dateObject, /*object?*/options){
+		// based on and similar to dojo.date.locale.format
+		//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.
+
+		options = options || {};
+
+		var locale = i18n.normalizeLocale(options.locale);
+		var formatLength = options.formatLength || 'short';
+		var bundle = dojox.date.hebrew.locale._getHebrewBundle(locale);
+		var str = [];
+
+		var sauce = dojo.hitch(this, formatPattern, dateObject, bundle, locale, options.fullYear);
+		if(options.selector == "year"){
+			var year = dateObject.getFullYear();
+			return locale.match(/^he(?:-.+)?$/) ?
+				numerals.getYearHebrewLetters(year) : 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
-};
+		return result; // String
+	};
 
-dojox.date.hebrew.locale.regexp = function(/*object?*/options){
-	//	based on and similar to dojo.date.locale.regexp
-	// summary:
-	//		Builds the regular needed to parse a hebrew.Date
+	dojox.date.hebrew.locale.regexp = function(/*object?*/options){
+		//	based on and similar to dojo.date.locale.regexp
+		// summary:
+		//		Builds the regular needed to parse a hebrew.Date
 
-	return dojox.date.hebrew.locale._parseInfo(options).regexp; // String
-};
+		return dojox.date.hebrew.locale._parseInfo(options).regexp; // String
+	};
 
-dojox.date.hebrew.locale._parseInfo = function(/*oblect?*/options){
-/* based on and similar to dojo.date.locale._parseInfo */
+	dojox.date.hebrew.locale._parseInfo = function(/*oblect?*/options){
+	/* based on and similar to dojo.date.locale._parseInfo */
 
-	options = options || {};
-	var locale = dojo.i18n.normalizeLocale(options.locale);
-	var bundle = dojox.date.hebrew.locale._getHebrewBundle(locale);
+		options = options || {};
+		var locale = i18n.normalizeLocale(options.locale);
+		var bundle = dojox.date.hebrew.locale._getHebrewBundle(locale);
 
-	var formatLength = options.formatLength || 'short';
-	var datePattern = options.datePattern || bundle["dateFormat-" + formatLength];
-	var timePattern = options.timePattern || bundle["timeFormat-" + formatLength];
+		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 = (timePattern === undefined) ? datePattern : datePattern + ' ' + timePattern; //hebrew resource file does not contain time patterns - a bug?
-	}
+		var pattern;
+		if(options.selector == 'date'){
+			pattern = datePattern;
+		}else if(options.selector == 'time'){
+			pattern = timePattern;
+		}else{
+			pattern = (timePattern === undefined) ? datePattern : datePattern + ' ' + timePattern; //hebrew resource file does not contain time patterns - a bug?
+		}
 
-	var tokens = [];
+		var tokens = [];
 	
-	var re = _processPattern(pattern, dojo.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
+		var re = _processPattern(pattern, dojo.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
 		
-	value =  value.replace(/[\u200E\u200F\u202A-\u202E]/g, ""); //remove special chars
+		value =  value.replace(/[\u200E\u200F\u202A-\u202E]/g, ""); //remove special chars
 
-	if(!options){options={};}
-	var info = dojox.date.hebrew.locale._parseInfo(options);
+		if(!options){options={};}
+		var info = dojox.date.hebrew.locale._parseInfo(options);
 	
-	var tokens = info.tokens, bundle = info.bundle;
-	var re = new RegExp("^" + info.regexp + "$");
+		var tokens = info.tokens, bundle = info.bundle;
+		var re = new RegExp("^" + info.regexp + "$");
 	
-	var match = re.exec(value);
+		var match = re.exec(value);
 
-	var locale = dojo.i18n.normalizeLocale(options.locale);
+		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){
+			console.debug("dojox.date.hebrew.locale.parse: value  "+value+" doesn't match pattern   " + re);
+			return null;
+		} // null
 	
-	var date, date1;
+		var date, date1;
 	
-	//var result = [1970,0,1,0,0,0,0]; //
-	var result = [5730,3,23,0,0,0,0];  // hebrew 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 = dojo.every(match, function(v, i){
-		if(!i){return true;}
-		var token=tokens[i-1];
-		var l=token.length;
-		switch(token.charAt(0)){
-			case 'y':
-				if(locale.match(/^he(?:-.+)?$/)){
-					result[0] = dojox.date.hebrew.numerals.parseYearHebrewLetters(v);
-				}else{
-					result[0] = Number(v);
-				}
-				break;
-			case 'M':
-				//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 dojox.date.hebrew.Date(5769, 1, 1)),
-						leapmonths = dojox.date.hebrew.locale.getNames('months', widthList[l-3], 'format', locale, new dojox.date.hebrew.Date(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; } );
-					}
-					var monthName = v;
-					v = dojo.indexOf(months, monthName);
-					if(v == -1){
-						v = dojo.indexOf(leapmonths, monthName);
-						if(v == -1){
-							//console.debug("dojox.date.hebrew.locale.parse: Could not parse month name:  second   " + v +"'.");
-							return false;
-						}
-					}
-					mLength = l;
-				}else{
+		//var result = [1970,0,1,0,0,0,0]; //
+		var result = [5730,3,23,0,0,0,0];  // hebrew 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 = dojo.every(match, function(v, i){
+			if(!i){return true;}
+			var token=tokens[i-1];
+			var l=token.length;
+			switch(token.charAt(0)){
+				case 'y':
 					if(locale.match(/^he(?:-.+)?$/)){
-						v = dojox.date.hebrew.numerals.parseMonthHebrewLetters(v);
+						result[0] = numerals.parseYearHebrewLetters(v);
 					}else{
-						v--;
+						result[0] = Number(v);
 					}
-				}
-				result[1] = Number(v);
-				break;
-			case 'D':
-				result[1] = 0;
-				// fallthrough...
-			case 'd':
-				if(locale.match(/^he(?:-.+)?$/)){
-					result[2] = dojox.date.hebrew.numerals.parseDayHebrewLetters(v);
-				}else{
-					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 dojox.date.hebrew.Date(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);
-	}
-	return dateObject; // hebrew.Date
-};
-
-
-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) == "'";
-
-	dojo.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 = dojo.regexp.escapeString(pattern);
-	var locale = dojo.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 = '\\S+';
 					break;
 				case 'M':
-					if(locale.match('^he(?:-.+)?$')){
-						s = (l>2) ? '\\S+ ?\\S+' : '\\S{1,4}';
+					//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));
+						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; } );
+						}
+						var monthName = v;
+						v = dojo.indexOf(months, monthName);
+						if(v == -1){
+							v = dojo.indexOf(leapmonths, monthName);
+							if(v == -1){
+								//console.debug("dojox.date.hebrew.locale.parse: Could not parse month name:  second   " + v +"'.");
+								return false;
+							}
+						}
+						mLength = l;
 					}else{
-						s = (l>2) ?  '\\S+ ?\\S+' : p2+'[1-9]|1[0-2]';
+						if(locale.match(/^he(?:-.+)?$/)){
+							v = numerals.parseMonthHebrewLetters(v);
+						}else{
+							v--;
+						}
 					}
+					result[1] = Number(v);
 					break;
+				case 'D':
+					result[1] = 0;
+					// fallthrough...
 				case 'd':
-					if(locale.match('^he(?:-.+)?$')){
-						s = '\\S[\'\"\'\u05F3]{1,2}\\S?';
+					if(locale.match(/^he(?:-.+)?$/)){
+						result[2] = numerals.parseDayHebrewLetters(v);
 					}else{
-						s = '[12]\\d|'+p2+'[1-9]|30';
+						result[2] = Number(v);
 					}
 					break;
-				case 'E':
-					if(locale.match('^he(?:-.+)?$')){
-						s = (l>3) ? '\\S+ ?\\S+' : '\\S';
-					}else{
-						s = '\\S+';
+				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)
-					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';
+				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 'S':
-					s = '\\d{'+l+'}';
+				case 'm': //minutes
+					result[4] = Number(v);
 					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(); }
-					}
+				case 's': //seconds
+					result[5] = Number(v);
 					break;
-				default:
-					s = ".*";
+				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 hebrewDate(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);
+		}
+		return dateObject; // hebrew.Date
+	};
+
+
+	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) == "'";
+
+		dojo.forEach(chunks, function(chunk, i){
+			if(!chunk){
+				chunks[i]='';
+			}else{
+				chunks[i]=(literal ? applyLiteral : applyPattern)(chunk);
+				literal = !literal;
 			}
-			if(tokens){ tokens.push(match); }
-			return "(" + s + ")"; // add capture
-		}).replace(/[\xa0 ]/g, "[\\s\\xa0]"); // normalize whitespace.  Need explicit handling of \xa0 for IE. */
-}
-})();
-
-
-
-(function(){
-var _customFormats = [];
-dojox.date.hebrew.locale.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`
-	//		The pattern string should match the format used by the CLDR.
-	//		See dojo.date.locale.format() for details.
-	//		The resources must be loaded by dojo.requireLocalization() prior to use
-
-	_customFormats.push({pkg:packageName,name:bundleName});
-};
-
-dojox.date.hebrew.locale._getHebrewBundle = function(/*String*/locale){
-	var hebrew = {};
-	dojo.forEach(_customFormats, function(desc){
-		var bundle = dojo.i18n.getLocalization(desc.pkg, desc.name, locale);
-		hebrew = dojo.mixin(hebrew, bundle);
-	}, this);
-	return hebrew; /*Object*/
-};
-})();
-
-dojox.date.hebrew.locale.addCustomFormats("dojo.cldr","hebrew");
-
-dojox.date.hebrew.locale.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'
-	// type:
-	//	'wide' || 'narrow' || 'abbr' (e.g. "Monday", "Mon", or "M" respectively, in English)
-	// use:
-	//	'standAlone' || 'format' (default)
-	// locale:
-	//	override locale used to find the names
-	// date:
-	//	required for item=months to determine leap month name
-	//
-	// using  var monthNames = dojox.date.hebrew.locale.getNames('months', 'wide', 'format', 'he', new dojox.date.hebrew.Date(5768, 2, 12));
-
-	var label,
-		lookup = dojox.date.hebrew.locale._getHebrewBundle(locale),
-		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
+		});
+		return applyAll(chunks.join(''));
 	}
-	props[1] = 'format';
+
+	function _buildDateTimeRE  (tokens, bundle, options, pattern){
+			// based on and similar to dojo.date.locale._buildDateTimeRE
+			//
 	
-	// return by copy so changes won't be made accidentally to the in-memory model
-	var result = (label || lookup[props.join('-')]).concat();
-
-	if(item == "months"){
-		if(date.isLeapYear(date.getFullYear())){
-			// Adar I (6th position in the array) will be used.
-			// Substitute the leap month Adar II for the regular Adar (7th position)
-			props.push("leap");
-			result[6] = lookup[props.join('-')];
-		}else{
-			// Remove Adar I but leave an empty position in the array
-			delete result[5];
-		}
+		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 = '\\S+';
+						break;
+					case 'M':
+						if(locale.match('^he(?:-.+)?$')){
+							s = (l>2) ? '\\S+ ?\\S+' : '\\S{1,4}';
+						}else{
+							s = (l>2) ?  '\\S+ ?\\S+' : p2+'[1-9]|1[0-2]';
+						}
+						break;
+					case 'd':
+						if(locale.match('^he(?:-.+)?$')){
+							s = '\\S[\'\"\'\u05F3]{1,2}\\S?';
+						}else{
+							s = '[12]\\d|'+p2+'[1-9]|30';
+						}
+						break;
+					case 'E':
+						if(locale.match('^he(?:-.+)?$')){
+							s = (l>3) ? '\\S+ ?\\S+' : '\\S';
+						}else{
+							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. */
 	}
 
-	return result; /*Array*/
-};
+	var _customFormats = [];
+	dojox.date.hebrew.locale.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`
+		//		The pattern string should match the format used by the CLDR.
+		//		See dojo.date.locale.format() for details.
+		//		The resources must be loaded by dojo.requireLocalization() prior to use
+
+		_customFormats.push({pkg:packageName,name:bundleName});
+	};
+
+	dojox.date.hebrew.locale._getHebrewBundle = function(/*String*/locale){
+		var hebrew = {};
+		dojo.forEach(_customFormats, function(desc){
+			var bundle = i18n.getLocalization(desc.pkg, desc.name, locale);
+			hebrew = dojo.mixin(hebrew, bundle);
+		}, this);
+		return hebrew; /*Object*/
+	};
+
+	dojox.date.hebrew.locale.addCustomFormats("dojo.cldr","hebrew");
+
+	dojox.date.hebrew.locale.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'
+		// type:
+		//	'wide' || 'narrow' || 'abbr' (e.g. "Monday", "Mon", or "M" respectively, in English)
+		// use:
+		//	'standAlone' || 'format' (default)
+		// locale:
+		//	override locale used to find the names
+		// date:
+		//	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),
+			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
+		var result = (label || lookup[props.join('-')]).concat();
+
+		if(item == "months"){
+			if(date.isLeapYear(date.getFullYear())){
+				// Adar I (6th position in the array) will be used.
+				// Substitute the leap month Adar II for the regular Adar (7th position)
+				props.push("leap");
+				result[6] = lookup[props.join('-')];
+			}else{
+				// Remove Adar I but leave an empty position in the array
+				delete result[5];
+			}
+		}
+
+		return result; /*Array*/
+	};
+
+	return dojox.date.hebrew.locale;
+});
diff --git a/dojox/date/hebrew/numerals.js b/dojox/date/hebrew/numerals.js
index 15b406d..9c48809 100644
--- a/dojox/date/hebrew/numerals.js
+++ b/dojox/date/hebrew/numerals.js
@@ -1,9 +1,9 @@
-dojo.provide("dojox.date.hebrew.numerals");
+define(["dojo/_base/kernel", "dojo/_base/array"], function(dojo){
+	dojo.getObject("date.hebrew.numerals", true, dojox);
+	dojo.experimental("dojox.date.hebrew.numerals");
 
 //Conversion from "Hindi" numerals to Hebrew numerals and vice versa
 
-(function(){
-
 	var DIG="אבגדהוזחט";
 	var	TEN="יכלמנסעפצ";
 	var	HUN="קרשת";
@@ -136,4 +136,5 @@ dojo.provide("dojox.date.hebrew.numerals");
 		}
 		return monnum;
 	};
-})();
+	return dojox.date.hebrew.numerals;
+});
diff --git a/dojox/date/islamic.js b/dojox/date/islamic.js
index 3e4ff9a..590160e 100644
--- a/dojox/date/islamic.js
+++ b/dojox/date/islamic.js
@@ -1,8 +1,8 @@
-dojo.provide("dojox.date.islamic");
+define(["dojo/_base/kernel", "dojo/date", "./islamic/Date"], function(dojo, dd, islamicDate){
+
+dojo.getObject("date.islamic", true, dojox);
+dojo.experimental("dojox.date.islamic");
 
-dojo.require("dojox.date.islamic.Date");
-dojo.require("dojo.date"); // for compare
-	
 // Utility methods to do arithmetic calculations with islamic.Dates
 
 	// added for compat to date
@@ -26,14 +26,14 @@ dojox.date.islamic.compare = function(/*islamic.Date*/date1, /*islamic.Date*/dat
 	//		Compares both "date" and "time" by default.  One of the following:
 	//		"date", "time", "datetime"
 
-	if(date1 instanceof dojox.date.islamic.Date){
+	if(date1 instanceof islamicDate){
 		date1 = date1.toGregorian();
 	}
-	if(date2 instanceof dojox.date.islamic.Date){
+	if(date2 instanceof islamicDate){
 		date2 = date2.toGregorian();
 	}
 	
-	return dojo.date.compare.apply(null, arguments);
+	return dd.compare.apply(null, arguments);
 };
 
 dojox.date.islamic.add = function(/*dojox.date.islamic.Date*/date, /*String*/interval, /*int*/amount){
@@ -49,7 +49,7 @@ dojox.date.islamic.add = function(/*dojox.date.islamic.Date*/date, /*String*/int
 	//	amount:
 	//		How much to add to the date.
 
-	var newIslamDate = new dojox.date.islamic.Date(date);
+	var newIslamDate = new islamicDate(date);
 
 	switch(interval){
 		case "day":
@@ -94,13 +94,13 @@ dojox.date.islamic.add = function(/*dojox.date.islamic.Date*/date, /*String*/int
 			newIslamDate.setHours(date.getHours() + amount);
 			break;
 		case "minute":
-			newIslamDate.setMinutes(date.getMinutes() + amount);
+			newIslamDate._addMinutes(amount);
 			break;
 		case "second":
-			newIslamDate.setSeconds(date.getSeconds() + amount);
+			newIslamDate._addSeconds(amount);
 			break;
 		case "millisecond":
-			newIslamDate.setMilliseconds(date.getMilliseconds() + amount);
+			newIslamDate._addMilliseconds(amount);
 			break;
 	}
 
@@ -110,7 +110,7 @@ dojox.date.islamic.add = function(/*dojox.date.islamic.Date*/date, /*String*/int
 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:
-	//        date1 - date2
+	//        date2 - date1
 	//	 date2 is islamic.Date object.  If not specified, the current islamic.Date is used.
 	//	interval:
 	//		A string representing the interval.  One of the following:
@@ -118,9 +118,9 @@ dojox.date.islamic.difference = function(/*dojox.date.islamic.Date*/date1, /*doj
 	//			"millisecond",  "week", "weekday"
 	//		Defaults to "day".
 
-	date2 = date2 || new dojox.date.islamic.Date();
+	date2 = date2 || new islamicDate();
 	interval = interval || "day";
-	var yearDiff = date1.getFullYear() - date2.getFullYear();
+	var yearDiff = date2.getFullYear() - date1.getFullYear();
 	var delta = 1; // Integer return value
 	switch(interval){
 		case "weekday":
@@ -134,14 +134,14 @@ dojox.date.islamic.difference = function(/*dojox.date.islamic.Date*/date1, /*doj
 			}else{
 				// Weeks plus spare change (< 7 days)
 				var adj = 0;
-				var aDay = date2.getDay();
-				var bDay = date1.getDay();
+				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 dojox.date.islamic.Date(date2);
+				var dtMark = new islamicDate(date1);
 				dtMark.setDate(dtMark.getDate()+(weeks*7));
 				var dayMark = dtMark.getDay();
 	
@@ -200,8 +200,8 @@ dojox.date.islamic.difference = function(/*dojox.date.islamic.Date*/date1, /*doj
 			delta = yearDiff;
 			break;
 		case "month":
-			var startdate =  (date1.toGregorian() > date2.toGregorian()) ? date1 : date2; // more
-			var enddate = (date1.toGregorian() > date2.toGregorian()) ? date2 : date1;
+			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();
@@ -217,7 +217,7 @@ dojox.date.islamic.difference = function(/*dojox.date.islamic.Date*/date1, /*doj
 					delta += 12;
 				}
 			}
-			if (date1.toGregorian() < date2.toGregorian()){
+			if (date2.toGregorian() < date1.toGregorian()){
 				delta = -delta;
 			}
 			break;
@@ -239,9 +239,11 @@ dojox.date.islamic.difference = function(/*dojox.date.islamic.Date*/date1, /*doj
 			delta /= 1000;
 			// fallthrough
 		case "millisecond":
-			delta *= date1.toGregorian().getTime()- date2.toGregorian().getTime();
+			delta *= date2.toGregorian().getTime()- date1.toGregorian().getTime();
 	}
 
 	// Round for fractional values and DST leaps
 	return Math.round(delta); // Number (integer)
 };
+return dojox.date.islamic;
+});
\ No newline at end of file
diff --git a/dojox/date/islamic/Date.js b/dojox/date/islamic/Date.js
index 9395197..3dad685 100644
--- a/dojox/date/islamic/Date.js
+++ b/dojox/date/islamic/Date.js
@@ -1,7 +1,7 @@
-dojo.provide("dojox.date.islamic.Date");
+define(["dojo/_base/kernel", "dojo/_base/declare", "dojo/date"], function(dojo, declare, dd){
 
-dojo.require("dojo.date");
-dojo.requireLocalization("dojo.cldr", "islamic");
+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
@@ -233,77 +233,43 @@ dojo.declare("dojox.date.islamic.Date", null, {
 		this._hours = hours;
 	},
 
-	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;
+	_addMinutes: function(/*Number*/minutes){
+		minutes += this._minutes;
+		this.setMinutes(minutes);
+		this.setHours(this._hours + parseInt(minutes / 60));
+		return this;
 	},
-		
-		
-	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;
+
+	_addSeconds: function(/*Number*/seconds){
+		seconds += this._seconds;
+		this.setSeconds(seconds);
+		this._addMinutes(parseInt(seconds / 60));
+		return this;
 	},
-		
-	setMilliseconds:function(/*number*/milliseconds){
-		//summary: set the Millisconds
-		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;
+
+	_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
@@ -354,15 +320,15 @@ dojo.declare("dojox.date.islamic.Date", null, {
 		
 		var tjd = (this._GREGORIAN_EPOCH - 1) + (365 * (year - 1)) + Math.floor((year - 1) / 4)
 				-( Math.floor((year - 1) / 100)) + Math.floor((year - 1) / 400) + Math.floor( (739 / 12)
-				+ ( (dojo.date.isLeapYear(new Date(year,3,1)) ? -1 : -2)) + 1);
+				+ ( (dd.isLeapYear(new Date(year,3,1)) ? -1 : -2)) + 1);
 			
-		var leapadj = ((wjd < tjd ) ? 0 : (dojo.date.isLeapYear(new Date(year,3,1)) ? 1 : 2));
+		var leapadj = ((wjd < tjd ) ? 0 : (dd.isLeapYear(new Date(year,3,1)) ? 1 : 2));
 					
 		var month = Math.floor((((yearday + leapadj) * 12) + 373) / 367);
 		var tjd2 = (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 : (dojo.date.isLeapYear(new Date(year,month,1)) ? -1 : -2)) + 1);
+					+ ((month <= 2) ? 0 : (dd.isLeapYear(new Date(year,month,1)) ? -1 : -2)) + 1);
 					
 		var day = (wjd - tjd2) + 1;
 
@@ -388,7 +354,7 @@ dojo.declare("dojox.date.islamic.Date", null, {
 		var julianDay = (this._GREGORIAN_EPOCH - 1) + (365 * (gYear - 1)) + Math.floor((gYear - 1) / 4)
 					+ (-Math.floor((gYear - 1) / 100)) + Math.floor((gYear - 1) / 400)
 					+ Math.floor((((367 * (gMonth+1)) - 362) / 12)
-					+ (((gMonth+1) <= 2) ? 0 : (dojo.date.isLeapYear(date) ? -1 : -2)) + gDay);
+					+ (((gMonth+1) <= 2) ? 0 : (dd.isLeapYear(date) ? -1 : -2)) + gDay);
 		julianDay = Math.floor(julianDay) + 0.5;
 
 		var days = julianDay - this._ISLAMIC_EPOCH;
@@ -454,3 +420,5 @@ dojo.declare("dojox.date.islamic.Date", null, {
 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
 };
+return dojox.date.islamic.Date;
+});
diff --git a/dojox/date/islamic/locale.js b/dojox/date/islamic/locale.js
index a2ff470..caed2a8 100644
--- a/dojox/date/islamic/locale.js
+++ b/dojox/date/islamic/locale.js
@@ -1,14 +1,11 @@
-dojo.provide("dojox.date.islamic.locale");
+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){
 
-dojo.require("dojox.date.islamic.Date");
-dojo.require("dojo.regexp");
-dojo.require("dojo.string");
-dojo.require("dojo.i18n");
-dojo.require("dojo.date");
+	dojo.getObject("date.islamic.locale", true, dojox);
+	dojo.experimental("dojox.date.islamic.locale");
 
-dojo.requireLocalization("dojo.cldr", "islamic");
+	dojo.requireLocalization("dojo.cldr", "islamic");
 
-(function(){
 	// Format a pattern without literals
 	function formatPattern(dateObject, bundle, locale, fullYear,  pattern){
 
@@ -82,7 +79,7 @@ dojo.requireLocalization("dojo.cldr", "islamic");
 					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
@@ -90,8 +87,8 @@ dojo.requireLocalization("dojo.cldr", "islamic");
 					var offset = dateObject.toGregorian().getTimezoneOffset();
 					var tz = [
 						(offset <= 0 ? "+" : "-"),
-						dojo.string.pad(Math.floor(Math.abs(offset) / 60), 2),
-						dojo.string.pad(Math.abs(offset) % 60, 2)
+						string.pad(Math.floor(Math.abs(offset) / 60), 2),
+						string.pad(Math.abs(offset) % 60, 2)
 					];
 					if(l == 4){
 						tz.splice(0, 0, "GMT");
@@ -102,324 +99,318 @@ dojo.requireLocalization("dojo.cldr", "islamic");
 				default:
 					throw new Error("dojox.date.islamic.locale.formatPattern: invalid pattern char: "+pattern);
 			}
-			if(pad){ s = dojo.string.pad(s, l); }
+			if(pad){ s = string.pad(s, l); }
 			return s;
 		});
 	}
 	
-// based on and similar to dojo.date.locale.format
-dojox.date.islamic.locale.format = function(/*islamic.Date*/dateObject, /*Object?*/options){
-	// summary:
-	//		Format a Date object as a String, using  settings.
-	options = options || {};
-
-	var locale = dojo.i18n.normalizeLocale(options.locale);
-	var formatLength = options.formatLength || 'short';
-	var bundle = dojox.date.islamic.locale._getIslamicBundle(locale);
-	var str = [];
-
-	var sauce = dojo.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
-};
-
-dojox.date.islamic.locale.regexp = function(/*object?*/options){
-	//	based on and similar to dojo.date.locale.regexp
-	// summary:
-	//		Builds the regular needed to parse a islamic.Date
-	return dojox.date.islamic.locale._parseInfo(options).regexp; // String
-};
-
-dojox.date.islamic.locale._parseInfo = function(/*oblect?*/options){
-/* based on and similar to dojo.date.locale._parseInfo */
-
-	options = options || {};
-	var locale = dojo.i18n.normalizeLocale(options.locale);
-	var bundle = dojox.date.islamic.locale._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, dojo.hitch(this, _buildDateTimeRE, tokens, bundle, options));
-	return {regexp: re, tokens: tokens, bundle: bundle};
-};
-
-
-
+	// based on and similar to dojo.date.locale.format
+	dojox.date.islamic.locale.format = function(/*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 str = [];
+
+		var sauce = dojo.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
+	};
+
+	dojox.date.islamic.locale.regexp = function(/*object?*/options){
+		//	based on and similar to dojo.date.locale.regexp
+		// summary:
+		//		Builds the regular needed to parse a islamic.Date
+		return dojox.date.islamic.locale._parseInfo(options).regexp; // String
+	};
+
+	dojox.date.islamic.locale._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 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;
+		}
 
-dojox.date.islamic.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
+		var tokens = [];
 	
-	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 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 re = _processPattern(pattern, dojo.hitch(this, _buildDateTimeRE, tokens, bundle, options));
+		return {regexp: re, tokens: tokens, bundle: bundle};
+	};
 
-	var match = re.exec(value);
-
-	var locale = dojo.i18n.normalizeLocale(options.locale);
-
-	if(!match){
-		console.debug("dojox.date.islamic.locale.parse: value  "+value+" doesn't match pattern   " + re);
-		return null;
-	} // null
-	
-	var date, date1;
+	dojox.date.islamic.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
 	
-	var result = [1389,0,1,0,0,0,0];  //FIXME: islamic 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 = dojo.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 = dojo.map(months, function(s){ return s ? s.replace(".","").toLowerCase() : s; } );
-					}
-					v = dojo.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 dojox.date.islamic.Date(result[0], result[1], result[2], result[3], result[4], result[5], result[6]);
-	return dateObject;
-};
+		value =  value.replace(/[\u200E\u200F\u202A\u202E]/g, ""); //remove bidi non-printing chars
 
+		if(!options){ options={}; }
+		var info = dojox.date.islamic.locale._parseInfo(options);
 
-function _processPattern(pattern, applyPattern, applyLiteral, applyAll){
-	//summary: Process a pattern with literals in it
+		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 + "$");
 
-	// 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;
+		var match = re.exec(value);
 
-	//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) == "'";
+		var locale = i18n.normalizeLocale(options.locale);
 
-	dojo.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
-		//
+		if(!match){
+			console.debug("dojox.date.islamic.locale.parse: value  "+value+" doesn't match pattern   " + re);
+			return null;
+		} // null
 	
-	pattern = dojo.regexp.escapeString(pattern);
-	var locale = dojo.i18n.normalizeLocale(options.locale);
+		var date, date1;
 	
-	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){
+		var result = [1389,0,1,0,0,0,0];  //FIXME: islamic 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 = dojo.every(match, function(v, i){
+			if(!i){return true;}
+			var token=tokens[i-1];
+			var l=token.length;
+			switch(token.charAt(0)){
 				case 'y':
-					s = '\\d+';
+					result[0] = Number(v);
 					break;
 				case 'M':
-					s = (l>2) ?  '\\S+ ?\\S+' : p2+'[1-9]|1[0-2]';
+					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 = dojo.map(months, function(s){ return s ? s.replace(".","").toLowerCase() : s; } );
+						}
+						v = dojo.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':
-					s = '[12]\\d|'+p2+'[1-9]|3[01]';
+						result[2] =  Number(v);
 					break;
-				case 'E':
-					s = '\\S+';
+				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)
-					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';
+				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 'S':
-					s = '\\d{'+l+'}';
+				case 'm': //minutes
+					result[4] = Number(v);
 					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(); }
-					}
+				case 's': //seconds
+					result[5] = Number(v);
 					break;
-				default:
-					s = ".*";
+				case 'S': //milliseconds
+					result[6] = Number(v);
 			}
-			if(tokens){ tokens.push(match); }
-			return "(" + s + ")"; // add capture
-		}).replace(/[\xa0 ]/g, "[\\s\\xa0]"); // normalize whitespace.  Need explicit handling of \xa0 for IE. */
-}
-})();
-
-
-
-(function(){
-var _customFormats = [];
-dojox.date.islamic.locale.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){
-	var islamic = {};
-	dojo.forEach(_customFormats, function(desc){
-		var bundle = dojo.i18n.getLocalization(desc.pkg, desc.name, locale);
-		islamic = dojo.mixin(islamic, bundle);
-	}, this);
-	return islamic; /*Object*/
-};
-})();
-
-dojox.date.islamic.locale.addCustomFormats("dojo.cldr","islamic");
-
-dojox.date.islamic.locale.getNames = function(/*String*/item, /*String*/type, /*String?*/context, /*String?*/locale, /*islamic Date Object?*/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 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
+			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 islamicDate(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) == "'";
+
+		dojo.forEach(chunks, function(chunk, i){
+			if(!chunk){
+				chunks[i]='';
+			}else{
+				chunks[i]=(literal ? applyLiteral : applyPattern)(chunk);
+				literal = !literal;
+			}
+		});
+		return applyAll(chunks.join(''));
 	}
-	props[1] = 'format';
+
+	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 by copy so changes won't be made accidentally to the in-memory model
-	return (label || lookup[props.join('-')]).concat(); /*Array*/
-};
+		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 = [];
+	dojox.date.islamic.locale.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){
+		var islamic = {};
+		dojo.forEach(_customFormats, function(desc){
+			var bundle = i18n.getLocalization(desc.pkg, desc.name, locale);
+			islamic = dojo.mixin(islamic, bundle);
+		}, this);
+		return islamic; /*Object*/
+	};
+
+	dojox.date.islamic.locale.addCustomFormats("dojo.cldr","islamic");
+
+	dojox.date.islamic.locale.getNames = function(/*String*/item, /*String*/type, /*String?*/context, /*String?*/locale, /*islamic Date Object?*/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 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*/
+	};
+
 
+	dojox.date.islamic.locale.weekDays = dojox.date.islamic.locale.getNames('days', 'wide', 'format');
 
-dojox.date.islamic.locale.weekDays = dojox.date.islamic.locale.getNames('days', 'wide', 'format');
+	dojox.date.islamic.locale.months = dojox.date.islamic.locale.getNames('months', 'wide', 'format');
 
-dojox.date.islamic.locale.months = dojox.date.islamic.locale.getNames('months', 'wide', 'format');
+	return dojox.date.islamic.locale;
+});
\ No newline at end of file
diff --git a/dojox/date/php.js b/dojox/date/php.js
index ac6511c..fb22a80 100644
--- a/dojox/date/php.js
+++ b/dojox/date/php.js
@@ -1,6 +1,5 @@
-dojo.provide("dojox.date.php");
-dojo.require("dojo.date");
-dojo.require("dojox.string.tokenize");
+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
@@ -22,7 +21,7 @@ dojox.date.php.DateFormat = function(/*String*/ format){
 
 	var replacements = [];
 
-	this.tokens = dojox.string.tokenize(format, this.regex, function(escape, token, i){
+	this.tokens = dxst(format, this.regex, function(escape, token, i){
 		if(token){
 			replacements.push([i, token]);
 			return token;
@@ -111,7 +110,7 @@ dojo.extend(dojox.date.php.DateFormat, {
 
 		if(z <= (8 - jan1_w) && jan1_w > 4){
 			var last_year = new Date(this.date.getFullYear() - 1, this.date.getMonth(), this.date.getDate());
-			if(jan1_w == 5 || (jan1_w == 6 && dojo.date.isLeapYear(last_year))){
+			if(jan1_w == 5 || (jan1_w == 6 && ddate.isLeapYear(last_year))){
 				week = 53;
 			}else{
 				week = 52;
@@ -169,7 +168,7 @@ dojo.extend(dojox.date.php.DateFormat, {
 
 	L: function(){
 		// summary: Whether it's a leap year
-		return (dojo.date.isLeapYear(this.date)) ? "1" : "0";
+		return (ddate.isLeapYear(this.date)) ? "1" : "0";
 	},
 
 	o: function(){
@@ -250,7 +249,7 @@ dojo.extend(dojox.date.php.DateFormat, {
 
 	e: function(){
 		// summary: Timezone identifier (added in PHP 5.1.0)
-		return dojo.date.getTimezoneName(this.date);
+		return ddate.getTimezoneName(this.date);
 	},
 
 	I: function(){
@@ -305,4 +304,6 @@ dojo.extend(dojox.date.php.DateFormat, {
 		return Math.floor(this.date.getTime() / 1000);
 	}
 
+});
+return dojox.date.php;
 });
\ No newline at end of file
diff --git a/dojox/date/posix.js b/dojox/date/posix.js
index 892acb4..60da32d 100644
--- a/dojox/date/posix.js
+++ b/dojox/date/posix.js
@@ -1,8 +1,7 @@
-dojo.provide("dojox.date.posix");
+define(["dojo/_base/kernel", "dojo/date", "dojo/date/locale", "dojo/string", "dojo/cldr/supplemental"],
+       function(dojo, dojoDate, dojoDateLocale, dojoString, dojoCldrSupplemental){
 
-dojo.require("dojo.date");
-dojo.require("dojo.date.locale");
-dojo.require("dojo.string");
+dojo.getObject("date.posix", true, dojox);
 
 dojox.date.posix.strftime = function(/*Date*/dateObject, /*String*/format, /*String?*/locale){
 //
@@ -15,29 +14,29 @@ dojox.date.posix.strftime = function(/*Date*/dateObject, /*String*/format, /*Str
 	// zero pad
 	var padChar = null;
 	var _ = function(s, n){
-		return dojo.string.pad(s, n || 2, padChar || "0");
+		return dojoString.pad(s, n || 2, padChar || "0");
 	};
 
-	var bundle = dojo.date.locale._getGregorianBundle(locale);
+	var bundle = dojoDateLocale._getGregorianBundle(locale);
 
 	var $ = function(property){
 		switch(property){
 			case "a": // abbreviated weekday name according to the current locale
-				return dojo.date.locale.getNames('days', 'abbr', 'format', locale)[dateObject.getDay()];
+				return dojoDateLocale.getNames('days', 'abbr', 'format', locale)[dateObject.getDay()];
 
 			case "A": // full weekday name according to the current locale
-				return dojo.date.locale.getNames('days', 'wide', 'format', locale)[dateObject.getDay()];
+				return dojoDateLocale.getNames('days', 'wide', 'format', locale)[dateObject.getDay()];
 
 			case "b":
 			case "h": // abbreviated month name according to the current locale
-				return dojo.date.locale.getNames('months', 'abbr', 'format', locale)[dateObject.getMonth()];
+				return dojoDateLocale.getNames('months', 'abbr', 'format', locale)[dateObject.getMonth()];
 				
 			case "B": // full month name according to the current locale
-				return dojo.date.locale.getNames('months', 'wide', 'format', locale)[dateObject.getMonth()];
+				return dojoDateLocale.getNames('months', 'wide', 'format', locale)[dateObject.getMonth()];
 				
 			case "c": // preferred date and time representation for the current
 				      // locale
-				return dojo.date.locale.format(dateObject, {formatLength: 'full', locale: locale});
+				return dojoDateLocale.format(dateObject, {formatLength: 'full', locale: locale});
 
 			case "C": // century number (the year divided by 100 and truncated
 				      // to an integer, range 00 to 99)
@@ -66,7 +65,7 @@ dojox.date.posix.strftime = function(/*Date*/dateObject, /*String*/format, /*Str
 				      // (see %V).  This has the same format and value as %Y,
 				      // except that if the ISO week number belongs to the
 				      // previous or next year, that year is used instead.
-				dojo.unimplemented("unimplemented modifier 'G'");
+				console.warn("unimplemented modifier 'G'");
 				break;
 			
 			case "F": // same as %Y-%m-%d
@@ -81,7 +80,7 @@ dojox.date.posix.strftime = function(/*Date*/dateObject, /*String*/format, /*Str
 				return _(dateObject.getHours() % 12 || 12);
 
 			case "j": // day of the year as a decimal number (range 001 to 366)
-				return _(dojo.date.locale._getDayOfYear(dateObject), 3);
+				return _(dojoDateLocale._getDayOfYear(dateObject), 3);
 
 			case "k": // Hour as a decimal number using a 24-hour clock (range
 					  // 0 to 23 (space-padded))
@@ -128,7 +127,7 @@ dojox.date.posix.strftime = function(/*Date*/dateObject, /*String*/format, /*Str
 			case "U": // week number of the current year as a decimal number,
 				      // starting with the first Sunday as the first day of the
 				      // first week
-				return _(dojo.date.locale._getWeekOfYear(dateObject));
+				return _(dojoDateLocale._getWeekOfYear(dateObject));
 
 			case "V": // week number of the year (Monday as the first day of the
 				      // week) as a decimal number [01,53]. If the week containing
@@ -140,18 +139,18 @@ dojox.date.posix.strftime = function(/*Date*/dateObject, /*String*/format, /*Str
 			case "W": // week number of the current year as a decimal number,
 				      // starting with the first Monday as the first day of the
 				      // first week
-				return _(dojo.date.locale._getWeekOfYear(dateObject, 1));
+				return _(dojoDateLocale._getWeekOfYear(dateObject, 1));
 				
 			case "w": // day of the week as a decimal, Sunday being 0
 				return String(dateObject.getDay());
 
 			case "x": // preferred date representation for the current locale
 				      // without the time
-				return dojo.date.locale.format(dateObject, {selector:'date', formatLength: 'full', locale:locale});
+				return dojoDateLocale.format(dateObject, {selector:'date', formatLength: 'full', locale:locale});
 
 			case "X": // preferred time representation for the current locale
 				      // without the date
-				return dojo.date.locale.format(dateObject, {selector:'time', formatLength: 'full', locale:locale});
+				return dojoDateLocale.format(dateObject, {selector:'time', formatLength: 'full', locale:locale});
 
 			case "y": // year as a decimal number without a century (range 00 to
 				      // 99)
@@ -167,7 +166,7 @@ dojox.date.posix.strftime = function(/*Date*/dateObject, /*String*/format, /*Str
 					_(Math.abs(timezoneOffset)%60);
 
 			case "Z": // time zone or name or abbreviation
-				return dojo.date.getTimezoneName(dateObject);
+				return dojoDate.getTimezoneName(dateObject);
 			
 			case "%":
 				return "%";
@@ -175,10 +174,10 @@ dojox.date.posix.strftime = function(/*Date*/dateObject, /*String*/format, /*Str
 	};
 
 	// parse the formatting string and construct the resulting string
-	var string = "";
-	var i = 0;
-	var index = 0;
-	var switchCase = null;
+	var string = "",
+		i = 0,
+		index = 0,
+		switchCase = null;
 	while ((index = format.indexOf("%", i)) != -1){
 		string += format.substring(i, index++);
 		
@@ -237,7 +236,7 @@ dojox.date.posix.getStartOfWeek = function(/*Date*/dateObject, /*Number*/firstDa
 	// summary: Return a date object representing the first day of the given
 	//   date's week.
 	if(isNaN(firstDay)){
-		firstDay = dojo.cldr.supplemental.getFirstDayOfWeek ? dojo.cldr.supplemental.getFirstDayOfWeek() : 0;
+		firstDay = dojoCldrSupplemental.getFirstDayOfWeek ? dojoCldrSupplemental.getFirstDayOfWeek() : 0;
 	}
 	var offset = firstDay;
 	if(dateObject.getDay() >= firstDay){
@@ -247,7 +246,7 @@ dojox.date.posix.getStartOfWeek = function(/*Date*/dateObject, /*Number*/firstDa
 	}
 	var date = new Date(dateObject);
 	date.setHours(0, 0, 0, 0);
-	return dojo.date.add(date, "day", offset); // Date
+	return dojoDate.add(date, "day", offset); // Date
 }
 
 dojox.date.posix.setIsoWeekOfYear = function(/*Date*/dateObject, /*Number*/week){
@@ -262,7 +261,7 @@ dojox.date.posix.setIsoWeekOfYear = function(/*Date*/dateObject, /*Number*/week)
 		var weeks = dojox.date.posix.getIsoWeeksInYear(dateObject);
 		offset = (weeks + week + 1) - currentWeek;
 	}
-	return dojo.date.add(dateObject, "week", offset); // Date
+	return dojoDate.add(dateObject, "week", offset); // Date
 }
 
 dojox.date.posix.getIsoWeekOfYear = function(/*Date*/dateObject){
@@ -287,3 +286,5 @@ dojox.date.posix.getIsoWeeksInYear = function(/*Date*/dateObject) {
 	var y = dateObject.getFullYear();
 	return ( p(y) % 7 == 4 || p(y-1) % 7 == 3 ) ? 53 : 52;	//	Integer
 }
+	return dojox.date.posix;
+});
\ No newline at end of file
diff --git a/dojox/date/relative.js b/dojox/date/relative.js
index 26cdbe9..f7a656d 100644
--- a/dojox/date/relative.js
+++ b/dojox/date/relative.js
@@ -1,36 +1,30 @@
-dojo.provide("dojox.date.relative");
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/date/locale", "dojo/i18n"], function(dojo, dlang, ddl, i18n){
 
-dojo.require("dojo.date");
-dojo.require("dojo.date.locale");
+dojo.getObject("date.relative", true, dojox);
 
-(function(d){
 /*=====
-	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;
-	}
+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 DAY = 1000*60*60*24;
-var SIX_DAYS = 6 * DAY;
-var del = d.delegate;
-var ddl = d.date.locale;
-var ggb = ddl._getGregorianBundle;
-var fmt = ddl.format;
+var DAY = 1000*60*60*24,
+	SIX_DAYS = 6 * DAY,
+	del = dojo.delegate,
+	ggb = ddl._getGregorianBundle,
+	fmt = ddl.format;
 
 function _clearTime(date){
-	date = dojo.clone(date);
-	date.setHours(0);
-	date.setMinutes(0);
-	date.setSeconds(0);
-	date.setMilliseconds(0);
+	date = new Date(date);
+	date.setHours(0, 0, 0, 0);
 	return date;
 }
 
@@ -66,9 +60,9 @@ dojox.date.relative.format = function(/*Date*/dateObject, /*dojox.date.relative.
 	
 	options = options || {};
 	
-	var today = _clearTime(options.relativeDate || new Date());
-	var diff = today.getTime() - _clearTime(dateObject).getTime();
-	var fmtOpts = {locale: options.locale};
+	var today = _clearTime(options.relativeDate || new Date()),
+		diff = today.getTime() - _clearTime(dateObject).getTime(),
+		fmtOpts = {locale: options.locale};
 	
 	if(diff === 0){
 		// today: 9:32 AM
@@ -80,7 +74,7 @@ dojox.date.relative.format = function(/*Date*/dateObject, /*dojox.date.relative.
 				fmt(dateObject, del(fmtOpts, {selector: "time", formatLength: "short"}));
 	}else if(dateObject.getFullYear() == today.getFullYear()){
 		// this year: Nov 1
-		var bundle = ggb(dojo.i18n.normalizeLocale(options.locale));
+		var bundle = ggb(i18n.normalizeLocale(options.locale));
 		return fmt(dateObject, del(fmtOpts, {
 			selector: "date",
 			datePattern: bundle["dateFormatItem-MMMd"]
@@ -94,4 +88,4 @@ dojox.date.relative.format = function(/*Date*/dateObject, /*dojox.date.relative.
 		}));
 	}
 };
-})(dojo);
+});
diff --git a/dojox/date/tests/buddhist/Date.js b/dojox/date/tests/buddhist/Date.js
index c23e349..95aedc7 100644
--- a/dojox/date/tests/buddhist/Date.js
+++ b/dojox/date/tests/buddhist/Date.js
@@ -2,21 +2,22 @@ dojo.provide("dojox.date.tests.buddhist.Date");
 dojo.require("dojox.date.buddhist");
 dojo.require("dojox.date.buddhist.Date");
 dojo.require("dojox.date.buddhist.locale");
+dojo.require("dojo.date.locale");
 
-dojo.requireLocalization("dojo.cldr", "greg");
-dojo.requireLocalization("dojo.cldr", "buddhist");
+//dojo.requireLocalization("dojo.cldr", "gregorian");
+//dojo.requireLocalization("dojo.cldr", "buddhist");
 
 tests.register("dojox.date.tests.buddhist.Date",
 	[
 		{
 			// see tests for dojo.date.locale for setup info
 
-			name: "dojox.date.tests.posix",
+			name: "setup",
 			setUp: function(){
 				var partLocaleList = ["th"];
 
 				dojo.forEach(partLocaleList, function(locale){
-					dojo.requireLocalization("dojo.cldr", "greg", locale);
+					dojo.requireLocalization("dojo.cldr", "gregorian", locale);
 					dojo.requireLocalization("dojo.cldr", "buddhist", locale);
 				});
 			},
@@ -25,8 +26,8 @@ tests.register("dojox.date.tests.buddhist.Date",
 			tearDown: function(){
 				//Clean up bundles that should not exist if
 				//the test is re-run.
-				delete dojo.cldr.nls.greg;
-				delete dojo.cldr.nls.buddhist;
+			//				delete dojo.cldr.nls.greg;
+			//				delete dojo.cldr.nls.buddhist;
 			}
 		},
 		{
@@ -107,35 +108,35 @@ tests.register("dojox.date.tests.buddhist.Date",
 				
 				var dateBuddhistAdd = dojox.date.buddhist.add(dateBuddhist, "month",  18);
 				var dateBuddhistAddLeap = dojox.date.buddhist.add(dateBuddhistLeap, "month",  18);
-				t.is(0, 18 - dojox.date.buddhist.difference(dateBuddhistAdd, dateBuddhist, "month"));
-				t.is(0, 18 - dojox.date.buddhist.difference(dateBuddhistAddLeap, dateBuddhistLeap, "month"));
+				t.is(0, 18 - dojox.date.buddhist.difference(dateBuddhist, dateBuddhistAdd, "month"));
+				t.is(0, 18 - dojox.date.buddhist.difference(dateBuddhistLeap, dateBuddhistAddLeap, "month"));
 				
 				var dateBuddhistAdd1= dojox.date.buddhist.add(dateBuddhist, "year", 2);
-				t.is(0,  2 - dojox.date.buddhist.difference(dateBuddhistAdd1, dateBuddhist, "year"));
-				t.is(0,  2 - dojox.date.buddhist.difference(dojox.date.buddhist.add(dateBuddhistLeap, "year", 2), dateBuddhistLeap, "year"));
+				t.is(0,  2 - dojox.date.buddhist.difference(dateBuddhist, dateBuddhistAdd1, "year"));
+				t.is(0,  2 - dojox.date.buddhist.difference(dateBuddhistLeap, dojox.date.buddhist.add(dateBuddhistLeap, "year", 2), "year"));
 				
 				var dateBuddhistAdd2= dojox.date.buddhist.add(dateBuddhist, "week",  12);
-				t.is(0, 12 - dojox.date.buddhist.difference(dateBuddhistAdd2, dateBuddhist, "week"));
-				t.is(0,  12 - dojox.date.buddhist.difference(dojox.date.buddhist.add(dateBuddhistLeap, "week", 12), dateBuddhistLeap,"week"));
-								
+				t.is(0, 12 - dojox.date.buddhist.difference(dateBuddhist, dateBuddhistAdd2, "week"));
+				t.is(0,  12 - dojox.date.buddhist.difference(dateBuddhistLeap, dojox.date.buddhist.add(dateBuddhistLeap, "week", 12), "week"));
+							
 				var dateBuddhistAdd3= dojox.date.buddhist.add(dateBuddhist, "weekday", 20);
-				t.is(0, 20 - dojox.date.buddhist.difference(dateBuddhistAdd3, dateBuddhist, "weekday"));
-				t.is(0,  20 - dojox.date.buddhist.difference(dojox.date.buddhist.add(dateBuddhistLeap, "weekday", 20), dateBuddhistLeap,"weekday"));
+				t.is(0, 20 - dojox.date.buddhist.difference(dateBuddhist, dateBuddhistAdd3, "weekday"));
+				t.is(0,  20 - dojox.date.buddhist.difference(dateBuddhistLeap, dojox.date.buddhist.add(dateBuddhistLeap, "weekday", 20), "weekday"));
 				
 				var dateBuddhistAdd4= dojox.date.buddhist.add(dateBuddhist, "day", -50)
-				t.is(0, -50 - dojox.date.buddhist.difference(dateBuddhistAdd4, dateBuddhist, "day"));
-				t.is(0, -50 - dojox.date.buddhist.difference(dojox.date.buddhist.add(dateBuddhistLeap, "day", -50), dateBuddhistLeap,"day"));
-											
+				t.is(0, -50 - dojox.date.buddhist.difference(dateBuddhist, dateBuddhistAdd4, "day"));
+				t.is(0, -50 - dojox.date.buddhist.difference(dateBuddhistLeap, dojox.date.buddhist.add(dateBuddhistLeap, "day", -50), "day"));
+									
 				var dateBuddhistAdd5= dojox.date.buddhist.add(dateBuddhist, "hour", 200);
-				t.is(0, 200 - dojox.date.buddhist.difference(dateBuddhistAdd5, dateBuddhist, "hour"));
-				t.is(0, 200 - dojox.date.buddhist.difference(dojox.date.buddhist.add(dateBuddhistLeap, "hour", 200), dateBuddhistLeap,"hour"));
+				t.is(0, 200 - dojox.date.buddhist.difference(dateBuddhist, dateBuddhistAdd5, "hour"));
+				t.is(0, 200 - dojox.date.buddhist.difference(dateBuddhistLeap, dojox.date.buddhist.add(dateBuddhistLeap, "hour", 200), "hour"));
 				
 				var dateBuddhistAdd6= dojox.date.buddhist.add(dateBuddhist, "minute", -200);
-				t.is(0, -200 - dojox.date.buddhist.difference(dateBuddhistAdd6, dateBuddhist, "minute"));
-				t.is(0, -200 - dojox.date.buddhist.difference(dojox.date.buddhist.add(dateBuddhistLeap, "minute", -200), dateBuddhistLeap,"minute"));
+				t.is(0, -200 - dojox.date.buddhist.difference(dateBuddhist, dateBuddhistAdd6, "minute"));
+				t.is(0, -200 - dojox.date.buddhist.difference(dateBuddhistLeap, dojox.date.buddhist.add(dateBuddhistLeap, "minute", -200), "minute"));
 				
 				var dateBuddhistDiff = new dojox.date.buddhist.Date(2552, 5, 17);
-				t.is(1, dojox.date.buddhist.difference(dateBuddhistDiff, dateBuddhist));
+				t.is(1, dojox.date.buddhist.difference(dateBuddhist, dateBuddhistDiff));
 			}
 		},
 		{
@@ -169,6 +170,68 @@ tests.register("dojox.date.tests.buddhist.Date",
 				t.is(0, dojo.date.compare(gregDate, dateBuddhist1.toGregorian(), 'time'));
 								 	
 			}
+		},
+		{
+			name: "addMilliseconds",
+			runTest: function(t){												
+				var buddhistDates = [
+							[5771, 8, 21, 10, 30],
+							[5771, 8, 21, 2, 2],
+							[5771, 8, 21, 8, 10], // "absolute" index of month, non-leap year
+							[5771, 8, 21, 12, 59],
+							[5771, 8, 21, 3, 33]
+						];
+						
+				var dates = [
+							[1432, 8, 21, 10, 30],
+							[1432, 8, 21, 2, 2],
+							[1432, 8, 21, 8, 10], // "absolute" index of month, non-leap year
+							[1432, 8, 21, 12, 59],
+							[1432, 8, 21, 3, 33]
+						];
+						
+				var traceAttributes = function(date){
+					console.log("getHours():" + date.getHours()+" getMinutes():"+date.getMinutes()+" getSeconds():"+date.getSeconds()+" getMilliseconds():"+date.getMilliseconds());
+				};
+						
+				var dateBuddhist, date2;
+				dojo.forEach(buddhistDates, function(date, i){
+					dateBuddhist = new dojox.date.buddhist.Date(date[0], date[1], date[2], date[3], date[4]);
+					date2 = new Date(dates[i][0], dates[i][1], dates[i][2], dates[i][3], dates[i][4]);			
+		
+					var newBuddhistDate = dojox.date.buddhist.add(dateBuddhist, "millisecond",  1200);
+					var newDate = dojo.date.add(date2, "millisecond",  1200);
+					t.is(newBuddhistDate.getHours(), newDate.getHours(), "Hours are different");
+					t.is(newBuddhistDate.getMinutes(), newDate.getMinutes(), "Minutes are different");
+					t.is(newBuddhistDate.getSeconds(), newDate.getSeconds(), "Seconds are different");
+					t.is(newBuddhistDate.getMilliseconds(), newDate.getMilliseconds(), "Milliseconds are different");
+					//traceAttributes(newBuddhistDate);
+
+					newBuddhistDate = dojox.date.buddhist.add(dateBuddhist, "millisecond",  12022);
+					newDate = dojo.date.add(date2, "millisecond",  12022);
+					t.is(newBuddhistDate.getHours(), newDate.getHours(), "Hours are different");
+					t.is(newBuddhistDate.getMinutes(), newDate.getMinutes(), "Minutes are different");
+					t.is(newBuddhistDate.getSeconds(), newDate.getSeconds(), "Seconds are different");
+					t.is(newBuddhistDate.getMilliseconds(), newDate.getMilliseconds(), "Milliseconds are different");
+					//traceAttributes(newBuddhistDate);
+
+					newBuddhistDate = dojox.date.buddhist.add(dateBuddhist, "millisecond",  120422);
+					newDate = dojo.date.add(date2, "millisecond",  120422);
+					t.is(newBuddhistDate.getHours(), newDate.getHours(), "Hours are different");
+					t.is(newBuddhistDate.getMinutes(), newDate.getMinutes(), "Minutes are different");
+					t.is(newBuddhistDate.getSeconds(), newDate.getSeconds(), "Seconds are different");
+					t.is(newBuddhistDate.getMilliseconds(), newDate.getMilliseconds(), "Milliseconds are different");
+					//traceAttributes(newBuddhistDate);
+
+					newBuddhistDate = dojox.date.buddhist.add(dateBuddhist, "millisecond",  1204422);
+					newDate = dojo.date.add(date2, "millisecond",  1204422);
+					t.is(newBuddhistDate.getHours(), newDate.getHours(), "Hours are different");
+					t.is(newBuddhistDate.getMinutes(), newDate.getMinutes(), "Minutes are different");
+					t.is(newBuddhistDate.getSeconds(), newDate.getSeconds(), "Seconds are different");
+					t.is(newBuddhistDate.getMilliseconds(), newDate.getMilliseconds(), "Milliseconds are different");
+					//traceAttributes(newBuddhistDate);
+				});
+			}
 		}
 	]
 );
diff --git a/dojox/date/tests/hebrew/Date.js b/dojox/date/tests/hebrew/Date.js
index 798279c..2e1b94d 100644
--- a/dojox/date/tests/hebrew/Date.js
+++ b/dojox/date/tests/hebrew/Date.js
@@ -2,6 +2,7 @@ dojo.provide("dojox.date.tests.hebrew.Date");
 dojo.require("dojox.date.hebrew");
 dojo.require("dojox.date.hebrew.Date");
 dojo.require("dojox.date.hebrew.locale");
+dojo.require("dojo.date.locale");
 
 dojo.requireLocalization("dojo.cldr", "gregorian");
 dojo.requireLocalization("dojo.cldr", "hebrew");
@@ -11,7 +12,7 @@ tests.register("dojox.date.tests.hebrew.Date",
 		{
 			// see tests for dojo.date.locale for setup info
 
-			name: "dojox.date.tests.posix",
+			name: "setup",
 			setUp: function(){
 				var partLocaleList = ["he", "en"];
 
@@ -25,8 +26,8 @@ tests.register("dojox.date.tests.hebrew.Date",
 			tearDown: function(){
 				//Clean up bundles that should not exist if
 				//the test is re-run.
-				delete dojo.cldr.nls.gregorian;
-				delete dojo.cldr.nls.hebrew;
+			//				delete dojo.cldr.nls.gregorian;
+			//				delete dojo.cldr.nls.hebrew;
 			}
 		},
 		{
@@ -109,6 +110,13 @@ tests.register("dojox.date.tests.hebrew.Date",
 					testHebrew = new dojox.date.hebrew.Date(d[3], d[4], d[5]);
 					t.is(0, dojo.date.compare(testHebrew.toGregorian() , dateHebrew.toGregorian(),  "date"));
 				});
+				
+				//test for invalid date, toGregorian and fromGregorian should return invalid date
+				var invDate = new Date("");
+				var hDate = new dojox.date.hebrew.Date(invDate);
+				t.is(true, isNaN(hDate));
+				t.is(true, isNaN(hDate.toGregorian()));
+				
 			}
 		},
 		{
@@ -185,7 +193,7 @@ tests.register("dojox.date.tests.hebrew.Date",
 					dojo.forEach(start, function(s, i){
 						dateHebRes = new dojox.date.hebrew.Date( s[2], s[3], 1);
 						dateHebStart =  new dojox.date.hebrew.Date( s[0], s[1], 1);
-						t.is(add[i], dojox.date.hebrew.difference(dateHebRes,  dateHebStart , "month"));
+						t.is(add[i], dojox.date.hebrew.difference(dateHebStart , dateHebRes, "month"));
 					});
 					
 					//different fields
@@ -238,7 +246,7 @@ tests.register("dojox.date.tests.hebrew.Date",
 					dojo.forEach( fields, function(f, i){
 						dateHebStart =  new dojox.date.hebrew.Date( f[0], f[1], f[2]);
 						dateHebRes = new dojox.date.hebrew.Date( f[5], f[6], f[7]);
-						res = dojox.date.hebrew.difference(dateHebRes,  dateHebStart , f[3]);
+						res = dojox.date.hebrew.difference(dateHebStart, dateHebRes, f[3]);
 						t.is(f[4], res);
 					});
 					
@@ -264,45 +272,45 @@ tests.register("dojox.date.tests.hebrew.Date",
 				dojo.forEach( amouts, function(amount, i){
 					dateHebrewAdd = dojox.date.hebrew.add(dateHebrew, "month",  amount);
 					dateHebrewAddLeap = dojox.date.hebrew.add(dateHebrewLeap, "month",  amount);
-					t.is(dojox.date.hebrew.difference(dateHebrewAdd, dateHebrew, "month"), amount);
-					t.is(amount, dojox.date.hebrew.difference(dateHebrewAddLeap, dateHebrewLeap, "month"));
+					t.is(dojox.date.hebrew.difference(dateHebrew, dateHebrewAdd, "month"), amount);
+					t.is(amount, dojox.date.hebrew.difference(dateHebrewLeap, dateHebrewAddLeap, "month"));
 												
 					dateHebrewAdd= dojox.date.hebrew.add(dateHebrew, "year", amount);
-					t.is(amount, dojox.date.hebrew.difference(dateHebrewAdd, dateHebrew, "year"));
-					t.is(amount, dojox.date.hebrew.difference(dojox.date.hebrew.add(dateHebrewLeap, "year", amount), dateHebrewLeap, "year"));
+					t.is(amount, dojox.date.hebrew.difference(dateHebrew, dateHebrewAdd, "year"));
+					t.is(amount, dojox.date.hebrew.difference(dateHebrewLeap, dojox.date.hebrew.add(dateHebrewLeap, "year", amount), "year"));
 					
 					dateHebrewAdd= dojox.date.hebrew.add(dateHebrew, "week",  amount);
-					t.is(amount,  dojox.date.hebrew.difference(dateHebrewAdd, dateHebrew, "week"));
-					t.is(amount,  dojox.date.hebrew.difference(dojox.date.hebrew.add(dateHebrewLeap, "week", amount), dateHebrewLeap,"week"));
+					t.is(amount,  dojox.date.hebrew.difference(dateHebrew, dateHebrewAdd, "week"));
+					t.is(amount,  dojox.date.hebrew.difference(dateHebrewLeap, dojox.date.hebrew.add(dateHebrewLeap, "week", amount), "week"));
 									
 					dateHebrewAdd= dojox.date.hebrew.add(dateHebrew, "weekday", amount);
-					t.is(amount,  dojox.date.hebrew.difference(dateHebrewAdd, dateHebrew, "weekday"));
+					t.is(amount,  dojox.date.hebrew.difference(dateHebrew, dateHebrewAdd, "weekday"));
 					dateHebrewAddLeap = dojox.date.hebrew.add(dateHebrewLeap, "weekday", amount);
-					t.is(amount,  dojox.date.hebrew.difference(dojox.date.hebrew.add(dateHebrewLeap, "weekday", amount), dateHebrewLeap,"weekday"));
+					t.is(amount,  dojox.date.hebrew.difference(dateHebrewLeap, dojox.date.hebrew.add(dateHebrewLeap, "weekday", amount), "weekday"));
 					
 					dateHebrewAdd= dojox.date.hebrew.add(dateHebrew, "day", amount)
-					t.is(amount,  dojox.date.hebrew.difference(dateHebrewAdd, dateHebrew, "day"));
-					t.is(amount, dojox.date.hebrew.difference(dojox.date.hebrew.add(dateHebrewLeap, "day", amount), dateHebrewLeap,"day"));
-												
+					t.is(amount,  dojox.date.hebrew.difference(dateHebrew, dateHebrewAdd, "day"));
+					t.is(amount, dojox.date.hebrew.difference(dateHebrewLeap, dojox.date.hebrew.add(dateHebrewLeap, "day", amount), "day"));
+										
 					dateHebrewAdd= dojox.date.hebrew.add(dateHebrew, "hour", amount);
-					t.is(amount,  dojox.date.hebrew.difference(dateHebrewAdd, dateHebrew, "hour"));
-					t.is(amount,  dojox.date.hebrew.difference(dojox.date.hebrew.add(dateHebrewLeap, "hour", amount), dateHebrewLeap,"hour"));
+					t.is(amount,  dojox.date.hebrew.difference(dateHebrew, dateHebrewAdd, "hour"));
+					t.is(amount,  dojox.date.hebrew.difference(dateHebrewLeap, dojox.date.hebrew.add(dateHebrewLeap, "hour", amount), "hour"));
 					
 					dateHebrewAdd= dojox.date.hebrew.add(dateHebrew, "minute", amount);
-					t.is(amount,  dojox.date.hebrew.difference(dateHebrewAdd, dateHebrew, "minute"));
-					t.is(amount,  dojox.date.hebrew.difference(dojox.date.hebrew.add(dateHebrewLeap, "minute", amount), dateHebrewLeap,"minute"));
+					t.is(amount,  dojox.date.hebrew.difference(dateHebrew, dateHebrewAdd, "minute"));
+					t.is(amount,  dojox.date.hebrew.difference(dateHebrewLeap, dojox.date.hebrew.add(dateHebrewLeap, "minute", amount), "minute"));
 					
 					dateHebrewAdd= dojox.date.hebrew.add(dateHebrew, "second", amount);
-					t.is(amount,  dojox.date.hebrew.difference(dateHebrewAdd, dateHebrew, "second"));
-					t.is(amount,  dojox.date.hebrew.difference(dojox.date.hebrew.add(dateHebrewLeap, "second", amount), dateHebrewLeap,"second"));
+					t.is(amount,  dojox.date.hebrew.difference(dateHebrew, dateHebrewAdd, "second"));
+					t.is(amount,  dojox.date.hebrew.difference(dateHebrewLeap, dojox.date.hebrew.add(dateHebrewLeap, "second", amount), "second"));
 					
 					dateHebrewAdd= dojox.date.hebrew.add(dateHebrew, "millisecond", amount);
-					t.is(amount,  dojox.date.hebrew.difference(dateHebrewAdd, dateHebrew, "millisecond"));
-					t.is(amount,  dojox.date.hebrew.difference(dojox.date.hebrew.add(dateHebrewLeap, "millisecond", amount), dateHebrewLeap,"millisecond"));
+					t.is(amount,  dojox.date.hebrew.difference(dateHebrew, dateHebrewAdd, "millisecond"));
+					t.is(amount,  dojox.date.hebrew.difference(dateHebrewLeap, dojox.date.hebrew.add(dateHebrewLeap, "millisecond", amount), "millisecond"));
 				 });
 				 
 				var dateHebrewDiff = new dojox.date.hebrew.Date(5769, 4, 17);
-				t.is(1, dojox.date.hebrew.difference(dateHebrewDiff, dateHebrew));
+				t.is(1, dojox.date.hebrew.difference(dateHebrew, dateHebrewDiff));
 			}
 		},
 		{
@@ -401,6 +409,68 @@ tests.register("dojox.date.tests.hebrew.Date",
 				str= dojox.date.hebrew.locale.format(dateHebrew, options);
 				t.is(str, "3:3:59");
 			}
+		},
+		{
+			name: "addMilliseconds",
+			runTest: function(t){												
+				var hebrewDates = [
+							[5771, 8, 21, 10, 30],
+							[5771, 8, 21, 2, 2],
+							[5771, 8, 21, 8, 10], // "absolute" index of month, non-leap year
+							[5771, 8, 21, 12, 59],
+							[5771, 8, 21, 3, 33]
+						];
+						
+				var dates = [
+							[1432, 8, 21, 10, 30],
+							[1432, 8, 21, 2, 2],
+							[1432, 8, 21, 8, 10], // "absolute" index of month, non-leap year
+							[1432, 8, 21, 12, 59],
+							[1432, 8, 21, 3, 33]
+						];
+						
+				var traceAttributes = function(date){
+					console.log("getHours():" + date.getHours()+" getMinutes():"+date.getMinutes()+" getSeconds():"+date.getSeconds()+" getMilliseconds():"+date.getMilliseconds());
+				};
+						
+				var dateHebrew, date2;
+				dojo.forEach(hebrewDates, function(date, i){
+					dateHebrew = new dojox.date.hebrew.Date(date[0], date[1], date[2], date[3], date[4]);
+					date2 = new Date(dates[i][0], dates[i][1], dates[i][2], dates[i][3], dates[i][4]);			
+		
+					var newHebrewDate = dojox.date.hebrew.add(dateHebrew, "millisecond",  1200);
+					var newDate = dojo.date.add(date2, "millisecond",  1200);
+					t.is(newHebrewDate.getHours(), newDate.getHours(), "Hours are different");
+					t.is(newHebrewDate.getMinutes(), newDate.getMinutes(), "Minutes are different");
+					t.is(newHebrewDate.getSeconds(), newDate.getSeconds(), "Seconds are different");
+					t.is(newHebrewDate.getMilliseconds(), newDate.getMilliseconds(), "Milliseconds are different");
+					//traceAttributes(newHebrewDate);
+
+					newHebrewDate = dojox.date.hebrew.add(dateHebrew, "millisecond",  12022);
+					newDate = dojo.date.add(date2, "millisecond",  12022);
+					t.is(newHebrewDate.getHours(), newDate.getHours(), "Hours are different");
+					t.is(newHebrewDate.getMinutes(), newDate.getMinutes(), "Minutes are different");
+					t.is(newHebrewDate.getSeconds(), newDate.getSeconds(), "Seconds are different");
+					t.is(newHebrewDate.getMilliseconds(), newDate.getMilliseconds(), "Milliseconds are different");
+					//traceAttributes(newHebrewDate);
+
+					newHebrewDate = dojox.date.hebrew.add(dateHebrew, "millisecond",  120422);
+					newDate = dojo.date.add(date2, "millisecond",  120422);
+					t.is(newHebrewDate.getHours(), newDate.getHours(), "Hours are different");
+					t.is(newHebrewDate.getMinutes(), newDate.getMinutes(), "Minutes are different");
+					t.is(newHebrewDate.getSeconds(), newDate.getSeconds(), "Seconds are different");
+					t.is(newHebrewDate.getMilliseconds(), newDate.getMilliseconds(), "Milliseconds are different");
+					//traceAttributes(newHebrewDate);
+
+					newHebrewDate = dojox.date.hebrew.add(dateHebrew, "millisecond",  1204422);
+					newDate = dojo.date.add(date2, "millisecond",  1204422);
+					t.is(newHebrewDate.getHours(), newDate.getHours(), "Hours are different");
+					t.is(newHebrewDate.getMinutes(), newDate.getMinutes(), "Minutes are different");
+					t.is(newHebrewDate.getSeconds(), newDate.getSeconds(), "Seconds are different");
+					t.is(newHebrewDate.getMilliseconds(), newDate.getMilliseconds(), "Milliseconds are different");
+					//traceAttributes(newHebrewDate);
+				});
+			}
 		}
 	]
 );
diff --git a/dojox/date/tests/islamic/Date.js b/dojox/date/tests/islamic/Date.js
index 3dbb80a..123fdcd 100644
--- a/dojox/date/tests/islamic/Date.js
+++ b/dojox/date/tests/islamic/Date.js
@@ -3,6 +3,7 @@ dojo.require("dojox.date.islamic.Date");
 dojo.require("dojox.date.islamic.locale");
 dojo.require("dojox.date.islamic");
 dojo.require("dojo.date");
+dojo.require("dojo.date.locale");
 
 dojo.requireLocalization("dojo.cldr", "gregorian");
 dojo.requireLocalization("dojo.cldr", "islamic");
@@ -14,7 +15,7 @@ tests.register("dojox.date.tests.islamic.Date",
 			// NOTE: we can't set djConfig.extraLocale before bootstrapping unit tests, so directly
 			// load resources here for specific locales:
 
-			name: "date.locale",
+			name: "setup",
 			setUp: function() {
 				var partLocaleList = ["ar","en"];
 
@@ -27,7 +28,7 @@ tests.register("dojox.date.tests.islamic.Date",
 			tearDown: function() {
 				//Clean up bundles that should not exist if
 				//the test is re-run.
-				delete dojo.cldr.nls.islamic;
+			//				delete dojo.cldr.nls.islamic;
 			}
 		},
 		{
@@ -116,7 +117,7 @@ tests.register("dojox.date.tests.islamic.Date",
 				dojo.forEach(start, function(s, i) {
 					dateHijriRes = new dojox.date.islamic.Date(s[2], s[3], 1);
 					dateHijriStart = new dojox.date.islamic.Date(s[0], s[1], 1);
-					t.is(add[i], dojox.date.islamic.difference(dateHijriRes, dateHijriStart, "month"));
+					t.is(add[i], dojox.date.islamic.difference(dateHijriStart, dateHijriRes, "month"));
 				});
 			}
 		},
@@ -131,35 +132,35 @@ tests.register("dojox.date.tests.islamic.Date",
 
 				dojo.forEach(amouts, function(amount, i) {
 					dateIslamicAdd = dojox.date.islamic.add(dateIslamic, "month", amount);
-					t.is(dojox.date.islamic.difference(dateIslamicAdd, dateIslamic, "month"), amount);
+					t.is(dojox.date.islamic.difference(dateIslamic, dateIslamicAdd, "month"), amount);
 
 					dateIslamicAdd = dojox.date.islamic.add(dateIslamic, "year", amount);
-					t.is(amount, dojox.date.islamic.difference(dateIslamicAdd, dateIslamic, "year"));
+					t.is(amount, dojox.date.islamic.difference(dateIslamic, dateIslamicAdd, "year"));
 
 					dateIslamicAdd = dojox.date.islamic.add(dateIslamic, "week", amount);
-					t.is(amount, dojox.date.islamic.difference(dateIslamicAdd, dateIslamic, "week"));
+					t.is(amount, dojox.date.islamic.difference(dateIslamic, dateIslamicAdd, "week"));
 
 					dateIslamicAdd = dojox.date.islamic.add(dateIslamic, "weekday", amount);
-					t.is(amount, dojox.date.islamic.difference(dateIslamicAdd, dateIslamic, "weekday"));
+					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(dateIslamicAdd, dateIslamic, "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(dateIslamicAdd, dateIslamic, "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(dateIslamicAdd, dateIslamic, "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(dateIslamicAdd, dateIslamic, "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(dateIslamicAdd, dateIslamic, "millisecond"));
+					t.is(amount, dojox.date.islamic.difference(dateIslamic, dateIslamicAdd, "millisecond"));
 				});
 
 				var dateIslamicDiff = new dojox.date.islamic.Date(1431, 4, 7);
-				t.is(1, dojox.date.islamic.difference(dateIslamicDiff, dateIslamic));
+				t.is(1, dojox.date.islamic.difference(dateIslamic, dateIslamicDiff));
 			}
 		},
 		{
@@ -226,6 +227,68 @@ tests.register("dojox.date.tests.islamic.Date",
 				str = dojox.date.islamic.locale.format(dateIslamic, options);
 				t.is(str, "3:3:59");
 			}
+		},
+		{
+			name: "addMilliseconds",
+			runTest: function(t){												
+				var islamicDates = [
+							[5771, 8, 21, 10, 30],
+							[5771, 8, 21, 2, 2],
+							[5771, 8, 21, 8, 10], // "absolute" index of month, non-leap year
+							[5771, 8, 21, 12, 59],
+							[5771, 8, 21, 3, 33]
+						];
+						
+				var dates = [
+							[1432, 8, 21, 10, 30],
+							[1432, 8, 21, 2, 2],
+							[1432, 8, 21, 8, 10], // "absolute" index of month, non-leap year
+							[1432, 8, 21, 12, 59],
+							[1432, 8, 21, 3, 33]
+						];
+						
+				var traceAttributes = function(date){
+					console.log("getHours():" + date.getHours()+" getMinutes():"+date.getMinutes()+" getSeconds():"+date.getSeconds()+" getMilliseconds():"+date.getMilliseconds());
+				};
+						
+				var dateIslamic, date2;
+				dojo.forEach(islamicDates, function(date, i){
+					dateIslamic = new dojox.date.islamic.Date(date[0], date[1], date[2], date[3], date[4]);
+					date2 = new Date(dates[i][0], dates[i][1], dates[i][2], dates[i][3], dates[i][4]);			
+		
+					var newIslamicDate = dojox.date.islamic.add(dateIslamic, "millisecond",  1200);
+					var newDate = dojo.date.add(date2, "millisecond",  1200);
+					t.is(newIslamicDate.getHours(), newDate.getHours(), "Hours are different");
+					t.is(newIslamicDate.getMinutes(), newDate.getMinutes(), "Minutes are different");
+					t.is(newIslamicDate.getSeconds(), newDate.getSeconds(), "Seconds are different");
+					t.is(newIslamicDate.getMilliseconds(), newDate.getMilliseconds(), "Milliseconds are different");
+					//traceAttributes(newIslamicDate);
+
+					newIslamicDate = dojox.date.islamic.add(dateIslamic, "millisecond",  12022);
+					newDate = dojo.date.add(date2, "millisecond",  12022);
+					t.is(newIslamicDate.getHours(), newDate.getHours(), "Hours are different");
+					t.is(newIslamicDate.getMinutes(), newDate.getMinutes(), "Minutes are different");
+					t.is(newIslamicDate.getSeconds(), newDate.getSeconds(), "Seconds are different");
+					t.is(newIslamicDate.getMilliseconds(), newDate.getMilliseconds(), "Milliseconds are different");
+					//traceAttributes(newIslamicDate);
+
+					newIslamicDate = dojox.date.islamic.add(dateIslamic, "millisecond",  120422);
+					newDate = dojo.date.add(date2, "millisecond",  120422);
+					t.is(newIslamicDate.getHours(), newDate.getHours(), "Hours are different");
+					t.is(newIslamicDate.getMinutes(), newDate.getMinutes(), "Minutes are different");
+					t.is(newIslamicDate.getSeconds(), newDate.getSeconds(), "Seconds are different");
+					t.is(newIslamicDate.getMilliseconds(), newDate.getMilliseconds(), "Milliseconds are different");
+					//traceAttributes(newIslamicDate);
+
+					newIslamicDate = dojox.date.islamic.add(dateIslamic, "millisecond",  1204422);
+					newDate = dojo.date.add(date2, "millisecond",  1204422);
+					t.is(newIslamicDate.getHours(), newDate.getHours(), "Hours are different");
+					t.is(newIslamicDate.getMinutes(), newDate.getMinutes(), "Minutes are different");
+					t.is(newIslamicDate.getSeconds(), newDate.getSeconds(), "Seconds are different");
+					t.is(newIslamicDate.getMilliseconds(), newDate.getMilliseconds(), "Milliseconds are different");
+					//traceAttributes(newIslamicDate);
+				});
+			}
 		}
 	]
 );
diff --git a/dojox/date/tests/module.js b/dojox/date/tests/module.js
index 438c89c..3eeb05c 100644
--- a/dojox/date/tests/module.js
+++ b/dojox/date/tests/module.js
@@ -1,6 +1,8 @@
 dojo.provide("dojox.date.tests.module");
 
 try{
+	dojo.require("dojox.date.tests.timezone");
+	dojo.require("dojox.date.tests.timezoneFormatting");
 	dojo.require("dojox.date.tests.relative");
 	dojo.require("dojox.date.tests.hebrew.Date");
 	dojo.require("dojox.date.tests.islamic.Date");
diff --git a/dojox/date/tests/posix.js b/dojox/date/tests/posix.js
index e427447..147ac7d 100644
--- a/dojox/date/tests/posix.js
+++ b/dojox/date/tests/posix.js
@@ -19,7 +19,7 @@ tests.register("dojox.date.tests.posix",
 			tearDown: function(){
 				//Clean up bundles that should not exist if
 				//the test is re-run.
-				delete dojo.cldr.nls.gregorian;
+//				delete dojo.cldr.nls.gregorian;
 			}
 		},
 		{
diff --git a/dojox/date/tests/timezoneFormatting.js b/dojox/date/tests/timezoneFormatting.js
index a80fdbd..8d93c07 100644
--- a/dojox/date/tests/timezoneFormatting.js
+++ b/dojox/date/tests/timezoneFormatting.js
@@ -47,7 +47,7 @@ tests.register("dojox.date.tests.timezoneFormatting",
 				// 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'}));
 				// Shanghai (in zh-cn)
-				doh.is("2006\u5e748\u670811\u65e5\u661f\u671f\u4e94\u4e0a\u534808\u65f655\u520612\u79d2 CST", dojo.date.locale.format(date, {formatLength:'full',locale:'zh-cn',timezone:'Asia/Shanghai'}));
+				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'}));
 				// 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)
diff --git a/dojox/date/timezone.js b/dojox/date/timezone.js
index 71769ef..4cdd7dc 100644
--- a/dojox/date/timezone.js
+++ b/dojox/date/timezone.js
@@ -9,13 +9,14 @@
  * Credits: Ideas included from incomplete JS implementation of Olson
  * parser, "XMLDate" by Philippe Goetz (philippe.goetz at wanadoo.fr)
  *****************************************************************************/
-dojo.experimental("dojox.date.timezone");
-dojo.provide("dojox.date.timezone");
 
-dojo.require("dojo.date.locale");
+define(["dojo", "dojo/date", "dojo/date/locale", "dojo/_base/array", "dojo/_base/xhr"],
+	function(dojo, _dd, _ddl){
 
-(function(_d){
-	var cfg = _d.config;
+	dojo.experimental("dojox.date.timezone");
+	dojo.getObject("date.timezone", true, dojox);
+
+	var cfg = dojo.config;
 	var _zoneFiles = [ "africa", "antarctica", "asia", "australasia", "backward",
 					"etcetera", "europe", "northamerica", "pacificnew",
 					"southamerica" ];
@@ -32,7 +33,7 @@ dojo.require("dojo.date.locale");
 	// timezoneFileBasePath: String
 	//		A different location to pull zone files from
 	var timezoneFileBasePath = cfg.timezoneFileBasePath ||
-								_d.moduleUrl("dojox.date", "zoneinfo");
+								dojo.moduleUrl("dojox.date", "zoneinfo");
 	
 	// loadingScheme: String
 	//		One of "preloadAll", "lazyLoad" (Defaults "lazyLoad")
@@ -45,15 +46,16 @@ dojo.require("dojo.date.locale");
 					((loadingScheme == "preloadAll") ? _zoneFiles : "northamerica");
 
 	// Set our olson-zoneinfo content handler
-	_d._contentHandlers["olson-zoneinfo"] = function(xhr){
-		var str = _d._contentHandlers["text"](xhr);
-		var s = "";
-		var lines = str.split("\n");
-		var arr = [];
-		var chunk = "";
-		var zone = null;
-		var rule = null;
-		var ret = {zones: {}, rules: {}};
+	dojo._contentHandlers["olson-zoneinfo"] = function(xhr){
+		var str = dojo._contentHandlers["text"](xhr),
+			s = "",
+			lines = str.split("\n"),
+			arr = [],
+			chunk = "",
+			zone = null,
+			rule = null,
+			ret = {zones: {}, rules: {}};
+
 		for(var i = 0; i < lines.length; i++){
 			var l = lines[i];
 			if(l.match(/^\s/)){
@@ -103,13 +105,8 @@ dojo.require("dojo.date.locale");
 		// data: Object
 		//		The data to load - contains "zones" and "rules" parameters
 		data = data || {};
-		_zones = _d.mixin(_zones, data.zones||{});
-		_rules = _d.mixin(_rules, data.rules||{});
-	}
-	
-	function errorLoadingZoneFile(e){
-		console.error("Error loading zone file:", e);
-		throw e;
+		_zones = dojo.mixin(_zones, data.zones||{});
+		_rules = dojo.mixin(_rules, data.rules||{});
 	}
 	
 	function loadZoneFile(/* String */ fileName){
@@ -123,12 +120,15 @@ dojo.require("dojo.date.locale");
 		// TODO: Maybe behave similar to requireLocalization - rather than
 		//		Using dojo.xhrGet?
 		_loadedZones[fileName] = true;
-		_d.xhrGet({
+		dojo.xhrGet({
 			url: timezoneFileBasePath + "/" + fileName,
 			sync: true, // Needs to be synchronous so we can return values
 			handleAs: "olson-zoneinfo",
 			load: loadZoneData,
-			error: errorLoadingZoneFile
+			error: function(e){
+				console.error("Error loading zone file:", e);
+				throw e;
+			}
 		});
 	}
 	
@@ -321,11 +321,11 @@ dojo.require("dojo.date.locale");
 				d = new Date(getUTCStamp(year, month + 1, 1,
 										time[1] - 24, time[2], time[3],
 										off));
-				dtDay = _d.date.add(d, "minute", -off).getUTCDay();
+				dtDay = _dd.add(d, "minute", -off).getUTCDay();
 				// Set it to the final day of the correct weekday that month
 				incr = (day > dtDay) ? (day - dtDay - 7) : (day - dtDay);
 				if(incr !== 0){
-					d = _d.date.add(d, "hour", incr * 24);
+					d = _dd.add(d, "hour", incr * 24);
 				}
 				return d;
 			}else{
@@ -335,22 +335,22 @@ dojo.require("dojo.date.locale");
 						// The stated date of the month
 						d = new Date(getUTCStamp(year, month, parseInt(rule[4].substr(5), 10),
 									time[1], time[2], time[3], off));
-						dtDay = _d.date.add(d, "minute", -off).getUTCDay();
+						dtDay = _dd.add(d, "minute", -off).getUTCDay();
 						// Set to the first correct weekday after the stated date
 						incr = (day < dtDay) ? (day - dtDay + 7) : (day - dtDay);
 						if(incr !== 0){
-							d = _d.date.add(d, "hour", incr * 24);
+							d = _dd.add(d, "hour", incr * 24);
 						}
 						return d;
 					}else if(day.substr(3, 2) == '<='){
 						// The stated date of the month
 						d = new Date(getUTCStamp(year, month, parseInt(rule[4].substr(5), 10),
 									time[1], time[2], time[3], off));
-						dtDay = _d.date.add(d, "minute", -off).getUTCDay();
+						dtDay = _dd.add(d, "minute", -off).getUTCDay();
 						// Set to first correct weekday before the stated date
 						incr = (day > dtDay) ? (day - dtDay - 7) : (day - dtDay);
 						if(incr !== 0){
-							d = _d.date.add(d, "hour", incr * 24);
+							d = _dd.add(d, "hour", incr * 24);
 						}
 						return d;
 					}
@@ -367,7 +367,7 @@ dojo.require("dojo.date.locale");
 
 	function _getRulesForYear(/* Zone */ zone, /* int */ year){
 		var rules = [];
-		_d.forEach(_rules[zone[1]]||[], function(r){
+		dojo.forEach(_rules[zone[1]]||[], function(r){
 			// Clean up rules as needed
 			for(var i = 0; i < 2; i++){
 				switch(r[i]){
@@ -439,7 +439,7 @@ dojo.require("dojo.date.locale");
 				rlz = rlz.concat(_getRulesForYear(z, j));
 			}
 			rlz.sort(function(a, b){
-				return _d.date.compare(a.d, b.d);
+				return _dd.compare(a.d, b.d);
 			});
 			var rl;
 			for(j = 0, rl; (rl = rlz[j]); j++){
@@ -448,16 +448,16 @@ dojo.require("dojo.date.locale");
 					if(j === 0 && i > 0){
 						if(prevRules.length){
 							// We have a previous rule - so use it
-							rl.d = _d.date.add(rl.d, "minute", prevRules[prevRules.length - 1].r[6]);
-						}else if(_d.date.compare(new Date(prevRange[1]), rl.d, "date") === 0){
+							rl.d = _dd.add(rl.d, "minute", prevRules[prevRules.length - 1].r[6]);
+						}else if(_dd.compare(new Date(prevRange[1]), rl.d, "date") === 0){
 							// No previous rules - but our date is the same as the
 							// previous zone ended on - so use that.
 							rl.d = new Date(prevRange[1]);
 						}else{
-							rl.d = _d.date.add(rl.d, "minute", getOffsetInMins(prevZone[1]));
+							rl.d = _dd.add(rl.d, "minute", getOffsetInMins(prevZone[1]));
 						}
 					}else if(j > 0){
-						rl.d = _d.date.add(rl.d, "minute", prevRule.r[6]);
+						rl.d = _dd.add(rl.d, "minute", prevRule.r[6]);
 					}
 				}
 			}
@@ -479,7 +479,7 @@ dojo.require("dojo.date.locale");
 					utcStmp = r[1] = _getRuleStart([0,0,0,z[4],z[5],z[6]||"0"],
 											year, ((time[4] == "u") ? 0 : z[0])).getTime();
 				}
-				var matches = _d.filter(rlz, function(rl, idx){
+				var matches = dojo.filter(rlz, function(rl, idx){
 					var o = idx > 0 ? rlz[idx - 1].r[6] * 60 * 1000 : 0;
 					return (rl.d.getTime() < utcStmp + o);
 				});
@@ -640,7 +640,7 @@ dojox.date.timezone.getAllZones = function(){
 	//	Returns an array of zones that have been loaded
 };
 =====*/
-	_d.setObject("dojox.date.timezone", {
+	dojo.setObject("dojox.date.timezone", {
 		getTzInfo: function(/* Date */ dt, /* String */ tz){
 			// Lazy-load any zones not yet loaded
 			if(loadingScheme == "lazyLoad"){
@@ -687,18 +687,16 @@ dojox.date.timezone.getAllZones = function(){
 	if(typeof defaultZoneFile == "string" && defaultZoneFile){
 		defaultZoneFile = [defaultZoneFile];
 	}
-	if(_d.isArray(defaultZoneFile)){
-		_d.forEach(defaultZoneFile, function(f){
-			loadZoneFile(f);
-		});
+	if(dojo.isArray(defaultZoneFile)){
+		dojo.forEach(defaultZoneFile, loadZoneFile);
 	}
 	
 	// And enhance the default formatting functions
 	// If you pass "timezone" as a parameter to your format options,
 	// then you get the date formatted (and offset) for that timezone
-	var oLocaleFmt = _d.date.locale.format,
-		oGetZone = _d.date.locale._getZone;
-	_d.date.locale.format = function(dateObject, options){
+	var oLocaleFmt = _ddl.format,
+		oGetZone = _ddl._getZone;
+	_ddl.format = function(dateObject, options){
 		options = options||{};
 		if(options.timezone && !options._tzInfo){
 			// Store it in our options so we can use it later
@@ -712,10 +710,10 @@ dojox.date.timezone.getAllZones = function(){
 		}
 		return oLocaleFmt.call(this, dateObject, options);
 	};
-	_d.date.locale._getZone = function(dateObject, getName, options){
+	_ddl._getZone = function(dateObject, getName, options){
 		if(options._tzInfo){
 			return getName ? options._tzInfo.tzAbbr : options._tzInfo.tzOffset;
 		}
 		return oGetZone.call(this, dateObject, getName, options);
 	};
-})(dojo);
+});
diff --git a/dojox/dnd/BoundingBoxController.js b/dojox/dnd/BoundingBoxController.js
index 807e660..574655c 100644
--- a/dojox/dnd/BoundingBoxController.js
+++ b/dojox/dnd/BoundingBoxController.js
@@ -1,130 +1,139 @@
-dojo.provide("dojox.dnd.BoundingBoxController");
+define(["dojo", "dojox"], function(dojo, dojox) {
 
-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
-		
-		// x,y start and end coordinates for the bounding box
-		_startX: null,
-		_startY: null,
-		_endX: null,
-		_endY: null,
+	return dojo.declare('dojox.dnd.BoundingBoxController', null, {
 
-		constructor: function(sources, domNode){
-			//	summary:
-			//		Sets mouse handlers for the document to capture when a user
-			//		is trying to draw a bounding box.
-			//	sources: Array:
-			//		an array of dojox.dnd.Selectors which need to be aware of
-			//		the positioning of the bounding box.
-			//	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"),
-				dojo.connect(dojo.doc, "onmouseup",   this, "_onMouseUp"),
-				// cancel text selection and text dragging
-				//dojo.connect(dojo.doc, "ondragstart",   dojo.stopEvent),
-				//dojo.connect(dojo.doc, "onselectstart", dojo.stopEvent),
-				// when a user is scrolling using a scrollbar, don't draw the bounding box.
-				dojo.connect(dojo.doc, "onscroll", this, "_finishSelecting")
-			];
-			// set up a subscription so the client can easily cancel a user drawing a bounding box.
-			this.subscriptions = [
-				dojo.subscribe("/dojox/bounding/cancel", this, "_finishSelecting")
-			];
-			dojo.forEach(sources, function(item){
-				// listen for "/dojox/dnd/bounding" events eminating from the bounding box.
-				// for each of the dojox.dnd.selectors passed in args.
-				if(item.selectByBBox){
-					this.subscriptions.push(dojo.subscribe("/dojox/dnd/bounding", item, "selectByBBox"));
+			// 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,
+			_startY: null,
+			_endX: null,
+			_endY: null,
+
+			constructor: function(sources, domNode) {
+				//	summary:
+				//		Sets mouse handlers for the document to capture when a user
+				//		is trying to draw a bounding box.
+				//	sources: Array:
+				//		an array of dojox.dnd.Selectors which need to be aware of
+				//		the positioning of the bounding box.
+				//	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'),
+					dojo.connect(dojo.doc, 'onmouseup', this, '_onMouseUp'),
+					// cancel text selection and text dragging
+					//dojo.connect(dojo.doc, "ondragstart",   dojo.stopEvent),
+					//dojo.connect(dojo.doc, "onselectstart", dojo.stopEvent),
+					// when a user is scrolling using a scrollbar, don't draw the bounding box.
+					dojo.connect(dojo.doc, 'onscroll', this, '_finishSelecting')
+				];
+				// set up a subscription so the client can easily cancel a user drawing a bounding box.
+				this.subscriptions = [
+					dojo.subscribe('/dojox/bounding/cancel', this, '_finishSelecting')
+				];
+				dojo.forEach(sources, function(item) {
+					// listen for "/dojox/dnd/bounding" events eminating from the bounding box.
+					// for each of the dojox.dnd.selectors passed in args.
+					if (item.selectByBBox) {
+						this.subscriptions.push(dojo.subscribe('/dojox/dnd/bounding', item, 'selectByBBox'));
+					}
+				}, this);
+				this.domNode = dojo.byId(domNode);
+				dojo.style(this.domNode, {
+					position: 'absolute',
+					display: 'none'
+				});
+			},
+
+			destroy: function() {
+				// summary:
+				//		prepares this object to be garbage-collected
+				dojo.forEach(this.events, dojo.disconnect);
+				dojo.forEach(this.subscriptions, dojo.unsubscribe);
+				this.domNode = null;
+			},
+
+			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.
+				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.
+				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.
+				if (this.shouldStartDrawingBox(evt) && dojo.mouseButtons.isLeft(evt)) {
+					if (this._startX == null) {
+						this._startX = evt.clientX;
+						this._startY = evt.clientY;
+					}
+					this.events.push(
+						dojo.connect(dojo.doc, 'onmousemove', this, '_onMouseMove')
+					);
 				}
-			}, this)
-			this.domNode = dojo.byId(domNode);
-			dojo.style(this.domNode, {
-				position: "absolute",
-				display:  "none"
-			});
-		},
-		
-		destroy: function(){
-			// summary:
-			//		prepares this object to be garbage-collected
-			dojo.forEach(this.events, dojo.disconnect);
-			dojo.forEach(this.subscriptions, dojo.unsubscribe);
-			this.domNode = null;
-		},
-		
-		boundingBoxIsViable: function(){
-			// 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.
-			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.
-			if(dojo.mouseButtons.isLeft(evt)){
-				if(this._startX === null){
-					this._startX = evt.clientX;
-					this._startY = evt.clientY;
+			},
+
+			_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.
+				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.
+				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.
+					dojo.publish('/dojox/dnd/bounding', [this._startX, this._startY, this._endX, this._endY]);
 				}
-				this.events.push(
-					dojo.connect(dojo.doc, "onmousemove", this, "_onMouseMove")
-				);
-			}
-		},
-		
-		_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.
-			this._endX = evt.clientX;
-			this._endY = evt.clientY;
-			this._drawBoundingBox();
-		},
+				this._finishSelecting();
+			},
 
-		_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.
-			if(this._endX !== null && this.boundingBoxIsViable()){
-				// the user has moused up ... tell the selector to check to see whether
-				// any nodes within the bounding box need to be selected.
-				dojo.publish("/dojox/dnd/bounding", [this._startX, this._startY, this._endX, this._endY]);
-			}
-			this._finishSelecting();
-		},
-		
-		_finishSelecting: function(){
-			// 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");
-				this._startX = this._endX = null;
+			_finishSelecting: function() {
+				// 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');
+					this._startX = null;
+					this._endX = null;
+				}
+			},
+
+			_drawBoundingBox: function() {
+				// 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',
+					width: Math.abs(this._startX - this._endX) + 'px',
+					height: Math.abs(this._startY - this._endY) + 'px',
+					display: ''
+				});
 			}
-		},
-		
-		_drawBoundingBox: function(){
-			// 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",
-				width:    Math.abs(this._startX - this._endX) + "px",
-				height:   Math.abs(this._startY - this._endY) + "px",
-				display:  ""
-			});
 		}
-	}
-);
+	);
+});
\ No newline at end of file
diff --git a/dojox/dnd/Selector.js b/dojox/dnd/Selector.js
index 041c261..2eaa7b7 100644
--- a/dojox/dnd/Selector.js
+++ b/dojox/dnd/Selector.js
@@ -1,159 +1,210 @@
-dojo.provide("dojox.dnd.Selector");
+define(["dojo", "dojox", "dojo/dnd/Selector"], function(dojo, dojox) {
 
-dojo.require("dojo.dnd.Selector");
+	return dojo.declare('dojox.dnd.Selector', dojo.dnd.Selector, {
 
-dojo.declare(
-	"dojox.dnd.Selector",
-	dojo.dnd.Selector,
-	{
-		isSelected: function(node){
-			//	summary:
-			//		checks if node is selected
-			//	node: String|DomNode:
-			//		Node to check (id or DOM Node)
-			var id = dojo.isString(node) ? node : node.id,
-				item = this.getItem(id);
-			return item && this.selected[id];	// Boolean
-		},
-		
-		selectNode: function(node, add){
-			//	summary:
-			//		selects a node
-			//	node: String|DomNode:
-			//		Node to select (id or DOM Node)
-			//	add: Boolean?:
-			//		If true, node is added to selection, otherwise current
-			//		selection is removed, and node will be the only selection.
-			if(!add){
-				this.selectNone();
-			}
-			var id = dojo.isString(node) ? node : node.id,
-				item = this.getItem(id);
-			if(item){
-				this._removeAnchor();
-				this.anchor = dojo.byId(node);
-				this._addItemClass(this.anchor, "Anchor");
-				this.selection[id] = 1;
-				this._addItemClass(this.anchor, "Selected");
-			}
-			return this;	// self
-		},
-		
-		deselectNode: function(node){
-			//	summary:
-			//		deselects a node
-			//	node: String|DomNode:
-			//		Node to deselect (id or DOM Node)
-			var id = dojo.isString(node) ? node : node.id,
-				item = this.getItem(id);
-			if(item && this.selection[id]){
-				if(this.anchor === dojo.byId(node)){
+			conservative: true,
+			
+			isSelected: function(node) {
+				//	summary:
+				//		checks if node is selected
+				//	node: String|DomNode:
+				//		Node to check (id or DOM Node)
+				var id = dojo.isString(node) ? node : node.id,
+					item = this.getItem(id);
+				return item && this.selected[id];	// Boolean
+			},
+
+			selectNode: function(node, add) {
+				//	summary:
+				//		selects a node
+				//	node: String|DomNode:
+				//		Node to select (id or DOM Node)
+				//	add: Boolean?:
+				//		If true, node is added to selection, otherwise current
+				//		selection is removed, and node will be the only selection.
+				if (!add) {
+					this.selectNone();
+				}
+				var id = dojo.isString(node) ? node : node.id,
+					item = this.getItem(id);
+				if (item) {
 					this._removeAnchor();
+					this.anchor = dojo.byId(node);
+					this._addItemClass(this.anchor, 'Anchor');
+					this.selection[id] = 1;
+					this._addItemClass(this.anchor, 'Selected');
 				}
-				delete this.selection[id];
-				this._removeItemClass(this.anchor, "Selected");
-			}
-			return this;	// self
-		},
-		
-		selectByBBox: function(left, top, right, bottom, add) {
-			//	summary:
-			//		selects nodes by bounding box
-			//	left: Number:
-			//		Left coordinate of the bounding box
-			//	top: Number:
-			//		Top coordinate of the bounding box
-			//	right: Number:
-			//		Right coordinate of the bounding box
-			//	bottom: Number:
-			//		Bottom coordinate of the bounding box
-			//	add: Boolean?:
-			//		If true, node is added to selection, otherwise current
-			//		selection is removed, and node will be the only selection.
+				return this;	// self
+			},
 
-			// user has drawn a bounding box ... time to see whether any dom nodes
-			// in this container satisfy the bounding box range.
-			if(!add){
-				this.selectNone();
-			}
-			this.forInItems(function(data, id){
-				var node = dojo.byId(id);
-				if(node && this._isBoundedByBox(node, left, top, right, bottom)){
-					this.selectNode(id, true);
+			deselectNode: function(node) {
+				//	summary:
+				//		deselects a node
+				//	node: String|DomNode:
+				//		Node to deselect (id or DOM Node)
+				var id = dojo.isString(node) ? node : node.id,
+					item = this.getItem(id);
+				if (item && this.selection[id]) {
+					if (this.anchor === dojo.byId(node)) {
+						this._removeAnchor();
+					}
+					delete this.selection[id];
+					this._removeItemClass(this.anchor, 'Selected');
 				}
-			}, this);
-			return this;	// self
-		},
-		
-		_isBoundedByBox: function(node, left, top, right, bottom) {
-			//	summary:
-			//		figures out whether certain coodinates bound a particular
-			//		dom node.
-			//	node: String|DomNode:
-			//		Node to check (id or DOM Node)
-			//	left: Number:
-			//		Left coordinate of the bounding box
-			//	top: Number:
-			//		Top coordinate of the bounding box
-			//	right: Number:
-			//		Right coordinate of the bounding box
-			//	bottom: Number:
-			//		Bottom coordinate of the bounding box
-			var c = dojo.coords(node), t;
-			// normalize input
-			if(left > right){
-				t = left;
-				left = right;
-				right = t;
-			}
-			if(top > bottom){
-				t = top;
-				top = bottom;
-				bottom = t;
-			}
-			return c.x >= left && c.x + c.w <= right && c.y >= top && c.y + c.h <= bottom;	// Boolean
-		},
-		
-		shift: function(toNext, add) {
-			//	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:
-			//		If true, we select the next node, otherwise the previous one.
-			//	add: Boolean?:
-			//		If true, add to selection, otherwise current selection is
-			//		removed before adding any nodes.
-			var selectedNodes = this.getSelectedNodes();
-			if(selectedNodes && selectedNodes.length) {
-				// only delegate to selectNode if at least one node is selected.
-				// If multiple nodes are selected assume that we go with
-				// the last selected node.
-				this.selectNode(this._getNodeId(selectedNodes[selectedNodes.length - 1].id, toNext), add);
-			}
-		},
+				return this;	// self
+			},
+
+			selectByBBox: function(left, top, right, bottom, add) {
+				//	summary:
+				//		selects nodes by bounding box
+				//	left: Number:
+				//		Left coordinate of the bounding box
+				//	top: Number:
+				//		Top coordinate of the bounding box
+				//	right: Number:
+				//		Right coordinate of the bounding box
+				//	bottom: Number:
+				//		Bottom coordinate of the bounding box
+				//	add: Boolean?:
+				//		If true, node is added to selection, otherwise current
+				//		selection is removed, and node will be the only selection.
+
+				// user has drawn a bounding box ... time to see whether any dom nodes
+				// in this container satisfy the bounding box range.
+				if (!add) {
+					this.selectNone();
+				}
+				this.forInItems(function(data, id) {
+					var node = dojo.byId(id);
+					if (node && this._isBoundedByBox(node, left, top, right, bottom)) {
+						this.selectNode(id, true);
+					}
+				}, this);
+				return this;	// self
+			},
+
+			_isBoundedByBox: function(node, left, top, right, bottom) {
+				//	summary:
+				//		figures out whether certain coodinates bound a particular
+				//		dom node.
+				//	node: String|DomNode:
+				//		Node to check (id or DOM Node)
+				//	left: Number:
+				//		Left coordinate of the bounding box
+				//	top: Number:
+				//		Top coordinate of the bounding box
+				//	right: Number:
+				//		Right coordinate of the bounding box
+				//	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);
+			},
 
-		_getNodeId: function(nodeId, toNext) {
-			//	summary:
-			//		finds a next/previous node in relation to nodeId
-			//	nodeId: String:
-			//		the id of the node to use as the base node
-			//	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) {
-				if(allNodes[i].id == nodeId) {
-					// have a match ... make sure we don't go outside
-					var j = Math.min(l - 1, Math.max(0, i + (toNext ? 1 : -1)));
-					if(i != j){
-						// we should be fine to go with the id the user has requested.
-						newId = allNodes[j].id;
+			shift: function(toNext, add) {
+				//	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:
+				//		If true, we select the next node, otherwise the previous one.
+				//	add: Boolean?:
+				//		If true, add to selection, otherwise current selection is
+				//		removed before adding any nodes.
+				var selectedNodes = this.getSelectedNodes();
+				if (selectedNodes && selectedNodes.length) {
+					// only delegate to selectNode if at least one node is selected.
+					// If multiple nodes are selected assume that we go with
+					// the last selected node.
+					this.selectNode(this._getNodeId(selectedNodes[selectedNodes.length - 1].id, toNext), add);
+				}
+			},
+
+			_getNodeId: function(nodeId, toNext) {
+				//	summary:
+				//		finds a next/previous node in relation to nodeId
+				//	nodeId: String:
+				//		the id of the node to use as the base node
+				//	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) {
+					if (allNodes[i].id == nodeId) {
+						// have a match ... make sure we don't go outside
+						var j = Math.min(l - 1, Math.max(0, i + (toNext ? 1 : -1)));
+						if (i != j) {
+							// we should be fine to go with the id the user has requested.
+							newId = allNodes[j].id;
+						}
+						break;
 					}
-					break;
 				}
+				// if we don't get a match, the newId defaults to the currently selected node
+				return newId;
+			},
+
+			_conservativeBBLogic: function(node, left, top, right, bottom) {
+				//	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
+				//		encompassed by the box determined by the left, top, right, bottom parameters.
+				var c = dojo.coords(node), t;
+				// normalize input
+				if (left > right) {
+					t = left;
+					left = right;
+					right = t;
+				}
+				if (top > bottom) {
+					t = top;
+					top = bottom;
+					bottom = t;
+				}
+				return c.x >= left && c.x + c.w <= right && c.y >= top && c.y + c.h <= bottom;	// Boolean
+			},
+
+			_liberalBBLogic: function(node, left, top, right, bottom) {
+				//	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
+				//		overlapping the coordinates of the node parameter constitutes a true
+				//		return value
+				var c = dojo.position(node), xBounded, yBounded, tlx, tly, brx, bry, leftGreater = false, bottomGreater = false,
+				nodeTlx = c.x, nodeTly = c.y, nodeBrx = c.x + c.w, nodeBry = c.y + c.h;
+				// tlx, tly represents the x,y coordinates for the top left of the bounding box
+				// brx, bry represents the x,y coordinates for the bottom right of the bounding box
+				// nodeTlx, nodeTly represents the x,y coordinates for the top left of the dom node
+				// nodeBrx, nodeBry represents the x,y coordinates for the bottom right of the dom node
+				if (left < right) {
+					tlx = left;
+					tly = top;
+				} else {
+					leftGreater = true;
+					tlx = right;
+					tly = bottom;
+				}
+				if (top < bottom) {
+					bottomGreater = true;
+					brx = right;
+					bry = bottom;
+				} else {
+					brx = left;
+					bry = top;
+					tlx = right;
+					tly = bottom;
+				}
+				if (leftGreater && bottomGreater) {
+					// accommodate for the case where the user is drawing from top down and from right to left.
+					brx = left;
+					bry = bottom;
+					tlx = right;
+					tly = top;
+				}
+				xBounded = (nodeTlx >= tlx || nodeBrx <= brx) && (tlx <= nodeBrx && brx >= nodeTlx) || (nodeTlx <= tlx && nodeBrx >= brx);
+				yBounded = (tly <= nodeBry && bry >= nodeTly) || (nodeBry >= bry && nodeTly <= bry);
+				return xBounded && yBounded;	// Boolean
 			}
-			// if we don't get a match, the newId defaults to the currently selected node
-			return newId;
 		}
-	}
-);
+	);
+});
\ No newline at end of file
diff --git a/dojox/dnd/tests/robot/test_selector.html b/dojox/dnd/tests/robot/test_selector.html
index 7b4fbc6..e69de29 100644
--- a/dojox/dnd/tests/robot/test_selector.html
+++ b/dojox/dnd/tests/robot/test_selector.html
@@ -1,71 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<title>doh.robot dojox DnD Test</title>
-	
-		<style>
-			@import "../../../../util/doh/robot/robot.css";
-		</style>
-
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
-		<script type="text/javascript">
-			dojo.require("dojo.robotx");
-			
-			dojo.addOnLoad(function() {
-	
-				doh.robot.initRobot('../test_selector.html');
-	
-				doh.register('dojox.robot.DndSelectorTest', [
-					{
-						name: 'dojox dnd shift down test',
-						timeout: 10000,
-						runTest: function() {
-							var d = new doh.Deferred();
-							doh.robot.mouseMoveAt('blonde', 1000);
-							doh.robot.mouseClick({left:true, middle:false, right:false}, 100);
-							doh.robot.mouseClick({left:true, middle:false, right:false}, 100);
-							doh.robot.mouseMoveAt('header', 250);
-							doh.robot.mouseClick({left:true, middle:false, right:false}, 100);
-							doh.robot.typeKeys("d", 100);
-							doh.robot.sequence(function() {
-								dojo.query("> div", dojo.byId('albums')).forEach(function(item, index, array) {
-									if(index == 1) {
-										if(dojo.hasClass(item, "dojoDndItemSelected") && item.id == "highway") {
-											d.callback(true);		
-										} else {
-											d.errback(new Error("Second item in the album list was not selected"));		
-										}
-									} else {
-										doh.assertFalse(dojo.hasClass(item, "dojoDndItemSelected"));
-									}
-								});
-							}, 3000);
-							return d;
-						}
-					},
-					{
-						name: 'dojox dnd shift up test',
-						timeout: 10000,
-						runTest: function() {
-							var d = new doh.Deferred();
-							doh.robot.typeKeys("u", 100);
-							doh.robot.sequence(function() {
-								dojo.query("> div", dojo.byId('albums')).forEach(function(item, index, array) {
-									if(index == 0) {
-										if(dojo.hasClass(item, "dojoDndItemSelected") && item.id == "blonde") {
-											d.callback(true);		
-										} else {
-											d.errback(new Error("First item in the album list was not selected"));		
-										}
-									}
-								});
-							}, 1000);
-							return d;
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-	</head>
-</html>
\ No newline at end of file
diff --git a/dojox/dnd/tests/runTests.html b/dojox/dnd/tests/runTests.html
new file mode 100644
index 0000000..dbfc116
--- /dev/null
+++ b/dojox/dnd/tests/runTests.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.dnd Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?testModule=dojox.dnd.tests.testAll">
+	</head>
+	<body>
+		Redirecting to D.O.H runner.
+	</body>
+</html>
\ No newline at end of file
diff --git a/dojox/dnd/tests/testAll.js b/dojox/dnd/tests/testAll.js
new file mode 100644
index 0000000..cf8da6c
--- /dev/null
+++ b/dojox/dnd/tests/testAll.js
@@ -0,0 +1,8 @@
+dojo.provide('dojox.dnd.tests.testAll');
+
+try {
+	doh.registerUrl('dojox.dnd.tests.selector', dojo.moduleUrl('dojox.dnd.tests', 'test_selector.html'));
+	doh.registerUrl('dojox.dnd.tests.boundingbox', dojo.moduleUrl('dojox.dnd.tests', 'test_boundingBoxController.html'));
+}catch (e) {
+	doh.debug(e);
+}
\ No newline at end of file
diff --git a/dojox/dnd/tests/test_boundingBoxController.html b/dojox/dnd/tests/test_boundingBoxController.html
new file mode 100644
index 0000000..7a2ea77
--- /dev/null
+++ b/dojox/dnd/tests/test_boundingBoxController.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>dojox dnd BoundingBoxController</title>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+        <style type="text/css">
+            @import "../../../dojo/resources/dojo.css";
+            @import "../../../dojo/tests/dnd/dndDefault.css";
+            body { padding: 20px; }
+            #boundingBox {
+                background:#999;
+                border:1px solid #2B2B2B;
+                opacity:0.6;
+                position:absolute;
+				z-index:19999;
+			}
+		</style>
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript">
+			dojo.require("dojox.dnd.BoundingBoxController");
+			dojo.require("dojox.dnd.Selector");
+			dojo.require("doh.runner");
+			mockEvent = function(args) {
+				var evt = {
+					stopPropagation: function() {},
+					preventDefault: function() {},
+					button: 0
+				};
+				dojo.mixin(evt, args);
+				return evt;
+			};
+			dojo.addOnLoad(function(){
+				source = new dojox.dnd.Selector(dojo.byId("source"));
+				doh.register("dojox.dnd.BoundingBoxController",
+					[
+						{ 
+							name: "testMouseDownUp",
+							timeout: 1000, 
+							setUp: function() {
+								source.conservative = false;
+								bbc = new dojox.dnd.BoundingBoxController([source], dojo.byId("boundingBox"));
+							},
+							runTest: function() {
+								var def = new doh.Deferred(), res = false,
+								s = dojo.subscribe("/dojox/dnd/bounding", function() {
+									dojo.unsubscribe(s);
+									res = true;
+								});
+								bbc._onMouseDown(mockEvent({clientX: 1, clientY: 1}));
+								bbc._onMouseMove(mockEvent({clientX: 1000, clientY: 1000}));
+								doh.assertTrue(dojo.style(dojo.byId("boundingBox"), "display") !== "none");
+								bbc._onMouseUp(mockEvent());
+								doh.assertTrue(source.getSelectedNodes().length === 3);
+								setTimeout(function() {
+									res && dojo.style(dojo.byId("boundingBox"), "display") === "none" ? def.callback(true) : def.errback(false);
+								}, 500);
+								return def;
+							},
+							tearDown: function() {
+								
+							}
+						}
+					]
+				);
+				doh.run();
+			});
+		</script>
+	</head>
+	<body>
+		<h1 id="header">Dojox DnD BoundingBoxController test</h1>
+		<div id="source" class="container">
+			<div id="blonde" class="dojoDndItem">Blonde on Blonde</div>
+			<div id="highway" class="dojoDndItem">Highway 61 Revisited</div>
+			<div id="tracks" class="dojoDndItem">Blood on the Tracks</div>
+		</div>
+		<div id="boundingBox"></div>
+	</body>
+</html>
\ No newline at end of file
diff --git a/dojox/dnd/tests/test_selector.html b/dojox/dnd/tests/test_selector.html
index 6396004..6ee2341 100644
--- a/dojox/dnd/tests/test_selector.html
+++ b/dojox/dnd/tests/test_selector.html
@@ -2,44 +2,64 @@
 <html>
 	<head>
 		<title>Dojox DnD selector test</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 		<style type="text/css">
 			@import "../../../dojo/resources/dojo.css";
 			@import "../../../dojo/tests/dnd/dndDefault.css";
 			body { padding: 20px; }
 		</style>
-		<style title="text/css">
-			#boundingBox {
-				background: #999;
-				border: 1px solid #2B2B2B;
-				opacity: 0.5;
-				filter: alpha(opacity = 60); /* for IE */
-				position: absolute;
-				z-index: 19999;
-			}
-			#albums {
-				position: relative;
-				width: 200px;
-			}
-		</style>
 		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojox.dnd.Selector");
-			dojo.require("dojox.dnd.BoundingBoxController");
-			var albums, bb;
-			var init = function() {
-				albums = new dojox.dnd.Selector(dojo.byId("albums"));
+			dojo.require("doh.runner");
+			var source,
+			init = function() {
+				source = new dojox.dnd.Selector(dojo.byId("source"));
 				dojo.connect(dojo.doc, "onkeydown", dojo.hitch(this, function(evt) {
 					// would usually use dojo.keys.UP_ARROW/dojo.keys.DOWN_ARROW
 					// but can't seem to get that working with doh. Instead, I'm using
 					// 'u' as an indicator for up and 'd' as an indicator for down.
-					if(evt.keyCode == dojo.keys.UP_ARROW) {
-						albums.shift(false, evt.shiftKey);
+					if(evt.keyCode == 85) {
+						source.shift(-1, evt.shiftKey);
 					}
-					if(evt.keyCode == dojo.keys.DOWN_ARROW) {
-						albums.shift(true, evt.shiftKey);
+					if(evt.keyCode == 68) {
+						source.shift(1, evt.shiftKey);
 					}
 				}));
-				bb = new dojox.dnd.BoundingBoxController([albums], "boundingBox");
+				doh.register("dojox.dnd.SelectorMixin",
+					[
+						{
+							name: "testAll", 
+							timeout: 3000, 
+							setUp: function() {
+								
+							},
+							runTest: function() {
+								var def = new doh.Deferred();
+								source.conservative = false;
+								source.selectNode("blonde");
+								doh.assertTrue(source.getSelectedNodes().length == 1);
+								source.shift(1, true);
+								doh.assertTrue(source.getSelectedNodes().length == 2);
+								source.shift(-1);
+								doh.assertTrue(source.getSelectedNodes().length == 1);
+								source.selectAll();
+								doh.assertTrue(source.getSelectedNodes().length == 3);
+								source.selectByBBox(0, 0, 0, 0, false);
+								doh.assertTrue(source.getSelectedNodes().length == 0);
+								source.selectAll(1000, 1000, 1, 1, true);
+								setTimeout(function() {
+									source.getSelectedNodes().length == 3 ? def.callback(true) : def.errback(false);
+								}, 500);
+								return def;
+							},
+							tearDown: function() {
+								
+							}
+						}
+					]
+				);
+				doh.run();
 			};
 			dojo.addOnLoad(init);
 		</script>
@@ -47,11 +67,10 @@
 	<body>
 		<h1 id="header">Dojox DnD selector test</h1>
 		<p>Use the up/down arrows to iterate through the list after selecting one.</p>
-		<div id="albums" class="container">
-			<div id="blonde"  class="dojoDndItem">Blonde on Blonde</div>
+		<div id="source" class="container">
+			<div id="blonde" class="dojoDndItem">Blonde on Blonde</div>
 			<div id="highway" class="dojoDndItem">Highway 61 Revisited</div>
-			<div id="tracks"  class="dojoDndItem">Blood on the Tracks</div>
+			<div id="tracks" class="dojoDndItem">Blood on the Tracks</div>
 		</div>
-		<div id="boundingBox" style="display:none;"></div>
 	</body>
 </html>
\ No newline at end of file
diff --git a/dojox/dojox.profile.js b/dojox/dojox.profile.js
new file mode 100644
index 0000000..dab25e0
--- /dev/null
+++ b/dojox/dojox.profile.js
@@ -0,0 +1,68 @@
+var profile = (function(){
+	var testResourceRe = /\/tests\//,
+
+		copyOnly = function(filename, mid){
+			var list = {
+				"dojox/dojox.profile":1,
+				"dojox/package.json":1,
+				"dojox/mobile/themes/common/compile":1
+			};
+			return (mid in list) || /^dojox\/resources\//.test(mid) || /(png|jpg|jpeg|gif|tiff)$/.test(filename);
+		},
+
+		excludes = [
+			"secure",
+			"cometd",
+			"data/(demos|ItemExplorer|StoreExplorer|restListener)",
+			"drawing",
+			"editor/plugins/(ResizeTableColumn|SpellCheck)",
+			"embed/(IE)",
+			"flash",
+			"gantt",
+			"help",
+			"image/(Gallery|SlideShow|ThumbnailPicker)",
+			"jq",
+			"jsonPath",
+			"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",
+			"xmpp"
+		],
+
+		excludesRe = new RegExp(("^dojox/(" + excludes.join("|") + ")").replace(/\//, "\\/")),
+
+		usesDojoProvideEtAl = function(mid){
+			return excludesRe.test(mid);
+		};
+
+	return {
+		resourceTags:{
+			test: function(filename, mid){
+				return testResourceRe.test(mid);
+			},
+
+			copyOnly: function(filename, mid){
+				return copyOnly(filename, mid);
+			},
+
+			amd: function(filename, mid){
+				return !testResourceRe.test(mid) && !copyOnly(filename, mid) && !usesDojoProvideEtAl(mid) && /\.js$/.test(filename);
+			},
+
+			miniExclude: function(filename, mid){
+				return 0;
+			}
+		},
+
+		trees:[
+			[".", ".", /(\/\.)|(~$)/]
+		]
+	};
+})();
diff --git a/dojox/drawing/Drawing.js b/dojox/drawing/Drawing.js
index 20a18aa..f812a63 100755
--- a/dojox/drawing/Drawing.js
+++ b/dojox/drawing/Drawing.js
@@ -131,9 +131,8 @@ dojo.provide("dojox.drawing.Drawing");
 			this.stencilTypeMap = {};
 			this.srcRefNode = node; // need this?
 			this.domNode = node;
-			var str = dojo.attr(node, "plugins"); // FIXME: get this from props if available
-			if(str){
-				this.plugins = eval(str);
+			if(props.plugins){
+				this.plugins = eval(props.plugins);
 			}else{
 				this.plugins = [];
 			}
@@ -248,7 +247,6 @@ dojo.provide("dojox.drawing.Drawing");
 				});
 				return;
 			}
-			
 			dojo.forEach(this.plugins, function(p, i){
 				var props = dojo.mixin({
 					util:this.util,
@@ -544,6 +542,13 @@ dojo.provide("dojox.drawing.Drawing");
 			}
 		},
 		
+		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");
+		},
+		
 		unSetTool: function(){
 			// summary:
 			//		Destroys current tool
diff --git a/dojox/drawing/README b/dojox/drawing/README
index 98bda14..e14f3a2 100644
--- a/dojox/drawing/README
+++ b/dojox/drawing/README
@@ -22,7 +22,7 @@ dojo.gfx
 -------------------------------------------------------------------------------
 Documentation
 
-http://docs.dojocampus.org/dojox/drawing
+http://dojotoolkit.org/reference-guide/dojox/drawing.html
 -------------------------------------------------------------------------------
 Installation instructions
 
diff --git a/dojox/drawing/annotations/Angle.js b/dojox/drawing/annotations/Angle.js
index 7e89231..d80c22d 100755
--- a/dojox/drawing/annotations/Angle.js
+++ b/dojox/drawing/annotations/Angle.js
@@ -101,4 +101,4 @@ dojox.drawing.annotations.Angle = dojox.drawing.util.oo.declare(
 		}
 	}
 
-)
\ No newline at end of file
+);
\ No newline at end of file
diff --git a/dojox/drawing/manager/Mouse.js b/dojox/drawing/manager/Mouse.js
index 03857df..1e91eef 100755
--- a/dojox/drawing/manager/Mouse.js
+++ b/dojox/drawing/manager/Mouse.js
@@ -31,13 +31,6 @@ dojox.drawing.manager.Mouse = dojox.drawing.util.oo.declare(
 		//		register as for onDoubleClick
 		doublClickSpeed:400,
 		
-		
-		// rightClickMenu: boolean
-		//		If true, right clicks bubble up so that context menus
-		//		can be attached to them or the default can be shown.
-		//		Otherwise right click is interpreted the same as a left click.
-		rightClickMenu: false,
-		
 		// private properties
 		
 		_lastx:0,
@@ -147,10 +140,8 @@ EventObject: function(){
 				}
 			});
 			dojo.connect(document, "mouseup", this, function(evt){
-				if(evt.button != dojo.mouseButtons.RIGHT){
-					dojo.disconnect(c);
-					_isDown = false;
-				}
+				dojo.disconnect(c);
+				_isDown = false;
 				this.up(evt);
 			});
 			dojo.connect(document, "mousemove", this, function(evt){
@@ -386,8 +377,8 @@ EventObject: function(){
 			//console.log("DOWN:", this.id, id, withinCanvas);
 			//console.log("this.drawingType:", this.drawingType);
 			
-			if(this.rightClickMenu && (evt.button == dojo.mouseButtons.RIGHT) && this.id == "mse"){
-				// Allow event to bubble for right click, for menus
+			if(evt.button == dojo.mouseButtons.RIGHT && this.id == "mse"){
+				//Allow right click events to bubble for context menus
 			}else{
 				evt.preventDefault();
 				dojo.stopEvent(evt);
diff --git a/dojox/drawing/manager/keys.js b/dojox/drawing/manager/keys.js
index ac796ad..6fb5837 100755
--- a/dojox/drawing/manager/keys.js
+++ b/dojox/drawing/manager/keys.js
@@ -83,7 +83,7 @@ dojo.provide("dojox.drawing.manager.keys");
 			//		NOTE: Not really used in code, but should work.
 			//		See manager.mouse for similar usage
 			//
-			var _handle = dojox.drawing.util.uid("listener");
+			var _handle = dojox.drawing.util.common.uid("listener");
 			this.listeners.push({
 				handle:_handle,
 				scope: options.scope || window,
diff --git a/dojox/drawing/plugins/drawing/GreekPalette.js b/dojox/drawing/plugins/drawing/GreekPalette.js
index b5b488c..0e7ec95 100644
--- a/dojox/drawing/plugins/drawing/GreekPalette.js
+++ b/dojox/drawing/plugins/drawing/GreekPalette.js
@@ -1,19 +1,25 @@
 dojo.provide("dojox.drawing.plugins.drawing.GreekPalette");
 
 dojo.require("dojox.drawing.library.greek");
+dojo.require("dijit.focus");
 dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
+dojo.require("dijit._TemplatedMixin");
 dojo.require("dijit._PaletteMixin");
 dojo.require("dojo.i18n");
 
 dojo.requireLocalization("dojox.editor.plugins", "latinEntities");
 
 dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
-	[dijit._Widget, dijit._Templated, dijit._PaletteMixin],
+	[dijit._Widget, dijit._TemplatedMixin, dijit._PaletteMixin],
 	{
 	// summary:
-	//		This plugin uses the palette dijit in order to give
-	//		tips for non-english (mostly greek for now) letters.
+	//		This plugin uses the palette dijit in order to give tips for
+	//		non-english (mostly greek for now) letters.
+	//
+	//		IMPORTANT!  Because it is a full blown dijit it is NOT loaded
+	//		like the other plugins.  INSTEAD currently it is instantiated
+	//		in markup.  TextBlock LOOKS FOR IT by ID - "greekPalette"
+	//		and if it finds it does the necessary initialization/connections.
 	// description:
 	//		Grid showing all available entity options which the
 	//		user can pick from.  The library loaded for use by the picker
@@ -22,13 +28,14 @@ dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
 	//
 	//		This works as a popup and as such its onChange and onCancel
 	//		close it.  TextBlock manages it, since it's what uses the assist
-	//		so opening it happens there.  In order to activate the plugin
-	//		add it to the dojox.drawing.Drawing node as shown below:
+	//		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:
-	// |	<div dojoType="dojox.drawing.Drawing" id="drawing" jsId="myDrawing" class="drawing"
-	//			     plugins="[{'name':'dojox.drawing.plugins.drawing.GreekPalette'}]" >
-
+	// |	<!--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;
@@ -54,9 +61,14 @@ dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
 		this._palette = rows;
 	},
 	
+	show: function(obj){
+		dojo.mixin(obj, {popup: this});
+		dijit.popup.open(obj);
+	},
+	
 	onChange: function(val){
 		var textBlock = this._textBlock;
-		dijit.popup.close(this);
+		dijit.popup.hide(this);
 		textBlock.insertText(this._pushChangeTo,val);
 		textBlock._dropMode = false;
 	},
@@ -64,11 +76,9 @@ 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.close(this);
+		dijit.popup.hide(this);
 		this._textBlock._dropMode = false;
 	},
-	
-	id: "dropdown",
 
 	// templateString: String
 	//		The template of this widget.  Using dojoxEntityPalette classes
@@ -127,7 +137,7 @@ dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
 			this.connect(cellNode, "onmouseenter", "_onCellMouseEnter");
 		}, this);
 	},
-        
+	
         _onCellMouseEnter: function(e){
 		// summary:
 		//		Simple function to handle updating the display at the bottom of
@@ -175,6 +185,7 @@ dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
 		if(!this.showPreview){
 			dojo.style(this.previewNode,"display","none");
 		}
+		dijit.popup.moveOffScreen(this);
 	},
 
 	_setCurrent: function(/*DOMNode*/ node){
@@ -296,30 +307,30 @@ 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.
+{
+	// 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;
-		},
+	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;
-		},
+	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+";";
-                }
+	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/resources/GreekPalette.css b/dojox/drawing/resources/GreekPalette.css
index 3b6015e..b1bb5e6 100644
--- a/dojox/drawing/resources/GreekPalette.css
+++ b/dojox/drawing/resources/GreekPalette.css
@@ -14,16 +14,16 @@
 .dojoxEntityPaletteCell {
 	/* individual cell of the drop down */
 	border: 1px dotted gray;
-	width: 20px;	/* todo: don't hardcode width/height; it's neither nececessary nor a11y safe */
+	width: 20px;	/* todo: don't hardcode width/height; it's neither necessary nor a11y safe */
 	line-height: 18px;
 	overflow: hidden;
 	z-index: 10;
 	text-align: center;
 }
 
-.dojoxEntityPaletteCellHover, .dojoxEntityPaletteCellActive, .dojoxEntityPaletteCellFocused {
+.dojoxEntityPaletteCell:hover, .dojoxEntityPaletteCell:active, .dojoxEntityPaletteCell:focus {
 	width: 18px;
-        line-height: 16px;
+    line-height: 16px;
 	overflow: hidden;
 	cursor: default;
 	border:1px dashed #000;
diff --git a/dojox/drawing/tests/drawing.html b/dojox/drawing/tests/drawing.html
index 0af4766..e190525 100755
--- a/dojox/drawing/tests/drawing.html
+++ b/dojox/drawing/tests/drawing.html
@@ -162,7 +162,7 @@
 		</div>
 
 		<div dojoType="dojox.drawing.Drawing" id="drawingNode" jsId="myDrawing" drawingType="canvas" class="drawing"
-			 plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{gap:100}},{'name':'dojox.drawing.plugins.drawing.GreekPalette'}]">
+			 plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{gap:100}}]">
 
 		</div>
 	</div>
@@ -181,5 +181,6 @@
 	<br/>
 
 	<textarea id="data"></textarea>
+	<div dojoType="dojox.drawing.plugins.drawing.GreekPalette" id="greekPalette"></div>
 </body>
 </html>
diff --git a/dojox/drawing/tests/test_drawing.html b/dojox/drawing/tests/test_drawing.html
index 0948e14..0297378 100644
--- a/dojox/drawing/tests/test_drawing.html
+++ b/dojox/drawing/tests/test_drawing.html
@@ -138,7 +138,7 @@
 	<div id="conEdit" contenteditable="true"></div>
 	<div id="wrapper">
 		<div dojoType="dojox.drawing.Drawing" id="drawingNode" jsId="myDrawing" class="drawing"
-			 plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{minor:20, major:100}},{'name':'dojox.drawing.plugins.drawing.GreekPalette'}]">
+			 plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{minor:20, major:100}}]">
 		</div>
 	</div>
 
@@ -155,6 +155,6 @@
 	<br/>
 
 	<textarea id="data"></textarea>
-
+	<div dojoType="dojox.drawing.plugins.drawing.GreekPalette" id="greekPalette"></div>
 </body>
 </html>
diff --git a/dojox/drawing/tests/test_drawing_toolbar.html b/dojox/drawing/tests/test_drawing_toolbar.html
index 08c51da..c53f356 100644
--- a/dojox/drawing/tests/test_drawing_toolbar.html
+++ b/dojox/drawing/tests/test_drawing_toolbar.html
@@ -95,9 +95,11 @@
 		<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"
-			 plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{gap:100}},{'name':'dojox.drawing.plugins.drawing.GreekPalette'}]">
+			 plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{gap:100}}]">
 		</div>
 	</div>
 	
+	<div dojoType="dojox.drawing.plugins.drawing.GreekPalette" id="greekPalette"></div>
+	
 </body>
 </html>
diff --git a/dojox/drawing/tests/test_paths.html b/dojox/drawing/tests/test_paths.html
index ffd4235..65acf96 100644
--- a/dojox/drawing/tests/test_paths.html
+++ b/dojox/drawing/tests/test_paths.html
@@ -110,9 +110,10 @@
 		<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"
-			 plugins="[{'name':'dojox.drawing.plugins.drawing.GreekPalette'},{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{minor:20, major:100}}]">
+			 plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{minor:20, major:100}}]">
 		</div>
 	</div>
 	
+	<div dojoType="dojox.drawing.plugins.drawing.GreekPalette" id="greekPalette"></div>
 </body>
 </html>
diff --git a/dojox/drawing/tools/TextBlock.js b/dojox/drawing/tools/TextBlock.js
index 1d984b1..e4ee99b 100755
--- a/dojox/drawing/tools/TextBlock.js
+++ b/dojox/drawing/tools/TextBlock.js
@@ -228,9 +228,18 @@ StencilData: {
 				//
 				if(this._textConnected){ return; } // good ol' IE and its double events
 				// FIXME:
-				// Ouch-getting dropdown by id.  At the minimum this should
+				// Ouch-getting greekPalette by id.  At the minimum this should
 				// be from the plugin manager
-				var dropdown = dijit.byId("dropdown");
+				var greekPalette = dijit.byId("greekPalette");
+				var greekHelp = greekPalette==undefined ? false : true;
+				if(greekHelp){
+					//set it up
+					dojo.mixin(greekPalette,{
+						_pushChangeTo: conEdit,
+						_textBlock: this
+					});
+				};
+				
 				this._textConnected = true;
 				this._dropMode = false;
 				this.mouse.setEventMode("TEXT");
@@ -264,7 +273,7 @@ StencilData: {
 					} else {
 						if(evt.keyCode==dojo.keys.SPACE){
 							dojo.stopEvent(evt);
-							dropdown.onCancel();
+							greekHelp && greekPalette.onCancel();
 						}
 					}
 				});
@@ -275,8 +284,8 @@ StencilData: {
 					//	if backslash, user is inputting a special character
 					//	This gives popup help.
 					if(evt.keyCode==220){
-						if(dropdown==undefined){
-							console.warn("Dropdown not found");
+						if(!greekHelp){
+							console.info("For greek letter assistance instantiate: dojox.drawing.plugins.drawing.GreekPalette");
 							return;
 						}
 						dojo.stopEvent(evt);
@@ -286,11 +295,7 @@ StencilData: {
 						this.insertText(conEdit,"\\");
 						this._dropMode = true;
 						this._blockExec = true;
-						dropdown._pushChangeTo = conEdit;
-						dropdown._textBlock = this;
-						dijit.popup.open({
-							parent:this.parentNode,
-							popup:dropdown,
+						greekPalette.show({
 							around:this.parentNode,
 							orient:{'BL':'TL'}
 						});
@@ -298,22 +303,23 @@ StencilData: {
 					if(!this._dropMode){
 						this._blockExec = false;
 					} else {
+						// Controls for when we have a character helper and it's active
 						switch(evt.keyCode){
 							case dojo.keys.UP_ARROW:
 							case dojo.keys.DOWN_ARROW:
 							case dojo.keys.LEFT_ARROW:
 							case dojo.keys.RIGHT_ARROW:
 								dojo.stopEvent(evt);
-								dropdown._navigateByArrow(evt);
+								greekPalette._navigateByArrow(evt);
 								break;
 							case dojo.keys.ENTER:
 								dojo.stopEvent(evt);
-								dropdown._onCellClick(evt);
+								greekPalette._onCellClick(evt);
 								break;
 							case dojo.keys.BACKSPACE:
 							case dojo.keys.DELETE:
 								dojo.stopEvent(evt);
-								dropdown.onCancel();
+								greekPalette.onCancel();
 								break;
 						}
 					}
diff --git a/dojox/drawing/util/oo.js b/dojox/drawing/util/oo.js
index e29d63f..c0303b9 100755
--- a/dojox/drawing/util/oo.js
+++ b/dojox/drawing/util/oo.js
@@ -58,7 +58,7 @@ dojox.drawing.util.oo = {
 		//
 		var f, o, ext=0, a = arguments;
 				
-		if(a.length<2){ console.error("gfx.oo.declare; not enough arguments")}
+		if(a.length<2){ console.error("drawing.util.oo.declare; not enough arguments")}
 		if(a.length==2){
 			f = a[0]; o = a[1];
 		}else{
@@ -99,7 +99,7 @@ dojox.drawing.util.oo = {
 		//		|	var e = new D();
 		//
 		var a = arguments, sub = a[0];
-		if(a.length<2){ console.error("gfx.oo.extend; not enough arguments")}
+		if(a.length<2){ console.error("drawing.util.oo.extend; not enough arguments")}
 		var f = function (){
 			for(var i=1;i<a.length;i++){
 				a[i].prototype.constructor.apply(this, arguments);
diff --git a/dojox/dtl.js b/dojox/dtl.js
index 6c6fe85..d58d4cc 100644
--- a/dojox/dtl.js
+++ b/dojox/dtl.js
@@ -1,2 +1,3 @@
-dojo.provide("dojox.dtl");
-dojo.require("dojox.dtl._base");
\ No newline at end of file
+define(["./dtl/_base"], function(dxdtl){
+	return dxdtl;
+});
\ No newline at end of file
diff --git a/dojox/dtl/Context.js b/dojox/dtl/Context.js
index 01bfd3c..88a27c3 100644
--- a/dojox/dtl/Context.js
+++ b/dojox/dtl/Context.js
@@ -1,69 +1,88 @@
-dojo.provide("dojox.dtl.Context");
-dojo.require("dojox.dtl._base");
-
-dojox.dtl.Context = dojo.extend(function(dict){
-	this._this = {};
-	dojox.dtl._Context.call(this, dict);
-}, dojox.dtl._Context.prototype,
-{
-	getKeys: function(){
-		var keys = [];
-		for(var key in this){
-			if(this.hasOwnProperty(key) && key != "_this"){
-				keys.push(key);
-			}
-		}
-		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.
-		return  dojo.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.
-		var context = new dojox.dtl.Context();
-		var keys = [];
-		var i, arg;
-		if(filter instanceof dojox.dtl.Context){
-			keys = filter.getKeys();
-		}else if(typeof filter == "object"){
-			for(var key in filter){
-				keys.push(key);
+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){
+		this._this = {};
+		dd._Context.call(this, dict);
+	}, dd._Context.prototype,
+	{
+		getKeys: function(){
+			// summary: Returns the set of keys exported by this context.
+			var keys = [];
+			for(var key in this){
+				if(this.hasOwnProperty(key) && key != "_this"){
+					keys.push(key);
+				}
 			}
-		}else{
-			for(i = 0; arg = arguments[i]; i++){
-				if(typeof arg == "string"){
-					keys.push(arg);
+			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.
+			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.
+			var context = new dd.Context();
+			var keys = [];
+			var i, arg;
+			if(filter instanceof dd.Context){
+				keys = filter.getKeys();
+			}else if(typeof filter == "object"){
+				for(var key in filter){
+					keys.push(key);
+				}
+			}else{
+				for(i = 0; arg = arguments[i]; i++){
+					if(typeof arg == "string"){
+						keys.push(arg);
+					}
 				}
 			}
-		}
 
-		for(i = 0, key; key = keys[i]; i++){
-			context[key] = this[key];
-		}
+			for(i = 0, key; key = keys[i]; i++){
+				context[key] = this[key];
+			}
 
-		return context;
-	},
-	setThis: function(/*Object*/ _this){
-		this._this = _this;
-	},
-	getThis: function(){
-		return this._this;
-	},
-	hasKey: function(key){
-		if(this._getter){
-			var got = this._getter(key);
-			if(typeof got != "undefined"){
-				return true;
+			return context;
+		},
+		setThis: function(/*Object*/ _this){
+			// summary: Sets the object on which to perform operations. 
+			// _this: the this ref.
+			this._this = _this;
+		},
+		getThis: function(){
+			// 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.
+			if(this._getter){
+				var got = this._getter(key);
+				if(typeof got != "undefined"){
+					return true;
+				}
 			}
-		}
 
-		if(typeof this[key] != "undefined"){
-			return true;
-		}
+			if(typeof this[key] != "undefined"){
+				return true;
+			}
 
 		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 a14fb53..e41bc58 100644
--- a/dojox/dtl/DomInline.js
+++ b/dojox/dtl/DomInline.js
@@ -1,36 +1,43 @@
-dojo.provide("dojox.dtl.DomInline");
-dojo.require("dojox.dtl.dom");
-
-dojo.require("dijit._Widget");
-
-dojox.dtl.DomInline = dojo.extend(function(args, node){
-	this.create(args, node);
-},
-dijit._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;
-		}
+define([
+	"dojo/_base/lang",
+	"./dom",
+	"./_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);
 	},
-	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);
-		}
+	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(dojo.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);
-	}
+			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);
+		}
+	});
+	return dojox.dtl.DomInline;
 });
\ No newline at end of file
diff --git a/dojox/dtl/HtmlInline.js b/dojox/dtl/HtmlInline.js
deleted file mode 100644
index 0c135d0..0000000
--- a/dojox/dtl/HtmlInline.js
+++ /dev/null
@@ -1,5 +0,0 @@
-dojo.provide("dojox.dtl.HtmlInline");
-dojo.require("dojox.dtl.DomInline");
-dojo.deprecated("dojox.dtl.html", "All packages and classes in dojox.dtl that start with Html or html have been renamed to Dom or dom");
-dojox.dtl.HtmlInline = dojox.dtl.DomInline;
-dojox.dtl.HtmlInline.prototype.declaredClass = "dojox.dtl.HtmlInline";
\ No newline at end of file
diff --git a/dojox/dtl/Inline.js b/dojox/dtl/Inline.js
index 105a53e..4d36d20 100644
--- a/dojox/dtl/Inline.js
+++ b/dojox/dtl/Inline.js
@@ -1,32 +1,40 @@
-dojo.provide("dojox.dtl.Inline");
-dojo.require("dojox.dtl._base");
-
-dojo.require("dijit._Widget");
-
-dojox.dtl.Inline = dojo.extend(function(args, node){
-	this.create(args, node);
-},
-dijit._Widget.prototype,
-{
-	context: null,
-	render: function(/*Object|dojox.dtl.Context?*/ context){
-		this.context = context || this.context;
-		this.postMixInProperties();
-		dojo.query("*", this.domNode).orphan();
-		this.domNode.innerHTML = this.template.render(this.context);
+define([
+	"dojo/_base/lang",
+	"./_base",
+	"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);
 	},
-	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);
-		}
+	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 dojox.dtl.Template(dojo.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);
-	}
+			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);
+		}
+	});
+	return dojox.dtl.Inline;
 });
\ No newline at end of file
diff --git a/dojox/dtl/_DomTemplated.js b/dojox/dtl/_DomTemplated.js
index f09fa61..bdc4c94 100644
--- a/dojox/dtl/_DomTemplated.js
+++ b/dojox/dtl/_DomTemplated.js
@@ -1,80 +1,99 @@
-dojo.provide("dojox.dtl._DomTemplated");
+define([
+	"dojo/dom-construct",
+	".",
+	"./contrib/dijit",
+	"./render/dom",
+	"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.prototype = {
+		_dijitTemplateCompat: false,
+		buildRendering: function(){
+			//	summary:
+			//		Construct the UI for this widget, setting this.domNode.
 
-dojo.require("dijit._Templated");
-dojo.require("dojox.dtl.dom");
-dojo.require("dojox.dtl.render.dom");
-dojo.require("dojox.dtl.contrib.dijit");
+			//render needs a domNode to work with
+			this.domNode = this.srcNodeRef;
 
-dojox.dtl._DomTemplated = function(){};
-dojox.dtl._DomTemplated.prototype = {
-	_dijitTemplateCompat: false,
-	buildRendering: function(){
-		//	summary:
-		//		Construct the UI for this widget, setting this.domNode.
+			if(!this._render){
+				var old = ddcd.widgetsInTemplate;
+				ddcd.widgetsInTemplate = this.widgetsInTemplate;
+				this.template = this.template || this._getCachedTemplate(this.templatePath, this.templateString);
+				this._render = new ddrd.Render(this.domNode, this.template);
+				ddcd.widgetsInTemplate = old;
+			}
 
-		//render needs a domNode to work with
-		this.domNode = this.srcNodeRef;
+			var context = this._getContext();
+			if(!this._created){
+				delete context._getter;
+			}
+			this.render(context);
 
-		if(!this._render){
-			var ddcd = dojox.dtl.contrib.dijit;
-			var old = ddcd.widgetsInTemplate;
-			ddcd.widgetsInTemplate = this.widgetsInTemplate;
-			this.template = this.template || this._getCachedTemplate(this.templatePath, this.templateString);
-			this._render = new dojox.dtl.render.dom.Render(this.domNode, this.template);
-			ddcd.widgetsInTemplate = old;
+			this.domNode = this.template.getRootNode();
+			if(this.srcNodeRef && this.srcNodeRef.parentNode){
+				domConstruct.destroy(this.srcNodeRef);
+				delete this.srcNodeRef;
+			}
+		},
+		setTemplate: function(/*String|dojo._Url*/ template, /*dojox.dtl.Context?*/ context){
+			// summary:
+			//		Quickly switch between templated by location
+			// template: The new template.
+			// context:
+			//		The runtime context.
+			if(dojox.dtl.text._isTemplate(template)){
+				this.template = this._getCachedTemplate(null, template);
+			}else{
+				this.template = this._getCachedTemplate(template);
+			}
+			this.render(context);
+		},
+		render: function(/*dojox.dtl.Context?*/ context, /*dojox.dtl.DomTemplate?*/ tpl){
+			// summary:
+			//		Renders this template.
+			// context:
+			//		The runtime context.
+			// tpl:
+			//		The template to render. Optional.
+			if(tpl){
+				this.template = tpl;
+			}
+			this._render.render(this._getContext(context), this.template);
+		},
+		_getContext: function(context){
+			if(!(context instanceof dojox.dtl.Context)){
+				context = false;
+			}
+			context = context || new dojox.dtl.Context(this);
+			context.setThis(this);
+			return context;
+		},
+		_getCachedTemplate: function(templatePath, templateString){
+			if(!this._templates){
+				this._templates = {};
+			}
+			if(!templateString){
+				templateString = cache(templatePath, {sanitize: true});
+			}
+			var key = templateString;
+			var tmplts = this._templates;
+			if(tmplts[key]){
+				return tmplts[key];
+			}
+			return (tmplts[key] = new dojox.dtl.DomTemplate(
+				TemplatedMixin.getCachedTemplate(
+					templateString,
+					true
+				)
+			));
 		}
+	};
+	return dojox.dtl._DomTemplated;
+});
 
-		var context = this._getContext();
-		if(!this._created){
-			delete context._getter;
-		}
-		this.render(context);
-
-		this.domNode = this.template.getRootNode();
-		if(this.srcNodeRef && this.srcNodeRef.parentNode){
-			dojo.destroy(this.srcNodeRef);
-			delete this.srcNodeRef;
-		}
-	},
-	setTemplate: function(/*String|dojo._Url*/ template, /*dojox.dtl.Context?*/ context){
-		// summary:
-		//		Quickly switch between templated by location
-		if(dojox.dtl.text._isTemplate(template)){
-			this.template = this._getCachedTemplate(null, template);
-		}else{
-			this.template = this._getCachedTemplate(template);
-		}
-		this.render(context);
-	},
-	render: function(/*dojox.dtl.Context?*/ context, /*dojox.dtl.DomTemplate?*/ tpl){
-		if(tpl){
-			this.template = tpl;
-		}
-		this._render.render(this._getContext(context), this.template);
-	},
-	_getContext: function(context){
-		if (!(context instanceof dojox.dtl.Context)) {
-			context = false;
-		}
-		context = context || new dojox.dtl.Context(this);
-		context.setThis(this);
-		return context;
-	},
-	_getCachedTemplate: function(templatePath, templateString){
-		if(!this._templates){
-			this._templates = {};
-		}
-		var key = templateString || templatePath.toString();
-		var tmplts = this._templates;
-		if(tmplts[key]){
-			return tmplts[key];
-		}
-		return (tmplts[key] = new dojox.dtl.DomTemplate(
-			dijit._Templated.getCachedTemplate(
-				templatePath,
-				templateString,
-				true
-			)
-		));
-	}
-};
diff --git a/dojox/dtl/_HtmlTemplated.js b/dojox/dtl/_HtmlTemplated.js
deleted file mode 100644
index 7efdb2e..0000000
--- a/dojox/dtl/_HtmlTemplated.js
+++ /dev/null
@@ -1,5 +0,0 @@
-dojo.provide("dojox.dtl._HtmlTemplated");
-dojo.require("dojox.dtl._DomTemplated");
-dojo.deprecated("dojox.dtl.html", "All packages and classes in dojox.dtl that start with Html or html have been renamed to Dom or dom");
-dojox.dtl._HtmlTemplated = dojox.dtl._DomTemplated;
-dojox.dtl._HtmlTemplated.prototype.declaredClass = "dojox.dtl._HtmlTemplated";
\ No newline at end of file
diff --git a/dojox/dtl/_Templated.js b/dojox/dtl/_Templated.js
index 56c2e7a..a39749b 100644
--- a/dojox/dtl/_Templated.js
+++ b/dojox/dtl/_Templated.js
@@ -1,127 +1,147 @@
-dojo.provide("dojox.dtl._Templated");
-dojo.require("dijit._Templated");
-dojo.require("dojox.dtl._base");
+define([
+	"dojo/_base/declare",
+	"./_base",
+	"dijit/_TemplatedMixin",
+	"dojo/dom-construct",
+	"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;
+	=====*/
+	return declare("dojox.dtl._Templated", TemplatedMixin, {
+		// summary: The base-class for DTL-templated widgets.
 
-dojo.declare("dojox.dtl._Templated", dijit._Templated, {
-	_dijitTemplateCompat: false,
-	buildRendering: function(){
-		var node;
+		_dijitTemplateCompat: false,
+		buildRendering: function(){
+			// summary: The method overrides dijit._TemplatedMixin.startup.
+			var node;
 
-		if(this.domNode && !this._template){
-			return;
-		}
-
-		if(!this._template){
-			var t = this.getCachedTemplate(
-				this.templatePath,
-				this.templateString,
-				this._skipNodeCache
-			);
-			if(t instanceof dojox.dtl.Template) {
-				this._template = t;
-			}else{
-				node = t;
+			if(this.domNode && !this._template){
+				return;
 			}
-		}
-		if(!node){
-			var context = new dojox.dtl._Context(this);
-			if(!this._created){
-				delete context._getter;
+
+			if(!this._template){
+				var t = this.getCachedTemplate(
+					this.templatePath,
+					this.templateString,
+					this._skipNodeCache
+				);
+				if(t instanceof dd.Template) {
+					this._template = t;
+				}else{
+					node = t;
+				}
 			}
-			var nodes = dojo._toDom(
-				this._template.render(context)
-			);
-			// TODO: is it really necessary to look for the first node?
-			if(nodes.nodeType !== 1 && nodes.nodeType !== 3){
-				// nodes.nodeType === 11
-				// the node is a document fragment
-				for(var i = 0, l = nodes.childNodes.length; i < l; ++i){
-					node = nodes.childNodes[i];
-					if(node.nodeType == 1){
-						break;
+			if(!node){
+				var context = new dd._Context(this);
+				if(!this._created){
+					delete context._getter;
+				}
+				var nodes = domConstruct.toDom(
+					this._template.render(context)
+				);
+				// TODO: is it really necessary to look for the first node?
+				if(nodes.nodeType !== 1 && nodes.nodeType !== 3){
+					// nodes.nodeType === 11
+					// the node is a document fragment
+					for(var i = 0, l = nodes.childNodes.length; i < l; ++i){
+						node = nodes.childNodes[i];
+						if(node.nodeType == 1){
+							break;
+						}
 					}
+				}else{
+					// the node is an element or a text
+					node = nodes;
 				}
-			}else{
-				// the node is an element or a text
-				node = nodes;
 			}
-		}
+			this._attachTemplateNodes(node, function(n,p){
+				return n.getAttribute(p);
+			});
+			if(this.widgetsInTemplate){
+				//Make sure dojoType is used for parsing widgets in template.
+				//The Parser.query could be changed from multiversion support.
+				var parser = Parser, qry, attr;
+				if(parser._query != "[dojoType]"){
+					qry = parser._query;
+					attr = parser._attrName;
+					parser._query = "[dojoType]";
+					parser._attrName = "dojoType";
+				}
 
-		this._attachTemplateNodes(node);
+				//Store widgets that we need to start at a later point in time
+				var cw = (this._startupWidgets = Parser.parse(node, {
+					noStart: !this._earlyTemplatedStartup,
+					inherited: {dir: this.dir, lang: this.lang}
+				}));
 
-		if(this.widgetsInTemplate){
-			//Make sure dojoType is used for parsing widgets in template.
-			//The dojo.parser.query could be changed from multiversion support.
-			var parser = dojo.parser, qry, attr;
-			if(parser._query != "[dojoType]"){
-				qry = parser._query;
-				attr = parser._attrName;
-				parser._query = "[dojoType]";
-				parser._attrName = "dojoType";
-			}
+				//Restore the query.
+				if(qry){
+					parser._query = qry;
+					parser._attrName = attr;
+				}
 
-			//Store widgets that we need to start at a later point in time
-			var cw = (this._startupWidgets = dojo.parser.parse(node, {
-				noStart: !this._earlyTemplatedStartup,
-				inherited: {dir: this.dir, lang: this.lang}
-			}));
+				this._supportingWidgets = dijitMgr.findWidgets(node);
 
-			//Restore the query.
-			if(qry){
-				parser._query = qry;
-				parser._attrName = attr;
+				this._attachTemplateNodes(cw, function(n,p){
+					return n[p];
+				});
 			}
 
-			this._supportingWidgets = dijit.findWidgets(node);
-
-			this._attachTemplateNodes(cw, function(n,p){
-				return n[p];
-			});
-		}
-
-		if(this.domNode){
-			dojo.place(node, this.domNode, "before");
-			this.destroyDescendants();
-			dojo.destroy(this.domNode);
-		}
-		this.domNode = node;
+			if(this.domNode){
+				domConstruct.place(node, this.domNode, "before");
+				this.destroyDescendants();
+				domConstruct.destroy(this.domNode);
+			}
+			this.domNode = node;
 
-		this._fillContent(this.srcNodeRef);
-	},
-	_templateCache: {},
-	getCachedTemplate: function(templatePath, templateString, alwaysUseString){
-		// summary:
-		//		Layer for dijit._Templated.getCachedTemplate
-		var tmplts = this._templateCache;
-		var key = templateString || templatePath;
-		if(tmplts[key]){
-			return tmplts[key];
-		}
+			this._fillContent(this.srcNodeRef);
+		},
+		_templateCache: {},
+		getCachedTemplate: function(templatePath, templateString, alwaysUseString){
+			// summary:
+			//		Layer for dijit._Templated.getCachedTemplate
+			var tmplts = this._templateCache;
+			var key = templateString || templatePath;
+			if(tmplts[key]){
+				return tmplts[key];
+			}
 
-		templateString = dojo.string.trim(templateString || dojo.cache(templatePath, {sanitize: true}));
+			templateString = dString.trim(templateString || Cache(templatePath, {sanitize: true}));
 
-		if(	this._dijitTemplateCompat &&
-			(alwaysUseString || templateString.match(/\$\{([^\}]+)\}/g))
-		){
-			templateString = this._stringRepl(templateString);
-		}
+			if(	this._dijitTemplateCompat &&
+				(alwaysUseString || templateString.match(/\$\{([^\}]+)\}/g))
+			){
+				templateString = this._stringRepl(templateString);
+			}
 
-		// If we always use a string, or find no variables, just store it as a node
-		if(alwaysUseString || !templateString.match(/\{[{%]([^\}]+)[%}]\}/g)){
-			return tmplts[key] = dojo._toDom(templateString);
-		}else{
-			return tmplts[key] = new dojox.dtl.Template(templateString);
-		}
-	},
-	render: function(){
-		this.buildRendering();
-	},
-	startup: function(){
-		dojo.forEach(this._startupWidgets, function(w){
-			if(w && !w._started && w.startup){
-				w.startup();
+			// If we always use a string, or find no variables, just store it as a node
+			if(alwaysUseString || !templateString.match(/\{[{%]([^\}]+)[%}]\}/g)){
+				return tmplts[key] = domConstruct.toDom(templateString);
+			}else{
+				return tmplts[key] = new dd.Template(templateString);
 			}
-		});
-		this.inherited(arguments);
-	}
-});
+		},
+		render: function(){
+			// 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();
+				}
+			});
+			this.inherited(arguments);
+		}
+	});
+});
\ No newline at end of file
diff --git a/dojox/dtl/_base.js b/dojox/dtl/_base.js
index b79915d..c509f53 100644
--- a/dojox/dtl/_base.js
+++ b/dojox/dtl/_base.js
@@ -1,22 +1,38 @@
-dojo.provide("dojox.dtl._base");
-
-dojo.require("dojox.string.Builder");
-dojo.require("dojox.string.tokenize");
-
-dojo.experimental("dojox.dtl");
-
-(function(){
-	var dd = dojox.dtl;
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojox/string/tokenize",
+	"dojo/_base/json",
+	"dojo/dom",
+	"dojo/_base/xhr",
+	"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._base = {};
+	/*=====
+		dd = dojox.dtl;
+	=====*/
 
 	dd.TOKEN_BLOCK = -1;
 	dd.TOKEN_VAR = -2;
 	dd.TOKEN_COMMENT = -3;
 	dd.TOKEN_TEXT = 3;
 
-	dd._Context = dojo.extend(function(dict){
+	/*=====
+		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.
 		if(dict){
-			dojo._mixin(this, dict);
+			lang._mixin(this, dict);
 			if(dict.get){
 				// Preserve passed getter and restore prototype get
 				this._getter = dict.get;
@@ -27,7 +43,7 @@ dojo.experimental("dojox.dtl");
 	{
 		push: function(){
 			var last = this;
-			var context = dojo.delegate(this);
+			var context = lang.delegate(this);
 			context.pop = function(){ return last; }
 			return context;
 		},
@@ -39,12 +55,12 @@ dojo.experimental("dojox.dtl");
 
 			if(this._getter){
 				var got = this._getter(key);
-				if(typeof got != "undefined"){
+				if(got !== undefined){
 					return n(got);
 				}
 			}
 
-			if(typeof this[key] != "undefined"){
+			if(this[key] !== undefined){
 				return n(this[key]);
 			}
 
@@ -66,7 +82,7 @@ dojo.experimental("dojox.dtl");
 		update: function(dict){
 			var context = this.push();
 			if(dict){
-				dojo._mixin(this, dict);
+				lang._mixin(this, dict);
 			}
 			return context;
 		}
@@ -85,7 +101,7 @@ dojo.experimental("dojox.dtl");
 		splitter.exec(""); // Reset the global
 
 		var part, parts = [], lastIndex = 0, i = 0;
-		while(part = splitter.exec(this)){
+		while((part = splitter.exec(this))){
 			parts.push(this.slice(lastIndex, splitter.lastIndex - part[0].length));
 			lastIndex = splitter.lastIndex;
 			if(limit && (++i > limit - 1)){
@@ -98,7 +114,7 @@ dojo.experimental("dojox.dtl");
 
 	dd.Token = function(token_type, contents){
 		this.token_type = token_type;
-		this.contents = new String(dojo.trim(contents));
+		this.contents = new String(lang.trim(contents));
 		this.contents.split = split;
 		this.split = function(){
 			return String.prototype.split.apply(this.contents, arguments);
@@ -132,7 +148,7 @@ dojo.experimental("dojox.dtl");
 			}
 
 			var fn = params[1];
-			var require = params[2];
+			var deps = params[2];
 
 			var parts;
 			if(fn.indexOf(":") != -1){
@@ -140,9 +156,14 @@ dojo.experimental("dojox.dtl");
 				fn = parts.pop();
 			}
 
-			dojo["require"](require);
+// FIXME: THIS DESIGN DOES NOT WORK WITH ASYNC LOADERS!
+			var mod = deps;
+			if (/\./.test(deps)) {
+				deps = deps.replace(/\./g, "/");
+			}
+			require([deps], function(){});
 
-			var parent = dojo.getObject(require);
+			var parent = lang.getObject(mod);
 
 			return parent[fn || name] || parent[name + "_"] || parent[fn + "_"];
 		},
@@ -156,18 +177,18 @@ dojo.experimental("dojox.dtl");
 			return new dd.Template(ddt.getTemplateString(file));
 		},
 		getTemplateString: function(file){
-			return dojo._getText(file.toString()) || "";
+			return xhr._getText(file.toString()) || "";
 		},
 		_resolveLazy: function(location, sync, json){
 			if(sync){
 				if(json){
-					return dojo.fromJson(dojo._getText(location)) || {};
+					return json.fromJson(xhr._getText(location)) || {};
 				}else{
 					return dd.text.getTemplateString(location);
 				}
 			}else{
-				return dojo.xhrGet({
-					handleAs: (json) ? "json" : "text",
+				return xhr.get({
+					handleAs: json ? "json" : "text",
 					url: location
 				});
 			}
@@ -175,7 +196,7 @@ dojo.experimental("dojox.dtl");
 		_resolveTemplateArg: function(arg, sync){
 			if(ddt._isTemplate(arg)){
 				if(!sync){
-					var d = new dojo.Deferred();
+					var d = new deferred();
 					d.callback(arg);
 					return d;
 				}
@@ -184,12 +205,12 @@ dojo.experimental("dojox.dtl");
 			return ddt._resolveLazy(arg, sync);
 		},
 		_isTemplate: function(arg){
-			return (typeof arg == "undefined") || (typeof arg == "string" && (arg.match(/^\s*[<{]/) || arg.indexOf(" ") != -1));
+			return (arg === undefined) || (typeof arg == "string" && (arg.match(/^\s*[<{]/) || arg.indexOf(" ") != -1));
 		},
 		_resolveContextArg: function(arg, sync){
 			if(arg.constructor == Object){
 				if(!sync){
-					var d = new dojo.Deferred;
+					var d = new deferred;
 					d.callback(arg);
 					return d;
 				}
@@ -199,15 +220,18 @@ dojo.experimental("dojox.dtl");
 		},
 		_re: /(?:\{\{\s*(.+?)\s*\}\}|\{%\s*(load\s*)?(.+?)\s*%\})/g,
 		tokenize: function(str){
-			return dojox.string.tokenize(str, ddt._re, ddt._parseDelims);
+			return Tokenize(str, ddt._re, ddt._parseDelims);
 		},
 		_parseDelims: function(varr, load, tag){
 			if(varr){
 				return [dd.TOKEN_VAR, varr];
 			}else if(load){
-				var parts = dojo.trim(tag).split(/\s+/g);
+				var parts = lang.trim(tag).split(/\s+/g);
 				for(var i = 0, part; part = parts[i]; i++){
-					dojo["require"](part);
+					if (/\./.test(part)){
+						part = part.replace(/\./g,"/");
+					}
+					require([part]);
 				}
 			}else{
 				return [dd.TOKEN_BLOCK, tag];
@@ -215,7 +239,35 @@ dojo.experimental("dojox.dtl");
 		}
 	}
 
-	dd.Template = dojo.extend(function(/*String|dojo._Url*/ template, /*Boolean*/ isString){
+	/*=====
+		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:
 		//		The string or location of the string to
 		//		use as a template
@@ -226,6 +278,8 @@ dojo.experimental("dojox.dtl");
 	},
 	{
 		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
@@ -237,7 +291,7 @@ dojo.experimental("dojox.dtl");
 						item.innerHTML = content;
 					});
 				}else{
-					dojo.byId(node).innerHTML = content;
+					dom.byId(node).innerHTML = content;
 				}
 				return this;
 			});
@@ -248,8 +302,7 @@ dojo.experimental("dojox.dtl");
 			return this.nodelist.render(context, buffer) + "";
 		},
 		getBuffer: function(){
-			dojo.require("dojox.string.Builder");
-			return new dojox.string.Builder();
+			return new StringBuilder();
 		}
 	});
 
@@ -260,18 +313,18 @@ dojo.experimental("dojox.dtl");
 		}
 
 		if(str.indexOf("{%") == -1){
-			return new dd._QuickNodeList(dojox.string.tokenize(str, qfRe, function(token){
+			return new dd._QuickNodeList(Tokenize(str, qfRe, function(token){
 				return new dd._Filter(token);
 			}));
 		}
 	}
 
-	dd._QuickNodeList = dojo.extend(function(contents){
+	dd._QuickNodeList = lang.extend(function(contents){
 		this.contents = contents;
 	},
 	{
 		render: function(context, buffer){
-			for(var i=0, l=this.contents.length; i<l; i++){
+			for(var i = 0, l = this.contents.length; i < l; i++){
 				if(this.contents[i].resolve){
 					buffer = buffer.concat(this.contents[i].resolve(context));
 				}else{
@@ -284,7 +337,7 @@ dojo.experimental("dojox.dtl");
 		clone: function(buffer){ return this; }
 	});
 
-	dd._Filter = dojo.extend(function(token){
+	dd._Filter = lang.extend(function(token){
 		// 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;
@@ -295,7 +348,7 @@ dojo.experimental("dojox.dtl");
 			this.filters = cache[1];
 		}else{
 			this.filters = [];
-			dojox.string.tokenize(token, this._re, this._tokenize, this);
+			Tokenize(token, this._re, this._tokenize, this);
 			this._cache[token] = [this.key, this.filters];
 		}
 	},
@@ -318,7 +371,7 @@ dojo.experimental("dojox.dtl");
 			var pos, arg;
 
 			for(var i = 0, has = []; i < arguments.length; i++){
-				has[i] = (typeof arguments[i] != "undefined" && typeof arguments[i] == "string" && arguments[i]);
+				has[i] = (arguments[i] !== undefined && typeof arguments[i] == "string" && arguments[i]);
 			}
 
 			if(!this.key){
@@ -343,7 +396,7 @@ dojo.experimental("dojox.dtl");
 				}
 				// Get a named filter
 				var fn = ddt.getFilter(arguments[3]);
-				if(!dojo.isFunction(fn)) throw new Error(arguments[3] + " is not registered as a filter");
+				if(!lang.isFunction(fn)) throw new Error(arguments[3] + " is not registered as a filter");
 				this.filters.push([fn, arg]);
 			}
 		},
@@ -351,7 +404,7 @@ dojo.experimental("dojox.dtl");
 			return this.contents;
 		},
 		resolve: function(context){
-			if(typeof this.key == "undefined"){
+			if(this.key === undefined){
 				return "";
 			}
 
@@ -388,7 +441,7 @@ dojo.experimental("dojox.dtl");
 				parts = path.split(".");
 				current = context.get(parts[0]);
 
-				if(dojo.isFunction(current)){
+				if(lang.isFunction(current)){
 					var self = context.getThis && context.getThis();
 					if(current.alters_data){
 						current = "";
@@ -403,7 +456,7 @@ dojo.experimental("dojox.dtl");
 					var part = parts[i];
 					if(current){
 						var base = current;
-						if(dojo.isObject(current) && part == "items" && typeof current[part] == "undefined"){
+						if(lang.isObject(current) && part == "items" && current[part] === undefined){
 							var items = [];
 							for(var key in current){
 								items.push([key, current[key]]);
@@ -412,16 +465,16 @@ dojo.experimental("dojox.dtl");
 							continue;
 						}
 
-						if(current.get && dojo.isFunction(current.get) && current.get.safe){
+						if(current.get && lang.isFunction(current.get) && current.get.safe){
 							current = current.get(part);
-						}else if(typeof current[part] == "undefined"){
+						}else if(current[part] === undefined){
 							current = current[part];
 							break;
 						}else{
 							current = current[part];
 						}
 
-						if(dojo.isFunction(current)){
+						if(lang.isFunction(current)){
 							if(current.alters_data){
 								current = "";
 							}else{
@@ -439,7 +492,7 @@ dojo.experimental("dojox.dtl");
 		}
 	});
 
-	dd._TextNode = dd._Node = dojo.extend(function(/*Object*/ obj){
+	dd._TextNode = dd._Node = lang.extend(function(/*Object*/ obj){
 		// summary: Basic catch-all node
 		this.contents = obj;
 	},
@@ -453,12 +506,12 @@ dojo.experimental("dojox.dtl");
 			return buffer.concat(this.contents);
 		},
 		isEmpty: function(){
-			return !dojo.trim(this.contents);
+			return !lang.trim(this.contents);
 		},
 		clone: function(){ return this; }
 	});
 
-	dd._NodeList = dojo.extend(function(/*Node[]*/ nodes){
+	dd._NodeList = lang.extend(function(/*Node[]*/ nodes){
 		// summary: Allows us to render a group of nodes
 		this.contents = nodes || [];
 		this.last = "";
@@ -500,7 +553,7 @@ dojo.experimental("dojox.dtl");
 		}
 	});
 
-	dd._VarNode = dojo.extend(function(str){
+	dd._VarNode = lang.extend(function(str){
 		// summary: A node to be processed as a variable
 		this.contents = new dd._Filter(str);
 	},
@@ -520,7 +573,7 @@ dojo.experimental("dojox.dtl");
 		this.clone = function(){ return this; }
 	}
 
-	dd._Parser = dojo.extend(function(tokens){
+	dd._Parser = lang.extend(function(tokens){
 		// summary: Parser used during initialization and for tag groups.
 		this.contents = tokens;
 	},
@@ -624,8 +677,8 @@ dojo.experimental("dojox.dtl");
 				if(entry.length == 3){
 					tags.push(entry);
 				}else{
-					var fn = dojo.getObject(entry[1]);
-					if(fn && dojo.isFunction(fn)){
+					var fn = lang.getObject(entry[1]);
+					if(fn && lang.isFunction(fn)){
 						entry.push(fn);
 						tags.push(entry);
 					}
@@ -637,7 +690,7 @@ dojo.experimental("dojox.dtl");
 			for(var path in locations){
 				for(var i = 0, fn; fn = locations[path][i]; i++){
 					var key = fn;
-					if(dojo.isArray(fn)){
+					if(lang.isArray(fn)){
 						key = fn[0];
 						fn = fn[1];
 					}
@@ -707,4 +760,6 @@ dojo.experimental("dojox.dtl");
 	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 3bc54f8..7be2653 100644
--- a/dojox/dtl/contrib/data.js
+++ b/dojox/dtl/contrib/data.js
@@ -1,13 +1,18 @@
-dojo.provide("dojox.dtl.contrib.data");
-dojo.require("dojox.dtl._base");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"../_base",
+	"dojo/_base/array"
+], function(kernel,lang,dd,array){
+	/*=====
+		dd = dojox.dtl;
+	=====*/
+	lang.getObject("dojox.dtl.contrib.data", true);
 
-(function(){
-	var dd = dojox.dtl;
 	var ddcd = dd.contrib.data;
-
 	var first = true;
 
-	ddcd._BoundItem = dojo.extend(function(item, store){
+	ddcd._BoundItem = lang.extend(function(item, store){
 		this.item = item;
 		this.store = store;
 	},
@@ -30,7 +35,7 @@ dojo.require("dojox.dtl._base");
 					if(key.slice(-1) == "s"){
 						if(first){
 							first = false;
-							dojo.deprecated("You no longer need an extra s to call getValues, it can be figured out automatically");
+							kernel.deprecated("You no longer need an extra s to call getValues, it can be figured out automatically");
 						}
 						key = key.slice(0, -1);
 					}
@@ -43,12 +48,12 @@ dojo.require("dojox.dtl._base");
 				if(!values){
 					return;
 				}
-				if(!dojo.isArray(values)){
+				if(!lang.isArray(values)){
 					return new ddcd._BoundItem(values, store);
 				}
 
-				values = dojo.map(values, function(value){
-					if(dojo.isObject(value) && store.isItem(value)){
+				values = array.map(values, function(value){
+					if(lang.isObject(value) && store.isItem(value)){
 						return new ddcd._BoundItem(value, store);
 					}
 					return value;
@@ -60,7 +65,7 @@ dojo.require("dojox.dtl._base");
 	});
 	ddcd._BoundItem.prototype.get.safe = true;
 
-	ddcd.BindDataNode = dojo.extend(function(items, query, store, alias){
+	ddcd.BindDataNode = lang.extend(function(items, query, store, alias){
 		this.items = items && new dd._Filter(items);
 		this.query = query && new dd._Filter(query);
 		this.store = new dd._Filter(store);
@@ -112,7 +117,7 @@ dojo.require("dojox.dtl._base");
 		}
 	});
 
-	dojo.mixin(ddcd, {
+	lang.mixin(ddcd, {
 		_get: function(key){
 			if(this.length){
 				return (this[0] instanceof ddcd._BoundItem) ? this[0].get(key) : this[0][key];
@@ -155,4 +160,5 @@ dojo.require("dojox.dtl._base");
 	dd.register.tags("dojox.dtl.contrib", {
 		"data": ["bind_data", "bind_query"]
 	});
-})();
+	return dojox.dtl.contrib.data;
+});
\ No newline at end of file
diff --git a/dojox/dtl/contrib/dijit.js b/dojox/dtl/contrib/dijit.js
index e8135b3..0d33a33 100644
--- a/dojox/dtl/contrib/dijit.js
+++ b/dojox/dtl/contrib/dijit.js
@@ -1,13 +1,21 @@
-dojo.provide("dojox.dtl.contrib.dijit");
-
-dojo.require("dojox.dtl.dom");
-dojo.require("dojo.parser");
-
-(function(){
-	var dd = dojox.dtl;
+define([
+	"dojo/_base/lang",
+	"dojo/_base/connect",
+	"dojo/_base/array",
+	"dojo/query",
+	"../_base",
+	"../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;
-
-	ddcd.AttachNode = dojo.extend(function(keys, object){
+	ddcd.AttachNode = lang.extend(function(keys, object){
 		this._keys = keys;
 		this._object = object;
 	},
@@ -15,7 +23,7 @@ dojo.require("dojo.parser");
 		render: function(context, buffer){
 			if(!this._rendered){
 				this._rendered = true;
-				for(var i=0, key; key = this._keys[i]; i++){
+				for(var i = 0, key; key = this._keys[i]; i++){
 					context.getThis()[key] = this._object || buffer.getParent();
 				}
 			}
@@ -24,7 +32,7 @@ dojo.require("dojo.parser");
 		unrender: function(context, buffer){
 			if(this._rendered){
 				this._rendered = false;
-				for(var i=0, key; key = this._keys[i]; i++){
+				for(var i = 0, key; key = this._keys[i]; i++){
 					if(context.getThis()[key] === (this._object || buffer.getParent())){
 						delete context.getThis()[key];
 					}
@@ -37,11 +45,11 @@ dojo.require("dojo.parser");
 		}
 	});
 
-	ddcd.EventNode = dojo.extend(function(command, obj){
+	ddcd.EventNode = lang.extend(function(command, obj){
 		this._command = command;
 
 		var type, events = command.split(/\s*,\s*/);
-		var trim = dojo.trim;
+		var trim = lang.trim;
 		var types = [];
 		var fns = [];
 		while(type = events.pop()){
@@ -81,10 +89,10 @@ dojo.require("dojo.parser");
 				var args;
 				if(fn.indexOf(" ") != -1){
 					if(this._rendered[i]){
-						dojo.disconnect(this._rendered[i]);
+						connect.disconnect(this._rendered[i]);
 						this._rendered[i] = false;
 					}
-					args = dojo.map(fn.split(" ").slice(1), function(item){
+					args = array.map(fn.split(" ").slice(1), function(item){
 						return new dd._Filter(item).resolve(context);
 					});
 					fn = fn.split(" ", 2)[0];
@@ -93,7 +101,7 @@ dojo.require("dojo.parser");
 					if(!this._object){
 						this._rendered[i] = buffer.addEvent(context, type, fn, args);
 					}else{
-						this._rendered[i] = dojo.connect(this._object, type, context.getThis(), fn);
+						this._rendered[i] = connect.connect(this._object, type, context.getThis(), fn);
 					}
 				}
 			}
@@ -103,7 +111,7 @@ dojo.require("dojo.parser");
 		},
 		unrender: function(context, buffer){
 			while(this._rendered.length){
-				dojo.disconnect(this._rendered.pop());
+				connect.disconnect(this._rendered.pop());
 			}
 			return buffer;
 		},
@@ -114,27 +122,27 @@ dojo.require("dojo.parser");
 
 	function cloneNode(n1){
 		var n2 = n1.cloneNode(true);
-		if(dojo.isIE){
-			dojo.query("script", n2).forEach("item.text = this[index].text;", dojo.query("script", n1));
+		if(has("ie")){
+			Query("script", n2).forEach("item.text = this[index].text;", Query("script", n1));
 		}
 		return n2;
 	}
 
-	ddcd.DojoTypeNode = dojo.extend(function(node, parsed){
+	ddcd.DojoTypeNode = lang.extend(function(node, parsed){
 		this._node = node;
 		this._parsed = parsed;
 
-		var events = node.getAttribute("dojoAttachEvent");
+		var events = node.getAttribute("dojoAttachEvent") || node.getAttribute("data-dojo-attach-event");
 		if(events){
-			this._events = new ddcd.EventNode(dojo.trim(events));
+			this._events = new ddcd.EventNode(lang.trim(events));
 		}
-		var attach = node.getAttribute("dojoAttachPoint");
+		var attach = node.getAttribute("dojoAttachPoint") || node.getAttribute("data-dojo-attach-point");
 		if(attach){
-			this._attach = new ddcd.AttachNode(dojo.trim(attach).split(/\s*,\s*/));
+			this._attach = new ddcd.AttachNode(lang.trim(attach).split(/\s*,\s*/));
 		}
 
-		if (!parsed){
-			this._dijit = dojo.parser.instantiate([cloneNode(node)])[0];
+		if(!parsed){
+			this._dijit = Parser.instantiate([cloneNode(node)])[0];
 		}else{
 			node = cloneNode(node);
 			var old = ddcd.widgetsInTemplate;
@@ -158,7 +166,7 @@ dojo.require("dojo.parser");
 					if(this._dijit){
 						this._dijit.destroyRecursive();
 					}
-					this._dijit = dojo.parser.instantiate([root])[0];
+					this._dijit = Parser.instantiate([root])[0];
 				}
 			}
 
@@ -183,29 +191,29 @@ dojo.require("dojo.parser");
 		}
 	});
 
-	dojo.mixin(ddcd, {
+	lang.mixin(ddcd, {
 		widgetsInTemplate: true,
 		dojoAttachPoint: function(parser, token){
-			return new ddcd.AttachNode(token.contents.slice(16).split(/\s*,\s*/));
+			return new ddcd.AttachNode(token.contents.slice(token.contents.indexOf("data-") !== -1 ? 23 : 16).split(/\s*,\s*/));
 		},
 		dojoAttachEvent: function(parser, token){
-			return new ddcd.EventNode(token.contents.slice(16));
+			return new ddcd.EventNode(token.contents.slice(token.contents.indexOf("data-") !== -1 ? 23 : 16));
 		},
 		dojoType: function(parser, token){
 			var parsed = false;
 			if(token.contents.slice(-7) == " parsed"){
 				parsed = true;
 			}
-			var contents = token.contents.slice(9);
+			var contents = token.contents.indexOf("data-") !== -1 ? token.contents.slice(15)  : token.contents.slice(9);
 			var dojoType = parsed ? contents.slice(0, -7) : contents.toString();
 
 			if(ddcd.widgetsInTemplate){
 				var node = parser.swallowNode();
-				node.setAttribute("dojoType", dojoType);
+				node.setAttribute("data-dojo-type", dojoType);
 				return new ddcd.DojoTypeNode(node, parsed);
 			}
 
-			return new dd.AttributeNode("dojoType", dojoType);
+			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
@@ -213,8 +221,13 @@ dojo.require("dojo.parser");
 			return new ddcd.EventNode(parts[0] + ":" + parts.slice(1).join(" "));
 		}
 	});
+	ddcd["data-dojo-type"] = ddcd.dojoType;
+	ddcd["data-dojo-attach-point"] = ddcd.dojoAttachPoint;
+	ddcd["data-dojo-attach-event"] = ddcd.dojoAttachEvent;
+	
 
 	dd.register.tags("dojox.dtl.contrib", {
-		"dijit": ["attr:dojoType", "attr:dojoAttachPoint", ["attr:attach", "dojoAttachPoint"], "attr:dojoAttachEvent", [/(attr:)?on(click|key(up))/i, "on"]]
+		"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"]]
 	});
-})();
\ No newline at end of file
+	return dojox.dtl.contrib.dijit;
+});
diff --git a/dojox/dtl/contrib/dom.js b/dojox/dtl/contrib/dom.js
index cd9c69e..d657f28 100644
--- a/dojox/dtl/contrib/dom.js
+++ b/dojox/dtl/contrib/dom.js
@@ -1,14 +1,20 @@
-dojo.provide("dojox.dtl.contrib.dom");
-
-dojo.require("dojox.dtl.dom");
-
-(function(){
-	var dd = dojox.dtl;
-	var ddch = dd.contrib.dom;
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/connect",
+	"dojo/dom-style",
+	"dojo/dom-construct",
+	"../_base",
+	"../dom"
+], function(kernel,lang,connect,domStyle,domConstruct,dd,dddom){
+	/*=====
+		dd = dojox.dtl;
+	=====*/
+	var ddch = lang.getObject("dojox.dtl.contrib.dom", true);
 
 	var simple = {render: function(){ return this.contents; }};
 
-	ddch.StyleNode = dojo.extend(function(styles){
+	ddch.StyleNode = lang.extend(function(styles){
 		this.contents = {};
 		this._current = {};
 		this._styles = styles;
@@ -16,7 +22,7 @@ dojo.require("dojox.dtl.dom");
 			if(styles[key].indexOf("{{") != -1){
 				var node = new dd.Template(styles[key]);
 			}else{
-				var node = dojo.delegate(simple);
+				var node = lang.delegate(simple);
 				node.contents = styles[key];
 			}
 			this.contents[key] = node;
@@ -27,7 +33,7 @@ dojo.require("dojox.dtl.dom");
 			for(var key in this.contents){
 				var value = this.contents[key].render(context);
 				if(this._current[key] != value){
-					dojo.style(buffer.getParent(), key, this._current[key] = value);
+					domStyle.set(buffer.getParent(), key, this._current[key] = value);
 				}
 			}
 			return buffer;
@@ -41,7 +47,7 @@ dojo.require("dojox.dtl.dom");
 		}
 	});
 
-	ddch.BufferNode = dojo.extend(function(nodelist, options){
+	ddch.BufferNode = lang.extend(function(nodelist, options){
 		this.nodelist = nodelist;
 		this.options = options;
 	},
@@ -58,10 +64,10 @@ dojo.require("dojox.dtl.dom");
 					}
 				}
 
-				this.onAddNode && dojo.disconnect(this.onAddNode);
-				this.onRemoveNode && dojo.disconnect(this.onRemoveNode);
-				this.onChangeAttribute && dojo.disconnect(this.onChangeAttribute);
-				this.onChangeData && dojo.disconnect(this.onChangeData);
+				this.onAddNode && connect.disconnect(this.onAddNode);
+				this.onRemoveNode && connect.disconnect(this.onRemoveNode);
+				this.onChangeAttribute && connect.disconnect(this.onChangeAttribute);
+				this.onChangeData && connect.disconnect(this.onChangeData);
 
 				this.swapped = this.parent.cloneNode(true);
 				this.parent.parentNode.replaceChild(this.swapped, this.parent);
@@ -70,26 +76,26 @@ dojo.require("dojox.dtl.dom");
 		render: function(context, buffer){
 			this.parent = buffer.getParent();
 			if(this.options.node){
-				this.onAddNode = dojo.connect(buffer, "onAddNode", dojo.hitch(this, "_swap", "node"));
-				this.onRemoveNode = dojo.connect(buffer, "onRemoveNode", dojo.hitch(this, "_swap", "node"));
+				this.onAddNode = connect.connect(buffer, "onAddNode", lang.hitch(this, "_swap", "node"));
+				this.onRemoveNode = connect.connect(buffer, "onRemoveNode", lang.hitch(this, "_swap", "node"));
 			}
 			if(this.options.text){
-				this.onChangeData = dojo.connect(buffer, "onChangeData", dojo.hitch(this, "_swap", "node"));
+				this.onChangeData = connect.connect(buffer, "onChangeData", lang.hitch(this, "_swap", "node"));
 			}
 			if(this.options["class"]){
-				this.onChangeAttribute = dojo.connect(buffer, "onChangeAttribute", dojo.hitch(this, "_swap", "class"));
+				this.onChangeAttribute = connect.connect(buffer, "onChangeAttribute", lang.hitch(this, "_swap", "class"));
 			}
 
 			buffer = this.nodelist.render(context, buffer);
 
 			if(this.swapped){
 				this.swapped.parentNode.replaceChild(this.parent, this.swapped);
-				dojo.destroy(this.swapped);
+				domConstruct.destroy(this.swapped);
 			}else{
-				this.onAddNode && dojo.disconnect(this.onAddNode);
-				this.onRemoveNode && dojo.disconnect(this.onRemoveNode);
-				this.onChangeAttribute && dojo.disconnect(this.onChangeAttribute);
-				this.onChangeData && dojo.disconnect(this.onChangeData);
+				this.onAddNode && connect.disconnect(this.onAddNode);
+				this.onRemoveNode && connect.disconnect(this.onRemoveNode);
+				this.onChangeAttribute && connect.disconnect(this.onChangeAttribute);
+				this.onChangeData && connect.disconnect(this.onChangeData);
 			}
 
 			delete this.parent;
@@ -104,7 +110,7 @@ dojo.require("dojox.dtl.dom");
 		}
 	});
 
-	dojo.mixin(ddch, {
+	lang.mixin(ddch, {
 		buffer: function(parser, token){
 			// summary:
 			//		Buffer large DOM manipulations during re-render.
@@ -132,7 +138,7 @@ dojo.require("dojox.dtl.dom");
 			var parts = token.contents.split().slice(1);
 			var options = {};
 			var found = false;
-			for(var i=parts.length; i--;){
+			for(var i = parts.length; i--;){
 				found = true;
 				options[parts[i]] = true;
 			}
@@ -144,7 +150,7 @@ dojo.require("dojox.dtl.dom");
 			return new ddch.BufferNode(nodelist, options);
 		},
 		html: function(parser, token){
-			dojo.deprecated("{% html someVariable %}", "Use {{ someVariable|safe }} instead");
+			kernel.deprecated("{% html someVariable %}", "Use {{ someVariable|safe }} instead");
 			return parser.create_variable_node(token.contents.slice(5) + "|safe");
 		},
 		style_: function(parser, token){
@@ -154,7 +160,7 @@ dojo.require("dojox.dtl.dom");
 			for(var i = 0, rule; rule = rules[i]; i++){
 				var parts = rule.split(/\s*:\s*/g);
 				var key = parts[0];
-				var value = dojo.trim(parts[1]);
+				var value = lang.trim(parts[1]);
 				if(value){
 					styles[key] = value;
 				}
@@ -166,4 +172,5 @@ dojo.require("dojox.dtl.dom");
 	dd.register.tags("dojox.dtl.contrib", {
 		"dom": ["html", "attr:style", "buffer"]
 	});
-})();
\ No newline at end of file
+	return dojox.dtl.contrib.dom;
+});
\ No newline at end of file
diff --git a/dojox/dtl/contrib/html.js b/dojox/dtl/contrib/html.js
deleted file mode 100644
index a8c60a0..0000000
--- a/dojox/dtl/contrib/html.js
+++ /dev/null
@@ -1,3 +0,0 @@
-dojo.provide("dojox.dtl.contrib.html");
-dojo.require("dojox.dtl.contrib.dom");
-dojo.deprecated("dojox.dtl.html", "All packages and classes in dojox.dtl that start with Html or html have been renamed to Dom or dom");
\ No newline at end of file
diff --git a/dojox/dtl/contrib/objects.js b/dojox/dtl/contrib/objects.js
index fb4ed72..56e7a7d 100644
--- a/dojox/dtl/contrib/objects.js
+++ b/dojox/dtl/contrib/objects.js
@@ -1,11 +1,20 @@
-dojo.provide("dojox.dtl.contrib.objects");
+define([
+	"dojo/_base/lang",
+	"../_base"	
+], function(lang,dd){
+	/*=====
+		dd = dojox.dtl;
+	=====*/
+	lang.getObject("dojox.dtl.contrib.objects", true);
 
-dojo.mixin(dojox.dtl.contrib.objects, {
-	key: function(value, arg){
-		return value[arg];
-	}
-});
+	lang.mixin(dd.contrib.objects, {
+		key: function(value, arg){
+			return value[arg];
+		}
+	});
 
-dojox.dtl.register.filters("dojox.dtl.contrib", {
-	"objects": ["key"]
+	dd.register.filters("dojox.dtl.contrib", {
+		"objects": ["key"]
+	});
+	return dojox.dtl.contrib.objects;
 });
\ No newline at end of file
diff --git a/dojox/dtl/demos/demo_Animation.html b/dojox/dtl/demos/demo_Animation.html
index 121395d..f4b43ee 100644
--- a/dojox/dtl/demos/demo_Animation.html
+++ b/dojox/dtl/demos/demo_Animation.html
@@ -3,10 +3,10 @@
 		<title>Testing dojox.dtl using animation to change attributes</title>
 		<script src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, usePlainJson: true"></script>
 		<script>
-			dojo.require("dijit._Widget");
+			dojo.require("dijit._WidgetBase");
 			dojo.require("dojox.dtl._DomTemplated");
 
-			dojo.declare("demo.Animation", [dijit._Widget, dojox.dtl._DomTemplated],
+			dojo.declare("demo.Animation", [dijit._WidgetBase, dojox.dtl._DomTemplated],
 			{
 				buffer: 0, // Note: Sensitivity is 0 by default, but this is to emphasize we're not doing any buffering
 				templateString: dojo.cache("dojox.dtl.demos.templates", "animation.html"),
diff --git a/dojox/dtl/demos/demo_Animation_amd.html b/dojox/dtl/demos/demo_Animation_amd.html
new file mode 100644
index 0000000..def5ecd
--- /dev/null
+++ b/dojox/dtl/demos/demo_Animation_amd.html
@@ -0,0 +1,53 @@
+<html>
+	<head>
+		<title>Testing dojox.dtl using animation to change attributes</title>
+		<script src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, usePlainJson: true, async:true"></script>
+		<script>
+			require(["dojo/_base/lang",
+					"dojo/_base/declare",
+					"dijit/_WidgetBase", 
+					"dojox/dtl/_DomTemplated",
+					"dojo/text!./templates/animation.html",
+					"dojo/aspect",
+					"dojo/_base/fx",
+					"dojo/dom-style",
+					'dojo/domReady!',
+					"dojo/parser",
+					"dojox/dtl/contrib/dom"], // the dtl deps used in animation.html. require it here so that it is loaded when dtl is processed.
+					function(lang, declare, _WidgetBase, _DomTemplated, template, aspect, fx, domstyle){
+			
+				declare("demo.Animation", [_WidgetBase, _DomTemplated], {
+					buffer: 0, // Note: Sensitivity is 0 by default, but this is to emphasize we're not doing any buffering
+					templateString: template,
+					constructor: function(props, node){
+						this.x = 0;
+						this.y = 0;
+					},
+					postCreate: function(){
+						var anim = new fx.Animation({
+							curve: [0, 300],
+							rate: 10,
+							duration: 5000,
+							easing: fx._defaultEasing
+						});
+						aspect.after(anim, "onAnimate", lang.hitch(this, this._reDraw), true);
+						anim.play();
+					},
+					_reDraw: function(obj){
+						this.x = obj;
+						this.y = Math.sqrt(obj) * 10;
+	
+						domstyle.set(this.blue, "left", this.x);
+						domstyle.set(this.blue, "top", this.y + 10);
+	
+						this.render();
+					}
+				});
+			});
+
+		</script>
+	</head>
+	<body>
+		<div data-dojo-type="demo.Animation" ></div>
+	</body>
+</html>
diff --git a/dojox/dtl/demos/demo_Blog.html b/dojox/dtl/demos/demo_Blog.html
index d58c4ed..5f244b8 100644
--- a/dojox/dtl/demos/demo_Blog.html
+++ b/dojox/dtl/demos/demo_Blog.html
@@ -3,11 +3,11 @@
 		<title>Testing dojox.dtl using a blog example</title>
 		<script src="../../../dojo/dojo.js" djConfig="usePlainJson: true, parseOnLoad: true"></script>
 		<script>
-			dojo.require("dijit._Widget");
+			dojo.require("dijit._WidgetBase");
 			dojo.require("dojox.dtl._DomTemplated");
 			dojo.require("dojo.parser");
 
-			dojo.declare("demo.Blog", [dijit._Widget, dojox.dtl._DomTemplated],
+			dojo.declare("demo.Blog", [dijit._WidgetBase, dojox.dtl._DomTemplated],
 			{
 				templatePath: dojo.moduleUrl("dojox.dtl.demos.templates", "blog_list.html"),
 				base: {
diff --git a/dojox/dtl/demos/demo_Data.html b/dojox/dtl/demos/demo_Data.html
index 8f2f92b..d84ff26 100644
--- a/dojox/dtl/demos/demo_Data.html
+++ b/dojox/dtl/demos/demo_Data.html
@@ -3,13 +3,13 @@
 			<title>Demo using the dojo.data bind_data tag</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">
+				dojo.require("dijit._WidgetBase");
 				dojo.require("dojox.dtl._Templated");
 				dojo.require("dojox.data.FlickrRestStore");
 				dojo.require("dojo.parser");
 
-				dojo.declare("demo.Gallery", [dijit._Widget, dojox.dtl._Templated], {
+				dojo.declare("demo.Gallery", [dijit._WidgetBase, dojox.dtl._Templated], {
 					templateString: dojo.cache("dojox.dtl.demos.templates", "gallery.html"),
 					store: new dojox.data.FlickrRestStore(),
 					selectThumbnail: function(e){
@@ -56,4 +56,4 @@
 		<p>Also see demo_Tree.html for an alternative way to use data stores.</p>
 		<div dojoType="demo.Gallery"></div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/dojox/dtl/demos/demo_DomTemplated.html b/dojox/dtl/demos/demo_DomTemplated.html
index 28a88b6..2e418e4 100644
--- a/dojox/dtl/demos/demo_DomTemplated.html
+++ b/dojox/dtl/demos/demo_DomTemplated.html
@@ -3,7 +3,6 @@
 			<title>Demo using dojox.dtl._DomTemplated</title>
 			<script type="text/javascript" src="../../../dojo/dojo.js"
 				djConfig="isDebug: true, parseOnLoad: true"></script>
-			<script type="text/javascript" src="../../../dijit/dijit.js"></script>
 			<style type="text/css">
 				@import "../../../dijit/themes/tundra/tundra.css";
 				#pane {
@@ -11,11 +10,12 @@
 				}
 			</style>
 	    <script type="text/javascript">
+					dojo.require("dijit._WidgetBase");
 					dojo.require("dojox.dtl._DomTemplated");
 					dojo.require("dijit.form.Button");
                     dojo.require("dijit.layout.ContentPane");
 
-					dojo.declare("Fruit", [dijit._Widget, dojox.dtl._DomTemplated], {
+					dojo.declare("Fruit", [dijit._WidgetBase, dojox.dtl._DomTemplated], {
 						widgetsInTemplate: true,
 						items: ["apple", "banana", "orange"],
 						keyUp: function(e){
@@ -32,7 +32,7 @@
 							}
 						},
 						// Note, the load tag here is superfluous, since _DomTemplate has a dojo.require for it.
-						templateString: '<!--{% load dojox.dtl.contrib.dijit %}--><div><input dojoAttachEvent="onkeyup: keyUp" dojoAttachPoint="input"> <button dojoType="dijit.form.Button" dojoAttachPoint="button" dojoAttachEvent="onClick: keyUp">Add/Remove Item</button><div id="pane" dojoType="dijit.layout.ContentPane parsed"><ul><!--{% for item in items %}--><li><button dojoType="dijit.form.Button parsed" title="Fruit: {{ item }}" otherAttr2="x_{{item}}"><!--{{ item }}--><script type="dojo/connect" even [...]
+						templateString: '<div><input dojoAttachEvent="onkeyup: keyUp" dojoAttachPoint="input"> <button dojoType="dijit.form.Button" dojoAttachPoint="button" dojoAttachEvent="onClick: keyUp">Add/Remove Item</button><div id="pane" dojoType="dijit.layout.ContentPane parsed"><ul><!--{% for item in items %}--><li><button dojoType="dijit.form.Button parsed" title="Fruit: {{ item }}" otherAttr2="x_{{item}}"><!--{{ item }}--><script type="dojo/connect" event="onClick" args="e">console.debug("You c [...]
 					});
 
 					dojo.require("dojo.parser");
@@ -41,4 +41,4 @@
 	<body class="tundra">
 		<div dojoType="Fruit" id="dtl"></div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/dojox/dtl/demos/demo_DomTemplated_amd.html b/dojox/dtl/demos/demo_DomTemplated_amd.html
new file mode 100644
index 0000000..8d681fa
--- /dev/null
+++ b/dojox/dtl/demos/demo_DomTemplated_amd.html
@@ -0,0 +1,50 @@
+<html>
+	<head>
+			<title>Demo using dojox.dtl._DomTemplated</title>
+			<script type="text/javascript" src="../../../dojo/dojo.js"
+				data-dojo-config="async:true, isDebug: true, parseOnLoad: true"></script>
+			<style type="text/css">
+				@import "../../../dijit/themes/tundra/tundra.css";
+				#pane {
+				    border: 1px solid darkblue;
+				}
+			</style>
+	    <script type="text/javascript">
+			require(["dojo/_base/declare",
+					 "dojo/keys",
+					 "dojo/_base/array",
+					 "dijit/_WidgetBase",
+					 "dojox/dtl/_DomTemplated",
+					 "dijit/form/Button",
+            		 "dijit/layout/ContentPane",
+					 "dojo/parser",
+					 "dojox/dtl/tag/logic"],
+				 function(declare, keys, array, _WidgetBase, _DomTemplated, Button, ContentPane){
+
+					declare("Fruit", [_WidgetBase, _DomTemplated], {
+						widgetsInTemplate: true,
+						items: ["apple", "banana", "orange"],
+						keyUp: function(e){
+							if((e.type == "click" || e.keyCode == keys.ENTER) && this.input.value){
+								console.debug(this.button);
+								var i = array.indexOf(this.items, this.input.value);
+								if(i != -1){
+									this.items.splice(i, 1);
+								}else{
+									this.items.push(this.input.value);
+								}
+								this.input.value = "";
+								this.render();
+							}
+						},
+						templateString: '<div><input data-dojo-attach-event="onkeyup:keyUp" data-dojo-attach-point="input"> <button data-dojo-type="dijit.form.Button" data-dojo-attach-point="button" data-dojo-attach-event="onClick: keyUp">Add/Remove Item</button><div id="pane" data-dojo-type="dijit.layout.ContentPane parsed"><ul><!--{% for item in items %}--><li><button data-dojo-type="dijit.form.Button parsed" title="Fruit: {{ item }}" otherAttr2="x_{{item}}"><!--{{ item }}--><script type="dojo/on" data- [...]
+					});
+				}
+			);
+				
+	    </script>
+	</head>
+	<body class="tundra">
+		<div data-dojo-type="Fruit" id="dtl"></div>
+	</body>
+</html>
diff --git a/dojox/dtl/demos/demo_Events.html b/dojox/dtl/demos/demo_Events.html
index 038a3d9..ec181b9 100644
--- a/dojox/dtl/demos/demo_Events.html
+++ b/dojox/dtl/demos/demo_Events.html
@@ -3,15 +3,15 @@
 			<title>Demo using dojox.dtl._Templated</title>
 	    <script type="text/javascript" src="../../../dojo/dojo.js"
 				djConfig="isDebug: true, parseOnLoad: true"></script>
-	    <script type="text/javascript" src="../../../dijit/dijit.js"></script>
 			<style type="text/css">
 				@import "../../../dijit/themes/tundra/tundra.css";
 			</style>
 	    <script type="text/javascript">
+					dojo.require("dijit._WidgetBase");
 					dojo.require("dojox.dtl._DomTemplated");
 					dojo.require("dijit.form.Button");
 
-					dojo.declare("Fruit", [dijit._Widget, dojox.dtl._DomTemplated], {
+					dojo.declare("Fruit", [dijit._WidgetBase, dojox.dtl._DomTemplated], {
 						widgetsInTemplate: true,
 						items: ["apple", "banana", "orange"],
 						keyUp: function(e){
@@ -34,7 +34,7 @@
 							console.debug("You " + verb + " a:", fruit);
 						},
 						// Note, the load tag here is superfluous, since _DomTemplate has a dojo.require for it.
-						templateString: '<!--{% load dojox.dtl.contrib.dijit %}--><div><input dojoAttachEvent="onkeyup: keyUp" dojoAttachPoint="input"> <button dojoType="dijit.form.Button" dojoAttachPoint="button">Add/Remove Item</button><ul><!--{% for item in items %}--><li onclick="debug \'ate\' item"><!--{{ item }}--></li><!--{% endfor %}--></ul></div>'
+						templateString: '{% load dojox.dtl.contrib.dijit %}<div><input dojoAttachEvent="onkeyup: keyUp" dojoAttachPoint="input"> <button dojoType="dijit.form.Button" dojoAttachPoint="button">Add/Remove Item</button><ul><!--{% for item in items %}--><li onclick="debug \'ate\' item"><!--{{ item }}--></li><!--{% endfor %}--></ul></div>'
 					});
 
 	        dojo.require("dojo.parser");
@@ -43,4 +43,4 @@
 	<body class="tundra">
 		<div dojoType="Fruit"></div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/dojox/dtl/demos/demo_NodeList_amd.html b/dojox/dtl/demos/demo_NodeList_amd.html
new file mode 100644
index 0000000..840d444
--- /dev/null
+++ b/dojox/dtl/demos/demo_NodeList_amd.html
@@ -0,0 +1,42 @@
+<html>
+	<head>
+		<title>Demo using dojox.dtl._Templated</title>
+    <script type="text/javascript" src="../../../dojo/dojo.js"
+			djConfig="async: true, isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript">
+		require(['dojox/dtl/ext-dojo/NodeList',
+				'dojox/dtl/Context',
+				'dojo/query',
+				'dojo/dom',
+				'dojo/parser',
+				'dojo/domReady!',
+				'dojox/dtl/tag/logic'], 
+				function(NodeList, Context, query, dom){
+					
+				// First, look at the NodeList extension
+				query(".fruit").dtl(require.toUrl("dojox/dtl/demos/templates/nodelist.html"), { items: ["apple", "banana", "pear"] });
+
+				query(".fruit2").dtl("<div><ul>{% for item in items %}<li>{{ item }}</li>{% endfor %}</ul></div", { items: ["apple", "banana", "pear"] });
+
+				// Now, create a real template object
+				var tpl = new dojox.dtl.Template(require.toUrl("dojox/dtl/demos/templates/nodelist.html"));
+
+				// And test its update function with a dojo.query
+				tpl.update(query(".update"), require.toUrl("dojox/dtl/demos/json/fruit.json"));
+
+				setTimeout(function(){
+					// And now test it with an ID reference
+					tpl.update("updateId", require.toUrl("dojox/dtl/demos/json/morefruit.json"));
+					// And throw in a standard rendering just for fun
+					dom.byId("updateId2").innerHTML = tpl.render(new dojox.dtl.Context({ items: ["pineapple", "orange", "tomato"] }));
+				}, 5000);
+			});
+		</script>
+	</head>
+	<body>
+		<div class="fruit"></div>
+		<div class="fruit2"></div>
+		<div class="update" id="updateId"></div>
+		<div class="update" id="updateId2"></div>
+	</body>
+</html>
diff --git a/dojox/dtl/demos/demo_Table.html b/dojox/dtl/demos/demo_Table.html
index cc13e4c..f1aa911 100644
--- a/dojox/dtl/demos/demo_Table.html
+++ b/dojox/dtl/demos/demo_Table.html
@@ -3,7 +3,6 @@
 			<title>Demo to show a massive nested for loop to render a table</title>
 	    <script type="text/javascript" src="../../../dojo/dojo.js"
 				djConfig="isDebug: true, parseOnLoad: true"></script>
-	    <script type="text/javascript" src="../../../dijit/dijit.js"></script>
 			<style type="text/css">
 				@import "../../../dijit/themes/tundra/tundra.css";
 
@@ -22,12 +21,13 @@
 				}
 			</style>
 	    <script type="text/javascript">
+					dojo.require("dijit._WidgetBase");
 					dojo.require("dojox.dtl._DomTemplated");
 					dojo.require("dojox.dtl.tag.logic");
 					dojo.require("dojox.dtl.tag.loop");
 					dojo.require("dojox.dtl.filter.lists");
 
-					dojo.declare("demo.Table", [dijit._Widget, dojox.dtl._DomTemplated], {
+					dojo.declare("demo.Table", [dijit._WidgetBase, dojox.dtl._DomTemplated], {
 						pos: 0,
 						postMixInProperties: function(){
 							this.ths = dojo.query("th", this.domNode).map(function(item){
diff --git a/dojox/dtl/demos/demo_Templated.html b/dojox/dtl/demos/demo_Templated.html
index 94d2a6f..b37af58 100644
--- a/dojox/dtl/demos/demo_Templated.html
+++ b/dojox/dtl/demos/demo_Templated.html
@@ -2,12 +2,12 @@
 	<head>
 			<title>Demo using dojox.dtl._Templated</title>
 	    <script type="text/javascript" src="../../../dojo/dojo.js"
-				djConfig="isDebug: false, parseOnLoad: true"></script>
-	    <script type="text/javascript" src="../../../dijit/dijit.js"></script> 
+				djConfig="isDebug: true, parseOnLoad: true"></script>
 	    <script type="text/javascript">
+					dojo.require("dijit._WidgetBase");
 					dojo.require("dojox.dtl._Templated");
 
-					dojo.declare("Fruit", [dijit._Widget, dojox.dtl._Templated], {
+					dojo.declare("Fruit", [dijit._WidgetBase, dojox.dtl._Templated], {
 						oldRepl: "Fruit: ",
 						_dijitTemplateCompat: true,
 						items: ["apple", "banana", "orange"],
diff --git a/dojox/dtl/demos/demo_Templated_amd.html b/dojox/dtl/demos/demo_Templated_amd.html
new file mode 100644
index 0000000..7235aac
--- /dev/null
+++ b/dojox/dtl/demos/demo_Templated_amd.html
@@ -0,0 +1,42 @@
+<html>
+	<head>
+			<title>Demo using dojox.dtl._Templated</title>
+	    <script type="text/javascript" src="../../../dojo/dojo.js"
+				data-dojo-config="isDebug: true, parseOnLoad: true, async:true"></script>
+	    <script type="text/javascript">
+			require(["dijit/_WidgetBase",
+					 "dojox/dtl/_Templated",
+					 "dojo/_base/array",
+					 "dojo/_base/declare",
+					 "dojo/query",
+					 "dojo/keys",					 
+					 "dojo/parser",
+					 "dojox/dtl/tag/logic"], 
+					 function(_WidgetBase, _Templated, array, declare, query, keys){
+
+						declare("Fruit", [_WidgetBase, _Templated], {
+							oldRepl: "Fruit: ",
+							_dijitTemplateCompat: true,
+							items: ["apple", "banana", "orange"],
+							keyUp: function(e){
+								if(e.keyCode == keys.ENTER){
+									var i = array.indexOf(this.items, e.target.value);
+									if(i != -1){
+										this.items.splice(i, 1);
+									}else{
+										this.items.push(e.target.value);
+									}
+									e.target.value = "";
+									this.render();
+									query("input", this.domNode).forEach("item.focus();");
+								}
+							},
+							templateString: '<div><input dojoAttachEvent="onkeyup: keyUp"><ul>{% for item in items %}<li>${oldRepl} {{ item }}</li>{% endfor %}</ul></div>'
+						});
+			});
+	    </script>
+	</head>
+	<body>
+		<div data-dojo-type="Fruit"></div>
+	</body>
+</html>
diff --git a/dojox/dtl/demos/demo_Tree.html b/dojox/dtl/demos/demo_Tree.html
index 434d20b..897ce8a 100644
--- a/dojox/dtl/demos/demo_Tree.html
+++ b/dojox/dtl/demos/demo_Tree.html
@@ -3,8 +3,8 @@
 			<title>Demo to show recursion in DTL</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">
+					dojo.require("dijit._WidgetBase");
 					dojo.require("dojox.dtl._DomTemplated");
 					dojo.require("dojo.data.ItemFileReadStore");
 					dojo.require("dojo.parser");
@@ -25,7 +25,7 @@
 							}
 						});
 
-						dojo.declare("demo.Tree", [dijit._Widget, dojox.dtl._DomTemplated], {
+						dojo.declare("demo.Tree", [dijit._WidgetBase, dojox.dtl._DomTemplated], {
 							constructor: function(){
 								this.disabled = {};
 							},
@@ -45,4 +45,4 @@
 	<body>
 		<div dojoType="demo.Tree"></div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/dojox/dtl/demos/templates/blog_base.html b/dojox/dtl/demos/templates/blog_base.html
index f01bbc4..cc5d150 100644
--- a/dojox/dtl/demos/templates/blog_base.html
+++ b/dojox/dtl/demos/templates/blog_base.html
@@ -1,4 +1,4 @@
-<!--{% load dojox.dtl.contrib.dom %}-->
+{% load dojox.dtl.contrib.dom %}
 <div>
 	<h1><!--{{ title }}--></h1>
 	<ul style="float: left; width: 100px; height: 300px; margin-right: 20px; border: 1px solid #666;">
diff --git a/dojox/dtl/demos/templates/blog_list.html b/dojox/dtl/demos/templates/blog_list.html
index 2413605..a686a4c 100644
--- a/dojox/dtl/demos/templates/blog_list.html
+++ b/dojox/dtl/demos/templates/blog_list.html
@@ -1,5 +1,5 @@
 <!--{% extends base %}-->
-<!--{% load dojox.dtl.contrib.dijit %}-->
+{% load dojox.dtl.contrib.dijit %}
 <!--{% block body %}-->
 <ul>
 <!--{% for key, blog in blog_list.items %}-->
diff --git a/dojox/dtl/demos/templates/blog_page.html b/dojox/dtl/demos/templates/blog_page.html
index 17be535..63ef126 100644
--- a/dojox/dtl/demos/templates/blog_page.html
+++ b/dojox/dtl/demos/templates/blog_page.html
@@ -1,5 +1,5 @@
 <!--{% extends "shared:templates/blog_base.html" %}-->
-<!--{% load dojox.dtl.contrib.dom %}-->
+{% load dojox.dtl.contrib.dom %}
 <!--{% block body %}-->
 <div>
 	<!--{{ body|safe }}-->
diff --git a/dojox/dtl/dom.js b/dojox/dtl/dom.js
index 744d0b9..6124f28 100755
--- a/dojox/dtl/dom.js
+++ b/dojox/dtl/dom.js
@@ -1,11 +1,19 @@
-dojo.provide("dojox.dtl.dom");
-
-dojo.require("dojox.dtl._base");
-dojo.require("dojox.dtl.Context");
-
-(function(){
-	var dd = dojox.dtl;
-
+define([
+	"dojo/_base/lang",
+	"./_base",
+	"dojox/string/tokenize",
+	"./Context",
+	"dojo/dom",
+	"dojo/dom-construct",
+	"dojo/_base/html",
+	"dojo/_base/array",
+	"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;
@@ -23,9 +31,9 @@ dojo.require("dojox.dtl.Context");
 			if(typeof this._commentable == "undefined"){
 				// Check to see if the browser can handle comments
 				this._commentable = false;
-				var div = document.createElement("div");
-				div.innerHTML = "<!--Test comment handling, and long comments, using comments whenever possible.-->";
-				if(div.childNodes.length && div.childNodes[0].nodeType == 8 && div.childNodes[0].data == "comment"){
+				var div = document.createElement("div"), comment = "Test comment handling, and long comments, using comments whenever possible.";
+				div.innerHTML = "<!--" + comment + "-->";
+				if(div.childNodes.length && div.firstChild.nodeType == 8 && div.firstChild.data == comment){
 					this._commentable = true;
 				}
 			}
@@ -35,13 +43,13 @@ dojo.require("dojox.dtl.Context");
 				text = text.replace(/<!--({({|%).*?(%|})})-->/g, "$1");
 			}
 
-			if(dojo.isIE){
+			if(has("ie")){
 				text = text.replace(/\b(checked|disabled|readonly|style)="/g, 't$1="');
 			}
 			text = text.replace(/\bstyle="/g, 'tstyle="');
 
 			var match;
-			var table = dojo.isWebKit;
+			var table = has("webkit");
 			var pairs = [ // Format: [enable, parent, allowed children (first for nesting), nestings]
 				[true, "select", "option"],
 				[table, "tr", "td|th"],
@@ -65,7 +73,7 @@ dojo.require("dojox.dtl.Context");
 							innerRe.push("<" + inner + "(?:.|\n)*?>(?:.|\n)*?</" + inner + ">");
 						}
 						var tags = [];
-						var tokens = dojox.string.tokenize(match[1], new RegExp("(" + innerRe.join("|") + ")", "ig"), function(data){
+						var tokens = Tokenize(match[1], new RegExp("(" + innerRe.join("|") + ")", "ig"), function(data){
 							var tag = /<(\w+)/.exec(data)[1];
 							if(!tags[tag]){
 								tags[tag] = true;
@@ -79,7 +87,7 @@ dojo.require("dojox.dtl.Context");
 							var replace = [];
 							for(var j = 0, jl = tokens.length; j < jl; j++) {
 								var token = tokens[j];
-								if(dojo.isObject(token)){
+								if(lang.isObject(token)){
 									replace.push(token.data);
 								}else{
 									var stripped = token.replace(this._reTrim, "");
@@ -117,7 +125,7 @@ dojo.require("dojox.dtl.Context");
 				}
 			}
 
-			for(var i=replacements.length; i--;){
+			for(var i = replacements.length; i--;){
 				text = text.replace("\xFF" + i, replacements[i]);
 			}
 
@@ -189,7 +197,7 @@ dojo.require("dojox.dtl.Context");
 			}
 
 			var children = [];
-			if(dojo.isIE && node.tagName == "SCRIPT"){
+			if(has("ie") && node.tagName == "SCRIPT"){
 				children.push({
 					nodeType: 3,
 					data: node.text
@@ -224,7 +232,7 @@ dojo.require("dojox.dtl.Context");
 				}else if(node.getAttribute){
 					value = node.getAttribute(key, 2) || value;
 					if(key == "href" || key == "src"){
-						if(dojo.isIE){
+						if(has("ie")){
 							var hash = location.href.lastIndexOf(location.hash);
 							var href = location.href.substring(0, hash).split("/");
 							href.pop();
@@ -237,9 +245,9 @@ dojo.require("dojox.dtl.Context");
 					}else if(key == "tstyle"){
 						clear = key; // Placeholder because we can't use style
 						key = "style";
-					}else if(dd.BOOLS[key.slice(1)] && dojo.trim(value)){
+					}else if(dd.BOOLS[key.slice(1)] && lang.trim(value)){
 						key = key.slice(1);
-					}else if(this._uppers[key] && dojo.trim(value)){
+					}else if(this._uppers[key] && lang.trim(value)){
 						clear = this._uppers[key]; // Replaced by lowercase
 					}
 				}
@@ -315,17 +323,20 @@ dojo.require("dojox.dtl.Context");
 					return;
 				case 8:
 					if(data.indexOf("{%") == 0){
-						var text = dojo.trim(data.slice(2, -2));
+						var text = lang.trim(data.slice(2, -2));
 						if(text.substr(0, 5) == "load "){
-							var parts = dojo.trim(text).split(/\s+/g);
+							var parts = lang.trim(text).split(/\s+/g);
 							for(var i = 1, part; part = parts[i]; i++){
-								dojo["require"](part);
+								if (/\./.test(part)){
+									part = part.replace(/\./g,"/");
+								}
+								require([part]);
 							}
 						}
 						tokens.push([dd.TOKEN_BLOCK, text]);
 					}
 					if(data.indexOf("{{") == 0){
-						tokens.push([dd.TOKEN_VAR, dojo.trim(data.slice(2, -2))]);
+						tokens.push([dd.TOKEN_VAR, lang.trim(data.slice(2, -2))]);
 					}
 					if(child.parentNode) child.parentNode.removeChild(child);
 					return;
@@ -333,12 +344,12 @@ dojo.require("dojox.dtl.Context");
 		}
 	};
 
-	dd.DomTemplate = dojo.extend(function(/*String|DOMNode|dojo._Url*/ obj){
-		// summary: Use this object 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 = dojo.byId(obj);
+			var node = dom.byId(obj);
 			if(node && node.nodeType == 1){
-				dojo.forEach(["class", "src", "href", "name", "value"], function(item){
+				array.forEach(["class", "src", "href", "name", "value"], function(item){
 					ddh._attributes[item] = true;
 				});
 				obj = {
@@ -363,16 +374,20 @@ dojo.require("dojox.dtl.Context");
 	{
 		_count: 0,
 		_re: /\bdojo:([a-zA-Z0-9_]+)\b/g,
-		setClass: function(str){
+		setClass: function(/*String*/str){
+			// summary: Sets the specified class name on the root node.
 			this.getRootNode().className = str;
 		},
 		getRootNode: function(){
+			// summary: Returns the template root node.
 			return this.buffer.rootNode;
 		},
 		getBuffer: function(){
+			// summary: Returns a new buffer.
 			return new dd.DomBuffer();
 		},
-		render: function(context, buffer){
+		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);
@@ -388,7 +403,7 @@ dojo.require("dojox.dtl.Context");
 		}
 	});
 
-	dd.DomBuffer = dojo.extend(function(/*Node*/ parent){
+	dd.DomBuffer = lang.extend(function(/*Node*/ parent){
 		// summary: Allows the manipulation of DOM
 		// description:
 		//		Use this to append a child, change the parent, or
@@ -409,13 +424,13 @@ dojo.require("dojox.dtl.Context");
 			}
 
 			if(!parent){
-				if(node.nodeType == 3 && dojo.trim(node.data)){
+				if(node.nodeType == 3 && lang.trim(node.data)){
 					throw new Error("Text should not exist outside of the root node in template");
 				}
 				return this;
 			}
 			if(this._closed){
-				if(node.nodeType == 3 && !dojo.trim(node.data)){
+				if(node.nodeType == 3 && !lang.trim(node.data)){
 					return this;
 				}else{
 					throw new Error("Content should not exist outside of the root node in template");
@@ -443,7 +458,7 @@ dojo.require("dojox.dtl.Context");
 			parent._cache.push(node);
 			return this;
 		},
-		remove: function(obj){
+		remove: function(/*String|DomNode*/obj){
 			if(typeof obj == "string"){
 				if(this._parent){
 					this._parent.removeAttribute(obj);
@@ -463,7 +478,7 @@ dojo.require("dojox.dtl.Context");
 			return this;
 		},
 		setAttribute: function(key, value){
-			var old = dojo.attr(this._parent, key);
+			var old = html.attr(this._parent, key);
 			if(this.onChangeAttribute && old != value){
 				this.onChangeAttribute(this._parent, key, old, value);
 			}
@@ -471,8 +486,11 @@ dojo.require("dojox.dtl.Context");
 				//console.log(value);
 				this._parent.style.cssText = value;
 			}else{
-				dojo.attr(this._parent, key, value);
+				html.attr(this._parent, key, value);
 				//console.log(this._parent, key, value);
+				if(key == "value"){
+					this._parent.setAttribute(key, value);
+				}
 			}
 			return this;
 		},
@@ -480,12 +498,12 @@ dojo.require("dojox.dtl.Context");
 			if(!context.getThis()){ throw new Error("You must use Context.setObject(instance)"); }
 			this.onAddEvent && this.onAddEvent(this.getParent(), type, fn);
 			var resolved = fn;
-			if(dojo.isArray(args)){
+			if(lang.isArray(args)){
 				resolved = function(e){
 					this[fn].apply(this, [e].concat(args));
 				}
 			}
-			return dojo.connect(this.getParent(), type, context.getThis(), resolved);
+			return connect.connect(this.getParent(), type, context.getThis(), resolved);
 		},
 		setParent: function(node, /*Boolean?*/ up, /*Boolean?*/ root){
 			if(!this._parent) this._parent = this._first = node;
@@ -497,7 +515,7 @@ dojo.require("dojox.dtl.Context");
 			if(up){
 				var parent = this._parent;
 				var script = "";
-				var ie = dojo.isIE && parent.tagName == "SCRIPT";
+				var ie = has("ie") && parent.tagName == "SCRIPT";
 				if(ie){
 					parent.text = "";
 				}
@@ -573,7 +591,7 @@ dojo.require("dojox.dtl.Context");
 		=====*/
 	});
 
-	dd._DomNode = dojo.extend(function(node){
+	dd._DomNode = lang.extend(function(node){
 		// summary: Places a node into DOM
 		this.contents = node;
 	},
@@ -594,7 +612,7 @@ dojo.require("dojox.dtl.Context");
 		}
 	});
 
-	dd._DomNodeList = dojo.extend(function(/*Node[]*/ nodes){
+	dd._DomNodeList = lang.extend(function(/*Node[]*/ nodes){
 		// summary: A list of any DOM-specific node objects
 		// description:
 		//		Any object that's used in the constructor or added
@@ -653,7 +671,7 @@ dojo.require("dojox.dtl.Context");
 			}
 
 			var html = div.innerHTML;
-			return (dojo.isIE) ? html.replace(/\s*_(dirty|clone)="[^"]*"/g, "") : html;
+			return (has("ie")) ? domconstruct.replace(/\s*_(dirty|clone)="[^"]*"/g, "") : html;
 		},
 		unrender: function(context, buffer, instance){
 			if(instance){
@@ -712,7 +730,7 @@ dojo.require("dojox.dtl.Context");
 		}
 	});
 
-	dd._DomVarNode = dojo.extend(function(str){
+	dd._DomVarNode = lang.extend(function(str){
 		// summary: A node to be processed as a variable
 		// description:
 		//		Will render an object that supports the render function
@@ -821,7 +839,7 @@ dojo.require("dojox.dtl.Context");
 				}
 				return buffer;
 			case "html":
-				for(var i=0, l=this._html.length; i<l; i++){
+				for(var i = 0, l = this._html.length; i < l; i++){
 					buffer = buffer.remove(this._html[i]);
 				}
 				return buffer;
@@ -834,7 +852,7 @@ dojo.require("dojox.dtl.Context");
 		}
 	});
 
-	dd.ChangeNode = dojo.extend(function(node, /*Boolean?*/ up, /*Bookean*/ root){
+	dd.ChangeNode = lang.extend(function(node, /*Boolean?*/ up, /*Bookean*/ root){
 		// summary: Changes the parent during render/unrender
 		this.contents = node;
 		this.up = up;
@@ -855,7 +873,7 @@ dojo.require("dojox.dtl.Context");
 		}
 	});
 
-	dd.AttributeNode = dojo.extend(function(key, value){
+	dd.AttributeNode = lang.extend(function(key, value){
 		// summary: Works on attributes
 		this.key = key;
 		this.value = value;
@@ -894,7 +912,7 @@ dojo.require("dojox.dtl.Context");
 		}
 	});
 
-	dd._DomTextNode = dojo.extend(function(str){
+	dd._DomTextNode = lang.extend(function(str){
 		// summary: Adds a straight text node without any processing
 		this.contents = document.createTextNode(str);
 		this.upcoming = str;
@@ -916,14 +934,14 @@ dojo.require("dojox.dtl.Context");
 			return buffer.remove(this.contents);
 		},
 		isEmpty: function(){
-			return !dojo.trim(this.contents.data);
+			return !lang.trim(this.contents.data);
 		},
 		clone: function(){
 			return new this.constructor(this.contents.data);
 		}
 	});
 
-	dd._DomParser = dojo.extend(function(tokens){
+	dd._DomParser = lang.extend(function(tokens){
 		// summary: Turn a simple array into a set of objects
 		// description:
 		//	This is also used by all tags to move through
@@ -959,12 +977,12 @@ dojo.require("dojox.dtl.Context");
 							value.setAttribute(token[2], "");
 						}
 						nodelist.push(fn(null, new dd.Token(type, token[2] + " " + token[3])));
-					}else if(dojo.isString(token[3])){
+					}else if(lang.isString(token[3])){
 						if(token[2] == "style" || token[3].indexOf("{%") != -1 || token[3].indexOf("{{") != -1){
 							nodelist.push(new dd.AttributeNode(token[2], token[3]));
-						}else if(dojo.trim(token[3])){
+						}else if(lang.trim(token[3])){
 							try{
-								dojo.attr(value, token[2], token[3]);
+								html.attr(value, token[2], token[3]);
 							}catch(e){}
 						}
 					}
@@ -1027,5 +1045,5 @@ dojo.require("dojox.dtl.Context");
 			return new dd.DomTemplate(ddh.getTemplate(loc));
 		}
 	});
-
-})();
+	return dojox.dtl.dom;
+});
diff --git a/dojox/dtl/ext-dojo/NodeList.js b/dojox/dtl/ext-dojo/NodeList.js
index a185057..99ffbce 100755
--- a/dojox/dtl/ext-dojo/NodeList.js
+++ b/dojox/dtl/ext-dojo/NodeList.js
@@ -1,29 +1,40 @@
-dojo.provide("dojox.dtl.ext-dojo.NodeList");
-dojo.require("dojox.dtl._base");
+define([
+	"dojo/_base/lang",
+	"dojo/_base/NodeList",
+	"../_base"
+], function(lang,Nodelist,dd){
+	/*=====
+		Nodelist = dojo.Nodelist;
+		dd = dojox.dtl;
+	=====*/
+	
+	var nl = lang.getObject("dojox.dtl.ext-dojo.NodeList", true);
 
-dojo.extend(dojo.NodeList, {
-	dtl: function(template, context){
-		// template: dojox.dtl.__StringArgs|String
-		//		The template string or location
-		// context: dojox.dtl.__ObjectArgs|Object
-		//		The context object or location
-		var d = dojox.dtl;
+	lang.extend(Nodelist, {
+		dtl: function(template, context){
+			// 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
+			//		The context object or location
+			var d = dd, self = this;
+			
+			var render = function(template, context){
+				var content = template.render(new d._Context(context));
+				self.forEach(function(node){
+					node.innerHTML = content;
+				});
+			}
 
-		var self = this;
-		var render = function(template, context){
-			var content = template.render(new d._Context(context));
-			self.forEach(function(node){
-				node.innerHTML = content;
+			d.text._resolveTemplateArg(template).addCallback(function(templateString){
+				template = new d.Template(templateString);
+				d.text._resolveContextArg(context).addCallback(function(context){
+					render(template, context);
+				});
 			});
-		}
-
-		d.text._resolveTemplateArg(template).addCallback(function(templateString){
-			template = new d.Template(templateString);
-			d.text._resolveContextArg(context).addCallback(function(context){
-				render(template, context);
-			});
-		});
 
-		return this;
-	}
+			return this;
+		}
+	});
+	return nl;
 });
\ No newline at end of file
diff --git a/dojox/dtl/filter/dates.js b/dojox/dtl/filter/dates.js
index 3ddb89d..6d34fa4 100644
--- a/dojox/dtl/filter/dates.js
+++ b/dojox/dtl/filter/dates.js
@@ -1,11 +1,15 @@
-dojo.provide("dojox.dtl.filter.dates");
+define([
+	"dojo/_base/lang",
+	"../_base",	
+	"../utils/date"
+], function(lang,dd,ddud){
+	/*=====
+		dd = dojox.dtl;
+	=====*/
+	lang.getObject("dojox.dtl.filter.dates", true);
 
-dojo.require("dojox.dtl.utils.date");
-
-(function(){
-	var ddfd = dojox.dtl.filter.dates;
-
-	dojo.mixin(ddfd, {
+	var ddfd = dd.filter.dates;
+	lang.mixin(ddfd, {
 		_toDate: function(value){
 			if(value instanceof Date){
 				return value;
@@ -23,7 +27,7 @@ dojo.require("dojox.dtl.utils.date");
 				return "";
 			}
 			arg = arg || "N j, Y";
-			return dojox.dtl.utils.date.format(value, arg);
+			return ddud.format(value, arg);
 		},
 		time: function(value, arg){
 			// summary: Formats a time according to the given format
@@ -32,7 +36,7 @@ dojo.require("dojox.dtl.utils.date");
 				return "";
 			}
 			arg = arg || "P";
-			return dojox.dtl.utils.date.format(value, arg);
+			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")
@@ -40,7 +44,7 @@ dojo.require("dojox.dtl.utils.date");
 			if(!value){
 				return "";
 			}
-			var timesince = dojox.dtl.utils.date.timesince;
+			var timesince = ddud.timesince;
 			if(arg){
 				return timesince(arg, value);
 			}
@@ -52,11 +56,12 @@ dojo.require("dojox.dtl.utils.date");
 			if(!value){
 				return "";
 			}
-			var timesince = dojox.dtl.utils.date.timesince;
+			var timesince = ddud.timesince;
 			if(arg){
 				return timesince(arg, value);
 			}
 			return timesince(new Date(), value);
 		}
 	});
-})();
\ No newline at end of file
+	return dojox.dtl.filter.dates;
+});
\ No newline at end of file
diff --git a/dojox/dtl/filter/htmlstrings.js b/dojox/dtl/filter/htmlstrings.js
index b6fb05b..7dd9f1e 100644
--- a/dojox/dtl/filter/htmlstrings.js
+++ b/dojox/dtl/filter/htmlstrings.js
@@ -1,45 +1,52 @@
-dojo.provide("dojox.dtl.filter.htmlstrings");
+define([
+	"dojo/_base/lang",
+	"../_base"
+], function(lang,dd){
+	/*=====
+		dd = dojox.dtl;
+	=====*/
+	lang.getObject("dojox.dtl.filter.htmlstrings", true);
 
-dojo.require("dojox.dtl._base");
+	lang.mixin(dd.filter.htmlstrings, {
+		_linebreaksrn: /(\r\n|\n\r)/g,
+		_linebreaksn: /\n{2,}/g,
+		_linebreakss: /(^\s+|\s+$)/g,
+		_linebreaksbr: /\n/g,
+		_removetagsfind: /[a-z0-9]+/g,
+		_striptags: /<[^>]*?>/g,
+		linebreaks: function(value){
+			// summary: Converts newlines into <p> and <br />s
+			var output = [];
+			var dh = dd.filter.htmlstrings;
+			value = value.replace(dh._linebreaksrn, "\n");
+			var parts = value.split(dh._linebreaksn);
+			for(var i = 0; i < parts.length; i++){
+				var part = parts[i].replace(dh._linebreakss, "").replace(dh._linebreaksbr, "<br />");
+				output.push("<p>" + part + "</p>");
+			}
 
-dojo.mixin(dojox.dtl.filter.htmlstrings, {
-	_linebreaksrn: /(\r\n|\n\r)/g,
-	_linebreaksn: /\n{2,}/g,
-	_linebreakss: /(^\s+|\s+$)/g,
-	_linebreaksbr: /\n/g,
-	_removetagsfind: /[a-z0-9]+/g,
-	_striptags: /<[^>]*?>/g,
-	linebreaks: function(value){
-		// summary: Converts newlines into <p> and <br />s
-		var output = [];
-		var dh = dojox.dtl.filter.htmlstrings;
-		value = value.replace(dh._linebreaksrn, "\n");
-		var parts = value.split(dh._linebreaksn);
-		for(var i = 0; i < parts.length; i++){
-			var part = parts[i].replace(dh._linebreakss, "").replace(dh._linebreaksbr, "<br />");
-			output.push("<p>" + part + "</p>");
+			return output.join("\n\n");
+		},
+		linebreaksbr: function(value){
+			// summary: Converts newlines into <br />s
+			var dh = dd.filter.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;
+			var tags = [];
+			var group;
+			while(group = dh._removetagsfind.exec(arg)){
+				tags.push(group[0]);
+			}
+			tags = "(" + tags.join("|") + ")";
+			return value.replace(new RegExp("</?\s*" + tags + "\s*[^>]*>", "gi"), "");
+		},
+		striptags: function(value){
+			// summary: Strips all [X]HTML tags
+			return value.replace(dojox.dtl.filter.htmlstrings._striptags, "");
 		}
-
-		return output.join("\n\n");
-	},
-	linebreaksbr: function(value){
-		// summary: Converts newlines into <br />s
-		var dh = dojox.dtl.filter.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 = dojox.dtl.filter.htmlstrings;
-		var tags = [];
-		var group;
-		while(group = dh._removetagsfind.exec(arg)){
-			tags.push(group[0]);
-		}
-		tags = "(" + tags.join("|") + ")";
-		return value.replace(new RegExp("</?\s*" + tags + "\s*[^>]*>", "gi"), "");
-	},
-	striptags: function(value){
-		// summary: Strips all [X]HTML tags
-		return value.replace(dojox.dtl.filter.htmlstrings._striptags, "");
-	}
+	});
+	return dojox.dtl.filter.htmlstrings;
 });
\ No newline at end of file
diff --git a/dojox/dtl/filter/integers.js b/dojox/dtl/filter/integers.js
index 890daa1..92a6265 100644
--- a/dojox/dtl/filter/integers.js
+++ b/dojox/dtl/filter/integers.js
@@ -1,28 +1,37 @@
-dojo.provide("dojox.dtl.filter.integers");
+define([
+	"dojo/_base/lang",
+	"../_base"
+], function(lang,dd){
+	/*=====
+		dd = dojox.dtl;
+	=====*/
+	lang.getObject("dojox.dtl.filter.integers", true);
 
-dojo.mixin(dojox.dtl.filter.integers, {
-	add: function(value, arg){
-		value = parseInt(value, 10);
-		arg = parseInt(arg, 10);
-		return isNaN(arg) ? value : value + arg;
-	},
-	get_digit: function(value, arg){
-		// summary:
-		//		Given a whole number, returns the 1-based requested digit of it
-		// desciprtion:
-		//		1 is the right-most digit, 2 is the second-right-most digit, etc. Returns the
-		//		original value for invalid input (if input or argument is not an integer,
-		//		or if argument is less than 1). Otherwise, output is always an integer.
-		value = parseInt(value, 10);
-		arg = parseInt(arg, 10) - 1;
-		if(arg >= 0){
-			value += "";
-			if(arg < value.length){
-				value = parseInt(value.charAt(arg), 10);
-			}else{
-				value = 0;
+	lang.mixin(dd.filter.integers, {
+		add: function(value, arg){
+			value = parseInt(value, 10);
+			arg = parseInt(arg, 10);
+			return isNaN(arg) ? value : value + arg;
+		},
+		get_digit: function(value, arg){
+			// summary:
+			//		Given a whole number, returns the 1-based requested digit of it
+			// desciprtion:
+			//		1 is the right-most digit, 2 is the second-right-most digit, etc. Returns the
+			//		original value for invalid input (if input or argument is not an integer,
+			//		or if argument is less than 1). Otherwise, output is always an integer.
+			value = parseInt(value, 10);
+			arg = parseInt(arg, 10) - 1;
+			if(arg >= 0){
+				value += "";
+				if(arg < value.length){
+					value = parseInt(value.charAt(arg), 10);
+				}else{
+					value = 0;
+				}
 			}
+			return (isNaN(value) ? 0 : value);
 		}
-		return (isNaN(value) ? 0 : value);
-	}
+	});
+	return dojox.dtl.filter.integers;
 });
\ No newline at end of file
diff --git a/dojox/dtl/filter/lists.js b/dojox/dtl/filter/lists.js
index c83a15b..a55b26e 100644
--- a/dojox/dtl/filter/lists.js
+++ b/dojox/dtl/filter/lists.js
@@ -1,137 +1,144 @@
-dojo.provide("dojox.dtl.filter.lists");
+define([
+	"dojo/_base/lang",
+	"../_base"
+], function(lang,dd){
+	/*=====
+		dd = dojox.dtl;
+	=====*/
+	lang.getObject("dojox.dtl.filter.lists", true);
 
-dojo.require("dojox.dtl._base");
-
-dojo.mixin(dojox.dtl.filter.lists, {
-	_dictsort: function(a, b){
-		if(a[0] == b[0]){
-			return 0;
-		}
-		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.
-		if(!arg){
-			return value;
-		}
+	lang.mixin(dd.filter.lists, {
+		_dictsort: function(a, b){
+			if(a[0] == b[0]){
+				return 0;
+			}
+			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.
+			if(!arg){
+				return value;
+			}
 
-		var i, item, items = [];
-		if(!dojo.isArray(value)){
-			var obj = value, value = [];
-			for(var key in obj){
-				value.push(obj[key]);
+			var i, item, items = [];
+			if(!lang.isArray(value)){
+				var obj = value, value = [];
+				for(var key in obj){
+					value.push(obj[key]);
+				}
 			}
-		}
-		for(i = 0; i < value.length; i++){
-			items.push([new dojox.dtl._Filter('var.' + arg).resolve(new dojox.dtl._Context({ 'var' : value[i]})), value[i]]);
-		}
-		items.sort(dojox.dtl.filter.lists._dictsort);
-		var output = [];
-		for(i = 0; item = items[i]; i++){
-			output.push(item[1]);
-		}
-		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.
-		if(!arg) return value;
+			for(i = 0; i < value.length; i++){
+				items.push([new dojox.dtl._Filter('var.' + arg).resolve(new dojox.dtl._Context({ 'var' : value[i]})), value[i]]);
+			}
+			items.sort(dojox.dtl.filter.lists._dictsort);
+			var output = [];
+			for(i = 0; item = items[i]; i++){
+				output.push(item[1]);
+			}
+			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.
+			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
-		return (value.length) ? value[0] : "";
-	},
-	join: function(value, arg){
-		// 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
-		//		as trivial here as an empty arg.
-		return value.join(arg || ",");
-	},
-	length: function(value){
-		// 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
-		return value.length == parseInt(arg);
-	},
-	random: function(value){
-		// 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.
-		// description:
-		//		Uses the same syntax as Python's list slicing; see
-		//		http://diveintopython.org/native_data_types/lists.html#odbchelper.list.slice
-		//		for an introduction.
-		//		Also uses the optional third value to denote every X item.
-		arg = arg || "";
-		var parts = arg.split(":");
-		var bits = [];
-		for(var i = 0; i < parts.length; i++){
-			if(!parts[i].length){
-				bits.push(null);
-			}else{
-				bits.push(parseInt(parts[i]));
+			var dictsort = dojox.dtl.filter.lists.dictsort(value, arg);
+			return dictsort.reverse();
+		},
+		first: function(value){
+			// 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)``
+			// 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
+			//		as trivial here as an empty arg.
+			return value.join(arg || ",");
+		},
+		length: function(value){
+			// 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
+			return value.length == parseInt(arg);
+		},
+		random: function(value){
+			// 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.
+			// description:
+			//		Uses the same syntax as Python's list slicing; see
+			//		http://diveintopython.org/native_data_types/lists.html#odbchelper.list.slice
+			//		for an introduction.
+			//		Also uses the optional third value to denote every X item.
+			arg = arg || "";
+			var parts = arg.split(":");
+			var bits = [];
+			for(var i = 0; i < parts.length; i++){
+				if(!parts[i].length){
+					bits.push(null);
+				}else{
+					bits.push(parseInt(parts[i]));
+				}
 			}
-		}
 
-		if(bits[0] === null){
-			bits[0] = 0;
-		}
-		if(bits[0] < 0){
-			bits[0] = value.length + bits[0];
-		}
-		if(bits.length < 2 || bits[1] === null){
-			bits[1] = value.length;
-		}
-		if(bits[1] < 0){
-			bits[1] = value.length + bits[1];
-		}
-		
-		return value.slice(bits[0], bits[1]);
-	},
-	_unordered_list: function(value, tabs){
-		var ddl = dojox.dtl.filter.lists;
-		var i, indent = "";
-		for(i = 0; i < tabs; i++){
-			indent += "\t";
-		}
-		if(value[1] && value[1].length){
-			var recurse = [];
-			for(i = 0; i < value[1].length; i++){
-				recurse.push(ddl._unordered_list(value[1][i], tabs + 1))
+			if(bits[0] === null){
+				bits[0] = 0;
+			}
+			if(bits[0] < 0){
+				bits[0] = value.length + bits[0];
+			}
+			if(bits.length < 2 || bits[1] === null){
+				bits[1] = value.length;
+			}
+			if(bits[1] < 0){
+				bits[1] = value.length + bits[1];
+			}
+			
+			return value.slice(bits[0], bits[1]);
+		},
+		_unordered_list: function(value, tabs){
+			var ddl = dojox.dtl.filter.lists;
+			var i, indent = "";
+			for(i = 0; i < tabs; i++){
+				indent += "\t";
+			}
+			if(value[1] && value[1].length){
+				var recurse = [];
+				for(i = 0; i < value[1].length; i++){
+					recurse.push(ddl._unordered_list(value[1][i], tabs + 1))
+				}
+				return indent + "<li>" + value[0] + "\n" + indent + "<ul>\n" + recurse.join("\n") + "\n" + indent + "</ul>\n" + indent + "</li>";
+			}else{
+				return indent + "<li>" + value[0] + "</li>";
 			}
-			return indent + "<li>" + value[0] + "\n" + indent + "<ul>\n" + recurse.join("\n") + "\n" + indent + "</ul>\n" + indent + "</li>";
-		}else{
-			return indent + "<li>" + value[0] + "</li>";
+		},
+		unordered_list: function(value){
+			// summary:
+			//		Recursively takes a self-nested list and returns an HTML unordered list --
+			//		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::
+			//
+			//		|	<li>States
+			//		|	<ul>
+			//		|		<li>Kansas
+			//		|		<ul>
+			//		|			<li>Lawrence</li>
+			//		|			<li>Topeka</li>
+			//		|		</ul>
+			//		|		</li>
+			//		|		<li>Illinois</li>
+			//		|	</ul>
+			//		|	</li>
+			return dojox.dtl.filter.lists._unordered_list(value, 1);
 		}
-	},
-	unordered_list: function(value){
-		// summary:
-		//		Recursively takes a self-nested list and returns an HTML unordered list --
-		//		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::
-		//
-		//		|	<li>States
-		//		|	<ul>
-		//		|		<li>Kansas
-		//		|		<ul>
-		//		|			<li>Lawrence</li>
-		//		|			<li>Topeka</li>
-		//		|		</ul>
-		//		|		</li>
-		//		|		<li>Illinois</li>
-		//		|	</ul>
-		//		|	</li>
-		return dojox.dtl.filter.lists._unordered_list(value, 1);
-	}
+	});
+	return dojox.dtl.filter.lists;
 });
\ No newline at end of file
diff --git a/dojox/dtl/filter/logic.js b/dojox/dtl/filter/logic.js
index 13bf9a9..94cf950 100644
--- a/dojox/dtl/filter/logic.js
+++ b/dojox/dtl/filter/logic.js
@@ -1,36 +1,45 @@
-dojo.provide("dojox.dtl.filter.logic");
+define([
+	"dojo/_base/lang",
+	"../_base"
+], function(lang,dd){
+	/*=====
+		dd = dojox.dtl;
+	=====*/
+	lang.getObject("dojox.dtl.filter.logic", true);
 
-dojo.mixin(dojox.dtl.filter.logic, {
-	default_: function(value, arg){
-		// 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
-		return (value === null) ? arg || "" : value || "";
-	},
-	divisibleby: function(value, arg){
-		// summary: Returns true if the value is devisible by the argument"
-		return (parseInt(value, 10) % parseInt(arg, 10)) === 0;
-	},
-	_yesno: /\s*,\s*/g,
-	yesno: function(value, arg){
-		// summary:
-		//		arg being a comma-delimited string, value of true/false/none
-		//		chooses the appropriate item from the string
-		if(!arg){
-			arg = 'yes,no,maybe';
+	lang.mixin(dd.filter.logic, {
+		default_: function(value, arg){
+			// 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
+			return (value === null) ? arg || "" : value || "";
+		},
+		divisibleby: function(value, arg){
+			// summary: Returns true if the value is devisible by the argument"
+			return (parseInt(value, 10) % parseInt(arg, 10)) === 0;
+		},
+		_yesno: /\s*,\s*/g,
+		yesno: function(value, arg){
+			// summary:
+			//		arg being a comma-delimited string, value of true/false/none
+			//		chooses the appropriate item from the string
+			if(!arg){
+				arg = 'yes,no,maybe';
+			}
+			var parts = arg.split(dojox.dtl.filter.logic._yesno);
+			if(parts.length < 2){
+				return value;
+			}
+			if(value){
+				return parts[0];
+			}
+			if((!value && value !== null) || parts.length < 3){
+				return parts[1];
+			}
+			return parts[2];
 		}
-		var parts = arg.split(dojox.dtl.filter.logic._yesno);
-		if(parts.length < 2){
-			return value;
-		}
-		if(value){
-			return parts[0];
-		}
-		if((!value && value !== null) || parts.length < 3){
-			return parts[1];
-		}
-		return parts[2];
-	}
+	});
+	return dojox.dtl.filter.logic;
 });
\ No newline at end of file
diff --git a/dojox/dtl/filter/misc.js b/dojox/dtl/filter/misc.js
index dccd526..3c8d0e7 100644
--- a/dojox/dtl/filter/misc.js
+++ b/dojox/dtl/filter/misc.js
@@ -1,55 +1,65 @@
-dojo.provide("dojox.dtl.filter.misc");
+define([
+	"dojo/_base/lang",
+	"dojo/_base/json",	// dojo.toJson
+	"../_base"
+], function(lang,json,dd){
+	/*=====
+		dd = dojox.dtl;
+	=====*/
+	lang.getObject("dojox.dtl.filter.misc", true);
 
-dojo.mixin(dojox.dtl.filter.misc, {
-	filesizeformat: function(value){
-		// 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";
-		}else if(value < 1024 * 1024){
-			return (value / 1024).toFixed(1) + " KB";
-		}else if(value < 1024 * 1024 * 1024){
-			return (value / 1024 / 1024).toFixed(1) + " MB";
-		}
-		return (value / 1024 / 1024 / 1024).toFixed(1) + " GB";
-	},
-	pluralize: function(value, arg){
-		// summary:
-		//		Returns a plural suffix if the value is not 1, for '1 vote' vs. '2 votes'
-		//	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.
-		arg = arg || 's';
-		if(arg.indexOf(",") == -1){
-			arg = "," + arg;
-		}
-		var parts = arg.split(",");
-		if(parts.length > 2){
-			return "";
-		}
-		var singular = parts[0];
-		var plural = parts[1];
+	lang.mixin(dd.filter.misc, {
+		filesizeformat: function(value){
+			// 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";
+			}else if(value < 1024 * 1024){
+				return (value / 1024).toFixed(1) + " KB";
+			}else if(value < 1024 * 1024 * 1024){
+				return (value / 1024 / 1024).toFixed(1) + " MB";
+			}
+			return (value / 1024 / 1024 / 1024).toFixed(1) + " GB";
+		},
+		pluralize: function(value, arg){
+			// summary:
+			//		Returns a plural suffix if the value is not 1, for '1 vote' vs. '2 votes'
+			//	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.
+			arg = arg || 's';
+			if(arg.indexOf(",") == -1){
+				arg = "," + arg;
+			}
+			var parts = arg.split(",");
+			if(parts.length > 2){
+				return "";
+			}
+			var singular = parts[0];
+			var plural = parts[1];
 
-		if(parseInt(value, 10) != 1){
-			return plural;
-		}
-		return singular;
-	},
-	_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
-		var dm = dojox.dtl.filter.misc;
-		value = value + "";
-		var output = "";
-		for(var i = 0; i < value.length; i++){
-			var chr = value.charAt(i).toLowerCase();
-			(dm._phone2numeric[chr]) ? output += dm._phone2numeric[chr] : output += value.charAt(i);
+			if(parseInt(value, 10) != 1){
+				return plural;
+			}
+			return singular;
+		},
+		_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
+			var dm = dd.filter.misc;
+			value = value + "";
+			var output = "";
+			for(var i = 0; i < value.length; i++){
+				var chr = value.charAt(i).toLowerCase();
+				(dm._phone2numeric[chr]) ? output += dm._phone2numeric[chr] : output += value.charAt(i);
+			}
+			return output;
+		},
+		pprint: function(value){
+			// summary: A wrapper around toJson unless something better comes along
+			return json.toJson(value);
 		}
-		return output;
-	},
-	pprint: function(value){
-		// summary: A wrapper around toJson unless something better comes along
-		return dojo.toJson(value);
-	}
-});
\ No newline at end of file
+	});
+	return dojox.dtl.filter.misc;
+});
diff --git a/dojox/dtl/filter/strings.js b/dojox/dtl/filter/strings.js
index 2de0179..205869c 100644
--- a/dojox/dtl/filter/strings.js
+++ b/dojox/dtl/filter/strings.js
@@ -1,325 +1,336 @@
-dojo.provide("dojox.dtl.filter.strings");
+define([
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojox/string/tokenize",
+	"dojox/string/sprintf",
+	"../filter/htmlstrings",
+	"../_base"
+], function(lang,array,Tokenize,Sprintf,htmlstrings,dd){
+	/*=====
+		dd = dojox.dtl;
+		Tokenize = dojox.string.tokenize;
+		Sprintf = dojox.string.sprintf;
+	=====*/
+	lang.getObject("dojox.dtl.filter.strings", true);
 
-dojo.require("dojox.dtl.filter.htmlstrings");
-dojo.require("dojox.string.sprintf");
-dojo.require("dojox.string.tokenize");
-
-dojo.mixin(dojox.dtl.filter.strings, {
-	_urlquote: function(/*String*/ url, /*String?*/ safe){
-		if(!safe){
-			safe = "/";
-		}
-		return dojox.string.tokenize(url, /([^\w-_.])/g, function(token){
-			if(safe.indexOf(token) == -1){
-				if(token == " "){
-					return "+";
-				}else{
-					return "%" + token.charCodeAt(0).toString(16).toUpperCase();
+	lang.mixin(dd.filter.strings, {
+		_urlquote: function(/*String*/ url, /*String?*/ safe){
+			if(!safe){
+				safe = "/";
+			}
+			return Tokenize(url, /([^\w-_.])/g, function(token){
+				if(safe.indexOf(token) == -1){
+					if(token == " "){
+						return "+";
+					}else{
+						return "%" + token.charCodeAt(0).toString(16).toUpperCase();
+					}
 				}
+				return token;
+			}).join("");
+		},
+		addslashes: function(value){
+			// 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
+			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
+			arg = arg || value.length;
+			value = value + "";
+			var diff = arg - value.length;
+			if(diff % 2){
+				value = value + " ";
+				diff -= 1;
 			}
-			return token;
-		}).join("");
-	},
-	addslashes: function(value){
-		// 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
-		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
-		arg = arg || value.length;
-		value = value + "";
-		var diff = arg - value.length;
-		if(diff % 2){
-			value = value + " ";
-			diff -= 1;
-		}
-		for(var i = 0; i < diff; i += 2){
-			value = " " + value + " ";
-		}
-		return value;
-	},
-	cut: function(value, arg){
-		// 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, "&");
-	},
-	floatformat: function(value, 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.
-		//		With a positive numeric argument, it displays that many decimal places
-		//		always.
-		//		With a negative numeric argument, it will display that many decimal
-		//		places -- but only if there's places to be displayed.
-		arg = parseInt(arg || -1, 10);
-		value = parseFloat(value);
-		var m = value - value.toFixed(0);
-		if(!m && arg < 0){
-			return value.toFixed();
-		}
-		value = value.toFixed(Math.abs(arg));
-		return (arg < 0) ? parseFloat(value) + "" : value;
-	},
-	iriencode: function(value){
-		return dojox.dtl.filter.strings._urlquote(value, "/#%[]=:;$&()+,!");
-	},
-	linenumbers: function(value){
-		// summary: Displays text with line numbers
-		var df = dojox.dtl.filter;
-		var lines = value.split("\n");
-		var output = [];
-		var width = (lines.length + "").length;
-		for(var i = 0, line; i < lines.length; i++){
-			line = lines[i];
-			output.push(df.strings.ljust(i + 1, width) + ". " + dojox.dtl._base.escape(line));
-		}
-		return output.join("\n");
-	},
-	ljust: function(value, arg){
-		value = value + "";
-		arg = parseInt(arg, 10);
-		while(value.length < arg){
-			value = value + " ";
-		}
-		return value;
-	},
-	lower: function(value){
-		// summary: Converts a string into all lowercase
-		return (value + "").toLowerCase();
-	},
-	make_list: function(value){
-		// summary:
-		//		Returns the value turned into a list. For an integer, it's a list of
-		//		digits. For a string, it's a list of characters.
-		var output = [];
-		if(typeof value == "number"){
+			for(var i = 0; i < diff; i += 2){
+				value = " " + value + " ";
+			}
+			return value;
+		},
+		cut: function(value, arg){
+			// summary: Removes all values of arg from the given string
+			arg = arg + "" || "";
 			value = value + "";
-		}
-		if(value.charAt){
-			for(var i = 0; i < value.length; i++){
-				output.push(value.charAt(i));
+			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, "&");
+		},
+		floatformat: function(value, 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.
+			//		With a positive numeric argument, it displays that many decimal places
+			//		always.
+			//		With a negative numeric argument, it will display that many decimal
+			//		places -- but only if there's places to be displayed.
+			arg = parseInt(arg || -1, 10);
+			value = parseFloat(value);
+			var m = value - value.toFixed(0);
+			if(!m && arg < 0){
+				return value.toFixed();
 			}
-			return output;
-		}
-		if(typeof value == "object"){
-			for(var key in value){
-				output.push(value[key]);
+			value = value.toFixed(Math.abs(arg));
+			return (arg < 0) ? parseFloat(value) + "" : value;
+		},
+		iriencode: function(value){
+			return dojox.dtl.filter.strings._urlquote(value, "/#%[]=:;$&()+,!");
+		},
+		linenumbers: function(value){
+			// summary: Displays text with line numbers
+			var df = dojox.dtl.filter;
+			var lines = value.split("\n");
+			var output = [];
+			var width = (lines.length + "").length;
+			for(var i = 0, line; i < lines.length; i++){
+				line = lines[i];
+				output.push(df.strings.ljust(i + 1, width) + ". " + dojox.dtl._base.escape(line));
 			}
-			return output;
-		}
-		return [];
-	},
-	rjust: function(value, arg){
-		value = value + "";
-		arg = parseInt(arg, 10);
-		while(value.length < arg){
-			value = " " + value;
-		}
-		return value;
-	},
-	slugify: function(value){
-		// 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, "-");
-	},
-	_strings: {},
-	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
-		//		the leading "%" is dropped.
-		arg = "" + arg;
-		var strings = dojox.dtl.filter.strings._strings;
-		if(!strings[arg]){
-			strings[arg] = new dojox.string.sprintf.Formatter("%" + arg);
-		}
-		return strings[arg].format(value);
-	},
-	title: function(value){
-		// summary: Converts a string into titlecase
-		var last, title = "";
-		for(var i = 0, current; i < value.length; i++){
-			current = value.charAt(i);
-			if(last == " " || last == "\n" || last == "\t" || !last){
-				title += current.toUpperCase();
-			}else{
-				title += current.toLowerCase();
+			return output.join("\n");
+		},
+		ljust: function(value, arg){
+			value = value + "";
+			arg = parseInt(arg, 10);
+			while(value.length < arg){
+				value = value + " ";
 			}
-			last = current;
-		}
-		return title;
-	},
-	_truncatewords: /[ \n\r\t]/,
-	truncatewords: function(value, arg){
-		// summary: Truncates a string after a certain number of words
-		// arg: Integer
-		//		Number of words to truncate after
-		arg = parseInt(arg, 10);
-		if(!arg){
 			return value;
-		}
+		},
+		lower: function(value){
+			// summary: Converts a string into all lowercase
+			return (value + "").toLowerCase();
+		},
+		make_list: function(value){
+			// summary:
+			//		Returns the value turned into a list. For an integer, it's a list of
+			//		digits. For a string, it's a list of characters.
+			var output = [];
+			if(typeof value == "number"){
+				value = value + "";
+			}
+			if(value.charAt){
+				for(var i = 0; i < value.length; i++){
+					output.push(value.charAt(i));
+				}
+				return output;
+			}
+			if(typeof value == "object"){
+				for(var key in value){
+					output.push(value[key]);
+				}
+				return output;
+			}
+			return [];
+		},
+		rjust: function(value, arg){
+			value = value + "";
+			arg = parseInt(arg, 10);
+			while(value.length < arg){
+				value = " " + value;
+			}
+			return value;
+		},
+		slugify: function(value){
+			// 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, "-");
+		},
+		_strings: {},
+		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
+			//		the leading "%" is dropped.
+			arg = "" + arg;
+			var strings = dojox.dtl.filter.strings._strings;
+			if(!strings[arg]){
+				strings[arg] = new Sprintf.Formatter("%" + arg);
+			}
+			return strings[arg].format(value);
+		},
+		title: function(value){
+			// summary: Converts a string into titlecase
+			var last, title = "";
+			for(var i = 0, current; i < value.length; i++){
+				current = value.charAt(i);
+				if(last == " " || last == "\n" || last == "\t" || !last){
+					title += current.toUpperCase();
+				}else{
+					title += current.toLowerCase();
+				}
+				last = current;
+			}
+			return title;
+		},
+		_truncatewords: /[ \n\r\t]/,
+		truncatewords: function(value, arg){
+			// summary: Truncates a string after a certain number of words
+			// arg: Integer
+			//		Number of words to truncate after
+			arg = parseInt(arg, 10);
+			if(!arg){
+				return value;
+			}
 
-		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)){
-					++count;
-					if(count == arg){
-						return value.substring(0, j + 1);
+			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)){
+						++count;
+						if(count == arg){
+							return value.substring(0, j + 1);
+						}
 					}
+				}else if(!dojox.dtl.filter.strings._truncatewords.test(current)){
+					j = i;
 				}
-			}else if(!dojox.dtl.filter.strings._truncatewords.test(current)){
-				j = i;
+				last = current;
 			}
-			last = current;
-		}
-		return value;
-	},
-	_truncate_words: /(&.*?;|<.*?>|(\w[\w\-]*))/g,
-	_truncate_tag: /<(\/)?([^ ]+?)(?: (\/)| .*?)?>/,
-	_truncate_singlets: { br: true, col: true, link: true, base: true, img: true, param: true, area: true, hr: true, input: true },
-	truncatewords_html: function(value, arg){
-		arg = parseInt(arg, 10);
+			return value;
+		},
+		_truncate_words: /(&.*?;|<.*?>|(\w[\w\-]*))/g,
+		_truncate_tag: /<(\/)?([^ ]+?)(?: (\/)| .*?)?>/,
+		_truncate_singlets: { br: true, col: true, link: true, base: true, img: true, param: true, area: true, hr: true, input: true },
+		truncatewords_html: function(value, arg){
+			arg = parseInt(arg, 10);
 
-		if(arg <= 0){
-			return "";
-		}
+			if(arg <= 0){
+				return "";
+			}
 
-		var strings = dojox.dtl.filter.strings;
-		var words = 0;
-		var open = [];
+			var strings = dojox.dtl.filter.strings;
+			var words = 0;
+			var open = [];
 
-		var output = dojox.string.tokenize(value, strings._truncate_words, function(all, word){
-			if(word){
-				// It's an actual non-HTML word
-				++words;
-				if(words < arg){
-					return word;
-				}else if(words == arg){
-					return word + " ...";
+			var output = Tokenize(value, strings._truncate_words, function(all, word){
+				if(word){
+					// It's an actual non-HTML word
+					++words;
+					if(words < arg){
+						return word;
+					}else if(words == arg){
+						return word + " ...";
+					}
 				}
-			}
-			// Check for tag
-			var tag = all.match(strings._truncate_tag);
-			if(!tag || words >= arg){
-				// Don't worry about non tags or tags after our truncate point
-				return;
-			}
-			var closing = tag[1];
-			var tagname = tag[2].toLowerCase();
-			var selfclosing = tag[3];
-			if(closing || strings._truncate_singlets[tagname]){
-			}else if(closing){
-				var i = dojo.indexOf(open, tagname);
-				if(i != -1){
-					open = open.slice(i + 1);
+				// Check for tag
+				var tag = all.match(strings._truncate_tag);
+				if(!tag || words >= arg){
+					// Don't worry about non tags or tags after our truncate point
+					return;
 				}
-			}else{
-				open.unshift(tagname);
-			}
-			return all;
-		}).join("");
-
-		output = output.replace(/\s+$/g, "");
+				var closing = tag[1];
+				var tagname = tag[2].toLowerCase();
+				var selfclosing = tag[3];
+				if(closing || strings._truncate_singlets[tagname]){
+				}else if(closing){
+					var i = array.indexOf(open, tagname);
+					if(i != -1){
+						open = open.slice(i + 1);
+					}
+				}else{
+					open.unshift(tagname);
+				}
+				return all;
+			}).join("");
 
-		for(var i = 0, tag; tag = open[i]; i++){
-			output += "</" + tag + ">";
-		}
+			output = output.replace(/\s+$/g, "");
 
-		return output;
-	},
-	upper: function(value){
-		return value.toUpperCase();
-	},
-	urlencode: function(value){
-		return dojox.dtl.filter.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);
-	},
-	urlizetrunc: function(value, arg){
-		arg = parseInt(arg);
-		return dojox.string.tokenize(value, /(\S+)/g, function(word){
-			var matches = dojox.dtl.filter.strings._urlize.exec(word);
-			if(!matches){
-				return word;
+			for(var i = 0, tag; tag = open[i]; i++){
+				output += "</" + tag + ">";
 			}
-			var lead = matches[1];
-			var middle = matches[2];
-			var trail = matches[3];
 
-			var startsWww = middle.indexOf("www.") == 0;
-			var hasAt = middle.indexOf("@") != -1;
-			var hasColon = middle.indexOf(":") != -1;
-			var startsHttp = middle.indexOf("http://") == 0;
-			var startsHttps = middle.indexOf("https://") == 0;
-			var firstAlpha = /[a-zA-Z0-9]/.test(middle.charAt(0));
-			var last4 = middle.substring(middle.length - 4);
+			return output;
+		},
+		upper: function(value){
+			return value.toUpperCase();
+		},
+		urlencode: function(value){
+			return dojox.dtl.filter.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);
+		},
+		urlizetrunc: function(value, arg){
+			arg = parseInt(arg);
+			return Tokenize(value, /(\S+)/g, function(word){
+				var matches = dojox.dtl.filter.strings._urlize.exec(word);
+				if(!matches){
+					return word;
+				}
+				var lead = matches[1];
+				var middle = matches[2];
+				var trail = matches[3];
 
-			var trimmed = middle;
-			if(arg > 3){
-				trimmed = trimmed.substring(0, arg - 3) + "...";
-			}
+				var startsWww = middle.indexOf("www.") == 0;
+				var hasAt = middle.indexOf("@") != -1;
+				var hasColon = middle.indexOf(":") != -1;
+				var startsHttp = middle.indexOf("http://") == 0;
+				var startsHttps = middle.indexOf("https://") == 0;
+				var firstAlpha = /[a-zA-Z0-9]/.test(middle.charAt(0));
+				var last4 = middle.substring(middle.length - 4);
 
-			if(startsWww || (!hasAt && !startsHttp && middle.length && firstAlpha && (last4 == ".org" || last4 == ".net" || last4 == ".com"))){
-				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)){
-				return '<a href="mailto:' + middle + '">' + middle + '</a>';
-			}
-			return word;
-		}).join("");
-	},
-	wordcount: function(value){
-		value = dojo.trim(value);
-		if(!value){ return 0; }
-		return value.split(/\s+/g).length;
-	},
-	wordwrap: function(value, arg){
-		arg = parseInt(arg);
-		// summary: Wraps words at specified line length
-		var output = [];
-		var parts = value.split(/\s+/g);
-		if(parts.length){
-			var word = parts.shift();
-			output.push(word);
-			var pos = word.length - word.lastIndexOf("\n") - 1;
-			for(var i = 0; i < parts.length; i++){
-				word = parts[i];
-				if(word.indexOf("\n") != -1){
-					var lines = word.split(/\n/g);
-				}else{
-					var lines = [word];
+				var trimmed = middle;
+				if(arg > 3){
+					trimmed = trimmed.substring(0, arg - 3) + "...";
 				}
-				pos += lines[0].length + 1;
-				if(arg && pos > arg){
-					output.push("\n");
-					pos = lines[lines.length - 1].length;
-				}else{
-					output.push(" ");
-					if(lines.length > 1){
+
+				if(startsWww || (!hasAt && !startsHttp && middle.length && firstAlpha && (last4 == ".org" || last4 == ".net" || last4 == ".com"))){
+					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)){
+					return '<a href="mailto:' + middle + '">' + middle + '</a>';
+				}
+				return word;
+			}).join("");
+		},
+		wordcount: function(value){
+			value = lang.trim(value);
+			if(!value){ return 0; }
+			return value.split(/\s+/g).length;
+		},
+		wordwrap: function(value, arg){
+			arg = parseInt(arg);
+			// summary: Wraps words at specified line length
+			var output = [];
+			var parts = value.split(/\s+/g);
+			if(parts.length){
+				var word = parts.shift();
+				output.push(word);
+				var pos = word.length - word.lastIndexOf("\n") - 1;
+				for(var i = 0; i < parts.length; i++){
+					word = parts[i];
+					if(word.indexOf("\n") != -1){
+						var lines = word.split(/\n/g);
+					}else{
+						var lines = [word];
+					}
+					pos += lines[0].length + 1;
+					if(arg && pos > arg){
+						output.push("\n");
 						pos = lines[lines.length - 1].length;
+					}else{
+						output.push(" ");
+						if(lines.length > 1){
+							pos = lines[lines.length - 1].length;
+						}
 					}
+					output.push(word);
 				}
-				output.push(word);
 			}
+			return output.join("");
 		}
-		return output.join("");
-	}
+	});
+	return dojox.dtl.filter.strings;
 });
\ No newline at end of file
diff --git a/dojox/dtl/html.js b/dojox/dtl/html.js
deleted file mode 100755
index 2d6ad04..0000000
--- a/dojox/dtl/html.js
+++ /dev/null
@@ -1,4 +0,0 @@
-dojo.provide("dojox.dtl.html");
-dojo.deprecated("dojox.dtl.html", "All packages and classes in dojox.dtl that start with Html or html have been renamed to Dom or dom");
-dojo.require("dojox.dtl.dom");
-dojox.dtl.HtmlTemplate = dojox.dtl.DomTemplate;
\ No newline at end of file
diff --git a/dojox/dtl/render/dom.js b/dojox/dtl/render/dom.js
index fb9138a..583d884 100644
--- a/dojox/dtl/render/dom.js
+++ b/dojox/dtl/render/dom.js
@@ -1,33 +1,42 @@
-dojo.provide("dojox.dtl.render.dom");
+define([
+	"dojo/_base/lang",
+	"dojo/dom",
+	"../Context",
+	"../dom",
+	"../_base"
+], function(lang,dom,ddc,dddom,dd){
+	/*=====
+		dd = dojox.dtl;
+	=====*/
+	lang.getObject("dojox.dtl.render.dom", true);
 
-dojo.require("dojox.dtl.Context");
-dojo.require("dojox.dtl.dom");
+	dd.render.dom.Render = function(/*DOMNode?*/ attachPoint, /*dojox.dtl.DomTemplate?*/ tpl){
+		this._tpl = tpl;
+		this.domNode = dom.byId(attachPoint);
+	}
+	lang.extend(dd.render.dom.Render, {
+		setAttachPoint: function(/*Node*/ node){
+			this.domNode = node;
+		},
+		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");
+			}
 
-dojox.dtl.render.dom.Render = function(/*DOMNode?*/ attachPoint, /*dojox.dtl.DomTemplate?*/ tpl){
-	this._tpl = tpl;
-	this.domNode = dojo.byId(attachPoint);
-}
-dojo.extend(dojox.dtl.render.dom.Render, {
-	setAttachPoint: function(/*Node*/ node){
-		this.domNode = node;
-	},
-	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");
-		}
+			this._tpl = tpl = tpl || this._tpl;
+			buffer = buffer || tpl.getBuffer();
+			context = context || new ddc();
 
-		this._tpl = tpl = tpl || this._tpl;
-		buffer = buffer || tpl.getBuffer();
-		context = context || new dojox.dtl.Context();
+			var frag = tpl.render(context, buffer).getParent();
+			if(!frag){
+				throw new Error("Rendered template does not have a root node");
+			}
 
-		var frag = tpl.render(context, buffer).getParent();
-		if(!frag){
-			throw new Error("Rendered template does not have a root node");
+			if(this.domNode !== frag){
+				this.domNode.parentNode.replaceChild(frag, this.domNode);
+				this.domNode = frag;
+			}
 		}
-
-		if(this.domNode !== frag){
-			this.domNode.parentNode.replaceChild(frag, this.domNode);
-			this.domNode = frag;
-		}
-	}
+	});
+	return dojox.dtl.render.dom;
 });
\ No newline at end of file
diff --git a/dojox/dtl/render/html.js b/dojox/dtl/render/html.js
index e14f82a..55963f4 100644
--- a/dojox/dtl/render/html.js
+++ b/dojox/dtl/render/html.js
@@ -1,3 +1,13 @@
-dojo.provide("dojox.dtl.render.html");
-dojo.require("dojox.dtl.render.dom");
-dojox.dtl.render.html.Render = dojox.dtl.render.dom.Render;
\ No newline at end of file
+define([
+	"dojo/_base/lang",
+	"../render/dom",
+	"../_base"
+], function(lang,ddrd,dd){
+	/*=====
+		dd = dojox.dtl;
+	=====*/ 
+	lang.getObject("dojox.dtl.render.html", true);
+
+	dd.render.html.Render = ddrd.Render;
+	return dojox.dtl.render.html;
+});
diff --git a/dojox/dtl/tag/date.js b/dojox/dtl/tag/date.js
index 49aaa8e..f41ed8a 100644
--- a/dojox/dtl/tag/date.js
+++ b/dojox/dtl/tag/date.js
@@ -1,31 +1,38 @@
-dojo.provide("dojox.dtl.tag.date");
+define([
+	"dojo/_base/lang",
+	"../_base",
+	"../utils/date"
+], function(lang,dd,ddud){
+	/*=====
+		dd = dojox.dtl;
+	=====*/
+	lang.getObject("dojox.dtl.tag.date", true);
 
-dojo.require("dojox.dtl._base");
-dojo.require("dojox.dtl.utils.date");
-
-dojox.dtl.tag.date.NowNode = function(format, node){
-	this._format = format;
-	this.format = new dojox.dtl.utils.date.DateFormat(format);
-	this.contents = node;
-}
-dojo.extend(dojox.dtl.tag.date.NowNode, {
-	render: function(context, buffer){
-		this.contents.set(this.format.format(new Date()));
-		return this.contents.render(context, buffer);
-	},
-	unrender: function(context, buffer){
-		return this.contents.unrender(context, buffer);
-	},
-	clone: function(buffer){
-		return new this.constructor(this._format, this.contents.clone(buffer));
+	dojox.dtl.tag.date.NowNode = function(format, node){
+		this._format = format;
+		this.format = new ddud.DateFormat(format);
+		this.contents = node;
 	}
-});
+	lang.extend(dd.tag.date.NowNode, {
+		render: function(context, buffer){
+			this.contents.set(this.format.format(new Date()));
+			return this.contents.render(context, buffer);
+		},
+		unrender: function(context, buffer){
+			return this.contents.unrender(context, buffer);
+		},
+		clone: function(buffer){
+			return new this.constructor(this._format, this.contents.clone(buffer));
+		}
+	});
 
-dojox.dtl.tag.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());
-}
\ No newline at end of file
+	dojox.dtl.tag.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 dojox.dtl.tag.date;
+});
diff --git a/dojox/dtl/tag/loader.js b/dojox/dtl/tag/loader.js
index 049be42..4d16aee 100644
--- a/dojox/dtl/tag/loader.js
+++ b/dojox/dtl/tag/loader.js
@@ -1,12 +1,17 @@
-dojo.provide("dojox.dtl.tag.loader");
+define([
+	"dojo/_base/lang",
+	"../_base",
+	"dojo/_base/array",
+	"dojo/_base/connect"
+], function(lang,dd,array,connect){
+	/*=====
+		dd = dojox.dtl;
+	=====*/
+	lang.getObject("dojox.dtl.tag.loader", true);
 
-dojo.require("dojox.dtl._base");
-
-(function(){
-	var dd = dojox.dtl;
 	var ddtl = dd.tag.loader;
 
-	ddtl.BlockNode = dojo.extend(function(name, nodelist){
+	ddtl.BlockNode = lang.extend(function(name, nodelist){
 		this.name = name;
 		this.nodelist = nodelist; // Can be overridden
 	},
@@ -47,14 +52,14 @@ dojo.require("dojox.dtl._base");
 
 			if(buffer.getParent){
 				var bufferParent = buffer.getParent();
-				var setParent = dojo.connect(buffer, "onSetParent", function(node, up, root){
+				var setParent = connect.connect(buffer, "onSetParent", function(node, up, root){
 					if(up && root){
 						buffer.setParent(bufferParent);
 					}
 				});
 			}
 			buffer = nodelist.render(context, buffer, this);
-			setParent && dojo.disconnect(setParent);
+			setParent && connect.disconnect(setParent);
 			context = context.pop();
 			return buffer;
 		},
@@ -67,7 +72,7 @@ dojo.require("dojox.dtl._base");
 		toString: function(){ return "dojox.dtl.tag.loader.BlockNode"; }
 	});
 
-	ddtl.ExtendsNode = dojo.extend(function(getTemplate, nodelist, shared, parent, key){
+	ddtl.ExtendsNode = lang.extend(function(getTemplate, nodelist, shared, parent, key){
 		this.getTemplate = getTemplate;
 		this.nodelist = nodelist;
 		this.shared = shared;
@@ -149,7 +154,7 @@ dojo.require("dojox.dtl._base");
 		toString: function(){ return "dojox.dtl.block.ExtendsNode"; }
 	});
 
-	ddtl.IncludeNode = dojo.extend(function(path, constant, getTemplate, text, parsed){
+	ddtl.IncludeNode = lang.extend(function(path, constant, getTemplate, text, parsed){
 		this._path = path;
 		this.constant = constant;
 		this.path = (constant) ? path : new dd._Filter(path);
@@ -231,7 +236,7 @@ dojo.require("dojox.dtl._base");
 		}
 	});
 
-	dojo.mixin(ddtl, {
+	lang.mixin(ddtl, {
 		block: function(parser, token){
 			var parts = token.contents.split();
 			var name = parts[1];
@@ -294,4 +299,5 @@ dojo.require("dojox.dtl._base");
 			return node;
 		}
 	});
-})();
\ No newline at end of file
+	return dojox.dtl.tag.loader;
+});
\ No newline at end of file
diff --git a/dojox/dtl/tag/logic.js b/dojox/dtl/tag/logic.js
index 6f77f27..b085f57 100644
--- a/dojox/dtl/tag/logic.js
+++ b/dojox/dtl/tag/logic.js
@@ -1,13 +1,16 @@
-dojo.provide("dojox.dtl.tag.logic");
+define([
+	"dojo/_base/lang",
+	"../_base"
+], function(lang, dd){
+	/*=====
+		dd = dojox.dtl;
+	=====*/
+	lang.getObject("dojox.dtl.tag.logic", true);
 
-dojo.require("dojox.dtl._base");
-
-(function(){
-	var dd = dojox.dtl;
 	var ddt = dd.text;
 	var ddtl = dd.tag.logic;
 
-	ddtl.IfNode = dojo.extend(function(bools, trues, falses, type){
+	ddtl.IfNode = lang.extend(function(bools, trues, falses, type){
 		this.bools = bools;
 		this.trues = trues;
 		this.falses = falses;
@@ -64,7 +67,7 @@ dojo.require("dojox.dtl._base");
 		}
 	});
 
-	ddtl.IfEqualNode = dojo.extend(function(var1, var2, trues, falses, negate){
+	ddtl.IfEqualNode = lang.extend(function(var1, var2, trues, falses, negate){
 		this.var1 = new dd._Filter(var1);
 		this.var2 = new dd._Filter(var2);
 		this.trues = trues;
@@ -98,7 +101,7 @@ dojo.require("dojox.dtl._base");
 		}
 	});
 
-	ddtl.ForNode = dojo.extend(function(assign, loop, reversed, nodelist){
+	ddtl.ForNode = lang.extend(function(assign, loop, reversed, nodelist){
 		this.assign = assign;
 		this.loop = new dd._Filter(loop);
 		this.reversed = reversed;
@@ -131,7 +134,7 @@ dojo.require("dojox.dtl._base");
 				items = items.slice(0).reverse();
 			}
 
-			var isObject = dojo.isObject(items) && !dojo.isArrayLike(items);
+			var isObject = lang.isObject(items) && !lang.isArrayLike(items);
 			var arred = [];
 			if(isObject){
 				for(var key in items){
@@ -155,7 +158,7 @@ dojo.require("dojox.dtl._base");
 				forloop.first = !j;
 				forloop.last = (j == arred.length - 1);
 
-				if(assign.length > 1 && dojo.isArrayLike(item)){
+				if(assign.length > 1 && lang.isArrayLike(item)){
 					if(!dirty){
 						dirty = true;
 						context = context.push();
@@ -164,7 +167,7 @@ dojo.require("dojox.dtl._base");
 					for(k = 0; k < item.length && k < assign.length; k++){
 						zipped[assign[k]] = item[k];
 					}
-					dojo.mixin(context, zipped);
+					lang.mixin(context, zipped);
 				}else{
 					context[assign[0]] = item;
 				}
@@ -196,7 +199,7 @@ dojo.require("dojox.dtl._base");
 		}
 	});
 
-	dojo.mixin(ddtl, {
+	lang.mixin(ddtl, {
 		if_: function(parser, token){
 			var i, part, type, bools = [], parts = token.contents.split();
 			parts.shift();
@@ -273,4 +276,5 @@ dojo.require("dojox.dtl._base");
 			return new ddtl.ForNode(loopvars, parts[parts.length + index + 1], reversed, nodelist);
 		}
 	});
-})();
+	return dojox.dtl.tag.logic;
+});
\ No newline at end of file
diff --git a/dojox/dtl/tag/loop.js b/dojox/dtl/tag/loop.js
index da44132..717df7a 100644
--- a/dojox/dtl/tag/loop.js
+++ b/dojox/dtl/tag/loop.js
@@ -1,13 +1,19 @@
-dojo.provide("dojox.dtl.tag.loop");
+define([
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/json",
+	"../_base",
+	"dojox/string/tokenize"
+], function(lang,array,json,dd,Tokenize){
+	/*=====
+		Tokenize = dojox.string.tokenize;
+		dd = dojox.dtl;
+	=====*/
+	lang.getObject("dojox.dtl.tag.loop", true);
 
-dojo.require("dojox.dtl._base");
-dojo.require("dojox.string.tokenize");
-
-(function(){
-	var dd = dojox.dtl;
 	var ddtl = dd.tag.loop;
 
-	ddtl.CycleNode = dojo.extend(function(cyclevars, name, text, shared){
+	ddtl.CycleNode = lang.extend(function(cyclevars, name, text, shared){
 		this.cyclevars = cyclevars;
 		this.name = name;
 		this.contents = text;
@@ -42,11 +48,11 @@ dojo.require("dojox.string.tokenize");
 		}
 	});
 
-	ddtl.IfChangedNode = dojo.extend(function(nodes, vars, shared){
+	ddtl.IfChangedNode = lang.extend(function(nodes, vars, shared){
 		this.nodes = nodes;
 		this._vars = vars;
 		this.shared = shared || {last: null, counter: 0};
-		this.vars = dojo.map(vars, function(item){
+		this.vars = array.map(vars, function(item){
 			return new dojox.dtl._Filter(item);
 		});
 	}, {
@@ -60,7 +66,7 @@ dojo.require("dojox.string.tokenize");
 
 			var change;
 			if(this.vars.length){
-				change = dojo.toJson(dojo.map(this.vars, function(item){
+				change = json.toJson(array.map(this.vars, function(item){
 					return item.resolve(context);
 				}));
 			}else{
@@ -87,7 +93,7 @@ dojo.require("dojox.string.tokenize");
 		}
 	});
 
-	ddtl.RegroupNode = dojo.extend(function(expression, key, alias){
+	ddtl.RegroupNode = lang.extend(function(expression, key, alias){
 		this._expression = expression;
 		this.expression = new dd._Filter(expression);
 		this.key = key;
@@ -127,7 +133,7 @@ dojo.require("dojox.string.tokenize");
 		}
 	});
 
-	dojo.mixin(ddtl, {
+	lang.mixin(ddtl, {
 		cycle: function(parser, token){
 			// summary: Cycle among the given strings each time this tag is encountered
 			var args = token.split_contents();
@@ -154,7 +160,7 @@ dojo.require("dojox.string.tokenize");
 					throw new Error("Named cycle '" + name + "' does not exist");
 				}
 
-		        return parser._namedCycleNodes[name];
+				return parser._namedCycleNodes[name];
 			}
 
 			if(args.length > 4 && args[args.length - 2] == "as"){
@@ -179,7 +185,7 @@ dojo.require("dojox.string.tokenize");
 			return new ddtl.IfChangedNode(nodes, parts.slice(1));
 		},
 		regroup: function(parser, token){
-			var tokens = dojox.string.tokenize(token.contents, /(\s+)/g, function(spaces){
+			var tokens = Tokenize(token.contents, /(\s+)/g, function(spaces){
 				return spaces;
 			});
 			if(tokens.length < 11 || tokens[tokens.length - 3] != "as" || tokens[tokens.length - 7] != "by"){
@@ -191,4 +197,5 @@ dojo.require("dojox.string.tokenize");
 			return new ddtl.RegroupNode(expression, key, alias);
 		}
 	});
-})();
+	return dojox.dtl.tag.loop;
+});
\ No newline at end of file
diff --git a/dojox/dtl/tag/misc.js b/dojox/dtl/tag/misc.js
index ea8dd5e..9b4c8b8 100644
--- a/dojox/dtl/tag/misc.js
+++ b/dojox/dtl/tag/misc.js
@@ -1,11 +1,17 @@
-dojo.provide("dojox.dtl.tag.misc");
-dojo.require("dojox.dtl._base");
+define([
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"../_base"
+], function(lang,array,connect,dd){
+	/*=====
+		dd = dojox.dtl;
+	=====*/
+	lang.getObject("dojox.dtl.tag.misc", true);
 
-(function(){
-	var dd = dojox.dtl;
 	var ddtm = dd.tag.misc;
 
-	ddtm.DebugNode = dojo.extend(function(text){
+	ddtm.DebugNode = lang.extend(function(text){
 		this.text = text;
 	},
 	{
@@ -29,7 +35,7 @@ dojo.require("dojox.dtl._base");
 		toString: function(){ return "ddtm.DebugNode"; }
 	});
 
-	ddtm.FilterNode = dojo.extend(function(varnode, nodelist){
+	ddtm.FilterNode = lang.extend(function(varnode, nodelist){
 		this._varnode = varnode;
 		this._nodelist = nodelist;
 	},
@@ -50,9 +56,9 @@ dojo.require("dojox.dtl._base");
 		}
 	});
 
-	ddtm.FirstOfNode = dojo.extend(function(vars, text){
+	ddtm.FirstOfNode = lang.extend(function(vars, text){
 		this._vars = vars;
-		this.vars = dojo.map(vars, function(item){
+		this.vars = array.map(vars, function(item){
 			return new dojox.dtl._Filter(item);
 		});
 		this.contents = text;
@@ -79,7 +85,7 @@ dojo.require("dojox.dtl._base");
 		}
 	});
 
-	ddtm.SpacelessNode = dojo.extend(function(nodelist, text){
+	ddtm.SpacelessNode = lang.extend(function(nodelist, text){
 		this.nodelist = nodelist;
 		this.contents = text;
 	},
@@ -88,12 +94,12 @@ dojo.require("dojox.dtl._base");
 			if(buffer.getParent){
 				// Unfortunately, we have to branch here
 				var watch = [
-					dojo.connect(buffer, "onAddNodeComplete", this, "_watch"),
-					dojo.connect(buffer, "onSetParent", this, "_watchParent")
+					connect.connect(buffer, "onAddNodeComplete", this, "_watch"),
+					connect.connect(buffer, "onSetParent", this, "_watchParent")
 				];
 				buffer = this.nodelist.render(context, buffer);
-				dojo.disconnect(watch[0]);
-				dojo.disconnect(watch[1]);
+				connect.disconnect(watch[0]);
+				connect.disconnect(watch[1]);
 			}else{
 				var value = this.nodelist.dummyRender(context);
 				this.contents.set(value.replace(/>\s+</g, '><'));
@@ -142,7 +148,7 @@ dojo.require("dojox.dtl._base");
 		}
 	});
 
-	ddtm.TemplateTagNode = dojo.extend(function(tag, text){
+	ddtm.TemplateTagNode = lang.extend(function(tag, text){
 		this.tag = tag;
 		this.contents = text;
 	},
@@ -169,7 +175,7 @@ dojo.require("dojox.dtl._base");
 		}
 	});
 
-	ddtm.WidthRatioNode = dojo.extend(function(current, max, width, text){
+	ddtm.WidthRatioNode = lang.extend(function(current, max, width, text){
 		this.current = new dd._Filter(current);
 		this.max = new dd._Filter(max);
 		this.width = width;
@@ -194,7 +200,7 @@ dojo.require("dojox.dtl._base");
 		}
 	});
 
-	ddtm.WithNode = dojo.extend(function(target, alias, nodelist){
+	ddtm.WithNode = lang.extend(function(target, alias, nodelist){
 		this.target = new dd._Filter(target);
 		this.alias = alias;
 		this.nodelist = nodelist;
@@ -216,7 +222,7 @@ dojo.require("dojox.dtl._base");
 		}
 	});
 
-	dojo.mixin(ddtm, {
+	lang.mixin(ddtm, {
 		comment: function(parser, token){
 			// summary: Ignore everything between {% comment %} and {% endcomment %}
 			parser.skip_past("endcomment");
@@ -283,4 +289,5 @@ dojo.require("dojox.dtl._base");
 			return new ddtm.WithNode(parts[1], parts[3], nodelist);
 		}
 	});
-})();
\ No newline at end of file
+	return dojox.dtl.tag.misc;
+});
\ No newline at end of file
diff --git a/dojox/dtl/tests/dom/tag.js b/dojox/dtl/tests/dom/tag.js
index c3f0cc3..2b915a8 100644
--- a/dojox/dtl/tests/dom/tag.js
+++ b/dojox/dtl/tests/dom/tag.js
@@ -3,6 +3,7 @@ dojo.provide("dojox.dtl.tests.dom.tag");
 dojo.require("dojox.dtl.dom");
 dojo.require("dojox.dtl.Context");
 dojo.require("dojox.dtl.tests.dom.util");
+dojo.require("dojo._base.sniff");
 
 doh.register("dojox.dtl.dom.tag",
 	[
diff --git a/dojox/dtl/utils/date.js b/dojox/dtl/utils/date.js
index 8cd04ed..6046185 100644
--- a/dojox/dtl/utils/date.js
+++ b/dojox/dtl/utils/date.js
@@ -1,72 +1,79 @@
-dojo.provide("dojox.dtl.utils.date");
+define([
+	"dojo/_base/lang",
+	"dojox/date/php",
+	"../_base"
+], function(lang,ddp,dd){
+	/*=====
+		ddp = dojox.data.php;
+		dd = dojox.dtl;
+	=====*/
+	lang.getObject("dojox.dtl.utils.date", true);
 
-dojo.require("dojox.date.php");
-
-dojox.dtl.utils.date.DateFormat = function(/*String*/ format){
-	dojox.date.php.DateFormat.call(this, format);
-}
-dojo.extend(dojox.dtl.utils.date.DateFormat, dojox.date.php.DateFormat.prototype, {
-	f: function(){
-		// summary:
-		//		Time, in 12-hour hours and minutes, with minutes left off if they're zero.
-		// description:
-		//		Examples: '1', '1:30', '2:05', '2'
-		//		Proprietary extension.
-		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()];
-	},
-	P: function(){
-		// summary:
-		//		Time, in 12-hour hours, minutes and 'a.m.'/'p.m.', with minutes left off
-		//		if they're zero and the strings 'midnight' and 'noon' if appropriate.
-		// description:
-		//		Examples: '1 a.m.', '1:30 p.m.', 'midnight', 'noon', '12:30 p.m.'
-		//		Proprietary extension.
-		if(!this.date.getMinutes() && !this.date.getHours()){
-			return 'midnight';
-		}
-		if(!this.date.getMinutes() && this.date.getHours() == 12){
-			return 'noon';
+	dd.utils.date.DateFormat = ddp.DateFormat;
+	lang.extend(dd.utils.date.DateFormat, ddp.DateFormat.prototype, {
+		f: function(){
+			// summary:
+			//		Time, in 12-hour hours and minutes, with minutes left off if they're zero.
+			// description:
+			//		Examples: '1', '1:30', '2:05', '2'
+			//		Proprietary extension.
+			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()];
+		},
+		P: function(){
+			// summary:
+			//		Time, in 12-hour hours, minutes and 'a.m.'/'p.m.', with minutes left off
+			//		if they're zero and the strings 'midnight' and 'noon' if appropriate.
+			// description:
+			//		Examples: '1 a.m.', '1:30 p.m.', 'midnight', 'noon', '12:30 p.m.'
+			//		Proprietary extension.
+			if(!this.date.getMinutes() && !this.date.getHours()){
+				return 'midnight';
+			}
+			if(!this.date.getMinutes() && this.date.getHours() == 12){
+				return 'noon';
+			}
+			return this.f() + " " + this.a();
 		}
-		return this.f() + " " + this.a();
-	}
-});
+	});
 
-dojo.mixin(dojox.dtl.utils.date, {
-	format: function(/*Date*/ date, /*String*/ format){
-		var df = new dojox.dtl.utils.date.DateFormat(format);
-		return df.format(date);
-	},
-	timesince: function(d, now){
-		// summary:
-		//		Takes two datetime objects and returns the time between then and now
-		//		as a nicely formatted string, e.g "10 minutes"
-		// description:
-		//		Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since
-		if(!(d instanceof Date)){
-			d = new Date(d.year, d.month, d.day);
-		}
-		if(!now){
-			now = new Date();
-		}
+	lang.mixin(dojox.dtl.utils.date, {
+		format: function(/*Date*/ date, /*String*/ format){
+			var df = new dojox.dtl.utils.date.DateFormat(format);
+			return df.format(date);
+		},
+		timesince: function(d, now){
+			// summary:
+			//		Takes two datetime objects and returns the time between then and now
+			//		as a nicely formatted string, e.g "10 minutes"
+			// description:
+			//		Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since
+			if(!(d instanceof Date)){
+				d = new Date(d.year, d.month, d.day);
+			}
+			if(!now){
+				now = new Date();
+			}
 
-		var delta = Math.abs(now.getTime() - d.getTime());
-		for(var i = 0, chunk; chunk = dojox.dtl.utils.date._chunks[i]; i++){
-			var count = Math.floor(delta / chunk[0]);
-			if(count) break;
-		}
-		return count + " " + chunk[1](count);
-	},
-	_chunks: [
-		[60 * 60 * 24 * 365 * 1000, function(n){ return (n == 1) ? 'year' : 'years'; }],
-		[60 * 60 * 24 * 30 * 1000, function(n){ return (n == 1) ? 'month' : 'months'; }],
-		[60 * 60 * 24 * 7 * 1000, function(n){ return (n == 1) ? 'week' : 'weeks'; }],
-		[60 * 60 * 24 * 1000, function(n){ return (n == 1) ? 'day' : 'days'; }],
-		[60 * 60 * 1000, function(n){ return (n == 1) ? 'hour' : 'hours'; }],
-		[60 * 1000, function(n){ return (n == 1) ? 'minute' : 'minutes'; }]
-	],
-	_months_ap: ["Jan.", "Feb.", "March", "April", "May", "June", "July", "Aug.", "Sept.", "Oct.", "Nov.", "Dec."]
-});
\ No newline at end of file
+			var delta = Math.abs(now.getTime() - d.getTime());
+			for(var i = 0, chunk; chunk = dojox.dtl.utils.date._chunks[i]; i++){
+				var count = Math.floor(delta / chunk[0]);
+				if(count) break;
+			}
+			return count + " " + chunk[1](count);
+		},
+		_chunks: [
+			[60 * 60 * 24 * 365 * 1000, function(n){ return (n == 1) ? 'year' : 'years'; }],
+			[60 * 60 * 24 * 30 * 1000, function(n){ return (n == 1) ? 'month' : 'months'; }],
+			[60 * 60 * 24 * 7 * 1000, function(n){ return (n == 1) ? 'week' : 'weeks'; }],
+			[60 * 60 * 24 * 1000, function(n){ return (n == 1) ? 'day' : 'days'; }],
+			[60 * 60 * 1000, function(n){ return (n == 1) ? 'hour' : 'hours'; }],
+			[60 * 1000, function(n){ return (n == 1) ? 'minute' : 'minutes'; }]
+		],
+		_months_ap: ["Jan.", "Feb.", "March", "April", "May", "June", "July", "Aug.", "Sept.", "Oct.", "Nov.", "Dec."]
+	});
+	return dojox.dtl.utils.date;
+});
diff --git a/dojox/editor/README b/dojox/editor/README
index ee7140c..251c9ce 100644
--- a/dojox/editor/README
+++ b/dojox/editor/README
@@ -13,7 +13,7 @@ Credits
 		Preview, Save, ToolbarLineBreak, InsertEntity, 
 		NormalizeIndentOutdent, Breadcrumb, FindReplace, 
 		CollapsibleToolbar, Blockquote, PasteFromWord, InsertAnchor,
-		TextColor, NormalizeStyle, StatusBar)
+		TextColor, NormalizeStyle, StatusBar, SafePaste)
 	Dustin Machi 	 - Technical Assistance
 	David Schwartz and Gu Yi He (IBM) - Contributed enhancements to the
 		look and feel of FindReplace, as well as behavioral
@@ -159,6 +159,13 @@ dojox.editor.plugins.SpellCheck
 	Status: Experimental (Unsupported)
 	A plugin that provides server-side spell-check support.
 
+	
+dojox.editor.plugins.SafePaste
+	Status: Beta (Supported)
+	A plugin that provides a safer paste function to the editor.  It strips out script tags, 
+	tries to fix up odd input from Word, Wordpad, etc.  Very similar to PasteFromWord except that
+	it takes complete control of paste in dijit.Editor instead of being an alternate paste icon.
+	
 -------------------------------------------------------------------------------
 Dependencies:
 
@@ -174,30 +181,31 @@ Documentation
 The plugins directory contains extensions which work with dijit.Editor.
 
 See also:
-	http://docs.dojocampus.org/dojox/editor/plugins/TablePlugins
-	http://docs.dojocampus.org/dojox/editor/plugins/PrettyPrint
-	http://docs.dojocampus.org/dojox/editor/plugins/PageBreak
-	http://docs.dojocampus.org/dojox/editor/plugins/ShowBlockNodes
-	http://docs.dojocampus.org/dojox/editor/plugins/Preview
-	http://docs.dojocampus.org/dojox/editor/plugins/Save
-	http://docs.dojocampus.org/dojox/editor/plugins/ToolbarLineBreak
-	http://docs.dojocampus.org/dojox/editor/plugins/InsertEntity
-	http://docs.dojocampus.org/dojox/editor/plugins/NormalizeIndentOutdent
-	http://docs.dojocampus.org/dojox/editor/plugins/Breadcrumb
-	http://docs.dojocampus.org/dojox/editor/plugins/FindReplace
-	http://docs.dojocampus.org/dojox/editor/plugins/CollapsibleToolbar
-	http://docs.dojocampus.org/dojox/editor/plugins/Blockquote
-	http://docs.dojocampus.org/dojox/editor/plugins/PasteFromWord
-	http://docs.dojocampus.org/dojox/editor/plugins/InsertAnchor       
-	http://docs.dojocampus.org/dojox/editor/plugins/TextColor
-	http://docs.dojocampus.org/dojox/editor/plugins/NormalizeStyle
-	http://docs.dojocampus.org/dojox/editor/plugins/StatusBar 
-	http://docs.dojocampus.org/dojox/editor/plugins/LocalImage
-	http://docs.dojocampus.org/dojox/editor/plugins/AutoUrlLink
-	http://docs.dojocampus.org/dojox/editor/plugins/ResizeTableColumn
-	http://docs.dojocampus.org/dojox/editor/plugins/AutoSave
-	http://docs.dojocampus.org/dojox/editor/plugins/SpellCheck
-
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/TablePlugins.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/PrettyPrint.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/PageBreak.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/ShowBlockNodes.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/Preview.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/Save.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/ToolbarLineBreak.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/InsertEntity.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/NormalizeIndentOutdent.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/Breadcrumb.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/FindReplace.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/CollapsibleToolbar.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/Blockquote.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/PasteFromWord.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/InsertAnchor.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/TextColor.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/NormalizeStyle.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/StatusBar.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/LocalImage.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/AutoUrlLink.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/ResizeTableColumn.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/AutoSave.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/SpellCheck.html
+	http://dojotoolkit.org/reference-guide/dojox/editor/plugins/SafePaste.html
+.html
 	
 -------------------------------------------------------------------------------
 Plugin Installation instructions
@@ -326,7 +334,12 @@ For the SpellCheck plugin:
 	dojo.require("dojox.editor.plugins.SpellCheck");
 	and CSS:
 	<link href="[path]dojox/editor/plugins/resources/css/SpellCheck.css" type="text/css" rel="stylesheet" />
-                
+
+For the SafePaste plugin:
+	dojo.require("dojox.editor.plugins.SafePaste");
+	and CSS:
+	<link href="[path]dojox/editor/plugins/resources/css/SafePaste.css" type="text/css" rel="stylesheet" />
+	
 See tests for examples:
 	dojox/editor/tests/editorTablePlugs.html
 	dojox/editor/tests/editorUploadPlug.html
@@ -352,4 +365,5 @@ See tests for examples:
 	dojox/editor/tests/editorResizeTableColumn.html
 	dojox/editor/tests/editorAutoSave.html
 	dojox/editor/tests/editorSpellCheck.html
+	dojox/editor/tests/editorSafePaste.html
 	dojox/editor/tests/testPluginsAll.html
diff --git a/dojox/editor/plugins/AutoSave.js b/dojox/editor/plugins/AutoSave.js
index 46a19b1..2ac43f7 100644
--- a/dojox/editor/plugins/AutoSave.js
+++ b/dojox/editor/plugins/AutoSave.js
@@ -1,8 +1,34 @@
-define("dojox/editor/plugins/AutoSave", ["dojo", "dijit", "dojox", "dojo/string", "dojo/date/locale", "dijit/Dialog", "dijit/MenuItem", "dijit.Menu", "dijit/form/Button", "dijit/form/ComboBox", "dijit/form/TextBox", "dijit/TooltipDialog", "dijit/_editor/_Plugin", "dijit/form/Button", "dojo/i18n", "dojox/editor/plugins/Save", "i18n!dojox/editor/plugins/nls/AutoSave"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",	// _scopeName
+	"dojox",
+	"dijit/_base/manager",	// getUniqueId()
+	"dijit/_base/popup",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dijit/_WidgetsInTemplateMixin",
+	"dijit/Dialog",
+	"dijit/MenuItem",
+	"dijit/Menu",
+	"dijit/form/Button",
+	"dijit/form/ComboButton",
+	"dijit/form/ComboBox",
+	"dijit/form/_TextBoxMixin",	// selectInputText()
+	"dijit/form/TextBox",
+	"dijit/TooltipDialog",
+	"dijit/_editor/_Plugin",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/date/locale",
+	"dojo/i18n",
+	"dojo/string",
+	"dojox/editor/plugins/Save",
+	"dojo/i18n!dojox/editor/plugins/nls/AutoSave"
+], function(dojo, dijit, dojox) {
 
 dojo.experimental("dojox.editor.plugins.AutoSave");
 
-dojo.declare("dojox.editor.plugins._AutoSaveSettingDialog", [dijit._Widget, dijit._Templated], {
+dojo.declare("dojox.editor.plugins._AutoSaveSettingDialog", [dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
 	
 	// dialogTitle [public] String
 	//		The tile of the Auto-Save setting dialog
@@ -217,7 +243,7 @@ dojo.declare("dojox.editor.plugins.AutoSave", dojox.editor.plugins.Save, {
 		});
 		this.connect(this._saveSettingDialog, "onOk", "_onDialogOk");
 		
-		var pd = this._promDialog = new dijit.TooltipDialog();
+		var pd = (this._promDialog = new dijit.TooltipDialog());
 		pd.startup();
 		pd.set("content", "");
 	},
@@ -230,10 +256,10 @@ dojo.declare("dojox.editor.plugins.AutoSave", dojox.editor.plugins.Save, {
 				iconClass: this._iconClassPrefix + "Default " + this._iconClassPrefix,
 				label: this._strings["saveLabel"]
 			}),
-			menuItemAutoSave = this._menuItemAutoSave = new dijit.MenuItem({
+			menuItemAutoSave = (this._menuItemAutoSave = new dijit.MenuItem({
 				iconClass: this._iconClassPrefix + "Setting " + this._iconClassPrefix,
 				label: this._strings["saveSettingLabelOn"]
-			});
+			}));
 			
 		menu.addChild(menuItemSave);
 		menu.addChild(menuItemAutoSave);
@@ -264,7 +290,7 @@ dojo.declare("dojox.editor.plugins.AutoSave", dojox.editor.plugins.Save, {
 		//		If the interval is set (larger than 0), enable auto-save.
 		// tags:
 		//		private
-		var interval = this.interval = this._saveSettingDialog.get("value") * this._MIN;
+		var interval = (this.interval = this._saveSettingDialog.get("value") * this._MIN);
 		if(interval > 0){
 			this._setSaveInterval(interval);
 			// Change the menu "Set Auto-Save Interval..." to "Turn off Auto-Save"
diff --git a/dojox/editor/plugins/AutoUrlLink.js b/dojox/editor/plugins/AutoUrlLink.js
index a6916ce..7df79a3 100644
--- a/dojox/editor/plugins/AutoUrlLink.js
+++ b/dojox/editor/plugins/AutoUrlLink.js
@@ -1,4 +1,15 @@
-define("dojox/editor/plugins/AutoUrlLink", ["dojo", "dijit", "dojox", "dojo/string", "dijit/_editor/_Plugin", "dijit/form/Button"], function(dojo, dijit, dojox) {
+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) {
 
 dojo.declare("dojox.editor.plugins.AutoUrlLink", [dijit._editor._Plugin], {
 	//summary:
diff --git a/dojox/editor/plugins/Blockquote.js b/dojox/editor/plugins/Blockquote.js
index d6f31f1..456e9a2 100755
--- a/dojox/editor/plugins/Blockquote.js
+++ b/dojox/editor/plugins/Blockquote.js
@@ -1,4 +1,16 @@
-define("dojox/editor/plugins/Blockquote", ["dojo", "dijit", "dojox", "dijit/_editor/_Plugin", "dijit/form/Button", "dojo/i18n", "i18n!dojox/editor/plugins/nls/Blockquote"], function(dojo, dijit, dojox) {
+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) {
 
 dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 	//	summary:
diff --git a/dojox/editor/plugins/Breadcrumb.js b/dojox/editor/plugins/Breadcrumb.js
index 355b918..a16f32c 100755
--- a/dojox/editor/plugins/Breadcrumb.js
+++ b/dojox/editor/plugins/Breadcrumb.js
@@ -1,8 +1,28 @@
-define("dojox/editor/plugins/Breadcrumb", ["dojo", "dijit", "dojox", "dojo/string", "dijit/Toolbar", "dijit/Menu", "dijit/MenuItem", "dijit/MenuSeparator", "dijit/_editor/range", "dijit/_editor/selection", "dijit/_editor/_Plugin", "dijit/form/Button", "dojo/i18n", "i18n!dojox/editor/plugins/nls/Breadcrumb"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dijit/Toolbar",
+	"dijit/Menu",
+	"dijit/MenuItem",
+	"dijit/MenuSeparator",
+	"dijit/_editor/range",
+	"dijit/_editor/selection",
+	"dijit/_editor/_Plugin",
+	"dijit/form/Button",
+	"dijit/form/ComboButton",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/i18n",
+	"dojo/string",
+	"dojo/i18n!dojox/editor/plugins/nls/Breadcrumb"
+], function(dojo, dijit, dojox) {
 
 dojo.experimental("dojox.editor.plugins.Breadcrumb");
 
-dojo.declare("dojox.editor.plugins._BreadcrumbMenuTitle",[dijit._Widget, dijit._Templated, dijit._Contained],{
+dojo.declare("dojox.editor.plugins._BreadcrumbMenuTitle",[dijit._Widget, dijit._TemplatedMixin, dijit._Contained],{
 	// summary:
 	//		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>",
@@ -12,7 +32,7 @@ dojo.declare("dojox.editor.plugins._BreadcrumbMenuTitle",[dijit._Widget, dijit._
 	postCreate: function(){
 		dojo.setSelectable(this.domNode, false);
 		var label = this.id+"_text";
-		dijit.setWaiState(this.domNode, "labelledby", label);
+		this.domNode.setAttribute("aria-labelledby", label);
 	},
 
 	_setMenuTitleAttr: function(str){
diff --git a/dojox/editor/plugins/CollapsibleToolbar.js b/dojox/editor/plugins/CollapsibleToolbar.js
index 35f421a..de45e75 100644
--- a/dojox/editor/plugins/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/CollapsibleToolbar.js
@@ -1,6 +1,19 @@
-define("dojox/editor/plugins/CollapsibleToolbar", ["dojo", "dijit", "dojox", "dijit/_Widget", "dijit/_Templated", "dijit/_editor/_Plugin", "dijit/form/Button", "dojo/i18n", "i18n!dojox/editor/plugins/nls/CollapsibleToolbar"], function(dojo, dijit, dojox) {
-
-dojo.declare("dojox.editor.plugins._CollapsibleToolbarButton", [dijit._Widget, dijit._Templated], {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dijit/_editor/_Plugin",
+	"dijit/form/Button",
+	"dijit/focus",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/i18n",
+	"dojo/i18n!dojox/editor/plugins/nls/CollapsibleToolbar"
+], function(dojo, dijit, dojox) {
+
+dojo.declare("dojox.editor.plugins._CollapsibleToolbarButton", [dijit._Widget, dijit._TemplatedMixin], {
 	// summary:
 	//		Simple internal widget for representing a clickable button for expand/collapse
 	//		with A11Y support.
diff --git a/dojox/editor/plugins/EntityPalette.js b/dojox/editor/plugins/EntityPalette.js
index e5f4a7a..54f14e1 100755
--- a/dojox/editor/plugins/EntityPalette.js
+++ b/dojox/editor/plugins/EntityPalette.js
@@ -1,9 +1,20 @@
-define("dojox/editor/plugins/EntityPalette", ["dojo", "dijit", "dojox", "dijit/_Widget", "dijit/_Templated", "dijit/_PaletteMixin", "dojo/i18n", "i18n!dojox/editor/plugins/nls/latinEntities"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dijit/_PaletteMixin",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/i18n",
+	"dojo/i18n!dojox/editor/plugins/nls/latinEntities"
+], function(dojo, dijit, dojox) {
 
 dojo.experimental("dojox.editor.plugins.EntityPalette");
 
 dojo.declare("dojox.editor.plugins.EntityPalette",
-	[dijit._Widget, dijit._Templated, dijit._PaletteMixin],
+	[dijit._Widget, dijit._TemplatedMixin, dijit._PaletteMixin],
 	{
 	// summary:
 	//		A keyboard accessible HTML entity-picking widget (for inserting symbol characters)
diff --git a/dojox/editor/plugins/FindReplace.js b/dojox/editor/plugins/FindReplace.js
index 43a0f3e..1352952 100755
--- a/dojox/editor/plugins/FindReplace.js
+++ b/dojox/editor/plugins/FindReplace.js
@@ -1,8 +1,33 @@
-define("dojox/editor/plugins/FindReplace", ["dojo", "dijit", "dojox", "dojo/string", "dijit/TooltipDialog", "dijit/Toolbar", "dijit/form/CheckBox", "dijit/form/TextBox", "dijit/_editor/_Plugin", "dijit/form/Button", "dojox/editor/plugins/ToolbarLineBreak",  "dojo/i18n", "i18n!dojox/editor/plugins/nls/FindReplace"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/_base/manager",	// getUniqueId
+	"dijit/_base/popup",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dijit/_KeyNavContainer",
+	"dijit/_WidgetsInTemplateMixin",
+	"dijit/TooltipDialog",
+	"dijit/Toolbar",
+	"dijit/form/CheckBox",
+	"dijit/form/_TextBoxMixin",	// selectInputText
+	"dijit/form/TextBox",
+	"dijit/_editor/_Plugin",
+	"dijit/form/Button",
+	"dijit/form/DropDownButton",
+	"dijit/form/ToggleButton",
+	"dojox/editor/plugins/ToolbarLineBreak",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/i18n",
+	"dojo/string",
+	"dojo/i18n!dojox/editor/plugins/nls/FindReplace"
+], function(dojo, dijit, dojox) {
 
 dojo.experimental("dojox.editor.plugins.FindReplace");
 
-dojo.declare("dojox.editor.plugins._FindReplaceCloseBox", [dijit._Widget, dijit._Templated], {
+dojo.declare("dojox.editor.plugins._FindReplaceCloseBox", [dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
 	// summary:
 	//		Base class for widgets that contains a button labeled X
 	//		to close the tool bar.
@@ -32,7 +57,7 @@ dojo.declare("dojox.editor.plugins._FindReplaceCloseBox", [dijit._Widget, dijit.
 
 
 dojo.declare("dojox.editor.plugins._FindReplaceTextBox",
-	[dijit._Widget, dijit._Templated],{
+	[dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin],{
 	// summary:
 	//		Base class for widgets that contains a label (like "Font:")
 	//		and a TextBox to pick a value.
@@ -56,7 +81,7 @@ dojo.declare("dojox.editor.plugins._FindReplaceTextBox",
 		"<span style='white-space: nowrap' class='dijit dijitReset dijitInline dijitEditorFindReplaceTextBox' " +
 			"title='${tooltip}' tabindex='-1'>" +
 			"<label class='dijitLeft dijitInline' for='${textId}' tabindex='-1'>${label}</label>" +
-			"<input dojoType='dijit.form.TextBox' required='false' intermediateChanges='true' class='focusTextBox'" +
+			"<input dojoType='dijit.form.TextBox' intermediateChanges='true' class='focusTextBox' " +
 					"tabIndex='0' id='${textId}' dojoAttachPoint='textBox, focusNode' value='' dojoAttachEvent='onKeyPress: _onKeyPress'/>" +
 		"</span>",
 
@@ -72,6 +97,7 @@ dojo.declare("dojox.editor.plugins._FindReplaceTextBox",
 		this.textBox.set("value", "");
 		this.disabled =  this.textBox.get("disabled");
 		this.connect(this.textBox, "onChange", "onChange");
+		dojo.attr(this.textBox.textbox, "formnovalidate", "true");
 	},
 
 	_setValueAttr: function(/*String*/ value){
@@ -137,7 +163,7 @@ dojo.declare("dojox.editor.plugins._FindReplaceTextBox",
 
 
 dojo.declare("dojox.editor.plugins._FindReplaceCheckBox",
-	[dijit._Widget, dijit._Templated],{
+	[dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin],{
 	// summary:
 	//		Base class for widgets that contains a label (like "Match case: ")
 	//		and a checkbox to indicate if it is checked or not.
@@ -161,7 +187,7 @@ dojo.declare("dojox.editor.plugins._FindReplaceCheckBox",
 	templateString:
 		"<span style='white-space: nowrap' tabindex='-1' " +
 			"class='dijit dijitReset dijitInline dijitEditorFindReplaceCheckBox' title='${tooltip}' >" +
-			"<input dojoType='dijit.form.CheckBox' required=false " +
+			"<input dojoType='dijit.form.CheckBox' " +
 					"tabIndex='0' id='${checkId}' dojoAttachPoint='checkBox, focusNode' value=''/>" +
 			"<label tabindex='-1' class='dijitLeft dijitInline' for='${checkId}'>${label}</label>" +
 		"</span>",
@@ -422,7 +448,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 dojox.editor.plugins._FindReplaceToolbar());
 			dojo.style(_tb.domNode, "display", "none");
 			dojo.place(_tb.domNode, toolbar.domNode, "after");
 			_tb.startup();
diff --git a/dojox/editor/plugins/InsertAnchor.js b/dojox/editor/plugins/InsertAnchor.js
index 5b3b094..55a81b3 100755
--- a/dojox/editor/plugins/InsertAnchor.js
+++ b/dojox/editor/plugins/InsertAnchor.js
@@ -1,4 +1,26 @@
-define("dojox/editor/plugins/InsertAnchor", ["dojo", "dijit", "dojox", "dojo/string", "dijit/_Widget", "dijit/_editor/range", "dijit/_Templated", "dijit/TooltipDialog", "dijit/form/ValidationTextBox", "dijit/form/Select", "dijit/_editor/_Plugin", "dijit/form/Button", "dojox/editor/plugins/ToolbarLineBreak",  "dojo/i18n", "i18n!dojox/editor/plugins/nls/InsertAnchor", "i18n!dijit/nls/common"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/_base/manager",	// TODO: change to dijit/registry, and change dijit.byId to registry.byId
+	"dijit/_editor/range",
+	"dijit/_Templated",
+	"dijit/TooltipDialog",
+	"dijit/form/ValidationTextBox",
+	"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",
+	"dojox/editor/plugins/ToolbarLineBreak",
+	"dojo/i18n!dojox/editor/plugins/nls/InsertAnchor",
+	"dojo/i18n!dijit/nls/common"
+], function(dojo, dijit, dojox) {
 
 dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 	// summary:
@@ -363,6 +385,9 @@ dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 					// IE doesn't like focus changes in event handles.
 					this.button.set("disabled", false);
 					this.button.openDropDown();
+					if(this.button.dropDown.focus){
+						this.button.dropDown.focus();
+					}
 				}), 10);
 			}
 		}
diff --git a/dojox/editor/plugins/InsertEntity.js b/dojox/editor/plugins/InsertEntity.js
index bc47480..0b9cb8c 100755
--- a/dojox/editor/plugins/InsertEntity.js
+++ b/dojox/editor/plugins/InsertEntity.js
@@ -1,4 +1,17 @@
-define("dojox/editor/plugins/InsertEntity", ["dojo", "dijit", "dojox", "dijit/TooltipDialog", "dijit/_editor/_Plugin", "dijit/form/Button", "dojox/html/entities", "dojox/editor/plugins/EntityPalette", "dojo/i18n", "i18n!dojox/editor/plugins/nls/InsertEntity"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/TooltipDialog",
+	"dijit/_editor/_Plugin",
+	"dijit/form/DropDownButton",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/i18n",
+	"dojox/html/entities",
+	"dojox/editor/plugins/EntityPalette",
+	"dojo/i18n!dojox/editor/plugins/nls/InsertEntity"
+], function(dojo, dijit, dojox) {
 
 dojo.declare("dojox.editor.plugins.InsertEntity",dijit._editor._Plugin,{
 	// summary:
diff --git a/dojox/editor/plugins/LocalImage.js b/dojox/editor/plugins/LocalImage.js
index 7092f32..05a7651 100644
--- a/dojox/editor/plugins/LocalImage.js
+++ b/dojox/editor/plugins/LocalImage.js
@@ -1,6 +1,25 @@
-define("dojox/editor/plugins/LocalImage", ["dojo", "dijit", "dojox", "dijit/_editor/plugins/LinkDialog", "dojox/form/FileUploader", "dojo/i18n", "i18n!dojox/editor/plugins/nls/LocalImage"], function(dojo, dijit, dojox) {
+define([
+	"dojo",//FIXME
+	"dijit",//FIXME
+	"dijit/registry",
+	"dijit/_base/popup",
+	"dijit/_editor/_Plugin",
+	"dijit/_editor/plugins/LinkDialog",
+	"dijit/TooltipDialog",
+	"dijit/form/_TextBoxMixin",
+	"dijit/form/Button",
+	"dijit/form/ValidationTextBox",
+	"dijit/form/DropDownButton",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/_base/sniff",
+	"dojox/form/FileUploader", //FIXME: deprecated.  Use Uploader instead
+	"dojo/i18n!dojox/editor/plugins/nls/LocalImage"
+], function(dojo, dijit, registry, popup, _Plugin, LinkDialog, TooltipDialog,
+			_TextBoxMixin, Button, ValidationTextBox, DropDownButton,
+			connect, declare, has, FileUploader, messages) {
 
-dojo.declare("dojox.editor.plugins.LocalImage", dijit._editor.plugins.ImgLinkDialog, {
+var LocalImage = dojo.declare("dojox.editor.plugins.LocalImage", LinkDialog.ImgLinkDialog, {
 	// summary:
 	//		This plugin provides an enhanced image link dialog that
 	//		not only insert the online images, but upload the local image files onto
@@ -41,11 +60,7 @@ dojo.declare("dojox.editor.plugins.LocalImage", dijit._editor.plugins.ImgLinkDia
 	//		Used to validate if the input is a valid image URL.
 	urlRegExp: "",
 	
-	// _fileUploader [private] dojox.form.FileUploader
-	//		The component to upload the local image file onto the server
-	_fileUploader: null,
-	
-	// _fileUploader [private] htmlFieldName
+	// htmlFieldName [private] htmlFieldName
 	htmlFieldName:"uploadedfile",
 	
 	// _isLocalFile [private] Boolean
@@ -98,19 +113,18 @@ dojo.declare("dojox.editor.plugins.LocalImage", dijit._editor.plugins.ImgLinkDia
 		//		Override _Plugin._initButton() to initialize DropDownButton and TooltipDialog.
 		// tags:
 		//		protected
-		var _this = this,
-			messages = this._messages = dojo.i18n.getLocalization("dojox.editor.plugins", "LocalImage");
-		
+	    	var _this = this;
+		this._messages = messages;
 		this.tag = "img";
-		var dropDown = (this.dropDown = new dijit.TooltipDialog({
+		var dropDown = (this.dropDown = new TooltipDialog({
 			title: messages[this.command + "Title"],
 			onOpen: function(){
 				_this._initialFileUploader();
 				_this._onOpenDialog();
-				dijit.TooltipDialog.prototype.onOpen.apply(this, arguments);
+				TooltipDialog.prototype.onOpen.apply(this, arguments);
 				setTimeout(function(){
 					// Auto-select the text if it is not empty
-					dijit.selectInputText(_this._urlInput.textbox);
+					_TextBoxMixin.selectInputText(_this._urlInput.textbox);
 					_this._urlInput.isLoadComplete = true;
 				}, 0);
 			},
@@ -134,7 +148,7 @@ dojo.declare("dojox.editor.plugins.LocalImage", dijit._editor.plugins.ImgLinkDia
 					tabIndex: "-1"
 				}, this.params || {});
 		
-		if(!dojo.isIE && (!dojo.isFF || dojo.isFF < 4)){
+		if(!has('ie')){
 			// Workaround for Non-IE problem:
 			// Safari 5: After the select-file dialog opens, the first time the user clicks anywhere (even on that dialog)
 			// it's treated like a plain click on the page, and the tooltip dialog closes
@@ -142,7 +156,7 @@ dojo.declare("dojox.editor.plugins.LocalImage", dijit._editor.plugins.ImgLinkDia
 			props.closeDropDown = function(/*Boolean*/ focus){
 				if(_this._closable){
 					if(this._opened){
-						dijit.popup.close(this.dropDown);
+						popup.close(this.dropDown);
 						if(focus){ this.focus(); }
 						this._opened = false;
 						this.state = "";
@@ -152,7 +166,7 @@ dojo.declare("dojox.editor.plugins.LocalImage", dijit._editor.plugins.ImgLinkDia
 			};
 		}
 		
-		this.button = new dijit.form.DropDownButton(props);
+		this.button = new DropDownButton(props);
 		
 		// Generate the RegExp of the ValidationTextBox from fileMask
 		// *.jpg;*.png => /.*\.jpg|.*\.JPG|.*\.png|.*\.PNG/
@@ -165,22 +179,22 @@ dojo.declare("dojox.editor.plugins.LocalImage", dijit._editor.plugins.ImgLinkDia
 		messages.urlRegExp = this.urlRegExp = temp.substring(1);
 		
 		if(!this.uploadable){
-			messages["prePopuTextBrowse"] = ".";
+			messages.prePopuTextBrowse = ".";
 		}
 		
-		messages.id = dijit.getUniqueId(this.editor.id);
+		messages.id = registry.getUniqueId(this.editor.id);
 		messages.uploadable = this.uploadable ? "inline" : "none";
 		this._uniqueId = messages.id;
 		this._setContent("<div class='" + this._cssPrefix + "Title'>" + dropDown.title + "</div>" +
 			dojo.string.substitute(this.linkDialogTemplate, messages));
 		dropDown.startup();
 		
-		var urlInput = this._urlInput = dijit.byId(this._uniqueId + "_urlInput");
-		this._textInput = dijit.byId(this._uniqueId + "_textInput");
-		this._setButton = dijit.byId(this._uniqueId + "_setButton");
+		var urlInput = (this._urlInput = registry.byId(this._uniqueId + "_urlInput"));
+		this._textInput = registry.byId(this._uniqueId + "_textInput");
+		this._setButton = registry.byId(this._uniqueId + "_setButton");
 		
 		if(urlInput){
-			var pt = dijit.form.ValidationTextBox.prototype;
+			var pt = ValidationTextBox.prototype;
 			urlInput = dojo.mixin(urlInput, {
 				// Indicate if the widget is ready to validate the input text
 				isLoadComplete: false,
@@ -218,7 +232,7 @@ dojo.declare("dojox.editor.plugins.LocalImage", dijit._editor.plugins.ImgLinkDia
 			urlInput = _this._urlInput;
 		
 		if(_this.uploadable && !_this._fileUploader){
-			fup = _this._fileUploader = new dojox.form.FileUploader({
+			fup = _this._fileUploader = new FileUploader({
 				force: "html", // Noticed that SWF may cause browsers to crash sometimes
 				uploadUrl: _this.uploadUrl,
 				htmlFieldName: _this.htmlFieldName,
@@ -236,12 +250,12 @@ dojo.declare("dojox.editor.plugins.LocalImage", dijit._editor.plugins.ImgLinkDia
 			
 			_this.connect(fup, "onClick", function(){
 				urlInput.validate(false);
-				if(!dojo.isIE && (!dojo.isFF || dojo.isFF < 4)){
-					// Firefox (below v4), Chome and Safari have a strange behavior:
+				if(!has('ie')){
+					// Firefox, Chrome and Safari have a strange behavior:
 					// When the File Upload dialog is open, the browse div (FileUploader) will lose its focus
 					// and triggers onBlur event. This event will cause the whole tooltip dialog
 					// to be closed when the File Upload dialog is open. The popup dialog should hang up
-					// the js executioin rather than triggering an event. IE does not have such a problem.
+					// the js execution rather than triggering an event. IE does not have such a problem.
 					_this._closable = false;
 				}
 			});
@@ -315,27 +329,23 @@ dojo.declare("dojox.editor.plugins.LocalImage", dijit._editor.plugins.ImgLinkDia
 		this.inherited(arguments);
 		if(this._fileUploader){
 			this._fileUploader.destroy();
-			this._fileUploader = null;
+			delete this._fileUploader;
 		}
 	}
 });
 
 // Register this plugin.
-dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
-	if(o.plugin){ return; }
-	var name = o.args.name.toLowerCase();
-	if(name ===  "localimage"){
-		o.plugin = new dojox.editor.plugins.LocalImage({
-			command: "insertImage",
-			uploadable: ("uploadable" in o.args) ? o.args.uploadable : false,
-			uploadUrl: ("uploadable" in o.args && "uploadUrl" in o.args) ? o.args.uploadUrl : "",
-			htmlFieldName: ("uploadable" in o.args && "htmlFieldName" in o.args) ? o.args.htmlFieldName : "uploadedfile",
-			baseImageUrl: ("uploadable" in o.args && "baseImageUrl" in o.args) ? o.args.baseImageUrl : "",
-			fileMask: ("fileMask" in o.args) ? o.args.fileMask : "*.jpg;*.jpeg;*.gif;*.png;*.bmp"
-		});
-	}
-});
+_Plugin.registry["LocalImage"] = function(args){
+	return new LocalImage({
+		command: "insertImage",
+		uploadable: ("uploadable" in args) ? args.uploadable : false,
+		uploadUrl: ("uploadable" in args && "uploadUrl" in args) ? args.uploadUrl : "",
+		htmlFieldName: ("uploadable" in args && "htmlFieldName" in args) ? args.htmlFieldName : "uploadedfile",
+		baseImageUrl: ("uploadable" in args && "baseImageUrl" in args) ? args.baseImageUrl : "",
+		fileMask: ("fileMask" in args) ? args.fileMask : "*.jpg;*.jpeg;*.gif;*.png;*.bmp"
+	});
+};
 
-return dojox.editor.plugins.LocalImage;
+return LocalImage;
 
 });
diff --git a/dojox/editor/plugins/NormalizeIndentOutdent.js b/dojox/editor/plugins/NormalizeIndentOutdent.js
index 2998bc0..62a8baa 100755
--- a/dojox/editor/plugins/NormalizeIndentOutdent.js
+++ b/dojox/editor/plugins/NormalizeIndentOutdent.js
@@ -1,4 +1,13 @@
-define("dojox/editor/plugins/NormalizeIndentOutdent", ["dojo", "dijit", "dojox", "dijit/_editor/selection", "dijit/_editor/_Plugin"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/_editor/range",
+	"dijit/_editor/selection",
+	"dijit/_editor/_Plugin",
+	"dojo/_base/connect",
+	"dojo/_base/declare"
+], function(dojo, dijit, dojox) {
 
 dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin,{
 	// summary:
diff --git a/dojox/editor/plugins/NormalizeStyle.js b/dojox/editor/plugins/NormalizeStyle.js
index 4529457..8f1b8c2 100755
--- a/dojox/editor/plugins/NormalizeStyle.js
+++ b/dojox/editor/plugins/NormalizeStyle.js
@@ -1,4 +1,12 @@
-define("dojox/editor/plugins/NormalizeStyle", ["dojo", "dijit", "dojox", "dijit/_editor/html", "dijit/_editor/_Plugin"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/_editor/html",
+	"dijit/_editor/_Plugin",
+	"dojo/_base/connect",
+	"dojo/_base/declare"
+], function(dojo, dijit, dojox) {
 
 dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 	// summary:
diff --git a/dojox/editor/plugins/PageBreak.js b/dojox/editor/plugins/PageBreak.js
index 6ba52e1..59cafbe 100755
--- a/dojox/editor/plugins/PageBreak.js
+++ b/dojox/editor/plugins/PageBreak.js
@@ -1,4 +1,14 @@
-define("dojox/editor/plugins/PageBreak", ["dojo", "dijit", "dojox", "dijit/_editor/html", "dijit/_editor/_Plugin", "dojo/i18n", "i18n!dojox/editor/plugins/nls/PageBreak"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/form/Button",
+	"dijit/_editor/_Plugin",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/i18n",
+	"dojo/i18n!dojox/editor/plugins/nls/PageBreak"
+], function(dojo, dijit, dojox) {
 
 dojo.declare("dojox.editor.plugins.PageBreak",dijit._editor._Plugin,{
 	//	summary:
diff --git a/dojox/editor/plugins/PasteFromWord.js b/dojox/editor/plugins/PasteFromWord.js
index 320d203..e3af559 100755
--- a/dojox/editor/plugins/PasteFromWord.js
+++ b/dojox/editor/plugins/PasteFromWord.js
@@ -1,4 +1,19 @@
-define("dojox/editor/plugins/PasteFromWord", ["dojo", "dijit", "dojox", "dojo/string", "dijit/_editor/_Plugin", "dijit/form/Button", "dijit/Dialog", "dojo/i18n", "dojox/html/format", "i18n!dojox/editor/plugins/nls/PasteFromWord"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/_base/manager",
+	"dijit/_editor/_Plugin",
+	"dijit/_editor/RichText",
+	"dijit/form/Button",
+	"dijit/Dialog",
+	"dojox/html/format",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/i18n",
+	"dojo/string",
+	"dojo/i18n!dojox/editor/plugins/nls/PasteFromWord"
+], function(dojo, dijit, dojox) {
 
 dojo.declare("dojox.editor.plugins.PasteFromWord",dijit._editor._Plugin,{
 	// summary:
@@ -37,7 +52,7 @@ dojo.declare("dojox.editor.plugins.PasteFromWord",dijit._editor._Plugin,{
 				"</table>",
 			   "</div>"].join(""),
 
-	// _filters: [private] Array
+	// _filters: [protected] Array
 	//		The filters is an array of regular expressions to try and strip out a lot
 	//		of style data MS Word likes to insert when pasting into a contentEditable.
 	//		Prettymuch all of it is junk and not good html.  The hander is a place to put a function
@@ -59,6 +74,8 @@ dojo.declare("dojox.editor.plugins.PasteFromWord",dijit._editor._Plugin,{
 	],
 
 	_initButton: function(){
+		this._filters = this._filters.slice(0); 
+		
 		// summary:
 		//		Over-ride for creation of the save button.
 		var strings = dojo.i18n.getLocalization("dojox.editor.plugins", "PasteFromWord");
@@ -202,4 +219,5 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	}
 });
 
+return dojox.editor.plugins.PasteFromWord;
 });
diff --git a/dojox/editor/plugins/PrettyPrint.js b/dojox/editor/plugins/PrettyPrint.js
index f9b7cbe..9acc489 100755
--- a/dojox/editor/plugins/PrettyPrint.js
+++ b/dojox/editor/plugins/PrettyPrint.js
@@ -1,4 +1,12 @@
-define("dojox/editor/plugins/PrettyPrint", ["dojo", "dijit", "dojox", "dijit/_editor/_Plugin", "dojox/html/format"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/_editor/_Plugin",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojox/html/format"
+], function(dojo, dijit, dojox) {
 
 dojo.declare("dojox.editor.plugins.PrettyPrint",dijit._editor._Plugin,{
 	// summary:
diff --git a/dojox/editor/plugins/Preview.js b/dojox/editor/plugins/Preview.js
index 873a66b..ef200ce 100755
--- a/dojox/editor/plugins/Preview.js
+++ b/dojox/editor/plugins/Preview.js
@@ -1,4 +1,14 @@
-define("dojox/editor/plugins/Preview", ["dojo", "dijit", "dojox", "dijit/form/Button", "dijit/_editor/_Plugin", "dojo/i18n", "i18n!dojox/editor/plugins/nls/Preview"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/form/Button",
+	"dijit/_editor/_Plugin",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/i18n",
+	"dojo/i18n!dojox/editor/plugins/nls/Preview"
+], function(dojo, dijit, dojox) {
 
 dojo.declare("dojox.editor.plugins.Preview",dijit._editor._Plugin,{
 	//	summary:
@@ -57,7 +67,7 @@ dojo.declare("dojox.editor.plugins.Preview",dijit._editor._Plugin,{
 		//		private
 		try{
 			var content = this.editor.get("value");
-			var head = "\t\t<meta http-equiv='Content-Type' content='text/html; charset='UTF-8'>\n";
+			var head = "\t\t<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>\n";
 			var i;
 			// Apply the stylesheets, then apply the styles.
 			if(this.stylesheets){
diff --git a/dojox/editor/plugins/SafePaste.js b/dojox/editor/plugins/SafePaste.js
new file mode 100644
index 0000000..231ac3f
--- /dev/null
+++ b/dojox/editor/plugins/SafePaste.js
@@ -0,0 +1,115 @@
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"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) {
+
+dojo.declare("dojox.editor.plugins.SafePaste", [dojox.editor.plugins.PasteFromWord],{
+	// summary:
+	//		This plugin extends from the PasteFromWord plugin and provides
+	//		'safe pasting', meaning that it will not allow keyboard/menu pasting
+	//		into the dijit editor.  It still runs all of the word cleanup code, 
+	//		including script strippers.  If you use this plugin, you don't need to 
+	//		use the 'PasteFromWord Plugin'
+
+	_initButton: function(){
+		// summary:
+		//		Over-ride the editor paste controls
+
+		// Create instance local copy.
+		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);
+
+		strings.uId = this._uId;
+		strings.width = this.width || "400px";
+		strings.height = this.height || "300px";
+
+		this._dialog = new dijit.Dialog({title: strings["paste"]}).placeAt(dojo.body());
+		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
+		// 'pretty'.
+		dojo.style(dojo.byId(this._uId + "_rte"), "opacity", 0.001);
+
+		// Link up the action buttons to perform the insert or cleanup.
+		this.connect(dijit.byId(this._uId + "_paste"), "onClick", "_paste");
+		this.connect(dijit.byId(this._uId + "_cancel"), "onClick", "_cancel");
+		this.connect(this._dialog, "onHide", "_clearDialog");
+		
+		// Create regular expressions for sripping out user-specified tags and register 
+		// them with the filters.
+		dojo.forEach(this.stripTags, function(tag){
+			var tagName = tag + "";
+			var rxStartTag = new RegExp("<\\s*" + tagName + "[^>]*>", "igm");
+			var rxEndTag = new RegExp("<\\\\?\\/\\s*" + tagName + "\\s*>", "igm");
+			this._filters.push({regexp: 
+				rxStartTag, 
+				handler: ""
+			});
+			this._filters.push({regexp: 
+				rxEndTag, 
+				handler: ""
+			});
+		}, this);
+	},
+	
+	updateState: function(){
+		// summary:
+		//		Overrides _Plugin.updateState(). 
+		// tags:
+		//		protected
+		// Do nothing.
+	},
+	
+	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.onLoadDeferred.addCallback(dojo.hitch(this, function(){
+			var spFunc = dojo.hitch(this, function(e){
+				if(e){
+					dojo.stopEvent(e);
+				}
+				this._openDialog();
+				return true;
+			});
+			this.connect(this.editor.editNode, "onpaste", spFunc);
+			this.editor._pasteImpl = spFunc;
+		}));
+	}
+});
+
+// Register this plugin.
+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({
+			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 
+		});
+	}
+});
+
+return dojox.editor.plugins.SafePaste;
+
+});
diff --git a/dojox/editor/plugins/Save.js b/dojox/editor/plugins/Save.js
index dd24385..e012fdb 100755
--- a/dojox/editor/plugins/Save.js
+++ b/dojox/editor/plugins/Save.js
@@ -1,4 +1,14 @@
-define("dojox/editor/plugins/Save", ["dojo", "dijit", "dojox", "dijit/form/Button", "dijit/_editor/_Plugin", "dojo/i18n", "i18n!dojox/editor/plugins/nls/Save"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/form/Button",
+	"dijit/_editor/_Plugin",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/i18n",
+	"dojo/i18n!dojox/editor/plugins/nls/Save"
+], function(dojo, dijit, dojox) {
 
 dojo.declare("dojox.editor.plugins.Save",dijit._editor._Plugin,{
 	// summary:
diff --git a/dojox/editor/plugins/ShowBlockNodes.js b/dojox/editor/plugins/ShowBlockNodes.js
index c9b44f6..f1c74cd 100755
--- a/dojox/editor/plugins/ShowBlockNodes.js
+++ b/dojox/editor/plugins/ShowBlockNodes.js
@@ -1,4 +1,15 @@
-define("dojox/editor/plugins/ShowBlockNodes", ["dojo", "dijit", "dojox", "dijit/_editor/_Plugin", "dijit/form/Button", "dojo/i18n", "i18n!dojox/editor/plugins/nls/ShowBlockNodes"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/_editor/_Plugin",
+	"dijit/form/Button",
+	"dijit/form/ToggleButton",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/i18n",
+	"dojo/i18n!dojox/editor/plugins/nls/ShowBlockNodes"
+], function(dojo, dijit, dojox) {
 
 dojo.declare("dojox.editor.plugins.ShowBlockNodes",dijit._editor._Plugin,{
 	// summary:
diff --git a/dojox/editor/plugins/Smiley.js b/dojox/editor/plugins/Smiley.js
index 3218f47..7e5183b 100644
--- a/dojox/editor/plugins/Smiley.js
+++ b/dojox/editor/plugins/Smiley.js
@@ -1,4 +1,16 @@
-define("dojox/editor/plugins/Smiley", ["dojo", "dijit", "dojox", "dijit/_editor/_Plugin", "dijit/form/ToggleButton", "dijit/form/DropDownButton", "dojox/editor/plugins/_SmileyPalette", "dojo/i18n", "dojox/html/format", "i18n!dojox/editor/plugins/nls/Smiley"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/_editor/_Plugin",
+	"dijit/form/DropDownButton",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/i18n",
+	"dojox/editor/plugins/_SmileyPalette",
+	"dojox/html/format",
+	"dojo/i18n!dojox/editor/plugins/nls/Smiley"
+], function(dojo, dijit, dojox) {
 
 dojo.experimental("dojox.editor.plugins.Smiley");
 
@@ -60,6 +72,30 @@ dojo.declare("dojox.editor.plugins.Smiley", dijit._editor._Plugin, {
 		this._initButton();
 		this.editor.contentPreFilters.push(dojo.hitch(this, this._preFilterEntities));
 		this.editor.contentPostFilters.push(dojo.hitch(this, this._postFilterEntities));
+		
+		if(dojo.isFF){
+			// This is a workaround for a really odd Firefox bug with
+			// leaving behind phantom cursors when deleting smiley images.
+			// See: #13299
+			var deleteHandler = dojo.hitch(this, function(){
+				var editor = this.editor;
+				// have to use timers here because the event has to happen
+				// (bubble), then we can poke the dom.
+				setTimeout(function(){
+					if(editor.editNode){
+						dojo.style(editor.editNode, "opacity", "0.99");
+						// Allow it to apply, then undo it to trigger cleanup of those
+						// phantoms.
+						setTimeout(function(){if(editor.editNode) { dojo.style(editor.editNode, "opacity", "");} }, 0);
+					}
+				}, 0);
+				return true;
+			})
+			this.editor.onLoadDeferred.addCallback(dojo.hitch(this, function(){
+				this.editor.addKeyHandler(dojo.keys.DELETE, false, false, deleteHandler);
+				this.editor.addKeyHandler(dojo.keys.BACKSPACE, false, false, deleteHandler);
+			}));
+		}
 	},
 
 	_preFilterEntities: function(/*String content passed in*/ value){
diff --git a/dojox/editor/plugins/SpellCheck.js b/dojox/editor/plugins/SpellCheck.js
index 5a5bf5c..7c6923c 100644
--- a/dojox/editor/plugins/SpellCheck.js
+++ b/dojox/editor/plugins/SpellCheck.js
@@ -1,5 +1,8 @@
 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");
@@ -571,8 +574,8 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		// tags:
 		//		private
 		var _this = this,
-			strings = this._strings = dojo.i18n.getLocalization("dojox.editor.plugins", "SpellCheck"),
-			dialogPane = this._dialog = new dijit.TooltipDialog();
+			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({
 			unfound: strings["unfound"],
@@ -614,7 +617,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		});
 		_this._dialogContent.isOpen = false;
 		
-		dijit.setWaiState(dialogPane.domNode, "label", this._strings["widgetLabel"]);
+		dialogPane.domNode.setAttribute("aria-label", this._strings["widgetLabel"]);
 	},
 	
 	_setNetwork: function(){
@@ -625,7 +628,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		var comms = this.exArgs;
 		
 		if(!this._service){
-			var service = this._service = new dojox.editor.plugins._SpellCheckScriptMultiPart();
+			var service = (this._service = new dojox.editor.plugins._SpellCheckScriptMultiPart());
 			service.serviceEndPoint = this.url;
 			service.maxBufferLength = this.bufferLength;
 			service.setWaitingTime(this.timeout);
diff --git a/dojox/editor/plugins/StatusBar.js b/dojox/editor/plugins/StatusBar.js
index 4a2b28c..ea93133 100755
--- a/dojox/editor/plugins/StatusBar.js
+++ b/dojox/editor/plugins/StatusBar.js
@@ -1,7 +1,17 @@
-define("dojox/editor/plugins/StatusBar", ["dojo", "dijit", "dojox", "dijit/Toolbar", "dijit/_editor/_Plugin", "dojox/layout/ResizeHandle", "dojo/i18n", "i18n!dojox/editor/plugins/nls/StatusBar"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dijit/_editor/_Plugin",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojox/layout/ResizeHandle"
+], function(dojo, dijit, dojox) {
 
 dojo.experimental("dojox.editor.plugins.StatusBar");
-dojo.declare("dojox.editor.plugins._StatusBar", [dijit._Widget, dijit._Templated],{
+dojo.declare("dojox.editor.plugins._StatusBar", [dijit._Widget, dijit._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.
diff --git a/dojox/editor/plugins/TablePlugins.js b/dojox/editor/plugins/TablePlugins.js
index f5b1d52..0743d75 100644
--- a/dojox/editor/plugins/TablePlugins.js
+++ b/dojox/editor/plugins/TablePlugins.js
@@ -1,4 +1,31 @@
-define("dojox/editor/plugins/TablePlugins", ["dojo", "dijit", "dojox", "dijit/form/Button", "dijit/Dialog", "dijit/form/TextBox", "dijit/form/FilteringSelect", "dijit/_editor/_Plugin", "dijit/_editor/selection", "dijit/Menu", "dijit/ColorPalette", "dojox/widget/ColorPicker", "dojo/i18n", "i18n!dojox/editor/plugins/nls/TableDialog"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/_base/popup",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dijit/_WidgetsInTemplateMixin",
+	"dijit/Menu",
+	"dijit/MenuItem",
+	"dijit/MenuSeparator",
+	"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) {
 
 dojo.experimental("dojox.editor.plugins.TablePlugins");
 
@@ -247,8 +274,8 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 			return true;
 		}
 		
-		// Only return avalable if the editor is focused.
-		this.currentlyAvailable = this.editor._focused ? this.editor.hasAncestorElement("table") : false;
+		// Only return available if the editor is focused.
+		this.currentlyAvailable = this.editor.focused ? this.editor.hasAncestorElement("table") : false;
 		
 		if(this.currentlyAvailable){
 			this.connectTableKeys();
@@ -794,7 +821,7 @@ dojo.declare("dojox.editor.plugins.ModifyTable",
 		}
 });
 
-dojo.declare("dojox.editor.plugins._CellColorDropDown", [dijit._Widget, dijit._Templated], {
+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.
@@ -949,13 +976,12 @@ dojo.declare("dojox.editor.plugins.ColorTableCell", dojox.editor.plugins.TablePl
 		}
 });
 
-dojo.declare("dojox.editor.plugins.EditorTableDialog", [dijit.Dialog], {
+dojo.declare("dojox.editor.plugins.EditorTableDialog", [dijit.Dialog, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
 	// summary:
 	//		Dialog box with options for table creation
-	//
+
 	baseClass:"EditorTableDialog",
 				
-	widgetsInTemplate:true,
 	templateString: dojo.cache("dojox.editor.plugins", "resources/insertTable.html"),
 
 	postMixInProperties: function(){
@@ -989,7 +1015,7 @@ dojo.declare("dojox.editor.plugins.EditorTableDialog", [dijit.Dialog], {
 			}
 			t += '\t</tr>\n';
 		}
-		t += '</table>';
+		t += '</table><br />';
 		
 		//console.log(t);
 		this.onBuildTable({htmlText:t, id:_id});
@@ -1021,7 +1047,7 @@ dojo.declare("dojox.editor.plugins.EditorTableDialog", [dijit.Dialog], {
 	}
 });
 
-dojo.declare("dojox.editor.plugins.EditorModifyTableDialog", [dijit.Dialog], {
+dojo.declare("dojox.editor.plugins.EditorModifyTableDialog", [dijit.Dialog, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
 	
 	// summary:
 	//		Dialog box with options for editing a table
@@ -1029,7 +1055,6 @@ dojo.declare("dojox.editor.plugins.EditorModifyTableDialog", [dijit.Dialog], {
 	
 	baseClass:"EditorTableDialog",
 
-	widgetsInTemplate:true,
 	table:null, //html table to be modified
 	tableAtts:{},
 	templateString: dojo.cache("dojox.editor.plugins", "resources/modifyTable.html"),
diff --git a/dojox/editor/plugins/TextColor.js b/dojox/editor/plugins/TextColor.js
index 6e8ef21..1ebc8e9 100755
--- a/dojox/editor/plugins/TextColor.js
+++ b/dojox/editor/plugins/TextColor.js
@@ -1,7 +1,24 @@
-define("dojox/editor/plugins/TextColor", ["dojo", "dijit", "dojox", "dijit/TooltipDialog", "dijit/form/Button", "dijit/_editor/_Plugin", "dojox/widget/ColorPicker", "dojo/i18n", "i18n!dojox/editor/plugins/nls/TextColor"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/_base/popup",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dijit/_WidgetsInTemplateMixin",
+	"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) {
 
 dojo.experimental("dojox.editor.plugins.TextColor");
-dojo.declare("dojox.editor.plugins._TextColorDropDown", [dijit._Widget, dijit._Templated], {
+dojo.declare("dojox.editor.plugins._TextColorDropDown", [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.
diff --git a/dojox/editor/plugins/ToolbarLineBreak.js b/dojox/editor/plugins/ToolbarLineBreak.js
index 0802309..8c47c62 100755
--- a/dojox/editor/plugins/ToolbarLineBreak.js
+++ b/dojox/editor/plugins/ToolbarLineBreak.js
@@ -1,11 +1,16 @@
-define("dojox/editor/plugins/ToolbarLineBreak", ["dojo", "dijit", "dojox", "dijit/_Widget", "dijit/_Templated", "dijit/_editor/_Plugin"], function(dojo, dijit, dojox) {
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._editor._Plugin");
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dijit/_editor/_Plugin",
+	"dojo/_base/connect",
+	"dojo/_base/declare"
+], function(dojo, dijit, dojox) {
 
 dojo.declare("dojox.editor.plugins.ToolbarLineBreak",
-	[ dijit._Widget, dijit._Templated ],
+	[ dijit._Widget, dijit._TemplatedMixin ],
 	{
 	// summary:
 	//		A 'line break' between two `dijit.Toolbar` items so that very
diff --git a/dojox/editor/plugins/UploadImage.js b/dojox/editor/plugins/UploadImage.js
index aab5417..0fc294e 100644
--- a/dojox/editor/plugins/UploadImage.js
+++ b/dojox/editor/plugins/UploadImage.js
@@ -1,4 +1,13 @@
-define("dojox/editor/plugins/UploadImage", ["dojo", "dijit", "dojox", "dojox/form/FileUploader", "dijit/_editor/_Plugin"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/_editor/_Plugin",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojox/form/FileUploader",
+	"dijit/_editor/_Plugin"
+], function(dojo, dijit, dojox) {
 
 dojo.experimental("dojox.editor.plugins.UploadImage");
 
diff --git a/dojox/editor/plugins/_SmileyPalette.js b/dojox/editor/plugins/_SmileyPalette.js
index 4909cd1..070cee7 100644
--- a/dojox/editor/plugins/_SmileyPalette.js
+++ b/dojox/editor/plugins/_SmileyPalette.js
@@ -1,9 +1,20 @@
-define("dojox/editor/plugins/_SmileyPalette", ["dojo", "dijit", "dojox", "dijit/_Widget", "dijit._PaletteMixin", "dojo/i18n", "i18n!dojox/editor/plugins/nls/Smiley"], function(dojo, dijit, dojox) {
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dijit/_PaletteMixin",
+	"dojo/_base/connect",
+	"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._Templated, dijit._PaletteMixin],
+	[dijit._Widget, dijit._TemplatedMixin, dijit._PaletteMixin],
 	{
 	// summary:
 	//		A keyboard accessible emoticon-picking widget (for inserting smiley characters)
diff --git a/dojox/editor/plugins/_SpellCheckParser.js b/dojox/editor/plugins/_SpellCheckParser.js
index 02516f6..4dfd975 100644
--- a/dojox/editor/plugins/_SpellCheckParser.js
+++ b/dojox/editor/plugins/_SpellCheckParser.js
@@ -1,4 +1,9 @@
-define("dojox/editor/plugins/_SpellCheckParser", ["dojo", "dojox"], function(dojo, dojox) {
+define([
+	"dojo",
+	"dojox",
+	"dojo/_base/connect",
+	"dojo/_base/declare"
+], function(dojo, dojox) {
 
 dojo.declare("dojox.editor.plugins._SpellCheckParser", null, {
 	lang: "english",
diff --git a/dojox/editor/plugins/nls/AutoSave.js b/dojox/editor/plugins/nls/AutoSave.js
index 655451f..35706b9 100644
--- a/dojox/editor/plugins/nls/AutoSave.js
+++ b/dojox/editor/plugins/nls/AutoSave.js
@@ -1,3 +1,5 @@
+define({ root:
+//begin v1.x content
 ({
 	"saveLabel": "Save",
 	"saveSettingLabelOn": "Set Auto-Save Interval...",
@@ -11,3 +13,36 @@
 	"saveMessageSuccess": "Saved at ${0}",
 	"saveMessageFail": "Failed to save at ${0}"
 })
+,
+//end v1.x content
+"zh": true,
+"zh-tw": 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,
+"ar": true
+});
diff --git a/dojox/editor/plugins/nls/Blockquote.js b/dojox/editor/plugins/nls/Blockquote.js
index 423f216..6459f62 100755
--- a/dojox/editor/plugins/nls/Blockquote.js
+++ b/dojox/editor/plugins/nls/Blockquote.js
@@ -1,3 +1,38 @@
+define({ root:
+//begin v1.x content
 ({
 	"blockquote": "Blockquote"
-})
\ No newline at end of file
+})
+,
+//end v1.x content
+"zh": true,
+"zh-tw": 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,
+"ar": true
+});
diff --git a/dojox/editor/plugins/nls/Breadcrumb.js b/dojox/editor/plugins/nls/Breadcrumb.js
index 26a8ee7..2a58313 100755
--- a/dojox/editor/plugins/nls/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/Breadcrumb.js
@@ -1,3 +1,5 @@
+define({ root:
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName} Actions",
 	"selectContents": "Select contents",
@@ -7,3 +9,36 @@
 	"moveStart": "Move cursor to start",
 	"moveEnd": "Move cursor to end"
 })
+,
+//end v1.x content
+"zh": true,
+"zh-tw": 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,
+"ar": true
+});
diff --git a/dojox/editor/plugins/nls/CollapsibleToolbar.js b/dojox/editor/plugins/nls/CollapsibleToolbar.js
index 13dd736..ebfdb3d 100755
--- a/dojox/editor/plugins/nls/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/CollapsibleToolbar.js
@@ -1,4 +1,39 @@
+define({ root:
+//begin v1.x content
 ({
 	"collapse": "Collapse Editor Toolbar",
 	"expand": "Expand Editor Toolbar"
-})
\ No newline at end of file
+})
+,
+//end v1.x content
+"zh": true,
+"zh-tw": 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,
+"ar": true
+});
diff --git a/dojox/editor/plugins/nls/FindReplace.js b/dojox/editor/plugins/nls/FindReplace.js
index 21cff9a..7584948 100755
--- a/dojox/editor/plugins/nls/FindReplace.js
+++ b/dojox/editor/plugins/nls/FindReplace.js
@@ -1,3 +1,5 @@
+define({ root:
+//begin v1.x content
 ({
 	"findLabel": "Find:",
 	"findTooltip": "Enter text to find",
@@ -19,3 +21,36 @@
 	"eofDialogTextFind": "found",
 	"eofDialogTextReplace": "replaced"
 })
+,
+//end v1.x content
+"zh": true,
+"zh-tw": 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,
+"ar": true
+});
diff --git a/dojox/editor/plugins/nls/InsertAnchor.js b/dojox/editor/plugins/nls/InsertAnchor.js
index 4470ebe..12eabe8 100755
--- a/dojox/editor/plugins/nls/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/InsertAnchor.js
@@ -1,3 +1,5 @@
+define({ root:
+//begin v1.x content
 ({
 	insertAnchor: "Insert Anchor",
 	title: "Anchor Properties",
@@ -6,3 +8,36 @@
 	set: "Set",
 	cancel: "Cancel"
 })
+,
+//end v1.x content
+"zh": true,
+"zh-tw": 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,
+"ar": true
+});
diff --git a/dojox/editor/plugins/nls/InsertEntity.js b/dojox/editor/plugins/nls/InsertEntity.js
index 9342d16..7c70ee0 100755
--- a/dojox/editor/plugins/nls/InsertEntity.js
+++ b/dojox/editor/plugins/nls/InsertEntity.js
@@ -1,3 +1,38 @@
+define({ root:
+//begin v1.x content
 ({
 	insertEntity: "Insert Symbol"
-})
\ No newline at end of file
+})
+,
+//end v1.x content
+"zh": true,
+"zh-tw": 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,
+"ar": true
+});
diff --git a/dojox/editor/plugins/nls/LocalImage.js b/dojox/editor/plugins/nls/LocalImage.js
index d8bfed3..646901b 100644
--- a/dojox/editor/plugins/nls/LocalImage.js
+++ b/dojox/editor/plugins/nls/LocalImage.js
@@ -1,3 +1,5 @@
+define({ root:
+//begin v1.x content
 ({
 	insertImageTitle: "Insert Image",
 	url: "Image",
@@ -8,3 +10,36 @@
 	prePopuTextUrl: "Enter an image URL",
 	prePopuTextBrowse: " or browse to a local file."
 })
+,
+//end v1.x content
+"zh": true,
+"zh-tw": 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,
+"ar": true
+});
diff --git a/dojox/editor/plugins/nls/PageBreak.js b/dojox/editor/plugins/nls/PageBreak.js
index 4f06fd6..ebfbe39 100755
--- a/dojox/editor/plugins/nls/PageBreak.js
+++ b/dojox/editor/plugins/nls/PageBreak.js
@@ -1,3 +1,38 @@
+define({ root:
+//begin v1.x content
 ({
 	"pageBreak": "Page Break"
-})
\ No newline at end of file
+})
+,
+//end v1.x content
+"zh": true,
+"zh-tw": 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,
+"ar": true
+});
diff --git a/dojox/editor/plugins/nls/PasteFromWord.js b/dojox/editor/plugins/nls/PasteFromWord.js
index c062165..da39440 100755
--- a/dojox/editor/plugins/nls/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/PasteFromWord.js
@@ -1,6 +1,40 @@
+define({ root:
+//begin v1.x content
 ({
-	"pasteFromWord": "Paste From  Word",
+	"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."
-})
\ No newline at end of file
+}),
+//end v1.x content
+"zh": true,
+"zh-tw": 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,
+"ar": true
+});
diff --git a/dojox/editor/plugins/nls/Preview.js b/dojox/editor/plugins/nls/Preview.js
index 25d3e81..82752e5 100755
--- a/dojox/editor/plugins/nls/Preview.js
+++ b/dojox/editor/plugins/nls/Preview.js
@@ -1,3 +1,38 @@
+define({ root:
+//begin v1.x content
 ({
 	"preview": "Preview"
-})
\ No newline at end of file
+})
+,
+//end v1.x content
+"zh": true,
+"zh-tw": 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,
+"ar": true
+});
diff --git a/dojox/editor/plugins/nls/SafePaste.js b/dojox/editor/plugins/nls/SafePaste.js
new file mode 100644
index 0000000..876836c
--- /dev/null
+++ b/dojox/editor/plugins/nls/SafePaste.js
@@ -0,0 +1,35 @@
+define({ root:
+//begin v1.x content
+({
+	"instructions": "Direct paste is disabled.  Please paste content in this dialog using the standard browser keyboard or menu paste controls.  Once you are satisfied with the content to insert, press the paste button.  To abort inserting content, press the cancel button."
+})
+//end v1.x content
+,
+"zh": true,
+"zh-tw": true,
+"tr": true,
+"th": true,
+"sv": true,
+"sl": true,
+"sk": true,
+"ru": true,
+"ro": true,
+"pt": true,
+"pl": true,
+"nl": true,
+"nb": true,
+"ko": true,
+"kk": true,
+"ja": true,
+"it": true,
+"hu": true,
+"hr": true,
+"fr": true,
+"fi": true,
+"es": true,
+"el": true,
+"de": true,
+"da": true,
+"cs": true,
+"ca": true
+});
diff --git a/dojox/editor/plugins/nls/Save.js b/dojox/editor/plugins/nls/Save.js
index 253100a..2284a04 100755
--- a/dojox/editor/plugins/nls/Save.js
+++ b/dojox/editor/plugins/nls/Save.js
@@ -1,3 +1,38 @@
+define({ root:
+//begin v1.x content
 ({
 	"save": "Save"
-})
\ No newline at end of file
+})
+,
+//end v1.x content
+"zh": true,
+"zh-tw": 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,
+"ar": true
+});
diff --git a/dojox/editor/plugins/nls/ShowBlockNodes.js b/dojox/editor/plugins/nls/ShowBlockNodes.js
index bc84151..0508a4d 100755
--- a/dojox/editor/plugins/nls/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/ShowBlockNodes.js
@@ -1,3 +1,38 @@
+define({ root:
+//begin v1.x content
 ({
 	"showBlockNodes": "Show HTML Block Elements"
 })
+,
+//end v1.x content
+"zh": true,
+"zh-tw": 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,
+"ar": true
+});
diff --git a/dojox/editor/plugins/nls/Smiley.js b/dojox/editor/plugins/nls/Smiley.js
index 522ce50..c2a4cfb 100644
--- a/dojox/editor/plugins/nls/Smiley.js
+++ b/dojox/editor/plugins/nls/Smiley.js
@@ -1,3 +1,5 @@
+define({ root:
+//begin v1.x content
 ({
 	smiley: "Insert Emoticon",
 	emoticonSmile: "smile",
@@ -17,5 +19,39 @@
 	emoticonYes: "yes",
 	emoticonNo: "no",
 	emoticonAngel: "angel",
-	emoticonCrying: "crying"
+	emoticonCrying: "crying",
+	emoticonHappy: "happy"
 })
+,
+//end v1.x content
+"zh": true,
+"zh-tw": 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,
+"ar": true
+});
diff --git a/dojox/editor/plugins/nls/SpellCheck.js b/dojox/editor/plugins/nls/SpellCheck.js
index 07faeb9..b0ce6c0 100644
--- a/dojox/editor/plugins/nls/SpellCheck.js
+++ b/dojox/editor/plugins/nls/SpellCheck.js
@@ -1,3 +1,5 @@
+define({ root:
+//begin v1.x content
 ({
 	widgetLabel: "Batch Spell Check",
 	unfound: "Not found",
@@ -14,3 +16,36 @@
 	iSkipAll: "Skip all like this",
 	iMsg: "No spelling suggestions"
 })
+,
+//end v1.x content
+"zh": true,
+"zh-tw": 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,
+"ar": true
+});
diff --git a/dojox/editor/plugins/nls/TableDialog.js b/dojox/editor/plugins/nls/TableDialog.js
index 6130f3b..0a23cf1 100644
--- a/dojox/editor/plugins/nls/TableDialog.js
+++ b/dojox/editor/plugins/nls/TableDialog.js
@@ -1,3 +1,5 @@
+define({ root:
+//begin v1.x content
 ({
 	insertTableTitle: "Insert Table",
 	modifyTableTitle: "Modify Table",
@@ -28,4 +30,37 @@
 	deleteTableRowLabel: "Delete Row",
 	deleteTableColumnLabel: "Delete Column"
 })
-	
\ No newline at end of file
+,
+//end v1.x content
+"zh": true,
+"zh-tw": 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,
+"az": true,
+"ar": true
+});
diff --git a/dojox/editor/plugins/nls/TextColor.js b/dojox/editor/plugins/nls/TextColor.js
index 3a623ab..d1672d9 100755
--- a/dojox/editor/plugins/nls/TextColor.js
+++ b/dojox/editor/plugins/nls/TextColor.js
@@ -1,4 +1,39 @@
+define({ root:
+//begin v1.x content
 ({
 	"setButtonText": "Set",
 	"cancelButtonText": "Cancel"
 })
+,
+//end v1.x content
+"zh": true,
+"zh-tw": 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,
+"ar": true
+});
diff --git a/dojox/editor/plugins/nls/ar/AutoSave.js b/dojox/editor/plugins/nls/ar/AutoSave.js
index ba5c591..ce79d42 100644
--- a/dojox/editor/plugins/nls/ar/AutoSave.js
+++ b/dojox/editor/plugins/nls/ar/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "حفظ",
 	"saveSettingLabelOn": "تحديد الفترة الزمنية للحفظ الآلي...",
@@ -12,3 +14,5 @@
 	"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 48194c3..c708330 100644
--- a/dojox/editor/plugins/nls/ar/Blockquote.js
+++ b/dojox/editor/plugins/nls/ar/Blockquote.js
@@ -1,4 +1,8 @@
+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 7b0cccf..c4b7513 100644
--- a/dojox/editor/plugins/nls/ar/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/ar/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName} تصرفات",
 	"selectContents": "تحديد المحتويات",
@@ -8,3 +10,5 @@
 	"moveEnd": "نقل المؤشر للنهاية"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ar/CollapsibleToolbar.js b/dojox/editor/plugins/nls/ar/CollapsibleToolbar.js
index 6811d2c..de9d828 100644
--- a/dojox/editor/plugins/nls/ar/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/ar/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 0f45207..4ecdb29 100644
--- a/dojox/editor/plugins/nls/ar/FindReplace.js
+++ b/dojox/editor/plugins/nls/ar/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "ايجاد:",
 	"findTooltip": "ادخال نص لايجاد",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "مطابقة حالة الحروف",
 	"backwards": "الى الوراء",
 	"backwardsTooltip": "البحث الى الوراء عن نص",
-	"replaceAll": "كل التكرارات",
 	"replaceAllButton": "استبدال كل",
 	"replaceAllButtonTooltip": "استبدال كل النص",
 	"findButton": "ايجاد",
@@ -21,3 +22,5 @@
 	"eofDialogTextReplace": "مستبدل"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ar/InsertAnchor.js b/dojox/editor/plugins/nls/ar/InsertAnchor.js
index 351f9b8..acaa18a 100644
--- a/dojox/editor/plugins/nls/ar/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/ar/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "ادراج نقطة التثبيت",
 	title: "خصائص نقطة التثبيت",
@@ -7,3 +9,5 @@
 	cancel: "الغاء"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ar/InsertEntity.js b/dojox/editor/plugins/nls/ar/InsertEntity.js
index 6ac1b72..4b3cbc1 100644
--- a/dojox/editor/plugins/nls/ar/InsertEntity.js
+++ b/dojox/editor/plugins/nls/ar/InsertEntity.js
@@ -1,4 +1,8 @@
+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 f61f2ad..147ef33 100644
--- a/dojox/editor/plugins/nls/ar/LocalImage.js
+++ b/dojox/editor/plugins/nls/ar/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "ادراج صورة",
 	url: "صورة",
@@ -9,3 +11,5 @@
 	prePopuTextBrowse: " أو تصفح الى ملف محلي."
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ar/PageBreak.js b/dojox/editor/plugins/nls/ar/PageBreak.js
index ea4675d..2d11a5a 100644
--- a/dojox/editor/plugins/nls/ar/PageBreak.js
+++ b/dojox/editor/plugins/nls/ar/PageBreak.js
@@ -1,4 +1,8 @@
+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 211ff4a..7a19b66 100644
--- a/dojox/editor/plugins/nls/ar/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/ar/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "لصق من Word",
 	"paste": "لصق",
@@ -5,3 +7,5 @@
 	"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 419fdb8..717daa3 100644
--- a/dojox/editor/plugins/nls/ar/Preview.js
+++ b/dojox/editor/plugins/nls/ar/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "معاينة"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ar/Save.js b/dojox/editor/plugins/nls/ar/Save.js
index 6b589b2..f193609 100644
--- a/dojox/editor/plugins/nls/ar/Save.js
+++ b/dojox/editor/plugins/nls/ar/Save.js
@@ -1,4 +1,8 @@
+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 d8fb3ca..43a4968 100644
--- a/dojox/editor/plugins/nls/ar/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/ar/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 9031c30..aac1581 100644
--- a/dojox/editor/plugins/nls/ar/Smiley.js
+++ b/dojox/editor/plugins/nls/ar/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "ادراج شكل متحرك",
 	emoticonSmile: "ابتسامة",
@@ -20,3 +22,5 @@
 	emoticonCrying: "يبكي"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ar/SpellCheck.js b/dojox/editor/plugins/nls/ar/SpellCheck.js
index d07e035..7c1cc84 100644
--- a/dojox/editor/plugins/nls/ar/SpellCheck.js
+++ b/dojox/editor/plugins/nls/ar/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "فحص هجاء دفعي",
 	unfound: "غير موجودة",
@@ -15,3 +17,5 @@
 	iMsg: "لا توجد اقتراحات للهجاء"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ar/TableDialog.js b/dojox/editor/plugins/nls/ar/TableDialog.js
index a474e51..dd64023 100644
--- a/dojox/editor/plugins/nls/ar/TableDialog.js
+++ b/dojox/editor/plugins/nls/ar/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "‏ادراج جدول‏",
 	modifyTableTitle: "تعديل جدول",
@@ -28,3 +30,5 @@
 	deleteTableRowLabel: "حذف صف",
 	deleteTableColumnLabel: "حذف عمود"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ar/TextColor.js b/dojox/editor/plugins/nls/ar/TextColor.js
index 90a9aa3..9acb9d2 100644
--- a/dojox/editor/plugins/nls/ar/TextColor.js
+++ b/dojox/editor/plugins/nls/ar/TextColor.js
@@ -1,5 +1,9 @@
+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 df844ac..6072590 100644
--- a/dojox/editor/plugins/nls/ar/latinEntities.js
+++ b/dojox/editor/plugins/nls/ar/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	euro:"علامة اليورو"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/az/TableDialog.js b/dojox/editor/plugins/nls/az/TableDialog.js
new file mode 100644
index 0000000..84bcec2
--- /dev/null
+++ b/dojox/editor/plugins/nls/az/TableDialog.js
@@ -0,0 +1,31 @@
+define(
+({
+	"buttonSet" : "Yönəlt",
+	"insertTableTitle" : "Cədvəl əlavə et",
+	"insertTableRowAfterLabel" : "Sətirin sonuna əlavə et",
+	"center" : "orta",
+	"deleteTableColumnLabel" : "Sütunu Sil",
+	"right" : "sağ",
+	"insertTableColumnBeforeLabel" : "Sütunu əvvəlinə əlavə et",
+	"tableWidth" : "Cədvəl Genişliyi",
+	"buttonInsert" : "Əlavə et",
+	"buttonCancel" : "Ləğv et",
+	"default" : "varsayılan",
+	"align" : "Doğrult:",
+	"insertTableRowBeforeLabel" : "Sətiri əvvəlinə əlavə et",
+	"cellSpacing" : "Hücrə Aralığı:",
+	"pixels" : "piksel",
+	"selectTableLabel" : "Cədvəl Seç",
+	"rows" : "Sətirlər:",
+	"modifyTableTitle" : "Cədvəli Dəyişdir",
+	"cellPadding" : "Hücrə Doldurmaq:",
+	"deleteTableRowLabel" : "Sətiri Sil",
+	"backgroundColor" : "Arxa Plan Rəngi:",
+	"insertTableColumnAfterLabel" : "Sütunu Arxasına əlavə et",
+	"left" : "sol",
+	"borderThickness" : "Çərçivə Qalınlığı",
+	"columns" : "Sütunlar:",
+	"percent" : "faiz",
+	"borderColor" : "Çərçivə Rəngi: "
+})
+);
diff --git a/dojox/editor/plugins/nls/ca/AutoSave.js b/dojox/editor/plugins/nls/ca/AutoSave.js
index 33b62c1..92dd5ea 100644
--- a/dojox/editor/plugins/nls/ca/AutoSave.js
+++ b/dojox/editor/plugins/nls/ca/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Desa",
 	"saveSettingLabelOn": "Estableix l'interval per desar automàticament...",
@@ -12,3 +14,5 @@
 	"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 859084b..e54a9ba 100644
--- a/dojox/editor/plugins/nls/ca/Blockquote.js
+++ b/dojox/editor/plugins/nls/ca/Blockquote.js
@@ -1,4 +1,8 @@
+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 41d0ed1..2e34c2a 100644
--- a/dojox/editor/plugins/nls/ca/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/ca/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName} - Accions",
 	"selectContents": "Selecciona contingut",
@@ -8,3 +10,5 @@
 	"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 94daaec..e5bd268 100644
--- a/dojox/editor/plugins/nls/ca/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/ca/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 e0429d1..6a7bb4c 100644
--- a/dojox/editor/plugins/nls/ca/FindReplace.js
+++ b/dojox/editor/plugins/nls/ca/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Cerca:",
 	"findTooltip": "Especifiqueu el text que voleu trobar",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "Coincidència de majúscules i minúscules",
 	"backwards": "Cap enrere",
 	"backwardsTooltip": "Cerca text cap enrere",
-	"replaceAll": "Totes les aparicions",
 	"replaceAllButton": "Substitueix tot",
 	"replaceAllButtonTooltip": "Substitueix tot el text",
 	"findButton": "Cerca",
@@ -21,3 +22,5 @@
 	"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 2f40546..86704f9 100644
--- a/dojox/editor/plugins/nls/ca/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/ca/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Insereix una àncora",
 	title: "Propietats de l'àncora",
@@ -7,3 +9,5 @@
 	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 c2cff1b..e96234b 100644
--- a/dojox/editor/plugins/nls/ca/InsertEntity.js
+++ b/dojox/editor/plugins/nls/ca/InsertEntity.js
@@ -1,4 +1,8 @@
+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 a27cced..fdc1957 100644
--- a/dojox/editor/plugins/nls/ca/LocalImage.js
+++ b/dojox/editor/plugins/nls/ca/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Insereix imatge",
 	url: "Imatge",
@@ -9,3 +11,5 @@
 	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 cd56c5c..d7c2e36 100644
--- a/dojox/editor/plugins/nls/ca/PageBreak.js
+++ b/dojox/editor/plugins/nls/ca/PageBreak.js
@@ -1,4 +1,8 @@
+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 f971b08..3ddc705 100644
--- a/dojox/editor/plugins/nls/ca/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/ca/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Enganxa des de Word",
 	"paste": "Enganxa",
@@ -5,3 +7,5 @@
 	"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 40a446c..1049be0 100644
--- a/dojox/editor/plugins/nls/ca/Preview.js
+++ b/dojox/editor/plugins/nls/ca/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "Visualització prèvia"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ca/SafePaste.js b/dojox/editor/plugins/nls/ca/SafePaste.js
new file mode 100644
index 0000000..4f4db12
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "L'acció d'enganxar dades directament està inhabilitada. Enganxeu el contingut d'aquest diàleg amb el teclat del navegador estàndard o amb els controls d'enganxament del menú. Quan estigueu satisfet amb el contingut que cal inserir, premeu el botó per enganxar-lo. Per avortar la inserció de contingut, premeu el botó per cancel·lar."
+})
+);
diff --git a/dojox/editor/plugins/nls/ca/Save.js b/dojox/editor/plugins/nls/ca/Save.js
index 5ab9ef5..1fb2c0d 100644
--- a/dojox/editor/plugins/nls/ca/Save.js
+++ b/dojox/editor/plugins/nls/ca/Save.js
@@ -1,4 +1,8 @@
+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 1fbccc9..cd7e8fd 100644
--- a/dojox/editor/plugins/nls/ca/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/ca/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 101a542..4205666 100644
--- a/dojox/editor/plugins/nls/ca/Smiley.js
+++ b/dojox/editor/plugins/nls/ca/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Insereix emoticona",
 	emoticonSmile: "somriure",
@@ -17,6 +19,9 @@
 	emoticonYes: "sí",
 	emoticonNo: "no",
 	emoticonAngel: "àngel",
-	emoticonCrying: "plorant"
+	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 80dc34f..c438188 100644
--- a/dojox/editor/plugins/nls/ca/SpellCheck.js
+++ b/dojox/editor/plugins/nls/ca/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Correcció ortogràfica per lots",
 	unfound: "No trobat",
@@ -15,3 +17,5 @@
 	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 1420bc1..eb55edb 100644
--- a/dojox/editor/plugins/nls/ca/TableDialog.js
+++ b/dojox/editor/plugins/nls/ca/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Insereix taula",
 	modifyTableTitle: "Modifica taula",
@@ -28,3 +30,5 @@
 	deleteTableRowLabel: "Suprimeix fila",
 	deleteTableColumnLabel: "Suprimeix columna"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ca/TextColor.js b/dojox/editor/plugins/nls/ca/TextColor.js
index b550bea..ded7693 100644
--- a/dojox/editor/plugins/nls/ca/TextColor.js
+++ b/dojox/editor/plugins/nls/ca/TextColor.js
@@ -1,5 +1,9 @@
+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 7e1c56d..a39d4e1 100644
--- a/dojox/editor/plugins/nls/ca/latinEntities.js
+++ b/dojox/editor/plugins/nls/ca/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	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 711c7b1..38710b6 100644
--- a/dojox/editor/plugins/nls/cs/AutoSave.js
+++ b/dojox/editor/plugins/nls/cs/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Uložit",
 	"saveSettingLabelOn": "Nastavit interval pro automatické uložení",
@@ -12,3 +14,5 @@
 	"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 3016648..671219c 100644
--- a/dojox/editor/plugins/nls/cs/Blockquote.js
+++ b/dojox/editor/plugins/nls/cs/Blockquote.js
@@ -1,4 +1,8 @@
+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 b1ca156..d05a639 100644
--- a/dojox/editor/plugins/nls/cs/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/cs/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "Akce uzlu ${nodeName}",
 	"selectContents": "Vybrat obsah",
@@ -8,3 +10,5 @@
 	"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 df9a95c..0ee257b 100644
--- a/dojox/editor/plugins/nls/cs/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/cs/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 19d7922..2689f4c 100644
--- a/dojox/editor/plugins/nls/cs/FindReplace.js
+++ b/dojox/editor/plugins/nls/cs/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Najít:",
 	"findTooltip": "Zadejte hledaný text.",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "S rozlišením velkých a malých písmen",
 	"backwards": "V opačném směru",
 	"backwardsTooltip": "Hledat text v opačném směru",
-	"replaceAll": "Všechny výskyty",
 	"replaceAllButton": "Nahradit vše",
 	"replaceAllButtonTooltip": "Nahradit všechen text",
 	"findButton": "Najít",
@@ -20,3 +21,5 @@
 	"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 54bb097..86cc6ad 100644
--- a/dojox/editor/plugins/nls/cs/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/cs/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Vložit kotvu",
 	title: "Vlastnosti kotvy",
@@ -7,3 +9,5 @@
 	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 b66cbdf..b291fdd 100644
--- a/dojox/editor/plugins/nls/cs/InsertEntity.js
+++ b/dojox/editor/plugins/nls/cs/InsertEntity.js
@@ -1,4 +1,8 @@
+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 5e2ab2a..a5e34e9 100644
--- a/dojox/editor/plugins/nls/cs/LocalImage.js
+++ b/dojox/editor/plugins/nls/cs/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Vložit obrázek",
 	url: "Obrázek",
@@ -9,3 +11,5 @@
 	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 f8088d0..f83f61f 100644
--- a/dojox/editor/plugins/nls/cs/PageBreak.js
+++ b/dojox/editor/plugins/nls/cs/PageBreak.js
@@ -1,4 +1,8 @@
+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 2a6329d..6f743dd 100644
--- a/dojox/editor/plugins/nls/cs/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/cs/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Vložit z aplikace Word",
 	"paste": "Vložit",
@@ -5,3 +7,5 @@
 	"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 f052206..987a780 100644
--- a/dojox/editor/plugins/nls/cs/Preview.js
+++ b/dojox/editor/plugins/nls/cs/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "Náhled"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/cs/SafePaste.js b/dojox/editor/plugins/nls/cs/SafePaste.js
new file mode 100644
index 0000000..4583c20
--- /dev/null
+++ b/dojox/editor/plugins/nls/cs/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "Přímé vložení je zakázáno. Vložte obsah do tohoto dialogového okna pomocí standardní klávesové zkratky nebo nabídky prohlížeče. Jakmile jste s vkládaným obsahem spokojeni, stiskněte tlačítko Vložit. Pomocí tlačítka Storno vkládání zrušíte."
+})
+);
diff --git a/dojox/editor/plugins/nls/cs/Save.js b/dojox/editor/plugins/nls/cs/Save.js
index 4e4e8a3..dc8988a 100644
--- a/dojox/editor/plugins/nls/cs/Save.js
+++ b/dojox/editor/plugins/nls/cs/Save.js
@@ -1,4 +1,8 @@
+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 4812158..85093c4 100644
--- a/dojox/editor/plugins/nls/cs/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/cs/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 9dd6953..045e968 100644
--- a/dojox/editor/plugins/nls/cs/Smiley.js
+++ b/dojox/editor/plugins/nls/cs/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Vložit emotikonu",
 	emoticonSmile: "úsměv",
@@ -17,6 +19,9 @@
 	emoticonYes: "ano",
 	emoticonNo: "ne",
 	emoticonAngel: "anděl",
-	emoticonCrying: "pláč"
+	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 48f65bf..e07ef93 100644
--- a/dojox/editor/plugins/nls/cs/SpellCheck.js
+++ b/dojox/editor/plugins/nls/cs/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Dávková kontrola pravopisu",
 	unfound: "Nenalezeno",
@@ -15,3 +17,5 @@
 	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 867b610..3d9a484 100644
--- a/dojox/editor/plugins/nls/cs/TableDialog.js
+++ b/dojox/editor/plugins/nls/cs/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Vložit tabulku",
 	modifyTableTitle: "Upravit tabulku",
@@ -28,3 +30,5 @@
 	deleteTableRowLabel: "Odstranit řádek",
 	deleteTableColumnLabel: "Odstranit sloupec"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/cs/TextColor.js b/dojox/editor/plugins/nls/cs/TextColor.js
index cc460e7..7cfd1e8 100644
--- a/dojox/editor/plugins/nls/cs/TextColor.js
+++ b/dojox/editor/plugins/nls/cs/TextColor.js
@@ -1,5 +1,9 @@
+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 bc45582..962063e 100644
--- a/dojox/editor/plugins/nls/cs/latinEntities.js
+++ b/dojox/editor/plugins/nls/cs/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	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 4e45c98..f4eaf08 100644
--- a/dojox/editor/plugins/nls/da/AutoSave.js
+++ b/dojox/editor/plugins/nls/da/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Gem",
 	"saveSettingLabelOn": "Angiv interval for automatisk lagring...",
@@ -12,3 +14,5 @@
 	"saveMessageFail": "Ikke gemt i ${0}"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/da/Blockquote.js b/dojox/editor/plugins/nls/da/Blockquote.js
index cc44605..c49cea9 100644
--- a/dojox/editor/plugins/nls/da/Blockquote.js
+++ b/dojox/editor/plugins/nls/da/Blockquote.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"blockquote": "Citat"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/da/Breadcrumb.js b/dojox/editor/plugins/nls/da/Breadcrumb.js
index 73e368a..385943f 100644
--- a/dojox/editor/plugins/nls/da/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/da/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName} - handlinger",
 	"selectContents": "Vælg indhold",
@@ -8,3 +10,5 @@
 	"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 d9cb207..c066bad 100644
--- a/dojox/editor/plugins/nls/da/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/da/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 aac4e7c..93d833d 100644
--- a/dojox/editor/plugins/nls/da/FindReplace.js
+++ b/dojox/editor/plugins/nls/da/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Søg efter:",
 	"findTooltip": "Indtast tekst, der skal søges efter",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "Store/små bogstaver",
 	"backwards": "Tilbage",
 	"backwardsTooltip": "Søg baglæns efter tekst",
-	"replaceAll": "Alle forekomster",
 	"replaceAllButton": "Erstat alle",
 	"replaceAllButtonTooltip": "Erstat alle forekomster i teksten",
 	"findButton": "Søg",
@@ -21,3 +22,5 @@
 	"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 4937e12..a8fdeae 100644
--- a/dojox/editor/plugins/nls/da/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/da/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Indsæt anker",
 	title: "Ankeregenskaber",
@@ -7,3 +9,5 @@
 	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 81e2c6d..07be1cd 100644
--- a/dojox/editor/plugins/nls/da/InsertEntity.js
+++ b/dojox/editor/plugins/nls/da/InsertEntity.js
@@ -1,4 +1,8 @@
+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 1e39501..50a5933 100644
--- a/dojox/editor/plugins/nls/da/LocalImage.js
+++ b/dojox/editor/plugins/nls/da/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Indsæt billede",
 	url: "Billede",
@@ -9,3 +11,5 @@
 	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 3fdbd10..a4dd6e6 100644
--- a/dojox/editor/plugins/nls/da/PageBreak.js
+++ b/dojox/editor/plugins/nls/da/PageBreak.js
@@ -1,4 +1,8 @@
+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 4c0cab3..8859661 100644
--- a/dojox/editor/plugins/nls/da/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/da/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Sæt ind fra Word",
 	"paste": "Sæt ind",
@@ -5,3 +7,5 @@
 	"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."
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/da/Preview.js b/dojox/editor/plugins/nls/da/Preview.js
index 6c63e4c..45e3968 100644
--- a/dojox/editor/plugins/nls/da/Preview.js
+++ b/dojox/editor/plugins/nls/da/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "Eksempel"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/da/SafePaste.js b/dojox/editor/plugins/nls/da/SafePaste.js
new file mode 100644
index 0000000..04eae99
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "Direkte indsættelse er deaktiveret. Indsæt indholdet i denne dialog ved hjælp af browserens standardtaster eller menupunkter til indsættelse. Klik på knappen Indsæt, når du er tilfreds med indholdet. Tryk på knappen Annullér for at fortryde indsættelsen."
+})
+);
diff --git a/dojox/editor/plugins/nls/da/Save.js b/dojox/editor/plugins/nls/da/Save.js
index a1f3aec..802b706 100644
--- a/dojox/editor/plugins/nls/da/Save.js
+++ b/dojox/editor/plugins/nls/da/Save.js
@@ -1,4 +1,8 @@
+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 4fa9842..34da4af 100644
--- a/dojox/editor/plugins/nls/da/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/da/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 565b13f..4ad8191 100644
--- a/dojox/editor/plugins/nls/da/Smiley.js
+++ b/dojox/editor/plugins/nls/da/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Indsæt humørikon",
 	emoticonSmile: "smil",
@@ -17,6 +19,9 @@
 	emoticonYes: "ja",
 	emoticonNo: "nej",
 	emoticonAngel: "engel",
-	emoticonCrying: "græder"
+	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 901f70f..4c0f4f9 100644
--- a/dojox/editor/plugins/nls/da/SpellCheck.js
+++ b/dojox/editor/plugins/nls/da/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Bundtvis stavekontrol",
 	unfound: "Ikke fundet",
@@ -15,3 +17,5 @@
 	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 76029da..65c699c 100644
--- a/dojox/editor/plugins/nls/da/TableDialog.js
+++ b/dojox/editor/plugins/nls/da/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Indsæt tabel",
 	modifyTableTitle: "Revidér tabel",
@@ -28,3 +30,5 @@
 	deleteTableRowLabel: "Slet række",
 	deleteTableColumnLabel: "Slet kolonne"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/da/TextColor.js b/dojox/editor/plugins/nls/da/TextColor.js
index dffe0b2..dbdfb23 100644
--- a/dojox/editor/plugins/nls/da/TextColor.js
+++ b/dojox/editor/plugins/nls/da/TextColor.js
@@ -1,5 +1,9 @@
+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 d45abcf..d512430 100644
--- a/dojox/editor/plugins/nls/da/latinEntities.js
+++ b/dojox/editor/plugins/nls/da/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	euro:"euro sign"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/de/AutoSave.js b/dojox/editor/plugins/nls/de/AutoSave.js
index 23a17b1..c1f0946 100644
--- a/dojox/editor/plugins/nls/de/AutoSave.js
+++ b/dojox/editor/plugins/nls/de/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Speichern",
 	"saveSettingLabelOn": "Intervall für automatisches Speichern festlegen",
@@ -12,3 +14,5 @@
 	"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 45e3ff8..7b05205 100644
--- a/dojox/editor/plugins/nls/de/Blockquote.js
+++ b/dojox/editor/plugins/nls/de/Blockquote.js
@@ -1,4 +1,8 @@
+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 a425ceb..872947a 100644
--- a/dojox/editor/plugins/nls/de/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/de/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "Aktionen für ${nodeName}",
 	"selectContents": "Inhalt auswählen",
@@ -8,3 +10,5 @@
 	"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 a9fcbf4..1b29f90 100644
--- a/dojox/editor/plugins/nls/de/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/de/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 982b3cf..cf8cf8e 100644
--- a/dojox/editor/plugins/nls/de/FindReplace.js
+++ b/dojox/editor/plugins/nls/de/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Suchbegriff:",
 	"findTooltip": "Text zum Suchen eingeben",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "Groß- und Kleinschreibung abgleichen",
 	"backwards": "Zurück",
 	"backwardsTooltip": "Rückwärts nach Text suchen",
-	"replaceAll": "Alle Vorkommen",
 	"replaceAllButton": "Global ersetzen",
 	"replaceAllButtonTooltip": "Gesamten Text ersetzen",
 	"findButton": "Suchen",
@@ -21,3 +22,5 @@
 	"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 748fd9c..72c1a42 100644
--- a/dojox/editor/plugins/nls/de/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/de/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Anker einfügen",
 	title: "Eigenschaften des Ankers",
@@ -7,3 +9,5 @@
 	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 e5bc34c..b50e564 100644
--- a/dojox/editor/plugins/nls/de/InsertEntity.js
+++ b/dojox/editor/plugins/nls/de/InsertEntity.js
@@ -1,4 +1,8 @@
+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 faa1699..0c6a60c 100644
--- a/dojox/editor/plugins/nls/de/LocalImage.js
+++ b/dojox/editor/plugins/nls/de/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Grafik einfügen",
 	url: "Grafik",
@@ -9,3 +11,5 @@
 	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 4285093..26ca51d 100644
--- a/dojox/editor/plugins/nls/de/PageBreak.js
+++ b/dojox/editor/plugins/nls/de/PageBreak.js
@@ -1,4 +1,8 @@
+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 3be00e6..7578607 100644
--- a/dojox/editor/plugins/nls/de/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/de/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Aus Word einfügen",
 	"paste": "Einfügen",
@@ -5,3 +7,5 @@
 	"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 701d9af..19c89b3 100644
--- a/dojox/editor/plugins/nls/de/Preview.js
+++ b/dojox/editor/plugins/nls/de/Preview.js
@@ -1,4 +1,8 @@
+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
new file mode 100644
index 0000000..17b1a74
--- /dev/null
+++ b/dojox/editor/plugins/nls/de/SafePaste.js
@@ -0,0 +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."
+})
+);
diff --git a/dojox/editor/plugins/nls/de/Save.js b/dojox/editor/plugins/nls/de/Save.js
index 0655245..f635309 100644
--- a/dojox/editor/plugins/nls/de/Save.js
+++ b/dojox/editor/plugins/nls/de/Save.js
@@ -1,4 +1,8 @@
+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 9929943..1c684b8 100644
--- a/dojox/editor/plugins/nls/de/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/de/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 dbc5ca3..226cf64 100644
--- a/dojox/editor/plugins/nls/de/Smiley.js
+++ b/dojox/editor/plugins/nls/de/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Emoticon einfügen",
 	emoticonSmile: "Lächeln",
@@ -17,6 +19,9 @@
 	emoticonYes: "Ja",
 	emoticonNo: "Nein",
 	emoticonAngel: "Engel",
-	emoticonCrying: "Weinen"
+	emoticonCrying: "Weinen",
+	emoticonHappy: "Fröhlich"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/de/SpellCheck.js b/dojox/editor/plugins/nls/de/SpellCheck.js
index 4861e14..5f504a5 100644
--- a/dojox/editor/plugins/nls/de/SpellCheck.js
+++ b/dojox/editor/plugins/nls/de/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Batchrechtschreibprüfung",
 	unfound: "Nicht gefunden",
@@ -15,3 +17,5 @@
 	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 d918793..a4284d0 100644
--- a/dojox/editor/plugins/nls/de/TableDialog.js
+++ b/dojox/editor/plugins/nls/de/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Tabelle einfügen",
 	modifyTableTitle: "Tabelle ändern",
@@ -28,3 +30,5 @@
 	deleteTableRowLabel: "Zeile löschen",
 	deleteTableColumnLabel: "Spalte löschen"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/de/TextColor.js b/dojox/editor/plugins/nls/de/TextColor.js
index b7d53cc..f2c42d6 100644
--- a/dojox/editor/plugins/nls/de/TextColor.js
+++ b/dojox/editor/plugins/nls/de/TextColor.js
@@ -1,5 +1,9 @@
+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 b291cdf..8a963ae 100644
--- a/dojox/editor/plugins/nls/de/latinEntities.js
+++ b/dojox/editor/plugins/nls/de/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	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 0b4edd9..855c06f 100644
--- a/dojox/editor/plugins/nls/el/AutoSave.js
+++ b/dojox/editor/plugins/nls/el/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Αποθήκευση",
 	"saveSettingLabelOn": "Ορισμός διαστήματος αυτόματης αποθήκευσης...",
@@ -12,3 +14,5 @@
 	"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 32046f0..a36e467 100644
--- a/dojox/editor/plugins/nls/el/Blockquote.js
+++ b/dojox/editor/plugins/nls/el/Blockquote.js
@@ -1,4 +1,8 @@
+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 a3c915d..754271f 100644
--- a/dojox/editor/plugins/nls/el/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/el/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName} - Ενέργειες",
 	"selectContents": "Επιλογή περιεχομένων",
@@ -8,3 +10,5 @@
 	"moveEnd": "Μετακίνηση δρομέα στο τέλος"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/el/CollapsibleToolbar.js b/dojox/editor/plugins/nls/el/CollapsibleToolbar.js
index d7bc087..e2dfb45 100644
--- a/dojox/editor/plugins/nls/el/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/el/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 021a38a..a5fd0f7 100644
--- a/dojox/editor/plugins/nls/el/FindReplace.js
+++ b/dojox/editor/plugins/nls/el/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Εύρεση:",
 	"findTooltip": "Καταχωρήστε το κείμενο που θέλετε να εντοπίσετε",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "Διάκριση πεζών/κεφαλαίων",
 	"backwards": "Προς τα πίσω",
 	"backwardsTooltip": "Αναζήτηση κειμένου προς τα πίσω",
-	"replaceAll": "Όλες οι εμφανίσεις",
 	"replaceAllButton": "Αντικατάσταση όλων",
 	"replaceAllButtonTooltip": "Αντικατάσταση όλου του κειμένου",
 	"findButton": "Εύρεση",
@@ -21,3 +22,5 @@
 	"eofDialogTextReplace": "αντικαταστάθηκε"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/el/InsertAnchor.js b/dojox/editor/plugins/nls/el/InsertAnchor.js
index eb188bb..f506414 100644
--- a/dojox/editor/plugins/nls/el/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/el/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Εισαγωγή αγκίστρωσης",
 	title: "Ιδιότητες αγκίστρωσης",
@@ -7,3 +9,5 @@
 	cancel: "Ακύρωση"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/el/InsertEntity.js b/dojox/editor/plugins/nls/el/InsertEntity.js
index e01c1d1..8a130fd 100644
--- a/dojox/editor/plugins/nls/el/InsertEntity.js
+++ b/dojox/editor/plugins/nls/el/InsertEntity.js
@@ -1,4 +1,8 @@
+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 810eb11..a0404da 100644
--- a/dojox/editor/plugins/nls/el/LocalImage.js
+++ b/dojox/editor/plugins/nls/el/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Εισαγωγή εικόνας",
 	url: "Εικόνα",
@@ -9,3 +11,5 @@
 	prePopuTextBrowse: " ή επιλέξτε ένα τοπικό αρχείο."
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/el/PageBreak.js b/dojox/editor/plugins/nls/el/PageBreak.js
index 9f012bc..56e2990 100644
--- a/dojox/editor/plugins/nls/el/PageBreak.js
+++ b/dojox/editor/plugins/nls/el/PageBreak.js
@@ -1,4 +1,8 @@
+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 c784559..f8d32be 100644
--- a/dojox/editor/plugins/nls/el/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/el/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Επικόλληση από το Word",
 	"paste": "Επικόλληση",
@@ -5,3 +7,5 @@
 	"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 bcb0872..eb9b7b3 100644
--- a/dojox/editor/plugins/nls/el/Preview.js
+++ b/dojox/editor/plugins/nls/el/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "Προεπισκόπηση"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/el/SafePaste.js b/dojox/editor/plugins/nls/el/SafePaste.js
new file mode 100644
index 0000000..68cdaf8
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "Η δυνατότητα άμεσης επικόλλησης έχει απενεργοποιηθεί. Επικολλήστε το περιεχόμενο σε αυτό το παράθυρο χρησιμοποιώντας τους καθιερωμένους συνδυασμούς πλήκτρων ή επιλογές μενού του προγράμματος πλοήγησης. Όταν το κείμενο για εισαγωγή είναι σωστό, πατήστε το κουμπί Επικόλληση. Για να ακυρώσετε την εισαγωγή περιεχομένου, πατήστε το κουμπί Ακύρωση."
+})
+);
diff --git a/dojox/editor/plugins/nls/el/Save.js b/dojox/editor/plugins/nls/el/Save.js
index e7f42b5..9ec635a 100644
--- a/dojox/editor/plugins/nls/el/Save.js
+++ b/dojox/editor/plugins/nls/el/Save.js
@@ -1,4 +1,8 @@
+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 115537a..ca7a605 100644
--- a/dojox/editor/plugins/nls/el/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/el/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 55547fb..53bd0ac 100644
--- a/dojox/editor/plugins/nls/el/Smiley.js
+++ b/dojox/editor/plugins/nls/el/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Εισαγωγή εικονιδίου συναισθήματος",
 	emoticonSmile: "Χαμόγελο",
@@ -17,6 +19,9 @@
 	emoticonYes: "Ναι",
 	emoticonNo: "Όχι",
 	emoticonAngel: "Αγγελούδι",
-	emoticonCrying: "Κλάμα"
+	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 ea629a8..4753341 100644
--- a/dojox/editor/plugins/nls/el/SpellCheck.js
+++ b/dojox/editor/plugins/nls/el/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Συνολικός ορθογραφικός έλεγχος",
 	unfound: "Δεν εντοπίστηκε",
@@ -15,3 +17,5 @@
 	iMsg: "Δεν υπάρχουν προτάσεις ορθογραφίας"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/el/TableDialog.js b/dojox/editor/plugins/nls/el/TableDialog.js
index c6a9a4c..5e95d11 100644
--- a/dojox/editor/plugins/nls/el/TableDialog.js
+++ b/dojox/editor/plugins/nls/el/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Εισαγωγή πίνακα",
 	modifyTableTitle: "Τροποποίηση πίνακα",
@@ -28,3 +30,5 @@
 	deleteTableRowLabel: "Διαγραφή γραμμής",
 	deleteTableColumnLabel: "Διαγραφή στήλης"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/el/TextColor.js b/dojox/editor/plugins/nls/el/TextColor.js
index f6f3b17..db99be9 100644
--- a/dojox/editor/plugins/nls/el/TextColor.js
+++ b/dojox/editor/plugins/nls/el/TextColor.js
@@ -1,5 +1,9 @@
+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 ed8b58c..94c0f21 100644
--- a/dojox/editor/plugins/nls/el/latinEntities.js
+++ b/dojox/editor/plugins/nls/el/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	euro:"Σύμβολο ευρώ"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/es/AutoSave.js b/dojox/editor/plugins/nls/es/AutoSave.js
index 324a35a..2f43e97 100644
--- a/dojox/editor/plugins/nls/es/AutoSave.js
+++ b/dojox/editor/plugins/nls/es/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Guardar",
 	"saveSettingLabelOn": "Definir intervalo de guardado automático...",
@@ -12,3 +14,5 @@
 	"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 9a4fb1a..3179f23 100644
--- a/dojox/editor/plugins/nls/es/Blockquote.js
+++ b/dojox/editor/plugins/nls/es/Blockquote.js
@@ -1,4 +1,8 @@
+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 29ad69e..5a31f80 100644
--- a/dojox/editor/plugins/nls/es/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/es/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "Acciones de ${nodeName}",
 	"selectContents": "Seleccionar contenido",
@@ -8,3 +10,5 @@
 	"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 0581505..ef6701d 100644
--- a/dojox/editor/plugins/nls/es/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/es/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 0bd0c39..16b6dff 100644
--- a/dojox/editor/plugins/nls/es/FindReplace.js
+++ b/dojox/editor/plugins/nls/es/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Buscar:",
 	"findTooltip": "Especifique el texto que desee buscar",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "Coincidir mayúsculas y minúsculas",
 	"backwards": "Hacia atrás",
 	"backwardsTooltip": "Buscar texto hacia atrás",
-	"replaceAll": "Todas las apariciones",
 	"replaceAllButton": "Sustituir todo",
 	"replaceAllButtonTooltip": "Sustituir todo el texto",
 	"findButton": "Buscar",
@@ -20,3 +21,5 @@
 	"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 65841f4..52be2ca 100644
--- a/dojox/editor/plugins/nls/es/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/es/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Insertar ancla",
 	title: "Propiedades del ancla",
@@ -7,3 +9,5 @@
 	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 cfc5f24..44e4452 100644
--- a/dojox/editor/plugins/nls/es/InsertEntity.js
+++ b/dojox/editor/plugins/nls/es/InsertEntity.js
@@ -1,4 +1,8 @@
+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 b38221c..314e5f4 100644
--- a/dojox/editor/plugins/nls/es/LocalImage.js
+++ b/dojox/editor/plugins/nls/es/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Insertar imagen",
 	url: "Imagen",
@@ -9,3 +11,5 @@
 	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 381e2f0..3522235 100644
--- a/dojox/editor/plugins/nls/es/PageBreak.js
+++ b/dojox/editor/plugins/nls/es/PageBreak.js
@@ -1,4 +1,8 @@
+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 ce07ae6..3ccd13c 100644
--- a/dojox/editor/plugins/nls/es/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/es/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Pegar desde Word",
 	"paste": "Pegar",
@@ -5,3 +7,5 @@
 	"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 581b725..d2aca5c 100644
--- a/dojox/editor/plugins/nls/es/Preview.js
+++ b/dojox/editor/plugins/nls/es/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "Previsualización"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/es/SafePaste.js b/dojox/editor/plugins/nls/es/SafePaste.js
new file mode 100644
index 0000000..a3e3991
--- /dev/null
+++ b/dojox/editor/plugins/nls/es/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "El pegado directo está inhabilitado. Pegue el contenido en este diálogo utilizando los controles de pegado del menú o del teclado de navegador estándar. Cuando esté satisfecho con el contenido que se debe insertar, pulse el botón Pegar. Para abortar la inserción de contenido, pulse el botón Cancelar."
+})
+);
diff --git a/dojox/editor/plugins/nls/es/Save.js b/dojox/editor/plugins/nls/es/Save.js
index 11af7ed..4e8a379 100644
--- a/dojox/editor/plugins/nls/es/Save.js
+++ b/dojox/editor/plugins/nls/es/Save.js
@@ -1,4 +1,8 @@
+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 2bfaf04..c4a40fb 100644
--- a/dojox/editor/plugins/nls/es/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/es/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 7fd1221..ac56e83 100644
--- a/dojox/editor/plugins/nls/es/Smiley.js
+++ b/dojox/editor/plugins/nls/es/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Insertar emoticono",
 	emoticonSmile: "sonrisa",
@@ -17,6 +19,9 @@
 	emoticonYes: "sí",
 	emoticonNo: "no",
 	emoticonAngel: "ángel",
-	emoticonCrying: "llorando"
+	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 d5395f7..6225d0c 100644
--- a/dojox/editor/plugins/nls/es/SpellCheck.js
+++ b/dojox/editor/plugins/nls/es/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Corrector ortográfico por lotes",
 	unfound: "No encontrado",
@@ -15,3 +17,5 @@
 	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 c4593e1..5d9087a 100644
--- a/dojox/editor/plugins/nls/es/TableDialog.js
+++ b/dojox/editor/plugins/nls/es/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Insertar tabla",
 	modifyTableTitle: "Modificar tabla",
@@ -30,3 +32,5 @@
 })
 	
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/es/TextColor.js b/dojox/editor/plugins/nls/es/TextColor.js
index f684f6e..cad4ae2 100644
--- a/dojox/editor/plugins/nls/es/TextColor.js
+++ b/dojox/editor/plugins/nls/es/TextColor.js
@@ -1,5 +1,9 @@
+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 584f9c3..7cce9a6 100644
--- a/dojox/editor/plugins/nls/es/latinEntities.js
+++ b/dojox/editor/plugins/nls/es/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	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 1b4ba49..c2949c3 100644
--- a/dojox/editor/plugins/nls/fi/AutoSave.js
+++ b/dojox/editor/plugins/nls/fi/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Tallenna",
 	"saveSettingLabelOn": "Aseta automaattisen tallennuksen väli...",
@@ -12,3 +14,5 @@
 	"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 23c7690..757ba92 100644
--- a/dojox/editor/plugins/nls/fi/Blockquote.js
+++ b/dojox/editor/plugins/nls/fi/Blockquote.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"blockquote": "Sitaatti"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/fi/Breadcrumb.js b/dojox/editor/plugins/nls/fi/Breadcrumb.js
index dcdcc87..b43fa7b 100644
--- a/dojox/editor/plugins/nls/fi/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/fi/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName} - Toiminnot",
 	"selectContents": "Valitse sisältö",
@@ -8,3 +10,5 @@
 	"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 f489ec1..f1fe530 100644
--- a/dojox/editor/plugins/nls/fi/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/fi/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 4a82134..c8af94c 100644
--- a/dojox/editor/plugins/nls/fi/FindReplace.js
+++ b/dojox/editor/plugins/nls/fi/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Etsi:",
 	"findTooltip": "Anna etsittävä teksti",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "Sama kirjainkoko",
 	"backwards": "Taaksepäin",
 	"backwardsTooltip": "Etsi tekstiä taaksepäin",
-	"replaceAll": "Kaikki esiintymät",
 	"replaceAllButton": "Korvaa kaikki",
 	"replaceAllButtonTooltip": "Korvaa kaikki teksti",
 	"findButton": "Etsi",
@@ -21,3 +22,5 @@
 	"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 c9f25cf..7e25d59 100644
--- a/dojox/editor/plugins/nls/fi/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/fi/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Lisää ankkuri",
 	title: "Ankkurin ominaisuudet",
@@ -7,3 +9,5 @@
 	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 78b0b2f..35863a5 100644
--- a/dojox/editor/plugins/nls/fi/InsertEntity.js
+++ b/dojox/editor/plugins/nls/fi/InsertEntity.js
@@ -1,4 +1,8 @@
+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 277dc07..d6e5b5a 100644
--- a/dojox/editor/plugins/nls/fi/LocalImage.js
+++ b/dojox/editor/plugins/nls/fi/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Lisää kuva",
 	url: "Kuva",
@@ -9,3 +11,5 @@
 	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 efeabe6..3b0e71e 100644
--- a/dojox/editor/plugins/nls/fi/PageBreak.js
+++ b/dojox/editor/plugins/nls/fi/PageBreak.js
@@ -1,4 +1,8 @@
+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 bfdcf52..d7fdadd 100644
--- a/dojox/editor/plugins/nls/fi/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/fi/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Liitä Word-ohjelmasta",
 	"paste": "Liitä",
@@ -5,3 +7,5 @@
 	"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 5cd828f..20dec44 100644
--- a/dojox/editor/plugins/nls/fi/Preview.js
+++ b/dojox/editor/plugins/nls/fi/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "Esikatselu"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/fi/SafePaste.js b/dojox/editor/plugins/nls/fi/SafePaste.js
new file mode 100644
index 0000000..19b79aa
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "Suora liittäminen ei ole käytössä. Liitä sisältö tähän valintaikkunaan käyttämällä tavallisia selaimen pikanäppäimiä tai valikon vaihtoehtoja. Kun lisättävä sisältö on mielestäsi valmis, napsauta Liitä-painiketta. Voit peruuttaa lisäyksen napsauttamalla Peruuta-painiketta."
+})
+);
diff --git a/dojox/editor/plugins/nls/fi/Save.js b/dojox/editor/plugins/nls/fi/Save.js
index 74e605a..2ba78f8 100644
--- a/dojox/editor/plugins/nls/fi/Save.js
+++ b/dojox/editor/plugins/nls/fi/Save.js
@@ -1,4 +1,8 @@
+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 f37ca88..bfb3bc9 100644
--- a/dojox/editor/plugins/nls/fi/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/fi/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 856b7c6..13b2802 100644
--- a/dojox/editor/plugins/nls/fi/Smiley.js
+++ b/dojox/editor/plugins/nls/fi/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Lisää hymiö",
 	emoticonSmile: "hymyillä",
@@ -17,6 +19,9 @@
 	emoticonYes: "kyllä",
 	emoticonNo: "ei",
 	emoticonAngel: "enkeli",
-	emoticonCrying: "itkeä"
+	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 449ab2f..0eb9833 100644
--- a/dojox/editor/plugins/nls/fi/SpellCheck.js
+++ b/dojox/editor/plugins/nls/fi/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Eräoikoluku",
 	unfound: "Ei löydy",
@@ -15,3 +17,5 @@
 	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 3f00b82..80eb46f 100644
--- a/dojox/editor/plugins/nls/fi/TableDialog.js
+++ b/dojox/editor/plugins/nls/fi/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Lisää taulukko",
 	modifyTableTitle: "Muokkaa taulukkoa",
@@ -28,3 +30,5 @@
 	deleteTableRowLabel: "Poista rivi",
 	deleteTableColumnLabel: "Poista sarake"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/fi/TextColor.js b/dojox/editor/plugins/nls/fi/TextColor.js
index 1d759d7..1ac9697 100644
--- a/dojox/editor/plugins/nls/fi/TextColor.js
+++ b/dojox/editor/plugins/nls/fi/TextColor.js
@@ -1,5 +1,9 @@
+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 be9ec5b..462ce1d 100644
--- a/dojox/editor/plugins/nls/fi/latinEntities.js
+++ b/dojox/editor/plugins/nls/fi/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	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 0c9cfc7..dc8fac1 100644
--- a/dojox/editor/plugins/nls/fr/AutoSave.js
+++ b/dojox/editor/plugins/nls/fr/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Enregistrer",
 	"saveSettingLabelOn": "Définir l'intervalle d'enregistrement automatique...",
@@ -12,3 +14,5 @@
 	"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 d73127b..8e0ecb1 100644
--- a/dojox/editor/plugins/nls/fr/Blockquote.js
+++ b/dojox/editor/plugins/nls/fr/Blockquote.js
@@ -1,4 +1,8 @@
+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 5899469..3e4b0b1 100644
--- a/dojox/editor/plugins/nls/fr/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/fr/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "Actions ${nodeName}",
 	"selectContents": "Sélection de contenus",
@@ -8,3 +10,5 @@
 	"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 e06f27a..9e24571 100644
--- a/dojox/editor/plugins/nls/fr/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/fr/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 1c81610..63e56d9 100644
--- a/dojox/editor/plugins/nls/fr/FindReplace.js
+++ b/dojox/editor/plugins/nls/fr/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Rechercher :",
 	"findTooltip": "Entrez le texte à rechercher",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "Respecter la casse",
 	"backwards": "Vers l'arrière",
 	"backwardsTooltip": "Recherchez le texte vers l'arrière",
-	"replaceAll": "Toutes les occurrences",
 	"replaceAllButton": "Remplacer tout",
 	"replaceAllButtonTooltip": "Remplacez tout le texte",
 	"findButton": "Rechercher",
@@ -20,3 +21,5 @@
 	"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 805e592..7ba6b6b 100644
--- a/dojox/editor/plugins/nls/fr/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/fr/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Insérer un point d'ancrage",
 	title: "Propriétés du point d'ancrage",
@@ -7,3 +9,5 @@
 	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 31256eb..ffea02a 100644
--- a/dojox/editor/plugins/nls/fr/InsertEntity.js
+++ b/dojox/editor/plugins/nls/fr/InsertEntity.js
@@ -1,4 +1,8 @@
+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 2e4399d..64c3fe5 100644
--- a/dojox/editor/plugins/nls/fr/LocalImage.js
+++ b/dojox/editor/plugins/nls/fr/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Insérer une image",
 	url: "Image",
@@ -9,3 +11,5 @@
 	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 4d89650..8290b8e 100644
--- a/dojox/editor/plugins/nls/fr/PageBreak.js
+++ b/dojox/editor/plugins/nls/fr/PageBreak.js
@@ -1,4 +1,8 @@
+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 016359c..2a0d546 100644
--- a/dojox/editor/plugins/nls/fr/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/fr/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Coller depuis Word",
 	"paste": "Coller",
@@ -5,3 +7,5 @@
 	"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 faead7f..cf58ce8 100644
--- a/dojox/editor/plugins/nls/fr/Preview.js
+++ b/dojox/editor/plugins/nls/fr/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "Aperçu"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/fr/SafePaste.js b/dojox/editor/plugins/nls/fr/SafePaste.js
new file mode 100644
index 0000000..c194e20
--- /dev/null
+++ b/dojox/editor/plugins/nls/fr/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "La fonction directe Coller est désactivée. Collez le contenu dans la boîte de dialogue à l'aide des commandes du clavier de navigateur standard ou de l'option coller dans le menu.  Quand le contenu à insérer vous convient, appuyez sur le bouton Coller.  Pour annuler l'insertion du contenu, utilisez le bouton Annuler."
+})
+);
diff --git a/dojox/editor/plugins/nls/fr/Save.js b/dojox/editor/plugins/nls/fr/Save.js
index 2adf8ab..564c5a8 100644
--- a/dojox/editor/plugins/nls/fr/Save.js
+++ b/dojox/editor/plugins/nls/fr/Save.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"save": "Sauvegarder"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/fr/ShowBlockNodes.js b/dojox/editor/plugins/nls/fr/ShowBlockNodes.js
index 0da669b..38f3a4c 100644
--- a/dojox/editor/plugins/nls/fr/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/fr/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 5d9e3ba..107705c 100644
--- a/dojox/editor/plugins/nls/fr/Smiley.js
+++ b/dojox/editor/plugins/nls/fr/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Insérer une émoticône",
 	emoticonSmile: "sourire",
@@ -17,6 +19,9 @@
 	emoticonYes: "oui",
 	emoticonNo: "non",
 	emoticonAngel: "ange",
-	emoticonCrying: "pleurs"
+	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 12ec416..83b586e 100644
--- a/dojox/editor/plugins/nls/fr/SpellCheck.js
+++ b/dojox/editor/plugins/nls/fr/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Vérification orthographique par lots",
 	unfound: "Introuvable",
@@ -15,3 +17,5 @@
 	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 37b42fa..f096094 100644
--- a/dojox/editor/plugins/nls/fr/TableDialog.js
+++ b/dojox/editor/plugins/nls/fr/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Insérer une table",
 	modifyTableTitle: "Modifier une table",
@@ -29,3 +31,5 @@
 	deleteTableColumnLabel: "Supprimer la colonne"
 })
 	
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/fr/TextColor.js b/dojox/editor/plugins/nls/fr/TextColor.js
index ad0fe03..82d0e41 100644
--- a/dojox/editor/plugins/nls/fr/TextColor.js
+++ b/dojox/editor/plugins/nls/fr/TextColor.js
@@ -1,5 +1,9 @@
+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 d7aca89..905a581 100644
--- a/dojox/editor/plugins/nls/fr/latinEntities.js
+++ b/dojox/editor/plugins/nls/fr/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	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 64b12c2..a2f6363 100644
--- a/dojox/editor/plugins/nls/he/AutoSave.js
+++ b/dojox/editor/plugins/nls/he/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "שמירה",
 	"saveSettingLabelOn": "הגדרת מרווח שמירה אוטומטית...‏",
@@ -12,3 +14,5 @@
 	"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 b995106..ae3d5f9 100644
--- a/dojox/editor/plugins/nls/he/Blockquote.js
+++ b/dojox/editor/plugins/nls/he/Blockquote.js
@@ -1,4 +1,8 @@
+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 9d6526c..3f8f245 100644
--- a/dojox/editor/plugins/nls/he/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/he/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "פעולות ${nodeName} ",
 	"selectContents": "בחירת תוכן ",
@@ -8,3 +10,5 @@
 	"moveEnd": "העברת הסמן לסוף "
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/he/CollapsibleToolbar.js b/dojox/editor/plugins/nls/he/CollapsibleToolbar.js
index a74a6e2..cb2a641 100644
--- a/dojox/editor/plugins/nls/he/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/he/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 a8fde39..d0c1fae 100644
--- a/dojox/editor/plugins/nls/he/FindReplace.js
+++ b/dojox/editor/plugins/nls/he/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "חיפוש: ",
 	"findTooltip": "ציינו תמליל לחיפוש",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "התאמת רישיות",
 	"backwards": "אחורה ",
 	"backwardsTooltip": "חיפוש תמליל אחורה ",
-	"replaceAll": "כל המופעים ",
 	"replaceAllButton": "החלפת הכל ",
 	"replaceAllButtonTooltip": "החלפת כל התמליל ",
 	"findButton": "חיפוש",
@@ -21,3 +22,5 @@
 	"eofDialogTextReplace": "הוחלפו "
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/he/InsertAnchor.js b/dojox/editor/plugins/nls/he/InsertAnchor.js
index 9638b00..33ba4c0 100644
--- a/dojox/editor/plugins/nls/he/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/he/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "הוספת עוגן ",
 	title: "תכונות עוגן ",
@@ -7,3 +9,5 @@
 	cancel: "ביטול"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/he/InsertEntity.js b/dojox/editor/plugins/nls/he/InsertEntity.js
index 3e1c46b..2a8dbf9 100644
--- a/dojox/editor/plugins/nls/he/InsertEntity.js
+++ b/dojox/editor/plugins/nls/he/InsertEntity.js
@@ -1,4 +1,8 @@
+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 50c4f11..7c0b981 100644
--- a/dojox/editor/plugins/nls/he/LocalImage.js
+++ b/dojox/editor/plugins/nls/he/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "הוספת תמונה",
 	url: "תמונה",
@@ -9,3 +11,5 @@
 	prePopuTextBrowse: " או נווטו לקובץ מקומי. "
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/he/PageBreak.js b/dojox/editor/plugins/nls/he/PageBreak.js
index 008130d..83fe084 100644
--- a/dojox/editor/plugins/nls/he/PageBreak.js
+++ b/dojox/editor/plugins/nls/he/PageBreak.js
@@ -1,4 +1,8 @@
+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 cd35c7d..bb5d05a 100644
--- a/dojox/editor/plugins/nls/he/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/he/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "הדבקה מתוך Word",
 	"paste": "הדבקה",
@@ -5,3 +7,5 @@
 	"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 dbbed34..e332bea 100644
--- a/dojox/editor/plugins/nls/he/Preview.js
+++ b/dojox/editor/plugins/nls/he/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "תצוגה מקדימה"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/he/Save.js b/dojox/editor/plugins/nls/he/Save.js
index 1683e27..946c8ff 100644
--- a/dojox/editor/plugins/nls/he/Save.js
+++ b/dojox/editor/plugins/nls/he/Save.js
@@ -1,4 +1,8 @@
+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 0547f02..cc6439e 100644
--- a/dojox/editor/plugins/nls/he/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/he/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 d2fc8f8..11bad8f 100644
--- a/dojox/editor/plugins/nls/he/Smiley.js
+++ b/dojox/editor/plugins/nls/he/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "הוספת רגשון",
 	emoticonSmile: "חיוך",
@@ -20,3 +22,5 @@
 	emoticonCrying: "בוכה"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/he/SpellCheck.js b/dojox/editor/plugins/nls/he/SpellCheck.js
index ec996bd..50b5c9c 100644
--- a/dojox/editor/plugins/nls/he/SpellCheck.js
+++ b/dojox/editor/plugins/nls/he/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "בדיקת איות באצווה ",
 	unfound: "לא נמצא ",
@@ -15,3 +17,5 @@
 	iMsg: "אין הצעות איות "
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/he/TableDialog.js b/dojox/editor/plugins/nls/he/TableDialog.js
index c2e1089..8cb38c9 100644
--- a/dojox/editor/plugins/nls/he/TableDialog.js
+++ b/dojox/editor/plugins/nls/he/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "הוספת טבלה",
 	modifyTableTitle: "שינוי טבלה",
@@ -28,3 +30,5 @@
 	deleteTableRowLabel: "מחיקת שורה",
 	deleteTableColumnLabel: "מחיקת עמודה"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/he/TextColor.js b/dojox/editor/plugins/nls/he/TextColor.js
index f52f472..912de00 100644
--- a/dojox/editor/plugins/nls/he/TextColor.js
+++ b/dojox/editor/plugins/nls/he/TextColor.js
@@ -1,5 +1,9 @@
+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 ca7f715..cc1257c 100644
--- a/dojox/editor/plugins/nls/he/latinEntities.js
+++ b/dojox/editor/plugins/nls/he/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -254,3 +256,5 @@
 	rsaquo:"single right-pointing angle quotation mark",
 	euro:"euro sign"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/hr/AutoSave.js b/dojox/editor/plugins/nls/hr/AutoSave.js
new file mode 100644
index 0000000..cac5a56
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/AutoSave.js
@@ -0,0 +1,15 @@
+define(
+({
+	"saveLabel": "Spremi",
+	"saveSettingLabelOn": "Postavi interval automatskog spremanja...",
+	"saveSettingLabelOff": "Isključi automatsko spremanje",
+	"saveSettingdialogTitle": "Automatsko spremanje",
+	"saveSettingdialogDescription": "Navedi interval automatskog spremanja",
+	"saveSettingdialogParamName": "Interval automatskog spremanja",
+	"saveSettingdialogParamLabel": "minimum",
+	"saveSettingdialogButtonOk": "Postavi interval",
+	"saveSettingdialogButtonCancel": "Opoziv",
+	"saveMessageSuccess": "Spremljeno na ${0}",
+	"saveMessageFail": "Neuspješno spremanje na ${0}"
+})
+);
diff --git a/dojox/editor/plugins/nls/hr/Blockquote.js b/dojox/editor/plugins/nls/hr/Blockquote.js
new file mode 100644
index 0000000..4de9332
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/Blockquote.js
@@ -0,0 +1,5 @@
+define(
+({
+	"blockquote": "Dugi citat"
+})
+);
diff --git a/dojox/editor/plugins/nls/hr/Breadcrumb.js b/dojox/editor/plugins/nls/hr/Breadcrumb.js
new file mode 100644
index 0000000..fdd6f20
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/Breadcrumb.js
@@ -0,0 +1,11 @@
+define(
+({
+	"nodeActions": "${nodeName} Akcije",
+	"selectContents": "Izaberi sadržaj",
+	"selectElement": "Izaberi elemente",
+	"deleteElement": "Izbriši element",
+	"deleteContents": "Izbriši sadržaj",
+	"moveStart": "Pomakni pokazivač na početak",
+	"moveEnd": "Pomakni pokazivač na kraj"
+})
+);
diff --git a/dojox/editor/plugins/nls/hr/CollapsibleToolbar.js b/dojox/editor/plugins/nls/hr/CollapsibleToolbar.js
new file mode 100644
index 0000000..295f9ff
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/CollapsibleToolbar.js
@@ -0,0 +1,6 @@
+define(
+({
+	"collapse": "Spusti traku s alatima editora",
+	"expand": "Proširi traku s alatima editora"
+})
+);
diff --git a/dojox/editor/plugins/nls/hr/FindReplace.js b/dojox/editor/plugins/nls/hr/FindReplace.js
new file mode 100644
index 0000000..53b4187
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/FindReplace.js
@@ -0,0 +1,23 @@
+define(
+({
+	"findLabel": "Traži:",
+	"findTooltip": "Unesi tekst pretrage",
+	"replaceLabel": "Zamijeni s:",
+	"replaceTooltip": "Unesi tekst za zamjenu",
+	"findReplace": "Traži i zamijeni",
+	"matchCase": "Usporedi velika/mala slova",
+	"matchCaseTooltip": "Usporedi velika/mala slova",
+	"backwards": "Natrag",
+	"backwardsTooltip": "Pretraži tekst u prethodnim koracima",
+	"replaceAllButton": "Zamijeni sve",
+	"replaceAllButtonTooltip": "Zamijeni cijeli tekst",
+	"findButton": "Traži",
+	"findButtonTooltip": "Traži tekst",
+	"replaceButton": "Zamijeni",
+	"replaceButtonTooltip": "Zamijeni tekst",
+	"replaceDialogText": "Zamijenjeno ${0} pojavljivanja.",
+	"eofDialogText": "Zadnje pojavljivanje ${0}",
+	"eofDialogTextFind": "nađeno",
+	"eofDialogTextReplace": "zamijenjeno"
+})
+);
diff --git a/dojox/editor/plugins/nls/hr/InsertAnchor.js b/dojox/editor/plugins/nls/hr/InsertAnchor.js
new file mode 100644
index 0000000..5c60ce1
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/InsertAnchor.js
@@ -0,0 +1,10 @@
+define(
+({
+	insertAnchor: "Umetni sidro",
+	title: "Svojstva sidra",
+	anchor: "Naziv:",
+	text: "Opis:",
+	set: "Postavi",
+	cancel: "Opoziv"
+})
+);
diff --git a/dojox/editor/plugins/nls/hr/InsertEntity.js b/dojox/editor/plugins/nls/hr/InsertEntity.js
new file mode 100644
index 0000000..761d408
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/InsertEntity.js
@@ -0,0 +1,5 @@
+define(
+({
+	insertEntity: "Umetni simbol"
+})
+);
diff --git a/dojox/editor/plugins/nls/hr/LocalImage.js b/dojox/editor/plugins/nls/hr/LocalImage.js
new file mode 100644
index 0000000..49e6fa0
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/LocalImage.js
@@ -0,0 +1,12 @@
+define(
+({
+	insertImageTitle: "Umetni sliku",
+	url: "Slika ",
+	browse: "Pregledaj...",
+	text: "Opis",
+	set: "Umetni",
+	invalidMessage: "Pogrešan tip slikovne datoteke",
+	prePopuTextUrl: "Unesite URL slike",
+	prePopuTextBrowse: " ili pregledajte mjesnu datoteku."
+})
+);
diff --git a/dojox/editor/plugins/nls/hr/PageBreak.js b/dojox/editor/plugins/nls/hr/PageBreak.js
new file mode 100644
index 0000000..b4f4a8e
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/PageBreak.js
@@ -0,0 +1,5 @@
+define(
+({
+	"pageBreak": "Prijelom stranice"
+})
+);
diff --git a/dojox/editor/plugins/nls/hr/PasteFromWord.js b/dojox/editor/plugins/nls/hr/PasteFromWord.js
new file mode 100644
index 0000000..6e1add5
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/PasteFromWord.js
@@ -0,0 +1,8 @@
+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."
+})
+);
diff --git a/dojox/editor/plugins/nls/hr/Preview.js b/dojox/editor/plugins/nls/hr/Preview.js
new file mode 100644
index 0000000..6a6ce16
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/Preview.js
@@ -0,0 +1,5 @@
+define(
+({
+	"preview": "Pregled"
+})
+);
diff --git a/dojox/editor/plugins/nls/hr/SafePaste.js b/dojox/editor/plugins/nls/hr/SafePaste.js
new file mode 100644
index 0000000..817bf8d
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/SafePaste.js
@@ -0,0 +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."
+})
+);
diff --git a/dojox/editor/plugins/nls/hr/Save.js b/dojox/editor/plugins/nls/hr/Save.js
new file mode 100644
index 0000000..de69158
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/Save.js
@@ -0,0 +1,5 @@
+define(
+({
+	"save": "Spremi"
+})
+);
diff --git a/dojox/editor/plugins/nls/hr/ShowBlockNodes.js b/dojox/editor/plugins/nls/hr/ShowBlockNodes.js
new file mode 100644
index 0000000..17fe691
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/ShowBlockNodes.js
@@ -0,0 +1,5 @@
+define(
+({
+	"showBlockNodes": "Prikaži elemente HTML bloka"
+})
+);
diff --git a/dojox/editor/plugins/nls/hr/Smiley.js b/dojox/editor/plugins/nls/hr/Smiley.js
new file mode 100644
index 0000000..e992c36
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/Smiley.js
@@ -0,0 +1,24 @@
+define(
+({
+	smiley: "Umetni emotikon",
+	emoticonSmile: "smiješak",
+	emoticonLaughing: "smijanje",
+	emoticonWink: "namigivanje",
+	emoticonGrin: "cerenje",
+	emoticonCool: "staložen",
+	emoticonAngry: "ljut",
+	emoticonHalf: "indiferentan",
+	emoticonEyebrow: "namigivanje",
+	emoticonFrown: "namršten",
+	emoticonShy: "stidljiv",
+	emoticonGoofy: "budalast",
+	emoticonOops: "ups",
+	emoticonTongue: "plaženje jezika",
+	emoticonIdea: "ideja",
+	emoticonYes: "da",
+	emoticonNo: "ne",
+	emoticonAngel: "anđeo",
+	emoticonCrying: "plakanje",
+	emoticonHappy: "sretan"
+})
+);
diff --git a/dojox/editor/plugins/nls/hr/SpellCheck.js b/dojox/editor/plugins/nls/hr/SpellCheck.js
new file mode 100644
index 0000000..6eeb49a
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/SpellCheck.js
@@ -0,0 +1,18 @@
+define(
+({
+	widgetLabel: "Provjera pravopisa paketa",
+	unfound: "Nije nađeno",
+	skip: "Preskoči",
+	skipAll: "Preskoči sve",
+	toDic: "Dodaj u rječnik",
+	suggestions: "Prijedlozi",
+	replace: "Zamijeni",
+	replaceWith: "Zamijeni s",
+	replaceAll: "Zamijeni sve",
+	cancel: "Opoziv",
+	msg: "Nisu nađene pogreš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
new file mode 100644
index 0000000..b5c833a
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/TableDialog.js
@@ -0,0 +1,31 @@
+define(
+({
+	insertTableTitle: "Umetni tablicu",
+	modifyTableTitle: "Promijeni tablicu",
+	rows: "Redovi:",
+	columns: "Stupci:",
+	align: "Poravnaj:",
+	cellPadding: "Punjenje ćelije:",
+	cellSpacing: "Prored ćelije:",
+	tableWidth: "Širina tablice:",
+	backgroundColor: "Boja pozadine:",
+	borderColor: "Boja obruba:",
+	borderThickness: "Debljina obruba:",
+	percent: "postotak",
+	pixels: "pikseli",
+	"default": "zadano",
+	left: "lijevo",
+	center: "sredina",
+	right: "desno",
+	buttonSet: "Postavi", // translated elsewhere?
+	buttonInsert: "Umetni",
+	buttonCancel: "Opoziv",
+	selectTableLabel: "Označi tablicu",
+	insertTableRowBeforeLabel: "Dodaj redak prije",
+	insertTableRowAfterLabel: "Dodaj redak nakon",
+	insertTableColumnBeforeLabel: "Dodaj stupac prije",
+	insertTableColumnAfterLabel: "Dodaj stupac nakon",
+	deleteTableRowLabel: "Izbriši redak",
+	deleteTableColumnLabel: "Izbriši stupac"
+})
+);
diff --git a/dojox/editor/plugins/nls/hr/TextColor.js b/dojox/editor/plugins/nls/hr/TextColor.js
new file mode 100644
index 0000000..8893b7b
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/TextColor.js
@@ -0,0 +1,6 @@
+define(
+({
+	"setButtonText": "Postavi",
+	"cancelButtonText": "Opoziv"
+})
+);
diff --git a/dojox/editor/plugins/nls/hr/latinEntities.js b/dojox/editor/plugins/nls/hr/latinEntities.js
new file mode 100644
index 0000000..e4a9a81
--- /dev/null
+++ b/dojox/editor/plugins/nls/hr/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:"obrnuti uskličnik",
+	cent:"znak centa",
+	pound:"znak funte",
+	curren:"znak valute",
+	yen:"znak yena\nznak yuana",
+	brvbar:"isprekidana crta\nisprekidana okomita crta",
+	sect:"znak odlomka",
+	uml:"dijareza\nprored dijareze",
+	copy:"znak autorskog prava",
+	ordf:"indikator rednog broja ženskog roda",
+	laquo:"navodnik okrenut prema lijevo s dvostrukom strelicom\nnavodnik sa strelicama okrenutim prema lijevo",
+	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",
+	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",
+	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",
+	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",
+	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",
+	Aacute:"Latinsko veliko slovo A s akutnim akcentom",
+	Acirc:"Latinsko veliko slovo A sa 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",
+	AElig:"Latinsko veliko slovo AE\nLatinsko veliko spojeno slovo AE",
+	Ccedil:"Latinsko veliko slovo C sa sedijom",
+	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",
+	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",
+	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",
+	Otilde:"Latinsko veliko slovo O s tildom",
+	Ouml:"Latinsko veliko slovo O s dijarezom",
+	times:"znak množenja",
+	Oslash:"Latinsko veliko slovo O s kosom crtom\nLatinsko veliko slovo O kosa crta",
+	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",
+	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",
+	aacute:"Latinsko malo slovo a s akutnim akcentom",
+	acirc:"Latinsko malo slovo a sa 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",
+	aelig:"Latinsko malo slovo ae\nLatinsko malo spojeno slovo ae",
+	ccedil:"Latinsko malo slovo c sa sedijom",
+	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",
+	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",
+	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",
+	otilde:"Latinsko malo slovo o s tildom",
+	ouml:"Latinsko malo slovo o s dijarezom",
+	divide:"znak dijeljenja",
+	oslash:"Latinsko malo slovo o s kosom crtom\nLatinsko malo slovo o kosa crta",
+	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",
+	yacute:"Latinsko malo slovo y s akutnim akcentom",
+	thorn:"Latinsko malo slovo thorn",
+	yuml:"Latinsko malo slovo y s dijarezom",
+// Greek Characters and Symbols
+	fnof:"Latinsko malo f s kvačicom\nfunkcija\nflorin",
+	Alpha:"Grčko veliko slovo alfa",
+	Beta:"Grčko veliko slovo beta",
+	Gamma:"Grčko veliko slovo gama",
+	Delta:"Grčko veliko slovo delta",
+	Epsilon:"Grčko veliko slovo epsilon",
+	Zeta:"Grčko veliko slovo zeta",
+	Eta:"Grčko veliko slovo eta",
+	Theta:"Grčko veliko slovo theta",
+	Iota:"Grčko veliko slovo jota",
+	Kappa:"Grčko veliko slovo kapa",
+	Lambda:"Grčko veliko slovo lambda",
+	Mu:"Grčko veliko slovo mi",
+	Nu:"Grčko veliko slovo ni",
+	Xi:"Grčko veliko slovo ksi",
+	Omicron:"Grčko veliko slovo omikron",
+	Pi:"Grčko veliko slovo pi",
+	Rho:"Grčko veliko slovo ro",
+	Sigma:"Grčko veliko slovo sigma",
+	Tau:"Grčko veliko slovo tau",
+	Upsilon:"Grčko veliko slovo ipsilon",
+	Phi:"Grčko veliko slovo fi",
+	Chi:"Grčko veliko slovo hi",
+	Psi:"Grčko veliko slovo psi",
+	Omega:"Grčko veliko slovo omega",
+	alpha:"Grčko malo slovo alfa",
+	beta:"Grčko malo slovo beta",
+	gamma:"Grčko malo slovo gama",
+	delta:"Grčko malo slovo delta",
+	epsilon:"Grčko malo slovo epsilon",
+	zeta:"Grčko malo slovo zeta",
+	eta:"Grčko malo slovo eta",
+	theta:"Grčko malo slovo theta",
+	iota:"Grčko malo slovo jota",
+	kappa:"Grčko malo slovo kapa",
+	lambda:"Grčko malo slovo lambda",
+	mu:"Grčko malo slovo mi",
+	nu:"Grčko malo slovo ni",
+	xi:"Grčko malo slovo ksi",
+	omicron:"Grčko malo slovo omikron",
+	pi:"Grčko malo slovo pi",
+	rho:"Grčko malo slovo ro",
+	sigmaf:"Grčko malo slovo zadnje sigma",
+	sigma:"Grčko malo slovo sigma",
+	tau:"Grčko malo slovo tau",
+	upsilon:"Grčko malo slovo ipsilon",
+	phi:"Grčko malo slovo fi",
+	chi:"Grčko malo slovo hi",
+	psi:"Grčko malo slovo psi",
+	omega:"Grčko malo slovo omega",
+	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",
+	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",
+	trade:"znak zaštitnog znaka",
+	alefsym:"simbol alef\nprvi transfinitni prost 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",
+	lArr:"dvostruka strelica ulijevo",
+	uArr:"dvostruka strelica prema gore",
+	rArr:"dvostruka strelica udesno",
+	dArr:"dvostruka strelica prema dolje",
+	hArr:"dvostruka strelica lijevo desno",
+	forall:"za sve",
+	part:"djelomični diferencijal",
+	exist:"tamo postoji",
+	empty:"prazan skup\nnull skup\ndijametar",
+	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",
+	minus:"znak minusa",
+	lowast:"operator zvjezdica",
+	radic:"kvadratni korijen\nznak 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",
+	there4:"prema tome",
+	sim:"operator tilda\nmijenja se s\nsličan",
+	cong:"približno jednako",
+	asymp:"pretežno jednako\nasimptotski",
+	ne:"nije jednako",
+	equiv:"identično",
+	le:"manje ili jednako",
+	ge:"veće ili jednako",
+	sub:"podskup",
+	sup:"nadskup",
+	nsub:"nije podskup",
+	sube:"podskup ili jednak",
+	supe:"nadskup oli jednak",
+	oplus:"zaokruženi plus\nizravna suma",
+	otimes:"zaokružen znak umnoška\numnožak vektora",
+	perp:"čvao prema gore\nortogonalan\nvertikalan",
+	sdot:"operator točka",
+	lceil:"lijevi stropni\nAPL lijevi stropni",
+	rceil:"desni stropni",
+	lfloor:"lijevi podni\nAPL lijevi podni",
+	rfloor:"desni podni",
+	lang:"uglata zagrada ulijevo",
+	rang:"uglata zagrada udesno",
+	loz:"dijamant",
+	spades:"boja crni pik",
+	clubs:"boja crni tref\ndjetelina",
+	hearts:"boja crni herc\nsrce",
+	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",
+	circ:"cirkumfleks akcent slova modifikatora",
+	tilde:"mala tilda",
+	ensp:"en prostor",
+	emsp:"em prostor",
+	thinsp:"tanak prostor",
+	zwnj:"ne-sastavljač nulte širine",
+	zwj:"sastavljač nulte širine",
+	lrm:"oznaka lijevo-desno",
+	rlm:"oznaka desno-lijevo",
+	ndash:"en crtica",
+	mdash:"em crtica",
+	lsquo:"lijevi jednostruki navodnik",
+	rsquo:"desni jednostruki navodnik",
+	sbquo:"jednostruki navodnik oblika male devetke",
+	ldquo:"lijevi dvostruki navodnik",
+	rdquo:"desni dvostruki navodnik",
+	bdquo:"dvostruki navodnik oblika male devetke",
+	dagger:"kama",
+	Dagger:"dvostruka kama",
+	permil:"znak milje",
+	lsaquo:"jednostruki navodnik ulijevo",
+	rsaquo:"jednostruki navodnik udesno",
+	euro:"znak eura"
+})
+);
diff --git a/dojox/editor/plugins/nls/hu/AutoSave.js b/dojox/editor/plugins/nls/hu/AutoSave.js
index 41d06c9..820d04c 100644
--- a/dojox/editor/plugins/nls/hu/AutoSave.js
+++ b/dojox/editor/plugins/nls/hu/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Mentés",
 	"saveSettingLabelOn": "Automatikus mentés időközének beállítása...",
@@ -12,3 +14,5 @@
 	"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 e1271e1..a6b3111 100644
--- a/dojox/editor/plugins/nls/hu/Blockquote.js
+++ b/dojox/editor/plugins/nls/hu/Blockquote.js
@@ -1,4 +1,8 @@
+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 4f80b8e..fc306ed 100644
--- a/dojox/editor/plugins/nls/hu/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/hu/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName} műveletek",
 	"selectContents": "Tartalom kiválasztása",
@@ -8,3 +10,5 @@
 	"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 6dd535e..7f84883 100644
--- a/dojox/editor/plugins/nls/hu/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/hu/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 71e8644..c146db0 100644
--- a/dojox/editor/plugins/nls/hu/FindReplace.js
+++ b/dojox/editor/plugins/nls/hu/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Keresés:",
 	"findTooltip": "Adja meg a keresett szöveget",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "Kis-nagybetűk egyeznek",
 	"backwards": "Visszafelé",
 	"backwardsTooltip": "Szöveg keresése visszafelé",
-	"replaceAll": "Minden előfordulás",
 	"replaceAllButton": "Mindent lecserél",
 	"replaceAllButtonTooltip": "Minden szöveg cseréje",
 	"findButton": "Keresés",
@@ -21,3 +22,5 @@
 	"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 1998bca..242fe0b 100644
--- a/dojox/editor/plugins/nls/hu/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/hu/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Horgony beszúrása",
 	title: "Horgony tulajdonságai",
@@ -7,3 +9,5 @@
 	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 51dddf1..8744bbd 100644
--- a/dojox/editor/plugins/nls/hu/InsertEntity.js
+++ b/dojox/editor/plugins/nls/hu/InsertEntity.js
@@ -1,4 +1,8 @@
+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 c9c99b1..4e0f2cb 100644
--- a/dojox/editor/plugins/nls/hu/LocalImage.js
+++ b/dojox/editor/plugins/nls/hu/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Kép beszúrása",
 	url: "Kép",
@@ -9,3 +11,5 @@
 	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 5536e17..12b4b38 100644
--- a/dojox/editor/plugins/nls/hu/PageBreak.js
+++ b/dojox/editor/plugins/nls/hu/PageBreak.js
@@ -1,4 +1,8 @@
+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 f0ce2b5..a515fec 100644
--- a/dojox/editor/plugins/nls/hu/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/hu/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Beillesztés Word alkalmazásból",
 	"paste": "Beillesztés",
@@ -5,3 +7,5 @@
 	"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 4053ccb..0d05ae2 100644
--- a/dojox/editor/plugins/nls/hu/Preview.js
+++ b/dojox/editor/plugins/nls/hu/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "Előzetes"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/hu/SafePaste.js b/dojox/editor/plugins/nls/hu/SafePaste.js
new file mode 100644
index 0000000..9203412
--- /dev/null
+++ b/dojox/editor/plugins/nls/hu/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "A közvetlen beillesztés le van tiltva. A böngésző szokványos beillesztési billentyűkombinációjával vagy menüparancsával illessze be a tartalmat ebbe a párbeszédpanelbe. Ha a beilleszteni kívánt tartalom megfelelő, kattintson a beillesztési gombra. A tartalom beillesztésének megszakításához kattintson a Mégse gombra."
+})
+);
diff --git a/dojox/editor/plugins/nls/hu/Save.js b/dojox/editor/plugins/nls/hu/Save.js
index 8d05ac5..07a7ffc 100644
--- a/dojox/editor/plugins/nls/hu/Save.js
+++ b/dojox/editor/plugins/nls/hu/Save.js
@@ -1,4 +1,8 @@
+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 10d4d96..2f1d299 100644
--- a/dojox/editor/plugins/nls/hu/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/hu/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 dd55a73..cff7a2a 100644
--- a/dojox/editor/plugins/nls/hu/Smiley.js
+++ b/dojox/editor/plugins/nls/hu/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Hangulatjel beszúrása",
 	emoticonSmile: "mosoly",
@@ -17,6 +19,9 @@
 	emoticonYes: "igen",
 	emoticonNo: "nem",
 	emoticonAngel: "angyal",
-	emoticonCrying: "sírás"
+	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 9b29fc5..bd1d7ed 100644
--- a/dojox/editor/plugins/nls/hu/SpellCheck.js
+++ b/dojox/editor/plugins/nls/hu/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Kötegelt helyesírás-ellenőrzés",
 	unfound: "Nem található",
@@ -15,3 +17,5 @@
 	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 3a134e4..d736041 100644
--- a/dojox/editor/plugins/nls/hu/TableDialog.js
+++ b/dojox/editor/plugins/nls/hu/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Táblázat beszúrása",
 	modifyTableTitle: "Táblázat módosítása",
@@ -28,3 +30,5 @@
 	deleteTableRowLabel: "Sor törlése",
 	deleteTableColumnLabel: "Oszlop törlése"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/hu/TextColor.js b/dojox/editor/plugins/nls/hu/TextColor.js
index 890e9a0..9e7f122 100644
--- a/dojox/editor/plugins/nls/hu/TextColor.js
+++ b/dojox/editor/plugins/nls/hu/TextColor.js
@@ -1,5 +1,9 @@
+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 224bdf7..536051c 100644
--- a/dojox/editor/plugins/nls/hu/latinEntities.js
+++ b/dojox/editor/plugins/nls/hu/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	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 10697ae..dcc1292 100644
--- a/dojox/editor/plugins/nls/it/AutoSave.js
+++ b/dojox/editor/plugins/nls/it/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Salva",
 	"saveSettingLabelOn": "Imposta intervallo di salvataggio automatico...",
@@ -12,3 +14,5 @@
 	"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 859084b..e54a9ba 100644
--- a/dojox/editor/plugins/nls/it/Blockquote.js
+++ b/dojox/editor/plugins/nls/it/Blockquote.js
@@ -1,4 +1,8 @@
+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 964b81d..862df3f 100644
--- a/dojox/editor/plugins/nls/it/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/it/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "Azioni ${nodeName}",
 	"selectContents": "Seleziona contenuto",
@@ -8,3 +10,5 @@
 	"moveEnd": "Sposta il cursore per terminare"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/it/CollapsibleToolbar.js b/dojox/editor/plugins/nls/it/CollapsibleToolbar.js
index 0c91077..5daf5c6 100644
--- a/dojox/editor/plugins/nls/it/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/it/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	"collapse": "Comprimi la barra degli strumenti dell'editor",
 	"expand": "Espandi la 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 7a60ef5..4d1320c 100644
--- a/dojox/editor/plugins/nls/it/FindReplace.js
+++ b/dojox/editor/plugins/nls/it/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Trova:",
 	"findTooltip": "Immettere il testo da trovare",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "Maiuscole/minuscole",
 	"backwards": "Indietro",
 	"backwardsTooltip": "Cerca testo indietro",
-	"replaceAll": "Tutte le ricorrenze",
 	"replaceAllButton": "Sostituisci tutto",
 	"replaceAllButtonTooltip": "Sostituisci tutto il testo",
 	"findButton": "Trova",
@@ -21,3 +22,5 @@
 	"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 2b1f40d..ac095b2 100644
--- a/dojox/editor/plugins/nls/it/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/it/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Inserisci ancoraggio",
 	title: "Proprietà ancoraggio",
@@ -7,3 +9,5 @@
 	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 838342b..32e3afc 100644
--- a/dojox/editor/plugins/nls/it/InsertEntity.js
+++ b/dojox/editor/plugins/nls/it/InsertEntity.js
@@ -1,4 +1,8 @@
+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 ba09478..664bf37 100644
--- a/dojox/editor/plugins/nls/it/LocalImage.js
+++ b/dojox/editor/plugins/nls/it/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Inserisci immagine",
 	url: "Immagine",
@@ -9,3 +11,5 @@
 	prePopuTextBrowse: " o individuare 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 8ffbce3..277463f 100644
--- a/dojox/editor/plugins/nls/it/PageBreak.js
+++ b/dojox/editor/plugins/nls/it/PageBreak.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"pageBreak": "Interruzione di pagina"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/it/PasteFromWord.js b/dojox/editor/plugins/nls/it/PasteFromWord.js
index 0c856ff..0aff219 100644
--- a/dojox/editor/plugins/nls/it/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/it/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Incolla da Word",
 	"paste": "Incolla",
@@ -5,3 +7,5 @@
 	"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."
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/it/Preview.js b/dojox/editor/plugins/nls/it/Preview.js
index 74543b1..6415dfd 100644
--- a/dojox/editor/plugins/nls/it/Preview.js
+++ b/dojox/editor/plugins/nls/it/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "Anteprima"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/it/SafePaste.js b/dojox/editor/plugins/nls/it/SafePaste.js
new file mode 100644
index 0000000..f697476
--- /dev/null
+++ b/dojox/editor/plugins/nls/it/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "Non è possibile incollare direttamente. Incollare i contenuti in questa finestra di dialogo utilizzando i controlli standard da menu o da tastiera del browser. Quando si è deciso quali contenuti inserire, fare clic sul pulsante incolla. Per interrompere l'inserimento dei contenuti premere il pulsante annulla."
+})
+);
diff --git a/dojox/editor/plugins/nls/it/Save.js b/dojox/editor/plugins/nls/it/Save.js
index 4a1b9aa..dd9f6aa 100644
--- a/dojox/editor/plugins/nls/it/Save.js
+++ b/dojox/editor/plugins/nls/it/Save.js
@@ -1,4 +1,8 @@
+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 5ada271..42dfb82 100644
--- a/dojox/editor/plugins/nls/it/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/it/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 c01a814..b73a8a8 100644
--- a/dojox/editor/plugins/nls/it/Smiley.js
+++ b/dojox/editor/plugins/nls/it/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Inserisci emoticon",
 	emoticonSmile: "sorriso",
@@ -17,6 +19,9 @@
 	emoticonYes: "yes",
 	emoticonNo: "no",
 	emoticonAngel: "angelo",
-	emoticonCrying: "in lacrime"
+	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 4546c0b..b37311d 100644
--- a/dojox/editor/plugins/nls/it/SpellCheck.js
+++ b/dojox/editor/plugins/nls/it/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Controllo ortografico batch",
 	unfound: "Non trovato",
@@ -15,3 +17,5 @@
 	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 293c6d8..42859cd 100644
--- a/dojox/editor/plugins/nls/it/TableDialog.js
+++ b/dojox/editor/plugins/nls/it/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Inserisci tabella",
 	modifyTableTitle: "Modifica tabella",
@@ -30,3 +32,5 @@
 })
 	
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/it/TextColor.js b/dojox/editor/plugins/nls/it/TextColor.js
index af28fa6..1b9c6d7 100644
--- a/dojox/editor/plugins/nls/it/TextColor.js
+++ b/dojox/editor/plugins/nls/it/TextColor.js
@@ -1,5 +1,9 @@
+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 7bd05bf..1737571 100644
--- a/dojox/editor/plugins/nls/it/latinEntities.js
+++ b/dojox/editor/plugins/nls/it/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	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 5c0cc4b..c259643 100644
--- a/dojox/editor/plugins/nls/ja/AutoSave.js
+++ b/dojox/editor/plugins/nls/ja/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "保存",
 	"saveSettingLabelOn": "自動保存間隔の設定...",
@@ -11,3 +13,5 @@
 	"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 deaf4d9..afe5edb 100644
--- a/dojox/editor/plugins/nls/ja/Blockquote.js
+++ b/dojox/editor/plugins/nls/ja/Blockquote.js
@@ -1,3 +1,7 @@
+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 cca348e..f2a80ad 100644
--- a/dojox/editor/plugins/nls/ja/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/ja/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName} アクション",
 	"selectContents": "内容の選択",
@@ -8,3 +10,5 @@
 	"moveEnd": "終了するためにカーソルを移動"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ja/CollapsibleToolbar.js b/dojox/editor/plugins/nls/ja/CollapsibleToolbar.js
index ba03720..59fc19a 100644
--- a/dojox/editor/plugins/nls/ja/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/ja/CollapsibleToolbar.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"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 21b7bf9..ec7332c 100644
--- a/dojox/editor/plugins/nls/ja/FindReplace.js
+++ b/dojox/editor/plugins/nls/ja/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "検索内容:",
 	"findTooltip": "検索するテキストを入力",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "大/小文字を区別",
 	"backwards": "後方",
 	"backwardsTooltip": "テキストを後方検索",
-	"replaceAll": "すべてのオカレンス",
 	"replaceAllButton": "すべてを置換",
 	"replaceAllButtonTooltip": "テキストすべてを置換",
 	"findButton": "検索",
@@ -20,3 +21,5 @@
 	"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 fdb8455..8ad3b62 100644
--- a/dojox/editor/plugins/nls/ja/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/ja/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "アンカーの挿入",
 	title: "アンカー・プロパティー",
@@ -6,3 +8,5 @@
 	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 f762af5..9907681 100644
--- a/dojox/editor/plugins/nls/ja/InsertEntity.js
+++ b/dojox/editor/plugins/nls/ja/InsertEntity.js
@@ -1,4 +1,8 @@
+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 aec866f..2f3cfb2 100644
--- a/dojox/editor/plugins/nls/ja/LocalImage.js
+++ b/dojox/editor/plugins/nls/ja/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "イメージの挿入",
 	url: "イメージ",
@@ -8,3 +10,5 @@
 	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 a3d63a7..44e5b61 100644
--- a/dojox/editor/plugins/nls/ja/PageBreak.js
+++ b/dojox/editor/plugins/nls/ja/PageBreak.js
@@ -1,4 +1,8 @@
+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 bc277c7..ec21e28 100644
--- a/dojox/editor/plugins/nls/ja/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/ja/PasteFromWord.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Word からの貼り付け",
 	"paste": "貼り付け",
 	"cancel": "キャンセル",
 	"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 26d3baa..b1121a6 100644
--- a/dojox/editor/plugins/nls/ja/Preview.js
+++ b/dojox/editor/plugins/nls/ja/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "プレビュー"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ja/SafePaste.js b/dojox/editor/plugins/nls/ja/SafePaste.js
new file mode 100644
index 0000000..19deedf
--- /dev/null
+++ b/dojox/editor/plugins/nls/ja/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "直接貼り付けはできません。ブラウザーのキーボードまたはメニューによる標準制御を使用して、コンテンツをこのダイアログに貼り付けでください。コンテンツを確認して問題がなければ、貼り付けボタンを押してコンテンツを挿入してください。挿入しない場合は、キャンセル・ボタンを押してください。"
+})
+);
diff --git a/dojox/editor/plugins/nls/ja/Save.js b/dojox/editor/plugins/nls/ja/Save.js
index dcfcf05..16e07aa 100644
--- a/dojox/editor/plugins/nls/ja/Save.js
+++ b/dojox/editor/plugins/nls/ja/Save.js
@@ -1,4 +1,8 @@
+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 74ea4a3..cdf1cfa 100644
--- a/dojox/editor/plugins/nls/ja/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/ja/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 411d64e..ea92ec0 100644
--- a/dojox/editor/plugins/nls/ja/Smiley.js
+++ b/dojox/editor/plugins/nls/ja/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "顔文字の挿入",
 	emoticonSmile: "微笑",
@@ -17,6 +19,9 @@
 	emoticonYes: "はい",
 	emoticonNo: "いいえ",
 	emoticonAngel: "エンジェル",
-	emoticonCrying: "泣く"
+	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 d1a2768..b87055a 100644
--- a/dojox/editor/plugins/nls/ja/SpellCheck.js
+++ b/dojox/editor/plugins/nls/ja/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "一括スペル・チェック",
 	unfound: "見つかりません",
@@ -14,3 +16,5 @@
 	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 644850e..4be4c85 100644
--- a/dojox/editor/plugins/nls/ja/TableDialog.js
+++ b/dojox/editor/plugins/nls/ja/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "テーブルの挿入",
 	modifyTableTitle: "テーブルの変更",
@@ -29,3 +31,5 @@
 	deleteTableColumnLabel: "列の削除"
 })
 	
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ja/TextColor.js b/dojox/editor/plugins/nls/ja/TextColor.js
index a59d4e7..df114fa 100644
--- a/dojox/editor/plugins/nls/ja/TextColor.js
+++ b/dojox/editor/plugins/nls/ja/TextColor.js
@@ -1,4 +1,8 @@
+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 82830a5..579c710 100644
--- a/dojox/editor/plugins/nls/ja/latinEntities.js
+++ b/dojox/editor/plugins/nls/ja/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	euro:"ユーロ記号"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/kk/AutoSave.js b/dojox/editor/plugins/nls/kk/AutoSave.js
index 19c3fc0..15c8ff3 100644
--- a/dojox/editor/plugins/nls/kk/AutoSave.js
+++ b/dojox/editor/plugins/nls/kk/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Сақтау",
 	"saveSettingLabelOn": "Автосақтау аралығын орнату...",
@@ -12,3 +14,5 @@
 	"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 859084b..e54a9ba 100644
--- a/dojox/editor/plugins/nls/kk/Blockquote.js
+++ b/dojox/editor/plugins/nls/kk/Blockquote.js
@@ -1,4 +1,8 @@
+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 c567e05..2f05e88 100644
--- a/dojox/editor/plugins/nls/kk/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/kk/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName} Әрекеттер",
 	"selectContents": "Мазмұнын таңдау",
@@ -8,3 +10,5 @@
 	"moveEnd": "Жүгіргіні аяғына жылжыту"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/kk/CollapsibleToolbar.js b/dojox/editor/plugins/nls/kk/CollapsibleToolbar.js
index 9bc93bb..a17abb2 100644
--- a/dojox/editor/plugins/nls/kk/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/kk/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 33f64c2..6392848 100644
--- a/dojox/editor/plugins/nls/kk/FindReplace.js
+++ b/dojox/editor/plugins/nls/kk/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Табу:",
 	"findTooltip": "Табылатын мәтінді енгізу",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "Үлкен-кішілігін ескеріп",
 	"backwards": "Артқа қарай",
 	"backwardsTooltip": "Мәтінді табу үшін артқа қарай іздеу",
-	"replaceAll": "Барлық оқиғалар",
 	"replaceAllButton": "Барлығын ауыстыру",
 	"replaceAllButtonTooltip": "Барлық мәтінді ауыстыру",
 	"findButton": "Табу",
@@ -21,3 +22,5 @@
 	"eofDialogTextReplace": "ауыстырылды"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/kk/InsertAnchor.js b/dojox/editor/plugins/nls/kk/InsertAnchor.js
index be15181..f6d2654 100644
--- a/dojox/editor/plugins/nls/kk/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/kk/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Бетбелгі кірістіру",
 	title: "Бетбелгі сипаттары",
@@ -7,3 +9,5 @@
 	cancel: "Болдырмау"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/kk/InsertEntity.js b/dojox/editor/plugins/nls/kk/InsertEntity.js
index 588f2c7..5b424c1 100644
--- a/dojox/editor/plugins/nls/kk/InsertEntity.js
+++ b/dojox/editor/plugins/nls/kk/InsertEntity.js
@@ -1,4 +1,8 @@
+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 9a9fa10..d4ac2ff 100644
--- a/dojox/editor/plugins/nls/kk/LocalImage.js
+++ b/dojox/editor/plugins/nls/kk/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Сурет кірістіру",
 	url: "Кескін",
@@ -9,3 +11,5 @@
 	prePopuTextBrowse: " немесе жергілікті файлға өтіңіз."
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/kk/PageBreak.js b/dojox/editor/plugins/nls/kk/PageBreak.js
index 68d46b0..ecbcd75 100644
--- a/dojox/editor/plugins/nls/kk/PageBreak.js
+++ b/dojox/editor/plugins/nls/kk/PageBreak.js
@@ -1,4 +1,8 @@
+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 de8c8c2..745ce31 100644
--- a/dojox/editor/plugins/nls/kk/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/kk/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Word бағдарламасынан қою",
 	"paste": "Қою",
@@ -5,3 +7,5 @@
 	"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 1cb20dd..35b9025 100644
--- a/dojox/editor/plugins/nls/kk/Preview.js
+++ b/dojox/editor/plugins/nls/kk/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "Алдын ала қарау"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/kk/SafePaste.js b/dojox/editor/plugins/nls/kk/SafePaste.js
new file mode 100644
index 0000000..3531325
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "Тікелей қою ажыратылды.  Стандартты шолғыш пернетақтасын немесе мәзір қоюдың басқару элементтерін пайдаланып, мазмұнды осы тілқатысу терезесіне қойыңыз.  Кірістірілетіен мазмұнмен қанағаттансаңыз, қою түймешігін басыңыз. Мазмұн қоюды тоқтатқыңыз келсе, болдырмау түймешігін басыңыз."
+})
+);
diff --git a/dojox/editor/plugins/nls/kk/Save.js b/dojox/editor/plugins/nls/kk/Save.js
index 1d871dc..347c126 100644
--- a/dojox/editor/plugins/nls/kk/Save.js
+++ b/dojox/editor/plugins/nls/kk/Save.js
@@ -1,4 +1,8 @@
+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 3f6913c..958a69d 100644
--- a/dojox/editor/plugins/nls/kk/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/kk/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 6552abd..c84a840 100644
--- a/dojox/editor/plugins/nls/kk/Smiley.js
+++ b/dojox/editor/plugins/nls/kk/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Эмограмма енгізу",
 	emoticonSmile: "күлімсіреу",
@@ -17,6 +19,9 @@
 	emoticonYes: "иә",
 	emoticonNo: "ешбір",
 	emoticonAngel: "періште",
-	emoticonCrying: "жылау"
+	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 f275c14..b063e6f 100644
--- a/dojox/editor/plugins/nls/kk/SpellCheck.js
+++ b/dojox/editor/plugins/nls/kk/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Бума емлесін тексеру",
 	unfound: "Табылмады",
@@ -15,3 +17,5 @@
 	iMsg: "Емле ұсыныстары жоқ"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/kk/TableDialog.js b/dojox/editor/plugins/nls/kk/TableDialog.js
index 410658a..5ee0d74 100644
--- a/dojox/editor/plugins/nls/kk/TableDialog.js
+++ b/dojox/editor/plugins/nls/kk/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Кесте кірістіру",
 	modifyTableTitle: "Кестені өзгерту",
@@ -30,3 +32,5 @@
 })
 	
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/kk/TextColor.js b/dojox/editor/plugins/nls/kk/TextColor.js
index 679b1ab..1328e29 100644
--- a/dojox/editor/plugins/nls/kk/TextColor.js
+++ b/dojox/editor/plugins/nls/kk/TextColor.js
@@ -1,5 +1,9 @@
+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 3dbd692..600f9b6 100644
--- a/dojox/editor/plugins/nls/kk/latinEntities.js
+++ b/dojox/editor/plugins/nls/kk/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	euro:"еуро белгісі"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ko/AutoSave.js b/dojox/editor/plugins/nls/ko/AutoSave.js
index a691dff..5b4e120 100644
--- a/dojox/editor/plugins/nls/ko/AutoSave.js
+++ b/dojox/editor/plugins/nls/ko/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "저장",
 	"saveSettingLabelOn": "자동 저장 간격 설정...",
@@ -12,3 +14,5 @@
 	"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 859084b..e54a9ba 100644
--- a/dojox/editor/plugins/nls/ko/Blockquote.js
+++ b/dojox/editor/plugins/nls/ko/Blockquote.js
@@ -1,4 +1,8 @@
+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 a26516c..51badb5 100755
--- a/dojox/editor/plugins/nls/ko/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/ko/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName} 조치",
 	"selectContents": "컨텐츠 선택",
@@ -8,3 +10,5 @@
 	"moveEnd": "커서를 이동하여 종료"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ko/CollapsibleToolbar.js b/dojox/editor/plugins/nls/ko/CollapsibleToolbar.js
index 6b8a2f1..93b51c3 100644
--- a/dojox/editor/plugins/nls/ko/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/ko/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 da6df43..1d59185 100755
--- a/dojox/editor/plugins/nls/ko/FindReplace.js
+++ b/dojox/editor/plugins/nls/ko/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "찾기:",
 	"findTooltip": "찾을 텍스트 입력",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "대소문자 구분",
 	"backwards": "뒤로",
 	"backwardsTooltip": "텍스트 역방향 검색",
-	"replaceAll": "모든 발생",
 	"replaceAllButton": "모두 바꾸기",
 	"replaceAllButtonTooltip": "텍스트 모두 바꾸기",
 	"findButton": "찾기",
@@ -20,3 +21,5 @@
 	"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 c29b77b..6c5a5b1 100644
--- a/dojox/editor/plugins/nls/ko/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/ko/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "기준 위치 삽입",
 	title: "기준 위치 특성",
@@ -7,3 +9,5 @@
 	cancel: "취소"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ko/InsertEntity.js b/dojox/editor/plugins/nls/ko/InsertEntity.js
index 0039e4b..4e59b4c 100755
--- a/dojox/editor/plugins/nls/ko/InsertEntity.js
+++ b/dojox/editor/plugins/nls/ko/InsertEntity.js
@@ -1,4 +1,8 @@
+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 2492bbc..6711b28 100644
--- a/dojox/editor/plugins/nls/ko/LocalImage.js
+++ b/dojox/editor/plugins/nls/ko/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "이미지 삽입",
 	url: "이미지",
@@ -9,3 +11,5 @@
 	prePopuTextBrowse: "또는 로컬 파일 찾아보기"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ko/PageBreak.js b/dojox/editor/plugins/nls/ko/PageBreak.js
index 6a0836a..c79a3a4 100755
--- a/dojox/editor/plugins/nls/ko/PageBreak.js
+++ b/dojox/editor/plugins/nls/ko/PageBreak.js
@@ -1,4 +1,8 @@
+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 86c979a..8ee9e7e 100644
--- a/dojox/editor/plugins/nls/ko/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/ko/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "단어에서 붙여넣기",
 	"paste": "붙여넣기",
@@ -5,3 +7,5 @@
 	"instructions": "단어에서 아래 텍스트 상자로 컨텐츠를 붙여 넣으십시오. 삽입할 컨텐츠가 준비되면 붙여넣기 단추를 누르십시오. 텍스트 삽입을 중단하려면 취소 단추를 누르십시오. "
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ko/Preview.js b/dojox/editor/plugins/nls/ko/Preview.js
index b340961..6ceb255 100755
--- a/dojox/editor/plugins/nls/ko/Preview.js
+++ b/dojox/editor/plugins/nls/ko/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "미리보기"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ko/SafePaste.js b/dojox/editor/plugins/nls/ko/SafePaste.js
new file mode 100644
index 0000000..8b82a42
--- /dev/null
+++ b/dojox/editor/plugins/nls/ko/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "직접 붙여넣기는 사용할 수 없습니다. 표준 브라우저 키보드 또는 메뉴 붙여넣기 컨트롤을 사용하여 이 대화 상자의 컨텐츠를 붙여 넣으십시오. 삽입할 컨텐츠가 준비되면 붙여넣기 단추를 누르십시오. 컨텐츠 삽입을 중단하려면 취소 단추를 누르십시오."
+})
+);
diff --git a/dojox/editor/plugins/nls/ko/Save.js b/dojox/editor/plugins/nls/ko/Save.js
index ba6eced..ba3095b 100755
--- a/dojox/editor/plugins/nls/ko/Save.js
+++ b/dojox/editor/plugins/nls/ko/Save.js
@@ -1,4 +1,8 @@
+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 1b8005c..7f4f76f 100755
--- a/dojox/editor/plugins/nls/ko/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/ko/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 fc34dec..c72b291 100644
--- a/dojox/editor/plugins/nls/ko/Smiley.js
+++ b/dojox/editor/plugins/nls/ko/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "이모티콘 삽입",
 	emoticonSmile: "미소",
@@ -17,5 +19,8 @@
 	emoticonYes: "예",
 	emoticonNo: "아니오",
 	emoticonAngel: "천사",
-	emoticonCrying: "울음"
+	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 5cc229a..3ef51df 100644
--- a/dojox/editor/plugins/nls/ko/SpellCheck.js
+++ b/dojox/editor/plugins/nls/ko/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "맞춤법 검사 일괄처리",
 	unfound: "찾을 수 없음",
@@ -15,3 +17,5 @@
 	iMsg: "맞춤법 제안 없음"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ko/TableDialog.js b/dojox/editor/plugins/nls/ko/TableDialog.js
index 852c8b8..37f53f0 100644
--- a/dojox/editor/plugins/nls/ko/TableDialog.js
+++ b/dojox/editor/plugins/nls/ko/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "테이블 삽입",
 	modifyTableTitle: "테이블 수정",
@@ -28,3 +30,5 @@
 	deleteTableRowLabel: "행 삭제",
 	deleteTableColumnLabel: "열 삭제"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ko/TextColor.js b/dojox/editor/plugins/nls/ko/TextColor.js
index cf91979..f4113e2 100644
--- a/dojox/editor/plugins/nls/ko/TextColor.js
+++ b/dojox/editor/plugins/nls/ko/TextColor.js
@@ -1,5 +1,9 @@
+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 9433b67..7f81478 100644
--- a/dojox/editor/plugins/nls/ko/latinEntities.js
+++ b/dojox/editor/plugins/nls/ko/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	euro:"euro 기호"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/latinEntities.js b/dojox/editor/plugins/nls/latinEntities.js
index ca7f715..a95ac2e 100644
--- a/dojox/editor/plugins/nls/latinEntities.js
+++ b/dojox/editor/plugins/nls/latinEntities.js
@@ -1,3 +1,5 @@
+define({ root:
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -254,3 +256,36 @@
 	rsaquo:"single right-pointing angle quotation mark",
 	euro:"euro sign"
 })
+,
+//end v1.x content
+"zh": true,
+"zh-tw": 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,
+"ar": true
+});
diff --git a/dojox/editor/plugins/nls/nb/AutoSave.js b/dojox/editor/plugins/nls/nb/AutoSave.js
index 24be57b..87dfccc 100644
--- a/dojox/editor/plugins/nls/nb/AutoSave.js
+++ b/dojox/editor/plugins/nls/nb/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Lagre",
 	"saveSettingLabelOn": "Angi intervall for automatisk lagring...",
@@ -11,3 +13,5 @@
 	"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 40fa6eb..87e18cd 100644
--- a/dojox/editor/plugins/nls/nb/Blockquote.js
+++ b/dojox/editor/plugins/nls/nb/Blockquote.js
@@ -1,3 +1,7 @@
+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 223b72d..1f2b107 100644
--- a/dojox/editor/plugins/nls/nb/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/nb/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName} Handlinger",
 	"selectContents": "Velg innhold",
@@ -7,3 +9,5 @@
 	"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 8e0e85e..6c5adf6 100644
--- a/dojox/editor/plugins/nls/nb/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/nb/CollapsibleToolbar.js
@@ -1,4 +1,8 @@
+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 16ecca2..6d09123 100644
--- a/dojox/editor/plugins/nls/nb/FindReplace.js
+++ b/dojox/editor/plugins/nls/nb/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Søk:",
 	"findTooltip": "Skriv inn teksten du vil søke etter",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "Skill mellom store og små bokstaver",
 	"backwards": "Bakover",
 	"backwardsTooltip": "Søk bakover etter tekst",
-	"replaceAll": "Alle forekomster",
 	"replaceAllButton": "Erstatt alle",
 	"replaceAllButtonTooltip": "Erstatt all tekst",
 	"findButton": "Søk",
@@ -20,3 +21,5 @@
 	"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 e53bc13..b03c87f 100644
--- a/dojox/editor/plugins/nls/nb/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/nb/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Sett inn anker",
 	title: "Ankeregenskaper",
@@ -6,3 +8,5 @@
 	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 0bce161..371a8e7 100644
--- a/dojox/editor/plugins/nls/nb/InsertEntity.js
+++ b/dojox/editor/plugins/nls/nb/InsertEntity.js
@@ -1,3 +1,7 @@
+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 5f07d91..65d116d 100644
--- a/dojox/editor/plugins/nls/nb/LocalImage.js
+++ b/dojox/editor/plugins/nls/nb/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Sett inn bilde",
 	url: "Bilde",
@@ -8,3 +10,5 @@
 	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 aad5cd4..87355c1 100644
--- a/dojox/editor/plugins/nls/nb/PageBreak.js
+++ b/dojox/editor/plugins/nls/nb/PageBreak.js
@@ -1,3 +1,7 @@
+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 0892207..5e11b2d 100644
--- a/dojox/editor/plugins/nls/nb/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/nb/PasteFromWord.js
@@ -1,6 +1,10 @@
+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 b821bea..3572550 100644
--- a/dojox/editor/plugins/nls/nb/Preview.js
+++ b/dojox/editor/plugins/nls/nb/Preview.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 ({
 	"preview": "Forhåndsvis"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/nb/SafePaste.js b/dojox/editor/plugins/nls/nb/SafePaste.js
new file mode 100644
index 0000000..8e8034c
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "Direkte innliming er deaktivert. Lim inn innhold i denne dialogboksen ved hjelp av standard innlimingstaster eller -menyvalg i nettleseren. Når du er fornøyd med innholdet du skal sette inn, trykker du på innlimingsknappen. Hvis du vil avbryte innsettingen av innholdet, trykker du på avbruddsknappen."
+})
+);
diff --git a/dojox/editor/plugins/nls/nb/Save.js b/dojox/editor/plugins/nls/nb/Save.js
index 0608da8..f6af5ef 100644
--- a/dojox/editor/plugins/nls/nb/Save.js
+++ b/dojox/editor/plugins/nls/nb/Save.js
@@ -1,3 +1,7 @@
+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 e5964c0..86bc92a 100644
--- a/dojox/editor/plugins/nls/nb/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/nb/ShowBlockNodes.js
@@ -1,3 +1,7 @@
+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 f4f8730..b96df2a 100644
--- a/dojox/editor/plugins/nls/nb/Smiley.js
+++ b/dojox/editor/plugins/nls/nb/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Sett inn uttrykksikon",
 	emoticonSmile: "smil",
@@ -17,5 +19,8 @@
 	emoticonYes: "ja",
 	emoticonNo: "nei",
 	emoticonAngel: "engel",
-	emoticonCrying: "gråt"
+	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 2e8d58c..b074bab 100644
--- a/dojox/editor/plugins/nls/nb/SpellCheck.js
+++ b/dojox/editor/plugins/nls/nb/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Satsvis stavekontroll",
 	unfound: "Ikke funnet",
@@ -14,3 +16,5 @@
 	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 ce412e1..9d4adbe 100644
--- a/dojox/editor/plugins/nls/nb/TableDialog.js
+++ b/dojox/editor/plugins/nls/nb/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Sett inn tabell",
 	modifyTableTitle: "Endre tabell",
@@ -28,3 +30,5 @@
 	deleteTableRowLabel: "Slett rad",
 	deleteTableColumnLabel: "Slett kolonne"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/nb/TextColor.js b/dojox/editor/plugins/nls/nb/TextColor.js
index e53687b..ef90e55 100644
--- a/dojox/editor/plugins/nls/nb/TextColor.js
+++ b/dojox/editor/plugins/nls/nb/TextColor.js
@@ -1,4 +1,8 @@
+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 ae206b5..a9ea4ec 100644
--- a/dojox/editor/plugins/nls/nb/latinEntities.js
+++ b/dojox/editor/plugins/nls/nb/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -254,3 +256,5 @@
 	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 9699de1..e4f458c 100644
--- a/dojox/editor/plugins/nls/nl/AutoSave.js
+++ b/dojox/editor/plugins/nls/nl/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Opslaan",
 	"saveSettingLabelOn": "Interval voor automatisch opslaan instellen...",
@@ -12,3 +14,5 @@
 	"saveMessageFail": "Opslaan mislukt op ${0}"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/nl/Blockquote.js b/dojox/editor/plugins/nls/nl/Blockquote.js
index 859084b..e54a9ba 100644
--- a/dojox/editor/plugins/nls/nl/Blockquote.js
+++ b/dojox/editor/plugins/nls/nl/Blockquote.js
@@ -1,4 +1,8 @@
+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 8ceefd0..252cf2d 100644
--- a/dojox/editor/plugins/nls/nl/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/nl/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName} Acties",
 	"selectContents": "Inhoud selecteren",
@@ -8,3 +10,5 @@
 	"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 adb6cae..8cbb506 100644
--- a/dojox/editor/plugins/nls/nl/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/nl/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 798af2a..d3c2a38 100644
--- a/dojox/editor/plugins/nls/nl/FindReplace.js
+++ b/dojox/editor/plugins/nls/nl/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Zoeken:",
 	"findTooltip": "Geef de zoektekst op",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "Hoofdlettergevoelig",
 	"backwards": "Terug",
 	"backwardsTooltip": "Terugwaarts naar tekst zoeken",
-	"replaceAll": "Alle posities",
 	"replaceAllButton": "Alle vervangen",
 	"replaceAllButtonTooltip": "Gehele tekst vervangen",
 	"findButton": "Zoeken:",
@@ -21,3 +22,5 @@
 	"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 958aee6..71e26f4 100644
--- a/dojox/editor/plugins/nls/nl/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/nl/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Anker invoegen",
 	title: "Ankereigenschappen",
@@ -7,3 +9,5 @@
 	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 145b9b8..65fd62b 100644
--- a/dojox/editor/plugins/nls/nl/InsertEntity.js
+++ b/dojox/editor/plugins/nls/nl/InsertEntity.js
@@ -1,4 +1,8 @@
+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 401d1d9..d115c23 100644
--- a/dojox/editor/plugins/nls/nl/LocalImage.js
+++ b/dojox/editor/plugins/nls/nl/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Afbeelding invoegen",
 	url: "Afbeelding",
@@ -9,3 +11,5 @@
 	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 c7ec1fa..a454a4c 100644
--- a/dojox/editor/plugins/nls/nl/PageBreak.js
+++ b/dojox/editor/plugins/nls/nl/PageBreak.js
@@ -1,4 +1,8 @@
+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 3087ce8..dab82ba 100644
--- a/dojox/editor/plugins/nls/nl/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/nl/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Plakken vanuit Word",
 	"paste": "Plakken",
@@ -5,3 +7,5 @@
 	"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 54c0dd2..1b5c179 100644
--- a/dojox/editor/plugins/nls/nl/Preview.js
+++ b/dojox/editor/plugins/nls/nl/Preview.js
@@ -1,4 +1,8 @@
+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
new file mode 100644
index 0000000..adbc3e2
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/SafePaste.js
@@ -0,0 +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."
+})
+);
diff --git a/dojox/editor/plugins/nls/nl/Save.js b/dojox/editor/plugins/nls/nl/Save.js
index ea761a1..472d7ef 100644
--- a/dojox/editor/plugins/nls/nl/Save.js
+++ b/dojox/editor/plugins/nls/nl/Save.js
@@ -1,4 +1,8 @@
+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 d2d13b8..e319e83 100644
--- a/dojox/editor/plugins/nls/nl/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/nl/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 26d115c..847d98e 100644
--- a/dojox/editor/plugins/nls/nl/Smiley.js
+++ b/dojox/editor/plugins/nls/nl/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Emoticon invoegen",
 	emoticonSmile: "glimlach",
@@ -17,6 +19,9 @@
 	emoticonYes: "ja",
 	emoticonNo: "nee",
 	emoticonAngel: "engel",
-	emoticonCrying: "bedroefd"
+	emoticonCrying: "bedroefd",
+	emoticonHappy: "vrolijk"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/nl/SpellCheck.js b/dojox/editor/plugins/nls/nl/SpellCheck.js
index 69d4a8a..931667e 100644
--- a/dojox/editor/plugins/nls/nl/SpellCheck.js
+++ b/dojox/editor/plugins/nls/nl/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Groepsgewijze spellingcontrole",
 	unfound: "Niet gevonden",
@@ -15,3 +17,5 @@
 	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 16df279..88c0d7d 100644
--- a/dojox/editor/plugins/nls/nl/TableDialog.js
+++ b/dojox/editor/plugins/nls/nl/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Tabel invoegen",
 	modifyTableTitle: "Tabel wijzigen",
@@ -28,3 +30,5 @@
 	deleteTableRowLabel: "Rij wissen",
 	deleteTableColumnLabel: "Kolom wissen"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/nl/TextColor.js b/dojox/editor/plugins/nls/nl/TextColor.js
index e43b60c..33fda27 100644
--- a/dojox/editor/plugins/nls/nl/TextColor.js
+++ b/dojox/editor/plugins/nls/nl/TextColor.js
@@ -1,5 +1,9 @@
+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 6367f61..7a3b45f 100644
--- a/dojox/editor/plugins/nls/nl/latinEntities.js
+++ b/dojox/editor/plugins/nls/nl/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	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 8b89855..bce25dc 100644
--- a/dojox/editor/plugins/nls/pl/AutoSave.js
+++ b/dojox/editor/plugins/nls/pl/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Zapisz",
 	"saveSettingLabelOn": "Ustaw odstęp czasu automatycznego zapisywania...",
@@ -12,3 +14,5 @@
 	"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 a948b82..ef57d5d 100644
--- a/dojox/editor/plugins/nls/pl/Blockquote.js
+++ b/dojox/editor/plugins/nls/pl/Blockquote.js
@@ -1,4 +1,8 @@
+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 8f58e55..c4114bc 100644
--- a/dojox/editor/plugins/nls/pl/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/pl/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName} - działania",
 	"selectContents": "Zaznacz treść",
@@ -8,3 +10,5 @@
 	"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 b034f4e..0a9b0e6 100644
--- a/dojox/editor/plugins/nls/pl/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/pl/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 0833763..ffa9499 100644
--- a/dojox/editor/plugins/nls/pl/FindReplace.js
+++ b/dojox/editor/plugins/nls/pl/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Znajdź:",
 	"findTooltip": "Wprowadź szukany tekst",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "Uwzględnij wielkość liter",
 	"backwards": "Do tyłu",
 	"backwardsTooltip": "Wyszukaj tekst wstecz",
-	"replaceAll": "Wszystkie wystąpienia",
 	"replaceAllButton": "Zastąp wszystkie",
 	"replaceAllButtonTooltip": "Zastąp cały tekst",
 	"findButton": "Znajdź",
@@ -21,3 +22,5 @@
 	"eofDialogTextReplace": "zastąpiono"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/pl/InsertAnchor.js b/dojox/editor/plugins/nls/pl/InsertAnchor.js
index 912f9b2..844652f 100644
--- a/dojox/editor/plugins/nls/pl/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/pl/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Wstaw zakotwiczenie",
 	title: "Właściwości zakotwiczenia",
@@ -7,3 +9,5 @@
 	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 084dc91..ffba573 100644
--- a/dojox/editor/plugins/nls/pl/InsertEntity.js
+++ b/dojox/editor/plugins/nls/pl/InsertEntity.js
@@ -1,4 +1,8 @@
+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 ee85290..8f53eb0 100644
--- a/dojox/editor/plugins/nls/pl/LocalImage.js
+++ b/dojox/editor/plugins/nls/pl/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Wstaw obraz",
 	url: "Obraz",
@@ -9,3 +11,5 @@
 	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 07dcf7f..3c34f1b 100644
--- a/dojox/editor/plugins/nls/pl/PageBreak.js
+++ b/dojox/editor/plugins/nls/pl/PageBreak.js
@@ -1,4 +1,8 @@
+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 47384b4..c283aac 100644
--- a/dojox/editor/plugins/nls/pl/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/pl/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Wklej z programu Word",
 	"paste": "Wklej",
@@ -5,3 +7,5 @@
 	"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. "
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/pl/Preview.js b/dojox/editor/plugins/nls/pl/Preview.js
index 3cb01c2..46d51a1 100644
--- a/dojox/editor/plugins/nls/pl/Preview.js
+++ b/dojox/editor/plugins/nls/pl/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "Podgląd"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/pl/SafePaste.js b/dojox/editor/plugins/nls/pl/SafePaste.js
new file mode 100644
index 0000000..9280fb0
--- /dev/null
+++ b/dojox/editor/plugins/nls/pl/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "Wklejanie bezpośrednie jest wyłączone. Wklej treść do tego okna dialogowego za pomocą standardowych skrótów klawiszowych przeglądarki lub opcji Wklej w menu. Po uzyskaniu odpowiedniej treści do wstawienia kliknij przycisk Wklej. Aby przerwać wstawianie treści, kliknij przycisk Anuluj."
+})
+);
diff --git a/dojox/editor/plugins/nls/pl/Save.js b/dojox/editor/plugins/nls/pl/Save.js
index 3c1d4b0..73389c3 100644
--- a/dojox/editor/plugins/nls/pl/Save.js
+++ b/dojox/editor/plugins/nls/pl/Save.js
@@ -1,4 +1,8 @@
+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 26fb420..cbb67d6 100644
--- a/dojox/editor/plugins/nls/pl/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/pl/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 a12a9f3..4aa54a0 100644
--- a/dojox/editor/plugins/nls/pl/Smiley.js
+++ b/dojox/editor/plugins/nls/pl/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Wstaw emotikon",
 	emoticonSmile: "uśmiech",
@@ -17,6 +19,9 @@
 	emoticonYes: "Tak",
 	emoticonNo: "Nie",
 	emoticonAngel: "anioł",
-	emoticonCrying: "płacz"
+	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 3642cf6..39dcfab 100644
--- a/dojox/editor/plugins/nls/pl/SpellCheck.js
+++ b/dojox/editor/plugins/nls/pl/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Wsadowe sprawdzanie pisowni",
 	unfound: "Nie znaleziono",
@@ -15,3 +17,5 @@
 	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 087d4f0..85af1c8 100644
--- a/dojox/editor/plugins/nls/pl/TableDialog.js
+++ b/dojox/editor/plugins/nls/pl/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Wstawianie tabeli",
 	modifyTableTitle: "Modyfikowanie tabeli",
@@ -28,3 +30,5 @@
 	deleteTableRowLabel: "Usuń wiersz",
 	deleteTableColumnLabel: "Usuń kolumnę"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/pl/TextColor.js b/dojox/editor/plugins/nls/pl/TextColor.js
index 7e954b4..a73aa0e 100644
--- a/dojox/editor/plugins/nls/pl/TextColor.js
+++ b/dojox/editor/plugins/nls/pl/TextColor.js
@@ -1,5 +1,9 @@
+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 c1385f8..92bd804 100644
--- a/dojox/editor/plugins/nls/pl/latinEntities.js
+++ b/dojox/editor/plugins/nls/pl/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	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 9f23d63..0d85628 100644
--- a/dojox/editor/plugins/nls/pt-pt/AutoSave.js
+++ b/dojox/editor/plugins/nls/pt-pt/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Guardar",
 	"saveSettingLabelOn": "Definir intervalo de gravação automática...",
@@ -12,3 +14,5 @@
 	"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 859084b..e54a9ba 100644
--- a/dojox/editor/plugins/nls/pt-pt/Blockquote.js
+++ b/dojox/editor/plugins/nls/pt-pt/Blockquote.js
@@ -1,4 +1,8 @@
+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 aee6191..e3ebb20 100644
--- a/dojox/editor/plugins/nls/pt-pt/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/pt-pt/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "Acções de ${nodeName}",
 	"selectContents": "Seleccionar conteúdo",
@@ -8,3 +10,5 @@
 	"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 fa26a52..73deb07 100644
--- a/dojox/editor/plugins/nls/pt-pt/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/pt-pt/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 df7176b..6ebf27f 100644
--- a/dojox/editor/plugins/nls/pt-pt/FindReplace.js
+++ b/dojox/editor/plugins/nls/pt-pt/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Localizar:",
 	"findTooltip": "Introduzir texto a localizar",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "Correspondência de maiúsculas/minúsculas",
 	"backwards": "Para trás",
 	"backwardsTooltip": "Procura de texto para trás",
-	"replaceAll": "Todas as ocorrências",
 	"replaceAllButton": "Substituir tudo",
 	"replaceAllButtonTooltip": "Substituir todo o texto",
 	"findButton": "Localizar",
@@ -21,3 +22,5 @@
 	"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 140265a..39f7c2a 100644
--- a/dojox/editor/plugins/nls/pt-pt/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/pt-pt/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Inserir âncora",
 	title: "Propriedades da âncora",
@@ -7,3 +9,5 @@
 	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 e2288f9..628bd32 100644
--- a/dojox/editor/plugins/nls/pt-pt/InsertEntity.js
+++ b/dojox/editor/plugins/nls/pt-pt/InsertEntity.js
@@ -1,4 +1,8 @@
+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 ea4aae6..8b2a3de 100644
--- a/dojox/editor/plugins/nls/pt-pt/LocalImage.js
+++ b/dojox/editor/plugins/nls/pt-pt/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Inserir imagem",
 	url: "Imagem",
@@ -9,3 +11,5 @@
 	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 76f29ef..191d70e 100644
--- a/dojox/editor/plugins/nls/pt-pt/PageBreak.js
+++ b/dojox/editor/plugins/nls/pt-pt/PageBreak.js
@@ -1,4 +1,8 @@
+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 52c10f1..ef129c8 100644
--- a/dojox/editor/plugins/nls/pt-pt/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/pt-pt/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Colar do Word",
 	"paste": "Colar",
@@ -5,3 +7,5 @@
 	"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 aaf4d32..e9f7e64 100644
--- a/dojox/editor/plugins/nls/pt-pt/Preview.js
+++ b/dojox/editor/plugins/nls/pt-pt/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "Pré-visualizar"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/pt-pt/Save.js b/dojox/editor/plugins/nls/pt-pt/Save.js
index 11af7ed..4e8a379 100644
--- a/dojox/editor/plugins/nls/pt-pt/Save.js
+++ b/dojox/editor/plugins/nls/pt-pt/Save.js
@@ -1,4 +1,8 @@
+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 9a7e5e5..2a30351 100644
--- a/dojox/editor/plugins/nls/pt-pt/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/pt-pt/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 8159299..978713e 100644
--- a/dojox/editor/plugins/nls/pt-pt/Smiley.js
+++ b/dojox/editor/plugins/nls/pt-pt/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Inserir ícone emotivo",
 	emoticonSmile: "sorriso",
@@ -20,3 +22,5 @@
 	emoticonCrying: "a chorar"
 })
 
+//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 bb4c272..39a3ecc 100644
--- a/dojox/editor/plugins/nls/pt-pt/SpellCheck.js
+++ b/dojox/editor/plugins/nls/pt-pt/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Verificação ortográfica por grupo",
 	unfound: "Não localizado",
@@ -15,3 +17,5 @@
 	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 fa72f93..072b0f1 100644
--- a/dojox/editor/plugins/nls/pt-pt/TableDialog.js
+++ b/dojox/editor/plugins/nls/pt-pt/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Inserir tabela",
 	modifyTableTitle: "Modificar tabela",
@@ -28,3 +30,5 @@
 	deleteTableRowLabel: "Eliminar linha",
 	deleteTableColumnLabel: "Eliminar coluna"
 })
+//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 aa9092c..d839c4b 100644
--- a/dojox/editor/plugins/nls/pt-pt/TextColor.js
+++ b/dojox/editor/plugins/nls/pt-pt/TextColor.js
@@ -1,5 +1,9 @@
+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 65e05da..afd76ae 100644
--- a/dojox/editor/plugins/nls/pt-pt/latinEntities.js
+++ b/dojox/editor/plugins/nls/pt-pt/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	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 510cf35..7b2d8ca 100644
--- a/dojox/editor/plugins/nls/pt/AutoSave.js
+++ b/dojox/editor/plugins/nls/pt/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Salvar",
 	"saveSettingLabelOn": "Configurar Intervalo de Salvamento Automático...",
@@ -11,3 +13,5 @@
 	"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 3da0bd2..95bdcda 100644
--- a/dojox/editor/plugins/nls/pt/Blockquote.js
+++ b/dojox/editor/plugins/nls/pt/Blockquote.js
@@ -1,3 +1,7 @@
+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 ffd24e1..77f163c 100644
--- a/dojox/editor/plugins/nls/pt/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/pt/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName} Ações",
 	"selectContents": "Selecionar Conteúdo",
@@ -8,3 +10,5 @@
 	"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 da50a0b..6ba443d 100644
--- a/dojox/editor/plugins/nls/pt/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/pt/CollapsibleToolbar.js
@@ -1,4 +1,8 @@
+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 5041fdc..a0c1ee1 100644
--- a/dojox/editor/plugins/nls/pt/FindReplace.js
+++ b/dojox/editor/plugins/nls/pt/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Localizar:",
 	"findTooltip": "Inserir texto a ser localizado",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "Coincidir maiúscula/minúscula",
 	"backwards": "Retroceder",
 	"backwardsTooltip": "Procurar texto para trás",
-	"replaceAll": "Todas as Ocorrências",
 	"replaceAllButton": "Substituir Todos",
 	"replaceAllButtonTooltip": "Substituir todo o texto",
 	"findButton": "Localizar",
@@ -20,3 +21,5 @@
 	"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 8817cc9..1ba2a9b 100644
--- a/dojox/editor/plugins/nls/pt/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/pt/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Inserir Âncora",
 	title: "Propriedades de Âncora",
@@ -6,3 +8,5 @@
 	set: "Definir",
 	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 b76fa26..ca43b94 100644
--- a/dojox/editor/plugins/nls/pt/InsertEntity.js
+++ b/dojox/editor/plugins/nls/pt/InsertEntity.js
@@ -1,4 +1,8 @@
+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 20fca98..99002d9 100644
--- a/dojox/editor/plugins/nls/pt/LocalImage.js
+++ b/dojox/editor/plugins/nls/pt/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Inserir imagem",
 	url: "Imagem",
@@ -8,3 +10,5 @@
 	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 417a561..d03057a 100644
--- a/dojox/editor/plugins/nls/pt/PageBreak.js
+++ b/dojox/editor/plugins/nls/pt/PageBreak.js
@@ -1,4 +1,8 @@
+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 3b6ea84..bb52185 100644
--- a/dojox/editor/plugins/nls/pt/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/pt/PasteFromWord.js
@@ -1,6 +1,10 @@
+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 2b7fd5e..189d65b 100644
--- a/dojox/editor/plugins/nls/pt/Preview.js
+++ b/dojox/editor/plugins/nls/pt/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "Visualização"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/pt/SafePaste.js b/dojox/editor/plugins/nls/pt/SafePaste.js
new file mode 100644
index 0000000..13fd51a
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "A colagem direta está desativada. Cole o conteúdo neste diálogo usando o teclado de navegador padrão ou os controles de colagem do menu. Quando estiver satisfeito com o conteúdo a ser inserido, pressione o botão colar. Para interromper a inserção de conteúdo, pressione o botão cancelar."
+})
+);
diff --git a/dojox/editor/plugins/nls/pt/Save.js b/dojox/editor/plugins/nls/pt/Save.js
index 60ffb59..f1be7b1 100644
--- a/dojox/editor/plugins/nls/pt/Save.js
+++ b/dojox/editor/plugins/nls/pt/Save.js
@@ -1,4 +1,8 @@
+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 4235eb3..2eb0e15 100644
--- a/dojox/editor/plugins/nls/pt/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/pt/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 13371bb..73d191c 100644
--- a/dojox/editor/plugins/nls/pt/Smiley.js
+++ b/dojox/editor/plugins/nls/pt/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Inserir Emoticon",
 	emoticonSmile: "sorriso",
@@ -17,5 +19,8 @@
 	emoticonYes: "sim",
 	emoticonNo: "não",
 	emoticonAngel: "angelical",
-	emoticonCrying: "chorando"
+	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 8399132..d9cb6bb 100644
--- a/dojox/editor/plugins/nls/pt/SpellCheck.js
+++ b/dojox/editor/plugins/nls/pt/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Verificação Ortográfica em Lote",
 	unfound: "Não localizado",
@@ -14,3 +16,5 @@
 	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 f2a828f..79a046b 100644
--- a/dojox/editor/plugins/nls/pt/TableDialog.js
+++ b/dojox/editor/plugins/nls/pt/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Inserir Tabela",
 	modifyTableTitle: "Modificar Tabela",
@@ -29,3 +31,5 @@
 	deleteTableColumnLabel: "Excluir Coluna"
 })
 	
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/pt/TextColor.js b/dojox/editor/plugins/nls/pt/TextColor.js
index 2d065fd..ee47cc4 100644
--- a/dojox/editor/plugins/nls/pt/TextColor.js
+++ b/dojox/editor/plugins/nls/pt/TextColor.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"setButtonText": "Definir",
 	"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 e8a26ec..2ef279c 100644
--- a/dojox/editor/plugins/nls/pt/latinEntities.js
+++ b/dojox/editor/plugins/nls/pt/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -254,3 +256,5 @@
 	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 3391244..80fdf56 100644
--- a/dojox/editor/plugins/nls/ro/AutoSave.js
+++ b/dojox/editor/plugins/nls/ro/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Salvare",
 	"saveSettingLabelOn": "Setare interval auto-salvare...",
@@ -12,3 +14,5 @@
 	"saveMessageFail": "A eşuat să salveze 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 859084b..e54a9ba 100644
--- a/dojox/editor/plugins/nls/ro/Blockquote.js
+++ b/dojox/editor/plugins/nls/ro/Blockquote.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"blockquote": "Blockquote"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ro/Breadcrumb.js b/dojox/editor/plugins/nls/ro/Breadcrumb.js
index 06d3485..fe945b2 100644
--- a/dojox/editor/plugins/nls/ro/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/ro/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "Acţiuni ${nodeName}",
 	"selectContents": "Selectare conţinut",
@@ -8,3 +10,5 @@
 	"moveEnd": "Mutare cursor la sfârşit"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ro/CollapsibleToolbar.js b/dojox/editor/plugins/nls/ro/CollapsibleToolbar.js
index cec6fcd..e9a06a6 100644
--- a/dojox/editor/plugins/nls/ro/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/ro/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 1442259..bcea70b 100644
--- a/dojox/editor/plugins/nls/ro/FindReplace.js
+++ b/dojox/editor/plugins/nls/ro/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Găsire:",
 	"findTooltip": "Introduceţi textul de găsit",
@@ -20,3 +22,5 @@
 	"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 ac50e7e..2525185 100644
--- a/dojox/editor/plugins/nls/ro/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/ro/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Inserare ancoră",
 	title: "Proprietăţi ancoră",
@@ -7,3 +9,5 @@
 	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 bb91e35..b2cbe02 100644
--- a/dojox/editor/plugins/nls/ro/InsertEntity.js
+++ b/dojox/editor/plugins/nls/ro/InsertEntity.js
@@ -1,4 +1,8 @@
+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 a8dcb07..3c55be0 100644
--- a/dojox/editor/plugins/nls/ro/LocalImage.js
+++ b/dojox/editor/plugins/nls/ro/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Inserare imagine",
 	url: "Imagine",
@@ -9,3 +11,5 @@
 	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 7d9d2dc..a61ffbf 100644
--- a/dojox/editor/plugins/nls/ro/PageBreak.js
+++ b/dojox/editor/plugins/nls/ro/PageBreak.js
@@ -1,4 +1,8 @@
+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 394fe10..04ec6b3 100644
--- a/dojox/editor/plugins/nls/ro/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/ro/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Lipire din Word",
 	"paste": "Lipire",
@@ -5,3 +7,5 @@
 	"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."
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ro/Preview.js b/dojox/editor/plugins/nls/ro/Preview.js
index 5d6629d..ab110ab 100644
--- a/dojox/editor/plugins/nls/ro/Preview.js
+++ b/dojox/editor/plugins/nls/ro/Preview.js
@@ -1,4 +1,8 @@
+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
new file mode 100644
index 0000000..92215f8
--- /dev/null
+++ b/dojox/editor/plugins/nls/ro/SafePaste.js
@@ -0,0 +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. "
+})
+);
diff --git a/dojox/editor/plugins/nls/ro/Save.js b/dojox/editor/plugins/nls/ro/Save.js
index 9b82668..43190f1 100644
--- a/dojox/editor/plugins/nls/ro/Save.js
+++ b/dojox/editor/plugins/nls/ro/Save.js
@@ -1,4 +1,8 @@
+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 5a75d78..ea7f475 100644
--- a/dojox/editor/plugins/nls/ro/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/ro/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 1ac00db..20b1f32 100644
--- a/dojox/editor/plugins/nls/ro/Smiley.js
+++ b/dojox/editor/plugins/nls/ro/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Inserare emoticoane",
 	emoticonSmile: "zâmbet",
@@ -17,6 +19,9 @@
 	emoticonYes: "da",
 	emoticonNo: "nu",
 	emoticonAngel: "înger",
-	emoticonCrying: "plâns"
+	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 e35c0b1..3d1245d 100644
--- a/dojox/editor/plugins/nls/ro/SpellCheck.js
+++ b/dojox/editor/plugins/nls/ro/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Verificare ortografică lot",
 	unfound: "Nu a fost găsit",
@@ -15,3 +17,5 @@
 	iMsg: "Nicio sugestie de verificare ortografică"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ro/TableDialog.js b/dojox/editor/plugins/nls/ro/TableDialog.js
index b66cf79..1c26f55 100644
--- a/dojox/editor/plugins/nls/ro/TableDialog.js
+++ b/dojox/editor/plugins/nls/ro/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Inserare tabel",
 	modifyTableTitle: "Modificare tabel",
@@ -30,3 +32,5 @@
 })
 	
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ro/TextColor.js b/dojox/editor/plugins/nls/ro/TextColor.js
index 56c2a03..c31e4c1 100644
--- a/dojox/editor/plugins/nls/ro/TextColor.js
+++ b/dojox/editor/plugins/nls/ro/TextColor.js
@@ -1,5 +1,9 @@
+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 70496a4..0d0b654 100644
--- a/dojox/editor/plugins/nls/ro/latinEntities.js
+++ b/dojox/editor/plugins/nls/ro/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	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 8e4c786..3a4ff60 100644
--- a/dojox/editor/plugins/nls/ru/AutoSave.js
+++ b/dojox/editor/plugins/nls/ru/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Сохранить",
 	"saveSettingLabelOn": "Задать интервал автосохранения...",
@@ -12,3 +14,5 @@
 	"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 6218872..4e4fb24 100644
--- a/dojox/editor/plugins/nls/ru/Blockquote.js
+++ b/dojox/editor/plugins/nls/ru/Blockquote.js
@@ -1,4 +1,8 @@
+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 044430a..e8eab41 100644
--- a/dojox/editor/plugins/nls/ru/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/ru/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName}: действия",
 	"selectContents": "Выбрать содержимое",
@@ -8,3 +10,5 @@
 	"moveEnd": "Поместить курсор в конец"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ru/CollapsibleToolbar.js b/dojox/editor/plugins/nls/ru/CollapsibleToolbar.js
index 0ae0da8..ac38dcd 100644
--- a/dojox/editor/plugins/nls/ru/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/ru/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 0292156..c9f07d2 100644
--- a/dojox/editor/plugins/nls/ru/FindReplace.js
+++ b/dojox/editor/plugins/nls/ru/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Найти:",
 	"findTooltip": "Введите текст для поиска",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "С учетом регистра",
 	"backwards": "Назад",
 	"backwardsTooltip": "Поиск текста в обратном направлении",
-	"replaceAll": "Все вхождения",
 	"replaceAllButton": "Заменить все",
 	"replaceAllButtonTooltip": "Заменить весь текст",
 	"findButton": "Найти",
@@ -21,3 +22,5 @@
 	"eofDialogTextReplace": "заменено"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ru/InsertAnchor.js b/dojox/editor/plugins/nls/ru/InsertAnchor.js
index 6909d0a..af7049d 100644
--- a/dojox/editor/plugins/nls/ru/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/ru/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Вставить метку",
 	title: "Свойства метки",
@@ -7,3 +9,5 @@
 	cancel: "Отменить"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ru/InsertEntity.js b/dojox/editor/plugins/nls/ru/InsertEntity.js
index 55473ce..7b84bd7 100644
--- a/dojox/editor/plugins/nls/ru/InsertEntity.js
+++ b/dojox/editor/plugins/nls/ru/InsertEntity.js
@@ -1,4 +1,8 @@
+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 315df73..0cd3b4a 100644
--- a/dojox/editor/plugins/nls/ru/LocalImage.js
+++ b/dojox/editor/plugins/nls/ru/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Вставить изображение",
 	url: "Изображение",
@@ -9,3 +11,5 @@
 	prePopuTextBrowse: " или выберите локальный файл."
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ru/PageBreak.js b/dojox/editor/plugins/nls/ru/PageBreak.js
index 9fffae7..db902d9 100644
--- a/dojox/editor/plugins/nls/ru/PageBreak.js
+++ b/dojox/editor/plugins/nls/ru/PageBreak.js
@@ -1,4 +1,8 @@
+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 4d0d575..0516494 100644
--- a/dojox/editor/plugins/nls/ru/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/ru/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Вставить из Word",
 	"paste": "Вставить",
@@ -5,3 +7,5 @@
 	"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 eb25d1f..9a6d321 100644
--- a/dojox/editor/plugins/nls/ru/Preview.js
+++ b/dojox/editor/plugins/nls/ru/Preview.js
@@ -1,4 +1,8 @@
+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
new file mode 100644
index 0000000..84575b6
--- /dev/null
+++ b/dojox/editor/plugins/nls/ru/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "Прямая вставка отключена. Вставьте содержимое в этот диалог при помощи стандартной клавиатуры браузера или управляющих команд вставки в меню. Когда выберите содержимое для вставки, нажмите кнопку Вставить. Для отмены вставки содержимого нажмите кнопку Отмена."
+})
+);
diff --git a/dojox/editor/plugins/nls/ru/Save.js b/dojox/editor/plugins/nls/ru/Save.js
index 32affcb..7b6387b 100644
--- a/dojox/editor/plugins/nls/ru/Save.js
+++ b/dojox/editor/plugins/nls/ru/Save.js
@@ -1,4 +1,8 @@
+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 56b9c59..ce18788 100644
--- a/dojox/editor/plugins/nls/ru/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/ru/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 70db6bf..f32aa59 100644
--- a/dojox/editor/plugins/nls/ru/Smiley.js
+++ b/dojox/editor/plugins/nls/ru/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Вставить значок настроения",
 	emoticonSmile: "улыбка",
@@ -17,6 +19,9 @@
 	emoticonYes: "да",
 	emoticonNo: "нет",
 	emoticonAngel: "ангел",
-	emoticonCrying: "плачь"
+	emoticonCrying: "плачь",
+	emoticonHappy: "счастлив"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ru/SpellCheck.js b/dojox/editor/plugins/nls/ru/SpellCheck.js
index 2cd93c5..a95cfa9 100644
--- a/dojox/editor/plugins/nls/ru/SpellCheck.js
+++ b/dojox/editor/plugins/nls/ru/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Проверка орфографии",
 	unfound: "Не найдено",
@@ -15,3 +17,5 @@
 	iMsg: "Нет вариантов написания"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ru/TableDialog.js b/dojox/editor/plugins/nls/ru/TableDialog.js
index 638e051..d43894e 100644
--- a/dojox/editor/plugins/nls/ru/TableDialog.js
+++ b/dojox/editor/plugins/nls/ru/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Вставить таблицу",
 	modifyTableTitle: "Изменить таблицу",
@@ -28,3 +30,5 @@
 	deleteTableRowLabel: "Удалить строку",
 	deleteTableColumnLabel: "Удалить столбец"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ru/TextColor.js b/dojox/editor/plugins/nls/ru/TextColor.js
index 51919e3..2404dbf 100644
--- a/dojox/editor/plugins/nls/ru/TextColor.js
+++ b/dojox/editor/plugins/nls/ru/TextColor.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	"setButtonText": "Задать",
 	"cancelButtonText": "Отменить"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/ru/latinEntities.js b/dojox/editor/plugins/nls/ru/latinEntities.js
index 9e5ec7f..94ccd07 100644
--- a/dojox/editor/plugins/nls/ru/latinEntities.js
+++ b/dojox/editor/plugins/nls/ru/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	euro:"символ евро"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/sk/AutoSave.js b/dojox/editor/plugins/nls/sk/AutoSave.js
index 47e14d5..fb98ddc 100644
--- a/dojox/editor/plugins/nls/sk/AutoSave.js
+++ b/dojox/editor/plugins/nls/sk/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Uložiť",
 	"saveSettingLabelOn": "Nastaviť interval automatického ukladania...",
@@ -12,3 +14,5 @@
 	"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 859084b..e54a9ba 100644
--- a/dojox/editor/plugins/nls/sk/Blockquote.js
+++ b/dojox/editor/plugins/nls/sk/Blockquote.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"blockquote": "Blockquote"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/sk/Breadcrumb.js b/dojox/editor/plugins/nls/sk/Breadcrumb.js
index 6fae818..8024961 100644
--- a/dojox/editor/plugins/nls/sk/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/sk/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "Akcie pre ${nodeName}",
 	"selectContents": "Vybrať obsah",
@@ -8,3 +10,5 @@
 	"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 fd57120..f33361f 100644
--- a/dojox/editor/plugins/nls/sk/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/sk/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 804e9e4..eb17817 100644
--- a/dojox/editor/plugins/nls/sk/FindReplace.js
+++ b/dojox/editor/plugins/nls/sk/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Hľadať:",
 	"findTooltip": "Zadajte text na nájdenie",
@@ -20,3 +22,5 @@
 	"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 c978c7c..c0e7fd1 100644
--- a/dojox/editor/plugins/nls/sk/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/sk/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Vložiť kotvu",
 	title: "Vlastnosti kotvy",
@@ -7,3 +9,5 @@
 	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 f325903..21b78e0 100644
--- a/dojox/editor/plugins/nls/sk/InsertEntity.js
+++ b/dojox/editor/plugins/nls/sk/InsertEntity.js
@@ -1,4 +1,8 @@
+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 0895ced..ead9996 100644
--- a/dojox/editor/plugins/nls/sk/LocalImage.js
+++ b/dojox/editor/plugins/nls/sk/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Vložiť obrázok",
 	url: "Obrázok",
@@ -9,3 +11,5 @@
 	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 ee4d65e..cd8ab7f 100644
--- a/dojox/editor/plugins/nls/sk/PageBreak.js
+++ b/dojox/editor/plugins/nls/sk/PageBreak.js
@@ -1,4 +1,8 @@
+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 5090a9c..7f55f02 100644
--- a/dojox/editor/plugins/nls/sk/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/sk/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Prilepiť z aplikácie Word",
 	"paste": "Prilepiť",
@@ -5,3 +7,5 @@
 	"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 835b4bd..5d71a73 100644
--- a/dojox/editor/plugins/nls/sk/Preview.js
+++ b/dojox/editor/plugins/nls/sk/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "Náhľad"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/sk/SafePaste.js b/dojox/editor/plugins/nls/sk/SafePaste.js
new file mode 100644
index 0000000..91b2ea6
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "Priame prilepenie je zakázané.  Prilepte obsah do tohto dialógového okna s použitím štandardných klávesnicových alebo ponukových ovládacích prvkov prehliadača.  Keď budete spokojný s vloženým obsahom, stlačte tlačidlo Prilepiť.  Ak chcete zrušiť vkladanie obsahu, kliknite na tlačidlo Zrušiť."
+})
+);
diff --git a/dojox/editor/plugins/nls/sk/Save.js b/dojox/editor/plugins/nls/sk/Save.js
index 0f8a1f1..c7f6f70 100644
--- a/dojox/editor/plugins/nls/sk/Save.js
+++ b/dojox/editor/plugins/nls/sk/Save.js
@@ -1,4 +1,8 @@
+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 a458f00..6501004 100644
--- a/dojox/editor/plugins/nls/sk/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/sk/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 0c11431..a5064f5 100644
--- a/dojox/editor/plugins/nls/sk/Smiley.js
+++ b/dojox/editor/plugins/nls/sk/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Vložiť emotikon",
 	emoticonSmile: "úsmev",
@@ -17,6 +19,9 @@
 	emoticonYes: "áno",
 	emoticonNo: "nie",
 	emoticonAngel: "anjel",
-	emoticonCrying: "plač"
+	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 04b0ad9..95e66a6 100644
--- a/dojox/editor/plugins/nls/sk/SpellCheck.js
+++ b/dojox/editor/plugins/nls/sk/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Dávková kontrola pravopisu",
 	unfound: "Nenašlo sa",
@@ -15,3 +17,5 @@
 	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 70d3f30..6931c85 100644
--- a/dojox/editor/plugins/nls/sk/TableDialog.js
+++ b/dojox/editor/plugins/nls/sk/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Vložiť tabuľku",
 	modifyTableTitle: "Upraviť tabuľku",
@@ -30,3 +32,5 @@
 })
 	
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/sk/TextColor.js b/dojox/editor/plugins/nls/sk/TextColor.js
index 58b7cf7..168f651 100644
--- a/dojox/editor/plugins/nls/sk/TextColor.js
+++ b/dojox/editor/plugins/nls/sk/TextColor.js
@@ -1,5 +1,9 @@
+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 f4b2187..c239e9d 100644
--- a/dojox/editor/plugins/nls/sk/latinEntities.js
+++ b/dojox/editor/plugins/nls/sk/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	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 d14ab32..587f02b 100644
--- a/dojox/editor/plugins/nls/sl/AutoSave.js
+++ b/dojox/editor/plugins/nls/sl/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Shrani",
 	"saveSettingLabelOn": "Nastavi interval za samodejno shranjevanje ... ",
@@ -12,3 +14,5 @@
 	"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 d572a2e..e514eed 100644
--- a/dojox/editor/plugins/nls/sl/Blockquote.js
+++ b/dojox/editor/plugins/nls/sl/Blockquote.js
@@ -1,4 +1,8 @@
+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 8f6fa98..c1e4209 100644
--- a/dojox/editor/plugins/nls/sl/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/sl/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "Dejanja ${nodeName} ",
 	"selectContents": "Izberi vsebine ",
@@ -8,3 +10,5 @@
 	"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 026cd07..9828391 100644
--- a/dojox/editor/plugins/nls/sl/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/sl/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 85f6614..b7689f2 100644
--- a/dojox/editor/plugins/nls/sl/FindReplace.js
+++ b/dojox/editor/plugins/nls/sl/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Najdi:",
 	"findTooltip": "Vnesite besedilo za iskanje",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "Razlikuj velike in male črke",
 	"backwards": "Nazaj",
 	"backwardsTooltip": "Vzvratno iskanje besedila ",
-	"replaceAll": "Vse pojavitve ",
 	"replaceAllButton": "Zamenjaj vse",
 	"replaceAllButtonTooltip": "Zamenjaj celotno besedilo ",
 	"findButton": "Najdi",
@@ -21,3 +22,5 @@
 	"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 dae88e9..611ba89 100644
--- a/dojox/editor/plugins/nls/sl/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/sl/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Vstavi sidro",
 	title: "Lastnosti sidra",
@@ -7,3 +9,5 @@
 	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 21d3473..457cb07 100644
--- a/dojox/editor/plugins/nls/sl/InsertEntity.js
+++ b/dojox/editor/plugins/nls/sl/InsertEntity.js
@@ -1,4 +1,8 @@
+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 8d2e6e2..7a3bbb0 100644
--- a/dojox/editor/plugins/nls/sl/LocalImage.js
+++ b/dojox/editor/plugins/nls/sl/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Vstavi sliko",
 	url: "Slika ",
@@ -9,3 +11,5 @@
 	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 8747566..3ec86ee 100644
--- a/dojox/editor/plugins/nls/sl/PageBreak.js
+++ b/dojox/editor/plugins/nls/sl/PageBreak.js
@@ -1,4 +1,8 @@
+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 3eb0906..559d58d 100644
--- a/dojox/editor/plugins/nls/sl/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/sl/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Prilepi iz programa Word",
 	"paste": "Prilepi",
@@ -5,3 +7,5 @@
 	"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 a6aae73..5e56aa5 100644
--- a/dojox/editor/plugins/nls/sl/Preview.js
+++ b/dojox/editor/plugins/nls/sl/Preview.js
@@ -1,4 +1,8 @@
+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
new file mode 100644
index 0000000..93e8a52
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/SafePaste.js
@@ -0,0 +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."
+})
+);
diff --git a/dojox/editor/plugins/nls/sl/Save.js b/dojox/editor/plugins/nls/sl/Save.js
index dfc67e8..d9d9cc6 100644
--- a/dojox/editor/plugins/nls/sl/Save.js
+++ b/dojox/editor/plugins/nls/sl/Save.js
@@ -1,4 +1,8 @@
+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 bcd98ebb..9ac93ea 100644
--- a/dojox/editor/plugins/nls/sl/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/sl/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 5e9183e..80b9abb 100644
--- a/dojox/editor/plugins/nls/sl/Smiley.js
+++ b/dojox/editor/plugins/nls/sl/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Vstavi čustveni simbol",
 	emoticonSmile: "smeško",
@@ -17,6 +19,9 @@
 	emoticonYes: "smeško prikimava",
 	emoticonNo: "smeško odkimava",
 	emoticonAngel: "smeško je angelček",
-	emoticonCrying: "smeško joka"
+	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 c434d14..1ab8dc4 100644
--- a/dojox/editor/plugins/nls/sl/SpellCheck.js
+++ b/dojox/editor/plugins/nls/sl/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Paketno preverjanje črkovanja ",
 	unfound: "Ni najdeno ",
@@ -15,3 +17,5 @@
 	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 502a298..de09528 100644
--- a/dojox/editor/plugins/nls/sl/TableDialog.js
+++ b/dojox/editor/plugins/nls/sl/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Vstavi tabelo",
 	modifyTableTitle: "Spremeni tabelo",
@@ -30,3 +32,5 @@
 })
 	
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/sl/TextColor.js b/dojox/editor/plugins/nls/sl/TextColor.js
index c3cd623..bc53cc6 100644
--- a/dojox/editor/plugins/nls/sl/TextColor.js
+++ b/dojox/editor/plugins/nls/sl/TextColor.js
@@ -1,5 +1,9 @@
+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 764c6d5..cc653df 100644
--- a/dojox/editor/plugins/nls/sl/latinEntities.js
+++ b/dojox/editor/plugins/nls/sl/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	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 de9b56c..03ee67a 100644
--- a/dojox/editor/plugins/nls/sv/AutoSave.js
+++ b/dojox/editor/plugins/nls/sv/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Spara",
 	"saveSettingLabelOn": "Ange intervall för automatiskt sparande...",
@@ -12,3 +14,5 @@
 	"saveMessageFail": "Kunde inte sparas ${0}"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/sv/Blockquote.js b/dojox/editor/plugins/nls/sv/Blockquote.js
index f654c02..5a289b1 100644
--- a/dojox/editor/plugins/nls/sv/Blockquote.js
+++ b/dojox/editor/plugins/nls/sv/Blockquote.js
@@ -1,4 +1,8 @@
+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 6a39235..7097e34 100644
--- a/dojox/editor/plugins/nls/sv/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/sv/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName}-åtgärder",
 	"selectContents": "Välj innehåll",
@@ -8,3 +10,5 @@
 	"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 35c57cd..bc430cd 100644
--- a/dojox/editor/plugins/nls/sv/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/sv/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	"collapse": "Komprimera redigerarverktygsfältet",
 	"expand": "Expandera redigerarverktygsfältet"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/sv/FindReplace.js b/dojox/editor/plugins/nls/sv/FindReplace.js
index 0a21346..c7652e3 100644
--- a/dojox/editor/plugins/nls/sv/FindReplace.js
+++ b/dojox/editor/plugins/nls/sv/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Sök:",
 	"findTooltip": "Ange den text du vill söka efter",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "Matcha skiftläge",
 	"backwards": "Bakåt",
 	"backwardsTooltip": "Sök bakåt efter text",
-	"replaceAll": "Alla förekomster",
 	"replaceAllButton": "Ersätt alla",
 	"replaceAllButtonTooltip": "Ersätt all text",
 	"findButton": "Sök",
@@ -21,3 +22,5 @@
 	"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 5bd899e..72d2c11 100644
--- a/dojox/editor/plugins/nls/sv/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/sv/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Infoga ankare",
 	title: "Egenskaper för ankare",
@@ -7,3 +9,5 @@
 	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 e9e76c2..b38cc7c 100644
--- a/dojox/editor/plugins/nls/sv/InsertEntity.js
+++ b/dojox/editor/plugins/nls/sv/InsertEntity.js
@@ -1,4 +1,8 @@
+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 2b00b3d..2cef853 100644
--- a/dojox/editor/plugins/nls/sv/LocalImage.js
+++ b/dojox/editor/plugins/nls/sv/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Infoga bild",
 	url: "Bild",
@@ -9,3 +11,5 @@
 	prePopuTextBrowse: " eller bläddra efter 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 f79d133..2f3b090 100644
--- a/dojox/editor/plugins/nls/sv/PageBreak.js
+++ b/dojox/editor/plugins/nls/sv/PageBreak.js
@@ -1,4 +1,8 @@
+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 003ff9a..2d6e21e 100644
--- a/dojox/editor/plugins/nls/sv/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/sv/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Klistra in från Word",
 	"paste": "Klistra in",
@@ -5,3 +7,5 @@
 	"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."
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/sv/Preview.js b/dojox/editor/plugins/nls/sv/Preview.js
index 75af1ba..44b726c 100644
--- a/dojox/editor/plugins/nls/sv/Preview.js
+++ b/dojox/editor/plugins/nls/sv/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "Förhandsgranska"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/sv/SafePaste.js b/dojox/editor/plugins/nls/sv/SafePaste.js
new file mode 100644
index 0000000..33746ac
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "Direkt inklistring är avaktiverat. Klistra in innehållet i det här fönstret med standardtangentkommandon eller inklistringsfunktionen på menyn. När du har valt innehåller klickar du på Klistra in. Avbryt om du inte vill klistra in innehållet. "
+})
+);
diff --git a/dojox/editor/plugins/nls/sv/Save.js b/dojox/editor/plugins/nls/sv/Save.js
index 94dd0cf..1702fdf 100644
--- a/dojox/editor/plugins/nls/sv/Save.js
+++ b/dojox/editor/plugins/nls/sv/Save.js
@@ -1,4 +1,8 @@
+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 787c683..fc22bb3 100644
--- a/dojox/editor/plugins/nls/sv/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/sv/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 dadaaf9..debc09f 100644
--- a/dojox/editor/plugins/nls/sv/Smiley.js
+++ b/dojox/editor/plugins/nls/sv/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "Infoga känslolägesikon",
 	emoticonSmile: "ler",
@@ -17,6 +19,9 @@
 	emoticonYes: "ja",
 	emoticonNo: "nej",
 	emoticonAngel: "ängel",
-	emoticonCrying: "gråter"
+	emoticonCrying: "gråter",
+	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 f2cbefa..d23fc4d 100644
--- a/dojox/editor/plugins/nls/sv/SpellCheck.js
+++ b/dojox/editor/plugins/nls/sv/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Kontrollera stavning",
 	unfound: "Hittades inte",
@@ -15,3 +17,5 @@
 	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 5874cc2..416c634 100644
--- a/dojox/editor/plugins/nls/sv/TableDialog.js
+++ b/dojox/editor/plugins/nls/sv/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Infoga tabell",
 	modifyTableTitle: "Ändra tabell",
@@ -28,3 +30,5 @@
 	deleteTableRowLabel: "Ta bort rad",
 	deleteTableColumnLabel: "Ta bort kolumn"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/sv/TextColor.js b/dojox/editor/plugins/nls/sv/TextColor.js
index 591c3c0..3d43fe5 100644
--- a/dojox/editor/plugins/nls/sv/TextColor.js
+++ b/dojox/editor/plugins/nls/sv/TextColor.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	"setButtonText": "Ange",
 	"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 ab998a7..9e7933d 100644
--- a/dojox/editor/plugins/nls/sv/latinEntities.js
+++ b/dojox/editor/plugins/nls/sv/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	euro:"eurotecken"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/th/AutoSave.js b/dojox/editor/plugins/nls/th/AutoSave.js
index 9b12b9d..436a367 100644
--- a/dojox/editor/plugins/nls/th/AutoSave.js
+++ b/dojox/editor/plugins/nls/th/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "บันทึก",
 	"saveSettingLabelOn": "ตั้งช่วงเวลาบันทึกอัตโนมัติ...",
@@ -12,3 +14,5 @@
 	"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 643efbf..0081f58 100644
--- a/dojox/editor/plugins/nls/th/Blockquote.js
+++ b/dojox/editor/plugins/nls/th/Blockquote.js
@@ -1,4 +1,8 @@
+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 08a9d53..98300cb 100644
--- a/dojox/editor/plugins/nls/th/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/th/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName} แอ็คชัน",
 	"selectContents": "เลือกเนื้อหา",
@@ -8,3 +10,5 @@
 	"moveEnd": "ย้ายเคอร์เซอร์ไปยังจุดสิ้นสุด"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/th/CollapsibleToolbar.js b/dojox/editor/plugins/nls/th/CollapsibleToolbar.js
index 270b0ab..c29a1e7 100644
--- a/dojox/editor/plugins/nls/th/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/th/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 4abd152..39ce585 100644
--- a/dojox/editor/plugins/nls/th/FindReplace.js
+++ b/dojox/editor/plugins/nls/th/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "ค้นหา:",
 	"findTooltip": "ป้อนข้อความเพื่อหา",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "ตรงตามตัวพิมพ์ใหญ่เล็ก",
 	"backwards": "ย้อนกลับ",
 	"backwardsTooltip": "ค้นหาย้อนกับเพื่อหาข้อความ",
-	"replaceAll": "ที่เกิดขึ้นทั้งหมด",
 	"replaceAllButton": "แทนที่ทั้งหมด",
 	"replaceAllButtonTooltip": "แทนที่ข้อความทั้งหมด",
 	"findButton": "ค้นหา",
@@ -21,3 +22,5 @@
 	"eofDialogTextReplace": "ถูกแทนที่"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/th/InsertAnchor.js b/dojox/editor/plugins/nls/th/InsertAnchor.js
index b8f941e..5f439de 100644
--- a/dojox/editor/plugins/nls/th/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/th/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "แทรกจุดยึด",
 	title: "คุณสมบัติจุดยึด",
@@ -7,3 +9,5 @@
 	cancel: "ยกเลิก"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/th/InsertEntity.js b/dojox/editor/plugins/nls/th/InsertEntity.js
index 7c05c08..f702bfe 100644
--- a/dojox/editor/plugins/nls/th/InsertEntity.js
+++ b/dojox/editor/plugins/nls/th/InsertEntity.js
@@ -1,4 +1,8 @@
+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 d7a6f93..cb5199d 100644
--- a/dojox/editor/plugins/nls/th/LocalImage.js
+++ b/dojox/editor/plugins/nls/th/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "แทรกรูปภาพ",
 	url: "รูปภาพ",
@@ -9,3 +11,5 @@
 	prePopuTextBrowse: " หรือเรียกดูโลคัลไฟล์"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/th/PageBreak.js b/dojox/editor/plugins/nls/th/PageBreak.js
index 62a2841..2aedf25 100644
--- a/dojox/editor/plugins/nls/th/PageBreak.js
+++ b/dojox/editor/plugins/nls/th/PageBreak.js
@@ -1,4 +1,8 @@
+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 cfafda8..8dde0e6 100644
--- a/dojox/editor/plugins/nls/th/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/th/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "วางจาก Word",
 	"paste": "วาง",
@@ -5,3 +7,5 @@
 	"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 d91eb68..a879e19 100644
--- a/dojox/editor/plugins/nls/th/Preview.js
+++ b/dojox/editor/plugins/nls/th/Preview.js
@@ -1,4 +1,8 @@
+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
new file mode 100644
index 0000000..742bde0
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "การแปะโดยตรงถูกปิดใช้งาน. โปรดแปะเนื้อหาในไดอะล็อกนี้โดยใช้คีบอร์ดเบราว์เซอร์พื้นฐานหรือการควบคุมเมนูการแปะ  เมื่อคุณพอใจกับเนื้อหาที่จะแทรก กดปุ่มแปะ ในการที่จะยกเลิกการแทรกเนื้อหา กดปุ่มยกเลิก"
+})
+);
diff --git a/dojox/editor/plugins/nls/th/Save.js b/dojox/editor/plugins/nls/th/Save.js
index ed35c1b..4f22ac6 100644
--- a/dojox/editor/plugins/nls/th/Save.js
+++ b/dojox/editor/plugins/nls/th/Save.js
@@ -1,4 +1,8 @@
+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 90546ee..1e20d9a 100644
--- a/dojox/editor/plugins/nls/th/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/th/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 ced4f0a..df827d9 100644
--- a/dojox/editor/plugins/nls/th/Smiley.js
+++ b/dojox/editor/plugins/nls/th/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "แทรกไอคอนแสดงอารมณ์",
 	emoticonSmile: "ยิ้ม",
@@ -17,6 +19,9 @@
 	emoticonYes: "ใช่",
 	emoticonNo: "ไม่ใช่",
 	emoticonAngel: "โมโห",
-	emoticonCrying: "ร้องไห้"
+	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 f64da88..83cc92f 100644
--- a/dojox/editor/plugins/nls/th/SpellCheck.js
+++ b/dojox/editor/plugins/nls/th/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "ตรวจสอบการสะกดคำแบบแบตช์",
 	unfound: "ไม่พบ",
@@ -15,3 +17,5 @@
 	iMsg: "ไม่มีการแนะนำการสะกด"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/th/TableDialog.js b/dojox/editor/plugins/nls/th/TableDialog.js
index b00e247..4491e10 100644
--- a/dojox/editor/plugins/nls/th/TableDialog.js
+++ b/dojox/editor/plugins/nls/th/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "แทรกตาราง",
 	modifyTableTitle: "ปรับเปลี่ยนไขตาราง",
@@ -28,3 +30,5 @@
 	deleteTableRowLabel: "ลบแถว",
 	deleteTableColumnLabel: "ลบคอลัมน์"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/th/TextColor.js b/dojox/editor/plugins/nls/th/TextColor.js
index 442ea59..50de4f2 100644
--- a/dojox/editor/plugins/nls/th/TextColor.js
+++ b/dojox/editor/plugins/nls/th/TextColor.js
@@ -1,5 +1,9 @@
+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 2834064..b1ea2c6 100644
--- a/dojox/editor/plugins/nls/th/latinEntities.js
+++ b/dojox/editor/plugins/nls/th/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	euro:"เครื่องหมายยูโร"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/tr/AutoSave.js b/dojox/editor/plugins/nls/tr/AutoSave.js
index 1aed6f3..7cb0275 100644
--- a/dojox/editor/plugins/nls/tr/AutoSave.js
+++ b/dojox/editor/plugins/nls/tr/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "Kaydet",
 	"saveSettingLabelOn": "Otomatik Kaydetme Aralığını Ayarla...",
@@ -12,3 +14,5 @@
 	"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 1bcb572..d399017 100644
--- a/dojox/editor/plugins/nls/tr/Blockquote.js
+++ b/dojox/editor/plugins/nls/tr/Blockquote.js
@@ -1,4 +1,8 @@
+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 e97ac04..ff18e96 100644
--- a/dojox/editor/plugins/nls/tr/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/tr/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName} Eylemleri",
 	"selectContents": "İçindekileri seç",
@@ -8,3 +10,5 @@
 	"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 93a281f..4d75416 100644
--- a/dojox/editor/plugins/nls/tr/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/tr/CollapsibleToolbar.js
@@ -1,5 +1,9 @@
+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 0798eee..8087970 100644
--- a/dojox/editor/plugins/nls/tr/FindReplace.js
+++ b/dojox/editor/plugins/nls/tr/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "Bul:",
 	"findTooltip": "Bulunacak metni girin",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "Büyük/küçük harf eşleştir",
 	"backwards": "Geri",
 	"backwardsTooltip": "Metni geriye doğru ara",
-	"replaceAll": "Tüm Tekrarlar",
 	"replaceAllButton": "Tümünü Değiştir",
 	"replaceAllButtonTooltip": "Tüm metni değiştir",
 	"findButton": "Bul",
@@ -21,3 +22,5 @@
 	"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 b366868..9db6349 100644
--- a/dojox/editor/plugins/nls/tr/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/tr/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "Tutturucu Ekle",
 	title: "Tutturucu Özellikleri",
@@ -7,3 +9,5 @@
 	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 5f84a4e..96fab89 100644
--- a/dojox/editor/plugins/nls/tr/InsertEntity.js
+++ b/dojox/editor/plugins/nls/tr/InsertEntity.js
@@ -1,4 +1,8 @@
+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 a9c3259..82817e2 100644
--- a/dojox/editor/plugins/nls/tr/LocalImage.js
+++ b/dojox/editor/plugins/nls/tr/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "Resim Ekle",
 	url: "Resim",
@@ -9,3 +11,5 @@
 	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 a12bd1d..db593fa 100644
--- a/dojox/editor/plugins/nls/tr/PageBreak.js
+++ b/dojox/editor/plugins/nls/tr/PageBreak.js
@@ -1,4 +1,8 @@
+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 8d0fccd..de1463e 100644
--- a/dojox/editor/plugins/nls/tr/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/tr/PasteFromWord.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "Word'den Kopyala",
 	"paste": "Yapıştır",
@@ -5,3 +7,5 @@
 	"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 fca84e7..0fd1c66 100644
--- a/dojox/editor/plugins/nls/tr/Preview.js
+++ b/dojox/editor/plugins/nls/tr/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "Önizleme"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/tr/SafePaste.js b/dojox/editor/plugins/nls/tr/SafePaste.js
new file mode 100644
index 0000000..8f290cb
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "Doğrudan kopyalama geçersiz kılındı. Lütfen bu iletişim kutusundaki içeriği standart tarayıcı klavyesini ya da menüde yer alan yapıştırma seçeneklerini kullanarak  yapıştırın. Eklenecek içeriğe karar verdikten sonra yapıştır düğmesine basın. İçeriği eklemeyi durdurmak için iptal düğmesine basın."
+})
+);
diff --git a/dojox/editor/plugins/nls/tr/Save.js b/dojox/editor/plugins/nls/tr/Save.js
index 87cd5bd..5e9d22c 100644
--- a/dojox/editor/plugins/nls/tr/Save.js
+++ b/dojox/editor/plugins/nls/tr/Save.js
@@ -1,4 +1,8 @@
+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 6ea4456..61f6eaf 100644
--- a/dojox/editor/plugins/nls/tr/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/tr/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 a44be6f..6944bd8 100644
--- a/dojox/editor/plugins/nls/tr/Smiley.js
+++ b/dojox/editor/plugins/nls/tr/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "İfade Ekle",
 	emoticonSmile: "gülümseme",
@@ -17,6 +19,9 @@
 	emoticonYes: "evet",
 	emoticonNo: "hayır",
 	emoticonAngel: "melek",
-	emoticonCrying: "ağlayan ifade"
+	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 3f8a548..13a61fa 100644
--- a/dojox/editor/plugins/nls/tr/SpellCheck.js
+++ b/dojox/editor/plugins/nls/tr/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "Toplu Yazım Denetimi",
 	unfound: "Bulunamadı",
@@ -15,3 +17,5 @@
 	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 d79d3de..cc2b99f 100644
--- a/dojox/editor/plugins/nls/tr/TableDialog.js
+++ b/dojox/editor/plugins/nls/tr/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "Tablo Ekle",
 	modifyTableTitle: "Tabloyu Değiştir",
@@ -28,3 +30,5 @@
 	deleteTableRowLabel: "Satırı Sil",
 	deleteTableColumnLabel: "Sütunu Sil"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/tr/TextColor.js b/dojox/editor/plugins/nls/tr/TextColor.js
index 6e866b7..9f6b1c3 100644
--- a/dojox/editor/plugins/nls/tr/TextColor.js
+++ b/dojox/editor/plugins/nls/tr/TextColor.js
@@ -1,5 +1,9 @@
+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 cec77b2..f773e61 100644
--- a/dojox/editor/plugins/nls/tr/latinEntities.js
+++ b/dojox/editor/plugins/nls/tr/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	euro:"euro işareti"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/zh-tw/AutoSave.js b/dojox/editor/plugins/nls/zh-tw/AutoSave.js
index 9490fd5..e75b06e 100644
--- a/dojox/editor/plugins/nls/zh-tw/AutoSave.js
+++ b/dojox/editor/plugins/nls/zh-tw/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "儲存",
 	"saveSettingLabelOn": "設定自動儲存間隔...",
@@ -11,3 +13,5 @@
 	"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 d83daa5..dbcb9de 100644
--- a/dojox/editor/plugins/nls/zh-tw/Blockquote.js
+++ b/dojox/editor/plugins/nls/zh-tw/Blockquote.js
@@ -1,3 +1,7 @@
+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 f11be70..6e06911 100644
--- a/dojox/editor/plugins/nls/zh-tw/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/zh-tw/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName} 動作",
 	"selectContents": "選取內容",
@@ -8,3 +10,5 @@
 	"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 affd4bd..935372a 100644
--- a/dojox/editor/plugins/nls/zh-tw/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/zh-tw/CollapsibleToolbar.js
@@ -1,4 +1,8 @@
+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 c78b0de..414b189 100644
--- a/dojox/editor/plugins/nls/zh-tw/FindReplace.js
+++ b/dojox/editor/plugins/nls/zh-tw/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "尋找:",
 	"findTooltip": "輸入要尋找的文字",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "大小寫相符",
 	"backwards": "向後",
 	"backwardsTooltip": "往回搜尋文字",
-	"replaceAll": "所有出現項目",
 	"replaceAllButton": "全部取代",
 	"replaceAllButtonTooltip": "取代所有文字",
 	"findButton": "尋找",
@@ -20,3 +21,5 @@
 	"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 f104625..460b5bb 100644
--- a/dojox/editor/plugins/nls/zh-tw/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/zh-tw/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "插入錨點",
 	title: "錨點內容",
@@ -6,3 +8,5 @@
 	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 518c8bb..a8872ba 100644
--- a/dojox/editor/plugins/nls/zh-tw/InsertEntity.js
+++ b/dojox/editor/plugins/nls/zh-tw/InsertEntity.js
@@ -1,4 +1,8 @@
+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 85fa74f..4d1da04 100644
--- a/dojox/editor/plugins/nls/zh-tw/LocalImage.js
+++ b/dojox/editor/plugins/nls/zh-tw/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "插入影像",
 	url: "影像",
@@ -8,3 +10,5 @@
 	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 06ee863..b966ada 100644
--- a/dojox/editor/plugins/nls/zh-tw/PageBreak.js
+++ b/dojox/editor/plugins/nls/zh-tw/PageBreak.js
@@ -1,4 +1,8 @@
+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 ac4c70d..3d10208 100644
--- a/dojox/editor/plugins/nls/zh-tw/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/zh-tw/PasteFromWord.js
@@ -1,6 +1,10 @@
+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 fc90ca3..1ce6596 100644
--- a/dojox/editor/plugins/nls/zh-tw/Preview.js
+++ b/dojox/editor/plugins/nls/zh-tw/Preview.js
@@ -1,4 +1,8 @@
+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
new file mode 100644
index 0000000..4708bc1
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh-tw/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "已停用直接貼上。請使用標準瀏覽器鍵盤或功能表貼上控制,將內容貼上至此對話框中。一旦您滿意要插入的內容,按下貼上按鈕。若要中斷插入內容,按下取消按鈕。"
+})
+);
diff --git a/dojox/editor/plugins/nls/zh-tw/Save.js b/dojox/editor/plugins/nls/zh-tw/Save.js
index 427d545..a75928d 100644
--- a/dojox/editor/plugins/nls/zh-tw/Save.js
+++ b/dojox/editor/plugins/nls/zh-tw/Save.js
@@ -1,4 +1,8 @@
+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 808865a..0ff24a8 100644
--- a/dojox/editor/plugins/nls/zh-tw/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/zh-tw/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 dabf814..5e5bda4 100644
--- a/dojox/editor/plugins/nls/zh-tw/Smiley.js
+++ b/dojox/editor/plugins/nls/zh-tw/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "插入表情符號",
 	emoticonSmile: "微笑",
@@ -17,6 +19,9 @@
 	emoticonYes: "對",
 	emoticonNo: "不對",
 	emoticonAngel: "守護神",
-	emoticonCrying: "哭泣"
+	emoticonCrying: "哭泣",
+	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 6376a00..8f8dab3 100644
--- a/dojox/editor/plugins/nls/zh-tw/SpellCheck.js
+++ b/dojox/editor/plugins/nls/zh-tw/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "批次拼字檢查",
 	unfound: "找不到",
@@ -14,3 +16,5 @@
 	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 fd07f14..c582b14 100644
--- a/dojox/editor/plugins/nls/zh-tw/TableDialog.js
+++ b/dojox/editor/plugins/nls/zh-tw/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "插入表格",
 	modifyTableTitle: "修改表格",
@@ -29,3 +31,5 @@
 	deleteTableColumnLabel: "刪除欄"
 })
 
+//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 56c66f4..041235a 100644
--- a/dojox/editor/plugins/nls/zh-tw/TextColor.js
+++ b/dojox/editor/plugins/nls/zh-tw/TextColor.js
@@ -1,4 +1,8 @@
+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 3b7da3f..9700299 100644
--- a/dojox/editor/plugins/nls/zh-tw/latinEntities.js
+++ b/dojox/editor/plugins/nls/zh-tw/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -255,3 +257,5 @@
 	euro:"歐元符號"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/zh/AutoSave.js b/dojox/editor/plugins/nls/zh/AutoSave.js
index 70cfc0d..4664acc 100644
--- a/dojox/editor/plugins/nls/zh/AutoSave.js
+++ b/dojox/editor/plugins/nls/zh/AutoSave.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"saveLabel": "保存",
 	"saveSettingLabelOn": "设置自动保存时间间隔...",
@@ -11,3 +13,5 @@
 	"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 0439fbc..af2721d 100644
--- a/dojox/editor/plugins/nls/zh/Blockquote.js
+++ b/dojox/editor/plugins/nls/zh/Blockquote.js
@@ -1,3 +1,7 @@
+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 b813f20..2033c28 100644
--- a/dojox/editor/plugins/nls/zh/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/zh/Breadcrumb.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"nodeActions": "${nodeName} 操作",
 	"selectContents": "选择内容",
@@ -8,3 +10,5 @@
 	"moveEnd": "将光标移至结尾"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/zh/CollapsibleToolbar.js b/dojox/editor/plugins/nls/zh/CollapsibleToolbar.js
index 6515c53..12f1985 100644
--- a/dojox/editor/plugins/nls/zh/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/zh/CollapsibleToolbar.js
@@ -1,4 +1,8 @@
+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 fc7418d..a4b4b3e 100644
--- a/dojox/editor/plugins/nls/zh/FindReplace.js
+++ b/dojox/editor/plugins/nls/zh/FindReplace.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"findLabel": "查找:",
 	"findTooltip": "输入要查找的文本",
@@ -8,7 +10,6 @@
 	"matchCaseTooltip": "匹配大小写",
 	"backwards": "向后",
 	"backwardsTooltip": "向后搜索文本",
-	"replaceAll": "所有匹配项",
 	"replaceAllButton": "全部替换",
 	"replaceAllButtonTooltip": "替换所有文本",
 	"findButton": "查找",
@@ -20,3 +21,5 @@
 	"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 269b334..3bf2c10 100644
--- a/dojox/editor/plugins/nls/zh/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/zh/InsertAnchor.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertAnchor: "插入锚点",
 	title: "锚点属性",
@@ -6,3 +8,5 @@
 	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 86d00d3..17b7d6f 100644
--- a/dojox/editor/plugins/nls/zh/InsertEntity.js
+++ b/dojox/editor/plugins/nls/zh/InsertEntity.js
@@ -1,4 +1,8 @@
+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 c06e1ab..1370436 100644
--- a/dojox/editor/plugins/nls/zh/LocalImage.js
+++ b/dojox/editor/plugins/nls/zh/LocalImage.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertImageTitle: "插入图像",
 	url: "图像",
@@ -8,3 +10,5 @@
 	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 49518ba..c809089 100644
--- a/dojox/editor/plugins/nls/zh/PageBreak.js
+++ b/dojox/editor/plugins/nls/zh/PageBreak.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"pageBreak": "换页符"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/zh/PasteFromWord.js b/dojox/editor/plugins/nls/zh/PasteFromWord.js
index 8d0b634..19d4ceb 100644
--- a/dojox/editor/plugins/nls/zh/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/zh/PasteFromWord.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	"pasteFromWord": "从 Word 中粘贴",
 	"paste": "粘贴",
 	"cancel": "取消",
 	"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 1ae149a..01155de 100644
--- a/dojox/editor/plugins/nls/zh/Preview.js
+++ b/dojox/editor/plugins/nls/zh/Preview.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"preview": "预览"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/zh/SafePaste.js b/dojox/editor/plugins/nls/zh/SafePaste.js
new file mode 100644
index 0000000..406edb8
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "禁用了直接粘贴。请使用标准浏览器键盘或菜单粘贴控件在此对话框中粘贴内容。一旦您满意要插入的内容,请按“粘贴”按钮。要中止插入内容,请按“取消”按钮。"
+})
+);
diff --git a/dojox/editor/plugins/nls/zh/Save.js b/dojox/editor/plugins/nls/zh/Save.js
index dcfcf05..16e07aa 100644
--- a/dojox/editor/plugins/nls/zh/Save.js
+++ b/dojox/editor/plugins/nls/zh/Save.js
@@ -1,4 +1,8 @@
+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 322d393..da43a4d 100644
--- a/dojox/editor/plugins/nls/zh/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/zh/ShowBlockNodes.js
@@ -1,4 +1,8 @@
+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 3bf6ab7..6278b11 100644
--- a/dojox/editor/plugins/nls/zh/Smiley.js
+++ b/dojox/editor/plugins/nls/zh/Smiley.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	smiley: "插入表情图标",
 	emoticonSmile: "微笑",
@@ -17,6 +19,9 @@
 	emoticonYes: "点头",
 	emoticonNo: "摇头",
 	emoticonAngel: "天使",
-	emoticonCrying: "哭泣"
+	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 6700857..1fcd97c 100644
--- a/dojox/editor/plugins/nls/zh/SpellCheck.js
+++ b/dojox/editor/plugins/nls/zh/SpellCheck.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	widgetLabel: "批处理拼写检查",
 	unfound: "未找到",
@@ -14,3 +16,5 @@
 	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 9ed06d4..a15f0ff 100644
--- a/dojox/editor/plugins/nls/zh/TableDialog.js
+++ b/dojox/editor/plugins/nls/zh/TableDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	insertTableTitle: "插入表",
 	modifyTableTitle: "修改表",
@@ -29,3 +31,5 @@
 	deleteTableColumnLabel: "删除列"
 })
 
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/nls/zh/TextColor.js b/dojox/editor/plugins/nls/zh/TextColor.js
index 1b3f283..ba86ce9 100644
--- a/dojox/editor/plugins/nls/zh/TextColor.js
+++ b/dojox/editor/plugins/nls/zh/TextColor.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"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 e2382e9..3570a48 100644
--- a/dojox/editor/plugins/nls/zh/latinEntities.js
+++ b/dojox/editor/plugins/nls/zh/latinEntities.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -254,3 +256,5 @@
 	rsaquo:"右尖括号",
 	euro:"欧元符号"
 })
+//end v1.x content
+);
diff --git a/dojox/editor/plugins/resources/css/InsertEntity.css b/dojox/editor/plugins/resources/css/InsertEntity.css
index cb790a0..403dcc5 100755
--- a/dojox/editor/plugins/resources/css/InsertEntity.css
+++ b/dojox/editor/plugins/resources/css/InsertEntity.css
@@ -22,16 +22,16 @@
 .dojoxEntityPaletteCell {
 	/* individual cell of the drop down */
 	border: 1px dotted gray;
-	width: 20px;	/* todo: don't hardcode width/height; it's neither nececessary nor a11y safe */
+	width: 20px;	/* todo: don't hardcode width/height; it's neither necessary nor a11y safe */
 	line-height: 18px;
 	overflow: hidden;
 	z-index: 10;
 	text-align: center;
 }
 
-.dojoxEntityPaletteCellHover, .dojoxEntityPaletteCellActive, .dojoxEntityPaletteCellFocused {
+.dojoxEntityPaletteCell:hover, .dojoxEntityPaletteCell:active, .dojoxEntityPaletteCell:focus {
 	width: 18px;
-        line-height: 16px;
+    line-height: 16px;
 	overflow: hidden;
 	cursor: default;
 	border:1px dashed #000;
diff --git a/dojox/editor/plugins/resources/css/SafePaste.css b/dojox/editor/plugins/resources/css/SafePaste.css
new file mode 100644
index 0000000..c43d405
--- /dev/null
+++ b/dojox/editor/plugins/resources/css/SafePaste.css
@@ -0,0 +1,3 @@
+ at import "PasteFromWord.css";
+
+
diff --git a/dojox/editor/tests/editorFindReplace.html b/dojox/editor/tests/editorFindReplace.html
index 72682fa..a8f9992 100755
--- a/dojox/editor/tests/editorFindReplace.html
+++ b/dojox/editor/tests/editorFindReplace.html
@@ -20,6 +20,7 @@
 		dojo.require("dojo.parser");
 		dojo.require("dojox.editor.plugins.FindReplace");
 		dojo.require("dijit._editor.plugins.FullScreen");
+		dojo.require("dijit._editor.plugins.TabIndent");
 		dojo.require("dijit._editor.plugins.ViewSource");
 		dojo.require("dojox.editor.plugins.ShowBlockNodes");
 	</script>
diff --git a/dojox/editor/tests/editorSafePaste.html b/dojox/editor/tests/editorSafePaste.html
new file mode 100644
index 0000000..31b6efc
--- /dev/null
+++ b/dojox/editor/tests/editorSafePaste.html
@@ -0,0 +1,105 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>Editor SafePaste Test</title>
+
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../../../dijit/tests/css/dijitTests.css";
+		@import "../../../dijit/themes/claro/claro.css";
+		@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">
+		dojo.require("dijit.Editor");
+		dojo.require("dijit.form.Button");
+		dojo.require("dojo.parser");
+		dojo.require("dojox.editor.plugins.SafePaste");
+		dojo.require("dojox.editor.plugins.PrettyPrint");
+		dojo.require("dijit._editor.plugins.ViewSource");
+	</script>
+</head>
+<body class="claro">
+	<br>
+	<h1 class="testTitle">Editor + SafePaste Plugin</h1>
+
+	<h2>This is an example editor with SafePaste enabled.</h2>  
+	The SafePaste plugin an extension of PasteFromWord that uses a special dialog that allows you to paste in content from 
+	WordPad and Microsoft word, or content that contains script tags and other odd items and it will filter out extraneous 
+	tags, scripts, and other items to make the content closer to standard HTML and safer for a web document before inserting it.
+	<br>
+
+	<div dojoType="dijit.Editor" id="editor1" extraPlugins="['safepaste', 'viewsource', 'prettyprint']">
+		This instance is created from a div with an <b>extra</b> plugin, 'PasteFromWord' loaded.
+		<ul>
+			<li>List Item One</li>
+			<li>List Item Two</li>
+			<li>List Item Three</li>
+			<li>List Item Four</li>
+		</ul>
+		<br>
+		<a href="http://www.dojotoolkit.org">The Dojo Toolkit</a>
+		<br>
+		<br>
+		<ol>
+			<li>One</li>
+			<li>Two
+			<ol>
+				<li>
+					Three
+				</li>
+			</ol>
+		</ol>
+		<br>
+		<br>
+		<h3>A bunch of Lorum Ipsum Text:</h3>
+		<p style="color: #646060;">
+			Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus eget turpis nunc.
+			Praesent ut metus ac mi gravida lobortis vel quis nulla. Sed elementum elit eget
+			ante viverra consectetur. Praesent pulvinar faucibus risus in pulvinar. Sed auctor,
+			dui sed suscipit semper, metus sapien feugiat urna, et auctor nisi est quis purus.
+			Aliquam eu tortor eu ante venenatis pellentesque nec sed massa. Nulla feugiat, nunc
+			ac aliquet elementum, lacus odio dictum nisl, vel molestie neque tellus eget nibh.
+			Curabitur et eros quam, non consectetur erat. Class aptent taciti sociosqu ad litora
+			torquent per conubia nostra, per inceptos himenaeos. Quisque luctus imperdiet felis,
+			a mollis sapien scelerisque ut. Quisque dui neque, vulputate eu consectetur et, fermentum
+			id est. Nulla euismod lorem at massa aliquam at cursus mi fermentum. Quisque rhoncus
+			ornare pharetra. Cras vestibulum convallis nisl, eget ultrices sem porta eget. Duis
+			in dolor id nibh volutpat sodales. Nullam eleifend, sapien accumsan convallis tincidunt,
+			justo mi pellentesque dolor, in suscipit dolor quam ac ligula.
+		</p>
+		<p>
+			Ut molestie facilisis nisi sed consequat. Nunc in turpis quam, vel elementum lectus.
+			Suspendisse vel consequat augue. Praesent id orci orci. Praesent est tortor, consequat
+			eu posuere nec, volutpat ac diam. Cras pretium quam non diam dictum tincidunt. Mauris
+			aliquet lacinia odio vitae elementum. Nam rutrum semper metus, in consectetur lectus
+			aliquam a. Maecenas pharetra nibh nec leo consequat vitae rhoncus nibh volutpat.
+			Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus
+			mus. Sed at odio turpis, sit amet molestie nisl. Curabitur in ligula id tortor feugiat
+			semper. Vestibulum id nunc magna, eu lacinia nibh. Ut congue adipiscing dictum.
+		</p>
+		<p>
+			Suspendisse potenti. Class aptent taciti sociosqu ad litora torquent per conubia
+			nostra, per inceptos himenaeos. Phasellus in orci purus, sed aliquet quam. Aenean
+			ultrices tincidunt augue, in feugiat massa dignissim in. Nunc a dolor eu mi fringilla
+			laoreet. Praesent lacinia mi eu sapien imperdiet dignissim. Praesent a pellentesque
+			est. Sed augue eros, porttitor nec consequat bibendum, mattis lobortis diam. Sed
+			at massa ante. In volutpat ultrices mattis. Vestibulum tempus pretium risus quis
+			aliquet. Donec non ante vitae orci euismod eleifend. Aliquam at metus quis turpis
+			pharetra porta. Sed dignissim risus in erat aliquam et posuere nulla molestie. Nunc
+			iaculis lectus eget augue sollicitudin gravida ac non nisl. Vivamus bibendum gravida
+			vehicula. Aliquam vitae mi ligula. Nulla at augue velit, vitae ultricies libero.
+			Proin at lorem turpis.
+		</p>
+		<center>Centered Text</center>
+	</div>
+	
+	<h1>SafePaste with bold, ul, ol, li, and center tag stripping.</h1>
+	Copy the content from the above editor and paste it down here, it will strip the b, center, and the ul/li/ol tags (the ones specified in stripTags)
+	<div dojoType="dijit.Editor" id="editor2" extraPlugins="[{name: 'safepaste', stripTags: ['b', 'ul', 'li', 'ol', 'center']}, 'viewsource', 'prettyprint']">
+	</div>
+</body>
+</html>
diff --git a/dojox/editor/tests/testPluginsAll.html b/dojox/editor/tests/testPluginsAll.html
index 0c27828..b28a314 100644
--- a/dojox/editor/tests/testPluginsAll.html
+++ b/dojox/editor/tests/testPluginsAll.html
@@ -5,6 +5,7 @@
 	<title>Editor with all plugins enabled (more or less)</title>
 
 	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/themes/claro/claro.css";
 		@import "../../../dojox/editor/plugins/resources/css/PageBreak.css";
 		@import "../../../dojox/editor/plugins/resources/css/ShowBlockNodes.css";
@@ -22,6 +23,8 @@
 		@import "../../../dojox/editor/plugins/resources/css/StatusBar.css"; 
 		@import "../../../dojox/editor/plugins/resources/css/LocalImage.css";
 		@import "../../../dojox/editor/plugins/resources/css/AutoSave.css";
+		@import "../../../dojox/editor/plugins/resources/css/SafePaste.css";
+		@import "../../../dojox/editor/plugins/resources/css/Smiley.css";
 
 		body, html { width:100%; height:100%; margin:0; padding:0; overflow:hidden;}
 		#borderContainer { width:100%; height:100%; overflow:hidden;}
@@ -66,7 +69,10 @@
 		dojo.require("dojox.editor.plugins.AutoUrlLink");
 		dojo.require("dojox.editor.plugins.ResizeTableColumn");
 		dojo.require("dojox.editor.plugins.AutoSave");
-			
+		dojo.require("dojox.editor.plugins.SafePaste");
+		dojo.require("dojox.editor.plugins.Smiley");
+		
+		
 		var plugins = ['collapsibletoolbar', 'newPage', 'save', 'autosave', {name: 'viewSource', stripScripts: true, stripComments: true}, 'showBlockNodes', '|',
 			{name: 'fullscreen', zIndex: 900}, 'preview', 'print', '|',
 			'selectAll', 'cut', 'copy', 'findreplace', 'paste','pastefromword', 'delete', 'undo', 'redo', '|',
@@ -74,7 +80,7 @@
 			'justifyLeft', 'justifyRight', 'justifyCenter', 'justifyFull', 'toggleDir', '|',
 			'bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript',  'foreColor', 'hiliteColor', 'removeFormat', '||',
 			'fontName', 'fontSize', 'formatBlock', '||',
-			'insertEntity', 'createLink', 'unlink', 'insertanchor', 'insertImage', 
+			'insertEntity', 'smiley', 'createLink', 'unlink', 'insertanchor', 'insertImage', 
 			{name: 'localImage', uploadable: true, uploadUrl: '../../form/tests/UploadFile.php', baseImageUrl: '../../form/tests/'},
 			{name: 'dojox.editor.plugins.TablePlugins', command: 'insertTable'},
 			{name: 'dojox.editor.plugins.TablePlugins', command: 'modifyTable'},
@@ -90,7 +96,7 @@
 			{name: 'prettyprint', indentBy: "3", entityMap: dojox.html.entities.html.concat(dojox.html.entities.latin)},
 			{name: 'dijit._editor.plugins.EnterKeyHandling', blockNodeForEnter: "P"},
 			'autoUrlLink',
-			'normalizeindentoutdent', 'breadcrumb', {name: 'normalizestyle', mode: "css"}, {name: 'statusbar', resizer: false}
+			'normalizeindentoutdent', 'breadcrumb', {name: 'normalizestyle', mode: "css"}, {name: 'statusbar', resizer: false}, "safepaste"
 		];
 	</script>
 </head>
diff --git a/dojox/embed/Flash.js b/dojox/embed/Flash.js
index 091b33d..3527bb3 100644
--- a/dojox/embed/Flash.js
+++ b/dojox/embed/Flash.js
@@ -1,6 +1,5 @@
-dojo.provide("dojox.embed.Flash");
+define(["dojo"], function(dojo) {
 
-(function(){
 	/*******************************************************
 		dojox.embed.Flash
 
@@ -10,6 +9,9 @@ dojo.provide("dojox.embed.Flash");
 		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)
 	var keyBase = "dojox-embed-flash-", keyCount=0;
@@ -25,7 +27,6 @@ dojo.provide("dojox.embed.Flash");
 	};
 
 	function prep(kwArgs){
-		// console.warn("KWARGS:", kwArgs)
 		kwArgs = dojo.delegate(_baseKwArgs, kwArgs);
 
 		if(!("path" in kwArgs)){
@@ -54,7 +55,6 @@ dojo.provide("dojox.embed.Flash");
 				kwArgs.params.FlashVars = a.join("&");
 				delete kwArgs.vars;
 			}
-			// FIXME: really? +'s?
 			var s = '<object id="' + kwArgs.id + '" '
 				+ 'classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" '
 				+ 'width="' + kwArgs.width + '" '
@@ -106,16 +106,6 @@ dojo.provide("dojox.embed.Flash");
 				});
 		});
 
-		//	TODO: ...and double check this fix; is IE really firing onbeforeunload with any kind of href="#" link?
-		/*
-		var beforeUnloadHandle = dojo.connect(dojo.global, "onbeforeunload", function(){
-			try{
-				if(__flash_unloadHandler){ __flash_unloadHandler=function(){ }; }
-				if(__flash_savedUnloadHandler){ __flash_savedUnloadHandler=function(){ }; }
-			} catch(e){ }
-			dojo.disconnect(beforeUnloadHandle);
-		});
-		*/
 	} else {
 		//	*** Sane browsers branch ******************************************************************
 		fMarkup = function(kwArgs){
@@ -219,13 +209,6 @@ 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).
 		//
-		//		*Important note*:  this code includes a workaround for the Eolas "fix" from
-		//		Microsoft; in order to work around the "click to activate this control" message
-		//		on any embedded Flash movie, this code will load a separate, non-dojo.require
-		//		javascript file in order to write the Flash movie into the document.  As such
-		//		it cannot be used with Dojo's scope map techniques for working with multiple
-		//		versions of Dojo on the same page.
-		//
 		//	kwArgs: dojox.embed.__flashArgs
 		//		The various arguments that will be used to help define the Flash movie.
 		//	node: DomNode
@@ -260,7 +243,6 @@ dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars,
 		//	minimumVersion: Number
 		//		The minimum version of Flash required to run this movie.
 		this.minimumVersion = kwArgs.minimumVersion || minimumVersion;
-		//console.log("AVAILABLE:", this);
 
 		//	id: String
 		//		The id of the DOMNode to be used for this movie.  Can be used with dojo.byId to get a reference.
@@ -297,13 +279,11 @@ dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars,
 
 	dojo.extend(dojox.embed.Flash, {
 		onReady: function(/*HTMLObject*/ movie){
-			console.warn("embed.Flash.movie.onReady:", movie)
 			//	summary:
 			//		Stub function for you to attach to when the movie reference is first
 			//		pushed into the document.
 		},
 		onLoad: function(/*HTMLObject*/ movie){
-			console.warn("embed.Flash.movie.onLoad:", movie)
 			//	summary:
 			//		Stub function for you to attach to when the movie has finished downloading
 			//		and is ready to be manipulated.
@@ -321,7 +301,6 @@ dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars,
 			this.onLoad(this.movie);
 		},
 		init: function(/*dojox.embed.__flashArgs*/ kwArgs, /*DOMNode?*/ node){
-			console.log("embed.Flash.movie.init")
 			//	summary
 			//		Initialize (i.e. place and load) the movie based on kwArgs.
 			this.destroy();		//	ensure we are clean first.
@@ -347,8 +326,7 @@ dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars,
 						try{
 							p = this.movie.PercentLoaded();
 						}catch(e){
-							/* squelch */
-							console.warn("this.movie.PercentLoaded() failed");
+							console.warn("this.movie.PercentLoaded() failed", e, this.movie);
 						}
 
 						if(p == 100){
@@ -357,7 +335,6 @@ dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars,
 
 						}else if(p==0 && this._pollCount++ > this._pollMax){
 							// after several attempts, we're not past zero.
-							// FIXME: What if we get stuck on 33% or something?
 							clearInterval(this._poller);
 							throw new Error("Building SWF failed.");
 						}
@@ -509,33 +486,21 @@ dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars,
 		}
 	});
 
-	/*if(dojo.isIE){
-		//	Ugh!
-		if(dojo._initFired){
-			var e = document.createElement("script");
-			e.type = "text/javascript";
-			e.src = dojo.moduleUrl("dojox", "embed/IE/flash.js");
-			document.getElementsByTagName("head")[0].appendChild(e);
-		}else{
-			//	we can use document.write.  What a kludge.
-			document.write('<scr'+'ipt type="text/javascript" src="' + dojo.moduleUrl("dojox", "embed/IE/flash.js") + '">'
-				+ '</scr'+'ipt>');
+	dojox.embed.Flash.place = function(kwArgs, node){
+		var o = fMarkup(kwArgs);
+		node = dojo.byId(node);
+		if(!node){
+			node = dojo.doc.createElement("div");
+			node.id = o.id+"-container";
+			dojo.body().appendChild(node);
 		}
-	}else{*/
-		dojox.embed.Flash.place = function(kwArgs, node){
-			var o = fMarkup(kwArgs);
-			node = dojo.byId(node);
-			if(!node){
-				node = dojo.doc.createElement("div");
-				node.id = o.id+"-container";
-				dojo.body().appendChild(node);
-			}
-			if(o){
-				node.innerHTML = o.markup;
-				return o.id;
-			}
-			return null;
+		if(o){
+			node.innerHTML = o.markup;
+			return o.id;
 		}
-		dojox.embed.Flash.onInitialize();
-	//}
-})();
+		return null;
+	}
+	dojox.embed.Flash.onInitialize();
+
+	return dojox.embed.Flash;
+});
diff --git a/dojox/embed/IE/flash.js b/dojox/embed/IE/flash.js
deleted file mode 100644
index ad20e89..0000000
--- a/dojox/embed/IE/flash.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// *** Fricking Eolas.  This is here to get around the Eolas issue.  Sigh. ***************
-dojox.embed.Flash.place = function(kwArgs, node){
-	var o = dojox.embed.Flash.__ie_markup__(kwArgs);
-	node=dojo.byId(node);
-
-	if(!node){
-		node=dojo.doc.createElement("div");
-		node.id=o.id+"-container";
-		dojo.body().appendChild(node);
-	}
-	
-	if(o){
-		node.innerHTML = o.markup;
-		//return window[o.id];
-		return o.id;
-	}
-	return null;
-}
-dojox.embed.Flash.onInitialize();
diff --git a/dojox/embed/Object.js b/dojox/embed/Object.js
index 5b81c47..b361f93 100644
--- a/dojox/embed/Object.js
+++ b/dojox/embed/Object.js
@@ -1,11 +1,14 @@
-dojo.provide("dojox.embed.Object");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",	// dojo.declare
+	"dojo/dom-geometry",
+	"dijit/_Widget",
+	"./Flash",
+	"./Quicktime"
+], function (dojo, declare, domGeometry, _Widget, Flash, Quicktime) {
 dojo.experimental("dojox.embed.Object");
 
-dojo.require("dijit._Widget");
-dojo.require("dojox.embed.Flash");
-dojo.require("dojox.embed.Quicktime");
-
-dojo.declare("dojox.embed.Object", dijit._Widget, {
+return dojo.declare("dojox.embed.Object", _Widget, {
 	//	summary:
 	//		A widget you can use to embed either a Flash or Quicktime
 	//		movie.
@@ -55,16 +58,16 @@ dojo.declare("dojox.embed.Object", dijit._Widget, {
 		//		Constructs the movie and places it in the document.
 		if(!this.width || !this.height){
 			//	get the width and height from the domNode
-			var box=dojo.marginBox(this.domNode);
+			var box=domGeometry.getMarginBox(this.domNode);
 			this.width=box.w, this.height=box.h;
 		}
 
 		//	the default embed constructor.
-		var em=dojox.embed.Flash;
+		var em=Flash;
 
 		//	figure out what kind of movie this is.
 		if(this.src.match(this.reQtMovie) || this.src.match(this.reQtAudio)){
-			em=dojox.embed.Quicktime;
+			em=Quicktime;
 		}
 
 		//	loop through any attributes and set up our params object.
@@ -103,3 +106,4 @@ dojo.declare("dojox.embed.Object", dijit._Widget, {
 		this.movie=new (em)(kwArgs, this.domNode);
 	}
 });
+});
diff --git a/dojox/embed/Quicktime.js b/dojox/embed/Quicktime.js
index aac38a0..ccf3c29 100644
--- a/dojox/embed/Quicktime.js
+++ b/dojox/embed/Quicktime.js
@@ -1,6 +1,12 @@
-dojo.provide("dojox.embed.Quicktime");
-
-(function(d){
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/sniff",
+	"dojo/_base/window",
+	"dojo/dom",
+	"dojo/dom-construct",
+	"dojo/domReady" // fixes doc.readyState in Fx<=3.5
+], function (dojo, lang, has, windowUtil, domUtil, domConstruct) {
 	/*******************************************************
 		dojox.embed.Quicktime
 
@@ -18,11 +24,12 @@ dojo.provide("dojox.embed.Quicktime");
 		},
 		keyBase = "dojox-embed-quicktime-",
 		keyCount = 0,
-		getQTMarkup = 'This content requires the <a href="http://www.apple.com/quicktime/download/" title="Download and install QuickTime.">QuickTime plugin</a>.';
+		getQTMarkup = 'This content requires the <a href="http://www.apple.com/quicktime/download/" title="Download and install QuickTime.">QuickTime plugin</a>.',
+		embed = dojo.getObject("dojox.embed", true);
 
 	//	*** private methods *********************************************************
 	function prep(kwArgs){
-		kwArgs = d.mixin(d.clone(__def__), kwArgs || {});
+		kwArgs = dojo.mixin(lang.clone(__def__), kwArgs || {});
 		if(!("path" in kwArgs) && !kwArgs.testing){
 			console.error("dojox.embed.Quicktime(ctor):: no path reference to a QuickTime movie was provided.");
 			return null;
@@ -36,7 +43,7 @@ dojo.provide("dojox.embed.Quicktime");
 		return kwArgs;
 	}
 
-	if(d.isIE){
+	if(has("ie")){
 		installed = (function(){
 			try{
 				var o = new ActiveXObject("QuickTimeCheckObject.QuickTimeCheck.1");
@@ -126,7 +133,7 @@ dojo.provide("dojox.embed.Quicktime");
 	}
 	=====*/
 
-	dojox.embed.Quicktime=function(/* dojox.embed.__QTArgs */kwArgs, /* DOMNode */node){
+	embed.Quicktime=function(/* dojox.embed.__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
@@ -150,10 +157,10 @@ dojo.provide("dojox.embed.Quicktime");
 		//	|		height: 300
 		//	|	}, myWrapperNode);
 
-		return dojox.embed.Quicktime.place(kwArgs, node);	//	HTMLObject
+		return embed.Quicktime.place(kwArgs, node);	//	HTMLObject
 	};
 
-	d.mixin(dojox.embed.Quicktime, {
+	dojo.mixin(embed.Quicktime, {
 		//	summary:
 		//		A singleton object used internally to get information
 		//		about the QuickTime player available in a browser, and
@@ -187,20 +194,20 @@ dojo.provide("dojox.embed.Quicktime");
 		version: qtVersion,
 		initialized: false,
 		onInitialize: function(){
-			dojox.embed.Quicktime.initialized = true;
+			embed.Quicktime.initialized = true;
 		},	//	stub function to let you know when this is ready
 
 		place: function(kwArgs, node){
 			var o = qtMarkup(kwArgs);
 
-			if(!(node = d.byId(node))){
-				node=d.create("div", { id:o.id+"-container" }, d.body());
+			if(!(node = domUtil.byId(node))){
+				node=domConstruct.create("div", { id:o.id+"-container" }, windowUtil.body());
 			}
 			
 			if(o){
 				node.innerHTML = o.markup;
 				if(o.id){
-					return d.isIE? d.byId(o.id) : document[o.id];	//	QuickTimeObject
+					return has("ie") ? dom.byId(o.id) : document[o.id];	//	QuickTimeObject
 				}
 			}
 			return null;	//	QuickTimeObject
@@ -208,7 +215,7 @@ dojo.provide("dojox.embed.Quicktime");
 	});
 
 	//	go get the info
-	if(!d.isIE){
+	if(!has("ie")){
 		var id = "-qt-version-test",
 			o = qtMarkup({ testing:true , width:4, height:4 }),
 			c = 10, // counter to prevent infinite looping
@@ -218,14 +225,14 @@ dojo.provide("dojox.embed.Quicktime");
 		function getVer(){
 			setTimeout(function(){
 				var qt = document[o.id],
-					n = d.byId(id);
+					n = domUtil.byId(id);
 
 				if(qt){
 					try{
 						var v = qt.GetQuickTimeVersion().split(".");
-						dojox.embed.Quicktime.version = { major: parseInt(v[0]||0), minor: parseInt(v[1]||0), rev: parseInt(v[2]||0) };
-						if(dojox.embed.Quicktime.supported = v[0]){
-							dojox.embed.Quicktime.onInitialize();
+						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();
 						}
 						c = 0;
 					} catch(e){
@@ -235,17 +242,17 @@ dojo.provide("dojox.embed.Quicktime");
 					}
 				}
 
-				if(!c && n){ d.destroy(n); }
+				if(!c && n){ domConstruct.destroy(n); }
 			}, 20);
 		}
 
-		if(d._initFired){
+		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
-			d.create("div", {
+			domConstruct.create("div", {
 				innerHTML: o.markup,
 				id: id,
 				style: { top:top, left:0, width:widthHeight, height:widthHeight, overflow:"hidden", position:"absolute" }
-			}, d.body());
+			}, windowUtil.body());
 		}else{
 			// body isn't loaded yet, so we need to document.write the QuickTime markup
 			document.write(
@@ -254,10 +261,12 @@ dojo.provide("dojox.embed.Quicktime");
 				+ '</div>');
 		}
 		getVer();
-	}else if(d.isIE && installed){
+	}else if(has("ie") && installed){
 		// we already know if IE has QuickTime installed, but we need this to seem like a callback.
 		setTimeout(function(){
-			dojox.embed.Quicktime.onInitialize();
+			embed.Quicktime.onInitialize();
 		}, 10);
 	}
-})(dojo);
+	
+	return embed.Quicktime;
+});
diff --git a/dojox/embed/flashVars.js b/dojox/embed/flashVars.js
index f5a83c5..798b5e9 100644
--- a/dojox/embed/flashVars.js
+++ b/dojox/embed/flashVars.js
@@ -1,6 +1,9 @@
-dojo.provide("dojox.embed.flashVars");
+define(['dojo'],function(dojo){
 
-dojo.mixin(dojox.embed.flashVars, {
+dojo.getObject("dojox.embed", true);
+dojo.deprecated("dojox.embed.flashVars", "Will be removed in 2.0", "2.0");
+
+dojox.embed.flashVars = {
 	//	summary
 	//		Handles flashvar serialization
 	//		Converting complex objects into a simple, clear string that can be appended
@@ -52,4 +55,6 @@ dojo.mixin(dojox.embed.flashVars, {
 		// Dev note: important that there is no double semi-colons
 		return n+":"+o; // String
 	}
-});
\ No newline at end of file
+};
+return dojox.embed.flashVars;
+});
diff --git a/dojox/embed/tests/flash.html b/dojox/embed/tests/flash.html
index f4dcab4..f654c43 100644
--- a/dojox/embed/tests/flash.html
+++ b/dojox/embed/tests/flash.html
@@ -6,33 +6,38 @@
 			@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="async:1, isDebug: true, fontSizeWatch: true" ></script>
 		<script type="text/javascript">
-			dojo.require("dojox.embed.Flash");
+			require(["dojo", "dojox/embed/Flash", "dojo/domReady!"], function(dojo){
+				onDomReady();
+			});
+
 
 			/*******************************************************************
 				A note.
 
 				You *can* dojo.require dojox.embed.Flash on the fly (i.e.
 				after load), but if you do so, you *must* give Safari and IE
-				a little bit of time before you can start using any of the 
+				a little bit of time before you can start using any of the
 				methods.  Quick tests showed that 200ms is more than enough,
 				but you should test intervals at your discretion.
 			********************************************************************/
-			var testMovieUrl=dojo.moduleUrl("dojox", "embed/tests/resources/hfp.swf"), movie;
-			var proxyMovieUrl=dojo.moduleUrl("dojox", "embed/tests/resources/TestFlash.swf"), proxy;
+
 
 			function log(msg){
 				dojo.byId("fakeconsole").innerHTML += "<div>"+msg+"</div>";
 			}
-			
-			dojo.addOnLoad(function(){
+
+			onDomReady = function(){
+				var testMovieUrl=dojo.moduleUrl("dojox", "embed/tests/resources/hfp.swf"), movie;
+				var proxyMovieUrl=dojo.moduleUrl("dojox", "embed/tests/resources/TestFlash.swf"), proxy;
+
 				dojo.byId("results").innerHTML = dojo.toJson(dojox.embed.Flash.version);
 				movie=new dojox.embed.Flash({ path: testMovieUrl }, "flashHolder");
 				dojo.connect(movie, "onReady", function(mv){
 					console.log("The test movie loaded.");
 				});
-				
+
 				proxy = new dojox.embed.Flash({ path: proxyMovieUrl, width:4, height:4 }, "proxyHolder");
 				dojo.connect(proxy, "onLoad", function(m){
 					dojox.embed.Flash.proxy(proxy, [ "setMessage", "getMessage" ]);
@@ -40,7 +45,7 @@
 					proxy.setMessage("we love dojox.embed");
 					console.log("The message stored in the test movie is: '", proxy.getMessage(), "'");
 				});
-			});
+			};
 		</script>
 	</head>
 	<body>
@@ -48,7 +53,7 @@
 		<p>
 			This page is testing the base Flash movie generator.
 		</p>
-		<div id="fakeconsole"></div>	
+		<div id="fakeconsole"></div>
 		<p>Installed Flash version: <span id="results"></span>.</p>
 		<div id="flashHolder" style="border:1px solid black;">
 			A movie will be inserted here on load.
diff --git a/dojox/embed/tests/object.html b/dojox/embed/tests/object.html
index d2db174..a04e49c 100644
--- a/dojox/embed/tests/object.html
+++ b/dojox/embed/tests/object.html
@@ -20,9 +20,9 @@
 	<body>
 		<h1>dojox.embed.Object</h1>
 		<p>
-		This is a test for the embedder widget.  Iron Man trailer is referenced directly from the Apple servers.
+		This is a test for the embedder widget.
 		</p>
-		<div dojoType="dojox.embed.Object" src="http://movies.apple.com/movies/paramount/iron_man/iron_man-tlr2_h.320.mov" width="320" height="152"></div>
+		<div dojoType="dojox.embed.Object" src="resources/sample.3gp" width="176" height="144"></div>
 		<div dojoType="dojox.embed.Object" src="resources/hfp.swf" style="float:right;width:100px;height:100px;border:1px solid black;"></div>
 		<div id="flashTest" dojoType="dojox.embed.Object" src="resources/hfp.swf"></div>
 	</body>
diff --git a/dojox/encoding/_base.js b/dojox/encoding/_base.js
index c3dfe82..c9dc0a0 100644
--- a/dojox/encoding/_base.js
+++ b/dojox/encoding/_base.js
@@ -1,3 +1,3 @@
-dojo.provide("dojox.encoding._base");
-
-
+define(['dojo/_base/lang'], function(lang){
+	return lang.getObject("dojox.encoding._base", true);
+});
diff --git a/dojox/encoding/ascii85.js b/dojox/encoding/ascii85.js
index 3ae7a49..4594cde 100644
--- a/dojox/encoding/ascii85.js
+++ b/dojox/encoding/ascii85.js
@@ -1,8 +1,10 @@
-// AMD-ID "dojox/encoding/ascii85"
-define(["dojo", "dojox"], function(dojo, dojox) {
-dojo.getObject("encoding.ascii85", true, dojox);
+define(["dojo/_base/lang"], function(lang) {
+
+	var ascii85 = lang.getObject("dojox.encoding.ascii85", true);
+	/*=====
+		ascii85 = dojox.encoding.ascii85;
+	=====*/
 
-(function(){
 	var c = function(input, length, result){
 		var i, j, n, b = [0, 0, 0, 0, 0];
 		for(i = 0; i < length; i += 4){
@@ -16,7 +18,7 @@ dojo.getObject("encoding.ascii85", true, dojox);
 		}
 	};
 
-	dojox.encoding.ascii85.encode = function(input){
+	ascii85.encode = function(input){
 		// 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;
@@ -32,7 +34,7 @@ dojo.getObject("encoding.ascii85", true, dojox);
 		return result.join("");	// String
 	};
 
-	dojox.encoding.ascii85.decode = function(input){
+	ascii85.decode = function(input){
 		// 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;
@@ -58,8 +60,6 @@ dojo.getObject("encoding.ascii85", true, dojox);
 		}
 		return r;
 	};
-})();
-
 
-return dojox.encoding.ascii85;
+	return ascii85;
 });
diff --git a/dojox/encoding/base64.js b/dojox/encoding/base64.js
index 2233536..ddf0e2a 100644
--- a/dojox/encoding/base64.js
+++ b/dojox/encoding/base64.js
@@ -1,13 +1,14 @@
-// AMD-ID "dojox/encoding/base64"
-define(["dojo", "dojox"], function(dojo, dojox) {
-dojo.getObject("encoding.base64", true, dojox);
+define(["dojo/_base/lang"], function(lang) {
+	
+	var base64 = lang.getObject("dojox.encoding.base64", true);
+	/*=====
+		base64 = dojox.encoding.base64;
+	=====*/
 
-(function(){
 	var p="=";
 	var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-	var dxe=dojox.encoding;
 
-	dxe.base64.encode=function(/* byte[] */ba){
+	base64.encode=function(/* byte[] */ba){
 		//	summary
 		//	Encode an array of bytes as a base64-encoded string
 		var s=[], l=ba.length;
@@ -42,7 +43,7 @@ dojo.getObject("encoding.base64", true, dojox);
 		return s.join("");	//	string
 	};
 
-	dxe.base64.decode=function(/* string */str){
+	base64.decode=function(/* string */str){
 		//	summary
 		//	Convert a base64-encoded string to an array of bytes
 		var s=str.split(""), out=[];
@@ -61,8 +62,6 @@ dojo.getObject("encoding.base64", true, dojox);
 		while(out[out.length-1]==0){ out.pop(); }
 		return out;	//	byte[]
 	};
-})();
-
-
-return dojox.encoding.base64;
+	
+	return base64;
 });
diff --git a/dojox/encoding/bits.js b/dojox/encoding/bits.js
index f2d8637..e5df2e0 100644
--- a/dojox/encoding/bits.js
+++ b/dojox/encoding/bits.js
@@ -1,70 +1,74 @@
-// AMD-ID "dojox/encoding/bits"
-define(["dojo", "dojox"], function(dojo, dojox) {
-dojo.getObject("encoding.bits", true, dojox);
+define([
+	"dojo/_base/lang"	// dojo.extend
+], function(lang) {
+	var bits = lang.getObject("dojox.encoding.bits", true);
+	/*=====
+		bits = dojox.encoding.bits;
+	=====*/
 
-dojox.encoding.bits.OutputStream = function(){
-	this.reset();
-};
+	bits.OutputStream = function(){
+		this.reset();
+	};
 
-dojo.extend(dojox.encoding.bits.OutputStream, {
-	reset: function(){
-		this.buffer = [];
-		this.accumulator = 0;
-		this.available = 8;
-	},
-	putBits: function(value, width){
-		while(width){
-			var w = Math.min(width, this.available);
-			var v = (w <= width ? value >>> (width - w) : value) << (this.available - w);
-			this.accumulator |= v & (255 >>> (8 - this.available));
-			this.available -= w;
-			if(!this.available){
-				this.buffer.push(this.accumulator);
-				this.accumulator = 0;
-				this.available = 8;
+	lang.extend(bits.OutputStream, {
+		reset: function(){
+			this.buffer = [];
+			this.accumulator = 0;
+			this.available = 8;
+		},
+		putBits: function(value, width){
+			while(width){
+				var w = Math.min(width, this.available);
+				var v = (w <= width ? value >>> (width - w) : value) << (this.available - w);
+				this.accumulator |= v & (255 >>> (8 - this.available));
+				this.available -= w;
+				if(!this.available){
+					this.buffer.push(this.accumulator);
+					this.accumulator = 0;
+					this.available = 8;
+				}
+				width -= w;
 			}
-			width -= w;
+		},
+		getWidth: function(){
+			return this.buffer.length * 8 + (8 - this.available);
+		},
+		getBuffer: function(){
+			var b = this.buffer;
+			if(this.available < 8){ b.push(this.accumulator & (255 << this.available)); }
+			this.reset();
+			return b;
 		}
-	},
-	getWidth: function(){
-		return this.buffer.length * 8 + (8 - this.available);
-	},
-	getBuffer: function(){
-		var b = this.buffer;
-		if(this.available < 8){ b.push(this.accumulator & (255 << this.available)); }
-		this.reset();
-		return b;
-	}
-});
+	});
 
-dojox.encoding.bits.InputStream = function(buffer, width){
-	this.buffer = buffer;
-	this.width = width;
-	this.bbyte = this.bit = 0;
-};
+	bits.InputStream = function(buffer, width){
+		this.buffer = buffer;
+		this.width = width;
+		this.bbyte = this.bit = 0;
+	};
 
-dojo.extend(dojox.encoding.bits.InputStream, {
-	getBits: function(width){
-		var r = 0;
-		while(width){
-			var w = Math.min(width, 8 - this.bit);
-			var v = this.buffer[this.bbyte] >>> (8 - this.bit - w);
-			r <<= w;
-			r |= v & ~(~0 << w);
-			this.bit += w;
-			if(this.bit == 8){
-				++this.bbyte;
-				this.bit = 0;
+	lang.extend(bits.InputStream, {
+		getBits: function(width){
+			var r = 0;
+			while(width){
+				var w = Math.min(width, 8 - this.bit);
+				var v = this.buffer[this.bbyte] >>> (8 - this.bit - w);
+				r <<= w;
+				r |= v & ~(~0 << w);
+				this.bit += w;
+				if(this.bit == 8){
+					++this.bbyte;
+					this.bit = 0;
+				}
+				width -= w;
 			}
-			width -= w;
+			return r;
+		},
+		getWidth: function(){
+			return this.width - this.bbyte * 8 - this.bit;
 		}
-		return r;
-	},
-	getWidth: function(){
-		return this.width - this.bbyte * 8 - this.bit;
-	}
-});
+	});
 
 
-return dojox.encoding.bits;
+	return bits;
 });
diff --git a/dojox/encoding/compression/lzw.js b/dojox/encoding/compression/lzw.js
index 4f8327e..374f6b9 100644
--- a/dojox/encoding/compression/lzw.js
+++ b/dojox/encoding/compression/lzw.js
@@ -1,20 +1,25 @@
-// AMD-ID "dojox/encoding/compression/lzw"
-define(["dojo", "dojox", "dojox/encoding/bits"], function(dojo, dojox) {
-dojo.getObject("encoding.compression.lzw", true, dojox);
+define([
+	"dojo/_base/lang",	// dojo.extend
+	"../bits"
+], function(lang, bits) {
 
-(function(){
-		var _bits = function(x){
+	var lzw = lang.getObject("dojox.encoding.compression.lzw", true);
+	/*=====
+		lzw = dojox.encoding.compression.lzw;
+	=====*/
+
+	var _bits = function(x){
 		var w = 1;
 		for(var v = 2; x >= v; v <<= 1, ++w);
 		return w;
 	};
 
-	dojox.encoding.compression.lzw.Encoder = function(n){
+	lzw.Encoder = function(n){
 		this.size = n;
 		this.init();
 	};
 
-	dojo.extend(dojox.encoding.compression.lzw.Encoder, {
+	lang.extend(lzw.Encoder, {
 		init: function(){
 			this.dict = {};
 			for(var i = 0; i < this.size; ++i){
@@ -50,12 +55,12 @@ dojo.getObject("encoding.compression.lzw", true, dojox);
 		}
 	});
 
-	dojox.encoding.compression.lzw.Decoder = function(n){
+	lzw.Decoder = function(n){
 		this.size = n;
 		this.init();
 	};
 
-	dojo.extend(dojox.encoding.compression.lzw.Decoder, {
+	lang.extend(lzw.Decoder, {
 		init: function(){
 			this.codes = new Array(this.size);
 			for(var i = 0; i < this.size; ++i){
@@ -85,8 +90,6 @@ dojo.getObject("encoding.compression.lzw", true, dojox);
 			return v;
 		}
 	});
-})();
-
 
-return dojox.encoding.compression.lzw;
+	return lzw;
 });
diff --git a/dojox/encoding/compression/splay.js b/dojox/encoding/compression/splay.js
index 29c9d29..f59140f 100644
--- a/dojox/encoding/compression/splay.js
+++ b/dojox/encoding/compression/splay.js
@@ -1,65 +1,70 @@
-// AMD-ID "dojox/encoding/compression/splay"
-define(["dojo", "dojox", "dojox/encoding/bits"], function(dojo, dojox) {
-dojo.getObject("encoding.compression.splay", true, dojox);
+define([
+	"dojo/_base/lang",	// dojo.extend
+	"../bits"
+], function(lang, bits) {
+	var compression = lang.getObject("dojox.encoding.compression", true);
+	/*=====
+		compression = dojox.encoding.compression;
+	=====*/
 
-dojox.encoding.compression.Splay = function(n){
-	this.up = new Array(2 * n + 1);
-	this.left = new Array(n);
-	this.right = new Array(n);
-	this.reset();
-};
+	compression.Splay = function(n){
+		this.up = new Array(2 * n + 1);
+		this.left = new Array(n);
+		this.right = new Array(n);
+		this.reset();
+	};
 
-dojo.extend(dojox.encoding.compression.Splay, {
-	reset: function(){
-		for(var i = 1; i < this.up.length; this.up[i] = Math.floor((i - 1) / 2), ++i);
-		for(var i = 0; i < this.left.length; this.left[i] = 2 * i + 1, this.right[i] = 2 * i + 2, ++i);
-	},
-	splay: function(i){
-		var a = i + this.left.length;
-		do{
-			var c = this.up[a];
-			if(c){	// root
-				// rotated pair
-				var d = this.up[c];
-				// swap descendants
-				var b = this.left[d];
-				if(c == b){
-					b = this.right[d];
-					this.right[d] = a;
-				} else {
-					this.left[d] = a;
+	lang.extend(compression.Splay, {
+		reset: function(){
+			for(var i = 1; i < this.up.length; this.up[i] = Math.floor((i - 1) / 2), ++i);
+			for(var i = 0; i < this.left.length; this.left[i] = 2 * i + 1, this.right[i] = 2 * i + 2, ++i);
+		},
+		splay: function(i){
+			var a = i + this.left.length;
+			do{
+				var c = this.up[a];
+				if(c){	// root
+					// rotated pair
+					var d = this.up[c];
+					// swap descendants
+					var b = this.left[d];
+					if(c == b){
+						b = this.right[d];
+						this.right[d] = a;
+					} else {
+						this.left[d] = a;
+					}
+					this[a == this.left[c] ? "left" : "right"][c] = b;
+					this.up[a] = d;
+					this.up[b] = c;
+					a = d;
+				}else{
+					a = c;
 				}
-				this[a == this.left[c] ? "left" : "right"][c] = b;
-				this.up[a] = d;
-				this.up[b] = c;
-				a = d;
-			}else{
-				a = c;
-			}
-		}while(a);	// root
-	},
-	encode: function(value, stream){
-		var s = [], a = value + this.left.length;
-		do{
-			s.push(this.right[this.up[a]] == a);
-			a = this.up[a];
-		}while(a);	// root
-		this.splay(value);
-		var l = s.length;
-		while(s.length){ stream.putBits(s.pop() ? 1 : 0, 1); }
-		return	l;
-	},
-	decode: function(stream){
-		var a = 0;	// root;
-		do{
-			a = this[stream.getBits(1) ? "right" : "left"][a];
-		}while(a < this.left.length);
-		a -= this.left.length;
-		this.splay(a);
-		return	a;
-	}
-});
+			}while(a);	// root
+		},
+		encode: function(value, stream){
+			var s = [], a = value + this.left.length;
+			do{
+				s.push(this.right[this.up[a]] == a);
+				a = this.up[a];
+			}while(a);	// root
+			this.splay(value);
+			var l = s.length;
+			while(s.length){ stream.putBits(s.pop() ? 1 : 0, 1); }
+			return	l;
+		},
+		decode: function(stream){
+			var a = 0;	// root;
+			do{
+				a = this[stream.getBits(1) ? "right" : "left"][a];
+			}while(a < this.left.length);
+			a -= this.left.length;
+			this.splay(a);
+			return	a;
+		}
+	});
 
 
-return dojox.encoding.compression.splay;
+	return compression.Splay;
 });
diff --git a/dojox/encoding/crypto/Blowfish.js b/dojox/encoding/crypto/Blowfish.js
index 3b381b7..2af5986 100644
--- a/dojox/encoding/crypto/Blowfish.js
+++ b/dojox/encoding/crypto/Blowfish.js
@@ -1,13 +1,19 @@
-// AMD-ID "dojox/encoding/crypto/Blowfish"
-define(["dojo", "dojox", "dojox/encoding/base64", "dojox/encoding/crypto/_base"], function(dojo, dojox) {
-dojo.getObject("encoding.crypto.Blowfish", true, dojox);
+define([
+	"dojo/_base/lang",	// dojo.isString
+	"dojo/_base/array",	// dojo.map
+	"../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/)
  *	Unsigned math based on Paul Johnstone and Peter Wood patches.
  *	2005-12-08
  */
-dojox.encoding.crypto.Blowfish = new function(){
+crypto.Blowfish = new function(){
 	//	summary
 	//	Object for doing Blowfish encryption/decryption.
 	var POW2=Math.pow(2,2);
@@ -233,8 +239,8 @@ dojox.encoding.crypto.Blowfish = new function(){
 	//	but we should be more secure this way.
 	function init(key){
 		var k=key;
-		if(dojo.isString(k)){
-			k = dojo.map(k.split(""), function(item){
+		if(lang.isString(k)){
+			k = arrayUtil.map(k.split(""), function(item){
 				return item.charCodeAt(0) & 0xff;
 			});
 		}
@@ -242,7 +248,7 @@ dojox.encoding.crypto.Blowfish = new function(){
 		//	init the boxes
 		var pos=0, data=0, res={ left:0, right:0 }, i, j, l;
 		var box = {
-			p: dojo.map(boxes.p.slice(0), function(item){
+			p: arrayUtil.map(boxes.p.slice(0), function(item){
 				var l=k.length, j;
 				for(j=0; j<4; j++){ data=(data*POW8)|k[pos++ % l]; }
 				return (((item>>0x10)^(data>>0x10))<<0x10)|(((item&0xffff)^(data&0xffff))&0xffff);
@@ -273,21 +279,21 @@ dojox.encoding.crypto.Blowfish = new function(){
 	this.getIV=function(/* dojox.encoding.crypto.outputTypes? */ outputType){
 		//	summary
 		//	returns the initialization vector in the output format specified by outputType
-		var out=outputType||dojox.encoding.crypto.outputTypes.Base64;
+		var out=outputType||crypto.outputTypes.Base64;
 		switch(out){
-			case dojox.encoding.crypto.outputTypes.Hex:{
-				return dojo.map(iv, function(item){
+			case crypto.outputTypes.Hex:{
+				return arrayUtil.map(iv, function(item){
 					return (item<=0xf?'0':'')+item.toString(16);
 				}).join("");			//	string
 			}
-			case dojox.encoding.crypto.outputTypes.String:{
+			case crypto.outputTypes.String:{
 				return iv.join("");		//	string
 			}
-			case dojox.encoding.crypto.outputTypes.Raw:{
+			case crypto.outputTypes.Raw:{
 				return iv;				//	array
 			}
 			default:{
-				return dojox.encoding.base64.encode(iv); 	//	 string
+				return base64.encode(iv); 	//	 string
 			}
 		}
 	};
@@ -295,28 +301,28 @@ dojox.encoding.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)
-		var ip=inputType||dojox.encoding.crypto.outputTypes.Base64;
+		var ip=inputType||crypto.outputTypes.Base64;
 		var ba=null;
 		switch(ip){
-			case dojox.encoding.crypto.outputTypes.String:{
-				ba = dojo.map(data.split(""), function(item){
+			case crypto.outputTypes.String:{
+				ba = arrayUtil.map(data.split(""), function(item){
 					return item.charCodeAt(0);
 				});
 				break;
 			}
-			case dojox.encoding.crypto.outputTypes.Hex:{
+			case crypto.outputTypes.Hex:{
 				ba=[];
 				for(var i=0, l=data.length-1; i<l; i+=2){
 					ba.push(parseInt(data.substr(i,2), 16));
 				}
 				break;
 			}
-			case dojox.encoding.crypto.outputTypes.Raw:{
+			case crypto.outputTypes.Raw:{
 				ba=data;
 				break;
 			}
 			default:{
-				ba=dojox.encoding.base64.decode(data);
+				ba=base64.decode(data);
 				break;
 			}
 		}
@@ -329,8 +335,8 @@ dojox.encoding.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"
-		var out=dojox.encoding.crypto.outputTypes.Base64;
-		var mode=dojox.encoding.crypto.cipherModes.ECB;
+		var out=crypto.outputTypes.Base64;
+		var mode=crypto.cipherModes.ECB;
 		if (ao){
 			if (ao.outputType) out=ao.outputType;
 			if (ao.cipherMode) mode=ao.cipherMode;
@@ -339,7 +345,7 @@ dojox.encoding.crypto.Blowfish = new function(){
 		var bx = init(key), padding = 8-(plaintext.length&7);
 		for (var i=0; i<padding; i++){ plaintext+=String.fromCharCode(padding); }
 
-		var cipher=[], count=plaintext.length >> 3, pos=0, o={}, isCBC=(mode==dojox.encoding.crypto.cipherModes.CBC);
+		var cipher=[], count=plaintext.length >> 3, pos=0, o={}, isCBC=(mode==crypto.cipherModes.CBC);
 		var vector={left:iv.left||null, right:iv.right||null};
 		for(var i=0; i<count; i++){
 			o.left=plaintext.charCodeAt(pos)*POW24
@@ -375,19 +381,19 @@ dojox.encoding.crypto.Blowfish = new function(){
 		}
 
 		switch(out){
-			case dojox.encoding.crypto.outputTypes.Hex:{
-				return dojo.map(cipher, function(item){
+			case crypto.outputTypes.Hex:{
+				return arrayUtil.map(cipher, function(item){
 					return (item<=0xf?'0':'')+item.toString(16);
 				}).join("");	//	string
 			}
-			case dojox.encoding.crypto.outputTypes.String:{
+			case crypto.outputTypes.String:{
 				return cipher.join("");	//	string
 			}
-			case dojox.encoding.crypto.outputTypes.Raw:{
+			case crypto.outputTypes.Raw:{
 				return cipher;	//	array
 			}
 			default:{
-				return dojox.encoding.base64.encode(cipher);	//	string
+				return base64.encode(cipher);	//	string
 			}
 		}
 	};
@@ -395,8 +401,8 @@ dojox.encoding.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.
-		var ip=dojox.encoding.crypto.outputTypes.Base64;
-		var mode=dojox.encoding.crypto.cipherModes.ECB;
+		var ip=crypto.outputTypes.Base64;
+		var mode=crypto.cipherModes.ECB;
 		if (ao){
 			if (ao.outputType) ip=ao.outputType;
 			if (ao.cipherMode) mode=ao.cipherMode;
@@ -406,30 +412,30 @@ dojox.encoding.crypto.Blowfish = new function(){
 
 		var c=null;
 		switch(ip){
-			case dojox.encoding.crypto.outputTypes.Hex:{
+			case crypto.outputTypes.Hex:{
 				c = [];
 				for(var i=0, l=ciphertext.length-1; i<l; i+=2){
 					c.push(parseInt(ciphertext.substr(i,2), 16));
 				}
 				break;
 			}
-			case dojox.encoding.crypto.outputTypes.String:{
-				c = dojo.map(ciphertext.split(""), function(item){
+			case crypto.outputTypes.String:{
+				c = arrayUtil.map(ciphertext.split(""), function(item){
 					return item.charCodeAt(0);
 				});
 				break;
 			}
-			case dojox.encoding.crypto.outputTypes.Raw:{
+			case crypto.outputTypes.Raw:{
 				c=ciphertext;	//	should be a byte array
 				break;
 			}
 			default:{
-				c=dojox.encoding.base64.decode(ciphertext);
+				c=base64.decode(ciphertext);
 				break;
 			}
 		}
 
-		var count=c.length >> 3, pos=0, o={}, isCBC=(mode==dojox.encoding.crypto.cipherModes.CBC);
+		var count=c.length >> 3, pos=0, o={}, isCBC=(mode==crypto.cipherModes.CBC);
 		var vector={left:iv.left||null, right:iv.right||null};
 		for(var i=0; i<count; i++){
 			o.left=c[pos]*POW24|c[pos+1]*POW16|c[pos+2]*POW8|c[pos+3];
@@ -467,14 +473,14 @@ dojox.encoding.crypto.Blowfish = new function(){
 		}
 
 		//	convert to string
-		return dojo.map(pt, function(item){
+		return arrayUtil.map(pt, function(item){
 			return String.fromCharCode(item);
 		}).join("");	//	string
 	};
 
-	this.setIV("0000000000000000", dojox.encoding.crypto.outputTypes.Hex);
+	this.setIV("0000000000000000", crypto.outputTypes.Hex);
 }();
 
 
-return dojox.encoding.crypto.Blowfish;
+return crypto.Blowfish;
 });
diff --git a/dojox/encoding/crypto/RSAKey-ext.js b/dojox/encoding/crypto/RSAKey-ext.js
index 607eef5..b029d91 100644
--- a/dojox/encoding/crypto/RSAKey-ext.js
+++ b/dojox/encoding/crypto/RSAKey-ext.js
@@ -1,11 +1,11 @@
-// AMD-ID "dojox/encoding/crypto/RSAKey-ext"
-define(["dojo", "dojox", "dojox/encoding/crypto/RSAKey", "dojox/math/BigInteger-ext"], function(dojo, dojox) {
+define([
+	"dojo/_base/kernel", // dojo.experimental
+	"dojo/_base/lang", // dojo.extend
+	"./RSAKey",
+	"../../math/BigInteger-ext"
+], function(kernel, lang, RSAKey, BigInteger) {
 
-dojo.experimental("dojox.encoding.crypto.RSAKey-ext");
-
-
-(function(){
-	var BigInteger = dojox.math.BigInteger;
+	kernel.experimental("dojox.encoding.crypto.RSAKey-ext");
 
 	// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
 	function pkcs1unpad2(d, n){
@@ -26,7 +26,7 @@ dojo.experimental("dojox.encoding.crypto.RSAKey-ext");
 		return ret;
 	}
 
-	dojo.extend(dojox.encoding.crypto.RSAKey, {
+	lang.extend(RSAKey, {
 		setPrivate: function(N, E, D){
 			// summary:
 			//	Set the private key fields N, e, d and CRT params from hex strings
@@ -117,8 +117,6 @@ dojo.experimental("dojox.encoding.crypto.RSAKey-ext");
 			return pkcs1unpad2(m, (this.n.bitLength() + 7) >> 3);
 		}
 	});
-})();
-
-
-return dojox.encoding.crypto.RSAKey;
+	
+	return RSAKey;
 });
diff --git a/dojox/encoding/crypto/RSAKey.js b/dojox/encoding/crypto/RSAKey.js
index 626cb31..2bf5459 100644
--- a/dojox/encoding/crypto/RSAKey.js
+++ b/dojox/encoding/crypto/RSAKey.js
@@ -1,16 +1,17 @@
-// AMD-ID "dojox/encoding/crypto/RSAKey"
-define(["dojo", "dojox", "dojox/math/BigInteger", "dojox/math/random/Simple"], function(dojo, dojox) {
-
-dojo.experimental("dojox.encoding.crypto.RSAKey");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"../../math/BigInteger",
+	"../../math/random/Simple"
+], function(kernel, declare, BigInteger, Simple) {
 
+	kernel.experimental("dojox.encoding.crypto.RSAKey");
 
 // Copyright (c) 2005  Tom Wu
 // All Rights Reserved.
 // See "LICENSE-BigInteger" in dojox.math for details.
 
-(function(){
-	var dm = dojox.math, BigInteger = dm.BigInteger, Simple = dm.random.Simple,
-		defaultRngf = function(){ return new Simple(); };
+	var defaultRngf = function(){ return new Simple(); };
 
 	// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
 	function pkcs1pad2(s, n, rngf) {
@@ -34,7 +35,7 @@ dojo.experimental("dojox.encoding.crypto.RSAKey");
 		return new BigInteger(ba);
 	}
 
-	dojo.declare("dojox.encoding.crypto.RSAKey", null, {
+	return declare("dojox.encoding.crypto.RSAKey", null, {
 		constructor: function(rngf){
 			// summary:
 			//	"empty" RSA key constructor
@@ -70,8 +71,4 @@ dojo.experimental("dojox.encoding.crypto.RSAKey");
 			return h.length % 2 ? "0" + h : h;
 		}
 	});
-})();
-
-
-return dojox.encoding.crypto.RSAKey;
 });
diff --git a/dojox/encoding/crypto/SimpleAES.js b/dojox/encoding/crypto/SimpleAES.js
index 03e1fac..35ce3e1 100644
--- a/dojox/encoding/crypto/SimpleAES.js
+++ b/dojox/encoding/crypto/SimpleAES.js
@@ -1,303 +1,305 @@
-// AMD-ID "dojox/encoding/crypto/SimpleAES"
-define(["dojo", "dojox", "dojox/encoding/base64", "dojox/encoding/crypto/_base"], function(dojo, dojox) {
-dojo.getObject("encoding.crypto.SimpleAES", true, dojox);
-
-(function(){
-		// 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,
-					 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
-					 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
-					 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
-					 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
-					 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
-					 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
-					 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
-					 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
-					 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
-					 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
-					 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
-					 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]
-		var Rcon = [ [0x00, 0x00, 0x00, 0x00],
-					 [0x01, 0x00, 0x00, 0x00],
-					 [0x02, 0x00, 0x00, 0x00],
-					 [0x04, 0x00, 0x00, 0x00],
-					 [0x08, 0x00, 0x00, 0x00],
-					 [0x10, 0x00, 0x00, 0x00],
-					 [0x20, 0x00, 0x00, 0x00],
-					 [0x40, 0x00, 0x00, 0x00],
-					 [0x80, 0x00, 0x00, 0x00],
-					 [0x1b, 0x00, 0x00, 0x00],
-					 [0x36, 0x00, 0x00, 0x00] ];
-
-		/*
-		 * AES Cipher function: encrypt 'input' with Rijndael algorithm
-		 *
-		 *	 takes	 byte-array 'input' (16 bytes)
-		 *			 2D byte-array key schedule 'w' (Nr+1 x Nb bytes)
-		 *
-		 *	 applies Nr rounds (10/12/14) using key schedule w for 'add round key' stage
-		 *
-		 *	 returns byte-array encrypted value (16 bytes)
-		 */
-		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]
-		  for (var i=0; i<4*Nb; i++) state[i%4][Math.floor(i/4)] = input[i];
-
-		  state = AddRoundKey(state, w, 0, Nb);
-
-		  for (var round=1; round<Nr; round++) {
-			state = SubBytes(state, Nb);
-			state = ShiftRows(state, Nb);
-			state = MixColumns(state, Nb);
-			state = AddRoundKey(state, w, round, Nb);
-		  }
-
-		  state = SubBytes(state, Nb);
-		  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]
-		  for (var i=0; i<4*Nb; i++) output[i] = state[i%4][Math.floor(i/4)];
-		  return output;
+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]
+	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,
+				 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
+				 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
+				 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
+				 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
+				 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
+				 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
+				 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
+				 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
+				 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
+				 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
+				 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
+				 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]
+	var Rcon = [ [0x00, 0x00, 0x00, 0x00],
+				 [0x01, 0x00, 0x00, 0x00],
+				 [0x02, 0x00, 0x00, 0x00],
+				 [0x04, 0x00, 0x00, 0x00],
+				 [0x08, 0x00, 0x00, 0x00],
+				 [0x10, 0x00, 0x00, 0x00],
+				 [0x20, 0x00, 0x00, 0x00],
+				 [0x40, 0x00, 0x00, 0x00],
+				 [0x80, 0x00, 0x00, 0x00],
+				 [0x1b, 0x00, 0x00, 0x00],
+				 [0x36, 0x00, 0x00, 0x00] ];
+
+	/*
+	 * AES Cipher function: encrypt 'input' with Rijndael algorithm
+	 *
+	 *	 takes	 byte-array 'input' (16 bytes)
+	 *			 2D byte-array key schedule 'w' (Nr+1 x Nb bytes)
+	 *
+	 *	 applies Nr rounds (10/12/14) using key schedule w for 'add round key' stage
+	 *
+	 *	 returns byte-array encrypted value (16 bytes)
+	 */
+	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]
+	  for (var i=0; i<4*Nb; i++) state[i%4][Math.floor(i/4)] = input[i];
+
+	  state = AddRoundKey(state, w, 0, Nb);
+
+	  for (var round=1; round<Nr; round++) {
+		state = SubBytes(state, Nb);
+		state = ShiftRows(state, Nb);
+		state = MixColumns(state, Nb);
+		state = AddRoundKey(state, w, round, Nb);
+	  }
+
+	  state = SubBytes(state, Nb);
+	  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]
+	  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]
+	  for (var r=0; r<4; r++) {
+		for (var c=0; c<Nb; c++) s[r][c] = Sbox[s[r][c]];
+	  }
+	  return s;
+	}
+
+
+	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
+		for (var c=0; c<4; c++) s[r][c] = t[c];			// and copy back
+	  }			 // note that this will work for Nb=4,5,6, but not 7,8 (always 4 for AES):
+	  return s;	 // see fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.311.pdf
+	}
+
+
+	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)
+		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;
 		}
-
-
-		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]];
-		  }
-		  return s;
-		}
-
-
-		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
-			for (var c=0; c<4; c++) s[r][c] = t[c];			// and copy back
-		  }			 // note that this will work for Nb=4,5,6, but not 7,8 (always 4 for AES):
-		  return s;	 // see fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.311.pdf
-		}
-
-
-		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)
-			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)
-			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
-			s[3][c] = a[0] ^ b[0] ^ a[1] ^ a[2] ^ b[3]; // 3*a0 + a1 + a2 + 2*a3
-		  }
-		  return s;
-		}
-
-
-		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];
-		  }
-		  return state;
+		// 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
+		s[3][c] = a[0] ^ b[0] ^ a[1] ^ a[2] ^ b[3]; // 3*a0 + a1 + a2 + 2*a3
+	  }
+	  return s;
+	}
+
+
+	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];
+	  }
+	  return state;
+	}
+
+
+	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
+
+	  var w = new Array(Nb*(Nr+1));
+	  var temp = new Array(4);
+
+	  for (var i=0; i<Nk; i++) {
+		var r = [key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]];
+		w[i] = r;
+	  }
+
+	  for (var i=Nk; i<(Nb*(Nr+1)); i++) {
+		w[i] = new Array(4);
+		for (var t=0; t<4; t++) temp[t] = w[i-1][t];
+		if (i % Nk == 0) {
+		  temp = SubWord(RotWord(temp));
+		  for (var t=0; t<4; t++) temp[t] ^= Rcon[i/Nk][t];
+		} else if (Nk > 6 && i%Nk == 4) {
+		  temp = SubWord(temp);
 		}
-
-
-		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
-
-		  var w = new Array(Nb*(Nr+1));
-		  var temp = new Array(4);
-
-		  for (var i=0; i<Nk; i++) {
-			var r = [key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]];
-			w[i] = r;
-		  }
-
-		  for (var i=Nk; i<(Nb*(Nr+1)); i++) {
-			w[i] = new Array(4);
-			for (var t=0; t<4; t++) temp[t] = w[i-1][t];
-			if (i % Nk == 0) {
-			  temp = SubWord(RotWord(temp));
-			  for (var t=0; t<4; t++) temp[t] ^= Rcon[i/Nk][t];
-			} else if (Nk > 6 && i%Nk == 4) {
-			  temp = SubWord(temp);
-			}
-			for (var t=0; t<4; t++) w[i][t] = w[i-Nk][t] ^ temp[t];
-		  }
-
-		  return w;
+		for (var t=0; t<4; t++) w[i][t] = w[i-Nk][t] ^ temp[t];
+	  }
+
+	  return w;
+	}
+
+	function SubWord(w) {	 // apply SBox to 4-byte word w
+	  for (var i=0; i<4; i++) w[i] = Sbox[w[i]];
+	  return w;
+	}
+
+	function RotWord(w) {	 // rotate 4-byte word w left by one byte
+	  w[4] = w[0];
+	  for (var i=0; i<4; i++) w[i] = w[i+1];
+	  return w;
+	}
+
+	/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
+
+	/*
+	 * Use AES to encrypt 'plaintext' with 'password' using 'nBits' key, in 'Counter' mode of operation
+	 *							 - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+	 *	 for each block
+	 *	 - outputblock = cipher(counter, key)
+	 *	 - cipherblock = plaintext xor outputblock
+	 */
+	function AESEncryptCtr(plaintext, password, nBits) {
+	  if (!(nBits==128 || nBits==192 || nBits==256)) return '';	 // standard allows 128/192/256 bit keys
+
+	  // for this example script, generate the key by applying Cipher to 1st 16/24/32 chars of password;
+	  // for real-world applications, a more secure approach would be to hash the password e.g. with SHA-1
+	  var nBytes = nBits/8;	 // no bytes in key
+	  var pwBytes = new Array(nBytes);
+	  for (var i=0; i<nBytes; i++) pwBytes[i] = password.charCodeAt(i) & 0xff;
+
+	  var key = Cipher(pwBytes, KeyExpansion(pwBytes));
+
+	  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,
+	  // 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
+	  var nonce = (new Date()).getTime();  // milliseconds since 1-Jan-1970
+
+	  // encode nonce in two stages to cater for JavaScript 32-bit limit on bitwise ops
+	  for (var i=0; i<4; i++) counterBlock[i] = (nonce >>> i*8) & 0xff;
+	  for (var i=0; i<4; i++) counterBlock[i+4] = (nonce/0x100000000 >>> i*8) & 0xff;
+
+	  // generate key schedule - an expansion of the key into distinct Key Rounds for each round
+	  var keySchedule = KeyExpansion(key);
+
+	  var blockCount = Math.ceil(plaintext.length/blockSize);
+	  var ciphertext = new Array(blockCount);  // ciphertext as array of strings
+
+	  for (var b=0; b<blockCount; b++) {
+		// set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
+		// again done in two stages for 32-bit ops
+		for (var c=0; c<4; c++) counterBlock[15-c] = (b >>> c*8) & 0xff;
+		for (var c=0; c<4; c++) counterBlock[15-c-4] = (b/0x100000000 >>> c*8)
+
+		var cipherCntr = Cipher(counterBlock, keySchedule);	 // -- encrypt counter block --
+
+		// calculate length of final block:
+		var blockLength = b<blockCount-1 ? blockSize : (plaintext.length-1)%blockSize+1;
+
+		var ct = '';
+		for (var i=0; i<blockLength; i++) {	 // -- xor plaintext with ciphered counter byte-by-byte --
+		  var plaintextByte = plaintext.charCodeAt(b*blockSize+i);
+		  var cipherByte = plaintextByte ^ cipherCntr[i];
+		  //ct += String.fromCharCode(cipherByte);
+		  ct += ((cipherByte < 16) ? "0" : "") + cipherByte.toString(16);
 		}
-
-		function SubWord(w) {	 // apply SBox to 4-byte word w
-		  for (var i=0; i<4; i++) w[i] = Sbox[w[i]];
-		  return w;
+		// ct is now ciphertext for this block
+
+		ciphertext[b] = ct; // escCtrlChars(ct);  // escape troublesome characters in ciphertext
+	  }
+
+	  // convert the nonce to a string to go on the front of the ciphertext
+	  var ctrTxt = '';
+	  for (var i=0; i<8; i++) ctrTxt += ((counterBlock[i] < 16) ? "0" : "") + counterBlock[i].toString(16); //String.fromCharCode(counterBlock[i]);
+	  //ctrTxt = escCtrlChars(ctrTxt);
+
+	  // use '-' to separate blocks, use Array.join to concatenate arrays of strings for efficiency
+	  return ctrTxt + ' ' + ciphertext.join(' ');
+	}
+
+	function stringToHex(s){
+		var ret = [];
+		s.replace(/(..)/g, function(str){
+			ret.push(parseInt(str, 16));
+		});
+		return ret;
+	}
+
+	/*
+	 * Use AES to decrypt 'ciphertext' with 'password' using 'nBits' key, in Counter mode of operation
+	 *
+	 *	 for each block
+	 *	 - outputblock = cipher(counter, key)
+	 *	 - cipherblock = plaintext xor outputblock
+	 */
+	function AESDecryptCtr(ciphertext, password, nBits) {
+	  if (!(nBits==128 || nBits==192 || nBits==256)) return '';	 // standard allows 128/192/256 bit keys
+
+	  var nBytes = nBits/8;	 // no bytes in key
+	  var pwBytes = new Array(nBytes);
+	  for (var i=0; i<nBytes; i++) pwBytes[i] = password.charCodeAt(i) & 0xff;
+	  var pwKeySchedule = KeyExpansion(pwBytes);
+	  var key = Cipher(pwBytes, pwKeySchedule);
+	  key = key.concat(key.slice(0, nBytes-16));  // key is now 16/24/32 bytes long
+
+	  var keySchedule = KeyExpansion(key);
+
+	  ciphertext = ciphertext.split(' ');  // split ciphertext into array of block-length strings
+
+	  // recover nonce from 1st element of ciphertext
+	  var blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
+	  var counterBlock = new Array(blockSize);
+	  var ctrTxt = ciphertext[0]; //unescCtrlChars(ciphertext[0]);
+	  counterBlock = stringToHex(ctrTxt);
+
+	  var plaintext = new Array(ciphertext.length-1);
+
+	  for (var b=1; b<ciphertext.length; b++) {
+		// set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
+		for (var c=0; c<4; c++) counterBlock[15-c] = ((b-1) >>> c*8) & 0xff;
+		for (var c=0; c<4; c++) counterBlock[15-c-4] = ((b/0x100000000-1) >>> c*8) & 0xff;
+
+		var cipherCntr = Cipher(counterBlock, keySchedule);	 // encrypt counter block
+
+		//ciphertext[b] = ciphertext[b]; //unescCtrlChars(ciphertext[b]);
+
+		var pt = '';
+		var tmp = stringToHex(ciphertext[b]);
+		for (var i=0; i<tmp.length; i++) {
+		  // -- xor plaintext with ciphered counter byte-by-byte --
+		  var ciphertextByte = ciphertext[b].charCodeAt(i);
+		  var plaintextByte = tmp[i] ^ cipherCntr[i];
+		  pt += String.fromCharCode(plaintextByte);
 		}
+		// pt is now plaintext for this block
 
-		function RotWord(w) {	 // rotate 4-byte word w left by one byte
-		  w[4] = w[0];
-		  for (var i=0; i<4; i++) w[i] = w[i+1];
-		  return w;
-		}
+		plaintext[b-1] = pt;  // b-1 'cos no initial nonce block in plaintext
+	  }
 
-		/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
-
-		/*
-		 * Use AES to encrypt 'plaintext' with 'password' using 'nBits' key, in 'Counter' mode of operation
-		 *							 - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
-		 *	 for each block
-		 *	 - outputblock = cipher(counter, key)
-		 *	 - cipherblock = plaintext xor outputblock
-		 */
-		function AESEncryptCtr(plaintext, password, nBits) {
-		  if (!(nBits==128 || nBits==192 || nBits==256)) return '';	 // standard allows 128/192/256 bit keys
-
-		  // for this example script, generate the key by applying Cipher to 1st 16/24/32 chars of password;
-		  // for real-world applications, a more secure approach would be to hash the password e.g. with SHA-1
-		  var nBytes = nBits/8;	 // no bytes in key
-		  var pwBytes = new Array(nBytes);
-		  for (var i=0; i<nBytes; i++) pwBytes[i] = password.charCodeAt(i) & 0xff;
-
-		  var key = Cipher(pwBytes, KeyExpansion(pwBytes));
-
-		  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,
-		  // 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
-		  var nonce = (new Date()).getTime();  // milliseconds since 1-Jan-1970
-
-		  // encode nonce in two stages to cater for JavaScript 32-bit limit on bitwise ops
-		  for (var i=0; i<4; i++) counterBlock[i] = (nonce >>> i*8) & 0xff;
-		  for (var i=0; i<4; i++) counterBlock[i+4] = (nonce/0x100000000 >>> i*8) & 0xff;
-
-		  // generate key schedule - an expansion of the key into distinct Key Rounds for each round
-		  var keySchedule = KeyExpansion(key);
-
-		  var blockCount = Math.ceil(plaintext.length/blockSize);
-		  var ciphertext = new Array(blockCount);  // ciphertext as array of strings
-
-		  for (var b=0; b<blockCount; b++) {
-			// set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
-			// again done in two stages for 32-bit ops
-			for (var c=0; c<4; c++) counterBlock[15-c] = (b >>> c*8) & 0xff;
-			for (var c=0; c<4; c++) counterBlock[15-c-4] = (b/0x100000000 >>> c*8)
-
-			var cipherCntr = Cipher(counterBlock, keySchedule);	 // -- encrypt counter block --
-
-			// calculate length of final block:
-			var blockLength = b<blockCount-1 ? blockSize : (plaintext.length-1)%blockSize+1;
-
-			var ct = '';
-			for (var i=0; i<blockLength; i++) {	 // -- xor plaintext with ciphered counter byte-by-byte --
-			  var plaintextByte = plaintext.charCodeAt(b*blockSize+i);
-			  var cipherByte = plaintextByte ^ cipherCntr[i];
-			  //ct += String.fromCharCode(cipherByte);
-			  ct += ((cipherByte < 16) ? "0" : "") + cipherByte.toString(16);
-			}
-			// ct is now ciphertext for this block
-
-			ciphertext[b] = ct; // escCtrlChars(ct);  // escape troublesome characters in ciphertext
-		  }
-
-		  // convert the nonce to a string to go on the front of the ciphertext
-		  var ctrTxt = '';
-		  for (var i=0; i<8; i++) ctrTxt += ((counterBlock[i] < 16) ? "0" : "") + counterBlock[i].toString(16); //String.fromCharCode(counterBlock[i]);
-		  //ctrTxt = escCtrlChars(ctrTxt);
-
-		  // use '-' to separate blocks, use Array.join to concatenate arrays of strings for efficiency
-		  return ctrTxt + ' ' + ciphertext.join(' ');
-		}
+	  return plaintext.join('');
+	}
 
-		function stringToHex(s){
-			var ret = [];
-			s.replace(/(..)/g, function(str){
-				ret.push(parseInt(str, 16));
-			});
-			return ret;
-		}
+	/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
 
-		/*
-		 * Use AES to decrypt 'ciphertext' with 'password' using 'nBits' key, in Counter mode of operation
-		 *
-		 *	 for each block
-		 *	 - outputblock = cipher(counter, key)
-		 *	 - cipherblock = plaintext xor outputblock
-		 */
-		function AESDecryptCtr(ciphertext, password, nBits) {
-		  if (!(nBits==128 || nBits==192 || nBits==256)) return '';	 // standard allows 128/192/256 bit keys
-
-		  var nBytes = nBits/8;	 // no bytes in key
-		  var pwBytes = new Array(nBytes);
-		  for (var i=0; i<nBytes; i++) pwBytes[i] = password.charCodeAt(i) & 0xff;
-		  var pwKeySchedule = KeyExpansion(pwBytes);
-		  var key = Cipher(pwBytes, pwKeySchedule);
-		  key = key.concat(key.slice(0, nBytes-16));  // key is now 16/24/32 bytes long
-
-		  var keySchedule = KeyExpansion(key);
-
-		  ciphertext = ciphertext.split(' ');  // split ciphertext into array of block-length strings
-
-		  // recover nonce from 1st element of ciphertext
-		  var blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
-		  var counterBlock = new Array(blockSize);
-		  var ctrTxt = ciphertext[0]; //unescCtrlChars(ciphertext[0]);
-		  counterBlock = stringToHex(ctrTxt);
-
-		  var plaintext = new Array(ciphertext.length-1);
-
-		  for (var b=1; b<ciphertext.length; b++) {
-			// set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
-			for (var c=0; c<4; c++) counterBlock[15-c] = ((b-1) >>> c*8) & 0xff;
-			for (var c=0; c<4; c++) counterBlock[15-c-4] = ((b/0x100000000-1) >>> c*8) & 0xff;
-
-			var cipherCntr = Cipher(counterBlock, keySchedule);	 // encrypt counter block
-
-			//ciphertext[b] = ciphertext[b]; //unescCtrlChars(ciphertext[b]);
-
-			var pt = '';
-			var tmp = stringToHex(ciphertext[b]);
-			for (var i=0; i<tmp.length; i++) {
-			  // -- xor plaintext with ciphered counter byte-by-byte --
-			  var ciphertextByte = ciphertext[b].charCodeAt(i);
-			  var plaintextByte = tmp[i] ^ cipherCntr[i];
-			  pt += String.fromCharCode(plaintextByte);
-			}
-			// pt is now plaintext for this block
-
-			plaintext[b-1] = pt;  // b-1 'cos no initial nonce block in plaintext
-		  }
-
-		  return plaintext.join('');
-		}
-
-		/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
+	function escCtrlChars(str) {  // escape control chars which might cause problems handling ciphertext
+	  return str.replace(/[\0\t\n\v\f\r\xa0!-]/g, function(c) { return '!' + c.charCodeAt(0) + '!'; });
+	}  // \xa0 to cater for bug in Firefox; include '-' to leave it free for use as a block marker
 
-		function escCtrlChars(str) {  // escape control chars which might cause problems handling ciphertext
-		  return str.replace(/[\0\t\n\v\f\r\xa0!-]/g, function(c) { return '!' + c.charCodeAt(0) + '!'; });
-		}  // \xa0 to cater for bug in Firefox; include '-' to leave it free for use as a block marker
+	function unescCtrlChars(str) {	// unescape potentially problematic control characters
+	  return str.replace(/!\d\d?\d?!/g, function(c) { return String.fromCharCode(c.slice(1,-1)); });
+	}
 
-		function unescCtrlChars(str) {	// unescape potentially problematic control characters
-		  return str.replace(/!\d\d?\d?!/g, function(c) { return String.fromCharCode(c.slice(1,-1)); });
-		}
+	/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
 
-		/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
-
-	dojox.encoding.crypto.SimpleAES = new (function(){
+	crypto.SimpleAES = new (function(){
 		// summary:
 		// 		SimpleAES, ported from dojox.sql, and done without the need for
 		// 		a Google Gears worker pool.
@@ -331,8 +333,6 @@ dojo.getObject("encoding.crypto.SimpleAES", true, dojox);
 			return AESDecryptCtr(ciphertext, key, 256);	//	String
 		};
 	})();
-})();
-
 
-return dojox.encoding.crypto.SimpleAES;
+	return crypto.SimpleAES;
 });
diff --git a/dojox/encoding/crypto/_base.js b/dojox/encoding/crypto/_base.js
index 3b8f133..af557a7 100644
--- a/dojox/encoding/crypto/_base.js
+++ b/dojox/encoding/crypto/_base.js
@@ -1,21 +1,20 @@
-// AMD-ID "dojox/encoding/crypto/_base"
-define(["dojo", "dojox"], function(dojo, dojox) {
-dojo.getObject("encoding.crypto", true, dojox);
+define(["dojo/_base/lang"], function(lang) {
+	
+	var c = lang.getObject("dojox.encoding.crypto", true);
+	/*=====
+		c = dojox.encoding.crypto;
+	=====*/
 
-(function(){
-	var c=dojox.encoding.crypto;
-	c.cipherModes={
-		//	summary
+	c.cipherModes = {
+		// summary:
 		//	Enumeration for various cipher modes.
 		ECB:0, CBC:1, PCBC:2, CFB:3, OFB:4, CTR:5
 	};
-	c.outputTypes={
-		//	summary
+	c.outputTypes = {
+		// summary:
 		//	Enumeration for input and output encodings.
 		Base64:0, Hex:1, String:2, Raw:3
 	};
-})();
-
-
-return dojox.encoding.crypto;
+	
+	return c;
 });
diff --git a/dojox/encoding/digests/MD5.js b/dojox/encoding/digests/MD5.js
index b13c7aa..30ca232 100644
--- a/dojox/encoding/digests/MD5.js
+++ b/dojox/encoding/digests/MD5.js
@@ -1,5 +1,8 @@
-// AMD-ID "dojox/encoding/digests/MD5"
-define(["dojo", "dojox", "dojox/encoding/digests/_base"], function(dojo, dojox) {
+define(["./_base"], function(dxd) {
+
+	/*=====
+		dxd = dojox.encoding.digests;
+	=====*/
 
 /*	A port of Paul Johnstone's MD5 implementation
  *	http://pajhome.org.uk/crypt/md5/index.html
@@ -10,8 +13,7 @@ define(["dojo", "dojox", "dojox/encoding/digests/_base"], function(dojo, dojox)
  *
  *	Dojo port by Tom Trenka
  */
-(function(){
-	var dxd=dojox.encoding.digests;
+
 	var chrsz=8;
 
 	//	MD5 rounds functions
@@ -169,8 +171,6 @@ define(["dojo", "dojox", "dojox/encoding/digests/_base"], function(dojo, dojox)
 			}
 		}
 	};
-})();
-
 
-return dojox.encoding.digests.MD5;
+	return dxd.MD5;
 });
diff --git a/dojox/encoding/digests/SHA1.js b/dojox/encoding/digests/SHA1.js
index 7409322..fa18d8a 100644
--- a/dojox/encoding/digests/SHA1.js
+++ b/dojox/encoding/digests/SHA1.js
@@ -1,5 +1,8 @@
-// AMD-ID "dojox/encoding/digests/SHA1"
-define(["dojo", "dojox", "dojox/encoding/digests/_base"], function(dojo, dojox) {
+define(["./_base"], function(dxd) {
+
+	/*=====
+		dxd = dojox.encoding.digests;
+	=====*/
 
 /*
  * A port of Paul Johnstone's SHA1 implementation
@@ -11,8 +14,7 @@ define(["dojo", "dojox", "dojox/encoding/digests/_base"], function(dojo, dojox)
  *
  * Dojo port by Tom Trenka
  */
-(function(){
-	var dxd=dojox.encoding.digests;
+
 	var chrsz=8,	//	change to 16 for unicode.
 		mask=(1<<chrsz)-1;
 
@@ -147,8 +149,6 @@ define(["dojo", "dojox", "dojox/encoding/digests/_base"], function(dojo, dojox)
 			}
 		}
 	};
-})();
-
 
-return dojox.encoding.digests.SHA1;
+	return dxd.SHA1;
 });
diff --git a/dojox/encoding/digests/_base.js b/dojox/encoding/digests/_base.js
index dc14807..1850636 100644
--- a/dojox/encoding/digests/_base.js
+++ b/dojox/encoding/digests/_base.js
@@ -1,11 +1,11 @@
-// AMD-ID "dojox/encoding/digests/_base"
-define(["dojo", "dojox"], function(dojo, dojox) {
-dojo.getObject("encoding.digests", true, dojox);
+define(["dojo/_base/lang"], function(lang){
+	var d = lang.getObject("dojox.encoding.digests", true);
+	/*=====
+		d = dojox.encoding.digests;
+	=====*/
 
-(function(){
 	//TODO: see if it makes sense to meld this into one with the
 	//	crypto base enums
-	var d=dojox.encoding.digests;
 	d.outputTypes={
 		//	summary:
 		//		Enumeration for input and output encodings.
@@ -73,8 +73,6 @@ dojo.getObject("encoding.digests", true, dojox);
 		}
 		return s.join("");	//	string
 	};
-})();
 
-
-return dojox.encoding.digests;
+	return d;
 });
diff --git a/dojox/encoding/easy64.js b/dojox/encoding/easy64.js
index 1f6ddc2..d891d75 100644
--- a/dojox/encoding/easy64.js
+++ b/dojox/encoding/easy64.js
@@ -1,8 +1,9 @@
-// AMD-ID "dojox/encoding/easy64"
-define(["dojo", "dojox"], function(dojo, dojox) {
-dojo.getObject("encoding.easy64", true, dojox);
+define(["dojo/_base/lang"], function(lang) {
+	var easy64 = lang.getObject("dojox.encoding.easy64", true);
+	/*=====
+		easy64 = dojox.encoding.easy64;
+	=====*/
 
-(function(){
 	var c = function(input, length, result){
 		for(var i = 0; i < length; i += 3){
 			result.push(
@@ -14,7 +15,7 @@ dojo.getObject("encoding.easy64", true, dojox);
 		}
 	};
 
-	dojox.encoding.easy64.encode = function(input){
+	easy64.encode = function(input){
 		// 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;
@@ -28,7 +29,7 @@ dojo.getObject("encoding.easy64", true, dojox);
 		return result.join("");	// String
 	};
 
-	dojox.encoding.easy64.decode = function(input){
+	easy64.decode = function(input){
 		// 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;
@@ -45,8 +46,6 @@ dojo.getObject("encoding.easy64", true, dojox);
 		}
 		return r;
 	};
-})();
 
-
-return dojox.encoding.easy64;
+	return easy64;
 });
diff --git a/dojox/encoding/tests/ascii85.js b/dojox/encoding/tests/ascii85.js
index ad05690..2e09961 100644
--- a/dojox/encoding/tests/ascii85.js
+++ b/dojox/encoding/tests/ascii85.js
@@ -1,12 +1,8 @@
-dojo.provide("dojox.encoding.tests.ascii85");
-dojo.require("dojox.encoding.ascii85");
-
-(function(){
+define(['doh', '../ascii85'], function(doh, dca){
 	var msg1 = "The rain in Spain falls mainly on the plain.";
 	var msg2 = "The rain in Spain falls mainly on the plain.1";
 	var msg3 = "The rain in Spain falls mainly on the plain.ab";
 	var msg4 = "The rain in Spain falls mainly on the plain.!@#";
-	var dca = dojox.encoding.ascii85;
 	
 	var s2b = function(s){
 		var b = [];
@@ -22,10 +18,10 @@ dojo.require("dojox.encoding.ascii85");
 		return s.join("");
 	};
 
-	tests.register("dojox.encoding.tests.ascii85", [
+	doh.register("dojox.encoding.tests.ascii85", [
 		function testMsg1(t){ t.assertEqual(msg1, b2s(dca.decode(dca.encode(s2b(msg1))))); },
 		function testMsg2(t){ t.assertEqual(msg2, b2s(dca.decode(dca.encode(s2b(msg2))))); },
 		function testMsg3(t){ t.assertEqual(msg3, b2s(dca.decode(dca.encode(s2b(msg3))))); },
 		function testMsg4(t){ t.assertEqual(msg4, b2s(dca.decode(dca.encode(s2b(msg4))))); }
 	]);
-})();
+});
diff --git a/dojox/encoding/tests/bits.js b/dojox/encoding/tests/bits.js
index 2ae7f59..f1ef686 100644
--- a/dojox/encoding/tests/bits.js
+++ b/dojox/encoding/tests/bits.js
@@ -1,12 +1,8 @@
-dojo.provide("dojox.encoding.tests.bits");
-dojo.require("dojox.encoding.bits");
-
-(function(){
+define(['doh', '../bits'], function(doh, dcb){
 	var msg1 = "The rain in Spain falls mainly on the plain.";
 	var msg2 = "The rain in Spain falls mainly on the plain.1";
 	var msg3 = "The rain in Spain falls mainly on the plain.ab";
 	var msg4 = "The rain in Spain falls mainly on the plain.!@#";
-	var dcb = dojox.encoding.bits;
 	
 	var s2b = function(s){
 		var b = [];
@@ -23,7 +19,7 @@ dojo.require("dojox.encoding.bits");
 	};
 	
 	var testOut = function(msg){
-		var a = new dojox.encoding.bits.OutputStream();
+		var a = new dcb.OutputStream();
 		for(var i = 0; i < msg.length; ++i){
 			var v = msg.charCodeAt(i);
 			var j = Math.floor(Math.random() * 7) + 1;
@@ -34,7 +30,7 @@ dojo.require("dojox.encoding.bits");
 	};
 
 	var testIn = function(msg){
-		var a = new dojox.encoding.bits.InputStream(s2b(msg), msg.length * 8);
+		var a = new dcb.InputStream(s2b(msg), msg.length * 8);
 		var r = [];
 		for(var i = 0; i < msg.length; ++i){
 			var j = Math.floor(Math.random() * 7) + 1;
@@ -44,8 +40,8 @@ dojo.require("dojox.encoding.bits");
 	};
 	
 	var test = function(msg){
-		var a = new dojox.encoding.bits.InputStream(s2b(msg), msg.length * 8);
-		var o = new dojox.encoding.bits.OutputStream();
+		var a = new dcb.InputStream(s2b(msg), msg.length * 8);
+		var o = new dcb.OutputStream();
 		while(a.getWidth() > 0){
 			var w = Math.min(a.getWidth(), 3);
 			o.putBits(a.getBits(w), w);
@@ -53,7 +49,7 @@ dojo.require("dojox.encoding.bits");
 		return b2s(o.getBuffer());
 	};
 
-	tests.register("dojox.encoding.tests.bits", [
+	doh.register("dojox.encoding.tests.bits", [
 		function testBitsOut1(t){ t.assertEqual(msg1, testOut(msg1)); },
 		function testBitsOut2(t){ t.assertEqual(msg2, testOut(msg2)); },
 		function testBitsOut3(t){ t.assertEqual(msg3, testOut(msg3)); },
@@ -67,4 +63,4 @@ dojo.require("dojox.encoding.bits");
 		function testBits3(t){ t.assertEqual(msg3, test(msg3)); },
 		function testBits4(t){ t.assertEqual(msg4, test(msg4)); }
 	]);
-})();
+});
diff --git a/dojox/encoding/tests/compression/_base.js b/dojox/encoding/tests/compression/_base.js
index 666149b..7f756d2 100644
--- a/dojox/encoding/tests/compression/_base.js
+++ b/dojox/encoding/tests/compression/_base.js
@@ -1,8 +1 @@
-dojo.provide("dojox.encoding.tests.compression._base");
-
-try{
-	dojo.require("dojox.encoding.tests.compression.splay");
-	dojo.require("dojox.encoding.tests.compression.lzw");
-}catch(e){
-	doh.debug(e);
-}
+define(['./splay', './lzw'], {});
diff --git a/dojox/encoding/tests/compression/lzw.js b/dojox/encoding/tests/compression/lzw.js
index 5dfa27f..636e3eb 100644
--- a/dojox/encoding/tests/compression/lzw.js
+++ b/dojox/encoding/tests/compression/lzw.js
@@ -1,13 +1,8 @@
-dojo.provide("dojox.encoding.tests.compression.lzw");
-dojo.require("dojox.encoding.compression.lzw");
-dojo.require("dojox.encoding.bits");
-
-(function(){
+define(['doh', '../../compression/lzw', '../../bits'], function(doh, dcl, dcb){
 	var msg1 = "The rain in Spain falls mainly on the plain.";
 	var msg2 = "The rain in Spain falls mainly on the plain.1";
 	var msg3 = "The rain in Spain falls mainly on the plain.ab";
 	var msg4 = "The rain in Spain falls mainly on the plain.!@#";
-	var dc = dojox.encoding.compression, dcb = dojox.encoding.bits, dcl = dc.lzw;
 	
 	var s2b = function(s){
 		var b = [];
@@ -41,10 +36,10 @@ dojo.require("dojox.encoding.bits");
 		return t.join("");
 	};
 
-	tests.register("dojox.encoding.tests.compression.lzw", [
+	doh.register("dojox.encoding.tests.compression.lzw", [
 		function testLzwMsg1(t){ t.assertEqual(msg1, decode(msg1.length, encode(msg1))); },
 		function testLzwMsg2(t){ t.assertEqual(msg2, decode(msg2.length, encode(msg2))); },
 		function testLzwMsg3(t){ t.assertEqual(msg3, decode(msg3.length, encode(msg3))); },
 		function testLzwMsg4(t){ t.assertEqual(msg4, decode(msg4.length, encode(msg4))); }
 	]);
-})();
+});
diff --git a/dojox/encoding/tests/compression/splay.js b/dojox/encoding/tests/compression/splay.js
index 09ad50e..59826c0 100644
--- a/dojox/encoding/tests/compression/splay.js
+++ b/dojox/encoding/tests/compression/splay.js
@@ -1,13 +1,8 @@
-dojo.provide("dojox.encoding.tests.compression.splay");
-dojo.require("dojox.encoding.compression.splay");
-dojo.require("dojox.encoding.bits");
-
-(function(){
+define(['doh', '../../compression/splay', '../../bits'], function(doh, Splay, dcb){
 	var msg1 = "The rain in Spain falls mainly on the plain.";
 	var msg2 = "The rain in Spain falls mainly on the plain.1";
 	var msg3 = "The rain in Spain falls mainly on the plain.ab";
 	var msg4 = "The rain in Spain falls mainly on the plain.!@#";
-	var dc = dojox.encoding.compression, dcb = dojox.encoding.bits;
 	
 	var s2b = function(s){
 		var b = [];
@@ -24,22 +19,22 @@ dojo.require("dojox.encoding.bits");
 	};
 	
 	var encode = function(msg){
-		var x = new dcb.OutputStream(), encoder = new dc.Splay(256);
+		var x = new dcb.OutputStream(), encoder = new Splay(256);
 		dojo.forEach(s2b(msg), function(v){ encoder.encode(v, x); });
 		console.debug("bits =", x.getWidth());
 		return x.getBuffer();
 	};
 	
 	var decode = function(n, buf){
-		var x = new dcb.InputStream(buf, buf.length * 8), decoder = new dc.Splay(256), t = [];
+		var x = new dcb.InputStream(buf, buf.length * 8), decoder = new Splay(256), t = [];
 		for(var i = 0; i < n; ++i){ t.push(decoder.decode(x)); }
 		return b2s(t);
 	};
 
-	tests.register("dojox.encoding.tests.compression.splay", [
+	doh.register("dojox.encoding.tests.compression.splay", [
 		function testSplayMsg1(t){ t.assertEqual(msg1, decode(msg1.length, encode(msg1))); },
 		function testSplayMsg2(t){ t.assertEqual(msg2, decode(msg2.length, encode(msg2))); },
 		function testSplayMsg3(t){ t.assertEqual(msg3, decode(msg3.length, encode(msg3))); },
 		function testSplayMsg4(t){ t.assertEqual(msg4, decode(msg4.length, encode(msg4))); }
 	]);
-})();
+});
diff --git a/dojox/encoding/tests/crypto/Blowfish.js b/dojox/encoding/tests/crypto/Blowfish.js
index 61a0bf2..47b6f46 100644
--- a/dojox/encoding/tests/crypto/Blowfish.js
+++ b/dojox/encoding/tests/crypto/Blowfish.js
@@ -1,31 +1,27 @@
-dojo.provide("dojox.encoding.tests.crypto.Blowfish");
-dojo.require("dojox.encoding.crypto.Blowfish");
-
-(function(){
+define(['doh', '../../crypto/Blowfish'], function(doh, Blowfish){
 	var message="The rain in Spain falls mainly on the plain.";
 	var key="foobar";
 	var base64Encrypted="WI5J5BPPVBuiTniVcl7KlIyNMmCosmKTU6a/ueyQuoUXyC5dERzwwdzfFsiU4vBw";
-	var dxc=dojox.encoding.crypto;
 
 	tests.register("dojox.encoding.crypto.tests.Blowfish", [
 		function testEncrypt(t){
 			var dt=new Date();
-			t.assertEqual(base64Encrypted, dxc.Blowfish.encrypt(message, key));
+			t.assertEqual(base64Encrypted, Blowfish.encrypt(message, key));
 			doh.debug("testEncrypt: ", new Date()-dt, "ms.");
 		},
 		function testDecrypt(t){
 			var dt=new Date();
-			t.assertEqual(message, dxc.Blowfish.decrypt(base64Encrypted, key));
+			t.assertEqual(message, Blowfish.decrypt(base64Encrypted, key));
 			doh.debug("testDecrypt: ", new Date()-dt, "ms.");
 		},
 		function testShortMessage(t){
 			var msg="pass";
 			var pwd="foobar";
 			var dt=new Date();
-			var enc=dxc.Blowfish.encrypt(msg, pwd);
-			var dec=dxc.Blowfish.decrypt(enc, pwd);
+			var enc=Blowfish.encrypt(msg, pwd);
+			var dec=Blowfish.decrypt(enc, pwd);
 			t.assertEqual(dec, msg);
 			doh.debug("testShortMessage: ", new Date()-dt, "ms.");
 		}
 	]);
-})();
+});
diff --git a/dojox/encoding/tests/crypto/RSA.js b/dojox/encoding/tests/crypto/RSA.js
index de31d2e..066f23d 100644
--- a/dojox/encoding/tests/crypto/RSA.js
+++ b/dojox/encoding/tests/crypto/RSA.js
@@ -1,15 +1,6 @@
-dojo.provide("dojox.encoding.tests.crypto.RSA");
+define(['doh', '../../crypto/RSAKey', '../../../math/random/Secure', '../../../math/random/prng4', '../../crypto/RSAKey-ext'], function(doh, RSAKey, Secure, prng4){
+	var message = "The rain in Spain falls mainly on the plain.",
 
-dojo.require("dojox.encoding.crypto.RSAKey");
-dojo.require("dojox.encoding.crypto.RSAKey-ext");
-dojo.require("dojox.math.random.Secure");
-dojo.require("dojox.math.random.prng4");
-
-(function(){
-	var dxc = dojox.encoding.crypto,
-		message = "The rain in Spain falls mainly on the plain.",
-
-		Secure = dojox.math.random.Secure, prng4 = dojox.math.random.prng4,
 		sec = function(){ return new Secure(prng4); },
 
 		keys = {
@@ -85,7 +76,7 @@ dojo.require("dojox.math.random.prng4");
 		};
 
 	function roundTrip(text, key, rngf){
-		var rsa = rngf ? new dxc.RSAKey(rngf) : new dxc.RSAKey();
+		var rsa = rngf ? new RSAKey(rngf) : new RSAKey();
 		rsa.setPublic(key.N, key.E);
 		var encoded = rsa.encrypt(text);
 		rsa.setPrivateEx(key.N, key.E, key.D, key.P, key.Q, key.DMP1, key.DMQ1, key.COEFF);
@@ -94,7 +85,7 @@ dojo.require("dojox.math.random.prng4");
 	}
 
 	function generateKey(len, e, rngf){
-		var rsa = rngf ? new dxc.RSAKey(rngf) : new dxc.RSAKey();
+		var rsa = rngf ? new RSAKey(rngf) : new RSAKey();
 		rsa.generate(len, e);
 		return {
 			N: rsa.n.toString(),
@@ -172,4 +163,4 @@ dojo.require("dojox.math.random.prng4");
 		}
 */
 	]);
-})();
+});
diff --git a/dojox/encoding/tests/crypto/SimpleAES.js b/dojox/encoding/tests/crypto/SimpleAES.js
index 8a8e6cb..b97cb1d 100644
--- a/dojox/encoding/tests/crypto/SimpleAES.js
+++ b/dojox/encoding/tests/crypto/SimpleAES.js
@@ -1,20 +1,16 @@
-dojo.provide("dojox.encoding.tests.crypto.SimpleAES");
-dojo.require("dojox.encoding.crypto.SimpleAES");
-
-(function(){
+define(['doh', '../../crypto/SimpleAES'], function(doh, SimpleAES){
 	var message="The rain in Spain falls mainly on the plain.";
 	var key="foo-bar-baz";
 	var enc = null;
-	var dxc=dojox.encoding.crypto;
 
 	tests.register("dojox.encoding.crypto.tests.SimpleAES", [
 		function testAES(t){
 			var dt = new Date();
-			enc = dxc.SimpleAES.encrypt(message, key);
+			enc = SimpleAES.encrypt(message, key);
 			doh.debug("Encrypt: ", new Date()-dt, "ms.");
 			var dt2 = new Date();
-			t.assertEqual(message, dxc.SimpleAES.decrypt(enc, key));
+			t.assertEqual(message, SimpleAES.decrypt(enc, key));
 			doh.debug("Decrypt: ", new Date()-dt2, "ms.");
 		}
 	]);
-})();
+});
diff --git a/dojox/encoding/tests/crypto/_base.js b/dojox/encoding/tests/crypto/_base.js
index 11b4c3b..838cd16 100644
--- a/dojox/encoding/tests/crypto/_base.js
+++ b/dojox/encoding/tests/crypto/_base.js
@@ -1,10 +1 @@
-dojo.provide("dojox.encoding.tests.crypto._base");
-dojo.require("dojox.encoding.crypto.Blowfish");
-
-try{
-	dojo.require("dojox.encoding.tests.crypto.Blowfish");
-	dojo.require("dojox.encoding.tests.crypto.SimpleAES");
-	dojo.require("dojox.encoding.tests.crypto.RSA");
-}catch(e){
-	doh.debug(e);
-}
+define(['./Blowfish', './SimpleAES', './RSA'], {});
diff --git a/dojox/encoding/tests/digests/MD5.js b/dojox/encoding/tests/digests/MD5.js
index 0422be4..95b4a85 100644
--- a/dojox/encoding/tests/digests/MD5.js
+++ b/dojox/encoding/tests/digests/MD5.js
@@ -1,22 +1,18 @@
-dojo.provide("dojox.encoding.tests.digests.MD5");
-dojo.require("dojox.encoding.digests.MD5");
-
-(function(){
+define(['doh', '../../digests/_base', '../../digests/MD5'], function(doh, ded, MD5){
 	var message="The rain in Spain falls mainly on the plain.";
 	var base64="OUhxbVZ1Mtmu4zx9LzS5cA==";
 	var hex="3948716d567532d9aee33c7d2f34b970";
 	var s="9HqmVu2\xD9\xAE\xE3<}/4\xB9p";
-	var ded=dojox.encoding.digests;
 
-	tests.register("dojox.encoding.tests.digests.MD5", [
+	doh.register("dojox.encoding.tests.digests.MD5", [
 		function testBase64Compute(t){
-			t.assertEqual(base64, ded.MD5(message));
+			t.assertEqual(base64, MD5(message));
 		},
 		function testHexCompute(t){
-			t.assertEqual(hex, ded.MD5(message, ded.outputTypes.Hex));
+			t.assertEqual(hex, MD5(message, ded.outputTypes.Hex));
 		},
 		function testStringCompute(t){
-			t.assertEqual(s, ded.MD5(message, ded.outputTypes.String));
+			t.assertEqual(s, MD5(message, ded.outputTypes.String));
 		}
 	]);
-})();
+});
diff --git a/dojox/encoding/tests/digests/SHA1.js b/dojox/encoding/tests/digests/SHA1.js
index bda28ef..0b38763 100644
--- a/dojox/encoding/tests/digests/SHA1.js
+++ b/dojox/encoding/tests/digests/SHA1.js
@@ -1,22 +1,18 @@
-dojo.provide("dojox.encoding.tests.digests.SHA1");
-dojo.require("dojox.encoding.digests.SHA1");
-
-(function(){
+define(['doh', '../../digests/_base', '../../digests/SHA1'], function(doh, ded, SHA1){
 	var message="abc";
 	var base64="qZk+NkcGgWq6PiVxeFDCbJzQ2J0=";
 	var hex="a9993e364706816aba3e25717850c26c9cd0d89d";
 	var s="\251\231\76\66\107\6\201\152\272\76\45\161\170\120\302\154\234\320\330\235";
-	var ded=dojox.encoding.digests;
 
-	tests.register("dojox.encoding.tests.digests.SHA1", [
+	doh.register("dojox.encoding.tests.digests.SHA1", [
 		function testBase64Compute(t){
-			t.assertEqual(base64, ded.SHA1(message));
+			t.assertEqual(base64, SHA1(message));
 		},
 		function testHexCompute(t){
-			t.assertEqual(hex, ded.SHA1(message, ded.outputTypes.Hex));
+			t.assertEqual(hex, SHA1(message, ded.outputTypes.Hex));
 		},
 		function testStringCompute(t){
-			t.assertEqual(s, ded.SHA1(message, ded.outputTypes.String));
+			t.assertEqual(s, SHA1(message, ded.outputTypes.String));
 		}
 	]);
-})();
+});
diff --git a/dojox/encoding/tests/digests/_base.js b/dojox/encoding/tests/digests/_base.js
index 5baecc3..652c6db 100644
--- a/dojox/encoding/tests/digests/_base.js
+++ b/dojox/encoding/tests/digests/_base.js
@@ -1,9 +1 @@
-dojo.provide("dojox.encoding.tests.digests._base");
-dojo.require("dojox.encoding.digests._base");
-
-try{
-	dojo.require("dojox.encoding.tests.digests.MD5");
-	dojo.require("dojox.encoding.tests.digests.SHA1");
-}catch(e){
-	doh.debug(e);
-}
+define(['./MD5', './SHA1'], {});
diff --git a/dojox/encoding/tests/easy64.js b/dojox/encoding/tests/easy64.js
index 6d23c66..b3058c8 100644
--- a/dojox/encoding/tests/easy64.js
+++ b/dojox/encoding/tests/easy64.js
@@ -1,12 +1,8 @@
-dojo.provide("dojox.encoding.tests.easy64");
-dojo.require("dojox.encoding.easy64");
-
-(function(){
+define(['doh', '../easy64'], function(doh, dce){
 	var msg1 = "The rain in Spain falls mainly on the plain.";
 	var msg2 = "The rain in Spain falls mainly on the plain.1";
 	var msg3 = "The rain in Spain falls mainly on the plain.ab";
 	var msg4 = "The rain in Spain falls mainly on the plain.!@#";
-	var dce = dojox.encoding.easy64;
 	
 	var s2b = function(s){
 		var b = [];
@@ -22,10 +18,10 @@ dojo.require("dojox.encoding.easy64");
 		return s.join("");
 	};
 
-	tests.register("dojox.encoding.tests.easy64", [
+	doh.register("dojox.encoding.tests.easy64", [
 		function testEasyMsg1(t){ t.assertEqual(msg1, b2s(dce.decode(dce.encode(s2b(msg1))))); },
 		function testEasyMsg2(t){ t.assertEqual(msg2, b2s(dce.decode(dce.encode(s2b(msg2))))); },
 		function testEasyMsg3(t){ t.assertEqual(msg3, b2s(dce.decode(dce.encode(s2b(msg3))))); },
 		function testEasyMsg4(t){ t.assertEqual(msg4, b2s(dce.decode(dce.encode(s2b(msg4))))); }
 	]);
-})();
+});
diff --git a/dojox/encoding/tests/encoding.js b/dojox/encoding/tests/encoding.js
index b2987fc..413d612 100644
--- a/dojox/encoding/tests/encoding.js
+++ b/dojox/encoding/tests/encoding.js
@@ -1,9 +1 @@
-dojo.provide("dojox.encoding.tests.encoding");
-
-try{
-	dojo.require("dojox.encoding.tests.ascii85");
-	dojo.require("dojox.encoding.tests.easy64");
-	dojo.require("dojox.encoding.tests.bits");
-}catch(e){
-	doh.debug(e);
-}
+define(['./ascii85', './easy64', './bits'], {});
diff --git a/dojox/form/BusyButton.js b/dojox/form/BusyButton.js
index ffe852a..356da26 100644
--- a/dojox/form/BusyButton.js
+++ b/dojox/form/BusyButton.js
@@ -1,123 +1,134 @@
-dojo.provide("dojox.form.BusyButton");
+define([
+	"dojo/_base/lang",
+	"dojo/dom-attr",
+	"dojo/dom-class",
+	"dijit/form/Button",
+	"dijit/form/DropDownButton",
+	"dijit/form/ComboButton",
+	"dojo/i18n",
+	"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, {
 
-dojo.require("dijit.form.Button");
-
-dojo.requireLocalization("dijit", "loading");
-
-dojo.declare("dojox.form._BusyButtonMixin",
-	null,
-	{
-		
 	isBusy: false,
 	busyLabel: "", // text while button is busy
 	timeout: null, // timeout, should be controlled by xhr call
 	useIcon: true, // use a busy icon
- 
+
 	postMixInProperties: function(){
 		this.inherited(arguments);
 		if(!this.busyLabel){
-			this.busyLabel = dojo.i18n.getLocalization("dijit", "loading", this.lang).loadingState;
+			this.busyLabel = i18n.getLocalization("dijit", "loading", this.lang).loadingState;
 		}
 	},
-	
+
 	postCreate: function(){
 		// summary:
-		//	stores initial label and timeout for reference
+		//		stores initial label and timeout for reference
 		this.inherited(arguments);
 		this._label = this.containerNode.innerHTML;
 		this._initTimeout = this.timeout;
-		
+
 		// for initial busy buttons
 		if(this.isBusy){
 			this.makeBusy();
 		}
 	},
-	
+
 	makeBusy: function(){
 		// summary:
-		//	sets state from idle to busy
+		//		sets state from idle to busy
 		this.isBusy = true;
 		this.set("disabled", true);
-			
+
 		this.setLabel(this.busyLabel, this.timeout);
 	},
-	
+
 	cancel: function(){
 		// summary:
-		//	if no timeout is set or for other reason the user can put the button back
-		//  to being idle
+		//		if no timeout is set or for other reason the user can put the button back
+		//  	to being idle
 		this.set("disabled", false);
 		this.isBusy = false;
 		this.setLabel(this._label);
 		if(this._timeout){	clearTimeout(this._timeout); }
 		this.timeout = this._initTimeout;
 	},
-	
+
 	resetTimeout: function(/*Int*/ timeout){
 		// summary:
-		//	to reset existing timeout and setting a new timeout
+		//		to reset existing timeout and setting a new timeout
 		if(this._timeout){
 			clearTimeout(this._timeout);
 		}
-		
+
 		// new timeout
 		if(timeout){
-			this._timeout = setTimeout(dojo.hitch(this, function(){
+			this._timeout = setTimeout(lang.hitch(this, function(){
 				this.cancel();
 			}), timeout);
 		}else if(timeout == undefined || timeout === 0){
 			this.cancel();
 		}
 	},
-	
+
 	setLabel: function(/*String*/ content, /*Int*/ timeout){
 		// summary:
-		//	setting a label and optional timeout of the labels state
-		
+		//		setting a label and optional timeout of the labels state
+
 		// 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){
+		while(this.containerNode.firstChild){
 			this.containerNode.removeChild(this.containerNode.firstChild);
 		}
 		this.containerNode.innerHTML = this.label;
-		
-		if(this.showLabel == false && !(dojo.attr(this.domNode, "title"))){
-			this.titleNode.title=dojo.trim(this.containerNode.innerText || this.containerNode.textContent || '');
+
+		if(this.showLabel == false && !domAttr.get(this.domNode, "title")){
+			this.titleNode.title=lang.trim(this.containerNode.innerText || this.containerNode.textContent || '');
 		}
 		// End IE hack
-		
+
 		// setting timeout
 		if(timeout){
 			this.resetTimeout(timeout);
 		}else{
 			this.timeout = null;
 		}
-		
+
 		// create optional busy image
 		if(this.useIcon && this.isBusy){
 			var node = new Image();
 			node.src = this._blankGif;
-			dojo.attr(node, "id", this.id+"_icon");
-			dojo.addClass(node, "dojoxBusyButtonIcon");
+			domAttr.set(node, "id", this.id+"_icon");
+			domClass.add(node, "dojoxBusyButtonIcon");
 			this.containerNode.appendChild(node);
 		}
 	},
-	
-	_clicked: function(e){
+
+	_onClick: function(e){
 		// summary:
-		//	on button click the button state gets changed
-		
+		//		on button click the button state gets changed
+
 		// only do something if button is not busy
 		if(!this.isBusy){
+			this.inherited(arguments);	// calls onClick()
 			this.makeBusy();
 		}
 	}
 });
 
-dojo.declare("dojox.form.BusyButton", [dijit.form.Button, dojox.form._BusyButtonMixin], {});
-dojo.declare("dojox.form.BusyComboButton", [dijit.form.ComboButton, dojox.form._BusyButtonMixin], {});
-dojo.declare("dojox.form.BusyDropDownButton", [dijit.form.DropDownButton, dojox.form._BusyButtonMixin], {});
+var BusyButton = declare("dojox.form.BusyButton", [Button, _BusyButtonMixin], {});
+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 93199b5..ae1ea0d 100644
--- a/dojox/form/CheckedMultiSelect.js
+++ b/dojox/form/CheckedMultiSelect.js
@@ -1,17 +1,47 @@
-dojo.provide("dojox.form.CheckedMultiSelect");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/event",
+	"dojo/dom-geometry",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/i18n",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dijit/_WidgetsInTemplateMixin",
+	"dijit/registry",
+	"dijit/Menu",
+	"dijit/MenuItem",
+	"dijit/Tooltip",
+	"dijit/form/_FormSelectWidget",
+	"dijit/form/ComboButton",
+	"dojo/text!dojox/form/resources/_CheckedMultiSelectMenuItem.html",
+	"dojo/text!dojox/form/resources/_CheckedMultiSelectItem.html",
+	"dojo/text!dojox/form/resources/CheckedMultiSelect.html",
+	"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){
 
-dojo.require("dijit.form.CheckBox");
-dojo.require("dijit.Tooltip");
-dojo.require("dijit.form._FormSelectWidget");
+	//	module:
+	//		dojox/form/CheckedMultiSelect
+	//	summary:
+	//		Extends the core dojox.form.CheckedMultiSelect to provide a "checkbox" selector
+	//
 
-dojo.declare("dojox.form._CheckedMultiSelectItem",
-	[dijit._Widget, dijit._Templated],
-	{
+	/*=====
+		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
 
-	widgetsInTemplate: true,
-	templateString: dojo.cache("dojox.form", "resources/_CheckedMultiSelectItem.html"),
+	templateString: CheckedMultiSelectItem,
 
 	baseClass: "dojoxMultiSelectItem",
 
@@ -19,7 +49,7 @@ dojo.declare("dojox.form._CheckedMultiSelectItem",
 	//		The option that is associated with this item
 	option: null,
 	parent: null,
-	
+
 	// disabled: boolean
 	//		Whether or not this widget is disabled
 	disabled: false,
@@ -32,11 +62,9 @@ dojo.declare("dojox.form._CheckedMultiSelectItem",
 		// summary:
 		//		Set the appropriate _subClass value - based on if we are multi-
 		//		or single-select
-		if(this.parent.multiple){
-			this._type = {type: "checkbox", baseClass: "dijitCheckBox"};
-		}else{
-			this._type = {type: "radio", baseClass: "dijitRadio"};
-		}
+		this._type = this.parent.multiple ?
+			{type: "checkbox", baseClass: "dijitCheckBox"} :
+			{type: "radio", baseClass: "dijitRadio"};
 		this.disabled = this.option.disabled = this.option.disabled||false;
 		this.inherited(arguments);
 	},
@@ -62,35 +90,35 @@ dojo.declare("dojox.form._CheckedMultiSelectItem",
 		}
 		// fire the parent's change
 		this.parent._updateSelection();
-		
+
 		// refocus the parent
 		this.parent.focus();
 	},
-	
+
 	_onClick: function(e){
 		// summary:
 		//		Sets the click state (passes through to the check box)
 		if(this.get("disabled") || this.get("readOnly")){
-			dojo.stopEvent(e);
+			event.stop(e);
 		}else{
 			this.checkBox._onClick(e);
 		}
 	},
-	
+
 	_updateBox: function(){
 		// summary:
 		//		Called to force the box to match the state of the select
 		this.checkBox.set('value', this.option.selected);
 	},
-	
+
 	_setDisabledAttr: function(value){
 		// summary:
 		//		Disables (or enables) all the children as well
 		this.disabled = value||this.option.disabled;
 		this.checkBox.set("disabled", this.disabled);
-		dojo.toggleClass(this.domNode, "dojoxMultiSelectDisabled", this.disabled);
+		domClass.toggle(this.domNode, "dojoxMultiSelectDisabled", this.disabled);
 	},
-	
+
 	_setReadOnlyAttr: function(value){
 		// summary:
 		//		Sets read only (or unsets) all the children as well
@@ -99,57 +127,276 @@ dojo.declare("dojox.form._CheckedMultiSelectItem",
 	}
 });
 
-dojo.declare("dojox.form.CheckedMultiSelect", dijit.form._FormSelectWidget, {
+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
+		//		otherwise, we won't respond correctly to heights/overflows
+		this.inherited(arguments);
+		var o = (this.menuTableNode = this.domNode),
+		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 + " dojoxCheckedMultiSelectMenu";
+		o.className = "dijitReset dijitMenuTable";
+		o.setAttribute("role", "listbox");
+		n.setAttribute("role", "presentation");
+		n.appendChild(o);
+	},
+
+	resize: function(/*Object*/ mb){
+		// 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%";
+			}
+		}
+	},
+
+	onClose: function(){
+		this.inherited(arguments);
+		if(this.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.menuTableNode.style.width = "";
+		}
+	},
+
+	onItemClick: function(/*dijit._Widget*/ item, /*Event*/ evt){
+		// summary:
+		//		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();
+		}
+
+		this.focusChild(item);
+
+		if(item.disabled || item.readOnly){ return false; }
+
+		if(!this.multiple){
+			// 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(evt);
+	}
+});
+
+var formCheckedMultiSelectMenuItem = declare("dojox.form._CheckedMultiSelectMenuItem", MenuItem, {
+	// summary:
+	//		A checkbox-like menu item for toggling on and off
+
+	templateString: CheckedMultiSelectMenuItem,
+
+	// option: dojox.form.__SelectOption
+	//		The option that is associated with this item
+	option: null,
+
+	// reference of dojox.form._CheckedMultiSelectMenu
+	parent: null,
+
+	// icon of the checkbox/radio button
+	_iconClass: "",
+
+	postMixInProperties: function(){
+	// 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"};
+		}else{
+			this._iconClass = "";
+			this._type = {type: "hidden"};
+		}
+		this.disabled = this.option.disabled;
+		this.checked = this.option.selected;
+		this.label = this.option.label;
+		this.readOnly = this.option.readOnly;
+		this.inherited(arguments);
+	},
+
+	onChange: function(/*Boolean*/ checked){
+		// summary:
+		//		User defined function to handle check/uncheck events
+		// tags:
+		//		callback
+	},
+
+	_updateBox: function(){
+		// summary:
+		//		Called to force the box to match the state of the select
+		domClass.toggle(this.domNode, "dojoxCheckedMultiSelectMenuItemChecked", !!this.option.selected);
+		this.domNode.setAttribute("aria-checked", this.option.selected);
+		this.inputNode.checked = this.option.selected;
+		if(!this.parent.multiple){
+			domClass.toggle(this.domNode, "dijitSelectSelectedOption", !!this.option.selected);
+		}
+	},
+
+	_onClick: function(/*Event*/ e){
+		// summary:
+		//		Clicking this item just toggles its state
+		// tags:
+		//		private
+		if(!this.disabled && !this.readOnly){
+			if(this.parent.multiple){
+				this.option.selected = !this.option.selected;
+				this.parent.onChange();
+				this.onChange(this.option.selected);
+			}else{
+				if(!this.option.selected){
+					array.forEach(this.parent.getChildren(), function(item){
+						item.option.selected = false;
+					});
+					this.option.selected = true;
+					this.parent.onChange();
+					this.onChange(this.option.selected);
+				}
+			}
+		}
+		this.inherited(arguments);
+	}
+});
+
+var formCheckedMultiSelect = declare("dojox.form.CheckedMultiSelect", FormSelectWidget, {
 	// summary:
 	//		Extends the core dijit MultiSelect to provide a "checkbox" selector
 
-	templateString: dojo.cache("dojox.form", "resources/CheckedMultiSelect.html"),
+	templateString: CheckedMultiSelect,
+
+	baseClass: "dojoxCheckedMultiSelect",
 
-	baseClass: "dojoxMultiSelect",
-	
 	// required: Boolean
 	//		User is required to check at least one item.
 	required: false,
-	
+
 	// invalidMessage: String
 	//		The message to display if value is invalid.
-	invalidMessage: "At least one item must be selected.",
-	
+	invalidMessage: "$_unset_$",
+
 	// _message: String
 	//		Currently displayed message
 	_message: "",
-	
+
+	// dropDown: Boolean
+	//		Drop down version or not
+	dropDown: false,
+
+	// labelText: String
+	//		Label of the drop down button
+	labelText: "",
+
 	// tooltipPosition: String[]
-	//		See description of `dijit.Tooltip.defaultPosition` for details on this parameter.
+	//		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);
+		if(this.invalidMessage == "$_unset_$"){ this.invalidMessage = this._nlsResources.invalidMessage; }
+	},
+
+	_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;
+		}
+		if(this.dropDown){
+			domClass.toggle(this.selectNode, "dojoxCheckedMultiSelectHidden");
+			this.dropDownMenu = new formCheckedMultiSelectMenu({
+				id: this.id + "_menu",
+				style: "display: none;",
+				multiple: this.multiple,
+				onChange: lang.hitch(this, "_updateSelection")
+			});
+		}
+	},
+
+	startup: function(){
+		// summary:
+		//		Set the value to be the first, or the selected index
+		this.inherited(arguments);
+		if(this.dropDown){
+			this.dropDownButton = new ComboButton({
+				label: this.labelText,
+				dropDown: this.dropDownMenu,
+				baseClass: "dojoxCheckedMultiSelectButton",
+				maxHeight: this.maxHeight
+			}, this.comboButtonNode);
+		}
+	},
+
 	_onMouseDown: function(e){
 		// summary:
 		//		Cancels the mousedown event to prevent others from stealing
 		//		focus
-		dojo.stopEvent(e);
+		event.stop(e);
 	},
-	
-	validator: function() {
+
+	validator: function(){
 		// summary:
 		//		Overridable function used to validate that an item is selected if required =
 		//		true.
 		// tags:
 		//		protected
-		if (!this.required){ return true; }
-		return dojo.some(this.getOptions(), function(opt){
+		if(!this.required){ return true; }
+		return array.some(this.getOptions(), function(opt){
 			return opt.selected && opt.value != null && opt.value.toString().length != 0;
 		});
 	},
-	
-	validate: function(isFocused) {
-		dijit.hideTooltip(this.domNode);
+
+	validate: function(isFocused){
+		Tooltip.hide(this.domNode);
 		var isValid = this.isValid(isFocused);
 		if(!isValid){ this.displayMessage(this.invalidMessage); }
 		return isValid;
 	},
-	
-	isValid: function(/*Boolean*/ isFocused) {
+
+	isValid: function(/*Boolean*/ isFocused){
 		// summary:
 		//		Tests if the required items are selected.
 		//		Can override with your own routine in a subclass.
@@ -158,45 +405,54 @@ dojo.declare("dojox.form.CheckedMultiSelect", dijit.form._FormSelectWidget, {
 		return this.validator();
 	},
 
-	getErrorMessage: function(/*Boolean*/ isFocused) {
+	getErrorMessage: function(/*Boolean*/ isFocused){
 		// summary:
 		//		Return an error message to show if appropriate
 		// tags:
 		//		protected
 		return this.invalidMessage;
 	},
-	
-	displayMessage: function(/*String*/ message) {
+
+	displayMessage: function(/*String*/ message){
 		// summary:
 		//		Overridable method to display validation errors/hints.
 		//		By default uses a tooltip.
 		// tags:
 		//		extension
-		dijit.hideTooltip(this.domNode);
+		Tooltip.hide(this.domNode);
 		if(message){
-			dijit.showTooltip(message, this.domNode, this.tooltipPosition);
+			Tooltip.show(message, this.domNode, this.tooltipPosition);
 		}
 	},
-	
+
 	onAfterAddOptionItem: function(item, option){
 		// summary:
 		//		a function that can be connected to in order to receive a
 		//		notification that an item as been added to this dijit.
 	},
-	
+
 	_addOptionItem: function(/* dojox.form.__SelectOption */ option){
-		var item = new dojox.form._CheckedMultiSelectItem({
-			option: option,
-			parent: this
-		});
-		this.wrapperDiv.appendChild(item.domNode);
+		var item;
+		if(this.dropDown){
+			item = new formCheckedMultiSelectMenuItem({
+				option: option,
+				parent: this.dropDownMenu
+			});
+			this.dropDownMenu.addChild(item);
+		}else{
+			item = new formCheckedMultiSelectItem({
+				option: option,
+				parent: this
+			});
+			this.wrapperDiv.appendChild(item.domNode);
+		}
 		this.onAfterAddOptionItem(item, option);
 	},
-	
+
 	_refreshState: function(){
 		// summary:
 		//		Validate if selection changes.
-		this.validate(this._focused);
+		this.validate(this.focused);
 	},
 
 	onChange: function(newValue){
@@ -204,54 +460,78 @@ dojo.declare("dojox.form.CheckedMultiSelect", dijit.form._FormSelectWidget, {
 		//		Validate if selection changes.
 		this._refreshState();
 	},
-	
+
 	reset: function(){
 		// summary: Overridden so that the state will be cleared.
 		this.inherited(arguments);
-		dijit.hideTooltip(this.domNode);
+		Tooltip.hide(this.domNode);
 	},
-	
+
 	_updateSelection: function(){
 		this.inherited(arguments);
 		this._handleOnChange(this.value);
-		dojo.forEach(this._getChildren(), function(c){ c._updateBox(); });
+		array.forEach(this._getChildren(), function(item){
+			item._updateBox();
+		});
+		if(this.dropDown && this.dropDownButton){
+			var i = 0, label = "";
+			array.forEach(this.options, function(option){
+				if(option.selected){
+					i++;
+					label = option.label;
+				}
+			});
+			this.dropDownButton.set("label", this.multiple ?
+				lang.replace(this._nlsResources.multiSelectLabelText, {num: i}) :
+				label);
+		}
 	},
-	
+
 	_getChildren: function(){
-		return dojo.map(this.wrapperDiv.childNodes, function(n){
-			return dijit.byNode(n);
-		});
+		if(this.dropDown){
+			return this.dropDownMenu.getChildren();
+		}else{
+			return array.map(this.wrapperDiv.childNodes, function(n){
+				return registry.byNode(n);
+			});
+		}
 	},
 
 	invertSelection: function(onChange){
 		// summary: Invert the selection
 		// onChange: Boolean
 		//		If null, onChange is not fired.
-		dojo.forEach(this.options, function(i){
-			i.selected = !i.selected;
-		});
-		this._updateSelection();
+		if(this.multiple){
+			array.forEach(this.options, function(i){
+				i.selected = !i.selected;
+			});
+			this._updateSelection();
+		}
 	},
 
 	_setDisabledAttr: function(value){
 		// summary:
 		//		Disable (or enable) all the children as well
 		this.inherited(arguments);
-		dojo.forEach(this._getChildren(), function(node){
+		if(this.dropDown){
+			this.dropDownButton.set("disabled", value);
+		}
+		array.forEach(this._getChildren(), function(node){
 			if(node && node.set){
 				node.set("disabled", value);
 			}
 		});
 	},
-	
+
 	_setReadOnlyAttr: function(value){
 		// summary:
 		//		Sets read only (or unsets) all the children as well
+		this.inherited(arguments);
 		if("readOnly" in this.attributeMap){
 			this._attrToDom("readOnly", value);
 		}
 		this.readOnly = value;
-		dojo.forEach(this._getChildren(), function(node){
+		array.forEach(this._getChildren(), function(node){
 			if(node && node.set){
 				node.set("readOnly", value);
 			}
@@ -259,11 +539,14 @@ dojo.declare("dojox.form.CheckedMultiSelect", dijit.form._FormSelectWidget, {
 	},
 
 	uninitialize: function(){
-		dijit.hideTooltip(this.domNode);
+		Tooltip.hide(this.domNode);
 		// Make sure these children are destroyed
-		dojo.forEach(this._getChildren(), function(child){
+		array.forEach(this._getChildren(), function(child){
 			child.destroyRecursive();
 		});
 		this.inherited(arguments);
 	}
 });
+
+return formCheckedMultiSelect;
+});
\ No newline at end of file
diff --git a/dojox/form/DateTextBox.js b/dojox/form/DateTextBox.js
index 30e2c55..b222209 100644
--- a/dojox/form/DateTextBox.js
+++ b/dojox/form/DateTextBox.js
@@ -1,13 +1,19 @@
-dojo.provide("dojox.form.DateTextBox");
-dojo.experimental("dojox.form.DateTextBox");
-
-dojo.require("dojox.widget.Calendar");
-dojo.require("dojox.widget.CalendarViews");
-dojo.require("dijit.form._DateTimeTextBox");
-
-dojo.declare(
-	"dojox.form.DateTextBox",
-	dijit.form._DateTimeTextBox,
+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");
+
+	/*=====
+		_DateTimeTextBox = dijit.form._DateTimeTextBox;
+	=====*/
+var DateTextBox = declare( "dojox.form.DateTextBox", _DateTimeTextBox,
 	{
 		// summary:
 		//		A validating, serializable, range-bound date text box with a popup calendar
@@ -19,15 +25,13 @@ dojo.declare(
 
 		openDropDown: function(){
 			this.inherited(arguments);
-			dojo.style(this.dropDown.domNode.parentNode, "position", "absolute");
+			domStyle.set(this.dropDown.domNode.parentNode, "position", "absolute");
 		}
 	}
 );
 
 
-dojo.declare(
-	"dojox.form.DayTextBox",
-	dojox.form.DateTextBox,
+declare( "dojox.form.DayTextBox", DateTextBox,
 	{
 		// summary:
 		//		A validating, serializable, range-bound date text box with a popup calendar that contains just months.
@@ -43,7 +47,7 @@ dojo.declare(
 		format: function(value){
 			return value.getDate ? value.getDate() : value;
 		},
-		validator: function(value) {
+		validator: function(value){
 			var num = Number(value);
 			var isInt = /(^-?\d\d*$)/.test(String(value));
 			return value == "" || value == null || (isInt && num >= 1 && num <= 31);
@@ -55,25 +59,23 @@ dojo.declare(
 					value = value.getDate();
 				}
 			}
-			dijit.form.TextBox.prototype._setValueAttr.call(this, value, priorityChange, formattedValue);
+			TextBox.prototype._setValueAttr.call(this, value, priorityChange, formattedValue);
 		},
 
 		openDropDown: function(){
 			this.inherited(arguments);
 
-			this.dropDown.onValueSelected = dojo.hitch(this, function(value){
+			this.dropDown.onValueSelected = lang.hitch(this, function(value){
 				this.focus(); // focus the textbox before the popup closes to avoid reopening the popup
-				setTimeout(dojo.hitch(this, "closeDropDown"), 1); // allow focus time to take
+				setTimeout(lang.hitch(this, "closeDropDown"), 1); // allow focus time to take
 
-				dijit.form.TextBox.prototype._setValueAttr.call(this, String(value.getDate()), true, String(value.getDate()));
+				TextBox.prototype._setValueAttr.call(this, String(value.getDate()), true, String(value.getDate()));
 			});
 		}
 	}
 );
 
-dojo.declare(
-	"dojox.form.MonthTextBox",
-	dojox.form.DateTextBox,
+declare( "dojox.form.MonthTextBox", DateTextBox,
 	{
 		// summary:
 		//		A validating, serializable, range-bound date text box with a popup calendar that contains only years
@@ -89,7 +91,7 @@ dojo.declare(
 			this.constraints.datePattern = "MM";
 		},
 
-		format: function(value) {
+		format: function(value){
 			if(!value && value !== 0){
 				return 1;
 			}
@@ -103,11 +105,11 @@ dojo.declare(
 			return Number(value) - 1;
 		},
 
-		serialize: function(value, constraints) {
+		serialize: function(value, constraints){
 			return String(value);
 		},
 
-		validator: function(value) {
+		validator: function(value){
 			var num = Number(value);
 			var isInt = /(^-?\d\d*$)/.test(String(value));
 			return value == "" || value == null || (isInt && num >= 1 && num <= 12);
@@ -119,43 +121,41 @@ dojo.declare(
 					value = value.getMonth();
 				}
 			}
-			dijit.form.TextBox.prototype._setValueAttr.call(this, value, priorityChange, formattedValue);
+			TextBox.prototype._setValueAttr.call(this, value, priorityChange, formattedValue);
 		},
 
 		openDropDown: function(){
 			this.inherited(arguments);
 
-			this.dropDown.onValueSelected = dojo.hitch(this, function(value){
+			this.dropDown.onValueSelected = lang.hitch(this, function(value){
 				this.focus(); // focus the textbox before the popup closes to avoid reopening the popup
-				setTimeout(dojo.hitch(this, "closeDropDown"), 1); // allow focus time to take
-				dijit.form.TextBox.prototype._setValueAttr.call(this, value, true, value);
+				setTimeout(lang.hitch(this, "closeDropDown"), 1); // allow focus time to take
+				TextBox.prototype._setValueAttr.call(this, value, true, value);
 			});
 		}
 	}
 );
 
 
-dojo.declare(
-	"dojox.form.YearTextBox",
-	dojox.form.DateTextBox,
+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"){
+		format: function(value){
+			//console.log('Year format ' + value);
+			if(typeof value == "string"){
 				return value;
 			}
-			else if (value.getFullYear){
+			else if(value.getFullYear){
 				return value.getFullYear();
 			}
 			return value;
 		},
 
-		validator: function(value) {
+		validator: function(value){
 			return value == "" || value == null || /(^-?\d\d*$)/.test(String(value));
 		},
 
@@ -165,29 +165,31 @@ dojo.declare(
 					value = value.getFullYear();
 				}
 			}
-			dijit.form.TextBox.prototype._setValueAttr.call(this, value, priorityChange, formattedValue);
+			TextBox.prototype._setValueAttr.call(this, value, priorityChange, formattedValue);
 		},
 
 		openDropDown: function(){
 			this.inherited(arguments);
-			console.log('yearly openDropDown and value = ' + this.get('value'));
+			//console.log('yearly openDropDown and value = ' + this.get('value'));
 
-			this.dropDown.onValueSelected = dojo.hitch(this, function(value){
+			this.dropDown.onValueSelected = lang.hitch(this, function(value){
 				this.focus(); // focus the textbox before the popup closes to avoid reopening the popup
-				setTimeout(dojo.hitch(this, "closeDropDown"), 1); // allow focus time to take
-				dijit.form.TextBox.prototype._setValueAttr.call(this,value, true, value);
+				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) {
+		parse: function(/*String*/value, /*dojo.date.locale.__FormatOptions*/constraints){
 			return value || (this._isEmpty(value) ? null : undefined); // Date
 		},
 
-		filter: function(val) {
-			if (val && val.getFullYear){
+		filter: function(val){
+			if(val && val.getFullYear){
 				return val.getFullYear().toString();
 			}
 			return this.inherited(arguments);
 		}
 	}
 );
+return DateTextBox;
+});
\ No newline at end of file
diff --git a/dojox/form/DropDownSelect.js b/dojox/form/DropDownSelect.js
index ef39077..a4a3107 100644
--- a/dojox/form/DropDownSelect.js
+++ b/dojox/form/DropDownSelect.js
@@ -1,6 +1,10 @@
-dojo.deprecated("dojox.form.DropDownSelect", "Use dijit.form.Select instead", "2.0");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dijit/form/Select"
+], function(kernel, lang, Select){
+	kernel.deprecated("dojox.form.DropDownSelect", "Use Select instead", "2.0");
 
-dojo.provide("dojox.form.DropDownSelect");
-dojo.require("dijit.form.Select");
-
-dojo.setObject("dojox.form.DropDownSelect", dijit.form.Select);
\ No newline at end of file
+	lang.setObject("dojox.form.DropDownSelect", Select);
+	return Select;
+});
\ No newline at end of file
diff --git a/dojox/form/DropDownStack.js b/dojox/form/DropDownStack.js
index 7282bae..dabf2e4 100644
--- a/dojox/form/DropDownStack.js
+++ b/dojox/form/DropDownStack.js
@@ -1,10 +1,14 @@
-dojo.provide("dojox.form.DropDownStack");
-
-dojo.require("dijit.form.Select");
-dojo.require("dojox.form._SelectStackMixin");
-
-dojo.declare("dojox.form.DropDownStack",
-	[ dijit.form.Select, dojox.form._SelectStackMixin ], {
+define([
+	"dijit/form/Select",
+	"./_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.
-	
-});
+
+	});
+});
\ No newline at end of file
diff --git a/dojox/form/FileInput.js b/dojox/form/FileInput.js
index 367f5c6..eabecf7 100644
--- a/dojox/form/FileInput.js
+++ b/dojox/form/FileInput.js
@@ -1,11 +1,20 @@
-dojo.provide("dojox.form.FileInput");
-dojo.experimental("dojox.form.FileInput");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/kernel",
+	"dojo/_base/fx",
+	"dojo/dom-attr",
+	"dojo/dom-class",
+	"dojo/text!./resources/FileInput.html",
+	"dijit/form/_FormWidget",
+	"dijit/_Templated"
+],
+function(declare, kernel, fx, domAttr, domClass, template, FormWidget, Templated){
+kernel.experimental("dojox.form.FileInput");
 
-dojo.require("dijit.form._FormWidget");
-dojo.require("dijit._Templated");
-
-dojo.declare("dojox.form.FileInput",
-	dijit.form._FormWidget,
+	/*=====
+		FormWidget = dijit.form._FormWidget;
+	=====*/
+declare("dojox.form.FileInput", FormWidget,
 	{
 	// summary: A styled input type="file"
 	//
@@ -25,8 +34,8 @@ dojo.declare("dojox.form.FileInput",
 	//	ugh, this should be pulled from this.domNode
 	name: "uploadFile",
 
-	templateString: dojo.cache("dojox.form","resources/FileInput.html"),
-	
+	templateString: template,
+
 	startup: function(){
 		// summary: listen for changes on our real file input
 		this._listener = this.connect(this.fileInput,"onchange","_matchValue");
@@ -36,13 +45,13 @@ dojo.declare("dojox.form.FileInput",
 	//get rid of the this.connect in _FormWidget.postCreate to allow IE to show
 	//the file picker dialog properly
 	postCreate: function(){},
-	
+
 	_matchValue: function(){
 		// 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";
-			dojo.fadeIn({ node: this.cancelNode, duration:275 }).play();
+			fx.fadeIn({ node: this.cancelNode, duration:275 }).play();
 		}
 	},
 
@@ -59,17 +68,17 @@ dojo.declare("dojox.form.FileInput",
 		if(this.fileInput){
 			this.domNode.removeChild(this.fileInput);
 		}
-		dojo.fadeOut({ node: this.cancelNode, duration:275 }).play();
+		fx.fadeOut({ node: this.cancelNode, duration:275 }).play();
 
 		// should we use cloneNode()? can we?
 		this.fileInput = document.createElement('input');
-		// dojo.attr(this.fileInput,{
+		// domAttr.set(this.fileInput,{
 		//	"type":"file", "id":this.id, "name": this.name
 		//});
 		this.fileInput.setAttribute("type","file");
 		this.fileInput.setAttribute("id", this.id);
 		this.fileInput.setAttribute("name", this.name);
-		dojo.addClass(this.fileInput,"dijitFileInputReal");
+		domClass.add(this.fileInput,"dijitFileInputReal");
 		this.domNode.appendChild(this.fileInput);
 
 		this._keyListener = this.connect(this.fileInput, "onkeyup", "_matchValue");
@@ -77,4 +86,7 @@ dojo.declare("dojox.form.FileInput",
 		this.inputNode.value = "";
 	}
 
-});
\ No newline at end of file
+});
+
+return dojox.form.FileInput;
+});
diff --git a/dojox/form/FileInputAuto.js b/dojox/form/FileInputAuto.js
index 2544372..923de2c 100644
--- a/dojox/form/FileInputAuto.js
+++ b/dojox/form/FileInputAuto.js
@@ -1,15 +1,25 @@
-dojo.provide("dojox.form.FileInputAuto");
-
-dojo.require("dojox.form.FileInput");
-dojo.require("dojo.io.iframe");
-
-dojo.declare("dojox.form.FileInputAuto",
-	dojox.form.FileInput,
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/fx",
+	"dojo/_base/window",
+	"dojo/dom-style",
+	"dojo/_base/sniff",
+	"dojo/text!./resources/FileInputAuto.html",
+	"dojox/form/FileInput",
+	"dojo/io/iframe"
+], 
+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 dojox.form.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 dojo.io.iframe to the url. example implementation
+	//	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
@@ -17,7 +27,7 @@ dojo.declare("dojox.form.FileInputAuto",
 	//
 	//	results = { size: "1024", filename: "file.txt" }
 	//
-	//	all the parameters allowed to dojox.form.FileInput apply
+	//	all the parameters allowed to FileInput apply
 
 	// url: String
 	// 	the URL where our background FileUpload will be sent
@@ -47,7 +57,7 @@ dojo.declare("dojox.form.FileInputAuto",
 	_sent: false,
 	
 	// small template changes, new attachpoint: overlay
-	templateString: dojo.cache("dojox.form","resources/FileInputAuto.html"),
+	templateString: template,
 	
 	onBeforeSend: function(){
 		// summary: Called immediately before a FileInput sends it's file via io.iframe.send.
@@ -72,7 +82,7 @@ dojo.declare("dojox.form.FileInputAuto",
 		// summary: start the upload timer
 		if(this._blurTimer){ clearTimeout(this._blurTimer); }
 		if(!this._sent){
-			this._blurTimer = setTimeout(dojo.hitch(this,"_sendFile"),this.blurDelay);
+			this._blurTimer = setTimeout(lang.hitch(this,"_sendFile"),this.blurDelay);
 		}
 	},
 
@@ -91,18 +101,18 @@ dojo.declare("dojox.form.FileInputAuto",
 
 		this._sending = true;
 
-		dojo.style(this.fakeNodeHolder,"display","none");
-		dojo.style(this.overlay,{
+		domStyle.set(this.fakeNodeHolder,"display","none");
+		domStyle.set(this.overlay,{
 			opacity:0,
 			display:"block"
 		});
 
 		this.setMessage(this.uploadMessage);
 
-		dojo.fadeIn({ node: this.overlay, duration:this.duration }).play();
+		fx.fadeIn({ node: this.overlay, duration:this.duration }).play();
 
 		var _newForm;
-		if(dojo.isIE < 9 || (dojo.isIE && dojo.isQuirks)){
+		if(has('ie') < 9 || (has('ie') && has('quirks'))){
 			// just to reiterate, IE is a steaming pile of code.
 			_newForm = document.createElement('<form enctype="multipart/form-data" method="post">');
 			_newForm.encoding = "multipart/form-data";
@@ -113,13 +123,13 @@ dojo.declare("dojox.form.FileInputAuto",
 			_newForm.setAttribute("enctype","multipart/form-data");
 		}
 		_newForm.appendChild(this.fileInput);
-		dojo.body().appendChild(_newForm);
+		win.body().appendChild(_newForm);
 	
-		dojo.io.iframe.send({
+		ioIframe.send({
 			url: this.url,
 			form: _newForm,
 			handleAs: "json",
-			handle: dojo.hitch(this,"_handleSend"),
+			handle: lang.hitch(this,"_handleSend"),
 			content: this.onBeforeSend()
 		});
 	},
@@ -132,7 +142,7 @@ dojo.declare("dojox.form.FileInputAuto",
 		
 		this._sent = true;
 		this._sending = false;
-		dojo.style(this.overlay,{
+		domStyle.set(this.overlay,{
 			opacity:0,
 			border:"none",
 			background:"none"
@@ -141,13 +151,13 @@ dojo.declare("dojox.form.FileInputAuto",
 		this.overlay.style.backgroundImage = "none";
 		this.fileInput.style.display = "none";
 		this.fakeNodeHolder.style.display = "none";
-		dojo.fadeIn({ node:this.overlay, duration:this.duration }).play(250);
+		fx.fadeIn({ node:this.overlay, duration:this.duration }).play(250);
 
 		this.disconnect(this._blurListener);
 		this.disconnect(this._focusListener);
 
 		//remove the form used to send the request
-		dojo.body().removeChild(ioArgs.args.form);
+		win.body().removeChild(ioArgs.args.form);
 		this.fileInput = null;
 
 		this.onComplete(data,ioArgs,this);
@@ -172,13 +182,12 @@ dojo.declare("dojox.form.FileInputAuto",
 	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 dojo.Deferred data being passed from the handle: callback
+		// 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
 	}
 });
 
-dojo.declare("dojox.form.FileInputBlind",
-	dojox.form.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
@@ -187,17 +196,17 @@ dojo.declare("dojox.form.FileInputBlind",
 	startup: function(){
 		// summary: hide our fileInput input field
 		this.inherited(arguments);
-		this._off = dojo.style(this.inputNode,"width");
+		this._off = domStyle.get(this.inputNode,"width");
 		this.inputNode.style.display = "none";
 		this._fixPosition();
 	},
 	
 	_fixPosition: function(){
 		// summary: in this case, set the button under where the visible button is
-		if(dojo.isIE){
-			dojo.style(this.fileInput,"width","1px");
+		if(has('ie')){
+			domStyle.set(this.fileInput,"width","1px");
 		}else{
-			dojo.style(this.fileInput,"left","-"+(this._off)+"px");
+			domStyle.set(this.fileInput,"left","-"+(this._off)+"px");
 		}
 	},
 
@@ -207,3 +216,6 @@ dojo.declare("dojox.form.FileInputBlind",
 		this._fixPosition();
 	}
 });
+
+return FileInputAuto;
+});
diff --git a/dojox/form/FileInputBlind.js b/dojox/form/FileInputBlind.js
index 52af5e9..fd814cc 100644
--- a/dojox/form/FileInputBlind.js
+++ b/dojox/form/FileInputBlind.js
@@ -1,4 +1,9 @@
-dojo.provide("dojox.form.FileInputBlind");
+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
 // backwards compatibility.
-dojo.require("dojox.form.FileInputAuto");
\ No newline at end of file
+	lang.setObject("dojox.form.FileInputBlind", FileInputAuto);
+	return FileInputAuto;
+});
\ No newline at end of file
diff --git a/dojox/form/FilePickerTextBox.js b/dojox/form/FilePickerTextBox.js
index 2f90b79..7c7fec2 100644
--- a/dojox/form/FilePickerTextBox.js
+++ b/dojox/form/FilePickerTextBox.js
@@ -1,38 +1,49 @@
-dojo.provide("dojox.form.FilePickerTextBox");
+define([
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/event",
+	"dojo/window",
+	"dijit/focus",
+	"dijit/registry",
+	"dijit/form/_TextBoxMixin",
+	"dijit/form/ValidationTextBox",
+	"dijit/_HasDropDown",
+	"dojox/widget/FilePicker",
+	"dojo/text!./resources/FilePickerTextBox.html",
+	"dojo/_base/declare",
+	"dojo/keys" // keys
+], function(lang, array, event, windowUtils, focus, registry, _TextBoxMixin, ValidationTextBox, _HasDropDown, FilePicker, template, declare, keys){
 
-dojo.require("dojo.window");
-dojo.require("dijit.form.ValidationTextBox");
-dojo.require("dijit._HasDropDown");
-dojo.require("dojox.widget.FilePicker");
-
-dojo.declare(
-	"dojox.form.FilePickerTextBox",
-	[dijit.form.ValidationTextBox, dijit._HasDropDown],
+	/*=====
+		ValidationTextBox = dijit.form.ValidationTextBox;
+		_HasDropDown = dijit._HasDropDown;
+	=====*/
+return declare( "dojox.form.FilePickerTextBox", [ValidationTextBox, _HasDropDown],
 	{
 		// summary:
 		//		A validating text box tied to a file picker popup
-		
+
 		baseClass: "dojoxFilePickerTextBox",
-		
-		templateString: dojo.cache("dojox.form", "resources/FilePickerTextBox.html"),
-		
+
+		templateString: template,
+
 		// searchDelay: Integer
 		//		Delay in milliseconds between when user types something and we start
 		//		searching based on that value
 		searchDelay: 500,
-		
+
 		// valueItem: item
 		//		The item, in our store, of the directory relating to our value
 		valueItem: null,
-		
+
 		// numPanes: number
 		//	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(){
 			this.inherited(arguments);
-			this.dropDown = new dojox.widget.FilePicker(this.constraints);
+			this.dropDown = new FilePicker(this.constraints);
 		},
 
 		postCreate: function(){
@@ -42,10 +53,10 @@ dojo.declare(
 			this.connect(this.focusNode, "onblur", "_focusBlur");
 			this.connect(this.focusNode, "onfocus", "_focusFocus");
 			this.connect(this.focusNode, "ondblclick", function(){
-				dijit.selectInputText(this.focusNode);
+				_TextBoxMixin.selectInputText(this.focusNode);
 			});
 		},
-		
+
 		_setValueAttr: function(/*string*/value, priorityChange, fromWidget){
 			// summary: sets the value of this widget
 			if(!this._searchInProgress){
@@ -54,13 +65,13 @@ dojo.declare(
 				var tVal = this.dropDown.get("pathValue") || "";
 				if(value !== tVal){
 					this._skip = true;
-					var fx = dojo.hitch(this, "_setBlurValue");
+					var fx = lang.hitch(this, "_setBlurValue");
 					this.dropDown._setPathValueAttr(value, !fromWidget,
 											this._settingBlurValue ? fx : null);
 				}
 			}
 		},
-		
+
 		_onWidgetChange: function(/*item*/item){
 			// summary: called when the path gets changed in the dropdown
 			if(!item && this.focusNode.value){
@@ -79,7 +90,7 @@ dojo.declare(
 			}
 			this.validate();
 		},
-		
+
 		startup: function(){
 			if(!this.dropDown._started){
 				this.dropDown.startup();
@@ -95,7 +106,7 @@ dojo.declare(
 			}
 			this.inherited(arguments);
 		},
-		
+
 		toggleDropDown: function(){
 			this.inherited(arguments);
 			// Make sure our display is up-to-date with our value
@@ -103,11 +114,11 @@ dojo.declare(
 				this.dropDown.set("pathValue", this.get("value"));
 			}
 		},
-		
+
 		_focusBlur: function(/*Event*/ e){
 			// summary: called when the focus node gets blurred
 			if(e.explicitOriginalTarget == this.focusNode && !this._allowBlur){
-				window.setTimeout(dojo.hitch(this, function(){
+				window.setTimeout(lang.hitch(this, function(){
 					if(!this._allowBlur){
 						this.focus();
 					}
@@ -117,16 +128,16 @@ dojo.declare(
 				delete this._menuFocus;
 			}
 		},
-		
+
 		_focusFocus: function(/*Event*/ e){
 			// summary: called when the focus node gets focus
 			if(this._menuFocus){
 				this.dropDown._updateClass(this._menuFocus, "Item", {"Hover": false});
 			}
 			delete this._menuFocus;
-			var focusNode = dijit.getFocus(this);
-			if(focusNode && focusNode.node){
-				focusNode = dijit.byNode(focusNode.node);
+			var focusNode = focus.curNode;
+			if(focusNode){
+				focusNode = registry.byNode(focusNode);
 				if(focusNode){
 					this._menuFocus = focusNode.domNode;
 				}
@@ -136,14 +147,14 @@ dojo.declare(
 			}
 			delete this._allowBlur;
 		},
-		
+
 		_onBlur: function(){
 			// 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
 			if(this.dropDown && !this._settingBlurValue){
@@ -154,7 +165,7 @@ dojo.declare(
 				this.inherited(arguments);
 			}
 		},
-		
+
 		parse: function(/* String */ value, /* Object */ constraints){
 			//	summary:
 			//		Function to convert a formatted string to a value - we use
@@ -180,41 +191,41 @@ dojo.declare(
 			}
 			return undefined;
 		},
-		
+
 		_startSearchFromInput: function(){
 			// 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){
-				dijit.selectInputText(fn, oVal.length);
+				_TextBoxMixin.selectInputText(fn, oVal.length);
 			}
 			this._hasSelection = false;
 			if(topDir.length && val.indexOf(topDir) === 0){
 				val = val.substring(topDir.length);
 			}
 			var dirs = val.split(dd.pathSeparator);
-			var setFromChain = dojo.hitch(this, function(idx){
+			var setFromChain = lang.hitch(this, function(idx){
 				var dir = dirs[idx];
 				var child = dd.getChildren()[idx];
 				var conn;
 				this._searchInProgress = true;
-				var _cleanup = dojo.hitch(this, function(){
+				var _cleanup = lang.hitch(this, function(){
 					delete this._searchInProgress;
 				});
 				if((dir || child) && !this._opened){
 					this.toggleDropDown();
 				}
 				if(dir && child){
-					var fx = dojo.hitch(this, function(){
+					var fx = lang.hitch(this, function(){
 						if(conn){
 							this.disconnect(conn);
 						}
 						delete conn;
 						var children = child._menu.getChildren();
-						var exact = dojo.filter(children, function(i){
+						var exact = array.filter(children, function(i){
 							return i.label == dir;
 						})[0];
-						var first = dojo.filter(children, function(i){
+						var first = array.filter(children, function(i){
 							return (i.label.indexOf(dir) === 0);
 						})[0];
 						if(exact &&
@@ -241,10 +252,10 @@ dojo.declare(
 								}
 								targetString = targetString.substring(dir.length);
 								window.setTimeout(function(){
-									dojo.window.scrollIntoView(first.domNode);
+									windowUtils.scrollIntoView(first.domNode);
 								}, 1);
 								fn.value = oVal + targetString;
-								dijit.selectInputText(fn, oVal.length);
+								_TextBoxMixin.selectInputText(fn, oVal.length);
 								this._hasSelection = true;
 								try{first.focusNode.focus();}catch(e){}
 							}else{
@@ -273,32 +284,31 @@ dojo.declare(
 			});
 			setFromChain(0);
 		},
-		
+
 		_onKey: function(/*Event*/ e){
 			// summary: callback when the user presses a key on menu popup node
 			if(this.disabled || this.readOnly){ return; }
-			var dk = dojo.keys;
 			var c = e.charOrCode;
-			if(c==dk.DOWN_ARROW){
+			if(c==keys.DOWN_ARROW){
 				this._allowBlur = true;
 			}
-			if(c==dk.ENTER && this._opened){
+			if(c==keys.ENTER && this._opened){
 				this.dropDown.onExecute();
-				dijit.selectInputText(this.focusNode, this.focusNode.value.length);
+				_TextBoxMixin.selectInputText(this.focusNode, this.focusNode.value.length);
 				this._hasSelection = false;
-				dojo.stopEvent(e);
+				event.stop(e);
 				return;
 			}
-			if((c==dk.RIGHT_ARROW || c==dk.LEFT_ARROW || c==dk.TAB) && this._hasSelection){
+			if((c==keys.RIGHT_ARROW || c==keys.LEFT_ARROW || c==keys.TAB) && this._hasSelection){
 				this._startSearchFromInput();
-				dojo.stopEvent(e);
+				event.stop(e);
 				return;
 			}
 			this.inherited(arguments);
 			var doSearch = false;
-			if((c==dk.BACKSPACE || c==dk.DELETE) && this._hasSelection){
+			if((c==keys.BACKSPACE || c==keys.DELETE) && this._hasSelection){
 				this._hasSelection = false;
-			}else if(c==dk.BACKSPACE || c==dk.DELETE || c==" "){
+			}else if(c==keys.BACKSPACE || c==keys.DELETE || c==" "){
 				doSearch = true;
 			}else{
 				doSearch = e.keyChar !== "";
@@ -310,8 +320,9 @@ dojo.declare(
 			if(doSearch){
 				this._hasValidPath = false;
 				this._hasSelection = false;
-				this._searchTimer = window.setTimeout(dojo.hitch(this, "_startSearchFromInput"), this.searchDelay + 1);
+				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 9cf138f..c75e5ad 100644
--- a/dojox/form/FileUploader.js
+++ b/dojox/form/FileUploader.js
@@ -1,13 +1,32 @@
-dojo.provide("dojox.form.FileUploader");
-dojo.require("dojox.embed.Flash");
-dojo.require("dojo.io.iframe");
-dojo.require("dojox.html.styles");
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dojox.embed.flashVars");
-dojo.require("dijit._Contained");
-
-console.warn("DEPRECATED: dojox.form.FileUploader is no longer supported and will be removed in 2.0. Suggested that you use dojox.form.Uploader instead.");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/window",
+	"dojo/_base/sniff",
+	"dojo/query",
+	"dojo/dom-style",
+	"dojo/dom-geometry",
+	"dojo/dom-attr",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-form",
+	"dojo/_base/config",
+	"dijit/_base/manager",
+	"dojo/io/iframe",
+	"dojo/_base/Color",
+	"dojo/_base/unload",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dijit/_Contained",
+	"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){
+
+kernel.deprecated("dojox.form.FileUploader", "Use dojox.form.Uploader", "2.0");
 
 	//	Usage Notes:
 	//		To center text vertically, use vertical-align:middle;
@@ -15,7 +34,12 @@ console.warn("DEPRECATED: dojox.form.FileUploader is no longer supported and wil
 	//			can cause height problems in IE6
 
 
-dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit._Contained], {
+	/*=====
+		Widget = dijit._Widget;
+		TemplatedMixin = dijit._TemplatedMixin;
+		Contained = dijit._Contained;
+	=====*/
+declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 	// version:
 	//		1.5 (deprecated)
 	// summary:
@@ -92,7 +116,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 	//		works like a charm:
 	//		BrowserMatch Safari nokeepalive
 	//
-	swfPath: dojo.config.uploaderPath || dojo.moduleUrl("dojox.form", "resources/fileuploader.swf"),
+	swfPath: config.uploaderPath || require.toUrl("dojox/form/resources/fileuploader.swf"),
 
 
 	templateString:'<div><div dojoAttachPoint="progNode"><div dojoAttachPoint="progTextNode"></div></div><div dojoAttachPoint="insideNode" class="uploaderInsideNode"></div></div>',
@@ -234,7 +258,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 	//
 	//	progressBackgroundUrl: String|Uri
 	//		The background image to use for the button-progress
-	progressBackgroundUrl:dojo.moduleUrl("dijit", "themes/tundra/images/buttonActive.png"),
+	progressBackgroundUrl:require.toUrl("dijit/themes/tundra/images/buttonActive.png"),
 	//
 	//	progressBackgroundColor: String|Number
 	//		The background color to use for the button-progress
@@ -284,18 +308,15 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		this.flashReady = false;
 		this._disabled = false;
 		this.force = this.force.toLowerCase(); // Pete FTW.
-		this.uploaderType = ((dojox.embed.Flash.available >= this.minFlashVersion || this.force=="flash") && this.force != "html") ? "flash" : "html";
+		this.uploaderType = ((embedFlash.available >= this.minFlashVersion || this.force=="flash") && this.force != "html") ? "flash" : "html";
 		this.deferredUploading = this.deferredUploading===true ? 1 : this.deferredUploading;
 
 		this._refNode = this.srcNodeRef;
 
 		this.getButtonStyle();
-
-
 	},
 
 	startup: function(){
-
 	},
 
 	postCreate: function(){
@@ -315,7 +336,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		this[createMethod]();
 
 		if(this.fileListId){
-			this.connect(dojo.byId(this.fileListId), "click", function(evt){
+			this.connect(dom.byId(this.fileListId), "click", function(evt){
 				var p = evt.target.parentNode.parentNode.parentNode; // in a table
 				if(p.id && p.id.indexOf("file_")>-1){
 					this.removeFile(p.id.split("file_")[1]);
@@ -324,27 +345,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		}
 
 		// cleaning up solves memory leak issues in the HTML version
-		dojo.addOnUnload(this, this.destroy);
-	},
-
-	getHiddenWidget: function(){
-		// summary:
-		//		Internal.
-		//		If a parent widget has an onShow event, it is assumed
-		//		that it is hidden and the parsing of the uploader is
-		//		delayed until onShow fires. Note that the widget must
-		//		fire onShow even if it is defaulted to showing/selected.
-		//		this seems to work for Tabs (the primary fix).
-		//
-		var node = this.domNode.parentNode;
-		while(node){
-			var id = node.getAttribute && node.getAttribute("widgetId");
-			if(id && dijit.byId(id).onShow){
-				return dijit.byId(id);
-			}
-			node = node.parentNode;
-		}
-		return null;
+		unloadUtils.addOnUnload(this, this.destroy);
 	},
 
 	getHiddenNode: function(/*DomNode*/ node){
@@ -360,7 +361,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		var hidden = null;
 		var p = node.parentNode;
 		while(p && p.tagName.toLowerCase() != "body"){
-			var d = dojo.style(p, "display");
+			var d = domStyle.get(p, "display");
 			if(d == "none"){
 				hidden = p;
 				break;
@@ -387,16 +388,16 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		var refNode = this.srcNodeRef;
 		this._hiddenNode = this.getHiddenNode(refNode);
 		if(this._hiddenNode){
-			dojo.style(this._hiddenNode, "display", "block");
+			domStyle.set(this._hiddenNode, "display", "block");
 		}
 
 		if(!refNode && this.button && this.button.domNode){
 			// backwards compat for a Dijit button
 			var isDijitButton = true;
 			var cls = this.button.domNode.className + " dijitButtonNode";
-			var txt = this.getText(dojo.query(".dijitButtonText", this.button.domNode)[0]);
+			var txt = this.getText(query(".dijitButtonText", this.button.domNode)[0]);
 			var domTxt = '<button id="'+this.button.id+'" class="'+cls+'">'+txt+'</button>';
-			refNode = dojo.place(domTxt, this.button.domNode, "after");	 /// Pete doesn't like this?
+			refNode = domConstruct.place(domTxt, this.button.domNode, "after");	 /// Pete doesn't like this?
 			this.srcNodeRef = refNode;
 			this.button.destroy();
 
@@ -409,10 +410,10 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 			refNode = this.button;
 		}
 
-		if(dojo.attr(refNode, "class")){
-			this.baseClass += " " + dojo.attr(refNode, "class");
+		if(domAttr.get(refNode, "class")){
+			this.baseClass += " " + domAttr.get(refNode, "class");
 		}
-		dojo.attr(refNode, "class", this.baseClass);
+		domAttr.set(refNode, "class", this.baseClass);
 
 
 		this.norm = this.getStyle(refNode);
@@ -457,7 +458,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		//		Internal.
 		//		Set up internal dom nodes for button construction.
 		//
-		dojo.style(this.domNode, {
+		domStyle.set(this.domNode, {
 			width:this.fhtml.nr.w+"px",
 			height:(this.fhtml.nr.h)+"px",
 			padding:"0px",
@@ -465,11 +466,11 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 			position:"relative"
 		});
 		if(this.uploaderType == "html" && this.norm.va == "middle"){
-			dojo.style(this.domNode, "lineHeight", this.norm.lh + "px");
+			domStyle.set(this.domNode, "lineHeight", this.norm.lh + "px");
 		}
 		if(this.showProgress){
 			this.progTextNode.innerHTML = this.progressMessage;
-			dojo.style(this.progTextNode, {
+			domStyle.set(this.progTextNode, {
 				width:this.fhtml.nr.w+"px",
 				height:(this.fhtml.nr.h+0)+"px",
 				padding:"0px",
@@ -478,7 +479,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 				lineHeight:(this.fhtml.nr.h+0)+"px",
 				position:"absolute"
 			});
-			dojo.style(this.progNode, {
+			domStyle.set(this.progNode, {
 				width:this.fhtml.nr.w+"px",
 				height:(this.fhtml.nr.h+0)+"px",
 				padding:"0px",
@@ -492,17 +493,17 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 				backgroundColor:this.progressBackgroundColor
 			});
 		}else{
-			dojo.destroy(this.progNode);
+			domConstruct.destroy(this.progNode);
 		}
-		dojo.style(this.insideNode,{
+		domStyle.set(this.insideNode,{
 			position:"absolute",
 			top:"0px",
 			left:"0px",
 			display:""
 		});
-		dojo.addClass(this.domNode, this.srcNodeRef.className);
+		domClass.add(this.domNode, this.srcNodeRef.className);
 		if(this.fhtml.nr.d.indexOf("inline")>-1){
-			dojo.addClass(this.domNode, "dijitInline");
+			domClass.add(this.domNode, "dijitInline");
 		}
 
 		try{
@@ -515,9 +516,9 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 			//
 			if(this.uploaderType == "flash"){
 			this.insideNode = this.insideNode.parentNode.removeChild(this.insideNode);
-				dojo.body().appendChild(this.insideNode);
+				win.body().appendChild(this.insideNode);
 				this.insideNode.innerHTML = this.fhtml.cn;
-				var c = dojo.connect(this, "onReady", this, function(){ dojo.disconnect(c);
+				var c = connect.connect(this, "onReady", this, function(){ connect.disconnect(c);
 					this.insideNode = this.insideNode.parentNode.removeChild(this.insideNode);
 					this.domNode.appendChild(this.insideNode);
 				});
@@ -526,7 +527,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 			}
 		}
 		if(this._hiddenNode){
-			dojo.style(this._hiddenNode, "display", "none");
+			domStyle.set(this._hiddenNode, "display", "none");
 		}
 	},
 
@@ -581,7 +582,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 
 	onReady: function(/* dojox.form.FileUploader */ uploader){
 		// summary:
-		//		Stub - Fired when dojox.embed.Flash has created the
+		//		Stub - Fired when embedFlash has created the
 		//		Flash object, but it has not necessarilly finished
 		//		downloading, and is ready to be communicated with.
 	},
@@ -599,7 +600,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		//		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 ? dojo.formToObject(form) : null;
+		var data = form ? domForm.toObject(form) : null;
 		this.upload(data);
 		return false; // Boolean
 	},
@@ -622,14 +623,14 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 
 		if(this.progressWidgetId){
 
-			var node = dijit.byId(this.progressWidgetId).domNode;
-			if(dojo.style(node, "display") == "none"){
+			var node = manager.byId(this.progressWidgetId).domNode;
+			if(domStyle.get(node, "display") == "none"){
 				this.restoreProgDisplay = "none";
-				dojo.style(node, "display", "block");
+				domStyle.set(node, "display", "block");
 			}
-			if(dojo.style(node, "visibility") == "hidden"){
+			if(domStyle.get(node, "visibility") == "hidden"){
 				this.restoreProgDisplay = "hidden";
-				dojo.style(node, "visibility", "visible");
+				domStyle.set(node, "visibility", "visible");
 			}
 		}
 
@@ -638,7 +639,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		}
 		this.log("upload type:", this.uploaderType, " - postData:", this.postData);
 
-		for (var i = 0; i < this.fileList.length; i++){
+		for(var i = 0; i < this.fileList.length; i++){
 			var f = this.fileList[i];
 			f.bytesLoaded = 0;
 			f.bytesTotal = f.size || 100000;
@@ -677,12 +678,12 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		if(this.uploaderType == "flash"){
 			this.flashMovie.removeFile(name);
 		}else if(!noListEdit){
-			dojo.destroy(this.fileInputs[i]);
+			domConstruct.destroy(this.fileInputs[i]);
 			this.fileInputs.splice(i,1);
 			this._renumberInputs();
 		}
 		if(this.fileListId){
-			dojo.destroy("file_"+name);
+			domConstruct.destroy("file_"+name);
 		}
 	},
 
@@ -690,20 +691,20 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		//	summary:
 		//		Destroys uploader button
 		if(this.uploaderType == "flash" && !this.flashMovie){
-			this._cons.push(dojo.connect(this, "onLoad", this, "destroy"));
+			this._cons.push(connect.connect(this, "onLoad", this, "destroy"));
 			return;
 		}
-		dojo.forEach(this._subs, dojo.unsubscribe, dojo);
-		dojo.forEach(this._cons, dojo.disconnect, dojo);
+		array.forEach(this._subs, connect.unsubscribe, dojo);
+		array.forEach(this._cons, connect.disconnect, dojo);
 		if(this.scrollConnect){
-			dojo.disconnect(this.scrollConnect);
+			connect.disconnect(this.scrollConnect);
 		}
 		if(this.uploaderType == "flash"){
 			this.flashObject.destroy();
 			delete this.flashObject;
 		}else{
-			dojo.destroy(this._fileInput);
-			dojo.destroy(this._formNode);
+			domConstruct.destroy(this._fileInput);
+			domConstruct.destroy(this._formNode);
 		}
 		this.inherited(arguments);
 	},
@@ -717,20 +718,20 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		//
 		if(display === true){
 			if(this.uploaderType == "flash"){
-				dojo.style(this.insideNode,"top", "-2500px");
+				domStyle.set(this.insideNode,"top", "-2500px");
 			}else{
-				dojo.style(this.insideNode,"display", "none");
+				domStyle.set(this.insideNode,"display", "none");
 			}
-			dojo.style(this.progNode,"display","");
+			domStyle.set(this.progNode,"display","");
 		}else if(display === false){
-			dojo.style(this.insideNode,{
+			domStyle.set(this.insideNode,{
 				display: "",
-				left: "0px"
+				top: "0"
 			});
-			dojo.style(this.progNode,"display","none");
+			domStyle.set(this.progNode,"display","none");
 		}else{
 			var w = display * this.fhtml.nr.w;
-			dojo.style(this.progNode, "width", w + "px");
+			domStyle.set(this.progNode, "width", w + "px");
 		}
 	},
 	_animateProgress: function(){
@@ -738,12 +739,12 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		//		Internal. Animated the built-in progress bar
 		this._displayProgress(true);
 		var _uploadDone = false;
-		var c = dojo.connect(this, "_complete", function(){
-			dojo.disconnect(c);
+		var c = connect.connect(this, "_complete", function(){
+			connect.disconnect(c);
 			_uploadDone = true;
 		});
 		var w = 0;
-		var interval = setInterval(dojo.hitch(this, function(){
+		var interval = setInterval(lang.hitch(this, function(){
 			w+=5;
 			if(w>this.fhtml.nr.w){
 				w = 0;
@@ -753,7 +754,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 
 			if(_uploadDone){
 				clearInterval(interval);
-				setTimeout(dojo.hitch(this, function(){
+				setTimeout(lang.hitch(this, function(){
 					this._displayProgress(false);
 				}), 500);
 			}
@@ -778,21 +779,21 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		//
 		if(this.fileListId){
 			var str = '';
-			dojo.forEach(this.fileList, function(d){
+			array.forEach(this.fileList, function(d){
 				// have to use tables because of IE. Grumble.
 				str += '<table id="file_'+d.name+'" class="fileToUpload"><tr><td class="fileToUploadClose"></td><td class="fileToUploadName">'+d.name+'</td><td class="fileToUploadSize">'+(d.size ? Math.ceil(d.size*.001) +"kb" : "")+'</td></tr></table>'
 			}, this);
-			dojo.byId(this.fileListId).innerHTML = str;
+			dom.byId(this.fileListId).innerHTML = str;
 		}
 	},
 
 	_change: function(dataArray){
 		// summary:
 		//		Internal. Updates uploader selection
-		if(dojo.isIE){
+		if(has("ie")){
 			//IE6 uses the entire path in the name, which isn't terrible, but much different
 			// than everything else
-			dojo.forEach(dataArray, function(f){
+			array.forEach(dataArray, function(f){
 				f.name = f.name.split("\\")[f.name.split("\\").length-1];
 			});
 		}
@@ -821,25 +822,25 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		// summary:
 		//		Internal. Handles tasks after files have finished uploading
 		//
-		dataArray = dojo.isArray(dataArray) ? dataArray : [dataArray];
+		dataArray = lang.isArray(dataArray) ? dataArray : [dataArray];
 
 		// Yes. Yes I do have to do three loops here. ugh.
 		//
 		// Check if one of the files had an error
-		dojo.forEach(dataArray, function(f){
+		array.forEach(dataArray, function(f){
 			if(f.ERROR){ this._error(f.ERROR); }
 		}, this);
 
 		// Have to be set them all too 100%, because
 		// onProgress does not always fire
-		dojo.forEach(this.fileList, function(f){
+		array.forEach(this.fileList, function(f){
 			f.bytesLoaded = 1;
 			f.bytesTotal = 1;
 			f.percent = 100;
 			this._progress(f);
 		}, this);
 		// we're done. remove files.
-		dojo.forEach(this.fileList, function(f){
+		array.forEach(this.fileList, function(f){
 			this.removeFile(f.name, true);
 		}, this);
 
@@ -852,8 +853,8 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 
 		if(this.restoreProgDisplay){
 			// using timeout so prog shows on screen for at least a short time
-			setTimeout(dojo.hitch(this, function(){
-				dojo.style(dijit.byId(this.progressWidgetId).domNode,
+			setTimeout(lang.hitch(this, function(){
+				domStyle.set(manager.byId(this.progressWidgetId).domNode,
 					this.restoreProgDisplay == "none" ? "display" : "visibility",
 					this.restoreProgDisplay
 				);
@@ -867,7 +868,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		//		Internal. Calculate progress
 		var total = 0;
 		var loaded = 0;
-		for (var i = 0; i < this.fileList.length; i++){
+		for(var i = 0; i < this.fileList.length; i++){
 			var f = this.fileList[i];
 			if(f.name == dataObject.name){
 				f.bytesLoaded = dataObject.bytesLoaded;
@@ -880,7 +881,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		}
 		var percent = Math.ceil(loaded / total * 100);
 		if(this.progressWidgetId){
-			dijit.byId(this.progressWidgetId).update({progress:percent+"%"});
+			manager.byId(this.progressWidgetId).update({progress:percent+"%"});
 		}
 		if(this.showProgress){
 			this._displayProgress(percent * .01);
@@ -901,8 +902,8 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 
 		if(this.uploaderType == "flash"){
 			if(!this.flashReady){
-				var _fc = dojo.connect(this, "onLoad", this, function(){
-					dojo.disconnect(_fc);
+				var _fc = connect.connect(this, "onLoad", this, function(){
+					connect.disconnect(_fc);
 					this._setDisabledAttr(disabled);
 				});
 				return;
@@ -911,9 +912,9 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 			this.flashMovie.doDisable(disabled);
 		}else{
 			this._disabled = disabled;
-			dojo.style(this._fileInput, "display", this._disabled ? "none" : "");
+			domStyle.set(this._fileInput, "display", this._disabled ? "none" : "");
 		}
-		dojo.toggleClass(this.domNode, this.disabledClass, disabled);
+		domClass.toggle(this.domNode, this.disabledClass, disabled);
 	},
 
 	_onFlashBlur: function(){
@@ -923,7 +924,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		//		out whom to give focus to next.
 		this.flashMovie.blur();
 		if(!this.nextFocusObject && this.tabIndex){
-			var nodes = dojo.query("[tabIndex]");
+			var nodes = query("[tabIndex]");
 			for(var i = 0; i<nodes.length; i++){
 				if(nodes[i].tabIndex >= Number(this.tabIndex)+1){
 					this.nextFocusObject = nodes[i];
@@ -936,7 +937,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 	_disconnect: function(){
 		// summary:
 		//		Internal. Disconnects fileInput in favor of new one.
-		dojo.forEach(this._cons, dojo.disconnect, dojo);
+		array.forEach(this._cons, connect.disconnect, dojo);
 	},
 
 	/*************************
@@ -955,20 +956,20 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		//		multiple times adding each fileInput
 		//
 		if(this.selectMultipleFiles){
-			dojo.destroy(this._fileInput);
+			domConstruct.destroy(this._fileInput);
 		}
 		this._setHtmlPostData();
 		if(this.showProgress){
 			this._animateProgress();
 		}
-		var dfd = dojo.io.iframe.send({
+		var dfd = ioIframe.send({
 			url: this.uploadUrl.toString(),
 			form: this._formNode,
 			handleAs: "json",
-			error: dojo.hitch(this, function(err){
+			error: lang.hitch(this, function(err){
 				this._error("HTML Upload Error:" + err.message);
 			}),
-			load: dojo.hitch(this, function(data, ioArgs, widgetRef){
+			load: lang.hitch(this, function(data, ioArgs, widgetRef){
 				this._complete(data);
 			})
 		});
@@ -982,7 +983,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		this._buildFileInput();
 		this._connectInput();
 		this._styleContent();
-		dojo.style(this.insideNode, "visibility", "visible");
+		domStyle.set(this.insideNode, "visibility", "visible");
 		this.onReady();
 	},
 
@@ -991,30 +992,30 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		//		Internal. HTML Uploader connections. These get disconnected
 		//		after upload or if multi upload.
 		this._disconnect();
-		this._cons.push(dojo.connect(this._fileInput, "mouseover", this, function(evt){
-			dojo.addClass(this.domNode, this.hoverClass);
+		this._cons.push(connect.connect(this._fileInput, "mouseover", this, function(evt){
+			domClass.add(this.domNode, this.hoverClass);
 			this.onMouseOver(evt);
 		}));
-		this._cons.push(dojo.connect(this._fileInput, "mouseout", this, function(evt){
-			setTimeout(dojo.hitch(this, function(){
-				dojo.removeClass(this.domNode, this.activeClass);
-				dojo.removeClass(this.domNode, this.hoverClass);
+		this._cons.push(connect.connect(this._fileInput, "mouseout", this, function(evt){
+			setTimeout(lang.hitch(this, function(){
+				domClass.remove(this.domNode, this.activeClass);
+				domClass.remove(this.domNode, this.hoverClass);
 				this.onMouseOut(evt);
 				this._checkHtmlCancel("off");
 			}), 0);
 		}));
-		this._cons.push(dojo.connect(this._fileInput, "mousedown", this, function(evt){
-			dojo.addClass(this.domNode, this.activeClass);
-			dojo.removeClass(this.domNode, this.hoverClass);
+		this._cons.push(connect.connect(this._fileInput, "mousedown", this, function(evt){
+			domClass.add(this.domNode, this.activeClass);
+			domClass.remove(this.domNode, this.hoverClass);
 			this.onMouseDown(evt);
 		}));
-		this._cons.push(dojo.connect(this._fileInput, "mouseup", this, function(evt){
-			dojo.removeClass(this.domNode, this.activeClass);
+		this._cons.push(connect.connect(this._fileInput, "mouseup", this, function(evt){
+			domClass.remove(this.domNode, this.activeClass);
 			this.onMouseUp(evt);
 			this.onClick(evt);
 			this._checkHtmlCancel("up");
 		}));
-		this._cons.push(dojo.connect(this._fileInput, "change", this, function(){
+		this._cons.push(connect.connect(this._fileInput, "change", this, function(){
 			this._checkHtmlCancel("change");
 			this._change([{
 				name: this._fileInput.value,
@@ -1023,7 +1024,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 			}]);
 		}));
 		if(this.tabIndex>=0){
-			dojo.attr(this.domNode, "tabIndex", this.tabIndex);
+			domAttr.set(this.domNode, "tabIndex", this.tabIndex);
 		}
 	},
 
@@ -1049,7 +1050,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		//		Internal.Apply style to node
 		var o = this.fhtml.nr;
 
-		dojo.style(this.insideNode, {
+		domStyle.set(this.insideNode, {
 			width:o.w+"px",
 			height:o.va == "middle"?o.h+"px":"auto",
 			textAlign:o.ta,
@@ -1060,7 +1061,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		});
 
 		try{
-			dojo.style(this.insideNode, "lineHeight", "inherit");
+			domStyle.set(this.insideNode, "lineHeight", "inherit");
 		}catch(e){
 			// There are certain cases where IE refuses to set lineHeight.
 			// For the life of me I cannot figure out the combination of
@@ -1074,8 +1075,8 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		//		fileInput.
 		if(this.uploaderType == "html" && this._formNode){
 			this.fileInputs = [];
-			dojo.query("*", this._formNode).forEach(function(n){
-				dojo.destroy(n);
+			query("*", this._formNode).forEach(function(n){
+				domConstruct.destroy(n);
 			});
 			this.fileCount = 0;
 			this._buildFileInput();
@@ -1089,16 +1090,16 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 
 		if(this._formNode){ return; }
 
-		if(dojo.isIE < 9 || (dojo.isIE && dojo.isQuirks)){
+		if(has("ie") < 9 || (has("ie") && has("quirks"))){
 			this._formNode = document.createElement('<form enctype="multipart/form-data" method="post">');
 			this._formNode.encoding = "multipart/form-data";
-			this._formNode.id = dijit.getUniqueId("FileUploaderForm"); // needed for dynamic style
+			this._formNode.id = manager.getUniqueId("FileUploaderForm"); // needed for dynamic style
 			this.domNode.appendChild(this._formNode);
 		}else{
-			this._formNode = dojo.create('form', {
+			this._formNode = domConstruct.create('form', {
 				enctype:"multipart/form-data",
 				method:"post",
-				id:dijit.getUniqueId("FileUploaderForm")
+				id:manager.getUniqueId("FileUploaderForm")
 			}, this.domNode);
 		}
 	},
@@ -1114,7 +1115,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 			//	reference to it and can't remove it from
 			//	the upload list.
 			this._fileInput.id = this._fileInput.id + this.fileCount;
-			dojo.style(this._fileInput, "display", "none");
+			domStyle.set(this._fileInput, "display", "none");
 		}
 		this._fileInput = document.createElement('input');
 		this.fileInputs.push(this._fileInput);
@@ -1127,16 +1128,16 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 			this.fileCount++;
 		}
 
-		dojo.attr(this._fileInput, {
+		domAttr.set(this._fileInput, {
 			id:this.id,
 			name:nm,
 			type:"file"
 		});
 
-		dojo.addClass(this._fileInput, "dijitFileInputReal");
+		domClass.add(this._fileInput, "dijitFileInputReal");
 		this._formNode.appendChild(this._fileInput);
-		var real = dojo.marginBox(this._fileInput);
-		dojo.style(this._fileInput, {
+		var real = domGeometry.getMarginBox(this._fileInput);
+		domStyle.set(this._fileInput, {
 			position:"relative",
 			left:(this.fhtml.nr.w - real.w) + "px",
 			opacity:0
@@ -1147,10 +1148,10 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		if(!this.selectMultipleFiles){ return; }
 		var nm;
 		this.fileCount = 0;
-		dojo.forEach(this.fileInputs, function(inp){
+		array.forEach(this.fileInputs, function(inp){
 			nm = this.htmlFieldName + this.fileCount;
 			this.fileCount++;
-			dojo.attr(inp, "name", nm);
+			domAttr.set(inp, "name", nm);
 		}, this);
 	},
 
@@ -1159,20 +1160,20 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		//		Apply a dynamic style to the form and input
 		var size = Math.max(2, Math.max(Math.ceil(this.fhtml.nr.w / 60), Math.ceil(this.fhtml.nr.h / 15)));
 		// Now create a style associated with the form ID
-		dojox.html.insertCssRule("#" + this._formNode.id + " input", "font-size:" + size + "em");
-		dojo.style(this.domNode, {
+		htmlStyles.insertCssRule("#" + this._formNode.id + " input", "font-size:" + size + "em");
+		domStyle.set(this.domNode, {
 			overflow:"hidden",
 			position:"relative"
 		});
-		dojo.style(this.insideNode, "position", "absolute");
+		domStyle.set(this.insideNode, "position", "absolute");
 	},
 
 	_setHtmlPostData: function(){
 		// summary:
 		//		Internal.Apply postData to hidden fields in form
 		if(this.postData){
-			for (var nm in this.postData){
-				dojo.create("input", {
+			for(var nm in this.postData){
+				domConstruct.create("input", {
 					type: "hidden",
 					name: nm,
 					value: this.postData[nm]
@@ -1190,8 +1191,8 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		try{
 			if(this.showProgress){
 				this._displayProgress(true);
-				var c = dojo.connect(this, "_complete", this, function(){
-					dojo.disconnect(c);
+				var c = connect.connect(this, "_complete", this, function(){
+					connect.disconnect(c);
 					this._displayProgress(false);
 				});
 			}
@@ -1248,8 +1249,8 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 				id: this.id,
 				isDebug: this.isDebug,
 				devMode:this.devMode,
-				flashButton:dojox.embed.flashVars.serialize("fh", this.fhtml),
-				fileMask:dojox.embed.flashVars.serialize("fm", this.fileMask),
+				flashButton:embedFlashVars.serialize("fh", this.fhtml),
+				fileMask:embedFlashVars.serialize("fm", this.fileMask),
 				noReturnCheck: this.skipServerCheck,
 				serverTimeout:this.serverTimeout
 			},
@@ -1262,16 +1263,16 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 
 		};
 
-		this.flashObject = new dojox.embed.Flash(args, this.insideNode);
-		this.flashObject.onError = dojo.hitch(function(msg){
+		this.flashObject = new embedFlash(args, this.insideNode);
+		this.flashObject.onError = lang.hitch(function(msg){
 			this._error("Flash Error: " + msg);
 		});
-		this.flashObject.onReady = dojo.hitch(this, function(){
-			dojo.style(this.insideNode, "visibility", "visible");
+		this.flashObject.onReady = lang.hitch(this, function(){
+			domStyle.set(this.insideNode, "visibility", "visible");
 			this.log("FileUploader flash object ready");
 			this.onReady(this);
 		});
-		this.flashObject.onLoad = dojo.hitch(this, function(mov){
+		this.flashObject.onLoad = lang.hitch(this, function(mov){
 			this.flashMovie = mov;
 			this.flashReady = true;
 
@@ -1308,14 +1309,14 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 			this.flashMovie.doFocus();
 		});
 		if(this.tabIndex>=0){
-			dojo.attr(this.domNode, "tabIndex", this.tabIndex);
+			domAttr.set(this.domNode, "tabIndex", this.tabIndex);
 		}
 	},
 
 	_doSub: function(subStr, funcStr){
 		// summary:
 		//		Internal. Shortcut for subscribes to Flash movie
-		this._subs.push(dojo.subscribe(this.id + subStr, this, funcStr));
+		this._subs.push(connect.subscribe(this.id + subStr, this, funcStr));
 	},
 
 	/*************************************
@@ -1339,43 +1340,43 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 	getTextStyle: function(node){
 		// getting font info
 		var o = {};
-		o.ff = dojo.style(node, "fontFamily");
+		o.ff = domStyle.get(node, "fontFamily");
 		if(o.ff){
 			o.ff = o.ff.replace(", ", ","); // remove spaces. IE in Flash no likee
 			o.ff = o.ff.replace(/\"|\'/g, "");
 			o.ff = o.ff == "sans-serif" ? "Arial" : o.ff; // Flash doesn't know what sans-serif is
-			o.fw = dojo.style(node, "fontWeight");
-			o.fi = dojo.style(node, "fontStyle");
-			o.fs = parseInt(dojo.style(node, "fontSize"), 10);
-			if(dojo.style(node, "fontSize").indexOf("%") > -1){
+			o.fw = domStyle.get(node, "fontWeight");
+			o.fi = domStyle.get(node, "fontStyle");
+			o.fs = parseInt(domStyle.get(node, "fontSize"), 10);
+			if(domStyle.get(node, "fontSize").indexOf("%") > -1){
 				// IE doesn't convert % to px. For god sakes.
 				var n = node;
 				while(n.tagName){
-					if(dojo.style(n, "fontSize").indexOf("%") == -1){
-						o.fs = parseInt(dojo.style(n, "fontSize"), 10);
+					if(domStyle.get(n, "fontSize").indexOf("%") == -1){
+						o.fs = parseInt(domStyle.get(n, "fontSize"), 10);
 						break;
 					}
 					if(n.tagName.toLowerCase()=="body"){
 						// if everyting is %, the the font size is 16px * the %
-						o.fs = 16 * .01 * parseInt(dojo.style(n, "fontSize"), 10);
+						o.fs = 16 * .01 * parseInt(domStyle.get(n, "fontSize"), 10);
 					}
 					n = n.parentNode;
 				}
 			}
-			o.fc = new dojo.Color(dojo.style(node, "color")).toHex();
+			o.fc = new Color(domStyle.get(node, "color")).toHex();
 			o.fc = parseInt(o.fc.substring(1,Infinity),16);
 		}
-		o.lh = dojo.style(node, "lineHeight");
-		o.ta = dojo.style(node, "textAlign");
+		o.lh = domStyle.get(node, "lineHeight");
+		o.ta = domStyle.get(node, "textAlign");
 		o.ta = o.ta == "start" || !o.ta ? "left" : o.ta;
-		o.va = this.isButton(node) ? "middle" : o.lh == o.h ? "middle" : dojo.style(node, "verticalAlign");
+		o.va = this.isButton(node) ? "middle" : o.lh == o.h ? "middle" : domStyle.get(node, "verticalAlign");
 		return o;
 	},
 
 	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.
-		var cn = dojo.trim(node.innerHTML);
+		var cn = lang.trim(node.innerHTML);
 		if(cn.indexOf("<") >- 1){
 			cn = escape(cn);
 		}
@@ -1386,34 +1387,34 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		// getting the style of a node. Using very abbreviated characters which the
 		//	Flash movie understands.
 		var o = {};
-		var dim = dojo.contentBox(node);
-		var pad = dojo._getPadExtents(node);
+		var dim = domGeometry.getContentBox(node);
+		var pad = domGeometry.getPadExtents(node);
 		o.p = [pad.t, pad.w-pad.l, pad.h-pad.t, pad.l];
 		o.w = dim.w + pad.w;
 		o.h = dim.h + pad.h;
-		o.d = dojo.style(node, "display");
-		var clr = new dojo.Color(dojo.style(node, "backgroundColor"));
+		o.d = domStyle.get(node, "display");
+		var clr = new Color(domStyle.get(node, "backgroundColor"));
 		// if no color, Safari sets #000000 and alpha=0 since we don't support alpha,
 		// it makes black - make it white
 		o.bc = clr.a == 0 ? "#ffffff" : clr.toHex();
 		o.bc = parseInt(o.bc.substring(1,Infinity),16);
-		var url = this.urlencode(dojo.style(node, "backgroundImage"));
+		var url = this.urlencode(domStyle.get(node, "backgroundImage"));
 		if(url){
 			o.bi = {
 				url:url,
-				rp:dojo.style(node, "backgroundRepeat"),
-				pos: escape(dojo.style(node, "backgroundPosition"))
+				rp:domStyle.get(node, "backgroundRepeat"),
+				pos: escape(domStyle.get(node, "backgroundPosition"))
 			};
 			if(!o.bi.pos){
 				// IE does Xpx and Ypx, not "X% Y%"
-				var rx = dojo.style(node, "backgroundPositionX");
-				var ry = dojo.style(node, "backgroundPositionY");
+				var rx = domStyle.get(node, "backgroundPositionX");
+				var ry = domStyle.get(node, "backgroundPositionY");
 				rx = (rx == "left") ? "0%" : (rx == "right") ? "100%" : rx;
 				ry = (ry == "top") ? "0%" : (ry == "bottom") ? "100%" : ry;
 				o.bi.pos = escape(rx+" "+ry);
 			}
 		}
-		return dojo.mixin(o, this.getTextStyle(node));
+		return lang.mixin(o, this.getTextStyle(node));
 	},
 
 	getTempNodeStyle: function(node, _class, isDijitButton){
@@ -1421,21 +1422,23 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		var temp, style;
 		if(isDijitButton){
 			// backwards compat until dojo 1.5
-			temp = dojo.place("<"+node.tagName+"><span>"+node.innerHTML+"</span></"+node.tagName+">", node.parentNode); //+" "+_class+"
+			temp = domConstruct.place("<"+node.tagName+"><span>"+node.innerHTML+"</span></"+node.tagName+">", node.parentNode); //+" "+_class+"
 			var first = temp.firstChild;
-			dojo.addClass(first, node.className);
-			dojo.addClass(temp, _class);
+			domClass.add(first, node.className);
+			domClass.add(temp, _class);
 			style = this.getStyle(first);
 		}else{
-			temp = dojo.place("<"+node.tagName+">"+node.innerHTML+"</"+node.tagName+">", node.parentNode);
-			dojo.addClass(temp, node.className);
-			dojo.addClass(temp, _class);
+			temp = domConstruct.place("<"+node.tagName+">"+node.innerHTML+"</"+node.tagName+">", node.parentNode);
+			domClass.add(temp, node.className);
+			domClass.add(temp, _class);
 			temp.id = node.id;
 			style = this.getStyle(temp);
 		}
 		// dev note: comment out this line to see what the
 		// button states look like to the FileUploader
-		dojo.destroy(temp);
+		domConstruct.destroy(temp);
 		return style;
 	}
 });
+return dojox.form.FileUploader;
+});
diff --git a/dojox/form/ListInput.js b/dojox/form/ListInput.js
index f2e31b6..a9c8332 100755
--- a/dojox/form/ListInput.js
+++ b/dojox/form/ListInput.js
@@ -1,111 +1,130 @@
-dojo.experimental("dojox.form.ListInput");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/json",
+	"dojo/_base/fx",
+	"dojo/_base/window",
+	"dojo/_base/connect",
+	"dojo/dom-class",
+	"dojo/dom-style",
+	"dojo/dom-construct",
+	"dojo/dom-geometry",
+	"dojo/keys",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dijit/form/_FormValueWidget",
+	"dijit/form/ValidationTextBox",
+	"dijit/InlineEditBox",
+	"dojo/i18n!dijit/nls/common",
+	"dojo/_base/declare"
+], 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");
 
-dojo.provide("dojox.form.ListInput");
-
-dojo.require("dijit.form._FormWidget");
-dojo.require("dijit.form.ValidationTextBox");
-dojo.require("dijit.InlineEditBox");
-dojo.requireLocalization("dijit", "common");
-
-dojo.declare("dojox.form.ListInput",
-	[dijit.form._FormValueWidget],
+	/*=====
+		Widget = dijit._Widget;
+		Templated = dijit._TemplatedMixin;
+		FormValueWidget = dijit.form._FormValueWidget;
+		ValidationTextBox = dijit.form.ValidationTextBox;
+	=====*/
+var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 	{
 	// summary:
 	//		An automatic list maker
 	// description:
 	//		you can add value to list with add method.
 	//		you can only remove by clicking close button
-	
+
 	constructor: function(){
 		this._items = [];
-		
-		
-		if(!dojo.isArray(this.delimiter)){
+
+
+		if(!lang.isArray(this.delimiter)){
 			this.delimiter=[this.delimiter];
 		}
 		var r="("+this.delimiter.join("|")+")?";
 		this.regExp="^"+this.regExp+r+"$";
 	},
-	
+
 	// inputClass: String
 	//		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
 	inputClass: "dojox.form._ListInputInputBox",
-	
+
 	// 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
 	//		Properties used to create input box
 	//		If String, it must be a valid JSON
 	inputProperties: {
 		minWidth:50
 	},
-	
+
 	// submitOnlyValidValue: Boolean
 	//		If true, only valid value will be submited with form
 	submitOnlyValidValue:true,
-	
+
 	// useOnBlur: Boolean
 	//		If true, onBlur event do a validate (like pressing ENTER)
 	useOnBlur:true,
-	
+
 	// readOnlyInput: Boolean
 	//		if false, the list will be editable
 	//		Can only be set when instanciate
 	readOnlyInput: false,
-	
+
 	// maxItems: Int
 	//		Specify max item the list can have
 	//		null = infiny
 	maxItems: null,
-	
+
 	// showCloseButtonWhenValid: Boolean
 	//		if true, a close button will be added on valid item
 	showCloseButtonWhenValid: true,
-	
+
 	// showCloseButtonWhenInvalid: Boolean
 	//		if true, a close button will be added on invalid item
 	showCloseButtonWhenInvalid: true,
-	
+
 	// regExp: [extension protected] String
 	//		regular expression string used to validate the input
 	//		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: ",",
-	
-	// constraints: dijit.form.ValidationTextBox.__Constraints
+
+	// constraints: ValidationTextBox.__Constraints
 	//		user-defined object needed to pass parameters to the validator functions
 	constraints: {},
 
 	baseClass:"dojoxListInput",
-	
+
 	type: "select",
-	
+
 	value: "",
-	
+
 	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>",
-	
+
 	// useAnim: Boolean
 	//		If true, then item will use an anime to show hide itself
 	useAnim: true,
-	
+
 	// duration: Integer
 	//		Animation duration
 	duration: 500,
-	
+
 	// easingIn: function
 	//		function used to easing on fadeIn end
 	easingIn: null,
-	
+
 	// easingOut: function
 	//		function used to easing on fadeOut end
 	easingOut: null,
@@ -114,40 +133,40 @@ dojo.declare("dojox.form.ListInput",
 	//		If true, items can be edited
 	//		Can only be set when instanciate
 	readOnlyItem: false,
-	
+
 	// useArrowForEdit: Boolean
 	//		If true, arraow left and right can be used for editing
 	//		Can only be set when instanciate
 	useArrowForEdit: true,
-	
+
 	// _items: Array
 	//		Array of widget.
 	//		Contain all reference to _ListInputInputItem
 	_items: null,
-	
+
 	// _lastAddedItem: Widget
 	//		Contain a reference to the last created item
 	_lastAddedItem: null,
-	
+
 	// _currentItem: Widget
 	//		Widget currently in edition
 	_currentItem: null,
-	
+
 	// _input: Widget
 	//		Widget use for input box
 	_input: null,
-	
+
 	// _count: Int
 	//		Count items
 	_count: 0,
-	
+
 	postCreate: function(){
 		// summary:
 		//		If closeButton is used, add a class
 		this.inherited(arguments);
 		this._createInputBox();
 	},
-	
+
 	_setReadOnlyInputAttr: function(/*Boolean*/value){
 		// summary:
 		//		Change status and if needed, create the inputbox
@@ -157,7 +176,7 @@ dojo.declare("dojox.form.ListInput",
 		this.readOnlyInput = value;
 		this._createInputBox();
 	},
-	
+
 	_setReadOnlyItemAttr: function(/*Boolean*/value){
 		// summary:
 		//		set read only items
@@ -168,43 +187,43 @@ dojo.declare("dojox.form.ListInput",
 			this._items[i].set("readOnlyItem", value);
 		}
 	},
-	
+
 	_createInputBox: function(){
 		// summary:
 		//		Create the input box
 		// tags:
 		//		private
-		dojo.toggleClass(this._inputNode, "dijitHidden", this.readOnlyInput);
+		domClass.toggle(this._inputNode, "dijitHidden", this.readOnlyInput);
 		if(this.readOnlyInput){ return; }
 		if(this._input){ return; }
-				
+
 		if(this.inputHandler === null){
 			console.warn("you must add some handler to connect to input field");
 			return false;
 		}
-		if(dojo.isString(this.inputHandler)){
+		if(lang.isString(this.inputHandler)){
 			this.inputHandler = this.inputHandler.split(",");
 		}
-		if(dojo.isString(this.inputProperties)){
-			this.inputProperties = dojo.fromJson(this.inputProperties);
+		if(lang.isString(this.inputProperties)){
+			this.inputProperties = jsonUtil.fromJson(this.inputProperties);
 		}
-		
 
-		var input = dojo.getObject(this.inputClass, false);
-		
+
+		var input = lang.getObject(this.inputClass, false);
+
 		this.inputProperties.regExp = this.regExpGen(this.constraints);
-		
+
 		this._input = new input(this.inputProperties);
 		this._input.startup();
 		this._inputNode.appendChild(this._input.domNode);
-		dojo.forEach(this.inputHandler, function(handler){
-			this.connect(this._input,dojo.string.trim(handler),"_onHandler");
+		array.forEach(this.inputHandler, function(handler){
+			this.connect(this._input,lang.trim(handler),"_onHandler");
 		},this);
-	
+
 		this.connect(this._input, "onKeyDown", "_inputOnKeyDown");
 		this.connect(this._input, "onBlur", "_inputOnBlur");
 	},
-	
+
 	compare: function(/*Array*/val1,/*Array*/val2){
 		// summary:
 		//		Compare 2 values (as returned by attr('value') for this widget).
@@ -220,17 +239,17 @@ dojo.declare("dojox.form.ListInput",
 			return 0;
 		}
 	},
-	
+
 	add: function(/*String || Array*/values){
 		// summary:
 		//		Create new list element
 		if(this._count>=this.maxItems && this.maxItems !== null){return;}
 		this._lastValueReported = this._getValues();
-		
-		if(!dojo.isArray(values)){
+
+		if(!lang.isArray(values)){
 			values = [values];
 		}
-		
+
 		for(var i in values){
 			var value=values[i];
 			if(value === "" || typeof value != "string"){
@@ -239,58 +258,58 @@ dojo.declare("dojox.form.ListInput",
 			this._count++;
 			var re = new RegExp(this.regExpGen(this.constraints));
 
-			this._lastAddedItem = new dojox.form._ListInputInputItem({
+			this._lastAddedItem = new _ListInputInputItem({
 				"index" : this._items.length,
 				readOnlyItem : this.readOnlyItem,
 				value : value,
 				regExp: this.regExpGen(this.constraints)
 			});
 			this._lastAddedItem.startup();
-			
+
 			this._testItem(this._lastAddedItem,value);
-			
-			this._lastAddedItem.onClose = dojo.hitch(this,"_onItemClose",this._lastAddedItem);
-			this._lastAddedItem.onChange = dojo.hitch(this,"_onItemChange",this._lastAddedItem);
-			this._lastAddedItem.onEdit = dojo.hitch(this,"_onItemEdit",this._lastAddedItem);
-			this._lastAddedItem.onKeyDown = dojo.hitch(this,"_onItemKeyDown",this._lastAddedItem);
+
+			this._lastAddedItem.onClose = lang.hitch(this,"_onItemClose",this._lastAddedItem);
+			this._lastAddedItem.onChange = lang.hitch(this,"_onItemChange",this._lastAddedItem);
+			this._lastAddedItem.onEdit = lang.hitch(this,"_onItemEdit",this._lastAddedItem);
+			this._lastAddedItem.onKeyDown = lang.hitch(this,"_onItemKeyDown",this._lastAddedItem);
 
 			if(this.useAnim){
-				dojo.style(this._lastAddedItem.domNode, {opacity:0, display:""});
+				domStyle.set(this._lastAddedItem.domNode, {opacity:0, display:""});
 			}
 
 			this._placeItem(this._lastAddedItem.domNode);
-			
+
 			if(this.useAnim){
-				var anim = dojo.fadeIn({
+				var anim = fx.fadeIn({
 					node : this._lastAddedItem.domNode,
 					duration : this.duration,
 					easing : this.easingIn
 				}).play();
 			}
-			
+
 			this._items[this._lastAddedItem.index] = this._lastAddedItem;
-			
+
 			if(this._onChangeActive && this.intermediateChanges){ this.onChange(value); }
-			
+
 			if(this._count>=this.maxItems && this.maxItems !== null){
 				break;
 			}
 		}
-		
+
 		this._updateValues();
 		if(this._lastValueReported.length==0){
 			this._lastValueReported = this.value;
 		}
-		
+
 		if(!this.readOnlyInput){
 			this._input.set("value", "");
 		}
-		
+
 		if(this._onChangeActive){ this.onChange(this.value); }
-		
+
 		this._setReadOnlyWhenMaxItemsReached();
 	},
-	
+
 	_setReadOnlyWhenMaxItemsReached: function(){
 		// summary:
 		//		set input to readonly when max is reached
@@ -298,32 +317,32 @@ dojo.declare("dojox.form.ListInput",
 		//		private
 		this.set("readOnlyInput",(this._count>=this.maxItems && this.maxItems !== null));
 	},
-	
+
 	_setSelectNode: function(){
 		// summary:
 		//		put all item in the select (for a submit)
 		// tags:
 		//		private
 		this._selectNode.options.length = 0;
-		
+
 		var values=this.submitOnlyValidValue?this.get("MatchedValue"):this.value;
-		
-		if(!dojo.isArray(values)){
+
+		if(!lang.isArray(values)){
 			return;
 		}
-		dojo.forEach(values,function(item){
+		array.forEach(values,function(item){
 			this._selectNode.options[this._selectNode.options.length]=new Option(item,item,true,true);
 		},this);
 	},
-	
+
 	_placeItem: function(/*domNode*/node){
 		// summary:
 		//		Place item in the list
 		// tags:
 		//		private
-		dojo.place(node,this._inputNode,"before");
+		domConstruct.place(node,this._inputNode,"before");
 	},
-	
+
 	_getCursorPos: function(/*domNode*/node){
 		// summary:
 		//		get current cursor pos
@@ -332,51 +351,51 @@ dojo.declare("dojox.form.ListInput",
 		if(typeof node.selectionStart != 'undefined'){
 			return node.selectionStart;
 		}
-		
+
 		// IE Support
 		try{ node.focus(); }catch(e){}
 		var range = node.createTextRange();
-		range.moveToBookmark(dojo.doc.selection.createRange().getBookmark());
+		range.moveToBookmark(win.doc.selection.createRange().getBookmark());
 		range.moveEnd('character', node.value.length);
 		try{
 			return node.value.length - range.text.length;
 		}finally{ range=null; }
 	},
-	
+
 	_onItemClose: function(/*dijit._Widget*/ item){
 		// summary:
 		//		Destroy a list element when close button is clicked
 		// tags:
 		//		private
 		if(this.disabled){ return; }
-		
+
 		if(this.useAnim){
-			var anim = dojo.fadeOut({
+			var anim = fx.fadeOut({
 				node : item.domNode,
 				duration : this.duration,
 				easing : this.easingOut,
-				onEnd : dojo.hitch(this, "_destroyItem", item)
+				onEnd : lang.hitch(this, "_destroyItem", item)
 			}).play();
 		}else{
 			this._destroyItem(item);
 		}
 	},
-	
+
 	_onItemKeyDown:  function(/*dijit._Widget*/ item, /*Event*/ e){
 		// summary:
 		//		Call when item get a keypress
 		// tags:
 		//		private
 		if(this.readOnlyItem || !this.useArrowForEdit){ return; }
-		
-		if(e.keyCode == dojo.keys.LEFT_ARROW && this._getCursorPos(e.target)==0){
+
+		if(e.keyCode == keys.LEFT_ARROW && this._getCursorPos(e.target)==0){
 			this._editBefore(item);
-		}else if(e.keyCode == dojo.keys.RIGHT_ARROW && this._getCursorPos(e.target)==e.target.value.length){
+		}else if(e.keyCode == keys.RIGHT_ARROW && this._getCursorPos(e.target)==e.target.value.length){
 			this._editAfter(item);
 		}
 	},
-	
-	_editBefore: function(/*widget*/item) {
+
+	_editBefore: function(/*widget*/item){
 		// summary:
 		//		move trough items
 		// tags:
@@ -386,7 +405,7 @@ dojo.declare("dojox.form.ListInput",
 			this._currentItem.edit();
 		}
 	},
-	_editAfter: function(/*widget*/item) {
+	_editAfter: function(/*widget*/item){
 		// summary:
 		//		move trough items
 		// tags:
@@ -395,7 +414,7 @@ dojo.declare("dojox.form.ListInput",
 		if(this._currentItem !== null){
 			this._currentItem.edit();
 		}
-		
+
 		if(!this.readOnlyInput){
 			if(this._currentItem === null){
 				//no more item ?
@@ -404,7 +423,7 @@ dojo.declare("dojox.form.ListInput",
 			}
 		}
 	},
-	
+
 	_onItemChange: function(/*dijit._Widget*/ item, /*String*/ value){
 		// summary:
 		//		Call when item value change
@@ -412,42 +431,42 @@ dojo.declare("dojox.form.ListInput",
 		//		private
 
 		value = value || item.get("value");
-		
+
 		//revalidate content
 		this._testItem(item,value);
-		
+
 		//update value
 		this._updateValues();
 	},
-	
+
 	_onItemEdit: function(/*dijit._Widget*/ item){
 		// summary:
 		//		Call when item is edited
 		// tags:
 		//		private
-		dojo.removeClass(item.domNode,["dijitError", this.baseClass + "Match", this.baseClass + "Mismatch"]);
+		domClass.remove(item.domNode,["dijitError", this.baseClass + "Match", this.baseClass + "Mismatch"]);
 	},
-	
+
 	_testItem: function(/*Object*/item,/*String*/value){
 		// summary:
 		//		Change class of item (match, mismatch)
 		// tags:
 		//		private
 		var re = new RegExp(this.regExpGen(this.constraints));
-		var match = value.match(re);
-		
-		dojo.removeClass(item.domNode, this.baseClass + (!match ? "Match" : "Mismatch"));
-		dojo.addClass(item.domNode, this.baseClass + (match ? "Match" : "Mismatch"));
-		dojo.toggleClass(item.domNode, "dijitError", !match);
-		
+		var match = ('' + value).match(re);
+
+		domClass.remove(item.domNode, this.baseClass + (!match ? "Match" : "Mismatch"));
+		domClass.add(item.domNode, this.baseClass + (match ? "Match" : "Mismatch"));
+		domClass.toggle(item.domNode, "dijitError", !match);
+
 		if((this.showCloseButtonWhenValid && match) ||
 			(this.showCloseButtonWhenInvalid && !match)){
-			dojo.addClass(item.domNode,this.baseClass+"Closable");
+			domClass.add(item.domNode,this.baseClass+"Closable");
 		}else {
-			dojo.removeClass(item.domNode,this.baseClass+"Closable");
+			domClass.remove(item.domNode,this.baseClass+"Closable");
 		}
 	},
-	
+
 	_getValueAttr: function(){
 		// summary:
 		//		get all value in then list and return an array
@@ -455,7 +474,7 @@ dojo.declare("dojox.form.ListInput",
 		//		private
 		return this.value;
 	},
-	
+
 	_setValueAttr: function(/*Array || String*/ newValue){
 		// summary:
 		//		Hook so attr('value', value) works.
@@ -464,17 +483,17 @@ dojo.declare("dojox.form.ListInput",
 		//		If the value has changed, then fire onChange event, unless priorityChange
 		//		is specified as null (or false?)
 		this._destroyAllItems();
-		
+
 		this.add(this._parseValue(newValue));
 	},
-	
+
 	_parseValue: function(/*String*/newValue){
 		// summary:
 		//		search for delemiters and split if needed
 		// tags:
 		//		private
 		if(typeof newValue == "string"){
-			if(dojo.isString(this.delimiter)){
+			if(lang.isString(this.delimiter)){
 				this.delimiter = [this.delimiter];
 			}
 			var re = new RegExp("^.*("+this.delimiter.join("|")+").*");
@@ -485,8 +504,8 @@ dojo.declare("dojox.form.ListInput",
 		}
 		return newValue;
 	},
-	
-	regExpGen: function(/*dijit.form.ValidationTextBox.__Constraints*/constraints){
+
+	regExpGen: function(/*ValidationTextBox.__Constraints*/constraints){
 		// summary:
 		//		Overridable function used to generate regExp when dependent on constraints.
 		//		Do not specify both regExp and regExpGen.
@@ -494,7 +513,7 @@ dojo.declare("dojox.form.ListInput",
 		//		extension protected
 		return this.regExp;     // String
 	},
-	
+
 	_setDisabledAttr: function(/*Boolean*/ value){
 		// summary:
 		//		also enable/disable editable items
@@ -505,24 +524,24 @@ dojo.declare("dojox.form.ListInput",
 				this._items[i].set("disabled", value);
 			}
 		}
-		
+
 		if(!this.readOnlyInput){
 			this._input.set("disabled", value);
 		}
 		this.inherited(arguments);
 	},
-	
+
 	_onHandler: function(/*String*/value){
 		// summary:
 		//		When handlers of input are fired, this method check input value and (if needed) modify it
 		// tags:
 		//		private
 		var parsedValue = this._parseValue(value);
-		if(dojo.isArray(parsedValue)){
+		if(lang.isArray(parsedValue)){
 			this.add(parsedValue);
 		}
 	},
-	
+
 	_onClick:  function(/*event*/e){
 		// summary:
 		//		give focus to inputbox
@@ -530,7 +549,7 @@ dojo.declare("dojox.form.ListInput",
 		//		private
 		this._focusInput();
 	},
-	
+
 	_focusInput: function(){
 		// summary:
 		//		give focus to input
@@ -548,17 +567,17 @@ dojo.declare("dojox.form.ListInput",
 		//		private
 		this._currentItem = null;
 		var val = this._input.get("value");
-		
-		if(e.keyCode == dojo.keys.BACKSPACE && val == "" && this.get("lastItem")){
+
+		if(e.keyCode == keys.BACKSPACE && val == "" && this.get("lastItem")){
 			this._destroyItem(this.get("lastItem"));
-		}else if(e.keyCode == dojo.keys.ENTER && val != ""){
+		}else if(e.keyCode == keys.ENTER && val != ""){
 			this.add(val);
-		}else if(e.keyCode == dojo.keys.LEFT_ARROW && this._getCursorPos(this._input.focusNode) == 0 &&
+		}else if(e.keyCode == keys.LEFT_ARROW && this._getCursorPos(this._input.focusNode) == 0 &&
 			!this.readOnlyItem && this.useArrowForEdit){
 				this._editBefore();
 		}
 	},
-	
+
 	_inputOnBlur: function(){
 		// summary:
 		//		Remove focus class and act like pressing ENTER key
@@ -569,23 +588,23 @@ dojo.declare("dojox.form.ListInput",
 			this.add(val);
 		}
 	},
-	
+
 	_getMatchedValueAttr: function(){
 		// summary:
 		//		get value that match regexp in then list and return an array
 		// tags:
 		//		private
-		return this._getValues(dojo.hitch(this,this._matchValidator));
+		return this._getValues(lang.hitch(this,this._matchValidator));
 	},
-	
+
 	_getMismatchedValueAttr: function(){
 		// summary:
 		//		get value that mismatch regexp in then list and return an array
 		// tags:
 		//		private
-		return this._getValues(dojo.hitch(this,this._mismatchValidator));
+		return this._getValues(lang.hitch(this,this._mismatchValidator));
 	},
-	
+
 	_getValues: function(/*function*/validator){
 		// summary:
 		//		return values with comparator constraint
@@ -605,7 +624,7 @@ dojo.declare("dojox.form.ListInput",
 		}
 		return value;
 	},
-	
+
 	_nullValidator: function(/*String*/itemValue){
 		// summary:
 		//		return true or false
@@ -629,7 +648,7 @@ dojo.declare("dojox.form.ListInput",
 		var re = new RegExp(this.regExpGen(this.constraints));
 		return !(itemValue.match(re));
 	},
-	
+
 	_getLastItemAttr: function(){
 		// summary:
 		//		return the last item in list
@@ -644,18 +663,18 @@ dojo.declare("dojox.form.ListInput",
 		//		private
 		item=item||false;
 		position=position||"last";
-		
+
 		var lastItem = null;
 		var stop=-1;
 		for(var i in this._items){
 			if(this._items[i] === null){ continue; }
-			
+
 			if(position=="before" && this._items[i] === item){
 				break;
 			}
-			
+
 			lastItem = this._items[i];
-			
+
 			if(position=="first" ||stop==0){
 				stop=1;
 				break;
@@ -683,7 +702,7 @@ dojo.declare("dojox.form.ListInput",
 		//		private
 		return this._getSomeItem(item,"after");
 	},
-	
+
 	_destroyItem: function(/*dijit._Widget*/ item, /*Boolean?*/ updateValue){
 		// summary:
 		//		destroy an item
@@ -697,7 +716,7 @@ dojo.declare("dojox.form.ListInput",
 			this._setReadOnlyWhenMaxItemsReached();
 		}
 	},
-	
+
 	_updateValues: function(){
 		// summary:
 		//		update this.value and the select node
@@ -706,7 +725,7 @@ dojo.declare("dojox.form.ListInput",
 		this.value = this._getValues();
 		this._setSelectNode();
 	},
-	
+
 	_destroyAllItems: function(){
 		// summary:
 		//		destroy all items
@@ -722,95 +741,94 @@ dojo.declare("dojox.form.ListInput",
 		this._setSelectNode();
 		this._setReadOnlyWhenMaxItemsReached();
 	},
-	
+
 	destroy: function(){
 		// summary:
 		//		Destroy all widget
 		this._destroyAllItems();
 		this._lastAddedItem = null;
-		
+
 		if(!this._input){
 			this._input.destroy();
 		}
-		
+
 		this.inherited(arguments);
 	}
 });
 
-dojo.declare("dojox.form._ListInputInputItem",
-	[dijit._Widget, dijit._Templated],
+var _ListInputInputItem = declare("dojox.form._ListInputInputItem", [Widget, TemplatedMixin],
 	{
 	// summary:
 	//	Item created by ListInputInput when delimiter is found
 	// description:
 	//		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>",
-	
+
 	// closeButtonNode: domNode
 	//		ref to the close button node
 	closeButtonNode: null,
-	
+
 	// readOnlyItem: Boolean
 	//		if true, item is editable
 	readOnlyItem: true,
-	
+
 	baseClass:"dojoxListInputItem",
-	
+
 	// value: String
 	//		value of item
 	value: "",
-	
+
 	// regExp: [extension protected] String
 	//		regular expression string used to validate the input
 	//		Do not specify both regExp and regExpGen
 	regExp: ".*",
-	
+
 	// _editBox: Widget
 	//		inline edit box
 	_editBox: null,
-	
+
 	// _handleKeyDown: handle
 	//		handle for the keyDown connect
 	_handleKeyDown: null,
-	
+
 	attributeMap: {
 		value: { node: "labelNode", type: "innerHTML" }
 	},
-	
+
 	postMixInProperties: function(){
-		var _nlsResources = dojo.i18n.getLocalization("dijit", "common");
-		dojo.mixin(this, _nlsResources);
+		var _nlsResources = i18nCommon;
+		lang.mixin(this, _nlsResources);
 		this.inherited(arguments);
 	},
-	
+
 	postCreate: function(){
 		// summary:
 		//		Create the close button if needed
 		this.inherited(arguments);
-		
-		this.closeButtonNode = dojo.create("span",{
+
+		this.closeButtonNode = domConstruct.create("span",{
 			"class" : "dijitButtonNode dijitDialogCloseIcon",
 			title : this.itemClose,
-			onclick: dojo.hitch(this, "onClose"),
-			onmouseenter: dojo.hitch(this, "_onCloseEnter"),
-			onmouseleave: dojo.hitch(this, "_onCloseLeave")
+			onclick: lang.hitch(this, "onClose"),
+			onmouseenter: lang.hitch(this, "_onCloseEnter"),
+			onmouseleave: lang.hitch(this, "_onCloseLeave")
 		}, this.domNode);
-		
-		dojo.create("span",{
+
+		domConstruct.create("span",{
 			"class" : "closeText",
 			title : this.itemClose,
 			innerHTML : "x"
 		}, this.closeButtonNode);
 	},
-	
+
 	startup: function(){
 		// summary:
 		//		add the edit box
 		this.inherited(arguments);
 		this._createInlineEditBox();
 	},
-	
+
 	_setReadOnlyItemAttr: function(/*Boolean*/value){
 		// summary:
 		//		change the readonly state
@@ -823,7 +841,7 @@ dojo.declare("dojox.form._ListInputInputItem",
 			this._editBox.set("disabled", true);
 		}
 	},
-	
+
 	_createInlineEditBox: function(){
 		// summary:
 		//		create the inline editbox if needed
@@ -835,7 +853,7 @@ dojo.declare("dojox.form._ListInputInputItem",
 			this._editBox.set("disabled",false);
 			return;
 		}
-		this._editBox = new dijit.InlineEditBox({
+		this._editBox = new InlineEditBox({
 			value:this.value,
 			editor: "dijit.form.ValidationTextBox",
 			editorParams:{
@@ -846,7 +864,7 @@ dojo.declare("dojox.form._ListInputInputItem",
 		this.connect(this._editBox,"onChange","_onCloseEdit");
 		this.connect(this._editBox,"onCancel","_onCloseEdit");
 	},
-	
+
 	edit: function(){
 		// summary:
 		//		enter inline editbox in edit mode
@@ -854,27 +872,27 @@ dojo.declare("dojox.form._ListInputInputItem",
 			this._editBox.edit();
 		}
 	},
-	
+
 	_onCloseEdit: function(/*String*/value){
 		// summary:
 		//		call when inline editor close himself
 		// tags:
 		//		private
-		dojo.removeClass(this.closeButtonNode,this.baseClass + "Edited");
-		dojo.disconnect(this._handleKeyDown);
+		domClass.remove(this.closeButtonNode,this.baseClass + "Edited");
+		connect.disconnect(this._handleKeyDown);
 		this.onChange(value);
 	},
-	
+
 	_onEdit: function(){
 		// summary:
 		//		call when inline editor start editing
 		// tags:
 		//		private
-		dojo.addClass(this.closeButtonNode,this.baseClass + "Edited");
-		this._handleKeyDown = dojo.connect(this._editBox.editWidget,"_onKeyPress",this,"onKeyDown");
+		domClass.add(this.closeButtonNode,this.baseClass + "Edited");
+		this._handleKeyDown = connect.connect(this._editBox.editWidget,"_onKeyPress",this,"onKeyDown");
 		this.onEdit();
 	},
-	
+
 	_setDisabledAttr: function(/*Boolean*/value){
 		// summary:
 		//		disable inline edit box
@@ -884,7 +902,7 @@ dojo.declare("dojox.form._ListInputInputItem",
 			this._editBox.set("disabled", value);
 		}
 	},
-	
+
 	_getValueAttr: function(){
 		// summary:
 		//		return value
@@ -892,7 +910,7 @@ dojo.declare("dojox.form._ListInputInputItem",
 		//		private
 		return (!this.readOnlyItem && this._started ? this._editBox.get("value") : this.value);
 	},
-	
+
 	destroy: function(){
 		// summary:
 		//		Destroy the inline editbox
@@ -901,13 +919,13 @@ dojo.declare("dojox.form._ListInputInputItem",
 		}
 		this.inherited(arguments);
 	},
-	
+
 	_onCloseEnter: function(){
 		// summary:
 		//		Called when user hovers over close icon
 		// tags:
 		//		private
-		dojo.addClass(this.closeButtonNode, "dijitDialogCloseIcon-hover");
+		domClass.add(this.closeButtonNode, "dijitDialogCloseIcon-hover");
 	},
 
 	_onCloseLeave: function(){
@@ -915,83 +933,84 @@ dojo.declare("dojox.form._ListInputInputItem",
 		//		Called when user stops hovering over close icon
 		// tags:
 		//		private
-		dojo.removeClass(this.closeButtonNode, "dijitDialogCloseIcon-hover");
+		domClass.remove(this.closeButtonNode, "dijitDialogCloseIcon-hover");
 	},
-	
+
 	onClose: function(){
 		// summary:
 		//		callback when close button is clicked
 	},
-	
+
 	onEdit: function(){
 		// summary:
 		//		callback when widget come in edition
 	},
-	
+
 	onClick: function(){
 		// summary:
 		//		callback when widget is click
 	},
-	
+
 	onChange: function(/*String*/value){
 		// summary:
 		//		callback when widget change its content
 	},
-	
-	
+
+
 	onKeyDown: function(/*String*/value){
 		// summary:
 		//		callback when widget get a KeyDown
 	}
 });
-dojo.declare("dojox.form._ListInputInputBox",
-	[dijit.form.ValidationTextBox],
+var _ListInputInputBox = declare("dojox.form._ListInputInputBox", [ValidationTextBox],
 	{
 	// summary:
 	//	auto-sized text box
 	// description:
 	//		Auto sized textbox based on dijit.form.TextBox
-	
+
 	// minWidth: Integer
 	//		Min width of the input box
 	minWidth:50,
-	
+
 	// intermediateChanges: Boolean
 	//		Fires onChange for each value change or only on demand
 	//		Force to true in order to get onChanged called
 	intermediateChanges:true,
-	
+
 	// regExp: [extension protected] String
 	//		regular expression string used to validate the input
 	//		Do not specify both regExp and regExpGen
 	regExp: ".*",
-	
+
 	// _sizer: DomNode
 	//		Used to get size of textbox content
 	_sizer:null,
-	
+
 	onChange: function(/*string*/value){
 		// summary:
 		//		compute content width
 		this.inherited(arguments);
 		if(this._sizer === null){
-			this._sizer = dojo.create("div",{
+			this._sizer = domConstruct.create("div",{
 				style : {
 					position : "absolute",
 					left : "-10000px",
 					top : "-10000px"
 				}
-			},dojo.body());
+			},win.body());
 		}
 		this._sizer.innerHTML = value;
-		var w = dojo.contentBox(this._sizer).w + this.minWidth;
-		dojo.contentBox(this.domNode,{ w : w });
+		var w = domGeometry.getContentBox(this._sizer).w + this.minWidth;
+		domGeometry.setContentSize(this.domNode,{ w : w });
 	},
-	
+
 	destroy: function(){
 		// summary:
 		//		destroy the widget
-		dojo.destroy(this._sizer);
+		domConstruct.destroy(this._sizer);
 		this.inherited(arguments);
 	}
+});
+return ListInput;
 });
\ No newline at end of file
diff --git a/dojox/form/Manager.js b/dojox/form/Manager.js
index aa9406d..f8c92c9 100644
--- a/dojox/form/Manager.js
+++ b/dojox/form/Manager.js
@@ -1,43 +1,54 @@
-dojo.provide("dojox.form.Manager");
+define([
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"./manager/_Mixin",
+	"./manager/_NodeMixin",
+	"./manager/_FormMixin",
+	"./manager/_ValueMixin",
+	"./manager/_EnableMixin",
+	"./manager/_DisplayMixin",
+	"./manager/_ClassMixin",
+	"dojo/_base/declare"
+], function(_Widget, _TemplatedMixin, _Mixin, _NodeMixin, _FormMixin, _ValueMixin, _EnableMixin, _DisplayMixin, _ClassMixin, declare){
 
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-
-dojo.require("dojox.form.manager._Mixin");
-dojo.require("dojox.form.manager._NodeMixin");
-dojo.require("dojox.form.manager._FormMixin");
-dojo.require("dojox.form.manager._ValueMixin");
-dojo.require("dojox.form.manager._EnableMixin");
-dojo.require("dojox.form.manager._DisplayMixin");
-dojo.require("dojox.form.manager._ClassMixin");
-
-dojo.declare("dojox.form.Manager", [
-		dijit._Widget,
-		dojox.form.manager._Mixin,
-		dojox.form.manager._NodeMixin,
-		dojox.form.manager._FormMixin,
-		dojox.form.manager._ValueMixin,
-		dojox.form.manager._EnableMixin,
-		dojox.form.manager._DisplayMixin,
-		dojox.form.manager._ClassMixin
-], {
+	/*=====
+		_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 ], {
 	// summary:
 	//		The widget to orchestrate dynamic forms.
 	// description:
 	//		This widget hosts dojox.form.manager mixins.
-	//		See dojox.form.manager._Mixin for more info.
+	//		See _Mixin for more info.
 
 	buildRendering: function(){
-		var node = this.domNode = this.srcNodeRef;
+		var node = (this.domNode = this.srcNodeRef);
 		if(!this.containerNode){
 			// all widgets with descendants must set containerNode
 				this.containerNode = node;
 		}
+		this.inherited(arguments);
 		this._attachPoints = [];
-		dijit._Templated.prototype._attachTemplateNodes.call(this, node);
+		this._attachEvents = [];
+		_TemplatedMixin.prototype._attachTemplateNodes.call(this, node, function(n, p){ return n.getAttribute(p); });
 	},
-	
-	destroyRendering: function(){
-		dijit._Templated.prototype.destroyRendering.call(this);
+
+	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/MultiComboBox.js b/dojox/form/MultiComboBox.js
index 8291d0a..cf79756 100644
--- a/dojox/form/MultiComboBox.js
+++ b/dojox/form/MultiComboBox.js
@@ -1,20 +1,27 @@
-dojo.provide("dojox.form.MultiComboBox");
-dojo.experimental("dojox.form.MultiComboBox");
-dojo.require("dijit.form.ComboBox");
-dojo.require("dijit.form.ValidationTextBox");
-
-dojo.declare("dojox.form.MultiComboBox",
-	[dijit.form.ValidationTextBox, dijit.form.ComboBoxMixin],{
-	//
-	// summary: A ComboBox that accpets multiple inputs on a single line?
-	//
+define([
+	"dojo/_base/kernel",
+	"dijit/form/ValidationTextBox",
+	"dijit/form/ComboBoxMixin",
+	"dojo/_base/declare"
+], 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
+
 	// delimiter: String
-	// 	The character to use to separate items in the ComboBox input
+	//		The character to use to separate items in the ComboBox input
 	delimiter: ",",
+
 	_previousMatches: false,
 
 	_setValueAttr: function(value){
-		if (this.delimiter && value.length != 0){
+		if(this.delimiter && value.length != 0){
 			value = value+this.delimiter+" ";
 			arguments[0] = this._addPreviousMatches(value);
 		}
@@ -39,7 +46,7 @@ dojo.declare("dojox.form.MultiComboBox",
 		}
 		return text;
 	},
-			
+
 	_autoCompleteText: function(/* String */text){
 		arguments[0] = this._addPreviousMatches(text);
 		this.inherited(arguments);
@@ -48,10 +55,11 @@ dojo.declare("dojox.form.MultiComboBox",
 	_startSearch: function(/* String */text){
 		text = this._cleanupDelimiters(text);
 		var re = new RegExp("^.*"+this.delimiter+" *");
-		
+
 		if((this._previousMatches = text.match(re))){
 			arguments[0] = text.replace(re, "");
 		}
 		this.inherited(arguments);
 	}
 });
+});
\ No newline at end of file
diff --git a/dojox/form/PasswordValidator.js b/dojox/form/PasswordValidator.js
index 5570d1c..06d2b73 100644
--- a/dojox/form/PasswordValidator.js
+++ b/dojox/form/PasswordValidator.js
@@ -1,11 +1,22 @@
-dojo.provide("dojox.form.PasswordValidator");
+define([
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/dom-attr",
+	"dojo/i18n",
+	"dojo/query",
+	"dojo/keys",
+	"dijit/form/_FormValueWidget",
+	"dijit/form/ValidationTextBox",
+	"dojo/text!./resources/PasswordValidator.html",
+	"dojo/i18n!./nls/PasswordValidator",
+	"dojo/_base/declare"
+], function(array, lang, domAttr, i18n, query, keys, FormValueWidget, ValidationTextBox, template, formNlsPasswordValidator, declare){
 
-dojo.require("dijit.form._FormWidget");
-dojo.require("dijit.form.ValidationTextBox");
-
-dojo.requireLocalization("dojox.form", "PasswordValidator");
-
-dojo.declare("dojox.form._ChildTextBox", dijit.form.ValidationTextBox, {
+	/*=====
+		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
@@ -13,20 +24,20 @@ dojo.declare("dojox.form._ChildTextBox", dijit.form.ValidationTextBox, {
 	// containerWidget: widget
 	//		Our parent (the PasswordValidator)
 	containerWidget: null,
-	
+
 	// type: string
 	//		Don't override this - we are all "password" types
 	type: "password",
-	
+
 	reset: function(){
 		// summary:
 		//		Force-set to empty string (we don't save passwords EVER)...and
 		//		since _OldPWBox overrides _setValueAttr to check for empty string,
 		//		call our parent class directly (not this.inherited())
-		dijit.form.ValidationTextBox.prototype._setValueAttr.call(this, "", true);
+		ValidationTextBox.prototype._setValueAttr.call(this, "", true);
 		this._hasBeenBlurred = false;
 	},
-	
+
 	postCreate: function(){
 		// summary:
 		//		We want to remove the "name" attribute from our focus node if
@@ -34,15 +45,15 @@ dojo.declare("dojox.form._ChildTextBox", dijit.form.ValidationTextBox, {
 		//		from being posted on submit
 		this.inherited(arguments);
 		if(!this.name){
-			dojo.removeAttr(this.focusNode, "name");
+			domAttr.remove(this.focusNode, "name");
 		}
 		this.connect(this.focusNode, "onkeypress", "_onChildKeyPress");
 	},
-	
+
 	_onChildKeyPress: function(e){
 		// Check if we pressed <enter> - if so, set our blur value so that
 		// the parent widget will be updated correctly.
-		if(e && e.keyCode == dojo.keys.ENTER){
+		if(e && e.keyCode == keys.ENTER){
 			this._setBlurValue();
 		}
 	}
@@ -50,20 +61,20 @@ dojo.declare("dojox.form._ChildTextBox", dijit.form.ValidationTextBox, {
 
 
 
-dojo.declare("dojox.form._OldPWBox", dojox.form._ChildTextBox, {
+var _OldPWBox = declare("dojox.form._OldPWBox", _ChildTextBox, {
 	// summary:
 	//		A class representing our "old password" box.
 	//
 	// _isPWValid: boolean
 	//		Whether or not the password is valid
 	_isPWValid: false,
-	
+
 	_setValueAttr: function(/* anything */ newVal, /* boolean? */ priority){
 		// summary:
 		//		Updates _isPWValid if this isn't our initial update by calling
 		//		our PasswordValidator's pwCheck function
 		if(newVal === ""){
-			newVal = dojox.form._OldPWBox.superclass.attr.call(this, "value");
+			newVal = _OldPWBox.superclass.attr.call(this, "value");
 		}
 		if(priority !== null){
 			//  Priority is passed in as null, explicitly when this is an
@@ -100,20 +111,20 @@ dojo.declare("dojox.form._OldPWBox", dojox.form._ChildTextBox, {
 		// is not valid, TextBox._setBlurValue will cause OldPWBox's value to be set to ""
 		//
 		// So, we directly call ValidationTextBox._getValueAttr to bypass our _getValueAttr
-		var value = dijit.form.ValidationTextBox.prototype._getValueAttr.call(this);
+		var value = ValidationTextBox.prototype._getValueAttr.call(this);
 		this._setValueAttr(value, (this.isValid ? this.isValid() : true));
 	}
 });
 
 
-dojo.declare("dojox.form._NewPWBox", dojox.form._ChildTextBox, {
+var _NewPWBox = declare("dojox.form._NewPWBox", _ChildTextBox, {
 	// summary:
 	//		A class representing our new password textbox
 
 	// required: boolean
 	//		Whether or not this widget is required (default: true)
 	required: true,
-	
+
 	onChange: function(){
 		// summary:
 		//		Validates our verify box - to make sure that a change to me is
@@ -123,7 +134,7 @@ dojo.declare("dojox.form._NewPWBox", dojox.form._ChildTextBox, {
 	}
 });
 
-dojo.declare("dojox.form._VerifyPWBox", dojox.form._ChildTextBox, {
+var _VerifyPWBox = declare("dojox.form._VerifyPWBox", _ChildTextBox, {
 	// summary:
 	//		A class representing our verify textbox
 
@@ -135,16 +146,16 @@ dojo.declare("dojox.form._VerifyPWBox", dojox.form._ChildTextBox, {
 	}
 });
 
-dojo.declare("dojox.form.PasswordValidator", dijit.form._FormValueWidget, {
+return declare("dojox.form.PasswordValidator", FormValueWidget, {
 	// summary:
 	//		A password validation widget that simplifies the "old/new/verify"
 	//		style of requesting passwords.  You will probably want to override
 	//		this class and implement your own pwCheck function.
-	//
+
 	// required: boolean
 	//		Whether or not it is required for form submission
 	required: true,
-	
+
 	// inputWidgets: TextBox[]
 	//		An array of text boxes that are our components
 	_inputWidgets: null,
@@ -152,14 +163,14 @@ dojo.declare("dojox.form.PasswordValidator", dijit.form._FormValueWidget, {
 	// oldName: string?
 	//		The name to send our old password as (when form is posted)
 	oldName: "",
-	
-	templateString: dojo.cache("dojox.form", "resources/PasswordValidator.html"),
-	
+
+	templateString: template,
+
 	_hasBeenBlurred: false,
 
 	isValid: function(/* boolean */ isFocused){
 		// summary: we are valid if ALL our children are valid
-		return dojo.every(this._inputWidgets, function(i){
+		return array.every(this._inputWidgets, function(i){
 			if(i && i._setStateClass){ i._setStateClass(); }
 			return (!i || i.isValid());
 		});
@@ -167,19 +178,19 @@ dojo.declare("dojox.form.PasswordValidator", dijit.form._FormValueWidget, {
 
 	validate: function(/* boolean */ isFocused){
 		// summary: Validating this widget validates all our children
-		return dojo.every(dojo.map(this._inputWidgets, function(i){
+		return array.every(array.map(this._inputWidgets, function(i){
 			if(i && i.validate){
 				i._hasBeenBlurred = (i._hasBeenBlurred || this._hasBeenBlurred);
 				return i.validate();
 			}
 			return true;
-		}, this), "return item;");
+		}, this), function(item){ return item; });
 	},
 
 	reset: function(){
 		// summary: Resetting this widget resets all our children
 		this._hasBeenBlurred = false;
-		dojo.forEach(this._inputWidgets, function(i){
+		array.forEach(this._inputWidgets, function(i){
 			if(i && i.reset){ i.reset(); }
 		}, this);
 	},
@@ -189,20 +200,20 @@ dojo.declare("dojox.form.PasswordValidator", dijit.form._FormValueWidget, {
 		//		Turns the inputs inside this widget into "real" validation
 		//		widgets - and sets up the needed connections.
 		var widgets = this._inputWidgets,
-			msg = dojo.i18n.getLocalization("dojox.form", "PasswordValidator", this.lang);
-		dojo.forEach(widgets, function(i, idx){
+			msg = i18n.getLocalization("dojox.form", "PasswordValidator", this.lang);
+		array.forEach(widgets, function(i, idx){
 			if(i){
 				var p = {containerWidget: this}, c;
 				if(idx === 0){
 					p.name = this.oldName;
 					p.invalidMessage = msg.badPasswordMessage;
-					c = dojox.form._OldPWBox;
+					c = _OldPWBox;
 				}else if(idx === 1){
 					p.required = this.required;
-					c = dojox.form._NewPWBox;
+					c = _NewPWBox;
 				}else if(idx === 2){
 					p.invalidMessage = msg.nomatchMessage;
-					c = dojox.form._VerifyPWBox;
+					c = _VerifyPWBox;
 				}
 				widgets[idx] = new c(p, i);
 			}
@@ -243,18 +254,18 @@ dojo.declare("dojox.form.PasswordValidator", dijit.form._FormValueWidget, {
 		//		specify a third child text box with pwType="old" in order to
 		//		prompt the user to enter in their old password before the
 		//		widget returns that it is valid.
-		
+
 		this.inherited(arguments);
-		
+
 		// Turn my inputs into the correct stuff....
 		var widgets = this._inputWidgets = [];
-		dojo.forEach(["old","new","verify"], function(i){
-			widgets.push(dojo.query("input[pwType=" + i + "]", this.containerNode)[0]);
+		array.forEach(["old","new","verify"], function(i){
+			widgets.push(query("input[pwType=" + i + "]", this.containerNode)[0]);
 		}, this);
-		if (!widgets[1] || !widgets[2]){
+		if(!widgets[1] || !widgets[2]){
 			throw new Error("Need at least pwType=\"new\" and pwType=\"verify\"");
 		}
-		if (this.oldName && !widgets[0]){
+		if(this.oldName && !widgets[0]){
 			throw new Error("Need to specify pwType=\"old\" if using oldName");
 		}
 		this.containerNode = this.domNode;
@@ -262,44 +273,44 @@ dojo.declare("dojox.form.PasswordValidator", dijit.form._FormValueWidget, {
 		this.connect(this._inputWidgets[1], "_setValueAttr", "_childValueAttr");
 		this.connect(this._inputWidgets[2], "_setValueAttr", "_childValueAttr");
 	},
-	
+
 	_childValueAttr: function(v){
 		this.set("value", this.isValid() ? v : "");
 	},
-	
+
 	_setDisabledAttr: function(value){
 		this.inherited(arguments);
-		dojo.forEach(this._inputWidgets, function(i){
+		array.forEach(this._inputWidgets, function(i){
 			if(i && i.set){ i.set("disabled", value);}
 		});
 	},
-	
+
 	_setRequiredAttribute: function(value){
 		this.required = value;
-		dojo.attr(this.focusNode, "required", value);
-		dijit.setWaiState(this.focusNode, "required", value);
+		domAttr.set(this.focusNode, "required", value);
+		this.focusNode.setAttribute("aria-required", value);
 		this._refreshState();
-		dojo.forEach(this._inputWidgets, function(i){
+		array.forEach(this._inputWidgets, function(i){
 			if(i && i.set){ i.set("required", value);}
 		});
 	},
 
 	_setValueAttr: function(v){
 		this.inherited(arguments);
-		dojo.attr(this.focusNode, "value", v);
+		domAttr.set(this.focusNode, "value", v);
 	},
-	
+
 	_getValueAttr: function(){
-		// Make sure we don't return undefined....
-		return this.inherited(arguments)||"";
+		// Make sure we don't return undefined.... maybe should do conversion in _setValueAttr() instead?
+		return this.value||"";
 	},
-	
+
 	focus: function(){
 		// summary:
 		//		places focus on the first invalid input widget - if all
 		//		input widgets are valid, the first widget is focused.
 		var f = false;
-		dojo.forEach(this._inputWidgets, function(i){
+		array.forEach(this._inputWidgets, function(i){
 			if(i && !i.isValid() && !f){
 				i.focus();
 				f = true;
@@ -307,4 +318,5 @@ dojo.declare("dojox.form.PasswordValidator", dijit.form._FormValueWidget, {
 		});
 		if(!f){ this._inputWidgets[1].focus(); }
 	}
+});
 });
\ No newline at end of file
diff --git a/dojox/form/README b/dojox/form/README
index c1b3ff7..462ca5b 100644
--- a/dojox/form/README
+++ b/dojox/form/README
@@ -9,9 +9,9 @@ experimental
 -------------------------------------------------------------------------------
 Credits
 	Nathan Toone (toonetown)
-	Peter Higgins	(dante)
-    Wolfram Kriesing (http://wolfram.kriesing.de/blog/): Rating
-    Mike Wilcox
+	Peter Higgins (dante)
+	Wolfram Kriesing (wolfram)
+	Mike Wilcox (mwilcox)
 -------------------------------------------------------------------------------
 Project description
 
@@ -39,8 +39,8 @@ Additional Notes (Brief widget list):
 	* CheckedMultiSelect - an extension to dijit.form.MultiSelect which
 						uses check boxes instead of ctrl-click
 
- 	* DropDownSelect - an extension to dijit.form.DropDownButton which is
- 						meant to mirror the html <select> drop down
+	* DropDownSelect - an extension to dijit.form.DropDownButton which is
+						meant to mirror the html <select> drop down
 
 	* DropDownStack/RadioStack - a widget that can toggle parts of a form as
 						"on" or "off" - to allow for different options based on 
diff --git a/dojox/form/RadioStack.js b/dojox/form/RadioStack.js
index cd65673..0a71f13 100644
--- a/dojox/form/RadioStack.js
+++ b/dojox/form/RadioStack.js
@@ -1,9 +1,13 @@
-dojo.provide("dojox.form.RadioStack");
-
-dojo.require("dojox.form.CheckedMultiSelect");
-dojo.require("dojox.form._SelectStackMixin");
-
-dojo.declare("dojox.form.RadioStack",
-	[ dojox.form.CheckedMultiSelect, dojox.form._SelectStackMixin ], {
+define([
+	"./CheckedMultiSelect",
+	"./_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.
+	});
 });
\ No newline at end of file
diff --git a/dojox/form/RangeSlider.js b/dojox/form/RangeSlider.js
index 9da0afc..6fc2408 100644
--- a/dojox/form/RangeSlider.js
+++ b/dojox/form/RangeSlider.js
@@ -1,23 +1,45 @@
-dojo.provide("dojox.form.RangeSlider");
-dojo.require("dijit.form.HorizontalSlider");
-dojo.require("dijit.form.VerticalSlider");
-dojo.require("dojox.fx");
-
-(function(){
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/fx",
+	"dojo/_base/event",
+	"dojo/_base/sniff",
+	"dojo/dom-style",
+	"dojo/dom-geometry",
+	"dojo/keys",
+	"dijit",
+	"dojo/dnd/Mover",
+	"dojo/dnd/Moveable",
+	"dojo/text!./resources/HorizontalRangeSlider.html",
+	"dojo/text!./resources/VerticalRangeSlider.html",
+	"dijit/form/HorizontalSlider",
+	"dijit/form/VerticalSlider",
+	"dijit/form/_FormValueWidget",
+	"dijit/focus",
+	"dojo/fx",
+	"dojox/fx" // unused?
+], function(declare, lang, array, fx, event, has, domStyle, domGeometry, keys, dijit, Mover, Moveable, hTemplate, vTemplate, HorizontalSlider, VerticalSlider, FormValueWidget, FocusManager, fxUtils){
 
 	// make these functions once:
 	var sortReversed = function(a, b){ return b - a; },
 		sortForward = function(a, b){ return a - b; }
 	;
 
-	dojo.declare("dojox.form._RangeSliderMixin", null, {
+	lang.getObject("form", true, dojox);
+
+	/*=====
+		hTemplate = dijit.form.HorizontalSlider;
+		vTemplate = dijit.form.VerticalSlider;
+	=====*/
+	var RangeSliderMixin = declare("dojox.form._RangeSliderMixin", null, {
 
 		value: [0,100],
 		postMixInProperties: function(){
 			this.inherited(arguments);
-			this.value = dojo.map(this.value, function(i){ return parseInt(i, 10); });
+			this.value = array.map(this.value, function(i){ return parseInt(i, 10); });
 		},
-	
+
 		postCreate: function(){
 			this.inherited(arguments);
 			// we sort the values!
@@ -26,182 +48,155 @@ dojo.require("dojox.fx");
 
 			// define a custom constructor for a SliderMoverMax that points back to me
 			var _self = this;
-            var mover = dojo.declare(dijit.form._SliderMoverMax, {
-                constructor: function(){
-                    this.widget = _self;
-                }
-            });
-
-			this._movableMax = new dojo.dnd.Moveable(this.sliderHandleMax,{ mover: mover });
-			dijit.setWaiState(this.focusNodeMax, "valuemin", this.minimum);
-			dijit.setWaiState(this.focusNodeMax, "valuemax", this.maximum);
-		
+			var mover = declare(SliderMoverMax, {
+				constructor: function(){
+					this.widget = _self;
+				}
+			});
+
+			this._movableMax = new Moveable(this.sliderHandleMax,{ mover: mover });
+			this.focusNodeMax.setAttribute("aria-valuemin", this.minimum);
+			this.focusNodeMax.setAttribute("aria-valuemax", this.maximum);
+
 			// a dnd for the bar!
-            var barMover = dojo.declare(dijit.form._SliderBarMover, {
-                constructor: function(){
-                    this.widget = _self;
-                }
-            });
-			this._movableBar = new dojo.dnd.Moveable(this.progressBar,{ mover: barMover });
+			var barMover = declare(SliderBarMover, {
+				constructor: function(){
+					this.widget = _self;
+				}
+			});
+			this._movableBar = new Moveable(this.progressBar,{ mover: barMover });
 		},
-	
+
 		destroy: function(){
 			this.inherited(arguments);
 			this._movableMax.destroy();
 			this._movableBar.destroy();
 		},
-	
+
 		_onKeyPress: function(/*Event*/ e){
 			if(this.disabled || this.readOnly || e.altKey || e.ctrlKey){ return; }
-		
-			var focusedEl = e.currentTarget,
-				minSelected = false,
-				maxSelected = false,
-				k = dojo.keys
-			;
-		
-			if(focusedEl == this.sliderHandle){
-				minSelected = true;
-			}else if(focusedEl == this.progressBar){
-				maxSelected = minSelected = true;
-			}else if(focusedEl == this.sliderHandleMax){
-				maxSelected = true;
+
+			var useMaxValue = e.target === this.sliderHandleMax;
+			var barFocus = e.target === this.progressBar;
+			var k = lang.delegate(keys, this.isLeftToRight() ? {PREV_ARROW: keys.LEFT_ARROW, NEXT_ARROW: keys.RIGHT_ARROW} 
+			                                                 : {PREV_ARROW: keys.RIGHT_ARROW, NEXT_ARROW: keys.LEFT_ARROW});			
+			var delta = 0;
+			var down = false;
+
+			switch(e.keyCode){
+				case k.HOME       :	this._setValueAttr(this.minimum, true, useMaxValue);event.stop(e);return;
+				case k.END        :	this._setValueAttr(this.maximum, true, useMaxValue);event.stop(e);return;
+				case k.PREV_ARROW :
+				case k.DOWN_ARROW :	down = true;
+				case k.NEXT_ARROW :
+				case k.UP_ARROW   :	delta = 1; break;
+				case k.PAGE_DOWN  :	down = true;
+				case k.PAGE_UP    :	delta = this.pageIncrement; break;
+				default           : this.inherited(arguments);return;
 			}
 			
-			switch(e.keyCode){
-				case k.HOME:
-					this._setValueAttr(this.minimum, true, maxSelected);
-					break;
-				case k.END:
-					this._setValueAttr(this.maximum, true, maxSelected);
-					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()) ? k.RIGHT_ARROW : k.LEFT_ARROW):
-				case (this._descending === false ? k.DOWN_ARROW : k.UP_ARROW):
-				case (this._descending === false ? k.PAGE_DOWN : k.PAGE_UP):
-					if(minSelected && maxSelected){
-						this._bumpValue([
-							{'change': e.keyCode == k.PAGE_UP ? this.pageIncrement : 1, 'useMaxValue': true},
-							{'change': e.keyCode == k.PAGE_UP ? this.pageIncrement : 1, 'useMaxValue': false}
-						]);
-					}else if(minSelected){
-						this._bumpValue(e.keyCode == k.PAGE_UP ? this.pageIncrement : 1, true);
-					}else if(maxSelected){
-						this._bumpValue(e.keyCode == k.PAGE_UP ? this.pageIncrement : 1);
-					}
-					break;
-				case ((this._descending || this.isLeftToRight()) ? k.LEFT_ARROW : k.RIGHT_ARROW) :
-				case (this._descending === false ? k.UP_ARROW : k.DOWN_ARROW):
-				case (this._descending === false ? k.PAGE_UP : k.PAGE_DOWN):
-					if (minSelected && maxSelected){
-						this._bumpValue([
-							{ change: e.keyCode == k.PAGE_DOWN ? -this.pageIncrement : -1, useMaxValue: false },
-							{ change: e.keyCode == k.PAGE_DOWN ? -this.pageIncrement : -1, useMaxValue: true }
-						]);
-					}else if(minSelected){
-						this._bumpValue(e.keyCode == k.PAGE_DOWN ? -this.pageIncrement : -1);
-					}else if(maxSelected){
-						this._bumpValue(e.keyCode == k.PAGE_DOWN ? -this.pageIncrement : -1, true);
-					}
-					break;
-				default:
-					dijit.form._FormValueWidget.prototype._onKeyPress.apply(this, arguments);
-					this.inherited(arguments);
-					return;
+			if(down){delta = -delta;}
+
+			if(delta){
+				if(barFocus){
+					this._bumpValue([
+						{ change: delta, useMaxValue: false },
+						{ change: delta, useMaxValue: true }
+					]);
+				}else{
+					this._bumpValue(delta, useMaxValue);
+				}
+				event.stop(e);
 			}
-			dojo.stopEvent(e);
 		},
-	
+
 		_onHandleClickMax: function(e){
 			if(this.disabled || this.readOnly){ return; }
-			if(!dojo.isIE){
+			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)
-				dijit.focus(this.sliderHandleMax);
+				FocusManager.focus(this.sliderHandleMax);
 			}
-			dojo.stopEvent(e);
+			event.stop(e);
 		},
-	
+
 		_onClkIncBumper: function(){
 			this._setValueAttr(this._descending === false ? this.minimum : this.maximum, true, true);
 		},
-	
+
 		_bumpValue: function(signedChange, useMaxValue){
 
 			// we pass an array to _setValueAttr when signedChange is an array
-			var value = dojo.isArray(signedChange) ? [
+			var value = lang.isArray(signedChange) ? [
 					this._getBumpValue(signedChange[0].change, signedChange[0].useMaxValue),
 					this._getBumpValue(signedChange[1].change, signedChange[1].useMaxValue)
 				]
 				: this._getBumpValue(signedChange, useMaxValue)
 
-			this._setValueAttr(value, true,
-				// conditional passed the valueAttr
-				!dojo.isArray(signedChange) &&
-				((signedChange > 0 && !useMaxValue) || (useMaxValue && signedChange < 0))
-			);
+			this._setValueAttr(value, true, useMaxValue);
 		},
-	
+
 		_getBumpValue: function(signedChange, useMaxValue){
-			var s = dojo.getComputedStyle(this.sliderBarContainer),
-				c = dojo._getContentBox(this.sliderBarContainer, s),
+
+			var idx = useMaxValue ? 1 : 0;
+			if(this._isReversed()){
+				idx = 1 - idx;
+			}
+
+			var s = domStyle.getComputedStyle(this.sliderBarContainer),
+				c = domGeometry.getContentBox(this.sliderBarContainer, s),
 				count = this.discreteValues,
-				myValue = !useMaxValue ? this.value[0] : this.value[1]
+				myValue = this.value[idx]
 			;
 
 			if(count <= 1 || count == Infinity){ count = c[this._pixelCount]; }
 			count--;
 
-			if((this._isReversed() && signedChange < 0) || (signedChange > 0 && !this._isReversed())){
-				myValue = !useMaxValue ? this.value[1] : this.value[0];
-			}
-			
 			var value = (myValue - this.minimum) * count / (this.maximum - this.minimum) + signedChange;
 			if(value < 0){ value = 0; }
 			if(value > count){ value = count; }
-			
+
 			return value * (this.maximum - this.minimum) / count + this.minimum;
 		},
-	
+
 		_onBarClick: function(e){
 			if(this.disabled || this.readOnly){ return; }
-			if(!dojo.isIE){
+			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)
-				dijit.focus(this.progressBar);
+				FocusManager.focus(this.progressBar);
 			}
-			dojo.stopEvent(e);
+			event.stop(e);
 		},
-	
+
 		_onRemainingBarClick: function(e){
 			if(this.disabled || this.readOnly){ return; }
-			if(!dojo.isIE){
+			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)
-				dijit.focus(this.progressBar);
+				FocusManager.focus(this.progressBar);
 			}
 
 			// now we set the min/max-value of the slider!
-			var abspos = dojo.coords(this.sliderBarContainer, true),
-				bar = dojo.coords(this.progressBar, true),
+			var abspos = domGeometry.position(this.sliderBarContainer, true),
+				bar = domGeometry.position(this.progressBar, true),
 				relMousePos = e[this._mousePixelCoord] - abspos[this._startingPixelCoord],
-				leftPos = bar[this._startingPixelCount],
+				leftPos = bar[this._startingPixelCoord],
 				rightPos = leftPos + bar[this._pixelCount],
 				isMaxVal = this._isReversed() ? relMousePos <= leftPos : relMousePos >= rightPos,
 				p = this._isReversed() ? abspos[this._pixelCount] - relMousePos : relMousePos
 			;
 
 			this._setPixelValue(p, abspos[this._pixelCount], true, isMaxVal);
-			dojo.stopEvent(e);
+			event.stop(e);
 		},
-	
+
 		_setPixelValue: function(/*Number*/ pixelValue, /*Number*/ maxPixels, /*Boolean*/ priorityChange, /*Boolean*/ isMaxVal){
 			if(this.disabled || this.readOnly){ return; }
 			var myValue = this._getValueByPixelValue(pixelValue, maxPixels);
 			this._setValueAttr(myValue, priorityChange, isMaxVal);
 		},
-	
+
 		_getValueByPixelValue: function(/*Number*/ pixelValue, /*Number*/ maxPixels){
 			pixelValue = pixelValue < 0 ? 0 : maxPixels < pixelValue ? maxPixels : pixelValue;
 			var count = this.discreteValues;
@@ -211,11 +206,11 @@ dojo.require("dojox.fx");
 			var wholeIncrements = Math.round(pixelValue / pixelsPerValue);
 			return (this.maximum-this.minimum)*wholeIncrements/count + this.minimum;
 		},
-	
+
 		_setValueAttr: function(/*Array or Number*/ value, /*Boolean, optional*/ priorityChange, /*Boolean, optional*/ isMaxVal){
 			// we pass an array, when we move the slider with the bar
 			var actValue = this.value;
-			if(!dojo.isArray(value)){
+			if(!lang.isArray(value)){
 				if(isMaxVal){
 					if(this._isReversed()){
 						actValue[0] = value;
@@ -235,16 +230,16 @@ dojo.require("dojox.fx");
 			// we have to reset this values. don't know the reason for that
 			this._lastValueReported = "";
 			this.valueNode.value = this.value = value = actValue;
-			dijit.setWaiState(this.focusNode, "valuenow", actValue[0]);
-			dijit.setWaiState(this.focusNodeMax, "valuenow", actValue[1]);
-		
+			this.focusNode.setAttribute("aria-valuenow", actValue[0]);
+			this.focusNodeMax.setAttribute("aria-valuenow", actValue[1]);
+
 			this.value.sort(this._isReversed() ? sortReversed : sortForward);
-			
-			// not calling the _setValueAttr-function of dijit.form.Slider, but the super-super-class (needed for the onchange-event!)
-			dijit.form._FormValueWidget.prototype._setValueAttr.apply(this, arguments);
+
+			// 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);
 		},
-	
+
 		_printSliderBar: function(priorityChange, isMaxVal){
 			var percentMin = (this.value[0] - this.minimum) / (this.maximum - this.minimum);
 			var percentMax = (this.value[1] - this.minimum) / (this.maximum - this.minimum);
@@ -256,7 +251,7 @@ dojo.require("dojox.fx");
 			var sliderHandleVal = this._isReversed() ? ((1-percentMin)*100) : (percentMin * 100);
 			var sliderHandleMaxVal = this._isReversed() ? ((1-percentMax)*100) : (percentMax * 100);
 			var progressBarVal = this._isReversed() ? ((1-percentMax)*100) : (percentMin * 100);
-			if (priorityChange && this.slideDuration > 0 && this.progressBar.style[this._progressPixelSize]){
+			if(priorityChange && this.slideDuration > 0 && this.progressBar.style[this._progressPixelSize]){
 				// animate the slider
 				var percent = isMaxVal ? percentMax : percentMin;
 				var _this = this;
@@ -273,10 +268,10 @@ dojo.require("dojox.fx");
 				propsHandleMax[this._handleOffsetCoord] = { start: this.sliderHandleMax.style[this._handleOffsetCoord], end: sliderHandleMaxVal, units:"%"};
 				propsBar[this._handleOffsetCoord] = { start: this.progressBar.style[this._handleOffsetCoord], end: progressBarVal, units:"%"};
 				propsBar[this._progressPixelSize] = { start: this.progressBar.style[this._progressPixelSize], end: (percentMax - percentMin) * 100, units:"%"};
-				var animHandle = dojo.animateProperty({node: this.sliderHandle,duration: duration, properties: propsHandle});
-				var animHandleMax = dojo.animateProperty({node: this.sliderHandleMax,duration: duration, properties: propsHandleMax});
-				var animBar = dojo.animateProperty({node: this.progressBar,duration: duration, properties: propsBar});
-				var animCombine = dojo.fx.combine([animHandle, animHandleMax, animBar]);
+				var animHandle = fx.animateProperty({node: this.sliderHandle,duration: duration, properties: propsHandle});
+				var animHandleMax = fx.animateProperty({node: this.sliderHandleMax,duration: duration, properties: propsHandleMax});
+				var animBar = fx.animateProperty({node: this.progressBar,duration: duration, properties: propsBar});
+				var animCombine = fxUtils.combine([animHandle, animHandleMax, animBar]);
 				animCombine.play();
 			}else{
 				this.sliderHandle.style[this._handleOffsetCoord] = sliderHandleVal + "%";
@@ -287,31 +282,31 @@ dojo.require("dojox.fx");
 		}
 	});
 
-	dojo.declare("dijit.form._SliderMoverMax", dijit.form._SliderMover, {
+	var SliderMoverMax = declare("dijit.form._SliderMoverMax", dijit.form._SliderMover, {
 
 		onMouseMove: function(e){
 			var widget = this.widget;
 			var abspos = widget._abspos;
 			if(!abspos){
-				abspos = widget._abspos = dojo.coords(widget.sliderBarContainer, true);
-				widget._setPixelValue_ = dojo.hitch(widget, "_setPixelValue");
+				abspos = widget._abspos = domGeometry.position(widget.sliderBarContainer, true);
+				widget._setPixelValue_ = lang.hitch(widget, "_setPixelValue");
 				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];
 			widget._setPixelValue_(widget._isReversed_ ? (abspos[widget._pixelCount]-pixelValue) : pixelValue, abspos[widget._pixelCount], false, true);
 		},
-	
+
 		destroy: function(e){
-			dojo.dnd.Mover.prototype.destroy.apply(this, arguments);
+			Mover.prototype.destroy.apply(this, arguments);
 			var widget = this.widget;
 			widget._abspos = null;
 			widget._setValueAttr(widget.value, true);
 		}
 	});
 
-	dojo.declare("dijit.form._SliderBarMover", dojo.dnd.Mover, {
+	var SliderBarMover = declare("dijit.form._SliderBarMover", Mover, {
 
 		onMouseMove: function(e){
 			var widget = this.widget;
@@ -320,22 +315,22 @@ dojo.require("dojox.fx");
 			var bar = widget._bar;
 			var mouseOffset = widget._mouseOffset;
 			if(!abspos){
-				abspos = widget._abspos = dojo.coords(widget.sliderBarContainer, true);
-				widget._setPixelValue_ = dojo.hitch(widget, "_setPixelValue");
-				widget._getValueByPixelValue_ = dojo.hitch(widget, "_getValueByPixelValue");
+				abspos = widget._abspos = domGeometry.position(widget.sliderBarContainer, true);
+				widget._setPixelValue_ = lang.hitch(widget, "_setPixelValue");
+				widget._getValueByPixelValue_ = lang.hitch(widget, "_getValueByPixelValue");
 				widget._isReversed_ = widget._isReversed();
 			}
-			
+
 			if(!bar){
-				bar = widget._bar = dojo.coords(widget.progressBar, true);
+				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._startingPixelCount];
+				mouseOffset = widget._mouseOffset = coordEvent[widget._mousePixelCoord] - abspos[widget._startingPixelCoord] - bar[widget._startingPixelCoord];
 			}
-			
-				
+
+
 			var pixelValueMin = coordEvent[widget._mousePixelCoord] - abspos[widget._startingPixelCoord] - mouseOffset,
 				pixelValueMax = pixelValueMin + bar[widget._pixelCount];
 				// we don't narrow the slider when it reaches the bumper!
@@ -361,9 +356,9 @@ dojo.require("dojox.fx");
 			// and setting the value of the widget
 			widget._setValueAttr(myValues, false, false);
 		},
-	
+
 		destroy: function(){
-			dojo.dnd.Mover.prototype.destroy.apply(this, arguments);
+			Mover.prototype.destroy.apply(this, arguments);
 			var widget = this.widget;
 			widget._abspos = null;
 			widget._bar = null;
@@ -372,22 +367,18 @@ dojo.require("dojox.fx");
 		}
 	});
 
-	dojo.declare("dojox.form.HorizontalRangeSlider",
-		[dijit.form.HorizontalSlider, dojox.form._RangeSliderMixin],
-		{
-			// summary:
-			// 	A form widget that allows one to select a range with two horizontally draggable images
-			templateString: dojo.cache('dojox.form','resources/HorizontalRangeSlider.html')
-		}
-	);
-
-	dojo.declare("dojox.form.VerticalRangeSlider",
-		[dijit.form.VerticalSlider, dojox.form._RangeSliderMixin],
-		{
-			// summary:
-			// 	A form widget that allows one to select a range with two vertically draggable images
-			templateString: dojo.cache('dojox.form','resources/VerticalRangeSlider.html')
-		}
-	);
+	declare("dojox.form.HorizontalRangeSlider", [HorizontalSlider, RangeSliderMixin], {
+		// summary:
+		//	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
+		templateString: vTemplate
+	});
+
+	return RangeSliderMixin;
 
-})();
+});
diff --git a/dojox/form/Rating.js b/dojox/form/Rating.js
index 449cd3d..c8e36a3 100644
--- a/dojox/form/Rating.js
+++ b/dojox/form/Rating.js
@@ -1,9 +1,17 @@
-dojo.provide("dojox.form.Rating");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/dom-attr",
+	"dojo/dom-class",
+	"dojo/string",
+	"dojo/query",
+	"dijit/form/_FormWidget"
+], function(declare, lang, domAttr, domClass, string, query, FormWidget){
 
-dojo.require("dijit.form._FormWidget");
-
-dojo.declare("dojox.form.Rating",
-	dijit.form._FormWidget,{
+	/*=====
+		FormWidget = dijit.form._FormWidget;
+	=====*/
+return declare("dojox.form.Rating", FormWidget,{
 	// summary:
 	//		A widget for rating using stars.
 	//
@@ -12,7 +20,7 @@ dojo.declare("dojox.form.Rating",
 	// required: false,
 
 	templateString: null,
-	
+
 	// numStars: Integer/Float
 	//		The number of stars to show, default is 3.
 	numStars: 3,
@@ -23,13 +31,13 @@ dojo.declare("dojox.form.Rating",
 	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.
-		dojo.mixin(this, params);
-		
+		lang.mixin(this, params);
+
 		// TODO actually "dijitInline" should be applied to the surrounding div, but FF2
-		// screws up when we dojo.query() for the star nodes, it orders them randomly, because of the use
+		// 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>' +
@@ -38,9 +46,9 @@ dojo.declare("dojox.form.Rating",
 		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 += dojo.string.substitute(starTpl, {value:i+1});
+			rendered += string.substitute(starTpl, {value:i+1});
 		}
-		this.templateString = dojo.string.substitute(tpl, {stars:rendered});
+		this.templateString = string.substitute(tpl, {stars:rendered});
 	},
 
 	postCreate: function(){
@@ -50,7 +58,7 @@ dojo.declare("dojox.form.Rating",
 
 	_onMouse: function(evt){
 		if(this.hovering){
-			var hoverValue = +dojo.attr(evt.target, "value");
+			var hoverValue = +domAttr.get(evt.target, "value");
 			this.onMouseOver(evt, hoverValue);
 			this._renderStars(hoverValue, true);
 		}else{
@@ -60,36 +68,37 @@ dojo.declare("dojox.form.Rating",
 
 	_renderStars: function(value, hover){
 		// summary: Render the stars depending on the value.
-		dojo.query(".dojoxRatingStar", this.domNode).forEach(function(star, i){
+		query(".dojoxRatingStar", this.domNode).forEach(function(star, i){
 			if(i + 1 > value){
-				dojo.removeClass(star, "dojoxRatingStarHover");
-				dojo.removeClass(star, "dojoxRatingStarChecked");
+				domClass.remove(star, "dojoxRatingStarHover");
+				domClass.remove(star, "dojoxRatingStarChecked");
 			}else{
-				dojo.removeClass(star, "dojoxRatingStar" + (hover ? "Checked" : "Hover"));
-				dojo.addClass(star, "dojoxRatingStar" + (hover ? "Hover" : "Checked"));
+				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: dojo.connect(widget, "onStarClick", function(event){ ... })
-		var newVal = +dojo.attr(evt.target, "value");
+		// 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.inherited("setAttribute", arguments);
-		if (key=="value"){
+		this.set(key, value);
+		if(key=="value"){
 			this._renderStars(this.value);
 			this.onChange(this.value); // Do I really have to call this by hand? :-(
 		}
 	}
 });
+});
diff --git a/dojox/form/TimeSpinner.js b/dojox/form/TimeSpinner.js
index 2be058e..72d44b7 100644
--- a/dojox/form/TimeSpinner.js
+++ b/dojox/form/TimeSpinner.js
@@ -1,13 +1,17 @@
-dojo.provide("dojox.form.TimeSpinner");
-
-dojo.require("dijit.form._Spinner");
-dojo.require("dojo.date");
-dojo.require("dojo.date.locale");
-dojo.require("dojo.date.stamp");
-
-dojo.declare(
-"dojox.form.TimeSpinner",
-[dijit.form._Spinner],
+define([
+	"dojo/_base/lang",
+	"dojo/_base/event",
+	"dijit/form/_Spinner",
+	"dojo/keys",
+	"dojo/date",
+	"dojo/date/locale",
+	"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,
 {
 	// summary: Time Spinner
 	// description: This widget is the same as a normal NumberSpinner, but for the time component of a date object instead
@@ -15,7 +19,7 @@ dojo.declare(
 	required: false,
 
 	adjust: function(/* Object */ val, /*Number*/ delta){
-		return dojo.date.add(val, "minute", delta)
+		return dateUtil.add(val, "minute", delta)
 	},
 
 	//FIXME should we allow for constraints in this widget?
@@ -28,29 +32,30 @@ dojo.declare(
 	timeoutChangeRate: 0.50,
 
 	parse: function(time, locale){
-		return dojo.date.locale.parse(time, {selector:"time", formatLength:"short"});
+		return dateLocale.parse(time, {selector:"time", formatLength:"short"});
 	},
 
 	format: function(time, locale){
-		if (dojo.isString(time)) { return time; }
-		return dojo.date.locale.format(time, {selector:"time", formatLength:"short"});
+		if(lang.isString(time)){ return time; }
+		return dateLocale.format(time, {selector:"time", formatLength:"short"});
 	},
 
-	serialize: dojo.date.stamp.toISOString,
+	serialize: dateStamp.toISOString,
 
 	value: "12:00 AM",
 
        _onKeyPress: function(e){
-                if((e.charOrCode == dojo.keys.HOME || e.charOrCode == dojo.keys.END) && !(e.ctrlKey || e.altKey || e.metaKey)
+                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 == dojo.keys.HOME ? "min" : "max")];
+                        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
-                        dojo.stopEvent(e);
+                        event.stop(e);
                 }
         }
 
 
 });
+});
diff --git a/dojox/form/TriStateCheckBox.js b/dojox/form/TriStateCheckBox.js
new file mode 100644
index 0000000..54a88ff
--- /dev/null
+++ b/dojox/form/TriStateCheckBox.js
@@ -0,0 +1,243 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/event",
+	"dojo/query",
+	"dojo/dom-attr",
+	"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
+
+		templateString: template,
+
+		baseClass: "dojoxTriStateCheckBox",
+
+		// type: [private] String
+		//		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"],
+		=====*/
+
+		/*=====
+		// _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'
+		},
+		=====*/
+
+		/*=====
+		// stateValues: Object
+		//		The values of the TriStateCheckBox in corresponding states.
+		stateValues:	{
+				"False": "off",
+				"True": "on",
+				"Mixed": "mixed"
+		},
+		=====*/
+
+		// _currentState: Integer
+		//		The current state of the TriStateCheckBox
+		_currentState: 0,
+
+		// _stateType: String
+		//		The current state type of the TriStateCheckBox
+		//		Could be "False", "True" or "Mixed"
+		_stateType: "False",
+
+		// readOnly: Boolean
+		//		Should this widget respond to user input?
+		//		In markup, this is specified as "readOnly".
+		//		Similar to disabled except readOnly form values are submitted.
+		readOnly: false,
+
+		constructor: function(){
+			// summary:
+			//		Runs on widget initialization to setup arrays etc.
+			// tags:
+			//		private
+			this.states = [false, true, "mixed"];
+			this._stateLabels = {
+				"False": '&#63219',
+				"True": '√',
+				"Mixed": '&#8801'
+			};
+			this.stateValues = {
+				"False": "off",
+				"True": "on",
+				"Mixed": "mixed"
+			};
+		},
+
+		// 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
+			//		set('checked', val).
+			// checked:
+			//		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);
+		},
+
+		setChecked: function(/*String|Boolean*/ checked){
+			// summary:
+			//		Deprecated.  Use set('checked', true/false) instead.
+			kernel.deprecated("setChecked("+checked+") is deprecated. Use set('checked',"+checked+") instead.", "", "2.0");
+			this.set('checked', checked);
+		},
+
+		_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){
+			// summary:
+			//		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>.
+			//
+			//		After initialization,
+			//		when passed a boolean or the string 'mixed', controls the state of the
+			//		TriStateCheckBox.
+			//		If passed a string except 'mixed', changes the value attribute of the
+			//		TriStateCheckBox. Sets the state of the TriStateCheckBox to checked.
+			if(typeof newValue == "string" && (array.indexOf(this.states, newValue) < 0)){
+				if(newValue == ""){
+					newValue = "on";
+				}
+				this.stateValues["True"] = newValue;
+				newValue = true;
+			}
+			if(this._created){
+				this._currentState = array.indexOf(this.states, newValue);
+				this.set('checked', newValue, priorityChange);
+				domAttr.set(this.focusNode, "value", this.stateValues[this._stateType]);
+			}
+		},
+
+		_setValuesAttr: function(/*Array*/ newValues){
+			// summary:
+			//		Handler for values = attribute to constructor, and also calls to
+			//		set('values', val).
+			// newValues:
+			//		If the length of newValues is 1, it will replace the value of
+			//		the TriStateCheckBox in true state. Otherwise, the values of
+			//		the TriStateCheckBox in true state and 'mixed' state will be
+			//		replaced by the first two values in newValues.
+			// 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"];
+		},
+
+		_getValueAttr: function(){
+			// summary:
+			//		Hook so get('value') works.
+			// description:
+			//		Returns value according to current state of the TriStateCheckBox.
+			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",
+				"True" : "on",
+				"Mixed" : "mixed"
+			};
+			this.set('checked', this.params.checked || this.states[0]);
+		},
+
+		_onFocus: function(){
+			if(this.id){
+				query("label[for='"+this.id+"']").addClass("dijitFocusedLabel");
+			}
+			this.inherited(arguments);
+		},
+
+		_onBlur: function(){
+			if(this.id){
+				query("label[for='"+this.id+"']").removeClass("dijitFocusedLabel");
+			}
+			this.inherited(arguments);
+		},
+
+		_onClick: function(/*Event*/ e){
+			// summary:
+			//		Internal function to handle click actions - need to check
+			//		readOnly and disabled
+			if(this.readOnly || this.disabled){
+				event.stop(e);
+				return false;
+			}
+			if(this._currentState >= this.states.length - 1){
+				this._currentState = 0;
+			}else{
+				this._currentState++;
+			}
+			this.set("checked", this.states[this._currentState]);
+			domAttr.set(this.stateLabelNode, 'innerHTML', this._stateLabels[this._stateType]);
+			return this.onClick(e); // user click actions
+		},
+
+		_getStateType: function(/*String|Boolean*/ state){
+			//	summary:
+			//		Internal function to return the type of a certain state
+			//		false: False
+			//		true: True
+			//		"mixed": Mixed
+			return state ? (state == "mixed" ? "Mixed" : "True") : "False";
+		}
+	}
+);
+
+});
diff --git a/dojox/form/Uploader.js b/dojox/form/Uploader.js
index 170bd48..d458223 100644
--- a/dojox/form/Uploader.js
+++ b/dojox/form/Uploader.js
@@ -1,8 +1,23 @@
-dojo.provide("dojox.form.Uploader");
-dojo.experimental("dojox.form.Uploader");
-dojo.require("dojox.form.uploader.Base");
-dojo.require("dijit.form.Button");
-
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/window",
+	"dojo/dom-style",
+	"dojo/dom-geometry",
+	"dojo/dom-attr",
+	"dojo/dom-construct",
+	"dojo/dom-form",
+	"dijit",
+	"dijit/form/Button",
+	"dojox/form/uploader/Base",
+	"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){
+
+	kernel.experimental("dojox.form.Uploader");
 	//
 	// TODO:
 	//		i18n
@@ -12,9 +27,14 @@ dojo.require("dijit.form.Button");
 	//		Use new FileReader() for thumbnails
 	//		flashFieldName should default to Flash
 	//		get('value'); and set warning
+	//		Make it so URL can change (current set to Flash on build)
 	//
 
-dojo.declare("dojox.form.Uploader", [dojox.form.uploader.Base], {
+	/*=====
+		uploader = dojox.form.uploader.Base;
+		WidgetsInTemplateMixin = dijit._WidgetsInTemplateMixin;
+	=====*/
+declare("dojox.form.Uploader", [uploader, Button], {
 	//
 	// Version: 1.6
 	//
@@ -49,7 +69,7 @@ dojo.declare("dojox.form.Uploader", [dojox.form.uploader.Base], {
 	//
 	//	label: String
 	//		The text used in the button that when clicked, opens a system Browse Dialog.
-	label:"Upload...",
+	label:res.label,
 	//
 	// url: String
 	//		The url targeted for upload. An absolute URL is preferred. Relative URLs are
@@ -73,28 +93,68 @@ dojo.declare("dojox.form.Uploader", [dojox.form.uploader.Base], {
 	//		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,
-	widgetsInTemplate:true,
-	templateString:'<div class="dojoxFileInput"><div dojoType="dijit.form.Button" dojoAttachPoint="button">${label}</div></div>',
+
+	templateString: template,
+
+	baseClass: 'dijitUploader '+Button.prototype.baseClass,
 
 	postMixInProperties: function(){
 		this._inputs = [];
-		this._getButtonStyle(this.srcNodeRef);
+		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);
 	},
-	postCreate: function(){
-		var restore = false;
-		var parent = this.domNode.parentNode;
-		var position = this._getNodePosition(this.domNode);
-		if(!this.btnSize.w || !this.btnSize.h) {
-			dojo.body().appendChild(this.domNode);
-			this._getButtonStyle(this.domNode);
-			restore = true;
+	_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 = '';
+			});
 		}
-		this._setButtonStyle();
-		if(restore){
-			dojo.place(this.domNode, position.node, position.pos)
+	},
+
+	startup: function(){
+		if(this._buildInitialized){
+			return;
 		}
+		this._buildInitialized = true;
+		this._getButtonStyle(this.domNode);
+		this._setButtonStyle();
 		this.inherited(arguments);
 	},
 
@@ -170,7 +230,10 @@ dojo.declare("dojox.form.Uploader", [dojox.form.uploader.Base], {
 	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. Only supported with plugins.
+		//		this instead of form submit.
+		form = !!form ? form.tagName ? form : this.getForm() : this.getForm();
+		var data = domForm.toObject(form);
+		this.upload(data);
 	},
 
 	reset: function(){
@@ -182,8 +245,9 @@ dojo.declare("dojox.form.Uploader", [dojox.form.uploader.Base], {
 		// 		TODO:
 		// 		Add this ability by effectively, not uploading them
 		//
+		delete this._files;
 		this._disconnectButton();
-		dojo.forEach(this._inputs, dojo.destroy, dojo);
+		array.forEach(this._inputs, domConstruct.destroy, dojo);
 		this._inputs = [];
 		this._nameIndex = 0;
 		this._createInput();
@@ -195,7 +259,7 @@ dojo.declare("dojox.form.Uploader", [dojox.form.uploader.Base], {
 		//
 		var fileArray = [];
 		if(this.supports("multiple")){
-			dojo.forEach(this.inputNode.files, function(f, i){
+			array.forEach(this._files, function(f, i){
 				fileArray.push({
 					index:i,
 					name:f.name,
@@ -204,14 +268,16 @@ dojo.declare("dojox.form.Uploader", [dojox.form.uploader.Base], {
 				});
 			}, this);
 		}else{
-			dojo.forEach(this._inputs, function(n, i){
-				fileArray.push({
-					index:i,
-					name:n.value.substring(n.value.lastIndexOf("\\")+1),
-					size:0,
-					type:n.value.substring(n.value.lastIndexOf(".")+1)
-				});
-			}, this)
+			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
@@ -231,84 +297,26 @@ dojo.declare("dojox.form.Uploader", [dojox.form.uploader.Base], {
 		console.error("Uploader value is read only");
 	},
 
-	_getDisabledAttr: function(){
-		// summary:
-		//		Internal. To get disabled use: uploader.get("disabled");
-		return this._disabled;
-	},
-
 	_setDisabledAttr: function(disabled){
 		// summary:
 		//		Internal. To set disabled use: uploader.set("disabled", true);
 		if(this._disabled == disabled){ return; }
-		this.button.set('disabled', disabled);
-		dojo.style(this.inputNode, "display", disabled ? "none" : "block");
-	},
-
-	_getNodePosition: function(node){
-		if(node.previousSibling){
-			return {
-				node:node.previousSibling,
-				pos:"after"
-			}
-		}
-		return {
-			node:node.nextSibling,
-			pos:"before"
-		}
+		this.inherited(arguments);
+		domStyle.set(this.inputNode, "display", disabled ? "none" : "");
 	},
 
 	_getButtonStyle: function(node){
-		if(!node){
-			// we don't want this to happen. But if it does, try and display *something*.
-			this.btnSize = {
-				w:200,
-				h:25
-			};
-		}else{
-			this.btnSize = dojo.marginBox(node);
-		}
+		this.btnSize = {w:domStyle.get(node,'width'), h:domStyle.get(node,'height')};
 	},
 
 	_setButtonStyle: function(){
-		var hasParent = true;
-		if(!this.domNode.parentNode || !this.domNode.parentNode.tagName){
-			document.body.appendChild(this.domNode);
-			hasParent = false;
-		}
-
-		dojo.style(this.domNode, {
-			width:this.btnSize.w+"px",
-			height:(this.btnSize.h+4)+"px",
-			overflow:"hidden",
-			position:"relative"
-		});
-
 		this.inputNodeFontSize = Math.max(2, Math.max(Math.ceil(this.btnSize.w / 60), Math.ceil(this.btnSize.h / 15)));
 		this._createInput();
-
-		dojo.style(this.button.domNode, {
-			margin:"0px",
-			display:"block",
-			verticalAlign:"top" // IE fix
-
-		});
-
-		dojo.style(this.button.domNode.firstChild, {
-			margin:"0px",
-			display:"block"
-			//height:this.btnSize.h+"px"
-		});
-
-		if(!hasParent){
-			document.body.removeChild(this.domNode);
-		}
 	},
 
 	_createInput: function(){
-
 		if(this._inputs.length){
-			dojo.style(this.inputNode, {
+			domStyle.set(this.inputNode, {
 				top:"500px"
 			});
 			this._disconnectButton();
@@ -323,61 +331,49 @@ dojo.declare("dojox.form.Uploader", [dojox.form.uploader.Base], {
 			// <=IE8
 			name = this.name + (this.multiple ? this._nameIndex : "");
 		}
-		this.inputNode = dojo.create("input", {type:"file", name:name, className:"dojoxInputNode"}, this.domNode, "first");
+		// 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){
-			dojo.attr(this.inputNode, "multiple", true);
+			domAttr.set(this.inputNode, "multiple", true);
 		}
 		this._inputs.push(this.inputNode);
 
-
-		dojo.style(this.inputNode, {
-			fontSize:this.inputNodeFontSize+"em"
-		});
-		var size = dojo.marginBox(this.inputNode);
-
-		dojo.style(this.inputNode, {
+		domStyle.set(this.inputNode, {
 			position:"absolute",
-			top:"-2px",
-			left:"-"+(size.w-this.btnSize.w-2)+"px",
+			fontSize:this.inputNodeFontSize+"em",
+			top:"-3px",
+			right:"-3px",
 			opacity:0
 		});
 		this._connectButton();
 	},
 
 	_connectButton: function(){
-		this._cons = [];
-		var cs = dojo.hitch(this, function(nm){
-			this._cons.push(dojo.connect(this.inputNode, nm, this, function(evt){
-				this.button._cssMouseEvent({type:nm})
-			}));
-		});
-		cs("mouseover");
-		cs("mouseout");
-		cs("mousedown");
-		this._cons.push(dojo.connect(this.inputNode, "change", this, function(evt){
+		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();
 		}));
 
-		this.button.set('tabIndex', -1);
 		if(this.tabIndex > -1){
 			this.inputNode.tabIndex = this.tabIndex;
-			var restoreBorderStyle = dojo.style(this.button.domNode.firstChild, "border");
-			this._cons.push(dojo.connect(this.inputNode, "focus", this, function(){
-				dojo.style(this.button.domNode.firstChild, "border", "1px dashed #ccc");
+
+			this._cons.push(connect.connect(this.inputNode, "focus", this, function(){
+				this.titleNode.style.outline= "1px dashed #ccc";
 			}));
-			this._cons.push(dojo.connect(this.inputNode, "blur", this, function(){
-				dojo.style(this.button.domNode.firstChild, "border", restoreBorderStyle);
+			this._cons.push(connect.connect(this.inputNode, "blur", this, function(){
+				this.titleNode.style.outline = "";
 			}));
 		}
 	},
 
 	_disconnectButton: function(){
-		dojo.forEach(this._cons, dojo.disconnect, dojo);
+		array.forEach(this._cons, connect.disconnect);
+		this._cons.splice(0,this._cons.length);
 	}
 });
 
-(function(){
 	dojox.form.UploaderOrg = dojox.form.Uploader;
 	var extensions = [dojox.form.UploaderOrg];
 	dojox.form.addUploaderPlugin = function(plug){
@@ -386,6 +382,8 @@ dojo.declare("dojox.form.Uploader", [dojox.form.uploader.Base], {
 		// 		the dojox.form.Uploader is recreated using the new plugin (mixin).
 		//
 		extensions.push(plug);
-		dojo.declare("dojox.form.Uploader", extensions, {});
+		declare("dojox.form.Uploader", extensions, {});
 	}
-})();
+
+	return dojox.form.Uploader;
+});
diff --git a/dojox/form/_FormSelectWidget.js b/dojox/form/_FormSelectWidget.js
index 5620fd9..8ac7e4c 100644
--- a/dojox/form/_FormSelectWidget.js
+++ b/dojox/form/_FormSelectWidget.js
@@ -1,6 +1,10 @@
-dojo.deprecated("dojox.form._FormSelectWidget", "Use dijit.form._FormSelectWidget instead", "2.0");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dijit/form/_FormSelectWidget"
+], function(kernel, lang, _FormSelectWidget){
+	kernel.deprecated("dojox.form._FormSelectWidget", "Use dijit.form._FormSelectWidget instead", "2.0");
 
-dojo.provide("dojox.form._FormSelectWidget");
-dojo.require("dijit.form._FormSelectWidget");
-
-dojo.setObject("dojox.form._FormSelectWidget", dijit.form._FormSelectWidget);
\ No newline at end of file
+	lang.setObject("dojox.form._FormSelectWidget", _FormSelectWidget);
+	return _FormSelectWidget;
+});
\ No newline at end of file
diff --git a/dojox/form/_HasDropDown.js b/dojox/form/_HasDropDown.js
index 4c9d7e6..252e65e 100644
--- a/dojox/form/_HasDropDown.js
+++ b/dojox/form/_HasDropDown.js
@@ -1,6 +1,10 @@
-dojo.deprecated("dojox.form._HasDropDown", "Use dijit._HasDropDown instead", "2.0");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dijit/_HasDropDown"
+], function(kernel, _HasDropDown){
+	kernel.deprecated("dojox.form._HasDropDown", "Use dijit._HasDropDown instead", "2.0");
 
-dojo.provide("dojox.form._HasDropDown");
-dojo.require("dijit._HasDropDown");
-
-dojo.setObject("dojox.form._HasDropDown", dijit._HasDropDown);
\ No newline at end of file
+	lang.setObject("dojox.form._HasDropDown", _HasDropDown);
+	return _HasDropDown;
+});
\ No newline at end of file
diff --git a/dojox/form/_SelectStackMixin.js b/dojox/form/_SelectStackMixin.js
index ae543b8..5818a31 100644
--- a/dojox/form/_SelectStackMixin.js
+++ b/dojox/form/_SelectStackMixin.js
@@ -1,6 +1,12 @@
-dojo.provide("dojox.form._SelectStackMixin");
+define([
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dijit/_base/manager",
+	"dojo/_base/connect",
+	"dojo/_base/declare"
+], function(lang, array, manager, connect, declare){
 
-dojo.declare("dojox.form._SelectStackMixin", null, {
+return declare("dojox.form._SelectStackMixin", null, {
 	// summary:
 	//		Mix this class in to a dijit.form._FormSelectWidget in order to
 	//		provide support for "selectable" multiforms.  The widget is pointed
@@ -17,7 +23,7 @@ dojo.declare("dojox.form._SelectStackMixin", null, {
 	// stackId: string
 	//		The id of the stack that this widget is supposed to control
 	stackId: "",
-	
+
 	// 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
@@ -28,12 +34,12 @@ dojo.declare("dojox.form._SelectStackMixin", null, {
 	//		with the same values - without having to have the panes require the
 	//		same ids.
 	stackPrefix: "",
-	
+
 	_paneIdFromOption: function(/*String*/ oVal){
 		// 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
 		var sp = this.stackPrefix;
@@ -42,17 +48,17 @@ dojo.declare("dojox.form._SelectStackMixin", null, {
 		}
 		return id; // String
 	},
-	
+
 	_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)
-		
+
 		if(pane._shown != undefined && pane._shown == shown){ return; }
-		var widgets = dojo.filter(pane.getDescendants(), "return item.name;");
+		var widgets = array.filter(pane.getDescendants(), "return item.name;");
 		if(!shown){
 			// We are hiding - save the current state and then disable them
 			savedStates = {};
-			dojo.forEach(widgets, function(w){
+			array.forEach(widgets, function(w){
 				savedStates[w.id] = w.disabled;
 				w.set("disabled", true);
 			});
@@ -60,7 +66,7 @@ dojo.declare("dojox.form._SelectStackMixin", null, {
 		}else{
 			// We are showing - restore our saved states
 			var savedStates = pane._savedStates||{};
-			dojo.forEach(widgets, function(w){
+			array.forEach(widgets, function(w){
 				var state = savedStates[w.id];
 				if(state == undefined){
 					state = false;
@@ -71,9 +77,9 @@ dojo.declare("dojox.form._SelectStackMixin", null, {
 		}
 		pane._shown = shown;
 	},
-	
+
 	_connectTitle: function(/*dijit._Widget*/ pane, /*String*/ value){
-		var fx = dojo.hitch(this, function(title){
+		var fx = lang.hitch(this, function(title){
 			this.updateOption({value: value, label: title});
 		});
 		if(pane._setTitleAttr){
@@ -96,12 +102,12 @@ dojo.declare("dojox.form._SelectStackMixin", null, {
 			this._connectTitle(pane, v);
 		}
 		if(!pane.onShow || !pane.onHide || pane._shown == undefined){
-			pane.onShow = dojo.hitch(this, "_togglePane", pane, true);
-			pane.onHide = dojo.hitch(this, "_togglePane", pane, false);
+			pane.onShow = lang.hitch(this, "_togglePane", pane, true);
+			pane.onHide = lang.hitch(this, "_togglePane", pane, false);
 			pane.onHide();
 		}
 	},
-	
+
 	_setValueAttr: function(v){
 		if("_savedValue" in this){
 			return;
@@ -122,16 +128,16 @@ dojo.declare("dojox.form._SelectStackMixin", null, {
 			this.removeOption(this._optionValFromPane(pane.id));
 		}
 	},
-	
+
 	onSelectChild: function(/*dijit._Widget*/ 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
 		var selPane = info.selected;
-		this.addOption(dojo.filter(dojo.map(info.children, function(c){
+		this.addOption(array.filter(array.map(info.children, function(c){
 			var v = this._optionValFromPane(c.id);
 			this._connectTitle(c, v);
 			var toAdd = null;
@@ -140,8 +146,8 @@ dojo.declare("dojox.form._SelectStackMixin", null, {
 				toAdd = {value: v, label: c.title};
 			}
 			if(!c.onShow || !c.onHide || c._shown == undefined){
-				c.onShow = dojo.hitch(this, "_togglePane", c, true);
-				c.onHide = dojo.hitch(this, "_togglePane", c, false);
+				c.onShow = lang.hitch(this, "_togglePane", c, true);
+				c.onHide = lang.hitch(this, "_togglePane", c, false);
 				c.onHide();
 			}
 			if("_savedValue" in this && v === this._savedValue){
@@ -161,7 +167,7 @@ dojo.declare("dojox.form._SelectStackMixin", null, {
 			}
 		};
 		if(selPane !== info.selected){
-			var stack = dijit.byId(this.stackId);
+			var stack = manager.byId(this.stackId);
 			var c = this.connect(stack, "_showChild", function(sel){
 				this.disconnect(c);
 				fx();
@@ -170,40 +176,40 @@ dojo.declare("dojox.form._SelectStackMixin", null, {
 			fx();
 		}
 	},
-	
+
 	postMixInProperties: function(){
 		this._savedValue = this.value;
 		this.inherited(arguments);
 		this.connect(this, "onChange", "_handleSelfOnChange");
 	},
-	
+
 	postCreate: function(){
 		this.inherited(arguments);
 		this._panes = {};
 		this._subscriptions = [
-			dojo.subscribe(this.stackId + "-startup", this, "onStartup"),
-			dojo.subscribe(this.stackId + "-addChild", this, "onAddChild"),
-			dojo.subscribe(this.stackId + "-removeChild", this, "onRemoveChild"),
-			dojo.subscribe(this.stackId + "-selectChild", this, "onSelectChild")
+			connect.subscribe(this.stackId + "-startup", this, "onStartup"),
+			connect.subscribe(this.stackId + "-addChild", this, "onAddChild"),
+			connect.subscribe(this.stackId + "-removeChild", this, "onRemoveChild"),
+			connect.subscribe(this.stackId + "-selectChild", this, "onSelectChild")
 		];
-		var stack = dijit.byId(this.stackId);
+		var stack = manager.byId(this.stackId);
 		if(stack && stack._started){
 			// If we have a stack, and it's already started, call our onStartup now
 			this.onStartup({children: stack.getChildren(), selected: stack.selectedChildWidget});
 		}
 	},
-	
+
 	destroy: function(){
-		dojo.forEach(this._subscriptions, dojo.unsubscribe);
+		array.forEach(this._subscriptions, connect.unsubscribe);
 		delete this._panes; // Fixes memory leak in IE
 		this.inherited("destroy", arguments);
 	},
-	
+
 	_handleSelfOnChange: function(/*String*/ val){
 		// summary: Called when form select widget's value has changed
 		var pane = this._panes[this._paneIdFromOption(val)];
-		if (pane){
-			var s = dijit.byId(this.stackId);
+		if(pane){
+			var s = manager.byId(this.stackId);
 			if(pane == s.selectedChildWidget){
 				s._transition(pane);
 			}else{
@@ -212,3 +218,4 @@ dojo.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 74dc747..e1c2236 100644
--- a/dojox/form/manager/_ClassMixin.js
+++ b/dojox/form/manager/_ClassMixin.js
@@ -1,13 +1,15 @@
-dojo.provide("dojox.form.manager._ClassMixin");
-
-dojo.require("dojox.form.manager._Mixin");
-
-(function(){
-	var fm = dojox.form.manager,
+define([
+	"dojo/_base/lang",
+	"dojo/_base/kernel",
+	"dojo/dom-class",
+	"./_Mixin",
+	"dojo/_base/declare"
+], function(lang, dojo, domClass, _Mixin, declare){
+	var fm = lang.getObject("dojox.form.manager", true),
 		aa = fm.actionAdapter,
 		ia = fm.inspectorAdapter;
 
-	dojo.declare("dojox.form.manager._ClassMixin", null, {
+	return declare("dojox.form.manager._ClassMixin", null, {
 		// summary:
 		//		Form manager's mixin for testing/assigning/removing
 		//		classes of controlled elements.
@@ -27,7 +29,7 @@ dojo.require("dojox.form.manager._Mixin");
 			//		If it is omitted, all known form elements are to be processed.
 
 			var result = this.inspect(ia(function(name, node){
-				return dojo.hasClass(node, className);
+				return domClass.contains(node, className);
 			}), names);
 
 			return result;	// Object
@@ -44,7 +46,7 @@ dojo.require("dojox.form.manager._Mixin");
 			//		If it is omitted, all known form elements are to be processed.
 
 			this.inspect(aa(function(name, node){
-				dojo.addClass(node, className);
+				domClass.add(node, className);
 			}), names);
 
 			return this;	// self
@@ -61,10 +63,10 @@ dojo.require("dojox.form.manager._Mixin");
 			//		If it is omitted, all known form elements are to be processed.
 
 			this.inspect(aa(function(name, node){
-				dojo.removeClass(node, className);
+				domClass.remove(node, className);
 			}), names);
 
 			return this;	// self
 		}
 	});
-})();
+});
diff --git a/dojox/form/manager/_DisplayMixin.js b/dojox/form/manager/_DisplayMixin.js
index c4b84e9..748ed6d 100644
--- a/dojox/form/manager/_DisplayMixin.js
+++ b/dojox/form/manager/_DisplayMixin.js
@@ -1,6 +1,9 @@
-dojo.provide("dojox.form.manager._DisplayMixin");
-
-dojo.declare("dojox.form.manager._DisplayMixin", null, {
+define([
+	"dojo/_base/kernel",
+	"dojo/dom-style",
+	"dojo/_base/declare"
+], function(dojo, domStyle, declare){
+return declare("dojox.form.manager._DisplayMixin", null, {
 	// summary:
 	//		Form manager's mixin for controlling show/hide state of
 	//		controlled elements (defined by dojoAttachPoint attributes).
@@ -20,7 +23,7 @@ dojo.declare("dojox.form.manager._DisplayMixin", null, {
 		//		If it is omitted, all known attach point nodes are to be processed.
 
 		var result = this.inspectAttachedPoints(function(name, node){
-			return dojo.style(node, "display") != "none";
+			return domStyle.get(node, "display") != "none";
 		}, names);
 
 		return result;	// Object
@@ -42,7 +45,7 @@ dojo.declare("dojox.form.manager._DisplayMixin", null, {
 		}
 
 		this.inspectAttachedPoints(function(name, node, value){
-			dojo.style(node, "display", value ? "" : "none");
+			domStyle.set(node, "display", value ? "" : "none");
 		}, state, defaultState);
 
 		return this;	// self
@@ -59,3 +62,4 @@ dojo.declare("dojox.form.manager._DisplayMixin", null, {
 		return this.show(state, false);	// self
 	}
 });
+});
diff --git a/dojox/form/manager/_EnableMixin.js b/dojox/form/manager/_EnableMixin.js
index 1a9aec3..8308cbf 100644
--- a/dojox/form/manager/_EnableMixin.js
+++ b/dojox/form/manager/_EnableMixin.js
@@ -1,13 +1,15 @@
-dojo.provide("dojox.form.manager._EnableMixin");
-
-dojo.require("dojox.form.manager._Mixin");
-
-(function(){
-	var fm = dojox.form.manager,
+define([
+	"dojo/_base/lang",
+	"dojo/_base/kernel",
+	"dojo/dom-attr",
+	"./_Mixin",
+	"dojo/_base/declare"
+], function(lang, dojo, domAttr, _Mixin, declare){
+	var fm = lang.getObject("dojox.form.manager", true),
 		aa = fm.actionAdapter,
 		ia = fm.inspectorAdapter;
 
-	dojo.declare("dojox.form.manager._EnableMixin", null, {
+	return declare("dojox.form.manager._EnableMixin", null, {
 		// summary:
 		//		Form manager's mixin for controlling enable/disable state of
 		//		form elements.
@@ -29,8 +31,8 @@ dojo.require("dojox.form.manager._Mixin");
 			}), names);
 
 			if(this.inspectFormNodes){
-				dojo.mixin(result, this.inspectFormNodes(ia(function(name, node){
-					return !dojo.attr(node, "disabled");
+				lang.mixin(result, this.inspectFormNodes(ia(function(name, node){
+					return !domAttr.get(node, "disabled");
 				}), names));
 			}
 
@@ -58,7 +60,7 @@ dojo.require("dojox.form.manager._Mixin");
 
 			if(this.inspectFormNodes){
 				this.inspectFormNodes(aa(function(name, node, value){
-					dojo.attr(node, "disabled", !value);
+					domAttr.set(node, "disabled", !value);
 				}), state, defaultState);
 			}
 
@@ -78,4 +80,4 @@ dojo.require("dojox.form.manager._Mixin");
 			return oldState;	// Object
 		}
 	});
-})();
+});
diff --git a/dojox/form/manager/_FormMixin.js b/dojox/form/manager/_FormMixin.js
index e3d9218..5b876f8 100644
--- a/dojox/form/manager/_FormMixin.js
+++ b/dojox/form/manager/_FormMixin.js
@@ -1,12 +1,15 @@
-dojo.provide("dojox.form.manager._FormMixin");
-
-dojo.require("dojox.form.manager._Mixin");
-
-(function(){
-	var fm = dojox.form.manager,
+define([
+	"dojo/_base/lang",
+	"dojo/_base/kernel",
+	"dojo/_base/event",
+	"dojo/window",
+	"./_Mixin",
+	"dojo/_base/declare"
+], function(lang, dojo, event, windowUtils, _Mixin, declare){
+	var fm = lang.getObject("dojox.form.manager", true),
 		aa = fm.actionAdapter;
 
-	dojo.declare("dojox.form.manager._FormMixin", null, {
+	return declare("dojox.form.manager._FormMixin", null, {
 		// summary:
 		//		Form manager's mixin for form-specific functionality.
 		// description:
@@ -51,7 +54,7 @@ dojo.require("dojox.form.manager._Mixin");
 			if(!(this.onReset(faux) === false) && faux.returnValue){
 				this.reset();
 			}
-			dojo.stopEvent(evt);
+			event.stop(evt);
 			return false;
 		},
 
@@ -83,7 +86,7 @@ dojo.require("dojox.form.manager._Mixin");
 			// for form-based managers.
 
 			if(this.onSubmit(evt) === false){ // only exactly false stops submit
-				dojo.stopEvent(evt);
+				event.stop(evt);
 			}
 		},
 
@@ -125,7 +128,7 @@ dojo.require("dojox.form.manager._Mixin");
 			}
 			return true;
 		},
-		validate: function () {
+		validate: function(){
 			var isValid = true,
 				formWidgets = this.formWidgets,
 				didFocus = false, name;
@@ -138,7 +141,7 @@ dojo.require("dojox.form.manager._Mixin");
 					var valid = widget.disabled || !widget.validate || widget.validate();
 					if(!valid && !didFocus){
 						// Set focus of the first non-valid widget
-						dojo.window.scrollIntoView(widget.containerNode || widget.domNode);
+						windowUtils.scrollIntoView(widget.containerNode || widget.domNode);
 						widget.focus();
 						didFocus = true;
 					}
@@ -149,4 +152,4 @@ dojo.require("dojox.form.manager._Mixin");
 			return isValid;
 		}
 	});
-})();
+});
diff --git a/dojox/form/manager/_Mixin.js b/dojox/form/manager/_Mixin.js
index 98bd1a9..a75aa7b 100644
--- a/dojox/form/manager/_Mixin.js
+++ b/dojox/form/manager/_Mixin.js
@@ -1,9 +1,21 @@
-dojo.provide("dojox.form.manager._Mixin");
-
-dojo.require("dijit._Widget");
-
-(function(){
-	var fm = dojox.form.manager,
+define([
+	"dojo/_base/window",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/dom-attr",
+	"dojo/dom-class",
+	"dijit/_base/manager",
+	"dijit/_Widget",
+	"dijit/form/_FormWidget",
+	"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,
+	// which is wasteful
+
+	var fm = lang.getObject("dojox.form.manager", true),
 
 		aa = fm.actionAdapter = function(action){
 			// summary:
@@ -13,8 +25,8 @@ dojo.require("dijit._Widget");
 			//		(usually node or widget), and a value. This action will
 			//		be applied to all elements of array.
 			return function(name, elems, value){
-				if(dojo.isArray(elems)){
-					dojo.forEach(elems, function(elem){
+				if(lang.isArray(elems)){
+					array.forEach(elems, function(elem){
 						action.call(this, name, elem, value);
 					}, this);
 				}else{
@@ -30,7 +42,7 @@ dojo.require("dijit._Widget");
 			//		Function that takes three parameters: a name, an object
 			//		(usually node or widget), and a value.
 			return function(name, elem, value){
-				return inspector.call(this, name, dojo.isArray(elem) ? elem[0] : elem, value);
+				return inspector.call(this, name, lang.isArray(elem) ? elem[0] : elem, value);
 			};
 		},
 
@@ -49,10 +61,10 @@ dojo.require("dijit._Widget");
 
 		registerWidget = function(widget){
 			var name = widget.get("name");
-			if(name && widget instanceof dijit.form._FormWidget){
+			if(name && widget instanceof FormWidget){
 				if(name in this.formWidgets){
 					var a = this.formWidgets[name].widget;
-					if(dojo.isArray(a)){
+					if(lang.isArray(a)){
 						a.push(widget);
 					}else{
 						this.formWidgets[name].widget = [a, widget];
@@ -71,9 +83,9 @@ dojo.require("dijit._Widget");
 			aa(function(_, w){
 				var o = w.get("observer");
 				if(o && typeof o == "string"){
-					dojo.forEach(o.split(","), function(o){
-						o = dojo.trim(o);
-						if(o && dojo.isFunction(this[o])){
+					array.forEach(o.split(","), function(o){
+						o = lang.trim(o);
+						if(o && lang.isFunction(this[o])){
 							observers[o] = 1;
 						}
 					}, this);
@@ -85,18 +97,18 @@ dojo.require("dijit._Widget");
 		connectWidget = function(name, observers){
 			var t = this.formWidgets[name], w = t.widget, c = t.connections;
 			if(c.length){
-				dojo.forEach(c, dojo.disconnect);
+				array.forEach(c, connect.disconnect);
 				c = t.connections = [];
 			}
-			if(dojo.isArray(w)){
+			if(lang.isArray(w)){
 				// radio buttons
-				dojo.forEach(w, function(w){
-					dojo.forEach(observers, function(o){
-						c.push(dojo.connect(w, "onChange", this, function(evt){
+				array.forEach(w, function(w){
+					array.forEach(observers, function(o){
+						c.push(connect.connect(w, "onChange", 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 && dojo.attr(w.focusNode, "checked")){
+							if(this.watching && domAttr.get(w.focusNode, "checked")){
 								this[o](w.get("value"), name, w, evt);
 							}
 						}));
@@ -104,11 +116,11 @@ dojo.require("dijit._Widget");
 				}, this);
 			}else{
 				// the rest
-				// the next line is a crude workaround for dijit.form.Button that fires onClick instead of onChange
-				var eventName = w.declaredClass == "dijit.form.Button" ?
+				// the next line is a crude workaround for Button that fires onClick instead of onChange
+				var eventName = w.isInstanceOf(Button) ?
 						"onClick" : "onChange";
-				dojo.forEach(observers, function(o){
-					c.push(dojo.connect(w, eventName, this, function(evt){
+				array.forEach(observers, function(o){
+					c.push(connect.connect(w, eventName, this, function(evt){
 						if(this.watching){
 							this[o](w.get("value"), name, w, evt);
 						}
@@ -117,7 +129,7 @@ dojo.require("dijit._Widget");
 			}
 		};
 
-	dojo.declare("dojox.form.manager._Mixin", null, {
+	var _Mixin = declare("dojox.form.manager._Mixin", null, {
 		// summary:
 		//		Mixin to orchestrate dynamic forms.
 		// description:
@@ -133,7 +145,7 @@ dojo.require("dijit._Widget");
 		startup: function(){
 			// summary:
 			//		Called after all the widgets have been instantiated and their
-			//		dom nodes have been inserted somewhere under dojo.doc.body.
+			//		dom nodes have been inserted somewhere under win.doc.body.
 
 			if(this._started){ return; }
 
@@ -149,7 +161,7 @@ dojo.require("dijit._Widget");
 			//		Called when the widget is being destroyed
 
 			for(var name in this.formWidgets){
-				dojo.forEach(this.formWidgets[name].connections, dojo.disconnect);
+				array.forEach(this.formWidgets[name].connections, connect.disconnect);
 			}
 			this.formWidgets = {};
 
@@ -166,9 +178,9 @@ dojo.require("dijit._Widget");
 			// returns: Object:
 			//		Returns self
 			if(typeof widget == "string"){
-				widget = dijit.byId(widget);
+				widget = manager.byId(widget);
 			}else if(widget.tagName && widget.cloneNode){
-				widget = dijit.byNode(widget);
+				widget = manager.byNode(widget);
 			}
 			var name = registerWidget.call(this, widget);
 			if(name){
@@ -186,7 +198,7 @@ dojo.require("dijit._Widget");
 			// returns: Object:
 			//		Returns self
 			if(name in this.formWidgets){
-				dojo.forEach(this.formWidgets[name].connections, this.disconnect, this);
+				array.forEach(this.formWidgets[name].connections, this.disconnect, this);
 				delete this.formWidgets[name];
 			}
 			return this;
@@ -202,16 +214,16 @@ dojo.require("dijit._Widget");
 
 			// convert to widget, if required
 			if(typeof widget == "string"){
-				widget = dijit.byId(widget);
+				widget = manager.byId(widget);
 			}else if(widget.tagName && widget.cloneNode){
-				widget = dijit.byNode(widget);
+				widget = manager.byNode(widget);
 			}
 
 			// build the map of widgets
-			var widgets = dojo.map(widget.getDescendants(), registerWidget, this);
+			var widgets = array.map(widget.getDescendants(), registerWidget, this);
 
 			// process observers for widgets
-			dojo.forEach(widgets, function(name){
+			array.forEach(widgets, function(name){
 				if(name){
 					connectWidget.call(this, name, getObserversFromWidget.call(this, name));
 				}
@@ -232,17 +244,17 @@ dojo.require("dijit._Widget");
 
 			// convert to widget, if required
 			if(typeof widget == "string"){
-				widget = dijit.byId(widget);
+				widget = manager.byId(widget);
 			}else if(widget.tagName && widget.cloneNode){
-				widget = dijit.byNode(widget);
+				widget = manager.byNode(widget);
 			}
 
 			// unregister widgets by names
-			dojo.forEach(
-				dojo.map(
+			array.forEach(
+				array.map(
 					widget.getDescendants(),
 					function(w){
-						return w instanceof dijit.form._FormWidget && w.get("name") || null;
+						return w instanceof FormWidget && w.get("name") || null;
 					}
 				),
 				function(name){
@@ -284,23 +296,23 @@ dojo.require("dijit._Widget");
 				return null;	// Object
 			}
 
-			if(dojo.isArray(elem)){
+			if(lang.isArray(elem)){
 				// input/radio array of widgets
 				if(isSetter){
-					dojo.forEach(elem, function(widget){
+					array.forEach(elem, function(widget){
 						widget.set("checked", false, !this.watching);
 					});
-					dojo.forEach(elem, function(widget){
+					array.forEach(elem, function(widget){
 						widget.set("checked", widget.value === value, !this.watching);
 					});
 					return this;	// self
 				}
 				// getter
-				dojo.some(elem, function(widget){
+				array.some(elem, function(widget){
 					// 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(dojo.attr(widget.focusNode, "checked")){
+					if(domAttr.get(widget.focusNode, "checked")){
 					//if(widget.get("checked")){
 						result = widget;
 						return true;
@@ -311,7 +323,7 @@ dojo.require("dijit._Widget");
 			}
 
 			// checkbox widget is a special case :-(
-			if(elem.declaredClass == "dijit.form.CheckBox"){
+			if(elem.isInstanceOf && elem.isInstanceOf(CheckBox)){
 				if(isSetter){
 					elem.set("value", Boolean(value), !this.watching);
 					return this;	// self
@@ -346,7 +358,7 @@ dojo.require("dijit._Widget");
 				return null;	// Object
 			}
 
-			if(!dojo.hasClass(elem, "dojoFormValue")){
+			if(!domClass.contains(elem, "dojoFormValue")){
 				// accessing the value of the attached point not marked with CSS class 'dojoFormValue'
 				return null;
 			}
@@ -379,8 +391,8 @@ dojo.require("dijit._Widget");
 			var name, result = {};
 
 			if(state){
-				if(dojo.isArray(state)){
-					dojo.forEach(state, function(name){
+				if(lang.isArray(state)){
+					array.forEach(state, function(name){
 						if(name in this.formWidgets){
 							result[name] = inspector.call(this, name, this.formWidgets[name].widget, defaultValue);
 						}
@@ -418,8 +430,8 @@ dojo.require("dijit._Widget");
 			var name, result = {};
 
 			if(state){
-				if(dojo.isArray(state)){
-					dojo.forEach(state, function(name){
+				if(lang.isArray(state)){
+					array.forEach(state, function(name){
 						var elem = this[name];
 						if(elem && elem.tagName && elem.cloneNode){
 							result[name] = inspector.call(this, name, elem, defaultValue);
@@ -463,22 +475,23 @@ dojo.require("dijit._Widget");
 			//		Optional. The default state (true, if omitted).
 
 			var result = this.inspectFormWidgets(function(name, widget, value){
-				if(dojo.isArray(widget)){
-					return inspector.call(this, name, dojo.map(widget, function(w){ return w.domNode; }), value);
+				if(lang.isArray(widget)){
+					return inspector.call(this, name, array.map(widget, function(w){ return w.domNode; }), value);
 				}
 				return inspector.call(this, name, widget.domNode, value);
 			}, state, defaultValue);
 			if(this.inspectFormNodes){
-				dojo.mixin(result, this.inspectFormNodes(inspector, state, defaultValue));
+				lang.mixin(result, this.inspectFormNodes(inspector, state, defaultValue));
 			}
-			return dojo.mixin(result, this.inspectAttachedPoints(inspector, state, defaultValue));	// Object
+			return lang.mixin(result, this.inspectAttachedPoints(inspector, state, defaultValue));	// Object
 		}
 	});
-})();
 
 // These arguments can be specified for widgets which are used in forms.
 // Since any widget can be specified as sub widgets, mix it into the base
 // widget class.  (This is a hack, but it's effective.)
-dojo.extend(dijit._Widget, {
+lang.extend(Widget, {
 	observer: ""
 });
+return _Mixin;
+});
diff --git a/dojox/form/manager/_NodeMixin.js b/dojox/form/manager/_NodeMixin.js
index 20dcf4c..643a562 100644
--- a/dojox/form/manager/_NodeMixin.js
+++ b/dojox/form/manager/_NodeMixin.js
@@ -1,9 +1,16 @@
-dojo.provide("dojox.form.manager._NodeMixin");
-
-dojo.require("dojox.form.manager._Mixin");
-
-(function(){
-	var fm = dojox.form.manager,
+define([
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/dom",
+	"dojo/dom-attr",
+	"dojo/query",
+	"./_Mixin",
+	"dijit/form/_FormWidget",
+	"dijit/_base/manager",
+	"dojo/_base/declare"
+], function(lang, array, connect, dom, domAttr, query, _Mixin, _FormWidget, manager, declare){
+	var fm = lang.getObject("dojox.form.manager", true),
 		aa = fm.actionAdapter,
 		keys = fm._keys,
 
@@ -37,12 +44,12 @@ dojo.require("dojox.form.manager._Mixin");
 		},
 
 		registerNode = function(node, groupNode){
-			var name = dojo.attr(node, "name");
+			var name = domAttr.get(node, "name");
 			groupNode = groupNode || this.domNode;
 			if(name && !(name in this.formWidgets)){
 				// verify that it is not part of any widget
 				for(var n = node; n && n !== groupNode; n = n.parentNode){
-					if(dojo.attr(n, "widgetId") && dijit.byNode(n) instanceof dijit.form._FormWidget){
+					if(domAttr.get(n, "widgetId") && manager.byNode(n).isInstanceOf(_FormWidget)){
 						// this is a child of some widget --- bail out
 						return null;
 					}
@@ -51,7 +58,7 @@ dojo.require("dojox.form.manager._Mixin");
 				if(node.tagName.toLowerCase() == "input" && node.type.toLowerCase() == "radio"){
 					var a = this.formNodes[name];
 					a = a && a.node;
-					if(a && dojo.isArray(a)){
+					if(a && lang.isArray(a)){
 						a.push(node);
 					}else{
 						this.formNodes[name] = {node: [node], connections: []};
@@ -68,11 +75,11 @@ dojo.require("dojox.form.manager._Mixin");
 		getObserversFromNode = function(name){
 			var observers = {};
 			aa(function(_, n){
-				var o = dojo.attr(n, "observer");
+				var o = domAttr.get(n, "observer");
 				if(o && typeof o == "string"){
-					dojo.forEach(o.split(","), function(o){
-						o = dojo.trim(o);
-						if(o && dojo.isFunction(this[o])){
+					array.forEach(o.split(","), function(o){
+						o = lang.trim(o);
+						if(o && lang.isFunction(this[o])){
 							observers[o] = 1;
 						}
 					}, this);
@@ -84,14 +91,14 @@ dojo.require("dojox.form.manager._Mixin");
 		connectNode = function(name, observers){
 			var t = this.formNodes[name], c = t.connections;
 			if(c.length){
-				dojo.forEach(c, dojo.disconnect);
+				array.forEach(c, connect.disconnect);
 				c = t.connections = [];
 			}
 			aa(function(_, n){
-				// the next line is a crude workaround for dijit.form.Button that fires onClick instead of onChange
+				// the next line is a crude workaround for Button that fires onClick instead of onChange
 				var eventName = ce(n);
-				dojo.forEach(observers, function(o){
-					c.push(dojo.connect(n, eventName, this, function(evt){
+				array.forEach(observers, function(o){
+					c.push(connect.connect(n, eventName, this, function(evt){
 						if(this.watching){
 							this[o](this.formNodeValue(name), name, n, evt);
 						}
@@ -99,7 +106,8 @@ dojo.require("dojox.form.manager._Mixin");
 				}, this);
 			}).call(this, null, t.node);
 		};
-	dojo.declare("dojox.form.manager._NodeMixin", null, {
+
+	return declare("dojox.form.manager._NodeMixin", null, {
 		// summary:
 		//		Mixin to orchestrate dynamic forms (works with DOM nodes).
 		// description:
@@ -114,7 +122,7 @@ dojo.require("dojox.form.manager._Mixin");
 			//		Called when the widget is being destroyed
 
 			for(var name in this.formNodes){
-				dojo.forEach(this.formNodes[name].connections, dojo.disconnect);
+				array.forEach(this.formNodes[name].connections, connect.disconnect);
 			}
 			this.formNodes = {};
 
@@ -131,7 +139,7 @@ dojo.require("dojox.form.manager._Mixin");
 			// returns: Object:
 			//		Returns self
 			if(typeof node == "string"){
-				node = dojo.byId(node);
+				node = dom.byId(node);
 			}
 			var name = registerNode.call(this, node);
 			if(name){
@@ -149,7 +157,7 @@ dojo.require("dojox.form.manager._Mixin");
 			// returns: Object:
 			//		Returns self
 			if(name in this.formNodes){
-				dojo.forEach(this.formNodes[name].connections, this.disconnect, this);
+				array.forEach(this.formNodes[name].connections, this.disconnect, this);
 				delete this.formNodes[name];
 			}
 			return this;
@@ -164,10 +172,10 @@ dojo.require("dojox.form.manager._Mixin");
 			//		Returns self
 
 			if(typeof node == "string"){
-				node = dojo.byId(node);
+				node = dom.byId(node);
 			}
 
-			dojo.query("input, select, textarea, button", node).
+			query("input, select, textarea, button", node).
 				map(function(n){
 					return registerNode.call(this, n, node);
 				}, this).
@@ -189,11 +197,11 @@ dojo.require("dojox.form.manager._Mixin");
 			//		Returns self
 
 			if(typeof node == "string"){
-				node = dojo.byId(node);
+				node = dom.byId(node);
 			}
 
-			dojo.query("input, select, textarea, button", node).
-				map(function(n){ return dojo.attr(node, "name") || null; }).
+			query("input, select, textarea, button", node).
+				map(function(n){ return domAttr.get(node, "name") || null; }).
 				forEach(function(name){
 					if(name){
 						this.unregisterNode(name);
@@ -229,19 +237,19 @@ dojo.require("dojox.form.manager._Mixin");
 				return null;	// Object
 			}
 
-			if(dojo.isArray(elem)){
+			if(lang.isArray(elem)){
 				// input/radio array
 				if(isSetter){
-					dojo.forEach(elem, function(node){
+					array.forEach(elem, function(node){
 						node.checked = "";
 					});
-					dojo.forEach(elem, function(node){
+					array.forEach(elem, function(node){
 						node.checked = node.value === value ? "checked" : "";
 					});
 					return this;	// self
 				}
 				// getter
-				dojo.some(elem, function(node){
+				array.some(elem, function(node){
 					if(node.checked){
 						result = node;
 						return true;
@@ -256,24 +264,24 @@ dojo.require("dojox.form.manager._Mixin");
 					if(elem.multiple){
 						// multiple is allowed
 						if(isSetter){
-							if(dojo.isArray(value)){
+							if(lang.isArray(value)){
 								var dict = {};
-								dojo.forEach(value, function(v){
+								array.forEach(value, function(v){
 									dict[v] = 1;
 								});
-								dojo.query("> option", elem).forEach(function(opt){
+								query("> option", elem).forEach(function(opt){
 									opt.selected = opt.value in dict;
 								});
 								return this;	// self
 							}
 							// singular property
-							dojo.query("> option", elem).forEach(function(opt){
+							query("> option", elem).forEach(function(opt){
 								opt.selected = opt.value === value;
 							});
 							return this;	// self
 						}
 						// getter
-						var result = dojo.query("> option", elem).filter(function(opt){
+						var result = query("> option", elem).filter(function(opt){
 							return opt.selected;
 						}).map(function(opt){
 							return opt.value;
@@ -282,7 +290,7 @@ dojo.require("dojox.form.manager._Mixin");
 					}
 					// singular
 					if(isSetter){
-						dojo.query("> option", elem).forEach(function(opt){
+						query("> option", elem).forEach(function(opt){
 							opt.selected = opt.value === value;
 						});
 						return this;	// self
@@ -335,8 +343,8 @@ dojo.require("dojox.form.manager._Mixin");
 			var name, result = {};
 
 			if(state){
-				if(dojo.isArray(state)){
-					dojo.forEach(state, function(name){
+				if(lang.isArray(state)){
+					array.forEach(state, function(name){
 						if(name in this.formNodes){
 							result[name] = inspector.call(this, name, this.formNodes[name].node, defaultValue);
 						}
@@ -357,4 +365,4 @@ dojo.require("dojox.form.manager._Mixin");
 			return result;	// Object
 		}
 	});
-})();
+});
diff --git a/dojox/form/manager/_ValueMixin.js b/dojox/form/manager/_ValueMixin.js
index 6d20986..3ce0062 100644
--- a/dojox/form/manager/_ValueMixin.js
+++ b/dojox/form/manager/_ValueMixin.js
@@ -1,6 +1,9 @@
-dojo.provide("dojox.form.manager._ValueMixin");
-
-dojo.declare("dojox.form.manager._ValueMixin", null, {
+define([
+	"dojo/_base/lang",
+	"dojo/_base/kernel",
+	"dojo/_base/declare"
+], function(lang, dojo, declare){
+return declare("dojox.form.manager._ValueMixin", null, {
 	// summary:
 	//		Form manager's mixin for getting/setting form values in the unified manner.
 	// description:
@@ -40,12 +43,12 @@ dojo.declare("dojox.form.manager._ValueMixin", null, {
 		}, names);
 
 		if(this.inspectFormNodes){
-			dojo.mixin(result, this.inspectFormNodes(function(name){
+			lang.mixin(result, this.inspectFormNodes(function(name){
 				return this.formNodeValue(name);
 			}, names));
 		}
 
-		dojo.mixin(result, this.inspectAttachedPoints(function(name){
+		lang.mixin(result, this.inspectAttachedPoints(function(name){
 			return this.formPointValue(name);
 		}, names));
 
@@ -75,3 +78,4 @@ dojo.declare("dojox.form.manager._ValueMixin", null, {
 		return this;
 	}
 });
+});
diff --git a/dojox/form/nls/CheckedMultiSelect.js b/dojox/form/nls/CheckedMultiSelect.js
new file mode 100644
index 0000000..d395164
--- /dev/null
+++ b/dojox/form/nls/CheckedMultiSelect.js
@@ -0,0 +1,36 @@
+define({ root:
+//begin v1.x content
+({
+	invalidMessage: "At least one item must be selected.",
+	multiSelectLabelText: "{num} item(s) selected"
+})
+//end v1.x content
+,
+"zh": true,
+"zh-tw": true,
+"tr": true,
+"th": true,
+"sv": true,
+"sl": true,
+"sk": true,
+"ru": true,
+"ro": true,
+"pt": true,
+"pl": true,
+"nl": true,
+"nb": true,
+"ko": true,
+"kk": true,
+"ja": true,
+"it": true,
+"hu": true,
+"hr": true,
+"fr": true,
+"fi": true,
+"es": true,
+"el": true,
+"de": true,
+"da": true,
+"cs": true,
+"ca": true
+});
diff --git a/dojox/form/nls/PasswordValidator.js b/dojox/form/nls/PasswordValidator.js
index 276f75f..2832e0f 100644
--- a/dojox/form/nls/PasswordValidator.js
+++ b/dojox/form/nls/PasswordValidator.js
@@ -1,4 +1,40 @@
+define({ root:
+//begin v1.x content
 ({
         nomatchMessage: "Passwords do not match.",
-		badPasswordMessage: "Invalid Password."
+	badPasswordMessage: "Invalid Password."
 })
+//end v1.x content
+,
+"ar": true,
+"az": true,
+"ca": true,
+"cs": true,
+"da": true,
+"de": true,
+"el": true,
+"es": true,
+"fi": true,
+"fr": true,
+"he": true,
+"hu": true,
+"hr": true,
+"it": true,
+"ja": true,
+"kk": true,
+"ko": true,
+"nb": true,
+"nl": true,
+"pl": true,
+"pt-pt": true,
+"pt": true,
+"ro": true,
+"ru": true,
+"sk": true,
+"sl": true,
+"sv": true,
+"th": true,
+"tr": true,
+"zh": true,
+"zh-tw": true
+});
diff --git a/dojox/form/nls/Uploader.js b/dojox/form/nls/Uploader.js
new file mode 100644
index 0000000..8f1aab7
--- /dev/null
+++ b/dojox/form/nls/Uploader.js
@@ -0,0 +1,35 @@
+define({ root:
+//begin v1.x content
+({
+	label: "Select Files..."
+})
+//end v1.x content
+,
+"zh": true,
+"zh-tw": true,
+"tr": true,
+"th": true,
+"sv": true,
+"sl": true,
+"sk": true,
+"ru": true,
+"ro": true,
+"pt": true,
+"pl": true,
+"nl": true,
+"nb": true,
+"ko": true,
+"kk": true,
+"ja": true,
+"it": true,
+"hu": true,
+"hr": true,
+"fr": true,
+"fi": true,
+"es": true,
+"el": true,
+"de": true,
+"da": true,
+"cs": true,
+"ca": true
+});
diff --git a/dojox/form/nls/ar/PasswordValidator.js b/dojox/form/nls/ar/PasswordValidator.js
index 7ced464..092a83f 100644
--- a/dojox/form/nls/ar/PasswordValidator.js
+++ b/dojox/form/nls/ar/PasswordValidator.js
@@ -1,5 +1,8 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "كلمات السرية غير مطابقة.",
 		badPasswordMessage: "كلمة سرية غير صحيحة."
 })
-
+//end v1.x content
+);
diff --git a/dojox/form/nls/az/PasswordValidator.js b/dojox/form/nls/az/PasswordValidator.js
new file mode 100644
index 0000000..31a42d3
--- /dev/null
+++ b/dojox/form/nls/az/PasswordValidator.js
@@ -0,0 +1,8 @@
+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/ca/CheckedMultiSelect.js b/dojox/form/nls/ca/CheckedMultiSelect.js
new file mode 100644
index 0000000..2a11e1e
--- /dev/null
+++ b/dojox/form/nls/ca/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Cal seleccionar, com a mínim, un element.",
+	multiSelectLabelText: "{num} element(s) seleccionat(s)"
+})
+);
diff --git a/dojox/form/nls/ca/PasswordValidator.js b/dojox/form/nls/ca/PasswordValidator.js
index 4f52779..aa58ea8 100644
--- a/dojox/form/nls/ca/PasswordValidator.js
+++ b/dojox/form/nls/ca/PasswordValidator.js
@@ -1,5 +1,8 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "Les contrasenyes no coincideixen",
 		badPasswordMessage: "La contrasenya no és correcta"
 })
-
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/ca/Uploader.js b/dojox/form/nls/ca/Uploader.js
new file mode 100644
index 0000000..3a208d8
--- /dev/null
+++ b/dojox/form/nls/ca/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Selecciona fitxers..."
+})
+);
diff --git a/dojox/form/nls/cs/CheckedMultiSelect.js b/dojox/form/nls/cs/CheckedMultiSelect.js
new file mode 100644
index 0000000..a57cfe4
--- /dev/null
+++ b/dojox/form/nls/cs/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Je třeba vybrat alespoň jednu položku.",
+	multiSelectLabelText: "Počet vybraných položek: {num}"
+})
+);
diff --git a/dojox/form/nls/cs/PasswordValidator.js b/dojox/form/nls/cs/PasswordValidator.js
index ca07c3c..d07f32e 100644
--- a/dojox/form/nls/cs/PasswordValidator.js
+++ b/dojox/form/nls/cs/PasswordValidator.js
@@ -1,5 +1,8 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "Hesla se neshodují.",
 		badPasswordMessage: "Neplatné heslo."
 })
-
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/cs/Uploader.js b/dojox/form/nls/cs/Uploader.js
new file mode 100644
index 0000000..3ddb79c
--- /dev/null
+++ b/dojox/form/nls/cs/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Vybrat soubory..."
+})
+);
diff --git a/dojox/form/nls/da/CheckedMultiSelect.js b/dojox/form/nls/da/CheckedMultiSelect.js
new file mode 100644
index 0000000..8579662
--- /dev/null
+++ b/dojox/form/nls/da/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Du skal vælge mindst ét element.",
+	multiSelectLabelText: "{num} element(er) valgt"
+})
+);
diff --git a/dojox/form/nls/da/PasswordValidator.js b/dojox/form/nls/da/PasswordValidator.js
index d516b77..fbe94c7 100644
--- a/dojox/form/nls/da/PasswordValidator.js
+++ b/dojox/form/nls/da/PasswordValidator.js
@@ -1,5 +1,8 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "Adgangskoderne stemmer ikke overens.",
 		badPasswordMessage: "Ugyldig adgangskode."
 })
-
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/da/Uploader.js b/dojox/form/nls/da/Uploader.js
new file mode 100644
index 0000000..d44df19
--- /dev/null
+++ b/dojox/form/nls/da/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Vælg filer..."
+})
+);
diff --git a/dojox/form/nls/de/CheckedMultiSelect.js b/dojox/form/nls/de/CheckedMultiSelect.js
new file mode 100644
index 0000000..ce8e895
--- /dev/null
+++ b/dojox/form/nls/de/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Es muss mindestens ein Element ausgewählt werden.",
+	multiSelectLabelText: "{num} Element(e) ausgewählt"
+})
+);
diff --git a/dojox/form/nls/de/PasswordValidator.js b/dojox/form/nls/de/PasswordValidator.js
index 64c5472..eb2bf65 100644
--- a/dojox/form/nls/de/PasswordValidator.js
+++ b/dojox/form/nls/de/PasswordValidator.js
@@ -1,5 +1,8 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "Die Kennwörter stimmen nicht überein.",
 		badPasswordMessage: "Ungültiges Kennwort."
 })
-
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/de/Uploader.js b/dojox/form/nls/de/Uploader.js
new file mode 100644
index 0000000..4319bbd
--- /dev/null
+++ b/dojox/form/nls/de/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Dateien auswählen..."
+})
+);
diff --git a/dojox/form/nls/el/CheckedMultiSelect.js b/dojox/form/nls/el/CheckedMultiSelect.js
new file mode 100644
index 0000000..7dced3a
--- /dev/null
+++ b/dojox/form/nls/el/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Πρέπει να επιλέξετε τουλάχιστον ένα στοιχείο.",
+	multiSelectLabelText: "Επιλέχθηκε(-αν) {num} στοιχείο(-α)"
+})
+);
diff --git a/dojox/form/nls/el/PasswordValidator.js b/dojox/form/nls/el/PasswordValidator.js
index 5e256a1..e89a600 100644
--- a/dojox/form/nls/el/PasswordValidator.js
+++ b/dojox/form/nls/el/PasswordValidator.js
@@ -1,5 +1,8 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "Οι κωδικοί πρόσβασης δεν συμφωνούν.",
 		badPasswordMessage: "Μη έγκυρος κωδικός πρόσβασης."
 })
-
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/el/Uploader.js b/dojox/form/nls/el/Uploader.js
new file mode 100644
index 0000000..b2494e3
--- /dev/null
+++ b/dojox/form/nls/el/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Επιλογή αρχείων..."
+})
+);
diff --git a/dojox/form/nls/es/CheckedMultiSelect.js b/dojox/form/nls/es/CheckedMultiSelect.js
new file mode 100644
index 0000000..6ecbad1
--- /dev/null
+++ b/dojox/form/nls/es/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Se debe seleccionar al menos un elemento.",
+	multiSelectLabelText: "{num} elemento(s) seleccionado(s)"
+})
+);
diff --git a/dojox/form/nls/es/PasswordValidator.js b/dojox/form/nls/es/PasswordValidator.js
index d984e1a..1ca3989 100644
--- a/dojox/form/nls/es/PasswordValidator.js
+++ b/dojox/form/nls/es/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "Las contraseñas no coinciden.",
 		badPasswordMessage: "Contraseña no válida."
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/es/Uploader.js b/dojox/form/nls/es/Uploader.js
new file mode 100644
index 0000000..d21e647
--- /dev/null
+++ b/dojox/form/nls/es/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Seleccionar archivos..."
+})
+);
diff --git a/dojox/form/nls/fi/CheckedMultiSelect.js b/dojox/form/nls/fi/CheckedMultiSelect.js
new file mode 100644
index 0000000..2c98859
--- /dev/null
+++ b/dojox/form/nls/fi/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Ainakin yksi kohde on valittava.",
+	multiSelectLabelText: "{num} kohde(tta) valittu"
+})
+);
diff --git a/dojox/form/nls/fi/PasswordValidator.js b/dojox/form/nls/fi/PasswordValidator.js
index f46212d..28e3e1b 100644
--- a/dojox/form/nls/fi/PasswordValidator.js
+++ b/dojox/form/nls/fi/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "Salasanat eivät täsmää.",
 		badPasswordMessage: "Salasana ei kelpaa."
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/fi/Uploader.js b/dojox/form/nls/fi/Uploader.js
new file mode 100644
index 0000000..ae10ca3
--- /dev/null
+++ b/dojox/form/nls/fi/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Valitse tiedostot..."
+})
+);
diff --git a/dojox/form/nls/fr/CheckedMultiSelect.js b/dojox/form/nls/fr/CheckedMultiSelect.js
new file mode 100644
index 0000000..0d12fb8
--- /dev/null
+++ b/dojox/form/nls/fr/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Au moins un des éléments doit être sélectionné.",
+	multiSelectLabelText: "{num} élément(s) sélectionné(s)"
+})
+);
diff --git a/dojox/form/nls/fr/PasswordValidator.js b/dojox/form/nls/fr/PasswordValidator.js
index a573834..c454136 100644
--- a/dojox/form/nls/fr/PasswordValidator.js
+++ b/dojox/form/nls/fr/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "Les mots de passe ne correspondent pas.",
 		badPasswordMessage: "Mot de passe incorrect."
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/fr/Uploader.js b/dojox/form/nls/fr/Uploader.js
new file mode 100644
index 0000000..2660f79
--- /dev/null
+++ b/dojox/form/nls/fr/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Sélectionner les fichiers..."
+})
+);
diff --git a/dojox/form/nls/he/PasswordValidator.js b/dojox/form/nls/he/PasswordValidator.js
index 6e6eae6..7f142bd 100644
--- a/dojox/form/nls/he/PasswordValidator.js
+++ b/dojox/form/nls/he/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "הסיסמאות אינן זהות.",
 		badPasswordMessage: "סיסמה לא חוקית."
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/hr/CheckedMultiSelect.js b/dojox/form/nls/hr/CheckedMultiSelect.js
new file mode 100644
index 0000000..6cad133
--- /dev/null
+++ b/dojox/form/nls/hr/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Mora biti izabrana najmanje jedna stavka.",
+	multiSelectLabelText: "{num} stavki je izabrano"
+})
+);
diff --git a/dojox/form/nls/hr/PasswordValidator.js b/dojox/form/nls/hr/PasswordValidator.js
new file mode 100644
index 0000000..b6e7dd6
--- /dev/null
+++ b/dojox/form/nls/hr/PasswordValidator.js
@@ -0,0 +1,6 @@
+define(
+({
+        nomatchMessage: "Lozinke se ne podudaraju.",
+	badPasswordMessage: "Neispravna lozinka."
+})
+);
diff --git a/dojox/form/nls/hr/Uploader.js b/dojox/form/nls/hr/Uploader.js
new file mode 100644
index 0000000..c7f5a33
--- /dev/null
+++ b/dojox/form/nls/hr/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Izaberite datoteke..."
+})
+);
diff --git a/dojox/form/nls/hu/CheckedMultiSelect.js b/dojox/form/nls/hu/CheckedMultiSelect.js
new file mode 100644
index 0000000..ae24ee4
--- /dev/null
+++ b/dojox/form/nls/hu/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Legalább egy tételt ki kell választani.",
+	multiSelectLabelText: "{num} elem van kiválasztva"
+})
+);
diff --git a/dojox/form/nls/hu/PasswordValidator.js b/dojox/form/nls/hu/PasswordValidator.js
index 95d705c..3a14fe8 100644
--- a/dojox/form/nls/hu/PasswordValidator.js
+++ b/dojox/form/nls/hu/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "A jelszavak nem egyeznek.",
 		badPasswordMessage: "Érvénytelen jelszó."
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/hu/Uploader.js b/dojox/form/nls/hu/Uploader.js
new file mode 100644
index 0000000..ad218cb
--- /dev/null
+++ b/dojox/form/nls/hu/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Fájlok kiválasztása..."
+})
+);
diff --git a/dojox/form/nls/it/CheckedMultiSelect.js b/dojox/form/nls/it/CheckedMultiSelect.js
new file mode 100644
index 0000000..1d50e02
--- /dev/null
+++ b/dojox/form/nls/it/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "È necessario selezionare almeno un elemento.",
+	multiSelectLabelText: "{num} elementi selezionati"
+})
+);
diff --git a/dojox/form/nls/it/PasswordValidator.js b/dojox/form/nls/it/PasswordValidator.js
index 1486b3d..9f16917 100644
--- a/dojox/form/nls/it/PasswordValidator.js
+++ b/dojox/form/nls/it/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "Le password non corrispondono.",
 		badPasswordMessage: "Password non valida."
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/it/Uploader.js b/dojox/form/nls/it/Uploader.js
new file mode 100644
index 0000000..810e2ad
--- /dev/null
+++ b/dojox/form/nls/it/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Seleziona file..."
+})
+);
diff --git a/dojox/form/nls/ja/CheckedMultiSelect.js b/dojox/form/nls/ja/CheckedMultiSelect.js
new file mode 100644
index 0000000..9c0fe52
--- /dev/null
+++ b/dojox/form/nls/ja/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "少なくとも 1 つの項目を選択しなければなりません。",
+	multiSelectLabelText: "{num} 個の項目が選択されています"
+})
+);
diff --git a/dojox/form/nls/ja/PasswordValidator.js b/dojox/form/nls/ja/PasswordValidator.js
index 890931e..6656b20 100644
--- a/dojox/form/nls/ja/PasswordValidator.js
+++ b/dojox/form/nls/ja/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "パスワードが一致しません。",
 		badPasswordMessage: "無効なパスワードです。"
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/ja/Uploader.js b/dojox/form/nls/ja/Uploader.js
new file mode 100644
index 0000000..91799e4
--- /dev/null
+++ b/dojox/form/nls/ja/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "ファイルの選択..."
+})
+);
diff --git a/dojox/form/nls/kk/CheckedMultiSelect.js b/dojox/form/nls/kk/CheckedMultiSelect.js
new file mode 100644
index 0000000..5f15b89
--- /dev/null
+++ b/dojox/form/nls/kk/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Кемінде бір элемент таңдалуы керек.",
+	multiSelectLabelText: "{num} элемент(тер)і таңдалды"
+})
+);
diff --git a/dojox/form/nls/kk/Uploader.js b/dojox/form/nls/kk/Uploader.js
new file mode 100644
index 0000000..7954701
--- /dev/null
+++ b/dojox/form/nls/kk/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Файлдарды таңдау..."
+})
+);
diff --git a/dojox/form/nls/ko/CheckedMultiSelect.js b/dojox/form/nls/ko/CheckedMultiSelect.js
new file mode 100644
index 0000000..a94d8a6
--- /dev/null
+++ b/dojox/form/nls/ko/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "최소한 한 가지 항목을 선택해야 합니다.",
+	multiSelectLabelText: "{num} 항목이 선택되었습니다."
+})
+);
diff --git a/dojox/form/nls/ko/PasswordValidator.js b/dojox/form/nls/ko/PasswordValidator.js
index a5150c9..4c3b48f 100644
--- a/dojox/form/nls/ko/PasswordValidator.js
+++ b/dojox/form/nls/ko/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "비밀번호가 일치하지 않습니다.",
 		badPasswordMessage: "올바르지 않은 비밀번호"
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/ko/Uploader.js b/dojox/form/nls/ko/Uploader.js
new file mode 100644
index 0000000..08dd92d
--- /dev/null
+++ b/dojox/form/nls/ko/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "파일 선택..."
+})
+);
diff --git a/dojox/form/nls/nb/CheckedMultiSelect.js b/dojox/form/nls/nb/CheckedMultiSelect.js
new file mode 100644
index 0000000..27dd69d
--- /dev/null
+++ b/dojox/form/nls/nb/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Du må velge minst ett element.",
+	multiSelectLabelText: "{num} element(er) valgt"
+})
+);
diff --git a/dojox/form/nls/nb/PasswordValidator.js b/dojox/form/nls/nb/PasswordValidator.js
index 12d3ea6..74d430e 100644
--- a/dojox/form/nls/nb/PasswordValidator.js
+++ b/dojox/form/nls/nb/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "Passordene samsvarer ikke.",
 		badPasswordMessage: "Ugyldig passord."
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/nb/Uploader.js b/dojox/form/nls/nb/Uploader.js
new file mode 100644
index 0000000..bc3b9b7
--- /dev/null
+++ b/dojox/form/nls/nb/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Velg filer..."
+})
+);
diff --git a/dojox/form/nls/nl/CheckedMultiSelect.js b/dojox/form/nls/nl/CheckedMultiSelect.js
new file mode 100644
index 0000000..c2130bc
--- /dev/null
+++ b/dojox/form/nls/nl/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Er moet te minste één item worden geselecteerd.",
+	multiSelectLabelText: "{num} item(s) geselecteerd"
+})
+);
diff --git a/dojox/form/nls/nl/PasswordValidator.js b/dojox/form/nls/nl/PasswordValidator.js
index 5b46472..bce234d 100644
--- a/dojox/form/nls/nl/PasswordValidator.js
+++ b/dojox/form/nls/nl/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "Wachtwoorden komen niet overeen.",
 		badPasswordMessage: "Ongeldig wachtwoord."
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/nl/Uploader.js b/dojox/form/nls/nl/Uploader.js
new file mode 100644
index 0000000..c90e9af
--- /dev/null
+++ b/dojox/form/nls/nl/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Bestanden selecteren..."
+})
+);
diff --git a/dojox/form/nls/pl/CheckedMultiSelect.js b/dojox/form/nls/pl/CheckedMultiSelect.js
new file mode 100644
index 0000000..76cf9c8
--- /dev/null
+++ b/dojox/form/nls/pl/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Należy wybrać co najmniej jeden element.",
+	multiSelectLabelText: "Wybrano elementów: {num}"
+})
+);
diff --git a/dojox/form/nls/pl/PasswordValidator.js b/dojox/form/nls/pl/PasswordValidator.js
index 0a0b136..b392c66 100644
--- a/dojox/form/nls/pl/PasswordValidator.js
+++ b/dojox/form/nls/pl/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "Hasła nie są zgodne.",
 		badPasswordMessage: "Niepoprawne hasło."
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/pl/Uploader.js b/dojox/form/nls/pl/Uploader.js
new file mode 100644
index 0000000..0ff4320
--- /dev/null
+++ b/dojox/form/nls/pl/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Wybierz pliki..."
+})
+);
diff --git a/dojox/form/nls/pt-pt/PasswordValidator.js b/dojox/form/nls/pt-pt/PasswordValidator.js
index 4ca422c..a19eda6 100644
--- a/dojox/form/nls/pt-pt/PasswordValidator.js
+++ b/dojox/form/nls/pt-pt/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "As palavras-passe não correspondem.",
 		badPasswordMessage: "Palavra-passe não válida."
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/pt/CheckedMultiSelect.js b/dojox/form/nls/pt/CheckedMultiSelect.js
new file mode 100644
index 0000000..2f55328
--- /dev/null
+++ b/dojox/form/nls/pt/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Ao menos um item deve ser selecionado.",
+	multiSelectLabelText: "{num} item(ns) selecionado(s)"
+})
+);
diff --git a/dojox/form/nls/pt/PasswordValidator.js b/dojox/form/nls/pt/PasswordValidator.js
index 102add5..24c906f 100644
--- a/dojox/form/nls/pt/PasswordValidator.js
+++ b/dojox/form/nls/pt/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "As senhas não correspondem.",
 		badPasswordMessage: "Senha Inválida."
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/pt/Uploader.js b/dojox/form/nls/pt/Uploader.js
new file mode 100644
index 0000000..81636e4
--- /dev/null
+++ b/dojox/form/nls/pt/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Selecione Arquivos..."
+})
+);
diff --git a/dojox/form/nls/ro/CheckedMultiSelect.js b/dojox/form/nls/ro/CheckedMultiSelect.js
new file mode 100644
index 0000000..4f14e24
--- /dev/null
+++ b/dojox/form/nls/ro/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Trebuie să selectaţi cel puţin un articol.",
+	multiSelectLabelText: "{num} articole selectate"
+})
+);
diff --git a/dojox/form/nls/ro/PasswordValidator.js b/dojox/form/nls/ro/PasswordValidator.js
index 5ac1688..368974a 100644
--- a/dojox/form/nls/ro/PasswordValidator.js
+++ b/dojox/form/nls/ro/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "Parolele nu se potrivesc. ",
 		badPasswordMessage: "Parola nu este validă. "
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/ro/Uploader.js b/dojox/form/nls/ro/Uploader.js
new file mode 100644
index 0000000..4597c95
--- /dev/null
+++ b/dojox/form/nls/ro/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Selectare fişiere..."
+})
+);
diff --git a/dojox/form/nls/ru/CheckedMultiSelect.js b/dojox/form/nls/ru/CheckedMultiSelect.js
new file mode 100644
index 0000000..9f0cd97
--- /dev/null
+++ b/dojox/form/nls/ru/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Необходимо выбрать, как минимум, один элемент.",
+	multiSelectLabelText: "Выбрано элементов: {num}"
+})
+);
diff --git a/dojox/form/nls/ru/PasswordValidator.js b/dojox/form/nls/ru/PasswordValidator.js
index 01ce959..a6b98c2 100644
--- a/dojox/form/nls/ru/PasswordValidator.js
+++ b/dojox/form/nls/ru/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "Пароли не совпадают.",
 		badPasswordMessage: "Неправильный пароль."
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/ru/Uploader.js b/dojox/form/nls/ru/Uploader.js
new file mode 100644
index 0000000..c3a6a34
--- /dev/null
+++ b/dojox/form/nls/ru/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Выберите файлы..."
+})
+);
diff --git a/dojox/form/nls/sk/CheckedMultiSelect.js b/dojox/form/nls/sk/CheckedMultiSelect.js
new file mode 100644
index 0000000..d794e7b
--- /dev/null
+++ b/dojox/form/nls/sk/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Musíte vybrať aspoň jednu položku.",
+	multiSelectLabelText: "Vybraté položky: {num}"
+})
+);
diff --git a/dojox/form/nls/sk/PasswordValidator.js b/dojox/form/nls/sk/PasswordValidator.js
index c3de5ef..785294d 100644
--- a/dojox/form/nls/sk/PasswordValidator.js
+++ b/dojox/form/nls/sk/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "Heslá sa nezhodujú.",
 		badPasswordMessage: "Neplatné heslo."
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/sk/Uploader.js b/dojox/form/nls/sk/Uploader.js
new file mode 100644
index 0000000..ef95d52
--- /dev/null
+++ b/dojox/form/nls/sk/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Vybrať súbory..."
+})
+);
diff --git a/dojox/form/nls/sl/CheckedMultiSelect.js b/dojox/form/nls/sl/CheckedMultiSelect.js
new file mode 100644
index 0000000..c881343
--- /dev/null
+++ b/dojox/form/nls/sl/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Izbrati morate vsaj eno postavko.",
+	multiSelectLabelText: "Število izbranih postavk: {num}"
+})
+);
diff --git a/dojox/form/nls/sl/PasswordValidator.js b/dojox/form/nls/sl/PasswordValidator.js
index 5247524..679b4f4 100644
--- a/dojox/form/nls/sl/PasswordValidator.js
+++ b/dojox/form/nls/sl/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "Gesli se ne ujemata.",
 		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
new file mode 100644
index 0000000..0df9fd7
--- /dev/null
+++ b/dojox/form/nls/sl/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Izberite datoteke ..."
+})
+);
diff --git a/dojox/form/nls/sv/CheckedMultiSelect.js b/dojox/form/nls/sv/CheckedMultiSelect.js
new file mode 100644
index 0000000..7dafe78
--- /dev/null
+++ b/dojox/form/nls/sv/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Du måste välja minst ett objekt.",
+	multiSelectLabelText: "{num} objekt har valts"
+})
+);
diff --git a/dojox/form/nls/sv/PasswordValidator.js b/dojox/form/nls/sv/PasswordValidator.js
index 94e4e80..3983071 100644
--- a/dojox/form/nls/sv/PasswordValidator.js
+++ b/dojox/form/nls/sv/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "Lösenorden stämmer inte överens.",
 		badPasswordMessage: "Ogiltigt lösenord."
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/sv/Uploader.js b/dojox/form/nls/sv/Uploader.js
new file mode 100644
index 0000000..ff954ad
--- /dev/null
+++ b/dojox/form/nls/sv/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Välj filer..."
+})
+);
diff --git a/dojox/form/nls/th/CheckedMultiSelect.js b/dojox/form/nls/th/CheckedMultiSelect.js
new file mode 100644
index 0000000..cdc2746
--- /dev/null
+++ b/dojox/form/nls/th/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "อย่างน้อยหนึ่งรายการต้องถูกเลือก",
+	multiSelectLabelText: "{num} รายการถูกเลือก"
+})
+);
diff --git a/dojox/form/nls/th/PasswordValidator.js b/dojox/form/nls/th/PasswordValidator.js
index 6f7e2ad..771fca4 100644
--- a/dojox/form/nls/th/PasswordValidator.js
+++ b/dojox/form/nls/th/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "รหัสผ่านไม่ตรงกัน",
 		badPasswordMessage: "รหัสผ่านไม่ถูกต้อง"
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/th/Uploader.js b/dojox/form/nls/th/Uploader.js
new file mode 100644
index 0000000..4553f3e
--- /dev/null
+++ b/dojox/form/nls/th/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "เลือกไฟล์..."
+})
+);
diff --git a/dojox/form/nls/tr/CheckedMultiSelect.js b/dojox/form/nls/tr/CheckedMultiSelect.js
new file mode 100644
index 0000000..d336184
--- /dev/null
+++ b/dojox/form/nls/tr/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "En az bir öğe seçilmiş olmalı.",
+	multiSelectLabelText: "{num} öğe seçildi"
+})
+);
diff --git a/dojox/form/nls/tr/PasswordValidator.js b/dojox/form/nls/tr/PasswordValidator.js
index f024ca8..e0c73d5 100644
--- a/dojox/form/nls/tr/PasswordValidator.js
+++ b/dojox/form/nls/tr/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "Parolalar eşleşmiyor.",
 		badPasswordMessage: "Geçersiz Parola."
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/tr/Uploader.js b/dojox/form/nls/tr/Uploader.js
new file mode 100644
index 0000000..1ce96dd
--- /dev/null
+++ b/dojox/form/nls/tr/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Dosyaları Seç..."
+})
+);
diff --git a/dojox/form/nls/zh-tw/CheckedMultiSelect.js b/dojox/form/nls/zh-tw/CheckedMultiSelect.js
new file mode 100644
index 0000000..3611f7a
--- /dev/null
+++ b/dojox/form/nls/zh-tw/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "至少必須選取一個項目。",
+	multiSelectLabelText: "已選取 {num} 項目"
+})
+);
diff --git a/dojox/form/nls/zh-tw/PasswordValidator.js b/dojox/form/nls/zh-tw/PasswordValidator.js
index 173d589..42e1440 100644
--- a/dojox/form/nls/zh-tw/PasswordValidator.js
+++ b/dojox/form/nls/zh-tw/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "密碼不符合。",
 		badPasswordMessage: "無效的密碼。"
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/zh-tw/Uploader.js b/dojox/form/nls/zh-tw/Uploader.js
new file mode 100644
index 0000000..c640408
--- /dev/null
+++ b/dojox/form/nls/zh-tw/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "選取檔案..."
+})
+);
diff --git a/dojox/form/nls/zh/CheckedMultiSelect.js b/dojox/form/nls/zh/CheckedMultiSelect.js
new file mode 100644
index 0000000..34c2aba
--- /dev/null
+++ b/dojox/form/nls/zh/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "必须至少选择一项。",
+	multiSelectLabelText: "选择了 {num} 个项"
+})
+);
diff --git a/dojox/form/nls/zh/PasswordValidator.js b/dojox/form/nls/zh/PasswordValidator.js
index 42acd78..e15b442 100644
--- a/dojox/form/nls/zh/PasswordValidator.js
+++ b/dojox/form/nls/zh/PasswordValidator.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
         nomatchMessage: "密码不匹配。",
 		badPasswordMessage: "密码无效。"
 })
 
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojox/form/nls/zh/Uploader.js b/dojox/form/nls/zh/Uploader.js
new file mode 100644
index 0000000..0b5b527
--- /dev/null
+++ b/dojox/form/nls/zh/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "选择文件..."
+})
+);
diff --git a/dojox/form/resources/CheckedMultiSelect.css b/dojox/form/resources/CheckedMultiSelect.css
index 311f8f0..8037ee1 100644
--- a/dojox/form/resources/CheckedMultiSelect.css
+++ b/dojox/form/resources/CheckedMultiSelect.css
@@ -3,9 +3,12 @@
 **  CheckedMultiSelect
 **----------------------------------------------------------------------------
 */
-.dojoxMultiSelectSelect { display: none; }
 
-.dojoxMultiSelect {
+.dojoxCheckedMultiSelectHidden{
+	display: none;
+}
+
+.dojoxCheckedMultiSelect .dojoxCheckedMultiSelectWrapper {
 	border: solid black 1px;
 	margin: 1px 0;
 	overflow: scroll; 
@@ -14,44 +17,74 @@
 	height: 100px;
 }
 
-.dj_ie .dojoxMultiSelect,
-.dj_webkit .dojoxMultiSelect {
+.dj_ie .dojoxCheckedMultiSelectWrapper,
+.dj_webkit .dojoxCheckedMultiSelectWrapper {
 	/* So that the scroll bar doesn't cover stuff up */
 	padding-right: 15px;
 }
 
 .dojoxMultiSelectItem {
+	cursor: default;
+	padding: 0.1em 0.2em;
+	white-space: nowrap;
+}
+
+.dojoxCheckedMultiSelectItem {
 	white-space: nowrap;
 	padding:.1em .2em;
 	cursor:default;
 }
 
-.dojoxMultiSelectDisabled *,
-.dojoxMultiSelectReadOnly * {
+.dojoxCheckedMultiSelectDisabled *,
+.dojoxCheckedMultiSelectReadOnly * {
 	color:gray !important;
 }
 
-.dojoxMultiSelectItemLabel {
+.dojoxCheckedMultiSelectItemLabel {
 	margin-left: .2em;
 }
 
+.dojoxCheckedMultiSelect .dojoxCheckedMultiSelectWrapper {
+	margin: 0em 0.1em;
+}
+
+.dojoxCheckedMultiSelectCheckBoxInput {
+	opacity: 0.01;
+}
+
+.dj_ie .dojoxCheckedMultiSelectCheckBoxInput {
+	filter: alpha(opacity=0);
+	width: 15px;
+	height: 16px;
+}
+
+.dijit_a11y .dojoxCheckedMultiSelectCheckBoxInput {
+	opacity: 1;
+	filter: none;
+}
+
+.dojoxCheckedMultiSelectMenu td.dijitMenuArrowCell {
+	display: none;
+}
+
+.dojoxCheckedMultiSelectMenu td.dijitMenuItemLabel {
+	position: static;
+	padding: 2px;
+}
+
 /*
 **----------------------------------------------------------------------------
 **  Tundra theme (make look similar to text box)
 **----------------------------------------------------------------------------
 */
-.tundra .dojoxMultiSelect {
-	margin: 0em 0.1em;
-}
-
-.tundra .dojoxMultiSelect {
+.tundra .dojoxCheckedMultiSelect .dojoxCheckedMultiSelectWrapper {
 	background:#fff url("../../../dijit/themes/tundra/images/validationInputBg.png") repeat-x top left;
 	#background:#fff url('../../../dijit/themes/tundra/images/validationInputBg.gif') repeat-x top left;
 	border:1px solid #b3b3b3;
 	line-height: normal;
 }
 
-.tundra .dojoxMultiSelectFocused {
+.tundra .dojoxCheckedMultiSelectFocused .dojoxCheckedMultiSelectWrapper {
 	/* input field when focused (ie: typing affects it) */
 	border-color:#406b9b;
 }
@@ -61,18 +94,14 @@
 **  Soria theme (make look similar to text box)
 **----------------------------------------------------------------------------
 */
-.soria .dojoxMultiSelect {
-	margin: 0em 0.1em;
-}
-
-.soria .dojoxMultiSelect {
+.soria .dojoxCheckedMultiSelect .dojoxCheckedMultiSelectWrapper {
 	background:#fff url("../../../dijit/themes/soria/images/validationInputBg.png") repeat-x top left;
 	#background:#fff url('../../../dijit/themes/soria/images/validationInputBg.gif') repeat-x top left;
 	border:1px solid #8ba0bd;
 	line-height: normal;
 }
 
-.soria .dojoxMultiSelectFocused {
+.soria .dojoxCheckedMultiSelectFocused .dojoxCheckedMultiSelectWrapper {
 	/* input field when focused (ie: typing affects it) */
 	border-color:#406b9b;
 }
@@ -82,18 +111,14 @@
 **  Nihilo theme (make look similar to text box)
 **----------------------------------------------------------------------------
 */
-.nihilo .dojoxMultiSelect {
-	margin: 0em 0.1em;
-}
-
-.nihilo .dojoxMultiSelect {
+.nihilo .dojoxCheckedMultiSelect .dojoxCheckedMultiSelectWrapper {
 	background:#fff url("../../../dijit/themes/nihilo/images/validationInputBg.png") repeat-x top left;
 	#background:#fff url('../../../dijit/themes/nihilo/images/validationInputBg.gif') repeat-x top left;
 	border:1px solid #d3d3d3;
 	line-height: normal;
 }
 
-.nihilo .dojoxMultiSelectFocused {
+.nihilo .dojoxCheckedMultiSelectFocused .dojoxCheckedMultiSelectWrapper {
 	/* input field when focused (ie: typing affects it) */
 	border-color:#b3b3b3;
 }
@@ -103,20 +128,15 @@
 **  Claro theme (make look similar to text box)
 **----------------------------------------------------------------------------
 */
-
-.claro .dojoxMultiSelect {
-	margin: 0em 0.1em;
-}
-
-.claro .dojoxMultiSelect {
+.claro .dojoxCheckedMultiSelect .dojoxCheckedMultiSelectWrapper {
 	border: 1px solid #b5bcc7;
 	background-color: #f7fcff;
 	line-height: normal;
 	-webkit-transition-property:background-color, border;
- 	-webkit-transition-duration:.35s;
+	-webkit-transition-duration:.35s;
 }
 
-.claro .dojoxMultiSelectHover {
+.claro .dojoxCheckedMultiSelectHover .dojoxCheckedMultiSelectWrapper {
 	border-color: #769dc0;
 	background-color: #e9f4fe;
 	background-image: url('../../../dijit/themes/claro/form/images/textBox_back.png');
@@ -124,7 +144,135 @@
 	-webkit-transition-duration:.25s;
 }
 
-.claro .dojoxMultiSelectFocused {
+.claro .dojoxCheckedMultiSelectFocused .dojoxCheckedMultiSelectWrapper {
 	border: 1px solid #769dc0;
 	-webkit-transition-duration:.1s;
 }
+
+.claro .dojoxCheckedMultiSelectMenuCheckBoxItemIcon {
+	background-image: url('../../../dijit/themes/claro/form/images/checkboxRadioButtonStates.png');
+	background-repeat: no-repeat;
+	background-position: -15px;
+	width: 15px;
+	height: 16px;
+}
+
+.claro .dojoxCheckedMultiSelectMenuRadioItemIcon {
+	background-image: url('../../../dijit/themes/claro/form/images/checkboxRadioButtonStates.png');
+	background-repeat: no-repeat;
+	background-position: -105px;
+	width: 15px;
+	height: 16px;
+}
+
+.dj_ie6 .claro .dojoxCheckedMultiSelectMenuItemIcon {
+	background-image: url('../../../dijit/themes/claro/form/images/checkboxRadioButtonStates.png');
+}
+
+.claro .dojoxCheckedMultiSelectMenuItemChecked .dojoxCheckedMultiSelectMenuCheckBoxItemIcon {
+	background-position: 0;
+}
+
+.claro .dojoxCheckedMultiSelectMenuItemChecked .dojoxCheckedMultiSelectMenuRadioItemIcon {
+	background-position: -90px;
+}
+
+/* Drop down button */
+.claro .dojoxCheckedMultiSelect .dojoxCheckedMultiSelectButton .dijitButtonText {
+	padding: 2px;
+}
+
+/* normal status */
+.claro .dojoxCheckedMultiSelectButton {
+	border: 1px solid #b5bcc7;
+	background-color: #ffffff;
+	border-collapse: separate;
+}
+
+.claro .dojoxCheckedMultiSelect .dijitButtonNode {
+	border: 0 solid #b5bcc7;
+	border-width: 0 0 0 0;
+}
+
+.dj_ie6 .claro .dojoxCheckedMultiSelectButton, .dj_ie6 .claro .dojoxCheckedMultiSelect .dojoxCheckedMultiSelectButton .dijitButtonNode {
+	background-image: none;
+}
+
+.claro .dojoxCheckedMultiSelectButton .dijitButtonContents {
+	border: 0 solid #b5bcc7;
+	border-right-width: 1px;
+}
+
+.claro .dojoxCheckedMultiSelectButton .dijitArrowButton {
+	padding: 0;
+	border: 1px solid #ffffff;
+	border-top: none;
+	background-color: #efefef;
+	background-image: url("../../../dijit/themes/claro/form/images/formHighlight.png");
+	background-repeat: repeat-x;
+}
+
+.claro .dojoxCheckedMultiSelectButton .dijitArrowButton .dijitArrowButtonInner {
+	background-image: url("../../../dijit/themes/claro/form/images/commonFormArrows.png");
+	background-position: -35px;
+	background-repeat: no-repeat;
+	width: 16px;
+	height: 16px;
+}
+
+/* hover status */
+.claro .dojoxCheckedMultiSelectButtonHover {
+	border: 1px solid #769dc0;
+	background-color: #e9f4fe;
+	background-image: url('../../../dijit/themes/claro/form/images/textBox_back.png');
+	background-repeat: repeat-x;
+}
+
+.claro .dojoxCheckedMultiSelectButtonHover .dijitButtonContents {
+	border-color: #769dc0;
+}
+
+.claro .dojoxCheckedMultiSelectButtonHover .dijitArrowButton {
+	background-color: #abd6ff;
+}
+
+.claro .dojoxCheckedMultiSelectButtonHover .dijitArrowButton .dijitArrowButtonInner {
+	background-position: -70px ;
+}
+
+/* focused status */
+.claro .dojoxCheckedMultiSelectButtonFocused {
+	border: 1px solid #769dc0;
+}
+
+.claro .dojoxCheckedMultiSelectButtonFocused .dijitButtonContents {
+	border-color: #769dc0;
+}
+
+.claro .dojoxCheckedMultiSelectButtonFocused .dijitArrowButton {
+	background-color: #7dbefa;
+	background-position: 0 -177px;
+	border: none;
+	padding: 0 1px;
+}
+
+.claro .dojoxCheckedMultiSelectButtonFocused .dijitArrowButton .dijitArrowButtonInner {
+	background-position: -70px;
+	margin-bottom: 1px;
+}
+
+/* disable status */
+.claro .dojoxCheckedMultiSelectButtonDisabled {
+	border: 1px solid #d3d3d3;
+	background-color: #efefef;
+	background-image: none;
+	color: #818181;
+}
+
+.claro .dojoxCheckedMultiSelectButtonDisabled .dijitArrowButton {
+	background-color: #efefef;
+}
+
+.claro .dojoxCheckedMultiSelectButtonDisabled .dijitArrowButton .dijitArrowButtonInner {
+	background-position: 0;
+}
\ No newline at end of file
diff --git a/dojox/form/resources/CheckedMultiSelect.html b/dojox/form/resources/CheckedMultiSelect.html
index c7b66dc..5e31a21 100644
--- a/dojox/form/resources/CheckedMultiSelect.html
+++ b/dojox/form/resources/CheckedMultiSelect.html
@@ -1,4 +1,8 @@
-<div class="dijit dijitReset dijitInline" dojoAttachEvent="onmousedown:_onMouseDown,onclick:focus"
-	><select class="${baseClass}Select" multiple="true" dojoAttachPoint="containerNode,focusNode"></select
-	><div dojoAttachPoint="wrapperDiv"></div
+<div class="dijit dijitReset dijitInline dijitLeft" id="widget_${id}"
+	><div data-dojo-attach-point="comboButtonNode"
+	></div
+	><div data-dojo-attach-point="selectNode" class="dijit dijitReset dijitInline ${baseClass}Wrapper" data-dojo-attach-event="onmousedown:_onMouseDown,onclick:focus"
+		><select class="${baseClass}Select dojoxCheckedMultiSelectHidden" multiple="true" data-dojo-attach-point="containerNode,focusNode"></select
+		><div data-dojo-attach-point="wrapperDiv"></div
+	></div
 ></div>
\ No newline at end of file
diff --git a/dojox/form/resources/FilePickerTextBox.css b/dojox/form/resources/FilePickerTextBox.css
index 17ff8aa..a2d13d5 100644
--- a/dojox/form/resources/FilePickerTextBox.css
+++ b/dojox/form/resources/FilePickerTextBox.css
@@ -199,8 +199,8 @@
 	margin: 0em 0.1em;
 }
 .soria .dojoxFilePickerTextBox {
-	background:#fff url("../images/validationInputBg.png") repeat-x top left;
-	#background:#fff url('../images/validationInputBg.gif') repeat-x top left;
+	background:#fff url("../../../dijit/themes/soria/images/validationInputBg.png") repeat-x top left;
+	#background:#fff url('../../../dijit/themes/soria/images/validationInputBg.gif') repeat-x top left;
 	border:1px solid #8ba0bd;
 	line-height: normal;
 }
@@ -238,11 +238,11 @@
 }
 .soria .dojoxFilePickerTextBoxHover .dijitDownArrowButton{
 	color:#000;
-	background:#acc5e2 url("../../../dijit/themes/soria/buttonHover.png") repeat-x top left;
+	background:#acc5e2 url("../../../dijit/themes/soria/images/buttonHover.png") repeat-x top left;
 }
 .soria .dojoxFilePickerTextBoxActive .dijitDownArrowButton {
 	border-color:#657c9c;
-	background: #91b4e5 url("../../../dijit/themes/soria/buttonActive.png") top left repeat-x;
+	background: #91b4e5 url("../../../dijit/themes/soria/images/buttonActive.png") top left repeat-x;
 }
 .dijitRtl .soria .dojoxFilePickerTextBox .dijitButtonNode {
 	border-width: 0px 0px 0px 1px;
diff --git a/dojox/form/resources/TriStateCheckBox.css b/dojox/form/resources/TriStateCheckBox.css
new file mode 100644
index 0000000..237f4bf
--- /dev/null
+++ b/dojox/form/resources/TriStateCheckBox.css
@@ -0,0 +1,137 @@
+/* TriStateCheckBox
+ * 
+ * Styling TriStateCheckBox mainly includes:
+ * 
+ * 1. Containers
+ * 		.dojoxTriStateCheckBox|.dojoxTriStateCheckBoxIcon - for border, padding, width|height and background image
+ * 
+ * 2. Checked state
+ * 		.dojoxTriStateCheckBoxChecked - for checked background-color|image
+ * 		.dojoxTriStateCheckBoxMixed - for mixed background-color|image
+ * 
+ * 3. Hover state
+ * 		.dojoxTriStateCheckBoxHover|.dojoxTriStateCheckBoxCheckedHover|.dojoxTriStateCheckBoxMixedHover - for background image
+ * 
+ * 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 */
+
+  background-repeat: no-repeat;
+  width: 15px;
+  height: 16px;
+  margin: 0 2px 0 0;
+  padding: 0;
+}
+.dj_ie6 .claro .dojoxTriStateCheckBox, .dj_ie6 .claro .dojoxTriStateCheckBoxIcon {
+  background-image: url('images/tristatecheckboxStates.png');
+  /* checkbox sprite image */
+
+}
+.claro .dojoxTriStateCheckBox{
+  /* unchecked */
+
+  background-position: -15px;
+}
+.claro .dojoxTriStateCheckBoxChecked{
+  /* checked */
+
+  background-position: 0px;
+}
+.claro .dojoxTriStateCheckBoxMixed {
+  /* mixed */
+
+  background-position: -30px;
+}
+.claro .dojoxTriStateCheckBoxDisabled {
+  /* disabled and unchecked */
+
+  background-position: -105px;
+}
+.claro .dojoxTriStateCheckBoxCheckedDisabled {
+  /* disabled and checked */
+
+  background-position: -90px;
+}
+.claro .dojoxTriStateCheckBoxMixedDisabled {
+  /* disabled and mixed */
+
+  background-position: -120px;
+}
+.claro .dojoxTriStateCheckBoxHover {
+  /* hovering over and unchecked */
+
+  background-position: -60px;
+}
+.claro .dojoxTriStateCheckBoxCheckedHover {
+  /* hovering over and checked */
+
+  background-position: -45px;
+}
+.claro .dojoxTriStateCheckBoxMixedHover {
+  /* hovering over and mixed */
+
+  background-position: -75px;
+}
+
+.dijit_a11y .dojoxTriStateCheckBoxHover .dojoxTriStateCheckBoxInner,
+.dijit_a11y .dojoxTriStateCheckBoxFocused .dojoxTriStateCheckBoxInner{
+	/* focused or hovering over */
+	border: dashed;
+}
+
+.dijit_a11y .dojoxTriStateCheckBoxHover .dojoxTriStateCheckBoxInner,
+.dijit_a11y .dojoxTriStateCheckBoxFocused .dojoxTriStateCheckBoxInner{
+	/* focused or hovering over */
+	border: solid;
+}
+
+.dijit_a11y .dojoxTriStateCheckBoxDisabled .dojoxTriStateCheckBoxInner{
+	/* focused or hovering over */
+	opacity: 0.5;
+}
+
+.dj_ie .dijit_a11y .dojoxTriStateCheckBoxDisabled .dojoxTriStateCheckBoxInner{
+	/* disabled */
+}
+
+
+.dojoxTriStateCheckBoxInner{
+  /* inner text */
+
+  visibility: hidden;
+  display: none;
+	position: absolute;
+	text-align: center;
+}
+
+.dijit_a11y .dojoxTriStateCheckBoxInner{
+  /* inner text */
+  
+  visibility: visible;
+	display: block;
+}
+
+.dojoxTriStateCheckBoxInput {
+	/* place the actual input on top, but all-but-invisible */
+	opacity: 0.01;
+	padding: 0;
+	margin: 0,
+	border: 0;
+	width: 15px;
+	height: 16px;
+	background-position:center center;
+	background-repeat:no-repeat;
+}
+
+.dj_ie .dojoxTriStateCheckBoxInput {
+	filter: alpha(opacity=0);
+}
diff --git a/dojox/form/resources/TriStateCheckBox.html b/dojox/form/resources/TriStateCheckBox.html
new file mode 100644
index 0000000..5605128
--- /dev/null
+++ b/dojox/form/resources/TriStateCheckBox.html
@@ -0,0 +1,5 @@
+<div class="dijit dijitReset dijitInline" role="presentation"
+	><div class="dojoxTriStateCheckBoxInner" dojoAttachPoint="stateLabelNode"></div
+	><input ${!nameAttrSetting} type="${type}" dojoAttachPoint="focusNode"
+	class="dijitReset dojoxTriStateCheckBoxInput" dojoAttachEvent="onclick:_onClick"
+/></div>
\ No newline at end of file
diff --git a/dojox/form/resources/Uploader.html b/dojox/form/resources/Uploader.html
new file mode 100644
index 0000000..449b2a1
--- /dev/null
+++ b/dojox/form/resources/Uploader.html
@@ -0,0 +1,18 @@
+<span class="dijit dijitReset dijitInline"
+	><span class="dijitReset dijitInline dijitButtonNode"
+		dojoAttachEvent="ondijitclick:_onClick"
+		><span class="dijitReset dijitStretch dijitButtonContents"
+			dojoAttachPoint="titleNode,focusNode"
+			role="button" aria-labelledby="${id}_label"
+			><span class="dijitReset dijitInline dijitIcon" dojoAttachPoint="iconNode"></span
+			><span class="dijitReset dijitToggleButtonIconChar">&#x25CF;</span
+			><span class="dijitReset dijitInline dijitButtonText"
+				id="${id}_label"
+				dojoAttachPoint="containerNode"
+			></span
+		></span
+	></span
+	><!--no need to have this for Uploader 
+	<input ${!nameAttrSetting} type="${type}" value="${value}" class="dijitOffScreen" tabIndex="-1"
+		dojoAttachPoint="valueNode"
+/--></span>
diff --git a/dojox/form/resources/_CheckedMultiSelectItem.html b/dojox/form/resources/_CheckedMultiSelectItem.html
index 3ee1f10..709b450 100644
--- a/dojox/form/resources/_CheckedMultiSelectItem.html
+++ b/dojox/form/resources/_CheckedMultiSelectItem.html
@@ -1,5 +1,5 @@
 <div class="dijitReset ${baseClass}"
-	><input class="${baseClass}Box" dojoType="dijit.form.CheckBox" dojoAttachPoint="checkBox" 
-		dojoAttachEvent="_onClick:_changeBox" type="${_type.type}" baseClass="${_type.baseClass}"
-	/><div class="dijitInline ${baseClass}Label" dojoAttachPoint="labelNode" dojoAttachEvent="onclick:_onClick"></div
+	><input class="${baseClass}Box" data-dojo-type="dijit.form.CheckBox" data-dojo-attach-point="checkBox" 
+		data-dojo-attach-event="_onClick:_changeBox" type="${_type.type}" baseClass="${_type.baseClass}"
+	/><div class="dijitInline ${baseClass}Label" data-dojo-attach-point="labelNode" data-dojo-attach-event="onclick:_onClick"></div
 ></div>
diff --git a/dojox/form/resources/_CheckedMultiSelectMenuItem.html b/dojox/form/resources/_CheckedMultiSelectMenuItem.html
new file mode 100644
index 0000000..23a5064
--- /dev/null
+++ b/dojox/form/resources/_CheckedMultiSelectMenuItem.html
@@ -0,0 +1,10 @@
+<tr class="dijitReset dijitMenuItem" dojoAttachPoint="focusNode" role="menuitemcheckbox" tabIndex="-1"
+	dojoAttachEvent="onmouseenter:_onHover,onmouseleave:_onUnhover,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}"
+		/></div></td
+	><td class="dijitReset dijitMenuItemLabel" colspan="2" dojoAttachPoint="containerNode,labelNode"></td
+	><td class="dijitReset dijitMenuItemAccelKey" style="display: none" dojoAttachPoint="accelKeyNode"></td
+	><td class="dijitReset dijitMenuArrowCell" role="presentation"> </td
+></tr>
\ No newline at end of file
diff --git a/dojox/form/resources/images/tristatecheckboxStates.png b/dojox/form/resources/images/tristatecheckboxStates.png
new file mode 100644
index 0000000..dde030f
Binary files /dev/null and b/dojox/form/resources/images/tristatecheckboxStates.png differ
diff --git a/dojox/form/tests/test_BusyButton.html b/dojox/form/tests/test_BusyButton.html
index 12df2d1..3b7757f 100644
--- a/dojox/form/tests/test_BusyButton.html
+++ b/dojox/form/tests/test_BusyButton.html
@@ -19,8 +19,9 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
 			djConfig="parseOnLoad: true, isDebug: true"></script>
-		<script type="text/javascript" src="../BusyButton.js"></script>
 		<script type="text/javascript">
+			dojo.require("dojox.form.BusyButton");
+			dojo.require("dojo.parser");
 			dojo.require("dijit.Menu");
 			dojo.addOnLoad(function(){
 				dojo.connect(dijit.byId("buttonCancel"), "onClick", function(){
@@ -46,7 +47,12 @@
 		<h1 class="testTitle">Test: dojox.form.BusyButton</h1>
 		<p>
 		Normal busy button, 5000 miliseconds timeout<br />
-		<button dojoType="dojox.form.BusyButton" timeout="5000" >Click</button>
+		<button dojoType="dojox.form.BusyButton" timeout="5000" >
+			<script type="dojo/connect" data-dojo-event="onClick" data-dojo-args="evt">
+				console.log("dojox.form.BusyButton clicked");
+			</script>
+			Click
+		</button>
 		</p>
 	
 		<p>
@@ -101,4 +107,4 @@
 			</button>
 		</p>
 	</body>
-</hmtl>
\ No newline at end of file
+</html>
diff --git a/dojox/form/tests/test_CheckedMultiSelect.html b/dojox/form/tests/test_CheckedMultiSelect.html
index f6a3ae7..b479532 100644
--- a/dojox/form/tests/test_CheckedMultiSelect.html
+++ b/dojox/form/tests/test_CheckedMultiSelect.html
@@ -19,7 +19,7 @@
 
 	    <script type="text/javascript">
 			dojo.require("doh.runner");
-	        dojo.require("dojo.parser");
+			dojo.require("dojo.parser");
 			dojo.require("dojox.form.CheckedMultiSelect");
 			dojo.require("dijit.form.Button");
 			dojo.require("dijit.form.Form");
diff --git a/dojox/form/tests/test_CheckedMultiSelectDropDown.html b/dojox/form/tests/test_CheckedMultiSelectDropDown.html
new file mode 100644
index 0000000..5cef268
--- /dev/null
+++ b/dojox/form/tests/test_CheckedMultiSelectDropDown.html
@@ -0,0 +1,200 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>dojox.form.CheckedMultiSelect</title>
+		<link rel="stylesheet" id="themeStyles" href="../../../dijit/themes/claro/claro.css">
+		<link rel="stylesheet" href="../resources/CheckedMultiSelect.css">
+		<style>
+			@import url(../../../dojo/resources/dojo.css);
+			@import url(../../../dijit/tests/css/dijitTests.css);
+			
+			.ark {
+			    text-decoration: underline;
+			}
+		</style>
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true">
+		</script>
+		<script src="../../../dijit/tests/_testCommon.js">
+		</script>
+		<script type="text/javascript">
+			
+			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",
+					selected: true
+				}, {
+					value: "AK",
+					label: "Alaska",
+					selected: true
+				}, {
+					value: "AZ",
+					label: "Arizona"
+				}, {
+					value: "AR",
+					label: "Arkansas"
+				}, {
+					value: "CA",
+					label: "California"
+				}, {
+					value: "CO",
+					label: "Colorado"
+				}, {
+					value: "CT",
+					label: "Connecticut",
+					selected: true
+				}]
+			};
+			
+			var readStore = new dojo.data.ItemFileReadStore({
+				data: dojo.clone(data)
+			});
+			var writeStore = new dojo.data.ItemFileWriteStore({
+				data: dojo.clone(data)
+			});
+			
+			var checkOptions = 0;
+			var radioOptions = 0;
+			var addNum = 10;
+			var testType;
+		</script>
+	</head>
+	<body class="claro">
+		<h1 class="testTitle">Test: dojox.form.CheckedMultiSelect</h1>
+		<h2>Non-dojo select (for comparison)</h2>
+		<select>
+			<option value ="volvo">Volvo</option>
+			<option value ="saab">Saab</option>
+			<option value="opel">Opel</option>
+			<option value="audi">Audi</option>
+		</select>
+		<form dojoType="dijit.form.Form" jsId="form">
+			<hr><h2>Multi-select</h2>
+			<table>
+				<tr>
+				<td>
+					<select jsId="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>
+						<option value="FL">Florida</option>
+						<option value="CA">California</option>
+					</select>
+				</td>
+				<td>
+					<button dojoType="dijit.form.Button">
+						<script type="dojo/method" event="onClick">
+							ms1.invertSelection(true);
+							return false;
+						</script>
+						Invert Selection
+					</button>
+					<button dojoType="dijit.form.Button">
+						<script type="dojo/method" event="onClick">
+							ms1.set("disabled", !ms1.disabled);
+							return false;
+						</script>
+						Toggle Disabled
+					</button>
+					<button dojoType="dijit.form.Button">
+						<script type="dojo/method" event="onClick">
+							console.log(ms1.get("displayedValue"));
+							return false;
+						</script>
+						Get Displayed Value
+					</button>
+				</td>
+				<tr>
+					<td>
+						<select jsId="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>
+							<option value="ID">Idaho</option>
+							<option value="WY">Wyoming</option>
+							<option value="OR">Oregon</option>
+							<option value="PA">Pennsylvania</option>
+						</select>
+					</td>
+					<td>
+						<button dojoType="dijit.form.Button">
+							<script type="dojo/method" event="onClick">
+								ms2.set("readOnly", !ms2.readOnly);
+								return false;
+							</script>
+							Toggle Read Only
+						</button>
+					</td>
+				</tr>
+				<tr>
+					<td>
+						<select jsId="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">
+								checkOptions++;
+								ms3.addOption({value: checkOptions + "", label: "Option " + (checkOptions)});
+								return false;
+							</script>
+							Add Check Option
+						</button>
+						<button dojoType="dijit.form.Button">
+							<script type="dojo/method" event="onClick">
+								if(checkOptions > 0){
+									checkOptions--;
+									ms3.removeOption(checkOptions);
+								}
+								return false;
+							</script>
+							Remove Check Option
+						</button>
+					</td>
+				</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>
+					</td>
+					<td>
+						Read-Store-based
+					</td>
+				</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>
+			<button dojoType="dijit.form.Button">
+				Validate
+				<script type='dojo/method' event='onClick'>
+					var isvalid = rq1.isValid();
+					console.warn("isvalid?", isvalid, form, form.validate);
+					try{
+					rq1.validate();
+					form.validate();
+					}catch(e){
+					console.log(e);
+					}
+					console.warn("validated");
+				</script>
+			</button>
+			<hr><h2>Output values in console</h2>
+			<button dojoType="dijit.form.Button">
+				<script type="dojo/method" event="onClick">
+					console.dir(form.get("value"));
+					return false;
+				</script>
+				Get Values
+			</button>
+		</form>
+	</body>
+</html>
diff --git a/dojox/form/tests/test_CheckedMultiSelectNonDropDown.html b/dojox/form/tests/test_CheckedMultiSelectNonDropDown.html
new file mode 100644
index 0000000..646f900
--- /dev/null
+++ b/dojox/form/tests/test_CheckedMultiSelectNonDropDown.html
@@ -0,0 +1,205 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>dojox.form.CheckedMultiSelect</title>
+		<link rel="stylesheet" id="themeStyles" href="../../../dijit/themes/claro/claro.css">
+		<link rel="stylesheet" href="../resources/CheckedMultiSelect.css">
+		<style>
+			@import url(../../../dojo/resources/dojo.css);
+			@import url(../../../dijit/tests/css/dijitTests.css);
+			
+			.ark {
+				text-decoration: underline;
+			}
+			td {
+				vertical-align: top;
+			}
+		</style>
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true">
+		</script>
+		<script src="../../../dijit/tests/_testCommon.js">
+		</script>
+		<script type="text/javascript">
+			
+			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",
+					selected: true
+				}, {
+					value: "AK",
+					label: "Alaska"
+				}, {
+					value: "AZ",
+					label: "Arizona",
+					selected: true
+				}, {
+					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)
+			});
+			
+			var checkOptions = 0;
+			var radioOptions = 0;
+			var addNum = 10;
+			var testType;
+			// Uncomment below line to run perf tests - note SLOW to run
+			//testType = "perf";
+			
+		</script>
+	</head>
+	<body class="claro">
+		<h1 class="testTitle">Test: dojox.form.CheckedMultiSelect</h1>
+		<h2>Non-dojo select (for comparison)</h2>
+		<select>
+			<option value ="volvo">Volvo</option>
+			<option value ="saab">Saab</option>
+			<option value="opel">Opel</option>
+			<option value="audi">Audi</option>
+		</select>
+		<form dojoType="dijit.form.Form" jsId="form">
+			<hr><h2>Multi-select</h2>
+			<table>
+				<tr>
+				<td>
+					<select jsId="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>
+						<option value="FL">Florida</option>
+						<option value="CA">California</option>
+					</select>
+				</td>
+				<td>
+					<button dojoType="dijit.form.Button">
+						<script type="dojo/method" event="onClick">
+							ms1.invertSelection(true);
+							return false;
+						</script>
+						Invert Selection
+					</button>
+					<button dojoType="dijit.form.Button">
+						<script type="dojo/method" event="onClick">
+							ms1.set("disabled", !ms1.disabled);
+							return false;
+						</script>
+						Toggle Disabled
+					</button>
+					<button dojoType="dijit.form.Button">
+						<script type="dojo/method" event="onClick">
+							console.log(ms1.get("displayedValue"));
+							return false;
+						</script>
+						Get Displayed Value
+					</button>
+				</td>
+				<tr>
+					<td>
+						<select jsId="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>
+							<option value="ID">Idaho</option>
+							<option value="WY">Wyoming</option>
+							<option value="OR">Oregon</option>
+							<option value="PA">Pennsylvania</option>
+						</select>
+					</td>
+					<td>
+						<button dojoType="dijit.form.Button">
+							<script type="dojo/method" event="onClick">
+								ms2.set("readOnly", !ms2.readOnly);
+								return false;
+							</script>
+							Toggle Read Only
+						</button>
+					</td>
+				</tr>
+				<tr>
+					<td>
+						<select jsId="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">
+								checkOptions++;
+								ms3.addOption({value: checkOptions + "", label: "Option " + (checkOptions)});
+								return false;
+							</script>
+							Add Check Option
+						</button>
+						<button dojoType="dijit.form.Button">
+							<script type="dojo/method" event="onClick">
+								if(checkOptions > 0){
+									checkOptions--;
+									ms3.removeOption(checkOptions);
+								}
+								return false;
+							</script>
+							Remove Check Option
+						</button>
+					</td>
+				</tr>
+				<tr>
+					<td>
+						<select jsId="ms4" multiple="true" maxHeight="125" size="5" name="ms4" store="readStore" dojoType="dojox.form.CheckedMultiSelect" dropdown="false">
+						</select>
+					</td>
+					<td>
+						Read-Store-based
+					</td>
+				</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>
+			<button dojoType="dijit.form.Button">
+				Validate
+				<script type='dojo/method' event='onClick'>
+					var isvalid = rq1.isValid();
+					console.warn("isvalid?", isvalid, form, form.validate);
+					try{
+					rq1.validate();
+					form.validate();
+					}catch(e){
+					console.log(e);
+					}
+					console.warn("validated");
+				</script>
+			</button>
+			<hr><h2>Output values in console</h2>
+			<button dojoType="dijit.form.Button">
+				<script type="dojo/method" event="onClick">
+					console.dir(form.get("value"));
+					return false;
+				</script>
+				Get Values
+			</button>
+		</form>
+	</body>
+</html>
diff --git a/dojox/form/tests/test_DateTextBox.html b/dojox/form/tests/test_DateTextBox.html
index b9e7e39..2187d17 100644
--- a/dojox/form/tests/test_DateTextBox.html
+++ b/dojox/form/tests/test_DateTextBox.html
@@ -41,11 +41,6 @@
 		<!-- do not use, only for dynamic themes -->
 		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 
-		<script type="text/javascript" src="../../../dijit/form/ValidationTextBox.js"></script>
-		<script type="text/javascript" src="../../../dijit/form/_DateTimeTextBox.js"></script>
-		<script type="text/javascript" src="../../widget/Calendar.js"></script>
-		<script type="text/javascript" src="../DateTextBox.js"></script>
-
 		<script type="text/javascript">
 			dojo.require("dojox.form.DateTextBox");
 			dojo.require("dijit.form.Form");
diff --git a/dojox/form/tests/test_FileInput.html b/dojox/form/tests/test_FileInput.html
index 6f09f79..ef1890f 100644
--- a/dojox/form/tests/test_FileInput.html
+++ b/dojox/form/tests/test_FileInput.html
@@ -11,10 +11,9 @@
 	</style>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
-	<script type="text/javascript" src="../FileInput.js"></script>
-	<script type="text/javascript" src="../FileInputAuto.js"></script>
 	<script type="text/javascript">
-		// dojo.require("dojox.form.FileInput"); 
+		dojo.require("dojox.form.FileInput"); 
+		dojo.require("dojox.form.FileInputAuto"); 
 		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 		
 		var sampleCallback = function(data,ioArgs,widgetRef){
diff --git a/dojox/form/tests/test_FilePickerTextBox.html b/dojox/form/tests/test_FilePickerTextBox.html
index 8bb4dc3..3f2e71d 100644
--- a/dojox/form/tests/test_FilePickerTextBox.html
+++ b/dojox/form/tests/test_FilePickerTextBox.html
@@ -24,6 +24,7 @@
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 
 	<script type="text/javascript">
+		dojo.require("dojo.parser");
 		dojo.require("dojox.form.FilePickerTextBox");
 		dojo.require("dojox.data.FileStore");
 		dojo.require("dijit.form.Form");
diff --git a/dojox/form/tests/test_FileUploaderCSS.html b/dojox/form/tests/test_FileUploaderCSS.html
index 53877df..39a5144 100644
--- a/dojox/form/tests/test_FileUploaderCSS.html
+++ b/dojox/form/tests/test_FileUploaderCSS.html
@@ -1,37 +1,35 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
 <html lang="en">
 <head>
-    <title>FileUploader CSS Test</title>
-    <link href="../../../dijit/themes/dijit.css" rel="stylesheet" />
-    <link href="../../../dijit/themes/tundra/form/Button.css" rel="stylesheet" />
-    <link href="../resources/FileUploader.css" rel="stylesheet" />
+	<title>FileUploader CSS Test</title>
+	<link href="../../../dijit/themes/dijit.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/tundra/form/Button.css" rel="stylesheet" />
+	<link href="../resources/FileUploader.css" rel="stylesheet" />
 	<script>
-        djConfig = {
-            isDebug: true,
+	        djConfig = {
+	        	isDebug: true,
 			popup:true,
-            parseOnLoad: true
-        }
-    </script>
-    <script src="../../../dojo/dojo.js"></script>
-    <script>
-        dojo.require("dojox.form.FileUploader");
-        dojo.require("dijit.form.Button");
-		
-        dojo.addOnLoad(function(){
-			
+	        	parseOnLoad: true
+	        }
+	</script>
+	<script src="../../../dojo/dojo.js"></script>
+	<script>
+		dojo.require("dojo.parser");
+	        dojo.require("dojox.form.FileUploader");
+	        dojo.require("dijit.form.Button");
+
+	        dojo.ready(function(){
 			var props = {
 				isDebug:false,
 				hoverClass:"btnDftHover",
 				activeClass:"btnDftActive"
 			}
-			if(dijit.byId("btnD"))
+			if(dijit.byId("btnD")){
 				new dojox.form.FileUploader(dojo.mixin({button:dijit.byId("btnD")}, props));
-			
+			}
 		});
-        
-        
-    </script>
-    <style>
+	</script>
+	<style>
 		body{
 			font-family:sans-serif;
 		}
@@ -60,28 +58,25 @@
 			font-weight:normal;
 			font-size:14px;
 		}
-    </style>
-	
-	<style>
 		.flashBtn{
-            border:2px solid #333333;
-            background:url(images/grad.jpg) #d0d0d0 repeat-x scroll 0px bottom;
-            font-size:12px;
-            font-family:Arial;
-            padding:5px;
-            width:100px;
-            height:100px;
+			border:2px solid #333333;
+			background:url(images/grad.jpg) #d0d0d0 repeat-x scroll 0px bottom;
+			font-size:12px;
+			font-family:Arial;
+			padding:5px;
+			width:100px;
+			height:100px;
 			vertical-align:middle; /* emulates a <button> */
 			text-align:center;
-        }
-        .flashBtnHover{
-            background-image:url(images/grad_over.jpg);
+		}
+		.flashBtnHover{
+			background-image:url(images/grad_over.jpg);
 			color:#fff;
-            cursor:pointer;
-        }
-        .flashBtnPress{
-            background-image:url(images/grad_down.jpg);
-        }
+			cursor:pointer;
+		}
+		.flashBtnPress{
+			background-image:url(images/grad_down.jpg);
+		}
 		.top{
 			vertical-align:top;
 		}
@@ -96,8 +91,6 @@
 		.left{
 			text-align:left;
 		}
-		
-		
 		.gfx{
 			width:197px;
 			height:29px;
@@ -105,7 +98,6 @@
 			border:0;
 			text-align:left;
 			padding-left:55px;
-			
 			font-size:14px;
 			color:#fff;
 			font-weight:bold;
@@ -120,7 +112,6 @@
 			background:url(images/rndBtn_down.png) no-repeat;
 			color:#c6dfe3;
 		}
-		
 		.sprite{
 			width:197px;
 			height:29px;
@@ -128,12 +119,10 @@
 			border:0;
 			text-align:left;
 			padding-left:55px;
-			
 			font-size:14px;
 			color:#fff;
 			font-weight:bold;
 			font-style:italic;
-			
 		}
 		.spriteOver{
 			background:url(images/rndBtnSprite.png) no-repeat 0px -30px;
@@ -154,7 +143,6 @@
 		.wrapping{
 			width:100px;
 			height:60px;
-			
 			white-space:normal;
 			line-height:12px !important;
 			vertical-align:top;
@@ -164,7 +152,6 @@
 </head>
 <body class="tundra">
 	<h1>FileUploader CSS Test</h1>
-	
 	<h3>
 		All the buttons on this page are either Flash or HTML uploaders. They all should open a
 		file-browse dialog, but otherwise the uploading is non-functional. This page is for testing
@@ -177,7 +164,7 @@
 	</div>
 	<button isDebug="true" devMode="true" dojoType="dojox.form.FileUploader">Default Markup Flash</button>
 	<button force="html" dojoType="dojox.form.FileUploader">Default Markup HTML</button>
-	
+
 	<div class="note">
 		Testing float right and left, and using style="" to override class. The buttons should cascade properly when resizing
 		the window.
@@ -185,17 +172,16 @@
 	<div style="padding:10px; border:1px solid #ccc;float:left; width:60%; margin-bottom:20px;">
 		<button class="floatLeft" dojoType="dojox.form.FileUploader">Flash Float Left</button>
 		<button force="html" class="floatLeft" dojoType="dojox.form.FileUploader">Flash Float Left</button>
-		
 		<button dojoType="dojox.form.FileUploader" style="display:block; width:150px;float:right;">Flash Float Right</button>
-		<button force="html" dojoType="dojox.form.FileUploader" style="display:block; width:150px;float:right;margin-right:5px;">HTML Float Right</button>	
+		<button force="html" dojoType="dojox.form.FileUploader" style="display:block; width:150px;float:right;margin-right:5px;">HTML Float Right</button>
 	</div>
-	
+
 	<div class="note">
 		Text wrapping - FileUploader does not support text wrapping natively, it needs some CSS massaging to make it happen. 
 	</div>
 	<button class="wrapping" dojoType="dojox.form.FileUploader">Using a Flash button with long wrapping text</button>
 	<button force="html" class="wrapping" dojoType="dojox.form.FileUploader">Using an HTML button with long wrapping text</button>
-	
+
 	<div class="note">
 		Testing Dijit Button for backward compatibility. Use of a dijit button is
 		deprecated and will be removed in 1.5. On the right is the Flash Upload button and on the left a
@@ -203,20 +189,19 @@
 	</div>
 	<button id="btnX" class="dBtn" dojoType="dijit.form.Button">Using Dijit Button</button>
 	<button id="btnD" class="dBtn" dojoType="dijit.form.Button">Using Dijit Button</button>
-	
-	
+
 	<div class="note">Testing top-center</div>
 	<div baseClass="flashBtn top" hoverClass="flashBtnHover" activeClass="flashBtnPress" dojoType="dojox.form.FileUploader">Flash Top</div>
-	
+
 	<div class="note">Testing bottom-center with 20px bottom padding</div>
 	<div baseClass="flashBtn bot" hoverClass="flashBtnHover" activeClass="flashBtnPress" dojoType="dojox.form.FileUploader">Flash Bottom</div>
-	
+
 	<div class="note">Testing centered text, wide border and a left margin</div>
 	<div id="btn1" class="flashBtn ctr" hoverClass="flashBtnHover" activeClass="flashBtnPress" dojoType="dojox.form.FileUploader">Flash Center</div>
-	
+
 	<div class="note">Testing left align</div>
 	<button id="btn3" class="flashBtn left" hoverClass="flashBtnHover" activeClass="flashBtnPress" dojoType="dojox.form.FileUploader">Flash Left</button>
-	
+
 	<div class="note">
 		Testing background images for HTML and Flash buttons. "GFX" uses three
 		different images, "SPRITE" uses one sprited image with the background-position changed. The
@@ -228,8 +213,7 @@
 	<button class="sprite" hoverClass="spriteOver" activeClass="spriteDown" dojoType="dojox.form.FileUploader">FLASH BK SPRITE</button>
 	<button class="gfx" hoverClass="gfxOver" activeClass="gfxDown" dojoType="dojox.form.FileUploader">HTML BK GFX</button>
 	<button class="gfx" hoverClass="gfxOver" activeClass="gfxDown" dojoType="dojox.form.FileUploader">Flash BK GFX</button>
-	
-	
+
 	<table style="margin-bottom:30px;">
 		<tr>
 		<td>
@@ -247,7 +231,7 @@
 		<td>
 			<div class="scrolls">
 				Testing a
-			<div>	
+			<div>
 				<button class="block" dojoType="dojox.form.FileUploader">HTML Block Display Button</button>
 			</div>
 			in a scrolling pane. This is really just to see if IE blows up on this as well as the
@@ -255,10 +239,8 @@
 			still work however - the button is built outside of the pane and inserted (as well as
 			the previous inline test). This will cause a slower render time.
 			</div>
-			
 		</td>
 		</tr>
 	</table>
-	
 </body>
 </html>
diff --git a/dojox/form/tests/test_FileUploaderDialog.html b/dojox/form/tests/test_FileUploaderDialog.html
index f5999a6..ac73caa 100644
--- a/dojox/form/tests/test_FileUploaderDialog.html
+++ b/dojox/form/tests/test_FileUploaderDialog.html
@@ -17,6 +17,7 @@
     </script>
     <script src="../../../dojo/dojo.js"></script>
     <script>
+		dojo.require("dojo.parser");
         dojo.require("dojox.form.FileUploader");
         dojo.require("dijit.form.Button");
 		dojo.require("dijit.Dialog");
diff --git a/dojox/form/tests/test_FileUploaderForm.html b/dojox/form/tests/test_FileUploaderForm.html
index eb0967f..3b6069c 100644
--- a/dojox/form/tests/test_FileUploaderForm.html
+++ b/dojox/form/tests/test_FileUploaderForm.html
@@ -12,13 +12,14 @@
 	</style>
 	<script>
         djConfig = {
-            isDebug: false,
+            isDebug: true,
 			popup:true,
             parseOnLoad: true
         }
     </script>
     <script src="../../../dojo/dojo.js"></script>
     <script>
+		dojo.require("dojo.parser");
         dojo.require("dojox.form.FileUploader");
         dojo.require("dijit.form.Button");
 		dojo.require("dijit.ProgressBar");
diff --git a/dojox/form/tests/test_FileUploaderTabs.html b/dojox/form/tests/test_FileUploaderTabs.html
index 2e87947..50020fd 100644
--- a/dojox/form/tests/test_FileUploaderTabs.html
+++ b/dojox/form/tests/test_FileUploaderTabs.html
@@ -17,6 +17,7 @@
     </script>
     <script src="../../../dojo/dojo.js"></script>
     <script>
+		dojo.require("dojo.parser");
         dojo.require("dojox.form.FileUploader");
         dojo.require("dijit.form.Button");
 		dojo.require("dijit.Dialog");
diff --git a/dojox/form/tests/test_ListInput.html b/dojox/form/tests/test_ListInput.html
index a64bc6e..41f42c1 100755
--- a/dojox/form/tests/test_ListInput.html
+++ b/dojox/form/tests/test_ListInput.html
@@ -18,7 +18,7 @@
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="debugAtAllCost:true,isDebug: true,parseOnLoad:true"></script>
 	
 	<script type="text/javascript">
-		//not for test
+		dojo.require("dojo.parser");
 		dojo.require("dijit.layout.TabContainer");
 		dojo.require("dijit.layout.ContentPane");
 		dojo.require("dijit.form.Button");
diff --git a/dojox/form/tests/test_Manager1.html b/dojox/form/tests/test_Manager1.html
index 42faeb7..e080fe4 100644
--- a/dojox/form/tests/test_Manager1.html
+++ b/dojox/form/tests/test_Manager1.html
@@ -18,19 +18,21 @@
 		.makeYellow		{ background-color: #ffa; }
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
-	<script type="text/javascript" src="../manager/Mixin.js"></script>
-	<script type="text/javascript" src="../manager/FormMixin.js"></script>
-	<script type="text/javascript" src="../manager/ValueMixin.js"></script>
-	<script type="text/javascript" src="../manager/EnableMixin.js"></script>
-	<script type="text/javascript" src="../manager/DisplayMixin.js"></script>
-	<script type="text/javascript" src="../manager/ClassMixin.js"></script>
+	<!--
+	<script type="text/javascript" src="../manager/_Mixin.js"></script>
+	<script type="text/javascript" src="../manager/_FormMixin.js"></script>
+	<script type="text/javascript" src="../manager/_ValueMixin.js"></script>
+	<script type="text/javascript" src="../manager/_EnableMixin.js"></script>
+	<script type="text/javascript" src="../manager/_DisplayMixin.js"></script>
+	<script type="text/javascript" src="../manager/_ClassMixin.js"></script>
 	<script type="text/javascript" src="../Manager.js"></script>
+	-->
 	<script type="text/javascript">
 		dojo.require("dojox.form.Manager");
 
 		dojo.require("dijit.dijit");			// optimize: load dijit layer
 		dojo.require("dijit.form.Button");
-		dojo.require("dijit.form.CheckBox");	// includes dijit.form.RadioButton
+		dojo.require("dijit.form.RadioButton");
 		dojo.require("dijit.form.TextBox");
 		dojo.require("dijit.form.ComboBox");
 		dojo.require("dijit.form.SimpleTextarea");
diff --git a/dojox/form/tests/test_MultiComboBox.html b/dojox/form/tests/test_MultiComboBox.html
index e017f02..cda0244 100644
--- a/dojox/form/tests/test_MultiComboBox.html
+++ b/dojox/form/tests/test_MultiComboBox.html
@@ -17,8 +17,9 @@
 		<script type="text/javascript" src="../../../dojo/dojo.js"
 			djConfig="isDebug: true, parseOnLoad: true"></script>
 		<script type="text/javascript">
-			dojo.require("dojox.form.MultiComboBox"); 
-			dojo.require("dojo.data.ItemFileReadStore"); 
+			dojo.require("dojo.parser");
+			dojo.require("dojox.form.MultiComboBox");
+			dojo.require("dojo.data.ItemFileReadStore");
 			dojo.require("dijit.form.Button"); 
 		</script>
 	</head>
diff --git a/dojox/form/tests/test_PasswordValidator.html b/dojox/form/tests/test_PasswordValidator.html
index ef6f9e9..df2d88c 100644
--- a/dojox/form/tests/test_PasswordValidator.html
+++ b/dojox/form/tests/test_PasswordValidator.html
@@ -4,10 +4,9 @@
 	        src="../../../dojo/dojo.js"
 	        djConfig="isDebug: true, parseOnLoad: true">
 	    </script>
-		<script type="text/javascript" src="../PasswordValidator.js"></script>
 	    <script type="text/javascript">
 			dojo.require("doh.runner");
-	        dojo.require("dojo.parser");
+			dojo.require("dojo.parser");
 			dojo.require("dojox.form.PasswordValidator");
 			dojo.require("dijit.form.Button");
 			dojo.require("dijit.form.Form");
@@ -17,70 +16,82 @@
 					[
 						function test_setDisabled(t){
 							valid1.set("disabled", true);
-							t.t(dojo.every(dojo.query("[widgetId]", 
-													valid1.domNode).map(function(i){
-														return dijit.byNode(i);
-													}), function(i){return i.disabled;}));
+							t.t(dojo.every(
+								dojo.query("[widgetId]", valid1.domNode)
+								.map(function(i){
+									return dijit.byNode(i);
+								}),
+								function(i){
+									return i.disabled;
+								}
+							), "disabled");
 							valid1.set("disabled", false);
-							t.t(dojo.every(dojo.query("[widgetId]", 
-													valid1.domNode).map(function(i){
-														return dijit.byNode(i);
-													}), function(i){return !i.disabled;}));
+							t.t(dojo.every(
+								dojo.query("[widgetId]", valid1.domNode)
+								.map(function(i){
+									return dijit.byNode(i);
+								}),
+								function(i){
+									return !i.disabled;
+								}
+							), "enabled");
 						},
 						function test_isValid(t){
-							t.f(form1.isValid());
+							t.f(form1.isValid(), "form invalid");
 							dijit.byId("nv1").set("value", "test");
 							dijit.byId("vv1").set("value", "Test");
-							t.f(form1.isValid());
+							t.f(form1.isValid(), "isValid() 1");
 							dijit.byId("vv1").set("value", "test");
-							t.t(form1.isValid());
-							t.t(form6.isValid());
-							t.is({password: ""}, form6.get("value"));
+							t.t(form1.isValid(), "isValid() 2");
+							t.t(form6.isValid(), "isValid() 3");
+							t.is({password: ""}, form6.get("value"), '{password: ""}');
 							dijit.byId("nv6").set("value", "test");
-							t.f(form6.isValid());
-							t.is({password: ""}, form6.get("value"));
+							t.f(form6.isValid(), "isValid() 4");
+							t.is({password: ""}, form6.get("value"), '{password: ""}');
 							dijit.byId("vv6").set("value", "test");
-							t.t(form6.isValid());
-							t.is({password: "test"}, form6.get("value"));
+							t.t(form6.isValid(), "isValid() 5");
+							t.is({password: "test"}, form6.get("value"), '{password: "test"}');
 						},
 						function test_getValue(t){
 							dijit.byId("nv1").set("value", "test");
 							dijit.byId("vv1").set("value", "Test");
-							t.is({password: ""}, form1.get("value"));
+							t.is({password: ""}, form1.get("value"), '{password: ""}');
 							dijit.byId("vv1").set("value", "test123");
 							dijit.byId("nv1").set("value", "test123");
-							t.is({password: "test123"}, form1.get("value"));
+							t.is({password: "test123"}, form1.get("value"), '{password: "test123"}');
 						},
 						function test_oldPW(t){
 							dijit.byId("nv2").set("value", "test");
 							dijit.byId("vv2").set("value", "test");
-							t.f(form2.isValid());
+							t.f(form2.isValid(), "isValid() 1");
 							dijit.byId("ov2").set("value", "oldpw4");
-							t.f(form2.isValid());
+							t.f(form2.isValid(), "isValid() 2");
 							dijit.byId("ov2").set("value", "oldpw2");
-							t.t(form2.isValid());
+							t.t(form2.isValid(), "isValid() 3");
 						},
 						function test_getOldValue(t){
-							t.is({password: "test"}, form2.get("value"));
+							t.is({password: "test"}, form2.get("value"), '{password: "test"}');
 							dijit.byId("nv3").set("value", "test");
 							dijit.byId("vv3").set("value", "test");
 							dijit.byId("ov3").set("value", "oldpw4");
-							t.is({password: "", oldPassword: ""}, form3.get("value"));
+							t.is({password: "", oldPassword: ""}, form3.get("value"), '{password: "", oldPassword: ""}');
 							dijit.byId("ov3").set("value", "oldpw3");
 							dijit.byId("vv3").set("value", "Test");
-							t.is({password: "", oldPassword: ""}, form3.get("value"));
+							t.is({password: "", oldPassword: ""}, form3.get("value"), '{password: "", oldPassword: ""}');
 							dijit.byId("vv3").set("value", "test");
-							t.is({password: "test", oldPassword: "oldpw3"}, form3.get("value"));
+							t.is({password: "test", oldPassword: "oldpw3"}, form3.get("value"),
+									'{password: "test", oldPassword: "oldpw3"}');
 						},
 						function test_getValuesInTable(t){ 
 							dijit.byId("nv4").set("value", "test"); 
 							dijit.byId("vv4").set("value", "test"); 
 							dijit.byId("ov4").set("value", "oldpw4"); 
-							t.is({password: "test"}, form4.get("value")); 
+							t.is({password: "test"}, form4.get("value"), '{password: "test"}');
 							dijit.byId("nv5").set("value", "test"); 
 							dijit.byId("vv5").set("value", "test"); 
 							dijit.byId("ov5").set("value", "oldpw5"); 
-							t.is({password: "test", oldPassword: "oldpw5"}, form5.get("value")); 
+							t.is({password: "test", oldPassword: "oldpw5"}, form5.get("value"),
+									'{password: "test", oldPassword: "oldpw5"}');
 						} 
 					]
 				);
diff --git a/dojox/form/tests/test_RangeSlider.html b/dojox/form/tests/test_RangeSlider.html
index e8873cf..5d8dfc9 100644
--- a/dojox/form/tests/test_RangeSlider.html
+++ b/dojox/form/tests/test_RangeSlider.html
@@ -23,6 +23,7 @@
 
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript">
+		dojo.require("dojo.parser");
 		dojo.require("dojox.form.RangeSlider");
 		dojo.require("dijit.form.HorizontalRule");
 		dojo.require("dijit.form.HorizontalRuleLabels");
diff --git a/dojox/form/tests/test_Rating.html b/dojox/form/tests/test_Rating.html
index 99b2fed..abe75a2 100644
--- a/dojox/form/tests/test_Rating.html
+++ b/dojox/form/tests/test_Rating.html
@@ -11,11 +11,8 @@
 	</style>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
-	<script type="text/javascript" src="../../../dijit/_Templated.js"></script>
-	<script type="text/javascript" src="../../../dijit/_Container.js"></script>
-	<script type="text/javascript" src="../../../dijit/form/_FormWidget.js"></script>
-	<script type="text/javascript" src="../Rating.js"></script>
 	<script type="text/javascript">
+		dojo.require("dojox.form.Rating");
 		dojo.require("dojo.parser"); // scan page for widgets and instantiate them
 	</script>
 	<style>
diff --git a/dojox/form/tests/test_TimeSpinner.html b/dojox/form/tests/test_TimeSpinner.html
index cb3f84b..7e8f8e5 100644
--- a/dojox/form/tests/test_TimeSpinner.html
+++ b/dojox/form/tests/test_TimeSpinner.html
@@ -13,6 +13,7 @@
 		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
 
 		<script type="text/javascript">
+			dojo.require("dojo.parser");
 			dojo.require("dojox.form.TimeSpinner");
 
 			function displayData() {
diff --git a/dojox/form/tests/test_TriStateCheckbox.html b/dojox/form/tests/test_TriStateCheckbox.html
new file mode 100644
index 0000000..5cc8880
--- /dev/null
+++ b/dojox/form/tests/test_TriStateCheckbox.html
@@ -0,0 +1,135 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>TriStateCheckBox Widget Demo</title>
+		<style type="text/css">
+			@import "../../../dijit/themes/claro/document.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+			@import "../resources/TriStateCheckBox.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" data-dojo-config="isDebug: true, parseOnLoad: true">
+		</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");
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<h1 class="testTitle">Dojox TriStateCheckBoxes Test</h1>
+		<p>
+			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"'>
+			<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="dojox.form.TriStateCheckBox" data-dojo-props='name:"cb1", value:"foo", onClick:function(){ console.log("clicked cb1") }'/>
+			<label for="cb1">
+				cb1: normal TriStateCheckbox, 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="dojox.form.TriStateCheckBox" data-dojo-props='onChange:reportChecked, name:"cb2", checked:true'/>
+			<label for="cb2">
+				cb2: normal 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'));">
+				get('value')
+			</button>
+			<br>
+			<input id="cb3" data-dojo-type="dojox.form.TriStateCheckBox" data-dojo-props='name:"cb3", disabled:true'/>
+			<label for="cb3">
+				cb3: disabled TriStateCheckbox
+			</label>
+			<br>
+			<input id="cb4" data-dojo-type="dojox.form.TriStateCheckBox" data-dojo-props='name:"cb4", readOnly:true, checked:true'/>
+			<label for="cb4">
+				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"); }'/>
+			<label for="cb5">
+				cb5: normal TriStateCheckbox, 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" type="text"/>
+			<label for="cb6">
+				cb6: instantiated from script
+			</label>
+			<br>
+			<input id="cb7" data-dojo-type="dojox.form.TriStateCheckBox" data-dojo-props='onChange:reportValueChanged, name:"cb7" '/>
+			<label for="cb7">
+				cb7: normal 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' />
+			<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"]'/>
+			<label for="cb8">
+				cb8: normal 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]'/>
+			<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]'/>
+			<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"'>
+				Submit
+			</button>
+			<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"reset"'>
+				HTML Reset
+			</button>
+		</form>
+		</div>
+		<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 e788757..f621a4d 100644
--- a/dojox/form/tests/test_Uploader.html
+++ b/dojox/form/tests/test_Uploader.html
@@ -5,10 +5,7 @@
 	<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>
@@ -18,22 +15,19 @@
 		}
 		.browseButton{
 			width:300px;
-			height:20px;
+			/*height:20px;*/
 			font-weight:bold;
 			margin:10px 0 2px 0;
 		}
 		.dijitTabPane{
 			padding:20px;
 		}
-		form{
-			width:315px;
-			margin-right:10px;
-		}
 		fieldset{
 			text-align:right;
+			padding: 5px;
 		}
 		input[type=text]{
-			width:140px;
+			width:135px;
 		}
 		.dijitButton{
 			margin-top:15px;
@@ -79,28 +73,19 @@
 		#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;
+		form{
+			margin-bottom:15px;
 		}
 		code{
 			font-family:monospace;
 			white-space:nowrap;
 		}
+		.browseButton, .browseButton .dijitButton, .browseButton .dijitButtonNode {
+			display:block;
+		}
+		.dijitUploadDisplayInput {
+			width:100px;
+		}
 	</style>
 	<script>
 		djConfig = {
@@ -110,15 +95,15 @@
 	</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");
 
 		var handleUpload = function(upl, node){
-
 			dojo.connect(upl, "onComplete", function(dataArray){
-				dojo.forEach(dataArray, function(file){
+				dojo.forEach(dojo.isArray(dataArray)?dataArray:[dataArray], function(file){
 					console.log("display:", file)
 
 					var div = dojo.create('div', {className:'thumb'});
@@ -127,10 +112,24 @@
 					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(){
-			dojo.connect(dijit.byId("remBtn"), "onClick", dijit.byId("uploader"), "reset");
-			handleUpload(dijit.byId("uploader"), dojo.byId('colImages'));
+			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'));
+			if(require.has('file-multiple')){
+				handleDnD(uploader.domNode.parentNode, uploader);
+				handleDnD(uploader2.domNode.parentNode, uploader2);
+			}
 		});
 	</script>
 </head>
@@ -148,14 +147,15 @@
 		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>
 
 	<table class="pageTable">
 		<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">
+						<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" />
@@ -163,11 +163,21 @@
 						<div id="files" dojoType="dojox.form.uploader.FileList" 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>
+					</fieldset>
+				</form>
 			</td>
 			<td id="colImages">
 			</td>
 		</tr>
 	</table>
-
 </body>
 </html>
diff --git a/dojox/form/tests/test_UploaderAll.html b/dojox/form/tests/test_UploaderAll.html
index d02a196..beb4f8d 100644
--- a/dojox/form/tests/test_UploaderAll.html
+++ b/dojox/form/tests/test_UploaderAll.html
@@ -110,6 +110,7 @@
 	</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");
diff --git a/dojox/form/uploader/Base.js b/dojox/form/uploader/Base.js
index 0c8dc2c..53f81a9 100644
--- a/dojox/form/uploader/Base.js
+++ b/dojox/form/uploader/Base.js
@@ -1,9 +1,26 @@
-dojo.provide("dojox.form.uploader.Base");
+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){
 
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
+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')]);});
 
-dojo.declare("dojox.form.uploader.Base", [dijit._Widget, dijit._Templated], {
+	/*=====
+		Widget = dijit._Widget;
+		TemplatedMixin = dijit._TemplatedMixin;
+		WidgetsInTemplateMixin = dijit._WidgetsInTemplateMixin;
+	=====*/
+return declare("dojox.form.uploader.Base", [Widget, TemplatedMixin, WidgetsInTemplateMixin], {
 	//
 	// Version: 1.6
 	//
@@ -44,44 +61,31 @@ dojo.declare("dojox.form.uploader.Base", [dijit._Widget, dijit._Templated], {
 
 
 	connectForm: function(){
-		//console.log("connectForm...", this.url, !!this.uploadUrl, !!this.getForm())
-
+		// 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){
-				dojo.stopEvent(evt);
-				this.submit(dojo.formToObject(this.form));
+				event.stop(evt);
+				this.submit(this.form);
 			});
-			//console.log("----------------form connected:", this.url)
 		}
-		//console.log("form:", this.form, this.url);
 	},
 
 	supports: function(what){
 		//	summary:
 		// 		Does feature testing for uploader capabilities. (No browser sniffing - yay)
 		//
-		if(!this._hascache){
-			this._hascache = {
-				testDiv: dojo.create("div"),
-				testInput: dojo.create("input", {type:"file"}),
-				xhr:!!window.XMLHttpRequest ? new XMLHttpRequest() : {}
-			};
-			dojo.style(this._hascache.testDiv, "opacity", .7);
-		}
 		switch(what){
-			case "FormData":
-				return !!window.FormData;
-			case "sendAsBinary":
-				return !!this._hascache.xhr.sendAsBinary;
-			case "opacity":
-				return dojo.style(this._hascache.testDiv, "opacity") == .7;
 			case "multiple":
 				if(this.force == "flash" || this.force == "iframe") return false;
-				var res = dojo.attr(this._hascache.testInput, "multiple");
-				return res===true || res===false; // IE will be undefined
+				return has("file-multiple");
+			case "FormData":
+				return has(what);
+			case "sendAsBinary":
+				return has("xhr-sendAsBinary");
 		}
 		return false; // Boolean
 	},
@@ -118,3 +122,4 @@ dojo.declare("dojox.form.uploader.Base", [dijit._Widget, dijit._Templated], {
 		}; // Object
 	}
 });
+});
diff --git a/dojox/form/uploader/FileList.js b/dojox/form/uploader/FileList.js
index 2f30a1b..1b4fcf7 100644
--- a/dojox/form/uploader/FileList.js
+++ b/dojox/form/uploader/FileList.js
@@ -1,8 +1,18 @@
-dojo.provide("dojox.form.uploader.FileList");
-
-dojo.require("dojox.form.uploader.Base");
-
-dojo.declare("dojox.form.uploader.FileList", [dojox.form.uploader.Base], {
+define([
+	"dojo/_base/fx",
+	"dojo/dom-style",
+	"dojo/dom-class",
+	"dojo/_base/declare",
+	"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
 	//
@@ -46,10 +56,9 @@ dojo.declare("dojox.form.uploader.FileList", [dojox.form.uploader.Base], {
 	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">'+
-							'<tr class="dojoxUploaderFileListHeader"><th class="dojoxUploaderIndex">${headerIndex}</th><th class="dojoxUploaderIcon">${headerType}</th><th class="dojoxUploaderFileName">${headerFilename}</th><th class="dojoxUploaderFileSize">${headerFilesize}</th></tr>'+
-							'<tr ><td colSpan="4" class="dojoxUploaderFileListContainer" dojoAttachPoint="containerNode">'+
-								'<table class="dojoxUploaderFileListContent" dojoAttachPoint="listNode"></table>'+
-							'</td><tr>'+
+							'<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>'
 						,
@@ -77,7 +86,7 @@ dojo.declare("dojox.form.uploader.FileList", [dojox.form.uploader.Base], {
 		if(!this.uploaderId && !this.uploader){
 			console.warn("uploaderId not passed to UploaderFileList");
 		}else if(this.uploaderId && !this.uploader){
-			this.uploader = dijit.byId(this.uploaderId);
+			this.uploader = manager.byId(this.uploaderId);
 		}else if(this._upCheckCnt>4){
 			console.warn("uploader not found for ID ", this.uploaderId);
 			return;
@@ -90,13 +99,18 @@ dojo.declare("dojox.form.uploader.FileList", [dojox.form.uploader.Base], {
 			});
 			this.connect(this.uploader, "onProgress", "_progress");
 			this.connect(this.uploader, "onComplete", function(){
-				setTimeout(dojo.hitch(this, function(){
+				setTimeout(lang.hitch(this, function(){
 					this.hideProgress(true);
 				}), 1250);
 			});
+			if(!(this._fileSizeAvail = {'html5':1,'flash':1}[this.uploader.uploadType])){
+				//if uploadType is neither html5 nor flash, file size is not available
+				//hide the size header
+				this.sizeHeader.style.display="none";
+			}
 		}else{
 			this._upCheckCnt++;
-			setTimeout(dojo.hitch(this, "setUploader"), 250);
+			setTimeout(lang.hitch(this, "setUploader"), 250);
 		}
 	},
 
@@ -128,17 +142,17 @@ dojo.declare("dojox.form.uploader.FileList", [dojox.form.uploader.Base], {
 
 	_progress: function(/* Object */ customEvent){
 		this.percentTextNode.innerHTML = customEvent.percent;
-		dojo.style(this.percentBarNode, "width", customEvent.percent);
+		domStyle.set(this.percentBarNode, "width", customEvent.percent);
 	},
 
 	_hideShowProgress: function(o){
 		var node = this.progressNode;
 		var onEnd = function(){
-			dojo.style(node, "display", o.endDisp);
+			domStyle.set(node, "display", o.endDisp);
 		}
 		if(o.ani){
-			dojo.style(node, "display", "block");
-			dojo.animateProperty({
+			domStyle.set(node, "display", "block");
+			fx.animateProperty({
 				node: node,
 				properties:{
 					height:{
@@ -156,7 +170,7 @@ dojo.declare("dojox.form.uploader.FileList", [dojox.form.uploader.Base], {
 
 	_onUploaderChange: function(fileArray){
 		this.reset();
-		dojo.forEach(fileArray, function(f, i){
+		array.forEach(fileArray, function(f, i){
 			this._addRow(i+1, this.getFileType(f.name), f.name, f.size);
 		}, this)
 	},
@@ -165,20 +179,23 @@ dojo.declare("dojox.form.uploader.FileList", [dojox.form.uploader.Base], {
 
 		var c, r = this.listNode.insertRow(-1);
 		c = r.insertCell(-1);
-		dojo.addClass(c, "dojoxUploaderIndex");
+		domClass.add(c, "dojoxUploaderIndex");
 		c.innerHTML = index;
 
 		c = r.insertCell(-1);
-		dojo.addClass(c, "dojoxUploaderIcon");
+		domClass.add(c, "dojoxUploaderIcon");
 		c.innerHTML = type;
 
 		c = r.insertCell(-1);
-		dojo.addClass(c, "dojoxUploaderFileName");
+		domClass.add(c, "dojoxUploaderFileName");
 		c.innerHTML = name;
-		c = r.insertCell(-1);
-		dojo.addClass(c, "dojoxUploaderSize");
-		c.innerHTML = this.convertBytes(size).value;
+		if(this._fileSizeAvail){
+			c = r.insertCell(-1);
+			domClass.add(c, "dojoxUploaderSize");
+			c.innerHTML = this.convertBytes(size).value;
+		}
 
 		this.rowAmt++;
 	}
 });
+});
diff --git a/dojox/form/uploader/plugins/Flash.js b/dojox/form/uploader/plugins/Flash.js
index 42ebc0f..4b31aff 100644
--- a/dojox/form/uploader/plugins/Flash.js
+++ b/dojox/form/uploader/plugins/Flash.js
@@ -1,10 +1,19 @@
-dojo.provide("dojox.form.uploader.plugins.Flash");
-
-dojo.require("dojox.form.uploader.plugins.HTML5");
-dojo.require("dojox.embed.flashVars");
-dojo.require("dojox.embed.Flash");
-
-dojo.declare("dojox.form.uploader.plugins.Flash", [], {
+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
 	//
@@ -16,12 +25,12 @@ dojo.declare("dojox.form.uploader.plugins.Flash", [], {
 	//		that Firefox and Webkit have with the Flash plugin.
 	//
 	//	description:
-	//		Inherits all properties from dojox.form.Uploader and dojox.form.uploader.plugins.HTML5.
+	//		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:dojo.config.uploaderPath || dojo.moduleUrl("dojox.form", "resources/uploader.swf"),
+	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.
@@ -71,7 +80,6 @@ dojo.declare("dojox.form.uploader.plugins.Flash", [], {
 			this.getFileList = this.getFlashFileList;
 			this.reset = this.flashReset;
 			this.upload = this.uploadFlash;
-			this.submit = this.submitFlash;
 			this.fieldname = "flashUploadFiles"; ///////////////////// this.name
 		}
 		this.inherited(arguments);
@@ -83,7 +91,7 @@ dojo.declare("dojox.form.uploader.plugins.Flash", [], {
 
 	onReady: function(/* dojox.form.FileUploader */ uploader){
 		// summary:
-		//		Stub - Fired when dojox.embed.Flash has created the
+		//		Stub - Fired when embedFlash has created the
 		//		Flash object, but it has not necessarilly finished
 		//		downloading, and is ready to be communicated with.
 	},
@@ -126,28 +134,18 @@ dojo.declare("dojox.form.uploader.plugins.Flash", [], {
 	 *	   Private Methods	 *
 	 *************************/
 
-	uploadFlash: function(){
+	uploadFlash: function(/*Object ? */formData){
 		// summary:
 		// 		Uploads selected files. Alias "upload()" should be used instead.
 		// tags:
 		//		private
 		this.onBegin(this.getFileList());
-		this.flashMovie.doUpload();
-	},
-
-	submitFlash: function(/* Object */formParams){
-		// summary:
-		// 		Uploads selected files with form data. Alias "submit()" should be used instead.
-		// tags:
-		//		private
-		this.onBegin(this.getFileList());
-		this.flashMovie.doUpload(formParams);
+		this.flashMovie.doUpload(formData);
 	},
 
-
 	_change: function(fileArray){
 		this._files = this._files.concat(fileArray);
-		dojo.forEach(fileArray, function(f){
+		array.forEach(fileArray, function(f){
 			f.bytesLoaded = 0;
 			f.bytesTotal = f.size;
 			this._fileMap[f.name+"_"+f.size] = f;
@@ -204,8 +202,8 @@ dojo.declare("dojox.form.uploader.plugins.Flash", [], {
 		this._subs = [];
 		this._cons = [];
 
-		var doSub = dojo.hitch(this, function(s, funcStr){
-			this._subs.push(dojo.subscribe(this.id + s, this, funcStr));
+		var doSub = lang.hitch(this, function(s, funcStr){
+			this._subs.push(connect.subscribe(this.id + s, this, funcStr));
 		});
 
 		doSub("/filesSelected", "_change");
@@ -215,16 +213,6 @@ dojo.declare("dojox.form.uploader.plugins.Flash", [], {
 		doSub("/filesCanceled", "onCancel");
 		doSub("/stageBlur", "_onFlashBlur");
 
-		var cs = dojo.hitch(this, function(s, nm){
-			this._cons.push(dojo.subscribe(this.id + s, this, function(evt){
-				this.button._cssMouseEvent({type:nm});
-			}));
-		});
-		cs("/up", "mouseup");
-		cs("/down", "mousedown");
-		cs("/over", "mouseover");
-		cs("/out", "mouseout");
-
 		this.connect(this.domNode, "focus", function(){
 			// TODO: some kind of indicator that the Flash button
 			//	is in focus
@@ -232,7 +220,7 @@ dojo.declare("dojox.form.uploader.plugins.Flash", [], {
 			this.flashMovie.doFocus();
 		});
 		if(this.tabIndex>=0){
-			dojo.attr(this.domNode, "tabIndex", this.tabIndex);
+			domAttr.set(this.domNode, "tabIndex", this.tabIndex);
 		}
 	},
 	_createFlashUploader: function(){
@@ -255,8 +243,8 @@ dojo.declare("dojox.form.uploader.plugins.Flash", [], {
 			console.warn("Warning: no uploadUrl provided.");
 		}
 
-		this.inputNode = dojo.create("div", {className:"dojoxFlashNode"}, this.domNode, "first");
-		dojo.style(this.inputNode, {
+		this.inputNode = domConstruct.create("div", {className:"dojoxFlashNode"}, this.domNode, "first");
+		domStyle.set(this.inputNode, {
 			position:"absolute",
 			top:"-2px",
 			width:this.btnSize.w+"px",
@@ -295,14 +283,14 @@ dojo.declare("dojox.form.uploader.plugins.Flash", [], {
 
 		};
 
-		this.flashObject = new dojox.embed.Flash(args, this.inputNode);
-		this.flashObject.onError = dojo.hitch(function(msg){
+		this.flashObject = new embedFlash(args, this.inputNode);
+		this.flashObject.onError = lang.hitch(function(msg){
 			console.error("Flash Error: " + msg);
 		});
-		this.flashObject.onReady = dojo.hitch(this, function(){
+		this.flashObject.onReady = lang.hitch(this, function(){
 			this.onReady(this);
 		});
-		this.flashObject.onLoad = dojo.hitch(this, function(mov){
+		this.flashObject.onLoad = lang.hitch(this, function(mov){
 			this.flashMovie = mov;
 			this.flashReady = true;
 
@@ -311,4 +299,8 @@ dojo.declare("dojox.form.uploader.plugins.Flash", [], {
 		this._connectFlash();
 	}
 });
-dojox.form.addUploaderPlugin(dojox.form.uploader.plugins.Flash);
+dojox.form.addUploaderPlugin(pluginsFlash);
+
+
+return pluginsFlash;
+});
diff --git a/dojox/form/uploader/plugins/HTML5.js b/dojox/form/uploader/plugins/HTML5.js
index a1681d8..fb06cbc 100644
--- a/dojox/form/uploader/plugins/HTML5.js
+++ b/dojox/form/uploader/plugins/HTML5.js
@@ -1,6 +1,11 @@
-dojo.provide("dojox.form.uploader.plugins.HTML5");
-
-dojo.declare("dojox.form.uploader.plugins.HTML5", [], {
+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
 	//
@@ -22,10 +27,18 @@ dojo.declare("dojox.form.uploader.plugins.HTML5", [], {
 		this.connectForm();
 		this.inherited(arguments);
 		if(this.uploadOnSelect){
-			this.connect(this, "onChange", "upload");
+			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	 *
 	 *************************/
@@ -42,16 +55,24 @@ dojo.declare("dojox.form.uploader.plugins.HTML5", [], {
 		}
 	},
 
-	submit: function(/* form Node ? */form){
+	addDropTarget: function(node, /*Boolean?*/onlyConnectDrop){
 		// summary:
-		//		See: dojox.form.Uploader.submit
-		//
-		form = !!form ? form.tagName ? form : this.getForm() : this.getForm();
-		var data = dojo.formToObject(form);
-		console.log("form data:", data);
-		this.upload(data);
+		//		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
@@ -76,6 +97,9 @@ dojo.declare("dojox.form.uploader.plugins.HTML5", [], {
 		if(!msg){
 			this.onError(this.errMsg);
 		}else{
+			console.log("msg:", msg)
+			console.log("xhr:", xhr)
+
 			xhr.sendAsBinary(msg);
 		}
 	},
@@ -89,9 +113,8 @@ dojo.declare("dojox.form.uploader.plugins.HTML5", [], {
 		if(!this.getUrl()){
 			console.error("No upload url found.", this); return;
 		}
-
 		var fd = new FormData();
-		dojo.forEach(this.inputNode.files, function(f, i){
+		array.forEach(this._files, function(f, i){
 			fd.append(this.name+"s[]", f);
 		}, this);
 
@@ -128,26 +151,26 @@ dojo.declare("dojox.form.uploader.plugins.HTML5", [], {
 	createXhr: function(){
 		var xhr = new XMLHttpRequest();
 		var timer;
-        xhr.upload.addEventListener("progress", dojo.hitch(this, "_xhrProgress"), false);
-        xhr.addEventListener("load", dojo.hitch(this, "_xhrProgress"), false);
-        xhr.addEventListener("error", dojo.hitch(this, function(evt){
+		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", dojo.hitch(this, function(evt){
+		xhr.addEventListener("abort", lang.hitch(this, function(evt){
 			this.onAbort(evt);
 			clearInterval(timer);
 		}), false);
-        xhr.onreadystatechange = dojo.hitch(this, function() {
-			if (xhr.readyState === 4) {
-				console.info("COMPLETE")
+		xhr.onreadystatechange = lang.hitch(this, function(){
+			if(xhr.readyState === 4){
+//				console.info("COMPLETE")
 				clearInterval(timer);
-				this.onComplete(dojo.eval(xhr.responseText));
+				this.onComplete(JSON.parse(xhr.responseText.replace(/^\{\}&&/,'')));
 			}
 		});
-        xhr.open("POST", this.getUrl());
+		xhr.open("POST", this.getUrl());
 
-		timer = setInterval(dojo.hitch(this, function(){
+		timer = setInterval(lang.hitch(this, function(){
 			try{
 				if(typeof(xhr.statusText)){} // accessing this error throws an error. Awesomeness.
 			}catch(e){
@@ -159,19 +182,19 @@ dojo.declare("dojox.form.uploader.plugins.HTML5", [], {
 		return xhr;
 	},
 
-	_buildRequestBody : function(data, boundary) {
+	_buildRequestBody : function(data, boundary){
 		var EOL  = "\r\n";
 		var part = "";
 		boundary = "--" + boundary;
 
-		var filesInError = [];
-		dojo.forEach(this.inputNode.files, function(f, i){
+		var filesInError = [], files = this._files;
+		array.forEach(files, function(f, i){
 			var fieldName = this.name+"s[]";//+i;
-			var fileName  = this.inputNode.files[i].fileName;
+			var fileName  = f.fileName;
 			var binary;
 
 			try{
-				binary = this.inputNode.files[i].getAsBinary() + EOL;
+				binary = f.getAsBinary() + EOL;
 				part += boundary + EOL;
 				part += 'Content-Disposition: form-data; ';
 				part += 'name="' + fieldName + '"; ';
@@ -184,7 +207,7 @@ dojo.declare("dojox.form.uploader.plugins.HTML5", [], {
 		}, this);
 
 		if(filesInError.length){
-			if(filesInError.length >= this.inputNode.files.length){
+			if(filesInError.length >= files.length){
 				// all files were bad. Nothing to upload.
 				this.onError({
 					message:this.errMsg,
@@ -211,4 +234,7 @@ dojo.declare("dojox.form.uploader.plugins.HTML5", [], {
 	}
 
 });
-dojox.form.addUploaderPlugin(dojox.form.uploader.plugins.HTML5);
+dojox.form.addUploaderPlugin(pluginsHTML5);
+
+return pluginsHTML5;
+});
diff --git a/dojox/form/uploader/plugins/IFrame.js b/dojox/form/uploader/plugins/IFrame.js
index e26e32e..9937e68 100644
--- a/dojox/form/uploader/plugins/IFrame.js
+++ b/dojox/form/uploader/plugins/IFrame.js
@@ -1,9 +1,14 @@
-dojo.provide("dojox.form.uploader.plugins.IFrame");
+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){
+	
 
-dojo.require("dojox.form.uploader.plugins.HTML5");
-dojo.require("dojo.io.iframe");
-
-dojo.declare("dojox.form.uploader.plugins.IFrame", [], {
+var pluginsIFrame = declare("dojox.form.uploader.plugins.IFrame", [], {
 	//
 	// Version: 1.6
 	//
@@ -12,49 +17,62 @@ dojo.declare("dojox.form.uploader.plugins.IFrame", [], {
 	//
 	//	description:
 	//		Only supported by IE, due to the specifc iFrame hack used. The
-	//		dojox.form.uploader.plugins.HTML5 plugin should be used along with this to add HTML5
+	//		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 dojox.form.uploader.plugins.HTML5.
+	//		Inherits all properties from dojox.form.Uploader and formUploaderPluginsHTML5.
 	//
 
 	force:"",
 
 	postMixInProperties: function(){
 		this.inherited(arguments);
-		if(!this.supports("multiple")){
-			this.uploadType = "iframe";
-		}
-	},
-
-	upload: function(/*Object ? */data){
-		// summary:
-		//		See: dojox.form.Uploader.upload
-		//
 		if(!this.supports("multiple") || this.force =="iframe"){
-			this.uploadIFrame(data);
-			dojo.stopEvent(data);
-			return;
+			this.uploadType = "iframe";
+			this.upload = this.uploadIFrame;
 		}
 	},
 
-	uploadIFrame: function(){
+	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 = dojo.io.iframe.send({
-			url: this.getUrl(),
-			form: this.form,
+
+		var dfd = ioIframe.send({
+			url: url,
+			form: form,
 			handleAs: "json",
-			error: dojo.hitch(this, function(err){
-				console.error("HTML Upload Error:" + err.message);
+			content: data,
+			error: lang.hitch(this, function(err){
+				if(destroyAfter){ domConstruct.destroy(form); }
+				this.onError(err);
 			}),
-			load: dojo.hitch(this, function(data, ioArgs, widgetRef){
-				this.onComplete(data);
+			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(dojox.form.uploader.plugins.IFrame);
+dojox.form.addUploaderPlugin(pluginsIFrame);
+
+return pluginsIFrame;
+});
diff --git a/dojox/fx.js b/dojox/fx.js
index b21b9d8..c3e3863 100644
--- a/dojox/fx.js
+++ b/dojox/fx.js
@@ -1,3 +1,3 @@
-dojo.provide("dojox.fx");
-
-dojo.require("dojox.fx._base");
+define(["./fx/_base"], function(DojoxFx){
+	return DojoxFx;
+});
diff --git a/dojox/fx/Shadow.js b/dojox/fx/Shadow.js
index 0d69f76..2e5cea7 100644
--- a/dojox/fx/Shadow.js
+++ b/dojox/fx/Shadow.js
@@ -1,146 +1,146 @@
-dojo.provide("dojox.fx.Shadow");
-dojo.experimental("dojox.fx.Shadow");
-
-dojo.require("dijit._Widget");
-dojo.require("dojo.NodeList-fx");
-
-dojo.declare("dojox.fx.Shadow",
-	dijit._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
-	shadowPng: dojo.moduleUrl("dojox.fx", "resources/shadow"),
-
-	// shadowThickness: Integer
-	// 	How wide (in px) to make the shadow
-	shadowThickness: 7,
-
-	// shadowOffset: Integer
-	//	How deep to make the shadow appear to be
-	shadowOffset: 3,
-
-	// opacity: Float
-	//	Overall opacity of the shadow
-	opacity: 0.75,
-
-	// animate: Boolean
-	// 	A toggle to disable animated transitions
-	animate: false,
-
-	// node: DomNode
-	// 	The node we will be applying this shadow to
-	node: null,
-
-	startup: function(){
-		// summary: Initializes the shadow.
-
-		this.inherited(arguments);
-		this.node.style.position = "relative";
-		// make all the pieces of the shadow, and position/size them as much
-		// as possible (but a lot of the coordinates are set in sizeShadow
-		this.pieces={};
-		var x1 = -1 * this.shadowThickness;
-		var y0 = this.shadowOffset;
-		var y1 = this.shadowOffset + this.shadowThickness;
-		this._makePiece("tl", "top", y0, "left", x1);
-		this._makePiece("l", "top", y1, "left", x1, "scale");
-		this._makePiece("tr", "top", y0, "left", 0);
-		this._makePiece("r", "top", y1, "left", 0, "scale");
-		this._makePiece("bl", "top", 0, "left", x1);
-		this._makePiece("b", "top", 0, "left", 0, "crop");
-		this._makePiece("br", "top", 0, "left", 0);
-
-		this.nodeList = dojo.query(".shadowPiece",this.node);
-
-		this.setOpacity(this.opacity);
-		this.resize();
-	},
-
-	_makePiece: function(name, vertAttach, vertCoord, horzAttach, horzCoord, sizing){
-		// summary: append a shadow pieces to the node, and position it
-		var img;
-		var url = this.shadowPng + name.toUpperCase() + ".png";
-		if(dojo.isIE < 7){
-			img = dojo.create("div");
-			img.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+url+"'"+
-				(sizing?", sizingMethod='"+sizing+"'":"") + ")";
-		}else{
-			img = dojo.create("img", { src:url });
+define(["dojo/_base/kernel", "dojo/_base/query" ,"dojo/_base/lang", "dojo/_base/declare", "dojo/_base/sniff",
+		"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.
+		//
+		// 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
+		shadowPng: kernel.moduleUrl("dojox.fx", "resources/shadow"),
+	
+		// shadowThickness: Integer
+		// 	How wide (in px) to make the shadow
+		shadowThickness: 7,
+	
+		// shadowOffset: Integer
+		//	How deep to make the shadow appear to be
+		shadowOffset: 3,
+	
+		// opacity: Float
+		//	Overall opacity of the shadow
+		opacity: 0.75,
+	
+		// animate: Boolean
+		// 	A toggle to disable animated transitions
+		animate: false,
+	
+		// node: DomNode
+		// 	The node we will be applying this shadow to
+		node: null,
+	
+		startup: function(){
+			// summary: Initializes the shadow.
+	
+			this.inherited(arguments);
+			this.node.style.position = "relative";
+			// make all the pieces of the shadow, and position/size them as much
+			// as possible (but a lot of the coordinates are set in sizeShadow
+			this.pieces={};
+			var x1 = -1 * this.shadowThickness;
+			var y0 = this.shadowOffset;
+			var y1 = this.shadowOffset + this.shadowThickness;
+			this._makePiece("tl", "top", y0, "left", x1);
+			this._makePiece("l", "top", y1, "left", x1, "scale");
+			this._makePiece("tr", "top", y0, "left", 0);
+			this._makePiece("r", "top", y1, "left", 0, "scale");
+			this._makePiece("bl", "top", 0, "left", x1);
+			this._makePiece("b", "top", 0, "left", 0, "crop");
+			this._makePiece("br", "top", 0, "left", 0);
+	
+			this.nodeList = query(".shadowPiece",this.node);
+	
+			this.setOpacity(this.opacity);
+			this.resize();
+		},
+	
+		_makePiece: function(name, vertAttach, vertCoord, horzAttach, horzCoord, sizing){
+			// summary: append a shadow pieces to the node, and position it
+			var img;
+			var url = this.shadowPng + name.toUpperCase() + ".png";
+			if(has("ie") < 7){
+				img = domConstruct.create("div");
+				img.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+url+"'"+
+					(sizing?", sizingMethod='"+sizing+"'":"") + ")";
+			}else{
+				img = domConstruct.create("img", { src:url });
+			}
+	
+			img.style.position="absolute";
+			img.style[vertAttach]=vertCoord+"px";
+			img.style[horzAttach]=horzCoord+"px";
+			img.style.width=this.shadowThickness+"px";
+			img.style.height=this.shadowThickness+"px";
+			domClass.add(img,"shadowPiece");
+			this.pieces[name]=img;
+			this.node.appendChild(img);
+	
+		},
+	
+		setOpacity: function(/* Float */n,/* Object? */animArgs){
+			// summary: set the opacity of the underlay
+			// note: does not work in IE? FIXME.
+			if(has("ie")){ return; }
+			if(!animArgs){ animArgs = {}; }
+			if(this.animate){
+				var _anims = [];
+				this.nodeList.forEach(function(node){
+					_anims.push(baseFx._fade(lang.mixin(animArgs,{ node: node, end: n })));
+				});
+				coreFx.combine(_anims).play();
+			}else{
+				this.nodeList.style("opacity",n);
+			}
+	
+		},
+	
+		setDisabled: function(/* Boolean */disabled){
+			// summary: enable / disable the shadow
+			if(disabled){
+				if(this.disabled){ return; }
+				if(this.animate){ this.nodeList.fadeOut().play();
+				}else{ this.nodeList.style("visibility","hidden"); }
+				this.disabled = true;
+			}else{
+				if(!this.disabled){ return; }
+				if(this.animate){ this.nodeList.fadeIn().play();
+				}else{ this.nodeList.style("visibility","visible"); }
+				this.disabled = false;
+			}
+		},
+	
+		resize: function(/* dojox.fx._arg.ShadowResizeArgs */args){
+			// summary: Resizes the shadow based on width and height.
+			var x; var y;
+			if(args){ x = args.x; y = args.y;
+			}else{
+				var co = domGeom.position(this.node);
+				x = co.w; y = co.h;
+			}
+			var sideHeight = y - (this.shadowOffset+this.shadowThickness);
+			if (sideHeight < 0) { sideHeight = 0; }
+			if (y < 1) { y = 1; }
+			if (x < 1) { x = 1; }
+			with(this.pieces){
+				l.style.height = sideHeight+"px";
+				r.style.height = sideHeight+"px";
+				b.style.width = x+"px";
+				bl.style.top = y+"px";
+				b.style.top = y+"px";
+				br.style.top = y+"px";
+				tr.style.left = x+"px";
+				r.style.left = x+"px";
+				br.style.left = x+"px";
+			}
 		}
-
-		img.style.position="absolute";
-		img.style[vertAttach]=vertCoord+"px";
-		img.style[horzAttach]=horzCoord+"px";
-		img.style.width=this.shadowThickness+"px";
-		img.style.height=this.shadowThickness+"px";
-		dojo.addClass(img,"shadowPiece");
-		this.pieces[name]=img;
-		this.node.appendChild(img);
-
-	},
-
-	setOpacity: function(/* Float */n,/* Object? */animArgs){
-		// summary: set the opacity of the underlay
-		// note: does not work in IE? FIXME.
-		if(dojo.isIE){ return; }
-		if(!animArgs){ animArgs = {}; }
-		if(this.animate){
-			var _anims = [];
-			this.nodeList.forEach(function(node){
-				_anims.push(dojo._fade(dojo.mixin(animArgs,{ node: node, end: n })));
-			});
-			dojo.fx.combine(_anims).play();
-		}else{
-			this.nodeList.style("opacity",n);
-		}
-
-	},
-
-	setDisabled: function(/* Boolean */disabled){
-		// summary: enable / disable the shadow
-		if(disabled){
-			if(this.disabled){ return; }
-			if(this.animate){ this.nodeList.fadeOut().play();
-			}else{ this.nodeList.style("visibility","hidden"); }
-			this.disabled = true;
-		}else{
-			if(!this.disabled){ return; }
-			if(this.animate){ this.nodeList.fadeIn().play();
-			}else{ this.nodeList.style("visibility","visible"); }
-			this.disabled = false;
-		}
-	},
-
-	resize: function(/* dojox.fx._arg.ShadowResizeArgs */args){
-		// summary: Resizes the shadow based on width and height.
-		var x; var y;
-		if(args){ x = args.x; y = args.y;
-		}else{
-			var co = dojo._getBorderBox(this.node);
-			x = co.w; y = co.h;
-		}
-		var sideHeight = y - (this.shadowOffset+this.shadowThickness);
-		if (sideHeight < 0) { sideHeight = 0; }
-		if (y < 1) { y = 1; }
-		if (x < 1) { x = 1; }
-		with(this.pieces){
-			l.style.height = sideHeight+"px";
-			r.style.height = sideHeight+"px";
-			b.style.width = x+"px";
-			bl.style.top = y+"px";
-			b.style.top = y+"px";
-			br.style.top = y+"px";
-			tr.style.left = x+"px";
-			r.style.left = x+"px";
-			br.style.left = x+"px";
-		}
-	}
+	});
+	return dojox.fx.Shadow;
 });
diff --git a/dojox/fx/Timeline.js b/dojox/fx/Timeline.js
index a06dbe3..2956a46 100644
--- a/dojox/fx/Timeline.js
+++ b/dojox/fx/Timeline.js
@@ -1,7 +1,8 @@
-dojo.provide("dojox.fx.Timeline");
-dojo.require("dojo.fx.easing");
+define(["dojo/_base/lang","dojo/fx/easing","dojo/_base/fx","dojo/dom","./_base","dojo/_base/connect",
+		"dojo/_base/html", "dojo/_base/array","dojo/_base/Color"],
+ function(lang, easingUtil, baseFx, dom, dojoxFx, connectUtil, htmlUtil, arrayUtil, Color){
 
-dojox.fx.animateTimeline = function(/* Object */options, /* DomNode|String */node){
+dojoxFx.animateTimeline = function(/* Object */options, /* DomNode|String */node){
 	// options: Object
 	// 		The paramters passed to the timeline animation. Includes:
 	// 			keys: Array
@@ -53,26 +54,26 @@ dojox.fx.animateTimeline = function(/* Object */options, /* DomNode|String */nod
 	// 		|	];
 	// 		|	ani = dojox.fx.animateTimeline({keys:keys, duration:2000}, "myDiv").play();
 	//
-	var _curve = new dojox.fx._Timeline(options.keys);
-	var ani = dojo.animateProperty({
-		node:dojo.byId(node || options.node),
+	var _curve = new Timeline(options.keys);
+	var ani = baseFx.animateProperty({
+		node:dom.byId(node || options.node),
 		duration:options.duration || 1000,
 		properties:_curve._properties,
 		// don't change! This easing is for the timeline,
 		// not individual properties
-		easing:dojo.fx.easing.linear,
+		easing:easingUtil.linear,
 		onAnimate: function(v){
 			//console.log("   ani:", v);
 		}
 	});
-	dojo.connect(ani, "onEnd", function(node){
+	connectUtil.connect(ani, "onEnd", function(node){
 		// Setting the final style. Hiccups in the browser
 		// can cause the animation to lose track. This ensures
 		// that it finishes in the proper location.
 		var sty = ani.curve.getValue(ani.reversed ? 0 : 1);
-		dojo.style(node, sty);
+		htmlUtil.style(node, sty);
 	});
-	dojo.connect(ani, "beforeBegin", function(){
+	connectUtil.connect(ani, "beforeBegin", function(){
 		// remove default curve and replace it with Timeline
 		if(ani.curve){ delete ani.curve; }
 		ani.curve = _curve;
@@ -81,16 +82,16 @@ dojox.fx.animateTimeline = function(/* Object */options, /* DomNode|String */nod
 	return ani; // dojo.Animation
 }
 
-dojox.fx._Timeline = function(/* Array */keys){
+var Timeline = function(/* Array */keys){
 	// summary:
 	//		The dojox.fx._Timeline object from which an instance
 	//		is created
 	// tags:
 	//		private
-	this.keys = dojo.isArray(keys) ? this.flatten(keys) : keys;
+	this.keys = lang.isArray(keys) ? this.flatten(keys) : keys;
 }
 
-dojox.fx._Timeline.prototype.flatten = function(keys){
+Timeline.prototype.flatten = function(keys){
 	// summary:
 	//		An internally used function that converts the keyframes
 	//		as used in the example above into a series of key values
@@ -104,9 +105,9 @@ dojox.fx._Timeline.prototype.flatten = function(keys){
 		return parseInt(str, 10) * .01
 	}
 	var p = {}, o = {};
-	dojo.forEach(keys, function(k, i){
+	arrayUtil.forEach(keys, function(k, i){
 		var step = getPercent(k.step, i);
-		var ease = dojo.fx.easing[k.ease] || dojo.fx.easing.linear;
+		var ease = easingUtil[k.ease] || easingUtil.linear;
 		
 		for(var nm in k){
 			if(nm == "step" || nm == "ease" || nm == "from" || nm == "to"){ continue; }
@@ -125,11 +126,11 @@ dojox.fx._Timeline.prototype.flatten = function(keys){
 				}
 			}
 			
-			o[nm].eases.push(dojo.fx.easing[k.ease || "linear"]);
+			o[nm].eases.push(easingUtil[k.ease || "linear"]);
 			
 			o[nm].steps.push(step);
 			if(p[nm].units == "isColor"){
-				o[nm].values.push(new dojo.Color(k[nm]));
+				o[nm].values.push(new Color(k[nm]));
 			}else{
 				o[nm].values.push(parseInt(/\d{1,}/.exec(k[nm]).join("")));
 			}
@@ -148,7 +149,7 @@ dojox.fx._Timeline.prototype.flatten = function(keys){
 	
 }
 
-dojox.fx._Timeline.prototype.getValue = function(/*float*/ p){
+Timeline.prototype.getValue = function(/*float*/ p){
 	// summary:
 	//		Replaces the native getValue in dojo.fx.Animation.
 	//		Returns an object with all propeties used in the animation
@@ -186,8 +187,8 @@ dojox.fx._Timeline.prototype.getValue = function(/*float*/ p){
 					var seg = (1 / (ns - step)) * (p - step);
 					seg = ease(seg);
 					
-					if(beg instanceof dojo.Color){
-						o[nm] = dojo.blendColors(beg, end, seg).toCss(false);
+					if(beg instanceof Color){
+						o[nm] = Color.blendColors(beg, end, seg).toCss(false);
 					}else{
 						var df = end - beg;
 						o[nm] = beg + seg * df + this._properties[nm].units;
@@ -206,5 +207,6 @@ dojox.fx._Timeline.prototype.getValue = function(/*float*/ p){
 	}
 	return o; // Object
 };
-
-
+dojoxFx._Timeline = Timeline;
+return dojoxFx;
+});
diff --git a/dojox/fx/_arg.js b/dojox/fx/_arg.js
index 4fab786..021dbcb 100644
--- a/dojox/fx/_arg.js
+++ b/dojox/fx/_arg.js
@@ -1,6 +1,6 @@
-dojo.provide("dojox.fx._arg");
-
-dojox.fx._arg.StyleArgs = function(/*Object*/ args){
+define(["dojo/_base/lang"],function(lang){
+var fxArg = lang.getObject("dojox.fx._arg",true);
+fxArg.StyleArgs = function(/*Object*/ args){
 	// summary:
 	//		The node and CSS class to use for style manipulations.
 	// node: DOMNode
@@ -11,7 +11,7 @@ dojox.fx._arg.StyleArgs = function(/*Object*/ args){
 	this.cssClass = args.cssClass;
 }
 
-dojox.fx._arg.ShadowResizeArgs = function(/*Object*/ args){
+fxArg.ShadowResizeArgs = function(/*Object*/ args){
 	// summary:
 	//	The odd way to document object parameters.
 	// x: Integer
@@ -20,4 +20,6 @@ dojox.fx._arg.ShadowResizeArgs = function(/*Object*/ args){
 	//	the height to set
 	this.x = args.x;
 	this.y = args.y;
-}
\ No newline at end of file
+}
+return fxArg;
+});
\ No newline at end of file
diff --git a/dojox/fx/_base.js b/dojox/fx/_base.js
index d28ee6d..75c4d2b 100644
--- a/dojox/fx/_base.js
+++ b/dojox/fx/_base.js
@@ -1,17 +1,19 @@
-dojo.provide("dojox.fx._base");
+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.
-dojo.require("dojo.fx");
-
-dojo.mixin(dojox.fx, {
+var dojoxFx = lang.getObject("dojox.fx", true);
+/*
+lang.mixin(dojox.fx, {
 
 	// anim: Function
 	//	Alias of `dojo.anim` - the shorthand `dojo.animateProperty` with auto-play
-	anim: dojo.anim,
+	anim: dojo.fx.anim,
 
 	// animateProperty: Function
 	//	Alias of `dojo.animateProperty` - animate any CSS property
-	animateProperty: dojo.animateProperty,
+	animateProperty: dojox.fx.animateProperty,
 
 	// fadeTo: Function
 	//		Fade an element from an opacity to an opacity.
@@ -48,8 +50,9 @@ dojo.mixin(dojox.fx, {
 	wipeOut: dojo.fx.wipeOut
 
 });
+*/
 
-dojox.fx.sizeTo = function(/* Object */args){
+dojoxFx.sizeTo = function(/* Object */args){
 	// summary:
 	//		Creates an animation that will size a node
 	//
@@ -73,7 +76,7 @@ dojox.fx.sizeTo = function(/* Object */args){
 	//	|	}).play();
 	//
 
-	var node = args.node = dojo.byId(args.node),
+	var node = args.node = dom.byId(args.node),
 		abs = "absolute";
 
 	var method = args.method || "chain";
@@ -84,7 +87,7 @@ dojox.fx.sizeTo = function(/* Object */args){
 
 	var init = (function(n){
 		return function(){
-			var cs = dojo.getComputedStyle(n),
+			var cs = domStyle.getComputedStyle(n),
 				pos = cs.position,
 				w = cs.width,
 				h = cs.height
@@ -99,7 +102,7 @@ dojox.fx.sizeTo = function(/* Object */args){
 			newTop = top - Math.floor((args.height - height) / 2);
 
 			if(pos != abs && pos != 'relative'){
-				var ret = dojo.coords(n, true);
+				var ret = domStyle.coords(n, true);
 				top = ret.y;
 				left = ret.x;
 				n.style.position = abs;
@@ -109,7 +112,7 @@ dojox.fx.sizeTo = function(/* Object */args){
 		}
 	})(node);
 
-	var anim1 = dojo.animateProperty(dojo.mixin({
+	var anim1 = baseFx.animateProperty(lang.mixin({
 		properties: {
 			height: function(){
 				init();
@@ -120,7 +123,7 @@ dojox.fx.sizeTo = function(/* Object */args){
 			}
 		}
 	}, args));
-	var anim2 = dojo.animateProperty(dojo.mixin({
+	var anim2 = baseFx.animateProperty(lang.mixin({
 		properties: {
 			width: function(){
 				return { start: width, end: args.width || 0 }
@@ -131,12 +134,12 @@ dojox.fx.sizeTo = function(/* Object */args){
 		}
 	}, args));
 
-	var anim = dojo.fx[(args.method == "combine" ? "combine" : "chain")]([anim1, anim2]);
+	var anim = coreFx[(args.method == "combine" ? "combine" : "chain")]([anim1, anim2]);
 	return anim; // dojo.Animation
 
 };
 
-dojox.fx.slideBy = function(/* Object */args){
+dojoxFx.slideBy = function(/* Object */args){
 	// summary:
 	//		Returns an animation to slide a node by a defined offset.
 	//
@@ -152,17 +155,17 @@ dojox.fx.slideBy = function(/* Object */args){
 	//	|		top: 50, left: -22
 	//	|	}).play();
 
-	var node = args.node = dojo.byId(args.node),
+	var node = args.node = dom.byId(args.node),
 		top, left;
 
 	var init = (function(n){
 		return function(){
-			var cs = dojo.getComputedStyle(n);
+			var cs = domStyle.getComputedStyle(n);
 			var pos = cs.position;
 			top = (pos == 'absolute' ? n.offsetTop : parseInt(cs.top) || 0);
 			left = (pos == 'absolute' ? n.offsetLeft : parseInt(cs.left) || 0);
 			if(pos != 'absolute' && pos != 'relative'){
-				var ret = dojo.coords(n, true);
+				var ret = domGeom.coords(n, true);
 				top = ret.y;
 				left = ret.x;
 				n.style.position = "absolute";
@@ -173,7 +176,7 @@ dojox.fx.slideBy = function(/* Object */args){
 	})(node);
 	init();
 	
-	var _anim = dojo.animateProperty(dojo.mixin({
+	var _anim = baseFx.animateProperty(lang.mixin({
 		properties: {
 			// FIXME: is there a way to update the _Line after creation?
 			// null start values allow chaining to work, animateProperty will
@@ -182,11 +185,11 @@ dojox.fx.slideBy = function(/* Object */args){
 			left: left + (args.left || 0)
 		}
 	}, args));
-	dojo.connect(_anim, "beforeBegin", _anim, init);
+	connectUtil.connect(_anim, "beforeBegin", _anim, init);
 	return _anim; // dojo.Animation
 };
 
-dojox.fx.crossFade = function(/* Object */args){
+dojoxFx.crossFade = function(/* Object */args){
 	// summary:
 	//		Returns an animation cross fading two element simultaneously
 	//
@@ -197,24 +200,24 @@ dojox.fx.crossFade = function(/* Object */args){
 	//
 
 	// simple check for which node is visible, maybe too simple?
-	var node1 = args.nodes[0] = dojo.byId(args.nodes[0]),
-		op1 = dojo.style(node1,"opacity"),
-		node2 = args.nodes[1] = dojo.byId(args.nodes[1]),
-		op2 = dojo.style(node2, "opacity")
+	var node1 = args.nodes[0] = dom.byId(args.nodes[0]),
+		op1 = htmlUtil.style(node1,"opacity"),
+		node2 = args.nodes[1] = dom.byId(args.nodes[1]),
+		op2 = htmlUtil.style(node2, "opacity")
 	;
 	
-	var _anim = dojo.fx.combine([
-		dojo[(op1 == 0 ? "fadeIn" : "fadeOut")](dojo.mixin({
+	var _anim = coreFx.combine([
+		baseFx[(op1 == 0 ? "fadeIn" : "fadeOut")](lang.mixin({
 			node: node1
 		},args)),
-		dojo[(op1 == 0 ? "fadeOut" : "fadeIn")](dojo.mixin({
+		baseFx[(op1 == 0 ? "fadeOut" : "fadeIn")](lang.mixin({
 			node: node2
 		},args))
 	]);
 	return _anim; // dojo.Animation
 };
 
-dojox.fx.highlight = function(/*Object*/ args){
+dojoxFx.highlight = function(/*Object*/ args){
 	// summary:
 	//		Highlight a node
 	//
@@ -225,13 +228,13 @@ dojox.fx.highlight = function(/*Object*/ args){
 	// example:
 	//	|	dojox.fx.highlight({ node:"foo" }).play();
 
-	var node = args.node = dojo.byId(args.node);
+	var node = args.node = dom.byId(args.node);
 
 	args.duration = args.duration || 400;
 	
 	// Assign default color light yellow
 	var startColor = args.color || '#ffff99',
-		endColor = dojo.style(node, "backgroundColor")
+		endColor = htmlUtil.style(node, "backgroundColor")
 	;
 
 	// safari "fix"
@@ -244,14 +247,14 @@ dojox.fx.highlight = function(/*Object*/ args){
 		endColor = "transparent";
 	}
 
-	var anim = dojo.animateProperty(dojo.mixin({
+	var anim = baseFx.animateProperty(lang.mixin({
 		properties: {
 			backgroundColor: { start: startColor, end: endColor }
 		}
 	}, args));
 
 	if(endColor == "transparent"){
-		dojo.connect(anim, "onEnd", anim, function(){
+		connectUtil.connect(anim, "onEnd", anim, function(){
 			node.style.backgroundColor = endColor;
 		});
 	}
@@ -260,7 +263,7 @@ dojox.fx.highlight = function(/*Object*/ args){
 };
 
  
-dojox.fx.wipeTo = function(/*Object*/ args){
+dojoxFx.wipeTo = function(/*Object*/ args){
 	// summary:
 	//		Animate a node wiping to a specific width or height
 	//
@@ -281,7 +284,7 @@ dojox.fx.wipeTo = function(/*Object*/ args){
 	//		Node must have no margin/border/padding, so put another
 	//		node inside your target node for additional styling.
 
-	args.node = dojo.byId(args.node);
+	args.node = dom.byId(args.node);
 	var node = args.node, s = node.style;
 
 	var dir = (args.width ? "width" : "height"),
@@ -301,13 +304,16 @@ dojox.fx.wipeTo = function(/*Object*/ args){
 				s.visibility = "";
 				return 1;
 			}else{
-				var now = dojo.style(node,dir);
+				var now = htmlUtil.style(node,dir);
 				return Math.max(now, 1);
 			}
 		},
 		end: endVal
 	};
 
-	var anim = dojo.animateProperty(dojo.mixin({ properties: props }, args));
+	var anim = baseFx.animateProperty(lang.mixin({ properties: props }, args));
 	return anim; // dojo.Animation
 };
+
+return dojoxFx;
+});
diff --git a/dojox/fx/_core.js b/dojox/fx/_core.js
index 96dc201..8224868 100644
--- a/dojox/fx/_core.js
+++ b/dojox/fx/_core.js
@@ -1,58 +1,62 @@
-dojo.provide("dojox.fx._core");
-
-dojox.fx._Line = function(start, end){
-	// summary: a custom _Line to accomodate 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.
-	//
-	// start: Integer|Array
-	//	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
-	//
-	// 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 = dojo.isArray(start),
-		d = (isArray ? [] : end - start);
-	
-	if(isArray){
-		// multi-dimensional branch
-		dojo.forEach(this.start, function(s, i){
-			d[i] = this.end[i] - s;
-		}, this);
+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
+		//
+		// 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.
+		//
+		// start: Integer|Array
+		//	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
+		//
+		// 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;
 		
-		this.getValue = function(/*float*/ n){
-			var res = [];
-			dojo.forEach(this.start, function(s, i){
-				res[i] = (d[i] * n) + s;
+		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);
-			return res; // Array
-		}
-	}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
-			// returns: Mixed
-			return (d * n) + this.start; // Decimal
+			
+			this.getValue = function(/*float*/ n){
+				var res = [];
+				arrayUtil.forEach(this.start, function(s, i){
+					res[i] = (d[i] * n) + s;
+				}, this);
+				return res; // Array
+			}
+		}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
+				// returns: Mixed
+				return (d * n) + this.start; // Decimal
+			}
 		}
-	}
-};
+	};
+	dojoxFx._Line = line; // COMPAT
+	return line;
+});
diff --git a/dojox/fx/easing.js b/dojox/fx/easing.js
index 34deb86..44c665c 100644
--- a/dojox/fx/easing.js
+++ b/dojox/fx/easing.js
@@ -1,10 +1,13 @@
-dojo.provide("dojox.fx.easing");
-dojo.deprecated("dojox.fx.easing","Upgraded to Core, use dojo.fx.easing instead","2.0");
-dojo.require("dojo.fx.easing");
+define(["dojo/_base/lang", "dojo/_base/kernel", "dojo/fx/easing"],
+  function(lang,kernel,easing){
+	kernel.deprecated("dojox.fx.easing","Upgraded to Core, use dojo.fx.easing instead","2.0");
+	var fxExt = lang.getObject("dojox.fx",true);
+	fxExt.easing = easing;
 /*=====
 	dojox.fx.easing = {
 		// summary:
 		//		An Alias to `dojo.fx.easing`. Moved to Core in Dojo 1.2.
 	};
 =====*/
-dojox.fx.easing = dojo.fx.easing;
+	return easing;
+});
diff --git a/dojox/fx/ext-dojo/NodeList-style.js b/dojox/fx/ext-dojo/NodeList-style.js
index d5ebb6c..29190d9 100644
--- a/dojox/fx/ext-dojo/NodeList-style.js
+++ b/dojox/fx/ext-dojo/NodeList-style.js
@@ -1,17 +1,15 @@
-dojo.provide("dojox.fx.ext-dojo.NodeList-style");
-dojo.experimental("dojox.fx.ext-dojo.NodeList-style");
+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 addtional fx to `dojo.NodeList-fx`
+//		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
 
-dojo.require("dojo.NodeList-fx");
-dojo.require("dojox.fx.style");
 
-dojo.extend(dojo.NodeList, {
+lang.extend( NodeList, {
 
 	addClassFx: function(cssClass, args){
 		// 	summary:
@@ -24,8 +22,8 @@ dojo.extend(dojo.NodeList, {
 		//	|	// fade all elements with class "bar" to to 50% opacity
 		//	|	dojo.query(".bar").addClassFx("bar").play();
 
-		return dojo.fx.combine(this.map(function(n){ // dojo.Animation
-			return dojox.fx.addClass(n, cssClass, args);
+		return coreFx.combine(this.map(function(n){ // dojo.Animation
+			return styleX.addClass(n, cssClass, args);
 		}));
 	},
 	
@@ -39,8 +37,8 @@ dojo.extend(dojo.NodeList, {
 		// example:
 		//	| dojo.query(".box").removeClassFx("bar").play();
 
-		return dojo.fx.combine(this.map(function(n){ // dojo.Animation
-			return dojox.fx.removeClass(n, cssClass, args);
+		return coreFx.combine(this.map(function(n){ // dojo.Animation
+			return styleX.removeClass(n, cssClass, args);
 		}));
 	},
 	
@@ -54,9 +52,10 @@ dojo.extend(dojo.NodeList, {
 		// example:
 		//	| dojo.query(".box").toggleClass("bar").play();
 
-		return dojo.fx.combine(this.map(function(n){ // dojo.Animation
-			return dojox.fx.toggleClass(n, cssClass, force, args);
+		return coreFx.combine(this.map(function(n){ // dojo.Animation
+			return styleX.toggleClass(n, cssClass, force, args);
 		}));
 	}
-
+});
+return NodeList;
 });
diff --git a/dojox/fx/ext-dojo/NodeList.js b/dojox/fx/ext-dojo/NodeList.js
index 13864c6..ff27eb7 100644
--- a/dojox/fx/ext-dojo/NodeList.js
+++ b/dojox/fx/ext-dojo/NodeList.js
@@ -1,14 +1,12 @@
-dojo.provide("dojox.fx.ext-dojo.NodeList");
-dojo.experimental("dojox.fx.ext-dojo.NodeList");
+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
 
-dojo.require("dojo.NodeList-fx");
-dojo.require("dojox.fx");
-
-dojo.extend(dojo.NodeList, {
+lang.extend(NodeList, {
 
 	sizeTo: function(args){
 		//	summary:
@@ -19,7 +17,7 @@ dojo.extend(dojo.NodeList, {
 		//	|		width:50,
 		//	|		height:50
 		//	|	}).play();
-		return this._anim(dojox.fx, "sizeTo", args); // dojo.Animation
+		return this._anim(CoreFx, "sizeTo", args); // dojo.Animation
 	},
 
 	slideBy: function(args){
@@ -29,7 +27,7 @@ dojo.extend(dojo.NodeList, {
 		//	example:
 		//	|	// slide all tables with class "blah" 10 px
 		//	|	dojo.query("table.blah").slideBy({ top:10, left:10 }).play();
-		return this._anim(dojox.fx, "slideBy", args); // dojo.Animation
+		return this._anim(CoreFx, "slideBy", args); // dojo.Animation
 	},
 
 	highlight: function(args){
@@ -39,7 +37,7 @@ dojo.extend(dojo.NodeList, {
 		//	example:
 		//	|	// highlight all links with class "foo"
 		//	|	dojo.query("a.foo").hightlight().play();
-		return this._anim(dojox.fx, "highlight", args); // dojo.Animation
+		return this._anim(CoreFx, "highlight", args); // dojo.Animation
 	},
 
 	fadeTo: function(args){
@@ -48,7 +46,7 @@ dojo.extend(dojo.NodeList, {
 		//	example:
 		//	|	// fade all elements with class "bar" to to 50% opacity
 		//	|	dojo.query(".bar").fadeTo({ end: 0.5 }).play();
-		return this._anim(dojo,"_fade",args);
+		return this._anim(baseFx,"_fade",args);
 	},
 	
 	wipeTo: function(args){
@@ -56,7 +54,9 @@ dojo.extend(dojo.NodeList, {
 		//		Wipe all elements of the NodeList to a specified width: or height:
 		// example:
 		//	| dojo.query(".box").wipeTo({ width: 300px }).play();
-		return this._anim(dojox.fx, "wipeTo", args);
+		return this._anim(CoreFx, "wipeTo", args);
 	}
 
 });
+return NodeList;
+});
diff --git a/dojox/fx/ext-dojo/complex.js b/dojox/fx/ext-dojo/complex.js
index f804dad..b529624 100644
--- a/dojox/fx/ext-dojo/complex.js
+++ b/dojox/fx/ext-dojo/complex.js
@@ -1,8 +1,10 @@
-dojo.provide("dojox.fx.ext-dojo.complex");
-
-(function(){
-	var da = dojo.animateProperty;
-	dojo.animateProperty = function(options){
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/connect", 
+	"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);
+	
+	var da = baseFx.animateProperty;
+	dojo.animateProperty = baseFx.animateProperty = function(options){
 		// summary:
 		//		An extension of dojo.animateProperty which adds functionality
 		//		that animates a "complex property". The primary example is the
@@ -29,8 +31,8 @@ dojo.provide("dojox.fx.ext-dojo.complex");
 		//
 		var d = dojo;
 		var ani = da(options);
-		
-		dojo.connect(ani, "beforeBegin", function(){
+
+		connectUtil.connect(ani, "beforeBegin", function(){
 			// dojo.Animate original still invokes and still
 			// works. We're appending this functionality to
 			// modify targeted properties.
@@ -52,7 +54,7 @@ dojo.provide("dojox.fx.ext-dojo.complex");
 				}
 				return ret;
 			};
-			
+
 			// this.properties has already been set, as has this.curve._properties.
 			// We're fixing the props in curve which will have NaN attributes from
 			// our string property.
@@ -63,107 +65,105 @@ dojo.provide("dojox.fx.ext-dojo.complex");
 					this.curve._properties[p].start = new dojox.fx._Complex(o);
 				}
 			}
-		
+
 		});
 		return ani; // dojo.Animation
 	}
-})();
 
-dojo.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()
-	//		that will return a string with the modified units.
-	//
-	PROP: /\([+-]?[\w|,|#|\.|\s]*\)/g,
-	constructor: function(options){
-		var beg = options.start.match(this.PROP);
-		var end = options.end.match(this.PROP);
+	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()
+		//		that will return a string with the modified units.
+		//
+		PROP: /\([\w|,|+|\-|#|\.|\s]*\)/g,
+		constructor: function(options){
+			var beg = options.start.match(this.PROP);
+			var end = options.end.match(this.PROP);
 
-		var begProps = dojo.map(beg, this.getProps, this);
-		var endProps = dojo.map(end, this.getProps, this);
+			var begProps = arrayUtil.map(beg, this.getProps, this);
+			var endProps = arrayUtil.map(end, this.getProps, this);
 
-		this._properties = {};
-		this.strProp = options.start;
-		dojo.forEach(begProps, function(prop, i){
-			dojo.forEach(prop, function(p, j){
-				this.strProp = this.strProp.replace(p, "PROP_"+i+""+j);
-				this._properties["PROP_"+i+""+j] = this.makePropObject(p, endProps[i][j])
+			this._properties = {};
+			this.strProp = options.start;
+			arrayUtil.forEach(begProps, function(prop, i){
+				arrayUtil.forEach(prop, function(p, j){
+					this.strProp = this.strProp.replace(p, "PROP_"+i+""+j);
+					this._properties["PROP_"+i+""+j] = this.makePropObject(p, endProps[i][j])
+				},this);
 			},this);
-		},this);
-	},
+		},
 
-	getValue: function(/*Float*/r){
-		// summary:
-		// 		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];
-			if(o.units == "isColor"){
-				v = dojo.blendColors(o.beg, o.end, r).toCss(false);
-				u = "";
-			}else{
-				v = ((o.end - o.beg) * r) + o.beg;
-				u = o.units;
+		getValue: function(/*Float*/r){
+			// summary:
+			// 		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];
+				if(o.units == "isColor"){
+					v = Color.blendColors(o.beg, o.end, r).toCss(false);
+					u = "";
+				}else{
+					v = ((o.end - o.beg) * r) + o.beg;
+					u = o.units;
+				}
+				str = str.replace(nm, v + u);
 			}
-			str = str.replace(nm, v + u);
-		}
-		
-		return str; // String
-	},
-	
-	makePropObject: function(/* String */beg, /* String */end){
-		// 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 {
-			beg:b.num,
-			end:e.num,
-			units:b.units
-		}; // Object
-	},
-	
-	getProps: function(/* String */str){
-		// 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)){
-			str = str.replace(/\s/g, "");
-			s = str.split(",");
-		}else{
-			str = str.replace(/\s{2,}/g, " ");
-			s = str.split(" ");
-		}
-		return s; // String
-	},
-	getNumAndUnits: function(prop){
-		// summary:
-		//		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 str; // String
+		},
+
+		makePropObject: function(/* String */beg, /* String */end){
+			// 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 {
-				num: new dojo.Color(prop),
-				units:"isColor"
+				beg:b.num,
+				end:e.num,
+				units:b.units
 			}; // Object
+		},
+
+		getProps: function(/* String */str){
+			// 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)){
+				str = str.replace(/\s/g, "");
+				s = str.split(",");
+			}else{
+				str = str.replace(/\s{2,}/g, " ");
+				s = str.split(" ");
+			}
+			return s; // String
+		},
+		getNumAndUnits: function(prop){
+			// summary:
+			//		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 {
+					num: new Color(prop),
+					units:"isColor"
+				}; // Object
+			}
+			var o = {
+				num:parseFloat(/-*[\d\.\d|\d]{1,}/.exec(prop).join(""))
+			};
+			o.units = /[a-z]{1,}/.exec(prop);//.join("");
+			o.units = o.units && o.units.length ? o.units.join("") : "";
+			return o; // Object
 		}
-		var o = {
-			num:parseFloat(/-*[\d\.\d|\d]{1,}/.exec(prop).join(""))
-		};
-		o.units = /[a-z]{1,}/.exec(prop);//.join("");
-		o.units = o.units && o.units.length ? o.units.join("") : "";
-		return o; // Object
-	}
+	});
 });
-
-
diff --git a/dojox/fx/ext-dojo/reverse.js b/dojox/fx/ext-dojo/reverse.js
index 5a856c7..413d59e 100644
--- a/dojox/fx/ext-dojo/reverse.js
+++ b/dojox/fx/ext-dojo/reverse.js
@@ -1,9 +1,11 @@
-dojo.provide("dojox.fx.ext-dojo.reverse");
-dojo.require("dojo.fx.easing");
-dojo.require("dojo.fx");
-
-			
-dojo.extend(dojo.Animation, {
+define(["dojo/_base/fx",
+		"dojo/fx",
+		"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:
@@ -57,7 +59,7 @@ dojo.extend(dojo.Animation, {
 					this.rEase = reverseEase;
 				}else{
 					// loop through dojo.fx.easing to find the matching ease
-					var de = dojo.fx.easing, found, eName;
+					var de = easingUtil, found, eName;
 					for(nm in de){
 						if(this.easing == de[nm]){
 							// get ease's name
@@ -75,7 +77,7 @@ dojo.extend(dojo.Animation, {
 							eName = nm.replace("Out", "In");
 						}
 						if(eName){
-							this.rEase = dojo.fx.easing[eName];
+							this.rEase = easingUtil[eName];
 						}
 					}else{
 						// default ease, and other's like linear do not have an opposite
@@ -95,4 +97,7 @@ dojo.extend(dojo.Animation, {
 		
 		return this;
 	}
+};
+lang.extend( baseFx.Animation, reverseApi);
+return baseFx.Animation;
 });
\ No newline at end of file
diff --git a/dojox/fx/flip.js b/dojox/fx/flip.js
index ba3abc4..305df99 100644
--- a/dojox/fx/flip.js
+++ b/dojox/fx/flip.js
@@ -1,6 +1,21 @@
-define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/html",
+	"dojo/dom",
+	"dojo/dom-construct",
+	"dojo/dom-geometry",
+	"dojo/_base/connect",
+	"dojo/_base/Color",
+	"dojo/_base/sniff",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/_base/fx",
+	"dojo/fx",
+	"./_base"
+], function(kernel, htmlUtil, dom, domConstruct, domGeom, connectUtil, Color, has, lang, winUtil, baseFx, coreFx, fxExt) {
+//kernel,lang->(sniff,array,has),sniff,unload,window
 
-	dojo.experimental("dojox.fx.flip");
+	kernel.experimental("dojox.fx.flip");
 	// because ShrinkSafe will eat this up:
 	var borderConst = "border",
 		widthConst = "Width",
@@ -11,7 +26,7 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 		bottomConst = "Bottom"
 	;
 
-	dojox.fx.flip = function(/*Object*/ args){
+	fxExt.flip = function(/*Object*/ args){
 		// summary: Animate a node flipping following a specific direction
 		//
 		// description:
@@ -26,24 +41,24 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 		//		darkColor: the darkest color reached during the animation
 		//		lightColor: the brightest color
 		//		endColor: the final backgroundColor for the node
-        //
-        //		depth: Float
+		//
+		//		depth: Float
 		//			 0 <= depth <= 1 overrides the computed "depth"
-        //          (0: min distorsion, 1: max distorsion)
-        //
-        //      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
+		//			(0: min distorsion, 1: max distorsion)
+		//
+		//		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:
 		//	|	var anim = dojox.fx.flip({
@@ -57,15 +72,15 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 		//	|		duration:300
 		//	|	  });
 
-		var helperNode = dojo.create("div"),
-			node = args.node = dojo.byId(args.node),
+		var helperNode = domConstruct.create("div"),
+			node = args.node = dom.byId(args.node),
 			s = node.style,
 			dims = null,
 			hs = null,
 			pn = null,
 			lightColor = args.lightColor || "#dddddd",
 			darkColor = args.darkColor || "#555555",
-			bgColor = dojo.style(node, "backgroundColor"),
+			bgColor = htmlUtil.style(node, "backgroundColor"),
 			endColor = args.endColor || bgColor,
 			staticProps = {},
 			anims = [],
@@ -79,10 +94,10 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 		;
 		// IE6 workaround: IE6 doesn't support transparent borders
 		var convertColor = function(color){
-			return ((new dojo.Color(color)).toHex() === "#000000") ? "#000001" : color;
+			return ((new Color(color)).toHex() === "#000000") ? "#000001" : color;
 		};
 
-		if(dojo.isIE < 7){
+		if(has("ie") < 7){
 			endColor = convertColor(endColor);
 			lightColor = convertColor(lightColor);
 			darkColor = convertColor(darkColor);
@@ -93,7 +108,7 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 
 		var init = (function(n){
 			return function(){
-				var ret = dojo.coords(n, true);
+				var ret = htmlUtil.coords(n, true);
 				dims = {
 					top: ret.y,
 					left: ret.x,
@@ -164,7 +179,7 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 		p0[borderConst + pn[1] + widthConst] = 0;
 		p0[borderConst + pn[1] + "Color"] = darkColor;
 		p0[borderConst + pn[2] + widthConst] = p0[borderConst + pn[3] + widthConst] = axis != "cube"
-			? (dims["end" + pn[5] +  "Max"] - dims["end" + pn[5] + "Min"]) / 2
+			? (dims["end" + pn[5] +	 "Max"] - dims["end" + pn[5] + "Min"]) / 2
 			: dims[pn[6]] / 2
 		;
 		p0[pn[7].toLowerCase()] = dims[pn[7].toLowerCase()] + dims[pn[4].toLowerCase()] / 2 + (args.shift || 0);
@@ -177,13 +192,13 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 		p1[borderConst + pn[3] + widthConst] = 0;
 		p1[pn[5].toLowerCase()] = { start: dims[pn[6]], end: dims[pn[5].toLowerCase()] };
 
-		dojo.mixin(hs, staticProps);
-		dojo.style(helperNode, hs);
-		dojo.body().appendChild(helperNode);
+		lang.mixin(hs, staticProps);
+		htmlUtil.style(helperNode, hs);
+		winUtil.body().appendChild(helperNode);
 
 		var finalize = function(){
 //			helperNode.parentNode.removeChild(helperNode);
-			dojo.destroy(helperNode);
+			domConstruct.destroy(helperNode);
 			// fixes a flicker when the animation ends
 			s.backgroundColor = endColor;
 			s.visibility = "visible";
@@ -196,14 +211,14 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 			p1 = p0;
 		}
 		if(!whichAnim || whichAnim == "first"){
-			anims.push(dojo.animateProperty({
+			anims.push(baseFx.animateProperty({
 				node: helperNode,
 				duration: duration,
 				properties: p0
 			}));
 		}
 		if(!whichAnim || whichAnim == "last"){
-			anims.push(dojo.animateProperty({
+			anims.push(baseFx.animateProperty({
 				node: helperNode,
 				duration: duration,
 				properties: p1,
@@ -212,16 +227,16 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 		}
 
 		// hide the original node
-		dojo.connect(anims[0], "play", function(){
+		connectUtil.connect(anims[0], "play", function(){
 			helperNode.style.visibility = "visible";
 			s.visibility = "hidden";
 		});
 
-		return dojo.fx.chain(anims); // dojo.Animation
+		return coreFx.chain(anims); // dojo.Animation
 
 	}
 
-	dojox.fx.flipCube = function(/*Object*/ args){
+	fxExt.flipCube = function(/*Object*/ args){
 		// summary: An extension to `dojox.fx.flip` providing a more 3d-like rotation
 		//
 		// description:
@@ -232,7 +247,7 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 		//	example:
 		//		See `dojox.fx.flip`
 		var anims = [],
-			mb = dojo.marginBox(args.node),
+			mb = domGeom.getMarginBox(args.node),
 			shiftX = mb.w / 2,
 			shiftY = mb.h / 2,
 			dims = {
@@ -305,13 +320,13 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 		args.depth = .8;
 		args.axis = "cube";
 		for(var i = p.length - 1; i >= 0; i--){
-			dojo.mixin(args, p[i]);
-			anims.push(dojox.fx.flip(args));
+			lang.mixin(args, p[i]);
+			anims.push(fxExt.flip(args));
 		}
-		return dojo.fx.combine(anims);
+		return coreFx.combine(anims);
 	};
 	
-	dojox.fx.flipPage = function(/*Object*/ args){
+	fxExt.flipPage = function(/*Object*/ args){
 		// summary: An extension to `dojox.fx.flip` providing a page flip like animation.
 		//
 		// description:
@@ -322,15 +337,15 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 		//	example:
 		//		See `dojox.fx.flip`
 		var n = args.node,
-			coords = dojo.coords(n, true),
+			coords = htmlUtil.coords(n, true),
 			x = coords.x,
 			y = coords.y,
 			w = coords.w,
 			h = coords.h,
-			bgColor = dojo.style(n, "backgroundColor"),
+			bgColor = htmlUtil.style(n, "backgroundColor"),
 			lightColor = args.lightColor || "#dddddd",
 			darkColor = args.darkColor,
-			helperNode = dojo.create("div"),
+			helperNode = domConstruct.create("div"),
 			anims = [],
 			hn = [],
 			dir = args.dir || "right",
@@ -347,11 +362,11 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 				bottom: [1, -1]
 			}
 		;
-		dojo.style(helperNode, {
+		htmlUtil.style(helperNode, {
 			position: "absolute",
 			width  : w + "px",
 			height : h + "px",
-			top    : y + "px",
+			top	   : y + "px",
 			left   : x + "px",
 			visibility: "hidden"
 		});
@@ -363,39 +378,39 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 				endColor = r ? bgColor : lightColor,
 				startColor = r ? endColor : args.startColor || n.style.backgroundColor
 			;
-			hn[i] = dojo.clone(helperNode);
-			var	finalize = function(x){
+			hn[i] = lang.clone(helperNode);
+			var finalize = function(x){
 					return function(){
-						dojo.destroy(hn[x]);
+						domConstruct.destroy(hn[x]);
 					}
 				}(i)
 			;
-			dojo.body().appendChild(hn[i]);
+			winUtil.body().appendChild(hn[i]);
 			hs[i] = {
 				backgroundColor: r ? startColor : bgColor
 			};
 			
 			hs[i][pn[dir][0]] = coords[pn[dir][2]] + shiftMultiplier[dir][0] * i * coords[pn[dir][3]] + "px";
-			dojo.style(hn[i], hs[i]);
+			htmlUtil.style(hn[i], hs[i]);
 			anims.push(dojox.fx.flip({
-			    node: hn[i],
-			    dir: d,
-			    axis: "shortside",
-			    depth: args.depth,
-			    duration: args.duration / 2,
-			    shift: shiftMultiplier[dir][i] * coords[pn[dir][3]] / 2,
+				node: hn[i],
+				dir: d,
+				axis: "shortside",
+				depth: args.depth,
+				duration: args.duration / 2,
+				shift: shiftMultiplier[dir][i] * coords[pn[dir][3]] / 2,
 				darkColor: darkColor,
 				lightColor: lightColor,
-			    whichAnim: wa,
-			    endColor: endColor
+				whichAnim: wa,
+				endColor: endColor
 			}));
-			dojo.connect(anims[i], "onEnd", finalize);
+			connectUtil.connect(anims[i], "onEnd", finalize);
 		}
-		return dojo.fx.chain(anims);
+		return coreFx.chain(anims);
 	};
 	
 	
-	dojox.fx.flipGrid = function(/*Object*/ args){
+	fxExt.flipGrid = function(/*Object*/ args){
 		// summary: An extension to `dojox.fx.flip` providing a decomposition in rows * cols flipping elements
 		//
 		// description:
@@ -403,19 +418,19 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 		//		Behaves the same as `dojox.fx.flip`, using the same attributes and
 		//		other standard `dojo.Animation` properties and
 		//
-        //      cols: Integer columns
-        //      rows: Integer rows
+		//		cols: Integer columns
+		//		rows: Integer rows
 		//
-		//      duration: the single flip duration
+		//		duration: the single flip duration
 		//
 		//	example:
 		//		See `dojox.fx.flip`
 		var rows = args.rows || 4,
 			cols = args.cols || 4,
 			anims = [],
-			helperNode = dojo.create("div"),
+			helperNode = domConstruct.create("div"),
 			n = args.node,
-			coords = dojo.coords(n, true),
+			coords = htmlUtil.coords(n, true),
 			x = coords.x,
 			y = coords.y,
 			nw = coords.w,
@@ -424,11 +439,11 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 			h = coords.h / rows,
 			cAnims = []
 		;
-		dojo.style(helperNode, {
+		htmlUtil.style(helperNode, {
 			position: "absolute",
 			width: w + "px",
 			height: h + "px",
-			backgroundColor: dojo.style(n, "backgroundColor")
+			backgroundColor: htmlUtil.style(n, "backgroundColor")
 		});
 		for(var i = 0; i < rows; i++){
 			var r = i % 2,
@@ -436,8 +451,8 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 				signum = r ? 1 : -1
 			;
 			// cloning
-			var cn = dojo.clone(n);
-			dojo.style(cn, {
+			var cn = lang.clone(n);
+			htmlUtil.style(cn, {
 				position: "absolute",
 				width: nw + "px",
 				height: nh + "px",
@@ -445,31 +460,31 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 				left: x + "px",
 				clip: "rect(" + i * h + "px," + nw + "px," + nh + "px,0)"
 			});
-	     	dojo.body().appendChild(cn);
+			winUtil.body().appendChild(cn);
 			anims[i] = [];
 			for(var j = 0; j < cols; j++){
-				var hn = dojo.clone(helperNode),
+				var hn = lang.clone(helperNode),
 					l = r ? j : cols - (j + 1)
 				;
 				var adjustClip = function(xn, yCounter, xCounter){
 					return function(){
 						if(!(yCounter % 2)){
-							dojo.style(xn, {
+							htmlUtil.style(xn, {
 								clip: "rect(" + yCounter * h + "px," + (nw - (xCounter + 1) * w ) + "px," + ((yCounter + 1) * h) + "px,0px)"
 							});
 						}else{
-							dojo.style(xn, {
+							htmlUtil.style(xn, {
 								clip: "rect(" + yCounter * h + "px," + nw + "px," + ((yCounter + 1) * h) + "px," + ((xCounter + 1) * w) + "px)"
 							});
 						}
 					}
 				}(cn, i, j);
-	     		dojo.body().appendChild(hn);
-	     		dojo.style(hn, {
-	     		    left: x + l * w + "px",
-	     		    top: y + i * h + "px",
+				winUtil.body().appendChild(hn);
+				htmlUtil.style(hn, {
+					left: x + l * w + "px",
+					top: y + i * h + "px",
 					visibility: "hidden"
-	     		});
+				});
 				var a = dojox.fx.flipPage({
 				   node: hn,
 				   dir: d,
@@ -482,21 +497,21 @@ define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
 				}),
 				removeHelper = function(xn){
 					return function(){
-						dojo.destroy(xn);
+						domConstruct.destroy(xn);
 					}
 				}(hn)
 				;
-				dojo.connect(a, "play", this, adjustClip);
-				dojo.connect(a, "play", this, removeHelper);
+				connectUtil.connect(a, "play", this, adjustClip);
+				connectUtil.connect(a, "play", this, removeHelper);
 				anims[i].push(a);
 			}
-			cAnims.push(dojo.fx.chain(anims[i]));
+			cAnims.push(coreFx.chain(anims[i]));
 			
 		}
-		dojo.connect(cAnims[0], "play", function(){
-			dojo.style(n, {visibility: "hidden"});
+		connectUtil.connect(cAnims[0], "play", function(){
+			htmlUtil.style(n, {visibility: "hidden"});
 		});
-		return dojo.fx.combine(cAnims);
+		return coreFx.combine(cAnims);
 	};
-	return dojox.fx.flip;
+	return fxExt;
 });
diff --git a/dojox/fx/scroll.js b/dojox/fx/scroll.js
index 9fefa8e..4ad1110 100644
--- a/dojox/fx/scroll.js
+++ b/dojox/fx/scroll.js
@@ -1,41 +1,43 @@
-dojo.provide("dojox.fx.scroll");
-dojo.experimental("dojox.fx.scroll");
-
-dojo.require("dojox.fx._core");
-
-dojox.fx.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
-
-	if(!args.target){ args.target = dojo.position(args.node); }
-
-	var isWindow = dojo[(dojo.isIE ? "isObject" : "isFunction")](args["win"].scrollTo),
-		delta = { x: args.target.x, y: args.target.y }
-	;
-	if(!isWindow){
-		var winPos = dojo.position(args.win);
-		delta.x -= winPos.x;
-		delta.y -= winPos.y;
-	}
-	var _anim = (isWindow) ?
-		(function(val){
-			args.win.scrollTo(val[0],val[1]);
-		}) :
-		(function(val){
-			args.win.scrollLeft = val[0];
-			args.win.scrollTop = val[1];
-		});
-	var anim = new dojo.Animation(dojo.mixin({
-		beforeBegin: function(){
-			if(this.curve){ delete this.curve; }
-			var current = isWindow ? dojo._docScroll() : {x: args.win.scrollLeft, y: args.win.scrollTop};
-			anim.curve = new dojox.fx._Line([current.x,current.y],[current.x + delta.x, current.y + delta.y]);
-		},
-		onAnimate: _anim
-	},args));
-	return anim; // dojo.Animation
-};
+define(["dojo/_base/kernel","dojo/_base/lang", "dojo/_base/fx", "dojox/fx/_base","dojox/fx/_core","dojo/dom-geometry","dojo/_base/sniff"],
+	function (kernel, lang, baseFx, fxExt, Line, domGeom, has){
+	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
+	
+		if(!args.target){ args.target = domGeom.position(args.node); }
+	
+		var isWindow = lang[(has("ie") ? "isObject" : "isFunction")](args["win"].scrollTo),
+			delta = { x: args.target.x, y: args.target.y }
+		;
+		if(!isWindow){
+			var winPos = domGeom.position(args.win);
+			delta.x -= winPos.x;
+			delta.y -= winPos.y;
+		}
+		var _anim = (isWindow) ?
+			(function(val){
+				args.win.scrollTo(val[0],val[1]);
+			}) :
+			(function(val){
+				args.win.scrollLeft = val[0];
+				args.win.scrollTop = val[1];
+			});
+		var anim = new baseFx.Animation(lang.mixin({
+			beforeBegin: function(){
+				if(this.curve){ delete this.curve; }
+				var current = isWindow ? dojo._docScroll() : {x: args.win.scrollLeft, y: args.win.scrollTop};
+				anim.curve = new Line([current.x,current.y],[current.x + delta.x, current.y + delta.y]);
+			},
+			onAnimate: _anim
+		},args));
+		return anim; // dojo.Animation
+	};
+	fx.smoothScroll = fxExt.smoothScroll;
+	return fxExt.smoothScroll;
+});
\ No newline at end of file
diff --git a/dojox/fx/split.js b/dojox/fx/split.js
index 83fc2a9..ef93a1d 100644
--- a/dojox/fx/split.js
+++ b/dojox/fx/split.js
@@ -1,9 +1,8 @@
-dojo.provide("dojox.fx.split");
-
-dojo.require("dojo.fx");
-dojo.require("dojo.fx.easing");
-
-dojo.mixin(dojox.fx,{
+define(["dojo/_base/lang", "dojo/dom", "dojo/_base/window", "dojo/_base/html", "dojo/dom-geometry", 
+		"dojo/dom-construct", "dojo/dom-attr", "dojo/_base/fx", "dojo/fx", "./_base", "dojo/fx/easing", "dojo/_base/connect"],
+	function(lang, dom, winUtil, htmlUtil, domGeom, domConstruct, domAttr, baseFx, coreFx, fxExt, easingUtil, connectUtil){
+var dojoxFx = lang.getObject("dojox.fx");
+lang.mixin(dojoxFx,{
 	_split: function(/*Object*/ args){
 		// summary: Split a node into rectangular pieces and animate them.
 		//
@@ -23,26 +22,26 @@ dojo.mixin(dojox.fx,{
 		args.columns = args.columns || 3;
 		args.duration = args.duration || 1000;
 
-		var node = args.node = dojo.byId(args.node),
+		var node = args.node = dom.byId(args.node),
 			parentNode = node.parentNode,
 			pNode = parentNode,
-			body = dojo.body(),
+			body = winUtil.body(),
 			_pos = "position"
 		;
 
-		while(pNode && pNode != body && dojo.style(pNode, _pos) == "static"){
+		while(pNode && pNode != body && htmlUtil.style(pNode, _pos) == "static"){
 			pNode = pNode.parentNode;
 		}
 
-		var pCoords = pNode != body ? dojo.position(pNode, true) : { x: 0, y: 0 },
-			coords = dojo.position(node, true),
-			nodeHeight = dojo.style(node, "height"),
-			nodeWidth = dojo.style(node, "width"),
-			hBorder = dojo.style(node, "borderLeftWidth") + dojo.style(node, "borderRightWidth"),
-			vBorder = dojo.style(node, "borderTopWidth") + dojo.style(node, "borderBottomWidth"),
+		var pCoords = pNode != body ? domGeom.position(pNode, true) : { x: 0, y: 0 },
+			coords = domGeom.position(node, true),
+			nodeHeight = htmlUtil.style(node, "height"),
+			nodeWidth = htmlUtil.style(node, "width"),
+			hBorder = htmlUtil.style(node, "borderLeftWidth") + htmlUtil.style(node, "borderRightWidth"),
+			vBorder = htmlUtil.style(node, "borderTopWidth") + htmlUtil.style(node, "borderBottomWidth"),
 			pieceHeight = Math.ceil(nodeHeight / args.rows),
 			pieceWidth = Math.ceil(nodeWidth / args.columns),
-			container = dojo.create(node.tagName, {
+			container = domConstruct.create(node.tagName, {
 				style: {
 					position: "absolute",
 					padding: 0,
@@ -54,11 +53,11 @@ dojo.mixin(dojox.fx,{
 					width: nodeWidth + hBorder + "px",
 					background: "none",
 					overflow: args.crop ? "hidden" : "visible",
-					zIndex: dojo.style(node, "zIndex")
+					zIndex: htmlUtil.style(node, "zIndex")
 				}
 			}, node, "after"),
 			animations = [],
-			pieceHelper = dojo.create(node.tagName, {
+			pieceHelper = domConstruct.create(node.tagName, {
 				style: {
 					position: "absolute",
 					border: "none",
@@ -74,8 +73,8 @@ dojo.mixin(dojox.fx,{
 		for(var y = 0, ly = args.rows; y < ly; y++){
 			for(var x = 0, lx = args.columns; x < lx; x++){
 				// Create the piece
-				var piece = dojo.clone(pieceHelper),
-					pieceContents = dojo.clone(node),
+				var piece = lang.clone(pieceHelper),
+					pieceContents = lang.clone(node),
 					pTop = y * pieceHeight,
 					pLeft = x * pieceWidth
 				;
@@ -84,15 +83,15 @@ dojo.mixin(dojox.fx,{
 				pieceContents.style.filter = "";
 
 				// removing the id attribute from the cloned nodes
-				dojo.removeAttr(pieceContents, "id");
+				domAttr.remove(pieceContents, "id");
 
-				dojo.style(piece, {
+				htmlUtil.style(piece, {
 					border: "none",
 					overflow: "hidden",
 					top: pTop + "px",
 					left: pLeft + "px"
 				});
-				dojo.style(pieceContents, {
+				htmlUtil.style(pieceContents, {
 					position: "static",
 					opacity: "1",
 					marginTop: -pTop + "px",
@@ -102,7 +101,7 @@ dojo.mixin(dojox.fx,{
 				container.appendChild(piece);
 
 				var pieceAnimation = args.pieceAnimation(piece, x, y, coords);
-				if(dojo.isArray(pieceAnimation)){
+				if(lang.isArray(pieceAnimation)){
 					// if pieceAnimation is an array, append its elements
 					animations = animations.concat(pieceAnimation);
 				}else{
@@ -111,15 +110,15 @@ dojo.mixin(dojox.fx,{
 				}
 			}
 		}
-		var anim = dojo.fx.combine(animations);
-		dojo.connect(anim, "onEnd", anim, function(){
+		var anim = coreFx.combine(animations);
+		connectUtil.connect(anim, "onEnd", anim, function(){
 			container.parentNode.removeChild(container);
 		});
 		if(args.onPlay){
-			dojo.connect(anim, "onPlay", anim, args.onPlay);
+			connectUtil.connect(anim, "onPlay", anim, args.onPlay);
 		}
 		if(args.onEnd){
-			dojo.connect(anim, "onEnd", anim, args.onEnd);
+			connectUtil.connect(anim, "onEnd", anim, args.onEnd);
 		}
 		return anim; // dojo.Animation
 	},
@@ -144,7 +143,7 @@ dojo.mixin(dojox.fx,{
 		//		args.sync: Boolean - If args.unhide is true, all the pieces converge at the same time
 		//							 (default is true)
 
-		var node = args.node = dojo.byId(args.node);
+		var node = args.node = dom.byId(args.node);
 		args.rows = args.rows || 3;
 		args.columns = args.columns || 3;
 		args.distance = args.distance || 1;
@@ -191,14 +190,14 @@ dojo.mixin(dojox.fx,{
 
 			// Create the animation objects for the piece
 			// These are separate anim objects so they can have different curves
-			var pieceSlide = dojo.animateProperty({
+			var pieceSlide = baseFx.animateProperty({
 				node: piece,
 				duration: duration,
 				delay: delay,
-				easing: (args.easing || (args.unhide ? dojo.fx.easing.sinOut : dojo.fx.easing.circOut)),
+				easing: (args.easing || (args.unhide ? easingUtil.sinOut : easingUtil.circOut)),
 				beforeBegin: (args.unhide ? function(){
 						if(args.fade){
-							dojo.style(piece, { opacity: "0"});
+							htmlUtil.style(piece, { opacity: "0"});
 						}
 						ps.top = endTop + "px";
 						ps.left = endLeft + "px";
@@ -209,11 +208,11 @@ dojo.mixin(dojox.fx,{
 				}
 			});
 			if(args.fade){
-				var pieceFade = dojo.animateProperty({
+				var pieceFade = baseFx.animateProperty({
 					node: piece,
 					duration: duration,
 					delay: delay,
-					easing: (args.fadeEasing || dojo.fx.easing.quadOut),
+					easing: (args.fadeEasing || easingUtil.quadOut),
 					properties: {
 						opacity: (args.unhide ? { start: "0", end: "1" } : { start: "1", end: "0" })
 					}
@@ -227,14 +226,14 @@ dojo.mixin(dojox.fx,{
 			}
 		};
 
-		var anim = dojox.fx._split(args);
+		var anim = dojoxFx._split(args);
 		if(args.unhide){
-			dojo.connect(anim, "onEnd", null, function(){
-				dojo.style(node, {opacity: "1" });
+			connectUtil.connect(anim, "onEnd", null, function(){
+				htmlUtil.style(node, {opacity: "1" });
 			});
 		}else{
-			dojo.connect(anim, "onPlay", null, function(){
-				dojo.style(node, { opacity: "0" });
+			connectUtil.connect(anim, "onPlay", null, function(){
+				htmlUtil.style(node, { opacity: "0" });
 			});
 		}
 		return anim; // dojo.Animation
@@ -242,7 +241,7 @@ dojo.mixin(dojox.fx,{
 
 	converge: function(/*Object*/ args){
 		args.unhide = true;
-		return dojox.fx.explode(args);
+		return dojoxFx.explode(args);
 	},
 
 	disintegrate: function(/*Object*/ args){
@@ -262,7 +261,7 @@ dojo.mixin(dojox.fx,{
 		//							   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
-		var node = args.node = dojo.byId(args.node);
+		var node = args.node = dom.byId(args.node);
 
 		args.rows = args.rows || 5;
 		args.columns = args.columns || 5;
@@ -305,15 +304,15 @@ dojo.mixin(dojox.fx,{
 					properties.opacity = {end: "0"};
 				}
 			}
-			var pieceAnimation = dojo.animateProperty({
+			var pieceAnimation = baseFx.animateProperty({
 				node: piece,
 				duration: duration,
 				delay: delay,
-				easing: (args.easing || (args.unhide ? dojo.fx.easing.sinIn : dojo.fx.easing.circIn)),
+				easing: (args.easing || (args.unhide ? easingUtil.sinIn : easingUtil.circIn)),
 				properties: properties,
 				beforeBegin: (args.unhide ? function(){
 					if(args.fade){
-						dojo.style(piece, { opacity: "0" });
+						htmlUtil.style(piece, { opacity: "0" });
 					}
 					ps.top = properties.top.start + "px";
 				} : undefined)
@@ -322,14 +321,14 @@ dojo.mixin(dojox.fx,{
 			return pieceAnimation;
 		};
 
-		var anim = dojox.fx._split(args);
+		var anim = dojoxFx._split(args);
 		if(args.unhide){
-			dojo.connect(anim, "onEnd", anim, function(){
-				dojo.style(node, { opacity: "1" });
+			connectUtil.connect(anim, "onEnd", anim, function(){
+				htmlUtil.style(node, { opacity: "1" });
 			});
 		}else{
-			dojo.connect(anim, "onPlay", anim, function(){
-				dojo.style(node, { opacity: "0" });
+			connectUtil.connect(anim, "onPlay", anim, function(){
+				htmlUtil.style(node, { opacity: "0" });
 			});
 		}
 		return anim; // dojo.Animation
@@ -337,7 +336,7 @@ dojo.mixin(dojox.fx,{
 
 	build: function(/*Object*/ args){
 		args.unhide = true;
-		return dojox.fx.disintegrate(args);
+		return dojoxFx.disintegrate(args);
 	},
 
 	shear: function(/*Object*/ args){
@@ -358,7 +357,7 @@ dojo.mixin(dojox.fx,{
 		//		args.reverseOrder: Boolean - If true, pieces animate in reversed order
 		//		args.unhide: Boolean - If true, the animation is reversed
 
-		var node = args.node = dojo.byId(args.node);
+		var node = args.node = dom.byId(args.node);
 
 		args.rows = args.rows || 6;
 		args.columns = args.columns || 6;
@@ -420,11 +419,11 @@ dojo.mixin(dojox.fx,{
 			}
 
 			// Create the animation object for the piece
-			var pieceAnimation = dojo.animateProperty({
+			var pieceAnimation = baseFx.animateProperty({
 				node: piece,
 				duration: duration,
 				delay: delay,
-				easing: (args.easing || dojo.fx.easing.sinInOut),
+				easing: (args.easing || easingUtil.sinInOut),
 				properties: properties,
 				beforeBegin: (args.unhide ? function(){
 					if(args.fade){
@@ -441,14 +440,14 @@ dojo.mixin(dojox.fx,{
 			return pieceAnimation;
 		};
 
-		var anim = dojox.fx._split(args);
+		var anim = dojoxFx._split(args);
 		if(args.unhide){
-			dojo.connect(anim, "onEnd", anim, function(){
-				dojo.style(node, { opacity: "1" });
+			connectUtil.connect(anim, "onEnd", anim, function(){
+				htmlUtil.style(node, { opacity: "1" });
 			});
 		}else{
-			dojo.connect(anim, "onPlay", anim, function(){
-				dojo.style(node, { opacity: "0" });
+			connectUtil.connect(anim, "onPlay", anim, function(){
+				htmlUtil.style(node, { opacity: "0" });
 			});
 		}
 		return anim; // dojo.Animation
@@ -456,7 +455,7 @@ dojo.mixin(dojox.fx,{
 
 	unShear: function(/*Object*/ args){
 		args.unhide = true;
-		return dojox.fx.shear(args);
+		return dojoxFx.shear(args);
 	},
 
 	pinwheel: function(/*Object*/ args){
@@ -476,7 +475,7 @@ dojo.mixin(dojox.fx,{
 		//							   randomness is introduced.
 		//		args.unhide: Boolean - If true, the animation is reversed
 
-		var node = args.node = dojo.byId(args.node);
+		var node = args.node = dom.byId(args.node);
 
 		args.rows = args.rows || 4;
 		args.columns = args.columns || 4;
@@ -544,15 +543,15 @@ dojo.mixin(dojox.fx,{
 			}
 
 			// Create the animation object for the piece
-			var pieceAnimation = dojo.animateProperty({
+			var pieceAnimation = baseFx.animateProperty({
 				node: piece,
 				duration: duration,
 				delay: delay,
-				easing: (args.easing || dojo.fx.easing.sinInOut),
+				easing: (args.easing || easingUtil.sinInOut),
 				properties: properties,
 				beforeBegin: (args.unhide ? function(){
 					if(args.fade){
-						dojo.style(piece, "opacity", 0);
+						htmlUtil.style(piece, "opacity", 0);
 					}
 					if(colIsOdd){
 						if(rowIsOdd){
@@ -575,14 +574,14 @@ dojo.mixin(dojox.fx,{
 			return pieceAnimation;
 		};
 
-		var anim = dojox.fx._split(args);
+		var anim = dojoxFx._split(args);
 		if(args.unhide){
-			dojo.connect(anim, "onEnd", anim, function(){
-				dojo.style(node, { opacity: "1" });
+			connectUtil.connect(anim, "onEnd", anim, function(){
+				htmlUtil.style(node, { opacity: "1" });
 			});
 		}else{
-			dojo.connect(anim, "play", anim, function(){
-				dojo.style(node, { opacity: "0" });
+			connectUtil.connect(anim, "play", anim, function(){
+				htmlUtil.style(node, { opacity: "0" });
 			});
 		}
 		return anim; // dojo.Animation
@@ -590,7 +589,7 @@ dojo.mixin(dojox.fx,{
 
 	unPinwheel: function(/*Object*/ args){
 		args.unhide = true;
-		return dojox.fx.pinwheel(args); // dojo.Animation
+		return dojoxFx.pinwheel(args); // dojo.Animation
 	},
 
 	blockFadeOut: function(/*Object*/ args){
@@ -609,7 +608,7 @@ dojo.mixin(dojox.fx,{
 		//		args.reverseOrder: Boolean - If true, pieces animate in reversed order
 		//		args.unhide: Boolean - If true, the animation is reversed
 
-		var node = args.node = dojo.byId(args.node);
+		var node = args.node = dom.byId(args.node);
 
 		args.rows = args.rows || 5;
 		args.columns = args.columns || 5;
@@ -628,27 +627,27 @@ dojo.mixin(dojox.fx,{
 					((x + y) * args.interval),
 				delay = randomDelay * random + Math.max(1 - random, 0) * uniformDelay,
 			// Create the animation object for the piece
-				pieceAnimation = dojo.animateProperty({
+				pieceAnimation = baseFx.animateProperty({
 					node: piece,
 					duration: duration,
 					delay: delay,
-					easing: (args.easing || dojo.fx.easing.sinInOut),
+					easing: (args.easing || easingUtil.sinInOut),
 					properties: {
 						opacity: (args.unhide ? {start: "0", end: "1"} : {start: "1", end: "0"})
 					},
-					beforeBegin: (args.unhide ? function(){ dojo.style(piece, { opacity: "0" });} : function(){ piece.style.filter = ""; })
+					beforeBegin: (args.unhide ? function(){ htmlUtil.style(piece, { opacity: "0" });} : function(){ piece.style.filter = ""; })
 				});
 
 			return pieceAnimation;
 		};
-		var anim = dojox.fx._split(args);
+		var anim = dojoxFx._split(args);
 		if(args.unhide){
-			dojo.connect(anim, "onEnd", anim, function(){
-				dojo.style(node, { opacity: "1" });
+			connectUtil.connect(anim, "onEnd", anim, function(){
+				htmlUtil.style(node, { opacity: "1" });
 			});
 		}else{
-			dojo.connect(anim, "onPlay", anim, function(){
-				dojo.style(node, { opacity: "0" });
+			connectUtil.connect(anim, "onPlay", anim, function(){
+				htmlUtil.style(node, { opacity: "0" });
 			});
 		}
 		return anim; // dojo.Animation
@@ -656,7 +655,8 @@ dojo.mixin(dojox.fx,{
 
 	blockFadeIn: function(/*Object*/ args){
 		args.unhide = true;
-		return dojox.fx.blockFadeOut(args); // dojo.Animation
+		return dojoxFx.blockFadeOut(args); // dojo.Animation
 	}
-
+});
+return fxExt;
 });
\ No newline at end of file
diff --git a/dojox/fx/style.js b/dojox/fx/style.js
index c956bab..ab6edfc 100644
--- a/dojox/fx/style.js
+++ b/dojox/fx/style.js
@@ -1,6 +1,7 @@
-dojo.provide("dojox.fx.style");
-dojo.experimental("dojox.fx.style");
-//
+define(["dojo/_base/kernel","dojo/_base/lang","dojo/_base/fx","dojo/fx","./_base","dojo/_base/array","dojo/dom","dojo/dom-style","dojo/dom-class",
+		"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:
 //
@@ -10,11 +11,7 @@ dojo.experimental("dojox.fx.style");
 //
 //	provides: addClass, removeClass, and toggleClass
 //
-dojo.require("dojo.fx");
-
-(function(){
 		
-	var d = dojo;
 
 	var _getStyleSnapshot = function(/* Object */cache){
 		// summary:
@@ -25,7 +22,7 @@ dojo.require("dojo.fx");
 		// returns:  Array
 		//		an array of raw, calculcated values (no keys), to be normalized/compared
 		//		elsewhere
-		return d.map(dojox.fx._allowedProperties, function(style){
+		return arrayUtil.map(dojoxFx._allowedProperties, function(style){
 			return cache[style]; // String
 		}); // Array
 	};
@@ -41,17 +38,17 @@ dojo.require("dojo.fx");
 		// 	true to calculate what adding a class would do,
 		// 	false to calculate what removing the class would do
 
-		node = d.byId(node);
-		var	cs = d.getComputedStyle(node);
+		node = dom.byId(node);
+		var	cs = domStyle.getComputedStyle(node);
 
 		// take our snapShots
 		var _before = _getStyleSnapshot(cs);
-		d[(addClass ? "addClass" : "removeClass")](node, cssClass);
+		dojo[(addClass ? "addClass" : "removeClass")](node, cssClass);
 		var _after = _getStyleSnapshot(cs);
-		d[(addClass ? "removeClass" : "addClass")](node, cssClass);
+		dojo[(addClass ? "removeClass" : "addClass")](node, cssClass);
 
 		var calculated = {}, i = 0;
-		d.forEach(dojox.fx._allowedProperties, function(prop){
+		arrayUtil.forEach(dojoxFx._allowedProperties, function(prop){
 			if(_before[i] != _after[i]){
 				// FIXME: the static units: px is not good, either. need to parse unit from computed style?
 				calculated[prop] = parseInt(_after[i]) /* start: parseInt(_before[i]), units: 'px' */ ;
@@ -61,7 +58,7 @@ dojo.require("dojo.fx");
 		return calculated;
 	};
 
-	d.mixin(dojox.fx,{
+	var styleFx = { // Augment dojox.fx for compat
 
 		addClass: function(node, cssClass, args){
 			// summary:
@@ -94,7 +91,7 @@ dojo.require("dojo.fx");
 			//	|	// animate to line-height:40px
 			//	|	dojo.fx.addClass("test", "foo").play();
 			//
-			node = d.byId(node);
+			node = dom.byId(node);
 
 			var pushClass = (function(n){
 				// summary: onEnd we want to add the class to the node
@@ -104,7 +101,7 @@ dojo.require("dojo.fx");
 				//	and will only apply the class so children can inherit
 				//	after the animation is done (potentially more flicker)
 				return function(){
-					d.addClass(n, cssClass);
+					domClass.add(n, cssClass);
 					n.style.cssText = _beforeStyle;
 				}
 			})(node);
@@ -112,11 +109,11 @@ dojo.require("dojo.fx");
 			// _getCalculatedStleChanges is the core of our style/class animations
 			var mixedProperties = _getCalculatedStyleChanges(node, cssClass, true);
 			var _beforeStyle = node.style.cssText;
-			var _anim = d.animateProperty(d.mixin({
+			var _anim = baseFx.animateProperty(lang.mixin({
 				node: node,
 				properties: mixedProperties
 			}, args));
-			d.connect(_anim, "onEnd", _anim, pushClass);
+			connectUtil.connect(_anim, "onEnd", _anim, pushClass);
 			return _anim; // dojo.Animation
 		},
 	
@@ -135,7 +132,7 @@ dojo.require("dojo.fx");
 			// |	// animate the removal of "foo" from a node with id="bar"
 			// |	dojox.fx.removeClass("bar", "foo").play()
 
-			node = d.byId(node);
+			node = dom.byId(node);
 
 			var pullClass = (function(n){
 				// summary: onEnd we want to remove the class from the node
@@ -146,18 +143,18 @@ dojo.require("dojo.fx");
 				//	animation is done (potentially more flicker)
 				//
 				return function(){
-					d.removeClass(n, cssClass);
+					domClass.remove(n, cssClass);
 					n.style.cssText = _beforeStyle;
 				}
 			})(node);
 
 			var mixedProperties = _getCalculatedStyleChanges(node, cssClass);
 			var _beforeStyle = node.style.cssText;
-			var _anim = d.animateProperty(d.mixin({
+			var _anim = baseFx.animateProperty(lang.mixin({
 				node: node,
 				properties: mixedProperties
 			}, args));
-			d.connect(_anim, "onEnd", _anim, pullClass);
+			connectUtil.connect(_anim, "onEnd", _anim, pullClass);
 			return _anim; // dojo.Animation
 		},
 
@@ -188,9 +185,9 @@ dojo.require("dojo.fx");
 			// |	dojox.fx.toggleClass("theNode","sampleClass").play();
 
 			if(typeof condition == "undefined"){
-				condition = !d.hasClass(node, cssClass);
+				condition = !domClass.contains(node, cssClass);
 			}
-			return dojox.fx[(condition ? "addClass" : "removeClass")](node, cssClass, args); // dojo.Animation
+			return dojoxFx[(condition ? "addClass" : "removeClass")](node, cssClass, args); // dojo.Animation
 		},
 	
 		_allowedProperties: [
@@ -233,7 +230,7 @@ dojo.require("dojo.fx");
 			"letterSpacing",
 			"fontSize"
 		]
-	
-	});
-
-})();
+	};
+		lang.mixin(dojoxFx,styleFx);
+	return styleFx;
+});
diff --git a/dojox/fx/tests/example_dojoAnimations.html b/dojox/fx/tests/example_dojoAnimations.html
index f32b3a5..c8cf6e1 100644
--- a/dojox/fx/tests/example_dojoAnimations.html
+++ b/dojox/fx/tests/example_dojoAnimations.html
@@ -82,6 +82,7 @@
 		djConfig="parseOnLoad:true, isDebug:true"></script>
 
 	<script type="text/javascript">
+		dojo.require("dojo.parser");
 		dojo.require("dijit.form.Button"); // for the tests
 		
 		// core animations:
diff --git a/dojox/fx/tests/example_easingChart2D.html b/dojox/fx/tests/example_easingChart2D.html
index e1caf59..45f03cf 100644
--- a/dojox/fx/tests/example_easingChart2D.html
+++ b/dojox/fx/tests/example_easingChart2D.html
@@ -37,7 +37,7 @@
 			}
 
 			if(!seriesData.length){
-				var func = func || dojox.fx.easing[str];
+				var func = func || dojo.fx.easing[str];
 				func = (dojo.isFunction(func) ? func : dojo._defaultEasing);
 
 				for(var i=0; i<=120; i++){
diff --git a/dojox/fx/tests/test_Nodelist-fx.html b/dojox/fx/tests/test_Nodelist-fx.html
index f298e1d..573860b 100644
--- a/dojox/fx/tests/test_Nodelist-fx.html
+++ b/dojox/fx/tests/test_Nodelist-fx.html
@@ -49,7 +49,7 @@
 
 	dojo.require("dojox.fx.ext-dojo.NodeList"); 
 	dojo.require("dijit.form.Button");
-	dojo.require("dijit.form.CheckBox");
+	dojo.require("dijit.form.RadioButton");
 
 	// its funny...
 	var dQuery = dojo.query;
@@ -204,7 +204,7 @@
 			return false; 
 		</script>
 
-		<button dojoType="dijit.form.Button" type="submit" id="runnerButton" />
+		<button dojoType="dijit.form.Button" type="submit" id="runnerButton" >
 			Run
 			<script type="dojo/method" event="onClick">
 				// our runner / submit button				
diff --git a/dojox/fx/tests/test_Shadow.html b/dojox/fx/tests/test_Shadow.html
index 26cc283..b20bbac 100644
--- a/dojox/fx/tests/test_Shadow.html
+++ b/dojox/fx/tests/test_Shadow.html
@@ -5,7 +5,6 @@
 	<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="../Shadow.js"></script>
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/themes/dijit.css";
@@ -16,6 +15,7 @@
 		dojo.require("dojo.dnd.Moveable");
 		dojo.require("dojox.layout.FloatingPane");
 		dojo.require("dijit.Calendar"); 
+		dojo.require("dojox.fx.Shadow");
 		var enabled = true, randInt=0;
 		dojo.addOnLoad(function(){
 			
diff --git a/dojox/fx/tests/test_animateClass.html b/dojox/fx/tests/test_animateClass.html
index 7e0a07b..025a5c4 100644
--- a/dojox/fx/tests/test_animateClass.html
+++ b/dojox/fx/tests/test_animateClass.html
@@ -14,16 +14,12 @@
 		
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
 		djConfig="isDebug:true, parseOnLoad: true" ></script>
-		
-	<!-- debugging -->
-	<script type="text/javascript" src="../style.js"></script>
-	<script type="text/javascript" src="../ext-dojo/NodeList-style.js"></script>
-	
+			
 	<script type="text/javascript">
+		dojo.require("dojo.parser");
+		dojo.require("dijit.form.Button"); 
 		dojo.require("dojox.fx.style");
 		dojo.require("dojox.fx.ext-dojo.NodeList-style");
-		
-		dojo.require("dijit.form.Button"); 
 	</script>
 </head>
 <body class="tundra">
@@ -74,8 +70,8 @@
 					}));
 					delay += 200;
 				});
-				this.attr('disabled',true);
-				dijit.byId('removeTall').attr('disabled',false);
+				this.set('disabled',true);
+				dijit.byId('removeTall').set('disabled',false);
 				dojo.fx.combine(_anims).play();
 		</script>
 	</button>
@@ -90,8 +86,8 @@
 						}));
 						delay += 200;
 				});
-				this.attr('disabled', true);
-				dijit.byId('addTall').attr('disabled',false);
+				this.set('disabled', true);
+				dijit.byId('addTall').set('disabled',false);
 				dojo.fx.combine(_anims).play();
 		</script>
 	</button>		 
@@ -106,8 +102,8 @@
 						}));
 						delay += 200;
 				});
-				this.attr('disabled',true);
-				dijit.byId('removeWide').attr('disabled',false);
+				this.set('disabled',true);
+				dijit.byId('removeWide').set('disabled',false);
 				dojo.fx.combine(_anims).play();
 		</script>
 	</button>
@@ -122,8 +118,8 @@
 					}));
 					delay += 200;
 				});
-				this.attr('disabled',true);
-				dijit.byId('addWide').attr('disabled',false);
+				this.set('disabled',true);
+				dijit.byId('addWide').set('disabled',false);
 				dojo.fx.combine(_anims).play();
 		</script>
 	</button>
diff --git a/dojox/fx/tests/test_flip.html b/dojox/fx/tests/test_flip.html
index b278a71..f626500 100644
--- a/dojox/fx/tests/test_flip.html
+++ b/dojox/fx/tests/test_flip.html
@@ -1,77 +1,76 @@
 <!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>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="../_base.js"></script>
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
-	    @import "../../../dijit/themes/tundra/tundra.css";
+		@import "../../../dijit/themes/tundra/tundra.css";
 		.testBox {
 			overflow:hidden;
-            font: 20px arial, sans-serif;
-            line-height:200px;
-            text-align:center;
-            width:300px;
-            height:200px;
+			font: 20px arial, sans-serif;
+			line-height:200px;
+			text-align:center;
+			width:300px;
+			height:200px;
 		}
-        .pageContainer{
-            position:relative;
-            border:1px solid #999;
-        }
-        .page{
-            padding:13px;
-            width:200px;
-            height:360px;
-            background:#f0ecec;
-            color:#333;
-            font:11px arial, sans-serif;
-        }
-        table.demoContainer{
-            border-collapse: collapse;
-            margin-top:20px;
-        }
-        table.demoContainer thead th{
-            font: 20px arial, sans-serif;
-            border-bottom:1px solid #999;
-            text-align:center;
-            color: #666;
-        }
-        table.demoContainer thead th.view{
-            border-right:1px solid #999;            
-        }
-        table.demoContainer td.view{
-            border-right: 1px solid #999;
-            width:400px;
-            padding:10px 0px 30px 100px;
-            text-align:center;
-        }
-        div.controls{
-            width:300px;
-            height:200px;
-            margin: 40px 20px 0 20px;
-        }
-        div.topBottom{
-            width:100%;
-            text-align:center;
-        }
-        div.middle{
-            margin:40px 0;
-            width:100%;
-            height:40px;
-            line-height:40px;
-            text-align:center;
-            position:relative;
-        }
-        input.button{
-            border:1px solid #999;
-            color: #333;
-            background: #ddd;
-            padding:5px;
-        }
-    </style>
+		.pageContainer{
+			position:relative;
+			border:1px solid #999;
+		}
+		.page{
+			padding:13px;
+			width:200px;
+			height:360px;
+			background:#f0ecec;
+			color:#333;
+			font:11px arial, sans-serif;
+		}
+		table.demoContainer{
+			border-collapse: collapse;
+			margin-top:20px;
+		}
+		table.demoContainer thead th{
+			font: 20px arial, sans-serif;
+			border-bottom:1px solid #999;
+			text-align:center;
+			color: #666;
+		}
+		table.demoContainer thead th.view{
+			border-right:1px solid #999;			
+		}
+		table.demoContainer td.view{
+			border-right: 1px solid #999;
+			width:400px;
+			padding:10px 0px 30px 100px;
+			text-align:center;
+		}
+		div.controls{
+			width:300px;
+			height:200px;
+			margin: 40px 20px 0 20px;
+		}
+		div.topBottom{
+			width:100%;
+			text-align:center;
+		}
+		div.middle{
+			margin:40px 0;
+			width:100%;
+			height:40px;
+			line-height:40px;
+			text-align:center;
+			position:relative;
+		}
+		input.button{
+			border:1px solid #999;
+			color: #333;
+			background: #ddd;
+			padding:5px;
+		}
+	</style>
 	<script type="text/javascript">
 		dojo.require("dojox.fx.flip");
 
@@ -89,10 +88,10 @@
 				dojo.connect(anim, "onEnd", this, function(){ 
 					var n = dojo.byId("flip1");
 					n.innerHTML = "TOP";
-                    dojo.style(n, {
-                        color: "#ddd",
-                        background: "#666"
-                    });
+					dojo.style(n, {
+						color: "#ddd",
+						background: "#666"
+					});
 				})
 				anim.play(); 
 			});
@@ -107,10 +106,10 @@
 				dojo.connect(anim, "onEnd", this, function(){ 
 					var n = dojo.byId("flip1");
 					n.innerHTML = "RIGHT";
-                    dojo.style(n, {
-                        color: "red",
-                        background: "yellow"
-                    });
+					dojo.style(n, {
+						color: "red",
+						background: "yellow"
+					});
 				})
 				anim.play(); 
 			});
@@ -125,10 +124,10 @@
 				dojo.connect(anim, "onEnd", this, function(){ 
 					var n = dojo.byId("flip1");
 					n.innerHTML = "BOTTOM";
-                    dojo.style(n, {
-                        color: "yellow",
-                        background: "red"
-                    });
+					dojo.style(n, {
+						color: "yellow",
+						background: "red"
+					});
 				})
 				anim.play(); 
 			});
@@ -143,40 +142,40 @@
 				});		
 													  
 				dojo.connect(anim, "onEnd", this, function(){ 
-                    var n = dojo.byId("flip1");
+					var n = dojo.byId("flip1");
 					n.innerHTML = "LEFT";
-                    dojo.style(n, {
-                        color: "white",
-                        background: "blue"
-                    });
+					dojo.style(n, {
+						color: "white",
+						background: "blue"
+					});
 				});
 				anim.play(); 
 			});
 		};
 
-        // fx.flip, half flip example:
-        var halfflipinit = function(){
-            dojo.connect(dojo.byId("halfflipreset"), "onclick", function(){
-                dojo.style(dojo.byId("hflip1"), {
-                    visibility: "hidden"
-                });
-            });
-            dojo.connect(dojo.byId("halfflip"), "onclick", function(e){
-                var anim = dojox.fx.flip({
-                    node: "hflip1",
-                    dir: "top",
-                    shift: -150,
-                    whichAnim: "last",
-                    depth: .5,
-                    endColor: "#666",
-                    duration: 1000
-                })
-                dojo.connect(anim, "onEnd", this, function(){
-                    var n = dojo.byId("hflip1");
-                })
-                anim.play();
-            });
-        };
+		// fx.flip, half flip example:
+		var halfflipinit = function(){
+			dojo.connect(dojo.byId("halfflipreset"), "onclick", function(){
+				dojo.style(dojo.byId("hflip1"), {
+					visibility: "hidden"
+				});
+			});
+			dojo.connect(dojo.byId("halfflip"), "onclick", function(e){
+				var anim = dojox.fx.flip({
+					node: "hflip1",
+					dir: "top",
+					shift: -150,
+					whichAnim: "last",
+					depth: .5,
+					endColor: "#666",
+					duration: 1000
+				})
+				dojo.connect(anim, "onEnd", this, function(){
+					var n = dojo.byId("hflip1");
+				})
+				anim.play();
+			});
+		};
 
 		// fx.flipCube example:
 		var cubeinit = function(){
@@ -188,12 +187,12 @@
 					duration:500
 				});
 				dojo.connect(anim, "onEnd", this, function(){
-                    var n = dojo.byId("cflip1");
+					var n = dojo.byId("cflip1");
 					n.innerHTML = "TOP";
-                    dojo.style(n, {
-                        color: "#ddd",
-                        background: "#666"
-                    });
+					dojo.style(n, {
+						color: "#ddd",
+						background: "#666"
+					});
 				});											  
 				anim.play(); 
 			});
@@ -205,12 +204,12 @@
 					duration:500
 				});											  
 				dojo.connect(anim, "onEnd", this, function(){ 
-                    var n = dojo.byId("cflip1");
+					var n = dojo.byId("cflip1");
 					n.innerHTML = "RIGHT";
-                    dojo.style(n, {
-                        color: "red",
-                        background: "yellow"
-                    });
+					dojo.style(n, {
+						color: "red",
+						background: "yellow"
+					});
 				});											  
 				anim.play(); 
 			});
@@ -222,12 +221,12 @@
 					duration: 500
 				});											  
 				dojo.connect(anim, "onEnd", this, function(){ 
-                    var n = dojo.byId("cflip1");
+					var n = dojo.byId("cflip1");
 					n.innerHTML = "BOTTOM";
-                    dojo.style(n, {
-                        color: "yellow",
-                        background: "red"
-                    });
+					dojo.style(n, {
+						color: "yellow",
+						background: "red"
+					});
 				});											  
 				anim.play(); 
 			});
@@ -239,22 +238,22 @@
 					duration: 500
 				});											  
 				dojo.connect(anim, "onEnd", this, function(){ 
-                    var n = dojo.byId("cflip1");
+					var n = dojo.byId("cflip1");
 					n.innerHTML = "LEFT";
-                    dojo.style(n, {
-                        color: "white",
-                        background: "blue"
-                    });
+					dojo.style(n, {
+						color: "white",
+						background: "blue"
+					});
 				});
 				anim.play(); 
 			});
 		};
 
-        // fx.flipGrid example:
-        var gridinit = function(){
+		// fx.flipGrid example:
+		var gridinit = function(){
 			dojo.connect(dojo.byId("reset"), "onclick", function(e){
-			    dojo.byId("flipGrid").disabled = "";
-			    dojo.style(dojo.byId("gflip1"), {
+				dojo.byId("flipGrid").disabled = "";
+				dojo.style(dojo.byId("gflip1"), {
 					visibility: "visible"
 				});
 			});
@@ -267,13 +266,13 @@
 					duration:900
 				});
 				dojo.connect(anim, "play", this, function(){
-				    dojo.byId("flipGrid").disabled = "disabled";
-   				});
+					dojo.byId("flipGrid").disabled = "disabled";
+				});
 				anim.play();
 			});
-        };
+		};
 
-        // fx.flipPage example:
+		// fx.flipPage example:
 		var currentPage = 0,
 			pages = 4
 		;
@@ -322,210 +321,210 @@
 			});
 		};
 
-		dojo.addOnLoad(flipinit);
-        dojo.addOnLoad(halfflipinit);
-		dojo.addOnLoad(cubeinit);
-		dojo.addOnLoad(gridinit);
-		dojo.addOnLoad(pageinit);
+		dojo.ready(flipinit);
+		dojo.ready(halfflipinit);
+		dojo.ready(cubeinit);
+		dojo.ready(gridinit);
+		dojo.ready(pageinit);
 	</script>
 </head>
 <body class="tundra">
-	    <table class="demoContainer">
-            <thead>
-                <tr><th class="view">dojox.fx.flip test</th><th></th></tr>
-            </thead>
-            <tbody>
-            <tr>
-                <td class="view">
-                    <div style="width:300px;height:200px;background:#666;color:#ddd;" id="flip1" class="testBox">
-                        dojox.fx.flip
-                    </div>
-                </td>
-                <td>
-                    <div class="controls">
-                        <div class="topBottom"><input type="button" class="button" style="margin:auto" id="flipTop" value="flip top" /></div>
-                        <div class="middle">
-                            <div style="position:absolute;margin:auto;right:0;top:0"><input type="button" class="button" id="flipRight" value="flip right" /></div>
-                            controls
-                            <div style="position:absolute;margin:auto;left:0;top:0"><input type="button" class="button" id="flipLeft" value="flip left" /></div>
-                        </div>
-                        <div class="topBottom"><input type="button" class="button" id="flipBottom" value="flip bottom" /></div>
-                    </div>
-                </td>
-            </tr>
-            </tbody>
-            <thead>
-                <tr><th class="view">dojox.fx.flip test - half flip</th><th></th></tr>
-            </thead>
-            <tbody>
-            <tr>
-                <td class="view">
-                    <div style="width:300px;height:200px;background:#666;color:#ddd;visibility:hidden" id="hflip1" class="testBox">
-                        WOOT!
-                    </div>
-                </td>
-                <td>
-                    <div class="controls">
-                        <div class="middle">
-                            <div style="position:absolute;left:60px;top:0"><input type="button" class="button" id="halfflip" value="half flip" /></div>
-                            <div style="position:absolute;right:60px;top:0"><input type="button" class="button" id="halfflipreset" value="reset" /></div>
-                        </div>
-                    </div>
-                </td>
-            </tr>
-            </tbody>
-            <thead>
-                <tr><th class="view">dojox.fx.flipCube test</th><th></th></tr>
-            </thead>
-            <tbody>
-            <tr>
-                <td class="view">
-                    <div style="width:300px;height:200px;background:#666;color:#ddd" id="cflip1" class="testBox">
-                        dojox.fx.flipCube
-                    </div>
-                </td>
-                <td>
-                    <div class="controls">
-                        <div class="topBottom"><input type="button" class="button" style="margin:auto" id="cflipTop" value="flip top" /></div>
-                        <div class="middle">
-                            <div style="position:absolute;margin:auto;right:0;top:0"><input type="button" class="button" id="cflipRight" value="flip right" /></div>
-                            controls
-                            <div style="position:absolute;margin:auto;left:0;top:0"><input type="button" class="button" id="cflipLeft" value="flip left" /></div>
-                        </div>
-                        <div class="topBottom"><input type="button" class="button" id="cflipBottom" value="flip bottom" /></div>
-                    </div>
-                </td>
-            </tr>
-            </tbody>
-            <thead>
-                <tr><th class="view">dojox.fx.flipGrid test</th><th></th></tr>
-            </thead>
-            <tbody>
-            <tr>
-                <td class="view">
-                    <div style="width:300px;height:200px;background:#666;color:#ddd" id="gflip1" class="testBox">
-                        dojox.fx.flipGrid
-                    </div>
-                <td>
-                <div class="controls">
-                    <div class="middle">
-                        <div style="position:absolute;left:60px;top:0"><input type="button" class="button" id="flipGrid" value="flip grid" /></div>
-                        <div style="position:absolute;right:60px;top:0"><input type="button" class="button" id="reset" value="reset" /></div>
-                    </div>
-                </div>
-                </td>
-            </tr>
-            </tbody>
-            <thead>
-                <tr><th class="view">dojox.fx.flipPage test</th><th></th></tr>
-            </thead>
-            <tbody>
-            <tr>
-                <td class="view" style="padding-left:20px">
-                    <table style="height:300px; width:400px; border-collapse:collapse">
-                        <tbody>
-                            <tr>
-                                <td>
-                                    <div id="pageContainer0" class="pageContainer">
-                                        <div style="display:none" id="page2" class="page">
-                                            Ed una lupa, che di tutte brame
-                                            sembiava carca ne la sua magrezza,
-                                            e molte genti fé già viver grame,
-                                            questa mi porse tanto di gravezza
-                                            con la paura ch'uscia di sua vista,
-                                            ch'io perdei la speranza de l'altezza.
-                                            E qual è quei che volontieri acquista,
-                                            e giugne 'l tempo che perder lo face,
-                                            che 'n tutt'i suoi pensier piange e s'attrista;
-                                            tal mi fece la bestia sanza pace,
-                                            che, venendomi 'ncontro, a poco a poco
-                                            mi ripigneva là dove 'l sol tace.
-                                            Mentre ch'i' rovinava in basso loco,
-                                            dinanzi a li occhi mi si fu offerto
-                                            chi per lungo silenzio parea fioco.
-                                            Quando vidi costui nel gran diserto,
-                                            «Miserere di me», gridai a lui,
-                                            «qual che tu sii, od ombra od omo certo!».
-                                            Rispuosemi: «Non omo, omo già fui,
-                                            e li parenti miei furon lombardi,
-                                            mantoani per patria ambedui.
-                                            Nacqui sub Iulio, ancor che fosse tardi,
-                                            e vissi a Roma sotto 'l buono Augusto
-                                            nel tempo de li dèi falsi e bugiardi.
-                                            Poeta fui, e cantai di quel giusto [...]
-                                        </div>
-                                        <div class="page" id="page0">
-                                            Nel mezzo del cammin di nostra vita
-                                            mi ritrovai per una selva oscura
-                                            ché la diritta via era smarrita.
-                                            Ahi quanto a dir qual era è cosa dura
-                                            esta selva selvaggia e aspra e forte
-                                            che nel pensier rinova la paura!
-                                            Tant'è amara che poco è più morte;
-                                            ma per trattar del ben ch'i' vi trovai,
-                                            dirò de l'altre cose ch'i' v'ho scorte.
-                                            Io non so ben ridir com'i' v'intrai,
-                                            tant'era pien di sonno a quel punto
-                                            che la verace via abbandonai.
-                                            Ma poi ch'i' fui al piè d'un colle giunto,
-                                            là dove terminava quella valle
-                                            che m'avea di paura il cor compunto,
-                                            guardai in alto, e vidi le sue spalle
-                                            vestite già de' raggi del pianeta
-                                            che mena dritto altrui per ogne calle.
-                                            Allor fu la paura un poco queta
-                                            che nel lago del cor m'era durata
-                                            la notte ch'i' passai con tanta pieta.
-                                            E come quei che con lena affannata
-                                            uscito fuor del pelago a la riva
-                                            si volge a l'acqua perigliosa e guata,
-                                            così l'animo mio, ch'ancor fuggiva,
-                                        </div>
-                                    </div>
-                                </td>
-                                <td>
-                                    <div id="pageContainer1" class="pageContainer">
-                                        <div style="display:none;" id="page3" class="page"></div>
-                                        <div id="page1" class="page">
-                                            si volse a retro a rimirar lo passo
-                                            che non lasciò già mai persona viva.
-                                            Poi ch'èi posato un poco il corpo lasso,
-                                            ripresi via per la piaggia diserta,
-                                            sì che 'l piè fermo sempre era 'l più basso.
-                                            Ed ecco, quasi al cominciar de l'erta,
-                                            una lonza leggera e presta molto,
-                                            che di pel macolato era coverta;
-                                            e non mi si partia dinanzi al volto,
-                                            anzi 'mpediva tanto il mio cammino,
-                                            ch'i' fui per ritornar più volte vòlto.
-                                            Temp'era dal principio del mattino,
-                                            e 'l sol montava 'n sù con quelle stelle
-                                            ch'eran con lui quando l'amor divino
-                                            mosse di prima quelle cose belle;
-                                            sì ch'a bene sperar m'era cagione
-                                            di quella fiera a la gaetta pelle
-                                            l'ora del tempo e la dolce stagione;
-                                            ma non sì che paura non mi desse
-                                            la vista che m'apparve d'un leone.
-                                            Questi parea che contra me venisse
-                                            con la test'alta e con rabbiosa fame,
-                                            sì che parea che l'aere ne tremesse.
-                                        </div>
-                                    </div>
-                                </td>
-                            </tr>
-                    </tbody>
-                    </table>
-                </td>
-                <td>
-                    <div class="middle">
-                        <div style="position:absolute;left:30px;top:0"><input type="button" class="button" value="previous page" id="flipPageLeft" /></div>
-                        <div style="position:absolute;right:30px;top:0"><input type="button" class="button" id="flipPageRight" value="next page" /></div>
-                    </div>
-                </td>
-            </tr>
-            </tbody>
-	    </table>
+		<table class="demoContainer">
+			<thead>
+				<tr><th class="view">dojox.fx.flip test</th><th></th></tr>
+			</thead>
+			<tbody>
+			<tr>
+				<td class="view">
+					<div style="width:300px;height:200px;background:#666;color:#ddd;" id="flip1" class="testBox">
+						dojox.fx.flip
+					</div>
+				</td>
+				<td>
+					<div class="controls">
+						<div class="topBottom"><input type="button" class="button" style="margin:auto" id="flipTop" value="flip top" /></div>
+						<div class="middle">
+							<div style="position:absolute;margin:auto;right:0;top:0"><input type="button" class="button" id="flipRight" value="flip right" /></div>
+							controls
+							<div style="position:absolute;margin:auto;left:0;top:0"><input type="button" class="button" id="flipLeft" value="flip left" /></div>
+						</div>
+						<div class="topBottom"><input type="button" class="button" id="flipBottom" value="flip bottom" /></div>
+					</div>
+				</td>
+			</tr>
+			</tbody>
+			<thead>
+				<tr><th class="view">dojox.fx.flip test - half flip</th><th></th></tr>
+			</thead>
+			<tbody>
+			<tr>
+				<td class="view">
+					<div style="width:300px;height:200px;background:#666;color:#ddd;visibility:hidden" id="hflip1" class="testBox">
+						WOOT!
+					</div>
+				</td>
+				<td>
+					<div class="controls">
+						<div class="middle">
+							<div style="position:absolute;left:60px;top:0"><input type="button" class="button" id="halfflip" value="half flip" /></div>
+							<div style="position:absolute;right:60px;top:0"><input type="button" class="button" id="halfflipreset" value="reset" /></div>
+						</div>
+					</div>
+				</td>
+			</tr>
+			</tbody>
+			<thead>
+				<tr><th class="view">dojox.fx.flipCube test</th><th></th></tr>
+			</thead>
+			<tbody>
+			<tr>
+				<td class="view">
+					<div style="width:300px;height:200px;background:#666;color:#ddd" id="cflip1" class="testBox">
+						dojox.fx.flipCube
+					</div>
+				</td>
+				<td>
+					<div class="controls">
+						<div class="topBottom"><input type="button" class="button" style="margin:auto" id="cflipTop" value="flip top" /></div>
+						<div class="middle">
+							<div style="position:absolute;margin:auto;right:0;top:0"><input type="button" class="button" id="cflipRight" value="flip right" /></div>
+							controls
+							<div style="position:absolute;margin:auto;left:0;top:0"><input type="button" class="button" id="cflipLeft" value="flip left" /></div>
+						</div>
+						<div class="topBottom"><input type="button" class="button" id="cflipBottom" value="flip bottom" /></div>
+					</div>
+				</td>
+			</tr>
+			</tbody>
+			<thead>
+				<tr><th class="view">dojox.fx.flipGrid test</th><th></th></tr>
+			</thead>
+			<tbody>
+			<tr>
+				<td class="view">
+					<div style="width:300px;height:200px;background:#666;color:#ddd" id="gflip1" class="testBox">
+						dojox.fx.flipGrid
+					</div>
+				<td>
+				<div class="controls">
+					<div class="middle">
+						<div style="position:absolute;left:60px;top:0"><input type="button" class="button" id="flipGrid" value="flip grid" /></div>
+						<div style="position:absolute;right:60px;top:0"><input type="button" class="button" id="reset" value="reset" /></div>
+					</div>
+				</div>
+				</td>
+			</tr>
+			</tbody>
+			<thead>
+				<tr><th class="view">dojox.fx.flipPage test</th><th></th></tr>
+			</thead>
+			<tbody>
+			<tr>
+				<td class="view" style="padding-left:20px">
+					<table style="height:300px; width:400px; border-collapse:collapse">
+						<tbody>
+							<tr>
+								<td>
+									<div id="pageContainer0" class="pageContainer">
+										<div style="display:none" id="page2" class="page">
+											Ed una lupa, che di tutte brame
+											sembiava carca ne la sua magrezza,
+											e molte genti fé già viver grame,
+											questa mi porse tanto di gravezza
+											con la paura ch'uscia di sua vista,
+											ch'io perdei la speranza de l'altezza.
+											E qual è quei che volontieri acquista,
+											e giugne 'l tempo che perder lo face,
+											che 'n tutt'i suoi pensier piange e s'attrista;
+											tal mi fece la bestia sanza pace,
+											che, venendomi 'ncontro, a poco a poco
+											mi ripigneva là dove 'l sol tace.
+											Mentre ch'i' rovinava in basso loco,
+											dinanzi a li occhi mi si fu offerto
+											chi per lungo silenzio parea fioco.
+											Quando vidi costui nel gran diserto,
+											«Miserere di me», gridai a lui,
+											«qual che tu sii, od ombra od omo certo!».
+											Rispuosemi: «Non omo, omo già fui,
+											e li parenti miei furon lombardi,
+											mantoani per patria ambedui.
+											Nacqui sub Iulio, ancor che fosse tardi,
+											e vissi a Roma sotto 'l buono Augusto
+											nel tempo de li dèi falsi e bugiardi.
+											Poeta fui, e cantai di quel giusto [...]
+										</div>
+										<div class="page" id="page0">
+											Nel mezzo del cammin di nostra vita
+											mi ritrovai per una selva oscura
+											ché la diritta via era smarrita.
+											Ahi quanto a dir qual era è cosa dura
+											esta selva selvaggia e aspra e forte
+											che nel pensier rinova la paura!
+											Tant'è amara che poco è più morte;
+											ma per trattar del ben ch'i' vi trovai,
+											dirò de l'altre cose ch'i' v'ho scorte.
+											Io non so ben ridir com'i' v'intrai,
+											tant'era pien di sonno a quel punto
+											che la verace via abbandonai.
+											Ma poi ch'i' fui al piè d'un colle giunto,
+											là dove terminava quella valle
+											che m'avea di paura il cor compunto,
+											guardai in alto, e vidi le sue spalle
+											vestite già de' raggi del pianeta
+											che mena dritto altrui per ogne calle.
+											Allor fu la paura un poco queta
+											che nel lago del cor m'era durata
+											la notte ch'i' passai con tanta pieta.
+											E come quei che con lena affannata
+											uscito fuor del pelago a la riva
+											si volge a l'acqua perigliosa e guata,
+											così l'animo mio, ch'ancor fuggiva,
+										</div>
+									</div>
+								</td>
+								<td>
+									<div id="pageContainer1" class="pageContainer">
+										<div style="display:none;" id="page3" class="page"></div>
+										<div id="page1" class="page">
+											si volse a retro a rimirar lo passo
+											che non lasciò già mai persona viva.
+											Poi ch'èi posato un poco il corpo lasso,
+											ripresi via per la piaggia diserta,
+											sì che 'l piè fermo sempre era 'l più basso.
+											Ed ecco, quasi al cominciar de l'erta,
+											una lonza leggera e presta molto,
+											che di pel macolato era coverta;
+											e non mi si partia dinanzi al volto,
+											anzi 'mpediva tanto il mio cammino,
+											ch'i' fui per ritornar più volte vòlto.
+											Temp'era dal principio del mattino,
+											e 'l sol montava 'n sù con quelle stelle
+											ch'eran con lui quando l'amor divino
+											mosse di prima quelle cose belle;
+											sì ch'a bene sperar m'era cagione
+											di quella fiera a la gaetta pelle
+											l'ora del tempo e la dolce stagione;
+											ma non sì che paura non mi desse
+											la vista che m'apparve d'un leone.
+											Questi parea che contra me venisse
+											con la test'alta e con rabbiosa fame,
+											sì che parea che l'aere ne tremesse.
+										</div>
+									</div>
+								</td>
+							</tr>
+					</tbody>
+					</table>
+				</td>
+				<td>
+					<div class="middle">
+						<div style="position:absolute;left:30px;top:0"><input type="button" class="button" value="previous page" id="flipPageLeft" /></div>
+						<div style="position:absolute;right:30px;top:0"><input type="button" class="button" id="flipPageRight" value="next page" /></div>
+					</div>
+				</td>
+			</tr>
+			</tbody>
+		</table>
 
 </body>
 </html>
diff --git a/dojox/fx/tests/test_scroll.html b/dojox/fx/tests/test_scroll.html
index c4d7712..a04e799 100644
--- a/dojox/fx/tests/test_scroll.html
+++ b/dojox/fx/tests/test_scroll.html
@@ -20,8 +20,7 @@
 				var anim = dojox.fx.smoothScroll({
 					node: node,
 					win:window,
-					duration:300,
-					easing:dojo.fx.easing.easeOut
+					duration:300
 				}).play();
 				return;
 			});
@@ -38,13 +37,13 @@
 
 			dojo.connect(dojo.byId("goToHeader"), "onclick", function (e) {
 				var node = dojo.byId('targetHeader3');
-				var anim0 = dojox.fx.smoothScroll({ node: node, win: window, duration:500, easing:dojo.fx.easing.easeOut });
+				var anim0 = dojox.fx.smoothScroll({ node: node, win: window, duration:500});
 				anim0.play();
 			});
 
 			dojo.connect(dojo.byId("goToHeader1"), "onclick", function(/* Event */e){
 				var node = dojo.byId('targetHeader1');
-				var anim0 = dojox.fx.smoothScroll({ node: node, win: window, duration:1000, easing:dojo.fx.easing.easeOut });
+				var anim0 = dojox.fx.smoothScroll({ node: node, win: window, duration:1000});
 				anim0.play();
 			});
 		}); 
diff --git a/dojox/fx/tests/test_sizeTo.html b/dojox/fx/tests/test_sizeTo.html
index ba4df7f..2b7b19a 100644
--- a/dojox/fx/tests/test_sizeTo.html
+++ b/dojox/fx/tests/test_sizeTo.html
@@ -5,7 +5,6 @@
 	<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="../_base.js"></script>
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/themes/dijit.css";
diff --git a/dojox/fx/tests/test_split.html b/dojox/fx/tests/test_split.html
index 26550a5..a631478 100644
--- a/dojox/fx/tests/test_split.html
+++ b/dojox/fx/tests/test_split.html
@@ -6,8 +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" djConfig="parseOnLoad:true, isDebug:false"></script>
 		
 	<script type="text/javascript">
 		dojo.require("dojox.fx.split");
diff --git a/dojox/fx/tests/test_wipeTo.html b/dojox/fx/tests/test_wipeTo.html
index 539453b..109edb8 100644
--- a/dojox/fx/tests/test_wipeTo.html
+++ b/dojox/fx/tests/test_wipeTo.html
@@ -1,11 +1,10 @@
 <!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>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="../_base.js"></script>
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/themes/dijit.css";
@@ -18,13 +17,14 @@
 			background:#ededed;
 			border:1px solid #b7b7b7;
 			-moz-border-radius:6pt;
-			-webkit-border-radius:5pt;      
+			-webkit-border-radius:5pt;		
 		}
 	</style>
-        <script type="text/javascript">
-			dojo.require("dojox.fx.ext-dojo.NodeList");
-			dojo.require("dojox.fx");
+		<script type="text/javascript">
+			dojo.require("dojo.parser");
 			dojo.require("dojo.fx");
+			dojo.require("dojox.fx");
+			dojo.require("dojox.fx.ext-dojo.NodeList");
 			dojo.require("dijit.form.Button");
 			var delayAnims = function(obj){
 				console.log('yo');
@@ -36,24 +36,23 @@
 					);
 				});
 				console.log(_anims);
-				dojo.fx.combine(_anims).play();
-				
+				dojo.fx.combine(_anims).play();				
 			}
-        </script>
+		</script>
 </head>
 <body class="tundra">
 	<h1 class="testTitle">dojox.fx.wipeTo test</h1>
-        
-        <p>quick sizeTo API overview:</p>
+		
+		<p>quick sizeTo API overview:</p>
 
-        <pre>
-        dojox.fx.wipeTo({
-                // basic requirements:
-                node: "aDomNodeId", // or a domNode reference        
-                width: 200 // measured in px
-                // height: 200 // measured in px (only one at a time, see sizeTo)         
-        });
-        </pre>
+		<pre>
+		dojox.fx.wipeTo({
+				// basic requirements:
+				node: "aDomNodeId", // or a domNode reference		 
+				width: 200 // measured in px
+				// height: 200 // measured in px (only one at a time, see sizeTo)		  
+		});
+		</pre>
 
 		<p>Some test boxes: (id="box1,box2,box3" etc ...)</p>
 
@@ -101,8 +100,8 @@
 		</div>
 
 
-        <br style="clear:both;">
-        
+		<br style="clear:both;">
+		
 	<br>
 
 </body>
diff --git a/dojox/fx/text.js b/dojox/fx/text.js
index 4fa7a05..2079441 100644
--- a/dojox/fx/text.js
+++ b/dojox/fx/text.js
@@ -1,10 +1,7 @@
-dojo.provide("dojox.fx.text");
-
-// dojo.require("dojox.fx._split");
-dojo.require("dojo.fx");
-dojo.require("dojo.fx.easing");
-
-dojox.fx.text._split = function(/*Object*/ args){
+define(["dojo/_base/lang", "./_base", "dojo/_base/fx", "dojo/fx","dojo/fx/easing", "dojo/dom", "dojo/dom-style", "dojo/_base/html", "dojo/_base/connect"],
+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
 	//
 	// description:
@@ -25,10 +22,10 @@ dojox.fx.text._split = function(/*Object*/ args){
 	//			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 = dojo.byId(args.node),
+	var node = args.node = dom.byId(args.node),
 		s = node.style,
-		cs = dojo.getComputedStyle(node),
-		nodeCoords = dojo.coords(node, true);
+		cs = domStyle.getComputedStyle(node),
+		nodeCoords = htmlLib.coords(node, true);
 		
 	args.duration = args.duration || 1000;
 	args.words = args.words || false;
@@ -38,7 +35,7 @@ dojox.fx.text._split = function(/*Object*/ args){
 		originalWidth = s.width,
 		animations = [];
 
-	dojo.style(node, {
+	domStyle.set(node, {
 		height: cs.height,
 		width: cs.width
 	});
@@ -73,9 +70,9 @@ dojox.fx.text._split = function(/*Object*/ args){
 	function animatePieces(piece){
 		var next = piece.nextSibling;
 		if(piece.tagName == "SPAN" && piece.childNodes.length == 1 && piece.firstChild.nodeType == 3){
-			var pieceCoords = dojo.coords(piece, true);
+			var pieceCoords = htmlLib.coords(piece, true);
 			number++;
-			dojo.style(piece, {
+			domStyle.set(piece, {
 				padding: 0,
 				margin: 0,
 				top: (args.crop ? "0px" : pieceCoords.t + "px"),
@@ -83,7 +80,7 @@ dojox.fx.text._split = function(/*Object*/ args){
 				display: "inline"
 			});
 			var pieceAnimation = args.pieceAnimation(piece, pieceCoords, nodeCoords, number, numPieces);
-			if(dojo.isArray(pieceAnimation)){
+			if(lang.isArray(pieceAnimation)){
 				// if pieceAnimation is an array, append its elements
 				animations = animations.concat(pieceAnimation);
 			}else{
@@ -100,24 +97,24 @@ dojox.fx.text._split = function(/*Object*/ args){
 	}
 
 	animatePieces(node.firstChild);
-	var anim = dojo.fx.combine(animations);
-	dojo.connect(anim, "onEnd", anim, function(){
+	var anim = coreFx.combine(animations);
+	connectUtil.connect(anim, "onEnd", anim, function(){
 		node.innerHTML = originalHTML;
-		dojo.style(node, {
+		domStyle.set(node, {
 			height: originalHeight,
 			width: originalWidth
 		});
 	});
 	if(args.onPlay){
-		dojo.connect(anim, "onPlay", anim, args.onPlay);
+		connectUtil.connect(anim, "onPlay", anim, args.onPlay);
 	}
 	if(args.onEnd){
-		dojo.connect(anim, "onEnd", anim, args.onEnd);
+		connectUtil.connect(anim, "onEnd", anim, args.onEnd);
 	}
 	return anim; // dojo.Animation
 };
 
-dojox.fx.text.explode = function(/*Object*/ args){
+textFx.explode = function(/*Object*/ args){
 	// summary: Explode a block of text into words or letters
 	//
 	// description:
@@ -137,7 +134,7 @@ dojox.fx.text.explode = function(/*Object*/ args){
 	//		args.sync: Boolean - If args.unhide is true, all the pieces converge at the same time
 	//							 (default is true)
 
-	var node = args.node = dojo.byId(args.node);
+	var node = args.node = dom.byId(args.node);
 	var s = node.style;
 
 	args.distance = args.distance || 1;
@@ -181,15 +178,15 @@ dojox.fx.text.explode = function(/*Object*/ args){
 
 		// Create the animation objects for the piece
 		// These are separate anim objects so they can have different curves
-		var pieceSlide = dojo.animateProperty({
+		var pieceSlide = baseFx.animateProperty({
 			node: piece,
 			duration: duration,
 			delay: delay,
-			easing: (args.easing || (args.unhide ? dojo.fx.easing.sinOut : dojo.fx.easing.circOut)),
+			easing: (args.easing || (args.unhide ? easingLib.sinOut : easingLib.circOut)),
 			beforeBegin: (args.unhide ? function(){
 					if(args.fade){
 						//piece.style.opacity = 0;
-						dojo.style(piece,"opacity", 0);
+						domStyle.set(piece,"opacity", 0);
 					}
 					piece.style.position = args.crop ? "relative" : "absolute";
 					piece.style.top = endTop + "px";
@@ -202,11 +199,11 @@ dojox.fx.text.explode = function(/*Object*/ args){
 		});
 
 		if(args.fade){
-			var pieceFade = dojo.animateProperty({
+			var pieceFade = baseFx.animateProperty({
 				node: piece,
 				duration: duration,
 				delay: delay,
-				easing: (args.fadeEasing || dojo.fx.easing.quadOut),
+				easing: (args.fadeEasing || easingLib.quadOut),
 				properties: {
 					opacity: (args.unhide ? {start: 0, end: 1} : {end: 0})
 				}
@@ -220,16 +217,16 @@ dojox.fx.text.explode = function(/*Object*/ args){
 		}
 	};
 
-	var anim = dojox.fx.text._split(args);
+	var anim = textFx._split(args);
 	return anim; // dojo.Animation
 };
 
-dojox.fx.text.converge = function(/*Object*/ args){
+textFx.converge = function(/*Object*/ args){
 	args.unhide = true;
-	return dojox.fx.text.explode(args);
+	return textFx.explode(args);
 };
 
-dojox.fx.text.disintegrate = function(/*Object*/ args){
+textFx.disintegrate = function(/*Object*/ args){
 	// summary: Split a block of text into words or letters and let them fall
 	//
 	// description:
@@ -247,7 +244,7 @@ dojox.fx.text.disintegrate = function(/*Object*/ args){
 	//		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 = dojo.byId(args.node);
+	var node = args.node = dom.byId(args.node);
 	var s = node.style;
 
 	args.duration = args.duration || 1500;
@@ -288,16 +285,16 @@ dojox.fx.text.disintegrate = function(/*Object*/ args){
 				properties.opacity = {end: 0};
 			}
 		}
-		var pieceAnimation = dojo.animateProperty({
+		var pieceAnimation = baseFx.animateProperty({
 			node: piece,
 			duration: duration,
 			delay: delay,
-			easing: (args.easing || (args.unhide ? dojo.fx.easing.sinIn : dojo.fx.easing.circIn)),
+			easing: (args.easing || (args.unhide ? easingLib.sinIn : easingLib.circIn)),
 			properties: properties,
 			beforeBegin: (args.unhide ? function(){
 				if(args.fade){
 					// piece.style.opacity = 0;
-					dojo.style(piece, "opacity", 0);
+					domStyle.set(piece, "opacity", 0);
 				}
 				piece.style.position = args.crop ? "relative" : "absolute";
 				piece.style.top = properties.top.start + "px";
@@ -307,16 +304,16 @@ dojox.fx.text.disintegrate = function(/*Object*/ args){
 		return pieceAnimation;
 	};
 
-	var anim = dojox.fx.text._split(args);
+	var anim = textFx._split(args);
 	return anim; // dojo.Animation
 };
 
-dojox.fx.text.build = function(/*Object*/ args){
+textFx.build = function(/*Object*/ args){
 	args.unhide = true;
-	return dojox.fx.text.disintegrate(args);
+	return textFx.disintegrate(args);
 };
 
-dojox.fx.text.blockFadeOut = function(/*Object*/ args){
+textFx.blockFadeOut = function(/*Object*/ args){
 	// summary: Split a block of text into words or letters and fade them
 	//
 	// description:
@@ -331,7 +328,7 @@ dojox.fx.text.blockFadeOut = function(/*Object*/ args){
 	//		args.reverseOrder: Boolean - If true, pieces animate in reversed order
 	//		args.unhide: Boolean - If true, the animation is reversed
 
-	var node = args.node = dojo.byId(args.node);;
+	var node = args.node = dom.byId(args.node);;
 	var s = node.style;
 
 	args.duration = args.duration || 1000;
@@ -350,30 +347,30 @@ dojox.fx.text.blockFadeOut = function(/*Object*/ args){
 		var delay = randomDelay * random + Math.max(1 - random, 0) * uniformDelay;
 
 		// Create the animation object for the piece
-		var pieceAnimation = dojo.animateProperty({
+		var pieceAnimation = baseFx.animateProperty({
 			node: piece,
 			duration: duration,
 			delay: delay,
-			easing: (args.easing || dojo.fx.easing.sinInOut),
+			easing: (args.easing || easingLib.sinInOut),
 			properties: {
 				opacity: (args.unhide ? {start: 0, end: 1} : {end:0})
 			},
-			beforeBegin: (args.unhide ? function(){ dojo.style(piece,"opacity",0); } : undefined)
+			beforeBegin: (args.unhide ? function(){ domStyle.set(piece,"opacity",0); } : undefined)
 		});
 
 		return pieceAnimation;
 	};
 
-	var anim = dojox.fx.text._split(args);
+	var anim = textFx._split(args);
 	return anim; // dojo.Animation
 };
 
-dojox.fx.text.blockFadeIn = function(/*Object*/ args){
+textFx.blockFadeIn = function(/*Object*/ args){
 	args.unhide = true;
-	return dojox.fx.text.blockFadeOut(args);
+	return textFx.blockFadeOut(args);
 };
 
-dojox.fx.text.backspace = function(/*Object*/ args){
+textFx.backspace = function(/*Object*/ args){
 	// summary: Split a block of text into words or letters and backspace them in sequence
 	//
 	// description:
@@ -391,7 +388,7 @@ dojox.fx.text.backspace = function(/*Object*/ args){
 	//							   randomness is introduced (only effective when args.unhide = true)
 	//		args.unhide: Boolean - If true, the animation is reversed
 
-	var node = args.node = dojo.byId(args.node);
+	var node = args.node = dom.byId(args.node);
 	var s = node.style;
 
 	args.words = false;
@@ -418,7 +415,7 @@ dojox.fx.text.backspace = function(/*Object*/ args){
 
 		if(args.fixed){
 			if(args.unhide){
-				var beforeBegin = function(){ dojo.style(piece,"opacity",0); };
+				var beforeBegin = function(){ domStyle.set(piece,"opacity",0); };
 			}
 		}else{
 			if(args.unhide){
@@ -430,11 +427,11 @@ dojox.fx.text.backspace = function(/*Object*/ args){
 		}
 
 		// Create the animation object for the piece
-		var pieceAnimation = dojo.animateProperty({
+		var pieceAnimation = baseFx.animateProperty({
 			node: piece,
 			duration: 1,
 			delay: delay,
-			easing: (args.easing || dojo.fx.easing.sinInOut),
+			easing: (args.easing || easingLib.sinInOut),
 			properties: {
 				opacity: (args.unhide ? {start: 0, end: 1} : {end:0})
 			},
@@ -453,11 +450,13 @@ dojox.fx.text.backspace = function(/*Object*/ args){
 		return pieceAnimation;
 	};
 
-	var anim = dojox.fx.text._split(args);
+	var anim = textFx._split(args);
 	return anim; // dojo.Animation
 };
 
-dojox.fx.text.type = function(/*Object*/ args){
+textFx.type = function(/*Object*/ args){
 	args.unhide = true;
-	return dojox.fx.text.backspace(args);
-};
\ No newline at end of file
+	return textFx.backspace(args);
+};
+return textFx;
+});
\ No newline at end of file
diff --git a/dojox/gantt/GanttProjectItem.js b/dojox/gantt/GanttProjectItem.js
index dcdbbd7..531b613 100644
--- a/dojox/gantt/GanttProjectItem.js
+++ b/dojox/gantt/GanttProjectItem.js
@@ -2,6 +2,7 @@ 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){
diff --git a/dojox/gantt/GanttResourceItem.js b/dojox/gantt/GanttResourceItem.js
index 937f33b..fe10720 100644
--- a/dojox/gantt/GanttResourceItem.js
+++ b/dojox/gantt/GanttResourceItem.js
@@ -25,7 +25,9 @@ dojo.declare("dojox.gantt.GanttResourceItem", null, {
 		this.ownerTimeConsume = {};
 	},
 	clearItems: function(){
-		dojo.destroy(this.content.firstChild);
+		if(this.content.firstChild){
+		    dojo.destroy(this.content.firstChild);
+		}
 	},
 	buildResource: function(){
 		var resourceInfo = {};
@@ -164,8 +166,8 @@ dojo.declare("dojox.gantt.GanttResourceItem", null, {
 			this.ownerNameItem.push(oNameItem);
 			this.ownerTaskNodeMapping[owner][owner].push(oNameItem);
 		}
-		var currentOwnerNode = this.ownerItem[this.ownerNameItem.length - 1];
-		var currentOwnerNameNode = this.ownerNameItem[this.ownerNameItem.length - 1];
+		var currentOwnerNode = this.ownerItem[this.ownerNameItem.length - 1],
+			currentOwnerNameNode = this.ownerNameItem[this.ownerNameItem.length - 1];
 		//adjust nodes
 		if(this.panelNames){
 			this.checkWidthTaskNameItem(currentOwnerNameNode);
@@ -192,9 +194,9 @@ dojo.declare("dojox.gantt.GanttResourceItem", null, {
 		return ownerName;
 	},
 	refreshOwnerItem: function(owner){
-		var item = this.ownerTaskNodeMapping[owner][owner][0];
-		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 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){
@@ -309,7 +311,7 @@ dojo.declare("dojox.gantt.GanttResourceItem", null, {
 		lineVerticalLeft.pNode = parentNode;
 		var LineHorizontalLeft = dojo.create("div", {
 			noShade: true,
-			color: "#000000",
+			color: "#000",
 			className: "ganttResourceLineHorizontalLeft"
 		}, this.panelNames.firstChild);
 		LineHorizontalLeft.cNode = currentNode;
@@ -329,27 +331,28 @@ dojo.declare("dojox.gantt.GanttResourceItem", null, {
 		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
-						var reachTarget = false;
-						for(var owner in this.ownerTaskNodeMapping){
-							var ownerItem = this.ownerTaskNodeMapping[owner];
+						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");
-								}, this);
+								});
 								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");
-										}, this);
-									}, this);
-								}, this);
+										});
+									});
+								});
 							}else{
 								if(owner == ownerNameItem.id){
 									reachTarget = true;
@@ -366,21 +369,20 @@ dojo.declare("dojox.gantt.GanttResourceItem", null, {
 						dojo.addClass(treeImg, "ganttImageTreeCollapse");
 						currentItem.isOpen = true;
 						//expand
-						var reachTarget = false;
-						for(var owner in this.ownerTaskNodeMapping){
-							var ownerItem = this.ownerTaskNodeMapping[owner];
+						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");
-								}, this);
+								});
 								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");
-										}, this);
-									}, this);
-								}, this);
+										});
+									});
+								});
 							}else{
 								if(owner == ownerNameItem.id){
 									reachTarget = true;
@@ -426,11 +428,10 @@ dojo.declare("dojox.gantt.GanttResourceItem", null, {
 	},
 	checkWidthTaskNameItem: function(taskNameItem){
 		if(taskNameItem && taskNameItem.offsetWidth + taskNameItem.offsetLeft > this.ganttChart.maxWidthPanelNames){
-			var width = taskNameItem.offsetWidth + taskNameItem.offsetLeft - this.ganttChart.maxWidthPanelNames;
-			var countChar = Math.round(width / (taskNameItem.offsetWidth / taskNameItem.firstChild.length));
-			var tName = taskNameItem.id.substring(0, taskNameItem.firstChild.length - countChar - 3);
-			tName += "...";
-			taskNameItem.innerHTML = tName;
+			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(){
diff --git a/dojox/gantt/GanttTaskItem.js b/dojox/gantt/GanttTaskItem.js
index c792e01..2bdac85 100644
--- a/dojox/gantt/GanttTaskItem.js
+++ b/dojox/gantt/GanttTaskItem.js
@@ -1,6 +1,7 @@
 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){
diff --git a/dojox/gauges/AnalogArcIndicator.js b/dojox/gauges/AnalogArcIndicator.js
new file mode 100644
index 0000000..5979f15
--- /dev/null
+++ b/dojox/gauges/AnalogArcIndicator.js
@@ -0,0 +1,92 @@
+define(["dojo/_base/declare","dojo/_base/lang","dojo/_base/connect","dojo/_base/fx","./AnalogIndicatorBase"],
+function(declare, lang, connect, fx, AnalogIndicatorBase) { 
+
+/*=====
+	AnalogIndicatorBase = dojox.gauges.AnalogIndicatorBase;
+=====*/
+
+return declare("dojox.gauges.AnalogArcIndicator",[AnalogIndicatorBase],{
+	
+	// summary:
+	//		An indicator for the AnalogGauge that draws a segment of arc.
+	//		The segment of arc starts at the start angle of the gauge and ends at the
+	//		angle that corresponds to the value of the indicator.
+	
+	_createArc: function(val){
+		
+		// Creating the Arc Path string manually.  This is instead of creating new dojox.gfx.Path object
+		// each time since we really just need the Path string (to use with setShape) and we don't want to
+		// have to redo the connects, etc.
+		if(this.shape){
+			var startAngle = this._gauge._mod360(this._gauge.startAngle);
+			var a = this._gauge._getRadians(this._gauge._getAngle(val));
+			var sa = this._gauge._getRadians(startAngle);
+
+			if (this._gauge.orientation == 'cclockwise'){
+				var tmp = a;
+				a = sa;
+				sa = tmp;
+			}
+
+			var arange;
+			var big = 0;
+			if (sa<=a)
+				arange = a-sa;
+			else
+				arange = 2*Math.PI+a-sa;
+			if(arange>Math.PI){big=1;}
+			
+			var cosa = Math.cos(a);
+			var sina = Math.sin(a);
+			var cossa = Math.cos(sa);
+			var sinsa = Math.sin(sa);
+			var off = this.offset + this.width;
+			var p = ['M'];
+			p.push(this._gauge.cx+this.offset*sinsa);
+			p.push(this._gauge.cy-this.offset*cossa);
+			p.push('A', this.offset, this.offset, 0, big, 1);
+			p.push(this._gauge.cx+this.offset*sina);
+			p.push(this._gauge.cy-this.offset*cosa);
+			p.push('L');
+			p.push(this._gauge.cx+off*sina);
+			p.push(this._gauge.cy-off*cosa);
+			p.push('A', off, off, 0, big, 0);
+			p.push(this._gauge.cx+off*sinsa);
+			p.push(this._gauge.cy-off*cossa);
+			p.push('z');
+			this.shape.setShape(p.join(' '));
+			this.currentValue = val;
+		}
+	},
+	draw: function(group, /*Boolean?*/ dontAnimate){
+		// summary:
+		//		Override of dojox.gauges._Indicator.draw
+		var v = this.value;
+		if(v < this._gauge.min){v = this._gauge.min;}
+		if(v > this._gauge.max){v = this._gauge.max;}
+		if(this.shape){
+			if(dontAnimate){
+				this._createArc(v);
+			}else{
+				var anim = new fx.Animation({curve: [this.currentValue, v], duration: this.duration, easing: this.easing});
+				connect.connect(anim, "onAnimate", lang.hitch(this, this._createArc));
+				anim.play();
+			}
+		}else{
+			var color = this.color ? this.color : 'black';
+			var strokeColor = this.strokeColor ? this.strokeColor : color;
+			var stroke = {color: strokeColor, width: 1};
+			if(this.color.type && !this.strokeColor){
+				stroke.color = this.color.colors[0].color;
+			}
+			this.shape = group.createPath().setStroke(stroke).setFill(color);
+			this._createArc(v);
+			this.shape.connect("onmouseover", this, this.handleMouseOver);
+			this.shape.connect("onmouseout", this,  this.handleMouseOut);
+			this.shape.connect("onmousedown", this, this.handleMouseDown);
+			this.shape.connect("touchstart", this, this.handleTouchStart);
+		}
+	}
+});
+
+});
diff --git a/dojox/gauges/AnalogArrowIndicator.js b/dojox/gauges/AnalogArrowIndicator.js
new file mode 100644
index 0000000..08c186e
--- /dev/null
+++ b/dojox/gauges/AnalogArrowIndicator.js
@@ -0,0 +1,52 @@
+define(["dojo/_base/declare","./AnalogIndicatorBase"],
+function(declare, AnalogIndicatorBase) { 
+
+/*=====
+	AnalogIndicatorBase = dojox.gauges.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.
+	
+	_getShapes: function(group){
+		// summary:
+		//		Override of dojox.gauges.AnalogLineIndicator._getShapes
+		if(!this._gauge){
+			return null;
+		}
+		var color = this.color ? this.color : 'black';
+		var strokeColor = this.strokeColor ? this.strokeColor : color;
+		var stroke = { color: strokeColor, width: 1};
+		if (this.color.type && !this.strokeColor){
+			stroke.color = this.color.colors[0].color;
+		}
+			
+		var x = Math.floor(this.width/2);
+		var head = this.width * 5;
+		var odd = (this.width & 1);
+		var shapes = [];
+		var points = [{x:-x,	 y:0},
+					  {x:-x,	 y:-this.length+head},
+					  {x:-2*x,	 y:-this.length+head},
+					  {x:0,		 y:-this.length},
+					  {x:2*x+odd,y:-this.length+head},
+					  {x:x+odd,	 y:-this.length+head},
+					  {x:x+odd,	 y:0},
+					  {x:-x,	 y:0}];
+		shapes[0] = group.createPolyline(points)
+					.setStroke(stroke)
+					.setFill(color);
+		shapes[1] = group.createLine({ x1:-x, y1: 0, x2: -x, y2:-this.length+head })
+					.setStroke({color: this.highlight});
+		shapes[2] = group.createLine({ x1:-x-3, y1: -this.length+head, x2: 0, y2:-this.length })
+					.setStroke({color: this.highlight});
+		shapes[3] = group.createCircle({cx: 0, cy: 0, r: this.width})
+					.setStroke(stroke)
+					.setFill(color);
+		return shapes;
+	}
+});
+});
\ No newline at end of file
diff --git a/dojox/gauges/AnalogCircleIndicator.js b/dojox/gauges/AnalogCircleIndicator.js
new file mode 100644
index 0000000..5e0891f
--- /dev/null
+++ b/dojox/gauges/AnalogCircleIndicator.js
@@ -0,0 +1,35 @@
+define(["dojo/_base/declare","./AnalogIndicatorBase"],
+  function(declare, AnalogIndicatorBase) { 
+
+/*=====
+	AnalogIndicatorBase = dojox.gauges.AnalogIndicatorBase;
+=====*/
+
+return declare("dojox.gauges.AnalogCircleIndicator", [AnalogIndicatorBase], {
+	// summary:
+	//		An indicator for the AnalogGauge that draws a circle. The center of the circle is positioned
+	//		on the circular gauge according to the value of the indicator. The circle has for radius the 
+	//		length of the indicator. This indicator is mainly used to draw round ticks for the scale.
+	
+	
+	_getShapes: function(group){
+		// summary: 
+		//		Override of dojox.gauges.AnalogLineIndicator._getShapes
+		var color = this.color ? this.color : 'black';
+		var strokeColor = this.strokeColor ? this.strokeColor : color;
+		var stroke = {
+			color: strokeColor,
+			width: 1
+		};
+		if (this.color.type && !this.strokeColor){
+			stroke.color = this.color.colors[0].color;
+		}
+		
+		return [group.createCircle({
+			cx: 0,
+			cy: -this.offset,
+			r: this.length
+		}).setFill(color).setStroke(stroke)];
+	}
+});
+});
diff --git a/dojox/gauges/AnalogGauge.js b/dojox/gauges/AnalogGauge.js
new file mode 100644
index 0000000..64dae44
--- /dev/null
+++ b/dojox/gauges/AnalogGauge.js
@@ -0,0 +1,368 @@
+define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/array","dojo/_base/lang","dojo/_base/html","dojo/_base/event",
+		"dojox/gfx", "./_Gauge","./AnalogLineIndicator", "dojo/dom-geometry"],
+	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.
+	//
+	// description:
+	//		using dojo.gfx (and thus either SVG or VML based on what is supported), this widget
+	//		builds a gauge component, used to display numerical data in a familiar format 
+	//
+	// example:
+	//	|	<script type="text/javascript">
+	//	|		require(["dojox/gauges/AnalogGauge"]);
+	//	|	</script>
+	//	|
+	//	|	<div	dojoType="dojox.gauges.AnalogGauge"
+	//	|			id="testGauge"
+	//	|			width="300"
+	//	|			height="200"
+	//	|			cx=150
+	//	|			cy=175
+	//	|			radius=125
+	//	|			image="gaugeOverlay.png"
+	//	|			imageOverlay="false"
+	//	|			imageWidth="280"
+	//	|			imageHeight="155"
+	//	|			imageX="12"
+	//	|			imageY="38">
+	//	|	</div>
+
+	// startAngle: Number
+	// 		angle (in degrees) for start of gauge (default is -90)
+	startAngle: -90,
+
+	// endAngle: Number
+	// 		angle (in degrees) for end of gauge (default is 90)
+	endAngle: 90,
+
+	// cx: Number
+	// 		center of gauge x coordinate (default is gauge width / 2)
+	cx: 0,
+
+	// cy: Number
+	// 		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: 0,
+	
+	// orientation: String
+	// 		The orientation of the gauge. The value can be 'clockwise' or 'cclockwise' (default is 'clockwise')
+	orientation: "clockwise",
+
+	// _defaultIndicator: dojox.gauges._Indicator
+	//		override of dojox.gauges._Gauge._defaultIndicator
+	_defaultIndicator: AnalogLineIndicator,
+
+	startup: function(){
+		// handle settings from HTML by making sure all the options are
+		// converted correctly to numbers and that we calculate defaults
+		// for cx, cy and radius
+		// also connects mouse handling events
+
+		if(this.getChildren){
+			arr.forEach(this.getChildren(), function(child){ child.startup(); });
+		}
+
+		this.startAngle = Number(this.startAngle);
+		this.endAngle = Number(this.endAngle);
+
+		this.cx = Number(this.cx);
+		if(!this.cx){this.cx = this.width/2;}
+		this.cy = Number(this.cy);
+		if(!this.cy){this.cy = this.height/2;}
+		this.radius = Number(this.radius);
+		if(!this.radius){this.radius = Math.min(this.cx,this.cy) - 25;}
+	
+
+		this.inherited(arguments);
+	},
+
+	_getAngle: function(/*Number*/value){
+		// summary:
+		//		This is a helper function used to determine the angle that represents
+		//		a given value on the gauge
+		// value:	Number
+		//		A value to be converted to an angle for this gauge.
+		
+		var v = Number(value);
+		var angle;
+		if (value == null || isNaN(v) || v <= this.min) 
+			angle = this._mod360(this.startAngle);
+		else
+			if (v >= this.max) 
+				angle = this._mod360(this.endAngle);
+			else {
+				var startAngle = this._mod360(this.startAngle);
+				var relativeValue = (v - this.min);
+				if (this.orientation != 'clockwise') 
+					relativeValue = -relativeValue;
+
+				angle = this._mod360(startAngle + this._getAngleRange() * relativeValue / Math.abs(this.min - this.max));
+			}
+
+		return angle;
+	},
+
+	_getValueForAngle: function(/*Number*/angle){
+		// summary:
+		//		This is a helper function used to determine the value represented by a
+		//		given angle on the gauge
+		// angle:	Number
+		//		A angle to be converted to a value for this gauge.
+		var startAngle = this._mod360(this.startAngle);
+		var endAngle = this._mod360(this.endAngle);
+
+		if (!this._angleInRange(angle)){
+
+			var min1 = this._mod360(startAngle - angle);
+			var min2 = 360 - min1;
+			var max1 = this._mod360(endAngle - angle);
+			var max2 = 360 - max1;
+			if (Math.min(min1, min2) < Math.min(max1, max2)) 
+				return this.min;
+			else 
+				return this.max;
+		}
+		else {
+			var range = Math.abs(this.max - this.min);
+			var relativeAngle = this._mod360(this.orientation == 'clockwise' ?
+				(angle - startAngle): (-angle + startAngle));
+			return this.min + range * relativeAngle / this._getAngleRange();
+		}
+	},
+
+	_getAngleRange: function(){
+		// summary:
+		//		This is a helper function that returns the angle range
+		//      from startAngle to endAngle according to orientation.
+		var range;
+		var startAngle = this._mod360(this.startAngle);
+		var endAngle = this._mod360(this.endAngle);
+		if (startAngle == endAngle) 
+			return 360;
+		if (this.orientation == 'clockwise'){
+			if (endAngle < startAngle) 
+				range = 360 - (startAngle - endAngle);
+			else 
+				range = endAngle - startAngle;
+		}
+		else {
+			if (endAngle < startAngle) 
+				range = startAngle - endAngle;
+			else 
+				range = 360 - (endAngle - startAngle); 
+		}
+		return range;
+	},
+	
+	_angleInRange: function(value){
+		// summary:
+		//		Test if the angle value is in the startAngle/endAngle range
+		var startAngle = this._mod360(this.startAngle);
+		var endAngle = this._mod360(this.endAngle);
+		if (startAngle == endAngle) 
+			return true;
+			value = this._mod360(value);
+		if (this.orientation == "clockwise"){
+			if (startAngle < endAngle) 
+				return value >= startAngle && value <= endAngle;
+			else 
+				return !(value > endAngle && value < startAngle);
+		}
+		else {
+			if (startAngle < endAngle) 
+				return !(value > startAngle && value < endAngle);
+			else 
+				return value >= endAngle && value <= startAngle;
+		}
+	},
+	
+	_isScaleCircular: function(){
+		// 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;
+		while (v>360) v = v - 360;
+		while (v<0) v = v + 360;
+		return v;
+	},
+
+	_getRadians: function(/*Number*/angle){
+		// summary:
+		//		This is a helper function than converts degrees to radians
+		// angle:	Number
+		//		An angle, in degrees, to be converted to radians.
+		return angle*Math.PI/180;
+	},
+
+	_getDegrees: function(/*Number*/radians){
+		// summary:
+		//		This is a helper function that converts radians to degrees
+		// radians:	Number
+		//		An angle, in radians, to be converted to degrees.
+		return radians*180/Math.PI;
+	},
+
+
+	drawRange: function(/*dojox.gfx.Group*/ group, /*Object*/range){
+		// summary:
+		//		This function is used to draw (or redraw) a range
+		// description:
+		//		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.
+		// range:
+		//		A range is a dojox.gauges.Range or an object
+		//		with similar parameters (low, high, hover, etc.).
+		var path;
+		if(range.shape){
+			range.shape.parent.remove(range.shape);
+			range.shape = null;
+		}
+		var a1, a2;
+		if((range.low == this.min) && (range.high == this.max) && ((this._mod360(this.endAngle) == this._mod360(this.startAngle)))){
+			path = group.createCircle({cx: this.cx, cy: this.cy, r: this.radius});
+		}else{
+			
+			
+			a1 = this._getRadians(this._getAngle(range.low));
+			a2 = this._getRadians(this._getAngle(range.high));
+			if (this.orientation == 'cclockwise')
+			{
+				var a = a2;
+				a2 = a1;
+				a1 = a;
+			}
+			
+			var x1=this.cx+this.radius*Math.sin(a1),
+				y1=this.cy-this.radius*Math.cos(a1),
+				x2=this.cx+this.radius*Math.sin(a2),
+				y2=this.cy-this.radius*Math.cos(a2),
+				big=0
+			;
+			
+			var arange;
+			if (a1<=a2)
+			   arange = a2-a1;
+			else
+			   arange = 2*Math.PI-a1+a2;
+			if(arange>Math.PI){big=1;}
+			
+			path = group.createPath();
+			if(range.size){
+				path.moveTo(this.cx+(this.radius-range.size)*Math.sin(a1),
+							this.cy-(this.radius-range.size)*Math.cos(a1));
+			}else{
+				path.moveTo(this.cx,this.cy);
+			}
+			path.lineTo(x1,y1);
+			path.arcTo(this.radius,this.radius,0,big,1,x2,y2);
+			if(range.size){
+				path.lineTo(this.cx+(this.radius-range.size)*Math.sin(a2),
+							this.cy-(this.radius-range.size)*Math.cos(a2));
+				path.arcTo((this.radius-range.size),(this.radius-range.size),0,big,0,
+							this.cx+(this.radius-range.size)*Math.sin(a1),
+							this.cy-(this.radius-range.size)*Math.cos(a1));
+			}
+			path.closePath();
+		}
+
+		if(lang.isArray(range.color) || lang.isString(range.color)){
+			path.setStroke({color: range.color});
+			path.setFill(range.color);
+		}else if(range.color.type){
+			// Color is a gradient
+			a1 = this._getRadians(this._getAngle(range.low));
+			a2 = this._getRadians(this._getAngle(range.high));
+			range.color.x1 = this.cx+(this.radius*Math.sin(a1))/2;
+			range.color.x2 = this.cx+(this.radius*Math.sin(a2))/2;
+			range.color.y1 = this.cy-(this.radius*Math.cos(a1))/2;
+			range.color.y2 = this.cy-(this.radius*Math.cos(a2))/2;
+			path.setFill(range.color);
+			path.setStroke({color: range.color.colors[0].color});
+		}else if (gfx.svg){
+			// We've defined a style rather than an explicit color
+			path.setStroke({color: "green"});	// Arbitrary color, just have to indicate
+			path.setFill("green");				// that we want it filled
+			path.getEventSource().setAttribute("class", range.color.style);
+		}
+		
+		path.connect("onmouseover", lang.hitch(this, this._handleMouseOverRange, range));
+		path.connect("onmouseout", lang.hitch(this, this._handleMouseOutRange, range));
+	
+		range.shape = path;
+	},
+
+	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.
+		var range = null,
+			pos = domGeometry.getContentBox(this.gaugeContent),
+			x = e.clientX - pos.x,
+			y = e.clientY - pos.y,
+			r = Math.sqrt((y - this.cy)*(y - this.cy) + (x - this.cx)*(x - this.cx))
+		;
+		if(r < this.radius){
+			var angle = this._getDegrees(Math.atan2(y - this.cy, x - this.cx) + Math.PI/2),
+			//if(angle > this.endAngle){angle = angle - 360;}
+				value = this._getValueForAngle(angle)
+			;
+			if(this._rangeData){
+				for(var i=0; (i<this._rangeData.length) && !range; i++){
+					if((Number(this._rangeData[i].low) <= value) && (Number(this._rangeData[i].high) >= value)){
+						range = this._rangeData[i];
+					}
+				}
+			}
+		}
+		return range;
+	},
+
+	_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
+		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
+		var pos = domGeometry.position(widget.gaugeContent, true),
+			xf = x - pos.x,
+			yf = y - pos.y,
+			angle = widget._getDegrees(Math.atan2(yf - widget.cy, xf - widget.cx) + Math.PI/2);
+		
+		// get value and restrict to our min/max
+		var value = widget._getValueForAngle(angle);
+		value = Math.min(Math.max(value, widget.min), widget.max);
+		// update the indicator
+		widget._drag.value = widget._drag.currentValue = value;
+		// callback
+		widget._drag.onDragMove(widget._drag);
+		// rotate indicator
+		widget._drag.draw(this._indicatorsGroup, true);
+		widget._drag.valueChanged();
+	}
+
+});
+});
diff --git a/dojox/gauges/AnalogIndicatorBase.js b/dojox/gauges/AnalogIndicatorBase.js
new file mode 100644
index 0000000..63c40c8
--- /dev/null
+++ b/dojox/gauges/AnalogIndicatorBase.js
@@ -0,0 +1,200 @@
+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:
+		//		An abstract base class for indicators that can be used in an AnalogGauge.
+		//
+
+	draw: function(/*dojox.gfx.Group*/ group, /*Boolean?*/ dontAnimate){
+		// summary: 
+		//		Override of dojox.gauges._Indicator.draw
+		// group: dojox.gfx.Group
+		//		The GFX group when the indicator must be drawn
+		// dontAnimate: Boolean
+		//		Indicates if the drawing should not be animated (vs. the default of doing an animation)
+		if(this.shape){
+			this._move(dontAnimate);
+		}else{
+			if(this.text){
+				this.text.parent.remove(this.text);
+				this.text = null;
+			}
+			var a = this._gauge._getAngle(Math.min(Math.max(this.value, this._gauge.min), this._gauge.max));
+
+			this.color = this.color || '#000000';
+			this.length = this.length || this._gauge.radius;
+			this.width = this.width || 1;
+			this.offset = this.offset || 0;
+			this.highlight = this.highlight || '#D0D0D0';
+
+			var shapes = this._getShapes(group, this._gauge, this);
+
+			if (shapes){
+				if (shapes.length > 1){
+					this.shape = group.createGroup();
+					for (var s = 0; s < shapes.length; s++){
+						this.shape.add(shapes[s]);
+					}
+				}
+				else 
+					this.shape = shapes[0];
+ 
+				this.shape.setTransform([{
+					dx: this._gauge.cx,
+					dy: this._gauge.cy
+				}, gfx.matrix.rotateg(a)]);
+
+				this.shape.connect("onmouseover", this, this.handleMouseOver);
+				this.shape.connect("onmouseout", this, this.handleMouseOut);
+				this.shape.connect("onmousedown", this, this.handleMouseDown);
+				this.shape.connect("touchstart", this, this.handleTouchStart);
+}
+			if(this.label){
+				var direction = this.direction;
+				if (!direction) direction = 'outside';
+		
+				var len;
+				if (direction == 'inside') 
+					len=-this.length+this.offset - 5;
+				else
+					len=this.length+this.offset + 5;
+				
+				var rad=this._gauge._getRadians(90-a);
+				this._layoutLabel(group, this.label+'', this._gauge.cx, this._gauge.cy,len ,rad , direction);
+				
+			}
+			this.currentValue = this.value;
+		}
+	},
+	
+	_layoutLabel:function(group, txt, ox, oy, lrad, angle, labelPlacement){
+		// summary: 
+		//		Places the label on the side of the tick.
+	
+		var font = this.font ? this.font : gfx.defaultFont;
+
+		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;
+				}
+			}
+		}
+		// since the size computed by getTextBox is too big,
+		// to lower the problem, we align this to the middle and
+		// place at the middle of the computed size.
+		this.text = this._gauge.drawText(group, txt, tfx + tw / 2, tfy + th, 'middle', this.color, this.font);
+	},
+	
+	_distance: function(x1,y1,x2,y2){
+		return Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
+	},
+	
+	_move: function(/*Boolean?*/ dontAnimate){
+		// 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),
+			c = this.currentValue
+		;
+		if(dontAnimate){
+			var angle = this._gauge._getAngle(v);
+			this.shape.setTransform([{dx:this._gauge.cx,dy:this._gauge.cy}, gfx.matrix.rotateg(angle)]);
+			this.currentValue = v;
+		}else{
+			if(c!=v){
+				var anim = new fx.Animation({curve: [c, v], duration: this.duration, easing: this.easing});
+				connect.connect(anim, "onAnimate", lang.hitch(this, function(step){
+				this.shape.setTransform([{dx:this._gauge.cx,dy:this._gauge.cy}, gfx.matrix.rotateg(this._gauge._getAngle(step))]);
+					
+				this.currentValue = step;
+				}));
+				anim.play();
+			}
+		}
+	}
+});
+});
\ No newline at end of file
diff --git a/dojox/gauges/AnalogLineIndicator.js b/dojox/gauges/AnalogLineIndicator.js
new file mode 100644
index 0000000..6a259bd
--- /dev/null
+++ b/dojox/gauges/AnalogLineIndicator.js
@@ -0,0 +1,29 @@
+define(["dojo/_base/declare","./AnalogIndicatorBase"],
+  function(declare, AnalogIndicatorBase) {
+
+/*=====
+	AnalogIndicatorBase = dojox.gauges.AnalogIndicatorBase;
+=====*/
+
+return declare("dojox.gauges.AnalogLineIndicator", [AnalogIndicatorBase], {
+	//	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
+	//		to the value of the indicator.
+
+	_getShapes: function(/*dojox.gfx.Group*/ group){
+		// summary:
+		//		Private function for generating the shapes for this indicator. An indicator that behaves the 
+		//		same might override this one and simply replace the shapes (such as ArrowIndicator).
+		var direction = this.direction;
+		var length = this.length;
+		if (direction == 'inside')
+			length = - length;
+		
+		return [group.createLine({x1: 0, y1: -this.offset, x2: 0, y2: -length-this.offset})
+					.setStroke({color: this.color, width: this.width})];
+	}
+	
+});
+
+});
\ No newline at end of file
diff --git a/dojox/gauges/AnalogNeedleIndicator.js b/dojox/gauges/AnalogNeedleIndicator.js
new file mode 100644
index 0000000..68c984b
--- /dev/null
+++ b/dojox/gauges/AnalogNeedleIndicator.js
@@ -0,0 +1,46 @@
+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.
+	
+	_getShapes: function(group){
+		// summary:
+		//		Override of dojox.gauges.AnalogLineIndicator._getShapes
+		if(!this._gauge){
+			return null;
+		}
+		var x = Math.floor(this.width/2);
+		var shapes = [];
+		
+		var color = this.color ? this.color : 'black';
+		var strokeColor = this.strokeColor ? this.strokeColor : color;
+		var strokeWidth = this.strokeWidth ? this.strokeWidth : 1;
+
+		var stroke = {
+			color: strokeColor,
+			width: strokeWidth
+		};
+		
+		if (color.type && !this.strokeColor){
+			stroke.color = color.colors[0].color;
+		}
+
+		var xy = (Math.sqrt(2) * (x));
+		shapes[0] = group.createPath()
+					.setStroke(stroke).setFill(color)
+					.moveTo(xy, -xy).arcTo((2*x), (2*x), 0, 0, 0, -xy, -xy)
+					.lineTo(0, -this.length).closePath();
+		shapes[1] = group.createCircle({cx: 0, cy: 0, r: this.width})
+					.setStroke(stroke)
+					.setFill(color);
+		return shapes;
+	}
+});
+});
diff --git a/dojox/gauges/BarCircleIndicator.js b/dojox/gauges/BarCircleIndicator.js
new file mode 100644
index 0000000..370ba31
--- /dev/null
+++ b/dojox/gauges/BarCircleIndicator.js
@@ -0,0 +1,45 @@
+define(["dojo/_base/declare","dojox/gfx","./BarLineIndicator"],
+  function(declare, gfx, BarLineIndicator) { 
+
+/*=====
+	BarLineIndicator = dojox.gauges.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.
+	
+	_getShapes: function(group){
+		// summary: 
+		//		Override of dojox.gauges.BarLineIndicator._getShapes
+		var color = this.color ? this.color : 'black';
+		var strokeColor = this.strokeColor ? this.strokeColor : color;
+		var stroke = {
+			color: strokeColor,
+			width: 1
+		};
+		if (this.color.type && !this.strokeColor){
+			stroke.color = this.color.colors[0].color;
+		}
+		var y = this._gauge.dataY + this.offset + this.length / 2;
+		var v = this.value;
+		if (v < this._gauge.min){
+			v = this._gauge.min;
+		}
+		if (v > this._gauge.max){
+			v = this._gauge.max;
+		}
+		var pos = this._gauge._getPosition(v);
+		
+		var shapes = [group.createCircle({
+			cx: 0,
+			cy: y,
+			r: this.length / 2
+		}).setFill(color).setStroke(stroke)];
+		
+		shapes[0].setTransform(gfx.matrix.translate(pos, 0));
+		return shapes;
+	}
+});
+});
\ No newline at end of file
diff --git a/dojox/gauges/BarGauge.js b/dojox/gauges/BarGauge.js
new file mode 100644
index 0000000..d3c3caa
--- /dev/null
+++ b/dojox/gauges/BarGauge.js
@@ -0,0 +1,180 @@
+define(["dojo/_base/declare","dojo/_base/lang","dojo/_base/array","dojo/_base/html","dojo/_base/event","dojox/gfx",
+		"./_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.
+	//
+	// description:
+	//		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>
+
+	// dataX: Number
+	// x position of data area (default 5)
+	dataX: 5,
+
+	// dataY: Number
+	// y position of data area (default 5)
+	dataY: 5,
+
+	// dataWidth: Number
+	// width of data area (default is bar graph width - 10)
+	dataWidth: 0,
+
+	// dataHeight: Number
+	// height of data area (default is bar graph width - 10)
+	dataHeight: 0,
+
+	// _defaultIndicator: Object
+	// 		override of dojox.gauges._Gauge._defaultIndicator
+	_defaultIndicator: BarLineIndicator,
+
+	startup: function(){
+		// handle settings from HTML by making sure all the options are
+		// converted correctly to numbers 
+		//
+		// also connects mouse handling events
+
+		if(this.getChildren){
+			arr.forEach(this.getChildren(), function(child){ child.startup(); });
+		}
+
+		if(!this.dataWidth){this.dataWidth = this.gaugeWidth - 10;}
+		if(!this.dataHeight){this.dataHeight = this.gaugeHeight - 10;}
+
+		this.inherited(arguments);
+	},
+
+	_getPosition: function(/*Number*/value){
+		// 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.
+
+		return this.dataX + Math.floor((value - this.min)/(this.max - this.min)*this.dataWidth);
+	},
+
+	_getValueForPosition: function(/*Number*/pos){
+		// 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.
+		return (pos - this.dataX)*(this.max - this.min)/this.dataWidth + this.min;
+	},
+
+	drawRange: function(/*dojox.gfx.Group*/ group, /*Object*/range){
+		// summary:
+		//		This function is used to draw (or redraw) a range
+		// description:
+		//		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.
+		// range:
+		//		A range is either a dojox.gauges.Range or an object
+		//		with similar parameters (low, high, hover, etc.).
+		if(range.shape){
+			range.shape.parent.remove(range.shape);
+			range.shape = null;
+		}
+
+		var x1 = this._getPosition(range.low);
+		var x2 = this._getPosition(range.high);
+		var path = group.createRect({
+			x: x1,
+			y: this.dataY,
+			width: x2 - x1,
+			height: this.dataHeight
+		});	
+		if(lang.isArray(range.color) || lang.isString(range.color)){
+			path.setStroke({color: range.color});
+			path.setFill(range.color);
+		}else if(range.color.type){
+			// Color is a gradient
+			var y = this.dataY + this.dataHeight/2;
+			range.color.x1 = x1;
+			range.color.x2 = x2;
+			range.color.y1 = y;
+			range.color.y2 = y;
+			path.setFill(range.color);
+			path.setStroke({color: range.color.colors[0].color});
+		}else if (gfx.svg){
+			// We've defined a style rather than an explicit color
+			path.setStroke({color: "green"});	// Arbitrary color, just have to indicate
+			path.setFill("green");				// that we want it filled
+			path.getEventSource().setAttribute("class", range.color.style);
+		}
+	
+		path.connect("onmouseover", lang.hitch(this, this._handleMouseOverRange, range));
+		path.connect("onmouseout", lang.hitch(this, this._handleMouseOutRange, range));
+	
+		range.shape = path;
+	},
+
+	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.
+		var range = null;
+		var pos = domGeometry.getContentBox(this.gaugeContent);
+		var x = e.clientX - pos.x;
+		var value = this._getValueForPosition(x);
+		if(this._rangeData){
+			for(var i=0; (i<this._rangeData.length) && !range; i++){
+				if((Number(this._rangeData[i].low) <= value) && (Number(this._rangeData[i].high) >= value)){
+					range = this._rangeData[i];
+				}
+			}
+		}
+		return range;
+	},
+
+	_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
+		this._dragIndicatorAt(widget, e.pageX, e.pageY);
+		event.stop(e);
+	},
+	
+	_dragIndicatorAt: function(/*Object*/ widget, x, y){
+		
+		// summary:
+		//		Handles the dragging of an indicator, including moving/re-drawing
+		// get new value based on mouse position
+		var pos = domGeometry.position(widget.gaugeContent, true);
+		var xl = x - pos.x;
+		var value = widget._getValueForPosition(xl);
+		if(value < widget.min){value = widget.min;}
+		if(value > widget.max){value = widget.max;}
+		// update the indicator
+		widget._drag.value = value;
+		// callback
+		widget._drag.onDragMove(widget._drag);
+		// redraw/move indicator(s)
+		widget._drag.draw(this._indicatorsGroup, true);
+		widget._drag.valueChanged();
+	}
+});
+});
diff --git a/dojox/gauges/BarIndicator.js b/dojox/gauges/BarIndicator.js
new file mode 100644
index 0000000..d62a447
--- /dev/null
+++ b/dojox/gauges/BarIndicator.js
@@ -0,0 +1,79 @@
+define(["dojo/_base/declare","dojo/_base/fx","dojo/_base/connect","dojo/_base/lang","./BarLineIndicator"],
+function(declare, fx, connect, lang, BarLineIndicator) { 
+
+/*=====
+	BarLineIndicator = dojox.gauges.BarLineIndicator;
+=====*/
+
+return declare("dojox.gauges.BarIndicator",[BarLineIndicator],{
+	
+	// summary:
+	//		An indicator for the BarGauge that draws a bar corresponding to the indicator value.	
+	
+	_getShapes: function(group){
+		// summary:
+		//		Override of dojox.gauges.BarLineIndicator._getShapes
+		if(!this._gauge){
+			return null;
+		}
+		var v = this.value;
+		if(v < this._gauge.min){v = this._gauge.min;}
+		if(v > this._gauge.max){v = this._gauge.max;}
+		var pos = this._gauge._getPosition(v);
+		if(pos == this.dataX){pos = this.dataX+1;}
+		var y = this._gauge.dataY + Math.floor((this._gauge.dataHeight - this.width)/2) + this.offset;
+
+		var shapes = [];
+		shapes[0] = group.createRect({x:this._gauge.dataX, y:y, width:pos - this._gauge.dataX, height:this.width});
+		shapes[0].setStroke({color: this.color});
+		shapes[0].setFill(this.color);
+		shapes[1] = group.createLine({ x1:this._gauge.dataX, y1:y, x2:pos, y2:y });
+		shapes[1].setStroke({color: this.highlight});
+		if(this.highlight2){
+			y--;
+			shapes[2] = group.createLine({ x1:this._gauge.dataX, y1:y, x2:pos, y2:y });
+			shapes[2].setStroke({color: this.highlight2});
+		}
+
+		return shapes;
+	},
+	_createShapes: function(val){
+		// summary:
+		//		Creates a shallow copy of the current shapes while adjusting for the new value
+		for(var i in this.shape.children){
+			i = this.shape.children[i];
+			var newShape = {};
+			for(var j in i){
+				newShape[j] = i[j];
+			}
+			if(i.shape.type == "line"){
+				newShape.shape.x2 = val+newShape.shape.x1;
+			}else if(i.shape.type == "rect"){
+				newShape.width = val;
+			}
+			i.setShape(newShape);
+		}
+	},
+	_move: function(/*Boolean?*/ dontAnimate){
+		// summary:
+		//		Override of dojox.gauges.BarLineIndicator._move to resize the bar (rather than moving it)
+		
+		var c;
+		var v = this.value ;
+		if(v < this.min){v = this.min;}
+		if(v > this.max){v = this.max;}
+		c = this._gauge._getPosition(this.currentValue);
+		this.currentValue = v;
+		v = this._gauge._getPosition(v)-this._gauge.dataX;
+		if(dontAnimate){
+			this._createShapes(v);
+		}else{
+			if(c!=v){
+				var anim = new fx.Animation({curve: [c, v], duration: this.duration, easing: this.easing});
+				connect.connect(anim, "onAnimate", lang.hitch(this, this._createShapes));
+				anim.play();
+			}
+		}
+	}
+});
+});
diff --git a/dojox/gauges/BarLineIndicator.js b/dojox/gauges/BarLineIndicator.js
new file mode 100644
index 0000000..43aa6b0
--- /dev/null
+++ b/dojox/gauges/BarLineIndicator.js
@@ -0,0 +1,133 @@
+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;
+=====*/
+
+return declare("dojox.gauges.BarLineIndicator",[Indicator],{
+	
+	// summary:
+	//		An indicator for the BarGauge that draws a segment a line corresponding to the indicator value.	
+	
+	width: 1,
+	_getShapes: function(/*dojox.gfx.Group*/ group){
+		// summary:
+		//		Private function for generating the shapes for this indicator. An indicator that behaves the 
+		//		same might override this one and simply replace the shapes (such as BarIndicator).
+		if(!this._gauge){
+			return null;
+		}
+		var v = this.value;
+		if(v < this._gauge.min){v = this._gauge.min;}
+		if(v > this._gauge.max){v = this._gauge.max;}
+		var pos = this._gauge._getPosition(v);
+		var shapes = [];
+		if(this.width > 1){
+			shapes[0] = group.createRect({
+				x:0, 
+				y:this._gauge.dataY + this.offset,
+				width:this.width, 
+				height:this.length
+			});
+			shapes[0].setStroke({color: this.color});
+			shapes[0].setFill(this.color);
+			shapes[0].setTransform(gfx.matrix.translate(pos,0));
+		}else{
+			shapes[0] = group.createLine({
+				x1:0, 
+				y1:this._gauge.dataY + this.offset,
+				x2:0, 
+				y2:this._gauge.dataY + this.offset + this.length
+			});
+			shapes[0].setStroke({color: this.color});
+			shapes[0].setTransform(gfx.matrix.translate(pos,0));
+		}
+		return shapes;
+	},
+	draw: function(/*dojox.gfx.Group*/group, /*Boolean?*/ dontAnimate){
+		// summary: 
+		//		Override of dojox.gauges._Indicator.draw
+		// dontAnimate: Boolean
+		//		Indicates if the drawing should not be animated (vs. the default of doing an animation)
+		var i;
+		if (this.shape){
+			this._move(dontAnimate);
+		}else{
+			if (this.shape){
+				this.shape.parent.remove(this.shape);
+				this.shape = null;
+			}
+			if (this.text){
+				this.text.parent.remove(this.text);
+				this.text = null;
+			}
+			
+			this.color = this.color || '#000000';
+			this.length = this.length || this._gauge.dataHeight;
+			this.width = this.width || 3;
+			this.offset = this.offset || 0;
+			this.highlight = this.highlight || '#4D4D4D';
+			this.highlight2 = this.highlight2 || '#A3A3A3';
+			
+			var shapes = this._getShapes(group, this._gauge, this);
+			
+			if (shapes.length > 1){
+				this.shape = group.createGroup();
+				for (var s = 0; s < shapes.length; s++){
+					this.shape.add(shapes[s]);
+				}
+			} else this.shape = shapes[0];
+			
+			if (this.label){
+				var v = this.value;
+				if (v < this._gauge.min){
+					v = this._gauge.min;
+				}
+				if (v > this._gauge.max){
+					v = this._gauge.max;
+				}
+				var pos = this._gauge._getPosition(v);
+				
+				if (this.direction == 'inside'){
+					var font = this.font ? this.font : gfx.defaultFont;
+					var fz = font.size;
+					var th = gfx.normalizedLength(fz);
+					
+					this.text = this._gauge.drawText(group, '' + this.label, pos, this._gauge.dataY + this.offset + this.length + 5 + th, 'middle', this.color, this.font);
+				} else this.text = this._gauge.drawText(group, '' + this.label, pos, this._gauge.dataY + this.offset - 5, 'middle', this.color, this.font);
+			}
+			
+			this.shape.connect("onmouseover", this, this.handleMouseOver);
+			this.shape.connect("onmouseout", this, this.handleMouseOut);
+			this.shape.connect("onmousedown", this, this.handleMouseDown);
+			this.shape.connect("touchstart", this, this.handleTouchStart);
+			this.currentValue = this.value;
+		}
+	},
+	
+	_move: function(/*Boolean?*/ dontAnimate){
+		// 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)
+		var v = this.value ;
+		if(v < this._gauge.min){v = this._gauge.min;}
+		if(v > this._gauge.max){v = this._gauge.max;}
+		var c = this._gauge._getPosition(this.currentValue);
+		this.currentValue = v;
+		v = this._gauge._getPosition(v);
+ 
+		if(dontAnimate || (c==v)){
+			this.shape.setTransform(gfx.matrix.translate(v,0));
+		}else{
+			var anim = new fx.Animation({curve: [c, v], duration: this.duration, easing: this.easing});
+			connect.connect(anim, "onAnimate", lang.hitch(this, function(jump){
+				if (this.shape)
+				 this.shape.setTransform(gfx.matrix.translate(jump,0));
+			}));
+			anim.play();
+		}
+	}
+});
+});
\ No newline at end of file
diff --git a/dojox/gauges/GlossyCircularGauge.js b/dojox/gauges/GlossyCircularGauge.js
new file mode 100644
index 0000000..dc9fc7d
--- /dev/null
+++ b/dojox/gauges/GlossyCircularGauge.js
@@ -0,0 +1,236 @@
+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.
+	//
+	// example:
+	//	|	<div	dojoType="dojox.gauges.GlossyCircularGauge"
+	//	|		id="testGauge"
+	//	|		width="300"
+	//	|		height="300"
+	//	|		min="0"
+	//	|		max="100"
+	//	|		value="0" 
+	//	|		majorTicksInterval="10"
+	//	|		majorTicksColor="#c4c4c4"
+	//	|		minorTicksInterval="5"
+	//	|		minorTicksColor="#c4c4c4"
+	//	|		color="black" 
+	//	|		needleColor="#c4c4c4"
+	//	|		font="normal normal normal 10pt sans-serif"
+	//	|		textIndicatorFont="normal normal normal 20pt sans-serif"
+	//	|		textIndicatorVisible="true" 
+	//	|		textIndicatorColor="#c4c4c4" 
+	//	|		majorTicksLabelPlacement="inside"|"outside"
+	//	|		noChange="true"
+	//	|		title="title"
+	//	|		scalePrecision="0"
+	//	|		textIndicatorPrecision="0">
+	//	|	</div>
+
+	_designWidth : 376.25,
+	_designHeight : 382.5,
+	_designCx : 187.19173,
+	_designCy : 187.81589,
+	_designTextIndicatorX :	187.19173,
+	_designTextIndicatorY :	267.81589,	
+	
+
+	constructor: function(){
+		// summary:
+		//		Creates a new GlossyCircularGauge.
+		this.startAngle= -135;
+		this.endAngle= 135;
+		this.min = 0;
+		this.max = 100;
+	},
+
+	drawBackground: function(group){
+		// summary:
+		//		Draws the background of the gauge.
+		// group: dojox.gfx.Group
+		//		The GFX group where the background must be drawn
+
+		var scale = Math.min((this.width / this._designWidth), (this.height / this._designHeight));
+		var transform = {
+				xx: scale,
+				xy: 0,
+				yx: 0,
+				yy: scale,
+				dx: (-161) * scale + (this.width - scale * this._designWidth) / 2,
+				dy: (-263.5) * scale + (this.height - scale * this._designHeight) / 2
+
+		};
+		
+		var lighterColor1 = Color.blendColors(new Color(this.color), new Color('white'), 0.4 );
+		var lighterColor2 = Color.blendColors(new Color(this.color), new Color('white'), 0.8 );		
+		
+		
+		if (this._gaugeBackground){
+			this._gaugeBackground.setTransform(transform);
+			return;
+		}
+		this._gaugeBackground = group.createGroup();
+		this._gaugeBackground.setTransform(transform);
+
+		this._gaugeBackground.createPath({
+			path: "M0 0 C0.028 -82.393 -66.741 -149.207 -149.134 -149.235 C-231.526 -149.264 -298.341 -82.494 -298.369 -0.101 L-298.369 0 C-298.397 82.393 -231.627 149.207 -149.235 149.235 C-66.843 149.264 -0.028 82.494 0 0.102 L0 0 Z"
+		}).setTransform({
+			xx: 1.25,
+			xy: 0,
+			yx: 0,
+			yy: -1.25,
+			dx: 535.09494,
+			dy: 452.53442
+		}).setFill(this.color);
+
+		this._gaugeBackground.createPath({
+			path: "M451.354 450.434 C451.382 374.317 389.698 312.593 313.581 312.566 C237.464 312.54 175.739 374.224 175.713 450.341 L175.713 450.434 C175.688 526.551 237.372 588.275 313.487 588.302 C389.604 588.327 451.329 526.644 451.354 450.527 L451.354 450.434 Z"
+		}).setTransform({
+			xx: 1.25,
+			xy: 0,
+			yx: 0,
+			yy: -1.25,
+			dx: -43.30358,
+			dy: 1015.57642
+		}).setFill({
+			type: "linear",
+			x1: 175.688,
+			y1: 312.54001,
+			x2: 175.688,
+			y2: 422.85482,
+			colors: [
+			         {offset: 0, color: lighterColor1},
+			         {offset: 1, color: this.color}
+			         ]
+		});
+
+		this._gaugeBackground.createPath({
+			path: "M451.321 453.375 C449.778 528.175 388.655 588.327 313.491 588.302 C238.359 588.276 177.295 528.135 175.753 453.377 C217.829 442.046 266.246 464.646 315.36 464.646 C364.489 464.646 409.364 442.041 451.321 453.375"
+		}).setTransform({
+			xx: 1.25,
+			xy: 0,
+			yx: 0,
+			yy: -1.25,
+			dx: -43.30358,
+			dy: 1015.57642
+		}).setFill({
+			type: "linear",
+			x1: 175.75301,
+			y1: 442.04099,
+			x2: 175.75301,
+			y2: 588.32703,
+			colors: [
+			         {offset: 0, color: this.color},
+			         {offset: 1, color: lighterColor2}
+			         ]
+		});
+
+		this._gaugeBackground.createPath({
+			path: "M0 0 C-1.543 74.8 -62.666 134.952 -137.83 134.927 C-212.962 134.901 -274.026 74.76 -275.568 0.002 C-233.492 -11.329 -185.075 11.271 -135.961 11.271 C-86.832 11.271 -41.957 -11.334 0 0"
+		}).setTransform({
+			xx: 1.25,
+			xy: 0,
+			yx: 0,
+			yy: -1.25,
+			dx: 520.84441,
+			dy: 448.85767
+		}).setFill([255,255,255,0.12157]);
+
+	},
+
+	drawForeground: function(group){
+		// summary:
+		//		Draws the foreground of the gauge.
+		// group: dojox.gfx.Group
+		//		The GFX group where the foreground must be drawn
+
+		var scale = Math.min((this.width / this._designWidth), (this.height / this._designHeight));
+		var transform = {
+				xx: scale,
+				xy: 0,
+				yx: 0,
+				yy: scale,
+				dx: (-160) * scale + (this.width - scale * this._designWidth) / 2,
+				dy: (-263.5) * scale + (this.height - scale * this._designHeight) / 2
+		};
+		
+		var lighterColor1 = Color.blendColors(new Color(this.color), new Color('white'), 0.4 );
+		var lighterColor2 = Color.blendColors(new Color(this.color), new Color('white'), 0.8 );		
+				
+		if (this._foreground){
+			this._foreground.setTransform(transform);
+			return;
+		}
+		this._foreground = group.createGroup();
+		this._foreground.setTransform(transform);
+
+		var group1 = this._foreground.createGroup();
+		group1.setTransform({
+			xx: 1.25,
+			xy: 0,
+			yx: 0,
+			yy: -1.25,
+			dx: -43.30358,
+			dy: 1015.57642
+		});
+		group1.createPath({
+			path: "M0 0 C0.004 -12.579 -10.189 -22.779 -22.768 -22.784 C-35.349 -22.788 -45.549 -12.594 -45.553 -0.016 L-45.553 0 C-45.558 12.579 -35.363 22.779 -22.783 22.784 C-10.205 22.788 -0.004 12.594 0 0.015 L0 0 Z"
+		}).setTransform({
+			xx: 1,
+			xy: 0,
+			yx: 0,
+			yy: 1,
+			dx: 336.31049,
+			dy: 451.43359
+		}).setFill(this.color);
+
+		group1.createPath({
+			path: "M333.443 451.434 C333.446 440.438 324.537 431.523 313.541 431.519 C302.546 431.515 293.63 440.425 293.626 451.42 L293.626 451.434 C293.622 462.429 302.532 471.345 313.527 471.349 C324.523 471.353 333.439 462.442 333.443 451.447 L333.443 451.434 Z"
+		}).setFill({
+			type: "linear",
+			x1: 293.62201,
+			y1: 431.51501,
+			x2: 293.62201,
+			y2: 451.43401,
+			colors: [
+			         {offset: 0, color: lighterColor1},
+			         {offset: 1, color: this.color}
+			         ]
+		});
+
+		group1.createPath({
+			path: "M333.438 451.858 C333.215 462.663 324.386 471.353 313.528 471.349 C302.675 471.345 293.854 462.658 293.632 451.858 C299.709 450.222 306.702 453.486 313.799 453.486 C320.895 453.486 327.377 450.221 333.438 451.858"
+		}).setFill({
+			type: "linear",
+			x1: 293.63199,
+			y1: 450.22101,
+			x2: 293.63199,
+			y2: 471.353,
+			colors: [
+			         {offset: 0, color: this.color},
+			         {offset: 1, color: lighterColor2}
+			         ]
+		});
+
+		group1.createPath({
+			path: "M0 0 C-0.223 10.805 -9.052 19.494 -19.909 19.49 C-30.763 19.486 -39.583 10.799 -39.806 0 C-33.729 -1.636 -26.735 1.628 -19.639 1.628 C-12.543 1.628 -6.061 -1.638 0 0"
+		}).setTransform({
+			xx: 1,
+			xy: 0,
+			yx: 0,
+			yy: 1,
+			dx: 333.4375,
+			dy: 451.8584
+		}).setFill([255,255,255,0.12157]);
+
+	}
+
+});
+});
diff --git a/dojox/gauges/GlossyCircularGaugeBase.js b/dojox/gauges/GlossyCircularGaugeBase.js
new file mode 100644
index 0000000..ba066de
--- /dev/null
+++ b/dojox/gauges/GlossyCircularGaugeBase.js
@@ -0,0 +1,540 @@
+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.
+	
+	
+	//_defaultIndicator : _Indicator
+	//		the type of default indicator to create
+	_defaultIndicator: AnalogCircleIndicator,
+	
+	// _needle: dojox.gauges.GlossyCircularGaugeNeedle
+	//	 	the needle of this circular gauge
+	_needle: null,
+	
+	// _textIndicator: dojox.gauges.TextIndicator
+	// 		the text displaying the gauge's value
+	_textIndicator: null,
+	
+	_textIndicatorAdded: false,
+	
+	// _range: Object
+	// 		the range of this gauge
+	_range: null,
+	
+	// value: Number
+	// 		The value of the gauge.
+	value: 0,
+	
+	// color: String
+	// 		The main color of the gauge.
+	color: 'black',
+	
+	// needleColor: Color
+	// 		The main color of the needle.
+	needleColor: '#c4c4c4',
+	
+	// textIndicatorFont: String
+	// 		The font of the text indicator
+	textIndicatorFont: "normal normal normal 20pt serif",
+	
+	// textIndicatorVisible: Boolean
+	// 		Indicates if the text indicator is visible			
+	textIndicatorVisible: true,
+	
+	// textIndicatorColor: Color
+	//		 The color of the text indicator
+	textIndicatorColor: '#c4c4c4',
+	
+	// _majorTicksOffset: Number
+	// 		Distance, at design, from gauge's center to major ticks
+	_majorTicksOffset: 130,
+	
+	// majorTicksInterval: Number
+	// 		Interval between major ticks
+	majorTicksInterval: 10,
+	
+	// _majorTicksLength: Number
+	// 		Major tick size, at design
+	_majorTicksLength: 5,
+	
+	// majorTicksColor: Color
+	// 		Color of major tick marks
+	majorTicksColor: '#c4c4c4',
+	
+	// majorTicksLabelPlacement: String
+	// 		Placement of major tick labels
+	majorTicksLabelPlacement: 'inside',
+	
+	// _minorTicksOffset: Number
+	// 		Distance, at design, from gauge's center to minor ticks
+	_minorTicksOffset: 130,
+	
+	// minorTicksInterval: Number
+	// 		Interval between minor ticks
+	minorTicksInterval: 5,
+	
+	// _minorTicksLength: Number
+	// 		Minor tick size, at design
+	_minorTicksLength: 3,
+	
+	// minorTicksColor: Color
+	// 		Color of minor tick marks
+	minorTicksColor: '#c4c4c4',
+	
+	// noChange: Boolean
+	// 		Indicates if the gauge reacts to touch events
+	noChange: false,
+	
+	// title: String
+	// 		The title displayed in the needle's tooltip
+	title: "",
+	
+	// font: Object
+	//		 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)
+	scalePrecision: 0,
+	
+	// textIndicatorPrecision: Number
+	//		 The precision for the formatting of numbers in the text indicator (default is 0)
+	textIndicatorPrecision: 0,
+	
+	_font: null,
+	
+	
+	constructor: function(){
+		this.startAngle = -135;
+		this.endAngle = 135;
+		this.min = 0;
+		this.max = 100;
+	},
+	
+	startup: function(){
+		// summary:
+		//		Overrides AnalogGauge.startup
+		this.inherited(arguments);
+		
+		//just in case someone calls the startup twice.
+
+		if (this._needle) return; 
+		
+		var scale = Math.min((this.width / this._designWidth), (this.height / this._designHeight));
+		this.cx = scale * this._designCx + (this.width - scale * this._designWidth) / 2;
+		this.cy = scale * this._designCy + (this.height - scale * this._designHeight) / 2;
+		
+		this._range = {
+			low: this.min ? this.min : 0,
+			high: this.max ? this.max : 100,
+			color: [255, 255, 255, 0]
+		};
+		this.addRange(this._range);
+		
+		this._majorTicksOffset = this._minorTicksOffset = scale * this._majorTicksOffset;
+		this._majorTicksLength = scale * this._majorTicksLength;
+		this._minorTicksLength = scale * this._minorTicksLength;
+		
+		// creates and add the major ticks
+		this.setMajorTicks({
+			fixedPrecision: true,
+			precision: this.scalePrecision,
+			font: this._font,
+			offset: this._majorTicksOffset,
+			interval: this.majorTicksInterval,
+			length: this._majorTicksLength,
+			color: this.majorTicksColor,
+			labelPlacement: this.majorTicksLabelPlacement
+		});
+		
+		// creates and add the minor ticks
+		this.setMinorTicks({
+			offset: this._minorTicksOffset,
+			interval: this.minorTicksInterval,
+			length: this._minorTicksLength,
+			color: this.minorTicksColor
+		});
+		
+		// creates and adds the needle
+		this._needle = new GlossyCircularGaugeNeedle({
+			hideValue: true,
+			title: this.title,
+			noChange: this.noChange,
+			color: this.needleColor,
+			value: this.value
+		});
+		this.addIndicator(this._needle);
+		
+		// creates and add the text indicator
+		this._textIndicator = new TextIndicator({
+			x: scale * this._designTextIndicatorX + (this.width - scale * this._designWidth) / 2,
+			y: scale * this._designTextIndicatorY + (this.height - scale * this._designHeight) / 2,
+			fixedPrecision: true,
+			precision: this.textIndicatorPrecision,
+			color: this.textIndicatorColor,
+			value: this.value ? this.value : this.min,
+			align: "middle",
+			font: this._textIndicatorFont
+		});
+		
+		if (this.textIndicatorVisible){
+			this.addIndicator(this._textIndicator);
+			this._textIndicatorAdded = true;
+		}
+		
+		// connect needle and text
+		connect.connect(this._needle, "valueChanged", lang.hitch(this, function(){
+			this.value = this._needle.value;
+			this._textIndicator.update(this._needle.value);
+			this.onValueChanged();
+		}));
+		
+	},
+	
+	
+	onValueChanged: function(){
+		// summary:
+		//		Invoked when the value of the gauge has changed.
+	
+	},
+	
+	//*******************************************************************************************
+	//* Property getters and setters
+	//*******************************************************************************************
+	
+	_setColorAttr: function(color){
+		// summary: 
+		//		Sets the main color of the gauge
+		// color: String
+		//      The color		
+		this.color = color ? color : 'black';
+		if (this._gaugeBackground && this._gaugeBackground.parent) 
+			this._gaugeBackground.parent.remove(this._gaugeBackground);
+		if (this._foreground && this._foreground.parent) 
+			this._foreground.parent.remove(this._foreground);
+		this._gaugeBackground = null;
+		this._foreground = null;
+		this.draw();
+	},
+	
+	_setNeedleColorAttr: function(color){
+		// summary: 
+		//		Sets the main color of the needle
+		// color: String
+		//      The color
+		this.needleColor = color;
+		if (this._needle){
+			this.removeIndicator(this._needle);
+			this._needle.color = this.needleColor;
+			this._needle.shape = null;
+			this.addIndicator(this._needle);
+		}
+	},
+	
+	_setTextIndicatorColorAttr: function(color){
+		// summary: 
+		//		Sets the color of text indicator display the gauge's value
+		// color: String
+		//      The color		
+		this.textIndicatorColor = color;
+		if (this._textIndicator){
+			this._textIndicator.color = this.textIndicatorColor;
+			this.draw();
+		}
+	},
+	
+	_setTextIndicatorFontAttr: function(font){
+		// 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'	
+		//
+		
+		this.textIndicatorFont = font;
+		this._textIndicatorFont = gfx.splitFontString(font);
+		if (this._textIndicator){
+			this._textIndicator.font = this._textIndicatorFont;
+			this.draw();
+		}
+	},
+	
+	setMajorTicksOffset: function(offset){
+		// summary: 
+		//		Sets the distance from gauge's center to major ticks
+		this._majorTicksOffset = offset;
+		this._setMajorTicksProperty({
+			'offset': this._majorTicksOffset
+		});
+		return this;
+	},
+	
+	getMajorTicksOffset: function(){
+		// summary: 
+		//		Return the distance from gauge's center to major ticks
+		return this._majorTicksOffset;
+	},
+	
+	_setMajorTicksIntervalAttr: function(interval){
+		// summary: 
+		//		Sets the interval between major ticks
+		this.majorTicksInterval = interval;
+		this._setMajorTicksProperty({
+			'interval': this.majorTicksInterval
+		});
+	},
+	
+	setMajorTicksLength: function(length){
+		// summary: 
+		//		Sets the size of the major ticks.
+		this._majorTicksLength = length;
+		this._setMajorTicksProperty({
+			'length': this._majorTicksLength
+		});
+		return this;
+	},
+	
+	getMajorTicksLength: function(){
+		// summary: 
+		//		Returns the size of the major ticks.
+		return this._majorTicksLength;
+	},
+	
+	_setMajorTicksColorAttr: function(color){
+		// summary: 
+		//		Sets the color of the major ticks.
+		this.majorTicksColor = color;
+		this._setMajorTicksProperty({
+			'color': this.majorTicksColor
+		});
+	},
+	
+	_setMajorTicksLabelPlacementAttr: function(placement){
+		// summary: 
+		//		Sets the placement of labels relatively to major ticks.
+		// placement: String
+		//		'inside' or 'outside'
+		this.majorTicksLabelPlacement = placement;
+		this._setMajorTicksProperty({
+			'labelPlacement': this.majorTicksLabelPlacement
+		});
+	},
+	
+	_setMajorTicksProperty: function(prop){
+		if (this.majorTicks){
+			lang.mixin(this.majorTicks, prop);
+			this.setMajorTicks(this.majorTicks);
+		}
+	},
+	
+	setMinorTicksOffset: function(offset){
+		// summary: 
+		//		Sets the distance from gauge's center to minor ticks
+		this._minorTicksOffset = offset;
+		this._setMinorTicksProperty({
+			'offset': this._minorTicksOffset
+		});
+		return this;
+	},
+	
+	getMinorTicksOffset: function(){
+		// summary: 
+		//		Returns the distance from gauge's center to minor ticks
+		return this._minorTicksOffset;
+	},
+	
+	_setMinorTicksIntervalAttr: function(interval){
+		// summary: 
+		//		Sets the interval between minor ticks
+		this.minorTicksInterval = interval;
+		this._setMinorTicksProperty({
+			'interval': this.minorTicksInterval
+		});
+	},
+	
+	setMinorTicksLength: function(length){
+		// summary: 
+		//		Sets the size of the minor ticks.
+		this._minorTicksLength = length;
+		this._setMinorTicksProperty({
+			'length': this._minorTicksLength
+		});
+		return this;
+	},
+	
+	getMinorTicksLength: function(){
+		// summary: 
+		//		Return the size of the minor ticks.
+		return this._minorTicksLength;
+	},
+	
+	_setMinorTicksColorAttr: function(color){
+		// summary: 
+		//		Sets the color of the minor ticks.
+		this.minorTicksColor = color;
+		this._setMinorTicksProperty({
+			'color': this.minorTicksColor
+		});
+	},
+	
+	_setMinorTicksProperty: function(prop){
+		if (this.minorTicks){
+			lang.mixin(this.minorTicks, prop);
+			this.setMinorTicks(this.minorTicks);
+		}
+	},
+	
+	_setMinAttr: function(min){
+		this.min = min;
+	
+		if (this.majorTicks != null) 
+			this.setMajorTicks(this.majorTicks);
+		if (this.minorTicks != null) 
+			this.setMinorTicks(this.minorTicks);
+		this.draw();
+		this._updateNeedle();
+	},
+	
+	_setMaxAttr: function(max){
+		this.max = max;
+	
+		if (this.majorTicks != null) 
+			this.setMajorTicks(this.majorTicks);
+		if (this.minorTicks != null) 
+			this.setMinorTicks(this.minorTicks);
+		this.draw();
+		this._updateNeedle();
+	},
+	
+	_setScalePrecisionAttr: function(value){
+		// summary: 
+		//		Changes precision of the numbers in the scale of the gauge
+		// value: Number
+		//		The new value
+		this.scalePrecision = value;
+		this._setMajorTicksProperty({
+			'precision': value
+		});
+	},
+	
+	_setTextIndicatorPrecisionAttr: function(value){
+		// summary: 
+		//		Changes precision of the numbers in the text indicator
+		// value: Number
+		//		The new value
+		this.textIndicatorPrecision = value;
+		this._setMajorTicksProperty({
+			'precision': value
+		});
+	},
+	
+	_setValueAttr: function(value){
+		// summary: 
+		//		Changes the value of the gauge
+		// value: Number
+		//		The new value for the gauge.			
+		
+		value = Math.min(this.max, value);
+		value = Math.max(this.min, value);
+		this.value = value;
+		if (this._needle){
+			// update will not work if noChange is true.
+			var noChange = this._needle.noChange;
+			this._needle.noChange = false;
+			this._needle.update(value);
+			this._needle.noChange = noChange;
+		}
+	},
+	
+	_setNoChangeAttr: function(value){
+		// 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	
+		this.noChange = value;
+		if (this._needle) 
+			this._needle.noChange = this.noChange;
+	},
+	
+	_setTextIndicatorVisibleAttr: function(value){
+		// summary: 
+		//		Changes the visibility of the text indicator displaying the gauge's value.
+		// value: boolean
+		//		true to show the indicator, false to hide.
+		
+		this.textIndicatorVisible = value;
+		if (this._textIndicator && this._needle){
+			if (this.textIndicatorVisible && !this._textIndicatorAdded){
+				this.addIndicator(this._textIndicator);
+				this._textIndicatorAdded = true;
+				this.moveIndicatorToFront(this._needle);
+				
+			}
+			else 
+				if (!this.textIndicatorVisible && this._textIndicatorAdded){
+					this.removeIndicator(this._textIndicator);
+					this._textIndicatorAdded = false;
+				}
+		}
+	},
+	
+	_setTitleAttr: function(value){
+		// summary: 
+		//		Sets the title displayed by the needle's tooltip .
+		// value: String
+		//		the title
+		
+		this.title = value;
+		if (this._needle){
+			this._needle.title = this.title;
+		}
+	},
+	
+	_setOrientationAttr: function(orientation){
+		// summary: 
+		//		Sets the orientation of the gauge
+		// orientation: String
+		//		Either "clockwise" or "cclockwise"	
+		
+		this.orientation = orientation;
+		if (this.majorTicks != null) 
+			this.setMajorTicks(this.majorTicks);
+		if (this.minorTicks != null) 
+			this.setMinorTicks(this.minorTicks);
+		this.draw();
+		this._updateNeedle();
+	
+	},
+	
+	_updateNeedle: function(){
+		// updates the needle with no animation 
+		this.value = Math.max(this.min, this.value);
+		this.value = Math.min(this.max, this.value);
+		
+		if (this._needle){
+			// update will not work if noChange is true.
+			var noChange = this._needle.noChange;
+			this._needle.noChange = false;
+			this._needle.update(this.value, false);
+			this._needle.noChange = noChange;
+		} // to redraw the needle
+	},
+	
+	_setFontAttr: function(font){
+		// 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);
+		this._setMajorTicksProperty({
+			'font': this._font
+		});
+	}});
+});
diff --git a/dojox/gauges/GlossyCircularGaugeNeedle.js b/dojox/gauges/GlossyCircularGaugeNeedle.js
new file mode 100644
index 0000000..8ff67d6
--- /dev/null
+++ b/dojox/gauges/GlossyCircularGaugeNeedle.js
@@ -0,0 +1,64 @@
+define(["dojo/_base/declare","dojo/_base/Color" ,"./AnalogIndicatorBase"],
+  function(declare, Color, AnalogIndicatorBase) {
+
+/*=====
+	AnalogIndicatorBase = dojox.gauges.AnalogIndicatorBase;
+=====*/
+
+return declare("dojox.gauges.GlossyCircularGaugeNeedle", [AnalogIndicatorBase], {
+	// summary:
+	//		The needle for the dojox.gauges.GlossyCircularGauge and
+	//		dojox.gauges.GlossySemiCircularGauge.
+	//
+	// description:
+	//		This object defines the needle for the dojox.gauges.GlossyCircularGauge and
+	//		dojox.gauges.GlossySemiCircularGauge.
+	//		Since the needle is created by the gauges class, you do not have to use this class directly.
+	
+	
+	interactionMode: "gauge",
+	
+	// color: String
+	// The color of the indicator.
+	color: '#c4c4c4',
+	
+	_getShapes: function(group){
+		// summary:
+		//		Overrides AnalogIndicatorBase._getShapes
+		
+		var darkerColor = Color.blendColors(new Color(this.color), new Color('black'), 0.3);
+		
+		if (!this._gauge) 
+			return null;
+		
+		var shapes = [];
+		shapes[0] = group.createGroup();
+		var scale = Math.min((this._gauge.width / this._gauge._designWidth), (this._gauge.height / this._gauge._designHeight));
+		shapes[0].createGroup().setTransform({
+			xx: scale,
+			xy: 0,
+			yx: 0,
+			yy: scale,
+			dx: 0,
+			dy: 0
+		});
+		shapes[0].children[0].createPath({
+			path: "M357.1429 452.005 L333.0357 465.9233 L333.0357 438.0868 L357.1429 452.005 Z"
+		}).setTransform({
+			xx: 0,
+			xy: 1,
+			yx: -6.21481,
+			yy: 0,
+			dx: -452.00505,
+			dy: 2069.75519
+		}).setFill(this.color).setStroke({
+			color: darkerColor,
+			width: 1,
+			style: "Solid",
+			cap: "butt",
+			join: 20.0
+		});
+		return shapes;
+	}
+});
+});
\ No newline at end of file
diff --git a/dojox/gauges/GlossyHorizontalGauge.js b/dojox/gauges/GlossyHorizontalGauge.js
new file mode 100644
index 0000000..eec7c32
--- /dev/null
+++ b/dojox/gauges/GlossyHorizontalGauge.js
@@ -0,0 +1,567 @@
+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.
+	//
+	// example:
+	//	|	<div dojoType="dojox.gauges.GlossyHorizontalGauge"
+	//	|		id="testGauge"
+	//	|		width="500"
+	//	|		height="100"
+	//	|		min="0"
+	//	|		max="100"
+	//	|		value="0" 
+	//	|		majorTicksInterval="10"
+	//	|		majorTicksColor="#c4c4c4"
+	//	|		minorTicksInterval="5"
+	//	|		minorTicksColor="#c4c4c4"
+	//	|		color="black" 
+	//	|		markerColor="#c4c4c4"
+	//	|		font="normal normal normal 10pt sans-serif"
+	//	|		noChange="true"
+	//	|		title="title"
+	//	|		scalePrecision="0"
+	//	|	>
+	//	|	</div>
+
+
+	// the type of default indicator to create
+	_defaultIndicator: BarCircleIndicator,
+	
+	// color: String
+	// 		The main color of the gauge.
+	color: 'black',
+	
+	// needleColor: Color
+	// 		The main color of the needle.
+	markerColor: 'black',
+	
+	// majorTicksInterval: Number
+	// 		Interval between major ticks
+	majorTicksInterval: 10,
+	
+	// _majorTicksLength: Number
+	// 		Major tick size, at design
+	_majorTicksLength: 10,
+	
+	// majorTicksColor: Color
+	// 		Color of major tick marks
+	majorTicksColor: '#c4c4c4',
+	
+	// minorTicksInterval: Number
+	// 		Interval between minor ticks
+	minorTicksInterval: 5,
+	
+	// _minorTicksLength: Number
+	// 		Minor tick size, at design
+	_minorTicksLength: 6,
+	
+	// minorTicksColor: Color
+	// 		Color of minor tick marks
+	minorTicksColor: '#c4c4c4',
+	
+	// value: Number
+	// 		The value of the gauge.
+	value: 0,
+	
+	// noChange: Boolean
+	// 		Indicates if the gauge reacts to touch events
+	noChange: false,
+	
+	// title: String
+	// 		The title displayed in the needle's tooltip
+	title: "",
+	
+	// font: Object
+	// 		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)
+	scalePrecision: 0,
+	
+	_font: null,
+	
+	_margin: 2,
+	_minBorderWidth: 2,
+	_maxBorderWidth: 6,
+	_tickLabelOffset: 5,
+	_designHeight: 100,
+	
+	constructor: function(){
+		this.min = 0;
+		this.max = 100;
+	},
+	
+	startup: function(){
+		this.inherited(arguments);
+		
+		if (this._gaugeStarted) return;
+		
+		this._gaugeStarted = true;
+		
+		var scale = this.height / this._designHeight;
+		
+		this._minorTicksLength = this._minorTicksLength * scale;
+		this._majorTicksLength = this._majorTicksLength * scale;
+		
+		var font = this._font;
+		this._computeDataRectangle();
+		
+		// computing scale height
+		
+		var th = gfx.normalizedLength(font.size);
+		var scaleHeight = th + this._tickLabelOffset + Math.max(this._majorTicksLength, this._minorTicksLength);
+		// indicator in the middle of the gauge
+		var yOffset = Math.max(0, (this.height - scaleHeight) / 2);
+		
+		this.addRange({
+			low: this.min ? this.min : 0,
+			high: this.max ? this.max : 100,
+			color: [0, 0, 0, 0]
+		});
+		
+		this.setMajorTicks({
+			fixedPrecision: true,
+			precision: this.scalePrecision,
+			font: font,
+			labelPlacement: 'inside',
+			offset: yOffset - this._majorTicksLength / 2,
+			interval: this.majorTicksInterval,
+			length: this._majorTicksLength,
+			color: this.majorTicksColor
+		
+		});
+		
+		this.setMinorTicks({
+			labelPlacement: 'inside',
+			offset: yOffset - this._minorTicksLength / 2,
+			interval: this.minorTicksInterval,
+			length: this._minorTicksLength,
+			color: this.minorTicksColor
+		
+		});
+		this._needle = new GlossyHorizontalGaugeMarker({
+			hideValue: true,
+			title: this.title,
+			noChange: this.noChange,
+			offset: yOffset,
+			color: this.markerColor,
+			value: this.value
+		});
+		this.addIndicator(this._needle);
+		
+		connect.connect(this._needle, "valueChanged", lang.hitch(this, function(){
+			this.value = this._needle.value;
+			this.onValueChanged();
+		}));
+	},
+	
+	_layoutGauge: function(){
+		// summary: 
+		//		Layout the gauge elements depending on the various parameters (size, font, tick length..)
+		
+		if (!this._gaugeStarted) 
+			return;
+		
+		var font = this._font;
+		this._computeDataRectangle();
+		var th = gfx.normalizedLength(font.size);
+		var scaleHeight = th + this._tickLabelOffset + Math.max(this._majorTicksLength, this._minorTicksLength);
+		// indicator in the middle of the gauge
+		var yOffset = Math.max(0, (this.height - scaleHeight) / 2);
+		
+		
+		this._setMajorTicksProperty({
+			fixedPrecision: true,
+			precision: this.scalePrecision,
+			font: font,
+			offset: yOffset - this._majorTicksLength / 2,
+			interval: this.majorTicksInterval,
+			length: this._majorTicksLength
+		});
+		
+		this._setMinorTicksProperty({
+			offset: yOffset - this._minorTicksLength / 2,
+			interval: this.minorTicksInterval,
+			length: this._minorTicksLength
+		});
+		
+		this.removeIndicator(this._needle);
+		this._needle.offset = yOffset;
+		this.addIndicator(this._needle);
+	},
+	
+	_formatNumber: function(val){
+	    var NumberUtils = this._getNumberModule();
+		if(NumberUtils){ // use internationalization if loaded
+			return NumberUtils.format(val, {
+				places: this.scalePrecision
+			});
+		}else{
+			return val.toFixed(this.scalePrecision);
+		}
+	},
+	
+	_computeDataRectangle: function(){
+		// summary: 
+		//		Computes the rectangle that defines the data area of the gauge.
+		
+		
+		if (!this._gaugeStarted) 
+			return;
+		
+		var font = this._font;
+		var leftTextMargin = this._getTextWidth(this._formatNumber(this.min), font) / 2;
+		var rightTextMargin = this._getTextWidth(this._formatNumber(this.max), font) / 2;
+		var textMargin = Math.max(leftTextMargin, rightTextMargin);
+		
+		var margin = this._getBorderWidth() + Math.max(this._majorTicksLength, this._majorTicksLength) / 2 + textMargin;
+		this.dataHeight = this.height;
+		this.dataY = 0;
+		this.dataX = margin + this._margin;
+		this.dataWidth = Math.max(0, this.width - 2 * this.dataX);
+	},
+	
+	_getTextWidth: function(s, font){
+		return gfx._base._getTextBox(s, {
+			font: gfx.makeFontString(gfx.makeParameters(gfx.defaultFont, font))
+		}).w ||
+		0;
+	},
+	
+	_getBorderWidth: function(){
+		// 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: 
+		//		Draws the background of the gauge
+		// group: dojox.gfx.Group
+		//		The GFX group where the background must be drawn
+		if (this._gaugeBackground){
+			return;
+		}
+		
+		var lighterColor = Color.blendColors(new Color(this.color), new Color('white'), 0.4);
+		this._gaugeBackground = group.createGroup();
+
+		var borderWidth = this._getBorderWidth();
+		var margin = this._margin;
+		var w = this.width;
+		var h = this.height;
+		var radius = Math.min(h / 4, 23);
+		this._gaugeBackground.createRect({
+			x: margin,
+			y: margin,
+			width: Math.max(0, w - 2 * margin),
+			height: Math.max(0, h - 2 * margin),
+			r: radius
+		}).setFill(this.color);
+		
+		var left = margin + borderWidth;
+		var right = w - borderWidth - margin;
+		var top = margin + borderWidth;
+		var w2 = w - 2 * borderWidth - 2 * margin;
+		var h2 = h - 2 * borderWidth - 2 * margin;
+		if (w2 <= 0 || h2 <= 0) 
+			return;
+		radius = Math.min(radius, w2 / 2);
+		radius = Math.min(radius, h2 / 2);
+		this._gaugeBackground.createRect({
+			x: left,
+			y: top,
+			width: w2,
+			height: h2,
+			r: radius
+		}).setFill({
+			type: "linear",
+			x1: left,
+			y1: 0,
+			x2: left,
+			y2: h - borderWidth - margin,
+			colors: [{
+				offset: 0,
+				color: lighterColor
+			}, {
+				offset: .2,
+				color: this.color
+			}, {
+				offset: .8,
+				color: this.color
+			}, {
+				offset: 1,
+				color: lighterColor
+			}]
+		});
+		
+		var f = 4 * (Math.sqrt(2) - 1) / 3 * radius;
+		this._gaugeBackground.createPath({
+			path: 'M' + left + ' ' + (top + radius) +
+			'C' +
+			left +
+			' ' +
+			(top + radius - f) +
+			' ' +
+			(left + radius - f) +
+			' ' +
+			top +
+			' ' +
+			(left + radius) +
+			' ' +
+			top +
+			'L' +
+			(right - radius) +
+			' ' +
+			top +
+			'C' +
+			(right - radius + f) +
+			' ' +
+			top +
+			' ' +
+			right +
+			' ' +
+			(top + radius - f) +
+			' ' +
+			right +
+			' ' +
+			(top + radius) +
+			'L' +
+			right +
+			' ' +
+			(top + h / 2) +
+			'L' +
+			left +
+			' ' +
+			(top + h / 3) +
+			'Z'
+		}).setFill({
+			type: "linear",
+			x1: left,
+			y1: top,
+			x2: left,
+			y2: top + this.height / 2,
+			colors: [{
+				offset: 0,
+				color: lighterColor
+			}, {
+				offset: 1,
+				color: Color.blendColors(new Color(this.color), new Color('white'), 0.2)
+			}]
+		});
+	},
+	
+	onValueChanged: function(){
+		// summary:
+		//		Callback when the value of the gauge has changed.
+	
+	},
+	
+	//*******************************************************************************************
+	//* Property getters and setters
+	//*******************************************************************************************
+	
+	_setColorAttr: function(color){
+		// summary: 
+		//		Sets the main color of the gauge
+		// color: String
+		//      The color		
+		this.color = color ? color : 'black';
+		if (this._gaugeBackground && this._gaugeBackground.parent) 
+			this._gaugeBackground.parent.remove(this._gaugeBackground);
+		
+		this._gaugeBackground = null;
+		this.draw();
+	},
+	
+	_setMarkerColorAttr: function(color){
+		// summary: 
+		//		Sets the main color of the marker
+		// color: String
+		//      The color
+		this.markerColor = color;
+		if (this._needle){
+			this.removeIndicator(this._needle);
+			this._needle.color = color;
+			this._needle.shape = null;
+			this.addIndicator(this._needle);
+		}
+	},
+	
+	_setMajorTicksIntervalAttr: function(interval){
+		// summary: 
+		//		Sets the interval between major ticks
+		this.majorTicksInterval = interval;
+		this._setMajorTicksProperty({
+			'interval': this.majorTicksInterval
+		});
+	},
+	
+	setMajorTicksLength: function(length){
+		// summary: 
+		//		Sets the size of the major ticks.
+		this._majorTicksLength = length;
+		this._layoutGauge();
+		return this;
+		
+	},
+	
+	getMajorTicksLength: function(){
+		// summary: 
+		//		Returns the size of the major ticks.
+		return this._majorTicksLength;
+	},
+	
+	_setMajorTicksColorAttr: function(color){
+		// summary: 
+		//		Sets the color of the major ticks.
+		this.majorTicksColor = color;
+		this._setMajorTicksProperty({
+			'color': this.majorTicksColor
+		});
+	},
+	
+	_setMajorTicksProperty: function(prop){
+		if (this.majorTicks == null){
+			return;
+		}
+		lang.mixin(this.majorTicks, prop);
+		this.setMajorTicks(this.majorTicks);
+	},
+	
+	_setMinorTicksIntervalAttr: function(interval){
+		// summary: 
+		//		Sets the interval between minor ticks
+		this.minorTicksInterval = interval;
+		this._setMinorTicksProperty({
+			'interval': this.minorTicksInterval
+		});
+	},
+	
+	setMinorTicksLength: function(length){
+		// summary: 
+		//		Sets the size of the minor ticks.
+		this._minorTicksLength = length;
+		this._layoutGauge();
+		return this;
+	},
+	
+	getMinorTicksLength: function(){
+		// summary: 
+		//		Gets the size of the minor ticks.
+		return this._minorTicksLength;
+	},
+	
+	_setMinorTicksColorAttr: function(color){
+		// summary: 
+		//		Sets the color of the minor ticks.
+		this.minorTicksColor = color;
+		this._setMinorTicksProperty({
+			'color': this.minorTicksColor
+		});
+	},
+	
+	_setMinorTicksProperty: function(prop){
+		if (this.minorTicks == null){
+			return;
+		}
+		lang.mixin(this.minorTicks, prop);
+		this.setMinorTicks(this.minorTicks);
+	},
+	
+	_setMinAttr: function(min){
+		this.min = min;
+		this._computeDataRectangle();
+		if (this.majorTicks != null) 
+			this.setMajorTicks(this.majorTicks);
+		if (this.minorTicks != null) 
+			this.setMinorTicks(this.minorTicks);
+		this.draw();
+	},
+	
+	_setMaxAttr: function(max){
+		this.max = max;
+		this._computeDataRectangle();
+		if (this.majorTicks != null) 
+			this.setMajorTicks(this.majorTicks);
+		if (this.minorTicks != null) 
+			this.setMinorTicks(this.minorTicks);
+		this.draw();
+	},
+	
+	_setValueAttr: function(value){
+		// summary: 
+		//		Changes the value of the gauge
+		// value: Number
+		//		The new value for the gauge.			
+		
+		value = Math.min(this.max, value);
+		value = Math.max(this.min, value);
+		this.value = value;
+		if (this._needle){
+			// update will not work if noChange is true.
+			var noChange = this._needle.noChange;
+			this._needle.noChange = false;
+			this._needle.update(value);
+			this._needle.noChange = noChange;
+		}
+	},
+	
+	_setScalePrecisionAttr: function(value){
+		// summary: 
+		//		Changes precision of the numbers in the scale of the gauge
+		// value: Number
+		//		The new value
+		this.scalePrecision = value;
+		this._layoutGauge();
+	},
+	
+	_setNoChangeAttr: function(value){
+		// 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	
+		this.noChange = value;
+		if (this._needle) 
+			this._needle.noChange = this.noChange;
+	},
+	
+	_setTitleAttr: function(value){
+		// summary: 
+		//		Sets the title displayed by the needle's tooltip .
+		// value: String
+		//		the title
+		
+		this.title = value;
+		if (this._needle){
+			this._needle.title = this.title;
+		}
+	},
+	
+	_setFontAttr: function(font){
+		// summary: 
+		//		Sets the font of the gauge
+		// 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);
+		this._layoutGauge();
+	}
+});
+});
+
diff --git a/dojox/gauges/GlossyHorizontalGaugeMarker.js b/dojox/gauges/GlossyHorizontalGaugeMarker.js
new file mode 100644
index 0000000..d83b7db
--- /dev/null
+++ b/dojox/gauges/GlossyHorizontalGaugeMarker.js
@@ -0,0 +1,129 @@
+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.
+	//
+	// description:
+	//		This object defines the marker for the dojox.gauges.GlossyHorizontalGauge.
+	//		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".
+	//	 	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: "gauge",
+	
+	// color: String
+	// 		The color of the indicator.
+	color: 'black',
+	
+	_getShapes: function(group){
+		// summary:
+		//		Overrides BarLineIndicator._getShapes
+		
+		if (!this._gauge){
+			return null;
+		}
+		var v = this.value;
+		if (v < this._gauge.min){
+			v = this._gauge.min;
+		}
+		if (v > this._gauge.max){
+			v = this._gauge.max;
+		}
+		
+		var pos = this._gauge._getPosition(v);
+		var shapes = [];
+		
+		var color = new Color(this.color);
+		color.a = .67;
+		
+		var lighterColor = Color.blendColors(color, new Color('white'), 0.4);
+		
+		var top = shapes[0] = group.createGroup();
+		var scale = this._gauge.height / 100;
+		scale = Math.max(scale, .5);
+		scale = Math.min(scale, 1);
+		
+		top.setTransform({
+			xx: 1,
+			xy: 0,
+			yx: 0,
+			yy: 1,
+			dx: pos,
+			dy: 0
+		});
+		var marker = top.createGroup().setTransform({
+			xx: 1,
+			xy: 0,
+			yx: 0,
+			yy: 1,
+			dx: -scale * 10,
+			dy: this._gauge.dataY + this.offset
+		});
+		var rescale = marker.createGroup().setTransform({
+			xx: scale,
+			xy: 0,
+			yx: 0,
+			yy: scale,
+			dx: 0,
+			dy: 0
+		});
+		
+		rescale.createRect({
+			x: .5,
+			y: .0,
+			width: 20,
+			height: 47,
+			r: 6
+		}).setFill(color).setStroke(lighterColor);
+		rescale.createPath({
+			path: 'M 10.106 41 L 10.106 6 C 10.106 2.687 7.419 0 4.106 0 L 0.372 0 C -0.738 6.567 1.022 15.113 1.022 23.917 C 1.022 32.721 2.022 40.667 0.372 47 L 4.106 47 C 7.419 47 10.106 44.314 10.106 41 Z'
+		}).setFill(lighterColor).setTransform({
+			xx: 1,
+			xy: 0,
+			yx: 0,
+			yy: 1,
+			dx: 10.306,
+			dy: 0.009
+		});
+		rescale.createRect({
+			x: 9.5,
+			y: 1.5,
+			width: 2,
+			height: 34,
+			r: 0.833717
+		}).setFill(color).setStroke(this.color);
+		rescale.createRect({
+			x: 9,
+			y: 0,
+			width: 3,
+			height: 34,
+			r: 6
+		}).setFill({
+			type: "linear",
+			x1: 9,
+			y1: 0,
+			x2: 9,
+			y2: 34,
+			colors: [{
+				offset: 0,
+				color: 'white'
+			}, {
+				offset: 1,
+				color: this.color
+			}]
+		});
+		return shapes;
+	}
+	
+});
+});
\ No newline at end of file
diff --git a/dojox/gauges/GlossySemiCircularGauge.js b/dojox/gauges/GlossySemiCircularGauge.js
new file mode 100644
index 0000000..827c4e4
--- /dev/null
+++ b/dojox/gauges/GlossySemiCircularGauge.js
@@ -0,0 +1,244 @@
+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.
+	//
+	// example:
+	//	|	<div	dojoType="dojox.gauges.GlossySemiCircularGauge"
+	//	|		id="testGauge"
+	//	|		width="300"
+	//	|		height="300"
+	//	|		min="0"
+	//	|		max="100"
+	//	|		value="0" 
+	//	|		majorTicksInterval="10"
+	//	|		majorTicksColor="#c4c4c4"
+	//	|		minorTicksInterval="5"
+	//	|		minorTicksColor="#c4c4c4"
+	//	|		color="black" 
+	//	|		needleColor="#c4c4c4"
+	//	|		font="normal normal normal 10pt sans-serif"
+	//	|		textIndicatorFont="normal normal normal 20pt sans-serif"
+	//	|		textIndicatorVisible="true" 
+	//	|		textIndicatorColor="#c4c4c4" 
+	//	|		majorTicksLabelPlacement="inside"|"outside"
+	//	|		noChange="true"
+	//	|		title="title"
+	//	|		scalePrecision="0"
+	//	|		textIndicatorPrecision="0"
+	//	|	>
+	//	|	</div>
+	
+	
+	_designWidth: 381.25,
+	_designHeight: 221.25,
+	_designCx: 190.6675,
+	_designCy: 185.87665,
+	_designTextIndicatorX: 190.6675,
+	_designTextIndicatorY: 145.87665,
+	
+
+	constructor: function(){
+		// summary: 
+		//		Creates a new GlossySemiCircularGauge
+		this.min = 0;
+		this.max = 100;
+		this.startAngle = -91.5;
+		this.endAngle = 91.5;
+	},
+
+	drawBackground: function(group){
+		// summary: 
+		//		Draws the background of the gauge
+		// group: dojox.gfx.Group
+		//		The GFX group where the background must be drawn
+		var lighterColor1 = Color.blendColors(new Color(this.color), new Color('white'), 0.4);
+		var lighterColor2 = Color.blendColors(new Color(this.color), new Color('white'), 0.8);
+		
+		var scale = Math.min((this.width / this._designWidth), (this.height / this._designHeight));
+		var transform = {
+			xx: scale,
+			xy: 0,
+			yx: 0,
+			yy: scale,
+			dx: -23.33928 * scale + (this.width - scale * this._designWidth) / 2,
+			dy: -483.30859 * scale + (this.height - scale * this._designHeight) / 2
+		};
+		
+		
+		if (this._gaugeBackground) {
+			this._gaugeBackground.setTransform(transform);
+			return;
+		}
+		this._gaugeBackground = group.createGroup();
+		this._gaugeBackground.setTransform(transform);
+		this._gaugeBackground.createPath({
+			path: "M0 0 C0.023 0.892 0.037 9.147 0.045 15.97 C-0.349 98.05 -67.016 164.455 -149.182 164.427 C-231.347 164.398 -297.969 97.949 -298.307 15.869 C-298.299 9.081 -298.285 0.884 -298.262 -0.006 C-298.119 -5.424 -293.686 -9.742 -288.265 -9.742 L-9.996 -9.742 C-4.574 -9.742 -0.139 -5.42 0 0"
+		}).setTransform({
+			xx: 1.25,
+			xy: 0,
+			yx: 0,
+			yy: -1.25,
+			dx: 400.74198,
+			dy: 690.00586
+		}).setFill(this.color);
+		
+		this._gaugeBackground.createPath({
+			path: "M451.297 436.5 C451.333 437.807 451.355 449.118 451.354 450.434 L451.354 450.527 C451.329 526.644 389.604 588.327 313.487 588.302 C237.372 588.275 175.688 526.551 175.713 450.434 C175.713 450.403 175.735 437.776 175.771 436.5 L451.297 436.5 Z"
+		}).setTransform({
+			xx: 1.25,
+			xy: 0,
+			yx: 0,
+			yy: -1.25,
+			dx: -177.58928,
+			dy: 1234.05859
+		}).setFill({
+			type: "linear",
+			x1: 175.688,
+			y1: 390.95189,
+			x2: 175.688,
+			y2: 474.45676,
+			colors: [{
+				offset: 0,
+				color: lighterColor1
+			}, {
+				offset: 1,
+				color: this.color
+			}]
+		});
+		this._gaugeBackground.createPath({
+			path: "M451.321 453.375 C449.778 528.175 388.655 588.327 313.491 588.302 C238.359 588.276 177.295 528.135 175.753 453.377 C217.829 442.046 266.246 464.646 315.36 464.646 C364.489 464.646 409.364 442.041 451.321 453.375"
+		}).setTransform({
+			xx: 1.25,
+			xy: 0,
+			yx: 0,
+			yy: -1.25,
+			dx: -177.58928,
+			dy: 1234.05859
+		}).setFill({
+			type: "linear",
+			x1: 175.75301,
+			y1: 442.04099,
+			x2: 175.75301,
+			y2: 588.32703,
+			colors: [{
+				offset: 0,
+				color: this.color
+			}, {
+				offset: 1,
+				color: lighterColor2
+			}]
+		});
+		this._gaugeBackground.createPath({
+			path: "M0 0 C-1.543 74.8 -62.666 134.952 -137.83 134.927 C-212.962 134.901 -274.026 74.76 -275.568 0.002 C-233.492 -11.329 -185.075 11.271 -135.961 11.271 C-86.832 11.271 -41.957 -11.334 0 0"
+		}).setTransform({
+			xx: 1.25,
+			xy: 0,
+			yx: 0,
+			yy: -1.25,
+			dx: 386.81123,
+			dy: 667.59241
+		}).setFill([255, 255, 255, 0.12157]);
+	},
+	
+	
+	drawForeground: function(group){
+		// summary: 
+		//		Draws the foreground of the gauge
+		// group: dojox.gfx.Group
+		//		The GFX group where the foreground must be drawn
+		var scale = Math.min((this.width / this._designWidth), (this.height / this._designHeight));
+		var transform = {
+			xx: scale,
+			xy: 0,
+			yx: 0,
+			yy: scale,
+			dx: (-160) * scale + (this.width - scale * this._designWidth) / 2,
+			dy: (-264.5) * scale + (this.height - scale * this._designHeight) / 2
+		};
+		
+		var lighterColor1 = Color.blendColors(new Color(this.color), new Color('white'), 0.4);
+		var lighterColor2 = Color.blendColors(new Color(this.color), new Color('white'), 0.8);
+		
+		if (this._foreground) {
+			this._foreground.setTransform(transform);
+			return;
+		}
+		this._foreground = group.createGroup();
+		this._foreground.setTransform(transform);
+		
+		var group1 = this._foreground.createGroup().setTransform({
+			xx: 1.25,
+			xy: 0,
+			yx: 0,
+			yy: -1.25,
+			dx: -43.30358,
+			dy: 1015.57642
+		});
+		group1.createPath({
+			path: "M0 0 C0.004 -12.579 -10.189 -22.779 -22.768 -22.784 C-35.349 -22.788 -45.549 -12.594 -45.553 -0.016 L-45.553 0 C-45.558 12.579 -35.363 22.779 -22.783 22.784 C-10.205 22.788 -0.004 12.594 0 0.015 L0 0 Z"
+		}).setTransform({
+			xx: 1,
+			xy: 0,
+			yx: 0,
+			yy: 1,
+			dx: 336.31049,
+			dy: 451.43359
+		}).setFill(this.color);
+		
+		group1.createPath({
+			path: "M333.443 451.434 C333.446 440.438 324.537 431.523 313.541 431.519 C302.546 431.515 293.63 440.425 293.626 451.42 L293.626 451.434 C293.622 462.429 302.532 471.345 313.527 471.349 C324.523 471.353 333.439 462.442 333.443 451.447 L333.443 451.434 Z"
+		}).setFill({
+			type: "linear",
+			x1: 293.62201,
+			y1: 431.51501,
+			x2: 293.62201,
+			y2: 451.43401,
+			colors: [{
+				offset: 0,
+				color: lighterColor1
+			}, {
+				offset: 1,
+				color: this.color
+			}]
+		});
+		
+		group1.createPath({
+			path: "M333.438 451.858 C333.215 462.663 324.386 471.353 313.528 471.349 C302.675 471.345 293.854 462.658 293.632 451.858 C299.709 450.222 306.702 453.486 313.799 453.486 C320.895 453.486 327.377 450.221 333.438 451.858"
+		}).setFill({
+			type: "linear",
+			x1: 293.63199,
+			y1: 450.22101,
+			x2: 293.63199,
+			y2: 471.353,
+			colors: [{
+				offset: 0,
+				color: this.color
+			}, {
+				offset: 1,
+				color: lighterColor2
+			}]
+		});
+		
+		group1.createPath({
+			path: "M0 0 C-0.223 10.805 -9.052 19.494 -19.909 19.49 C-30.763 19.486 -39.583 10.799 -39.806 0 C-33.729 -1.636 -26.735 1.628 -19.639 1.628 C-12.543 1.628 -6.061 -1.638 0 0"
+		}).setTransform({
+			xx: 1,
+			xy: 0,
+			yx: 0,
+			yy: 1,
+			dx: 333.4375,
+			dy: 451.8584
+		}).setFill([255, 255, 255, 0.12157]);
+		
+	}
+	
+	
+});
+});
diff --git a/dojox/gauges/Range.js b/dojox/gauges/Range.js
new file mode 100644
index 0000000..030201f
--- /dev/null
+++ b/dojox/gauges/Range.js
@@ -0,0 +1,73 @@
+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"]);
+	//	|	</script>
+	//	|	...
+	//	|	<div	dojoType="dojox.gauges.AnalogGauge"
+	//	|			id="testGauge"
+	//	|			width="300"
+	//	|			height="200"
+	//	|			cx=150
+	//	|			cy=175
+	//	|			radius=125
+	//	|			image="gaugeOverlay.png"
+	//	|			imageOverlay="false"
+	//	|			imageWidth="280"
+	//	|			imageHeight="155"
+	//	|			imageX="12"
+	//	|			imageY="38">
+	//	|		<div	dojoType="dojox.gauges.Range"
+	//	|				low=5
+	//	|				high=10
+	//	|				hover="5 - 10"
+	//	|		></div>
+	//	|		<div	dojoType="dojox.gauges.Range"
+	//	|				low=10
+	//	|				high=20
+	//	|				hover="10 - 20"
+	//	|		></div>
+	//	|	</div>
+	
+	// low: Number
+	// 		the low value of the range
+	low: 0,
+	
+	// high: Number
+	// 		the high value of the range
+	high: 0,
+	
+	// hover: String
+	// 		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'}] }
+	color: null,
+	
+	// size: Number
+	// 		for a circular gauge (such as an AnalogGauge), this dictates the size of the arc
+	size: 0,
+
+	startup: function(){
+		this.color = this.color ? ( this.color.color || this.color) : 'black';
+	}
+});
+});
\ No newline at end of file
diff --git a/dojox/gauges/TextIndicator.js b/dojox/gauges/TextIndicator.js
new file mode 100644
index 0000000..90442b8
--- /dev/null
+++ b/dojox/gauges/TextIndicator.js
@@ -0,0 +1,78 @@
+define(["dojo/_base/declare","./_Indicator"],
+  function(declare, Indicator) { 
+
+/*=====
+	Indicator = dojox.gauges._Indicator;
+=====*/
+
+return declare("dojox.gauges.TextIndicator", [Indicator], {
+	// summary:
+	//		A gauge indicator the simply draws its value as text.
+	
+	
+	// x: Number
+	// 		The x coordinate of the indicator
+	x: 0,
+	
+	// y: Number
+	// 		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'
+	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).
+	fixedPrecision: true,
+	
+	// precision: Number
+	//		The number of tailing digits to display the value of the indicator when the 'fixedPrecision' property is set to true (default is 0).
+	precision: 0,
+	
+	draw: function(group, /*Boolean?*/ dontAnimate){
+		// summary: 
+		//		Override of dojox.gauges._Indicator.draw
+		var v = this.value;
+		
+		if (v < this._gauge.min) {
+			v = this._gauge.min;
+		}
+		if (v > this._gauge.max) {
+			v = this._gauge.max;
+		}
+		var txt;
+		var NumberUtils = this._gauge ? this._gauge._getNumberModule() : null;
+		if (NumberUtils) {
+			txt = this.fixedPrecision ? NumberUtils.format(v, {
+				places: this.precision
+			}) : NumberUtils.format(v);
+		} else {
+			txt = this.fixedPrecision ? v.toFixed(this.precision) : v.toString();
+		}
+		
+		var x = this.x ? this.x : 0;
+		var y = this.y ? this.y : 0;
+		var align = this.align ? this.align : "middle";
+		if(!this.shape){
+			this.shape = group.createText({
+				x: x,
+				y: y,
+				text: txt,
+				align: align
+			});
+		}else{
+			this.shape.setShape({
+				x: x,
+				y: y,
+				text: txt,
+				align: align
+			});
+		}
+		this.shape.setFill(this.color);
+		if (this.font) this.shape.setFont(this.font);
+		
+	}
+	
+});
+});
diff --git a/dojox/gauges/_Gauge.css b/dojox/gauges/_Gauge.css
new file mode 100644
index 0000000..46dd7fb
--- /dev/null
+++ b/dojox/gauges/_Gauge.css
@@ -0,0 +1,63 @@
+ at CHARSET "ISO-8859-1";
+
+.dojoxGaugeContent {
+	font-family: Verdana;
+	border-width: 1px;
+	border-style: solid;
+	border-color: #CCCCCC;
+}
+
+.dojoxGaugeRange1 {
+	fill: #606060 ;
+	stroke: #606060 ;
+}
+
+.dojoxGaugeRange2 {
+	fill: #707070 ;
+	stroke: #707070 ;
+}
+
+.dojoxGaugeRange3 {
+	fill: #808080 ;
+	stroke: #808080 ;
+}
+
+.dojoxGaugeRange4 {
+	fill: #909090 ;
+	stroke: #909090 ;
+}
+
+.dojoxGaugeRange5 {
+	fill: #A0A0A0;
+	stroke: #A0A0A0;
+}
+
+.dojoxGaugeRange6 {
+	fill: #B0B0B0;
+	stroke: #B0B0B0;
+}
+
+.dojoxGaugeRange7 {
+	fill: #C0C0C0;
+	stroke: #C0C0C0;
+}
+
+.dojoxGaugeRange8 {
+	fill: #D0D0D0;
+	stroke: #D0D0D0;
+}
+
+.dojoxGaugeRange9 {
+	fill: #E0E0E0;
+	stroke: #E0E0E0;
+}
+
+.dojoxGaugeRange10 {
+	fill: #F0F0F0;
+	stroke: #F0F0F0;
+}
+
+.testing {
+	fill: blue;
+	stroke: blue;
+}
diff --git a/dojox/gauges/_Gauge.js b/dojox/gauges/_Gauge.js
new file mode 100644
index 0000000..4bb8398
--- /dev/null
+++ b/dojox/gauges/_Gauge.js
@@ -0,0 +1,844 @@
+define(["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) {
+
+	var _tooltipModule =  0;
+	var _numberModule =  0;
+
+/*=====
+	Widget = dijit._Widget;
+=====*/
+	
+return declare("dojox.gauges._Gauge",[Widget],{
+	// summary:
+	//		The abstract base class for gauges.
+	//
+	// description:
+	//		using dojo.gfx (and thus either SVG or VML based on what is supported), this widget
+	//		builds a gauge component, used to display numerical data in a familiar format.
+	//		This widget is not to be used alone. it is meant to be subclassed, such as
+	//		dojox.gauges.BarGauge or dojox.gauges.AnalogGauge
+
+	// width: Number
+	//		The width of the gauge (default is 300)
+	width: 0,
+
+	// height: Number
+	//		The height of the gauge (default is 200)
+	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'}] }
+	background: null,
+
+	// image: String
+	// 		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)
+	useRangeStyles: 0,
+
+	// useTooltip: Boolean
+	// 		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 *):
+	//		- 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"}
+	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.
+	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.
+	_defaultIndicator: null,
+
+	// defaultColors: Array
+	//		 Set of default colors to color ranges with.
+	defaultColors: [[0x00,0x54,0xAA,1],
+					[0x44,0x77,0xBB,1],
+					[0x66,0x99,0xCC,1],
+					[0x99,0xBB,0xEE,1],
+					[0x99,0xCC,0xFF,1],
+					[0xCC,0xEE,0xFF,1],
+					[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.
+	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.
+	max: null,
+	
+	// surface: Object
+	// 		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.
+	hideValues: false,
+
+	// internal data
+	gaugeContent: undefined,
+	_backgroundDefault: {color: '#E0E0E0'},
+	_rangeData: null,
+	_indicatorData: null,
+	_drag: null,
+	_img: null,
+	_overOverlay: false,
+	_lastHover: '',
+
+	startup: function(){
+		// handle settings from HTML by making sure all the options are
+		// converted correctly to numbers and that we calculate defaults
+		// for cx, cy and radius
+		if(this.image === null){
+			this.image={};
+		}
+		
+		this.connect(this.gaugeContent, 'onmousedown', this.handleMouseDown);
+		this.connect(this.gaugeContent, 'onmousemove', this.handleMouseMove);
+		this.connect(this.gaugeContent, 'onmouseover', this.handleMouseOver);
+		this.connect(this.gaugeContent, 'onmouseout', this.handleMouseOut);
+		this.connect(this.gaugeContent, 'touchstart', this.handleTouchStart);
+		this.connect(this.gaugeContent, 'touchend', this.handleTouchEnd);
+		this.connect(this.gaugeContent, 'touchmove', this.handleTouchMove);	
+
+		if(!lang.isArray(this.ranges)){ this.ranges = []; }
+		if(!lang.isArray(this.indicators)){ this.indicators = []; }
+		var ranges = [], indicators = [];
+		var i;
+		if(this.hasChildren()){
+			var children = this.getChildren();
+			for(i=0; i<children.length; i++){
+				if(/.*Indicator/.test(children[i].declaredClass)){
+					indicators.push(children[i]);
+					//this.addIndicator(children[i]);
+					continue;
+				}
+
+				switch(children[i].declaredClass){
+					case Range.prototype.declaredClass:
+						ranges.push(children[i]);
+						break;
+				}
+			}
+			this.ranges = this.ranges.concat(ranges);
+			this.indicators = this.indicators.concat(indicators);
+		}
+		if(!this.background){ this.background = this._backgroundDefault; }
+		this.background = this.background.color || this.background;
+		if(!this.surface){ this.createSurface(); }
+
+		this.addRanges(this.ranges);
+		if(this.minorTicks && this.minorTicks.interval){
+			this.setMinorTicks(this.minorTicks);
+		}
+		if(this.majorTicks && this.majorTicks.interval){
+			this.setMajorTicks(this.majorTicks);
+		}
+		for(i=0; i<this.indicators.length; i++){
+			this.addIndicator(this.indicators[i]);
+		}
+		this.inherited(arguments);
+	},
+	
+	hasChildren: function(){
+		// summary:
+		//		Returns true if widget has children, i.e. if this.containerNode contains something.
+		return this.getChildren().length > 0;	// Boolean
+	},
+	
+	buildRendering: function(){
+		// summary: 
+		//		Overrides _Widget.buildRendering
+		var n = this.domNode = this.srcNodeRef ? this.srcNodeRef: dom.create("div");
+		this.gaugeContent = dom.create("div", {
+			className: "dojoxGaugeContent"
+		});
+		this.containerNode = dom.create("div");
+		this.mouseNode = dom.create("div");
+		while(n.hasChildNodes()){
+			this.containerNode.appendChild(n.firstChild);
+		}
+		dom.place(this.gaugeContent, n);
+		dom.place(this.containerNode, n);
+		dom.place(this.mouseNode, n);
+	},
+
+	_setTicks: function(/*Object*/ oldTicks, /*Object*/ newTicks, /*Boolean*/ major){
+		// summary: 
+		//		internal method used to clear existing tick marks, then add new ones
+		var i;
+		if (oldTicks && lang.isArray(oldTicks._ticks)){
+			for (i = 0; i < oldTicks._ticks.length; i++){
+				this._removeScaleTick(oldTicks._ticks[i]);
+			}
+		}
+		var t = {
+			length: newTicks.length,
+			offset: newTicks.offset,
+			noChange: true
+		};
+		if (newTicks.color){
+			t.color = newTicks.color;
+		}
+		if (newTicks.font){
+			t.font = newTicks.font;
+		}
+		if (newTicks.labelPlacement){
+			t.direction = newTicks.labelPlacement;
+		}
+		newTicks._ticks = [];
+		for (i=this.min;i<=this.max;i+=newTicks.interval){
+			if (i==this.max&&this._isScaleCircular()) continue; // do not draw last tick on fully circular gauges
+			t.value=i;
+			if (major){
+				var NumberUtils = this._getNumberModule();
+				if (NumberUtils){ // use internationalization if loaded
+					t.label = (newTicks.fixedPrecision && newTicks.precision) ? NumberUtils.format(i, {
+						places: newTicks.precision
+					}): NumberUtils.format(i);
+				}else{
+					t.label = (newTicks.fixedPrecision && newTicks.precision) ? i.toFixed(newTicks.precision): i.toString();
+				}
+			}
+			newTicks._ticks.push(this._addScaleTick(t, major));
+		}
+		return newTicks;
+	},
+	
+	_isScaleCircular: function(){
+		// summary: 
+		//		Internal method to check if the scale is fully circular
+		return false;
+	},
+	
+	setMinorTicks: function(/*Object*/ ticks){
+		// summary:
+		//		Creates and draws the minor tick marks based on the passed object (expecting the same format
+		//		as the minorTicks object documented above)
+		this.minorTicks = this._setTicks(this.minorTicks, ticks, false);
+	},
+
+	setMajorTicks: function(/*Object*/ ticks){
+		// summary:
+		//		Creates and draws the major tick marks based on the passed object (expecting the same format
+		//		as the majorTicks object documented above)
+		this.majorTicks = this._setTicks(this.majorTicks, ticks, true);
+	},
+
+	postCreate: function(){
+		if(this.hideValues){
+			html.style(this.containerNode, "display", "none");
+		}
+		html.style(this.mouseNode, 'width', '0');
+		html.style(this.mouseNode, 'height', '0');
+		html.style(this.mouseNode, 'position', 'absolute');
+		html.style(this.mouseNode, 'z-index', '100');
+
+		if(this.useTooltip){
+			require(["dijit/Tooltip"], dojo.hitch(this, function(Tooltip){
+				Tooltip.show('test', this.mouseNode, !this.isLeftToRight());
+				Tooltip.hide(this.mouseNode);
+			}));
+		}
+	},
+
+	_getNumberModule :function() {
+		// summary:
+		//		Tests is AMD dojo/number is loaded
+		
+		if (_numberModule == 0) {
+			try {
+				_numberModule = require("dojo/number");
+			} 
+			catch (e) {
+				_numberModule = null;
+			}
+		}
+		return _numberModule;
+	},
+	
+	createSurface: function(){
+		// summary:
+		//		Internal method used by the gauge to create the graphics surface area
+		this.gaugeContent.style.width = this.width + 'px';
+		this.gaugeContent.style.height = this.height + 'px';
+		this.surface = gfx.createSurface(this.gaugeContent, this.width, this.height);
+		
+		// create several groups where various gauge elements will be created.
+		this._backgroundGroup = this.surface.createGroup();
+		this._rangeGroup = this.surface.createGroup();
+		this._minorTicksGroup = this.surface.createGroup();
+		this._majorTicksGroup = this.surface.createGroup();
+		this._overlayGroup = this.surface.createGroup();
+		this._indicatorsGroup = this.surface.createGroup();
+		this._foregroundGroup = this.surface.createGroup();
+		
+		this._background = this._backgroundGroup.createRect({x: 0, y: 0, width: this.width, height: this.height });
+		this._background.setFill(this.background);
+
+		if(this.image.url){
+			var imageGroup = this._backgroundGroup;
+			if (this.image.overlay)
+			   imageGroup = this._overlayGroup;
+			   
+			this._img = imageGroup.createImage({width: this.image.width || this.width, height: this.image.height || this.height, src: this.image.url});
+			if(this.image.x || this.image.y){
+				this._img.setTransform({dx: this.image.x || 0, dy: this.image.y || 0});
+			}
+		}
+	},
+
+	draw: function(){
+		// summary:
+		//		This function is used to draw (or redraw) the gauge.
+		// description:
+		//		Draws the gauge by drawing the surface, the ranges, and the indicators.
+		var i;
+		if (!this.surface)return;
+		
+		this.drawBackground(this._backgroundGroup);
+		
+		if(this._rangeData){
+			for(i=0; i<this._rangeData.length; i++){
+				this.drawRange(this._rangeGroup, this._rangeData[i]);
+			}
+		}
+		
+		if(this._minorTicksData){
+			for(i=0; i<this._minorTicksData.length; i++){
+				this._minorTicksData[i].draw(this._minorTicksGroup);
+			}
+		}
+		if(this._majorTicksData){
+			for(i=0; i<this._majorTicksData.length; i++){
+				this._majorTicksData[i].draw(this._majorTicksGroup);
+			}
+		}
+		
+		if(this._indicatorData){
+			for(i=0; i<this._indicatorData.length; i++){
+				this._indicatorData[i].draw(this._indicatorsGroup);
+			}
+		}
+		this.drawForeground(this._foregroundGroup);
+	},
+
+
+	drawBackground:function(group){
+		// summary:
+		//		This function is used to draw (or redraw) the background of the gauge.
+		// description:
+		//		The method may be used by subclasses to draw (or redraw) the background of the gauge.
+		
+	},
+	
+	drawForeground:function(group){
+		// summary:
+		//		This function is used to draw (or redraw) the foreground of the gauge.
+		// description:
+		//		The method may be used by subclasses to draw (or redraw) the foreground of the gauge.
+		
+	},
+
+	setBackground: function(background){
+		// summary:
+		//		This method is used to set the background of the gauge after it is created.
+		// description:
+		//		Sets the background using the given object.  Must be the same 'type' of object
+		//		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'}] }
+		//		If background is null or undefined, this will set the fill to this._backgroundDefault
+		if(!background){ background = this._backgroundDefault; }
+		this.background = background.color || background;
+		this._background.setFill(this.background);
+	},
+
+	addRange: function(/*Object*/range){
+		// summary:
+		//		This method is used to add a range to the gauge.
+		// description:
+		//		Creates a range (colored area on the background of the gauge)
+		//		based on the given arguments.
+		// range: Object
+		//		A range is either a dojox.gauges.Range object, or a object
+		//		with similar parameters (low, high, hover, etc.).
+		this.addRanges([range]);
+	},
+
+	addRanges: function(/*Array*/ranges){
+		// summary:
+		//		This method is used to add ranges to the gauge.
+		// description:
+		//		Creates a range (colored area on the background of the gauge)
+		//		based on the given arguments.
+		// range: Range
+		//		A range is either a dojox.gauges.Range object, or a object
+		//		with similar parameters (low, high, hover, etc.).
+		if(!this._rangeData){
+			this._rangeData = [];
+		}
+		var range;
+		for(var i=0; i<ranges.length; i++){
+			range = ranges[i];
+			if((this.min === null) || (range.low < this.min)){this.min = range.low;}
+			if((this.max === null) || (range.high > this.max)){this.max = range.high;}
+
+			if(!range.color){
+				var colorIndex = this._rangeData.length % this.defaultColors.length;
+				if(gfx.svg && this.useRangeStyles > 0){
+					colorIndex = (this._rangeData.length % this.useRangeStyles)+1;
+					range.color = {style: "dojoxGaugeRange"+colorIndex};
+				}else{
+					colorIndex = this._rangeData.length % this.defaultColors.length;
+					range.color = this.defaultColors[colorIndex];
+				}
+			}
+			this._rangeData[this._rangeData.length] = range;
+		}
+		this.draw();
+	},
+
+	_addScaleTick: function(/*Object*/indicator, /*Boolean*/ major){
+		// summary:
+		//		Adds a scale ticks, that is an indicator.
+		// description:
+		//		This method adds  a tick mark to the gauge
+		// indicator: dojox.gauges._Indicator
+		//		A dojox.gauges._Indicator or an object with similar parameters
+		//		(value, color, offset, etc.).
+	
+		if(!indicator.declaredClass){// !== 'dojox.gauges.Indicator'){
+			// We were passed a plain object, need to make an indicator out of it.
+			indicator = new this._defaultIndicator(indicator);
+		}
+	
+		indicator._gauge = this;
+		if (major){
+			if (!this._majorTicksData){
+				this._majorTicksData = [];
+			}
+			this._majorTicksData[this._majorTicksData.length] = indicator;
+			indicator.draw(this._majorTicksGroup);
+		} else {
+				if (!this._minorTicksData){
+				this._minorTicksData = [];
+			}
+			this._minorTicksData[this._minorTicksData.length] = indicator;
+			indicator.draw(this._minorTicksGroup);
+		}
+		return indicator;
+	},
+	
+	_removeScaleTick: function(/*Object*/indicator){
+		// summary:
+		//		Removes the given scale tick from the gauge by calling it's remove function 
+		//		and removing it from the local cache.
+		var i;
+		if (this._majorTicksData) for (i = 0; i < this._majorTicksData.length; i++){
+			if (this._majorTicksData[i] === indicator){
+				this._majorTicksData.splice(i, 1);
+				indicator.remove();
+				return;
+			}
+		}
+		if (this._minorTicksData) for (i = 0; i < this._minorTicksData.length; i++){
+			if (this._minorTicksData[i] === indicator){
+				this._minorTicksData.splice(i, 1);
+				indicator.remove();
+				return;
+			}
+		}
+	},
+	
+	addIndicator: function(/*Object*/indicator){
+		// summary:
+		//		This method is used to add an indicator to the gauge.
+		// description:
+		//		This method adds an indicator, such as a t needle,
+		//		to the gauge.
+		// indicator: dojox.gauges._Indicator
+		//		A dojox.gauges._Indicator or an object with similar parameters
+		//		(value, color, offset, etc.).
+
+		if(!indicator.declaredClass){// !== 'dojox.gauges.Indicator'){
+			// We were passed a plain object, need to make an indicator out of it.
+			indicator = new this._defaultIndicator(indicator);
+		}
+		indicator._gauge = this;
+		if(!indicator.hideValue){
+			this.containerNode.appendChild(indicator.domNode);
+		}
+		if(!this._indicatorData){this._indicatorData = [];}
+		this._indicatorData[this._indicatorData.length] = indicator;
+		indicator.draw(this._indicatorsGroup);
+		return indicator;
+	},
+
+	removeIndicator: function(/*Object*/indicator){
+		// summary:
+		//		Removes the given indicator from the gauge by calling it's remove function 
+		//		and removing it from the local cache.
+		// indicator: dojox.gauges._Indicator
+		//		The indicator to remove.
+		for(var i=0; i<this._indicatorData.length; i++){
+			if(this._indicatorData[i] === indicator){
+				this._indicatorData.splice(i, 1);
+				indicator.remove();
+				break;
+			}
+		}
+	},
+
+	moveIndicatorToFront: function(/*Object*/indicator){
+		// summary:
+		//		This function is used to move an indicator the the front (top)
+		//		of the gauge
+		// indicator: dojox.gauges._Indicator
+		//		A dojox.gauges._Indicator or an object with similar parameters
+		//		(value, color, offset, etc.).
+		if(indicator.shape)
+		   indicator.shape.moveToFront();
+		
+	},
+
+	drawText: function(/*dojox.gfx.Group*/ group, /*String*/txt, /*Number*/x, /*Number*/y, /*String?*/align, /*String?*/color, /*Object?*/font){
+		// summary:
+		//		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"}
+
+		var t = group.createText({x: x, y: y, text: txt, align: align});
+		t.setFill(color ? color: 'black');
+		if (font) t.setFont(font);
+		return t;
+	},
+
+	removeText:function(/*String*/t){
+		// summary:
+		//		Removes a text element from the gauge.
+		// t:	String
+		//		The text to remove.
+		if (t.parent)
+	    	t.parent.remove(t);
+	},
+
+	updateTooltip: function(/*String*/txt, /*Event*/ e){
+		// summary:
+		//		Updates the tooltip for the gauge to display the given text.
+		// txt:		String
+		//		The text to put in the tooltip.
+	
+		if (this.useTooltip) {
+			require(["dijit/Tooltip"], dojo.hitch(this, function(Tooltip){
+				if (this._lastHover != txt) {
+					if (txt !== '') {
+						Tooltip.hide(this.mouseNode);
+						Tooltip.show(txt, this.mouseNode, !this.isLeftToRight());
+					} else {
+						Tooltip.hide(this.mouseNode);
+					}
+					this._lastHover = txt;
+				}
+			}));
+		}
+	},
+
+	handleMouseOver: function(/*Object*/e){
+		// summary:
+		//		This is an internal handler used by the gauge to support 
+		//		hover text
+		// e:	Object
+		//		The event object
+		
+		if (this.image && this.image.overlay){
+			if (e.target == this._img.getEventSource()){
+				var hover;
+				this._overOverlay = true;
+				var r = this.getRangeUnderMouse(e);
+				if (r && r.hover){
+					hover = r.hover;
+				}
+				
+				if (this.useTooltip && !this._drag){					
+					if (hover){
+						this.updateTooltip(hover, e);
+					} else {
+						this.updateTooltip('', e);
+					}
+				}
+			}
+		}
+	},
+
+	handleMouseOut: function(/*Object*/e){
+		// summary:
+		//		This is an internal handler used by the gauge to support
+		//		hover text
+		// e:	Object
+		//		The event object
+
+		this._overOverlay = false;
+		this._hideTooltip();
+	},
+
+	handleMouseMove: function(/*Object*/e){
+		// summary:
+		//		This is an internal handler used by the gauge to support using
+		//		the mouse to show the tooltips
+		// e:	Object
+		//		The event object
+			
+		if (this.useTooltip) {
+				if (e) {
+					html.style(this.mouseNode, 'left', e.pageX + 1 + 'px');
+					html.style(this.mouseNode, 'top', e.pageY + 1 + 'px');
+				}
+				if (this._overOverlay) {
+					var r = this.getRangeUnderMouse(e);
+					if (r && r.hover) {
+						this.updateTooltip(r.hover, e);
+					} else {
+						this.updateTooltip('', e);
+					}
+				}
+		}
+	},
+	
+	handleMouseDown: function(e){
+		// summary:
+		//		This is an internal handler used by the gauge to support using
+		//		the mouse to move indicators
+		// e:	Object
+		//		The event object
+		var indicator = this._getInteractiveIndicator();
+		if (indicator){
+			this._handleMouseDownIndicator(indicator, e);
+		}
+	},	
+	
+	_handleDragInteractionMouseMove: function(e){
+		// 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
+		//		The event object
+		
+		if(this._drag){
+			this._dragIndicator(this, e);
+			event.stop(e);
+		}
+	},
+	
+	_handleDragInteractionMouseUp: function(/*Object*/e){
+		// 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
+		//		The event object
+		this._drag = null;
+		
+		for (var i = 0 ; i < this._mouseListeners.length; i++){
+			connect.disconnect(this._mouseListeners[i]);
+		}
+		this._mouseListeners = [];
+		event.stop(e);
+	},
+	
+	_handleMouseDownIndicator: function (indicator, e){
+		// summary:
+		//		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 event object
+		
+		if (!indicator.noChange){
+			if (!this._mouseListeners) this._mouseListeners = [];
+			this._drag = indicator;
+			this._mouseListeners.push(connect.connect(document, "onmouseup", this, this._handleDragInteractionMouseUp));
+			this._mouseListeners.push(connect.connect(document, "onmousemove", this, this._handleDragInteractionMouseMove));
+			this._mouseListeners.push(connect.connect(document, "ondragstart", this, event.stop));
+			this._mouseListeners.push(connect.connect(document, "onselectstart", this, event.stop));
+			this._dragIndicator(this, e);
+			event.stop(e);
+		}
+	},
+	
+	_handleMouseOverIndicator: function (indicator, e){
+		// summary:
+		//		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 event object	
+		if (this.useTooltip && !this._drag){
+			
+			if (indicator.hover){
+				require(["dijit/Tooltip"], dojo.hitch(this, function(Tooltip){
+					html.style(this.mouseNode, 'left', e.pageX + 1 + 'px');
+					html.style(this.mouseNode, 'top', e.pageY + 1 + 'px');
+					Tooltip.show(indicator.hover, this.mouseNode, !this.isLeftToRight());
+				}));
+			} else {
+				this.updateTooltip('', e);
+			}
+		}
+		
+		if (indicator.onDragMove && !indicator.noChange){
+			this.gaugeContent.style.cursor = 'pointer';
+		}
+	},
+	
+	_handleMouseOutIndicator: function (indicator, e){
+		// summary:
+		//		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 event object
+		this._hideTooltip();
+		this.gaugeContent.style.cursor = 'pointer';
+		
+	},
+	
+	_hideTooltip: function(){
+		if (this.useTooltip && this.mouseNode) {
+			require(["dijit/Tooltip"], dojo.hitch(this, function(Tooltip){
+				Tooltip.hide(this.mouseNode);
+			}));
+		}
+	},
+	
+	_handleMouseOutRange: function ( range, e){
+			this._hideTooltip();
+	},
+	
+	_handleMouseOverRange: function (range, e){
+		if (this.useTooltip && !this._drag){
+			if (range.hover) {
+				html.style(this.mouseNode, 'left', e.pageX + 1 + 'px');
+				html.style(this.mouseNode, 'top', e.pageY + 1 + 'px');
+				require(["dijit/Tooltip"], dojo.hitch(this, function(Tooltip){
+					Tooltip.show(range.hover, this.mouseNode, !this.isLeftToRight());
+				}));
+			} else {
+				this.updateTooltip('', e);
+			}
+		}
+	},
+	
+	handleTouchStartIndicator: function(indicator, e){
+		// summary:
+		//		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 event object
+		if (!indicator.noChange){
+			this._drag = indicator;
+			event.stop(e);
+		}
+	},
+		
+	handleTouchStart: function(e){
+		// 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
+		//		The touch event object
+		this._drag = this._getInteractiveIndicator();
+		this.handleTouchMove(e); //drag indicator to touch position
+	},	
+	
+	handleTouchEnd: function(e){
+		// 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
+		//		The touch e object	
+		if (this._drag){
+			this._drag = null;
+			event.stop(e);
+		}
+	},	
+
+	handleTouchMove: function(e){
+		// 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
+		//		The touch event object
+		
+		if (this._drag && !this._drag.noChange){
+			var touches = e.touches;
+			var firstTouch = touches[0];
+			this._dragIndicatorAt(this, firstTouch.pageX, firstTouch.pageY);
+			event.stop(e);
+		}
+	},
+
+	_getInteractiveIndicator: function(){
+		for (var i = 0; i < this._indicatorData.length; i++){
+			var indicator = this._indicatorData[i];
+			if (indicator.interactionMode == "gauge" && !indicator.noChange){
+				return indicator;
+			}
+		}
+		return null;
+	}
+});
+});
+
diff --git a/dojox/gauges/_Indicator.js b/dojox/gauges/_Indicator.js
new file mode 100644
index 0000000..b684ee1
--- /dev/null
+++ b/dojox/gauges/_Indicator.js
@@ -0,0 +1,260 @@
+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
+	//
+	// description:
+	//		An indicator widget, which has given properties.  drawn by a gauge.
+	//
+	// example:
+	//	|	<script type="text/javascript">
+	//	|		require(["dojox/gauges/AnalogGauge","dojox/gauges/Indicator"]);
+	//	|	</script>
+	//	|	...
+	//	|	<div	dojoType="dojox.gauges.AnalogGauge"
+	//	|			id="testGauge"
+	//	|			width="300"
+	//	|			height="200"
+	//	|			cx=150
+	//	|			cy=175
+	//	|			radius=125
+	//	|			image="gaugeOverlay.png"
+	//	|			imageOverlay="false"
+	//	|			imageWidth="280"
+	//	|			imageHeight="155"
+	//	|			imageX="12"
+	//	|			imageY="38">
+	//	|		<div 	dojoType="dojox.gauges.Indicator"
+	//	|				value=17
+	//	|				type="arrow"
+	//	|				length=135
+	//	|				width=3
+	//	|				hover="Value: 17"
+	//	|				onDragMove="handleDragMove">
+	//	|		</div>
+	//	|	</div>
+
+	// value: Number
+	// 		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"
+	type: '',
+
+	// color: String
+	// 		The color of the indicator.
+	color: 'black',
+	
+	// strokeColor: String
+	// 		The color to stroke the outline of the indicator.
+	strokeColor: '',
+
+	// label: String
+	//		The text label for the indicator.
+	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}
+	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
+	length: 0,
+
+	// width: Number
+	// 		The width of the indicator.
+	width: 0,
+
+	// offset: Number
+	// 		The offset of the indicator
+	offset: 0,
+
+	// hover: String
+	// 		The string to put in the tooltip when this indicator is hovered over.
+	hover: '',
+
+	// front: boolean
+	// 		Keep this indicator at the front
+	front: false,
+
+	// onDragMove: String
+	// 		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.
+	easing: fx._defaultEasing,
+
+	// duration: Number
+	// 		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.
+	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).
+	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.
+	interactionMode: "indicator",
+	
+	_gauge: null,
+	
+	// title: String
+	//		 The title of the indicator, to be displayed next to it's input box for the text-representation.
+	title: "",
+
+	startup: function(){
+		if(this.onDragMove){
+			this.onDragMove = lang.hitch(this.onDragMove);
+		}
+		if (this.strokeColor === ""){
+			this.strokeColor = undefined;
+		}
+	},
+
+	postCreate: function(){
+		if(this.title === ""){
+			html.style(this.domNode, "display", "none");
+		}
+		if(lang.isString(this.easing)){
+			this.easing = lang.getObject(this.easing);
+		}
+	},
+		
+	buildRendering: function(){
+		// summary: 
+		//		Overrides _Widget.buildRendering
+		
+		var n = this.domNode = this.srcNodeRef ? this.srcNodeRef: dom.create("div");
+		domClass.add(n, "dojoxGaugeIndicatorDiv");
+		var title = dom.create("label");
+		if (this.title) title.innerHTML = this.title + ":";
+		dom.place(title, n);
+		this.valueNode = dom.create("input", {
+			className: "dojoxGaugeIndicatorInput",
+			size: 5,
+			value: this.value
+		});
+		
+		dom.place(this.valueNode, n);
+		connect.connect(this.valueNode, "onchange", this, this._update);
+	},
+	
+	_update: function(){
+		// summary:
+		//		A private function, handling the updating of the gauge
+
+		this._updateValue(true);
+	},
+	
+	_updateValue: function(animate){
+		// summary:
+		//		A private function, handling the updating of the gauge
+		var value = this.valueNode.value;
+		if(value === ''){
+			this.value = null;
+		}else{
+			this.value = Number(value);
+			this.hover = this.title+': '+value;
+		}
+		if(this._gauge){
+			this.draw(this._gauge._indicatorsGroup, animate || animate==undefined ? false: true);
+			this.valueNode.value = this.value;
+			if((this.title == 'Target' || this.front) && this._gauge.moveIndicator){
+				// if re-drawing value, make sure target is still on top
+				this._gauge.moveIndicatorToFront(this);
+			}
+			this.valueChanged();
+		}
+	},
+	
+	valueChanged: function(){
+		// summary:
+		//		Invoked every time the value of the indicator changes.
+	
+	},
+	 
+	update: function(value, animate){
+		// summary:
+		//		Updates the value of the indicator, including moving/re-drawing at it's new location and
+		//		updating the text box
+		if(!this.noChange){
+			this.valueNode.value = value;
+			this._updateValue(animate);
+		}
+	},
+
+	handleMouseOver: function(e){
+		// summary:
+		//		Handles mouse-over events in the indicator.
+		this._gauge._handleMouseOverIndicator(this, e);
+	},
+	
+	handleMouseOut: function(e){
+		// summary:
+		//		Handles mouse-out events in the indicator.
+		this._gauge._handleMouseOutIndicator(this,e);
+		this._gauge.gaugeContent.style.cursor = '';
+	},
+	
+	handleMouseDown: function(e){
+		// summary:
+		//		Handles mouse-down events in the indicator.
+		this._gauge._handleMouseDownIndicator(this,e);
+	},
+	
+	handleTouchStart: function(e){
+		// summary:
+		//		Handles touch start events in the indicator.
+		this._gauge.handleTouchStartIndicator(this, e);
+	},	
+	
+	onDragMove: function(){
+		// summary:
+		//		Handles updating the text box and the hover text while dragging an indicator
+		this.value = Math.floor(this.value);
+		this.valueNode.value = this.value;
+		this.hover = this.title+': '+this.value;
+	},
+
+	draw: function(/* Boolean? */ dontAnimate){
+		// summary:
+		//		Performs the initial drawing of the indicator.
+		// dontAnimate: Boolean
+		//		Indicates if the drawing should not be animated (rather than teh default, to animate)
+	},
+
+	remove: function(){
+		// summary:
+		//		Removes the indicator's shape from the gauge surface.
+		if (this.shape)
+			this.shape.parent.remove(this.shape);
+		this.shape = null;
+		if(this.text){
+			this.text.parent.remove(this.text);
+		}
+		this.text = null;
+	}
+});
+});
diff --git a/dojox/gauges/tests/images/flare.png b/dojox/gauges/tests/images/flare.png
new file mode 100755
index 0000000..2054044
Binary files /dev/null and b/dojox/gauges/tests/images/flare.png differ
diff --git a/dojox/gauges/tests/images/gaugeOverlay.png b/dojox/gauges/tests/images/gaugeOverlay.png
new file mode 100755
index 0000000..72bcdbb
Binary files /dev/null and b/dojox/gauges/tests/images/gaugeOverlay.png differ
diff --git a/dojox/gauges/tests/test_AnalogGauge-AMD.html b/dojox/gauges/tests/test_AnalogGauge-AMD.html
new file mode 100644
index 0000000..92a9588
--- /dev/null
+++ b/dojox/gauges/tests/test_AnalogGauge-AMD.html
@@ -0,0 +1,284 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Dojo Gauges</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+	</head>
+	<style>	
+		html {
+			height: 100%;
+		}
+		
+		body {
+			margin: 0;
+			background-repeat: no-repeat;
+			background: #003366;
+			/* gecko based browsers */
+			background: -moz-linear-gradient(top,  #003366, #000000);
+								                                
+			/* webkit based browsers */
+			background: -webkit-gradient(linear, left top, left bottom, from(#003366), to(#000000));
+		}
+								                   
+		.footer {
+			position:absolute;
+			bottom:0;
+		}
+								            
+			
+	</style>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: 1,  async:1"></script>
+	<script language="JavaScript" type="text/javascript">
+		require(['dojo/_base/lang', 'dojo/dom', 'dojo/_base/connect', 'dojox/gauges/AnalogGauge', 
+		         'dojox/gauges/AnalogArcIndicator', 'dojox/gauges/AnalogNeedleIndicator', 
+				 'dojox/gauges/AnalogCircleIndicator', 'dojox/gauges/TextIndicator', 
+				 'dojo/domReady', 'dojo/parser'], function(lang, dom, connect, AnalogGauge, 
+				 AnalogArcIndicator, AnalogNeedleIndicator, AnalogCircleIndicator, TextIndicator){
+		
+			var gauge = new AnalogGauge({
+			
+				background: [200, 200, 200, 0],
+				id: "gauge",
+				width: 250,
+				height: 200,
+				cx: 125,
+				cy: 150,
+				radius: 125,
+				useTooltip:false,
+				ranges: [{
+					low: 0,
+					high: 100,
+					color: 'black'
+				}],
+				
+				majorTicks: {
+					offset: 90,
+					interval: 10,
+					length: 3,
+					color: 'white'
+				},
+				
+				indicators: [new AnalogArcIndicator({
+					value: 100,
+					width: 30,
+					offset: 60,
+					color: 'white',
+					noChange: true,
+					title: 'value',
+					hideValue: true
+				}), new AnalogArcIndicator({
+					interactionMode: "gauge",
+					value: 20,
+					width: 20,
+					offset: 65,
+					color: 'gray',
+					noChange: false,
+					title: 'value',
+					hideValue: true
+				}), new TextIndicator({
+					value: 20,
+					align: 'middle',
+					x: 125,
+					y: 135,
+					font: {
+						family: "Arial",
+						style: "normal",
+						variant: 'small-caps',
+						weight: 'bold',
+						size: "30px"
+					},
+					hideValue: false,
+					color: 'gray'
+				})]
+			}, dom.byId("g1"));
+			
+			gauge.startup();
+			
+			connect.connect(gauge.indicators[1], "valueChanged", lang.hitch(gauge, function(){
+				this.indicators[2].update(this.indicators[1].value);
+			}));
+			
+			
+			gauge = new AnalogGauge({
+				id: "gauge2",
+				startAngle: 0,
+				endAngle: 270,
+				background: [0, 0, 0, 0],
+				id: "defaultGauge",
+				width: 250,
+				height: 250,
+				cx: 127,
+				cy: 125,
+				useTooltip:false,
+				radius: 125,
+				ranges: [{
+					low: 0,
+					high: 100,
+					color: [0, 0, 0, 0]
+				}],
+				
+				majorTicks: {
+					offset: 95,
+					interval: 20,
+					length: 3,
+					color: 'white',
+					labelPlacement: 'outside'
+				},
+				
+				indicators: [new AnalogArcIndicator({
+					value: 1000,
+					width: 30,
+					offset: 65,
+					strokeColor: 'black',
+					color: 'white',
+					noChange: true,
+					title: 'value',
+					hideValue: true
+				}), new AnalogArcIndicator({
+					value: 20,
+					width: 20,
+					offset: 70,
+					interactionMode: "gauge",
+					color: [122, 103, 140],
+					noChange: false,
+					title: 'value',
+					hideValue: true
+				}), new TextIndicator({
+					value: 20,
+					align: 'middle',
+					x: 125,
+					y: 140,
+					font: {
+						family: "Arial",
+						style: "normal",
+						variant: 'small-caps',
+						weight: 'bold',
+						size: "40px"
+					},
+					hideValue: false,
+					color: 'gray'
+				})]
+			}, dom.byId("g2"));
+			
+			gauge.startup();
+			
+			connect.connect(gauge.indicators[1], "valueChanged", lang.hitch(gauge, function(){
+				this.indicators[2].update(this.indicators[1].value);
+			}));
+			
+			
+			gauge = new AnalogGauge({
+				id: "gauge3",
+				startAngle: -30,
+				endAngle: 30,
+				background: [0, 0, 0, 0],
+				width: 200,
+				height: 180,
+				cx: 100,
+				cy: 150,
+				radius: 130,
+				ranges: [{
+					low: -30,
+					high: 30,
+					color: [0, 0, 0, 0]
+				}],
+				useTooltip:false,
+				majorTicks: {
+					offset: 100,
+					interval: 10,
+					length: 3,
+					color: 'white',
+					labelPlacement: 'outside'
+				},
+				
+				indicators: [new AnalogNeedleIndicator({
+					interactionMode: "gauge",
+					value: 0,
+					width: 10,
+					length: 100,
+					strokeColor: [100, 100, 100],
+					color: [200, 200, 200]
+				})]
+			}, dom.byId("g3"));
+			
+			gauge.startup();
+			
+			
+			gauge = new AnalogGauge({
+				id: "gauge4",
+				startAngle: 20,
+				endAngle: 20,
+				background: [0, 0, 0, 0],
+				width: 200,
+				height: 200,
+				cx: 100,
+				cy: 100,
+				radius: 95,
+				useTooltip:false,
+				ranges: [{
+					low: 0,
+					high: 8,
+					color: [50, 90, 102]
+				}],
+				
+				majorTicks: {
+					offset: 70,
+					interval: 1,
+					length: 3,
+					color: 'white',
+					labelPlacement: 'outside'
+				},
+				
+				indicators: [new AnalogCircleIndicator({
+					interactionMode: "gauge",
+					offset: 45,
+					value: 5,
+					length: 10,
+					strokeColor: [163, 43, 38],
+					color: [222, 161, 64]
+				
+				}), new AnalogArcIndicator({
+					value: 7,
+					width: 10,
+					offset: 60,
+					
+					color: [255, 248, 178],
+					noChange: true,
+					title: 'value',
+					hideValue: true
+				})]
+			}, dom.byId("g4"));
+			
+			gauge.startup();
+			
+		})
+	</script>
+	<body>
+		<h2 align='center' style='color:gray;'>Analog Gauges</h2>
+		<table style='height:100%; width:100%'>
+			<tr style='height:20'>
+				<td align='center'>
+					<div id="g1">
+					</div>
+				</td>
+				<td align='center'>
+					<div id="g2">
+				</td>
+			</tr>
+			<tr style='height:20'>
+				<td align='center'>
+					<div id="g3">
+					</div>
+				</td>
+				<td align='center'>
+					<div id="g4">
+					</div>
+				</td>
+			</tr>
+		</table>
+		<div class='footer'>
+			<p style='color:gray; font-size:'xx-small'>Click a gauge to change its value.</p>
+		</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/gauges/tests/test_AnalogGaugeWidget.html b/dojox/gauges/tests/test_AnalogGaugeWidget.html
new file mode 100644
index 0000000..50cb505
--- /dev/null
+++ b/dojox/gauges/tests/test_AnalogGaugeWidget.html
@@ -0,0 +1,554 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Analog Gauge Widget</title>
+<style>
+	@import "../_Gauge.css";
+	@import "../../../dojo/resources/dojo.css";
+	@import "../../../dijit/themes/tundra/tundra.css";
+</style>
+<script type="text/javascript">
+	djConfig = {
+		parseOnLoad: true,
+		isDebug: true
+	};
+</script>
+<script type="text/javascript" src="../../../dojo/dojo.js" dojoConfig="parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	dojo.require('dojox.gauges.AnalogGauge');
+	dojo.require('dojox.gauges.AnalogArcIndicator');
+	dojo.require('dojox.gauges.AnalogNeedleIndicator');
+	dojo.require('dojox.gauges.AnalogArrowIndicator');
+	dojo.require('dijit.form.Button');
+	dojo.require('dojo.parser');
+	dojo.ready(init);
+
+	var gauge, valueIndicator, targetIndicator, handle;
+	var ranges1 = [ {low:5, high:10, hover:'5 - 10'},
+				   {low:10, high:20, hover:'10 - 20'},
+				   {low:20, high:30, hover:'20 - 30'},
+				   {low:30, high:40, hover:'30 - 40'},
+				   {low:40, high:50, hover:'40 - 50'},
+				   {low:50, high:60, hover:'50 - 60'},
+				   {low:60, high:70, hover:'60 - 70'},
+				   {low:70, high:75, hover:'70 - 75'}
+				 ];
+	var ranges2 = [ {low:5, high:10, hover:'5 - 10'},
+				   {low:10, high:20, hover:'10 - 20'},
+				   {low:20, high:30, hover:'20 - 30'},
+				   {low:30, high:40, hover:'30 - 40'},
+				   {low:40, high:50, hover:'40 - 50'},
+				   {low:50, high:60, hover:'50 - 60'},
+				   {low:60, high:70, hover:'60 - 70'},
+				   {low:70, high:75, hover:'70 - 75'}
+				 ];
+	
+	function init() {
+		gauge = dojo.byId("defaultGauge");
+		gauge = new dojox.gauges.AnalogGauge({
+			id: "defaultGauge",
+			width: 350,
+			height: 200,
+			cx: 175,
+			cy: 175,
+			radius: 125,
+			ranges: ranges1,
+			minorTicks: {
+				offset: 125,
+				interval: 2.5,
+				length: 5,
+				color: 'gray'
+			},
+			majorTicks: {
+				offset: 125,
+				interval: 5,
+				length: 10
+			},
+			indicators: [
+				new dojox.gauges.AnalogArrowIndicator({
+					value:17, 
+					width: 3,
+					hover:'Value: 17', 
+					title: 'Value'
+				}),
+				new dojox.gauges.AnalogLineIndicator({
+					value:6, 
+					color:'#D00000',
+					width: 3,
+					hover:'Target: 6',
+					title: 'Target'
+				})
+			]
+		}, gauge);
+		gauge.startup();
+		var g = gauge;
+		var int = 10;
+		dojo.connect(dijit.byId('changeTicks'), 'onClick', function(){
+			var o = g.majorTicks;
+			o.interval = ++int;
+			g.setMajorTicks(o);
+		});
+
+		/* Entirely programmatic gauge (ranges, ticks, indicators, etc.) */
+		var fill = {
+			'type': 'linear',
+			'x1': 0,
+			'x2': 0,
+			'y2': 0,
+			'y1': gauge.height,
+			'colors': [{offset: 0, color: "#ECECEC"}, {offset: 1, color: "white"}]
+		};
+		gauge = dojo.byId("programmaticGauge");
+		gauge = new dojox.gauges.AnalogGauge({
+			id: "programmaticGauge",
+			width: 350,
+			height: 200,
+			cx: 175,
+			cy: 175,
+			radius: 125,
+			background: fill,
+			image: {
+				url: "images/gaugeOverlay.png",
+				width: 280,
+				height: 155,
+				x: 35,
+				y: 38,
+				overlay: true
+			},
+			useRangeStyles: 8
+		}, gauge);
+		gauge.startup();
+		gauge.addRanges(ranges2);
+		gauge.setMajorTicks({
+			length: 5,
+			interval: 5,
+			offset: 125,
+			font: {family: "Arial", style: "italic", variant: 'small-caps', weight: 'bold', size: "18px"}
+		});
+		valueIndicator = new dojox.gauges.AnalogArrowIndicator({
+			value:17, 
+			width: 3,
+			hover:'Value: 17', 
+			title: 'Value',
+			easing: dojo.fx.easing.bounceOut
+		});
+		gauge.addIndicator(valueIndicator);
+		targetIndicator = new dojox.gauges.AnalogLineIndicator({
+			value:6, 
+			color:'#D00000', 
+			width: 3,
+			hover:'Target: 6', 
+			title: 'Target',
+			// Can use string to indicate easing function (just like in de
+			easing: 'dojo.fx.easing.linear'
+		});
+		gauge.addIndicator(targetIndicator);
+		handle = setInterval((function(t, v){
+			return (function(){
+				t.update(Math.floor(Math.random() * 70) + 5);
+				v.update(Math.floor(Math.random() * 70) + 5);
+			});
+		})(valueIndicator, targetIndicator), 3000);
+		dojo.connect(dijit.byId('stop'), 'onClick', function(){
+			clearInterval(handle);
+		});
+
+		gauge = dojo.byId("speedometer");
+		gauge = new dojox.gauges.AnalogGauge({
+			id: "speedometer",
+			width:270,
+			height: 230,
+			cx: 135,
+			cy: 135,
+			radius: 125,
+			image: {
+				url: "images/flare.png",
+				width: 112,
+				height: 116,
+				x: 140,
+				y: 40,
+				overlay: true
+			},
+			startAngle: -135,
+			endAngle: 135,
+			useRangeStyles: 8,
+			ranges: [{low:0, high:180, color: 'black'}],
+			majorTicks: {
+				offset: 85,
+				length: 10,
+				interval: 20,
+				color: 'gray'
+			},
+			minorTicks: {
+				offset: 85,
+				length: 5,
+				interval: 5,
+				color: 'gray'
+			},
+			indicators: [new dojox.gauges.AnalogNeedleIndicator({
+							value:0, 
+							width: 3,
+							length: 100,
+							hover:'Value: 0', 
+							title: 'Value',
+							color: 'red'
+			})]
+		}, gauge);
+		gauge.startup();
+
+		gauge = dojo.byId("tachometer");
+		gauge = new dojox.gauges.AnalogGauge({
+			id: "tachometer",
+			width:270,
+			height: 230,
+			cx: 135,
+			cy: 135,
+			radius: 125,
+			image: {
+				url: "images/flare.png",
+				width: 112,
+				height: 116,
+				x: 140,
+				y: 40,
+				overlay: true
+			},
+			startAngle: -135,
+			endAngle: 135,
+			useRangeStyles: 8,
+			ranges: [{low:0, high:9000, color: 'black'}],
+			majorTicks: {
+				offset: 75,
+				length: 10,
+				color: 'gray',
+				interval: 1000
+			},
+			minorTicks: {
+				offset: 75,
+				length: 5,
+				color: 'gray',
+				interval: 500
+			},
+			indicators: [new dojox.gauges.AnalogNeedleIndicator({
+							value:0, 
+							width: 3,
+							length: 100,
+							hover:'Value: 0', 
+							title: 'Value',
+							color: 'red'
+			})]
+		}, gauge);
+		gauge.startup();
+
+		// Used for a gradient arc indicator below:
+		var fill = {
+			'type': 'linear',
+			'x1': 50,
+			'y1': 50,
+			'x2': 550,
+			'y2': 550,
+			'colors': [{offset: 0, color: 'black'}, {offset: 0.5, color: 'black'}, {offset: 0.75, color: 'yellow'}, {offset: 1, color: 'red'}]
+		};
+		gauge = dojo.byId("arctest");
+		gauge = new dojox.gauges.AnalogGauge({
+			id: "arctest",
+			width: 650,
+			height: 550,
+			radius: 300,
+			cx: 320,
+			cy: 310,
+			startAngle: -135,
+			endAngle: 135,
+			ranges: [
+				{low: 0, high: 100, color: 'black'},
+				{low: 100, high: 200, color: 'black'}
+			],
+			minorTicks: {
+				offset: 235,
+				interval: 5,
+				length: 5,
+				color: 'gray'
+			},
+			majorTicks: {
+				offset: 235,
+				interval: 10,
+				length: 10,
+				color: 'gray'
+			},
+			indicators: [new dojox.gauges.AnalogArcIndicator({
+							value: 200, 
+							width: 20,
+							offset: 280,
+							color: fill,
+							noChange: true,
+							hideValue: true
+						}),
+						new dojox.gauges.AnalogArcIndicator({
+							value: 80, 
+							width: 10,
+							offset: 280,
+							hover:'Arc: 80', 
+							title: 'Arc',
+							color: 'blue'
+						}),
+						new dojox.gauges.AnalogLineIndicator({
+							value:6, 
+							color:'#D00000', 
+							width: 8,
+							hover:'Target: 6', 
+							title: 'Target',
+							// Can use string to indicate easing function (just like in declarative version) 
+							easing: 'dojo.fx.easing.linear'
+						}),
+						new dojox.gauges.AnalogArrowIndicator({
+							value: 20, 
+							width: 8,
+							length: 300,
+							hover:'Arrow: 20', 
+							title: 'Arrow',
+							color: 'red',
+							easing: dojo.fx.easing.bounceOut
+						}),
+						new dojox.gauges.AnalogNeedleIndicator({
+							value: 100, 
+							width: 8,
+							length: 300,
+							hover: 'Needle: 100', 
+							title: 'Needle',
+							color: 'red'
+						})
+			]
+		}, gauge);
+		gauge.startup();
+
+		var fill = {
+			'type': 'linear',
+			'x1': 0,
+			'x2': 0,
+			'y2': 0,
+			'y1': gauge.height,
+			'colors': [{offset: 0, color: "#ECECEC"}, {offset: 1, color: "white"}]
+		};
+		gauge.setBackground(fill);
+	}
+	dojo.addOnUnload(function(){
+		clearInterval(handle);
+	});
+	
+</script>
+</head>
+<body class="tundra">
+<h1>Analog Gauge Widget</h1>
+<h2>Default Colored Gauge</h2>
+<div id="defaultGauge"></div>
+<button dojoType="dijit.form.Button" id="changeTicks">Change Ticks</button>
+<h2>CSS Themed Ranges, Image Overlay, Gradient Background, Updating to Random Values on 3s Timer</h2>
+<div id="programmaticGauge"></div>
+<button dojoType="dijit.form.Button" id="stop">Stop Timer</button>
+<div style="float: left;">
+	<h2>Speedometer</h2>
+	<div id="speedometer"></div>
+</div>
+<div style="float: left;">
+	<h2>Tachometer</h2>
+	<div id="tachometer"></div>
+</div>
+<div style="clear: both;">
+	<h2>Various Indicators Test</h2>
+	<div id="arctest"></div>
+</div>
+<h2>Declarative, Gradient Ranges, Gradient Background, No Indicator Boxes</h2>
+<div	dojoType="dojox.gauges.AnalogGauge"
+		id="declarativeGauge"
+		width="270"
+		height="265"
+		cx="110"
+		cy="150"
+		radius="125"
+		startAngle="-45"
+		endAngle="135"
+		useRangeStyles="0"
+		hideValues="true"
+		majorTicks="{length: 5, offset: 125, interval: 5}"
+		background="{
+			'type': 'linear',
+			'x1': 0,
+			'y1': 265,
+			'x2': 0,
+			'y2': 0,
+			'colors': [{offset: 0, color: '#ECECEC'}, {offset: 1, color: 'white'}]
+		}">
+	<div	dojoType="dojox.gauges.Range"
+			low="5"
+			high="10"
+			hover="5 - 10"
+			color="{
+				'type': 'linear',
+				'colors': [{offset: 0, color:'#606060'}, {offset: 1, color: '#707070'}]
+			}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			id="range1"
+			low="10"
+			high="20"
+			hover="10 - 20"
+			color="{
+				'type': 'linear',
+				'colors': [{offset: 0, color:'#707070'}, {offset: 1, color: '#808080'}]
+			}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			id="range2"
+			low="20"
+			high="30"
+			hover="20 - 30"
+			color="{
+				'type': 'linear',
+				'colors': [{offset: 0, color:'#808080'}, {offset: 1, color: '#909090'}]
+			}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			id="range3"
+			low="30"
+			high="40"
+			hover="30 - 40"
+			color="{
+				'type': 'linear',
+				'colors': [{offset: 0, color:'#909090'}, {offset: 1, color: '#A0A0A0'}]
+			}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			id="range4"
+			low="40"
+			high="50"
+			hover="40 - 50"
+			color="{
+				'type': 'linear',
+				'colors': [{offset: 0, color:'#A0A0A0'}, {offset: 1, color: '#B0B0B0'}]
+			}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			id="range5"
+			low="50"
+			high="60"
+			hover="50 - 60"
+			color="{
+				'type': 'linear',
+				'colors': [{offset: 0, color:'#B0B0B0'}, {offset: 1, color: '#C0C0C0'}]
+			}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			id="range6"
+			low="60"
+			high="70"
+			hover="60 - 70"
+			color="{
+				'type': 'linear',
+				'colors': [{offset: 0, color:'#C0C0C0'}, {offset: 1, color: '#D0D0D0'}]
+			}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			id="range7"
+			low="70"
+			high="75"
+			hover="70 - 75"
+			color="{
+				'type': 'linear',
+				'colors': [{offset: 0, color:'#D0D0D0'}, {offset: 1, color: '#E0E0E0'}]
+			}">
+	</div>
+	<div	dojoType="dojox.gauges.AnalogLineIndicator"
+			id="target"
+			value="6"
+			color="#D00000"
+			width="3"
+			hover="Target: 6"
+			title="Target">
+	</div>
+	<div 	dojoType="dojox.gauges.AnalogArrowIndicator"
+			id="value"
+			value="17"
+			type="arrow"
+			length="135"
+			width="3"
+			hover="Value: 17"
+			title="Value">
+	</div>
+</div>
+<h2>Declarative, (Ugly) Colored Ranges, No Numbers, No Indicator Boxes</h2>
+<div	dojoType="dojox.gauges.AnalogGauge"
+		id="declarativeGauge2"
+		width="270"
+		height="270"
+		cx="135"
+		cy="135"
+		radius="125"
+		startAngle="-90"
+		endAngle="270"
+		useRangeStyles="0"
+		hideValues="true"
+		background="{color: 'green'}">
+	<div	dojoType="dojox.gauges.Range"
+			low="5"
+			high="10"
+			hover="5 - 10"
+			color="{color: 'red'}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			low="10"
+			high="20"
+			hover="10 - 20"
+			color="{color: '#FFA500'}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			low="20"
+			high="30"
+			hover="20 - 30"
+			color="{color: 'yellow'}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			low="30"
+			high="40"
+			hover="30 - 40"
+			color="{color: '#7FFF00'}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			low="40"
+			high="50"
+			hover="40 - 50"
+			color="{color: '#00FFFF'}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			low="50"
+			high="60"
+			hover="50 - 60"
+			color="{color: 'blue'}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			low="60"
+			high="70"
+			hover="60 - 70"
+			color="{color: '#191970'}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			low="70"
+			high="75"
+			hover="70 - 75"
+			color="{color: 'purple'}">
+	</div>
+	<div	dojoType="dojox.gauges.AnalogLineIndicator"
+			value="6"
+			color="#D00000"
+			width="3"
+			hover="Target: 6"
+			title="Target">
+	</div>
+	<div 	dojoType="dojox.gauges.AnalogArrowIndicator"
+			value="55"
+			length="135"
+			width="3"
+			hover="Value: 55"
+			title="Value">
+	</div>
+</div>
+</body>
+</html>
diff --git a/dojox/gauges/tests/test_AnalogGaugeWidgetIndicators.html b/dojox/gauges/tests/test_AnalogGaugeWidgetIndicators.html
new file mode 100644
index 0000000..d8f8d2e
--- /dev/null
+++ b/dojox/gauges/tests/test_AnalogGaugeWidgetIndicators.html
@@ -0,0 +1,279 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Analog Gauge Widget Indicators</title>
+		<style>
+			@import "../_Gauge.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/tundra/tundra.css";
+		</style>
+		<script type="text/javascript">
+			djConfig = {
+				parseOnLoad: true,
+				isDebug: true
+			};
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+		<script language="JavaScript" type="text/javascript">
+			dojo.require('dojox.gauges.AnalogGauge');
+			dojo.require('dojox.gauges.AnalogArcIndicator');
+			dojo.require('dojox.gauges.AnalogNeedleIndicator');
+			dojo.require('dojox.gauges.AnalogCircleIndicator');
+			dojo.require('dojox.gauges.TextIndicator');
+			dojo.require('dijit.form.Button');
+			dojo.require('dojo.parser');
+			
+			dojo.addOnLoad(init);
+			
+			
+			function init(){
+				var gauge = new dojox.gauges.AnalogGauge({
+				
+					background: [200, 200, 200],
+					id: "gauge",
+					width: 250,
+					height: 200,
+					cx: 125,
+					cy: 150,
+					radius: 125,
+					ranges: [{
+						low: 0,
+						high: 100,
+						color: 'black'
+					}],
+					
+					majorTicks: {
+						offset: 90,
+						interval: 10,
+						length: 3,
+						color: 'white'
+					},
+					
+					indicators: [new dojox.gauges.AnalogArcIndicator({
+						value: 100,
+						width: 30,
+						offset: 60,
+						color: 'white',
+						noChange: true,
+						title: 'value',
+						hideValue: true
+					}), new dojox.gauges.AnalogArcIndicator({
+						interactionMode: "gauge",
+						value: 20,
+						width: 20,
+						offset: 65,
+						color: 'gray',
+						noChange: false,
+						title: 'value',
+						hideValue: true
+					}), new dojox.gauges.TextIndicator({
+						value: 20,
+						align: 'middle',
+						x: 125,
+						y: 135,
+						font: {
+							family: "Arial",
+							style: "normal",
+							variant: 'small-caps',
+							weight: 'bold',
+							size: "30px"
+						},
+						hideValue: false,
+						color: 'gray'
+					})]
+				}, dojo.byId("gauge"));
+				
+				gauge.startup();
+				
+				dojo.connect(gauge.indicators[1], "valueChanged", dojo.hitch(gauge, function(){
+					this.indicators[2].update(this.indicators[1].value);
+				}));
+				
+				
+				gauge = new dojox.gauges.AnalogGauge({
+					id: "gauge2",
+					startAngle: 0,
+					endAngle: 270,
+					background: 'white',
+					id: "defaultGauge",
+					width: 250,
+					height: 250,
+					cx: 127,
+					cy: 125,
+					radius: 125,
+					ranges: [{
+						low: 0,
+						high: 100,
+						color: 'white'
+					}],
+					
+					majorTicks: {
+						offset: 95,
+						interval: 20,
+						length: 3,
+						color: 'black',
+						labelPlacement: 'outside'
+					},
+					
+					indicators: [new dojox.gauges.AnalogArcIndicator({
+						value: 1000,
+						width: 30,
+						offset: 65,
+						strokeColor: 'black',
+						color: 'white',
+						noChange: true,
+						title: 'value',
+						hideValue: true
+					}), new dojox.gauges.AnalogArcIndicator({
+						value: 20,
+						width: 20,
+						offset: 70,
+						interactionMode: "gauge",
+						color: [122, 103, 140],
+						noChange: false,
+						title: 'value',
+						hideValue: true
+					}), new dojox.gauges.TextIndicator({
+						value: 20,
+						align: 'middle',
+						x: 125,
+						y: 140,
+						font: {
+							family: "Arial",
+							style: "normal",
+							variant: 'small-caps',
+							weight: 'bold',
+							size: "40px"
+						},
+						hideValue: false,
+						color: 'gray'
+					})]
+				}, dojo.byId("gauge2"));
+				
+				gauge.startup();
+				
+				dojo.connect(gauge.indicators[1], "valueChanged", dojo.hitch(gauge, function(){
+					this.indicators[2].update(this.indicators[1].value);
+				}));
+				
+				
+				gauge = new dojox.gauges.AnalogGauge({
+					id: "gauge3",
+					startAngle: -30,
+					endAngle: 30,
+					background: 'white',
+					width: 200,
+					height: 180,
+					cx: 100,
+					cy: 150,
+					radius: 130,
+					ranges: [{
+						low: -30,
+						high: 30,
+						color: 'white'
+					}],
+					
+					majorTicks: {
+						offset: 100,
+						interval: 10,
+						length: 3,
+						color: 'black',
+						labelPlacement: 'outside'
+					},
+					
+					indicators: [new dojox.gauges.AnalogNeedleIndicator({
+						interactionMode: "gauge",
+						value: 0,
+						width: 10,
+						length: 100,
+						strokeColor: [100, 100, 100],
+						color: [200, 200, 200]
+					})]
+				}, dojo.byId("gauge3"));
+				
+				gauge.startup();
+				
+				
+				gauge = new dojox.gauges.AnalogGauge({
+					id: "gauge4",
+					startAngle: 20,
+					endAngle: 20,
+					background: 'white',
+					width: 200,
+					height: 200,
+					cx: 100,
+					cy: 100,
+					radius: 95,
+					ranges: [{
+						low: 0,
+						high: 8,
+						color: [50, 90, 102]
+					}],
+					
+					majorTicks: {
+						offset: 70,
+						interval: 1,
+						length: 3,
+						color: 'white',
+						labelPlacement: 'outside'
+					},
+					
+					indicators: [new dojox.gauges.AnalogCircleIndicator({
+						interactionMode: "gauge",
+						offset: 45,
+						value: 5,
+						length: 10,
+						strokeColor: [163, 43, 38],
+						color: [222, 161, 64]
+					
+					}), new dojox.gauges.AnalogArcIndicator({
+						value: 7,
+						width: 10,
+						offset: 60,
+						
+						color: [255, 248, 178],
+						noChange: true,
+						title: 'value',
+						hideValue: true
+					})]
+				}, dojo.byId("gauge4"));
+				
+				gauge.startup();
+				
+			}
+		</script>
+	</head>
+	<body class="tundra">
+	<h1>Analog Gauge Widget Indicators</h1>
+	<ul class="lst">
+		<li>
+			Arc and Text indicators
+		</li>
+	</ul>
+	<div id="gauge">
+	</div>
+	<ul class="lst">
+		<li>
+			Arc and Text indicators again.
+		</li>
+	</ul>
+	<div id="gauge2">
+	</div>
+	<ul class="lst">
+		<li>
+			Needle indicator.
+		</li>
+	</ul>
+	<div id="gauge3">
+	</div>
+	<ul class="lst">
+		<li>
+			Circle indicator.
+		</li>
+	</ul>
+	<div id="gauge4">
+	</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/gauges/tests/test_AnalogGaugeWidgetLabelPlacement.html b/dojox/gauges/tests/test_AnalogGaugeWidgetLabelPlacement.html
new file mode 100644
index 0000000..7d73bed
--- /dev/null
+++ b/dojox/gauges/tests/test_AnalogGaugeWidgetLabelPlacement.html
@@ -0,0 +1,91 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Analog Gauge Widget Orientation</title>
+		<style>
+			@import "../_Gauge.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/tundra/tundra.css";
+		</style>
+		<script type="text/javascript">
+			djConfig = {
+				parseOnLoad: true,
+				isDebug: true
+			};
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+		<script language="JavaScript" type="text/javascript">
+			dojo.require('dojox.gauges.AnalogGauge');
+			dojo.require('dojox.gauges.AnalogNeedleIndicator');
+			dojo.require('dijit.form.Button');
+			dojo.require('dojo.parser');
+			
+			dojo.addOnLoad(init);
+			
+			
+			function init(){
+			
+			
+				var gauge = new dojox.gauges.AnalogGauge({
+					id: "gauge",
+					
+					startAngle: 30,
+					endAngle: 30,
+					background: 'white',
+					width: 200,
+					height: 200,
+					cx: 100,
+					cy: 100,
+					radius: 100,
+					ranges: [{
+						low: 1,
+						high: 13,
+						color: [200, 200, 200]
+					}],
+					
+					majorTicks: {
+						offset: 80,
+						interval: 1,
+						length: 5,
+						color: 'white',
+						labelPlacement: 'inside'
+					},
+					
+					indicators: [new dojox.gauges.AnalogNeedleIndicator({
+						interactionMode: "gauge",
+						value: 12,
+						width: 5,
+						length: 50,
+						strokeColor: [100, 100, 100],
+						color: 'white'
+					
+					})]
+				}, dojo.byId("gauge"));
+				
+				gauge.startup();
+				
+				dojo.connect(dijit.byId('btn'), 'onClick', function(){
+					var o = gauge.majorTicks;
+					if (o.labelPlacement == 'outside') {
+						o.labelPlacement = 'inside';
+						o.offset = 80;
+					} else {
+						o.labelPlacement = 'outside';
+						o.offset = 60;
+					}
+					gauge.setMajorTicks(o);
+				});
+				
+			}
+		</script>
+	</head>
+	<body class="tundra">
+		<h1>Analog Gauge Widget Scale Label Placement</h1>
+		<div id="gauge">
+		</div>
+		<button id="btn" dojoType='dijit.form.Button'>
+			Change label placement
+		</button>
+	</body>
+</html>
diff --git a/dojox/gauges/tests/test_AnalogGaugeWidgetOrientation.html b/dojox/gauges/tests/test_AnalogGaugeWidgetOrientation.html
new file mode 100644
index 0000000..72d9a49
--- /dev/null
+++ b/dojox/gauges/tests/test_AnalogGaugeWidgetOrientation.html
@@ -0,0 +1,129 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Analog Gauge Widget Orientation</title>
+		<style>
+			@import "../_Gauge.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/tundra/tundra.css";
+		</style>
+		<script type="text/javascript">
+			djConfig = {
+				parseOnLoad: true,
+				isDebug: true
+			};
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+		<script language="JavaScript" type="text/javascript">
+			dojo.require('dojox.gauges.AnalogGauge');
+			dojo.require('dojox.gauges.AnalogArcIndicator');
+			dojo.require('dojox.gauges.AnalogNeedleIndicator');
+			dojo.require('dojox.gauges.AnalogCircleIndicator');
+			dojo.require('dojox.gauges.TextIndicator');
+			dojo.require('dijit.form.Button');
+			dojo.require('dojo.parser');
+			
+			dojo.addOnLoad(init);
+			
+			
+			function init(){
+			
+			
+				var gauge1 = new dojox.gauges.AnalogGauge({
+					id: "gauge",
+					startAngle: -60,
+					endAngle: 60,
+					background: 'white',
+					width: 300,
+					height: 180,
+					cx: 150,
+					cy: 150,
+					radius: 130,
+					ranges: [{
+						low: 0,
+						high: 60,
+						color: 'white'
+					}],
+					
+					majorTicks: {
+						offset: 100,
+						interval: 10,
+						length: 3,
+						color: 'black',
+						labelPlacement: 'outside'
+					},
+					
+					indicators: [new dojox.gauges.AnalogNeedleIndicator({
+						interactionMode: "gauge",
+						value: 0,
+						width: 10,
+						length: 100,
+						strokeColor: [100, 100, 100],
+						color: [200, 200, 200]
+					
+					})]
+				}, dojo.byId("gauge"));
+				
+				gauge1.startup();
+				
+				
+				var gauge2 = new dojox.gauges.AnalogGauge({
+					id: "gauge2",
+					orientation: "cclockwise",
+					startAngle: 60,
+					endAngle: -60,
+					background: 'white',
+					width: 300,
+					height: 180,
+					cx: 150,
+					cy: 150,
+					radius: 130,
+					ranges: [{
+						low: 0,
+						high: 60,
+						color: 'white'
+					}],
+					
+					majorTicks: {
+						offset: 100,
+						interval: 10,
+						length: 3,
+						color: 'black'
+					},
+					
+					indicators: [new dojox.gauges.AnalogNeedleIndicator({
+						interactionMode: "gauge",
+						value: 0,
+						width: 10,
+						length: 100,
+						strokeColor: [100, 100, 100],
+						color: [200, 200, 200]
+					
+					})]
+				}, dojo.byId("gauge2"));
+				
+				gauge2.startup();
+				
+				
+			}
+		</script>
+	</head>
+	<body class="tundra">
+		<h1>Analog Gauge Widget Orientation</h1>
+		<ul class="lst">
+			<li>
+				Clockwise
+			</li>
+		</ul>
+		<div id="gauge">
+		</div>
+		<ul class="lst">
+			<li>
+				Counter Clockwise
+			</li>
+		</ul>
+		<div id="gauge2">
+		</div>
+	</body>
+</html>
diff --git a/dojox/gauges/tests/test_BarGaugeWidget.html b/dojox/gauges/tests/test_BarGaugeWidget.html
new file mode 100644
index 0000000..f1f7a20
--- /dev/null
+++ b/dojox/gauges/tests/test_BarGaugeWidget.html
@@ -0,0 +1,340 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Bar Gauge Widget</title>
+<style>
+	@import "../_Gauge.css";
+	@import "../../../dojo/resources/dojo.css";
+	@import "../../../dijit/themes/tundra/tundra.css";
+</style>
+<script type="text/javascript">
+	djConfig = {
+		parseOnLoad: true,
+		isDebug: true
+	};
+</script>
+<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+<script language="JavaScript" type="text/javascript">
+	dojo.require('dojox.gauges.BarGauge');
+	dojo.require('dojox.gauges.BarIndicator');
+	dojo.require('dijit.form.Button');
+	dojo.require('dojo.parser');
+
+
+	dojo.addOnLoad(init);
+
+	var gauge, valueIndicator, targetIndicator, handle;
+	var ranges1 = [ {low:5, high:10, hover:'5 - 10'},
+				   {low:10, high:20, hover:'10 - 20'},
+				   {low:20, high:30, hover:'20 - 30'},
+				   {low:30, high:40, hover:'30 - 40'},
+				   {low:40, high:50, hover:'40 - 50'},
+				   {low:50, high:60, hover:'50 - 60'},
+				   {low:60, high:70, hover:'60 - 70'},
+				   {low:70, high:75, hover:'70 - 75'}
+				 ];
+	var ranges2 = [ {low:5, high:10, hover:'5 - 10'},
+				   {low:10, high:20, hover:'10 - 20'},
+				   {low:20, high:30, hover:'20 - 30'},
+				   {low:30, high:40, hover:'30 - 40'},
+				   {low:40, high:50, hover:'40 - 50'},
+				   {low:50, high:60, hover:'50 - 60'},
+				   {low:60, high:70, hover:'60 - 70'},
+				   {low:70, high:75, hover:'70 - 75'}
+				 ];
+	
+	function init() {
+		gauge = dojo.byId("defaultGauge");
+		gauge = new dojox.gauges.BarGauge({
+			id: "defaultGauge",
+			width: 300,
+			height: 55,
+			dataHeight: 25,
+			dataWidth: 275,
+			dataY: 25,
+			dataX: 10,
+			ranges: ranges1,
+			majorTicks: {
+				length: 5,
+				width: 1,
+				offset: -5,
+				interval: 5
+			},
+			indicators: [
+				new dojox.gauges.BarIndicator({
+					value:17,
+					width: 7,
+					hover:'Value: 17',
+					title: 'Value'
+				}),
+				new dojox.gauges.BarLineIndicator({
+					value:6,
+					color:'#D00000',
+					hover:'Target: 6',
+					title: 'Target'
+				})
+			]
+		}, gauge);
+		gauge.startup();
+
+		var fill = {
+			type: "linear",
+			x1: 0,
+			y1: gauge.height,
+			x2: 0,
+			y2: 0,
+			colors: [{offset: 0, color: "#ECECEC"}, {offset: 1, color: "white"}]
+		};
+		gauge = dojo.byId("programmaticGauge");
+		gauge = new dojox.gauges.BarGauge({
+			id: "programmaticGauge",
+			width: 300,
+			height: 55,
+			dataHeight: 25,
+			dataWidth: 275,
+			dataX: 10,
+			dataY: 25,
+			useRangeStyles: 8,
+			background: fill
+		}, gauge);
+		gauge.startup();
+		
+		gauge.addRanges(ranges2);
+		gauge.setMinorTicks({interval: 1,
+							 length:2,
+							 offset:-2,
+							 width: 1});
+		gauge.setMajorTicks({interval: 5,
+							 length:5,
+							 offset:-5,
+							 width: 1,
+							 font: {family: "Arial", style: "italic", variant: 'small-caps', weight: 'bold', size: "12px"}});
+		valueIndicator = new dojox.gauges.BarIndicator({
+			value:17,
+			width: 7,
+			hover:'Value: 17', 
+			title: 'Value',
+			easing: dojo.fx.easing.bounceOut
+		});
+		targetIndicator = new dojox.gauges.BarLineIndicator({
+			value:6,
+			color:'#D00000',
+			hover:'Target: 6',
+			title: 'Target',
+			// Can use string to indicate easing function (just like in declarative)
+			easing: 'dojo.fx.easing.linear'
+		});
+		gauge.addIndicator(targetIndicator);
+		gauge.addIndicator(valueIndicator);
+		//targetIndicator.update(Math.floor(Math.random() * 70) + 5);
+		handle = setInterval((function(t, v){
+			return (function(){
+				t.update(Math.floor(Math.random() * 70) + 5);
+				v.update(Math.floor(Math.random() * 70) + 5);
+			});
+		})(valueIndicator, targetIndicator), 3000);
+		dojo.connect(dijit.byId('stop'), 'onClick', function(){
+			clearInterval(handle);
+		});
+	}
+	dojo.addOnUnload(function(){
+		clearInterval(handle);
+	});
+</script>
+</head>
+<body class="tundra">
+<h1>Bar Gauge Widget</h1>
+<h2>Default Colored Gauge</h2>
+<div id="defaultGauge"></div>
+<h2>CSS Themed Ranges, Gradient Background, Updating to Random Values on 3s Timer</h2>
+<div id="programmaticGauge"></div>
+<button dojoType="dijit.form.Button" id="stop">Stop Timer</button>
+<h2>Declarative, Gradient Ranges, Gradient Background, No Indicator Boxes</h2>
+<div	dojoType="dojox.gauges.BarGauge"
+		id="declarativeGauge"
+		width="300"
+		height="55"
+		dataHeight="25"
+		dataWidth="275"
+		dataX="10"
+		dataY="25"
+		useRangeStyles="0"
+		hideValues="true"
+		majorTicks="{length: 5, width: 1, offset: -5, interval: 5}"
+		background="{
+			type: 'linear',
+			x1: 0,
+			x2: 0,
+			y1: 55,
+			y2: 0,
+			colors: [{offset: 0, color: '#ECECEC'}, {offset: 1, color: 'white'}]
+		}">
+	<div	dojoType="dojox.gauges.Range"
+			low="5"
+			high="10"
+			hover="5 - 10"
+			color="{
+				'type': 'linear',
+				'colors': [{offset: 0, color:'#606060'}, {offset: 1, color: '#707070'}]
+			}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			id="range1"
+			low="10"
+			high="20"
+			hover="10 - 20"
+			color="{
+				'type': 'linear',
+				'colors': [{offset: 0, color:'#707070'}, {offset: 1, color: '#808080'}]
+			}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			id="range2"
+			low="20"
+			high="30"
+			hover="20 - 30"
+			color="{
+				'type': 'linear',
+				'colors': [{offset: 0, color:'#808080'}, {offset: 1, color: '#909090'}]
+			}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			id="range3"
+			low="30"
+			high="40"
+			hover="30 - 40"
+			color="{
+				'type': 'linear',
+				'colors': [{offset: 0, color:'#909090'}, {offset: 1, color: '#A0A0A0'}]
+			}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			id="range4"
+			low="40"
+			high="50"
+			hover="40 - 50"
+			color="{
+				'type': 'linear',
+				'colors': [{offset: 0, color:'#A0A0A0'}, {offset: 1, color: '#B0B0B0'}]
+			}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			id="range5"
+			low="50"
+			high="60"
+			hover="50 - 60"
+			color="{
+				'type': 'linear',
+				'colors': [{offset: 0, color:'#B0B0B0'}, {offset: 1, color: '#C0C0C0'}]
+			}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			id="range6"
+			low="60"
+			high="70"
+			hover="60 - 70"
+			color="{
+				'type': 'linear',
+				'colors': [{offset: 0, color:'#C0C0C0'}, {offset: 1, color: '#C0C0C0'}]
+			}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			id="range7"
+			low="70"
+			high="75"
+			hover="70 - 75"
+			color="{
+				'type': 'linear',
+				'colors': [{offset: 0, color:'#C0C0C0'}, {offset: 1, color: '#E0E0E0'}]
+			}">
+	</div>
+	<div	dojoType="dojox.gauges.BarLineIndicator"
+			id="target"
+			value="6"
+			color="#D00000"
+			width="3"
+			hover="Target: 6"
+			title="Target">
+	</div>
+	<div 	dojoType="dojox.gauges.BarIndicator"
+			id="value"
+			value="17"
+			length="135"
+			width="3"
+			hover="Value: 17"
+			title="Value">
+	</div>
+</div>
+<h2>Declarative, (Ugly) Colored Ranges, No Numbers, No Indicator Boxes</h2>
+<div	dojoType="dojox.gauges.BarGauge"
+		id="declarativeGauge2"
+		width="300"
+		height="35"
+		dataHeight="25"
+		dataWidth="290"
+		useRangeStyles="0"
+		hideValues="true"
+		background="{color: 'green'}">
+	<div	dojoType="dojox.gauges.Range"
+			low="5"
+			high="10"
+			hover="5 - 10"
+			color="{color: 'red'}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			low="10"
+			high="20"
+			hover="10 - 20"
+			color="{color: '#FFA500'}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			low="20"
+			high="30"
+			hover="20 - 30"
+			color="{color: 'yellow'}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			low="30"
+			high="40"
+			hover="30 - 40"
+			color="{color: '#7FFF00'}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			low="40"
+			high="50"
+			hover="40 - 50"
+			color="{color: '#00FFFF'}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			low="50"
+			high="60"
+			hover="50 - 60"
+			color="{color: 'blue'}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			low="60"
+			high="70"
+			hover="60 - 70"
+			color="{color: '#191970'}">
+	</div>
+	<div	dojoType="dojox.gauges.Range"
+			low="70"
+			high="75"
+			hover="70 - 75"
+			color="{color: 'purple'}">
+	</div>
+	<div	dojoType="dojox.gauges.BarLineIndicator"
+			value="6"
+			color="#D00000"
+			hover="Target: 6"
+			title="Target">
+	</div>
+	<div 	dojoType="dojox.gauges.BarIndicator"
+			value="55"
+			width="7"
+			hover="Value: 55"
+			title="Value">
+	</div>
+</div>
+</body>
+</html>
diff --git a/dojox/gauges/tests/test_GlossyCircularGauge.html b/dojox/gauges/tests/test_GlossyCircularGauge.html
new file mode 100644
index 0000000..78f0eb8
--- /dev/null
+++ b/dojox/gauges/tests/test_GlossyCircularGauge.html
@@ -0,0 +1,300 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Circular Gauge Sample</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+		<link rel="stylesheet" type="text/css" href="../../../dijit/themes/claro/claro.css">
+	</head>
+	<script type="text/javascript">
+		var djConfig = {
+			parseOnLoad: true,
+			isDebug: true
+		}
+	</script>
+	<script type="text/javascript" src="../../../dojo/dojo.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.ColorPalette");
+		
+		dojo.require('dijit.form.Button');
+		dojo.require('dijit.form.CheckBox');
+		dojo.require("dijit.form.ComboBox");
+		dojo.require("dijit.form.HorizontalSlider");
+		dojo.require("dijit.TitlePane");
+		
+		dojo.require('dojox.gauges.GlossyCircularGauge');
+		dojo.require('dojox.gauges.GlossySemiCircularGauge');
+		dojo.require("dojo.parser");
+		
+		dojo.addOnLoad(sample);
+		
+		
+		
+		var glossyCircular = null;
+		var glossyCircular2 = null;
+		
+		function sample(){
+		
+			// create an glossy Circular Gauge
+			glossyCircular = new dojox.gauges.GlossyCircularGauge({
+				background: [255, 255, 255, 0],
+				title: 'Value',
+				id: "glossyGauge",
+				width: 300,
+				height: 300
+			}, dojo.byId("CircularGauge"));
+			glossyCircular.startup();
+			
+			// create an glossy semi Circular Gauge
+			glossyCircular2 = new dojox.gauges.GlossySemiCircularGauge({
+				title: 'Value',
+				background: [255, 255, 255, 0],
+				id: "glossyGauge2",
+				width: 300,
+				height: 300
+			}, dojo.byId("SemiCircularGauge"));
+			glossyCircular2.startup();
+			
+		}
+		
+		function changeOrientation(orientation){
+			var t = glossyCircular.startAngle;
+			glossyCircular.startAngle = glossyCircular.endAngle;
+			glossyCircular.endAngle = t;
+			glossyCircular.set('orientation', orientation);
+			
+			t = glossyCircular2.startAngle;
+			glossyCircular2.startAngle = glossyCircular2.endAngle;
+			glossyCircular2.endAngle = t;
+			glossyCircular2.set('orientation', orientation);
+		}
+		
+		function changeGaugeColor(v){
+			glossyCircular.set('color', v);
+			glossyCircular2.set('color', v)
+		}
+		
+		function changeNeedleColor(v){
+			glossyCircular.set('needleColor', v);
+			glossyCircular2.set('needleColor', v)
+		}
+		
+		function changeMinorTicksColor(v){
+			glossyCircular.set('minorTicksColor', v);
+			glossyCircular2.set('minorTicksColor', v)
+		}
+		
+		function changeMajorTicksColor(v){
+			glossyCircular.set('majorTicksColor', v);
+			glossyCircular2.set('majorTicksColor', v)
+		}
+		
+		function changeTextIndicatorColor(v){
+			glossyCircular.set('textIndicatorColor', v);
+			glossyCircular2.set('textIndicatorColor', v)
+		}
+	</script>
+	<body class="claro">
+		<table width="100%" border="0">
+			<tr>
+				<td width="450px">
+					<div id="CircularGauge">
+					</div>
+					<div id="SemiCircularGauge">
+					</div>
+				</td>
+				<td>
+					<table border="0">
+						<tr>
+							<td>
+								Title
+							</td>
+							<td>
+								<input type="text" value="Value" dojoType="dijit.form.TextBox" trim="true" onChange="glossyCircular.set('title',this.value);glossyCircular2.set('title',this.value)">
+							</td>
+						</tr>
+						<tr>
+							<td>
+								Clockwise orientation 
+							</td>
+							<td>
+								<div dojoType='dijit.form.CheckBox' checked onChange="changeOrientation(this.checked?'clockwise':'cclockwise')" />
+							</td>
+						</tr>
+						<tr>
+							<td>
+								Minimum
+							</td>
+							<td>
+								<div dojoType='dijit.form.HorizontalSlider' intermediateChanges="true" onChange="glossyCircular.set('min',Math.round(this.value));glossyCircular2.set('min',Math.round(this.value))" value="0" minimum="0" maximum="200" discreteValues="200" showButtons="false" style="width: 200px; height: 20px"/>
+							</td>
+						</tr>
+						<tr>
+							<td>
+								Maximum
+							</td>
+							<td>
+								<div dojoType='dijit.form.HorizontalSlider' intermediateChanges="true" onChange="glossyCircular.set('max',Math.round(this.value));glossyCircular2.set('max',Math.round(this.value))" value="100" minimum="0" maximum="200" discreteValues="200" showButtons="false" style="width: 200px; height: 20px"/>
+							</td>
+						</tr>
+						<tr>
+							<td>
+								Gauge Color
+							</td>
+							<td>
+								<div id='gaugeColorPicker' dojoType='dijit.ColorPalette' onChange="changeGaugeColor" palette="3x4"/>
+							</td>
+						</tr>
+						<tr>
+							<td>
+								Needle Color
+							</td>
+							<td>
+								<div id='needleColorPicker' dojoType='dijit.ColorPalette' onChange='changeNeedleColor' palette="3x4"/>
+							</td>
+						</tr>
+						<tr>
+							<td>
+								Text Indicator Color
+							</td>
+							<td>
+								<div id='textColorPicker' dojoType='dijit.ColorPalette' onChange='changeTextIndicatorColor' palette="3x4"/>
+							</td>
+						</tr>
+						<tr>
+							<td>
+								Scale font 
+							</td>
+							<td>
+								<div dojoType='dijit.form.Button' onClick="glossyCircular.set('font','italic normal normal 18pt serif');glossyCircular2.set('font','italic normal normal 18pt serif')">
+									Sample #1
+								</div>
+								<div dojoType='dijit.form.Button' onClick="glossyCircular.set('font','normal normal bold 12pt serif');glossyCircular2.set('font','normal normal bold 12pt serif')">
+									Sample #2
+								</div>
+								<div dojoType='dijit.form.Button' onClick="glossyCircular.set('font','normal normal normal 10pt serif');glossyCircular2.set('font','normal normal normal 10pt serif')">
+									Default
+								</div>
+							</td>
+						</tr>
+						<tr>
+							<td>
+								Text Indicator font 
+							</td>
+							<td>
+								<div dojoType='dijit.form.Button' onClick="glossyCircular.set('textIndicatorFont','normal small-caps bold 12pt Arial');glossyCircular2.set('textIndicatorFont','normal small-caps bold 12pt Arial')">
+									Sample #1
+								</div>
+								<div dojoType='dijit.form.Button' onClick="glossyCircular.set('textIndicatorFont','italic normal normal 30pt Arial');glossyCircular2.set('textIndicatorFont','italic normal normal 30pt Arial')">
+									Sample #2
+								</div>
+								<div dojoType='dijit.form.Button' onClick="glossyCircular.set('textIndicatorFont','normal normal normal 20pt Arial,sans-serif');glossyCircular2.set('textIndicatorFont','normal normal normal 20pt Arial,sans-serif')">
+									Default
+								</div>
+							</td>
+						</tr>
+						<tr>
+							<td>
+								Display text indicator 
+							</td>
+							<td>
+								<div dojoType='dijit.form.CheckBox' checked onChange="glossyCircular.set('textIndicatorVisible',this.checked);glossyCircular2.set('textIndicatorVisible',this.checked)" />
+							</td>
+						</tr>
+						<tr>
+							<td>
+								Allow interaction
+							</td>
+							<td>
+								<div dojoType='dijit.form.CheckBox' checked onChange="glossyCircular.set('noChange',!this.checked);glossyCircular2.set('noChange',!this.checked)" />
+							</td>
+						</tr>
+						<tr>
+							<table border="0" width="100%">
+								<tr align="left">
+									<td title="Major Ticks">
+										<table>
+											<tr>
+												<td>
+													Major Ticks interval
+												</td>
+												<td>
+													<div dojoType='dijit.form.HorizontalSlider' intermediateChanges="true" onChange="glossyCircular.set('majorTicksInterval',this.value);glossyCircular2.set('majorTicksInterval',this.value)" value="10" minimum="1" maximum="100" discreteValues="100" showButtons="false" style="width: 200px; height: 20px"/>
+												</td>
+											</tr>
+											<tr>
+												<td>
+													Major Ticks length
+												</td>
+												<td>
+													<div dojoType='dijit.form.HorizontalSlider' intermediateChanges="true" onChange="glossyCircular.setMajorTicksLength(this.value);glossyCircular2.setMajorTicksLength(this.value)" value="5" minimum="1" maximum="15" discreteValues="1" showButtons="false" style="width: 200px; height: 20px"/>
+												</td>
+											</tr>
+											<tr>
+												<td>
+													Major Ticks Color
+												</td>
+												<td>
+													<div dojoType='dijit.ColorPalette' onChange="changeMajorTicksColor" palette="3x4"/>
+												</td>
+											</tr>
+											<tr>
+												<td>
+													Label placement inside
+												</td>
+												<td>
+													<div dojoType='dijit.form.CheckBox' checked onChange="glossyCircular.set('majorTicksLabelPlacement',this.checked?'inside':'outside');glossyCircular2.set('majorTicksLabelPlacement',this.checked?'inside':'outside')" />
+												</td>
+											</tr>
+										</table>
+									</td>
+									<td title="Minor Ticks">
+										<table>
+											<!--
+											<tr>
+											<td>
+											Minor Ticks offset
+											</td>
+											<td>
+											<div dojoType='dijit.form.HorizontalSlider' intermediateChanges="true" onChange="glossyCircular.setMinorTicksOffset(this.value)" value="130" minimum="0" maximum="200" showButtons="false" style="width: 200px; height: 20px"/>
+											</td>
+											</tr>
+											-->
+											<tr>
+												<td>
+													Minor Ticks interval
+												</td>
+												<td>
+													<div dojoType='dijit.form.HorizontalSlider' intermediateChanges="true" onChange="glossyCircular.set('minorTicksInterval',this.value);glossyCircular2.set('minorTicksInterval',this.value)" value="10" minimum="1" maximum="100" discreteValues="100" showButtons="false" style="width: 200px; height: 20px"/>
+												</td>
+											</tr>
+											<tr>
+												<td>
+													Minor Ticks length
+												</td>
+												<td>
+													<div dojoType='dijit.form.HorizontalSlider' intermediateChanges="true" onChange="glossyCircular.setMinorTicksLength(this.value);glossyCircular2.setMinorTicksLength(this.value)" value="5" minimum="1" maximum="15" discreteValues="1" showButtons="false" style="width: 200px; height: 20px"/>
+												</td>
+											</tr>
+											<tr>
+												<td>
+													Minor Ticks Color
+												</td>
+												<td>
+													<div dojoType='dijit.ColorPalette' onChange="changeMinorTicksColor" palette="3x4"/>
+												</td>
+											</tr>
+										</table>
+									</td>
+								</tr>
+							</table>
+						</tr>
+					</table>
+				</td>
+			</tr>
+		</table>
+	</body>
+</html>
\ No newline at end of file
diff --git a/dojox/gauges/tests/test_GlossyGauges-AMD.html b/dojox/gauges/tests/test_GlossyGauges-AMD.html
new file mode 100644
index 0000000..47ac021
--- /dev/null
+++ b/dojox/gauges/tests/test_GlossyGauges-AMD.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+    <head>
+        <title>Gauge</title>
+        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+    </head>
+    <style>    
+        html {
+            height: 100%;
+        }
+        
+        body {
+            margin: 0;
+            background-repeat: no-repeat;
+            background: #003366;
+            /* gecko based browsers */
+            background: -moz-linear-gradient(top,  #003366, #000000);
+                                
+            /* webkit based browsers */
+            background: -webkit-gradient(linear, left top, left bottom, from(#003366), to(#000000));
+        }
+                   
+        .footer {
+           position:absolute;
+           bottom:0;
+        }
+            
+    </style>
+ <script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: 1,  async:1"></script>
+	<script language="JavaScript" type="text/javascript">
+		require(['dojox/gauges/GlossyCircularGauge', 
+		         'dojox/gauges/GlossySemiCircularGauge', 'dojox/gauges/GlossyHorizontalGauge', 
+				 'dojo/parser'], function(){
+		})
+    </script>
+
+    <body>
+        <h2 align='center' style='color:gray;'>Glossy Gauges</h2>
+        <table style='height:100%; width:100%'>
+            <tr>
+                <td align='center'>
+                    <div id="CircularGauge" background='{color : "rgba(0,0,0,0)"}'useTooltip='false'  data-dojo-type='dojox.gauges.GlossyCircularGauge' width='200' height='200' value='20'>
+                    </div>
+                </td>
+                <td align='center'>
+                    <div id="CircularGauge2" background='{color : "rgba(0,0,0,0)"}' useTooltip='false'  data-dojo-type='dojox.gauges.GlossySemiCircularGauge' value='60' width='250' height='200'>
+                </td>
+            </tr>
+            <tr >
+                <td valign='middle' align='center' colspan='2'>
+                    <div id="HGauge3" style='margin:30px 0px 0px 0px' useTooltip='false' background='{color : "rgba(0,0,0,0)"}' data-dojo-type='dojox.gauges.GlossyHorizontalGauge' width='400' height='60' value='20'>
+                    </div>
+                </td>
+            </tr>
+        </table>
+        <div class='footer'>
+            <p style='color:gray; font-size:'xx-small'>Click a gauge to change its value.</p>
+        </div>
+        </div>
+    </body>
+</html>
diff --git a/dojox/gauges/tests/test_GlossyHorizontalGauge.html b/dojox/gauges/tests/test_GlossyHorizontalGauge.html
new file mode 100644
index 0000000..b133582
--- /dev/null
+++ b/dojox/gauges/tests/test_GlossyHorizontalGauge.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>Horizontal Gauge Sample</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+		<link rel="stylesheet" type="text/css" href="../../../dijit/themes/claro/claro.css">
+	</head>
+	<script type="text/javascript">
+		var djConfig = {
+		
+			parseOnLoad: true,
+			isDebug: true
+		}
+	</script>
+	<script type="text/javascript" src="../../../dojo/dojo.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.ColorPalette");
+		
+		dojo.require('dijit.form.Button');
+		dojo.require('dijit.form.CheckBox');
+		dojo.require("dijit.form.ComboBox");
+		dojo.require("dijit.form.HorizontalSlider");
+		dojo.require("dijit.TitlePane");
+		
+		dojo.require('dojox.gauges.GlossyHorizontalGauge');
+		dojo.require("dojo.parser");
+		
+		dojo.addOnLoad(sample);
+		
+		var gauge = null;
+		
+		function sample(){
+			// create an  Horizontal Gauge
+			gauge = new dojox.gauges.GlossyHorizontalGauge({
+				background: [255, 255, 255, 0],
+				id: "glossyGauge",
+				title: "Value",
+				width: 400,
+				height: 100
+			}, dojo.byId("HorizontalGauge"));
+			
+			gauge.startup();
+		}
+		
+		function changeGaugeColor(v){
+			gauge.set('color', v);
+		}
+		
+		function changeNeedleColor(v){
+			gauge.set('markerColor', v);
+		}
+		
+		function changeMinorTicksColor(v){
+			gauge.set('minorTicksColor', v);
+		}
+		
+		function changeMajorTicksColor(v){
+			gauge.set('majorTicksColor', v);
+		}
+	</script>
+	<body class="claro">
+		<table width="100%" border="0">
+			<tr>
+				<td width="450px">
+					<div id="HorizontalGauge">
+					</div>
+				</td>
+				<td>
+					<table border="0">
+						<tr>
+							<td>
+								Title
+							</td>
+							<td>
+								<input type="text" value="Value" dojoType="dijit.form.TextBox" trim="true" onChange="gauge.set('title',this.value);">
+							</td>
+						</tr>
+						<tr>
+							<td>
+								Minimum
+							</td>
+							<td>
+								<div dojoType='dijit.form.HorizontalSlider' intermediateChanges="true" onChange="gauge.set('min',Math.round(this.value));" value="0" minimum="0" maximum="200" discreteValues="200" showButtons="false" style="width: 200px; height: 20px"/>
+							</td>
+						</tr>
+						<tr>
+							<td>
+								Maximum
+							</td>
+							<td>
+								<div dojoType='dijit.form.HorizontalSlider' intermediateChanges="true" onChange="gauge.set('max',Math.round(this.value));" value="100" minimum="0" maximum="200" discreteValues="200" showButtons="false" style="width: 200px; height: 20px"/>
+							</td>
+						</tr>
+						<tr>
+							<td>
+								Gauge Color
+							</td>
+							<td>
+								<div id='gaugeColorPicker' dojoType='dijit.ColorPalette' onChange="changeGaugeColor" palette="3x4"/>
+							</td>
+						</tr>
+						<tr>
+							<td>
+								Needle Color
+							</td>
+							<td>
+								<div id='needleColorPicker' dojoType='dijit.ColorPalette' onChange="changeNeedleColor" palette="3x4"/>
+							</td>
+						</tr>
+						<tr>
+							<td>
+								Scale font 
+							</td>
+							<td>
+								<div dojoType='dijit.form.Button' onClick="gauge.set('font','italic normal normal 18pt Arial,sans-serif')">
+									Sample #1
+								</div>
+								<div dojoType='dijit.form.Button' onClick="gauge.set('font','normal normal bold 12pt Arial,sans-serif')">
+									Sample #2
+								</div>
+								<div dojoType='dijit.form.Button' onClick="gauge.set('font','normal normal normal 10pt serif')">
+									Default
+								</div>
+							</td>
+						</tr>
+						<tr>
+							<td>
+								Allow interaction
+							</td>
+							<td>
+								<div dojoType='dijit.form.CheckBox' checked onChange="gauge.set('noChange',!this.checked);" />
+							</td>
+						</tr>
+						<tr>
+							<table border="0" width="100%">
+								<tr align="left">
+									<td title="Major Ticks">
+										<table>
+											<tr>
+												<td>
+													Major Ticks interval
+												</td>
+												<td>
+													<div dojoType='dijit.form.HorizontalSlider' intermediateChanges="true" onChange="gauge.set('majorTicksInterval',this.value);" value="10" minimum="1" maximum="100" discreteValues="100" showButtons="false" style="width: 200px; height: 20px"/>
+												</td>
+											</tr>
+											<tr>
+												<td>
+													Major Ticks length
+												</td>
+												<td>
+													<div dojoType='dijit.form.HorizontalSlider' intermediateChanges="true" onChange="gauge.setMajorTicksLength(this.value)" value="5" minimum="1" maximum="15" discreteValues="1" showButtons="false" style="width: 200px; height: 20px"/>
+												</td>
+											</tr>
+											<tr>
+												<td>
+													Major Ticks Color
+												</td>
+												<td>
+													<div dojoType='dijit.ColorPalette' onChange="changeMajorTicksColor" palette="3x4"/>
+												</td>
+											</tr>
+										</table>
+									</td>
+									<td title="Minor Ticks">
+										<table>
+											<tr>
+												<td>
+													Minor Ticks interval
+												</td>
+												<td>
+													<div dojoType='dijit.form.HorizontalSlider' intermediateChanges="true" onChange="gauge.set('minorTicksInterval',this.value);" value="10" minimum="1" maximum="100" discreteValues="100" showButtons="false" style="width: 200px; height: 20px"/>
+												</td>
+											</tr>
+											<tr>
+												<td>
+													Minor Ticks length
+												</td>
+												<td>
+													<div dojoType='dijit.form.HorizontalSlider' intermediateChanges="true" onChange="gauge.setMinorTicksLength(this.value)" value="5" minimum="1" maximum="15" discreteValues="1" showButtons="false" style="width: 200px; height: 20px"/>
+												</td>
+											</tr>
+											<tr>
+												<td>
+													Minor Ticks Color
+												</td>
+												<td>
+													<div dojoType='dijit.ColorPalette' onChange="changeMinorTicksColor" palette="3x4"/>
+												</td>
+											</tr>
+										</table>
+									</td>
+								</tr>
+							</table>
+						</tr>
+					</table>
+				</td>
+			</tr>
+		</table>
+	</body>
+</html>
\ No newline at end of file
diff --git a/dojox/geo/README b/dojox/geo/README
index 85d638d..76b3f9b 100644
--- a/dojox/geo/README
+++ b/dojox/geo/README
@@ -12,7 +12,13 @@ Credits
 		Dean Williams (deanw at ca.ibm.com)
 		Qi Ruan (ruanqi at cn.ibm.com)
 		Wei CDL Huang (hwcdl at cn.ibm.com)
-
+    Erwan Aullas (eaullas+dojo at gmail.com)
+    Marc Durocher (durocher.marc at gmail.com)
+    
+  dojox.geo.openlayers
+    Marc Durocher (durocher.marc at gmail.com)
+    Erwan Aullas (eaullas+dojo at gmail.com)
+    
 	Tom Trenka (ttrenka at gmail.com)
 -------------------------------------------------------------------------------
 Project description
diff --git a/dojox/geo/charting/Feature.js b/dojox/geo/charting/Feature.js
new file mode 100644
index 0000000..8409321
--- /dev/null
+++ b/dojox/geo/charting/Feature.js
@@ -0,0 +1,198 @@
+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
+
+	_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) {
+			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();
+			}
+		}
+	},
+	_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"
+			});
+		});
+	},
+	_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");
+			}
+		}
+	},
+	_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) {
+		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;
+			this._isZoomIn = 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(){
+		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
new file mode 100644
index 0000000..7761095
--- /dev/null
+++ b/dojox/geo/charting/KeyboardInteractionSupport.js
@@ -0,0 +1,144 @@
+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;
+				}
+			});
+			needClick = true;
+		}
+		if(leadingRegion){
+			if(needClick) {
+				leadingRegion._onclickHandler(null);
+			}else{
+			}
+			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((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);
+		}
+	}
+});
+});
\ No newline at end of file
diff --git a/dojox/geo/charting/Map.js b/dojox/geo/charting/Map.js
index 1f72ceb..0948022 100644
--- a/dojox/geo/charting/Map.js
+++ b/dojox/geo/charting/Map.js
@@ -1,11 +1,10 @@
-dojo.provide("dojox.geo.charting.Map");
+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) {
 
-dojo.require("dojox.gfx");
-dojo.require("dojox.geo.charting._base");
-dojo.require("dojox.geo.charting._Feature");
-dojo.require("dojox.geo.charting._Marker");
-
-dojo.declare("dojox.geo.charting.Map", null, {
+	return declare("dojox.geo.charting.Map", null, {
 	//	summary:
 	//		Map widget interacted with charting.
 	//	description:
@@ -24,36 +23,126 @@ dojo.declare("dojox.geo.charting.Map", null, {
 	//	series: Array
 	//		stack to data range, e.g: [{name:'label 1', min:20, max:70, color:'#DDDDDD'},{...},...]
 	series:[],
-	constructor: function(/*HTML Node*/container, /*String*/shapeFile){
+	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
-		//	shapeFile:
-		//		map shape data url, handled as json style
-		//		data format:
+		//	shapeData:
+		//		map shape data json object, or url to json file
+		
+		html.style(container, "display", "block");
 		
-		// get map container coords
-		dojo.style(container, "display", "block");
-		this.containerSize = {
-			x: dojo.coords(container).x,
-			y: dojo.coords(container).y,
-			w: dojo.coords(container).w || 100,
-			h: dojo.coords(container).h || 100
-		};
-		this.surface = dojox.gfx.createSurface(container, this.containerSize.w, this.containerSize.h);
 		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 = {};
-        // load map shape file
-		dojo.xhrGet({
-			url: shapeFile,
-			handleAs: "json",
-			sync:true,
-			load: dojo.hitch(this, "_init")
-		});
+		
+		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);
+			}
+			
+			//	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
@@ -61,74 +150,447 @@ dojo.declare("dojox.geo.charting.Map", null, {
 		//	markerFile:
 		//		outside marker data url, handled as json style.
 		//		data format: {"NY":"New York",.....}
-		dojo.xhrGet({
+		xhr.get({
 			url: markerFile,
 			handleAs: "json",
-			handle: dojo.hitch(this, "_appendMarker")
+			handle: lang.hitch(this, "_appendMarker")
 		});
 	},
-	setDataStore: function(/*ItemFileReadStore*/ dataStore, /*Object*/ query){
-		//	summary:
-		//		populate data for each map feature from fetched data store
-		this.dataStore = dataStore;
-		var self = this;
+	
+	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();
+		}
+	},
+	
+	
+	
+	_queryDataStore: function() {
+		if (!this.dataBindingAttribute || (this.dataBindingAttribute.length == 0))
+			return;
+		
+		var mapInstance = this;
 		this.dataStore.fetch({
-			query: query,
+			scope: this,
 			onComplete: function(items){
-				var item = items[0];
-				var attributes = self.dataStore.getAttributes(item);
-				dojo.forEach(attributes, function(name){
-					if(self.mapObj.features[name]){
-						self.mapObj.features[name].setValue(self.dataStore.getValue(item, name));
+				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);
 					}
-				});
+				},this);						
 			}
 		});
 	},
-	addSeries: function(series){
+	
+	_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();
+		}
+	},
+
+	_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);
+			}
+			
+			// 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);
+
+	},
+	
+	
+	
+	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(/*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]
+			}
+			]
+		});
+
+		//install callback
+		if (onAnimationEnd) {
+			var listener = connect.connect(anim,"onEnd",this,function(event){
+				onAnimationEnd(event);
+				connect.disconnect(listener);
+			});
+		}
+		
+		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;
+	},
+	
 	_init: function(shapeData){
+		
+		//	summary: 
+		//		inits this Map component.
+		
 		//transform map to fit container
-		var mapWidth = shapeData.layerExtent[2] - shapeData.layerExtent[0];
-		var mapHeight = shapeData.layerExtent[3] - shapeData.layerExtent[1];
-		this.mapObj.scale = Math.min(this.containerSize.w / mapWidth, this.containerSize.h / mapHeight);
-		this.mapObj.currentScale = this.mapObj.scale;
-		this.mapObj.boundBox = shapeData.layerExtent;
-		this.mapObj.currentBBox = {
-			x: shapeData.layerExtent[0],
-			y:shapeData.layerExtent[1]
-		};
-		this.mapObj.setTransform([
-			dojox.gfx.matrix.scale(this.mapObj.scale),
-			dojox.gfx.matrix.translate(-shapeData.layerExtent[0], -shapeData.layerExtent[1])
-		]);
+		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.
-		dojo.forEach(shapeData.featureNames, function(item){
+		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 dojox.geo.charting._Feature(this, item, featureShape);
+			var feature = new Feature(this, item, featureShape);
 			feature.init();
 			this.mapObj.features[item] = feature;
 		}, this);
+		
 
 		//	set up a marker.
-		this.mapObj.marker = new dojox.geo.charting._Marker({}, this);
+		this.mapObj.marker = new Marker({}, this);
 	},
 	_appendMarker: function(markerData){
-		this.mapObj.marker = new dojox.geo.charting._Marker(markerData, this);
+		this.mapObj.marker = new Marker(markerData, this);
 	},
 	_createZoomingCursor: function(){
-		if(!dojo.byId("mapZoomCursor")){
-			var mapZoomCursor = dojo.doc.createElement("div");
-			dojo.attr(mapZoomCursor,"id","mapZoomCursor");
-			dojo.addClass(mapZoomCursor,"mapZoomIn");
-			dojo.style(mapZoomCursor,"display","none");
-			dojo.body().appendChild(mapZoomCursor);
+		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){
@@ -138,3 +600,4 @@ dojo.declare("dojox.geo.charting.Map", null, {
 	onZoomEnd:function(feature){
 	}
 });
+});
\ No newline at end of file
diff --git a/dojox/geo/charting/MouseInteractionSupport.js b/dojox/geo/charting/MouseInteractionSupport.js
new file mode 100644
index 0000000..fa70fc1
--- /dev/null
+++ b/dojox/geo/charting/MouseInteractionSupport.js
@@ -0,0 +1,334 @@
+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:
+		//		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: 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
+
+		
+		// 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: 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: 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
new file mode 100644
index 0000000..e196ab2
--- /dev/null
+++ b/dojox/geo/charting/TouchInteractionSupport.js
@@ -0,0 +1,312 @@
+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
+	},
+
+	connect: function() {
+		//	summary: 
+		//		install touch listeners
+		_touchStartListener = this._map.surface.connect("touchstart", this, this._touchStartHandler);
+	},
+
+	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;
+		}
+	},
+
+	_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};
+	},
+
+	_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;
+	},
+
+	_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;
+			}
+		}
+		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
+			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);
+		}
+	},
+
+	_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;
+	},
+
+	_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);
+	},
+
+	_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);
+			}
+			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;
+			}
+			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;
+		}
+	},
+	
+	_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);
+			}
+			this._map.onFeatureClick(null);
+		}
+	},
+
+	_touchMoveHandler: function(touchEvent){
+		//	summary: 
+		//		action performed on the map when a touch move was triggered 
+		//	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);
+	}
+});
+});
diff --git a/dojox/geo/charting/_Feature.js b/dojox/geo/charting/_Feature.js
deleted file mode 100644
index b2b7792..0000000
--- a/dojox/geo/charting/_Feature.js
+++ /dev/null
@@ -1,169 +0,0 @@
-dojo.provide("dojox.geo.charting._Feature");
-dojo.require("dojox.gfx.fx");
-
-dojo.declare("dojox.geo.charting._Feature", null, {
-	_isZoomIn: false,
-	_isFocused: false,
-	markerText:null,
-
-	constructor: function(parent, name, shapeData){
-		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._defaultFill = ["#FFCE52", "#CE6342", "#63A584"][Math.floor(Math.random() * 3)];
-		this._defaultFill = parent.defaultColor;
-		this._highlightFill = parent.highlightColor;
-		this._defaultStroke = {
-			width: this._normalizeStrokeWeight(.5),
-			color: "white"
-		};
-		this._scale = Math.min(this.parent.containerSize.w / this._bbox.w, this.parent.containerSize.h / this._bbox.h);
-		
-		var shapes = (dojo.isArray(shapeData.shape[0])) ? shapeData.shape : [shapeData.shape];
-		dojo.forEach(shapes, function(points){
-			this.shape.createPolyline(points).setStroke(this._defaultStroke).setFill(this._defaultFill);
-		}, this);
-	},
-	setValue:function(value){
-		this.value = value;
-		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;
-				}
-			}
-		}
-	},
-	_setFillWith: function(color){
-		var borders = (dojo.isArray(this.shape.children)) ? this.shape.children : [this.shape.children];
-		dojo.forEach(borders, function(item){
-			item.setFill(color);
-		});
-	},
-	_setStrokeWith: function(stroke){
-		var borders = (dojo.isArray(this.shape.children)) ? this.shape.children : [this.shape.children];
-		dojo.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);
-	},
-	_onmouseoutHandler: function(){
-		this._setFillWith(this._defaultFill);
-		this.mapObj.marker.hide();
-		dojo.style("mapZoomCursor", "display", "none");
-	},
-	_onmousemoveHandler: function(evt){
-		if(this._isFocused){
-			var evt = dojo.fixEvent(evt || window.event);
-			dojo.style("mapZoomCursor", "left", evt.pageX + 12 + "px");
-			dojo.style("mapZoomCursor", "top", evt.pageY + "px");
-			dojo.byId("mapZoomCursor").className = (this._isZoomIn)?"mapZoomOut":"mapZoomIn";
-			dojo.style("mapZoomCursor", "display", "block");
-		}
-	},
-	_onclickHandler: function(){
-		if(!this._isFocused){
-			for (var name in this.mapObj.features){
-				if (this.mapObj.features[name] != this){
-					this.mapObj.features[name]._setStrokeWith(this._defaultStroke);
-					this.mapObj.features[name]._setFillWith(this.mapObj.features[name]._defaultFill);
-					this.mapObj.features[name]._isFocused = false;
-					this.mapObj.features[name]._isZoomIn = false;
-				}
-			}
-			this._focus();
-		}
-		else if (this._isZoomIn){
-			this._zoomOut();
-		}
-		else {
-			this._zoomIn();
-		}
-	},
-	_focus: function(){
-		this.shape._moveToFront();
-		this._setStrokeWith({color:"black",width:this._normalizeStrokeWeight(2)});
-		this.parent.onFeatureClick(this);
-		this._isFocused = true;
-	},
-	_zoomIn: function(){
-		var anim = dojox.gfx.fx.animateTransform({
-			duration: 1000,
-			shape: this.mapObj,
-			transform: [{
-				name: "translate",
-				start: [-this.mapObj.currentBBox.x, -this.mapObj.currentBBox.y],
-				end: [-this._bbox.x, -this._bbox.y]
-			},{
-				name: "scaleAt",
-				start: [this.mapObj.currentScale, this.mapObj.currentBBox.x, this.mapObj.currentBBox.y],
-				end: [this._scale, this._bbox.x, this._bbox.y]
-			}]
-		});
-		dojo.connect(anim,"onEnd",this,function(){
-			this._setStrokeWith({color:"black",width:this._normalizeStrokeWeight(2)});
-			this.parent.onZoomEnd(this);
-		});
-		anim.play();
-		this.mapObj.currentScale = this._scale;
-		this.mapObj.currentBBox = {
-			x: this._bbox.x,
-			y: this._bbox.y
-		};
-		this._isZoomIn = true;
-		dojo.byId("mapZoomCursor").className = "";
-	},
-	_zoomOut: function(){
-		var anim = dojox.gfx.fx.animateTransform({
-			duration: 1000,
-			shape: this.mapObj,
-			transform: [{
-				name: "translate",
-				start: [-this._bbox.x, -this._bbox.y],
-				end: [-this.mapObj.boundBox[0], -this.mapObj.boundBox[1]]
-			}, {
-				name: "scaleAt",
-				start: [this._scale, this._bbox.x, this._bbox.y],
-				end: [this.mapObj.scale, this.mapObj.boundBox[0], this.mapObj.boundBox[1]]
-			}]
-		});
-		dojo.connect(anim,"onEnd",this,function(){
-			this._setStrokeWith({color:"black",width:this._normalizeStrokeWeight(2)});
-		});
-		anim.play();
-		this.mapObj.currentScale = this.mapObj.scale;
-		this.mapObj.currentBBox = {
-			x: this.mapObj.boundBox[0],
-			y: this.mapObj.boundBox[1]
-		};
-		this._isZoomIn = false;
-		dojo.byId("mapZoomCursor").className = "";
-	},
-	
-	init: function(){
-		this.shape.rawNode.id = this.id;
-		this.tooltip = null;
-		this.shape.connect("onmouseover", this, this._onmouseoverHandler);
-		this.shape.connect("onmouseout", this, this._onmouseoutHandler);
-		this.shape.connect("onmousemove", this, this._onmousemoveHandler);
-		this.shape.connect("onclick", this, this._onclickHandler);
-	}
-});
diff --git a/dojox/geo/charting/_Marker.js b/dojox/geo/charting/_Marker.js
index 78d9418..f6f2114 100644
--- a/dojox/geo/charting/_Marker.js
+++ b/dojox/geo/charting/_Marker.js
@@ -1,28 +1,40 @@
-dojo.provide("dojox.geo.charting._Marker");
 
-dojo.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;
 	},
 
-	show: function(featureId){
-		this.markerText = this.features[featureId].markerText || this.markerData[featureId] || featureId;
+	show: function(featureId,evt){
 		this.currentFeature = this.features[featureId];
-		dojox.geo.charting.showTooltip(this.markerText, this.currentFeature.shape, "before");
+		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(){
-		dojox.geo.charting.hideTooltip(this.currentFeature.shape);
+		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 = dojo.clone(bbox);
-		dojo.forEach(shapes, function(item){
+		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);
@@ -32,11 +44,11 @@ dojo.declare("dojox.geo.charting._Marker", null, {
 	_toWindowCoords: function(arround, coords, containerSize){
 		var toLeft = (arround.x - this.topLeft[0]) * this.scale;
 		var toTop = (arround.y - this.topLeft[1]) * this.scale
-		if (dojo.isFF == 3.5) {
+		if (has("ff") == 3.5) {
 			arround.x = coords.x;
 			arround.y = coords.y;
 		}
-		else if (dojo.isChrome) {
+		else if (has("chrome")) {
 			arround.x = containerSize.x + toLeft;
 			arround.y = containerSize.y + toTop;
 		}
@@ -50,3 +62,4 @@ dojo.declare("dojox.geo.charting._Marker", null, {
 		arround.y += arround.height / 4;
 	}
 });
+});
diff --git a/dojox/geo/charting/_base.js b/dojox/geo/charting/_base.js
index b6bdc6a..7e77a8c 100644
--- a/dojox/geo/charting/_base.js
+++ b/dojox/geo/charting/_base.js
@@ -1,18 +1,15 @@
-dojo.provide("dojox.geo.charting._base");
+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); 
 
-dojo.require("dojo.NodeList-traverse");
-dojo.require("dojox.gfx.matrix");
-dojo.require("dijit.Tooltip");
-
-(function(){
-	var dgc = dojox.geo.charting;
-	dgc.showTooltip = function(/*String*/innerHTML, /*dojox.gfx.shape*/ gfxObject, /*String[]?*/ position){
+	dgc.showTooltip = function(/*String*/innerHTML, /*dojox.gfx.shape*/ gfxObject, /*String[]?*/ positions){
 		var arroundNode = dgc._normalizeArround(gfxObject);
-		return dijit.showTooltip(innerHTML, arroundNode, position);
+		return Tooltip.show(innerHTML, arroundNode, positions);
 	};
 
 	dgc.hideTooltip = function( /*dojox.gfx.shape*/gfxObject){
-		return dijit.hideTooltip(gfxObject);
+		return Tooltip.hide(gfxObject);
 	};
 
 	dgc._normalizeArround = function(gfxObject){
@@ -20,25 +17,29 @@ dojo.require("dijit.Tooltip");
 		//var bbox = gfxObject.getBoundingBox();
 		//get the real screen coords for gfx object
 		var realMatrix = gfxObject._getRealMatrix() || {xx:1,xy:0,yx:0,yy:1,dx:0,dy:0};
-		var point = dojox.gfx.matrix.multiplyPoint(realMatrix, bbox.x, bbox.y);
-		var gfxDomContainer = dojo.coords(dgc._getGfxContainer(gfxObject));
-		gfxObject.x = dojo.coords(gfxDomContainer,true).x + point.x,
-		gfxObject.y = dojo.coords(gfxDomContainer,true).y + point.y,
-		gfxObject.width = bbox.width * realMatrix.xx,
-		gfxObject.height = bbox.height * realMatrix.yy
+		var point = matrix.multiplyPoint(realMatrix, bbox.x, bbox.y);
+		var gfxDomContainer = dgc._getGfxContainer(gfxObject);
+		gfxObject.x = domGeom.position(gfxDomContainer,true).x + point.x,
+		gfxObject.y = domGeom.position(gfxDomContainer,true).y + point.y,
+		gfxObject.w = bbox.width * realMatrix.xx,
+		gfxObject.h = bbox.height * realMatrix.yy
 		return gfxObject;
 	};
 
 	dgc._getGfxContainer = function(gfxObject){
-		return (new dojo.NodeList(gfxObject.rawNode)).parents("div")[0];
+		if (gfxObject.surface) {
+			return (new NodeList(gfxObject.surface.rawNode)).parents("div")[0];
+		} else {
+			return (new NodeList(gfxObject.rawNode)).parents("div")[0];
+		}
 	};
 
 	dgc._getRealBBox = function(gfxObject){
 		var bboxObject = gfxObject.getBoundingBox();
 		if(!bboxObject){//the gfx object is group
 			var shapes = gfxObject.children;
-			var bboxObject = dojo.clone(dgc._getRealBBox(shapes[0]));
-			dojo.forEach(shapes, function(item){
+			bboxObject = lang.clone(dgc._getRealBBox(shapes[0]));
+			arr.forEach(shapes, function(item){
 				var nextBBox = dgc._getRealBBox(item);
 				bboxObject.x = Math.min(bboxObject.x, nextBBox.x);
 				bboxObject.y = Math.min(bboxObject.y, nextBBox.y);
@@ -50,4 +51,4 @@ dojo.require("dijit.Tooltip");
 		}
 		return bboxObject;
 	};
-})();
+});
diff --git a/dojox/geo/charting/resources/Map.css b/dojox/geo/charting/resources/Map.css
index 2370b26..48409ee 100644
--- a/dojox/geo/charting/resources/Map.css
+++ b/dojox/geo/charting/resources/Map.css
@@ -1,4 +1,12 @@
-.tundra .dijitTooltipAbove .dijitTooltipConnector, .dj_ie .tundra .dijitTooltipAbove .dijitTooltipConnector {
+.tundra .dijitTooltipAbove .dijitTooltipConnector,
+.tundra .dijitTooltipLeft .dijitTooltipConnector,
+.tundra .dijitTooltipBottom .dijitTooltipConnector,
+.tundra .dijitTooltipRight.dijitTooltipConnector,
+.dj_ie .tundra .dijitTooltipAbove .dijitTooltipConnector 
+.dj_ie .tundra .dijitTooltipLeft .dijitTooltipConnector,
+.dj_ie .tundra .dijitTooltipBottom .dijitTooltipConnector,
+.dj_ie .tundra .dijitTooltipRight .dijitTooltipConnector
+{
 	display: none;
 }
 
diff --git a/dojox/geo/charting/resources/data/USStates.json b/dojox/geo/charting/resources/data/USStates.json
index 509034a..7014802 100644
--- a/dojox/geo/charting/resources/data/USStates.json
+++ b/dojox/geo/charting/resources/data/USStates.json
@@ -1,261 +1,262 @@
 {
-  "layerExtent":[0, 0, 8036, 5263],
-  "featureNames":["RI", "VT", "HI", "ME", "VA", "MI", "DE", "ID", "IA", "MD", "MA", "AR", "IL", "UT", "IN", "MN", "AZ", "MO", "MT", "MS", "NH", "NJ", "NM", "AK", "TX", "AL", "NC", "ND", "NE", "NY", "GA", "NV", "TN", "CA", "OK", "OH", "WY", "FL", "SD", "SC", "CT", "WV", "DC", "WI", "KY", "KS", "OR", "LA", "WA", "CO", "PA"],
-  "features":{
-    "RI":{
-      "shape":[[7641, 1436, 7651, 1437, 7661, 1467, 7661, 1467, 7653, 1478, 7641, 1436], [7541, 1398, 7559, 1392, 7598, 1380, 7615, 1420, 7635, 1430, 7635, 1431, 7627, 1445, 7626, 1427, 7615, 1429, 7607, 1410, 7618, 1435, 7606, 1444, 7617, 1460, 7618, 1506, 7612, 1496, 7568, 1527, 7568, 1526, 7541, 1398], [7633, 1474, 7639, 1442, 7645, 1476, 7631, 1485, 7633, 1474]],
-      "center":[7585, 1442],
-      "bbox":[7541, 1380, 120, 147]
-    },
-    "VT":{
-      "shape":[7427, 828, 7434, 848, 7424, 882, 7445, 909, 7444, 926, 7390, 984, 7404, 1022, 7383, 1128, 7402, 1236, 7394, 1266, 7414, 1289, 7393, 1294, 7309, 1313, 7302, 1314, 7267, 1166, 7255, 1151, 7239, 1162, 7241, 1126, 7216, 1076, 7218, 999, 7196, 969, 7184, 893, 7202, 888, 7427, 828],
-      "center":[7317, 1057],
-      "bbox":[7184, 828, 261, 487]
-    },
-    "HI":{
-      "shape":[[2254, 4585, 2254, 4606, 2228, 4628, 2227, 4605, 2254, 4585], [2319, 4564, 2350, 4551, 2385, 4559, 2393, 4577, 2383, 4610, 2361, 4625, 2334, 4617, 2305, 4588, 2319, 4564], [2597, 4694, 2619, 4684, 2634, 4731, 2654, 4734, 2664, 4766, 2634, 4772, 2610, 4758, 2611, 4743, 2600, 4747, 2608, 4758, 2584, 4760, 2558, 4702, 2597, 4694], [2790, 4803, 2827, 4807, 2796, 4829, 2719, 4809, 2731, 4787, 2790, 4803], [2835, 4839, 2851, 4839, 2864, 4864, 2908, 4860, 2948, 4903, 2921, 4921,  [...]
-      "center":[2703, 4833],
-      "bbox":[2227, 4551, 916, 711]
-    },
-    "ME":{
-      "shape":[7610, 288, 7625, 320, 7647, 327, 7714, 269, 7794, 304, 7867, 514, 7872, 558, 7925, 560, 7935, 577, 7924, 583, 7942, 600, 7938, 620, 7951, 635, 7967, 644, 7989, 630, 8016, 661, 8002, 670, 8009, 678, 7997, 675, 8010, 692, 8012, 675, 8023, 684, 8018, 671, 8036, 683, 8015, 725, 7984, 720, 7990, 744, 7983, 731, 7983, 745, 7967, 737, 7971, 762, 7958, 759, 7952, 775, 7939, 756, 7937, 801, 7931, 783, 7932, 800, 7922, 784, 7916, 789, 7929, 803, 7920, 819, 7884, 779, 7876, 786, 7891 [...]
-      "center":[7710, 682],
-      "bbox":[7468, 269, 569, 888]
-    },
-    "VA":{
-      "shape":[[7177, 2288, 7216, 2271, 7216, 2271, 7186, 2362, 7195, 2366, 7166, 2410, 7166, 2458, 7149, 2420, 7162, 2388, 7151, 2391, 7152, 2377, 7165, 2373, 7151, 2366, 7172, 2341, 7161, 2341, 7171, 2335, 7160, 2328, 7182, 2314, 7176, 2301, 7163, 2305, 7177, 2288], [6817, 2100, 6818, 2100, 6841, 2099, 6860, 2110, 6855, 2132, 6921, 2156, 6921, 2156, 6928, 2160, 6929, 2161, 6940, 2194, 6923, 2201, 6931, 2212, 6914, 2210, 6913, 2262, 6903, 2256, 6919, 2269, 6907, 2273, 6953, 2253, 6967,  [...]
-      "center":[6750, 2455],
-      "bbox":[6012, 2092, 1204, 676]
-    },
-    "MI":{
-      "shape":[[5098, 797, 5138, 760, 5201, 760, 5169, 771, 5115, 855, 5107, 841, 5115, 813, 5106, 835, 5083, 821, 5098, 797], [5071, 647, 5077, 644, 5024, 682, 5036, 684, 4995, 694, 5003, 677, 5095, 620, 5071, 647], [5296, 933, 5311, 924, 5362, 943, 5421, 886, 5578, 848, 5574, 904, 5628, 898, 5637, 911, 5670, 891, 5694, 937, 5683, 947, 5717, 955, 5713, 963, 5739, 981, 5654, 996, 5635, 982, 5627, 1025, 5589, 996, 5520, 987, 5503, 1014, 5421, 1028, 5412, 1058, 5384, 1077, 5382, 1099, 5366 [...]
-      "center":[5662, 1450],
-      "bbox":[4855, 620, 1168, 1218]
-    },
-    "DE":{
-      "shape":[7082, 1965, 7100, 1940, 7132, 1937, 7133, 1938, 7135, 1938, 7119, 1976, 7130, 2008, 7129, 2009, 7158, 2039, 7187, 2099, 7225, 2115, 7236, 2145, 7222, 2135, 7217, 2144, 7232, 2147, 7205, 2160, 7219, 2166, 7236, 2147, 7246, 2177, 7246, 2178, 7242, 2179, 7242, 2179, 7239, 2180, 7234, 2181, 7150, 2199, 7082, 1965],
-      "center":[7157, 2107],
-      "bbox":[7082, 1937, 163, 261]
-    },
-    "ID":{
-      "shape":[1428, 192, 1536, 217, 1550, 220, 1507, 416, 1537, 477, 1537, 498, 1526, 505, 1539, 522, 1521, 528, 1570, 572, 1620, 694, 1634, 689, 1638, 710, 1676, 715, 1641, 802, 1630, 805, 1638, 859, 1610, 874, 1616, 891, 1602, 915, 1628, 941, 1691, 907, 1704, 930, 1697, 943, 1706, 945, 1707, 996, 1731, 1041, 1724, 1076, 1764, 1103, 1769, 1166, 1787, 1189, 1802, 1167, 1854, 1183, 1871, 1163, 1982, 1188, 1979, 1168, 2000, 1150, 2037, 1210, 2037, 1210, 1959, 1681, 1903, 1671, 1536, 1604, [...]
-      "center":[1499, 1209],
-      "bbox":[1117, 192, 920, 1489]
-    },
-    "IA":{
-      "shape":[4779, 1552, 4779, 1554, 4782, 1580, 4804, 1599, 4789, 1625, 4809, 1695, 4860, 1714, 4871, 1739, 4871, 1740, 4911, 1792, 4944, 1810, 4945, 1869, 4908, 1927, 4825, 1952, 4817, 1986, 4843, 2012, 4843, 2044, 4825, 2066, 4822, 2096, 4782, 2118, 4789, 2150, 4781, 2154, 4781, 2154, 4734, 2111, 4171, 2132, 4143, 2131, 4125, 2102, 4136, 2071, 4126, 2040, 4131, 2018, 4119, 2014, 4127, 1995, 4115, 1986, 4121, 1965, 4095, 1948, 4099, 1898, 4089, 1865, 4074, 1860, 4059, 1827, 4054, 176 [...]
-      "center":[4463, 1860],
-      "bbox":[4018, 1552, 927, 602]
-    },
-    "MD":{
-      "shape":[[7242, 2179, 7246, 2178, 7246, 2180, 7245, 2203, 7242, 2179], [6546, 2075, 6559, 2073, 7050, 1972, 7082, 1965, 7150, 2199, 7234, 2181, 7233, 2182, 7240, 2190, 7225, 2191, 7243, 2203, 7215, 2270, 7216, 2271, 7177, 2288, 7177, 2288, 7142, 2302, 7158, 2270, 7138, 2277, 7150, 2256, 7125, 2268, 7144, 2239, 7125, 2242, 7133, 2204, 7122, 2248, 7107, 2224, 7111, 2256, 7075, 2228, 7068, 2236, 7054, 2214, 7065, 2220, 7082, 2197, 7064, 2193, 7061, 2204, 7056, 2185, 7095, 2191, 7108,  [...]
-      "center":[7052, 2222],
-      "bbox":[6546, 1965, 699, 337]
-    },
-    "MA":{
-      "shape":[[7758, 1469, 7708, 1483, 7719, 1484, 7734, 1449, 7758, 1469], [7302, 1314, 7309, 1313, 7393, 1294, 7414, 1289, 7429, 1285, 7575, 1251, 7591, 1222, 7631, 1200, 7632, 1202, 7623, 1212, 7635, 1211, 7646, 1230, 7639, 1232, 7674, 1236, 7634, 1264, 7649, 1271, 7632, 1292, 7640, 1303, 7626, 1303, 7631, 1317, 7671, 1313, 7707, 1352, 7696, 1344, 7692, 1357, 7719, 1364, 7728, 1388, 7767, 1391, 7757, 1396, 7800, 1365, 7776, 1328, 7753, 1328, 7777, 1323, 7817, 1385, 7806, 1370, 7814,  [...]
-      "center":[7490, 1333],
-      "bbox":[7302, 1200, 533, 284]
-    },
-    "AR":{
-      "shape":[4323, 2915, 4351, 2914, 5015, 2888, 5031, 2925, 4986, 2986, 5087, 2978, 5089, 2978, 5089, 2979, 5102, 2996, 5083, 3000, 5093, 3013, 5055, 3032, 5073, 3047, 5057, 3059, 5065, 3073, 5046, 3067, 5048, 3098, 5038, 3082, 5026, 3095, 5041, 3100, 5028, 3122, 5045, 3148, 5009, 3177, 5009, 3178, 5020, 3191, 5011, 3206, 4986, 3199, 4990, 3227, 4974, 3219, 4972, 3234, 4988, 3238, 4978, 3250, 4969, 3241, 4974, 3291, 4961, 3311, 4944, 3302, 4932, 3333, 4919, 3328, 4939, 3340, 4915, 335 [...]
-      "center":[4662, 3220],
-      "bbox":[4323, 2888, 779, 695]
-    },
-    "IL":{
-      "shape":[4871, 1739, 4872, 1739, 5275, 1711, 5276, 1714, 5277, 1759, 5328, 1857, 5328, 1858, 5370, 2310, 5358, 2319, 5366, 2336, 5355, 2353, 5379, 2385, 5386, 2426, 5342, 2519, 5321, 2525, 5333, 2543, 5316, 2567, 5323, 2594, 5311, 2594, 5322, 2613, 5322, 2614, 5305, 2642, 5320, 2674, 5261, 2698, 5266, 2759, 5185, 2735, 5158, 2769, 5164, 2782, 5166, 2783, 5147, 2769, 5138, 2770, 5143, 2784, 5127, 2775, 5103, 2732, 5116, 2710, 5098, 2652, 5045, 2615, 5030, 2621, 5032, 2605, 4964, 256 [...]
-      "center":[5115, 2145],
-      "bbox":[4770, 1711, 615, 1073]
-    },
-    "UT":{
-      "shape":[1536, 1604, 1903, 1671, 1959, 1681, 1956, 1693, 1927, 1871, 2214, 1915, 2213, 1925, 2105, 2676, 2039, 2667, 1351, 2546, 1345, 2545, 1536, 1604],
-      "center":[1781, 2167],
-      "bbox":[1345, 1604, 869, 1072]
-    },
-    "IN":{
-      "shape":[5428, 1839, 5717, 1806, 5718, 1819, 5721, 1845, 5778, 2313, 5777, 2313, 5768, 2324, 5779, 2338, 5773, 2350, 5788, 2355, 5786, 2374, 5734, 2399, 5695, 2396, 5701, 2433, 5675, 2455, 5666, 2484, 5645, 2489, 5637, 2538, 5620, 2553, 5585, 2539, 5567, 2513, 5574, 2523, 5553, 2530, 5550, 2566, 5531, 2585, 5501, 2558, 5472, 2578, 5462, 2603, 5385, 2574, 5383, 2602, 5340, 2587, 5340, 2610, 5323, 2613, 5322, 2613, 5311, 2594, 5323, 2594, 5316, 2567, 5333, 2543, 5321, 2525, 5342, 251 [...]
-      "center":[5553, 2130],
-      "bbox":[5311, 1806, 477, 807]
-    },
-    "MN":{
-      "shape":[3957, 591, 3967, 564, 3950, 502, 3976, 503, 4218, 503, 4217, 428, 4242, 430, 4260, 439, 4284, 553, 4388, 573, 4395, 595, 4463, 568, 4503, 569, 4544, 585, 4534, 600, 4562, 603, 4581, 646, 4594, 641, 4593, 620, 4621, 617, 4635, 642, 4688, 664, 4687, 676, 4779, 632, 4793, 661, 4874, 652, 4906, 674, 4958, 667, 4798, 754, 4628, 929, 4629, 930, 4604, 948, 4609, 1063, 4558, 1095, 4534, 1135, 4532, 1162, 4550, 1165, 4566, 1188, 4551, 1218, 4548, 1321, 4585, 1355, 4614, 1357, 4667, [...]
-      "center":[4328, 1050],
-      "bbox":[3950, 428, 1007, 1142]
-    },
-    "AZ":{
-      "shape":[2105, 2676, 1948, 3757, 1919, 3753, 1616, 3706, 1051, 3370, 1074, 3333, 1075, 3331, 1106, 3331, 1121, 3315, 1121, 3280, 1092, 3262, 1105, 3229, 1097, 3220, 1102, 3200, 1139, 3179, 1153, 3106, 1178, 3078, 1229, 3058, 1196, 3013, 1193, 2962, 1174, 2927, 1179, 2903, 1179, 2903, 1179, 2902, 1195, 2871, 1202, 2695, 1260, 2695, 1276, 2722, 1293, 2725, 1315, 2697, 1345, 2545, 1345, 2545, 1351, 2546, 2039, 2667, 2105, 2676],
-      "center":[1610, 3091],
-      "bbox":[1051, 2545, 1054, 1212]
-    },
-    "MO":{
-      "shape":[4781, 2154, 4780, 2155, 4770, 2203, 4796, 2279, 4895, 2364, 4915, 2433, 4940, 2417, 4992, 2437, 4960, 2538, 4964, 2560, 5032, 2605, 5030, 2621, 5045, 2615, 5098, 2652, 5116, 2710, 5103, 2732, 5127, 2775, 5143, 2784, 5138, 2770, 5147, 2769, 5166, 2783, 5167, 2783, 5161, 2817, 5171, 2825, 5159, 2831, 5160, 2860, 5137, 2853, 5129, 2880, 5128, 2881, 5118, 2882, 5118, 2880, 5110, 2865, 5109, 2880, 5110, 2881, 5115, 2907, 5100, 2914, 5113, 2927, 5089, 2931, 5107, 2950, 5089, 297 [...]
-      "center":[4649, 2529],
-      "bbox":[4142, 2111, 1030, 875]
-    },
-    "MT":{
-      "shape":[3074, 458, 3023, 1050, 3022, 1057, 3005, 1232, 3001, 1232, 2053, 1110, 2042, 1174, 2037, 1210, 2000, 1150, 1979, 1168, 1982, 1188, 1871, 1163, 1854, 1183, 1802, 1167, 1787, 1189, 1769, 1166, 1764, 1103, 1724, 1076, 1731, 1041, 1707, 996, 1706, 945, 1697, 943, 1704, 930, 1691, 907, 1628, 941, 1602, 915, 1616, 891, 1610, 874, 1638, 859, 1630, 805, 1641, 802, 1676, 715, 1638, 710, 1634, 689, 1620, 694, 1570, 572, 1521, 528, 1539, 522, 1526, 505, 1537, 498, 1537, 477, 1507, 41 [...]
-      "center":[2366, 706],
-      "bbox":[1507, 220, 1567, 1012]
-    },
-    "MS":{
-      "shape":[5342, 3152, 5360, 3170, 5349, 3751, 5385, 4042, 5385, 4042, 5370, 4056, 5286, 4042, 5308, 4047, 5237, 4070, 5243, 4062, 5228, 4057, 5213, 4094, 5200, 4096, 5199, 4096, 5183, 4090, 5138, 4007, 5153, 3940, 4836, 3959, 4848, 3948, 4831, 3910, 4853, 3903, 4842, 3879, 4858, 3885, 4850, 3857, 4869, 3845, 4850, 3837, 4867, 3838, 4872, 3813, 4891, 3811, 4873, 3810, 4877, 3794, 4892, 3798, 4918, 3759, 4905, 3747, 4918, 3752, 4929, 3733, 4903, 3736, 4902, 3724, 4931, 3722, 4948, 368 [...]
-      "center":[5130, 3618],
-      "bbox":[4831, 3152, 554, 944]
-    },
-    "NH":{
-      "shape":[7427, 828, 7425, 784, 7467, 758, 7468, 758, 7581, 1111, 7613, 1135, 7616, 1152, 7616, 1153, 7608, 1172, 7618, 1155, 7636, 1165, 7631, 1199, 7631, 1200, 7591, 1222, 7575, 1251, 7429, 1285, 7414, 1289, 7394, 1266, 7402, 1236, 7383, 1128, 7404, 1022, 7390, 984, 7444, 926, 7445, 909, 7424, 882, 7434, 848, 7427, 828],
-      "center":[7487, 1110],
-      "bbox":[7383, 758, 253, 531]
-    },
-    "NJ":{
-      "shape":[7167, 1623, 7175, 1625, 7297, 1663, 7292, 1722, 7290, 1722, 7255, 1776, 7310, 1776, 7302, 1788, 7313, 1783, 7311, 1794, 7305, 1766, 7312, 1771, 7319, 1834, 7309, 1835, 7321, 1839, 7325, 1898, 7317, 1844, 7308, 1847, 7317, 1847, 7308, 1852, 7315, 1867, 7304, 1869, 7317, 1870, 7319, 1912, 7299, 1943, 7306, 1955, 7288, 1950, 7297, 1971, 7285, 1979, 7298, 1986, 7264, 2005, 7281, 2005, 7260, 2061, 7254, 2048, 7258, 2069, 7235, 2086, 7234, 2040, 7200, 2046, 7131, 2007, 7130, 200 [...]
-      "center":[7248, 1862],
-      "bbox":[7119, 1623, 206, 464]
-    },
-    "NM":{
-      "shape":[2105, 2676, 2182, 2687, 3017, 2778, 3031, 2779, 3030, 2791, 3023, 2874, 3017, 2874, 2946, 3738, 2363, 3681, 2358, 3706, 2373, 3724, 2337, 3720, 2098, 3690, 2086, 3776, 1953, 3758, 1948, 3757, 2105, 2676],
-      "center":[2533, 3173],
-      "bbox":[1948, 2676, 1083, 1100]
-    },
-    "AK":{
-      "shape":[620, 3939, 642, 3931, 650, 3935, 643, 3931, 675, 3922, 680, 3925, 667, 3924, 694, 3939, 689, 3941, 699, 3939, 714, 3945, 716, 3951, 700, 3957, 686, 3954, 692, 3958, 682, 3955, 685, 3953, 664, 3953, 690, 3958, 684, 3960, 693, 3962, 682, 3961, 693, 3964, 689, 3969, 696, 3965, 713, 3966, 721, 3973, 725, 3971, 714, 3968, 714, 3961, 731, 3962, 728, 3956, 734, 3954, 738, 3960, 738, 3953, 741, 3955, 737, 3962, 744, 3956, 760, 3968, 750, 3974, 776, 3987, 791, 3982, 827, 3987, 846, [...]
-      "center":[813, 4358],
-      "bbox":[17, 3922, 1806, 1313]
-    },
-    "TX":{
-      "shape":[[3960, 4548, 3926, 4590, 3956, 4534, 4038, 4483, 3960, 4548], [3765, 3367, 3774, 3393, 3796, 3396, 3793, 3416, 3813, 3422, 3840, 3397, 3880, 3431, 3914, 3413, 3927, 3451, 3950, 3405, 3986, 3430, 4014, 3417, 4009, 3427, 4053, 3458, 4085, 3428, 4145, 3427, 4173, 3408, 4222, 3421, 4233, 3404, 4291, 3445, 4352, 3464, 4354, 3465, 4369, 3483, 4424, 3481, 4426, 3583, 4426, 3596, 4431, 3781, 4468, 3822, 4467, 3859, 4487, 3873, 4481, 3881, 4500, 3900, 4492, 3912, 4519, 3935, 4524,  [...]
-      "center":[3629, 3892],
-      "bbox":[2358, 2874, 2166, 2107]
-    },
-    "AL":{
-      "shape":[5342, 3152, 5751, 3113, 5757, 3137, 5866, 3512, 5911, 3591, 5907, 3611, 5927, 3621, 5902, 3649, 5896, 3708, 5919, 3762, 5916, 3831, 5939, 3865, 5910, 3869, 5508, 3912, 5506, 3942, 5548, 3975, 5545, 4009, 5544, 4009, 5552, 4017, 5539, 4037, 5516, 4037, 5518, 4048, 5534, 4045, 5527, 4052, 5450, 4070, 5500, 4054, 5480, 4029, 5466, 4030, 5458, 3981, 5441, 3978, 5426, 4000, 5435, 4008, 5430, 4053, 5386, 4042, 5385, 4042, 5349, 3751, 5360, 3170, 5342, 3152],
-      "center":[5617, 3547],
-      "bbox":[5342, 3113, 596, 956]
-    },
-    "NC":{
-      "shape":[[7201, 2563, 7205, 2562, 7205, 2563, 7287, 2693, 7245, 2651, 7201, 2563], [6319, 2725, 6333, 2723, 7179, 2568, 7180, 2569, 7175, 2579, 7200, 2600, 7202, 2588, 7236, 2649, 7199, 2610, 7200, 2632, 7214, 2636, 7164, 2617, 7193, 2645, 7174, 2653, 7155, 2639, 7171, 2659, 7130, 2648, 7157, 2663, 7130, 2669, 7142, 2671, 7119, 2688, 7091, 2665, 7093, 2636, 7052, 2626, 7089, 2638, 7098, 2707, 7206, 2677, 7191, 2684, 7209, 2684, 7198, 2697, 7209, 2714, 7198, 2716, 7215, 2729, 7199,  [...]
-      "center":[6700, 2826],
-      "bbox":[5952, 2562, 1361, 590]
-    },
-    "ND":{
-      "shape":[3950, 502, 3967, 564, 3957, 591, 3957, 592, 3959, 670, 3996, 776, 3997, 891, 4008, 907, 4001, 959, 4028, 1023, 4033, 1100, 4002, 1099, 3164, 1062, 3023, 1050, 3074, 458, 3116, 461, 3950, 502],
-      "center":[3524, 756],
-      "bbox":[3023, 458, 1010, 642]
-    },
-    "NE":{
-      "shape":[2971, 1616, 2976, 1616, 3755, 1662, 3820, 1709, 3848, 1690, 3931, 1693, 4010, 1732, 4020, 1761, 4043, 1765, 4044, 1765, 4045, 1765, 4054, 1768, 4059, 1827, 4074, 1860, 4089, 1865, 4099, 1898, 4095, 1948, 4121, 1965, 4115, 1986, 4127, 1995, 4119, 2014, 4131, 2018, 4126, 2040, 4136, 2071, 4125, 2102, 4143, 2131, 4142, 2133, 4159, 2139, 4159, 2184, 4185, 2197, 4195, 2236, 4211, 2244, 4206, 2243, 3243, 2215, 3215, 2213, 3228, 2022, 3006, 2005, 2937, 1999, 2971, 1616, 2971, 1616],
-      "center":[3612, 1930],
-      "bbox":[2937, 1616, 1274, 628]
-    },
-    "NY":{
-      "shape":[[7362, 1671, 7357, 1658, 7401, 1659, 7402, 1642, 7477, 1620, 7517, 1573, 7481, 1633, 7506, 1626, 7517, 1598, 7550, 1598, 7581, 1575, 7480, 1659, 7339, 1731, 7361, 1728, 7312, 1749, 7333, 1725, 7294, 1740, 7303, 1702, 7327, 1700, 7328, 1680, 7341, 1689, 7346, 1667, 7362, 1671], [7184, 893, 7196, 969, 7218, 999, 7216, 1076, 7241, 1126, 7239, 1162, 7255, 1151, 7267, 1166, 7302, 1314, 7302, 1327, 7304, 1452, 7307, 1462, 7331, 1595, 7345, 1608, 7315, 1637, 7331, 1657, 7330, 165 [...]
-      "center":[6982, 1368],
-      "bbox":[6418, 893, 1163, 873]
-    },
-    "GA":{
-      "shape":[6143, 3060, 6144, 3060, 6113, 3123, 6176, 3156, 6176, 3156, 6196, 3157, 6258, 3247, 6374, 3325, 6375, 3348, 6410, 3379, 6457, 3400, 6481, 3470, 6523, 3496, 6545, 3561, 6579, 3568, 6580, 3568, 6593, 3574, 6582, 3589, 6576, 3573, 6575, 3590, 6562, 3577, 6582, 3595, 6574, 3607, 6549, 3590, 6554, 3602, 6539, 3599, 6557, 3608, 6523, 3597, 6568, 3616, 6555, 3636, 6545, 3622, 6548, 3636, 6521, 3624, 6546, 3641, 6534, 3650, 6555, 3641, 6558, 3655, 6553, 3669, 6540, 3655, 6547, 366 [...]
-      "center":[6159, 3499],
-      "bbox":[5751, 3060, 842, 864]
-    },
-    "NV":{
-      "shape":[1536, 1604, 1345, 2545, 1345, 2545, 1315, 2697, 1293, 2725, 1276, 2722, 1260, 2695, 1202, 2695, 1195, 2871, 1179, 2902, 1179, 2903, 553, 1964, 701, 1416, 703, 1408, 722, 1413, 1117, 1512, 1117, 1512, 1118, 1512, 1535, 1604, 1536, 1604],
-      "center":[1045, 1927],
-      "bbox":[553, 1408, 983, 1495]
-    },
-    "TN":{
-      "shape":[6012, 2768, 6017, 2767, 6319, 2725, 6319, 2725, 6322, 2773, 6293, 2785, 6278, 2822, 6229, 2830, 6202, 2866, 6186, 2847, 6165, 2877, 6147, 2879, 6140, 2910, 6114, 2916, 6067, 2961, 6009, 2978, 5990, 3001, 5989, 3028, 5952, 3042, 5953, 3088, 5944, 3089, 5772, 3111, 5751, 3113, 5342, 3152, 5341, 3152, 5014, 3177, 5009, 3177, 5045, 3148, 5028, 3122, 5041, 3100, 5026, 3095, 5038, 3082, 5048, 3098, 5046, 3067, 5065, 3073, 5057, 3059, 5073, 3047, 5055, 3032, 5093, 3013, 5083, 300 [...]
-      "center":[5533, 2967],
-      "bbox":[5009, 2725, 1313, 453]
-    },
-    "CA":{
-      "shape":[124, 1236, 703, 1408, 701, 1416, 553, 1964, 1179, 2903, 1179, 2903, 1174, 2927, 1193, 2962, 1196, 3013, 1229, 3058, 1178, 3078, 1153, 3106, 1139, 3179, 1102, 3200, 1097, 3220, 1105, 3229, 1092, 3262, 1121, 3280, 1121, 3315, 1106, 3331, 1075, 3331, 1073, 3331, 684, 3281, 675, 3245, 689, 3269, 691, 3255, 679, 3241, 671, 3251, 680, 3184, 663, 3123, 582, 3010, 537, 3005, 544, 2987, 533, 2946, 487, 2941, 442, 2909, 390, 2833, 254, 2790, 232, 2760, 261, 2654, 231, 2628, 243, 260 [...]
-      "center":[507, 2428],
-      "bbox":[0, 1236, 1229, 2095]
-    },
-    "OK":{
-      "shape":[3178, 2791, 3178, 2791, 4284, 2819, 4321, 2819, 4322, 2863, 4323, 2915, 4327, 2945, 4356, 3126, 4352, 3449, 4352, 3464, 4291, 3445, 4233, 3404, 4222, 3421, 4173, 3408, 4145, 3427, 4085, 3428, 4053, 3458, 4009, 3427, 4014, 3417, 3986, 3430, 3950, 3405, 3927, 3451, 3914, 3413, 3880, 3431, 3840, 3397, 3813, 3422, 3793, 3416, 3796, 3396, 3774, 3393, 3765, 3367, 3765, 3367, 3729, 3362, 3710, 3380, 3692, 3360, 3598, 3347, 3595, 3323, 3571, 3299, 3565, 3315, 3520, 3312, 3484, 327 [...]
-      "center":[3930, 3108],
-      "bbox":[3023, 2779, 1332, 686]
-    },
-    "OH":{
-      "shape":[5911, 1786, 5991, 1817, 6004, 1801, 5999, 1814, 6023, 1808, 5975, 1832, 6041, 1829, 6027, 1817, 6061, 1832, 6123, 1797, 6162, 1796, 6219, 1734, 6320, 1675, 6321, 1675, 6364, 1929, 6364, 1929, 6345, 1942, 6363, 1991, 6345, 2130, 6303, 2183, 6281, 2195, 6267, 2184, 6254, 2214, 6237, 2217, 6224, 2255, 6236, 2284, 6216, 2296, 6209, 2275, 6192, 2271, 6172, 2320, 6184, 2354, 6168, 2361, 6166, 2388, 6127, 2398, 6127, 2398, 6084, 2371, 6074, 2341, 6017, 2380, 5981, 2364, 5961, 238 [...]
-      "center":[6096, 2082],
-      "bbox":[5718, 1675, 646, 724]
-    },
-    "WY":{
-      "shape":[3005, 1232, 3004, 1235, 2971, 1616, 2971, 1616, 2937, 1999, 2924, 1998, 2225, 1917, 2214, 1915, 1927, 1871, 1956, 1693, 1959, 1681, 2037, 1210, 2037, 1210, 2042, 1174, 2053, 1110, 3001, 1232, 3005, 1232],
-      "center":[2487, 1535],
-      "bbox":[1927, 1110, 1078, 889]
-    },
-    "FL":{
-      "shape":[6508, 3840, 6528, 3854, 6539, 3839, 6543, 3875, 6530, 3858, 6584, 4003, 6595, 4014, 6587, 3987, 6675, 4136, 6637, 4084, 6664, 4136, 6750, 4223, 6762, 4245, 6748, 4256, 6756, 4285, 6793, 4358, 6731, 4264, 6724, 4233, 6740, 4221, 6739, 4270, 6756, 4303, 6745, 4219, 6711, 4219, 6718, 4202, 6694, 4187, 6727, 4263, 6862, 4481, 6836, 4471, 6851, 4487, 6868, 4482, 6890, 4522, 6876, 4517, 6902, 4547, 6896, 4539, 6921, 4741, 6919, 4751, 6915, 4716, 6894, 4786, 6893, 4872, 6861, 486 [...]
-      "center":[6585, 4335],
-      "bbox":[5506, 3827, 1414, 1079]
-    },
-    "SD":{
-      "shape":[3023, 1050, 3164, 1062, 4002, 1099, 4033, 1100, 4029, 1123, 3992, 1163, 4047, 1222, 4045, 1570, 4025, 1570, 4035, 1591, 4026, 1613, 4047, 1642, 4018, 1718, 4044, 1765, 4043, 1765, 4020, 1761, 4010, 1732, 3931, 1693, 3848, 1690, 3820, 1709, 3755, 1662, 2976, 1616, 2971, 1616, 3004, 1235, 3005, 1232, 3022, 1057, 3023, 1050],
-      "center":[3544, 1347],
-      "bbox":[2971, 1050, 1076, 715]
-    },
-    "SC":{
-      "shape":[6176, 3156, 6113, 3123, 6144, 3060, 6143, 3060, 6249, 3003, 6461, 2982, 6465, 3002, 6480, 2987, 6509, 3016, 6511, 3038, 6686, 3010, 6891, 3152, 6891, 3152, 6826, 3243, 6815, 3270, 6821, 3298, 6801, 3279, 6812, 3254, 6800, 3266, 6799, 3286, 6821, 3302, 6814, 3316, 6806, 3304, 6812, 3316, 6795, 3313, 6807, 3317, 6785, 3340, 6797, 3341, 6769, 3342, 6758, 3362, 6768, 3367, 6729, 3404, 6719, 3386, 6734, 3368, 6716, 3392, 6709, 3373, 6716, 3402, 6698, 3393, 6727, 3408, 6714, 342 [...]
-      "center":[6541, 3231],
-      "bbox":[6113, 2982, 779, 586]
-    },
-    "CT":{
-      "shape":[7541, 1398, 7568, 1526, 7567, 1528, 7539, 1536, 7531, 1523, 7535, 1539, 7521, 1547, 7504, 1553, 7491, 1539, 7496, 1559, 7426, 1581, 7424, 1569, 7401, 1605, 7331, 1655, 7331, 1657, 7315, 1637, 7345, 1608, 7331, 1595, 7307, 1462, 7304, 1452, 7321, 1448, 7541, 1398],
-      "center":[7442, 1505],
-      "bbox":[7304, 1398, 264, 259]
-    },
-    "WV":{
-      "shape":[6364, 1929, 6369, 1959, 6394, 2102, 6546, 2075, 6549, 2091, 6565, 2173, 6610, 2111, 6632, 2114, 6652, 2069, 6669, 2087, 6701, 2086, 6702, 2065, 6726, 2061, 6736, 2044, 6790, 2051, 6785, 2062, 6804, 2069, 6817, 2100, 6817, 2101, 6809, 2139, 6720, 2092, 6723, 2150, 6670, 2239, 6647, 2227, 6621, 2315, 6560, 2293, 6550, 2358, 6492, 2481, 6507, 2491, 6493, 2505, 6500, 2512, 6479, 2534, 6467, 2527, 6433, 2553, 6418, 2545, 6415, 2567, 6368, 2591, 6344, 2575, 6301, 2608, 6258, 258 [...]
-      "center":[6378, 2332],
-      "bbox":[6127, 1929, 690, 680]
-    },
-    "DC":{
-      "shape":[6928, 2160, 6921, 2156, 6921, 2156, 6924, 2150, 6930, 2142, 6953, 2157, 6940, 2177, 6939, 2177, 6944, 2161, 6928, 2160],
-      "center":[6934, 2153],
-      "bbox":[6921, 2142, 33, 36]
-    },
-    "WI":{
-      "shape":[[5338, 1169, 5315, 1247, 5302, 1264, 5292, 1258, 5286, 1242, 5305, 1190, 5314, 1193, 5326, 1164, 5338, 1169], [4702, 927, 4791, 882, 4806, 895, 4783, 954, 4818, 940, 4808, 931, 4855, 954, 4855, 954, 4883, 965, 4898, 996, 5176, 1057, 5173, 1078, 5222, 1098, 5217, 1122, 5225, 1135, 5213, 1163, 5244, 1157, 5236, 1192, 5255, 1208, 5256, 1209, 5255, 1232, 5227, 1244, 5210, 1289, 5214, 1313, 5205, 1316, 5221, 1322, 5264, 1256, 5284, 1246, 5301, 1264, 5282, 1331, 5285, 1384, 5268 [...]
-      "center":[4969, 1326],
-      "bbox":[4532, 882, 805, 857]
-    },
-    "KY":{
-      "shape":[[5118, 2880, 5110, 2881, 5109, 2880, 5110, 2865, 5118, 2880], [5778, 2313, 5780, 2312, 5831, 2303, 5874, 2358, 5927, 2360, 5961, 2382, 5981, 2364, 6017, 2380, 6074, 2341, 6084, 2371, 6127, 2398, 6127, 2398, 6127, 2399, 6128, 2452, 6159, 2478, 6155, 2489, 6192, 2533, 6212, 2535, 6222, 2552, 6247, 2551, 6247, 2552, 6230, 2571, 6144, 2648, 6127, 2694, 6098, 2707, 6091, 2729, 6012, 2768, 6011, 2769, 5334, 2828, 5339, 2863, 5140, 2878, 5129, 2880, 5137, 2853, 5160, 2860, 5159,  [...]
-      "center":[5828, 2581],
-      "bbox":[5109, 2303, 1138, 577]
-    },
-    "KS":{
-      "shape":[3215, 2213, 3243, 2215, 4206, 2243, 4211, 2244, 4210, 2245, 4242, 2269, 4266, 2264, 4277, 2292, 4262, 2293, 4241, 2331, 4274, 2360, 4282, 2393, 4319, 2406, 4321, 2819, 4284, 2819, 3178, 2791, 3178, 2791, 3210, 2296, 3215, 2213],
-      "center":[3753, 2506],
-      "bbox":[3178, 2213, 1143, 606]
-    },
-    "OR":{
-      "shape":[477, 509, 504, 509, 532, 539, 534, 584, 521, 593, 534, 585, 521, 632, 526, 623, 577, 662, 633, 657, 633, 657, 691, 657, 734, 693, 810, 686, 863, 705, 955, 690, 1008, 704, 1037, 696, 1297, 762, 1309, 764, 1309, 766, 1319, 800, 1346, 822, 1352, 851, 1276, 949, 1267, 976, 1234, 998, 1194, 1057, 1195, 1080, 1231, 1110, 1197, 1168, 1117, 1512, 1117, 1512, 722, 1413, 703, 1408, 124, 1236, 124, 1235, 110, 1211, 113, 1167, 135, 1113, 125, 1067, 178, 985, 186, 997, 204, 973, 210, 9 [...]
-      "center":[746, 1019],
-      "bbox":[110, 466, 1241, 1045]
-    },
-    "LA":{
-      "shape":[4426, 3583, 4464, 3582, 4879, 3569, 4894, 3568, 4894, 3569, 4889, 3586, 4903, 3571, 4912, 3587, 4897, 3615, 4915, 3623, 4900, 3641, 4922, 3637, 4913, 3654, 4928, 3664, 4910, 3656, 4908, 3669, 4932, 3675, 4928, 3692, 4948, 3689, 4931, 3722, 4902, 3724, 4903, 3736, 4929, 3733, 4918, 3752, 4905, 3747, 4918, 3759, 4892, 3798, 4877, 3794, 4873, 3810, 4891, 3811, 4872, 3813, 4867, 3838, 4850, 3837, 4869, 3845, 4850, 3857, 4858, 3885, 4842, 3879, 4853, 3903, 4831, 3910, 4848, 394 [...]
-      "center":[4688, 3984],
-      "bbox":[4426, 3568, 872, 772]
-    },
-    "WA":{
-      "shape":[717, 0, 1411, 188, 1428, 192, 1306, 692, 1315, 731, 1304, 745, 1309, 764, 1297, 762, 1037, 696, 1008, 704, 955, 690, 863, 705, 810, 686, 734, 693, 691, 657, 633, 657, 633, 656, 586, 660, 539, 635, 528, 620, 541, 567, 535, 534, 510, 509, 483, 507, 446, 465, 392, 456, 416, 389, 407, 438, 415, 443, 422, 427, 431, 442, 422, 423, 431, 419, 429, 393, 435, 403, 437, 387, 456, 393, 444, 375, 417, 370, 422, 336, 433, 355, 435, 342, 468, 337, 434, 312, 419, 331, 430, 294, 436, 171,  [...]
-      "center":[952, 376],
-      "bbox":[392, 0, 1036, 764]
-    },
-    "CO":{
-      "shape":[2214, 1915, 2225, 1917, 2924, 1998, 2937, 1999, 3006, 2005, 3228, 2022, 3215, 2213, 3210, 2296, 3178, 2791, 3134, 2787, 3031, 2779, 3017, 2778, 2182, 2687, 2105, 2676, 2213, 1925, 2214, 1915],
-      "center":[2749, 2301],
-      "bbox":[2105, 1915, 1123, 875]
-    },
-    "PA":{
-      "shape":[6321, 1675, 6417, 1602, 6418, 1601, 6427, 1652, 7046, 1524, 7066, 1546, 7094, 1550, 7103, 1589, 7121, 1609, 7167, 1623, 7166, 1623, 7122, 1706, 7138, 1727, 7125, 1764, 7132, 1786, 7151, 1788, 7157, 1810, 7217, 1848, 7133, 1938, 7132, 1937, 7100, 1940, 7082, 1965, 7050, 1972, 6559, 2073, 6546, 2075, 6394, 2102, 6369, 1959, 6364, 1929, 6321, 1675],
-      "center":[6777, 1802],
-      "bbox":[6321, 1524, 896, 578]
+  "layerExtent":[0.0, 0.0, 8036.4007820436855, 5262.578216533747],
+    "layerExtentLL":[-124.7342529296875, 23.725082397460938, 57.780250549316406, 25.66031265258789],
+    "featureNames":["RI", "VT", "HI", "ME", "VA", "MI", "DE", "ID", "IA", "MD", "MA", "AR", "IL", "UT", "IN", "MN", "AZ", "MO", "MT", "MS", "NH", "NJ", "NM", "AK", "TX", "AL", "NC", "ND", "NE", "NY", "GA", "NV", "TN", "CA", "OK", "OH", "WY", "FL", "SD", "SC", "CT", "WV", "DC", "WI", "KY", "KS", "OR", "LA", "WA", "CO", "PA"],
+    "features":{
+      "RI":{
+        "shape":[[7641, 1436, 7651, 1437, 7661, 1467, 7661, 1467, 7653, 1478, 7641, 1436], [7541, 1398, 7559, 1392, 7598, 1380, 7615, 1420, 7635, 1430, 7635, 1431, 7627, 1445, 7626, 1427, 7615, 1429, 7607, 1410, 7618, 1435, 7606, 1444, 7617, 1460, 7618, 1506, 7612, 1496, 7568, 1527, 7568, 1526, 7541, 1398], [7633, 1474, 7639, 1442, 7645, 1476, 7631, 1485, 7633, 1474]],
+        "center":[7585, 1442],
+        "bbox":[7541.023426203894, 1379.9911631012965, 120.38955278578123, 146.89851936205946]
+      },
+      "VT":{
+        "shape":[7427, 828, 7434, 848, 7424, 882, 7445, 909, 7444, 926, 7390, 984, 7404, 1022, 7383, 1128, 7402, 1236, 7394, 1266, 7414, 1289, 7393, 1294, 7309, 1313, 7302, 1314, 7267, 1166, 7255, 1151, 7239, 1162, 7241, 1126, 7216, 1076, 7218, 999, 7196, 969, 7184, 893, 7202, 888, 7427, 828],
+        "center":[7317, 1057],
+        "bbox":[7183.629180866541, 827.7125085121527, 261.2952454831775, 486.6287466336828]
+      },
+      "HI":{
+        "shape":[[2254, 4585, 2254, 4606, 2228, 4628, 2227, 4605, 2254, 4585], [2319, 4564, 2350, 4551, 2385, 4559, 2393, 4577, 2383, 4610, 2361, 4625, 2334, 4617, 2305, 4588, 2319, 4564], [2597, 4694, 2619, 4684, 2634, 4731, 2654, 4734, 2664, 4766, 2634, 4772, 2610, 4758, 2611, 4743, 2600, 4747, 2608, 4758, 2584, 4760, 2558, 4702, 2597, 4694], [2790, 4803, 2827, 4807, 2796, 4829, 2719, 4809, 2731, 4787, 2790, 4803], [2835, 4839, 2851, 4839, 2864, 4864, 2908, 4860, 2948, 4903, 2921, 4921 [...]
+        "center":[2703, 4833],
+        "bbox":[2226.7877701712587, 4551.091358635575, 915.9598550544888, 711.4868578981723]
+      },
+      "ME":{
+        "shape":[7610, 288, 7625, 320, 7647, 327, 7714, 269, 7794, 304, 7867, 514, 7872, 558, 7925, 560, 7935, 577, 7924, 583, 7942, 600, 7938, 620, 7951, 635, 7967, 644, 7989, 630, 8016, 661, 8002, 670, 8009, 678, 7997, 675, 8010, 692, 8012, 675, 8023, 684, 8018, 671, 8036, 683, 8015, 725, 7984, 720, 7990, 744, 7983, 731, 7983, 745, 7967, 737, 7971, 762, 7958, 759, 7952, 775, 7939, 756, 7937, 801, 7931, 783, 7932, 800, 7922, 784, 7916, 789, 7929, 803, 7920, 819, 7884, 779, 7876, 786, 78 [...]
+        "center":[7710, 682],
+        "bbox":[7467.685076331587, 269.1289575024286, 568.7157057120985, 887.6751354524711]
+      },
+      "VA":{
+        "shape":[[7177, 2288, 7216, 2271, 7216, 2271, 7186, 2362, 7195, 2366, 7166, 2410, 7166, 2458, 7149, 2420, 7162, 2388, 7151, 2391, 7152, 2377, 7165, 2373, 7151, 2366, 7172, 2341, 7161, 2341, 7171, 2335, 7160, 2328, 7182, 2314, 7176, 2301, 7163, 2305, 7177, 2288], [6817, 2100, 6818, 2100, 6841, 2099, 6860, 2110, 6855, 2132, 6921, 2156, 6921, 2156, 6928, 2160, 6929, 2161, 6940, 2194, 6923, 2201, 6931, 2212, 6914, 2210, 6913, 2262, 6903, 2256, 6919, 2269, 6907, 2273, 6953, 2253, 6967 [...]
+        "center":[6750, 2455],
+        "bbox":[6012.441825481979, 2091.8790360725766, 1203.6208629785642, 675.6390679572082]
+      },
+      "MI":{
+        "shape":[[5098, 797, 5138, 760, 5201, 760, 5169, 771, 5115, 855, 5107, 841, 5115, 813, 5106, 835, 5083, 821, 5098, 797], [5071, 647, 5077, 644, 5024, 682, 5036, 684, 4995, 694, 5003, 677, 5095, 620, 5071, 647], [5296, 933, 5311, 924, 5362, 943, 5421, 886, 5578, 848, 5574, 904, 5628, 898, 5637, 911, 5670, 891, 5694, 937, 5683, 947, 5717, 955, 5713, 963, 5739, 981, 5654, 996, 5635, 982, 5627, 1025, 5589, 996, 5520, 987, 5503, 1014, 5421, 1028, 5412, 1058, 5384, 1077, 5382, 1099, 53 [...]
+        "center":[5662, 1450],
+        "bbox":[4854.911490750158, 620.4912315367447, 1167.6361755384014, 1218.2194209192758]
+      },
+      "DE":{
+        "shape":[7082, 1965, 7100, 1940, 7132, 1937, 7133, 1938, 7135, 1938, 7119, 1976, 7130, 2008, 7129, 2009, 7158, 2039, 7187, 2099, 7225, 2115, 7236, 2145, 7222, 2135, 7217, 2144, 7232, 2147, 7205, 2160, 7219, 2166, 7236, 2147, 7246, 2177, 7246, 2178, 7242, 2179, 7242, 2179, 7239, 2180, 7234, 2181, 7150, 2199, 7082, 1965],
+        "center":[7157, 2107],
+        "bbox":[7082.430069572815, 1937.1742059381268, 163.18616844855842, 261.4809650452348]
+      },
+      "ID":{
+        "shape":[1428, 192, 1536, 217, 1550, 220, 1507, 416, 1537, 477, 1537, 498, 1526, 505, 1539, 522, 1521, 528, 1570, 572, 1620, 694, 1634, 689, 1638, 710, 1676, 715, 1641, 802, 1630, 805, 1638, 859, 1610, 874, 1616, 891, 1602, 915, 1628, 941, 1691, 907, 1704, 930, 1697, 943, 1706, 945, 1707, 996, 1731, 1041, 1724, 1076, 1764, 1103, 1769, 1166, 1787, 1189, 1802, 1167, 1854, 1183, 1871, 1163, 1982, 1188, 1979, 1168, 2000, 1150, 2037, 1210, 2037, 1210, 1959, 1681, 1903, 1671, 1536, 160 [...]
+        "center":[1499, 1209],
+        "bbox":[1116.7271597781803, 191.89745587373298, 920.1469178039938, 1488.964617046075]
+      },
+      "IA":{
+        "shape":[4779, 1552, 4779, 1554, 4782, 1580, 4804, 1599, 4789, 1625, 4809, 1695, 4860, 1714, 4871, 1739, 4871, 1740, 4911, 1792, 4944, 1810, 4945, 1869, 4908, 1927, 4825, 1952, 4817, 1986, 4843, 2012, 4843, 2044, 4825, 2066, 4822, 2096, 4782, 2118, 4789, 2150, 4781, 2154, 4781, 2154, 4734, 2111, 4171, 2132, 4143, 2131, 4125, 2102, 4136, 2071, 4126, 2040, 4131, 2018, 4119, 2014, 4127, 1995, 4115, 1986, 4121, 1965, 4095, 1948, 4099, 1898, 4089, 1865, 4074, 1860, 4059, 1827, 4054, 1 [...]
+        "center":[4463, 1860],
+        "bbox":[4018.187084563174, 1552.3336974056806, 926.7482669008059, 601.9610296119108]
+      },
+      "MD":{
+        "shape":[[7242, 2179, 7246, 2178, 7246, 2180, 7245, 2203, 7242, 2179], [6546, 2075, 6559, 2073, 7050, 1972, 7082, 1965, 7150, 2199, 7234, 2181, 7233, 2182, 7240, 2190, 7225, 2191, 7243, 2203, 7215, 2270, 7216, 2271, 7177, 2288, 7177, 2288, 7142, 2302, 7158, 2270, 7138, 2277, 7150, 2256, 7125, 2268, 7144, 2239, 7125, 2242, 7133, 2204, 7122, 2248, 7107, 2224, 7111, 2256, 7075, 2228, 7068, 2236, 7054, 2214, 7065, 2220, 7082, 2197, 7064, 2193, 7061, 2204, 7056, 2185, 7095, 2191, 7108 [...]
+        "center":[7052, 2222],
+        "bbox":[6546.235946891058, 1964.9808172764635, 699.4200881793276, 336.6030056060624]
+      },
+      "MA":{
+        "shape":[[7758, 1469, 7708, 1483, 7719, 1484, 7734, 1449, 7758, 1469], [7302, 1314, 7309, 1313, 7393, 1294, 7414, 1289, 7429, 1285, 7575, 1251, 7591, 1222, 7631, 1200, 7632, 1202, 7623, 1212, 7635, 1211, 7646, 1230, 7639, 1232, 7674, 1236, 7634, 1264, 7649, 1271, 7632, 1292, 7640, 1303, 7626, 1303, 7631, 1317, 7671, 1313, 7707, 1352, 7696, 1344, 7692, 1357, 7719, 1364, 7728, 1388, 7767, 1391, 7757, 1396, 7800, 1365, 7776, 1328, 7753, 1328, 7777, 1323, 7817, 1385, 7806, 1370, 7814 [...]
+        "center":[7490, 1333],
+        "bbox":[7301.785749503367, 1200.2581210721266, 533.1245306226901, 283.6107339386617]
+      },
+      "AR":{
+        "shape":[4323, 2915, 4351, 2914, 5015, 2888, 5031, 2925, 4986, 2986, 5087, 2978, 5089, 2978, 5089, 2979, 5102, 2996, 5083, 3000, 5093, 3013, 5055, 3032, 5073, 3047, 5057, 3059, 5065, 3073, 5046, 3067, 5048, 3098, 5038, 3082, 5026, 3095, 5041, 3100, 5028, 3122, 5045, 3148, 5009, 3177, 5009, 3178, 5020, 3191, 5011, 3206, 4986, 3199, 4990, 3227, 4974, 3219, 4972, 3234, 4988, 3238, 4978, 3250, 4969, 3241, 4974, 3291, 4961, 3311, 4944, 3302, 4932, 3333, 4919, 3328, 4939, 3340, 4915, 3 [...]
+        "center":[4662, 3220],
+        "bbox":[4322.829240491697, 2887.82523560477, 778.9827073906772, 694.879092657869]
+      },
+      "IL":{
+        "shape":[4871, 1739, 4872, 1739, 5275, 1711, 5276, 1714, 5277, 1759, 5328, 1857, 5328, 1858, 5370, 2310, 5358, 2319, 5366, 2336, 5355, 2353, 5379, 2385, 5386, 2426, 5342, 2519, 5321, 2525, 5333, 2543, 5316, 2567, 5323, 2594, 5311, 2594, 5322, 2613, 5322, 2614, 5305, 2642, 5320, 2674, 5261, 2698, 5266, 2759, 5185, 2735, 5158, 2769, 5164, 2782, 5166, 2783, 5147, 2769, 5138, 2770, 5143, 2784, 5127, 2775, 5103, 2732, 5116, 2710, 5098, 2652, 5045, 2615, 5030, 2621, 5032, 2605, 4964, 2 [...]
+        "center":[5115, 2145],
+        "bbox":[4770.196295410327, 1711.191338731059, 615.4388548089883, 1073.0606632626743]
+      },
+      "UT":{
+        "shape":[1536, 1604, 1903, 1671, 1959, 1681, 1956, 1693, 1927, 1871, 2214, 1915, 2213, 1925, 2105, 2676, 2039, 2667, 1351, 2546, 1345, 2545, 1536, 1604],
+        "center":[1781, 2167],
+        "bbox":[1344.750115055111, 1604.3978062032195, 869.4968003325662, 1072.015936358547]
+      },
+      "IN":{
+        "shape":[5428, 1839, 5717, 1806, 5718, 1819, 5721, 1845, 5778, 2313, 5777, 2313, 5768, 2324, 5779, 2338, 5773, 2350, 5788, 2355, 5786, 2374, 5734, 2399, 5695, 2396, 5701, 2433, 5675, 2455, 5666, 2484, 5645, 2489, 5637, 2538, 5620, 2553, 5585, 2539, 5567, 2513, 5574, 2523, 5553, 2530, 5550, 2566, 5531, 2585, 5501, 2558, 5472, 2578, 5462, 2603, 5385, 2574, 5383, 2602, 5340, 2587, 5340, 2610, 5323, 2613, 5322, 2613, 5311, 2594, 5323, 2594, 5316, 2567, 5333, 2543, 5321, 2525, 5342, 2 [...]
+        "center":[5553, 2130],
+        "bbox":[5310.914233466702, 1806.2693159343437, 476.59488846766635, 807.1441757493742]
+      },
+      "MN":{
+        "shape":[3957, 591, 3967, 564, 3950, 502, 3976, 503, 4218, 503, 4217, 428, 4242, 430, 4260, 439, 4284, 553, 4388, 573, 4395, 595, 4463, 568, 4503, 569, 4544, 585, 4534, 600, 4562, 603, 4581, 646, 4594, 641, 4593, 620, 4621, 617, 4635, 642, 4688, 664, 4687, 676, 4779, 632, 4793, 661, 4874, 652, 4906, 674, 4958, 667, 4798, 754, 4628, 929, 4629, 930, 4604, 948, 4609, 1063, 4558, 1095, 4534, 1135, 4532, 1162, 4550, 1165, 4566, 1188, 4551, 1218, 4548, 1321, 4585, 1355, 4614, 1357, 466 [...]
+        "center":[4328, 1050],
+        "bbox":[3950.4253913269413, 427.57079578020245, 1007.2005431623966, 1142.3275358037831]
+      },
+      "AZ":{
+        "shape":[2105, 2676, 1948, 3757, 1919, 3753, 1616, 3706, 1051, 3370, 1074, 3333, 1075, 3331, 1106, 3331, 1121, 3315, 1121, 3280, 1092, 3262, 1105, 3229, 1097, 3220, 1102, 3200, 1139, 3179, 1153, 3106, 1178, 3078, 1229, 3058, 1196, 3013, 1193, 2962, 1174, 2927, 1179, 2903, 1179, 2903, 1179, 2902, 1195, 2871, 1202, 2695, 1260, 2695, 1276, 2722, 1293, 2725, 1315, 2697, 1345, 2545, 1345, 2545, 1351, 2546, 2039, 2667, 2105, 2676],
+        "center":[1610, 3091],
+        "bbox":[1051.3556136955926, 2544.815557518358, 1053.5072639848177, 1212.212023750329]
+      },
+      "MO":{
+        "shape":[4781, 2154, 4780, 2155, 4770, 2203, 4796, 2279, 4895, 2364, 4915, 2433, 4940, 2417, 4992, 2437, 4960, 2538, 4964, 2560, 5032, 2605, 5030, 2621, 5045, 2615, 5098, 2652, 5116, 2710, 5103, 2732, 5127, 2775, 5143, 2784, 5138, 2770, 5147, 2769, 5166, 2783, 5167, 2783, 5161, 2817, 5171, 2825, 5159, 2831, 5160, 2860, 5137, 2853, 5129, 2880, 5128, 2881, 5118, 2882, 5118, 2880, 5110, 2865, 5109, 2880, 5110, 2881, 5115, 2907, 5100, 2914, 5113, 2927, 5089, 2931, 5107, 2950, 5089, 2 [...]
+        "center":[4649, 2529],
+        "bbox":[4141.599891262755, 2111.1869114797505, 1029.5962543407404, 874.9905328579766]
+      },
+      "MT":{
+        "shape":[3074, 458, 3023, 1050, 3022, 1057, 3005, 1232, 3001, 1232, 2053, 1110, 2042, 1174, 2037, 1210, 2000, 1150, 1979, 1168, 1982, 1188, 1871, 1163, 1854, 1183, 1802, 1167, 1787, 1189, 1769, 1166, 1764, 1103, 1724, 1076, 1731, 1041, 1707, 996, 1706, 945, 1697, 943, 1704, 930, 1691, 907, 1628, 941, 1602, 915, 1616, 891, 1610, 874, 1638, 859, 1630, 805, 1641, 802, 1676, 715, 1638, 710, 1634, 689, 1620, 694, 1570, 572, 1521, 528, 1539, 522, 1526, 505, 1537, 498, 1537, 477, 1507,  [...]
+        "center":[2366, 706],
+        "bbox":[1506.9365729336703, 219.959812182772, 1567.488761621926, 1012.1411673843539]
+      },
+      "MS":{
+        "shape":[5342, 3152, 5360, 3170, 5349, 3751, 5385, 4042, 5385, 4042, 5370, 4056, 5286, 4042, 5308, 4047, 5237, 4070, 5243, 4062, 5228, 4057, 5213, 4094, 5200, 4096, 5199, 4096, 5183, 4090, 5138, 4007, 5153, 3940, 4836, 3959, 4848, 3948, 4831, 3910, 4853, 3903, 4842, 3879, 4858, 3885, 4850, 3857, 4869, 3845, 4850, 3837, 4867, 3838, 4872, 3813, 4891, 3811, 4873, 3810, 4877, 3794, 4892, 3798, 4918, 3759, 4905, 3747, 4918, 3752, 4929, 3733, 4903, 3736, 4902, 3724, 4931, 3722, 4948, 3 [...]
+        "center":[5130, 3618],
+        "bbox":[4830.8439535221705, 3152.185506272538, 554.1423743161158, 943.8294240195419]
+      },
+      "NH":{
+        "shape":[7427, 828, 7425, 784, 7467, 758, 7468, 758, 7581, 1111, 7613, 1135, 7616, 1152, 7616, 1153, 7608, 1172, 7618, 1155, 7636, 1165, 7631, 1199, 7631, 1200, 7591, 1222, 7575, 1251, 7429, 1285, 7414, 1289, 7394, 1266, 7402, 1236, 7383, 1128, 7404, 1022, 7390, 984, 7444, 926, 7445, 909, 7424, 882, 7434, 848, 7427, 828],
+        "center":[7487, 1110],
+        "bbox":[7383.275752846597, 757.6279479694789, 253.13402332287387, 530.9874508377478]
+      },
+      "NJ":{
+        "shape":[7167, 1623, 7175, 1625, 7297, 1663, 7292, 1722, 7290, 1722, 7255, 1776, 7310, 1776, 7302, 1788, 7313, 1783, 7311, 1794, 7305, 1766, 7312, 1771, 7319, 1834, 7309, 1835, 7321, 1839, 7325, 1898, 7317, 1844, 7308, 1847, 7317, 1847, 7308, 1852, 7315, 1867, 7304, 1869, 7317, 1870, 7319, 1912, 7299, 1943, 7306, 1955, 7288, 1950, 7297, 1971, 7285, 1979, 7298, 1986, 7264, 2005, 7281, 2005, 7260, 2061, 7254, 2048, 7258, 2069, 7235, 2086, 7234, 2040, 7200, 2046, 7131, 2007, 7130, 2 [...]
+        "center":[7248, 1862],
+        "bbox":[7119.486993899072, 1622.7122776765768, 205.74226205555533, 463.7265235430323]
+      },
+      "NM":{
+        "shape":[2105, 2676, 2182, 2687, 3017, 2778, 3031, 2779, 3030, 2791, 3023, 2874, 3017, 2874, 2946, 3738, 2363, 3681, 2358, 3706, 2373, 3724, 2337, 3720, 2098, 3690, 2086, 3776, 1953, 3758, 1948, 3757, 2105, 2676],
+        "center":[2533, 3173],
+        "bbox":[1947.8141535882821, 2676.4137425617664, 1082.71177385349, 1099.5607135602122]
+      },
+      "AK":{
+        "shape":[620, 3939, 642, 3931, 650, 3935, 643, 3931, 675, 3922, 680, 3925, 667, 3924, 694, 3939, 689, 3941, 699, 3939, 714, 3945, 716, 3951, 700, 3957, 686, 3954, 692, 3958, 682, 3955, 685, 3953, 664, 3953, 690, 3958, 684, 3960, 693, 3962, 682, 3961, 693, 3964, 689, 3969, 696, 3965, 713, 3966, 721, 3973, 725, 3971, 714, 3968, 714, 3961, 731, 3962, 728, 3956, 734, 3954, 738, 3960, 738, 3953, 741, 3955, 737, 3962, 744, 3956, 760, 3968, 750, 3974, 776, 3987, 791, 3982, 827, 3987, 84 [...]
+        "center":[813, 4358],
+        "bbox":[17.226250526593294, 3922.1622828273585, 1806.1690621660666, 1313.3765572801585]
+      },
+      "TX":{
+        "shape":[[3960, 4548, 3926, 4590, 3956, 4534, 4038, 4483, 3960, 4548], [3765, 3367, 3774, 3393, 3796, 3396, 3793, 3416, 3813, 3422, 3840, 3397, 3880, 3431, 3914, 3413, 3927, 3451, 3950, 3405, 3986, 3430, 4014, 3417, 4009, 3427, 4053, 3458, 4085, 3428, 4145, 3427, 4173, 3408, 4222, 3421, 4233, 3404, 4291, 3445, 4352, 3464, 4354, 3465, 4369, 3483, 4424, 3481, 4426, 3583, 4426, 3596, 4431, 3781, 4468, 3822, 4467, 3859, 4487, 3873, 4481, 3881, 4500, 3900, 4492, 3912, 4519, 3935, 4524 [...]
+        "center":[3629, 3892],
+        "bbox":[2357.5862085056892, 2873.8949636291673, 2166.2516199112247, 2106.8870904247105]
+      },
+      "AL":{
+        "shape":[5342, 3152, 5751, 3113, 5757, 3137, 5866, 3512, 5911, 3591, 5907, 3611, 5927, 3621, 5902, 3649, 5896, 3708, 5919, 3762, 5916, 3831, 5939, 3865, 5910, 3869, 5508, 3912, 5506, 3942, 5548, 3975, 5545, 4009, 5544, 4009, 5552, 4017, 5539, 4037, 5516, 4037, 5518, 4048, 5534, 4045, 5527, 4052, 5450, 4070, 5500, 4054, 5480, 4029, 5466, 4030, 5458, 3981, 5441, 3978, 5426, 4000, 5435, 4008, 5430, 4053, 5386, 4042, 5385, 4042, 5349, 3751, 5360, 3170, 5342, 3152],
+        "center":[5617, 3547],
+        "bbox":[5342.095656308308, 3113.4827673729174, 596.451313025831, 956.3113443753509]
+      },
+      "NC":{
+        "shape":[[7201, 2563, 7205, 2562, 7205, 2563, 7287, 2693, 7245, 2651, 7201, 2563], [6319, 2725, 6333, 2723, 7179, 2568, 7180, 2569, 7175, 2579, 7200, 2600, 7202, 2588, 7236, 2649, 7199, 2610, 7200, 2632, 7214, 2636, 7164, 2617, 7193, 2645, 7174, 2653, 7155, 2639, 7171, 2659, 7130, 2648, 7157, 2663, 7130, 2669, 7142, 2671, 7119, 2688, 7091, 2665, 7093, 2636, 7052, 2626, 7089, 2638, 7098, 2707, 7206, 2677, 7191, 2684, 7209, 2684, 7198, 2697, 7209, 2714, 7198, 2716, 7215, 2729, 7199 [...]
+        "center":[6700, 2826],
+        "bbox":[5952.042953294017, 2562.1635913643336, 1361.0084056628302, 590.1898019127811]
+      },
+      "ND":{
+        "shape":[3950, 502, 3967, 564, 3957, 591, 3957, 592, 3959, 670, 3996, 776, 3997, 891, 4008, 907, 4001, 959, 4028, 1023, 4033, 1100, 4002, 1099, 3164, 1062, 3023, 1050, 3074, 458, 3116, 461, 3950, 502],
+        "center":[3524, 756],
+        "bbox":[3022.527264265822, 457.59212376958726, 1010.0102311329347, 641.9094378926393]
+      },
+      "NE":{
+        "shape":[2971, 1616, 2976, 1616, 3755, 1662, 3820, 1709, 3848, 1690, 3931, 1693, 4010, 1732, 4020, 1761, 4043, 1765, 4044, 1765, 4045, 1765, 4054, 1768, 4059, 1827, 4074, 1860, 4089, 1865, 4099, 1898, 4095, 1948, 4121, 1965, 4115, 1986, 4127, 1995, 4119, 2014, 4131, 2018, 4126, 2040, 4136, 2071, 4125, 2102, 4143, 2131, 4142, 2133, 4159, 2139, 4159, 2184, 4185, 2197, 4195, 2236, 4211, 2244, 4206, 2243, 3243, 2215, 3215, 2213, 3228, 2022, 3006, 2005, 2937, 1999, 2971, 1616, 2971, 1616],
+        "center":[3612, 1930],
+        "bbox":[2937.015040594679, 1615.8297803697847, 1273.652496708105, 627.6938449973413]
+      },
+      "NY":{
+        "shape":[[7362, 1671, 7357, 1658, 7401, 1659, 7402, 1642, 7477, 1620, 7517, 1573, 7481, 1633, 7506, 1626, 7517, 1598, 7550, 1598, 7581, 1575, 7480, 1659, 7339, 1731, 7361, 1728, 7312, 1749, 7333, 1725, 7294, 1740, 7303, 1702, 7327, 1700, 7328, 1680, 7341, 1689, 7346, 1667, 7362, 1671], [7184, 893, 7196, 969, 7218, 999, 7216, 1076, 7241, 1126, 7239, 1162, 7255, 1151, 7267, 1166, 7302, 1314, 7302, 1327, 7304, 1452, 7307, 1462, 7331, 1595, 7345, 1608, 7315, 1637, 7331, 1657, 7330, 1 [...]
+        "center":[6982, 1368],
+        "bbox":[6417.580786242645, 893.4859395487013, 1162.9619795113686, 873.4925980295768]
+      },
+      "GA":{
+        "shape":[6143, 3060, 6144, 3060, 6113, 3123, 6176, 3156, 6176, 3156, 6196, 3157, 6258, 3247, 6374, 3325, 6375, 3348, 6410, 3379, 6457, 3400, 6481, 3470, 6523, 3496, 6545, 3561, 6579, 3568, 6580, 3568, 6593, 3574, 6582, 3589, 6576, 3573, 6575, 3590, 6562, 3577, 6582, 3595, 6574, 3607, 6549, 3590, 6554, 3602, 6539, 3599, 6557, 3608, 6523, 3597, 6568, 3616, 6555, 3636, 6545, 3622, 6548, 3636, 6521, 3624, 6546, 3641, 6534, 3650, 6555, 3641, 6558, 3655, 6553, 3669, 6540, 3655, 6547, 3 [...]
+        "center":[6159, 3499],
+        "bbox":[5751.066659695458, 3059.735439125348, 842.1830852324074, 864.2944778928199]
+      },
+      "NV":{
+        "shape":[1536, 1604, 1345, 2545, 1345, 2545, 1315, 2697, 1293, 2725, 1276, 2722, 1260, 2695, 1202, 2695, 1195, 2871, 1179, 2902, 1179, 2903, 553, 1964, 701, 1416, 703, 1408, 722, 1413, 1117, 1512, 1117, 1512, 1118, 1512, 1535, 1604, 1536, 1604],
+        "center":[1045, 1927],
+        "bbox":[552.6877160601398, 1407.9247770441316, 982.9101261496735, 1495.0102889725422]
+      },
+      "TN":{
+        "shape":[6012, 2768, 6017, 2767, 6319, 2725, 6319, 2725, 6322, 2773, 6293, 2785, 6278, 2822, 6229, 2830, 6202, 2866, 6186, 2847, 6165, 2877, 6147, 2879, 6140, 2910, 6114, 2916, 6067, 2961, 6009, 2978, 5990, 3001, 5989, 3028, 5952, 3042, 5953, 3088, 5944, 3089, 5772, 3111, 5751, 3113, 5342, 3152, 5341, 3152, 5014, 3177, 5009, 3177, 5045, 3148, 5028, 3122, 5041, 3100, 5026, 3095, 5038, 3082, 5048, 3098, 5046, 3067, 5065, 3073, 5057, 3059, 5073, 3047, 5055, 3032, 5093, 3013, 5083, 3 [...]
+        "center":[5533, 2967],
+        "bbox":[5008.8876325677875, 2724.57469597311, 1312.8105366827986, 452.62423421965195]
+      },
+      "CA":{
+        "shape":[124, 1236, 703, 1408, 701, 1416, 553, 1964, 1179, 2903, 1179, 2903, 1174, 2927, 1193, 2962, 1196, 3013, 1229, 3058, 1178, 3078, 1153, 3106, 1139, 3179, 1102, 3200, 1097, 3220, 1105, 3229, 1092, 3262, 1121, 3280, 1121, 3315, 1106, 3331, 1075, 3331, 1073, 3331, 684, 3281, 675, 3245, 689, 3269, 691, 3255, 679, 3241, 671, 3251, 680, 3184, 663, 3123, 582, 3010, 537, 3005, 544, 2987, 533, 2946, 487, 2941, 442, 2909, 390, 2833, 254, 2790, 232, 2760, 261, 2654, 231, 2628, 243, 2 [...]
+        "center":[507, 2428],
+        "bbox":[0.0, 1235.8258093785118, 1228.720840043634, 2095.1776242661253]
+      },
+      "OK":{
+        "shape":[3178, 2791, 3178, 2791, 4284, 2819, 4321, 2819, 4322, 2863, 4323, 2915, 4327, 2945, 4356, 3126, 4352, 3449, 4352, 3464, 4291, 3445, 4233, 3404, 4222, 3421, 4173, 3408, 4145, 3427, 4085, 3428, 4053, 3458, 4009, 3427, 4014, 3417, 3986, 3430, 3950, 3405, 3927, 3451, 3914, 3413, 3880, 3431, 3840, 3397, 3813, 3422, 3793, 3416, 3796, 3396, 3774, 3393, 3765, 3367, 3765, 3367, 3729, 3362, 3710, 3380, 3692, 3360, 3598, 3347, 3595, 3323, 3571, 3299, 3565, 3315, 3520, 3312, 3484, 3 [...]
+        "center":[3930, 3108],
+        "bbox":[3023.197942403276, 2778.8561310642554, 1332.3624136691633, 685.566148248552]
+      },
+      "OH":{
+        "shape":[5911, 1786, 5991, 1817, 6004, 1801, 5999, 1814, 6023, 1808, 5975, 1832, 6041, 1829, 6027, 1817, 6061, 1832, 6123, 1797, 6162, 1796, 6219, 1734, 6320, 1675, 6321, 1675, 6364, 1929, 6364, 1929, 6345, 1942, 6363, 1991, 6345, 2130, 6303, 2183, 6281, 2195, 6267, 2184, 6254, 2214, 6237, 2217, 6224, 2255, 6236, 2284, 6216, 2296, 6209, 2275, 6192, 2271, 6172, 2320, 6184, 2354, 6168, 2361, 6166, 2388, 6127, 2398, 6127, 2398, 6084, 2371, 6074, 2341, 6017, 2380, 5981, 2364, 5961, 2 [...]
+        "center":[6096, 2082],
+        "bbox":[5718.242249393261, 1674.6267669674462, 645.9704766536042, 723.8687419559174]
+      },
+      "WY":{
+        "shape":[3005, 1232, 3004, 1235, 2971, 1616, 2971, 1616, 2937, 1999, 2924, 1998, 2225, 1917, 2214, 1915, 1927, 1871, 1956, 1693, 1959, 1681, 2037, 1210, 2037, 1210, 2042, 1174, 2053, 1110, 3001, 1232, 3005, 1232],
+        "center":[2487, 1535],
+        "bbox":[1926.8321924800312, 1110.197616627383, 1077.7683497025378, 889.2322221788561]
+      },
+      "FL":{
+        "shape":[6508, 3840, 6528, 3854, 6539, 3839, 6543, 3875, 6530, 3858, 6584, 4003, 6595, 4014, 6587, 3987, 6675, 4136, 6637, 4084, 6664, 4136, 6750, 4223, 6762, 4245, 6748, 4256, 6756, 4285, 6793, 4358, 6731, 4264, 6724, 4233, 6740, 4221, 6739, 4270, 6756, 4303, 6745, 4219, 6711, 4219, 6718, 4202, 6694, 4187, 6727, 4263, 6862, 4481, 6836, 4471, 6851, 4487, 6868, 4482, 6890, 4522, 6876, 4517, 6902, 4547, 6896, 4539, 6921, 4741, 6919, 4751, 6915, 4716, 6894, 4786, 6893, 4872, 6861, 4 [...]
+        "center":[6585, 4335],
+        "bbox":[5506.310458865219, 3827.186951564696, 1414.2469623466595, 1078.9271397334787]
+      },
+      "SD":{
+        "shape":[3023, 1050, 3164, 1062, 4002, 1099, 4033, 1100, 4029, 1123, 3992, 1163, 4047, 1222, 4045, 1570, 4025, 1570, 4035, 1591, 4026, 1613, 4047, 1642, 4018, 1718, 4044, 1765, 4043, 1765, 4020, 1761, 4010, 1732, 3931, 1693, 3848, 1690, 3820, 1709, 3755, 1662, 2976, 1616, 2971, 1616, 3004, 1235, 3005, 1232, 3022, 1057, 3023, 1050],
+        "center":[3544, 1347],
+        "bbox":[2971.124373651464, 1050.043615899464, 1075.661674971776, 715.2386540159926]
+      },
+      "SC":{
+        "shape":[6176, 3156, 6113, 3123, 6144, 3060, 6143, 3060, 6249, 3003, 6461, 2982, 6465, 3002, 6480, 2987, 6509, 3016, 6511, 3038, 6686, 3010, 6891, 3152, 6891, 3152, 6826, 3243, 6815, 3270, 6821, 3298, 6801, 3279, 6812, 3254, 6800, 3266, 6799, 3286, 6821, 3302, 6814, 3316, 6806, 3304, 6812, 3316, 6795, 3313, 6807, 3317, 6785, 3340, 6797, 3341, 6769, 3342, 6758, 3362, 6768, 3367, 6729, 3404, 6719, 3386, 6734, 3368, 6716, 3392, 6709, 3373, 6716, 3402, 6698, 3393, 6727, 3408, 6714, 3 [...]
+        "center":[6541, 3231],
+        "bbox":[6112.614477369485, 2981.961131844549, 778.5946861628072, 586.2283645094535]
+      },
+      "CT":{
+        "shape":[7541, 1398, 7568, 1526, 7567, 1528, 7539, 1536, 7531, 1523, 7535, 1539, 7521, 1547, 7504, 1553, 7491, 1539, 7496, 1559, 7426, 1581, 7424, 1569, 7401, 1605, 7331, 1655, 7331, 1657, 7315, 1637, 7345, 1608, 7331, 1595, 7307, 1462, 7304, 1452, 7321, 1448, 7541, 1398],
+        "center":[7442, 1505],
+        "bbox":[7304.222285771861, 1397.8167615354203, 263.7757107347343, 259.100971032168]
+      },
+      "WV":{
+        "shape":[6364, 1929, 6369, 1959, 6394, 2102, 6546, 2075, 6549, 2091, 6565, 2173, 6610, 2111, 6632, 2114, 6652, 2069, 6669, 2087, 6701, 2086, 6702, 2065, 6726, 2061, 6736, 2044, 6790, 2051, 6785, 2062, 6804, 2069, 6817, 2100, 6817, 2101, 6809, 2139, 6720, 2092, 6723, 2150, 6670, 2239, 6647, 2227, 6621, 2315, 6560, 2293, 6550, 2358, 6492, 2481, 6507, 2491, 6493, 2505, 6500, 2512, 6479, 2534, 6467, 2527, 6433, 2553, 6418, 2545, 6415, 2567, 6368, 2591, 6344, 2575, 6301, 2608, 6258, 2 [...]
+        "center":[6378, 2332],
+        "bbox":[6127.105822495098, 1928.5641252578148, 690.343968832166, 679.5274353689069]
+      },
+      "DC":{
+        "shape":[6928, 2160, 6921, 2156, 6921, 2156, 6924, 2150, 6930, 2142, 6953, 2157, 6940, 2177, 6939, 2177, 6944, 2161, 6928, 2160],
+        "center":[6934, 2153],
+        "bbox":[6920.506533181993, 2141.589247282631, 32.58943373685452, 35.901722553833224]
+      },
+      "WI":{
+        "shape":[[5338, 1169, 5315, 1247, 5302, 1264, 5292, 1258, 5286, 1242, 5305, 1190, 5314, 1193, 5326, 1164, 5338, 1169], [4702, 927, 4791, 882, 4806, 895, 4783, 954, 4818, 940, 4808, 931, 4855, 954, 4855, 954, 4883, 965, 4898, 996, 5176, 1057, 5173, 1078, 5222, 1098, 5217, 1122, 5225, 1135, 5213, 1163, 5244, 1157, 5236, 1192, 5255, 1208, 5256, 1209, 5255, 1232, 5227, 1244, 5210, 1289, 5214, 1313, 5205, 1316, 5221, 1322, 5264, 1256, 5284, 1246, 5301, 1264, 5282, 1331, 5285, 1384, 52 [...]
+        "center":[4969, 1326],
+        "bbox":[4532.3918561497785, 881.6938347091063, 805.2276107605994, 857.1162210960997]
+      },
+      "KY":{
+        "shape":[[5118, 2880, 5110, 2881, 5109, 2880, 5110, 2865, 5118, 2880], [5778, 2313, 5780, 2312, 5831, 2303, 5874, 2358, 5927, 2360, 5961, 2382, 5981, 2364, 6017, 2380, 6074, 2341, 6084, 2371, 6127, 2398, 6127, 2398, 6127, 2399, 6128, 2452, 6159, 2478, 6155, 2489, 6192, 2533, 6212, 2535, 6222, 2552, 6247, 2551, 6247, 2552, 6230, 2571, 6144, 2648, 6127, 2694, 6098, 2707, 6091, 2729, 6012, 2768, 6011, 2769, 5334, 2828, 5339, 2863, 5140, 2878, 5129, 2880, 5137, 2853, 5160, 2860, 5159 [...]
+        "center":[5828, 2581],
+        "bbox":[5109.050661398359, 2303.369688273179, 1137.790998421695, 577.2572832752585]
+      },
+      "KS":{
+        "shape":[3215, 2213, 3243, 2215, 4206, 2243, 4211, 2244, 4210, 2245, 4242, 2269, 4266, 2264, 4277, 2292, 4262, 2293, 4241, 2331, 4274, 2360, 4282, 2393, 4319, 2406, 4321, 2819, 4284, 2819, 3178, 2791, 3178, 2791, 3210, 2296, 3215, 2213],
+        "center":[3753, 2506],
+        "bbox":[3177.7941461662417, 2213.4066104839408, 1143.4447618402305, 605.7450113212822]
+      },
+      "OR":{
+        "shape":[477, 509, 504, 509, 532, 539, 534, 584, 521, 593, 534, 585, 521, 632, 526, 623, 577, 662, 633, 657, 633, 657, 691, 657, 734, 693, 810, 686, 863, 705, 955, 690, 1008, 704, 1037, 696, 1297, 762, 1309, 764, 1309, 766, 1319, 800, 1346, 822, 1352, 851, 1276, 949, 1267, 976, 1234, 998, 1194, 1057, 1195, 1080, 1231, 1110, 1197, 1168, 1117, 1512, 1117, 1512, 722, 1413, 703, 1408, 124, 1236, 124, 1235, 110, 1211, 113, 1167, 135, 1113, 125, 1067, 178, 985, 186, 997, 204, 973, 210, [...]
+        "center":[746, 1019],
+        "bbox":[110.42702484968872, 466.18654659455024, 1241.1399115078336, 1045.3897533373636]
+      },
+      "LA":{
+        "shape":[4426, 3583, 4464, 3582, 4879, 3569, 4894, 3568, 4894, 3569, 4889, 3586, 4903, 3571, 4912, 3587, 4897, 3615, 4915, 3623, 4900, 3641, 4922, 3637, 4913, 3654, 4928, 3664, 4910, 3656, 4908, 3669, 4932, 3675, 4928, 3692, 4948, 3689, 4931, 3722, 4902, 3724, 4903, 3736, 4929, 3733, 4918, 3752, 4905, 3747, 4918, 3759, 4892, 3798, 4877, 3794, 4873, 3810, 4891, 3811, 4872, 3813, 4867, 3838, 4850, 3837, 4869, 3845, 4850, 3857, 4858, 3885, 4842, 3879, 4853, 3903, 4831, 3910, 4848, 3 [...]
+        "center":[4688, 3984],
+        "bbox":[4426.055011069621, 3568.2982314605933, 872.2791142400201, 771.7208876645427]
+      },
+      "WA":{
+        "shape":[717, 0, 1411, 188, 1428, 192, 1306, 692, 1315, 731, 1304, 745, 1309, 764, 1297, 762, 1037, 696, 1008, 704, 955, 690, 863, 705, 810, 686, 734, 693, 691, 657, 633, 657, 633, 656, 586, 660, 539, 635, 528, 620, 541, 567, 535, 534, 510, 509, 483, 507, 446, 465, 392, 456, 416, 389, 407, 438, 415, 443, 422, 427, 431, 442, 422, 423, 431, 419, 429, 393, 435, 403, 437, 387, 456, 393, 444, 375, 417, 370, 422, 336, 433, 355, 435, 342, 468, 337, 434, 312, 419, 331, 430, 294, 436, 171 [...]
+        "center":[952, 376],
+        "bbox":[391.5842598432282, 0.0, 1036.0850727961474, 764.2512207821578]
+      },
+      "CO":{
+        "shape":[2214, 1915, 2225, 1917, 2924, 1998, 2937, 1999, 3006, 2005, 3228, 2022, 3215, 2213, 3210, 2296, 3178, 2791, 3134, 2787, 3031, 2779, 3017, 2778, 2182, 2687, 2105, 2676, 2213, 1925, 2214, 1915],
+        "center":[2749, 2301],
+        "bbox":[2104.8628776804103, 1915.455020807188, 1122.9312587549507, 875.2906417521679]
+      },
+      "PA":{
+        "shape":[6321, 1675, 6417, 1602, 6418, 1601, 6427, 1652, 7046, 1524, 7066, 1546, 7094, 1550, 7103, 1589, 7121, 1609, 7167, 1623, 7166, 1623, 7122, 1706, 7138, 1727, 7125, 1764, 7132, 1786, 7151, 1788, 7157, 1810, 7217, 1848, 7133, 1938, 7132, 1937, 7100, 1940, 7082, 1965, 7050, 1972, 6559, 2073, 6546, 2075, 6394, 2102, 6369, 1959, 6364, 1929, 6321, 1675],
+        "center":[6777, 1802],
+        "bbox":[6320.668447791168, 1524.3096158541616, 896.2956547030162, 577.9314409361236]
+      }
     }
-  }
 }
diff --git a/dojox/geo/charting/resources/data/series.json b/dojox/geo/charting/resources/data/series.json
new file mode 100644
index 0000000..7d0b807
--- /dev/null
+++ b/dojox/geo/charting/resources/data/series.json
@@ -0,0 +1,20 @@
+{
+	"series": [{
+		name: "Low sales state(0~$3.0M)",
+		min: "0.0",
+		max: "3.0",
+		color: "#FFCE52"
+	},
+	{
+		name: "Normal sales state($3.0M~$6.0M)",
+		min: "3.0",
+		max: "6.0",
+		color: "#63A584"
+	},
+	{
+		name: "High sales state($6.0M~$10.0M)",
+		min: "6.0",
+		max: "9.0",
+		color: "#CE6342"
+	}]
+}
diff --git a/dojox/geo/charting/tests/datastore/dataStore.json b/dojox/geo/charting/tests/datastore/dataStore.json
index 73459db..1fee73a 100644
--- a/dojox/geo/charting/tests/datastore/dataStore.json
+++ b/dojox/geo/charting/tests/datastore/dataStore.json
@@ -1 +1 @@
-{"identifier":"product","idAttribute":"product","label":"product","items":[{"product":"A","RI":7.462633468705088,"VT":1.0747727711335298,"HI":5.799375636164497,"ME":1.451271727380056,"VA":2.829702713495596,"MI":5.642995600110112,"DE":2.739617463034918,"ID":2.363980549092777,"IA":7.431769770088566,"MD":3.0785135982470684,"MA":1.7526041060228308,"AR":3.8586965961630613,"IL":4.429268677942292,"UT":1.4132568641617622,"IN":4.278380121077843,"MN":1.7667677604047078,"AZ":3.1685622594553893,"MO" [...]
\ No newline at end of file
+{	"identifier": "State",	"label": "State",	"items": [{		"State": "RI",		"product  A": 7.462633468705088,		"product B": 2.9470583970267237,		"product C": 1.2074466753785296,		"product D": 1.2022236908488764,		"product E": 5.336555888565814,		"product F": 4.805973785497435	},	{		"State": "VT",		"product A": 1.0747727711335298,		"product B": 4.334786112963775,		"product C": 6.617436105834342,		"product D": 5.601530537934105,		"product E": 1.0269790425535916,		"product F": 3.9031095011563894 [...]
\ 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 2544633..c8d015a 100644
--- a/dojox/geo/charting/tests/test_mapWithCharting.html
+++ b/dojox/geo/charting/tests/test_mapWithCharting.html
@@ -21,42 +21,83 @@
 				border: solid 1px;
 			}
 		</style>
-		<script type="text/javascript" djConfig="parseOnLoad:true,gfxRenderer:'svg,vml,silverlight'" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript" djConfig="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);
+		</script>
 		<script type="text/javascript">
 			dojo.require("dojox.geo.charting.Map");
-			dojo.require("dojox.charting.DataChart");
+			dojo.require("dojox.charting.Chart");
+			dojo.require("dojox.charting.axis2d.Default");
+      		dojo.require("dojox.charting.plot2d.ClusteredBars");
+			dojo.require("dojox.charting.plot2d.Grid");
 			dojo.require("dojo.data.ItemFileReadStore");
+			dojo.requireIf(isTouchDevice,"dojox.geo.charting.TouchInteractionSupport");
+			dojo.requireIf(!isTouchDevice,"dojox.geo.charting.MouseInteractionSupport");
+			dojo.require("dojox.geo.charting.KeyboardInteractionSupport");
+			dojo.require("dojox.charting.themes.PlotKit.blue");
 			var chartStore = new dojo.data.ItemFileReadStore({
 				url: "datastore/dataStore.json"
 			});
-			var chart;
+			var chart,series,productList;
 			dojo.addOnLoad(function(){
-				chart = new dojox.charting.DataChart("chartDiv", {
-					displayRange: 8,
-					yaxis: {
-						max: 8,
-						min: 1,
-						majorTickStep: 1,
-						labelFunc: "seriesLabels",
-						maxLabelSize: 30
-					},
-					scroll: false
-				});
-				chart.addPlot("default", {
-					type: "Bars",
-					gap: 2,
-					animate: {
-						duration: 1000
-					}
-				});
-				
+				productSeries = [0,0,0,0,0,0];
+            	productList = ["product A", "product B","product C","product D","product E","product F"];
+			
+				chart = (new dojox.charting.Chart("chartDiv")).
+						addAxis("x", {
+							fixLower: "major",
+							fixUpper: "major",
+							minorTicks: false,
+							includeZero: true,
+							min:0,
+							max: 8,
+							labelFunc: function(value) {
+								return "$" + value + "M";
+							}
+						}).
+						addAxis("y", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true,labels: [
+								{ value: 1, text: productList[0] },
+								{ value: 2, text: productList[1] },
+								{ value: 3, text: productList[2] },
+								{ value: 4, text: productList[3] },
+								{ value: 5, text: productList[4] },
+								{ value: 6, text: productList[5] }
+							]}).
+						addPlot("default", { type: "ClusteredBars", gap: 5, animate:{duration: 1000}}).
+						addSeries("productSeries", productSeries, { stroke: { color: "gray" }, fill: "gray" }).
+						render();
 				var map = new dojox.geo.charting.Map("map", "../resources/data/USStates.json");
 				map.setMarkerData("../resources/markers/USStates.json");
+				// install mouse/touch navigation
+				if (!isTouchDevice) {
+					var mouseInteraction = new dojox.geo.charting.MouseInteractionSupport(map,{enablePan:true,enableZoom:true});
+					mouseInteraction.connect();
+				} else {
+					var touchInteraction = new dojox.geo.charting.TouchInteractionSupport(map,{});
+					touchInteraction.connect();
+				}
+				var keyboardInteraction = new dojox.geo.charting.KeyboardInteractionSupport(map, {enableZoom: true});
+				keyboardInteraction.connect();
+			
 				map.onFeatureClick = function(feature){
-					if (!feature._isFocused) {
-						chart.setStore(chartStore, {
-							product: "*"
-						}, feature.id);
+					
+					if (!feature) {
+						productSeries = [0,0,0,0,0,0];
+						chart.updateSeries("productSeries",productSeries);
+						chart.render();
+					} else if (!feature.isSelected) {
+						chartStore.fetchItemByIdentity({
+			            	identity: feature.id,
+			            	onItem: function(item){
+				                for (var i = productList.length - 1; i >= 0; i--){
+									productSeries[i] = chartStore.getValue(item, productList[i]);
+								};
+								chart.updateSeries("productSeries",productSeries);
+								chart.render();
+			            	}
+			        	});
 					}
 				};
 			});
@@ -64,6 +105,7 @@
 	</head>
 	<body class="tundra">
 		<h1>Map connect with DataChart(Click on map)</h1>
+		<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 style="width:610px;height:400px;border:solid 1px;background:#f5f5f5;" id="map">
 		</div>
 		<div id="chartDiv" style="width: 400px; height: 150px;">
diff --git a/dojox/geo/charting/tests/test_mapWithLegend.html b/dojox/geo/charting/tests/test_mapWithLegend.html
index 6606a35..4dd7da5 100644
--- a/dojox/geo/charting/tests/test_mapWithLegend.html
+++ b/dojox/geo/charting/tests/test_mapWithLegend.html
@@ -8,23 +8,47 @@
 			@import "../../../../dijit/themes/tundra/tundra.css";
 			@import "../resources/Map.css";
 		</style>
-		<script type="text/javascript" djConfig="parseOnLoad:true,gfxRenderer:'svg,vml,silverlight'" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript" djConfig="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);
+		</script>
 		<script type="text/javascript">
 			dojo.require("dojox.geo.charting.Map");
 			dojo.require("dojox.geo.charting.widget.Legend");
-			dojo.require("dojo.data.ItemFileReadStore");
+			dojo.require("dojo.data.ItemFileWriteStore");
+			dojo.require("dijit.form.RadioButton");
+			dojo.require("dijit.layout.BorderContainer");
+			dojo.require("dijit.layout.ContentPane");
+			dojo.requireIf(isTouchDevice,"dojox.geo.charting.TouchInteractionSupport");
+			dojo.requireIf(!isTouchDevice,"dojox.geo.charting.MouseInteractionSupport");
+			dojo.require("dojox.geo.charting.KeyboardInteractionSupport");
+			
 			dojo.addOnLoad(function(){
 				//create new map
 				var map = new dojox.geo.charting.Map("USStates", "../resources/data/USStates.json");
 				//add outside map marker file
 				map.setMarkerData("../resources/markers/USStates.json");
+				
+				// install mouse/touch navigation
+				if (!isTouchDevice) {
+					var mouseInteraction = new dojox.geo.charting.MouseInteractionSupport(map,{enablePan:true,enableZoom:true});
+					mouseInteraction.connect();
+				} else {
+					var touchInteraction = new dojox.geo.charting.TouchInteractionSupport(map,{});
+					touchInteraction.connect();
+				}
+				// install keyboard navigation
+				var keyboardInteraction = new dojox.geo.charting.KeyboardInteractionSupport(map, {enableZoom: true});
+        		keyboardInteraction.connect();
+				
 				//set data store to map
-				var dataStore = new dojo.data.ItemFileReadStore({
+				var dataStore = new dojo.data.ItemFileWriteStore({
 					url: "datastore/dataStore.json"
 				});
-				map.setDataStore(dataStore, {
-					product: "A"
-				});
+								
+				map.setDataStore(dataStore, "product A");
+				
 				//add series to map 
 				map.addSeries([{
 					name: "Low sales state(0~$3.0M)",
@@ -48,16 +72,66 @@
 				});
 				//map marker customization
 				map.onFeatureOver = function(feature){
-					if(!feature.markerText){
-						feature.markerText = map.mapObj.marker.markerData[feature.id] + ": $" + feature.value.toFixed(3) + "M";
+					feature.markerText = map.mapObj.marker.markerData[feature.id] + ": $" + feature.value.toFixed(3) + "M";
+				};
+				
+				dojo.connect(window,"onresize",this,function() {map.resize();});
+				
+							
+				changeProduct = function(radioButton) {
+					//console.log("change product called " + productName);
+					if (radioButton.checked) {
+						map.setDataBindingAttribute(radioButton.value);
 					}
 				};
+
+				function changeStoreValues() {
+					for (prop in map.mapObj.features) {
+						dataStore.fetchItemByIdentity({
+							identity: prop, 
+        					onItem: function(item) {
+            					dataStore.setValue(item,"product A",Math.random() * 10);
+            					//dataStore.setValue(item,"product B",Math.random() * 10);
+            					//dataStore.setValue(item,"product C",Math.random() * 10);
+            					
+        					}, 
+        					onError: function(err) { console.info(err.message);}
+    					}); 
+					}
+				}
+				
+				// simulate product value changes
+				//setInterval(changeStoreValues,1000);
+				
 			});
-		</script>
+
+	
+</script>
 	</head>
-	<body class="tundra">
+	<body class="tundra" >
 		<h1>Map with series, data, legend</h1>
+		<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 id="USStates" style="width:900px;height:500px;border:1px solid;">
 		</div>
+		 <table id="productChoice" cellspacing="10" style="border: 1px">
+		        <tr>
+		        <td><label>Show product :</label></td>
+				<td><input type="radio" dojoType="dijit.form.RadioButton" name="product" id="radioA" checked
+			    onchange="changeProduct(this)"
+			    	value="product A" />
+			    <label for="radioA">A</label>
+			    </td>
+			    <td><input type="radio" dojoType="dijit.form.RadioButton" name="product" id="radioB"
+			    onchange="changeProduct(this)"
+			    	value="product B" />
+			    <label for="radioB">B</label>
+			    </td>
+			    <td><input type="radio" dojoType="dijit.form.RadioButton" name="product" id="radioC"
+			    onchange="changeProduct(this)"
+			    	value="product C" />
+			    <label for="radioC">C</label>
+			    </td>
+				</tr>
+			</table>
 	</body>
 </html>
diff --git a/dojox/geo/charting/tests/test_maps.html b/dojox/geo/charting/tests/test_maps.html
index 88d7ab8..dcfeb40 100644
--- a/dojox/geo/charting/tests/test_maps.html
+++ b/dojox/geo/charting/tests/test_maps.html
@@ -1,7 +1,10 @@
 <html>
 	<head>
-		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-		<title>Chart: Map</title>
+		<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";
@@ -9,8 +12,8 @@
 			@import "../resources/Map.css";
 			.mapContainer {
 				display: none;
-				width: 810px;
-				height: 400px;
+				width: 100%;
+				height: 100%;
 				border: solid 1px;
 			}
 			
@@ -21,17 +24,36 @@
 				border: solid 1px;
 			}
 		</style>
-		<script type="text/javascript" djConfig="parseOnLoad:true,gfxRenderer:'svg,vml,silverlight'" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript" djConfig="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);
+		</script>
 		<script type="text/javascript">
 			dojo.require("dojox.geo.charting.Map");
+			dojo.requireIf(isTouchDevice,"dojox.geo.charting.TouchInteractionSupport");
+			dojo.requireIf(!isTouchDevice,"dojox.geo.charting.MouseInteractionSupport");
+			dojo.require("dojox.geo.charting.KeyboardInteractionSupport");
+			
 			dojo.addOnLoad(function(){
-				var USStates = new dojox.geo.charting.Map("USStates", "../resources/data/USStates.json");
-				USStates.setMarkerData("../resources/markers/USStates.json");
+				var map = new dojox.geo.charting.Map("USStates", "../resources/data/USStates.json");
+				map.setMarkerData("../resources/markers/USStates.json");
+				if (!isTouchDevice) {
+					var mouseInteraction = new dojox.geo.charting.MouseInteractionSupport(map,{enablePan:true,enableZoom:true});
+					mouseInteraction.connect();
+				} else {
+					var touchInteraction = new dojox.geo.charting.TouchInteractionSupport(map,{});
+					touchInteraction.connect();
+				}
+				var keyboardInteraction = new dojox.geo.charting.KeyboardInteractionSupport(map, {enableZoom: true});
+        keyboardInteraction.connect();
+				dojo.connect(window,"onresize",this,function(){map.resize(true,true);});
+				
 			});
 		</script>
 	</head>
 	<body class="tundra">
-		<h1>Simple Maps,support zoom in and zoom out.</h1>
+	  <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>
 	</body>
-</html>
+</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
new file mode 100644
index 0000000..b9243c7
--- /dev/null
+++ b/dojox/geo/charting/tests/test_widget.html
@@ -0,0 +1,71 @@
+<html>
+<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" />
+
+<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>
+
+
+</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%; ">
+
+<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>
+</html>
+
diff --git a/dojox/geo/charting/widget/Legend.js b/dojox/geo/charting/widget/Legend.js
index 740bbca..4422caa 100644
--- a/dojox/geo/charting/widget/Legend.js
+++ b/dojox/geo/charting/widget/Legend.js
@@ -1,47 +1,76 @@
-dojo.provide("dojox.geo.charting.widget.Legend");
 
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dojox.lang.functional.array");
-dojo.require("dojox.lang.functional.fold");
+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) {
 
-dojo.declare("dojox.geo.charting.widget.Legend",[dijit._Widget, dijit._Templated], {
-	templateString: "<table dojoAttachPoint='legendNode' class='dojoxLegendNode'><tbody dojoAttachPoint='legendBody'></tbody></table>",
+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,
-	legendNode:null,
 	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;
-		dojo.byId(this.map.container).appendChild(this.domNode);
+		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);  
+ 	},  
+
 	refresh:function(){
+		//	summary:
+		//		Refreshes this legend contents when Map series has changed.		
 		// cleanup
 		while(this.legendBody.lastChild){
-			dojo.destroy(this.legendBody.lastChild);
+			domConstruct.destroy(this.legendBody.lastChild);
 		}
 		
 		if(this.horizontal){
-			dojo.addClass(this.legendNode,"dojoxLegendHorizontal");
-			this._tr = dojo.doc.createElement("tr");
+			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;}
 		
-		dojo.forEach(s,function(x){
+		arr.forEach(s,function(x){
 			this._addLabel(x.color, x.name);
 		},this);
 	},
 	_addLabel:function(color,label){
-		var icon = dojo.doc.createElement("td");
-		var text = dojo.doc.createElement("td");
-		var div = dojo.doc.createElement("div");
-		dojo.addClass(icon, "dojoxLegendIcon");
-		dojo.addClass(text, "dojoxLegendText");
+		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);
@@ -50,7 +79,7 @@ dojo.declare("dojox.geo.charting.widget.Legend",[dijit._Widget, dijit._Templated
 			this._tr.appendChild(icon);
 			this._tr.appendChild(text);
 		}else{
-			var tr = dojo.doc.createElement("tr");
+			var tr = win.doc.createElement("tr");
 			this.legendBody.appendChild(tr);
 			tr.appendChild(icon);
 			tr.appendChild(text);
@@ -60,3 +89,4 @@ dojo.declare("dojox.geo.charting.widget.Legend",[dijit._Widget, dijit._Templated
 		text.innerHTML = String(label);
 	}
 });
+});
diff --git a/dojox/geo/charting/widget/Map.js b/dojox/geo/charting/widget/Map.js
new file mode 100644
index 0000000..c32d6cb
--- /dev/null
+++ b/dojox/geo/charting/widget/Map.js
@@ -0,0 +1,181 @@
+
+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;
+			}
+			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.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
new file mode 100644
index 0000000..b5636e6
--- /dev/null
+++ b/dojox/geo/openlayers/Collection.js
@@ -0,0 +1,27 @@
+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.
+
+				setGeometries : function(/* Array */g) {
+					// summary:
+					// Sets the geometries
+					// g: Array
+					// The array of geometries.
+					this.coordinates = g;
+				},
+
+				// summary:
+				// Retrieves the geometries.
+				// returns: Array
+				// The array of geometries defining this collection.
+				getGeometries : function() {
+					return this.coordinates;
+				}
+			});
+		});
diff --git a/dojox/geo/openlayers/Feature.js b/dojox/geo/openlayers/Feature.js
new file mode 100644
index 0000000..5d0442e
--- /dev/null
+++ b/dojox/geo/openlayers/Feature.js
@@ -0,0 +1,78 @@
+define(["dojo/_base/kernel", "dojo/_base/declare", "dojox/geo/openlayers/Map"], function(dojo, declare, Map){
+
+	return declare("dojox.geo.openlayers.Feature", null, {
+		//	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:
+			//		Construct a new Feature
+			this._layer = null;
+			this._coordSys = dojox.geo.openlayers.EPSG4326;
+		},
+
+		getCoordinateSystem : function(){
+			//	summary:
+			//		Returns the coordinate system in which coordinates of this feature are expressed.
+			//	returns: OpenLayers.Projection
+			//		The coordinate system in which coordinates of this feature are expressed.
+			return this._coordSys;
+		},
+
+		setCoordinateSystem : function(/* OpenLayers.Projection */cs){
+			//	summary:
+			//		Set the coordinate system in which coordinates of this feature are expressed.
+			//	cs: OpenLayers.Projection
+			//		The coordinate system in which coordinates of this feature are expressed.
+			this._coordSys = cs;
+		},
+
+		getLayer : function(){
+			//	summary:
+			//		Returns the Layer to which this feature belongs.
+			//	returns: dojox.geo.openlayers.Layer
+			//		The layer to which this feature belongs.
+			return this._layer;
+		},
+
+		_setLayer : function(/* dojox.geo.openlayers.Layer */l){
+			//	summary:
+			//		Sets the layer to which this Feature belongs
+			//	description:
+			//		Called when the feature is added to the Layer.
+			//	tags:
+			//		private
+			this._layer = l;
+		},
+
+		render : function(){
+		//	summary:
+		//		subclasses implements drawing specific behavior.
+		},
+
+		remove : function(){
+		//	summary:
+		//		Subclasses implements specific behavior.
+		//		Called when removed from the layer.
+		},
+
+		_getLocalXY : function(p){
+			//	summary:
+			//		From projected coordinates to screen coordinates
+			//	p: Object 
+			//		Object with x and y fields
+			//	tags:
+			//		private
+			var x = p.x;
+			var y = p.y;
+			var layer = this.getLayer();
+			var resolution = layer.olLayer.map.getResolution();
+			var extent = layer.olLayer.getExtent();
+			var rx = (x / resolution + (-extent.left / resolution));
+			var ry = ((extent.top / resolution) - y / resolution);
+			return [rx, ry];
+		}
+	});
+});
diff --git a/dojox/geo/openlayers/Geometry.js b/dojox/geo/openlayers/Geometry.js
new file mode 100644
index 0000000..ce91409
--- /dev/null
+++ b/dojox/geo/openlayers/Geometry.js
@@ -0,0 +1,36 @@
+define(["dojo/_base/kernel", "dojo/_base/declare"], function(dojo, declare){
+
+	return declare("dojox.geo.openlayers.Geometry", null, {
+		//	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.
+
+		//	summary:
+		//		The coordinates of the geometry.
+		//		coordinates: {x, y} | Array 
+		coordinates : null,
+
+		//	summary:
+		//		The associated shape when rendered
+		//	shape : dojox.gfx.Shape
+		// 		The shape
+		//	tags:
+		//		internal
+		shape : null,
+
+		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.
+			this.coordinates = coords;
+		}
+	});
+});
diff --git a/dojox/geo/openlayers/GeometryFeature.js b/dojox/geo/openlayers/GeometryFeature.js
new file mode 100644
index 0000000..f0194a6
--- /dev/null
+++ b/dojox/geo/openlayers/GeometryFeature.js
@@ -0,0 +1,404 @@
+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; 
+	=====*/
+	return declare("dojox.geo.openlayers.GeometryFeature", Feature, {
+		//	summary:
+		//		A Feature encapsulating a geometry.
+		//	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:
+		//	|  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:
+			//		Constructs a GeometryFeature for the specified geometry.
+			//	geometry: OpenLayer.Geometry
+			//		The geometry to render.
+			this._geometry = geometry;
+			this._shapeProperties = {};
+			this._fill = null;
+			this._stroke = null;
+		},
+
+		_createCollection : function(/* dojox.geo.openlayers.Geometry */g){
+			//	summary:
+			//		Create collection shape and add it to the viewport.
+			//	tags:
+			//		private
+			var layer = this.getLayer();
+			var s = layer.getSurface();
+			var c = this.createShape(s, g);
+			var vp = layer.getViewport();
+			vp.add(c);
+			return c;
+		},
+
+		_getCollectionShape : function(/* dojox.geo.openlayers.Geometry */g){
+			//	summary:
+			//		Get the collection shape, create it if necessary
+			//	tags:
+			//		private
+			var s = g.shape;
+			if (s == null) {
+				s = this._createCollection(g);
+				g.shape = s;
+			}
+			return s;
+		},
+
+		renderCollection : function(/* undefined | dojox.geo.openlayers.Geometry */g){
+			//	summary:
+			//		Renders a geometry collection.
+			//	g: undefined | dojox.geo.openlayers.Geometry
+			//		The geometry to render.
+			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)
+					this.renderPoint(item);
+				else if (item instanceof LineString)
+					this.renderLineString(item);
+				else if (item instanceof Collection)
+					this.renderCollection(item);
+				else
+					throw new Error();
+			}, this);
+			this._applyStyle(g);
+		},
+
+		render : function(/* undefined || dojox.geo.openlayer.Geometry */g){
+			//	summary:
+			//		Render a geometry. 
+			//		Called by the Layer on which the feature is added. 
+			//	g: undefined || dojox.geo.openlayer.Geometry
+			//		The geometry to draw
+			if (g == undefined)
+				g = this._geometry;
+
+			if (g instanceof Point)
+				this.renderPoint(g);
+			else if (g instanceof LineString)
+				this.renderLineString(g);
+			else if (g instanceof Collection)
+				this.renderCollection(g);
+			else
+				throw new Error();
+		},
+
+		getShapeProperties : function(){
+			//	summary:
+			//		Returns the shape properties. 
+			//	returns: Object
+			//		The shape properties.
+			return this._shapeProperties;
+		},
+
+		setShapeProperties : function(/* Object */s){
+			//	summary:
+			//		Sets the shape properties. 
+			//	s: Object
+			//		The shape properties to set.
+			this._shapeProperties = s;
+			return this;
+		},
+
+		createShape : function(/* Surface */s, /* dojox.geo.openlayers.Geometry */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
+			//		The surface on which the method create the shapes.
+			//	g: dojox.geo.openlayers.Geometry
+			//		The reference geometry 
+			//	returns: dojox.gfx.Shape
+			//		The resulting shape.
+			if (!g)
+				g = this._geometry;
+
+			var shape = null;
+			if (g instanceof Point) {
+				shape = s.createCircle();
+			} else if (g instanceof LineString) {
+				shape = s.createPolyline();
+			} 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
+				throw new Error();
+			return shape;
+		},
+
+		getShape : function(){
+			//	summary:
+			//		Retrieves the shape rendering the geometry
+			//	returns: Shape
+			//		The shape used to render the geometry.
+			var g = this._geometry;
+			if (!g)
+				return null;
+			if (g.shape)
+				return g.shape;
+			this.render();
+			return g.shape;
+		},
+
+		_createPoint : function(/* dojox.geo.openlayer.Geometry */g){
+			//	summary:
+			//		Create a point shape
+			//	tags:
+			//		private
+			var layer = this.getLayer();
+			var s = layer.getSurface();
+			var c = this.createShape(s, g);
+			var vp = layer.getViewport();
+			vp.add(c);
+			return c;
+		},
+
+		_getPointShape : function(/* dojox.geo.openlayers.Geometry */g){
+			//	summary:
+			//		get the point geometry shape, create it if necessary
+			//	tags:
+			//		private
+			var s = g.shape;
+			if (s == null) {
+				s = this._createPoint(g);
+				g.shape = s;
+			}
+			return s;
+		},
+
+		renderPoint : function(/* undefined | dojox.geo.openlayers.Point */g){
+			//	summary:
+			//		Renders a point geometry.
+			//	g: undefined | dojox.geo.openlayers.Point
+			//		The geometry to render.
+			if (g == undefined)
+				g = this._geometry;
+			var layer = this.getLayer();
+			var map = layer.getDojoMap();
+
+			s = this._getPointShape(g);
+			var prop = lang.mixin({}, this._defaults.pointShape);
+			prop = lang.mixin(prop, this.getShapeProperties());
+			s.setShape(prop);
+
+			var from = this.getCoordinateSystem();
+			var p = map.transform(g.coordinates, from);
+
+			var a = this._getLocalXY(p);
+			var cx = a[0];
+			var cy = a[1];
+			var tr = layer.getViewport().getTransform();
+			if (tr)
+				s.setTransform(matrix.translate(cx - tr.dx, cy - tr.dy));
+
+			this._applyStyle(g);
+		},
+
+		_createLineString : function(/* dojox.geo.openlayers.Geometry */g){
+			//	summary:
+			//		Create polyline shape and add it to the viewport.
+			//	tags:
+			//		private
+			var layer = this.getLayer();
+			var s = layer._surface;
+			var shape = this.createShape(s, g);
+			var vp = layer.getViewport();
+			vp.add(shape);
+			g.shape = shape;
+			return shape;
+		},
+
+		_getLineStringShape : function(/* dojox.geo.openlayers.Geometry */g){
+			//	summary:
+			//		Get the line string geometry shape, create it if necessary
+			//	tags:
+			//		private
+			var s = g.shape;
+			if (s == null) {
+				s = this._createLineString(g);
+				g.shape = s;
+			}
+			return s;
+		},
+
+		renderLineString : function(/* undefined | dojox.geo.openlayers.geometry */g){
+			//	summary:
+			//		Renders a line string geometry.
+			//	g: undefined | dojox.geo.openlayers.Geometry
+			//		The geometry to render.
+			if (g == undefined)
+				g = this._geometry;
+			var layer = this.getLayer();
+			var map = layer.getDojoMap();
+			var lss = this._getLineStringShape(g);
+			var from = this.getCoordinateSystem();
+			var points = new Array(g.coordinates.length); // ss.getShape().points;		
+			var tr = layer.getViewport().getTransform();
+			array.forEach(g.coordinates, function(c, i, array){
+				var p = map.transform(c, from);
+				var a = this._getLocalXY(p);
+				if (tr) {
+					a[0] -= tr.dx;
+					a[1] -= tr.dy;
+				}
+				points[i] = {
+					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
+			});
+			lss.setShape(prop);
+			this._applyStyle(g);
+		},
+
+		_applyStyle : function(/* Geometry */g){
+			//	summary:
+			//		Apply the style on the geometry's shape.
+			//	g: dojox.geo.openlayers.Geometry
+			//		The geometry.
+			//	tags:
+			//		private
+			if (!g || !g.shape)
+				return;
+
+			var f = this.getFill();
+
+			var fill;
+			if (!f || lang.isString(f) || lang.isArray(f))
+				fill = f;
+			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))
+				stroke = s;
+			else {
+				stroke = lang.mixin({}, this._defaults.stroke);
+				stroke = lang.mixin(stroke, s);
+			}
+
+			this._applyRecusiveStyle(g, stroke, fill);
+		},
+
+		_applyRecusiveStyle : function(g, stroke, fill){
+			//	summary:
+			//		Apply the style on the geometry's shape recursively.
+			//	g: dojox.geo.openlayers.Geometry
+			//		The geometry.
+			//	stroke: Object
+			//		The stroke
+			//	fill:Object
+			//		The fill
+			//	tags:
+			//		private
+			var shp = g.shape;
+
+			if (shp.setFill)
+				shp.setFill(fill);
+
+			if (shp.setStroke)
+				shp.setStroke(stroke);
+
+			if (g instanceof Collection) {
+				array.forEach(g.coordinates, function(i){
+					this._applyRecusiveStyle(i, stroke, fill);
+				}, this);
+			}
+		},
+
+		setStroke : function(/* Object */s){
+			//	summary:
+			//		Set the stroke style to be applied on the rendered shape.
+			//	s: Object
+			//		The stroke style
+			this._stroke = s;
+			return this;
+		},
+
+		getStroke : function(){
+			//	summary:
+			//		Retrieves the stroke style
+			//	returns: Object
+			//		The stroke style
+			return this._stroke;
+		},
+
+		setFill : function(/* Object */f){
+			//	summary:
+			//		Set the fill style to be applied on the rendered shape.
+			//	f: Object
+			//		The fill style
+			this._fill = f;
+			return this;
+		},
+
+		getFill : function(){
+			//	summary:
+			//		Retrieves the fill style
+			//	returns: Object
+			//		The fill style
+			return this._fill;
+		},
+
+		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)
+				shp.removeShape();
+			if (g instanceof Collection) {
+				array.forEach(g.coordinates, function(i){
+					this.remove(i);
+				}, this);
+			}
+		},
+
+		_defaults : {
+			fill : null,
+			stroke : null,
+			pointShape : {
+				r : 30
+			},
+			lineStringShape : null
+		}
+
+	});
+});
diff --git a/dojox/geo/openlayers/GfxLayer.js b/dojox/geo/openlayers/GfxLayer.js
new file mode 100644
index 0000000..6cb503e
--- /dev/null
+++ b/dojox/geo/openlayers/GfxLayer.js
@@ -0,0 +1,141 @@
+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; 
+	=====*/
+	return declare("dojox.geo.openlayers.GfxLayer", Layer, {
+		//	summary: 
+		//		A layer dedicated to render dojox.geo.openlayers.GeometryFeature
+		//	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:
+		//		private
+		_viewport : null,
+
+		constructor : function(name, options){
+			//	summary:
+			//		Constructs a new GFX layer.
+			var s = dojox.gfx.createSurface(this.olLayer.div, 100, 100);
+			this._surface = s;
+			var vp;
+			if (options && options.viewport)
+				vp = options.viewport;
+			else
+				vp = s.createGroup();
+			this.setViewport(vp);
+			dojo.connect(this.olLayer, "onMapResize", this, "onMapResize");
+			this.olLayer.getDataExtent = this.getDataExtent;
+		},
+
+		getViewport : function(){
+			//	summary:
+			//		Gets the viewport
+			//	tags:
+			//		internal
+			return this._viewport;
+		},
+
+		setViewport : function(g){
+			//	summary:
+			//		Sets the viewport
+			//	g: dojox.gfx.Group
+			//	tags:
+			//		internal
+			if (this._viewport)
+				this._viewport.removeShape();
+			this._viewport = g;
+			this._surface.add(g);
+		},
+
+		onMapResize : function(){
+			//	summary:
+			//		Called when map is resized.
+			//	tag:
+			//	protected
+			this._surfaceSize();
+		},
+
+		setMap : function(map){
+			//	summary:
+			//		Sets the map for this layer.
+			//	tag:
+			//		protected
+			this.inherited(arguments);
+			this._surfaceSize();
+		},
+
+		getDataExtent : function(){
+			//	summary:
+			//		Get data extent
+			//	tags:
+			//		private
+			var ret = this._surface.getDimensions();
+			return ret;
+		},
+
+		getSurface : function(){
+			//	summary:
+			//		Get the underlying dojox.gfx.Surface
+			//	returns: dojox.gfx.Surface 
+			//		The dojox.gfx.Surface this layer uses to draw its GFX rendering.
+			return this._surface;
+		},
+
+		_surfaceSize : function(){
+			//	summary:
+			//		Recomputes the surface size when being resized.
+			//	tags:
+			//		private
+			var s = this.olLayer.map.getSize();
+			this._surface.setDimensions(s.w, s.h);
+		},
+
+		moveTo : function(event){
+			// summary:
+			//   Called when this layer is moved or zoommed.
+			//	event:
+			//		The event
+			var s = dojo.style(this.olLayer.map.layerContainerDiv);
+			var left = parseInt(s.left);
+			var top = parseInt(s.top);
+
+			if (event.zoomChanged || left || top) {
+				var d = this.olLayer.div;
+
+				dojo.style(d, {
+					left : -left + "px",
+					top : -top + "px"
+				});
+
+				if (this._features == null)
+					return;
+				var vp = this.getViewport();
+
+				vp.setTransform(matrix.translate(left, top));
+
+				this.inherited(arguments);
+
+			}
+		},
+
+		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
new file mode 100644
index 0000000..6d25bc8
--- /dev/null
+++ b/dojox/geo/openlayers/GreatCircle.js
@@ -0,0 +1,121 @@
+define(["dojo/_base/lang",
+				"dojox/geo/openlayers/GeometryFeature",
+				"dojox/geo/openlayers/Point",
+				"dojox/geo/openlayers/LineString"], function(lang, GeometryFeature, Point, lineString){
+
+	lang.getObject("geo.openlayers", true, dojox);
+
+	dojox.geo.openlayers.GreatCircle = {
+
+		toPointArray : function(p1, p2, increment){
+			//	summary:
+			//		Create a geodetic line as an array of OpenLayers.Point.
+			//	descritpion:
+			//		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
+			//		The first point of the geodetic line. x and y fields are longitude and
+			//		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
+			//		The value at which a new point is computed. 
+			var startLon = p1.x;
+			var endLon = p2.x;
+			var sl = Math.min(startLon, endLon);
+			var el = Math.max(startLon, endLon);
+
+			var d2r = this.DEG2RAD;
+			var lat1 = p1.y * d2r;
+			var lon1 = p1.x * d2r;
+			var lat2 = p2.y * d2r;
+			var lon2 = p2.x * d2r;
+
+			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) {
+					lat2 += Math.PI / 180000000;
+				}
+			}
+
+			var lon = sl * d2r;
+			var elon = el * d2r;
+			var incr = increment * d2r;
+			var wp = [];
+			var k = 0;
+			var r2d = this.RAD2DEG;
+
+			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
+				};
+				wp[k++] = p;
+				if (lon < elon && (lon + incr) >= elon)
+					lon = elon;
+				else
+					lon = lon + incr;
+			}
+			return wp;
+		},
+
+		toLineString : function(p1, p2, increment){
+			//	summary:
+			//		Create a geodetic line as an array of OpenLayers.Geometry.LineString.
+			//	descritpion:
+			//		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
+			//		The first point of the geodetic line. x and y fields are longitude and
+			//	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
+			//		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:
+			//		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
+			//		ant 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
+			//		The second point of the geodetic line. x and y fields are longitude and
+			//		latitude in decimal degrees.
+			//	increment: Float
+			//		The value at which a new point is computed. 
+			//	returns: GeometryFeature
+			//		The geodetic line as a GeometryFeature
+
+			var ls = this.toLineString(p1, p2, increment);
+			return new GeometryFeature(ls);
+		},
+
+		DEG2RAD : Math.PI / 180,
+
+		RAD2DEG : 180 / Math.PI,
+
+		TOLERANCE : 0.00001
+	};
+
+	return dojox.geo.openlayers.GreatCircle;
+});
diff --git a/dojox/geo/openlayers/JsonImport.js b/dojox/geo/openlayers/JsonImport.js
new file mode 100644
index 0000000..35bbbd3
--- /dev/null
+++ b/dojox/geo/openlayers/JsonImport.js
@@ -0,0 +1,150 @@
+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){
+
+	return declare("dojox.geo.openlayers.JsonImport", null, {
+		//	summary:
+		//		Class to load JSON formated ShapeFile as output of the JSon Custom Map Converter.
+		//	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:
+			//		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>
+			this._params = params;
+		},
+
+		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)
+			});
+		},
+
+		_gotData : function(/* Object */items){
+			//	summary:
+			//		Called when loading is complete.
+			//	tags:
+			//		private
+			var nf = this._params.nextFeature;
+			if (!lang.isFunction(nf))
+				return;
+
+			var extent = items.layerExtent;
+			var ulx = extent[0];
+			var uly = extent[1];
+			var lrx = ulx + extent[2];
+			var lry = uly + extent[3];
+
+			var extentLL = items.layerExtentLL;
+			var x1 = extentLL[0];
+			var y1 = extentLL[1];
+			var x2 = x1 + extentLL[2];
+			var y2 = y1 + extentLL[3];
+
+			var ulxLL = x1;
+			var ulyLL = y2;
+			var lrxLL = x2;
+			var lryLL = y1;
+
+			var features = items.features;
+
+			for ( var f in features) {
+				var o = features[f];
+				var s = o["shape"];
+				var gf = null;
+				if (lang.isArray(s[0])) {
+
+					var a = new Array();
+					array.forEach(s, function(item){
+						var ls = this._makeGeometry(item, ulx, uly, lrx, lry, ulxLL, ulyLL, lrxLL, lryLL);
+						a.push(ls);
+					}, this);
+					var g = new Collection(a);
+					gf = new GeometryFeature(g);
+					nf.call(this, gf);
+
+				} 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))
+				complete.call(this, complete);
+		},
+
+		_makeGeometry : function(/* Array */s, /* Float */ulx, /* Float */uly, /* Float */lrx, /* Float */
+		lry, /* Float */ulxLL, /* Float */ulyLL, /* Float */lrxLL, /* Float */lryLL){
+			//	summary:
+			//		Make a geometry with the specified points.
+			//	tags:
+			//		private
+			var a = [];
+			var k = 0.0;
+			for ( var i = 0; i < s.length - 1; i += 2) {
+				var x = s[i];
+				var y = s[i + 1];
+
+				k = (x - ulx) / (lrx - ulx);
+				var px = k * (lrxLL - ulxLL) + ulxLL;
+
+				k = (y - uly) / (lry - uly);
+				var py = k * (lryLL - ulyLL) + ulyLL;
+
+				a.push({
+					x : px,
+					y : py
+				});
+
+			}
+			var ls = new LineString(a);
+			return ls;
+		},
+
+		_makeFeature : function(/* Array */s, /* Float */ulx, /* Float */uly, /* Float */lrx, /* Float */
+		lry, /* Float */ulxLL, /* Float */ulyLL, /* Float */lrxLL, /* Float */lryLL){
+			//	summary:
+			//		Make a GeometryFeature with the specified points.
+			//	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:
+			//		Called when an error occurs. Calls the error function is provided in the parameters.
+			//	tags:
+			//		private
+			var f = this._params.error;
+			if (lang.isFunction(f))
+				f.apply(this, parameters);
+		}
+	});
+});
diff --git a/dojox/geo/openlayers/Layer.js b/dojox/geo/openlayers/Layer.js
new file mode 100644
index 0000000..f3cdf1f
--- /dev/null
+++ b/dojox/geo/openlayers/Layer.js
@@ -0,0 +1,163 @@
+define(["dojo/_base/kernel", "dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/sniff"],
+	function(dojo, declare, lang, array, sniff){
+
+		return declare("dojox.geo.openlayers.Layer", null, {
+			//	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:
+				//		Constructs a new Layer.
+				//	name: String
+				//		The name of the layer.
+				//	options: Object
+				//		Options passed to the underlying OpenLayers.Layer object.
+
+				var ol = options ? options.olLayer : null;
+
+				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:
+				//		Called when rendering a feature is necessary.
+				//	f : Feature
+				//		The feature to draw.
+				f.render();
+			},
+
+			getDojoMap : function(){
+				return this.dojoMap;
+			},
+
+			addFeature : function(/* Feature | Array */f){
+				//	summary:
+				//		Add a feature or an array of features to the layer.
+				//	f : Feature or Array
+				//		The Feature or array of features to add.
+				if (lang.isArray(f)) {
+					array.forEach(f, function(item){
+						this.addFeature(item);
+					}, this);
+					return;
+				}
+				if (this._features == null)
+					this._features = [];
+				this._features.push(f);
+				f._setLayer(this);
+			},
+
+			removeFeature : function(/* Feature | Array */f){
+				//	summary :
+				//		Removes a feature or an array of features from the layer.
+				//	f : Feature or Array
+				//		The Feature or array of features to remove.
+				var ft = this._features;
+				if (ft == null)
+					return;
+				if (f instanceof Array) {
+					f = f.slice(0);
+					array.forEach(f, function(item){
+						this.removeFeature(item);
+					}, this);
+					return;
+				}
+				var i = array.indexOf(ft, f);
+				if (i != -1)
+					ft.splice(i, 1);
+				f._setLayer(null);
+				f.remove();
+			},
+
+			removeFeatureAt : function(index){
+				//	summary:
+				//		Remove the feature at the specified index.
+				//	description:
+				//		Remove the feature at the specified index.
+				//	index: Number
+				//		The index of the feature to remove.
+				var ft = this._features;
+				var f = ft[index];
+				if (!f)
+					return;
+				ft.splice(index, 1);
+				f._setLayer(null);
+				f.remove();
+			},
+
+			getFeatures : function(){
+				//	summary:
+				//		Retrieves the feature hold by this layer.
+				//	returns: Array
+				//		The untouched array of features hold by this layer.
+				return this._features;
+			},
+
+			getFeatureAt : function(i){
+				//	summary:
+				//		Returns the i-th feature of this layer.
+				//	i : int
+				//		The index of the feature to return.
+				//	returns : ibm_maps.maps.Layer
+				//		The i-th feature of this layer.
+				if (this._features == null)
+					return undefined;
+				return this._features[i];
+			},
+
+			getFeatureCount : function(){
+				//	summary:
+				//		Returns the number of the features contained by this layer.
+				//	returns: int
+				//		The number of the features contained by this layer.
+				if (this._features == null)
+					return 0;
+				return this._features.length;
+			},
+
+			clear : function(){
+				//	summary:
+				//		Removes all the features from this layer.
+				var fa = this.getFeatures();
+				this.removeFeature(fa);
+			},
+
+			moveTo : function(event){
+				//	summary:
+				//		Called when the layer is panned or zoomed.
+				//	event: Object
+				//		The event
+				if (event.zoomChanged) {
+					if (this._features == null)
+						return;
+					array.forEach(this._features, function(f){
+						this.renderFeature(f);
+					}, this);
+				}
+			},
+
+			redraw : function(){
+				//	summary:
+				//		Redraws this layer
+				if (sniff.isIE)
+					setTimeout(lang.hitch(this, function(){
+						this.olLayer.redraw();
+					}, 0));
+				else
+					this.olLayer.redraw();
+			},
+
+			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
new file mode 100644
index 0000000..17cb285
--- /dev/null
+++ b/dojox/geo/openlayers/LineString.js
@@ -0,0 +1,27 @@
+define(["dojo/_base/kernel", "dojo/_base/declare", "dojox/geo/openlayers/Geometry"], function(dojo, declare,
+		/* ===== 
+		var Geometry = dojox.geo.openlayers.Geometry; 
+		=====*/																																															Geometry){
+	return declare("dojox.geo.openlayers.LineString", Geometry, {
+		//	summary:
+		//		The `dojox.geo.openlayers.LineString` geometry. This geometry holds an array
+		//		of coordinates.
+
+		setPoints : function(p){
+			//	summary:
+			//		Sets the points for this geometry.
+			//	p : Array
+			//		An array of {x, y} objects
+			this.coordinates = p;
+		},
+
+		getPoints : function(){
+			//	summary:
+			//		Gets the points of this geometry.
+			//	returns: Array
+			//		The points of this geometry.
+			return this.coordinates;
+		}
+
+	});
+});
diff --git a/dojox/geo/openlayers/Map.js b/dojox/geo/openlayers/Map.js
new file mode 100644
index 0000000..a614a76
--- /dev/null
+++ b/dojox/geo/openlayers/Map.js
@@ -0,0 +1,591 @@
+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"
+	};
+
+	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();
+
+	return declare("dojox.geo.openlayers.Map", null, {
+		//	summary:
+		//		A map viewer based on the OpenLayers library.
+		//
+		//	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
+		//
+		//	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.
+		//
+		//	example:
+		// 
+		//	|	var map = new dojox.geo.openlayers.widget.Map(div, {
+		//	|		baseLayerType : dojox.geo.openlayers.BaseLayerType.OSM,
+		//	|		baseLayerName : 'Open Street Map Layer'
+		//	|	});
+
+		//	summary:
+		//		The underlying OpenLayers.Map object.
+		//		Should be accessed on read mode only.
+		olMap : null,
+
+		_tp : null,
+
+		constructor : function(div, options){
+			//	summary: 
+			//		Constructs a new Map object
+			if (!options)
+				options = {};
+
+			div = html.byId(div);
+
+			this._tp = {
+				x : 0,
+				y : 0
+			};
+
+			var opts = options.openLayersMapOptions;
+
+			if (!opts) {
+				opts = {
+					controls : [new OpenLayers.Control.ScaleLine({
+						maxWidth : 200
+					}), new OpenLayers.Control.Navigation()]
+				};
+			}
+			if (options.accessible) {
+				var kbd = new OpenLayers.Control.KeyboardDefaults();
+				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"
+			});
+
+			var map = new OpenLayers.Map(div, opts);
+			this.olMap = map;
+
+			this._layerDictionary = {
+				olLayers : [],
+				layers : []
+			};
+
+			if (options.touchHandler)
+				this._touchControl = new TouchInteractionSupport(map);
+
+			var base = this._createBaseLayer(options);
+			this.addLayer(base);
+
+			this.initialFit(options);
+		},
+
+		initialFit : function(params){
+			var o = params.initialLocation;
+			if (!o)
+				o = [-160, 70, 160, -70];
+			this.fitTo(o);
+		},
+
+		setBaseLayerType : function(
+		/* dojox.geo.openlayers.Map.BaseLayerType */type){
+			//	summary: 
+			//		Set the base layer type, replacing the existing base layer
+			//	type: dojox.geo.openlayers.BaseLayerType
+			//		base layer type
+			//	returns: OpenLayers.Layer
+			//		The newly created layer.
+			if (type == this.baseLayerType)
+				return null;
+
+			var o = null;
+			if (typeof type == "string") {
+				o = {
+					baseLayerName : type,
+					baseLayerType : type
+				};
+				this.baseLayerType = type;
+			} else if (typeof type == "object") {
+				o = type;
+				this.baseLayerType = o.baseLayerType;
+			}
+			var bl = null;
+			if (o != null) {
+				bl = this._createBaseLayer(o);
+				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) {
+						var proj = olm.getProjectionObject();
+						if (proj != null)
+							oc = oc.transform(proj, dojox.geo.openlayers.EPSG4326);
+					}
+					var old = olm.baseLayer;
+					if (old != null) {
+						var l = this._getLayer(old);
+						this.removeLayer(l);
+					}
+					if (bl != null)
+						this.addLayer(bl);
+					if (recenter) {
+						proj = olm.getProjectionObject();
+						if (proj != null)
+							oc = oc.transform(dojox.geo.openlayers.EPSG4326, proj);
+						olm.setCenter(oc, ob);
+					}
+				}
+			}
+			return bl;
+		},
+
+		getBaseLayerType : function(){
+			//	summary:
+			//		Retrieves the base layer type.
+			//	returns: dojox.geo.openlayers.BaseLayerType
+			//		The current base layer type.
+			return this.baseLayerType;
+		},
+
+		getScale : function(geodesic){
+			//	summary: 
+			//		Returns the current scale
+			//	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 om = this.olMap;
+			if (geodesic) {
+				var units = om.getUnits();
+				if (!units) {
+					return null;
+				}
+				var inches = OpenLayers.INCHES_PER_UNIT;
+				scale = (om.getGeodesicPixelSize().w || 0.000001) * inches["km"] * OpenLayers.DOTS_PER_INCH;
+			} else {
+				scale = om.getScale();
+			}
+			return scale;
+		},
+
+		getOLMap : function(){
+			//	summary:
+			//		gets the underlying OpenLayers map object.
+			//	returns : OpenLayers.Map
+			//		The underlying OpenLayers map object.
+			return this.olMap;
+		},
+
+		_createBaseLayer : function(params){
+			//	summary:
+			//		Creates the base layer.
+			//	tags:
+			//		private
+			var base = null;
+			var type = params.baseLayerType;
+			var url = params.baseLayerUrl;
+			var name = params.baseLayerName;
+			var options = params.baseLayerOptions;
+
+			if (!name)
+				name = type;
+			if (!options)
+				options = {};
+			switch (type) {
+				case dojox.geo.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)
+					});
+				break;
+				case dojox.geo.openlayers.BaseLayerType.WMS:
+					if (!url) {
+						url = "http://labs.metacarta.com/wms/vmap0";
+						if (!options.layers)
+							options.layers = "basic";
+					}
+					base = new Layer(name, {
+						olLayer : new OpenLayers.Layer.WMS(name, url, options, {
+							transitionEffect : "resize"
+						})
+					});
+				break;
+				case dojox.geo.openlayers.BaseLayerType.GOOGLE:
+					base = new Layer(name, {
+						olLayer : new OpenLayers.Layer.Google(name, options)
+					});
+				break;
+				case dojox.geo.openlayers.BaseLayerType.VIRTUAL_EARTH:
+					base = new Layer(name, {
+						olLayer : new OpenLayers.Layer.VirtualEarth(name, options)
+					});
+				break;
+				case dojox.geo.openlayers.BaseLayerType.YAHOO:
+					//				base = new OpenLayers.Layer.Yahoo(name);
+					base = new Layer(name, {
+						olLayer : new OpenLayers.Layer.Yahoo(name, options)
+					});
+				break;
+				case dojox.geo.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, {})
+					});
+
+				break;
+			}
+
+			if (base == null) {
+				if (type instanceof OpenLayers.Layer)
+					base = type;
+				else {
+					options.transitionEffect = "resize";
+					base = new Layer(name, {
+						olLayer : new OpenLayers.Layer.OSM(name, url, options)
+					});
+					this.baseLayerType = dojox.geo.openlayers.BaseLayerType.OSM;
+				}
+			}
+
+			return base;
+		},
+
+		removeLayer : function(/* dojox.geo.openlayers.Layer */layer){
+			//	summary: 
+			//		Remove the specified layer from the map.
+			//	layer: dojox.geo.openlayers.Layer
+			//		The layer to remove from the map.
+			var om = this.olMap;
+			var i = array.indexOf(this._layerDictionary.layers, layer);
+			if (i > 0)
+				this._layerDictionary.layers.splice(i, 1);
+			var oll = layer.olLayer;
+			var j = array.indexOf(this._layerDictionary.olLayers, oll);
+			if (j > 0)
+				this._layerDictionary.olLayers.splice(i, j);
+			om.removeLayer(oll, false);
+		},
+
+		layerIndex : function(/* dojox.geo.openlayers.Layer */layer, index){
+			//	summary:
+			//		Set or retrieve the layer index.
+			//	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
+			//		index of the layer
+			// 	returns: int
+			//		the index of the layer.
+			var olm = this.olMap;
+			if (!index)
+				return olm.getLayerIndex(layer.olLayer);
+			//olm.raiseLayer(layer.olLayer, index);
+			olm.setLayerIndex(layer.olLayer, index);
+
+			this._layerDictionary.layers.sort(function(l1, l2){
+				return olm.getLayerIndex(l1.olLayer) - olm.getLayerIndex(l2.olLayer);
+			});
+			this._layerDictionary.olLayers.sort(function(l1, l2){
+				return olm.getLayerIndex(l1) - olm.getLayerIndex(l2);
+			});
+
+			return index;
+		},
+
+		addLayer : function(/* dojox.geo.openlayers.Layer */layer){
+			//	summary: 
+			//		Add the specified layer to the map.
+			//	layer: dojox.geo.openlayer.Layer
+			//		The layer to add to the map.
+			layer.dojoMap = this;
+			var om = this.olMap;
+			var ol = layer.olLayer;
+			this._layerDictionary.olLayers.push(ol);
+			this._layerDictionary.layers.push(layer);
+			om.addLayer(ol);
+			layer.added();
+		},
+
+		_getLayer : function(/*OpenLayer.Layer */ol){
+			//	summary:
+			//		Retrieve the dojox.geo.openlayer.Layer from the OpenLayer.Layer
+			//	tags:
+			//		private
+			var i = array.indexOf(this._layerDictionary.olLayers, ol);
+			if (i != -1)
+				return this._layerDictionary.layers[i];
+			return null;
+		},
+
+		getLayer : function(property, value){
+			//	summary: 
+			//		Returns the layer whose property matches the value.
+			//	property: String
+			//		The property to check
+			//	value: Object
+			//		The value to match
+			//	returns: dojox.geo.openlayer.Layer | Array
+			//		The layer(s) matching the property's value. Since multiple layers
+			//		match the property's value the return value is an array. 
+			//	example: 
+			//		var layers = map.getLayer("name", "Layer Name");
+			var om = this.olMap;
+			var ols = om.getBy("layers", property, value);
+			var ret = new Array(); //[];
+			array.forEach(ols, function(ol){
+				ret.push(this._getLayer(ol));
+			}, this);
+			return ret;
+		},
+
+		getLayerCount : function(){
+			//	summary: 
+			//		Returns the count of layers of this map.
+			//	returns: int 
+			//		The number of layers of this map. 
+			var om = this.olMap;
+			if (om.layers == null)
+				return 0;
+			return om.layers.length;
+		},
+
+		fitTo : function(o){
+			//	summary: 
+			//		Fits the map on a point,or an area
+			//	description: 
+			//		Fits the map on the point or extent specified as parameter. 
+			//	o: Object
+			//		Object with key values fit parameters or a JSON string.
+			//	example:
+			//		Examples of arguments passed to the fitTo function :
+			//	|	null
+			//		The map is fit on full extent
+			//
+			//	|	{
+			//	|	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
+			//	|	}
+			//		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;
+
+			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")
+				var j = json.fromJson(o);
+			else
+				j = o;
+			var ul;
+			var lr;
+			if (j.hasOwnProperty("bounds")) {
+				var a = j.bounds;
+				b = new OpenLayers.Bounds();
+				ul = this.transformXY(a[0], a[1], from);
+				b.left = ul.x;
+				b.top = ul.y;
+				lr = this.transformXY(a[2], a[3], from);
+				b.right = lr.x;
+				b.bottom = lr.y;
+			}
+			if (b == null) {
+				if (j.hasOwnProperty("position")) {
+					var p = j.position;
+					var e = j.hasOwnProperty("extent") ? j.extent : 1;
+					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;
+					b.top = ul.y;
+					lr = this.transformXY(p[0] + e, p[1] - e, from);
+					b.right = lr.x;
+					b.bottom = lr.y;
+				}
+			}
+			if (b == null) {
+				if (o.length == 4) {
+					b = new OpenLayers.Bounds();
+					// TODO Choose the correct method
+					if (false) {
+						b.left = o[0];
+						b.top = o[1];
+
+						b.right = o[2];
+						b.bottom = o[3];
+					} else {
+						ul = this.transformXY(o[0], o[1], from);
+						b.left = ul.x;
+						b.top = ul.y;
+						lr = this.transformXY(o[2], o[3], from);
+						b.right = lr.x;
+						b.bottom = lr.y;
+					}
+				}
+			}
+			if (b != null) {
+				map.zoomToExtent(b, true);
+			}
+		},
+
+		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:
+			//		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}
+			//		The point to transform
+			//	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
+			//		Transforms the coordinates passed as argument, expressed in the <em>from</em> 
+			//		coordinate system to the map coordinate system.
+			//	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 
+			//		The longitude coordinate to transform.
+			//	y : Number
+			//		The latitude coordinate to transform.
+			//	from: OpenLayers.Projection
+			//		The projection in which the point is expressed.
+
+			var tp = this._tp;
+			tp.x = x;
+			tp.y = y;
+			if (!from)
+				from = dojox.geo.openlayers.EPSG4326;
+			if (!to)
+				to = this.olMap.getProjectionObject();
+			tp = OpenLayers.Projection.transform(tp, from, to);
+			return tp;
+		}
+
+	});
+
+});
diff --git a/dojox/geo/openlayers/Patch.js b/dojox/geo/openlayers/Patch.js
new file mode 100644
index 0000000..5ce22e7
--- /dev/null
+++ b/dojox/geo/openlayers/Patch.js
@@ -0,0 +1,66 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",	// dojo.extend getObject
+	"dojo/_base/sniff",	// dojo.isIE
+	"dojox/gfx",
+	"dojox/gfx/shape"
+], function(dojo, lang, sniff, gfx, shape){
+
+	var dgo = lang.getObject("geo.openlayers", true, dojox);
+
+	dgo.Patch = {
+
+		patchMethod : function(/*Object*/type, /*String*/method, /*Function*/execBefore, /*Function*/
+		execAfter){
+			//	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:
+			//		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:
+			//		private
+			var old = type.prototype[method];
+			type.prototype[method] = function(){
+				var callee = method;
+				if (execBefore)
+					execBefore.call(this, callee, arguments);
+				var ret = old.apply(this, arguments);
+				if (execAfter)
+					ret = execAfter.call(this, callee, ret, arguments) || ret;
+				return ret;
+			};
+		},
+
+		patchGFX : function(){
+
+			var vmlFixRawNodePath = function(){
+				if (!this.rawNode.path)
+					this.rawNode.path = {};
+			};
+
+			var vmlFixFillColors = function() {
+				if(this.rawNode.fill && !this.rawNode.fill.colors)
+					this.rawNode.fill.colors = {};
+			};
+			
+			if (sniff.isIE <= 8) {
+				
+				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);
+			}
+		}
+	};
+	return dgo.Patch;
+});
diff --git a/dojox/geo/openlayers/Point.js b/dojox/geo/openlayers/Point.js
new file mode 100644
index 0000000..4e4652f
--- /dev/null
+++ b/dojox/geo/openlayers/Point.js
@@ -0,0 +1,26 @@
+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.Point", Geometry, {
+		//	summary:
+		//		A Point geometry handles description of points to be rendered in a GfxLayer
+
+		setPoint : function(p){
+			//	summary:
+			//		Sets the point for this geometry.
+			//	p : {x, y} Object
+			//		The point geometry.
+			this.coordinates = p;
+		},
+
+		getPoint : function(){
+			//	summary:
+			//		Gets the point defining this geometry.
+			//	returns: {x, y} Object
+			//		The point defining this geometry.
+			return this.coordinates;
+		}
+	});
+});
diff --git a/dojox/geo/openlayers/TouchInteractionSupport.js b/dojox/geo/openlayers/TouchInteractionSupport.js
new file mode 100644
index 0000000..f973612
--- /dev/null
+++ b/dojox/geo/openlayers/TouchInteractionSupport.js
@@ -0,0 +1,247 @@
+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){
+
+	return declare("dojox.geo.openlayers.TouchInteractionSupport", null, {
+		//	summary: 
+		//		class to handle touch interactions on a OpenLayers.Map widget
+		//	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: 
+			//		Constructs a new TouchInteractionSupport instance
+			//	map: OpenLayers.Map
+			//		the Map widget this class provides touch navigation for.
+			this._map = map;
+			this._centerTouchLocation = new OpenLayers.LonLat(0, 0);
+
+			var div = this._map.div;
+
+			// install touch listeners
+			connect.connect(div, "touchstart", this, this._touchStartHandler);
+			connect.connect(div, "touchmove", this, this._touchMoveHandler);
+			connect.connect(div, "touchend", this, this._touchEndHandler);
+
+			this._tapCount = 0;
+			this._lastTap = {
+				x : 0,
+				y : 0
+			};
+			this._tapThreshold = 100; // square distance in pixels
+
+		},
+
+		_getTouchBarycenter : function(touchEvent){
+			//	summary: 
+			//		returns the midpoint of the two first fingers (or the first finger location if only one)
+			//	touchEvent: Event
+			//		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 marginBox = html.marginBox(this._map.div);
+
+			var middleX = (firstTouch.pageX + secondTouch.pageX) / 2.0 - marginBox.l;
+			var middleY = (firstTouch.pageY + secondTouch.pageY) / 2.0 - marginBox.t;
+
+			return {
+				x : middleX,
+				y : middleY
+			};
+
+		},
+
+		_getFingerSpacing : function(touchEvent){
+			//	summary: 
+			//		computes the distance between the first two fingers
+			//	touchEvent: Event
+			//		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;
+		},
+
+		_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
+			//		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;
+				}
+			}
+			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: Event 
+			//		a touch event
+			//	tags:
+			//		private
+			// perform a basic 2x zoom on touch
+			var touches = touchEvent.touches;
+			var marginBox = html.marginBox(this._map.div);
+			var offX = touches[0].pageX - marginBox.l;
+			var offY = touches[0].pageY - marginBox.t;
+			// clicked map point before zooming
+			var mapPoint = this._map.getLonLatFromPixel(new OpenLayers.Pixel(offX, offY));
+			// zoom increment power
+			this._map.setCenter(new OpenLayers.LonLat(mapPoint.lon, mapPoint.lat), this._map.getZoom() + 1);
+		},
+
+		_touchStartHandler : function(touchEvent){
+			//	summary: 
+			//		action performed on the map when a touch start was triggered 
+			//	touchEvent: Event 
+			// 		a touch event
+			//	tags:
+			//		private
+			event.stop(touchEvent);
+
+			// test double tap
+			if (this._isDoubleTap(touchEvent)) {
+				this._doubleTapHandler(touchEvent);
+				return;
+			}
+
+			// compute map midpoint between fingers		
+			var middlePoint = this._getTouchBarycenter(touchEvent);
+
+			this._centerTouchLocation = this._map.getLonLatFromPixel(new OpenLayers.Pixel(middlePoint.x, middlePoint.y));
+
+			// store initial finger spacing to compute zoom later
+			this._initialFingerSpacing = this._getFingerSpacing(touchEvent);
+
+			// store initial map scale
+			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);
+
+		},
+
+		_touchEndHandler : function(touchEvent){
+			//	summary: 
+			//		action performed on the map when a touch end was triggered 
+			//	touchEvent: Event 
+			//		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);
+
+				this._centerTouchLocation = this._map.getLonLatFromPixel(new OpenLayers.Pixel(middlePoint.x, middlePoint.y));
+			}
+		},
+
+		_touchMoveHandler : function(touchEvent){
+			//	summary: 
+			//		action performed on the map when a touch move was triggered 
+			//	touchEvent: Event
+			//		a touch event
+			//	tags:
+			//		private
+
+			// prevent browser interaction
+			event.stop(touchEvent);
+
+			var middlePoint = this._getTouchBarycenter(touchEvent);
+
+			// compute map offset
+			var mapPoint = this._map.getLonLatFromPixel(new OpenLayers.Pixel(middlePoint.x, middlePoint.y));
+			var mapOffsetLon = mapPoint.lon - this._centerTouchLocation.lon;
+			var mapOffsetLat = mapPoint.lat - this._centerTouchLocation.lat;
+
+			// compute scale factor
+			var scaleFactor = 1;
+			var touches = touchEvent.touches;
+			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...
+				this._map.zoomToScale(this._initialScale / scaleFactor);
+			}
+
+			// adjust map center on barycenter
+			var currentMapCenter = this._map.getCenter();
+			this._map.setCenter(new OpenLayers.LonLat(currentMapCenter.lon - mapOffsetLon, currentMapCenter.lat
+																																											- mapOffsetLat));
+
+		}
+	});
+});
diff --git a/dojox/geo/openlayers/WidgetFeature.js b/dojox/geo/openlayers/WidgetFeature.js
new file mode 100644
index 0000000..18ade13
--- /dev/null
+++ b/dojox/geo/openlayers/WidgetFeature.js
@@ -0,0 +1,205 @@
+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; 
+		=====*/
+		return declare("dojox.geo.openlayers.WidgetFeature", Feature, {
+			//	summary:
+			//		Wraps a Dojo widget, provide geolocalisation of the widget and interface
+			//		to Layer class.
+			//	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:
+				//		Constructs a new `dojox.geo.openlayers.WidgetFeature`
+				//	params: Object
+				//		The parameters describing the widget.
+				this._params = params;
+			},
+
+			setParameters : function(params){
+				//	summary:
+				//		Sets the parameters describing the widget.
+				//	params: Object
+				//		The parameters describing the widget.
+				this._params = params;
+			},
+
+			getParameters : function(){
+				//	summary:
+				//		Retreives the parameters describing the widget.
+				//	returns: Object
+				//		The parameters describing the widget.
+				return this._params;
+			},
+
+			_getWidget : function(){
+				//	summary:
+				//		Creates, if necessary the widget and returns it;
+				//	tags:
+				//		private
+				var params = this._params;
+
+				if ((this._widget == null) && (params != null)) {
+					var w = null;
+
+					if (typeof (params.createWidget) == "function") {
+						w = params.createWidget.call(this);
+					} 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) {
+						w = params.widget;
+					}
+
+					if (w != null) {
+						this._widget = w;
+						if (typeof (w.startup) == "function")
+							w.startup();
+						var n = w.domNode;
+						if (n != null)
+							html.style(n, {
+								position : "absolute"
+							});
+					}
+					this._widget = w;
+				}
+				return this._widget;
+			},
+
+			_getWidgetWidth : function(){
+				//	summary:
+				//		gets the widget width
+				//	tags:
+				//		private
+				var p = this._params;
+				if (p.width)
+					return p.width;
+				var w = this._getWidget();
+				if (w)
+					return html.style(w.domNode, "width");
+				return 10;
+			},
+
+			_getWidgetHeight : function(){
+				//	summary:
+				//		gets the widget height
+				//	tags:
+				//		private
+				var p = this._params;
+				if (p.height)
+					return p.height;
+				var w = this._getWidget();
+				if (w)
+					return html.style(w.domNode, "height");
+				return 10;
+			},
+
+			render : function(){
+				//	summary:
+				//		renders the widget.
+				//	descrption:
+				//		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)
+					return;
+				var params = this._params;
+				var lon = params.longitude;
+				var lat = params.latitude;
+				var from = this.getCoordinateSystem();
+				var map = layer.getDojoMap();
+				var p = map.transformXY(lon, lat, from);
+				var a = this._getLocalXY(p);
+
+				var width = this._getWidgetWidth();
+				var height = this._getWidgetHeight();
+
+				var x = a[0] - width / 2;
+				var y = a[1] - height / 2;
+				var dom = widget.domNode;
+
+				var pa = layer.olLayer.div;
+				if (dom.parentNode != pa) {
+					if (dom.parentNode)
+						dom.parentNode.removeChild(dom);
+					pa.appendChild(dom);
+				}
+				this._updateWidgetPosition({
+					x : x,
+					y : y,
+					width : width,
+					height : height
+				});
+			},
+
+			_updateWidgetPosition : function(box){
+				//	summary:
+				//		Places the widget with the computed x and y values
+				//	tags:
+				//		private
+				//	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"
+				});
+
+				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 (lang.isFunction(w.resize))
+					w.resize({
+						w : box.width,
+						h : box.height
+					});
+			},
+
+			remove : function(){
+				//	summary:
+				//		removes this feature.
+				//	description:
+				//		Remove this feature by disconnecting the widget from the dom.
+				var w = this.getWidget();
+				if (!w)
+					return;
+				var dom = w.domNode;
+				if (dom.parentNode)
+					dom.parentNode.removeChild(dom);
+			}
+		});
+	});
diff --git a/dojox/geo/openlayers/tests/baseLayers/test_baseLayers.html b/dojox/geo/openlayers/tests/baseLayers/test_baseLayers.html
new file mode 100644
index 0000000..47fe9c7
--- /dev/null
+++ b/dojox/geo/openlayers/tests/baseLayers/test_baseLayers.html
@@ -0,0 +1,223 @@
+<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
new file mode 100644
index 0000000..0efb102
--- /dev/null
+++ b/dojox/geo/openlayers/tests/ecr/Ecr.js
@@ -0,0 +1,209 @@
+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
new file mode 100644
index 0000000..841cd37
--- /dev/null
+++ b/dojox/geo/openlayers/tests/ecr/EcrRenderer.js
@@ -0,0 +1,163 @@
+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
new file mode 100644
index 0000000..aec3224
--- /dev/null
+++ b/dojox/geo/openlayers/tests/ecr/LegsRenderer.js
@@ -0,0 +1,66 @@
+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
new file mode 100644
index 0000000..f0a7ccd
--- /dev/null
+++ b/dojox/geo/openlayers/tests/ecr/PortRenderer.js
@@ -0,0 +1,27 @@
+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
new file mode 100644
index 0000000..827818b
--- /dev/null
+++ b/dojox/geo/openlayers/tests/ecr/data/ecr.json
@@ -0,0 +1,41 @@
+{
+	"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
new file mode 100644
index 0000000..839909f
--- /dev/null
+++ b/dojox/geo/openlayers/tests/ecr/data/ecr2.json
@@ -0,0 +1,277 @@
+{
+	"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
new file mode 100644
index 0000000..e909466
--- /dev/null
+++ b/dojox/geo/openlayers/tests/ecr/data/ecr3.json
@@ -0,0 +1,3352 @@
+{
+    "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
new file mode 100644
index 0000000..fdc4bbe
--- /dev/null
+++ b/dojox/geo/openlayers/tests/ecr/data/mapDataFixed.json
@@ -0,0 +1,41467 @@
+{
+   "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
new file mode 100644
index 0000000..548d04c
--- /dev/null
+++ b/dojox/geo/openlayers/tests/ecr/test_ecr.html
@@ -0,0 +1,88 @@
+<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/json/ContinentalEurope.json b/dojox/geo/openlayers/tests/json/ContinentalEurope.json
new file mode 100644
index 0000000..3669b9a
--- /dev/null
+++ b/dojox/geo/openlayers/tests/json/ContinentalEurope.json
@@ -0,0 +1,222 @@
+{
+  "layerExtent":[0.0, 0.0, 4170.268870073072, 2758.4157683894323],
+    "layerExtentLL":[-10.46209716796875, 34.58451461791992, 55.28059387207031, 36.56523513793945],
+    "featureNames":["MCO", "MDA", "MKD", "YUG", "LUX", "VAT", "LTU", "LIE", "LVA", "GBR", "TUR", "UKR", "IRL", "ITA", "GRC", "HUN", "ESP", "SVN", "CHE", "SWE", "ROM", "AUT", "PRT", "AND", "ALB", "SVK", "SMR", "BGR", "BIH", "BEL", "DNK", "BLR", "EST", "FIN", "CZE", "FRA", "DEU", "CYP", "GIB", "HRV", "NLD", "NOR", "POL"],
+    "features":{
+      "MCO":{
+        "shape":[1351, 2065, 1347, 2065, 1347, 2065, 1348, 2064, 1351, 2064, 1352, 2065, 1351, 2065],
+        "center":[1349, 2064],
+        "bbox":[1346.9852627088287, 2063.5793050294146, 4.5789507162537575, 1.676570863937286]
+      },
+      "MDA":{
+        "shape":[2930, 1937, 2923, 1929, 2924, 1914, 2920, 1901, 2916, 1893, 2919, 1881, 2925, 1868, 2929, 1855, 2928, 1838, 2915, 1818, 2905, 1814, 2886, 1805, 2878, 1794, 2872, 1782, 2861, 1776, 2850, 1767, 2850, 1754, 2835, 1736, 2821, 1725, 2801, 1724, 2815, 1712, 2846, 1712, 2870, 1711, 2902, 1721, 2922, 1730, 2942, 1728, 2965, 1730, 2970, 1736, 2985, 1741, 2994, 1748, 2993, 1763, 2991, 1774, 2989, 1781, 2998, 1787, 3011, 1789, 3022, 1796, 3022, 1810, 3024, 1822, 3039, 1824, 3049, 1 [...]
+        "center":[2935, 1805],
+        "bbox":[2800.7090382418633, 1711.3549610942366, 252.77572007857543, 225.64727254281115]
+      },
+      "MKD":{
+        "shape":[2481, 2171, 2485, 2182, 2502, 2189, 2518, 2202, 2527, 2218, 2527, 2234, 2522, 2242, 2518, 2242, 2514, 2243, 2513, 2254, 2510, 2257, 2507, 2253, 2501, 2258, 2498, 2257, 2489, 2258, 2487, 2256, 2482, 2257, 2480, 2256, 2474, 2254, 2470, 2255, 2465, 2257, 2460, 2255, 2458, 2256, 2450, 2259, 2447, 2265, 2441, 2268, 2439, 2271, 2437, 2271, 2433, 2271, 2430, 2272, 2430, 2273, 2424, 2276, 2423, 2276, 2420, 2272, 2413, 2272, 2402, 2276, 2399, 2276, 2397, 2274, 2396, 2274, 2389, 2 [...]
+        "center":[2429, 2227],
+        "bbox":[2335.862068119121, 2169.944862851962, 191.33656348590966, 112.39355814642204]
+      },
+      "YUG":{
+        "shape":[2481, 2171, 2467, 2170, 2457, 2172, 2439, 2177, 2416, 2182, 2401, 2191, 2391, 2191, 2376, 2181, 2361, 2190, 2346, 2198, 2339, 2207, 2339, 2198, 2338, 2191, 2331, 2179, 2316, 2174, 2313, 2168, 2310, 2157, 2299, 2159, 2283, 2159, 2279, 2146, 2267, 2155, 2258, 2165, 2251, 2174, 2252, 2183, 2251, 2200, 2248, 2205, 2237, 2203, 2232, 2193, 2223, 2183, 2209, 2174, 2205, 2169, 2208, 2163, 2200, 2157, 2195, 2162, 2187, 2164, 2165, 2156, 2160, 2150, 2145, 2143, 2131, 2136, 2120, 2 [...]
+        "center":[2322, 2067],
+        "bbox":[2108.3392290459783, 1881.578990863573, 417.0894490577398, 325.41158439078663]
+      },
+      "LUX":{
+        "shape":[1282, 1638, 1271, 1635, 1251, 1635, 1238, 1633, 1236, 1623, 1241, 1614, 1229, 1600, 1235, 1588, 1247, 1581, 1259, 1587, 1261, 1593, 1268, 1603, 1286, 1607, 1300, 1610, 1291, 1615, 1287, 1623, 1282, 1638],
+        "center":[1261, 1612],
+        "bbox":[1229.4446161825535, 1580.5021447831639, 70.35043577484885, 57.21607430150925]
+      },
+      "VAT":{
+        "shape":[1740, 2222, 1740, 2222, 1739, 2222, 1739, 2222, 1740, 2222],
+        "center":[1740, 2222],
+        "bbox":[1739.359752163026, 2222.026762628325, 0.4620210302182386, 0.3450409313181808]
+      },
+      "LTU":{
+        "shape":[2559, 1300, 2561, 1290, 2561, 1278, 2547, 1270, 2532, 1264, 2516, 1263, 2505, 1254, 2507, 1243, 2512, 1230, 2505, 1217, 2494, 1208, 2473, 1207, 2454, 1206, 2432, 1202, 2418, 1197, 2394, 1196, 2389, 1190, 2390, 1183, 2389, 1177, 2385, 1169, 2381, 1162, 2378, 1157, 2375, 1152, 2372, 1148, 2374, 1137, 2384, 1134, 2401, 1129, 2414, 1122, 2433, 1116, 2450, 1112, 2471, 1111, 2492, 1112, 2512, 1116, 2527, 1112, 2537, 1110, 2549, 1110, 2580, 1117, 2597, 1119, 2617, 1121, 2637, 1 [...]
+        "center":[2598, 1192],
+        "bbox":[2372.4479177957082, 1108.2254275671962, 436.03562069677764, 192.83327564920137]
+      },
+      "LIE":{
+        "shape":[1504, 1806, 1505, 1806, 1508, 1802, 1510, 1803, 1510, 1805, 1512, 1806, 1511, 1809, 1513, 1809, 1515, 1811, 1515, 1812, 1515, 1813, 1516, 1814, 1516, 1815, 1514, 1817, 1514, 1817, 1505, 1818, 1506, 1813, 1504, 1806],
+        "center":[1510, 1811],
+        "bbox":[1504.4142164577233, 1801.6388488877067, 11.662253980295873, 16.067281333025676]
+      },
+      "LVA":{
+        "shape":[2374, 1137, 2371, 1132, 2367, 1125, 2367, 1119, 2367, 1110, 2371, 1100, 2374, 1094, 2373, 1088, 2371, 1082, 2380, 1076, 2392, 1069, 2400, 1065, 2402, 1056, 2404, 1047, 2408, 1040, 2416, 1035, 2421, 1027, 2425, 1024, 2440, 1023, 2455, 1020, 2469, 1017, 2480, 1015, 2494, 1013, 2492, 1017, 2491, 1021, 2496, 1025, 2508, 1029, 2515, 1032, 2517, 1036, 2524, 1039, 2535, 1041, 2535, 1048, 2536, 1055, 2537, 1059, 2541, 1063, 2550, 1066, 2559, 1069, 2572, 1070, 2583, 1066, 2592, 1 [...]
+        "center":[2643, 1080],
+        "bbox":[2366.980788843927, 992.7768614750898, 554.6268218935229, 177.38672266384333]
+      },
+      "GBR":{
+        "shape":[[181, 1261, 191, 1256, 203, 1251, 208, 1244, 199, 1246, 195, 1242, 197, 1237, 203, 1236, 210, 1236, 217, 1235, 223, 1231, 225, 1224, 233, 1218, 244, 1216, 250, 1212, 261, 1214, 267, 1211, 278, 1208, 290, 1207, 295, 1204, 306, 1202, 321, 1203, 339, 1209, 347, 1216, 347, 1222, 355, 1229, 364, 1235, 359, 1241, 353, 1247, 358, 1248, 364, 1247, 376, 1248, 380, 1255, 383, 1264, 379, 1268, 375, 1265, 377, 1263, 376, 1259, 368, 1255, 363, 1257, 368, 1258, 371, 1262, 368, 1267, 3 [...]
+        "center":[559, 1278],
+        "bbox":[181.44325579820233, 943.7781714886728, 741.9204855345828, 654.9815019404978]
+      },
+      "TUR":{
+        "shape":[[2749, 2298, 2760, 2291, 2761, 2291, 2767, 2290, 2770, 2285, 2775, 2284, 2774, 2282, 2775, 2280, 2777, 2280, 2778, 2278, 2779, 2279, 2781, 2279, 2780, 2276, 2785, 2275, 2783, 2273, 2785, 2272, 2786, 2269, 2783, 2267, 2784, 2263, 2783, 2263, 2784, 2261, 2783, 2258, 2785, 2252, 2791, 2252, 2800, 2247, 2805, 2247, 2807, 2246, 2809, 2242, 2806, 2236, 2806, 2226, 2801, 2225, 2795, 2220, 2794, 2214, 2789, 2208, 2803, 2204, 2815, 2202, 2828, 2196, 2843, 2193, 2858, 2199, 2864,  [...]
+        "center":[3392, 2439],
+        "bbox":[2747.918639071918, 2192.7621692767334, 1422.3502310011545, 471.4433239406567]
+      },
+      "UKR":{
+        "shape":[3675, 1808, 3657, 1818, 3667, 1807, 3656, 1804, 3640, 1807, 3625, 1809, 3613, 1819, 3603, 1826, 3607, 1819, 3597, 1820, 3590, 1823, 3576, 1829, 3574, 1839, 3565, 1843, 3563, 1836, 3561, 1830, 3552, 1831, 3537, 1836, 3533, 1842, 3526, 1842, 3515, 1838, 3498, 1841, 3483, 1849, 3479, 1853, 3468, 1858, 3459, 1850, 3455, 1841, 3452, 1847, 3455, 1855, 3463, 1862, 3457, 1867, 3445, 1856, 3438, 1860, 3432, 1870, 3422, 1875, 3403, 1881, 3398, 1888, 3398, 1880, 3387, 1878, 3378, 1 [...]
+        "center":[3140, 1689],
+        "bbox":[2468.132602652162, 1412.8134032581268, 1349.3878871755314, 546.5246910338046]
+      },
+      "IRL":{
+        "shape":[244, 1216, 233, 1218, 225, 1224, 223, 1231, 217, 1235, 210, 1236, 203, 1236, 197, 1237, 195, 1242, 199, 1246, 208, 1244, 203, 1251, 191, 1256, 181, 1261, 185, 1269, 194, 1271, 197, 1278, 206, 1282, 218, 1283, 226, 1286, 247, 1277, 246, 1271, 253, 1266, 263, 1264, 287, 1287, 296, 1291, 307, 1290, 314, 1287, 319, 1288, 322, 1290, 324, 1292, 325, 1295, 323, 1297, 312, 1296, 310, 1304, 319, 1307, 320, 1314, 322, 1319, 335, 1326, 335, 1339, 326, 1342, 323, 1347, 335, 1349, 33 [...]
+        "center":[148, 1351],
+        "bbox":[0.0, 1193.306650642314, 339.0298736840829, 293.9207719860856]
+      },
+      "ITA":{
+        "shape":[[1405, 2287, 1414, 2285, 1427, 2285, 1435, 2280, 1445, 2277, 1456, 2271, 1464, 2263, 1468, 2258, 1475, 2260, 1479, 2256, 1486, 2253, 1487, 2258, 1495, 2259, 1497, 2265, 1502, 2263, 1508, 2265, 1508, 2271, 1507, 2279, 1514, 2282, 1516, 2289, 1519, 2297, 1521, 2304, 1520, 2311, 1514, 2320, 1511, 2324, 1510, 2331, 1514, 2337, 1520, 2340, 1518, 2346, 1516, 2355, 1515, 2368, 1512, 2380, 1510, 2390, 1508, 2396, 1508, 2410, 1496, 2409, 1487, 2404, 1478, 2400, 1461, 2398, 1464,  [...]
+        "center":[1753, 2110],
+        "bbox":[1297.4400900463704, 1816.239634319149, 884.1191843715158, 779.7156691425703]
+      },
+      "GRC":{
+        "shape":[[2443, 2481, 2462, 2489, 2493, 2495, 2507, 2503, 2522, 2508, 2533, 2517, 2538, 2522, 2537, 2530, 2558, 2537, 2560, 2546, 2539, 2548, 2524, 2542, 2517, 2536, 2509, 2531, 2501, 2532, 2505, 2548, 2518, 2568, 2528, 2592, 2525, 2599, 2530, 2611, 2535, 2618, 2524, 2613, 2513, 2604, 2509, 2596, 2499, 2592, 2487, 2603, 2485, 2611, 2490, 2619, 2478, 2615, 2478, 2602, 2469, 2589, 2462, 2585, 2462, 2578, 2457, 2569, 2444, 2570, 2440, 2582, 2442, 2591, 2439, 2598, 2433, 2593, 2425,  [...]
+        "center":[2542, 2352],
+        "bbox":[2298.9514655726484, 2215.594439945399, 509.6843053240641, 517.7769396443887]
+      },
+      "HUN":{
+        "shape":[2034, 1854, 2031, 1852, 2026, 1844, 2023, 1835, 2014, 1831, 2002, 1831, 2003, 1823, 2009, 1816, 2023, 1815, 2036, 1816, 2036, 1807, 2035, 1797, 2041, 1789, 2050, 1785, 2049, 1774, 2051, 1766, 2072, 1766, 2083, 1764, 2086, 1757, 2088, 1744, 2110, 1750, 2131, 1756, 2149, 1762, 2169, 1764, 2195, 1759, 2211, 1757, 2212, 1746, 2221, 1742, 2237, 1741, 2250, 1740, 2268, 1741, 2278, 1726, 2299, 1731, 2317, 1731, 2329, 1726, 2338, 1712, 2354, 1705, 2376, 1704, 2392, 1707, 2411, 1 [...]
+        "center":[2259, 1803],
+        "bbox":[2001.6725158150703, 1700.2296213071074, 524.9286971298961, 214.64740218525253]
+      },
+      "ESP":{
+        "shape":[918, 2162, 922, 2160, 934, 2165, 944, 2166, 954, 2169, 963, 2165, 973, 2165, 985, 2172, 996, 2174, 1004, 2170, 1012, 2165, 1023, 2165, 1030, 2171, 1028, 2177, 1019, 2179, 1019, 2187, 1024, 2192, 1024, 2198, 1028, 2203, 1019, 2210, 989, 2228, 970, 2234, 960, 2243, 949, 2251, 924, 2255, 889, 2264, 862, 2272, 853, 2276, 845, 2287, 849, 2292, 852, 2296, 843, 2304, 833, 2302, 821, 2315, 811, 2326, 795, 2337, 786, 2345, 778, 2364, 765, 2382, 760, 2394, 762, 2401, 769, 2407, 77 [...]
+        "center":[502, 2293],
+        "bbox":[87.59053972304365, 2065.1286798202555, 942.6654396653893, 585.192585029064]
+      },
+      "SVN":{
+        "shape":[2002, 1831, 2014, 1831, 2023, 1835, 2026, 1844, 2031, 1852, 2034, 1854, 2028, 1855, 2016, 1861, 1997, 1863, 1977, 1865, 1967, 1872, 1958, 1879, 1950, 1888, 1965, 1892, 1966, 1899, 1956, 1908, 1944, 1914, 1942, 1920, 1938, 1928, 1914, 1924, 1895, 1921, 1885, 1914, 1876, 1914, 1873, 1923, 1867, 1930, 1856, 1931, 1837, 1932, 1838, 1919, 1833, 1914, 1823, 1908, 1831, 1902, 1829, 1895, 1808, 1896, 1802, 1885, 1803, 1875, 1811, 1866, 1826, 1864, 1830, 1855, 1879, 1866, 1901, 1 [...]
+        "center":[1915, 1880],
+        "bbox":[1801.961299566224, 1831.283303815061, 231.78577805236228, 100.504466372872]
+      },
+      "CHE":{
+        "shape":[1504, 1806, 1506, 1813, 1505, 1818, 1514, 1817, 1515, 1817, 1535, 1821, 1536, 1826, 1554, 1833, 1563, 1827, 1572, 1823, 1581, 1824, 1580, 1827, 1579, 1828, 1580, 1830, 1577, 1832, 1579, 1836, 1575, 1841, 1574, 1848, 1581, 1851, 1579, 1857, 1567, 1856, 1562, 1853, 1561, 1849, 1552, 1852, 1548, 1857, 1548, 1865, 1553, 1864, 1556, 1868, 1552, 1871, 1557, 1878, 1547, 1880, 1542, 1870, 1533, 1869, 1521, 1875, 1507, 1873, 1502, 1859, 1490, 1860, 1491, 1872, 1486, 1880, 1474, 1 [...]
+        "center":[1415, 1843],
+        "bbox":[1238.1133738927858, 1758.8037007419707, 342.9771966154101, 151.81311762341943]
+      },
+      "SWE":{
+        "shape":[1630, 908, 1639, 908, 1648, 908, 1666, 923, 1679, 906, 1685, 882, 1683, 870, 1691, 859, 1685, 847, 1710, 849, 1730, 844, 1740, 829, 1732, 816, 1748, 808, 1739, 796, 1734, 785, 1716, 775, 1711, 758, 1733, 758, 1756, 753, 1764, 738, 1753, 729, 1728, 720, 1710, 711, 1710, 689, 1717, 665, 1699, 656, 1700, 639, 1690, 623, 1708, 614, 1698, 603, 1691, 588, 1701, 569, 1755, 536, 1796, 534, 1840, 538, 1858, 525, 1858, 513, 1840, 498, 1817, 494, 1851, 468, 1881, 444, 1878, 423, 18 [...]
+        "center":[2076, 632],
+        "bbox":[1628.6288797888515, 155.2851099806804, 985.4291299493589, 1038.225572371646]
+      },
+      "ROM":{
+        "shape":[2939, 2062, 2918, 2062, 2908, 2060, 2902, 2048, 2890, 2043, 2867, 2044, 2848, 2042, 2821, 2042, 2799, 2047, 2774, 2052, 2755, 2060, 2744, 2069, 2728, 2077, 2713, 2075, 2696, 2069, 2684, 2069, 2676, 2074, 2662, 2077, 2650, 2074, 2635, 2077, 2624, 2082, 2608, 2076, 2581, 2069, 2556, 2066, 2539, 2068, 2523, 2069, 2517, 2055, 2517, 2050, 2527, 2044, 2507, 2039, 2507, 2036, 2499, 2032, 2488, 2028, 2486, 2019, 2492, 2010, 2496, 2002, 2483, 1997, 2473, 2007, 2464, 2017, 2452, 2 [...]
+        "center":[2684, 1920],
+        "bbox":[2315.0088187053984, 1723.7916866395121, 713.6822019006154, 357.8088846467408]
+      },
+      "AUT":{
+        "shape":[1830, 1855, 1817, 1852, 1791, 1851, 1740, 1844, 1742, 1835, 1722, 1834, 1711, 1829, 1718, 1818, 1704, 1817, 1677, 1820, 1661, 1816, 1631, 1822, 1620, 1835, 1601, 1833, 1589, 1827, 1581, 1824, 1572, 1823, 1563, 1827, 1554, 1833, 1536, 1826, 1535, 1821, 1515, 1817, 1505, 1818, 1506, 1813, 1503, 1803, 1509, 1794, 1510, 1785, 1505, 1778, 1513, 1780, 1523, 1780, 1528, 1774, 1542, 1777, 1544, 1784, 1545, 1790, 1553, 1794, 1566, 1800, 1573, 1794, 1574, 1784, 1575, 1783, 1577, 1 [...]
+        "center":[1803, 1779],
+        "bbox":[1503.4819728405375, 1668.900250072106, 584.3759545846531, 197.0281560960966]
+      },
+      "PRT":{
+        "shape":[125, 2203, 132, 2197, 147, 2201, 156, 2197, 171, 2192, 169, 2210, 178, 2216, 195, 2209, 207, 2206, 224, 2216, 233, 2214, 245, 2203, 272, 2203, 287, 2210, 292, 2222, 312, 2230, 304, 2242, 280, 2257, 259, 2277, 262, 2289, 267, 2305, 265, 2330, 267, 2353, 259, 2362, 254, 2376, 243, 2381, 223, 2379, 232, 2389, 234, 2397, 242, 2411, 256, 2424, 248, 2443, 241, 2463, 239, 2475, 250, 2480, 258, 2484, 250, 2496, 239, 2503, 233, 2511, 227, 2525, 229, 2533, 232, 2543, 235, 2555, 22 [...]
+        "center":[182, 2381],
+        "bbox":[73.6048710478089, 2191.913523983608, 238.1265526566595, 382.6040612307711]
+      },
+      "AND":{
+        "shape":[918, 2153, 918, 2161, 918, 2162, 918, 2163, 912, 2165, 908, 2164, 908, 2166, 899, 2165, 899, 2163, 898, 2161, 900, 2161, 900, 2160, 900, 2158, 897, 2158, 900, 2153, 901, 2150, 906, 2149, 918, 2153],
+        "center":[907, 2158],
+        "bbox":[896.7998342866069, 2148.6777945397944, 21.39314026838531, 16.913336660862115]
+      },
+      "ALB":{
+        "shape":[2248, 2205, 2251, 2200, 2252, 2183, 2251, 2174, 2258, 2165, 2267, 2155, 2279, 2146, 2283, 2159, 2299, 2159, 2310, 2157, 2313, 2168, 2316, 2174, 2331, 2179, 2338, 2191, 2339, 2198, 2339, 2207, 2343, 2213, 2344, 2219, 2343, 2228, 2336, 2237, 2340, 2248, 2345, 2260, 2356, 2277, 2376, 2282, 2383, 2290, 2382, 2297, 2377, 2301, 2374, 2305, 2367, 2304, 2363, 2308, 2362, 2313, 2359, 2317, 2358, 2317, 2356, 2320, 2356, 2323, 2354, 2327, 2352, 2332, 2344, 2335, 2335, 2334, 2333, 2 [...]
+        "center":[2302, 2265],
+        "bbox":[2245.4407682783576, 2146.4069705289244, 137.30916811640463, 227.24038896964885]
+      },
+      "SVK":{
+        "shape":[2084, 1694, 2089, 1688, 2101, 1682, 2120, 1682, 2135, 1672, 2147, 1665, 2167, 1664, 2175, 1654, 2190, 1633, 2196, 1626, 2217, 1626, 2220, 1633, 2229, 1639, 2242, 1631, 2252, 1625, 2260, 1627, 2262, 1632, 2279, 1643, 2287, 1653, 2297, 1650, 2314, 1647, 2324, 1643, 2333, 1639, 2358, 1647, 2376, 1639, 2390, 1633, 2407, 1639, 2420, 1635, 2430, 1644, 2439, 1640, 2456, 1650, 2471, 1655, 2511, 1664, 2488, 1667, 2482, 1676, 2480, 1689, 2470, 1700, 2468, 1710, 2470, 1717, 2447, 1 [...]
+        "center":[2288, 1689],
+        "bbox":[2074.9027771611745, 1624.670261731124, 435.66093905159323, 139.46387535013787]
+      },
+      "SMR":{
+        "shape":[1732, 2048, 1734, 2051, 1733, 2053, 1731, 2053, 1726, 2052, 1728, 2049, 1732, 2048],
+        "center":[1730, 2051],
+        "bbox":[1726.2879815175113, 2048.2544804126537, 7.7668742417154135, 4.707118026333774]
+      },
+      "BGR":{
+        "shape":[2795, 2220, 2788, 2219, 2774, 2216, 2766, 2218, 2766, 2220, 2768, 2224, 2771, 2225, 2772, 2229, 2774, 2231, 2772, 2235, 2774, 2238, 2769, 2245, 2762, 2245, 2758, 2247, 2758, 2247, 2752, 2248, 2750, 2248, 2748, 2246, 2739, 2247, 2737, 2248, 2734, 2247, 2726, 2247, 2724, 2250, 2719, 2249, 2709, 2252, 2702, 2252, 2700, 2248, 2698, 2247, 2693, 2244, 2689, 2243, 2678, 2239, 2672, 2240, 2668, 2244, 2664, 2238, 2659, 2238, 2658, 2237, 2656, 2237, 2652, 2233, 2650, 2227, 2649, 2 [...]
+        "center":[2698, 2139],
+        "bbox":[2478.764266277759, 2039.2647108935091, 467.0091594784226, 212.80133248182688]
+      },
+      "BIH":{
+        "shape":[2119, 2125, 2115, 2125, 2121, 2116, 2122, 2109, 2104, 2096, 2080, 2081, 2051, 2063, 2041, 2050, 2035, 2037, 2021, 2034, 2004, 2026, 2003, 2015, 1993, 2000, 1982, 1988, 1981, 1980, 1981, 1966, 1982, 1954, 1991, 1950, 2005, 1959, 2020, 1949, 2041, 1942, 2060, 1939, 2072, 1935, 2086, 1943, 2099, 1939, 2114, 1937, 2122, 1949, 2138, 1948, 2159, 1952, 2180, 1957, 2197, 1960, 2209, 1967, 2212, 1975, 2228, 1974, 2241, 1973, 2255, 1973, 2255, 1982, 2246, 1994, 2233, 2009, 2237, 2 [...]
+        "center":[2134, 2028],
+        "bbox":[1981.2445243131538, 1934.91040500506, 284.29523793189946, 219.80114533702954]
+      },
+      "BEL":{
+        "shape":[1259, 1587, 1247, 1581, 1235, 1588, 1229, 1600, 1241, 1614, 1236, 1623, 1217, 1629, 1205, 1629, 1190, 1618, 1169, 1611, 1157, 1603, 1168, 1584, 1153, 1585, 1139, 1595, 1117, 1597, 1112, 1583, 1112, 1584, 1110, 1584, 1109, 1584, 1108, 1584, 1107, 1584, 1106, 1584, 1106, 1584, 1105, 1584, 1104, 1584, 1104, 1584, 1104, 1584, 1104, 1583, 1103, 1583, 1102, 1583, 1102, 1583, 1101, 1583, 1100, 1583, 1100, 1583, 1100, 1582, 1101, 1582, 1101, 1582, 1101, 1581, 1102, 1581, 1102, 1 [...]
+        "center":[1143, 1550],
+        "bbox":[985.2982108011588, 1485.2086885723545, 292.0107984863207, 143.51832212356908]
+      },
+      "DNK":{
+        "shape":[1400, 1133, 1402, 1122, 1411, 1123, 1416, 1116, 1402, 1113, 1401, 1098, 1418, 1101, 1436, 1104, 1442, 1111, 1449, 1104, 1451, 1098, 1459, 1095, 1464, 1088, 1471, 1082, 1480, 1087, 1476, 1095, 1473, 1103, 1482, 1098, 1491, 1100, 1494, 1107, 1495, 1097, 1489, 1090, 1482, 1078, 1484, 1072, 1494, 1068, 1505, 1070, 1513, 1073, 1524, 1066, 1541, 1065, 1557, 1069, 1568, 1070, 1567, 1080, 1572, 1088, 1557, 1091, 1560, 1096, 1573, 1097, 1571, 1102, 1580, 1108, 1593, 1108, 1600, 1 [...]
+        "center":[1495, 1138],
+        "bbox":[1399.7271000295998, 1065.22855047784, 215.29690792502356, 169.4781197660193]
+      },
+      "BLR":{
+        "shape":[3188, 1431, 3146, 1431, 3128, 1434, 3106, 1454, 3096, 1470, 3099, 1479, 3097, 1487, 3085, 1489, 3065, 1484, 3048, 1480, 3037, 1483, 3028, 1485, 3013, 1490, 3005, 1480, 2993, 1474, 2975, 1478, 2969, 1484, 2965, 1491, 2956, 1485, 2944, 1479, 2930, 1480, 2921, 1474, 2904, 1483, 2886, 1477, 2883, 1486, 2874, 1484, 2866, 1474, 2840, 1477, 2837, 1470, 2835, 1463, 2811, 1462, 2789, 1460, 2770, 1454, 2743, 1447, 2718, 1448, 2685, 1448, 2658, 1450, 2639, 1451, 2635, 1459, 2630, 1 [...]
+        "center":[2901, 1332],
+        "bbox":[2535.899188333537, 1128.94802762077, 723.3065129156371, 362.1260690100753]
+      },
+      "EST":{
+        "shape":[2621, 1002, 2624, 994, 2628, 989, 2629, 982, 2633, 976, 2639, 968, 2635, 961, 2622, 962, 2616, 966, 2616, 971, 2600, 975, 2595, 967, 2588, 965, 2581, 965, 2576, 968, 2569, 961, 2569, 956, 2563, 951, 2557, 946, 2560, 938, 2566, 937, 2576, 936, 2585, 935, 2582, 931, 2568, 932, 2558, 934, 2552, 930, 2552, 925, 2559, 920, 2568, 918, 2566, 915, 2556, 918, 2557, 910, 2558, 906, 2554, 902, 2558, 899, 2569, 899, 2582, 898, 2596, 896, 2605, 895, 2597, 889, 2605, 887, 2609, 890, 2 [...]
+        "center":[2722, 938],
+        "bbox":[2552.2355382827286, 869.3592599617424, 364.421066030312, 159.4630117662349]
+      },
+      "FIN":{
+        "shape":[2345, 156, 2354, 151, 2380, 157, 2386, 152, 2375, 149, 2373, 143, 2391, 134, 2417, 139, 2463, 161, 2474, 183, 2495, 177, 2504, 184, 2520, 184, 2541, 186, 2558, 182, 2577, 179, 2585, 172, 2614, 176, 2627, 184, 2653, 185, 2674, 191, 2689, 186, 2696, 175, 2704, 169, 2720, 170, 2736, 163, 2735, 152, 2734, 136, 2751, 112, 2783, 93, 2790, 89, 2817, 92, 2844, 93, 2859, 88, 2870, 79, 2887, 81, 2895, 79, 2903, 84, 2916, 93, 2942, 101, 2977, 106, 3003, 124, 2966, 144, 2971, 157, 2 [...]
+        "center":[2728, 451],
+        "bbox":[2344.779750271047, 79.0935111001877, 836.987283810839, 771.9731117971821]
+      },
+      "CZE":{
+        "shape":[2084, 1694, 2076, 1693, 2055, 1693, 2033, 1683, 2016, 1690, 1996, 1686, 1978, 1677, 1953, 1672, 1926, 1669, 1920, 1673, 1917, 1686, 1904, 1686, 1899, 1700, 1881, 1694, 1870, 1697, 1861, 1706, 1832, 1692, 1829, 1684, 1787, 1667, 1775, 1657, 1761, 1637, 1744, 1632, 1735, 1618, 1738, 1601, 1722, 1595, 1707, 1592, 1702, 1582, 1691, 1574, 1708, 1571, 1718, 1581, 1731, 1573, 1741, 1570, 1757, 1564, 1771, 1563, 1782, 1560, 1795, 1553, 1823, 1542, 1840, 1535, 1879, 1532, 1874, 1 [...]
+        "center":[1958, 1611],
+        "bbox":[1690.7361754826754, 1516.6108666093774, 527.879027311805, 189.66143149157733]
+      },
+      "FRA":{
+        "shape":[[1500, 2120, 1504, 2127, 1504, 2136, 1502, 2144, 1502, 2151, 1509, 2175, 1507, 2186, 1505, 2193, 1499, 2198, 1495, 2207, 1497, 2212, 1497, 2219, 1493, 2222, 1486, 2225, 1485, 2234, 1479, 2243, 1473, 2238, 1466, 2236, 1455, 2230, 1452, 2225, 1456, 2221, 1446, 2216, 1452, 2211, 1453, 2205, 1442, 2205, 1440, 2201, 1445, 2197, 1444, 2190, 1436, 2187, 1433, 2180, 1442, 2176, 1438, 2170, 1443, 2163, 1449, 2154, 1453, 2150, 1461, 2147, 1469, 2146, 1474, 2142, 1481, 2142, 1488,  [...]
+        "center":[936, 1834],
+        "bbox":[425.84558212474565, 1517.5446929831287, 1083.1002102674815, 725.734461487391]
+      },
+      "DEU":{
+        "shape":[1234, 1538, 1245, 1528, 1257, 1519, 1262, 1503, 1265, 1494, 1260, 1480, 1253, 1470, 1253, 1459, 1264, 1454, 1282, 1451, 1295, 1453, 1306, 1447, 1296, 1442, 1306, 1436, 1316, 1436, 1327, 1431, 1330, 1424, 1329, 1416, 1317, 1416, 1301, 1411, 1297, 1404, 1303, 1399, 1312, 1395, 1329, 1394, 1334, 1380, 1340, 1369, 1340, 1352, 1345, 1352, 1348, 1347, 1345, 1343, 1339, 1339, 1330, 1337, 1331, 1331, 1330, 1325, 1338, 1322, 1352, 1318, 1375, 1320, 1395, 1317, 1395, 1323, 1405, 1 [...]
+        "center":[1573, 1497],
+        "bbox":[1234.4920268705089, 1228.0542005113434, 706.7486130189905, 572.4050630740496]
+      },
+      "CYP":{
+        "shape":[3218, 2722, 3227, 2724, 3232, 2719, 3235, 2715, 3243, 2713, 3259, 2716, 3265, 2712, 3265, 2707, 3263, 2701, 3276, 2700, 3288, 2703, 3305, 2703, 3323, 2701, 3338, 2699, 3345, 2695, 3356, 2691, 3359, 2686, 3369, 2685, 3374, 2681, 3382, 2678, 3392, 2678, 3375, 2686, 3368, 2689, 3360, 2692, 3354, 2699, 3344, 2702, 3340, 2709, 3340, 2715, 3349, 2723, 3350, 2727, 3339, 2727, 3329, 2727, 3321, 2730, 3318, 2737, 3312, 2738, 3303, 2744, 3295, 2746, 3283, 2748, 3276, 2749, 3273, 2 [...]
+        "center":[3304, 2716],
+        "bbox":[3217.6002110680115, 2677.887128745054, 174.45977411301828, 80.52863964437847]
+      },
+      "GIB":{
+        "shape":[380, 2646, 380, 2645, 382, 2635, 389, 2636, 389, 2637, 387, 2644, 380, 2646],
+        "center":[384, 2640],
+        "bbox":[379.7266817378443, 2635.3616253383493, 9.350026496537396, 10.187196804561609]
+      },
+      "HRV":{
+        "shape":[2115, 2125, 2106, 2122, 2099, 2114, 2084, 2107, 2072, 2099, 2064, 2092, 2047, 2089, 2039, 2085, 2030, 2081, 2013, 2081, 1994, 2083, 1990, 2078, 1988, 2071, 1975, 2062, 1964, 2059, 1958, 2053, 1941, 2042, 1927, 2031, 1933, 2027, 1937, 2030, 1944, 2026, 1951, 2031, 1962, 2033, 1972, 2031, 1959, 2024, 1945, 2017, 1934, 2009, 1927, 2006, 1916, 1999, 1913, 1992, 1912, 1984, 1917, 1973, 1909, 1964, 1903, 1959, 1889, 1954, 1880, 1944, 1873, 1946, 1863, 1957, 1857, 1963, 1854, 1 [...]
+        "center":[2022, 1972],
+        "bbox":[1810.8584058827958, 1854.3190306458964, 443.0588871265443, 271.112098778945]
+      },
+      "NLD":{
+        "shape":[1029, 1499, 1048, 1497, 1058, 1495, 1064, 1490, 1072, 1492, 1076, 1496, 1082, 1499, 1093, 1495, 1098, 1488, 1104, 1483, 1111, 1481, 1105, 1473, 1105, 1469, 1098, 1464, 1100, 1459, 1110, 1465, 1121, 1469, 1136, 1471, 1150, 1470, 1148, 1464, 1134, 1467, 1114, 1464, 1103, 1460, 1101, 1453, 1105, 1444, 1110, 1441, 1111, 1435, 1120, 1435, 1127, 1427, 1133, 1415, 1139, 1405, 1144, 1391, 1150, 1370, 1159, 1356, 1164, 1362, 1156, 1371, 1158, 1379, 1172, 1377, 1181, 1381, 1179, 1 [...]
+        "center":[1197, 1435],
+        "bbox":[1029.402855613661, 1335.7947421285858, 311.05019088990343, 202.28578563336646]
+      },
+      "NOR":{
+        "shape":[1154, 704, 1161, 700, 1178, 700, 1176, 698, 1168, 694, 1167, 691, 1184, 694, 1191, 690, 1182, 685, 1171, 683, 1172, 679, 1181, 679, 1186, 683, 1197, 687, 1204, 686, 1193, 683, 1197, 679, 1208, 680, 1216, 679, 1221, 677, 1224, 673, 1221, 666, 1228, 661, 1246, 661, 1260, 661, 1271, 662, 1284, 658, 1262, 658, 1259, 652, 1260, 646, 1285, 643, 1307, 639, 1319, 640, 1323, 643, 1337, 642, 1352, 641, 1347, 635, 1350, 630, 1327, 633, 1312, 634, 1309, 629, 1320, 626, 1309, 623, 13 [...]
+        "center":[2056, 371],
+        "bbox":[1154.3445078127984, 0.0, 1975.0922775988734, 992.3687980550653]
+      },
+      "POL":{
+        "shape":[2516, 1263, 2532, 1264, 2547, 1270, 2561, 1278, 2561, 1290, 2559, 1300, 2566, 1320, 2574, 1336, 2593, 1355, 2597, 1364, 2596, 1377, 2599, 1386, 2586, 1395, 2564, 1398, 2551, 1404, 2540, 1410, 2536, 1423, 2553, 1425, 2573, 1429, 2583, 1438, 2578, 1451, 2570, 1474, 2571, 1482, 2574, 1494, 2592, 1510, 2599, 1521, 2611, 1526, 2610, 1530, 2603, 1533, 2611, 1542, 2607, 1554, 2596, 1561, 2573, 1568, 2544, 1587, 2525, 1604, 2507, 1620, 2505, 1627, 2508, 1642, 2513, 1652, 2519, 1 [...]
+        "center":[2252, 1438],
+        "bbox":[1866.7843177528346, 1232.129079233168, 744.178251803786, 431.9118204083775]
+      }
+    }
+}
diff --git a/dojox/geo/openlayers/tests/json/test_json.html b/dojox/geo/openlayers/tests/json/test_json.html
new file mode 100644
index 0000000..b50eef5
--- /dev/null
+++ b/dojox/geo/openlayers/tests/json/test_json.html
@@ -0,0 +1,76 @@
+<html>
+<head profile="http://www.w3.org/2002/12/namespace">
+
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<meta name="GENERATOR"
+	content="Rational Application Developer Standard Edition for WebSphere Software">
+<meta name="viewport" content="user-scalable=no, width=device-width" />
+
+<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/dijit.css">
+<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/tundra/tundra.css">
+
+<title>JSON Import</title>
+
+<!-- -->
+<script type="text/javascript" src="http://openlayers.org/api/2.10/OpenLayers.js"></script>
+
+<script type="text/javascript" src="../../../../../dojo/dojo.js"></script>
+
+<script type="text/javascript">
+	require([	"dojo/ready",
+						"dojo/_base/lang",
+						"dojox/geo/openlayers/Map",
+						"dojox/geo/openlayers/Layer",
+						"dojox/geo/openlayers/GfxLayer",
+						"dojox/geo/openlayers/JsonImport"], function(ready, lang, Map, Layer, GfxLayer, JsonImport){
+
+		var map;
+
+		ready(function(){
+			var options = {
+				baseLayerName : "TheMap"
+			};
+
+			map = new Map("map", options);
+
+			loadJsonMap();
+
+			map.fitTo([-160, 70, 160, -70]);
+
+		});
+
+		function loadJsonMap(){
+
+			layer = new GfxLayer("GfxLayer");
+			map.addLayer(layer);
+
+			var cmc = new JsonImport({
+				url : 'ContinentalEurope.json',
+				nextFeature : lang.hitch(this, function(f){
+					f.setStroke([	Math.floor(Math.random() * 255),
+												Math.floor(Math.random() * 255),
+												Math.floor(Math.random() * 255)]);
+					var c = [	Math.floor(Math.random() * 255),
+										Math.floor(Math.random() * 255),
+										Math.floor(Math.random() * 255),
+										0.5];
+					f.setFill(c);
+					layer.addFeature(f);
+				}),
+				complete : lang.hitch(this, function(){
+					layer.redraw();
+				})
+			});
+			cmc.loadData();
+		};
+	});
+</script>
+
+</head>
+<body class="tundra">
+</head>
+
+<div id="map" style="background-color: #b5d0d0; width: 100%; height: 100%;"></div>
+
+</body>
+</html>
diff --git a/dojox/geo/openlayers/tests/nonWidget/test_nonWidget.html b/dojox/geo/openlayers/tests/nonWidget/test_nonWidget.html
new file mode 100644
index 0000000..c52e45a
--- /dev/null
+++ b/dojox/geo/openlayers/tests/nonWidget/test_nonWidget.html
@@ -0,0 +1,51 @@
+<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 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>
+
+<!-- hosted version -->
+<script type="text/javascript" src="http://openlayers.org/api/OpenLayers.js"></script>
+
+<script type="text/javascript" src="../../../../../dojo/dojo.js"></script>
+
+<script type="text/javascript">
+	require(["dojo/ready", "dojo/dom", "dojo/_base/html", "dojox/geo/openlayers/Map", "dojo/parser"],
+		function(ready, dom, html, Map){
+
+			var map;
+
+			ready(function(){
+				var options = {
+					baseLayerName : "TheMap",
+					baseLayerType : dojox.geo.openlayers.BaseLayerType.GOOGLE,
+					touchHandler : true
+				};
+
+				var div = dom.byId("map");
+				map = new Map(div, options);
+				map.fitTo([-160, 70, 160, -70]);
+
+			});
+
+		});
+</script>
+
+<style type="text/css">
+.olLayerGoogleCopyright {
+	visibility: hidden;
+}
+</style>
+
+</head>
+<body class="tundra">
+</head>
+
+<div id="map" style="background-color: #b5d0d0; width: 100%; height: 100%;"></div>
+
+</body>
+</html>
diff --git a/dojox/geo/openlayers/tests/sun/Cities.js b/dojox/geo/openlayers/tests/sun/Cities.js
new file mode 100644
index 0000000..5dd82d5
--- /dev/null
+++ b/dojox/geo/openlayers/tests/sun/Cities.js
@@ -0,0 +1,310 @@
+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
new file mode 100644
index 0000000..82aa634
--- /dev/null
+++ b/dojox/geo/openlayers/tests/sun/Sun.js
@@ -0,0 +1,226 @@
+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
new file mode 100644
index 0000000..0e3e29d
--- /dev/null
+++ b/dojox/geo/openlayers/tests/sun/SunDemo.js
@@ -0,0 +1,298 @@
+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
new file mode 100644
index 0000000..7a9a45d
--- /dev/null
+++ b/dojox/geo/openlayers/tests/sun/c.csv
@@ -0,0 +1,340 @@
+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
new file mode 100644
index 0000000..456fcf7
--- /dev/null
+++ b/dojox/geo/openlayers/tests/sun/test_sun.html
@@ -0,0 +1,135 @@
+<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
new file mode 100644
index 0000000..3f80f35
--- /dev/null
+++ b/dojox/geo/openlayers/tests/test_bench.html
@@ -0,0 +1,282 @@
+<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 OpenLayers Benchmarks</title>
+<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">
+	var djConfig = {
+		parseOnLoad : true
+	};
+</script>
+
+<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
+
+<script type="text/javascript">
+
+	require(["dojo/ready", 
+					"dojo/dom",
+					"dojo/_base/array",
+					"dojo/_base/html",
+					"dojox/geo/openlayers/Map", 
+					"dojox/geo/openlayers/Layer", 
+					"dojox/geo/openlayers/GfxLayer", 
+					"dojox/geo/openlayers/Point", 
+					"dojox/geo/openlayers/LineString", 
+					"dojox/geo/openlayers/GeometryFeature", 
+					"dojo/parser"],
+	function(ready, dom, arr, html, Map, Layer, GfxLayer, Point, LineString, GeometryFeature, parser) {
+
+	var map;
+	//	var messageDiv;
+	var Cookies = {
+		init : function(){
+			var allCookies = document.cookie.split('; ');
+			for ( var i = 0; i < allCookies.length; i++) {
+				var cookiePair = allCookies[i].split('=');
+				this[cookiePair[0]] = cookiePair[1];
+			}
+		},
+
+		create : function(name, value, days){
+			var expires = "";
+			if (days) {
+				var date = new Date();
+				date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
+				expires = "; expires=" + date.toGMTString();
+			}
+			document.cookie = name + "=" + value + expires + "; path=/";
+			this[name] = value;
+		},
+
+		erase : function(name){
+			this.create(name, '', -1);
+			this[name] = undefined;
+		}
+	};
+
+	Cookies.init();
+	var numLoad = 4;
+	var numLoadString = "numLoad";
+	var cumulativeTimeString = "cumulativeTime";
+
+	ready(function(){
+		var options = {
+			baseLayerName : "TheLayer",
+			baseLayerType : dojox.geo.openlayers.BaseLayerType.OSM,
+			touchHandler : true
+		};
+
+		if (!Cookies[numLoadString])
+			Cookies.create(numLoadString, numLoad);
+		if (!Cookies[cumulativeTimeString])
+			Cookies.create(cumulativeTimeString, "0");
+		var div = dom.byId("map");
+		map = new Map(div, options);
+		var la = map.getLayer("name", "TheLayer");
+		arr.forEach(la, function(l){
+			var ol = l.olLayer;
+			ol.events.register("loadstart", this, loadStart);
+			ol.events.register("tileloaded", this, tileLoaded);
+			ol.events.register("loadend", this, loadEnd);
+		}, this);
+		map.fitTo([ -160, 70, 160, -70 ]);
+
+	});
+
+	var startDate = null;
+	var numTiles = undefined;
+
+	function loadStart(event){
+		startDate = new Date();
+		numTiles = event.object.numLoadingTiles;
+	}
+
+	function tileLoaded(event){
+		if (!startDate)
+			startDate = new Date();
+		if (!numTiles)
+			numTiles = event.object.numLoadingTiles;
+	}
+
+	function loadEnd(event){
+		var endDate = new Date();
+		var time = endDate.getTime() - startDate.getTime();
+//		console.log("loading " + numTiles + " tiles took " + time + " ms");
+		if (Cookies[cumulativeTimeString]) {
+			var ct = Cookies[cumulativeTimeString];
+			var ict = parseInt(ct) + time;
+			Cookies.create(cumulativeTimeString, ict.toString());
+		}
+		if (Cookies[numLoadString]) {
+			var nl = Cookies[numLoadString];
+			var i = parseInt(nl) - 1;
+			Cookies.create(numLoadString, i.toString());
+			if (i > 0) {
+				window.location.reload();
+			} else {
+				ct = Cookies[cumulativeTimeString];
+				log(numLoad + " load(s) took " + ct + " ms");
+				log(ct / numLoad + " ms for each load");
+				Cookies.erase(numLoadString);
+				Cookies.erase(cumulativeTimeString);
+				benchPoints();
+        benchLines();
+        showLayers();
+			}
+		}
+	}
+  
+  var pointLayer = null;
+	var numPoints = dojo.isIE ? 10 : 1000;
+	function benchPoints(){
+		var layer = new GfxLayer();
+		map.addLayer(layer);
+		var startDate = new Date();
+		for ( var i = 0; i < numPoints; i++) {
+			var x = Math.random() * 360 - 180;
+			var y = Math.random() * 180 - 90;
+			var g = new Point({
+				x : x,
+				y : y
+			});
+			var pf = new GeometryFeature(g).setStroke([ 0, 0, 0 ]).setShapeProperties({
+				r : 10
+			});
+			layer.addFeature(pf);
+		}
+		var endDate = new Date();
+		var time = endDate.getTime() - startDate.getTime();
+		log("creating " + numPoints + " points took " + time + " ms");
+
+		startDate = new Date();
+		layer.redraw();
+		endDate = new Date();
+		time = endDate.getTime() - startDate.getTime();
+		log("redrawing " + numPoints + " points took " + time + " ms");
+
+		var olm = map.getOLMap();
+		var center = olm.getCenter();
+		var zoom = olm.getZoom();
+		startDate = new Date();
+		olm.setCenter(center, zoom + 1);
+		endDate = new Date();
+		time = endDate.getTime() - startDate.getTime();
+		log("zooming " + numPoints + " points took " + time + " ms");
+    olm.setCenter(center, zoom);
+    pointLayer = layer;
+    map.removeLayer(layer);
+	}
+
+var lineLayer = null;
+	var numLines = 100;
+	var numPointsPerLine = 20;
+	function benchLines(){
+		var layer = new GfxLayer();
+		map.addLayer(layer);
+		var startDate = new Date();
+
+		for ( var i = 0; i < numLines; i++) {
+			var x = Math.random() * 360 - 180;
+			var y = Math.random() * 180 - 90;
+			var start = {
+				x : x,
+				y : y
+			};
+			var a = [];
+			a.push(start);
+			for ( var j = 0; j < numPointsPerLine; j++) {
+				var dx = Math.random() * 3 - 1.5;
+				var dy = Math.random() * 3 - 1.5;
+        if(x + dx > -180 && x + dx < 180 && y + dy > -90 && y + dy < 90) {
+          x = x + dx;
+          y = y + dy;
+          var p = {x:x, y:y};
+          a.push(p);
+        }
+      }
+      var g = new LineString(a);
+			var lf = new GeometryFeature(g).setStroke([ 0, 0, 0 ]);
+			layer.addFeature(lf);
+	  }
+
+		var endDate = new Date();
+		var time = endDate.getTime() - startDate.getTime();
+		log("creating " + numLines + " lines took " + time + " ms");
+
+		startDate = new Date();
+		layer.redraw();
+		endDate = new Date();
+		time = endDate.getTime() - startDate.getTime();
+		log("redrawing " + numLines + " lines took " + time + " ms");
+
+		var olm = map.getOLMap();
+		var center = olm.getCenter();
+		var zoom = olm.getZoom();
+		startDate = new Date();
+		olm.setCenter(center, zoom + 1);
+		endDate = new Date();
+		time = endDate.getTime() - startDate.getTime();
+		log("zooming " + numLines + " lines took " + time + " ms");
+    olm.setCenter(center, zoom);
+    lineLayer = layer;
+    map.removeLayer(layer);
+	}
+  
+  function showLayers() {
+    map.addLayer(pointLayer);
+    map.addLayer(lineLayer);
+  }
+  
+  var msgDiv = null;
+  function log(msg) {
+    console.log(msg);
+    if(msgDiv == null) {
+      var layer = new Layer();
+      map.addLayer(layer);
+      
+      var s = layer.olLayer.map.getSize();
+
+      html.style(layer.olLayer.div, {
+          width : s.w.toFixed(),
+          left : "0px",
+          top : "0px",
+          height : s.h.toFixed()
+      });
+      msgDiv = dojo.create("div", {
+        style : {
+          width : "100%",
+          left : "0px",
+          top : "0px",
+          height : "100%",
+          position : "absolute"
+        }
+      }, layer.olLayer.div);
+    }
+    var d = dojo.create("div", {
+    }, msgDiv);
+    d.textContent = msg;
+    d.innerText = msg;
+  }
+  });
+  
+</script>
+
+<style type="text/css">
+.olLayerGoogleCopyright {
+	visibility: hidden;
+}
+</style>
+
+</head>
+<body class="tundra">
+</head>
+
+<div id="map" style="background-color: #b5d0d0; width: 100%; height: 100%;"></div>
+
+</body>
+</html>
diff --git a/dojox/geo/openlayers/tests/test_gfx.html b/dojox/geo/openlayers/tests/test_gfx.html
new file mode 100644
index 0000000..4f9c318
--- /dev/null
+++ b/dojox/geo/openlayers/tests/test_gfx.html
@@ -0,0 +1,165 @@
+<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/OpenLayers.js"></script>
+
+<script type="text/javascript">
+	var djConfig = {
+		isDebug : true,
+		parseOnLoad : true
+	};
+</script>
+
+<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
+
+<script type="text/javascript">
+	require([	"dojo/ready",
+						"dojo/_base/array",
+						"dojo/_base/lang",
+						"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, Map, GfxLayer, Point, LineString, Collection, GeometryFeature){
+
+		ready(function(){
+			var map = dijit.byId("map");
+			var 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_gfx2.html b/dojox/geo/openlayers/tests/test_gfx2.html
new file mode 100644
index 0000000..0d6853b
--- /dev/null
+++ b/dojox/geo/openlayers/tests/test_gfx2.html
@@ -0,0 +1,219 @@
+<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. Random Stars on a Map</title>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<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">
+	var djConfig = {
+		parseOnLoad : true
+	};
+</script>
+
+<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
+
+<script type="text/javascript">
+	require([	"dojo/ready",
+						"dojo/_base/lang",
+						"dojo/_base/array",
+						"dojo/_base/Color",
+						"dojox/geo/openlayers/widget/Map",
+						"dojox/geo/openlayers/GfxLayer",
+						"dojox/geo/openlayers/LineString",
+						"dojox/geo/openlayers/GeometryFeature",
+						"dojox/gfx",
+						"dojox/gfx/move",
+						"dojox/gfx/fx",
+						"dojo/fx",
+						"dojo/colors",
+						"dojo/parser"], function(ready, lang, arr, Color, Map, GfxLayer, LineString, GeometryFeature, gfx, move, fx, colors){
+
+		ready(function(){
+			var map = dijit.byId("map");
+			var layer = new GfxLayer("Stars Layer");
+			map.map.addLayer(layer);
+			var b = layer.olLayer.getExtent();
+
+			var p1 = {
+				x : b.left,
+				y : b.top
+			};
+			var proj = map.map.olMap.getProjectionObject();
+			p1 = map.map.transform(p1, proj, dojox.geo.openlayers.EPSG4326);
+			p1 = lang.mixin({}, p1);
+
+			var p2 = {
+				x : b.right,
+				y : b.bottom
+			};
+			p2 = map.map.transform(p2, proj, dojox.geo.openlayers.EPSG4326);
+			p2 = lang.mixin({}, p2);
+
+			var numPoints = 100;
+			var precision = 10;
+			for ( var i = 0; i < numPoints; i++) {
+				var dx = p2.x - p1.x;
+				var x = Math.random() * dx + p1.x;
+				var dy = p2.y - p1.y;
+				var y = Math.random() * dy + p1.y;
+				var pg = new dojox.geo.openlayers.Point({
+					x : x.toFixed(precision),
+					y : y.toFixed(precision)
+				});
+
+				var pf = new GeometryFeature(pg);
+				pf.createShape = function(/* Surface */s){
+					var status = null;
+					function createText(surface, x, y, text){
+						var t = surface.createText({});
+						t.moveToFront().setFill(new Color([0, 0, 0, 1])).setFont({
+							family : "serif",
+							//      variant : "small-caps",
+							weight : "normal",
+							size : "20pt"
+						}).setShape({
+							x : x,
+							y : y,
+							text : text,
+							align : "start"
+						});
+						t.setFill("red");
+						t.setStroke({
+							color : [0, 0, 0, 0],
+							weight : 0.5
+						});
+						var anim = dojox.gfx.fx.animateFill({
+							shape : t,
+							duration : 2000,
+							color : {
+								end : "transparent"
+							}
+						});
+						dojo.connect(anim, "onEnd", function(){
+							t.removeShape();
+						});
+						anim.play();
+						return t;
+					}
+
+					function showStatus(event, surface, star, text){
+						var mx = event.pageX;
+						var my = event.pageY;
+						if (lang.isArray(text)) {
+							var x = mx + 10;
+							var y = my + 10;
+							var dy = 30;
+							status = surface.createGroup();
+							arr.forEach(text, function(s){
+								var t = createText(surface, x, y, s);
+								y += dy;
+								status.add(t);
+							});
+						} else {
+							status = createText(surface, mx, my, text);
+						}
+						var anim = dojox.gfx.fx.animateFill({
+							shape : status,
+							duration : 3000,
+							color : {
+								end : "transparent"
+							}
+						});
+						dojo.connect(anim, "onEnd", function(){
+							status.removeShape();
+							status = null;
+						});
+						anim.play();
+						return status;
+					}
+					var r1 = Math.floor(Math.random() * 50 + 2);
+					var r2 = Math.floor(Math.random() * 30 + 2);
+					var branches = Math.floor(Math.random() * 10 + 2);
+					var start = Math.random() * Math.PI * 2;
+					var star = makeStarShape(r1, r2, branches, start);
+					var path = s.createPath();
+					path.setShape({
+						path : star
+					});
+					var msg = [	"star r1:" + r1 + " r2:" + r2,
+											"branches: " + branches,
+											"longitude: " + x.toFixed(4),
+											"latitude: " + y.toFixed(4)];
+					path.connect("onmouseenter", function(event){
+
+					});
+					path.connect("onmouseout", function(event){
+
+					});
+					path.connect("onmousemove", function(event){
+						if (!status)
+							status = showStatus(event, s, path, msg);
+					});
+					return path;
+				};
+				var r = Math.floor(Math.random() * 255);
+				var g = Math.floor(Math.random() * 255);
+				var b = Math.floor(Math.random() * 255);
+				var t = 1;
+				var c1 = [r, g, b, t];
+				pf.setStroke(c1);
+				r = Math.floor(Math.random() * 255);
+				g = Math.floor(Math.random() * 255);
+				b = Math.floor(Math.random() * 255);
+				t = Math.random() * 0.75 + 0.25;
+				var c2 = [r, g, b, t];
+				pf.setFill(c2);
+				layer.addFeature(pf);
+			}
+
+			setTimeout(function(){
+				layer.olLayer.redraw();
+			}, 0);
+
+		});
+
+		function makeStarShape(r1, r2, b, start){
+			var precision = 2;
+			var TPI = Math.PI * 2;
+			var di = TPI / b;
+			if (!start)
+				start = Math.PI;
+			var s = null;
+			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(precision) + "," + (c1 * r1).toFixed(precision) + " ";
+				} else {
+					s += "L" + (s1 * r1).toFixed(precision) + "," + (c1 * r1).toFixed(precision) + " ";
+				}
+				s += "L" + (s2 * r2).toFixed(precision) + "," + (c2 * r2).toFixed(precision) + " ";
+			}
+			s += "z";
+			return s;
+		}
+
+	});
+</script>
+
+</head>
+<body class="tundra">
+</head>
+
+<div id="map" dojoType="dojox.geo.openlayers.widget.Map" baseLayerType="ArcGIS"
+	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_resize.html b/dojox/geo/openlayers/tests/test_resize.html
new file mode 100644
index 0000000..b6523b2
--- /dev/null
+++ b/dojox/geo/openlayers/tests/test_resize.html
@@ -0,0 +1,145 @@
+<html>
+<head>
+
+<link rel="stylesheet" type="text/css"
+	href="../../../../dojo/resources/dojo.css" />
+<link rel="stylesheet" type="text/css"
+	href="../../../../dijit/themes/claro/claro.css" />
+
+<script type="text/javascript">
+	var djConfig = {
+		parseOnLoad : true
+	};
+</script>
+
+<!--  Google API -->
+<script src="http://maps.google.com/maps/api/js?v=3&sensor=false"></script>
+
+<!-- Virtual Earth -->
+<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>
+
+<!-- hosted version -->
+<script type="text/javascript"
+	src="http://openlayers.org/api/2.10/OpenLayers.js"></script>
+<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
+<script>
+	require([ "dojo/ready", 
+	        "dojo/_base/array", 
+	        "dojo/_base/connect", 
+	        "dojo/aspect", 
+	        "dijit/registry", 
+	        "dojo/_base/lang",
+			"dojox/geo/openlayers/widget/Map", 
+			"dijit/layout/ContentPane", 
+			"dijit/layout/BorderContainer", 
+			"dojo/parser" ],
+			function(ready, arr, connect, aspect, WidgetRegistry, lang, Map) {
+
+				var maps = [ "osm", "google", "yahoo", "arcGis", "virtualEarth" ];
+
+				ready(function() {
+					arr.forEach(maps, function(map) {
+						var m = WidgetRegistry.byId(map);
+						connect.connect(m.map.olMap, "setCenter", m, update);
+					});
+				});
+
+				var _updating = false;
+
+				function update(center, zoom, dragging, forceZoomChange) {
+					if (dragging)
+						return;
+					if (_updating)
+						return;
+
+					var from = this.map.olMap.getProjectionObject();
+					var to = dojox.geo.openlayers.EPSG4326;
+					var p = {
+						x : center.lon,
+						y : center.lat
+					};
+					OpenLayers.Projection.transform(p, from, to);
+					_updating = true;
+					arr.forEach(maps, function(map) {
+						var m = WidgetRegistry.byId(map);
+						if (m != this) {
+							from = dojox.geo.openlayers.EPSG4326;
+							to = m.map.olMap.getProjectionObject();
+							var c = lang.mixin({}, p);
+							OpenLayers.Projection.transform(c, from, to);
+							m.map.olMap.setCenter(new OpenLayers.LonLat(c.x, c.y));
+						}
+					});
+					_updating = false;
+				}
+			});
+</script>
+
+<style type="text/css">
+.olLayerGoogleCopyright {
+	visibility: hidden;
+}
+</style>
+
+</head>
+<body class="claro">
+	<div data-dojo-type="dijit.layout.BorderContainer" design="headline"
+		style="height: 100%; width: 100%;">
+
+		<div data-dojo-type="dijit.layout.ContentPane" region="top"
+			style="height: 200px;" splitter="true">
+			<div data-dojo-type="dojox.geo.openlayers.widget.Map" baseLayerType="OSM"
+				initialLocation="{
+    position : [7.154126, 43.651748],
+    extent : 0.2 }"
+				id="osm"></div>
+
+		</div>
+
+		<div data-dojo-type="dijit.layout.ContentPane" region="center">
+			<div data-dojo-type="dojox.geo.openlayers.widget.Map"
+				baseLayerType="Google"
+				initialLocation="{
+    position : [7.154126, 43.651748],
+    extent : 0.2 }"
+				id="google"></div>
+		</div>
+
+		<div data-dojo-type="dijit.layout.ContentPane" region="bottom"
+			style="height: 200px;" splitter="true">
+			<div data-dojo-type="dojox.geo.openlayers.widget.Map" baseLayerType="Yahoo"
+				initialLocation="{
+    position : [7.154126, 43.651748],
+    extent : 0.2 }"
+				id="yahoo"></div>
+		</div>
+
+		<div data-dojo-type="dijit.layout.ContentPane" region="left"
+			style="width: 200px;" splitter="true">
+			<div data-dojo-type="dojox.geo.openlayers.widget.Map"
+				baseLayerType="ArcGIS"
+				initialLocation="{
+    position : [7.154126, 43.651748],
+    extent : 0.2 }"
+				id="arcGis"></div>
+		</div>
+
+		<div data-dojo-type="dijit.layout.ContentPane" region="right"
+			style="width: 200px;" splitter="true">
+			<div data-dojo-type="dojox.geo.openlayers.widget.Map"
+				baseLayerType="VirtualEarth"
+				initialLocation="{
+    position : [7.154126, 43.651748],
+    extent : 0.2 }"
+				id="virtualEarth"></div>
+		</div>
+
+	</div>
+</body>
+</html>
+
diff --git a/dojox/geo/openlayers/tests/test_widget.html b/dojox/geo/openlayers/tests/test_widget.html
new file mode 100644
index 0000000..2dd3fd8
--- /dev/null
+++ b/dojox/geo/openlayers/tests/test_widget.html
@@ -0,0 +1,100 @@
+<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>Widget</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>
+
+<!-- hosted version -->
+<script type="text/javascript" src="http://openlayers.org/api/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/ready",
+						"dojo/_base/html",
+						"dojox/geo/openlayers/widget/Map",
+						"dojox/geo/openlayers/WidgetFeature",
+						"dojox/geo/openlayers/Point",
+						"dojox/geo/openlayers/GeometryFeature",
+						"dijit/form/Button",
+						"dojo/parser"], function(ready, html, Map, WidgetFeature, Point, GeometryFeature, Button){
+
+		ready(function(){
+			var map = dijit.byId("map");
+			var ol = map.map.getOLMap();
+
+			var gfx = map.map.getLayer("name", "aGfxLayer")[0];
+			var cannes = ['7 1\' 0" E', '43 33\' 0" N'];
+			var p = {
+				x : dojox.geo.openlayers.parseDMS(cannes[0], true),
+				y : dojox.geo.openlayers.parseDMS(cannes[1], true)
+			};
+			var pg = new dojox.geo.openlayers.Point(p);
+
+			var gf = new dojox.geo.openlayers.GeometryFeature(pg);
+			gf.setStroke({
+				color : "red",
+				width : 5
+			});
+			gf.setShapeProperties({
+				r : 20
+			});
+			gfx.addFeature(gf);
+			gfx.redraw();
+
+			var layer = map.map.getLayer("name", "aLayer")[0];
+			var o = {
+				createWidget : function(){
+					var b = new dijit.form.Button();
+					b.set("label", "A Button at <br/> longitude 7.15 ° <br/> latitude 43.65 °");
+					html.style(b.domNode, {
+						width : 200 + "px",
+						height : 100 + "px"
+					});
+					return b;
+				},
+				longitude : 7.154126,
+				latitude : 43.651748
+			};
+			var widgetFeature = new WidgetFeature(o);
+			layer.addFeature(widgetFeature);
+			layer.redraw();
+
+		});
+	});
+</script>
+
+<style type="text/css">
+.olLayerGoogleCopyright {
+	visibility: hidden;
+}
+</style>
+
+</head>
+<body class="tundra">
+</head>
+
+<div id="map" dojoType="dojox.geo.openlayers.widget.Map" baseLayerType="Google"
+	initialLocation="{
+    position : [7.154126, 43.651748],
+    extent : 0.2 }"
+	style="background-color: #b5d0d0; width: 100%; height: 100%;">
+
+	<div class="layer" id="aGfxLayer" name="aGfxLayer" type="GfxLayer"></div>
+
+	<div class="layer" id="aLayer" name="aLayer" type="Layer"></div>
+
+</div>
+
+</body>
+</html>
diff --git a/dojox/geo/openlayers/tests/widgetFeature/test_widgetFeature.html b/dojox/geo/openlayers/tests/widgetFeature/test_widgetFeature.html
new file mode 100644
index 0000000..ceafa77
--- /dev/null
+++ b/dojox/geo/openlayers/tests/widgetFeature/test_widgetFeature.html
@@ -0,0 +1,350 @@
+<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/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/ready",
+						"dojo/_base/array",
+						"dojo/dom-construct",
+						"dojox/geo/openlayers/widget/Map",
+						"dojox/geo/openlayers/Layer",
+						"dojox/geo/openlayers/WidgetFeature",
+						"dojox/charting/widget/Chart2D",
+						"dojox/charting/themes/PlotKit/blue",
+						"dijit/form/RadioButton",
+						"dojo/parser"], function(ready, arr, domConstruct, Map, Layer, WidgetFeature, Chart2D, blue, RadioButton, parser){
+
+		var map;
+
+		var paris = {
+			x : 2.3488,
+			y : 48.85341
+		};
+
+		var newyork = {
+			x : -74.0059729,
+			y : 40.7142691
+		};
+
+		var nice = {
+			lng : "07�15'44'' E",
+			lat : " 43�42'22''"
+		};
+
+		var sf = {
+			lat : "37� 46' 30'' ",
+			lng : "122� 25' 5S W"
+		};
+
+		ready(function(){
+			var opts = {
+				baseLayerType : dojox.geo.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 dojox.geo.openlayers.Layer();
+			map.map.addLayer(layer);
+			var lo;
+			if (dojo.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 = dojox.geo.openlayers.parseDMS(loc.lng, true);
+
+			var lat = 0;
+			if (loc.hasOwnProperty('y'))
+				lat = loc.y;
+			if (loc.hasOwnProperty('lat'))
+				lat = dojox.geo.openlayers.parseDMS(loc.lat, true);
+			return [lng, lat];
+		}
+
+		function createButton(loc){
+
+			var db = domConstruct.create("div", {}, dojo.body());
+
+			var b = new dijit.form.RadioButton({
+				checked : false
+			}, db);
+			var c = getCoords(loc);
+			var f = {
+				longitude : c[0],
+				latitude : c[1],
+				widget : b,
+				width : 15,
+				height : 15
+			};
+			return new dojox.geo.openlayers.WidgetFeature(f);
+		}
+
+		function createChart(loc, params){
+			var feature = null;
+			var co = getCoords(loc);
+
+			if (params.dijitId) {
+				var descr = {
+					longitude : co[0],
+					latitude : co[1],
+					dijitId : params.dijitId,
+					width : 50,
+					height : 50
+				};
+				feature = new dojox.geo.openlayers.WidgetFeature(descr);
+			} else {
+				var chartSize = 50;
+				var descr = {
+					// location of the widget
+					longitude : co[0],
+					latitude : co[1],
+					// the function which creates the widget
+					createWidget : function(){
+						var div = domConstruct.create("div", {}, dojo.body());
+						var chart = new dojox.charting.widget.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(dojox.charting.themes.PlotKit.blue);
+						c.render();
+						c.theme.plotarea.fill = undefined;
+						return chart;
+					},
+					width : chartSize,
+					height : chartSize
+				};
+				feature = new dojox.geo.openlayers.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
new file mode 100644
index 0000000..8d086e0
--- /dev/null
+++ b/dojox/geo/openlayers/widget/Map.js
@@ -0,0 +1,160 @@
+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; 
+		=====*/
+	return declare("dojox.geo.openlayers.widget.Map", Widget, {
+		//	summary: 
+		//		A widget version of the `dojox.geo.openlayers.Map` component.
+		//	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:
+		//	
+		//	| <div id="map" dojoType="dojox.geo.openlayers.widget.Map" baseLayerType="Google" initialLocation="{
+		//	|   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,
+
+		//	summary:
+		//		The part of the map shown at startup time.
+		//	description:
+		//		initial location 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]
+		//	|	}
+		//		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
+		//	|	}
+		//	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:
+		//		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,
+
+		//	summary:
+		//		The underlying `dojox.geo.openlayers.Map` object.
+		//		This is s readonly member.
+		map : null,
+
+		startup : function(){
+			//	summary:
+			//		Processing after the DOM fragment is added to the document
+			this.inherited(arguments);
+			this.map.initialFit({
+				initialLocation : this.initialLocation
+			});
+		},
+
+		buildRendering : function(){
+			//	summary:
+			//		Construct the UI for this widget, creates the real dojox.geo.openlayers.Map object.		
+			//	tags:
+			//		protected
+			this.inherited(arguments);
+			var div = this.domNode;
+			var map = new Map(div, {
+				baseLayerType : this.baseLayerType,
+				touchHandler : this.touchHandler
+			});
+			this.map = map;
+
+			this._makeLayers();
+		},
+
+		_makeLayers : function(){
+			//	summary:
+			//		Creates layers defined as markup.
+			//	tags:
+			//		private
+			var n = this.domNode;
+			var layers = /* ?? query. */query("> .layer", n);
+			array.forEach(layers, function(l){
+				var type = l.getAttribute("type");
+				var name = l.getAttribute("name");
+				var cls = "dojox.geo.openlayers." + type;
+				var p = dojo.getObject(cls);
+				if (p) {
+					var layer = new p(name, {});
+					if (layer)
+						this.map.addLayer(layer);
+				}
+			}, this);
+		},
+
+		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 }`
+			//	b: undefined | Box | width, height
+			//		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.
+
+			var olm = this.map.getOLMap();
+
+			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 = dojo.mixin({}, b);
+					dojo.marginBox(olm.div, box);
+				break;
+				case 2:
+					// two argument, width, height
+					box = {
+						w : arguments[0],
+						h : arguments[1]
+					};
+					dojo.marginBox(olm.div, box);
+				break;
+			}
+			olm.updateSize();
+		}
+	});
+});
diff --git a/dojox/gesture/Base.js b/dojox/gesture/Base.js
new file mode 100644
index 0000000..65aeed0
--- /dev/null
+++ b/dojox/gesture/Base.js
@@ -0,0 +1,371 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/dom",
+	"dojo/on",
+	"dojo/touch",
+	"dojo/has",
+	"../main"
+], function(kernel, declare, array, lang, dom, on, touch, has, dojox){
+	// module:
+	//		dojox/gesture/Base
+	// summary:
+	//		This module provides an abstract parental class for various gesture implementations.
+	
+/*=====
+	dojox.gesture.Base = {
+		// summary:
+		//		An abstract parental class for various gesture implementations.
+		//
+		//		It's mainly responsible for:
+		//
+		//		1. Binding on() listening handlers for supported gesture events.
+		//
+		//		2. Monitoring underneath events and process different phases - 'press'|'move'|'release'|'cancel'.
+		//
+		//		3. Firing and bubbling gesture events with on() API.
+		//
+		//		A gesture implementation only needs to extend this class and overwrite appropriate phase handlers:
+		//
+		//		- press()|move()|release()|cancel for recognizing and firing gestures
+		//
+		// example:
+		//		1. A typical gesture implementation.
+		//
+		//		Suppose we have dojox/gesture/a which provides 3 gesture events:"a", "a.x", "a.y" to be used as:
+		//		|	dojo.connect(node, dojox.gesture.a, function(e){});
+		//		|	dojo.connect(node, dojox.gesture.a.x, function(e){});
+		//		|	dojo.connect(node, dojox.gesture.a.y, function(e){});
+		//
+		//		The definition of the gesture "a" may look like:
+		//		|	define([..., "./Base"], function(..., Base){
+		//		|		var clz = declare(Base, {
+		//		|			defaultEvent: "a",
+		//		|
+		//		|			subEvents: ["x", "y"],
+		//		|			
+		//		|			press: function(data, e){
+		//		|				this.fire(node, {type: "a.x", ...});
+		//		|			},
+		//		|			move: function(data, e){
+		//		|				this.fire(node, {type: "a.y", ...});
+		//		|			},
+		//		|			release: function(data, e){
+		//		|				this.fire(node, {type: "a", ...});
+		//		|			},
+		//		|			cancel: function(data, e){
+		//		|				// clean up
+		//		|			}
+		//		|		});
+		//		|
+		//		|		// in order to have a default instance for handy use
+		//		|		dojox.gesture.a = new clz();
+		//		|
+		//		|		// so that we can create new instances like
+		//		|		// var mine = new dojox.gesture.a.A({...})
+		//		|		dojox.gesture.a.A = clz;
+		//		|
+		//		|		return dojox.gesture.a;
+		//		|	});
+		//
+		//		2. A gesture can be used in the following ways(taking dojox.gestre.tap for example):
+		//
+		//		A. Used with dojo.connect()
+		//		|	dojo.connect(node, dojox.gesture.tap, function(e){});
+		//		|	dojo.connect(node, dojox.gesture.tap.hold, function(e){});
+		//		|	dojo.connect(node, dojox.gesture.tap.doubletap, function(e){});		
+		//
+		//		B. Used with dojo.on
+		//		|	define(["dojo/on", "dojox/gesture/tap"], function(on, tap){
+		//		|		on(node, tap, function(e){});
+		//		|		on(node, tap.hold, function(e){});
+		//		|		on(node, tap.doubletap, function(e){});
+		//
+		//		C. Used with dojox.gesture.tap directly
+		//		|	dojox.gesture.tap(node, function(e){});
+		//		|	dojox.gesture.tap.hold(node, function(e){});
+		//		|	dojox.gesture.tap.doubletap(node, function(e){});
+		//
+		//		Though there is always a default gesture instance after being required, e.g 
+		//		|	require(["dojox/gesture/tap"], function(){...});
+		//
+		//		It's possible to create a new one with different parameter setting:
+		//		|	var myTap = new dojox.gesture.tap.Tap({holdThreshold: 300});
+		//		|	dojo.connect(node, myTap, function(e){});
+		//		|	dojo.connect(node, myTap.hold, function(e){});
+		//		|	dojo.connect(node, myTap.doubletap, function(e){});
+		//		
+		//		Please refer to dojox/gesture/ for more gesture usages
+	};
+=====*/
+	kernel.experimental("dojox.gesture.Base");
+	
+	lang.getObject("gesture", true, dojox);
+
+	// Declare an internal anonymous class which will only be exported by module return value
+	return declare(/*===== "dojox.gesture.Base", =====*/null, {
+
+		// defaultEvent: [readonly] String
+		//		Default event e.g. 'tap' is a default event of dojox.gesture.tap
+		defaultEvent: " ",
+
+		// subEvents: [readonly] Array
+		//		A list of sub events e.g ['hold', 'doubletap'],
+		//		used by being combined with defaultEvent like 'tap.hold', 'tap.doubletap' etc.
+		subEvents: [],
+
+		// touchOnly: boolean
+		//		Whether the gesture is touch-device only
+		touchOnly : false,
+
+		//	_elements: Array
+		//		List of elements that wraps target node and gesture data
+		_elements: null,
+
+		/*=====
+		// _lock: Dom
+		//		The dom node whose descendants are all locked for processing
+		_lock: null,
+		
+		// _events: [readonly] Array
+		//		The complete list of supported gesture events with full name space
+		//		e.g ['tap', 'tap.hold', 'tap.doubletap']
+		_events: null,
+		=====*/
+
+		constructor: function(args){
+			lang.mixin(this, args);
+			this.init();
+		},
+		init: function(){
+			// summary:
+			//		Initialization works
+			this._elements = [];
+
+			if(!has("touch") && this.touchOnly){
+				console.warn("Gestures:[", this.defaultEvent, "] is only supported on touch devices!");
+				return;
+			}
+
+			// bind on() handlers for various events
+			var evt = this.defaultEvent;
+			this.call = this._handle(evt);
+
+			this._events = [evt];
+			array.forEach(this.subEvents, function(subEvt){
+				this[subEvt] = this._handle(evt + '.' + subEvt);
+				this._events.push(evt + '.' + subEvt);
+			}, this);
+		},
+		_handle: function(/*String*/eventType){
+			// summary:
+			//		Bind listen handler for the given gesture event(e.g. 'tap', 'tap.hold' etc.)
+			//		the returned handle will be used internally by dojo/on
+			var self = this;
+			//called by dojo/on
+			return function(node, listener){
+				// normalize, arguments might be (null, node, listener)
+				var a = arguments;
+				if(a.length > 2){
+					node = a[1];
+					listener = a[2];
+				}
+				var isNode = node && (node.nodeType || node.attachEvent || node.addEventListener);
+				if(!isNode){
+					return on(node, eventType, listener);
+				}else{
+					var onHandle = self._add(node, eventType, listener);
+					// FIXME - users are supposed to explicitly call either
+					// disconnect(signal) or signal.remove() to release resources
+					var signal = {
+						remove: function(){
+							onHandle.remove();
+							self._remove(node, eventType);
+						}
+					};
+					return signal;
+				}
+			}; // dojo/on handle
+		},
+		_add: function(/*Dom*/node, /*String*/type, /*function*/listener){
+			// summary:
+			//		Bind dojo/on handlers for both gesture event(e.g 'tab.hold')
+			//		and underneath 'press'|'move'|'release' events
+			var element = this._getGestureElement(node);
+			if(!element){
+				// the first time listening to the node
+				element = {
+					target: node,
+					data: {},
+					handles: {}
+				};
+
+				var _press = lang.hitch(this, "_process", element, "press");
+				var _move = lang.hitch(this, "_process", element, "move");
+				var _release = lang.hitch(this, "_process", element, "release");
+				var _cancel = lang.hitch(this, "_process", element, "cancel");
+
+				var handles = element.handles;
+				if(this.touchOnly){
+					handles.press = on(node, 'touchstart', _press);
+					handles.move = on(node, 'touchmove', _move);
+					handles.release = on(node, 'touchend', _release);
+					handles.cancel = on(node, 'touchcancel', _cancel);
+				}else{
+					handles.press = touch.press(node, _press);
+					handles.move = touch.move(node, _move);
+					handles.release = touch.release(node, _release);
+					handles.cancel = touch.cancel(node, _cancel);
+				}
+				this._elements.push(element);
+			}
+			// track num of listeners for the gesture event - type
+			// so that we can release element if no more gestures being monitored
+			element.handles[type] = !element.handles[type] ? 1 : ++element.handles[type];
+
+			return on(node, type, listener); //handle
+		},
+		_getGestureElement: function(/*Dom*/node){
+			// summary:
+			//		Obtain a gesture element for the give node
+			var i = 0, element;
+			for(; i < this._elements.length; i++){
+				element = this._elements[i];
+				if(element.target === node){
+					return element;
+				}
+			}
+		},
+		_process: function(element, phase, e){
+			// summary:
+			//		Process and dispatch to appropriate phase handlers.
+			//		Also provides the machinery for managing gesture bubbling.
+			// description:
+			//		1. e._locking is used to make sure only the most inner node
+			//		will be processed for the same gesture, suppose we have:
+			//	|	on(inner, dojox.gesture.tap, func1);
+			//	|	on(outer, dojox.gesture.tap, func2);
+			//		only the inner node will be processed by tap gesture, once matched,
+			//		the 'tap' event will be bubbled up from inner to outer, dojo.StopEvent(e)
+			//		can be used at any level to stop the 'tap' event.
+			//
+			//		2. Once a node starts being processed, all it's descendant nodes will be locked.
+			//		The same gesture won't be processed on its descendant nodes until the lock is released.
+			// element: Object
+			//		Gesture element
+			// phase: String
+			//		Phase of a gesture to be processed, might be 'press'|'move'|'release'|'cancel'
+			// e: Event
+			//		Native event
+			e._locking = e._locking || {};
+			if(e._locking[this.defaultEvent] || this.isLocked(e.currentTarget)){
+				return;
+			}
+			// invoking gesture.press()|move()|release()|cancel()
+			e.preventDefault();
+			e._locking[this.defaultEvent] = true;
+			this[phase](element.data, e);
+		},
+		press: function(data, e){
+			// summary:
+			//		Process the 'press' phase of a gesture
+		},
+		move: function(data, e){
+			// summary:
+			//		Process the 'move' phase of a gesture
+		},
+		release: function(data, e){
+			// summary:
+			//		Process the 'release' phase of a gesture
+		},
+		cancel: function(data, e){
+			// summary:
+			//		Process the 'cancel' phase of a gesture
+		},
+		fire: function(node, event){
+			// summary:
+			//		Fire a gesture event and invoke registered listeners
+			//		a simulated GestureEvent will also be sent along
+			// node: DomNode
+			//		Target node to fire the gesture
+			// event: Object
+			//		An object containing specific gesture info e.g {type: 'tap.hold'|'swipe.left'), ...}
+			//		all these properties will be put into a simulated GestureEvent when fired.
+			//		Note - Default properties in a native Event won't be overwritten, see on.emit() for more details.
+			if(!node || !event){
+				return;
+			}
+			event.bubbles = true;
+			event.cancelable = true;
+			on.emit(node, event.type, event);
+		},
+		_remove: function(/*Dom*/node, /*String*/type){
+			// summary:
+			//		Check and remove underneath handlers if node
+			//		is not being listened for 'this' gesture anymore,
+			//		this happens when user removed all previous on() handlers.
+			var element = this._getGestureElement(node);
+			if(!element || !element.handles){ return; }
+			
+			element.handles[type]--;
+
+			var handles = element.handles;
+			if(!array.some(this._events, function(evt){
+				return handles[evt] > 0;
+			})){
+				// clean up if node is not being listened anymore
+				this._cleanHandles(handles);
+				var i = array.indexOf(this._elements, element);
+				if(i >= 0){
+					this._elements.splice(i, 1);
+				}
+			}
+		},
+		_cleanHandles: function(/*Object*/handles){
+			// summary:
+			//		Clean up on handles
+			for(var x in handles){
+				//remove handles for "press"|"move"|"release"|"cancel"
+				if(handles[x].remove){
+					handles[x].remove();
+				}
+				delete handles[x];
+			}
+		},
+		lock: function(/*Dom*/node){
+			// summary:
+			//		Lock all descendants of the node.
+			// tags:
+			//		protected
+			this._lock = node;
+		},
+		unLock: function(){
+			// summary:
+			//		Release the lock
+			// tags:
+			//		protected
+			this._lock = null;
+		},
+		isLocked: function(node){
+			// summary:
+			//		Check if the node is locked, isLocked(node) means
+			//		whether it's a descendant of the currently locked node.
+			// tags:
+			//		protected
+			if(!this._lock || !node){
+				return false;
+			}
+			return this._lock !== node && dom.isDescendant(node, this._lock);
+		},
+		destroy: function(){
+			// summary:
+			//		Release all handlers and resources
+			array.forEach(this._elements, function(element){
+				this._cleanHandles(element.handles);
+			}, this);
+			this._elements = null;
+		}
+	});
+});
\ No newline at end of file
diff --git a/dojox/gesture/README b/dojox/gesture/README
new file mode 100644
index 0000000..0a70194
--- /dev/null
+++ b/dojox/gesture/README
@@ -0,0 +1,39 @@
+-------------------------------------------------------------------------------
+dojox.gesture
+-------------------------------------------------------------------------------
+Version 1.00
+Release date: 10/01/2011
+-------------------------------------------------------------------------------
+Project state:
+experimental
+-------------------------------------------------------------------------------
+Credits
+	Evan(Wei Huang) (evanhuangwei at gmail.com)
+	Si Qi Zhong (zhongsq at cn.ibm.com)	
+	Eduardo Abe (eabe at us.ibm.com)
+	Qi Ruan (rqruanqi at cn.ibm.com)
+	He Gu Yi (heguyi at cn.ibm.com)
+-------------------------------------------------------------------------------
+Project description
+
+Provide device neutral gestures that can be used on either touch devices or
+desktops, a machinery is also implemented for extending with more 3rd party gestures.
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core
+-------------------------------------------------------------------------------
+Documentation
+
+[TODO]
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/gesture/*
+
+Install into the following directory structure:
+/dojox/gesture/
+-------------------------------------------------------------------------------
\ No newline at end of file
diff --git a/dojox/gesture/swipe.js b/dojox/gesture/swipe.js
new file mode 100644
index 0000000..3b27d08
--- /dev/null
+++ b/dojox/gesture/swipe.js
@@ -0,0 +1,143 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"./Base",
+	"../main"
+], function(kernel, declare, Base, dojox){
+// module:
+//		dojox/gesture/swipe
+
+/*=====
+	dojox.gesture.swipe = {
+		// summary:
+		//		This module provides swipe gestures including:
+		//
+		//		1. 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).
+		//
+		//		2. 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.
+		//
+		//		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)
+		//
+		// example:
+		//		A. Used with dojo.connect()
+		//		|	dojo.connect(node, dojox.gesture.swipe, function(e){});
+		//		|	dojo.connect(node, dojox.gesture.swipe.end, function(e){});
+		//
+		//		B. Used with dojo.on
+		//		|	define(['dojo/on', 'dojox/gesture/swipe'], function(on, swipe){
+		//		|		on(node, swipe, function(e){});
+		//		|		on(node, swipe.end, function(e){});
+		//
+		//		C. Used with dojox.gesture.swipe.* directly
+		//		|	dojox.gesture.swipe(node, function(e){});
+		//		|	dojox.gesture.swipe.end(node, function(e){});
+	};
+=====*/
+
+kernel.experimental("dojox.gesture.swipe");
+
+// Declare an internal anonymous class which will only be exported
+// by module return value e.g. dojox.gesture.swipe.Swipe
+var clz = declare(/*===== "dojox.gesture.swipe", =====*/Base, {
+
+	// defaultEvent: [readonly] String
+	//		Default event - 'swipe'
+	defaultEvent: "swipe",
+
+	// subEvents: [readonly] Array
+	//		List of sub events, used by 
+	//		being combined with defaultEvent as 'swipe.end'
+	subEvents: ["end"],
+
+	press: function(/*Object*/data, /*Event*/e){
+		// summary:
+		//		Overwritten, set initial swipe info
+		if(e.touches && e.touches.length >= 2){
+			//currently only support single-touch swipe
+			delete data.context;
+			return;
+		}
+		if(!data.context){
+			data.context = {x: 0, y: 0, t: 0};
+		}
+		data.context.x = e.screenX;
+		data.context.y = e.screenY;
+		data.context.t = new Date().getTime();
+		this.lock(e.currentTarget);
+	},
+	move: function(/*Object*/data, /*Event*/e){
+		// summary:
+		//		Overwritten, fire matched 'swipe' during touchmove
+		this._recognize(data, e, "swipe");
+	},
+	release: function(/*Object*/data, /*Event*/e){
+		// summary:
+		//		Overwritten, fire matched 'swipe.end' when touchend
+		this._recognize(data, e, "swipe.end");		
+		delete data.context;
+		this.unLock();
+	},
+	cancel: function(data, e){
+		// summary:
+		//		Overwritten
+		delete data.context;
+		this.unLock();
+	},
+	_recognize: function(/*Object*/data, /*Event*/e, /*String*/type){
+		// summary:
+		//		Recognize and fire appropriate gesture events
+		if(!data.context){
+			return;
+		}
+		var info = this._getSwipeInfo(data, e);
+		if(!info){
+			// no swipe happened
+			return;
+		}
+		info.type = type;
+		this.fire(e.target, info);
+	},
+	_getSwipeInfo: function(/*Object*/data, /*Event*/e){
+		// summary:
+		//		Calculate swipe information - time, dx and dy
+		var dx, dy, info = {}, startData = data.context;
+		
+		info.time = new Date().getTime() - startData.t;
+		
+		dx = e.screenX - startData.x;
+		dy = e.screenY - startData.y;
+		
+		if(dx === 0 && dy === 0){
+			// no swipes happened
+			return null;
+		}
+		info.dx = dx;
+		info.dy = dy;
+		return info;
+	}
+});
+
+// the default swipe instance for handy use
+dojox.gesture.swipe = new clz();
+// Class for creating a new Swipe instance
+dojox.gesture.swipe.Swipe = clz;
+
+return dojox.gesture.swipe;
+
+});
\ No newline at end of file
diff --git a/dojox/gesture/tap.js b/dojox/gesture/tap.js
new file mode 100644
index 0000000..a130dd6
--- /dev/null
+++ b/dojox/gesture/tap.js
@@ -0,0 +1,144 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"./Base",
+	"../main"
+], function(kernel, declare, lang, Base, dojox){
+// module:
+//		dojox/gesture/tap
+	
+/*=====
+	dojox.gesture.tap = {
+		// summary:
+		//		This module provides tap gesture event handlers:
+		//
+		//		1. dojox.gesture.tap: 'tap' event
+		//
+		//		2. dojox.gesture.tap.hold: 'tap.hold' event
+		//
+		//		3. dojox.gesture.tap.doubletap: 'tap.doubletap' event
+		//
+		// example:
+		//		A. Used with dojo.connect()
+		//		|	dojo.connect(node, dojox.gesture.tap, function(e){});
+		//		|	dojo.connect(node, dojox.gesture.tap.hold, function(e){});
+		//		|	dojo.connect(node, dojox.gesture.tap.doubletap, function(e){});
+		//
+		//		B. Used with dojo.on
+		//		|	define(['dojo/on', 'dojox/gesture/tap'], function(on, tap){
+		//		|		on(node, tap, function(e){});
+		//		|		on(node, tap.hold, function(e){});
+		//		|		on(node, tap.doubletap, function(e){});
+		//
+		//		C. Used with dojox.gesture.tap.* directly
+		//		|	dojox.gesture.tap(node, function(e){});
+		//		|	dojox.gesture.tap.hold(node, function(e){});
+		//		|	dojox.gesture.tap.doubletap(node, function(e){});
+		//
+		//		Though there is always a default gesture instance after being required, e.g
+		//		|	require(['dojox/gesture/tap'], function(){...});
+		//
+		//		It's possible to create a new one with different parameter setting:
+		//		|	var myTap = new dojox.gesture.tap.Tap({holdThreshold: 300});
+		//		|	dojo.connect(node, myTap, function(e){});
+		//		|	dojo.connect(node, myTap.hold, function(e){});
+		//		|	dojo.connect(node, myTap.doubletap, function(e){});
+	};
+=====*/
+
+kernel.experimental("dojox.gesture.tap");
+
+// Declare an internal anonymous class which will only be exported
+// by module return value e.g. dojox.gesture.tap.Tap
+var clz = declare(/*===== "dojox.gesture.tap", =====*/Base, {
+	// defaultEvent: [readonly] String
+	//		Default event - 'tap'
+	defaultEvent: "tap",
+
+	// subEvents: [readonly] Array
+	//		List of sub events, used by being
+	//		combined with defaultEvent as 'tap.hold', 'tap.doubletap'.
+	subEvents: ["hold", "doubletap"],
+
+	// holdThreshold: Integer
+	//		Threshold(in milliseconds) for 'tap.hold'
+	holdThreshold: 500,
+
+	// holdThreshold: Integer
+	//		Timeout (in milliseconds) for 'tap.doubletap'
+	doubleTapTimeout: 250,
+
+	// tapRadius: Integer
+	//		Valid tap radius from previous touch point
+	tapRadius: 10,
+
+	press: function(/*Object*/data, /*Event*/e){
+		// summary:
+		//		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
+			delete data.context;
+			return;
+		}
+		var target = e.target;
+		this._initTap(data, e);
+		data.tapTimeOut = setTimeout(lang.hitch(this, function(){
+			if(this._isTap(data, e)){
+				this.fire(target, {type: "tap.hold"});
+			}
+			delete data.context;
+		}), this.holdThreshold);
+	},
+	release: function(/*Object*/data, /*Event*/e){
+		// summary:
+		//		Overwritten, fire matched 'tap' or 'tap.doubletap' during touchend
+		if(!data.context){
+			clearTimeout(data.tapTimeOut);
+			return;
+		}
+		if(this._isTap(data, e)){
+			switch(data.context.c){
+			case 1: 
+				this.fire(e.target, {type: "tap"});
+				break;
+			case 2:
+				this.fire(e.target, {type: "tap.doubletap"});
+				break;
+			}
+		}
+		clearTimeout(data.tapTimeOut);
+	},
+	_initTap: function(/*Object*/data, /*Event*/e){
+		// summary:
+		//		Update the gesture data with new tap info 
+		if(!data.context){
+			data.context = {x: 0, y: 0, t: 0, c: 0};
+		}
+		var ct = new Date().getTime();
+		if(ct - data.context.t <= this.doubleTapTimeout){
+			data.context.c++;
+		}else{
+			data.context.c = 1;
+			data.context.x = e.screenX;
+			data.context.y = e.screenY;
+		}
+		data.context.t = ct;
+	},
+	_isTap: function(/*Object*/data, /*Event*/e){
+		// summary:
+		//		Check whether it's an valid tap
+		var dx = Math.abs(data.context.x - e.screenX);
+		var dy = Math.abs(data.context.y - e.screenY);
+		return dx <= this.tapRadius && dy <= this.tapRadius;
+	}
+});
+
+// the default tap instance for handy use
+dojox.gesture.tap = new clz();
+// Class for creating a new Tap instance
+dojox.gesture.tap.Tap = clz;
+
+return dojox.gesture.tap;
+
+});
\ No newline at end of file
diff --git a/dojox/gesture/tests/doh/bubble.html b/dojox/gesture/tests/doh/bubble.html
new file mode 100644
index 0000000..e7e3d71
--- /dev/null
+++ b/dojox/gesture/tests/doh/bubble.html
@@ -0,0 +1,169 @@
+<!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=iso-8859-1">
+		<title>dojox.gesture bubbling Unit Test</title>
+	</head>
+	<style type="text/css">
+		@import "../../../../util/doh/robot/robot.css";
+		
+		#outer {
+			width: 350px;
+			height: 200px;
+			border: 1px solid #54A201;
+			background-color: #54A201;			
+		}
+		#inner {
+			width: 250px;
+			height: 80px;
+			border: 1px solid #7FB0DB;
+			background-color: #7FB0DB
+		}
+		
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:true"></script>
+	<script type="text/javascript">
+		require([
+			"dojo/_base/html",
+			"dojo/_base/sniff",
+			"dojo/ready",
+			"dojo/on",
+			"doh/runner",
+			"dojo/touch",
+			"dojox/gesture/tap",
+			"dojox/gesture/swipe"
+		], function(html, has, ready, on, doh, touch, tap, swipe){	
+			ready(function(){
+				var h1, h2, h3;
+				var inner = html.byId("inner");
+				var outer = html.byId("outer");
+				var innerExecuted, outerExecuted, touchExecuted;
+				var innerObj = {}, outerObj = {}, outerTouchObj = {};
+				
+				function setObj(obj, e){
+					obj.type = e.type;
+					obj.target = e.target;
+					obj.currentTarget = e.currentTarget;					
+				}
+				function assert(obj, type, target, currentTarget){
+					doh.assertEqual(type, obj.type);
+					doh.assertEqual(target, obj.target);
+					doh.assertEqual(currentTarget && !has('ie'), !!obj.currentTarget);			
+				}
+				
+				doh.register("dojox.gesture.* bubbling", [
+					function tapBubble(){
+						// test tap bubbling
+						h1 = on(inner, tap, function(e){
+							innerExecuted = true;
+							setObj(innerObj, e);
+						});
+						h2 = on(outer, tap, function(e){
+							outerExecuted = true;
+							setObj(outerObj, e);
+						});
+						// shouldn't affect other native events, e.g. touch.release = mouseup|touchend
+						h3 = on(outer, touch.release, function(e){
+							touchExecuted = true;
+							setObj(outerTouchObj, e);
+						});
+						on.emit(inner, 'mousedown', {screenX: 100, screenY: 100, bubbles:true, cancelable:true});
+						on.emit(inner, 'mouseup', {screenX: 106, screenY: 108, bubbles:true, cancelable:true});
+						doh.assertTrue(innerExecuted && outerExecuted && touchExecuted, 'tapBubble(),tap not bubbled to outer!');
+						
+						// inner tap assertion
+						assert(innerObj, 'tap', inner, inner);				
+						// outer tap assertion
+						assert(outerObj, 'tap', inner, outer);
+						// outer touch assertion
+						assert(outerTouchObj, 'mouseup', inner, outer);
+					},
+					function tapStopBubble(){
+						// test prevent bubbling						
+						innerExecuted = outerExecuted = touchExecuted = false;
+						innerObj = {}, outerObj = {}, outerTouchObj = {};
+						h1.remove();
+						//use dojo.stopEven() to prevent bubbling of tap event
+						h1 = on(inner, tap, function(e){
+							innerExecuted = true;
+							setObj(innerObj, e);
+							dojo.stopEvent(e);							
+						});
+						on.emit(inner, 'mousedown', {screenX: 100, screenY: 100, bubbles:true, cancelable:true});
+						on.emit(inner, 'mouseup', {screenX: 106, screenY: 108, bubbles:true, cancelable:true});
+						doh.assertTrue(innerExecuted && !outerExecuted && touchExecuted, "tapStopBubble(),tap shouldn't bubbled to outer!");
+
+						// inner tap assertion
+						assert(innerObj, 'tap', inner, inner);
+						// outer touch assertion
+						assert(outerTouchObj, 'mouseup', inner, outer);
+
+						h1.remove();
+						h2.remove();							
+						h3.remove();
+					},
+					function swipeBubble(){
+						// test swipe bubbling
+						innerExecuted = outerExecuted = touchExecuted = false;
+						innerObj = {}, outerObj = {}, outerTouchObj = {};
+						h1 = on(inner, swipe, function(e){
+							innerExecuted = true;
+							setObj(innerObj, e);
+						});
+						h2 = on(outer, swipe, function(e){
+							outerExecuted = true;
+							setObj(outerObj, e);
+						});
+						// shouldn't affect other native events, e.g. touch.release = mouseup|touchend
+						h3 = on(outer, touch.release, function(e){
+							touchExecuted = true;
+							setObj(outerTouchObj, e);
+						});
+						on.emit(inner, 'mousedown', {screenX: 100, screenY: 200, bubbles:true, cancelable:true});
+						on.emit(inner, 'mousemove', {screenX: 260, screenY: 100, bubbles:true, cancelable:true});
+						on.emit(inner, 'mouseup', {screenX: 300, screenY: 80, bubbles:true, cancelable:true});
+						doh.assertTrue(innerExecuted && outerExecuted && touchExecuted, 'swipeBubble(), swipe not bubbled to outer!');
+						
+						// inner swipe assertion
+						assert(innerObj, 'swipe', inner, inner);					
+						// outer swipe assertion
+						assert(outerObj, 'swipe', inner, outer);
+						// outer touch assertion
+						assert(outerTouchObj, 'mouseup', inner, outer);
+					},
+					function swipeStopBubble(){
+						// test prevent bubbling						
+						innerExecuted = outerExecuted = touchExecuted = false;
+						innerObj = {}, outerObj = {}, outerTouchObj = {};
+						h1.remove();
+						//use dojo.stopEven() to prevent bubbling of tap event
+						h1 = on(inner, swipe, function(e){
+							innerExecuted = true;
+							setObj(innerObj, e);
+							dojo.stopEvent(e);
+						});
+						on.emit(inner, 'mousedown', {screenX: 100, screenY: 200, bubbles:true, cancelable:true});
+						on.emit(inner, 'mousemove', {screenX: 260, screenY: 100, bubbles:true, cancelable:true});
+						on.emit(inner, 'mouseup', {screenX: 300, screenY: 80, bubbles:true, cancelable:true});
+						doh.assertTrue(innerExecuted && !outerExecuted && touchExecuted, "tapStopBubble(),tap shouldn't bubbled to outer!");
+
+						// inner swipe assertion
+						assert(innerObj, 'swipe', inner, inner);
+						// outer touch assertion
+						assert(outerTouchObj, 'mouseup', inner, outer);
+
+						h1.remove();
+						h2.remove();
+						h3.remove();
+					}
+				]);
+				doh.run();
+			});
+		});
+	</script>
+	<body class='claro'>
+		<div id="outer">
+			outer<div id="inner">inner</div>
+		</div>
+	</body>
+</html>
\ No newline at end of file
diff --git a/dojox/gesture/tests/doh/swipe.html b/dojox/gesture/tests/doh/swipe.html
new file mode 100644
index 0000000..07ea44f
--- /dev/null
+++ b/dojox/gesture/tests/doh/swipe.html
@@ -0,0 +1,100 @@
+<!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=iso-8859-1">
+		<title>dojox.gesture.swipe Unit Test</title>
+	</head>
+	<style type="text/css">
+		@import "../../../../util/doh/robot/robot.css";
+		
+		#outer {
+			width: 350px;
+			height: 200px;
+			border: 1px solid #54A201;
+			background-color: #54A201;			
+		}
+		#inner {
+			width: 250px;
+			height: 80px;
+			border: 1px solid #7FB0DB;
+			background-color: #7FB0DB
+		}
+		
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:true"></script>
+	<script type="text/javascript">
+		require([
+			"dojo/_base/html",
+			"dojo/ready",
+			"dojo/on",
+			"doh/runner",
+			"dojox/gesture/swipe"
+		], function(html, ready, on, doh, swipe){			
+			ready(function(){
+				var inner = html.byId("inner");
+				var h1, h2;
+				doh.register("dojox.gesture.swipe", [
+					function swipe_swipeEnd(){
+						var executed, endExecuted;
+						var swipeType, swipeTarget, swipeDx, swipeDy;
+						h1 = on(inner, swipe, function(e){
+							executed = true;
+							swipeType = e.type;
+							swipeTarget = e.target;
+							swipeDx = e.dx;
+							swipeDy = e.dy;
+						});
+						var swipeEndType, swipeEndTarget, swipeEndDx, swipeEndDy;
+						h2 = on(inner, swipe.end, function(e){
+							endExecuted = true;
+							swipeEndType = e.type;
+							swipeEndTarget = e.target;
+							swipeEndDx = e.dx;
+							swipeEndDy = e.dy;
+						});
+						on.emit(inner, 'mousedown', {screenX: 100, screenY: 200});
+						on.emit(inner, 'mousemove', {screenX: 260, screenY: 100});
+						on.emit(inner, 'mouseup', {screenX: 300, screenY: 80});
+						
+						// swipe assertions
+						doh.assertEqual('swipe', swipeType);
+						doh.assertEqual(inner, swipeTarget);
+						doh.assertEqual(160, swipeDx);
+						doh.assertEqual(-100, swipeDy);
+						
+						// swipe.end assertions
+						doh.assertEqual('swipe.end', swipeEndType);
+						doh.assertEqual(inner, swipeEndTarget);
+						doh.assertEqual(200, swipeEndDx);
+						doh.assertEqual(-120, swipeEndDy);	
+						
+						doh.assertTrue(executed, 'dojox.gesture.swipe not fired!');
+						doh.assertTrue(endExecuted, 'dojox.gesture.swipe.end not fired!');
+					}, 
+					function disconnect(){
+						var elements = swipe._elements;
+						h1.remove();
+						doh.assertTrue(elements[0].handles.swipe === 0, 'dojox.gesture.swipe handle not cleared!');
+						
+						h2.remove();
+						doh.assertTrue(elements.length === 0, 'dojox.gesture.swipe elements not cleared!');
+					},
+					function destroy(){
+						//re-connect them back
+						h1 = on(inner, swipe, function(e){ });
+						h2 = on(inner, swipe.end, function(e){ });
+						//destroy them all		
+						swipe.destroy();
+						doh.assertTrue(swipe._elements === null, 'dojox.gesture.swipe not destroyed!');
+					}
+				]);
+				doh.run();
+			});
+		});
+	</script>
+	<body class='claro'>
+		<div id="outer">
+			outer<div id="inner">inner</div>
+		</div>
+	</body>
+</html>
\ No newline at end of file
diff --git a/dojox/gesture/tests/doh/tap.html b/dojox/gesture/tests/doh/tap.html
new file mode 100644
index 0000000..eca13f2
--- /dev/null
+++ b/dojox/gesture/tests/doh/tap.html
@@ -0,0 +1,137 @@
+<!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=iso-8859-1">
+		<title>dojox.gesture.tap Unit Test</title>
+	</head>
+	<style type="text/css">
+		@import "../../../../util/doh/robot/robot.css";
+		
+		#outer {
+			width: 350px;
+			height: 200px;
+			border: 1px solid #54A201;
+			background-color: #54A201;			
+		}
+		#inner {
+			width: 250px;
+			height: 80px;
+			border: 1px solid #7FB0DB;
+			background-color: #7FB0DB
+		}
+		
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:true"></script>
+	<script type="text/javascript">
+		require([
+			"dojo/_base/html",
+			"dojo/ready",
+			"dojo/on",
+			"doh/runner",
+			"dojox/gesture/tap"
+		], function(html, ready, on, doh, tap){
+			ready(function(){
+				var h1, h2, h3, obj = {};
+				var inner = html.byId("inner");
+
+				function setObj(obj, e){
+					obj.type = e.type;
+					obj.target = e.target;
+				}
+				function assert(obj, type, target){
+					doh.assertEqual(type, obj.type);
+					doh.assertEqual(target, obj.target);
+				}
+
+				doh.register("dojox.gesture.tap", [
+					function singleTap(){
+						var executed, d = new doh.Deferred();
+						h1 = on(inner, tap, function(e){
+							executed = true;
+							setObj(obj, e);
+						});
+						on.emit(inner, 'mousedown', {screenX: 100, screenY: 100});
+						on.emit(inner, 'mouseup', {screenX: 106, screenY: 108});
+						doh.assertTrue(executed, 'dojox.gesture.tap not fired!');
+						assert(obj, 'tap', inner);
+						setTimeout(function(){
+							d.callback(true);
+						}, 300);
+						return d;
+					},
+					function doubleTap(){
+						var executed, d = new doh.Deferred();
+						obj = {};
+						h2 = on(inner, tap.doubletap, function(e){
+							executed = true;
+							setObj(obj, e);
+						});
+						//first tap
+						on.emit(inner, 'mousedown', {screenX: 0, screenY: 0});
+						on.emit(inner, 'mouseup', {screenX: 0, screenY: 0});
+						//second tap
+						on.emit(inner, 'mousedown', {screenX: 0, screenY: 0});
+						on.emit(inner, 'mouseup', {screenX: 0, screenY: 0});
+						doh.assertTrue(executed, 'dojox.gesture.tap.doubletap not fired!');
+						assert(obj, 'tap.doubletap', inner);
+						setTimeout(function(){
+							d.callback(true);
+						}, 100);
+						return d;
+					},
+					function tapHold(){
+						var executed, d = new doh.Deferred();
+						obj = {};
+						h3 = on(inner, tap.hold, function(e){
+							executed = true;
+							setObj(obj, e);
+						});
+						on.emit(inner, 'mousedown', {screenX: 0, screenY: 0});
+						setTimeout(function(){
+							assert(obj, 'tap.hold', inner);
+							doh.assertTrue(executed, 'dojox.gesture.tap.hold not fired!');
+							d.callback(true);
+						}, tap.holdThreshold);
+						return d;
+					},
+					function disconnect(){
+						var d = new doh.Deferred();
+						var elements = tap._elements;
+						h1.remove();
+						doh.assertTrue(elements[0].handles.tap === 0, 'dojox.gesture.tap handle not cleared!');
+						
+						h2.remove();
+						doh.assertTrue(elements[0].handles.tap === 0, 'dojox.gesture.tap handle not cleared!');
+						doh.assertTrue(elements[0].handles['tap.doubletap'] === 0, 'dojox.gesture.tap.doubletap handle not cleared!');
+						
+						h3.remove();
+						doh.assertTrue(elements.length === 0, 'dojox.gesture.tap elements not cleared!');
+						
+						d.callback(true);
+						return d;
+					},
+					function destroy(){
+						var d = new doh.Deferred();
+						//re-connect them back
+						h1 = on(inner, tap, function(e){});
+						h2 = on(inner, tap.doubletap, function(e){});
+						h3 = on(inner, tap.hold, function(e){});
+						
+						//destroy them all
+						tap.destroy();
+						doh.assertTrue(tap._elements === null, 'dojox.gesture.tap not destroyed!');
+						
+						d.callback(true);
+						return d;
+					}
+				]);
+				doh.run();
+			});
+		});
+	</script>
+	<body class='claro'>
+		<div id="outer">
+			outer<div id="inner">inner</div>
+		</div>
+	</body>
+</html>
\ No newline at end of file
diff --git a/dojox/gesture/tests/module.js b/dojox/gesture/tests/module.js
new file mode 100644
index 0000000..0873caf
--- /dev/null
+++ b/dojox/gesture/tests/module.js
@@ -0,0 +1,9 @@
+dojo.provide('dojox.gesture.tests.module');
+
+try {
+	doh.registerUrl('dojox.gesture.tests.tap', dojo.moduleUrl('dojox.gesture.tests', 'doh/tap.html'));
+	doh.registerUrl('dojox.gesture.tests.swipe', dojo.moduleUrl('dojox.gesture.tests', 'doh/swipe.html'));
+	doh.registerUrl('dojox.gesture.tests.bubble', dojo.moduleUrl('dojox.gesture.tests', 'doh/bubble.html'));
+}catch (e) {
+	doh.debug(e);
+}
\ No newline at end of file
diff --git a/dojox/gesture/tests/runTests.html b/dojox/gesture/tests/runTests.html
new file mode 100644
index 0000000..868e948
--- /dev/null
+++ b/dojox/gesture/tests/runTests.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+  <head>
+    <title>Gesture Unit Test Runner</title>
+    <meta http-equiv="REFRESH"         
+content="0;url=../../../util/doh/runner.html?testModule=dojox.gesture.tests.module">
+  </head>
+  <body>
+      Redirecting to D.O.H runner.
+  </body>
+</html>
diff --git a/dojox/gesture/tests/test_gesture.html b/dojox/gesture/tests/test_gesture.html
new file mode 100644
index 0000000..6fb3ca4
--- /dev/null
+++ b/dojox/gesture/tests/test_gesture.html
@@ -0,0 +1,94 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<meta name="viewport" content="width=device-width,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+		<title>Dojo Gesture Testing</title>
+		<style type="text/css">
+			#outer {
+				width: 350px;
+				height: 180px;
+				border: 1px solid #54A201;
+				background-color: #54A201;			
+			}
+			#inner {
+				width: 250px;
+				height: 80px;
+				border: 1px solid #7FB0DB;
+				background-color: #7FB0DB
+			}
+			#log1, #log2 {
+				width: 350px;
+				height: 50px;
+			}
+		</style>		
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+		<script>
+			require([
+				"dojo/_base/kernel",
+				"dojo/_base/connect",
+				"dojo/_base/html",
+				"dojo/_base/event",
+				"dojo/on",
+				"dojo/touch",
+				"dojo/ready",
+				"dojox/gesture/tap",
+				"dojox/gesture/swipe"
+			], function(dojo, conn, html, evt, on, touch, ready, tap, swipe){
+				
+				ready(function(){
+					var action = function(e){
+						html.byId("log1").innerHTML = "";
+						var info = " e.target.id=" + e.target.id + " | e.type=" + e.type + " | e.currentTarget.id="+ e.currentTarget.id;
+						/*
+						for(var i in e){
+						    if(typeof e[i] != "function"){
+						      info += "- " + i + ": " + e[i] + (e[i] && e[i]['id'] ? ' id = '+e[i]['id'] : '') + "<br/>";
+						    }
+						}*/
+						html.byId("log1").innerHTML += info;
+						//evt.stop(e);
+					};
+					
+					var swipeAction = function(e){
+						html.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/>";
+						html.byId("log2").innerHTML += info;
+						//evt.stop(e);
+					};
+					
+					//tap and swipe gestures both work well both on PC and touch devices
+					var inner = html.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 = html.byId("outer");
+					conn.connect(outer, tap, action);
+					conn.connect(outer, tap.hold, action);
+					conn.connect(outer, tap.doubletap, action);
+					conn.connect(outer, swipe, swipeAction);
+					conn.connect(outer, swipe.end, swipeAction);
+					
+					//conn.connect(outer, touch.press, function(){console.log('outer.touch.press!');});
+					
+					on(dojo.doc, "orientationchange", function(e){
+						html.byId("log1").innerHTML="";
+						html.byId("log2").innerHTML="";
+					});
+				});
+			});
+		</script>
+	</head>
+	<body>
+		<div id="outer">
+			outer<div id="inner">inner</div>
+		</div>
+		<div id="log1"></div>
+		<hr/>
+		<div id="log2"></div>
+	</body>
+</html>
\ No newline at end of file
diff --git a/dojox/gfx.js b/dojox/gfx.js
index e809d2d..ebb9182 100644
--- a/dojox/gfx.js
+++ b/dojox/gfx.js
@@ -1,80 +1,9 @@
-dojo.provide("dojox.gfx");
-
-dojo.require("dojox.gfx.matrix");
-dojo.require("dojox.gfx._base");
-
-dojo.loadInit(function(){
-	// Since loaderInit can be fired before any dojo.provide/require calls,
-	// make sure the dojox.gfx object exists and only run this logic if dojox.gfx.renderer
-	// has not been defined yet.
-	var gfx = dojo.getObject("dojox.gfx", true), sl, flag, match;
-	while(!gfx.renderer){
-		// Have a way to force a GFX renderer, if so desired.
-		// Useful for being able to serialize GFX data in a particular format.
-		if(dojo.config.forceGfxRenderer){
-			dojox.gfx.renderer = dojo.config.forceGfxRenderer;
-			break;
-		}
-		var renderers = (typeof dojo.config.gfxRenderer == "string" ?
-			dojo.config.gfxRenderer : "svg,vml,canvas,silverlight").split(",");
-		for(var i = 0; i < renderers.length; ++i){
-			switch(renderers[i]){
-				case "svg":
-					// the next test is from https://github.com/phiggins42/has.js
-					if("SVGAngle" in dojo.global){
-						dojox.gfx.renderer = "svg";
-					}
-					break;
-				case "vml":
-					if(dojo.isIE){
-						dojox.gfx.renderer = "vml";
-					}
-					break;
-				case "silverlight":
-					try{
-						if(dojo.isIE){
-							sl = new ActiveXObject("AgControl.AgControl");
-							if(sl && sl.IsVersionSupported("1.0")){
-								flag = true;
-							}
-						}else{
-							if(navigator.plugins["Silverlight Plug-In"]){
-								flag = true;
-							}
-						}
-					}catch(e){
-						flag = false;
-					}finally{
-						sl = null;
-					}
-					if(flag){
-						dojox.gfx.renderer = "silverlight";
-					}
-					break;
-				case "canvas":
-					if(dojo.global.CanvasRenderingContext2D){
-						dojox.gfx.renderer = "canvas";
-					}
-					break;
-			}
-			if(gfx.renderer){
-				break;
-			}
-		}
-		break;
-	}
-	
-	if(dojo.config.isDebug){
-		console.log("gfx renderer = " + gfx.renderer);
-	}
-
-	// load & initialize renderer
-	if(gfx[gfx.renderer]){
-		// already loaded
-		gfx.switchTo(gfx.renderer);
-	}else{
-		// load
-		gfx.loadAndSwitch = gfx.renderer;
-		dojo["require"]("dojox.gfx." + gfx.renderer);
-	}
+define(["dojo/_base/lang", "./gfx/_base", "./gfx/renderer!"], 
+  function(lang, gfxBase, renderer){
+	// module:
+	//		dojox/gfx
+	// summary:
+	//		This the root of the Dojo Graphics package
+	gfxBase.switchTo(renderer);
+	return gfxBase;
 });
diff --git a/dojox/gfx/Moveable.js b/dojox/gfx/Moveable.js
index ebc027b..2e3689f 100644
--- a/dojox/gfx/Moveable.js
+++ b/dojox/gfx/Moveable.js
@@ -1,98 +1,98 @@
-dojo.provide("dojox.gfx.Moveable");
-
-dojo.require("dojox.gfx.Mover");
-
-dojo.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
-		this.shape = shape;
-		this.delay = (params && params.delay > 0) ? params.delay : 0;
-		this.mover = (params && params.mover) ? params.mover : dojox.gfx.Mover;
-		this.events = [
-			this.shape.connect("onmousedown", 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
-		dojo.forEach(this.events, this.shape.disconnect, this.shape);
-		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
-		if(this.delay){
-			this.events.push(
-				this.shape.connect("onmousemove", this, "onMouseMove"),
-				this.shape.connect("onmouseup", this, "onMouseUp"));
-			this._lastX = e.clientX;
-			this._lastY = e.clientY;
-		}else{
-			new this.mover(this.shape, e, this);
+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){
+	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
+			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")
+				// 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);
+			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
+			if(this.delay){
+				this.events.push(
+					this.shape.connect("onmousemove", this, "onMouseMove"),
+					this.shape.connect("onmouseup", this, "onMouseUp"));
+				this._lastX = e.clientX;
+				this._lastY = e.clientY;
+			}else{
+				new this.mover(this.shape, e, this);
+			}
+			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){
+				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());
+		},
+	
+		// local events
+		onMoveStart: function(/* dojox.gfx.Mover */ mover){
+			// summary: called before every move operation
+			connect.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]);
+			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.
+	
+			// 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.
+			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.
+	
+			// default implementation does nothing
+		},
+		onMoved: function(/* dojox.gfx.Mover */ mover, /* Object */ shift){
+			// summary: called after every incremental move,
+			//	can be overwritten.
+	
+			// default implementation does nothing
 		}
-		dojo.stopEvent(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){
-			this.onMouseUp(e);
-			new this.mover(this.shape, e, this);
-		}
-		dojo.stopEvent(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());
-	},
-
-	// local events
-	onMoveStart: function(/* dojox.gfx.Mover */ mover){
-		// summary: called before every move operation
-		dojo.publish("/gfx/move/start", [mover]);
-		dojo.addClass(dojo.body(), "dojoMove");
-	},
-	onMoveStop: function(/* dojox.gfx.Mover */ mover){
-		// summary: called after every move operation
-		dojo.publish("/gfx/move/stop", [mover]);
-		dojo.removeClass(dojo.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.
-
-		// 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.
-		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.
-
-		// default implementation does nothing
-	},
-	onMoved: function(/* dojox.gfx.Mover */ mover, /* Object */ shift){
-		// summary: called after every incremental move,
-		//	can be overwritten.
-
-		// default implementation does nothing
-	}
+	});
 });
diff --git a/dojox/gfx/Mover.js b/dojox/gfx/Mover.js
index 5134582..bec60a4 100644
--- a/dojox/gfx/Mover.js
+++ b/dojox/gfx/Mover.js
@@ -1,58 +1,59 @@
-dojo.provide("dojox.gfx.Mover");
-
-dojo.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)
-		this.shape = shape;
-		this.lastX = e.clientX
-		this.lastY = e.clientY;
-		var h = this.host = host, d = document,
-			firstEvent = dojo.connect(d, "onmousemove", this, "onFirstMove");
-		this.events = [
-			dojo.connect(d, "onmousemove", this, "onMouseMove"),
-			dojo.connect(d, "onmouseup",   this, "destroy"),
-			// cancel text selection and text dragging
-			dojo.connect(d, "ondragstart",   dojo, "stopEvent"),
-			dojo.connect(d, "onselectstart", dojo, "stopEvent"),
-			firstEvent
-		];
-		// notify that the move has started
-		if(h && h.onMoveStart){
-			h.onMoveStart(this);
+define(["dojo/_base/lang","dojo/_base/array", "dojo/_base/declare", "dojo/_base/connect", "dojo/_base/event"], 
+  function(lang,arr,declare,connect,evt){
+	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)
+			this.shape = shape;
+			this.lastX = e.clientX
+			this.lastY = e.clientY;
+			var h = this.host = host, d = document,
+				firstEvent = connect.connect(d, "onmousemove", this, "onFirstMove");
+			this.events = [
+				connect.connect(d, "onmousemove", this, "onMouseMove"),
+				connect.connect(d, "onmouseup",   this, "destroy"),
+				// cancel text selection and text dragging
+				connect.connect(d, "ondragstart",   evt, "stop"),
+				connect.connect(d, "onselectstart", evt, "stop"),
+				firstEvent
+			];
+			// notify that the move has started
+			if(h && h.onMoveStart){
+				h.onMoveStart(this);
+			}
+		},
+		// mouse event processors
+		onMouseMove: function(e){
+			// 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);
+		},
+		// utilities
+		onFirstMove: function(){
+			// summary: it is meant to be called only once
+			this.host.onFirstMove(this);
+			connect.disconnect(this.events.pop());
+		},
+		destroy: function(){
+			// summary: stops the move, deletes all references, so the object can be garbage-collected
+			arr.forEach(this.events, connect.disconnect);
+			// undo global settings
+			var h = this.host;
+			if(h && h.onMoveStop){
+				h.onMoveStop(this);
+			}
+			// destroy objects
+			this.events = this.shape = null;
 		}
-	},
-	// mouse event processors
-	onMouseMove: function(e){
-		// 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;
-		dojo.stopEvent(e);
-	},
-	// utilities
-	onFirstMove: function(){
-		// summary: it is meant to be called only once
-		this.host.onFirstMove(this);
-		dojo.disconnect(this.events.pop());
-	},
-	destroy: function(){
-		// summary: stops the move, deletes all references, so the object can be garbage-collected
-		dojo.forEach(this.events, dojo.disconnect);
-		// undo global settings
-		var h = this.host;
-		if(h && h.onMoveStop){
-			h.onMoveStop(this);
-		}
-		// destroy objects
-		this.events = this.shape = null;
-	}
+	});
 });
diff --git a/dojox/gfx/VectorText.js b/dojox/gfx/VectorText.js
index 83b9dd5..42098b0 100644
--- a/dojox/gfx/VectorText.js
+++ b/dojox/gfx/VectorText.js
@@ -1,38 +1,47 @@
-dojo.provide("dojox.gfx.VectorText");
-dojo.require("dojox.gfx");
-dojo.require("dojox.xml.DomParser");
-dojo.require("dojox.html.metrics");
-
-(function(){
-	/*
-		dojox.gfx.VectorText
-		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.
-	 */
-	dojo.mixin(dojox.gfx, {
+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.
+	};
+ =====*/ 
+	var _getText = function(url){
+		var result;
+		xhr.get({url:url, sync:true, load:function(text){ // Note synchronous!
+			result = text;
+		}});
+		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
@@ -49,14 +58,14 @@ dojo.require("dojox.html.metrics");
 		_vectorFontCache: {},
 		_svgFontCache: {},
 		getVectorFont: function(/* String */url){
-			if(dojox.gfx._vectorFontCache[url]){
-				return dojox.gfx._vectorFontCache[url];
+			if(gfx._vectorFontCache[url]){
+				return gfx._vectorFontCache[url];
 			}
-			return new dojox.gfx.VectorFont(url);
+			return new gfx.VectorFont(url);
 		}
 	});
 
-	dojo.declare("dojox.gfx.VectorFont", null, {
+	return declare("dojox.gfx.VectorFont", null, {  // EARLY RETURN
 		_entityRe: /&(quot|apos|lt|gt|amp|#x[^;]+|#\d+);/g,
 		_decodeEntitySequence: function(str){
 			//	unescape the unicode sequences
@@ -87,7 +96,7 @@ dojo.require("dojox.html.metrics");
 			//		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 = dojox.gfx._svgFontCache[url]||dojox.xml.DomParser.parse(svg);
+			var doc = gfx._svgFontCache[url]||xmlDomParser.parse(svg);
 
 			//	font information
 			var f = doc.documentElement.byName("font")[0], face = doc.documentElement.byName("font-face")[0];
@@ -133,10 +142,10 @@ dojo.require("dojox.html.metrics");
 			}
 
 			//	see if this is cached already, and if so, forget the rest of the parsing.
-			if(dojox.gfx._vectorFontCache[name]){ return; }
+			if(gfx._vectorFontCache[name]){ return; }
 
 			//	get any provided baseline alignment offsets.
-			dojo.forEach(["alphabetic", "ideographic", "mathematical", "hanging" ], function(attr){
+			arr.forEach(["alphabetic", "ideographic", "mathematical", "hanging" ], function(attr){
 				var a = face.getAttribute(attr);
 				if(a !== null /* be explicit, might be 0 */){
 					baseline[attr] = parseFloat(a, 10);
@@ -146,7 +155,7 @@ dojo.require("dojox.html.metrics");
 		/*
 			//	TODO: decoration hinting.
 			var decoration = { };
-			dojo.forEach(["underline", "strikethrough", "overline"], function(type){
+			arr.forEach(["underline", "strikethrough", "overline"], function(type){
 				if(face.getAttribute(type+"-position")!=null){
 					decoration[type]={ };
 				}
@@ -158,7 +167,7 @@ dojo.require("dojox.html.metrics");
 
 			//	glyph information
 			var glyphs = {}, glyphsByName={}, g=doc.documentElement.byName("glyph");
-			dojo.forEach(g, function(node){
+			arr.forEach(g, function(node){
 				//	we are going to assume the following:
 				//		1) we have the unicode attribute
 				//		2) we have the name attribute
@@ -181,7 +190,7 @@ dojo.require("dojox.html.metrics");
 
 			//	now the fun part: look for kerning pairs.
 			var hkern=doc.documentElement.byName("hkern");
-			dojo.forEach(hkern, function(node, i){
+			arr.forEach(hkern, function(node, i){
 				var k = -parseInt(node.getAttribute("k"),10);
 				//	look for either a code or a name
 				var u1=node.getAttribute("u1"),
@@ -220,7 +229,7 @@ dojo.require("dojox.html.metrics");
 			}, this);
 
 			//	pop the final definition in the font cache.
-			dojo.mixin(this, {
+			lang.mixin(this, {
 				family: family,
 				name: name,
 				style: style,
@@ -230,7 +239,7 @@ dojo.require("dojox.html.metrics");
 				range: range,
 				viewbox: { width: unitsPerEm, height: unitsPerEm },
 				origin: origin,
-				advance: dojo.mixin(advance, {
+				advance: lang.mixin(advance, {
 					missing:{ x: missing, y: missing }
 				}),
 				ascent: ascent,
@@ -240,22 +249,22 @@ dojo.require("dojox.html.metrics");
 			});
 
 			//	cache the parsed font
-			dojox.gfx._vectorFontCache[name] = this;
-			dojox.gfx._vectorFontCache[url] = this;
-			if(name!=family && !dojox.gfx._vectorFontCache[family]){
-				dojox.gfx._vectorFontCache[family] = this;
+			gfx._vectorFontCache[name] = this;
+			gfx._vectorFontCache[url] = this;
+			if(name!=family && !gfx._vectorFontCache[family]){
+				gfx._vectorFontCache[family] = this;
 			}
 
 			//	cache the doc
-			if(!dojox.gfx._svgFontCache[url]){
-				dojox.gfx._svgFontCache[url]=doc;
+			if(!gfx._svgFontCache[url]){
+				gfx._svgFontCache[url]=doc;
 			}
 		},
 		_clean: function(){
 			//	summary:
 			//		Clean off all of the given mixin parameters.
 			var name = this.name, family = this.family;
-			dojo.forEach(["family","name","style","variant",
+			arr.forEach(["family","name","style","variant",
 				"weight","stretch","range","viewbox",
 				"origin","advance","ascent","descent",
 				"baseline","glyphs"], function(prop){
@@ -263,11 +272,11 @@ dojo.require("dojox.html.metrics");
 			}, this);
 
 			//	try to pull out of the font cache.
-			if(dojox.gfx._vectorFontCache[name]){
-				delete dojox.gfx._vectorFontCache[name];
+			if(gfx._vectorFontCache[name]){
+				delete gfx._vectorFontCache[name];
 			}
-			if(dojox.gfx._vectorFontCache[family]){
-				delete dojox.gfx._vectorFontCache[family];
+			if(gfx._vectorFontCache[family]){
+				delete gfx._vectorFontCache[family];
 			}
 			return this;
 		},
@@ -285,7 +294,7 @@ dojo.require("dojox.html.metrics");
 			//		Load the passed SVG and send it to the parser for parsing.
 			this.onLoadBegin(url.toString());
 			this._parse(
-				dojox.gfx._svgFontCache[url.toString()]||dojo._getText(url.toString()),
+				gfx._svgFontCache[url.toString()]||_getText(url.toString()),
 				url.toString()
 			);
 			this.onLoad(this);
@@ -306,7 +315,7 @@ dojo.require("dojox.html.metrics");
 
 		_getWidth: function(glyphs){
 			var w=0, last=0, lastGlyph=null;
-			dojo.forEach(glyphs, function(glyph, i){
+			arr.forEach(glyphs, function(glyph, i){
 				last=glyph.xAdvance;
 				if(glyphs[i] && glyph.kern && glyph.kern[glyphs[i].code]){
 					last += glyph.kern[glyphs[i].code].x;
@@ -325,7 +334,7 @@ dojo.require("dojox.html.metrics");
 
 		_getLongestLine: function(lines){
 			var maxw=0, idx=0;
-			dojo.forEach(lines, function(line, i){
+			arr.forEach(lines, function(line, i){
 				var max = Math.max(maxw, this._getWidth(line));
 				if(max > maxw){
 					maxw = max;
@@ -344,9 +353,9 @@ dojo.require("dojox.html.metrics");
 				if(arr[0].code == " "){ arr.splice(0, 1); }
 			};
 
-			if(dojo.isArray(lines[0])){
+			if(lang.isArray(lines[0])){
 				//	more than one line.
-				dojo.forEach(lines, fn);
+				arr.forEach(lines, fn);
 			} else {
 				fn(lines);
 			}
@@ -391,7 +400,7 @@ dojo.require("dojox.html.metrics");
 			//	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 = dojox.html.metrics.getCachedFontMeasurements(),
+			var metrics = HtmlMetrics.getCachedFontMeasurements(),
 				height=this.viewbox.height,
 				f=metrics["1em"],
 				unit=parseFloat(size, 10);	//	the default.
@@ -480,7 +489,7 @@ dojo.require("dojox.html.metrics");
 		getWidth: function(/* String */text, /* Float? */scale){
 			//	summary:
 			//		Get the width of the rendered text without actually rendering it.
-			return this._getWidth(dojo.map(this._normalize(text).split(""), function(chr){
+			return this._getWidth(arr.map(this._normalize(text).split(""), function(chr){
 				return this.glyphs[chr] || { xAdvance: this.advance.missing.x };
 			}, this)) * (scale || 1);	//	Float
 		},
@@ -604,7 +613,7 @@ dojo.require("dojox.html.metrics");
 			}
 
 			//	go get the glyph array.
-			var text = dojo.map(this._normalize(textArgs.text).split(""), function(chr){
+			var text = arr.map(this._normalize(textArgs.text).split(""), function(chr){
 				return this.glyphs[chr] || { path:null, xAdvance: this.advance.missing.x };
 			}, this);
 
@@ -619,22 +628,22 @@ dojo.require("dojox.html.metrics");
 			//	figure out if we have to do fitting at all.
 			if(fitting){
 				//	more than zero.
-				if((fitting==dojox.gfx.vectorFontFitting.FLOW && !width) || (fitting==dojox.gfx.vectorFontFitting.FIT && (!width || !height))){
+				if((fitting==gfx.vectorFontFitting.FLOW && !width) || (fitting==gfx.vectorFontFitting.FIT && (!width || !height))){
 					//	reset the fitting if we don't have everything we need.
-					fitting = dojox.gfx.vectorFontFitting.NONE;
+					fitting = gfx.vectorFontFitting.NONE;
 				}
 			}
 
 			//	set up the lines array and the scaling factor.
 			var lines, scale;
 			switch(fitting){
-				case dojox.gfx.vectorFontFitting.FIT:
+				case gfx.vectorFontFitting.FIT:
 					var o=this._getBestFit(text, width, height, leading);
 					scale = o.scale;
 					lines = o.lines;
 					break;
 
-				case dojox.gfx.vectorFontFitting.FLOW:
+				case gfx.vectorFontFitting.FLOW:
 					scale = this._getSizeFactor(size);
 					lines = this._getBestFlow(text, width, scale);
 					break;
@@ -646,7 +655,7 @@ dojo.require("dojox.html.metrics");
 			}
 
 			//	make sure lines doesn't have any empty lines.
-			lines = dojo.filter(lines, function(item){
+			lines = arr.filter(lines, function(item){
 				return item.length>0;
 			});
 
@@ -667,8 +676,8 @@ dojo.require("dojox.html.metrics");
 						var p = lg.createPath(glyph.path).setFill(fillArgs);
 						if(strokeArgs){ p.setStroke(strokeArgs); }
 						p.setTransform([
-							dojox.gfx.matrix.flipY,
-							dojox.gfx.matrix.translate(cx, -this.viewbox.height-this.descent)
+							Matrix.flipY,
+							Matrix.translate(cx, -this.viewbox.height-this.descent)
 						]);
 					}
 					cx += glyph.xAdvance;
@@ -686,7 +695,7 @@ dojo.require("dojox.html.metrics");
 			}
 
 			//	scale the group
-			g.setTransform(dojox.gfx.matrix.scale(scale));
+			g.setTransform(Matrix.scale(scale));
 
 			//	return the overall group
 			return g;	//	dojox.gfx.Group
@@ -774,4 +783,4 @@ dojo.require("dojox.html.metrics");
 		return this.createObject(dojox.gfx.VectorText, text);
 	}
 */
-})();
+});
diff --git a/dojox/gfx/_base.js b/dojox/gfx/_base.js
index c3d1a49..dc9cfa4 100644
--- a/dojox/gfx/_base.js
+++ b/dojox/gfx/_base.js
@@ -1,8 +1,14 @@
-dojo.provide("dojox.gfx._base");
-
-(function(){
-	var g = dojox.gfx, b = g._base;
-
+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){
+	// 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:
@@ -44,15 +50,16 @@ dojo.provide("dojox.gfx._base");
 			'x-small': 0, 'small': 0, 'medium': 0, 'large': 0, 'x-large': 0,
 			'xx-large': 0
 		};
+		var p;
 
-		if(dojo.isIE){
+		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.
-			dojo.doc.documentElement.style.fontSize="100%";
+			win.doc.documentElement.style.fontSize="100%";
 		}
 
 		//	set up the measuring node.
-		var div = dojo.create("div", {style: {
+		var div = domConstruct.create("div", {style: {
 				position: "absolute",
 				left: "0",
 				top: "-100px",
@@ -64,16 +71,16 @@ dojo.provide("dojox.gfx._base");
 				outline: "none",
 				lineHeight: "1",
 				overflow: "hidden"
-			}}, dojo.body());
+			}}, win.body());
 
 		//	do the measurements.
-		for(var p in heights){
+		for(p in heights){
 			div.style.fontSize = p;
 			heights[p] = Math.round(div.offsetHeight * 12/16) * 16/12 / 1000;
 		}
 
-		dojo.body().removeChild(div);
-		return heights; 	//	object
+		win.body().removeChild(div);
+		return heights; //object
 	};
 
 	var fontMeasurements = null;
@@ -92,12 +99,13 @@ dojo.provide("dojox.gfx._base");
 								/*Object*/ style,
 								/*String?*/ className){
 		var m, s, al = arguments.length;
+		var i;
 		if(!measuringNode){
-			measuringNode = dojo.create("div", {style: {
+			measuringNode = domConstruct.create("div", {style: {
 				position: "absolute",
 				top: "-10000px",
 				left: "0"
-			}}, dojo.body());
+			}}, win.body());
 		}
 		m = measuringNode;
 		// reset styles
@@ -109,7 +117,7 @@ dojo.provide("dojox.gfx._base");
 		s.outline = "0";
 		// set new style
 		if(al > 1 && style){
-			for(var i in style){
+			for(i in style){
 				if(i in empty){ continue; }
 				s[i] = style[i];
 			}
@@ -125,7 +133,7 @@ dojo.provide("dojox.gfx._base");
 			var bcr = m.getBoundingClientRect();
 			return {l: bcr.left, t: bcr.top, w: bcr.width || (bcr.right - bcr.left), h: bcr.height || (bcr.bottom - bcr.top)};
 		}else{
-			return dojo.marginBox(m);
+			return domGeom.getMarginBox(m);
 		}
 	};
 
@@ -136,242 +144,499 @@ dojo.provide("dojox.gfx._base");
 		// summary: returns a unique string for use with any DOM element
 		var id;
 		do{
-			id = dojo._scopeName + "Unique" + (++uniqueId);
-		}while(dojo.byId(id));
+			id = dojo._scopeName + "xUnique" + (++uniqueId);
+		}while(dom.byId(id));
 		return id;
 	};
-})();
 
-dojo.mixin(dojox.gfx, {
-	//	summary:
-	// 		defines constants, prototypes, and utility functions
+	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: {
-		type: "path", path: ""
-	},
-	defaultPolyline: {
-		type: "polyline", points: []
-	},
-	defaultRect: {
-		type: "rect", x: 0, y: 0, width: 100, height: 100, r: 0
-	},
-	defaultEllipse: {
-		type: "ellipse", cx: 0, cy: 0, rx: 200, ry: 100
-	},
-	defaultCircle: {
-		type: "circle", cx: 0, cy: 0, r: 100
-	},
-	defaultLine: {
-		type: "line", x1: 0, y1: 0, x2: 100, y2: 100
-	},
-	defaultImage: {
-		type: "image", x: 0, y: 0, width: 0, height: 0, src: ""
-	},
-	defaultText: {
-		type: "text", x: 0, y: 0, text: "", align: "start",
-		decoration: "none", rotated: false, kerning: true
-	},
-	defaultTextPath: {
-		type: "textpath", text: "", align: "start",
-		decoration: "none", rotated: false, kerning: true
-	},
+		// default shapes, which are used to fill in missing parameters
+		defaultPath: {
+			//	summary:
+			//		Defines the default Path prototype object.
+			type: "path", 
+			//	type: String
+			//		Specifies this object is a Path, default value 'path'.
+			path: ""
+			//	path: String
+			//		The path commands. See W32C SVG 1.0 specification. 
+			//		Defaults to empty string value.
+		},
+		defaultPolyline: {
+			//	summary:
+			//		Defines the default PolyLine prototype.
+			type: "polyline", 
+			//	type: String
+			//		Specifies this object is a PolyLine, default value 'polyline'.
+			points: []
+			//	points: Array
+			//		An array of point objects [{x:0,y:0},...] defining the default polyline's line segments. Value is an empty array [].
+		},
+		defaultRect: {
+			//	summary:
+			//		Defines the default Rect prototype.
+			type: "rect",
+			//	type: String
+			//		Specifies this default object is a type of Rect. Value is 'rect' 
+			x: 0, 
+			//	x: Number
+			//		The X coordinate of the default rectangles position, value 0.
+			y: 0, 
+			//	y: Number
+			//		The Y coordinate of the default rectangle's position, value 0.
+			width: 100, 
+			//	width: Number
+			//		The width of the default rectangle, value 100.
+			height: 100, 
+			//	height: Number
+			//		The height of the default rectangle, value 100.
+			r: 0
+			//	r: Number
+			//		The corner radius for the default rectangle, value 0.
+		},
+		defaultEllipse: {
+			//	summary:
+			//		Defines the default Ellipse prototype.
+			type: "ellipse", 
+			//	type: String
+			//		Specifies that this object is a type of Ellipse, value is 'ellipse'
+			cx: 0, 
+			//	cx: Number
+			//		The X coordinate of the center of the ellipse, default value 0.
+			cy: 0, 
+			//	cy: Number
+			//		The Y coordinate of the center of the ellipse, default value 0.
+			rx: 200,
+			//	rx: Number
+			//		The radius of the ellipse in the X direction, default value 200.
+			ry: 100
+			//	ry: Number
+			//		The radius of the ellipse in the Y direction, default value 200.
+		},
+		defaultCircle: {
+			//	summary:
+			//		An object defining the default Circle prototype.
+			type: "circle", 
+			//	type: String
+			//		Specifies this object is a circle, value 'circle'
+			cx: 0, 
+			//	cx: Number
+			//		The X coordinate of the center of the circle, default value 0.
+			cy: 0, 
+			//	cy: Number
+			//		The Y coordinate of the center of the circle, default value 0.
+			r: 100
+			//	r: Number
+			//		The radius, default value 100.
+		},
+		defaultLine: {
+			//	summary:
+			//		An pbject defining the default Line prototype.
+			type: "line", 
+			//	type: String
+			//		Specifies this is a Line, value 'line'
+			x1: 0, 
+			//	x1: Number
+			//		The X coordinate of the start of the line, default value 0.
+			y1: 0, 
+			//	y1: Number
+			//		The Y coordinate of the start of the line, default value 0.
+			x2: 100,
+			//	x2: Number
+			//		The X coordinate of the end of the line, default value 100.
+			y2: 100
+			//	y2: Number
+			//		The Y coordinate of the end of the line, default value 100.
+		},
+		defaultImage: {
+			//	summary:
+			//		Defines the default Image prototype.
+			type: "image",
+			//	type: String
+			//		Specifies this object is an image, value 'image'.
+			x: 0, 
+			//	x: Number
+			//		The X coordinate of the image's position, default value 0.
+			y: 0, 
+			//	y: Number
+			//		The Y coordinate of the image's position, default value 0.
+			width: 0,
+			//	width: Number
+			//		The width of the image, default value 0.
+			height: 0,
+			//	height:Number
+			//		The height of the image, default value 0.
+			src: ""
+			//	src: String
+			//		The src url of the image, defaults to empty string.
+		},
+		defaultText: {
+			//	summary:
+			//		Defines the default Text prototype.
+			type: "text", 
+			//	type: String
+			//		Specifies this is a Text shape, value 'text'.
+			x: 0, 
+			//	x: Number
+			//		The X coordinate of the text position, default value 0.
+			y: 0, 
+			//	y: Number
+			//		The Y coordinate of the text position, default value 0.
+			text: "",
+			//	text: String
+			//		The text to be displayed, default value empty string.
+			align: "start",
+			//	align:	String
+			//		The horizontal text alignment, one of 'start', 'end', 'center'. Default value 'start'.
+			decoration: "none",
+			//	decoration: String
+			//		The text decoration , one of 'none', ... . Default value 'none'.
+			rotated: false,
+			//	rotated: Boolean
+			//		Whether the text is rotated, boolean default value false.
+			kerning: true
+			//	kerning: Boolean
+			//		Whether kerning is used on the text, boolean default value true.
+		},
+		defaultTextPath: {
+			//	summary:
+			//		Defines the default TextPath prototype.
+			type: "textpath", 
+			//	type: String
+			//		Specifies this is a TextPath, value 'textpath'.
+			text: "", 
+			//	text: String
+			//		The text to be displayed, default value empty string.
+			align: "start",
+			//	align: String
+			//		The horizontal text alignment, one of 'start', 'end', 'center'. Default value 'start'.
+			decoration: "none",
+			//	decoration: String
+			//		The text decoration , one of 'none', ... . Default value 'none'.
+			rotated: false,
+			//	rotated: Boolean
+			//		Whether the text is rotated, boolean default value false.
+			kerning: true
+			//	kerning: Boolean
+			//		Whether kerning is used on the text, boolean default value true.
+		},
 
-	// default geometric attributes
-	defaultStroke: {
-		type: "stroke", color: "black", style: "solid", width: 1,
-		cap: "butt", join: 4
-	},
-	defaultLinearGradient: {
-		type: "linear", x1: 0, y1: 0, x2: 100, y2: 100,
-		colors: [
-			{ offset: 0, color: "black" }, { offset: 1, color: "white" }
-		]
-	},
-	defaultRadialGradient: {
-		type: "radial", cx: 0, cy: 0, r: 100,
-		colors: [
-			{ offset: 0, color: "black" }, { offset: 1, color: "white" }
-		]
-	},
-	defaultPattern: {
-		type: "pattern", x: 0, y: 0, width: 0, height: 0, src: ""
-	},
-	defaultFont: {
-		type: "font", style: "normal", variant: "normal",
-		weight: "normal", size: "10pt", family: "serif"
-	},
+		// default stylistic attributes
+		defaultStroke: {
+			//	summary:
+			//		A stroke defines stylistic properties that are used when drawing a path.  
+			//		This object defines the default Stroke prototype.
+			type: "stroke", 
+			//	type: String
+			//		Specifies this object is a type of Stroke, value 'stroke'.
+			color: "black", 
+			//	color: String
+			//		The color of the stroke, default value 'black'.
+			style: "solid",
+			//	style: String
+			//		The style of the stroke, one of 'solid', ... . Default value 'solid'.
+			width: 1,
+			//	width: Number
+			//		The width of a stroke, default value 1.
+			cap: "butt",
+			//	cap: String
+			//		The endcap style of the path. One of 'butt', 'round', ... . Default value 'butt'.
+			join: 4
+			//	join: Number
+			//		The join style to use when combining path segments. Default value 4.
+		},
+		defaultLinearGradient: {
+			//	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
+			//		Specifies this object is a Linear Gradient, value 'linear'
+			x1: 0, 
+			//	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
+			//		The Y coordinate of the start of the virtual line along which the gradient is drawn, default value 0.
+			x2: 100,
+			//	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
+			//		The Y coordinate of the end of the virtual line along which the gradient is drawn, default value 100.
+			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
+			//		Specifies this is a RadialGradient, value 'radial'
+			cx: 0, 
+			//	cx: Number
+			//		The X coordinate of the center of the radial gradient, default value 0.
+			cy: 0, 
+			//	cy: Number
+			//		The Y coordinate of the center of the radial gradient, default value 0.
+			r: 100,
+			//	r: Number
+			//		The radius to the end of the radial gradient, default value 100.
+			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
+			//		The X coordinate of the position of the pattern, default value is 0.
+			y: 0, 
+			//	y: Number
+			//		The Y coordinate of the position of the pattern, default value is 0.
+			width: 0, 
+			//	width: Number
+			//		The width of the pattern image, default value is 0.
+			height: 0, 
+			//	height: Number
+			//		The height of the pattern image, default value is 0.
+			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
+			//		The font style, one of 'normal', 'bold', default value 'normal'.
+			variant: "normal",
+			//	variant: String
+			//		The font variant, one of 'normal', ... , default value 'normal'.
+			weight: "normal", 
+			//	weight: String
+			//		The font weight, one of 'normal', ..., default value 'normal'.
+			size: "10pt", 
+			//	size: String
+			//		The font size (including units), default value '10pt'.
+			family: "serif"
+			//	family: String
+			//		The font family, one of 'serif', 'sanserif', ..., default value 'serif'.
+		},
 
-	getDefault: (function(){
-		var typeCtorCache = {};
-		// a memoized delegate()
-		return function(/*String*/ type){
-			var t = typeCtorCache[type];
-			if(t){
+		getDefault: (function(){
+			//	summary:
+			//		Returns a function used to access default memoized prototype objects (see them defined above).
+			var typeCtorCache = {};
+			// a memoized delegate()
+			return function(/*String*/ type){
+				var t = typeCtorCache[type];
+				if(t){
+					return new t();
+				}
+				t = typeCtorCache[type] = new Function();
+				t.prototype = g[ "default" + type ];
 				return new t();
 			}
-			t = typeCtorCache[type] = new Function;
-			t.prototype = dojox.gfx[ "default" + type ];
-			return new t();
-		}
-	})(),
+		})(),
 
-	normalizeColor: function(/*Color*/ color){
-		//	summary:
-		// 		converts any legal color representation to normalized
-		// 		dojo.Color object
-		return (color instanceof dojo.Color) ? color : new dojo.Color(color); // dojo.Color
-	},
-	normalizeParameters: function(existed, update){
-		//	summary:
-		// 		updates an existing object with properties from an "update"
-		// 		object
-		//	existed: Object
-		//		the "target" object to be updated
-		//	update:  Object
-		//		the "update" object, whose properties will be used to update
-		//		the existed object
-		if(update){
-			var empty = {};
-			for(var x in existed){
-				if(x in update && !(x in empty)){
-					existed[x] = update[x];
+		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
+		},
+		normalizeParameters: function(existed, update){
+			//	summary:
+			//		updates an existing object with properties from an 'update'
+			//		object
+			//	existed: Object
+			//		the target object to be updated
+			//	update:  Object
+			//		the 'update' object, whose properties will be used to update
+			//		the existed object
+			var x;
+			if(update){
+				var empty = {};
+				for(x in existed){
+					if(x in update && !(x in empty)){
+						existed[x] = update[x];
+					}
 				}
 			}
-		}
-		return existed;	// Object
-	},
-	makeParameters: function(defaults, update){
-		//	summary:
-		// 		copies the original object, and all copied properties from the
-		// 		"update" object
-		//	defaults: Object
-		//		the object to be cloned before updating
-		//	update:   Object
-		//		the object, which properties are to be cloned during updating
-		if(!update){
-			// return dojo.clone(defaults);
-			return dojo.delegate(defaults);
-		}
-		var result = {};
-		for(var i in defaults){
-			if(!(i in result)){
-				result[i] = dojo.clone((i in update) ? update[i] : defaults[i]);
+			return existed;	// Object
+		},
+		makeParameters: function(defaults, update){
+			//	summary:
+			//		copies the original object, and all copied properties from the
+			//		'update' object
+			//	defaults: Object
+			//		the object to be cloned before updating
+			//	update:   Object
+			//		the object, which properties are to be cloned during updating
+			var i = null;
+			if(!update){
+				// return dojo.clone(defaults);
+				return lang.delegate(defaults);
 			}
-		}
-		return result; // Object
-	},
-	formatNumber: function(x, addSpace){
-		// summary: converts a number to a string using a fixed notation
-		// x:			Number:		number to be converted
-		// addSpace:	Boolean?:	if it is true, add a space before a positive number
-		var val = x.toString();
-		if(val.indexOf("e") >= 0){
-			val = x.toFixed(4);
-		}else{
-			var point = val.indexOf(".");
-			if(point >= 0 && val.length - point > 5){
-				val = x.toFixed(4);
+			var result = {};
+			for(i in defaults){
+				if(!(i in result)){
+					result[i] = lang.clone((i in update) ? update[i] : defaults[i]);
+				}
 			}
-		}
-		if(x < 0){
-			return val; // String
-		}
-		return addSpace ? " " + val : val; // String
-	},
-	// font operations
-	makeFontString: function(font){
-		// 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){
-		// summary:
-		//		converts a CSS font string to a font object
-		// description:
-		//		Converts a CSS font string to a gfx font object. The CSS font
-		//		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.
-		// str: String
-		//		a CSS font string
-		var font = dojox.gfx.getDefault("Font");
-		var t = str.split(/\s+/);
-		do{
-			if(t.length < 5){ break; }
-			font.style   = t[0];
-			font.variant = t[1];
-			font.weight  = t[2];
-			var i = t[3].indexOf("/");
-			font.size = i < 0 ? t[3] : t[3].substring(0, i);
-			var j = 4;
-			if(i < 0){
-				if(t[4] == "/"){
-					j = 6;
-				}else if(t[4].charAt(0) == "/"){
-					j = 5;
+			return result; // Object
+		},
+		formatNumber: function(x, addSpace){
+			// 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
+			var val = x.toString();
+			if(val.indexOf("e") >= 0){
+				val = x.toFixed(4);
+			}else{
+				var point = val.indexOf(".");
+				if(point >= 0 && val.length - point > 5){
+					val = x.toFixed(4);
 				}
 			}
-			if(j < t.length){
-				font.family = t.slice(j).join(" ");
+			if(x < 0){
+				return val; // String
 			}
-		}while(false);
-		return font;	// Object
-	},
-	// length operations
-	cm_in_pt: 72 / 2.54,	// Number: points per centimeter
-	mm_in_pt: 7.2 / 2.54,	// Number: points per millimeter
-	px_in_pt: function(){
-		// summary: returns a number of pixels per point
-		return dojox.gfx._base._getCachedFontMeasurements()["12pt"] / 12;	// Number
-	},
-	pt2px: function(len){
-		// summary: converts points to pixels
-		// len: Number: a value in points
-		return len * dojox.gfx.px_in_pt();	// Number
-	},
-	px2pt: function(len){
-		// summary: converts pixels to points
-		// len: Number: a value in pixels
-		return len / dojox.gfx.px_in_pt();	// Number
-	},
-	normalizedLength: function(len) {
-		// summary: converts any length value to pixels
-		// len: String: a length, e.g., "12pc"
-		if(len.length == 0) return 0;
-		if(len.length > 2){
-			var px_in_pt = dojox.gfx.px_in_pt();
-			var val = parseFloat(len);
-			switch(len.slice(-2)){
-				case "px": return val;
-				case "pt": return val * px_in_pt;
-				case "in": return val * 72 * px_in_pt;
-				case "pc": return val * 12 * px_in_pt;
-				case "mm": return val * dojox.gfx.mm_in_pt * px_in_pt;
-				case "cm": return val * dojox.gfx.cm_in_pt * px_in_pt;
+			return addSpace ? " " + val : val; // String
+		},
+		// font operations
+		makeFontString: function(font){
+			// 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){
+			// summary:
+			//		converts a CSS font string to a font object
+			// description:
+			//		Converts a CSS font string to a gfx font object. The CSS font
+			//		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.
+			// str: String
+			//		a CSS font string
+			var font = g.getDefault("Font");
+			var t = str.split(/\s+/);
+			do{
+				if(t.length < 5){ break; }
+				font.style   = t[0];
+				font.variant = t[1];
+				font.weight  = t[2];
+				var i = t[3].indexOf("/");
+				font.size = i < 0 ? t[3] : t[3].substring(0, i);
+				var j = 4;
+				if(i < 0){
+					if(t[4] == "/"){
+						j = 6;
+					}else if(t[4].charAt(0) == "/"){
+						j = 5;
+					}
+				}
+				if(j < t.length){
+					font.family = t.slice(j).join(" ");
+				}
+			}while(false);
+			return font;	// Object
+		},
+		// length operations
+		cm_in_pt: 72 / 2.54, 
+			//	cm_in_pt: Number
+			//		points per centimeter (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.
+			return g._base._getCachedFontMeasurements()["12pt"] / 12;	// Number
+		},
+		pt2px: function(len){
+			//	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
+			//		a value in pixels
+			return len / g.px_in_pt();	// Number
+		},
+		normalizedLength: function(len) {
+			//	summary: converts any length value to pixels
+			//	len: String
+			//		a length, e.g., '12pc'
+			if(len.length === 0){ return 0; }
+			if(len.length > 2){
+				var px_in_pt = g.px_in_pt();
+				var val = parseFloat(len);
+				switch(len.slice(-2)){
+					case "px": return val;
+					case "pt": return val * px_in_pt;
+					case "in": return val * 72 * px_in_pt;
+					case "pc": return val * 12 * px_in_pt;
+					case "mm": return val * g.mm_in_pt * px_in_pt;
+					case "cm": return val * g.cm_in_pt * px_in_pt;
+				}
 			}
-		}
-		return parseFloat(len);	// Number
-	},
+			return parseFloat(len);	// Number
+		},
 
-	// a constant used to split a SVG/VML path into primitive components
-	pathVmlRegExp: /([A-Za-z]+)|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g,
-	pathSvgRegExp: /([A-Za-z])|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g,
+		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
+		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, b){
-		// summary: compares event sources, returns true if they are equal
-		return a && b && a == b;
-	},
-	
-	switchTo: function(renderer){
-		var ns = dojox.gfx[renderer];
-		if(ns){
-			dojo.forEach(["Group", "Rect", "Ellipse", "Circle", "Line",
-					"Polyline", "Image", "Text", "Path", "TextPath",
-					"Surface", "createSurface"], function(name){
-				dojox.gfx[name] = ns[name];
-			});
+		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
+			return a && b && a === b;
+		},
+
+		switchTo: function(renderer/*String|Object*/){
+			//	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){
+				arr.forEach(["Group", "Rect", "Ellipse", "Circle", "Line",
+						"Polyline", "Image", "Text", "Path", "TextPath",
+						"Surface", "createSurface", "fixTarget"], function(name){
+					g[name] = ns[name];
+				});
+			}
 		}
-	}
+	});
+	return g; // defaults object api
 });
diff --git a/dojox/gfx/_gfxBidiSupport.js b/dojox/gfx/_gfxBidiSupport.js
new file mode 100644
index 0000000..3ac682f
--- /dev/null
+++ b/dojox/gfx/_gfxBidiSupport.js
@@ -0,0 +1,404 @@
+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){
+	lang.getObject("dojox.gfx._gfxBidiSupport", true);
+	/*===== g = dojox.gfx; =====*/
+	switch (g.renderer){
+		case 'vml':
+			g.isVml = true;
+			break;
+		case 'svg':
+			g.isSvg = true;
+			if(g.svg.useSvgWeb){
+				g.isSvgWeb = true;
+			}
+			break;
+		case 'silverlight':
+			g.isSilverlight = true;
+			break;
+		case 'canvas':
+			g.isCanvas = true;
+			break;
+	}
+
+	var bidi_const = {
+		LRM : '\u200E',
+		LRE : '\u202A',
+		PDF : '\u202C',
+		RLM : '\u200f',
+		RLE : '\u202B'
+	};
+
+	// the object that performs text transformations.
+	var bidiEngine = new BidiEngine();
+
+	lang.extend(g.shape.Surface, {
+		// 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.
+		textDir: "",
+
+		setTextDir: function(/*String*/newTextDir){
+			// summary:
+			//		Used for propogation and change of textDir.
+			//		newTextDir will be forced as textDir for all of it's children (Group/Text/TextPath).
+			setTextDir(this, newTextDir);
+		},
+
+		getTextDir: function(){
+			return this.textDir;
+		}
+	});
+
+	lang.extend(g.Group, {                          
+		// textDir: String
+		//		Will be used for inheritance, or as default for text objects
+		//		that textDir wasn't directly specified for them but the bidi support was required.
+		textDir: "",
+
+		setTextDir: function(/*String*/newTextDir){
+			// summary:
+			//		Used for propogation and change of textDir.
+			//		newTextDir will be forced as textDir for all of it's children (Group/Text/TextPath).
+			setTextDir(this, newTextDir);
+		},
+
+		getTextDir: function(){
+			return this.textDir;
+		}	
+	});
+	
+	lang.extend(g.Text, {  
+		// summary:
+		//		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).
+		textDir: "",
+
+		formatText: function (/*String*/ text, /*String*/ textDir){
+			// 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:
+			//		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].
+
+			if(textDir && text && text.length > 1){
+			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;
+			}
+
+			if(g.isSvgWeb){
+				if(targetDir == "rtl"){
+					return bidiEngine.bidiTransform(text,"IRNNN","ILNNN");
+				}
+				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(has("chrome") || has("safari") || has("opera")){
+					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).
+		textDir: "",
+
+		formatText: function (/*String*/text, /*String*/textDir){
+			// summary: 
+			//		Applies the right transform on text, according to renderer.
+			// 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:
+			//		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].
+
+			if(textDir && text && text.length > 1){
+				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;
+				}
+				if(g.isSvgWeb){
+					if(targetDir == "rtl"){
+						return bidiEngine.bidiTransform(text,"IRNNN","ILNNN");
+					}
+					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).
+				if(g.isSvg){
+					if(has("opera")){
+						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");
+					}
+				}					
+			}	
+			return text;
+		},
+		bidiPreprocess: function(newText){
+			if(newText && (typeof newText == "string")){
+				this.origText = newText;
+				newText = this.formatText(newText,this.textDir);
+			}
+			return newText;
+		}
+	});	
+		
+	var extendMethod = function(shape, method, before, after){
+		// Some helper function. Used for extending metod of shape.
+		// shape: Object
+		//		The shape we overriding it's metod.
+		// method: String
+		//		The method that is extended, the original metod 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
+		//		If defined this function will be executed after the original method.
+		var old = shape.prototype[method];
+		shape.prototype[method] = 
+			function(){
+				var rBefore;
+				if (before){
+					rBefore = before.apply(this, arguments);
+				}
+				var r = old.call(this, rBefore);
+				if (after){
+					r = after.call(this, r, arguments);
+				}
+				return r;
+			};
+	};
+
+	var bidiPreprocess = function(newText){
+		if (newText){  
+			if (newText.textDir){
+				newText.textDir = validateTextDir(newText.textDir);
+			}
+			if (newText.text && (newText.text instanceof Array)){
+				newText.text = newText.text.join(",");
+			}
+		}
+		if(newText && (newText.text != undefined || newText.textDir) && (this.textDir != newText.textDir || newText.text != this.origText)){
+			// store the original text. 
+			this.origText = (newText.text != undefined) ? newText.text : this.origText;
+			if(newText.textDir){
+				this.textDir = newText.textDir;
+			}
+			newText.text = this.formatText(this.origText,this.textDir);
+		}
+		return this.bidiPreprocess(newText);
+
+	};
+
+	// Istead 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);
+	extendMethod(g.TextPath,"setText", bidiPreprocess, null);
+	
+	var restoreText = function(origObj){
+		var obj = lang.clone(origObj);
+		if (obj && this.origText){
+			obj.text = this.origText;
+		}
+		return obj;
+	};
+
+	// Istead 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);
+	extendMethod(g.TextPath, "getText", null, restoreText);
+
+	var groupTextDir = function(group, args){
+		var textDir;
+		if (args && args[0]){
+			textDir = validateTextDir(args[0]);
+		}
+		group.setTextDir(textDir ? textDir : this.textDir);
+		return group;	// dojox.gfx.Group				
+	};
+
+	// In creation of Group there's a need to update it's textDir,
+	// so instead of doing it in renders one by one (vml vs others)
+	// use the extendMethod, at first the original createGroup is applied, the
+	// groupTextDir which is setts Group's textDir as it's father's or if was defined
+	// by user by this value.
+	extendMethod(g.Surface, "createGroup", null, groupTextDir);
+	extendMethod(g.Group, "createGroup", null, groupTextDir);
+
+	var textDirPreprocess =  function(text){
+		//  inherit from surface / group  if textDir is defined there
+		if(text){
+			var textDir = text.textDir ? validateTextDir(text.textDir) : this.textDir;
+			if(textDir){
+				text.textDir = textDir;
+			}
+		}
+		return text;
+	};
+
+	// In creation there's a need to some preprocess,
+	// so instead of doing it in renders one by one (vml vs others)
+	// use the extendMethod, at first the textDirPreprocess function handles the input
+	// then the original createXXXXXX is applied.
+	extendMethod(g.Surface,"createText", textDirPreprocess, null);
+	extendMethod(g.Surface,"createTextPath", textDirPreprocess, null);
+	extendMethod(g.Group,"createText", textDirPreprocess, null);
+	extendMethod(g.Group,"createTextPath", textDirPreprocess, null);
+
+	g.createSurface = function(parentNode, width, height, textDir) {        
+		var s = g[g.renderer].createSurface(parentNode, width, height);
+		var tDir = validateTextDir(textDir);
+		
+		if(g.isSvgWeb){
+			s.textDir = tDir ? tDir : html.style(dom.byId(parentNode),"direction");
+			return s;
+		}
+		// if textDir was defined use it, else get default value.
+		//s.textDir = tDir ? tDir : html.style(s.rawNode,"direction");
+		if(g.isVml || g.isSvg || g.isCanvas){
+			s.textDir = tDir ? tDir : html.style(s.rawNode,"direction");
+		}
+		if(g.isSilverlight){
+			// allow this once rawNode will be able for the silverlight
+			//s.textDir = tDir ? tDir : dojo.style(s.rawNode,"direction");
+			s.textDir = tDir ? tDir : html.style(s._nodes[1],"direction");
+		}
+		
+		return s;
+	};
+
+	// some helper functions
+	
+	function setTextDir(/*Object*/ obj, /*String*/ newTextDir){
+		var tDir = validateTextDir(newTextDir);
+		if (tDir){
+			g.utils.forEach(obj,function(e){
+				if(e instanceof g.Surface || e instanceof g.Group){
+					e.textDir = tDir;
+				}		
+				if(e instanceof g.Text){
+					e.setShape({textDir: tDir});
+				}
+				if(e instanceof g.TextPath){
+					e.setText({textDir: tDir})
+				}
+			}, obj);
+		}
+		return obj;
+	}
+
+	function validateTextDir(textDir){
+		var validValues = ["ltr","rtl","auto"]; 
+		if (textDir){
+			textDir = textDir.toLowerCase();
+			if (arr.indexOf(validValues, textDir) < 0){
+				return null;
+			}
+		}
+		return textDir;
+	}
+
+	return g; // return gfx api augmented with bidi support	
+});
+
diff --git a/dojox/gfx/arc.js b/dojox/gfx/arc.js
index 6e5df46..8b233a5 100644
--- a/dojox/gfx/arc.js
+++ b/dojox/gfx/arc.js
@@ -1,16 +1,21 @@
-dojo.provide("dojox.gfx.arc");
-
-dojo.require("dojox.gfx.matrix");
+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.
+	};
+  =====*/
 
-(function(){
-	var m = dojox.gfx.matrix,
-		twoPI = 2 * Math.PI, pi4 = Math.PI / 4, pi8 = Math.PI / 8,
+	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
 		//		a an arc, which is reflected on the x axis
-		// alpha: Number: angle in radians, the arc will be 2 * angle size
+		// alpha: Number
+		//		angle in radians, the arc will be 2 * angle size
 		var cosa  = Math.cos(alpha), sina  = Math.sin(alpha),
 			p2 = {x: cosa + (4 / 3) * (1 - cosa), y: sina - (4 / 3) * cosa * (1 - cosa) / sina};
 		return {	// Object
@@ -21,22 +26,40 @@ dojo.require("dojox.gfx.matrix");
 		};
 	}
 
-	dojox.gfx.arc = {
+	var arc = g.arc = {
 		unitArcAsBezier: unitArcAsBezier,
+		/*===== 
+			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: 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.
-			// last: Object: a point-like object as a start of the arc
-			// rx: Number: a horizontal radius for the virtual ellipse
-			// ry: Number: a vertical radius for the virtual ellipse
-			// xRotg: Number: a rotation of an x axis of the virtual ellipse in degrees
-			// large: Boolean: which part of the ellipse will be used (the larger arc if true)
-			// sweep: Boolean: direction of the arc (CW if true)
-			// x: Number: the x coordinate of the end point of the arc
-			// y: Number: the y coordinate of the end point of the arc
+			// last: Object
+			//		a point-like object as a start of the arc
+			// rx: Number
+			//		a horizontal radius for the virtual ellipse
+			// ry: Number
+			//		a vertical radius for the virtual ellipse
+			// xRotg: Number
+			//		a rotation of an x axis of the virtual ellipse in degrees
+			// large: Boolean
+			//		which part of the ellipse will be used (the larger arc if true)
+			// sweep: Boolean
+			//		direction of the arc (CW if true)
+			// x: Number
+			//		the x coordinate of the end point of the arc
+			// y: Number
+			//		the y coordinate of the end point of the arc
 
 			// calculate parameters
 			large = Boolean(large);
@@ -98,8 +121,7 @@ dojo.require("dojox.gfx.matrix");
 					step  = sweep ? alpha : -alpha;
 					angle = 0;	// stop the loop
 				}
-				var c1, c2, e,
-					M = m.normalize([elliptic_transform, m.rotate(startAngle + step)]);
+				var c2, e, M = m.normalize([elliptic_transform, m.rotate(startAngle + step)]);
 				if(sweep){
 					c1 = m.multiplyPoint(M, curve.c1);
 					c2 = m.multiplyPoint(M, curve.c2);
@@ -116,4 +138,6 @@ dojo.require("dojox.gfx.matrix");
 			return result;	// Array
 		}
 	};
-})();
+	
+	return arc;
+});
diff --git a/dojox/gfx/attach.js b/dojox/gfx/attach.js
index f306b59..c281a1c 100644
--- a/dojox/gfx/attach.js
+++ b/dojox/gfx/attach.js
@@ -1,11 +1,10 @@
-dojo.provide("dojox.gfx.attach");
-
-dojo.require("dojox.gfx");
-
-// rename an attacher conditionally
-
-(function(){
+define(["dojox/gfx"], function(){
+	// TODO: the current implementation is not functional, please implement correctly
+	/*
+	dojo.getObject("dojox.gfx.arc", true);
 	var r = dojox.gfx.svg.attach[dojox.gfx.renderer];
 	dojo.gfx.attachSurface = r.attachSurface;
 	dojo.gfx.attachNode = r.attachNode;
-})();
+	return r;
+	*/
+});
diff --git a/dojox/gfx/canvas.js b/dojox/gfx/canvas.js
index 26061fe..badc57f 100644
--- a/dojox/gfx/canvas.js
+++ b/dojox/gfx/canvas.js
@@ -1,19 +1,48 @@
-dojo.provide("dojox.gfx.canvas");
-
-dojo.require("dojox.gfx._base");
-dojo.require("dojox.gfx.shape");
-dojo.require("dojox.gfx.path");
-dojo.require("dojox.gfx.arc");
-dojo.require("dojox.gfx.decompose");
-
-dojo.experimental("dojox.gfx.canvas");
-
-(function(){
-	var d = dojo, g = dojox.gfx, gs = g.shape, ga = g.arc, canvas = g.canvas,
-		m = g.matrix, mp = m.multiplyPoint, pi = Math.PI, twoPI = 2 * pi, halfPI = pi /2,
-		pattrnbuffer = null;
-
-	d.declare("dojox.gfx.canvas.Shape", gs.Shape, {
+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.
+	};
+	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, 
+		halfPI = pi /2,
+		extend = lang.extend;
+
+	declare("dojox.gfx.canvas.Shape", gs.Shape, {
 		_render: function(/* Object */ ctx){
 			// summary: render the shape
 			ctx.save();
@@ -132,7 +161,7 @@ dojo.experimental("dojox.gfx.canvas");
 							f = fs.type == "linear" ?
 								ctx.createLinearGradient(fs.x1, fs.y1, fs.x2, fs.y2) :
 								ctx.createRadialGradient(fs.cx, fs.cy, 0, fs.cx, fs.cy, fs.r);
-							d.forEach(fs.colors, function(step){
+							arr.forEach(fs.colors, function(step){
 								f.addColorStop(step.offset, g.normalizeColor(step.color).toString());
 							});
 							break;
@@ -160,7 +189,7 @@ dojo.experimental("dojox.gfx.canvas");
 	modifyMethod(canvas.Shape, "setStroke");
 	modifyMethod(canvas.Shape, "setShape");
 
-	dojo.declare("dojox.gfx.canvas.Group", canvas.Shape, {
+	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(){
@@ -177,7 +206,7 @@ dojo.experimental("dojox.gfx.canvas");
 		}
 	});
 
-	dojo.declare("dojox.gfx.canvas.Rect", [canvas.Shape, gs.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),
@@ -210,7 +239,7 @@ dojo.experimental("dojox.gfx.canvas");
 		}
 	})();
 
-	dojo.declare("dojox.gfx.canvas.Ellipse", [canvas.Shape, gs.Ellipse], {
+	declare("dojox.gfx.canvas.Ellipse", [canvas.Shape, gs.Ellipse], {
 		// summary: an ellipse shape (Canvas)
 		setShape: function(){
 			this.inherited(arguments);
@@ -239,7 +268,7 @@ dojo.experimental("dojox.gfx.canvas");
 		}
 	});
 
-	dojo.declare("dojox.gfx.canvas.Circle", [canvas.Shape, gs.Circle], {
+	declare("dojox.gfx.canvas.Circle", [canvas.Shape, gs.Circle], {
 		// summary: a circle shape (Canvas)
 		_renderShape: function(/* Object */ ctx){
 			var s = this.shape;
@@ -248,7 +277,7 @@ dojo.experimental("dojox.gfx.canvas");
 		}
 	});
 
-	dojo.declare("dojox.gfx.canvas.Line", [canvas.Shape, gs.Line], {
+	declare("dojox.gfx.canvas.Line", [canvas.Shape, gs.Line], {
 		// summary: a line shape (Canvas)
 		_renderShape: function(/* Object */ ctx){
 			var s = this.shape;
@@ -258,28 +287,29 @@ dojo.experimental("dojox.gfx.canvas");
 		}
 	});
 
-	dojo.declare("dojox.gfx.canvas.Polyline", [canvas.Shape, gs.Polyline], {
+	declare("dojox.gfx.canvas.Polyline", [canvas.Shape, gs.Polyline], {
 		// summary: a polyline/polygon shape (Canvas)
 		setShape: function(){
 			this.inherited(arguments);
-			// prepare Canvas-specific structures
-			var p = this.shape.points, f = p[0], r = [], c, i;
-			if(p.length){
-				if(typeof f == "number"){
-					r.push(f, p[1]);
-					i = 2;
-				}else{
-					r.push(f.x, f.y);
-					i = 1;
-				}
-				for(; i < p.length; ++i){
-					c = p[i];
-					if(typeof c == "number"){
-						r.push(c, p[++i]);
-					}else{
+			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 
+			// and p references the original points array
+			// prepare Canvas-specific structures, if needed
+			if(p.length){  
+				if(typeof f == "number"){ // already in the canvas format [x1,y1,x2,y2,...]
+					r = p; 
+				}else{ // convert into canvas-specific format
+					r = [];
+					for(i=0; i < p.length; ++i){
+						c = p[i];
 						r.push(c.x, c.y);
 					}
 				}
+			}else{
+				r = [];
 			}
 			this.canvasPolyline = r;
 			return this;
@@ -296,7 +326,7 @@ dojo.experimental("dojox.gfx.canvas");
 		}
 	});
 
-	dojo.declare("dojox.gfx.canvas.Image", [canvas.Shape, gs.Image], {
+	declare("dojox.gfx.canvas.Image", [canvas.Shape, gs.Image], {
 		// summary: an image shape (Canvas)
 		setShape: function(){
 			this.inherited(arguments);
@@ -312,7 +342,7 @@ dojo.experimental("dojox.gfx.canvas");
 		}
 	});
 	
-	dojo.declare("dojox.gfx.canvas.Text", [canvas.Shape, gs.Text], {
+	declare("dojox.gfx.canvas.Text", [canvas.Shape, gs.Text], {
 		_setFont:function(){
 			if (this.fontStyle){
 				this.canvasFont = g.makeFontString(this.fontStyle);
@@ -378,13 +408,18 @@ dojo.experimental("dojox.gfx.canvas");
 	modifyMethod(canvas.Text, "setFont");
 	
 	// the next test is from https://github.com/phiggins42/has.js
-	if(typeof dojo.doc.createElement("canvas").getContext("2d").fillText != "function"){
-		canvas.Text.extend({
-			getTextWidth: function(){
-				return 0;
-			},
-			_renderShape: function(){}
-		});
+	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(){
+				}
+			});
+		}
 	}
 	
 
@@ -401,7 +436,7 @@ dojo.experimental("dojox.gfx.canvas");
 			Z: "_closePath", z: "_closePath"
 		};
 
-	dojo.declare("dojox.gfx.canvas.Path", [canvas.Shape, g.path.Path], {
+	declare("dojox.gfx.canvas.Path", [canvas.Shape, pathLib.Path], {
 		// summary: a path shape (Canvas)
 		constructor: function(){
 			this.lastControl = {};
@@ -411,7 +446,7 @@ dojo.experimental("dojox.gfx.canvas");
 			return this.inherited(arguments);
 		},
 		_updateWithSegment: function(segment){
-			var last = d.clone(this.last);
+			var last = lang.clone(this.last);
 			this[pathRenderers[segment.action]](this.canvasPath, segment.action, segment.args);
 			this.last = last;
 			this.inherited(arguments);
@@ -608,7 +643,7 @@ dojo.experimental("dojox.gfx.canvas");
 					args[i + 3] ? 1 : 0, args[i + 4] ? 1 : 0,
 					x1, y1
 				);
-				d.forEach(arcs, function(p){
+				arr.forEach(arcs, function(p){
 					result.push("bezierCurveTo", p);
 				});
 				this.last.x = x1;
@@ -621,12 +656,12 @@ dojo.experimental("dojox.gfx.canvas");
 			this.lastControl = {};
 		}
 	});
-	d.forEach(["moveTo", "lineTo", "hLineTo", "vLineTo", "curveTo",
+	arr.forEach(["moveTo", "lineTo", "hLineTo", "vLineTo", "curveTo",
 		"smoothCurveTo", "qCurveTo", "qSmoothCurveTo", "arcTo", "closePath"],
 		function(method){ modifyMethod(canvas.Path, method); }
 	);
 
-	dojo.declare("dojox.gfx.canvas.TextPath", [canvas.Shape, g.path.TextPath], {
+	declare("dojox.gfx.canvas.TextPath", [canvas.Shape, pathLib.TextPath], {
 		// summary: a text shape (Canvas)
 		_renderShape: function(/* Object */ ctx){
 			var s = this.shape;
@@ -640,7 +675,7 @@ dojo.experimental("dojox.gfx.canvas");
 		}
 	});
 
-	dojo.declare("dojox.gfx.canvas.Surface", gs.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);
@@ -654,9 +689,17 @@ dojo.experimental("dojox.gfx.canvas");
 			this.width  = g.normalizedLength(width);	// in pixels
 			this.height = g.normalizedLength(height);	// in pixels
 			if(!this.rawNode) return this;
-			this.rawNode.width = width;
-			this.rawNode.height = height;
-			this.makeDirty();
+			var dirty = false;
+			if (this.rawNode.width != this.width){
+				this.rawNode.width = this.width;
+				dirty = true;
+			}
+			if (this.rawNode.height != this.height){
+				this.rawNode.height = this.height;
+				dirty = true;
+			}
+			if (dirty)
+				this.makeDirty();
 			return this;	// self
 		},
 		getDimensions: function(){
@@ -681,7 +724,7 @@ dojo.experimental("dojox.gfx.canvas");
 		makeDirty: function(){
 			// summary: internal method, which is called when we may need to redraw
 			if(!this.pendingImagesCount && !("pendingRender" in this)){
-				this.pendingRender = setTimeout(d.hitch(this, this._render), 0);
+				this.pendingRender = setTimeout(lang.hitch(this, this._render), 0);
 			}
 		},
 		downloadImage: function(img, url){
@@ -691,7 +734,7 @@ dojo.experimental("dojox.gfx.canvas");
 			//		the image object
 			// url: String:
 			//		the url of the image
-			var handler = d.hitch(this, this.onImageLoad);
+			var handler = lang.hitch(this, this.onImageLoad);
 			if(!this.pendingImageCount++ && "pendingRender" in this){
 				clearTimeout(this.pendingRender);
 				delete this.pendingRender;
@@ -718,7 +761,7 @@ dojo.experimental("dojox.gfx.canvas");
 		// height: String: height of surface, e.g., "100px"
 
 		if(!width && !height){
-			var pos = d.position(parentNode);
+			var pos = domGeom.position(parentNode);
 			width  = width  || pos.w;
 			height = height || pos.h;
 		}
@@ -730,7 +773,7 @@ dojo.experimental("dojox.gfx.canvas");
 		}
 
 		var s = new canvas.Surface(),
-			p = d.byId(parentNode),
+			p = dom.byId(parentNode),
 			c = p.ownerDocument.createElement("canvas");
 
 		c.width  = g.normalizedLength(width);	// in pixels
@@ -783,17 +826,18 @@ dojo.experimental("dojox.gfx.canvas");
 		}
 	};
 
-	d.extend(canvas.Group, Container);
-	d.extend(canvas.Group, gs.Creator);
-	d.extend(canvas.Group, Creator);
+	extend(canvas.Group, Container);
+	extend(canvas.Group, gs.Creator);
+	extend(canvas.Group, Creator);
 
-	d.extend(canvas.Surface, Container);
-	d.extend(canvas.Surface, gs.Creator);
-	d.extend(canvas.Surface, Creator);
+	extend(canvas.Surface, Container);
+	extend(canvas.Surface, gs.Creator);
+	extend(canvas.Surface, Creator);
 	
-	// see if we are required to initilize
-	if(g.loadAndSwitch === "canvas"){
-		g.switchTo("canvas");
-		delete g.loadAndSwitch;
-	}
-})();
+	// no event support -> nothing to fix. 
+	canvas.fixTarget = function(event, gfxElement){
+		return true;
+	};
+	 
+	return canvas;
+});
diff --git a/dojox/gfx/canvasWithEvents.js b/dojox/gfx/canvasWithEvents.js
new file mode 100644
index 0000000..4a6902a
--- /dev/null
+++ b/dojox/gfx/canvasWithEvents.js
@@ -0,0 +1,642 @@
+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.	
+	};
+	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) {
+				// pixel-based until a getStrokedPath-like api is available on the path
+				this._hitTestPixel(ctx, pos);
+			} else {
+				this._renderShape(ctx);
+				var cnt = pos.length, t = this.getTransform();
+				for (var i = 0; i < pos.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
+					};
+					input.target = this._hitTestGeometry(ctx, p.x, p.y);
+				}
+			}
+		},
+		_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;
+				ctx.clearRect(0,0,1,1);
+				ctx.save();
+				ctx.translate(-x, -y);
+				this._render(ctx, true);
+				input.target = ctx.getImageData(0, 0, 1, 1).data[0] ? this : null;
+				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
+			// ctx:
+			//		a canvas context object
+			// apply:
+			//		whether ctx.fill() shall be called
+			if(ctx.pickingMode){
+				if("canvasFill" in this && apply){ ctx.fill(); }
+				return;
+			}
+			this.inherited(arguments);
+		},
+		_renderStroke: function(/* Object */ ctx, /* Boolean */ apply){
+			// summary:
+			//		render stroke for the shape
+			// ctx:
+			//		a canvas context object
+			// apply:
+			//		whether ctx.stroke() shall be called
+			if (this.strokeStyle && ctx.pickingMode) {
+				var c = this.strokeStyle.color;
+				try {
+					this.strokeStyle.color = new Color(ctx.strokeStyle);
+					this.inherited(arguments);
+				} finally {
+					this.strokeStyle.color = c;
+				}
+			} 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();
+		},
+		
+		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);
+		},
+		disconnect: function(token){
+			// summary: disconnects an event handler
+			hub.disconnect(token);
+		},
+		// 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(){}
+	});
+	
+	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){
+				return;
+			}
+			var posbk = [];
+			for(i = 0; i < pos.length; ++i){
+				var input = pos[i];
+				// backup position before transform applied
+				posbk[i] = {
+					x: input.x,
+					y: input.y
+				};
+				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
+				};
+				input.x = p.x;
+				input.y = p.y;
+			}
+			for(i = children.length - 1; i >= 0; --i){
+				children[i]._testInputs(ctx, pos);
+				// does it need more hit tests ?
+				var allFound = true;
+				for(j = 0; j < pos.length; ++j){
+					if(pos[j].target == null){
+						allFound = false;
+						break;
+					}
+				}
+				if(allFound){
+					break;
+				}
+			}
+			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], {
+		_renderShape: function(/* Object */ ctx){
+			// summary:
+			//		render image
+			// ctx:
+			//		a canvas context object
+			var s = this.shape;
+			if(ctx.pickingMode){
+				ctx.fillRect(s.x, s.y, s.width, s.height);
+			}else{
+				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], {
+		_testInputs: function(ctx, pos){
+			return this._hitTestPixel(ctx, pos);
+		}
+	});
+
+
+	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));
+			}	
+		},
+
+		// 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;
+			}
+		},
+
+		_setupEvents: function(eventName){
+			// summary: 
+			//		setup event listeners if not yet
+
+			// 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"));
+				}
+			 	if(!this._eventsH['onmouseup']){
+					this._eventsH['onmouseup'] = hub.connect(this.getEventSource(),
+							'onmouseup', shapeLib.fixCallback(this, g.fixTarget, this, "_onmouseup"));
+				}
+			} 			
+		},
+		
+		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;
+		},
+
+		// 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]);
+				}
+			}
+			if(!handler && method.indexOf('touch') !== -1){
+				// special case for surface touch handlers
+				method = "_" + method + "Impl_";
+				handler = base[method];
+				if(handler){
+					handler.apply(base, [event]);
+				}
+			}
+			// 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);
+			}
+		},
+		_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);
+			}
+			
+		},
+		_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);
+			}
+		},
+		_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);
+					}
+				}
+			}
+		},
+		_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);
+				}
+			}
+		},
+		_ontouchmove: function(e){
+			// summary: triggers ontouchmove
+			if(this._pick.curr){
+				this._fireTouchEvent(e);
+			}
+		},
+		
+		_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;
+					}
+				}
+			}
+			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);
+				}
+			}
+		},
+		_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 mirror = surface.mirrorCanvas,
+				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;
+			// process the inputs to find the target.
+			for(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){
+					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"
+
+		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");
+
+		c.width  = g.normalizedLength(width);	// in pixels
+		c.height = g.normalizedLength(height);	// in pixels
+
+		p.appendChild(c);
+		s.rawNode = c;
+		s._parent = p;
+		s.surface = s;
+		return s;	// dojox.gfx.Surface
+	};
+
+
+	// 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;
+		}
+		return true;
+	};
+
+	return canvasEvent;
+});
diff --git a/dojox/gfx/canvas_attach.js b/dojox/gfx/canvas_attach.js
index 85e846c..3558745 100644
--- a/dojox/gfx/canvas_attach.js
+++ b/dojox/gfx/canvas_attach.js
@@ -1,10 +1,11 @@
-dojo.provide("dojox.gfx.canvas_attach");
+define(["dojo/_base/lang", "dojo/_base/kernel","dojox/gfx/canvas"], function(lang,kernel,canvas){
+	lang.getObject("dojox.gfx.canvas_attach", true);
+	kernel.experimental("dojox.gfx.canvas_attach");
 
-dojo.require("dojox.gfx.canvas");
+	// not implemented
+	canvas.attachSurface = canvas.attachNode = function(){
+		return null;	// for now
+	};
 
-dojo.experimental("dojox.gfx.canvas_attach");
-
-// not implemented
-dojox.gfx.canvas.attachSurface = dojox.gfx.canvas.attachNode = function(){
-	return null;	// for now
-};
+	return canvas;
+});
diff --git a/dojox/gfx/decompose.js b/dojox/gfx/decompose.js
index 8e91e5a..df03c0d 100644
--- a/dojox/gfx/decompose.js
+++ b/dojox/gfx/decompose.js
@@ -1,10 +1,6 @@
-dojo.provide("dojox.gfx.decompose");
-
-dojo.require("dojox.gfx.matrix");
-
-(function(){
-	var m = dojox.gfx.matrix;
-
+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
 		return Math.abs(a - b) <= 1e-6 * (Math.abs(a) + Math.abs(b));	// Boolean
@@ -17,14 +13,14 @@ dojo.require("dojox.gfx.matrix");
 		}else if(!isFinite(r2)){
 			return r1;	// Number
 		}
-		m1 = Math.abs(m1), m2 = Math.abs(m2);
+		m1 = Math.abs(m1); m2 = Math.abs(m2);
 		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
 		var M = new m.Matrix2D(matrix);
-		return dojo.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){
@@ -96,9 +92,9 @@ dojo.require("dojox.gfx.matrix");
 		return result;	// Object
 	}
 
-	dojox.gfx.decompose = function(matrix){
-		// summary: decompose a 2D matrix into translation, scaling, and rotation components
-		// description: this function decompose a matrix into four logical components:
+	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:
 		//	| [translate, rotate(angle2), scale, rotate(angle1)]
@@ -107,7 +103,7 @@ dojo.require("dojox.gfx.matrix");
 			result = {dx: M.dx, dy: M.dy, sx: 1, sy: 1, angle1: 0, angle2: 0};
 		// detect case: [scale]
 		if(eq(M.xy, 0) && eq(M.yx, 0)){
-			return dojo.mixin(result, {sx: M.xx, sy: M.yy});	// Object
+			return lang.mixin(result, {sx: M.xx, sy: M.yy});	// Object
 		}
 		// detect case: [scale, rotate]
 		if(eq(M.xx * M.yx, -M.xy * M.yy)){
@@ -130,6 +126,6 @@ dojo.require("dojox.gfx.matrix");
 		decomposeRS(U, result);
 		S.xx *= result.sx;
 		S.yy *= result.sy;
-		return dojo.mixin(result, {sx: S.xx, sy: S.yy});	// Object
+		return lang.mixin(result, {sx: S.xx, sy: S.yy});	// Object
 	};
-})();
+});
diff --git a/dojox/gfx/fx.js b/dojox/gfx/fx.js
index 1d783c6..7603aa2 100644
--- a/dojox/gfx/fx.js
+++ b/dojox/gfx/fx.js
@@ -1,9 +1,7 @@
-dojo.provide("dojox.gfx.fx");
-
-dojo.require("dojox.gfx.matrix");
-
-(function(){
-	var d = dojo, g = dojox.gfx, m = g.matrix;
+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){
+	var fxg = g.fx = {};
+	/*===== g = dojox.gfx; fxg = dojox.gfx.fx; =====*/
 
 	// Generic interpolators. Should they be moved to dojox.fx?
 
@@ -24,10 +22,10 @@ dojo.require("dojox.gfx.matrix");
 
 	function InterpolColor(start, end){
 		this.start = start, this.end = end;
-		this.temp = new dojo.Color();
+		this.temp = new Color();
 	}
 	InterpolColor.prototype.getValue = function(r){
-		return d.blendColors(this.start, this.end, r, this.temp);
+		return Color.blendColors(this.start, this.end, r, this.temp);
 	};
 
 	function InterpolValues(values){
@@ -43,7 +41,7 @@ dojo.require("dojox.gfx.matrix");
 		this.def = def ? def : {};
 	}
 	InterpolObject.prototype.getValue = function(r){
-		var ret = dojo.clone(this.def);
+		var ret = lang.clone(this.def);
 		for(var i in this.values){
 			ret[i] = this.values[i].getValue(r);
 		}
@@ -56,7 +54,7 @@ dojo.require("dojox.gfx.matrix");
 	}
 	InterpolTransform.prototype.getValue = function(r){
 		var ret = [];
-		dojo.forEach(this.stack, function(t){
+		arr.forEach(this.stack, function(t){
 			if(t instanceof m.Matrix2D){
 				ret.push(t);
 				return;
@@ -72,7 +70,7 @@ dojo.require("dojox.gfx.matrix");
 				ret.push(f);
 				return;
 			}
-			var val = dojo.map(t.start, function(v, i){
+			var val = arr.map(t.start, function(v, i){
 							return (t.end[i] - v) * r + v;
 						}),
 				matrix = f.apply(m, val);
@@ -83,7 +81,7 @@ dojo.require("dojox.gfx.matrix");
 		return ret;
 	};
 
-	var transparent = new d.Color(0, 0, 0, 0);
+	var transparent = new Color(0, 0, 0, 0);
 
 	function getColorInterpol(prop, obj, name, def){
 		if(prop.values){
@@ -127,9 +125,9 @@ dojo.require("dojox.gfx.matrix");
 		return new InterpolNumber(start, end);
 	}
 
-	g.fx.animateStroke = function(/*Object*/ args){
+	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.
 		// example:
 		//	|	dojox.gfx.fx.animateStroke{{
 		//	|		shape: shape,
@@ -138,9 +136,9 @@ dojo.require("dojox.gfx.matrix");
 		//	|		width: {end: 15},
 		//	|		join:  {values: ["miter", "bevel", "round"]}
 		//	|	}).play();
-		if(!args.easing){ args.easing = d._defaultEasing; }
-		var anim = new d.Animation(args), shape = args.shape, stroke;
-		d.connect(anim, "beforeBegin", anim, function(){
+		if(!args.easing){ args.easing = fx._defaultEasing; }
+		var anim = new fx.Animation(args), shape = args.shape, stroke;
+		Hub.connect(anim, "beforeBegin", anim, function(){
 			stroke = shape.getStroke();
 			var prop = args.color, values = {}, value, start, end;
 			if(prop){
@@ -172,11 +170,11 @@ dojo.require("dojox.gfx.matrix");
 			}
 			this.curve = new InterpolObject(values, stroke);
 		});
-		d.connect(anim, "onAnimate", shape, "setStroke");
+		Hub.connect(anim, "onAnimate", shape, "setStroke");
 		return anim; // dojo.Animation
 	};
 
-	g.fx.animateFill = function(/*Object*/ args){
+	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
@@ -186,22 +184,22 @@ dojo.require("dojox.gfx.matrix");
 		//	|		duration: 500,
 		//	|		color: {start: "red", end: "green"}
 		//	|	}).play();
-		if(!args.easing){ args.easing = d._defaultEasing; }
-		var anim = new d.Animation(args), shape = args.shape, fill;
-		d.connect(anim, "beforeBegin", anim, function(){
+		if(!args.easing){ args.easing = fx._defaultEasing; }
+		var anim = new fx.Animation(args), shape = args.shape, fill;
+		Hub.connect(anim, "beforeBegin", anim, function(){
 			fill = shape.getFill();
 			var prop = args.color, values = {};
 			if(prop){
 				this.curve = getColorInterpol(prop, fill, "", transparent);
 			}
 		});
-		d.connect(anim, "onAnimate", shape, "setFill");
+		Hub.connect(anim, "onAnimate", shape, "setFill");
 		return anim; // dojo.Animation
 	};
 
-	g.fx.animateFont = function(/*Object*/ args){
+	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.
 		// example:
 		//	|	dojox.gfx.fx.animateFont{{
 		//	|		shape: shape,
@@ -209,9 +207,9 @@ dojo.require("dojox.gfx.matrix");
 		//	|		variant: {values: ["normal", "small-caps"]},
 		//	|		size:  {end: 10, units: "pt"}
 		//	|	}).play();
-		if(!args.easing){ args.easing = d._defaultEasing; }
-		var anim = new d.Animation(args), shape = args.shape, font;
-		d.connect(anim, "beforeBegin", anim, function(){
+		if(!args.easing){ args.easing = fx._defaultEasing; }
+		var anim = new fx.Animation(args), shape = args.shape, font;
+		Hub.connect(anim, "beforeBegin", anim, function(){
 			font = shape.getFont();
 			var prop = args.style, values = {}, value, start, end;
 			if(prop && prop.values){
@@ -237,13 +235,13 @@ dojo.require("dojox.gfx.matrix");
 			}
 			this.curve = new InterpolObject(values, font);
 		});
-		d.connect(anim, "onAnimate", shape, "setFont");
+		Hub.connect(anim, "onAnimate", shape, "setFont");
 		return anim; // dojo.Animation
 	};
 
-	g.fx.animateTransform = function(/*Object*/ args){
+	fxg.animateTransform = function(/*Object*/ args){
 		// summary:
-		//	Returns an animation which will change transformation over time
+		//	Returns an animation which will change transformation over time.
 		// example:
 		//	|	dojox.gfx.fx.animateTransform{{
 		//	|		shape: shape,
@@ -253,13 +251,15 @@ dojo.require("dojox.gfx.matrix");
 		//	|			{name: "original"}
 		//	|		]
 		//	|	}).play();
-		if(!args.easing){ args.easing = d._defaultEasing; }
-		var anim = new d.Animation(args), shape = args.shape, original;
-		d.connect(anim, "beforeBegin", anim, function(){
+		if(!args.easing){ args.easing = fx._defaultEasing; }
+		var anim = new fx.Animation(args), shape = args.shape, original;
+		Hub.connect(anim, "beforeBegin", anim, function(){
 			original = shape.getTransform();
 			this.curve = new InterpolTransform(args.transform, original);
 		});
-		d.connect(anim, "onAnimate", shape, "setTransform");
+		Hub.connect(anim, "onAnimate", shape, "setTransform");
 		return anim; // dojo.Animation
 	};
-})();
+	
+	return fxg;
+});
diff --git a/dojox/gfx/gradient.js b/dojox/gfx/gradient.js
index ee5847e..85d0311 100644
--- a/dojox/gfx/gradient.js
+++ b/dojox/gfx/gradient.js
@@ -1,23 +1,21 @@
-dojo.provide("dojox.gfx.gradient");
-
-dojo.require("dojox.gfx.matrix");
-
+define(["dojo/_base/lang", "./matrix", "dojo/_base/Color"], 
+  function(lang, m, Color){
 // Various utilities to deal with a linear gradient (mostly VML-specific)
-
-(function(){
-	var d = dojo, m = dojox.gfx.matrix, C = d.Color;
+	var grad = lang.getObject("dojox.gfx.gradient", true);
+	var C = Color;
+	/*===== grad = dojox.gfx.gradient;  =====*/
 	
-	dojox.gfx.gradient.rescale = function(stops, from, to){
+	grad.rescale = function(stops, from, to){
 		// summary:
-		//		recalculates a gradient from 0-1 window to
+		//		Recalculates a gradient from 0-1 window to
 		//		"from"-"to" window blending and replicating colors,
-		//		if necessary
-		// stops: Array:
+		//		if necessary.
+		// stops: Array
 		//		input gradient as a list of colors with offsets
 		//		(see dojox.gfx.defaultLinearGradient and dojox.gfx.defaultRadialGradient)
-		// from: Number:
+		// from: Number
 		//		the beginning of the window, should be less than "to"
-		// to: Number:
+		// to: Number
 		//		the end of the window, should be more than "from"
 
 		var len = stops.length, reverseFlag = (to < from), newStops;
@@ -64,7 +62,7 @@ dojo.require("dojox.gfx.matrix");
 				prev = stops[i - 1];
 				newStops.push({
 					offset: 0,
-					color: d.blendColors(new C(prev.color), new C(stop.color), (from - prev.offset) / (stop.offset - prev.offset))
+					color: Color.blendColors(new C(prev.color), new C(stop.color), (from - prev.offset) / (stop.offset - prev.offset))
 				});
 			}else{
 				newStops.push({offset: 0, color: new C(stop.color)});
@@ -80,7 +78,7 @@ dojo.require("dojox.gfx.matrix");
 				prev = stops[i - 1];
 				newStops.push({
 					offset: 1,
-					color: d.blendColors(new C(prev.color), new C(stop.color), (to - prev.offset) / (stop.offset - prev.offset))
+					color: Color.blendColors(new C(prev.color), new C(stop.color), (to - prev.offset) / (stop.offset - prev.offset))
 				});
 			}else{
 				newStops.push({offset: 1, color: new C(stops[len - 1].color)});
@@ -109,12 +107,12 @@ dojo.require("dojox.gfx.matrix");
 		return a.o - b.o;
 	}
 	
-	dojox.gfx.gradient.project = function(matrix, grad, tl, rb, ttl, trb){
+	grad.project = function(matrix, gradient, tl, rb, ttl, trb){
 		// summary:
-		//		return a new gradient using the "VML algorithm" and suitable for VML
+		//		Returns a new gradient using the "VML algorithm" and suitable for VML.
 		// matrix: dojox.gfx.Matrix2D|Null:
 		//		matrix to apply to a shape and its gradient
-		// grad: Object:
+		// gradient: Object:
 		//		a linear gradient object to be transformed
 		// tl: dojox.gfx.Point:
 		//		top-left corner of shape's bounding box
@@ -127,8 +125,8 @@ dojo.require("dojox.gfx.matrix");
 		
 		matrix = matrix || m.identity;
 
-		var f1 = m.multiplyPoint(matrix, grad.x1, grad.y1),
-			f2 = m.multiplyPoint(matrix, grad.x2, grad.y2),
+		var f1 = m.multiplyPoint(matrix, gradient.x1, gradient.y1),
+			f2 = m.multiplyPoint(matrix, gradient.x2, gradient.y2),
 			angle = Math.atan2(f2.y - f1.y, f2.x - f1.x),
 			project = m.project(f2.x - f1.x, f2.y - f1.y),
 			pf1 = m.multiplyPoint(project, f1),
@@ -145,7 +143,7 @@ dojo.require("dojox.gfx.matrix");
 				].sort(sortPoints),
 			from = points[0].o,
 			to   = points[3].o,
-			stops = dojox.gfx.gradient.rescale(grad.colors, from, to),
+			stops = grad.rescale(gradient.colors, from, to),
 			//angle2 = Math.atan2(Math.abs(points[3].r.y - points[0].r.y) * (f2.y - f1.y), Math.abs(points[3].r.x - points[0].r.x) * (f2.x - f1.x));
 			angle2 = Math.atan2(points[3].r.y - points[0].r.y, points[3].r.x - points[0].r.x);
 
@@ -157,4 +155,6 @@ dojo.require("dojox.gfx.matrix");
 			angle: angle
 		};
 	};
-})();
+	
+	return grad;
+});
diff --git a/dojox/gfx/gradutils.js b/dojox/gfx/gradutils.js
index 2ec00e1..7dd9771 100644
--- a/dojox/gfx/gradutils.js
+++ b/dojox/gfx/gradutils.js
@@ -1,12 +1,12 @@
-dojo.provide("dojox.gfx.gradutils");
-
-dojo.require("dojox.gfx.matrix");
-
 // Various generic utilities to deal with a linear gradient
 
-(function(){
-	var d = dojo, m = dojox.gfx.matrix, C = d.Color;
-	
+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){
 			return c[0].color;
@@ -21,7 +21,7 @@ dojo.require("dojox.gfx.matrix");
 			if(stop.offset >= o){
 				if(i){
 					var prev = c[i - 1];
-					return d.blendColors(new C(prev.color), new C(stop.color),
+					return Color.blendColors(new Color(prev.color), new Color(stop.color),
 						(o - prev.offset) / (stop.offset - prev.offset));
 				}
 				return stop.color;
@@ -30,7 +30,7 @@ dojo.require("dojox.gfx.matrix");
 		return c[len - 1].color;
 	}
 
-	dojox.gfx.gradutils.getColor = function(fill, pt){
+	gradutils.getColor = function(fill, pt){
 		// summary:
 		//		sample a color from a gradient using a point
 		// fill: Object:
@@ -47,21 +47,21 @@ dojo.require("dojox.gfx.matrix");
 						p = m.multiplyPoint(projection, pt),
 						pf1 = m.multiplyPoint(projection, fill.x1, fill.y1),
 						pf2 = m.multiplyPoint(projection, fill.x2, fill.y2),
-						scale = m.multiplyPoint(rotation, pf2.x - pf1.x, pf2.y - pf1.y).x,
-						o = m.multiplyPoint(rotation, p.x - pf1.x, p.y - pf1.y).x / scale;
+						scale = m.multiplyPoint(rotation, pf2.x - pf1.x, pf2.y - pf1.y).x;
+					o = m.multiplyPoint(rotation, p.x - pf1.x, p.y - pf1.y).x / scale;
 					break;
 				case "radial":
-					var dx = pt.x - fill.cx, dy = pt.y - fill.cy,
-						o = Math.sqrt(dx * dx + dy * dy) / fill.r;
+					var dx = pt.x - fill.cx, dy = pt.y - fill.cy;
+					o = Math.sqrt(dx * dx + dy * dy) / fill.r;
 					break;
 			}
 			return findColor(o, fill.colors);	// dojo.Color
 		}
 		// simple color
-		return new C(fill || [0, 0, 0, 0]);	// dojo.Color
+		return new Color(fill || [0, 0, 0, 0]);	// dojo.Color
 	};
 
-	dojox.gfx.gradutils.reverse = function(fill){
+	gradutils.reverse = function(fill){
 		// summary:
 		//		reverses a gradient
 		// fill: Object:
@@ -70,7 +70,7 @@ dojo.require("dojox.gfx.matrix");
 			switch(fill.type){
 				case "linear":
 				case "radial":
-					fill = dojo.delegate(fill);
+					fill = lang.delegate(fill);
 					if(fill.colors){
 						var c = fill.colors, l = c.length, i = 0, stop,
 							n = fill.colors = new Array(c.length);
@@ -88,4 +88,6 @@ dojo.require("dojox.gfx.matrix");
 		}
 		return fill;	// Object
 	};
-})();
+
+	return gradutils;
+});
diff --git a/dojox/gfx/matrix.js b/dojox/gfx/matrix.js
index 45b0855..5e0a2d8 100644
--- a/dojox/gfx/matrix.js
+++ b/dojox/gfx/matrix.js
@@ -1,7 +1,7 @@
-dojo.provide("dojox.gfx.matrix");
-
-(function(){
-	var m = dojox.gfx.matrix;
+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,7 +11,8 @@ dojo.provide("dojox.gfx.matrix");
 	m._radToDeg = function(radian){ return radian / Math.PI * 180; };
 
 	m.Matrix2D = function(arg){
-		// summary: a 2D matrix object
+		// summary: 
+		//		a 2D matrix object
 		// description: Normalizes a 2D matrix-like object. If arrays is passed,
 		//		all objects of the array are normalized and multiplied sequentially.
 		// arg: Object
@@ -24,7 +25,7 @@ dojo.provide("dojox.gfx.matrix");
 					var matrix = m.normalize(arg[0]);
 					// combine matrices
 					for(var i = 1; i < arg.length; ++i){
-						var l = matrix, r = dojox.gfx.matrix.normalize(arg[i]);
+						var l = matrix, r = m.normalize(arg[i]);
 						matrix = new m.Matrix2D();
 						matrix.xx = l.xx * r.xx + l.xy * r.yx;
 						matrix.xy = l.xx * r.xy + l.xy * r.yy;
@@ -33,18 +34,18 @@ dojo.provide("dojox.gfx.matrix");
 						matrix.dx = l.xx * r.dx + l.xy * r.dy + l.dx;
 						matrix.dy = l.yx * r.dx + l.yy * r.dy + l.dy;
 					}
-					dojo.mixin(this, matrix);
+					lang.mixin(this, matrix);
 				}
 			}else{
-				dojo.mixin(this, arg);
+				lang.mixin(this, arg);
 			}
 		}
 	};
 
 	// the default (identity) matrix, which is used to fill in missing values
-	dojo.extend(m.Matrix2D, {xx: 1, xy: 0, yx: 0, yy: 1, dx: 0, dy: 0});
+	lang.extend(m.Matrix2D, {xx: 1, xy: 0, yx: 0, yy: 1, dx: 0, dy: 0});
 
-	dojo.mixin(m, {
+	lang.mixin(m, {
 		// summary: class constants, and methods of dojox.gfx.matrix
 
 		// matrix constants
@@ -207,7 +208,7 @@ dojo.provide("dojox.gfx.matrix");
 			// summary: inverts a 2D matrix
 			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object to be inverted
 			var M = m.normalize(matrix),
-				D = M.xx * M.yy - M.xy * M.yx,
+				D = M.xx * M.yy - M.xy * M.yx;
 				M = new m.Matrix2D({
 					xx: M.yy/D, xy: -M.xy/D,
 					yx: -M.yx/D, yy: M.xx/D,
@@ -223,11 +224,11 @@ dojo.provide("dojox.gfx.matrix");
 			// 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
 		},
-		multiplyPoint: function(matrix, /* Number||Point */ a, /* Number, optional */ b){
+		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
+			// b: Number?: a y coordinate of a point
 			var M = m.normalize(matrix);
 			if(typeof a == "number" && typeof b == "number"){
 				return m._multiplyPoint(M, a, b); // dojox.gfx.Point
@@ -412,12 +413,12 @@ dojo.provide("dojox.gfx.matrix");
 			// b: null
 			return m._sandwich(m.skewY(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D
 		},
-		skewYgAt: function(/* Number */ degree, /* Number||Point */ a, /* Number, optional */ b){
+		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
+			// b: Number?: a y component of a central point
 
 			// accepts several signatures:
 			//	1) skew angle in degrees, Point
@@ -437,7 +438,10 @@ dojo.provide("dojox.gfx.matrix");
 		//TODO: rect-to-rect mapping, scale-to-fit (isotropic and anisotropic versions)
 
 	});
-})();
+	// propagate Matrix2D up
+	g.Matrix2D = m.Matrix2D;
+
+	return m;
+});
+
 
-// propagate Matrix2D up
-dojox.gfx.Matrix2D = dojox.gfx.matrix.Matrix2D;
diff --git a/dojox/gfx/move.js b/dojox/gfx/move.js
index 60b14a7..207f1b8 100644
--- a/dojox/gfx/move.js
+++ b/dojox/gfx/move.js
@@ -1,4 +1,2 @@
-dojo.provide("dojox.gfx.move");
-
-dojo.require("dojox.gfx.Mover");
-dojo.require("dojox.gfx.Moveable");
+define(["dojo/_base/lang", "./Mover", "./Moveable"], 
+  function(lang){ return lang.getObject("dojox.gfx.move", true); });
diff --git a/dojox/gfx/path.js b/dojox/gfx/path.js
index 3df64e6..349338d 100644
--- a/dojox/gfx/path.js
+++ b/dojox/gfx/path.js
@@ -1,419 +1,445 @@
-dojo.provide("dojox.gfx.path");
+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;
+  =====*/
 
-dojo.require("dojox.gfx.matrix");
-dojo.require("dojox.gfx.shape");
+	var path = g.path = {};
+	var Path = declare("dojox.gfx.path.Path", shapeLib.Shape, {
+		// summary: a generalized path shape
 
-dojo.declare("dojox.gfx.path.Path", dojox.gfx.shape.Shape, {
-	// summary: a generalized path shape
+		constructor: function(rawNode){
+			// summary: a path constructor
+			// rawNode: Node
+			//		a DOM node to be used by this path object
+			this.shape = lang.clone(g.defaultPath);
+			this.segments = [];
+			this.tbbox = null;
+			this.absolute = true;
+			this.last = {};
+			this.rawNode = rawNode;
+			this.segmented = false;
+		},
 
-	constructor: function(rawNode){
-		// summary: a path constructor
-		// rawNode: Node: a DOM node to be used by this path object
-		this.shape = dojo.clone(dojox.gfx.defaultPath);
-		this.segments = [];
-		this.tbbox = null;
-		this.absolute = true;
-		this.last = {};
-		this.rawNode = rawNode;
-		this.segmented = false;
-	},
-
-	// mode manipulations
-	setAbsoluteMode: function(mode){
-		// summary: sets an absolute or relative mode for path points
-		// mode: Boolean: true/false or "absolute"/"relative" to specify the mode
-		this._confirmSegmented();
-		this.absolute = typeof mode == "string" ? (mode == "absolute") : mode;
-		return this; // self
-	},
-	getAbsoluteMode: function(){
-		// summary: returns a current value of the absolute mode
-		this._confirmSegmented();
-		return this.absolute; // Boolean
-	},
+		// mode manipulations
+		setAbsoluteMode: function(mode){
+			// summary: sets an absolute or relative mode for path points
+			// mode: Boolean
+			//		true/false or "absolute"/"relative" to specify the mode
+			this._confirmSegmented();
+			this.absolute = typeof mode == "string" ? (mode == "absolute") : mode;
+			return this; // self
+		},
+		getAbsoluteMode: function(){
+			// 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
-		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
-	},
+		getBoundingBox: function(){
+			// 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
+		},
 
-	_getRealBBox: function(){
-		// summary: returns an array of four points or null
-		//	four points represent four corners of the untransformed bounding box
-		this._confirmSegmented();
-		if(this.tbbox){
+		_getRealBBox: function(){
+			// 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
+			}
+			var bbox = this.bbox, matrix = this._getRealMatrix();
+			this.bbox = null;
+			for(var i = 0, len = this.segments.length; i < len; ++i){
+				this._updateWithSegment(this.segments[i], matrix);
+			}
+			var t = this.bbox;
+			this.bbox = bbox;
+			this.tbbox = t ? [
+				{x: t.l, y: t.t},
+				{x: t.r, y: t.t},
+				{x: t.r, y: t.b},
+				{x: t.l, y: t.b}
+			] : null;
 			return this.tbbox;	// Array
-		}
-		var bbox = this.bbox, matrix = this._getRealMatrix();
-		this.bbox = null;
-		for(var i = 0, len = this.segments.length; i < len; ++i){
-			this._updateWithSegment(this.segments[i], matrix);
-		}
-		var t = this.bbox;
-		this.bbox = bbox;
-		this.tbbox = t ? [
-			{x: t.l, y: t.t},
-			{x: t.r, y: t.t},
-			{x: t.r, y: t.b},
-			{x: t.l, y: t.b}
-		] : null;
-		return this.tbbox;	// Array
-	},
+		},
 
-	getLastPosition: function(){
-		// summary: returns the last point in the path, or null
-		this._confirmSegmented();
-		return "x" in this.last ? this.last : null; // Object
-	},
+		getLastPosition: function(){
+			// summary: returns the last point in the path, or null
+			this._confirmSegmented();
+			return "x" in this.last ? this.last : null; // Object
+		},
 
-	_applyTransform: function(){
-		this.tbbox = null;
-		return this.inherited(arguments);
-	},
+		_applyTransform: function(){
+			this.tbbox = null;
+			return this.inherited(arguments);
+		},
 
-	// segment interpretation
-	_updateBBox: function(x, y, matrix){
-		// summary: updates the bounding box of path with new point
-		// x: Number: an x coordinate
-		// y: Number: a y coordinate
-		
-		if(matrix){
-			var t = dojox.gfx.matrix.multiplyPoint(matrix, x, y);
-			x = t.x;
-			y = t.y;
-		}
+		// segment interpretation
+		_updateBBox: function(x, y, m){
+			// summary: updates the bounding box of path with new point
+			// x: Number
+			//		an x coordinate
+			// y: Number
+			//		a y coordinate
 
-		// we use {l, b, r, t} representation of a bbox
-		if(this.bbox && ("l" in this.bbox)){
-			if(this.bbox.l > x) this.bbox.l = x;
-			if(this.bbox.r < x) this.bbox.r = x;
-			if(this.bbox.t > y) this.bbox.t = y;
-			if(this.bbox.b < y) this.bbox.b = y;
-		}else{
-			this.bbox = {l: x, b: y, r: x, t: y};
-		}
-	},
-	_updateWithSegment: function(segment, matrix){
-		// summary: updates the bounding box of path with new segment
-		// segment: Object: a segment
-		var n = segment.args, l = n.length;
-		// update internal variables: bbox, absolute, last
-		switch(segment.action){
-			case "M":
-			case "L":
-			case "C":
-			case "S":
-			case "Q":
-			case "T":
-				for(var i = 0; i < l; i += 2){
-					this._updateBBox(n[i], n[i + 1], matrix);
-				}
-				this.last.x = n[l - 2];
-				this.last.y = n[l - 1];
-				this.absolute = true;
-				break;
-			case "H":
-				for(var i = 0; i < l; ++i){
-					this._updateBBox(n[i], this.last.y, matrix);
-				}
-				this.last.x = n[l - 1];
-				this.absolute = true;
-				break;
-			case "V":
-				for(var i = 0; i < l; ++i){
-					this._updateBBox(this.last.x, n[i], matrix);
-				}
-				this.last.y = n[l - 1];
-				this.absolute = true;
-				break;
-			case "m":
-				var start = 0;
-				if(!("x" in this.last)){
-					this._updateBBox(this.last.x = n[0], this.last.y = n[1], matrix);
-					start = 2;
-				}
-				for(var i = start; i < l; i += 2){
-					this._updateBBox(this.last.x += n[i], this.last.y += n[i + 1], matrix);
-				}
-				this.absolute = false;
-				break;
-			case "l":
-			case "t":
-				for(var i = 0; i < l; i += 2){
-					this._updateBBox(this.last.x += n[i], this.last.y += n[i + 1], matrix);
-				}
-				this.absolute = false;
-				break;
-			case "h":
-				for(var i = 0; i < l; ++i){
-					this._updateBBox(this.last.x += n[i], this.last.y, matrix);
-				}
-				this.absolute = false;
-				break;
-			case "v":
-				for(var i = 0; i < l; ++i){
-					this._updateBBox(this.last.x, this.last.y += n[i], matrix);
-				}
-				this.absolute = false;
-				break;
-			case "c":
-				for(var i = 0; i < l; i += 6){
-					this._updateBBox(this.last.x + n[i], this.last.y + n[i + 1], matrix);
-					this._updateBBox(this.last.x + n[i + 2], this.last.y + n[i + 3], matrix);
-					this._updateBBox(this.last.x += n[i + 4], this.last.y += n[i + 5], matrix);
-				}
-				this.absolute = false;
-				break;
-			case "s":
-			case "q":
-				for(var i = 0; i < l; i += 4){
-					this._updateBBox(this.last.x + n[i], this.last.y + n[i + 1], matrix);
-					this._updateBBox(this.last.x += n[i + 2], this.last.y += n[i + 3], matrix);
-				}
-				this.absolute = false;
-				break;
-			case "A":
-				for(var i = 0; i < l; i += 7){
-					this._updateBBox(n[i + 5], n[i + 6], matrix);
-				}
-				this.last.x = n[l - 2];
-				this.last.y = n[l - 1];
-				this.absolute = true;
-				break;
-			case "a":
-				for(var i = 0; i < l; i += 7){
-					this._updateBBox(this.last.x += n[i + 5], this.last.y += n[i + 6], matrix);
-				}
-				this.absolute = false;
-				break;
-		}
-		// add an SVG path segment
-		var path = [segment.action];
-		for(var i = 0; i < l; ++i){
-			path.push(dojox.gfx.formatNumber(n[i], true));
-		}
-		if(typeof this.shape.path == "string"){
-			this.shape.path += path.join("");
-		}else{
-			Array.prototype.push.apply(this.shape.path, path); //FIXME: why not simple push()?
-		}
-	},
+			if(m){
+				var t = matrix.multiplyPoint(m, x, y);
+				x = t.x;
+				y = t.y;
+			}
+
+			// we use {l, b, r, t} representation of a bbox
+			if(this.bbox && ("l" in this.bbox)){
+				if(this.bbox.l > x) this.bbox.l = x;
+				if(this.bbox.r < x) this.bbox.r = x;
+				if(this.bbox.t > y) this.bbox.t = y;
+				if(this.bbox.b < y) this.bbox.b = y;
+			}else{
+				this.bbox = {l: x, b: y, r: x, t: y};
+			}
+		},
+		_updateWithSegment: function(segment, matrix){
+			// summary: updates the bounding box of path with new segment
+			// segment: Object
+			//		a segment
+			var n = segment.args, l = n.length, i;
+			// update internal variables: bbox, absolute, last
+			switch(segment.action){
+				case "M":
+				case "L":
+				case "C":
+				case "S":
+				case "Q":
+				case "T":
+					for(i = 0; i < l; i += 2){
+						this._updateBBox(n[i], n[i + 1], matrix);
+					}
+					this.last.x = n[l - 2];
+					this.last.y = n[l - 1];
+					this.absolute = true;
+					break;
+				case "H":
+					for(i = 0; i < l; ++i){
+						this._updateBBox(n[i], this.last.y, matrix);
+					}
+					this.last.x = n[l - 1];
+					this.absolute = true;
+					break;
+				case "V":
+					for(i = 0; i < l; ++i){
+						this._updateBBox(this.last.x, n[i], matrix);
+					}
+					this.last.y = n[l - 1];
+					this.absolute = true;
+					break;
+				case "m":
+					var start = 0;
+					if(!("x" in this.last)){
+						this._updateBBox(this.last.x = n[0], this.last.y = n[1], matrix);
+						start = 2;
+					}
+					for(i = start; i < l; i += 2){
+						this._updateBBox(this.last.x += n[i], this.last.y += n[i + 1], matrix);
+					}
+					this.absolute = false;
+					break;
+				case "l":
+				case "t":
+					for(i = 0; i < l; i += 2){
+						this._updateBBox(this.last.x += n[i], this.last.y += n[i + 1], matrix);
+					}
+					this.absolute = false;
+					break;
+				case "h":
+					for(i = 0; i < l; ++i){
+						this._updateBBox(this.last.x += n[i], this.last.y, matrix);
+					}
+					this.absolute = false;
+					break;
+				case "v":
+					for(i = 0; i < l; ++i){
+						this._updateBBox(this.last.x, this.last.y += n[i], matrix);
+					}
+					this.absolute = false;
+					break;
+				case "c":
+					for(i = 0; i < l; i += 6){
+						this._updateBBox(this.last.x + n[i], this.last.y + n[i + 1], matrix);
+						this._updateBBox(this.last.x + n[i + 2], this.last.y + n[i + 3], matrix);
+						this._updateBBox(this.last.x += n[i + 4], this.last.y += n[i + 5], matrix);
+					}
+					this.absolute = false;
+					break;
+				case "s":
+				case "q":
+					for(i = 0; i < l; i += 4){
+						this._updateBBox(this.last.x + n[i], this.last.y + n[i + 1], matrix);
+						this._updateBBox(this.last.x += n[i + 2], this.last.y += n[i + 3], matrix);
+					}
+					this.absolute = false;
+					break;
+				case "A":
+					for(i = 0; i < l; i += 7){
+						this._updateBBox(n[i + 5], n[i + 6], matrix);
+					}
+					this.last.x = n[l - 2];
+					this.last.y = n[l - 1];
+					this.absolute = true;
+					break;
+				case "a":
+					for(i = 0; i < l; i += 7){
+						this._updateBBox(this.last.x += n[i + 5], this.last.y += n[i + 6], matrix);
+					}
+					this.absolute = false;
+					break;
+			}
+			// add an SVG path segment
+			var path = [segment.action];
+			for(i = 0; i < l; ++i){
+				path.push(g.formatNumber(n[i], true));
+			}
+			if(typeof this.shape.path == "string"){
+				this.shape.path += path.join("");
+			}else{
+				Array.prototype.push.apply(this.shape.path, path); //FIXME: why not simple push()?
+			}
+		},
 
-	// a dictionary, which maps segment type codes to a number of their arguments
-	_validSegments: {m: 2, l: 2, h: 1, v: 1, c: 6, s: 4, q: 4, t: 2, a: 7, z: 0},
+		// a dictionary, which maps segment type codes to a number of their arguments
+		_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
-		// action: String: valid SVG code for a segment's type
-		// args: Array: a list of parameters for this segment
-		this.tbbox = null;
-		var group = this._validSegments[action.toLowerCase()];
-		if(typeof group == "number"){
-			if(group){
-				if(args.length >= group){
-					var segment = {action: action, args: args.slice(0, args.length - args.length % group)};
+		_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
+			this.tbbox = null;
+			var group = this._validSegments[action.toLowerCase()], segment;
+			if(typeof group == "number"){
+				if(group){
+					if(args.length >= group){
+						segment = {action: action, args: args.slice(0, args.length - args.length % group)};
+						this.segments.push(segment);
+						this._updateWithSegment(segment);
+					}
+				}else{
+					segment = {action: action, args: []};
 					this.segments.push(segment);
 					this._updateWithSegment(segment);
 				}
-			}else{
-				var segment = {action: action, args: []};
-				this.segments.push(segment);
-				this._updateWithSegment(segment);
 			}
-		}
-	},
+		},
 
-	_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)
-		for(var i = 0; i < args.length; ++i){
-			var t = args[i];
-			if(typeof t == "boolean"){
-				array.push(t ? 1 : 0);
-			}else if(typeof t == "number"){
-				array.push(t);
-			}else if(t instanceof Array){
-				this._collectArgs(array, t);
-			}else if("x" in t && "y" in t){
-				array.push(t.x, t.y);
+		_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)
+			for(var i = 0; i < args.length; ++i){
+				var t = args[i];
+				if(typeof t == "boolean"){
+					array.push(t ? 1 : 0);
+				}else if(typeof t == "number"){
+					array.push(t);
+				}else if(t instanceof Array){
+					this._collectArgs(array, t);
+				}else if("x" in t && "y" in t){
+					array.push(t.x, t.y);
+				}
 			}
-		}
-	},
+		},
 
-	// segments
-	moveTo: function(){
-		// summary: formes a move segment
-		this._confirmSegmented();
-		var args = [];
-		this._collectArgs(args, arguments);
-		this._pushSegment(this.absolute ? "M" : "m", args);
-		return this; // self
-	},
-	lineTo: function(){
-		// summary: formes a line segment
-		this._confirmSegmented();
-		var args = [];
-		this._collectArgs(args, arguments);
-		this._pushSegment(this.absolute ? "L" : "l", args);
-		return this; // self
-	},
-	hLineTo: function(){
-		// summary: formes a horizontal line segment
-		this._confirmSegmented();
-		var args = [];
-		this._collectArgs(args, arguments);
-		this._pushSegment(this.absolute ? "H" : "h", args);
-		return this; // self
-	},
-	vLineTo: function(){
-		// summary: formes a vertical line segment
-		this._confirmSegmented();
-		var args = [];
-		this._collectArgs(args, arguments);
-		this._pushSegment(this.absolute ? "V" : "v", args);
-		return this; // self
-	},
-	curveTo: function(){
-		// summary: formes a curve segment
-		this._confirmSegmented();
-		var args = [];
-		this._collectArgs(args, arguments);
-		this._pushSegment(this.absolute ? "C" : "c", args);
-		return this; // self
-	},
-	smoothCurveTo: function(){
-		// summary: formes a smooth curve segment
-		this._confirmSegmented();
-		var args = [];
-		this._collectArgs(args, arguments);
-		this._pushSegment(this.absolute ? "S" : "s", args);
-		return this; // self
-	},
-	qCurveTo: function(){
-		// summary: formes a quadratic curve segment
-		this._confirmSegmented();
-		var args = [];
-		this._collectArgs(args, arguments);
-		this._pushSegment(this.absolute ? "Q" : "q", args);
-		return this; // self
-	},
-	qSmoothCurveTo: function(){
-		// summary: formes a quadratic smooth curve segment
-		this._confirmSegmented();
-		var args = [];
-		this._collectArgs(args, arguments);
-		this._pushSegment(this.absolute ? "T" : "t", args);
-		return this; // self
-	},
-	arcTo: function(){
-		// summary: formes an elliptic arc segment
-		this._confirmSegmented();
-		var args = [];
-		this._collectArgs(args, arguments);
-		this._pushSegment(this.absolute ? "A" : "a", args);
-		return this; // self
-	},
-	closePath: function(){
-		// summary: closes a path
-		this._confirmSegmented();
-		this._pushSegment("Z", []);
-		return this; // self
-	},
+		// segments
+		moveTo: function(){
+			// summary: forms a move segment
+			this._confirmSegmented();
+			var args = [];
+			this._collectArgs(args, arguments);
+			this._pushSegment(this.absolute ? "M" : "m", args);
+			return this; // self
+		},
+		lineTo: function(){
+			// summary: forms a line segment
+			this._confirmSegmented();
+			var args = [];
+			this._collectArgs(args, arguments);
+			this._pushSegment(this.absolute ? "L" : "l", args);
+			return this; // self
+		},
+		hLineTo: function(){
+			// summary: forms a horizontal line segment
+			this._confirmSegmented();
+			var args = [];
+			this._collectArgs(args, arguments);
+			this._pushSegment(this.absolute ? "H" : "h", args);
+			return this; // self
+		},
+		vLineTo: function(){
+			// summary: forms a vertical line segment
+			this._confirmSegmented();
+			var args = [];
+			this._collectArgs(args, arguments);
+			this._pushSegment(this.absolute ? "V" : "v", args);
+			return this; // self
+		},
+		curveTo: function(){
+			// summary: forms a curve segment
+			this._confirmSegmented();
+			var args = [];
+			this._collectArgs(args, arguments);
+			this._pushSegment(this.absolute ? "C" : "c", args);
+			return this; // self
+		},
+		smoothCurveTo: function(){
+			// summary: forms a smooth curve segment
+			this._confirmSegmented();
+			var args = [];
+			this._collectArgs(args, arguments);
+			this._pushSegment(this.absolute ? "S" : "s", args);
+			return this; // self
+		},
+		qCurveTo: function(){
+			// summary: forms a quadratic curve segment
+			this._confirmSegmented();
+			var args = [];
+			this._collectArgs(args, arguments);
+			this._pushSegment(this.absolute ? "Q" : "q", args);
+			return this; // self
+		},
+		qSmoothCurveTo: function(){
+			// summary: forms a quadratic smooth curve segment
+			this._confirmSegmented();
+			var args = [];
+			this._collectArgs(args, arguments);
+			this._pushSegment(this.absolute ? "T" : "t", args);
+			return this; // self
+		},
+		arcTo: function(){
+			// summary: forms an elliptic arc segment
+			this._confirmSegmented();
+			var args = [];
+			this._collectArgs(args, arguments);
+			this._pushSegment(this.absolute ? "A" : "a", args);
+			return this; // self
+		},
+		closePath: function(){
+			// summary: closes a path
+			this._confirmSegmented();
+			this._pushSegment("Z", []);
+			return this; // self
+		},
 
-	_confirmSegmented: function() {
-		if (!this.segmented) {
-			var path = this.shape.path;
-			// switch to non-updating version of path building
-			this.shape.path = [];
-			this._setPath(path);
-			// switch back to the string path
-			this.shape.path = this.shape.path.join("");
-			// become segmented
-			this.segmented = true;
-		}
-	},
+		_confirmSegmented: function() {
+			if (!this.segmented) {
+				var path = this.shape.path;
+				// switch to non-updating version of path building
+				this.shape.path = [];
+				this._setPath(path);
+				// switch back to the string path
+				this.shape.path = this.shape.path.join("");
+				// become segmented
+				this.segmented = true;
+			}
+		},
 
-	// setShape
-	_setPath: function(path){
-		// summary: forms a path using an SVG path string
-		// path: String: an SVG path string
-		var p = dojo.isArray(path) ? path : path.match(dojox.gfx.pathSvgRegExp);
-		this.segments = [];
-		this.absolute = true;
-		this.bbox = {};
-		this.last = {};
-		if(!p) return;
-		// create segments
-		var action = "",	// current action
-			args = [],		// current arguments
-			l = p.length;
-		for(var i = 0; i < l; ++i){
-			var t = p[i], x = parseFloat(t);
-			if(isNaN(x)){
-				if(action){
-					this._pushSegment(action, args);
+		// setShape
+		_setPath: function(path){
+			// 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);
+			this.segments = [];
+			this.absolute = true;
+			this.bbox = {};
+			this.last = {};
+			if(!p) return;
+			// create segments
+			var action = "",	// current action
+				args = [],		// current arguments
+				l = p.length;
+			for(var i = 0; i < l; ++i){
+				var t = p[i], x = parseFloat(t);
+				if(isNaN(x)){
+					if(action){
+						this._pushSegment(action, args);
+					}
+					args = [];
+					action = t;
+				}else{
+					args.push(x);
 				}
-				args = [];
-				action = t;
-			}else{
-				args.push(x);
 			}
-		}
-		this._pushSegment(action, args);
-	},
-	setShape: function(newShape){
-		// summary: forms a path using a shape
-		// newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
-		this.inherited(arguments, [typeof newShape == "string" ? {path: newShape} : newShape]);
-		
-		this.segmented = false;
-		this.segments = [];
-		if(!dojox.gfx.lazyPathSegmentation){
-			this._confirmSegmented();
-		}
-		return this; // self
-	},
+			this._pushSegment(action, args);
+		},
+		setShape: function(newShape){
+			// summary: forms a path using a shape
+			// newShape: Object
+			//		an SVG path string or a path object (see dojox.gfx.defaultPath)
+			this.inherited(arguments, [typeof newShape == "string" ? {path: newShape} : newShape]);
 
-	// useful constant for descendants
-	_2PI: Math.PI * 2
-});
+			this.segmented = false;
+			this.segments = [];
+			if(!g.lazyPathSegmentation){
+				this._confirmSegmented();
+			}
+			return this; // self
+		},
 
-dojo.declare("dojox.gfx.path.TextPath", dojox.gfx.path.Path, {
-	// summary: a generalized TextPath shape
+		// useful constant for descendants
+		_2PI: Math.PI * 2
+	});
 
-	constructor: function(rawNode){
-		// summary: a TextPath shape constructor
-		// rawNode: Node: a DOM node to be used by this TextPath object
-		if(!("text" in this)){
-			this.text = dojo.clone(dojox.gfx.defaultTextPath);
-		}
-		if(!("fontStyle" in this)){
-			this.fontStyle = dojo.clone(dojox.gfx.defaultFont);
+	var TextPath = declare("dojox.gfx.path.TextPath", Path, {
+		// summary: a generalized TextPath shape
+
+		constructor: function(rawNode){
+			// summary: a TextPath shape constructor
+			// rawNode: Node
+			//		a DOM node to be used by this TextPath object
+			if(!("text" in this)){
+				this.text = lang.clone(g.defaultTextPath);
+			}
+			if(!("fontStyle" in this)){
+				this.fontStyle = lang.clone(g.defaultFont);
+			}
+		},
+		getText: function(){
+			// 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
+			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
+			return this.fontStyle;	// Object
+		},
+		setFont: function(newFont){
+			// summary: sets a font for text
+			this.fontStyle = typeof newFont == "string" ?
+				g.splitFontString(newFont) :
+				g.makeParameters(g.defaultFont, newFont);
+			this._setFont();
+			return this;	// self
 		}
-	},
-	getText: function(){
-		// 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
-		this.text = dojox.gfx.makeParameters(this.text,
-			typeof newText == "string" ? {text: newText} : newText);
-		this._setText();
-		return this;	// self
-	},
-	getFont: function(){
-		// summary: returns the current font object or null
-		return this.fontStyle;	// Object
-	},
-	setFont: function(newFont){
-		// summary: sets a font for text
-		this.fontStyle = typeof newFont == "string" ?
-			dojox.gfx.splitFontString(newFont) :
-			dojox.gfx.makeParameters(dojox.gfx.defaultFont, newFont);
-		this._setFont();
-		return this;	// self
-	}
+	});
+
+	return { // our hash of newly defined objects
+		Path: Path,
+		TextPath: TextPath
+	};
 });
diff --git a/dojox/gfx/renderer.js b/dojox/gfx/renderer.js
new file mode 100644
index 0000000..a50c4d5
--- /dev/null
+++ b/dojox/gfx/renderer.js
@@ -0,0 +1,89 @@
+define(["./_base","dojo/_base/lang", "dojo/_base/sniff", "dojo/_base/window", "dojo/_base/config"],
+  function(g, lang, has, win, config){
+  //>> noBuildResolver
+/*=====
+	dojox.gfx.renderer = {
+		// 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){
+			if(currentRenderer && id != "force"){
+				load(currentRenderer);
+				return;
+			}
+			var renderer = config.forceGfxRenderer,
+				renderers = !renderer && (lang.isString(config.gfxRenderer) ?
+					config.gfxRenderer : "svg,vml,canvas,silverlight").split(","),
+				silverlightObject, silverlightFlag;
+
+			while(!renderer && renderers.length){
+				switch(renderers.shift()){
+					case "svg":
+						// the next test is from https://github.com/phiggins42/has.js
+						if("SVGAngle" in win.global){
+							renderer = "svg";
+						}
+						break;
+					case "vml":
+						if(has("ie")){
+							renderer = "vml";
+						}
+						break;
+					case "silverlight":
+						try{
+							if(has("ie")){
+								silverlightObject = new ActiveXObject("AgControl.AgControl");
+								if(silverlightObject && silverlightObject.IsVersionSupported("1.0")){
+									silverlightFlag = true;
+								}
+							}else{
+								if(navigator.plugins["Silverlight Plug-In"]){
+									silverlightFlag = true;
+								}
+							}
+						}catch(e){
+							silverlightFlag = false;
+						}finally{
+							silverlightObject = null;
+						}
+						if(silverlightFlag){
+							renderer = "silverlight";
+						}
+						break;
+					case "canvas":
+						if(win.global.CanvasRenderingContext2D){
+							renderer = "canvas";
+						}
+						break;
+				}
+			}
+
+			if (renderer === 'canvas' && config.canvasEvents !== false) {
+				renderer = "canvasWithEvents";
+			}
+
+			if(config.isDebug){
+				console.log("gfx renderer = " + renderer);
+			}
+
+			function loadRenderer(){
+				require(["dojox/gfx/" + renderer], function(module){
+					g.renderer = renderer;
+					// memorize the renderer module
+					currentRenderer = module;
+					// now load it
+					load(module);
+				});
+			}
+			if(renderer == "svg" && typeof window.svgweb != "undefined"){
+				window.svgweb.addOnLoad(loadRenderer);
+			}else{
+				loadRenderer();
+			}
+		}
+	};
+});
diff --git a/dojox/gfx/resources/gfxSvgProxyFrame.html b/dojox/gfx/resources/gfxSvgProxyFrame.html
index 1a9ed5e..cfc7e26 100644
--- a/dojox/gfx/resources/gfxSvgProxyFrame.html
+++ b/dojox/gfx/resources/gfxSvgProxyFrame.html
@@ -5,8 +5,7 @@
     	</script>
         <script type="text/javascript" src="../../../dojo/dojo.js" ></script>
         <script type="text/javascript">
-			dojo.require("dojox.gfx");
-			dojo.require("dojox.gfx.utils");
+		require(['dojox/gfx','dojox/gfx/utils'], function(gfx, utils){});
         </script>
     </head>
     <body>
diff --git a/dojox/gfx/resources/svg2gfx.xsl b/dojox/gfx/resources/svg2gfx.xsl
index 91ba90f..03c25a9 100644
--- a/dojox/gfx/resources/svg2gfx.xsl
+++ b/dojox/gfx/resources/svg2gfx.xsl
@@ -41,7 +41,7 @@ GMail, etc.) or Eric (Saugus.net, ShellTown, etc.)
 	
 	<!-- The following templates process little bits of things that can often occur in multiple contexts -->
 	
-	<xsl:template name="kill-extra-spaces" mode="kill-extra-spaces">
+	<xsl:template name="kill-extra-spaces">
 		<xsl:param name="string"/>
 		<!-- Some don't feel that SVG is verbose enough and thus add extra spaces, which when -->
 		<!-- untreated can look exactly like delimiters in point sets. -->
@@ -63,7 +63,7 @@ GMail, etc.) or Eric (Saugus.net, ShellTown, etc.)
 		</xsl:choose>
 	</xsl:template>
 
-	<xsl:template name="arg-processor" mode="arg-processor">
+	<xsl:template name="arg-processor">
 		<xsl:param name="values"/>
 		<xsl:param name="labels"/>
 		<!-- Recursively chew through the arguments in a traditional CAR / CDR pattern -->
@@ -92,7 +92,7 @@ GMail, etc.) or Eric (Saugus.net, ShellTown, etc.)
 		</xsl:choose>
 	</xsl:template>
 
-	<xsl:template name="background-processor" mode="background-processor">
+	<xsl:template name="background-processor">
 		<xsl:param name="background"/>
 		<xsl:choose>
 			<xsl:when test="starts-with($background,'url')">
@@ -136,7 +136,7 @@ GMail, etc.) or Eric (Saugus.net, ShellTown, etc.)
 		</xsl:choose>
 	</xsl:template>
 
-	<xsl:template name="point-processor" mode="point-processor">
+	<xsl:template name="point-processor">
 		<xsl:param name="points"/>
 		<!-- Recursively process points in a traditional CAR / CDR pattern -->
 		<xsl:variable name="pointsCdr" select="normalize-space(substring-after($points,' '))"/>
@@ -165,7 +165,7 @@ GMail, etc.) or Eric (Saugus.net, ShellTown, etc.)
 		</xsl:choose>
 	</xsl:template>
 	
-	<xsl:template name="rgb-triple-processor" mode="rgb-triple-processor">
+	<xsl:template name="rgb-triple-processor">
 		<xsl:param name="triple"/>
 		<!-- Note that as SVG triples cannot contain alpha values, we hardcode it to be fully opaque -->
 		<!-- This could theoretically be better handled by watching for fill-opacity -->
@@ -181,7 +181,7 @@ GMail, etc.) or Eric (Saugus.net, ShellTown, etc.)
 		<xsl:text>,"a":1},</xsl:text>
 	</xsl:template>
 	
-	<xsl:template name="styles-processor" mode="styles-processor">
+	<xsl:template name="styles-processor">
 		<xsl:param name="styles"/>
 		<!-- Recursively chew through the styles in a traditional CAR / CDR pattern -->
 		<xsl:variable name="stylesCdr" select="substring-after($styles,';')"/>
@@ -206,7 +206,7 @@ GMail, etc.) or Eric (Saugus.net, ShellTown, etc.)
 		</xsl:choose>
 	</xsl:template>
 
-	<xsl:template name="transform-processor" mode="transform-processor">
+	<xsl:template name="transform-processor">
 		<xsl:param name="transforms"/>
 		<!-- Recursively chew through the transforms in a traditional CAR / CDR pattern -->
 		<xsl:variable name="transformsCdr" select="normalize-space(substring-after($transforms,')'))"/>
@@ -323,7 +323,7 @@ GMail, etc.) or Eric (Saugus.net, ShellTown, etc.)
 		</xsl:if>
 	</xsl:template>
 
-	<xsl:template name="url-processor" mode="url-processor">
+	<xsl:template name="url-processor">
 		<xsl:param name="url"/>
 		<xsl:param name="groupAttrs" select="''"/>
 		<!-- We can only handle local references; that's probably all we should get anyway -->
@@ -340,7 +340,7 @@ GMail, etc.) or Eric (Saugus.net, ShellTown, etc.)
 	<!-- The biggest of these is gradient transforms; when GFX natively supports it all the -->
 	<!-- kluges made to support it here (including all the following code) should be removed. -->
 	
-	<xsl:template name="gradient-transform-helper" mode="gradient-transform-helper">
+	<xsl:template name="gradient-transform-helper">
 		<!-- This nasty little routine helps gradient adjuster and can be -->
 		<!-- removed when GFX gets gradientTransform support. -->
 		<xsl:param name="cxa"/>
@@ -390,7 +390,7 @@ GMail, etc.) or Eric (Saugus.net, ShellTown, etc.)
 		</xsl:choose>
 	</xsl:template>
 	
-	<xsl:template name="gradient-adjuster" mode="gradient-adjuster">
+	<xsl:template name="gradient-adjuster">
 		<xsl:param name="node"/>
 		<!-- This code is awful and only meant to serve until GFX gets gradientTransform support. -->
 		<!-- Once GFX does gradientTransforms, the following should be destroyed and forgotten. -->
diff --git a/dojox/gfx/shape.js b/dojox/gfx/shape.js
index 1ebaa7a..36f95a8 100644
--- a/dojox/gfx/shape.js
+++ b/dojox/gfx/shape.js
@@ -1,750 +1,875 @@
-dojo.provide("dojox.gfx.shape");
-
-dojo.require("dojox.gfx._base");
-
-dojo.declare("dojox.gfx.shape.Shape", null, {
-	// summary: a Shape object, which knows how to apply
-	// graphical attributes and transformations
-
-	constructor: function(){
-		// rawNode: Node: underlying node
-		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)
-		this.shape = null;
-
-		// matrix: dojox.gfx.Matrix2D: a transformation matrix
-		this.matrix = null;
-
-		// fillStyle: Object: a fill object
-		//	(see dojox.gfx.defaultLinearGradient,
-		//	dojox.gfx.defaultRadialGradient,
-		//	dojox.gfx.defaultPattern,
-		//	or dojo.Color)
-		this.fillStyle = null;
-
-		// strokeStyle: Object: a stroke object
-		//	(see dojox.gfx.defaultStroke)
-		this.strokeStyle = null;
-
-		// bbox: dojox.gfx.Rectangle: a bounding box of this shape
-		//	(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)
-		this.parent = null;
-
-		// parentMatrix: dojox.gfx.Matrix2D
-		//	a transformation matrix inherited from the parent
-		this.parentMatrix = null;
-	},
-
-	// trivial getters
-
-	getNode: function(){
-		// summary: returns the current DOM Node or null
-		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)
-		return this.shape; // Object
-	},
-	getTransform: function(){
-		// summary: returns the current transformation matrix or null
-		return this.matrix;	// dojox.gfx.Matrix2D
-	},
-	getFill: function(){
-		// 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)
-		return this.strokeStyle;	// Object
-	},
-	getParent: function(){
-		// summary: returns the parent or null
-		//	(see dojox.gfx.Surface,
-		//	dojox.gfx.shape.VirtualGroup,
-		//	or dojox.gfx.Group)
-		return this.parent;	// Object
-	},
-	getBoundingBox: function(){
-		// summary: returns the bounding box or null
-		//	(see dojox.gfx.defaultRect)
-		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
-		var b = this.getBoundingBox();
-		if(!b){
-			return null;	// null
-		}
-		var m = this._getRealMatrix();
-			gm = dojox.gfx.matrix;
-		return [	// Array
-				gm.multiplyPoint(m, b.x, b.y),
-				gm.multiplyPoint(m, b.x + b.width, b.y),
-				gm.multiplyPoint(m, b.x + b.width, b.y + b.height),
-				gm.multiplyPoint(m, b.x, b.y + b.height)
-			];
-	},
-	getEventSource: function(){
-		// 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
-
-	setShape: function(shape){
-		// 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)
-
-		// COULD BE RE-IMPLEMENTED BY THE RENDERER!
-
-		this.shape = dojox.gfx.makeParameters(this.shape, shape);
-		this.bbox = null;
-		return this;	// self
-	},
-	setFill: function(fill){
-		// 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)
-
-		// COULD BE RE-IMPLEMENTED BY THE RENDERER!
-
-		if(!fill){
-			// don't fill
+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){
+
+/*===== 
+	dojox.gfx.shape = {
+		// summary:
+		//		This module contains the core graphics Shape API.
+		//		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
+	
+		constructor: function(){
+			//	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)
+			this.shape = null;
+	
+			//	matrix: dojox.gfx.Matrix2D
+			//		a transformation matrix
+			this.matrix = null;
+	
+			//	fillStyle: Object
+			//		a fill object
+			//		(see dojox.gfx.defaultLinearGradient,
+			//		dojox.gfx.defaultRadialGradient,
+			//		dojox.gfx.defaultPattern,
+			//		or dojo.Color)
 			this.fillStyle = null;
+	
+			//	strokeStyle: Object
+			//		a stroke object
+			//		(see dojox.gfx.defaultStroke)
+			this.strokeStyle = null;
+	
+			// bbox: dojox.gfx.Rectangle
+			//		a bounding box of this shape
+			//		(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)
+			this.parent = null;
+	
+			// parentMatrix: dojox.gfx.Matrix2D
+			//	a transformation matrix inherited from the parent
+			this.parentMatrix = null;
+			
+			var uid = shape.register(this);
+			this.getUID = function(){
+				return uid;
+			}
+		},	
+	
+		// 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.
+			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)
+			return this.shape; // Object
+		},
+		getTransform: function(){
+			// summary: Returns the current transformation matrix applied to this Shape or null
+			return this.matrix;	// dojox.gfx.Matrix2D
+		},
+		getFill: function(){
+			// 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)
+			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)
+			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
+		},
+		getTransformedBoundingBox: function(){
+			// 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
+			}
+			var m = this._getRealMatrix(),
+				gm = matrixLib;
+			return [	// Array
+					gm.multiplyPoint(m, b.x, b.y),
+					gm.multiplyPoint(m, b.x + b.width, b.y),
+					gm.multiplyPoint(m, b.x + b.width, b.y + b.height),
+					gm.multiplyPoint(m, b.x, b.y + b.height)
+				];
+		},
+		getEventSource: function(){
+			// 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
+	
+		setShape: function(shape){
+			// 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)
+			// COULD BE RE-IMPLEMENTED BY THE RENDERER!
+			this.shape = g.makeParameters(this.shape, shape);
+			this.bbox = null;
 			return this;	// self
-		}
-		var f = null;
-		if(typeof(fill) == "object" && "type" in fill){
-			// gradient or pattern
-			switch(fill.type){
-				case "linear":
-					f = dojox.gfx.makeParameters(dojox.gfx.defaultLinearGradient, fill);
-					break;
-				case "radial":
-					f = dojox.gfx.makeParameters(dojox.gfx.defaultRadialGradient, fill);
-					break;
-				case "pattern":
-					f = dojox.gfx.makeParameters(dojox.gfx.defaultPattern, fill);
-					break;
+		},
+		setFill: function(fill){
+			// 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)
+			// COULD BE RE-IMPLEMENTED BY THE RENDERER!
+			if(!fill){
+				// don't fill
+				this.fillStyle = null;
+				return this;	// self
+			}
+			var f = null;
+			if(typeof(fill) == "object" && "type" in fill){
+				// gradient or pattern
+				switch(fill.type){
+					case "linear":
+						f = g.makeParameters(g.defaultLinearGradient, fill);
+						break;
+					case "radial":
+						f = g.makeParameters(g.defaultRadialGradient, fill);
+						break;
+					case "pattern":
+						f = g.makeParameters(g.defaultPattern, fill);
+						break;
+				}
+			}else{
+				// color object
+				f = g.normalizeColor(fill);
+			}
+			this.fillStyle = f;
+			return this;	// self
+		},
+		setStroke: function(stroke){
+			// summary: sets a stroke object
+			//	(the default implementation simply ignores it)
+			// stroke: Object
+			//	a stroke object
+			//	(see dojox.gfx.defaultStroke)
+			// COULD BE RE-IMPLEMENTED BY THE RENDERER!
+			if(!stroke){
+				// don't stroke
+				this.strokeStyle = null;
+				return this;	// self
+			}
+			// normalize the stroke
+			if(typeof stroke == "string" || lang.isArray(stroke) || stroke instanceof Color){
+				stroke = {color: stroke};
+			}
+			var s = this.strokeStyle = g.makeParameters(g.defaultStroke, stroke);
+			s.color = g.normalizeColor(s.color);
+			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)
+			// 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
+			// COULD BE RE-IMPLEMENTED BY THE RENDERER!
+			return this;	// self
+		},
+	
+		// z-index
+	
+		moveToFront: function(){
+			// summary: moves a shape to front of its parent's list of shapes
+			var p = this.getParent();
+			if(p){
+				p._moveChildToFront(this);
+				this._moveToFront();	// execute renderer-specific action
+			}
+			return this;	// self
+		},
+		moveToBack: function(){
+			// summary: moves a shape to back of its parent's list of shapes
+			var p = this.getParent();
+			if(p){
+				p._moveChildToBack(this);
+				this._moveToBack();	// execute renderer-specific action
+			}
+			return this;
+		},
+		_moveToFront: function(){
+			// 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()
+			// 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)
+			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)
+			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)
+			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
+			// silently: Boolean
+			// 		if true, do not redraw a picture yet
+			if(this.parent){
+				this.parent.remove(this, silently);
 			}
-		}else{
-			// color object
-			f = dojox.gfx.normalizeColor(fill);
-		}
-		this.fillStyle = f;
-		return this;	// self
-	},
-	setStroke: function(stroke){
-		// summary: sets a stroke object
-		//	(the default implementation simply ignores it)
-		// stroke: Object: a stroke object
-		//	(see dojox.gfx.defaultStroke)
-
-		// COULD BE RE-IMPLEMENTED BY THE RENDERER!
-
-		if(!stroke){
-			// don't stroke
-			this.strokeStyle = null;
 			return this;	// self
+		},
+		_setParent: function(parent, matrix){
+			// 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
+			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
+			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
+			var m = this.matrix;
+			var p = this.parent;
+			while(p){
+				if(p.matrix){
+					m = matrixLib.multiply(p.matrix, m);
+				}
+				p = p.parent;
+			}
+			return m;	// dojox.gfx.Matrix2D
 		}
-		// normalize the stroke
-		if(typeof stroke == "string" || dojo.isArray(stroke) || stroke instanceof dojo.Color){
-			stroke = {color: stroke};
+	});
+	
+	shape._eventsProcessing = {
+		connect: function(name, object, method){
+			// 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));
+			
+		},
+		disconnect: function(token){
+			// summary: connects a handler by token from an event on this shape
+			// COULD BE RE-IMPLEMENTED BY THE RENDERER!
+	
+			events.disconnect(token);
 		}
-		var s = this.strokeStyle = dojox.gfx.makeParameters(dojox.gfx.defaultStroke, stroke);
-		s.color = dojox.gfx.normalizeColor(s.color);
-		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)
-
-		// COULD BE RE-IMPLEMENTED BY THE RENDERER!
-
-		this.matrix = dojox.gfx.matrix.clone(matrix ? dojox.gfx.matrix.normalize(matrix) : dojox.gfx.matrix.identity);
-		return this._applyTransform();	// self
-	},
-
-	_applyTransform: function(){
-		// summary: physically sets a matrix
-
-		// COULD BE RE-IMPLEMENTED BY THE RENDERER!
-
-		return this;	// self
-	},
-
-	// z-index
-
-	moveToFront: function(){
-		// summary: moves a shape to front of its parent's list of shapes
-		var p = this.getParent();
-		if(p){
-			p._moveChildToFront(this);
-			this._moveToFront();	// execute renderer-specific action
+	};
+	
+	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.
+		if(!method){
+			method = scope;
+			scope = null;
 		}
-		return this;	// self
-	},
-	moveToBack: function(){
-		// summary: moves a shape to back of its parent's list of shapes
-		var p = this.getParent();
-		if(p){
-			p._moveChildToBack(this);
-			this._moveToBack();	// execute renderer-specific action
+		if(lang.isString(method)){
+			scope = scope || win.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
 		}
-		return this;
-	},
-	_moveToFront: function(){
-		// 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()
-
-		// 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)
-		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)
-		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)
-		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
-		// silently: Boolean?: 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
-		// 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
-		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
-		this.parentMatrix = matrix ? dojox.gfx.matrix.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
-		var m = this.matrix;
-		var p = this.parent;
-		while(p){
-			if(p.matrix){
-				m = dojox.gfx.matrix.multiply(p.matrix, m);
+		return !scope 
+			? function(e){ 
+				return fixFunction(e,gfxElement) ? method.apply(scope, arguments) : undefined; } 
+			: function(e){ 
+				return fixFunction(e,gfxElement) ? method.apply(scope, arguments || []) : undefined; }; // Function
+	};
+	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)
+	
+		_init: function() {
+			// children: Array: a list of children
+			this.children = [];
+		},
+	
+		// 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
+		},
+		closeBatch: function() {
+			// summary: submits the current batch, append all pending child shapes to DOM
+		},
+		add: function(shape){
+			// summary: adds a shape to the list
+			// shape: dojox.gfx.Shape
+			//		the shape to add to the list
+			var oldParent = shape.getParent();
+			if(oldParent){
+				oldParent.remove(shape, true);
 			}
-			p = p.parent;
-		}
-		return m;	// dojox.gfx.Matrix2D
-	}
-});
-
-dojox.gfx.shape._eventsProcessing = {
-	connect: function(name, object, method){
-		// summary: connects a handler to an event on this shape
-
-		// COULD BE RE-IMPLEMENTED BY THE RENDERER!
-
-		return arguments.length > 2 ?	// Object
-			dojo.connect(this.getEventSource(), name, object, method) :
-			dojo.connect(this.getEventSource(), name, object);
-	},
-	disconnect: function(token){
-		// summary: connects a handler by token from an event on this shape
-
-		// COULD BE RE-IMPLEMENTED BY THE RENDERER!
-
-		dojo.disconnect(token);
-	}
-};
-
-dojo.extend(dojox.gfx.shape.Shape, dojox.gfx.shape._eventsProcessing);
-
-dojox.gfx.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)
-
-	_init: function() {
-		// children: Array: a list of children
-		this.children = [];
-	},
-
-	// 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
-	},
-	closeBatch: function() {
-		// summary: submits the current batch, append all pending child shapes to DOM
-	},
-	add: function(shape){
-		// summary: adds a shape to the list
-		// shape: dojox.gfx.Shape: a shape
-		var oldParent = shape.getParent();
-		if(oldParent){
-			oldParent.remove(shape, true);
-		}
-		this.children.push(shape);
-		return shape._setParent(this, this._getRealMatrix());	// self
-	},
-	remove: function(shape, silently){
-		// summary: removes a shape from the list
-		// silently: Boolean?: if true, do not redraw a picture yet
-		for(var i = 0; i < this.children.length; ++i){
-			if(this.children[i] == shape){
-				if(silently){
-					// skip for now
-				}else{
-					shape.parent = null;
-					shape.parentMatrix = null;
+			this.children.push(shape);
+			return shape._setParent(this, this._getRealMatrix());	// self
+		},
+		remove: function(shape, silently){
+			// 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
+			for(var i = 0; i < this.children.length; ++i){
+				if(this.children[i] == shape){
+					if(silently){
+						// skip for now
+					}else{
+						shape.parent = null;
+						shape.parentMatrix = null;
+					}
+					this.children.splice(i, 1);
+					break;
 				}
-				this.children.splice(i, 1);
-				break;
 			}
-		}
-		return this;	// self
-	},
-	clear: function(){
-		// summary: removes all shapes from a group/surface
-		this.children = [];
-		return this;	// self
-	},
-
-	// moving child nodes
-
-	_moveChildToFront: function(shape){
-		// summary: moves a shape to front of the list of shapes
-		for(var i = 0; i < this.children.length; ++i){
-			if(this.children[i] == shape){
-				this.children.splice(i, 1);
-				this.children.push(shape);
-				break;
+			return this;	// self
+		},
+		clear: function(){
+			// summary: removes all shapes from a group/surface
+			var shape;
+			for(var i = 0; i < this.children.length;++i){
+				shape = this.children[i];
+				shape.parent = null;
+				shape.parentMatrix = null;
 			}
-		}
-		return this;	// self
-	},
-	_moveChildToBack: function(shape){
-		// summary: moves a shape to back of the list of shapes
-		for(var i = 0; i < this.children.length; ++i){
-			if(this.children[i] == shape){
-				this.children.splice(i, 1);
-				this.children.unshift(shape);
-				break;
+			this.children = [];
+			return this;	// self
+		},
+	
+		// moving child nodes
+	
+		_moveChildToFront: function(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){
+					this.children.splice(i, 1);
+					this.children.push(shape);
+					break;
+				}
+			}
+			return this;	// self
+		},
+		_moveChildToBack: function(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){
+					this.children.splice(i, 1);
+					this.children.unshift(shape);
+					break;
+				}
 			}
+			return this;	// self
 		}
-		return this;	// self
-	}
-};
-
-dojo.declare("dojox.gfx.shape.Surface", null, {
-	// summary: a surface object to be used for drawings
-	constructor: function(){
-		// underlying node
-		this.rawNode = null;
-		// the parent node
-		this._parent = null;
-		// the list of DOM nodes to be deleted in the case of destruction
-		this._nodes = [];
-		// the list of events to be detached in the case of destruction
-		this._events = [];
-	},
-	destroy: function(){
-		// summary: destroy all relevant external resources and release all
-		//	external references to make this object garbage-collectible
-		dojo.forEach(this._nodes, dojo.destroy);
-		this._nodes = [];
-		dojo.forEach(this._events, dojo.disconnect);
-		this._events = [];
-		this.rawNode = null;	// recycle it in _nodes, if it needs to be recycled
-		if(dojo.isIE){
-			while(this._parent.lastChild){
-				dojo.destroy(this._parent.lastChild);
+	};
+	
+	declare("dojox.gfx.shape.Surface", null, {
+		// summary: a surface object to be used for drawings
+		constructor: function(){
+			// underlying node
+			this.rawNode = null;
+			// the parent node
+			this._parent = null;
+			// the list of DOM nodes to be deleted in the case of destruction
+			this._nodes = [];
+			// the list of events to be detached in the case of destruction
+			this._events = [];
+		},
+		destroy: function(){
+			// 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);
+			this._events = [];
+			this.rawNode = null;	// recycle it in _nodes, if it needs to be recycled
+			if(has("ie")){
+				while(this._parent.lastChild){
+					domConstruct.destroy(this._parent.lastChild);
+				}
+			}else{
+				this._parent.innerHTML = "";
+			}
+			this._parent = null;
+		},
+		getEventSource: function(){
+			// 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
+		},
+		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.
+		},
+		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);
+					f(surface);
+				});
 			}
-		}else{
-			this._parent.innerHTML = "";
 		}
-		this._parent = null;
-	},
-	getEventSource: function(){
-		// 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
-	},
-	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.
-	},
-	whenLoaded: function(
-		/*Object?*/ context,
-		/*Function|String*/ method
-	){
-		var f = dojo.hitch(context, method);
-		if(this.isLoaded){
-			f(this);
-		}else{
-			var h = dojo.connect(this, "onLoad", function(surface){
-				dojo.disconnect(h);
-				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}.
+	});
+	
+	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}.
+	});
+	
+	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)
+			this.shape = g.getDefault("Rect");
+			this.rawNode = rawNode;
+		},
+		getBoundingBox: function(){
+			// summary: returns the bounding box (its shape in this case)
+			return this.shape;	// dojox.gfx.Rectangle
 		}
-	}
-});
-
-dojo.extend(dojox.gfx.shape.Surface, dojox.gfx.shape._eventsProcessing);
-
-dojo.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}.
-});
-
-dojo.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}.
-});
-
-dojo.declare("dojox.gfx.shape.Rect", dojox.gfx.shape.Shape, {
-	// summary: a generic rectangle
-	constructor: function(rawNode){
-		// rawNode: Node: a DOM Node
-		this.shape = dojox.gfx.getDefault("Rect");
-		this.rawNode = rawNode;
-	},
-	getBoundingBox: function(){
-		// summary: returns the bounding box (its shape in this case)
-		return this.shape;	// dojox.gfx.Rectangle
-	}
-});
-
-dojo.declare("dojox.gfx.shape.Ellipse", dojox.gfx.shape.Shape, {
-	// summary: a generic ellipse
-	constructor: function(rawNode){
-		// rawNode: Node: a DOM Node
-		this.shape = dojox.gfx.getDefault("Ellipse");
-		this.rawNode = rawNode;
-	},
-	getBoundingBox: function(){
-		// 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
-	}
-});
-
-dojo.declare("dojox.gfx.shape.Circle", dojox.gfx.shape.Shape, {
-	// summary: a generic circle
-	//	(this is a helper object, which is defined for convenience)
-	constructor: function(rawNode){
-		// rawNode: Node: a DOM Node
-		this.shape = dojox.gfx.getDefault("Circle");
-		this.rawNode = rawNode;
-	},
-	getBoundingBox: function(){
-		// 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};
+	});
+	
+	declare("dojox.gfx.shape.Ellipse", shape.Shape, {
+		// summary: a generic ellipse
+		constructor: function(rawNode){
+			// rawNode: Node
+			//		a DOM Node
+			this.shape = g.getDefault("Ellipse");
+			this.rawNode = rawNode;
+		},
+		getBoundingBox: function(){
+			// 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
-	}
-});
-
-dojo.declare("dojox.gfx.shape.Line", dojox.gfx.shape.Shape, {
-	// summary: a generic line
-	//	(this is a helper object, which is defined for convenience)
-	constructor: function(rawNode){
-		// rawNode: Node: a DOM Node
-		this.shape = dojox.gfx.getDefault("Line");
-		this.rawNode = rawNode;
-	},
-	getBoundingBox: function(){
-		// summary: returns the bounding box
-		if(!this.bbox){
-			var shape = this.shape;
-			this.bbox = {
-				x:		Math.min(shape.x1, shape.x2),
-				y:		Math.min(shape.y1, shape.y2),
-				width:	Math.abs(shape.x2 - shape.x1),
-				height:	Math.abs(shape.y2 - shape.y1)
-			};
+	});
+	
+	declare("dojox.gfx.shape.Circle", shape.Shape, {
+		// summary: a generic circle
+		//	(this is a helper object, which is defined for convenience)
+		constructor: function(rawNode){
+			// rawNode: Node
+			//		a DOM Node
+			this.shape = g.getDefault("Circle");
+			this.rawNode = rawNode;
+		},
+		getBoundingBox: function(){
+			// 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
-	}
-});
-
-dojo.declare("dojox.gfx.shape.Polyline", dojox.gfx.shape.Shape, {
-	// summary: a generic polyline/polygon
-	//	(this is a helper object, which is defined for convenience)
-	constructor: function(rawNode){
-		// rawNode: Node: a DOM Node
-		this.shape = dojox.gfx.getDefault("Polyline");
-		this.rawNode = rawNode;
-	},
-	setShape: function(points, closed){
-		// summary: sets a polyline/polygon shape object
-		// points: Object: a polyline/polygon shape object
-		// 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]);
+	});
+	
+	declare("dojox.gfx.shape.Line", shape.Shape, {
+		// summary: a generic line
+		//	(this is a helper object, which is defined for convenience)
+		constructor: function(rawNode){
+			// rawNode: Node
+			//		a DOM Node
+			this.shape = g.getDefault("Line");
+			this.rawNode = rawNode;
+		},
+		getBoundingBox: function(){
+			// summary: returns the bounding box
+			if(!this.bbox){
+				var shape = this.shape;
+				this.bbox = {
+					x:		Math.min(shape.x1, shape.x2),
+					y:		Math.min(shape.y1, shape.y2),
+					width:	Math.abs(shape.x2 - shape.x1),
+					height:	Math.abs(shape.y2 - shape.y1)
+				};
 			}
-		}else{
-			this.inherited(arguments, [points]);
+			return this.bbox;	// dojox.gfx.Rectangle
 		}
-		return this;	// self
-	},
-	_normalizePoints: function(){
-		// 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 = [];
-			for(var i = 0; i < l; i += 2){
-				points.push({x: p[i], y: p[i + 1]});
+	});
+	
+	declare("dojox.gfx.shape.Polyline", shape.Shape, {
+		// summary: a generic polyline/polygon
+		//	(this is a helper object, which is defined for convenience)
+		constructor: function(rawNode){
+			// rawNode: Node
+			//		a DOM Node
+			this.shape = g.getDefault("Polyline");
+			this.rawNode = rawNode;
+		},
+		setShape: function(points, closed){
+			// summary: sets a polyline/polygon shape object
+			// points: Object
+			//		a polyline/polygon shape object
+			// 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]);
+				}
+			}else{
+				this.inherited(arguments, [points]);
 			}
-			this.shape.points = points;
+			return this;	// self
+		},
+		_normalizePoints: function(){
+			// 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 = [];
+				for(var i = 0; i < l; i += 2){
+					points.push({x: p[i], y: p[i + 1]});
+				}
+				this.shape.points = points;
+			}
+		},
+		getBoundingBox: function(){
+			// summary: returns the bounding box
+			if(!this.bbox && this.shape.points.length){
+				var p = this.shape.points;
+				var l = p.length;
+				var t = p[0];
+				var bbox = {l: t.x, t: t.y, r: t.x, b: t.y};
+				for(var i = 1; i < l; ++i){
+					t = p[i];
+					if(bbox.l > t.x) bbox.l = t.x;
+					if(bbox.r < t.x) bbox.r = t.x;
+					if(bbox.t > t.y) bbox.t = t.y;
+					if(bbox.b < t.y) bbox.b = t.y;
+				}
+				this.bbox = {
+					x:		bbox.l,
+					y:		bbox.t,
+					width:	bbox.r - bbox.l,
+					height:	bbox.b - bbox.t
+				};
+			}
+			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)
+		constructor: function(rawNode){
+			// rawNode: Node
+			//		a DOM Node
+			this.shape = g.getDefault("Image");
+			this.rawNode = rawNode;
+		},
+		getBoundingBox: function(){
+			// summary: returns the bounding box (its shape in this case)
+			return this.shape;	// dojox.gfx.Rectangle
+		},
+		setStroke: function(){
+			// summary: ignore setting a stroke style
+			return this;	// self
+		},
+		setFill: function(){
+			// summary: ignore setting a fill style
+			return this;	// self
+		}
+	});
+	
+	declare("dojox.gfx.shape.Text", shape.Shape, {
+		// summary: a generic text
+		constructor: function(rawNode){
+			// rawNode: Node
+			//		a DOM Node
+			this.fontStyle = null;
+			this.shape = g.getDefault("Text");
+			this.rawNode = rawNode;
+		},
+		getFont: function(){
+			// summary: returns the current font object or null
+			return this.fontStyle;	// Object
+		},
+		setFont: function(newFont){
+			// summary: sets a font for text
+			// newFont: Object
+			//		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(){
-		// summary: returns the bounding box
-		if(!this.bbox && this.shape.points.length){
-			var p = this.shape.points;
-			var l = p.length;
-			var t = p[0];
-			var bbox = {l: t.x, t: t.y, r: t.x, b: t.y};
-			for(var i = 1; i < l; ++i){
-				t = p[i];
-				if(bbox.l > t.x) bbox.l = t.x;
-				if(bbox.r < t.x) bbox.r = t.x;
-				if(bbox.t > t.y) bbox.t = t.y;
-				if(bbox.b < t.y) bbox.b = t.y;
+	});
+	
+	shape.Creator = {
+		// 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
+			// shape: Object
+			//		a shape descriptor 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.defaultLine.type:		return this.createLine(shape);
+				case g.defaultPolyline.type:	return this.createPolyline(shape);
+				case g.defaultImage.type:		return this.createImage(shape);
+				case g.defaultText.type:		return this.createText(shape);
+				case g.defaultTextPath.type:	return this.createTextPath(shape);
 			}
-			this.bbox = {
-				x:		bbox.l,
-				y:		bbox.t,
-				width:	bbox.r - bbox.l,
-				height:	bbox.b - bbox.t
-			};
+			return null;
+		},
+		createGroup: function(){
+			// summary: creates a group shape
+			return this.createObject(g.Group);	// dojox.gfx.Group
+		},
+		createRect: function(rect){
+			// summary: creates a rectangle shape
+			// rect: Object
+			//		a path object (see dojox.gfx.defaultRect)
+			return this.createObject(g.Rect, rect);	// dojox.gfx.Rect
+		},
+		createEllipse: function(ellipse){
+			// summary: creates an ellipse shape
+			// ellipse: Object
+			//		an ellipse object (see dojox.gfx.defaultEllipse)
+			return this.createObject(g.Ellipse, ellipse);	// dojox.gfx.Ellipse
+		},
+		createCircle: function(circle){
+			// summary: creates a circle shape
+			// circle: Object
+			//		a circle object (see dojox.gfx.defaultCircle)
+			return this.createObject(g.Circle, circle);	// dojox.gfx.Circle
+		},
+		createLine: function(line){
+			// summary: creates a line shape
+			// line: Object
+			//		a line object (see dojox.gfx.defaultLine)
+			return this.createObject(g.Line, line);	// dojox.gfx.Line
+		},
+		createPolyline: function(points){
+			// summary: creates a polyline/polygon shape
+			// points: Object
+			//		a points object (see dojox.gfx.defaultPolyline)
+			//		or an Array of points
+			return this.createObject(g.Polyline, points);	// dojox.gfx.Polyline
+		},
+		createImage: function(image){
+			// summary: creates a image shape
+			// image: Object
+			//		an image object (see dojox.gfx.defaultImage)
+			return this.createObject(g.Image, image);	// dojox.gfx.Image
+		},
+		createText: function(text){
+			// summary: creates a text shape
+			// text: Object
+			//		a text object (see dojox.gfx.defaultText)
+			return this.createObject(g.Text, text);	// dojox.gfx.Text
+		},
+		createPath: function(path){
+			// summary: creates a path shape
+			// path: Object
+			//		a path object (see dojox.gfx.defaultPath)
+			return this.createObject(g.Path, path);	// dojox.gfx.Path
+		},
+		createTextPath: function(text){
+			// summary: creates a text shape
+			// text: Object
+			//		a textpath object (see dojox.gfx.defaultTextPath)
+			return this.createObject(g.TextPath, {}).setText(text);	// dojox.gfx.TextPath
+		},
+		createObject: function(shapeType, rawShape){
+			// summary: creates an instance of the passed shapeType class
+			// SHOULD BE RE-IMPLEMENTED BY THE RENDERER!
+			// 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
 		}
-		return this.bbox;	// dojox.gfx.Rectangle
-	}
+	};
+	
+	return shape;
 });
 
-dojo.declare("dojox.gfx.shape.Image", dojox.gfx.shape.Shape, {
-	// summary: a generic image
-	//	(this is a helper object, which is defined for convenience)
-	constructor: function(rawNode){
-		// rawNode: Node: a DOM Node
-		this.shape = dojox.gfx.getDefault("Image");
-		this.rawNode = rawNode;
-	},
-	getBoundingBox: function(){
-		// summary: returns the bounding box (its shape in this case)
-		return this.shape;	// dojox.gfx.Rectangle
-	},
-	setStroke: function(){
-		// summary: ignore setting a stroke style
-		return this;	// self
-	},
-	setFill: function(){
-		// summary: ignore setting a fill style
-		return this;	// self
-	}
-});
-
-dojo.declare("dojox.gfx.shape.Text", dojox.gfx.shape.Shape, {
-	// summary: a generic text
-	constructor: function(rawNode){
-		// rawNode: Node: a DOM Node
-		this.fontStyle = null;
-		this.shape = dojox.gfx.getDefault("Text");
-		this.rawNode = rawNode;
-	},
-	getFont: function(){
-		// summary: returns the current font object or null
-		return this.fontStyle;	// Object
-	},
-	setFont: function(newFont){
-		// summary: sets a font for text
-		// newFont: Object: a font object (see dojox.gfx.defaultFont) or a font string
-		this.fontStyle = typeof newFont == "string" ? dojox.gfx.splitFontString(newFont) :
-			dojox.gfx.makeParameters(dojox.gfx.defaultFont, newFont);
-		this._setFont();
-		return this;	// self
-	}
-});
-
-dojox.gfx.shape.Creator = {
-	// 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
-		// shape: Object: a shape descriptor object
-		var gfx = dojox.gfx;
-		switch(shape.type){
-			case gfx.defaultPath.type:		return this.createPath(shape);
-			case gfx.defaultRect.type:		return this.createRect(shape);
-			case gfx.defaultCircle.type:	return this.createCircle(shape);
-			case gfx.defaultEllipse.type:	return this.createEllipse(shape);
-			case gfx.defaultLine.type:		return this.createLine(shape);
-			case gfx.defaultPolyline.type:	return this.createPolyline(shape);
-			case gfx.defaultImage.type:		return this.createImage(shape);
-			case gfx.defaultText.type:		return this.createText(shape);
-			case gfx.defaultTextPath.type:	return this.createTextPath(shape);
-		}
-		return null;
-	},
-	createGroup: function(){
-		// summary: creates a group shape
-		return this.createObject(dojox.gfx.Group);	// dojox.gfx.Group
-	},
-	createRect: function(rect){
-		// summary: creates a rectangle shape
-		// rect: Object: a path object (see dojox.gfx.defaultRect)
-		return this.createObject(dojox.gfx.Rect, rect);	// dojox.gfx.Rect
-	},
-	createEllipse: function(ellipse){
-		// summary: creates an ellipse shape
-		// ellipse: Object: an ellipse object (see dojox.gfx.defaultEllipse)
-		return this.createObject(dojox.gfx.Ellipse, ellipse);	// dojox.gfx.Ellipse
-	},
-	createCircle: function(circle){
-		// summary: creates a circle shape
-		// circle: Object: a circle object (see dojox.gfx.defaultCircle)
-		return this.createObject(dojox.gfx.Circle, circle);	// dojox.gfx.Circle
-	},
-	createLine: function(line){
-		// summary: creates a line shape
-		// line: Object: a line object (see dojox.gfx.defaultLine)
-		return this.createObject(dojox.gfx.Line, line);	// dojox.gfx.Line
-	},
-	createPolyline: function(points){
-		// summary: creates a polyline/polygon shape
-		// points: Object: a points object (see dojox.gfx.defaultPolyline)
-		//	or an Array of points
-		return this.createObject(dojox.gfx.Polyline, points);	// dojox.gfx.Polyline
-	},
-	createImage: function(image){
-		// summary: creates a image shape
-		// image: Object: an image object (see dojox.gfx.defaultImage)
-		return this.createObject(dojox.gfx.Image, image);	// dojox.gfx.Image
-	},
-	createText: function(text){
-		// summary: creates a text shape
-		// text: Object: a text object (see dojox.gfx.defaultText)
-		return this.createObject(dojox.gfx.Text, text);	// dojox.gfx.Text
-	},
-	createPath: function(path){
-		// summary: creates a path shape
-		// path: Object: a path object (see dojox.gfx.defaultPath)
-		return this.createObject(dojox.gfx.Path, path);	// dojox.gfx.Path
-	},
-	createTextPath: function(text){
-		// summary: creates a text shape
-		// text: Object: a textpath object (see dojox.gfx.defaultTextPath)
-		return this.createObject(dojox.gfx.TextPath, {}).setText(text);	// dojox.gfx.TextPath
-	},
-	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
-
-		// SHOULD BE RE-IMPLEMENTED BY THE RENDERER!
-
-		return null;	// dojox.gfx.Shape
-	}
-};
diff --git a/dojox/gfx/silverlight.js b/dojox/gfx/silverlight.js
index f5b653d..a7996ef 100644
--- a/dojox/gfx/silverlight.js
+++ b/dojox/gfx/silverlight.js
@@ -1,13 +1,32 @@
-dojo.provide("dojox.gfx.silverlight");
-
-dojo.require("dojox.gfx._base");
-dojo.require("dojox.gfx.shape");
-dojo.require("dojox.gfx.path");
-
-dojo.experimental("dojox.gfx.silverlight");
-
-(function(){
-	var d = dojo, g = dojox.gfx, gs = g.shape, sl = g.silverlight;
+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
+	};
+	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 = {
 			solid:				"none",
@@ -45,7 +64,7 @@ dojo.experimental("dojox.gfx.silverlight");
 		return "#" + (a.length < 2 ? "0" + a : a) + t.slice(1);	// String
 	}
 
-	d.declare("dojox.gfx.silverlight.Shape", gs.Shape, {
+	declare("dojox.gfx.silverlight.Shape", gs.Shape, {
 		// summary: Silverlight-specific implementation of dojox.gfx.Shape methods
 
 		setFill: function(fill){
@@ -72,7 +91,7 @@ dojo.experimental("dojox.gfx.silverlight");
 						lgb.mappingMode = "Absolute";
 						lgb.startPoint = f.x1 + "," + f.y1;
 						lgb.endPoint = f.x2 + "," + f.y2;
-						d.forEach(f.colors, function(c){
+						arr.forEach(f.colors, function(c){
 							var t = p.createFromXaml("<GradientStop/>");
 							t.offset = c.offset;
 							t.color = hexColor(c.color);
@@ -89,7 +108,7 @@ dojo.experimental("dojox.gfx.silverlight");
 						rgb.gradientOrigin = pt;
 						rgb.center = pt;
 						rgb.radiusX = rgb.radiusY = f.r;
-						d.forEach(f.colors, function(c){
+						arr.forEach(f.colors, function(c){
 							var t = p.createFromXaml("<GradientStop/>");
 							t.offset = c.offset;
 							t.color = hexColor(c.color);
@@ -130,7 +149,7 @@ dojo.experimental("dojox.gfx.silverlight");
 				return this;
 			}
 			// normalize the stroke
-			if(typeof stroke == "string" || d.isArray(stroke) || stroke instanceof d.Color){
+			if(typeof stroke == "string" || lang.isArray(stroke) || stroke instanceof color){
 				stroke = {color: stroke};
 			}
 			var s = this.strokeStyle = g.makeParameters(g.defaultStroke, stroke);
@@ -153,7 +172,7 @@ dojo.experimental("dojox.gfx.silverlight");
 				var da = s.style.toLowerCase();
 				if(da in dasharray){ da = dasharray[da]; }
 				if(da instanceof Array){
-					da = d.clone(da);
+					da = lang.clone(da);
 					var i;
 					/*
 					for(var i = 0; i < da.length; ++i){
@@ -213,6 +232,7 @@ dojo.experimental("dojox.gfx.silverlight");
 			rawNode.fill = null;
 			rawNode.stroke = null;
 			this.rawNode = rawNode;
+			this.rawNode.tag = this.getUID();						
 		},
 
 		// move family
@@ -238,7 +258,7 @@ dojo.experimental("dojox.gfx.silverlight");
 		}
 	});
 
-	d.declare("dojox.gfx.silverlight.Group", sl.Shape, {
+	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(){
@@ -248,11 +268,13 @@ dojo.experimental("dojox.gfx.silverlight");
 			// summary: sets a raw Silverlight node to be used by this shape
 			// rawNode: Node: an Silverlight node
 			this.rawNode = rawNode;
+			this.rawNode.tag = this.getUID();						
+			
 		}
 	});
 	sl.Group.nodeType = "Canvas";
 
-	d.declare("dojox.gfx.silverlight.Rect", [sl.Shape, gs.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)
@@ -273,7 +295,7 @@ dojo.experimental("dojox.gfx.silverlight");
 	});
 	sl.Rect.nodeType = "Rectangle";
 
-	d.declare("dojox.gfx.silverlight.Ellipse", [sl.Shape, gs.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)
@@ -293,7 +315,7 @@ dojo.experimental("dojox.gfx.silverlight");
 	});
 	sl.Ellipse.nodeType = "Ellipse";
 
-	d.declare("dojox.gfx.silverlight.Circle", [sl.Shape, gs.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)
@@ -312,7 +334,7 @@ dojo.experimental("dojox.gfx.silverlight");
 	});
 	sl.Circle.nodeType = "Ellipse";
 
-	d.declare("dojox.gfx.silverlight.Line", [sl.Shape, gs.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)
@@ -326,7 +348,7 @@ dojo.experimental("dojox.gfx.silverlight");
 	});
 	sl.Line.nodeType = "Line";
 
-	d.declare("dojox.gfx.silverlight.Polyline", [sl.Shape, gs.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)
@@ -353,7 +375,7 @@ dojo.experimental("dojox.gfx.silverlight");
 	});
 	sl.Polyline.nodeType = "Polyline";
 
-	d.declare("dojox.gfx.silverlight.Image", [sl.Shape, gs.Image], {
+	declare("dojox.gfx.silverlight.Image", [sl.Shape, gs.Image], {
 		// summary: an image (Silverlight)
 		setShape: function(newShape){
 			// summary: sets an image shape object (Silverlight)
@@ -377,11 +399,12 @@ dojo.experimental("dojox.gfx.silverlight");
 			//	shape. Once set, transforms, gradients, etc, can be applied.
 			//	(no fill & stroke by default)
 			this.rawNode = rawNode;
+			this.rawNode.tag = this.getUID();						
 		}
 	});
 	sl.Image.nodeType = "Image";
 
-	d.declare("dojox.gfx.silverlight.Text", [sl.Shape, gs.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)
@@ -394,7 +417,7 @@ dojo.experimental("dojox.gfx.silverlight");
 			r["Canvas.Left"] = -10000;
 			r["Canvas.Top"]  = -10000;
 			if(!this._delay){
-				this._delay = window.setTimeout(d.hitch(this, "_delayAlignment"), 10);
+				this._delay = window.setTimeout(lang.hitch(this, "_delayAlignment"), 10);
 			}
 			return this;	// self
 		},
@@ -446,6 +469,7 @@ dojo.experimental("dojox.gfx.silverlight");
 			//	shape. Once set, transforms, gradients, etc, can be applied.
 			//	(no fill & stroke by default)
 			this.rawNode = rawNode;
+			this.rawNode.tag = this.getUID();						
 		},
 		getTextWidth: function(){
 			// summary: get the text width in pixels
@@ -454,7 +478,7 @@ dojo.experimental("dojox.gfx.silverlight");
 	});
 	sl.Text.nodeType = "TextBlock";
 
-	d.declare("dojox.gfx.silverlight.Path", [sl.Shape, g.path.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
@@ -476,7 +500,7 @@ dojo.experimental("dojox.gfx.silverlight");
 	});
 	sl.Path.nodeType = "Path";
 
-	d.declare("dojox.gfx.silverlight.TextPath", [sl.Shape, g.path.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
@@ -493,7 +517,7 @@ dojo.experimental("dojox.gfx.silverlight");
 
 	var surfaces = {}, nullFunc = new Function;
 
-	d.declare("dojox.gfx.silverlight.Surface", gs.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);
@@ -533,7 +557,7 @@ dojo.experimental("dojox.gfx.silverlight");
 		// height: String: height of surface, e.g., "100px"
 
 		if(!width && !height){
-			var pos = d.position(parentNode);
+			var pos = domGeom.position(parentNode);
 			width  = width  || pos.w;
 			height = height || pos.h;
 		}
@@ -545,7 +569,7 @@ dojo.experimental("dojox.gfx.silverlight");
 		}
 
 		var s = new sl.Surface();
-		parentNode = d.byId(parentNode);
+		parentNode = dom.byId(parentNode);
 		s._parent = parentNode;
 		s._nodeName = g._base._getUniqueId();
 
@@ -564,13 +588,13 @@ dojo.experimental("dojox.gfx.silverlight");
 		s._onLoadName = onLoadName;
 		window[onLoadName] = function(sender){
 			if(!s.rawNode){
-				s.rawNode = d.byId(pluginName).content.root;
+				s.rawNode = dom.byId(pluginName).content.root;
 				// register the plugin with its parent node
 				surfaces[s._nodeName] = parentNode;
 				s.onLoad(s);
 			}
 		};
-		if(d.isSafari){
+		if(has("safari")){
 			obj = "<embed type='application/x-silverlight' id='" +
 			pluginName + "' width='" + width + "' height='" + height +
 			" background='transparent'" +
@@ -593,7 +617,7 @@ dojo.experimental("dojox.gfx.silverlight");
 		}
 		parentNode.innerHTML = obj;
 
-		var pluginNode = d.byId(pluginName);
+		var pluginNode = dom.byId(pluginName);
 		if(pluginNode.content && pluginNode.content.root){
 			// the plugin was created synchronously
 			s.rawNode = pluginNode.content.root;
@@ -649,7 +673,7 @@ dojo.experimental("dojox.gfx.silverlight");
 
 			// update the transform
 			if(!this._delay){
-				this._delay = window.setTimeout(d.hitch(this, "_delayAlignment"), 10);
+				this._delay = window.setTimeout(lang.hitch(this, "_delayAlignment"), 10);
 			}
 		}
 	};
@@ -701,16 +725,16 @@ dojo.experimental("dojox.gfx.silverlight");
 		}
 	};
 
-	d.extend(sl.Text, Font);
-	//d.extend(sl.TextPath, Font);
+	lang.extend(sl.Text, Font);
+	//dojo.extend(sl.TextPath, Font);
 
-	d.extend(sl.Group, Container);
-	d.extend(sl.Group, gs.Creator);
-	d.extend(sl.Group, Creator);
+	lang.extend(sl.Group, Container);
+	lang.extend(sl.Group, gs.Creator);
+	lang.extend(sl.Group, Creator);
 
-	d.extend(sl.Surface, Container);
-	d.extend(sl.Surface, gs.Creator);
-	d.extend(sl.Surface, Creator);
+	lang.extend(sl.Surface, Container);
+	lang.extend(sl.Surface, gs.Creator);
+	lang.extend(sl.Surface, Creator);
 
 	function mouseFix(s, a){
 		var ev = {target: s, currentTarget: s, preventDefault: function(){}, stopPropagation: function(){}};
@@ -718,6 +742,8 @@ dojo.experimental("dojox.gfx.silverlight");
 			if(a.source){
 				// support silverlight 2.0
 				ev.target = a.source;
+				var gfxId = ev.target.tag;				
+				ev.gfxTarget = gs.byId(gfxId);
 			}
 		}catch(e){
 			// a.source does not exist in 1.0
@@ -732,7 +758,7 @@ dojo.experimental("dojox.gfx.silverlight");
 				ev.y = ev.offsetY = ev.layerY = p.y;
 				// calculate clientX and clientY
 				var parent = surfaces[s.getHost().content.root.name];
-				var t = d.position(parent);
+				var t = domGeom.position(parent);
 				ev.clientX = t.x + p.x;
 				ev.clientY = t.y + p.y;
 			}catch(e){
@@ -752,6 +778,7 @@ dojo.experimental("dojox.gfx.silverlight");
 			if(a.source){
 				// source is defined from Silverlight 2+
 				ev.target = a.source;
+				ev.gfxTarget = gs.byId(ev.target.tag);
 			}
 		}catch(e){
 			// a.source does not exist in 1.0
@@ -778,7 +805,7 @@ dojo.experimental("dojox.gfx.silverlight");
 				{name: name, fix: function(){ return {}; }};
 			if(arguments.length > 2){
 				token = this.getEventSource().addEventListener(n.name,
-					function(s, a){ d.hitch(object, method)(n.fix(s, a)); });
+					function(s, a){ lang.hitch(object, method)(n.fix(s, a)); });
 			}else{
 				token = this.getEventSource().addEventListener(n.name,
 					function(s, a){ object(n.fix(s, a)); });
@@ -794,8 +821,8 @@ dojo.experimental("dojox.gfx.silverlight");
 		}
 	};
 	
-	d.extend(sl.Shape, eventsProcessing);
-	d.extend(sl.Surface, eventsProcessing);
+	lang.extend(sl.Shape, eventsProcessing);
+	lang.extend(sl.Surface, eventsProcessing);
 	
 	// patch dojox.gfx
 	g.equalSources = function(a, b){
@@ -803,10 +830,6 @@ dojo.experimental("dojox.gfx.silverlight");
 		return a && b && a.equals(b);
 	};
 	
-	// see if we are required to initilize
-	if(g.loadAndSwitch === "silverlight"){
-		g.switchTo("silverlight");
-		delete g.loadAndSwitch;
-	}
-})();
+	return sl;
+});
 
diff --git a/dojox/gfx/silverlight_attach.js b/dojox/gfx/silverlight_attach.js
index 491a58c..c5b909e 100644
--- a/dojox/gfx/silverlight_attach.js
+++ b/dojox/gfx/silverlight_attach.js
@@ -1,11 +1,7 @@
-dojo.provide("dojox.gfx.silverlight_attach");
-
-dojo.require("dojox.gfx.silverlight");
-
-dojo.experimental("dojox.gfx.silverlight_attach");
-
-(function(){
-	var g = dojox.gfx, sl = g.silverlight;
+define(["dojo/_base/kernel", "dojo/_base/lang", "./_base", "./silverlight"], 
+  function(kernel, lang, g, sl){
+	lang.getObject("dojox.gfx.silverlight_attach", true);
+	kernel.experimental("dojox.gfx.silverlight_attach");
 	
 	sl.attachNode = function(node){
 		// summary: creates a shape from a Node
@@ -18,4 +14,6 @@ dojo.experimental("dojox.gfx.silverlight_attach");
 		// node: Node: an 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 8355fc8..7094176 100644
--- a/dojox/gfx/svg.js
+++ b/dojox/gfx/svg.js
@@ -1,38 +1,62 @@
-dojo.provide("dojox.gfx.svg");
+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.
+	};
+	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");
 
-dojo.require("dojox.gfx._base");
-dojo.require("dojox.gfx.shape");
-dojo.require("dojox.gfx.path");
+	// 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;
 
-(function(){
-	var d = dojo, g = dojox.gfx, gs = g.shape, svg = g.svg;
-	svg.useSvgWeb = (typeof window.svgweb != "undefined");
-	
 	function _createElementNS(ns, nodeType){
 		// summary:
 		//		Internal helper to deal with creating elements that
 		//		are namespaced.  Mainly to get SVG markup output
 		//		working on IE.
-		if(dojo.doc.createElementNS){
-			return dojo.doc.createElementNS(ns,nodeType);
+		if(win.doc.createElementNS){
+			return win.doc.createElementNS(ns,nodeType);
 		}else{
-			return dojo.doc.createElement(nodeType);
+			return win.doc.createElement(nodeType);
 		}
 	}
-	
+
 	function _createTextNode(text){
 		if(svg.useSvgWeb){
-			return dojo.doc.createTextNode(text, true);
+			return win.doc.createTextNode(text, true);
 		}else{
-			return dojo.doc.createTextNode(text);
+			return win.doc.createTextNode(text);
 		}
 	}
-	
+
 	function _createFragment(){
 		if(svg.useSvgWeb){
-			return dojo.doc.createDocumentFragment(true);
+			return win.doc.createDocumentFragment(true);
 		}else{
-			return dojo.doc.createDocumentFragment();
+			return win.doc.createDocumentFragment();
 		}
 	}
 
@@ -46,12 +70,12 @@ dojo.require("dojox.gfx.path");
 		// name: String: an SVG external reference
 		if(!name || name == "none") return null;
 		if(name.match(/^url\(#.+\)$/)){
-			return d.byId(name.slice(5, -1));	// Node
+			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
-			return d.byId(name.slice(1));	// Node
+			return dom.byId(name.slice(1));	// Node
 		}
 		return null;	// Node
 	};
@@ -70,7 +94,7 @@ dojo.require("dojox.gfx.path");
 		longdashdotdot:		[8, 3, 1, 3, 1, 3]
 	};
 
-	d.declare("dojox.gfx.svg.Shape", gs.Shape, {
+	declare("dojox.gfx.svg.Shape", gs.Shape, {
 		// summary: SVG-specific implementation of dojox.gfx.Shape methods
 
 		setFill: function(fill){
@@ -100,24 +124,24 @@ dojo.require("dojox.gfx.path");
 					case "linear":
 						f = g.makeParameters(g.defaultLinearGradient, fill);
 						var gradient = this._setFillObject(f, "linearGradient");
-						d.forEach(["x1", "y1", "x2", "y2"], setter, gradient);
+						arr.forEach(["x1", "y1", "x2", "y2"], setter, gradient);
 						break;
 					case "radial":
 						f = g.makeParameters(g.defaultRadialGradient, fill);
-						var gradient = this._setFillObject(f, "radialGradient");
-						d.forEach(["cx", "cy", "r"], setter, gradient);
+						var grad = this._setFillObject(f, "radialGradient");
+						arr.forEach(["cx", "cy", "r"], setter, grad);
 						break;
 					case "pattern":
 						f = g.makeParameters(g.defaultPattern, fill);
 						var pattern = this._setFillObject(f, "pattern");
-						d.forEach(["x", "y", "width", "height"], setter, pattern);
+						arr.forEach(["x", "y", "width", "height"], setter, pattern);
 						break;
 				}
 				this.fillStyle = f;
 				return this;
 			}
 			// color object
-			var f = g.normalizeColor(fill);
+			f = g.normalizeColor(fill);
 			this.fillStyle = f;
 			this.rawNode.setAttribute("fill", f.toCss());
 			this.rawNode.setAttribute("fill-opacity", f.a);
@@ -140,7 +164,7 @@ dojo.require("dojox.gfx.path");
 				return this;
 			}
 			// normalize the stroke
-			if(typeof stroke == "string" || d.isArray(stroke) || stroke instanceof d.Color){
+			if(typeof stroke == "string" || lang.isArray(stroke) || stroke instanceof Color){
 				stroke = { color: stroke };
 			}
 			var s = this.strokeStyle = g.makeParameters(g.defaultStroke, stroke);
@@ -162,7 +186,7 @@ dojo.require("dojox.gfx.path");
 					da = svg.dasharray[da];
 				}
 				if(da instanceof Array){
-					da = d._toArray(da);
+					da = lang._toArray(da);
 					for(var i = 0; i < da.length; ++i){
 						da[i] *= s.width;
 					}
@@ -270,6 +294,9 @@ dojo.require("dojox.gfx.path");
 			r.setAttribute("stroke-linecap", "butt");
 			r.setAttribute("stroke-linejoin", "miter");
 			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();
 		},
 
 		setShape: function(newShape){
@@ -306,7 +333,7 @@ dojo.require("dojox.gfx.path");
 		}
 	});
 
-	dojo.declare("dojox.gfx.svg.Group", svg.Shape, {
+	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(){
@@ -316,11 +343,14 @@ dojo.require("dojox.gfx.path");
 			// 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();
 		}
 	});
 	svg.Group.nodeType = "g";
 
-	dojo.declare("dojox.gfx.svg.Rect", [svg.Shape, gs.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)
@@ -332,7 +362,7 @@ dojo.require("dojox.gfx.path");
 					this.rawNode.setAttribute(i, this.shape[i]);
 				}
 			}
-			if(this.shape.r){
+			if(this.shape.r != null){
 				this.rawNode.setAttribute("ry", this.shape.r);
 				this.rawNode.setAttribute("rx", this.shape.r);
 			}
@@ -341,16 +371,16 @@ dojo.require("dojox.gfx.path");
 	});
 	svg.Rect.nodeType = "rect";
 
-	dojo.declare("dojox.gfx.svg.Ellipse", [svg.Shape, gs.Ellipse], {});
+	declare("dojox.gfx.svg.Ellipse", [svg.Shape, gs.Ellipse], {});
 	svg.Ellipse.nodeType = "ellipse";
 
-	dojo.declare("dojox.gfx.svg.Circle", [svg.Shape, gs.Circle], {});
+	declare("dojox.gfx.svg.Circle", [svg.Shape, gs.Circle], {});
 	svg.Circle.nodeType = "circle";
 
-	dojo.declare("dojox.gfx.svg.Line", [svg.Shape, gs.Line], {});
+	declare("dojox.gfx.svg.Line", [svg.Shape, gs.Line], {});
 	svg.Line.nodeType = "line";
 
-	dojo.declare("dojox.gfx.svg.Polyline", [svg.Shape, gs.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)
@@ -377,7 +407,7 @@ dojo.require("dojox.gfx.path");
 	});
 	svg.Polyline.nodeType = "polyline";
 
-	dojo.declare("dojox.gfx.svg.Image", [svg.Shape, gs.Image], {
+	declare("dojox.gfx.svg.Image", [svg.Shape, gs.Image], {
 		// summary: an image (SVG)
 		setShape: function(newShape){
 			// summary: sets an image shape object (SVG)
@@ -392,12 +422,15 @@ dojo.require("dojox.gfx.path");
 			}
 			rawNode.setAttribute("preserveAspectRatio", "none");
 			rawNode.setAttributeNS(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();
 			return this;	// self
 		}
 	});
 	svg.Image.nodeType = "image";
 
-	dojo.declare("dojox.gfx.svg.Text", [svg.Shape, gs.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)
@@ -412,7 +445,7 @@ dojo.require("dojox.gfx.path");
 			r.setAttribute("rotate", s.rotated ? 90 : 0);
 			r.setAttribute("kerning", s.kerning ? "auto" : 0);
 			r.setAttribute("text-rendering", "optimizeLegibility");
-			
+
 			// update the text content
 			if(r.firstChild){
 				r.firstChild.nodeValue = s.text;
@@ -449,7 +482,7 @@ else
 	});
 	svg.Text.nodeType = "text";
 
-	dojo.declare("dojox.gfx.svg.Path", [svg.Shape, g.path.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
@@ -473,7 +506,7 @@ else
 	});
 	svg.Path.nodeType = "path";
 
-	dojo.declare("dojox.gfx.svg.TextPath", [svg.Shape, g.path.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
@@ -550,7 +583,7 @@ else
 	});
 	svg.TextPath.nodeType = "text";
 
-	dojo.declare("dojox.gfx.svg.Surface", gs.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);
@@ -585,6 +618,7 @@ else
 
 		var s = new svg.Surface();
 		s.rawNode = _createElementNS(svg.xmlns.svg, "svg");
+		s.rawNode.setAttribute("overflow", "hidden");
 		if(width){
 			s.rawNode.setAttribute("width",  width);
 		}
@@ -596,7 +630,7 @@ else
 		s.rawNode.appendChild(defNode);
 		s.defNode = defNode;
 
-		s._parent = d.byId(parentNode);
+		s._parent = dom.byId(parentNode);
 		s._parent.appendChild(s.rawNode);
 
 		return s;	// dojox.gfx.Surface
@@ -696,17 +730,36 @@ else
 		}
 	};
 
-	d.extend(svg.Text, Font);
-	d.extend(svg.TextPath, Font);
+	lang.extend(svg.Text, Font);
+	lang.extend(svg.TextPath, Font);
 
-	d.extend(svg.Group, Container);
-	d.extend(svg.Group, gs.Creator);
-	d.extend(svg.Group, Creator);
+	lang.extend(svg.Group, Container);
+	lang.extend(svg.Group, gs.Creator);
+	lang.extend(svg.Group, Creator);
 
-	d.extend(svg.Surface, Container);
-	d.extend(svg.Surface, gs.Creator);
-	d.extend(svg.Surface, Creator);
+	lang.extend(svg.Surface, Container);
+	lang.extend(svg.Surface, gs.Creator);
+	lang.extend(svg.Surface, Creator);
 
+	// 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.
+		// event: Object
+		//     The current input event (MouseEvent or TouchEvent)
+		// gfxElement: Object
+		//     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__);
+			} else {
+				event.gfxTarget = gs.byId(event.target.__gfxObject__);
+			}
+		}
+		return true;
+	};
 
 	// some specific override for svgweb + flash
 	if(svg.useSvgWeb){
@@ -716,15 +769,15 @@ else
 
 			// ensure width / height
 			if(!width || !height){
-				var pos = d.position(parentNode);
+				var pos = domGeom.position(parentNode);
 				width  = width  || pos.w;
 				height = height || pos.h;
 			}
 
 			// ensure id
-			parentNode = d.byId(parentNode);
+			parentNode = dom.byId(parentNode);
 			var id = parentNode.id ? parentNode.id+'_svgweb' : g._base._getUniqueId();
-			
+
 			// create dynamic svg root
 			var mockSvg = _createElementNS(svg.xmlns.svg, 'svg');
 			mockSvg.id = id;
@@ -737,12 +790,12 @@ else
 				// become loaded
 				s.rawNode = this;
 				s.isLoaded = true;
-				
+
 				// init defs
 				var defNode = _createElementNS(svg.xmlns.svg, "defs");
 				s.rawNode.appendChild(defNode);
 				s.defNode = defNode;
-				
+
 				// notify application
 				if (s.onLoad)
 					s.onLoad(s);
@@ -752,7 +805,7 @@ else
 			s.isLoaded = false;
 			return s;
 		};
-		
+
 		// override Surface.destroy()
 		svg.Surface.extend({
 			destroy: function(){
@@ -769,7 +822,7 @@ else
 				if (arguments.length == 2) {
 					method = object;
 				} else {
-					method = d.hitch(object, method);
+					method = lang.hitch(object, method);
 				}
 				this.getEventSource().addEventListener(name, method, false);
 				return [this, name, method];
@@ -780,14 +833,10 @@ else
 				delete token[0];
 			}
 		};
-		
-		dojo.extend(svg.Shape, _eventsProcessing);
-		dojo.extend(svg.Surface, _eventsProcessing);
-	}
 
-	// see if we are required to initilize
-	if(g.loadAndSwitch === "svg"){
-		g.switchTo("svg");
-		delete g.loadAndSwitch;
+		lang.extend(svg.Shape, _eventsProcessing);
+		lang.extend(svg.Surface, _eventsProcessing);
 	}
-})();
+
+	return svg;
+});
diff --git a/dojox/gfx/svg_attach.js b/dojox/gfx/svg_attach.js
index af1ea33..7161c9c 100644
--- a/dojox/gfx/svg_attach.js
+++ b/dojox/gfx/svg_attach.js
@@ -1,11 +1,7 @@
-dojo.provide("dojox.gfx.svg_attach");
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/Color", "./_base","./svg","./matrix"], 
+  function(kernel, lang, arr, Color, g, svg, Matrix){
 
-dojo.require("dojox.gfx.svg");
-
-dojo.experimental("dojox.gfx.svg_attach");
-
-(function(){
-	var g = dojox.gfx, svg = g.svg;
+	kernel.experimental("dojox.gfx.svg_attach");
 	
 	svg.attachNode = function(node){
 		// summary: creates a shape from a Node
@@ -93,13 +89,13 @@ dojo.experimental("dojox.gfx.svg_attach");
 			switch(gradient.tagName.toLowerCase()){
 				case "lineargradient":
 					fillStyle = _getGradient(g.defaultLinearGradient, gradient);
-					dojo.forEach(["x1", "y1", "x2", "y2"], function(x){
+					arr.forEach(["x1", "y1", "x2", "y2"], function(x){
 						fillStyle[x] = gradient.getAttribute(x);
 					});
 					break;
 				case "radialgradient":
 					fillStyle = _getGradient(g.defaultRadialGradient, gradient);
-					dojo.forEach(["cx", "cy", "r"], function(x){
+					arr.forEach(["cx", "cy", "r"], function(x){
 						fillStyle[x] = gradient.getAttribute(x);
 					});
 					fillStyle.cx = gradient.getAttribute("cx");
@@ -107,15 +103,15 @@ dojo.experimental("dojox.gfx.svg_attach");
 					fillStyle.r  = gradient.getAttribute("r");
 					break;
 				case "pattern":
-					fillStyle = dojo.clone(g.defaultPattern);
-					dojo.forEach(["x", "y", "width", "height"], function(x){
+					fillStyle = lang.clone(g.defaultPattern);
+					arr.forEach(["x", "y", "width", "height"], function(x){
 						fillStyle[x] = gradient.getAttribute(x);
 					});
 					fillStyle.src = gradient.firstChild.getAttributeNS(svg.xmlns.xlink, "href");
 					break;
 			}
 		}else{
-			fillStyle = new dojo.Color(fill);
+			fillStyle = new Color(fill);
 			var opacity = object.rawNode.getAttribute("fill-opacity");
 			if(opacity != null){ fillStyle.a = opacity; }
 		}
@@ -123,12 +119,12 @@ dojo.experimental("dojox.gfx.svg_attach");
 	}
 
 	function _getGradient(defaultGradient, gradient){
-		var fillStyle = dojo.clone(defaultGradient);
+		var fillStyle = lang.clone(defaultGradient);
 		fillStyle.colors = [];
 		for(var i = 0; i < gradient.childNodes.length; ++i){
 			fillStyle.colors.push({
 				offset: gradient.childNodes[i].getAttribute("offset"),
-				color:  new dojo.Color(gradient.childNodes[i].getAttribute("stop-color"))
+				color:  new Color(gradient.childNodes[i].getAttribute("stop-color"))
 			});
 		}
 		return fillStyle;
@@ -142,8 +138,8 @@ dojo.experimental("dojox.gfx.svg_attach");
 			object.strokeStyle = null;
 			return;
 		}
-		var strokeStyle = object.strokeStyle = dojo.clone(g.defaultStroke);
-		var color = new dojo.Color(stroke);
+		var strokeStyle = object.strokeStyle = lang.clone(g.defaultStroke);
+		var color = new Color(stroke);
 		if(color){
 			strokeStyle.color = color;
 			strokeStyle.color.a = rawNode.getAttribute("stroke-opacity");
@@ -163,7 +159,7 @@ dojo.experimental("dojox.gfx.svg_attach");
 		var matrix = object.rawNode.getAttribute("transform");
 		if(matrix.match(/^matrix\(.+\)$/)){
 			var t = matrix.slice(7, -1).split(",");
-			object.matrix = g.matrix.normalize({
+			object.matrix = Matrix.normalize({
 				xx: parseFloat(t[0]), xy: parseFloat(t[2]),
 				yx: parseFloat(t[1]), yy: parseFloat(t[3]),
 				dx: parseFloat(t[4]), dy: parseFloat(t[5])
@@ -176,7 +172,7 @@ dojo.experimental("dojox.gfx.svg_attach");
 	function attachFont(object){
 		// summary: deduces a font style from a Node.
 		// object: dojox.gfx.Shape: an SVG shape
-		var fontStyle = object.fontStyle = dojo.clone(g.defaultFont),
+		var fontStyle = object.fontStyle = lang.clone(g.defaultFont),
 			r = object.rawNode;
 		fontStyle.style = r.getAttribute("font-style");
 		fontStyle.variant = r.getAttribute("font-variant");
@@ -189,7 +185,7 @@ dojo.experimental("dojox.gfx.svg_attach");
 		// summary: builds a shape from a node.
 		// object: dojox.gfx.Shape: an SVG shape
 		// def: Object: a default shape template
-		var shape = object.shape = dojo.clone(def), r = object.rawNode;
+		var shape = object.shape = lang.clone(def), r = object.rawNode;
 		for(var i in shape) {
 			shape[i] = r.getAttribute(i);
 		}
@@ -205,7 +201,7 @@ dojo.experimental("dojox.gfx.svg_attach");
 	function attachText(object){
 		// summary: builds a text shape from a node.
 		// object: dojox.gfx.Shape: an SVG shape
-		var shape = object.shape = dojo.clone(g.defaultText),
+		var shape = object.shape = lang.clone(g.defaultText),
 			r = object.rawNode;
 		shape.x = r.getAttribute("x");
 		shape.y = r.getAttribute("y");
@@ -219,7 +215,7 @@ dojo.experimental("dojox.gfx.svg_attach");
 	function attachTextPath(object){
 		// summary: builds a textpath shape from a node.
 		// object: dojox.gfx.Shape: an SVG shape
-		var shape = object.shape = dojo.clone(g.defaultTextPath),
+		var shape = object.shape = lang.clone(g.defaultTextPath),
 			r = object.rawNode;
 		shape.align = r.getAttribute("text-anchor");
 		shape.decoration = r.getAttribute("text-decoration");
@@ -227,4 +223,6 @@ dojo.experimental("dojox.gfx.svg_attach");
 		shape.kerning = r.getAttribute("kerning") == "auto";
 		shape.text = r.firstChild.nodeValue;
 	}
-})();
+
+	return svg; // return augmented svg api
+});
diff --git a/dojox/gfx/tests/_gfxBidiSupport/canvas/dynamicallyChangeTextCanvas.html b/dojox/gfx/tests/_gfxBidiSupport/canvas/dynamicallyChangeTextCanvas.html
new file mode 100644
index 0000000..bfef3ac
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/canvas/dynamicallyChangeTextCanvas.html
@@ -0,0 +1,84 @@
+<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, gfxRenderer:'canvas'"></script>
+
+		<script type="text/javascript">
+			dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._gfxBidiSupport");
+
+			var ROTATION = 30;
+
+			var surface = null, t1;
+
+			var placeAnchor = function(surface, x, y){
+				surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y});
+				surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2});
+			};
+
+			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;
+			};
+
+			makeShapes = function(){
+				surface = dojox.gfx.createSurface("test", 500, 200);
+				var m = dojox.gfx.matrix;
+				//surface.createLine({x1: 250, y1: 0, x2: 250, y2: 500}).setStroke("green");
+				t1 = makeText(surface, {id: "t1",x: 250, y: 50, text:"Hello!", textDir:"ltr"}, 
+					{family: "Times", size: "24pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 50));
+			
+		
+			}
+
+			dojo.addOnLoad(makeShapes);
+
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx Text test</h1>
+		<div id="test" style="width: 500px; height: 200px;"></div>
+
+		<label>write inside to test dojox.gfx.Text with BidiEngine</label>
+		<br>
+		<textarea id="inputF" 
+       		onkeyup="dealInput();"
+ 		>write in me to test dojox.gfx.Text with BidiEngine</textarea>
+		
+		<script>
+			function dealInput(){
+				var  v = inputF.value ? inputF.value : ""; 
+				t1.setShape({text: v});
+			}
+		</script>
+		
+		<br>
+		<input id="SHALOM" type="button" value="click on me to write a Hebrew word!"
+			onclick="t1.setShape({text:'\u05e9\u05dc\u05d5\u05dd!'}); inputF.value = '\u05e9\u05dc\u05d5\u05dd!'"
+		/>	
+
+		<br>
+		<br>
+
+		<input id="textDirLTR" type="button" value="change textDir to 'LTR'"
+			onclick="t1.setShape({textDir:'ltr'});"
+		/>		
+		<input id="textDirRTL" type="button" value="change textDir to 'RTL'"
+			onclick="t1.setShape({textDir:'rtl'});"
+		/>		
+		<input id="textDirAUTO" type="button" value="change textDir to 'AUTO'"
+			onclick="t1.setShape({textDir:'auto'});"
+		/>	
+
+	</body>
+</html>
diff --git a/dojox/gfx/tests/_gfxBidiSupport/canvas/inheritFromSurfaceCanvas.html b/dojox/gfx/tests/_gfxBidiSupport/canvas/inheritFromSurfaceCanvas.html
new file mode 100644
index 0000000..f9b72f5
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/canvas/inheritFromSurfaceCanvas.html
@@ -0,0 +1,184 @@
+<html >
+	<head>
+		<title>Testing textpath</title>
+		<style type="text/css">
+			@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, gfxRenderer:'canvas'"></script>
+		<script type="text/javascript">
+
+			dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._gfxBidiSupport");
+
+			var CPD = 30, tp1, tp2, tp3,tp4,tp5, t1, t2, t3, t4, t5, t6;
+			var g1 = null;
+			var g2 = null;
+
+			var surfaceLTR = null, surfaceRTL = null, surfaceAUTO = null;
+			
+			var placeAnchor = function(surface, x, y){
+				surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y});
+				surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2});
+			};			
+			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;
+			};
+
+			makeShapes = function(){
+				var m = dojox.gfx.matrix;
+				surfaceLTR = dojox.gfx.createSurface("testLTR", 500, 170, "ltr");
+				console.debug("surfaceLTR created");
+				var p = surfaceLTR.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 50,  0)
+					;
+				console.debug("p created");
+				tp1 = surfaceLTR.createTextPath({
+						text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+						, align: "start"
+					})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("blue")
+					;
+				console.debug("tp1 created");
+				tp2 = surfaceLTR.createTextPath({
+						text: "Beginning \u05e1\u05d5\u05e3."
+						, align: "start"
+						
+					})
+					.moveTo(0, 50)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("blue")
+					;
+				console.debug("tp2 created");
+				g1 = surfaceLTR.createGroup();
+				t1 = makeText(surfaceLTR, {id: "t1",x: 0, y: 100, text: "1.) \u05d4\u05ea\u05d7\u05dc\u05d4 end!"}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 150));
+
+				t2 = makeText(surfaceLTR, {x: 0, y: 140, text: "1.) Beginning \u05e1\u05d5\u05e3!"}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 100));
+				
+				surfaceRTL = dojox.gfx.createSurface("testRTL", 500, 170, "rtl");
+				console.debug("surfaceRTL created");
+				var p2 = surfaceRTL.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					;
+				console.debug("p2 created");
+				tp3 = surfaceRTL.createTextPath({
+						text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+						, align: "start"
+						//, rotated: true
+					})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("red")
+					;
+				console.debug("tp3 created");
+				tp4 = surfaceRTL.createTextPath({
+						text: "Beginning \u05e1\u05d5\u05e3."
+						, align: "start"
+						
+						//, rotated: true
+					})
+					//.setShape(p.shape)
+					.moveTo(0, 50)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("red")
+					;				
+				console.debug("tp4 created");
+
+				t3 = makeText(surfaceRTL, {id: "t1",x: 0, y: 100, text: "1.) \u05d4\u05ea\u05d7\u05dc\u05d4 end!"}, 
+					{family: "Times", size: "18pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 150));
+
+				t4 = makeText(surfaceRTL, {x: 0, y: 140, text: "1.) Beginning \u05e1\u05d5\u05e3!"}, 
+					{family: "Times", size: "18pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 100));
+				
+				surfaceAUTO = dojox.gfx.createSurface("testAUTO", 500, 170,"auto");
+				console.debug("surfaceAUTO created");
+				var p3 = surfaceAUTO.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					;
+				console.debug("p3 created");
+
+				var tp5 = surfaceAUTO.createTextPath({
+						text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+						, align: "start"
+						
+						//, rotated: true
+					})
+					//.setShape(p.shape)
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+
+					.setFont({family: "times", size: "12pt"})
+					.setFill("red")
+					;
+				console.debug("tp5 created");
+				var tp6 = surfaceAUTO.createTextPath({
+						text: "Beginning \u05e1\u05d5\u05e3."
+						, align: "start"
+						
+						//, rotated: true
+					})
+					//.setShape(p.shape)
+					.moveTo(0, 50)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("blue")
+					;				
+				console.debug("tp6 created");
+
+				t3 = makeText(surfaceAUTO, {id: "t1",x: 0, y: 100, text: "1.) \u05d4\u05ea\u05d7\u05dc\u05d4 end!"}, 
+					{family: "Times", size: "18pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 150));
+
+				t4 = makeText(surfaceAUTO, {x: 0, y: 140, text: "1.) Beginning \u05e1\u05d5\u05e3!"}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 100));
+
+				};
+
+				
+			dojo.addOnLoad(makeShapes);
+
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx Text on a Path test</h1>
+		<h2>LTR TextPath and Text first two are TextPath and two others are Text</h2>
+		<div id="testLTR" style="width: 500px;"></div>
+		<h2>RTL Text Path and Text first two are TextPath and two others are Text</h2>
+		<div id="testRTL" style="width: 500px;"></div>
+		<h2>AUTO Text Path and Text first two are TextPath and two others are Text</h2>
+		<div id="testAUTO" style="width: 500px;"></div>
+
+	<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/_gfxBidiSupport/canvas/test_SurfaceGroupCanvas.html b/dojox/gfx/tests/_gfxBidiSupport/canvas/test_SurfaceGroupCanvas.html
new file mode 100644
index 0000000..652d724
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/canvas/test_SurfaceGroupCanvas.html
@@ -0,0 +1,262 @@
+<html dir="rtl">
+	<head>
+		<title>Testing textpath</title>
+		<style type="text/css">
+			@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, gfxRenderer:'canvas'"></script>
+		<script type="text/javascript">
+
+			dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._gfxBidiSupport");
+			dojo.require("doh.runner");
+
+
+			var CPD = 30, tp1, tp2, tp3, tp4, tp5, tp6, t1, t2, t3, t4, t5, t6;
+			var g1 = null, g2 = null, g3, g4;
+
+			var surfaceLTR = null, surfaceRTL = null, surfaceAUTO = null;
+			
+			var placeAnchor = function(surface, x, y){
+				surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y});
+				surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2});
+			};			
+			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;
+			};
+
+			makeShapes = function(){
+				var m = dojox.gfx.matrix;
+				surfaceLTR = dojox.gfx.createSurface("testLTR", 500, 170, "ltr");
+				console.debug("surfaceLTR created");
+				var p = surfaceLTR.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 50,  0)
+					;
+				console.debug("p created");
+				tp1 = surfaceLTR.createTextPath({
+						text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+						, align: "start"
+					})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("blue")
+					;
+				console.debug("tp1 created");
+				tp2 = surfaceLTR.createTextPath({
+						text: "Beginning \u05e1\u05d5\u05e3."
+						, align: "start"
+						
+					})
+					.moveTo(0, 50)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("blue")
+					;
+				console.debug("tp2 created");
+				g1 = surfaceLTR.createGroup();
+				g1.setTextDir("rtl");
+		//		surfaceLTR.setTextDir("ltr");
+				t1 = makeText(g1, {id: "t1",x: 0, y: 100, text: "1.) \u05d4\u05ea\u05d7\u05dc\u05d4 end!"}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 150));
+
+				t2 = makeText(surfaceLTR, {x: 0, y: 140, text: "1.) Beginning \u05e1\u05d5\u05e3!"}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 100));
+				
+				surfaceRTL = dojox.gfx.createSurface("testRTL", 500, 170);
+				console.debug("surfaceRTL created");
+				var p2 = surfaceRTL.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					;
+				console.debug("p2 created");
+				tp3 = surfaceRTL.createTextPath({
+						text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+						, align: "start"
+						//, rotated: true
+					})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("red")
+					;
+				g2 = surfaceRTL.createGroup();
+				g2.add(tp3);
+				g2.setTextDir("ltr");
+				  
+				g3 = g2.createGroup("rtl");
+				
+				g4 = surfaceRTL.createGroup("auto");
+
+				tp4 = surfaceRTL.createTextPath({
+						text: "Beginning \u05e1\u05d5\u05e3."
+						, align: "start"
+						
+						//, rotated: true
+					})
+					//.setShape(p.shape)
+					.moveTo(0, 50)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("red")
+					;				
+				console.debug("tp4 created");
+
+				t3 = makeText(g3, {id: "t1",x: 0, y: 100, text: "1.) \u05d4\u05ea\u05d7\u05dc\u05d4 end!"}, 
+					{family: "Times", size: "18pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 150));
+
+				t4 = makeText(surfaceRTL, {x: 0, y: 140, text: "1.) Beginning \u05e1\u05d5\u05e3!"}, 
+					{family: "Times", size: "18pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 100));
+				
+				surfaceAUTO = dojox.gfx.createSurface("testAUTO", 500, 170,"auto");
+				console.debug("surfaceAUTO created");
+				var p3 = surfaceAUTO.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					;
+				console.debug("p3 created");
+
+				tp5 = surfaceAUTO.createTextPath({
+						text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+						, align: "start"
+						
+						//, rotated: true
+					})
+					//.setShape(p.shape)
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+
+					.setFont({family: "times", size: "12pt"})
+					.setFill("red")
+					;
+				console.debug("tp5 created");
+				tp6 = surfaceAUTO.createTextPath({
+						text: "Beginning \u05e1\u05d5\u05e3."
+						, align: "start"
+						
+						//, rotated: true
+					})
+					//.setShape(p.shape)
+					.moveTo(0, 50)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("blue")
+					;				
+				console.debug("tp6 created");
+
+				t5 = makeText(surfaceAUTO, {id: "t1",x: 0, y: 100, text: "1.) \u05d4\u05ea\u05d7\u05dc\u05d4 end!"}, 
+					{family: "Times", size: "18pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 150));
+
+				t6 = makeText(surfaceAUTO, {x: 0, y: 140, text: "1.) Beginning \u05e1\u05d5\u05e3!"}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 100));
+					
+				};
+
+				
+			dojo.addOnLoad(function(){
+				makeShapes();
+				
+
+				doh.register("Test inheritance", [
+					function surfaces_TextDir(){
+						doh.is("ltr", surfaceLTR.getTextDir(), "surfaceLTR.getTextDir"); 
+						doh.is("rtl", surfaceRTL.getTextDir(), "surfaceRTL.getTextDir"); 
+						doh.is("auto", surfaceAUTO.getTextDir(), "surfaceAUTO.getTextDir"); 
+					},
+					function groups_TextDir(){
+						doh.is("rtl", g1.getTextDir(), "g1.getTextDir"); 
+						doh.is("ltr", g2.getTextDir(), "g2.getTextDir"); 
+						doh.is("rtl", g3.getTextDir(), "g3.getTextDir"); 
+						doh.is("auto", g4.getTextDir(), "g4.getTextDir"); 
+					},
+					function gfxText_TextDir(){
+						doh.is("rtl", t1.textDir, "t1.getTextDir"); 
+						doh.is("ltr", t2.textDir, "t2.getTextDir"); 
+						doh.is("rtl", t3.textDir, "t3.getTextDir"); 
+						doh.is("rtl", t4.textDir, "t4.getTextDir"); 
+						doh.is("auto", t5.textDir, "t5.getTextDir"); 
+						doh.is("auto", t6.textDir, "t6h.getTextDir"); 
+					},
+					function gfxTextPath_TextDir(){
+						doh.is("ltr", tp1.textDir, "tp1.getTextDir"); 
+						doh.is("ltr", tp2.textDir, "tp2.getTextDir"); 
+						doh.is("ltr", tp3.textDir, "tp3.getTextDir"); 
+						doh.is("rtl", tp4.textDir, "tp4.getTextDir"); 
+						doh.is("auto", tp5.textDir, "tp5.getTextDir"); 
+						doh.is("auto", tp6.textDir, "tp6.getTextDir"); 
+					},
+					function changeSurfaceRTLextDir(){
+						surfaceRTL.setTextDir("ltr");
+						
+						doh.is("ltr", surfaceRTL.getTextDir(), "surfaceRTL.getTextDir"); 
+
+						doh.is("ltr", g2.getTextDir(), "g2.getTextDir"); 
+						doh.is("ltr", g3.getTextDir(), "g3.getTextDir"); 
+						doh.is("ltr", g4.getTextDir(), "g4.getTextDir"); 
+						
+						
+						doh.is("ltr", t3.textDir, "t3.getTextDir"); 
+						doh.is("ltr", t4.textDir, "t4.getTextDir"); 
+						
+						doh.is("ltr", tp3.textDir, "tp3.getTextDir"); 
+						doh.is("ltr", tp4.textDir, "tp4.getTextDir"); 
+					},
+					function changeGroupTextDir(){
+					
+						g3.add(tp5);
+						g3.add(t2);
+						
+						g2.setTextDir("rtl");
+
+						doh.is("rtl", g2.getTextDir(), "g2.getTextDir"); 
+						// son of g2
+						doh.is("rtl", g3.getTextDir(), "g3.getTextDir"); 
+						
+						doh.is("rtl", t2.textDir, "t2.getTextDir"); 
+						doh.is("rtl", t3.textDir, "t3.getTextDir"); 
+						
+						doh.is("rtl", tp5.textDir, "tp3.getTextDir"); 
+					}
+				]);
+
+				doh.run();
+				
+			});
+
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx Text on a Path test</h1>
+		<h2>LTR TextPath and Text first two are TextPath and two others are Text</h2>
+		<div id="testLTR" style="width: 500px;"></div>
+		<h2>RTL Text Path and Text first two are TextPath and two others are Text</h2>
+		<div id="testRTL" style="width: 500px;"></div>
+		<h2>AUTO Text Path and Text first two are TextPath and two others are Text</h2>
+		<div id="testAUTO" style="width: 500px;"></div>
+
+	<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/_gfxBidiSupport/canvas/textBidiCanvas.html b/dojox/gfx/tests/_gfxBidiSupport/canvas/textBidiCanvas.html
new file mode 100644
index 0000000..a7ceaba
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/canvas/textBidiCanvas.html
@@ -0,0 +1,67 @@
+<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, gfxRenderer:'canvas'"></script>
+
+		<script type="text/javascript">
+			dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._gfxBidiSupport");
+
+			var surface = null, t1, t2, t3, t4, t5;
+
+			var placeAnchor = function(surface, x, y){
+				surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y});
+				surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2});
+			};
+
+			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;
+			};
+
+			makeShapes = function(){
+				surface = dojox.gfx.createSurface("test", 500, 500);
+				var m = dojox.gfx.matrix;
+				//surface.createLine({x1: 250, y1: 0, x2: 250, y2: 500}).setStroke("green");
+				t1 = makeText(surface, {id: "t1",x: 250, y: 50, text: "1.) \u05d4\u05ea\u05d7\u05dc\u05d4 end!", textDir:"ltr"}, 
+					{family: "Times", size: "24pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 50));
+				
+				t2 = makeText(surface, {x: 250, y: 100, text: "1.) Beginning \u05e1\u05d5\u05e3!", textDir:"ltr"}, 
+					{family: "Times", size: "24pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 100));
+
+				t3 = makeText(surface, {x: 250, y: 150, text: "1.) \u05d4\u05ea\u05d7\u05dc\u05d4 end!", textDir:"rtl"}, 
+					{family: "Times", size: "24pt"}, "red", "black")
+					.setTransform(m.rotategAt(0, 250, 150));
+				t4 = makeText(surface, {x: 250, y: 200, text: "1.) Beginning \u05e1\u05d5\u05e3!",  kerning: true,textDir:"rtl"}, 
+					{family: "Times", size: "24pt"}, "red", "black")
+					.setTransform(m.rotategAt(0, 250, 200));
+				t5 = makeText(surface, {x: 250, y: 250, text: "1.) \u05e9\u05dc\u05d5\u05dd AUTO!", kerning: false,textDir:"auto"}, 
+					{family: "Times", size: "24pt"}, "red", "black")
+					.setTransform(m.rotategAt(0, 250, 250));
+				t6 = makeText(surface, {x: 250, y: 300, text: "1.) Beginning \u05e1\u05d5\u05e3!", kerning: false,textDir:"auto"}, 
+					{family: "Times", size: "24pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 300));		
+			};
+
+			dojo.addOnLoad(makeShapes);
+
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx Text test</h1>
+		<div id="test" style="width: 500px; height: 500px;"></div>
+
+
+	</body>
+</html>
diff --git a/dojox/gfx/tests/_gfxBidiSupport/dynamicallyChangeText.html b/dojox/gfx/tests/_gfxBidiSupport/dynamicallyChangeText.html
new file mode 100644
index 0000000..5741fac
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/dynamicallyChangeText.html
@@ -0,0 +1,84 @@
+<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">
+			dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._gfxBidiSupport");
+
+			var ROTATION = 30;
+
+			var surface = null, t1;
+
+			var placeAnchor = function(surface, x, y){
+				surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y});
+				surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2});
+			};
+
+			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;
+			};
+
+			makeShapes = function(){
+				surface = dojox.gfx.createSurface("test", 500, 200);
+				var m = dojox.gfx.matrix;
+				//surface.createLine({x1: 250, y1: 0, x2: 250, y2: 500}).setStroke("green");
+				t1 = makeText(surface, {id: "t1",x: 250, y: 50, text:"Hello!", textDir:"ltr"}, 
+					{family: "Times", size: "24pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 50));
+			
+		
+			}
+
+			dojo.addOnLoad(makeShapes);
+
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx Text test</h1>
+		<div id="test" style="width: 500px; height: 200px;"></div>
+
+		<label>write inside to test dojox.gfx.Text with BidiEngine</label>
+		<br>
+		<textarea id="inputF" 
+       		onkeyup="dealInput();"
+ 		>write in me to test dojox.gfx.Text with BidiEngine</textarea>
+		
+		<script>
+			function dealInput(){
+				var  v = inputF.value ? inputF.value : ""; 
+				t1.setShape({text: v});
+			}
+		</script>
+		
+		<br>
+		<input id="SHALOM" type="button" value="click on me to write a Hebrew word!"
+			onclick="t1.setShape({text:'\u05e9\u05dc\u05d5\u05dd!'}); inputF.value = '\u05e9\u05dc\u05d5\u05dd!'"
+		/>	
+
+		<br>
+		<br>
+
+		<input id="textDirLTR" type="button" value="change textDir to 'LTR'"
+			onclick="t1.setShape({textDir:'ltr'});"
+		/>		
+		<input id="textDirRTL" type="button" value="change textDir to 'RTL'"
+			onclick="t1.setShape({textDir:'rtl'});"
+		/>		
+		<input id="textDirAUTO" type="button" value="change textDir to 'AUTO'"
+			onclick="t1.setShape({textDir:'auto'});"
+		/>	
+
+	</body>
+</html>
diff --git a/dojox/gfx/tests/_gfxBidiSupport/inheritFromSurface.html b/dojox/gfx/tests/_gfxBidiSupport/inheritFromSurface.html
new file mode 100644
index 0000000..e4f0325
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/inheritFromSurface.html
@@ -0,0 +1,184 @@
+<html dir="rtl">
+	<head>
+		<title>Testing textpath</title>
+		<style type="text/css">
+			@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">
+
+			dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._gfxBidiSupport");
+
+			var CPD = 30, tp1, tp2, tp3,tp4,tp5, t1, t2, t3, t4, t5, t6;
+			var g1 = null;
+			var g2 = null;
+
+			var surfaceLTR = null, surfaceRTL = null, surfaceAUTO = null;
+			
+			var placeAnchor = function(surface, x, y){
+				surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y});
+				surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2});
+			};			
+			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;
+			};
+
+			makeShapes = function(){
+				var m = dojox.gfx.matrix;
+				surfaceLTR = dojox.gfx.createSurface("testLTR", 500, 170, "ltr");
+				console.debug("surfaceLTR created");
+				var p = surfaceLTR.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 50,  0)
+					;
+				console.debug("p created");
+				tp1 = surfaceLTR.createTextPath({
+						text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+						, align: "start"
+					})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("blue")
+					;
+				console.debug("tp1 created");
+				tp2 = surfaceLTR.createTextPath({
+						text: "Beginning \u05e1\u05d5\u05e3."
+						, align: "start"
+						
+					})
+					.moveTo(0, 50)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("blue")
+					;
+				console.debug("tp2 created");
+				g1 = surfaceLTR.createGroup();
+				t1 = makeText(surfaceLTR, {id: "t1",x: 0, y: 100, text: "1.) \u05d4\u05ea\u05d7\u05dc\u05d4 end!"}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 150));
+
+				t2 = makeText(surfaceLTR, {x: 0, y: 140, text: "1.) Beginning \u05e1\u05d5\u05e3!"}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 100));
+				
+				surfaceRTL = dojox.gfx.createSurface("testRTL", 500, 170);
+				console.debug("surfaceRTL created");
+				var p2 = surfaceRTL.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					;
+				console.debug("p2 created");
+				tp3 = surfaceRTL.createTextPath({
+						text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+						, align: "start"
+						//, rotated: true
+					})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("red")
+					;
+				console.debug("tp3 created");
+				tp4 = surfaceRTL.createTextPath({
+						text: "Beginning \u05e1\u05d5\u05e3."
+						, align: "start"
+						
+						//, rotated: true
+					})
+					//.setShape(p.shape)
+					.moveTo(0, 50)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("red")
+					;				
+				console.debug("tp4 created");
+
+				t3 = makeText(surfaceRTL, {id: "t1",x: 0, y: 100, text: "1.) \u05d4\u05ea\u05d7\u05dc\u05d4 end!"}, 
+					{family: "Times", size: "18pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 150));
+
+				t4 = makeText(surfaceRTL, {x: 0, y: 140, text: "1.) Beginning \u05e1\u05d5\u05e3!"}, 
+					{family: "Times", size: "18pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 100));
+				
+				surfaceAUTO = dojox.gfx.createSurface("testAUTO", 500, 170,"auto");
+				console.debug("surfaceAUTO created");
+				var p3 = surfaceAUTO.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					;
+				console.debug("p3 created");
+
+				var tp5 = surfaceAUTO.createTextPath({
+						text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+						, align: "start"
+						
+						//, rotated: true
+					})
+					//.setShape(p.shape)
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+
+					.setFont({family: "times", size: "12pt"})
+					.setFill("red")
+					;
+				console.debug("tp5 created");
+				var tp6 = surfaceAUTO.createTextPath({
+						text: "Beginning \u05e1\u05d5\u05e3."
+						, align: "start"
+						
+						//, rotated: true
+					})
+					//.setShape(p.shape)
+					.moveTo(0, 50)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("blue")
+					;				
+				console.debug("tp6 created");
+
+				t3 = makeText(surfaceAUTO, {id: "t1",x: 0, y: 100, text: "1.) \u05d4\u05ea\u05d7\u05dc\u05d4 end!"}, 
+					{family: "Times", size: "18pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 150));
+
+				t4 = makeText(surfaceAUTO, {x: 0, y: 140, text: "1.) Beginning \u05e1\u05d5\u05e3!"}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 100));
+
+				};
+
+				
+			dojo.addOnLoad(makeShapes);
+
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx Text on a Path test</h1>
+		<h2>LTR TextPath and Text first two are TextPath and two others are Text</h2>
+		<div id="testLTR" style="width: 500px;"></div>
+		<h2>RTL Text Path and Text first two are TextPath and two others are Text</h2>
+		<div id="testRTL" style="width: 500px;"></div>
+		<h2>AUTO Text Path and Text first two are TextPath and two others are Text</h2>
+		<div id="testAUTO" style="width: 500px;"></div>
+
+	<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/_gfxBidiSupport/module.js b/dojox/gfx/tests/_gfxBidiSupport/module.js
new file mode 100644
index 0000000..4651ba0
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/module.js
@@ -0,0 +1,15 @@
+dojo.provide("dojox.gfx.tests._gfxBidiSupport.module");
+
+try{
+	doh.registerUrl("dojox.gfx.tests._gfxBidiSupport.test_SurfaceGroup", dojo.moduleUrl("dojox", "gfx/tests/_gfxBidiSupport/test_SurfaceGroup.html"));
+
+	if(dojo.isIE){
+		doh.registerUrl("dojox.gfx.tests._gfxBidiSupport.silverlight.test_SurfaceGroupSilverlight", dojo.moduleUrl("dojox", "gfx/tests/_gfxBidiSupport/silverlight/test_SurfaceGroupSilverlight.html"));
+	}else{
+		doh.registerUrl("dojox.gfx.tests._gfxBidiSupport.canvas.test_SurfaceGroupCanvas", dojo.moduleUrl("dojox", "gfx/tests/_gfxBidiSupport/canvas/test_SurfaceGroupCanvas.html"));
+	}
+	doh.registerUrl("dojox.gfx.tests._gfxBidiSupport.svgWeb.test_SurfaceGroupSvgWeb", dojo.moduleUrl("dojox", "gfx/tests/_gfxBidiSupport/svgWeb/test_SurfaceGroupSvgWeb.html"));
+
+}catch(e){
+     doh.debug(e);
+}
\ No newline at end of file
diff --git a/dojox/gfx/tests/_gfxBidiSupport/runTests.html b/dojox/gfx/tests/_gfxBidiSupport/runTests.html
new file mode 100644
index 0000000..808c780
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/runTests.html
@@ -0,0 +1,11 @@
+!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+  <head>
+    <title>textDirTests Unit Test Runner</title>
+    <meta http-equiv="REFRESH"         
+content="0;url=../../../../util/doh/runner.html?testModule=dojox.gfx.tests._gfxBidiSupport.module">
+  </head>
+  <body>
+      Redirecting to D.O.H runner.
+  </body>
+</html>
\ No newline at end of file
diff --git a/dojox/gfx/tests/_gfxBidiSupport/silverlight/dynamicallyChangeTextSilverlight.html b/dojox/gfx/tests/_gfxBidiSupport/silverlight/dynamicallyChangeTextSilverlight.html
new file mode 100644
index 0000000..c72635c
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/silverlight/dynamicallyChangeTextSilverlight.html
@@ -0,0 +1,84 @@
+<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, gfxRenderer:'silverlight'"></script>
+
+		<script type="text/javascript">
+			dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._gfxBidiSupport");
+
+			var ROTATION = 30;
+
+			var surface = null, t1;
+
+			var placeAnchor = function(surface, x, y){
+				surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y});
+				surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2});
+			};
+
+			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;
+			};
+
+			makeShapes = function(){
+				surface = dojox.gfx.createSurface("test", 500, 200);
+				var m = dojox.gfx.matrix;
+				//surface.createLine({x1: 250, y1: 0, x2: 250, y2: 500}).setStroke("green");
+				t1 = makeText(surface, {id: "t1",x: 250, y: 50, text:"Hello!", textDir:"ltr"}, 
+					{family: "Times", size: "24pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 50));
+			
+		
+			}
+
+			dojo.addOnLoad(makeShapes);
+
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx Text test</h1>
+		<div id="test" style="width: 500px; height: 200px;"></div>
+
+		<label>write inside to test dojox.gfx.Text with BidiEngine</label>
+		<br>
+		<textarea id="inputF" 
+       		onkeyup="dealInput();"
+ 		>write in me to test dojox.gfx.Text with BidiEngine</textarea>
+		
+		<script>
+			function dealInput(){
+				var  v = inputF.value ? inputF.value : ""; 
+				t1.setShape({text: v});
+			}
+		</script>
+		
+		<br>
+		<input id="SHALOM" type="button" value="click on me to write a Hebrew word!"
+			onclick="t1.setShape({text:'\u05e9\u05dc\u05d5\u05dd!'}); inputF.value = '\u05e9\u05dc\u05d5\u05dd!'"
+		/>	
+
+		<br>
+		<br>
+
+		<input id="textDirLTR" type="button" value="change textDir to 'LTR'"
+			onclick="t1.setShape({textDir:'ltr'});"
+		/>		
+		<input id="textDirRTL" type="button" value="change textDir to 'RTL'"
+			onclick="t1.setShape({textDir:'rtl'});"
+		/>		
+		<input id="textDirAUTO" type="button" value="change textDir to 'AUTO'"
+			onclick="t1.setShape({textDir:'auto'});"
+		/>	
+
+	</body>
+</html>
diff --git a/dojox/gfx/tests/_gfxBidiSupport/silverlight/inheritFromSurfaceSilverlight.html b/dojox/gfx/tests/_gfxBidiSupport/silverlight/inheritFromSurfaceSilverlight.html
new file mode 100644
index 0000000..424bab2
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/silverlight/inheritFromSurfaceSilverlight.html
@@ -0,0 +1,106 @@
+<html dir="rtl">
+	<head>
+		<title>Testing textpath</title>
+		<style type="text/css">
+			@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, gfxRenderer:'silverlight'"></script>
+		<script type="text/javascript">
+
+			dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._gfxBidiSupport");
+
+			var CPD = 30, tp1, tp2, tp3,tp4,tp5, t1, t2, t3, t4, t5, t6;
+			var g1 = null;
+			var g2 = null;
+
+			var surfaceLTR = null, surfaceRTL = null, surfaceAUTO = null;
+			
+			var placeAnchor = function(surface, x, y){
+				surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y});
+				surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2});
+			};			
+			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;
+			};
+
+			makeShapes = function(){
+				var m = dojox.gfx.matrix;
+				surfaceLTR = dojox.gfx.createSurface("testLTR", 500, 170, "ltr");
+				console.debug("surfaceLTR created");
+				var p = surfaceLTR.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 50,  0)
+					;
+				console.debug("p created");
+
+				g1 = surfaceLTR.createGroup();
+				t1 = makeText(surfaceLTR, {id: "t1",x: 0, y: 100, text: "1.) \u05e9\u05dc\u05d5\u05dd world!"}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 150));
+
+				t2 = makeText(surfaceLTR, {x: 0, y: 140, text: "1.) Hello \u05e2\u05d5\u05dc\u05dd!"}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 100));
+				
+				surfaceRTL = dojox.gfx.createSurface("testRTL", 500, 170);
+				console.debug("surfaceRTL created");
+				var p2 = surfaceRTL.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					;
+				console.debug("p2 created");
+
+				t3 = makeText(surfaceRTL, {id: "t1",x: 0, y: 100, text: "1.) \u05e9\u05dc\u05d5\u05dd world!"}, 
+					{family: "Times", size: "18pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 150));
+
+				t4 = makeText(surfaceRTL, {x: 0, y: 140, text: "1.) Hello \u05e2\u05d5\u05dc\u05dd!"}, 
+					{family: "Times", size: "18pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 100));
+				
+				surfaceAUTO = dojox.gfx.createSurface("testAUTO", 500, 170, "auto");
+				console.debug("surfaceAUTO created");
+				var p3 = surfaceAUTO.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					;
+				console.debug("p3 created");
+
+				t3 = makeText(surfaceAUTO, {id: "t1",x: 0, y: 100, text: "1.) \u05e9\u05dc\u05d5\u05dd world!"}, 
+					{family: "Times", size: "18pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 150));
+
+				t4 = makeText(surfaceAUTO, {x: 0, y: 140, text: "1.) Hello \u05e2\u05d5\u05dc\u05dd!"}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 100));
+
+				};
+
+				
+			dojo.addOnLoad(makeShapes);
+
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx.Text</h1>
+		<h2>LTR Text</h2>
+		<div id="testLTR" style="width: 500px;"></div>
+		<h2>RTL Text</h2>
+		<div id="testRTL" style="width: 500px;"></div>
+		<h2>AUTO Text</h2>
+		<div id="testAUTO" style="width: 500px;"></div>
+
+	<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/_gfxBidiSupport/silverlight/test_SurfaceGroupSilverlight.html b/dojox/gfx/tests/_gfxBidiSupport/silverlight/test_SurfaceGroupSilverlight.html
new file mode 100644
index 0000000..09062ff
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/silverlight/test_SurfaceGroupSilverlight.html
@@ -0,0 +1,179 @@
+<html dir="rtl">
+	<head>
+		<title>Testing textpath</title>
+		<style type="text/css">
+			@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, gfxRenderer:'silverlight'"></script>
+		<script type="text/javascript">
+
+			dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._gfxBidiSupport");
+			dojo.require("doh.runner");
+
+
+			var CPD = 30, tp3, t1, t2, t3, t4, t5, t6;
+			var g1 = null, g2 = null, g3, g4;
+
+			var surfaceLTR = null, surfaceRTL = null, surfaceAUTO = null;
+			
+			var placeAnchor = function(surface, x, y){
+				surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y});
+				surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2});
+			};			
+			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;
+			};
+
+			makeShapes = function(){
+				var m = dojox.gfx.matrix;
+				surfaceLTR = dojox.gfx.createSurface("testLTR", 500, 170, "ltr");
+				console.debug("surfaceLTR created");
+				var p = surfaceLTR.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 50,  0)
+					;
+				console.debug("p created");
+				g1 = surfaceLTR.createGroup();
+				g1.setTextDir("rtl");
+		//		surfaceLTR.setTextDir("ltr");
+				t1 = makeText(g1, {id: "t1",x: 0, y: 100, text: "1.) \u05e9\u05dc\u05d5\u05dd world!"}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 150));
+
+				t2 = makeText(surfaceLTR, {x: 0, y: 140, text: "1.) Hello \u05e2\u05d5\u05dc\u05dd!"}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 100));
+				
+				surfaceRTL = dojox.gfx.createSurface("testRTL", 500, 170);
+				console.debug("surfaceRTL created");
+				var p2 = surfaceRTL.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					;
+				console.debug("p2 created");
+				tp3 = makeText(surfaceRTL, {x: 0, y: 160, text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 100));
+				
+				g2 = surfaceRTL.createGroup();
+				g2.add(tp3);
+				g2.setTextDir("ltr");
+				  
+				g3 = g2.createGroup("rtl");
+				
+				g4 = surfaceRTL.createGroup("auto");
+				console.debug("tp3 created");
+
+				t3 = makeText(g3, {id: "t1",x: 0, y: 100, text: "1.) \u05e9\u05dc\u05d5\u05dd world!"}, 
+					{family: "Times", size: "18pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 150));
+
+				t4 = makeText(surfaceRTL, {x: 0, y: 140, text: "1.) Hello \u05e2\u05d5\u05dc\u05dd!"}, 
+					{family: "Times", size: "18pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 100));
+				
+				surfaceAUTO = dojox.gfx.createSurface("testAUTO", 500, 170,"auto");
+				console.debug("surfaceAUTO created");
+				var p3 = surfaceAUTO.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					;
+				console.debug("p3 created");
+
+				t5 = makeText(surfaceAUTO, {id: "t1",x: 0, y: 100, text: "1.) \u05e9\u05dc\u05d5\u05dd world!"}, 
+					{family: "Times", size: "18pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 150));
+
+				t6 = makeText(surfaceAUTO, {x: 0, y: 140, text: "1.) Hello \u05e2\u05d5\u05dc\u05dd!"}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 100));
+
+				};
+				
+			dojo.addOnLoad(function(){
+				makeShapes();
+				
+
+				doh.register("Test inheritance", [
+					function surfaces_TextDir(){
+						doh.is("ltr", surfaceLTR.getTextDir(), "surfaceLTR.getTextDir"); 
+						doh.is("rtl", surfaceRTL.getTextDir(), "surfaceRTL.getTextDir"); 
+						doh.is("auto", surfaceAUTO.getTextDir(), "surfaceAUTO.getTextDir"); 
+					},
+					function groups_TextDir(){
+						doh.is("rtl", g1.getTextDir(), "g1.getTextDir"); 
+						doh.is("ltr", g2.getTextDir(), "g2.getTextDir"); 
+						doh.is("rtl", g3.getTextDir(), "g3.getTextDir"); 
+						doh.is("auto", g4.getTextDir(), "g4.getTextDir"); 
+					},
+					function gfxText_TextDir(){
+						doh.is("rtl", t1.textDir, "t1.getTextDir"); 
+						doh.is("ltr", t2.textDir, "t2.getTextDir"); 
+						doh.is("rtl", t3.textDir, "t3.getTextDir"); 
+						doh.is("rtl", t4.textDir, "t4.getTextDir"); 
+						doh.is("auto", t5.textDir, "t5.getTextDir"); 
+						doh.is("auto", t6.textDir, "t6.getTextDir"); 
+						doh.is("ltr", tp3.textDir, "tp3.getTextDir"); 
+					},
+					function changeSurfaceRTLextDir(){
+						surfaceRTL.setTextDir("ltr");
+						
+						doh.is("ltr", surfaceRTL.getTextDir(), "surfaceRTL.getTextDir"); 
+
+						doh.is("ltr", g2.getTextDir(), "g2.getTextDir"); 
+						doh.is("ltr", g3.getTextDir(), "g3.getTextDir"); 
+						doh.is("ltr", g4.getTextDir(), "g4.getTextDir"); 
+						
+						
+						doh.is("ltr", t3.textDir, "t3.getTextDir"); 
+						doh.is("ltr", t4.textDir, "t4.getTextDir"); 
+						
+						doh.is("ltr", tp3.textDir, "tp3.getTextDir"); 
+					},
+					function changeGroupTextDir(){
+						// add doesn't work for silverlight because of the rawNode call.
+//						g3.add(t5);
+//						g3.add(t2);
+						
+						g2.setTextDir("rtl");
+
+						doh.is("rtl", g2.getTextDir(), "g2.getTextDir"); 
+						// son of g2
+						doh.is("rtl", g3.getTextDir(), "g3.getTextDir"); 
+						
+//						doh.is("rtl", t2.textDir, "t2.getTextDir"); 
+						doh.is("rtl", t3.textDir, "t3.getTextDir"); 
+						
+//						doh.is("rtl", t5.textDir, "t5.getTextDir"); 
+					}
+				]);
+
+				doh.run();
+				
+			});
+
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx Text on a Path test</h1>
+		<h2>LTR TextPath and Text first two are TextPath and two others are Text</h2>
+		<div id="testLTR" style="width: 500px;"></div>
+		<h2>RTL Text Path and Text first two are TextPath and two others are Text</h2>
+		<div id="testRTL" style="width: 500px;"></div>
+		<h2>AUTO Text Path and Text first two are TextPath and two others are Text</h2>
+		<div id="testAUTO" style="width: 500px;"></div>
+
+	<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/_gfxBidiSupport/silverlight/textBidiSilverlight.html b/dojox/gfx/tests/_gfxBidiSupport/silverlight/textBidiSilverlight.html
new file mode 100644
index 0000000..461f91a
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/silverlight/textBidiSilverlight.html
@@ -0,0 +1,69 @@
+<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, gfxRenderer:'silverlight'"></script>
+
+		<script type="text/javascript">
+			dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._gfxBidiSupport");
+
+			var ROTATION = 30;
+
+			var surface = null, t1, t2, t3, t4, t5;
+
+			var placeAnchor = function(surface, x, y){
+				surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y});
+				surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2});
+			};
+
+			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;
+			};
+
+			makeShapes = function(){
+				surface = dojox.gfx.createSurface("test", 700, 500);
+				var m = dojox.gfx.matrix;
+				//surface.createLine({x1: 250, y1: 0, x2: 250, y2: 500}).setStroke("green");
+				t1 = makeText(surface, {id: "t1",x: 250, y: 50, text: "1.) \u05e9\u05dc\u05d5\u05dd world LTR!", textDir:"ltr"}, 
+					{family: "Times", size: "24pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 50));
+				
+				t2 = makeText(surface, {x: 250, y: 100, text: "2.) Hello \u05e2\u05d5\u05dc\u05dd LTR!", textDir:"ltr"}, 
+					{family: "Times", size: "24pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 100));
+
+				t3 = makeText(surface, {x: 250, y: 150, text: "3.)\u05e9\u05dc\u05d5\u05dd world RTL!", textDir:"rtl"}, 
+					{family: "Times", size: "24pt"}, "red", "black")
+					.setTransform(m.rotategAt(0, 250, 150));
+				t4 = makeText(surface, {x: 250, y: 200, text: "4.) Hello \u05e2\u05d5\u05dc\u05dd RTL!",  kerning: true,textDir:"rtl"}, 
+					{family: "Times", size: "24pt"}, "red", "black")
+					.setTransform(m.rotategAt(0, 250, 200));
+				t5 = makeText(surface, {x: 250, y: 250, text: "5.) \u05e9\u05dc\u05d5\u05dd world AUTO!", kerning: false,textDir:"auto"}, 
+					{family: "Times", size: "24pt"}, "red", "black")
+					.setTransform(m.rotategAt(0, 250, 250));
+				t6 = makeText(surface, {x: 250, y: 300, text: "6.) Hello \u05e2\u05d5\u05dc\u05dd AUTO!", kerning: false,textDir:"auto"}, 
+					{family: "Times", size: "24pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 300));			
+			};
+
+			dojo.addOnLoad(makeShapes);
+
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx Text test</h1>
+		<div id="test" style="width: 700px; height: 500px;"></div>
+
+
+	</body>
+</html>
diff --git a/dojox/gfx/tests/_gfxBidiSupport/svgWeb/dynamicallyChangeTextSvgWeb.html b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/dynamicallyChangeTextSvgWeb.html
new file mode 100644
index 0000000..5c92bb3
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/dynamicallyChangeTextSvgWeb.html
@@ -0,0 +1,89 @@
+<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>
+<!-- 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 type="text/javascript">
+			dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._gfxBidiSupport");
+
+			var ROTATION = 30;
+
+			var surface = null, t1;
+
+			var placeAnchor = function(surface, x, y){
+				surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y});
+				surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2});
+			};
+
+			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;
+			};
+
+			makeShapes = function(){
+				surface = dojox.gfx.createSurface("test", 500, 200);
+				surface.whenLoaded(function() {
+					var m = dojox.gfx.matrix;
+					//surface.createLine({x1: 250, y1: 0, x2: 250, y2: 500}).setStroke("green");
+					t1 = makeText(surface, {id: "t1",x: 250, y: 50, text:"Hello!", textDir:"ltr"}, 
+						{family: "Times", size: "24pt"}, "black", "red")
+						.setTransform(m.rotategAt(0, 250, 50));
+				});
+		
+			}
+
+			dojo.addOnLoad(makeShapes);
+
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx Text test</h1>
+		<div id="test" style="width: 500px; height: 200px;"></div>
+
+		<label>write inside to test dojox.gfx.Text with BidiEngine</label>
+		<br>
+		<textarea id="inputF" 
+       		onkeyup="dealInput();"
+ 		>write in me to test dojox.gfx.Text with BidiEngine</textarea>
+		
+		<script>
+			function dealInput(){
+				var  v = inputF.value ? inputF.value : ""; 
+				t1.setShape({text: v});
+			}
+		</script>
+		
+		<br>
+		<input id="SHALOM" type="button" value="click on me to write a Hebrew word!"
+			onclick="t1.setShape({text:'\u05e9\u05dc\u05d5\u05dd!'}); inputF.value = '\u05e9\u05dc\u05d5\u05dd!'"
+		/>	
+
+		<br>
+		<br>
+
+		<input id="textDirLTR" type="button" value="change textDir to 'LTR'"
+			onclick="t1.setShape({textDir:'ltr'});"
+		/>		
+		<input id="textDirRTL" type="button" value="change textDir to 'RTL'"
+			onclick="t1.setShape({textDir:'rtl'});"
+		/>		
+		<input id="textDirAUTO" type="button" value="change textDir to 'AUTO'"
+			onclick="t1.setShape({textDir:'auto'});"
+		/>	
+
+	</body>
+</html>
diff --git a/dojox/gfx/tests/_gfxBidiSupport/svgWeb/inheritFromSurfaceSvgWeb.html b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/inheritFromSurfaceSvgWeb.html
new file mode 100644
index 0000000..90e173e
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/inheritFromSurfaceSvgWeb.html
@@ -0,0 +1,192 @@
+<html dir="rtl">
+	<head>
+		<title>Testing textpath</title>
+		<style type="text/css">
+			@import "../../../../../dojo/resources/dojo.css";
+			@import "../../../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<!-- 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 type="text/javascript">
+
+			dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._gfxBidiSupport");
+
+			var CPD = 30, tp1, tp2, tp3,tp4,tp5, t1, t2, t3, t4, t5, t6;
+			var g1 = null;
+			var g2 = null;
+
+			var surfaceLTR = null, surfaceRTL = null, surfaceAUTO = null;
+			
+			var placeAnchor = function(surface, x, y){
+				surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y});
+				surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2});
+			};			
+			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;
+			};
+
+			makeShapes = function(){
+				var m = dojox.gfx.matrix;
+				surfaceLTR = dojox.gfx.createSurface("testLTR", 500, 170, "ltr");
+				surfaceLTR.whenLoaded(function() {
+					console.debug("surfaceLTR created");
+					var p = surfaceLTR.createPath({})
+						.moveTo(0, 15)
+						.setAbsoluteMode(false)
+						.curveTo(CPD, 0, 0,  0, 50,  0)
+						;
+					console.debug("p created");
+					tp1 = surfaceLTR.createTextPath({
+							text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+							, align: "start"
+						})
+						.moveTo(0, 15)
+						.setAbsoluteMode(false)
+						.curveTo(CPD, 0, 0,  0, 100,  0)
+						.setFont({family: "times", size: "12pt"})
+						.setFill("blue")
+						;
+					console.debug("tp1 created");
+					tp2 = surfaceLTR.createTextPath({
+							text: "Beginning \u05e1\u05d5\u05e3."
+							, align: "start"
+							
+						})
+						.moveTo(0, 50)
+						.setAbsoluteMode(false)
+						.curveTo(CPD, 0, 0,  0, 100,  0)
+						.setFont({family: "times", size: "12pt"})
+						.setFill("blue")
+						;
+					console.debug("tp2 created");
+					g1 = surfaceLTR.createGroup();
+					t1 = makeText(surfaceLTR, {id: "t1",x: 0, y: 100, text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end."}, 
+						{family: "Times", size: "18pt"}, "black", "blue")
+						.setTransform(m.rotategAt(0, 250, 150));
+
+					t2 = makeText(surfaceLTR, {x: 0, y: 140, text: "Beginning \u05e1\u05d5\u05e3."}, 
+						{family: "Times", size: "18pt"}, "black", "blue")
+						.setTransform(m.rotategAt(0, 250, 100));
+				});				
+				surfaceRTL = dojox.gfx.createSurface("testRTL", 500, 170);
+				console.debug("surfaceRTL created");
+				surfaceRTL.whenLoaded(function() {
+					var p2 = surfaceRTL.createPath({})
+						.moveTo(0, 15)
+						.setAbsoluteMode(false)
+						.curveTo(CPD, 0, 0,  0, 100,  0)
+						;
+					console.debug("p2 created");
+					tp3 = surfaceRTL.createTextPath({
+							text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+							, align: "start"
+							//, rotated: true
+						})
+						.moveTo(0, 15)
+						.setAbsoluteMode(false)
+						.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+						.setFont({family: "times", size: "12pt"})
+						.setFill("red")
+						;
+					console.debug("tp3 created");
+					tp4 = surfaceRTL.createTextPath({
+							text: "Beginning \u05e1\u05d5\u05e3."
+							, align: "start"
+							
+							//, rotated: true
+						})
+						//.setShape(p.shape)
+						.moveTo(0, 50)
+						.setAbsoluteMode(false)
+						.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+						.setFont({family: "times", size: "12pt"})
+						.setFill("red")
+						;				
+					console.debug("tp4 created");
+
+					t3 = makeText(surfaceRTL, {id: "t1",x: 0, y: 100, text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end."}, 
+						{family: "Times", size: "18pt"}, "black", "red")
+						.setTransform(m.rotategAt(0, 250, 150));
+
+					t4 = makeText(surfaceRTL, {x: 0, y: 140, text: "Beginning \u05e1\u05d5\u05e3."}, 
+						{family: "Times", size: "18pt"}, "black", "red")
+						.setTransform(m.rotategAt(0, 250, 100));
+				});					
+				surfaceAUTO = dojox.gfx.createSurface("testAUTO", 500, 170,"auto");
+				console.debug("surfaceAUTO created");
+
+				surfaceAUTO.whenLoaded(function() {
+					var p3 = surfaceAUTO.createPath({})
+						.moveTo(0, 15)
+						.setAbsoluteMode(false)
+						.curveTo(CPD, 0, 0,  0, 100,  0)
+						;
+					console.debug("p3 created");
+
+					var tp5 = surfaceAUTO.createTextPath({
+							text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+							, align: "start"
+							
+							//, rotated: true
+						})
+						//.setShape(p.shape)
+						.moveTo(0, 15)
+						.setAbsoluteMode(false)
+						.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+
+						.setFont({family: "times", size: "12pt"})
+						.setFill("red")
+						;
+					console.debug("tp5 created");
+					var tp6 = surfaceAUTO.createTextPath({
+							text: "Beginning \u05e1\u05d5\u05e3."
+							, align: "start"
+							
+							//, rotated: true
+						})
+						//.setShape(p.shape)
+						.moveTo(0, 50)
+						.setAbsoluteMode(false)
+						.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+						.setFont({family: "times", size: "12pt"})
+						.setFill("blue")
+						;				
+					console.debug("tp6 created");
+
+					t3 = makeText(surfaceAUTO, {id: "t1",x: 0, y: 100, text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end."}, 
+						{family: "Times", size: "18pt"}, "black", "red")
+						.setTransform(m.rotategAt(0, 250, 150));
+
+					t4 = makeText(surfaceAUTO, {x: 0, y: 140, text: "Beginning \u05e1\u05d5\u05e3."}, 
+						{family: "Times", size: "18pt"}, "black", "blue")
+						.setTransform(m.rotategAt(0, 250, 100));
+				});
+			};
+
+				
+			dojo.addOnLoad(makeShapes);
+
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx Text on a Path test</h1>
+		<h2>LTR TextPath and Text first two are TextPath and two others are Text</h2>
+		<div id="testLTR" style="width: 500px;"></div>
+		<h2>RTL Text Path and Text first two are TextPath and two others are Text</h2>
+		<div id="testRTL" style="width: 500px;"></div>
+		<h2>AUTO Text Path and Text first two are TextPath and two others are Text</h2>
+		<div id="testAUTO" style="width: 500px;"></div>
+
+	<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/_gfxBidiSupport/svgWeb/test_SurfaceGroupSvgWeb.html b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/test_SurfaceGroupSvgWeb.html
new file mode 100644
index 0000000..d2c28e7
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/test_SurfaceGroupSvgWeb.html
@@ -0,0 +1,274 @@
+<html dir="rtl">
+	<head>
+		<title>Testing textpath</title>
+		<style type="text/css">
+			@import "../../../../../dojo/resources/dojo.css";
+			@import "../../../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<!-- 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 type="text/javascript">
+
+			dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._gfxBidiSupport");
+			dojo.require("doh.runner");
+
+			var CPD = 30, tp1, tp2, tp3, tp4, tp5, tp6, t1, t2, t3, t4, t5, t6;
+			var g1 = null, g2 = null, g3, g4;
+
+			var surfaceLTR = null, surfaceRTL = null, surfaceAUTO = null;
+			
+			var placeAnchor = function(surface, x, y){
+				surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y});
+				surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2});
+			};			
+
+			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;
+			};
+
+			var makeShapes = function(){
+				var m = dojox.gfx.matrix;
+				surfaceLTR = dojox.gfx.createSurface("testLTR", 500, 170, "ltr");
+				console.debug("surfaceLTR created");
+				
+				surfaceLTR.whenLoaded(function() {
+					var p = surfaceLTR.createPath({})
+						.moveTo(0, 15)
+						.setAbsoluteMode(false)
+						.curveTo(CPD, 0, 0,  0, 50,  0)
+						;
+					console.debug("p created");
+					tp1 = surfaceLTR.createTextPath({
+							text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end."
+							, align: "start"
+						})
+						.moveTo(0, 15)
+						.setAbsoluteMode(false)
+						.curveTo(CPD, 0, 0,  0, 100,  0)
+						.setFont({family: "times", size: "12pt"})
+						.setFill("blue")
+						;
+					console.debug("tp1 created");
+					tp2 = surfaceLTR.createTextPath({
+							text: "Beginning \u05e1\u05d5\u05e3."
+							, align: "start"
+							
+						})
+						.moveTo(0, 50)
+						.setAbsoluteMode(false)
+						.curveTo(CPD, 0, 0,  0, 100,  0)
+						.setFont({family: "times", size: "12pt"})
+						.setFill("blue")
+						;
+					console.debug("tp2 created");
+
+					g1 = surfaceLTR.createGroup();
+					g1.setTextDir("rtl");
+
+					t1 = makeText(g1, {id: "t1",x: 0, y: 100, text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end."}, 
+						{family: "Times", size: "18pt"}, "black", "blue")
+						.setTransform(m.rotategAt(0, 250, 150));
+
+					t2 = makeText(surfaceLTR, {x: 0, y: 140, text: "Beginning \u05e1\u05d5\u05e3."}, 
+						{family: "Times", size: "18pt"}, "black", "blue")
+						.setTransform(m.rotategAt(0, 250, 100));
+
+					surfaceRTL = dojox.gfx.createSurface("testRTL", 500, 170);
+					console.debug("surfaceRTL created");
+
+					surfaceRTL.whenLoaded(function(){
+						var p2 = surfaceRTL.createPath({})
+							.moveTo(0, 15)
+							.setAbsoluteMode(false)
+							.curveTo(CPD, 0, 0,  0, 100,  0)
+							;
+						console.debug("p2 created");
+						tp3 = surfaceRTL.createTextPath({
+								text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+								, align: "start"
+								//, rotated: true
+							})
+							.moveTo(0, 15)
+							.setAbsoluteMode(false)
+							.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+							.setFont({family: "times", size: "12pt"})
+							.setFill("red")
+							;
+						g2 = surfaceRTL.createGroup();
+						g2.add(tp3);
+						g2.setTextDir("ltr");
+						  
+						g3 = g2.createGroup("rtl");
+						
+						g4 = surfaceRTL.createGroup("auto");
+						console.debug("tp3 created");
+						tp4 = surfaceRTL.createTextPath({
+								text: "Beginning \u05e1\u05d5\u05e3."
+								, align: "start"
+								
+								//, rotated: true
+							})
+							//.setShape(p.shape)
+							.moveTo(0, 50)
+							.setAbsoluteMode(false)
+							.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+							.setFont({family: "times", size: "12pt"})
+							.setFill("red")
+							;				
+						console.debug("tp4 created");
+
+						t3 = makeText(g3, {id: "t1",x: 0, y: 100, text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end."}, 
+							{family: "Times", size: "18pt"}, "black", "red")
+							.setTransform(m.rotategAt(0, 250, 150));
+
+						t4 = makeText(surfaceRTL, {x: 0, y: 140, text: "Beginning \u05e1\u05d5\u05e3."}, 
+							{family: "Times", size: "18pt"}, "black", "red")
+							.setTransform(m.rotategAt(0, 250, 100));
+							
+						surfaceAUTO = dojox.gfx.createSurface("testAUTO", 500, 170,"auto");
+						console.debug("surfaceAUTO created");
+						
+						surfaceAUTO.whenLoaded(function() {
+							var p3 = surfaceAUTO.createPath({})
+								.moveTo(0, 15)
+								.setAbsoluteMode(false)
+								.curveTo(CPD, 0, 0,  0, 100,  0)
+								;
+							console.debug("p3 created");
+
+							tp5 = surfaceAUTO.createTextPath({
+									text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+									, align: "start"
+									
+									//, rotated: true
+								})
+								//.setShape(p.shape)
+								.moveTo(0, 15)
+								.setAbsoluteMode(false)
+								.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+
+								.setFont({family: "times", size: "12pt"})
+								.setFill("red")
+								;
+							console.debug("tp5 created");
+							tp6 = surfaceAUTO.createTextPath({
+									text: "Beginning \u05e1\u05d5\u05e3."
+									, align: "start"
+									
+									//, rotated: true
+								})
+								//.setShape(p.shape)
+								.moveTo(0, 50)
+								.setAbsoluteMode(false)
+								.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+								.setFont({family: "times", size: "12pt"})
+								.setFill("blue")
+								;				
+							console.debug("tp6 created");
+
+							t5 = makeText(surfaceAUTO, {id: "t1",x: 0, y: 100, text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end."}, 
+								{family: "Times", size: "18pt"}, "black", "red")
+								.setTransform(m.rotategAt(0, 250, 150));
+
+							t6 = makeText(surfaceAUTO, {x: 0, y: 140, text: "Beginning \u05e1\u05d5\u05e3."}, 
+								{family: "Times", size: "18pt"}, "black", "blue")
+								.setTransform(m.rotategAt(0, 250, 100));
+							
+							runTests();
+						});	
+					});
+				});
+			};
+				
+			function runTests(){
+				doh.register("Test inheritance", [
+					function surfaces_TextDir(){
+						doh.is("ltr", surfaceLTR.getTextDir(), "surfaceLTR.getTextDir"); 
+						doh.is("rtl", surfaceRTL.getTextDir(), "surfaceRTL.getTextDir"); 
+						doh.is("auto", surfaceAUTO.getTextDir(), "surfaceAUTO.getTextDir"); 
+					},
+					function groups_TextDir(){
+						doh.is("rtl", g1.getTextDir(), "g1.getTextDir"); 
+						doh.is("ltr", g2.getTextDir(), "g2.getTextDir"); 
+						doh.is("rtl", g3.getTextDir(), "g3.getTextDir"); 
+						doh.is("auto", g4.getTextDir(), "g4.getTextDir"); 
+					},
+					function gfxText_TextDir(){
+						doh.is("rtl", t1.textDir, "t1.getTextDir"); 
+						doh.is("ltr", t2.textDir, "t2.getTextDir"); 
+						doh.is("rtl", t3.textDir, "t3.getTextDir"); 
+						doh.is("rtl", t4.textDir, "t4.getTextDir"); 
+						doh.is("auto", t5.textDir, "t5.getTextDir"); 
+						doh.is("auto", t6.textDir, "t6h.getTextDir"); 
+					},
+					function gfxTextPath_TextDir(){
+						doh.is("ltr", tp1.textDir, "tp1.getTextDir"); 
+						doh.is("ltr", tp2.textDir, "tp2.getTextDir"); 
+						doh.is("ltr", tp3.textDir, "tp3.getTextDir"); 
+						doh.is("rtl", tp4.textDir, "tp4.getTextDir"); 
+						doh.is("auto", tp5.textDir, "tp5.getTextDir"); 
+						doh.is("auto", tp6.textDir, "tp6.getTextDir"); 
+					},
+					function changeSurfaceRTLextDir(){
+						surfaceRTL.setTextDir("ltr");
+						
+						doh.is("ltr", surfaceRTL.getTextDir(), "surfaceRTL.getTextDir"); 
+
+						doh.is("ltr", g2.getTextDir(), "g2.getTextDir"); 
+						doh.is("ltr", g3.getTextDir(), "g3.getTextDir"); 
+						doh.is("ltr", g4.getTextDir(), "g4.getTextDir"); 
+						
+						
+						doh.is("ltr", t3.textDir, "t3.getTextDir"); 
+						doh.is("ltr", t4.textDir, "t4.getTextDir"); 
+						
+						doh.is("ltr", tp3.textDir, "tp3.getTextDir"); 
+						doh.is("ltr", tp4.textDir, "tp4.getTextDir"); 
+					},
+					function changeGroupTextDir(){
+					
+						g3.add(tp5);
+						g3.add(t2);
+						
+						g2.setTextDir("rtl");
+
+						doh.is("rtl", g2.getTextDir(), "g2.getTextDir"); 
+						// son of g2
+						doh.is("rtl", g3.getTextDir(), "g3.getTextDir"); 
+						
+						doh.is("rtl", t2.textDir, "t2.getTextDir"); 
+						doh.is("rtl", t3.textDir, "t3.getTextDir"); 
+						
+						doh.is("rtl", tp5.textDir, "tp3.getTextDir"); 
+					}
+				]);
+
+				doh.run();
+			}				
+
+			dojo.addOnLoad(makeShapes);	
+
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx Text on a Path test</h1>
+		<h2>LTR TextPath and Text first two are TextPath and two others are Text</h2>
+		<div id="testLTR" style="width: 500px;"></div>
+		<h2>RTL Text Path and Text first two are TextPath and two others are Text</h2>
+		<div id="testRTL" style="width: 500px;"></div>
+		<h2>AUTO Text Path and Text first two are TextPath and two others are Text</h2>
+		<div id="testAUTO" style="width: 500px;"></div>
+
+	<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/_gfxBidiSupport/svgWeb/textBidiSvgWeb.html b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/textBidiSvgWeb.html
new file mode 100644
index 0000000..0a75a08
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/textBidiSvgWeb.html
@@ -0,0 +1,80 @@
+<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>
+<!-- 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 type="text/javascript">	
+		dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._gfxBidiSupport");
+			
+			
+
+			var surface = null, t1, t2, t3, t4, t5;
+
+			var placeAnchor = function(surface, x, y){
+				surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y});
+				surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2});
+			};
+
+			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;
+			};
+
+			makeShapes = function(){
+				surface = dojox.gfx.createSurface("test", 500, 500);
+				surface.whenLoaded(function() {
+
+				var m = dojox.gfx.matrix;
+				//surface.createLine({x1: 250, y1: 0, x2: 250, y2: 500}).setStroke("green");
+				t1 = makeText(surface, {id: "t1",x: 250, y: 50, text: "@ \u05e9\u05dc\u05d5\u05dd world LTR!", textDir:"ltr"}, 
+					{family: "Times", size: "24pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 50));
+				
+				t2 = makeText(surface, {x: 250, y: 100, text: "@ Hello \u05e2\u05d5\u05dc\u05dd LTR!", textDir:"ltr"}, 
+					{family: "Times", size: "24pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 100));
+
+				t3 = makeText(surface, {x: 250, y: 150, text: "@ \u05e9\u05dc\u05d5\u05dd world RTL!", textDir:"rtl"}, 
+					{family: "Times", size: "24pt"}, "red", "black")
+					.setTransform(m.rotategAt(0, 250, 150));
+				t4 = makeText(surface, {x: 250, y: 200, text: "@ Hello \u05e2\u05d5\u05dc\u05dd RTL!",  kerning: true,textDir:"rtl"}, 
+					{family: "Times", size: "24pt"}, "red", "black")
+					.setTransform(m.rotategAt(0, 250, 200));
+				t5 = makeText(surface, {x: 250, y: 250, text: "@ \u05e9\u05dc\u05d5\u05dd world AUTO!", kerning: false,textDir:"auto"}, 
+					{family: "Times", size: "24pt"}, "red", "black")
+					.setTransform(m.rotategAt(0, 250, 250));
+				t6 = makeText(surface, {x: 250, y: 300, text: "@ Hello \u05e2\u05d5\u05dc\u05dd AUTO!", kerning: false,textDir:"auto"}, 
+					{family: "Times", size: "24pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 300));	
+				});
+			};
+
+			dojo.addOnLoad(makeShapes);
+
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx Text test</h1>
+
+		<h2>The black colored sentences should be in LTR layout</h2>
+		<h2>The red colored sentences should be in RTL layout</h2>
+
+		<div id="test" style="width: 700px; height: 500px;"></div>
+		
+
+
+	</body>
+</html>
diff --git a/dojox/gfx/tests/_gfxBidiSupport/svgWeb/textpathBidiSvgWeb.html b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/textpathBidiSvgWeb.html
new file mode 100644
index 0000000..0f9e677
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/textpathBidiSvgWeb.html
@@ -0,0 +1,151 @@
+<title>Testing textpath</title>
+<style type="text/css">
+	@import "../../../../../dojo/resources/dojo.css";
+	@import "../../../../../dijit/tests/css/dijitTests.css";
+</style>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<!-- 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 type="text/javascript">
+			dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._gfxBidiSupport");
+
+			var CPD = 30, t, t2, t3,t4,t5;
+
+			var surface = null;
+
+			makeShapes = function(){
+				surfaceLTR = dojox.gfx.createSurface("testLTR", 500, 60);
+surfaceLTR.whenLoaded(function() {
+				console.debug("surfaceLTR created");
+				var p = surfaceLTR.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 50,  0)
+					;
+				console.debug("p created");
+				var t = surfaceLTR.createTextPath({
+						text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+						, align: "start"
+						, textDir: "ltr"
+					})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("blue")
+					;
+				console.debug("t created");
+				var t2 = surfaceLTR.createTextPath({
+						text: "Beginning \u05e1\u05d5\u05e3."
+						, align: "start"
+						,textDir: "ltr"
+					})
+					.moveTo(0, 50)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("blue")
+					;
+				console.debug("t2 created");
+});	
+				surfaceRTL = dojox.gfx.createSurface("testRTL", 500, 60);
+				
+surfaceRTL.whenLoaded(function() {
+				console.debug("surfaceRTL created");
+				var p2 = surfaceRTL.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					;
+				console.debug("p2 created");
+
+				var t3 = surfaceRTL.createTextPath({
+						text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+						, align: "start"
+						,textDir: "rtl"
+						//, rotated: true
+					})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("red")
+					;
+				console.debug("t3 created");
+				var t4 = surfaceRTL.createTextPath({
+						text: "Beginning \u05e1\u05d5\u05e3."
+						, align: "start"
+						,textDir: "rtl"
+						//, rotated: true
+					})
+					//.setShape(p.shape)
+					.moveTo(0, 50)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("red")
+					;				
+				console.debug("t4 created");
+});					
+				surfaceAUTO = dojox.gfx.createSurface("testAUTO", 500, 60);
+surfaceAUTO.whenLoaded(function() {
+				console.debug("surfaceAUTO created");
+				var p3 = surfaceAUTO.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					;
+				console.debug("p3 created");
+
+				var t5 = surfaceAUTO.createTextPath({
+						text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+						, align: "start"
+						, textDir: "auto"
+						//, rotated: true
+					})
+					//.setShape(p.shape)
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+
+					.setFont({family: "times", size: "12pt"})
+					.setFill("red")
+					;
+				console.debug("t5 created");
+				var t6 = surfaceAUTO.createTextPath({
+						text: "Beginning \u05e1\u05d5\u05e3."
+						, align: "start"
+						, textDir: "auto"
+						//, rotated: true
+					})
+					//.setShape(p.shape)
+					.moveTo(0, 50)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("blue")
+					;				
+				console.debug("t6 created");
+});				
+			};
+
+			dojo.addOnLoad(makeShapes);
+
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx Text on a Path test</h1>
+		<h2>LTR Text Path</h2>
+		<div id="testLTR" style="width: 500px;"></div>
+		<h2>RTL Text Path</h2>
+		<div id="testRTL" style="width: 500px;"></div>
+		<h2>AUTO Text Path</h2>
+		<div id="testAUTO" style="width: 500px;"></div>
+
+	<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/_gfxBidiSupport/test_SurfaceGroup.html b/dojox/gfx/tests/_gfxBidiSupport/test_SurfaceGroup.html
new file mode 100644
index 0000000..ab8785e
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/test_SurfaceGroup.html
@@ -0,0 +1,262 @@
+<html dir="rtl">
+	<head>
+		<title>Testing textpath</title>
+		<style type="text/css">
+			@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">
+
+			dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._gfxBidiSupport");
+			dojo.require("doh.runner");
+
+
+			var CPD = 30, tp1, tp2, tp3, tp4, tp5, tp6, t1, t2, t3, t4, t5, t6;
+			var g1 = null, g2 = null, g3, g4;
+
+			var surfaceLTR = null, surfaceRTL = null, surfaceAUTO = null;
+			
+			var placeAnchor = function(surface, x, y){
+				surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y});
+				surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2});
+			};			
+			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;
+			};
+
+			makeShapes = function(){
+				var m = dojox.gfx.matrix;
+				surfaceLTR = dojox.gfx.createSurface("testLTR", 500, 170, "ltr");
+				console.debug("surfaceLTR created");
+				var p = surfaceLTR.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 50,  0)
+					;
+				console.debug("p created");
+				tp1 = surfaceLTR.createTextPath({
+						text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+						, align: "start"
+					})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("blue")
+					;
+				console.debug("tp1 created");
+				tp2 = surfaceLTR.createTextPath({
+						text: "Beginning \u05e1\u05d5\u05e3."
+						, align: "start"
+						
+					})
+					.moveTo(0, 50)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("blue")
+					;
+				console.debug("tp2 created");
+				g1 = surfaceLTR.createGroup();
+				g1.setTextDir("rtl");
+		//		surfaceLTR.setTextDir("ltr");
+				t1 = makeText(g1, {id: "t1",x: 0, y: 100, text: "1.) \u05d4\u05ea\u05d7\u05dc\u05d4 end!"}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 150));
+
+				t2 = makeText(surfaceLTR, {x: 0, y: 140, text: "1.) Beginning \u05e1\u05d5\u05e3!"}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 100));
+				
+				surfaceRTL = dojox.gfx.createSurface("testRTL", 500, 170);
+				console.debug("surfaceRTL created");
+				var p2 = surfaceRTL.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					;
+				console.debug("p2 created");
+				tp3 = surfaceRTL.createTextPath({
+						text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+						, align: "start"
+						//, rotated: true
+					})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("red")
+					;
+				g2 = surfaceRTL.createGroup();
+				g2.add(tp3);
+				g2.setTextDir("ltr");
+				  
+				g3 = g2.createGroup("rtl");
+				
+				g4 = surfaceRTL.createGroup("auto");
+				console.debug("tp3 created");
+				tp4 = surfaceRTL.createTextPath({
+						text: "Beginning \u05e1\u05d5\u05e3."
+						, align: "start"
+						
+						//, rotated: true
+					})
+					//.setShape(p.shape)
+					.moveTo(0, 50)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("red")
+					;				
+				console.debug("tp4 created");
+
+				t3 = makeText(g3, {id: "t1",x: 0, y: 100, text: "1.) \u05d4\u05ea\u05d7\u05dc\u05d4 end!"}, 
+					{family: "Times", size: "18pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 150));
+
+				t4 = makeText(surfaceRTL, {x: 0, y: 140, text: "1.) Beginning \u05e1\u05d5\u05e3!"}, 
+					{family: "Times", size: "18pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 100));
+				
+				surfaceAUTO = dojox.gfx.createSurface("testAUTO", 500, 170,"auto");
+				console.debug("surfaceAUTO created");
+				var p3 = surfaceAUTO.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					;
+				console.debug("p3 created");
+
+				tp5 = surfaceAUTO.createTextPath({
+						text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+						, align: "start"
+						
+						//, rotated: true
+					})
+					//.setShape(p.shape)
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+
+					.setFont({family: "times", size: "12pt"})
+					.setFill("red")
+					;
+				console.debug("tp5 created");
+				tp6 = surfaceAUTO.createTextPath({
+						text: "Beginning \u05e1\u05d5\u05e3."
+						, align: "start"
+						
+						//, rotated: true
+					})
+					//.setShape(p.shape)
+					.moveTo(0, 50)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("blue")
+					;				
+				console.debug("tp6 created");
+
+				t5 = makeText(surfaceAUTO, {id: "t1",x: 0, y: 100, text: "1.) \u05d4\u05ea\u05d7\u05dc\u05d4 end!"}, 
+					{family: "Times", size: "18pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 150));
+
+				t6 = makeText(surfaceAUTO, {x: 0, y: 140, text: "1.) Beginning \u05e1\u05d5\u05e3!"}, 
+					{family: "Times", size: "18pt"}, "black", "blue")
+					.setTransform(m.rotategAt(0, 250, 100));
+
+				};
+
+				
+			dojo.addOnLoad(function(){
+				makeShapes();
+				
+
+				doh.register("Test inheritance", [
+					function surfaces_TextDir(){
+						doh.is("ltr", surfaceLTR.getTextDir(), "surfaceLTR.getTextDir"); 
+						doh.is("rtl", surfaceRTL.getTextDir(), "surfaceRTL.getTextDir"); 
+						doh.is("auto", surfaceAUTO.getTextDir(), "surfaceAUTO.getTextDir"); 
+					},
+					function groups_TextDir(){
+						doh.is("rtl", g1.getTextDir(), "g1.getTextDir"); 
+						doh.is("ltr", g2.getTextDir(), "g2.getTextDir"); 
+						doh.is("rtl", g3.getTextDir(), "g3.getTextDir"); 
+						doh.is("auto", g4.getTextDir(), "g4.getTextDir"); 
+					},
+					function gfxText_TextDir(){
+						doh.is("rtl", t1.textDir, "t1.getTextDir"); 
+						doh.is("ltr", t2.textDir, "t2.getTextDir"); 
+						doh.is("rtl", t3.textDir, "t3.getTextDir"); 
+						doh.is("rtl", t4.textDir, "t4.getTextDir"); 
+						doh.is("auto", t5.textDir, "t5.getTextDir"); 
+						doh.is("auto", t6.textDir, "t6h.getTextDir"); 
+					},
+					function gfxTextPath_TextDir(){
+						doh.is("ltr", tp1.textDir, "tp1.getTextDir"); 
+						doh.is("ltr", tp2.textDir, "tp2.getTextDir"); 
+						doh.is("ltr", tp3.textDir, "tp3.getTextDir"); 
+						doh.is("rtl", tp4.textDir, "tp4.getTextDir"); 
+						doh.is("auto", tp5.textDir, "tp5.getTextDir"); 
+						doh.is("auto", tp6.textDir, "tp6.getTextDir"); 
+					},
+					function changeSurfaceRTLextDir(){
+						surfaceRTL.setTextDir("ltr");
+						
+						doh.is("ltr", surfaceRTL.getTextDir(), "surfaceRTL.getTextDir"); 
+
+						doh.is("ltr", g2.getTextDir(), "g2.getTextDir"); 
+						doh.is("ltr", g3.getTextDir(), "g3.getTextDir"); 
+						doh.is("ltr", g4.getTextDir(), "g4.getTextDir"); 
+						
+						
+						doh.is("ltr", t3.textDir, "t3.getTextDir"); 
+						doh.is("ltr", t4.textDir, "t4.getTextDir"); 
+						
+						doh.is("ltr", tp3.textDir, "tp3.getTextDir"); 
+						doh.is("ltr", tp4.textDir, "tp4.getTextDir"); 
+					},
+					function changeGroupTextDir(){
+					
+						g3.add(tp5);
+						g3.add(t2);
+						
+						g2.setTextDir("rtl");
+
+						doh.is("rtl", g2.getTextDir(), "g2.getTextDir"); 
+						// son of g2
+						doh.is("rtl", g3.getTextDir(), "g3.getTextDir"); 
+						
+						doh.is("rtl", t2.textDir, "t2.getTextDir"); 
+						doh.is("rtl", t3.textDir, "t3.getTextDir"); 
+						
+						doh.is("rtl", tp5.textDir, "tp3.getTextDir"); 
+					}
+				]);
+
+				doh.run();
+				
+			});
+
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx Text on a Path test</h1>
+		<h2>LTR TextPath and Text first two are TextPath and two others are Text</h2>
+		<div id="testLTR" style="width: 500px;"></div>
+		<h2>RTL Text Path and Text first two are TextPath and two others are Text</h2>
+		<div id="testRTL" style="width: 500px;"></div>
+		<h2>AUTO Text Path and Text first two are TextPath and two others are Text</h2>
+		<div id="testAUTO" style="width: 500px;"></div>
+
+	<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/_gfxBidiSupport/textBidi.html b/dojox/gfx/tests/_gfxBidiSupport/textBidi.html
new file mode 100644
index 0000000..f0d2eed
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/textBidi.html
@@ -0,0 +1,69 @@
+<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">
+			dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._gfxBidiSupport");
+
+			var surface = null, t1, t2, t3, t4, t5;
+
+			var placeAnchor = function(surface, x, y){
+				surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y});
+				surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2});
+			};
+
+			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;
+			};
+
+			makeShapes = function(){
+				surface = dojox.gfx.createSurface("test", 700, 500);
+				var m = dojox.gfx.matrix;
+				//surface.createLine({x1: 250, y1: 0, x2: 250, y2: 500}).setStroke("green");
+				t1 = makeText(surface, {id: "t1",x: 250, y: 50, text: "1.) \u05e9\u05dc\u05d5\u05dd world LTR!", textDir:"ltr"}, 
+					{family: "Times", size: "24pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 50));
+				
+				t2 = makeText(surface, {x: 250, y: 100, text: "1.) Hello \u05e2\u05d5\u05dc\u05dd LTR!", textDir:"ltr"}, 
+					{family: "Times", size: "24pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 100));
+
+				t3 = makeText(surface, {x: 250, y: 150, text: "1.) \u05e9\u05dc\u05d5\u05dd world RTL!", textDir:"rtl"}, 
+					{family: "Times", size: "24pt"}, "red", "black")
+					.setTransform(m.rotategAt(0, 250, 150));
+				t4 = makeText(surface, {x: 250, y: 200, text: "1.) Hello \u05e2\u05d5\u05dc\u05dd RTL!",  kerning: true,textDir:"rtl"}, 
+					{family: "Times", size: "24pt"}, "red", "black")
+					.setTransform(m.rotategAt(0, 250, 200));
+				t5 = makeText(surface, {x: 250, y: 250, text: "1.) \u05e9\u05dc\u05d5\u05dd world AUTO!", kerning: false,textDir:"auto"}, 
+					{family: "Times", size: "24pt"}, "red", "black")
+					.setTransform(m.rotategAt(0, 250, 250));
+				t6 = makeText(surface, {x: 250, y: 300, text: "1.) Hello \u05e2\u05d5\u05dc\u05dd AUTO!", kerning: false,textDir:"auto"}, 
+					{family: "Times", size: "24pt"}, "black", "red")
+					.setTransform(m.rotategAt(0, 250, 300));
+
+//surface.setTextDir("ltr");					
+			};
+
+			dojo.addOnLoad(makeShapes);
+
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx Text test</h1>
+		<div id="test" style="width: 700px; height: 500px;"></div>
+
+
+	</body>
+</html>
diff --git a/dojox/gfx/tests/_gfxBidiSupport/textpathBidi.html b/dojox/gfx/tests/_gfxBidiSupport/textpathBidi.html
new file mode 100644
index 0000000..68f0bc3
--- /dev/null
+++ b/dojox/gfx/tests/_gfxBidiSupport/textpathBidi.html
@@ -0,0 +1,144 @@
+<html>
+	<head>
+		<title>Testing textpath</title>
+		<style type="text/css">
+			@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">
+
+			dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._gfxBidiSupport");
+
+			var CPD = 30, t, t2, t3,t4,t5;
+
+			var surface = null;
+
+			makeShapes = function(){
+				surfaceLTR = dojox.gfx.createSurface("testLTR", 500, 60);
+				console.debug("surfaceLTR created");
+				var p = surfaceLTR.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 50,  0)
+					;
+				console.debug("p created");
+				var t = surfaceLTR.createTextPath({
+						text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end."
+						, align: "start"
+						, textDir: "ltr"
+					})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("blue")
+					;
+				console.debug("t created");
+				var t2 = surfaceLTR.createTextPath({
+						text: "Beginning \u05e1\u05d5\u05e3."
+						, align: "start"
+						,textDir: "ltr"
+					})
+					.moveTo(0, 50)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("blue")
+					;
+				console.debug("t2 created");
+				surfaceRTL = dojox.gfx.createSurface("testRTL", 500, 60);
+				console.debug("surfaceRTL created");
+				var p2 = surfaceRTL.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					;
+				console.debug("p2 created");
+
+				var t3 = surfaceRTL.createTextPath({
+						text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+						, align: "start"
+						,textDir: "rtl"
+						//, rotated: true
+					})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("red")
+					;
+				console.debug("t3 created");
+				var t4 = surfaceRTL.createTextPath({
+						text: "Beginning \u05e1\u05d5\u05e3."
+						, align: "start"
+						,textDir: "rtl"
+						//, rotated: true
+					})
+					//.setShape(p.shape)
+					.moveTo(0, 50)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("red")
+					;				
+				console.debug("t4 created");
+				
+				surfaceAUTO = dojox.gfx.createSurface("testAUTO", 500, 60);
+				console.debug("surfaceAUTO created");
+				var p3 = surfaceAUTO.createPath({})
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 0,  0, 100,  0)
+					;
+				console.debug("p3 created");
+
+				var t5 = surfaceAUTO.createTextPath({
+						text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end. "
+						, align: "start"
+						, textDir: "auto"
+						//, rotated: true
+					})
+					//.setShape(p.shape)
+					.moveTo(0, 15)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+
+					.setFont({family: "times", size: "12pt"})
+					.setFill("red")
+					;
+				console.debug("t5 created");
+				var t6 = surfaceAUTO.createTextPath({
+						text: "Beginning \u05e1\u05d5\u05e3."
+						, align: "start"
+						, textDir: "auto"
+						//, rotated: true
+					})
+					//.setShape(p.shape)
+					.moveTo(0, 50)
+					.setAbsoluteMode(false)
+					.curveTo(CPD, 0, 100 - CPD,  0, 100,  0)
+					.setFont({family: "times", size: "12pt"})
+					.setFill("blue")
+					;				
+				console.debug("t6 created");
+			};
+
+			dojo.addOnLoad(makeShapes);
+
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx Text on a Path test</h1>
+		<h2>LTR Text Path</h2>
+		<div id="testLTR" style="width: 500px;"></div>
+		<h2>RTL Text Path</h2>
+		<div id="testRTL" style="width: 500px;"></div>
+		<h2>AUTO Text Path</h2>
+		<div id="testAUTO" style="width: 500px;"></div>
+
+	<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/events-canvas.html b/dojox/gfx/tests/events-canvas.html
new file mode 100644
index 0000000..3ec9369
--- /dev/null
+++ b/dojox/gfx/tests/events-canvas.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+	<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>
+		<script type="text/javascript">
+			
+			require([
+				"dojo/ready",
+				"dojo/dom",
+				"dojox/gfx",
+				"dojox/gfx/matrix"
+				],function(ready, dom, gfx, matrix){
+					var container = null, surface = null;
+					
+					ready(function(){
+						container = dom.byId("gfx_holder");
+						surface = gfx.createSurface(container, 600, 100);
+						
+						var g1 = surface.createGroup(), g2 = surface.createGroup();
+						
+						g1.setTransform(matrix.translate({x: 0,y: 0}));
+						g1.createRect({x: 0,y: 0,width: 220,height: 56,r: 12}).setFill("#212833");
+						g1.createImage({x: 0,y: 0,width: 215,height: 53,src: 'http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif'});
+						g1.connect("onclick", null, function(){alert('Thank you for choosing jQuery')});
+						
+						g2.setTransform(matrix.translate({x: 300,y: 0}));
+						g2.createPath("M0 -10l16 0").setStroke({color: 'red',width: 4});
+						g2.createRect({x: 0,y: 0,width: 220,height: 56,r: 12}).setFill("#212833");
+						g2.createImage({x: 0,y: 0,width: 123,height: 56,src: 'http://dojotoolkit.org/images/logo.png'});
+						g2.connect("onclick", null, function(){alert('Thank you for choosing dojo')});
+						
+					});
+				});
+		</script>
+	</head>
+	<body>
+		<h1>dojox.gfx: Canvas events bug (Canvas version)</h1>
+		<p>
+			Click on one of the image below. An alert should pop up displaying the chosen framework name.
+		</p>
+		<div id="gfx_holder" style="width: 600px; height: 100px;">
+		</div>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/smokeRenderer.html b/dojox/gfx/tests/smokeRenderer.html
new file mode 100644
index 0000000..951f841
--- /dev/null
+++ b/dojox/gfx/tests/smokeRenderer.html
@@ -0,0 +1,21 @@
+<html>
+<head>
+	<script type="text/javascript">
+		var dojoConfig= {
+			async:!!location.search
+		};
+	</script>
+	<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+	<script type="text/javascript">
+		require(["dojox/gfx", "dojo/domReady!"], function(gfx){
+			console.log(gfx);
+		});
+
+		require(["dojo", "dojo/domReady!"], function(dojo){
+			dojo.byId("status").innerHTML= "OK";
+		});
+	</script>
+</head>
+<body>
+	<div id="status">loading</div>
+</body>
diff --git a/dojox/gfx/tests/svgweb/sample.html b/dojox/gfx/tests/svgweb/sample.html
index b3350e8..2d4f493 100644
--- a/dojox/gfx/tests/svgweb/sample.html
+++ b/dojox/gfx/tests/svgweb/sample.html
@@ -7,19 +7,10 @@
 		<!-- 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="isDebug: true, forceGfxRenderer: 'svg'"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="async: true, isDebug: true, forceGfxRenderer: 'svg'"></script>
 
 		<script type="text/javascript">
-			dojo.require("dojox.gfx");
-			dojo.require("dojox.gfx.move");
-
-			dojo.addOnLoad(function() {
-				try {
-					testSurface();
-				} catch (ex) {
-					alert(ex);
-				}
-			});
+			require(["dojox/gfx", "dojox/gfx/move"], function(){
 			
 			function testSurface() {
 				var node = dojo.byId("surface");
@@ -161,6 +152,8 @@
 				}).setFill([0,0,255,0.5]);
 
 			}
+					testSurface();
+				});
 		</script>
 	</head>
 
@@ -168,4 +161,4 @@
 		<div id="surface" style="width:600;height:550;border:solid 1px">
 		</div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/dojox/gfx/tests/test.roundrect.html b/dojox/gfx/tests/test.roundrect.html
deleted file mode 100644
index 43ead48..0000000
--- a/dojox/gfx/tests/test.roundrect.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
-<head>
-<title>Testing rounded rectangle</title>
-<style type="text/css">
-	@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");
-
-createSurface = function(){
-	var surface = dojox.gfx.createSurface("test", 800, 600);
-	surface.whenLoaded(makeShapes);
-};
-
-makeShapes = function(surface){
-    var rect1 = surface.createRect({x: 100, y: 100, width: 300, height: 200, r: 50}).setFill("red").setStroke("black");
-	new dojox.gfx.Moveable(rect1);
-};
-
-dojo.addOnLoad(createSurface);
-
-</script>
-</head>
-<body>
-<h1>dojox.gfx Rounded rectangle</h1>
-<div id="test"></div>
-<p>That's all Folks!</p>
-</body>
-</html>
diff --git a/dojox/gfx/tests/test_arc.html b/dojox/gfx/tests/test_arc.html
index 3a96bf5..5bde56a 100644
--- a/dojox/gfx/tests/test_arc.html
+++ b/dojox/gfx/tests/test_arc.html
@@ -7,16 +7,11 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
 <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="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>
-<script type="text/javascript" src="../arc.js"></script>
-<!--<script type="text/javascript" src="../vml.js"></script>-->
-<!--<script type="text/javascript" src="../svg.js"></script>-->
-<!--<script type="text/javascript" src="../canvas.js"></script>-->
-<!--<script type="text/javascript" src="../silverlight.js"></script>-->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
+dojo.require("dojox.gfx.shape");
+dojo.require("dojox.gfx.path");
+dojo.require("dojox.gfx.arc");
 
 createSurface = function(){
 	var surface = dojox.gfx.createSurface("test", 500, 500);
diff --git a/dojox/gfx/tests/test_bezier.html b/dojox/gfx/tests/test_bezier.html
index 6d5d71a..a7ccab2 100644
--- a/dojox/gfx/tests/test_bezier.html
+++ b/dojox/gfx/tests/test_bezier.html
@@ -7,16 +7,11 @@
 </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="../_base.js"></script>
-<script type="text/javascript" src="../shape.js"></script>
-<script type="text/javascript" src="../path.js"></script>
-<script type="text/javascript" src="../arc.js"></script>
-<!--<script type="text/javascript" src="../vml.js"></script>-->
-<!--<script type="text/javascript" src="../svg.js"></script>-->
-<!--<script type="text/javascript" src="../canvas.js"></script>-->
-<!--<script type="text/javascript" src="../silverlight.js"></script>-->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
+dojo.require("dojox.gfx.shape");
+dojo.require("dojox.gfx.path");
+dojo.require("dojox.gfx.arc");
 
 createSurface = function(){
 	var surface = dojox.gfx.createSurface("test", 500, 500);
diff --git a/dojox/gfx/tests/test_bubbling.html b/dojox/gfx/tests/test_bubbling.html
new file mode 100644
index 0000000..b57d8fa
--- /dev/null
+++ b/dojox/gfx/tests/test_bubbling.html
@@ -0,0 +1,61 @@
+<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);
+	});
+	
+};
+
+dojo.addOnLoad(createSurface);
+
+</script>
+</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>
+</body>
+</html>
diff --git a/dojox/gfx/tests/test_canvaspolyline.html b/dojox/gfx/tests/test_canvaspolyline.html
new file mode 100644
index 0000000..e665801
--- /dev/null
+++ b/dojox/gfx/tests/test_canvaspolyline.html
@@ -0,0 +1,74 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Testing polyline points initialization</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="gfxRenderer:'canvas', isDebug: true"></script>
+<script type="text/javascript">
+dojo.require("dojox.gfx");
+dojo.require("dojox.gfx.shape");
+dojo.require("dojox.gfx.path");
+dojo.require("dojox.gfx.arc");
+
+createSurface = function(){
+	surface = dojox.gfx.createSurface("test", 500, 200);
+	surface.whenLoaded(makeShapes);
+};
+
+logBBox = function(shape, msg){
+	var bbox = shape.getBoundingBox(), t = shape.getTransform();
+	if (bbox)
+		surface.createText({
+			text:msg + " bbox: [" + bbox.x+","+bbox.y+","+bbox.width+","+bbox.height+"]",
+			align:"middle",
+			x:bbox.x+bbox.width/2,
+			y:bbox.y+bbox.height+20
+		}).setFill("black").setTransform(t);
+	else
+		dojo.byId("o1").innerHTML = msg + " bbox: null";
+	return bbox;	
+};
+
+makeShapes = function(surface){
+	var poly1 = surface.createPolyline([{x: 150, y: 50}, {x: 200, y: 100}, {x: 150, y: 150}, {x: 100, y: 100}, {x: 150, y: 50}])
+		.setStroke({color:"blue"})
+		,
+		bbox1 = logBBox(poly1,"Polyline1"); 
+	
+	var poly2 = surface.createPolyline([150, 50, 200, 100, 150, 150, 100, 100, 150, 50])
+		.setStroke({color:"blue"})
+		.setTransform(dojox.gfx.matrix.translate(200,0))
+		,
+		bbox2 = logBBox(poly2,"Polyline2"); 
+	
+	var poly3 = surface.createPolyline(),
+		bbox3 = logBBox(poly3,"Polyline3"); 
+	
+	var t =  bbox1.x === bbox2.x && 
+			 bbox1.y === bbox2.y &&
+			 bbox1.width === bbox2.width &&
+			 bbox1.height === bbox2.height;
+	var s;
+	if(t){
+		s = "OK";
+	}else{
+		s = "KO";
+		dojo.style("o3","color","red");
+	}
+	dojo.byId("o3").innerHTML = "Test Result : " + (t ? "OK" : "KO");
+};
+
+dojo.addOnLoad(createSurface);
+
+</script>
+</head>
+<body>
+<h1>dojox.gfx Polyline points initialization test </h1>
+<div id="test" style="width: 500px; height: 200px;"></div>
+<p id="o1"></p>
+<p id="o3" style="font-weight:bold"></p>
+</body>
+</html>
diff --git a/dojox/gfx/tests/test_decompose.html b/dojox/gfx/tests/test_decompose.html
index 6291cc2..5dc92af 100644
--- a/dojox/gfx/tests/test_decompose.html
+++ b/dojox/gfx/tests/test_decompose.html
@@ -7,9 +7,9 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
 <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
-<script type="text/javascript" src="../matrix.js"></script>
-<script type="text/javascript" src="../decompose.js"></script>
 <script type="text/javascript">
+dojo.require("dojox.gfx");
+dojo.require("dojox.gfx.matrix");
 dojo.require("dojox.gfx.decompose");
 
 var m = dojox.gfx.matrix;
diff --git a/dojox/gfx/tests/test_gfx.html b/dojox/gfx/tests/test_gfx.html
index e977dc4..8ffd140 100644
--- a/dojox/gfx/tests/test_gfx.html
+++ b/dojox/gfx/tests/test_gfx.html
@@ -12,17 +12,11 @@
 	</style>
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
-
-	<!-- for debuggin: -->
-	<!--<script type="text/javascript" src="../_base.js"></script>-->
-	<!--<script type="text/javascript" src="../path.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" src="../../../dojo/dojo.js" djConfig="async: true, isDebug: true"></script>
+
 	<script type="text/javascript">
 
-		dojo.require("dojox.gfx");
+		require(['dojox/gfx','dojo/domReady!'], function(gfx){
 
 		var gTestContainer = null;
 		var gTests = {};
@@ -108,7 +102,6 @@
 
 		var runTest = dojo.config.isDebug ? runTest_debug : runTest_nodebug;
 
-		dojo.addOnLoad(function(){
 			gTestContainer = dojo.byId('testcontainer');
 			var rect = { x: 0, y: 0, width: 100, height: 100 };
 
diff --git a/dojox/gfx/tests/test_gfx_amd.html b/dojox/gfx/tests/test_gfx_amd.html
new file mode 100644
index 0000000..c29ee6a
--- /dev/null
+++ b/dojox/gfx/tests/test_gfx_amd.html
@@ -0,0 +1,457 @@
+<html>
+<head>
+	<title>Dojo Unified 2D Graphics</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+	<!-- test styles -->
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../../../dijit/tests/css/dijitTests.css";
+		td { border: 1px solid black; text-align: left; vertical-align: top; }
+		v:group { text-align: left; }
+	</style>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="async: true, isDebug: true"></script>
+
+	<script type="text/javascript">
+
+		require(['dojox/gfx','dojox/gfx/matrix','dojo/domReady!'], function(Gfx, Matrix){
+
+		var gTestContainer = null;
+		var gTests = {};
+
+		function isEqual(foo, bar, prefix){
+		    var flag = true;
+		    if(foo != bar ){
+		        console.debug(prefix+":"+foo + "!=" + bar + " try dig into it" );
+		        if( foo instanceof Array ) {
+		            for( var i = 0; i< foo.length; i++ ) {
+		                flag = isEqual(foo[i], bar[i], prefix+"["+i+"]") && flag;
+		            }
+		            flag = false;
+		        } else {
+		            for(var x in foo) {
+		                if(bar[x] != undefined ) {
+		                    flag = isEqual(foo[x], bar[x], prefix+"."+x) && flag;
+		                } else {
+		                    console.debug(prefix+":"+ x + " is undefined in bar" );
+		                    flag = false;
+		                }
+		            }
+		        }
+		    }
+		    return flag;
+		}
+
+
+		function getTestSurface(testName, testDescription, width, height){
+		   width = width ? width : 300;
+		   height = height ? height : 300;
+
+		   // Create a DOM node for the surface
+		   var testRow = document.createElement('tr');
+		   var testCell = document.createElement('td');
+		   var testHolder = document.createElement('div');
+		   testHolder.id = testName + '_holder';
+		   testHolder.style.width  = width;
+		   testHolder.style.height = height;
+
+		   testCell.appendChild(testHolder);
+		   testRow.appendChild(testCell);
+		   gTestContainer.appendChild(testRow);
+
+		   var descRow = document.createElement('tr');
+		   var desc = document.createElement('td');
+		   desc.innerHTML = testDescription || testName;
+		   descRow.appendChild(desc);
+		   gTestContainer.appendChild(descRow);
+
+		   return Gfx.createSurface(testHolder, width, height);
+		}
+
+		function addTest(testName, fn){
+		   gTests[testName] = fn;
+		}
+
+		function runTest_nodebug(testName){
+		   try {
+		      var t = gTests[testName];
+		      if (!t) {
+		         return 'no test named ' + testName;
+		      }
+			  getTestSurface(testName).whenLoaded(function(surface){
+				t(testName, surface);
+			  });
+		      return null; // the success condition
+		   } catch (e) {
+		      return e.message;
+		   }
+		}
+
+		function runTest_debug(testName){
+		      var t = gTests[testName];
+		      if (!t) {
+		         return 'no test named ' + testName;
+		      }
+			  getTestSurface(testName).whenLoaded(function(surface){
+				t(testName, surface);
+			  });
+		      return null; // the success condition
+		}
+
+		var runTest = dojo.config.isDebug ? runTest_debug : runTest_nodebug;
+
+			gTestContainer = dojo.byId('testcontainer');
+			var rect = { x: 0, y: 0, width: 100, height: 100 };
+
+			addTest('rect', function(testName, surface){
+				var red_rect = surface.createRect(rect);
+				red_rect.setFill([255, 0, 0, 0.5]);
+				red_rect.setStroke({color: "blue", width: 10, join: "round" });
+				red_rect.setTransform({dx: 100, dy: 100});
+				//dojo.connect(red_rect.getNode(), "onclick", function(){ alert("red"); });
+				red_rect.connect("onclick", function(){ alert("red"); });
+			});
+
+			addTest('straight_rect', function(testName, surface){
+				var blue_rect = surface.createRect(rect).setFill([0, 255, 0, 0.5]).setTransform({ dx: 100, dy: 100 });
+				//dojo.connect( blue_rect.getNode(), "onclick", function(){ blue_rect.setShape({width: blue_rect.getShape().width + 20}); });
+				blue_rect.connect("onclick", function(){ blue_rect.setShape({width: blue_rect.getShape().width + 20}); });
+			});
+
+			addTest('rotated_rect', function(testName, surface){
+				console.debug('rotated_rect');
+				// anonymous 30 degree CCW rotated green rectangle
+				surface.createRect({r: 20})
+					.setFill([0, 0, 255, 0.5])
+					// rotate it around its center and move to (100, 100)
+					.setTransform([Matrix.translate(100, 100), Matrix.rotategAt(-30, 0, 0)])
+					;
+			});
+
+			addTest('skew_rect', function(testName, surface){
+				// anonymous red rectangle
+				surface.createRect(rect).setFill(new dojo.Color([255, 0, 0, 0.5]))
+					// skew it around LB point -30d, rotate it around LB point 30d, and move it to (100, 100)
+					.setTransform([Matrix.translate(100, 100), Matrix.rotategAt(-30, 0, 100), Matrix.skewXgAt(30, 0, 100)]);
+				// anonymous blue rectangle
+				surface.createRect(rect).setFill(new dojo.Color([0, 0, 255, 0.5]))
+					// skew it around LB point -30d, and move it to (100, 100)
+					.setTransform([Matrix.translate(100, 100), Matrix.skewXgAt(30, 0, 100)]);
+				// anonymous yellow rectangle
+				surface.createRect(rect).setFill(new dojo.Color([255, 255, 0, 0.25]))
+					// move it to (100, 100)
+					.setTransform(Matrix.translate(100, 100));
+			});
+
+			addTest('matrix_rect', function(testName, surface){
+				var group = surface.createGroup();
+		
+				var blue_rect = group.createRect(rect).setFill([0, 0, 255, 0.5]).applyTransform(Matrix.identity);
+				console.debug( "blue_rect: rect with identity" );
+
+				group.createRect(rect).setFill([0, 255, 0, 0.5]).applyTransform(Matrix.translate(30, 40));
+				console.debug( "lime_rect: translate(30,40) " );
+		
+				group.createRect(rect).setFill([255, 0, 0, 0.5]).applyTransform(Matrix.rotateg(-30));
+				console.debug( "red_rect: rotate 30 degree counterclockwise " );
+
+				group.createRect(rect).setFill([0, 255, 255, 0.5])
+					.applyTransform(Matrix.scale({x:1.5, y:0.5}))
+					.applyTransform(Matrix.translate(-40, 220))
+					;
+				console.debug( "lightblue_rect: scale(1.5, 0.5)" );
+
+				group.createRect(rect).setFill([0, 0, 255, 0.5]).setFill([255, 0, 255, 0.5]).applyTransform(Matrix.flipX);
+				console.debug( "pink_rect: flipX" );
+
+				group.createRect(rect).setFill([0, 0, 255, 0.5]).setFill([255, 255, 0, 0.5]).applyTransform(Matrix.flipY);
+				console.debug( "yellow_rect: flipY" );
+
+				group.createRect(rect).setFill([0, 0, 255, 0.5]).setFill([128, 0, 128, 0.5]).applyTransform(Matrix.flipXY);
+				console.debug( "purple_rect: flipXY" );
+
+				group.createRect(rect).setFill([0, 0, 255, 0.5]).setFill([255, 128, 0, 0.5]).applyTransform(Matrix.skewXg(-15));
+				console.debug( "purple_rect: skewXg 15 degree" );
+
+				group.createRect(rect).setFill([0, 0, 255, 0.5]).setFill([0, 0, 0, 0.5]).applyTransform(Matrix.skewYg(-50));
+				console.debug( "black_rect: skewXg 50 degree" );
+
+				// move
+				group
+					.setTransform({ xx: 1.5, yy: 0.5, dx: 100, dy: 100 })
+					.applyTransform(Matrix.rotateg(-30))
+					;
+			});
+
+			addTest('attach', function(testName, surface){
+				var red_rect = surface.createRect(rect)
+					.setShape({ width: 75 })
+					.setFill([255, 0, 0, 0.5])
+					.setStroke({ color: "blue", width: 1 })
+					.setTransform({ dx: 50, dy: 50, xx: 1, xy: 0.5, yx: 0.7, yy: 1.1 })
+					;
+
+				console.debug("attaching !");
+				// now attach it!
+				var ar = Gfx.attachNode(red_rect.rawNode);
+				console.assert( ar.rawNode == red_rect.rawNode );
+
+				// FIXME: more generic method to compare two dictionary?
+				console.debug("attach shape: ");
+				isEqual(ar.shape, red_rect.shape, "rect.shape");
+				console.debug("attach matrix: ");
+				isEqual(ar.matrix, red_rect.matrix, "rect.matrix");
+				console.debug("attach strokeStyle: ");
+				isEqual(ar.strokeStyle, red_rect.strokeStyle, "rect.strokeStyle");
+				console.debug("attach fillStyle: ");
+				isEqual(ar.fillStyle, red_rect.fillStyle, "rect.fillStyle");
+			});
+	
+			// test circle
+			addTest('circle', function(testName, surface){
+				var circle = { cx: 130, cy: 130, r: 50 };
+				surface.createCircle(circle).setFill([0, 255, 0, 0.5]).setTransform({ dx: 20, dy: 20 });
+			});
+
+			// test line
+			addTest('line', function(testName, surface){
+				var line = { x1: 20, y1: 20, x2: 100, y2: 120 };
+				surface.createLine(line).setFill([255, 0, 0, 0.5]).setStroke({color: "red", width: 1}).setTransform({ dx:70, dy: 100 });
+			});
+
+			// test ellipse 
+			addTest('ellipse', function(testName, surface){
+				var ellipse = { cx: 50, cy: 80, rx: 50, ry: 80 };
+				surface.createEllipse(ellipse).setFill([0, 255, 255, 0.5]).setTransform({ dx: 30, dy: 70 });
+			});
+
+			// test polyline
+			addTest('polyline', function(testName, surface){
+				var points = [ {x: 10, y: 20}, {x: 40, y: 70}, {x: 120, y: 50}, {x: 90, y: 90} ];
+				surface.createPolyline(points).setFill(null).setStroke({ color: "blue", width: 1 }).setTransform({ dx: 15, dy: 0 });
+			});
+
+			// test polygon
+			addTest('polygon', function(testName, surface){
+				var points2 = [{x: 100, y: 0}, {x: 200, y: 40}, {x: 180, y: 150}, {x: 60, y: 170}, {x: 20, y: 100}];
+				surface.createPolyline(points2).setFill([0, 128, 255, 0.6]).setTransform({dx:30, dy: 20});
+			});
+
+			// test path: lineTo, moveTo, closePath
+			addTest('lineTo', function(testName, surface){
+				surface.createPath()
+					.moveTo(10, 20).lineTo(80, 150)
+					.setAbsoluteMode(false).lineTo(40, 0)
+					.setAbsoluteMode(true).lineTo(180, 100)
+					.setAbsoluteMode(false).lineTo(0, -30).lineTo(-30, -50)
+					.closePath()
+					.setStroke({ color: "red", width: 1 })
+					.setFill(null)
+					.setTransform({ dx: 10, dy: 18 })
+					;
+			});
+
+			addTest('setPath', function(testName, surface){
+				surface.createPath()
+					.moveTo(10, 20).lineTo(80, 150)
+					.setAbsoluteMode(false).lineTo(40,0)
+					.setAbsoluteMode(true).lineTo(180, 100)
+					.setAbsoluteMode(false).lineTo(0, -30).lineTo(-30, -50)
+					.curveTo(10, -80, -150, -10, -90, -10)
+					.closePath()
+					.setStroke({ color: "red", width: 1 })
+					.setFill(null)
+					.setTransform({ dx: 10, dy: 58 })
+					;
+
+				surface.createPath({ path: "M10,20 L80,150 l40,0 L180,100 l0,-30 l-30,-50 c10,-80 -150,-10 -90,-10 z" })
+					.setFill(null)
+					.setStroke({ color: "blue", width: 1 })
+					.setTransform({ dx: 50, dy: 78 })
+					;
+			});
+
+			// test arcTo 
+			addTest('arcTo', function(testName, surface){
+				var m = Matrix;
+				var g1 = surface.createGroup();
+				var g2 = g1.createGroup();
+
+				var rx = 100, ry = 60, xRotg = 30;
+				var startPoint = m.multiplyPoint(m.rotateg(xRotg), {x: -rx, y: 0  });
+				var endPoint   = m.multiplyPoint(m.rotateg(xRotg), {x: 0,   y: -ry});
+	    
+				var re1 = g1.createPath()
+					.moveTo(startPoint)
+					.arcTo(rx, ry, xRotg, true, false, endPoint)
+					.setStroke({color: "red"})
+					;
+				var ge1 = g1.createPath()
+					.moveTo(re1.getLastPosition())
+					.arcTo(rx, ry, xRotg, false, false, startPoint)
+					.setStroke({color: "blue"})
+					;
+				var re2 = g2.createPath()
+					.moveTo(startPoint)
+					.arcTo(rx, ry, xRotg, false, true, endPoint)
+					.setStroke({color: "red"})
+					;
+				var ge2 = g2.createPath()
+					.moveTo(re2.getLastPosition())
+					.arcTo(rx, ry, xRotg, true, true, startPoint)
+					.setStroke({color: "blue"})
+					;
+			
+				g1.setTransform({dx: 150, dy: 150});
+				g2.setTransform({dx: 10,  dy: 10});
+			});
+
+			// test path: curveTo, smoothCurveTo
+			addTest('curveTo', function(testName, surface) {
+				surface.createPath()
+					.moveTo(10, 20).curveTo(50, 50, 50, 100, 150, 100).smoothCurveTo(300, 300, 200, 200)
+					.setStroke({ color: "green", width: 1 }).setFill(null).setTransform({ dx: 10, dy: 30 })
+					;
+			});
+
+			// test path: curveTo, smoothCurveTo with relative.
+			addTest('curveTo2', function(testName, surface) {
+				surface.createPath()
+					.moveTo(10, 20).curveTo(50, 50, 50, 100, 150, 100)
+					.setAbsoluteMode(false).smoothCurveTo(150, 200, 50, 100)
+					.setAbsoluteMode(true).smoothCurveTo(50, 100, 10, 230)
+					.setStroke({ color: "green", width: 1 }).setFill(null).setTransform({ dx: 10, dy: 30 })
+					;
+			});
+
+			// test path: curveTo, smoothCurveTo with relative.
+			addTest('qCurveTo', function(testName, surface) {
+				surface.createPath()
+					.moveTo(10, 15).qCurveTo(50, 50, 100, 100).qSmoothCurveTo(150, 20)
+					.setStroke({ color: "green", width: 1 }).setFill(null).setTransform({ dx: 10, dy: 30 })
+					;
+			});
+
+			addTest('qCurveTo2', function(testName, surface) {
+				surface.createPath()
+					.moveTo(10, 20).qCurveTo(50, 50, 100, 100)
+					.setAbsoluteMode(false).qSmoothCurveTo(50, -80)
+					.setAbsoluteMode(true).qSmoothCurveTo(200, 80)
+					.setStroke({ color: "green", width: 1 }).setFill(null).setTransform({ dx: 10, dy: 30 })
+					;
+			});
+
+			// test defines, linearGradient
+			addTest('linearGradient', function(testName, surface) {
+				// this is an example to split the linearGradient from setFill:
+				var lg = {
+					type: "linear",
+					x1: 0, y1: 0, x2: 75, y2: 50,
+					colors: [
+						{ offset: 0, color: "#F60" },
+						{ offset: 1, color: "#FF6" }
+					]
+				};
+				surface.createRect(rect).setFill(lg).setTransform({ dx: 40, dy: 100 });
+			});
+
+			// TODO: test radialGradient
+			addTest('radialGradient', function(testName, surface) {
+				// this is a total inline implementation compared with previous one.
+				var rg = {
+					type: "radial",
+					cx: 100, cy: 100, r: 100,
+					colors: [
+						{ offset:   0, color: "red" },
+						{ offset: 0.5, color: "green" },
+						{ offset:   1, color: "blue" }
+					]
+				};
+		
+				surface.createCircle({cx: 100, cy: 100, r: 100})
+					.setStroke({})
+					.setFill(rg)
+					.setTransform({dx: 40, dy: 30})
+					;
+		//		surface.createRect(rect)
+		//			.setShape({width: 200})
+		//			.setStroke({})
+		//			.setFill(rg)
+		//			.setTransform({dx: 40, dy: 30})
+		//			;
+			});
+
+			addTest('attach_gradient', function(testName, surface) {
+				// this is an example to split the linearGradient from setFill:
+				var lg = {
+					type: "linear",
+					x1: 0, y1: 0, x2: 75, y2: 50,
+					colors: [
+						{ offset:   0, color: "#F60" },
+						{ offset: 0.5, color: "#FAF" },
+						{ offset:   1, color: "#FF6" }
+					]
+				};
+
+				var lgr = surface.createRect(rect).setFill(lg).setTransform({ dx: 40, dy: 100 });
+
+				var ar = Gfx.attachNode(lgr.rawNode);
+				// FIXME: more generic method to compare two dictionary?
+				console.debug("attach_gradient!");
+
+				console.debug("attach shape: ");
+				isEqual(lgr.shape, ar.shape, "rect.shape");
+				console.debug("attach matrix: ");
+				isEqual(lgr.matrix, ar.matrix, "rect.matrix");
+				console.debug("attach strokeStyle: ");
+				isEqual(lgr.strokeStyle, ar.strokeStyle, "rect.strokeStyle");
+				console.debug("attach fillStyle: ");
+				isEqual(lgr.fillStyle.gradient, ar.fillStyle.gradient, "rect.fillStyle.gradient");
+				//isEqual(lgr.fillStyle.id, ar.fillStyle.id, "rect.fillStyle.id");
+			});
+
+			var gTestsToRun = [
+				'rect',
+				'straight_rect',
+				'rotated_rect',
+				'skew_rect',
+				'matrix_rect', 
+				//'attach',
+				//'attach_gradient',
+				'circle',
+				'arcTo',
+				'line',
+				'ellipse',
+				'polyline',
+				'polygon',
+				'lineTo',
+				'setPath',
+				'curveTo',
+				'curveTo2',
+				'qCurveTo',
+				'qCurveTo2',
+				'linearGradient',
+				'radialGradient'
+			];
+
+			for (var i = 0; i < gTestsToRun.length; ++i) {
+				var testName = gTestsToRun[i];
+				var err = runTest(testName);
+				if (err) {
+					getTestSurface(testName, testName + ' FAILED (' + err + ')');
+				}
+			}
+
+		}); // end onload
+		</script>
+</head>
+<body>
+	<h1 class="testTitle">Test Graphics API</h1>
+		<table>
+			<tbody id="testcontainer">
+			</tbody>
+		</table>
+</body>
+</html>
diff --git a/dojox/gfx/tests/test_group2.html b/dojox/gfx/tests/test_group2.html
index 0adc7b8..c2fc153 100644
--- a/dojox/gfx/tests/test_group2.html
+++ b/dojox/gfx/tests/test_group2.html
@@ -28,7 +28,8 @@ flip = function(){
 			surface.add(shape);
 		}
 	}else{
-		surface.remove(shape);
+		surface.clear(); // Shapes removed from the surface can now be added back to it.
+		//surface.remove(shape);
 	}
 }
 
diff --git a/dojox/gfx/tests/test_linearGradient.html b/dojox/gfx/tests/test_linearGradient.html
index 4f08fa7..bb81eac 100644
--- a/dojox/gfx/tests/test_linearGradient.html
+++ b/dojox/gfx/tests/test_linearGradient.html
@@ -8,18 +8,13 @@
 </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/_base/Color.js"></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>
-<script type="text/javascript" src="../arc.js"></script>
-<!--<script type="text/javascript" src="../vml.js"></script>-->
-<!--<script type="text/javascript" src="../svg.js"></script>-->
-<!--<script type="text/javascript" src="../canvas.js"></script>-->
-<!--<script type="text/javascript" src="../silverlight.js"></script>-->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 dojo.require("dojo.colors");
+dojo.require("dojox.gfx");
+dojo.require("dojox.gfx.shape");
+dojo.require("dojox.gfx.path");
+dojo.require("dojox.gfx.arc");
 
 createSurface = function(){
 	var surface = dojox.gfx.createSurface("grad", 300, 300);
diff --git a/dojox/gfx/tests/test_loadCanvas.html b/dojox/gfx/tests/test_loadCanvas.html
new file mode 100644
index 0000000..ab9f310
--- /dev/null
+++ b/dojox/gfx/tests/test_loadCanvas.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"	"http://www.w3.org/TR/html4/strict.dtd">
+<head>
+<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">
+	window.onerror = function(){
+		document.writeln("Test has failed: canvas.js cannot be loaded.");
+	}
+	require(["dojox/gfx/canvas", "dojo/ready"], function(canvas,ready){
+		ready(function(){
+			dojox.gfx.switchTo("canvas");
+			dojo.byId("test").innerHTML = "Test is successful.";
+		});
+	});
+	
+</script>
+</head>
+<body>
+<h1>Test canvas.js loading under IE7/8 (Ticket 14288)</h1>
+<p>The purpose of this test is to check whether loading canvas.js breaks under IE7/8. This may happen
+when a custom dojo layer that includes gfx is built. In this case, the canvas.js code is included in
+the layer, therefore loaded.
+</p>
+<div id="test" style="width: 500px; height: 500px;font-weight:bold;"></div>
+</body>
+</html>
diff --git a/dojox/gfx/tests/test_poly.html b/dojox/gfx/tests/test_poly.html
index eeb1060..8b6d7c4 100644
--- a/dojox/gfx/tests/test_poly.html
+++ b/dojox/gfx/tests/test_poly.html
@@ -7,16 +7,11 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
 <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="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>
-<script type="text/javascript" src="../arc.js"></script>
-<!--<script type="text/javascript" src="../vml.js"></script>-->
-<!--<script type="text/javascript" src="../svg.js"></script>-->
-<!--<script type="text/javascript" src="../canvas.js"></script>-->
-<!--<script type="text/javascript" src="../silverlight.js"></script>-->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
+dojo.require("dojox.gfx.shape");
+dojo.require("dojox.gfx.path");
+dojo.require("dojox.gfx.arc");
 
 createSurface = function(){
 	var surface = dojox.gfx.createSurface("test", 500, 500);
diff --git a/dojox/gfx/tests/test_rect_setShape_vml.html b/dojox/gfx/tests/test_rect_setShape_vml.html
new file mode 100644
index 0000000..1ccf201
--- /dev/null
+++ b/dojox/gfx/tests/test_rect_setShape_vml.html
@@ -0,0 +1,37 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Test rect with mixed width/height percentage/px values</title>
+<style type="text/css">
+	@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");
+
+createSurface = function(){
+	var surface = dojox.gfx.createSurface("test", 800, 600);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(surface){
+    surface.createRect({x: 10, y: 10, width: "100%", height: 100}).setFill("red").setStroke("black");
+    surface.createRect({x: 10, y: 130, width: 100, height: "100%"}).setFill("red").setStroke("black");
+};
+
+dojo.addOnLoad(createSurface);
+
+</script>
+</head>
+<body>
+<h1>[12558] Test rect with mixed width/height percentage/px values</h1>
+<div id="test"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/dojox/gfx/tests/test_registry.html b/dojox/gfx/tests/test_registry.html
new file mode 100644
index 0000000..78cf5d6
--- /dev/null
+++ b/dojox/gfx/tests/test_registry.html
@@ -0,0 +1,89 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>GFX Test: Test the shape registry</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" djConfig="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");
+		</script>
+		<script type="text/javascript">
+			dojo.addOnLoad(function(){
+				var drawing;
+				var ta;
+				doh.register("GFX: Registry Tests", [
+					{
+						name: "dojox.gfx.shape.register",
+						timeout: 1000,
+						runTest: function(t){
+							var obj = {
+								declaredClass: 'module.sub.foo'
+							};
+							// register
+							var id = dojox.gfx.shape.register(obj);
+							t.t(dojo.isString(id) && id.length>0, "checking register() return value.");
+							var ret = dojox.gfx.shape.byId(id);
+							t.t(ret === obj, "Checking byId() after register().");
+							var obj2 = {declaredClass: 'module.sub.foo'};
+							var ret2 = dojox.gfx.shape.register(obj2);
+							t.t(dojo.isString(ret2) && ret2.length>0, "checking register() with same declaredClass.");
+							t.t(ret2 != id, "checking _uid unicity.");
+							//dispose
+							obj.getUID =function(){return id;};
+							dojox.gfx.shape.dispose(obj);
+							ret = dojox.gfx.shape.byId(id);
+							t.t(!ret, "Checking dojox.gfx.shape.dispose().");							
+						}
+					},
+					{
+						name: "shape registration",
+						timeout: 1000,
+						setUp: function(){
+							if (!drawing) {
+								var dn = dojo.byId("gfxObject");
+								drawing = dojox.gfx.createSurface(dn, 300, 300);
+							}
+						},
+						runTest: function(t){
+							var dic={};
+							dojo.forEach(["Group", "Rect", "Ellipse", "Circle", "Line", "Polyline", "Image", "Text", "Path", "TextPath"], function(name, idx, values){
+								// no TextPath in Silverlight
+								if (idx == values.length-1 && dojox.gfx.renderer=='silverlight')
+									return;
+								var s = drawing["create"+name]();
+								t.t(s.getUID() && s.getUID().length>0,"Checking automatic shape registration for "+name);
+								var o = dojox.gfx.shape.byId(s.getUID());
+								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.");
+								dic[name] = s.getUID();
+							});
+							// successive registration
+							dojo.forEach(["Group", "Rect", "Ellipse", "Circle", "Line", "Polyline", "Image", "Text", "Path", "TextPath"], function(name, idx, values){
+								// no TextPath in Silverlight
+								if (idx == values.length-1 && dojox.gfx.renderer=='silverlight')
+									return;
+								var s = drawing["create"+name]();
+								var id = s.getUID();
+								t.t(dic[name] != id, "Checking unicity.");
+							});
+						}
+					}
+				]);
+				doh.run();
+			});
+			</script>
+	</head>
+	<body class="tundra">
+		<h1>Test of GFX registry functions</h1>
+		<div id="gfxObject"></div>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/test_resize.html b/dojox/gfx/tests/test_resize.html
index 75cc236..4c02dda 100644
--- a/dojox/gfx/tests/test_resize.html
+++ b/dojox/gfx/tests/test_resize.html
@@ -7,16 +7,11 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
 <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="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>
-<script type="text/javascript" src="../arc.js"></script>
-<!--<script type="text/javascript" src="../vml.js"></script>-->
-<!--<script type="text/javascript" src="../svg.js"></script>-->
-<!--<script type="text/javascript" src="../canvas.js"></script>-->
-<!--<script type="text/javascript" src="../silverlight.js"></script>-->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
+dojo.require("dojox.gfx.shape");
+dojo.require("dojox.gfx.path");
+dojo.require("dojox.gfx.arc");
 
 var surface;
 
diff --git a/dojox/gfx/tests/test_roundrect.html b/dojox/gfx/tests/test_roundrect.html
new file mode 100644
index 0000000..37c9086
--- /dev/null
+++ b/dojox/gfx/tests/test_roundrect.html
@@ -0,0 +1,36 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<head>
+<title>Testing rounded rectangle</title>
+<style type="text/css">
+	@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">
+dojo.require("dojox.gfx");
+dojo.require("dojox.gfx.move");
+dojo.require("dojo.colors");
+
+createSurface = function(){
+	var surface = dojox.gfx.createSurface("test", 800, 600);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(surface){
+    rect1 = surface.createRect({x: 20, y: 100, width: 300, height: 200, r: 50}).setFill("red").setStroke("black");
+	new dojox.gfx.Moveable(rect1);
+    rect1 = surface.createRect({x: 0, y: 100, width: 300, height: 200, r: 50}).setFill("red").setStroke("black").setTransform(dojox.gfx.matrix.translate(350,0)).setShape({r:0});
+};
+
+dojo.addOnLoad(createSurface);
+
+</script>
+</head>
+<body>
+<h1>dojox.gfx Rounded rectangle</h1>
+The test should display 2 rectangles: the left one with round corners (radius=50), the right one with square corners (radius=0).
+<div id="test"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/dojox/gfx/tests/test_setPath.html b/dojox/gfx/tests/test_setPath.html
index 45edc95..7d32f80 100644
--- a/dojox/gfx/tests/test_setPath.html
+++ b/dojox/gfx/tests/test_setPath.html
@@ -8,10 +8,6 @@
 	li {font-weight: bold;}
 </style>
 <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
-<!--<script type="text/javascript" src="../path.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");
 
diff --git a/dojox/gfx/tests/test_surfaceClip.html b/dojox/gfx/tests/test_surfaceClip.html
new file mode 100644
index 0000000..98cedea
--- /dev/null
+++ b/dojox/gfx/tests/test_surfaceClip.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
+<head>
+	<title>Testing clipping on surface</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" djConfig="isDebug: true"></script>
+	<script>
+		dojo.require("dojox.gfx");
+
+		createSurface = function(){
+			var surface = dojox.gfx.createSurface("test", 200, 200);
+			surface.whenLoaded(makeShapes);
+		};
+
+		makeShapes = function(surface){
+			surface.createRect({width: 200, height: 200}).setStroke("black");
+			surface.createRect({x: 150, y: 10, width: 300, height: 300}).setFill("red");
+		};
+
+		dojo.addOnLoad(createSurface);
+	</script>
+</head>
+<body>
+	<h1>Testing clipping on surface</h1>
+	<!--<p><button onclick="createSurface();">Go</button></p>-->
+	<div id="test"></div>
+	<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/dojox/gfx/tests/test_tbbox.html b/dojox/gfx/tests/test_tbbox.html
index 4b85e39..e50ab57 100644
--- a/dojox/gfx/tests/test_tbbox.html
+++ b/dojox/gfx/tests/test_tbbox.html
@@ -7,16 +7,11 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
 <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="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>
-<script type="text/javascript" src="../arc.js"></script>
-<!--<script type="text/javascript" src="../vml.js"></script>-->
-<!--<script type="text/javascript" src="../svg.js"></script>-->
-<!--<script type="text/javascript" src="../canvas.js"></script>-->
-<!--<script type="text/javascript" src="../silverlight.js"></script>-->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
+dojo.require("dojox.gfx.shape");
+dojo.require("dojox.gfx.path");
+dojo.require("dojox.gfx.arc");
 
 createSurface = function(){
 	var surface = dojox.gfx.createSurface("test", 500, 500);
diff --git a/dojox/gfx/tests/test_utils.html b/dojox/gfx/tests/test_utils.html
index 02d4c9d..5d4dbca 100755
--- a/dojox/gfx/tests/test_utils.html
+++ b/dojox/gfx/tests/test_utils.html
@@ -32,6 +32,7 @@
 									 x: 100,
 									 y: 100
 								}).setFill("blue").setStroke("black");
+								drawing.createImage({width:200,height:200,src:'http://demos.dojotoolkit.org/demos/resources/images/no_thumb.gif'});
 							}
 							if(!ta){
 								ta = dojo.byId("outputArea");
@@ -69,6 +70,7 @@
 									 x: 100,
 									 y: 100
 								}).setFill("blue").setStroke("black");
+								drawing.createImage({width:200,height:200,src:'http://demos.dojotoolkit.org/demos/resources/images/no_thumb.gif'});
 							}
 							if(!ta){
 								ta = dojo.byId("outputArea");
@@ -112,6 +114,7 @@
 									 x: 100,
 									 y: 100
 								}).setFill("blue").setStroke("black");
+								drawing.createImage({width:200,height:200,src:'http://demos.dojotoolkit.org/demos/resources/images/no_thumb.gif'});
 							}
 							if(!ta){
 								ta = dojo.byId("outputArea");
@@ -125,7 +128,12 @@
 									doh.assertTrue(svg != null, "Checking that non-null was returned.");
 									ta.value = svg;
 									doh.assertTrue(svg.length > 0, "Checking that svg length > 0");
-									doh.assertTrue(svg.toLowerCase().indexOf("<svg") === 0, "Checking that the string starts with SVG open tag.");
+									var low = svg.toLowerCase();
+									doh.assertTrue(low.indexOf("<svg") === 0, "Checking that the string starts with SVG open tag.");
+									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(svg.indexOf("__gfxObject__") === -1, "Checking __gfxObject__ attribute cleanup.");
 									d.callback(true);
 								}catch(e){
 									d.errback(e);
diff --git a/dojox/gfx/utils.js b/dojox/gfx/utils.js
index b6f5c00..c916355 100644
--- a/dojox/gfx/utils.js
+++ b/dojox/gfx/utils.js
@@ -1,30 +1,38 @@
-dojo.provide("dojox.gfx.utils");
+define(["dojo/_base/kernel","dojo/_base/lang","./_base", "dojo/_base/html","dojo/_base/array", "dojo/_base/window", "dojo/_base/json", 
+	"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; =====*/
 
-dojo.require("dojox.gfx");
-
-(function(){
-	var d = dojo, g = dojox.gfx, gu = g.utils;
-
-	dojo.mixin(gu, {
+	lang.mixin(gu, {
 		forEach: function(
-			/* dojox.gfx.Surface || dojox.gfx.Shape */ object,
+			/*dojox.gfx.Surface|dojox.gfx.Shape*/ object,
 			/*Function|String|Array*/ f, /*Object?*/ o
 		){
-			o = o || d.global;
+			// 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 
+			//		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;
 			f.call(o, object);
 			if(object instanceof g.Surface || object instanceof g.Group){
-				d.forEach(object.children, function(shape){
+				arr.forEach(object.children, function(shape){
 					gu.forEach(shape, f, o);
 				});
 			}
 		},
 
 		serialize: function(
-			/* dojox.gfx.Surface || dojox.gfx.Shape */ object
+			/* dojox.gfx.Surface|dojox.gfx.Shape */ object
 		){
+			// summary:
+			//		Takes a shape or a surface and returns a DOM object, which describes underlying shapes.
 			var t = {}, v, isSurface = object instanceof g.Surface;
 			if(isSurface || object instanceof g.Group){
-				t.children = d.map(object.children, gu.serialize);
+				t.children = arr.map(object.children, gu.serialize);
 				if(isSurface){
 					return t.children;	// Array
 				}
@@ -51,18 +59,22 @@ dojo.require("dojox.gfx");
 		},
 
 		toJson: function(
-			/* dojox.gfx.Surface || dojox.gfx.Shape */ object,
+			/* dojox.gfx.Surface|dojox.gfx.Shape */ object,
 			/* Boolean? */ prettyPrint
 		){
-			return d.toJson(gu.serialize(object), prettyPrint);	// String
+			// 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.
+			return jsonLib.toJson(gu.serialize(object), prettyPrint);	// String
 		},
 
 		deserialize: function(
-			/* dojox.gfx.Surface || dojox.gfx.Shape */ parent,
-			/* dojox.gfx.Shape || Array */ object
+			/* dojox.gfx.Surface|dojox.gfx.Shape */ parent,
+			/* dojox.gfx.Shape|Array */ object
 		){
+			// summary:
+			//		Takes a surface or a shape and populates it with an object produced by serialize().
 			if(object instanceof Array){
-				return d.map(object, d.hitch(null, gu.deserialize, parent));	// Array
+				return arr.map(object, lang.hitch(null, gu.deserialize, parent));	// Array
 			}
 			var shape = ("shape" in object) ? parent.createShape(object.shape) : parent.createGroup();
 			if("transform" in object){
@@ -78,15 +90,17 @@ dojo.require("dojox.gfx");
 				shape.setFont(object.font);
 			}
 			if("children" in object){
-				d.forEach(object.children, d.hitch(null, gu.deserialize, shape));
+				arr.forEach(object.children, lang.hitch(null, gu.deserialize, shape));
 			}
 			return shape;	// dojox.gfx.Shape
 		},
 
 		fromJson: function(
-			/* dojox.gfx.Surface || dojox.gfx.Shape */ parent,
+			/* dojox.gfx.Surface|dojox.gfx.Shape */ parent,
 			/* String */ json){
-			return gu.deserialize(parent, d.fromJson(json));	// Array || dojox.gfx.Shape
+			// summary:
+			//		Works just like deserialize() but takes a JSON representation of the object.
+			return gu.deserialize(parent, jsonLib.fromJson(json));	// Array || dojox.gfx.Shape
 		},
 
 		toSvg: function(/*GFX object*/surface){
@@ -105,9 +119,9 @@ dojo.require("dojox.gfx");
 		
 			//Since the init and even surface creation can be async, we need to
 			//return a deferred that will be called when content has serialized.
-			var deferred = new dojo.Deferred();
+			var deferred = new Deferred();
 		
-			if(dojox.gfx.renderer === "svg"){
+			if(g.renderer === "svg"){
 				//If we're already in SVG mode, this is easy and quick.
 				try{
 					var svg = gu._cleanSvg(gu._innerXML(surface.rawNode));
@@ -121,7 +135,7 @@ dojo.require("dojox.gfx");
 				if (!gu._initSvgSerializerDeferred) {
 					gu._initSvgSerializer();
 				}
-				var jsonForm = dojox.gfx.utils.toJson(surface);
+				var jsonForm = gu.toJson(surface);
 				var serializer = function(){
 					try{
 						var sDim = surface.getDimensions();
@@ -132,9 +146,9 @@ dojo.require("dojox.gfx");
 						var node = gu._gfxSvgProxy.document.createElement("div");
 						gu._gfxSvgProxy.document.body.appendChild(node);
 						//Set the node scaling.
-						dojo.withDoc(gu._gfxSvgProxy.document, function() {
-							dojo.style(node, "width", width);
-							dojo.style(node, "height", height);
+						win.withDoc(gu._gfxSvgProxy.document, function() {
+							html.style(node, "width", width);
+							html.style(node, "height", height);
 						}, this);
 
 						//Create temp surface to render object to and render.
@@ -193,9 +207,9 @@ dojo.require("dojox.gfx");
 			// tags:
 			//		private
 			if(!gu._initSvgSerializerDeferred){
-				gu._initSvgSerializerDeferred = new dojo.Deferred();
-				var f = dojo.doc.createElement("iframe");
-				dojo.style(f, {
+				gu._initSvgSerializerDeferred = new Deferred();
+				var f = win.doc.createElement("iframe");
+				html.style(f, {
 					display: "none",
 					position: "absolute",
 					width: "1em",
@@ -203,17 +217,17 @@ dojo.require("dojox.gfx");
 					top: "-10000px"
 				});
 				var intv;
-				if(dojo.isIE){
+				if(has("ie")){
 					f.onreadystatechange = function(){
 						if(f.contentWindow.document.readyState == "complete"){
 							f.onreadystatechange = function() {};
 							intv = setInterval(function() {
-								if(f.contentWindow[dojo._scopeName] &&
-								   f.contentWindow[dojox._scopeName].gfx &&
-								   f.contentWindow[dojox._scopeName].gfx.utils){
+								if(f.contentWindow[kernel.scopeMap["dojo"][1]._scopeName] &&
+								   f.contentWindow[kernel.scopeMap["dojox"][1]._scopeName].gfx &&
+								   f.contentWindow[kernel.scopeMap["dojox"][1]._scopeName].gfx.utils){
 									clearInterval(intv);
-									f.contentWindow.parent[dojox._scopeName].gfx.utils._gfxSvgProxy = f.contentWindow;
-									f.contentWindow.parent[dojox._scopeName].gfx.utils._svgSerializerInitialized();
+									f.contentWindow.parent[kernel.scopeMap["dojox"][1]._scopeName].gfx.utils._gfxSvgProxy = f.contentWindow;
+									f.contentWindow.parent[kernel.scopeMap["dojox"][1]._scopeName].gfx.utils._svgSerializerInitialized();
 								}
 							}, 50);
 						}
@@ -222,20 +236,20 @@ dojo.require("dojox.gfx");
 					f.onload = function(){
 						f.onload = function() {};
 						intv = setInterval(function() {
-							if(f.contentWindow[dojo._scopeName] &&
-							   f.contentWindow[dojox._scopeName].gfx &&
-							   f.contentWindow[dojox._scopeName].gfx.utils){
+							if(f.contentWindow[kernel.scopeMap["dojo"][1]._scopeName] &&
+							   f.contentWindow[kernel.scopeMap["dojox"][1]._scopeName].gfx &&
+							   f.contentWindow[kernel.scopeMap["dojox"][1]._scopeName].gfx.utils){
 								clearInterval(intv);
-								f.contentWindow.parent[dojox._scopeName].gfx.utils._gfxSvgProxy = f.contentWindow;
-								f.contentWindow.parent[dojox._scopeName].gfx.utils._svgSerializerInitialized();
+								f.contentWindow.parent[kernel.scopeMap["dojox"][1]._scopeName].gfx.utils._gfxSvgProxy = f.contentWindow;
+								f.contentWindow.parent[kernel.scopeMap["dojox"][1]._scopeName].gfx.utils._svgSerializerInitialized();
 							}
 						}, 50);
 					};
 				}
 				//We have to load the GFX SVG proxy frame.  Default is to use the one packaged in dojox.
-				var uri = (dojo.config["dojoxGfxSvgProxyFrameUrl"]||dojo.moduleUrl("dojox", "gfx/resources/gfxSvgProxyFrame.html"));
-				f.setAttribute("src", uri);
-				dojo.body().appendChild(f);
+				var uri = (config["dojoxGfxSvgProxyFrameUrl"]||require.toUrl("dojox/gfx/resources/gfxSvgProxyFrame.html"));
+				f.setAttribute("src", uri.toString());
+				win.body().appendChild(f);
 			}
 		},
 
@@ -267,11 +281,25 @@ dojo.require("dojox.gfx");
 					svg = svg.substring(4, svg.length);
 					svg = "<svg xmlns=\"http://www.w3.org/2000/svg\"" + svg;
 				}
+				//Same for xmlns:xlink (missing in Chrome and Safari)
+				if(svg.indexOf("xmlns:xlink=\"http://www.w3.org/1999/xlink\"") == -1){
+					svg = svg.substring(4, svg.length);
+					svg = "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\"" + svg;
+				}
+				//and add namespace to href attribute if not done yet 
+				//(FF 5+ adds xlink:href but not the xmlns def)
+				if(svg.indexOf("xlink:href") === -1){
+					svg = svg.replace(/href\s*=/g, "xlink:href=");
+				}
 				//Do some other cleanup, like stripping out the
-				//dojoGfx attributes.
+				//dojoGfx attributes and quoting ids.
 				svg = svg.replace(/\bdojoGfx\w*\s*=\s*(['"])\w*\1/g, "");
+				svg = svg.replace(/\b__gfxObject__\s*=\s*(['"])\w*\1/g, "");
+				svg = svg.replace(/[=]([^"']+?)(\s|>)/g,'="$1"$2');
 			}
 			return svg;  //Cleaned SVG text.
 		}
 	});
-})();
+
+	return gu;
+});
diff --git a/dojox/gfx/vml.js b/dojox/gfx/vml.js
index 56e8332..8ba4ed8 100644
--- a/dojox/gfx/vml.js
+++ b/dojox/gfx/vml.js
@@ -1,17 +1,46 @@
-dojo.provide("dojox.gfx.vml");
-
-dojo.require("dojox.gfx._base");
-dojo.require("dojox.gfx.shape");
-dojo.require("dojox.gfx.path");
-dojo.require("dojox.gfx.arc");
-dojo.require("dojox.gfx.gradient");
-
-(function(){
-	var d = dojo, g = dojox.gfx, m = g.matrix, gs = g.shape, vml = g.vml;
+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", 
+		"./_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.
+	};
+	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);
+	var vmlElems = ["*", "group", "roundrect", "oval", "shape", "rect", "imagedata", "path", "textpath", "text"],
+		i = 0, l = 1, s = document.createStyleSheet();
+	if(has("ie") >= 8){
+		i = 1;
+		l = vmlElems.length;
+	}
+	for (; i < l; ++i) {
+		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"};
 
@@ -23,7 +52,7 @@ dojo.require("dojox.gfx.gradient");
 
 	vml._bool = {"t": 1, "true": 1};
 
-	d.declare("dojox.gfx.vml.Shape", gs.Shape, {
+	declare("dojox.gfx.vml.Shape", gs.Shape, {
 		// summary: VML-specific implementation of dojox.gfx.Shape methods
 
 		setFill: function(fill){
@@ -87,7 +116,7 @@ dojo.require("dojox.gfx.gradient");
 							a.push({offset: 1, color: g.normalizeColor(f.colors[0].color)});
 						}
 						// massage colors
-						d.forEach(f.colors, function(v, i){
+						arr.forEach(f.colors, function(v, i){
 							a.push({offset: 1 - v.offset * c, color: g.normalizeColor(v.color)});
 						});
 						i = a.length - 1;
@@ -95,7 +124,7 @@ dojo.require("dojox.gfx.gradient");
 						if(i < a.length - 1){
 							// correct excessive colors
 							var q = a[i], p = a[i + 1];
-							p.color = d.blendColors(q.color, p.color, q.offset / (q.offset - p.offset));
+							p.color = Color.blendColors(q.color, p.color, q.offset / (q.offset - p.offset));
 							p.offset = 0;
 							while(a.length - i > 2) a.pop();
 						}
@@ -171,7 +200,7 @@ dojo.require("dojox.gfx.gradient");
 				return this;
 			}
 			// normalize the stroke
-			if(typeof stroke == "string" || d.isArray(stroke) || stroke instanceof d.Color){
+			if(typeof stroke == "string" || lang.isArray(stroke) || stroke instanceof Color){
 				stroke = {color: stroke};
 			}
 			var s = this.strokeStyle = g.makeParameters(g.defaultStroke, stroke);
@@ -260,6 +289,7 @@ dojo.require("dojox.gfx.gradient");
 			rawNode.stroked = "f";
 			rawNode.filled  = "f";
 			this.rawNode = rawNode;
+			this.rawNode.__gfxObject__ = this.getUID();
 		},
 
 		// move family
@@ -283,11 +313,11 @@ dojo.require("dojox.gfx.gradient");
 		_getRealMatrix: function(){
 			// summary: returns the cumulative ("real") transformation matrix
 			//	by combining the shape's matrix with its parent's matrix
-			return this.parentMatrix ? new g.Matrix2D([this.parentMatrix, this.matrix]) : this.matrix;	// dojox.gfx.Matrix2D
+			return this.parentMatrix ? new m.Matrix2D([this.parentMatrix, this.matrix]) : this.matrix;	// dojox.gfx.Matrix2D
 		}
 	});
 
-	dojo.declare("dojox.gfx.vml.Group", vml.Shape, {
+	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(){
@@ -322,7 +352,7 @@ dojo.require("dojox.gfx.gradient");
 	});
 	vml.Group.nodeType = "group";
 
-	dojo.declare("dojox.gfx.vml.Rect", [vml.Shape, gs.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)
@@ -343,11 +373,12 @@ dojo.require("dojox.gfx.gradient");
 				}
 				parent.removeChild(this.rawNode);
 			}
-			if(d.isIE > 7){
+			if(has("ie") > 7){
 				var node = this.rawNode.ownerDocument.createElement("v:roundrect");
 				node.arcsize = r;
 				node.style.display = "inline-block";
 				this.rawNode = node;
+				this.rawNode.__gfxObject__ = this.getUID();						
 			}else{
 				this.rawNode.arcsize = r;
 			}
@@ -361,15 +392,15 @@ dojo.require("dojox.gfx.gradient");
 			var style = this.rawNode.style;
 			style.left   = shape.x.toFixed();
 			style.top    = shape.y.toFixed();
-			style.width  = (typeof shape.width == "string" && shape.width.indexOf("%") >= 0)  ? shape.width  : shape.width.toFixed();
-			style.height = (typeof shape.width == "string" && shape.height.indexOf("%") >= 0) ? shape.height : shape.height.toFixed();
+			style.width  = (typeof shape.width == "string" && shape.width.indexOf("%") >= 0)  ? shape.width  : Math.max(shape.width.toFixed(),0);
+			style.height = (typeof shape.height == "string" && shape.height.indexOf("%") >= 0) ? shape.height : Math.max(shape.height.toFixed(),0);
 			// set all necessary styles, which are lost by VML (yes, it's a VML's bug)
 			return this.setTransform(this.matrix).setFill(this.fillStyle).setStroke(this.strokeStyle);	// self
 		}
 	});
 	vml.Rect.nodeType = "roundrect"; // use a roundrect so the stroke join type is respected
 
-	dojo.declare("dojox.gfx.vml.Ellipse", [vml.Shape, gs.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)
@@ -386,7 +417,7 @@ dojo.require("dojox.gfx.gradient");
 	});
 	vml.Ellipse.nodeType = "oval";
 
-	dojo.declare("dojox.gfx.vml.Circle", [vml.Shape, gs.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)
@@ -403,7 +434,7 @@ dojo.require("dojox.gfx.gradient");
 	});
 	vml.Circle.nodeType = "oval";
 
-	dojo.declare("dojox.gfx.vml.Line", [vml.Shape, gs.Line], {
+	declare("dojox.gfx.vml.Line", [vml.Shape, gs.Line], {
 		// summary: a line shape (VML)
 		constructor: function(rawNode){
 			if(rawNode) rawNode.setAttribute("dojoGfxType", "line");
@@ -420,7 +451,7 @@ dojo.require("dojox.gfx.gradient");
 	});
 	vml.Line.nodeType = "shape";
 
-	dojo.declare("dojox.gfx.vml.Polyline", [vml.Shape, gs.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");
@@ -457,7 +488,7 @@ dojo.require("dojox.gfx.gradient");
 	});
 	vml.Polyline.nodeType = "shape";
 
-	dojo.declare("dojox.gfx.vml.Image", [vml.Shape, gs.Image], {
+	declare("dojox.gfx.vml.Image", [vml.Shape, gs.Image], {
 		// summary: an image (VML)
 		setShape: function(newShape){
 			// summary: sets an image shape object (VML)
@@ -526,7 +557,7 @@ dojo.require("dojox.gfx.gradient");
 	});
 	vml.Image.nodeType = "rect";
 
-	dojo.declare("dojox.gfx.vml.Text", [vml.Shape, gs.Text], {
+	declare("dojox.gfx.vml.Text", [vml.Shape, gs.Text], {
 		// summary: an anchored text (VML)
 		constructor: function(rawNode){
 			if(rawNode){rawNode.setAttribute("dojoGfxType", "text");}
@@ -615,7 +646,7 @@ dojo.require("dojox.gfx.gradient");
 	});
 	vml.Text.nodeType = "shape";
 
-	dojo.declare("dojox.gfx.vml.Path", [vml.Shape, g.path.Path], {
+	declare("dojox.gfx.vml.Path", [vml.Shape, pathLib.Path], {
 		// summary: a path shape (VML)
 		constructor: function(rawNode){
 			if(rawNode && !rawNode.getAttribute("dojoGfxType")){
@@ -627,7 +658,7 @@ dojo.require("dojox.gfx.gradient");
 		_updateWithSegment: function(segment){
 			// summary: updates the bounding box of path with new segment
 			// segment: Object: a segment
-			var last = d.clone(this.last);
+			var last = lang.clone(this.last);
 			this.inherited(arguments);
 			if(arguments.length > 1){ return; } // skip transfomed bbox calculations
 			// add a VML path segment
@@ -843,7 +874,7 @@ dojo.require("dojox.gfx.gradient");
 					x1 += last.x;
 					y1 += last.y;
 				}
-				var result = g.arc.arcAsBezier(
+				var result = arcLib.arcAsBezier(
 					last, n[i], n[i + 1], n[i + 2],
 					n[i + 3] ? 1 : 0, n[i + 4] ? 1 : 0,
 					x1, y1
@@ -869,16 +900,16 @@ dojo.require("dojox.gfx.gradient");
 	});
 	vml.Path.nodeType = "shape";
 
-	dojo.declare("dojox.gfx.vml.TextPath", [vml.Path, g.path.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;
 			if(!("text" in this)){
-				this.text = d.clone(g.defaultTextPath);
+				this.text = lang.clone(g.defaultTextPath);
 			}
 			if(!("fontStyle" in this)){
-				this.fontStyle = d.clone(g.defaultFont);
+				this.fontStyle = lang.clone(g.defaultFont);
 			}
 		},
 		setText: function(newText){
@@ -943,7 +974,7 @@ dojo.require("dojox.gfx.gradient");
 	});
 	vml.TextPath.nodeType = "shape";
 
-	dojo.declare("dojox.gfx.vml.Surface", gs.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);
@@ -992,7 +1023,7 @@ dojo.require("dojox.gfx.gradient");
 		// height: String: height of surface, e.g., "100px"
 
 		if(!width && !height){
-			var pos = d.position(parentNode);
+			var pos = domGeom.position(parentNode);
 			width  = width  || pos.w;
 			height = height || pos.h;
 		}
@@ -1003,12 +1034,12 @@ dojo.require("dojox.gfx.gradient");
 			height = height + "px";
 		}
 
-		var s = new vml.Surface(), p = d.byId(parentNode),
+		var s = new vml.Surface(), p = dom.byId(parentNode),
 			c = s.clipNode = p.ownerDocument.createElement("div"),
 			r = s.rawNode = p.ownerDocument.createElement("v:group"),
 			cs = c.style, rs = r.style;
 
-		if(d.isIE > 7){
+		if(has("ie") > 7){
 			rs.display = "inline-block";
 		}
 
@@ -1050,40 +1081,53 @@ dojo.require("dojox.gfx.gradient");
 	
 	// copied from dojox.gfx.utils
 	function forEach(object, f, o){
-		o = o || d.global;
+		o = o || win.global;
 		f.call(o, object);
 		if(object instanceof g.Surface || object instanceof g.Group){
-			d.forEach(object.children, function(shape){
+			arr.forEach(object.children, function(shape){
 				forEach(shape, f, o);
 			});
 		}
 	}
 
+	var addPatch9624 = function(shape){
+		if(this != shape.getParent()){
+			// cleanup from old parent
+			var oldParent = shape.getParent();
+			if(oldParent) { oldParent.remove(shape); }
+			// then move the raw node
+			this.rawNode.appendChild(shape.rawNode);
+			C.add.apply(this, arguments);
+			// reapply visual attributes (slow..)
+			forEach(this, function(s){
+				if (typeof(s.getFont) == 'function'){ // text shapes need to be completely refreshed
+					s.setShape(s.getShape());
+					s.setFont(s.getFont());
+				}
+				if (typeof(s.setFill) == 'function'){ // if setFill is available a setStroke should be safe to assume also
+					s.setFill(s.getFill());
+					s.setStroke(s.getStroke());
+				}
+			});
+		}
+		return this;	// self
+	};
+	
+	var add15 = function(shape){
+		if(this != shape.getParent()){
+			this.rawNode.appendChild(shape.rawNode);
+			if(!shape.getParent()){ 
+				// reapply visual attributes 
+				shape.setFill(shape.getFill()); 
+				shape.setStroke(shape.getStroke()); 
+			} 
+			C.add.apply(this, arguments);
+		}
+		return this;	// self
+	};
+
 	var C = gs.Container, Container = {
-		add: function(shape){
-			// summary: adds a shape to a group/surface
-			// shape: dojox.gfx.Shape: an VML shape object
-			if(this != shape.getParent()){
-				// cleanup from old parent
-				var oldParent = shape.getParent();
-				if(oldParent) { oldParent.remove(shape); }
-				// then move the raw node
-				this.rawNode.appendChild(shape.rawNode);
-				C.add.apply(this, arguments);
-				// reapply visual attributes (slow..)
-				forEach(this, function(s){
-					if (typeof(s.getFont) == 'function'){ // text shapes need to be completely refreshed
-						s.setShape(s.getShape());
-						s.setFont(s.getFont());
-					}
-					if (typeof(s.setFill) == 'function'){ // if setFill is available a setStroke should be safe to assume also
-						s.setFill(s.getFill());
-						s.setStroke(s.getStroke());
-					}
-				});
-			}
-			return this;	// self
-		},
+		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
@@ -1152,7 +1196,7 @@ dojo.require("dojox.gfx.gradient");
 			if(!this.rawNode) return null;
 			var shape = new vml.Rect,
 				node = this.rawNode.ownerDocument.createElement("v:roundrect");
-			if(d.isIE > 7){
+			if(has("ie") > 7){
 				node.style.display = "inline-block";
 			}
 			shape.setRawNode(node);
@@ -1193,17 +1237,28 @@ dojo.require("dojox.gfx.gradient");
 		}
 	};
 
-	d.extend(vml.Group, Container);
-	d.extend(vml.Group, gs.Creator);
-	d.extend(vml.Group, Creator);
+	lang.extend(vml.Group, Container);
+	lang.extend(vml.Group, gs.Creator);
+	lang.extend(vml.Group, Creator);
 
-	d.extend(vml.Surface, Container);
-	d.extend(vml.Surface, gs.Creator);
-	d.extend(vml.Surface, Creator);
+	lang.extend(vml.Surface, Container);
+	lang.extend(vml.Surface, gs.Creator);
+	lang.extend(vml.Surface, Creator);
 
-	// see if we are required to initilize
-	if(g.loadAndSwitch === "vml"){
-		g.switchTo("vml");
-		delete g.loadAndSwitch;
-	}
-})();
\ No newline at end of file
+	// 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.
+		// event: Object 
+		//     The current input event (MouseEvent or TouchEvent)
+		// gfxElement: Object
+		//     The GFX target element
+		if (!event.gfxTarget) {
+			event.gfxTarget = gs.byId(event.target.__gfxObject__);
+		}
+		return true;
+	};
+	
+	return vml;
+});
diff --git a/dojox/gfx/vml_attach.js b/dojox/gfx/vml_attach.js
index 2b920c3..d385d6c 100644
--- a/dojox/gfx/vml_attach.js
+++ b/dojox/gfx/vml_attach.js
@@ -1,9 +1,7 @@
-dojo.require("dojox.gfx.vml");
+define(["dojo/_base/kernel", "dojo/_base/lang", "./_base", "./matrix", "./path", "dojo/_base/Color", "./vml"],
+  function (kernel, lang, g, m, pathLib, Color, vml){
 
-dojo.experimental("dojox.gfx.vml_attach");
-
-(function(){
-	var g = dojox.gfx, m = g.matrix, vml = g.vml;
+	kernel.experimental("dojox.gfx.vml_attach");
 	
 	vml.attachNode = function(node){
 		// summary: creates a shape from a Node
@@ -92,34 +90,34 @@ dojo.experimental("dojox.gfx.vml_attach");
 	var attachFill = function(object){
 		// summary: deduces a fill style from a node.
 		// object: dojox.gfx.Shape: an VML shape
-		var fillStyle = null, r = object.rawNode, fo = r.fill;
+		var fillStyle = null, r = object.rawNode, fo = r.fill, stops, i, t;
 		if(fo.on && fo.type == "gradient"){
-			var fillStyle = dojo.clone(g.defaultLinearGradient),
+			fillStyle = lang.clone(g.defaultLinearGradient),
 				rad = m._degToRad(fo.angle);
 			fillStyle.x2 = Math.cos(rad);
 			fillStyle.y2 = Math.sin(rad);
 			fillStyle.colors = [];
-			var stops = fo.colors.value.split(";");
-			for(var i = 0; i < stops.length; ++i){
-				var t = stops[i].match(/\S+/g);
+			stops = fo.colors.value.split(";");
+			for(i = 0; i < stops.length; ++i){
+				 t = stops[i].match(/\S+/g);
 				if(!t || t.length != 2){ continue; }
-				fillStyle.colors.push({offset: vml._parseFloat(t[0]), color: new dojo.Color(t[1])});
+				fillStyle.colors.push({offset: vml._parseFloat(t[0]), color: new Color(t[1])});
 			}
 		}else if(fo.on && fo.type == "gradientradial"){
-			var fillStyle = dojo.clone(g.defaultRadialGradient),
+			fillStyle = lang.clone(g.defaultRadialGradient),
 				w = parseFloat(r.style.width), h = parseFloat(r.style.height);
 			fillStyle.cx = isNaN(w) ? 0 : fo.focusposition.x * w;
 			fillStyle.cy = isNaN(h) ? 0 : fo.focusposition.y * h;
 			fillStyle.r  = isNaN(w) ? 1 : w / 2;
 			fillStyle.colors = [];
-			var stops = fo.colors.value.split(";");
-			for(var i = stops.length - 1; i >= 0; --i){
-				var t = stops[i].match(/\S+/g);
+			stops = fo.colors.value.split(";");
+			for(i = stops.length - 1; i >= 0; --i){
+				t = stops[i].match(/\S+/g);
 				if(!t || t.length != 2){ continue; }
-				fillStyle.colors.push({offset: vml._parseFloat(t[0]), color: new dojo.Color(t[1])});
+				fillStyle.colors.push({offset: vml._parseFloat(t[0]), color: new Color(t[1])});
 			}
 		}else if(fo.on && fo.type == "tile"){
-			var fillStyle = dojo.clone(g.defaultPattern);
+			fillStyle = lang.clone(g.defaultPattern);
 			fillStyle.width  = g.pt2px(fo.size.x); // from pt
 			fillStyle.height = g.pt2px(fo.size.y); // from pt
 			fillStyle.x = fo.origin.x * fillStyle.width;
@@ -127,7 +125,7 @@ dojo.experimental("dojox.gfx.vml_attach");
 			fillStyle.src = fo.src;
 		}else if(fo.on && r.fillcolor){
 			// a color object !
-			fillStyle = new dojo.Color(r.fillcolor+"");
+			fillStyle = new Color(r.fillcolor+"");
 			fillStyle.a = fo.opacity;
 		}
 		object.fillStyle = fillStyle;
@@ -141,9 +139,9 @@ dojo.experimental("dojox.gfx.vml_attach");
 			object.strokeStyle = null;
 			return;
 		}
-		var strokeStyle = object.strokeStyle = dojo.clone(g.defaultStroke),
+		var strokeStyle = object.strokeStyle = lang.clone(g.defaultStroke),
 			rs = r.stroke;
-		strokeStyle.color = new dojo.Color(r.strokecolor.value);
+		strokeStyle.color = new Color(r.strokecolor.value);
 		strokeStyle.width = g.normalizedLength(r.strokeweight+"");
 		strokeStyle.color.a = rs.opacity;
 		strokeStyle.cap = this._translate(this._capMapReversed, rs.endcap);
@@ -217,7 +215,7 @@ dojo.experimental("dojox.gfx.vml_attach");
 	var attachLine = function(object){
 		// summary: builds a line shape from a node.
 		// object: dojox.gfx.Shape: an VML shape
-		var shape = object.shape = dojo.clone(g.defaultLine),
+		var shape = object.shape = lang.clone(g.defaultLine),
 			p = object.rawNode.path.v.match(g.pathVmlRegExp);
 		do{
 			if(p.length < 7 || p[0] != "m" || p[3] != "l" || p[6] != "e"){ break; }
@@ -231,7 +229,7 @@ dojo.experimental("dojox.gfx.vml_attach");
 	var attachPolyline = function(object){
 		// summary: builds a polyline/polygon shape from a node.
 		// object: dojox.gfx.Shape: an VML shape
-		var shape = object.shape = dojo.clone(g.defaultPolyline),
+		var shape = object.shape = lang.clone(g.defaultPolyline),
 			p = object.rawNode.path.v.match(g.pathVmlRegExp);
 		do{
 			if(p.length < 3 || p[0] != "m"){ break; }
@@ -251,7 +249,7 @@ dojo.experimental("dojox.gfx.vml_attach");
 	var attachImage = function(object){
 		// summary: builds an image shape from a node.
 		// object: dojox.gfx.Shape: an VML shape
-		object.shape = dojo.clone(g.defaultImage);
+		object.shape = lang.clone(g.defaultImage);
 		object.shape.src = object.rawNode.firstChild.src;
 	};
 
@@ -272,7 +270,7 @@ dojo.experimental("dojox.gfx.vml_attach");
 	var attachText = function(object){
 		// summary: builds a text shape from a node.
 		// object: dojox.gfx.Shape: an VML shape
-		var shape = object.shape = dojo.clone(g.defaultText),
+		var shape = object.shape = lang.clone(g.defaultText),
 			r = object.rawNode, p = r.path.v.match(g.pathVmlRegExp);
 		do{
 			if(!p || p.length != 7){ break; }
@@ -307,7 +305,7 @@ dojo.experimental("dojox.gfx.vml_attach");
 	var attachFont = function(object){
 		// summary: deduces a font style from a node.
 		// object: dojox.gfx.Shape: an VML shape
-		var fontStyle = object.fontStyle = dojo.clone(g.defaultFont),
+		var fontStyle = object.fontStyle = lang.clone(g.defaultFont),
 			c = object.rawNode.childNodes, i = 0;
 		for(; i < c.length && c[i].tagName == "textpath"; ++i);
 		if(i >= c.length){
@@ -336,9 +334,9 @@ dojo.experimental("dojox.gfx.vml_attach");
 	var attachPath = function(object){
 		// summary: builds a path shape from a Node.
 		// object: dojox.gfx.Shape: an VML shape
-		var shape = object.shape = dojo.clone(g.defaultPath),
+		var shape = object.shape = lang.clone(g.defaultPath),
 			p = object.rawNode.path.v.match(g.pathVmlRegExp),
-			t = [], skip = false, map = g.Path._pathVmlToSvgMap;
+			t = [], skip = false, map = pathLib._pathVmlToSvgMap;
 		for(var i = 0; i < p.length; ++p){
 			var s = p[i];
 			if(s in map) {
@@ -361,4 +359,6 @@ dojo.experimental("dojox.gfx.vml_attach");
 			shape.path = t.join(" ");
 		}
 	};
-})();
+
+	return vml; //return augmented vml api
+});
diff --git a/dojox/gfx3d.js b/dojox/gfx3d.js
index c6aee36..a92f812 100644
--- a/dojox/gfx3d.js
+++ b/dojox/gfx3d.js
@@ -1,7 +1,6 @@
-dojo.provide("dojox.gfx3d");
-
-dojo.require("dojox.gfx3d.matrix");
-dojo.require("dojox.gfx3d._base");
-dojo.require("dojox.gfx3d.object");
-
+// AMD-ID "dojox/gfx3d"
+define(["dojo/_base/kernel","dojox","./gfx3d/matrix","./gfx3d/_base","./gfx3d/object"], function(dojo,dojox) {
+dojo.getObject("gfx3d", true, dojox);
 
+return dojox.gfx3d;
+});
diff --git a/dojox/gfx3d/_base.js b/dojox/gfx3d/_base.js
index 393b0a4..0979591 100644
--- a/dojox/gfx3d/_base.js
+++ b/dojox/gfx3d/_base.js
@@ -1,15 +1,17 @@
-dojo.provide("dojox.gfx3d._base");
-
-dojo.mixin(dojox.gfx3d, {
-	// summary: defines constants, prototypes, and utility functions
-	
-	// default objects, which are used to fill in missing parameters
-	defaultEdges:	  {type: "edges",     style: null, points: []},
-	defaultTriangles: {type: "triangles", style: null, points: []},
-	defaultQuads:	  {type: "quads",     style: null, points: []},
-	defaultOrbit:	  {type: "orbit",     center: {x: 0, y: 0, z: 0}, radius: 50},
-	defaultPath3d:	  {type: "path3d",    path: []},
-	defaultPolygon:	  {type: "polygon",   path: []},
-	defaultCube:	  {type: "cube",      bottom: {x: 0, y: 0, z: 0}, top: {x: 100, y: 100, z: 100}},
-	defaultCylinder:  {type: "cylinder",  center: /* center of bottom */ {x: 0, y: 0, z: 0}, height: 100, radius: 50}
-});
+define(["dojo/_base/lang"],function(lang) {
+	var gfx3d = lang.getObject("dojox.gfx3d",true);
+	lang.mixin( gfx3d, {
+		// summary: defines constants, prototypes, and utility functions
+		
+		// default objects, which are used to fill in missing parameters
+		defaultEdges:	  {type: "edges",     style: null, points: []},
+		defaultTriangles: {type: "triangles", style: null, points: []},
+		defaultQuads:	  {type: "quads",     style: null, points: []},
+		defaultOrbit:	  {type: "orbit",     center: {x: 0, y: 0, z: 0}, radius: 50},
+		defaultPath3d:	  {type: "path3d",    path: []},
+		defaultPolygon:	  {type: "polygon",   path: []},
+		defaultCube:	  {type: "cube",      bottom: {x: 0, y: 0, z: 0}, top: {x: 100, y: 100, z: 100}},
+		defaultCylinder:  {type: "cylinder",  center: /* center of bottom */ {x: 0, y: 0, z: 0}, height: 100, radius: 50}
+	});
+	return gfx3d;
+});
\ No newline at end of file
diff --git a/dojox/gfx3d/gradient.js b/dojox/gfx3d/gradient.js
index bf22861..4f8a192 100644
--- a/dojox/gfx3d/gradient.js
+++ b/dojox/gfx3d/gradient.js
@@ -1,13 +1,12 @@
-dojo.provide("dojox.gfx3d.gradient");
+define(["dojo/_base/lang","./matrix","./vector"], 
+	function(lang,m,v){
 
-dojo.require("dojox.gfx3d.vector");
-dojo.require("dojox.gfx3d.matrix");
+	var gfx3d = lang.getObject("dojox.gfx3d",true);
 
-(function(){
 	var dist = function(a, b){ return Math.sqrt(Math.pow(b.x - a.x, 2) + Math.pow(b.y - a.y, 2)); };
 	var N = 32;
 
-	dojox.gfx3d.gradient = function(model, material, center, radius, from, to, matrix){
+	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
@@ -16,9 +15,9 @@ dojo.require("dojox.gfx3d.matrix");
 		// from: Number: from position in radians
 		// to: Number: from position in radians
 		// matrix: dojox.gfx3d.Matrix3D: the cumulative transformation matrix
-		// tolerance: Number: tolerable diffirence in colors between gradient steps
+		// tolerance: Number: tolerable difference in colors between gradient steps
 
-		var m = dojox.gfx3d.matrix, v = dojox.gfx3d.vector, mx = m.normalize(matrix),
+		var mx = m.normalize(matrix),
 			f = m.multiplyPoint(mx, radius * Math.cos(from) + center.x, radius * Math.sin(from) + center.y, center.z),
 			t = m.multiplyPoint(mx, radius * Math.cos(to)   + center.x, radius * Math.sin(to)   + center.y, center.z),
 			c = m.multiplyPoint(mx, center.x, center.y, center.z), step = (to - from) / N, r = dist(f, t) / 2,
@@ -34,4 +33,6 @@ dojo.require("dojox.gfx3d.matrix");
 
 		return {type: "linear", x1: 0, y1: -r, x2: 0, y2: r, colors: colors};
 	};
-})();
+
+	return gfx3d.gradient;
+});
\ No newline at end of file
diff --git a/dojox/gfx3d/lighting.js b/dojox/gfx3d/lighting.js
index c663ff2..e68350e 100644
--- a/dojox/gfx3d/lighting.js
+++ b/dojox/gfx3d/lighting.js
@@ -1,10 +1,12 @@
-dojo.provide("dojox.gfx3d.lighting");
-dojo.require("dojox.gfx._base");
+define([
+	"dojo/_base/lang",
+	"dojo/_base/Color",	// dojo.Color
+	"dojo/_base/declare",	// dojo.declare
+	"dojox/gfx/_base",
+	"./_base"
+],function(lang,Color,declare,gfx,gfx3d) {
 
-(function(){
-	var lite = dojox.gfx3d.lighting;
-
-	dojo.mixin(dojox.gfx3d.lighting, {
+	var lite = gfx3d.lighting = {
 		// color utilities
 		black: function(){
 			return {r: 0, g: 0, b: 0, a: 1};
@@ -13,11 +15,11 @@ dojo.require("dojox.gfx._base");
 			return {r: 1, g: 1, b: 1, a: 1};
 		},
 		toStdColor: function(c){
-			c = dojox.gfx.normalizeColor(c);
+			c = gfx.normalizeColor(c);
 			return {r: c.r / 255, g: c.g / 255, b: c.b / 255, a: c.a};
 		},
 		fromStdColor: function(c){
-			return new dojo.Color([Math.round(255 * c.r), Math.round(255 * c.g), Math.round(255 * c.b), c.a]);
+			return new Color([Math.round(255 * c.r), Math.round(255 * c.g), Math.round(255 * c.b), c.a]);
 		},
 		scaleColor: function(s, c){
 			return {r: s * c.r, g: s * c.g, b: s * c.b, a: s * c.a};
@@ -65,18 +67,18 @@ dojo.require("dojox.gfx._base");
 			return Math.min(Math.max(v, 0), 1);
 		},
 		length: function(v){
-			return Math.sqrt(dojox.gfx3d.lighting.dot(v, v));
+			return Math.sqrt(gfx3d.lighting.dot(v, v));
 		},
 		normalize: function(v){
 			return lite.scale(1 / lite.length(v), v);
 		},
 		faceforward: function(n, i){
-			var p = dojox.gfx3d.lighting;
+			var p = gfx3d.lighting;
 			var s = p.dot(i, n) < 0 ? 1 : -1;
 			return p.scale(s, n);
 		},
 		reflect: function(i, n){
-			var p = dojox.gfx3d.lighting;
+			var p = gfx3d.lighting;
 			return p.add(i, p.scale(-2 * p.dot(i, n), n));
 		},
 		
@@ -111,11 +113,11 @@ dojo.require("dojox.gfx._base");
 			}
 			return lite.saturateColor(c);
 		}
-	});
+	};
 
 	// this lighting model is derived from RenderMan Interface Specification Version 3.2
 
-	dojo.declare("dojox.gfx3d.lighting.Model", null, {
+	declare("dojox.gfx3d.lighting.Model", null, {
 		constructor: function(incident, lights, ambient, specular){
 			this.incident = lite.normalize(incident);
 			this.lights = [];
@@ -202,36 +204,39 @@ dojo.require("dojox.gfx._base");
 			return lite.fromStdColor(lite.saturateColor(color));
 		}
 	});
-})();
-
-// POV-Ray basic finishes
 
-dojox.gfx3d.lighting.finish = {
 
-	// Default
+	// POV-Ray basic finishes
+	
+	gfx3d.lighting.finish = {
+	
+		// Default
+		
+		defaults: {Ka: 0.1, Kd: 0.6, Ks: 0.0, roughness: 0.05},
+		
+		dull:     {Ka: 0.1, Kd: 0.6, Ks: 0.5, roughness: 0.15},
+		shiny:    {Ka: 0.1, Kd: 0.6, Ks: 1.0, roughness: 0.001},
+		glossy:   {Ka: 0.1, Kd: 0.6, Ks: 1.0, roughness: 0.0001},
+		
+		phong_dull:   {Ka: 0.1, Kd: 0.6, Ks: 0.5, phong: 0.5, phong_size: 1},
+		phong_shiny:  {Ka: 0.1, Kd: 0.6, Ks: 1.0, phong: 1.0, phong_size: 200},
+		phong_glossy: {Ka: 0.1, Kd: 0.6, Ks: 1.0, phong: 1.0, phong_size: 300},
 	
-	defaults: {Ka: 0.1, Kd: 0.6, Ks: 0.0, roughness: 0.05},
+		luminous: {Ka: 1.0, Kd: 0.0, Ks: 0.0, roughness: 0.05},
 	
-	dull:     {Ka: 0.1, Kd: 0.6, Ks: 0.5, roughness: 0.15},
-	shiny:    {Ka: 0.1, Kd: 0.6, Ks: 1.0, roughness: 0.001},
-	glossy:   {Ka: 0.1, Kd: 0.6, Ks: 1.0, roughness: 0.0001},
+		// Metals
 	
-	phong_dull:   {Ka: 0.1, Kd: 0.6, Ks: 0.5, phong: 0.5, phong_size: 1},
-	phong_shiny:  {Ka: 0.1, Kd: 0.6, Ks: 1.0, phong: 1.0, phong_size: 200},
-	phong_glossy: {Ka: 0.1, Kd: 0.6, Ks: 1.0, phong: 1.0, phong_size: 300},
-
-	luminous: {Ka: 1.0, Kd: 0.0, Ks: 0.0, roughness: 0.05},
-
-	// Metals
+		// very soft and dull
+		metalA: {Ka: 0.35, Kd: 0.3, Ks: 0.8, roughness: 1/20},
+		// fairly soft and dull
+		metalB: {Ka: 0.30, Kd: 0.4, Ks: 0.7, roughness: 1/60},
+		// medium reflectivity, holds color well
+		metalC: {Ka: 0.25, Kd: 0.5, Ks: 0.8, roughness: 1/80},
+		// highly hard and polished, high reflectivity
+		metalD: {Ka: 0.15, Kd: 0.6, Ks: 0.8, roughness: 1/100},
+		// very highly polished and reflective
+		metalE: {Ka: 0.10, Kd: 0.7, Ks: 0.8, roughness: 1/120}
+	};
 
-	// very soft and dull
-	metalA: {Ka: 0.35, Kd: 0.3, Ks: 0.8, roughness: 1/20},
-	// fairly soft and dull
-	metalB: {Ka: 0.30, Kd: 0.4, Ks: 0.7, roughness: 1/60},
-	// medium reflectivity, holds color well
-	metalC: {Ka: 0.25, Kd: 0.5, Ks: 0.8, roughness: 1/80},
-	// highly hard and polished, high reflectivity
-	metalD: {Ka: 0.15, Kd: 0.6, Ks: 0.8, roughness: 1/100},
-	// very highly polished and reflective
-	metalE: {Ka: 0.10, Kd: 0.7, Ks: 0.8, roughness: 1/120}
-};
+	return lite;
+});
diff --git a/dojox/gfx3d/matrix.js b/dojox/gfx3d/matrix.js
index 62ddca8..01f16b1 100644
--- a/dojox/gfx3d/matrix.js
+++ b/dojox/gfx3d/matrix.js
@@ -1,335 +1,340 @@
-dojo.provide("dojox.gfx3d.matrix");
-
-// candidates for dojox.math:
-dojox.gfx3d.matrix._degToRad = function(degree){ return Math.PI * degree / 180; };
-dojox.gfx3d.matrix._radToDeg = function(radian){ return radian / Math.PI * 180; };
-
-dojox.gfx3d.matrix.Matrix3D = function(arg){
-	// 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
-	if(arg){
-		if(typeof arg == "number"){
-			this.xx = this.yy = this.zz = arg;
-		}else if(arg instanceof Array){
-			if(arg.length > 0){
-				var m = dojox.gfx3d.matrix.normalize(arg[0]);
-				// combine matrices
-				for(var i = 1; i < arg.length; ++i){
-					var l = m;
-					var r = dojox.gfx3d.matrix.normalize(arg[i]);
-					m = new dojox.gfx3d.matrix.Matrix3D();
-					m.xx = l.xx * r.xx + l.xy * r.yx + l.xz * r.zx;
-					m.xy = l.xx * r.xy + l.xy * r.yy + l.xz * r.zy;
-					m.xz = l.xx * r.xz + l.xy * r.yz + l.xz * r.zz;
-					m.yx = l.yx * r.xx + l.yy * r.yx + l.yz * r.zx;
-					m.yy = l.yx * r.xy + l.yy * r.yy + l.yz * r.zy;
-					m.yz = l.yx * r.xz + l.yy * r.yz + l.yz * r.zz;
-					m.zx = l.zx * r.xx + l.zy * r.yx + l.zz * r.zx;
-					m.zy = l.zx * r.xy + l.zy * r.yy + l.zz * r.zy;
-					m.zz = l.zx * r.xz + l.zy * r.yz + l.zz * r.zz;
-					m.dx = l.xx * r.dx + l.xy * r.dy + l.xz * r.dz + l.dx;
-					m.dy = l.yx * r.dx + l.yy * r.dy + l.yz * r.dz + l.dy;
-					m.dz = l.zx * r.dx + l.zy * r.dy + l.zz * r.dz + l.dz;
+define(["dojo/_base/lang", "./_base"], function(lang, gfx3d){
+	
+	// candidates for dojox.math:
+	gfx3d.matrix = {
+		_degToRad : function(degree){ return Math.PI * degree / 180; },
+		_radToDeg : function(radian){ return radian / Math.PI * 180; }
+	};
+	
+	gfx3d.matrix.Matrix3D = function(arg){
+		// 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
+		if(arg){
+			if(typeof arg == "number"){
+				this.xx = this.yy = this.zz = arg;
+			}else if(arg instanceof Array){
+				if(arg.length > 0){
+					var m = gfx3d.matrix.normalize(arg[0]);
+					// combine matrices
+					for(var i = 1; i < arg.length; ++i){
+						var l = m;
+						var r = gfx3d.matrix.normalize(arg[i]);
+						m = new gfx3d.matrix.Matrix3D();
+						m.xx = l.xx * r.xx + l.xy * r.yx + l.xz * r.zx;
+						m.xy = l.xx * r.xy + l.xy * r.yy + l.xz * r.zy;
+						m.xz = l.xx * r.xz + l.xy * r.yz + l.xz * r.zz;
+						m.yx = l.yx * r.xx + l.yy * r.yx + l.yz * r.zx;
+						m.yy = l.yx * r.xy + l.yy * r.yy + l.yz * r.zy;
+						m.yz = l.yx * r.xz + l.yy * r.yz + l.yz * r.zz;
+						m.zx = l.zx * r.xx + l.zy * r.yx + l.zz * r.zx;
+						m.zy = l.zx * r.xy + l.zy * r.yy + l.zz * r.zy;
+						m.zz = l.zx * r.xz + l.zy * r.yz + l.zz * r.zz;
+						m.dx = l.xx * r.dx + l.xy * r.dy + l.xz * r.dz + l.dx;
+						m.dy = l.yx * r.dx + l.yy * r.dy + l.yz * r.dz + l.dy;
+						m.dz = l.zx * r.dx + l.zy * r.dy + l.zz * r.dz + l.dz;
+					}
+					lang.mixin(this, m);
 				}
-				dojo.mixin(this, m);
+			}else{
+				lang.mixin(this, arg);
 			}
-		}else{
-			dojo.mixin(this, arg);
 		}
-	}
-};
-
-// the default (identity) matrix, which is used to fill in missing values
-dojo.extend(dojox.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});
-
-dojo.mixin(dojox.gfx3d.matrix, {
-	// summary: class constants, and methods of dojox.gfx3d.matrix
+	};
 	
-	// matrix constants
+	// the default (identity) matrix, which is used to fill in missing values
+	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});
 	
-	// identity: dojox.gfx3d.matrix.Matrix3D
-	//		an identity matrix constant: identity * (x, y, z) == (x, y, z)
-	identity: new dojox.gfx3d.matrix.Matrix3D(),
+	lang.mixin(gfx3d.matrix, {
+		// summary: class constants, and methods of dojox.gfx3d.matrix
+		
+		// matrix constants
+		
+		// identity: dojox.gfx3d.matrix.Matrix3D
+		//		an identity matrix constant: identity * (x, y, z) == (x, y, z)
+		identity: new gfx3d.matrix.Matrix3D(),
+		
+		// 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
+			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
+			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
+			//		around the origin of coordinates (0, 0) by specified angle.
+			// 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
+			//		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)
+			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
+			//		around the origin of coordinates (0, 0) by specified angle.
+			// 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
+			//		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)
+			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
+			//		around the origin of coordinates (0, 0) by specified angle.
+			// 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
+			//		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)
+			return gfx3d.matrix.rotateZ(gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
+		},
 	
-	// matrix creators
+		// 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
+			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
+			//		around the origin of coordinates (0, 0) by specified angle.
+			// 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
+			//		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)
+			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
+			//		around the origin of coordinates (0, 0) by specified angle.
+			// 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
+			//		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)
+			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
+			//		around the origin of coordinates (0, 0) by specified angle.
+			// 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
+			//		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)
+			return gfx3d.matrix.rotateZ(gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
+		},
 	
-	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
-		if(arguments.length > 1){
-			return new dojox.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 dojox.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
-		if(arguments.length > 1){
-			return new dojox.gfx3d.matrix.Matrix3D({xx: a, yy: b, zz: c}); // dojox.gfx3d.matrix.Matrix3D
-		}
-		if(typeof a == "number"){
+		// 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
+			//		such objects to a valid dojox.gfx3d.matrix.Matrix3D object.
+			// 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
+			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];
+			}
+			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
+			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({
+				xx: (m.yy * m.zz - m.yz * m.zy) / D,
+				xy: (m.xz * m.zy - m.xy * m.zz) / D,
+				xz: (m.xy * m.yz - m.xz * m.yy) / D,
+				yx: (m.yz * m.zx - m.yx * m.zz) / D,
+				yy: (m.xx * m.zz - m.xz * m.zx) / D,
+				yz: (m.xz * m.yx - m.xx * m.yz) / D,
+				zx: (m.yx * m.zy - m.yy * m.zx) / D,
+				zy: (m.xy * m.zx - m.xx * m.zy) / D,
+				zz: (m.xx * m.yy - m.xy * m.yx) / D,
+				dx: -1 * (m.xy * m.yz * m.dz + m.xz * m.dy * m.zy + m.dx * m.yy * m.zz - m.xy * m.dy * m.zz - m.xz * m.yy * m.dz - m.dx * m.yz * m.zy) / D,
+				dy: (m.xx * m.yz * m.dz + m.xz * m.dy * m.zx + m.dx * m.yx * m.zz - m.xx * m.dy * m.zz - m.xz * m.yx * m.dz - m.dx * m.yz * m.zx) / D,
+				dz: -1 * (m.xx * m.yy * m.dz + m.xy * m.dy * m.zx + m.dx * m.yx * m.zy - m.xx * m.dy * m.zy - m.xy * m.yx * m.dz - m.dx * m.yy * m.zx) / D
+			});
+			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
+			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
+			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
-			// a: Number: a uniform scaling factor used for the all coordinates
+			// matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
+			// a: Object: a point
 			// b: null
-			return new dojox.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 dojox.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
-		//		around the origin of coordinates (0, 0) by specified angle.
-		// angle: Number: an angle of rotation in radians (>0 for CW)
-		var c = Math.cos(angle);
-		var s = Math.sin(angle);
-		return new dojox.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
-		//		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)
-		return dojox.gfx3d.matrix.rotateX(dojox.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
-		//		around the origin of coordinates (0, 0) by specified angle.
-		// angle: Number: an angle of rotation in radians (>0 for CW)
-		var c = Math.cos(angle);
-		var s = Math.sin(angle);
-		return new dojox.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
-		//		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)
-		return dojox.gfx3d.matrix.rotateY(dojox.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
-		//		around the origin of coordinates (0, 0) by specified angle.
-		// angle: Number: an angle of rotation in radians (>0 for CW)
-		var c = Math.cos(angle);
-		var s = Math.sin(angle);
-		return new dojox.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
-		//		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)
-		return dojox.gfx3d.matrix.rotateZ(dojox.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
-		if(arguments.length > 1){
-			return new dojox.gfx3d.matrix.Matrix3D({dx: -a, dy: -b, dz: -c}); // dojox.gfx3d.matrix.Matrix3D
+			// 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,
+			//		all subsequent arguments are matrix-like objects too
+			var m = gfx3d.matrix.normalize(matrix);
+			// combine matrices
+			for(var i = 1; i < arguments.length; ++i){
+				var l = m;
+				var r = gfx3d.matrix.normalize(arguments[i]);
+				m = new gfx3d.matrix.Matrix3D();
+				m.xx = l.xx * r.xx + l.xy * r.yx + l.xz * r.zx;
+				m.xy = l.xx * r.xy + l.xy * r.yy + l.xz * r.zy;
+				m.xz = l.xx * r.xz + l.xy * r.yz + l.xz * r.zz;
+				m.yx = l.yx * r.xx + l.yy * r.yx + l.yz * r.zx;
+				m.yy = l.yx * r.xy + l.yy * r.yy + l.yz * r.zy;
+				m.yz = l.yx * r.xz + l.yy * r.yz + l.yz * r.zz;
+				m.zx = l.zx * r.xx + l.zy * r.yx + l.zz * r.zx;
+				m.zy = l.zx * r.xy + l.zy * r.yy + l.zz * r.zy;
+				m.zz = l.zx * r.xz + l.zy * r.yz + l.zz * r.zz;
+				m.dx = l.xx * r.dx + l.xy * r.dy + l.xz * r.dz + l.dx;
+				m.dy = l.yx * r.dx + l.yy * r.dy + l.yz * r.dz + l.dy;
+				m.dz = l.zx * r.dx + l.zy * r.dy + l.zz * r.dz + l.dz;
+			}
+			return m; // dojox.gfx3d.matrix.Matrix3D
+		},
+	
+		_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
+			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
+			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
 		}
-		// branch
-		// a: Object: a point-like object, which specifies offsets for 3 dimensions
-		// b: null
-		return new dojox.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
-		//		around the origin of coordinates (0, 0) by specified angle.
-		// angle: Number: an angle of rotation in radians (>0 for CW)
-		var c = Math.cos(-angle);
-		var s = Math.sin(-angle);
-		return new dojox.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
-		//		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)
-		return dojox.gfx3d.matrix.rotateX(dojox.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
-		//		around the origin of coordinates (0, 0) by specified angle.
-		// angle: Number: an angle of rotation in radians (>0 for CW)
-		var c = Math.cos(-angle);
-		var s = Math.sin(-angle);
-		return new dojox.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
-		//		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)
-		return dojox.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
-		//		around the origin of coordinates (0, 0) by specified angle.
-		// angle: Number: an angle of rotation in radians (>0 for CW)
-		var c = Math.cos(-angle);
-		var s = Math.sin(-angle);
-		return new dojox.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
-		//		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)
-		return dojox.gfx3d.matrix.rotateZ(dojox.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
-		//		such objects to a valid dojox.gfx3d.matrix.Matrix3D object.
-		// matrix: Object: an object, which is converted to a matrix, if necessary
-		return (matrix instanceof dojox.gfx3d.matrix.Matrix3D) ? matrix : new dojox.gfx3d.matrix.Matrix3D(matrix); // dojox.gfx3d.matrix.Matrix3D
-	},
+	});
 	
-	// common operations
+	// propagate matrix up
+	gfx3d.Matrix3D = gfx3d.matrix.Matrix3D;
 	
-	clone: function(matrix){
-		// summary: creates a copy of a 3D matrix
-		// matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix-like object to be cloned
-		var obj = new dojox.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];
-		}
-		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
-		var m = dojox.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 dojox.gfx3d.matrix.Matrix3D({
-			xx: (m.yy * m.zz - m.yz * m.zy) / D,
-			xy: (m.xz * m.zy - m.xy * m.zz) / D,
-			xz: (m.xy * m.yz - m.xz * m.yy) / D,
-			yx: (m.yz * m.zx - m.yx * m.zz) / D,
-			yy: (m.xx * m.zz - m.xz * m.zx) / D,
-			yz: (m.xz * m.yx - m.xx * m.yz) / D,
-			zx: (m.yx * m.zy - m.yy * m.zx) / D,
-			zy: (m.xy * m.zx - m.xx * m.zy) / D,
-			zz: (m.xx * m.yy - m.xy * m.yx) / D,
-			dx: -1 * (m.xy * m.yz * m.dz + m.xz * m.dy * m.zy + m.dx * m.yy * m.zz - m.xy * m.dy * m.zz - m.xz * m.yy * m.dz - m.dx * m.yz * m.zy) / D,
-			dy: (m.xx * m.yz * m.dz + m.xz * m.dy * m.zx + m.dx * m.yx * m.zz - m.xx * m.dy * m.zz - m.xz * m.yx * m.dz - m.dx * m.yz * m.zx) / D,
-			dz: -1 * (m.xx * m.yy * m.dz + m.xy * m.dy * m.zx + m.dx * m.yx * m.zy - m.xx * m.dy * m.zy - m.xy * m.yx * m.dz - m.dx * m.yy * m.zx) / D
-		});
-		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
-		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
-		var m = dojox.gfx3d.matrix.normalize(matrix);
-		if(typeof a == "number" && typeof b == "number" && typeof c == "number"){
-			return dojox.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 dojox.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,
-		//		all subsequent arguments are matrix-like objects too
-		var m = dojox.gfx3d.matrix.normalize(matrix);
-		// combine matrices
-		for(var i = 1; i < arguments.length; ++i){
-			var l = m;
-			var r = dojox.gfx3d.matrix.normalize(arguments[i]);
-			m = new dojox.gfx3d.matrix.Matrix3D();
-			m.xx = l.xx * r.xx + l.xy * r.yx + l.xz * r.zx;
-			m.xy = l.xx * r.xy + l.xy * r.yy + l.xz * r.zy;
-			m.xz = l.xx * r.xz + l.xy * r.yz + l.xz * r.zz;
-			m.yx = l.yx * r.xx + l.yy * r.yx + l.yz * r.zx;
-			m.yy = l.yx * r.xy + l.yy * r.yy + l.yz * r.zy;
-			m.yz = l.yx * r.xz + l.yy * r.yz + l.yz * r.zz;
-			m.zx = l.zx * r.xx + l.zy * r.yx + l.zz * r.zx;
-			m.zy = l.zx * r.xy + l.zy * r.yy + l.zz * r.zy;
-			m.zz = l.zx * r.xz + l.zy * r.yz + l.zz * r.zz;
-			m.dx = l.xx * r.dx + l.xy * r.dy + l.xz * r.dz + l.dx;
-			m.dy = l.yx * r.dx + l.yy * r.dy + l.yz * r.dz + l.dy;
-			m.dz = l.zx * r.dx + l.zy * r.dy + l.zz * r.dz + l.dz;
-		}
-		return m; // dojox.gfx3d.matrix.Matrix3D
-	},
-
-	_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
-		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
-		var m = dojox.gfx3d.matrix.normalize(matrix);
-		if(typeof a == "number" && typeof b == "number" && typeof c == "number"){
-			return dojox.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 dojox.gfx3d.matrix._project(m, a.x, a.y, a.z); // Object
-	}
-});
-
-// propagate matrix up
-dojox.gfx3d.Matrix3D = dojox.gfx3d.matrix.Matrix3D;
+	return gfx3d.matrix;
+});
\ No newline at end of file
diff --git a/dojox/gfx3d/object.js b/dojox/gfx3d/object.js
index 6d446bd..49014e7 100644
--- a/dojox/gfx3d/object.js
+++ b/dojox/gfx3d/object.js
@@ -1,12 +1,20 @@
-dojo.provide("dojox.gfx3d.object");
-
-dojo.require("dojox.gfx");
-dojo.require("dojox.gfx3d.lighting");
-dojo.require("dojox.gfx3d.scheduler");
-dojo.require("dojox.gfx3d.vector");
-dojo.require("dojox.gfx3d.gradient");
-
-// FIXME: why the global "out" var here?
+define([
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojox/gfx",
+	"dojox/gfx/matrix",
+	"./_base",
+	"./scheduler",
+	"./gradient",
+	"./vector",
+	"./matrix",
+	"./lighting"
+], function(arrayUtil,declare,lang,gfx,matrixUtil2d,gfx3d,schedulerExtensions,Gradient,VectorUtil,matrixUtil,lightUtil){
+
+var scheduler = schedulerExtensions.scheduler;
+	
+// FIXME: why the "out" var here?
 var out = function(o, x){
 	if(arguments.length > 1){
 		// console.debug("debug:", o);
@@ -19,7 +27,7 @@ var out = function(o, x){
 	}
 };
 
-dojo.declare("dojox.gfx3d.Object", null, {
+declare("dojox.gfx3d.Object", null, {
 	constructor: function(){
 		// summary: a Object object, which knows how to map
 		// 3D objects to 2D shapes.
@@ -59,7 +67,7 @@ dojo.declare("dojox.gfx3d.Object", null, {
 		// dojox.gfx3d.defaultOrbit
 		// dojox.gfx3d.defaultCube
 		// or dojox.gfx3d.defaultCylinder)
-		this.object = dojox.gfx.makeParameters(this.object, newObject);
+		this.object = gfx.makeParameters(this.object, newObject);
 		return this;
 	},
 
@@ -68,7 +76,7 @@ dojo.declare("dojox.gfx3d.Object", null, {
 		// 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 = dojox.gfx3d.matrix.clone(matrix ? dojox.gfx3d.matrix.normalize(matrix) : dojox.gfx3d.identity, true);
+		this.matrix = matrixUtil.clone(matrix ? matrixUtil.normalize(matrix) : gfx3d.identity, true);
 		return this;	// self
 	},
 
@@ -123,7 +131,9 @@ dojo.declare("dojox.gfx3d.Object", null, {
 	},
 
 	toStdFill: function(lighting, normal){
-		return (this.fillStyle && typeof this.fillStyle['type'] != "undefined") ? lighting[this.fillStyle.type](normal, this.fillStyle.finish, this.fillStyle.color) : this.fillStyle;
+		return (this.fillStyle && typeof this.fillStyle['type'] != "undefined") ? 
+			lighting[this.fillStyle.type](normal, this.fillStyle.finish, this.fillStyle.color)
+			: this.fillStyle;
 	},
 
 	invalidate: function(){
@@ -161,7 +171,7 @@ dojo.declare("dojox.gfx3d.Object", null, {
 
 });
 
-dojo.declare("dojox.gfx3d.Scene", dojox.gfx3d.Object, {
+declare("dojox.gfx3d.Scene", gfx3d.Object, {
 	// summary: the Scene is just a containter.
 	// note: we have the following assumption:
 	// all objects in the Scene are not overlapped with other objects
@@ -170,13 +180,13 @@ dojo.declare("dojox.gfx3d.Scene", dojox.gfx3d.Object, {
 		// summary: a containter of other 3D objects
 		this.objects= [];
 		this.todos = [];
-		this.schedule = dojox.gfx3d.scheduler.zOrder;
-		this._draw = dojox.gfx3d.drawer.conservative;
+		this.schedule = scheduler.zOrder;
+		this._draw = gfx3d.drawer.conservative;
 	},
 
 	setFill: function(fill){
 		this.fillStyle = fill;
-		dojo.forEach(this.objects, function(item){
+		arrayUtil.forEach(this.objects, function(item){
 			item.setFill(fill);
 		});
 		return this;
@@ -184,18 +194,18 @@ dojo.declare("dojox.gfx3d.Scene", dojox.gfx3d.Object, {
 
 	setStroke: function(stroke){
 		this.strokeStyle = stroke;
-		dojo.forEach(this.objects, function(item){
+		arrayUtil.forEach(this.objects, function(item){
 			item.setStroke(stroke);
 		});
 		return this;
 	},
 
 	render: function(camera, deep){
-		var m = dojox.gfx3d.matrix.multiply(camera, this.matrix);
+		var m = matrixUtil.multiply(camera, this.matrix);
 		if(deep){
 			this.todos = this.objects;
 		}
-		dojo.forEach(this.todos, function(item){ item.render(m, deep); });
+		arrayUtil.forEach(this.todos, function(item){ item.render(m, deep); });
 	},
 
 	draw: function(lighting){
@@ -205,7 +215,7 @@ dojo.declare("dojox.gfx3d.Scene", dojox.gfx3d.Object, {
 
 	addTodo: function(newObject){
 		// FIXME: use indexOf?
-		if(dojo.every(this.todos, function(item){ return item != newObject; })){
+		if(arrayUtil.every(this.todos, function(item){ return item != newObject; })){
 			this.todos.push(newObject);
 			this.invalidate();
 		}
@@ -217,36 +227,36 @@ dojo.declare("dojox.gfx3d.Scene", dojox.gfx3d.Object, {
 
 	getZOrder: function(){
 		var zOrder = 0;
-		dojo.forEach(this.objects, function(item){ zOrder += item.getZOrder(); });
+		arrayUtil.forEach(this.objects, function(item){ zOrder += item.getZOrder(); });
 		return (this.objects.length > 1) ?  zOrder / this.objects.length : 0;
 	}
 });
 
 
-dojo.declare("dojox.gfx3d.Edges", dojox.gfx3d.Object, {
+declare("dojox.gfx3d.Edges", gfx3d.Object, {
 	constructor: function(){
 		// summary: a generic edge in 3D viewport
-		this.object = dojo.clone(dojox.gfx3d.defaultEdges);
+		this.object = lang.clone(gfx3d.defaultEdges);
 	},
 
 	setObject: function(newObject, /* String, optional */ style){
 		// summary: setup the object
 		// newObject: Array of points || Object
 		// style: String, optional
-		this.object = dojox.gfx.makeParameters(this.object, (newObject instanceof Array) ? { points: newObject, style: style } : newObject);
+		this.object = gfx.makeParameters(this.object, (newObject instanceof Array) ? { points: newObject, style: style } : newObject);
 		return this;
 	},
 
 	getZOrder: function(){
 		var zOrder = 0;
-		dojo.forEach(this.cache, function(item){ zOrder += item.z;} );
+		arrayUtil.forEach(this.cache, function(item){ zOrder += item.z;} );
 		return (this.cache.length > 1) ?  zOrder / this.cache.length : 0;
 	},
 
 	render: function(camera){
-		var m = dojox.gfx3d.matrix.multiply(camera, this.matrix);
-		this.cache = dojo.map(this.object.points, function(item){
-			return dojox.gfx3d.matrix.multiplyPoint(m, item);
+		var m = matrixUtil.multiply(camera, this.matrix);
+		this.cache = arrayUtil.map(this.object.points, function(item){
+			return matrixUtil.multiplyPoint(m, item);
 		});
 	},
 
@@ -261,7 +271,7 @@ dojo.declare("dojox.gfx3d.Edges", dojox.gfx3d.Object, {
 
 		if(this.object.style == "strip" || this.object.style == "loop"){
 			p.moveTo(c[0].x, c[0].y);
-			dojo.forEach(c.slice(1), function(item){
+			arrayUtil.forEach(c.slice(1), function(item){
 				p.lineTo(item.x, item.y);
 			});
 			if(this.object.style == "loop"){
@@ -280,29 +290,29 @@ dojo.declare("dojox.gfx3d.Edges", dojox.gfx3d.Object, {
 	}
 });
 
-dojo.declare("dojox.gfx3d.Orbit", dojox.gfx3d.Object, {
+declare("dojox.gfx3d.Orbit", gfx3d.Object, {
 	constructor: function(){
 		// summary: a generic edge in 3D viewport
-		this.object = dojo.clone(dojox.gfx3d.defaultOrbit);
+		this.object = lang.clone(gfx3d.defaultOrbit);
 	},
 
 	render: function(camera){
-		var m = dojox.gfx3d.matrix.multiply(camera, this.matrix);
+		var m = matrixUtil.multiply(camera, this.matrix);
 		var angles = [0, Math.PI/4, Math.PI/3];
-		var center = dojox.gfx3d.matrix.multiplyPoint(m, this.object.center);
-		var marks = dojo.map(angles, function(item){
+		var center = matrixUtil.multiplyPoint(m, this.object.center);
+		var marks = arrayUtil.map(angles, function(item){
 			return {x: this.center.x + this.radius * Math.cos(item),
 				y: this.center.y + this.radius * Math.sin(item), z: this.center.z};
 			}, this.object);
 
-		marks = dojo.map(marks, function(item){
-			return dojox.gfx3d.matrix.multiplyPoint(m, item);
+		marks = arrayUtil.map(marks, function(item){
+			return matrixUtil.multiplyPoint(m, item);
 		});
 
-		var normal = dojox.gfx3d.vector.normalize(marks);
+		var normal = VectorUtil.normalize(marks);
 
-		marks = dojo.map(marks, function(item){
-			return dojox.gfx3d.vector.substract(item, center);
+		marks = arrayUtil.map(marks, function(item){
+			return VectorUtil.substract(item, center);
 		});
 
 		// Use the algorithm here:
@@ -318,17 +328,17 @@ dojo.declare("dojox.gfx3d.Orbit", dojox.gfx3d.Object, {
 			zx: marks[2].x * marks[2].y, zy: marks[2].y * marks[2].y, zz: 1,
 			dx: 0, dy: 0, dz: 0
 		};
-		var B = dojo.map(marks, function(item){
+		var B = arrayUtil.map(marks, function(item){
 			return -Math.pow(item.x, 2);
 		});
 
 		// X is 2b, c, f
-		var X = dojox.gfx3d.matrix.multiplyPoint(dojox.gfx3d.matrix.invert(A),B[0], B[1], B[2]);
+		var X = matrixUtil.multiplyPoint(matrixUtil.invert(A),B[0], B[1], B[2]);
 		var theta = Math.atan2(X.x, 1 - X.y) / 2;
 
 		// rotate the marks back to the canonical form
-		var probes = dojo.map(marks, function(item){
-			return dojox.gfx.matrix.multiplyPoint(dojox.gfx.matrix.rotate(-theta), item.x, item.y);
+		var probes = arrayUtil.map(marks, function(item){
+			return matrixUtil2d.multiplyPoint(matrixUtil2d.rotate(-theta), item.x, item.y);
 		});
 
 		// we are solving the equation: Ax = b
@@ -344,7 +354,7 @@ dojo.declare("dojox.gfx3d.Orbit", dojox.gfx3d.Object, {
 		// the invert matrix is
 		// 1/(ad -bc) [ d, -b; -c, a];
 		var rx = Math.sqrt( (a*d - b*c)/ (d-b) );
-		var ry  = Math.sqrt( (a*d - b*c)/ (a-c) );
+		var ry = Math.sqrt( (a*d - b*c)/ (a-c) );
 
 		this.cache = {cx: center.x, cy: center.y, rx: rx, ry: ry, theta: theta, normal: normal};
 	},
@@ -355,18 +365,18 @@ dojo.declare("dojox.gfx3d.Orbit", dojox.gfx3d.Object, {
 		} else {
 			this.shape = this.renderer.createEllipse(this.cache);
 		}
-		this.shape.applyTransform(dojox.gfx.matrix.rotateAt(this.cache.theta, this.cache.cx, this.cache.cy))
+		this.shape.applyTransform(matrixUtil2d.rotateAt(this.cache.theta, this.cache.cx, this.cache.cy))
 			.setStroke(this.strokeStyle)
 			.setFill(this.toStdFill(lighting, this.cache.normal));
 	}
 });
 
-dojo.declare("dojox.gfx3d.Path3d", dojox.gfx3d.Object, {
+declare("dojox.gfx3d.Path3d", gfx3d.Object, {
 	// This object is still very immature !
 	constructor: function(){
 		// summary: a generic line
 		//	(this is a helper object, which is defined for convenience)
-		this.object = dojo.clone(dojox.gfx3d.defaultPath3d);
+		this.object = lang.clone(gfx3d.defaultPath3d);
 		this.segments = [];
 		this.absolute = true;
 		this.last = {};
@@ -436,15 +446,15 @@ dojo.declare("dojox.gfx3d.Path3d", dojox.gfx3d.Object, {
 
 	render: function(camera){
 		// TODO: we need to get the ancestors' matrix
-		var m = dojox.gfx3d.matrix.multiply(camera, this.matrix);
+		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 _validSegments = this._validSegments;
-		dojo.forEach(this.segments, function(item){
+		arrayUtil.forEach(this.segments, function(item){
 			path += item.action;
 			for(var i = 0; i < item.args.length; i+= _validSegments[item.action.toLowerCase()] ){
-				var pt = dojox.gfx3d.matrix.multiplyPoint(m, item.args[i], item.args[i+1], item.args[i+2])
+				var pt = matrixUtil.multiplyPoint(m, item.args[i], item.args[i+1], item.args[i+2])
 				path += " " + pt.x + " " + pt.y;
 			}
 		});
@@ -457,11 +467,11 @@ dojo.declare("dojox.gfx3d.Path3d", dojox.gfx3d.Object, {
 	}
 });
 
-dojo.declare("dojox.gfx3d.Triangles", dojox.gfx3d.Object, {
+declare("dojox.gfx3d.Triangles", gfx3d.Object, {
 	constructor: function(){
 		// summary: a generic triangle
 		//	(this is a helper object, which is defined for convenience)
-		this.object = dojo.clone(dojox.gfx3d.defaultTriangles);
+		this.object = lang.clone(gfx3d.defaultTriangles);
 	},
 
 	setObject: function(newObject, /* String, optional */ style){
@@ -469,29 +479,29 @@ dojo.declare("dojox.gfx3d.Triangles", dojox.gfx3d.Object, {
 		// newObject: Array of points || Object
 		// style: String, optional
 		if(newObject instanceof Array){
-			this.object = dojox.gfx.makeParameters(this.object, { points: newObject, style: style } );
+			this.object = gfx.makeParameters(this.object, { points: newObject, style: style } );
 		} else {
-			this.object = dojox.gfx.makeParameters(this.object, newObject);
+			this.object = gfx.makeParameters(this.object, newObject);
 		}
 		return this;
 	},
 	render: function(camera){
-		var m = dojox.gfx3d.matrix.multiply(camera, this.matrix);
-		var c = dojo.map(this.object.points, function(item){
-			return dojox.gfx3d.matrix.multiplyPoint(m, item);
+		var m = matrixUtil.multiply(camera, this.matrix);
+		var c = arrayUtil.map(this.object.points, function(item){
+			return matrixUtil.multiplyPoint(m, item);
 		});
 		this.cache = [];
 		var pool = c.slice(0, 2);
 		var center = c[0];
 		if(this.object.style == "strip"){
-			dojo.forEach(c.slice(2), function(item){
+			arrayUtil.forEach(c.slice(2), function(item){
 				pool.push(item);
 				pool.push(pool[0]);
 				this.cache.push(pool);
 				pool = pool.slice(1, 3);
 			}, this);
 		} else if(this.object.style == "fan"){
-			dojo.forEach(c.slice(2), function(item){
+			arrayUtil.forEach(c.slice(2), function(item){
 				pool.push(item);
 				pool.push(center);
 				this.cache.push(pool);
@@ -507,45 +517,47 @@ dojo.declare("dojox.gfx3d.Triangles", dojox.gfx3d.Object, {
 
 	draw: function(lighting){
 		// use the BSP to schedule
-		this.cache = dojox.gfx3d.scheduler.bsp(this.cache, function(it){  return it; });
+		this.cache = scheduler.bsp(this.cache, function(it){  return it; });
 		if(this.shape){
 			this.shape.clear();
 		} else {
 			this.shape = this.renderer.createGroup();
 		}
-		dojo.forEach(this.cache, function(item){
+		arrayUtil.forEach(this.cache, function(item){
 			this.shape.createPolyline(item)
 				.setStroke(this.strokeStyle)
-				.setFill(this.toStdFill(lighting, dojox.gfx3d.vector.normalize(item)));
+				.setFill(this.toStdFill(lighting, VectorUtil.normalize(item)));
 		}, this);
 	},
 
 	getZOrder: function(){
 		var zOrder = 0;
-		dojo.forEach(this.cache, function(item){
+		arrayUtil.forEach(this.cache, function(item){
 				zOrder += (item[0].z + item[1].z + item[2].z) / 3; });
 		return (this.cache.length > 1) ?  zOrder / this.cache.length : 0;
 	}
 });
 
-dojo.declare("dojox.gfx3d.Quads", dojox.gfx3d.Object, {
+declare("dojox.gfx3d.Quads", gfx3d.Object, {
 	constructor: function(){
 		// summary: a generic triangle
 		//	(this is a helper object, which is defined for convenience)
-		this.object = dojo.clone(dojox.gfx3d.defaultQuads);
+		this.object = lang.clone(gfx3d.defaultQuads);
 	},
 
 	setObject: function(newObject, /* String, optional */ style){
 		// summary: setup the object
 		// newObject: Array of points || Object
 		// style: String, optional
-		this.object = dojox.gfx.makeParameters(this.object, (newObject instanceof Array) ? { points: newObject, style: style } : newObject );
+		this.object = gfx.makeParameters(this.object, (newObject instanceof Array) ? 
+			{ points: newObject, style: style } 
+				: newObject );
 		return this;
 	},
 	render: function(camera){
-		var m = dojox.gfx3d.matrix.multiply(camera, this.matrix), i;
-		var c = dojo.map(this.object.points, function(item){
-			return dojox.gfx3d.matrix.multiplyPoint(m, item);
+		var m = matrixUtil.multiply(camera, this.matrix), i;
+		var c = arrayUtil.map(this.object.points, function(item){
+			return matrixUtil.multiplyPoint(m, item);
 		});
 		this.cache = [];
 		if(this.object.style == "strip"){
@@ -566,7 +578,7 @@ dojo.declare("dojox.gfx3d.Quads", dojox.gfx3d.Object, {
 
 	draw: function(lighting){
 		// use the BSP to schedule
-		this.cache = dojox.gfx3d.scheduler.bsp(this.cache, function(it){  return it; });
+		this.cache = gfx3d.scheduler.bsp(this.cache, function(it){  return it; });
 		if(this.shape){
 			this.shape.clear();
 		}else{
@@ -576,7 +588,7 @@ dojo.declare("dojox.gfx3d.Quads", dojox.gfx3d.Object, {
 		for(var x=0; x<this.cache.length; x++){
 			this.shape.createPolyline(this.cache[x])
 				.setStroke(this.strokeStyle)
-				.setFill(this.toStdFill(lighting, dojox.gfx3d.vector.normalize(this.cache[x])));
+				.setFill(this.toStdFill(lighting, VectorUtil.normalize(this.cache[x])));
 		}
 		/*
 		dojo.forEach(this.cache, function(item){
@@ -602,24 +614,24 @@ dojo.declare("dojox.gfx3d.Quads", dojox.gfx3d.Object, {
 	}
 });
 
-dojo.declare("dojox.gfx3d.Polygon", dojox.gfx3d.Object, {
+declare("dojox.gfx3d.Polygon", gfx3d.Object, {
 	constructor: function(){
 		// summary: a generic triangle
 		//	(this is a helper object, which is defined for convenience)
-		this.object = dojo.clone(dojox.gfx3d.defaultPolygon);
+		this.object = lang.clone(gfx3d.defaultPolygon);
 	},
 
 	setObject: function(newObject){
 		// summary: setup the object
 		// newObject: Array of points || Object
-		this.object = dojox.gfx.makeParameters(this.object, (newObject instanceof Array) ? {path: newObject} : newObject)
+		this.object = gfx.makeParameters(this.object, (newObject instanceof Array) ? {path: newObject} : newObject)
 		return this;
 	},
 
 	render: function(camera){
-		var m = dojox.gfx3d.matrix.multiply(camera, this.matrix);
-		this.cache = dojo.map(this.object.path, function(item){
-			return dojox.gfx3d.matrix.multiplyPoint(m, item);
+		var m = matrixUtil.multiply(camera, this.matrix);
+		this.cache = arrayUtil.map(this.object.path, function(item){
+			return matrixUtil.multiplyPoint(m, item);
 		});
 		// add the first point to close the polyline
 		this.cache.push(this.cache[0]);
@@ -633,7 +645,7 @@ dojo.declare("dojox.gfx3d.Polygon", dojox.gfx3d.Object, {
 		}
 
 		this.shape.setStroke(this.strokeStyle)
-			.setFill(this.toStdFill(lighting, dojox.gfx3d.matrix.normalize(this.cache)));
+			.setFill(this.toStdFill(lighting, matrixUtil.normalize(this.cache)));
 	},
 
 	getZOrder: function(){
@@ -650,18 +662,18 @@ dojo.declare("dojox.gfx3d.Polygon", dojox.gfx3d.Object, {
 	}
 });
 
-dojo.declare("dojox.gfx3d.Cube", dojox.gfx3d.Object, {
+declare("dojox.gfx3d.Cube", gfx3d.Object, {
 	constructor: function(){
 		// summary: a generic triangle
 		//	(this is a helper object, which is defined for convenience)
-		this.object = dojo.clone(dojox.gfx3d.defaultCube);
+		this.object = lang.clone(gfx3d.defaultCube);
 		this.polygons = [];
 	},
 
 	setObject: function(newObject){
 		// summary: setup the object
 		// newObject: Array of points || Object
-		this.object = dojox.gfx.makeParameters(this.object, newObject);
+		this.object = gfx.makeParameters(this.object, newObject);
 	},
 
 	render: function(camera){
@@ -675,9 +687,9 @@ dojo.declare("dojox.gfx3d.Cube", dojox.gfx3d.Object, {
 		var f = {x: g.x, y: a.y, z: g.z};
 		var h = {x: a.x, y: g.y, z: g.z};
 		var polygons = [a, b, c, d, e, f, g, h];
-		var m = dojox.gfx3d.matrix.multiply(camera, this.matrix);
-		var p = dojo.map(polygons, function(item){
-			return dojox.gfx3d.matrix.multiplyPoint(m, item);
+		var m = matrixUtil.multiply(camera, this.matrix);
+		var p = arrayUtil.map(polygons, function(item){
+			return matrixUtil.multiplyPoint(m, item);
 		});
 		a = p[0]; b = p[1]; c = p[2]; d = p[3]; e = p[4]; f = p[5]; g = p[6]; h = p[7];
 		this.cache = [[a, b, c, d, a], [e, f, g, h, e], [a, d, h, e, a], [d, c, g, h, d], [c, b, f, g, c], [b, a, e, f, b]];
@@ -685,7 +697,7 @@ dojo.declare("dojox.gfx3d.Cube", dojox.gfx3d.Object, {
 
 	draw: function(lighting){
 		// use bsp to sort.
-		this.cache = dojox.gfx3d.scheduler.bsp(this.cache, function(it){ return it; });
+		this.cache = gfx3d.scheduler.bsp(this.cache, function(it){ return it; });
 		// only the last 3 polys are visible.
 		var cache = this.cache.slice(3);
 
@@ -697,7 +709,7 @@ dojo.declare("dojox.gfx3d.Cube", dojox.gfx3d.Object, {
 		for(var x=0; x<cache.length; x++){
 			this.shape.createPolyline(cache[x])
 				.setStroke(this.strokeStyle)
-				.setFill(this.toStdFill(lighting, dojox.gfx3d.vector.normalize(cache[x])));
+				.setFill(this.toStdFill(lighting, VectorUtil.normalize(cache[x])));
 		}
 		/*
 		dojo.forEach(cache, function(item){
@@ -716,23 +728,23 @@ dojo.declare("dojox.gfx3d.Cube", dojox.gfx3d.Object, {
 });
 
 
-dojo.declare("dojox.gfx3d.Cylinder", dojox.gfx3d.Object, {
+declare("dojox.gfx3d.Cylinder", gfx3d.Object, {
 	constructor: function(){
-		this.object = dojo.clone(dojox.gfx3d.defaultCylinder);
+		this.object = lang.clone(gfx3d.defaultCylinder);
 	},
 
 	render: function(camera){
 		// get the bottom surface first
-		var m = dojox.gfx3d.matrix.multiply(camera, this.matrix);
+		var m = matrixUtil.multiply(camera, this.matrix);
 		var angles = [0, Math.PI/4, Math.PI/3];
-		var center = dojox.gfx3d.matrix.multiplyPoint(m, this.object.center);
-		var marks = dojo.map(angles, function(item){
+		var center = matrixUtil.multiplyPoint(m, this.object.center);
+		var marks = arrayUtil.map(angles, function(item){
 			return {x: this.center.x + this.radius * Math.cos(item),
 				y: this.center.y + this.radius * Math.sin(item), z: this.center.z};
 			}, this.object);
 
-		marks = dojo.map(marks, function(item){
-			return dojox.gfx3d.vector.substract(dojox.gfx3d.matrix.multiplyPoint(m, item), center);
+		marks = arrayUtil.map(marks, function(item){
+			return VectorUtil.substract(matrixUtil.multiplyPoint(m, item), center);
 		});
 
 		// Use the algorithm here:
@@ -748,17 +760,17 @@ dojo.declare("dojox.gfx3d.Cylinder", dojox.gfx3d.Object, {
 			zx: marks[2].x * marks[2].y, zy: marks[2].y * marks[2].y, zz: 1,
 			dx: 0, dy: 0, dz: 0
 		};
-		var B = dojo.map(marks, function(item){
+		var B = arrayUtil.map(marks, function(item){
 			return -Math.pow(item.x, 2);
 		});
 
 		// X is 2b, c, f
-		var X = dojox.gfx3d.matrix.multiplyPoint(dojox.gfx3d.matrix.invert(A), B[0], B[1], B[2]);
+		var X = matrixUtil.multiplyPoint(matrixUtil.invert(A), B[0], B[1], B[2]);
 		var theta = Math.atan2(X.x, 1 - X.y) / 2;
 
 		// rotate the marks back to the canonical form
-		var probes = dojo.map(marks, function(item){
-			return dojox.gfx.matrix.multiplyPoint(dojox.gfx.matrix.rotate(-theta), item.x, item.y);
+		var probes = arrayUtil.map(marks, function(item){
+			return matrixUtil2d.multiplyPoint(matrixUtil2d.rotate(-theta), item.x, item.y);
 		});
 
 		// we are solving the equation: Ax = b
@@ -782,11 +794,11 @@ dojo.declare("dojox.gfx3d.Cylinder", dojox.gfx3d.Object, {
 			theta -= Math.PI/2;
 		}
 
-		var top = dojox.gfx3d.matrix.multiplyPoint(m,
-			dojox.gfx3d.vector.sum(this.object.center, {x: 0, y:0, z: this.object.height}));
+		var top = matrixUtil.multiplyPoint(m,
+			VectorUtil.sum(this.object.center, {x: 0, y:0, z: this.object.height}));
 
 		var gradient = this.fillStyle.type == "constant" ? this.fillStyle.color
-			: dojox.gfx3d.gradient(this.renderer.lighting, this.fillStyle, this.object.center, this.object.radius, Math.PI, 2 * Math.PI, m);
+			: Gradient(this.renderer.lighting, this.fillStyle, this.object.center, this.object.radius, Math.PI, 2 * Math.PI, m);
 		if(isNaN(rx) || isNaN(ry) || isNaN(theta)){
 			// in case the cap is invisible (parallel to the incident vector)
 			rx = this.object.radius, ry = 0, theta = 0;
@@ -795,7 +807,7 @@ dojo.declare("dojox.gfx3d.Cylinder", dojox.gfx3d.Object, {
 	},
 
 	draw: function(){
-		var c = this.cache, v = dojox.gfx3d.vector, m = dojox.gfx.matrix,
+		var c = this.cache, v = VectorUtil, m = matrixUtil2d,
 			centers = [c.center, c.top], normal = v.substract(c.top, c.center);
 		if(v.dotProduct(normal, this.renderer.lighting.incident) > 0){
 			centers = [c.top, c.center];
@@ -831,7 +843,7 @@ dojo.declare("dojox.gfx3d.Cylinder", dojox.gfx3d.Object, {
 
 
 // the ultimate container of 3D world
-dojo.declare("dojox.gfx3d.Viewport", dojox.gfx.Group, {
+declare("dojox.gfx3d.Viewport", gfx.Group, {
 	constructor: function(){
 		// summary: a viewport/container for 3D objects, which knows
 		// the camera and lightings
@@ -848,8 +860,8 @@ dojo.declare("dojox.gfx3d.Viewport", dojox.gfx.Group, {
 		// FIXME: memory leak?
 		this.renderer = this;
 		// Using zOrder as the default scheduler
-		this.schedule = dojox.gfx3d.scheduler.zOrder;
-		this.draw = dojox.gfx3d.drawer.conservative;
+		this.schedule = gfx3d.scheduler.zOrder;
+		this.draw = gfx3d.drawer.conservative;
 		// deep: boolean, true means the whole viewport needs to re-render, redraw
 		this.deep = false;
 
@@ -863,7 +875,7 @@ dojo.declare("dojox.gfx3d.Viewport", dojox.gfx.Group, {
 		// 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 = dojox.gfx3d.matrix.clone(matrix ? dojox.gfx3d.matrix.normalize(matrix) : dojox.gfx3d.identity, true);
+		this.camera = matrixUtil.clone(matrix ? matrixUtil.normalize(matrix) : gfx3d.identity, true);
 		this.invalidate();
 		return this;	// self
 	},
@@ -901,10 +913,12 @@ dojo.declare("dojox.gfx3d.Viewport", dojox.gfx.Group, {
 		// 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;
+		this.lights = (lights instanceof Array) ? 
+			{sources: lights, ambient: ambient, specular: specular}
+				: lights;
 		var view = {x: 0, y: 0, z: 1};
 
-		this.lighting = new dojox.gfx3d.lighting.Model(view, this.lights.sources,
+		this.lighting = new lightUtil.Model(view, this.lights.sources,
 				this.lights.ambient, this.lights.specular);
 		this.invalidate();
 		return this;
@@ -921,7 +935,7 @@ dojo.declare("dojox.gfx3d.Viewport", dojox.gfx.Group, {
 		// except calling invalidate, since invalidate is used as
 		// any modification needs to redraw the object itself, call invalidate.
 		// then call render.
-		if(dojo.every(this.todos,
+		if(arrayUtil.every(this.todos,
 			function(item){
 				return item != newObject;
 			}
@@ -937,8 +951,8 @@ dojo.declare("dojox.gfx3d.Viewport", dojox.gfx.Group, {
 
 	setDimensions: function(dim){
 		if(dim){
-			var w = dojo.isString(dim.width) ? parseInt(dim.width)  : dim.width;
-			var h = dojo.isString(dim.height) ? parseInt(dim.height) : dim.height;
+			var w = lang.isString(dim.width) ? parseInt(dim.width)  : dim.width;
+			var h = lang.isString(dim.height) ? parseInt(dim.height) : dim.height;
 			// there is no rawNode in canvas GFX implementation
 			if(this.rawNode){
 				var trs = this.rawNode.style;
@@ -958,11 +972,11 @@ dojo.declare("dojox.gfx3d.Viewport", dojox.gfx.Group, {
 		// summary: iterate all children and call their render callback function.
 		if(!this.todos.length){ return; }
 		// console.debug("Viewport::render");
-		var m = dojox.gfx3d.matrix;
+		var m = matrixUtil;
 		
 		// Iterate the todos and call render to prepare the rendering:
 		for(var x=0; x<this.todos.length; x++){
-			this.todos[x].render(dojox.gfx3d.matrix.normalize([
+			this.todos[x].render(matrixUtil.normalize([
 				m.cameraRotateXg(180),
 				m.cameraTranslate(0, this.dimension.height, 0),
 				this.camera
@@ -978,58 +992,58 @@ dojo.declare("dojox.gfx3d.Viewport", dojox.gfx.Group, {
 });
 
 //FIXME: Viewport cannot masquerade as a Group
-dojox.gfx3d.Viewport.nodeType = dojox.gfx.Group.nodeType;
+gfx3d.Viewport.nodeType = gfx.Group.nodeType;
 
-dojox.gfx3d._creators = {
+gfx3d._creators = {
 	// summary: object creators
 	createEdges: function(edges, style){
 		// summary: creates an edge object
 		// line: Object: a edge object (see dojox.gfx3d.defaultPath)
-		return this.create3DObject(dojox.gfx3d.Edges, edges, style);	// dojox.gfx3d.Edge
+		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)
-		return this.create3DObject(dojox.gfx3d.Triangles, tris, style);	// dojox.gfx3d.Edge
+		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)
-		return this.create3DObject(dojox.gfx3d.Quads, quads, style);	// dojox.gfx3d.Edge
+		return this.create3DObject(gfx3d.Quads, quads, style);	// dojox.gfx3d.Edge
 	},
 	createPolygon: function(points){
 		// summary: creates an triangle object
 		// points: Array of points || Object
-		return this.create3DObject(dojox.gfx3d.Polygon, points);	// dojox.gfx3d.Polygon
+		return this.create3DObject(gfx3d.Polygon, points);	// dojox.gfx3d.Polygon
 	},
 
 	createOrbit: function(orbit){
 		// summary: creates an triangle object
 		// points: Array of points || Object
-		return this.create3DObject(dojox.gfx3d.Orbit, orbit);	// dojox.gfx3d.Cube
+		return this.create3DObject(gfx3d.Orbit, orbit);	// dojox.gfx3d.Cube
 	},
 
 	createCube: function(cube){
 		// summary: creates an triangle object
 		// points: Array of points || Object
-		return this.create3DObject(dojox.gfx3d.Cube, cube);	// dojox.gfx3d.Cube
+		return this.create3DObject(gfx3d.Cube, cube);	// dojox.gfx3d.Cube
 	},
 
 	createCylinder: function(cylinder){
 		// summary: creates an triangle object
 		// points: Array of points || Object
-		return this.create3DObject(dojox.gfx3d.Cylinder, cylinder);	// dojox.gfx3d.Cube
+		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)
-		return this.create3DObject(dojox.gfx3d.Path3d, path);	// dojox.gfx3d.Edge
+		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)
-		return this.create3DObject(dojox.gfx3d.Scene);	// dojox.gfx3d.Scene
+		return this.create3DObject(gfx3d.Scene);	// dojox.gfx3d.Scene
 	},
 
 	create3DObject: function(objectType, rawObject, style){
@@ -1077,20 +1091,23 @@ dojox.gfx3d._creators = {
 	}
 };
 
-dojo.extend(dojox.gfx3d.Viewport, dojox.gfx3d._creators);
-dojo.extend(dojox.gfx3d.Scene, dojox.gfx3d._creators);
-delete dojox.gfx3d._creators;
+lang.extend(gfx3d.Viewport, gfx3d._creators);
+lang.extend(gfx3d.Scene, gfx3d._creators);
+delete gfx3d._creators;
 
 
 //FIXME: extending dojox.gfx.Surface and masquerading Viewport as Group is hacky!
 
 // Add createViewport to dojox.gfx.Surface
-dojo.extend(dojox.gfx.Surface, {
+lang.extend(gfx.Surface, {
 	createViewport: function(){
 		//FIXME: createObject is non-public method!
-		var viewport = this.createObject(dojox.gfx3d.Viewport, null, true);
+		var viewport = this.createObject(gfx3d.Viewport, null, true);
 		//FIXME: this may not work with dojox.gfx.Group !!
 		viewport.setDimensions(this.getDimensions());
 		return viewport;
 	}
 });
+
+	return gfx3d.Object;
+});
diff --git a/dojox/gfx3d/scheduler.js b/dojox/gfx3d/scheduler.js
index 2b47ca1..06edffc 100644
--- a/dojox/gfx3d/scheduler.js
+++ b/dojox/gfx3d/scheduler.js
@@ -1,10 +1,14 @@
-dojo.provide("dojox.gfx3d.scheduler");
-dojo.provide("dojox.gfx3d.drawer");
-dojo.require("dojox.gfx3d.vector");
-
-dojo.mixin(dojox.gfx3d.scheduler, {
+define([
+	"dojo/_base/lang",
+	"dojo/_base/array",	// dojo.forEach, dojo.every
+	"dojo/_base/declare",	// dojo.declare
+	"./_base",
+	"./vector"
+], function(lang, arrayUtil, declare, gfx3d, vectorUtil){
+
+gfx3d.scheduler = {
 	zOrder: function(buffer, order){
-		order = order ? order : dojox.gfx3d.scheduler.order;
+		order = order ? order : gfx3d.scheduler.order;
 		buffer.sort(function(a, b){
 			return order(b) - order(a);
 		});
@@ -13,9 +17,9 @@ dojo.mixin(dojox.gfx3d.scheduler, {
 
 	bsp: function(buffer, outline){
 		// console.debug("BSP scheduler");
-		outline = outline ? outline : dojox.gfx3d.scheduler.outline;
-		var p = new dojox.gfx3d.scheduler.BinarySearchTree(buffer[0], outline);
-		dojo.forEach(buffer.slice(1), function(item){ p.add(item, outline); });
+		outline = outline ? outline : gfx3d.scheduler.outline;
+		var p = new gfx3d.scheduler.BinarySearchTree(buffer[0], outline);
+		arrayUtil.forEach(buffer.slice(1), function(item){ p.add(item, outline); });
 		return p.iterate(outline);
 	},
 
@@ -27,10 +31,9 @@ dojo.mixin(dojox.gfx3d.scheduler, {
 	outline: function(it){
 		return it.getOutline();
 	}
+};
 
-});
-
-dojo.declare("dojox.gfx3d.scheduler.BinarySearchTree", null, {
+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
@@ -50,19 +53,19 @@ dojo.declare("dojox.gfx3d.scheduler.BinarySearchTree", null, {
 
 		var o = outline(obj);
 		this.orient = o[0];
-		this.normal = dojox.gfx3d.vector.normalize(o);
+		this.normal = vectorUtil.normalize(o);
 	},
 
 	add: function(obj, outline){
 		var epsilon = 0.5,
 			o = outline(obj),
-			v = dojox.gfx3d.vector,
+			v = vectorUtil,
 			n = this.normal,
 			a = this.orient,
-			BST = dojox.gfx3d.scheduler.BinarySearchTree;
+			BST = gfx3d.scheduler.BinarySearchTree;
 
 		if(
-			dojo.every(o, function(item){
+			arrayUtil.every(o, function(item){
 				return Math.floor(epsilon + v.dotProduct(n, v.substract(item, a))) <= 0;
 			})
 		){
@@ -72,7 +75,7 @@ dojo.declare("dojox.gfx3d.scheduler.BinarySearchTree", null, {
 				this.minus = new BST(obj, outline);
 			}
 		}else if(
-			dojo.every(o, function(item){
+			arrayUtil.every(o, function(item){
 				return Math.floor(epsilon + v.dotProduct(n, v.substract(item, a))) >= 0;
 			})
 		){
@@ -83,17 +86,17 @@ dojo.declare("dojox.gfx3d.scheduler.BinarySearchTree", null, {
 			}
 		}else{
 			/*
-			dojo.forEach(o, function(item){
+			arrayUtil.forEach(o, function(item){
 				console.debug(v.dotProduct(n, v.substract(item, a)));
 			});
 			*/
-			throw "The case: polygon cross siblings' plate is not implemneted yet";
+			throw "The case: polygon cross siblings' plate is not implemented yet";
 		}
 	},
 
 	iterate: function(outline){
 		var epsilon = 0.5;
-		var v = dojox.gfx3d.vector;
+		var v = vectorUtil;
 		var sorted = [];
 		var subs = null;
 		// FIXME: using Infinity here?
@@ -118,13 +121,13 @@ dojo.declare("dojox.gfx3d.scheduler.BinarySearchTree", null, {
 
 });
 
-dojo.mixin(dojox.gfx3d.drawer, {
+gfx3d.drawer = {
 	conservative: function(todos, objects, viewport){
 		// console.debug('conservative draw');
-		dojo.forEach(this.objects, function(item){
+		arrayUtil.forEach(this.objects, function(item){
 			item.destroy();
 		});
-		dojo.forEach(objects, function(item){
+		arrayUtil.forEach(objects, function(item){
 			item.draw(viewport.lighting);
 		});
 	},
@@ -133,10 +136,19 @@ dojo.mixin(dojox.gfx3d.drawer, {
 		// to redraw themselves to maintain the z-order.
 
 		// console.debug('chart draw');
-		dojo.forEach(this.todos, function(item){
+		arrayUtil.forEach(this.todos, function(item){
 			item.draw(viewport.lighting);
 		});
 	}
 	// More aggrasive optimization may re-order the DOM nodes using the order
 	// of objects, and only elements of todos call setShape.
-});
+};
+
+var api = { 
+	scheduler: gfx3d.scheduler,
+	drawer: gfx3d.drawer,
+	BinarySearchTree: BST
+};
+
+return api;
+});
\ No newline at end of file
diff --git a/dojox/gfx3d/tests/test_camerarotate.html b/dojox/gfx3d/tests/test_camerarotate.html
index e1cc4ab..cc6dee3 100644
--- a/dojox/gfx3d/tests/test_camerarotate.html
+++ b/dojox/gfx3d/tests/test_camerarotate.html
@@ -8,8 +8,6 @@
 	@import "../../../dijit/themes/tundra/tundra.css";
 </style>
 <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: false"></script>
-<script type="text/javascript" src="../object.js"></script>
-<script type="text/javascript" src="../scheduler.js"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.gfx3d");
@@ -36,7 +34,6 @@ rotate = function() {
 		m.cameraRotateYg(angles.y), 
 		m.cameraRotateZg(angles.z)
 		]);
-	console.debug(t);
 	view.setCameraTransform(t);
 	view.render();
 }
diff --git a/dojox/gfx3d/tests/test_camerarotate_shaded.html b/dojox/gfx3d/tests/test_camerarotate_shaded.html
index 6fa6ac4..fad5dbe 100644
--- a/dojox/gfx3d/tests/test_camerarotate_shaded.html
+++ b/dojox/gfx3d/tests/test_camerarotate_shaded.html
@@ -8,8 +8,6 @@
 		@import "../../../dijit/themes/tundra/tundra.css";
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: false"></script>
-	<script type="text/javascript" src="../object.js"></script>
-	<script type="text/javascript" src="../scheduler.js"></script>
 	<script type="text/javascript">
 
 		dojo.require("dojox.gfx3d");
diff --git a/dojox/gfx3d/tests/test_cylinder.html b/dojox/gfx3d/tests/test_cylinder.html
index cd1d5c1..d6edbb5 100644
--- a/dojox/gfx3d/tests/test_cylinder.html
+++ b/dojox/gfx3d/tests/test_cylinder.html
@@ -7,9 +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="../lighting.js"></script>
-<script type="text/javascript" src="../gradient.js"></script>
-<script type="text/javascript" src="../object.js"></script>
+
 <script type="text/javascript">
 
 dojo.require("dojox.gfx3d");
diff --git a/dojox/gfx3d/vector.js b/dojox/gfx3d/vector.js
index db62210..0a5609a 100644
--- a/dojox/gfx3d/vector.js
+++ b/dojox/gfx3d/vector.js
@@ -1,10 +1,11 @@
-dojo.provide("dojox.gfx3d.vector");
+define(["dojo/_base/lang", "dojo/_base/array", "./_base"],function(lang, arrayUtil, gfx3d) {
 
-dojo.mixin(dojox.gfx3d.vector, {
+gfx3d.vector =  {
+	
 	sum: function(){
 		// summary: sum of the vectors
 		var v = {x: 0, y: 0, z:0};
-		dojo.forEach(arguments, function(item){ v.x += item.x; v.y += item.y; v.z += item.z; });
+		arrayUtil.forEach(arguments, function(item){ v.x += item.x; v.y += item.y; v.z += item.z; });
 		return v;
 	},
 
@@ -14,7 +15,7 @@ dojo.mixin(dojox.gfx3d.vector, {
 		if(l == 0){
 			return {x: 0, y: 0, z: 0};
 		}
-		var v = dojox.gfx3d.vector.sum(arguments);
+		var v = gfx3d.vector.sum(arguments);
 		return {x: v.x/l, y: v.y/l, z: v.z/l};
 	},
 
@@ -42,8 +43,8 @@ dojo.mixin(dojox.gfx3d.vector, {
 		// d: Number: an x coordinate of a point
 		// e: Number: a y coordinate of a point
 		// f: Number: a z coordinate of a point
-		if(arguments.length == 6 && dojo.every(arguments, function(item){ return typeof item == "number"; })){
-			return dojox.gfx3d.vector._crossProduct(a, b, c, d, e, f); // Object
+		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
@@ -52,7 +53,7 @@ dojo.mixin(dojox.gfx3d.vector, {
 		// d: null
 		// e: null
 		// f: null
-		return dojox.gfx3d.vector._crossProduct(a.x, a.y, a.z, b.x, b.y, b.z); // Object
+		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){
@@ -74,8 +75,8 @@ dojo.mixin(dojox.gfx3d.vector, {
 		// d: Number: an x coordinate of a point
 		// e: Number: a y coordinate of a point
 		// f: Number: a z coordinate of a point
-		if(arguments.length == 6 && dojo.every(arguments, function(item){ return typeof item == "number"; })){
-			return dojox.gfx3d.vector._dotProduct(a, b, c, d, e, f); // Object
+		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
@@ -84,7 +85,7 @@ dojo.mixin(dojox.gfx3d.vector, {
 		// d: null
 		// e: null
 		// f: null
-		return dojox.gfx3d.vector._dotProduct(a.x, a.y, a.z, b.x, b.y, b.z); // Object
+		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){
@@ -99,8 +100,10 @@ dojo.mixin(dojox.gfx3d.vector, {
 			l = a; m = b; n = c;
 		}
 
-		var u = dojox.gfx3d.vector.substract(m, l);
-		var v = dojox.gfx3d.vector.substract(n, l);
-		return dojox.gfx3d.vector.crossProduct(u, v);
+		var u = gfx3d.vector.substract(m, l);
+		var v = gfx3d.vector.substract(n, l);
+		return gfx3d.vector.crossProduct(u, v);
 	}
+};
+	return gfx3d.vector;
 });
diff --git a/dojox/grid/DataGrid.js b/dojox/grid/DataGrid.js
index 9746080..f67c6c5 100644
--- a/dojox/grid/DataGrid.js
+++ b/dojox/grid/DataGrid.js
@@ -1,10 +1,17 @@
-dojo.provide("dojox.grid.DataGrid");
-
-dojo.require("dojox.grid._Grid");
-dojo.require("dojox.grid.DataSelection");
+define([
+	"../main",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/_base/json",
+	"dojo/_base/sniff",
+	"dojo/_base/declare",
+	"./_Grid",
+	"./DataSelection",
+	"dojo/_base/html"
+], function(dojox, array, lang, json, has, declare, _Grid, DataSelection, html){
 
 /*=====
-dojo.declare("dojox.grid.__DataCellDef", dojox.grid.__CellDef, {
+declare("dojox.grid.__DataCellDef", dojox.grid.__CellDef, {
 	constructor: function(){
 		//	field: String?
 		//		The attribute to read from the dojo.data item for the row.
@@ -19,7 +26,7 @@ dojo.declare("dojox.grid.__DataCellDef", dojox.grid.__CellDef, {
 =====*/
 
 /*=====
-dojo.declare("dojox.grid.__DataViewDef", dojox.grid.__ViewDef, {
+declare("dojox.grid.__DataViewDef", dojox.grid.__ViewDef, {
 	constructor: function(){
 		//	cells: dojox.grid.__DataCellDef[]|Array[dojox.grid.__DataCellDef[]]?
 		//		The structure of the cells within this grid.
@@ -32,7 +39,7 @@ dojo.declare("dojox.grid.__DataViewDef", dojox.grid.__ViewDef, {
 });
 =====*/
 
-dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
+var DataGrid = declare("dojox.grid.DataGrid", _Grid, {
 	store: null,
 	query: null,
 	queryOptions: null,
@@ -70,6 +77,10 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 	_isLoaded: false,
 	_isLoading: false,
 	
+	//keepSelection: Boolean
+	//		Whether keep selection after sort, filter etc.
+	keepSelection: false,	
+	
 	postCreate: function(){
 		this._pages = [];
 		this._store_connects = [];
@@ -81,9 +92,14 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 		this._setStore(this.store);
 		this.inherited(arguments);
 	},
+	
+	destroy: function(){
+		this.selection.destroy();
+		this.inherited(arguments);
+	},
 
 	createSelection: function(){
-		this.selection = new dojox.grid.DataSelection(this);
+		this.selection = new DataSelection(this);
 	},
 
 	get: function(inRowIndex, inItem){
@@ -101,7 +117,7 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 		}else if(inItem && this.fields){
 			var ret = [];
 			var s = this.grid.store;
-			dojo.forEach(this.fields, function(f){
+			array.forEach(this.fields, function(f){
 				ret = ret.concat(s.getValues(inItem, f));
 			});
 			return ret;
@@ -142,7 +158,7 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 	},
 	
 	_createItem: function(item, index){
-		var idty = this._hasIdentity ? this.store.getIdentity(item) : dojo.toJson(this.query) + ":idx:" + index + ":sort:" + dojo.toJson(this.getSortProps());
+		var idty = this._hasIdentity ? this.store.getIdentity(item) : json.toJson(this.query) + ":idx:" + index + ":sort:" + json.toJson(this.getSortProps());
 		var o = this._by_idty[idty] = { idty: idty, item: item };
 		return o;
 	},
@@ -187,6 +203,10 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 				this.showMessage(this.noDataMessage);
 			}
 		}
+		if(this.selection.isSelected(idx)){
+			this.selection.deselect(idx);
+			this.selection.selected.splice(idx, 1);
+		}
 	},
 
 	_onRevert: function(){
@@ -194,12 +214,18 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 	},
 
 	setStore: function(store, query, queryOptions){
+		if(this._requestsPending(0)){
+			return;
+		}
 		this._setQuery(query, queryOptions);
 		this._setStore(store);
 		this._refresh(true);
 	},
 	
 	setQuery: function(query, queryOptions){
+		if(this._requestsPending(0)){
+			return;
+		}
 		this._setQuery(query, queryOptions);
 		this._refresh(true);
 	},
@@ -217,7 +243,7 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 
 	_setStore: function(store){
 		if(this.store && this._store_connects){
-			dojo.forEach(this._store_connects, this.disconnect, this);
+			array.forEach(this._store_connects, this.disconnect, this);
 		}
 		this.store = store;
 
@@ -269,7 +295,7 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 		if(!this.scroller){ return; }
 		if(items && items.length > 0){
 			//console.log(items);
-			dojo.forEach(items, function(item, idx){
+			array.forEach(items, function(item, idx){
 				this._addItem(item, req.start+idx, true);
 			}, this);
 			this.updateRows(req.start, items.length);
@@ -279,6 +305,9 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 			}else if(this._lastScrollTop){
 				this.setScrollTop(this._lastScrollTop);
 			}
+			if(has("ie")){
+				html.setSelectable(this.domNode, this.selectable);
+			}	
 		}
 		delete this._lastScrollTop;
 		if(!this._isLoaded){
@@ -326,7 +355,7 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 					
 					// Load them if we need to
 					var waitCount = 0;
-					dojo.forEach(items, function(i){
+					array.forEach(items, function(i){
 						if(!store.isItemLoaded(i)){ waitCount++; }
 					});
 					if(waitCount === 0){
@@ -338,7 +367,7 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 								this._onFetchComplete(items, req);
 							}
 						};
-						dojo.forEach(items, function(i){
+						array.forEach(items, function(i){
 							if(!store.isItemLoaded(i)){
 								store.loadItem({item: i, onItem: onItem, scope: this});
 							}
@@ -352,9 +381,9 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 						sort: this.getSortProps(),
 						queryOptions: this.queryOptions,
 						isRender: isRender,
-						onBegin: dojo.hitch(this, "_onFetchBegin"),
-						onComplete: dojo.hitch(this, "_onFetchComplete"),
-						onError: dojo.hitch(this, "_onFetchError")
+						onBegin: lang.hitch(this, "_onFetchBegin"),
+						onComplete: lang.hitch(this, "_onFetchComplete"),
+						onError: lang.hitch(this, "_onFetchError")
 					});
 				}
 			}catch(e){
@@ -459,7 +488,7 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 		if(count > 0){
 			this._requests++;
 			if(!this._requestsPending(row)){
-				setTimeout(dojo.hitch(this, "_fetch", row, false), 1);
+				setTimeout(lang.hitch(this, "_fetch", row, false), 1);
 				//this.requestRows(row, count);
 			}
 		}
@@ -545,7 +574,7 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 	doApplyCellEdit: function(inValue, inRowIndex, inAttrName){
 		this.store.fetchItemByIdentity({
 			identity: this._by_idx[inRowIndex].idty,
-			onItem: dojo.hitch(this, function(item){
+			onItem: lang.hitch(this, function(item){
 				var oldValue = this.store.getValue(item, inAttrName);
 				if(typeof oldValue == 'number'){
 					inValue = isNaN(inValue) ? inValue : parseFloat(inValue);
@@ -587,9 +616,9 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 		//		Remove the selected rows from the grid.
 		if(this._canEdit){
 			this.edit.apply();
-			var fx = dojo.hitch(this, function(items){
+			var fx = lang.hitch(this, function(items){
 				if(items.length){
-					dojo.forEach(items, this.store.deleteItem, this.store);
+					array.forEach(items, this.store.deleteItem, this.store);
 					this.selection.clear();
 				}
 			});
@@ -605,13 +634,13 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 	}
 });
 
-dojox.grid.DataGrid.cell_markupFactory = function(cellFunc, node, cellDef){
-	var field = dojo.trim(dojo.attr(node, "field")||"");
+DataGrid.cell_markupFactory = function(cellFunc, node, cellDef){
+	var field = lang.trim(html.attr(node, "field")||"");
 	if(field){
 		cellDef.field = field;
 	}
 	cellDef.field = cellDef.field||cellDef.name;
-	var fields = dojo.trim(dojo.attr(node, "fields")||"");
+	var fields = lang.trim(html.attr(node, "fields")||"");
 	if(fields){
 		cellDef.fields = fields.split(",");
 	}
@@ -620,7 +649,11 @@ dojox.grid.DataGrid.cell_markupFactory = function(cellFunc, node, cellDef){
 	}
 };
 
-dojox.grid.DataGrid.markupFactory = function(props, node, ctor, cellFunc){
-	return dojox.grid._Grid.markupFactory(props, node, ctor,
-					dojo.partial(dojox.grid.DataGrid.cell_markupFactory, cellFunc));
+DataGrid.markupFactory = function(props, node, ctor, cellFunc){
+	return _Grid.markupFactory(props, node, ctor,
+					lang.partial(DataGrid.cell_markupFactory, cellFunc));
 };
+
+return DataGrid;
+
+});
\ No newline at end of file
diff --git a/dojox/grid/DataSelection.js b/dojox/grid/DataSelection.js
index 1c65860..d570a4e 100644
--- a/dojox/grid/DataSelection.js
+++ b/dojox/grid/DataSelection.js
@@ -1,9 +1,24 @@
-dojo.provide("dojox.grid.DataSelection");
-dojo.require("dojox.grid.Selection");
-
-dojo.declare("dojox.grid.DataSelection", dojox.grid.Selection, {
+define([
+	"dojo/_base/declare",
+	"./_SelectionPreserver",
+	"./Selection"
+], function(declare, _SelectionPreserver, Selection){
+	
+return declare("dojox.grid.DataSelection", Selection, {
+	constructor: function(grid){
+		if(grid.keepSelection){
+			this.preserver = new _SelectionPreserver(this);
+		}
+	},
+	
+	destroy: function(){
+		if(this.preserver){
+			this.preserver.destroy();
+		}
+	},
+	
 	getFirstSelected: function(){
-		var idx = dojox.grid.Selection.prototype.getFirstSelected.call(this);
+		var idx = Selection.prototype.getFirstSelected.call(this);
 
 		if(idx == -1){ return null; }
 		return this.grid.getItem(idx);
@@ -11,7 +26,7 @@ dojo.declare("dojox.grid.DataSelection", dojox.grid.Selection, {
 
 	getNextSelected: function(inPrev){
 		var old_idx = this.grid.getItemIndex(inPrev);
-		var idx = dojox.grid.Selection.prototype.getNextSelected.call(this, old_idx);
+		var idx = Selection.prototype.getNextSelected.call(this, old_idx);
 
 		if(idx == -1){ return null; }
 		return this.grid.getItem(idx);
@@ -35,7 +50,7 @@ dojo.declare("dojox.grid.DataSelection", dojox.grid.Selection, {
 		}else{
 			idx = this.grid.getItemIndex(inItemOrIndex);
 		}
-		dojox.grid.Selection.prototype.addToSelection.call(this, idx);
+		Selection.prototype.addToSelection.call(this, idx);
 	},
 
 	deselect: function(inItemOrIndex){
@@ -46,7 +61,7 @@ dojo.declare("dojox.grid.DataSelection", dojox.grid.Selection, {
 		}else{
 			idx = this.grid.getItemIndex(inItemOrIndex);
 		}
-		dojox.grid.Selection.prototype.deselect.call(this, idx);
+		Selection.prototype.deselect.call(this, idx);
 	},
 
 	deselectAll: function(inItemOrIndex){
@@ -57,9 +72,10 @@ dojo.declare("dojox.grid.DataSelection", dojox.grid.Selection, {
 			}else{
 				idx = this.grid.getItemIndex(inItemOrIndex);
 			}
-			dojox.grid.Selection.prototype.deselectAll.call(this, idx);
+			Selection.prototype.deselectAll.call(this, idx);
 		}else{
 			this.inherited(arguments);
 		}
 	}
 });
+});
\ No newline at end of file
diff --git a/dojox/grid/EnhancedGrid.js b/dojox/grid/EnhancedGrid.js
index 86c6cba..e8984e4 100644
--- a/dojox/grid/EnhancedGrid.js
+++ b/dojox/grid/EnhancedGrid.js
@@ -1,12 +1,24 @@
-dojo.provide("dojox.grid.EnhancedGrid");
-
-dojo.require("dojox.grid.DataGrid");
-dojo.require("dojox.grid.enhanced._PluginManager");
-dojo.requireLocalization("dojox.grid.enhanced", "EnhancedGrid");
+define([
+	"dojo/_base/kernel",
+	"../main",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"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){
 
 dojo.experimental("dojox.grid.EnhancedGrid");
 
-dojo.declare("dojox.grid.EnhancedGrid", dojox.grid.DataGrid, {
+var EnhancedGrid = declare("dojox.grid.EnhancedGrid", DataGrid, {
 	// summary:
 	//		Provides enhanced features based on DataGrid
 	//
@@ -60,17 +72,13 @@ dojo.declare("dojox.grid.EnhancedGrid", dojox.grid.DataGrid, {
 	//		Singleton plugin manager
 	pluginMgr: null,
 
-	//keepSelection: Boolean
-	//		Whether keep selection after sort, filter, pagination etc.
-	keepSelection: false,
-	
 	//_pluginMgrClass: Object
 	//		Default plugin manager class
-	_pluginMgrClass: dojox.grid.enhanced._PluginManager,
+	_pluginMgrClass: _PluginManager,
 
 	postMixInProperties: function(){
 		//load nls bundle
-		this._nls = dojo.i18n.getLocalization("dojox.grid.enhanced", "EnhancedGrid", this.lang);
+		this._nls = i18n.getLocalization("dojox.grid.enhanced", "EnhancedGrid", this.lang);
 		this.inherited(arguments);
 	},
 	postCreate: function(){
@@ -125,7 +133,7 @@ dojo.declare("dojox.grid.EnhancedGrid", dojox.grid.DataGrid, {
 			}
 			props[p] = source[p];
 		}
-		dojo.mixin(target, props);
+		lang.mixin(target, props);
 	},
 	_copyAttr: function(idx, attr){
 		// summary:
@@ -139,7 +147,7 @@ dojo.declare("dojox.grid.EnhancedGrid", dojox.grid.DataGrid, {
 		//		Overwritten, see _Grid._getHeaderHeight()
 		//		Should include borders/margins of this.viewsHeaderNode
 		this.inherited(arguments);
-		return dojo.marginBox(this.viewsHeaderNode).h;
+		return domGeometry.getMarginBox(this.viewsHeaderNode).h;
 	},
 	_fetch: function(start, isRender){
 		// summary:
@@ -162,9 +170,9 @@ dojo.declare("dojox.grid.EnhancedGrid", dojox.grid.DataGrid, {
 					sort: this.getSortProps(),
 					queryOptions: this.queryOptions,
 					isRender: isRender,
-					onBegin: dojo.hitch(this, "_onFetchBegin"),
-					onComplete: dojo.hitch(this, "_onFetchComplete"),
-					onError: dojo.hitch(this, "_onFetchError")
+					onBegin: lang.hitch(this, "_onFetchBegin"),
+					onComplete: lang.hitch(this, "_onFetchComplete"),
+					onError: lang.hitch(this, "_onFetchError")
 				};
 				this._storeLayerFetch(req);
 			}catch(e){
@@ -179,7 +187,7 @@ dojo.declare("dojox.grid.EnhancedGrid", dojox.grid.DataGrid, {
 		this.store.fetch(req);
 	},
 	getCellByField: function(field){
-		return dojo.filter(this.layout.cells, function(cell){
+		return array.filter(this.layout.cells, function(cell){
 			return cell.field == field;
 		})[0];
 	},
@@ -188,7 +196,7 @@ dojo.declare("dojox.grid.EnhancedGrid", dojox.grid.DataGrid, {
 		// summary
 		//		Overwrite: rewrite getCellX of view.header
 		var view = this.inherited(arguments);
-		if(dojo.isMoz){
+		if(has('mozilla')){
 			var ascendDom = function(inNode, inWhile){
 				for(var n = inNode; n && inWhile(n); n = n.parentNode){}
 				return n;
@@ -202,7 +210,7 @@ dojo.declare("dojox.grid.EnhancedGrid", dojox.grid.DataGrid, {
 			view.header.getCellX = function(e){
 				var x = func.call(view.header, e);
 				var n = ascendDom(e.target, makeNotTagName("th"));
-				if(n && n !== e.target && dojo.isDescendant(e.target, n)){ x += n.firstChild.offsetLeft; }
+				if(n && n !== e.target && dom.isDescendant(e.target, n)){ x += n.firstChild.offsetLeft; }
 				return x;
 			};
 		}
@@ -212,19 +220,18 @@ dojo.declare("dojox.grid.EnhancedGrid", dojox.grid.DataGrid, {
 		// summary:
 		//		Destroy all resources
 		delete this._nls;
-		this.selection.destroy();
 		this.pluginMgr.destroy();
 		this.inherited(arguments);
 	}
 });
 
-dojo.provide("dojox.grid.enhanced.DataSelection");
-dojo.require("dojox.grid.enhanced.plugins._SelectionPreserver");//default loaded plugin
-
-dojo.declare("dojox.grid.enhanced.DataSelection", dojox.grid.DataSelection, {
+declare("dojox.grid.enhanced.DataSelection", DataSelection, {
 	constructor: function(grid){
 		if(grid.keepSelection){
-			this.preserver = new dojox.grid.enhanced.plugins._SelectionPreserver(this);
+			if(this.preserver){
+				this.preserver.destroy();
+			}
+			this.preserver = new _SelectionPreserver(this);
 		}
 	},
 	_range: function(inFrom, inTo){
@@ -238,19 +245,18 @@ dojo.declare("dojox.grid.enhanced.DataSelection", dojox.grid.DataSelection, {
 		this.inherited(arguments);
 		this.grid._selectingRange = false;
 		this.onChanged();
-	},
-	destroy: function(){
-		if(this.preserver){
-			this.preserver.destroy();
-		}
 	}
 });
 
-dojox.grid.EnhancedGrid.markupFactory = function(props, node, ctor, cellFunc){
+EnhancedGrid.markupFactory = function(props, node, ctor, cellFunc){
 	return dojox.grid._Grid.markupFactory(props, node, ctor,
-					dojo.partial(dojox.grid.DataGrid.cell_markupFactory, cellFunc));
+					lang.partial(DataGrid.cell_markupFactory, cellFunc));
+};
+
+EnhancedGrid.registerPlugin = function(clazz, props){
+	_PluginManager.registerPlugin(clazz, props);
 };
 
-dojox.grid.EnhancedGrid.registerPlugin = function(clazz, props){
-	dojox.grid.enhanced._PluginManager.registerPlugin(clazz, props);
-};
\ No newline at end of file
+return EnhancedGrid;
+
+});
\ No newline at end of file
diff --git a/dojox/grid/LazyTreeGrid.js b/dojox/grid/LazyTreeGrid.js
index 666cf1d..77f4e98 100644
--- a/dojox/grid/LazyTreeGrid.js
+++ b/dojox/grid/LazyTreeGrid.js
@@ -1,111 +1,116 @@
-dojo.provide("dojox.grid.LazyTreeGrid");
-
-dojo.require("dojox.grid._View");
-dojo.require("dojox.grid.TreeGrid");
-dojo.require("dojox.grid.cells.tree");
-dojo.require("dojox.grid.LazyTreeGridStoreModel");
-
-dojo.declare("dojox.grid._LazyExpando", [dijit._Widget, dijit._Templated], {
-	itemId: "",
-	cellIdx: -1,
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/event",
+	"dojo/_base/array",
+	"dojo/query",
+	"dojo/parser",
+	"dojo/dom-construct",
+	"dojo/dom-class",
+	"dojo/dom-style",
+	"dojo/dom-geometry",
+	"dojo/dom",
+	"dojo/keys",	
+	"dojo/text!./resources/Expando.html",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"./TreeGrid",
+	"./_Builder",
+	"./_View",
+	"./_Layout",
+	"./cells/tree",
+	"./_RowManager",
+	"./_FocusManager",
+	"./_EditManager",
+	"./DataSelection",
+	"./util"
+], function(dojo, declare, lang, event, array, query, parser, domConstruct,
+	domClass, domStyle, domGeometry, dom, keys, template, _widget, _templatedMixin,
+	TreeGrid, _Builder, _View, _Layout, TreeCell, _RowManager, _FocusManager, _EditManager, DataSelection, util){
+		
+var _LazyExpando = declare("dojox.grid._LazyExpando", [_widget, _templatedMixin], {
+	grid: null,
 	view: null,
 	rowIdx: -1,
-	expandoCell: null,
+	cellIdx: -1,
 	level: 0,
-	open: false,
-	templatePath: dojo.moduleUrl("dojox.grid", "resources/Expando.html"),
-	
-	onToggle: function(event){
-		// Summary
-		//		Function for expand/collapse row
-		this.setOpen(!this.view.grid.cache.getExpandoStatusByRowIndex(this.rowIdx));
-		try{
-			dojo.stopEvent(event);
-		}catch(e){}
+	itemId: "",
+	templateString: template,
+	onToggle: function(evt){
+		// summary:
+		//		The onclick handler of expando, expand/collapse a tree node if has children.
+		if(this.grid._treeCache.items[this.rowIdx]){
+			this.grid.focus.setFocusIndex(this.rowIdx, this.cellIdx);
+			this.setOpen(!this.grid._treeCache.items[this.rowIdx].opened);
+			try{
+				event.stop(evt);
+			}catch(e){}
+		}
 	},
-	
 	setOpen: function(open){
-		var g = this.view.grid,
-			item = g.cache.getItemByRowIndex(this.rowIdx);
-		if(!g.treeModel.mayHaveChildren(item)){
-			g.stateChangeNode = null;
-			return;
-		}
-		if(item && !g._loading){
-			g.stateChangeNode = this.domNode;
-			g.cache.updateCache(this.rowIdx, {"expandoStatus": open});
+		// summary:
+		//		expand/collapse the row where the expando is in.
+		var g = this.grid,
+			item = g._by_idx[this.rowIdx].item;
+		if(item && g.treeModel.mayHaveChildren(item) && !g._loading && g._treeCache.items[this.rowIdx].opened !== open){
+			g._treeCache.items[this.rowIdx].opened = open;
 			g.expandoFetch(this.rowIdx, open);
-			this.open = open;
+			this._updateOpenState(item);
 		}
-		this._updateOpenState(item);
 	},
-	
 	_updateOpenState: function(item){
-		// Summary
-		//		Update the expando icon
-		var grid = this.view.grid;
-		if(item && grid.treeModel.mayHaveChildren(item)){
-			var state = grid.cache.getExpandoStatusByRowIndex(this.rowIdx);
+		var g = this.grid, state;
+		if(item && g.treeModel.mayHaveChildren(item)){
+			state = g._treeCache.items[this.rowIdx].opened;
 			this.expandoInner.innerHTML = state ? "-" : "+";
-			dojo.toggleClass(this.domNode, "dojoxGridExpandoOpened", state);
-			dijit.setWaiState(this.domNode.parentNode, "expanded", state);
+			domClass.toggle(this.domNode, "dojoxGridExpandoOpened", state);
+			this.domNode.parentNode.setAttribute("aria-expanded", state);
+		}else{
+			domClass.remove(this.domNode, "dojoxGridExpandoOpened");
 		}
 	},
-	
 	setRowNode: function(rowIdx, rowNode, view){
-		if(this.cellIdx < 0 || !this.itemId){ return false; }
-		this._initialized = false;
+		if(this.cellIdx < 0 || !this.itemId){
+			return false;
+		}
 		this.view = view;
+		this.grid = view.grid;
 		this.rowIdx = rowIdx;
-		this.expandoCell = view.structure.cells[0][this.cellIdx];
-		var d = this.domNode;
-		if(d && d.parentNode && d.parentNode.parentNode){
-			this._tableRow = d.parentNode.parentNode;
-		}
-		dojo.style(this.domNode , "marginLeft" , (this.level * 1.125) + "em");
-		this._updateOpenState(view.grid.cache.getItemByRowIndex(this.rowIdx));
+		var marginPos = this.grid.isLeftToRight() ? "marginLeft" : "marginRight";
+		domStyle.set(this.domNode.parentNode, marginPos, (this.level * 1.125) + "em");
+		this._updateOpenState(this.grid._by_idx[this.rowIdx].item);
 		return true;
 	}
 });
 
-dojo.declare("dojox.grid._TreeGridContentBuilder", dojox.grid._ContentBuilder, {
-	// summary:
-	//		Could create row content innerHTML by different appoarch for different data structure
-	generateHtml: function(inDataIndex, inRowIndex){
-		// summary:
-		//		create row innterHTML for flat data structure
+var _TreeGridContentBuilder = declare("dojox.grid._TreeGridContentBuilder", _Builder._ContentBuilder, {
+	generateHtml: function(inDataIndex, rowIndex){
 		var html = this.getTableArray(),
 			grid = this.grid,
 			v = this.view,
 			cells = v.structure.cells,
-			item = grid.getItem(inRowIndex),
+			item = grid.getItem(rowIndex),
 			level = 0,
-			treePath = grid.cache.getTreePathByRowIndex(inRowIndex),
-			rowStack = [],
-			toggleClasses = [];
-			
-		dojox.grid.util.fire(this.view, "onBeforeRow", [inRowIndex, cells]);
-			
-		if(item !== null && treePath !== null){
-			rowStack = treePath.split("/");
-			level = rowStack.length - 1;
-			toggleClasses[0] = "dojoxGridRowToggle-" + rowStack.join("-");
-			if(!grid.treeModel.mayHaveChildren(item)){
-				toggleClasses.push("dojoxGridNoChildren");
-			}
-		}
-		
-		for(var j = 0, row; (row = cells[j]); j++){
+			toggleClass = "",
+			treePath = grid._treeCache.items[rowIndex] ? grid._treeCache.items[rowIndex].treePath : null;
+		util.fire(this.view, "onBeforeRow", [rowIndex, cells]);
+		if(item && lang.isArray(treePath)){
+			level = treePath.length;
+			toggleClass = grid.treeModel.mayHaveChildren(item) ? "" : "dojoxGridNoChildren";
+		}
+		var i = 0, j = 0, row, cell,
+			mergedCells, totalWidth = 0, totalWidthes = [];
+		for(; row = cells[j]; j++){
 			if(row.hidden || row.header){
 				continue;
 			}
-			var tr = '<tr style="" class="' + toggleClasses.join(' ') + '" dojoxTreeGridPath="' + rowStack.join('/') + '" dojoxTreeGridBaseClasses="' + toggleClasses.join(' ') + '">';
-			html.push(tr);
-			var k = 0, mergedCells = this._getColSpans(level);
-			var totalWidth = 0, totalWidthes = [];
+			html.push('<tr class="' + toggleClass + '">');
+			// cell merge
+			mergedCells = this._getColSpans(level);
 			if(mergedCells){
-				dojo.forEach(mergedCells, function(c){
-					for(var i = 0, cell;(cell = row[i]); i++){
+				array.forEach(mergedCells, function(c){
+					for(i = 0; cell = row[i]; i++){
 						if(i >= c.start && i <= c.end){
 							totalWidth += this._getCellWidth(row, i);
 						}
@@ -114,18 +119,17 @@ dojo.declare("dojox.grid._TreeGridContentBuilder", dojox.grid._ContentBuilder, {
 					totalWidth = 0;
 				}, this);
 			}
-			for(var i = 0, cell, m, cc, cs; (cell = row[i]); i++){
+			var m, cc, cs, pbm, k = 0;
+			for(i = 0; cell = row[i]; i++){
 				m = cell.markup;
 				cc = cell.customClasses = [];
 				cs = cell.customStyles = [];
 				if(mergedCells && mergedCells[k] && (i >= mergedCells[k].start && i <= mergedCells[k].end)){
-					var primaryIdx = mergedCells[k].primary ? mergedCells[k].primary : mergedCells[k].start;
+					var primaryIdx = mergedCells[k].primary || mergedCells[k].start;
 					if(i == primaryIdx){
-						m[5] = cell.formatAtLevel(rowStack, item, level, false, toggleClasses[0], cc, inRowIndex);
-						// classes
+						m[5] = cell.formatAtLevel(item, level, rowIndex);
 						m[1] = cc.join(' ');
-						// styles
-						var pbm = dojo.marginBox(cell.getHeaderNode()).w - dojo.contentBox(cell.getHeaderNode()).w;
+						pbm = domGeometry.getMarginBox(cell.getHeaderNode()).w - domGeometry.getContentBox(cell.getHeaderNode()).w;
 						cs = cell.customStyles = ['width:' + (totalWidthes[k] - pbm) + "px"];
 						m[3] = cs.join(';');
 						html.push.apply(html, m);
@@ -136,300 +140,217 @@ dojo.declare("dojox.grid._TreeGridContentBuilder", dojox.grid._ContentBuilder, {
 						continue;
 					}
 				}else{
-					// content (format can fill in cc and cs as side-effects)
-					// m[5] = cell.format(inRowIndex, item);
-					m[5] = cell.formatAtLevel(rowStack, item, level, false, toggleClasses[0], cc, inRowIndex);
-					// classes
+					m[5] = cell.formatAtLevel(item, level, rowIndex);
 					m[1] = cc.join(' ');
-					// styles
 					m[3] = cs.join(';');
-					// in-place concat
 					html.push.apply(html, m);
 				}
-				
 			}
 			html.push('</tr>');
 		}
 		html.push('</table>');
 		return html.join(''); // String
 	},
-
 	_getColSpans: function(level){
-		// summary:
-		//		handle the column span object
 		var colSpans = this.grid.colSpans;
-		if(colSpans && (colSpans[level])){
-			return colSpans[level];
-		}else{
-			return null;
-		}
+		return colSpans && colSpans[level] ? colSpans[level] : null;
 	},
-	
 	_getCellWidth: function(cells, colIndex){
-		// summary:
-		//		calculate column width by header cell's size
-		var node = cells[colIndex].getHeaderNode();
-		if(colIndex == cells.length - 1 || dojo.every(cells.slice(colIndex + 1), function(cell){
+		var curCell = cells[colIndex], node = curCell.getHeaderNode();
+		if(curCell.hidden){
+			return 0;
+		}
+		if(colIndex == cells.length - 1 || array.every(cells.slice(colIndex + 1), function(cell){
 			return cell.hidden;
 		})){
-			var headerNodePos = dojo.position(cells[colIndex].view.headerContentNode.firstChild);
-			return headerNodePos.x + headerNodePos.w - dojo.position(node).x;
+			var headerNodePos = domGeometry.position(cells[colIndex].view.headerContentNode.firstChild);
+			return headerNodePos.x + headerNodePos.w - domGeometry.position(node).x;
 		}else{
-			var nextNode = cells[colIndex + 1].getHeaderNode();
-			return dojo.position(nextNode).x - dojo.position(node).x;
+			var nextCell;
+			do{
+				nextCell = cells[++colIndex];
+			}while(nextCell.hidden);
+			return domGeometry.position(nextCell.getHeaderNode()).x - domGeometry.position(node).x;
 		}
 	}
 });
 
-dojo.declare("dojox.grid._TreeGridView", [dojox.grid._View], {
-	
-	_contentBuilderClass: dojox.grid._TreeGridContentBuilder,
-	
+declare("dojox.grid._TreeGridView", _View, {
+	_contentBuilderClass: _TreeGridContentBuilder,
 	postCreate: function(){
 		this.inherited(arguments);
 		this._expandos = {};
-		this.connect(this.grid, '_cleanupExpandoCache', '_cleanupExpandoCache');
+		this.connect(this.grid, '_onCleanupExpandoCache', '_cleanupExpandoCache');
 	},
-	
-	_cleanupExpandoCache: function(index, identity, item){
-		if(index == -1){
-			return;
-		}
-		dojo.forEach(this.grid.layout.cells, function(cell){
-			if(cell.openStates && identity in cell.openStates){
-				delete cell.openStates[identity];
-			}
-		});
-		for(var i in this._expandos){
-			if(this._expandos[i]){
+	destroy: function(){
+		this._cleanupExpandoCache();
+		this.inherited(arguments);
+	},
+	_cleanupExpandoCache: function(identity){
+		if(identity && this._expandos[identity]){
+			this._expandos[identity].destroy();
+			delete this._expandos[identity];
+		}else{
+			var i;
+			for(i in this._expandos){
 				this._expandos[i].destroy();
 			}
+			this._expandos = {};
 		}
-		this._expandos = {};
 	},
-
-	onAfterRow: function(inRowIndex, cells, inRowNode){
-		// summary:
-		//		parse the expando of each row to a widget
-		dojo.query("span.dojoxGridExpando", inRowNode).forEach(function(n){
+	onAfterRow: function(rowIndex, cells, rowNode){
+		query("span.dojoxGridExpando", rowNode).forEach(function(n){
 			if(n && n.parentNode){
-				// Either create our expando or put the existing expando back
-				// into place
 				var idty, expando, _byIdx = this.grid._by_idx;
-				if(_byIdx && _byIdx[inRowIndex] && _byIdx[inRowIndex].idty){
-					idty = _byIdx[inRowIndex].idty;
+				if(_byIdx && _byIdx[rowIndex] && _byIdx[rowIndex].idty){
+					idty = _byIdx[rowIndex].idty;
 					expando = this._expandos[idty];
 				}
 				if(expando){
-					dojo.place(expando.domNode, n, "replace");
+					domConstruct.place(expando.domNode, n, "replace");
 					expando.itemId = n.getAttribute("itemId");
 					expando.cellIdx = parseInt(n.getAttribute("cellIdx"), 10);
 					if(isNaN(expando.cellIdx)){
 						expando.cellIdx = -1;
 					}
 				}else{
-					expando = dojo.parser.parse(n.parentNode)[0];
+					expando = parser.parse(n.parentNode)[0];
 					if(idty){
 						this._expandos[idty] = expando;
 					}
 				}
-				if(!expando.setRowNode(inRowIndex, inRowNode, this)){
+				if(!expando.setRowNode(rowIndex, rowNode, this)){
 					expando.domNode.parentNode.removeChild(expando.domNode);
 				}
+				domConstruct.destroy(n);
 			}
 		}, this);
 		this.inherited(arguments);
+	},
+	updateRow: function(rowIndex){
+		var grid = this.grid, item;
+		if(grid.keepSelection){
+			item = grid.getItem(rowIndex);
+			if(item){
+				grid.selection.preserver._reSelectById(item, rowIndex);
+			}
+		}
+		this.inherited(arguments);
 	}
-	
 });
 
-dojox.grid.cells.LazyTreeCell = dojo.mixin(dojo.clone(dojox.grid.cells.TreeCell), {
-	formatAtLevel: function(inRowIndexes, inItem, level, summaryRow, toggleClass, cellClasses, inRowIndex){
-		if(!inItem){
-			return this.formatIndexes(inRowIndex, inRowIndexes, inItem, level);
-		}
-		if(!dojo.isArray(inRowIndexes)){
-			inRowIndexes = [inRowIndexes];
-		}
-		var result = "";
-		var ret = "";
-		if(this.isCollapsable){
-			var store = this.grid.store, id = "";
-			if(inItem && store.isItem(inItem)){
-				id = store.getIdentity(inItem);
-			}
-			cellClasses.push("dojoxGridExpandoCell");
-			ret = '<span ' + dojo._scopeName + 'Type="dojox.grid._LazyExpando" level="' + level + '" class="dojoxGridExpando"' +
-					'" toggleClass="' + toggleClass + '" itemId="' + id + '" cellIdx="' + this.index + '"></span>';
+var LazyTreeCell = lang.mixin(lang.clone(TreeCell), {
+	formatAtLevel: function(item, level, rowIndex){
+		if(!item){
+			return this.formatIndexes(rowIndex, item, level);
 		}
-		result = ret + this.formatIndexes(inRowIndex, inRowIndexes, inItem, level);
-		if(this.grid.focus.cell && this.index == this.grid.focus.cell.index && inRowIndexes.join('/') == this.grid.focus.rowIndex){
-			cellClasses.push(this.grid.focus.focusClass);
+		var result = "", ret = "", content;
+		if(this.isCollapsable && this.grid.store.isItem(item)){
+			ret = '<span ' + dojo._scopeName + 'Type="dojox.grid._LazyExpando" level="' + level + '" class="dojoxGridExpando"' +
+					' itemId="' + this.grid.store.getIdentity(item) + '" cellIdx="' + this.index + '"></span>';
 		}
+		content = this.formatIndexes(rowIndex, item, level);
+		result = ret !== "" ? '<div>' + ret + content + '</div>' : content;
 		return result;
 	},
-	
-	formatIndexes: function(inRowIndex, inRowIndexes, inItem, level){
+	formatIndexes: function(rowIndex, item, level){
 		var info = this.grid.edit.info,
-			d = this.get ? this.get(inRowIndexes[0], inItem, inRowIndexes) : (this.value || this.defaultValue);
-		if(this.editable && (this.alwaysEditing || (info.rowIndex == inRowIndexes[0] && info.cell == this))){
-			return this.formatEditing(d, inRowIndex, inRowIndexes);
+			d = this.get ? this.get(rowIndex, item) : (this.value || this.defaultValue);
+		if(this.editable && (this.alwaysEditing || (info.rowIndex === rowIndex && info.cell === this))){
+			return this.formatEditing(d, rowIndex);
 		}else{
-			return this._defaultFormat(d, [d, inRowIndex, level, this]);
+			return this._defaultFormat(d, [d, rowIndex, level, this]);
 		}
 	}
 });
 
-dojo.declare("dojox.grid._LazyTreeLayout", dojox.grid._Layout, {
+var _LazyTreeLayout = declare("dojox.grid._LazyTreeLayout", _Layout, {
 	// summary:
 	//		Override the dojox.grid._TreeLayout to modify the _TreeGridView and cell formatter
-	setStructure: function(inStructure){
-		var s = inStructure;
-		var g = this.grid;
-		if(g && !dojo.every(s, function(i){
-			return ("cells" in i);
+	setStructure: function(structure){
+		var g = this.grid, s = structure;
+		if(g && !array.every(s, function(i){
+			return !!i.cells;
 		})){
 			s = arguments[0] = [{cells:[s]}];//intentionally change arguments[0]
 		}
-		if(s.length == 1 && s[0].cells.length == 1){
+		if(s.length === 1 && s[0].cells.length === 1){
 			s[0].type = "dojox.grid._TreeGridView";
 			this._isCollapsable = true;
 			s[0].cells[0][this.grid.expandoCell].isCollapsable = true;
 		}
 		this.inherited(arguments);
 	},
-	
-	addCellDef: function(inRowIndex, inCellIndex, inDef){
+	addCellDef: function(rowIndex, cellIndex, def){
 		var obj = this.inherited(arguments);
-		return dojo.mixin(obj, dojox.grid.cells.LazyTreeCell);
+		return lang.mixin(obj, LazyTreeCell);
 	}
 });
 
-dojo.declare("dojox.grid.TreeGridItemCache", null, {
-	
-	unInit: true,
-	
-	items: null,
-	
-	constructor: function(grid){
-		this.rowsPerPage = grid.rowsPerPage;
-		this._buildCache(grid.rowsPerPage);
-	},
-	
-	_buildCache: function(size){
-		// Summary
-		//		Build the cache only with the treepath using given size
+var _LazyTreeGridCache = declare("dojox.grid._LazyTreeGridCache", null, {
+	// summary:
+	//		An internal object used to cache the tree path and open state of each item.
+	//		The form of the cache items would be an object array: 
+	//		[{opened: true/false, treePath: [level0 parent id, level1 parent id, ...]}]
+	// example:
+	//		| [{opened: true, treePath: []},
+	//		|  {opened: false, treePath: ["root0"]},
+	//		|  {opened: false, treePath: ["root0"]},
+	//		|  {opened: false, treePath: []},
+	//		|  ...]
+	constructor: function(){
 		this.items = [];
-		for(var i = 0; i < size; i++){
-			this.cacheItem(i, {item: null, treePath: i + "", expandoStatus: false});
-		}
-	},
-	
-	cacheItem: function(/*integer*/rowIdx, cacheObj){
-		// Summary
-		//		Add an item and its tree structure information to the cache.
-		this.items[rowIdx] = dojo.mixin({
-			item: null,
-			treePath: "",
-			expandoStatus: false
-		}, cacheObj);
-	},
-	
-	insertItem: function(/*integer*/rowIdx, cacheObj){
-		this.items.splice(rowIdx, 0, dojo.mixin({
-			item: null,
-			treePath: "",
-			expandoStatus: false
-		}, cacheObj));
-	},
-	
-	initCache: function(size){
-		if(!this.unInit){ return; }
-		this._buildCache(size);
-		this.unInit = false;
-	},
-	
-	getItemByRowIndex: function(/*integer*/rowIdx){
-		return this.items[rowIdx] ? this.items[rowIdx].item : null;
 	},
-	
-	getItemByTreePath: function(treePath){
-		for(var i = 0, len = this.items.length; i < len; i++){
-			if(this.items[i].treePath === treePath){
-				return this.items[i].item;
-			}
-		}
-		return null;
-	},
-	
-	getTreePathByRowIndex: function(/*integer*/rowIdx){
-		return this.items[rowIdx] ? this.items[rowIdx].treePath : null;
-	},
-	
-	getExpandoStatusByRowIndex: function(/*integer*/rowIdx){
-		return this.items[rowIdx] ? this.items[rowIdx].expandoStatus : null;
-	},
-	
-	getInfoByItem: function(item){
-		for(var i = 0, len = this.items.length; i < len; i++){
-			if(this.items[i].item == item){
-				return dojo.mixin({rowIdx: i}, this.items[i]);
+	getSiblingIndex: function(rowIndex, treePath){
+		var i = rowIndex - 1, indexCount = 0, tp;
+		for(; i >=0; i--){
+			tp = this.items[i] ? this.items[i].treePath : [];
+			if(tp.join('/') === treePath.join('/')){
+				indexCount++;
+			}else if(tp.length < treePath.length){
+				break;
 			}
 		}
-		return null;
-	},
-	
-	updateCache: function(/*integer*/rowIdx, cacheObj){
-		if(this.items[rowIdx]){
-			dojo.mixin(this.items[rowIdx], cacheObj);
-		}
-	},
-	
-	deleteItem: function(rowIdx){
-		if(this.items[rowIdx]){
-			this.items.splice(rowIdx, 1);
-		}
+		return indexCount;
 	},
-	
-	cleanChildren: function(rowIdx){
-		var treePath = this.getTreePathByRowIndex(rowIdx);
-		for(var i = this.items.length - 1; i >= 0; i--){
-			if(this.items[i].treePath.indexOf(treePath) === 0 && this.items[i].treePath !== treePath){
-				this.items.splice(i, 1);
+	removeChildren: function(rowIndex){
+		// find next sibling index
+		var i = rowIndex + 1, count, tp,
+			treePath = this.items[rowIndex] ? this.items[rowIndex].treePath : [];
+		for(; i < this.items.length; i++){
+			tp = this.items[i] ? this.items[i].treePath : [];
+			if(tp.join('/') === treePath.join('/') || tp.length <= treePath.length){
+				break;
 			}
 		}
-	},
-	
-	emptyCache: function(){
-		this.unInit = true;
-		this._buildCache(this.rowsPerPage);
-	},
-	
-	cleanupCache: function(){
-		this.items = null;
+		count = i - (rowIndex + 1);
+		this.items.splice(rowIndex + 1, count);
+		return count;
 	}
-	
 });
 
-dojo.declare("dojox.grid.LazyTreeGrid", dojox.grid.TreeGrid, {
+var LazyTreeGrid = declare("dojox.grid.LazyTreeGrid", TreeGrid, {
 	// summary:
-	//		An enhanced TreeGrid widget which supports lazy-loading nested-level items
+	//		An enhanced TreeGrid widget which supports lazy-loading for nested children items
 	//
 	// description:
-	//		LazyTreeGrid inherits from dojo.grid.TreeGrid, and applies virtual scrolling mechanism
-	//		to nested children rows so that it's possible to deal with large data set specifically
-	//		in tree structure with large number of children rows. It's also compatible with dijit.tree.ForestStoreModel
+	//		LazyTreeGrid inherits from dojo.grid.TreeGrid and applies virtual scrolling mechanism
+	//		to nested children rows so that it's possible to deal with complex tree structure data set
+	//		with nested and huge children rows. It's also compatible with dijit.tree.ForestStoreModel
 	//
-	//		Most methods and properties pertaining to the dojox.grid.DataGrid
+	//		Most methods and properties pertaining to dojox.grid.DataGrid
 	//		and dojox.grid.TreeGrid also apply here
 	//
-	//		LazyTreeGrid does not support summary row/items aggregate for the
-	//		lazy-loading reason.
-	
+	//		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
+	//		A tree store model object.
 	treeModel: null,
-	
-	_layoutClass: dojox.grid._LazyTreeLayout,
-	
+	// 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:
@@ -450,35 +371,33 @@ dojo.declare("dojox.grid.LazyTreeGrid", dojox.grid.TreeGrid, {
 	colSpans: null,
 	
 	postCreate: function(){
+		this._setState();
 		this.inherited(arguments);
-		this.cache = new dojox.grid.TreeGridItemCache(this);
+		if(!this._treeCache){
+			this._treeCache = new _LazyTreeGridCache();
+		}
 		if(!this.treeModel || !(this.treeModel instanceof dijit.tree.ForestStoreModel)){
-			throw new Error("dojox.grid.LazyTreeGrid: must use a treeModel and treeModel must be an instance of dijit.tree.ForestStoreModel");
+			throw new Error("dojox.grid.LazyTreeGrid: must be used with a treeModel which is an instance of dijit.tree.ForestStoreModel");
 		}
-		dojo.addClass(this.domNode, "dojoxGridTreeModel");
-		dojo.setSelectable(this.domNode, this.selectable);
+		domClass.add(this.domNode, "dojoxGridTreeModel");
+		dom.setSelectable(this.domNode, this.selectable);
 	},
-	
 	createManagers: function(){
-		// summary:
-		//		create grid managers for various tasks including rows, focus, selection, editing
-		this.rows = new dojox.grid._RowManager(this);
-		this.focus = new dojox.grid._FocusManager(this);
-		this.edit = new dojox.grid._EditManager(this);
+		this.rows = new _RowManager(this);
+		this.focus = new _FocusManager(this);
+		this.edit = new _EditManager(this);
 	},
-
 	createSelection: function(){
-		this.selection = new dojox.grid.DataSelection(this);
+		this.selection = new DataSelection(this);
 	},
-	
 	setModel: function(treeModel){
 		if(!treeModel){
 			return;
 		}
 		this._setModel(treeModel);
+		this._cleanup();
 		this._refresh(true);
 	},
-	
 	setStore: function(store, query, queryOptions){
 		if(!store){
 			return;
@@ -489,22 +408,74 @@ dojo.declare("dojox.grid.LazyTreeGrid", dojox.grid.TreeGrid, {
 		this.treeModel.root.children = [];
 		this.setModel(this.treeModel);
 	},
-	
+	onSetState: function(){
+		// summary:
+		//		Event fired when a default state being set.
+	},
+	_setState: function(){
+		if(this.defaultState){
+			this._treeCache = this.defaultState.cache;
+			this.sortInfo = this.defaultState.sortInfo || 0;
+			this.query = this.defaultState.query || this.query;
+			this._lastScrollTop = this.defaultState.scrollTop;
+			if(this.keepSelection){
+				this.selection.preserver._selectedById = this.defaultState.selection;
+			}else{
+				this.selection.selected = this.defaultState.selection || [];
+			}
+			this.onSetState();
+		}
+	},
+	getState: function(){
+		// summary:
+		//		Get the current state of LazyTreeGrid including expanding, sorting, selection and scroll top state.
+		var _this = this, 
+			selection = this.keepSelection ? this.selection.preserver._selectedById : this.selection.selected;
+		return {
+			cache: lang.clone(_this._treeCache),
+			query: lang.clone(_this.query),
+			sortInfo: lang.clone(_this.sortInfo),
+			scrollTop: lang.clone(_this.scrollTop),
+			selection: lang.clone(selection)
+		};
+	},
 	_setQuery: function(query, queryOptions){
 		this.inherited(arguments);
 		this.treeModel.query = query;
 	},
-	
+	filter: function(query, reRender){
+		this._cleanup();
+		this.inherited(arguments);
+    },
 	destroy: function(){
 		this._cleanup();
 		this.inherited(arguments);
 	},
-	
+	expand: function(itemId){
+		//	summary:
+		//		Expand the row with the given itemId.
+		//	id: string?
+		this._fold(itemId, true);
+	},
+	collapse: function(itemId){
+		//	summary:
+		//		Collapse the row with the given itemId.
+		//	id: string?
+		this._fold(itemId, false);
+	},
+	refresh: function(keepState){
+		//	summary:
+		//		Refresh, and persist the expand/collapse state when keepState equals true
+		//	keepState: boolean
+		if(!keepState){
+			this._cleanup();
+		}
+		this._refresh(true);
+	},
 	_cleanup: function(){
-		this.cache.emptyCache();
-		this._cleanupExpandoCache();
+		this._treeCache.items = [];
+		this._onCleanupExpandoCache();
 	},
-	
 	setSortIndex: function(inIndex, inAsc){
 		// Need to clean up the cache before sorting
 		if(this.canSort(inIndex + 1)){
@@ -512,322 +483,352 @@ dojo.declare("dojox.grid.LazyTreeGrid", dojox.grid.TreeGrid, {
 		}
 		this.inherited(arguments);
 	},
-	
 	_refresh: function(isRender){
-		this._cleanup();
-		this.inherited(arguments);
+		this._clearData();
+		this.updateRowCount(this._size);
+		this._fetch(0, true);
 	},
-	
 	render: function(){
 		this.inherited(arguments);
 		this.setScrollTop(this.scrollTop);
 	},
-	
 	_onNew: function(item, parentInfo){
-		var isAddingChild = false;
-		var info;
-		if(parentInfo && this.store.isItem(parentInfo.item) && dojo.some(this.treeModel.childrenAttrs, function(c){
+		var addingChild = parentInfo && this.store.isItem(parentInfo.item) && array.some(this.treeModel.childrenAttrs, function(c){
 			return c === parentInfo.attribute;
-		})){
-			isAddingChild = true;
-			info = this.cache.getInfoByItem(parentInfo.item);
-		}
-		if(!isAddingChild){
+		});
+		var items = this._treeCache.items, byIdx = this._by_idx;
+		if(!addingChild){
+			items.push({opened: false, treePath: []});
+			this._size += 1;
 			this.inherited(arguments);
-			var items = this.cache.items;
-			var treePath = (parseInt(items[items.length - 1].treePath.split("/")[0], 10) + 1) + "";
-			this.cache.insertItem(this.get('rowCount'), {item: item, treePath: treePath, expandoStatus: false});
-		}else if(info && info.expandoStatus && info.rowIdx >= 0){
-			this.expandoFetch(info.rowIdx, false);
-			this.expandoFetch(info.rowIdx, true);
-		}else if(info && info.rowIdx){
-			this.updateRow(info.rowIdx);
+		}else{
+			var parentItem = parentInfo.item, 
+				parentIdty = this.store.getIdentity(parentItem),
+				rowIndex = -1, i = 0;
+			for(; i < byIdx.length; i++){
+				if(parentIdty === byIdx[i].idty){
+					rowIndex = i;
+					break;
+				}
+			}
+			if(rowIndex >= 0){
+				if(items[rowIndex] && items[rowIndex].opened){
+					var parentTreePath = items[rowIndex].treePath, pos = rowIndex + 1;
+					for(; pos < items.length; pos++){
+						if(items[pos].treePath.length <= parentTreePath.length){
+							break;
+						}
+					}
+					var treePath = parentTreePath.slice();
+					treePath.push(parentIdty);
+					this._treeCache.items.splice(pos, 0, {opened: false, treePath: treePath});
+					// update grid._by_idx
+					var idty = this.store.getIdentity(item);
+					this._by_idty[idty] = { idty: idty, item: item };
+					byIdx.splice(pos, 0, this._by_idty[idty]);
+					// update grid
+					this._size += 1;
+					this.updateRowCount(this._size);
+					this._updateRenderedRows(pos);
+				}else{
+					this.updateRow(rowIndex);
+				}
+			}
 		}
 	},
-	
 	_onDelete: function(item){
-		this._pages = [];
-		this._bop = -1;
-		this._eop = -1;
-		this._refresh();
+		var i = 0, rowIndex = -1, idty = this.store.getIdentity(item);
+		for(; i < this._by_idx.length; i++){
+			if(idty === this._by_idx[i].idty){
+				rowIndex = i;
+				break;
+			}
+		}
+		if(rowIndex >= 0){
+			var items = this._treeCache.items, treePath = items[rowIndex] ? items[rowIndex].treePath : [], tp, count = 1;
+			i = rowIndex + 1;
+			for(; i < this._size; i++, count++){
+				tp = items[i] ? items[i].treePath : [];
+				if(items[i].treePath.length <= treePath.length){
+					break;
+				}
+			}
+			items.splice(rowIndex, count);
+			this._onCleanupExpandoCache(idty);
+			this._by_idx.splice(rowIndex, count);
+			this._size -= count;
+			this.updateRowCount(this._size);
+			this._updateRenderedRows(rowIndex);
+		}
 	},
-	
-	_cleanupExpandoCache: function(index, identity, item){},
-	
+	_onCleanupExpandoCache: function(identity){},
 	_fetch: function(start, isRender){
-		// summary:
-		//		Function for fetch data when initializing TreeGrid and
-		//		scroll the TreeGrid
+		if(!this._loading){
+			this._loading = true;
+		}
 		start = start || 0;
-		this.reqQueue = [];
-		// Check cache, do not need to fetch data if there are required data in cache
-		var i = 0, fetchedItems = [];
-		var count = Math.min(this.rowsPerPage, this.cache.items.length - start);
-		for(i = start; i < count; i++){
-			if(this.cache.getItemByRowIndex(i)){
-				fetchedItems.push(this.cache.getItemByRowIndex(i));
+		var count = this._size - start > 0 ? Math.min(this.rowsPerPage, this._size - start) : this.rowsPerPage;
+		var i = 0;
+		var fetchedItems = [];
+		this._reqQueueLen = 0;
+		for(; i < count; i++){
+			if(this._by_idx[start + i]){
+				fetchedItems.push(this._by_idx[start + i].item);
 			}else{
 				break;
 			}
 		}
-		if(fetchedItems.length === count){// || !this.cache.getTreePathByRowIndex(start + fetchedItems.length)){
+		if(fetchedItems.length === count){
+			this._reqQueueLen = 1;
+			this._onFetchBegin(this._size, {startRowIdx: start, count: count});
 			this._onFetchComplete(fetchedItems, {startRowIdx: start, count: count});
 		}else{
-			// In case there need different level data, we need to do multiple fetch.
-			// Do next fetch only when the last request complete.
-			this.reqQueueIndex = 0;
-			var level = "",
-				nextRowLevel = "",
-				startRowIdx = start,
-				startTreePath = this.cache.getTreePathByRowIndex(start);
-			count = 0;
-			// Create request queue
-			for(i = start + 1; i < start + this.rowsPerPage; i++){
-				if(!this.cache.getTreePathByRowIndex(i)){
-					break;
-				}
-				level = this.cache.getTreePathByRowIndex(i - 1).split("/").length - 1;
-				nextRowLevel = this.cache.getTreePathByRowIndex(i).split("/").length - 1;
-				if(level !== nextRowLevel){
-					this.reqQueue.push({
-						startTreePath: startTreePath,
-						startRowIdx: startRowIdx,
-						count: count + 1
-					});
-					count = 0;
-					startRowIdx = i;
-					startTreePath = this.cache.getTreePathByRowIndex(i);
+			var level, nextLevel, len = 1, items = this._treeCache.items, 
+				treePath = items[start] ? items[start].treePath : [];
+			for(i = 1; i < count; i++){
+				level = items[start + len - 1] ? items[start + len - 1].treePath.length : 0;
+				nextLevel = items[start + len] ? items[start + len].treePath.length : 0;
+				if(level !== nextLevel){
+					this._reqQueueLen++;
+					this._fetchItems({startRowIdx: start, count: len, treePath: treePath});
+					start = start + len;
+					len = 1;
+					treePath = items[start] ? items[start].treePath : 0;
 				}else{
-					count++;
+					len++;
 				}
 			}
-			this.reqQueue.push({
-				startTreePath: startTreePath,
-				startRowIdx: startRowIdx,
-				count: count + 1
-			});
-			var len = this.reqQueue.length;
-			for(i = 0; i < len; i++){
-				this._fetchItems(i, dojo.hitch(this, "_onFetchBegin"), dojo.hitch(this, "_onFetchComplete"), dojo.hitch(this, "_onFetchError"));
-			}
+			this._reqQueueLen++;
+			this._fetchItems({startRowIdx: start, count: len, treePath: treePath});
 		}
 	},
-	
-	_fetchItems: function(idx, onBegin, onComplete, onError){
-		if(!this._loading){
-			this._loading = true;
-			this.showMessage(this.loadingMessage);
+	_fetchItems: function(req){
+		if(this._pending_requests[req.startRowIdx]){
+			return;
 		}
-		var level = this.reqQueue[idx].startTreePath.split("/").length - 1;
-		this._pending_requests[this.reqQueue[idx].startRowIdx] = true;
-		if(level === 0){
+		this.showMessage(this.loadingMessage);
+		this._pending_requests[req.startRowIdx] = true;
+		var	onError = lang.hitch(this, '_onFetchError'),
+			start = this._treeCache.getSiblingIndex(req.startRowIdx, req.treePath);
+		if(req.treePath.length === 0){
 			this.store.fetch({
-				start: parseInt(this.reqQueue[idx].startTreePath, 10),
-				startRowIdx: this.reqQueue[idx].startRowIdx,
-				count: this.reqQueue[idx].count,
+				start: start,
+				startRowIdx: req.startRowIdx,
+				treePath: req.treePath,
+				count: req.count,
 				query: this.query,
 				sort: this.getSortProps(),
 				queryOptions: this.queryOptions,
-				onBegin: onBegin,
-				onComplete: onComplete,
-				onError: onError
+				onBegin: lang.hitch(this, '_onFetchBegin'),
+				onComplete: lang.hitch(this, '_onFetchComplete'),
+				onError: lang.hitch(this, '_onFetchError')
 			});
 		}else{
-			var startTreePath = this.reqQueue[idx].startTreePath;
-			var parentTreePath = startTreePath.substring(0, startTreePath.lastIndexOf("/"));
-			var startIdx = startTreePath.substring(startTreePath.lastIndexOf("/") + 1);
-			var parentItem = this.cache.getItemByTreePath(parentTreePath);
-			if(!parentItem){
-				throw new Error("Lazy loading TreeGrid on fetch error:");
-			}
-			var parentId = this.store.getIdentity(parentItem);
-			this.queryObj = {
-				start: parseInt(startIdx, 10),
-				startRowIdx: this.reqQueue[idx].startRowIdx,
-				count: this.reqQueue[idx].count,
+			var parentId = req.treePath[req.treePath.length - 1], parentItem;
+			var queryObj = {
+				start: start,
+				startRowIdx: req.startRowIdx,
+				treePath: req.treePath,
+				count: req.count,
 				parentId: parentId,
 				sort: this.getSortProps()
 			};
-			this.treeModel.getChildren(parentItem, onComplete, onError, this.queryObj);
+			var _this = this;
+			var onComplete = function(){
+				var f = lang.hitch(_this, '_onFetchComplete');
+				if(arguments.length == 1){
+					f.apply(_this, [arguments[0], queryObj]);
+				}else{
+					f.apply(_this, arguments);
+				}
+			};
+			if(this._by_idty[parentId]){
+				parentItem = this._by_idty[parentId].item;
+				this.treeModel.getChildren(parentItem, onComplete, onError, queryObj);
+			}else{
+				this.store.fetchItemByIdentity({
+					identity: parentId,
+					onItem: function(item){
+						_this.treeModel.getChildren(item, onComplete, onError, queryObj);
+					},
+					onError: onError
+				});
+			}
 		}
 	},
-	
 	_onFetchBegin: function(size, request){
-		this.cache.initCache(size);
-		size = this.cache.items.length;
+		if(this._treeCache.items.length === 0){
+			this._size = parseInt(size, 10);
+		}
+		size = this._size;
+		// this._size = size = this._treeCache.items.length;
 		this.inherited(arguments);
 	},
-
-    filter: function(query, reRender){
-    	this.cache.emptyCache();
-        this.inherited(arguments);
-    },
-
-	_onFetchComplete: function(items, request, size){
-		var treePath = "",
-			startRowIdx, count, start;
-			
-		if(request){
-			startRowIdx = request.startRowIdx;
-			count = request.count;
-			start = 0;
-		}else{
-			startRowIdx = this.queryObj.startRowIdx;
-			count = this.queryObj.count;
-			start = this.queryObj.start;
-		}
-		
-		for(var i = 0; i < count; i++){
-			treePath = this.cache.getTreePathByRowIndex(startRowIdx + i);
-			if(treePath){
-				if(!this.cache.getItemByRowIndex(startRowIdx + i)){
-					this.cache.cacheItem(startRowIdx + i, {
-						item: items[start + i],
-						treePath: treePath,
-						expandoStatus: false
-					});
+	_onFetchComplete: function(items, request){
+		var startRowIdx = request.startRowIdx,
+			count = request.count,
+			start = items.length <= count ? 0: request.start,
+			treePath = request.treePath || [];
+		if(lang.isArray(items) && items.length > 0){
+			var i = 0, len = Math.min(count, items.length);
+			for(; i < len; i++){
+				if(!this._treeCache.items[startRowIdx + i]){
+					this._treeCache.items[startRowIdx + i] = {opened: false, treePath: treePath};
 				}
+				if(!this._by_idx[startRowIdx + i]){
+					this._addItem(items[start + i], startRowIdx + i, true);
+				}
+				// this._treeCache.items.splice(startRowIdx + i, 0, {opened: false, treePath: treePath});
 			}
+			this.updateRows(startRowIdx, len);
 		}
-		this._pending_requests[startRowIdx] = false;
-		// Add items when all request complete
-		if(!this.scroller){
-			return;
-		}
-		var len = Math.min(count, items.length);
-		for(i = 0; i < len; i++){
-			this._addItem(items[start + i], startRowIdx + i, true);
-		}
-		this.updateRows(startRowIdx, len);
-		if(this._lastScrollTop){
-			this.setScrollTop(this._lastScrollTop);
+		if(this._size == 0){
+			this.showMessage(this.noDataMessage);
+		}else{
+			this.showMessage();
 		}
-		if(this._loading){
+		this._pending_requests[startRowIdx] = false;
+		this._reqQueueLen--;
+		if(this._loading && this._reqQueueLen === 0){
 			this._loading = false;
-			if(!this.cache.items.length){
-				this.showMessage(this.noDataMessage);
-			}else{
-				this.showMessage();
+			if(this._lastScrollTop){
+				this.setScrollTop(this._lastScrollTop);
 			}
 		}
-		
 	},
-	
 	expandoFetch: function(rowIndex, open){
 		// summary:
 		//		Function for fetch children of a given row
-		if(this._loading){return;}
+		if(this._loading || !this._by_idx[rowIndex]){return;}
 		this._loading = true;
-		this.toggleLoadingClass(true);
-		var item = this.cache.getItemByRowIndex(rowIndex);
+		this._toggleLoadingClass(rowIndex, true);
 		this.expandoRowIndex = rowIndex;
-		this._pages = [];
+		var item = this._by_idx[rowIndex].item;
+		// this._pages = [];
 		if(open){
-			var parentId = this.store.getIdentity(item);
 			var queryObj = {
 				start: 0,
-				count: this.keepRows,
-				parentId: parentId,
+				count: this.rowsPerPage,
+				parentId: this.store.getIdentity(this._by_idx[rowIndex].item),
 				sort: this.getSortProps()
 			};
-			this.treeModel.getChildren(item, dojo.hitch(this, "_onExpandoComplete"), dojo.hitch(this, "_onFetchError"), queryObj);
+			this.treeModel.getChildren(item, lang.hitch(this, "_onExpandoComplete"), lang.hitch(this, "_onFetchError"), queryObj);
 		}else{
-			this.cache.cleanChildren(rowIndex);
-			for(var i = rowIndex + 1, len = this._by_idx.length; i < len; i++){
-				delete this._by_idx[i];
-			}
-			this.updateRowCount(this.cache.items.length);
-			if(this.cache.getTreePathByRowIndex(rowIndex + 1)){
-				this._fetch(rowIndex + 1);
-			}else{
-				this._fetch(rowIndex);
+			// get the whole children number when clear the children from cache
+			var num = this._treeCache.removeChildren(rowIndex);
+			// remove the items from grid._by_idx
+			this._by_idx.splice(rowIndex + 1, num);
+			this._bop = this._eop = -1;
+			//update grid
+			this._size -= num;
+			this.updateRowCount(this._size);
+			this._updateRenderedRows(rowIndex + 1);
+			this._toggleLoadingClass(rowIndex, false);
+			if(this._loading){
+				this._loading = false;
 			}
-			this.toggleLoadingClass(false);
+			this.focus._delayedCellFocus();
 		}
 	},
-	
 	_onExpandoComplete: function(childItems, request, size){
-		var parentTreePath = this.cache.getTreePathByRowIndex(this.expandoRowIndex);
-		if(size && !isNaN(parseInt(size, 10))){
-			size = parseInt(size, 10);
-		}else{
-			size = childItems.length;
-		}
-		var i, j = 0, len = this._by_idx.length;
-		for(i = this.expandoRowIndex + 1; j < size; i++, j++){
-			this.cache.insertItem(i, {
-				item: null,
-				treePath: parentTreePath + "/" + j,
-				expandoStatus: false
-			});
-		}
-		this.updateRowCount(this.cache.items.length);
-		
-		for(i = this.expandoRowIndex + 1; i < len; i++){
-			delete this._by_idx[i];
-		}
-		this.cache.updateCache(this.expandoRowIndex, {childrenNum: size});
+		size = isNaN(size) ? childItems.length : parseInt(size, 10);
+		var treePath = this._treeCache.items[this.expandoRowIndex].treePath.slice(0);
+		treePath.push(this.store.getIdentity(this._by_idx[this.expandoRowIndex].item));
+		var i = 1, idty;
+		for(; i <= size; i++){
+			this._treeCache.items.splice(this.expandoRowIndex + i, 0, {treePath: treePath, opened: false});
+		}
+		this._size += size;
+		this.updateRowCount(this._size);
 		for(i = 0; i < size; i++){
-			this.cache.updateCache(this.expandoRowIndex + 1 + i, {item: childItems[i]});
-		}
-		for(i = 0; i < Math.min(size, this.keepRows); i++){
-			this._addItem(childItems[i], this.expandoRowIndex + 1 + i, false);
-			this.updateRow(this.expandoRowIndex + 1 + i);
+			if(childItems[i]){
+				idty = this.store.getIdentity(childItems[i]);
+				this._by_idty[idty] = { idty: idty, item: childItems[i] };
+				this._by_idx.splice(this.expandoRowIndex + 1 + i, 0, this._by_idty[idty]);
+			}else{
+				this._by_idx.splice(this.expandoRowIndex + 1 + i, 0, null);
+			}
 		}
-		
-		this.toggleLoadingClass(false);
+		this._updateRenderedRows(this.expandoRowIndex + 1);
+		this._toggleLoadingClass(this.expandoRowIndex, false);
 		this.stateChangeNode = null;
 		if(this._loading){
 			this._loading = false;
 		}
-		if(size < this.keepRows && this.cache.getTreePathByRowIndex(this.expandoRowIndex + 1 + size)){
-			this._fetch(this.expandoRowIndex + 1 + size);
-		}
-	},
-	
-	toggleLoadingClass: function(flag){
-		// summary:
-		//		set loading class when expanding/collapsing
-		if(this.stateChangeNode){
-			dojo.toggleClass(this.stateChangeNode, "dojoxGridExpandoLoading", flag);
+		if(this.autoHeight === true){
+			this._resize();
 		}
+		this.focus._delayedCellFocus();
 	},
-	
-	styleRowNode: function(inRowIndex, inRowNode){
-		if(inRowNode){
-			this.rows.styleRowNode(inRowIndex, inRowNode);
+	styleRowNode: function(rowIndex, rowNode){
+		if(rowNode){
+			this.rows.styleRowNode(rowIndex, rowNode);
 		}
 	},
-	
 	onStyleRow: function(row){
 		if(!this.layout._isCollapsable){
 			this.inherited(arguments);
 			return;
 		}
-		var base = dojo.attr(row.node, 'dojoxTreeGridBaseClasses');
-		if(base){
-			row.customClasses = base;
-		}
-		var i = row;
-		i.customClasses += (i.odd ? " dojoxGridRowOdd" : "") + (i.selected ? " dojoxGridRowSelected" : "") + (i.over ? " dojoxGridRowOver" : "");
-		this.focus.styleRow(i);
-		this.edit.styleRow(i);
+		row.customClasses = (row.odd ? " dojoxGridRowOdd" : "") + (row.selected ? " dojoxGridRowSelected" : "") + (row.over ? " dojoxGridRowOver" : "");
+		this.focus.styleRow(row);
+		this.edit.styleRow(row);
 	},
-	
-	dokeydown: function(e){
+	onKeyDown: function(e){
 		if(e.altKey || e.metaKey){
 			return;
 		}
-		var dk = dojo.keys,
-			target = e.target,
-			expando = target && target.firstChild ? dijit.byId(target.firstChild.id) : null;
-		if(e.keyCode === dk.ENTER && expando instanceof dojox.grid._LazyExpando){
+		var expando = dijit.findWidgets(e.target)[0];
+		if(e.keyCode === keys.ENTER && expando instanceof _LazyExpando){
 			expando.onToggle();
 		}
-		this.onKeyDown(e);
+		this.inherited(arguments);
+	},
+	_toggleLoadingClass: function(rowIndex, flag){
+		var views = this.views.views, node,
+			rowNode = views[views.length - 1].getRowNode(rowIndex);
+		if(rowNode){
+			node = query('.dojoxGridExpando', rowNode)[0];
+			if(node){
+				domClass.toggle(node, "dojoxGridExpandoLoading", flag);
+			}
+		}
+	},
+	_updateRenderedRows: function(start){
+		array.forEach(this.scroller.stack, function(p){
+			if(p * this.rowsPerPage >= start){
+				this.updateRows(p * this.rowsPerPage, this.rowsPerPage);
+			}else if((p + 1) * this.rowsPerPage >=  start){
+				this.updateRows(start, (p + 1) * this.rowsPerPage - start + 1);
+			}
+		}, this);
+	},
+	_fold: function(itemId, open){
+		var rowIndex = -1, i = 0, byIdx = this._by_idx, idty = this._by_idty[itemId];
+		if(idty && idty.item && this.treeModel.mayHaveChildren(idty.item)){
+			for(; i < byIdx.length; i++){
+				if(byIdx[i] && byIdx[i].idty === itemId){
+					rowIndex = i;
+					break;
+				}
+			}
+			if(rowIndex >= 0){
+				var rowNode = this.views.views[this.views.views.length - 1].getRowNode(rowIndex);
+				if(rowNode){
+					var expando = dijit.findWidgets(rowNode)[0];
+					if(expando){
+						expando.setOpen(open);
+					}
+				}
+			}
+		}
 	}
 });
 
-dojox.grid.LazyTreeGrid.markupFactory = function(props, node, ctor, cellFunc){
-	return dojox.grid.TreeGrid.markupFactory(props, node, ctor, cellFunc);
+LazyTreeGrid.markupFactory = function(props, node, ctor, cellFunc){
+	return TreeGrid.markupFactory(props, node, ctor, cellFunc);
 };
+
+return LazyTreeGrid;
+
+});
\ No newline at end of file
diff --git a/dojox/grid/LazyTreeGridStoreModel.js b/dojox/grid/LazyTreeGridStoreModel.js
index aadccff..7bb1dff 100644
--- a/dojox/grid/LazyTreeGridStoreModel.js
+++ b/dojox/grid/LazyTreeGridStoreModel.js
@@ -1,8 +1,10 @@
-dojo.provide("dojox.grid.LazyTreeGridStoreModel");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dijit/tree/ForestStoreModel"], function(declare, array, lang, ForestStoreModel){
 
-dojo.require("dijit.tree.ForestStoreModel");
-
-dojo.declare("dojox.grid.LazyTreeGridStoreModel", dijit.tree.ForestStoreModel, {
+return declare("dojox.grid.LazyTreeGridStoreModel", ForestStoreModel, {
 
 	// There are different approaches to get children for client-side
 	// DataStore (e.g. dojo.data.ItemFileReadStore) or server-side DataStore
@@ -11,14 +13,14 @@ dojo.declare("dojox.grid.LazyTreeGridStoreModel", dijit.tree.ForestStoreModel, {
 	serverStore: false, // server side store
 	
 	constructor: function(/* Object */ args){
-		this.serverStore = args.serverStore === true ? true : false;
+		this.serverStore = !!args.serverStore;
 	},
 
 	mayHaveChildren: function(/*dojo.data.Item*/ item){
 		var children = null;
-		return dojo.some(this.childrenAttrs, function(attr){
+		return array.some(this.childrenAttrs, function(attr){
 				children = this.store.getValue(item, attr);
-				if(dojo.isString(children)){
+				if(lang.isString(children)){
 					return parseInt(children, 10) > 0 || children.toLowerCase() === "true" ? true : false;
 				}else if(typeof children == "number"){
 					return children > 0;
@@ -26,7 +28,7 @@ dojo.declare("dojox.grid.LazyTreeGridStoreModel", dijit.tree.ForestStoreModel, {
 					return children;
 				}else if(this.store.isItem(children)){
 					children = this.store.getValues(item, attr);
-					return dojo.isArray(children) ? children.length > 0 : false;
+					return lang.isArray(children) ? children.length > 0 : false;
 				}else{
 					return false;
 				}
@@ -46,10 +48,10 @@ dojo.declare("dojox.grid.LazyTreeGridStoreModel", dijit.tree.ForestStoreModel, {
 					count: count,
 					sort: sort,
 					query: this.query,
-					onBegin: dojo.hitch(this, function(size){
+					onBegin: lang.hitch(this, function(size){
 						this.root.size = size;
 					}),
-					onComplete: dojo.hitch(this, function(items){
+					onComplete: lang.hitch(this, function(items){
 						onComplete(items, queryObj, this.root.size);
 					}),
 					onError: onError
@@ -57,7 +59,7 @@ dojo.declare("dojox.grid.LazyTreeGridStoreModel", dijit.tree.ForestStoreModel, {
 			}else{
 				var store = this.store;
 				if(!store.isItemLoaded(parentItem)){
-					var getChildren = dojo.hitch(this, arguments.callee);
+					var getChildren = lang.hitch(this, arguments.callee);
 					store.loadItem({
 						item: parentItem,
 						onItem: function(parentItem){
@@ -73,11 +75,11 @@ dojo.declare("dojox.grid.LazyTreeGridStoreModel", dijit.tree.ForestStoreModel, {
 						start: start,
 						count: count,
 						sort: sort,
-						query: dojo.mixin({parentId: parentId}, this.query || {}),
-						onBegin: dojo.hitch(this, function(size){
+						query: lang.mixin({parentId: parentId}, this.query || {}),
+						onBegin: lang.hitch(this, function(size){
 							this.childrenSize = size;
 						}),
-						onComplete: dojo.hitch(this, function(items){
+						onComplete: lang.hitch(this, function(items){
 							onComplete(items, queryObj, this.childrenSize);
 						}),
 						onError: onError
@@ -95,11 +97,17 @@ dojo.declare("dojox.grid.LazyTreeGridStoreModel", dijit.tree.ForestStoreModel, {
 		// summary:
 		//		Check if all children of the given item have been loaded
 		var children = null;
-		return dojo.every(this.childrenAttrs, function(attr){
+		return array.every(this.childrenAttrs, function(attr){
 			children = this.store.getValues(parentItem, attr);
-			return dojo.every(children, function(c){
+			return array.every(children, function(c){
 				return this.store.isItemLoaded(c);
 			}, this);
 		}, this);
-	}
+	},
+	
+	//overwritten
+	onNewItem: function(item, parentInfo){ },
+	
+	onDeleteItem: function(item){ }
+});
 });
diff --git a/dojox/grid/README b/dojox/grid/README
index 6d3dc3c..91b762c 100644
--- a/dojox/grid/README
+++ b/dojox/grid/README
@@ -46,6 +46,9 @@ Install into the following directory structure:
 If you wish us use the old (compat / 1.2) grid, you can untar the
 compatGrid.tar.gz archive.  This version of the grid is no longer maintained
 or updated - but should work with any newer version of the dojo library.
+
+dojox.grid.* is a11y enabled, please see the following doc page for more details
+- http://dojotoolkit.org/reference-guide/dojox/grid/DataGrid.html#accessibility-in-1-3-and-beyond
 -------------------------------------------------------------------------------
 
 
@@ -94,7 +97,7 @@ Dojo Core, dojox.grid.DataGrid
 -------------------------------------------------------------------------------
 Documentation
 
-http://docs.dojocampus.org/dojox/grid/EnhancedGrid
+http://dojotoolkit.org/reference-guide/dojox/grid/EnhancedGrid.html
 -------------------------------------------------------------------------------
 Installation instructions
 
@@ -134,7 +137,7 @@ Dojo Core, dojox.grid.TreeGrid
 -------------------------------------------------------------------------------
 Documentation
 
-http://docs.dojocampus.org/dojox/grid/LazyTreeGrid
+http://dojotoolkit.org/reference-guide/dojox/grid/LazyTreeGrid.html
 -------------------------------------------------------------------------------
 Installation instructions
 
@@ -145,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 98b461c..102da69 100644
--- a/dojox/grid/Selection.js
+++ b/dojox/grid/Selection.js
@@ -1,6 +1,11 @@
-dojo.provide('dojox.grid.Selection');
-
-dojo.declare("dojox.grid.Selection", null, {
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/dom-attr"
+], function(declare, array, lang, domAttr){
+
+return declare("dojox.grid.Selection", null, {
 	// summary:
 	//		Manages row selection for grid. Owned by grid and used internally
 	//		for selection. Override to implement custom selection.
@@ -123,8 +128,8 @@ dojo.declare("dojox.grid.Selection", null, {
 
 	addToSelection: function(inIndex){
 		if(this.mode == 'none'){ return; }
-		if(dojo.isArray(inIndex)){
-			dojo.forEach(inIndex, this.addToSelection, this);
+		if(lang.isArray(inIndex)){
+			array.forEach(inIndex, this.addToSelection, this);
 			return;
 		}
 		inIndex = Number(inIndex);
@@ -135,7 +140,7 @@ dojo.declare("dojox.grid.Selection", null, {
 				this.selectedIndex = inIndex;
 				var rowNode = this.grid.getRowNode(inIndex);
 				if(rowNode){
-					dojo.attr(rowNode,"aria-selected","true");
+					domAttr.set(rowNode, "aria-selected", "true");
 				}
 				this._beginUpdate();
 				this.selected[inIndex] = true;
@@ -149,8 +154,8 @@ dojo.declare("dojox.grid.Selection", null, {
 
 	deselect: function(inIndex){
 		if(this.mode == 'none'){ return; }
-		if(dojo.isArray(inIndex)){
-			dojo.forEach(inIndex, this.deselect, this);
+		if(lang.isArray(inIndex)){
+			array.forEach(inIndex, this.deselect, this);
 			return;
 		}
 		inIndex = Number(inIndex);
@@ -163,7 +168,7 @@ dojo.declare("dojox.grid.Selection", null, {
 			}
 			var rowNode = this.grid.getRowNode(inIndex);
 			if(rowNode){
-				dojo.attr(rowNode,"aria-selected","false");
+				domAttr.set(rowNode, "aria-selected", "false");
 			}
 			this._beginUpdate();
 			delete this.selected[inIndex];
@@ -179,8 +184,8 @@ dojo.declare("dojox.grid.Selection", null, {
 	},
 
 	toggleSelect: function(inIndex){
-		if(dojo.isArray(inIndex)){
-			dojo.forEach(inIndex, this.toggleSelect, this);
+		if(lang.isArray(inIndex)){
+			array.forEach(inIndex, this.toggleSelect, this);
 			return;
 		}
 		this.setSelected(inIndex, !this.selected[inIndex]);
@@ -198,11 +203,11 @@ dojo.declare("dojox.grid.Selection", null, {
 	},
 
 	selectRange: function(inFrom, inTo){
-		this._range(inFrom, inTo, dojo.hitch(this, "addToSelection"));
+		this._range(inFrom, inTo, lang.hitch(this, "addToSelection"));
 	},
 
 	deselectRange: function(inFrom, inTo){
-		this._range(inFrom, inTo, dojo.hitch(this, "deselect"));
+		this._range(inFrom, inTo, lang.hitch(this, "deselect"));
 	},
 
 	insert: function(inIndex){
@@ -258,3 +263,4 @@ dojo.declare("dojox.grid.Selection", null, {
 		this._endUpdate();
 	}
 });
+});
\ No newline at end of file
diff --git a/dojox/grid/TreeGrid.js b/dojox/grid/TreeGrid.js
index a435107..7103a80 100644
--- a/dojox/grid/TreeGrid.js
+++ b/dojox/grid/TreeGrid.js
@@ -1,13 +1,29 @@
+define([
+	"dojo/_base/kernel",
+	"../main",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/_base/event",
+	"dojo/dom-attr",
+	"dojo/dom-class",
+	"dojo/query",
+	"dojo/keys",
+	"dijit/tree/ForestStoreModel",
+	"./DataGrid",
+	"./_Layout",
+	"./_FocusManager",
+	"./_RowManager",
+	"./_EditManager",
+	"./TreeSelection",
+	"./cells/tree",
+	"./_TreeView"
+], function(dojo, dojox, declare, array, lang, event, domAttr, domClass, query, keys, ForestStoreModel, 
+	DataGrid, _Layout, _FocusManager, _RowManager, _EditManager, TreeSelection, TreeCell){
+		
 dojo.experimental("dojox.grid.TreeGrid");
 
-dojo.provide("dojox.grid.TreeGrid");
-
-dojo.require("dojox.grid.DataGrid");
-dojo.require("dojox.grid._TreeView");
-dojo.require("dojox.grid.cells.tree");
-dojo.require("dojox.grid.TreeSelection");
-
-dojo.declare("dojox.grid._TreeAggregator", null, {
+var _TreeAggregator = declare("dojox.grid._TreeAggregator", null, {
 	cells: [],
 	grid: null,
 	childFields: [],
@@ -43,7 +59,7 @@ dojo.declare("dojox.grid._TreeAggregator", null, {
 			if (cell.index <= level + 1){
 				total = children.length;
 			}else{
-				dojo.forEach(children, function(c){
+				array.forEach(children, function(c){
 					total += this.getForCell(cell, level + 1, c, "cnt");
 				}, this);
 			}
@@ -59,7 +75,7 @@ dojo.declare("dojox.grid._TreeAggregator", null, {
 		var store = this.store;
 		var childFields = this.childFields;
 		if(childFields[level]){
-			dojo.forEach(store.getValues(item, childFields[level]), function(c){
+			array.forEach(store.getValues(item, childFields[level]), function(c){
 				total += this.getForCell(cell, level + 1, c, "sum");
 			}, this);
 		}else{
@@ -116,7 +132,7 @@ dojo.declare("dojox.grid._TreeAggregator", null, {
 	}
 });
 
-dojo.declare("dojox.grid._TreeLayout", dojox.grid._Layout, {
+var _TreeLayout = declare("dojox.grid._TreeLayout", _Layout, {
 	// Whether or not we are collapsable - this is calculated when we
 	// set our structure.
 	_isCollapsable: false,
@@ -141,7 +157,7 @@ dojo.declare("dojox.grid._TreeLayout", dojox.grid._Layout, {
 				for(k in originalCell){
 					n[k] = originalCell[k];
 				}
-				n = dojo.mixin(n, {
+				n = lang.mixin(n, {
 					level: level,
 					idxInParent: level > 0 ? idx : -1,
 					parentCell: level > 0 ? parentCell : null
@@ -149,7 +165,7 @@ dojo.declare("dojox.grid._TreeLayout", dojox.grid._Layout, {
 				return n;
 			};
 			var ret = [];
-			dojo.forEach(children, function(c, idx){
+			array.forEach(children, function(c, idx){
 				if("children" in c){
 					cFields.push(c.field);
 					var last = ret[ret.length - 1];
@@ -165,7 +181,7 @@ dojo.declare("dojox.grid._TreeLayout", dojox.grid._Layout, {
 		};
 		var tCell = {children: cells, itemAggregates: []};
 		tree.cells[0] = getTreeCells(tCell, 0);
-		g.aggregator = new dojox.grid._TreeAggregator({cells: tree.cells[0],
+		g.aggregator = new _TreeAggregator({cells: tree.cells[0],
 														grid: g,
 														childFields: cFields});
 		if(g.scroller && g.defaultOpen){
@@ -180,7 +196,7 @@ dojo.declare("dojox.grid._TreeLayout", dojox.grid._Layout, {
 		var g = this.grid;
 		// Only supporting single-view, single row or else we
 		// are not collapsable
-		if(g && g.treeModel && !dojo.every(s, function(i){
+		if(g && g.treeModel && !array.every(s, function(i){
 			return ("cells" in i);
 		})){
 			s = arguments[0] = [{cells:[s]}];
@@ -191,7 +207,7 @@ dojo.declare("dojox.grid._TreeLayout", dojox.grid._Layout, {
 				this._isCollapsable = true;
 				s[0].cells[0][(this.grid.treeModel?this.grid.expandoCell:0)].isCollapsable = true;
 			}else{
-				var childCells = dojo.filter(s[0].cells[0], function(c){
+				var childCells = array.filter(s[0].cells[0], function(c){
 					return ("children" in c);
 				});
 				if(childCells.length === 1){
@@ -207,11 +223,11 @@ dojo.declare("dojox.grid._TreeLayout", dojox.grid._Layout, {
 
 	addCellDef: function(inRowIndex, inCellIndex, inDef){
 		var obj = this.inherited(arguments);
-		return dojo.mixin(obj, dojox.grid.cells.TreeCell);
+		return lang.mixin(obj, TreeCell);
 	}
 });
 
-dojo.declare("dojox.grid.TreePath", null, {
+var TreePath = declare("dojox.grid.TreePath", null, {
 	level: 0,
 	_str: "",
 	_arr: null,
@@ -221,10 +237,10 @@ dojo.declare("dojox.grid.TreePath", null, {
 	item: null,
 
 	constructor: function(/*String|Integer[]|Integer|dojox.grid.TreePath*/ path, /*dojox.grid.TreeGrid*/ grid){
-		if(dojo.isString(path)){
+		if(lang.isString(path)){
 			this._str = path;
-			this._arr = dojo.map(path.split('/'), function(item){ return parseInt(item, 10); });
-		}else if(dojo.isArray(path)){
+			this._arr = array.map(path.split('/'), function(item){ return parseInt(item, 10); });
+		}else if(lang.isArray(path)){
 			this._str = path.join('/');
 			this._arr = path.slice(0);
 		}else if(typeof path == "number"){
@@ -254,11 +270,11 @@ dojo.declare("dojox.grid.TreePath", null, {
 	compare: function(path /*dojox.grid.TreePath|String|Array*/){
 		// summary:
 		//	compares two paths
-		if(dojo.isString(path) || dojo.isArray(path)){
+		if(lang.isString(path) || lang.isArray(path)){
 			if(this._str == path){ return 0; }
 			if(path.join && this._str == path.join('/')){ return 0; }
-			path = new dojox.grid.TreePath(path, this.grid);
-		}else if(path instanceof dojox.grid.TreePath){
+			path = new TreePath(path, this.grid);
+		}else if(path instanceof TreePath){
 			if(this._str == path._str){ return 0; }
 		}
 		for(var i=0, l=(this._arr.length < path._arr.length ? this._arr.length : path._arr.length); i<l; i++){
@@ -288,11 +304,11 @@ dojo.declare("dojox.grid.TreePath", null, {
 
 		if(new_path[last] === 0){
 			new_path.pop();
-			return new dojox.grid.TreePath(new_path, this.grid);
+			return new TreePath(new_path, this.grid);
 		}
 
 		new_path[last]--;
-		var path = new dojox.grid.TreePath(new_path, this.grid);
+		var path = new TreePath(new_path, this.grid);
 		return path.lastChild(true);
 	},
 	next: function(){
@@ -320,7 +336,7 @@ dojo.declare("dojox.grid.TreePath", null, {
 			}
 		}
 
-		return new dojox.grid.TreePath(new_path, this.grid);
+		return new TreePath(new_path, this.grid);
 	},
 	children: function(alwaysReturn){
 		// summary:
@@ -337,7 +353,7 @@ dojo.declare("dojox.grid.TreePath", null, {
 			if(!model.mayHaveChildren(item)){
 				return null;
 			}
-			dojo.forEach(model.childrenAttrs, function(attr){
+			array.forEach(model.childrenAttrs, function(attr){
 				items = items.concat(store.getValues(item, attr));
 			});
 		}else{
@@ -364,8 +380,8 @@ dojo.declare("dojox.grid.TreePath", null, {
 		if(!childItems){
 			return [];
 		}
-		return dojo.map(childItems, function(item, index){
-			return new dojox.grid.TreePath(this._str + '/' + index, this.grid);
+		return array.map(childItems, function(item, index){
+			return new TreePath(this._str + '/' + index, this.grid);
 		}, this);
 	},
 	parent: function(){
@@ -375,7 +391,7 @@ dojo.declare("dojox.grid.TreePath", null, {
 		if(this.level === 0){
 			return null;
 		}
-		return new dojox.grid.TreePath(this._arr.slice(0, this.level), this.grid);
+		return new TreePath(this._arr.slice(0, this.level), this.grid);
 	},
 	lastChild: function(/*Boolean?*/ traverse){
 		// summary:
@@ -386,7 +402,7 @@ dojo.declare("dojox.grid.TreePath", null, {
 		if(!children || !children.length){
 			return this;
 		}
-		var path = new dojox.grid.TreePath(this._str + "/" + String(children.length-1), this.grid);
+		var path = new TreePath(this._str + "/" + String(children.length-1), this.grid);
 		if(!traverse){
 			return path;
 		}
@@ -397,7 +413,7 @@ dojo.declare("dojox.grid.TreePath", null, {
 	}
 });
 
-dojo.declare("dojox.grid._TreeFocusManager", dojox.grid._FocusManager, {
+var _TreeFocusManager = declare("dojox.grid._TreeFocusManager", _FocusManager, {
 	setFocusCell: function(inCell, inRowIndex){
 		if(inCell && inCell.getNode(inRowIndex)){
 			this.inherited(arguments);
@@ -405,7 +421,7 @@ dojo.declare("dojox.grid._TreeFocusManager", dojox.grid._FocusManager, {
 	},
 	isLastFocusCell: function(){
 		if(this.cell && this.cell.index == this.grid.layout.cellCount-1){
-			var path = new dojox.grid.TreePath(this.grid.rowCount-1, this.grid);
+			var path = new TreePath(this.grid.rowCount-1, this.grid);
 			path = path.lastChild(true);
 			return this.rowIndex == path._str;
 		}
@@ -416,7 +432,7 @@ dojo.declare("dojox.grid._TreeFocusManager", dojox.grid._FocusManager, {
 		//	focus next grid cell
 		if(this.cell){
 			var row=this.rowIndex, col=this.cell.index+1, cc=this.grid.layout.cellCount-1;
-			var path = new dojox.grid.TreePath(this.rowIndex, this.grid);
+			var path = new TreePath(this.rowIndex, this.grid);
 			if(col > cc){
 				var new_path = path.next();
 				if(!new_path){
@@ -444,7 +460,7 @@ dojo.declare("dojox.grid._TreeFocusManager", dojox.grid._FocusManager, {
 		//	focus previous grid cell
 		if(this.cell){
 			var row=(this.rowIndex || 0), col=(this.cell.index || 0) - 1;
-			var path = new dojox.grid.TreePath(row, this.grid);
+			var path = new TreePath(row, this.grid);
 			if(col < 0){
 				var new_path = path.previous();
 				if(!new_path){
@@ -477,7 +493,7 @@ dojo.declare("dojox.grid._TreeFocusManager", dojox.grid._FocusManager, {
 		var sc = this.grid.scroller,
 			r = this.rowIndex,
 			rc = this.grid.rowCount-1,
-			path = new dojox.grid.TreePath(this.rowIndex, this.grid);
+			path = new TreePath(this.rowIndex, this.grid);
 		if(inRowDelta){
 			var row;
 			if(inRowDelta>0){
@@ -517,7 +533,7 @@ dojo.declare("dojox.grid._TreeFocusManager", dojox.grid._FocusManager, {
 	}
 });
 
-dojo.declare("dojox.grid.TreeGrid", dojox.grid.DataGrid, {
+var TreeGrid = declare("dojox.grid.TreeGrid", DataGrid, {
 	// summary:
 	//		A grid that supports nesting rows - it provides an expando function
 	//		similar to dijit.Tree.  It also provides mechanisms for aggregating
@@ -567,10 +583,10 @@ dojo.declare("dojox.grid.TreeGrid", dojox.grid.DataGrid, {
 
 
 	// Override this to get our "magic" layout
-	_layoutClass: dojox.grid._TreeLayout,
+	_layoutClass: _TreeLayout,
 
 	createSelection: function(){
-		this.selection = new dojox.grid.TreeSelection(this);
+		this.selection = new TreeSelection(this);
 	},
 
 	_childItemSorter: function(a, b, attribute, descending){
@@ -618,7 +634,7 @@ dojo.declare("dojox.grid.TreeGrid", dojox.grid.DataGrid, {
 	_addItem: function(item, index, noUpdate, dontUpdateRoot){
 		// add our root items to the root of the model's children
 		// list since we don't query the model
-		if(!dontUpdateRoot && this.model && dojo.indexOf(this.model.root.children, item) == -1){
+		if(!dontUpdateRoot && this.model && array.indexOf(this.model.root.children, item) == -1){
 			this.model.root.children[index] = item;
 		}
 		this.inherited(arguments);
@@ -629,8 +645,8 @@ dojo.declare("dojox.grid.TreeGrid", dojox.grid.DataGrid, {
 		//		overridden so that you can pass in a '/' delimited string of indexes to get the
 		//		item based off its path...that is, passing in "1/3/2" will get the
 		//		3rd (0-based) child from the 4th child of the 2nd top-level item.
-		var isArray = dojo.isArray(idx);
-		if(dojo.isString(idx) && idx.indexOf('/')){
+		var isArray = lang.isArray(idx);
+		if(lang.isString(idx) && idx.indexOf('/')){
 			idx = idx.split('/');
 			isArray = true;
 		}
@@ -639,10 +655,10 @@ dojo.declare("dojox.grid.TreeGrid", dojox.grid.DataGrid, {
 			isArray = false;
 		}
 		if(!isArray){
-			return dojox.grid.DataGrid.prototype.getItem.call(this, idx);
+			return DataGrid.prototype.getItem.call(this, idx);
 		}
 		var s = this.store;
-		var itm = dojox.grid.DataGrid.prototype.getItem.call(this, idx[0]);
+		var itm = DataGrid.prototype.getItem.call(this, idx[0]);
 		var cf, i, j;
 		if(this.aggregator){
 			cf = this.aggregator.childFields||[];
@@ -692,7 +708,7 @@ dojo.declare("dojox.grid.TreeGrid", dojox.grid.DataGrid, {
 			this.defaultOpen = false;
 		}
 		var def = this.defaultOpen;
-		this.openAtLevels = dojo.map(this.openAtLevels, function(l){
+		this.openAtLevels = array.map(this.openAtLevels, function(l){
 			if(typeof l == "string"){
 				switch(l.toLowerCase()){
 					case "true":
@@ -729,11 +745,11 @@ dojo.declare("dojox.grid.TreeGrid", dojox.grid.DataGrid, {
 	},
 	
 	_setModel: function(treeModel){
-		if(treeModel && (!dijit.tree.ForestStoreModel || !(treeModel instanceof dijit.tree.ForestStoreModel))){
+		if(treeModel && (!ForestStoreModel || !(treeModel instanceof ForestStoreModel))){
 			throw new Error("dojox.grid.TreeGrid: treeModel must be an instance of dijit.tree.ForestStoreModel");
 		}
 		this.treeModel = treeModel;
-		dojo.toggleClass(this.domNode, "dojoxGridTreeModel", this.treeModel ? true : false);
+		domClass.toggle(this.domNode, "dojoxGridTreeModel", this.treeModel ? true : false);
 		this._setQuery(treeModel ? treeModel.query : null);
 		this._setStore(treeModel ? treeModel.store : null);
 	},
@@ -748,11 +764,11 @@ dojo.declare("dojox.grid.TreeGrid", dojox.grid.DataGrid, {
 		//		create grid managers for various tasks including rows, focus, selection, editing
 
 		// row manager
-		this.rows = new dojox.grid._RowManager(this);
+		this.rows = new _RowManager(this);
 		// focus manager
-		this.focus = new dojox.grid._TreeFocusManager(this);
+		this.focus = new _TreeFocusManager(this);
 		// edit manager
-		this.edit = new dojox.grid._EditManager(this);
+		this.edit = new _EditManager(this);
 	},
 
 	_setStore: function(store){
@@ -793,7 +809,7 @@ dojo.declare("dojox.grid.TreeGrid", dojox.grid.DataGrid, {
 			this.inherited(arguments);
 			return;
 		}
-		var base = dojo.attr(row.node, 'dojoxTreeGridBaseClasses');
+		var base = domAttr.get(row.node, 'dojoxTreeGridBaseClasses');
 		if(base){
 			row.customClasses = base;
 		}
@@ -808,17 +824,17 @@ dojo.declare("dojox.grid.TreeGrid", dojox.grid.DataGrid, {
 	styleRowNode: function(inRowIndex, inRowNode){
 		if(inRowNode){
 			if(inRowNode.tagName.toLowerCase() == 'div' && this.aggregator){
-				dojo.query("tr[dojoxTreeGridPath]", inRowNode).forEach(function(rowNode){
-					this.rows.styleRowNode(dojo.attr(rowNode, 'dojoxTreeGridPath'), rowNode);
+				query("tr[dojoxTreeGridPath]", inRowNode).forEach(function(rowNode){
+					this.rows.styleRowNode(domAttr.get(rowNode, 'dojoxTreeGridPath'), rowNode);
 				},this);
 			}
 			this.rows.styleRowNode(inRowIndex, inRowNode);
 		}
 	},
 	onCanSelect: function(inRowIndex){
-		var nodes = dojo.query("tr[dojoxTreeGridPath='" + inRowIndex + "']", this.domNode);
+		var nodes = query("tr[dojoxTreeGridPath='" + inRowIndex + "']", this.domNode);
 		if(nodes.length){
-			if(dojo.hasClass(nodes[0], 'dojoxGridSummaryRow')){
+			if(domClass.contains(nodes[0], 'dojoxGridSummaryRow')){
 				return false;
 			}
 		}
@@ -828,20 +844,19 @@ dojo.declare("dojox.grid.TreeGrid", dojox.grid.DataGrid, {
 		if(e.altKey || e.metaKey){
 			return;
 		}
-		var dk = dojo.keys;
 		switch(e.keyCode){
-			case dk.UP_ARROW:
+			case keys.UP_ARROW:
 				if(!this.edit.isEditing() && this.focus.rowIndex != "0"){
-					dojo.stopEvent(e);
+					event.stop(e);
 					this.focus.move(-1, 0);
 				}
 				break;
-			case dk.DOWN_ARROW:
-				var currPath = new dojox.grid.TreePath(this.focus.rowIndex, this);
-				var lastPath = new dojox.grid.TreePath(this.rowCount-1, this);
+			case keys.DOWN_ARROW:
+				var currPath = new TreePath(this.focus.rowIndex, this);
+				var lastPath = new TreePath(this.rowCount-1, this);
 				lastPath = lastPath.lastChild(true);
 				if(!this.edit.isEditing() && currPath.toString() != lastPath.toString()){
-					dojo.stopEvent(e);
+					event.stop(e);
 					this.focus.move(1, 0);
 				}
 				break;
@@ -869,10 +884,9 @@ dojo.declare("dojox.grid.TreeGrid", dojox.grid.DataGrid, {
 		this.onApplyCellEdit(inValue, inRowIndex, inAttrName);
 	}
 });
-dojox.grid.TreeGrid.markupFactory = function(props, node, ctor, cellFunc){
-	var d = dojo;
+TreeGrid.markupFactory = function(props, node, ctor, cellFunc){
 	var widthFromAttr = function(n){
-		var w = d.attr(n, "width")||"auto";
+		var w = domAttr.get(n, "width")||"auto";
 		if((w != "auto")&&(w.slice(-2) != "em")&&(w.slice(-1) != "%")){
 			w = parseInt(w, 10)+"px";
 		}
@@ -883,50 +897,50 @@ dojox.grid.TreeGrid.markupFactory = function(props, node, ctor, cellFunc){
 		var rows;
 		// Don't support colgroup on our grid - single view, single row only
 		if(table.nodeName.toLowerCase() == "table" &&
-					d.query("> colgroup", table).length === 0 &&
-					(rows = d.query("> thead > tr", table)).length == 1){
+					query("> colgroup", table).length === 0 &&
+					(rows = query("> thead > tr", table)).length == 1){
 			var tr = rows[0];
-			return d.query("> th", rows[0]).map(function(th){
+			return query("> th", rows[0]).map(function(th){
 				// Grab type and field (the only ones that are shared
 				var cell = {
-					type: d.trim(d.attr(th, "cellType")||""),
-					field: d.trim(d.attr(th, "field")||"")
+					type: lang.trim(domAttr.get(th, "cellType")||""),
+					field: lang.trim(domAttr.get(th, "field")||"")
 				};
 				if(cell.type){
-					cell.type = d.getObject(cell.type);
+					cell.type = lang.getObject(cell.type);
 				}
 				
-				var subTable = d.query("> table", th)[0];
+				var subTable = query("> table", th)[0];
 				if(subTable){
 					// If we have a subtable, we are an aggregate and a summary cell
 					cell.name = "";
 					cell.children = cellsFromMarkup(subTable);
-					if(d.hasAttr(th, "itemAggregates")){
-						cell.itemAggregates = d.map(d.attr(th, "itemAggregates").split(","), function(v){
-							return d.trim(v);
+					if(domAttr.has(th, "itemAggregates")){
+						cell.itemAggregates = array.map(domAttr.get(th, "itemAggregates").split(","), function(v){
+							return lang.trim(v);
 						});
 					}else{
 						cell.itemAggregates = [];
 					}
-					if(d.hasAttr(th, "aggregate")){
-						cell.aggregate = d.attr(th, "aggregate");
+					if(domAttr.has(th, "aggregate")){
+						cell.aggregate = domAttr.get(th, "aggregate");
 					}
 					cell.type = cell.type || dojox.grid.cells.SubtableCell;
 				}else{
 					// Grab our other stuff we need (mostly what's in the normal
 					// Grid)
-					cell.name = d.trim(d.attr(th, "name")||th.innerHTML);
-					if(d.hasAttr(th, "width")){
+					cell.name = lang.trim(domAttr.get(th, "name")||th.innerHTML);
+					if(domAttr.has(th, "width")){
 						cell.width = widthFromAttr(th);
 					}
-					if(d.hasAttr(th, "relWidth")){
-						cell.relWidth = window.parseInt(d.attr(th, "relWidth"), 10);
+					if(domAttr.has(th, "relWidth")){
+						cell.relWidth = window.parseInt(domAttr.get(th, "relWidth"), 10);
 					}
-					if(d.hasAttr(th, "hidden")){
-						cell.hidden = d.attr(th, "hidden") == "true";
+					if(domAttr.has(th, "hidden")){
+						cell.hidden = domAttr.get(th, "hidden") == "true";
 					}
 					cell.field = cell.field||cell.name;
-					dojox.grid.DataGrid.cell_markupFactory(cellFunc, th, cell);
+					DataGrid.cell_markupFactory(cellFunc, th, cell);
 					cell.type = cell.type || dojox.grid.cells.Cell;
 				}
 				if(cell.type && cell.type.markupFactory){
@@ -947,5 +961,9 @@ dojox.grid.TreeGrid.markupFactory = function(props, node, ctor, cellFunc){
 			props.structure = [{__span: Infinity, cells:[row]}];
 		}
 	}
-	return dojox.grid.DataGrid.markupFactory(props, node, ctor, cellFunc);
+	return DataGrid.markupFactory(props, node, ctor, cellFunc);
 };
+
+return TreeGrid;
+
+});
\ No newline at end of file
diff --git a/dojox/grid/TreeSelection.js b/dojox/grid/TreeSelection.js
index aa1a4fa..cb2609b 100644
--- a/dojox/grid/TreeSelection.js
+++ b/dojox/grid/TreeSelection.js
@@ -1,14 +1,20 @@
-dojo.provide("dojox.grid.TreeSelection");
+define([
+	"../main",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/dom-attr",
+	"dojo/query",
+	"./DataSelection"
+], function(dojox, declare, array, lang, domAttr, query, DataSelection){
 
-dojo.require("dojox.grid.DataSelection");
-
-dojo.declare("dojox.grid.TreeSelection", dojox.grid.DataSelection, {
+return declare("dojox.grid.TreeSelection", DataSelection, {
 	setMode: function(mode){
 		this.selected = {};
 		this.sorted_sel = [];
 		this.sorted_ltos = {};
 		this.sorted_stol = {};
-		dojox.grid.DataSelection.prototype.setMode.call(this, mode);
+		DataSelection.prototype.setMode.call(this, mode);
 	},
 	addToSelection: function(inItemOrIndex){
 		if(this.mode == 'none'){ return; }
@@ -23,9 +29,9 @@ dojo.declare("dojox.grid.TreeSelection", dojox.grid.DataSelection, {
 		}else{
 			if(this.onCanSelect(idx) !== false){
 				this.selectedIndex = idx;
-				var rowNodes = dojo.query("tr[dojoxTreeGridPath='" + idx + "']", this.grid.domNode);
+				var rowNodes = query("tr[dojoxTreeGridPath='" + idx + "']", this.grid.domNode);
 				if(rowNodes.length){
-					dojo.attr(rowNodes[0],"aria-selected","true");
+					domAttr.set(rowNodes[0], "aria-selected", "true");
 				}
 				this._beginUpdate();
 				this.selected[idx] = true;
@@ -52,9 +58,9 @@ dojo.declare("dojox.grid.TreeSelection", dojox.grid.DataSelection, {
 			if(this.onCanDeselect(idx) === false){
 				return;
 			}
-			var rowNodes = dojo.query("tr[dojoxTreeGridPath='" + idx + "']", this.grid.domNode);
+			var rowNodes = query("tr[dojoxTreeGridPath='" + idx + "']", this.grid.domNode);
 			if(rowNodes.length){
-				dojo.attr(rowNodes[0],"aria-selected","false");
+				domAttr.set(rowNodes[0], "aria-selected", "false");
 			}
 			this._beginUpdate();
 			delete this.selected[idx];
@@ -110,7 +116,7 @@ dojo.declare("dojox.grid.TreeSelection", dojox.grid.DataSelection, {
 		var ss = this.sorted_stol;
 
 		var lpath = index.split('/');
-		lpath = dojo.map(lpath, function(item){ return parseInt(item, 10); });
+		lpath = array.map(lpath, function(item){ return parseInt(item, 10); });
 		sl[lpath] = index;
 		ss[index] = lpath;
 
@@ -174,7 +180,7 @@ dojo.declare("dojox.grid.TreeSelection", dojox.grid.DataSelection, {
 		return this.sorted_ltos[lpath];
 	},
 	_range: function(inFrom, inTo, func){
-		if(!dojo.isString(inFrom) && inFrom < 0){
+		if(!lang.isString(inFrom) && inFrom < 0){
 			inFrom = inTo;
 		}
 		var cells = this.grid.layout.cells,
@@ -206,3 +212,4 @@ dojo.declare("dojox.grid.TreeSelection", dojox.grid.DataSelection, {
 		func(inToStr);
 	}
 });
+});
\ No newline at end of file
diff --git a/dojox/grid/_Builder.js b/dojox/grid/_Builder.js
index fb7b29f..af55e09 100644
--- a/dojox/grid/_Builder.js
+++ b/dojox/grid/_Builder.js
@@ -1,17 +1,25 @@
-dojo.provide("dojox.grid._Builder");
+define([
+	"../main",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/_base/event",
+	"dojo/_base/sniff",
+	"dojo/_base/connect",
+	"dojo/dnd/Moveable",
+	"dojox/html/metrics",
+	"./util",
+	"dojo/_base/html"
+], function(dojox, array, lang, win, event, has, connect, Moveable, metrics, util, html){
 
-dojo.require("dojox.grid.util");
-dojo.require("dojo.dnd.Moveable");
-
-(function(){
 	var dg = dojox.grid;
 
 	var getTdIndex = function(td){
-		return td.cellIndex >=0 ? td.cellIndex : dojo.indexOf(td.parentNode.cells, td);
+		return td.cellIndex >=0 ? td.cellIndex : array.indexOf(td.parentNode.cells, td);
 	};
 	
 	var getTrIndex = function(tr){
-		return tr.rowIndex >=0 ? tr.rowIndex : dojo.indexOf(tr.parentNode.childNodes, tr);
+		return tr.rowIndex >=0 ? tr.rowIndex : array.indexOf(tr.parentNode.childNodes, tr);
 	};
 	
 	var getTr = function(rowOwner, index){
@@ -33,11 +41,11 @@ dojo.require("dojo.dnd.Moveable");
 		return function(node){ return node.tagName != name; };
 	};
 
-	var rowIndexTag = dojox.grid.util.rowIndexTag;
-	var gridViewTag = dojox.grid.util.gridViewTag;
+	var rowIndexTag = util.rowIndexTag;
+	var gridViewTag = util.gridViewTag;
 
 	// base class for generating markup for the views
-	dg._Builder = dojo.extend(function(view){
+	var _Builder = dg._Builder = lang.extend(function(view){
 		if(view){
 			this.view = view;
 			this.grid = view.grid;
@@ -119,11 +127,11 @@ dojo.require("dojo.dnd.Moveable");
 
 		// cell finding
 		isCellNode: function(inNode){
-			return Boolean(inNode && inNode!=dojo.doc && dojo.attr(inNode, "idx"));
+			return Boolean(inNode && inNode!=win.doc && html.attr(inNode, "idx"));
 		},
 		
 		getCellNodeIndex: function(inCellNode){
-			return inCellNode ? Number(dojo.attr(inCellNode, "idx")) : -1;
+			return inCellNode ? Number(html.attr(inCellNode, "idx")) : -1;
 		},
 		
 		getCellNode: function(inRowNode, inCellIndex){
@@ -170,7 +178,7 @@ dojo.require("dojo.dnd.Moveable");
 
 		isIntraNodeEvent: function(e){
 			try{
-				return (e.cellNode && e.relatedTarget && dojo.isDescendant(e.relatedTarget, e.cellNode));
+				return (e.cellNode && e.relatedTarget && html.isDescendant(e.relatedTarget, e.cellNode));
 			}catch(x){
 				// e.relatedTarget has permission problem in FF if it's an input: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
 				return false;
@@ -222,9 +230,9 @@ dojo.require("dojo.dnd.Moveable");
 
 	// Produces html for grid data content. Owned by grid and used internally
 	// for rendering data. Override to implement custom rendering.
-	dg._ContentBuilder = dojo.extend(function(view){
-		dg._Builder.call(this, view);
-	},dg._Builder.prototype,{
+	var _ContentBuilder = dg._ContentBuilder = lang.extend(function(view){
+		_Builder.call(this, view);
+	},_Builder.prototype,{
 		update: function(){
 			this.prepareHtml();
 		},
@@ -251,7 +259,7 @@ dojo.require("dojo.dnd.Moveable");
 				cells = v.structure.cells,
 				item = this.grid.getItem(inRowIndex);
 
-			dojox.grid.util.fire(this.view, "onBeforeRow", [inRowIndex, cells]);
+			util.fire(this.view, "onBeforeRow", [inRowIndex, cells]);
 			for(var j=0, row; (row=cells[j]); j++){
 				if(row.hidden || row.header){
 					continue;
@@ -261,6 +269,10 @@ dojo.require("dojo.dnd.Moveable");
 					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
@@ -286,10 +298,10 @@ dojo.require("dojo.dnd.Moveable");
 
 	// Produces html for grid header content. Owned by grid and used internally
 	// for rendering data. Override to implement custom rendering.
-	dg._HeaderBuilder = dojo.extend(function(view){
+	var _HeaderBuilder = dg._HeaderBuilder = lang.extend(function(view){
 		this.moveable = null;
-		dg._Builder.call(this, view);
-	},dg._Builder.prototype,{
+		_Builder.call(this, view);
+	},_Builder.prototype,{
 		_skipBogusClicks: false,
 		overResizeWidth: 4,
 		minColWidth: 1,
@@ -305,7 +317,7 @@ dojo.require("dojo.dnd.Moveable");
 		generateHtml: function(inGetValue, inValue){
 			var html = this.getTableArray(), cells = this.view.structure.cells;
 			
-			dojox.grid.util.fire(this.view, "onBeforeRow", [-1, cells]);
+			util.fire(this.view, "onBeforeRow", [-1, cells]);
 			for(var j=0, row; (row=cells[j]); j++){
 				if(row.hidden){
 					continue;
@@ -350,11 +362,11 @@ dojo.require("dojo.dnd.Moveable");
 		// event helpers
 		getCellX: function(e){
 			var n, x = e.layerX;
-			if(dojo.isMoz || dojo.isIE >= 9){
+			if(has('mozilla') || has('ie') >= 9){
 				n = ascendDom(e.target, makeNotTagName("th"));
 				x -= (n && n.offsetLeft) || 0;
 				var t = e.sourceView.getScrollbarWidth();
-				if(!dojo._isBodyLtr()/*&& e.sourceView.headerNode.scrollLeft < t*/){
+				if(!this.grid.isLeftToRight()/*&& e.sourceView.headerNode.scrollLeft < t*/){
 					//fix #11253
 					table = ascendDom(n,makeNotTagName("table"));
 					x -= (table && table.offsetLeft) || 0;
@@ -386,7 +398,7 @@ dojo.require("dojo.dnd.Moveable");
 		// resizing
 		prepareResize: function(e, mod){
 			do{
-				var i = getTdIndex(e.cellNode);
+				var i = e.cellIndex;
 				e.cellNode = (i ? e.cellNode.parentNode.cells[i+mod] : null);
 				e.cellIndex = (e.cellNode ? this.getCellNodeIndex(e.cellNode) : -1);
 			}while(e.cellNode && e.cellNode.style.display == "none");
@@ -403,22 +415,23 @@ dojo.require("dojo.dnd.Moveable");
 
 		overLeftResizeArea: function(e){
 			// We are never over a resize area if we are in the process of moving
-			if(dojo.hasClass(dojo.body(), "dojoDndMove")){
+			if(html.hasClass(win.body(), "dojoDndMove")){
 				return false;
 			}
 			//Bugfix for crazy IE problem (#8807).  IE returns position information for the icon and text arrow divs
 			//as if they were still on the left instead of returning the position they were 'float: right' to.
 			//So, the resize check ends up checking the wrong adjacent cell.  This checks to see if the hover was over
 			//the image or text nodes, then just ignored them/treat them not in scale range.
-			if(dojo.isIE){
+			if(has('ie')){
 				var tN = e.target;
-				if(dojo.hasClass(tN, "dojoxGridArrowButtonNode") ||
-					dojo.hasClass(tN, "dojoxGridArrowButtonChar")){
+				if(html.hasClass(tN, "dojoxGridArrowButtonNode") ||
+					html.hasClass(tN, "dojoxGridArrowButtonChar") ||
+					html.hasClass(tN, "dojoxGridColCaption")){
 					return false;
 				}
 			}
 
-			if(dojo._isBodyLtr()){
+			if(this.grid.isLeftToRight()){
 				return (e.cellIndex>0) && (e.cellX > 0 && e.cellX < this.overResizeWidth) && this.prepareResize(e, -1);
 			}
 			var t = e.cellNode && (e.cellX > 0 && e.cellX < this.overResizeWidth);
@@ -427,22 +440,23 @@ dojo.require("dojo.dnd.Moveable");
 
 		overRightResizeArea: function(e){
 			// We are never over a resize area if we are in the process of moving
-			if(dojo.hasClass(dojo.body(), "dojoDndMove")){
+			if(html.hasClass(win.body(), "dojoDndMove")){
 				return false;
 			}
 			//Bugfix for crazy IE problem (#8807).  IE returns position information for the icon and text arrow divs
 			//as if they were still on the left instead of returning the position they were 'float: right' to.
 			//So, the resize check ends up checking the wrong adjacent cell.  This checks to see if the hover was over
 			//the image or text nodes, then just ignored them/treat them not in scale range.
-			if(dojo.isIE){
+			if(has('ie')){
 				var tN = e.target;
-				if(dojo.hasClass(tN, "dojoxGridArrowButtonNode") ||
-					dojo.hasClass(tN, "dojoxGridArrowButtonChar")){
+				if(html.hasClass(tN, "dojoxGridArrowButtonNode") ||
+					html.hasClass(tN, "dojoxGridArrowButtonChar") ||
+					html.hasClass(tN, "dojoxGridColCaption")){
 					return false;
 				}
 			}
 
-			if(dojo._isBodyLtr()){
+			if(this.grid.isLeftToRight()){
 				return e.cellNode && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth);
 			}
 			return (e.cellIndex>0) && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth) && this.prepareResize(e, -1);
@@ -455,14 +469,10 @@ dojo.require("dojo.dnd.Moveable");
 				if(c && !this.canResize(e)){
 					c = 'dojoxGridColNoResize';
 				}
-				dojo.toggleClass(e.sourceView.headerNode, "dojoxGridColNoResize", (c == "dojoxGridColNoResize"));
-				dojo.toggleClass(e.sourceView.headerNode, "dojoxGridColResize", (c == "dojoxGridColResize"));
-				if(dojo.isIE){
-					var t = e.sourceView.headerNode.scrollLeft;
-					e.sourceView.headerNode.scrollLeft = t;
-				}
+				html.toggleClass(e.sourceView.headerNode, "dojoxGridColNoResize", (c == "dojoxGridColNoResize"));
+				html.toggleClass(e.sourceView.headerNode, "dojoxGridColResize", (c == "dojoxGridColResize"));
 				if(c){
-					dojo.stopEvent(e);
+					event.stop(e);
 				}
 			}
 		},
@@ -483,7 +493,7 @@ dojo.require("dojo.dnd.Moveable");
 
 		doclick: function(e) {
 			if(this._skipBogusClicks){
-				dojo.stopEvent(e);
+				event.stop(e);
 				return true;
 			}
 			return false;
@@ -494,27 +504,26 @@ dojo.require("dojo.dnd.Moveable");
 			//Set up the drag object for column resizing
 			// Called with mouse event in case of drag and drop,
 			// Also called from keyboard shift-arrow event when focus is on a header
-			var headContentBox = dojo.contentBox(e.sourceView.headerNode);
+			var headContentBox = html.contentBox(e.sourceView.headerNode);
 			
 			if(isMouse){  //IE draws line even with no mouse down so separate from keyboard
 				this.lineDiv = document.createElement('div');
 
-				// NOTE: this is for backwards compatibility with Dojo 1.3
-				var vw = (dojo.position||dojo._abs)(e.sourceView.headerNode, true);
-				var bodyContentBox = dojo.contentBox(e.sourceView.domNode);
+				var vw = html.position(e.sourceView.headerNode, true);
+				var bodyContentBox = html.contentBox(e.sourceView.domNode);
 				//fix #11340
 				var l = e.pageX;
-				if(!dojo._isBodyLtr() && dojo.isIE < 8){
-					l -= dojox.html.metrics.getScrollbar().w;
+				if(!this.grid.isLeftToRight() && has('ie') < 8){
+					l -= metrics.getScrollbar().w;
 				}
-				dojo.style(this.lineDiv, {
+				html.style(this.lineDiv, {
 					top: vw.y + "px",
 					left: l + "px",
 					height: (bodyContentBox.h + headContentBox.h) + "px"
 				});
-				dojo.addClass(this.lineDiv, "dojoxGridResizeColLine");
+				html.addClass(this.lineDiv, "dojoxGridResizeColLine");
 				this.lineDiv._origLeft = l;
-				dojo.body().appendChild(this.lineDiv);
+				win.body().appendChild(this.lineDiv);
 			}
 			var spanners = [], nodes = this.tableMap.findOverlappingNodes(e.cellNode);
 			for(var i=0, cell; (cell=nodes[i]); i++){
@@ -523,7 +532,7 @@ dojo.require("dojo.dnd.Moveable");
 			}
 
 			var view = e.sourceView;
-			var adj = dojo._isBodyLtr() ? 1 : -1;
+			var adj = this.grid.isLeftToRight() ? 1 : -1;
 			var views = e.grid.views.views;
 			var followers = [];
 			for(var j=view.idx+adj, cView; (cView=views[j]); j=j+adj){
@@ -535,10 +544,10 @@ dojo.require("dojo.dnd.Moveable");
 				view: view,
 				node: e.cellNode,
 				index: e.cellIndex,
-				w: dojo.contentBox(e.cellNode).w,
+				w: html.contentBox(e.cellNode).w,
 				vw: headContentBox.w,
 				table: table,
-				tw: dojo.contentBox(table).w,
+				tw: html.contentBox(table).w,
 				spanners: spanners,
 				followers: followers
 			};
@@ -546,16 +555,16 @@ dojo.require("dojo.dnd.Moveable");
 		},
 		beginColumnResize: function(e){
 			this.moverDiv = document.createElement("div");
-			dojo.style(this.moverDiv,{position: "absolute", left:0}); // to make DnD work with dir=rtl
-			dojo.body().appendChild(this.moverDiv);
-			dojo.addClass(this.grid.domNode, "dojoxGridColumnResizing");
-			var m = (this.moveable = new dojo.dnd.Moveable(this.moverDiv));
+			html.style(this.moverDiv,{position: "absolute", left:0}); // to make DnD work with dir=rtl
+			win.body().appendChild(this.moverDiv);
+			html.addClass(this.grid.domNode, "dojoxGridColumnResizing");
+			var m = (this.moveable = new Moveable(this.moverDiv));
 
 			var drag = this.colResizeSetup(e,true);
 
-			m.onMove = dojo.hitch(this, "doResizeColumn", drag);
+			m.onMove = lang.hitch(this, "doResizeColumn", drag);
 
-			dojo.connect(m, "onMoveStop", dojo.hitch(this, function(){
+			connect.connect(m, "onMoveStop", lang.hitch(this, function(){
 				this.endResizeColumn(drag);
 				if(drag.node.releaseCapture){
 					drag.node.releaseCapture();
@@ -563,7 +572,7 @@ dojo.require("dojo.dnd.Moveable");
 				this.moveable.destroy();
 				delete this.moveable;
 				this.moveable = null;
-				dojo.removeClass(this.grid.domNode, "dojoxGridColumnResizing");
+				html.removeClass(this.grid.domNode, "dojoxGridColumnResizing");
 			}));
 
 			if(e.cellNode.setCapture){
@@ -576,7 +585,7 @@ dojo.require("dojo.dnd.Moveable");
 			var changeX = leftTop.l;
 			var data = {
 				deltaX: changeX,
-				w: inDrag.w + (dojo._isBodyLtr() ? changeX : -changeX),//fix #11341
+				w: inDrag.w + (this.grid.isLeftToRight() ? changeX : -changeX),//fix #11341
 				vw: inDrag.vw + changeX,
 				tw: inDrag.tw + changeX
 			};
@@ -588,7 +597,7 @@ dojo.require("dojo.dnd.Moveable");
 					this.doResizeNow(inDrag, data);
 				}
 				else{
-					dojo.style(this.lineDiv, "left", (this.lineDiv._origLeft + data.deltaX) + "px");
+					html.style(this.lineDiv, "left", (this.lineDiv._origLeft + data.deltaX) + "px");
 				}
 			}
 		},
@@ -596,13 +605,13 @@ dojo.require("dojo.dnd.Moveable");
 		endResizeColumn: function(inDrag){
 			if(this.dragRecord){
 				var leftTop = this.dragRecord.leftTop;
-				var changeX = dojo._isBodyLtr() ? leftTop.l : -leftTop.l;
+				var changeX = this.grid.isLeftToRight() ? leftTop.l : -leftTop.l;
 				// Make sure we are not under our minimum
 				// http://bugs.dojotoolkit.org/ticket/9390
 				changeX += Math.max(inDrag.w + changeX, this.minColWidth) - (inDrag.w + changeX);
-				if(dojo.isWebKit && inDrag.spanners.length){
+				if(has('webkit') && inDrag.spanners.length){
 					// Webkit needs the pad border extents back in
-					changeX += dojo._getPadBorderExtents(inDrag.spanners[0].node).w;
+					changeX += html._getPadBorderExtents(inDrag.spanners[0].node).w;
 				}
 				var data = {
 					deltaX: changeX,
@@ -615,9 +624,9 @@ dojo.require("dojo.dnd.Moveable");
 				delete this.dragRecord;
 			}
 			
-			dojo.destroy(this.lineDiv);
- 			dojo.destroy(this.moverDiv);
-			dojo.destroy(this.moverDiv);
+			html.destroy(this.lineDiv);
+ 			html.destroy(this.moverDiv);
+			html.destroy(this.moverDiv);
 			delete this.moverDiv;
 			this._skipBogusClicks = true;
 			inDrag.view.update();
@@ -640,7 +649,7 @@ dojo.require("dojo.dnd.Moveable");
 					inDrag.view.setColWidth(s.index, sw);
 				}
 			}
-			if(dojo._isBodyLtr() || !dojo.isIE){//fix #11339
+			if(this.grid.isLeftToRight() || !has('ie')){//fix #11339
 				for(i=0; (f=inDrag.followers[i]); i++){
 					fl = f.left + data.deltaX;
 					f.node.style.left = fl + 'px';
@@ -650,7 +659,7 @@ dojo.require("dojo.dnd.Moveable");
 			inDrag.view.setColWidth(inDrag.index, data.w);
 			inDrag.view.headerNode.style.width = data.vw + 'px';
 			inDrag.view.setColumnsWidth(data.tw);
-			if(!dojo._isBodyLtr()){
+			if(!this.grid.isLeftToRight()){
 				inDrag.view.headerNode.scrollLeft = inDrag.scrollLeft + data.deltaX;
 			}
 		}
@@ -658,7 +667,7 @@ dojo.require("dojo.dnd.Moveable");
 
 	// Maps an html table into a structure parsable for information about cell row and col spanning.
 	// Used by HeaderBuilder.
-	dg._TableMap = dojo.extend(function(rows){
+	dg._TableMap = lang.extend(function(rows){
 		this.mapRows(rows);
 	},{
 		map: null,
@@ -741,4 +750,10 @@ dojo.require("dojo.dnd.Moveable");
 			return this._findOverlappingNodes(findTable(inNode), getTrIndex(inNode.parentNode), getTdIndex(inNode));
 		}
 	});
-})();
+
+	return {
+		_Builder: _Builder,
+		_HeaderBuilder: _HeaderBuilder,
+		_ContentBuilder: _ContentBuilder
+	};
+});
\ No newline at end of file
diff --git a/dojox/grid/_CheckBoxSelector.js b/dojox/grid/_CheckBoxSelector.js
index fad9313..1f66256 100644
--- a/dojox/grid/_CheckBoxSelector.js
+++ b/dojox/grid/_CheckBoxSelector.js
@@ -1,3 +1,3 @@
-dojo.provide("dojox.grid._CheckBoxSelector");
-
-dojo.require("dojox.grid._Selector");
+define(["../main", "./_Selector"], function(dojox){
+	return dojox.grid._CheckBoxSelector;
+});
\ No newline at end of file
diff --git a/dojox/grid/_EditManager.js b/dojox/grid/_EditManager.js
index 7477c71..5ae4559 100644
--- a/dojox/grid/_EditManager.js
+++ b/dojox/grid/_EditManager.js
@@ -1,25 +1,30 @@
-dojo.provide("dojox.grid._EditManager");
+define([
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/connect",
+	"dojo/_base/sniff",
+	"./util"
+], function(lang, array, declare, connect, has, util){
 
-dojo.require("dojox.grid.util");
-
-dojo.declare("dojox.grid._EditManager", null, {
+return declare("dojox.grid._EditManager", null, {
 	// summary:
 	//		Controls grid cell editing process. Owned by grid and used internally for editing.
 	constructor: function(inGrid){
 		// inGrid: dojox.Grid
 		//		The dojox.Grid this editor should be attached to
 		this.grid = inGrid;
-		if(dojo.isIE){
-			this.connections = [dojo.connect(document.body, "onfocus", dojo.hitch(this, "_boomerangFocus"))];
+		if(has('ie')){
+			this.connections = [connect.connect(document.body, "onfocus", lang.hitch(this, "_boomerangFocus"))];
 		}else{
-			this.connections = [dojo.connect(this.grid, 'onBlur', this, 'apply')];
+			this.connections = [connect.connect(this.grid, 'onBlur', this, 'apply')];
 		}
 	},
 	
 	info: {},
 
 	destroy: function(){
-		dojo.forEach(this.connections,dojo.disconnect);
+		array.forEach(this.connections, connect.disconnect);
 	},
 
 	cellFocus: function(inCell, inRowIndex){
@@ -104,7 +109,7 @@ dojo.declare("dojox.grid._EditManager", null, {
 	},
 
 	_focusEditor: function(inCell, inRowIndex){
-		dojox.grid.util.fire(inCell, "focus", [inRowIndex]);
+		util.fire(inCell, "focus", [inRowIndex]);
 	},
 
 	focusEditor: function(){
@@ -131,11 +136,14 @@ dojo.declare("dojox.grid._EditManager", null, {
 	},
 	_doCatchBoomerang: function(){
 		// give ourselves a few ms to boomerang IE focus effects
-		if(dojo.isIE){this._catchBoomerang = new Date().getTime() + this._boomerangWindow;}
+		if(has('ie')){this._catchBoomerang = new Date().getTime() + this._boomerangWindow;}
 	},
 	// end boomerang fix API
 
 	start: function(inCell, inRowIndex, inEditing){
+		if(!this._isValidInput()){
+			return;
+		}
 		this.grid.beginUpdate();
 		this.editorApply();
 		if(this.isEditing() && !this.isEditRow(inRowIndex)){
@@ -187,7 +195,7 @@ dojo.declare("dojox.grid._EditManager", null, {
 	apply: function(){
 		// summary:
 		//		Apply a grid edit
-		if(this.isEditing()){
+		if(this.isEditing() && this._isValidInput()){
 			this.grid.beginUpdate();
 			this.editorApply();
 			this.applyRowEdit();
@@ -233,7 +241,18 @@ dojo.declare("dojox.grid._EditManager", null, {
 		//		Grid view
 		var c = this.info.cell;
 		if(this.isEditRow(inRowIndex) && c.view == inView && c.editable){
-			c.restore(c, this.info.rowIndex);
+			c.restore(this.info.rowIndex);
 		}
+	},
+	
+	_isValidInput: function(){
+		var w = (this.info.cell || {}).widget;		
+		if(!w || !w.isValid){
+			//no validation needed
+			return true;
+		}		
+		w.focused = true;
+		return w.isValid(true);
 	}
 });
+});
\ No newline at end of file
diff --git a/dojox/grid/_Events.js b/dojox/grid/_Events.js
index 77aeace..5e61c46 100644
--- a/dojox/grid/_Events.js
+++ b/dojox/grid/_Events.js
@@ -1,6 +1,12 @@
-dojo.provide("dojox.grid._Events");
-
-dojo.declare("dojox.grid._Events", null, {
+define([
+	"dojo/keys",
+	"dojo/dom-class",
+	"dojo/_base/declare",
+	"dojo/_base/event",
+	"dojo/_base/sniff"
+], function(keys, domClass, declare, event, has){
+
+return declare("dojox.grid._Events", null, {
 	// summary:
 	//		_Grid mixin that provides default implementations for grid events.
 	// description:
@@ -49,13 +55,12 @@ dojo.declare("dojox.grid._Events", null, {
 		if(e.altKey || e.metaKey){
 			return;
 		}
-		var dk = dojo.keys;
 		var colIdx;
 		switch(e.keyCode){
-			case dk.ESCAPE:
+			case keys.ESCAPE:
 				this.edit.cancel();
 				break;
-			case dk.ENTER:
+			case keys.ENTER:
 				if(!this.edit.isEditing()){
 					colIdx = this.focus.getHeaderIndex();
 					if(colIdx >= 0) {
@@ -64,7 +69,7 @@ dojo.declare("dojox.grid._Events", null, {
 					}else {
 						this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey);
 					}
-					dojo.stopEvent(e);
+					event.stop(e);
 				}
 				if(!e.shiftKey){
 					var isEditing = this.edit.isEditing();
@@ -77,10 +82,10 @@ dojo.declare("dojox.grid._Events", null, {
 					var curView = this.focus.focusView || this.views.views[0];  //if no focusView than only one view
 					curView.content.decorateEvent(e);
 					this.onRowClick(e);
-					dojo.stopEvent(e);
+					event.stop(e);
 				}
 				break;
-			case dk.SPACE:
+			case keys.SPACE:
 				if(!this.edit.isEditing()){
 					colIdx = this.focus.getHeaderIndex();
 					if(colIdx >= 0) {
@@ -89,43 +94,43 @@ dojo.declare("dojox.grid._Events", null, {
 					}else {
 						this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey);
 					}
-					dojo.stopEvent(e);
+					event.stop(e);
 				}
 				break;
-			case dk.TAB:
+			case keys.TAB:
 				this.focus[e.shiftKey ? 'previousKey' : 'nextKey'](e);
 				break;
-			case dk.LEFT_ARROW:
-			case dk.RIGHT_ARROW:
+			case keys.LEFT_ARROW:
+			case keys.RIGHT_ARROW:
 				if(!this.edit.isEditing()){
 					var keyCode = e.keyCode;  // IE seems to lose after stopEvent when modifier keys
-					dojo.stopEvent(e);
+					event.stop(e);
 					colIdx = this.focus.getHeaderIndex();
 					if (colIdx >= 0 && (e.shiftKey && e.ctrlKey)){
-						this.focus.colSizeAdjust(e, colIdx, (keyCode == dk.LEFT_ARROW ? -1 : 1)*5);
+						this.focus.colSizeAdjust(e, colIdx, (keyCode == keys.LEFT_ARROW ? -1 : 1)*5);
 					}
 					else{
-						var offset = (keyCode == dk.LEFT_ARROW) ? 1 : -1;
-						if(dojo._isBodyLtr()){ offset *= -1; }
+						var offset = (keyCode == keys.LEFT_ARROW) ? 1 : -1;
+						if(this.isLeftToRight()){ offset *= -1; }
 						this.focus.move(0, offset);
 					}
 				}
 				break;
-			case dk.UP_ARROW:
+			case keys.UP_ARROW:
 				if(!this.edit.isEditing() && this.focus.rowIndex !== 0){
-					dojo.stopEvent(e);
+					event.stop(e);
 					this.focus.move(-1, 0);
 				}
 				break;
-			case dk.DOWN_ARROW:
+			case keys.DOWN_ARROW:
 				if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){
-					dojo.stopEvent(e);
+					event.stop(e);
 					this.focus.move(1, 0);
 				}
 				break;
-			case dk.PAGE_UP:
+			case keys.PAGE_UP:
 				if(!this.edit.isEditing() && this.focus.rowIndex !== 0){
-					dojo.stopEvent(e);
+					event.stop(e);
 					if(this.focus.rowIndex != this.scroller.firstVisibleRow+1){
 						this.focus.move(this.scroller.firstVisibleRow-this.focus.rowIndex, 0);
 					}else{
@@ -134,9 +139,9 @@ dojo.declare("dojox.grid._Events", null, {
 					}
 				}
 				break;
-			case dk.PAGE_DOWN:
+			case keys.PAGE_DOWN:
 				if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){
-					dojo.stopEvent(e);
+					event.stop(e);
 					if(this.focus.rowIndex != this.scroller.lastVisibleRow-1){
 						this.focus.move(this.scroller.lastVisibleRow-this.focus.rowIndex-1, 0);
 					}else{
@@ -213,7 +218,7 @@ dojo.declare("dojox.grid._Events", null, {
 		// e: Event
 		//		Decorated event object contains reference to grid, cell, and rowIndex
 		if(e.cellNode){
-			dojo.addClass(e.cellNode, this.cellOverClass);
+			domClass.add(e.cellNode, this.cellOverClass);
 		}
 	},
 	
@@ -223,7 +228,7 @@ dojo.declare("dojox.grid._Events", null, {
 		// e: Event
 		//		Decorated event object which contains reference to grid, cell, and rowIndex
 		if(e.cellNode){
-			dojo.removeClass(e.cellNode, this.cellOverClass);
+			domClass.remove(e.cellNode, this.cellOverClass);
 		}
 	},
 	
@@ -244,6 +249,10 @@ dojo.declare("dojox.grid._Events", null, {
 		if(!this.edit.isEditCell(e.rowIndex, e.cellIndex)){
 			this.focus.setFocusCell(e.cell, e.rowIndex);
 		}
+		// in some cases click[0] is null which causes false doubeClicks. Fixes #100703
+		if(this._click.length > 1 && this._click[0] == null){
+			this._click.shift();
+		}
 		this.onRowClick(e);
 	},
 
@@ -252,13 +261,17 @@ dojo.declare("dojox.grid._Events", null, {
 		//		Event fired when a cell is double-clicked.
 		// e: Event
 		//		Decorated event object contains reference to grid, cell, and rowIndex
-		if(this._click.length > 1 && dojo.isIE){
-			this.edit.setEditCell(this._click[1].cell, this._click[1].rowIndex);
+		var event;
+		if(this._click.length > 1 && has('ie')){
+			event = this._click[1];
 		}else if(this._click.length > 1 && this._click[0].rowIndex != this._click[1].rowIndex){
-			this.edit.setEditCell(this._click[0].cell, this._click[0].rowIndex);
+			event = this._click[0];
 		}else{
-			this.edit.setEditCell(e.cell, e.rowIndex);
+			event = e;
 		}
+		this.focus.setFocusCell(event.cell, event.rowIndex);
+		this.onRowClick(event);
+		this.edit.setEditCell(event.cell, event.rowIndex);
 		this.onRowDblClick(e);
 	},
 
@@ -323,7 +336,7 @@ dojo.declare("dojox.grid._Events", null, {
 		//		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
-		dojo.stopEvent(e);
+		event.stop(e);
 	},
 
 	// header events
@@ -347,7 +360,7 @@ dojo.declare("dojox.grid._Events", null, {
 		// e: Event
 		// 		Decorated event object which contains reference to grid, cell, and rowIndex
 		if(e.cellNode){
-			dojo.addClass(e.cellNode, this.cellOverClass);
+			domClass.add(e.cellNode, this.cellOverClass);
 		}
 	},
 
@@ -357,7 +370,7 @@ dojo.declare("dojox.grid._Events", null, {
 		// e: Event
 		// 		Decorated event object which contains reference to grid, cell, and rowIndex
 		if(e.cellNode){
-			dojo.removeClass(e.cellNode, this.cellOverClass);
+			domClass.remove(e.cellNode, this.cellOverClass);
 		}
 	},
 	
@@ -413,7 +426,7 @@ dojo.declare("dojox.grid._Events", null, {
 		// e: Event
 		//		Decorated event object which contains reference to grid, cell, and rowIndex
 		if(!this.headerMenu){
-			dojo.stopEvent(e);
+			event.stop(e);
 		}
 	},
 
@@ -491,3 +504,4 @@ dojo.declare("dojox.grid._Events", null, {
 	onSelectionChanged: function(){
 	}
 });
+});
\ No newline at end of file
diff --git a/dojox/grid/_FocusManager.js b/dojox/grid/_FocusManager.js
index 5048812..38d5998 100644
--- a/dojox/grid/_FocusManager.js
+++ b/dojox/grid/_FocusManager.js
@@ -1,9 +1,17 @@
-dojo.provide("dojox.grid._FocusManager");
-
-dojo.require("dojox.grid.util");
+define([
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dojo/_base/connect",
+	"dojo/_base/event",
+	"dojo/_base/sniff",
+	"dojo/query",
+	"./util",
+	"dojo/_base/html"
+], function(array, lang, declare, connect, event, has, query, util, html){
 
 // focus management
-dojo.declare("dojox.grid._FocusManager", null, {
+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.
@@ -14,17 +22,19 @@ dojo.declare("dojox.grid._FocusManager", null, {
 		this._connects = [];
 		this._headerConnects = [];
 		this.headerMenu = this.grid.headerMenu;
-		this._connects.push(dojo.connect(this.grid.domNode, "onfocus", this, "doFocus"));
-		this._connects.push(dojo.connect(this.grid.domNode, "onblur", this, "doBlur"));
-		this._connects.push(dojo.connect(this.grid.domNode, "oncontextmenu", this, "doContextMenu"));
-		this._connects.push(dojo.connect(this.grid.lastFocusNode, "onfocus", this, "doLastNodeFocus"));
-		this._connects.push(dojo.connect(this.grid.lastFocusNode, "onblur", this, "doLastNodeBlur"));
-		this._connects.push(dojo.connect(this.grid,"_onFetchComplete", this, "_delayedCellFocus"));
-		this._connects.push(dojo.connect(this.grid,"postrender", this, "_delayedHeaderFocus"));
+		this._connects.push(connect.connect(this.grid.domNode, "onfocus", this, "doFocus"));
+		this._connects.push(connect.connect(this.grid.domNode, "onblur", this, "doBlur"));
+		this._connects.push(connect.connect(this.grid.domNode, "mousedown", this, "_mouseDown"));
+		this._connects.push(connect.connect(this.grid.domNode, "mouseup", this, "_mouseUp"));
+		this._connects.push(connect.connect(this.grid.domNode, "oncontextmenu", this, "doContextMenu"));
+		this._connects.push(connect.connect(this.grid.lastFocusNode, "onfocus", this, "doLastNodeFocus"));
+		this._connects.push(connect.connect(this.grid.lastFocusNode, "onblur", this, "doLastNodeBlur"));
+		this._connects.push(connect.connect(this.grid,"_onFetchComplete", this, "_delayedCellFocus"));
+		this._connects.push(connect.connect(this.grid,"postrender", this, "_delayedHeaderFocus"));
 	},
 	destroy: function(){
-		dojo.forEach(this._connects, dojo.disconnect);
-		dojo.forEach(this._headerConnects, dojo.disconnect);
+		array.forEach(this._connects, connect.disconnect);
+		array.forEach(this._headerConnects, connect.disconnect);
 		delete this.grid;
 		delete this.cell;
 	},
@@ -77,7 +87,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 		// returns:
 		//	index of the focused column header, or -1 if none have focus.
 		if(this._colHeadNode){
-			return dojo.indexOf(this._findHeaderCells(), this._colHeadNode);
+			return array.indexOf(this._findHeaderCells(), this._colHeadNode);
 		}else{
 			return -1;
 		}
@@ -85,12 +95,12 @@ dojo.declare("dojox.grid._FocusManager", null, {
 	_focusifyCellNode: function(inBork){
 		var n = this.cell && this.cell.getNode(this.rowIndex);
 		if(n){
-			dojo.toggleClass(n, this.focusClass, inBork);
+			html.toggleClass(n, this.focusClass, inBork);
 			if(inBork){
 				var sl = this.scrollIntoView();
 				try{
 					if(!this.grid.edit.isEditing()){
-						dojox.grid.util.fire(n, "focus");
+						util.fire(n, "focus");
 						if(sl){ this.cell.view.scrollboxNode.scrollLeft = sl; }
 					}
 				}catch(e){}
@@ -98,16 +108,18 @@ dojo.declare("dojox.grid._FocusManager", null, {
 		}
 	},
 	_delayedCellFocus: function(){
-		if(this.isNavHeader()||!this.grid._focused){
+		if(this.isNavHeader()||!this.grid.focused){
 				return;
 		}
 		var n = this.cell && this.cell.getNode(this.rowIndex);
 		if(n){
 			try{
 				if(!this.grid.edit.isEditing()){
-					dojo.toggleClass(n, this.focusClass, true);
-					this.blurHeader();
-					dojox.grid.util.fire(n, "focus");
+					html.toggleClass(n, this.focusClass, true);
+					if(this._colHeadNode){
+						this.blurHeader();
+					}
+					util.fire(n, "focus");
 				}
 			}
 			catch(e){}
@@ -120,24 +132,24 @@ dojo.declare("dojox.grid._FocusManager", null, {
 		}
 	},
 	_initColumnHeaders: function(){
-		dojo.forEach(this._headerConnects, dojo.disconnect);
+		array.forEach(this._headerConnects, connect.disconnect);
 		this._headerConnects = [];
 		var headers = this._findHeaderCells();
 		for(var i = 0; i < headers.length; i++){
-			this._headerConnects.push(dojo.connect(headers[i], "onfocus", this, "doColHeaderFocus"));
-			this._headerConnects.push(dojo.connect(headers[i], "onblur", this, "doColHeaderBlur"));
+			this._headerConnects.push(connect.connect(headers[i], "onfocus", this, "doColHeaderFocus"));
+			this._headerConnects.push(connect.connect(headers[i], "onblur", this, "doColHeaderBlur"));
 		}
 	},
 	_findHeaderCells: function(){
 		// This should be a one liner:
-		//	dojo.query("th[tabindex=-1]", this.grid.viewsHeaderNode);
-		// But there is a bug in dojo.query() for IE -- see trac #7037.
-		var allHeads = dojo.query("th", this.grid.viewsHeaderNode);
+		//	query("th[tabindex=-1]", this.grid.viewsHeaderNode);
+		// But there is a bug in query() for IE -- see trac #7037.
+		var allHeads = query("th", this.grid.viewsHeaderNode);
 		var headers = [];
 		for (var i = 0; i < allHeads.length; i++){
 			var aHead = allHeads[i];
-			var hasTabIdx = dojo.hasAttr(aHead, "tabIndex");
-			var tabindex = dojo.attr(aHead, "tabIndex");
+			var hasTabIdx = html.hasAttr(aHead, "tabIndex");
+			var tabindex = html.attr(aHead, "tabIndex");
 			if (hasTabIdx && tabindex < 0) {
 				headers.push(aHead);
 			}
@@ -146,11 +158,11 @@ dojo.declare("dojox.grid._FocusManager", null, {
 	},
 	_setActiveColHeader: function(/*Node*/colHeaderNode, /*Integer*/colFocusIdx, /*Integer*/ prevColFocusIdx){
 		//console.log("setActiveColHeader() - colHeaderNode:colFocusIdx:prevColFocusIdx = " + colHeaderNode + ":" + colFocusIdx + ":" + prevColFocusIdx);
-		dojo.attr(this.grid.domNode, "aria-activedescendant",colHeaderNode.id);
+		this.grid.domNode.setAttribute("aria-activedescendant",colHeaderNode.id);
 		if (prevColFocusIdx != null && prevColFocusIdx >= 0 && prevColFocusIdx != colFocusIdx){
-			dojo.toggleClass(this._findHeaderCells()[prevColFocusIdx],this.focusClass,false);
+			html.toggleClass(this._findHeaderCells()[prevColFocusIdx],this.focusClass,false);
 		}
-		dojo.toggleClass(colHeaderNode,this.focusClass, true);
+		html.toggleClass(colHeaderNode,this.focusClass, true);
 		this._colHeadNode = colHeaderNode;
 		this._colHeadFocusIdx = colFocusIdx;
 		this._scrollHeader(this._colHeadFocusIdx);
@@ -205,6 +217,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 		var info = null;
 		if(this._colHeadNode){
 			var cell = this.grid.getCell(currentIdx);
+			if(!cell){ return; }
 			info = this._scrollInfo(cell, cell.getNode(0));
 		}
 		if(info && info.s && info.sr && info.n){
@@ -214,7 +227,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 				info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w;
 			}else if(info.n.offsetLeft < info.sr.l){
 				info.s.scrollLeft = info.n.offsetLeft;
-			}else if(dojo.isIE <= 7 && cell && cell.view.headerNode){
+			}else if(has('ie') <= 7 && cell && cell.view.headerNode){
 				// Trac 7158: scroll dojoxGridHeader for IE7 and lower
 				cell.view.headerNode.scrollLeft = info.s.scrollLeft;
 			}
@@ -239,7 +252,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 				}
 			}
 		}
-		return (curView && dojo.getComputedStyle(curView.headerNode).display == "none");
+		return (curView && html.getComputedStyle(curView.headerNode).display == "none");
 	},
 	colSizeAdjust: function (e, colIdx, delta){ // adjust the column specified by colIdx by the specified delta px
 		var headers = this._findHeaderCells();
@@ -304,8 +317,8 @@ dojo.declare("dojox.grid._FocusManager", null, {
 		}
 		// even if this cell isFocusCell, the document focus may need to be rejiggered
 		// call opera on delay to prevent keypress from altering focus
-		if(dojo.isOpera){
-			setTimeout(dojo.hitch(this.grid, 'onCellFocus', this.cell, this.rowIndex), 1);
+		if(has('opera')){
+			setTimeout(lang.hitch(this.grid, 'onCellFocus', this.cell, this.rowIndex), 1);
 		}else{
 			this.grid.onCellFocus(this.cell, this.rowIndex);
 		}
@@ -373,7 +386,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 		// Handle column headers.
 		if(this.isNavHeader()){
 			var headers = this._findHeaderCells();
-			var savedIdx = currentIdx = dojo.indexOf(headers, this._colHeadNode);
+			var savedIdx = currentIdx = array.indexOf(headers, this._colHeadNode);
 			currentIdx += inColDelta;
 			while(currentIdx >=0 && currentIdx < headers.length && headers[currentIdx].style.display == "none"){
 				// skip over hidden column headers
@@ -422,7 +435,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 						this.move(inRowDelta > 0 ? ++inRowDelta : --inRowDelta, inColDelta);
 					}
 					return;
-				}else if((!n || dojo.style(n, "display") === "none") && inColDelta){
+				}else if((!n || html.style(n, "display") === "none") && inColDelta){
 					if((col + inRowDelta) >= 0 && (col + inRowDelta) <= cc){
 						this.move(inRowDelta, inColDelta > 0 ? ++inColDelta : --inColDelta);
 					}
@@ -437,15 +450,15 @@ dojo.declare("dojox.grid._FocusManager", null, {
 	},
 	previousKey: function(e){
 		if(this.grid.edit.isEditing()){
-			dojo.stopEvent(e);
+			event.stop(e);
 			this.previous();
 		}else if(!this.isNavHeader() && !this._isHeaderHidden()) {
 			this.grid.domNode.focus(); // will call doFocus and set focus into header.
-			dojo.stopEvent(e);
+			event.stop(e);
 		}else{
 			this.tabOut(this.grid.domNode);
 			if (this._colHeadFocusIdx != null) { // clear grid header focus
-				dojo.toggleClass(this._findHeaderCells()[this._colHeadFocusIdx], this.focusClass, false);
+				html.toggleClass(this._findHeaderCells()[this._colHeadFocusIdx], this.focusClass, false);
 				this._colHeadFocusIdx = null;
 			}
 			this._focusifyCellNode(false);
@@ -455,7 +468,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 		var isEmpty = (this.grid.rowCount === 0);
 		if(e.target === this.grid.domNode && this._colHeadFocusIdx == null){
 			this.focusHeader();
-			dojo.stopEvent(e);
+			event.stop(e);
 		}else if(this.isNavHeader()){
 			// if tabbing from col header, then go to grid proper.
 			this.blurHeader();
@@ -464,7 +477,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 			}
 			this._colHeadNode = this._colHeadFocusIdx= null;
 		}else if(this.grid.edit.isEditing()){
-			dojo.stopEvent(e);
+			event.stop(e);
 			this.next();
 		}else{
 			this.tabOut(this.grid.lastFocusNode);
@@ -475,7 +488,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 		inFocusNode.focus();
 	},
 	focusGridView: function(){
-		dojox.grid.util.fire(this.focusView, "focus");
+		util.fire(this.focusView, "focus");
 	},
 	focusGrid: function(inSkipFocusCell){
 		this.focusGridView();
@@ -554,8 +567,8 @@ dojo.declare("dojox.grid._FocusManager", null, {
 		}
 	},
 	blurHeader: function(){
-		dojo.removeClass(this._colHeadNode, this.focusClass);
-		dojo.removeAttr(this.grid.domNode,"aria-activedescendant");
+		html.removeClass(this._colHeadNode, this.focusClass);
+		html.removeAttr(this.grid.domNode,"aria-activedescendant");
 		// reset contextMenu onto viewsHeaderNode so right mouse on header will invoke (see focusHeader)
 		if (this.headerMenu && this._contextMenuBindNode == this.grid.domNode) {
 			var viewsHeader = this.grid.viewsHeaderNode;
@@ -567,7 +580,11 @@ dojo.declare("dojox.grid._FocusManager", null, {
 	doFocus: function(e){
 		// trap focus only for grid dom node
 		if(e && e.target != e.currentTarget){
-			dojo.stopEvent(e);
+			event.stop(e);
+			return;
+		}
+		// don't change focus if clicking on scroller bar
+		if(this._clickFocus){
 			return;
 		}
 		// do not focus for scrolling if grid is about to blur
@@ -575,15 +592,15 @@ dojo.declare("dojox.grid._FocusManager", null, {
 			this.focusHeader();
 		}
 		this.tabbingOut = false;
-		dojo.stopEvent(e);
+		event.stop(e);
 	},
 	doBlur: function(e){
-		dojo.stopEvent(e);	// FF2
+		event.stop(e);	// FF2
 	},
 	doContextMenu: function(e){
 	//stop contextMenu event if no header Menu to prevent default/browser contextMenu
 		if (!this.headerMenu){
-			dojo.stopEvent(e);
+			event.stop(e);
 		}
 	},
 	doLastNodeFocus: function(e){
@@ -598,17 +615,27 @@ dojo.declare("dojox.grid._FocusManager", null, {
 			this.focusHeader();
 		}
 		this.tabbingOut = false;
-		dojo.stopEvent(e);	 // FF2
+		event.stop(e);	 // FF2
 	},
 	doLastNodeBlur: function(e){
-		dojo.stopEvent(e);	 // FF2
+		event.stop(e);	 // FF2
 	},
 	doColHeaderFocus: function(e){
-		this._setActiveColHeader(e.target,dojo.attr(e.target, "idx"),this._colHeadFocusIdx);
+		this._setActiveColHeader(e.target,html.attr(e.target, "idx"),this._colHeadFocusIdx);
 		this._scrollHeader(this.getHeaderIndex());
-		dojo.stopEvent(e);
+		event.stop(e);
 	},
 	doColHeaderBlur: function(e){
-		dojo.toggleClass(e.target, this.focusClass, false);
+		html.toggleClass(e.target, this.focusClass, false);
+	},
+	_mouseDown: function(e){
+		// a flag indicating grid is being focused by clicking
+		this._clickFocus = dojo.some(this.grid.views.views, function(v){
+			return v.scrollboxNode === e.target;
+		});
+	},
+	_mouseUp: function(e){
+		this._clickFocus = false;
 	}
 });
+});
\ No newline at end of file
diff --git a/dojox/grid/_Grid.js b/dojox/grid/_Grid.js
index a5d590a..2d9e0d1 100644
--- a/dojox/grid/_Grid.js
+++ b/dojox/grid/_Grid.js
@@ -1,25 +1,35 @@
-dojo.provide("dojox.grid._Grid");
+define([
+	"dojo/_base/kernel",
+	"../main",
+	"dojo/_base/declare",
+	"./_Events",
+	"./_Scroller",
+	"./_Layout",
+	"./_View",
+	"./_ViewManager",
+	"./_RowManager",
+	"./_FocusManager",
+	"./_EditManager",
+	"./Selection",
+	"./_RowSelector",
+	"./util",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dijit/CheckedMenuItem",
+	"dojo/text!./resources/_Grid.html",
+	"dojo/string",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/_base/sniff",
+	"dojox/html/metrics",
+	"dojo/_base/html",
+	"dojo/query",
+	"dojo/dnd/common",
+	"dojo/i18n!dijit/nls/loading"
+], function(dojo, dojox, declare, _Events, _Scroller, _Layout, _View, _ViewManager,
+	_RowManager, _FocusManager, _EditManager, Selection, _RowSelector, util, _Widget,
+	 _TemplatedMixin, CheckedMenuItem, template, string, array, lang, has, metrics, html, query){
 
-dojo.require("dijit.dijit");
-dojo.require("dijit.Menu");
-
-dojo.require("dojox.html.metrics");
-dojo.require("dojox.grid.util");
-dojo.require("dojox.grid._Scroller");
-dojo.require("dojox.grid._Layout");
-dojo.require("dojox.grid._View");
-dojo.require("dojox.grid._ViewManager");
-dojo.require("dojox.grid._RowManager");
-dojo.require("dojox.grid._FocusManager");
-dojo.require("dojox.grid._EditManager");
-dojo.require("dojox.grid.Selection");
-dojo.require("dojox.grid._RowSelector");
-dojo.require("dojox.grid._Events");
-
-
-dojo.requireLocalization("dijit", "loading");
-
-(function(){
 	// NOTE: this is for backwards compatibility with Dojo 1.3
 	if(!dojo.isCopyKey){
 		dojo.isCopyKey = dojo.dnd.getCopyKeyState;
@@ -141,8 +151,8 @@ dojo.requireLocalization("dijit", "loading");
 	}
 	=====*/
 
-	dojo.declare('dojox.grid._Grid',
-		[ dijit._Widget, dijit._Templated, dojox.grid._Events ],
+	var _Grid = declare('dojox.grid._Grid',
+		[ _Widget, _TemplatedMixin, _Events ],
 		{
 		// summary:
 		// 		A grid widget with virtual scrolling, cell editing, complex rows,
@@ -181,7 +191,7 @@ dojo.requireLocalization("dijit", "loading");
 		//	|		structure="structure"
 		//	|		dojoType="dojox.grid._Grid"></div>
 
-		templatePath: dojo.moduleUrl("dojox.grid","resources/_Grid.html"),
+		templateString: template,
 
 		// classTag: String
 		// 		CSS class applied to the grid's domNode
@@ -324,7 +334,7 @@ dojo.requireLocalization("dijit", "loading");
 
 		// _layoutClass: Object
 		//	The class to use for our layout - can be overridden by grid subclasses
-		_layoutClass: dojox.grid._Layout,
+		_layoutClass: _Layout,
 
 		// initialization
 		buildRendering: function(){
@@ -343,24 +353,24 @@ dojo.requireLocalization("dijit", "loading");
 			this.connect(this.selection, "onDeselected", "onDeselected");
 			this.connect(this.selection, "onChanged", "onSelectionChanged");
 
-			dojox.html.metrics.initOnFontResize();
-			this.connect(dojox.html.metrics, "onFontResize", "textSizeChanged");
-			dojox.grid.util.funnelEvents(this.domNode, this, 'doKeyEvent', dojox.grid.util.keyEvents);
+			metrics.initOnFontResize();
+			this.connect(metrics, "onFontResize", "textSizeChanged");
+			util.funnelEvents(this.domNode, this, 'doKeyEvent', util.keyEvents);
 			if (this.selectionMode != "none") {
-				dojo.attr(this.domNode, "aria-multiselectable", this.selectionMode == "single" ? "false" : "true");
+				this.domNode.setAttribute("aria-multiselectable", this.selectionMode == "single" ? "false" : "true");
 			}
 
-			dojo.addClass(this.domNode, this.classTag);
+			html.addClass(this.domNode, this.classTag);
 			if(!this.isLeftToRight()){
-				dojo.addClass(this.domNode, this.classTag+"Rtl");
+				html.addClass(this.domNode, this.classTag+"Rtl");
 			}
 		},
 		
 		postMixInProperties: function(){
 			this.inherited(arguments);
 			var messages = dojo.i18n.getLocalization("dijit", "loading", this.lang);
-			this.loadingMessage = dojo.string.substitute(this.loadingMessage, messages);
-			this.errorMessage = dojo.string.substitute(this.errorMessage, messages);
+			this.loadingMessage = string.substitute(this.loadingMessage, messages);
+			this.errorMessage = string.substitute(this.errorMessage, messages);
 			if(this.srcNodeRef && this.srcNodeRef.style.height){
 				this.height = this.srcNodeRef.style.height;
 			}
@@ -380,7 +390,7 @@ dojo.requireLocalization("dijit", "loading");
 			}
 			if (this.domNode && !this.editable){
 				// default value for aria-readonly is false, set to true if grid is not editable
-				dojo.attr(this.domNode,"aria-readonly", "true");
+				html.attr(this.domNode,"aria-readonly", "true");
 			}
 		},
 
@@ -391,20 +401,19 @@ dojo.requireLocalization("dijit", "loading");
 			// Fixes IE domNode leak
 			delete this._click;
 
-			this.edit.destroy();
-			delete this.edit;
-
-			this.views.destroyViews();
 			if(this.scroller){
 				this.scroller.destroy();
 				delete this.scroller;
 			}
+			this.edit.destroy();
+			delete this.edit;
+			this.views.destroyViews();
 			if(this.focus){
 				this.focus.destroy();
 				delete this.focus;
 			}
 			if(this.headerMenu&&this._placeholders.length){
-				dojo.forEach(this._placeholders, function(p){ p.unReplace(true); });
+				array.forEach(this._placeholders, function(p){ p.unReplace(true); });
 				this.headerMenu.unBindDomNode(this.viewsHeaderNode);
 			}
 			this.inherited(arguments);
@@ -466,26 +475,26 @@ dojo.requireLocalization("dijit", "loading");
 			//		create grid managers for various tasks including rows, focus, selection, editing
 
 			// row manager
-			this.rows = new dojox.grid._RowManager(this);
+			this.rows = new _RowManager(this);
 			// focus manager
-			this.focus = new dojox.grid._FocusManager(this);
+			this.focus = new _FocusManager(this);
 			// edit manager
-			this.edit = new dojox.grid._EditManager(this);
+			this.edit = new _EditManager(this);
 		},
 
 		createSelection: function(){
 			// summary:	Creates a new Grid selection manager.
 
 			// selection manager
-			this.selection = new dojox.grid.Selection(this);
+			this.selection = new Selection(this);
 		},
 
 		createScroller: function(){
 			// summary: Creates a new virtual scroller
-			this.scroller = new dojox.grid._Scroller();
+			this.scroller = new _Scroller();
 			this.scroller.grid = this;
-			this.scroller.renderRow = dojo.hitch(this, "renderRow");
-			this.scroller.removeRow = dojo.hitch(this, "rowRemoved");
+			this.scroller.renderRow = lang.hitch(this, "renderRow");
+			this.scroller.removeRow = lang.hitch(this, "rowRemoved");
 		},
 
 		createLayout: function(){
@@ -504,17 +513,17 @@ dojo.requireLocalization("dijit", "loading");
 
 		// views
 		createViews: function(){
-			this.views = new dojox.grid._ViewManager(this);
-			this.views.createView = dojo.hitch(this, "createView");
+			this.views = new _ViewManager(this);
+			this.views.createView = lang.hitch(this, "createView");
 		},
 
 		createView: function(inClass, idx){
-			var c = dojo.getObject(inClass);
+			var c = lang.getObject(inClass);
 			var view = new c({ grid: this, index: idx });
 			this.viewsNode.appendChild(view.domNode);
 			this.viewsHeaderNode.appendChild(view.headerNode);
 			this.views.addView(view);
-			dojo.attr(this.domNode, "align", dojo._isBodyLtr() ? 'left' : 'right');
+			html.attr(this.domNode, "align", this.isLeftToRight() ? 'left' : 'right');
 			return view;
 		},
 
@@ -527,9 +536,9 @@ dojo.requireLocalization("dijit", "loading");
 
 		_setStructureAttr: function(structure){
 			var s = structure;
-			if(s && dojo.isString(s)){
+			if(s && lang.isString(s)){
 				dojo.deprecated("dojox.grid._Grid.set('structure', 'objVar')", "use dojox.grid._Grid.set('structure', objVar) instead", "2.0");
-				s=dojo.getObject(s);
+				s=lang.getObject(s);
 			}
 			this.structure = s;
 			if(!s){
@@ -557,11 +566,12 @@ dojo.requireLocalization("dijit", "loading");
 		getColumnTogglingItems: function(){
 			// Summary: returns an array of dijit.CheckedMenuItem widgets that can be
 			//		added to a menu for toggling columns on and off.
-			return dojo.map(this.layout.cells, function(cell){
+			var items, checkedItems = [];
+			items = array.map(this.layout.cells, function(cell){
 				if(!cell.menuItems){ cell.menuItems = []; }
 
 				var self = this;
-				var item = new dijit.CheckedMenuItem({
+				var item = new CheckedMenuItem({
 					label: cell.name,
 					checked: !cell.hidden,
 					_gridCell: cell,
@@ -569,40 +579,47 @@ dojo.requireLocalization("dijit", "loading");
 						if(self.layout.setColumnVisibility(this._gridCell.index, checked)){
 							var items = this._gridCell.menuItems;
 							if(items.length > 1){
-								dojo.forEach(items, function(item){
+								array.forEach(items, function(item){
 									if(item !== this){
 										item.setAttribute("checked", checked);
 									}
 								}, this);
 							}
-							checked = dojo.filter(self.layout.cells, function(c){
+							checked = array.filter(self.layout.cells, function(c){
 								if(c.menuItems.length > 1){
-									dojo.forEach(c.menuItems, "item.set('disabled', false);");
+									array.forEach(c.menuItems, "item.set('disabled', false);");
 								}else{
 									c.menuItems[0].set('disabled', false);
 								}
 								return !c.hidden;
 							});
 							if(checked.length == 1){
-								dojo.forEach(checked[0].menuItems, "item.set('disabled', true);");
+								array.forEach(checked[0].menuItems, "item.set('disabled', true);");
 							}
 						}
 					},
 					destroy: function(){
-						var index = dojo.indexOf(this._gridCell.menuItems, this);
+						var index = array.indexOf(this._gridCell.menuItems, this);
 						this._gridCell.menuItems.splice(index, 1);
 						delete this._gridCell;
-						dijit.CheckedMenuItem.prototype.destroy.apply(this, arguments);
+						CheckedMenuItem.prototype.destroy.apply(this, arguments);
 					}
 				});
 				cell.menuItems.push(item);
+				if(!cell.hidden) {
+					checkedItems.push(item);
+				}
 				return item;
 			}, this); // dijit.CheckedMenuItem[]
+			if(checkedItems.length == 1) {
+				checkedItems[0].set('disabled', true);
+			}
+			return items;
 		},
 
 		_setHeaderMenuAttr: function(menu){
 			if(this._placeholders && this._placeholders.length){
-				dojo.forEach(this._placeholders, function(p){
+				array.forEach(this._placeholders, function(p){
 					p.unReplace(true);
 				});
 				this._placeholders = [];
@@ -626,7 +643,7 @@ dojo.requireLocalization("dijit", "loading");
 		
 		setupHeaderMenu: function(){
 			if(this._placeholders && this._placeholders.length){
-				dojo.forEach(this._placeholders, function(p){
+				array.forEach(this._placeholders, function(p){
 					if(p._replaced){
 						p.unReplace(true);
 					}
@@ -673,13 +690,21 @@ dojo.requireLocalization("dijit", "loading");
 			// save our input values, if any, and use them there when it gets
 			// 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();
 		},
 
 		_getPadBorder: function() {
-			this._padBorder = this._padBorder || dojo._getPadBorderExtents(this.domNode);
+			this._padBorder = this._padBorder || html._getPadBorderExtents(this.domNode);
 			return this._padBorder;
 		},
 
@@ -727,18 +752,18 @@ dojo.requireLocalization("dijit", "loading");
 			if(resultSize){
 				changeSize = resultSize;
 			}
-			if(changeSize){
-				dojo.marginBox(this.domNode, changeSize);
+			if(!this._autoHeight && changeSize){
+				html.marginBox(this.domNode, changeSize);
 				this.height = this.domNode.style.height;
 				delete this.fitTo;
 			}else if(this.fitTo == "parent"){
-				h = this._parentContentBoxHeight = this._parentContentBoxHeight || dojo._getContentBox(pn).h;
+				h = this._parentContentBoxHeight = this._parentContentBoxHeight || html._getContentBox(pn).h;
 				this.domNode.style.height = Math.max(0, h) + "px";
 			}
 			
-			var hasFlex = dojo.some(this.views.views, function(v){ return v.flexCells; });
+			var hasFlex = array.some(this.views.views, function(v){ return v.flexCells; });
 
-			if(!this._autoHeight && (h || dojo._getContentBox(this.domNode).h) === 0){
+			if(!this._autoHeight && (h || html._getContentBox(this.domNode).h) === 0){
 				// We need to hide the header, since the Grid is essentially hidden.
 				this.viewsHeaderNode.style.display = "none";
 			}else{
@@ -783,13 +808,13 @@ dojo.requireLocalization("dijit", "loading");
 			this.views.onEach('adaptHeight');
 			if(!this._autoHeight){
 				var numScroll = 0, numNoScroll = 0;
-				var noScrolls = dojo.filter(this.views.views, function(v){
+				var noScrolls = array.filter(this.views.views, function(v){
 					var has = v.hasHScrollbar();
 					if(has){ numScroll++; }else{ numNoScroll++; }
 					return (!has);
 				});
 				if(numScroll > 0 && numNoScroll > 0){
-					dojo.forEach(noScrolls, function(v){
+					array.forEach(noScrolls, function(v){
 						v.adaptHeight(true);
 					});
 				}
@@ -847,7 +872,7 @@ dojo.requireLocalization("dijit", "loading");
 			this.postresize();
 			this.focus.initFocusView();
 			// make rows unselectable
-			dojo.setSelectable(this.domNode, this.selectable);
+			html.setSelectable(this.domNode, this.selectable);
 		},
 
 		postresize: function(){
@@ -985,11 +1010,11 @@ dojo.requireLocalization("dijit", "loading");
 		getRowNode: function(inRowIndex){
 			// summary:
 			//		find the rowNode that is not a rowSelector
-			if (this.focus.focusView && !(this.focus.focusView instanceof dojox.grid._RowSelector)){
+			if (this.focus.focusView && !(this.focus.focusView instanceof _RowSelector)){
 					return this.focus.focusView.rowNodes[inRowIndex];
 			}else{ // search through views
 				for (var i = 0, cView; (cView = this.views.views[i]); i++) {
-					if (!(cView instanceof dojox.grid._RowSelector)) {
+					if (!(cView instanceof _RowSelector)) {
 						return cView.rowNodes[inRowIndex];
 					}
 				}
@@ -1016,7 +1041,7 @@ dojo.requireLocalization("dijit", "loading");
 
 		// scrollRedrawThreshold: int
 		//	pixel distance a user must scroll vertically to trigger grid scrolling.
-		scrollRedrawThreshold: (dojo.isIE ? 100 : 50),
+		scrollRedrawThreshold: (has('ie') ? 100 : 50),
 
 		// scroll methods
 		scrollTo: function(inTop){
@@ -1264,10 +1289,9 @@ dojo.requireLocalization("dijit", "loading");
 
 	});
 
-	dojox.grid._Grid.markupFactory = function(props, node, ctor, cellFunc){
-		var d = dojo;
+	_Grid.markupFactory = function(props, node, ctor, cellFunc){
 		var widthFromAttr = function(n){
-			var w = d.attr(n, "width")||"auto";
+			var w = html.attr(n, "width")||"auto";
 			if((w != "auto")&&(w.slice(-2) != "em")&&(w.slice(-1) != "%")){
 				w = parseInt(w, 10)+"px";
 			}
@@ -1280,14 +1304,14 @@ dojo.requireLocalization("dijit", "loading");
 			node.nodeName.toLowerCase() == "table"){
 
 			// try to discover a structure
-			props.structure = d.query("> colgroup", node).map(function(cg){
-				var sv = d.attr(cg, "span");
+			props.structure = query("> colgroup", node).map(function(cg){
+				var sv = html.attr(cg, "span");
 				var v = {
-					noscroll: (d.attr(cg, "noscroll") == "true") ? true : false,
+					noscroll: (html.attr(cg, "noscroll") == "true") ? true : false,
 					__span: (!!sv ? parseInt(sv, 10) : 1),
 					cells: []
 				};
-				if(d.hasAttr(cg, "width")){
+				if(html.hasAttr(cg, "width")){
 					v.width = widthFromAttr(cg);
 				}
 				return v; // for vendetta
@@ -1301,12 +1325,12 @@ dojo.requireLocalization("dijit", "loading");
 			// check to see if we're gonna have more than one view
 
 			// for each tr in our th, create a row of cells
-			d.query("thead > tr", node).forEach(function(tr, tr_idx){
+			query("thead > tr", node).forEach(function(tr, tr_idx){
 				var cellCount = 0;
 				var viewIdx = 0;
 				var lastViewIdx;
 				var cView = null;
-				d.query("> th", tr).map(function(th){
+				query("> th", tr).map(function(th){
 					// what view will this cell go into?
 
 					// NOTE:
@@ -1329,31 +1353,31 @@ dojo.requireLocalization("dijit", "loading");
 
 					// actually define the cell from what markup hands us
 					var cell = {
-						name: d.trim(d.attr(th, "name")||th.innerHTML),
-						colSpan: parseInt(d.attr(th, "colspan")||1, 10),
-						type: d.trim(d.attr(th, "cellType")||""),
-						id: d.trim(d.attr(th,"id")||"")
+						name: lang.trim(html.attr(th, "name")||th.innerHTML),
+						colSpan: parseInt(html.attr(th, "colspan")||1, 10),
+						type: lang.trim(html.attr(th, "cellType")||""),
+						id: lang.trim(html.attr(th,"id")||"")
 					};
 					cellCount += cell.colSpan;
-					var rowSpan = d.attr(th, "rowspan");
+					var rowSpan = html.attr(th, "rowspan");
 					if(rowSpan){
 						cell.rowSpan = rowSpan;
 					}
-					if(d.hasAttr(th, "width")){
+					if(html.hasAttr(th, "width")){
 						cell.width = widthFromAttr(th);
 					}
-					if(d.hasAttr(th, "relWidth")){
-						cell.relWidth = window.parseInt(dojo.attr(th, "relWidth"), 10);
+					if(html.hasAttr(th, "relWidth")){
+						cell.relWidth = window.parseInt(html.attr(th, "relWidth"), 10);
 					}
-					if(d.hasAttr(th, "hidden")){
-						cell.hidden = (d.attr(th, "hidden") == "true" || d.attr(th, "hidden") === true/*always boolean true in Chrome*/);
+					if(html.hasAttr(th, "hidden")){
+						cell.hidden = (html.attr(th, "hidden") == "true" || html.attr(th, "hidden") === true/*always boolean true in Chrome*/);
 					}
 
 					if(cellFunc){
 						cellFunc(th, cell);
 					}
 
-					cell.type = cell.type ? dojo.getObject(cell.type) : dojox.grid.cells.Cell;
+					cell.type = cell.type ? lang.getObject(cell.type) : dojox.grid.cells.Cell;
 
 					if(cell.type && cell.type.markupFactory){
 						cell.type.markupFactory(th, cell);
@@ -1369,4 +1393,7 @@ dojo.requireLocalization("dijit", "loading");
 
 		return new ctor(props, node);
 	};
-})();
+
+	return _Grid;
+
+});
\ No newline at end of file
diff --git a/dojox/grid/_Layout.js b/dojox/grid/_Layout.js
index 8d35b2d..7b3f095 100644
--- a/dojox/grid/_Layout.js
+++ b/dojox/grid/_Layout.js
@@ -1,8 +1,15 @@
-dojo.provide("dojox.grid._Layout");
-dojo.require("dojox.grid.cells");
-dojo.require("dojox.grid._RowSelector");
+define([
+	"dojo/_base/kernel",
+	"../main",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/dom-geometry",
+	"./cells",
+	"./_RowSelector"
+], function(dojo, dojox, declare, array, lang, domGeometry){
 
-dojo.declare("dojox.grid._Layout", null, {
+return declare("dojox.grid._Layout", null, {
 	// summary:
 	//	Controls grid cell layout. Owned by grid and used internally.
 	constructor: function(inGrid){
@@ -69,7 +76,7 @@ dojo.declare("dojox.grid._Layout", null, {
 		}
 		
 		//Fix #9481 - reset idx in cell markup
-		dojo.forEach(this.cells, function(c){
+		array.forEach(this.cells, function(c){
 			var marks = c.markup[2].split(" ");
 			var oldIdx = parseInt(marks[1].substring(5));//get old "idx"
 			if(oldIdx != c.index){
@@ -88,7 +95,7 @@ dojo.declare("dojox.grid._Layout", null, {
 			cell.hidden = !visible;
 			var v = cell.view, w = v.viewWidth;
 			if(w && w != "auto"){
-				v._togglingColumn = dojo.marginBox(cell.getHeaderNode()).w || 0;
+				v._togglingColumn = domGeometry.getMarginBox(cell.getHeaderNode()).w || 0;
 			}
 			v.update();
 			return true;
@@ -121,16 +128,19 @@ dojo.declare("dojox.grid._Layout", null, {
 		};
 
 		if(inDef && inDef instanceof dojox.grid.cells._Base){
-			var new_cell = dojo.clone(inDef);
+			var new_cell = lang.clone(inDef);
 			props.unitWidth = getCellWidth(new_cell._props);
-			new_cell = dojo.mixin(new_cell, this._defaultCellProps, inDef._props, props);
+			new_cell = lang.mixin(new_cell, this._defaultCellProps, inDef._props, props);
 			return new_cell;
 		}
 
 		var cell_type = inDef.type || inDef.cellType || this._defaultCellProps.type || this._defaultCellProps.cellType || dojox.grid.cells.Cell;
+		if(lang.isString(cell_type)){
+			cell_type = lang.getObject(cell_type);
+		}
 
 		props.unitWidth = getCellWidth(inDef);
-		return new cell_type(dojo.mixin({}, this._defaultCellProps, inDef, props));
+		return new cell_type(lang.mixin({}, this._defaultCellProps, inDef, props));
 	},
 	
 	addRowDef: function(inRowIndex, inDef){
@@ -157,7 +167,7 @@ dojo.declare("dojox.grid._Layout", null, {
 		}
 		if(relSum && doRel){
 			// We have some kind of relWidths specified - so change them to %
-			dojo.forEach(result, function(cell){
+			array.forEach(result, function(cell){
 				if(cell.relWidth){
 					cell.width = cell.unitWidth = ((cell.relWidth / relSum) * (100 - pctSum)) + "%";
 				}
@@ -169,8 +179,8 @@ dojo.declare("dojox.grid._Layout", null, {
 
 	addRowsDef: function(inDef){
 		var result = [];
-		if(dojo.isArray(inDef)){
-			if(dojo.isArray(inDef[0])){
+		if(lang.isArray(inDef)){
+			if(lang.isArray(inDef[0])){
 				for(var i=0, row; inDef && (row=inDef[i]); i++){
 					result.push(this.addRowDef(i, row));
 				}
@@ -186,7 +196,7 @@ dojo.declare("dojox.grid._Layout", null, {
 		if(inDef.width && inDef.width == "auto"){
 			delete inDef.width;
 		}
-		return dojo.mixin({}, inDef, {cells: this.addRowsDef(inDef.rows || inDef.cells)});
+		return lang.mixin({}, inDef, {cells: this.addRowsDef(inDef.rows || inDef.cells)});
 	},
 	
 	setStructure: function(inStructure){
@@ -197,7 +207,7 @@ dojo.declare("dojox.grid._Layout", null, {
 		if(this.grid.rowSelector){
 			var sel = { type: dojox._scopeName + ".grid._RowSelector" };
 
-			if(dojo.isString(this.grid.rowSelector)){
+			if(lang.isString(this.grid.rowSelector)){
 				var width = this.grid.rowSelector;
 
 				if(width == "false"){
@@ -221,8 +231,8 @@ dojo.declare("dojox.grid._Layout", null, {
 		};
 
 		var isRowDef = function(def){
-			if(dojo.isArray(def)){
-				if(dojo.isArray(def[0]) || isCell(def[0])){
+			if(lang.isArray(def)){
+				if(lang.isArray(def[0]) || isCell(def[0])){
 					return true;
 				}
 			}
@@ -230,11 +240,11 @@ dojo.declare("dojox.grid._Layout", null, {
 		};
 
 		var isView = function(def){
-			return (def !== null && dojo.isObject(def) &&
+			return (def !== null && lang.isObject(def) &&
 					("cells" in def || "rows" in def || ("type" in def && !isCell(def))));
 		};
 
-		if(dojo.isArray(inStructure)){
+		if(lang.isArray(inStructure)){
 			var hasViews = false;
 			for(var i=0, st; (st=inStructure[i]); i++){
 				if(isView(st)){
@@ -262,3 +272,4 @@ dojo.declare("dojox.grid._Layout", null, {
 		this.grid.setupHeaderMenu();
 	}
 });
+});
\ No newline at end of file
diff --git a/dojox/grid/_RadioSelector.js b/dojox/grid/_RadioSelector.js
index 055c446..00c1bbd 100644
--- a/dojox/grid/_RadioSelector.js
+++ b/dojox/grid/_RadioSelector.js
@@ -1,3 +1,3 @@
-dojo.provide("dojox.grid._RadioSelector");
-
-dojo.require("dojox.grid._Selector");
+define(["../main", "./_Selector"], function(dojox){
+	return dojox.grid._RadioSelector;
+});
\ No newline at end of file
diff --git a/dojox/grid/_RowManager.js b/dojox/grid/_RowManager.js
index 1d81884..4d49a0a 100644
--- a/dojox/grid/_RowManager.js
+++ b/dojox/grid/_RowManager.js
@@ -1,6 +1,9 @@
-dojo.provide("dojox.grid._RowManager");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/dom-class"
+], function(declare, lang, domClass){
 
-(function(){
 	var setStyleText = function(inNode, inStyleText){
 		if(inNode.style.cssText == undefined){
 			inNode.setAttribute("style", inStyleText);
@@ -9,7 +12,7 @@ dojo.provide("dojox.grid._RowManager");
 		}
 	};
 
-	dojo.declare("dojox.grid._RowManager", null, {
+	return declare("dojox.grid._RowManager", null, {
 		//	Stores information about grid rows. Owned by grid and used internally.
 		constructor: function(inGrid){
 			this.grid = inGrid;
@@ -48,13 +51,13 @@ dojo.provide("dojox.grid._RowManager");
 		setOverRow: function(inRowIndex){
 			var last = this.overRow;
 			this.overRow = inRowIndex;
-			if((last!=this.overRow)&&(dojo.isString(last) || last >= 0)){
+			if((last!=this.overRow)&&(lang.isString(last) || last >= 0)){
 				this.updateStyles(last);
 			}
 			this.updateStyles(this.overRow);
 		},
 		isOver: function(inRowIndex){
-			return (this.overRow == inRowIndex && !dojo.hasClass(this.grid.domNode, "dojoxGridColumnResizing"));
+			return (this.overRow == inRowIndex && !domClass.contains(this.grid.domNode, "dojoxGridColumnResizing"));
 		}
 	});
-})();
+});
\ No newline at end of file
diff --git a/dojox/grid/_RowSelector.js b/dojox/grid/_RowSelector.js
index 08c1e67..152caa1 100644
--- a/dojox/grid/_RowSelector.js
+++ b/dojox/grid/_RowSelector.js
@@ -1,7 +1,9 @@
-dojo.provide("dojox.grid._RowSelector");
-dojo.require("dojox.grid._View");
+define([
+	"dojo/_base/declare",
+	"./_View"
+], function(declare, _View){
 
-dojo.declare('dojox.grid._RowSelector', dojox.grid._View, {
+return declare('dojox.grid._RowSelector', _View, {
 	// summary:
 	//	Custom grid view. If used in a grid structure, provides a small selectable region for grid rows.
 	defaultWidth: "2em",
@@ -53,3 +55,4 @@ dojo.declare('dojox.grid._RowSelector', dojox.grid._View, {
 		}
 	}
 });
+});
\ No newline at end of file
diff --git a/dojox/grid/_Scroller.js b/dojox/grid/_Scroller.js
index 59f36ef..dbcfcd6 100644
--- a/dojox/grid/_Scroller.js
+++ b/dojox/grid/_Scroller.js
@@ -1,6 +1,11 @@
-dojo.provide("dojox.grid._Scroller");
+define([
+	"dijit/registry",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"./util",
+	"dojo/_base/html"
+], function(dijitRegistry, declare, lang, util, html){
 
-(function(){
 	var indexInParent = function(inNode){
 		var i=0, n, p=inNode.parentNode;
 		while((n = p.childNodes[i++])){
@@ -15,18 +20,15 @@ dojo.provide("dojox.grid._Scroller");
 		if(!inNode){
 			return;
 		}
-		var filter = function(inW){
-			return inW.domNode && dojo.isDescendant(inW.domNode, inNode, true);
-		};
-		var ws = dijit.registry.filter(filter);
-		for(var i=0, w; (w=ws[i]); i++){
-			w.destroy();
-		}
-		delete ws;
+		dojo.forEach(dijitRegistry.toArray(), function(w){
+			if(w.domNode && html.isDescendant(w.domNode, inNode, true)){
+				w.destroy();
+			}
+		});
 	};
 
 	var getTagName = function(inNodeOrId){
-		var node = dojo.byId(inNodeOrId);
+		var node = html.byId(inNodeOrId);
 		return (node && node.tagName ? node.tagName.toLowerCase() : '');
 	};
 	
@@ -46,7 +48,7 @@ dojo.provide("dojox.grid._Scroller");
 		return nodeKids(inNode, 'div');
 	};
 
-	dojo.declare("dojox.grid._Scroller", null, {
+	return declare("dojox.grid._Scroller", null, {
 		constructor: function(inContentNodes){
 			this.setContentNodes(inContentNodes);
 			this.pageHeights = [];
@@ -85,7 +87,7 @@ dojo.provide("dojox.grid._Scroller");
 			if(this.scrollboxNode){
 				this.scrollboxNode.scrollTop = 0;
 				this.scroll(0);
-				this.scrollboxNode.onscroll = dojo.hitch(this, 'onscroll');
+				this.scrollboxNode.onscroll = lang.hitch(this, 'onscroll');
 			}
 		},
 		_getPageCount: function(rowCount, rowsPerPage){
@@ -218,7 +220,7 @@ dojo.provide("dojox.grid._Scroller");
 			for(var i=0; i<this.colCount; i++){
 				var n = this.invalidatePageNode(inPageIndex, this.pageNodes[i]);
 				if(n){
-					dojo.destroy(n);
+					html.destroy(n);
 				}
 			}
 		},
@@ -253,7 +255,7 @@ dojo.provide("dojox.grid._Scroller");
 			for(var i=0; i<this.colCount; i++){
 				//We want to have 1px in height min to keep scroller.  Otherwise can't scroll
 				//and see header in empty grid.
-				dojox.grid.util.setStyleHeightPx(this.contentNodes[i], Math.max(1,this.height));
+				util.setStyleHeightPx(this.contentNodes[i], Math.max(1,this.height));
 			}
 			
 			// Calculate the average row height and update the defaults (row and page).
@@ -322,10 +324,10 @@ dojo.provide("dojox.grid._Scroller");
 		},
 		createPageNode: function(){
 			var p = document.createElement('div');
-			dojo.attr(p,"role","presentation");
+			html.attr(p,"role","presentation");
 			p.style.position = 'absolute';
 			//p.style.width = '100%';
-			p.style[dojo._isBodyLtr() ? "left" : "right"] = '0';
+			p.style[this.grid.isLeftToRight() ? "left" : "right"] = '0';
 			return p;
 		},
 		getPageHeight: function(inPageIndex){
@@ -501,4 +503,4 @@ dojo.provide("dojox.grid._Scroller");
 		},
 		dummy: 0
 	});
-})();
+});
diff --git a/dojox/grid/_SelectionPreserver.js b/dojox/grid/_SelectionPreserver.js
new file mode 100644
index 0000000..9e9b655
--- /dev/null
+++ b/dojox/grid/_SelectionPreserver.js
@@ -0,0 +1,66 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/connect",
+	"dojo/_base/lang",
+	"dojo/_base/array"
+], function(declare, connect, lang, array){
+
+return declare("dojox.grid._SelectionPreserver", null, {
+	// summary:
+	//		Preserve selections across various user actions.
+	//
+	// description:
+	//		When this feature is turned on, Grid will try to preserve selections across actions, e.g. sorting, filtering etc.
+	//
+	//		Precondition - Identifier(id) is required for store since id is the only way for differentiating row items.
+	//		Known issue - The preserved selections might be inaccurate if some unloaded rows are previously selected by range(e.g.SHIFT + click)
+	//
+	// example:
+	// |	//To turn on this - please set 'keepSelection' attribute to true
+	// |	<div dojoType="dojox.grid.DataGrid" keepSelection = true .../>
+	// |	<div dojoType="dojox.grid.TreeGrid" keepSelection = true .../>
+	// |	<div dojoType="dojox.grid.LazyTreeGrid" keepSelection = true .../>
+	
+	constructor: function(selection){
+		this.selection = selection;
+		var grid = this.grid = selection.grid;
+		this.reset();
+		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, 'deselectAll', this, 'reset')
+		];
+	},
+	destroy: function(){
+		this.reset();
+		array.forEach(this._connects, connect.disconnect);
+		delete this._connects;
+	},
+	reset: function(){
+		this._selectedById = {};
+	},
+	_reSelectById: function(item, index){
+		// summary:
+		//		When some rows is fetched, determine whether it should be selected.
+		if(item && this.grid._hasIdentity){
+			this.selection.selected[index] = this._selectedById[this.grid.store.getIdentity(item)];
+		}
+	},
+	_selectById: function(toSelect, inItemOrIndex){
+		// summary:
+		//		Record selected rows by ID.
+		if(this.selection.mode == 'none' || !this.grid._hasIdentity){ return; }
+		var item = inItemOrIndex, g = this.grid;
+		if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+			var entry = g._by_idx[inItemOrIndex];
+			item = entry && entry.item;
+		}
+		if(item){
+			this._selectedById[g.store.getIdentity(item)] = !!toSelect;
+		}
+		return item;
+	}
+});
+});
\ No newline at end of file
diff --git a/dojox/grid/_Selector.js b/dojox/grid/_Selector.js
index 04e18fd..53dd75f 100644
--- a/dojox/grid/_Selector.js
+++ b/dojox/grid/_Selector.js
@@ -1,13 +1,18 @@
-dojo.provide("dojox.grid._Selector");
-
-dojo.require("dojox.grid.Selection");
-dojo.require("dojox.grid._View");
-dojo.require("dojox.grid._Builder");
-
-(function(){
-	dojox.grid._InputSelectorHeaderBuilder = dojo.extend(function(view){
-		dojox.grid._HeaderBuilder.call(this, view);
-	},dojox.grid._HeaderBuilder.prototype,{
+define([
+	"../main",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/query",
+	"dojo/dom-class",
+	"./Selection",
+	"./_View",
+	"./_Builder",
+	"./util"
+], function(dojox, declare, lang, query, domClass, Selection, _View, _Builder, util){
+	
+	var _InputSelectorHeaderBuilder = dojox.grid._InputSelectorHeaderBuilder = lang.extend(function(view){
+		_Builder._HeaderBuilder.call(this, view);
+	},_Builder._HeaderBuilder.prototype,{
 		generateHtml: function(){
 			var w = this.view.contentWidth || 0;
 			var selectedCount = this.view.grid.selection.getSelectedCount();
@@ -32,9 +37,9 @@ dojo.require("dojox.grid._Builder");
 		}
 	});
 
-	dojox.grid._SelectorContentBuilder = dojo.extend(function(view){
-		dojox.grid._ContentBuilder.call(this, view);
-	},dojox.grid._ContentBuilder.prototype,{
+	var _SelectorContentBuilder = dojox.grid._SelectorContentBuilder = lang.extend(function(view){
+		_Builder._ContentBuilder.call(this, view);
+	},_Builder._ContentBuilder.prototype,{
 		generateHtml: function(inDataIndex, inRowIndex){
 			var w = this.view.contentWidth || 0;
 			return '<table class="dojoxGridRowbarTable" style="width:' + w + 'px;" border="0" ' +
@@ -45,7 +50,7 @@ dojo.require("dojox.grid._Builder");
 			return ' ';
 		},
 		findTarget: function(){
-			var t = dojox.grid._ContentBuilder.prototype.findTarget.apply(this, arguments);
+			var t = _Builder._ContentBuilder.prototype.findTarget.apply(this, arguments);
 			return t;
 		},
 		domouseover: function(e){
@@ -75,9 +80,9 @@ dojo.require("dojox.grid._Builder");
 		}
 	});
 
-	dojox.grid._InputSelectorContentBuilder = dojo.extend(function(view){
-		dojox.grid._SelectorContentBuilder.call(this, view);
-	},dojox.grid._SelectorContentBuilder.prototype,{
+	var _InputSelectorContentBuilder = dojox.grid._InputSelectorContentBuilder = lang.extend(function(view){
+		_SelectorContentBuilder.call(this, view);
+	},_SelectorContentBuilder.prototype,{
 		getCellContent: function(rowIndex){
 			var v = this.view;
 			var type = v.inputType == "checkbox" ? "CheckBox" : "Radio";
@@ -86,7 +91,7 @@ dojo.require("dojox.grid._Builder");
 		}
 	});
 
-	dojo.declare("dojox.grid._Selector", dojox.grid._View, {
+	var _Selector = declare("dojox.grid._Selector", _View, {
 		inputType: '',
 		selectionMode: '',
 
@@ -96,7 +101,7 @@ dojo.require("dojox.grid._Builder");
 		noscroll: true,
 		padBorderWidth: 2,
 
-		_contentBuilderClass: dojox.grid._SelectorContentBuilder,
+		_contentBuilderClass: _SelectorContentBuilder,
 
 		postCreate: function(){
 			this.inherited(arguments);
@@ -148,24 +153,24 @@ dojo.require("dojox.grid._Builder");
 			this.grid.updateRow(inIndex);
 		}
 	});
-	if(!dojox.grid._View.prototype._headerBuilderClass &&
-		!dojox.grid._View.prototype._contentBuilderClass){
-		dojox.grid._Selector.prototype.postCreate = function(){
+	if(!_View.prototype._headerBuilderClass &&
+		!_View.prototype._contentBuilderClass){
+		_Selector.prototype.postCreate = function(){
 			this.connect(this.scrollboxNode,"onscroll","doscroll");
-			dojox.grid.util.funnelEvents(this.contentNode, this, "doContentEvent", [ 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]);
-			dojox.grid.util.funnelEvents(this.headerNode, this, "doHeaderEvent", [ 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]);
+			util.funnelEvents(this.contentNode, this, "doContentEvent", [ 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]);
+			util.funnelEvents(this.headerNode, this, "doHeaderEvent", [ 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]);
 			if(this._contentBuilderClass){
 				this.content = new this._contentBuilderClass(this);
 			}else{
-				this.content = new dojox.grid._ContentBuilder(this);
+				this.content = new _Builder._ContentBuilder(this);
 			}
 			if(this._headerBuilderClass){
 				this.header = new this._headerBuilderClass(this);
 			}else{
-				this.header = new dojox.grid._HeaderBuilder(this);
+				this.header = new _Builder._HeaderBuilder(this);
 			}
 			//BiDi: in RTL case, style width='9000em' causes scrolling problem in head node
-			if(!dojo._isBodyLtr()){
+			if(!this.grid.isLeftToRight()){
 				this.headerNodeContainer.style.width = "";
 			}
 			this.connect(this.grid.selection, 'onSelected', 'onSelected');
@@ -173,11 +178,11 @@ dojo.require("dojox.grid._Builder");
 		};
 	}
 
-	dojo.declare("dojox.grid._RadioSelector", dojox.grid._Selector, {
+	declare("dojox.grid._RadioSelector", _Selector, {
 		inputType: 'radio',
 		selectionMode: 'single',
 
-		_contentBuilderClass: dojox.grid._InputSelectorContentBuilder,
+		_contentBuilderClass: _InputSelectorContentBuilder,
 
 		buildRendering: function(){
 			this.inherited(arguments);
@@ -187,10 +192,10 @@ dojo.require("dojox.grid._Builder");
 		renderHeader: function(){}
 	});
 
-	dojo.declare("dojox.grid._CheckBoxSelector", dojox.grid._Selector, {
+	declare("dojox.grid._CheckBoxSelector", _Selector, {
 		inputType: 'checkbox',
-		_headerBuilderClass: dojox.grid._InputSelectorHeaderBuilder,
-		_contentBuilderClass: dojox.grid._InputSelectorContentBuilder,
+		_headerBuilderClass: _InputSelectorHeaderBuilder,
+		_contentBuilderClass: _InputSelectorContentBuilder,
 		postCreate: function(){
 			this.inherited(arguments);
 			this.connect(this.grid, 'onSelectionChanged', 'onSelectionChanged');
@@ -205,12 +210,15 @@ dojo.require("dojox.grid._Builder");
 		},
 		onSelectionChanged: function(){
 			if(this._selectionChanging){ return; }
-			var inputDiv = dojo.query('.dojoxGridCheckSelector', this.headerNode)[0];
+			var inputDiv = query('.dojoxGridCheckSelector', this.headerNode)[0];
 			var g = this.grid;
 			var s = (g.rowCount && g.rowCount == g.selection.getSelectedCount());
 			g.allItemsSelected = s||false;
-			dojo.toggleClass(inputDiv, "dijitChecked", g.allItemsSelected);
-			dojo.toggleClass(inputDiv, "dijitCheckBoxChecked", g.allItemsSelected);
+			domClass.toggle(inputDiv, "dijitChecked", g.allItemsSelected);
+			domClass.toggle(inputDiv, "dijitCheckBoxChecked", g.allItemsSelected);
 		}
 	});
-})();
+	
+	return _Selector;
+
+});
\ No newline at end of file
diff --git a/dojox/grid/_TreeView.js b/dojox/grid/_TreeView.js
index 3b4d555..e33d952 100644
--- a/dojox/grid/_TreeView.js
+++ b/dojox/grid/_TreeView.js
@@ -1,10 +1,26 @@
-dojo.provide("dojox.grid._TreeView");
+define([
+	"dijit/registry",
+	"../main",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/_base/event",
+	"dojo/dom-attr",
+	"dojo/dom-class",
+	"dojo/dom-style",
+	"dojo/dom-construct",
+	"dojo/query",
+	"dojo/parser",
+	"dojo/text!./resources/Expando.html",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"./_View",
+	"./_Builder",
+	"./util"
+], function(dijit, dojox, declare, array, lang, event, domAttr, domClass, 
+	domStyle, domCtr, query, parser, template, _Widget, _TemplatedMixin, _View, _Builder, util){
 
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dojox.grid._View");
-
-dojo.declare("dojox.grid._Expando", [ dijit._Widget, dijit._Templated ], {
+declare("dojox.grid._Expando", [ _Widget, _TemplatedMixin ], {
 	open: false,
 	toggleClass: "",
 	itemId: "",
@@ -14,10 +30,10 @@ dojo.declare("dojox.grid._Expando", [ dijit._Widget, dijit._Templated ], {
 	rowIdx: -1,
 	expandoCell: null,
 	level: 0,
-	templatePath: dojo.moduleUrl("dojox.grid", "resources/Expando.html"),
+	templateString: template,
 	_toggleRows: function(toggleClass, open){
 		if(!toggleClass || !this.rowNode){ return; }
-		if(dojo.query("table.dojoxGridRowTableNeedsRowUpdate").length){
+		if(query("table.dojoxGridRowTableNeedsRowUpdate").length){
 			if(this._initialized){
 				this.view.grid.updateRow(this.rowIdx);
 			}
@@ -26,12 +42,12 @@ dojo.declare("dojox.grid._Expando", [ dijit._Widget, dijit._Templated ], {
 		var self = this;
 		var g = this.view.grid;
 		if(g.treeModel){
-			var p = this._tableRow ? dojo.attr(this._tableRow, "dojoxTreeGridPath") : "";
+			var p = this._tableRow ? domAttr.get(this._tableRow, "dojoxTreeGridPath") : "";
 			if(p){
-				dojo.query("tr[dojoxTreeGridPath^=\"" + p + "/\"]", this.rowNode).forEach(function(n){
-					var en = dojo.query(".dojoxGridExpando", n)[0];
+				query("tr[dojoxTreeGridPath^=\"" + p + "/\"]", this.rowNode).forEach(function(n){
+					var en = query(".dojoxGridExpando", n)[0];
 					if(en && en.parentNode && en.parentNode.parentNode &&
-								!dojo.hasClass(en.parentNode.parentNode, "dojoxGridNoChildren")){
+								!domClass.contains(en.parentNode.parentNode, "dojoxGridNoChildren")){
 						var ew = dijit.byNode(en);
 						if(ew){
 							ew._toggleRows(toggleClass, ew.open&&open);
@@ -41,9 +57,9 @@ dojo.declare("dojox.grid._Expando", [ dijit._Widget, dijit._Templated ], {
 				});
 			}
 		}else{
-			dojo.query("tr." + toggleClass, this.rowNode).forEach(function(n){
-				if(dojo.hasClass(n, "dojoxGridExpandoRow")){
-					var en = dojo.query(".dojoxGridExpando", n)[0];
+			query("tr." + toggleClass, this.rowNode).forEach(function(n){
+				if(domClass.contains(n, "dojoxGridExpandoRow")){
+					var en = query(".dojoxGridExpando", n)[0];
 					if(en){
 						var ew = dijit.byNode(en);
 						var toggleClass = ew ? ew.toggleClass : en.getAttribute("toggleClass");
@@ -56,7 +72,7 @@ dojo.declare("dojox.grid._Expando", [ dijit._Widget, dijit._Templated ], {
 		}
 	},
 	setOpen: function(open){
-		if(open && dojo.hasClass(this.domNode, "dojoxGridExpandoLoading")){
+		if(open && domClass.contains(this.domNode, "dojoxGridExpandoLoading")){
 			open = false;
 		}
 		var view = this.view;
@@ -70,10 +86,10 @@ dojo.declare("dojox.grid._Expando", [ dijit._Widget, dijit._Templated ], {
 		if(treeModel && !this._loadedChildren){
 			if(open){
 				// Do this to make sure our children are fully-loaded
-				var itm = grid.getItem(dojo.attr(this._tableRow, "dojoxTreeGridPath"));
+				var itm = grid.getItem(domAttr.get(this._tableRow, "dojoxTreeGridPath"));
 				if(itm){
 					this.expandoInner.innerHTML = "o";
-					dojo.addClass(this.domNode, "dojoxGridExpandoLoading");
+					domClass.add(this.domNode, "dojoxGridExpandoLoading");
 					treeModel.getChildren(itm, function(items){
 						d._loadedChildren = true;
 						d._setOpen(open);
@@ -89,10 +105,10 @@ dojo.declare("dojox.grid._Expando", [ dijit._Widget, dijit._Templated ], {
 				var data = grid._by_idx[this.rowIdx];
 				if(data&&!store.isItemLoaded(data.item)){
 					this.expandoInner.innerHTML = "o";
-					dojo.addClass(this.domNode, "dojoxGridExpandoLoading");
+					domClass.add(this.domNode, "dojoxGridExpandoLoading");
 					store.loadItem({
 						item: data.item,
-						onItem: dojo.hitch(this, function(i){
+						onItem: lang.hitch(this, function(i){
 							var idty = store.getIdentity(i);
 							grid._by_idty[idty] = grid._by_idx[this.rowIdx] = { idty: idty, item: i };
 							this._setOpen(open);
@@ -109,19 +125,19 @@ dojo.declare("dojox.grid._Expando", [ dijit._Widget, dijit._Templated ], {
 		}
 	},
 	_setOpen: function(open){
-		if(open && this._tableRow && dojo.hasClass(this._tableRow, "dojoxGridNoChildren")){
+		if(open && this._tableRow && domClass.contains(this._tableRow, "dojoxGridNoChildren")){
 			this._setOpen(false);
 			return;
 		}
 		this.expandoInner.innerHTML = open ? "-" : "+";
-		dojo.removeClass(this.domNode, "dojoxGridExpandoLoading");
-		dojo.toggleClass(this.domNode, "dojoxGridExpandoOpened", open);
+		domClass.remove(this.domNode, "dojoxGridExpandoLoading");
+		domClass.toggle(this.domNode, "dojoxGridExpandoOpened", open);
 		if(this._tableRow){
-			dojo.toggleClass(this._tableRow, "dojoxGridRowCollapsed", !open);
-			var base = dojo.attr(this._tableRow, "dojoxTreeGridBaseClasses");
+			domClass.toggle(this._tableRow, "dojoxGridRowCollapsed", !open);
+			var base = domAttr.get(this._tableRow, "dojoxTreeGridBaseClasses");
 			var new_base = "";
 			if(open){
-				new_base = dojo.trim((" " + base + " ").replace(" dojoxGridRowCollapsed ", " "));
+				new_base = lang.trim((" " + base + " ").replace(" dojoxGridRowCollapsed ", " "));
 			}else{
 				if((" " + base + " ").indexOf(' dojoxGridRowCollapsed ') < 0){
 					new_base = base + (base ? ' ' : '' ) + 'dojoxGridRowCollapsed';
@@ -129,7 +145,7 @@ dojo.declare("dojox.grid._Expando", [ dijit._Widget, dijit._Templated ], {
 					new_base = base;
 				}
 			}
-			dojo.attr(this._tableRow, 'dojoxTreeGridBaseClasses', new_base);
+			domAttr.set(this._tableRow, 'dojoxTreeGridBaseClasses', new_base);
 		}
 		var changed = (this.open !== open);
 		this.open = open;
@@ -152,7 +168,7 @@ dojo.declare("dojox.grid._Expando", [ dijit._Widget, dijit._Templated ], {
 	},
 	onToggle: function(e){
 		this.setOpen(!this.open);
-		dojo.stopEvent(e);
+		event.stop(e);
 	},
 	setRowNode: function(rowIdx, rowNode, view){
 		if(this.cellIdx < 0 || !this.itemId){ return false; }
@@ -170,9 +186,9 @@ dojo.declare("dojox.grid._Expando", [ dijit._Widget, dijit._Templated ], {
 			// TODO: Rather than hard-code the 18px and 3px, we should probably
 			// calculate them based off css or something...  However, all the
 			// themes that we support use these values.
-			dojo.style(this.domNode , "marginLeft" , (this.level * 18) + "px");
+			domStyle.set(this.domNode , "marginLeft" , (this.level * 18) + "px");
 			if(this.domNode.parentNode){
-				dojo.style(this.domNode.parentNode, "backgroundPosition", ((this.level * 18) + (3)) + "px");
+				domStyle.set(this.domNode.parentNode, "backgroundPosition", ((this.level * 18) + (3)) + "px");
 			}
 		}
 		this.setOpen(this.open);
@@ -180,7 +196,7 @@ dojo.declare("dojox.grid._Expando", [ dijit._Widget, dijit._Templated ], {
 	}
 });
 
-dojo.declare("dojox.grid._TreeContentBuilder", dojox.grid._ContentBuilder, {
+var _TreeContentBuilder = declare("dojox.grid._TreeContentBuilder", _Builder._ContentBuilder, {
 	generateHtml: function(inDataIndex, inRowIndex){
 		var
 			html = this.getTableArray(),
@@ -190,7 +206,7 @@ dojo.declare("dojox.grid._TreeContentBuilder", dojox.grid._ContentBuilder, {
 			grid = this.grid,
 			store = this.grid.store;
 
-		dojox.grid.util.fire(this.view, "onBeforeRow", [inRowIndex, [row]]);
+		util.fire(this.view, "onBeforeRow", [inRowIndex, [row]]);
 		
 		var createRow = function(level, rowItem, summaryRow, toggleClasses, rowStack, shown){
 			if(!shown){
@@ -243,7 +259,7 @@ dojo.declare("dojox.grid._TreeContentBuilder", dojox.grid._ContentBuilder, {
 					parentOpen = expandoCell.getOpenState(rowItem) && shown;
 					path = new dojox.grid.TreePath(rowStack.join('/'), grid);
 					values = path.children(true)||[];
-					dojo.forEach(values, function(cItm, idx){
+					array.forEach(values, function(cItm, idx){
 						var nToggle = tcJoin.split('|');
 						nToggle.push(nToggle[nToggle.length - 1] + "-" + idx);
 						iStack.push(idx);
@@ -261,7 +277,7 @@ dojo.declare("dojox.grid._TreeContentBuilder", dojox.grid._ContentBuilder, {
 					values = path.children(true)||[];
 					if(values.length){
 						html[rowNodeIdx] = '<tr class="' + tToggle.join(' ') +' dojoxGridExpandoRow" dojoxTreeGridPath="' + rowStack.join('/') + '">';
-						dojo.forEach(values, function(cItm, idx){
+						array.forEach(values, function(cItm, idx){
 							var nToggle = tcJoin.split('|');
 							nToggle.push(nToggle[nToggle.length - 1] + "-" + idx);
 							iStack.push(idx);
@@ -299,23 +315,23 @@ dojo.declare("dojox.grid._TreeContentBuilder", dojox.grid._ContentBuilder, {
 		return (n != this.domNode) ? n : null;
 	},
 	getCellNode: function(inRowNode, inCellIndex){
-		var node = dojo.query("td[idx='" + inCellIndex + "']", inRowNode)[0];
-		if(node&&node.parentNode&&!dojo.hasClass(node.parentNode, "dojoxGridSummaryRow")){
+		var node = query("td[idx='" + inCellIndex + "']", inRowNode)[0];
+		if(node&&node.parentNode&&!domClass.contains(node.parentNode, "dojoxGridSummaryRow")){
 			return node;
 		}
 	},
 	decorateEvent: function(e){
 		e.rowNode = this.findRowTarget(e.target);
 		if(!e.rowNode){return false;}
-		e.rowIndex = dojo.attr(e.rowNode, 'dojoxTreeGridPath');
+		e.rowIndex = domAttr.get(e.rowNode, 'dojoxTreeGridPath');
 		this.baseDecorateEvent(e);
 		e.cell = this.grid.getCell(e.cellIndex);
 		return true; // Boolean
 	}
 });
 
-dojo.declare("dojox.grid._TreeView", [dojox.grid._View], {
-	_contentBuilderClass: dojox.grid._TreeContentBuilder,
+return declare("dojox.grid._TreeView", _View, {
+	_contentBuilderClass: _TreeContentBuilder,
 	_onDndDrop: function(source, nodes, copy){
 		if(this.grid && this.grid.aggregator){
 			this.grid.aggregator.clearSubtotalCache();
@@ -330,7 +346,7 @@ dojo.declare("dojox.grid._TreeView", [dojox.grid._View], {
 		if(index == -1){
 			return;
 		}
-		dojo.forEach(this.grid.layout.cells, function(cell){
+		array.forEach(this.grid.layout.cells, function(cell){
 			if(typeof cell['openStates'] != 'undefined'){
 				if(identity in cell.openStates){
 					delete cell.openStates[identity];
@@ -388,7 +404,7 @@ dojo.declare("dojox.grid._TreeView", [dojox.grid._View], {
 		this.inherited(arguments);
 	},
 	onAfterRow: function(inRowIndex, cells, inRowNode){
-		dojo.forEach(dojo.query("span.dojoxGridExpando", inRowNode), function(n){
+		array.forEach(query("span.dojoxGridExpando", inRowNode), function(n){
 			if(n && n.parentNode){
 				// Either create our expando or put the existing expando back
 				// into place
@@ -401,43 +417,48 @@ dojo.declare("dojox.grid._TreeView", [dojox.grid._View], {
 					expando = this._expandos[idty][tc];
 				}
 				if(expando){
-					dojo.place(expando.domNode, n, "replace");
+					domCtr.place(expando.domNode, n, "replace");
 					expando.itemId = n.getAttribute("itemId");
 					expando.cellIdx = parseInt(n.getAttribute("cellIdx"), 10);
 					if(isNaN(expando.cellIdx)){
 						expando.cellIdx = -1;
 					}
 				}else{
-					expando = dojo.parser.parse(n.parentNode)[0];
 					if(idty){
+						expando = parser.parse(n.parentNode)[0];
 						this._expandos[idty][tc] = expando;
 					}
 				}
-				if(!expando.setRowNode(inRowIndex, inRowNode, this)){
+				if(expando && !expando.setRowNode(inRowIndex, inRowNode, this)){
 					expando.domNode.parentNode.removeChild(expando.domNode);
 				}
 			}
 		}, this);
 		var alt = false;
 		var self = this;
-		dojo.query("tr[dojoxTreeGridPath]", inRowNode).forEach(function(n){
-			dojo.toggleClass(n, "dojoxGridSubRowAlt", alt);
-			dojo.attr(n, "dojoxTreeGridBaseClasses", n.className);
+		query("tr[dojoxTreeGridPath]", inRowNode).forEach(function(n){
+			domClass.toggle(n, "dojoxGridSubRowAlt", alt);
+			domAttr.set(n, "dojoxTreeGridBaseClasses", n.className);
 			alt = !alt;
-			self.grid.rows.styleRowNode(dojo.attr(n, 'dojoxTreeGridPath'), n);
+			self.grid.rows.styleRowNode(domAttr.get(n, 'dojoxTreeGridPath'), n);
 		});
 		this.inherited(arguments);
 	},
 	updateRowStyles: function(inRowIndex){
-		var rowNodes = dojo.query("tr[dojoxTreeGridPath='" + inRowIndex + "']", this.domNode);
+		var rowNodes = query("tr[dojoxTreeGridPath='" + inRowIndex + "']", this.domNode);
 		if(rowNodes.length){
 			this.styleRowNode(inRowIndex, rowNodes[0]);
 		}
 	},
 	getCellNode: function(inRowIndex, inCellIndex){
-		var row = dojo.query("tr[dojoxTreeGridPath='" + inRowIndex + "']", this.domNode)[0];
+		var row = query("tr[dojoxTreeGridPath='" + inRowIndex + "']", this.domNode)[0];
 		if(row){
 			return this.content.getCellNode(row, inCellIndex);
 		}
+	},
+	destroy: function(){
+		this._cleanupExpandoCache();
+		this.inherited(arguments);
 	}
 });
+});
\ No newline at end of file
diff --git a/dojox/grid/_View.js b/dojox/grid/_View.js
index 102ade6..b8820d1 100644
--- a/dojox/grid/_View.js
+++ b/dojox/grid/_View.js
@@ -1,22 +1,34 @@
-dojo.provide("dojox.grid._View");
+define([
+	"dojo",
+	"dijit/registry",
+	"../main",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/_base/connect",
+	"dojo/_base/sniff",
+	"dojo/query",
+	"dojo/_base/window",
+	"dojo/text!./resources/View.html",
+	"dojo/dnd/Source",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dojox/html/metrics",
+	"./util",
+	"dojo/_base/html",
+	"./_Builder",
+	"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){
 
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dojox.grid._Builder");
-dojo.require("dojox.html.metrics");
-dojo.require("dojox.grid.util");
-
-dojo.require("dojo.dnd.Source");
-dojo.require("dojo.dnd.Manager");
-
-(function(){
 	// a private function
 	var getStyleText = function(inNode, inStyleText){
 		return inNode.style.cssText == undefined ? inNode.getAttribute("style") : inNode.style.cssText;
 	};
 
 	// some public functions
-	dojo.declare('dojox.grid._View', [dijit._Widget, dijit._Templated], {
+	var _View = declare('dojox.grid._View', [_Widget, _TemplatedMixin], {
 		// summary:
 		//		A collection of grid columns. A grid is comprised of a set of views that stack horizontally.
 		//		Grid creates views automatically based on grid's layout structure.
@@ -30,7 +42,7 @@ dojo.require("dojo.dnd.Manager");
 		// 		Width for the view, in valid css unit
 		viewWidth: "",
 
-		templatePath: dojo.moduleUrl("dojox.grid","resources/View.html"),
+		templateString: template,
 		
 		themeable: false,
 		classTag: 'dojoxGrid',
@@ -43,11 +55,11 @@ dojo.require("dojo.dnd.Manager");
 		
 		// _headerBuilderClass: Object
 		//		The class to use for our header builder
-		_headerBuilderClass: dojox.grid._HeaderBuilder,
+		_headerBuilderClass: _Builder._HeaderBuilder,
 		
 		// _contentBuilderClass: Object
 		//		The class to use for our content builder
-		_contentBuilderClass: dojox.grid._ContentBuilder,
+		_contentBuilderClass: _Builder._ContentBuilder,
 		
 		postMixInProperties: function(){
 			this.rowNodes = {};
@@ -55,21 +67,22 @@ dojo.require("dojo.dnd.Manager");
 
 		postCreate: function(){
 			this.connect(this.scrollboxNode,"onscroll","doscroll");
-			dojox.grid.util.funnelEvents(this.contentNode, this, "doContentEvent", [ 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]);
-			dojox.grid.util.funnelEvents(this.headerNode, this, "doHeaderEvent", [ 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]);
+			util.funnelEvents(this.contentNode, this, "doContentEvent", [ 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]);
+			util.funnelEvents(this.headerNode, this, "doHeaderEvent", [ 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]);
 			this.content = new this._contentBuilderClass(this);
 			this.header = new this._headerBuilderClass(this);
 			//BiDi: in RTL case, style width='9000em' causes scrolling problem in head node
-			if(!dojo._isBodyLtr()){
+			if(!this.grid.isLeftToRight()){
 				this.headerNodeContainer.style.width = "";
 			}
 		},
 
 		destroy: function(){
-			dojo.destroy(this.headerNode);
+			html.destroy(this.headerNode);
 			delete this.headerNode;
 			for(var i in this.rowNodes){
-				dojo.destroy(this.rowNodes[i]);
+				this._cleanupRowWidgets(this.rowNodes[i]);
+				html.destroy(this.rowNodes[i]);
 			}
 			this.rowNodes = {};
 			if(this.source){
@@ -80,7 +93,7 @@ dojo.require("dojo.dnd.Manager");
 
 		// focus
 		focus: function(){
-			if(dojo.isIE || dojo.isWebKit || dojo.isOpera){
+			if(has('ie') || has('webkit') || has('opera')){
 				this.hiddenFocusNode.focus();
 			}else{
 				this.scrollboxNode.focus();
@@ -113,7 +126,7 @@ dojo.require("dojo.dnd.Manager");
 			//		Cleans up the widgets for the given row node so that
 			//		we can reattach them if needed
 			if(inRowNode){
-				dojo.forEach(dojo.query("[widgetId]", inRowNode).map(dijit.byNode), function(w){
+				array.forEach(query("[widgetId]", inRowNode).map(dijit.byNode), function(w){
 					if(w._destroyOnRemove){
 						w.destroy();
 						delete w;
@@ -134,10 +147,10 @@ dojo.require("dojo.dnd.Manager");
 		onAfterRow: function(inRowIndex, cells, inRowNode){
 			this._onAfterRow(inRowIndex, cells, inRowNode);
 			var g = this.grid;
-			dojo.forEach(dojo.query(".dojoxGridStubNode", inRowNode), function(n){
+			array.forEach(query(".dojoxGridStubNode", inRowNode), function(n){
 				if(n && n.parentNode){
 					var lw = n.getAttribute("linkWidget");
-					var cellIdx = window.parseInt(dojo.attr(n, "cellIdx"), 10);
+					var cellIdx = window.parseInt(html.attr(n, "cellIdx"), 10);
 					var cellDef = g.getCell(cellIdx);
 					var w = dijit.byId(lw);
 					if(w){
@@ -145,6 +158,7 @@ dojo.require("dojo.dnd.Manager");
 						if(!w._started){
 							w.startup();
 						}
+						dojo.destroy(n);
 					}else{
 						n.innerHTML = "";
 					}
@@ -173,13 +187,13 @@ dojo.require("dojo.dnd.Manager");
 
 		getScrollbarWidth: function(){
 			var hasScrollSpace = this.hasVScrollbar();
-			var overflow = dojo.style(this.scrollboxNode, "overflow");
+			var overflow = html.style(this.scrollboxNode, "overflow");
 			if(this.noscroll || !overflow || overflow == "hidden"){
 				hasScrollSpace = false;
 			}else if(overflow == "scroll"){
 				hasScrollSpace = true;
 			}
-			return (hasScrollSpace ? dojox.html.metrics.getScrollbar().w : 0); // Integer
+			return (hasScrollSpace ? metrics.getScrollbar().w : 0); // Integer
 		},
 
 		getColumnsWidth: function(){
@@ -199,7 +213,7 @@ dojo.require("dojo.dnd.Manager");
 		},
 
 		getContentWidth: function(){
-			return Math.max(0, dojo._getContentBox(this.domNode).w - this.getScrollbarWidth()) + 'px'; // String
+			return Math.max(0, html._getContentBox(this.domNode).w - this.getScrollbarWidth()) + 'px'; // String
 		},
 
 		render: function(){
@@ -210,8 +224,8 @@ dojo.require("dojo.dnd.Manager");
 				this._togglingColumn = -1;
 			}
 			var cells = this.grid.layout.cells;
-			var getSibling = dojo.hitch(this, function(node, before){
-				!dojo._isBodyLtr() && (before = !before);
+			var getSibling = lang.hitch(this, function(node, before){
+				!this.grid.isLeftToRight() && (before = !before);
 				var inc = before?-1:1;
 				var idx = this.header.getCellNodeIndex(node) + inc;
 				var cell = cells[idx];
@@ -233,37 +247,37 @@ dojo.require("dojo.dnd.Manager");
 				var bottomMarkerId = "dojoxGrid_bottomMarker";
 				var topMarkerId = "dojoxGrid_topMarker";
 				if(this.bottomMarker){
-					dojo.destroy(this.bottomMarker);
+					html.destroy(this.bottomMarker);
 				}
-				this.bottomMarker = dojo.byId(bottomMarkerId);
+				this.bottomMarker = html.byId(bottomMarkerId);
 				if(this.topMarker){
-					dojo.destroy(this.topMarker);
+					html.destroy(this.topMarker);
 				}
-				this.topMarker = dojo.byId(topMarkerId);
+				this.topMarker = html.byId(topMarkerId);
 				if (!this.bottomMarker) {
-					this.bottomMarker = dojo.create("div", {
+					this.bottomMarker = html.create("div", {
 						"id": bottomMarkerId,
 						"class": "dojoxGridColPlaceBottom"
-					}, dojo.body());
+					}, win.body());
 					this._hide(this.bottomMarker);
 
 					
-					this.topMarker = dojo.create("div", {
+					this.topMarker = html.create("div", {
 						"id": topMarkerId,
 						"class": "dojoxGridColPlaceTop"
-					}, dojo.body());
+					}, win.body());
 					this._hide(this.topMarker);
 				}
-				this.arrowDim = dojo.contentBox(this.bottomMarker);
+				this.arrowDim = html.contentBox(this.bottomMarker);
 
-				var headerHeight = dojo.contentBox(this.headerContentNode.firstChild.rows[0]).h;
+				var headerHeight = html.contentBox(this.headerContentNode.firstChild.rows[0]).h;
 				
-				this.source = new dojo.dnd.Source(this.headerContentNode.firstChild.rows[0], {
+				this.source = new Source(this.headerContentNode.firstChild.rows[0], {
 					horizontal: true,
 					accept: [ "gridColumn_" + this.grid.id ],
 					viewIndex: this.index,
 					generateText: false,
-					onMouseDown: dojo.hitch(this, function(e){
+					onMouseDown: lang.hitch(this, function(e){
 						this.header.decorateEvent(e);
 						if((this.header.overRightResizeArea(e) || this.header.overLeftResizeArea(e)) &&
 							this.header.canResize(e) && !this.header.moveable){
@@ -273,45 +287,44 @@ dojo.require("dojo.dnd.Manager");
 								this.grid.headerMenu.onCancel(true);
 							}
 							// IE reports a left click as 1, where everything else reports 0
-							if(e.button === (dojo.isIE ? 1 : 0)){
-								dojo.dnd.Source.prototype.onMouseDown.call(this.source, e);
+							if(e.button === (has('ie') < 9 ? 1 : 0)){
+								Source.prototype.onMouseDown.call(this.source, e);
 							}
 						}
 					}),
-					onMouseOver: dojo.hitch(this, function(e){
+					onMouseOver: lang.hitch(this, function(e){
 						var src = this.source;
 						if(src._getChildByEvent(e)){
-							dojo.dnd.Source.prototype.onMouseOver.apply(src, arguments);
+							Source.prototype.onMouseOver.apply(src, arguments);
 						}
 					}),
-					_markTargetAnchor: dojo.hitch(this, function(before){
+					_markTargetAnchor: lang.hitch(this, function(before){
 						var src = this.source;
 						if(src.current == src.targetAnchor && src.before == before){ return; }
 						if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
 							src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
 						}
-						dojo.dnd.Source.prototype._markTargetAnchor.call(src, before);
+						Source.prototype._markTargetAnchor.call(src, before);
 						
 						var target = before ? src.targetAnchor : getSibling(src.targetAnchor, src.before);
 						var endAdd = 0;
 
 						if (!target) {
 							target = src.targetAnchor;
-							endAdd = dojo.contentBox(target).w + this.arrowDim.w/2 + 2;
+							endAdd = html.contentBox(target).w + this.arrowDim.w/2 + 2;
 						}
 
-						// NOTE: this is for backwards compatibility with Dojo 1.3
-						var pos = (dojo.position||dojo._abs)(target, true);
+						var pos = html.position(target, true);
 						var left = Math.floor(pos.x - this.arrowDim.w/2 + endAdd);
 
-						dojo.style(this.bottomMarker, "visibility", "visible");
-						dojo.style(this.topMarker, "visibility", "visible");
-						dojo.style(this.bottomMarker, {
+						html.style(this.bottomMarker, "visibility", "visible");
+						html.style(this.topMarker, "visibility", "visible");
+						html.style(this.bottomMarker, {
 							"left": left + "px",
 							"top" : (headerHeight + pos.y) + "px"
 						});
 
-						dojo.style(this.topMarker, {
+						html.style(this.topMarker, {
 							"left": left + "px",
 							"top" : (pos.y - this.arrowDim.h) + "px"
 						});
@@ -320,7 +333,7 @@ dojo.require("dojo.dnd.Manager");
 							src._addItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
 						}
 					}),
-					_unmarkTargetAnchor: dojo.hitch(this, function(){
+					_unmarkTargetAnchor: lang.hitch(this, function(){
 						var src = this.source;
 						if(!src.targetAnchor){ return; }
 						if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
@@ -328,37 +341,36 @@ dojo.require("dojo.dnd.Manager");
 						}
 						this._hide(this.bottomMarker);
 						this._hide(this.topMarker);
-						dojo.dnd.Source.prototype._unmarkTargetAnchor.call(src);
+						Source.prototype._unmarkTargetAnchor.call(src);
 					}),
-					destroy: dojo.hitch(this, function(){
-						dojo.disconnect(this._source_conn);
-						dojo.unsubscribe(this._source_sub);
-						dojo.dnd.Source.prototype.destroy.call(this.source);
+					destroy: lang.hitch(this, function(){
+						connect.disconnect(this._source_conn);
+						connect.unsubscribe(this._source_sub);
+						Source.prototype.destroy.call(this.source);
 						if(this.bottomMarker){
-							dojo.destroy(this.bottomMarker);
+							html.destroy(this.bottomMarker);
 							delete this.bottomMarker;
 						}
 						if(this.topMarker){
-							dojo.destroy(this.topMarker);
+							html.destroy(this.topMarker);
 							delete this.topMarker;
 						}
 					}),
-					onDndCancel: dojo.hitch(this, function(){
-						dojo.dnd.Source.prototype.onDndCancel.call(this.source);
+					onDndCancel: lang.hitch(this, function(){
+						Source.prototype.onDndCancel.call(this.source);
 						this._hide(this.bottomMarker);
 						this._hide(this.topMarker);
 					})
 				});
 
-				this._source_conn = dojo.connect(this.source, "onDndDrop", this, "_onDndDrop");
-				this._source_sub = dojo.subscribe("/dnd/drop/before", this, "_onDndDropBefore");
+				this._source_conn = connect.connect(this.source, "onDndDrop", this, "_onDndDrop");
+				this._source_sub = connect.subscribe("/dnd/drop/before", this, "_onDndDropBefore");
 				this.source.startup();
 			}
 		},
 		
 		_hide: function(node){
-			dojo.style(node, {
-				left: "-10000px",
+			html.style(node, {
 				top: "-10000px",
 				"visibility": "hidden"
 			});
@@ -390,9 +402,9 @@ dojo.require("dojo.dnd.Manager");
 			this._hide(this.topMarker);
 
 			var getIdx = function(n){
-				return n ? dojo.attr(n, "idx") : null;
+				return n ? html.attr(n, "idx") : null;
 			};
-			var w = dojo.marginBox(nodes[0]).w;
+			var w = html.marginBox(nodes[0]).w;
 			if(source.viewIndex !== this.index){
 				var views = this.grid.views.views;
 				var srcView = views[source.viewIndex];
@@ -406,7 +418,7 @@ dojo.require("dojo.dnd.Manager");
 			}
 			var stn = this.source._targetNode;
 			var stb = this.source._beforeTarget;
-			!dojo._isBodyLtr() && (stb = !stb);
+			!this.grid.isLeftToRight() && (stb = !stb);
 			var layout = this.grid.layout;
 			var idx = this.index;
 			delete this.source._targetNode;
@@ -426,12 +438,15 @@ dojo.require("dojo.dnd.Manager");
 				this.contentWidth = this.getContentWidth();
 				this.headerContentNode.firstChild.style.width = this.contentWidth;
 			}
-			dojox.grid.util.fire(this, "onAfterRow", [-1, this.structure.cells, this.headerContentNode]);
+			util.fire(this, "onAfterRow", [-1, this.structure.cells, this.headerContentNode]);
 		},
 
 		// note: not called in 'view' context
 		_getHeaderContent: function(inCell){
 			var n = inCell.name || inCell.grid.getCellName(inCell);
+			if(/^\s+$/.test(n)){
+				n = ' '//otherwise arrow styles will be messed up
+			}
 			var ret = [ '<div class="dojoxGridSortNode' ];
 			
 			if(inCell.index != inCell.grid.getSortIndex()){
@@ -459,7 +474,7 @@ dojo.require("dojo.dnd.Manager");
 				if(this.noscroll){
 					this._hasHScroll = false;
 				}else{
-					var style = dojo.style(this.scrollboxNode, "overflow");
+					var style = html.style(this.scrollboxNode, "overflow");
 					if(style == "hidden"){
 						this._hasHScroll = false;
 					}else if(style == "scroll"){
@@ -481,7 +496,7 @@ dojo.require("dojo.dnd.Manager");
 				if(this.noscroll){
 					this._hasVScroll = false;
 				}else{
-					var style = dojo.style(this.scrollboxNode, "overflow");
+					var style = html.style(this.scrollboxNode, "overflow");
 					if(style == "hidden"){
 						this._hasVScroll = false;
 					}else if(style == "scroll"){
@@ -501,25 +516,25 @@ dojo.require("dojo.dnd.Manager");
 			// Fix any percentage widths to be pixel values
 			var hasPct = false;
 			this.grid.initialWidth = "";
-			var cellNodes = dojo.query("th", this.headerContentNode);
-			var fixedWidths = dojo.map(cellNodes, function(c, vIdx){
+			var cellNodes = query("th", this.headerContentNode);
+			var fixedWidths = array.map(cellNodes, function(c, vIdx){
 				var w = c.style.width;
-				dojo.attr(c, "vIdx", vIdx);
+				html.attr(c, "vIdx", vIdx);
 				if(w && w.slice(-1) == "%"){
 					hasPct = true;
 				}else if(w && w.slice(-2) == "px"){
 					return window.parseInt(w, 10);
 				}
-				return dojo.contentBox(c).w;
+				return html.contentBox(c).w;
 			});
 			if(hasPct){
-				dojo.forEach(this.grid.layout.cells, function(cell, idx){
+				array.forEach(this.grid.layout.cells, function(cell, idx){
 					if(cell.view == this){
 						var cellNode = cell.view.getHeaderCellNode(cell.index);
-						if(cellNode && dojo.hasAttr(cellNode, "vIdx")){
-							var vIdx = window.parseInt(dojo.attr(cellNode, "vIdx"));
+						if(cellNode && html.hasAttr(cellNode, "vIdx")){
+							var vIdx = window.parseInt(html.attr(cellNode, "vIdx"));
 							this.setColWidth(idx, fixedWidths[vIdx]);
-							dojo.removeAttr(cellNode, "vIdx");
+							html.removeAttr(cellNode, "vIdx");
 						}
 					}
 				}, this);
@@ -543,9 +558,9 @@ dojo.require("dojo.dnd.Manager");
 					return false;
 				};
 				if(minusScroll || (this.noscroll && checkOtherViewScrollers())){
-					h -= dojox.html.metrics.getScrollbar().h;
+					h -= metrics.getScrollbar().h;
 				}
-				dojox.grid.util.setStyleHeightPx(this.scrollboxNode, h);
+				util.setStyleHeightPx(this.scrollboxNode, h);
 			}
 			this.hasVScrollbar(true);
 		},
@@ -584,7 +599,7 @@ dojo.require("dojo.dnd.Manager");
 		renderRow: function(inRowIndex){
 			var rowNode = this.createRowNode(inRowIndex);
 			this.buildRow(inRowIndex, rowNode);
-			this.grid.edit.restore(this, inRowIndex);
+			//this.grid.edit.restore(this, inRowIndex);
 			return rowNode;
 		},
 
@@ -592,15 +607,15 @@ dojo.require("dojo.dnd.Manager");
 			var node = document.createElement("div");
 			node.className = this.classTag + 'Row';
 			if (this instanceof dojox.grid._RowSelector){
-				dojo.attr(node,"role","presentation");
+				html.attr(node,"role","presentation");
 			}else{
-				dojo.attr(node,"role","row");
+				html.attr(node,"role","row");
 				if (this.grid.selectionMode != "none") {
-					dojo.attr(node, "aria-selected", "false"); //rows can be selected so add aria-selected prop
+					node.setAttribute("aria-selected", "false"); //rows can be selected so add aria-selected prop
 				}
 			}
-			node[dojox.grid.util.gridViewTag] = this.id;
-			node[dojox.grid.util.rowIndexTag] = inRowIndex;
+			node[util.gridViewTag] = this.id;
+			node[util.rowIndexTag] = inRowIndex;
 			this.rowNodes[inRowIndex] = node;
 			return node;
 		},
@@ -620,7 +635,7 @@ dojo.require("dojo.dnd.Manager");
 				// FIXME: accessing firstChild here breaks encapsulation
 				inRowNode.firstChild.style.width = this.contentWidth;
 			}
-			dojox.grid.util.fire(this, "onAfterRow", [inRowIndex, this.structure.cells, inRowNode]);
+			util.fire(this, "onAfterRow", [inRowIndex, this.structure.cells, inRowNode]);
 		},
 
 		rowRemoved:function(inRowIndex){
@@ -684,13 +699,13 @@ dojo.require("dojo.dnd.Manager");
 
 		doscroll: function(inEvent){
 			//var s = dojo.marginBox(this.headerContentNode.firstChild);
-			var isLtr = dojo._isBodyLtr();
+			var isLtr = this.grid.isLeftToRight();
 			if(this.firstScroll < 2){
 				if((!isLtr && this.firstScroll == 1) || (isLtr && this.firstScroll === 0)){
-					var s = dojo.marginBox(this.headerNodeContainer);
-					if(dojo.isIE){
+					var s = html.marginBox(this.headerNodeContainer);
+					if(has('ie')){
 						this.headerNodeContainer.style.width = s.w + this.getScrollbarWidth() + 'px';
-					}else if(dojo.isMoz){
+					}else if(has('mozilla')){
 						//TODO currently only for FF, not sure for safari and opera
 						this.headerNodeContainer.style.width = s.w - this.getScrollbarWidth() + 'px';
 						//this.headerNodeContainer.style.width = s.w + 'px';
@@ -758,9 +773,9 @@ dojo.require("dojo.dnd.Manager");
 		}
 	});
 
-	dojo.declare("dojox.grid._GridAvatar", dojo.dnd.Avatar, {
+	var _GridAvatar = declare("dojox.grid._GridAvatar", Avatar, {
 		construct: function(){
-			var dd = dojo.doc;
+			var dd = win.doc;
 
 			var a = dd.createElement("table");
 			a.cellPadding = a.cellSpacing = "0";
@@ -806,7 +821,7 @@ dojo.require("dojo.dnd.Manager");
 			td.appendChild(node);
 			tr.appendChild(img);
 			tr.appendChild(td);
-			dojo.style(tr, "opacity", 0.9);
+			html.style(tr, "opacity", 0.9);
 			b.appendChild(tr);
 
 			a.appendChild(b);
@@ -825,9 +840,12 @@ dojo.require("dojo.dnd.Manager");
 	var oldMakeAvatar = dojo.dnd.manager().makeAvatar;
 	dojo.dnd.manager().makeAvatar = function(){
 		var src = this.source;
-		if(src.viewIndex !== undefined && !dojo.hasClass(dojo.body(),"dijit_a11y")){
-			return new dojox.grid._GridAvatar(this);
+		if(src.viewIndex !== undefined && !html.hasClass(win.body(),"dijit_a11y")){
+			return new _GridAvatar(this);
 		}
 		return oldMakeAvatar.call(dojo.dnd.manager());
 	};
-})();
+
+	return _View;
+
+});
\ No newline at end of file
diff --git a/dojox/grid/_ViewManager.js b/dojox/grid/_ViewManager.js
index a20a6ab..18181e4 100644
--- a/dojox/grid/_ViewManager.js
+++ b/dojox/grid/_ViewManager.js
@@ -1,6 +1,10 @@
-dojo.provide("dojox.grid._ViewManager");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/sniff",
+	"dojo/dom-class"
+], function(declare, has, domClass){
 
-dojo.declare('dojox.grid._ViewManager', null, {
+return declare('dojox.grid._ViewManager', null, {
 	// summary:
 	//		A collection of grid views. Owned by grid and used internally for managing grid views.
 	// description:
@@ -85,7 +89,7 @@ dojo.declare('dojox.grid._ViewManager', null, {
 				// depends on the container not having any margin (which it shouldn't)
 				// Also - we only look up the height if the cell doesn't have the
 				// dojoxGridNonNormalizedCell class (like for row selectors)
-				if(!dojo.hasClass(n, "dojoxGridNonNormalizedCell")){
+				if(!domClass.contains(n, "dojoxGridNonNormalizedCell")){
 					currHeights[i] = n.firstChild.offsetHeight;
 					h =  Math.max(h, currHeights[i]);
 				}
@@ -94,7 +98,7 @@ dojo.declare('dojox.grid._ViewManager', null, {
 	
 			//Work around odd FF3 rendering bug: #8864.
 			//A one px increase fixes FireFox 3's rounding bug for fractional font sizes.
-			if(dojo.isMoz && h){h++;}
+			if((has('mozilla') || has('ie') > 8 ) && h){h++;}
 		}
 		for(i=0; (n=inRowNodes[i]); i++){
 			if(currHeights[i] != h){
@@ -174,7 +178,7 @@ dojo.declare('dojox.grid._ViewManager', null, {
 	},
 
 	arrange: function(l, w){
-		var i, v, vw, len = this.views.length;
+		var i, v, vw, len = this.views.length, self = this;
 		// find the client
 		var c = (w <= 0 ? len : this.findClient());
 		// layout views
@@ -182,10 +186,10 @@ dojo.declare('dojox.grid._ViewManager', null, {
 			var ds = v.domNode.style;
 			var hs = v.headerNode.style;
 
-			if(!dojo._isBodyLtr()){
+			if(!self.grid.isLeftToRight()){
 				ds.right = l + 'px';
-				// fixed rtl, the scrollbar is on the right side in FF
-				if (dojo.isMoz) {
+				// fixed rtl, the scrollbar is on the right side in FF or WebKit
+				if (has('ff') < 4 || has('webkit')){
 					hs.right = l + v.getScrollbarWidth() + 'px';
 					hs.width = parseInt(hs.width, 10) - v.getScrollbarWidth() + 'px';
 				}else{
@@ -281,7 +285,7 @@ dojo.declare('dojox.grid._ViewManager', null, {
 			top = v.setScrollTop(inTop);
 			// Work around IE not firing scroll events that cause header offset
 			// issues to occur.
-			if(dojo.isIE && v.headerNode && v.scrollboxNode){
+			if(has('ie') && v.headerNode && v.scrollboxNode){
 				v.headerNode.scrollLeft = v.scrollboxNode.scrollLeft;
 			}
 		}
@@ -298,5 +302,5 @@ dojo.declare('dojox.grid._ViewManager', null, {
 		}
 		return null;
 	}
-	
 });
+});
\ No newline at end of file
diff --git a/dojox/grid/cells.js b/dojox/grid/cells.js
index 551af16..c385330 100644
--- a/dojox/grid/cells.js
+++ b/dojox/grid/cells.js
@@ -1,2 +1,3 @@
-dojo.provide("dojox.grid.cells");
-dojo.require("dojox.grid.cells._base");
+define(["../main", "./cells/_base"], function(dojox){
+	return dojox.grid.cells;
+});
\ No newline at end of file
diff --git a/dojox/grid/cells/_base.js b/dojox/grid/cells/_base.js
index 76fdc56..a5e6a31 100644
--- a/dojox/grid/cells/_base.js
+++ b/dojox/grid/cells/_base.js
@@ -1,38 +1,45 @@
-dojo.provide("dojox.grid.cells._base");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/event",
+	"dojo/_base/connect",
+	"dojo/_base/array",
+	"dojo/_base/sniff",
+	"dojo/dom",
+	"dojo/dom-attr",
+	"dojo/dom-construct",
+	"dijit/_Widget",
+	"../util"
+], function(dojo, declare, lang, event, connect, array, has, dom, domAttr, domConstruct, _Widget, util){
 
-dojo.require("dojox.grid.util");
-dojo.require("dijit._Widget");
-
-dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
-	deferred: null,
-	_destroyOnRemove: true,
-	postCreate: function(){
-		if(this.deferred){
-			this.deferred.addBoth(dojo.hitch(this, function(text){
-				if(this.domNode){
-					this.domNode.innerHTML = text;
-				}
-			}));
+	var _DeferredTextWidget = declare("dojox.grid._DeferredTextWidget", _Widget, {
+		deferred: null,
+		_destroyOnRemove: true,
+		postCreate: function(){
+			if(this.deferred){
+				this.deferred.addBoth(lang.hitch(this, function(text){
+					if(this.domNode){
+						this.domNode.innerHTML = text;
+					}
+				}));
+			}
 		}
-	}
-});
+	});
 
-(function(){
 	var focusSelectNode = function(inNode){
 		try{
-			dojox.grid.util.fire(inNode, "focus");
-			dojox.grid.util.fire(inNode, "select");
+			util.fire(inNode, "focus");
+			util.fire(inNode, "select");
 		}catch(e){// IE sux bad
 		}
 	};
 	
 	var whenIdle = function(/*inContext, inMethod, args ...*/){
-		setTimeout(dojo.hitch.apply(dojo, arguments), 0);
+		setTimeout(lang.hitch.apply(dojo, arguments), 0);
 	};
 
-	var dgc = dojox.grid.cells;
-
-	dojo.declare("dojox.grid.cells._Base", null, {
+	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.
@@ -54,7 +61,7 @@ dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
 
 		constructor: function(inProps){
 			this._props = inProps || {};
-			dojo.mixin(this, inProps);
+			lang.mixin(this, inProps);
 			if(this.draggable === undefined){
 				this.draggable = true;
 			}
@@ -72,8 +79,8 @@ dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
 			}
 			if(v && v.addBoth){
 				// Check if it's a deferred
-				v = new dojox.grid._DeferredTextWidget({deferred: v},
-									dojo.create("span", {innerHTML: this.defaultValue}));
+				v = new _DeferredTextWidget({deferred: v},
+									domConstruct.create("span", {innerHTML: this.defaultValue}));
 			}
 			if(v && v.declaredClass && v.startup){
 				return "<div class='dojoxGridStubNode' linkWidget='" +
@@ -132,7 +139,7 @@ dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
 		},
 		isFlex: function(){
 			var uw = this.unitWidth;
-			return uw && dojo.isString(uw) && (uw=='auto' || uw.slice(-1)=='%');
+			return uw && lang.isString(uw) && (uw=='auto' || uw.slice(-1)=='%');
 		},
 		// edit support
 		applyEdit: function(inValue, inRowIndex){
@@ -149,9 +156,9 @@ dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
 		},
 		registerOnBlur: function(inNode, inRowIndex){
 			if(this.commitOnBlur){
-				dojo.connect(inNode, "onblur", function(e){
+				connect.connect(inNode, "onblur", function(e){
 					// hack: if editor still thinks this editor is current some ms after it blurs, assume we've focused away from grid
-					setTimeout(dojo.hitch(this, "_onEditBlur", inRowIndex), 250);
+					setTimeout(lang.hitch(this, "_onEditBlur", inRowIndex), 250);
 				});
 			}
 		},
@@ -168,7 +175,9 @@ dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
 			if(this._formatPending){
 				this._formatPending = false;
 				// make cell selectable
-				dojo.setSelectable(this.grid.domNode, true);
+				if(!has('ie')){
+					dom.setSelectable(this.grid.domNode, true);
+				}
 				this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex);
 			}
 		},
@@ -182,7 +191,7 @@ dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
 			//	cell data to edit
 			// inRowIndex: int
 			//	grid row index
-			if(dojo.isIE){
+			if(has('ie')){
 				// IE sux bad
 				whenIdle(this, "focus", inRowIndex, inNode);
 			}else{
@@ -247,7 +256,7 @@ dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
 			//	called when editing is completed to clean up editor
 			// inRowIndex: int
 			// grid row index
-			dojo.setSelectable(this.grid.domNode, false);
+			dom.setSelectable(this.grid.domNode, false);
 			this.cancelFormatNode();
 		},
 		//public
@@ -268,18 +277,17 @@ dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
 			this._finish(inRowIndex);
 		}
 	});
-	dgc._Base.markupFactory = function(node, cellDef){
-		var d = dojo;
-		var formatter = d.trim(d.attr(node, "formatter")||"");
+	BaseCell.markupFactory = function(node, cellDef){
+		var formatter = lang.trim(domAttr.get(node, "formatter")||"");
 		if(formatter){
-			cellDef.formatter = dojo.getObject(formatter)||formatter;
+			cellDef.formatter = lang.getObject(formatter)||formatter;
 		}
-		var get = d.trim(d.attr(node, "get")||"");
+		var get = lang.trim(domAttr.get(node, "get")||"");
 		if(get){
-			cellDef.get = dojo.getObject(get);
+			cellDef.get = lang.getObject(get);
 		}
 		var getBoolAttr = function(attr, cell, cellAttr){
-			var value = d.trim(d.attr(node, attr)||"");
+			var value = lang.trim(domAttr.get(node, attr)||"");
 			if(value){ cell[cellAttr||attr] = !(value.toLowerCase()=="false"); }
 		};
 		getBoolAttr("sortDesc", cellDef);
@@ -288,13 +296,13 @@ dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
 		getBoolAttr("noresize", cellDef);
 		getBoolAttr("draggable", cellDef);
 
-		var value = d.trim(d.attr(node, "loadingText")||d.attr(node, "defaultValue")||"");
+		var value = lang.trim(domAttr.get(node, "loadingText")||domAttr.get(node, "defaultValue")||"");
 		if(value){
 			cellDef.defaultValue = value;
 		}
 
 		var getStrAttr = function(attr, cell, cellAttr){
-			var value = d.trim(d.attr(node, attr)||"")||undefined;
+			var value = lang.trim(domAttr.get(node, attr)||"")||undefined;
 			if(value){ cell[cellAttr||attr] = value; }
 		};
 		getStrAttr("styles", cellDef);
@@ -305,7 +313,7 @@ dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
 		getStrAttr("cellClasses", cellDef);
 	};
 
-	dojo.declare("dojox.grid.cells.Cell", dgc._Base, {
+	var Cell = declare("dojox.grid.cells.Cell", BaseCell, {
 		// summary
 		// grid cell that provides a standard text input box upon editing
 		constructor: function(){
@@ -327,7 +335,7 @@ dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
 			if(this.keyFilter){
 				var key = String.fromCharCode(e.charCode);
 				if(key.search(this.keyFilter) == -1){
-					dojo.stopEvent(e);
+					event.stop(e);
 				}
 			}
 		},
@@ -335,20 +343,19 @@ dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
 			this.inherited(arguments);
 			var n = this.getEditNode(inRowIndex);
 			try{
-				dojox.grid.util.fire(n, "blur");
+				util.fire(n, "blur");
 			}catch(e){}
 		}
 	});
-	dgc.Cell.markupFactory = function(node, cellDef){
-		dgc._Base.markupFactory(node, cellDef);
-		var d = dojo;
-		var keyFilter = d.trim(d.attr(node, "keyFilter")||"");
+	Cell.markupFactory = function(node, cellDef){
+		BaseCell.markupFactory(node, cellDef);
+		var keyFilter = lang.trim(domAttr.get(node, "keyFilter")||"");
 		if(keyFilter){
 			cellDef.keyFilter = new RegExp(keyFilter);
 		}
 	};
 
-	dojo.declare("dojox.grid.cells.RowIndex", dgc.Cell, {
+	var RowIndex = declare("dojox.grid.cells.RowIndex", Cell, {
 		name: 'Row',
 
 		postscript: function(){
@@ -358,11 +365,11 @@ dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
 			return inRowIndex + 1;
 		}
 	});
-	dgc.RowIndex.markupFactory = function(node, cellDef){
-		dgc.Cell.markupFactory(node, cellDef);
+	RowIndex.markupFactory = function(node, cellDef){
+		Cell.markupFactory(node, cellDef);
 	};
 
-	dojo.declare("dojox.grid.cells.Select", dgc.Cell, {
+	var Select = declare("dojox.grid.cells.Select", Cell, {
 		// summary:
 		// grid cell that provides a standard select for editing
 
@@ -385,11 +392,25 @@ dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
 			this.needFormatNode(inDatum, inRowIndex);
 			var h = [ '<select 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;
 				h.push("<option", (inDatum==v ? ' selected' : ''), ' value="' + v + '"', ">", o, "</option>");
 			}
 			h.push('</select>');
 			return h.join('');
 		},
+		_defaultFormat: function(inValue, callArgs){
+			var v = this.inherited(arguments);
+			// when 'values' and 'options' both provided and there is no cutomized formatter,
+			// then we use 'options' as label in order to be consistent
+			if(!this.formatter && this.values && this.options){
+				var i = array.indexOf(this.values, v);
+				if(i >= 0){
+					v = this.options[i];
+				}
+			}
+			return v;
+		},
 		getValue: function(inRowIndex){
 			var n = this.getEditNode(inRowIndex);
 			if(n){
@@ -398,17 +419,16 @@ dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
 			}
 		}
 	});
-	dgc.Select.markupFactory = function(node, cell){
-		dgc.Cell.markupFactory(node, cell);
-		var d=dojo;
-		var options = d.trim(d.attr(node, "options")||"");
+	Select.markupFactory = function(node, cell){
+		Cell.markupFactory(node, cell);
+		var options = lang.trim(domAttr.get(node, "options")||"");
 		if(options){
 			var o = options.split(',');
 			if(o[0] != options){
 				cell.options = o;
 			}
 		}
-		var values = d.trim(d.attr(node, "values")||"");
+		var values = lang.trim(domAttr.get(node, "values")||"");
 		if(values){
 			var v = values.split(',');
 			if(v[0] != values){
@@ -417,7 +437,7 @@ dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
 		}
 	};
 
-	dojo.declare("dojox.grid.cells.AlwaysEdit", dgc.Cell, {
+	var AlwaysEdit = declare("dojox.grid.cells.AlwaysEdit", Cell, {
 		// summary:
 		// grid cell that is always in an editable state, regardless of grid editing state
 		alwaysEditing: true,
@@ -430,11 +450,11 @@ dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
 			e.start(this, inRowIndex, true);
 		}
 	});
-	dgc.AlwaysEdit.markupFactory = function(node, cell){
-		dgc.Cell.markupFactory(node, cell);
+	AlwaysEdit.markupFactory = function(node, cell){
+		Cell.markupFactory(node, cell);
 	};
 
-	dojo.declare("dojox.grid.cells.Bool", dgc.AlwaysEdit, {
+	var Bool = declare("dojox.grid.cells.Bool", AlwaysEdit, {
 		// summary:
 		// grid cell that provides a standard checkbox that is always on for editing
 		_valueProp: "checked",
@@ -447,7 +467,10 @@ dojo.declare("dojox.grid._DeferredTextWidget", dijit._Widget, {
 			}
 		}
 	});
-	dgc.Bool.markupFactory = function(node, cell){
-		dgc.AlwaysEdit.markupFactory(node, cell);
+	Bool.markupFactory = function(node, cell){
+		AlwaysEdit.markupFactory(node, cell);
 	};
-})();
+
+	return BaseCell;
+
+});
\ No newline at end of file
diff --git a/dojox/grid/cells/dijit.js b/dojox/grid/cells/dijit.js
index c10ae1f..94f1636 100644
--- a/dojox/grid/cells/dijit.js
+++ b/dojox/grid/cells/dijit.js
@@ -1,31 +1,43 @@
-dojo.provide("dojox.grid.cells.dijit");
-
-dojo.require("dojox.grid.cells");
-
+define([
+	"dojo/_base/kernel",
+	"../../main",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/_base/json",
+	"dojo/_base/connect",
+	"dojo/_base/sniff",
+	"dojo/dom",
+	"dojo/dom-attr",
+	"dojo/dom-construct",
+	"dojo/dom-geometry",
+	"dojo/data/ItemFileReadStore",
+	"dijit/form/DateTextBox",
+	"dijit/form/TimeTextBox",
+	"dijit/form/ComboBox",
+	"dijit/form/CheckBox",
+	"dijit/form/TextBox",
+	"dijit/form/NumberSpinner",
+	"dijit/form/NumberTextBox",
+	"dijit/form/CurrencyTextBox",
+	"dijit/form/HorizontalSlider",
+	"dijit/Editor",
+	"../util",
+	"./_base"
+], function(dojo, dojox, declare, array, lang, json, connect, has, dom, domAttr, domConstruct,
+	domGeometry, ItemFileReadStore, DateTextBox, TimeTextBox, ComboBox, CheckBox, TextBox,
+	NumberSpinner, NumberTextBox, CurrencyTextBox, HorizontalSlider, 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.
-
-dojo.require("dijit.form.DateTextBox");
-dojo.require("dijit.form.TimeTextBox");
-dojo.require("dijit.form.ComboBox");
-dojo.require("dojo.data.ItemFileReadStore");
-dojo.require("dijit.form.CheckBox");
-dojo.require("dijit.form.TextBox");
-dojo.require("dijit.form.NumberSpinner");
-dojo.require("dijit.form.NumberTextBox");
-dojo.require("dijit.form.CurrencyTextBox");
-dojo.require("dijit.form.HorizontalSlider");
-dojo.require("dijit.Editor");
-
-(function(){
-	var dgc = dojox.grid.cells;
-	dojo.declare("dojox.grid.cells._Widget", dgc._Base, {
-		widgetClass: dijit.form.TextBox,
+	
+	var _Widget = declare("dojox.grid.cells._Widget", BaseCell, {
+		widgetClass: TextBox,
 		constructor: function(inCell){
 			this.widget = null;
 			if(typeof this.widgetClass == "string"){
 				dojo.deprecated("Passing a string to widgetClass is deprecated", "pass the widget class object instead", "2.0");
-				this.widgetClass = dojo.getObject(this.widgetClass);
+				this.widgetClass = lang.getObject(this.widgetClass);
 			}
 		},
 		formatEditing: function(inDatum, inRowIndex){
@@ -35,8 +47,13 @@ dojo.require("dijit.Editor");
 		getValue: function(inRowIndex){
 			return this.widget.get('value');
 		},
+		_unescapeHTML: function(value){
+			return (value && value.replace && this.grid.escapeHTMLInData) ? 
+					value.replace(/</g, '<').replace(/&/g, '&') : value;
+		},
 		setValue: function(inRowIndex, inValue){
 			if(this.widget&&this.widget.set){
+				inValue = this._unescapeHTML(inValue);
 				//Look for lazy-loading editor and handle it via its deferred.
 				if(this.widget.onLoadDeferred){
 					var self = this;
@@ -51,15 +68,15 @@ dojo.require("dijit.Editor");
 			}
 		},
 		getWidgetProps: function(inDatum){
-			return dojo.mixin(
+			return lang.mixin(
 				{
 					dir: this.dir,
 					lang: this.lang
 				},
 				this.widgetProps||{},
 				{
-					constraints: dojo.mixin({}, this.constraint) || {}, //TODO: really just for ValidationTextBoxes
-					value: inDatum
+					constraints: lang.mixin({}, this.constraint) || {}, //TODO: really just for ValidationTextBoxes
+					value: this._unescapeHTML(inDatum)
 				}
 			);
 		},
@@ -93,45 +110,44 @@ dojo.require("dijit.Editor");
 		},
 		focus: function(inRowIndex, inNode){
 			if(this.widget){
-				setTimeout(dojo.hitch(this.widget, function(){
-					dojox.grid.util.fire(this, "focus");
+				setTimeout(lang.hitch(this.widget, function(){
+					util.fire(this, "focus");
 				}), 0);
 			}
 		},
 		_finish: function(inRowIndex){
 			this.inherited(arguments);
-			dojox.grid.util.removeNode(this.widget.domNode);
-			if(dojo.isIE){
-				dojo.setSelectable(this.widget.domNode, true);
+			util.removeNode(this.widget.domNode);
+			if(has('ie')){
+				dom.setSelectable(this.widget.domNode, true);
 			}
 		}
 	});
-	dgc._Widget.markupFactory = function(node, cell){
-		dgc._Base.markupFactory(node, cell);
-		var d = dojo;
-		var widgetProps = d.trim(d.attr(node, "widgetProps")||"");
-		var constraint = d.trim(d.attr(node, "constraint")||"");
-		var widgetClass = d.trim(d.attr(node, "widgetClass")||"");
+	_Widget.markupFactory = function(node, cell){
+		BaseCell.markupFactory(node, cell);
+		var widgetProps = lang.trim(domAttr.get(node, "widgetProps")||"");
+		var constraint = lang.trim(domAttr.get(node, "constraint")||"");
+		var widgetClass = lang.trim(domAttr.get(node, "widgetClass")||"");
 		if(widgetProps){
-			cell.widgetProps = d.fromJson(widgetProps);
+			cell.widgetProps = json.fromJson(widgetProps);
 		}
 		if(constraint){
-			cell.constraint = d.fromJson(constraint);
+			cell.constraint = json.fromJson(constraint);
 		}
 		if(widgetClass){
-			cell.widgetClass = d.getObject(widgetClass);
+			cell.widgetClass = lang.getObject(widgetClass);
 		}
 	};
 
-	dojo.declare("dojox.grid.cells.ComboBox", dgc._Widget, {
-		widgetClass: dijit.form.ComboBox,
+	var ComboBox = declare("dojox.grid.cells.ComboBox", _Widget, {
+		widgetClass: ComboBox,
 		getWidgetProps: function(inDatum){
 			var items=[];
-			dojo.forEach(this.options, function(o){
+			array.forEach(this.options, function(o){
 				items.push({name: o, value: o});
 			});
-			var store = new dojo.data.ItemFileReadStore({data: {identifier:"name", items: items}});
-			return dojo.mixin({}, this.widgetProps||{}, {
+			var store = new ItemFileReadStore({data: {identifier:"name", items: items}});
+			return lang.mixin({}, this.widgetProps||{}, {
 				value: inDatum,
 				store: store
 			});
@@ -143,10 +159,9 @@ dojo.require("dijit.Editor");
 			return e.get('value');
 		}
 	});
-	dgc.ComboBox.markupFactory = function(node, cell){
-		dgc._Widget.markupFactory(node, cell);
-		var d=dojo;
-		var options = d.trim(d.attr(node, "options")||"");
+	ComboBox.markupFactory = function(node, cell){
+		_Widget.markupFactory(node, cell);
+		var options = lang.trim(domAttr.get(node, "options")||"");
 		if(options){
 			var o = options.split(',');
 			if(o[0] != options){
@@ -155,8 +170,8 @@ dojo.require("dijit.Editor");
 		}
 	};
 
-	dojo.declare("dojox.grid.cells.DateTextBox", dgc._Widget, {
-		widgetClass: dijit.form.DateTextBox,
+	var DateTextBox = declare("dojox.grid.cells.DateTextBox", _Widget, {
+		widgetClass: DateTextBox,
 		setValue: function(inRowIndex, inValue){
 			if(this.widget){
 				this.widget.set('value', new Date(inValue));
@@ -165,17 +180,17 @@ dojo.require("dijit.Editor");
 			}
 		},
 		getWidgetProps: function(inDatum){
-			return dojo.mixin(this.inherited(arguments), {
+			return lang.mixin(this.inherited(arguments), {
 				value: new Date(inDatum)
 			});
 		}
 	});
-	dgc.DateTextBox.markupFactory = function(node, cell){
-		dgc._Widget.markupFactory(node, cell);
+	DateTextBox.markupFactory = function(node, cell){
+		_Widget.markupFactory(node, cell);
 	};
 
-	dojo.declare("dojox.grid.cells.CheckBox", dgc._Widget, {
-		widgetClass: dijit.form.CheckBox,
+	var CheckBox = declare("dojox.grid.cells.CheckBox", _Widget, {
+		widgetClass: CheckBox,
 		getValue: function(){
 			return this.widget.checked;
 		},
@@ -190,32 +205,32 @@ dojo.require("dijit.Editor");
 			return;
 		}
 	});
-	dgc.CheckBox.markupFactory = function(node, cell){
-		dgc._Widget.markupFactory(node, cell);
+	CheckBox.markupFactory = function(node, cell){
+		_Widget.markupFactory(node, cell);
 	};
 
-	dojo.declare("dojox.grid.cells.Editor", dgc._Widget, {
-		widgetClass: dijit.Editor,
+	var Editor = declare("dojox.grid.cells.Editor", _Widget, {
+		widgetClass: Editor,
 		getWidgetProps: function(inDatum){
-			return dojo.mixin({}, this.widgetProps||{}, {
+			return lang.mixin({}, this.widgetProps||{}, {
 				height: this.widgetHeight || "100px"
 			});
 		},
 		createWidget: function(inNode, inDatum, inRowIndex){
 			// widget needs its value set after creation
 			var widget = new this.widgetClass(this.getWidgetProps(inDatum), inNode);
-			dojo.connect(widget, 'onLoad', dojo.hitch(this, 'populateEditor'));
+			connect.connect(widget, 'onLoad', lang.hitch(this, 'populateEditor'));
 			return widget;
 		},
 		formatNode: function(inNode, inDatum, inRowIndex){
 			this.content = inDatum;
 			this.inherited(arguments);
-			if(dojo.isMoz){
+			if(has('mozilla')){
 				// FIXME: seem to need to reopen the editor and display the toolbar
 				var e = this.widget;
 				e.open();
 				if(this.widgetToolbar){
-					dojo.place(e.toolbar.domNode, e.editingArea, "before");
+					domConstruct.place(e.toolbar.domNode, e.editingArea, "before");
 				}
 			}
 		},
@@ -224,10 +239,9 @@ dojo.require("dijit.Editor");
 			this.widget.placeCursorAtEnd();
 		}
 	});
-	dgc.Editor.markupFactory = function(node, cell){
-		dgc._Widget.markupFactory(node, cell);
-		var d = dojo;
-		var h = dojo.trim(dojo.attr(node, "widgetHeight")||"");
+	Editor.markupFactory = function(node, cell){
+		_Widget.markupFactory(node, cell);
+		var h = lang.trim(domAttr.get(node, "widgetHeight")||"");
 		if(h){
 			if((h != "auto")&&(h.substr(-2) != "em")){
 				h = parseInt(h, 10)+"px";
@@ -235,4 +249,7 @@ dojo.require("dijit.Editor");
 			cell.widgetHeight = h;
 		}
 	};
-})();
+
+	return dojox.grid.cells.dijit;
+
+});
\ No newline at end of file
diff --git a/dojox/grid/cells/tree.js b/dojox/grid/cells/tree.js
index 19a5118..cc26702 100644
--- a/dojox/grid/cells/tree.js
+++ b/dojox/grid/cells/tree.js
@@ -1,6 +1,9 @@
-dojo.provide("dojox.grid.cells.tree");
-
-dojo.require("dojox.grid.cells");
+define([
+	"dojo/_base/kernel",
+	"../../main",
+	"dojo/_base/lang",
+	"../cells"
+], function(dojo, dojox, lang){
 
 dojox.grid.cells.TreeCell = {
 	formatAggregate: function(inItem, level, inRowIndexes){
@@ -30,7 +33,7 @@ dojox.grid.cells.TreeCell = {
 		return this.openStates[itemId];
 	},
 	formatAtLevel: function(inRowIndexes, inItem, level, summaryRow, toggleClass, cellClasses){
-		if(!dojo.isArray(inRowIndexes)){
+		if(!lang.isArray(inRowIndexes)){
 			inRowIndexes = [inRowIndexes];
 		}
 		var result = "";
@@ -51,7 +54,7 @@ dojox.grid.cells.TreeCell = {
 					id = store.getIdentity(inItem);
 				}
 				cellClasses.push("dojoxGridExpandoCell");
-				ret = '<span dojoType="dojox.grid._Expando" level="' + level + '" class="dojoxGridExpando"' +
+				ret = '<span ' + dojo._scopeName + 'Type="dojox.grid._Expando" level="' + level + '" class="dojoxGridExpando"' +
 						'" toggleClass="' + toggleClass + '" itemId="' + id + '" cellIdx="' + this.index + '"></span>';
 			}
 			result = ret + this.formatIndexes(inRowIndexes, inItem);
@@ -65,3 +68,7 @@ dojox.grid.cells.TreeCell = {
 		return result;
 	}
 };
+
+return dojox.grid.cells.TreeCell;
+
+});
\ No newline at end of file
diff --git a/dojox/grid/enhanced/_Events.js b/dojox/grid/enhanced/_Events.js
index e5fd1c5..b0b31ae 100644
--- a/dojox/grid/enhanced/_Events.js
+++ b/dojox/grid/enhanced/_Events.js
@@ -1,6 +1,13 @@
-dojo.provide("dojox.grid.enhanced._Events");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/keys",
+	"dojo/_base/html",
+	"dojo/_base/event",
+	"dojox/grid/_Events"
+], function(dojo, declare, keys, html, event, _Events){
 
-dojo.declare("dojox.grid.enhanced._Events", null, {
+return declare("dojox.grid.enhanced._Events", null, {
 	// summary:
 	//		Overwrite some default events of DataGrid
 	//
@@ -25,14 +32,8 @@ dojo.declare("dojox.grid.enhanced._Events", null, {
 	rowActiveClass: 'dojoxGridRowActive',
 
 	constructor: function(inGrid){
-		//get the default Grid events
-		this._events = new dojox.grid._Events();
-		//for methods that won't be overwritten, copy them to "this" scope
-		for(var p in this._events){
-			if(!this[p]){
-				this.p = this._events.p;
-			}
-		}
+		//TODO - extend dojox.grid._Events rather than mixin for 1.8
+		this._events = new _Events();
 		//mixin "this" to Grid
 		inGrid.mixin(inGrid, this);
 	},
@@ -47,24 +48,26 @@ dojo.declare("dojox.grid.enhanced._Events", null, {
 		// summary:
 		//		Overwritten, see dojox.grid._Events.onKeyDown();
 		if(e.altKey || e.metaKey){ return; }
-		var dk = dojo.keys;
 		var focus = this.focus;
+		var editing = this.edit.isEditing();
 		switch(e.keyCode){
-			case dk.TAB:
+			case keys.TAB:
 				if(e.ctrlKey){ return; }
 				focus.tab(e.shiftKey ? -1:1,e);
 				break;
-			case dk.UP_ARROW:
-			case dk.DOWN_ARROW:
-				focus.currentArea().move(e.keyCode == dk.UP_ARROW ? -1 : 1, 0, e);
+			case keys.UP_ARROW:
+			case keys.DOWN_ARROW:
+				if(editing){ return; }
+				focus.currentArea().move(e.keyCode == keys.UP_ARROW ? -1 : 1, 0, e);
 				break;
-			case dk.LEFT_ARROW:
-			case dk.RIGHT_ARROW:
-				var offset = (e.keyCode == dk.LEFT_ARROW) ? 1 : -1;
-				if(dojo._isBodyLtr()){ offset *= -1; }
+			case keys.LEFT_ARROW:
+			case keys.RIGHT_ARROW:
+				if(editing){ return; }
+				var offset = (e.keyCode == keys.LEFT_ARROW) ? 1 : -1;
+				if(html._isBodyLtr()){ offset *= -1; }
 				focus.currentArea().move(0, offset, e);
 				break;
-			case dk.F10:
+			case keys.F10:
 				if(this.menus && e.shiftKey){
 					this.onRowContextMenu(e);
 				}
@@ -98,16 +101,16 @@ dojo.declare("dojox.grid.enhanced._Events", null, {
 	onCellMouseDown: function(e){
 		// summary:
 		//		Overwritten, see dojox.grid._Events.onCellMouseDown()
-		dojo.addClass(e.cellNode, this.cellActiveClass);
-		dojo.addClass(e.rowNode, this.rowActiveClass);
+		html.addClass(e.cellNode, this.cellActiveClass);
+		html.addClass(e.rowNode, this.rowActiveClass);
 	},
 	onCellMouseUp: function(e){
 		// summary:
 		//		New - Event fired when mouse is up inside content cell.
 		// e: Event
 		//		Decorated event object that contains reference to grid, cell, and rowIndex
-		dojo.removeClass(e.cellNode, this.cellActiveClass);
-		dojo.removeClass(e.rowNode, this.rowActiveClass);
+		html.removeClass(e.cellNode, this.cellActiveClass);
+		html.removeClass(e.rowNode, this.rowActiveClass);
 	},
 	onCellClick: function(e){
 		// summary:
@@ -127,14 +130,12 @@ dojo.declare("dojox.grid.enhanced._Events", null, {
 		}
 		//invoke dojox.grid._Events.onCellDblClick()
 		this._events.onCellDblClick.call(this, e);
-		//now focus.setFocusCell need isEditing info, so call it after that is set.
-		//this.focus.setFocusCell(e.cell, e.rowIndex);
 	},
 	onRowClick: function(e){
 		// summary:
 		//		Overwritten, see dojox.grid._Events.onRowClick()
 		this.edit.rowClick(e);
-		if(!e.cell || (!e.cell.isRowSelector && (!this.rowSelectCell || !this.rowSelectCell.disabled(e.rowIndex)))){
+		if(!e.cell || !this.plugin('indirectSelection')){
 			this.selection.clickSelectEvent(e);
 		}
 	},
@@ -154,34 +155,34 @@ dojo.declare("dojox.grid.enhanced._Events", null, {
 		if(this.selectedRegionMenu){
 			this.selectedRegionMenu._openMyself({
 				target: e.target,
-				coords: e.keyCode !== dojo.keys.F10 && "pageX" in e ? {
+				coords: e.keyCode !== keys.F10 && "pageX" in e ? {
 					x: e.pageX,
 					y: e.pageY
 				} : null
 			});
-			dojo.stopEvent(e);
+			event.stop(e);
 		}
 	},
 	onHeaderCellMouseOut: function(e){
 		// summary:
 		//		Overwritten, see dojox.grid._Events.onHeaderCellMouseOut()
 		if(e.cellNode){
-			dojo.removeClass(e.cellNode, this.cellOverClass);
-			dojo.removeClass(e.cellNode, this.headerCellActiveClass);
+			html.removeClass(e.cellNode, this.cellOverClass);
+			html.removeClass(e.cellNode, this.headerCellActiveClass);
 		}
 	},
 	onHeaderCellMouseDown: function(e){
 		// summary:
 		//		Overwritten, see dojox.grid._Events.onHeaderCellMouseDown()
 		if(e.cellNode){//TBD - apply to selection region for nested sorting?
-			dojo.addClass(e.cellNode, this.headerCellActiveClass);
+			html.addClass(e.cellNode, this.headerCellActiveClass);
 		}
 	},
 	onHeaderCellMouseUp: function(e){
 		// summary:
 		//		New event
 		if(e.cellNode){
-			dojo.removeClass(e.cellNode, this.headerCellActiveClass);
+			html.removeClass(e.cellNode, this.headerCellActiveClass);
 		}
 	},
 	onHeaderCellClick: function(e){
@@ -209,4 +210,5 @@ dojo.declare("dojox.grid.enhanced._Events", null, {
 		}
 	},
 	onRowMouseUp: function(e){}
+});
 });
\ No newline at end of file
diff --git a/dojox/grid/enhanced/_FocusManager.js b/dojox/grid/enhanced/_FocusManager.js
index e7b519e..bb417d4 100644
--- a/dojox/grid/enhanced/_FocusManager.js
+++ b/dojox/grid/enhanced/_FocusManager.js
@@ -1,6 +1,19 @@
-dojo.provide("dojox.grid.enhanced._FocusManager");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/event",
+	"dojo/_base/sniff",
+	"dojo/_base/html",
+	"dojo/keys",
+	"dijit/a11y",
+	"dijit/focus",
+	"../_FocusManager"
+], function(dojo, lang, declare, array, connect, event, has, html, keys, dijitA11y, dijitFocus, _FocusManager){
 
-dojo.declare("dojox.grid.enhanced._FocusArea",null,{
+var _FocusArea = declare("dojox.grid.enhanced._FocusArea", null, {
 	// summary:
 	//		This is a friend class of _FocusManager
 /*=====
@@ -69,7 +82,7 @@ dojo.declare("dojox.grid.enhanced._FocusArea",null,{
 		area.onMove = area.onMove || dummy;
 		area.onKeyUp = area.onKeyUp || dummy;
 		area.onKeyDown = area.onKeyDown || dummy;
-		dojo.mixin(this, area);
+		lang.mixin(this, area);
 	},
 	move: function(rowStep, colStep, evt){
 		if(this.name){
@@ -111,11 +124,12 @@ dojo.declare("dojox.grid.enhanced._FocusArea",null,{
 		return 0;
 	}
 });
-dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
+
+return declare("dojox.grid.enhanced._FocusManager", _FocusManager, {
 	_stopEvent: function(evt){
 		try{
 			if(evt && evt.preventDefault){
-				dojo.stopEvent(evt);
+				event.stop(evt);
 			}
 		}catch(e){}
 	},
@@ -128,32 +142,32 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 		this._headerMouseEventHandlers = [];
 		this._currentAreaIdx = -1;
 		this._gridBlured = true;
-		this._connects.push(dojo.connect(grid, "onBlur", this, "_doBlur"));
-		this._connects.push(dojo.connect(grid.scroller, "renderPage", this, "_delayedCellFocus"));
+		this._connects.push(connect.connect(grid, "onBlur", this, "_doBlur"));
+		this._connects.push(connect.connect(grid.scroller, "renderPage", this, "_delayedCellFocus"));
 		
 		this.addArea({
 			name: "header",
-			onFocus: dojo.hitch(this, this.focusHeader),
-			onBlur: dojo.hitch(this, this._blurHeader),
-			onMove: dojo.hitch(this, this._navHeader),
-			getRegions: dojo.hitch(this, this._findHeaderCells),
-			onRegionFocus: dojo.hitch(this, this.doColHeaderFocus),
-			onRegionBlur: dojo.hitch(this, this.doColHeaderBlur),
-			onKeyDown: dojo.hitch(this, this._onHeaderKeyDown)
+			onFocus: lang.hitch(this, this.focusHeader),
+			onBlur: lang.hitch(this, this._blurHeader),
+			onMove: lang.hitch(this, this._navHeader),
+			getRegions: lang.hitch(this, this._findHeaderCells),
+			onRegionFocus: lang.hitch(this, this.doColHeaderFocus),
+			onRegionBlur: lang.hitch(this, this.doColHeaderBlur),
+			onKeyDown: lang.hitch(this, this._onHeaderKeyDown)
 		});
 		this.addArea({
 			name: "content",
-			onFocus: dojo.hitch(this, this._focusContent),
-			onBlur: dojo.hitch(this, this._blurContent),
-			onMove: dojo.hitch(this, this._navContent),
-			onKeyDown: dojo.hitch(this, this._onContentKeyDown)
+			onFocus: lang.hitch(this, this._focusContent),
+			onBlur: lang.hitch(this, this._blurContent),
+			onMove: lang.hitch(this, this._navContent),
+			onKeyDown: lang.hitch(this, this._onContentKeyDown)
 		});
 		this.addArea({
 			name: "editableCell",
-			onFocus: dojo.hitch(this, this._focusEditableCell),
-			onBlur: dojo.hitch(this, this._blurEditableCell),
-			onKeyDown: dojo.hitch(this, this._onEditableCellKeyDown),
-			onContentMouseEvent: dojo.hitch(this, this._onEditableCellMouseEvent),
+			onFocus: lang.hitch(this, this._focusEditableCell),
+			onBlur: lang.hitch(this, this._blurEditableCell),
+			onKeyDown: lang.hitch(this, this._onEditableCellKeyDown),
+			onContentMouseEvent: lang.hitch(this, this._onEditableCellMouseEvent),
 			contentMouseEventPlanner: function(evt, areas){ return -1; }
 		});
 		this.placeArea("header");
@@ -164,7 +178,7 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 	destroy: function(){
 		for(var name in this._areas){
 			var area = this._areas[name];
-			dojo.forEach(area._connects, dojo.disconnect);
+			array.forEach(area._connects, connect.disconnect);
 			area._connects = null;
 			if(area.uninitialize){
 				area.uninitialize();
@@ -173,12 +187,12 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 		this.inherited(arguments);
 	},
 	addArea: function(area){
-		if(area.name && dojo.isString(area.name)){
+		if(area.name && lang.isString(area.name)){
 			if(this._areas[area.name]){
 				//Just replace the original area, instead of remove it, so the position does not change.
-				dojo.forEach(area._connects, dojo.disconnect);
+				array.forEach(area._connects, connect.disconnect);
 			}
-			this._areas[area.name] = new dojox.grid.enhanced._FocusArea(area, this);
+			this._areas[area.name] = new _FocusArea(area, this);
 			if(area.onHeaderMouseEvent){
 				this._headerMouseEventHandlers.push(area.name);
 			}
@@ -192,23 +206,23 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 	},
 	_bindAreaEvents: function(){
 		var area, hdl, areas = this._areas;
-		dojo.forEach(this._areaQueue, function(name){
+		array.forEach(this._areaQueue, function(name){
 			area = areas[name];
-			if(!area._initialized && dojo.isFunction(area.initialize)){
+			if(!area._initialized && lang.isFunction(area.initialize)){
 				area.initialize();
 				area._initialized = true;
 			}
 			if(area.getRegions){
 				area._regions = area.getRegions() || [];
-				dojo.forEach(area._connects || [], dojo.disconnect);
+				array.forEach(area._connects || [], connect.disconnect);
 				area._connects = [];
-				dojo.forEach(area._regions, function(r){
+				array.forEach(area._regions, function(r){
 					if(area.onRegionFocus){
-						hdl = dojo.connect(r, "onfocus", area.onRegionFocus);
+						hdl = connect.connect(r, "onfocus", area.onRegionFocus);
 						area._connects.push(hdl);
 					}
 					if(area.onRegionBlur){
-						hdl = dojo.connect(r, "onblur", area.onRegionBlur);
+						hdl = connect.connect(r, "onblur", area.onRegionBlur);
 						area._connects.push(hdl);
 					}
 				});
@@ -219,15 +233,15 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 		var area = this._areas[areaName];
 		if(area){
 			this.ignoreArea(areaName);
-			var i = dojo.indexOf(this._contentMouseEventHandlers, areaName);
+			var i = array.indexOf(this._contentMouseEventHandlers, areaName);
 			if(i >= 0){
 				this._contentMouseEventHandlers.splice(i, 1);
 			}
-			i = dojo.indexOf(this._headerMouseEventHandlers, areaName);
+			i = array.indexOf(this._headerMouseEventHandlers, areaName);
 			if(i >= 0){
 				this._headerMouseEventHandlers.splice(i, 1);
 			}
-			dojo.forEach(area._connects, dojo.disconnect);
+			array.forEach(area._connects, connect.disconnect);
 			if(area.uninitialize){
 				area.uninitialize();
 			}
@@ -239,7 +253,7 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 		//		Set current area to the one areaName refers.
 		// areaName: String
 		var idx, cai = this._currentAreaIdx;
-		if(dojo.isString(areaName) && (idx = dojo.indexOf(this._areaQueue, areaName)) >= 0){
+		if(lang.isString(areaName) && (idx = array.indexOf(this._areaQueue, areaName)) >= 0){
 			if(cai != idx){
 				this.tabbingOut = false;
 				if(toBlurOld && cai >= 0 && cai < this._areaQueue.length){
@@ -249,7 +263,7 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 			}
 		}else{
 			return (cai < 0 || cai >= this._areaQueue.length) ?
-				new dojox.grid.enhanced._FocusArea({}, this) :
+				new _FocusArea({}, this) :
 				this._areas[this._areaQueue[this._currentAreaIdx]];
 		}
 		return null;
@@ -261,7 +275,7 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 		//		placeArea("myarea","before"|"after",...)
 		//		placeArea("myarea","below"|"above",...)
 		if(!this._areas[name]){ return; }
-		var idx = dojo.indexOf(this._areaQueue,otherAreaName);
+		var idx = array.indexOf(this._areaQueue,otherAreaName);
 		switch(pos){
 			case "after":
 				if(idx >= 0){ ++idx; }
@@ -290,7 +304,7 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 		}
 	},
 	ignoreArea: function(name){
-		this._areaQueue = dojo.filter(this._areaQueue,function(areaName){
+		this._areaQueue = array.filter(this._areaQueue,function(areaName){
 			return areaName != name;
 		});
 	},
@@ -299,8 +313,8 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 		if(typeof areaId == "number"){
 			idx = areaId < 0 ? this._areaQueue.length + areaId : areaId;
 		}else{
-			idx = dojo.indexOf(this._areaQueue,
-				dojo.isString(areaId) ? areaId : (areaId && areaId.name));
+			idx = array.indexOf(this._areaQueue,
+				lang.isString(areaId) ? areaId : (areaId && areaId.name));
 		}
 		if(idx < 0){ idx = 0; }
 		var step = idx - this._currentAreaIdx;
@@ -326,8 +340,8 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 			var nextArea = this._areas[this._areaQueue[cai]].onBlur(evt,step);
 			if(nextArea === true){
 				cai = (this._currentAreaIdx += step);
-			}else if(dojo.isString(nextArea) && this._areas[nextArea]){
-				cai = this._currentAreaIdx = dojo.indexOf(this._areaQueue,nextArea);
+			}else if(lang.isString(nextArea) && this._areas[nextArea]){
+				cai = this._currentAreaIdx = array.indexOf(this._areaQueue,nextArea);
 			}
 		}
 		//console.log("target area:",cai);
@@ -342,16 +356,16 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 		this.tabbingOut = true;
 		if(step < 0){
 			this._currentAreaIdx = -1;
-			dijit.focus(this.grid.domNode);
+			dijitFocus.focus(this.grid.domNode);
 		}else{
 			this._currentAreaIdx = this._areaQueue.length;
-			dijit.focus(this.grid.lastFocusNode);
+			dijitFocus.focus(this.grid.lastFocusNode);
 		}
 	},
 	_onMouseEvent: function(type, evt){
 		var lowercase = type.toLowerCase(),
 			handlers = this["_" + lowercase + "MouseEventHandlers"],
-			res = dojo.map(handlers, function(areaName){
+			res = array.map(handlers, function(areaName){
 				return {
 					"area": areaName,
 					"idx": this._areas[areaName][lowercase + "MouseEventPlanner"](evt, handlers)
@@ -359,7 +373,7 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 			}, this).sort(function(a, b){
 				return b.idx - a.idx;
 			}),
-			resHandlers = dojo.map(res, function(handler){
+			resHandlers = array.map(res, function(handler){
 				return res.area;
 			}),
 			i = res.length;
@@ -430,7 +444,7 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 		}else{
 			this.tabbingOut = false;
 		}
-		dojo.stopEvent(e);
+		event.stop(e);
 	},
 	_doBlur: function(){
 		this._gridBlured = true;
@@ -471,8 +485,8 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 		//		Overwritten
 		var didFocus = false;
 		this.inherited(arguments);
-		if(this._colHeadNode && dojo.style(this._colHeadNode, 'display') != "none"){
-			dijit.focus(this._colHeadNode);
+		if(this._colHeadNode && html.style(this._colHeadNode, 'display') != "none"){
+			dijitFocus.focus(this._colHeadNode);
 			this._stopEvent(evt);
 			didFocus = true;
 		}
@@ -482,9 +496,9 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 		// summary:
 		//		Overwritten
 		if(this._colHeadNode){
-			dojo.removeClass(this._colHeadNode, this.focusClass);
+			html.removeClass(this._colHeadNode, this.focusClass);
 		}
-		dojo.removeAttr(this.grid.domNode,"aria-activedescendant");
+		html.removeAttr(this.grid.domNode,"aria-activedescendant");
 		// reset contextMenu onto viewsHeaderNode so right mouse on header will invoke (see focusHeader)
 		this._changeMenuBindNode(this.grid.domNode,this.grid.viewsHeaderNode);
 		//moved here from nextKey
@@ -493,7 +507,7 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 	},
 	_navHeader: function(rowStep, colStep, evt){
 		var colDir = colStep < 0 ? -1 : 1,
-			savedIdx = dojo.indexOf(this._findHeaderCells(), this._colHeadNode);
+			savedIdx = array.indexOf(this._findHeaderCells(), this._colHeadNode);
 		if(savedIdx >= 0 && (evt.shiftKey && evt.ctrlKey)){
 			this.colSizeAdjust(evt, savedIdx, colDir * 5);
 			return;
@@ -502,14 +516,14 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 	},
 	_onHeaderKeyDown: function(e, isBubble){
 		if(isBubble){
-			var dk = dojo.keys;
+			var dk = keys;
 			switch(e.keyCode){
 				case dk.ENTER:
 				case dk.SPACE:
 					var colIdx = this.getHeaderIndex();
 					if(colIdx >= 0 && !this.grid.pluginMgr.isFixedCell(e.cell)/*TODO*/){
 						this.grid.setSortIndex(colIdx, null, e);
-						dojo.stopEvent(e);
+						event.stop(e);
 					}
 					break;
 			}
@@ -521,7 +535,7 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 		//		Overwritten
 		this.inherited(arguments);
 		//EDG now will decorate event on header key events, if no focus, the cell will be wrong
-		dijit.focus(this._colHeadNode);
+		dijitFocus.focus(this._colHeadNode);
 	},
 	//---------------Content Area------------------------------------------
 	findAndFocusGridCell: function(){
@@ -562,20 +576,20 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 		this._colHeadNode = null;
 		this.move(rowStep, colStep, evt);
 		if(evt){
-			dojo.stopEvent(evt);
+			event.stop(evt);
 		}
 	},
 	_onContentKeyDown: function(e, isBubble){
 		if(isBubble){
-			var dk = dojo.keys, s = this.grid.scroller;
+			var dk = keys, s = this.grid.scroller;
 			switch(e.keyCode){
 				case dk.ENTER:
 				case dk.SPACE:
 					var g = this.grid;
 					if(g.indirectSelection){ break; }
-					g.selection.clickSelect(this.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+					g.selection.clickSelect(this.rowIndex, connect.isCopyKey(e), e.shiftKey);
 					g.onRowClick(e);
-					dojo.stopEvent(e);
+					event.stop(e);
 					break;
 				case dk.PAGE_UP:
 					if(this.rowIndex !== 0){
@@ -585,19 +599,19 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 							this.grid.setScrollTop(s.findScrollTop(this.rowIndex - 1));
 							this._navContent(s.firstVisibleRow - s.lastVisibleRow + 1, 0);
 						}
-						dojo.stopEvent(e);
+						event.stop(e);
 					}
 					break;
 				case dk.PAGE_DOWN:
 					if(this.rowIndex + 1 != this.grid.rowCount){
-						dojo.stopEvent(e);
+						event.stop(e);
 						if(this.rowIndex != s.lastVisibleRow - 1){
 							this._navContent(s.lastVisibleRow - this.rowIndex - 1, 0);
 						}else{
 							this.grid.setScrollTop(s.findScrollTop(this.rowIndex + 1));
 							this._navContent(s.lastVisibleRow - s.firstVisibleRow - 1, 0);
 						}
-						dojo.stopEvent(e);
+						event.stop(e);
 					}
 					break;
 			}
@@ -636,11 +650,12 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 				var elems = this._navElems;
 				var firstElem = elems.lowest || elems.first;
 				var lastElem = elems.last || elems.highest || firstElem;
-				var target = dojo.isIE ? evt.srcElement : evt.target;
+				var target = has('ie') ? evt.srcElement : evt.target;
 				toBlur = target == (step > 0 ? lastElem : firstElem);
 			}
 			if(toBlur){
 				this._isNavigating = false;
+				html.setSelectable(this.cell.getNode(this.rowIndex), false);
 				return "content";
 			}
 			return false;
@@ -673,10 +688,10 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 		return true;
 	},
 	_initNavigatableElems: function(){
-		this._navElems = dijit._getTabNavigable(this.cell.getNode(this.rowIndex));
+		this._navElems = dijitA11y._getTabNavigable(this.cell.getNode(this.rowIndex));
 	},
 	_onEditableCellKeyDown: function(e, isBubble){
-		var dk = dojo.keys,
+		var dk = keys,
 			g = this.grid,
 			edit = g.edit,
 			editApplied = false,
@@ -686,7 +701,7 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 				if(isBubble && edit.isEditing()){
 					this._applyEditableCell();
 					editApplied = true;
-					dojo.stopEvent(e);
+					event.stop(e);
 				}
 				//intentional drop through
 			case dk.SPACE:
@@ -700,8 +715,9 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 						var toFocus = this._navElems.lowest || this._navElems.first;
 						if(toFocus){
 							this._isNavigating = true;
-							dijit.focus(toFocus);
-							dojo.stopEvent(e);
+							html.setSelectable(this.cell.getNode(this.rowIndex), true);
+							dijitFocus.focus(toFocus);
+							event.stop(e);
 							this.currentArea("editableCell", true);
 							break;
 						}
@@ -737,11 +753,12 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 			if(cell && !cell.editable && cell.navigatable){
 				this._initNavigatableElems();
 				if(this._navElems.lowest || this._navElems.first){
-					var target = dojo.isIE ? evt.srcElement : evt.target;
+					var target = has('ie') ? evt.srcElement : evt.target;
 					if(target != cell.getNode(evt.rowIndex)){
 						this._isNavigating = true;
 						this.focusArea("editableCell", evt);
-						dijit.focus(target);
+						html.setSelectable(cell.getNode(evt.rowIndex), true);
+						dijitFocus.focus(target);
 						return false;
 					}
 				}
@@ -753,3 +770,4 @@ dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
 		return true;
 	}
 });
+});
\ No newline at end of file
diff --git a/dojox/grid/enhanced/_Plugin.js b/dojox/grid/enhanced/_Plugin.js
index 6fd68f4..5510739 100644
--- a/dojox/grid/enhanced/_Plugin.js
+++ b/dojox/grid/enhanced/_Plugin.js
@@ -1,7 +1,13 @@
-dojo.provide("dojox.grid.enhanced._Plugin");
-
-dojo.require("dojox.grid.EnhancedGrid");
-dojo.declare("dojox.grid.enhanced._Plugin", null, {
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+    "../EnhancedGrid"
+], function(dojo, lang, declare, array, connect){
+	
+return declare("dojox.grid.enhanced._Plugin", null, {
 	// summary:
 	//		Base class for all plugins.
 	//
@@ -76,7 +82,7 @@ dojo.declare("dojox.grid.enhanced._Plugin", null, {
 		this.option = option;
 		this._connects = [];
 		this._subscribes = [];
-		this.privates = dojo.mixin({},dojox.grid.enhanced._Plugin.prototype);
+		this.privates = lang.mixin({},dojox.grid.enhanced._Plugin.prototype);
 		this.init();
 	},
 	
@@ -97,16 +103,16 @@ dojo.declare("dojox.grid.enhanced._Plugin", null, {
 		//	|	plugin.connect(foo, "bar", function(){
 		//	|		console.debug(this.xxx());//"this" - plugin scope
 		//	|	});
-		var conn = dojo.connect(obj, event, this, method);
+		var conn = connect.connect(obj, event, this, method);
 		this._connects.push(conn);
 		return conn;
 	},
 	disconnect: function(handle){
 		// summary:
 		//		Disconnects handle and removes it from connection list.
-		dojo.some(this._connects, function(conn, i, conns){
+		array.some(this._connects, function(conn, i, conns){
 			if(conn == handle){
-				dojo.disconnect(handle);
+				connect.disconnect(handle);
 				conns.splice(i, 1);
 				return true;
 			}
@@ -124,16 +130,16 @@ dojo.declare("dojox.grid.enhanced._Plugin", null, {
 		//	|	plugin.subscribe("/my/topic", function(v){
 		//	|		console.debug(this.xxx(v));//"this" - plugin scope
 		//	|	});
-		var subscribe = dojo.subscribe(topic, this, method);
+		var subscribe = connect.subscribe(topic, this, method);
 		this._subscribes.push(subscribe);
 		return subscribe;
 	},
 	unsubscribe: function(handle){
 		// summary:
 		//		Un-subscribes handle and removes it from subscriptions list.
-		dojo.some(this._subscribes, function(subscribe, i, subscribes){
+		array.some(this._subscribes, function(subscribe, i, subscribes){
 			if(subscribe == handle){
-				dojo.unsubscribe(handle);
+				connect.unsubscribe(handle);
 				subscribes.splice(i, 1);
 				return true;
 			}
@@ -147,8 +153,8 @@ dojo.declare("dojox.grid.enhanced._Plugin", null, {
 	destroy: function(){
 		// summary:
 		//		Destroy all resources.
-		dojo.forEach(this._connects, dojo.disconnect);
-		dojo.forEach(this._subscribes, dojo.unsubscribe);
+		array.forEach(this._connects, connect.disconnect);
+		array.forEach(this._subscribes, connect.unsubscribe);
 		delete this._connects;
 		delete this._subscribes;
 		delete this.option;
@@ -161,3 +167,5 @@ dojo.declare("dojox.grid.enhanced._Plugin", null, {
 // e.g. for DnD plugin(name:'dnd'):
 // |	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 4537145..ab75d38 100644
--- a/dojox/grid/enhanced/_PluginManager.js
+++ b/dojox/grid/enhanced/_PluginManager.js
@@ -1,16 +1,22 @@
-dojo.provide("dojox.grid.enhanced._PluginManager");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"./_Events",
+	"./_FocusManager",
+	"../util"
+], function(dojo, lang, declare, array, connect, _Events, _FocusManager, util){
 
-dojo.require("dojox.grid.enhanced._Events");
-dojo.require("dojox.grid.enhanced._FocusManager");
-
-dojo.declare("dojox.grid.enhanced._PluginManager", null, {
+var _PluginManager = declare("dojox.grid.enhanced._PluginManager", null, {
 	// summary:
 	//		Singleton plugin manager
 	//
 	// description:
 	//		Plugin manager is responsible for
 	//		1. Loading required plugins
-	//		2. Handling collaboration and dependencies among plugins
+	//		2. Handling collaborat	ion and dependencies among plugins
 	//
 	//      Some plugin dependencies:
 	//		- "columnReordering" attribute won't work when either DnD or Indirect Selections plugin is on.
@@ -35,7 +41,7 @@ dojo.declare("dojox.grid.enhanced._PluginManager", null, {
 		this._connects = [];
 		this._parseProps(this.grid.plugins);
 		
-		inGrid.connect(inGrid, "_setStore", dojo.hitch(this, function(store){
+		inGrid.connect(inGrid, "_setStore", lang.hitch(this, function(store){
 			if(this._store !== store){
 				this.forEach('onSetStore', [store, this._store]);
 				this._store = store;
@@ -50,8 +56,8 @@ dojo.declare("dojox.grid.enhanced._PluginManager", null, {
 		//		Load appropriate plugins before DataGrid.postCreate().
 		//		See EnhancedGrid.postCreate()
 		this.grid.focus.destroy();
-		this.grid.focus = new dojox.grid.enhanced._FocusManager(this.grid);
-		new dojox.grid.enhanced._Events(this.grid);//overwrite some default events of DataGrid
+		this.grid.focus = new _FocusManager(this.grid);
+		new _Events(this.grid);//overwrite some default events of DataGrid
 		this._init(true);
 		this.forEach('onPreInit');
 	},
@@ -61,8 +67,8 @@ dojo.declare("dojox.grid.enhanced._PluginManager", null, {
 		//		See EnhancedGrid.postCreate()
 		this._init(false);
 		
-		dojo.forEach(this.grid.views.views, this._initView, this);
-		this._connects.push(dojo.connect(this.grid.views, 'addView', dojo.hitch(this, this._initView)));
+		array.forEach(this.grid.views.views, this._initView, this);
+		this._connects.push(connect.connect(this.grid.views, 'addView', lang.hitch(this, this._initView)));
 			
 		if(this._plugins.length > 0){
 			var edit = this.grid.edit;
@@ -71,7 +77,7 @@ dojo.declare("dojox.grid.enhanced._PluginManager", null, {
 		this.forEach('onPostInit');
 	},
 	forEach: function(func, args){
-		dojo.forEach(this._plugins, function(p){
+		array.forEach(this._plugins, function(p){
 			if(!p || !p[func]){ return; }
 			p[func].apply(p, args ? args : []);
 		});
@@ -84,7 +90,7 @@ dojo.declare("dojox.grid.enhanced._PluginManager", null, {
 		if(!plugins){ return; }
 		
 		var p, loading = {}, options = this._options, grid = this.grid;
-		var registry = dojox.grid.enhanced._PluginManager.registry;//global plugin registry
+		var registry = _PluginManager.registry;//global plugin registry
 		for(p in plugins){
 			if(plugins[p]){//filter out boolean false e.g. {p:false}
 				this._normalize(p, plugins, registry, loading);
@@ -96,7 +102,7 @@ dojo.declare("dojox.grid.enhanced._PluginManager", null, {
 		}
 		
 		//mixin all plugin properties into Grid
-		dojo.mixin(grid, options);
+		lang.mixin(grid, options);
 	},
 	_normalize: function(p, plugins, registry, loading){
 		// summary:
@@ -118,14 +124,14 @@ dojo.declare("dojox.grid.enhanced._PluginManager", null, {
 		
 		loading[p] = true;
 		//TBD - more strict conditions?
-		options[p] = dojo.mixin({}, registry[p], dojo.isObject(plugins[p]) ? plugins[p] : {});
+		options[p] = lang.mixin({}, registry[p], lang.isObject(plugins[p]) ? plugins[p] : {});
 		
 		var dependencies = options[p]['dependency'];
 		if(dependencies){
-			if(!dojo.isArray(dependencies)){
+			if(!lang.isArray(dependencies)){
 				dependencies = options[p]['dependency'] = [dependencies];
 			}
-			dojo.forEach(dependencies, function(dependency){
+			array.forEach(dependencies, function(dependency){
 				if(!this._normalize(dependency, plugins, registry, loading)){
 					throw new Error('Plugin ' + dependency + ' is required.');
 				}
@@ -161,7 +167,7 @@ dojo.declare("dojox.grid.enhanced._PluginManager", null, {
 		if(plugin){ return plugin; } //return if plugin("name") already existed
 		
 		var dependencies = option['dependency'];
-		dojo.forEach(dependencies, function(dependency){
+		array.forEach(dependencies, function(dependency){
 			if(!this.loadPlugin(dependency)){
 				throw new Error('Plugin ' + dependency + ' is required.');
 			}
@@ -177,8 +183,8 @@ dojo.declare("dojox.grid.enhanced._PluginManager", null, {
 		//		Overwrite several default behavior for each views(including _RowSelector view)
 		if(!view){ return; }
 		//add more events handler - _View
-		dojox.grid.util.funnelEvents(view.contentNode, view, "doContentEvent", ['mouseup', 'mousemove']);
-		dojox.grid.util.funnelEvents(view.headerNode, view, "doHeaderEvent", ['mouseup']);
+		util.funnelEvents(view.contentNode, view, "doContentEvent", ['mouseup', 'mousemove']);
+		util.funnelEvents(view.headerNode, view, "doHeaderEvent", ['mouseup']);
 	},
 	pluginExisted: function(name){
 		// summary:
@@ -207,15 +213,15 @@ dojo.declare("dojox.grid.enhanced._PluginManager", null, {
 	},
 	getPluginClazz: function(clazz){
 		// summary:
-		//		Load target plugin which must be already required (dojo.require(..))
+		//		Load target plugin which must be already required (require(..))
 		// clazz: class | String
 		//		Plugin class
-		if(dojo.isFunction(clazz)){
+		if(lang.isFunction(clazz)){
 			return clazz;//return if it's already a clazz
 		}
 		var errorMsg = 'Please make sure Plugin "' + clazz + '" is existed.';
 		try{
-			var cls = dojo.getObject(clazz);
+			var cls = lang.getObject(clazz);
 			if(!cls){ throw new Error(errorMsg); }
 			return cls;
 		}catch(e){
@@ -236,7 +242,7 @@ dojo.declare("dojox.grid.enhanced._PluginManager", null, {
 	destroy: function(){
 		// summary:
 		//		Destroy all resources
-		dojo.forEach(this._connects, dojo.disconnect);
+		array.forEach(this._connects, connect.disconnect);
 		this.forEach('destroy');
 		if(this.grid.unwrap){
 			this.grid.unwrap();
@@ -247,7 +253,7 @@ dojo.declare("dojox.grid.enhanced._PluginManager", null, {
 	}
 });
 
-dojox.grid.enhanced._PluginManager.registerPlugin = function(clazz, props){
+_PluginManager.registerPlugin = function(clazz, props){
 		// summary:
 		//		Register plugins - TODO, a better way rather than global registry?
 		// clazz: String
@@ -258,7 +264,11 @@ dojox.grid.enhanced._PluginManager.registerPlugin = function(clazz, props){
 		console.warn("Failed to register plugin, class missed!");
 		return;
 	}
-	var cls = dojox.grid.enhanced._PluginManager;
+	var cls = _PluginManager;
 	cls.registry = cls.registry || {};
-	cls.registry[clazz.prototype.name]/*plugin name*/ = dojo.mixin({"class": clazz}, (props ? props : {}));
+	cls.registry[clazz.prototype.name]/*plugin name*/ = lang.mixin({"class": clazz}, (props ? 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 9099ec8..0d36b36 100644
--- a/dojox/grid/enhanced/nls/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/EnhancedGrid.js
@@ -1,11 +1,47 @@
+define({ root:
+//begin v1.x content
 ({
 	singleSort: "Single Sort",
 	nestedSort: "Nested Sort",
-	ascending: "Ascending",
-	descending: "Descending",
+	ascending: "Click to sort Ascending",
+	descending: "Click to sort Descending",
 	sortingState: "${0} - ${1}",
 	unsorted: "Do not sort this column",
 	indirectSelectionRadio: "Row ${0}, single selection, radio box",
 	indirectSelectionCheckBox: "Row ${0}, multiple selection, check box",
 	selectAll: "Select all"
 })
+//end v1.x content
+,
+"ar": true,
+"ca": true,
+"cs": true,
+"da": true,
+"de": true,
+"el": true,
+"es": true,
+"fi": true,
+"fr": true,
+"he": true,
+"hr": true,
+"hu": true,
+"hr": true,
+"it": true,
+"ja": true,
+"kk": 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-tw": true
+});
diff --git a/dojox/grid/enhanced/nls/Filter.js b/dojox/grid/enhanced/nls/Filter.js
index d6ebf6b..bc08970 100644
--- a/dojox/grid/enhanced/nls/Filter.js
+++ b/dojox/grid/enhanced/nls/Filter.js
@@ -1,3 +1,5 @@
+define({ root:
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Clear Filter",
 	"filterDefDialogTitle": "Filter",
@@ -28,7 +30,7 @@
 	"waiRelAll": "Match all of the following rules:",
 	"relationAny": "any rules",
 	"waiRelAny": "Match any of the following rules:",
-	"relationMsgFront": "Match",
+	"relationMsgFront": "Match:",
 	"relationMsgTail": "",
 	"and": "and",
 	"or": "or",
@@ -62,8 +64,8 @@
 	"anycolumn": "any column",
 	"statusTipTitleNoFilter": "Filter Bar",
 	"statusTipTitleHasFilter": "Filter",
-	"statusTipRelPre": "Match",
-	"statusTipRelPost": "rules.",
+	"statusTipRelAny": "Match any rules.",
+	"statusTipRelAll": "Match all rules.",
 	
 	"defaultItemsName": "items",
 	"filterBarMsgHasFilterTemplate": "${0} of ${1} ${2} shown.",
@@ -82,4 +84,37 @@
 	"trueLabel": "True",
 	"falseLabel": "False"
 })
-
+//end v1.x content
+,
+"ar": true,
+"ca": true,
+"cs": true,
+"da": true,
+"de": true,
+"el": true,
+"es": true,
+"fi": true,
+"fr": true,
+"he": true,
+"hr": true,
+"hu": true,
+"hr": true,
+"it": true,
+"ja": true,
+"kk": 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-tw": true
+});
diff --git a/dojox/grid/enhanced/nls/Pagination.js b/dojox/grid/enhanced/nls/Pagination.js
index 7d5bff1..2c693cf 100644
--- a/dojox/grid/enhanced/nls/Pagination.js
+++ b/dojox/grid/enhanced/nls/Pagination.js
@@ -1,3 +1,5 @@
+define({ root:
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} of ${1} ${0}",
 	"firstTip": "First Page",
@@ -5,6 +7,7 @@
 	"nextTip": "Next Page",
 	"prevTip": "Previous Page",
 	"itemTitle": "items",
+	"singularItemTitle": "item",
 	"pageStepLabelTemplate": "Page ${0}",
 	"pageSizeLabelTemplate": "${0} items per page",
 	"allItemsLabelTemplate": "All items",
@@ -13,5 +16,40 @@
 	"dialogIndication": "Specify the page number",
 	"pageCountIndication": " (${0} pages)",
 	"dialogConfirm": "Go",
-	"dialogCancel": "Cancel"
+	"dialogCancel": "Cancel",
+	"all": "All"
 })
+//end v1.x content
+,
+"ar": true,
+"ca": true,
+"cs": true,
+"da": true,
+"de": true,
+"el": true,
+"es": true,
+"fi": true,
+"fr": true,
+"he": true,
+"hr": true,
+"hu": true,
+"hr": true,
+"it": true,
+"ja": true,
+"kk": 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-tw": true
+});
diff --git a/dojox/grid/enhanced/nls/ar/EnhancedGrid.js b/dojox/grid/enhanced/nls/ar/EnhancedGrid.js
index 35401bc..ea856ed 100644
--- a/dojox/grid/enhanced/nls/ar/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/ar/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "فرز منفرد",
 	nestedSort: "فرز متداخل",
@@ -9,4 +11,6 @@
 	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 78132c7..d855c76 100644
--- a/dojox/grid/enhanced/nls/ar/Filter.js
+++ b/dojox/grid/enhanced/nls/ar/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "محو ترشيح البيانات",
 	"filterDefDialogTitle": "ترشيح البيانات",
@@ -62,8 +64,6 @@
 	"anycolumn": "أي عمود",
 	"statusTipTitleNoFilter": "خط ترشيح البيانات",
 	"statusTipTitleHasFilter": "ترشيح البيانات",
-	"statusTipRelPre": "مطابقة",
-	"statusTipRelPost": "قواعد.",
 	
 	"defaultItemsName": "بنود",
 	"filterBarMsgHasFilterTemplate": "يتم عرض ${0} من ${1} ${2}.",
@@ -82,6 +82,8 @@
 	"trueLabel": "متحقق",
 	"falseLabel": "غير متحقق"
 })
+//end v1.x content
+);
 
 
 
diff --git a/dojox/grid/enhanced/nls/ar/Pagination.js b/dojox/grid/enhanced/nls/ar/Pagination.js
index 6e03e28..dd42fce 100644
--- a/dojox/grid/enhanced/nls/ar/Pagination.js
+++ b/dojox/grid/enhanced/nls/ar/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} من ${1} ${0}",
 	"firstTip": "الصفحة الأولى",
@@ -13,6 +15,9 @@
 	"dialogIndication": "حدد رقم الصفحة",
 	"pageCountIndication": " (${0} صفحات)",
 	"dialogConfirm": "بدء",
-	"dialogCancel": "الغاء"
+	"dialogCancel": "الغاء",
+	"all": "كل"
 })
+//end v1.x content
+);
 
diff --git a/dojox/grid/enhanced/nls/ca/EnhancedGrid.js b/dojox/grid/enhanced/nls/ca/EnhancedGrid.js
index 4b72067..5beb6ce 100644
--- a/dojox/grid/enhanced/nls/ca/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/ca/EnhancedGrid.js
@@ -1,8 +1,16 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Ordre únic",
 	nestedSort: "Ordre imbricat",
 	ascending: "Ascendent",
 	descending: "Descendent",
-	unsorted: "No ordenis aquesta finestra"
+	sortingState: "${0} - ${1}",
+	unsorted: "No ordenis aquesta finestra",
+	indirectSelectionRadio: "Fila ${0}, selecció única, quadre d'opció",
+	indirectSelectionCheckBox: "Fila ${0}, selecció múltiple, quadre de selecció",
+	selectAll: "Seleccionar-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 0025e79..a544f9e 100644
--- a/dojox/grid/enhanced/nls/ca/Filter.js
+++ b/dojox/grid/enhanced/nls/ca/Filter.js
@@ -1,7 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Netejar el filtre",
 	"filterDefDialogTitle": "Filtre",
-	"incompleteRuleTip": "Aquesta regla no està completa",
 	"ruleTitleTemplate": "Regla ${0}",
 	
 	"conditionEqual": "igual que",
@@ -21,6 +22,7 @@
 	"conditionBefore": "abans",
 	"conditionAfter": "després",
 	"conditionRange": "interval",
+	"conditionIsEmpty": "és buida",
 	
 	"all": "tot",
 	"any": "qualsevol",
@@ -62,8 +64,8 @@
 	"anycolumn": "qualsevol columna",
 	"statusTipTitleNoFilter": "Barra de filtre",
 	"statusTipTitleHasFilter": "Filtre",
-	"statusTipRelPre": "Coincidència",
-	"statusTipRelPost": "regles.",
+	"statusTipRelAny": "Coincideix amb qualsevol regla.",
+	"statusTipRelAll": "Coincideix amb totes les regles.",
 	
 	"defaultItemsName": "elements",
 	"filterBarMsgHasFilterTemplate": "Es mostren ${0} de ${1} ${2}.",
@@ -79,10 +81,8 @@
 	"clearFilterMsg": "Això eliminarà el filtre i mostrarà tots els registres disponibles.",
 	"anyColumnOption": "Qualsevol columna",
 	
-	"trueLabelEditable": "Seleccionat",
 	"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 d616a0b..e04c5dc 100644
--- a/dojox/grid/enhanced/nls/ca/Pagination.js
+++ b/dojox/grid/enhanced/nls/ca/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} de ${1} ${0}",
 	"firstTip": "Primera pàgina",
@@ -5,6 +7,7 @@
 	"nextTip": "Pàgina següent",
 	"prevTip": "Pàgina anterior",
 	"itemTitle": "elements",
+	"singularItemTitle": "element",
 	"pageStepLabelTemplate": "Pàgina ${0}",
 	"pageSizeLabelTemplate": "${0} elements per pàgina",
 	"allItemsLabelTemplate": "Tots els elements",
@@ -13,6 +16,8 @@
 	"dialogIndication": "Especifiqueu el número de pàgina",
 	"pageCountIndication": " (${0} pàgines)",
 	"dialogConfirm": "Vés-hi",
-	"dialogCancel": "Cancel·la"
+	"dialogCancel": "Cancel·la",
+	"all": "tot"
 })
-
+//end v1.x content
+);
diff --git a/dojox/grid/enhanced/nls/cs/EnhancedGrid.js b/dojox/grid/enhanced/nls/cs/EnhancedGrid.js
index f6db50e..6a2fcb5 100644
--- a/dojox/grid/enhanced/nls/cs/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/cs/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Jednotlivé řazení",
 	nestedSort: "Vnořené řazení",
@@ -9,4 +11,6 @@
 	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 c212c55..ae25317 100644
--- a/dojox/grid/enhanced/nls/cs/Filter.js
+++ b/dojox/grid/enhanced/nls/cs/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Vymazat filtr",
 	"filterDefDialogTitle": "Filtr",
@@ -62,8 +64,8 @@
 	"anycolumn": "jakýkoli sloupec",
 	"statusTipTitleNoFilter": "Panel filtrování",
 	"statusTipTitleHasFilter": "Filtr",
-	"statusTipRelPre": "Shoda",
-	"statusTipRelPost": "pravidla.",
+	"statusTipRelAny": "Vyhovovat libovolnému pravidlu",
+	"statusTipRelAll": "Vyhovovat všem pravidlům",
 	
 	"defaultItemsName": "položek",
 	"filterBarMsgHasFilterTemplate": "${0} z ${1} ${2} zobrazeno.",
@@ -82,6 +84,5 @@
 	"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 18478cc..39f5dc6 100644
--- a/dojox/grid/enhanced/nls/cs/Pagination.js
+++ b/dojox/grid/enhanced/nls/cs/Pagination.js
@@ -1,18 +1,24 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} z ${1} ${0}",
-	"firstTip": "První strana",
-	"lastTip": "Poslední strana",
-	"nextTip": "Další strana",
-	"prevTip": "Předchozí strana",
-	"itemTitle": "položek",
+	"firstTip": "První stránka",
+	"lastTip": "Poslední stránka",
+	"nextTip": "Další stránka",
+	"prevTip": "Předchozí stránka",
+	"itemTitle": "položky",
+	"singularItemTitle": "položka",
 	"pageStepLabelTemplate": "Stránka ${0}",
-	"pageSizeLabelTemplate": "${0} položek na stránce",
+	"pageSizeLabelTemplate": "${0} položek na stránku",
 	"allItemsLabelTemplate": "Všechny položky",
 	"gotoButtonTitle": "Přejít na specifickou stránku",
 	"dialogTitle": "Přejít na stránku",
-	"dialogIndication": "Uveďte číslo stránky",
-	"pageCountIndication": " (${0} stránek)",
+	"dialogIndication": "Uvést číslo stránky",
+	"pageCountIndication": " (${0} stránky)",
 	"dialogConfirm": "Přejít",
-	"dialogCancel": "Storno"
+	"dialogCancel": "Storno",
+	"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 c707b5c..c55db2a 100644
--- a/dojox/grid/enhanced/nls/da/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/da/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Enkelt sortering",
 	nestedSort: "Indlejret sortering",
@@ -9,4 +11,6 @@
 	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 73c0d1c..0f38e3a 100644
--- a/dojox/grid/enhanced/nls/da/Filter.js
+++ b/dojox/grid/enhanced/nls/da/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Ryd filter",
 	"filterDefDialogTitle": "Filter",
@@ -62,8 +64,8 @@
 	"anycolumn": "vilkårlig kolonne",
 	"statusTipTitleNoFilter": "Filterlinje",
 	"statusTipTitleHasFilter": "Filter",
-	"statusTipRelPre": "Match",
-	"statusTipRelPost": "regler.",
+	"statusTipRelAny": "Matcher en hvilken som helst regel.",
+	"statusTipRelAll": "Matcher alle regler.",
 	
 	"defaultItemsName": "elementer",
 	"filterBarMsgHasFilterTemplate": "${0} af ${1} ${2} vist.",
@@ -82,6 +84,5 @@
 	"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 fd139bf..357ed4d 100644
--- a/dojox/grid/enhanced/nls/da/Pagination.js
+++ b/dojox/grid/enhanced/nls/da/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} af ${1} ${0}",
 	"firstTip": "Første side",
@@ -5,6 +7,7 @@
 	"nextTip": "Næste side",
 	"prevTip": "Forrige side",
 	"itemTitle": "elementer",
+	"singularItemTitle": "element",
 	"pageStepLabelTemplate": "Side ${0}",
 	"pageSizeLabelTemplate": "${0} elementer pr. side",
 	"allItemsLabelTemplate": "Alle elementer",
@@ -13,6 +16,8 @@
 	"dialogIndication": "Angiv sidetallet",
 	"pageCountIndication": " (${0} sider)",
 	"dialogConfirm": "Gå",
-	"dialogCancel": "Annullér"
+	"dialogCancel": "Annullér",
+	"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 c36bcfd..4891395 100644
--- a/dojox/grid/enhanced/nls/de/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/de/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Einzelne Sortierung",
 	nestedSort: "Verschachtelte Sortierung",
@@ -9,4 +11,6 @@
 	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 31f6236..76856b4 100644
--- a/dojox/grid/enhanced/nls/de/Filter.js
+++ b/dojox/grid/enhanced/nls/de/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Filter löschen",
 	"filterDefDialogTitle": "Filter",
@@ -62,8 +64,8 @@
 	"anycolumn": "beliebige Spalte",
 	"statusTipTitleNoFilter": "Filterleiste",
 	"statusTipTitleHasFilter": "Filter",
-	"statusTipRelPre": "Übereinstimmung",
-	"statusTipRelPost": "Regeln.",
+	"statusTipRelAny": "Übereinstimmung mit einer oder mehreren beliebigen Regeln.",
+	"statusTipRelAll": "Übereinstimmung mit allen Regeln.",
 	
 	"defaultItemsName": "Elemente",
 	"filterBarMsgHasFilterTemplate": "${0} von ${1} ${2} angezeigt.",
@@ -82,6 +84,5 @@
 	"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 05e0e64..741ce0a 100644
--- a/dojox/grid/enhanced/nls/de/Pagination.js
+++ b/dojox/grid/enhanced/nls/de/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} von ${1} ${0}",
 	"firstTip": "Erste Seite",
@@ -5,14 +7,18 @@
 	"nextTip": "Nächste Seite",
 	"prevTip": "Vorherige Seite",
 	"itemTitle": "Elemente",
+	"singularItemTitle": "Element",
 	"pageStepLabelTemplate": "Seite ${0}",
 	"pageSizeLabelTemplate": "${0} Elemente pro Seite",
 	"allItemsLabelTemplate": "Alle Elemente",
-	"gotoButtonTitle": "Eine bestimmte Seite aufrufen",
-	"dialogTitle": "Zu Seite",
-	"dialogIndication": "Geben Sie die Seitenzahl an.",
+	"gotoButtonTitle": "Bestimmte Seite aufrufen",
+	"dialogTitle": "Seite aufrufen",
+	"dialogIndication": "Seitenzahl angeben",
 	"pageCountIndication": " (${0} Seiten)",
 	"dialogConfirm": "Start",
-	"dialogCancel": "Abbrechen"
+	"dialogCancel": "Abbrechen",
+	"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 272da62..83f27bd 100644
--- a/dojox/grid/enhanced/nls/el/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/el/EnhancedGrid.js
@@ -1,8 +1,16 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Απλή ταξινόμηση",
 	nestedSort: "Ένθετη ταξινόμηση",
 	ascending: "Αύξουσα",
 	descending: "Φθίνουσα",
-	unsorted: "Χωρίς ταξινόμηση αυτής της στήλης"
+	sortingState: "${0} - ${1}",
+	unsorted: "Χωρίς ταξινόμηση αυτής της στήλης",
+	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 4111980..6a7c759 100644
--- a/dojox/grid/enhanced/nls/el/Filter.js
+++ b/dojox/grid/enhanced/nls/el/Filter.js
@@ -1,7 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Εκκαθάριση φίλτρου",
 	"filterDefDialogTitle": "Φίλτρο",
-	"incompleteRuleTip": "Αυτός ο κανόνας δεν είναι πλήρης.",
 	"ruleTitleTemplate": "Κανόνας ${0}",
 	
 	"conditionEqual": "ίσο",
@@ -21,6 +22,7 @@
 	"conditionBefore": "πριν",
 	"conditionAfter": "μετά",
 	"conditionRange": "εύρος",
+	"conditionIsEmpty": "είναι κενό",
 	
 	"all": "όλα",
 	"any": "οποιοδήποτε",
@@ -62,8 +64,8 @@
 	"anycolumn": "οποιαδήποτε στήλη",
 	"statusTipTitleNoFilter": "Γραμμή φίλτρου",
 	"statusTipTitleHasFilter": "Φίλτρο",
-	"statusTipRelPre": "Αντιστοιχία",
-	"statusTipRelPost": "κανόνες.",
+	"statusTipRelAny": "Αντιστοιχία με οποιουσδήποτε κανόνες.",
+	"statusTipRelAll": "Αντιστοιχία με όλους τους κανόνες.",
 	
 	"defaultItemsName": "στοιχεία",
 	"filterBarMsgHasFilterTemplate": "Εμφανίζονται ${0} από ${1} ${2}.",
@@ -79,10 +81,8 @@
 	"clearFilterMsg": "Με την επιλογή αυτή θα αφαιρεθεί το φίλτρο και θα εμφανιστούν όλες οι διαθέσιμες εγγραφές.",
 	"anyColumnOption": "Οποιαδήποτε στήλη",
 	
-	"trueLabelEditable": "Επιλεγμένο",
 	"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 bb4ad80..19110ae 100644
--- a/dojox/grid/enhanced/nls/el/Pagination.js
+++ b/dojox/grid/enhanced/nls/el/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} από ${1} ${0}",
 	"firstTip": "Πρώτη σελίδα",
@@ -5,6 +7,7 @@
 	"nextTip": "Επόμενη σελίδα",
 	"prevTip": "Προηγούμενη σελίδα",
 	"itemTitle": "στοιχεία",
+	"singularItemTitle": "στοιχείο",
 	"pageStepLabelTemplate": "Σελίδα ${0}",
 	"pageSizeLabelTemplate": "${0} στοιχεία ανά σελίδα",
 	"allItemsLabelTemplate": "Όλα τα στοιχεία",
@@ -13,6 +16,8 @@
 	"dialogIndication": "Καθορίστε τον αριθμό της σελίδας",
 	"pageCountIndication": " (${0} σελίδες)",
 	"dialogConfirm": "Μετάβαση",
-	"dialogCancel": "Ακύρωση"
+	"dialogCancel": "Ακύρωση",
+	"all": "όλα"
 })
-
+//end v1.x content
+);
diff --git a/dojox/grid/enhanced/nls/es/EnhancedGrid.js b/dojox/grid/enhanced/nls/es/EnhancedGrid.js
index 38614ca..30deaf9 100644
--- a/dojox/grid/enhanced/nls/es/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/es/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Orden único",
 	nestedSort: "Orden anidado",
@@ -9,4 +11,6 @@
 	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 a858170..e77895f 100644
--- a/dojox/grid/enhanced/nls/es/Filter.js
+++ b/dojox/grid/enhanced/nls/es/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Borrar filtro",
 	"filterDefDialogTitle": "Filtro",
@@ -62,8 +64,8 @@
 	"anycolumn": "cualquier columna",
 	"statusTipTitleNoFilter": "Barra de filtro",
 	"statusTipTitleHasFilter": "Filtro",
-	"statusTipRelPre": "Coincidir",
-	"statusTipRelPost": "reglas.",
+	"statusTipRelAny": "Coincidir con cualquier regla.",
+	"statusTipRelAll": "Coincidir con todas las reglas.",
 	
 	"defaultItemsName": "elementos",
 	"filterBarMsgHasFilterTemplate": "${0} de ${1} ${2} mostrados.",
@@ -82,6 +84,5 @@
 	"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 fb950e5..a284fa9 100644
--- a/dojox/grid/enhanced/nls/es/Pagination.js
+++ b/dojox/grid/enhanced/nls/es/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} de ${1} ${0}",
 	"firstTip": "Primera página",
@@ -5,6 +7,7 @@
 	"nextTip": "Página siguiente",
 	"prevTip": "Página anterior",
 	"itemTitle": "elementos",
+	"singularItemTitle": "elemento",
 	"pageStepLabelTemplate": "Página ${0}",
 	"pageSizeLabelTemplate": "${0} elementos por página",
 	"allItemsLabelTemplate": "Todos los elementos",
@@ -13,6 +16,9 @@
 	"dialogIndication": "Especifique el número de página",
 	"pageCountIndication": " (${0} páginas)",
 	"dialogConfirm": "Ir",
-	"dialogCancel": "Cancelar"
+	"dialogCancel": "Cancelar",
+	"all": "todas"
 })
+//end v1.x content
+);
 
diff --git a/dojox/grid/enhanced/nls/fi/EnhancedGrid.js b/dojox/grid/enhanced/nls/fi/EnhancedGrid.js
index 524eceb..a01e2ba 100644
--- a/dojox/grid/enhanced/nls/fi/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/fi/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Yksinkertainen lajittelu",
 	nestedSort: "Sisäkkäinen lajittelu",
@@ -9,4 +11,6 @@
 	indirectSelectionCheckBox: "Rivi ${0}, monivalinta, 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 2842259..e3c661b 100644
--- a/dojox/grid/enhanced/nls/fi/Filter.js
+++ b/dojox/grid/enhanced/nls/fi/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Tyhjennä suodatin",
 	"filterDefDialogTitle": "Suodatin",
@@ -62,8 +64,8 @@
 	"anycolumn": "mikä tahansa sarake",
 	"statusTipTitleNoFilter": "Suodatinpalkki",
 	"statusTipTitleHasFilter": "Suodatin",
-	"statusTipRelPre": "Vastine",
-	"statusTipRelPost": "säännöt.",
+	"statusTipRelAny": "Vastaa jotakin sääntöä.",
+	"statusTipRelAll": "Vastaa kaikkia sääntöjä.",
 	
 	"defaultItemsName": "nimikkeet",
 	"filterBarMsgHasFilterTemplate": "näkyvissä ${0} / ${1} ${2}.",
@@ -82,6 +84,5 @@
 	"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 8447738..66dd638 100644
--- a/dojox/grid/enhanced/nls/fi/Pagination.js
+++ b/dojox/grid/enhanced/nls/fi/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} / ${1} ${0}",
 	"firstTip": "Ensimmäinen sivu",
@@ -5,6 +7,7 @@
 	"nextTip": "Seuraava sivu",
 	"prevTip": "Edellinen sivu",
 	"itemTitle": "nimikkeet",
+	"singularItemTitle": "kohde",
 	"pageStepLabelTemplate": "Sivu ${0}",
 	"pageSizeLabelTemplate": "${0} nimikettä sivua kohti",
 	"allItemsLabelTemplate": "Kaikki nimikkeet",
@@ -13,6 +16,8 @@
 	"dialogIndication": "Kirjoita sivunumero",
 	"pageCountIndication": " (${0} sivua)",
 	"dialogConfirm": "Siirry",
-	"dialogCancel": "Peruuta"
+	"dialogCancel": "Peruuta",
+	"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 d7c7205..5709bfc 100644
--- a/dojox/grid/enhanced/nls/fr/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/fr/EnhancedGrid.js
@@ -1,4 +1,6 @@
-({
+define(
+//begin v1.x content
+({
 	singleSort: "Tri simple",
 	nestedSort: "Tri imbriqué",
 	ascending: "Croissant",
@@ -9,4 +11,6 @@
 	indirectSelectionCheckBox: "Ligne ${0}, sélection multiple, case à cocher",
 	selectAll: "Tout sélectionner"
 })
+//end v1.x content
+);
 
diff --git a/dojox/grid/enhanced/nls/fr/Filter.js b/dojox/grid/enhanced/nls/fr/Filter.js
index 7b3dcd4..2e2fb9c 100644
--- a/dojox/grid/enhanced/nls/fr/Filter.js
+++ b/dojox/grid/enhanced/nls/fr/Filter.js
@@ -1,4 +1,6 @@
-({
+define(
+//begin v1.x content
+({
 	"clearFilterDialogTitle": "Effacer le filtre",
 	"filterDefDialogTitle": "Filtrer",
 	"ruleTitleTemplate": "Règle ${0}",
@@ -62,8 +64,8 @@
 	"anycolumn": "n'importe quelle colonne",
 	"statusTipTitleNoFilter": "Barre de filtre",
 	"statusTipTitleHasFilter": "Filtrer",
-	"statusTipRelPre": "Satisfaire",
-	"statusTipRelPost": "règles.",
+	"statusTipRelAny": "Répondre à l'une des règles.",
+	"statusTipRelAll": "Réponde à toutes les régles.",
 	
 	"defaultItemsName": "éléments",
 	"filterBarMsgHasFilterTemplate": "${0} sur ${1} ${2} affichés.",
@@ -82,6 +84,5 @@
 	"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 bae2b9d..8fb15fc 100644
--- a/dojox/grid/enhanced/nls/fr/Pagination.js
+++ b/dojox/grid/enhanced/nls/fr/Pagination.js
@@ -1,18 +1,24 @@
+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",
 	"prevTip": "Page précédente",
 	"itemTitle": "éléments",
+	"singularItemTitle": "élément",
 	"pageStepLabelTemplate": "Page ${0}",
 	"pageSizeLabelTemplate": "${0} éléments par page",
 	"allItemsLabelTemplate": "Tous les éléments",
-	"gotoButtonTitle": "Aller à une page donnée",
-	"dialogTitle": "Aller à la page",
+	"gotoButtonTitle": "Accéder à une page spécifique",
+	"dialogTitle": "Accéder à la page",
 	"dialogIndication": "Indiquer le numéro de page",
 	"pageCountIndication": " (${0} pages)",
-	"dialogConfirm": "Aller",
-	"dialogCancel": "Annuler"
+	"dialogConfirm": "Accès",
+	"dialogCancel": "Annuler",
+	"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 db4ed87..970a7cf 100644
--- a/dojox/grid/enhanced/nls/he/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/he/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "מיון יחיד",
 	nestedSort: "מיון מקונן",
@@ -9,4 +11,6 @@
 	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 63fa21a..1724756 100644
--- a/dojox/grid/enhanced/nls/he/Filter.js
+++ b/dojox/grid/enhanced/nls/he/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "ניקוי מסנן",
 	"filterDefDialogTitle": "מסנן",
@@ -62,8 +64,6 @@
 	"anycolumn": "כל עמודה",
 	"statusTipTitleNoFilter": "סרגל סינון",
 	"statusTipTitleHasFilter": "מסנן",
-	"statusTipRelPre": "התאמה",
-	"statusTipRelPost": "כללים.",
 	
 	"defaultItemsName": "פריטים",
 	"filterBarMsgHasFilterTemplate": "מוצג ${0} מתוך ${1} ${2}.",
@@ -82,6 +82,8 @@
 	"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 c7e3d66..5cc0ec2 100644
--- a/dojox/grid/enhanced/nls/he/Pagination.js
+++ b/dojox/grid/enhanced/nls/he/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} מתוך ${1} ${0}",
 	"firstTip": "עמוד ראשון",
@@ -13,6 +15,9 @@
 	"dialogIndication": "ציון מספר העמוד",
 	"pageCountIndication": " (${0} עמודים)",
 	"dialogConfirm": "ביצוע",
-	"dialogCancel": "ביטול"
+	"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 ffc8e0b..d46c1a5 100644
--- a/dojox/grid/enhanced/nls/hr/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/hr/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Jedan sort",
 	nestedSort: "Ugniježđeni sort",
@@ -9,4 +11,6 @@
 	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 58cb3c9..aeb7b95 100644
--- a/dojox/grid/enhanced/nls/hr/Filter.js
+++ b/dojox/grid/enhanced/nls/hr/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Brisanje filtera",
 	"filterDefDialogTitle": "Filter",
@@ -62,8 +64,8 @@
 	"anycolumn": "bilo koji stupac",
 	"statusTipTitleNoFilter": "Traka filtera",
 	"statusTipTitleHasFilter": "Filter",
-	"statusTipRelPre": "Odgovara",
-	"statusTipRelPost": "pravila.",
+	"statusTipRelAny": "Usporedi bilo koja pravila.",
+	"statusTipRelAll": "Usporedi sva pravila.",
 	
 	"defaultItemsName": "stavke",
 	"filterBarMsgHasFilterTemplate": "${0} od ${1} ${2} prikazano.",
@@ -82,6 +84,5 @@
 	"trueLabel": "True",
 	"falseLabel": "False"
 })
-
-
-
+//end v1.x content
+);
diff --git a/dojox/grid/enhanced/nls/hr/Pagination.js b/dojox/grid/enhanced/nls/hr/Pagination.js
index 5205ad0..5248fa1 100644
--- a/dojox/grid/enhanced/nls/hr/Pagination.js
+++ b/dojox/grid/enhanced/nls/hr/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} od ${1} ${0}",
 	"firstTip": "Prva stranica",
@@ -5,6 +7,7 @@
 	"nextTip": "Sljedeća stranica",
 	"prevTip": "Prethodna stranica",
 	"itemTitle": "stavke",
+	"singularItemTitle": "stavka",
 	"pageStepLabelTemplate": "Strana ${0}",
 	"pageSizeLabelTemplate": "${0} stavki po stranici",
 	"allItemsLabelTemplate": "Sve stavke",
@@ -13,6 +16,9 @@
 	"dialogIndication": "Navedite broj stranice",
 	"pageCountIndication": " (${0} stranica)",
 	"dialogConfirm": "Idi",
-	"dialogCancel": "Opoziv"
+	"dialogCancel": "Opoziv",
+	"all": "svi"
 })
+//end v1.x content
+);
 
diff --git a/dojox/grid/enhanced/nls/hu/EnhancedGrid.js b/dojox/grid/enhanced/nls/hu/EnhancedGrid.js
index f20fd41..c260371 100644
--- a/dojox/grid/enhanced/nls/hu/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/hu/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Egyszerű rendezés",
 	nestedSort: "Beágyazott rendezés",
@@ -9,4 +11,6 @@
 	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 babd050..709a238 100644
--- a/dojox/grid/enhanced/nls/hu/Filter.js
+++ b/dojox/grid/enhanced/nls/hu/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Szűrő törlése",
 	"filterDefDialogTitle": "Szűrő",
@@ -62,8 +64,8 @@
 	"anycolumn": "bármely oszlop",
 	"statusTipTitleNoFilter": "Szűrősáv",
 	"statusTipTitleHasFilter": "Szűrő",
-	"statusTipRelPre": "Egyezik",
-	"statusTipRelPost": "szabályok.",
+	"statusTipRelAny": "Bármely szabálynak megfelel.",
+	"statusTipRelAll": "Minden szabálynak megfelel.",
 	
 	"defaultItemsName": "elemek",
 	"filterBarMsgHasFilterTemplate": "${0} / ${1} ${2} megjelenítve.",
@@ -82,6 +84,5 @@
 	"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 367f69f..1cfb2ed 100644
--- a/dojox/grid/enhanced/nls/hu/Pagination.js
+++ b/dojox/grid/enhanced/nls/hu/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} / ${1} ${0}",
 	"firstTip": "Első oldal",
@@ -5,6 +7,7 @@
 	"nextTip": "Következő oldal",
 	"prevTip": "Előző oldal",
 	"itemTitle": "elemek",
+	"singularItemTitle": "elem",
 	"pageStepLabelTemplate": "${0}. oldal",
 	"pageSizeLabelTemplate": "${0} elem oldalanként",
 	"allItemsLabelTemplate": "Összes elem",
@@ -13,6 +16,9 @@
 	"dialogIndication": "Adja meg az oldalszámot",
 	"pageCountIndication": " (${0} oldal)",
 	"dialogConfirm": "Mehet",
-	"dialogCancel": "Mégse"
+	"dialogCancel": "Mégse",
+	"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 e2b2175..caf91fb 100644
--- a/dojox/grid/enhanced/nls/it/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/it/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Ordine singolo",
 	nestedSort: "Ordine nidificato",
@@ -9,4 +11,6 @@
 	indirectSelectionCheckBox: "Riga ${0}, selezione multipla, casella di spunta",
 	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 87860e4..8d07004 100644
--- a/dojox/grid/enhanced/nls/it/Filter.js
+++ b/dojox/grid/enhanced/nls/it/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Cancella filtro",
 	"filterDefDialogTitle": "Filtro",
@@ -62,8 +64,8 @@
 	"anycolumn": "qualsiasi colonna",
 	"statusTipTitleNoFilter": "Barra di filtro",
 	"statusTipTitleHasFilter": "Filtro",
-	"statusTipRelPre": "Confronta",
-	"statusTipRelPost": "regole.",
+	"statusTipRelAny": "Corrispondenza con qualsiasi regola.",
+	"statusTipRelAll": "Corrispondenza con tutte le regole.",
 	
 	"defaultItemsName": "elementi",
 	"filterBarMsgHasFilterTemplate": "${0} di ${1} ${2} visualizzati.",
@@ -82,6 +84,5 @@
 	"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 1de040b..12b642a 100644
--- a/dojox/grid/enhanced/nls/it/Pagination.js
+++ b/dojox/grid/enhanced/nls/it/Pagination.js
@@ -1,18 +1,24 @@
+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 alla pagina",
+	"gotoButtonTitle": "Vai a una pagina specifica ",
+	"dialogTitle": "Vai a pagina ",
 	"dialogIndication": "Specificare il numero di pagina",
 	"pageCountIndication": " (${0} pagine)",
 	"dialogConfirm": "Vai",
-	"dialogCancel": "Annulla"
+	"dialogCancel": "Annulla",
+	"all": "tutte"
 })
+//end v1.x content
+);
 
diff --git a/dojox/grid/enhanced/nls/ja/EnhancedGrid.js b/dojox/grid/enhanced/nls/ja/EnhancedGrid.js
index 7c9f49e..5b20c7d 100644
--- a/dojox/grid/enhanced/nls/ja/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/ja/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "単一ソート",
 	nestedSort: "ネスト・ソート",
@@ -9,3 +11,5 @@
 	indirectSelectionCheckBox: "行 ${0}、複数選択、チェック・ボックス",
 	selectAll: "すべてを選択"
 })
+//end v1.x content
+);
diff --git a/dojox/grid/enhanced/nls/ja/Filter.js b/dojox/grid/enhanced/nls/ja/Filter.js
index d673843..21f0e58 100644
--- a/dojox/grid/enhanced/nls/ja/Filter.js
+++ b/dojox/grid/enhanced/nls/ja/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "フィルターのクリア",
 	"filterDefDialogTitle": "フィルター",
@@ -62,8 +64,8 @@
 	"anycolumn": "いずれかの列",
 	"statusTipTitleNoFilter": "フィルター・バー",
 	"statusTipTitleHasFilter": "フィルター",
-	"statusTipRelPre": "一致",
-	"statusTipRelPost": "ルール",
+	"statusTipRelAny": "いずれかのルールに一致。",
+	"statusTipRelAll": "すべてのルールに一致。",
 	
 	"defaultItemsName": "項目",
 	"filterBarMsgHasFilterTemplate": "${0}/${1} ${2} が表示されました。",
@@ -82,4 +84,5 @@
 	"trueLabel": "True",
 	"falseLabel": "False"
 })
-
+//end v1.x content
+);
diff --git a/dojox/grid/enhanced/nls/ja/Pagination.js b/dojox/grid/enhanced/nls/ja/Pagination.js
index a2c1487..65a88ef 100644
--- a/dojox/grid/enhanced/nls/ja/Pagination.js
+++ b/dojox/grid/enhanced/nls/ja/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3}/${1} ${0}",
 	"firstTip": "最初のページ",
@@ -5,6 +7,7 @@
 	"nextTip": "次のページ",
 	"prevTip": "前のページ",
 	"itemTitle": "項目",
+	"singularItemTitle": "項目",
 	"pageStepLabelTemplate": "ページ ${0}",
 	"pageSizeLabelTemplate": "ページ当たり ${0} 項目",
 	"allItemsLabelTemplate": "すべての項目",
@@ -12,6 +15,9 @@
 	"dialogTitle": "ページの移動",
 	"dialogIndication": "ページ番号を指定してください",
 	"pageCountIndication": " (${0} ページ)",
-	"dialogConfirm": "移動",
-	"dialogCancel": "キャンセル"
+	"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 01ee777..2fb1569 100644
--- a/dojox/grid/enhanced/nls/kk/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/kk/EnhancedGrid.js
@@ -1,8 +1,16 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Бір рет сұрыптау",
 	nestedSort: "Кірістірілген сұрыптау",
-	ascending: "Өсу реті бойынша",
-	descending: "Кему",
-	unsorted: "Бұл бағанды сұрыптамау"
+	ascending: "Артуы бойынша",
+	descending: "Кемуі бойынша",
+	sortingState: "${0} - ${1}",
+	unsorted: "Бұл бағанды сұрыптамау",
+	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 1215640..050e065 100644
--- a/dojox/grid/enhanced/nls/kk/Filter.js
+++ b/dojox/grid/enhanced/nls/kk/Filter.js
@@ -1,7 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Сүзгіні тазалау",
 	"filterDefDialogTitle": "Сүзгі",
-	"incompleteRuleTip": "Бұл ереже толық емес.",
 	"ruleTitleTemplate": "${0} ережесі",
 	
 	"conditionEqual": "тең",
@@ -21,6 +22,7 @@
 	"conditionBefore": "алдында",
 	"conditionAfter": "артында",
 	"conditionRange": "ауқым",
+	"conditionIsEmpty": "– бос",
 	
 	"all": "барлығы",
 	"any": "кез келген",
@@ -62,8 +64,8 @@
 	"anycolumn": "кез келген баған",
 	"statusTipTitleNoFilter": "Сүзгі тақтасы",
 	"statusTipTitleHasFilter": "Сүзгі",
-	"statusTipRelPre": "Сәйкес келу",
-	"statusTipRelPost": "ережелер.",
+	"statusTipRelAny": "Кез келген ережелерді сәйкестендіріңіз.",
+	"statusTipRelAll": "Барлық ережелерді сәйкестендіріңіз.",
 	
 	"defaultItemsName": "элементтер",
 	"filterBarMsgHasFilterTemplate": "${1} ${2} ішінен ${0} көрсетілді.",
@@ -79,10 +81,8 @@
 	"clearFilterMsg": "Бұл сүзгіні жояды және барлық қол жетімді жазбаларды көрсетеді.",
 	"anyColumnOption": "Кез келген баған",
 	
-	"trueLabelEditable": "Белгіленген",
 	"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 736f4da..3c96d49 100644
--- a/dojox/grid/enhanced/nls/kk/Pagination.js
+++ b/dojox/grid/enhanced/nls/kk/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${1} ${0} элементтің ${2} - ${3} элементі",
 	"firstTip": "Бірінші бет",
@@ -5,6 +7,7 @@
 	"nextTip": "Келесі бет",
 	"prevTip": "Алдыңғы бет",
 	"itemTitle": "элементтер",
+	"singularItemTitle": "элемент",
 	"pageStepLabelTemplate": "Бет ${0}",
 	"pageSizeLabelTemplate": "Бетіне ${0} элемент",
 	"allItemsLabelTemplate": "Барлық элементтер",
@@ -13,6 +16,8 @@
 	"dialogIndication": "Бет нөмірін көрсету",
 	"pageCountIndication": " (${0} бет)",
 	"dialogConfirm": "Өту",
-	"dialogCancel": "Болдырмау"
+	"dialogCancel": "Болдырмау",
+	"all": "барлығы"
 })
-
+//end v1.x content
+);
diff --git a/dojox/grid/enhanced/nls/ko/EnhancedGrid.js b/dojox/grid/enhanced/nls/ko/EnhancedGrid.js
index 83cf705..6e97a42 100644
--- a/dojox/grid/enhanced/nls/ko/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/ko/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "단일 정렬",
 	nestedSort: "중첩된 정렬",
@@ -9,4 +11,6 @@
 	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 31cc104..fc44d89 100644
--- a/dojox/grid/enhanced/nls/ko/Filter.js
+++ b/dojox/grid/enhanced/nls/ko/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "필터 지우기",
 	"filterDefDialogTitle": "필터",
@@ -62,8 +64,8 @@
 	"anycolumn": "임의의 컬럼",
 	"statusTipTitleNoFilter": "필터 표시줄",
 	"statusTipTitleHasFilter": "필터",
-	"statusTipRelPre": "일치",
-	"statusTipRelPost": "규칙",
+	"statusTipRelAny": "임의 규칙과 일치.",
+	"statusTipRelAll": "모든 규칙과 일치.",
 	
 	"defaultItemsName": "항목",
 	"filterBarMsgHasFilterTemplate": "${0}/${1} ${2} 표시됨",
@@ -82,6 +84,5 @@
 	"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 d1b5187..250f72a 100644
--- a/dojox/grid/enhanced/nls/ko/Pagination.js
+++ b/dojox/grid/enhanced/nls/ko/Pagination.js
@@ -1,18 +1,24 @@
+define(
+//begin v1.x content
 ({
-	"descTemplate": "${2} - ${3}/${1} ${0}",
-	"firstTip": "첫 페이지",
+	"descTemplate": "${1} ${0} 중 ${2} - ${3}",
+	"firstTip": "첫 번째 페이지",
 	"lastTip": "마지막 페이지",
 	"nextTip": "다음 페이지",
 	"prevTip": "이전 페이지",
 	"itemTitle": "항목",
-	"pageStepLabelTemplate": "${0} 페이지",
-	"pageSizeLabelTemplate": "페이지당 ${0} 항목",
+	"singularItemTitle": "항목",
+	"pageStepLabelTemplate": "페이지 ${0}",
+	"pageSizeLabelTemplate": "페이지 당 ${0} 항목",
 	"allItemsLabelTemplate": "모든 항목",
 	"gotoButtonTitle": "특정 페이지로 이동",
-	"dialogTitle": "페이지 이동",
+	"dialogTitle": "페이지로 이동",
 	"dialogIndication": "페이지 번호 지정",
-	"pageCountIndication": " (${0}페이지)",
+	"pageCountIndication": " (${0} 페이지)",
 	"dialogConfirm": "이동",
-	"dialogCancel": "취소"
+	"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 18b5989..b5a7182 100644
--- a/dojox/grid/enhanced/nls/nb/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/nb/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Enkeltsortering",
 	nestedSort: "Nestet sortering",
@@ -9,4 +11,6 @@
 	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 03f4cbc..912fa72 100644
--- a/dojox/grid/enhanced/nls/nb/Filter.js
+++ b/dojox/grid/enhanced/nls/nb/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Tøm filter",
 	"filterDefDialogTitle": "Filter",
@@ -62,8 +64,8 @@
 	"anycolumn": "enhver kolonne",
 	"statusTipTitleNoFilter": "Filterlinje",
 	"statusTipTitleHasFilter": "Filter",
-	"statusTipRelPre": "Samsvar med",
-	"statusTipRelPost": "regler.",
+	"statusTipRelAny": "Samsvar med minst en regel.",
+	"statusTipRelAll": "Samsvar med alle regler.",
 	
 	"defaultItemsName": "elementer",
 	"filterBarMsgHasFilterTemplate": "${0} av ${1} ${2} vist.",
@@ -82,6 +84,5 @@
 	"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 2e8a3f9..74795dd 100644
--- a/dojox/grid/enhanced/nls/nb/Pagination.js
+++ b/dojox/grid/enhanced/nls/nb/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} av ${1} ${0}",
 	"firstTip": "Første side",
@@ -5,6 +7,7 @@
 	"nextTip": "Neste side",
 	"prevTip": "Forrige side",
 	"itemTitle": "elementer",
+	"singularItemTitle": "element",
 	"pageStepLabelTemplate": "Side ${0}",
 	"pageSizeLabelTemplate": "${0} elementer per side",
 	"allItemsLabelTemplate": "Alle elementer",
@@ -13,6 +16,8 @@
 	"dialogIndication": "Oppgi sidetallet",
 	"pageCountIndication": " (${0} sider)",
 	"dialogConfirm": "Utfør",
-	"dialogCancel": "Avbryt"
+	"dialogCancel": "Avbryt",
+	"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 36f32b4..c048fd2 100644
--- a/dojox/grid/enhanced/nls/nl/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/nl/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Enkelvoudig sorteren",
 	nestedSort: "Genest sorteren",
@@ -9,4 +11,6 @@
 	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 b1c1ce0..6f2f24a 100644
--- a/dojox/grid/enhanced/nls/nl/Filter.js
+++ b/dojox/grid/enhanced/nls/nl/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Filter wissen",
 	"filterDefDialogTitle": "Filteren",
@@ -62,8 +64,8 @@
 	"anycolumn": "een kolom",
 	"statusTipTitleNoFilter": "Filterbalk",
 	"statusTipTitleHasFilter": "Filter",
-	"statusTipRelPre": "Voldoen aan",
-	"statusTipRelPost": "regel.",
+	"statusTipRelAny": "Voldoen aan een van de regels.",
+	"statusTipRelAll": "Voldoen aan alle regels.",
 	
 	"defaultItemsName": "items",
 	"filterBarMsgHasFilterTemplate": "${0} van ${1} ${2} afgebeeld.",
@@ -82,6 +84,5 @@
 	"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 b972dda..063b9f6 100644
--- a/dojox/grid/enhanced/nls/nl/Pagination.js
+++ b/dojox/grid/enhanced/nls/nl/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} van ${1} ${0}",
 	"firstTip": "Eerste pagina",
@@ -5,14 +7,18 @@
 	"nextTip": "Volgende pagina",
 	"prevTip": "Vorige pagina",
 	"itemTitle": "items",
+	"singularItemTitle": "item",
 	"pageStepLabelTemplate": "Pagina ${0}",
 	"pageSizeLabelTemplate": "${0} items per pagina",
 	"allItemsLabelTemplate": "Alle items",
-	"gotoButtonTitle": "Naar een specifieke pagina gaan",
-	"dialogTitle": "Naar pagina gaan",
-	"dialogIndication": "Geef het paginanummer op:",
+	"gotoButtonTitle": "Ga naar bepaalde pagina",
+	"dialogTitle": "Ga naar pagina",
+	"dialogIndication": "Geef het paginanummer op",
 	"pageCountIndication": " (${0} pagina's)",
-	"dialogConfirm": "Start",
-	"dialogCancel": "Annuleren"
+	"dialogConfirm": "Go",
+	"dialogCancel": "Annuleren",
+	"all": "alle"
 })
+//end v1.x content
+);
 
diff --git a/dojox/grid/enhanced/nls/pl/EnhancedGrid.js b/dojox/grid/enhanced/nls/pl/EnhancedGrid.js
index c5baab4..a391a5f 100644
--- a/dojox/grid/enhanced/nls/pl/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/pl/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Pojedyncze sortowanie",
 	nestedSort: "Zagnieżdżone sortowanie",
@@ -9,4 +11,6 @@
 	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 d533d1a..2edfcf2 100644
--- a/dojox/grid/enhanced/nls/pl/Filter.js
+++ b/dojox/grid/enhanced/nls/pl/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Wyczyść filtr",
 	"filterDefDialogTitle": "Filtr",
@@ -62,8 +64,8 @@
 	"anycolumn": "dowolna kolumna",
 	"statusTipTitleNoFilter": "Pasek filtru",
 	"statusTipTitleHasFilter": "Filtr",
-	"statusTipRelPre": "Dopasuj",
-	"statusTipRelPost": "reguły.",
+	"statusTipRelAny": "Dopasuj do dowolnej z reguł.",
+	"statusTipRelAll": "Dopasuj do wszystkich reguł.",
 	
 	"defaultItemsName": "elementy",
 	"filterBarMsgHasFilterTemplate": "Wyświetlane ${0} z ${1} ${2}.",
@@ -82,6 +84,5 @@
 	"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 50e4f98..042bdd8 100644
--- a/dojox/grid/enhanced/nls/pl/Pagination.js
+++ b/dojox/grid/enhanced/nls/pl/Pagination.js
@@ -1,18 +1,24 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} z ${1} ${0}",
 	"firstTip": "Pierwsza strona",
 	"lastTip": "Ostatnia strona",
 	"nextTip": "Następna strona",
 	"prevTip": "Poprzednia strona",
-	"itemTitle": "elementy",
+	"itemTitle": "poz.",
+	"singularItemTitle": "pozycja",
 	"pageStepLabelTemplate": "Strona ${0}",
-	"pageSizeLabelTemplate": "${0} elementów na stronę",
-	"allItemsLabelTemplate": "Wszystkie elementy",
-	"gotoButtonTitle": "Idź do określonej strony",
+	"pageSizeLabelTemplate": "${0} poz. na stronę",
+	"allItemsLabelTemplate": "Wszystkie pozycje",
+	"gotoButtonTitle": "Idź do konkretnej strony",
 	"dialogTitle": "Idź do strony",
 	"dialogIndication": "Podaj numer strony",
-	"pageCountIndication": " (${0} stron)",
-	"dialogConfirm": "Idź",
-	"dialogCancel": "Anuluj"
+	"pageCountIndication": " (${0} str.)",
+	"dialogConfirm": "Wykonaj",
+	"dialogCancel": "Anuluj",
+	"all": "wszystkie"
 })
+//end v1.x content
+);
 
diff --git a/dojox/grid/enhanced/nls/pt-br/EnhancedGrid.js b/dojox/grid/enhanced/nls/pt-br/EnhancedGrid.js
new file mode 100644
index 0000000..6232cdd
--- /dev/null
+++ b/dojox/grid/enhanced/nls/pt-br/EnhancedGrid.js
@@ -0,0 +1,12 @@
+({
+	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
new file mode 100644
index 0000000..b96eaa8
--- /dev/null
+++ b/dojox/grid/enhanced/nls/pt-br/Filter.js
@@ -0,0 +1,85 @@
+({
+	"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
new file mode 100644
index 0000000..b1cfc6d
--- /dev/null
+++ b/dojox/grid/enhanced/nls/pt-br/Pagination.js
@@ -0,0 +1,32 @@
+({
+	// ${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 b845586..696992d 100644
--- a/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.js
@@ -1,8 +1,16 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Ordenação única",
 	nestedSort: "Ordenação imbricada",
 	ascending: "Ascendente",
 	descending: "Descendente",
-	unsorted: "Não ordenar esta coluna"
+	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",
+	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 e5d139b..c8d7fc0 100644
--- a/dojox/grid/enhanced/nls/pt-pt/Filter.js
+++ b/dojox/grid/enhanced/nls/pt-pt/Filter.js
@@ -1,7 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Limpar filtro",
 	"filterDefDialogTitle": "Filtro",
-	"incompleteRuleTip": "Esta regra não está completa.",
 	"ruleTitleTemplate": "Regra ${0}",
 	
 	"conditionEqual": "igual",
@@ -21,6 +22,7 @@
 	"conditionBefore": "antes",
 	"conditionAfter": "após",
 	"conditionRange": "intervalo",
+	"conditionIsEmpty": "está vazio",
 	
 	"all": "tudo",
 	"any": "qualquer",
@@ -62,8 +64,6 @@
 	"anycolumn": "qualquer coluna",
 	"statusTipTitleNoFilter": "Barra do filtro",
 	"statusTipTitleHasFilter": "Filtro",
-	"statusTipRelPre": "Correspondência",
-	"statusTipRelPost": "regras.",
 	
 	"defaultItemsName": "itens",
 	"filterBarMsgHasFilterTemplate": "${0} de ${1} ${2} apresentado(s).",
@@ -79,10 +79,11 @@
 	"clearFilterMsg": "Este procedimento irá remover o filtro e apresentar todos os registos disponíveis.",
 	"anyColumnOption": "Qualquer coluna",
 	
-	"trueLabelEditable": "Verificado",
 	"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 d76cd3d..cbd7d63 100644
--- a/dojox/grid/enhanced/nls/pt-pt/Pagination.js
+++ b/dojox/grid/enhanced/nls/pt-pt/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} de ${1} ${0}",
 	"firstTip": "Primeira página",
@@ -13,6 +15,9 @@
 	"dialogIndication": "Especificar o número de página",
 	"pageCountIndication": " (${0} páginas)",
 	"dialogConfirm": "Ir",
-	"dialogCancel": "Cancelar"
+	"dialogCancel": "Cancelar",
+	"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 6346323..e3863ba 100644
--- a/dojox/grid/enhanced/nls/pt/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/pt/EnhancedGrid.js
@@ -1,8 +1,16 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Classificação Única",
 	nestedSort: "Classificação Aninhada",
 	ascending: "Ascendente",
 	descending: "Descendente",
-	unsorted: "Não classificar esta coluna"
+	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 0f47217..5359533 100644
--- a/dojox/grid/enhanced/nls/pt/Filter.js
+++ b/dojox/grid/enhanced/nls/pt/Filter.js
@@ -1,9 +1,10 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Limpar Filtro",
 	"filterDefDialogTitle": "Filtrar",
-	"incompleteRuleTip": "Esta regra não está completa.",
 	"ruleTitleTemplate": "Regra ${0}",
-
+	
 	"conditionEqual": "igual",
 	"conditionNotEqual": "não é igual",
 	"conditionLess": "é menor que",
@@ -21,7 +22,8 @@
 	"conditionBefore": "antes",
 	"conditionAfter": "depois",
 	"conditionRange": "intervalo",
-
+	"conditionIsEmpty": "está vazio",
+	
 	"all": "todos",
 	"any": "qualquer um",
 	"relationAll": "todas as regras",
@@ -32,29 +34,29 @@
 	"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": "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",
 	"rangeTemplate": "de ${0} a ${1}",
-
+	
 	"statusTipHeaderColumn": "Coluna",
 	"statusTipHeaderCondition": "Regras",
 	"statusTipTitle": "Barra de Filtragem",
@@ -62,25 +64,28 @@
 	"anycolumn": "qualquer coluna",
 	"statusTipTitleNoFilter": "Barra de Filtragem",
 	"statusTipTitleHasFilter": "Filtrar",
-	"statusTipRelPre": "Corresponder",
-	"statusTipRelPost": "regras.",
-
+	"statusTipRelAny": "Quaisquer Regras.",
+	"statusTipRelAll": "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",
-
-	"trueLabelEditable": "Verificado",
+	
 	"trueLabel": "Verdadeiro",
 	"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 4d68a04..0b75f31 100644
--- a/dojox/grid/enhanced/nls/pt/Pagination.js
+++ b/dojox/grid/enhanced/nls/pt/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} de ${1} ${0}",
 	"firstTip": "Primeira Página",
@@ -5,6 +7,7 @@
 	"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",
@@ -13,5 +16,8 @@
 	"dialogIndication": "Especifique o número da página",
 	"pageCountIndication": " (${0} páginas)",
 	"dialogConfirm": "Ir",
-	"dialogCancel": "Cancelar"
+	"dialogCancel": "Cancelar",
+	"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 9ce83fb..75e0c8c 100644
--- a/dojox/grid/enhanced/nls/ro/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/ro/EnhancedGrid.js
@@ -1,8 +1,16 @@
+define(
+//begin v1.x content
 ({
-	singleSort: "Sortare singură",
+	singleSort: "Sortare singulară",
 	nestedSort: "Sortare imbricată",
 	ascending: "Crescător",
 	descending: "Descrescător",
-	unsorted: "Nu sortaţi această coloană"
+	sortingState: "${0} - ${1}",
+	unsorted: "Nu se sortează această coloană",
+	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 7be1915..d5bb491 100644
--- a/dojox/grid/enhanced/nls/ro/Filter.js
+++ b/dojox/grid/enhanced/nls/ro/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Ştergere filtru",
 	"filterDefDialogTitle": "Filtru",
@@ -15,7 +17,7 @@
 	"conditionEndWith": "se termină cu",
 	"conditionNotContain": "nu conţine",
 	"conditionIsNot": "nu este",
-	"conditionNotStartWith": "nu începe cu ",
+	"conditionNotStartWith": "nu începe cu",
 	"conditionNotEndWith": "nu se termină cu",
 	"conditionBefore": "înaintea",
 	"conditionAfter": "după",
@@ -62,8 +64,8 @@
 	"anycolumn": "orice coloană",
 	"statusTipTitleNoFilter": "Bară de filtru",
 	"statusTipTitleHasFilter": "Filtru",
-	"statusTipRelPre": "Îndeplinire",
-	"statusTipRelPost": "reguli.",
+	"statusTipRelAny": "Potrivire orice regulă.",
+	"statusTipRelAll": "Potrivire toate regulile.",
 	
 	"defaultItemsName": "articole",
 	"filterBarMsgHasFilterTemplate": "${0} din ${1} ${2} afişate.",
@@ -82,6 +84,5 @@
 	"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 b897e77..7829a01 100644
--- a/dojox/grid/enhanced/nls/ro/Pagination.js
+++ b/dojox/grid/enhanced/nls/ro/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} din ${1} ${0}",
 	"firstTip": "Prima pagină",
@@ -5,6 +7,7 @@
 	"nextTip": "Următoarea pagină",
 	"prevTip": "Pagina anterioarp",
 	"itemTitle": "articole",
+	"singularItemTitle": "articol",
 	"pageStepLabelTemplate": "Pagina ${0}",
 	"pageSizeLabelTemplate": "${0} articole pe pagină",
 	"allItemsLabelTemplate": "Toate articolele",
@@ -13,6 +16,8 @@
 	"dialogIndication": "Specificaţi numărul de pagină",
 	"pageCountIndication": " (${0} pagini)",
 	"dialogConfirm": "Deplasare",
-	"dialogCancel": "Anulare"
+	"dialogCancel": "Anulare",
+	"all": "toate"
 })
-
+//end v1.x content
+);
diff --git a/dojox/grid/enhanced/nls/ru/EnhancedGrid.js b/dojox/grid/enhanced/nls/ru/EnhancedGrid.js
index ef48b03..3fb9e01 100644
--- a/dojox/grid/enhanced/nls/ru/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/ru/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Простая сортировка",
 	nestedSort: "Вложенная сортировка",
@@ -9,4 +11,6 @@
 	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 b50c35f..dcbbd3a 100644
--- a/dojox/grid/enhanced/nls/ru/Filter.js
+++ b/dojox/grid/enhanced/nls/ru/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Удалить фильтр",
 	"filterDefDialogTitle": "Фильтр",
@@ -62,8 +64,8 @@
 	"anycolumn": "любой столбец",
 	"statusTipTitleNoFilter": "Панель фильтра",
 	"statusTipTitleHasFilter": "Фильтр",
-	"statusTipRelPre": "Соответствие",
-	"statusTipRelPost": "правила.",
+	"statusTipRelAny": "Соответствует любому из правил.",
+	"statusTipRelAll": "Соответствует всем правилам.",
 	
 	"defaultItemsName": "элементов",
 	"filterBarMsgHasFilterTemplate": "Показано ${0} из ${1} ${2}.",
@@ -82,6 +84,5 @@
 	"trueLabel": "True",
 	"falseLabel": "False"
 })
-
-
-
+//end v1.x content
+);
diff --git a/dojox/grid/enhanced/nls/ru/Pagination.js b/dojox/grid/enhanced/nls/ru/Pagination.js
index 864395c..8c0655c 100644
--- a/dojox/grid/enhanced/nls/ru/Pagination.js
+++ b/dojox/grid/enhanced/nls/ru/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} из ${1} ${0}",
 	"firstTip": "Первая страница",
@@ -5,14 +7,18 @@
 	"nextTip": "Следующая страница",
 	"prevTip": "Предыдущая страница",
 	"itemTitle": "элементов",
+	"singularItemTitle": "элемент",
 	"pageStepLabelTemplate": "Страница ${0}",
 	"pageSizeLabelTemplate": "${0} элементов на странице",
 	"allItemsLabelTemplate": "Все элементы",
-	"gotoButtonTitle": "Перейти на конкретную страницу",
+	"gotoButtonTitle": "Перейти на определенную страницу",
 	"dialogTitle": "Перейти на страницу",
-	"dialogIndication": "Укажите номер страницы",
+	"dialogIndication": "Задайте номер страницы",
 	"pageCountIndication": " (${0} страниц)",
 	"dialogConfirm": "Перейти",
-	"dialogCancel": "Отмена"
+	"dialogCancel": "Отмена",
+	"all": "все"
 })
+//end v1.x content
+);
 
diff --git a/dojox/grid/enhanced/nls/sk/EnhancedGrid.js b/dojox/grid/enhanced/nls/sk/EnhancedGrid.js
index 711f562..ce7dd87 100644
--- a/dojox/grid/enhanced/nls/sk/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/sk/EnhancedGrid.js
@@ -1,8 +1,16 @@
+define(
+//begin v1.x content
 ({
-	singleSort: "Jednoduché triedenie ",
-	nestedSort: "Vnorené triedenie ",
-	ascending: "Vzostupne ",
-	descending: "Zostupne ",
-	unsorted: "Netriediť tento stĺpec "
+	singleSort: "Jednoduché triedenie",
+	nestedSort: "Vnorené triedenie",
+	ascending: "Vzostupne",
+	descending: "Zostupne",
+	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 b2303f3..47316a4 100644
--- a/dojox/grid/enhanced/nls/sk/Filter.js
+++ b/dojox/grid/enhanced/nls/sk/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Zrušiť filter",
 	"filterDefDialogTitle": "Filter",
@@ -62,8 +64,8 @@
 	"anycolumn": "ľubovoľný stĺpec",
 	"statusTipTitleNoFilter": "Lišta filtra",
 	"statusTipTitleHasFilter": "Filter",
-	"statusTipRelPre": "Vyhovieť",
-	"statusTipRelPost": "pravidlá.",
+	"statusTipRelAny": "Zhoda s akýmikoľvek pravidlami.",
+	"statusTipRelAll": "Zhoda so všetkými pravidlami.",
 	
 	"defaultItemsName": "položky",
 	"filterBarMsgHasFilterTemplate": "Zobrazuje sa ${0} z ${1} ${2}.",
@@ -82,6 +84,5 @@
 	"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 d1afa89..c8e84b5 100644
--- a/dojox/grid/enhanced/nls/sk/Pagination.js
+++ b/dojox/grid/enhanced/nls/sk/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} z ${1} ${0}",
 	"firstTip": "Prvá strana",
@@ -5,6 +7,7 @@
 	"nextTip": "Ďalšia strana",
 	"prevTip": "Predošlá strana",
 	"itemTitle": "položiek",
+	"singularItemTitle": "položka",
 	"pageStepLabelTemplate": "Strana ${0}",
 	"pageSizeLabelTemplate": "${0} položiek na strane",
 	"allItemsLabelTemplate": "Všetky položky",
@@ -13,6 +16,8 @@
 	"dialogIndication": "Zadajte číslo strany",
 	"pageCountIndication": " (${0} strán)",
 	"dialogConfirm": "Prejsť",
-	"dialogCancel": "Zrušiť"
+	"dialogCancel": "Zrušiť",
+	"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 7201d7f..a0ded6f 100644
--- a/dojox/grid/enhanced/nls/sl/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/sl/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Enostavno razvrščanje",
 	nestedSort: "Ugnezdeno razvrščanje",
@@ -9,4 +11,6 @@
 	indirectSelectionCheckBox: "Vrstica ${0}, izbira več elementov, 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 7d1e47b..cbcbffd 100644
--- a/dojox/grid/enhanced/nls/sl/Filter.js
+++ b/dojox/grid/enhanced/nls/sl/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Počisti filter",
 	"filterDefDialogTitle": "Filter",
@@ -62,8 +64,8 @@
 	"anycolumn": "katerikoli stolpec",
 	"statusTipTitleNoFilter": "Vrstica za filtriranje",
 	"statusTipTitleHasFilter": "Filter",
-	"statusTipRelPre": "Ujemanje",
-	"statusTipRelPost": "pravila.",
+	"statusTipRelAny": "Ujemanje s katerimkoli pravilom.",
+	"statusTipRelAll": "Ujemanje z vsemi pravili.",
 	
 	"defaultItemsName": "postavke",
 	"filterBarMsgHasFilterTemplate": "Prikazanih je ${0} od ${1} ${2}.",
@@ -82,6 +84,5 @@
 	"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 935f3a9..e563ff0 100644
--- a/dojox/grid/enhanced/nls/sl/Pagination.js
+++ b/dojox/grid/enhanced/nls/sl/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} od ${1} ${0}",
 	"firstTip": "Prva stran",
@@ -5,6 +7,7 @@
 	"nextTip": "Naslednja stran",
 	"prevTip": "Prejšnja stran",
 	"itemTitle": "postavke",
+	"singularItemTitle": "postavka",
 	"pageStepLabelTemplate": "Stran ${0}",
 	"pageSizeLabelTemplate": "${0} postavk na stran",
 	"allItemsLabelTemplate": "Vse postavke",
@@ -13,6 +16,9 @@
 	"dialogIndication": "Podajte številko strani",
 	"pageCountIndication": " (${0} strani)",
 	"dialogConfirm": "Pojdi",
-	"dialogCancel": "Prekliči"
+	"dialogCancel": "Prekliči",
+	"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 2d23b4a..44c3b5f 100644
--- a/dojox/grid/enhanced/nls/sv/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/sv/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Enkel sortering",
 	nestedSort: "Nästlad sortering",
@@ -9,4 +11,6 @@
 	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 efe276e..da971c0 100644
--- a/dojox/grid/enhanced/nls/sv/Filter.js
+++ b/dojox/grid/enhanced/nls/sv/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Rensa filter",
 	"filterDefDialogTitle": "Filter",
@@ -62,8 +64,8 @@
 	"anycolumn": "alla kolumner",
 	"statusTipTitleNoFilter": "Filterfält",
 	"statusTipTitleHasFilter": "Filter",
-	"statusTipRelPre": "Matcha",
-	"statusTipRelPost": "regler.",
+	"statusTipRelAny": "Matcha någon regel.",
+	"statusTipRelAll": "Matcha alla regler.",
 	
 	"defaultItemsName": "objekt",
 	"filterBarMsgHasFilterTemplate": "${0} av ${1} ${2} visas.",
@@ -82,6 +84,5 @@
 	"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 cb2c9b9..628201c 100644
--- a/dojox/grid/enhanced/nls/sv/Pagination.js
+++ b/dojox/grid/enhanced/nls/sv/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} av ${1} ${0}",
 	"firstTip": "Första sidan",
@@ -5,6 +7,7 @@
 	"nextTip": "Nästa sida",
 	"prevTip": "Föregående sida",
 	"itemTitle": "objekt",
+	"singularItemTitle": "objekt",
 	"pageStepLabelTemplate": "Sida ${0}",
 	"pageSizeLabelTemplate": "${0} objekt per sida",
 	"allItemsLabelTemplate": "Alla objekt",
@@ -13,6 +16,8 @@
 	"dialogIndication": "Ange sidnummer",
 	"pageCountIndication": " (${0} sidor)",
 	"dialogConfirm": "Gå",
-	"dialogCancel": "Avbryt"
+	"dialogCancel": "Avbryt",
+	"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 2b26c2a..983d781 100644
--- a/dojox/grid/enhanced/nls/th/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/th/EnhancedGrid.js
@@ -1,8 +1,16 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "เรียงลำดับแบบเดี่ยว",
 	nestedSort: "เรียงลำดับที่ซับซ้อน",
 	ascending: "จากน้อยไปหามาก",
 	descending: "จากมากไปหาน้อย",
-	unsorted: "ห้ามเรียงลำดับคอลัมน์นี้"
+	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 d190f9c..b6e69e0 100644
--- a/dojox/grid/enhanced/nls/th/Filter.js
+++ b/dojox/grid/enhanced/nls/th/Filter.js
@@ -1,7 +1,8 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "ลบตัวกรอง",
 	"filterDefDialogTitle": "ตัวกรอง",
-	"incompleteRuleTip": "กฏนี้ยังไม่สมบูรณ์",
 	"ruleTitleTemplate": "กฏ ${0}",
 	
 	"conditionEqual": "เท่ากับ",
@@ -21,6 +22,7 @@
 	"conditionBefore": "ก่อน",
 	"conditionAfter": "หลัง",
 	"conditionRange": "ช่วง",
+	"conditionIsEmpty": "ว่างอยู่",
 	
 	"all": "ทั้งหมด",
 	"any": "ใด",
@@ -62,8 +64,8 @@
 	"anycolumn": "คอลัมน์ใดๆ",
 	"statusTipTitleNoFilter": "แถบตัวกรอง",
 	"statusTipTitleHasFilter": "ตัวกรอง",
-	"statusTipRelPre": "ตรงกับ",
-	"statusTipRelPost": "กฏ",
+	"statusTipRelAny": "ตรงกับกฏใดๆ",
+	"statusTipRelAll": "ตรงกับทุกกฏ",
 	
 	"defaultItemsName": "ไอเท็ม",
 	"filterBarMsgHasFilterTemplate": "${0} ของ ${1} ${2} จะถูกแสดง",
@@ -79,10 +81,8 @@
 	"clearFilterMsg": "ซึ่งจะลบตัวกรองออกและแสดงเร็กคอร์ดที่พร้อมใช้งานทั้งหมด",
 	"anyColumnOption": "คอลัมน์ใดๆ",
 	
-	"trueLabelEditable": "ได้รับการตรวจสอบ",
 	"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 603c03f..24f54ff 100644
--- a/dojox/grid/enhanced/nls/th/Pagination.js
+++ b/dojox/grid/enhanced/nls/th/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} จาก ${1} ${0}",
 	"firstTip": "หน้าแรก",
@@ -5,6 +7,7 @@
 	"nextTip": "หน้าถัดไป",
 	"prevTip": "หน้าก่อนหน้านี้",
 	"itemTitle": "ไอเท็ม",
+	"singularItemTitle": "ไอเท็ม",
 	"pageStepLabelTemplate": "หน้า ${0}",
 	"pageSizeLabelTemplate": "${0} ไอเท็มต่อหน้า",
 	"allItemsLabelTemplate": "รายการ ทั้งหมด",
@@ -13,6 +16,8 @@
 	"dialogIndication": "ระบุหมายเลขหน้า",
 	"pageCountIndication": " (${0} หน้า)",
 	"dialogConfirm": "ไปที่",
-	"dialogCancel": "ยกเลิก"
+	"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 1b87ce0..cc98a9f 100644
--- a/dojox/grid/enhanced/nls/tr/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/tr/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "Tekli Sıralama",
 	nestedSort: "İç İçe Sıralama",
@@ -9,4 +11,6 @@
 	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 6083c2b..3a1050d 100644
--- a/dojox/grid/enhanced/nls/tr/Filter.js
+++ b/dojox/grid/enhanced/nls/tr/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Süzgeci Kaldır",
 	"filterDefDialogTitle": "Süzgeç",
@@ -62,8 +64,8 @@
 	"anycolumn": "herhangi bir sütun",
 	"statusTipTitleNoFilter": "Süzgeç Çubuğu",
 	"statusTipTitleHasFilter": "Süzgeç",
-	"statusTipRelPre": "Eşleştir",
-	"statusTipRelPost": "kurallar.",
+	"statusTipRelAny": "Herhangi bir kuralı eşleştir.",
+	"statusTipRelAll": "Bütün kuralları eşleştir.",
 	
 	"defaultItemsName": "öğe",
 	"filterBarMsgHasFilterTemplate": "${0} / ${1} ${2} gösteriliyor.",
@@ -82,6 +84,5 @@
 	"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 4750df9..1aa949f 100644
--- a/dojox/grid/enhanced/nls/tr/Pagination.js
+++ b/dojox/grid/enhanced/nls/tr/Pagination.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} / ${1} ${0}",
 	"firstTip": "İlk Sayfa",
@@ -5,6 +7,7 @@
 	"nextTip": "Sonraki Sayfa",
 	"prevTip": "Önceki Sayfa",
 	"itemTitle": "öğe",
+	"singularItemTitle": "öğe",
 	"pageStepLabelTemplate": "Sayfa ${0}",
 	"pageSizeLabelTemplate": "Sayfa başına ${0} öğe",
 	"allItemsLabelTemplate": "Tüm öğeler",
@@ -13,6 +16,8 @@
 	"dialogIndication": "Sayfa numarasını belirtin",
 	"pageCountIndication": " (${0} sayfa)",
 	"dialogConfirm": "Git",
-	"dialogCancel": "İptal"
+	"dialogCancel": "İptal",
+	"all": "tümü"
 })
-
+//end v1.x content
+);
diff --git a/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js b/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js
index 3963132..0233afd 100644
--- a/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "單一排序",
 	nestedSort: "巢狀排序",
@@ -9,4 +11,6 @@
 	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 feefdb7..785459e 100644
--- a/dojox/grid/enhanced/nls/zh-tw/Filter.js
+++ b/dojox/grid/enhanced/nls/zh-tw/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "清除過濾器",
 	"filterDefDialogTitle": "過濾器",
@@ -62,8 +64,8 @@
 	"anycolumn": "任何直欄",
 	"statusTipTitleNoFilter": "過濾器列",
 	"statusTipTitleHasFilter": "過濾器",
-	"statusTipRelPre": "符合",
-	"statusTipRelPost": "規則。",
+	"statusTipRelAny": "符合任何規則。",
+	"statusTipRelAll": "符合所有規則。",
 	
 	"defaultItemsName": "項目",
 	"filterBarMsgHasFilterTemplate": "顯示 ${1} ${2} 之 ${0}。",
@@ -82,6 +84,5 @@
 	"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 82c929f..0d344d1 100644
--- a/dojox/grid/enhanced/nls/zh-tw/Pagination.js
+++ b/dojox/grid/enhanced/nls/zh-tw/Pagination.js
@@ -1,18 +1,24 @@
+define(
+//begin v1.x content
 ({
-	"descTemplate": "${2} - ${1} ${0} 之 ${3}",
+	"descTemplate": "${2} - ${3} / ${1} ${0}",
 	"firstTip": "首頁",
 	"lastTip": "末頁",
 	"nextTip": "下一頁",
 	"prevTip": "上一頁",
 	"itemTitle": "項目",
-	"pageStepLabelTemplate": "頁面 ${0}",
+	"singularItemTitle": "項目",
+	"pageStepLabelTemplate": "第 ${0} 頁",
 	"pageSizeLabelTemplate": "每頁 ${0} 個項目",
 	"allItemsLabelTemplate": "所有項目",
-	"gotoButtonTitle": "跳至特定的頁面",
+	"gotoButtonTitle": "跳至特定頁面",
 	"dialogTitle": "跳至頁面",
 	"dialogIndication": "指定頁碼",
-	"pageCountIndication": " (${0} 頁)",
+	"pageCountIndication": "(${0} 頁)",
 	"dialogConfirm": "執行",
-	"dialogCancel": "取消"
+	"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 d44a0af..036aa00 100644
--- a/dojox/grid/enhanced/nls/zh/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/zh/EnhancedGrid.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	singleSort: "单层排序",
 	nestedSort: "嵌套排序",
@@ -9,4 +11,6 @@
 	indirectSelectionCheckBox: "第 ${0} 行,多选,复选框",
 	selectAll: "全部选中"
 })
+//end v1.x content
+);
 
diff --git a/dojox/grid/enhanced/nls/zh/Filter.js b/dojox/grid/enhanced/nls/zh/Filter.js
index c9da151..e7a1e19 100644
--- a/dojox/grid/enhanced/nls/zh/Filter.js
+++ b/dojox/grid/enhanced/nls/zh/Filter.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	"clearFilterDialogTitle": "清除过滤器",
 	"filterDefDialogTitle": "过滤器",
@@ -62,8 +64,8 @@
 	"anycolumn": "任何列",
 	"statusTipTitleNoFilter": "过滤器栏",
 	"statusTipTitleHasFilter": "过滤器",
-	"statusTipRelPre": "符合",
-	"statusTipRelPost": "规则。",
+	"statusTipRelAny": "与任何规则匹配。",
+	"statusTipRelAll": "与所有规则匹配。",
 	
 	"defaultItemsName": "项目",
 	"filterBarMsgHasFilterTemplate": "显示的 ${1} ${2} 的 ${0}。",
@@ -82,6 +84,5 @@
 	"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 d8cdd27..c1b5452 100644
--- a/dojox/grid/enhanced/nls/zh/Pagination.js
+++ b/dojox/grid/enhanced/nls/zh/Pagination.js
@@ -1,18 +1,24 @@
+define(
+//begin v1.x content
 ({
-	"descTemplate": "${2} - ${1} ${0} 的 ${3}",
+	"descTemplate": "${1} 个${0}中的  ${2} - ${3}",
 	"firstTip": "第一页",
 	"lastTip": "最后一页",
 	"nextTip": "下一页",
 	"prevTip": "上一页",
 	"itemTitle": "项目",
+	"singularItemTitle": "项",
 	"pageStepLabelTemplate": "第 ${0} 页",
 	"pageSizeLabelTemplate": "每页的 ${0} 项目",
 	"allItemsLabelTemplate": "所有项目",
 	"gotoButtonTitle": "转到指定页面",
 	"dialogTitle": "转到页面",
 	"dialogIndication": "指定页数",
-	"pageCountIndication": " (${0} 页)",
+	"pageCountIndication": "(${0} 页)",
 	"dialogConfirm": "确定",
-	"dialogCancel": "取消"
+	"dialogCancel": "取消",
+	"all": "全部"
 })
+//end v1.x content
+);
 
diff --git a/dojox/grid/enhanced/plugins/AutoScroll.js b/dojox/grid/enhanced/plugins/AutoScroll.js
index 12ecb04..d8bcb01 100644
--- a/dojox/grid/enhanced/plugins/AutoScroll.js
+++ b/dojox/grid/enhanced/plugins/AutoScroll.js
@@ -1,9 +1,15 @@
-dojo.provide("dojox.grid.enhanced.plugins.AutoScroll");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/_base/html",
+	"dojo/_base/window",
+	"../_Plugin",
+	"../../_RowSelector",
+	"../../EnhancedGrid"
+], function(declare, array, lang, html, win, _Plugin, _RowSelector, EnhancedGrid){
 
-dojo.require("dojox.grid.enhanced._Plugin");
-dojo.require("dojox.grid._RowSelector");
-
-dojo.declare("dojox.grid.enhanced.plugins.AutoScroll", dojox.grid.enhanced._Plugin, {
+var AutoScroll = declare("dojox.grid.enhanced.plugins.AutoScroll", _Plugin, {
 	// summary:
 	//		Provides horizontal and vertical auto-scroll for grid.
 	
@@ -23,7 +29,7 @@ dojo.declare("dojox.grid.enhanced.plugins.AutoScroll", dojox.grid.enhanced._Plug
 		this.grid = grid;
 		this.readyForAutoScroll = false;
 		this._scrolling = false;
-		args = dojo.isObject(args) ? args : {};
+		args = lang.isObject(args) ? args : {};
 		if("interval" in args){
 			this.autoScrollInterval = args.interval;
 		}
@@ -44,14 +50,14 @@ dojo.declare("dojox.grid.enhanced.plugins.AutoScroll", dojox.grid.enhanced._Plug
 		this.connect(g, "onRowSelectorMouseDown", function(){
 			this.readyForAutoScroll = true;
 		});
-		this.connect(dojo.doc, "onmouseup", function(evt){
+		this.connect(win.doc, "onmouseup", function(evt){
 			this._manageAutoScroll(true);
 			this.readyForAutoScroll = false;
 		});
-		this.connect(dojo.doc, "onmousemove", function(evt){
+		this.connect(win.doc, "onmousemove", function(evt){
 			if(this.readyForAutoScroll){
 				this._event = evt;
-				var gridPos = dojo.position(g.domNode),
+				var gridPos = html.position(g.domNode),
 					hh = g._getHeaderHeight(),
 					margin = this.autoScrollMargin,
 					ey = evt.clientY, ex = evt.clientX,
@@ -65,11 +71,11 @@ dojo.declare("dojox.grid.enhanced.plugins.AutoScroll", dojox.grid.enhanced._Plug
 						this._manageAutoScroll(false, true, true);
 						return;
 					}else if(ey >= gy && ey <= gy + gh){
-						var withinSomeview = dojo.some(g.views.views, function(view, i){
-							if(view instanceof dojox.grid._RowSelector){
+						var withinSomeview = array.some(g.views.views, function(view, i){
+							if(view instanceof _RowSelector){
 								return false;
 							}
-							var viewPos = dojo.position(view.domNode);
+							var viewPos = html.position(view.domNode);
 							if(ex < viewPos.x + margin && ex >= viewPos.x){
 								this._manageAutoScroll(false, false, false, view);
 								return true;
@@ -113,7 +119,7 @@ dojo.declare("dojox.grid.enhanced.plugins.AutoScroll", dojox.grid.enhanced._Plug
 			this._scrolling = true;
 			this._fireEvent("start", [isVertical, isForward, view]);
 			this._autoScroll(isVertical, isForward, view);
-			this._handler = setInterval(dojo.hitch(this, "_autoScroll", isVertical, isForward, view), this.autoScrollInterval);
+			this._handler = setInterval(lang.hitch(this, "_autoScroll", isVertical, isForward, view), this.autoScrollInterval);
 		}
 	},
 	_autoScroll: function(isVertical, isForward, view){
@@ -136,15 +142,15 @@ dojo.declare("dojox.grid.enhanced.plugins.AutoScroll", dojox.grid.enhanced._Plug
 		var node = view.scrollboxNode,
 			target = null;
 		if(node.clientWidth < node.scrollWidth){
-			var cells = dojo.filter(this.grid.layout.cells, function(cell){
+			var cells = array.filter(this.grid.layout.cells, function(cell){
 				return !cell.hidden;
 			});
-			var viewPos = dojo.position(view.domNode);
+			var viewPos = html.position(view.domNode);
 			var limit, edge, headerPos, i;
 			if(isForward){
 				limit = node.clientWidth;
 				for(i = 0; i < cells.length; ++i){
-					headerPos = dojo.position(cells[i].getHeaderNode());
+					headerPos = html.position(cells[i].getHeaderNode());
 					edge = headerPos.x - viewPos.x + headerPos.w;
 					if(edge > limit){
 						target = cells[i].index;
@@ -155,7 +161,7 @@ dojo.declare("dojox.grid.enhanced.plugins.AutoScroll", dojox.grid.enhanced._Plug
 			}else{
 				limit = 0;
 				for(i = cells.length - 1; i >= 0; --i){
-					headerPos = dojo.position(cells[i].getHeaderNode());
+					headerPos = html.position(cells[i].getHeaderNode());
 					edge = headerPos.x - viewPos.x;
 					if(edge < limit){
 						target = cells[i].index;
@@ -168,4 +174,8 @@ dojo.declare("dojox.grid.enhanced.plugins.AutoScroll", dojox.grid.enhanced._Plug
 		return target;
 	}
 });
-dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.AutoScroll/*name:'autoScroll'*/);
+
+EnhancedGrid.registerPlugin(AutoScroll);
+
+return AutoScroll;
+});
diff --git a/dojox/grid/enhanced/plugins/CellMerge.js b/dojox/grid/enhanced/plugins/CellMerge.js
index cc2accb..fd359fc 100644
--- a/dojox/grid/enhanced/plugins/CellMerge.js
+++ b/dojox/grid/enhanced/plugins/CellMerge.js
@@ -1,8 +1,13 @@
-dojo.provide("dojox.grid.enhanced.plugins.CellMerge");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/_base/html",
+	"../_Plugin",
+	"../../EnhancedGrid"
+], function(declare, array, lang, html, _Plugin, EnhancedGrid){
 
-dojo.require("dojox.grid.enhanced._Plugin");
-
-dojo.declare("dojox.grid.enhanced.plugins.CellMerge", dojox.grid.enhanced._Plugin, {
+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:
@@ -30,7 +35,7 @@ dojo.declare("dojox.grid.enhanced.plugins.CellMerge", dojox.grid.enhanced._Plugi
 		this.grid = grid;
 		this._records = [];
 		this._merged = {};
-		if(args && dojo.isObject(args)){
+		if(args && lang.isObject(args)){
 			this._setupConfig(args.mergedCells);
 		}
 		this._initEvents();
@@ -77,7 +82,7 @@ dojo.declare("dojox.grid.enhanced.plugins.CellMerge", dojox.grid.enhanced._Plugi
 		// mergeHandler: object
 		//		A handler for the merged cells created by a call of function mergeCells.
 		var idx;
-		if(mergeHandler && (idx = dojo.indexOf(this._records, mergeHandler)) >= 0){
+		if(mergeHandler && (idx = array.indexOf(this._records, mergeHandler)) >= 0){
 			this._records.splice(idx, 1);
 			this._updateRows(mergeHandler);
 		}
@@ -115,23 +120,23 @@ dojo.declare("dojox.grid.enhanced.plugins.CellMerge", dojox.grid.enhanced._Plugi
 	
 	//----------------Private--------------------------
 	_setupConfig: function(config){
-		dojo.forEach(config, this._createRecord, this);
+		array.forEach(config, this._createRecord, this);
 	},
 	_initEvents: function(){
-		dojo.forEach(this.grid.views.views, function(view){
-			this.connect(view, "onAfterRow", dojo.hitch(this, "_onAfterRow", view.index));
+		array.forEach(this.grid.views.views, function(view){
+			this.connect(view, "onAfterRow", lang.hitch(this, "_onAfterRow", view.index));
 		}, this);
 	},
 	_mixinGrid: function(){
 		var g = this.grid;
-		g.mergeCells = dojo.hitch(this, "mergeCells");
-		g.unmergeCells = dojo.hitch(this, "unmergeCells");
-		g.getMergedCells = dojo.hitch(this, "getMergedCells");
-		g.getMergedCellsByRow = dojo.hitch(this, "getMergedCellsByRow");
+		g.mergeCells = lang.hitch(this, "mergeCells");
+		g.unmergeCells = lang.hitch(this, "unmergeCells");
+		g.getMergedCells = lang.hitch(this, "getMergedCells");
+		g.getMergedCellsByRow = lang.hitch(this, "getMergedCellsByRow");
 	},
 	_getWidth: function(colIndex){
 		var node = this.grid.layout.cells[colIndex].getHeaderNode();
-		return dojo.position(node).w;
+		return html.position(node).w;
 	},
 	_onAfterRow: function(viewIdx, rowIndex, subrows){
 		try{
@@ -175,21 +180,21 @@ dojo.declare("dojox.grid.enhanced.plugins.CellMerge", dojox.grid.enhanced._Plugi
 				}
 			}
 			this._merged[rowIndex] = [];
-			dojo.forEach(result, function(res){
-				dojo.forEach(res.hiddenCells, function(node){
-					dojo.style(node, "display", "none");
+			array.forEach(result, function(res){
+				array.forEach(res.hiddenCells, function(node){
+					html.style(node, "display", "none");
 				});
-				var pbm = dojo.marginBox(res.majorHeaderNode).w - dojo.contentBox(res.majorHeaderNode).w;
+				var pbm = html.marginBox(res.majorHeaderNode).w - html.contentBox(res.majorHeaderNode).w;
 				var tw = res.totalWidth;
 				
 				//Tricky for WebKit.
-				if(!dojo.isWebKit){
+				if(!html.isWebKit){
 					tw -= pbm;
 				}
 				
-				dojo.style(res.majorNode, "width", tw + "px");
+				html.style(res.majorNode, "width", tw + "px");
 				//In case we're dealing with multiple subrows.
-				dojo.attr(res.majorNode, "colspan", res.hiddenCells.length + 1);
+				res.majorNode.setAttribute("colspan", res.hiddenCells.length + 1);
 	
 				this._merged[rowIndex].push({
 					"row": rowIndex,
@@ -232,7 +237,7 @@ dojo.declare("dojox.grid.enhanced.plugins.CellMerge", dojox.grid.enhanced._Plugi
 					return false;
 				};
 			}
-			if(dojo.isFunction(item.row)){
+			if(lang.isFunction(item.row)){
 				this._records.push(item);
 				return item;
 			}
@@ -242,7 +247,7 @@ dojo.declare("dojox.grid.enhanced.plugins.CellMerge", dojox.grid.enhanced._Plugi
 	_isValid: function(item){
 		var cells = this.grid.layout.cells,
 			colCount = cells.length;
-		return (dojo.isObject(item) && ("row" in item) && ("start" in item) && ("end" in item) &&
+		return (lang.isObject(item) && ("row" in item) && ("start" in item) && ("end" in item) &&
 			item.start >= 0 && item.start < colCount &&
 			item.end > item.start && item.end < colCount &&
 			cells[item.start].view.index == cells[item.end].view.index &&
@@ -263,4 +268,8 @@ dojo.declare("dojox.grid.enhanced.plugins.CellMerge", dojox.grid.enhanced._Plugi
 		}
 	}
 });
-dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.CellMerge/*name:'cellMerge'*/);
+
+EnhancedGrid.registerPlugin(CellMerge);
+
+return CellMerge;
+});
diff --git a/dojox/grid/enhanced/plugins/Cookie.js b/dojox/grid/enhanced/plugins/Cookie.js
index a5c0302..0f4a87e 100644
--- a/dojox/grid/enhanced/plugins/Cookie.js
+++ b/dojox/grid/enhanced/plugins/Cookie.js
@@ -1,11 +1,21 @@
-dojo.provide("dojox.grid.enhanced.plugins.Cookie");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/_base/sniff",
+	"dojo/_base/html",
+	"dojo/_base/json",
+	"dojo/_base/window",
+	"dojo/_base/unload",
+	"dojo/cookie",
+	"../_Plugin",
+	"../../_RowSelector",
+	"../../EnhancedGrid",
+	"../../cells/_base"
+], function(declare, array, lang, has, html, json, win, unload, cookie, _Plugin, _RowSelector, EnhancedGrid){
 
-dojo.require("dojox.grid.enhanced._Plugin");
-dojo.require("dojo.cookie");
-dojo.require("dojox.grid._RowSelector");
-dojo.require("dojox.grid.cells._base");
+	var gridCells = lang.getObject("dojox.grid.cells");
 
-(function(){
 	// Generate a cookie key for the given grid.
 	var _cookieKeyBuilder = function(grid){
 		return window.location + "/" + grid.id;
@@ -14,21 +24,21 @@ dojo.require("dojox.grid.cells._base");
 	//Utilities:
 	var _getCellsFromStructure = function(structure){
 		var cells = [];
-		if(!dojo.isArray(structure)){
+		if(!lang.isArray(structure)){
 			structure = [structure];
 		}
-		dojo.forEach(structure,function(viewDef){
-			if(dojo.isArray(viewDef)){
+		array.forEach(structure,function(viewDef){
+			if(lang.isArray(viewDef)){
 				viewDef = {"cells" : viewDef};
 			}
 			var rows = viewDef.rows || viewDef.cells;
-			if(dojo.isArray(rows)){
-				if(!dojo.isArray(rows[0])){
+			if(lang.isArray(rows)){
+				if(!lang.isArray(rows[0])){
 					rows = [rows];
 				}
-				dojo.forEach(rows, function(row){
-					if(dojo.isArray(row)){
-						dojo.forEach(row, function(cell){
+				array.forEach(rows, function(row){
+					if(lang.isArray(row)){
+						array.forEach(row, function(cell){
 							cells.push(cell);
 						});
 					}
@@ -40,7 +50,7 @@ dojo.require("dojox.grid.cells._base");
 	
 	// Persist column width
 	var _loadColWidth = function(colWidths, grid){
-		if(dojo.isArray(colWidths)){
+		if(lang.isArray(colWidths)){
 			var oldFunc = grid._setStructureAttr;
 			grid._setStructureAttr = function(structure){
 				if(!grid._colWidthLoaded){
@@ -49,6 +59,8 @@ dojo.require("dojox.grid.cells._base");
 					for(var i = cells.length - 1; i >= 0; --i){
 						if(typeof colWidths[i] == "number"){
 							cells[i].width = colWidths[i] + "px";
+						}else if(colWidths[i] == 'hidden'){
+							cells[i].hidden = true;
 						}
 					}
 				}
@@ -58,19 +70,20 @@ dojo.require("dojox.grid.cells._base");
 		}
 	};
 	
+
 	var _saveColWidth = function(grid){
-		return dojo.map(dojo.filter(grid.layout.cells, function(cell){
-			return !(cell.isRowSelector || cell instanceof dojox.grid.cells.RowIndex);
+		return array.map(array.filter(grid.layout.cells, function(cell){
+			return !(cell.isRowSelector || cell instanceof gridCells.RowIndex);
 		}), function(cell){
-			return dojo[dojo.isWebKit ? "marginBox" : "contentBox"](cell.getHeaderNode()).w;
+			return cell.hidden ? 'hidden' : html[has('webkit') ? "marginBox" : "contentBox"](cell.getHeaderNode()).w;
 		});
 	};
 	
 	// Persist column order
 	var _loadColumnOrder = function(colOrder, grid){
-		if(colOrder && dojo.every(colOrder, function(viewInfo){
-			return dojo.isArray(viewInfo) && dojo.every(viewInfo, function(subrowInfo){
-				return dojo.isArray(subrowInfo) && subrowInfo.length > 0;
+		if(colOrder && array.every(colOrder, function(viewInfo){
+			return lang.isArray(viewInfo) && array.every(viewInfo, function(subrowInfo){
+				return lang.isArray(subrowInfo) && subrowInfo.length > 0;
 			});
 		})){
 			var oldFunc = grid._setStructureAttr;
@@ -78,34 +91,34 @@ dojo.require("dojox.grid.cells._base");
 				return ("name" in def || "field" in def || "get" in def);
 			};
 			var isView = function(def){
-				return (def !== null && dojo.isObject(def) &&
+				return (def !== null && lang.isObject(def) &&
 						("cells" in def || "rows" in def || ("type" in def && !isCell(def))));
 			};
 			grid._setStructureAttr = function(structure){
 				if(!grid._colOrderLoaded){
 					grid._colOrderLoaded = true;
 					grid._setStructureAttr = oldFunc;
-					structure = dojo.clone(structure);
-					if(dojo.isArray(structure) && !dojo.some(structure, isView)){
+					structure = lang.clone(structure);
+					if(lang.isArray(structure) && !array.some(structure, isView)){
 						structure = [{ cells: structure }];
 					}else if(isView(structure)){
 						structure = [structure];
 					}
 					var cells = _getCellsFromStructure(structure);
-					dojo.forEach(dojo.isArray(structure) ? structure : [structure], function(viewDef, viewIdx){
+					array.forEach(lang.isArray(structure) ? structure : [structure], function(viewDef, viewIdx){
 						var cellArray = viewDef;
-						if(dojo.isArray(viewDef)){
+						if(lang.isArray(viewDef)){
 							viewDef.splice(0, viewDef.length);
 						}else{
 							delete viewDef.rows;
 							cellArray = viewDef.cells = [];
 						}
-						dojo.forEach(colOrder[viewIdx], function(subrow){
-							dojo.forEach(subrow, function(cellInfo){
+						array.forEach(colOrder[viewIdx], function(subrow){
+							array.forEach(subrow, function(cellInfo){
 								var i, cell;
 								for(i = 0; i < cells.length; ++i){
 									cell = cells[i];
-									if(dojo.toJson({'name':cell.name,'field':cell.field}) == dojo.toJson(cellInfo)){
+									if(json.toJson({'name':cell.name,'field':cell.field}) == json.toJson(cellInfo)){
 										break;
 									}
 								}
@@ -122,12 +135,12 @@ dojo.require("dojox.grid.cells._base");
 	};
 	
 	var _saveColumnOrder = function(grid){
-		var colOrder = dojo.map(dojo.filter(grid.views.views, function(view){
-			return !(view instanceof dojox.grid._RowSelector);
+		var colOrder = array.map(array.filter(grid.views.views, function(view){
+			return !(view instanceof _RowSelector);
 		}), function(view){
-			return dojo.map(view.structure.cells, function(subrow){
-				return dojo.map(dojo.filter(subrow, function(cell){
-					return !(cell.isRowSelector || cell instanceof dojox.grid.cells.RowIndex);
+			return array.map(view.structure.cells, function(subrow){
+				return array.map(array.filter(subrow, function(cell){
+					return !(cell.isRowSelector || cell instanceof gridCells.RowIndex);
 				}), function(cell){
 					return {
 						"name": cell.name,
@@ -142,7 +155,7 @@ dojo.require("dojox.grid.cells._base");
 	// Persist sorting order
 	var _loadSortOrder = function(sortOrder, grid){
 		try{
-			if(dojo.isObject(sortOrder)){
+			if(lang.isObject(sortOrder)){
 				grid.setSortIndex(sortOrder.idx, sortOrder.asc);
 			}
 		}catch(e){
@@ -158,19 +171,19 @@ dojo.require("dojox.grid.cells._base");
 		};
 	};
 	
-	if(!dojo.isIE){
+	if(!has('ie')){
 		// Now in non-IE, widgets are no longer destroyed on page unload,
 		// so we have to destroy it manually to trigger saving cookie.
-		dojo.addOnWindowUnload(function(){
-			dojo.forEach(dijit.findWidgets(dojo.body()), function(widget){
-				if(widget instanceof dojox.grid.EnhancedGrid && !widget._destroyed){
+		unload.addOnWindowUnload(function(){
+			array.forEach(dijit.findWidgets(win.body()), function(widget){
+				if(widget instanceof EnhancedGrid && !widget._destroyed){
 					widget.destroyRecursive();
 				}
 			});
 		});
 	}
 	
-	dojo.declare("dojox.grid.enhanced.plugins.Cookie", dojox.grid.enhanced._Plugin, {
+	var Cookie = declare("dojox.grid.enhanced.plugins.Cookie", _Plugin, {
 		// summary:
 		//		This plugin provides a way to persist some grid features in cookie.
 		//		Default persistable features are:
@@ -198,7 +211,7 @@ dojo.require("dojox.grid.cells._base");
 		
 		constructor: function(grid, args){
 			this.grid = grid;
-			args = (args && dojo.isObject(args)) ? args : {};
+			args = (args && lang.isObject(args)) ? args : {};
 			this.cookieProps = args.cookieProps;
 			this._cookieHandlers = [];
 			this._mixinGrid();
@@ -220,7 +233,7 @@ dojo.require("dojox.grid.cells._base");
 				onSave: _saveSortOrder
 			});
 			
-			dojo.forEach(this._cookieHandlers, function(handler){
+			array.forEach(this._cookieHandlers, function(handler){
 				if(args[handler.name] === false){
 					handler.enable = false;
 				}
@@ -233,25 +246,25 @@ dojo.require("dojox.grid.cells._base");
 		},
 		_mixinGrid: function(){
 			var g = this.grid;
-			g.addCookieHandler = dojo.hitch(this, "addCookieHandler");
-			g.removeCookie = dojo.hitch(this, "removeCookie");
-			g.setCookieEnabled = dojo.hitch(this, "setCookieEnabled");
-			g.getCookieEnabled = dojo.hitch(this, "getCookieEnabled");
+			g.addCookieHandler = lang.hitch(this, "addCookieHandler");
+			g.removeCookie = lang.hitch(this, "removeCookie");
+			g.setCookieEnabled = lang.hitch(this, "setCookieEnabled");
+			g.getCookieEnabled = lang.hitch(this, "getCookieEnabled");
 		},
 		_saveCookie: function(){
 			if(this.getCookieEnabled()){
-				var cookie = {},
+				var ck = {},
 					chs = this._cookieHandlers,
 					cookieProps = this.cookieProps,
 					cookieKey = _cookieKeyBuilder(this.grid);
 				for(var i = chs.length-1; i >= 0; --i){
 					if(chs[i].enabled){
 						//Do the real saving work here.
-						cookie[chs[i].name] = chs[i].onSave(this.grid);
+						ck[chs[i].name] = chs[i].onSave(this.grid);
 					}
 				}
-				cookieProps = dojo.isObject(this.cookieProps) ? this.cookieProps : {};
-				dojo.cookie(cookieKey, dojo.toJson(cookie), cookieProps);
+				cookieProps = lang.isObject(this.cookieProps) ? this.cookieProps : {};
+				cookie(cookieKey, json.toJson(ck), cookieProps);
 			}else{
 				this.removeCookie();
 			}
@@ -260,17 +273,17 @@ dojo.require("dojox.grid.cells._base");
 			var grid = this.grid,
 				chs = this._cookieHandlers,
 				cookieKey = _cookieKeyBuilder(grid),
-				cookie = dojo.cookie(cookieKey);
-			if(cookie){
-				cookie = dojo.fromJson(cookie);
+				ck = cookie(cookieKey);
+			if(ck){
+				ck = json.fromJson(ck);
 				for(var i = 0; i < chs.length; ++i){
-					if(chs[i].name in cookie && chs[i].enabled){
+					if(chs[i].name in ck && chs[i].enabled){
 						//Do the real loading work here.
-						chs[i].onLoad(cookie[chs[i].name], grid);
+						chs[i].onLoad(ck[chs[i].name], grid);
 					}
 				}
 			}
-			this._cookie = cookie || {};
+			this._cookie = ck || {};
 			this._cookieStartedup = true;
 		},
 		addCookieHandler: function(args){
@@ -306,7 +319,7 @@ dojo.require("dojox.grid.cells._base");
 			// summary:
 			//		Remove cookie for this grid.
 			var key = _cookieKeyBuilder(this.grid);
-			dojo.cookie(key, null, {expires: -1});
+			cookie(key, null, {expires: -1});
 		},
 		setCookieEnabled: function(cookieName, enabled){
 			// summary:
@@ -314,7 +327,7 @@ dojo.require("dojox.grid.cells._base");
 			// cookieName: String?
 			//		Name of a cookie handler if provided, otherwise for all cookies.
 			// enabled: Boolean
-			if(arguments.length == 2){
+			if(typeof cookieName == 'string'){
 				var chs = this._cookieHandlers;
 				for(var i = chs.length - 1; i >= 0; --i){
 					if(chs[i].name === cookieName){
@@ -331,7 +344,7 @@ dojo.require("dojox.grid.cells._base");
 			//		A getter to check cookie support of a particular Grid feature.
 			// cookieName: String?
 			//		Name of a cookie handler if provided, otherwise for all cookies.
-			if(dojo.isString(cookieName)){
+			if(lang.isString(cookieName)){
 				var chs = this._cookieHandlers;
 				for(var i = chs.length - 1; i >= 0; --i){
 					if(chs[i].name == cookieName){ return chs[i].enabled; }
@@ -341,5 +354,8 @@ dojo.require("dojox.grid.cells._base");
 			return this._cookieEnabled;
 		}
 	});
-	dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Cookie/*name:'cookie'*/, {"preInit": true});
-})();
+
+	EnhancedGrid.registerPlugin(Cookie, {"preInit": true});
+
+	return Cookie;
+});
diff --git a/dojox/grid/enhanced/plugins/Dialog.js b/dojox/grid/enhanced/plugins/Dialog.js
index d7e4053..a8c9b8a 100644
--- a/dojox/grid/enhanced/plugins/Dialog.js
+++ b/dojox/grid/enhanced/plugins/Dialog.js
@@ -1,34 +1,39 @@
-dojo.provide("dojox.grid.enhanced.plugins.Dialog");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/html",
+	"dojo/window",
+	"dijit/Dialog"
+], function(declare, html, win, Dialog){
 
-dojo.require("dijit.Dialog");
-dojo.require("dojo.window");
-
-dojo.declare("dojox.grid.enhanced.plugins.Dialog", dijit.Dialog, {
+return declare("dojox.grid.enhanced.plugins.Dialog", Dialog, {
 	refNode: null,
 	_position: function(){
 		if(this.refNode && !this._relativePosition){
-			var refPos = dojo.position(dojo.byId(this.refNode)),
-				thisPos = dojo.position(this.domNode),
-				viewPort = dojo.window.getBox();
-			if(refPos.x < 0){
-				refPos.x = 0;
-			}
-			if(refPos.x + refPos.w > viewPort.w){
-				refPos.w = viewPort.w - refPos.x;
-			}
-			if(refPos.y < 0){
-				refPos.y = 0;
-			}
-			if(refPos.y + refPos.h > viewPort.h){
-				refPos.h = viewPort.h - refPos.y;
-			}
-			refPos.x = refPos.x + refPos.w / 2 - thisPos.w / 2;
-			refPos.y = refPos.y + refPos.h / 2 - thisPos.h / 2;
-			if(refPos.x >= 0 && refPos.x + thisPos.w <= viewPort.w &&
-				refPos.y >= 0 && refPos.y + thisPos.h <= viewPort.h){
-				this._relativePosition = refPos;
+			var refPos = html.position(html.byId(this.refNode)),
+				thisPos = html.position(this.domNode),
+				viewPort = win.getBox();
+			if(thisPos.w && thisPos.h){
+				if(refPos.x < 0){
+					refPos.x = 0;
+				}
+				if(refPos.x + refPos.w > viewPort.w){
+					refPos.w = viewPort.w - refPos.x;
+				}
+				if(refPos.y < 0){
+					refPos.y = 0;
+				}
+				if(refPos.y + refPos.h > viewPort.h){
+					refPos.h = viewPort.h - refPos.y;
+				}
+				refPos.x = refPos.x + refPos.w / 2 - thisPos.w / 2;
+				refPos.y = refPos.y + refPos.h / 2 - thisPos.h / 2;
+				if(refPos.x >= 0 && refPos.x + thisPos.w <= viewPort.w &&
+					refPos.y >= 0 && refPos.y + thisPos.h <= viewPort.h){
+					this._relativePosition = refPos;
+				}
 			}
 		}
 		this.inherited(arguments);
 	}
 });
+});
diff --git a/dojox/grid/enhanced/plugins/DnD.js b/dojox/grid/enhanced/plugins/DnD.js
index 65d6150..12133ee 100644
--- a/dojox/grid/enhanced/plugins/DnD.js
+++ b/dojox/grid/enhanced/plugins/DnD.js
@@ -1,12 +1,23 @@
-dojo.provide("dojox.grid.enhanced.plugins.DnD");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/connect",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/_base/html",
+	"dojo/_base/json",
+	"dojo/_base/window",
+	"dojo/query",
+	"dojo/keys",
+	"dojo/dnd/Source",
+	"dojo/dnd/Avatar",
+	"../_Plugin",
+	"../../EnhancedGrid",
+	"./Selector",
+	"./Rearrange",
+	"dojo/dnd/Manager"
+], function(dojo, declare, connect, array, lang, html, json, win, query, keys, Source, Avatar, _Plugin, EnhancedGrid){
 
-dojo.require("dojox.grid.enhanced._Plugin");
-dojo.require("dojox.grid.enhanced.plugins.Selector");
-dojo.require("dojox.grid.enhanced.plugins.Rearrange");
-dojo.require("dojo.dnd.move");
-dojo.require("dojo.dnd.Source");
-
-(function(){
 var _devideToArrays = function(a){
 		a.sort(function(v1, v2){
 			return v1 - v2;
@@ -28,7 +39,206 @@ var _devideToArrays = function(a){
 		}
 		return a;
 	};
-dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
+var GridDnDElement = declare("dojox.grid.enhanced.plugins.GridDnDElement", null, {
+	constructor: function(dndPlugin){
+		this.plugin = dndPlugin;
+		this.node = html.create("div");
+		this._items = {};
+	},
+	destroy: function(){
+		this.plugin = null;
+		html.destroy(this.node);
+		this.node = null;
+		this._items = null;
+	},
+	createDnDNodes: function(dndRegion){
+		this.destroyDnDNodes();
+		var acceptType = ["grid/" + dndRegion.type + "s"];
+		var itemNodeIdBase = this.plugin.grid.id + "_dndItem";
+		array.forEach(dndRegion.selected, function(range, i){
+			var id = itemNodeIdBase + i;
+			this._items[id] = {
+				"type": acceptType,
+				"data": range,
+				"dndPlugin": this.plugin
+			};
+			this.node.appendChild(html.create("div", {
+				"id": id
+			}));
+		}, this);
+	},
+	getDnDNodes: function(){
+		return array.map(this.node.childNodes, function(node){
+			return node;
+		});
+	},
+	destroyDnDNodes: function(){
+		html.empty(this.node);
+		this._items = {};
+	},
+	getItem: function(nodeId){
+		return this._items[nodeId];
+	}
+});
+var GridDnDSource = declare("dojox.grid.enhanced.plugins.GridDnDSource", Source,{
+	accept: ["grid/cells", "grid/rows", "grid/cols"],
+	constructor: function(node, param){
+		this.grid = param.grid;
+		this.dndElem = param.dndElem;
+		this.dndPlugin = param.dnd;
+		this.sourcePlugin = null;
+	},
+	destroy: function(){
+		this.inherited(arguments);
+		this.grid = null;
+		this.dndElem = null;
+		this.dndPlugin = null;
+		this.sourcePlugin = null;
+	},
+	getItem: function(nodeId){
+		return this.dndElem.getItem(nodeId);
+	},
+	checkAcceptance: function(source, nodes){
+		if(this != source && nodes[0]){
+			var item = source.getItem(nodes[0].id);
+			if(item.dndPlugin){
+				var type = item.type;
+				for(var j = 0; j < type.length; ++j){
+					if(type[j] in this.accept){
+						if(this.dndPlugin._canAccept(item.dndPlugin)){
+							this.sourcePlugin = item.dndPlugin;
+						}else{
+							return false;
+						}
+						break;
+					}
+				}
+			}else if("grid/rows" in this.accept){
+				var rows = [];
+				array.forEach(nodes, function(node){
+					var item = source.getItem(node.id);
+					if(item.data && array.indexOf(item.type, "grid/rows") >= 0){
+						var rowData = item.data;
+						if(typeof item.data == "string"){
+							rowData = json.fromJson(item.data);
+						}
+						if(rowData){
+							rows.push(rowData);
+						}
+					}
+				});
+				if(rows.length){
+					this.sourcePlugin = {
+						_dndRegion: {
+							type: "row",
+							selected: [rows]
+						}
+					};
+				}else{
+					return false;
+				}
+			}
+		}
+		return this.inherited(arguments);
+	},
+	onDraggingOver: function(){
+		this.dndPlugin.onDraggingOver(this.sourcePlugin);
+	},
+	onDraggingOut: function(){
+		this.dndPlugin.onDraggingOut(this.sourcePlugin);
+	},
+	onDndDrop: function(source, nodes, copy, target){
+		//this.inherited(arguments);
+		this.onDndCancel();
+		if(this != source && this == target){
+			this.dndPlugin.onDragIn(this.sourcePlugin, copy);
+		}
+	}
+});
+
+var GridDnDAvatar = declare("dojox.grid.enhanced.plugins.GridDnDAvatar", Avatar, {
+	construct: function(){
+		// summary:
+		//		constructor function;
+		//		it is separate so it can be (dynamically) overwritten in case of need
+		this._itemType = this.manager._dndPlugin._dndRegion.type;
+		this._itemCount = this._getItemCount();
+			
+		this.isA11y = html.hasClass(win.body(), "dijit_a11y");
+		var a = html.create("table", {
+				"border": "0",
+				"cellspacing": "0",
+				"class": "dojoxGridDndAvatar",
+				"style": {
+					position: "absolute",
+					zIndex: "1999",
+					margin: "0px"
+				}
+			}),
+			source = this.manager.source,
+			b = html.create("tbody", null, a),
+			tr = html.create("tr", null, b),
+			td = html.create("td", {
+				"class": "dojoxGridDnDIcon"
+			}, tr);
+		if(this.isA11y){
+			html.create("span", {
+				"id" : "a11yIcon",
+				"innerHTML" : this.manager.copy ? '+' : "<"
+			}, td);
+		}
+		td = html.create("td", {
+			"class" : "dojoxGridDnDItemIcon " + this._getGridDnDIconClass()
+		}, tr);
+		td = html.create("td", null, tr);
+		html.create("span", {
+			"class": "dojoxGridDnDItemCount",
+			"innerHTML": source.generateText ? this._generateText() : ""
+		}, td);
+		// we have to set the opacity on IE only after the node is live
+		html.style(tr, {
+			"opacity": 0.9
+		});
+		this.node = a;
+	},
+	_getItemCount: function(){
+		var selected = this.manager._dndPlugin._dndRegion.selected,
+			count = 0;
+		switch(this._itemType){
+			case "cell":
+				selected = selected[0];
+				var cells = this.manager._dndPlugin.grid.layout.cells,
+					colCount = selected.max.col - selected.min.col + 1,
+					rowCount = selected.max.row - selected.min.row + 1;
+				if(colCount > 1){
+					for(var i = selected.min.col; i <= selected.max.col; ++i){
+						if(cells[i].hidden){
+							--colCount;
+						}
+					}
+				}
+				count = colCount * rowCount;
+				break;
+			case "row":
+			case "col":
+				count = _joinToArray(selected).length;
+		}
+		return count;
+	},
+	_getGridDnDIconClass: function(){
+		return {
+			"row": ["dojoxGridDnDIconRowSingle", "dojoxGridDnDIconRowMulti"],
+			"col": ["dojoxGridDnDIconColSingle", "dojoxGridDnDIconColMulti"],
+			"cell": ["dojoxGridDnDIconCellSingle", "dojoxGridDnDIconCellMulti"]
+		}[this._itemType][this._itemCount == 1 ? 0 : 1];
+	},
+	_generateText: function(){
+		// summary:
+		//		generates a proper text to reflect copying or moving of items
+		return "(" + this._itemCount + ")";
+	}
+});
+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.
@@ -65,8 +275,8 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 	},
 	constructor: function(grid, args){
 		this.grid = grid;
-		this._config = dojo.clone(this._config);
-		args = dojo.isObject(args) ? args : {};
+		this._config = lang.clone(this._config);
+		args = lang.isObject(args) ? args : {};
 		this.setupConfig(args.dndConfig);
 		this._copyOnly = !!args.copyOnly;
 		
@@ -79,13 +289,13 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 		
 		//Initialized the components we need.
 		this._clear();
-		this._elem = new dojox.grid.enhanced.plugins.GridDnDElement(this);
-		this._source = new dojox.grid.enhanced.plugins.GridDnDSource(this._elem.node, {
+		this._elem = new GridDnDElement(this);
+		this._source = new GridDnDSource(this._elem.node, {
 			"grid": grid,
 			"dndElem": this._elem,
 			"dnd": this
 		});
-		this._container = dojo.query(".dojoxGridMasterView", this.grid.domNode)[0];
+		this._container = query(".dojoxGridMasterView", this.grid.domNode)[0];
 		this._initEvents();
 	},
 	destroy: function(){
@@ -102,8 +312,8 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 	_mixinGrid: function(){
 		// summary:
 		//		Provide APIs for grid.
-		this.grid.setupDnDConfig = dojo.hitch(this, "setupConfig");
-		this.grid.dndCopyOnly = dojo.hitch(this, "copyOnly");
+		this.grid.setupDnDConfig = lang.hitch(this, "setupConfig");
+		this.grid.dndCopyOnly = lang.hitch(this, "copyOnly");
 	},
 	setupConfig: function(config){
 		// summary:
@@ -152,37 +362,37 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 		//	|			"within": true
 		//	|		}
 		//	|	});
-		if(config && dojo.isObject(config)){
+		if(config && lang.isObject(config)){
 			var firstLevel = ["row", "col", "cell"],
 				secondLevel = ["within", "in", "out"],
 				cfg = this._config;
-			dojo.forEach(firstLevel, function(type){
+			array.forEach(firstLevel, function(type){
 				if(type in config){
 					var t = config[type];
-					if(t && dojo.isObject(t)){
-						dojo.forEach(secondLevel, function(mode){
+					if(t && lang.isObject(t)){
+						array.forEach(secondLevel, function(mode){
 							if(mode in t){
 								cfg[type][mode] = !!t[mode];
 							}
 						});
 					}else{
-						dojo.forEach(secondLevel, function(mode){
+						array.forEach(secondLevel, function(mode){
 							cfg[type][mode] = !!t;
 						});
 					}
 				}
 			});
-			dojo.forEach(secondLevel, function(mode){
+			array.forEach(secondLevel, function(mode){
 				if(mode in config){
 					var m = config[mode];
-					if(m && dojo.isObject(m)){
-						dojo.forEach(firstLevel, function(type){
+					if(m && lang.isObject(m)){
+						array.forEach(firstLevel, function(type){
 							if(type in m){
 								cfg[type][mode] = !!m[type];
 							}
 						});
 					}else{
-						dojo.forEach(firstLevel, function(type){
+						array.forEach(firstLevel, function(type){
 							cfg[type][mode] = !!m;
 						});
 					}
@@ -199,7 +409,7 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 		return this._copyOnly;
 	},
 	_isOutOfGrid: function(evt){
-		var gridPos = dojo.position(this.grid.domNode), x = evt.clientX, y = evt.clientY;
+		var gridPos = html.position(this.grid.domNode), x = evt.clientX, y = evt.clientY;
 		return y < gridPos.y || y > gridPos.y + gridPos.h ||
 			x < gridPos.x || x > gridPos.x + gridPos.w;
 	},
@@ -210,8 +420,8 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 		}else{
 			if(this._isMouseDown && !this._dndRegion){
 				delete this._isMouseDown;
-				this._oldCursor = dojo.style(dojo.body(), "cursor");
-				dojo.style(dojo.body(), "cursor", "not-allowed");
+				this._oldCursor = html.style(win.body(), "cursor");
+				html.style(win.body(), "cursor", "not-allowed");
 			}
 			//TODO: should implement as mouseenter/mouseleave
 			//But we have an avatar under mouse when dnd, and this will cause a lot of mouseenter in FF.
@@ -241,13 +451,13 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 			}
 			this._endDnd(isInner);
 		}
-		dojo.style(dojo.body(), "cursor", this._oldCursor || "");
+		html.style(win.body(), "cursor", this._oldCursor || "");
 		delete this._isMouseDown;
 	},
 	_initEvents: function(){
 		var g = this.grid, s = this.selector;
-		this.connect(dojo.doc, "onmousemove", "_onMouseMove");
-		this.connect(dojo.doc, "onmouseup", "_onMouseUp");
+		this.connect(win.doc, "onmousemove", "_onMouseMove");
+		this.connect(win.doc, "onmouseup", "_onMouseUp");
 		
 		this.connect(g, "onCellMouseOver", function(evt){
 			if(!this._dnding && !s.isSelecting() && !evt.ctrlKey){
@@ -287,16 +497,16 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 				this._markTargetAnchor(evt);
 			}
 		});
-		this.connect(dojo.doc, "onkeydown", function(evt){
-			if(evt.keyCode == dojo.keys.ESCAPE){
+		this.connect(win.doc, "onkeydown", function(evt){
+			if(evt.keyCode == keys.ESCAPE){
 				this._endDnd(false);
-			}else if(evt.keyCode == dojo.keys.CTRL){
+			}else if(evt.keyCode == keys.CTRL){
 				s.selectEnabled(true);
 				this._isCopy = true;
 			}
 		});
-		this.connect(dojo.doc, "onkeyup", function(evt){
-			if(evt.keyCode == dojo.keys.CTRL){
+		this.connect(win.doc, "onkeyup", function(evt){
+			if(evt.keyCode == keys.CTRL){
 				s.selectEnabled(!this._dndReady);
 				this._isCopy = false;
 			}
@@ -349,7 +559,7 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 						}
 					};
 				
-				dojo.forEach(selected[type], function(item){
+				array.forEach(selected[type], function(item){
 					if(item.row < range.min.row){
 						range.min.row = item.row;
 					}
@@ -363,10 +573,10 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 						range.max.col = item.col;
 					}
 				});
-				if(dojo.some(selected[type], function(item){
+				if(array.some(selected[type], function(item){
 					return item.row == rowIndex && item.col == colIndex;
 				})){
-					if(getCount(range) == selected[type].length && dojo.every(selected[type], function(item){
+					if(getCount(range) == selected[type].length && array.every(selected[type], function(item){
 						return inRange(item, range);
 					})){
 						return {
@@ -407,16 +617,16 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 	_createDnDUI: function(evt, isMovingIn){
 		//By default the master view of grid do not have height, because the children in it are all positioned absolutely.
 		//But we need it to contain avatars.
-		var viewPos = dojo.position(this.grid.views.views[0].domNode);
-		dojo.style(this._container, "height", viewPos.h + "px");
+		var viewPos = html.position(this.grid.views.views[0].domNode);
+		html.style(this._container, "height", viewPos.h + "px");
 		try{
 			//If moving in from out side, dnd source is already created.
 			if(!isMovingIn){
 				this._createSource(evt);
 			}
 			this._createMoveable(evt);
-			this._oldCursor = dojo.style(dojo.body(), "cursor");
-			dojo.style(dojo.body(), "cursor", "default");
+			this._oldCursor = html.style(win.body(), "cursor");
+			html.style(win.body(), "cursor", "default");
 		}catch(e){
 			console.warn("DnD._createDnDUI() error:", e);
 		}
@@ -430,7 +640,7 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 			if(!isMovingOut){
 				this._destroyMoveable();
 			}
-			dojo.style(dojo.body(), "cursor", this._oldCursor);
+			html.style(win.body(), "cursor", this._oldCursor);
 		}catch(e){
 			console.warn("DnD._destroyDnDUI() error:", this.grid.id, e);
 		}
@@ -441,7 +651,7 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 		var oldMakeAvatar = m.makeAvatar;
 		m._dndPlugin = this;
 		m.makeAvatar = function(){
-			var avatar = new dojox.grid.enhanced.plugins.GridDnDAvatar(m);
+			var avatar = new GridDnDAvatar(m);
 			delete m._dndPlugin;
 			return avatar;
 		};
@@ -450,12 +660,11 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 		m.onMouseMove(evt);
 	},
 	_destroySource: function(){
-		dojo.publish("/dnd/cancel");
-		this._elem.destroyDnDNodes();
+		connect.publish("/dnd/cancel");
 	},
 	_createMoveable: function(evt){
 		if(!this._markTagetAnchorHandler){
-			this._markTagetAnchorHandler = this.connect(dojo.doc, "onmousemove", "_markTargetAnchor");
+			this._markTagetAnchorHandler = this.connect(win.doc, "onmousemove", "_markTargetAnchor");
 		}
 	},
 	_destroyMoveable: function(){
@@ -467,10 +676,10 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 		//		Calculate the position of the column DnD avatar
 		var i, headPos, left, target, ex = evt.clientX,
 			cells = this.grid.layout.cells,
-			ltr = dojo._isBodyLtr(),
+			ltr = html._isBodyLtr(),
 			headers = this._getVisibleHeaders();
 		for(i = 0; i < headers.length; ++i){
-			headPos = dojo.position(headers[i].node);
+			headPos = html.position(headers[i].node);
 			if(ltr ? ((i === 0 || ex >= headPos.x) && ex < headPos.x + headPos.w) :
 				((i === 0 || ex < headPos.x + headPos.w) && ex >= headPos.x)){
 				left = headPos.x + (ltr ? 0 : headPos.w);
@@ -487,9 +696,9 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 			if(this.selector.isSelected("col", target) && this.selector.isSelected("col", target - 1)){
 				var ranges = this._dndRegion.selected;
 				for(i = 0; i < ranges.length; ++i){
-					if(dojo.indexOf(ranges[i], target) >= 0){
+					if(array.indexOf(ranges[i], target) >= 0){
 						target = ranges[i][0];
-						headPos = dojo.position(cells[target].getHeaderNode());
+						headPos = html.position(cells[target].getHeaderNode());
 						left = headPos.x + (ltr ? 0 : headPos.w);
 						break;
 					}
@@ -509,20 +718,27 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 		while(cells[i].hidden){ ++i; }
 		var cell = g.layout.cells[i],
 			rowIndex = g.scroller.firstVisibleRow,
-			nodePos = dojo.position(cell.getNode(rowIndex));
+			cellNode = cell.getNode(rowIndex);
+		if(!cellNode){
+			//if the target grid is empty, set to -1 
+			//which will be processed in Rearrange
+		    this._target = -1;
+		    return 0; //position of the insert bar
+		}
+		var nodePos = html.position(cellNode);
 		while(nodePos.y + nodePos.h < evt.clientY){
 			if(++rowIndex >= g.rowCount){
 				break;
 			}
-			nodePos = dojo.position(cell.getNode(rowIndex));
+			nodePos = html.position(cell.getNode(rowIndex));
 		}
 		if(rowIndex < g.rowCount){
 			if(this.selector.isSelected("row", rowIndex) && this.selector.isSelected("row", rowIndex - 1)){
 				var ranges = this._dndRegion.selected;
 				for(i = 0; i < ranges.length; ++i){
-					if(dojo.indexOf(ranges[i], rowIndex) >= 0){
+					if(array.indexOf(ranges[i], rowIndex) >= 0){
 						rowIndex = ranges[i][0];
-						nodePos = dojo.position(cell.getNode(rowIndex));
+						nodePos = html.position(cell.getNode(rowIndex));
 						break;
 					}
 				}
@@ -539,7 +755,7 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 		//		Calculate the position of the cell DnD avatar
 		var s = this._dndRegion.selected[0],
 			origin = this._dndRegion.handle,
-			g = this.grid, ltr = dojo._isBodyLtr(),
+			g = this.grid, ltr = html._isBodyLtr(),
 			cells = g.layout.cells, headPos,
 			minPos, maxPos, headers,
 			height, width, left, top,
@@ -548,15 +764,15 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 			postSpan = s.max.col - origin.col,
 			leftTopDiv, rightBottomDiv;
 		if(!targetAnchor.childNodes.length){
-			leftTopDiv = dojo.create("div", {
+			leftTopDiv = html.create("div", {
 				"class": "dojoxGridCellBorderLeftTopDIV"
 			}, targetAnchor);
-			rightBottomDiv = dojo.create("div", {
+			rightBottomDiv = html.create("div", {
 				"class": "dojoxGridCellBorderRightBottomDIV"
 			}, targetAnchor);
 		}else{
-			leftTopDiv = dojo.query(".dojoxGridCellBorderLeftTopDIV", targetAnchor)[0];
-			rightBottomDiv = dojo.query(".dojoxGridCellBorderRightBottomDIV", targetAnchor)[0];
+			leftTopDiv = query(".dojoxGridCellBorderLeftTopDIV", targetAnchor)[0];
+			rightBottomDiv = query(".dojoxGridCellBorderRightBottomDIV", targetAnchor)[0];
 		}
 		for(i = s.min.col + 1; i < origin.col; ++i){
 			if(cells[i].hidden){
@@ -571,7 +787,7 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 		headers = this._getVisibleHeaders();
 		//calc width
 		for(i = preSpan; i < headers.length - postSpan; ++i){
-			headPos = dojo.position(headers[i].node);
+			headPos = html.position(headers[i].node);
 			if((evt.clientX >= headPos.x && evt.clientX < headPos.x + headPos.w) || //within in this column
 				//prior to this column, but within range
 				(i == preSpan && (ltr ? evt.clientX < headPos.x : evt.clientX >= headPos.x + headPos.w)) ||
@@ -579,8 +795,8 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 				(i == headers.length - postSpan - 1 && (ltr ? evt.clientX >= headPos.x + headPos.w : evt < headPos.x))){
 					minCol = headers[i - preSpan];
 					maxCol = headers[i + postSpan];
-					minPos = dojo.position(minCol.node);
-					maxPos = dojo.position(maxCol.node);
+					minPos = html.position(minCol.node);
+					maxPos = html.position(maxCol.node);
 					minCol = minCol.cell.index;
 					maxCol = maxCol.cell.index;
 					left = ltr ? minPos.x : maxPos.x;
@@ -593,10 +809,10 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 		while(cells[i].hidden){ ++i; }
 		var cell = cells[i],
 			rowIndex = g.scroller.firstVisibleRow,
-			nodePos = dojo.position(cell.getNode(rowIndex));
+			nodePos = html.position(cell.getNode(rowIndex));
 		while(nodePos.y + nodePos.h < evt.clientY){
 			if(++rowIndex < g.rowCount){
-				nodePos = dojo.position(cell.getNode(rowIndex));
+				nodePos = html.position(cell.getNode(rowIndex));
 			}else{
 				break;
 			}
@@ -607,8 +823,8 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 			maxRow = g.rowCount - 1;
 			minRow = maxRow - s.max.row + s.min.row;
 		}
-		minPos = dojo.position(cell.getNode(minRow));
-		maxPos = dojo.position(cell.getNode(maxRow));
+		minPos = html.position(cell.getNode(minRow));
+		maxPos = html.position(cell.getNode(maxRow));
 		top = minPos.y;
 		height = maxPos.y + maxPos.h - minPos.y;
 		this._target = {
@@ -621,14 +837,14 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 				"col": maxCol
 			}
 		};
-		var anchorBorderSize = (dojo.marginBox(leftTopDiv).w - dojo.contentBox(leftTopDiv).w) / 2;
-		var leftTopCellPos = dojo.position(cells[minCol].getNode(minRow));
-		dojo.style(leftTopDiv, {
+		var anchorBorderSize = (html.marginBox(leftTopDiv).w - html.contentBox(leftTopDiv).w) / 2;
+		var leftTopCellPos = html.position(cells[minCol].getNode(minRow));
+		html.style(leftTopDiv, {
 			"width": (leftTopCellPos.w - anchorBorderSize) + "px",
 			"height": (leftTopCellPos.h - anchorBorderSize) + "px"
 		});
-		var rightBottomCellPos = dojo.position(cells[maxCol].getNode(maxRow));
-		dojo.style(rightBottomDiv, {
+		var rightBottomCellPos = html.position(cells[maxCol].getNode(maxRow));
+		html.style(rightBottomDiv, {
 			"width": (rightBottomCellPos.w - anchorBorderSize) + "px",
 			"height": (rightBottomCellPos.h - anchorBorderSize) + "px"
 		});
@@ -647,12 +863,12 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 		}
 		var height, width, left, top,
 			targetAnchor = this._targetAnchor[t],
-			pos = dojo.position(this._container);
+			pos = html.position(this._container);
 		if(!targetAnchor){
-			targetAnchor = this._targetAnchor[t] = dojo.create("div", {
+			targetAnchor = this._targetAnchor[t] = html.create("div", {
 				"class": (t == "cell") ? "dojoxGridCellBorderDIV" : "dojoxGridBorderDIV"
 			});
-			dojo.style(targetAnchor, "display", "none");
+			html.style(targetAnchor, "display", "none");
 			this._container.appendChild(targetAnchor);
 		}
 		switch(t){
@@ -676,13 +892,13 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 				top = cellPos.t;
 		}
 		if(typeof height == "number" && typeof width == "number" && typeof left == "number" && typeof top == "number"){
-			dojo.style(targetAnchor, {
+			html.style(targetAnchor, {
 				"height": height + "px",
 				"width": width + "px",
 				"left": left + "px",
 				"top": top + "px"
 			});
-			dojo.style(targetAnchor, "display", "");
+			html.style(targetAnchor, "display", "");
 		}else{
 			this._target = null;
 		}
@@ -694,12 +910,12 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 		if(this._dndRegion){
 			var targetAnchor = this._targetAnchor[this._dndRegion.type];
 			if(targetAnchor){
-				dojo.style(this._targetAnchor[this._dndRegion.type], "display", "none");
+				html.style(this._targetAnchor[this._dndRegion.type], "display", "none");
 			}
 		}
 	},
 	_getVisibleHeaders: function(){
-		return dojo.map(dojo.filter(this.grid.layout.cells, function(cell){
+		return array.map(array.filter(this.grid.layout.cells, function(cell){
 			return !cell.hidden;
 		}), function(cell){
 			return {
@@ -715,9 +931,9 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 		var t = this._dndRegion.type;
 		var ranges = this._dndRegion.selected;
 		if(t === "cell"){
-			this.rearranger[(this._isCopy || this._copyOnly) ? "copyCells" : "moveCells"](ranges[0], this._target);
+			this.rearranger[(this._isCopy || this._copyOnly) ? "copyCells" : "moveCells"](ranges[0], this._target === -1 ? null : this._target);
 		}else{
-			this.rearranger[t == "col" ? "moveColumns" : "moveRows"](_joinToArray(ranges), this._target);
+			this.rearranger[t == "col" ? "moveColumns" : "moveRows"](_joinToArray(ranges), this._target === -1 ? null: this._target);
 		}
 		this._target = null;
 	},
@@ -749,7 +965,7 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 					--cnt;
 				}
 			}
-			var region = dojo.clone(dndRegion);
+			var region = lang.clone(dndRegion);
 			region.selected[0].min.col = 0;
 			region.selected[0].max.col = c - 1;
 			for(c = srcRange.min.col; c <= dndRegion.handle.col; ++c){
@@ -822,7 +1038,7 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 		}
 		var g = this.grid;
 		var ranges = srcRegion.selected;
-		var colCnt = dojo.filter(g.layout.cells, function(cell){
+		var colCnt = array.filter(g.layout.cells, function(cell){
 			return !cell.hidden;
 		}).length;
 		var rowCnt = g.rowCount;
@@ -832,7 +1048,7 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 				ranges = ranges[0];
 				res = g.store.getFeatures()["dojo.data.api.Write"] &&
 					(ranges.max.row - ranges.min.row) <= rowCnt &&
-					dojo.filter(sourcePlugin.grid.layout.cells, function(cell){
+					array.filter(sourcePlugin.grid.layout.cells, function(cell){
 						return cell.index >= ranges.min.col && cell.index <= ranges.max.col && !cell.hidden;
 					}).length <= colCnt;
 				//intentional drop through - don't break
@@ -861,214 +1077,17 @@ dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
 					return false;
 			}
 			var cache = this.grid._by_idx;
-			return dojo.every(rows, function(rowIndex){
+			return array.every(rows, function(rowIndex){
 				return !!cache[rowIndex];
 			});
 		}
 		return false;
 	}
 });
-dojo.declare("dojox.grid.enhanced.plugins.GridDnDElement", null, {
-	constructor: function(dndPlugin){
-		this.plugin = dndPlugin;
-		this.node = dojo.create("div");
-		this._items = {};
-	},
-	destroy: function(){
-		this.plugin = null;
-		dojo.destroy(this.node);
-		this.node = null;
-		this._items = null;
-	},
-	createDnDNodes: function(dndRegion){
-		this.destroyDnDNodes();
-		var acceptType = ["grid/" + dndRegion.type + "s"];
-		var itemNodeIdBase = this.plugin.grid.id + "_dndItem";
-		dojo.forEach(dndRegion.selected, function(range, i){
-			var id = itemNodeIdBase + i;
-			this._items[id] = {
-				"type": acceptType,
-				"data": range,
-				"dndPlugin": this.plugin
-			};
-			this.node.appendChild(dojo.create("div", {
-				"id": id
-			}));
-		}, this);
-	},
-	getDnDNodes: function(){
-		return dojo.map(this.node.childNodes, function(node){
-			return node;
-		});
-	},
-	destroyDnDNodes: function(){
-		dojo.empty(this.node);
-		this._items = {};
-	},
-	getItem: function(nodeId){
-		return this._items[nodeId];
-	}
-});
-dojo.declare("dojox.grid.enhanced.plugins.GridDnDSource",dojo.dnd.Source,{
-	accept: ["grid/cells", "grid/rows", "grid/cols"],
-	constructor: function(node, param){
-		this.grid = param.grid;
-		this.dndElem = param.dndElem;
-		this.dndPlugin = param.dnd;
-		this.sourcePlugin = null;
-	},
-	destroy: function(){
-		this.inherited(arguments);
-		this.grid = null;
-		this.dndElem = null;
-		this.dndPlugin = null;
-		this.sourcePlugin = null;
-	},
-	getItem: function(nodeId){
-		return this.dndElem.getItem(nodeId);
-	},
-	checkAcceptance: function(source, nodes){
-		if(this != source && nodes[0]){
-			var item = source.getItem(nodes[0].id);
-			if(item.dndPlugin){
-				var type = item.type;
-				for(var j = 0; j < type.length; ++j){
-					if(type[j] in this.accept){
-						if(this.dndPlugin._canAccept(item.dndPlugin)){
-							this.sourcePlugin = item.dndPlugin;
-						}else{
-							return false;
-						}
-						break;
-					}
-				}
-			}else if("grid/rows" in this.accept){
-				var rows = [];
-				dojo.forEach(nodes, function(node){
-					var item = source.getItem(node.id);
-					if(item.data && dojo.indexOf(item.type, "grid/rows") >= 0){
-						var rowData = item.data;
-						if(typeof item.data == "string"){
-							rowData = dojo.fromJson(item.data);
-						}
-						if(rowData){
-							rows.push(rowData);
-						}
-					}
-				});
-				if(rows.length){
-					this.sourcePlugin = {
-						_dndRegion: {
-							type: "row",
-							selected: [rows]
-						}
-					};
-				}else{
-					return false;
-				}
-			}
-		}
-		return this.inherited(arguments);
-	},
-	onDraggingOver: function(){
-		this.dndPlugin.onDraggingOver(this.sourcePlugin);
-	},
-	onDraggingOut: function(){
-		this.dndPlugin.onDraggingOut(this.sourcePlugin);
-	},
-	onDndDrop: function(source, nodes, copy, target){
-		//this.inherited(arguments);
-		this.onDndCancel();
-		if(this != source && this == target){
-			this.dndPlugin.onDragIn(this.sourcePlugin, copy);
-		}
-	}
-});
 
-dojo.declare("dojox.grid.enhanced.plugins.GridDnDAvatar", dojo.dnd.Avatar, {
-	construct: function(){
-		// summary:
-		//		constructor function;
-		//		it is separate so it can be (dynamically) overwritten in case of need
-		this._itemType = this.manager._dndPlugin._dndRegion.type;
-		this._itemCount = this._getItemCount();
-			
-		this.isA11y = dojo.hasClass(dojo.body(), "dijit_a11y");
-		var a = dojo.create("table", {
-				"border": "0",
-				"cellspacing": "0",
-				"class": "dojoxGridDndAvatar",
-				"style": {
-					position: "absolute",
-					zIndex: "1999",
-					margin: "0px"
-				}
-			}),
-			source = this.manager.source,
-			b = dojo.create("tbody", null, a),
-			tr = dojo.create("tr", null, b),
-			td = dojo.create("td", {
-				"class": "dojoxGridDnDIcon"
-			}, tr);
-		if(this.isA11y){
-			dojo.create("span", {
-				"id" : "a11yIcon",
-				"innerHTML" : this.manager.copy ? '+' : "<"
-			}, td);
-		}
-		td = dojo.create("td", {
-			"class" : "dojoxGridDnDItemIcon " + this._getGridDnDIconClass()
-		}, tr);
-		td = dojo.create("td", null, tr);
-		dojo.create("span", {
-			"class": "dojoxGridDnDItemCount",
-			"innerHTML": source.generateText ? this._generateText() : ""
-		}, td);
-		// we have to set the opacity on IE only after the node is live
-		dojo.style(tr, {
-			"opacity": 0.9
-		});
-		this.node = a;
-	},
-	_getItemCount: function(){
-		var selected = this.manager._dndPlugin._dndRegion.selected,
-			count = 0;
-		switch(this._itemType){
-			case "cell":
-				selected = selected[0];
-				var cells = this.manager._dndPlugin.grid.layout.cells,
-					colCount = selected.max.col - selected.min.col + 1,
-					rowCount = selected.max.row - selected.min.row + 1;
-				if(colCount > 1){
-					for(var i = selected.min.col; i <= selected.max.col; ++i){
-						if(cells[i].hidden){
-							--colCount;
-						}
-					}
-				}
-				count = colCount * rowCount;
-				break;
-			case "row":
-			case "col":
-				count = _joinToArray(selected).length;
-		}
-		return count;
-	},
-	_getGridDnDIconClass: function(){
-		return {
-			"row": ["dojoxGridDnDIconRowSingle", "dojoxGridDnDIconRowMulti"],
-			"col": ["dojoxGridDnDIconColSingle", "dojoxGridDnDIconColMulti"],
-			"cell": ["dojoxGridDnDIconCellSingle", "dojoxGridDnDIconCellMulti"]
-		}[this._itemType][this._itemCount == 1 ? 0 : 1];
-	},
-	_generateText: function(){
-		// summary:
-		//		generates a proper text to reflect copying or moving of items
-		return "(" + this._itemCount + ")";
-	}
+EnhancedGrid.registerPlugin(DnD/*name:'dnd'*/, {
+	"dependency": ["selector", "rearrange"]
 });
 
-dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.DnD/*name:'dnd'*/, {
-	"dependency": ["selector", "rearrange"]
+return DnD;
 });
-})();
\ No newline at end of file
diff --git a/dojox/grid/enhanced/plugins/Exporter.js b/dojox/grid/enhanced/plugins/Exporter.js
index 9e48569..52e932c 100644
--- a/dojox/grid/enhanced/plugins/Exporter.js
+++ b/dojox/grid/enhanced/plugins/Exporter.js
@@ -1,9 +1,16 @@
-dojo.provide("dojox.grid.enhanced.plugins.Exporter");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"../_Plugin",
+	"../../_RowSelector",
+	"../../EnhancedGrid",
+	"../../cells/_base"
+], function(declare, array, lang, _Plugin, _RowSelector, EnhancedGrid){
 
-dojo.require("dojox.grid.enhanced._Plugin");
-dojo.require("dojox.grid._RowSelector");
+var gridCells = lang.getObject("dojox.grid.cells");
 
-dojo.declare("dojox.grid.enhanced.plugins.Exporter", dojox.grid.enhanced._Plugin, {
+var Exporter = declare("dojox.grid.enhanced.plugins.Exporter", _Plugin, {
 	// summary:
 	//		Provide functions to export the grid data into a given format.
 	//
@@ -38,15 +45,15 @@ dojo.declare("dojox.grid.enhanced.plugins.Exporter", dojox.grid.enhanced._Plugin
 		// grid: EnhancedGrid
 		//		The grid to plug in to.
 		this.grid = grid;
-		this.formatter = (args && dojo.isObject(args)) && args.exportFormatter;
+		this.formatter = (args && lang.isObject(args)) && args.exportFormatter;
 		this._mixinGrid();
 	},
 	_mixinGrid: function(){
 		var g = this.grid;
-		g.exportTo = dojo.hitch(this, this.exportTo);
-		g.exportGrid = dojo.hitch(this, this.exportGrid);
-		g.exportSelected = dojo.hitch(this, this.exportSelected);
-		g.setExportFormatter = dojo.hitch(this, this.setExportFormatter);
+		g.exportTo = lang.hitch(this, this.exportTo);
+		g.exportGrid = lang.hitch(this, this.exportGrid);
+		g.exportSelected = lang.hitch(this, this.exportSelected);
+		g.setExportFormatter = lang.hitch(this, this.setExportFormatter);
 	},
 	setExportFormatter: function(formatter){
 		this.formatter = formatter;
@@ -70,17 +77,17 @@ dojo.declare("dojox.grid.enhanced.plugins.Exporter", dojox.grid.enhanced._Plugin
 		//		}
 		// onExported: function(string)
 		//		Call back function when export result is ready
-		if(dojo.isFunction(args)){
+		if(lang.isFunction(args)){
 			onExported = args;
 			args = {};
 		}
-		if(!dojo.isString(type) || !dojo.isFunction(onExported)){
+		if(!lang.isString(type) || !lang.isFunction(onExported)){
 			return;
 		}
 		args = args || {};
 		var g = this.grid, _this = this,
 			writer = this._getExportWriter(type, args.writerArgs),
-			fetchArgs = (args.fetchArgs && dojo.isObject(args.fetchArgs)) ? args.fetchArgs : {},
+			fetchArgs = (args.fetchArgs && lang.isObject(args.fetchArgs)) ? args.fetchArgs : {},
 			oldFunc = fetchArgs.onComplete;
 		if(g.store){
 			fetchArgs.onComplete = function(items, request){
@@ -113,7 +120,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Exporter", dojox.grid.enhanced._Plugin
 		//		Arguments for the given format writer
 		// returns: string
 		//		The exported string
-		if(!dojo.isString(type)){
+		if(!lang.isString(type)){
 			return "";
 		}
 		var writer = this._getExportWriter(type, writerArgs);
@@ -128,15 +135,15 @@ dojo.declare("dojox.grid.enhanced.plugins.Exporter", dojox.grid.enhanced._Plugin
 		// returns:
 		//		undefined
 		var _this = this;
-		dojo.forEach(arg_obj._views, function(view, vIdx){
+		array.forEach(arg_obj._views, function(view, vIdx){
 			arg_obj.view = view;
 			arg_obj.viewIdx = vIdx;
 			if(writer.beforeView(arg_obj)){
-				dojo.forEach(view.structure.cells, function(subrow, srIdx){
+				array.forEach(view.structure.cells, function(subrow, srIdx){
 					arg_obj.subrow = subrow;
 					arg_obj.subrowIdx = srIdx;
 					if(writer.beforeSubrow(arg_obj)){
-						dojo.forEach(subrow, function(cell, cIdx){
+						array.forEach(subrow, function(cell, cIdx){
 							if(arg_obj.isHeader && _this._isSpecialCol(cell)){
 								arg_obj.spCols.push(cell.index);
 							}
@@ -158,8 +165,8 @@ dojo.declare("dojox.grid.enhanced.plugins.Exporter", dojox.grid.enhanced._Plugin
 		// tags:
 		//		private
 		var grid = this.grid,
-			views = dojo.filter(grid.views.views, function(view){
-				return !(view instanceof dojox.grid._RowSelector);
+			views = array.filter(grid.views.views, function(view){
+				return !(view instanceof _RowSelector);
 			}),
 			arg_obj = {
 				'grid': grid,
@@ -176,7 +183,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Exporter", dojox.grid.enhanced._Plugin
 		//go through content
 		arg_obj.isHeader = false;
 		if(writer.beforeContent(items)){
-			dojo.forEach(items, function(item, rIdx){
+			array.forEach(items, function(item, rIdx){
 				arg_obj.row = item;
 				arg_obj.rowIdx = rIdx;
 				if(writer.beforeContentRow(arg_obj)){
@@ -193,7 +200,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Exporter", dojox.grid.enhanced._Plugin
 		//		Row selectors and row indexes should be recognized and handled separately.
 		// tags:
 		//		private
-		return header_cell.isRowSelector || header_cell instanceof dojox.grid.cells.RowIndex;	//Boolean
+		return header_cell.isRowSelector || header_cell instanceof gridCells.RowIndex;	//Boolean
 	},
 	_getExportWriter: function(/* string */ fileType, /* object? */ writerArgs){
 		// summary:
@@ -203,10 +210,10 @@ dojo.declare("dojox.grid.enhanced.plugins.Exporter", dojox.grid.enhanced._Plugin
 		// tags:
 		//		private
 		var writerName, cls,
-			expCls = dojox.grid.enhanced.plugins.Exporter;
+			expCls = Exporter;
 		if(expCls.writerNames){
 			writerName = expCls.writerNames[fileType.toLowerCase()];
-			cls = dojo.getObject(writerName);
+			cls = lang.getObject(writerName);
 			if(cls){
 				var writer = new cls(writerArgs);
 				writer.formatter = this.formatter;
@@ -218,14 +225,18 @@ dojo.declare("dojox.grid.enhanced.plugins.Exporter", dojox.grid.enhanced._Plugin
 		throw new Error('The writer for "' + fileType + '" has not been registered.');
 	}
 });
-dojox.grid.enhanced.plugins.Exporter.registerWriter = function(/* string */fileType,/* string */writerClsName){
+
+Exporter.registerWriter = function(/* string */fileType,/* string */writerClsName){
 	// summary:
 	//		Register a writer(writerClsName) to a export format type(fileType).
 	//		This function separates the Exporter from all kinds of writers.
 	// tags:
 	//		public
-	var expCls = dojox.grid.enhanced.plugins.Exporter;
-	expCls.writerNames = expCls.writerNames || {};
-	expCls.writerNames[fileType] = writerClsName;
+	Exporter.writerNames = Exporter.writerNames || {};
+	Exporter.writerNames[fileType] = writerClsName;
 };
-dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Exporter/*name:'exporter'*/);
+
+EnhancedGrid.registerPlugin(Exporter/*name:'exporter'*/);
+
+return Exporter;
+});
diff --git a/dojox/grid/enhanced/plugins/Filter.js b/dojox/grid/enhanced/plugins/Filter.js
index 6783ace..7a20c9c 100644
--- a/dojox/grid/enhanced/plugins/Filter.js
+++ b/dojox/grid/enhanced/plugins/Filter.js
@@ -1,19 +1,19 @@
-dojo.provide("dojox.grid.enhanced.plugins.Filter");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/i18n",
+	"../_Plugin",
+	"./Dialog",
+	"./filter/FilterLayer",
+	"./filter/FilterBar",
+	"./filter/FilterDefDialog",
+	"./filter/FilterStatusTip",
+	"./filter/ClearFilterConfirm",
+	"../../EnhancedGrid",
+	"dojo/i18n!../nls/Filter"
+], function(declare, lang, i18n, _Plugin, Dialog, layers, FilterBar, FilterDefDialog, FilterStatusTip, ClearFilterConfirm, EnhancedGrid){
 
-dojo.requireLocalization("dojox.grid.enhanced", "Filter");
-dojo.require("dojox.grid.enhanced._Plugin");
-dojo.require("dojox.grid.enhanced.plugins.Dialog");
-dojo.require("dojox.grid.enhanced.plugins.filter.FilterLayer");
-dojo.require("dojox.grid.enhanced.plugins.filter.FilterBar");
-dojo.require("dojox.grid.enhanced.plugins.filter.FilterDefDialog");
-dojo.require("dojox.grid.enhanced.plugins.filter.FilterStatusTip");
-dojo.require("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm");
-
-(function(){
-	var ns = dojox.grid.enhanced.plugins,
-		fns = ns.filter;
-		
-	dojo.declare("dojox.grid.enhanced.plugins.Filter", dojox.grid.enhanced._Plugin, {
+	var Filter = declare("dojox.grid.enhanced.plugins.Filter", _Plugin, {
 		// summary:
 		//		Provide filter functionality for grid.
 		//
@@ -34,6 +34,11 @@ dojo.require("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm");
 		//			If isServerSide is true, set the server side filter to be stateful or not. default to false.
 		//		7. url: string
 		//			If using stateful, this is the url to send commands. default to store.url.
+		//		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
@@ -83,26 +88,30 @@ dojo.require("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm");
 			// summary:
 			//		See constructor of dojox.grid.enhanced._Plugin.
 			this.grid = grid;
-			this.nls = dojo.i18n.getLocalization("dojox.grid.enhanced", "Filter");
+			this.nls = i18n.getLocalization("dojox.grid.enhanced", "Filter");
 			
-			args = this.args = dojo.isObject(args) ? args : {};
+			args = this.args = lang.isObject(args) ? args : {};
 			if(typeof args.ruleCount != 'number' || args.ruleCount < 0){
 				args.ruleCount = 3;
 			}
+			var rc = this.ruleCountToConfirmClearFilter = args.ruleCountToConfirmClearFilter;
+			if(rc === undefined){
+				this.ruleCountToConfirmClearFilter = 2;
+			}
 			
 			//Install filter layer
 			this._wrapStore();
 			
 			//Install UI components
 			var obj = { "plugin": this };
-			this.clearFilterDialog = new dojox.grid.enhanced.plugins.Dialog({
+			this.clearFilterDialog = new Dialog({
 				refNode: this.grid.domNode,
 				title: this.nls["clearFilterDialogTitle"],
-				content: new fns.ClearFilterConfirm(obj)
+				content: new ClearFilterConfirm(obj)
 			});
-			this.filterDefDialog = new fns.FilterDefDialog(obj);
-			this.filterBar = new fns.FilterBar(obj);
-			this.filterStatusTip = new fns.FilterStatusTip(obj);
+			this.filterDefDialog = new FilterDefDialog(obj);
+			this.filterBar = new FilterBar(obj);
+			this.filterStatusTip = new FilterStatusTip(obj);
 			
 			//Expose the layer event to grid.
 			grid.onFilterDefined = function(){};
@@ -132,15 +141,15 @@ dojo.require("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm");
 		_wrapStore: function(){
 			var g = this.grid;
 			var args = this.args;
-			var filterLayer = args.isServerSide ? new fns.ServerSideFilterLayer(args) :
-				new fns.ClientSideFilterLayer({
+			var filterLayer = args.isServerSide ? new layers.ServerSideFilterLayer(args) :
+				new layers.ClientSideFilterLayer({
 					cacheSize: args.filterCacheSize,
 					fetchAll: args.fetchAllOnFirstFilter,
 					getter: this._clientFilterGetter
 				});
-			ns.wrap(g, "_storeLayerFetch", filterLayer);
+			layers.wrap(g, "_storeLayerFetch", filterLayer);
 			
-			this.connect(g, "_onDelete", dojo.hitch(filterLayer, "invalidate"));
+			this.connect(g, "_onDelete", lang.hitch(filterLayer, "invalidate"));
 		},
 		onSetStore: function(store){
 			this.filterDefDialog.clearFilter(true);
@@ -155,6 +164,9 @@ dojo.require("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm");
 			return cell.get(rowIndex, datarow);
 		}
 	});
-})();
 
-dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Filter/*name:'filter'*/);
+	EnhancedGrid.registerPlugin(Filter/*name:'filter'*/);
+
+	return Filter;
+
+});
diff --git a/dojox/grid/enhanced/plugins/GridSource.js b/dojox/grid/enhanced/plugins/GridSource.js
index fa7fdfa..a2e59ff 100644
--- a/dojox/grid/enhanced/plugins/GridSource.js
+++ b/dojox/grid/enhanced/plugins/GridSource.js
@@ -1,9 +1,11 @@
-dojo.provide("dojox.grid.enhanced.plugins.GridSource");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/dnd/Source",
+	"./DnD"
+], function(declare, array, lang, Source, DnD){
 
-dojo.require("dojo.dnd.Source");
-dojo.require("dojox.grid.enhanced.plugins.DnD");
-
-(function(){
 var _joinToArray = function(arrays){
 	var a = arrays[0];
 	for(var i = 1; i < arrays.length; ++i){
@@ -11,7 +13,10 @@ var _joinToArray = function(arrays){
 	}
 	return a;
 };
-dojo.declare("dojox.grid.enhanced.plugins.GridSource", dojo.dnd.Source, {
+
+var GridDnDSource = lang.getObject("dojox.grid.enhanced.plugins.GridDnDSource");
+
+return declare("dojox.grid.enhanced.plugins.GridSource", Source, {
 	// summary:
 	//		A special source that can accept grid contents.
 	//		Only for non-grid widgets or domNodes.
@@ -24,13 +29,14 @@ dojo.declare("dojox.grid.enhanced.plugins.GridSource", dojo.dnd.Source, {
 	insertNodesForGrid: false,
 	
 	markupFactory: function(params, node){
-		return new dojox.grid.enhanced.plugins.GridSource(node, params);
+		cls = lang.getObject("dojox.grid.enhanced.plugins.GridSource");
+		return new cls(node, params);
 	},
 	checkAcceptance: function(source, nodes){
-		if(source instanceof dojox.grid.enhanced.plugins.GridDnDSource){
+		if(source instanceof GridDnDSource){
 			if(nodes[0]){
 				var item = source.getItem(nodes[0].id);
-				if(item && (dojo.indexOf(item.type, "grid/rows") >= 0 || dojo.indexOf(item.type, "grid/cells") >= 0) &&
+				if(item && (array.indexOf(item.type, "grid/rows") >= 0 || array.indexOf(item.type, "grid/cells") >= 0) &&
 					!source.dndPlugin._allDnDItemsLoaded()){
 					return false;
 				}
@@ -50,8 +56,8 @@ dojo.declare("dojox.grid.enhanced.plugins.GridSource", dojo.dnd.Source, {
 		}
 	},
 	onDropExternal: function(source, nodes, copy){
-		if(source instanceof dojox.grid.enhanced.plugins.GridDnDSource){
-			var ranges = dojo.map(nodes, function(node){
+		if(source instanceof GridDnDSource){
+			var ranges = array.map(nodes, function(node){
 				return source.getItem(node.id).data;
 			});
 			var item = source.getItem(nodes[0].id);
@@ -145,4 +151,4 @@ dojo.declare("dojox.grid.enhanced.plugins.GridSource", dojo.dnd.Source, {
 		
 	}
 });
-})();
+});
diff --git a/dojox/grid/enhanced/plugins/IndirectSelection.js b/dojox/grid/enhanced/plugins/IndirectSelection.js
index 1e5493e..e9a98db 100644
--- a/dojox/grid/enhanced/plugins/IndirectSelection.js
+++ b/dojox/grid/enhanced/plugins/IndirectSelection.js
@@ -1,84 +1,23 @@
-dojo.provide("dojox.grid.enhanced.plugins.IndirectSelection");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/event",
+	"dojo/_base/lang",
+	"dojo/_base/html",
+	"dojo/_base/window",
+	"dojo/_base/connect",
+	"dojo/_base/sniff",
+	"dojo/query",
+	"dojo/keys",
+	"dojo/string",
+	"../_Plugin",
+	"../../EnhancedGrid",
+	"../../cells/dijit"
+], function(declare, array, evt, lang, html, win, connect, has, query, keys, string, _Plugin, EnhancedGrid){
 
-dojo.require('dojo.string');
-dojo.require("dojox.grid.cells.dijit");
-dojo.require("dojox.grid.enhanced._Plugin");
+var gridCells = lang.getObject("dojox.grid.cells");
 
-dojo.declare("dojox.grid.enhanced.plugins.IndirectSelection", dojox.grid.enhanced._Plugin, {
-	// summary:
-	//		A handy way for adding check boxe/radio button for rows, and selecting rows by swiping(or keyboard)
-
-	// description:
-	//		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>
-
-	//name: String
-	//		Plugin name
-	name: "indirectSelection",
-	
-	constructor: function(){
-		//Hook layout.setStructure(), so that indirectSelection is always included
-		var layout = this.grid.layout;
-		this.connect(layout, 'setStructure', dojo.hitch(layout, this.addRowSelectCell, this.option));
-	},
-	addRowSelectCell: function(option){
-		// summary:
-		//		Add indirectSelection cell(mapped to a column of radio button|check boxes)
-		if(!this.grid.indirectSelection || this.grid.selectionMode == 'none'){
-			return;
-		}
-		var rowSelectCellAdded = false, inValidFields = ['get', 'formatter', 'field', 'fields'],
-		defaultCellDef = {type: dojox.grid.cells.MultipleRowSelector, name: '', width:'30px', styles:'text-align: center;'};
-		if(option.headerSelector){ option.name = ''; }//mutual conflicting attrs
-
-		if(this.grid.rowSelectCell){//remove the existed one
-			this.grid.rowSelectCell.destroy();
-		}
-		
-		dojo.forEach(this.structure, function(view){
-			var cells = view.cells;
-			if(cells && cells.length > 0 && !rowSelectCellAdded){
-				var firstRow = cells[0];
-				if(firstRow[0] && firstRow[0].isRowSelector){
-					console.debug('addRowSelectCell() - row selector cells already added, return.');
-					rowSelectCellAdded = true;
-					return;
-				}
-				var selectDef, cellType = this.grid.selectionMode == 'single' ? dojox.grid.cells.SingleRowSelector : dojox.grid.cells.MultipleRowSelector;
-				selectDef = dojo.mixin(defaultCellDef, option, {type: cellType, editable: false, notselectable: true, filterable: false, navigatable: true, nosort: true});
-				dojo.forEach(inValidFields, function(field){//remove invalid fields
-					if(field in selectDef){ delete selectDef[field]; }
-				});
-				if(cells.length > 1){ selectDef.rowSpan = cells.length; }//for complicate layout
-				dojo.forEach(this.cells, function(cell, i){
-					if(cell.index >= 0){
-						cell.index += 1;
-						//console.debug('cell '+ (cell.index - 1) +  ' is updated to index ' + cell.index);
-					}else{
-						console.warn('Error:IndirectSelection.addRowSelectCell()-  cell ' + i + ' has no index!');
-					}
-				});
-				var rowSelectCell = this.addCellDef(0, 0, selectDef);
-				rowSelectCell.index = 0;
-				firstRow.unshift(rowSelectCell);
-				this.cells.unshift(rowSelectCell);
-				this.grid.rowSelectCell = rowSelectCell;
-				rowSelectCellAdded = true;
-			}
-		}, this);
-		this.cellCount = this.cells.length;
-	},
-	destroy: function(){
-		this.grid.rowSelectCell.destroy();
-		delete this.grid.rowSelectCell;
-		this.inherited(arguments);
-	}
-});
-
-dojo.declare("dojox.grid.cells.RowSelector", dojox.grid.cells._Widget, {
+var RowSelector = declare("dojox.grid.cells.RowSelector", gridCells._Widget, {
 	// summary:
 	//		 Common attributes & functions for row selectors(Radio|CheckBox)
 
@@ -108,7 +47,7 @@ dojo.declare("dojox.grid.cells.RowSelector", dojox.grid.cells._Widget, {
 
 	//checkedText: String
 	//		Checked character for high contrast mode
-	checkedText: '√',
+	checkedText: '✓',
 
 	//unCheckedText: String
 	//		Unchecked character for high contrast mode
@@ -117,7 +56,7 @@ dojo.declare("dojox.grid.cells.RowSelector", dojox.grid.cells._Widget, {
 	constructor: function(){
 		this.map = {}; this.disabledMap = {}, this.disabledCount= 0;
 		this._connects = []; this._subscribes = [];
-		this.inA11YMode = dojo.hasClass(dojo.body(), "dijit_a11y");
+		this.inA11YMode = html.hasClass(win.body(), "dijit_a11y");
 		
 		this.baseClass = "dojoxGridRowSelector dijitReset dijitInline dijit" + this.inputType;
 		this.checkedClass = " dijit" + this.inputType + "Checked";
@@ -125,32 +64,33 @@ dojo.declare("dojox.grid.cells.RowSelector", dojox.grid.cells._Widget, {
 		this.checkedDisabledClass = " dijit" + this.inputType + "CheckedDisabled";
 		this.statusTextClass = " dojoxGridRowSelectorStatusText";//a11y use
 
-		this._connects.push(dojo.connect(this.grid, 'dokeyup', this, '_dokeyup'));
-		this._connects.push(dojo.connect(this.grid.selection, 'onSelected', this, '_onSelected'));
-		this._connects.push(dojo.connect(this.grid.selection, 'onDeselected', this, '_onDeselected'));
-		this._connects.push(dojo.connect(this.grid.scroller, 'invalidatePageNode', this, '_pageDestroyed'));
-		this._connects.push(dojo.connect(this.grid, 'onCellClick', this, '_onClick'));
-		this._connects.push(dojo.connect(this.grid, 'updateRow', this, '_onUpdateRow'));
+		this._connects.push(connect.connect(this.grid, 'dokeyup', this, '_dokeyup'));
+		this._connects.push(connect.connect(this.grid.selection, 'onSelected', this, '_onSelected'));
+		this._connects.push(connect.connect(this.grid.selection, 'onDeselected', this, '_onDeselected'));
+		this._connects.push(connect.connect(this.grid.scroller, 'invalidatePageNode', this, '_pageDestroyed'));
+		this._connects.push(connect.connect(this.grid, 'onCellClick', this, '_onClick'));
+		this._connects.push(connect.connect(this.grid, 'updateRow', this, '_onUpdateRow'));
 	},
-	formatter: function(data, rowIndex){
+	formatter: function(data, rowIndex, scope){
 		// summary:
 		//		Overwritten, see dojox.grid.cells._Widget
-		var clazz = this.baseClass;
-		var checked = this.getValue(rowIndex);
-		var disabled = !!this.disabledMap[rowIndex];//normalize 'undefined'
+		var _this = scope;
+		var clazz = _this.baseClass;
+		var checked = _this.getValue(rowIndex);
+		var disabled = !!_this.disabledMap[rowIndex];//normalize 'undefined'
 		
 		if(checked){
-			clazz += this.checkedClass;
-			if(disabled){ clazz += this.checkedDisabledClass; }
+			clazz += _this.checkedClass;
+			if(disabled){ clazz += _this.checkedDisabledClass; }
 		}else if(disabled){
-			clazz += this.disabledClass;
+			clazz += _this.disabledClass;
 		}
 		return ["<div tabindex = -1 ",
-				"id = '" + this.grid.id + "_rowSelector_" + rowIndex + "' ",
-				"name = '" + this.grid.id + "_rowSelector' class = '" + clazz + "' ",
+				"id = '" + _this.grid.id + "_rowSelector_" + rowIndex + "' ",
+				"name = '" + _this.grid.id + "_rowSelector' class = '" + clazz + "' ",
 				"role = 'presentation' aria-pressed = '" + checked + "' aria-disabled = '" + disabled +
-				"' aria-label = '" + dojo.string.substitute(this.grid._nls["indirectSelection" + this.inputType], [rowIndex + 1]) + "'>",
-				"<span class = '" + this.statusTextClass + "'>" + (checked ? this.checkedText : this.unCheckedText) + "</span>",
+				"' aria-label = '" + string.substitute(_this.grid._nls["indirectSelection" + _this.inputType], [rowIndex + 1]) + "'>",
+				"<span class = '" + _this.statusTextClass + "'>" + (checked ? _this.checkedText : _this.unCheckedText) + "</span>",
 				"</div>"].join("");
 	},
 	setValue: function(rowIndex, inValue){
@@ -200,7 +140,7 @@ dojo.declare("dojox.grid.cells.RowSelector", dojox.grid.cells._Widget, {
 		//		- from dojox.grid.enhanced._Events.dokeyup()
 		// e: Event
 		//		Key up event
-		if(e.cellIndex == this.index && e.rowIndex >= 0 && e.keyCode == dojo.keys.SPACE){
+		if(e.cellIndex == this.index && e.rowIndex >= 0 && e.keyCode == keys.SPACE){
 			this._selectRow(e);
 		}
 	},
@@ -247,13 +187,13 @@ dojo.declare("dojox.grid.cells.RowSelector", dojox.grid.cells._Widget, {
 		//		Change css styles for checked | unchecked
 		var selector = this._getSelector(index);
 		if(selector){
-			dojo.toggleClass(selector, this.checkedClass, value);
+			html.toggleClass(selector, this.checkedClass, value);
 			if(this.disabledMap[index]){
-				dojo.toggleClass(selector, this.checkedDisabledClass, value);
+				html.toggleClass(selector, this.checkedDisabledClass, value);
 			}
-			dijit.setWaiState(selector, 'pressed', value);
+			selector.setAttribute("aria-pressed", value);
 			if(this.inA11YMode){
-				dojo.attr(selector.firstChild, 'innerHTML', value ? this.checkedText : this.unCheckedText);
+				selector.firstChild.innerHTML = (value ? this.checkedText : this.unCheckedText);
 			}
 		}
 	},
@@ -262,11 +202,11 @@ dojo.declare("dojox.grid.cells.RowSelector", dojox.grid.cells._Widget, {
 		//		Change css styles for disabled | enabled
 		var selector = this._getSelector(index);
 		if(selector){
-			dojo.toggleClass(selector, this.disabledClass, disabled);
+			html.toggleClass(selector, this.disabledClass, disabled);
 			if(this.getValue(index)){
-				dojo.toggleClass(selector, this.checkedDisabledClass, disabled);
+				html.toggleClass(selector, this.checkedDisabledClass, disabled);
 			}
-			dijit.setWaiState(selector, 'disabled', disabled);
+			selector.setAttribute("aria-disabled", disabled);
 		}
 		this.disabledMap[index] = disabled;
 		if(index >= 0){
@@ -280,7 +220,7 @@ dojo.declare("dojox.grid.cells.RowSelector", dojox.grid.cells._Widget, {
 		if(!selector){//use accurate query for better performance
 			var rowNode = this.view.rowNodes[index];
 			if(rowNode){
-				selector = dojo.query('.dojoxGridRowSelector', rowNode)[0];
+				selector = query('.dojoxGridRowSelector', rowNode)[0];
 				if(selector){ this.map[index] = selector; }
 			}
 		}
@@ -296,26 +236,26 @@ dojo.declare("dojox.grid.cells.RowSelector", dojox.grid.cells._Widget, {
 		var start = pageIndex * rowsPerPage, end = start + rowsPerPage - 1;
 		for(var i = start; i <= end; i++){
 			if(!this.map[i]){continue;}
-			dojo.destroy(this.map[i]);
+			html.destroy(this.map[i]);
 			delete this.map[i];
 		}
 		//console.log("Page ",pageIndex, " destroyed, Map=",this.map);
 	},
 	destroy: function(){
 		for(var i in this.map){
-			dojo.destroy(this.map[i]);
+			html.destroy(this.map[i]);
 			delete this.map[i];
 		}
 		for(i in this.disabledMap){ delete this.disabledMap[i]; }
-		dojo.forEach(this._connects, dojo.disconnect);
-		dojo.forEach(this._subscribes, dojo.unsubscribe);
+		array.forEach(this._connects, connect.disconnect);
+		array.forEach(this._subscribes, connect.unsubscribe);
 		delete this._connects;
 		delete this._subscribes;
 		//console.log('Single(Multiple)RowSelector.destroy() executed!');
 	}
 });
 
-dojo.declare("dojox.grid.cells.SingleRowSelector", dojox.grid.cells.RowSelector, {
+var SingleRowSelector = declare("dojox.grid.cells.SingleRowSelector", RowSelector, {
 	// summary:
 	//		IndirectSelection cell(column) for single selection mode, using styles of dijit.form.RadioButton
 	inputType: "Radio",
@@ -332,7 +272,7 @@ dojo.declare("dojox.grid.cells.SingleRowSelector", dojox.grid.cells.RowSelector,
 	}
 });
 
-dojo.declare("dojox.grid.cells.MultipleRowSelector", dojox.grid.cells.RowSelector, {
+var MultipleRowSelector = declare("dojox.grid.cells.MultipleRowSelector", RowSelector, {
 	// summary:
 	//		Indirect selection cell for multiple or extended mode, using dijit.form.CheckBox
 	inputType: "CheckBox",
@@ -364,15 +304,16 @@ dojo.declare("dojox.grid.cells.MultipleRowSelector", dojox.grid.cells.RowSelecto
 	unCheckedText: '□',
 
 	constructor: function(){
-		this._connects.push(dojo.connect(dojo.doc, 'onmouseup', this, '_domouseup'));
-		this._connects.push(dojo.connect(this.grid, 'onRowMouseOver', this, '_onRowMouseOver'));
-		this._connects.push(dojo.connect(this.grid.focus, 'move', this, '_swipeByKey'));
-		this._connects.push(dojo.connect(this.grid, 'onCellMouseDown', this, '_onMouseDown'));
+		this._connects.push(connect.connect(win.doc, 'onmouseup', this, '_domouseup'));
+		this._connects.push(connect.connect(this.grid, 'onRowMouseOver', this, '_onRowMouseOver'));
+		this._connects.push(connect.connect(this.grid.focus, 'move', this, '_swipeByKey'));
+		this._connects.push(connect.connect(this.grid, 'onCellMouseDown', this, '_onMouseDown'));
 		if(this.headerSelector){//option set by user to add a select-all checkbox in column header
-			this._connects.push(dojo.connect(this.grid.views, 'render', this, '_addHeaderSelector'));
-			this._connects.push(dojo.connect(this.grid, 'onSelectionChanged', this, '_onSelectionChanged'));
-			this._connects.push(dojo.connect(this.grid, 'onKeyDown', this, function(e){
-				if(e.rowIndex == -1 && e.cellIndex == this.index && e.keyCode == dojo.keys.SPACE){
+			this._connects.push(connect.connect(this.grid.views, 'render', this, '_addHeaderSelector'));
+			this._connects.push(connect.connect(this.grid, '_onFetchComplete', this, '_addHeaderSelector'));
+			this._connects.push(connect.connect(this.grid, 'onSelectionChanged', this, '_onSelectionChanged'));
+			this._connects.push(connect.connect(this.grid, 'onKeyDown', this, function(e){
+				if(e.rowIndex == -1 && e.cellIndex == this.index && e.keyCode == keys.SPACE){
 					this._toggletHeader();//TBD - a better way
 				}
 			}));
@@ -394,7 +335,7 @@ dojo.declare("dojox.grid.cells.MultipleRowSelector", dojox.grid.cells.RowSelecto
 	_onMouseDown: function(e){
 		if(e.cell == this){
 			this._startSelection(e.rowIndex);
-			dojo.stopEvent(e);
+			evt.stop(e);
 		}
 	},
 	_onRowMouseOver: function(e){
@@ -410,7 +351,7 @@ dojo.declare("dojox.grid.cells.MultipleRowSelector", dojox.grid.cells.RowSelecto
 		//		Event handler for mouse up event - from dojo.doc.domouseup()
 		// e: Event
 		//		Mouse up event
-		if(dojo.isIE){
+		if(has('ie')){
 			this.view.content.decorateEvent(e);//TODO - why only e in IE hasn't been decorated?
 		}
 		var inSwipeSelection = e.cellIndex >= 0 && this.inSwipeSelection() && !this.grid.edit.isEditRow(e.rowIndex);
@@ -523,7 +464,7 @@ dojo.declare("dojox.grid.cells.MultipleRowSelector", dojox.grid.cells.RowSelecto
 		//		Event fired on the target row
 		var rowIndex = e.rowIndex;
 		if(this.disabledMap[rowIndex]){ return; }
-		dojo.stopEvent(e);
+		evt.stop(e);
 		this._focusEndingCell(rowIndex, 0);
 		
 		var delta = rowIndex - this.lastClickRowIdx;
@@ -553,9 +494,10 @@ dojo.declare("dojox.grid.cells.MultipleRowSelector", dojox.grid.cells.RowSelecto
 		//		Add selector in column header for selecting|deselecting all
 		var headerCellNode = this.view.getHeaderCellNode(this.index);
 		if(!headerCellNode){ return; }
-		dojo.empty(headerCellNode);
+		html.empty(headerCellNode);
 		var g = this.grid;
-		var selector = headerCellNode.appendChild(dojo.create("div", {
+		var selector = headerCellNode.appendChild(html.create("div", {
+			'aria-label': g._nls["selectAll"],
 			"tabindex": -1, "id": g.id + "_rowSelector_-1", "class": this.baseClass, "role": "presentation",
 			"innerHTML": "<span class = '" + this.statusTextClass +
 				"'></span><span style='height: 0; width: 0; overflow: hidden; display: block;'>" +
@@ -564,11 +506,11 @@ dojo.declare("dojox.grid.cells.MultipleRowSelector", dojox.grid.cells.RowSelecto
 		this.map[-1] = selector;
 		var idx = this._headerSelectorConnectIdx;
 		if(idx !== undefined){
-			dojo.disconnect(this._connects[idx]);
+			connect.disconnect(this._connects[idx]);
 			this._connects.splice(idx, 1);
 		}
 		this._headerSelectorConnectIdx = this._connects.length;
-		this._connects.push(dojo.connect(selector, 'onclick', this, '_toggletHeader'));
+		this._connects.push(connect.connect(selector, 'onclick', this, '_toggletHeader'));
 		this._onSelectionChanged();
 	},
 	_toggletHeader: function(){
@@ -585,7 +527,8 @@ dojo.declare("dojox.grid.cells.MultipleRowSelector", dojox.grid.cells.RowSelecto
 		//		Update header selector anytime selection changed
 		var g = this.grid;
 		if(!this.map[-1] || g._selectingRange){ return; }
-		this._toggleCheckedStyle(-1, this.getValue(-1));
+		g.allItemsSelected = this.getValue(-1);
+		this._toggleCheckedStyle(-1, g.allItemsSelected);
 	},
 	_toggleDisabledStyle: function(index, disabled){
 		// summary:
@@ -602,4 +545,81 @@ dojo.declare("dojox.grid.cells.MultipleRowSelector", dojox.grid.cells.RowSelecto
 	}
 });
 
-dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.IndirectSelection/*name:'indirectSelection'*/, {"preInit": true});
\ No newline at end of file
+var IndirectSelection = declare("dojox.grid.enhanced.plugins.IndirectSelection", _Plugin, {
+	// summary:
+	//		A handy way for adding check boxe/radio button for rows, and selecting rows by swiping(or keyboard)
+
+	// description:
+	//		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>
+
+	//name: String
+	//		Plugin name
+	name: "indirectSelection",
+	
+	constructor: function(){
+		//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));
+	},
+	addRowSelectCell: function(option){
+		// summary:
+		//		Add indirectSelection cell(mapped to a column of radio button|check boxes)
+		if(!this.grid.indirectSelection || this.grid.selectionMode == 'none'){
+			return;
+		}
+		var rowSelectCellAdded = false, inValidFields = ['get', 'formatter', 'field', 'fields'],
+		defaultCellDef = {type: MultipleRowSelector, name: '', width:'30px', styles:'text-align: center;'};
+		if(option.headerSelector){ option.name = ''; }//mutual conflicting attrs
+
+		if(this.grid.rowSelectCell){//remove the existed one
+			this.grid.rowSelectCell.destroy();
+		}
+		
+		array.forEach(this.structure, function(view){
+			var cells = view.cells;
+			if(cells && cells.length > 0 && !rowSelectCellAdded){
+				var firstRow = cells[0];
+				if(firstRow[0] && firstRow[0].isRowSelector){
+					console.debug('addRowSelectCell() - row selector cells already added, return.');
+					rowSelectCellAdded = true;
+					return;
+				}
+				var selectDef, cellType = this.grid.selectionMode == 'single' ? SingleRowSelector : MultipleRowSelector;
+				selectDef = lang.mixin(defaultCellDef, option, {type: cellType, editable: false, notselectable: true, filterable: false, navigatable: true, nosort: true});
+				array.forEach(inValidFields, function(field){//remove invalid fields
+					if(field in selectDef){ delete selectDef[field]; }
+				});
+				if(cells.length > 1){ selectDef.rowSpan = cells.length; }//for complicate layout
+				array.forEach(this.cells, function(cell, i){
+					if(cell.index >= 0){
+						cell.index += 1;
+						//console.debug('cell '+ (cell.index - 1) +  ' is updated to index ' + cell.index);
+					}else{
+						console.warn('Error:IndirectSelection.addRowSelectCell()-  cell ' + i + ' has no index!');
+					}
+				});
+				var rowSelectCell = this.addCellDef(0, 0, selectDef);
+				rowSelectCell.index = 0;
+				firstRow.unshift(rowSelectCell);
+				this.cells.unshift(rowSelectCell);
+				this.grid.rowSelectCell = rowSelectCell;
+				rowSelectCellAdded = true;
+			}
+		}, this);
+		this.cellCount = this.cells.length;
+	},
+	destroy: function(){
+		this.grid.rowSelectCell.destroy();
+		delete this.grid.rowSelectCell;
+		this.inherited(arguments);
+	}
+});
+
+EnhancedGrid.registerPlugin(IndirectSelection/*name:'indirectSelection'*/, {"preInit": true});
+
+return IndirectSelection;
+});
diff --git a/dojox/grid/enhanced/plugins/Menu.js b/dojox/grid/enhanced/plugins/Menu.js
index 4110976..98dd50c 100644
--- a/dojox/grid/enhanced/plugins/Menu.js
+++ b/dojox/grid/enhanced/plugins/Menu.js
@@ -1,8 +1,15 @@
-dojo.provide("dojox.grid.enhanced.plugins.Menu");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/_base/html",
+	"dojo/_base/event",
+	"dojo/keys",
+	"../_Plugin",
+	"../../EnhancedGrid"
+], function(declare, array, lang, html, evt, keys, _Plugin, EnhancedGrid){
 
-dojo.require("dojox.grid.enhanced._Plugin");
-
-dojo.declare("dojox.grid.enhanced.plugins.Menu", dojox.grid.enhanced._Plugin, {
+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:
@@ -21,15 +28,15 @@ dojo.declare("dojox.grid.enhanced.plugins.Menu", dojox.grid.enhanced._Plugin, {
 	
 	constructor: function(){
 		var g = this.grid;
-		g.showMenu = dojo.hitch(g, this.showMenu);
-		g._setRowMenuAttr = dojo.hitch(this, '_setRowMenuAttr');
-		g._setCellMenuAttr = dojo.hitch(this, '_setCellMenuAttr');
-		g._setSelectedRegionMenuAttr = dojo.hitch(this, '_setSelectedRegionMenuAttr');
+		g.showMenu = lang.hitch(g, this.showMenu);
+		g._setRowMenuAttr = lang.hitch(this, '_setRowMenuAttr');
+		g._setCellMenuAttr = lang.hitch(this, '_setCellMenuAttr');
+		g._setSelectedRegionMenuAttr = lang.hitch(this, '_setSelectedRegionMenuAttr');
 	},
 	onStartUp: function(){
 		var type, option = this.option;
 		for(type in option){
-			if(dojo.indexOf(this.types, type) >= 0 && option[type]){
+			if(array.indexOf(this.types, type) >= 0 && option[type]){
 				this._initMenu(type, option[type]);
 			}
 		}
@@ -42,6 +49,8 @@ dojo.declare("dojox.grid.enhanced.plugins.Menu", dojox.grid.enhanced._Plugin, {
 			g.set(menuType, m);
 			if(menuType != "headerMenu"){
 				m._scheduleOpen = function(){return;};
+			}else{
+				g.setupHeaderMenu();
 			}
 		}
 	},
@@ -84,25 +93,25 @@ dojo.declare("dojox.grid.enhanced.plugins.Menu", dojox.grid.enhanced._Plugin, {
 		//		Show appropriate context menu
 		//		Fired from dojox.grid.enhanced._Events.onRowContextMenu, 'this' scope - Grid
 		//		TODO: test Shift-F10
-		var inSelectedRegion = (e.cellNode && dojo.hasClass(e.cellNode, 'dojoxGridRowSelected') ||
-			e.rowNode && (dojo.hasClass(e.rowNode, 'dojoxGridRowSelected') || dojo.hasClass(e.rowNode, 'dojoxGridRowbarSelected')));
+		var inSelectedRegion = (e.cellNode && html.hasClass(e.cellNode, 'dojoxGridRowSelected') ||
+			e.rowNode && (html.hasClass(e.rowNode, 'dojoxGridRowSelected') || html.hasClass(e.rowNode, 'dojoxGridRowbarSelected')));
 		
 		if(inSelectedRegion && this.selectedRegionMenu){
 			this.onSelectedRegionContextMenu(e);
 			return;
 		}
 		
-		var info = {target: e.target, coords: e.keyCode !== dojo.keys.F10 && "pageX" in e ? {x: e.pageX, y: e.pageY } : null};
-		if(this.rowMenu && (!this.cellMenu || this.selection.isSelected(e.rowIndex) || e.rowNode && dojo.hasClass(e.rowNode, 'dojoxGridRowbar'))){
+		var info = {target: e.target, coords: e.keyCode !== keys.F10 && "pageX" in e ? {x: e.pageX, y: e.pageY } : null};
+		if(this.rowMenu && (!this.cellMenu || this.selection.isSelected(e.rowIndex) || e.rowNode && html.hasClass(e.rowNode, 'dojoxGridRowbar'))){
 			this.rowMenu._openMyself(info);
-			dojo.stopEvent(e);
+			evt.stop(e);
 			return;
 		}
 
 		if(this.cellMenu){
 			this.cellMenu._openMyself(info);
 		}
-		dojo.stopEvent(e);
+		evt.stop(e);
 	},
 	destroy: function(){
 		// summary:
@@ -117,4 +126,8 @@ dojo.declare("dojox.grid.enhanced.plugins.Menu", dojox.grid.enhanced._Plugin, {
 	}
 });
 
-dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Menu/*name:'menus'*/);
\ No newline at end of file
+EnhancedGrid.registerPlugin(Menu/*name:'menus'*/);
+
+return Menu;
+
+});
diff --git a/dojox/grid/enhanced/plugins/NestedSorting.js b/dojox/grid/enhanced/plugins/NestedSorting.js
index c0b9970..ed0b01e 100644
--- a/dojox/grid/enhanced/plugins/NestedSorting.js
+++ b/dojox/grid/enhanced/plugins/NestedSorting.js
@@ -1,8 +1,19 @@
-dojo.provide("dojox.grid.enhanced.plugins.NestedSorting");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/lang",
+	"dojo/_base/html",
+	"dojo/_base/event",
+	"dojo/_base/window",
+	"dojo/keys",
+	"dojo/query",
+	"dojo/string",
+	"../_Plugin",
+	"../../EnhancedGrid"
+], function(declare, array, connect, lang, html, evt, win, keys, query, string, _Plugin, EnhancedGrid){
 
-dojo.require("dojox.grid.enhanced._Plugin");
-
-dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._Plugin, {
+var NestedSorting = declare("dojox.grid.enhanced.plugins.NestedSorting", _Plugin, {
 	// summary:
 	//		Provides nested sorting feature
 	//
@@ -47,14 +58,15 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 		this._excludedColIdx = [];
 		this.nls = this.grid._nls;
 		this.grid.setSortInfo = function(){};
-		this.grid.setSortIndex = dojo.hitch(this, '_setGridSortIndex');
-		this.grid.getSortProps = dojo.hitch(this, 'getSortProps');
+		this.grid.setSortIndex = lang.hitch(this, '_setGridSortIndex');
+		this.grid.getSortIndex = function(){};
+		this.grid.getSortProps = lang.hitch(this, 'getSortProps');
 		if(this.grid.sortFields){
 			this._setGridSortIndex(this.grid.sortFields, null, true);
 		}
 		this.connect(this.grid.views, 'render', '_initSort');//including column resize
 		this.initCookieHandler();
-		dojo.subscribe("dojox/grid/rearrange/move/" + this.grid.id, dojo.hitch(this, '_onColumnDnD'));
+		this.subscribe("dojox/grid/rearrange/move/" + this.grid.id, lang.hitch(this, '_onColumnDnD'));
 	},
 	onStartUp: function(){
 		//overwrite base Grid functions
@@ -70,7 +82,7 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 		var m = mapping, obj = {}, d = this._sortData, p;
 		var cr = this._getCurrentRegion();
 		this._blurRegion(cr);
-		var idx = dojo.attr(this._getRegionHeader(cr), 'idx');
+		var idx = this._getRegionHeader(cr).getAttribute('idx');
 		for(p in m){
 			if(d[p]){
 				obj[m[p]] = d[p];
@@ -84,11 +96,11 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 			d[p] = obj[p];
 		}
 		var c = this._headerNodes[idx];
-		this._currRegionIdx = dojo.indexOf(this._getRegions(), c.firstChild);
+		this._currRegionIdx = array.indexOf(this._getRegions(), c.firstChild);
 		this._initSort(false);
 	},
 	_setGridSortIndex: function(inIndex, inAsc, noRefresh){
-		if(dojo.isArray(inIndex)){
+		if(lang.isArray(inIndex)){
 			var i, d, cell;
 			for(i = 0; i < inIndex.length; i++){
 				d = inIndex[i];
@@ -103,7 +115,7 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 				}
 			}
 			this.clearSort();
-			dojo.forEach(inIndex, function(d, i){
+			array.forEach(inIndex, function(d, i){
 				cell = this.grid.getCellByField(d.attribute);
 				this.setSortData(cell.index, 'index', i);
 				this.setSortData(cell.index, 'order', d.descending ? 'desc': 'asc');
@@ -128,17 +140,17 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 		// summary:
 		//		Initiate sorting
 		var g = this.grid, n = g.domNode, len = this._sortDef.length;
-		dojo.toggleClass(n, 'dojoxGridSorted', !!len);
-		dojo.toggleClass(n, 'dojoxGridSingleSorted', len === 1);
-		dojo.toggleClass(n, 'dojoxGridNestSorted', len > 1);
+		html.toggleClass(n, 'dojoxGridSorted', !!len);
+		html.toggleClass(n, 'dojoxGridSingleSorted', len === 1);
+		html.toggleClass(n, 'dojoxGridNestSorted', len > 1);
 		if(len > 0){
 			this._currMainSort = this._sortDef[0].descending ? 'desc' : 'asc';
 		}
 		var idx, excluded = this._excludedCoIdx = [];//reset it
 		//cache column index of hidden, un-sortable or indirect selection
-		this._headerNodes = dojo.query("th", g.viewsHeaderNode).forEach(function(n){
-			idx = parseInt(dojo.attr(n, 'idx'), 10);
-			if(dojo.style(n, 'display') === 'none' || g.layout.cells[idx]['nosort'] || (g.canSort && !g.canSort(idx, g.layout.cells[idx]['field']))){
+		this._headerNodes = query("th", g.viewsHeaderNode).forEach(function(n){
+			idx = parseInt(n.getAttribute('idx'), 10);
+			if(html.style(n, 'display') === 'none' || g.layout.cells[idx]['nosort'] || (g.canSort && !g.canSort(idx, g.layout.cells[idx]['field']))){
 				excluded.push(idx);
 			}
 		});
@@ -151,47 +163,48 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 	_initHeaderNode: function(node){
 		// summary:
 		//		Initiate sort for each header cell node
-		var sortNode = dojo.query('.dojoxGridSortNode', node)[0];
+		html.toggleClass(node, 'dojoxGridSortNoWrap', true);
+		var sortNode = query('.dojoxGridSortNode', node)[0];
 		if(sortNode){
-			dojo.toggleClass(sortNode, 'dojoxGridSortNoWrap', true);
+			html.toggleClass(sortNode, 'dojoxGridSortNoWrap', true);
 		}
-		if(dojo.indexOf(this._excludedCoIdx, dojo.attr(node,'idx')) >= 0){
-			dojo.addClass(node, 'dojoxGridNoSort');
+		if(array.indexOf(this._excludedCoIdx, node.getAttribute('idx')) >= 0){
+			html.addClass(node, 'dojoxGridNoSort');
 			return;
 		}
-		if(!dojo.query('.dojoxGridSortBtn', node).length){
+		if(!query('.dojoxGridSortBtn', node).length){
 			//clear any previous connects
-			this._connects = dojo.filter(this._connects, function(conn){
+			this._connects = array.filter(this._connects, function(conn){
 				if(conn._sort){
-					dojo.disconnect(conn);
+					connect.disconnect(conn);
 					return false;
 				}
 				return true;
 			});
-			var n = dojo.create('a', {
+			var n = html.create('a', {
 				className: 'dojoxGridSortBtn dojoxGridSortBtnNested',
-				title: this.nls.nestedSort + ' - ' + this.nls.ascending,
+				title: string.substitute(this.nls.sortingState, [this.nls.nestedSort, this.nls.ascending]),
 				innerHTML: '1'
 			}, node.firstChild, 'last');
-			n.onmousedown = dojo.stopEvent;
-			n = dojo.create('a', {
+			n.onmousedown = evt.stop;
+			n = html.create('a', {
 				className: 'dojoxGridSortBtn dojoxGridSortBtnSingle',
-				title: this.nls.singleSort + ' - ' + this.nls.ascending
+				title: string.substitute(this.nls.sortingState, [this.nls.singleSort, this.nls.ascending])
 			}, node.firstChild, 'last');
-			n.onmousedown = dojo.stopEvent;
+			n.onmousedown = evt.stop;
 		}else{
 			//deal with small height grid which doesn't re-render the grid after refresh
-			var a1 = dojo.query('.dojoxGridSortBtnSingle', node)[0];
-			var a2 = dojo.query('.dojoxGridSortBtnNested', node)[0];
+			var a1 = query('.dojoxGridSortBtnSingle', node)[0];
+			var a2 = query('.dojoxGridSortBtnNested', node)[0];
 			a1.className = 'dojoxGridSortBtn dojoxGridSortBtnSingle';
 			a2.className = 'dojoxGridSortBtn dojoxGridSortBtnNested';
 			a2.innerHTML = '1';
-			dojo.removeClass(node, 'dojoxGridCellShowIndex');
-			dojo.removeClass(node.firstChild, 'dojoxGridSortNodeSorted');
-			dojo.removeClass(node.firstChild, 'dojoxGridSortNodeAsc');
-			dojo.removeClass(node.firstChild, 'dojoxGridSortNodeDesc');
-			dojo.removeClass(node.firstChild, 'dojoxGridSortNodeMain');
-			dojo.removeClass(node.firstChild, 'dojoxGridSortNodeSub');
+			html.removeClass(node, 'dojoxGridCellShowIndex');
+			html.removeClass(node.firstChild, 'dojoxGridSortNodeSorted');
+			html.removeClass(node.firstChild, 'dojoxGridSortNodeAsc');
+			html.removeClass(node.firstChild, 'dojoxGridSortNodeDesc');
+			html.removeClass(node.firstChild, 'dojoxGridSortNodeMain');
+			html.removeClass(node.firstChild, 'dojoxGridSortNodeSub');
 		}
 		this._updateHeaderNodeUI(node);
 	},
@@ -199,9 +212,9 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 		// summary
 		//		See dojox.grid.enhanced._Events._onHeaderCellClick()
 		this._focusRegion(e.target);
-		if(dojo.hasClass(e.target, 'dojoxGridSortBtn')){
+		if(html.hasClass(e.target, 'dojoxGridSortBtn')){
 			this._onSortBtnClick(e);
-			dojo.stopEvent(e);
+			evt.stop(e);
 			this._focusRegion(this._getCurrentRegion());
 		}
 	},
@@ -216,25 +229,25 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 		var p;
 		for(p in this._sortData){
 			if(this._sortData[p] && this._sortData[p].index === 0){
-				dojo.addClass(this._headerNodes[p], 'dojoxGridCellShowIndex');
+				html.addClass(this._headerNodes[p], 'dojoxGridCellShowIndex');
 				break;
 			}
 		}
-		if(!dojo.hasClass(dojo.body(), 'dijit_a11y')){ return; }
+		if(!html.hasClass(win.body(), 'dijit_a11y')){ return; }
 		//a11y support
 		var i = e.cell.index, node = e.cellNode;
-		var singleSortBtn = dojo.query('.dojoxGridSortBtnSingle', node)[0];
-		var nestedSortBtn = dojo.query('.dojoxGridSortBtnNested', node)[0];
+		var singleSortBtn = query('.dojoxGridSortBtnSingle', node)[0];
+		var nestedSortBtn = query('.dojoxGridSortBtnNested', node)[0];
 		
 		var sortMode = 'none';
-		if(dojo.hasClass(this.grid.domNode, 'dojoxGridSingleSorted')){
+		if(html.hasClass(this.grid.domNode, 'dojoxGridSingleSorted')){
 			sortMode = 'single';
-		}else if(dojo.hasClass(this.grid.domNode, 'dojoxGridNestSorted')){
+		}else if(html.hasClass(this.grid.domNode, 'dojoxGridNestSorted')){
 			sortMode = 'nested';
 		}
-		var nestedIndex = dojo.attr(nestedSortBtn, 'orderIndex');
+		var nestedIndex = nestedSortBtn.getAttribute('orderIndex');
 		if(nestedIndex === null || nestedIndex === undefined){
-			dojo.attr(nestedSortBtn, 'orderIndex', nestedSortBtn.innerHTML);
+			nestedSortBtn.setAttribute('orderIndex', nestedSortBtn.innerHTML);
 			nestedIndex = nestedSortBtn.innerHTML;
 		}
 		if(this.isAsc(i)){
@@ -258,7 +271,7 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 		var p;
 		for(p in this._sortData){
 			if(this._sortData[p] && this._sortData[p].index === 0){
-				dojo.removeClass(this._headerNodes[p], 'dojoxGridCellShowIndex');
+				html.removeClass(this._headerNodes[p], 'dojoxGridCellShowIndex');
 				break;
 			}
 		}
@@ -269,14 +282,14 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 		//		Else if the click target is nested sort button, do nest sort.
 		//		Otherwise return.
 		var cellIdx = e.cell.index;
-		if(dojo.hasClass(e.target, 'dojoxGridSortBtnSingle')){
+		if(html.hasClass(e.target, 'dojoxGridSortBtnSingle')){
 			this._prepareSingleSort(cellIdx);
-		}else if(dojo.hasClass(e.target, 'dojoxGridSortBtnNested')){
+		}else if(html.hasClass(e.target, 'dojoxGridSortBtnNested')){
 			this._prepareNestedSort(cellIdx);
 		}else{
 			return;
 		}
-		dojo.stopEvent(e);
+		evt.stop(e);
 		this._doSort(cellIdx);
 	},
 	_doSort: function(cellIdx){
@@ -350,18 +363,18 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 		var cell = this._getCellByNode(node);
 		var cellIdx = cell.index;
 		var data = this._sortData[cellIdx];
-		var sortNode = dojo.query('.dojoxGridSortNode', node)[0];
-		var singleSortBtn = dojo.query('.dojoxGridSortBtnSingle', node)[0];
-		var nestedSortBtn = dojo.query('.dojoxGridSortBtnNested', node)[0];
+		var sortNode = query('.dojoxGridSortNode', node)[0];
+		var singleSortBtn = query('.dojoxGridSortBtnSingle', node)[0];
+		var nestedSortBtn = query('.dojoxGridSortBtnNested', node)[0];
 		
-		dojo.toggleClass(singleSortBtn, 'dojoxGridSortBtnAsc', this._currMainSort === 'asc');
-		dojo.toggleClass(singleSortBtn, 'dojoxGridSortBtnDesc', this._currMainSort === 'desc');
+		html.toggleClass(singleSortBtn, 'dojoxGridSortBtnAsc', this._currMainSort === 'asc');
+		html.toggleClass(singleSortBtn, 'dojoxGridSortBtnDesc', this._currMainSort === 'desc');
 		if(this._currMainSort === 'asc'){
-			singleSortBtn.title = this.nls.singleSort + ' - ' + this.nls.descending;
+			singleSortBtn.title = string.substitute(this.nls.sortingState, [this.nls.singleSort, this.nls.descending]);
 		}else if(this._currMainSort === 'desc'){
-			singleSortBtn.title = this.nls.singleSort + ' - ' + this.nls.unsorted;
+			singleSortBtn.title = string.substitute(this.nls.sortingState, [this.nls.singleSort, this.nls.unsorted]);
 		}else{
-			singleSortBtn.title = this.nls.singleSort + ' - ' + this.nls.ascending;
+			singleSortBtn.title = string.substitute(this.nls.sortingState, [this.nls.singleSort, this.nls.ascending]);
 		}
 		
 		var _this = this;
@@ -378,46 +391,48 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 			var a11ySingleLabelHover = columnInfo + ' - choose to sort by ' + orderAction;
 			var a11yNestedLabelHover = columnInfo + ' - choose to nested sort by ' + orderAction;
 			
-			dijit.setWaiState(singleSortBtn, 'label', a11ySingleLabel);
-			dijit.setWaiState(nestedSortBtn, 'label', a11yNestedLabel);
+			singleSortBtn.setAttribute("aria-label", a11ySingleLabel);
+			nestedSortBtn.setAttribute("aria-label", a11yNestedLabel);
 			
 			var handles = [
 				_this.connect(singleSortBtn, "onmouseover", function(){
-					dijit.setWaiState(singleSortBtn, 'label', a11ySingleLabelHover);
+					singleSortBtn.setAttribute("aria-label", a11ySingleLabelHover);
 				}),
 				_this.connect(singleSortBtn, "onmouseout", function(){
-					dijit.setWaiState(singleSortBtn, 'label', a11ySingleLabel);
+					singleSortBtn.setAttribute("aria-label", a11ySingleLabel);
 				}),
 				_this.connect(nestedSortBtn, "onmouseover", function(){
-					dijit.setWaiState(nestedSortBtn, 'label', a11yNestedLabelHover);
+					nestedSortBtn.setAttribute("aria-label", a11yNestedLabelHover);
 				}),
 				_this.connect(nestedSortBtn, "onmouseout", function(){
-					dijit.setWaiState(nestedSortBtn, 'label', a11yNestedLabel);
+					nestedSortBtn.setAttribute("aria-label", a11yNestedLabel);
 				})
 			];
-			dojo.forEach(handles, function(handle){ handle._sort = true; });
+			array.forEach(handles, function(handle){ handle._sort = true; });
 		}
 		setWaiState();
 
-		var a11y = dojo.hasClass(dojo.body(), "dijit_a11y");
+		var a11y = html.hasClass(win.body(), "dijit_a11y");
 		if(!data){
 			nestedSortBtn.innerHTML = this._sortDef.length + 1;
+			nestedSortBtn.title = string.substitute(this.nls.sortingState, [this.nls.nestedSort, this.nls.ascending]);
+			if(a11y){sortNode.innerHTML = this._a11yText.dojoxGridUnsortedTip;}
 			return;
 		}
 		if(data.index || (data.index === 0 && this._sortDef.length > 1)){
 			nestedSortBtn.innerHTML = data.index + 1;
 		}
-		dojo.addClass(sortNode, 'dojoxGridSortNodeSorted');
+		html.addClass(sortNode, 'dojoxGridSortNodeSorted');
 		if(this.isAsc(cellIdx)){
-			dojo.addClass(sortNode, 'dojoxGridSortNodeAsc');
-			nestedSortBtn.title = this.nls.nestedSort + ' - ' + this.nls.descending;
+			html.addClass(sortNode, 'dojoxGridSortNodeAsc');
+			nestedSortBtn.title = string.substitute(this.nls.sortingState, [this.nls.nestedSort, this.nls.descending]);
 			if(a11y){sortNode.innerHTML = this._a11yText.dojoxGridAscendingTip;}
 		}else if(this.isDesc(cellIdx)){
-			dojo.addClass(sortNode, 'dojoxGridSortNodeDesc');
-			nestedSortBtn.title = this.nls.nestedSort + ' - ' + this.nls.unsorted;
+			html.addClass(sortNode, 'dojoxGridSortNodeDesc');
+			nestedSortBtn.title = string.substitute(this.nls.sortingState, [this.nls.nestedSort, this.nls.unsorted]);
 			if(a11y){sortNode.innerHTML = this._a11yText.dojoxGridDescendingTip;}
 		}
-		dojo.addClass(sortNode, (data.index === 0 ? 'dojoxGridSortNodeMain' : 'dojoxGridSortNodeSub'));
+		html.addClass(sortNode, (data.index === 0 ? 'dojoxGridSortNodeMain' : 'dojoxGridSortNodeSub'));
 	},
 	isAsc: function(cellIndex){
 		return this._sortData[cellIndex].order === 'asc';
@@ -444,8 +459,8 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 		if(this.grid.addCookieHandler){
 			this.grid.addCookieHandler({
 				name: "sortOrder",
-				onLoad: dojo.hitch(this, '_loadNestedSortingProps'),
-				onSave: dojo.hitch(this, '_saveNestedSortingProps')
+				onLoad: lang.hitch(this, '_loadNestedSortingProps'),
+				onSave: lang.hitch(this, '_saveNestedSortingProps')
 			});
 		}
 	},
@@ -462,16 +477,16 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 		this._focusRegions = this._getRegions();
 		if(!this._headerArea){
 			var area = this._headerArea = f.getArea('header');
-			area.onFocus = f.focusHeader = dojo.hitch(this, '_focusHeader');
-			area.onBlur = f.blurHeader = f._blurHeader = dojo.hitch(this, '_blurHeader');
-			area.onMove = dojo.hitch(this, '_onMove');
-			area.onKeyDown = dojo.hitch(this, '_onKeyDown');
+			area.onFocus = f.focusHeader = lang.hitch(this, '_focusHeader');
+			area.onBlur = f.blurHeader = f._blurHeader = lang.hitch(this, '_blurHeader');
+			area.onMove = lang.hitch(this, '_onMove');
+			area.onKeyDown = lang.hitch(this, '_onKeyDown');
 			area._regions = [];
 			area.getRegions = null;
 			this.connect(this.grid, 'onBlur', '_blurHeader');
 		}
 	},
-	_focusHeader: function(evt){
+	_focusHeader: function(e){
 		// summary:
 		//		Overwritten, see _FocusManager.focusHeader()
 		//delayed: Boolean
@@ -482,22 +497,22 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 			this._focusRegion(this._getCurrentRegion());
 		}
 		try{
-			dojo.stopEvent(evt);
+			evt.stop(e);
 		}catch(e){}
 		return true;
 	},
-	_blurHeader: function(evt){
+	_blurHeader: function(e){
 		this._blurRegion(this._getCurrentRegion());
 		return true;
 	},
-	_onMove: function(rowStep, colStep, evt){
+	_onMove: function(rowStep, colStep, e){
 		var curr = this._currRegionIdx || 0, regions = this._focusRegions;
 		var region = regions[curr + colStep];
 		if(!region){
 			return;
-		}else if(dojo.style(region, 'display') === 'none' || dojo.style(region, 'visibility') === 'hidden'){
+		}else if(html.style(region, 'display') === 'none' || html.style(region, 'visibility') === 'hidden'){
 			//if the region is invisible, keep finding next
-			this._onMove(rowStep, colStep + (colStep > 0 ? 1 : -1), evt);
+			this._onMove(rowStep, colStep + (colStep > 0 ? 1 : -1), e);
 			return;
 		}
 		this._focusRegion(region);
@@ -508,10 +523,10 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 	_onKeyDown: function(e, isBubble){
 		if(isBubble){
 			switch(e.keyCode){
-				case dojo.keys.ENTER:
-				case dojo.keys.SPACE:
-					if(dojo.hasClass(e.target, 'dojoxGridSortBtnSingle') ||
-						dojo.hasClass(e.target, 'dojoxGridSortBtnNested')){
+				case keys.ENTER:
+				case keys.SPACE:
+					if(html.hasClass(e.target, 'dojoxGridSortBtnSingle') ||
+						html.hasClass(e.target, 'dojoxGridSortBtnNested')){
 						this._onSortBtnClick(e);
 					}
 			}
@@ -519,9 +534,9 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 	},
 	_getRegionView: function(region){
 		var header = region;
-		while(header && !dojo.hasClass(header, 'dojoxGridHeader')){ header = header.parentNode; }
+		while(header && !html.hasClass(header, 'dojoxGridHeader')){ header = header.parentNode; }
 		if(header){
-			return dojo.filter(this.grid.views.views, function(view){
+			return array.filter(this.grid.views.views, function(view){
 				return view.headerNode === header;
 			})[0] || null;
 		}
@@ -530,14 +545,13 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 	_getRegions: function(){
 		var regions = [], cells = this.grid.layout.cells;
 		this._headerNodes.forEach(function(n, i){
-			if(dojo.style(n, 'display') === 'none'){return;}
+			if(html.style(n, 'display') === 'none'){return;}
 			if(cells[i]['isRowSelector']){
 				regions.push(n);
 				return;
 			}
-			dojo.query('.dojoxGridSortNode,.dojoxGridSortBtnNested,.dojoxGridSortBtnSingle', n)
-				.forEach(function(node){
-					dojo.attr(node, 'tabindex', 0);
+			query('.dojoxGridSortNode,.dojoxGridSortBtnNested,.dojoxGridSortBtnSingle', n).forEach(function(node){
+					node.setAttribute('tabindex', 0);
 					regions.push(node);
 			});
 		},this);
@@ -552,32 +566,32 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 			this._blurRegion(currRegion);
 		}
 		var header = this._getRegionHeader(region);
-		dojo.addClass(header, 'dojoxGridCellSortFocus');
-		if(dojo.hasClass(region, 'dojoxGridSortNode')){
-			dojo.addClass(region, 'dojoxGridSortNodeFocus');
-		}else if(dojo.hasClass(region, 'dojoxGridSortBtn')){
-			dojo.addClass(region, 'dojoxGridSortBtnFocus');
+		html.addClass(header, 'dojoxGridCellSortFocus');
+		if(html.hasClass(region, 'dojoxGridSortNode')){
+			html.addClass(region, 'dojoxGridSortNodeFocus');
+		}else if(html.hasClass(region, 'dojoxGridSortBtn')){
+			html.addClass(region, 'dojoxGridSortBtnFocus');
 		}
 		region.focus();
 		this.focus.currentArea('header');
-		this._currRegionIdx = dojo.indexOf(this._focusRegions, region);
+		this._currRegionIdx = array.indexOf(this._focusRegions, region);
 	},
 	_blurRegion: function(region){
 		if(!region){return;}
 		var header = this._getRegionHeader(region);
-		dojo.removeClass(header, 'dojoxGridCellSortFocus');
-		if(dojo.hasClass(region, 'dojoxGridSortNode')){
-			dojo.removeClass(region, 'dojoxGridSortNodeFocus');
-		}else if(dojo.hasClass(region, 'dojoxGridSortBtn')){
-			dojo.removeClass(region, 'dojoxGridSortBtnFocus');
+		html.removeClass(header, 'dojoxGridCellSortFocus');
+		if(html.hasClass(region, 'dojoxGridSortNode')){
+			html.removeClass(region, 'dojoxGridSortNodeFocus');
+		}else if(html.hasClass(region, 'dojoxGridSortBtn')){
+			html.removeClass(region, 'dojoxGridSortBtnFocus');
 		}
 		region.blur();
 	},
 	_getCurrentRegion: function(){
-		return this._focusRegions[this._currRegionIdx];
+		return this._focusRegions ? this._focusRegions[this._currRegionIdx] : null;
 	},
 	_getRegionHeader: function(region){
-		while(region && !dojo.hasClass(region, 'dojoxGridCell')){
+		while(region && !html.hasClass(region, 'dojoxGridCell')){
 			region = region.parentNode;
 		}
 		return region;
@@ -588,4 +602,8 @@ dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._P
 		this.inherited(arguments);
 	}
 });
-dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.NestedSorting);
+
+EnhancedGrid.registerPlugin(NestedSorting);
+
+return NestedSorting;
+});
diff --git a/dojox/grid/enhanced/plugins/Pagination.js b/dojox/grid/enhanced/plugins/Pagination.js
index b6df641..1250504 100644
--- a/dojox/grid/enhanced/plugins/Pagination.js
+++ b/dojox/grid/enhanced/plugins/Pagination.js
@@ -1,454 +1,343 @@
-dojo.provide("dojox.grid.enhanced.plugins.Pagination");
-
-dojo.require("dijit.form.NumberTextBox");
-dojo.require("dijit.form.Button");
-dojo.require("dojox.grid.enhanced._Plugin");
-dojo.require("dojox.grid.enhanced.plugins.Dialog");
-dojo.require("dojox.grid.enhanced.plugins._StoreLayer");
-
-dojo.requireLocalization("dojox.grid.enhanced", "Pagination");
-
-dojo.declare("dojox.grid.enhanced.plugins.Pagination", dojox.grid.enhanced._Plugin, {
-	// summary:
-	//		The typical pagination way as an alternative to deal with huge data set besides the default virtual scrolling way
-	
-	name: "pagination",
-	// The page size used with the store, default = 25.
-	pageSize: 25,
-	
-	defaultRows: 25,
-	
-	//current page we are at
-	_currentPage: 0,
-
-	//The currently obtained max # of rows to page through.
-	_maxSize: 0,
-	
-	init: function(){
-		this.gh = null;
-		this.grid.rowsPerPage = this.pageSize = this.grid.rowsPerPage ? this.grid.rowsPerPage : this.pageSize;
-		this.grid.usingPagination = true;
-		this.nls = dojo.i18n.getLocalization("dojox.grid.enhanced", "Pagination");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"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",
+	"./_StoreLayer",
+	"../_Plugin",
+	"../../EnhancedGrid",
+	"dijit/form/Button",
+	"dijit/form/NumberTextBox",
+	"dijit/focus",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"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){
 		
-		this._wrapStoreLayer();
-		this._createPaginators(this.option);
-		
-		this._regApis();
+var _GotoPagePane = declare("dojox.grid.enhanced.plugins.pagination._GotoPagePane", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
+	templateString: "<div>" + 
+						"<div class='dojoxGridDialogMargin' dojoAttachPoint='_mainMsgNode'></div>" +
+						"<div class='dojoxGridDialogMargin'>" +
+							"<input dojoType='dijit.form.NumberTextBox' style='width: 50px;' dojoAttachPoint='_pageInputBox' dojoAttachEvent='onKeyUp: _onKey'></input>" +
+							"<label dojoAttachPoint='_pageLabelNode'></label>" +
+						"</div>" +
+						"<div class='dojoxGridDialogButton'>" +
+							"<button dojoType='dijit.form.Button' dojoAttachPoint='_confirmBtn' dojoAttachEvent='onClick: _onConfirm'></button>" +
+							"<button dojoType='dijit.form.Button' dojoAttachPoint='_cancelBtn' dojoAttachEvent='onClick: _onCancel'></button>" +
+						"</div>" +
+					"</div>",
+	widgetsInTemplate: true,
+	dlg: null,
+	postMixInProperties: function(){
+		this.plugin = this.dlg.plugin;
 	},
-	
-	_createPaginators: function(paginationArgs){
-		// summary:
-		//		Function to create the pagination control bar.
-		this.paginators = [];
-		if(paginationArgs.position === "both"){
-			this.paginators = [
-				new dojox.grid.enhanced.plugins._Paginator(dojo.mixin(paginationArgs, {position: "bottom", plugin: this})),
-				new dojox.grid.enhanced.plugins._Paginator(dojo.mixin(paginationArgs, {position: "top", plugin: this}))
-			];
-		}else{
-			this.paginators = [new dojox.grid.enhanced.plugins._Paginator(dojo.mixin(paginationArgs, {plugin: this}))];
-		}
-	},
-	 
-	_wrapStoreLayer: function(){
-		var g = this.grid,
-			ns = dojox.grid.enhanced.plugins;
-		this._store = g.store;
-		this.query = g.query;
-		
-		this.forcePageStoreLayer = new ns._ForcedPageStoreLayer(this);
-		ns.wrap(g, "_storeLayerFetch", this.forcePageStoreLayer);
-		
-		this.connect(g, "setQuery", function(query){
-			if(query !== this.query){
-				this.query = query;
-			}
-		});
-	},
-	
-	_stopEvent: function(event){
-		try{
-			dojo.stopEvent(event);
-		}catch(e){}
-	},
-	
-	_onNew: function(item, parentInfo){
-		var totalPages = Math.ceil(this._maxSize / this.pageSize);
-		if(((this._currentPage + 1 === totalPages || totalPages === 0) && this.grid.rowCount < this.pageSize) || this.showAll){
-			dojo.hitch(this.grid, this._originalOnNew)(item, parentInfo);
-			this.forcePageStoreLayer.endIdx++;
-		}
-		this._maxSize++;
-		if(this.showAll){
-			this.pageSize++;
-		}
-		if(this.showAll && this.grid.autoHeight){
-			this.grid._refresh();
-		}else{
-			dojo.forEach(this.paginators, function(p){
-				p.update();
-			});
-		}
-	},
-	
-	_removeSelectedRows: function(){
-		this._multiRemoving = true;
-		this._originalRemove();
-		this._multiRemoving = false;
-		this.grid.resize();
-		this.grid._refresh();
-	},
-	
-	_onDelete: function(){
-		if(!this._multiRemoving){
-			this.grid.resize();
-			if(this.showAll){
-				this.grid._refresh();
-			}
-		}
-		if(this.grid.get('rowCount') === 0){
-			this.prevPage();
-		}
-	},
-	
-	_regApis: function(){
-		// summary:
-		//		register pagination public APIs to grid.
-		var g = this.grid;
-		// New added APIs
-		g.gotoPage = dojo.hitch(this, this.gotoPage);
-		g.nextPage = dojo.hitch(this, this.nextPage);
-		g.prevPage = dojo.hitch(this, this.prevPage);
-		g.gotoFirstPage = dojo.hitch(this, this.gotoFirstPage);
-		g.gotoLastPage = dojo.hitch(this, this.gotoLastPage);
-		g.changePageSize = dojo.hitch(this, this.changePageSize);
-		g.showGotoPageButton = dojo.hitch(this, this.showGotoPageButton);
-		g.getTotalRowCount = dojo.hitch(this, this.getTotalRowCount);
-		// Changed APIs
-		this.originalScrollToRow = dojo.hitch(g, g.scrollToRow);
-		g.scrollToRow = dojo.hitch(this, this.scrollToRow);
-		this._originalOnNew = dojo.hitch(g, g._onNew);
-		this._originalRemove = dojo.hitch(g, g.removeSelectedRows);
-		g.removeSelectedRows = dojo.hitch(this, this._removeSelectedRows);
-		g._onNew = dojo.hitch(this, this._onNew);
-		this.connect(g, "_onDelete", dojo.hitch(this, this._onDelete));
-	},
-	
-	destroy: function(){
+	postCreate: function(){
 		this.inherited(arguments);
-		var g = this.grid;
-		try{
-			dojo.forEach(this.paginators, function(p){
-				p.destroy();
-			});
-			g.unwrap(this.forcePageStoreLayer.name());
-			g._onNew = this._originalOnNew;
-			g.removeSelectedRows = this._originalRemove;
-			g.scrollToRow = this.originalScrollToRow;
-			this.paginators = null;
-			this.nls = null;
-		}catch(e){
-			console.warn("Pagination.destroy() error: ", e);
-		}
-	},
-	
-	nextPage: function(){
-		// summary:
-		//		Function to handle shifting to the next page in the list.
-		if(this._maxSize > ((this._currentPage + 1) * this.pageSize)){
-			//Current page is indexed at 0 and gotoPage expects 1-X.  So to go
-			//up  one, pass current page + 2!
-			this.gotoPage(this._currentPage + 2);
-		}
-	},
-
-	prevPage: function(){
-		// summary:
-		//		Function to handle shifting to the previous page in the list.
-		if(this._currentPage > 0){
-			//Current page is indexed at 0 and gotoPage expects 1-X.  So to go
-			//back one, pass current page!
-			this.gotoPage(this._currentPage);
-		}
+		this._mainMsgNode.innerHTML = this.plugin._nls[12];
+		this._confirmBtn.set("label", this.plugin._nls[14]);
+		this._confirmBtn.set("disabled", true);
+		this._cancelBtn.set("label", this.plugin._nls[15]);
 	},
-
-	gotoPage: function(page){
-		// summary:
-		//		Function to handle shifting to an arbirtary page in the list.
-		//	page:
-		//		The page to go to, starting at 1.
-		var totalPages = Math.ceil(this._maxSize / this.pageSize);
-		page--;
-		if(page < totalPages && page >= 0 && this._currentPage !== page){
-			this._currentPage = page;
-			// this._updateSelected();
-			this.grid.setQuery(this.query);
-			this.grid.resize();
+	_onConfirm: function(evt){
+		if(this._pageInputBox.isValid() && this._pageInputBox.getDisplayedValue() !== ""){
+			this.plugin.currentPage(this._pageInputBox.parse(this._pageInputBox.getDisplayedValue()));
+			this.dlg._gotoPageDialog.hide();
+			this._pageInputBox.reset();
 		}
+		stopEvent(evt);
 	},
-	
-	gotoFirstPage: function(){
-		// summary:
-		//		Go to the first page
-		this.gotoPage(1);
-	},
-	
-	gotoLastPage: function(){
-		// summary:
-		//		Go to the last page
-		var totalPages = Math.ceil(this._maxSize / this.pageSize);
-		this.gotoPage(totalPages);
+	_onCancel: function(evt){
+		this._pageInputBox.reset();
+		this.dlg._gotoPageDialog.hide();
+		stopEvent(evt);
 	},
-	
-	changePageSize: function(size){
-		// summary:
-		//		Change size of items per page.
-		//		This function will only be called by _Paginator
-		if(typeof size == "string"){
-			size = parseInt(size, 10);
+	_onKey: function(evt){
+		this._confirmBtn.set("disabled", !this._pageInputBox.isValid() || this._pageInputBox.getDisplayedValue() == "");
+		if(!evt.altKey && !evt.metaKey && evt.keyCode === keys.ENTER){
+			this._onConfirm(evt);
 		}
-		var startIndex = this.pageSize * this._currentPage;
-		dojo.forEach(this.paginators, function(f){
-			f.currentPageSize = this.grid.rowsPerPage = this.pageSize = size;
-			if(size >= this._maxSize){
-				this.grid.rowsPerPage = this.defaultRows;
-				this.grid.usingPagination = false;
-			}else{
-				this.grid.usingPagination = true;
-			}
-		}, this);
-		var endIndex = startIndex + Math.min(this.pageSize, this._maxSize);
-		if(endIndex > this._maxSize){
-			this.gotoLastPage();
-		}else{
-			var cp = Math.ceil(startIndex / this.pageSize);
-			if(cp !== this._currentPage){
-				this.gotoPage(cp + 1);
-			}else{
-				this.grid._refresh(true);
-			}
-		}
-		this.grid.resize();
-	},
-	
-	showGotoPageButton: function(flag){
-		// summary:
-		//		For show/hide the go to page button dynamically
-		// flag: boolean
-		//		Show the go to page button when flag is true, otherwise hide it
-		dojo.forEach(this.paginators, function(p){
-			p._showGotoButton(flag);
+	}
+});
+
+var _GotoPageDialog = declare("dojox.grid.enhanced.plugins.pagination._GotoPageDialog", null, {
+	pageCount: 0,
+	dlgPane: null,
+	constructor: function(plugin){
+		this.plugin = plugin;
+		this.dlgPane = new _GotoPagePane({"dlg": this});
+		this.dlgPane.startup();
+		this._gotoPageDialog = new Dialog({
+			"refNode": plugin.grid.domNode,
+			"title": this.plugin._nls[11],
+			"content": this.dlgPane
 		});
+		this._gotoPageDialog.startup();
 	},
-	
-	scrollToRow: function(inRowIndex){
-		// summary:
-		//		Override the grid.scrollToRow(), could jump to the right page
-		//		and scroll to the specific row
-		// inRowIndex: integer
-		//		The row index
-		var page = parseInt(inRowIndex / this.pageSize, 10),
-			totalPages = Math.ceil(this._maxSize / this.pageSize);
-		if(page > totalPages){
-			return;
-		}
-		this.gotoPage(page + 1);
-		var rowIdx = inRowIndex % this.pageSize;
-		this.grid.setScrollTop(this.grid.scroller.findScrollTop(rowIdx) + 1);
+	_updatePageCount: function(){
+		this.pageCount = this.plugin.getTotalPageNum();
+		this.dlgPane._pageInputBox.constraints = {fractional:false, min:1, max:this.pageCount};
+		this.dlgPane._pageLabelNode.innerHTML = string.substitute(this.plugin._nls[13], [this.pageCount]);
 	},
-	
-	getTotalRowCount: function(){
-		// summary:
-		//		Function for get total row count
-		return this._maxSize;
+	showDialog: function(){
+		this._updatePageCount();
+		this._gotoPageDialog.show();
+	},
+	destroy: function(){
+		this._gotoPageDialog.destroy();
 	}
 });
 
-dojo.declare("dojox.grid.enhanced.plugins._ForcedPageStoreLayer", dojox.grid.enhanced.plugins._StoreLayer, {
+var _ForcedPageStoreLayer = declare("dojox.grid.enhanced.plugins._ForcedPageStoreLayer", layers._StoreLayer, {
 	tags: ["presentation"],
-	
 	constructor: function(plugin){
 		this._plugin = plugin;
 	},
-	
 	_fetch: function(request){
-		var self = this,
-			plugin = self._plugin,
+		var _this = this,
+			plugin = _this._plugin,
 			grid = plugin.grid,
-			scope = request.scope || dojo.global,
+			scope = request.scope || win.global,
 			onBegin = request.onBegin;
-		
-		request.start = plugin._currentPage * plugin.pageSize + request.start;
-		self.startIdx = request.start;
-		self.endIdx = request.start + plugin.pageSize - 1;
-		if(onBegin && (plugin.showAll || dojo.every(plugin.paginators, function(p){
-			return plugin.showAll = !p.sizeSwitch && !p.pageStepper && !p.gotoButton;
-		}))){
+		request.start = (plugin._currentPage - 1) * plugin._currentPageSize + request.start;
+		_this.startIdx = request.start;
+		_this.endIdx = request.start + plugin._currentPageSize - 1;
+		var p = plugin._paginator;
+		if(!plugin._showAll){
+			plugin._showAll = !p.sizeSwitch && !p.pageStepper && !p.gotoButton;
+		}
+		if(onBegin && plugin._showAll){
 			request.onBegin = function(size, req){
-				plugin._maxSize = plugin.pageSize = size;
-				self.startIdx = 0;
-				self.endIdx = size - 1;
-				dojo.forEach(plugin.paginators, function(f){
-					f.update();
-				});
+				plugin._maxSize = plugin._currentPageSize = size;
+				_this.startIdx = 0;
+				_this.endIdx = size - 1;
+				plugin._paginator._update();
 				req.onBegin = onBegin;
 				req.onBegin.call(scope, size, req);
 			};
 		}else if(onBegin){
 			request.onBegin = function(size, req){
 				req.start = 0;
-				req.count = plugin.pageSize;
+				req.count = plugin._currentPageSize;
 				plugin._maxSize = size;
-				self.endIdx = self.endIdx >= size ? (size - 1) : self.endIdx;
-				if(self.startIdx > size && size !== 0){
+				_this.endIdx = _this.endIdx >= size ? (size - 1) : _this.endIdx;
+				if(_this.startIdx > size && size !== 0){
 					grid._pending_requests[req.start] = false;
-					plugin.gotoFirstPage();
+					plugin.firstPage();
 				}
-				dojo.forEach(plugin.paginators, function(f){
-					f.update();
-				});
+				plugin._paginator._update();
 				req.onBegin = onBegin;
-				req.onBegin.call(scope, Math.min(plugin.pageSize, (size - self.startIdx)), req);
+				req.onBegin.call(scope, Math.min(plugin._currentPageSize, (size - _this.startIdx)), req);
 			};
 		}
-		return dojo.hitch(this._store, this._originFetch)(request);
+		return lang.hitch(this._store, this._originFetch)(request);
 	}
 });
 
-dojo.declare("dojox.grid.enhanced.plugins._Paginator", [dijit._Widget,dijit._Templated], {
-	templatePath: dojo.moduleUrl("dojox.grid","enhanced/templates/Pagination.html"),
-		
-	// pagination bar position - "bottom"|"top"
-	position: "bottom",
-	
-	// max data item size
-	_maxItemSize: 0,
-	
-	// description message status params
-	description: true,
-	
-	// fast step page status params
-	pageStepper: true,
-	
-	maxPageStep: 7,
-	
-	// items per page size switch params
-	sizeSwitch: true,
-	
-	pageSizes: ["10", "25", "50", "100", "All"],
-	
-	gotoButton: false,
-	
+var stopEvent = function(evt){
+	try{
+		event.stop(evt);
+	}catch(e){}
+};
+
+var _Focus = declare("dojox.grid.enhanced.plugins.pagination._Focus", null, {
+	_focusedNode: null,
+	_isFocused: false,
+	constructor: function(paginator){
+		this._pager = paginator;
+		var focusMgr =  paginator.plugin.grid.focus;
+		paginator.plugin.connect(paginator, 'onSwitchPageSize', lang.hitch(this, '_onActive'));
+		paginator.plugin.connect(paginator, 'onPageStep', lang.hitch(this, '_onActive'));
+		paginator.plugin.connect(paginator, 'onShowGotoPageDialog', lang.hitch(this, '_onActive'));
+		paginator.plugin.connect(paginator, '_update', lang.hitch(this, '_moveFocus'));
+	},
+	_onFocus: function(evt, step){
+		var node, nodes;
+		if(!this._isFocused){
+			node = this._focusedNode || query('[tabindex]', this._pager.domNode)[0];
+		}else if(step && this._focusedNode){
+			var dir = step > 0 ? -1 : 1,
+				tabindex = parseInt(this._focusedNode.getAttribute('tabindex'), 10) + dir;
+			while(tabindex >= -3 && tabindex < 0){
+				node = query('[tabindex=' + tabindex + ']', this._pager.domNode)[0];
+				if(node){
+					break;
+				}else{
+					tabindex += dir;
+				}
+			}
+		}
+		return this._focus(node, evt);
+	},
+	_onBlur: function(evt, step){
+		if(!step || !this._focusedNode){
+			this._isFocused = false;
+			if(this._focusedNode && html.hasClass(this._focusedNode, 'dojoxGridButtonFocus')){
+				html.removeClass(this._focusedNode, 'dojoxGridButtonFocus');
+			}
+			return true;
+		}
+		var node, dir = step > 0 ? -1 : 1,
+			tabindex = parseInt(this._focusedNode.getAttribute('tabindex'), 10) + dir;
+		while(tabindex >= -3 && tabindex < 0){
+			node = query('[tabindex=' + tabindex + ']', this._pager.domNode)[0];
+			if(node){
+				break;
+			}else{
+				tabindex += dir;
+			}
+		}
+		if(!node){
+			this._isFocused = false;
+			if(html.hasClass(this._focusedNode, 'dojoxGridButtonFocus')){
+				html.removeClass(this._focusedNode, 'dojoxGridButtonFocus');
+			}
+		}
+		return node ? false : true;
+	},
+	_onMove: function(rowDelta, colDelta, evt){
+		if(this._focusedNode){
+			var tabindex = this._focusedNode.getAttribute('tabindex'),
+				delta = colDelta == 1 ? "nextSibling" : "previousSibling",
+				node = this._focusedNode[delta];
+			while(node){
+				if(node.getAttribute('tabindex') == tabindex){
+					this._focus(node);
+					break;
+				}
+				node = node[delta];
+			}
+		}
+	},
+	_focus: function(node, evt){
+		if(node){
+			this._isFocused = true;
+			if(kernel.isIE && this._focusedNode){
+				html.removeClass(this._focusedNode, 'dojoxGridButtonFocus');
+			}
+			this._focusedNode = node;
+			node.focus();
+			if(kernel.isIE){
+				html.addClass(node, 'dojoxGridButtonFocus');
+			}
+			stopEvent(evt);
+			return true;
+		}
+		return false;
+	},
+	_onActive: function(e){
+		this._focusedNode = e.target;
+		if(!this._isFocused){
+			this._pager.plugin.grid.focus.focusArea('pagination' + this._pager.position);
+		}
+	},
+	_moveFocus: function(){
+		if(this._focusedNode && !this._focusedNode.getAttribute('tabindex')){
+			var next = this._focusedNode.nextSibling;
+			while(next){
+				if(next.getAttribute('tabindex')){
+					this._focus(next);
+					return;
+				}
+				next = next.nextSibling;
+			}
+			var prev = this._focusedNode.previousSibling;
+			while(prev){
+				if(prev.getAttribute('tabindex')){
+					this._focus(prev);
+					return;
+				}
+				prev = prev.previousSibling;
+			}
+			this._focusedNode = null;
+			this._onBlur();
+		}else if(kernel.isIE && this._focusedNode){
+			html.addClass(this._focusedNode, 'dojoxGridButtonFocus');
+		}
+	}
+});
+
+var _Paginator = declare("dojox.grid.enhanced.plugins._Paginator", [_Widget, _TemplatedMixin], {
+	templateString: template,
 	constructor: function(params){
-		dojo.mixin(this, params);
+		lang.mixin(this, params);
 		this.grid = this.plugin.grid;
-		this.itemTitle = this.itemTitle ? this.itemTitle : this.plugin.nls.itemTitle;
-		this.descTemplate = this.descTemplate ? this.descTemplate : this.plugin.nls.descTemplate;
 	},
-	
 	postCreate: function(){
 		this.inherited(arguments);
-		this._setWidthValue();
-		var self = this;
-		var g = this.grid;
-		this.plugin.connect(g, "_resize", dojo.hitch(this, "_resetGridHeight"));
-		this._originalResize = dojo.hitch(g, "resize");
+		var _this = this, g = this.grid;
+		this.plugin.connect(g, "_resize", lang.hitch(this, "_resetGridHeight"));
+		this._originalResize = g.resize;
 		g.resize = function(changeSize, resultSize){
-			self._changeSize = g._pendingChangeSize = changeSize;
-			self._resultSize = g._pendingResultSize = resultSize;
-			g.sizeChange();
+			_this._changeSize = changeSize;
+			_this._resultSize = resultSize;
+			_this._originalResize.apply(g, arguments);
 		};
+		this.focus = _Focus(this);
 		this._placeSelf();
 	},
-	
 	destroy: function(){
 		this.inherited(arguments);
-		this.grid.focus.removeArea("pagination" + this.position.toLowerCase());
+		this.grid.focus.removeArea("pagination" + this.position);
 		if(this._gotoPageDialog){
 			this._gotoPageDialog.destroy();
-			dojo.destroy(this.gotoPageTd);
-			delete this.gotoPageTd;
-			delete this._gotoPageDialog;
 		}
 		this.grid.resize = this._originalResize;
-		this.pageSizes = null;
 	},
-	
-	update: function(){
+	onSwitchPageSize: function(/*Event*/evt){
+
+	},
+	onPageStep: function(/*Event*/evt){
+
+	},
+	onShowGotoPageDialog: function(/*Event*/evt){
+
+	},
+	_update: function(){
 		// summary:
 		//		Function to update paging information and update
 		//		pagination bar display.
-		this.currentPageSize = this.plugin.pageSize;
-		this._maxItemSize = this.plugin._maxSize;
-		
-		// update pagination bar display information
 		this._updateDescription();
 		this._updatePageStepper();
 		this._updateSizeSwitch();
 		this._updateGotoButton();
 	},
-	
-	_setWidthValue: function(){
-		var type = ["description", "sizeSwitch", "pageStepper"];
-		var endWith = function(str1, str2){
-			var reg = new RegExp(str2+"$");
-			return reg.test(str1);
-		};
-		dojo.forEach(type, function(t){
-			var width, flag = this[t];
-			if(flag === undefined || typeof flag == "boolean"){
-				return;
-			}
-			if(dojo.isString(flag)){
-				width = endWith(flag, "px") || endWith(flag, "%") || endWith(flag, "em") ? flag : parseInt(flag, 10) > 0 ? parseInt(flag, 10) + "px" : null;
-			}else if(typeof flag === "number" && flag > 0){
-				width = flag + "px";
-			}
-			this[t] = width ? true : false;
-			this[t + "Width"] = width;
-		}, this);
-	},
-	
-	_regFocusMgr: function(position){
+	_registerFocus: function(isTop){
 		// summary:
 		//		Function to register pagination bar to focus manager.
-		this.grid.focus.addArea({
-			name: "pagination" + position,
-			onFocus: dojo.hitch(this, this._onFocusPaginator),
-			onBlur: dojo.hitch(this, this._onBlurPaginator),
-			onMove: dojo.hitch(this, this._moveFocus),
-			onKeyDown: dojo.hitch(this, this._onKeyDown)
+		var focusMgr = this.grid.focus, 
+			name = "pagination" + this.position,
+			f = this.focus;
+		focusMgr.addArea({
+			name: name,
+			onFocus: lang.hitch(this.focus, "_onFocus"),
+			onBlur: lang.hitch(this.focus, "_onBlur"),
+			onMove: lang.hitch(this.focus, "_onMove")
 		});
-		switch(position){
-			case "top":
-				this.grid.focus.placeArea("pagination" + position, "before", "header");
-				break;
-			case "bottom":
-			default:
-				this.grid.focus.placeArea("pagination" + position, "after", "content");
-				break;
-		}
+		focusMgr.placeArea(name, isTop ? "before" : "after", isTop ? "header" : "content");
 	},
-	
 	_placeSelf: function(){
 		// summary:
 		//		Place pagination bar to a position.
 		//		There are two options, top of the grid, bottom of the grid.
-		var g = this.grid;
-		var	position = dojo.trim(this.position.toLowerCase());
-		switch(position){
-			case "top":
-				this.placeAt(g.viewsHeaderNode, "before");
-				this._regFocusMgr("top");
-				break;
-			case "bottom":
-			default:
-				this.placeAt(g.viewsNode, "after");
-				this._regFocusMgr("bottom");
-				break;
-		}
+		var g = this.grid,
+			isTop = this.position == "top";
+		this.placeAt(isTop ? g.viewsHeaderNode : g.viewsNode, isTop ? "before" : "after");
+		this._registerFocus(isTop);
 	},
-	
 	_resetGridHeight: function(changeSize, resultSize){
 		// summary:
 		//		Function of resize grid height to place this pagination bar.
@@ -465,165 +354,133 @@ dojo.declare("dojox.grid.enhanced.plugins._Paginator", [dijit._Widget,dijit._Tem
 		}
 		var padBorder = g._getPadBorder().h;
 		if(!this.plugin.gh){
-			this.plugin.gh = dojo.contentBox(g.domNode).h + 2 * padBorder;
+			this.plugin.gh = html.contentBox(g.domNode).h + 2 * padBorder;
 		}
 		if(resultSize){
 			changeSize = resultSize;
 		}
 		if(changeSize){
-			this.plugin.gh = dojo.contentBox(g.domNode).h + 2 * padBorder;
+			this.plugin.gh = html.contentBox(g.domNode).h + 2 * padBorder;
 		}
 		var gh = this.plugin.gh,
 			hh = g._getHeaderHeight(),
-			ph = dojo.marginBox(this.domNode).h;
-		ph = this.plugin.paginators[1] ? ph * 2 : ph;
-		if(typeof g.autoHeight == "number"){
+			ph = html.marginBox(this.domNode).h;
+		// ph = this.plugin._paginator.position == "bottom" ? ph * 2 : ph;
+		if(typeof g.autoHeight === "number"){
 			var cgh = gh + ph - padBorder;
-			dojo.style(g.domNode, "height", cgh + "px");
-			dojo.style(g.viewsNode, "height", (cgh - ph - hh) + "px");
-			
-			this._styleMsgNode(hh, dojo.marginBox(g.viewsNode).w, cgh - ph - hh);
+			html.style(g.domNode, "height", cgh + "px");
+			html.style(g.viewsNode, "height", (cgh - ph - hh) + "px");
+			this._styleMsgNode(hh, html.marginBox(g.viewsNode).w, cgh - ph - hh);
 		}else{
 			var h = gh - ph - hh - padBorder;
-			dojo.style(g.viewsNode, "height", h + "px");
-			var hasHScroller = dojo.some(g.views.views, function(v){
+			html.style(g.viewsNode, "height", h + "px");
+			var hasHScroller = array.some(g.views.views, function(v){
 				return v.hasHScrollbar();
 			});
-			dojo.forEach(g.viewsNode.childNodes, function(c, idx){
-				dojo.style(c, "height", h + "px");
+			array.forEach(g.viewsNode.childNodes, function(c){
+				html.style(c, "height", h + "px");
 			});
-			dojo.forEach(g.views.views, function(v, idx){
+			array.forEach(g.views.views, function(v){
 				if(v.scrollboxNode){
 					if(!v.hasHScrollbar() && hasHScroller){
-						dojo.style(v.scrollboxNode, "height", (h - dojox.html.metrics.getScrollbar().h) + "px");
+						html.style(v.scrollboxNode, "height", (h - metrics.getScrollbar().h) + "px");
 					}else{
-						dojo.style(v.scrollboxNode, "height", h + "px");
+						html.style(v.scrollboxNode, "height", h + "px");
 					}
 				}
 			});
-			this._styleMsgNode(hh, dojo.marginBox(g.viewsNode).w, h);
+			this._styleMsgNode(hh, html.marginBox(g.viewsNode).w, h);
 		}
 	},
-	
 	_styleMsgNode: function(top, width, height){
 		var messagesNode = this.grid.messagesNode;
-		dojo.style(messagesNode, {"position": "absolute", "top": top + "px", "width": width + "px", "height": height + "px", "z-Index": "100"});
+		html.style(messagesNode, {"position": "absolute", "top": top + "px", "width": width + "px", "height": height + "px", "z-Index": "100"});
 	},
-	
 	_updateDescription: function(){
 		// summary:
 		//		Update size information.
-		var s = this.plugin.forcePageStoreLayer;
+		var s = this.plugin.forcePageStoreLayer,
+			maxSize = this.plugin._maxSize,
+			nls = this.plugin._nls,
+			getItemTitle = function(){
+				return maxSize <= 0 || maxSize == 1 ? nls[5] : nls[4];
+			};
 		if(this.description && this.descriptionDiv){
-			this.descriptionDiv.innerHTML = this._maxItemSize > 0 ? dojo.string.substitute(this.descTemplate, [this.itemTitle, this._maxItemSize, s.startIdx + 1, s.endIdx + 1]) : "0 " + this.itemTitle;
-		}
-		if(this.descriptionWidth){
-			dojo.style(this.descriptionTd, "width", this.descriptionWidth);
+			this.descriptionDiv.innerHTML = maxSize > 0 ? string.substitute(nls[0], [getItemTitle(), maxSize, s.startIdx + 1, s.endIdx + 1]) : "0 " + getItemTitle();
 		}
 	},
-	
 	_updateSizeSwitch: function(){
 		// summary:
 		//		Update "items per page" information.
-		if(!this.sizeSwitchTd){
-			return;
-		}
-		if(!this.sizeSwitch || this._maxItemSize <= 0){
-			dojo.style(this.sizeSwitchTd, "display", "none");
-			return;
-		}else{
-			dojo.style(this.sizeSwitchTd, "display", "");
-		}
-		if(this.initializedSizeNode && !this.pageSizeValue){
-			// do not update page size if page size was not changed
+		html.style(this.sizeSwitchTd, "display", this.sizeSwitch ? "" : "none");
+		if(!this.sizeSwitch){
 			return;
 		}
 		if(this.sizeSwitchTd.childNodes.length < 1){
 			this._createSizeSwitchNodes();
 		}
-		this._updateSwitchNodeClass();
-		
-		// move focus to next activable node
-		this._moveToNextActivableNode(this._getAllPageSizeNodes(), this.pageSizeValue);
-		this.pageSizeValue = null;
+		this._updateSwitchNodesStyle();
 	},
-	
 	_createSizeSwitchNodes: function(){
 		// summary:
 		//		The function to create the size switch nodes
-		var node = null;
-		if(!this.pageSizes || this.pageSizes.length < 1){
-			return;
-		}
-		dojo.forEach(this.pageSizes, function(size){
+		var node = null, 
+			nls = this.plugin._nls, 
+			connect = lang.hitch(this.plugin, 'connect');
+		array.forEach(this.pageSizes, function(size){
 			// create page size switch node
-			size = dojo.trim(size);
-			var labelValue = size.toLowerCase() == "all" ? this.plugin.nls.allItemsLabelTemplate : dojo.string.substitute(this.plugin.nls.pageSizeLabelTemplate, [size]);
-			node = dojo.create("span", {innerHTML: size, title: labelValue, value: size, tabindex: 0}, this.sizeSwitchTd, "last");
+			var labelValue = isFinite(size) ? string.substitute(nls[2], [size]) : nls[1],
+				value = isFinite(size) ? size : nls[16];
+			node = html.create("span", {innerHTML: value, title: labelValue, value: size, tabindex: "-1"}, this.sizeSwitchTd, "last");
 			// for accessibility
-			dijit.setWaiState(node, "label", labelValue);
+			node.setAttribute("aria-label", labelValue);
 			// connect event
-			this.plugin.connect(node, "onclick", dojo.hitch(this, "_onSwitchPageSize"));
-			this.plugin.connect(node, "onmouseover", function(e){
-				dojo.addClass(e.target, "dojoxGridPageTextHover");
+			connect(node, "onclick", lang.hitch(this, "_onSwitchPageSize"));
+			connect(node, "onkeydown", lang.hitch(this, "_onSwitchPageSize"));
+			connect(node, "onmouseover", function(e){
+				html.addClass(e.target, "dojoxGridPageTextHover");
 			});
-			this.plugin.connect(node, "onmouseout", function(e){
-				dojo.removeClass(e.target, "dojoxGridPageTextHover");
+			connect(node, "onmouseout", function(e){
+				html.removeClass(e.target, "dojoxGridPageTextHover");
 			});
 			// create a separation node
-			node = dojo.create("span", {innerHTML: "|"}, this.sizeSwitchTd, "last");
-			dojo.addClass(node, "dojoxGridSeparator");
+			node = html.create("span", {innerHTML: "|"}, this.sizeSwitchTd, "last");
+			html.addClass(node, "dojoxGridSeparator");
 		}, this);
 		// delete last separation node
-		dojo.destroy(node);
-		this.initializedSizeNode = true;
-		if(this.sizeSwitchWidth){
-			dojo.style(this.sizeSwitchTd, "width", this.sizeSwitchWidth);
-		}
+		html.destroy(node);
 	},
-	
-	_updateSwitchNodeClass: function(){
+	_updateSwitchNodesStyle: function(){
 		// summary:
 		//		Update the switch nodes style
 		var size = null;
-		var hasActivedNode = false;
 		var styleNode = function(node, status){
 			if(status){
-				dojo.addClass(node, "dojoxGridActivedSwitch");
-				dojo.attr(node, "tabindex", "-1");
-				hasActivedNode = true;
+				html.addClass(node, "dojoxGridActivedSwitch");
+				html.removeAttr(node, "tabindex");
 			}else{
-				dojo.addClass(node, "dojoxGridInactiveSwitch");
-				dojo.attr(node, "tabindex", "0");
+				html.addClass(node, "dojoxGridInactiveSwitch");
+				node.setAttribute("tabindex", "-1");
 			}
 		};
-		dojo.forEach(this.sizeSwitchTd.childNodes, function(node){
+		array.forEach(this.sizeSwitchTd.childNodes, function(node){
 			if(node.value){
+				html.removeClass(node);
 				size = node.value;
-				dojo.removeClass(node);
-				if(this.pageSizeValue){
-					styleNode(node, size === this.pageSizeValue && !hasActivedNode);
+				if(this.plugin._showAll){
+					styleNode(node, isNaN(parseInt(size, 10)));
 				}else{
-					if(size.toLowerCase() == "all"){
-						size = this._maxItemSize;
-					}
-					styleNode(node, this.currentPageSize === parseInt(size, 10) && !hasActivedNode);
+					styleNode(node, this.plugin._currentPageSize == size);
 				}
 			}
 		}, this);
 	},
-	
 	_updatePageStepper: function(){
 		// summary:
 		//		Update the page step nodes
-		if(!this.pageStepperTd){
-			return;
-		}
-		if(!this.pageStepper || this._maxItemSize <= 0){
-			dojo.style(this.pageStepperTd, "display", "none");
+		html.style(this.pageStepperTd, "display", this.pageStepper ? "" : "none");
+		if(!this.pageStepper){
 			return;
-		}else{
-			dojo.style(this.pageStepperTd, "display", "");
 		}
 		if(this.pageStepperDiv.childNodes.length < 1){
 			this._createPageStepNodes();
@@ -631,57 +488,50 @@ dojo.declare("dojox.grid.enhanced.plugins._Paginator", [dijit._Widget,dijit._Tem
 		}else{
 			this._resetPageStepNodes();
 		}
-		this._updatePageStepNodeClass();
-		
-		this._moveToNextActivableNode(this._getAllPageStepNodes(), this.pageStepValue);
-		this.pageStepValue = null;
+		this._updatePageStepNodesStyle();
 	},
-	
 	_createPageStepNodes: function(){
 		// summary:
 		//		Create the page step nodes if they do not exist
 		var startPage = this._getStartPage(),
 			stepSize = this._getStepPageSize(),
-			label = "",
-			node = null;
-		for(var i = startPage; i < this.maxPageStep + 1; i++){
-			label = dojo.string.substitute(this.plugin.nls.pageStepLabelTemplate, [i + ""]);
-			node = dojo.create("div", {innerHTML: i, value: i, title: label, tabindex: i < startPage + stepSize ? 0 : -1}, this.pageStepperDiv, "last");
-			dijit.setWaiState(node, "label", label);
+			label = "", node = null, i = startPage,
+			connect = lang.hitch(this.plugin, 'connect');
+		for(; i < startPage + this.maxPageStep + 1; i++){
+			label = string.substitute(this.plugin._nls[3], [i]);
+			node = html.create("div", {innerHTML: i, value: i, title: label}, this.pageStepperDiv, "last");
+			node.setAttribute("aria-label", label);
 			// connect event
-			this.plugin.connect(node, "onclick", dojo.hitch(this, "_onPageStep"));
-			this.plugin.connect(node, "onmouseover", function(e){
-				dojo.addClass(e.target, "dojoxGridPageTextHover");
+			connect(node, "onclick", lang.hitch(this, "_onPageStep"));
+			connect(node, "onkeydown", lang.hitch(this, "_onPageStep"));
+			connect(node, "onmouseover", function(e){
+				html.addClass(e.target, "dojoxGridPageTextHover");
 			});
-			this.plugin.connect(node, "onmouseout", function(e){
-				dojo.removeClass(e.target, "dojoxGridPageTextHover");
+			connect(node, "onmouseout", function(e){
+				html.removeClass(e.target, "dojoxGridPageTextHover");
 			});
-			dojo.style(node, "display", i < startPage + stepSize ? "block" : "none");
-		}
-		if(this.pageStepperWidth){
-			dojo.style(this.pageStepperTd, "width", this.pageStepperWidth);
+			html.style(node, "display", i < startPage + stepSize ? "" : "none");
 		}
 	},
-	
 	_createWardBtns: function(){
 		// summary:
 		//		Create the previous/next/first/last button
-		var self = this;
+		var _this = this, nls = this.plugin._nls;
 		var highContrastLabel = {prevPage: "<", firstPage: "«", nextPage: ">", lastPage: "»"};
 		var createWardBtn = function(value, label, position){
-			var node = dojo.create("div", {value: value, title: label, tabindex: 1}, self.pageStepperDiv, position);
-			self.plugin.connect(node, "onclick", dojo.hitch(self, "_onPageStep"));
-			dijit.setWaiState(node, "label", label);
+			var node = html.create("div", {value: value, title: label, tabindex: "-2"}, _this.pageStepperDiv, position);
+			_this.plugin.connect(node, "onclick", lang.hitch(_this, "_onPageStep"));
+			_this.plugin.connect(node, "onkeydown", lang.hitch(_this, "_onPageStep"));
+			node.setAttribute("aria-label", label);
 			// for high contrast
-			var highConrastNode = dojo.create("span", {value: value, title: label, innerHTML: highContrastLabel[value]}, node, position);
-			dojo.addClass(highConrastNode, "dojoxGridWardButtonInner");
+			var highConrastNode = html.create("span", {value: value, title: label, innerHTML: highContrastLabel[value]}, node, position);
+			html.addClass(highConrastNode, "dojoxGridWardButtonInner");
 		};
-		createWardBtn("prevPage", this.plugin.nls.prevTip, "first");
-		createWardBtn("firstPage", this.plugin.nls.firstTip, "first");
-		createWardBtn("nextPage", this.plugin.nls.nextTip, "last");
-		createWardBtn("lastPage", this.plugin.nls.lastTip, "last");
+		createWardBtn("prevPage", nls[6], "first");
+		createWardBtn("firstPage", nls[7], "first");
+		createWardBtn("nextPage", nls[8], "last");
+		createWardBtn("lastPage", nls[9], "last");
 	},
-	
 	_resetPageStepNodes: function(){
 		// summary:
 		//		The page step nodes might be changed when fetch data, we need to
@@ -689,536 +539,433 @@ dojo.declare("dojox.grid.enhanced.plugins._Paginator", [dijit._Widget,dijit._Tem
 		var startPage = this._getStartPage(),
 			stepSize = this._getStepPageSize(),
 			stepNodes = this.pageStepperDiv.childNodes,
-			node = null;
-		for(var i = startPage, j = 2; j < stepNodes.length - 2; j++, i++){
+			node = null, i = startPage, j = 2, tip;
+		for(; j < stepNodes.length - 2; j++, i++){
 			node = stepNodes[j];
 			if(i < startPage + stepSize){
-				dojo.attr(node, "innerHTML", i);
-				dojo.attr(node, "value", i);
-				dojo.style(node, "display", "block");
-				dijit.setWaiState(node, "label", dojo.string.substitute(this.plugin.nls.pageStepLabelTemplate, [i + ""]));
+				tip = string.substitute(this.plugin._nls[3], [i]);
+				html.attr(node, {
+					"innerHTML": i,
+					"title": tip,
+					"value": i
+				});
+				html.style(node, "display", "");
+				node.setAttribute("aria-label", tip);
 			}else{
-				dojo.style(node, "display", "none");
+				html.style(node, "display", "none");
 			}
 		}
 	},
-	
-	_updatePageStepNodeClass: function(){
+	_updatePageStepNodesStyle: function(){
 		// summary:
 		//		Update the style of the page step nodes
 		var value = null,
-			curPage = this._getCurrentPageNo(),
-			pageCount = this._getPageCount(),
-			visibleNodeLen = 0;
-			
+			curPage = this.plugin.currentPage(),
+			pageCount = this.plugin.getTotalPageNum();
 		var updateClass = function(node, isWardBtn, status){
 			var value = node.value,
 				enableClass = isWardBtn ? "dojoxGrid" + value + "Btn" : "dojoxGridInactived",
 				disableClass = isWardBtn ? "dojoxGrid" + value + "BtnDisable" : "dojoxGridActived";
 			if(status){
-				dojo.addClass(node, disableClass);
-				dojo.attr(node, "tabindex", "-1");
+				html.addClass(node, disableClass);
+				html.removeAttr(node, "tabindex");
 			}else{
-				dojo.addClass(node, enableClass);
-				dojo.attr(node, "tabindex", "0");
+				html.addClass(node, enableClass);
+				node.setAttribute("tabindex", "-2");
 			}
 		};
-		dojo.forEach(this.pageStepperDiv.childNodes, function(node){
-			dojo.removeClass(node);
+		array.forEach(this.pageStepperDiv.childNodes, function(node){
+			html.removeClass(node);
 			if(isNaN(parseInt(node.value, 10))){
-				dojo.addClass(node, "dojoxGridWardButton");
+				html.addClass(node, "dojoxGridWardButton");
 				var disablePageNum = node.value == "prevPage" || node.value == "firstPage" ? 1 : pageCount;
-				updateClass(node, true, (curPage == disablePageNum));
+				updateClass(node, true, (curPage === disablePageNum));
 			}else{
 				value = parseInt(node.value, 10);
-				updateClass(node, false, (value === curPage || dojo.style(node, "display") === "none"));
+				updateClass(node, false, (value === curPage || html.style(node, "display") === "none"));
 			}
 		}, this);
 	},
-	
 	_showGotoButton: function(flag){
 		this.gotoButton = flag;
 		this._updateGotoButton();
 	},
-	
 	_updateGotoButton: function(){
 		// summary:
 		//		Create/destroy the goto page button
 		if(!this.gotoButton){
-			if(this.gotoPageTd){
-				if(this._gotoPageDialog){
-					this._gotoPageDialog.destroy();
-				}
-				dojo.destroy(this.gotoPageDiv);
-				dojo.destroy(this.gotoPageTd);
-				delete this.gotoPageDiv;
-				delete this.gotoPageTd;
+			if(this._gotoPageDialog){
+				this._gotoPageDialog.destroy();
 			}
+			html.removeAttr(this.gotoPageDiv, "tabindex");
+			html.style(this.gotoPageTd, 'display', 'none');
 			return;
 		}
-		if(!this.gotoPageTd){
-			this._createGotoNode();
+		if(html.style(this.gotoPageTd, 'display') == 'none'){
+			html.style(this.gotoPageTd, 'display', '');
 		}
-		dojo.toggleClass(this.gotoPageDiv, "dojoxGridPaginatorGotoDivDisabled", this.plugin.pageSize >= this.plugin._maxSize);
-	},
-	
-	_createGotoNode: function(){
-		// summary:
-		//		Create the goto page button
-		this.gotoPageTd = dojo.create("td", {}, dojo.query("tr", this.domNode)[0], "last");
-		dojo.addClass(this.gotoPageTd, "dojoxGridPaginatorGotoTd");
-		this.gotoPageDiv = dojo.create("div", {tabindex: "0", title: this.plugin.nls.gotoButtonTitle}, this.gotoPageTd, "first");
-		dojo.addClass(this.gotoPageDiv, "dojoxGridPaginatorGotoDiv");
-		this.plugin.connect(this.gotoPageDiv, "onclick", dojo.hitch(this, "_openGotopageDialog"));
-		// for high contrast
-		var highConrastNode = dojo.create("span", {title: this.plugin.nls.gotoButtonTitle, innerHTML: "⊥"}, this.gotoPageDiv, "last");
-		dojo.addClass(highConrastNode, "dojoxGridWardButtonInner");
-	},
-	
-	_openGotopageDialog: function(event){
-		// summary:
-		//		Show the goto page dialog
-		if(!this._gotoPageDialog){
-			this._gotoPageDialog = new dojox.grid.enhanced.plugins.pagination._GotoPageDialog(this.plugin);
-		}
-		// focus
-		if(!this._currentFocusNode){
-			this.grid.focus.focusArea("pagination" + this.position, event);
+		this.gotoPageDiv.setAttribute('title', this.plugin._nls[10]);
+		html.toggleClass(this.gotoPageDiv, "dojoxGridPaginatorGotoDivDisabled", this.plugin.getTotalPageNum() <= 1);
+		if(this.plugin.getTotalPageNum() <= 1){
+			html.removeAttr(this.gotoPageDiv, "tabindex");
 		}else{
-			this._currentFocusNode = this.gotoPageDiv;
-		}
-		if(this.focusArea != "pageStep"){
-			this.focusArea = "pageStep";
+			this.gotoPageDiv.setAttribute("tabindex", "-3");
 		}
-		this._gotoPageDialog.updatePageCount();
-		this._gotoPageDialog.showDialog();
 	},
-	
-	// ===== focus handlers ===== //
-	_onFocusPaginator: function(event, step){
+	_openGotopageDialog: function(e){
 		// summary:
-		//		Focus handler
-		if(!this._currentFocusNode){
-			if(step > 0){
-				return this._onFocusPageSizeNode(event) ? true : this._onFocusPageStepNode(event);
-			}else if(step < 0){
-				return this._onFocusPageStepNode(event) ? true : this._onFocusPageSizeNode(event);
-			}else{
-				return false;
-			}
-		}else{
-			if(step > 0){
-				return this.focusArea === "pageSize" ? this._onFocusPageStepNode(event) : false;
-			}else if(step < 0){
-				return this.focusArea === "pageStep" ? this._onFocusPageSizeNode(event) : false;
-			}else{
-				return false;
-			}
-		}
-	},
-	
-	_onFocusPageSizeNode: function(event){
-		// summary:
-		//		Focus the page size area, if there is no focusable node, return false
-		var pageSizeNodes = this._getPageSizeActivableNodes();
-		if(event && event.type !== "click"){
-			if(pageSizeNodes[0]){
-				dijit.focus(pageSizeNodes[0]);
-				this._currentFocusNode = pageSizeNodes[0];
-				this.focusArea = "pageSize";
-				this.plugin._stopEvent(event);
-				return true;
-			}else{
-				return false;
-			}
-		}
-		if(event && event.type == "click"){
-			if(dojo.indexOf(this._getPageSizeActivableNodes(), event.target) > -1){
-				this.focusArea = "pageSize";
-				this.plugin._stopEvent(event);
-				return true;
-			}
-		}
-		return false;
-	},
-	
-	_onFocusPageStepNode: function(event){
-		// summary:
-		//		Focus the page step area, if there is no focusable node, return false
-		var pageStepNodes = this._getPageStepActivableNodes();
-		if(event && event.type !== "click"){
-			if(pageStepNodes[0]){
-				dijit.focus(pageStepNodes[0]);
-				this._currentFocusNode = pageStepNodes[0];
-				this.focusArea = "pageStep";
-				this.plugin._stopEvent(event);
-				return true;
-			}else if(this.gotoPageDiv){
-				dijit.focus(this.gotoPageDiv);
-				this._currentFocusNode = this.gotoPageDiv;
-				this.focusArea = "pageStep";
-				this.plugin._stopEvent(event);
-				return true;
-			}else{
-				return false;
-			}
-		}
-		if(event && event.type == "click"){
-			if(dojo.indexOf(this._getPageStepActivableNodes(), event.target) > -1){
-				this.focusArea = "pageStep";
-				this.plugin._stopEvent(event);
-				return true;
-			}else if(event.target == this.gotoPageDiv){
-				dijit.focus(this.gotoPageDiv);
-				this._currentFocusNode = this.gotoPageDiv;
-				this.focusArea = "pageStep";
-				this.plugin._stopEvent(event);
-				return true;
-			}
-		}
-		return false;
-	},
-	
-	_onFocusGotoPageNode: function(event){
-		// summary:
-		//		Focus the goto page button, if there is no focusable node, return false
-		if(!this.gotoButton || !this.gotoPageTd){
-			return false;
-		}
-		if(event && event.type !== "click" || (event.type == "click" && event.target == this.gotoPageDiv)){
-			dijit.focus(this.gotoPageDiv);
-			this._currentFocusNode = this.gotoPageDiv;
-			this.focusArea = "gotoButton";
-			this.plugin._stopEvent(event);
-			return true;
-		}
-		return true;
-	},
-	
-	_onBlurPaginator: function(event, step){
-		var pageSizeNodes = this._getPageSizeActivableNodes(),
-			pageStepNodes = this._getPageStepActivableNodes();
-		
-		if(step > 0 && this.focusArea === "pageSize" && (pageStepNodes.length > 1 || this.gotoButton)){
-			return false;
-		}else if(step < 0 && this.focusArea === "pageStep" && pageSizeNodes.length > 1){
-			return false;
-		}
-		this._currentFocusNode = null;
-		this.focusArea = null;
-		return true;
-	},
-	
-	_onKeyDown: function(event, isBubble){
-		// summary:
-		//		Focus navigation
-		if(isBubble){
-			return;
-		}
-		if(event.altKey || event.metaKey){
-			return;
-		}
-		var dk = dojo.keys;
-		if(event.keyCode === dk.ENTER || event.keyCode === dk.SPACE){
-			if(dojo.indexOf(this._getPageStepActivableNodes(), this._currentFocusNode) > -1){
-				this._onPageStep(event);
-			}else if(dojo.indexOf(this._getPageSizeActivableNodes(), this._currentFocusNode) > -1){
-				this._onSwitchPageSize(event);
-			}else if(this._currentFocusNode === this.gotoPageDiv){
-				this._openGotopageDialog(event);
-			}
-		}
-		this.plugin._stopEvent(event);
-	},
-	
-	_moveFocus: function(rowDelta, colDelta, evt){
-		// summary:
-		//		Move focus according row delta&column delta
-		var nodes;
-		if(this.focusArea == "pageSize"){
-			nodes = this._getPageSizeActivableNodes();
-		}else if(this.focusArea == "pageStep"){
-			nodes = this._getPageStepActivableNodes();
-			if(this.gotoPageDiv){
-				nodes.push(this.gotoPageDiv);
-			}
-		}
-		if(nodes.length < 1){
+		//		Show the goto page dialog
+		if(this.plugin.getTotalPageNum() <= 1){
 			return;
 		}
-		var currentIdx = dojo.indexOf(nodes, this._currentFocusNode);
-		var focusIdx = currentIdx + colDelta;
-		if(focusIdx >= 0 && focusIdx < nodes.length){
-			dijit.focus(nodes[focusIdx]);
-			this._currentFocusNode = nodes[focusIdx];
-		}
-		this.plugin._stopEvent(evt);
-	},
-	
-	_getPageSizeActivableNodes: function(){
-		return dojo.query("span[tabindex='0']", this.sizeSwitchTd);
-	},
-	
-	_getPageStepActivableNodes: function(){
-		return (dojo.query("div[tabindex='0']", this.pageStepperDiv));
-	},
-	
-	_getAllPageSizeNodes: function(){
-		var nodeList = [];
-		dojo.forEach(this.sizeSwitchTd.childNodes, function(node){
-			if(node.value){
-				nodeList.push(node);
-			}
-		});
-		return nodeList;
-	},
-	
-	_getAllPageStepNodes: function(){
-		var nodeList = [];
-		for(var i = 0, len = this.pageStepperDiv.childNodes.length; i < len; i++){
-			nodeList.push(this.pageStepperDiv.childNodes[i]);
-		}
-		return nodeList;
-	},
-	
-	_moveToNextActivableNode: function(nodeList, curNodeValue){
-		// summary:
-		//		Need to move the focus to next node since current node is inactive and unfocusable
-		if(!curNodeValue){
+		if(e.type === "keydown" && e.keyCode !== keys.ENTER && e.keyCode !== keys.SPACE){
 			return;
 		}
-		if(nodeList.length < 2){
-			this.grid.focus.tab(1);
-		}
-		var nl = [],
-			node = null,
-			index = 0;
-		dojo.forEach(nodeList, function(n){
-			if(n.value == curNodeValue){
-				nl.push(n);
-				node = n;
-			}else if(dojo.attr(n, "tabindex") == "0"){
-				nl.push(n);
-			}
-		});
-		if(nl.length < 2){
-			this.grid.focus.tab(1);
-		}
-		index = dojo.indexOf(nl, node);
-		if(dojo.attr(node, "tabindex") != "0"){
-			node = nl[index + 1] ? nl[index + 1] : nl[index - 1];
+		if(!this._gotoPageDialog){
+			this._gotoPageDialog = new _GotoPageDialog(this.plugin);
 		}
-		dijit.focus(node);
-		this._currentFocusNode = node;
+		this._gotoPageDialog.showDialog();
+		this.onShowGotoPageDialog(e);
 	},
-	
-	// ===== pagination events handlers ===== //
 	_onSwitchPageSize: function(/*Event*/e){
 		// summary:
 		//		The handler of switch the page size
-		var size = this.pageSizeValue = e.target.value;
-		if(!size){
+		if(e.type === "keydown" && e.keyCode !== keys.ENTER && e.keyCode !== keys.SPACE){
 			return;
 		}
-		if(dojo.trim(size.toLowerCase()) == "all"){
-			size = this._maxItemSize;
-			showAll = true;
-		}
-		this.plugin.grid.usingPagination = !this.plugin.showAll;
-		
-		size = parseInt(size, 10);
-		if(isNaN(size) || size <= 0/* || size == this.currentPageSize*/){
-			return;
-		}
-		
-		if(!this._currentFocusNode){
-			this.grid.focus.currentArea("pagination" + this.position);
-		}
-		if(this.focusArea != "pageSize"){
-			this.focusArea = "pageSize";
-		}
-		this.plugin.changePageSize(size);
+		this.onSwitchPageSize(e);
+		this.plugin.currentPageSize(e.target.value);
 	},
-	
 	_onPageStep: function(/*Event*/e){
 		// summary:
 		//		The handler jump page event
-		var p = this.plugin,
-			value = this.pageStepValue = e.target.value;
-		
-		if(!this._currentFocusNode){
-			this.grid.focus.currentArea("pagination" + this.position);
-		}
-		if(this.focusArea != "pageStep"){
-			this.focusArea = "pageStep";
+		if(e.type === "keydown" && e.keyCode !== keys.ENTER && e.keyCode !== keys.SPACE){
+			return;
 		}
+		var p = this.plugin,
+			value = e.target.value;
+		this.onPageStep(e);
 		if(!isNaN(parseInt(value, 10))){
-			p.gotoPage(value);
+			p.currentPage(parseInt(value, 10));
 		}else{
-			switch(e.target.value){
-				case "prevPage":
-					p.prevPage();
-					break;
-				case "nextPage":
-					p.nextPage();
-					break;
-				case "firstPage":
-					p.gotoFirstPage();
-					break;
-				case "lastPage":
-					p.gotoLastPage();
-			}
+			p[value]();
 		}
 	},
-	
-	// ===== information getters ===== //
-	_getCurrentPageNo: function(){
-		return this.plugin._currentPage + 1;
-	},
-	
-	_getPageCount: function(){
-		if(!this._maxItemSize || !this.currentPageSize){
-			return 0;
-		}
-		return Math.ceil(this._maxItemSize / this.currentPageSize);
-	},
-	
 	_getStartPage: function(){
-		var cp = this._getCurrentPageNo();
-		var ms = parseInt(this.maxPageStep / 2, 10);
-		var pc = this._getPageCount();
-		if(cp < ms || (cp - ms) < 1){
-			return 1;
-		}else if(pc <= this.maxPageStep){
+		var cp = this.plugin.currentPage(),
+			ms = this.maxPageStep,
+			hs = parseInt(ms / 2, 10),
+			tp = this.plugin.getTotalPageNum();
+		if(cp < hs || (cp - hs) < 1 || tp <= ms){
 			return 1;
 		}else{
-			if(pc - cp < ms && cp - this.maxPageStep >= 0){
-				return pc - this.maxPageStep + 1;
-			}else{
-				return (cp - ms);
-			}
+			return tp - cp < hs && cp - ms >= 0 ? tp - ms + 1 : cp - hs;
 		}
 	},
-	
 	_getStepPageSize: function(){
-		var sp = this._getStartPage();
-		var count = this._getPageCount();
-		if((sp + this.maxPageStep) > count){
-			return count - sp + 1;
-		}else{
-			return this.maxPageStep;
-		}
+		var sp = this._getStartPage(),
+			tp = this.plugin.getTotalPageNum(),
+			ms = this.maxPageStep;
+		return sp + ms > tp ? tp - sp + 1 : ms;
 	}
-
 });
 
-dojo.declare("dojox.grid.enhanced.plugins.pagination._GotoPageDialog", null, {
-	
-	pageCount: 0,
+var Pagination = declare("dojox.grid.enhanced.plugins.Pagination", _Plugin, {
+	// summary:
+	//		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',
 	
-	constructor: function(plugin){
-		this.plugin = plugin;
-		this.pageCount = this.plugin.paginators[0]._getPageCount();
-		this._dialogNode = dojo.create("div", {}, dojo.body(), "last");
-		this._gotoPageDialog = new dojox.grid.enhanced.plugins.Dialog({
-			"refNode": plugin.grid.domNode,
-			"title": this.plugin.nls.dialogTitle
-		}, this._dialogNode);
-		this._createDialogContent();
-		this._gotoPageDialog.startup();
+	init: function(){
+		var g = this.grid;
+		g.usingPagination = true;
+		this._initOptions();
+		this._currentPage = this.defaultPage;
+		this._currentPageSize = this.grid.rowsPerPage = this.defaultPageSize;
+		// wrap store layer
+		this._store = g.store;
+		this.forcePageStoreLayer = new _ForcedPageStoreLayer(this);
+		layers.wrap(g, "_storeLayerFetch", this.forcePageStoreLayer);
+		// create pagination bar
+		this._paginator = this.option.position != "top" ? 
+			new _Paginator(lang.mixin(this.option, {position: "bottom", plugin: this})) :
+			new _Paginator(lang.mixin(this.option, {position: "top", plugin: this}));
+		this._regApis();
 	},
-	
-	_createDialogContent: function(){
-		// summary:
-		//		Create the dialog content
-		this._specifyNode = dojo.create("div", {innerHTML: this.plugin.nls.dialogIndication}, this._gotoPageDialog.containerNode, "last");
-		
-		this._pageInputDiv = dojo.create("div", {}, this._gotoPageDialog.containerNode, "last");
-		this._pageTextBox = new dijit.form.NumberTextBox();
-		this._pageTextBox.constraints = {fractional:false, min:1, max:this.pageCount};
-		this.plugin.connect(this._pageTextBox.textbox, "onkeyup", dojo.hitch(this, "_setConfirmBtnState"));
-		
-		this._pageInputDiv.appendChild(this._pageTextBox.domNode);
-		this._pageLabel = dojo.create("label", {innerHTML: dojo.string.substitute(this.plugin.nls.pageCountIndication, [this.pageCount])}, this._pageInputDiv, "last");
-		
-		this._buttonDiv = dojo.create("div", {}, this._gotoPageDialog.containerNode, "last");
-		this._confirmBtn = new dijit.form.Button({label: this.plugin.nls.dialogConfirm, onClick: dojo.hitch(this, this._onConfirm)});
-		this._confirmBtn.set("disabled", true);
-		
-		this._cancelBtn = new dijit.form.Button({label: this.plugin.nls.dialogCancel, onClick: dojo.hitch(this, this._onCancel)});
-		this._buttonDiv.appendChild(this._confirmBtn.domNode);
-		this._buttonDiv.appendChild(this._cancelBtn.domNode);
-		this._styleContent();
-		this._gotoPageDialog.onCancel = dojo.hitch(this, this._onCancel);
-		this.plugin.connect(this._gotoPageDialog, "_onKey", dojo.hitch(this, "_onKeyDown"));
+	destroy: function(){
+		this.inherited(arguments);
+		this._paginator.destroy();
+		var g = this.grid;
+		g.unwrap(this.forcePageStoreLayer.name());
+		g.scrollToRow = this._gridOriginalfuncs[0];
+		g._onNew = this._gridOriginalfuncs[1];
+		g.removeSelectedRows = this._gridOriginalfuncs[2];
+		this._paginator = null;
+		this._nls = null;
+	},
+	currentPage: function(page){
+		// 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
+		//		The page to go to, starting at 1.
+		//	return:
+		//		Current page number
+		if(page <= this.getTotalPageNum() && page > 0 && this._currentPage !== page){
+			this._currentPage = page;
+			this.grid._refresh(true);
+			this.grid.resize();
+		}
+		return this._currentPage;
 	},
-	
-	_styleContent: function(){
-		dojo.addClass(this._specifyNode, "dojoxGridDialogMargin");
-		dojo.addClass(this._pageInputDiv, "dojoxGridDialogMargin");
-		dojo.addClass(this._buttonDiv, "dojoxGridDialogButton");
-		dojo.style(this._pageTextBox.domNode, "width", "50px");
+	nextPage: function(){
+		// summary:
+		//		Go to the next page.
+		this.currentPage(this._currentPage + 1);
 	},
-	
-	updatePageCount: function(){
-		this.pageCount = this.plugin.paginators[0]._getPageCount();
-		this._pageTextBox.constraints = {fractional:false, min:1, max:this.pageCount};
-		dojo.attr(this._pageLabel, "innerHTML", dojo.string.substitute(this.plugin.nls.pageCountIndication, [this.pageCount]));
+	prevPage: function(){
+		// summary:
+		//		Go to the previous page.
+		this.currentPage(this._currentPage - 1);
 	},
-	
-	showDialog: function(){
-		this._gotoPageDialog.show();
+	firstPage: function(){
+		// summary:
+		//		Go to the first page
+		this.currentPage(1);
 	},
-	
-	_onConfirm: function(event){
+	lastPage: function(){
 		// summary:
-		//		Jump to the given page
-		if(this._pageTextBox.isValid() && this._pageTextBox.getDisplayedValue() !== ""){
-			this.plugin.gotoPage(this._pageTextBox.parse(this._pageTextBox.getDisplayedValue()));
-			this._gotoPageDialog.hide();
-			this._pageTextBox.reset();
+		//		Go to the last page
+		this.currentPage(this.getTotalPageNum());
+	},
+	currentPageSize: function(size){
+		//	summary:
+		//		Change the size of current page or return the current page size.
+		//	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
+		//		in, the current page size will be returned.
+		//	return
+		//		Current size of items per page.  
+		if(!isNaN(size)){
+			var g = this.grid,
+				startIndex = this._currentPageSize * (this._currentPage - 1), endIndex;
+			this._showAll = !isFinite(size);
+			this.grid.usingPagination = !this._showAll;
+			this._currentPageSize = this._showAll ? this._maxSize : size;
+			g.rowsPerPage = this._showAll ? this._defaultRowsPerPage : size;
+			endIndex = startIndex + Math.min(this._currentPageSize, this._maxSize);
+			if(endIndex > this._maxSize){
+				this.lastPage();
+			}else{
+				var cp = Math.ceil(startIndex / this._currentPageSize) + 1;
+				if(cp !== this._currentPage){
+					this.currentPage(cp);
+				}else{
+					this.grid._refresh(true);
+				}
+			}
+			this.grid.resize();
 		}
-		this.plugin._stopEvent(event);
+		return this._currentPageSize;
 	},
-	
-	_onCancel: function(event){
+	getTotalPageNum: function(){
 		// summary:
-		//		Cancel action and hide the dialog
-		this._pageTextBox.reset();
-		this._gotoPageDialog.hide();
-		this.plugin._stopEvent(event);
+		//		Get total page number
+		return Math.ceil(this._maxSize / this._currentPageSize);
 	},
-	
-	_onKeyDown: function(event){
-		if(event.altKey || event.metaKey){
+	getTotalRowCount: function(){
+		// summary:
+		//		Function for get total row count
+		return this._maxSize;
+	},
+	scrollToRow: function(inRowIndex){
+		// summary:
+		//		Override the grid.scrollToRow(), could jump to the right page
+		//		and scroll to the specific row
+		// inRowIndex: integer
+		//		The row index
+		var page = parseInt(inRowIndex / this._currentPageSize, 10) + 1;
+		if(page > this.getTotalPageNum()){
 			return;
 		}
-		var dk = dojo.keys;
-		if(event.keyCode === dk.ENTER){
-			this._onConfirm(event);
-		}
+		this.currentPage(page);
+		var rowIdx = inRowIndex % this._currentPageSize;
+		return this._gridOriginalfuncs[0](rowIdx);
 	},
-	
-	_setConfirmBtnState: function(){
-		if(this._pageTextBox.isValid() && this._pageTextBox.getDisplayedValue() !== ""){
-			this._confirmBtn.set("disabled", false);
+	removeSelectedRows: function(){
+		this._multiRemoving = true;
+		this._gridOriginalfuncs[2].apply();
+		this._multiRemoving = false;
+		this.grid.resize();
+		this.grid._refresh();
+	},
+	showGotoPageButton: function(flag){
+		// summary:
+		//		For show/hide the go to page button dynamically
+		// flag: boolean
+		//		Show the go to page button when flag is true, otherwise hide it
+		this._paginator.gotoButton = flag;
+		this._paginator._updateGotoButton();
+	},
+	// [DEPRECATED] ============
+	gotoPage: function(page){
+		kernel.deprecated("dojox.grid.enhanced.EnhancedGrid.gotoPage(page)", "use dojox.grid.enhanced.EnhancedGrid.currentPage(page) instead", "1.8");
+		this.currentPage(page);
+	},
+	gotoFirstPage: function(){
+		kernel.deprecated("dojox.grid.enhanced.EnhancedGrid.gotoFirstPage()", "use dojox.grid.enhanced.EnhancedGrid.firstPage() instead", "1.8");
+		this.firstPage();
+	},
+	gotoLastPage: function(){
+		kernel.deprecated("dojox.grid.enhanced.EnhancedGrid.gotoLastPage()", "use dojox.grid.enhanced.EnhancedGrid.lastPage() instead", "1.8");
+		this.lastPage();
+	},
+	changePageSize: function(size){
+		kernel.deprecated("dojox.grid.enhanced.EnhancedGrid.changePageSize(size)", "use dojox.grid.enhanced.EnhancedGrid.currentPageSize(size) instead", "1.8");
+		this.currentPageSize(size);
+	},
+	// =============== Protected ================
+	_nls: null,
+	_showAll: false,
+	_maxSize: 0,
+	// =============== Private =============== 
+	_defaultRowsPerPage: 25,
+	_currentPage: 1,
+	_currentPageSize: 25,
+	
+	_initOptions: function(){
+		this._defaultRowsPerPage = this.grid.rowsPerPage || 25;
+		this.defaultPage = this.option.defaultPage >= 1 ? parseInt(this.option.defaultPage, 10) : 1;
+		this.option.description = this.option.description !== undefined ? !!this.option.description : this.description;
+		this.option.sizeSwitch = this.option.sizeSwitch !== undefined ? !!this.option.sizeSwitch : this.sizeSwitch;
+		this.option.pageStepper = this.option.pageStepper !== undefined ? !!this.option.pageStepper : this.pageStepper;
+		this.option.gotoButton = this.option.gotoButton !== undefined ? !!this.option.gotoButton : this.gotoButton;
+		if(lang.isArray(this.option.pageSizes)){
+			var pageSizes = [];
+			array.forEach(this.option.pageSizes, function(size){
+				size = typeof size == 'number' ? size : parseInt(size, 10);
+				if(!isNaN(size) && size > 0){
+					pageSizes.push(size);
+				}else if(array.indexOf(pageSizes, Infinity) < 0){
+					pageSizes.push(Infinity);
+				}
+			}, this);
+			this.option.pageSizes = pageSizes.sort(function(a, b){return a - b;});
 		}else{
-			this._confirmBtn.set("disabled", true);
-		}
+			this.option.pageSizes = this.pageSizes;
+		}
+		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,
+			nls.pageSizeLabelTemplate,
+			nls.pageStepLabelTemplate,
+			nls.itemTitle,
+			nls.singularItemTitle,
+			nls.prevTip,
+			nls.firstTip,
+			nls.nextTip,
+			nls.lastTip,
+			nls.gotoButtonTitle,
+			nls.dialogTitle,
+			nls.dialogIndication,
+			nls.pageCountIndication,
+			nls.dialogConfirm,
+			nls.dialogCancel,
+			nls.all
+		];
 	},
-	
-	destroy: function(){
-		this._pageTextBox.destroy();
-		this._confirmBtn.destroy();
-		this._cancelBtn.destroy();
-		this._gotoPageDialog.destroy();
+	_regApis: function(){
+		var g = this.grid;
+		// New added APIs
+		g.currentPage = lang.hitch(this, this.currentPage);
+		g.nextPage = lang.hitch(this, this.nextPage);
+		g.prevPage = lang.hitch(this, this.prevPage);
+		g.firstPage = lang.hitch(this, this.firstPage);
+		g.lastPage = lang.hitch(this, this.lastPage);
+		g.currentPageSize = lang.hitch(this, this.currentPageSize);
+		g.showGotoPageButton = lang.hitch(this, this.showGotoPageButton);
+		g.getTotalRowCount = lang.hitch(this, this.getTotalRowCount);
+		g.getTotalPageNum = lang.hitch(this, this.getTotalPageNum);
 		
-		dojo.destroy(this._specifyNode);
-		dojo.destroy(this._pageInputDiv);
-		dojo.destroy(this._pageLabel);
-		dojo.destroy(this._buttonDiv);
-		dojo.destroy(this._dialogNode);
+		g.gotoPage = lang.hitch(this, this.gotoPage);
+		g.gotoFirstPage = lang.hitch(this, this.gotoFirstPage);
+		g.gotoLastPage = lang.hitch(this, this.gotoLastPage);
+		g.changePageSize = lang.hitch(this, this.changePageSize);
+		// Changed APIs
+		this._gridOriginalfuncs = [
+			lang.hitch(g, g.scrollToRow),
+			lang.hitch(g, g._onNew),		
+			lang.hitch(g, g.removeSelectedRows)
+		];
+		g.scrollToRow = lang.hitch(this, this.scrollToRow);
+		g.removeSelectedRows = lang.hitch(this, this.removeSelectedRows);
+		g._onNew = lang.hitch(this, this._onNew);
+		this.connect(g, "_onDelete", lang.hitch(this, this._onDelete));
+	},
+	_onNew: function(item, parentInfo){
+		var totalPages = this.getTotalPageNum();
+		if(((this._currentPage === totalPages || totalPages === 0) && this.grid.get('rowCount') < this._currentPageSize) || this._showAll){
+			lang.hitch(this.grid, this._gridOriginalfuncs[1])(item, parentInfo);
+			this.forcePageStoreLayer.endIdx++;
+		}
+		this._maxSize++;
+		if(this._showAll){
+			this._currentPageSize++;
+		}
+		if(this._showAll && this.grid.autoHeight){
+			this.grid._refresh();
+		}else{
+			this._paginator._update();
+		}
+	},
+	_onDelete: function(){
+		if(!this._multiRemoving){
+			this.grid.resize();
+			if(this._showAll){
+				this.grid._refresh();
+			}
+		}
+		if(this.grid.get('rowCount') === 0){
+			this.prevPage();
+		}
 	}
 });
 
-dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Pagination/*name:'pagination'*/);
\ No newline at end of file
+EnhancedGrid.registerPlugin(Pagination/*name:'pagination'*/);
+
+return Pagination;
+
+});
\ No newline at end of file
diff --git a/dojox/grid/enhanced/plugins/Printer.js b/dojox/grid/enhanced/plugins/Printer.js
index d96bfd1..7d1f4ba 100644
--- a/dojox/grid/enhanced/plugins/Printer.js
+++ b/dojox/grid/enhanced/plugins/Printer.js
@@ -1,9 +1,19 @@
-dojo.provide("dojox.grid.enhanced.plugins.Printer");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/html",
+	"dojo/_base/Deferred",
+	"dojo/_base/lang",
+	"dojo/_base/sniff",
+	"dojo/_base/xhr",
+	"dojo/_base/array",
+	"dojo/query", 
+	"dojo/DeferredList",
+	"../_Plugin",
+	"../../EnhancedGrid",
+	"./exporter/TableWriter"
+], function(declare, html, Deferred, lang, has, xhr, array, query, DeferredList, _Plugin, EnhancedGrid, TableWriter){
 
-dojo.require("dojox.grid.enhanced._Plugin");
-dojo.require("dojox.grid.enhanced.plugins.exporter.TableWriter");
-
-dojo.declare("dojox.grid.enhanced.plugins.Printer", dojox.grid.enhanced._Plugin, {
+var Printer = declare("dojox.grid.enhanced.plugins.Printer", _Plugin, {
 	// summary:
 	//		Provide printGrid function to the grid.
 	// example:
@@ -52,11 +62,11 @@ dojo.declare("dojox.grid.enhanced.plugins.Printer", dojox.grid.enhanced._Plugin,
 	},
 	_mixinGrid: function(){
 		var g = this.grid;
-		g.printGrid = dojo.hitch(this, this.printGrid);
-		g.printSelected = dojo.hitch(this, this.printSelected);
-		g.exportToHTML = dojo.hitch(this, this.exportToHTML);
-		g.exportSelectedToHTML = dojo.hitch(this, this.exportSelectedToHTML);
-		g.normalizePrintedGrid = dojo.hitch(this, this.normalizeRowHeight);
+		g.printGrid = lang.hitch(this, this.printGrid);
+		g.printSelected = lang.hitch(this, this.printSelected);
+		g.exportToHTML = lang.hitch(this, this.exportToHTML);
+		g.exportSelectedToHTML = lang.hitch(this, this.exportSelectedToHTML);
+		g.normalizePrintedGrid = lang.hitch(this, this.normalizeRowHeight);
 	},
 	printGrid: function(args){
 		// summary:
@@ -68,7 +78,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Printer", dojox.grid.enhanced._Plugin,
 		//		public
 		// args: __printArgs?
 		//		Arguments for print.
-		this.exportToHTML(args, dojo.hitch(this, this._print));
+		this.exportToHTML(args, lang.hitch(this, this._print));
 	},
 	printSelected: function(args){
 		// summary:
@@ -78,7 +88,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Printer", dojox.grid.enhanced._Plugin,
 		//		public
 		// args: __printArgs?
 		//		Arguments for print.
-		this._print(this.exportSelectedToHTML(args));
+		this.exportSelectedToHTML(args, lang.hitch(this, this._print));
 	},
 	exportToHTML: function(args, onExported){
 		// summary:
@@ -94,10 +104,10 @@ dojo.declare("dojox.grid.enhanced.plugins.Printer", dojox.grid.enhanced._Plugin,
 		args = this._formalizeArgs(args);
 		var _this = this;
 		this.grid.exportGrid("table", args, function(str){
-			onExported(_this._wrapHTML(args.title, args.cssFiles, args.titleInBody + str));
+			_this._wrapHTML(args.title, args.cssFiles, args.titleInBody + str).then(onExported);
 		});
 	},
-	exportSelectedToHTML: function(args){
+	exportSelectedToHTML: function(args, onExported){
 		// summary:
 		//		Export selected rows to HTML string, but do NOT print.
 		//		Users can use this to implement print preview.
@@ -107,8 +117,26 @@ dojo.declare("dojox.grid.enhanced.plugins.Printer", dojox.grid.enhanced._Plugin,
 		// args: __printArgs?
 		//		Arguments for print.
 		args = this._formalizeArgs(args);
-		var str = this.grid.exportSelected("table", args.writerArgs);
-		return this._wrapHTML(args.title, args.cssFiles, args.titleInBody + str);	//String
+		var _this = this;
+		this.grid.exportSelected("table", args.writerArgs, function(str){
+			_this._wrapHTML(args.title, args.cssFiles, args.titleInBody + str).then(onExported);
+		});
+	},
+
+	_loadCSSFiles: function(cssFiles){
+		var dl = array.map(cssFiles, function(cssFile){
+			cssFile = lang.trim(cssFile);
+			if(cssFile.substring(cssFile.length - 4).toLowerCase() === '.css'){
+				return xhr.get({
+					url: cssFile
+				});
+			}else{
+				var d = new Deferred();
+				d.callback(cssFile);
+				return d;
+			}
+		});
+		return DeferredList.prototype.gatherResults(dl);
 	},
 	_print: function(/* string */htmlStr){
 		// summary:
@@ -121,7 +149,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Printer", dojox.grid.enhanced._Plugin,
 		//		undefined
 		var win, _this = this,
 			fillDoc = function(w){
-				var doc = win.document;
+				var doc = w.document;
 				doc.open();
 				doc.write(htmlStr);
 				doc.close();
@@ -130,18 +158,19 @@ dojo.declare("dojox.grid.enhanced.plugins.Printer", dojox.grid.enhanced._Plugin,
 		if(!window.print){
 			//We don't have a print facility.
 			return;
-		}else if(dojo.isChrome || dojo.isOpera){
+		}else if(has('chrome') || has('opera')){
 			//referred from dijit._editor.plugins.Print._print()
 			//In opera and chrome the iframe.contentWindow.print
 			//will also print the outside window. So we must create a
 			//stand-alone new window.
-			win = window.open("javascript: ''", "", "status=0,menubar=0,location=0,toolbar=0,width=1,height=1,resizable=0,scrollbars=0");
+			win = window.open("javascript: ''", "",
+				"status=0,menubar=0,location=0,toolbar=0,width=1,height=1,resizable=0,scrollbars=0");
 			fillDoc(win);
+			win.print();
 			//Opera will stop at this point, showing the popping-out window.
 			//If the user closes the window, the following codes will not execute.
 			//If the user returns focus to the main window, the print function
 			// is executed, but still a no-op.
-			win.print();
 			win.close();
 		}else{
 			//Put private things in deeper namespace to avoid poluting grid namespace.
@@ -149,22 +178,22 @@ dojo.declare("dojox.grid.enhanced.plugins.Printer", dojox.grid.enhanced._Plugin,
 				dn = this.grid.domNode;
 			if(!fn){
 				var frameId = dn.id + "_print_frame";
-				if(!(fn = dojo.byId(frameId))){
+				if(!(fn = html.byId(frameId))){
 					//create an iframe to store the grid data.
-					fn = dojo.create("iframe");
+					fn = html.create("iframe");
 					fn.id = frameId;
 					fn.frameBorder = 0;
-					dojo.style(fn, {
+					html.style(fn, {
 						width: "1px",
 						height: "1px",
 						position: "absolute",
 						right: 0,
-						bottoom: 0,
+						bottom: 0,
 						border: "none",
 						overflow: "hidden"
 					});
-					if(!dojo.isIE){
-						dojo.style(fn, "visibility","hidden");
+					if(!has('ie')){
+						html.style(fn, "visibility", "hidden");
 					}
 					dn.appendChild(fn);
 				}
@@ -173,10 +202,8 @@ dojo.declare("dojox.grid.enhanced.plugins.Printer", dojox.grid.enhanced._Plugin,
 			}
 			win = fn.contentWindow;
 			fillDoc(win);
-			// IE requires the frame to be focused for
-			// print to work, but since this is okay for all
-			// no special casing.
-			dijit.focus(fn);
+			//IE requires the frame to be focused for print to work, and it's harmless for FF.
+			win.focus();
 			win.print();
 		}
 	},
@@ -193,66 +220,72 @@ dojo.declare("dojox.grid.enhanced.plugins.Printer", dojox.grid.enhanced._Plugin,
 		//		Content to print, not including <head></head> part and <html> tags
 		// returns:
 		//		the wrapped HTML string ready for print
-		var html = ['<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
-					'<html><head><title>', title,
+		return this._loadCSSFiles(cssFiles).then(function(cssStrs){
+			var i, sb = ['<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
+					'<html ', html._isBodyLtr() ? '' : 'dir="rtl"', '><head><title>', title,
 					'</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>'];
-		for(var i = 0; i < cssFiles.length; ++i){
-			html.push('<link rel="stylesheet" type="text/css" href="' + cssFiles[i] + '" />');
-		}
-		html.push('</head>');
-		if(body_content.search(/^\s*<body/i) < 0){
-			body_content = '<body>' + body_content + '</body>';
-		}
-		html.push(body_content);
-		return html.join('\n');	//String
+			for(i = 0; i < cssStrs.length; ++i){
+				sb.push('<style type="text/css">', cssStrs[i], '</style>');
+			}
+			sb.push('</head>');
+			if(body_content.search(/^\s*<body/i) < 0){
+				body_content = '<body>' + body_content + '</body>';
+			}
+			sb.push(body_content, '</html>');
+			return sb.join('');
+		});
 	},
 	normalizeRowHeight: function(doc){
-		var views = dojo.query("table.grid_view", doc.body);
-		var headPerView = dojo.map(views, function(view){
-			return dojo.query("thead.grid_header", view)[0];
+		var views = query(".grid_view", doc.body);
+		var headPerView = array.map(views, function(view){
+			return query(".grid_header", view)[0];
 		});
-		var rowsPerView = dojo.map(views, function(view){
-			return dojo.query("tbody.grid_row", view);
+		var rowsPerView = array.map(views, function(view){
+			return query(".grid_row", view);
 		});
 		var rowCount = rowsPerView[0].length;
 		var i, v, h, maxHeight = 0;
 		for(v = views.length - 1; v >= 0; --v){
-			h = dojo.contentBox(headPerView[v]).h;
+			h = html.contentBox(headPerView[v]).h;
 			if(h > maxHeight){
 				maxHeight = h;
 			}
 		}
 		for(v = views.length - 1; v >= 0; --v){
-			dojo.style(headPerView[v], "height", maxHeight + "px");
+			html.style(headPerView[v], "height", maxHeight + "px");
 		}
 		for(i = 0; i < rowCount; ++i){
 			maxHeight = 0;
 			for(v = views.length - 1; v >= 0; --v){
-				h = dojo.contentBox(rowsPerView[v][i]).h;
+				h = html.contentBox(rowsPerView[v][i]).h;
 				if(h > maxHeight){
 					maxHeight = h;
 				}
 			}
 			for(v = views.length - 1; v >= 0; --v){
-				dojo.style(rowsPerView[v][i], "height", maxHeight + "px");
+				html.style(rowsPerView[v][i], "height", maxHeight + "px");
 			}
 		}
-		var left = 0;
+		var left = 0, ltr = html._isBodyLtr();
 		for(v = 0; v < views.length; ++v){
-			dojo.style(views[v], "left", left + "px");
-			left += dojo.marginBox(views[v]).w;
+			html.style(views[v], ltr ? "left" : "right", left + "px");
+			left += html.marginBox(views[v]).w;
 		}
 	},
 	_formalizeArgs: function(args){
-		args = (args && dojo.isObject(args)) ? args : {};
+		args = (args && lang.isObject(args)) ? args : {};
 		args.title = String(args.title) || "";
-		if(!dojo.isArray(args.cssFiles)){
+		if(!lang.isArray(args.cssFiles)){
 			args.cssFiles = [args.cssFiles];
 		}
 		args.titleInBody = args.title ? ['<h1>', args.title, '</h1>'].join('') : '';
 		return args;	//Object
 	}
 });
-dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Printer/*name:'printer'*/, {
+
+EnhancedGrid.registerPlugin(Printer/*name:'printer'*/, {
 	"dependency": ["exporter"]
 });
+
+return Printer;
+});
diff --git a/dojox/grid/enhanced/plugins/Rearrange.js b/dojox/grid/enhanced/plugins/Rearrange.js
index 29684e8..484671b 100644
--- a/dojox/grid/enhanced/plugins/Rearrange.js
+++ b/dojox/grid/enhanced/plugins/Rearrange.js
@@ -1,9 +1,15 @@
-dojo.provide("dojox.grid.enhanced.plugins.Rearrange");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"../../EnhancedGrid",
+	"../_Plugin",
+	"./_RowMapLayer"
+], function(dojo, lang, declare, array, connect, EnhancedGrid, _Plugin, _RowMapLayer){
 
-dojo.require("dojox.grid.enhanced._Plugin");
-dojo.require("dojox.grid.enhanced.plugins._RowMapLayer");
-
-dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugin, {
+var Rearrange = declare("dojox.grid.enhanced.plugins.Rearrange", _Plugin, {
 	// summary:
 	//		Provides a set of method to re-arrange the structure of grid.
 	
@@ -14,11 +20,11 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 	constructor: function(grid, args){
 		this.grid = grid;
 		this.setArgs(args);
-		var rowMapLayer = new dojox.grid.enhanced.plugins._RowMapLayer(grid);
+		var rowMapLayer = new _RowMapLayer(grid);
 		dojox.grid.enhanced.plugins.wrap(grid, "_storeLayerFetch", rowMapLayer);
 	},
 	setArgs: function(args){
-		this.args = dojo.mixin(this.args || {}, args || {});
+		this.args = lang.mixin(this.args || {}, args || {});
 		this.args.setIdentifierForNewItem = this.args.setIdentifierForNewItem || function(v){return v;};
 	},
 	destroy: function(){
@@ -31,7 +37,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 	_hasIdentity: function(points){
 		var g = this.grid, s = g.store, cells = g.layout.cells;
 		if(s.getFeatures()["dojo.data.api.Identity"]){
-			if(dojo.some(points, function(point){
+			if(array.some(points, function(point){
 				return s.getIdentityAttributes(g._by_idx[point.r].item) == cells[point.c].field;
 			})){
 				return true;
@@ -62,24 +68,22 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 				++delta;
 			}
 		}
-		var leftCount = 0;
-		var rightCount = 0;
+		var leftCount = 0, rightCount = 0;
 		var maxCol = Math.max(colsToMove[colsToMove.length - 1], targetPos);
 		if(maxCol == cells.length){
 			--maxCol;
 		}
-		for(i = colsToMove[0]; i <= maxCol; ++i){
+		var minCol = Math.min(colsToMove[0], targetPos);
+		for(i = minCol; i <= maxCol; ++i){
 			var j = tmp[i];
 			if(j >= 0){
-				if(i != targetPos - delta + j){
-					mapping[i] = targetPos - delta + j;
-				}
-				leftCount = j + 1;
-				rightCount = colsToMove.length - j - 1;
-			}else if(i < targetPos && leftCount > 0){
-				mapping[i] = i - leftCount;
-			}else if(i >= targetPos && rightCount > 0){
-				mapping[i] = i + rightCount;
+				mapping[i] = targetPos - delta + j;
+			}else if(i < targetPos){
+				mapping[i] = minCol + leftCount;
+				++leftCount;
+			}else if(i >= targetPos){
+				mapping[i] = targetPos + colsToMove.length - delta + rightCount;
+				++rightCount;
 			}
 		}
 		//console.log("mapping:", mapping, ", colsToMove:", colsToMove,", target:", targetPos);
@@ -104,7 +108,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 			}
 		}
 		delete g._notRefreshSelection;
-		dojo.publish("dojox/grid/rearrange/move/" + g.id, ["col", mapping, colsToMove]);
+		connect.publish("dojox/grid/rearrange/move/" + g.id, ["col", mapping, colsToMove]);
 	},
 	moveRows: function(rowsToMove, targetPos){
 		// summary:
@@ -135,7 +139,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 		len = arr.length;
 		if(len){
 			rowMap = {};
-			dojo.forEach(arr, function(r){
+			array.forEach(arr, function(r){
 				rowMap[r] = true;
 			});
 			mapping[arr[0]] = targetPos - len;
@@ -153,7 +157,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 		len = arr.length;
 		if(len){
 			rowMap = {};
-			dojo.forEach(arr, function(r){
+			array.forEach(arr, function(r){
 				rowMap[r] = true;
 			});
 			mapping[arr[len - 1]] = targetPos + len - 1;
@@ -167,7 +171,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 				}
 			}
 		}
-		var tmpMapping = dojo.clone(mapping);
+		var tmpMapping = lang.clone(mapping);
 		g.layer("rowmap").setMapping(mapping);
 		g.forEachLayer(function(layer){
 			if(layer.name() != "rowmap"){
@@ -181,7 +185,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 		g._noInternalMapping = true;
 		g._refresh();
 		setTimeout(function(){
-			dojo.publish("dojox/grid/rearrange/move/" + g.id, ["row", tmpMapping, rowsToMove]);
+			connect.publish("dojox/grid/rearrange/move/" + g.id, ["row", tmpMapping, rowsToMove]);
 			g._noInternalMapping = false;
 		}, 0);
 	},
@@ -220,15 +224,15 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 				console.warn("Can not write to identity!");
 				return;
 			}
-			dojo.forEach(sources, function(point){
+			array.forEach(sources, function(point){
 				s.setValue(g._by_idx[point.r].item, cells[point.c].field, "");
 			});
-			dojo.forEach(targets, function(point){
+			array.forEach(targets, function(point){
 				s.setValue(g._by_idx[point.r].item, cells[point.c].field, point.v);
 			});
 			s.save({
 				onComplete: function(){
-					dojo.publish("dojox/grid/rearrange/move/" + g.id, ["cell", {
+					connect.publish("dojox/grid/rearrange/move/" + g.id, ["cell", {
 						"from": cellsToMove,
 						"to": target
 					}]);
@@ -266,13 +270,13 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 				console.warn("Can not write to identity!");
 				return;
 			}
-			dojo.forEach(targets, function(point){
+			array.forEach(targets, function(point){
 				s.setValue(g._by_idx[point.r].item, cells[point.c].field, point.v);
 			});
 			s.save({
 				onComplete: function(){
 					setTimeout(function(){
-						dojo.publish("dojox/grid/rearrange/copy/" + g.id, ["cell", {
+						connect.publish("dojox/grid/rearrange/copy/" + g.id, ["cell", {
 							"from": cellsToMove,
 							"to": target
 						}]);
@@ -309,12 +313,12 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 				console.warn("Can not write to identity!");
 				return;
 			}
-			dojo.forEach(targets, function(point){
+			array.forEach(targets, function(point){
 				s.setValue(g._by_idx[point.r].item, cells[point.c].field, point.v);
 			});
 			s.save({
 				onComplete: function(){
-					dojo.publish("dojox/grid/rearrange/change/" + g.id, ["cell", target]);
+					connect.publish("dojox/grid/rearrange/change/" + g.id, ["cell", target]);
 				}
 			});
 		}
@@ -341,12 +345,12 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 				console.warn("Can not write to identity!");
 				return;
 			}
-			dojo.forEach(targets, function(point){
+			array.forEach(targets, function(point){
 				s.setValue(g._by_idx[point.r].item, cells[point.c].field, "");
 			});
 			s.save({
 				onComplete: function(){
-					dojo.publish("dojox/grid/rearrange/change/" + g.id, ["cell", cellsToClear]);
+					connect.publish("dojox/grid/rearrange/change/" + g.id, ["cell", cellsToClear]);
 				}
 			});
 		}
@@ -359,26 +363,41 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 				mapping = {},
 				obj = {idx: 0},
 				newRows = [], i,
+				emptyTarget = targetPos < 0;
 				_this = this;
 			var len = rowsToMove.length;
-			for(i = targetPos; i < g.rowCount; ++i){
-				mapping[i] = i + len;
+			if(emptyTarget){
+				targetPos = 0;
+			}else{
+				for(i = targetPos; i < g.rowCount; ++i){
+					mapping[i] = i + len;
+				}
 			}
 			if(s.getFeatures()['dojo.data.api.Write']){
 				if(sourceGrid){
 					var srcg = sourceGrid,
 						srcs = srcg.store,
-						thisItem;
-					for(i = 0; !thisItem; ++i){
-						thisItem = g._by_idx[i];
+						thisItem, attrs;
+					if(!emptyTarget){
+						for(i = 0; !thisItem; ++i){
+							thisItem = g._by_idx[i];
+						}
+						attrs = s.getAttributes(thisItem.item);
+					}else{
+						//If the target grid is empty, there is no way to retrieve attributes.
+						//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){
+							return cell.field;
+						});
 					}
-					var attrs = s.getAttributes(thisItem.item);
 					var rowsToFetch = [];
-					dojo.forEach(rowsToMove, function(rowIndex, i){
+					array.forEach(rowsToMove, function(rowIndex, i){
 						var item = {};
 						var srcItem = srcg._by_idx[rowIndex];
 						if(srcItem){
-							dojo.forEach(attrs, function(attr){
+							array.forEach(attrs, function(attr){
 								item[attr] = srcs.getValue(srcItem.item, attr);
 							});
 							item = _this.args.setIdentifierForNewItem(item, s, rowCnt + obj.idx) || item;
@@ -394,8 +413,8 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 							rowsToFetch.push(rowIndex);
 						}
 					});
-				}else if(rowsToMove.length && dojo.isObject(rowsToMove[0])){
-					dojo.forEach(rowsToMove, function(rowData, i){
+				}else if(rowsToMove.length && lang.isObject(rowsToMove[0])){
+					array.forEach(rowsToMove, function(rowData, i){
 						var item = _this.args.setIdentifierForNewItem(rowData, s, rowCnt + obj.idx) || rowData;
 						try{
 							s.newItem(item);
@@ -414,7 +433,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 					onComplete: function(){
 						g._refresh();
 						setTimeout(function(){
-							dojo.publish("dojox/grid/rearrange/insert/" + g.id, ["row", newRows]);
+							connect.publish("dojox/grid/rearrange/insert/" + g.id, ["row", newRows]);
 						}, 0);
 					}
 				});
@@ -427,7 +446,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 		var g = this.grid;
 		var s = g.store;
 		try{
-			dojo.forEach(dojo.map(rowsToRemove, function(rowIndex){
+			array.forEach(array.map(rowsToRemove, function(rowIndex){
 				return g._by_idx[rowIndex];
 			}), function(row){
 				if(row){
@@ -436,7 +455,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 			});
 			s.save({
 				onComplete: function(){
-					dojo.publish("dojox/grid/rearrange/remove/" + g.id, ["row", rowsToRemove]);
+					connect.publish("dojox/grid/rearrange/remove/" + g.id, ["row", rowsToRemove]);
 				}
 			});
 		}catch(e){
@@ -458,7 +477,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 			topRow, bottomRow, matched,
 			invalidPages = [];
 		
-		dojo.forEach(renderedPages, function(page, pageIndex){
+		array.forEach(renderedPages, function(page, pageIndex){
 			if(!page){ return; }
 			matched = false;
 			topRow = pageIndex * rowsPerPage;
@@ -478,4 +497,9 @@ dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugi
 		return {topPage: topPage, bottomPage: bottomPage, invalidPages: invalidPages};
 	}
 });
-dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Rearrange/*name:'rearrange'*/);
+
+EnhancedGrid.registerPlugin(Rearrange/*name:'rearrange'*/);
+
+return Rearrange;
+
+});
\ No newline at end of file
diff --git a/dojox/grid/enhanced/plugins/Search.js b/dojox/grid/enhanced/plugins/Search.js
index 4df51f4..5c4d191 100644
--- a/dojox/grid/enhanced/plugins/Search.js
+++ b/dojox/grid/enhanced/plugins/Search.js
@@ -1,9 +1,14 @@
-dojo.provide("dojox.grid.enhanced.plugins.Search");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/data/util/filter",
+	"../../EnhancedGrid",
+	"../_Plugin"
+], function(dojo, lang, declare, array, dFilter, EnhancedGrid, _Plugin){
 
-dojo.require("dojox.grid.enhanced._Plugin");
-dojo.require("dojo.data.util.filter");
-
-dojo.declare("dojox.grid.enhanced.plugins.Search", dojox.grid.enhanced._Plugin, {
+var Search = declare("dojox.grid.enhanced.plugins.Search", _Plugin, {
 	// summary:
 	//		Search the grid using wildcard string or Regular Expression.
 	
@@ -13,23 +18,23 @@ dojo.declare("dojox.grid.enhanced.plugins.Search", dojox.grid.enhanced._Plugin,
 	
 	constructor: function(grid, args){
 		this.grid = grid;
-		args = (args && dojo.isObject(args)) ? args : {};
+		args = (args && lang.isObject(args)) ? args : {};
 		this._cacheSize = args.cacheSize || -1;
-		grid.searchRow = dojo.hitch(this, "searchRow");
+		grid.searchRow = lang.hitch(this, "searchRow");
 	},
 	searchRow: function(/* Object|RegExp|String */searchArgs, /* function(Integer, item) */onSearched){
-		if(!dojo.isFunction(onSearched)){ return; }
-		if(dojo.isString(searchArgs)){
-			searchArgs = dojo.data.util.filter.patternToRegExp(searchArgs);
+		if(!lang.isFunction(onSearched)){ return; }
+		if(lang.isString(searchArgs)){
+			searchArgs = dFilter.patternToRegExp(searchArgs);
 		}
 		var isGlobal = false;
 		if(searchArgs instanceof RegExp){
 			isGlobal = true;
-		}else if(dojo.isObject(searchArgs)){
+		}else if(lang.isObject(searchArgs)){
 			var isEmpty = true;
 			for(var field in searchArgs){
-				if(dojo.isString(searchArgs[field])){
-					searchArgs[field] = dojo.data.util.filter.patternToRegExp(searchArgs[field]);
+				if(lang.isString(searchArgs[field])){
+					searchArgs[field] = dFilter.patternToRegExp(searchArgs[field]);
 				}
 				isEmpty = false;
 			}
@@ -43,12 +48,15 @@ dojo.declare("dojox.grid.enhanced.plugins.Search", dojox.grid.enhanced._Plugin,
 		var _this = this,
 			cnt = this._cacheSize,
 			args = {
-				"start": start,
-				"onBegin": function(size){
+				start: start,
+				query: this.grid.query,
+				sort: this.grid.getSortProps(),
+				queryOptions: this.grid.queryOptions,
+				onBegin: function(size){
 					_this._storeSize = size;
 				},
-				"onComplete": function(items){
-					if(!dojo.some(items, function(item, i){
+				onComplete: function(items){
+					if(!array.some(items, function(item, i){
 						if(_this._checkRow(item, searchArgs, isGlobal)){
 							onSearched(start + i, item);
 							return true;
@@ -70,11 +78,11 @@ dojo.declare("dojox.grid.enhanced.plugins.Search", dojox.grid.enhanced._Plugin,
 	},
 	_checkRow: function(/* store item */item, /* Object|RegExp */searchArgs, /* Boolean */isGlobal){
 		var g = this.grid, s = g.store, i, field,
-			cells = dojo.filter(g.layout.cells, function(cell){
+			cells = array.filter(g.layout.cells, function(cell){
 				return !cell.hidden;
 			});
 		if(isGlobal){
-			return dojo.some(cells, function(cell){
+			return array.some(cells, function(cell){
 				try{
 					if(cell.field){
 						return String(s.getValue(item, cell.field)).search(searchArgs) >= 0;
@@ -106,4 +114,9 @@ dojo.declare("dojox.grid.enhanced.plugins.Search", dojox.grid.enhanced._Plugin,
 		}
 	}
 });
-dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Search/*name:'search'*/);
+
+EnhancedGrid.registerPlugin(Search/*name:'search'*/);
+
+return Search;
+
+});
\ No newline at end of file
diff --git a/dojox/grid/enhanced/plugins/Selector.js b/dojox/grid/enhanced/plugins/Selector.js
index 51f01d6..330cc13 100644
--- a/dojox/grid/enhanced/plugins/Selector.js
+++ b/dojox/grid/enhanced/plugins/Selector.js
@@ -1,10 +1,21 @@
-dojo.provide("dojox.grid.enhanced.plugins.Selector");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/event",
+	"dojo/keys",
+	"dojo/query",
+	"dojo/_base/html",
+	"dojo/_base/window",
+	"dijit/focus",
+	"../../_RowSelector",
+	"../_Plugin",
+	"../../EnhancedGrid",
+	"../../cells/_base",
+	"./AutoScroll"
+], function(dojo, lang, declare, array, event, keys, query, html, win, dijitFocus, _RowSelector, _Plugin, EnhancedGrid){
 
-dojo.require("dojox.grid.enhanced._Plugin");
-dojo.require("dojox.grid.enhanced.plugins.AutoScroll");
-dojo.require("dojox.grid.cells._base");
-
-(function(){
 /*=====
 dojo.declare("__SelectItem", null,{
 	// summary:
@@ -81,7 +92,7 @@ var DISABLED = 0, SINGLE = 1, MULTI = 2,
 	_stopEvent = function(evt){
 		try{
 			if(evt && evt.preventDefault){
-				dojo.stopEvent(evt);
+				event.stop(evt);
 			}
 		}catch(e){}
 	},
@@ -105,7 +116,7 @@ var DISABLED = 0, SINGLE = 1, MULTI = 2,
 		}
 		return null;
 	};
-dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin, {
+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.
@@ -119,6 +130,9 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 	// name: String
 	//		plugin name
 	name: "selector",
+
+	// noClear: Boolean
+	//		Not to clear rows selected by IndirectSelection.
 /*
 	//	_config: null,
 	//	_enabled: true,
@@ -156,6 +170,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 			col: MULTI,
 			cell: MULTI
 		};
+		this.noClear = args && args.noClear;
 		this.setupConfig(args);
 		if(grid.selectionMode === "single"){
 			this._config.row = SINGLE;
@@ -196,12 +211,12 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		//			col: false|"disabled"|"single",
 		//			cell: false|"disabled"|"single"
 		//		}
-		if(!config || !dojo.isObject(config)){
+		if(!config || !lang.isObject(config)){
 			return;
 		}
 		var types = ["row", "col", "cell"];
 		for(var type in config){
-			if(dojo.indexOf(types, type) >= 0){
+			if(array.indexOf(types, type) >= 0){
 				if(!config[type] || config[type] == "disabled"){
 					this._config[type] = DISABLED;
 				}else if(config[type] == "single"){
@@ -328,10 +343,10 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		// return: __SelectItem[]
 		switch(type){
 			case "cell":
-				return dojo.map(this._selected[type], function(item){ return item; });
+				return array.map(this._selected[type], function(item){ return item; });
 			case "col": case "row":
-				return dojo.map(includeExceptions ? this._selected[type]
-				: dojo.filter(this._selected[type], function(item){
+				return array.map(includeExceptions ? this._selected[type]
+				: array.filter(this._selected[type], function(item){
 					return item.except.length === 0;
 				}), function(item){
 					return includeExceptions ? item : item[type];
@@ -355,7 +370,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 				return this._selected[type].length;
 			case "col": case "row":
 				return (includeExceptions ? this._selected[type]
-				: dojo.filter(this._selected[type], function(item){
+				: array.filter(this._selected[type], function(item){
 					return item.except.length === 0;
 				})).length;
 		}
@@ -398,12 +413,12 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 			}
 			g.onMouseUpRow(e);
 		};
-		var mouseUp = dojo.hitch(g, "onMouseUp");
-		var mouseDown = dojo.hitch(g, "onMouseDown");
+		var mouseUp = lang.hitch(g, "onMouseUp");
+		var mouseDown = lang.hitch(g, "onMouseDown");
 		var doRowSelectorFocus = function(e){
 			e.cellNode.style.border = "solid 1px";
 		};
-		dojo.forEach(g.views.views, function(view){
+		array.forEach(g.views.views, function(view){
 			view.content.domouseup = doContentMouseUp;
 			view.header.domouseup = mouseUp;
 			if(view.declaredClass == "dojox.grid._RowSelector"){
@@ -434,7 +449,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		g.selection.deselectAll = function(){
 			g._selectingRange = true;
 			_this._oldDeselectAll.apply(g.selection, arguments);
-			_this._clearSelection("row");
+			_this._clearSelection("all");
 			g._selectingRange = false;
 			if(g.selection.preserver){
 				g.selection.preserver._updateMapping(true, false, true);
@@ -444,17 +459,17 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		
 		var rowSelector = g.views.views[0];
 		//The default function re-write the whole className, so can not insert any other classes.
-		if(rowSelector instanceof dojox.grid._RowSelector){
+		if(rowSelector instanceof _RowSelector){
 			rowSelector.doStyleRowNode = function(inRowIndex, inRowNode){
-				dojo.removeClass(inRowNode, "dojoxGridRow");
-				dojo.addClass(inRowNode, "dojoxGridRowbar");
-				dojo.addClass(inRowNode, "dojoxGridNonNormalizedCell");
-				dojo.toggleClass(inRowNode, "dojoxGridRowbarOver", g.rows.isOver(inRowIndex));
-				dojo.toggleClass(inRowNode, "dojoxGridRowbarSelected", !!g.selection.isSelected(inRowIndex));
+				html.removeClass(inRowNode, "dojoxGridRow");
+				html.addClass(inRowNode, "dojoxGridRowbar");
+				html.addClass(inRowNode, "dojoxGridNonNormalizedCell");
+				html.toggleClass(inRowNode, "dojoxGridRowbarOver", g.rows.isOver(inRowIndex));
+				html.toggleClass(inRowNode, "dojoxGridRowbarSelected", !!g.selection.isSelected(inRowIndex));
 			};
 		}
 		this.connect(g, "updateRow", function(rowIndex){
-			dojo.forEach(g.layout.cells, function(cell){
+			array.forEach(g.layout.cells, function(cell){
 				if(this.isSelected("cell", rowIndex, cell.index)){
 					this._highlightNode(cell.getNode(rowIndex), true);
 				}
@@ -465,7 +480,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		// summary:
 		//		Expose events to grid.
 		var g = this.grid;
-		g.setupSelectorConfig = dojo.hitch(this, this.setupConfig);
+		g.setupSelectorConfig = lang.hitch(this, this.setupConfig);
 		g.onStartSelect = function(){};
 		g.onEndSelect = function(){};
 		g.onStartDeselect = function(){};
@@ -477,7 +492,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		//		Connect events, create event handlers.
 		var g = this.grid,
 			_this = this,
-			dp = dojo.partial,
+			dp = lang.partial,
 			starter = function(type, e){
 				if(type === "row"){
 					_this._isUsingRowSelector = true;
@@ -495,7 +510,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 					_this._startSelect(type, target, e.ctrlKey, e.shiftKey);
 				}
 			},
-			ender = dojo.hitch(this, "_endSelect");
+			ender = lang.hitch(this, "_endSelect");
 		this.connect(g, "onHeaderCellMouseDown", dp(starter, "col"));
 		this.connect(g, "onHeaderCellMouseUp", dp(ender, "col"));
 		
@@ -557,7 +572,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		});
 		
 		//Whenever the mouse is up, end selecting.
-		this.connect(dojo.doc, "onmouseup", dp(ender, "all"));
+		this.connect(win.doc, "onmouseup", dp(ender, "all"));
 		
 		//If autoscroll is enabled, connect to it.
 		this.connect(g, "onEndAutoScroll", function(isVertical, isForward, view, target){
@@ -604,7 +619,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 			this._lastSelectedAnchorPoint.row, this._lastSelectedEndPoint.row];
 		pointSet = pointSet.concat(this._selected.row);
 		var found = false;
-		dojo.forEach(pointSet, function(item){
+		array.forEach(pointSet, function(item){
 			if(item){
 				if(item.id === id){
 					found = true;
@@ -615,7 +630,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 			}
 		});
 		if(!found && isSelected){
-			dojo.some(this._selected.row, function(item){
+			array.some(this._selected.row, function(item){
 				if(item && !item.id && !item.except.length){
 					item.id = id;
 					item.row = newIndex;
@@ -628,7 +643,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		pointSet = [this._lastAnchorPoint.cell, this._lastEndPoint.cell,
 			this._lastSelectedAnchorPoint.cell, this._lastSelectedEndPoint.cell];
 		pointSet = pointSet.concat(this._selected.cell);
-		dojo.forEach(pointSet, function(item){
+		array.forEach(pointSet, function(item){
 			if(item){
 				if(item.id === id){
 					found = true;
@@ -647,16 +662,16 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		//The column can not refresh it self!
 		this._refresh("col", false);
 		
-		dojo.forEach(this._selected.row, function(item){
-			dojo.forEach(this.grid.layout.cells, function(cell){
+		array.forEach(this._selected.row, function(item){
+			array.forEach(this.grid.layout.cells, function(cell){
 				this._highlightNode(cell.getNode(item.row), false);
 			}, this);
 		}, this);
 		//The rowbar must be cleaned manually
-		dojo.query(".dojoxGridRowSelectorSelected").forEach(function(node){
-			dojo.removeClass(node, "dojoxGridRowSelectorSelected");
-			dojo.removeClass(node, "dojoxGridRowSelectorSelectedUp");
-			dojo.removeClass(node, "dojoxGridRowSelectorSelectedDown");
+		query(".dojoxGridRowSelectorSelected").forEach(function(node){
+			html.removeClass(node, "dojoxGridRowSelectorSelected");
+			html.removeClass(node, "dojoxGridRowSelectorSelectedUp");
+			html.removeClass(node, "dojoxGridRowSelectorSelectedDown");
 		});
 		
 		var cleanUp = function(item){
@@ -670,7 +685,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		if(type === "cell"){
 			this.selectRange("cell", mapping.to.min, mapping.to.max);
 			var cells = this.grid.layout.cells;
-			dojo.forEach(pointSet, function(item){
+			array.forEach(pointSet, function(item){
 				if(item.converted){ return; }
 				for(var r = mapping.from.min.row, tr = mapping.to.min.row; r <= mapping.from.max.row; ++r, ++tr){
 					for(var c = mapping.from.min.col, tc = mapping.to.min.col; c <= mapping.from.max.col; ++c, ++tc){
@@ -690,7 +705,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 			pointSet = this._selected.cell.concat(this._selected[type]).concat(pointSet).concat(
 				[this._lastAnchorPoint.cell, this._lastEndPoint.cell,
 				this._lastSelectedAnchorPoint.cell, this._lastSelectedEndPoint.cell]);
-			dojo.forEach(pointSet, function(item){
+			array.forEach(pointSet, function(item){
 				if(item && !item.converted){
 					var from = item[type];
 					if(from in mapping){
@@ -699,7 +714,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 					item.converted = true;
 				}
 			});
-			dojo.forEach(this._selected[_theOther[type]], function(item){
+			array.forEach(this._selected[_theOther[type]], function(item){
 				for(var i = 0, len = item.except.length; i < len; ++i){
 					var from = item.except[i];
 					if(from in mapping){
@@ -709,7 +724,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 			});
 		}
 		
-		dojo.forEach(pointSet, cleanUp);
+		array.forEach(pointSet, cleanUp);
 		
 		this._refreshSelected(true);
 		this._focusPoint(type, this._lastEndPoint);
@@ -724,7 +739,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 	},
 	_refresh: function(type, toHighlight){
 		if(!this._keyboardSelect[type]){
-			dojo.forEach(this._selected[type], function(item){
+			array.forEach(this._selected[type], function(item){
 				this._highlightSingle(type, toHighlight, item, undefined, true);
 			}, this);
 		}
@@ -735,7 +750,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		this._refresh("cell", true);
 	},
 	_initAreas: function(){
-		var g = this.grid, f = g.focus, _this = this, dk = dojo.keys,
+		var g = this.grid, f = g.focus, _this = this,
 			keyboardSelectReady = 1, duringKeyboardSelect = 2,
 			onmove = function(type, createNewEnd, rowStep, colStep, evt){
 				//Keyboard swipe selection is SHIFT + Direction Keys.
@@ -766,12 +781,12 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 			onkeydown = function(type, getTarget, evt, isBubble){
 				if(isBubble && _this.selectEnabled() && _this._config[type] != DISABLED){
 					switch(evt.keyCode){
-						case dk.SPACE:
+						case keys.SPACE:
 							//Keyboard single point selection is SPACE.
 							_this._startSelect(type, getTarget(), evt.ctrlKey, evt.shiftKey);
 							_this._endSelect(type);
 							break;
-						case dk.SHIFT:
+						case keys.SHIFT:
 							//Keyboard swipe selection starts with SHIFT.
 							if(_this._config[type] == MULTI && _this._isValid(type, _this._lastAnchorPoint[type], g)){
 								//End last selection if any.
@@ -783,22 +798,22 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 				}
 			},
 			onkeyup = function(type, evt, isBubble){
-				if(isBubble && evt.keyCode == dojo.keys.SHIFT && _this._keyboardSelect[type]){
+				if(isBubble && evt.keyCode == keys.SHIFT && _this._keyboardSelect[type]){
 					_this._endSelect(type);
 					_this._keyboardSelect[type] = 0;
 				}
 			};
 		//TODO: this area "rowHeader" should be put outside, same level as header/content.
-		if(g.views.views[0] instanceof dojox.grid._RowSelector){
+		if(g.views.views[0] instanceof _RowSelector){
 			this._lastFocusedRowBarIdx = 0;
 			f.addArea({
 				name:"rowHeader",
 				onFocus: function(evt, step){
 					var view = g.views.views[0];
-					if(view instanceof dojox.grid._RowSelector){
+					if(view instanceof _RowSelector){
 						var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
 						if(rowBarNode){
-							dojo.toggleClass(rowBarNode, f.focusClass, false);
+							html.toggleClass(rowBarNode, f.focusClass, false);
 						}
 						//evt might not be real event, it may be a mock object instead.
 						if(evt && "rowIndex" in evt){
@@ -810,8 +825,8 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 						}
 						rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
 						if(rowBarNode){
-							dijit.focus(rowBarNode);
-							dojo.toggleClass(rowBarNode, f.focusClass, true);
+							dijitFocus.focus(rowBarNode);
+							html.toggleClass(rowBarNode, f.focusClass, true);
 						}
 						f.rowIndex = _this._lastFocusedRowBarIdx;
 						_stopEvent(evt);
@@ -821,10 +836,10 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 				},
 				onBlur: function(evt, step){
 					var view = g.views.views[0];
-					if(view instanceof dojox.grid._RowSelector){
+					if(view instanceof _RowSelector){
 						var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
 						if(rowBarNode){
-							dojo.toggleClass(rowBarNode, f.focusClass, false);
+							html.toggleClass(rowBarNode, f.focusClass, false);
 						}
 						_stopEvent(evt);
 					}
@@ -832,13 +847,13 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 				},
 				onMove: function(rowStep, colStep, evt){
 					var view = g.views.views[0];
-					if(rowStep && view instanceof dojox.grid._RowSelector){
+					if(rowStep && view instanceof _RowSelector){
 						var next = _this._lastFocusedRowBarIdx + rowStep;
 						if(next >= 0 && next < g.rowCount){
 							//TODO: these logic require a better Scroller.
 							_stopEvent(evt);
 							var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
-							dojo.toggleClass(rowBarNode, f.focusClass, false);
+							html.toggleClass(rowBarNode, f.focusClass, false);
 							//If the row is not fetched, fetch it.
 							var sc = g.scroller;
 							var lastPageRow = sc.getLastPageRow(sc.page);
@@ -848,8 +863,8 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 							}
 							//Now we have fetched the row.
 							rowBarNode = view.getCellNode(next, 0);
-							dijit.focus(rowBarNode);
-							dojo.toggleClass(rowBarNode, f.focusClass, true);
+							dijitFocus.focus(rowBarNode);
+							html.toggleClass(rowBarNode, f.focusClass, true);
 							_this._lastFocusedRowBarIdx = next;
 							//If the row is out of view, scroll to it.
 							f.cell = rowBarNode;
@@ -869,37 +884,37 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		//Support keyboard selection.
 		f.addArea({
 			name:"cellselect",
-			onMove: dojo.partial(onmove, "cell", function(type, rowStep, colStep, evt){
+			onMove: lang.partial(onmove, "cell", function(type, rowStep, colStep, evt){
 				var current = _this._currentPoint[type];
 				return _createItem("cell", current.row + rowStep, current.col + colStep);
 			}),
-			onKeyDown: dojo.partial(onkeydown, "cell", function(){
+			onKeyDown: lang.partial(onkeydown, "cell", function(){
 				return _createItem("cell", f.rowIndex, f.cell.index);
 			}),
-			onKeyUp: dojo.partial(onkeyup, "cell")
+			onKeyUp: lang.partial(onkeyup, "cell")
 		});
 		f.placeArea("cellselect","below","content");
 		f.addArea({
 			name:"colselect",
-			onMove: dojo.partial(onmove, "col", function(type, rowStep, colStep, evt){
+			onMove: lang.partial(onmove, "col", function(type, rowStep, colStep, evt){
 				var current = _this._currentPoint[type];
 				return _createItem("col", current.col + colStep);
 			}),
-			onKeyDown: dojo.partial(onkeydown, "col", function(){
+			onKeyDown: lang.partial(onkeydown, "col", function(){
 				return _createItem("col", f.getHeaderIndex());
 			}),
-			onKeyUp: dojo.partial(onkeyup, "col")
+			onKeyUp: lang.partial(onkeyup, "col")
 		});
 		f.placeArea("colselect","below","header");
 		f.addArea({
 			name:"rowselect",
-			onMove: dojo.partial(onmove, "row", function(type, rowStep, colStep, evt){
+			onMove: lang.partial(onmove, "row", function(type, rowStep, colStep, evt){
 				return _createItem("row", f.rowIndex);
 			}),
-			onKeyDown: dojo.partial(onkeydown, "row", function(){
+			onKeyDown: lang.partial(onkeydown, "row", function(){
 				return _createItem("row", f.rowIndex);
 			}),
-			onKeyUp: dojo.partial(onkeyup, "row")
+			onKeyUp: lang.partial(onkeyup, "row")
 		});
 		f.placeArea("rowselect","below","rowHeader");
 	},
@@ -920,7 +935,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 			return;
 		}
 		this._isUsingRowSelector = true;
-		dojo.forEach(this._selected[type], function(item){
+		array.forEach(this._selected[type], function(item){
 			if(!_isEqual(type, reservedItem, item)){
 				this._highlightSingle(type, false, item);
 			}
@@ -961,12 +976,20 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		var lastIsSelected = this._isSelected(type, this._lastEndPoint[type]),
 			isSelected = this._isSelected(type, start);
 		
-		//If we are modifying the selection using keyboard, retain the old status.
-		this._toSelect = mandatarySelect ? isSelected : !isSelected;
+		if(this.noClear && !extending){
+			this._toSelect = toSelect === undefined ? true : toSelect;
+		}else{
+			//If we are modifying the selection using keyboard, retain the old status.
+			this._toSelect = mandatarySelect ? isSelected : !isSelected;
+		}
 		
 		//If CTRL is not pressed or it's SINGLE mode, this is a brand new selection.
 		if(!extending || (!isSelected && this._config[type] == SINGLE)){
-			this._clearSelection("all", start);
+			this._clearSelection("col", start);
+			this._clearSelection("cell", start);
+			if(!this.noClear || (type === 'row' && this._config[type] == SINGLE)){
+				this._clearSelection('row', start);
+			}
 			this._toSelect = toSelect === undefined ? true : toSelect;
 		}
 		
@@ -974,7 +997,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		this._currentPoint[type] = null;
 		
 		//We're holding SHIFT while clicking, it's a Click-Range selection.
-		if(isRange && this._lastType == type && lastIsSelected == this._toSelect){
+		if(isRange && this._lastType == type && lastIsSelected == this._toSelect && this._config[type] == MULTI){
 			if(type === "row"){
 				this._isUsingRowSelector = true;
 			}
@@ -1060,24 +1083,24 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		if(node){
 			var selectCSSClass = "dojoxGridRowSelected";
 			var selectCellClass = "dojoxGridCellSelected";
-			dojo.toggleClass(node, selectCSSClass, toHighlight);
-			dojo.toggleClass(node, selectCellClass, toHighlight);
+			html.toggleClass(node, selectCSSClass, toHighlight);
+			html.toggleClass(node, selectCellClass, toHighlight);
 		}
 	},
 	_highlightHeader: function(colIdx, toHighlight){
 		var cells = this.grid.layout.cells;
 		var node = cells[colIdx].getHeaderNode();
 		var selectedClass = "dojoxGridHeaderSelected";
-		dojo.toggleClass(node, selectedClass, toHighlight);
+		html.toggleClass(node, selectedClass, toHighlight);
 	},
 	_highlightRowSelector: function(rowIdx, toHighlight){
 		//var t1 = (new Date()).getTime();
 		var rowSelector = this.grid.views.views[0];
-		if(rowSelector instanceof dojox.grid._RowSelector){
+		if(rowSelector instanceof _RowSelector){
 			var node = rowSelector.getRowNode(rowIdx);
 			if(node){
 				var selectedClass = "dojoxGridRowSelectorSelected";
-				dojo.toggleClass(node, selectedClass, toHighlight);
+				html.toggleClass(node, selectedClass, toHighlight);
 			}
 		}
 		//console.log((new Date()).getTime() - t1);
@@ -1098,7 +1121,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 			case "col":
 				toHL = this._calcToHighlight(type, target, toHighlight, toSelect);
 				this._highlightHeader(target.col, toHL);
-				dojo.query("td[idx='" + target.col + "']", g.domNode).forEach(function(cellNode){
+				query("td[idx='" + target.col + "']", g.domNode).forEach(function(cellNode){
 					var rowNode = cells[target.col].view.content.findRowTarget(cellNode);
 					if(rowNode){
 						var rowIndex = rowNode[dojox.grid.util.rowIndexTag];
@@ -1113,13 +1136,15 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 			case "row":
 				toHL = this._calcToHighlight(type, target, toHighlight, toSelect);
 				this._highlightRowSelector(target.row, toHL);
-				dojo.forEach(cells, function(cell){
-					_this._highlightSingle("cell", toHL, {
-						"row": target.row,
-						"col": cell.index,
-						"node": cell.getNode(target.row)
+				if(this._config.cell){
+					array.forEach(cells, function(cell){
+						_this._highlightSingle("cell", toHL, {
+							"row": target.row,
+							"col": cell.index,
+							"node": cell.getNode(target.row)
+						});
 					});
-				});
+				}
 				//To avoid dead lock
 				this._selectedRowModified = true;
 				if(!isRefresh){
@@ -1235,7 +1260,7 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		this._remove(type, toRemove);
 		
 		// have to keep record in original grid selection
-		dojo.forEach(this._selected.row, function(item){
+		array.forEach(this._selected.row, function(item){
 			if(item.except.length > 0){
 				//to avoid dead lock
 				this._selectedRowModified = true;
@@ -1276,10 +1301,10 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		// summary:
 		//		When new cells is selected, maybe they will fill in the "holes" in selected rows and columns.
 		var makedUps = [];
-		dojo.forEach(this._selected[type], function(v1){
-			dojo.forEach(newCellItems, function(v2){
+		array.forEach(this._selected[type], function(v1){
+			array.forEach(newCellItems, function(v2){
 				if(v1[type] == v2[type]){
-					var pos = dojo.indexOf(v1.except, v2[_theOther[type]]);
+					var pos = array.indexOf(v1.except, v2[_theOther[type]]);
 					if(pos >= 0){
 						v1.except.splice(pos, 1);
 					}
@@ -1294,8 +1319,8 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		//		When some rows/cols are selected, maybe they can cover some of the selected cells,
 		//		and fill some of the "holes" in the selected cols/rows.
 		var toRemove = [];
-		dojo.forEach(this._selected.cell, function(v1){
-			dojo.some(newItems, function(v2){
+		array.forEach(this._selected.cell, function(v1){
+			array.some(newItems, function(v2){
 				if(v1[type] == v2[type]){
 					toRemove.push(v1);
 					return true;
@@ -1304,9 +1329,9 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 			});
 		});
 		this._remove("cell", toRemove);
-		dojo.forEach(this._selected[_theOther[type]], function(v1){
-			dojo.forEach(newItems, function(v2){
-				var pos = dojo.indexOf(v1.except, v2[type]);
+		array.forEach(this._selected[_theOther[type]], function(v1){
+			array.forEach(newItems, function(v2){
+				var pos = array.indexOf(v1.except, v2[type]);
 				if(pos >= 0){
 					v1.except.splice(pos, 1);
 				}
@@ -1316,8 +1341,8 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 	_addException: function(type, items){
 		// summary:
 		//		If some rows/cols are deselected, maybe they have created "holes" in selected cols/rows.
-		dojo.forEach(this._selected[type], function(v1){
-			dojo.forEach(items, function(v2){
+		array.forEach(this._selected[type], function(v1){
+			array.forEach(items, function(v2){
 				v1.except.push(v2[_theOther[type]]);
 			});
 		});
@@ -1325,8 +1350,8 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 	_addCellException: function(type, items){
 		// summary:
 		//		If some cells are deselected, maybe they have created "holes" in selected rows/cols.
-		dojo.forEach(this._selected[type], function(v1){
-			dojo.forEach(items, function(v2){
+		array.forEach(this._selected[type], function(v1){
+			array.forEach(items, function(v2){
 				if(v1[type] == v2[type]){
 					v1.except.push(v2[_theOther[type]]);
 				}
@@ -1341,26 +1366,26 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 			var colMakedup = this._makeupForExceptions("col", items);
 			var rowMakedup = this._makeupForExceptions("row", items);
 			//Step over hidden columns.
-			items = dojo.filter(items, function(item){
-				return dojo.indexOf(colMakedup, item) < 0 && dojo.indexOf(rowMakedup, item) < 0 &&
+			items = array.filter(items, function(item){
+				return array.indexOf(colMakedup, item) < 0 && array.indexOf(rowMakedup, item) < 0 &&
 					!cells[item.col].hidden && !cells[item.col].notselectable;
 			});
 		}else{
 			if(type == "col"){
 				//Step over hidden columns.
-				items = dojo.filter(items, function(item){
+				items = array.filter(items, function(item){
 					return !cells[item.col].hidden && !cells[item.col].notselectable;
 				});
 			}
 			this._makeupForCells(type, items);
-			this._selected[type] = dojo.filter(this._selected[type], function(v){
-				return dojo.every(items, function(item){
+			this._selected[type] = array.filter(this._selected[type], function(v){
+				return array.every(items, function(item){
 					return v[type] !== item[type];
 				});
 			});
 		}
 		if(type != "col" && this.grid._hasIdentity){
-			dojo.forEach(items, function(item){
+			array.forEach(items, function(item){
 				var record = this.grid._by_idx[item.row];
 				if(record){
 					item.id = record.idty;
@@ -1372,16 +1397,16 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 	_remove: function(type, items){
 		// summary:
 		//		Remove from the selection record.
-		var comp = dojo.partial(_isEqual, type);
-		this._selected[type] = dojo.filter(this._selected[type], function(v1){
-			return !dojo.some(items, function(v2){
+		var comp = lang.partial(_isEqual, type);
+		this._selected[type] = array.filter(this._selected[type], function(v1){
+			return !array.some(items, function(v2){
 				return comp(v1, v2);
 			});
 		});
 		if(type == "cell"){
 			this._addCellException("col", items);
 			this._addCellException("row", items);
-		}else{
+		}else if(this._config.cell){
 			this._addException(_theOther[type], items);
 		}
 	},
@@ -1389,15 +1414,15 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		// summary:
 		//		Return true only when a cell is covered by selected row/col, and its not a "hole".
 		var attr = item[type], corres = item[_theOther[type]];
-		return dojo.some(this._selected[type], function(v){
-			return v[type] == attr && dojo.indexOf(v.except, corres) < 0;
+		return array.some(this._selected[type], function(v){
+			return v[type] == attr && array.indexOf(v.except, corres) < 0;
 		});
 	},
 	_isSelected: function(type, item){
 		// summary:
 		//		Return true when the item is selected. (or logically selected, i.e, covered by a row/col).
 		if(!item){ return false; }
-		var res = dojo.some(this._selected[type], function(v){
+		var res = array.some(this._selected[type], function(v){
 			var ret = _isEqual(type, item, v);
 			if(ret && type !== "cell"){
 				return v.except.length === 0;
@@ -1428,10 +1453,10 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 			var g = this.grid, index = item[type];
 			switch(type){
 				case "col":
-					return index >= 0 && index < g.layout.cells.length && dojo.isArray(item.except) &&
+					return index >= 0 && index < g.layout.cells.length && lang.isArray(item.except) &&
 							(allowNotSelectable || !g.layout.cells[index].notselectable);
 				case "row":
-					return index >= 0 && index < g.rowCount && dojo.isArray(item.except);
+					return index >= 0 && index < g.rowCount && lang.isArray(item.except);
 				case "cell":
 					return item.col >= 0 && item.col < g.layout.cells.length &&
 							item.row >= 0 && item.row < g.rowCount &&
@@ -1441,7 +1466,11 @@ dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin
 		return false;
 	}
 });
-dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Selector/*name:'selector'*/, {
+
+EnhancedGrid.registerPlugin(Selector/*name:'selector'*/, {
 	"dependency": ["autoScroll"]
 });
-})();
+
+return Selector;
+
+});
\ No newline at end of file
diff --git a/dojox/grid/enhanced/plugins/_RowMapLayer.js b/dojox/grid/enhanced/plugins/_RowMapLayer.js
index d543fb8..532da67 100644
--- a/dojox/grid/enhanced/plugins/_RowMapLayer.js
+++ b/dojox/grid/enhanced/plugins/_RowMapLayer.js
@@ -1,8 +1,10 @@
-dojo.provide("dojox.grid.enhanced.plugins._RowMapLayer");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"./_StoreLayer"
+], function(declare, array, lang, layers){
 
-dojo.require("dojox.grid.enhanced.plugins._StoreLayer");
-
-(function(){
 var _devideToArrays = function(a){
 	a.sort(function(v1, v2){
 		return v1 - v2;
@@ -18,10 +20,10 @@ var _devideToArrays = function(a){
 	return arr;
 },
 hitchIfCan = function(scope, func){
-	return func ? dojo.hitch(scope || dojo.global, func) : function(){};
+	return func ? lang.hitch(scope || lang.global, func) : function(){};
 };
 
-dojo.declare("dojox.grid.enhanced.plugins._RowMapLayer", dojox.grid.enhanced.plugins._StoreLayer, {
+return declare("dojox.grid.enhanced.plugins._RowMapLayer", layers._StoreLayer, {
 	tags: ["reorder"],
 	constructor: function(grid){
 		this._map = {};
@@ -159,7 +161,7 @@ dojo.declare("dojox.grid.enhanced.plugins._RowMapLayer", dojox.grid.enhanced.plu
 			return userRequest;
 		}else{
 			//No row mapping at all.
-			return dojo.hitch(this._store, this._originFetch)(userRequest);
+			return lang.hitch(this._store, this._originFetch)(userRequest);
 		}
 	},
 	_getRowArrays: function(rows){
@@ -170,7 +172,7 @@ dojo.declare("dojox.grid.enhanced.plugins._RowMapLayer", dojox.grid.enhanced.plu
 		var urstart = userRequest.start = arr[0];
 		userRequest.count = arr[arr.length - 1] - arr[0] + 1;
 		userRequest.onComplete = function(items){
-			dojo.forEach(items, function(item, i){
+			array.forEach(items, function(item, i){
 				var r = urstart + i;
 				if(r in map){
 					result[map[r]] = item;
@@ -201,4 +203,4 @@ dojo.declare("dojox.grid.enhanced.plugins._RowMapLayer", dojox.grid.enhanced.plu
 		_this.originFetch(userRequest);
 	}
 });
-})();
+});
diff --git a/dojox/grid/enhanced/plugins/_SelectionPreserver.js b/dojox/grid/enhanced/plugins/_SelectionPreserver.js
index 732f85b..5e1e272 100644
--- a/dojox/grid/enhanced/plugins/_SelectionPreserver.js
+++ b/dojox/grid/enhanced/plugins/_SelectionPreserver.js
@@ -1,65 +1,54 @@
-dojo.provide("dojox.grid.enhanced.plugins._SelectionPreserver");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/connect",
+	'../../_SelectionPreserver'
+], function(declare, lang, connect, _SelectionPreserver){
 
-dojo.declare("dojox.grid.enhanced.plugins._SelectionPreserver", null, {
+return declare("dojox.grid.enhanced.plugins._SelectionPreserver", _SelectionPreserver, {
 	// summary:
 	//		Preserve selections across various user actions.
 	//
 	// description:
-	//		When this feature turned on, Grid will try to preserve selections across various user actions, e.g. sorting, filtering etc.
+	//		Extends dojox.grid._SelectionPreserver adding a bit more support to make selection persistence working well
+	//		with various EnhancedGrid features, e.g. filtering, nested sorting, pagination, select all etc.
+	//
 	//		Precondition - Identifier(id) is required for store, as id is used for differentiating row items.
-	//		Known issue - The preserved selections might be inaccurate if some unloaded rows are selected by range previously(e.g.SHIFT + click)
+	//		Known issue - The preserved selections might be inaccurate if some unloaded rows are previously selected by range(e.g.SHIFT + click)
 	//
 	// example:
 	// |	//To turn on this - set 'keepSelection' attribute to true
 	// |	<div dojoType="dojox.grid.EnhancedGrid" keepSelection = true .../>
 	
-	//_connects: Array
-	//		List of all connections.
-	_connects: [],
-	
 	constructor: function(selection){
-		this.selection = selection;
-		var grid = this.grid = selection.grid;
+		var grid = this.grid;
 		grid.onSelectedById = this.onSelectedById;
-		this.reset();
-
-		var oldClearData = grid._clearData;
-		var _this = this;
+		this._oldClearData = grid._clearData;
+		var self = this;
 		grid._clearData = function(){
-			_this._updateMapping(!grid._noInternalMapping);
-			_this._trustSelection = [];
-			oldClearData.apply(grid, arguments);
+			self._updateMapping(!grid._noInternalMapping);
+			self._trustSelection = [];
+			self._oldClearData.apply(grid, arguments);
 		};
-		this.connect(grid, '_setStore', 'reset');
-		this.connect(grid, '_addItem', '_reSelectById');
-		this.connect(selection, 'addToSelection', dojo.hitch(this, '_selectById', true));
-		this.connect(selection, 'deselect', dojo.hitch(this, '_selectById', false));
-		this.connect(selection, 'selectRange', dojo.hitch(this, '_updateMapping', true, true, false));
-		this.connect(selection, 'deselectRange', dojo.hitch(this, '_updateMapping', true, false, false));
-		this.connect(selection, 'deselectAll', dojo.hitch(this, '_updateMapping', true, false, true));
+		this._connects.push(
+			connect.connect(selection, 'selectRange', lang.hitch(this, '_updateMapping', true, true, false)),
+			connect.connect(selection, 'deselectRange', lang.hitch(this, '_updateMapping', true, false, false)),
+			connect.connect(selection, 'deselectAll', lang.hitch(this, '_updateMapping', true, false, true))
+		);
 	},
 	destroy: function(){
-		this.reset();
-		dojo.forEach(this._connects, dojo.disconnect);
-		delete this._connects;
-	},
-	connect: function(obj, event, method){
-		// summary:
-		//		Connects specified obj/event to specified method of this object.
-		var conn = dojo.connect(obj, event, this, method);
-		this._connects.push(conn);
-		return conn;
+		this.inherited(arguments);
+		this.grid._clearData = this._oldClearData;
 	},
 	reset: function(){
+		this.inherited(arguments);
 		this._idMap = [];
-		this._selectedById = {};
 		this._trustSelection = [];
 		this._defaultSelected = false;
 	},
 	_reSelectById: function(item, index){
 		// summary:
-		//		When some rows is fetched, determine whether it should be selected.
-		//		When this function is called, grid.selection.selected[] is not trustable.
+		//		Overwritten
 		var s = this.selection, g = this.grid;
 		if(item && g._hasIdentity){
 			var id = g.store.getIdentity(item);
@@ -76,17 +65,8 @@ dojo.declare("dojox.grid.enhanced.plugins._SelectionPreserver", null, {
 	},
 	_selectById: function(toSelect, inItemOrIndex){
 		// summary:
-		//		Record selected rows by ID.
-		if(this.selection.mode == 'none' || !this.grid._hasIdentity){ return; }
-		var item = inItemOrIndex;
-		if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
-			var entry = this.grid._by_idx[inItemOrIndex];
-			item = entry && entry.item;
-		}
-		if(item){
-			var id = this.grid.store.getIdentity(item);
-			this._selectedById[id] = !!toSelect;
-		}else{
+		//		Overwritten
+		if(!this.inherited(arguments)){
 			this._trustSelection[inItemOrIndex] = true;
 		}
 	},
@@ -94,7 +74,7 @@ dojo.declare("dojox.grid.enhanced.plugins._SelectionPreserver", null, {
 	
 	_updateMapping: function(trustSelection, isSelect, isForAll, from, to){
 		// summary:
-		//		This function trys to keep the selection info updated when range selection is performed.
+		//		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.
@@ -118,10 +98,11 @@ dojo.declare("dojox.grid.enhanced.plugins._SelectionPreserver", null, {
 		}
 		// When deselectAll, make sure every thing is deselected, even if it was selected but not loaded now.
 		// This occurs only when pagination's "All" is used.
-		if(isForAll && !g.usingPagination){
-			for(i = this._idMap.length; i >= 0; --i){
+		if(isForAll && (!g.usingPagination || g.selectionMode === 'single')){
+			for(i = this._idMap.length - 1; i >= 0; --i){
 				this._selectedById[this._idMap[i]] = isSelect;
 			}
 		}
 	}
 });
+});
diff --git a/dojox/grid/enhanced/plugins/_StoreLayer.js b/dojox/grid/enhanced/plugins/_StoreLayer.js
index 9d94b07..05b213f 100644
--- a/dojox/grid/enhanced/plugins/_StoreLayer.js
+++ b/dojox/grid/enhanced/plugins/_StoreLayer.js
@@ -1,4 +1,9 @@
-dojo.provide("dojox.grid.enhanced.plugins._StoreLayer");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"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
@@ -32,14 +37,14 @@ dojo.provide("dojox.grid.enhanced.plugins._StoreLayer");
 //		//now use the store as usual...
 //
 //		store.unwrap(); //remove all the layers, get the original store back.
-(function(){
-	var ns = dojox.grid.enhanced.plugins,
+
+	var ns = lang.getObject("grid.enhanced.plugins", true, dojox);
 	
-	getPrevTags = function(tags){
+	var getPrevTags = function(tags){
 		var tagList = ["reorder", "sizeChange", "normal", "presentation"];
 		var idx = tagList.length;
 		for(var i = tags.length - 1; i >= 0; --i){
-			var p = dojo.indexOf(tagList, tags[i]);
+			var p = array.indexOf(tagList, tags[i]);
 			if(p >= 0 && p <= idx){
 				idx = p;
 			}
@@ -144,14 +149,14 @@ dojo.provide("dojox.grid.enhanced.plugins._StoreLayer");
 		//		The wrapped store, for nested use only.
 		if(!store._layers){
 			store._layers = [];
-			store.layer = dojo.hitch(store, getLayer);
-			store.unwrap = dojo.hitch(store, unwrap);
-			store.forEachLayer = dojo.hitch(store, forEachLayer);
+			store.layer = lang.hitch(store, getLayer);
+			store.unwrap = lang.hitch(store, unwrap);
+			store.forEachLayer = lang.hitch(store, forEachLayer);
 		}
 		var prevTags = getPrevTags(layer.tags);
-		if(!dojo.some(store._layers, function(lyr, i){
-			if(dojo.some(lyr.tags, function(tag){
-				return dojo.indexOf(prevTags, tag) >= 0;
+		if(!array.some(store._layers, function(lyr, i){
+			if(array.some(lyr.tags, function(tag){
+				return array.indexOf(prevTags, tag) >= 0;
 			})){
 				return false;
 			}else{
@@ -167,7 +172,7 @@ dojo.provide("dojox.grid.enhanced.plugins._StoreLayer");
 		return store;	//Read-store
 	};
 
-	dojo.declare("dojox.grid.enhanced.plugins._StoreLayer", null, {
+	var _StoreLayer = declare("dojox.grid.enhanced.plugins._StoreLayer", null, {
 		// summary:
 		//		The most abstract class of store layers, provides basic utilities and some interfaces.
 		// tags:
@@ -214,7 +219,7 @@ dojo.provide("dojox.grid.enhanced.plugins._StoreLayer");
 			//		The store to be wrapped.
 			this._store = store;
 			this._funcName = funcName;
-			var fetchFunc = dojo.hitch(this, function(){
+			var fetchFunc = lang.hitch(this, function(){
 				return (this.enabled() ? this[layerFuncName || this.layerFuncName] : this.originFetch).apply(this, arguments);
 			});
 			if(nextLayer){
@@ -271,10 +276,10 @@ dojo.provide("dojox.grid.enhanced.plugins._StoreLayer");
 			return this.__name;
 		},
 		originFetch: function(){
-			return (dojo.hitch(this._store, this._originFetch)).apply(this, arguments);
+			return (lang.hitch(this._store, this._originFetch)).apply(this, arguments);
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins._ServerSideLayer", ns._StoreLayer, {
+	var _ServerSideLayer = declare("dojox.grid.enhanced.plugins._ServerSideLayer", _StoreLayer, {
 		// summary:
 		//		The most abstract class for all server side store layers.
 		// tags:
@@ -323,14 +328,14 @@ dojo.provide("dojox.grid.enhanced.plugins._StoreLayer");
 			//		Implementation of _StoreLayer._fetch
 			if(this.__cmds.cmdlayer){
 				//We're gonna send command to server before fetch.
-				dojo.xhrPost({
+				xhr.post({
 					url: this._url || this._store.url,
 					content: this.__cmds,
-					load: dojo.hitch(this, function(responce){
+					load: lang.hitch(this, function(responce){
 						this.onCommandLoad(responce, userRequest);
 						this.originFetch(userRequest);
 					}),
-					error: dojo.hitch(this, this.onCommandError)
+					error: lang.hitch(this, this.onCommandError)
 				});
 			}else{
 				//The user only wants to modify the request object.
@@ -380,4 +385,10 @@ dojo.provide("dojox.grid.enhanced.plugins._StoreLayer");
 			throw error;
 		}
 	});
-})();
+
+	return {
+		_StoreLayer: _StoreLayer,
+		_ServerSideLayer: _ServerSideLayer,
+		wrap: ns.wrap
+	};
+});
diff --git a/dojox/grid/enhanced/plugins/exporter/CSVWriter.js b/dojox/grid/enhanced/plugins/exporter/CSVWriter.js
index b26b48c..4032466 100644
--- a/dojox/grid/enhanced/plugins/exporter/CSVWriter.js
+++ b/dojox/grid/enhanced/plugins/exporter/CSVWriter.js
@@ -1,16 +1,19 @@
-dojo.provide("dojox.grid.enhanced.plugins.exporter.CSVWriter");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"./_ExportWriter",
+	"../Exporter"
+], function(declare, array, _ExportWriter, Exporter){
 
-dojo.require("dojox.grid.enhanced.plugins.exporter._ExportWriter");
+Exporter.registerWriter("csv", "dojox.grid.enhanced.plugins.exporter.CSVWriter");
 
-dojox.grid.enhanced.plugins.Exporter.registerWriter("csv",
-	"dojox.grid.enhanced.plugins.exporter.CSVWriter");
-
-dojo.declare("dojox.grid.enhanced.plugins.exporter.CSVWriter",
-	dojox.grid.enhanced.plugins.exporter._ExportWriter, {
+return declare("dojox.grid.enhanced.plugins.exporter.CSVWriter", _ExportWriter, {
 	// summary:
 	//		Export grid to CSV format.
 	_separator: ',',
+
 	_newline: "\r\n",
+
 	constructor: function(/* object? */writerArgs){
 		// summary:
 		//		CSV default separator is ','.
@@ -24,6 +27,7 @@ dojo.declare("dojox.grid.enhanced.plugins.exporter.CSVWriter",
 		this._headers = [];
 		this._dataRows = [];
 	},
+
 	_formatCSVCell: function(/* string */cellValue){
 		// summary:
 		//		Format cell value to follow CSV standard.
@@ -43,14 +47,15 @@ dojo.declare("dojox.grid.enhanced.plugins.exporter.CSVWriter",
 		}
 		return result;	//String
 	},
+
 	beforeContentRow: function(/* object */arg_obj){
 		// summary:
 		//		Overrided from _ExportWriter
 		var row = [],
 			func = this._formatCSVCell;
-		dojo.forEach(arg_obj.grid.layout.cells, function(cell){
+		array.forEach(arg_obj.grid.layout.cells, function(cell){
 			//We are not interested in indirect selectors and row indexes.
-			if(!cell.hidden && dojo.indexOf(arg_obj.spCols,cell.index) < 0){
+			if(!cell.hidden && array.indexOf(arg_obj.spCols,cell.index) < 0){
 				//We only need data here, not html
 				row.push(func(this._getExportDataForCell(arg_obj.rowIndex, arg_obj.row, cell, arg_obj.grid)));
 			}
@@ -59,14 +64,16 @@ dojo.declare("dojox.grid.enhanced.plugins.exporter.CSVWriter",
 		//We do not need to go into the row.
 		return false;	//Boolean
 	},
+
 	handleCell: function(/* object */arg_obj){
 		// summary:
 		//		Overrided from _ExportWriter
 		var cell = arg_obj.cell;
-		if(arg_obj.isHeader && !cell.hidden && dojo.indexOf(arg_obj.spCols,cell.index) < 0){
+		if(arg_obj.isHeader && !cell.hidden && array.indexOf(arg_obj.spCols,cell.index) < 0){
 			this._headers.push(cell.name || cell.field);
 		}
 	},
+
 	toString: function(){
 		// summary:
 		//		Overrided from _ExportWriter
@@ -77,3 +84,4 @@ dojo.declare("dojox.grid.enhanced.plugins.exporter.CSVWriter",
 		return result + this._newline + this._dataRows.join(this._newline);	//String
 	}
 });
+});
diff --git a/dojox/grid/enhanced/plugins/exporter/TableWriter.js b/dojox/grid/enhanced/plugins/exporter/TableWriter.js
index 7fc10d0..8a07ef8 100644
--- a/dojox/grid/enhanced/plugins/exporter/TableWriter.js
+++ b/dojox/grid/enhanced/plugins/exporter/TableWriter.js
@@ -1,12 +1,14 @@
-dojo.provide("dojox.grid.enhanced.plugins.exporter.TableWriter");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/dom-geometry",
+	"./_ExportWriter",
+	"../Exporter"
+], function(declare, array, domGeometry, _ExportWriter, Exporter){
 
-dojo.require("dojox.grid.enhanced.plugins.exporter._ExportWriter");
-
-dojox.grid.enhanced.plugins.Exporter.registerWriter("table",
-	"dojox.grid.enhanced.plugins.exporter.TableWriter");
+Exporter.registerWriter("table", "dojox.grid.enhanced.plugins.exporter.TableWriter");
 	
-dojo.declare("dojox.grid.enhanced.plugins.exporter.TableWriter",
-	dojox.grid.enhanced.plugins.exporter._ExportWriter, {
+return declare("dojox.grid.enhanced.plugins.exporter.TableWriter", _ExportWriter, {
 	// summary:
 	//		Export grid to HTML table format. Primarily used by Printer plugin.
 	constructor: function(/* object? */writerArgs){
@@ -19,6 +21,7 @@ dojo.declare("dojox.grid.enhanced.plugins.exporter.TableWriter",
 		this._viewTables = [];
 		this._tableAttrs = writerArgs || {};
 	},
+
 	_getTableAttrs: function(/* string */tagName){
 		// summary:
 		//		Get html attribute string for the given kind of tag.
@@ -35,87 +38,95 @@ dojo.declare("dojox.grid.enhanced.plugins.exporter.TableWriter",
 		}
 		return attrs;	//String
 	},
+
 	_getRowClass: function(/* object */arg_obj){
 		// summary:
 		//		Get CSS class string for a row
 		// tags:
 		//		private
-		return arg_obj.isHeader ? " grid_header"//String
-				: [" grid_row grid_row_", arg_obj.rowIdx + 1,
-				arg_obj.rowIdx % 2 ? " grid_even_row" : " grid_odd_row"].join('');
+		return arg_obj.isHeader ? " grid_header" : [//String
+			" grid_row grid_row_",
+			arg_obj.rowIdx + 1,
+			arg_obj.rowIdx % 2 ? " grid_even_row" : " grid_odd_row"
+		].join('');
 	},
+
 	_getColumnClass: function(/* object */arg_obj){
 		// summary:
 		//		Get CSS class string for a column
 		// tags:
 		//		private
 		var col_idx = arg_obj.cell.index + arg_obj.colOffset + 1;
-		return [" grid_column_", col_idx,//String
+		return [" grid_column grid_column_", col_idx,//String
 				col_idx % 2 ? " grid_odd_column" : " grid_even_column"].join('');
 	},
+
 	beforeView: function(/* object */arg_obj){
 		// summary:
 		//		Overrided from _ExportWriter
 		var viewIdx = arg_obj.viewIdx,
 			table = this._viewTables[viewIdx],
-			tagName, height,
-			width = dojo.marginBox(arg_obj.view.contentNode).w;
+			height, width = domGeometry.getMarginBox(arg_obj.view.contentNode).w;
 		if(!table){
 			var left = 0;
 			for(var i = 0; i < viewIdx; ++i){
 				left += this._viewTables[i]._width;
 			}
-			table = this._viewTables[viewIdx] = ['<table class="grid_view" style="position: absolute; top: 0; left:', left,
-				'px;"', this._getTableAttrs("table"), '>'];
+			table = this._viewTables[viewIdx] = ['<div class="grid_view" style="position: absolute; top: 0; ',
+				domGeometry.isBodyLtr() ? 'left' : 'right', ':', left,
+				'px;">'];
 		}
 		table._width = width;
 		if(arg_obj.isHeader){
-			tagName = 'thead';
-			height = dojo.contentBox(arg_obj.view.headerContentNode).h;
+			height = domGeometry.getContentBox(arg_obj.view.headerContentNode).h;
 		}else{
-			tagName = 'tbody';
 			var rowNode = arg_obj.grid.getRowNode(arg_obj.rowIdx);
 			if(rowNode){
-				height = dojo.contentBox(rowNode).h;
+				height = domGeometry.getContentBox(rowNode).h;
 			}else{
 				//This row has not been loaded from store, so we should estimate it's height.
 				height = arg_obj.grid.scroller.averageRowHeight;
 			}
 		}
-		table.push('<',tagName,
-					' style="height:', height, 'px; width:', width, 'px;"',
-					' class="', this._getRowClass(arg_obj), '"',
-					this._getTableAttrs(tagName), '>');
+		table.push('<table class="', this._getRowClass(arg_obj), 
+			'" style="table-layout:fixed; height:', height, 'px; width:', width, 'px;" ', 
+			'border="0" cellspacing="0" cellpadding="0" ',
+			this._getTableAttrs("table"),
+			'><tbody ', this._getTableAttrs('tbody'), '>');
 		return true;	//Boolean
 	},
+
 	afterView: function(/* object */arg_obj){
 		// summary:
 		//		Overrided from _ExportWriter
-		this._viewTables[arg_obj.viewIdx].push(arg_obj.isHeader ? '</thead>' : '</tbody>');
+		this._viewTables[arg_obj.viewIdx].push('</tbody></table>');
 	},
+
 	beforeSubrow: function(/* object */arg_obj){
 		// summary:
 		//		Overrided from _ExportWriter
 		this._viewTables[arg_obj.viewIdx].push('<tr', this._getTableAttrs('tr'), '>');
 		return true;	//Boolean
 	},
+
 	afterSubrow: function(/* object */arg_obj){
 		// summary:
 		//		Overrided from _ExportWriter
 		this._viewTables[arg_obj.viewIdx].push('</tr>');
 	},
+
 	handleCell: function(/* object */arg_obj){
 		// summary:
 		//		Overrided from _ExportWriter
 		var cell = arg_obj.cell;
-		if(cell.hidden || dojo.indexOf(arg_obj.spCols, cell.index) >= 0){
+		if(cell.hidden || array.indexOf(arg_obj.spCols, cell.index) >= 0){
 			//We are not interested in indirect selectors and row indexes.
 			return;
 		}
 		var cellTagName = arg_obj.isHeader ? 'th' : 'td',
 			attrs = [cell.colSpan ? ' colspan="' + cell.colSpan + '"' : '',
 					cell.rowSpan ? ' rowspan="' + cell.rowSpan + '"' : '',
-					' style="width: ', dojo.contentBox(cell.getHeaderNode()).w, 'px;"',
+					' style="width: ', domGeometry.getContentBox(cell.getHeaderNode()).w, 'px;"',
 					this._getTableAttrs(cellTagName),
 					' class="', this._getColumnClass(arg_obj), '"'].join(''),
 			table = this._viewTables[arg_obj.viewIdx];
@@ -127,19 +138,22 @@ dojo.declare("dojox.grid.enhanced.plugins.exporter.TableWriter",
 		}
 		table.push('</', cellTagName, '>');
 	},
+
 	afterContent: function(){
 		// summary:
 		//		Overrided from _ExportWriter
-		dojo.forEach(this._viewTables, function(table){
-			table.push('</table>');
+		array.forEach(this._viewTables, function(table){
+			table.push('</div>');
 		});
 	},
+
 	toString: function(){
 		// summary:
 		//		Overrided from _ExportWriter
-		var viewsHTML = dojo.map(this._viewTables, function(table){	//String
+		var viewsHTML = array.map(this._viewTables, function(table){	//String
 			return table.join('');
 		}).join('');
 		return ['<div style="position: relative;">', viewsHTML, '</div>'].join('');
 	}
 });
+});
diff --git a/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js b/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js
index 1c0feee..319674e 100644
--- a/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js
+++ b/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js
@@ -1,10 +1,10 @@
-dojo.provide("dojox.grid.enhanced.plugins.exporter._ExportWriter");
-
+define([
+	"dojo/_base/declare"
+], function(declare){
 //require Exporter here, so the implementations only need to require this file,
 //and the users only need to require the implementation file.
-dojo.require("dojox.grid.enhanced.plugins.Exporter");
 
-dojo.declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, {
+return declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, {
 	// summary:
 	//		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,
@@ -265,3 +265,4 @@ dojo.declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, {
 		return '';	//String
 	}
 });
+});
diff --git a/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js b/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js
index 10cad70..0eadec9 100644
--- a/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js
+++ b/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js
@@ -1,33 +1,45 @@
-dojo.provide("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm");
+define([
+	"dojo/_base/declare",
+	"dojo/cache",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dijit/_WidgetsInTemplateMixin"
+], function(declare, cache, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin){
 
-dojo.require("dijit.form.Button");
-
-dojo.declare("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm",[dijit._Widget,dijit._Templated],{
+return declare("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm",
+	[_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
 	// summary:
 	//		The UI for user to confirm the operation of clearing filter.
-	templateString: dojo.cache("dojox.grid", "enhanced/templates/ClearFilterConfirmPane.html"),
+	templateString: cache("dojox.grid", "enhanced/templates/ClearFilterConfirmPane.html"),
+
 	widgetsInTemplate: true,
+
 	plugin: null,
+
 	postMixInProperties: function(){
 		var nls = this.plugin.nls;
 		this._clearBtnLabel = nls["clearButton"];
 		this._cancelBtnLabel = nls["cancelButton"];
 		this._clearFilterMsg = nls["clearFilterMsg"];
 	},
+
 	postCreate: function(){
 		this.inherited(arguments);
-		dijit.setWaiState(this.cancelBtn.domNode, "label", this.plugin.nls["waiCancelButton"]);
-		dijit.setWaiState(this.clearBtn.domNode, "label", this.plugin.nls["waiClearButton"]);
+		this.cancelBtn.domNode.setAttribute("aria-label", this.plugin.nls["waiCancelButton"]);
+		this.clearBtn.domNode.setAttribute("aria-label", this.plugin.nls["waiClearButton"]);
 	},
+
 	uninitialize: function(){
 		this.plugin = null;
 	},
+
 	_onCancel: function(){
 		this.plugin.clearFilterDialog.hide();
 	},
+
 	_onClear: function(){
 		this.plugin.clearFilterDialog.hide();
 		this.plugin.filterDefDialog.clearFilter(this.plugin.filterDefDialog._clearWithoutRefresh);
 	}
 });
-
+});
diff --git a/dojox/grid/enhanced/plugins/filter/FilterBar.js b/dojox/grid/enhanced/plugins/filter/FilterBar.js
index 44a7c42..2987321 100644
--- a/dojox/grid/enhanced/plugins/filter/FilterBar.js
+++ b/dojox/grid/enhanced/plugins/filter/FilterBar.js
@@ -1,31 +1,48 @@
-dojo.provide("dojox.grid.enhanced.plugins.filter.FilterBar");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/lang",
+	"dojo/_base/sniff",
+	"dojo/_base/event",
+	"dojo/_base/html",
+	"dojo/_base/window",
+	"dojo/cache",
+	"dojo/query",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dijit/_WidgetsInTemplateMixin",
+	"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){
 
-dojo.require("dijit.form.Button");
-dojo.require("dojo.string");
-dojo.require("dojo.fx");
-
-(function(){
 var _focusClass = "dojoxGridFBarHover",
 	_filteredClass = "dojoxGridFBarFiltered",
 	_stopEvent = function(evt){
 		try{
 			if(evt && evt.preventDefault){
-				dojo.stopEvent(evt);
+				event.stop(evt);
 			}
 		}catch(e){}
 	};
 	
-dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, dijit._Templated],{
+return declare("dojox.grid.enhanced.plugins.filter.FilterBar", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin],{
 	// summary:
 	//		The filter bar UI.
-	templateString: dojo.cache("dojox.grid","enhanced/templates/FilterBar.html"),
+	templateString: cache("dojox.grid","enhanced/templates/FilterBar.html"),
+
 	widgetsInTemplate: true,
 	
 	_timeout_statusTooltip: 300,
+
 	_handle_statusTooltip: null,
+
 	_curColIdx: -1,
 	
 	plugin: null,
+
 	postMixInProperties: function(){
 		var plugin = this.plugin;
 		var nls = plugin.nls;
@@ -33,7 +50,7 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, diji
 		this._filterBarClearBtnLabel = nls["filterBarClearButton"];
 		this._closeFilterBarBtnLabel = nls["closeFilterBarBtn"];
 		var itemsName = plugin.args.itemsName || nls["defaultItemsName"];
-		this._noFilterMsg = dojo.string.substitute(nls["filterBarMsgNoFilterTemplate"], ["", itemsName]);
+		this._noFilterMsg = string.substitute(nls["filterBarMsgNoFilterTemplate"], ["", itemsName]);
 		
 		var t = this.plugin.args.statusTipTimeout;
 		if(typeof t == 'number'){
@@ -41,18 +58,18 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, diji
 		}
 		
 		var g = plugin.grid;
-		g.showFilterBar = dojo.hitch(this, "showFilterBar");
-		g.toggleFilterBar = dojo.hitch(this, "toggleFilterBar");
-		g.isFilterBarShown = dojo.hitch(this, "isFilterBarShown");
+		g.showFilterBar = lang.hitch(this, "showFilterBar");
+		g.toggleFilterBar = lang.hitch(this, "toggleFilterBar");
+		g.isFilterBarShown = lang.hitch(this, "isFilterBarShown");
 	},
 	postCreate: function(){
 		this.inherited(arguments);
 		if(!this.plugin.args.closeFilterbarButton){
-			dojo.style(this.closeFilterBarButton.domNode, "display", "none");
+			html.style(this.closeFilterBarButton.domNode, "display", "none");
 		}
 		var _this = this,
 			g = this.plugin.grid,
-			old_func = this.oldGetHeaderHeight = dojo.hitch(g,g._getHeaderHeight);
+			old_func = this.oldGetHeaderHeight = lang.hitch(g,g._getHeaderHeight);
 		
 		this.placeAt(g.viewsHeaderNode, "after");
 		this.connect(this.plugin.filterDefDialog, "showDialog", "_onShowFilterDefDialog");
@@ -60,7 +77,7 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, diji
 		this.connect(g.layer("filter"), "onFiltered", this._onFiltered);
 		
 		this.defineFilterButton.domNode.title = this.plugin.nls["filterBarDefButton"];
-		if(dojo.hasClass(dojo.body(), "dijit_a11y")){
+		if(html.hasClass(win.body(), "dijit_a11y")){
 			this.defineFilterButton.set("label", this.plugin.nls["a11yFilterBarDefButton"]);
 		}
 		this.connect(this.defineFilterButton.domNode, "click", _stopEvent);
@@ -72,13 +89,13 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, diji
 		
 		//Hack the header height to include filter bar height;
 		g._getHeaderHeight = function(){
-			return old_func() + dojo.marginBox(_this.domNode).h;
+			return old_func() + html.marginBox(_this.domNode).h;
 		};
 		//Define an area to make focusManager handle all the navigation stuff
 		g.focus.addArea({
 			name: "filterbar",
-			onFocus: dojo.hitch(this, this._onFocusFilterBar, false),
-			onBlur: dojo.hitch(this, this._onBlurFilterBar)
+			onFocus: lang.hitch(this, this._onFocusFilterBar, false),
+			onBlur: lang.hitch(this, this._onBlurFilterBar)
 		});
 		g.focus.placeArea("filterbar","after","header");
 	},
@@ -89,7 +106,7 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, diji
 		this.plugin = null;
 	},
 	isFilterBarShown: function(){
-		return dojo.style(this.domNode, "display") != "none";
+		return html.style(this.domNode, "display") != "none";
 	},
 	showFilterBar: function(toShow, useAnim, animArgs){
 		var g = this.plugin.grid;
@@ -97,7 +114,7 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, diji
 			if(Boolean(toShow) == this.isFilterBarShown()){ return; }
 			animArgs = animArgs || {};
 			var anims = [], defaultDuration = 500;
-			anims.push(dojo.fx[toShow ? "wipeIn" : "wipeOut"](dojo.mixin({
+			anims.push(fx[toShow ? "wipeIn" : "wipeOut"](lang.mixin({
 				"node": this.domNode,
 				"duration": defaultDuration
 			}, animArgs)));
@@ -106,9 +123,9 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, diji
 				"duration": defaultDuration,
 				"properties": {
 					"height": {
-						"end": dojo.hitch(this, function(){
+						"end": lang.hitch(this, function(){
 							var barHeight = this.domNode.scrollHeight;
-							if(dojo.isFF){
+							if(has('ff')){
 								barHeight -= 2;
 							}
 							return toShow ? (curHeight - barHeight) : (curHeight + barHeight);
@@ -116,19 +133,19 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, diji
 					}
 				}
 			};
-			dojo.forEach(g.views.views, function(view){
-				anims.push(dojo.animateProperty(dojo.mixin({
+			array.forEach(g.views.views, function(view){
+				anims.push(baseFx.animateProperty(lang.mixin({
 					"node": view.domNode
-				}, prop, animArgs)), dojo.animateProperty(dojo.mixin({
+				}, prop, animArgs)), baseFx.animateProperty(lang.mixin({
 					"node": view.scrollboxNode
 				}, prop, animArgs)));
 			});
-			anims.push(dojo.animateProperty(dojo.mixin({
+			anims.push(baseFx.animateProperty(lang.mixin({
 				"node": g.viewsNode
 			}, prop, animArgs)));
-			dojo.fx.combine(anims).play();
+			fx.combine(anims).play();
 		}else{
-			dojo.style(this.domNode, "display", toShow ? "" : "none");
+			html.style(this.domNode, "display", toShow ? "" : "none");
 			g.update();
 		}
 	},
@@ -136,10 +153,10 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, diji
 		this.showFilterBar(!this.isFilterBarShown(), useAnim, animArgs);
 	},
 	getColumnIdx: function(/* int */coordX){
-		var headers = dojo.query("[role='columnheader']", this.plugin.grid.viewsHeaderNode);
+		var headers = query("[role='columnheader']", this.plugin.grid.viewsHeaderNode);
 		var idx = -1;
 		for(var i = headers.length - 1; i >= 0; --i){
-			var coord = dojo.coords(headers[i]);
+			var coord = html.position(headers[i]);
 			if(coordX >= coord.x && coordX < coord.x + coord.w){
 				idx = i;
 				break;
@@ -152,15 +169,15 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, diji
 		}
 	},
 	toggleClearFilterBtn: function(toHide){
-		dojo.style(this.clearFilterButton.domNode, "display", toHide ? "none" : "");
+		html.style(this.clearFilterButton.domNode, "display", toHide ? "none" : "");
 	},
 	_closeFilterBar: function(e){
 		_stopEvent(e);
 		var rulesCnt = this.plugin.filterDefDialog.getCriteria();
 		if(rulesCnt){
-			var handle = dojo.connect(this.plugin.filterDefDialog, "clearFilter", this, function(){
+			var handle = connect.connect(this.plugin.filterDefDialog, "clearFilter", this, function(){
 				this.showFilterBar(false, true);
-				dojo.disconnect(handle);
+				connect.disconnect(handle);
 			});
 			this._clearFilterDefDialog(e);
 		}else{
@@ -200,7 +217,7 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, diji
 		this._defPaneIsShown = false;
 		//Do not remember what column are we on, so clicking the btn will show 'any column'
 		this._curColIdx = -1;
-		dijit.focus(this.defineFilterButton.domNode);
+		dijitFocus.focus(this.defineFilterButton.domNode);
 	},
 	_onClickFilterBar: function(/* event */e){
 		_stopEvent(e);
@@ -240,10 +257,10 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, diji
 			return false;
 		}
 		this._isFocused = true;
-		dojo.addClass(this.domNode,_focusClass);
+		html.addClass(this.domNode,_focusClass);
 		if(!highlightOnly){
-			var hasFilter = dojo.style(this.clearFilterButton.domNode, "display") !== "none";
-			var hasCloseButton = dojo.style(this.closeFilterBarButton.domNode, "display") !== "none";
+			var hasFilter = html.style(this.clearFilterButton.domNode, "display") !== "none";
+			var hasCloseButton = html.style(this.closeFilterBarButton.domNode, "display") !== "none";
 			if(typeof this._focusPos == "undefined"){
 				if(step > 0){
 					this._focusPos = 0;
@@ -259,11 +276,11 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, diji
 				}
 			}
 			if(this._focusPos === 0){
-				dijit.focus(this.defineFilterButton.focusNode);
+				dijitFocus.focus(this.defineFilterButton.focusNode);
 			}else if(this._focusPos === 1 && hasFilter){
-				dijit.focus(this.clearFilterButton.focusNode);
+				dijitFocus.focus(this.clearFilterButton.focusNode);
 			}else{
-				dijit.focus(this.closeFilterBarButton.focusNode);
+				dijitFocus.focus(this.closeFilterBarButton.focusNode);
 			}
 		}
 		_stopEvent(evt);
@@ -272,17 +289,17 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, diji
 	_onBlurFilterBar: function(evt, step){
 		if(this._isFocused){
 			this._isFocused = false;
-			dojo.removeClass(this.domNode,_focusClass);
+			html.removeClass(this.domNode,_focusClass);
 			this._clearStatusTipTimeout();
 			this._clearHeaderHighlight();
 		}
 		var toBlur = true;
 		if(step){
 			var buttonCount = 3;
-			if(dojo.style(this.closeFilterBarButton.domNode, "display") === "none"){
+			if(html.style(this.closeFilterBarButton.domNode, "display") === "none"){
 				--buttonCount;
 			}
-			if(dojo.style(this.clearFilterButton.domNode, "display") === "none"){
+			if(html.style(this.clearFilterButton.domNode, "display") === "none"){
 				--buttonCount;
 			}
 			if(buttonCount == 1){
@@ -307,27 +324,27 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, diji
 			msg = "", g = p.grid,
 			filterLayer = g.layer("filter");
 		if(filterLayer.filterDef()){
-			msg = dojo.string.substitute(p.nls["filterBarMsgHasFilterTemplate"], [filteredSize, originSize, itemsName]);
-			dojo.addClass(this.domNode, _filteredClass);
+			msg = string.substitute(p.nls["filterBarMsgHasFilterTemplate"], [filteredSize, originSize, itemsName]);
+			html.addClass(this.domNode, _filteredClass);
 		}else{
-			msg = dojo.string.substitute(p.nls["filterBarMsgNoFilterTemplate"], [originSize, itemsName]);
-			dojo.removeClass(this.domNode, _filteredClass);
+			msg = string.substitute(p.nls["filterBarMsgNoFilterTemplate"], [originSize, itemsName]);
+			html.removeClass(this.domNode, _filteredClass);
 		}
 		this.statusBarNode.innerHTML = msg;
 		this._focusPos = 0;
 	},
 	_initAriaInfo: function(){
-		dijit.setWaiState(this.defineFilterButton.domNode, "label", this.plugin.nls["waiFilterBarDefButton"]);
-		dijit.setWaiState(this.clearFilterButton.domNode,"label", this.plugin.nls["waiFilterBarClearButton"]);
+		this.defineFilterButton.domNode.setAttribute("aria-label", this.plugin.nls["waiFilterBarDefButton"]);
+		this.clearFilterButton.domNode.setAttribute("aria-label", this.plugin.nls["waiFilterBarClearButton"]);
 	},
 	_isInColumn: function(/* int */mousePos_x, /* domNode */headerNode, /* int */colIndex){
-		var coord = dojo.coords(headerNode);
+		var coord = html.position(headerNode);
 		return mousePos_x >= coord.x && mousePos_x < coord.x + coord.w;
 	},
 	_setStatusTipTimeout: function(){
 		this._clearStatusTipTimeout();
 		if(!this._defPaneIsShown){
-			this._handle_statusTooltip = setTimeout(dojo.hitch(this,this._showStatusTooltip),this._timeout_statusTooltip);
+			this._handle_statusTooltip = setTimeout(lang.hitch(this,this._showStatusTooltip),this._timeout_statusTooltip);
 		}
 	},
 	_clearStatusTipTimeout: function(){
@@ -343,11 +360,11 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, diji
 			var g = this.plugin.grid,
 			cell = g.getCell(this._previousHeaderIdx);
 			if(cell){
-				dojo.removeClass(cell.getHeaderNode(), "dojoxGridCellOver");
+				html.removeClass(cell.getHeaderNode(), "dojoxGridCellOver");
 			}
 			cell = g.getCell(colIdx);
 			if(cell){
-				dojo.addClass(cell.getHeaderNode(), "dojoxGridCellOver");
+				html.addClass(cell.getHeaderNode(), "dojoxGridCellOver");
 			}
 			this._previousHeaderIdx = colIdx;
 		}
@@ -365,5 +382,4 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, diji
 		}
 	}
 });
-})();
-
+});
diff --git a/dojox/grid/enhanced/plugins/filter/FilterBuilder.js b/dojox/grid/enhanced/plugins/filter/FilterBuilder.js
index f4f166c..b922bd8 100644
--- a/dojox/grid/enhanced/plugins/filter/FilterBuilder.js
+++ b/dojox/grid/enhanced/plugins/filter/FilterBuilder.js
@@ -1,26 +1,28 @@
-dojo.provide("dojox.grid.enhanced.plugins.filter.FilterBuilder");
-dojo.require("dojox.grid.enhanced.plugins.filter._FilterExpr");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"./_FilterExpr"
+], function(declare, array, lang, exprs){
 
-(function(){
-var fns = dojox.grid.enhanced.plugins.filter,
-	bdr = function(opCls){
-		return dojo.partial(function(cls,operands){
-			return new fns[cls](operands);
+var bdr = function(opCls){
+		return lang.partial(function(cls,operands){
+			return new exprs[cls](operands);
 		},opCls);
 	},
 	bdr_not = function(opCls){
-		return dojo.partial(function(cls,operands){
-			return new fns.LogicNOT(new fns[cls](operands));
+		return lang.partial(function(cls,operands){
+			return new exprs.LogicNOT(new exprs[cls](operands));
 		},opCls);
 	};
-dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBuilder", null, {
+return declare("dojox.grid.enhanced.plugins.filter.FilterBuilder", null, {
 	// summary:
 	//		Create filter expression from a JSON object.
 	buildExpression: function(def){
 		if("op" in def){
-			return this.supportedOps[def.op.toLowerCase()](dojo.map(def.data, this.buildExpression, this));
+			return this.supportedOps[def.op.toLowerCase()](array.map(def.data, this.buildExpression, this));
 		}else{
-			var args = dojo.mixin(this.defaultArgs[def.datatype], def.args || {});
+			var args = lang.mixin(this.defaultArgs[def.datatype], def.args || {});
 			return new this.supportedTypes[def.datatype](def.data, def.isColumn, args);
 		}
 	},
@@ -41,20 +43,20 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBuilder", null, {
 		"notendswith": bdr_not("EndsWith"),
 		"isempty": bdr("IsEmpty"),
 		"range": function(operands){
-			return new fns.LogicALL(
-				new fns.LargerThanOrEqualTo(operands.slice(0,2)),
-				new fns.LessThanOrEqualTo(operands[0], operands[2])
+			return new exprs.LogicALL(
+				new exprs.LargerThanOrEqualTo(operands.slice(0,2)),
+				new exprs.LessThanOrEqualTo(operands[0], operands[2])
 			);
 		},
 		"logicany": bdr("LogicANY"),
 		"logicall": bdr("LogicALL")
 	},
 	supportedTypes: {
-		"number": fns.NumberExpr,
-		"string": fns.StringExpr,
-		"boolean": fns.BooleanExpr,
-		"date": fns.DateExpr,
-		"time": fns.TimeExpr
+		"number": exprs.NumberExpr,
+		"string": exprs.StringExpr,
+		"boolean": exprs.BooleanExpr,
+		"date": exprs.DateExpr,
+		"time": exprs.TimeExpr
 	},
 	defaultArgs: {
 		"boolean": {
@@ -62,7 +64,7 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBuilder", null, {
 			"convert": function(dataValue, args){
 				var falseValue = args.falseValue;
 				var trueValue = args.trueValue;
-				if(dojo.isString(dataValue)){
+				if(lang.isString(dataValue)){
 					if(trueValue && dataValue.toLowerCase() == trueValue){
 						return true;
 					}
@@ -75,4 +77,4 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBuilder", null, {
 		}
 	}
 });
-})();
+});
diff --git a/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js b/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js
index e88657f..35da5f2 100644
--- a/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js
+++ b/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js
@@ -1,29 +1,42 @@
-dojo.provide("dojox.grid.enhanced.plugins.filter.FilterDefDialog");
-
-dojo.require("dijit.dijit");
-dojo.require("dijit.Tooltip");
-dojo.require("dojox.grid.enhanced.plugins.Dialog");
-dojo.require("dijit.form.ComboBox");
-dojo.require("dijit.form.Select");
-dojo.require("dijit.form.TextBox");
-dojo.require("dijit.form.CheckBox");
-dojo.require("dijit.form.NumberTextBox");
-dojo.require("dijit.form.DateTextBox");
-dojo.require("dijit.form.TimeTextBox");
-dojo.require("dijit.form.Button");
-dojo.require("dijit.layout.AccordionContainer");
-dojo.require("dijit.layout.ContentPane");
-dojo.require("dojo.date.locale");
-dojo.require("dojo.string");
-dojo.require("dojox.grid.enhanced.plugins.filter.FilterBuilder");
-dojo.require("dojox.grid.cells.dijit");
-dojo.require("dojox.html.ellipsis");
-dojo.require("dojox.html.metrics");
-dojo.require("dojo.window");
-
-(function(){
-var fns = dojox.grid.enhanced.plugins.filter,
-	_tabIdxes = {
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/lang",
+	"dojo/_base/event",
+	"dojo/_base/html",
+	"dojo/_base/sniff",
+	"dojo/cache",
+	"dojo/keys",
+	"dojo/string",
+	"dojo/window",
+	"dojo/date/locale",		
+	"./FilterBuilder",
+	"../Dialog",
+	"dijit/form/ComboBox",
+	"dijit/form/TextBox",
+	"dijit/form/NumberTextBox",
+	"dijit/form/DateTextBox",
+	"dijit/form/TimeTextBox",
+	"dijit/form/Button",
+	"dijit/layout/AccordionContainer",
+	"dijit/layout/ContentPane",
+	"dijit/_Widget", 
+	"dijit/_TemplatedMixin", 
+	"dijit/_WidgetsInTemplateMixin",
+	"dijit/focus",
+	"dojox/html/metrics",
+	"dijit/a11y",
+	"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, 
+	FilterBuilder, Dialog, ComboBox, TextBox, NumberTextBox, DateTextBox, TimeTextBox, Button, 
+	AccordionContainer, ContentPane, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, dijitFocus, metrics, dijitA11y){
+		
+var _tabIdxes = {
 		// summary:
 		//		Define tabindexes for elements in the filter definition dialog
 		relSelect: 60,
@@ -37,615 +50,222 @@ var fns = dojox.grid.enhanced.plugins.filter,
 		clearBtn: 40,
 		cancelBtn: 50
 	};
-dojo.declare("dojox.grid.enhanced.plugins.filter.FilterDefDialog", null, {
-	// summary:
-	//		Create the filter definition UI.
-	curColIdx: -1,
-	_relOpCls: "logicall",
-	_savedCriterias: null,
-	plugin: null,
-	constructor: function(args){
-		var plugin = this.plugin = args.plugin;
-		this.builder = new fns.FilterBuilder();
-		this._setupData();
-		this._cboxes = [];
-		this.defaultType = plugin.args.defaultType || "string";
-		
-		(this.filterDefPane = new fns.FilterDefPane({
-			"dlg": this
-		})).startup();
-		(this._defPane = new dojox.grid.enhanced.plugins.Dialog({
-			"refNode": this.plugin.grid.domNode,
-			"title": plugin.nls.filterDefDialogTitle,
-			"class": "dojoxGridFDTitlePane",
-			"iconClass": "dojoxGridFDPaneIcon",
-			"content": this.filterDefPane
-		})).startup();
-		
-		this._defPane.connect(plugin.grid.layer('filter'), "filterDef", dojo.hitch(this, "_onSetFilter"));
-		plugin.grid.setFilter = dojo.hitch(this, "setFilter");
-		plugin.grid.getFilter = dojo.hitch(this, "getFilter");
-		plugin.grid.getFilterRelation = dojo.hitch(this, function(){
-			return this._relOpCls;
+var FilterAccordionContainer = declare("dojox.grid.enhanced.plugins.filter.AccordionContainer", AccordionContainer, {
+	nls: null,
+	addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){
+		var pane = arguments[0] = child._pane = new ContentPane({
+			content: child
 		});
-		
-		plugin.connect(plugin.grid.layout, "moveColumn", dojo.hitch(this, "onMoveColumn"));
+		this.inherited(arguments);
+		this._modifyChild(pane);
 	},
-	onMoveColumn: function(sourceViewIndex, destViewIndex, cellIndex, targetIndex, before){
-		if(this._savedCriterias && cellIndex != targetIndex){
-			if(before){ --targetIndex; }
-			var min = cellIndex < targetIndex ? cellIndex : targetIndex;
-			var max = cellIndex < targetIndex ? targetIndex : cellIndex;
-			var dir = targetIndex > min ? 1 : -1;
-			dojo.forEach(this._savedCriterias, function(sc){
-				var idx = parseInt(sc.column, 10);
-				if(!isNaN(idx) && idx >= min && idx <= max){
-					sc.column = String(idx == cellIndex ? idx + (max - min) * dir : idx - dir);
-				}
-			});
+	removeChild: function(child){
+		var pane = child, isRemoveByUser = false;
+		if(child._pane){
+			isRemoveByUser = true;
+			pane = arguments[0] = child._pane;
 		}
-	},
-	destroy: function(){
-		this._defPane.destroyRecursive();
-		this._defPane = null;
-		this.filterDefPane = null;
-		this.builder = null;
-		this._dataTypeMap = null;
-		this._cboxes = null;
-		var g = this.plugin.grid;
-		g.setFilter = null;
-		g.getFilter = null;
-		g.getFilterRelation = null;
-		this.plugin = null;
-	},
-	_setupData: function(){
-		var nls = this.plugin.nls;
-		this._dataTypeMap = {
-		// summary:
-		//		All supported data types
-			"number":{
-				valueBoxCls: {
-					dft: dijit.form.NumberTextBox
-				},
-				conditions:[
-					{label: nls.conditionEqual, value: "equalto", selected: true},
-					{label: nls.conditionNotEqual, value: "notequalto"},
-					{label: nls.conditionLess, value: "lessthan"},
-					{label: nls.conditionLessEqual, value: "lessthanorequalto"},
-					{label: nls.conditionLarger, value: "largerthan"},
-					{label: nls.conditionLargerEqual, value: "largerthanorequalto"},
-					{label: nls.conditionIsEmpty, value: "isempty"}
-				]
-			},
-			"string":{
-				valueBoxCls: {
-					dft: dijit.form.TextBox,
-					ac: fns.UniqueComboBox		//For autoComplete
-				},
-				conditions:[
-					{label: nls.conditionContains, value: "contains", selected: true},
-					{label: nls.conditionIs, value: "equalto"},
-					{label: nls.conditionStartsWith, value: "startswith"},
-					{label: nls.conditionEndWith, value: "endswith"},
-					{label: nls.conditionNotContain, value: "notcontains"},
-					{label: nls.conditionIsNot, value: "notequalto"},
-					{label: nls.conditionNotStartWith, value: "notstartswith"},
-					{label: nls.conditionNotEndWith, value: "notendswith"},
-					{label: nls.conditionIsEmpty, value: "isempty"}
-				]
-			},
-			"date":{
-				valueBoxCls: {
-					dft: dijit.form.DateTextBox
-				},
-				conditions:[
-					{label: nls.conditionIs, value: "equalto", selected: true},
-					{label: nls.conditionBefore, value: "lessthan"},
-					{label: nls.conditionAfter, value: "largerthan"},
-					{label: nls.conditionRange, value: "range"},
-					{label: nls.conditionIsEmpty, value: "isempty"}
-				]
-			},
-			"time":{
-				valueBoxCls: {
-					dft: dijit.form.TimeTextBox
-				},
-				conditions:[
-					{label: nls.conditionIs, value: "equalto", selected: true},
-					{label: nls.conditionBefore, value: "lessthan"},
-					{label: nls.conditionAfter, value: "largerthan"},
-					{label: nls.conditionRange, value: "range"},
-					{label: nls.conditionIsEmpty, value: "isempty"}
-				]
-			},
-			"boolean": {
-				valueBoxCls: {
-					dft: fns.BooleanValueBox
-				},
-				conditions: [
-					{label: nls.conditionIs, value: "equalto", selected: true},
-					{label: nls.conditionIsEmpty, value: "isempty"}
-				]
+		this.inherited(arguments);
+		if(isRemoveByUser){
+			this._hackHeight(false, this._titleHeight);
+			var children = this.getChildren();
+			if(children.length === 1){
+				html.style(children[0]._removeCBoxBtn.domNode, "display", "none");
 			}
-		};
-	},
-	setFilter: function(rules, ruleRelation){
-		rules = rules || [];
-		if(!dojo.isArray(rules)){
-			rules = [rules];
 		}
-		var func = function(){
-			if(rules.length){
-				this._savedCriterias = dojo.map(rules, function(rule){
-					var type = rule.type || this.defaultType;
-					return {
-						"type": type,
-						"column": String(rule.column),
-						"condition": rule.condition,
-						"value": rule.value,
-						"colTxt": this.getColumnLabelByValue(String(rule.column)),
-						"condTxt": this.getConditionLabelByValue(type, rule.condition),
-						"formattedVal": rule.formattedVal || rule.value
-					};
-				}, this);
-				this._criteriasChanged = true;
-				if(ruleRelation === "logicall" || ruleRelation === "logicany"){
-					this._relOpCls = ruleRelation;
-				}
-				var exprs = dojo.map(rules, this.getExprForCriteria, this);
-				exprs = this.builder.buildExpression(exprs.length == 1 ? exprs[0] : {
-					"op": this._relOpCls,
-					"data": exprs
-				});
-				this.plugin.grid.layer("filter").filterDef(exprs);
-				this.plugin.filterBar.toggleClearFilterBtn(false);
-			}
-			this._closeDlgAndUpdateGrid();
-		};
-		if(this._savedCriterias){
-			this._clearWithoutRefresh = true;
-			var handle = dojo.connect(this, "clearFilter", this, function(){
-				dojo.disconnect(handle);
-				this._clearWithoutRefresh = false;
-				func.apply(this);
-			});
-			this.onClearFilter();
-		}else{
-			func.apply(this);
+		pane.destroyRecursive();
+	},
+	selectChild: function(child){
+		if(child._pane){
+			arguments[0] = child._pane;
 		}
+		this.inherited(arguments);
 	},
-	getFilter: function(){
-		return dojo.clone(this._savedCriterias) || [];
+	resize: function(){
+		this.inherited(arguments);
+		array.forEach(this.getChildren(), this._setupTitleDom);
 	},
-	getColumnLabelByValue: function(v){
-		var nls = this.plugin.nls;
-		if(v.toLowerCase() == "anycolumn"){
-			return nls["anyColumnOption"];
-		}else{
-			var cell = this.plugin.grid.layout.cells[parseInt(v, 10)];
-			return cell ? (cell.name || cell.field) : "";
+	startup: function(){
+		if(this._started){
+			return;
 		}
-	},
-	getConditionLabelByValue: function(type, c){
-		var conditions = this._dataTypeMap[type].conditions;
-		for(var i = conditions.length - 1; i >= 0; --i){
-			var cond = conditions[i];
-			if(cond.value == c.toLowerCase()){
-				return cond.label;
-			}
+		this.inherited(arguments);
+		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"){
+					this.disconnect(cnnt);
+					return true;
+				}
+			}, this);
 		}
-		return "";
+		array.forEach(this.getChildren(), function(child){
+			this._modifyChild(child, true);
+		}, this);
 	},
-	addCriteriaBoxes: function(/* int */cnt){
+	_onKeyPress: function(/*Event*/ e, /*dijit._Widget*/ fromTitle){
 		// summary:
-		//		Add *cnt* criteria boxes to the filter definition pane.
-		//		Check overflow if necessary.
-		if(typeof cnt != "number" || cnt <= 0){
+		//		Overrides base class method, make left/right button do other things.
+		if(this.disabled || e.altKey || !(fromTitle || e.ctrlKey)){
 			return;
 		}
-		var cbs = this._cboxes,
-			cc = this.filterDefPane.cboxContainer,
-			total = this.plugin.args.ruleCount,
-			len = cbs.length, cbox;
-		//If overflow, add to max rule count.
-		if(total > 0 && len + cnt > total){
-			cnt = total - len;
+		var k = keys, c = e.charOrCode, ltr = html._isBodyLtr(), toNext = null;
+		if((fromTitle && c == k.UP_ARROW) || (e.ctrlKey && c == k.PAGE_UP)){
+			toNext = false;
+		}else if((fromTitle && c == k.DOWN_ARROW) || (e.ctrlKey && (c == k.PAGE_DOWN || c == k.TAB))){
+			toNext = true;
+		}else if(c == (ltr ? k.LEFT_ARROW : k.RIGHT_ARROW)){
+			toNext = this._focusOnRemoveBtn ? null : false;
+			this._focusOnRemoveBtn = !this._focusOnRemoveBtn;
+		}else if(c == (ltr ? k.RIGHT_ARROW : k.LEFT_ARROW)){
+			toNext = this._focusOnRemoveBtn ? true : null;
+			this._focusOnRemoveBtn = !this._focusOnRemoveBtn;
+		}else{
+			return;
 		}
-		for(; cnt > 0; --cnt){
-			cbox = new fns.CriteriaBox({
-				dlg: this
-			});
-			cbs.push(cbox);
-			cc.addChild(cbox);
+		if(toNext !== null){
+			this._adjacent(toNext)._buttonWidget._onTitleClick();
 		}
-		//If there's no content box in it , AccordionContainer can not startup
-		cc.startup();
-		this._updatePane();
-		this._updateCBoxTitles();
-		cc.selectChild(cbs[cbs.length-1]);
-		//Asign an impossibly large scrollTop to scroll the criteria pane to the bottom.
-		this.filterDefPane.criteriaPane.scrollTop = 1000000;
-		if(cbs.length === 4){
-			if(dojo.isIE <= 6 && !this.__alreadyResizedForIE6){
-				var size = dojo.position(cc.domNode);
-				size.w -= dojox.html.metrics.getScrollbar().w;
-				cc.resize(size);
-				this.__alreadyResizedForIE6 = true;
-			}else{
-				cc.resize();
-			}
+		event.stop(e);
+		win.scrollIntoView(this.selectedChildWidget._buttonWidget.domNode.parentNode);
+		if(has('ie')){
+			//IE will not show focus indicator if tabIndex is -1
+			this.selectedChildWidget._removeCBoxBtn.focusNode.setAttribute("tabIndex", this._focusOnRemoveBtn ? _tabIdxes.accordionTitle : -1);
 		}
+		dijitFocus.focus(this.selectedChildWidget[this._focusOnRemoveBtn ? "_removeCBoxBtn" : "_buttonWidget"].focusNode);
 	},
-	removeCriteriaBoxes: function(/* int|CriteriaBox|int[] */cnt,/* bool? */isIdx){
-		// summary:
-		//		Remove criteria boxes from the filter definition pane.
-		var cbs = this._cboxes, cc = this.filterDefPane.cboxContainer,
-			len = cbs.length, start = len - cnt,
-			end = len - 1, cbox,
-			curIdx = dojo.indexOf(cbs, cc.selectedChildWidget.content);
-		if(dojo.isArray(cnt)){
-			var i, idxes = cnt;
-			idxes.sort();
-			cnt = idxes.length;
-			//find a rule that's not deleted.
-			//must find and focus the last one, or the hack will not work.
-			for(i = len - 1; i >= 0 && dojo.indexOf(idxes, i) >= 0; --i){}
-			if(i >= 0){
-				//must select before remove
-				if(i != curIdx){
-					cc.selectChild(cbs[i]);
-				}
-				//idxes is sorted from small to large,
-				//so travel reversely won't need change index after delete from array.
-				for(i = cnt-1; i >= 0; --i){
-					if(idxes[i] >= 0 && idxes[i] < len){
-						cc.removeChild(cbs[idxes[i]]);
-						cbs.splice(idxes[i],1);
-					}
-				}
+	_modifyChild: function(child, isFirst){
+		if(!child || !this._started){
+			return;
+		}
+		html.style(child.domNode, "overflow", "hidden");
+		child._buttonWidget.connect(child._buttonWidget, "_setSelectedAttr", function(){
+			this.focusNode.setAttribute("tabIndex", this.selected ? _tabIdxes.accordionTitle : "-1");
+		});
+		var _this = this;
+		child._buttonWidget.connect(child._buttonWidget.domNode, "onclick", function(){
+			_this._focusOnRemoveBtn = false;
+		});
+		(child._removeCBoxBtn = new Button({
+			label: this.nls.removeRuleButton,
+			showLabel: false,
+			iconClass: "dojoxGridFCBoxRemoveCBoxBtnIcon",
+			tabIndex: _tabIdxes.removeCBoxBtn,
+			onClick: lang.hitch(child.content, "onRemove"),
+			onKeyPress: function(e){
+				_this._onKeyPress(e, child._buttonWidget.contentWidget);
 			}
-			start = cbs.length;
+		})).placeAt(child._buttonWidget.domNode);
+		var i, children = this.getChildren();
+		if(children.length === 1){
+			child._buttonWidget.set("selected", true);
+			html.style(child._removeCBoxBtn.domNode, "display", "none");
 		}else{
-			if(isIdx === true){
-				if(cnt >= 0 && cnt < len){
-					start = end = cnt;
-					cnt = 1;
-				}else{
-					return;
-				}
-			}else{
-				if(cnt instanceof fns.CriteriaBox){
-					cbox = cnt;
-					cnt = 1;
-					start = end = dojo.indexOf(cbs, cbox);
-				}else if(typeof cnt != "number" || cnt <= 0){
-					return;
-				}else if(cnt >= len){
-					cnt = end;
-					start = 1;
+			for(i = 0; i < children.length; ++i){
+				if(children[i]._removeCBoxBtn){
+					html.style(children[i]._removeCBoxBtn.domNode, "display", "");
 				}
 			}
-			if(end < start){
-				return;
-			}
-			//must select before remove
-			if(curIdx >= start && curIdx <= end){
-				cc.selectChild(cbs[start ? start-1 : end+1]);
-			}
-			for(; end >= start; --end){
-				cc.removeChild(cbs[end]);
-			}
-			cbs.splice(start, cnt);
-		}
-		this._updatePane();
-		this._updateCBoxTitles();
-		if(cbs.length === 3){
-			//In ie6, resize back to the normal width will cause the title button look strange.
-			cc.resize();
 		}
-	},
-	getCriteria: function(/* int */idx){
-		// summary:
-		//		Get the *idx*-th criteria.
-		if(typeof idx != "number"){
-			return this._savedCriterias ? this._savedCriterias.length : 0;
+		this._setupTitleDom(child);
+		if(!this._titleHeight){
+			for(i = 0; i < children.length; ++i){
+				if(children[i] != this.selectedChildWidget){
+					this._titleHeight = html.marginBox(children[i]._buttonWidget.domNode.parentNode).h;
+					break;
+				}
+			}
 		}
-		if(this._savedCriterias && this._savedCriterias[idx]){
-			return dojo.mixin({
-				relation: this._relOpCls == "logicall" ? this.plugin.nls.and : this.plugin.nls.or
-			},this._savedCriterias[idx]);
+		if(!isFirst){
+			this._hackHeight(true, this._titleHeight);
 		}
-		return null;
 	},
-	getExprForCriteria: function(rule){
-		if(rule.column == "anycolumn"){
-			var cells = dojo.filter(this.plugin.grid.layout.cells, function(cell){
-				return !(cell.filterable === false || cell.hidden);
-			});
-			return {
-				"op": "logicany",
-				"data": dojo.map(cells, function(cell){
-					return this.getExprForColumn(rule.value, cell.index, rule.type, rule.condition);
-				}, this)
-			};
+	_hackHeight: function(/* bool */toGrow,/* int */heightDif){
+		var children = this.getChildren(),
+			dn = this.domNode, h = html.style(dn, "height");
+		if(!toGrow){
+			dn.style.height = (h - heightDif) + 'px';
+		}else if(children.length > 1){
+			dn.style.height = (h + heightDif) + 'px';
 		}else{
-			return this.getExprForColumn(rule.value, rule.column, rule.type, rule.condition);
+			//Only one rule, no need to do anything.
+			return;
 		}
+		this.resize();
 	},
-	getExprForColumn: function(value, colIdx, type, condition){
-		colIdx = parseInt(colIdx, 10);
-		var cell = this.plugin.grid.layout.cells[colIdx],
-			colName = cell.field || cell.name,
-			obj = {
-				"datatype": type || this.getColumnType(colIdx),
-				"args": cell.dataTypeArgs,
-				"isColumn": true
-			},
-			operands = [dojo.mixin({"data": this.plugin.args.isServerSide ? colName : cell}, obj)];
-		obj.isColumn = false;
-		if(condition == "range"){
-			operands.push(dojo.mixin({"data": value.start}, obj),
-				dojo.mixin({"data": value.end}, obj));
-		}else if(condition != "isempty"){
-			operands.push(dojo.mixin({"data": value}, obj));
-		}
-		return {
-			"op": condition,
-			"data": operands
-		};
+	_setupTitleDom: function(child){
+		var w = html.contentBox(child._buttonWidget.titleNode).w;
+		if(has('ie') < 8){ w -= 8; }
+		html.style(child._buttonWidget.titleTextNode, "width", w + "px");
+	}
+});
+var FilterDefPane = declare("dojox.grid.enhanced.plugins.filter.FilterDefPane",[_Widget, _TemplatedMixin, _WidgetsInTemplateMixin],{
+	templateString: cache("dojox.grid","enhanced/templates/FilterDefPane.html"),
+	widgetsInTemplate: true,
+	dlg: null,
+	postMixInProperties: function(){
+		this.plugin = this.dlg.plugin;
+		var nls = this.plugin.nls;
+		this._addRuleBtnLabel = nls.addRuleButton;
+		this._cancelBtnLabel = nls.cancelButton;
+		this._clearBtnLabel = nls.clearButton;
+		this._filterBtnLabel = nls.filterButton;
+		this._relAll = nls.relationAll;
+		this._relAny = nls.relationAny;
+		this._relMsgFront = nls.relationMsgFront;
+		this._relMsgTail = nls.relationMsgTail;
 	},
-	getColumnType: function(/* int */colIndex){
-		var cell = this.plugin.grid.layout.cells[parseInt(colIndex, 10)];
-		if(!cell || !cell.datatype){
-			return this.defaultType;
-		}
-		var type = String(cell.datatype).toLowerCase();
-		return this._dataTypeMap[type] ? type : this.defaultType;
+	postCreate: function(){
+		this.inherited(arguments);
+		this.connect(this.domNode, "onkeypress", "_onKey");
+		(this.cboxContainer = new FilterAccordionContainer({
+			nls: this.plugin.nls
+		})).placeAt(this.criteriaPane);
+		
+		this._relSelect.set("tabIndex", _tabIdxes.relSelect);
+		this._addCBoxBtn.set("tabIndex", _tabIdxes.addCBoxBtn);
+		this._cancelBtn.set("tabIndex", _tabIdxes.cancelBtn);
+		this._clearFilterBtn.set("tabIndex", _tabIdxes.clearBtn);
+		this._filterBtn.set("tabIndex", _tabIdxes.filterBtn);
+		
+		var nls = this.plugin.nls;
+		this._relSelect.domNode.setAttribute("aria-label", nls.waiRelAll);
+		this._addCBoxBtn.domNode.setAttribute("aria-label", nls.waiAddRuleButton);
+		this._cancelBtn.domNode.setAttribute("aria-label", nls.waiCancelButton);
+		this._clearFilterBtn.domNode.setAttribute("aria-label", nls.waiClearButton);
+		this._filterBtn.domNode.setAttribute("aria-label", nls.waiFilterButton);
+		
+		this._relSelect.set("value", this.dlg._relOpCls === "logicall" ? "0" : "1");
 	},
-	//////////////////////////////////////////////////////////////////////////////////////////////////////////
-	clearFilter: function(noRefresh){
-		// summary:
-		//		Clear filter definition.
-		if(!this._savedCriterias){
-			return;
-		}
-		this._savedCriterias = null;
-		this.plugin.grid.layer("filter").filterDef(null);
-		try{
-			this.plugin.filterBar.toggleClearFilterBtn(true);
-			this.filterDefPane._clearFilterBtn.set("disabled", true);
-			this.removeCriteriaBoxes(this._cboxes.length-1);
-			this._cboxes[0].load({});
-		}catch(e){
-			//Any error means the filter is defined outside this plugin.
-		}
-		if(noRefresh){
-			this.closeDialog();
-		}else{
-			this._closeDlgAndUpdateGrid();
-		}
+	uninitialize: function(){
+		this.cboxContainer.destroyRecursive();
+		this.plugin = null;
+		this.dlg = null;
 	},
-	showDialog: function(/* int */colIndex){
-		// summary:
-		//		Show the filter defintion dialog.
-		this._defPane.show();
-		this.plugin.filterStatusTip.closeDialog();
-		this._prepareDialog(colIndex);
+	_onRelSelectChange: function(val){
+		this.dlg._relOpCls = val == "0" ? "logicall" : "logicany";
+		this._relSelect.domNode.setAttribute("aria-label", this.plugin.nls[val == "0" ? "waiRelAll" : "waiRelAny"]);
 	},
-	closeDialog: function(){
-		// summary:
-		//		Close the filter definition dialog.
-		this._defPane.hide();
+	_onAddCBox: function(){
+		this.dlg.addCriteriaBoxes(1);
 	},
-	onFilter: function(e){
-		// summary:
-		//		Triggered when the "Filter" button is clicked.
-		if(this.canFilter()){
-			this._defineFilter();
-			this._closeDlgAndUpdateGrid();
-			this.plugin.filterBar.toggleClearFilterBtn(false);
-		}
+	_onCancel: function(){
+		this.dlg.onCancel();
 	},
-	onClearFilter: function(e){
-		// summary:
-		//		Triggered when the "Clear" button is clicked.
-		if(this._savedCriterias){
-			if(this._savedCriterias.length > 1){
-				this.plugin.clearFilterDialog.show();
-			}else{
-				this.clearFilter(this._clearWithoutRefresh);
-			}
-		}
+	_onClearFilter: function(){
+		this.dlg.onClearFilter();
 	},
-	onCancel: function(e){
-		// summary:
-		//		Triggered when the "Cancel" buttton is clicked.
-		var sc = this._savedCriterias;
-		var cbs = this._cboxes;
-		if(sc){
-			this.addCriteriaBoxes(sc.length - cbs.length);
-			this.removeCriteriaBoxes(cbs.length - sc.length);
-			dojo.forEach(sc, function(c, i){
-				cbs[i].load(c);
-			});
-		}else{
-			this.removeCriteriaBoxes(cbs.length - 1);
-			cbs[0].load({});
-		}
-		this.closeDialog();
+	_onFilter: function(){
+		this.dlg.onFilter();
 	},
-	onRendered: function(cbox){
-		// summary:
-		//		Triggered when the rendering of the filter definition dialog is completely finished.
-		// cbox:
-		//		Current visible criteria box
-		if(!dojo.isFF){
-			var elems = dijit._getTabNavigable(dojo.byId(cbox.domNode));
-			dijit.focus(elems.lowest || elems.first);
-		}else{
-			var dp = this._defPane;
-			dp._getFocusItems(dp.domNode);
-			dijit.focus(dp._firstFocusItem);
+	_onKey: function(e){
+		if(e.keyCode == keys.ENTER){
+			this.dlg.onFilter();
 		}
-	},
-	_onSetFilter: function(filterDef){
-		// summary:
-		//		If someone clear the filter def in the store directly, we must clear it in the UI.
-		//		If someone defines a filter, don't know how to handle it!
-		if(filterDef === null && this._savedCriterias){
-			this.clearFilter();
-		}
-	},
-	_prepareDialog: function(/* int */colIndex){
-		var sc = this._savedCriterias,
-			cbs = this._cboxes, i, cbox;
-		this.curColIdx = colIndex;
-		if(!sc){
-			if(cbs.length === 0){
-				this.addCriteriaBoxes(1);
-			}else{
-				//Re-populate columns anyway, because we don't know when the column is set to hidden.
-				for(i = 0; (cbox = cbs[i]); ++i){
-					cbox.changeCurrentColumn();
-				}
-			}
-		}else if(this._criteriasChanged){
-			this.filterDefPane._relSelect.set("value", this._relOpCls === "logicall" ? "0" : "1");
-			this._criteriasChanged = false;
-			var needNewCBox = sc.length > cbs.length;
-			this.addCriteriaBoxes(sc.length - cbs.length);
-			this.removeCriteriaBoxes(cbs.length - sc.length);
-			this.filterDefPane._clearFilterBtn.set("disabled", false);
-			if(needNewCBox){
-				dojo.forEach(sc, function(c, i){
-					var handle = dojo.connect(this, "onRendered", function(cbox){
-						if(cbox == cbs[i]){
-							dojo.disconnect(handle);
-							cbox.load(c);
-						}
-					});
-				}, this);
-			}else{
-				for(i = 0; i < sc.length; ++i){
-					cbs[i].load(sc[i]);
-				}
-			}
-		}
-		//Since we're allowed to remove cboxes when the definition pane is not shown,
-		//we have to resize the container to have a correct _verticalSpace.
-		this.filterDefPane.cboxContainer.resize();
-	},
-	_defineFilter: function(){
-		var cbs = this._cboxes,
-			filterCboxes = function(method){
-				return dojo.filter(dojo.map(cbs, function(cbox){
-					return cbox[method]();
-				}), function(result){
-					return !!result;
-				});
-			},
-			exprs = filterCboxes("getExpr");
-		this._savedCriterias = filterCboxes("save");
-		exprs = exprs.length == 1 ? exprs[0] : {
-			"op": this._relOpCls,
-			"data": exprs
-		};
-		exprs = this.builder.buildExpression(exprs);
-		
-		this.plugin.grid.layer("filter").filterDef(exprs);
-		this.filterDefPane._clearFilterBtn.set("disabled", false);
-	},
-	_updateCBoxTitles: function(){
-		for(var cbs = this._cboxes, i = cbs.length; i > 0; --i){
-			cbs[i - 1].updateRuleIndex(i);
-			cbs[i - 1].setAriaInfo(i);
-		}
-	},
-	_updatePane: function(){
-		var cbs = this._cboxes,
-			defPane = this.filterDefPane;
-		defPane._addCBoxBtn.set("disabled", cbs.length == this.plugin.args.ruleCount);
-		defPane._filterBtn.set("disabled", !this.canFilter());
-	},
-	canFilter: function(){
-		return dojo.filter(this._cboxes, function(cbox){
-			return !cbox.isEmpty();
-		}).length > 0;
-	},
-	_closeDlgAndUpdateGrid: function(){
-		this.closeDialog();
-		var g = this.plugin.grid;
-		g.showMessage(g.loadingMessage);
-		setTimeout(dojo.hitch(g, g._refresh), this._defPane.duration + 10);
 	}
 });
-dojo.declare("dojox.grid.enhanced.plugins.filter.FilterDefPane",[dijit._Widget,dijit._Templated],{
-	templateString: dojo.cache("dojox.grid","enhanced/templates/FilterDefPane.html"),
-	widgetsInTemplate: true,
-	dlg: null,
-	postMixInProperties: function(){
-		this.plugin = this.dlg.plugin;
-		var nls = this.plugin.nls;
-		this._addRuleBtnLabel = nls.addRuleButton;
-		this._cancelBtnLabel = nls.cancelButton;
-		this._clearBtnLabel = nls.clearButton;
-		this._filterBtnLabel = nls.filterButton;
-		this._relAll = nls.relationAll;
-		this._relAny = nls.relationAny;
-		this._relMsgFront = nls.relationMsgFront;
-		this._relMsgTail = nls.relationMsgTail;
-	},
-	postCreate: function(){
-		this.inherited(arguments);
-		this.connect(this.domNode, "onkeypress", "_onKey");
-		(this.cboxContainer = new fns.AccordionContainer({
-			nls: this.plugin.nls
-		})).placeAt(this.criteriaPane);
-		
-		this._relSelect.set("tabIndex", _tabIdxes.relSelect);
-		this._addCBoxBtn.set("tabIndex", _tabIdxes.addCBoxBtn);
-		this._cancelBtn.set("tabIndex", _tabIdxes.cancelBtn);
-		this._clearFilterBtn.set("tabIndex", _tabIdxes.clearBtn);
-		this._filterBtn.set("tabIndex", _tabIdxes.filterBtn);
-		
-		var nls = this.plugin.nls;
-		dijit.setWaiState(this._relSelect.domNode, "label", nls.waiRelAll);
-		dijit.setWaiState(this._addCBoxBtn.domNode, "label", nls.waiAddRuleButton);
-		dijit.setWaiState(this._cancelBtn.domNode, "label", nls.waiCancelButton);
-		dijit.setWaiState(this._clearFilterBtn.domNode, "label", nls.waiClearButton);
-		dijit.setWaiState(this._filterBtn.domNode, "label", nls.waiFilterButton);
-		
-		this._relSelect.set("value", this.dlg._relOpCls === "logicall" ? "0" : "1");
-	},
-	uninitialize: function(){
-		this.cboxContainer.destroyRecursive();
-		this.plugin = null;
-		this.dlg = null;
-	},
-	_onRelSelectChange: function(val){
-		this.dlg._relOpCls = val == "0" ? "logicall" : "logicany";
-		dijit.setWaiState(this._relSelect.domNode,"label", this.plugin.nls[val == "0" ? "waiRelAll" : "waiRelAny"]);
-	},
-	_onAddCBox: function(){
-		this.dlg.addCriteriaBoxes(1);
-	},
-	_onCancel: function(){
-		this.dlg.onCancel();
-	},
-	_onClearFilter: function(){
-		this.dlg.onClearFilter();
-	},
-	_onFilter: function(){
-		this.dlg.onFilter();
-	},
-	_onKey: function(e){
-		if(e.keyCode == dojo.keys.ENTER){
-			this.dlg.onFilter();
-		}
-	}
-});
-dojo.declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[dijit._Widget,dijit._Templated],{
-	templateString: dojo.cache("dojox.grid","enhanced/templates/CriteriaBox.html"),
+var CriteriaBox = declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[_Widget, _TemplatedMixin, _WidgetsInTemplateMixin],{
+	templateString: cache("dojox.grid","enhanced/templates/CriteriaBox.html"),
 	widgetsInTemplate: true,
 	dlg: null,
 	postMixInProperties: function(){
@@ -676,7 +296,7 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[dijit._Widget,dij
 	},
 	_getColumnOptions: function(){
 		var colIdx = this.dlg.curColIdx >= 0 ? String(this.dlg.curColIdx) : "anycolumn";
-		return dojo.map(dojo.filter(this.plugin.grid.layout.cells, function(cell){
+		return array.map(array.filter(this.plugin.grid.layout.cells, function(cell){
 			return !(cell.filterable === false || cell.hidden);
 		}), function(cell){
 			return {
@@ -722,11 +342,11 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[dijit._Widget,dij
 		var options = sel.getOptions();
 		if(options.length == 1){
 			alt.innerHTML = options[0].label;
-			dojo.style(sel.domNode, "display", "none");
-			dojo.style(alt, "display", "");
+			html.style(sel.domNode, "display", "none");
+			html.style(alt, "display", "");
 		}else{
-			dojo.style(sel.domNode, "display", "");
-			dojo.style(alt, "display", "none");
+			html.style(sel.domNode, "display", "");
+			html.style(alt, "display", "none");
 		}
 	},
 	_onChangeColumn: function(val){
@@ -751,7 +371,7 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[dijit._Widget,dij
 	_checkValidCriteria: function(){
 		// summary:
 		//		Check whether the given criteria box is completed. If it is, mark it.
-		setTimeout(dojo.hitch(this, function(){
+		setTimeout(lang.hitch(this, function(){
 			this.updateRuleTitle();
 			this.dlg._updatePane();
 		}),0);
@@ -759,8 +379,8 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[dijit._Widget,dij
 	_createValueBox: function(/* widget constructor */cls,/* object */arg){
 		// summary:
 		//		Create a value input box with given class and arguments
-		var func = dojo.hitch(arg.cbox, "_checkValidCriteria");
-		return new cls(dojo.mixin(arg,{
+		var func = lang.hitch(arg.cbox, "_checkValidCriteria");
+		return new cls(lang.mixin(arg,{
 			tabIndex: _tabIdxes.valueBox,
 			onKeyPress: func,
 			onChange: func,
@@ -770,25 +390,25 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[dijit._Widget,dij
 	_createRangeBox: function(/* widget constructor */cls,/* object */arg){
 		// summary:
 		//		Create a DIV containing 2 input widgets, which represents a range, with the given class and arguments
-		var func = dojo.hitch(arg.cbox, "_checkValidCriteria");
-		dojo.mixin(arg,{
+		var func = lang.hitch(arg.cbox, "_checkValidCriteria");
+		lang.mixin(arg,{
 			tabIndex: _tabIdxes.valueBox,
 			onKeyPress: func,
 			onChange: func
 		});
-		var div = dojo.create("div", {"class": "dojoxGridFCBoxValueBox"}),
+		var div = html.create("div", {"class": "dojoxGridFCBoxValueBox"}),
 			start = new cls(arg),
-			txt = dojo.create("span", {"class": "dojoxGridFCBoxRangeValueTxt", "innerHTML": this.plugin.nls.rangeTo}),
+			txt = html.create("span", {"class": "dojoxGridFCBoxRangeValueTxt", "innerHTML": this.plugin.nls.rangeTo}),
 			end = new cls(arg);
-		dojo.addClass(start.domNode, "dojoxGridFCBoxStartValue");
-		dojo.addClass(end.domNode, "dojoxGridFCBoxEndValue");
+		html.addClass(start.domNode, "dojoxGridFCBoxStartValue");
+		html.addClass(end.domNode, "dojoxGridFCBoxEndValue");
 		div.appendChild(start.domNode);
 		div.appendChild(txt);
 		div.appendChild(end.domNode);
 		div.domNode = div;
 		//Mock functions for set and get (in place of the old attr function)
 		div.set = function(dummy, args){
-			if(dojo.isObject(args)){
+			if(lang.isObject(args)){
 				start.set("value", args.start);
 				end.set("value", args.end);
 			}
@@ -860,7 +480,7 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[dijit._Widget,dij
 			this._curValueBox.set("value", value);
 		}
 		this._updateValueBox();
-		setTimeout(dojo.hitch(this, function(){
+		setTimeout(lang.hitch(this, function(){
 			this._onChangeColumn = tmp[0];
 			this._onChangeCondition = tmp[1];
 		}), 0);
@@ -889,7 +509,7 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[dijit._Widget,dij
 			"<div class='dojoxEllipsis'>"
 		];
 		if(isEmpty || this.isEmpty()){
-			node.title = dojo.string.substitute(this.plugin.nls.ruleTitleTemplate, [this._ruleIndex || 1]);
+			node.title = string.substitute(this.plugin.nls.ruleTitleTemplate, [this._ruleIndex || 1]);
 			title.push(node.title);
 		}else{
 			var type = this.dlg.getColumnType(this._colSelect.get("value"));
@@ -905,325 +525,727 @@ dojo.declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[dijit._Widget,dij
 			);
 			node.title = [column, " ", condition, " ", value].join('');
 		}
-		node.innerHTML = title.join('');
-		if(dojo.isMoz){
-			var tt = dojo.create("div", {
-				"style": "width: 100%; height: 100%; position: absolute; top: 0; left: 0; z-index: 9999;"
-			}, node);
-			tt.title = node.title;
+		node.innerHTML = title.join('');
+		if(has('mozilla')){
+			var tt = html.create("div", {
+				"style": "width: 100%; height: 100%; position: absolute; top: 0; left: 0; z-index: 9999;"
+			}, node);
+			tt.title = node.title;
+		}
+	},
+	updateRuleIndex: function(index){
+		if(this._ruleIndex != index){
+			this._ruleIndex = index;
+			if(this.isEmpty()){
+				this.updateRuleTitle();
+			}
+		}
+	},
+	setAriaInfo: function(idx){
+		var dss = string.substitute, nls = this.plugin.nls;
+		this._colSelect.domNode.setAttribute("aria-label", dss(nls.waiColumnSelectTemplate, [idx]));
+		this._condSelect.domNode.setAttribute("aria-label", dss(nls.waiConditionSelectTemplate, [idx]));
+		this._pane._removeCBoxBtn.domNode.setAttribute("aria-label", dss(nls.waiRemoveRuleButtonTemplate, [idx]));
+		this._index = idx;
+	},
+	_getUsableConditions: function(type){
+		var conditions = lang.clone(this.dlg._dataTypeMap[type].conditions);
+		var typeDisabledConds = (this.plugin.args.disabledConditions || {})[type];
+		var colIdx = parseInt(this._colSelect.get("value"), 10);
+		var colDisabledConds = isNaN(colIdx) ?
+			(this.plugin.args.disabledConditions || {})["anycolumn"] :
+			this.plugin.grid.layout.cells[colIdx].disabledConditions;
+		if(!lang.isArray(typeDisabledConds)){
+			typeDisabledConds = [];
+		}
+		if(!lang.isArray(colDisabledConds)){
+			colDisabledConds = [];
+		}
+		var arr = typeDisabledConds.concat(colDisabledConds);
+		if(arr.length){
+			var disabledConds = {};
+			array.forEach(arr, function(c){
+				if(lang.isString(c)){
+					disabledConds[c.toLowerCase()] = true;
+				}
+			});
+			return array.filter(conditions, function(condOption){
+				return !(condOption.value in disabledConds);
+			});
+		}
+		return conditions;
+	},
+	_setConditionsByType: function(/* string */type){
+		var condSelect = this._condSelect;
+		condSelect.removeOption(condSelect.options);
+		condSelect.addOption(this._getUsableConditions(type));
+		this._showSelectOrLabel(this._condSelect, this._condSelectAlt);
+	},
+	_setValueBoxByType: function(/* string */type){
+		if(this._curValueBox){
+			this.valueNode.removeChild(this._curValueBox.domNode);
+			try{
+				this._curValueBox.destroyRecursive();
+			}catch(e){}
+			delete this._curValueBox;
+		}
+		//value box class
+		var vbcls = this.dlg._dataTypeMap[type].valueBoxCls[this._getValueBoxClsInfo(this._colSelect.get("value"), type)],
+			vboxArg = this._getValueBoxArgByType(type);
+		this._curValueBox = this[this._isRange ? "_createRangeBox" : "_createValueBox"](vbcls, vboxArg);
+		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]));
+		//Now our cbox is completely ready
+		this.dlg.onRendered(this);
+	},
+	//--------------------------UI Configuration--------------------------------------
+	_getValueBoxArgByType: function(/* string */type){
+		// summary:
+		//		Get the arguments for the value box construction.
+		var g = this.plugin.grid,
+			cell = g.layout.cells[parseInt(this._colSelect.get("value"), 10)],
+			res = {
+				cbox: this
+			};
+		if(type == "string"){
+			if(cell && (cell.suggestion || cell.autoComplete)){
+				html.mixin(res, {
+					store: g.store,
+					searchAttr: cell.field || cell.name,
+					fetchProperties: {
+						sort: [{"attribute": cell.field || cell.name}],
+						query: g.query,
+						queryOptions: g.queryOptions
+					}
+				});
+			}
+		}else if(type == "boolean"){
+			html.mixin(res, this.dlg.builder.defaultArgs["boolean"]);
+		}
+		if(cell && cell.dataTypeArgs){
+			html.mixin(res, cell.dataTypeArgs);
+		}
+		return res;
+	},
+	formatValue: function(type, cond, v){
+		// summary:
+		//		Format the value to be shown in tooltip.
+		if(cond == "isempty"){return "";}
+		if(type == "date" || type == "time"){
+			var opt = {selector: type},
+				fmt = dateLocale.format;
+			if(cond == "range"){
+				return string.substitute(this.plugin.nls.rangeTemplate, [fmt(v.start, opt), fmt(v.end, opt)]);
+			}
+			return fmt(v, opt);
+		}else if(type == "boolean"){
+			return v ? this._curValueBox._lblTrue : this._curValueBox._lblFalse;
+		}
+		return v;
+	},
+	_getValueBoxClsInfo: function(/* int|string */colIndex, /* string */type){
+		// summary:
+		//		Decide which value box to use given data type and column index.
+		var cell = this.plugin.grid.layout.cells[parseInt(colIndex, 10)];
+		//Now we only need to handle string. But maybe we need to handle more types here in the future.
+		if(type == "string"){
+			return (cell && (cell.suggestion || cell.autoComplete)) ? "ac" : "dft";
+		}
+		return "dft";
+	}
+});
+
+
+var UniqueComboBox = declare("dojox.grid.enhanced.plugins.filter.UniqueComboBox", ComboBox, {
+	_openResultList: function(results){
+		var cache = {}, s = this.store, colName = this.searchAttr;
+		arguments[0] = array.filter(results, function(item){
+			var key = s.getValue(item, colName), existed = cache[key];
+			cache[key] = true;
+			return !existed;
+		});
+		this.inherited(arguments);
+	},
+	_onKey: function(evt){
+		if(evt.charOrCode === keys.ENTER && this._opened){
+			event.stop(evt);
+		}
+		this.inherited(arguments);
+	}
+});
+var BooleanValueBox = declare("dojox.grid.enhanced.plugins.filter.BooleanValueBox", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
+	templateString: cache("dojox.grid","enhanced/templates/FilterBoolValueBox.html"),
+	widgetsInTemplate: true,
+	constructor: function(args){
+		var nls = args.cbox.plugin.nls;
+		this._baseId = args.cbox.id;
+		this._lblTrue = args.trueLabel || nls.trueLabel || "true";
+		this._lblFalse = args.falseLabel || nls.falseLabel || "false";
+		this.args = args;
+	},
+	postCreate: function(){
+		this.onChange();
+	},
+	onChange: function(){},
+	
+	get: function(prop){
+		return this.rbTrue.get("checked");
+	},
+	set: function(prop, v){
+		this.inherited(arguments);
+		if(prop == "value"){
+			this.rbTrue.set("checked", !!v);
+			this.rbFalse.set("checked", !v);
+		}
+	}
+});
+var FilterDefDialog = declare("dojox.grid.enhanced.plugins.filter.FilterDefDialog", null, {
+	// summary:
+	//		Create the filter definition UI.
+	curColIdx: -1,
+	_relOpCls: "logicall",
+	_savedCriterias: null,
+	plugin: null,
+	constructor: function(args){
+		var plugin = this.plugin = args.plugin;
+		this.builder = new FilterBuilder();
+		this._setupData();
+		this._cboxes = [];
+		this.defaultType = plugin.args.defaultType || "string";
+		
+		(this.filterDefPane = new FilterDefPane({
+			"dlg": this
+		})).startup();
+		(this._defPane = new Dialog({
+			"refNode": this.plugin.grid.domNode,
+			"title": plugin.nls.filterDefDialogTitle,
+			"class": "dojoxGridFDTitlePane",
+			"iconClass": "dojoxGridFDPaneIcon",
+			"content": this.filterDefPane
+		})).startup();
+		
+		this._defPane.connect(plugin.grid.layer('filter'), "filterDef", lang.hitch(this, "_onSetFilter"));
+		plugin.grid.setFilter = lang.hitch(this, "setFilter");
+		plugin.grid.getFilter = lang.hitch(this, "getFilter");
+		plugin.grid.getFilterRelation = lang.hitch(this, function(){
+			return this._relOpCls;
+		});
+		
+		plugin.connect(plugin.grid.layout, "moveColumn", lang.hitch(this, "onMoveColumn"));
+	},
+	onMoveColumn: function(sourceViewIndex, destViewIndex, cellIndex, targetIndex, before){
+		if(this._savedCriterias && cellIndex != targetIndex){
+			if(before){ --targetIndex; }
+			var min = cellIndex < targetIndex ? cellIndex : targetIndex;
+			var max = cellIndex < targetIndex ? targetIndex : cellIndex;
+			var dir = targetIndex > min ? 1 : -1;
+			array.forEach(this._savedCriterias, function(sc){
+				var idx = parseInt(sc.column, 10);
+				if(!isNaN(idx) && idx >= min && idx <= max){
+					sc.column = String(idx == cellIndex ? idx + (max - min) * dir : idx - dir);
+				}
+			});
+		}
+	},
+	destroy: function(){
+		this._defPane.destroyRecursive();
+		this._defPane = null;
+		this.filterDefPane = null;
+		this.builder = null;
+		this._dataTypeMap = null;
+		this._cboxes = null;
+		var g = this.plugin.grid;
+		g.setFilter = null;
+		g.getFilter = null;
+		g.getFilterRelation = null;
+		this.plugin = null;
+	},
+	_setupData: function(){
+		var nls = this.plugin.nls;
+		this._dataTypeMap = {
+		// summary:
+		//		All supported data types
+			"number":{
+				valueBoxCls: {
+					dft: NumberTextBox
+				},
+				conditions:[
+					{label: nls.conditionEqual, value: "equalto", selected: true},
+					{label: nls.conditionNotEqual, value: "notequalto"},
+					{label: nls.conditionLess, value: "lessthan"},
+					{label: nls.conditionLessEqual, value: "lessthanorequalto"},
+					{label: nls.conditionLarger, value: "largerthan"},
+					{label: nls.conditionLargerEqual, value: "largerthanorequalto"},
+					{label: nls.conditionIsEmpty, value: "isempty"}
+				]
+			},
+			"string":{
+				valueBoxCls: {
+					dft: TextBox,
+					ac: UniqueComboBox		//For autoComplete
+				},
+				conditions:[
+					{label: nls.conditionContains, value: "contains", selected: true},
+					{label: nls.conditionIs, value: "equalto"},
+					{label: nls.conditionStartsWith, value: "startswith"},
+					{label: nls.conditionEndWith, value: "endswith"},
+					{label: nls.conditionNotContain, value: "notcontains"},
+					{label: nls.conditionIsNot, value: "notequalto"},
+					{label: nls.conditionNotStartWith, value: "notstartswith"},
+					{label: nls.conditionNotEndWith, value: "notendswith"},
+					{label: nls.conditionIsEmpty, value: "isempty"}
+				]
+			},
+			"date":{
+				valueBoxCls: {
+					dft: DateTextBox
+				},
+				conditions:[
+					{label: nls.conditionIs, value: "equalto", selected: true},
+					{label: nls.conditionBefore, value: "lessthan"},
+					{label: nls.conditionAfter, value: "largerthan"},
+					{label: nls.conditionRange, value: "range"},
+					{label: nls.conditionIsEmpty, value: "isempty"}
+				]
+			},
+			"time":{
+				valueBoxCls: {
+					dft: TimeTextBox
+				},
+				conditions:[
+					{label: nls.conditionIs, value: "equalto", selected: true},
+					{label: nls.conditionBefore, value: "lessthan"},
+					{label: nls.conditionAfter, value: "largerthan"},
+					{label: nls.conditionRange, value: "range"},
+					{label: nls.conditionIsEmpty, value: "isempty"}
+				]
+			},
+			"boolean": {
+				valueBoxCls: {
+					dft: BooleanValueBox
+				},
+				conditions: [
+					{label: nls.conditionIs, value: "equalto", selected: true},
+					{label: nls.conditionIsEmpty, value: "isempty"}
+				]
+			}
+		};
+	},
+	setFilter: function(rules, ruleRelation){
+		rules = rules || [];
+		if(!lang.isArray(rules)){
+			rules = [rules];
+		}
+		var func = function(){
+			if(rules.length){
+				this._savedCriterias = array.map(rules, function(rule){
+					var type = rule.type || this.defaultType;
+					return {
+						"type": type,
+						"column": String(rule.column),
+						"condition": rule.condition,
+						"value": rule.value,
+						"colTxt": this.getColumnLabelByValue(String(rule.column)),
+						"condTxt": this.getConditionLabelByValue(type, rule.condition),
+						"formattedVal": rule.formattedVal || rule.value
+					};
+				}, this);
+				this._criteriasChanged = true;
+				if(ruleRelation === "logicall" || ruleRelation === "logicany"){
+					this._relOpCls = ruleRelation;
+				}
+				var exprs = array.map(rules, this.getExprForCriteria, this);
+				exprs = this.builder.buildExpression(exprs.length == 1 ? exprs[0] : {
+					"op": this._relOpCls,
+					"data": exprs
+				});
+				this.plugin.grid.layer("filter").filterDef(exprs);
+				this.plugin.filterBar.toggleClearFilterBtn(false);
+			}
+			this._closeDlgAndUpdateGrid();
+		};
+		if(this._savedCriterias){
+			this._clearWithoutRefresh = true;
+			var handle = connect.connect(this, "clearFilter", this, function(){
+				connect.disconnect(handle);
+				this._clearWithoutRefresh = false;
+				func.apply(this);
+			});
+			this.onClearFilter();
+		}else{
+			func.apply(this);
+		}
+	},
+	getFilter: function(){
+		return lang.clone(this._savedCriterias) || [];
+	},
+	getColumnLabelByValue: function(v){
+		var nls = this.plugin.nls;
+		if(v.toLowerCase() == "anycolumn"){
+			return nls["anyColumnOption"];
+		}else{
+			var cell = this.plugin.grid.layout.cells[parseInt(v, 10)];
+			return cell ? (cell.name || cell.field) : "";
 		}
 	},
-	updateRuleIndex: function(index){
-		if(this._ruleIndex != index){
-			this._ruleIndex = index;
-			if(this.isEmpty()){
-				this.updateRuleTitle();
+	getConditionLabelByValue: function(type, c){
+		var conditions = this._dataTypeMap[type].conditions;
+		for(var i = conditions.length - 1; i >= 0; --i){
+			var cond = conditions[i];
+			if(cond.value == c.toLowerCase()){
+				return cond.label;
 			}
 		}
+		return "";
 	},
-	setAriaInfo: function(idx){
-		var dss = dojo.string.substitute, nls = this.plugin.nls;
-		dijit.setWaiState(this._colSelect.domNode,"label", dss(nls.waiColumnSelectTemplate, [idx]));
-		dijit.setWaiState(this._condSelect.domNode,"label", dss(nls.waiConditionSelectTemplate, [idx]));
-		dijit.setWaiState(this._pane._removeCBoxBtn.domNode,"label", dss(nls.waiRemoveRuleButtonTemplate, [idx]));
-		this._index = idx;
-	},
-	_getUsableConditions: function(type){
-		var conditions = this.dlg._dataTypeMap[type].conditions;
-		var typeDisabledConds = (this.plugin.args.disabledConditions || {})[type];
-		var colIdx = parseInt(this._colSelect.get("value"), 10);
-		var colDisabledConds = isNaN(colIdx) ?
-			(this.plugin.args.disabledConditions || {})["anycolumn"] :
-			this.plugin.grid.layout.cells[colIdx].disabledConditions;
-		if(!dojo.isArray(typeDisabledConds)){
-			typeDisabledConds = [];
+	addCriteriaBoxes: function(/* int */cnt){
+		// summary:
+		//		Add *cnt* criteria boxes to the filter definition pane.
+		//		Check overflow if necessary.
+		if(typeof cnt != "number" || cnt <= 0){
+			return;
 		}
-		if(!dojo.isArray(colDisabledConds)){
-			colDisabledConds = [];
+		var cbs = this._cboxes,
+			cc = this.filterDefPane.cboxContainer,
+			total = this.plugin.args.ruleCount,
+			len = cbs.length, cbox;
+		//If overflow, add to max rule count.
+		if(total > 0 && len + cnt > total){
+			cnt = total - len;
 		}
-		var arr = typeDisabledConds.concat(colDisabledConds);
-		if(arr.length){
-			var disabledConds = {};
-			dojo.forEach(arr, function(c){
-				if(dojo.isString(c)){
-					disabledConds[c.toLowerCase()] = true;
-				}
-			});
-			return dojo.filter(conditions, function(condOption){
-				return !(condOption.value in disabledConds);
+		for(; cnt > 0; --cnt){
+			cbox = new CriteriaBox({
+				dlg: this
 			});
+			cbs.push(cbox);
+			cc.addChild(cbox);
 		}
-		return conditions;
-	},
-	_setConditionsByType: function(/* string */type){
-		var condSelect = this._condSelect;
-		condSelect.removeOption(condSelect.options);
-		condSelect.addOption(this._getUsableConditions(type));
-		this._showSelectOrLabel(this._condSelect, this._condSelectAlt);
-	},
-	_setValueBoxByType: function(/* string */type){
-		if(this._curValueBox){
-			this.valueNode.removeChild(this._curValueBox.domNode);
-			try{
-				this._curValueBox.destroyRecursive();
-			}catch(e){}
-			delete this._curValueBox;
+		//If there's no content box in it , AccordionContainer can not startup
+		cc.startup();
+		this._updatePane();
+		this._updateCBoxTitles();
+		cc.selectChild(cbs[cbs.length-1]);
+		//Asign an impossibly large scrollTop to scroll the criteria pane to the bottom.
+		this.filterDefPane.criteriaPane.scrollTop = 1000000;
+		if(cbs.length === 4){
+			if(has('ie') <= 6 && !this.__alreadyResizedForIE6){
+				var size = html.position(cc.domNode);
+				size.w -= metrics.getScrollbar().w;
+				cc.resize(size);
+				this.__alreadyResizedForIE6 = true;
+			}else{
+				cc.resize();
+			}
 		}
-		//value box class
-		var vbcls = this.dlg._dataTypeMap[type].valueBoxCls[this._getValueBoxClsInfo(this._colSelect.get("value"), type)],
-			vboxArg = this._getValueBoxArgByType(type);
-		this._curValueBox = this[this._isRange ? "_createRangeBox" : "_createValueBox"](vbcls, vboxArg);
-		this.valueNode.appendChild(this._curValueBox.domNode);
-		
-		//Can not move to setAriaInfo, 'cause the value box is created after the defpane is loaded.
-		dijit.setWaiState(this._curValueBox.domNode, "label", dojo.string.substitute(this.plugin.nls.waiValueBoxTemplate,[this._index]));
-		//Now our cbox is completely ready
-		this.dlg.onRendered(this);
 	},
-	//--------------------------UI Configuration--------------------------------------
-	_getValueBoxArgByType: function(/* string */type){
+	removeCriteriaBoxes: function(/* int|CriteriaBox|int[] */cnt,/* bool? */isIdx){
 		// summary:
-		//		Get the arguments for the value box construction.
-		var g = this.plugin.grid,
-			cell = g.layout.cells[parseInt(this._colSelect.get("value"), 10)],
-			res = {
-				cbox: this
-			};
-		if(type == "string"){
-			if(cell && (cell.suggestion || cell.autoComplete)){
-				dojo.mixin(res, {
-					store: g.store,
-					searchAttr: cell.field || cell.name,
-					fetchProperties: {
-						sort: [{"attribute": cell.field || cell.name}]
+		//		Remove criteria boxes from the filter definition pane.
+		var cbs = this._cboxes, cc = this.filterDefPane.cboxContainer,
+			len = cbs.length, start = len - cnt,
+			end = len - 1, cbox,
+			curIdx = array.indexOf(cbs, cc.selectedChildWidget.content);
+		if(lang.isArray(cnt)){
+			var i, idxes = cnt;
+			idxes.sort();
+			cnt = idxes.length;
+			//find a rule that's not deleted.
+			//must find and focus the last one, or the hack will not work.
+			for(i = len - 1; i >= 0 && array.indexOf(idxes, i) >= 0; --i){}
+			if(i >= 0){
+				//must select before remove
+				if(i != curIdx){
+					cc.selectChild(cbs[i]);
+				}
+				//idxes is sorted from small to large,
+				//so travel reversely won't need change index after delete from array.
+				for(i = cnt-1; i >= 0; --i){
+					if(idxes[i] >= 0 && idxes[i] < len){
+						cc.removeChild(cbs[idxes[i]]);
+						cbs.splice(idxes[i],1);
 					}
-				});
+				}
 			}
-		}else if(type == "boolean"){
-			dojo.mixin(res, this.dlg.builder.defaultArgs["boolean"]);
+			start = cbs.length;
+		}else{
+			if(isIdx === true){
+				if(cnt >= 0 && cnt < len){
+					start = end = cnt;
+					cnt = 1;
+				}else{
+					return;
+				}
+			}else{
+				if(cnt instanceof CriteriaBox){
+					cbox = cnt;
+					cnt = 1;
+					start = end = array.indexOf(cbs, cbox);
+				}else if(typeof cnt != "number" || cnt <= 0){
+					return;
+				}else if(cnt >= len){
+					cnt = end;
+					start = 1;
+				}
+			}
+			if(end < start){
+				return;
+			}
+			//must select before remove
+			if(curIdx >= start && curIdx <= end){
+				cc.selectChild(cbs[start ? start-1 : end+1]);
+			}
+			for(; end >= start; --end){
+				cc.removeChild(cbs[end]);
+			}
+			cbs.splice(start, cnt);
 		}
-		if(cell && cell.dataTypeArgs){
-			dojo.mixin(res, cell.dataTypeArgs);
+		this._updatePane();
+		this._updateCBoxTitles();
+		if(cbs.length === 3){
+			//In ie6, resize back to the normal width will cause the title button look strange.
+			cc.resize();
 		}
-		return res;
 	},
-	formatValue: function(type, cond, v){
+	getCriteria: function(/* int */idx){
 		// summary:
-		//		Format the value to be shown in tooltip.
-		if(cond == "isempty"){return "";}
-		if(type == "date" || type == "time"){
-			var opt = {selector: type},
-				fmt = dojo.date.locale.format;
-			if(cond == "range"){
-				return dojo.string.substitute(this.plugin.nls.rangeTemplate, [fmt(v.start, opt), fmt(v.end, opt)]);
-			}
-			return fmt(v, opt);
-		}else if(type == "boolean"){
-			return v ? this._curValueBox._lblTrue : this._curValueBox._lblFalse;
+		//		Get the *idx*-th criteria.
+		if(typeof idx != "number"){
+			return this._savedCriterias ? this._savedCriterias.length : 0;
 		}
-		return v;
+		if(this._savedCriterias && this._savedCriterias[idx]){
+			return lang.mixin({
+				relation: this._relOpCls == "logicall" ? this.plugin.nls.and : this.plugin.nls.or
+			},this._savedCriterias[idx]);
+		}
+		return null;
 	},
-	_getValueBoxClsInfo: function(/* int|string */colIndex, /* string */type){
-		// summary:
-		//		Decide which value box to use given data type and column index.
-		var cell = this.plugin.grid.layout.cells[parseInt(colIndex, 10)];
-		//Now we only need to handle string. But maybe we need to handle more types here in the future.
-		if(type == "string"){
-			return (cell && (cell.suggestion || cell.autoComplete)) ? "ac" : "dft";
+	getExprForCriteria: function(rule){
+		if(rule.column == "anycolumn"){
+			var cells = array.filter(this.plugin.grid.layout.cells, function(cell){
+				return !(cell.filterable === false || cell.hidden);
+			});
+			return {
+				"op": "logicany",
+				"data": array.map(cells, function(cell){
+					return this.getExprForColumn(rule.value, cell.index, rule.type, rule.condition);
+				}, this)
+			};
+		}else{
+			return this.getExprForColumn(rule.value, rule.column, rule.type, rule.condition);
 		}
-		return "dft";
-	}
-});
-dojo.declare("dojox.grid.enhanced.plugins.filter.AccordionContainer", dijit.layout.AccordionContainer, {
-	nls: null,
-	addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){
-		var pane = arguments[0] = child._pane = new dijit.layout.ContentPane({
-			content: child
-		});
-		this.inherited(arguments);
-		this._modifyChild(pane);
 	},
-	removeChild: function(child){
-		var pane = child, isRemoveByUser = false;
-		if(child._pane){
-			isRemoveByUser = true;
-			pane = arguments[0] = child._pane;
+	getExprForColumn: function(value, colIdx, type, condition){
+		colIdx = parseInt(colIdx, 10);
+		var cell = this.plugin.grid.layout.cells[colIdx],
+			colName = cell.field || cell.name,
+			obj = {
+				"datatype": type || this.getColumnType(colIdx),
+				"args": cell.dataTypeArgs,
+				"isColumn": true
+			},
+			operands = [lang.mixin({"data": this.plugin.args.isServerSide ? colName : cell}, obj)];
+		obj.isColumn = false;
+		if(condition == "range"){
+			operands.push(lang.mixin({"data": value.start}, obj),
+				lang.mixin({"data": value.end}, obj));
+		}else if(condition != "isempty"){
+			operands.push(lang.mixin({"data": value}, obj));
 		}
-		this.inherited(arguments);
-		if(isRemoveByUser){
-			this._hackHeight(false, this._titleHeight);
-			var children = this.getChildren();
-			if(children.length === 1){
-				dojo.style(children[0]._removeCBoxBtn.domNode, "display", "none");
-			}
+		return {
+			"op": condition,
+			"data": operands
+		};
+	},
+	getColumnType: function(/* int */colIndex){
+		var cell = this.plugin.grid.layout.cells[parseInt(colIndex, 10)];
+		if(!cell || !cell.datatype){
+			return this.defaultType;
 		}
-		pane.destroyRecursive();
+		var type = String(cell.datatype).toLowerCase();
+		return this._dataTypeMap[type] ? type : this.defaultType;
 	},
-	selectChild: function(child){
-		if(child._pane){
-			arguments[0] = child._pane;
+	//////////////////////////////////////////////////////////////////////////////////////////////////////////
+	clearFilter: function(noRefresh){
+		// summary:
+		//		Clear filter definition.
+		if(!this._savedCriterias){
+			return;
+		}
+		this._savedCriterias = null;
+		this.plugin.grid.layer("filter").filterDef(null);
+		try{
+			this.plugin.filterBar.toggleClearFilterBtn(true);
+			this.filterDefPane._clearFilterBtn.set("disabled", true);
+			this.removeCriteriaBoxes(this._cboxes.length-1);
+			this._cboxes[0].load({});
+		}catch(e){
+			//Any error means the filter is defined outside this plugin.
+		}
+		if(noRefresh){
+			this.closeDialog();
+		}else{
+			this._closeDlgAndUpdateGrid();
 		}
-		this.inherited(arguments);
 	},
-	resize: function(){
-		this.inherited(arguments);
-		dojo.forEach(this.getChildren(), this._setupTitleDom);
+	showDialog: function(/* int */colIndex){
+		// summary:
+		//		Show the filter defintion dialog.
+		this._defPane.show();
+		this.plugin.filterStatusTip.closeDialog();
+		this._prepareDialog(colIndex);
 	},
-	startup: function(){
-		if(this._started){
-			return;
+	closeDialog: function(){
+		// summary:
+		//		Close the filter definition dialog.
+		if(this._defPane.open){
+			this._defPane.hide();
 		}
-		this.inherited(arguments);
-		if(parseInt(dojo.isIE, 10) == 7){
-			//IE7 will fire a lot of "onresize" event during initialization.
-			dojo.some(this._connects, function(cnnt){
-				if(cnnt[0][1] == "onresize"){
-					this.disconnect(cnnt);
-					return true;
-				}
-			}, this);
+	},
+	onFilter: function(e){
+		// summary:
+		//		Triggered when the "Filter" button is clicked.
+		if(this.canFilter()){
+			this._defineFilter();
+			this._closeDlgAndUpdateGrid();
+			this.plugin.filterBar.toggleClearFilterBtn(false);
 		}
-		dojo.forEach(this.getChildren(), function(child){
-			this._modifyChild(child, true);
-		}, this);
 	},
-	_onKeyPress: function(/*Event*/ e, /*dijit._Widget*/ fromTitle){
+	onClearFilter: function(e){
 		// summary:
-		//		Overrides base class method, make left/right button do other things.
-		if(this.disabled || e.altKey || !(fromTitle || e.ctrlKey)){
-			return;
+		//		Triggered when the "Clear" button is clicked.
+		if(this._savedCriterias){
+			if(this._savedCriterias.length >= this.plugin.ruleCountToConfirmClearFilter){
+				this.plugin.clearFilterDialog.show();
+			}else{
+				this.clearFilter(this._clearWithoutRefresh);
+			}
 		}
-		var k = dojo.keys, c = e.charOrCode, ltr = dojo._isBodyLtr(), toNext = null;
-		if((fromTitle && c == k.UP_ARROW) || (e.ctrlKey && c == k.PAGE_UP)){
-			toNext = false;
-		}else if((fromTitle && c == k.DOWN_ARROW) || (e.ctrlKey && (c == k.PAGE_DOWN || c == k.TAB))){
-			toNext = true;
-		}else if(c == (ltr ? k.LEFT_ARROW : k.RIGHT_ARROW)){
-			toNext = this._focusOnRemoveBtn ? null : false;
-			this._focusOnRemoveBtn = !this._focusOnRemoveBtn;
-		}else if(c == (ltr ? k.RIGHT_ARROW : k.LEFT_ARROW)){
-			toNext = this._focusOnRemoveBtn ? true : null;
-			this._focusOnRemoveBtn = !this._focusOnRemoveBtn;
+	},
+	onCancel: function(e){
+		// summary:
+		//		Triggered when the "Cancel" buttton is clicked.
+		var sc = this._savedCriterias;
+		var cbs = this._cboxes;
+		if(sc){
+			this.addCriteriaBoxes(sc.length - cbs.length);
+			this.removeCriteriaBoxes(cbs.length - sc.length);
+			array.forEach(sc, function(c, i){
+				cbs[i].load(c);
+			});
 		}else{
-			return;
-		}
-		if(toNext !== null){
-			this._adjacent(toNext)._buttonWidget._onTitleClick();
+			this.removeCriteriaBoxes(cbs.length - 1);
+			cbs[0].load({});
 		}
-		dojo.stopEvent(e);
-		dojo.window.scrollIntoView(this.selectedChildWidget._buttonWidget.domNode.parentNode);
-		if(dojo.isIE){
-			//IE will not show focus indicator if tabIndex is -1
-			this.selectedChildWidget._removeCBoxBtn.focusNode.setAttribute("tabIndex", this._focusOnRemoveBtn ? _tabIdxes.accordionTitle : -1);
+		this.closeDialog();
+	},
+	onRendered: function(cbox){
+		// summary:
+		//		Triggered when the rendering of the filter definition dialog is completely finished.
+		// cbox:
+		//		Current visible criteria box
+		if(!has('ff')){
+			var elems = dijitA11y._getTabNavigable(html.byId(cbox.domNode));
+			dijitFocus.focus(elems.lowest || elems.first);
+		}else{
+			var dp = this._defPane;
+			dp._getFocusItems(dp.domNode);
+			dijitFocus.focus(dp._firstFocusItem);
 		}
-		dijit.focus(this.selectedChildWidget[this._focusOnRemoveBtn ? "_removeCBoxBtn" : "_buttonWidget"].focusNode);
 	},
-	_modifyChild: function(child, isFirst){
-		if(!child || !this._started){
-			return;
+	_onSetFilter: function(filterDef){
+		// summary:
+		//		If someone clear the filter def in the store directly, we must clear it in the UI.
+		//		If someone defines a filter, don't know how to handle it!
+		if(filterDef === null && this._savedCriterias){
+			this.clearFilter();
 		}
-		dojo.style(child.domNode, "overflow", "hidden");
-		child._buttonWidget.connect(child._buttonWidget, "_setSelectedAttr", function(){
-			this.focusNode.setAttribute("tabIndex", this.selected ? _tabIdxes.accordionTitle : "-1");
-		});
-		var _this = this;
-		child._buttonWidget.connect(child._buttonWidget.domNode, "onclick", function(){
-			_this._focusOnRemoveBtn = false;
-		});
-		(child._removeCBoxBtn = new dijit.form.Button({
-			label: this.nls.removeRuleButton,
-			showLabel: false,
-			iconClass: "dojoxGridFCBoxRemoveCBoxBtnIcon",
-			tabIndex: _tabIdxes.removeCBoxBtn,
-			onClick: dojo.hitch(child.content, "onRemove"),
-			onKeyPress: function(e){
-				_this._onKeyPress(e, child._buttonWidget.contentWidget);
-			}
-		})).placeAt(child._buttonWidget.domNode);
-		var i, children = this.getChildren();
-		if(children.length === 1){
-			child._buttonWidget.set("selected", true);
-			dojo.style(child._removeCBoxBtn.domNode, "display", "none");
-		}else{
-			for(i = 0; i < children.length; ++i){
-				if(children[i]._removeCBoxBtn){
-					dojo.style(children[i]._removeCBoxBtn.domNode, "display", "");
+	},
+	_prepareDialog: function(/* int */colIndex){
+		var sc = this._savedCriterias,
+			cbs = this._cboxes, i, cbox;
+		this.curColIdx = colIndex;
+		if(!sc){
+			if(cbs.length === 0){
+				this.addCriteriaBoxes(1);
+			}else{
+				//Re-populate columns anyway, because we don't know when the column is set to hidden.
+				for(i = 0; (cbox = cbs[i]); ++i){
+					cbox.changeCurrentColumn();
 				}
 			}
-		}
-		this._setupTitleDom(child);
-		if(!this._titleHeight){
-			for(i = 0; i < children.length; ++i){
-				if(children[i] != this.selectedChildWidget){
-					this._titleHeight = dojo.marginBox(children[i]._buttonWidget.domNode.parentNode).h;
-					break;
-				}
+		}else if(this._criteriasChanged){
+			this.filterDefPane._relSelect.set("value", this._relOpCls === "logicall" ? "0" : "1");
+			this._criteriasChanged = false;
+			var needNewCBox = sc.length > cbs.length ? sc.length - cbs.length : 0;
+			this.addCriteriaBoxes(needNewCBox);
+			this.removeCriteriaBoxes(cbs.length - sc.length);
+			this.filterDefPane._clearFilterBtn.set("disabled", false);
+			for(i = 0; i < cbs.length - needNewCBox; ++i){
+				cbs[i].load(sc[i]);
+			}
+			if(needNewCBox > 0){
+				var handled = [], handle = connect.connect(this, "onRendered", function(cbox){
+					var i = array.indexOf(cbs, cbox);
+					if(!handled[i]){
+						handled[i] = true;
+						if(--needNewCBox === 0){
+							connect.disconnect(handle);
+						}
+						cbox.load(sc[i]);
+					}
+				});
 			}
 		}
-		if(!isFirst){
-			this._hackHeight(true, this._titleHeight);
-		}
-	},
-	_hackHeight: function(/* bool */toGrow,/* int */heightDif){
-		var children = this.getChildren(),
-			dn = this.domNode, h = dojo.style(dn, "height");
-		if(!toGrow){
-			dn.style.height = (h - heightDif) + 'px';
-		}else if(children.length > 1){
-			dn.style.height = (h + heightDif) + 'px';
-		}else{
-			//Only one rule, no need to do anything.
-			return;
-		}
-		this.resize();
+		//Since we're allowed to remove cboxes when the definition pane is not shown,
+		//we have to resize the container to have a correct _verticalSpace.
+		this.filterDefPane.cboxContainer.resize();
 	},
-	_setupTitleDom: function(child){
-		var w = dojo.contentBox(child._buttonWidget.titleNode).w;
-		if(dojo.isIE < 8){ w -= 8; }
-		dojo.style(child._buttonWidget.titleTextNode, "width", w + "px");
-	}
-});
-dojo.declare("dojox.grid.enhanced.plugins.filter.UniqueComboBox", dijit.form.ComboBox, {
-	_openResultList: function(results){
-		var cache = {}, s = this.store, colName = this.searchAttr;
-		arguments[0] = dojo.filter(results, function(item){
-			var key = s.getValue(item, colName), existed = cache[key];
-			cache[key] = true;
-			return !existed;
-		});
-		this.inherited(arguments);
+	_defineFilter: function(){
+		var cbs = this._cboxes,
+			filterCboxes = function(method){
+				return array.filter(array.map(cbs, function(cbox){
+					return cbox[method]();
+				}), function(result){
+					return !!result;
+				});
+			},
+			exprs = filterCboxes("getExpr");
+		this._savedCriterias = filterCboxes("save");
+		exprs = exprs.length == 1 ? exprs[0] : {
+			"op": this._relOpCls,
+			"data": exprs
+		};
+		exprs = this.builder.buildExpression(exprs);
+		
+		this.plugin.grid.layer("filter").filterDef(exprs);
+		this.filterDefPane._clearFilterBtn.set("disabled", false);
 	},
-	_onKey: function(evt){
-		if(evt.charOrCode === dojo.keys.ENTER && this._opened){
-			dojo.stopEvent(evt);
+	_updateCBoxTitles: function(){
+		for(var cbs = this._cboxes, i = cbs.length; i > 0; --i){
+			cbs[i - 1].updateRuleIndex(i);
+			cbs[i - 1].setAriaInfo(i);
 		}
-		this.inherited(arguments);
-	}
-});
-dojo.declare("dojox.grid.enhanced.plugins.filter.BooleanValueBox", [dijit._Widget, dijit._Templated], {
-	templateString: dojo.cache("dojox.grid","enhanced/templates/FilterBoolValueBox.html"),
-	widgetsInTemplate: true,
-	constructor: function(args){
-		var nls = args.cbox.plugin.nls;
-		this._baseId = args.cbox.id;
-		this._lblTrue = args.trueLabel || nls.trueLabel || "true";
-		this._lblFalse = args.falseLabel || nls.falseLabel || "false";
-		this.args = args;
 	},
-	postCreate: function(){
-		this.onChange();
+	_updatePane: function(){
+		var cbs = this._cboxes,
+			defPane = this.filterDefPane;
+		defPane._addCBoxBtn.set("disabled", cbs.length == this.plugin.args.ruleCount);
+		defPane._filterBtn.set("disabled", !this.canFilter());
 	},
-	onChange: function(){},
-	
-	get: function(prop){
-		return this.rbTrue.get("checked");
+	canFilter: function(){
+		return array.filter(this._cboxes, function(cbox){
+			return !cbox.isEmpty();
+		}).length > 0;
 	},
-	set: function(prop, v){
-		this.inherited(arguments);
-		if(prop == "value"){
-			this.rbTrue.set("checked", !!v);
-			this.rbFalse.set("checked", !v);
-		}
+	_closeDlgAndUpdateGrid: function(){
+		this.closeDialog();
+		var g = this.plugin.grid;
+		g.showMessage(g.loadingMessage);
+		setTimeout(lang.hitch(g, g._refresh), this._defPane.duration + 10);
 	}
 });
-})();
+
+return FilterDefDialog;
+});
diff --git a/dojox/grid/enhanced/plugins/filter/FilterLayer.js b/dojox/grid/enhanced/plugins/filter/FilterLayer.js
index d479379..bfc8281 100644
--- a/dojox/grid/enhanced/plugins/filter/FilterLayer.js
+++ b/dojox/grid/enhanced/plugins/filter/FilterLayer.js
@@ -1,25 +1,26 @@
-dojo.provide("dojox.grid.enhanced.plugins.filter.FilterLayer");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/_base/json",
+	"../_StoreLayer"
+], function(declare, lang, win, json, layers){
 
-dojo.require("dojox.grid.enhanced.plugins.filter._FilterExpr");
-dojo.require("dojox.grid.enhanced.plugins._StoreLayer");
-
-(function(){
-var ns = dojox.grid.enhanced.plugins,
-	cmdSetFilter = "filter",
-	cmdClearFilter = "clear",
-	hitchIfCan = function(scope, func){
-		return func ? dojo.hitch(scope || dojo.global, func) : function(){};
-	},
-	shallowClone = function(obj){
-		var res = {};
-		if(obj && dojo.isObject(obj)){
-			for(var name in obj){
-				res[name] = obj[name];
+	var cmdSetFilter = "filter",
+		cmdClearFilter = "clear",
+		hitchIfCan = function(scope, func){
+			return func ? lang.hitch(scope || win.global, func) : function(){};
+		},
+		shallowClone = function(obj){
+			var res = {};
+			if(obj && lang.isObject(obj)){
+				for(var name in obj){
+					res[name] = obj[name];
+				}
 			}
-		}
-		return res;
-	};
-	dojo.declare("dojox.grid.enhanced.plugins.filter._FilterLayerMixin", null, {
+			return res;
+		};
+	var _FilterLayerMixin = declare("dojox.grid.enhanced.plugins.filter._FilterLayerMixin", null, {
 /*=====
 		// _filter: _ConditionExpr
 		//		The filter definition
@@ -56,7 +57,7 @@ var ns = dojox.grid.enhanced.plugins,
 			//		The number of original fetched items.
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.ServerSideFilterLayer", [ns._ServerSideLayer, ns.filter._FilterLayerMixin], {
+	var ServerSideFilterLayer = declare("dojox.grid.enhanced.plugins.filter.ServerSideFilterLayer", [layers._ServerSideLayer, _FilterLayerMixin], {
 		constructor: function(args){
 			this._onUserCommandLoad = args.setupFilterQuery || this._onUserCommandLoad;
 			this.filterDef(null);
@@ -68,7 +69,7 @@ var ns = dojox.grid.enhanced.plugins,
 				this._filter = filter;
 				var obj = filter.toObject();
 				//Stateless implementation will need to parse the filter object.
-				this.command(cmdSetFilter, this._isStateful ? dojo.toJson(obj) : obj);
+				this.command(cmdSetFilter, this._isStateful ? json.toJson(obj) : obj);
 				this.command(cmdClearFilter, null);
 				this.useCommands(true);
 				this.onFilterDefined(filter);
@@ -121,7 +122,7 @@ var ns = dojox.grid.enhanced.plugins,
 			}
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.ClientSideFilterLayer", [ns._StoreLayer, ns.filter._FilterLayerMixin], {
+	var ClientSideFilterLayer = declare("dojox.grid.enhanced.plugins.filter.ClientSideFilterLayer", [layers._StoreLayer, _FilterLayerMixin], {
 		// summary:
 		//		Add a client side filter layer on top of the data store,
 		//		so any filter expression can be applied to the store.
@@ -161,9 +162,9 @@ var ns = dojox.grid.enhanced.plugins,
 		
 		constructor: function(args){
 			this.filterDef(null);
-			args = dojo.isObject(args) ? args : {};
+			args = lang.isObject(args) ? args : {};
 			this.fetchAllOnFirstFilter(args.fetchAll);
-			this._getter = dojo.isFunction(args.getter) ? args.getter : this._defaultGetter;
+			this._getter = lang.isFunction(args.getter) ? args.getter : this._defaultGetter;
 		},
 		_defaultGetter: function(datarow, colName, rowIndex, store){
 			return store.getValue(datarow, colName);
@@ -184,7 +185,7 @@ var ns = dojox.grid.enhanced.plugins,
 			// tags:
 			//		public
 			// getter: function(datarow, colArg, rowIndex, store);
-			if(dojo.isFunction(getter)){
+			if(lang.isFunction(getter)){
 				this._getter = getter;
 			}
 		},
@@ -244,9 +245,9 @@ var ns = dojox.grid.enhanced.plugins,
 					this._result = [];
 					this._resultStartIdx = start;
 					var sortStr;
-					if(dojo.isArray(userRequest.sort) && userRequest.sort.length > 0 &&
+					if(lang.isArray(userRequest.sort) && userRequest.sort.length > 0 &&
 						//Sort info will stay here in every re-fetch, so remember it!
-						(sortStr = dojo.toJson(userRequest.sort)) != this._lastSortInfo){
+						(sortStr = json.toJson(userRequest.sort)) != this._lastSortInfo){
 						//If we should sort data, all the old caches are no longer valid.
 						this.invalidate();
 						this._lastSortInfo = sortStr;
@@ -272,8 +273,8 @@ var ns = dojox.grid.enhanced.plugins,
 						//Initially, we've got to create a new request object.
 						filterRequest = shallowClone(userRequest);
 						//Use our own onBegin function to remember the total size of the original store.
-						filterRequest.onBegin = dojo.hitch(this, this._onFetchBegin);
-						filterRequest.onComplete = dojo.hitch(this, function(items, req){
+						filterRequest.onBegin = lang.hitch(this, this._onFetchBegin);
+						filterRequest.onComplete = lang.hitch(this, function(items, req){
 							//We've fetched some more, so march ahead!
 							this._nextUnfetchedIdx += items.length;
 							//Actual filtering work goes here. Survived items are added to our cache.
@@ -374,7 +375,7 @@ var ns = dojox.grid.enhanced.plugins,
 			//		Data items to add.
 			// filterStartIdx: Integer
 			//		The start point to insert in the cache.
-			if(!dojo.isArray(items)){
+			if(!lang.isArray(items)){
 				items = [items];
 			}
 			for(var k = 0; k < items.length; ++k){
@@ -385,7 +386,7 @@ var ns = dojox.grid.enhanced.plugins,
 		onRowMappingChange: function(mapping){
 			//This function runs in FilterLayer scope!
 			if(this._filter){
-				var m = dojo.clone(mapping),
+				var m = lang.clone(mapping),
 					alreadyUpdated = {};
 				for(var r in m){
 					r = parseInt(r, 10);
@@ -401,4 +402,9 @@ var ns = dojox.grid.enhanced.plugins,
 			}
 		}
 	});
-})();
+
+	return lang.mixin({
+		ServerSideFilterLayer: ServerSideFilterLayer,
+		ClientSideFilterLayer: ClientSideFilterLayer
+	}, layers);
+});
diff --git a/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js b/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js
index e37e718..6d8efb3 100644
--- a/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js
+++ b/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js
@@ -1,21 +1,33 @@
-dojo.provide("dojox.grid.enhanced.plugins.filter.FilterStatusTip");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/query",
+	"dojo/cache",
+	"dojo/string",
+	"dojo/date/locale",
+	"dijit/_Widget", 
+	"dijit/_TemplatedMixin", 
+	"dijit/_WidgetsInTemplateMixin", 
+	"dijit/TooltipDialog",
+	"dijit/form/Button",
+	"dijit/_base/popup",
+	"dojo/i18n!../../nls/Filter"
+], function(declare, array, lang, query, cache, string, dateLocale, _Widget, 
+	_TemplatedMixin, _WidgetsInTemplateMixin, TooltipDialog, Button, popup){
 
-dojo.requireLocalization("dojox.grid.enhanced", "Filter");
-dojo.require("dijit.TooltipDialog");
-dojo.require("dijit._base.popup");
-dojo.require("dijit.form.Button");
-dojo.require("dojo.string");
-dojo.require("dojo.date.locale");
+	var gridCssCls = "", headerCssCls = "", cellCssCls = "", rowCssCls = "",
+		oddRowCssCls = "dojoxGridFStatusTipOddRow",
+		handleHolderCssCls = "dojoxGridFStatusTipHandle",
+		conditionCssCls = "dojoxGridFStatusTipCondition",
+		_removeRuleIconCls = "dojoxGridFStatusTipDelRuleBtnIcon",
+		_statusFooter = "</tbody></table>";
 
-(function(){
-var gridCssCls = "", headerCssCls = "", cellCssCls = "", rowCssCls = "",
-	oddRowCssCls = "dojoxGridFStatusTipOddRow",
-	handleHolderCssCls = "dojoxGridFStatusTipHandle",
-	conditionCssCls = "dojoxGridFStatusTipCondition",
-	_removeRuleIconCls = "dojoxGridFStatusTipDelRuleBtnIcon",
-	_statusFooter = "</tbody></table>";
-	
-	dojo.declare("dojox.grid.enhanced.plugins.filter.FilterStatusTip", null, {
+	var FilterStatusPane = declare("dojox.grid.enhanced.plugins.filter.FilterStatusPane", [_Widget, _TemplatedMixin], {
+		templateString: cache("dojox.grid", "enhanced/templates/FilterStatusPane.html")
+	});
+
+	return declare("dojox.grid.enhanced.plugins.filter.FilterStatusTip", null, {
 		// summary:
 		//		Create the status tip UI.
 		constructor: function(args){
@@ -28,16 +40,14 @@ var gridCssCls = "", headerCssCls = "", cellCssCls = "", rowCssCls = "",
 			].join('');
 			this._removedCriterias = [];
 			this._rules = [];
-			this.statusPane = new dojox.grid.enhanced.plugins.filter.FilterStatusPane();
-			this._dlg = new dijit.TooltipDialog({
+			this.statusPane = new FilterStatusPane();
+			this._dlg = new TooltipDialog({
 				"class": "dojoxGridFStatusTipDialog",
 				content: this.statusPane,
-				autofocus: false,
-				onMouseLeave: dojo.hitch(this,function(){
-					this.closeDialog();
-				})
+				autofocus: false
 			});
-			this._dlg.connect(this._dlg.domNode,"click", dojo.hitch(this, this._modifyFilter));
+			this._dlg.connect(this._dlg.domNode, 'onmouseleave', lang.hitch(this, this.closeDialog));
+			this._dlg.connect(this._dlg.domNode, 'click', lang.hitch(this, this._modifyFilter));
 		},
 		destroy: function(){
 			this._dlg.destroyRecursive();
@@ -45,19 +55,20 @@ var gridCssCls = "", headerCssCls = "", cellCssCls = "", rowCssCls = "",
 		//-----------------Public Functions------------------------
 		showDialog: function(/* int */pos_x,/* int */pos_y, columnIdx){
 			this._pos = {x:pos_x,y:pos_y};
-			dijit.popup.close(this._dlg);
+			popup.close(this._dlg);
 			this._removedCriterias = [];
 			this._rules = [];
 			this._updateStatus(columnIdx);
-			dijit.popup.open({
+			popup.open({
 				popup: this._dlg,
 				parent: this.plugin.filterBar,
+				onCancel: function(){},
 				x:pos_x - 12,
 				y:pos_y - 3
 			});
 		},
 		closeDialog: function(){
-			dijit.popup.close(this._dlg);
+			popup.close(this._dlg);
 			if(this._removedCriterias.length){
 				this.plugin.filterDefDialog.removeCriteriaBoxes(this._removedCriterias);
 				this._removedCriterias = [];
@@ -72,16 +83,13 @@ var gridCssCls = "", headerCssCls = "", cellCssCls = "", rowCssCls = "",
 				fdg = p.filterDefDialog;
 			if(fdg.getCriteria() === 0){
 				sp.statusTitle.innerHTML = nls["statusTipTitleNoFilter"];
-				sp.statusRel.innerHTML = sp.statusRelPre.innerHTML = sp.statusRelPost.innerHTML = "";
+				sp.statusRel.innerHTML = "";
 				var cell = p.grid.layout.cells[columnIdx];
 				var colName = cell ? "'" + (cell.name || cell.field) + "'" : nls["anycolumn"];
-				res = dojo.string.substitute(nls["statusTipMsg"], [colName]);
+				res = string.substitute(nls["statusTipMsg"], [colName]);
 			}else{
 				sp.statusTitle.innerHTML = nls["statusTipTitleHasFilter"];
-				sp.statusRelPre.innerHTML = nls["statusTipRelPre"] + " ";
-				sp.statusRelPost.innerHTML = " " + nls["statusTipRelPost"];
-				sp.statusRel.innerHTML = fdg._relOpCls == "logicall" ? nls["all"] : nls["any"];
-				
+				sp.statusRel.innerHTML = fdg._relOpCls == "logicall" ? nls["statusTipRelAll"] : nls["statusTipRelAny"];
 				this._rules = [];
 				var i = 0, c = fdg.getCriteria(i++);
 				while(c){
@@ -95,18 +103,18 @@ var gridCssCls = "", headerCssCls = "", cellCssCls = "", rowCssCls = "",
 			this._addButtonForRules();
 		},
 		_createStatusDetail: function(){
-			return this._statusHeader + dojo.map(this._rules, function(rule, i){
+			return this._statusHeader + array.map(this._rules, function(rule, i){
 				return this._getCriteriaStr(rule, i);
 			}, this).join('') + _statusFooter;
 		},
 		_addButtonForRules: function(){
 			if(this._rules.length > 1){
-				dojo.query("." + handleHolderCssCls, this.statusPane.statusDetailNode).forEach(dojo.hitch(this, function(nd, idx){
-					(new dijit.form.Button({
+				query("." + handleHolderCssCls, this.statusPane.statusDetailNode).forEach(lang.hitch(this, function(nd, idx){
+					(new Button({
 						label: this.plugin.nls["removeRuleButton"],
 						showLabel: false,
 						iconClass: _removeRuleIconCls,
-						onClick: dojo.hitch(this, function(e){
+						onClick: lang.hitch(this, function(e){
 							e.stopPropagation();
 							this._removedCriterias.push(this._rules[idx].index);
 							this._rules.splice(idx,1);
@@ -133,7 +141,7 @@ var gridCssCls = "", headerCssCls = "", cellCssCls = "", rowCssCls = "",
 			p.filterDefDialog.showDialog(p.filterBar.getColumnIdx(this._pos.x));
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.FilterStatusPane", [dijit._Widget, dijit._Templated], {
-		templateString: dojo.cache("dojox.grid", "enhanced/templates/FilterStatusPane.html")
-	});
-})();
+	
+
+	return FilterStatusTip;
+});
diff --git a/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js b/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js
index 6ae9325..0fb3b6b 100644
--- a/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js
+++ b/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js
@@ -1,9 +1,10 @@
-dojo.provide("dojox.grid.enhanced.plugins.filter._ConditionExpr");
-
-(function(){
-	var fns = dojox.grid.enhanced.plugins.filter;
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/array"
+], function(declare, lang, array){
 	
-dojo.declare("dojox.grid.enhanced.plugins.filter._ConditionExpr",null,{
+var _ConditionExpr = declare("dojox.grid.enhanced.plugins.filter._ConditionExpr", null, {
 	// summary:
 	//		The most abstract class for all condition expressions.
 	//		A condition expression can be applied on a data row (e.g. an item in a store)
@@ -12,6 +13,7 @@ dojo.declare("dojox.grid.enhanced.plugins.filter._ConditionExpr",null,{
 	//		abstract
 	
 	_name: "expr",
+
 	applyRow: function(/* data item */datarow,/* function(row,colArg) */getter){
 		// summary:
 		//		*Unimplemented Interface*
@@ -28,6 +30,7 @@ dojo.declare("dojox.grid.enhanced.plugins.filter._ConditionExpr",null,{
 		//		MUST return a _ConditionExpr object
 		throw new Error("_ConditionExpr.applyRow: unimplemented interface");
 	},
+
 	toObject: function(){
 		// summary:
 		//		Convert this data expression to a simple object. Mainly used for serialization.
@@ -37,6 +40,7 @@ dojo.declare("dojox.grid.enhanced.plugins.filter._ConditionExpr",null,{
 		//		An object for serialization.
 		return {};	//Object
 	},
+
 	getName: function(){
 		// summary:
 		//		Get the name of this kind of expression.
@@ -47,7 +51,8 @@ dojo.declare("dojox.grid.enhanced.plugins.filter._ConditionExpr",null,{
 		return this._name;	//String
 	}
 });
-dojo.declare("dojox.grid.enhanced.plugins.filter._DataExpr", fns._ConditionExpr, {
+
+var _DataExpr = declare("dojox.grid.enhanced.plugins.filter._DataExpr", _ConditionExpr, {
 	// summary:
 	//		The most abstract class for all data expressions.
 	//		A _DataExpr is a condition expression for a single data value.
@@ -59,6 +64,7 @@ dojo.declare("dojox.grid.enhanced.plugins.filter._DataExpr", fns._ConditionExpr,
 	//		_value: anything
 	//		_colArg: anything
 	_name: "data",
+
 	constructor: function(/* anything */dataValue,/* bool */isColumn, /* object */convertArgs){
 		// summary:
 		//		If a _DataExpr is constructed with only one argument, this argument is regarded as a pure value.
@@ -72,8 +78,8 @@ dojo.declare("dojox.grid.enhanced.plugins.filter._DataExpr", fns._ConditionExpr,
 		// isColumn: boolean?
 		//		Optional. To specify whether this _DataExpr represents a column or a pure value.
 		this._convertArgs = convertArgs || {};
-		if(dojo.isFunction(this._convertArgs.convert)){
-			this._convertData = dojo.hitch(this._convertArgs.scope, this._convertArgs.convert);
+		if(lang.isFunction(this._convertArgs.convert)){
+			this._convertData = lang.hitch(this._convertArgs.scope, this._convertArgs.convert);
 		}
 		if(isColumn){
 			this._colArg = dataValue;
@@ -81,6 +87,7 @@ dojo.declare("dojox.grid.enhanced.plugins.filter._DataExpr", fns._ConditionExpr,
 			this._value = this._convertData(dataValue, this._convertArgs);
 		}
 	},
+
 	getValue: function(){
 		// summary:
 		//		If this is a pure value wrapper, simply return the value.
@@ -91,6 +98,7 @@ dojo.declare("dojox.grid.enhanced.plugins.filter._DataExpr", fns._ConditionExpr,
 		//		the value of this data expression.
 		return this._value;	//String
 	},
+
 	applyRow: function(/* data item */datarow,/* function(row,colIdx) */getter){
 		// summary:
 		//		Implement _ConditionExpr.applyRow.
@@ -98,10 +106,11 @@ dojo.declare("dojox.grid.enhanced.plugins.filter._DataExpr", fns._ConditionExpr,
 		//		Otherwise, extract the cell data from datarow using the given getter function,
 		//		and then convert this cell data to a _DataExpr and return the expression.
 		return typeof this._colArg == "undefined" ? this :			//_ConditionExpr
-			new (dojo.getObject(this.declaredClass))(
+			new (lang.getObject(this.declaredClass))(
 				this._convertData(getter(datarow, this._colArg), this._convertArgs)
 			);
 	},
+
 	_convertData: function(/* anything */dataValue){
 		// summary:
 		//
@@ -112,6 +121,7 @@ dojo.declare("dojox.grid.enhanced.plugins.filter._DataExpr", fns._ConditionExpr,
 		// returns:
 		return dataValue;
 	},
+
 	toObject: function(){
 		// summary:
 		//		Overrided from _ConditionExpr.toObject
@@ -122,17 +132,19 @@ dojo.declare("dojox.grid.enhanced.plugins.filter._DataExpr", fns._ConditionExpr,
 		};
 	}
 });
-dojo.declare("dojox.grid.enhanced.plugins.filter._OperatorExpr", fns._ConditionExpr, {
+
+var _OperatorExpr = declare("dojox.grid.enhanced.plugins.filter._OperatorExpr", _ConditionExpr, {
 	// summary:
 	//		The most abstract class for all operator expressions.
 	//		An operator expression is a _ConditionExpr that represents an operation.
 	_name: "operator",
+
 	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.
 		//		Every operand should be a _ConditionExpr.
-		if(dojo.isArray(arguments[0])){
+		if(lang.isArray(arguments[0])){
 			this._operands = arguments[0];
 		}else{
 			this._operands = [];
@@ -146,27 +158,30 @@ dojo.declare("dojox.grid.enhanced.plugins.filter._OperatorExpr", fns._ConditionE
 		//		Overrided from _ConditionExpr.toObject
 		return {											//Object
 			op: this.getName(),
-			data: dojo.map(this._operands,function(operand){
+			data: array.map(this._operands,function(operand){
 				return operand.toObject();
 			})
 		};
 	}
 });
-dojo.declare("dojox.grid.enhanced.plugins.filter._UniOpExpr", fns._OperatorExpr, {
+
+var _UniOpExpr = declare("dojox.grid.enhanced.plugins.filter._UniOpExpr", _OperatorExpr, {
 	// summary:
 	//		The most abstract class for all uni-operator expressions.
 	//		A uni-operator expression is an _OperatorExpr that only allow one operand.
 	_name: "uniOperator",
+
 	applyRow: function(/* data item */datarow,/* function(row,colArg) */getter){
 		// summary:
 		//		Implement _ConditionExpr.applyRow.
 		//		Apply the restriction of "only one operand" and confirm the operand is a valid _ConditionExpr.
 		//		Then do the calculation of this operator.
-		if(!(this._operands[0] instanceof fns._ConditionExpr)){
+		if(!(this._operands[0] instanceof _ConditionExpr)){
 			throw new Error("_UniOpExpr: operand is not expression.");
 		}
 		return this._calculate(this._operands[0],datarow,getter);	//_ConditionExpr
 	},
+
 	_calculate: function(/* _ConditionExpr */operand,/* data item*/datarow,/* function(row,colArg) */getter){
 		// summary:
 		//		*Unimplemented Interface*
@@ -181,22 +196,25 @@ dojo.declare("dojox.grid.enhanced.plugins.filter._UniOpExpr", fns._OperatorExpr,
 		throw new Error("_UniOpExpr._calculate: unimplemented interface");
 	}
 });
-dojo.declare("dojox.grid.enhanced.plugins.filter._BiOpExpr", fns._OperatorExpr, {
+
+var _BiOpExpr = declare("dojox.grid.enhanced.plugins.filter._BiOpExpr", _OperatorExpr, {
 	// summary:
 	//		The most abstract class for all bi-operator expressions.
 	//		A bi-operator expression is an _OperatorExpr that allow and only allow two operands.
 	_name: "biOperator",
+
 	applyRow: function(/* data item */datarow,/* function(row,colArg) */getter){
 		// summary:
 		//		Implement _ConditionExpr.applyRow.
 		//		Apply the restriction of "two operands" and confirm operands are valid _ConditionExpr's.
-		if(!(this._operands[0] instanceof fns._ConditionExpr)){
+		if(!(this._operands[0] instanceof _ConditionExpr)){
 			throw new Error("_BiOpExpr: left operand is not expression.");
-		}else if(!(this._operands[1] instanceof fns._ConditionExpr)){
+		}else if(!(this._operands[1] instanceof _ConditionExpr)){
 			throw new Error("_BiOpExpr: right operand is not expression.");
 		}
 		return this._calculate(this._operands[0],this._operands[1],datarow,getter);
 	},
+
 	_calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,/* data item*/datarow,/* function(row,colArg) */getter){
 		// summary:
 		//		*Unimplemented Interface*
@@ -212,4 +230,13 @@ dojo.declare("dojox.grid.enhanced.plugins.filter._BiOpExpr", fns._OperatorExpr,
 		throw new Error("_BiOpExpr._calculate: unimplemented interface");
 	}
 });
-})();
+
+return {
+	_ConditionExpr: _ConditionExpr,
+	_DataExpr: _DataExpr,
+	_OperatorExpr: _OperatorExpr,
+	_UniOpExpr: _UniOpExpr,
+	_BiOpExpr: _BiOpExpr
+};
+
+});
diff --git a/dojox/grid/enhanced/plugins/filter/_DataExprs.js b/dojox/grid/enhanced/plugins/filter/_DataExprs.js
index 387db38..29a6650 100644
--- a/dojox/grid/enhanced/plugins/filter/_DataExprs.js
+++ b/dojox/grid/enhanced/plugins/filter/_DataExprs.js
@@ -1,12 +1,11 @@
-dojo.provide("dojox.grid.enhanced.plugins.filter._DataExprs");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/date/locale",
+	"./_ConditionExpr"
+], function(declare, lang, dateLocale, exprs){
 
-dojo.require("dojox.grid.enhanced.plugins.filter._ConditionExpr");
-dojo.require("dojo.date.locale");
-
-(function(){
-	var fns = dojox.grid.enhanced.plugins.filter;
-
-	dojo.declare("dojox.grid.enhanced.plugins.filter.BooleanExpr", fns._DataExpr, {
+	var BooleanExpr = declare("dojox.grid.enhanced.plugins.filter.BooleanExpr", exprs._DataExpr, {
 		// summary:
 		//		A condition expression wrapper for boolean values
 		_name: "bool",
@@ -16,7 +15,7 @@ dojo.require("dojo.date.locale");
 			return !!dataValue;	//Boolean
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.StringExpr", fns._DataExpr, {
+	var StringExpr = declare("dojox.grid.enhanced.plugins.filter.StringExpr", exprs._DataExpr, {
 		// summary:
 		//		A condition expression wrapper for string values
 		_name: "string",
@@ -26,7 +25,7 @@ dojo.require("dojo.date.locale");
 			return String(dataValue);	//String
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.NumberExpr", fns._DataExpr, {
+	var NumberExpr = declare("dojox.grid.enhanced.plugins.filter.NumberExpr", exprs._DataExpr, {
 		// summary:
 		//		A condition expression wrapper for number values
 		_name: "number",
@@ -36,7 +35,7 @@ dojo.require("dojo.date.locale");
 			return parseFloat(dataValue);	//Number
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.DateExpr", fns._DataExpr, {
+	var DateExpr = declare("dojox.grid.enhanced.plugins.filter.DateExpr", exprs._DataExpr, {
 		// summary:
 		//		A condition expression wrapper for date values
 		_name: "date",
@@ -48,7 +47,7 @@ dojo.require("dojo.date.locale");
 			}else if(typeof dataValue == "number"){
 				return new Date(dataValue);
 			}else{
-				var res = dojo.date.locale.parse(String(dataValue), dojo.mixin({selector: this._name}, this._convertArgs));
+				var res = dateLocale.parse(String(dataValue), lang.mixin({selector: this._name}, this._convertArgs));
 				if(!res){
 					throw new Error("Datetime parse failed: " + dataValue);
 				}
@@ -69,10 +68,17 @@ dojo.require("dojo.date.locale");
 			}
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.TimeExpr", fns.DateExpr, {
+	var TimeExpr = declare("dojox.grid.enhanced.plugins.filter.TimeExpr", DateExpr, {
 		// summary:
 		//		A condition expression wrapper for time values
 		_name: "time"
 	});
-})();
 
+	return lang.mixin({
+		BooleanExpr: BooleanExpr,
+		StringExpr: StringExpr,
+		NumberExpr: NumberExpr,
+		DateExpr: DateExpr,
+		TimeExpr: TimeExpr
+	}, exprs);
+});
diff --git a/dojox/grid/enhanced/plugins/filter/_FilterExpr.js b/dojox/grid/enhanced/plugins/filter/_FilterExpr.js
index b8c545e..8ab4ab2 100644
--- a/dojox/grid/enhanced/plugins/filter/_FilterExpr.js
+++ b/dojox/grid/enhanced/plugins/filter/_FilterExpr.js
@@ -1,13 +1,13 @@
-dojo.provide("dojox.grid.enhanced.plugins.filter._FilterExpr");
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/date",
+	"./_DataExprs"
+], function(declare, lang, date, exprs){
 //This is the main file that should be 'required' if filter expression facility is necessary.
 
-dojo.require("dojox.grid.enhanced.plugins.filter._DataExprs");
-dojo.require("dojo.date");
-
-(function(){
-	var fns = dojox.grid.enhanced.plugins.filter;
 	/* Logic Operations */
-	dojo.declare("dojox.grid.enhanced.plugins.filter.LogicAND", fns._BiOpExpr, {
+	var LogicAND = declare("dojox.grid.enhanced.plugins.filter.LogicAND", exprs._BiOpExpr, {
 		// summary:
 		//		A logic AND condition expression.
 		_name: "and",
@@ -17,10 +17,10 @@ dojo.require("dojo.date");
 			//		Override from _BiOpExpr
 			var res = left_operand.applyRow(datarow, getter).getValue() &&
 				right_operand.applyRow(datarow, getter).getValue();
-			return new fns.BooleanExpr(res);	//_ConditionExpr
+			return new exprs.BooleanExpr(res);	//_ConditionExpr
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.LogicOR", fns._BiOpExpr, {
+	var LogicOR = declare("dojox.grid.enhanced.plugins.filter.LogicOR", exprs._BiOpExpr, {
 		// summary:
 		//		A logic OR condition expression.
 		_name: "or",
@@ -30,10 +30,10 @@ dojo.require("dojo.date");
 			//		Override from _BiOpExpr
 			var res = left_operand.applyRow(datarow, getter).getValue() ||
 				right_operand.applyRow(datarow, getter).getValue();
-			return new fns.BooleanExpr(res);	//_ConditionExpr
+			return new exprs.BooleanExpr(res);	//_ConditionExpr
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.LogicXOR", fns._BiOpExpr, {
+	var LogicXOR = declare("dojox.grid.enhanced.plugins.filter.LogicXOR", exprs._BiOpExpr, {
 		// summary:
 		//		A logic XOR condition expression.
 		_name: "xor",
@@ -43,41 +43,41 @@ dojo.require("dojo.date");
 			//		Override from _BiOpExpr
 			var left_res = left_operand.applyRow(datarow, getter).getValue();
 			var right_res = right_operand.applyRow(datarow, getter).getValue();
-			return new fns.BooleanExpr((!!left_res) != (!!right_res));	//_ConditionExpr
+			return new exprs.BooleanExpr((!!left_res) != (!!right_res));	//_ConditionExpr
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.LogicNOT", fns._UniOpExpr, {
+	var LogicNOT = declare("dojox.grid.enhanced.plugins.filter.LogicNOT", exprs._UniOpExpr, {
 		// summary:
 		//		A logic NOT condition expression.
 		_name: "not",
 		_calculate: function(/* _ConditionExpr */operand,/* data item*/datarow,/* function(row,colIdx) */getter){
 			// summary:
 			//		Override from _UniOpExpr
-			return new fns.BooleanExpr(!operand.applyRow(datarow, getter).getValue());	//_ConditionExpr
+			return new exprs.BooleanExpr(!operand.applyRow(datarow, getter).getValue());	//_ConditionExpr
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.LogicALL", fns._OperatorExpr, {
+	var LogicALL = declare("dojox.grid.enhanced.plugins.filter.LogicALL", exprs._OperatorExpr, {
 		// summary:
 		//		A logic ALL condition expression, equals a sequence of logic ANDs
 		_name: "all",
 		applyRow: function(/* data item */datarow,/* function(row,colIdx) */ getter){
 			// summary:
 			//		Override from _ConditionExpr
-			for(var i = 0, res = true; res && (this._operands[i] instanceof fns._ConditionExpr); ++i){
+			for(var i = 0, res = true; res && (this._operands[i] instanceof exprs._ConditionExpr); ++i){
 				res = this._operands[i].applyRow(datarow,getter).getValue();
 			}
-			return new fns.BooleanExpr(res);	//_ConditionExpr
+			return new exprs.BooleanExpr(res);	//_ConditionExpr
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.LogicANY", fns._OperatorExpr, {
+	var LogicANY = declare("dojox.grid.enhanced.plugins.filter.LogicANY", exprs._OperatorExpr, {
 		// summary:
 		//		A logic ANY condition expression, equals a sequence of logic ORs
 		_name: "any",
 		applyRow: function(/* data item */datarow,/* function(row,colIdx) */ getter){
-			for(var i = 0,res = false; !res && (this._operands[i] instanceof fns._ConditionExpr); ++i){
+			for(var i = 0,res = false; !res && (this._operands[i] instanceof exprs._ConditionExpr); ++i){
 				res = this._operands[i].applyRow(datarow,getter).getValue();
 			}
-			return new fns.BooleanExpr(res);	//_ConditionExpr
+			return new exprs.BooleanExpr(res);	//_ConditionExpr
 		}
 	});
 	
@@ -87,19 +87,19 @@ dojo.require("dojo.date");
 		right = right.applyRow(row, getter);
 		var left_res = left.getValue();
 		var right_res = right.getValue();
-		if(left instanceof fns.TimeExpr){
-			return dojo.date.compare(left_res,right_res,"time");
-		}else if(left instanceof fns.DateExpr){
-			return dojo.date.compare(left_res,right_res,"date");
+		if(left instanceof exprs.TimeExpr){
+			return date.compare(left_res,right_res,"time");
+		}else if(left instanceof exprs.DateExpr){
+			return date.compare(left_res,right_res,"date");
 		}else{
-			if(left instanceof fns.StringExpr){
+			if(left instanceof exprs.StringExpr){
 				left_res = left_res.toLowerCase();
 				right_res = String(right_res).toLowerCase();
 			}
 			return left_res == right_res ? 0 : (left_res < right_res ? -1 : 1);
 		}
 	}
-	dojo.declare("dojox.grid.enhanced.plugins.filter.EqualTo", fns._BiOpExpr, {
+	var EqualTo = declare("dojox.grid.enhanced.plugins.filter.EqualTo", exprs._BiOpExpr, {
 		// summary:
 		//		An "equal to" condition expression.
 		_name: "equal",
@@ -108,10 +108,10 @@ dojo.require("dojo.date");
 			// summary:
 			//		Override from _BiOpExpr
 			var res = compareFunc(left_operand,right_operand,datarow,getter);
-			return new fns.BooleanExpr(res === 0);	//_ConditionExpr
+			return new exprs.BooleanExpr(res === 0);	//_ConditionExpr
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.LessThan", fns._BiOpExpr, {
+	var LessThan = declare("dojox.grid.enhanced.plugins.filter.LessThan", exprs._BiOpExpr, {
 		// summary:
 		//		A "less than" condition expression.
 		_name: "less",
@@ -120,10 +120,10 @@ dojo.require("dojo.date");
 			// summary:
 			//		Override from _BiOpExpr
 			var res = compareFunc(left_operand,right_operand,datarow,getter);
-			return new fns.BooleanExpr(res < 0);	//_ConditionExpr
+			return new exprs.BooleanExpr(res < 0);	//_ConditionExpr
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.LessThanOrEqualTo", fns._BiOpExpr, {
+	var LessThanOrEqualTo = declare("dojox.grid.enhanced.plugins.filter.LessThanOrEqualTo", exprs._BiOpExpr, {
 		// summary:
 		//		A "less than or equal to" condition expression.
 		_name: "lessEqual",
@@ -132,10 +132,10 @@ dojo.require("dojo.date");
 			// summary:
 			//		Override from _BiOpExpr
 			var res = compareFunc(left_operand,right_operand,datarow,getter);
-			return new fns.BooleanExpr(res <= 0);	//_ConditionExpr
+			return new exprs.BooleanExpr(res <= 0);	//_ConditionExpr
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.LargerThan", fns._BiOpExpr, {
+	var LargerThan = declare("dojox.grid.enhanced.plugins.filter.LargerThan", exprs._BiOpExpr, {
 		// summary:
 		//		A "larger than" condition expression.
 		_name: "larger",
@@ -144,10 +144,10 @@ dojo.require("dojo.date");
 			// summary:
 			//		Override from _BiOpExpr
 			var res = compareFunc(left_operand,right_operand,datarow,getter);
-			return new fns.BooleanExpr(res > 0);	//_ConditionExpr
+			return new exprs.BooleanExpr(res > 0);	//_ConditionExpr
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.LargerThanOrEqualTo", fns._BiOpExpr, {
+	var LargerThanOrEqualTo = declare("dojox.grid.enhanced.plugins.filter.LargerThanOrEqualTo", exprs._BiOpExpr, {
 		// summary:
 		//		A "larger than or equal to" condition expression.
 		_name: "largerEqual",
@@ -156,12 +156,12 @@ dojo.require("dojo.date");
 			// summary:
 			//		Override from _BiOpExpr
 			var res = compareFunc(left_operand,right_operand,datarow,getter);
-			return new fns.BooleanExpr(res >= 0);	//_ConditionExpr
+			return new exprs.BooleanExpr(res >= 0);	//_ConditionExpr
 		}
 	});
 	
 	/* String Operations */
-	dojo.declare("dojox.grid.enhanced.plugins.filter.Contains", fns._BiOpExpr, {
+	var Contains = declare("dojox.grid.enhanced.plugins.filter.Contains", exprs._BiOpExpr, {
 		// summary:
 		//		A "contains" condition expression.
 		_name: "contains",
@@ -171,10 +171,10 @@ dojo.require("dojo.date");
 			//		Override from _BiOpExpr
 			var left_res = String(left_operand.applyRow(datarow, getter).getValue()).toLowerCase();
 			var right_res = String(right_operand.applyRow(datarow, getter).getValue()).toLowerCase();
-			return new fns.BooleanExpr(left_res.indexOf(right_res) >= 0);	//_ConditionExpr
+			return new exprs.BooleanExpr(left_res.indexOf(right_res) >= 0);	//_ConditionExpr
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.StartsWith", fns._BiOpExpr, {
+	var StartsWith = declare("dojox.grid.enhanced.plugins.filter.StartsWith", exprs._BiOpExpr, {
 		// summary:
 		//		A "starts with" condition expression.
 		_name: "startsWith",
@@ -184,10 +184,10 @@ dojo.require("dojo.date");
 			//		Override from _BiOpExpr
 			var left_res = String(left_operand.applyRow(datarow, getter).getValue()).toLowerCase();
 			var right_res = String(right_operand.applyRow(datarow, getter).getValue()).toLowerCase();
-			return new fns.BooleanExpr(left_res.substring(0, right_res.length) == right_res);	//_ConditionExpr
+			return new exprs.BooleanExpr(left_res.substring(0, right_res.length) == right_res);	//_ConditionExpr
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.EndsWith", fns._BiOpExpr, {
+	var EndsWith = declare("dojox.grid.enhanced.plugins.filter.EndsWith", exprs._BiOpExpr, {
 		// summary:
 		//		An "ends with" condition expression.
 		_name: "endsWith",
@@ -197,10 +197,10 @@ dojo.require("dojo.date");
 			//		Override from _BiOpExpr
 			var left_res = String(left_operand.applyRow(datarow, getter).getValue()).toLowerCase();
 			var right_res = String(right_operand.applyRow(datarow, getter).getValue()).toLowerCase();
-			return new fns.BooleanExpr(left_res.substring(left_res.length - right_res.length) == right_res);	//_ConditionExpr
+			return new exprs.BooleanExpr(left_res.substring(left_res.length - right_res.length) == right_res);	//_ConditionExpr
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.Matches", fns._BiOpExpr, {
+	var Matches = declare("dojox.grid.enhanced.plugins.filter.Matches", exprs._BiOpExpr, {
 		// summary:
 		//		A "regular expression match" condition expression.
 		//		The second operand's value will be regarded as an regular expression string.
@@ -211,10 +211,10 @@ dojo.require("dojo.date");
 			//		Override from _BiOpExpr
 			var left_res = String(left_operand.applyRow(datarow, getter).getValue());
 			var right_res = new RegExp(right_operand.applyRow(datarow, getter).getValue());
-			return new fns.BooleanExpr(left_res.search(right_res) >= 0);	//_ConditionExpr
+			return new exprs.BooleanExpr(left_res.search(right_res) >= 0);	//_ConditionExpr
 		}
 	});
-	dojo.declare("dojox.grid.enhanced.plugins.filter.IsEmpty", fns._UniOpExpr, {
+	var IsEmpty = declare("dojox.grid.enhanced.plugins.filter.IsEmpty", exprs._UniOpExpr, {
 		// summary:
 		//		Check empty
 		_name: "isEmpty",
@@ -222,7 +222,26 @@ dojo.require("dojo.date");
 			// summary:
 			//		Override from _BiOpExpr
 			var res = operand.applyRow(datarow, getter).getValue();
-			return new fns.BooleanExpr(res === "" || res == null);
+			return new exprs.BooleanExpr(res === "" || res == null);
 		}
 	});
-})();
+
+	return lang.mixin({
+		LogicAND: LogicAND,
+		LogicOR: LogicOR,
+		LogicXOR: LogicXOR,
+		LogicNOT: LogicNOT,
+		LogicALL: LogicALL,
+		LogicANY: LogicANY,
+		EqualTo: EqualTo,
+		LessThan: LessThan,
+		LessThanOrEqualTo: LessThanOrEqualTo,
+		LargerThan: LargerThan,
+		LargerThanOrEqualTo: LargerThanOrEqualTo,
+		Contains: Contains,
+		StartsWith: StartsWith,
+		EndsWith: EndsWith,
+		Matches: Matches,
+		IsEmpty: IsEmpty
+	}, exprs);
+});
diff --git a/dojox/grid/enhanced/resources/Common.css b/dojox/grid/enhanced/resources/Common.css
index d2842f1..fc3d346 100644
--- a/dojox/grid/enhanced/resources/Common.css
+++ b/dojox/grid/enhanced/resources/Common.css
@@ -1,16 +1,7 @@
-.dojoxGrid {
-	border:1px solid #DBDBDB;
-}
-.dojoxGridCellContent {
-	padding:3px;
-}
-.dojoxGridSortNode {
-	padding:3px;
-}
-.dojoxGridInProgress {
-	cursor:progress;
-}
 /* Indirect Selection */
+.dojoxGridRowSelector {
+	cursor: pointer;
+}
 .dojoxGridRowSelectorStatusText{
 	visibility:hidden;
 }
diff --git a/dojox/grid/enhanced/resources/Filter.css b/dojox/grid/enhanced/resources/Filter.css
index 1c7039c..46ca5fe 100644
--- a/dojox/grid/enhanced/resources/Filter.css
+++ b/dojox/grid/enhanced/resources/Filter.css
@@ -182,7 +182,7 @@
 .dojoxGridFCBox .dojoxGridFCBoxColSelect, 
 .dojoxGridFCBox .dojoxGridFCBoxCondSelect, 
 .dojoxGridFCBox .dojoxGridFCBoxValueBox {
-	margin: 5px 0 0 0;
+	margin: 0.1em 0 0 0;
 	width: 100%;
 	/* inherited is inline-block this will cause width "error" in non IE for html tables */
 	display: inline-table;
diff --git a/dojox/grid/enhanced/resources/Filter_rtl.css b/dojox/grid/enhanced/resources/Filter_rtl.css
index 54683c4..c9f2333 100644
--- a/dojox/grid/enhanced/resources/Filter_rtl.css
+++ b/dojox/grid/enhanced/resources/Filter_rtl.css
@@ -1,4 +1,8 @@
 /* filter bar */
+.dojoxGridRtl .dojoxGridFBarDefFilterBtnIcon {
+	background: url("images/sprite_icons.png") no-repeat;
+	background-position: -180px -18px;
+}
 .dojoxGridRtl .dojoxGridFBarStatus {
 	margin-left: 0;
 	margin-right: 9px;
diff --git a/dojox/grid/enhanced/resources/Pagination.css b/dojox/grid/enhanced/resources/Pagination.css
index 8eaa176..bc1ae55 100644
--- a/dojox/grid/enhanced/resources/Pagination.css
+++ b/dojox/grid/enhanced/resources/Pagination.css
@@ -34,6 +34,7 @@
 	background: url("images/sprite_icons.png") no-repeat -77px 4px;
 }
 .dojoxGridPaginatorGotoDivDisabled {
+	cursor: not-allowed;
 	background: url("images/sprite_icons.png") no-repeat -77px -16px;
 }
 .dojoxGridWardButton {
@@ -57,6 +58,7 @@
 }
 .dojoxGridfirstPageBtnDisable {
 	margin-left: 1px;
+	cursor: not-allowed;
 	background-position: -57px -17px;
 }
 .dojoxGridprevPageBtn {
@@ -65,6 +67,7 @@
 	background-position: 3px 3px;
 }
 .dojoxGridprevPageBtnDisable {
+	cursor: not-allowed;
 	margin: 2px 2px 0 9px;
 	background-position: 3px -17px;
 }
@@ -74,6 +77,7 @@
 	background-position: -37px 3px;
 }
 .dojoxGridlastPageBtnDisable {
+	cursor: not-allowed;
 	margin: 2px 9px 0 9px;
 	background-position: -37px -17px;
 }
@@ -85,6 +89,7 @@
 }
 .dojoxGridnextPageBtnDisable {
 	margin-left: 3px;
+	cursor: not-allowed;
 	background-position: -17px -17px;
 }
 .dojoxGridInactived {
@@ -136,3 +141,7 @@
 	width: 220px!important;
 	text-align: right;
 }
+.dojoxGridButtonFocus {
+	outline: none;
+	border: 0.5px dotted darkblue !important;
+}
diff --git a/dojox/grid/enhanced/resources/Pagination_rtl.css b/dojox/grid/enhanced/resources/Pagination_rtl.css
index 1175570..e3a2dd1 100644
--- a/dojox/grid/enhanced/resources/Pagination_rtl.css
+++ b/dojox/grid/enhanced/resources/Pagination_rtl.css
@@ -65,4 +65,4 @@
 .dijitRtl .dojoxGridnextPageBtnDisable {
 	margin: 2px 3px 0 0;
 	background-position: 3px -17px;
-}
+}
\ No newline at end of file
diff --git a/dojox/grid/enhanced/resources/Sorter.css b/dojox/grid/enhanced/resources/Sorter.css
index bfa909c..11e6fc5 100644
--- a/dojox/grid/enhanced/resources/Sorter.css
+++ b/dojox/grid/enhanced/resources/Sorter.css
@@ -11,6 +11,7 @@
 .dojoxGrid .dojoxGridSortNode {
 	position: relative;
 	border: 1px solid transparent;
+	cursor: pointer;
 }
 .dj_ie6 .dojoxGrid .dojoxGridSortNode,
 .dj_ie7 .dojoxGrid .dojoxGridSortNode {
@@ -19,7 +20,7 @@
 }
 .dojoxGrid .dojoxGridSortNoWrap {
 	white-space:nowrap;
-	cursor: pointer;
+	word-wrap: normal;
 }
 .dojoxGridSortBtn {
 	width: 10px;
diff --git a/dojox/grid/enhanced/resources/claro/Common.css b/dojox/grid/enhanced/resources/claro/Common.css
index 102f703..cec6c02 100644
--- a/dojox/grid/enhanced/resources/claro/Common.css
+++ b/dojox/grid/enhanced/resources/claro/Common.css
@@ -1,71 +1,4 @@
-/* overwrite claroGrid.css */
-.claro .dojoxGridMasterHeader .dojoxGridRowTable {
-	border-left: 1px solid #BCBCBC;
-	border-right: 1px solid white;
-	background-color: transparent;
-}
-.claro .dojoxGridHeader tr:first-child .dojoxGridCell {
-	border-top: 1px solid transparent;
-}
-.claro .dojoxGridHeader:first-child .dojoxGridRowTable {
-	border-left-width: 0;
-}
-.claro .dojoxGridMasterHeader {
-	background: url("../../../resources/images/header.png") #EDF2F7 repeat-x bottom;
-	background: -moz-linear-gradient(top, #EDF2F7, #D0DFEA);
-	background: -webkit-gradient(linear, left top, left bottom, from(#EDF2F7), to(#D0DFEA));
-	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#FFEDF2F7, endColorstr=#FFD0DFEA);
-	border-bottom: 1px solid white;
-	border-left: 1px solid white;
-	border-top: 1px solid white;
-}
-.claro .dojoxGridCell {
-	padding: 3px 5px;
-	border-color: transparent #E5DAC8 #E5DAC8 transparent;
-}
-.dj_ie6 .claro .dojoxGridCell{
-	border-color:#F5F5F5;
-}
-.claro .dojoxGridHeader {
-	background: transparent;
-	margin-left: -2px;
-}
-.claro .dojoxGridHeader:first-child {
-	margin-left: -1px;
-}
-.claro .dojoxGridHeader .dojoxGridCell{
-	padding: 2px 5px;
-	background: transparent;
-	border-bottom: 1px solid #BCBCBC;
-	border-top: 1px solid white;
-	border-left: 1px solid white;
-	border-right: 1px solid #BCBCBC;
-	vertical-align: top;
-}
-.claro .dojoxGridHeader .dojoxGridCellOver {
-	background:#9dcfff;
-}
-.claro .dojoxGridSortNode{
-	white-space: normal;
-	background: none;
-	border: none;
-	padding: 0;
-}
-.claro .dojoxGridHeader .dojoxGridRowTable tr {
-	background:none;
-}
-.claro .dojoxGridCellContent {
-	padding:4px 6px 4px 6px;
-}
-.dj_webkit .claro th.dojoxGridCell > .dojoxGridCellContent {
-	padding: 4px 0;
-}
-.claro .dojoxGridRowbarInner {
-	width:20px;
-}
-/* end overwrite */
-
-.claro .dojoxGridHeaderSelected .dojoxGridHeaderActive {
+.claro .dojoxGridHeader .dojoxGridHeaderActive {
 	background-color:#91c9fe;
 }
 .claro td.dojoxGridRowSelected {
@@ -86,12 +19,6 @@
 	border-color: #7DBEFA;
 }
 
-/* Don't need any explicit outlines */
-.claro .dojoxGridCell,
-.claro .dojoxGridCellFocus {
-	outline: none;
-}
-
 /* Pagination */
 .claro .dojoxGridPaginator{
 	background: url("../../../resources/images/header_shadow.png") repeat-x scroll center bottom #E5EDF4;
diff --git a/dojox/grid/enhanced/resources/claro/Filter.css b/dojox/grid/enhanced/resources/claro/Filter.css
index 4574142..f2069f6 100644
--- a/dojox/grid/enhanced/resources/claro/Filter.css
+++ b/dojox/grid/enhanced/resources/claro/Filter.css
@@ -50,7 +50,6 @@
 	border-top: 1px solid white;
 	border-bottom: 1px solid white;
 }
-.claro .dojoxGridFStatusTipRel,
 .claro .dojoxGridFStatusTipCondition {
 	font-style: italic;
 }
diff --git a/dojox/grid/enhanced/resources/claroEnhancedGrid.css b/dojox/grid/enhanced/resources/claroEnhancedGrid.css
new file mode 100644
index 0000000..2cbc1de
--- /dev/null
+++ b/dojox/grid/enhanced/resources/claroEnhancedGrid.css
@@ -0,0 +1,2 @@
+/*backward compatible*/
+ at import "claro/EnhancedGrid.css";
\ No newline at end of file
diff --git a/dojox/grid/enhanced/resources/images/sprite_icons.png b/dojox/grid/enhanced/resources/images/sprite_icons.png
index 565e63f..28be879 100644
Binary files a/dojox/grid/enhanced/resources/images/sprite_icons.png and b/dojox/grid/enhanced/resources/images/sprite_icons.png differ
diff --git a/dojox/grid/enhanced/resources/tundraEnhancedGrid.css b/dojox/grid/enhanced/resources/tundraEnhancedGrid.css
new file mode 100644
index 0000000..a770d0c
--- /dev/null
+++ b/dojox/grid/enhanced/resources/tundraEnhancedGrid.css
@@ -0,0 +1,2 @@
+/*backward compatible*/
+ at import "tundra/EnhancedGrid.css";
\ No newline at end of file
diff --git a/dojox/grid/enhanced/templates/FilterStatusPane.html b/dojox/grid/enhanced/templates/FilterStatusPane.html
index f832b9b..67be8d4 100644
--- a/dojox/grid/enhanced/templates/FilterStatusPane.html
+++ b/dojox/grid/enhanced/templates/FilterStatusPane.html
@@ -1,9 +1,8 @@
-<div class="dojoxGridFStatusTip">
-	<div class="dojoxGridFStatusTipHead">
-		<span class="dojoxGridFStatusTipTitle" dojoAttachPoint="statusTitle"></span
-		><span class="dojoxGridFStatusTipRelPre" dojoAttachPoint="statusRelPre"></span
+<div class="dojoxGridFStatusTip"
+	><div class="dojoxGridFStatusTipHead"
+		><span class="dojoxGridFStatusTipTitle" dojoAttachPoint="statusTitle"></span
 		><span class="dojoxGridFStatusTipRel" dojoAttachPoint="statusRel"></span
-		><span class="dojoxGridFStatusTipRelPost" dojoAttachPoint="statusRelPost"></span>
-	</div>
-	<div class="dojoxGridFStatusTipDetail" dojoAttachPoint="statusDetailNode"></div>
-</div>
+	></div
+	><div class="dojoxGridFStatusTipDetail" dojoAttachPoint="statusDetailNode"
+	></div
+></div>
diff --git a/dojox/grid/enhanced/templates/Pagination.html b/dojox/grid/enhanced/templates/Pagination.html
index e26a8e5..ad55539 100644
--- a/dojox/grid/enhanced/templates/Pagination.html
+++ b/dojox/grid/enhanced/templates/Pagination.html
@@ -1,13 +1,18 @@
-<div dojoAttachPoint="paginatorBar">
-	<table cellpadding="0" cellspacing="0"  class="dojoxGridPaginator">
-		<tr>
-			<td dojoAttachPoint="descriptionTd" class="dojoxGridDescriptionTd">
-				<div dojoAttachPoint="descriptionDiv" class="dojoxGridDescription" />
-			</td>
-			<td dojoAttachPoint="sizeSwitchTd"></td>
-			<td dojoAttachPoint="pageStepperTd" class="dojoxGridPaginatorFastStep">
-				<div dojoAttachPoint="pageStepperDiv" class="dojoxGridPaginatorStep"></div>
-			</td>
-		</tr>
-	</table>
-</div>
+<div dojoAttachPoint="paginatorBar"
+	><table cellpadding="0" cellspacing="0"  class="dojoxGridPaginator"
+		><tr
+			><td dojoAttachPoint="descriptionTd" class="dojoxGridDescriptionTd"
+				><div dojoAttachPoint="descriptionDiv" class="dojoxGridDescription"></div
+			></div></td
+			><td dojoAttachPoint="sizeSwitchTd"></td
+			><td dojoAttachPoint="pageStepperTd" class="dojoxGridPaginatorFastStep"
+				><div dojoAttachPoint="pageStepperDiv" class="dojoxGridPaginatorStep"></div
+			></td
+			><td dojoAttachPoint="gotoPageTd" class="dojoxGridPaginatorGotoTd"
+				><div dojoAttachPoint="gotoPageDiv" class="dojoxGridPaginatorGotoDiv" dojoAttachEvent="onclick:_openGotopageDialog, onkeydown:_openGotopageDialog"
+					><span class="dojoxGridWardButtonInner">⊥</span
+				></div
+			></td
+		></tr
+	></table
+></div>
diff --git a/dojox/grid/resources/claroGrid.css b/dojox/grid/resources/claroGrid.css
index 867a765..f15ff84 100644
--- a/dojox/grid/resources/claroGrid.css
+++ b/dojox/grid/resources/claroGrid.css
@@ -5,7 +5,8 @@
 	margin:0px;
 	padding:0px;
 	border-collapse:collapse;	
-	background-color:#fff;	
+	background-color: #fff;
+	border: 1px solid #DBDBDB;
 }
 /*  messages */
 .claro .dojoxGridMasterMessages {
@@ -29,28 +30,32 @@
 
 /* header */
 .claro .dojoxGridHeader {
-	background-color:#FFF;
+	background: transparent;
+	margin-left: -2px;
 }
-.claro .dojoxGridHeader .dojoxGridCell { 
-	background:url("images/header.png") #e5edf4 repeat-x top;
+.claro .dojoxGridHeader .dojoxGridCell {
+	padding: 2px 5px;
+	vertical-align: top;
+	background: transparent;
 	border-style:solid;
 	border-width:1px;
-	border-color:#BCBCBC #BCBCBC #BCBCBC transparent;
+	border-color: #FFFFFF #BCBCBC #BCBCBC #FFFFFF;
 }
 .dj_ie6 .claro .dojoxGridHeader .dojoxGridCell { 
 	border-color:#BCBCBC #BCBCBC #BCBCBC #e5edf4;
 }
+.claro .dojoxGridHeader .dojoxGridCellOver {
+	background: #9dcfff;
+}
 
 /* header sorting arrow */
 .claro .dojoxGridSortNode {
-	background:url("images/header_shadow.png") #e5edf4 repeat-x bottom;
 	text-decoration:none;
 	display:block;
-	padding:4px 6px 5px 6px;
-	border:1px solid #e0eefb;
-}
-.dj_ie6 .claro .dojoxGridSortNode {
-	background-image:none;
+	white-space: normal;
+	background: none;
+	border: none;
+	padding: 0;
 }
 .claro .dojoxGridCellOver .dojoxGridSortNode {
 	background-color:#9dcfff;
@@ -73,10 +78,34 @@
 }
 
 /* header rows */
+.claro .dojoxGridMasterHeader {
+	background: url("images/header.png") #EDF2F7 repeat-x bottom;
+	background: -moz-linear-gradient(top, #EDF2F7, #D0DFEA);
+	background: -webkit-gradient(linear, left top, left bottom, from(#EDF2F7), to(#D0DFEA));
+	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#FFEDF2F7, endColorstr=#FFD0DFEA);
+	border: 1px solid #FFFFFF;
+	border-right: none;
+}
+.claro .dojoxGridMasterHeader .dojoxGridRowTable {
+	border-left: 1px solid #BCBCBC;
+	border-right: 1px solid #FFFFFF;
+	background-color: transparent;
+}
 .dj_ie .claro .dojoxGridHeader .dojoxGridRowTable {
 	border-collapse:separate;
 }
-
+.claro .dojoxGridHeader .dojoxGridRowTable tr {
+	background: none;
+}
+.claro .dojoxGridHeader tr:first-child .dojoxGridCell {
+	border-top: 1px solid transparent;
+}
+.claro .dojoxGridHeader:first-child .dojoxGridRowTable {
+	border-left-width: 0;
+}
+.claro .dojoxGridHeader:first-child {
+	margin-left: -1px;
+}
 /* Grid view content */
 .claro .dojoxGridScrollbox {
 	background-color: #fefefe;
@@ -102,9 +131,6 @@
 .claro .dojoxGridRowbarOver .dojoxGridRowbarTable {
 	background-color:#abd5fd;
 }
-.claro .dojoxGridRowBarActive .dojoxGridRowbarTable {
-	background-color:#91c9fe;
-}
 .claro .dojoxGridRowbarSelected {
 	background-color:#abd5fd;
 	border-right:1px solid #ccc;
@@ -130,11 +156,14 @@
 
 /* cells */
 .claro .dojoxGridCell {
-	padding:0px;
+	outline: none;
+	padding: 3px 5px;
+	word-wrap: break-word;
 	border:1px solid transparent;
+	border-color: transparent #E5DAC8 #E5DAC8 transparent;
 }
 .dj_ie6 .claro .dojoxGridCell {
-	border-color:#fff
+	border-color: #F5F5F5;
 }
 .dj_ie6 .claro .dojoxGridRowOdd .dojoxGridCell {
 	border-left-color:#f4f9fd;
@@ -149,11 +178,9 @@
 	border-bottom:1px solid #BFD6EB;
 }
 .claro .dojoxGridCellFocus {
+	outline: none;
 	border:1px dashed darkblue !important;
 }
-.claro .dojoxGridCellContent {
-	padding:4px 6px 4px 6px;
-}
 
 /*  Single Affordance Hover Effect */
 .claro .dojoxGridRowOver .dojoxGridCell {
@@ -232,8 +259,9 @@
 }
 .claro .dojoxGridExpandoNode {
 	background-image: url('../../../dijit/themes/claro/images/treeExpandImages.png');
-    width: 16px;
-    height: 16px;
+	width: 16px;
+	height: 16px;
+	cursor: pointer;
 	background-position: 1px 0px; /* for closed state */
 }
 .dj_ie6 .claro .dojoxGridExpandoNode {
diff --git a/dojox/grid/tests/databaseModel.js b/dojox/grid/tests/databaseModel.js
deleted file mode 100644
index 5e29e9c..0000000
--- a/dojox/grid/tests/databaseModel.js
+++ /dev/null
@@ -1,333 +0,0 @@
-dojo.provide("dojox.grid.tests.databaseModel");
-dojo.require("dojox.grid._data.model");
-
-// Provides a sparse array that is also traversable inorder
-// with basic Array:
-//   - iterating by index is slow for large sparse arrays
-//   - for...in iteration is in order of element creation
-// maintains a secondary index for interating
-// over sparse elements inorder
-dojo.declare("dojox.grid.Sparse", null, {
-	constructor: function() {
-		this.clear();
-	},
-	clear: function() {
-		this.indices = [];
-		this.values = [];
-	},
-	length: function() {
-		return this.indices.length;
-	},
-	set: function(inIndex, inValue) {
-		for (var i=0,l=this.indices.length; i<l; i++) {
-			if (this.indices[i] >= inIndex)
-				break;
-		}
-		if (this.indices[i] != inIndex)
-			this.indices.splice(i, 0, inIndex);
-		this.values[inIndex] = inValue;
-	},
-	get: function(inIndex) {
-		return this.values[inIndex];
-	},
-	remove: function(inIndex) {
-		for (var i=0,l=this.indices.length; i<l; i++)
-			if (this.indices[i] == inIndex) {
-				this.indices.splice(i, 1);
-				break;
-			}
-		delete this.values[inIndex];
-	},
-	inorder: function(inFor) {
-		for (var i=0,l=this.indices.length, ix; i<l; i++) {
-			ix = this.indices[i];
-			if (inFor(this.values[ix], ix) === false)
-				break;
-		}
-	}
-});
-
-// sample custom model implementation that works with mysql server.
-dojo.declare("dojox.grid._data.DbTable", dojox.grid._data.Dynamic, {
-	delayedInsertCommit: true,
-	constructor: function(inFields, inData, inServer, inDatabase, inTable) {
-		this.server = inServer;
-		this.database = inDatabase;
-		this.table = inTable;
-		this.stateNames = ['inflight', 'inserting', 'removing', 'error'];
-		this.clearStates();
-		this.clearSort();
-	},
-	clearData: function() {
-		this.cache = [ ];
-		this.clearStates();
-		this.inherited(arguments);
-	},
-	clearStates: function() {
-		this.states = {};
-		for (var i=0, s; (s=this.stateNames[i]); i++) {
-			delete this.states[s];
-			this.states[s] = new dojox.grid.Sparse();
-		}
-	},
-	// row state information
-	getState: function(inRowIndex) {
-		for (var i=0, r={}, s; (s=this.stateNames[i]); i++)
-			r[s] = this.states[s].get(inRowIndex);
-		return r;
-	},
-	setState: function(inRowIndex, inState, inValue) {
-		this.states[inState].set(inRowIndex, inValue||true);
-	},
-	clearState: function(inRowIndex, inState) {
-		if (arguments.length == 1) {
-			for (var i=0, s; (s=this.stateNames[i]); i++)
-				this.states[s].remove(inRowIndex);
-		}	else {
-			for (var i=1, l=arguments.length, arg; (i<l) &&((arg=arguments[i])!=undefined); i++)
-				this.states[arg].remove(inRowIndex);
-		}
-	},
-	setStateForIndexes: function(inRowIndexes, inState, inValue) {
-		for (var i=inRowIndexes.length-1, k; (i>=0) && ((k=inRowIndexes[i])!=undefined); i--)
-			this.setState(k, inState, inValue);
-	},
-	clearStateForIndexes: function(inRowIndexes, inState) {
-		for (var i=inRowIndexes.length-1, k; (i>=0) && ((k=inRowIndexes[i])!=undefined); i--)
-			this.clearState(k, inState);
-	},
-	//$ Return boolean stating whether or not an operation is in progress that may change row indexing.
-	isAddRemoving: function() {
-		return Boolean(this.states['inserting'].length() || this.states['removing'].length());
-	},
-	isInflight: function() {
-		return Boolean(this.states['inflight'].length());
-	},
-	//$ Return boolean stating if the model is currently undergoing any type of edit.
-	isEditing: function() {
-		for (var i=0, r={}, s; (s=this.stateNames[i]); i++)
-			if (this.states[s].length())
-				return true;
-	},
-	//$ Return true if ok to modify the given row. Override as needed, using model editing state information.
-	canModify: function(inRowIndex) {
-		return !this.getState(inRowIndex).inflight && !(this.isInflight() && this.isAddRemoving());
-	},
-	// server send / receive
-	getSendParams: function(inParams) {
-		var p = {
-			database: this.database || '',
-			table: this.table || ''
-		}
-		return dojo.mixin(p, inParams || {});
-	},
-	send: function(inAsync, inParams, inCallbacks) {
-		//console.log('send', inParams.command);
-		var p = this.getSendParams(inParams);
-		var d = dojo.xhrPost({
-			url: this.server,
-			content: p,
-			handleAs: 'json-comment-filtered',
-			contentType: "application/x-www-form-urlencoded; charset=utf-8",
-			sync: !inAsync
-		});
-		d.addCallbacks(dojo.hitch(this, "receive", inCallbacks), dojo.hitch(this, "receiveError", inCallbacks));
-		return d;
-	},
-	_callback: function(cb, eb, data) {
-		try{ cb && cb(data); }
-		catch(e){ eb && eb(data, e); }
-	},
-	receive: function(inCallbacks, inData) {
-		inCallbacks && this._callback(inCallbacks.callback, inCallbacks.errback, inData);
-	},
-	receiveError: function(inCallbacks, inErr) {
-		this._callback(inCallbacks.errback, null, inErr)
-	},
-	encodeRow: function(inParams, inRow, inPrefix) {
-		for (var i=0, l=inRow.length; i < l; i++)
-			inParams['_' + (inPrefix ? inPrefix : '') + i] = (inRow[i] ? inRow[i] : '');
-	},
-	measure: function() {
-		this.send(true, { command: 'info' }, { callback: dojo.hitch(this, this.callbacks.info) });
-	},
-	fetchRowCount: function(inCallbacks) {
-		this.send(true, { command: 'count' }, inCallbacks);
-	},
-	// server commits
-	commitEdit: function(inOldData, inNewData, inRowIndex, inCallbacks) {
-		this.setState(inRowIndex, "inflight", true);
-		var params = {command: 'update'};
-		this.encodeRow(params, inOldData, 'o');
-		this.encodeRow(params, inNewData);
-		this.send(true, params, inCallbacks);
-	},
-	commitInsert: function(inRowIndex, inNewData, inCallbacks) {
-		this.setState(inRowIndex, "inflight", true);
-		var params = {command: 'insert'};
-		this.encodeRow(params, inNewData);
-		this.send(true, params, inCallbacks);
-	},
-	// NOTE: supported only in tables with pk
-	commitDelete: function(inRows, inCallbacks) {
-		var params = {
-			command: 'delete',
-			count: inRows.length
-		}
-		var pk = this.getPkIndex();
-		if (pk < 0)
-			return;
-		for (var i=0; i < inRows.length; i++)	{
-			params['_' + i] = inRows[i][pk];
-		}
-		this.send(true, params, inCallbacks);
-	},
-	getUpdateCallbacks: function(inRowIndex) {
-		return {
-			callback: dojo.hitch(this, this.callbacks.update, inRowIndex),
-			errback: dojo.hitch(this, this.callbacks.updateError, inRowIndex)
-		};
-	},
-	// primary key from fields
-	getPkIndex: function() {
-		for (var i=0, l=this.fields.count(), f; (i<l) && (f=this.fields.get(i)); i++)
-			if (f.Key = 'PRI')
-				return i;
-		return -1;
-	},
-	// model implementations
-	update: function(inOldData, inNewData, inRowIndex) {
-		var cbs = this.getUpdateCallbacks(inRowIndex);
-		if (this.getState(inRowIndex).inserting)
-			this.commitInsert(inRowIndex, inNewData, cbs);
-		else
-			this.commitEdit(this.cache[inRowIndex] || inOldData, inNewData, inRowIndex, cbs);
-		// set push data immediately to model	so reflectd while committing
-		this.setRow(inNewData, inRowIndex);
-	},
-	insert: function(inData, inRowIndex) {
-		this.setState(inRowIndex, 'inserting', true);
-		if (!this.delayedInsertCommit)
-			this.commitInsert(inRowIndex, inData, this.getUpdateCallbacks(inRowIndex));
-		return this.inherited(arguments);
-	},
-	remove: function(inRowIndexes) {
-		var rows = [];
-		for (var i=0, r=0, indexes=[]; (r=inRowIndexes[i]) !== undefined; i++)
-			if (!this.getState(r).inserting) {
-				rows.push(this.getRow(r));
-				indexes.push(r);
-				this.setState(r, 'removing');
-			}
-		var cbs = {
-			callback: dojo.hitch(this, this.callbacks.remove, indexes),
-			errback: dojo.hitch(this, this.callbacks.removeError, indexes)
-		};
-		this.commitDelete(rows, cbs);
-		dojox.grid._data.Dynamic.prototype.remove.apply(this, arguments);
-	},
-	cancelModifyRow: function(inRowIndex) {
-		if (this.isDelayedInsert(inRowIndex)) {
-			this.removeInsert(inRowIndex);
-		} else
-			this.finishUpdate(inRowIndex);
-	},
-	finishUpdate: function(inRowIndex, inData) {
-		this.clearState(inRowIndex);
-		var d = (inData&&inData[0]) || this.cache[inRowIndex];
-		if (d)
-			this.setRow(d, inRowIndex);
-		delete this.cache[inRowIndex];
-	},
-	isDelayedInsert: function(inRowIndex) {
-		return (this.delayedInsertCommit && this.getState(inRowIndex).inserting);
-	},
-	removeInsert: function(inRowIndex) {
-		this.clearState(inRowIndex);
-		dojox.grid._data.Dynamic.prototype.remove.call(this, [inRowIndex]);
-	},
-	// request data
-	requestRows: function(inRowIndex, inCount)	{
-		var params = {
-			command: 'select',
-			orderby: this.sortField,
-			desc: (this.sortDesc ? "true" : ''),
-			offset: inRowIndex,
-			limit: inCount
-		}
-		this.send(true, params, {callback: dojo.hitch(this, this.callbacks.rows, inRowIndex)});
-	},
-	// sorting
-	canSort: function () {
-		return true;
-	},
-	setSort: function(inSortIndex) {
-		this.sortField = this.fields.get(Math.abs(inSortIndex) - 1).name || inSortIndex;
-		this.sortDesc = (inSortIndex < 0);
-	},
-	sort: function(inSortIndex) {
-		this.setSort(inSortIndex);
-		this.clearData();
-	},
-	clearSort: function(){
-		this.sortField = '';
-		this.sortDesc = false;
-	},
-	endModifyRow: function(inRowIndex){
-		var cache = this.cache[inRowIndex];
-		var m = false;
-		if(cache){
-			var data = this.getRow(inRowIndex);
-			if(!dojox.grid.util.arrayCompare(cache, data)){
-				m = true;
-				this.update(cache, data, inRowIndex);
-			}
-		}
-		if (!m)
-			this.cancelModifyRow(inRowIndex);
-	},
-	// server callbacks (called with this == model)
-	callbacks: {
-		update: function(inRowIndex, inData) {
-			console.log('received update', arguments);
-			if (inData.error)
-				this.updateError(inData)
-			else
-				this.finishUpdate(inRowIndex, inData);
-		},
-		updateError: function(inRowIndex) {
-			this.clearState(inRowIndex, 'inflight');
-			this.setState(inRowIndex, "error", "update failed: " + inRowIndex);
-			this.rowChange(this.getRow(inRowIndex), inRowIndex);
-		},
-		remove: function(inRowIndexes) {
-			this.clearStateForIndexes(inRowIndexes);
-		},
-		removeError: function(inRowIndexes) {
-			this.clearStateForIndexes(inRowIndexes);
-			alert('Removal error. Please refresh.');
-		},
-		rows: function(inRowIndex, inData) {
-			//this.beginUpdate();
-			for (var i=0, l=inData.length; i<l; i++)
-				this.setRow(inData[i], inRowIndex + i);
-			//this.endUpdate();
-			//this.allChange();
-		},
-		count: function(inRowCount) {
-			this.count = Number(inRowCount);
-			this.clearData();
-		},
-		info: function(inInfo) {
-			this.fields.clear();
-			for (var i=0, c; (c=inInfo.columns[i]); i++) {
-				c.name = c.Field;
-				this.fields.set(i, c);
-			}
-			this.table = inInfo.table;
-			this.database = inInfo.database;
-			this.notify("MetaData", arguments);
-			this.callbacks.count.call(this, inInfo.count);
-		}
-	}
-});
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_cookie.html b/dojox/grid/tests/enhanced/test_enhanced_grid_cookie.html
index e3c218e..3946742 100644
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_cookie.html
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_cookie.html
@@ -79,6 +79,7 @@
 		<input type="checkbox" onclick="enableCookie('columnWidth',!this.checked)" /> Do not persist column width<br />
 		<input type="checkbox" onclick="enableCookie('sortOrder',!this.checked)" /> Do not persist sorting order<br />
 		<input type="checkbox" onclick="enableCookie('columnOrder',!this.checked)" /> Do not persist column arrangement<br />
+		<input type="checkbox" onclick="(dijit.byId('grid')).layout.setColumnVisibility(1, !this.checked)" /> Hide column with idx = 1<br /> 
 	</div>
 	<div id="gridContainer">
 		<div id="grid" dojoType="dojox.grid.EnhancedGrid" store="test_store[0]" structure="layout" plugins="plugins"></div>
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 90735cd..9763ac1 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
@@ -52,6 +52,7 @@
 	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.form.CheckBox");
+		dojo.require("dijit._WidgetsInTemplateMixin");
 		dojo.require("dojox.grid.enhanced.plugins.Filter");
 		dojo.require("dojox.grid.enhanced.plugins.exporter.CSVWriter");
 		dojo.require("dojox.grid.enhanced.plugins.Printer");
@@ -180,7 +181,7 @@
 			sb.push("</tbody></table>");
 			return sb.join('');
 		}
-		dojo.declare("PluginTable", [dijit._Widget, dijit._Templated], {
+		dojo.declare("PluginTable", [dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
 			templateString: getTableString(),
 			widgetsInTemplate: true,
 			_onChangePlugin:  function(pluginName, cb, e){
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_pagination.html b/dojox/grid/tests/enhanced/test_enhanced_grid_pagination.html
index e9f5656..21c15e5 100644
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_pagination.html
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_pagination.html
@@ -19,6 +19,9 @@
 			width: 100em;
 			height: 30em;
 		}
+		#API-btn-grp{
+			margin: 1em;
+		}
 	</style>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
@@ -27,10 +30,13 @@
 		dojo.require("dojox.grid.EnhancedGrid");
 		dojo.require("dojox.grid.enhanced.plugins.Pagination");
 		dojo.require("dojo.parser");
+		dojo.require('dijit.form.NumberTextBox');
+		dojo.require('dijit.form.Button');
+		dojo.require('dijit.form.Select');
 		
 		var layout = [{
 			cells: [
-				{ field: "id", name:"Identity", datatype:"number", width: 4, editable: false},
+				{ field: "id", name:"Identity", datatype:"number", width: 4},
 				{ field: "Genre", name:"Genre", datatype:"string", width: 10},
 				{ field: "Artist", name:"Artist", datatype:"string", width: 10},
 				{ field: "Year", name:"Year", datatype:"string", width: 2.5},
@@ -46,25 +52,56 @@
 		}];
 		var plugins = {
 			pagination: {
-				pageSizes: ["10", "25", "50", "100", "All"],	// Array, custom the items per page button
-				// itemTitle: "entrys", 	// String, custom the item' title of description
-				description: "30%",	// boolean, custom whether or not the description will be displayed
-				sizeSwitch: "260px",	// boolean, custom whether or not the page size switch will be displayed
-				pageStepper: "30em",	// boolean, custom whether or not the page step will be displayed
+				pageSizes: [10, 25, 30, 50, 100, Infinity],// Array, custom the items per page button
+				description: true,	// boolean, custom whether or not the description will be displayed
+				sizeSwitch: true,	// boolean, custom whether or not the page size switch will be displayed
+				pageStepper: true,	// boolean, custom whether or not the page step will be displayed
 				gotoButton: true,	// boolean, custom whether or not the goto page button will be displayed
-				maxPageStep: 7,		// Integer, custom how many page step will be displayed
-				position: "bottom"	// String, custom the position of the pagination bar
-										// there're three options: top, bottom, both
-				// ,descTemplate: "${1} ${0}" // A template of the current position description.
+				maxPageStep: 10,	// Integer, custom how many page step will be displayed
+				position: "bottom",	// String, custom the position of the pagination bar. There're two options: top, bottom
+				defaultPage: 2, 	// Integer, which page will be displayed by default 
+				defaultPageSize: 25 // Integer, what page size will be used by default
 			}
 		};
+		
+		var grid;
+		dojo.ready(function(){
+			grid = dijit.byId("grid");
+		});
+		
+		function currentPageSize(){
+			grid.currentPageSize(dijit.byId("pagesize").value);
+		}
+		
+		function currentPage(){
+			grid.currentPage(dijit.byId("page").value);
+		}
+		
+		function scrollToRow(){
+			grid.scrollToRow(dijit.byId("row").value - 1);
+		}
 	</script>
 </head>
 <body class="claro">
-	<h1 class="title" tabindex="0"
-		onfocus="console.log('focus a'),this.style.color='red';"
-		onblur="console.log('blur a'),this.style.color='black';">
-		dojox.grid.EnhancedGrid - Pagination</h1>
+	<h1 class="title">dojox.grid.EnhancedGrid - Pagination</h1>
+	<div id='API-btn-grp'>
+		<input data-dojo-type="dijit.form.NumberTextBox" id="pagesize" data-dojo-id="pagesize" data-dojo-props="style:{width:'40px'}"></input>
+		<button data-dojo-type="dijit.form.Button" onclick="currentPageSize()">Set Page Size</button>
+		 | 
+		<button data-dojo-type="dijit.form.Button" onclick="grid.firstPage()">first page</button>
+		<button data-dojo-type="dijit.form.Button" onclick="grid.prevPage()">previous page</button>
+		 | 
+		Page: 
+		<input data-dojo-type="dijit.form.NumberTextBox" id="page" data-dojo-id="page" data-dojo-props="style:{width:'40px'}"></input>
+		<button data-dojo-type="dijit.form.Button" onclick="currentPage()">Go</button>
+		 | 
+		<button data-dojo-type="dijit.form.Button" onclick="grid.nextPage()">next page</button>
+		<button data-dojo-type="dijit.form.Button" onclick="grid.lastPage()">last page</button>
+		 | 
+		Goto specific row: 
+		<input data-dojo-type="dijit.form.NumberTextBox" id="row" data-dojo-id="row" data-dojo-props="style:{width:'40px'}"></input>
+		<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><br/>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_plugins.html b/dojox/grid/tests/enhanced/test_enhanced_grid_plugins.html
index 94798cf..8c8d939 100644
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_plugins.html
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_plugins.html
@@ -51,6 +51,7 @@
 		djConfig="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("dojox.grid.enhanced.plugins.Filter");
 		dojo.require("dojox.grid.enhanced.plugins.exporter.CSVWriter");
@@ -180,7 +181,7 @@
 			sb.push("</tbody></table>");
 			return sb.join('');
 		}
-		dojo.declare("PluginTable", [dijit._Widget, dijit._Templated], {
+		dojo.declare("PluginTable", [dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
 			templateString: getTableString(),
 			widgetsInTemplate: true,
 			_onChangePlugin:  function(pluginName, cb, e){
@@ -370,7 +371,7 @@
 			grid.connect(grid, "onEndSelect", func);
 			grid.connect(grid, "onEndDeselect", func);
 		}
-		dojo.declare("TestWidget", [dijit._Widget,dijit._Templated], {
+		dojo.declare("TestWidget", [dijit._Widget,dijit._TemplatedMixin], {
 			templateString: dojo.cache("dojox.grid", "enhanced/templates/ClearFilterConfirmPane.html"),
 			widgetsInTemplate: true,
 			_clearBtnLabel: "clearButton",
diff --git a/dojox/grid/tests/robot/7815.html b/dojox/grid/tests/robot/7815.html
index 645197a..33c515f 100755
--- a/dojox/grid/tests/robot/7815.html
+++ b/dojox/grid/tests/robot/7815.html
@@ -42,7 +42,7 @@
 						doh.robot.keyPress(dojo.keys.ENTER,500);
 						doh.robot.sequence(d.getTestCallback(function(){
 							doh.isNot(undefined,dijit.byId('dijit_Editor_0'),"Editing the 6th field of the 1st row did not open the expected dijit.Editor.");
-							doh.t(dijit.byId('dijit_Editor_0')._focused);
+							doh.t(dijit.byId('dijit_Editor_0').focused);
 							doh.isNot(undefined,dijit.byId('dijit_Toolbar_0'),"Editor toolbar should have been created.");
 							doh.isNot(undefined,dijit.byId('dijit_Toolbar_0').domNode.parentNode,"Editor toolbar should have been attached to the DOM");
 						}),500);
diff --git a/dojox/grid/tests/robot/DataGrid_a11y.html b/dojox/grid/tests/robot/DataGrid_a11y.html
index e2e2b8c..f037c9e 100755
--- a/dojox/grid/tests/robot/DataGrid_a11y.html
+++ b/dojox/grid/tests/robot/DataGrid_a11y.html
@@ -103,7 +103,7 @@
 									try{
 										// this better have opened the expected editor or something very bad happened
 										doh.isNot(undefined,dijit.byId(editorids[i]),"Editing the "+i+" field of the 1st row did not open the expected editor.");
-										doh.t(dijit.byId(editorids[i])._focused);
+										doh.t(dijit.byId(editorids[i]).focused);
 										grid.edit.cancel();
 										doh.robot.keyPress(dojo.keys.RIGHT_ARROW,500);
 										doh.robot.sequence(function(){
diff --git a/dojox/grid/tests/robot/DataGrid_mouse.html b/dojox/grid/tests/robot/DataGrid_mouse.html
index fdbea46..8868450 100755
--- a/dojox/grid/tests/robot/DataGrid_mouse.html
+++ b/dojox/grid/tests/robot/DataGrid_mouse.html
@@ -386,7 +386,7 @@
 									try{
 										// this better have opened the expected editor or something very bad happened
 										doh.isNot(undefined,dijit.byId(editorids[i]),"Editing the "+i+" field of the 1st row did not open the expected editor.");
-										doh.t(dijit.byId(editorids[i])._focused);
+										doh.t(dijit.byId(editorids[i]).focused);
 										grid.edit.cancel();
 										nextTest(i+1);
 									}catch(e){
@@ -495,7 +495,7 @@
 									try{
 										// this better have opened the expected editor or something very bad happened
 										doh.isNot(undefined,dijit.byId(editorids[i]),"Editing the "+(i-editorids.length)+" field of the 2nd row after column drag and drop did not open the expected editor.");
-										doh.t(dijit.byId(editorids[i])._focused);
+										doh.t(dijit.byId(editorids[i]).focused);
 										grid.edit.cancel();
 										nextTest(i+1);
 									}catch(e){
diff --git a/dojox/grid/tests/support/test_data.js b/dojox/grid/tests/support/test_data.js
index 9045e9b..2ab095c 100644
--- a/dojox/grid/tests/support/test_data.js
+++ b/dojox/grid/tests/support/test_data.js
@@ -1,4 +1,5 @@
 // example sample data and code
+dojo.require("dojo.data.ItemFileWriteStore");
 (function(){
 	// some sample data
 	// global var "data"
diff --git a/dojox/grid/tests/support/yahoo_search.js b/dojox/grid/tests/support/yahoo_search.js
index fd28d95..2eae396 100644
--- a/dojox/grid/tests/support/yahoo_search.js
+++ b/dojox/grid/tests/support/yahoo_search.js
@@ -1,7 +1,7 @@
 // model that works with Yahoo Search API
 (function(){
 var nop = function(){};
-dojo.declare("dojox.grid._data.yahooSearch", dojox.grid._data.dynamic,
+dojo.declare("dojox.grid._data.yahooSearch", null,
 	function(inFields, inData) {
 		this.rowsPerPage = 20;
 		this.fieldNames = [];
diff --git a/dojox/grid/tests/test_data_grid.html b/dojox/grid/tests/test_data_grid.html
index 6760e87..ab69db3 100644
--- a/dojox/grid/tests/test_data_grid.html
+++ b/dojox/grid/tests/test_data_grid.html
@@ -37,7 +37,7 @@
 	<span dojoType="dojo.data.ItemFileWriteStore" 
 		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
 	</span>
-	<table dojoType="dojox.grid.DataGrid"
+	<table dojoType="dojox.grid.DataGrid" keepSelection=true
 		jsid="grid" id="grid" 
 		store="jsonStore" query="{ name: '*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
diff --git a/dojox/grid/tests/test_data_grid_hideHdr.html b/dojox/grid/tests/test_data_grid_hideHdr.html
index 8508c7a..8f4c30e 100644
--- a/dojox/grid/tests/test_data_grid_hideHdr.html
+++ b/dojox/grid/tests/test_data_grid_hideHdr.html
@@ -35,7 +35,7 @@
 </head>
 <body class="tundra">
 	<div class="heading">dojox.grid.DataGrid Basic Test</div>
-	<p><a href="http://docs.dojocampus.org/dojox/grid">grid docs</a> (focusable element before grid)</p>
+	<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">
 	</span>
@@ -49,6 +49,6 @@
 			</tr>
 		</thead>
 	</table>
-	<p> <a href="http://docs.dojocampus.org/dojox/grid">grid docs</a> (focusable element after grid)</p>
+	<p> <a href="http://dojotoolkit.org/reference-guide/dojox/grid">grid docs</a> (focusable element after grid)</p>
 </body>
 </html>
diff --git a/dojox/grid/tests/test_grid_colspan_resize.html b/dojox/grid/tests/test_grid_colspan_resize.html
index 7a65713..8cf647d 100644
--- a/dojox/grid/tests/test_grid_colspan_resize.html
+++ b/dojox/grid/tests/test_grid_colspan_resize.html
@@ -29,7 +29,6 @@
 		dojo.require("dijit.dijit");
 		dojo.require("dojo.data.ItemFileReadStore");
 		dojo.require("dojox.grid.DataGrid");
-//		dojo.require("dojox.grid._data.model");
 		dojo.require("dojo.parser");
 
 		var columnView =
diff --git a/dojox/grid/tests/test_grid_tooltip_menu.html b/dojox/grid/tests/test_grid_tooltip_menu.html
index ba246b1..2c03da5 100644
--- a/dojox/grid/tests/test_grid_tooltip_menu.html
+++ b/dojox/grid/tests/test_grid_tooltip_menu.html
@@ -62,9 +62,6 @@
 				},
 				hideTooltip = function(e) {
 					dijit.hideTooltip(e.cellNode);
-					// FIXME: make sure that pesky tooltip doesn't reappear!
-					// would be nice if there were a way to hide tooltip without regard to aroundNode.
-					dijit._masterTT._onDeck=null;
 				}
 			
 			// cell tooltip
diff --git a/dojox/grid/tests/test_treegrid_lazyloading.html b/dojox/grid/tests/test_treegrid_lazyloading.html
index 1ccb2f0..c77121f 100644
--- a/dojox/grid/tests/test_treegrid_lazyloading.html
+++ b/dojox/grid/tests/test_treegrid_lazyloading.html
@@ -1,6 +1,7 @@
-	<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
 <html>
-    <head>
+	<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">
@@ -18,20 +19,26 @@
 				text-align:center;
 				margin:1em;
 			}
-			.grid {
-                width: 70em;
-                height: 30em;
+			#grid1 {
+                width: 65em;
+                height: 25em;
+				border: 1px solid #333333;
+            }
+			#grid2 {
+                width: 65em;
+                height: 25em;
 				border: 1px solid #333333;
             }
         </style>
         <script type="text/javascript" src="../../../dojo/dojo.js"  djConfig="isDebug:true, parseOnLoad: true"></script>
         <script type="text/javascript">
             dojo.require("dojox.grid.LazyTreeGrid");
+			dojo.require("dojo.data.ItemFileWriteStore");
             dojo.require("dijit.tree.ForestStoreModel");
-            dojo.require("dojo.data.ItemFileWriteStore");
-            dojo.require("dojo.parser");
+			dojo.require("dojox.grid.LazyTreeGridStoreModel");
 			dojo.require("dijit.form.Button");
-
+			
+			// large dataset
 			var rows = 5;
 			var continentItems = [
 				{name:'South America', type:'continent', population:'', area:''},
@@ -96,59 +103,67 @@
 				]
 			};
 			
-			function deleteItem() {
-				var item = grid.getItem(3);
-				grid.store.deleteItem(item);
-			}
+			var readStore = new dojo.data.ItemFileReadStore({data: dataItems});
+			var writeStore = new dojo.data.ItemFileWriteStore({url: "support/countryStore.json?"});
+			var model1 = new dijit.tree.ForestStoreModel({store: readStore, childrenAttrs: ['children']})
+			var model2 = new dojox.grid.LazyTreeGridStoreModel({store: writeStore, childrenAttrs: ['children']});
+			
+			var layout = [
+				{name: 'Name', field: 'name', width: 'auto'},
+				{name: 'Type', field: 'type', width: 'auto'},
+				{name: 'Population', field: 'population', width: 'auto'},
+				{name: 'Area', field: 'area', width: 'auto'}
+			]
 			
-			var idx = 1000;
+			function refresh(flg){
+				grid2.refresh(flg);
+			}
+			var idx = 0;
 			function addItem(){
-				var item = {id:'test_' + idx, name:'test_' + idx, type:'', population: '', area: ''};
-				grid.store.newItem(item);
-				idx++;
+				var item = {id:'test_' + idx, name:'test_' + (idx++), type:'', population: '', area: ''};
+				grid2.store.newItem(item);
 			}
-			
 			function addChildItem(){
-				var addedItem = {id:'test_child_' + idx, name:'test_child_' + idx, type:'', population: '', area: ''};
-				var s = grid.store;
-				s.fetchItemByIdentity({identity: "Continent", onItem: function(item){
-					s.newItem(addedItem, {parent: item, attribute: "children"});
-					idx++;
-				}});
+				var parentItem = grid2.selection.getSelected()[0];
+				if(parentItem){
+					var item = {id:'test_child_' + idx, name:'test_child_' + (idx++), type:'', population: '', area: ''};
+					grid2.store.newItem(item, {parent: parentItem, attribute: "children"});
+				}
 			}
-			
 			function removeSelected(){
-				grid.removeSelectedRows();
+				grid2.removeSelectedRows();
+			}
+			function expandSelected(){
+				var item = grid2.selection.getSelected()[0];
+				if(item){
+					grid2.expand(grid2.store.getIdentity(item));
+				}
+			}
+			function collapseSelected(){
+				var item = grid2.selection.getSelected()[0];
+				if(item){
+					grid2.collapse(grid2.store.getIdentity(item));
+				}
 			}
-
         </script>
     </head>
     <body class="claro">
         <h1 class="title">Test: dojox.grid.TreeGrid - Lazy-loading for children items</h1>
-        <span dojoType="dojo.data.ItemFileWriteStore"
-              jsId="jsonStore" data="dataItems">
-        </span>
-
-        <div dojoType="dijit.tree.ForestStoreModel" jsId="continentModel"
-        	store="jsonStore" query="{type:'*'}" childrenAttrs="children"></div>
-		<div dojoType="dojox.grid.LazyTreeGridStoreModel" jsId="continentModel"
-        	store="jsonStore" query="{type:'*'}" childrenAttrs="children"></div>
-
-        <table jsid="grid" dojoType="dojox.grid.LazyTreeGrid" class="grid" defaultOpen=true rowsPerPage=5
-			   store="jsonStore" treeModel="continentModel" rowSelector="20px"  columnReordering=true>
-            <thead>
-                <tr>
-                    <th field="name" width="auto">Name</th>
-                    <th field="type" width="auto">Type</th> 
-					<th field="population" width="auto">Population</th>
-					<th field="area" width="auto">Area</th>
-                </tr>
-            </thead>
-        </table>
+		<h2>grid 1</h2>
+		<div id='grid1' jsid='grid1' dojoType='dojox.grid.LazyTreeGrid' 
+				structure='layout' treeModel='model1' rowSelector='true'></div>
+				
+		<h2>grid 2</h2>
+		<div id='grid2' jsid='grid2' dojoType='dojox.grid.LazyTreeGrid'
+				structure='layout' treeModel='model2' 
+				keepSelection='true' rowSelector='true'></div>
+		
+		<button dojoType="dijit.form.Button" onClick="refresh(true)">Refresh with state</button>
+		<button dojoType="dijit.form.Button" onClick="refresh(false)">Refresh without state</button>
+		<button dojoType="dijit.form.Button" onClick="addItem()">Add Item</button>
+		<button dojoType="dijit.form.Button" onClick="addChildItem()">Add Child Item</button>
+		<button dojoType="dijit.form.Button" onClick="removeSelected()">Delete Selected</button>
+		<button dojoType="dijit.form.Button" onClick="expandSelected()">Expand Selected</button>
+		<button dojoType="dijit.form.Button" onClick="collapseSelected()">Collapse Selected</button>
     </body>
-	
-	<button dojoType="dijit.form.Button" onClick="addItem()">Add Item</button>
-	<button dojoType="dijit.form.Button" onClick="addChildItem()">Add Child Item</button>
-	<button dojoType="dijit.form.Button" onClick="removeSelected()">Delete Selected</button>
 </html>
-
diff --git a/dojox/grid/tests/test_treegrid_performance.html b/dojox/grid/tests/test_treegrid_performance.html
index d6aab22..4bbf327 100644
--- a/dojox/grid/tests/test_treegrid_performance.html
+++ b/dojox/grid/tests/test_treegrid_performance.html
@@ -67,9 +67,9 @@
 		
 		dojo.addOnLoad(function(){
 			dojo.parser.parse(dojo.query(".testTitle")[0]);
-			dijit._Templated.getCachedTemplate(dojo.moduleUrl("dojox.grid","resources/_Grid.html"));
-			dijit._Templated.getCachedTemplate(dojo.moduleUrl("dojox.grid", "resources/Expando.html"));
-			dijit._Templated.getCachedTemplate(dojo.moduleUrl("dojox.grid","resources/View.html"));
+			dijit._TemplatedMixin.getCachedTemplate(dojo.moduleUrl("dojox.grid","resources/_Grid.html"));
+			dijit._TemplatedMixin.getCachedTemplate(dojo.moduleUrl("dojox.grid", "resources/Expando.html"));
+			dijit._TemplatedMixin.getCachedTemplate(dojo.moduleUrl("dojox.grid","resources/View.html"));
 			jsonStore.fetch({onComplete: function(){
 				doProfiling = dojo.isMoz && doProfiling;
 				dojo.connect(window, "onresize", function(){
diff --git a/dojox/grid/util.js b/dojox/grid/util.js
index cc0c227..1b431bd 100644
--- a/dojox/grid/util.js
+++ b/dojox/grid/util.js
@@ -1,8 +1,11 @@
-dojo.provide("dojox.grid.util");
+define([
+	"../main",
+	"dojo/_base/lang",
+	"dojo/dom"
+], function(dojox, lang, dom){
 
 // summary: grid utility library
-(function(){
-	var dgu = dojox.grid.util;
+	var dgu = lang.getObject("grid.util", true, dojox);
 
 	dgu.na = '...';
 	dgu.rowIndexTag = "gridRowIndex";
@@ -36,7 +39,7 @@ dojo.provide("dojox.grid.util");
 	};
 
 	dgu.removeNode = function(inNode){
-		inNode = dojo.byId(inNode);
+		inNode = dom.byId(inNode);
 		inNode && inNode.parentNode && inNode.parentNode.removeChild(inNode);
 		return inNode;
 	};
@@ -65,4 +68,7 @@ dojo.provide("dojox.grid.util");
 		inArray[inI] = inArray[inJ];
 		inArray[inJ] = cache;
 	};
-})();
+
+	return dojox.grid.util;
+
+});
\ No newline at end of file
diff --git a/dojox/highlight.js b/dojox/highlight.js
index a598862..5c30eb2 100644
--- a/dojox/highlight.js
+++ b/dojox/highlight.js
@@ -1,2 +1,3 @@
-dojo.provide("dojox.highlight");
-dojo.require("dojox.highlight._base");
+define(["./highlight/_base"], function(highlight){
+	return highlight;
+});
diff --git a/dojox/highlight/_base.js b/dojox/highlight/_base.js
index 516cefa..64bef1d 100644
--- a/dojox/highlight/_base.js
+++ b/dojox/highlight/_base.js
@@ -1,23 +1,23 @@
-dojo.provide("dojox.highlight._base");
-/*=====
-	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/
-		//
-		//
-	};
-=====*/
+define(["dojo", "dojox/main"], function(dojo, dojox){
 
-;(function(){
-	var dh = dojox.highlight,
-		C_NUMBER_RE = '\\b(0x[A-Za-z0-9]+|\\d+(\\.\\d+)?)';
-	
+	/*=====
+		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),
+		C_NUMBER_RE = '\\b(0x[A-Za-z0-9]+|\\d+(\\.\\d+)?)'
+	;
+	dh.languages = dh.languages || {};
 	// constants
 
 	dh.constants = {
@@ -457,6 +457,8 @@ dojo.provide("dojox.highlight._base");
 	};
 =====*/
 
-	dh.Code = function(p, n){ dh.init(n); };
+	dh.Code = function(props, node){ dh.init(node); };
+
+	return dh;
 
-})();
+});
diff --git a/dojox/highlight/languages/_all.js b/dojox/highlight/languages/_all.js
index 8f748b7..5937740 100644
--- a/dojox/highlight/languages/_all.js
+++ b/dojox/highlight/languages/_all.js
@@ -1,7 +1,2 @@
-dojo.provide("dojox.highlight.languages._all");
-
-/* groups of similar languages */
-dojo.require("dojox.highlight.languages._static");
-dojo.require("dojox.highlight.languages._dynamic");
-dojo.require("dojox.highlight.languages._www");
+define(["./_static", "./_dynamic", "./_www"], function(){})
 
diff --git a/dojox/highlight/languages/_dynamic.js b/dojox/highlight/languages/_dynamic.js
index 7907673..80f1960 100644
--- a/dojox/highlight/languages/_dynamic.js
+++ b/dojox/highlight/languages/_dynamic.js
@@ -1,9 +1 @@
-dojo.provide("dojox.highlight.languages._dynamic");
-
-/* common scripted languages */
-dojo.require("dojox.highlight.languages.python");
-// dojo.require("dojox.highlight.languages.perl");
-// dojo.require("dojox.highlight.languages.php");
-// dojo.require("dojox.highlight.languages.ruby");
-dojo.require("dojox.highlight.languages.xquery");
-dojo.require("dojox.highlight.languages.groovy");
+define(["./python", "./xquery", "./groovy"], function(){});
diff --git a/dojox/highlight/languages/_static.js b/dojox/highlight/languages/_static.js
index d94420e..a3eee6f 100644
--- a/dojox/highlight/languages/_static.js
+++ b/dojox/highlight/languages/_static.js
@@ -1,6 +1,3 @@
-dojo.provide("dojox.highlight.languages._static");
-
-/* common static languages */
-dojo.require("dojox.highlight.languages.cpp")
-dojo.require("dojox.highlight.languages.java");
-dojo.require("dojox.highlight.languages.delphi");
+define(["./cpp", "./java", "./delphi"], function(){
+	
+});
diff --git a/dojox/highlight/languages/_www.js b/dojox/highlight/languages/_www.js
index 631921c..94d45cf 100644
--- a/dojox/highlight/languages/_www.js
+++ b/dojox/highlight/languages/_www.js
@@ -1,8 +1 @@
-dojo.provide("dojox.highlight.languages._www");
-
-/* common web-centric languages */
-dojo.require("dojox.highlight.languages.xml");
-dojo.require("dojox.highlight.languages.html");
-dojo.require("dojox.highlight.languages.css");
-dojo.require("dojox.highlight.languages.django");
-dojo.require("dojox.highlight.languages.javascript");
\ No newline at end of file
+define(["./xml", "./html", "./css", "./django", "./javascript"], function(){ });
diff --git a/dojox/highlight/languages/cpp.js b/dojox/highlight/languages/cpp.js
index 97b1af6..148feaa 100644
--- a/dojox/highlight/languages/cpp.js
+++ b/dojox/highlight/languages/cpp.js
@@ -1,8 +1,5 @@
-dojo.provide("dojox.highlight.languages.cpp");
-
-dojo.require("dojox.highlight._base");
-
-(function(){
+define(["dojo", "dojox/main", "../_base"], function(dojo, dojox){
+	
 	var dh = dojox.highlight, dhc = dh.constants;
 	dh.languages.cpp = {
 		// summary: C++ highlight definitions
@@ -46,4 +43,7 @@ dojo.require("dojox.highlight._base");
 			}
 		]
 	};
-})();
+	
+	return dh.languages.cpp;
+
+});
diff --git a/dojox/highlight/languages/css.js b/dojox/highlight/languages/css.js
index c5b5cee..4909215 100644
--- a/dojox/highlight/languages/css.js
+++ b/dojox/highlight/languages/css.js
@@ -1,14 +1,11 @@
-dojo.provide("dojox.highlight.languages.css");
-
-dojo.require("dojox.highlight._base");
-dojo.require("dojox.highlight.languages.html");
-
-(function(){
-	var dh = dojox.highlight, dhc = dh.constants, dhl = dh.languages;
-	dhl.css = {
+define(["dojox/main", "../_base", "./html"], function(dojox, dh, html){
+	
+	var dhc = dh.constants;
+	return dh.languages.css = {
+		// summary: CSS Language definition file. 
 		defaultMode: {
 			contains: ['id', 'class', 'attr_selector', 'rules', 'comment'],
-			keywords: dhl.html.HTML_TAGS,
+			keywords: html.HTML_TAGS,
 			lexems: [dhc.IDENT_RE],
 			illegal: '='
 		},
@@ -89,4 +86,4 @@ dojo.require("dojox.highlight.languages.html");
 			}
 		]
 	};
-})();
+});
diff --git a/dojox/highlight/languages/delphi.js b/dojox/highlight/languages/delphi.js
index 288c0ee..4202a49 100644
--- a/dojox/highlight/languages/delphi.js
+++ b/dojox/highlight/languages/delphi.js
@@ -1,8 +1,5 @@
-dojo.provide("dojox.highlight.languages.delphi");
+define(["dojox/main", "../_base"], function(dojox){
 
-dojo.require("dojox.highlight._base");
-
-(function(){
 	var DELPHI_KEYWORDS = {
 		'and': 1, 'safecall': 1, 'cdecl': 1, 'then': 1, 'string': 1,
 		'exports': 1, 'library': 1, 'not': 1, 'pascal': 1, 'set': 1,
@@ -42,6 +39,7 @@ dojo.require("dojox.highlight._base");
 
 	var dh = dojox.highlight, dhc = dh.constants;
 	dh.languages.delphi = {
+		// summary: Delphi highlight definitions
 		defaultMode: {
 			lexems: [dhc.IDENT_RE],
 			illegal: '("|\\$[G-Zg-z]|\\/\\*|</)',
@@ -115,4 +113,6 @@ dojo.require("dojox.highlight._base");
 			}
 		]
 	};
-})();
+
+	return dh.languages.delphi
+});
diff --git a/dojox/highlight/languages/django.js b/dojox/highlight/languages/django.js
index 0e179f9..227a46c 100644
--- a/dojox/highlight/languages/django.js
+++ b/dojox/highlight/languages/django.js
@@ -1,10 +1,5 @@
-dojo.provide("dojox.highlight.languages.django");
+define(["dojox/main", "../_base", "./xml", "./html"], function(dojox){
 
-dojo.require("dojox.highlight._base");
-dojo.require("dojox.highlight.languages.xml");
-dojo.require("dojox.highlight.languages.html");
-
-(function(){
 	var dh = dojox.highlight, dhc = dh.constants, dhl = dh.languages, x = dhl.xml, h = dhl.html;
 	dhl.django = {
 		defaultMode: {
@@ -90,4 +85,7 @@ dojo.require("dojox.highlight.languages.html");
 			}
 		]
 	};
-})();
+
+	return dhl.django;
+	
+});
diff --git a/dojox/highlight/languages/groovy.js b/dojox/highlight/languages/groovy.js
index 46d7454..12ccac5 100644
--- a/dojox/highlight/languages/groovy.js
+++ b/dojox/highlight/languages/groovy.js
@@ -1,8 +1,5 @@
-dojo.provide("dojox.highlight.languages.groovy");
+define(["dojox/main", "../_base"], function(dojox){
 
-dojo.require("dojox.highlight._base");
-
-(function(){
 	var dh = dojox.highlight, dhc = dh.constants;
 	var GROOVY_KEYWORDS = {
 				'false': 1, 'int': 1, 'float': 1, 'while': 1, 'private': 1,
@@ -64,4 +61,7 @@ dojo.require("dojox.highlight._base");
 		//exporting constants
 		GROOVY_KEYWORDS: GROOVY_KEYWORDS
 	};
-})();
+
+	return dh.languages.groovy;
+	
+});
diff --git a/dojox/highlight/languages/html.js b/dojox/highlight/languages/html.js
index 1790dd3..34a85b9 100644
--- a/dojox/highlight/languages/html.js
+++ b/dojox/highlight/languages/html.js
@@ -1,9 +1,5 @@
-dojo.provide("dojox.highlight.languages.html");
+define(["dojox/main", "../_base", "./xml"], function(dojox){
 
-dojo.require("dojox.highlight._base");
-dojo.require("dojox.highlight.languages.xml");
-
-(function(){
 	var HTML_TAGS = {
 		'code': 1, 'kbd': 1, 'font': 1, 'noscript': 1, 'style': 1, 'img': 1,
 		'title': 1, 'menu': 1, 'tt': 1, 'tr': 1, 'param': 1, 'li': 1, 'tfoot': 1,
@@ -63,4 +59,7 @@ dojo.require("dojox.highlight.languages.xml");
 		HTML_ATTR: HTML_ATTR,
 		HTML_VALUE: HTML_VALUE
 	};
-})();
+
+	return dhl.html;
+	
+});
diff --git a/dojox/highlight/languages/java.js b/dojox/highlight/languages/java.js
index e34935b..14fe324 100644
--- a/dojox/highlight/languages/java.js
+++ b/dojox/highlight/languages/java.js
@@ -1,8 +1,5 @@
-dojo.provide("dojox.highlight.languages.java");
+define(["dojox/main", "../_base"], function(dojox){
 
-dojo.require("dojox.highlight._base");
-
-(function(){
 	var dh = dojox.highlight, dhc = dh.constants;
 	var javakeywords = {
 				'false': 1, 'int': 1, 'float': 1, 'while': 1, 'private': 1,
@@ -55,4 +52,6 @@ dojo.require("dojox.highlight._base");
 			}
 		]
 	};
-})();
+
+	return dh.languages.java;
+});
diff --git a/dojox/highlight/languages/javascript.js b/dojox/highlight/languages/javascript.js
index ead742f..9b7b9e1 100644
--- a/dojox/highlight/languages/javascript.js
+++ b/dojox/highlight/languages/javascript.js
@@ -1,8 +1,5 @@
-dojo.provide("dojox.highlight.languages.javascript");
+define(["dojox/main", "../_base"], function(dojox){
 
-dojo.require("dojox.highlight._base");
-
-(function(){
 	var dh = dojox.highlight, dhc = dh.constants;
 	dh.languages.javascript = {
 		defaultMode: {
@@ -48,4 +45,6 @@ dojo.require("dojox.highlight._base");
 			}
 		]
 	};
-})();
+
+	return dh.languages.javascript;
+});
diff --git a/dojox/highlight/languages/pygments/_html.js b/dojox/highlight/languages/pygments/_html.js
index 146aae4..e6c7454 100644
--- a/dojox/highlight/languages/pygments/_html.js
+++ b/dojox/highlight/languages/pygments/_html.js
@@ -1,21 +1,23 @@
-dojo.provide("dojox.highlight.languages.pygments._html");
+define(["dojo", "dojox/main", "../../_base"], function(dojo, dojox){
 
-// html-related constants
+	dojo.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,
-	"title": 1, "menu": 1, "tt": 1, "tr": 1, "param": 1, "li": 1, "tfoot": 1,
-	"th": 1, "input": 1, "td": 1, "dl": 1, "blockquote": 1, "fieldset": 1,
-	"big": 1, "dd": 1, "abbr": 1, "optgroup": 1, "dt": 1, "button": 1,
-	"isindex": 1, "p": 1, "small": 1, "div": 1, "dir": 1, "em": 1, "frame": 1,
-	"meta": 1, "sub": 1, "bdo": 1, "label": 1, "acronym": 1, "sup": 1,
-	"body": 1, "xml": 1, "basefont": 1, "base": 1, "br": 1, "address": 1,
-	"strong": 1, "legend": 1, "ol": 1, "script": 1, "caption": 1, "s": 1,
-	"col": 1, "h2": 1, "h3": 1, "h1": 1, "h6": 1, "h4": 1, "h5": 1, "table": 1,
-	"select": 1, "noframes": 1, "span": 1, "area": 1, "dfn": 1, "strike": 1,
-	"cite": 1, "thead": 1, "head": 1, "option": 1, "form": 1, "hr": 1,
-	"var": 1, "link": 1, "b": 1, "colgroup": 1, "ul": 1, "applet": 1, "del": 1,
-	"iframe": 1, "pre": 1, "frameset": 1, "ins": 1, "tbody": 1, "html": 1,
-	"samp": 1, "map": 1, "object": 1, "a": 1, "xmlns": 1, "center": 1,
-	"textarea": 1, "i": 1, "q": 1, "u": 1
-};
+	dojox.highlight.languages.pygments._html.tags = {
+		"code": 1, "kbd": 1, "font": 1, "noscript": 1, "style": 1, "img": 1,
+		"title": 1, "menu": 1, "tt": 1, "tr": 1, "param": 1, "li": 1, "tfoot": 1,
+		"th": 1, "input": 1, "td": 1, "dl": 1, "blockquote": 1, "fieldset": 1,
+		"big": 1, "dd": 1, "abbr": 1, "optgroup": 1, "dt": 1, "button": 1,
+		"isindex": 1, "p": 1, "small": 1, "div": 1, "dir": 1, "em": 1, "frame": 1,
+		"meta": 1, "sub": 1, "bdo": 1, "label": 1, "acronym": 1, "sup": 1,
+		"body": 1, "xml": 1, "basefont": 1, "base": 1, "br": 1, "address": 1,
+		"strong": 1, "legend": 1, "ol": 1, "script": 1, "caption": 1, "s": 1,
+		"col": 1, "h2": 1, "h3": 1, "h1": 1, "h6": 1, "h4": 1, "h5": 1, "table": 1,
+		"select": 1, "noframes": 1, "span": 1, "area": 1, "dfn": 1, "strike": 1,
+		"cite": 1, "thead": 1, "head": 1, "option": 1, "form": 1, "hr": 1,
+		"var": 1, "link": 1, "b": 1, "colgroup": 1, "ul": 1, "applet": 1, "del": 1,
+		"iframe": 1, "pre": 1, "frameset": 1, "ins": 1, "tbody": 1, "html": 1,
+		"samp": 1, "map": 1, "object": 1, "a": 1, "xmlns": 1, "center": 1,
+		"textarea": 1, "i": 1, "q": 1, "u": 1
+	};
+
+});
\ No newline at end of file
diff --git a/dojox/highlight/languages/pygments/_www.js b/dojox/highlight/languages/pygments/_www.js
index c3c4dbb..51b2861 100644
--- a/dojox/highlight/languages/pygments/_www.js
+++ b/dojox/highlight/languages/pygments/_www.js
@@ -1,8 +1 @@
-dojo.provide("dojox.highlight.languages.pygments._www");
-
-/* common web-centric languages */
-dojo.require("dojox.highlight.languages.pygments.xml");
-dojo.require("dojox.highlight.languages.pygments.html");
-dojo.require("dojox.highlight.languages.pygments.css");
-//dojo.require("dojox.highlight.languages.pygments.django");
-dojo.require("dojox.highlight.languages.pygments.javascript");
\ No newline at end of file
+define(["dojox/main", "../../_base", "./xml", "./html", "./css", "./javascript"], function(){ });
\ No newline at end of file
diff --git a/dojox/highlight/languages/pygments/css.js b/dojox/highlight/languages/pygments/css.js
index cf360f4..fcebf4e 100644
--- a/dojox/highlight/languages/pygments/css.js
+++ b/dojox/highlight/languages/pygments/css.js
@@ -1,9 +1,5 @@
-dojo.provide("dojox.highlight.languages.pygments.css");
+define(["dojox/main", "../../_base", "./_html"], function(dojox){
 
-dojo.require("dojox.highlight._base");
-dojo.require("dojox.highlight.languages.pygments._html");
-
-(function(){
 	var dh = dojox.highlight, dhl = dh.languages;
 	dhl.css = {
 		defaultMode: {
@@ -204,4 +200,6 @@ dojo.require("dojox.highlight.languages.pygments._html");
 			}
 		]
 	};
-})();
+
+	return dhl.css;
+});
diff --git a/dojox/highlight/languages/pygments/html.js b/dojox/highlight/languages/pygments/html.js
index a86481a..5af4731 100644
--- a/dojox/highlight/languages/pygments/html.js
+++ b/dojox/highlight/languages/pygments/html.js
@@ -1,9 +1,5 @@
-dojo.provide("dojox.highlight.languages.pygments.html");
+define(["dojox/main", "../../_base", "./_html"], function(dojox){
 
-dojo.require("dojox.highlight._base");
-dojo.require("dojox.highlight.languages.pygments._html");
-
-(function(){
 	var dh = dojox.highlight, dhl = dh.languages, tags = [],
 		ht = dhl.pygments._html.tags;
 	
@@ -94,4 +90,7 @@ dojo.require("dojox.highlight.languages.pygments._html");
 			}
 		]
 	};
-})();
+
+	return dhl.html;
+	
+});
diff --git a/dojox/highlight/languages/pygments/javascript.js b/dojox/highlight/languages/pygments/javascript.js
index 091c922..57eecdf 100644
--- a/dojox/highlight/languages/pygments/javascript.js
+++ b/dojox/highlight/languages/pygments/javascript.js
@@ -1,8 +1,5 @@
-dojo.provide("dojox.highlight.languages.pygments.javascript");
+define(["dojox/main", "../../_base"], function(dojox){
 
-dojo.require("dojox.highlight._base");
-
-(function(){
 	var dh = dojox.highlight, dhc = dh.constants;
 	dh.languages.javascript = {
 		defaultMode: {
@@ -145,4 +142,6 @@ dojo.require("dojox.highlight._base");
 			*/
 		]
 	};
-})();
+
+	return dh.languages.javascript;
+});
diff --git a/dojox/highlight/languages/pygments/xml.js b/dojox/highlight/languages/pygments/xml.js
index fe2388e..8591245 100644
--- a/dojox/highlight/languages/pygments/xml.js
+++ b/dojox/highlight/languages/pygments/xml.js
@@ -1,75 +1,76 @@
-dojo.provide("dojox.highlight.languages.pygments.xml");
+define(["dojox/main", "../../_base", "../xml"], function(dojox){
 
-dojo.require("dojox.highlight._base");
-dojox.highlight.languages.pygments.xml = {a: 1};
-dojox.highlight.languages.xml = {
-	defaultMode: {
-		contains: [
-			"name entity",
-			"comment", "comment preproc",
-			"_tag"
-		]
-	},
-	modes: [
-		// comments
-		{
-			className: "comment",
-			begin: "<!--", end: "-->"
-		},
-		{
-			className: "comment preproc",
-			begin: "\\<\\!\\[CDATA\\[", end: "\\]\\]\\>"
-		},
-		{
-			className: "comment preproc",
-			begin: "\\<\\!", end: "\\>"
-		},
-		{
-			className: "comment preproc",
-			begin: "\\<\\?", end: "\\?\\>",
-			relevance: 5
+	var dxml = dojox.highlight.languages.xml = {
+		defaultMode: {
+			contains: [
+				"name entity",
+				"comment", "comment preproc",
+				"_tag"
+			]
 		},
+		modes: [
+			// comments
+			{
+				className: "comment",
+				begin: "<!--", end: "-->"
+			},
+			{
+				className: "comment preproc",
+				begin: "\\<\\!\\[CDATA\\[", end: "\\]\\]\\>"
+			},
+			{
+				className: "comment preproc",
+				begin: "\\<\\!", end: "\\>"
+			},
+			{
+				className: "comment preproc",
+				begin: "\\<\\?", end: "\\?\\>",
+				relevance: 5
+			},
 
-		// strings
-		{
-			className: "string",
-			begin: "'", end: "'",
-			illegal: "\\n",
-			relevance: 0
-		},
-		{
-			className: "string",
-			begin: '"',
-			end: '"',
-			illegal: "\\n",
-			relevance: 0
-		},
+			// strings
+			{
+				className: "string",
+				begin: "'", end: "'",
+				illegal: "\\n",
+				relevance: 0
+			},
+			{
+				className: "string",
+				begin: '"',
+				end: '"',
+				illegal: "\\n",
+				relevance: 0
+			},
 		
-		// names
-		{
-			className: "name entity",
-			begin: "\\&[a-z]+;", end: "^"
-		},
-		{
-			className: "name tag",
-			begin: "\\b[a-z0-9_\\:\\-]+\\b", end: "^"
-		},
-		{
-			className: "name attribute",
-			begin: "\\b[a-z0-9_\\:\\-]+=", end: "^",
-			relevance: 0
-		},
+			// names
+			{
+				className: "name entity",
+				begin: "\\&[a-z]+;", end: "^"
+			},
+			{
+				className: "name tag",
+				begin: "\\b[a-z0-9_\\:\\-]+\\b", end: "^"
+			},
+			{
+				className: "name attribute",
+				begin: "\\b[a-z0-9_\\:\\-]+=", end: "^",
+				relevance: 0
+			},
 		
 		
-		{
-			className: "_tag",
-			begin: "\\<", end: "\\>",
-			contains: ["name tag", "name attribute", "string"]
-		},
-		{
-			className: "_tag",
-			begin: "\\</", end: "\\>",
-			contains: ["name tag"]
-		}
-	]
-};
+			{
+				className: "_tag",
+				begin: "\\<", end: "\\>",
+				contains: ["name tag", "name attribute", "string"]
+			},
+			{
+				className: "_tag",
+				begin: "\\</", end: "\\>",
+				contains: ["name tag"]
+			}
+		]
+	};
+
+	return dxml;
+});
\ No newline at end of file
diff --git a/dojox/highlight/languages/python.js b/dojox/highlight/languages/python.js
index c1581ea..8452ba8 100644
--- a/dojox/highlight/languages/python.js
+++ b/dojox/highlight/languages/python.js
@@ -1,98 +1,98 @@
-dojo.provide("dojox.highlight.languages.python");
+define(["dojox/main", "../_base"], function(dojox){
 
-dojo.require("dojox.highlight._base");
-
-(function(){
 	var dh = dojox.highlight, dhc = dh.constants;
 	dh.languages.python = {
-	    // summary: Python highlight definitions
-        defaultMode: {
-          lexems: [dhc.UNDERSCORE_IDENT_RE],
-          illegal: '(</|->)',
-          contains: ['comment', 'string', 'function', 'class', 'number', 'decorator'],
-          keywords: {'and': 1, 'elif': 1, 'is': 1, 'global': 1, 'as': 1, 'in': 1, 'if': 1,
-		  	'from': 1, 'raise': 1, 'for': 1, 'except': 1, 'finally': 1, 'print': 1,
-			'import': 1, 'pass': 1, 'None': 1, 'return': 1, 'exec': 1, 'else': 1,
-			'break': 1, 'not': 1, 'with': 1, 'class': 1, 'assert': 1, 'yield': 1,
-			'try': 1, 'while': 1, 'continue': 1, 'del': 1, 'or': 1, 'def': 1, 'lambda': 1}
-        },
-        modes: [
-          {
-            className: 'function',
-            lexems: [dhc.UNDERSCORE_IDENT_RE],
-            begin: '\\bdef ', end: ':',
-            illegal: '$',
-            keywords: {'def': 1},
-            contains: ['title', 'params'],
-            relevance: 10
-          },
-          {
-            className: 'class',
-            lexems: [dhc.UNDERSCORE_IDENT_RE],
-            begin: '\\bclass ', end: ':',
-            illegal: '[${]',
-            keywords: {'class': 1},
-            contains: ['title', 'params'],
-            relevance: 10
-          },
-          {
-          className: 'title',
-          begin: dhc.UNDERSCORE_IDENT_RE, end: '^'
-        },
-        {
-          className: 'params',
-          begin: '\\(', end: '\\)',
-          contains: ['string']
-        },
-        dhc.HASH_COMMENT_MODE,
-        dhc.C_NUMBER_MODE,
-        {
-          className: 'string',
-          begin: '\'\'\'', end: '\'\'\'',
-          relevance: 10
-        },
-        {
-          className: 'string',
-          begin: '"""', end: '"""',
-          relevance: 10
-        },
-        dhc.APOS_STRING_MODE,
-        dhc.QUOTE_STRING_MODE,
-        dhc.BACKSLASH_ESCAPE,
-        {
-          className: 'string',
-          begin: 'r\'', end: '\'',
-          relevance: 10
-        },
-        {
-          className: 'string',
-          begin: 'r"', end: '"',
-          relevance: 10
-        },
-        {
-          className: 'string',
-          begin: 'u\'', end: '(^|[^\\\\])\'',
-          relevance: 10
-        },
-        {
-          className: 'string',
-          begin: 'u"', end: '(^|[^\\\\])"',
-          relevance: 10
-        },
-        {
-          className: 'string',
-          begin: 'ur\'', end: '\'',
-          relevance: 10
-        },
-        {
-          className: 'string',
-          begin: 'ur"', end: '"',
-          relevance: 10
-        },
-        {
-          className: 'decorator',
-          begin: '@', end: '$'
-        }
-      ]
-    };
-})();
+		// summary: Python highlight definitions
+		defaultMode: {
+			lexems: [dhc.UNDERSCORE_IDENT_RE],
+			illegal: '(</|->)',
+			contains: ['comment', 'string', 'function', 'class', 'number', 'decorator'],
+			keywords: {'and': 1, 'elif': 1, 'is': 1, 'global': 1, 'as': 1, 'in': 1, 'if': 1,
+				'from': 1, 'raise': 1, 'for': 1, 'except': 1, 'finally': 1, 'print': 1,
+				'import': 1, 'pass': 1, 'None': 1, 'return': 1, 'exec': 1, 'else': 1,
+				'break': 1, 'not': 1, 'with': 1, 'class': 1, 'assert': 1, 'yield': 1,
+				'try': 1, 'while': 1, 'continue': 1, 'del': 1, 'or': 1, 'def': 1, 'lambda': 1
+			}
+		},
+		modes: [
+			{
+				className: 'function',
+				lexems: [dhc.UNDERSCORE_IDENT_RE],
+				begin: '\\bdef ', end: ':',
+				illegal: '$',
+				keywords: {'def': 1},
+				contains: ['title', 'params'],
+				relevance: 10
+			},
+			{
+				className: 'class',
+				lexems: [dhc.UNDERSCORE_IDENT_RE],
+				begin: '\\bclass ', end: ':',
+				illegal: '[${]',
+				keywords: {'class': 1},
+				contains: ['title', 'params'],
+				relevance: 10
+			},
+			{
+				className: 'title',
+				begin: dhc.UNDERSCORE_IDENT_RE, end: '^'
+			},
+			{
+				className: 'params',
+				begin: '\\(', end: '\\)',
+				contains: ['string']
+			},
+			dhc.HASH_COMMENT_MODE,
+			dhc.C_NUMBER_MODE,
+			{
+				className: 'string',
+				begin: '\'\'\'', end: '\'\'\'',
+				relevance: 10
+			},
+			{
+				className: 'string',
+				begin: '"""', end: '"""',
+				relevance: 10
+			},
+			dhc.APOS_STRING_MODE,
+			dhc.QUOTE_STRING_MODE,
+			dhc.BACKSLASH_ESCAPE,
+			{
+				className: 'string',
+				begin: 'r\'', end: '\'',
+				relevance: 10
+			},
+			{
+				className: 'string',
+				begin: 'r"', end: '"',
+				relevance: 10
+			},
+			{
+				className: 'string',
+				begin: 'u\'', end: '(^|[^\\\\])\'',
+				relevance: 10
+			},
+			{
+				className: 'string',
+				begin: 'u"', end: '(^|[^\\\\])"',
+				relevance: 10
+			},
+			{
+				className: 'string',
+				begin: 'ur\'', end: '\'',
+				relevance: 10
+			},
+			{
+				className: 'string',
+				begin: 'ur"', end: '"',
+				relevance: 10
+			},
+			{
+				className: 'decorator',
+				begin: '@', end: '$'
+			}
+		]
+	};
+
+	return dh.languages.python;
+});
diff --git a/dojox/highlight/languages/sql.js b/dojox/highlight/languages/sql.js
index 9980e6a..98f092f 100644
--- a/dojox/highlight/languages/sql.js
+++ b/dojox/highlight/languages/sql.js
@@ -1,8 +1,5 @@
-dojo.provide("dojox.highlight.languages.sql");
+define(["dojox/main", "../_base"], function(dojox){
 
-dojo.require("dojox.highlight._base");
-
-(function(){
 	var SQL_KEYWORDS = {
 		'all': 1, 'partial': 1, 'global': 1, 'month': 1,
 		'current_timestamp': 1, 'using': 1, 'go': 1, 'revoke': 1,
@@ -94,4 +91,6 @@ dojo.require("dojox.highlight._base");
 			dhc.BACKSLASH_ESCAPE
 		]
 	};
-})();
+
+	return dh.languages.sql;
+});
diff --git a/dojox/highlight/languages/xml.js b/dojox/highlight/languages/xml.js
index c502650..304825f 100644
--- a/dojox/highlight/languages/xml.js
+++ b/dojox/highlight/languages/xml.js
@@ -1,8 +1,5 @@
-dojo.provide("dojox.highlight.languages.xml");
+define(["dojox/main", "../_base"], function(dojox){
 
-dojo.require("dojox.highlight._base");
-
-(function(){
 	var XML_COMMENT = {
 		className: 'comment',
 		begin: '<!--', end: '-->'
@@ -10,7 +7,7 @@ dojo.require("dojox.highlight._base");
 	
 	var XML_ATTR = {
 		className: 'attribute',
-		begin: ' [a-zA-Z-]+=', end: '^',
+		begin: ' [a-zA-Z-]+\\s*=\\s*', end: '^',
 		contains: ['value']
 	};
 	
@@ -62,4 +59,7 @@ dojo.require("dojox.highlight._base");
 		XML_ATTR: XML_ATTR,
 		XML_VALUE: XML_VALUE
 	};
-})();
+
+	return dh.languages.xml;
+
+});
diff --git a/dojox/highlight/languages/xquery.js b/dojox/highlight/languages/xquery.js
index d17c71d..828080d 100644
--- a/dojox/highlight/languages/xquery.js
+++ b/dojox/highlight/languages/xquery.js
@@ -1,11 +1,9 @@
-dojo.provide("dojox.highlight.languages.xquery");
+define(["dojox/main", "../_base"], function(dojox){
 
-dojo.require("dojox.highlight._base");
+	// Very simple XQuery language file.  Would be nice
+	// to eventually handle more of the enclosed expressions
+	// and direct XML element construction
 
-// Very simple XQuery language file.  Would be nice
-// to eventually handle more of the enclosed expressions
-// and direct XML element construction
-(function(){
 	var XQUERY_COMMENT = {
 		className: 'comment',
 		begin: '\\(\\:', end: '\\:\\)'
@@ -53,4 +51,6 @@ dojo.require("dojox.highlight._base");
 		],
 		XQUERY_COMMENT: XQUERY_COMMENT
 	};
-})();
+
+	return dh.languages.xquery;
+});
diff --git a/dojox/highlight/tests/test_highlight.html b/dojox/highlight/tests/test_highlight.html
index 06a03d5..328157a 100644
--- a/dojox/highlight/tests/test_highlight.html
+++ b/dojox/highlight/tests/test_highlight.html
@@ -12,7 +12,7 @@
 		@import "../resources/highlight.css";
 
 		/* additional styling for this test case */
-		pre code[class]:after {
+		pre.item code[class]:after {
 		  content: 'highlight: ' attr(class);
 		  display: block; text-align: right;
 		  font-size: smaller;
@@ -35,8 +35,7 @@
 		}
 	</style>
 
-	<script type="text/javascript" djConfig="parseOnLoad: true, isDebug: true" src="../../../dojo/dojo.js"></script>
-	<script type="text/javascript" src="../_base.js"></script>
+	<script type="text/javascript" djConfig="parseOnLoad: false, isDebug: true" src="../../../dojo/dojo.js"></script>
 
 	<script type="text/javascript">
 		// initHighlightOnLoad is deprecated.
@@ -47,35 +46,27 @@
 		// will "do it's best" based on the language maps available
 		// at the time of construction.
 		//
-		dojo.require("dojox.highlight");
-
-		// several layer-like files have been provided grouping
-		// similar langauges, and a catch all language module
-		// dojox.highlight.languages._all is available for "best results"
-
-		// we need some language definitions:		
-		dojo.require("dojox.highlight.languages._all");
-		//dojo.require("dojox.highlight.languages._static");
-		//dojo.require("dojox.highlight.languages._dynamic");
-		//dojo.require("dojox.highlight.languages._www");
-
-		var lazyCode = function(){
-			
+		
+		require(["dojo/parser", "dojox/highlight", "dojox/highlight/languages/_all", "dojox/highlight/widget/Code"], function(){
+		    
 			dojo.query("code").forEach(dojox.highlight.init);
-			
 			dojo.xhrGet({
-				url: "../../../dojo/_base.js",
+				url: "../../../dojo/aspect.js",
 				load: function(data){
 					var n = dojo.byId("foobar"),
 						c = document.createElement('div'),
 						e = n.parentNode.parentNode;
-					c.innerHTML = '<pre><code class="javascript">' + data.replace(/\</gi,"<") + '</code></pre>';
+					c.innerHTML = '<pre class="item"><code class="javascript">' + data.replace(/\</gi,"<") + '</code></pre>';
 					e.replaceChild(c.firstChild, n.parentNode);
 					dojo.query("pre > code", e).forEach(dojox.highlight.init);
 				}
 			});
-		};	
-		dojo.addOnLoad(lazyCode); 
+			
+			dojo.ready(function(){
+				dojo.parser.parse();
+			})
+
+		});
 
 	</script>
 </head>
@@ -94,7 +85,7 @@
 
 	<p>Some Python code:</p>
 
-<pre><code>@requires_authorization
+<pre class="item"><code>@requires_authorization
 def somefunc(param1, param2):
   '''A docstring'''
   if param1 > param2: # interesting
@@ -107,11 +98,11 @@ class SomeClass:<br>    pass
 
 	<p>A chunk of PHP: </p>
 
-<pre><code class="php">
+<pre class="item"><code class="php">
 $opAr = array (    "-a|--append", // a or append toggle, nothing extra
         "-i|--input:", // i or input with next input being needed
         "-l|--list:",           // l with input needed
-		//"--foo",     // broken
+        //"--foo",     // broken
         "-f:",           // f with no input
         "--wot:"      // wot with input, no short
         );
@@ -178,7 +169,7 @@ return $return;
 
 	<p>A custom XML document:</p>
 
-<pre><code><?xml version="1.0"?>
+<pre class="item"><code><?xml version="1.0"?>
 <response value="ok">
   <text>Ok</text>
   <comment/>
@@ -190,7 +181,7 @@ return $return;
 
 	<p>Some HTML code:</p>
 
-<pre><code><head>
+<pre class="item"><code><head>
   <title>Title</title>
 <body>
   <p class="something">Something</p>
@@ -203,7 +194,7 @@ return $return;
 
 	<p>HTML with Django templates:</p>
 
-<pre><code>{% if articles|length %}
+<pre class="item"><code>{% if articles|length %}
 {% for article in articles %}
 
 {# Striped table #}
@@ -223,7 +214,7 @@ multiline.
 
 	<p>Some CSS code:</p>
 
-<pre><code>body, 
+<pre class="item"><code>body, 
 html {
   font: Tahoma, Arial, san-serif;
 }
@@ -240,20 +231,20 @@ p[lang=ru] {
 
 	<p>Explicit Python highlight:</p>
 
-<pre><code class="python">for x in [1, 2, 3]:
+<pre class="item"><code class="python">for x in [1, 2, 3]:
   count(x)
 </code></pre>
 
 	<p>Disabled highlighting:</p>
 
-<pre><code class="no-highlight"><div id="contents">
+<pre class="item"><code class="no-highlight"><div id="contents">
   <p>Hello, World!
 </div>
 </code></pre>
 
 	<p>Normal dojo-looking code</p>
 
-<pre><code>
+<pre class="item"><code>
 dojo.provide("some.object");
 dojo.declare("some.object",null,{
 	param: "value",
@@ -282,7 +273,7 @@ dojo.addOnLoad(function(){
 
 	<p>Lazy, xhr'd code:</p>
 
-<pre><code id="foobar"></code></pre>
+<pre class="item"><code id="foobar"></code></pre>
 
 <hr>
 
@@ -292,7 +283,7 @@ dojo.addOnLoad(function(){
 
 	<p>Markuped code (python), no language was specified:</p>
 
-<pre><code dojoType="dojo.highlight.Code">@requires_authorization
+<div data-dojo-type="dojox.highlight.widget.Code">@requires_authorization
 def somefunc(param1, param2):
   '''A docstring'''
   if param1 > param2: # interesting
@@ -301,11 +292,11 @@ def somefunc(param1, param2):
   return param2 - param1 + 1
   
 class SomeClass:<br>    pass
-</code></pre>
+</div>
 
 	<p>Markuped code, "python" was specified:</p>
 
-<pre><code dojoType="dojo.highlight.Code" class="python">
+<div data-dojo-type="dojox.highlight.widget.Code" class="python">
 @requires_authorization
 def somefunc(param1, param2):
   '''A docstring'''
@@ -315,11 +306,11 @@ def somefunc(param1, param2):
   return param2 - param1 + 1
   
 class SomeClass:<br>    pass
-</code></pre>
+</div>
 
 	<p>Some XQuery code:</p>
 
-<pre><code class="xquery">
+<pre class="item"><code class="xquery">
 declare variable $my:entityName as xs:string external;
 
 declare variable $databaseURI := concat('jdbc://getCreditDefaultSwapsByEntityName?cd%&', $my:entityName); 
@@ -355,7 +346,7 @@ declare function local:equityRows($root) {
 
 	<p>Some Java code:</p>
 
-<pre><code class="java">
+<pre class="item"><code class="java">
 import java.io.*;
 public final class DOHRobot extends Applet{
 	// The last reported mouse x,y.
@@ -419,7 +410,7 @@ public final class DOHRobot extends Applet{
 
 	<p>A Groovy fragment:</p>
 
-<pre><code class="groovy">
+<pre class="item"><code class="groovy">
 /*
 * A comment test block
 * 
diff --git a/dojox/highlight/widget/Code.js b/dojox/highlight/widget/Code.js
index 661642e..e5a543e 100644
--- a/dojox/highlight/widget/Code.js
+++ b/dojox/highlight/widget/Code.js
@@ -1,96 +1,100 @@
-dojo.provide("dojox.highlight.widget.Code");
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dojox.highlight");
+define(["dojo", "dijit", "dijit/_Widget", "dijit/_Templated", "dojox/highlight"], function(dojo, dijit){
 
-// A simple source code formatting widget that adds line numbering, alternating line colors
-// and line range support on top of dojox.highlight module.
-dojo.declare("highlight.Code",[dijit._Widget, dijit._Templated],{
-	url: "",
-	range:null,
-	style:"",
-	listType:"1",
-	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...
-	templateString:
-		'<div class="formatted" style="${style}">'+
-			'<div class="titleBar"></div>'+
-			'<ol type="${listType}" dojoAttachPoint="codeList" class="numbers"></ol>' +
-			'<div style="display:none" dojoAttachPoint="containerNode"></div>' +
-		'</div>',
-	
-	postCreate: function(){
-		this.inherited(arguments);
-		if(this.url){
-			// load from a url
-			dojo.xhrGet({
-				url: this.url,
-				// then poopulate:
-				load: dojo.hitch(this,"_populate"),
-				error: dojo.hitch(this,"_loadError")
-			});
-		}else{
-			// or just populate from our internal content
-			this._populate(this.containerNode.innerHTML);
-		}
-	},
+	dojo.declare("dojox.highlight.widget.Code",[dijit._Widget, dijit._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.
+
+		url: "",
+		range:null,
+		style:"",
+		listType:"1",
+		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...
+		templateString:
+			'<div class="formatted" style="${style}">'+
+				'<div class="titleBar"></div>'+
+				'<ol type="${listType}" dojoAttachPoint="codeList" class="numbers"></ol>' +
+				'<div style="display:none" dojoAttachPoint="containerNode"></div>' +
+			'</div>',
 	
-	_populate: function(data){
-		// put the content in a common node
-		this.containerNode.innerHTML =
-			"<pre><code class='" + this.lang + "'>" +
-				data.replace(/\</g,"<") +
-			"</code></pre>";
-		// highlight it
-		dojo.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){
-			// setup all the lines of the content as <li>'s
-			var li = dojo.doc.createElement('li');
-			// add some style sugar:
-			dojo.addClass(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._updateView();
-	},
+		postCreate: function(){
+			this.inherited(arguments);
+			if(this.url){
+				// load from a url
+				dojo.xhrGet({
+					url: this.url,
+					// then poopulate:
+					load: dojo.hitch(this,"_populate"),
+					error: dojo.hitch(this,"_loadError")
+				});
+			}else{
+				// or just populate from our internal content
+				this._populate(this.containerNode.innerHTML);
+			}
+		},
 	
-	setRange: function(/* Array */range){
-		// summary: update the view to a new passed range
-		if(dojo.isArray(range)){
-			this.range = range;
+		_populate: function(data){
+			// put the content in a common node
+			this.containerNode.innerHTML =
+				"<pre><code class='" + this.lang + "'>" +
+					data.replace(/\</g,"<") +
+				"</code></pre>";
+			// highlight it
+			dojo.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){
+				// setup all the lines of the content as <li>'s
+				var li = dojo.doc.createElement('li');
+				// add some style sugar:
+				dojo.addClass(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._updateView();
-		}
-	},
+		},
 	
-	_updateView: function(){
-		// summary: set the list to the current range
-		if(this.range){
-			var r = this.range;
-			this._lines
-				// hide them all
-				.style({ display:"none" })
-				.filter(function(n,i){
-					// remove nodes out of range
-					return (i + 1 >= r[0] && i + 1 <= r[1]);
-				})
-				// set them visible again
-				.style({ display:"" })
-			;
-			// set the "start" attribute on the OL so numbering works
-			dojo.attr(this.codeList,"start",r[0]);
-		}
-	},
+		// 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)){
+				this.range = range;
+				this._updateView();
+			}
+		},
+	
+		_updateView: function(){
+			// summary: set the list to the current range
+			if(this.range){
+				var r = this.range;
+				this._lines
+					// hide them all
+					.style({ display:"none" })
+					.filter(function(n,i){
+						// remove nodes out of range
+						return (i + 1 >= r[0] && i + 1 <= r[1]);
+					})
+					// set them visible again
+					.style({ display:"" })
+				;
+				// set the "start" attribute on the OL so numbering works
+				dojo.attr(this.codeList,"start",r[0]);
+			}
+		},
 	
-	_loadError: function(error){
-		// summary: a generic error handler for the url=""
-		console.warn("loading: ", this.url, " FAILED", error);
-	}
+		_loadError: function(error){
+			// summary: a generic error handler for the url=""
+			console.warn("loading: ", this.url, " FAILED", error);
+		}
+
+	});
+
 });
\ No newline at end of file
diff --git a/dojox/html.js b/dojox/html.js
index ace60eb..e923302 100644
--- a/dojox/html.js
+++ b/dojox/html.js
@@ -1,4 +1,3 @@
-dojo.provide("dojox.html");
-
-dojo.require("dojox.html._base");
-
+define(["./html/_base"], function (html) {
+	return html;
+});
\ No newline at end of file
diff --git a/dojox/html/_base.js b/dojox/html/_base.js
index 2796932..9de2918 100644
--- a/dojox/html/_base.js
+++ b/dojox/html/_base.js
@@ -1,20 +1,26 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/xhr",
+	"dojo/_base/window",
+	"dojo/_base/sniff",
+	"dojo/_base/url",
+	"dojo/dom-construct",
+	"dojo/html",
+	"dojo/_base/declare"
+], function (dojo, lang, xhrUtil, windowUtil, has, _Url, domConstruct, htmlUtil) {
 /*
 	Status: dont 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 (?)
-	
-	Gut the ContentPane, replace its _setContent with our own call to dojox.html.set()
-	
-
-*/
 
-dojo.provide("dojox.html._base");
+	Gut the ContentPane, replace its _setContent with our own call to dojox.html.set()
 
-dojo.require("dojo.html");
 
-(function() {
+*/
+	var html = dojo.getObject("dojox.html", true);
 
-	if(dojo.isIE){
+	if(has("ie")){
 		var alphaImageLoader = /(AlphaImageLoader\([^)]*?src=(['"]))(?![a-z]+:|\/)([^\r\n;}]+?)(\2[^)]*\)\s*[;}]?)/g;
 	}
 
@@ -28,13 +34,13 @@ dojo.require("dojo.html");
 	// @namespace dojo "http://dojotoolkit.org/dojo.css"; /* namespace URL should always be a absolute URI */
 	// @charset 'utf-8';
 	// @media print{ #menuRoot {display:none;} }
-		
+
 	// we adjust all paths that dont start on '/' or contains ':'
 	//(?![a-z]+:|\/)
 
 	var cssPaths = /(?:(?:@import\s*(['"])(?![a-z]+:|\/)([^\r\n;{]+?)\1)|url\(\s*(['"]?)(?![a-z]+:|\/)([^\r\n;]+?)\3\s*\))([a-z, \s]*[;}]?)/g;
 
-	var adjustCssPaths = dojox.html._adjustCssPaths = function(cssUrl, cssText){
+	var adjustCssPaths = html._adjustCssPaths = function(cssUrl, cssText){
 		//	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 ':'
@@ -70,15 +76,15 @@ dojo.require("dojo.html");
 		// like * > .myselector { filter:none; }
 		if(alphaImageLoader){
 			cssText = cssText.replace(alphaImageLoader, function(ignore, pre, delim, url, post){
-				return pre + (new dojo._Url(cssUrl, './'+url).toString()) + post;
+				return pre + (new _Url(cssUrl, './'+url).toString()) + post;
 			});
 		}
 
 		return cssText.replace(cssPaths, function(ignore, delimStr, strUrl, delimUrl, urlUrl, media){
 			if(strUrl){
-				return '@import "' + (new dojo._Url(cssUrl, './'+strUrl).toString()) + '"' + media;
+				return '@import "' + (new _Url(cssUrl, './'+strUrl).toString()) + '"' + media;
 			}else{
-				return 'url(' + (new dojo._Url(cssUrl, './'+urlUrl).toString()) + ')' + media;
+				return 'url(' + (new _Url(cssUrl, './'+urlUrl).toString()) + ')' + media;
 			}
 		});
 	};
@@ -88,20 +94,20 @@ dojo.require("dojo.html");
 	// <img style='filter:progid...AlphaImageLoader(src="noticeTheSrcHereRunsThroughHtmlSrc")' src="img">
 	var htmlAttrPaths = /(<[a-z][a-z0-9]*\s[^>]*)(?:(href|src)=(['"]?)([^>]*?)\3|style=(['"]?)([^>]*?)\5)([^>]*>)/gi;
 
-	var adjustHtmlPaths = dojox.html._adjustHtmlPaths = function(htmlUrl, cont){
+	var adjustHtmlPaths = html._adjustHtmlPaths = function(htmlUrl, cont){
 		var url = htmlUrl || "./";
 
 		return cont.replace(htmlAttrPaths,
 			function(tag, start, name, delim, relUrl, delim2, cssText, end){
 				return start + (name ?
-							(name + '=' + delim + (new dojo._Url(url, relUrl).toString()) + delim)
+							(name + '=' + delim + (new _Url(url, relUrl).toString()) + delim)
 						: ('style=' + delim2 + adjustCssPaths(url, cssText) + delim2)
 				) + end;
 			}
 		);
 	};
-	
-	var snarfStyles = dojox.html._snarfStyles = function	(/*String*/cssUrl, /*String*/cont, /*Array*/styles){
+
+	var snarfStyles = html._snarfStyles = function	(/*String*/cssUrl, /*String*/cont, /*Array*/styles){
 		/****************  cut out all <style> and <link rel="stylesheet" href=".."> **************/
 		// also return any attributes from this tag (might be a media attribute)
 		// if cssUrl is set it will adjust paths accordingly
@@ -131,7 +137,7 @@ dojo.require("dojo.html");
 		);
 	};
 
-	var snarfScripts = dojox.html._snarfScripts = function(cont, byRef){
+	var snarfScripts = html._snarfScripts = function(cont, byRef){
 		// summary
 		//		strips out script tags from cont
 		// invoke with
@@ -161,7 +167,7 @@ dojo.require("dojo.html");
 							return name.charAt(0)=="#" ? String.fromCharCode(name.substring(1)) : "&"+name+";";
 					}
 				});
-				dojo.xhrGet({
+				xhrUtil.get({
 					url: src,
 					sync: true,
 					load: function(code){
@@ -171,7 +177,7 @@ dojo.require("dojo.html");
 				});
 			}
 		}
-		
+
 		// 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,
 			function(ignore, delim, src, code){
@@ -184,19 +190,19 @@ dojo.require("dojo.html");
 			}
 		);
 	};
-	
-	var evalInGlobal = dojox.html.evalInGlobal = function(code, appendNode){
+
+	var evalInGlobal = html.evalInGlobal = function(code, appendNode){
 		// we do our own eval here as dojo.eval doesn't eval in global crossbrowser
 		// This work X browser but but it relies on a DOM
 		// plus it doesn't return anything, thats unrelevant here but not for dojo core
-		appendNode = appendNode || dojo.doc.body;
+		appendNode = appendNode || windowUtil.doc.body;
 		var n = appendNode.ownerDocument.createElement('script');
 		n.type = "text/javascript";
 		appendNode.appendChild(n);
 		n.text = code; // DOM 1 says this should work
 	};
 
-	dojo.declare("dojox.html._ContentSetter", [dojo.html._ContentSetter], {
+	html._ContentSetter = dojo.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
@@ -207,7 +213,7 @@ dojo.require("dojo.html");
 		executeScripts: false,
 		scriptHasHooks: false,
 		scriptHookReplacement: null,
-		
+
 		_renderStyles: function(styles){
 			// insert css from content into document head
 			this._styleNodes = [];
@@ -236,11 +242,11 @@ dojo.require("dojo.html");
 
 		empty: function() {
 			this.inherited("empty", arguments);
-			
+
 			// empty out the styles array from any previous use
 			this._styles = [];
 		},
-		
+
 		onBegin: function() {
 			// summary
 			//		Called after instantiation, but before set();
@@ -249,13 +255,13 @@ dojo.require("dojo.html");
 			//		This implementation extends that of dojo.html._ContentSetter
 			//		to add handling for adjustPaths, renderStyles on the html string content before it is set
 			this.inherited("onBegin", arguments);
-			
+
 			var cont = this.content,
 				node = this.node;
-				
+
 			var styles = this._styles;// init vars
 
-			if(dojo.isString(cont)){
+			if(lang.isString(cont)){
 				if(this.adjustPaths && this.referencePath){
 					cont = adjustHtmlPaths(this.referencePath, cont);
 				}
@@ -280,23 +286,23 @@ dojo.require("dojo.html");
 			}
 			this.content = cont;
 		},
-		
+
 		onEnd: function() {
 			// 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
-			
+
 			var code = this._code,
 				styles = this._styles;
-				
+
 			// clear old stylenodes from the DOM
 			// these were added by the last set call
 			// (in other words, if you dont keep and reuse the ContentSetter for a particular node
 			// .. you'll have no practical way to do this)
 			if(this._styleNodes && this._styleNodes.length){
 				while(this._styleNodes.length){
-					dojo.destroy(this._styleNodes.pop());
+					domConstruct.destroy(this._styleNodes.pop());
 				}
 			}
 			// render new style nodes
@@ -331,17 +337,20 @@ dojo.require("dojo.html");
 			// references to the style nodes we added
 			if(this._styleNodes && this._styleNodes.length){
 				while(this._styleNodes.length){
-					dojo.destroy(this._styleNodes.pop());
+					domConstruct.destroy(this._styleNodes.pop());
 				}
 			}
 			delete this._styleNodes;
 			// reset the defaults from the prototype
-			dojo.mixin(this, dojo.getObject(this.declaredClass).prototype);
+			// 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);
 		}
-		
+
 	});
-	
-	dojox.html.set = function(/* DomNode */ node, /* String|DomNode|NodeList */ cont, /* Object? */ params){
+
+	html.set = function(/* DomNode */ node, /* String|DomNode|NodeList */ cont, /* Object? */ params){
 		// TODO: add all the other options
 			// summary:
 			//		inserts (replaces) the given content into the given node
@@ -358,18 +367,19 @@ dojo.require("dojo.html");
 			//		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 dojo.html._setNodeContent(node, cont, true);
+			return htmlUtil._setNodeContent(node, cont, true);
 		}else{
 			// more options but slower
-			var op = new dojox.html._ContentSetter(dojo.mixin(
+			var op = new html._ContentSetter(dojo.mixin(
 					params,
 					{ content: cont, node: node }
 			));
 			return op.set();
 		}
 	};
-	
-})();
+
+	return html;
+});
\ No newline at end of file
diff --git a/dojox/html/ellipsis.js b/dojox/html/ellipsis.js
index a5cb1c3..363dc01 100644
--- a/dojox/html/ellipsis.js
+++ b/dojox/html/ellipsis.js
@@ -1,18 +1,16 @@
-dojo.provide("dojox.html.ellipsis");
-
-/*=====
-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
-}
-=====*/
-
-(function(d){
-	if(d.isMoz){ //TODO: feature detect text-overflow in computed style?
+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
+	}
+	=====*/
+	
+	if(d.isFF < 7){ //TODO: feature detect text-overflow in computed style?
 		// The delay (in ms) to wait so that we don't keep querying when many
 		// changes happen at once - set config "dojoxFFEllipsisDelay" if you
 		// want a different value
@@ -192,4 +190,4 @@ dojox.html.ellipsis = {
 			connFx();
 		});
 	}
-})(dojo);
+});
diff --git a/dojox/html/entities.js b/dojox/html/entities.js
index cff6fb5..bd0e6df 100755
--- a/dojox/html/entities.js
+++ b/dojox/html/entities.js
@@ -1,9 +1,9 @@
-define("dojox/html/entities", ["dojo", "dojox"], function(dojo, dojox) {
-(function(){
+define(["dojo/_base/lang"], function(lang) {
 	// dojox.html.entities.html [public] Array
 	//		Entity characters for HTML, represented as an array of
 	//		character code, entity name (minus & and ; wrapping.
 	//		The function wrapper is to fix global leking with the build tools.
+	var dhe = lang.getObject("dojox.html.entities",true);	
 	
 	var _applyEncodingMap = function(str, map){
 		// summary:
@@ -77,8 +77,8 @@ define("dojox/html/entities", ["dojo", "dojox"], function(dojo, dojox) {
 		});
 		return str;
 	};
-	
-	dojox.html.entities.html = [
+
+	dhe.html = [
 		["\u0026","amp"], ["\u0022","quot"],["\u003C","lt"], ["\u003E","gt"],
 		["\u00A0","nbsp"]
 	];
@@ -86,7 +86,7 @@ define("dojox/html/entities", ["dojo", "dojox"], function(dojo, dojox) {
 	// dojox.html.entities.latin [public] Array
 	//		Entity characters for Latin characters and similar, represented as an array of
 	//		character code, entity name (minus & and ; wrapping.
-	dojox.html.entities.latin = [
+	dhe.latin = [
 		["\u00A1","iexcl"],["\u00A2","cent"],["\u00A3","pound"],["\u20AC","euro"],
 		["\u00A4","curren"],["\u00A5","yen"],["\u00A6","brvbar"],["\u00A7","sect"],
 		["\u00A8","uml"],["\u00A9","copy"],["\u00AA","ordf"],["\u00AB","laquo"],
@@ -151,7 +151,7 @@ define("dojox/html/entities", ["dojo", "dojox"], function(dojo, dojox) {
 		["\u2030","permil"],["\u2039","lsaquo"],["\u203A","rsaquo"]
 	];
 	
-	dojox.html.entities.encode = function(str/*string*/, m /*array?*/){
+	dhe.encode = function(str/*string*/, m /*array?*/){
 		// summary:
 		//		Function to obtain an entity encoding for a specified character
 		// str:
@@ -166,8 +166,8 @@ define("dojox/html/entities", ["dojo", "dojox"], function(dojo, dojox) {
 			if(!m){
 				// Apply the basic mappings.  HTML should always come first when decoding
 				// as well.
-				str = _applyEncodingMap(str, dojox.html.entities.html);
-				str = _applyEncodingMap(str, dojox.html.entities.latin);
+				str = _applyEncodingMap(str, dhe.html);
+				str = _applyEncodingMap(str, dhe.latin);
 	
 			}else{
 				str = _applyEncodingMap(str, m);
@@ -176,7 +176,7 @@ define("dojox/html/entities", ["dojo", "dojox"], function(dojo, dojox) {
 		return str;
 	};
 	
-	dojox.html.entities.decode = function(str/*string*/, m /*array?*/){
+	dhe.decode = function(str/*string*/, m /*array?*/){
 		// summary:
 		//		Function to obtain an entity encoding for a specified character
 		// str:
@@ -191,8 +191,8 @@ define("dojox/html/entities", ["dojo", "dojox"], function(dojo, dojox) {
 			if(!m){
 				// Apply the basic mappings.  HTML should always come first when decoding
 				// as well.
-				str = _applyDecodingMap(str, dojox.html.entities.html);
-				str = _applyDecodingMap(str, dojox.html.entities.latin);
+				str = _applyDecodingMap(str, dhe.html);
+				str = _applyDecodingMap(str, dhe.latin);
 	
 			}else{
 				str = _applyDecodingMap(str, m);
@@ -200,6 +200,6 @@ define("dojox/html/entities", ["dojo", "dojox"], function(dojo, dojox) {
 		}
 		return str;
 	};
-})();
+	return dhe;
 });
 
diff --git a/dojox/html/ext-dojo/style.js b/dojox/html/ext-dojo/style.js
index 4ff6e66..df669a4 100644
--- a/dojox/html/ext-dojo/style.js
+++ b/dojox/html/ext-dojo/style.js
@@ -1,460 +1,456 @@
-dojo.provide("dojox.html.ext-dojo.style");
-dojo.experimental("dojox.html.ext-dojo.style");
-
-// 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
-dojo.mixin(dojox.html["ext-dojo"].style, {
-	supportsTransform: true,
-	_toPx: function(measure){
-		var ds = dojo.style, _conversion = this._conversion;
-		if(typeof measure === "number"){
-			return measure + "px";
-		}else if(measure.toLowerCase().indexOf("px") != -1){
-			return measure;
-		}
-		// "native" conversion in px
-		!_conversion.parentNode && dojo.place(_conversion, dojo.body());
-		ds(_conversion, "margin", measure);
-		return ds(_conversion, "margin");
-	},
-	init: function(){
-		var ds = dojo.style, docStyle = dojo.doc.documentElement.style, extStyle = dojox.html["ext-dojo"].style;
-		dojo.style = function(	/*DomNode|String*/ node,
-								/*String?|Object?*/ style,
-								/*String?*/ value){
-			// summary:
-			//      extended dojo.style()
-			// description:
-			//      extended dojo.style() function, capable of handling the css3 "transform" and "transform-origin" properties
-			// example:
-			// | dojo.style("rotate(20deg) scaleX(1.5) scaleY(2) skew(10deg, 20deg)")
-			var n = dojo.byId(node),
-				tr = (style == "transform"),
-				to = (style == "transformOrigin"),
-				args = arguments.length
-			;
-			if(args == 3){
+define(["dojo/_base/kernel", "dojo/dom-style", "dojo/_base/lang", "dojo/_base/html", "dojo/_base/sniff",
+		"dojo/_base/window", "dojo/dom", "dojo/dom-construct", "dojo/dom-style", "dojo/dom-attr"], 
+	function(kernel, domStyle, lang, Html, has, win, DOM, DOMConstruct, DOMStyle, DOMAttr){
+	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+
+	// description:
+	//	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){
+			var ds = Html.style, _conversion = this._conversion;
+			if(typeof measure === "number"){
+				return measure + "px";
+			}else if(measure.toLowerCase().indexOf("px") != -1){
+				return measure;
+			}
+			// "native" conversion in px
+			!_conversion.parentNode && DOMConstruct.place(_conversion, win.body());
+			ds(_conversion, "margin", measure);
+			return ds(_conversion, "margin");
+		},
+		init: function(){
+			var docStyle = win.doc.documentElement.style, extStyle = HtmlX["ext-dojo"].style,
+				sget = DOMStyle.get, sset = DOMStyle.set;
+			DOMStyle.get = function(/*DOMNode|String*/ node, /*String|Object*/ name){
+				var tr = (name == "transform"),
+					to = (name == "transformOrigin");
 				if(tr){
-					extStyle.setTransform(n, value, true);
+					return extStyle.getTransform(node);
 				}else if(to){
-					extStyle.setTransformOrigin(n, value);
+					return extStyle.getTransformOrigin(node);
 				}else{
-					ds(node, style, value);
+					return arguments.length == 2 ? sget(node, name) : sget(node);
 				}
-			}
-			if(args == 2){
+			};
+			DOMStyle.set = function(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){
+				var tr = (name == "transform"),
+					to = (name == "transformOrigin"),
+					n = DOM.byId(node)
+				;
 				if(tr){
-					return extStyle.getTransform(node);
+					return extStyle.setTransform(n, value, true);
 				}else if(to){
-					return extStyle.getTransformOrigin(node);
+					return extStyle.setTransformOrigin(n, value);
 				}else{
-					return ds(node, style);
+					return arguments.length == 3 ? sset(n, name, value) : sset(n, name);
+				}
+			};
+			// prefixes and property names
+			for(var i = 0, tPrefix = ["WebkitT", "MozT", "OT", "msT", "t"]; i < tPrefix.length; i++){
+				if(typeof docStyle[tPrefix[i] + "ransform"] !== "undefined"){
+					this.tPropertyName = tPrefix[i] + "ransform";
+				}
+				if(typeof docStyle[tPrefix[i] + "ransformOrigin"] !== "undefined"){
+					this.toPropertyName = tPrefix[i] + "ransformOrigin";
 				}
 			}
-		};
-		// prefixes and property names
-		for(var i = 0, tPrefix = ["WebkitT", "MozT", "OT", "t"]; i < tPrefix.length; i++){
-			if(typeof docStyle[tPrefix[i] + "ransform"] !== "undefined"){
-				this.tPropertyName = tPrefix[i] + "ransform";
+			if(this.tPropertyName){
+				this.setTransform = function(/*DomNode*/node, /*String*/ transform){
+					return DOMStyle.set(node, this.tPropertyName, transform);
+				};
+				this.getTransform = function(/*DomNode*/node){
+					return DOMStyle.get(node, this.tPropertyName);
+				};
+			}else if(has("ie")){
+				this.setTransform = this._setTransformFilter;
+				this.getTransform = this._getTransformFilter;
 			}
-			if(typeof docStyle[tPrefix[i] + "ransformOrigin"] !== "undefined"){
-				this.toPropertyName = tPrefix[i] + "ransformOrigin";
+			if(this.toPropertyName){
+				this.setTransformOrigin = function(/*DomNode*/node, /*String*/ transformOrigin){
+					return sset(node, this.toPropertyName, transformOrigin);
+				};
+				this.getTransformOrigin = function(/*DomNode*/node){
+					return sget(node, this.toPropertyName);
+				};
+			}else if(has("ie")){
+				this.setTransformOrigin = this._setTransformOriginFilter;
+				this.getTransformOrigin = this._getTransformOriginFilter;
+			}else{
+				this.supportsTransform = false;
 			}
-		}
-		if(this.tPropertyName){
-			this.setTransform = function(/*DomNode*/node, /*String*/ transform){
-				return dojo.style(node, this.tPropertyName, transform);
-			};
-			this.getTransform = function(/*DomNode*/node){
-				return dojo.style(node, this.tPropertyName);
-			};
-		}else if(dojo.isIE){
-			this.setTransform = this._setTransformFilter;
-			this.getTransform = this._getTransformFilter;
-		}
-		if(this.toPropertyName){
-			this.setTransformOrigin = function(/*DomNode*/node, /*String*/ transformOrigin){
-				return dojo.style(node, this.toPropertyName, transformOrigin);
-			};
-			this.getTransformOrigin = function(/*DomNode*/node){
-				return dojo.style(node, this.toPropertyName);
-			};
-		}else if(dojo.isIE){
-			this.setTransformOrigin = this._setTransformOriginFilter;
-			this.getTransformOrigin = this._getTransformOriginFilter;
-		}else{
-			this.supportsTransform = false;
-		}
-		this._conversion = dojo.create("div", {
-			style: {
-				position: "absolute",
-				top: "-100px",
-				left: "-100px",
-				fontSize: 0,
-				width: "0",
-				backgroundPosition: "50% 50%"
+			this._conversion = DOMConstruct.create("div", {
+				style: {
+					position: "absolute",
+					top: "-100px",
+					left: "-100px",
+					fontSize: 0,
+					width: "0",
+					backgroundPosition: "50% 50%"
+				}
+			});
+		},
+		_notSupported: function(){
+			console.warn("Sorry, this browser doesn't support transform and transform-origin");
+		},
+		_setTransformOriginFilter: function(/*DomNode*/ node, /*String*/ transformOrigin){
+			var to = lang.trim(transformOrigin)
+				.replace(" top", " 0")
+				.replace("left ", "0 ")
+				.replace(" center", "50%")
+				.replace("center ", "50% ")
+				.replace(" bottom", " 100%")
+				.replace("right ", "100% ")
+				.replace(/\s+/, " "),
+				toAry = to.split(" "),
+				n = DOM.byId(node),
+				t = this.getTransform(n),
+				validOrigin = true
+			;
+			for(var i = 0; i < toAry.length; i++){
+				validOrigin = validOrigin && /^0|(\d+(%|px|pt|in|pc|mm|cm))$/.test(toAry[i]);
+				if(toAry[i].indexOf("%") == -1){
+					toAry[i] = this._toPx(toAry[i]);
+				}
 			}
-		});
-	},
-	_notSupported: function(){
-		console.warn("Sorry, this browser doesn't support transform and transform-origin");
-	},
-	_setTransformOriginFilter: function(/*DomNode*/ node, /*String*/ transformOrigin){
-		var to = dojo.trim(transformOrigin)
-			.replace(" top", " 0")
-			.replace("left ", "0 ")
-			.replace(" center", "50%")
-			.replace("center ", "50% ")
-			.replace(" bottom", " 100%")
-			.replace("right ", "100% ")
-			.replace(/\s+/, " "),
-			toAry = to.split(" "),
-			n = dojo.byId(node),
-			t = this.getTransform(n),
-			validOrigin = true
-		;
-		for(var i = 0; i < toAry.length; i++){
-			validOrigin = validOrigin && /^0|(\d+(%|px|pt|in|pc|mm|cm))$/.test(toAry[i]);
-			if(toAry[i].indexOf("%") == -1){
-				toAry[i] = this._toPx(toAry[i]);
+			if(!validOrigin || !toAry.length || toAry.length > 2 ){
+				return transformOrigin;
 			}
-		}
-		if(!validOrigin){
-			return;
-		}
-		if(!toAry.length || toAry.length > 2 ){
-			return;
-		}
-		dojo.attr(n, "dojo-transform-origin", toAry.join(" "));
-		t && this.setTransform(node, t);
-	},
-	_getTransformOriginFilter: function(/*DomNode*/ node){
-		return dojo.attr(node, "dojo-transform-origin") || "50% 50%";
-	},
-	_setTransformFilter: function(/*DomNode*/ node, /*String*/ transform){
-		// Using the Matrix Filter to implement the transform property on IE
-		var t = transform.replace(/\s/g, ""),
-			n = dojo.byId(node),
-			transforms = t.split(")"),
-			toRad = 1, toRad1 = 1,
-			mstr = "DXImageTransform.Microsoft.Matrix",
-			hasAttr = dojo.hasAttr,
-			attr = dojo.attr,
-			// Math functions
-			PI = Math.PI, cos = Math.cos, sin = Math.sin, tan = Math.tan, max = Math.max, min = Math.min, abs = Math.abs,
-			degToRad = PI/180, gradToRad = PI/200,
+			Html.attr(n, "dojo-transform-origin", toAry.join(" "));
+			t && this.setTransform(node, t);
+			return transformOrigin;
+		},
+		_getTransformOriginFilter: function(/*DomNode*/ node){
+			return Html.attr(node, "dojo-transform-origin") || "50% 50%";
+		},
+		_setTransformFilter: function(/*DomNode*/ node, /*String*/ transform){
+			// Using the Matrix Filter to implement the transform property on IE
+			var t = transform.replace(/\s/g, ""),
+				n = DOM.byId(node),
+				transforms = t.split(")"),
+				toRad = 1, toRad1 = 1,
+				mstr = "DXImageTransform.Microsoft.Matrix",
+				hasAttr = DOMAttr.has,
+				attr = Html.attr,
+				// Math functions
+				PI = Math.PI, cos = Math.cos, sin = Math.sin, tan = Math.tan, max = Math.max, min = Math.min, abs = Math.abs,
+				degToRad = PI/180, gradToRad = PI/200,
 
-			// current transform
-			ct = "", currentTransform = "",
-			matchingTransforms = [],
-			x0 = 0, y0 = 0, dx = 0, dy = 0, xc = 0, yc = 0, a = 0,
+				// current transform
+				ct = "", currentTransform = "",
+				matchingTransforms = [],
+				x0 = 0, y0 = 0, dx = 0, dy = 0, xc = 0, yc = 0, a = 0,
 
-			// default transform, identity matrix
-			m11 = 1, m12 = 0, m21 = 0, m22 = 1,
+				// default transform, identity matrix
+				m11 = 1, m12 = 0, m21 = 0, m22 = 1,
 
-			// no translation
-			tx = 0, ty = 0,
-			props = [m11, m12, m21, m22, tx, ty],
-			hasMatrix = false,
-			ds = dojo.style,
-			newPosition = ds(n, "position") == "absolute" ? "absolute" : "relative",
-			w = ds(n, "width") + ds(n, "paddingLeft") + ds(n, "paddingRight"),
-			h = ds(n, "height") + ds(n, "paddingTop") + ds(n, "paddingBottom"),
-			toPx = this._toPx
-		;
+				// no translation
+				tx = 0, ty = 0,
+				props = [m11, m12, m21, m22, tx, ty],
+				hasMatrix = false,
+				ds = Html.style,
+				newPosition = ds(n, "position") == "absolute" ? "absolute" : "relative",
+				w = ds(n, "width") + ds(n, "paddingLeft") + ds(n, "paddingRight"),
+				h = ds(n, "height") + ds(n, "paddingTop") + ds(n, "paddingBottom"),
+				toPx = this._toPx
+			;
 
-		!hasAttr(n, "dojo-transform-origin") && this.setTransformOrigin(n, "50% 50%");
+			!hasAttr(n, "dojo-transform-origin") && this.setTransformOrigin(n, "50% 50%");
 
-		for(var i = 0, l = transforms.length; i < l; i++){
-			matchingTransforms = transforms[i].match(/matrix|rotate|scaleX|scaleY|scale|skewX|skewY|skew|translateX|translateY|translate/);
-			currentTransform = matchingTransforms ? matchingTransforms[0] : "";
-			switch(currentTransform){
-				case "matrix":
-					// generic transformation
-					//
-					// matrix:
-					// m11        m12
-					//
-					// m21        m22
-					//
-					ct = transforms[i].replace(/matrix\(|\)/g, "");
-					var matrix = ct.split(",");
-					m11 = props[0]*matrix[0] + props[1]*matrix[2];
-					m12 = props[0]*matrix[1] + props[1]*matrix[3];
-					m21 = props[2]*matrix[0] + props[3]*matrix[2];
-					m22 = props[2]*matrix[1] + props[3]*matrix[3];
-					tx = props[4] + matrix[4];
-					ty = props[5] + matrix[5];
-				break;
-				case "rotate":
-					// rotate
-					//
-					// rotation angle:
-					// a (rad, deg or grad)
-					//
-					// matrix:
-					// cos(a)     -sin(a)
-					//
-					// sin(a)     cos(a)
-					//
-					ct = transforms[i].replace(/rotate\(|\)/g, "");
-					toRad = ct.indexOf("deg") != -1 ? degToRad : ct.indexOf("grad") != -1 ? gradToRad : 1;
-					a = parseFloat(ct)*toRad;
-					var s = sin(a),
-						c = cos(a)
-					;
-					m11 = props[0]*c + props[1]*s;
-					m12 = -props[0]*s + props[1]*c;
-					m21 = props[2]*c + props[3]*s;
-					m22 = -props[2]*s + props[3]*c;
-				break;
-				case "skewX":
-					// skewX
-					//
-					// skew angle:
-					// a (rad, deg or grad)
-					//
-					// matrix:
-					// 1          tan(a)
-					//
-					// 0          1
-					//
-					ct = transforms[i].replace(/skewX\(|\)/g, "");
-					toRad = ct.indexOf("deg") != -1 ? degToRad : ct.indexOf("grad") != -1 ? gradToRad : 1;
-					var ta = tan(parseFloat(ct)*toRad);
-					m11 = props[0];
-					m12 = props[0]*ta + props[1];
-					m21 = props[2];
-					m22 = props[2]*ta + props[3];
-				break;
-				case "skewY":
-					// skewY
-					//
-					// skew angle:
-					// a (rad, deg or grad)
-					//
-					// matrix:
-					// 1          0
-					//
-					// tan(a)     1
-					//
-					ct = transforms[i].replace(/skewY\(|\)/g, "");
-					toRad = ct.indexOf("deg") != -1 ? degToRad : ct.indexOf("grad") != -1 ? gradToRad : 1;
-					ta = tan(parseFloat(ct)*toRad);
-					m11 = props[0] + props[1]*ta;
-					m12 = props[1];
-					m21 = props[2] + props[3]*ta;
-					m22 = props[3];
-				break;
-				case "skew":
-					// skew
-					//
-					// skew angles:
-					// a0 (rad, deg or grad)
-					// a1 (rad, deg or grad)
-					//
-					// matrix:
-					// 1          tan(a0)
-					//
-					// tan(a1)    1
-					//
-					ct = transforms[i].replace(/skew\(|\)/g, "");
-					var skewAry = ct.split(",");
-					skewAry[1] = skewAry[1] || "0";
-					toRad = skewAry[0].indexOf("deg") != -1 ? degToRad : skewAry[0].indexOf("grad") != -1 ? gradToRad : 1;
-					toRad1 = skewAry[1].indexOf("deg") != -1 ? degToRad : skewAry[1].indexOf("grad") != -1 ? gradToRad : 1;
-					var a0 = tan(parseFloat(skewAry[0])*toRad),
-						a1 = tan(parseFloat(skewAry[1])*toRad1)
+			for(var i = 0, l = transforms.length; i < l; i++){
+				matchingTransforms = transforms[i].match(/matrix|rotate|scaleX|scaleY|scale|skewX|skewY|skew|translateX|translateY|translate/);
+				currentTransform = matchingTransforms ? matchingTransforms[0] : "";
+				switch(currentTransform){
+					case "matrix":
+						// generic transformation
+						//
+						// matrix:
+						// m11        m12
+						//
+						// m21        m22
+						//
+						ct = transforms[i].replace(/matrix\(|\)/g, "");
+						var matrix = ct.split(",");
+						m11 = props[0]*matrix[0] + props[1]*matrix[2];
+						m12 = props[0]*matrix[1] + props[1]*matrix[3];
+						m21 = props[2]*matrix[0] + props[3]*matrix[2];
+						m22 = props[2]*matrix[1] + props[3]*matrix[3];
+						tx = props[4] + matrix[4];
+						ty = props[5] + matrix[5];
+					break;
+					case "rotate":
+						// rotate
+						//
+						// rotation angle:
+						// a (rad, deg or grad)
+						//
+						// matrix:
+						// cos(a)     -sin(a)
+						//
+						// sin(a)     cos(a)
+						//
+						ct = transforms[i].replace(/rotate\(|\)/g, "");
+						toRad = ct.indexOf("deg") != -1 ? degToRad : ct.indexOf("grad") != -1 ? gradToRad : 1;
+						a = parseFloat(ct)*toRad;
+						var s = sin(a),
+							c = cos(a)
+						;
+						m11 = props[0]*c + props[1]*s;
+						m12 = -props[0]*s + props[1]*c;
+						m21 = props[2]*c + props[3]*s;
+						m22 = -props[2]*s + props[3]*c;
+					break;
+					case "skewX":
+						// skewX
+						//
+						// skew angle:
+						// a (rad, deg or grad)
+						//
+						// matrix:
+						// 1          tan(a)
+						//
+						// 0          1
+						//
+						ct = transforms[i].replace(/skewX\(|\)/g, "");
+						toRad = ct.indexOf("deg") != -1 ? degToRad : ct.indexOf("grad") != -1 ? gradToRad : 1;
+						var ta = tan(parseFloat(ct)*toRad);
+						m11 = props[0];
+						m12 = props[0]*ta + props[1];
+						m21 = props[2];
+						m22 = props[2]*ta + props[3];
+					break;
+					case "skewY":
+						// skewY
+						//
+						// skew angle:
+						// a (rad, deg or grad)
+						//
+						// matrix:
+						// 1          0
+						//
+						// tan(a)     1
+						//
+						ct = transforms[i].replace(/skewY\(|\)/g, "");
+						toRad = ct.indexOf("deg") != -1 ? degToRad : ct.indexOf("grad") != -1 ? gradToRad : 1;
+						ta = tan(parseFloat(ct)*toRad);
+						m11 = props[0] + props[1]*ta;
+						m12 = props[1];
+						m21 = props[2] + props[3]*ta;
+						m22 = props[3];
+					break;
+					case "skew":
+						// skew
+						//
+						// skew angles:
+						// a0 (rad, deg or grad)
+						// a1 (rad, deg or grad)
+						//
+						// matrix:
+						// 1          tan(a0)
+						//
+						// tan(a1)    1
+						//
+						ct = transforms[i].replace(/skew\(|\)/g, "");
+						var skewAry = ct.split(",");
+						skewAry[1] = skewAry[1] || "0";
+						toRad = skewAry[0].indexOf("deg") != -1 ? degToRad : skewAry[0].indexOf("grad") != -1 ? gradToRad : 1;
+						toRad1 = skewAry[1].indexOf("deg") != -1 ? degToRad : skewAry[1].indexOf("grad") != -1 ? gradToRad : 1;
+						var a0 = tan(parseFloat(skewAry[0])*toRad),
+							a1 = tan(parseFloat(skewAry[1])*toRad1)
+						;
+						m11 = props[0] + props[1]*a1;
+						m12 = props[0]*a0 + props[1];
+						m21 = props[2]+ props[3]*a1;
+						m22 = props[2]*a0 + props[3];
+					break;
+					case "scaleX":
+						// scaleX
+						//
+						// scale factor:
+						// sx
+						//
+						// matrix:
+						// sx         0
+						//
+						// 0          1
+						//
+						ct = parseFloat(transforms[i].replace(/scaleX\(|\)/g, "")) || 1;
+						m11 = props[0]*ct;
+						m12 = props[1];
+						m21 = props[2]*ct;
+						m22 = props[3];
+					break;
+					case "scaleY":
+						// scaleY
+						//
+						// scale factor:
+						// sy
+						//
+						// matrix:
+						// 1          0
+						//
+						// 0          sy
+						//
+						ct = parseFloat(transforms[i].replace(/scaleY\(|\)/g, "")) || 1;
+						m11 = props[0];
+						m12 = props[1]*ct;
+						m21 = props[2];
+						m22 = props[3]*ct;
+					break;
+					case "scale":
+						// scale
+						//
+						// scale factor:
+						// sx, sy
+						//
+						// matrix:
+						// sx         0
+						//
+						// 0          sy
+						//
+						ct = transforms[i].replace(/scale\(|\)/g, "");
+						var scaleAry = ct.split(",");
+						scaleAry[1] = scaleAry[1] || scaleAry[0];
+						m11 = props[0]*scaleAry[0];
+						m12 = props[1]*scaleAry[1];
+						m21 = props[2]*scaleAry[0];
+						m22 = props[3]*scaleAry[1];
+					break;
+					case "translateX":
+						ct = parseInt(transforms[i].replace(/translateX\(|\)/g, "")) || 1;
+						m11 = props[0];
+						m12 = props[1];
+						m21 = props[2];
+						m22 = props[3];
+						tx = toPx(ct);
+						tx && attr(n, "dojo-transform-matrix-tx", tx);
+					break;
+					case "translateY":
+						ct = parseInt(transforms[i].replace(/translateY\(|\)/g, "")) || 1;
+						m11 = props[0];
+						m12 = props[1];
+						m21 = props[2];
+						m22 = props[3];
+						ty = toPx(ct);
+						ty && attr(n, "dojo-transform-matrix-ty", ty);
+					break;
+					case "translate":
+						ct = transforms[i].replace(/translate\(|\)/g, "");
+						m11 = props[0];
+						m12 = props[1];
+						m21 = props[2];
+						m22 = props[3];
+						var translateAry = ct.split(",");
+						translateAry[0] = parseInt(toPx(translateAry[0])) || 0;
+						translateAry[1] = parseInt(toPx(translateAry[1])) || 0;
+						tx = translateAry[0];
+						ty = translateAry[1];
+						tx && attr(n, "dojo-transform-matrix-tx", tx);
+						ty && attr(n, "dojo-transform-matrix-ty", ty);
+					break;
+				}
+				props = [m11, m12, m21, m22, tx, ty];
+			}
+			// test
+			var Bx = min(w*m11 + h*m12, min(min(w*m11, h*m12), 0)),
+				By = min(w*m21 + h*m22, min(min(w*m21, h*m22), 0))
+			;
+			dx = -Bx;
+			dy = -By;
+			if(has("ie") < 8){
+				// on IE < 8 the node must have hasLayout = true
+				n.style.zoom = "1";
+				if(newPosition != "absolute"){
+					var parentWidth = ds(node.parentNode, "width"),
+						tw = abs(w*m11),
+						th = abs(h*m12),
+						wMax = max(tw + th, max(max(th, tw), 0))
 					;
-					m11 = props[0] + props[1]*a1;
-					m12 = props[0]*a0 + props[1];
-					m21 = props[2]+ props[3]*a1;
-					m22 = props[2]*a0 + props[3];
-				break;
-				case "scaleX":
-					// scaleX
-					//
-					// scale factor:
-					// sx
-					//
-					// matrix:
-					// sx         0
-					//
-					// 0          1
-					//
-					ct = parseFloat(transforms[i].replace(/scaleX\(|\)/g, "")) || 1;
-					m11 = props[0]*ct;
-					m12 = props[1];
-					m21 = props[2]*ct;
-					m22 = props[3];
-				break;
-				case "scaleY":
-					// scaleY
-					//
-					// scale factor:
-					// sy
-					//
-					// matrix:
-					// 1          0
-					//
-					// 0          sy
-					//
-					ct = parseFloat(transforms[i].replace(/scaleY\(|\)/g, "")) || 1;
-					m11 = props[0];
-					m12 = props[1]*ct;
-					m21 = props[2];
-					m22 = props[3]*ct;
-				break;
-				case "scale":
-					// scale
-					//
-					// scale factor:
-					// sx, sy
-					//
-					// matrix:
-					// sx         0
-					//
-					// 0          sy
-					//
-					ct = transforms[i].replace(/scale\(|\)/g, "");
-					var scaleAry = ct.split(",");
-					scaleAry[1] = scaleAry[1] || scaleAry[0];
-					m11 = props[0]*scaleAry[0];
-					m12 = props[1]*scaleAry[1];
-					m21 = props[2]*scaleAry[0];
-					m22 = props[3]*scaleAry[1];
-				break;
-				case "translateX":
-					ct = parseInt(transforms[i].replace(/translateX\(|\)/g, "")) || 1;
-					m11 = props[0];
-					m12 = props[1];
-					m21 = props[2];
-					m22 = props[3];
-					tx = toPx(ct);
-					tx && attr(n, "dojo-transform-matrix-tx", tx);
-				break;
-				case "translateY":
-					ct = parseInt(transforms[i].replace(/translateY\(|\)/g, "")) || 1;
-					m11 = props[0];
-					m12 = props[1];
-					m21 = props[2];
-					m22 = props[3];
-					ty = toPx(ct);
-					ty && attr(n, "dojo-transform-matrix-ty", ty);
-				break;
-				case "translate":
-					ct = transforms[i].replace(/translate\(|\)/g, "");
-					m11 = props[0];
-					m12 = props[1];
-					m21 = props[2];
-					m22 = props[3];
-					var translateAry = ct.split(",");
-					translateAry[0] = parseInt(toPx(translateAry[0])) || 0;
-					translateAry[1] = parseInt(toPx(translateAry[1])) || 0;
-					tx = translateAry[0];
-					ty = translateAry[1];
-					tx && attr(n, "dojo-transform-matrix-tx", tx);
-					ty && attr(n, "dojo-transform-matrix-ty", ty);
-				break;
+					dx -= (wMax - w) / 2 - (parentWidth > wMax ? 0 : (wMax - parentWidth) / 2);
+				}
+			}else if(has("ie") == 8){
+				// IE8 bug, a filter is applied to positioned descendants
+				// only if the parent has z-index
+				ds(n, "zIndex") == "auto" && (n.style.zIndex = "0");
 			}
-			props = [m11, m12, m21, m22, tx, ty];
-		}
-		// test
-		var Bx = min(w*m11 + h*m12, min(min(w*m11, h*m12), 0)),
-			By = min(w*m21 + h*m22, min(min(w*m21, h*m22), 0))
-		;
-		dx = -Bx;
-		dy = -By;
-		if(dojo.isIE < 8){
-			// on IE < 8 the node must have hasLayout = true
-			n.style.zoom = "1";
-			if(newPosition != "absolute"){
-				var parentWidth = ds(node.parentNode, "width"),
-					tw = abs(w*m11),
-					th = abs(h*m12),
-					wMax = max(tw + th, max(max(th, tw), 0))
+
+			try{
+				hasMatrix = !!n.filters.item(mstr);
+			}catch(e){
+				hasMatrix = false;
+			}
+			if(hasMatrix){
+				n.filters.item(mstr).M11 = m11;
+				n.filters.item(mstr).M12 = m12;
+				n.filters.item(mstr).M21 = m21;
+				n.filters.item(mstr).M22 = m22;
+				// use 'nearest' for a faster transform
+				n.filters.item(mstr).filterType = 'bilinear';
+				n.filters.item(mstr).Dx = 0;
+				n.filters.item(mstr).Dy = 0;
+				n.filters.item(mstr).sizingMethod = 'auto expand';
+			}else{
+				n.style.filter +=
+					" progid:" + mstr + "(M11=" + m11 +
+					",M12=" + m12 +
+					",M21=" + m21 +
+					",M22=" + m22 +
+					",FilterType='bilinear',Dx=0,Dy=0,sizingMethod='auto expand')"
 				;
-				dx -= (wMax - w) / 2 - (parentWidth > wMax ? 0 : (wMax - parentWidth) / 2);
 			}
-		}else if(dojo.isIE == 8){
-			// IE8 bug, a filter is applied to positioned descendants
-			// only if the parent has z-index
-			ds(n, "zIndex") == "auto" && (n.style.zIndex = "0");
-		}
-
-		try{
-			hasMatrix = !!n.filters.item(mstr);
-		}catch(e){
-			hasMatrix = false;
-		}
-		if(hasMatrix){
-			n.filters.item(mstr).M11 = m11;
-			n.filters.item(mstr).M12 = m12;
-			n.filters.item(mstr).M21 = m21;
-			n.filters.item(mstr).M22 = m22;
-			// use 'nearest' for a faster transform
-			n.filters.item(mstr).filterType = 'bilinear';
-			n.filters.item(mstr).Dx = 0;
-			n.filters.item(mstr).Dy = 0;
-			n.filters.item(mstr).sizingMethod = 'auto expand';
-		}else{
-			n.style.filter +=
-				" progid:" + mstr + "(M11=" + m11 +
-				",M12=" + m12 +
-				",M21=" + m21 +
-				",M22=" + m22 +
-				",FilterType='bilinear',Dx=0,Dy=0,sizingMethod='auto expand')"
-			;
-		}
-		tx = parseInt(attr(n, "dojo-transform-matrix-tx") || "0");
-		ty = parseInt(attr(n, "dojo-transform-matrix-ty") || "0");
+			tx = parseInt(attr(n, "dojo-transform-matrix-tx") || "0");
+			ty = parseInt(attr(n, "dojo-transform-matrix-ty") || "0");
 
-		// transform origin
-		var toAry = attr(n, "dojo-transform-origin").split(" ");
+			// transform origin
+			var toAry = attr(n, "dojo-transform-origin").split(" ");
 
-		for(i = 0; i < 2; i++){
-			toAry[i] = toAry[i] || "50%";
-		}
-		xc = (toAry[0].toString().indexOf("%") != -1) ? w * parseInt(toAry[0]) * .01 : toAry[0];
-		yc = (toAry[1].toString().indexOf("%") != -1) ? h * parseInt(toAry[1]) * .01 : toAry[1];
-		if(hasAttr(n, "dojo-startX")){
-			x0 = parseInt(attr(n, "dojo-startX"));
-		}else{
-			x0 = parseInt(ds(n, "left"));
-			attr(n, "dojo-startX", newPosition == "absolute" ? x0 : "0");
-		}
-		if(hasAttr(n, "dojo-startY")){
-			y0 = parseInt(attr(n, "dojo-startY"));
-		}else{
-			y0 = parseInt(ds(n, "top"));
-			attr(n, "dojo-startY", newPosition == "absolute" ? y0 : "0");
-		}
-		ds(n, {
-			position: newPosition,
-			left: x0 - parseInt(dx) + parseInt(xc) - ((parseInt(xc) - tx)*m11 + (parseInt(yc) - ty)*m12) + "px",
-			top:  y0 - parseInt(dy) + parseInt(yc) - ((parseInt(xc) - tx)*m21 + (parseInt(yc) - ty)*m22) + "px"
-		});
-	},
-	_getTransformFilter: function(/*DomNode*/ node){
-		try{
-			var n = dojo.byId(node),
-				item = n.filters.item(0)
-			;
-			return "matrix(" + item.M11 + ", " + item.M12 + ", " + item.M21 + ", " +
-				item.M22 + ", " + (dojo.attr(node, "dojo-transform-tx") || "0") + ", " + (dojo.attr(node, "dojo-transform-ty") || "0") + ")";
-		}catch(e){
-			return "matrix(1, 0, 0, 1, 0, 0)";
+			for(i = 0; i < 2; i++){
+				toAry[i] = toAry[i] || "50%";
+			}
+			xc = (toAry[0].toString().indexOf("%") != -1) ? w * parseInt(toAry[0]) * .01 : toAry[0];
+			yc = (toAry[1].toString().indexOf("%") != -1) ? h * parseInt(toAry[1]) * .01 : toAry[1];
+			if(hasAttr(n, "dojo-startX")){
+				x0 = parseInt(attr(n, "dojo-startX"));
+			}else{
+				x0 = parseInt(ds(n, "left"));
+				attr(n, "dojo-startX", newPosition == "absolute" ? x0 : "0");
+			}
+			if(hasAttr(n, "dojo-startY")){
+				y0 = parseInt(attr(n, "dojo-startY"));
+			}else{
+				y0 = parseInt(ds(n, "top"));
+				attr(n, "dojo-startY", newPosition == "absolute" ? y0 : "0");
+			}
+			ds(n, {
+				position: newPosition,
+				left: x0 - parseInt(dx) + parseInt(xc) - ((parseInt(xc) - tx)*m11 + (parseInt(yc) - ty)*m12) + "px",
+				top:  y0 - parseInt(dy) + parseInt(yc) - ((parseInt(xc) - tx)*m21 + (parseInt(yc) - ty)*m22) + "px"
+			});
+			return transform;
+		},
+		_getTransformFilter: function(/*DomNode*/ node){
+			try{
+				var n = DOM.byId(node),
+					item = n.filters.item(0)
+				;
+				return "matrix(" + item.M11 + ", " + item.M12 + ", " + item.M21 + ", " +
+					item.M22 + ", " + (Html.attr(node, "dojo-transform-tx") || "0") + ", " + (Html.attr(node, "dojo-transform-ty") || "0") + ")";
+			}catch(e){
+				return "matrix(1, 0, 0, 1, 0, 0)";
+			}
+		},
+		setTransform: function(){
+			this._notSupported();
+		},
+		setTransformOrigin: function(){
+			this._notSupported();
 		}
-	},
-	setTransform: function(){
-		this._notSupported();
-	},
-	setTransformOrigin: function(){
-		this._notSupported();
-	}
-});
+	});
 
-dojox.html["ext-dojo"].style.init();
\ No newline at end of file
+	HtmlX["ext-dojo"].style.init();
+	return Html.style;
+});
diff --git a/dojox/html/format.js b/dojox/html/format.js
index 9146e1c..3855570 100755
--- a/dojox/html/format.js
+++ b/dojox/html/format.js
@@ -1,474 +1,477 @@
-define("dojox/html/format", ["dojo", "dojox", "dojox/html/entities"], function(dojo, dojox) {
-
-dojox.html.format.prettyPrint = function(html/*String*/, indentBy /*Integer?*/, maxLineLength /*Integer?*/, map/*Array?*/, /*boolean*/ xhtml){
-	// summary:
-	//		Function for providing a 'pretty print' version of HTML content from
-	//		the provided string.  It's nor perfect by any means, but it does
-	//		a 'reasonable job'.
-	// html: String
-	//		The string of HTML to try and generate a 'pretty' formatting.
-	// indentBy:  Integer
-	//		Optional input for the number of spaces to use when indenting.
-	//		If not defined, zero, negative, or greater than 10, will just use tab
-	//		as the indent.
-	// maxLineLength: Integer
-	//		Optional input for the number of characters a text line should use in
-	//		the document, including the indent if possible.
-	// map:	Array
-	//		Optional array of entity mapping characters to use when processing the
-	//		HTML Text content.  By default it uses the default set used by the
-	//		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 />
-	var content = [];
-	var indentDepth = 0;
-	var closeTags = [];
-	var iTxt = "\t";
-	var textContent = "";
-	var inlineStyle = [];
-	var i;
-
-	// Compile regexps once for this call.
-	var rgxp_fixIEAttrs = /[=]([^"']+?)(\s|>)/g;
-	var rgxp_styleMatch = /style=("[^"]*"|'[^']*'|\S*)/gi;
-	var rgxp_attrsMatch = /[\w-]+=("[^"]*"|'[^']*'|\S*)/gi;
-
-	// Check to see if we want to use spaces for indent instead
-	// of tab.
-	if(indentBy && indentBy > 0 && indentBy < 10){
-		iTxt = "";
-		for(i = 0; i < indentBy; i++){
-			iTxt += " ";
-		}
-	}
-
-	//Build the content outside of the editor so we can walk
-	//via DOM and build a 'pretty' output.
-	var contentDiv = dojo.doc.createElement("div");
-	contentDiv.innerHTML = html;
-
-	// Use the entity encode/decode functions, they cache on the map,
-	// so it won't multiprocess a map.
-	var encode = dojox.html.entities.encode;
-	var decode = dojox.html.entities.decode;
-
-	/** Define a bunch of formatters to format the output. **/
-	var isInlineFormat = function(tag){
-		// summary:
-		//		Function to determine if the current tag is an inline
-		//		element that does formatting, as we don't want to
-		//		break/indent around it, as it can screw up text.
-		// tag:
-		//		The tag to examine
-		switch(tag){
-			case "a":
-			case "b":
-			case "strong":
-			case "s":
-			case "strike":
-			case "i":
-			case "u":
-			case "em":
-			case "sup":
-			case "sub":
-			case "span":
-			case "font":
-			case "big":
-			case "cite":
-			case "q":
-			case "small":
-				return true;
-			default:
-				return false;
-		}
-	};
-
-	//Create less divs.
-	var div = contentDiv.ownerDocument.createElement("div");
-	var outerHTML =  function(node){
-		// summary:
-		//		Function to return the outer HTML of a node.
-		//		Yes, IE has a function like this, but using cloneNode
-		//		allows avoiding looking at any child nodes, because in this
-		//		case, we don't want them.
-		var clone = node.cloneNode(false);
-		div.appendChild(clone);
-		var html = div.innerHTML;
-		div.innerHTML = "";
-		return html;
-	};
-
-	var sizeIndent = function(){
-		var i, txt = "";
-		for(i = 0; i < indentDepth; i++){
-			txt += iTxt;
-		}
-		return txt.length;
-	}
-
-	var indent = function(){
+define(["dojo/_base/kernel", "./entities", "dojo/_base/array", "dojo/_base/window", "dojo/_base/sniff"], 
+	function(lang, Entities, ArrayUtil, Window, has) {
+	var dhf = lang.getObject("dojox.html.format",true);
+	
+	dhf.prettyPrint = function(html/*String*/, indentBy /*Integer?*/, maxLineLength /*Integer?*/, map/*Array?*/, /*boolean*/ xhtml){
 		// summary:
-		//		Function to handle indent depth.
+		//		Function for providing a 'pretty print' version of HTML content from
+		//		the provided string.  It's nor perfect by any means, but it does
+		//		a 'reasonable job'.
+		// html: String
+		//		The string of HTML to try and generate a 'pretty' formatting.
+		// indentBy:  Integer
+		//		Optional input for the number of spaces to use when indenting.
+		//		If not defined, zero, negative, or greater than 10, will just use tab
+		//		as the indent.
+		// maxLineLength: Integer
+		//		Optional input for the number of characters a text line should use in
+		//		the document, including the indent if possible.
+		// map:	Array
+		//		Optional array of entity mapping characters to use when processing the
+		//		HTML Text content.  By default it uses the default set used by the
+		//		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 />
+		var content = [];
+		var indentDepth = 0;
+		var closeTags = [];
+		var iTxt = "\t";
+		var textContent = "";
+		var inlineStyle = [];
 		var i;
-		for(i = 0; i < indentDepth; i++){
-			content.push(iTxt);
+	
+		// Compile regexps once for this call.
+		var rgxp_fixIEAttrs = /[=]([^"']+?)(\s|>)/g;
+		var rgxp_styleMatch = /style=("[^"]*"|'[^']*'|\S*)/gi;
+		var rgxp_attrsMatch = /[\w-]+=("[^"]*"|'[^']*'|\S*)/gi;
+	
+		// Check to see if we want to use spaces for indent instead
+		// of tab.
+		if(indentBy && indentBy > 0 && indentBy < 10){
+			iTxt = "";
+			for(i = 0; i < indentBy; i++){
+				iTxt += " ";
+			}
 		}
-	};
-	var newline = function(){
-		// summary:
-		//		Function to handle newlining.
-		content.push("\n");
-	};
-
-	var processTextNode = function(n){
-		// summary:
-		//		Function to process the text content for doc
-		//		insertion
-		// n:
-		//		The text node to process.
-		textContent += encode(n.nodeValue, map);
-	};
-
-	var formatText = function(txt){
-		// summary:
-		//		Function for processing the text content encountered up to a
-		//		point and inserting it into the formatted document output.
-		// txt:
-		//		The text to format.
-		var i;
-		var _iTxt;
-
-		// Clean up any indention organization since we're going to rework it
-		// anyway.
-		var _lines = txt.split("\n");
-		for(i = 0; i < _lines.length; i++){
-			_lines[i] = dojo.trim(_lines[i]);
+	
+		//Build the content outside of the editor so we can walk
+		//via DOM and build a 'pretty' output.
+		var contentDiv = Window.doc.createElement("div");
+		contentDiv.innerHTML = html;
+	
+		// Use the entity encode/decode functions, they cache on the map,
+		// so it won't multiprocess a map.
+		var encode = Entities.encode;
+		var decode = Entities.decode;
+	
+		/** Define a bunch of formatters to format the output. **/
+		var isInlineFormat = function(tag){
+			// summary:
+			//		Function to determine if the current tag is an inline
+			//		element that does formatting, as we don't want to
+			//		break/indent around it, as it can screw up text.
+			// tag:
+			//		The tag to examine
+			switch(tag){
+				case "a":
+				case "b":
+				case "strong":
+				case "s":
+				case "strike":
+				case "i":
+				case "u":
+				case "em":
+				case "sup":
+				case "sub":
+				case "span":
+				case "font":
+				case "big":
+				case "cite":
+				case "q":
+				case "small":
+					return true;
+				default:
+					return false;
+			}
+		};
+	
+		//Create less divs.
+		var div = contentDiv.ownerDocument.createElement("div");
+		var outerHTML =  function(node){
+			// summary:
+			//		Function to return the outer HTML of a node.
+			//		Yes, IE has a function like this, but using cloneNode
+			//		allows avoiding looking at any child nodes, because in this
+			//		case, we don't want them.
+			var clone = node.cloneNode(false);
+			div.appendChild(clone);
+			var html = div.innerHTML;
+			div.innerHTML = "";
+			return html;
+		};
+	
+		var sizeIndent = function(){
+			var i, txt = "";
+			for(i = 0; i < indentDepth; i++){
+				txt += iTxt;
+			}
+			return txt.length;
 		}
-		txt = _lines.join(" ");
-		txt = dojo.trim(txt);
-		if(txt !== ""){
-			var lines = [];
-			if(maxLineLength && maxLineLength > 0){
-				var indentSize = sizeIndent();
-				var maxLine = maxLineLength;
-				if(maxLineLength > indentSize){
-					maxLine -= indentSize;
-				}
-				while(txt){
-					if(txt.length > maxLineLength){
-						for(i = maxLine; (i > 0 && txt.charAt(i) !== " "); i--){
-							// Do nothing, we're just looking for a space to split at.
-						}
-						if(!i){
-							// Couldn't find a split going back, so go forward.
-							for(i = maxLine; (i < txt.length && txt.charAt(i) !== " "); i++){
+	
+		var indent = function(){
+			// summary:
+			//		Function to handle indent depth.
+			var i;
+			for(i = 0; i < indentDepth; i++){
+				content.push(iTxt);
+			}
+		};
+		var newline = function(){
+			// summary:
+			//		Function to handle newlining.
+			content.push("\n");
+		};
+	
+		var processTextNode = function(n){
+			// summary:
+			//		Function to process the text content for doc
+			//		insertion
+			// n:
+			//		The text node to process.
+			textContent += encode(n.nodeValue, map);
+		};
+	
+		var formatText = function(txt){
+			// summary:
+			//		Function for processing the text content encountered up to a
+			//		point and inserting it into the formatted document output.
+			// txt:
+			//		The text to format.
+			var i;
+			var _iTxt;
+	
+			// Clean up any indention organization since we're going to rework it
+			// anyway.
+			var _lines = txt.split("\n");
+			for(i = 0; i < _lines.length; i++){
+				_lines[i] = lang.trim(_lines[i]);
+			}
+			txt = _lines.join(" ");
+			txt = lang.trim(txt);
+			if(txt !== ""){
+				var lines = [];
+				if(maxLineLength && maxLineLength > 0){
+					var indentSize = sizeIndent();
+					var maxLine = maxLineLength;
+					if(maxLineLength > indentSize){
+						maxLine -= indentSize;
+					}
+					while(txt){
+						if(txt.length > maxLineLength){
+							for(i = maxLine; (i > 0 && txt.charAt(i) !== " "); i--){
 								// Do nothing, we're just looking for a space to split at.
 							}
-						}
-						var line = txt.substring(0, i);
-						line = dojo.trim(line);
-						// Shift up the text string to the next chunk.
-						txt = dojo.trim(txt.substring((i == txt.length)?txt.length:i + 1, txt.length));
-						if(line){
+							if(!i){
+								// Couldn't find a split going back, so go forward.
+								for(i = maxLine; (i < txt.length && txt.charAt(i) !== " "); i++){
+									// Do nothing, we're just looking for a space to split at.
+								}
+							}
+							var line = txt.substring(0, i);
+							line = lang.trim(line);
+							// Shift up the text string to the next chunk.
+							txt = lang.trim(txt.substring((i == txt.length)?txt.length:i + 1, txt.length));
+							if(line){
+								_iTxt = "";
+								for(i = 0; i < indentDepth; i++){
+									_iTxt += iTxt;
+								}
+								line = _iTxt + line + "\n";
+							}
+							lines.push(line);
+						}else{
+							// Line is shorter than out desired length, so use it.
+							// as/is
 							_iTxt = "";
 							for(i = 0; i < indentDepth; i++){
 								_iTxt += iTxt;
 							}
-							line = _iTxt + line + "\n";
-						}
-						lines.push(line);
-					}else{
-						// Line is shorter than out desired length, so use it.
-						// as/is
-						_iTxt = "";
-						for(i = 0; i < indentDepth; i++){
-							_iTxt += iTxt;
+							txt = _iTxt + txt + "\n";
+							lines.push(txt);
+							txt = null;
 						}
-						txt = _iTxt + txt + "\n";
-						lines.push(txt);
-						txt = null;
 					}
+					return lines.join("");
+				}else{
+					_iTxt = "";
+					for(i = 0; i < indentDepth; i++){
+						_iTxt += iTxt;
+					}
+					txt = _iTxt + txt + "\n";
+					return txt;
 				}
-				return lines.join("");
 			}else{
-				_iTxt = "";
-				for(i = 0; i < indentDepth; i++){
-					_iTxt += iTxt;
-				}
-				txt = _iTxt + txt + "\n";
-				return txt;
+				return "";
 			}
-		}else{
-			return "";
-		}
-	};
-
-	var processScriptText = function(txt){
-		// summary:
-		//		Function to clean up potential escapes in the script code.
-		if(txt){
-			txt = txt.replace(/"/gi, "\"");
-			txt = txt.replace(/>/gi, ">");
-			txt = txt.replace(/</gi, "<");
-			txt = txt.replace(/&/gi, "&");
-		}
-		return txt;
-	};
-
-	var formatScript = function(txt){
-		// summary:
-		//		Function to rudimentary formatting of script text.
-		//		Not perfect, but it helps get some level of organization
-		//		in there.
-		// txt:
-		//		The script text to try to format a bit.
-		if(txt){
-			txt = processScriptText(txt);
-			var i, t, c, _iTxt;
-			var indent = 0;
-			var scriptLines = txt.split("\n");
-			var newLines = [];
-			for (i = 0; i < scriptLines.length; i++){
-				var line = scriptLines[i];
-				var hasNewlines = (line.indexOf("\n") > -1);
-				line = dojo.trim(line);
-				if(line){
-					var iLevel = indent;
-					// Not all blank, so we need to process.
-					for(c = 0; c < line.length; c++){
-						var ch = line.charAt(c);
-						if(ch === "{"){
-							indent++;
-						}else if(ch === "}"){
-							indent--;
-							// We want to back up a bit before the
-							// line is written.
-							iLevel = indent;
+		};
+	
+		var processScriptText = function(txt){
+			// summary:
+			//		Function to clean up potential escapes in the script code.
+			if(txt){
+				txt = txt.replace(/"/gi, "\"");
+				txt = txt.replace(/>/gi, ">");
+				txt = txt.replace(/</gi, "<");
+				txt = txt.replace(/&/gi, "&");
+			}
+			return txt;
+		};
+	
+		var formatScript = function(txt){
+			// summary:
+			//		Function to rudimentary formatting of script text.
+			//		Not perfect, but it helps get some level of organization
+			//		in there.
+			// txt:
+			//		The script text to try to format a bit.
+			if(txt){
+				txt = processScriptText(txt);
+				var i, t, c, _iTxt;
+				var indent = 0;
+				var scriptLines = txt.split("\n");
+				var newLines = [];
+				for (i = 0; i < scriptLines.length; i++){
+					var line = scriptLines[i];
+					var hasNewlines = (line.indexOf("\n") > -1);
+					line = lang.trim(line);
+					if(line){
+						var iLevel = indent;
+						// Not all blank, so we need to process.
+						for(c = 0; c < line.length; c++){
+							var ch = line.charAt(c);
+							if(ch === "{"){
+								indent++;
+							}else if(ch === "}"){
+								indent--;
+								// We want to back up a bit before the
+								// line is written.
+								iLevel = indent;
+							}
 						}
+						_iTxt = "";
+						for(t = 0; t < indentDepth + iLevel; t++){
+							_iTxt += iTxt;
+						}
+						newLines.push(_iTxt + line + "\n");
+					}else if(hasNewlines && i === 0){
+						// Just insert a newline for blank lines as
+						// long as it's not the first newline (we
+						// already inserted that in the openTag handler)
+						newLines.push("\n");
 					}
-					_iTxt = "";
-					for(t = 0; t < indentDepth + iLevel; t++){
-						_iTxt += iTxt;
-					}
-					newLines.push(_iTxt + line + "\n");
-				}else if(hasNewlines && i === 0){
-					// Just insert a newline for blank lines as
-					// long as it's not the first newline (we
-					// already inserted that in the openTag handler)
-					newLines.push("\n");
+	
 				}
-
+				// Okay, create the script text, hopefully reasonably
+				// formatted.
+				txt = newLines.join("");
 			}
-			// Okay, create the script text, hopefully reasonably
-			// formatted.
-			txt = newLines.join("");
-		}
-		return txt;
-	};
-
-	var openTag = function(node){
-		// summary:
-		//		Function to open a new tag for writing content.
-		var name = node.nodeName.toLowerCase();
-		// Generate the outer node content (tag with attrs)
-		var nText = dojo.trim(outerHTML(node));
-		var tag = nText.substring(0, nText.indexOf(">") + 1);
-
-		// Also thanks to IE, we need to check for quotes around
-		// attributes and insert if missing.
-		tag = tag.replace(rgxp_fixIEAttrs,'="$1"$2');
-
-		// And lastly, thanks IE for changing style casing and end
-		// semi-colon and webkit adds spaces, so lets clean it up by
-		// sorting, etc, while we're at it.
-		tag = tag.replace(rgxp_styleMatch, function(match){
-			var sL = match.substring(0,6);
-			var style = match.substring(6, match.length);
-			var closure = style.charAt(0);
-			style = dojo.trim(style.substring(1,style.length -1));
-			style = style.split(";");
-			var trimmedStyles = [];
-			dojo.forEach(style, function(s){
-				s = dojo.trim(s);
-				if(s){
-					// Lower case the style name, leave the value alone.  Mainly a fixup for IE.
-					s = s.substring(0, s.indexOf(":")).toLowerCase() + s.substring(s.indexOf(":"), s.length);
-					trimmedStyles.push(s);
+			return txt;
+		};
+	
+		var openTag = function(node){
+			// summary:
+			//		Function to open a new tag for writing content.
+			var name = node.nodeName.toLowerCase();
+			// Generate the outer node content (tag with attrs)
+			var nText = lang.trim(outerHTML(node));
+			var tag = nText.substring(0, nText.indexOf(">") + 1);
+	
+			// Also thanks to IE, we need to check for quotes around
+			// attributes and insert if missing.
+			tag = tag.replace(rgxp_fixIEAttrs,'="$1"$2');
+	
+			// And lastly, thanks IE for changing style casing and end
+			// semi-colon and webkit adds spaces, so lets clean it up by
+			// sorting, etc, while we're at it.
+			tag = tag.replace(rgxp_styleMatch, function(match){
+				var sL = match.substring(0,6);
+				var style = match.substring(6, match.length);
+				var closure = style.charAt(0);
+				style = lang.trim(style.substring(1,style.length -1));
+				style = style.split(";");
+				var trimmedStyles = [];
+				ArrayUtil.forEach(style, function(s){
+					s = lang.trim(s);
+					if(s){
+						// Lower case the style name, leave the value alone.  Mainly a fixup for IE.
+						s = s.substring(0, s.indexOf(":")).toLowerCase() + s.substring(s.indexOf(":"), s.length);
+						trimmedStyles.push(s);
+					}
+				});
+				trimmedStyles = trimmedStyles.sort();
+				
+				// Reassemble and return the styles in sorted order.
+				style = trimmedStyles.join("; ");
+				var ts = lang.trim(style);
+				if(!ts || ts === ";"){
+					// Just remove any style attrs that are empty.
+					return "";
+				}else{
+					style += ";";
+					return sL + closure + style + closure;
 				}
 			});
-			trimmedStyles = trimmedStyles.sort();
-			
-			// Reassemble and return the styles in sorted order.
-			style = trimmedStyles.join("; ");
-			var ts = dojo.trim(style);
-			if(!ts || ts === ";"){
-				// Just remove any style attrs that are empty.
+	
+			// Try and sort the attributes while we're at it.
+			var attrs = [];
+			tag = tag.replace(rgxp_attrsMatch, function(attr){
+				attrs.push(lang.trim(attr));
 				return "";
-			}else{
-				style += ";";
-				return sL + closure + style + closure;
+			});
+			attrs = attrs.sort();
+	
+			// Reassemble the tag with sorted attributes!
+			tag = "<" + name;
+			if(attrs.length){
+				 tag += " " + attrs.join(" ");
 			}
-		});
-
-		// Try and sort the attributes while we're at it.
-		var attrs = [];
-		tag = tag.replace(rgxp_attrsMatch, function(attr){
-			attrs.push(dojo.trim(attr));
-			return "";
-		});
-		attrs = attrs.sort();
-
-		// Reassemble the tag with sorted attributes!
-		tag = "<" + name;
-		if(attrs.length){
-			 tag += " " + attrs.join(" ");
-		}
-
-		// Determine closure status.  If xhtml,
-		// then close the tag properly as needed.
-		if(nText.indexOf("</") != -1){
-			closeTags.push(name);
-			tag += ">";
-		}else{
-			if(xhtml){
-				tag += " />";
-			}else{
+	
+			// Determine closure status.  If xhtml,
+			// then close the tag properly as needed.
+			if(nText.indexOf("</") != -1){
+				closeTags.push(name);
 				tag += ">";
+			}else{
+				if(xhtml){
+					tag += " />";
+				}else{
+					tag += ">";
+				}
+				closeTags.push(false);
 			}
-			closeTags.push(false);
-		}
-
-		var inline = isInlineFormat(name);
-		inlineStyle.push(inline);
-		if(textContent && !inline){
-			// Process any text content we have that occurred
-			// before the open tag of a non-inline.
-			content.push(formatText(textContent));
-			textContent = "";
-		}
-
-		// Determine if this has a closing tag or not!
-		if(!inline){
-			indent();
-			content.push(tag);
-			newline();
-			indentDepth++;
-		}else{
-			textContent += tag;
-		}
-		
-	};
 	
-	var closeTag = function(){
-		// summary:
-		//		Function to close out a tag if necessary.
-		var inline = inlineStyle.pop();
-		if(textContent && !inline){
-			// Process any text content we have that occurred
-			// before the close tag.
-			content.push(formatText(textContent));
-			textContent = "";
-		}
-		var ct = closeTags.pop();
-		if(ct){
-			ct = "</" + ct + ">";
+			var inline = isInlineFormat(name);
+			inlineStyle.push(inline);
+			if(textContent && !inline){
+				// Process any text content we have that occurred
+				// before the open tag of a non-inline.
+				content.push(formatText(textContent));
+				textContent = "";
+			}
+	
+			// Determine if this has a closing tag or not!
 			if(!inline){
-				indentDepth--;
 				indent();
-				content.push(ct);
+				content.push(tag);
 				newline();
+				indentDepth++;
 			}else{
-				textContent += ct;
+				textContent += tag;
 			}
-		}else{
+			
+		};
+		
+		var closeTag = function(){
+			// summary:
+			//		Function to close out a tag if necessary.
+			var inline = inlineStyle.pop();
+			if(textContent && !inline){
+				// Process any text content we have that occurred
+				// before the close tag.
+				content.push(formatText(textContent));
+				textContent = "";
+			}
+			var ct = closeTags.pop();
+			if(ct){
+				ct = "</" + ct + ">";
+				if(!inline){
+					indentDepth--;
+					indent();
+					content.push(ct);
+					newline();
+				}else{
+					textContent += ct;
+				}
+			}else{
+				indentDepth--;
+			}
+		};
+	
+		var processCommentNode = function(n){
+			// summary:
+			//		Function to handle processing a comment node.
+			// n:
+			//		The comment node to process.
+	
+			//Make sure contents aren't double-encoded.
+			var commentText = decode(n.nodeValue, map);
+			indent();
+			content.push("<!--");
+			newline();
+			indentDepth++;
+			content.push(formatText(commentText));
 			indentDepth--;
-		}
-	};
-
-	var processCommentNode = function(n){
-		// summary:
-		//		Function to handle processing a comment node.
-		// n:
-		//		The comment node to process.
-
-		//Make sure contents aren't double-encoded.
-		var commentText = decode(n.nodeValue, map);
-		indent();
-		content.push("<!--");
-		newline();
-		indentDepth++;
-		content.push(formatText(commentText));
-		indentDepth--;
-		indent();
-		content.push("-->");
-		newline();
-	};
-
-	var processNode = function(node) {
-		// summary:
-		//		Entrypoint for processing all the text!
-		var children = node.childNodes;
-		if(children){
-			var i;
-			for(i = 0; i < children.length; i++){
-				var n = children[i];
-				if(n.nodeType === 1){
-					var tg = dojo.trim(n.tagName.toLowerCase());
-					if(dojo.isIE && n.parentNode != node){
-						// 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.
-						continue;
-					}
-					if(tg && tg.charAt(0) === "/"){
-						// IE oddity.  Malformed HTML can put in odd tags like:
-						// </ >, </span>.  It treats a mismatched closure as a new
-						// start tag.  So, remove them.
-						continue;
-					}else{
-						//Process non-dup, seemingly wellformed elements!
-						openTag(n);
-						if(tg === "script"){
-							content.push(formatScript(n.innerHTML));
-						}else if(tg === "pre"){
-							var preTxt = n.innerHTML;
-							if(dojo.isMoz){
-								//Mozilla screws this up, so fix it up.
-								preTxt = preTxt.replace("<br>", "\n");
-								preTxt = preTxt.replace("<pre>", "");
-								preTxt = preTxt.replace("</pre>", "");
-							}
-							// Add ending newline, if needed.
-							if(preTxt.charAt(preTxt.length - 1) !== "\n"){
-								preTxt += "\n";
-							}
-							content.push(preTxt);
+			indent();
+			content.push("-->");
+			newline();
+		};
+	
+		var processNode = function(node) {
+			// summary:
+			//		Entrypoint for processing all the text!
+			var children = node.childNodes;
+			if(children){
+				var i;
+				for(i = 0; i < children.length; i++){
+					var n = children[i];
+					if(n.nodeType === 1){
+						var tg = lang.trim(n.tagName.toLowerCase());
+						if(has("ie") && n.parentNode != node){
+							// 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.
+							continue;
+						}
+						if(tg && tg.charAt(0) === "/"){
+							// IE oddity.  Malformed HTML can put in odd tags like:
+							// </ >, </span>.  It treats a mismatched closure as a new
+							// start tag.  So, remove them.
+							continue;
 						}else{
-							processNode(n);
+							//Process non-dup, seemingly wellformed elements!
+							openTag(n);
+							if(tg === "script"){
+								content.push(formatScript(n.innerHTML));
+							}else if(tg === "pre"){
+								var preTxt = n.innerHTML;
+								if(has("mozilla")){
+									//Mozilla screws this up, so fix it up.
+									preTxt = preTxt.replace("<br>", "\n");
+									preTxt = preTxt.replace("<pre>", "");
+									preTxt = preTxt.replace("</pre>", "");
+								}
+								// Add ending newline, if needed.
+								if(preTxt.charAt(preTxt.length - 1) !== "\n"){
+									preTxt += "\n";
+								}
+								content.push(preTxt);
+							}else{
+								processNode(n);
+							}
+							closeTag();
 						}
-						closeTag();
+					}else if(n.nodeType === 3 || n.nodeType === 4){
+						processTextNode(n);
+					}else if(n.nodeType === 8){
+						processCommentNode(n);
 					}
-				}else if(n.nodeType === 3 || n.nodeType === 4){
-					processTextNode(n);
-				}else if(n.nodeType === 8){
-					processCommentNode(n);
 				}
 			}
+		};
+	
+		//Okay, finally process the input string.
+		processNode(contentDiv);
+		if(textContent){
+			// Insert any trailing text.  See: #10854
+			content.push(formatText(textContent));
+			textContent = "";
 		}
+		return content.join(""); //String
 	};
-
-	//Okay, finally process the input string.
-	processNode(contentDiv);
-	if(textContent){
-		// Insert any trailing text.  See: #10854
-		content.push(formatText(textContent));
-		textContent = "";
-	}
-	return content.join(""); //String
-};
+	return dhf;
 });
 
diff --git a/dojox/html/metrics.js b/dojox/html/metrics.js
index 2c84199..e22b580 100644
--- a/dojox/html/metrics.js
+++ b/dojox/html/metrics.js
@@ -1,7 +1,8 @@
-dojo.provide("dojox.html.metrics");
-
-(function(){
-	var dhm = dojox.html.metrics;
+define(["dojo/_base/kernel","dojo/_base/lang", "dojo/_base/sniff", "dojo/ready", "dojo/_base/unload",
+		"dojo/_base/window", "dojo/dom-geometry"],
+  function(kernel,lang,has,ready,UnloadUtil,Window,DOMGeom){
+	var dhm = lang.getObject("dojox.html.metrics",true);
+	var dojox = lang.getObject("dojox");
 
 	//	derived from Morris John's emResized measurer
 	dhm.getFontMeasurements = function(){
@@ -12,14 +13,14 @@ dojo.provide("dojox.html.metrics");
 			'small':0, 'medium':0, 'large':0, 'x-large':0, 'xx-large':0
 		};
 	
-		if(dojo.isIE){
+		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.
-			dojo.doc.documentElement.style.fontSize="100%";
+			Window.doc.documentElement.style.fontSize="100%";
 		}
 	
 		//	set up the measuring node.
-		var div=dojo.doc.createElement("div");
+		var div=Window.doc.createElement("div");
 		var ds = div.style;
 		ds.position="absolute";
 		ds.left="-100px";
@@ -32,7 +33,7 @@ dojo.provide("dojox.html.metrics");
 		ds.outline="0";
 		ds.lineHeight="1";
 		ds.overflow="hidden";
-		dojo.body().appendChild(div);
+		Window.body().appendChild(div);
 	
 		//	do the measurements.
 		for(var p in heights){
@@ -40,7 +41,7 @@ dojo.provide("dojox.html.metrics");
 			heights[p] = Math.round(div.offsetHeight * 12/16) * 16/12 / 1000;
 		}
 		
-		dojo.body().removeChild(div);
+		Window.body().removeChild(div);
 		div = null;
 		return heights; 	//	object
 	};
@@ -58,10 +59,10 @@ dojo.provide("dojox.html.metrics");
 	dhm.getTextBox = function(/* String */ text, /* Object */ style, /* String? */ className){
 		var m, s;
 		if(!measuringNode){
-			m = measuringNode = dojo.doc.createElement("div");
+			m = measuringNode = Window.doc.createElement("div");
 			// Container that we can set contraints on so that it doesn't
 			// trigger a scrollbar.
-			var c = dojo.doc.createElement("div");
+			var c = Window.doc.createElement("div");
 			c.appendChild(m);
 			s = c.style;
 			s.overflow='scroll';
@@ -75,7 +76,7 @@ dojo.provide("dojox.html.metrics");
 			s.margin = "0";
 			s.padding = "0";
 			s.outline = "0";
-			dojo.body().appendChild(c);
+			Window.body().appendChild(c);
 		}else{
 			m = measuringNode;
 		}
@@ -99,7 +100,7 @@ dojo.provide("dojox.html.metrics");
 		}
 		// take a measure
 		m.innerHTML = text;
-		var box = dojo.position(m);
+		var box = DOMGeom.position(m);
 		// position doesn't report right (reports 1, since parent is 1)
 		// So we have to look at the scrollWidth to get the real width
 		// Height is right.
@@ -114,13 +115,13 @@ dojo.provide("dojox.html.metrics");
 	dhm._fontResizeNode = null;
 
 	dhm.initOnFontResize = function(interval){
-		var f = dhm._fontResizeNode = dojo.doc.createElement("iframe");
+		var f = dhm._fontResizeNode = Window.doc.createElement("iframe");
 		var fs = f.style;
 		fs.position = "absolute";
 		fs.width = "5em";
 		fs.height = "10em";
 		fs.top = "-10000px";
-		if(dojo.isIE){
+		if(has("ie")){
 			f.onreadystatechange = function(){
 				if(f.contentWindow.document.readyState == "complete"){
 					f.onresize = f.contentWindow.parent[dojox._scopeName].html.metrics._fontresize;
@@ -133,7 +134,7 @@ dojo.provide("dojox.html.metrics");
 		}
 		//The script tag is to work around a known firebug race condition.  See comments in bug #9046
 		f.setAttribute("src", "javascript:'<html><head><script>if(\"loadFirebugConsole\" in window){window.loadFirebugConsole();}</script></head><body></body></html>'");
-		dojo.body().appendChild(f);
+		Window.body().appendChild(f);
 		dhm.initOnFontResize = function(){};
 	};
 
@@ -142,11 +143,11 @@ dojo.provide("dojox.html.metrics");
 		dhm.onFontResize();
 	}
 
-	dojo.addOnUnload(function(){
+	UnloadUtil.addOnUnload(function(){
 		// destroy our font resize iframe if we have one
 		var f = dhm._fontResizeNode;
 		if(f){
-			if(dojo.isIE && f.onresize){
+			if(has("ie") && f.onresize){
 				f.onresize = null;
 			}else if(f.contentWindow && f.contentWindow.onresize){
 				f.contentWindow.onresize = null;
@@ -155,22 +156,23 @@ dojo.provide("dojox.html.metrics");
 		}
 	});
 
-	dojo.addOnLoad(function(){
+	ready(function(){
 		// getScrollbar metrics node
 		try{
-			var n=dojo.doc.createElement("div");
+			var n=Window.doc.createElement("div");
 			n.style.cssText = "top:0;left:0;width:100px;height:100px;overflow:scroll;position:absolute;visibility:hidden;";
-			dojo.body().appendChild(n);
+			Window.body().appendChild(n);
 			scroll.w = n.offsetWidth - n.clientWidth;
 			scroll.h = n.offsetHeight - n.clientHeight;
-			dojo.body().removeChild(n);
+			Window.body().removeChild(n);
 			//console.log("Scroll bar dimensions: ", scroll);
 			delete n;
 		}catch(e){}
 
 		// text size poll setup
-		if("fontSizeWatch" in dojo.config && !!dojo.config.fontSizeWatch){
+		if("fontSizeWatch" in kernel.config && !!kernel.config.fontSizeWatch){
 			dhm.initOnFontResize();
 		}
 	});
-})();
+	return dhm;
+});
\ No newline at end of file
diff --git a/dojox/html/styles.js b/dojox/html/styles.js
index 90c8a47..791f3a2 100755
--- a/dojox/html/styles.js
+++ b/dojox/html/styles.js
@@ -1,7 +1,7 @@
-dojo.provide("dojox.html.styles");
-
+define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "dojo/_base/sniff"], 
+	function(lang, ArrayUtil, Window, has) {
 	// summary:
-	//		Methods for creating and minipulating dynamic CSS Styles and Style Sheets
+	//		Methods for creating and manipulating dynamic CSS Styles and Style Sheets
 	//
 	// example:
 	//		| dojox.html.createStyle("#myDiv input", "font-size:24px");
@@ -9,15 +9,12 @@ dojo.provide("dojox.html.styles");
 	//			the inner input will be targeted
 	//		| dojox.html.createStyle(".myStyle", "color:#FF0000");
 	//			Now the class myStyle can be assigned to a node's className
-
-(function(){
-
+	var dh = lang.getObject("dojox.html",true);
 	var dynamicStyleMap = {};
 	var pageStyleSheets = {};
 	var titledSheets = [];
-	var styleIndicies = [];
 
-	dojox.html.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:
@@ -39,37 +36,38 @@ dojo.provide("dojox.html.styles");
 		//					created. If no name is passed, the name "default" is
 		//					used.
 		//
-		var ss = dojox.html.getDynamicStyleSheet(styleSheetName);
+		var ss = dh.getDynamicStyleSheet(styleSheetName);
 		var styleText = selector + " {" + declaration + "}";
-		console.log("insertRule:", styleText)
-		if(dojo.isIE){
+		console.log("insertRule:", styleText);
+		if(has("ie")){
 			// Note: check for if(ss.cssText) does not work
 			ss.cssText+=styleText;
-			console.log("ss.cssText:", ss.cssText)
+			console.log("ss.cssText:", ss.cssText);
 		}else if(ss.sheet){
 			ss.sheet.insertRule(styleText, ss._indicies.length);
 		}else{
-			ss.appendChild(dojo.doc.createTextNode(styleText));
+			ss.appendChild(Window.doc.createTextNode(styleText));
 		}
 		ss._indicies.push(selector+" "+declaration);
 		return selector; // String
+	};
 
-	}
-
-	dojox.html.removeCssRule = function(/*String*/selector, /*String*/declaration, /*String*/styleSheetName){
+	dh.removeCssRule = function(/*String*/selector, /*String*/declaration, /*String*/styleSheetName){
 		// summary:
 		//		Removes a cssRule base on the selector and declaration passed
 		//		The declaration is needed for cases of dupe selectors
 		// description: Only removes DYNAMICALLY created cssRules. If you
-		//		created it with dojox.html.insertCssRule, it can be removed.
+		//		created it with dh.insertCssRule, it can be removed.
 		//
 		var ss;
 		var index=-1;
-		for(var nm in dynamicStyleMap){
-			if(styleSheetName && styleSheetName!=nm) {continue;}
+		var nm;
+		var i;
+		for(nm in dynamicStyleMap){
+			if(styleSheetName && styleSheetName !== nm) {continue;}
 			ss = dynamicStyleMap[nm];
-			for(var i=0;i<ss._indicies.length;i++){
-				if(selector+" "+declaration == ss._indicies[i]){
+			for(i=0;i<ss._indicies.length;i++){
+				if(selector+" "+declaration === ss._indicies[i]){
 					index = i;
 					break;
 				}
@@ -77,42 +75,32 @@ dojo.provide("dojox.html.styles");
 			if(index>-1) { break; }
 		}
 		if(!ss){
-			console.log("No dynamic style sheet has been created from which to remove a rule.");
+			console.warn("No dynamic style sheet has been created from which to remove a rule.");
 			return false;
 		}
-		if(index==-1){
-			console.log("The css rule was not found and could not be removed.");
+		if(index===-1){
+			console.warn("The css rule was not found and could not be removed.");
 			return false;
 		}
-
 		ss._indicies.splice(index, 1);
-
-
-
-		if(dojo.isIE){
+		if(has("ie")){
 			// Note: check for if(ss.removeRule) does not work
 			ss.removeRule(index);
 		}else if(ss.sheet){
 			ss.sheet.deleteRule(index);
-		}else if(document.styleSheets[0]){
-			console.log("what browser hath useth thith?")
-			//
 		}
 		return true; //Boolean
+	};
 
-	}
-
-	/* TODO
-	dojox.html.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.
+	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
-	}
-	*/
+	};
 
-	dojox.html.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,
@@ -124,7 +112,6 @@ dojo.provide("dojox.html.styles");
 		//		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"];
@@ -134,28 +121,26 @@ dojo.provide("dojox.html.styles");
 			// and it has not been created yet.
 			return false;
 		}
-
-		var allSheets = dojox.html.getStyleSheets();
-
+		var allSheets = dh.getStyleSheets();
 		// now try document style sheets by name
 		if(allSheets[styleSheetName]){
-			return dojox.html.getStyleSheets()[styleSheetName];
+			return dh.getStyleSheets()[styleSheetName];
 		}
-
 		// check for partial matches in hrefs (so that a fully
 		//qualified name does not have to be passed)
-		for ( var nm in allSheets){
+		var nm;
+		for ( nm in allSheets){
 			if(	allSheets[nm].href && allSheets[nm].href.indexOf(styleSheetName)>-1){
 				return allSheets[nm];
 			}
 		}
 		return false; //StyleSheet or false
-	}
+	};
 
-	dojox.html.getDynamicStyleSheet = function(/*String*/styleSheetName){
+	dh.getDynamicStyleSheet = function(/*String*/styleSheetName){
 		// summary:
 		//		Creates and returns a dynamically created style sheet
-		// 		used for dynamic styles
+		//		used for dynamic styles
 		//
 		//	argument:
 		//			styleSheetName /* optional String */
@@ -164,34 +149,30 @@ dojo.provide("dojox.html.styles");
 		//			no argument is given, the name "default" is used.
 		//
 		if(!styleSheetName){ styleSheetName="default"; }
-
 		if(!dynamicStyleMap[styleSheetName]){
-			if(dojo.doc.createStyleSheet){ //IE
-
-				dynamicStyleMap[styleSheetName] = dojo.doc.createStyleSheet();
-				if(dojo.isIE < 9) {
+			if(Window.doc.createStyleSheet){ //IE
+				dynamicStyleMap[styleSheetName] = Window.doc.createStyleSheet();
+				if(has("ie") < 9) {
 					// IE9 calls this read-only. Loving the new browser so far.
 					dynamicStyleMap[styleSheetName].title = styleSheetName;
 				}
 			}else{
-				dynamicStyleMap[styleSheetName] = dojo.doc.createElement("style");
+				dynamicStyleMap[styleSheetName] = Window.doc.createElement("style");
 				dynamicStyleMap[styleSheetName].setAttribute("type", "text/css");
-				dojo.doc.getElementsByTagName("head")[0].appendChild(dynamicStyleMap[styleSheetName]);
+				Window.doc.getElementsByTagName("head")[0].appendChild(dynamicStyleMap[styleSheetName]);
 				console.log(styleSheetName, " ss created: ", dynamicStyleMap[styleSheetName].sheet);
 			}
 			dynamicStyleMap[styleSheetName]._indicies = [];
 		}
-
-
 		return dynamicStyleMap[styleSheetName]; //StyleSheet
-	}
+	};
 
-	dojox.html.enableStyleSheet = function(/*String*/styleSheetName){
+	dh.enableStyleSheet = function(/*String*/styleSheetName){
 		// summary:
 		//		Enables the style sheet with the name passed in the
 		//		argument. Deafults to the default style sheet.
 		//
-		var ss = dojox.html.getStyleSheet(styleSheetName);
+		var ss = dh.getStyleSheet(styleSheetName);
 		if(ss){
 			if(ss.sheet){
 				ss.sheet.disabled = false;
@@ -199,14 +180,14 @@ dojo.provide("dojox.html.styles");
 				ss.disabled = false;
 			}
 		}
-	}
+	};
 
-	dojox.html.disableStyleSheet = function(styleSheetName){
+	dh.disableStyleSheet = function(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 = dojox.html.getStyleSheet(styleSheetName);
+		var ss = dh.getStyleSheet(styleSheetName);
 		if(ss){
 			if(ss.sheet){
 				ss.sheet.disabled = true;
@@ -214,9 +195,9 @@ dojo.provide("dojox.html.styles");
 				ss.disabled = true;
 			}
 		}
-	}
+	};
 
-	dojox.html.activeStyleSheet = function(/*?String*/title){
+	dh.activeStyleSheet = function(/*?String*/title){
 		// summary:
 		//		Getter/Setter
 		// description:
@@ -225,61 +206,55 @@ dojo.provide("dojox.html.styles");
 		//		If no argument is passed, returns currently enabled
 		//		style sheet.
 		//
-		var sheets = dojox.html.getToggledStyleSheets();
-		if(arguments.length == 1){
+		var sheets = dh.getToggledStyleSheets();
+		var i;
+		if(arguments.length === 1){
 			//console.log("sheets:", sheets);
-			dojo.forEach(sheets, function(s){
-				s.disabled = (s.title == title) ? false : true;
-				//console.log("SWITCHED:", s.title, s.disabled, s.id);
+			ArrayUtil.forEach(sheets, function(s){
+				s.disabled = (s.title === title) ? false : true;
 			});
 		}else{
-			for(var i=0; i<sheets.length;i++){
-				if(sheets[i].disabled == false){
+			for(i=0;i<sheets.length;i++){
+				if(sheets[i].disabled === false){
 					return sheets[i];
 				}
 			}
 		}
 		return true; //StyleSheet or Boolean - FIXME - doesn't make a lot of sense
-	}
+	};
 
-	dojox.html.getPreferredStyleSheet = function(){
+	dh.getPreferredStyleSheet = function(){
 		// summary
 		//	Returns the style sheet that was initially enabled
 		//	on document launch.
-
 		//TODO
-	}
+	};
 
-
-
-
-	dojox.html.getToggledStyleSheets = function(){
+	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:
 		//		An array of all toggle-able style sheets
-		//	TODO: 	Sets of style sheets could be grouped according to
+		//	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 = dojox.html.getStyleSheets();
-			for(var nm in sObjects){
-
+			var sObjects = dh.getStyleSheets();
+			for(nm in sObjects){
 				if(sObjects[nm].title){
-					//console.log("TITLE:", sObjects[nm].title, sObjects[nm])
 					titledSheets.push(sObjects[nm]);
 				}
 			}
 		}
 		return titledSheets; //Array
-	}
-
+	};
 
-	dojox.html.getStyleSheets = function(){
+	dh.getStyleSheets = function(){
 		// summary:
 		//		Collects all the style sheets referenced in the HTML page,
 		//		including any incuded via @import.
@@ -287,59 +262,47 @@ dojo.provide("dojox.html.styles");
 		//	returns:
 		//		An hash map of all the style sheets.
 		//
-		//	TODO: 	Does not recursively search for @imports, so it will
-		//			only go one level deep.
+		//TODO: Does not recursively search for @imports, so it will
+		//		only go one level deep.
 		//
 		if(pageStyleSheets.collected) {return pageStyleSheets;}
-
-		var sheets = dojo.doc.styleSheets;
-		//console.log("styleSheets:", sheets);
-		dojo.forEach(sheets, function(n){
+		var sheets = Window.doc.styleSheets;
+		ArrayUtil.forEach(sheets, function(n){
 			var s = (n.sheet) ? n.sheet : n;
 			var name = s.title || s.href;
-			if(dojo.isIE){
+			if(has("ie")){
 				// IE attaches a style sheet for VML - do not include this
-				if(s.cssText.indexOf("#default#VML")==-1){
-
-
+				if(s.cssText.indexOf("#default#VML") === -1){
 					if(s.href){
 						// linked
 						pageStyleSheets[name] = s;
-
 					}else if(s.imports.length){
 						// Imported via @import
-						dojo.forEach(s.imports, function(si){
+						ArrayUtil.forEach(s.imports, function(si){
 							pageStyleSheets[si.title || si.href] = si;
 						});
-
 					}else{
 						//embedded within page
 						pageStyleSheets[name] = s;
 					}
 				}
-
 			}else{
 				//linked or embedded
 				pageStyleSheets[name] = s;
 				pageStyleSheets[name].id = s.ownerNode.id;
-				dojo.forEach(s.cssRules, function(r){
+				ArrayUtil.forEach(s.cssRules, function(r){
 					if(r.href){
 						// imported
 						pageStyleSheets[r.href] = r.styleSheet;
 						pageStyleSheets[r.href].id = s.ownerNode.id;
 					}
 				});
-
 			}
-
 		});
-
 		//console.log("pageStyleSheets:", pageStyleSheets);
-
-
 		pageStyleSheets.collected = true;
 		return pageStyleSheets; //Object
-	}
-
-
-})();
+	};
+	
+	return dh;
+});
diff --git a/dojox/html/tests/test_metrics.html b/dojox/html/tests/test_metrics.html
index edb67f7..ced9ecd 100644
--- a/dojox/html/tests/test_metrics.html
+++ b/dojox/html/tests/test_metrics.html
@@ -7,7 +7,6 @@
 	@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="../metrics.js"></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 020ec68..91611af 100644
--- a/dojox/html/tests/test_metrics_getTextBox.html
+++ b/dojox/html/tests/test_metrics_getTextBox.html
@@ -13,7 +13,6 @@
             .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="../metrics.js"></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 a4042bf..beb2fb7 100644
--- a/dojox/html/tests/test_set.html
+++ b/dojox/html/tests/test_set.html
@@ -25,12 +25,13 @@
 		}
 	</style>
 	<script src='../../../dojo/dojo.js' djConfig='isDebug:true, parseOnLoad:true'></script>
-	<script src='../../../dojo/html.js'></script>
-	<script src='../../../dojox/html/_base.js'></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(){
diff --git a/dojox/html/tests/test_styles.html b/dojox/html/tests/test_styles.html
index ab70f3d..c4d5460 100644
--- a/dojox/html/tests/test_styles.html
+++ b/dojox/html/tests/test_styles.html
@@ -15,24 +15,26 @@
 	}
 </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.styles");
-	
+
 	getSelectedStyleSheet = function(){
 		if(dojo.byId("ssDefault").checked) return false;
 		if(dojo.byId("ssExtra").checked) return "ssExtra";
 	}
-	
+
 	enableStyleSheet = function(){
 		dojox.html.enableStyleSheet(getSelectedStyleSheet());
 	}
-	
+
 	disableStyleSheet = function(){
 		dojox.html.disableStyleSheet(getSelectedStyleSheet());
 	}
-	dojo.addOnLoad(function(){
+
+	dojo.ready(function(){
+
 		console.log(dojo.version.toString());
 		var styles = [
 			"p { font-size:24; margin:20px;}",
@@ -42,21 +44,21 @@
 			"p span {font-weight:bold;}",
 			"span {font-style:italic;}"
 		]
-		
+
 		var col = dojo.byId("btnCol");
 		dojo.forEach(styles, function(s){
-		
+
 			var sel = s.substring(0,s.indexOf("{")-1);
 			var des = s.substring(s.indexOf("{")+1, s.indexOf("}") );
-			
+
 			var div = dojo.doc.createElement("div");
 			col.appendChild(div);
-			
+
 			var d = dojo.doc.createElement("span");
 			dojo.style(d, "display", "block");
 			d.innerHTML = s;
 			div.appendChild(d);
-			
+
 			var b = dojo.doc.createElement("button");
 			div.appendChild(b);
 			b.innerHTML = "Insert";
@@ -71,14 +73,12 @@
 				console.log("Rem:", s);
 				dojox.html.removeCssRule(sel, des);
 			});
-			
+
 		});
-		
-		
-		
-		
+
 		console.log("Style Sheets tests:");
 		console.log("dojox.html.getStyleSheet [is false]:", dojox.html.getStyleSheet());
+
 		// insert a style, which creates our dynamic style sheet:
 		var sel = styles[0].substring(0,styles[0].indexOf("{")-1);
 		var des = styles[0].substring(styles[0].indexOf("{")+1, styles[0].indexOf("}") );
@@ -88,6 +88,7 @@
 		dojo.forEach(dojox.html.getToggledStyleSheets(), function(s){
 			console.log("    toggled style sheet:", s.title, "enabled:", !s.disabled);
 		});
+
 		var ss = dojox.html.getStyleSheets(); //return object
 		for(var nm in ss){
 			//display either title or href
@@ -95,11 +96,11 @@
 			if(!name){ name = "*Persistant*"}
 			console.log("    style sheet:", name);
 		}
+
 		console.log("dojox.html.getStyleSheet [href:dijitTests.css, object]:", dojox.html.getStyleSheet("dijitTests.css"));
 		console.log("dojox.html.getStyleSheet [title:BadStyleName]:", dojox.html.getStyleSheet("BadStyleName"));
-	
-	});
 
+	});
 </script>
 <style>
 	#btnCol{
@@ -110,7 +111,7 @@
 	}
 	body table td{
 		vertical-align:top;
-		
+
 	}
 	button{
 		width:70px;
@@ -144,24 +145,24 @@ to create a second style sheet. Toggle them on and off. See the log for more sty
     </td>
     <td>
     	<p>paragraph text</p>
-    
+
     <p class="foo">paragraph class=foo text
     	<span class="woot">span class=woot</span>
         with a span inside it
     </p>
-    
+
     <p class="bar">paragraph class=bar text
     	<span class="zoot">span class=zoot</span>
     	with a span inside it
     </p>
-     
+
      <span class="xoot">external span class=xoot</span>
     </td>
   </tr>
 </table>
-	
-     
-     
-    	
+
+
+
+
 </body>
 </html>
diff --git a/dojox/html/tests/test_themes.html b/dojox/html/tests/test_themes.html
index f188bf7..4081a51 100644
--- a/dojox/html/tests/test_themes.html
+++ b/dojox/html/tests/test_themes.html
@@ -31,6 +31,9 @@ dojo.require("dojox.html.styles");
 dojo.require("dijit.Menu");
 dojo.require("dijit.Calendar");
 dojo.require("dijit.form.Button");
+dojo.require("dijit.form.DropDownButton");
+dojo.require("dijit.form.ComboButton");
+dojo.require("dijit.form.ToggleButton");
 dojo.require("dijit.Calendar");
 changeStyle = function(title){
 	dojox.html.activeStyleSheet(title);
diff --git a/dojox/image.js b/dojox/image.js
index 60c010f..d1fe6d0 100644
--- a/dojox/image.js
+++ b/dojox/image.js
@@ -1,2 +1,8 @@
-dojo.provide("dojox.image");
-dojo.require("dojox.image._base");
+define(["./image/_base"], function(image){
+	/*=====
+	dojox.image = {
+		// summary: Collection of image-related widgets and controls
+	};
+	=====*/
+	return image;
+});
\ No newline at end of file
diff --git a/dojox/image/Badge.js b/dojox/image/Badge.js
index 17b2baa..21c3b82 100644
--- a/dojox/image/Badge.js
+++ b/dojox/image/Badge.js
@@ -1,226 +1,228 @@
-dojo.provide("dojox.image.Badge");
-dojo.experimental("dojox.image.Badge");
+define(["dojo", "dijit", "dojox/main", "dijit/_Widget", "dijit/_TemplatedMixin", "dojo/fx/easing"], function(dojo, dijit, dojox){
 
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dojo.fx.easing");
+	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
+		//
 
-dojo.declare("dojox.image.Badge", [dijit._Widget, dijit._Templated], {
-	// summary: A simple grid of Images that loops through thumbnails
-	//
+		baseClass: "dojoxBadge",
 
-	baseClass: "dojoxBadge",
-	
-	templateString:'<div class="dojoxBadge" dojoAttachPoint="containerNode"></div>',
+		templateString:'<div class="dojoxBadge" dojoAttachPoint="containerNode"></div>',
 
-	// children: String
-	// 		A CSS3 Selector that determines the node to become a child
-	children: "div.dojoxBadgeImage",
+		// children: String
+		// 		A CSS3 Selector that determines the node to become a child
+		children: "div.dojoxBadgeImage",
 
-	// rows: Integer
-	//		Number of Rows to display
-	rows: 4,
-	
-	// cols: Integer
-	//		Number of Columns to display
-	cols: 5,
-	
-	// cellSize: Integer
-	//		Size in PX of each thumbnail
-	cellSize: 50,
-	
-	// cellMargin: Integer
-	//		Size in PX to adjust for cell margins
-	cellMargin: 1,
-	
-	// delay: Integer
-	//		Time (in ms) to show the image before sizing down again
-	delay: 2000,
-	
-	// threads: Integer
-	//		how many cycles will be going "simultaneously" (>2 not reccommended)
-	threads: 1,
-	
-	// easing: Function|String
-	//		An easing function to use when showing the node (does not apply to shrinking)
-	easing: "dojo.fx.easing.backOut",
-	
-	startup: function(){
-		if(this._started){ return; }
-		if(dojo.isString(this.easing)){
-			this.easing = dojo.getObject(this.easing);
-		}
-		this.inherited(arguments);
-		this._init();
-	},
-	
-	_init: function(){
-		// summary: Setup and layout the images
-	
-		var _row = 0,
-			_w = this.cellSize;
-
-		dojo.style(this.domNode, {
-			width: _w * this.cols + "px",
-			height: _w * this.rows + "px"
-		});
-
-		this._nl = dojo.query(this.children, this.containerNode)
-			.forEach(function(n, _idx){
-
-				var _col = _idx % this.cols,
-					t = _row * _w,
-					l = _col * _w,
-					m = this.cellMargin * 2;
-			
-				dojo.style(n, {
-		 			top: t + "px",
-		 			left: l + "px",
-					width: _w - m + "px",
-					height: _w - m + "px"
-		 		});
-
-				if(_col == this.cols - 1){ _row++; }
-				dojo.addClass(n, this.baseClass + "Image");
-				
-			}, this)
-		;
-		
-		var l = this._nl.length;
-		while(this.threads--){
-			var s = Math.floor(Math.random() * l);
-			setTimeout(dojo.hitch(this, "_enbiggen", {
-				target: this._nl[s]
-			}), this.delay * this.threads);
-		}
-		
-	},
-	
-	_getCell: function(/* DomNode */ n){
-		// summary: Return information about the position for a given node
-		var _pos = this._nl.indexOf(n);
-		if(_pos >= 0){
-			var _col = _pos % this.cols;
-			var _row = Math.floor(_pos / this.cols);
-			return { x: _col, y: _row, n: this._nl[_pos], io: _pos };
-		}else{
-			return undefined;
-		}
-	},
-	
-	_getImage: function(){
-		// 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
-		var _pos = this._getCell(e.target || e);
-
-		if (_pos){
-			// we have a node, and know where it is
-
-			var m = this.cellMargin,
-				_cc = (this.cellSize * 2) - (m * 2),
-				props = {
-					height: _cc,
-					width: _cc
-				}
+		// rows: Integer
+		//		Number of Rows to display
+		rows: 4,
+
+		// cols: Integer
+		//		Number of Columns to display
+		cols: 5,
+
+		// cellSize: Integer
+		//		Size in PX of each thumbnail
+		cellSize: 50,
+
+		// cellMargin: Integer
+		//		Size in PX to adjust for cell margins
+		cellMargin: 1,
+
+		// delay: Integer
+		//		Time (in ms) to show the image before sizing down again
+		delay: 2000,
+
+		// threads: Integer
+		//		how many cycles will be going "simultaneously" (>2 not reccommended)
+		threads: 1,
+
+		// easing: Function|String
+		//		An easing function to use when showing the node (does not apply to shrinking)
+		easing: "dojo.fx.easing.backOut",
+
+		startup: function(){
+			if(this._started){ return; }
+			if(dojo.isString(this.easing)){
+				this.easing = dojo.getObject(this.easing);
+			}
+			this.inherited(arguments);
+			this._init();
+		},
+
+		_init: function(){
+			// summary: Setup and layout the images
+
+			var _row = 0,
+				_w = this.cellSize;
+
+			dojo.style(this.domNode, {
+				width: _w * this.cols + "px",
+				height: _w * this.rows + "px"
+			});
+
+			this._nl = dojo.query(this.children, this.containerNode)
+				.forEach(function(n, _idx){
+
+					var _col = _idx % this.cols,
+						t = _row * _w,
+						l = _col * _w,
+						m = this.cellMargin * 2;
+
+					dojo.style(n, {
+			 			top: t + "px",
+			 			left: l + "px",
+						width: _w - m + "px",
+						height: _w - m + "px"
+			 		});
+
+					if(_col == this.cols - 1){ _row++; }
+					dojo.addClass(n, this.baseClass + "Image");
+
+				}, this)
 			;
-			
-			var _tehDecider = function(){
-				// if we have room, we'll want to decide which direction to go
-				// let "teh decider" decide.
-				return Math.round(Math.random());
-			};
-			
-			if(_pos.x == this.cols - 1 || (_pos.x > 0 && _tehDecider() )){
-				// we have to go left, at right edge (or we want to and not on left edge)
-				props.left = this.cellSize * (_pos.x - m);
+
+			var l = this._nl.length;
+			while(this.threads--){
+				var s = Math.floor(Math.random() * l);
+				setTimeout(dojo.hitch(this, "_enbiggen", {
+					target: this._nl[s]
+				}), this.delay * this.threads);
 			}
-			
-			if(_pos.y == this.rows - 1 || (_pos.y > 0 && _tehDecider() )){
-				// we have to go up, at bottom edge (or we want to and not at top)
-				props.top = this.cellSize * (_pos.y - m);
+
+		},
+
+		_getCell: function(/* DomNode */ n){
+			// summary: Return information about the position for a given node
+			var _pos = this._nl.indexOf(n);
+			if(_pos >= 0){
+				var _col = _pos % this.cols;
+				var _row = Math.floor(_pos / this.cols);
+				return { x: _col, y: _row, n: this._nl[_pos], io: _pos };
+			}else{
+				return undefined;
 			}
+		},
+
+		_getImage: function(){
+			// 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
+			var _pos = this._getCell(e.target || e);
+
+			if (_pos){
+				// we have a node, and know where it is
+
+				var m = this.cellMargin,
+					_cc = (this.cellSize * 2) - (m * 2),
+					props = {
+						height: _cc,
+						width: _cc
+					}
+				;
+
+				var _tehDecider = function(){
+					// if we have room, we'll want to decide which direction to go
+					// let "teh decider" decide.
+					return Math.round(Math.random());
+				};
+
+				if(_pos.x == this.cols - 1 || (_pos.x > 0 && _tehDecider() )){
+					// we have to go left, at right edge (or we want to and not on left edge)
+					props.left = this.cellSize * (_pos.x - m);
+				}
 
-			var bc = this.baseClass;
-			dojo.addClass(_pos.n, bc + "Top");
-			dojo.addClass(_pos.n, bc + "Seen");
-
-			dojo.animateProperty({ node: _pos.n, properties: props,
-				onEnd: dojo.hitch(this, "_loadUnder", _pos, props),
-				easing: this.easing
-			}).play();
-			
-		}
-	},
-	
-	_loadUnder: function(info, props){
-		// summary: figure out which three images are being covered, and
-		//		determine if they need loaded or not
-
-		var idx = info.io;
-		var nodes = [];
-
-		var isLeft = (props.left >= 0);
-		var isUp = (props.top >= 0);
-		
-		var c = this.cols,
-			// the three node index's we're allegedly over:
-			e = idx + (isLeft ? -1 : 1),
-			f = idx + (isUp ? -c : c),
-			// don't ask:
-			g = (isUp ? (isLeft ? e - c : f + 1) : (isLeft ? f - 1 : e + c)),
-
-			bc = this.baseClass;
-		
-		dojo.forEach([e, f, g], function(x){
-			var n = this._nl[x];
-			if(n){
-				if(dojo.hasClass(n, bc + "Seen")){
-					// change the background image out?
-					dojo.removeClass(n, bc + "Seen");
+				if(_pos.y == this.rows - 1 || (_pos.y > 0 && _tehDecider() )){
+					// we have to go up, at bottom edge (or we want to and not at top)
+					props.top = this.cellSize * (_pos.y - m);
 				}
+
+				var bc = this.baseClass;
+				dojo.addClass(_pos.n, bc + "Top");
+				dojo.addClass(_pos.n, bc + "Seen");
+
+				dojo.animateProperty({ node: _pos.n, properties: props,
+					onEnd: dojo.hitch(this, "_loadUnder", _pos, props),
+					easing: this.easing
+				}).play();
+
 			}
-		},this);
-		
-		setTimeout(dojo.hitch(this, "_disenbiggen", info, props), this.delay * 1.25);
+		},
+
+		_loadUnder: function(info, props){
+			// summary: figure out which three images are being covered, and
+			//		determine if they need loaded or not
+
+			var idx = info.io;
+			var nodes = [];
+
+			var isLeft = (props.left >= 0);
+			var isUp = (props.top >= 0);
+
+			var c = this.cols,
+				// the three node index's we're allegedly over:
+				e = idx + (isLeft ? -1 : 1),
+				f = idx + (isUp ? -c : c),
+				// don't ask:
+				g = (isUp ? (isLeft ? e - c : f + 1) : (isLeft ? f - 1 : e + c)),
+
+				bc = this.baseClass;
+
+			dojo.forEach([e, f, g], function(x){
+				var n = this._nl[x];
+				if(n){
+					if(dojo.hasClass(n, bc + "Seen")){
+						// change the background image out?
+						dojo.removeClass(n, bc + "Seen");
+					}
+				}
+			},this);
+
+			setTimeout(dojo.hitch(this, "_disenbiggen", info, props), this.delay * 1.25);
+
+		},
+
+		_disenbiggen: function(info, props){
+			// summary: Hide the passed node (info.n), passing along properties
+			//		received.
+
+			if(props.top >= 0){
+				props.top += this.cellSize;
+			}
+			if(props.left >= 0){
+				props.left += this.cellSize;
+			}
+			var _cc = this.cellSize - (this.cellMargin * 2);
+			dojo.animateProperty({
+				node: info.n,
+				properties: dojo.mixin(props, {
+					width:_cc,
+					height:_cc
+				}),
+				onEnd: dojo.hitch(this, "_cycle", info, props)
+			}).play(5);
+		},
+
+		_cycle: function(info, props){
+			// summary: Select an un-viewed image from the list, and show it
+
+			var bc = this.baseClass;
+			dojo.removeClass(info.n, bc + "Top");
+			var ns = this._nl.filter(function(n){
+				return !dojo.hasClass(n, bc + "Seen")
+			});
+			var c = ns[Math.floor(Math.random() * ns.length)];
+			setTimeout(dojo.hitch(this,"_enbiggen", { target: c }), this.delay / 2)
 
-	},
-	
-	_disenbiggen: function(info, props){
-		// summary: Hide the passed node (info.n), passing along properties
-		//		received.
-		
-		if(props.top >= 0){
-			props.top += this.cellSize;
-		}
-		if(props.left >= 0){
-			props.left += this.cellSize;
 		}
-		var _cc = this.cellSize - (this.cellMargin * 2);
-		dojo.animateProperty({
-			node: info.n,
-			properties: dojo.mixin(props, {
-				width:_cc,
-				height:_cc
-			}),
-			onEnd: dojo.hitch(this, "_cycle", info, props)
-		}).play(5);
-	},
-	
-	_cycle: function(info, props){
-		// summary: Select an un-viewed image from the list, and show it
-
-		var bc = this.baseClass;
-		dojo.removeClass(info.n, bc + "Top");
-		var ns = this._nl.filter(function(n){
-			return !dojo.hasClass(n, bc + "Seen")
-		});
-		var c = ns[Math.floor(Math.random() * ns.length)];
-		setTimeout(dojo.hitch(this,"_enbiggen", { target: c }), this.delay / 2)
-
-	}
-	
-});
+
+	});
+
+	return dojox.image.Badge;
+})
+
diff --git a/dojox/image/FlickrBadge.js b/dojox/image/FlickrBadge.js
index d58ce70..238d8bf 100644
--- a/dojox/image/FlickrBadge.js
+++ b/dojox/image/FlickrBadge.js
@@ -1,105 +1,106 @@
-dojo.provide("dojox.image.FlickrBadge");
+define(["dojo", "dojox/main", "dojox/image/Badge", "dojox/data/FlickrRestStore"], function(dojo, dojox){
+	
+	dojo.getObject("image", true, dojox);
+	return dojo.declare("dojox.image.FlickrBadge", dojox.image.Badge, {
+		children: "a.flickrImage",
 
-dojo.require("dojox.image.Badge");
-dojo.require("dojox.data.FlickrRestStore");
+		// userid: String
+		// 		If you know your Flickr userid, you can set it to prevent a call to fetch the id
+		userid: "",
 
-dojo.declare("dojox.image.FlickrBadge", dojox.image.Badge, {
-	children: "a.flickrImage",
+		// username: String
+		// 		Your Flickr username
+		username: "",
 
-	// userid: String
-	// 		If you know your Flickr userid, you can set it to prevent a call to fetch the id
-	userid: "",
+		// setid: String
+		// 		The id of the set to display
+		setid: "",
 
-	// username: String
-	// 		Your Flickr username
-	username: "",
+		// tags: String|Array
+		// 		A comma separated list of tags or an array of tags to grab from Flickr
+		tags: "",
 
-	// setid: String
-	// 		The id of the set to display
-	setid: "",
+		// searchText: String
+		// 		Free text search.  Photos who's title, description, or tags contain the text will be displayed
+		searchText: "",
 
-	// tags: String|Array
-	// 		A comma separated list of tags or an array of tags to grab from Flickr
-	tags: "",
+		// target: String
+		// 		Where to display the pictures when clicked on.  Valid values are the same as the target attribute
+		// 		of the A tag.
+		target: "",
 
-	// searchText: String
-	// 		Free text search.  Photos who's title, description, or tags contain the text will be displayed
-	searchText: "",
+		apikey: "8c6803164dbc395fb7131c9d54843627",
+		_store: null,
 
-	// target: String
-	// 		Where to display the pictures when clicked on.  Valid values are the same as the target attribute
-	// 		of the A tag.
-	target: "",
-
-	apikey: "8c6803164dbc395fb7131c9d54843627",
-	_store: null,
-
-	postCreate: function(){
-		if(this.username && !this.userid){
-			var def = dojo.io.script.get({
-				url: "http://www.flickr.com/services/rest/",
-				preventCache: true,
-				content: {
-					format: "json",
-					method: "flickr.people.findByUsername",
-					api_key: this.apikey,
-					username: this.username
-				},
-				callbackParamName: "jsoncallback"
-			});
-			def.addCallback(this, function(data){
-				if(data.user && data.user.nsid){
-					this.userid = data.user.nsid;
-					if(!this._started){
-						this.startup();
+		postCreate: function(){
+			if(this.username && !this.userid){
+				var def = dojo.io.script.get({
+					url: "http://www.flickr.com/services/rest/",
+					preventCache: true,
+					content: {
+						format: "json",
+						method: "flickr.people.findByUsername",
+						api_key: this.apikey,
+						username: this.username
+					},
+					callbackParamName: "jsoncallback"
+				});
+				def.addCallback(this, function(data){
+					if(data.user && data.user.nsid){
+						this.userid = data.user.nsid;
+						if(!this._started){
+							this.startup();
+						}
 					}
-				}
-			});
-		}
-	},
-
-	startup: function(){
-		if(this._started){ return; }
-		if(this.userid){
-			var query = {
-				userid: this.userid
-			};
-			if(this.setid){
-				query["setid"] = this.setid;
-			}
-			if(this.tags){
-				query.tags = this.tags;
-			}
-			if(this.searchText){
-				query.text = this.searchText;
+				});
 			}
-			var args = arguments;
-			this._store = new dojox.data.FlickrRestStore({ apikey: this.apikey });
-			this._store.fetch({
-				count: this.cols * this.rows,
-				query: query,
-				onComplete: dojo.hitch(this, function(items){
-					dojo.forEach(items, function(item){
-						var a = dojo.doc.createElement("a");
-						dojo.addClass(a, "flickrImage");
-						a.href = this._store.getValue(item, "link");
-						if(this.target){
-							a.target = this.target;
-						}
+		},
 
-						var img = dojo.doc.createElement("img");
-						img.src = this._store.getValue(item, "imageUrlThumb");
-						dojo.style(img, {
-							width: "100%",
-							height: "100%"
-						});
+		startup: function(){
+			if(this._started){ return; }
+			if(this.userid){
+				var query = {
+					userid: this.userid
+				};
+				if(this.setid){
+					query["setid"] = this.setid;
+				}
+				if(this.tags){
+					query.tags = this.tags;
+				}
+				if(this.searchText){
+					query.text = this.searchText;
+				}
+				var args = arguments;
+				this._store = new dojox.data.FlickrRestStore({ apikey: this.apikey });
+				this._store.fetch({
+					count: this.cols * this.rows,
+					query: query,
+					onComplete: dojo.hitch(this, function(items){
+						dojo.forEach(items, function(item){
+							var a = dojo.doc.createElement("a");
+							dojo.addClass(a, "flickrImage");
+							a.href = this._store.getValue(item, "link");
+							if(this.target){
+								a.target = this.target;
+							}
 
-						a.appendChild(img);
-						this.domNode.appendChild(a);
-					}, this);
-					dojox.image.Badge.prototype.startup.call(this, args);
-				})
-			});
+							var img = dojo.doc.createElement("img");
+							img.src = this._store.getValue(item, "imageUrlThumb");
+							dojo.style(img, {
+								width: "100%",
+								height: "100%"
+							});
+
+							a.appendChild(img);
+							this.domNode.appendChild(a);
+						}, this);
+						dojox.image.Badge.prototype.startup.call(this, args);
+					})
+				});
+			}
 		}
-	}
+	});
+	
 });
+
diff --git a/dojox/image/Lightbox.js b/dojox/image/Lightbox.js
index 1926e48..cd6028b 100644
--- a/dojox/image/Lightbox.js
+++ b/dojox/image/Lightbox.js
@@ -1,601 +1,605 @@
-dojo.provide("dojox.image.Lightbox");
-dojo.experimental("dojox.image.Lightbox");
-
-dojo.require("dojo.window");
-dojo.require("dijit.Dialog");
-dojo.require("dojox.fx._base");
-
-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
-	//
-	//	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: "",
-
-	// title: String
-	//		A string of text to be shown in the Lightbox beneath the image (empty if using a store)
-	title: "",
-
-	// href; String
-	//		Link to image to use for this Lightbox node (empty if using a store).
-	href: "",
-
-	// duration: Integer
-	//		Generic time in MS to adjust the feel of widget. could possibly add various
-	//		durations for the various actions (dialog fadein, sizeing, img fadein ...)
-	duration: 500,
-
-	// 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)
-	modal: false,
-
-	// _allowPassthru: Boolean
-	//		Privately set this to disable/enable natural link of anchor tags
-	_allowPassthru: false,
-	
-	// _attachedDialg: dojox.image._LightboxDialog
-	//		The pointer to the global lightbox dialog for this widget
-	_attachedDialog: null, // try to share a single underlay per page?
-
-	startup: function(){
-		this.inherited(arguments);
-		// setup an attachment to the masterDialog (or create the masterDialog)
-		var tmp = dijit.byId('dojoxLightboxDialog');
-		if(tmp){
-			this._attachedDialog = tmp;
-		}else{
-			// this is the first instance to start, so we make the masterDialog
-			this._attachedDialog = new dojox.image.LightboxDialog({ id: "dojoxLightboxDialog" });
-			this._attachedDialog.startup();
-		}
-		if(!this.store){
-			// FIXME: full store support lacking, have to manually call this._attachedDialog.addImage(imgage,group) as it stands
-			this._addSelf();
-			this.connect(this.domNode, "onclick", "_handleClick");
-		}
+define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/Dialog", "dojox/fx/_base"], function(dojo, dijit, dojox, template){
 
-	},
-
-	_addSelf: function(){
-		// summary: Add this instance to the master LightBoxDialog
-		this._attachedDialog.addImage({
-			href: this.href,
-			title: this.title
-		}, this.group || null);
-	},
-
-	_handleClick: function(/* Event */e){
-		// 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
-		this._attachedDialog.show(this);
-	},
-	
-	hide: function(){
-		// 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
-		this._allowPassthru = true;
-	},
-
-	enable: function(){
-		// summary: Enables the dialog (prevents default link)
-		this._allowPassthru = false;
-	},
-	
-	onClick: function(){
+	dojo.experimental("dojox.image.Lightbox");
+	dojo.getObject("image", true, dojox);
+
+	dojo.declare("dojox.image.Lightbox", dijit._Widget, {
 		// summary:
-		//		Stub fired when the image in the lightbox is clicked.
-	},
-	
-	destroy: function(){
-		this._attachedDialog.removeImage(this);
-		this.inherited(arguments);
-	}
+		//		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
+		//
+		//	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: "",
+
+		// title: String
+		//		A string of text to be shown in the Lightbox beneath the image (empty if using a store)
+		title: "",
+
+		// href; String
+		//		Link to image to use for this Lightbox node (empty if using a store).
+		href: "",
+
+		// duration: Integer
+		//		Generic time in MS to adjust the feel of widget. could possibly add various
+		//		durations for the various actions (dialog fadein, sizeing, img fadein ...)
+		duration: 500,
+
+		// 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)
+		modal: false,
+
+		// _allowPassthru: Boolean
+		//		Privately set this to disable/enable natural link of anchor tags
+		_allowPassthru: false,
+
+		// _attachedDialg: dojox.image._LightboxDialog
+		//		The pointer to the global lightbox dialog for this widget
+		_attachedDialog: null, // try to share a single underlay per page?
+
+		startup: function(){
+			this.inherited(arguments);
+			// setup an attachment to the masterDialog (or create the masterDialog)
+			var tmp = dijit.byId('dojoxLightboxDialog');
+			if(tmp){
+				this._attachedDialog = tmp;
+			}else{
+				// this is the first instance to start, so we make the masterDialog
+				this._attachedDialog = new dojox.image.LightboxDialog({ id: "dojoxLightboxDialog" });
+				this._attachedDialog.startup();
+			}
+			if(!this.store){
+				// FIXME: full store support lacking, have to manually call this._attachedDialog.addImage(imgage,group) as it stands
+				this._addSelf();
+				this.connect(this.domNode, "onclick", "_handleClick");
+			}
 
-});
+		},
+
+		_addSelf: function(){
+			// summary: Add this instance to the master LightBoxDialog
+			this._attachedDialog.addImage({
+				href: this.href,
+				title: this.title
+			}, this.group || null);
+		},
+
+		_handleClick: function(/* Event */e){
+			// 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
+			this._attachedDialog.show(this);
+		},
+
+		hide: function(){
+			// 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
+			this._allowPassthru = true;
+		},
+
+		enable: function(){
+			// summary: Enables the dialog (prevents default link)
+			this._allowPassthru = false;
+		},
+
+		onClick: function(){
+			// summary:
+			//		Stub fired when the image in the lightbox is clicked.
+		},
+
+		destroy: function(){
+			this._attachedDialog.removeImage(this);
+			this.inherited(arguments);
+		}
 
-dojo.declare("dojox.image.LightboxDialog",
-	dijit.Dialog, {
-	// summary:
-	//		The "dialog" shared	 between any Lightbox instances on the page, publically available
-	//		for programatic 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
-	//		unless you need the direct access.
-	//
-	//		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:
-	//	|	// 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: "",
-
-	// FIXME: implement titleTemplate
-
-	// inGroup: Array
-	//		Array of objects. this is populated by from the JSON object _groups, and
-	//		should not be populate manually. it is a placeholder for the currently
-	//		showing group of images in this master dialog
-	inGroup: null,
-
-	// imgUrl: String
-	//		The src="" attribute of our imageNode (can be null at statup)
-	imgUrl: dijit._Widget.prototype._blankGif,
-		
-	// errorMessage: String
-	//		The text to display when an unreachable image is linked
-	errorMessage: "Image not found.",
-
-	// adjust: Boolean
-	//		If true, ensure the image always stays within the viewport
-	//		more difficult than necessary to disable, but enabled by default
-	//		seems sane in most use cases.
-	adjust: true,
-
-	// 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)
-	modal: false,
-
-/*=====
-	// _groups: Object
-	//		an object of arrays, each array (of objects) being a unique 'group'
-	_groups: { XnoGroupX: [] },
-
-=====*/
-
-	// errorImg: Url
-	//		Path to the image used when a 404 is encountered
-	errorImg: dojo.moduleUrl("dojox.image","resources/images/warning.png"),
-
-	templateString: dojo.cache("dojox.image","resources/Lightbox.html"),
-	constructor: function(args){
-		this._groups = this._groups || (args && args._groups) || { XnoGroupX:[] };
-	},
-
-	startup: function(){
-		// 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()
+	});
 
-		this.inherited(arguments);
-		
-		this._animConnects = [];
-		this.connect(this.nextButtonNode, "onclick", "_nextImage");
-		this.connect(this.prevButtonNode, "onclick", "_prevImage");
-		this.connect(this.closeButtonNode, "onclick", "hide");
-		this._makeAnims();
-		this._vp = dojo.window.getBox();
-		return this;
-	},
-
-	show: function(/* Object */groupData){
-		// 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
+	dojo.declare("dojox.image.LightboxDialog",
+		dijit.Dialog, {
+		// summary:
+		//		The "dialog" shared	 between any Lightbox instances on the page, publically available
+		//		for programatic manipulation.
+		//
+		// description:
 		//
-		// groupData: Object
-		//		needs href and title attributes. the values for this image.
+		//		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
+		//		unless you need the direct access.
 		//
+		//		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)
 		//
-		var _t = this; // size
-		this._lastGroup = groupData;
+		//	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: "",
+
+		// FIXME: implement titleTemplate
+
+		// inGroup: Array
+		//		Array of objects. this is populated by from the JSON object _groups, and
+		//		should not be populate manually. it is a placeholder for the currently
+		//		showing group of images in this master dialog
+		inGroup: null,
+
+		// imgUrl: String
+		//		The src="" attribute of our imageNode (can be null at statup)
+		imgUrl: dijit._Widget.prototype._blankGif,
+
+		// errorMessage: String
+		//		The text to display when an unreachable image is linked
+		errorMessage: "Image not found.",
+
+		// adjust: Boolean
+		//		If true, ensure the image always stays within the viewport
+		//		more difficult than necessary to disable, but enabled by default
+		//		seems sane in most use cases.
+		adjust: true,
+
+		// 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)
+		modal: false,
+
+	/*=====
+		// _groups: Object
+		//		an object of arrays, each array (of objects) being a unique 'group'
+		_groups: { XnoGroupX: [] },
+
+	=====*/
+
+		// errorImg: Url
+		//		Path to the image used when a 404 is encountered
+		errorImg: dojo.moduleUrl("dojox.image","resources/images/warning.png"),
+
+		templateString: template, 
 		
-		// we only need to call dijit.Dialog.show() if we're not already open.
-		if(!_t.open){
-			_t.inherited(arguments);
-			_t._modalconnects.push(
-				dojo.connect(dojo.global, "onscroll", this, "_position"),
-				dojo.connect(dojo.global, "onresize", this, "_position"),
-				dojo.connect(dojo.body(), "onkeypress", this, "_handleKey")
-			);
-			if(!groupData.modal){
+		constructor: function(args){
+			this._groups = this._groups || (args && args._groups) || { XnoGroupX:[] };
+		},
+
+		startup: function(){
+			// 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()
+
+			this.inherited(arguments);
+
+			this._animConnects = [];
+			this.connect(this.nextButtonNode, "onclick", "_nextImage");
+			this.connect(this.prevButtonNode, "onclick", "_prevImage");
+			this.connect(this.closeButtonNode, "onclick", "hide");
+			this._makeAnims();
+			this._vp = dojo.window.getBox();
+			return this;
+		},
+
+		show: function(/* Object */groupData){
+			// 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;
+
+			// we only need to call dijit.Dialog.show() if we're not already open.
+			if(!_t.open){
+				_t.inherited(arguments);
 				_t._modalconnects.push(
-					dojo.connect(dijit._underlay.domNode, "onclick", this, "onCancel")
+					dojo.connect(dojo.global, "onscroll", this, "_position"),
+					dojo.connect(dojo.global, "onresize", this, "_position"),
+					dojo.connect(dojo.body(), "onkeypress", this, "_handleKey")
 				);
+				if(!groupData.modal){
+					_t._modalconnects.push(
+						dojo.connect(dijit._underlay.domNode, "onclick", this, "onCancel")
+					);
+				}
 			}
-		}
-		
-		if(this._wasStyled){
-			// 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");
-			dojo.destroy(_t.imgNode);
-			_t.imgNode = tmpImg;
-			_t._makeAnims();
-			_t._wasStyled = false;
-		}
-		
-		dojo.style(_t.imgNode,"opacity","0");
-		dojo.style(_t.titleNode,"opacity","0");
-		
-		var src = groupData.href;
-		
-		if((groupData.group && groupData !== "XnoGroupX") || _t.inGroup){
-			if(!_t.inGroup){
-				_t.inGroup = _t._groups[(groupData.group)];
-				// determine where we were or are in the show
-				dojo.forEach(_t.inGroup, function(g, i){
-					if(g.href == groupData.href){
-						_t._index = i;
-						//return false;
-					}
-					//return true;
-				});
+
+			if(this._wasStyled){
+				// 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");
+				dojo.destroy(_t.imgNode);
+				_t.imgNode = tmpImg;
+				_t._makeAnims();
+				_t._wasStyled = false;
 			}
-			if(!_t._index){
-				_t._index = 0;
-				var sr = _t.inGroup[_t._index];
-				src = (sr && sr.href) || _t.errorImg;
+
+			dojo.style(_t.imgNode,"opacity","0");
+			dojo.style(_t.titleNode,"opacity","0");
+
+			var src = groupData.href;
+
+			if((groupData.group && groupData !== "XnoGroupX") || _t.inGroup){
+				if(!_t.inGroup){
+					_t.inGroup = _t._groups[(groupData.group)];
+					// determine where we were or are in the show
+					dojo.forEach(_t.inGroup, function(g, i){
+						if(g.href == groupData.href){
+							_t._index = i;
+							//return false;
+						}
+						//return true;
+					});
+				}
+				if(!_t._index){
+					_t._index = 0;
+					var sr = _t.inGroup[_t._index];
+					src = (sr && sr.href) || _t.errorImg;
+				}
+				// FIXME: implement titleTemplate
+				_t.groupCount.innerHTML = " (" + (_t._index + 1) + " of " + Math.max(1, _t.inGroup.length) + ")";
+				_t.prevButtonNode.style.visibility = "visible";
+				_t.nextButtonNode.style.visibility = "visible";
+			}else{
+				// single images don't have buttons, or counters:
+				_t.groupCount.innerHTML = "";
+				_t.prevButtonNode.style.visibility = "hidden";
+				_t.nextButtonNode.style.visibility = "hidden";
 			}
-			// FIXME: implement titleTemplate
-			_t.groupCount.innerHTML = " (" + (_t._index + 1) + " of " + Math.max(1, _t.inGroup.length) + ")";
-			_t.prevButtonNode.style.visibility = "visible";
-			_t.nextButtonNode.style.visibility = "visible";
-		}else{
-			// single images don't have buttons, or counters:
-			_t.groupCount.innerHTML = "";
-			_t.prevButtonNode.style.visibility = "hidden";
-			_t.nextButtonNode.style.visibility = "hidden";
-		}
-		if(!groupData.leaveTitle){
-			_t.textNode.innerHTML = groupData.title;
-		}
-		_t._ready(src);
-	},
-	
-	_ready: function(src){
-		// summary: A function to trigger all 'real' showing of some src
-		
-		var _t = this;
-		
-		// listen for 404's:
-		_t._imgError = dojo.connect(_t.imgNode, "error", _t, function(){
-			dojo.disconnect(_t._imgError);
-			// trigger the above onload with a new src:
-			_t.imgNode.src = _t.errorImg;
-			_t.textNode.innerHTML = _t.errorMessage;
-		});
-		
-		// connect to the onload of the image
-		_t._imgConnect = dojo.connect(_t.imgNode, "load", _t, function(e){
-			_t.resizeTo({
-				w: _t.imgNode.width,
-				h: _t.imgNode.height,
-				duration:_t.duration
-			});
-			// cleanup
-			dojo.disconnect(_t._imgConnect);
-			if(_t._imgError){
-				dojo.disconnect(_t._imgError);
+			if(!groupData.leaveTitle){
+				_t.textNode.innerHTML = groupData.title;
 			}
-		});
-		
-		_t.imgNode.src = src;
-	},
-
-	_nextImage: function(){
-		// summary: Load next image in group
-		if(!this.inGroup){ return; }
-		if(this._index + 1 < this.inGroup.length){
-			this._index++;
-		}else{
-			this._index = 0;
-		}
-		this._loadImage();
-	},
-
-	_prevImage: function(){
-		// summary: Load previous image in group
-		if(this.inGroup){
-			if(this._index == 0){
-				this._index = this.inGroup.length - 1;
+			_t._ready(src);
+		},
+
+		_ready: function(src){
+			// summary: A function to trigger all 'real' showing of some src
+
+			var _t = this;
+
+			// listen for 404's:
+			_t._imgError = dojo.connect(_t.imgNode, "error", _t, function(){
+				dojo.disconnect(_t._imgError);
+				// trigger the above onload with a new src:
+				_t.imgNode.src = _t.errorImg;
+				_t.textNode.innerHTML = _t.errorMessage;
+			});
+
+			// connect to the onload of the image
+			_t._imgConnect = dojo.connect(_t.imgNode, "load", _t, function(e){
+				_t.resizeTo({
+					w: _t.imgNode.width,
+					h: _t.imgNode.height,
+					duration:_t.duration
+				});
+				// cleanup
+				dojo.disconnect(_t._imgConnect);
+				if(_t._imgError){
+					dojo.disconnect(_t._imgError);
+				}
+			});
+
+			_t.imgNode.src = src;
+		},
+
+		_nextImage: function(){
+			// summary: Load next image in group
+			if(!this.inGroup){ return; }
+			if(this._index + 1 < this.inGroup.length){
+				this._index++;
 			}else{
-				this._index--;
+				this._index = 0;
 			}
 			this._loadImage();
-		}
-	},
-
-	_loadImage: function(){
-		// summary: Do the prep work before we can show another image
-		this._loadingAnim.play(1);
-	},
-
-	_prepNodes: function(){
-		// summary: A localized hook to accompany _loadImage
-		this._imageReady = false;
-		if(this.inGroup && this.inGroup[this._index]){
-			this.show({
-				href: this.inGroup[this._index].href,
-				title: this.inGroup[this._index].title
-			});
-		}else{
-			this.show({
-				title: this.errorMessage,
-				href: this.errorImg
-			});
-		}
-		
-	},
+		},
+
+		_prevImage: function(){
+			// summary: Load previous image in group
+			if(this.inGroup){
+				if(this._index == 0){
+					this._index = this.inGroup.length - 1;
+				}else{
+					this._index--;
+				}
+				this._loadImage();
+			}
+		},
+
+		_loadImage: function(){
+			// summary: Do the prep work before we can show another image
+			this._loadingAnim.play(1);
+		},
+
+		_prepNodes: function(){
+			// summary: A localized hook to accompany _loadImage
+			this._imageReady = false;
+			if(this.inGroup && this.inGroup[this._index]){
+				this.show({
+					href: this.inGroup[this._index].href,
+					title: this.inGroup[this._index].title
+				});
+			}else{
+				this.show({
+					title: this.errorMessage,
+					href: this.errorImg
+				});
+			}
 
-	_calcTitleSize: function(){
-		var sizes = dojo.map(dojo.query("> *", this.titleNode).position(), function(s){ return s.h; });
-		return { h: Math.max.apply(Math, sizes) };
-	},
-	
-	resizeTo: function(/* Object */size, forceTitle){
-		// summary: Resize our dialog container, and fire _showImage
-		
-		var adjustSize = dojo.boxModel == "border-box" ?
-			dojo._getBorderExtents(this.domNode).w : 0,
-			titleSize = forceTitle || this._calcTitleSize()
-		;
-		
-		this._lastTitleSize = titleSize;
-		
-		if(this.adjust &&
-			(size.h + titleSize.h + adjustSize + 80 > this._vp.h ||
-			 size.w + adjustSize + 60 > this._vp.w
-			)
-		){
-			this._lastSize = size;
-			size = this._scaleToFit(size);
-		}
-		this._currentSize = size;
-		
-		var _sizeAnim = dojox.fx.sizeTo({
-			node: this.containerNode,
-			duration: size.duration||this.duration,
-			width: size.w + adjustSize,
-			height: size.h + titleSize.h + adjustSize
-		});
-		this.connect(_sizeAnim, "onEnd", "_showImage");
-		_sizeAnim.play(15);
-	},
-
-	_scaleToFit: function(/* Object */size){
-		// summary: resize an image to fit within the bounds of the viewport
-		// size: Object
-		//		The 'size' object passed around for this image
-
-		var ns = {},   // New size
-			nvp = {
-				w: this._vp.w - 80,
-				h: this._vp.h - 60 - this._lastTitleSize.h
-			};	// New viewport
-
-		// Calculate aspect ratio
-		var viewportAspect = nvp.w / nvp.h,
-			imageAspect = size.w / size.h;
-
-		// Calculate new image size
-		if(imageAspect >= viewportAspect){
-			ns.h = nvp.w / imageAspect;
-			ns.w = nvp.w;
-		}else{
-			ns.w = imageAspect * nvp.h;
-			ns.h = nvp.h;
-		}
+		},
 
-		// we actually have to style this image, it's too big
-		this._wasStyled = true;
-		this._setImageSize(ns);
+		_calcTitleSize: function(){
+			var sizes = dojo.map(dojo.query("> *", this.titleNode).position(), function(s){ return s.h; });
+			return { h: Math.max.apply(Math, sizes) };
+		},
 
-		ns.duration = size.duration;
-		return ns; // Object
-	},
-	
-	_setImageSize: function(size){
-		// summary: Reset the image size to some actual size.
-		var s = this.imgNode;
-		s.height = size.h;
-		s.width = size.w;
-	},
-
-	// clobber inherited function, it is useless.
-	_size: function(){},
-	
-	_position: function(/* Event */e){
-		// summary: we want to know the viewport size any time it changes
-		this._vp = dojo.window.getBox();
-		this.inherited(arguments);
-		
-		// determine if we need to scale up or down, if at all.
-		if(e && e.type == "resize"){
-			if(this._wasStyled){
-				this._setImageSize(this._lastSize);
-				this.resizeTo(this._lastSize);
+		resizeTo: function(/* Object */size, forceTitle){
+			// summary: Resize our dialog container, and fire _showImage
+
+			var adjustSize = dojo.boxModel == "border-box" ?
+				dojo._getBorderExtents(this.domNode).w : 0,
+				titleSize = forceTitle || this._calcTitleSize()
+			;
+
+			this._lastTitleSize = titleSize;
+
+			if(this.adjust &&
+				(size.h + titleSize.h + adjustSize + 80 > this._vp.h ||
+				 size.w + adjustSize + 60 > this._vp.w
+				)
+			){
+				this._lastSize = size;
+				size = this._scaleToFit(size);
+			}
+			this._currentSize = size;
+
+			var _sizeAnim = dojox.fx.sizeTo({
+				node: this.containerNode,
+				duration: size.duration||this.duration,
+				width: size.w + adjustSize,
+				height: size.h + titleSize.h + adjustSize
+			});
+			this.connect(_sizeAnim, "onEnd", "_showImage");
+			_sizeAnim.play(15);
+		},
+
+		_scaleToFit: function(/* Object */size){
+			// summary: resize an image to fit within the bounds of the viewport
+			// size: Object
+			//		The 'size' object passed around for this image
+
+			var ns = {},   // New size
+				nvp = {
+					w: this._vp.w - 80,
+					h: this._vp.h - 60 - this._lastTitleSize.h
+				};	// New viewport
+
+			// Calculate aspect ratio
+			var viewportAspect = nvp.w / nvp.h,
+				imageAspect = size.w / size.h;
+
+			// Calculate new image size
+			if(imageAspect >= viewportAspect){
+				ns.h = nvp.w / imageAspect;
+				ns.w = nvp.w;
 			}else{
-				if(this.imgNode.height + 80 > this._vp.h || this.imgNode.width + 60 > this._vp.h){
-					this.resizeTo({
-						w: this.imgNode.width, h: this.imgNode.height
-					});
-				}
+				ns.w = imageAspect * nvp.h;
+				ns.h = nvp.h;
 			}
-		}
-	},
-
-	_showImage: function(){
-		// summary: Fade in the image, and fire showNav
-		this._showImageAnim.play(1);
-	},
-
-	_showNav: function(){
-		// 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);
-		}else{
-			this._showNavAnim.play(1);
-		}
-	},
-
-	hide: function(){
-		// summary: Hide the Master Lightbox
-		dojo.fadeOut({
-			node: this.titleNode,
-			duration: 200,
-			// #5112 - if you _don't_ change the .src, safari will
-			// _never_ fire onload for this image
-			onEnd: dojo.hitch(this, function(){
-				this.imgNode.src = this._blankGif;
-			})
-		}).play(5);
-
-		this.inherited(arguments);
-
-		this.inGroup = null;
-		this._index = null;
-	},
-
-	addImage: function(child, group){
-		// 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
-		//
-		// group: String?
-		//		attach to group of similar tag or null for individual image instance
-		var g = group;
-		if(!child.href){ return; }
-		if(g){
-			if(!this._groups[g]){
-				this._groups[g] = [];
+
+			// we actually have to style this image, it's too big
+			this._wasStyled = true;
+			this._setImageSize(ns);
+
+			ns.duration = size.duration;
+			return ns; // Object
+		},
+
+		_setImageSize: function(size){
+			// summary: Reset the image size to some actual size.
+			var s = this.imgNode;
+			s.height = size.h;
+			s.width = size.w;
+		},
+
+		// clobber inherited function, it is useless.
+		_size: function(){},
+
+		_position: function(/* Event */e){
+			// summary: we want to know the viewport size any time it changes
+			this._vp = dojo.window.getBox();
+			this.inherited(arguments);
+
+			// determine if we need to scale up or down, if at all.
+			if(e && e.type == "resize"){
+				if(this._wasStyled){
+					this._setImageSize(this._lastSize);
+					this.resizeTo(this._lastSize);
+				}else{
+					if(this.imgNode.height + 80 > this._vp.h || this.imgNode.width + 60 > this._vp.h){
+						this.resizeTo({
+							w: this.imgNode.width, h: this.imgNode.height
+						});
+					}
+				}
 			}
-			this._groups[g].push(child);
-		}else{ this._groups["XnoGroupX"].push(child); }
-	},
-
-	removeImage: function(/* Widget */child){
-		// 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
-		//		a .group member as well.
-		
-		var g = child.group || "XnoGroupX";
-		dojo.every(this._groups[g], function(item, i, ar){
-			if(item.href == child.href){
-				ar.splice(i, 1);
-				return false;
+		},
+
+		_showImage: function(){
+			// summary: Fade in the image, and fire showNav
+			this._showImageAnim.play(1);
+		},
+
+		_showNav: function(){
+			// 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);
+			}else{
+				this._showNavAnim.play(1);
 			}
-			return true;
-		});
-	},
-	
-	removeGroup: function(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
-		if(!this.open){ return; }
-
-		var dk = dojo.keys;
-		switch(e.charOrCode){
-			
-			case dk.ESCAPE:
-				this.hide();
-				break;
-
-			case dk.DOWN_ARROW:
-			case dk.RIGHT_ARROW:
-			case 78: // key "n"
-				this._nextImage();
-				break;
-
-			case dk.UP_ARROW:
-			case dk.LEFT_ARROW:
-			case 80: // key "p"
-				this._prevImage();
-				break;
-		}
-	},
-		
-	_makeAnims: function(){
-		// summary: make and cleanup animation and animation connections
-		
-		dojo.forEach(this._animConnects, dojo.disconnect);
-		this._animConnects = [];
-		this._showImageAnim = dojo.fadeIn({
-				node: this.imgNode,
-				duration: this.duration
+		},
+
+		hide: function(){
+			// summary: Hide the Master Lightbox
+			dojo.fadeOut({
+				node: this.titleNode,
+				duration: 200,
+				// #5112 - if you _don't_ change the .src, safari will
+				// _never_ fire onload for this image
+				onEnd: dojo.hitch(this, function(){
+					this.imgNode.src = this._blankGif;
+				})
+			}).play(5);
+
+			this.inherited(arguments);
+
+			this.inGroup = null;
+			this._index = null;
+		},
+
+		addImage: function(child, group){
+			// 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
+			//
+			// group: String?
+			//		attach to group of similar tag or null for individual image instance
+			var g = group;
+			if(!child.href){ return; }
+			if(g){
+				if(!this._groups[g]){
+					this._groups[g] = [];
+				}
+				this._groups[g].push(child);
+			}else{ this._groups["XnoGroupX"].push(child); }
+		},
+
+		removeImage: function(/* Widget */child){
+			// 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
+			//		a .group member as well.
+
+			var g = child.group || "XnoGroupX";
+			dojo.every(this._groups[g], function(item, i, ar){
+				if(item.href == child.href){
+					ar.splice(i, 1);
+					return false;
+				}
+				return true;
 			});
-		this._animConnects.push(dojo.connect(this._showImageAnim, "onEnd", this, "_showNav"));
-		this._loadingAnim = dojo.fx.combine([
-				dojo.fadeOut({ node:this.imgNode, duration:175 }),
-				dojo.fadeOut({ node:this.titleNode, duration:175 })
-			]);
-		this._animConnects.push(dojo.connect(this._loadingAnim, "onEnd", this, "_prepNodes"));
-		this._showNavAnim = dojo.fadeIn({ node: this.titleNode, duration:225 });
-	},
-	
-	onClick: function(groupData){
-		// summary: a stub function, called with the currently displayed image as the only argument
-	},
-	
-	_onImageClick: function(e){
-		if(e && e.target == this.imgNode){
-			this.onClick(this._lastGroup);
-			// also fire the onclick for the Lightbox widget which triggered, if you
-			// aren't working directly with the LBDialog
-			if(this._lastGroup.declaredClass){
-				this._lastGroup.onClick(this._lastGroup);
+		},
+
+		removeGroup: function(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
+			if(!this.open){ return; }
+
+			var dk = dojo.keys;
+			switch(e.charOrCode){
+
+				case dk.ESCAPE:
+					this.hide();
+					break;
+
+				case dk.DOWN_ARROW:
+				case dk.RIGHT_ARROW:
+				case 78: // key "n"
+					this._nextImage();
+					break;
+
+				case dk.UP_ARROW:
+				case dk.LEFT_ARROW:
+				case 80: // key "p"
+					this._prevImage();
+					break;
+			}
+		},
+
+		_makeAnims: function(){
+			// summary: make and cleanup animation and animation connections
+
+			dojo.forEach(this._animConnects, dojo.disconnect);
+			this._animConnects = [];
+			this._showImageAnim = dojo.fadeIn({
+					node: this.imgNode,
+					duration: this.duration
+				});
+			this._animConnects.push(dojo.connect(this._showImageAnim, "onEnd", this, "_showNav"));
+			this._loadingAnim = dojo.fx.combine([
+					dojo.fadeOut({ node:this.imgNode, duration:175 }),
+					dojo.fadeOut({ node:this.titleNode, duration:175 })
+				]);
+			this._animConnects.push(dojo.connect(this._loadingAnim, "onEnd", this, "_prepNodes"));
+			this._showNavAnim = dojo.fadeIn({ node: this.titleNode, duration:225 });
+		},
+
+		onClick: function(groupData){
+			// summary: a stub function, called with the currently displayed image as the only argument
+		},
+
+		_onImageClick: function(e){
+			if(e && e.target == this.imgNode){
+				this.onClick(this._lastGroup);
+				// also fire the onclick for the Lightbox widget which triggered, if you
+				// aren't working directly with the LBDialog
+				if(this._lastGroup.declaredClass){
+					this._lastGroup.onClick(this._lastGroup);
+				}
 			}
 		}
-	}
+	});
+	
+
+	return dojox.image.Lightbox;
+
 });
+
diff --git a/dojox/image/LightboxNano.js b/dojox/image/LightboxNano.js
index c45212b..e1e066e 100644
--- a/dojox/image/LightboxNano.js
+++ b/dojox/image/LightboxNano.js
@@ -1,4 +1,4 @@
-define("dojox/image/LightboxNano", ["dojo", "dojo/fx"], function(dojo, fx) {
+define(["dojo", "dojo/fx"], function(dojo, fx) {
 
 	var abs = "absolute",
 		vis = "visibility",
@@ -10,7 +10,7 @@ define("dojox/image/LightboxNano", ["dojo", "dojo/fx"], function(dojo, fx) {
 			}
 	;
 
-	dojo.declare("dojox.image.LightboxNano", null, {
+	return dojo.declare("dojox.image.LightboxNano", null, {
 		//	summary:
 		//		A simple "nano" version of the lightbox.
 		//
@@ -306,5 +306,4 @@ define("dojox/image/LightboxNano", ["dojo", "dojo/fx"], function(dojo, fx) {
 		}
 	});
 
-	return dojox.image.LightboxNano;
 });
diff --git a/dojox/image/Magnifier.js b/dojox/image/Magnifier.js
index c511a53..ddccafb 100644
--- a/dojox/image/Magnifier.js
+++ b/dojox/image/Magnifier.js
@@ -1,73 +1,70 @@
-dojo.provide("dojox.image.Magnifier");
+define(["dojo/_base/declare", "dojo/dom-construct", "dojo/_base/window", "dojox/gfx", "dojox/gfx/canvas", "./MagnifierLite"], function(declare, construct, window, gfx, canvas, MagnifierLite){
+	
+	return declare("dojox.image.Magnifier", MagnifierLite, {
+		// summary:
+		//		Adds magnification on a portion of an image element, using `dojox.gfx`
+		//
+		// 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).
+		//
+		//		over-ride the _createGlass method to create your custom surface,
+		//		being sure to create an img node on that surface.
 
-dojo.require("dojox.gfx");
-dojo.require("dojox.image.MagnifierLite");
+		_createGlass: function(){
+			// summary: create the glassNode, and an img on a dojox.gfx surface
 
-dojo.declare("dojox.image.Magnifier",
-	dojox.image.MagnifierLite,{
-	// summary:
-	//		Adds magnification on a portion of an image element, using `dojox.gfx`
-	//
-	// 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).
-	//
-	//		over-ride the _createGlass method to create your custom surface,
-	//		being sure to create an img node on that surface.
+			// images are hard to make into workable templates, so just add outer overlay
+			// and skip using dijit._Templated
+			this.glassNode = construct.create('div', {
+				style: {
+					height: this.glassSize + "px",
+					width: this.glassSize + "px"
+				},
+				className: "glassNode"
+			}, window.body());
+			this.surfaceNode = construct.create('div', null, this.glassNode);
 
-	_createGlass: function(){
-		// summary: create the glassNode, and an img on a dojox.gfx surface
+			gfx.switchTo('canvas');
+			this.surface = canvas.createSurface(this.surfaceNode, this.glassSize, this.glassSize);
+			this.img = this.surface.createImage({
+			   src: this.domNode.src,
+			   width: this._zoomSize.w,
+			   height: this._zoomSize.h
+			});
 
-		// images are hard to make into workable templates, so just add outer overlay
-		// and skip using dijit._Templated
-		this.glassNode = dojo.create('div', {
-			style:{
-				height: this.glassSize + "px",
-				width: this.glassSize + "px"
-			},
-			"className":"glassNode"
-		}, dojo.body());
-		this.surfaceNode = dojo.create('div', null, this.glassNode);
+		},
 
-		this.surface = dojox.gfx.createSurface(this.surfaceNode, this.glassSize, this.glassSize);
-		this.img = this.surface.createImage({
-		   src: this.domNode.src,
-		   width: this._zoomSize.w,
-		   height: this._zoomSize.h
-		});
+		_placeGlass: function(e){
+			// 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,
+				yMax = this.offset.y + this.offset.h + 2
+			;
 
-	},
+			// with svg, our mouseout connection to the image surface doesn't
+			// fire, so we'r have to manually calculate offsets
+			if(x < this.offset.x || y < this.offset.y || x > xMax || y > yMax){
+				this._hideGlass();
+			}else{
+				this.inherited(arguments);
+			}
+		},
 
-	_placeGlass: function(e){
-		// 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,
-			yMax = this.offset.y + this.offset.h + 2
-		;
-		
-		// with svg, our mouseout connection to the image surface doesn't
-		// fire, so we'r have to manually calculate offsets
-		if(x < this.offset.x || y < this.offset.y || x > xMax || y > yMax){
-			this._hideGlass();
-		}else{
-			this.inherited(arguments);
-		}
-	},
-
-	_setImage: function(e){
-		// summary: set the image's offset in the clipping window relative to the mouse position
+		_setImage: function(e){
+			// summary: set the image's offset in the clipping window relative to the mouse position
 
-		var xOff = (e.pageX - this.offset.l) / this.offset.w,
-			yOff = (e.pageY - this.offset.t) / this.offset.h,
-			x = (this._zoomSize.w * xOff * -1)+(this.glassSize*xOff),
-			y = (this._zoomSize.h * yOff * -1)+(this.glassSize*yOff)
-		;
-		// set the image offset
-		this.img.setShape({ x: x, y: y });
-
-	}
+			var xOff = (e.pageX - this.offset.x) / this.offset.w,
+				yOff = (e.pageY - this.offset.y) / this.offset.h,
+				x = (this._zoomSize.w * xOff * -1)+(this.glassSize*xOff),
+				y = (this._zoomSize.h * yOff * -1)+(this.glassSize*yOff)
+			;
+			// set the image offset
+			this.img.setShape({ x: x, y: y });
 
+		}
+	});	
 });
\ No newline at end of file
diff --git a/dojox/image/MagnifierLite.js b/dojox/image/MagnifierLite.js
index ff7899d..a9fe316 100644
--- a/dojox/image/MagnifierLite.js
+++ b/dojox/image/MagnifierLite.js
@@ -1,130 +1,125 @@
-dojo.provide("dojox.image.MagnifierLite");
-dojo.experimental("dojox.image.MagnifierLite");
-
-dojo.require("dijit._Widget");
-
-dojo.declare("dojox.image.MagnifierLite", dijit._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
-	//		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
-	glassSize: 125,
-
-	// scale: Decimal
-	// 		the multiplier of the Mangification.
-	scale: 6,
-
-	postCreate: function(){
-		this.inherited(arguments);
-		
-		// images are hard to make into workable templates, so just add outer overlay
-		// and skip using dijit._Templated
-		this._adjustScale();
-		this._createGlass();
-		
-		this.connect(this.domNode,"onmouseenter","_showGlass");
-		this.connect(this.glassNode,"onmousemove","_placeGlass");
-		this.connect(this.img,"onmouseout","_hideGlass");
-
-		// when position of domNode changes, _adjustScale needs to run.
-		// window.resize isn't it always, FIXME:
-		this.connect(window,"onresize","_adjustScale");
-		
-	},
-
-	_createGlass: function(){
-		// summary: make img and glassNode elements as children of the body
-
-		var node = this.glassNode = dojo.create('div', {
-			style:{
-				height: this.glassSize + "px",
-				width: this.glassSize + "px"
-			},
-			className:"glassNode"
-		}, dojo.body());
-		
-		this.surfaceNode = node.appendChild(dojo.create('div'));
-
-		this.img = dojo.place(dojo.clone(this.domNode), node);
-		// float the image around inside the .glassNode
-		dojo.style(this.img, {
-			position: "relative",
-			top: 0, left: 0,
-			width: this._zoomSize.w + "px",
-			height: this._zoomSize.h + "px"
-		});
-
-	},
-	
-	_adjustScale: function(){
-		// summary: update the calculations should this.scale change
-
-		this.offset = dojo.coords(this.domNode, true);
-		this._imageSize = { w: this.offset.w, h:this.offset.h };
-		this._zoomSize = {
-			w: this._imageSize.w * this.scale,
-			h: this._imageSize.h * this.scale
-		};
-	},
-	
-	_showGlass: function(e){
-		// summary: show the overlay
-		this._placeGlass(e);
-		dojo.style(this.glassNode, {
-			visibility: "visible",
-			display:""
-		});
-		
-	},
-	
-	_hideGlass: function(e){
-		// summary: hide the overlay
-		dojo.style(this.glassNode, {
-			visibility: "hidden",
-			display:"none"
-		});
-	},
-	
-	_placeGlass: function(e){
-		// summary: position the overlay centered under the cursor
-
-		this._setImage(e);
-		var sub = Math.floor(this.glassSize / 2);
-		dojo.style(this.glassNode,{
-			top: Math.floor(e.pageY - sub) + "px",
-			left:Math.floor(e.pageX - sub) + "px"
-		});
-		
-	},
-
-	_setImage: function(e){
-		// summary: set the image's offset in the clipping window relative to the mouse position
-
-		var xOff = (e.pageX - this.offset.l) / this.offset.w,
-			yOff = (e.pageY - this.offset.t) / this.offset.h,
-			x = (this._zoomSize.w * xOff * -1) + (this.glassSize * xOff),
-			y = (this._zoomSize.h * yOff * -1) + (this.glassSize * yOff);
-
-		dojo.style(this.img, {
-			top: y + "px",
-			left: x + "px"
-		});
-
-	},
-	
-	destroy: function(finalize){
-		dojo.destroy(this.glassNode);
-		this.inherited(arguments);
-	}
+define(["dojo/_base/kernel", "dojo/_base/declare", "dijit/_Widget", "dojo/dom-construct", "dojo/dom-style", "dojo/dom-geometry", "dojo/_base/window", "dojo/_base/lang"], function(kernel, declare, _Widget, construct, style, geometry, window, lang){
 
-});
\ No newline at end of file
+	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
+		//		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
+		glassSize: 125,
+
+		// scale: Decimal
+		// 		the multiplier of the Mangification.
+		scale: 6,
+
+		postCreate: function(){
+			this.inherited(arguments);
+
+			// images are hard to make into workable templates, so just add outer overlay
+			// and skip using dijit._Templated
+			this._adjustScale();
+			this._createGlass();
+
+			this.connect(this.domNode,"onmouseenter","_showGlass");
+			this.connect(this.glassNode,"onmousemove","_placeGlass");
+			this.connect(this.img,"onmouseout","_hideGlass");
+
+			// when position of domNode changes, _adjustScale needs to run.
+			// window.resize isn't it always, FIXME:
+			this.connect(window,"onresize","_adjustScale");
+		},
+
+		_createGlass: function(){
+			// summary: make img and glassNode elements as children of the body
+
+			var node = this.glassNode = construct.create('div', {
+				style: {
+					height: this.glassSize + "px",
+					width: this.glassSize + "px"
+				},
+				className: "glassNode"
+			}, window.body());
+
+			this.surfaceNode = node.appendChild(construct.create('div'));
+
+			this.img = construct.place(lang.clone(this.domNode), node);
+			// float the image around inside the .glassNode
+			style.set(this.img, {
+				position: "relative",
+				top: 0, left: 0,
+				width: this._zoomSize.w + "px",
+				height: this._zoomSize.h + "px"
+			});
+		},
+
+		_adjustScale: function(){
+			// summary: update the calculations should this.scale change
+
+			this.offset = geometry.position(this.domNode, true);
+			console.dir(this.offset);
+			this._imageSize = { w: this.offset.w, h:this.offset.h };
+			this._zoomSize = {
+				w: this._imageSize.w * this.scale,
+				h: this._imageSize.h * this.scale
+			};
+		},
+
+		_showGlass: function(e){
+			// summary: show the overlay
+			this._placeGlass(e);
+			style.set(this.glassNode, {
+				visibility: "visible",
+				display:""
+			});
+		},
+
+		_hideGlass: function(e){
+			// summary: hide the overlay
+			style.set(this.glassNode, {
+				visibility: "hidden",
+				display:"none"
+			});
+		},
+
+		_placeGlass: function(e){
+			// summary: position the overlay centered under the cursor
+
+			this._setImage(e);
+			var sub = Math.floor(this.glassSize / 2);
+			style.set(this.glassNode,{
+				top: Math.floor(e.pageY - sub) + "px",
+				left:Math.floor(e.pageX - sub) + "px"
+			});
+		},
+
+		_setImage: function(e){
+			// 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,
+				x = (this._zoomSize.w * xOff * -1) + (this.glassSize * xOff),
+				y = (this._zoomSize.h * yOff * -1) + (this.glassSize * yOff);
+
+			style.set(this.img, {
+				top: y + "px",
+				left: x + "px"
+			});
+		},
+
+		destroy: function(finalize){
+			construct.destroy(this.glassNode);
+			this.inherited(arguments);
+		}
+
+	});
+});
diff --git a/dojox/image/SlideShow.js b/dojox/image/SlideShow.js
index 4521011..838ce38 100644
--- a/dojox/image/SlideShow.js
+++ b/dojox/image/SlideShow.js
@@ -142,6 +142,7 @@ dojo.declare("dojox.image.SlideShow",
 		
 		this._loadImage(0, dojo.hitch(this, "showImage", 0));
 		this._calcNavDimensions();
+		dojo.style(this.navNode, "opacity", 0);
 	},
 
 	setDataStore: function(dataStore, request, /*optional*/paramNames){
@@ -513,6 +514,7 @@ dojo.declare("dojox.image.SlideShow",
 	_prev: function(){
 		// summary:
 		//		Show the previous image.
+
 		// FIXME: either pull code from showNext/prev, or call it here
 		if(this.imageIndex < 1){ return; }
 		this.showImage(this.imageIndex - 1);
@@ -541,15 +543,12 @@ dojo.declare("dojox.image.SlideShow",
 		//Place the navigation controls far off screen
 		dojo.style(this.navNode, "top", "-10000px");
 		
-		//Make the navigation controls visible
-		dojo._setOpacity(this.navNode, 1);
+		dojo.style(this.navPlay, 'marginLeft', 0);
 		
 		this.navPlay._size = dojo.marginBox(this.navPlay);
 		this.navPrev._size = dojo.marginBox(this.navPrev);
 		this.navNext._size = dojo.marginBox(this.navNext);
 		
-		dojo._setOpacity(this.navNode, 0);
-		
 		dojo.style(this.navNode, {"position": "", top: ""});
 	},
 
@@ -605,9 +604,13 @@ dojo.declare("dojox.image.SlideShow",
 		//		If true, the navigation controls are repositioned even if they are
 		//		currently visible.
 		if(this._navShowing && !force){return;}
+		this._calcNavDimensions();
 		dojo.style(this.navNode, "marginTop", "0px");
 		
+		
 		var navPlayPos = dojo.style(this.navNode, "width")/2 - this.navPlay._size.w/2 - this.navPrev._size.w;
+		console.log('navPlayPos = ' + dojo.style(this.navNode, "width")/2 + ' - ' + this.navPlay._size.w + '/2 - '
+				+ this.navPrev._size.w);
 		
 		dojo.style(this.navPlay, "marginLeft", navPlayPos + "px");
 		var wrapperSize = dojo.marginBox(this.outerNode);
@@ -662,13 +665,11 @@ dojo.declare("dojox.image.SlideShow",
 		if(typeof(dojo) == "undefined"){ return false; }
 		element = dojo.byId(element);
 		var m = { x: e.pageX, y: e.pageY };
-		var bb = dojo._getBorderBox(element);
-		var absl = dojo.coords(element, true);
-		var left = absl.x;
+		var bb = dojo.position(element, true);
 
-		return (m.x >= left
-			&& m.x <= (left + bb.w)
-			&& m.y >= absl.y
+		return (m.x >= bb.x
+			&& m.x <= (bb.x + bb.w)
+			&& m.y >= bb.y
 			&& m.y <= (top + bb.h)
 		);	//	boolean
 	}
diff --git a/dojox/image/ThumbnailPicker.js b/dojox/image/ThumbnailPicker.js
index 3682b42..fad42fc 100644
--- a/dojox/image/ThumbnailPicker.js
+++ b/dojox/image/ThumbnailPicker.js
@@ -14,6 +14,8 @@ dojo.require("dojo.fx");
 dojo.require("dijit._Widget");
 dojo.require("dijit._Templated");
 
+// FIXME: use CSS for size, thumbHeight, and thumbWidth
+
 dojo.declare("dojox.image.ThumbnailPicker",
 	[dijit._Widget, dijit._Templated],
 	{
@@ -29,15 +31,15 @@ dojo.declare("dojox.image.ThumbnailPicker",
 
 	// size: Number
 	// Width or height in pixels, depending if horizontal or vertical.
-	size: 500, //FIXME: use CSS?
+	size: 500, 
 
 	// thumbHeight: Number
 	// Default height of a thumbnail image
-	thumbHeight: 75, // FIXME: use CSS?
+	thumbHeight: 75, 
 
 	// thumbWidth: Number
 	// Default width of an image
-	thumbWidth: 100, // FIXME: use CSS?
+	thumbWidth: 100, 
 
 	// useLoadNotifier: Boolean
 	// Setting useLoadNotifier to true makes a colored DIV appear under each
diff --git a/dojox/image/_base.js b/dojox/image/_base.js
index 5322cf7..8c1c0c7 100644
--- a/dojox/image/_base.js
+++ b/dojox/image/_base.js
@@ -1,7 +1,7 @@
-dojo.provide("dojox.image._base");
-
-// summary: Core Image-related functionality
-;(function(d){
+define(["dojo", "dojox"], function(dojo, dojox){
+	
+	dojo.getObject("image", true, dojox);
+	var d = dojo;
 	
 	var cacheNode;
 	dojox.image.preload = function(/* Array */urls){
@@ -37,13 +37,14 @@ dojo.provide("dojox.image._base");
 	};
 	
 	/*=====
-		dojo.mixin(djConfig, {
-			// preloadImages: Array?
-			//		An optional array of urls to preload immediately upon
-			//		page load. Uses `dojox.image`, and is unused if not present.
-			preloadImages: []
-		})
+	dojo.mixin(djConfig, {
+		// preloadImages: Array?
+		//		An optional array of urls to preload immediately upon
+		//		page load. Uses `dojox.image`, and is unused if not present.
+		preloadImages: []
+	});
 	=====*/
+	
 	if(d.config.preloadImages){
 		d.addOnLoad(function(){
 			dojox.image.preload(d.config.preloadImages);
@@ -111,4 +112,4 @@ dojo.provide("dojox.image._base");
 //
 //	});
 		
-})(dojo);
\ No newline at end of file
+});
\ No newline at end of file
diff --git a/dojox/image/tests/test_Badge.html b/dojox/image/tests/test_Badge.html
index f550693..3c4f4ef 100644
--- a/dojox/image/tests/test_Badge.html
+++ b/dojox/image/tests/test_Badge.html
@@ -1,11 +1,11 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-        "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+    
 	<title>dojox.image.Badge Tests | The Dojo Toolkit</title>
 
 	<!-- required: a default theme file, and project css: -->
-	<link rel="stylesheet" id="themeStyles" href="../../../dijit/themes/tundra/tundra.css" />
+	<link rel="stylesheet" id="themeStyles" href="../../../dijit/themes/claro/claro.css" />
 	<link rel="stylesheet" href="../resources/image.css" />
 	
 	<style type="text/css">
@@ -35,16 +35,12 @@
 	</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" djConfig="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="../Badge.js"></script>
-	<script type="text/javascript">
-		dojo.require("dojox.image.Badge"); 
-		dojo.require("dojox.data.FlickrStore");
+	<script>
+    	require(["dojo/parser", "dojox/image/Badge", "dojox/data/FlickrStore", "dojo/domReady!"]);
 	</script>
 
 	<!--script type="text/javascript">
@@ -85,7 +81,7 @@
 
 
 </head>
-<body class="tundra">
+<body class="claro">
 
 	<div style="padding:20px;">
 		
@@ -96,7 +92,7 @@
 				<img src="images/square.jpg" class="thing" alt="thingr" />
 				<img src="images/square.jpg" class="thing" alt="thingr" />
 				<img src="images/square.jpg" class="thing" alt="thingr" />
-				<img src="images/square.jpg" class="thing" alt="thingr" />			
+				<img src="images/square.jpg" class="thing" alt="thingr" />
 			</div>
 		
 			<h3>[4x3]</h3>	
diff --git a/dojox/image/tests/test_FlickrBadge.html b/dojox/image/tests/test_FlickrBadge.html
index 2b4bb27..4de7f36 100644
--- a/dojox/image/tests/test_FlickrBadge.html
+++ b/dojox/image/tests/test_FlickrBadge.html
@@ -1,11 +1,10 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-        "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
 	<title>dojox.image.FlickrBadge Tests | The Dojo Toolkit</title>
 
 	<!-- required: a default theme file, and project css: -->
-	<link rel="stylesheet" id="themeStyles" href="../../../dijit/themes/tundra/tundra.css" />
+	<link rel="stylesheet" id="themeStyles" href="../../../dijit/themes/claro/claro.css" />
 	<link rel="stylesheet" href="../resources/image.css" />
 	
 	<style type="text/css">
@@ -39,20 +38,17 @@
 
 	<!-- 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="../Badge.js"></script>
 	<script type="text/javascript">
-		dojo.require("dojox.image.FlickrBadge"); 
+	    require(["dojo/parser", "dojox/image/FlickrBadge"]);
 	</script>
 
 </head>
-<body class="tundra">
+<body class="claro">
 
 	<div style="padding:20px;">
 		<h2>FlickrBadge: Dylan's photos</h2>
 		<div class="noBorderWrapper">
-			<div dojoType="dojox.image.FlickrBadge" rows="6" cols="6" username="dylans"></div>
+			<div data-dojo-type="dojox.image.FlickrBadge" data-dojo-props="rows:6, cols:6, username:'dylans'"></div>
 		</div>
 
 		<h2>FlickrBadge: Dylan's tagged photos ('dojotoolkit' and 'italy')</h2>
diff --git a/dojox/image/tests/test_Gallery.html b/dojox/image/tests/test_Gallery.html
index dfea0fc..5a6aeb5 100644
--- a/dojox/image/tests/test_Gallery.html
+++ b/dojox/image/tests/test_Gallery.html
@@ -13,26 +13,19 @@
 	</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" djConfig=" parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
-	
-	<!-- debugging includes -->
-	<script type="text/javascript" src="../ThumbnailPicker.js"></script>
-	<script type="text/javascript" src="../SlideShow.js"></script>
-	<script type="text/javascript" src="../Gallery.js"></script>
-	<script type="text/javascript" src="../../../dojo/data/util/simpleFetch.js"></script>
-	<script type="text/javascript" src="../../data/FlickrStore.js"></script>
-	<script type="text/javascript" src="../../data/FlickrRestStore.js"></script>
-	<script type="text/javascript" src="../../../dojo/data/ItemFileReadStore.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dojox.image.Gallery");
-		dojo.require("dojox.data.FlickrRestStore");
+		dojo.require('dojo.data.ItemFileReadStore');
+		dojo.require('dojox.image.Gallery');
+		dojo.require('dojox.data.FlickrRestStore');
 		dojo.require("dojo.parser");	// find widgets
-
-		dojo.addOnLoad(function(){
+		
+		dojo.ready(function(){
+			console.log('onload');
 			var flickrRestStore = new dojox.data.FlickrRestStore();
 			var req = {
 				query: {
@@ -52,12 +45,11 @@
 			setTimeout(function(){
 				dijit.byId('gallery1').setDataStore(flickrRestStore, req);				
 			},250);
-/*
+
 			dijit.byId('gallery2').setDataStore(imageItemStore,{ count:20 },{
 				imageThumbAttr: "thumb",
 				imageLargeAttr: "large"
 			});
-*/
 		});
 	</script>
 </head>
@@ -67,10 +59,10 @@
 	<h2>From FlickrRestStore:</h2>
 	<div id="gallery1" dojoType="dojox.image.Gallery" imageWidth="700" imageHeight="500"></div>
 
-<!--
 	<h2>From ItemFileReadStore:</h2>
+	
+	<div jsId="imageItemStore" dojoType="dojo.data.ItemFileReadStore" url="images.json"></div>
 	<div id="gallery2" dojoType="dojox.image.Gallery"></div>
--->
 
 </body>
 </html>
diff --git a/dojox/image/tests/test_Lightbox.html b/dojox/image/tests/test_Lightbox.html
index bbcd34c..a40d755 100644
--- a/dojox/image/tests/test_Lightbox.html
+++ b/dojox/image/tests/test_Lightbox.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.image.Lightbox Tests | The Dojo Toolkit</title>
@@ -28,13 +27,10 @@
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 
 	<!-- for debugging: -->
-	<script type="text/javascript" src="../Lightbox.js"></script>
 	<script type="text/javascript">
-		dojo.require("dijit.form.Button");
-		dojo.require("dojox.image.Lightbox"); 
-		dojo.require("dojox.data.FlickrStore");
-		dojo.ready(function(){
-			// sample with super-rich text content (no widgets or undelegated events please).
+	    require(["dojo", "dijit/form/Button", "dojox/image/Lightbox", "dojox/data/FlickrStore", "dojo/parser", "dojo/domReady!"], function(){
+	        
+	    	// sample with super-rich text content (no widgets or undelegated events please).
 			
 			var title = dojo.byId("customExample").innerHTML;
 			dojo.empty("customExample");
@@ -80,7 +76,7 @@
 			
 			// and example of onClick for the image (to hide the lightbox);
 			var clb = new dojox.image.Lightbox({
-				title:"fun fun fun",
+				title:"fun fun fun fun",
 				href:"images/chris1_lg.jpg",
 				onClick: function(){
 					this.hide();
@@ -97,7 +93,7 @@
 
 			// and example of onClick for the image (to toggle between large/small);
 			var clb2 = new dojox.image.Lightbox({
-				title:"fun fun fun",
+				title:"fun fun fun fun", // friday, friday!
 				href:"images/chris1_sm.jpg",
 				onClick: function(info){
 					
@@ -140,10 +136,9 @@
 				var lbd = dijit.byId("dojoxLightboxDialog");
 				lbd.removeGroup("group3");
 			});
-		})
-	</script>
+		
+		});
 
-	<script type="text/javascript">
 		// programatic flickrstore implementation [basic]
 		function onComplete(items,request){
 			if(items.length > 0){
@@ -174,10 +169,9 @@
 			};
 			flickrStore.fetch(flickrRequest);
 		}
-		dojo.addOnLoad(init);
+		dojo.ready(init);
 	</script>
 
-
 </head>
 <body class="claro">
 
diff --git a/dojox/image/tests/test_Magnifier.html b/dojox/image/tests/test_Magnifier.html
index fef1ddd..1eb33a0 100644
--- a/dojox/image/tests/test_Magnifier.html
+++ b/dojox/image/tests/test_Magnifier.html
@@ -1,4 +1,5 @@
-<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<!DOCTYPE html>
+<html>
 <head>
     <title>Testing image</title>
     <style type="text/css">
@@ -12,14 +13,9 @@
 		#testImage { border:2px solid #000; }
 		
     </style>
-    <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad:true"></script>
-	<!-- for debugging -->
-	<script type="text/javascript" src="../MagnifierLite.js"></script>
-	<script type="text/javascript" src="../Magnifier.js"></script>
-
+    <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="async: true, isDebug: true, parseOnLoad:true"></script>
     <script type="text/javascript">
-		dojo.require("dojox.image.Magnifier");
-		dojo.require("dijit.form.Button");		
+        require(["dojox/image/Magnifier", "dijit/form/Button", "dojo/parser"]);
 	</script>
 
 </head>
diff --git a/dojox/image/tests/test_MagnifierLite.html b/dojox/image/tests/test_MagnifierLite.html
index a6edc56..5006eab 100644
--- a/dojox/image/tests/test_MagnifierLite.html
+++ b/dojox/image/tests/test_MagnifierLite.html
@@ -1,7 +1,8 @@
-<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<!DOCTYPE html>
+<html>
 <head>
-    <title>Testing image</title>
-    <style type="text/css">
+	<title>Testing image</title>
+	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/tests/css/dijitTests.css";
 		@import "../../../dijit/themes/tundra/tundra.css";
@@ -10,19 +11,17 @@
 		p { padding:20px; border:1px solid #ededed; }
 		#testImage { border:2px solid #000; }
 		
-    </style>
+	</style>
 
-    <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad:true"></script>
-	<script type="text/javascript" src="../MagnifierLite.js"></script>
-    <script type="text/javascript">
-		dojo.require("dojox.image.MagnifierLite");
-		dojo.require("dijit.form.Button");		
+	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="async: true, isDebug: true, parseOnLoad:true"></script>
+	<script type="text/javascript">
+		require(["dojox/image/MagnifierLite", "dijit/form/Button", "dojo/parser"]);
 	</script>
 
 </head>
 <body class="tundra">
 
-    <h1 class="testTitle">dojox.image.MagnifierLite test page</h1>
+	<h1 class="testTitle">dojox.image.MagnifierLite test page</h1>
 
 		<p>They are just images. It's entirely unobtrusive to add magnification to an image, and style it accordingly.</p>
 
diff --git a/dojox/image/tests/test_SlideShow.html b/dojox/image/tests/test_SlideShow.html
index d1ac2b2..1a845e6 100644
--- a/dojox/image/tests/test_SlideShow.html
+++ b/dojox/image/tests/test_SlideShow.html
@@ -18,15 +18,11 @@
 	<!-- 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="../SlideShow.js"></script>
-	<script type="text/javascript" src="../../../dojo/data/ItemFileReadStore.js"></script>	
-	<script type="text/javascript" src="../../data/FlickrRestStore.js"></script>	
 
 	<script type="text/javascript">
-		// dojo.require("dojox.image.SlideShow");
-		// dojo.require("dojox.data.FlickrRestStore");
-		// dojo.require("dojo.data.ItemFileReadStore"); 
+		dojo.require("dojox.image.SlideShow");
+		dojo.require("dojox.data.FlickrRestStore");
+		dojo.require("dojo.data.ItemFileReadStore"); 
 		dojo.require("dojo.parser");	// find widgets		
 		
 		dojo.addOnLoad(function(){
diff --git a/dojox/io/OAuth.js b/dojox/io/OAuth.js
index ebad428..45694d4 100644
--- a/dojox/io/OAuth.js
+++ b/dojox/io/OAuth.js
@@ -1,5 +1,12 @@
-dojo.provide("dojox.io.OAuth");
-dojo.require("dojox.encoding.digests.SHA1");
+define([
+	"dojo/_base/kernel", // dojo
+	"dojo/_base/lang", // mixin
+	"dojo/_base/array", // isArray, map
+	"dojo/_base/xhr", // formToObject, queryToObject, xhr
+	"dojo/dom", // byId
+	"dojox/encoding/digests/SHA1" // SHA1
+], function(dojo, lang, array, xhr, dom, SHA1){
+dojo.getObject("io.OAuth", true, dojox);
 
 dojox.io.OAuth = new (function(){
 	//	summary:
@@ -20,7 +27,7 @@ dojox.io.OAuth = new (function(){
 	//		This object was developed against the Netflix API (OAuth-based service); see
 	//		http://developer.netflix.com for more details.
 	var encode = this.encode = function(s){
-		if(!s){ return ""; }
+		if(!("" + s).length){ return ""; }
 		return encodeURIComponent(s)
 			.replace(/\!/g, "%21")
 			.replace(/\*/g, "%2A")
@@ -101,7 +108,7 @@ dojox.io.OAuth = new (function(){
 			return key;
 		} else {
 			//	assume SHA1 HMAC
-			return dojox.encoding.digests.SHA1._hmac(data, key);
+			return SHA1._hmac(data, key);
 		}
 	}
 
@@ -196,7 +203,7 @@ dojox.io.OAuth = new (function(){
 
 		//	encode.
 		var s = dojo.map(a, function(item){
-			return encode(item[0]) + "=" + encode(item[1]||"");
+			return encode(item[0]) + "=" + encode((""+item[1]).length ? item[1] : "");
 		}).join("&");
 
 		var baseString = method.toUpperCase()
@@ -277,7 +284,7 @@ dojox.io.OAuth = new (function(){
 		 *	|	});
 		 */
 		sign(method, args, oaa);
-		return dojo.xhr(method, args, hasBody);
+		return xhr(method, args, hasBody);
 	};
 
 	this.xhrGet = function(/* dojo.__XhrArgs */args, /* dojox.io.OAuth.__OAuthArgs*/ oaa){
@@ -293,3 +300,7 @@ dojox.io.OAuth = new (function(){
 		return this.xhr("DELETE", args, oaa);
 	};
 })();
+
+return dojox.io.OAuth;
+
+});
diff --git a/dojox/io/httpParse.js b/dojox/io/httpParse.js
index 0b3fd2a..d19f37a 100644
--- a/dojox/io/httpParse.js
+++ b/dojox/io/httpParse.js
@@ -1,4 +1,6 @@
-dojo.provide("dojox.io.httpParse");
+define(["dojo/_base/kernel"], function(dojo){
+dojo.getObject("io.httpParse", true, dojox);
+
 dojox.io.httpParse = function(/*String*/httpStream, /*String?*/topHeaders,/*Boolean?*/ partial){
 	// summary:
 	//		Parses an HTTP stream for a message.
@@ -72,4 +74,8 @@ dojox.io.httpParse = function(/*String*/httpStream, /*String?*/topHeaders,/*Bool
 		xhr._lastIndex = streamLength - httpStream.length; // need to pick up from where we left on streaming connections
 	}while(httpStream);
 	return xhrs;
-}
\ No newline at end of file
+};
+
+return dojox.io.httpParse;
+
+});
diff --git a/dojox/io/proxy/tests/xip.html b/dojox/io/proxy/tests/xip.html
index 5a5ba5f..1471cdd 100644
--- a/dojox/io/proxy/tests/xip.html
+++ b/dojox/io/proxy/tests/xip.html
@@ -11,41 +11,39 @@
 
 	<script type="text/javascript" src="../../../../dojo/dojo.js"
 		djConfig="isDebug:true"></script>
-	<script type="text/javascript" src="../xip.js"></script>
 	<script type="text/javascript">
-		dojo.require("dojox.io.proxy.xip");
-
-		function testXmlGet(){
-/*
-			//Normal xhrGet call.
-			dojo.xhrGet({
-				url: "frag.xml",
-				handleAs: "xml",
-				load: function(result, ioArgs){
-					var foo = result.getElementsByTagName("foo").item(0);
-
-					dojo.byId("xmlGetOut").innerHTML = "Success: First foobar value is: " + foo.firstChild.nodeValue;
-				}
-			});
-*/
-
-			//xip xhrGet call.
-			dojo.xhrGet({
-				iframeProxyUrl: "../xip_server.html",
-				url: "tests/frag.xml",
-				handleAs: "xml",
-				load: function(result, ioArgs){
-					var foo = result.getElementsByTagName("foo").item(0);
-
-					dojo.byId("xmlGetOut").innerHTML = "Success: First foobar value is: " + foo.firstChild.nodeValue;
-				}
-			});
-
-		}
-
-		dojo.addOnLoad(function(){
-
+		var testXmlGet;
+		require(['dojo/_base/kernel', 'dojox/io/proxy/xip', 'dojo/_base/xhr', 'dojo/_base/html'], function(dojo, xip){
+
+			testXmlGet = function(){
+	/*
+				//Normal xhrGet call.
+				dojo.xhrGet({
+					url: "frag.xml",
+					handleAs: "xml",
+					load: function(result, ioArgs){
+						var foo = result.getElementsByTagName("foo").item(0);
+
+						dojo.byId("xmlGetOut").innerHTML = "Success: First foobar value is: " + foo.firstChild.nodeValue;
+					}
+				});
+	*/
+
+				//xip xhrGet call.
+				dojo.xhrGet({
+					iframeProxyUrl: "../xip_server.html",
+					url: "tests/frag.xml",
+					handleAs: "xml",
+					load: function(result, ioArgs){
+						var foo = result.getElementsByTagName("foo").item(0);
+
+						dojo.byId("xmlGetOut").innerHTML = "Success: First foobar value is: " + foo.firstChild.nodeValue;
+					}
+				});
+
+			}
 		});
+
 	</script>
 </head>
 <body class="tundra">
diff --git a/dojox/io/proxy/xip.js b/dojox/io/proxy/xip.js
index 10fb54c..acb08a4 100644
--- a/dojox/io/proxy/xip.js
+++ b/dojox/io/proxy/xip.js
@@ -1,7 +1,5 @@
-dojo.provide("dojox.io.proxy.xip");
-
-dojo.require("dojo.io.iframe");
-dojo.require("dojox.data.dom");
+define(['dojo/main', 'dojo/io/iframe', 'dojox/data/dom', 'dojo/_base/xhr', 'dojo/_base/url'], function(dojo, iframe, dom){
+	dojo.getObject("io.proxy.xip", true, dojox);
 
 dojox.io.proxy.xip = {
 	//summary: Object that implements the iframe handling for XMLHttpRequest
@@ -41,7 +39,7 @@ dojox.io.proxy.xip = {
 	together.
 	*/
 
-	xipClientUrl: ((dojo.config || djConfig)["xipClientUrl"]) || dojo.moduleUrl("dojox.io.proxy", "xip_client.html"),
+	xipClientUrl: ((dojo.config || djConfig)["xipClientUrl"]) || dojo.moduleUrl("dojox.io.proxy", "xip_client.html").toString(),
 
 
 	//MSIE has the lowest limit for URLs with fragment identifiers,
@@ -61,7 +59,7 @@ dojox.io.proxy.xip = {
 		var url = this.xipClientUrl;
 		//Make sure we are not dealing with javascript urls, just to be safe.
 		if(url.split(":")[0].match(/javascript/i) || facade._ifpServerUrl.split(":")[0].match(/javascript/i)){
-			return;
+			return null;
 		}
 		
 		//Make xip_client a full URL.
@@ -101,7 +99,7 @@ dojox.io.proxy.xip = {
 		this._state[stateId] = {
 			facade: facade,
 			stateId: stateId,
-			clientFrame: dojo.io.iframe.create(stateId, "", frameUrl),
+			clientFrame: iframe.create(stateId, "", frameUrl),
 			isSending: false,
 			serverUrl: facade._ifpServerUrl,
 			requestData: null,
@@ -151,7 +149,7 @@ dojox.io.proxy.xip = {
 			if(contentType){
 				var mimeType = contentType.split(";")[0];
 				if(mimeType.indexOf("application/xml") == 0 || mimeType.indexOf("text/xml") == 0){
-					facade.responseXML = dojox.data.dom.createDocument(response.responseText, contentType);
+					facade.responseXML = dom.createDocument(response.responseText, contentType);
 				}
 			}
 		}
@@ -435,3 +433,7 @@ dojo.extend(dojox.io.proxy.xip.XhrIframeFacade, {
 		}
 	}
 });
+
+return dojox.io.proxy.xip;
+
+});
diff --git a/dojox/io/scriptFrame.js b/dojox/io/scriptFrame.js
index 5ed04dd..dd4c05c 100644
--- a/dojox/io/scriptFrame.js
+++ b/dojox/io/scriptFrame.js
@@ -1,7 +1,6 @@
-dojo.provide("dojox.io.scriptFrame");
-
-dojo.require("dojo.io.script");
-dojo.require("dojo.io.iframe");
+define(["dojo/main", "dojo/io/script", "dojo/io/iframe"], function(dojo, ioScript, iframe){
+	dojo.deprecated("dojox.io.scriptFrame", "dojo.io.script now supports parallel requests without dojox.io.scriptFrame", "2.0");
+	dojo.getObject("io.scriptFrame", true, dojox);
 
 //This module extends dojo.io.script to use an iframe for the dojo.io.script.attach calls
 //if the frameDoc argument is passed to dojo.io.script.get(), and if frameDoc is a string (representing
@@ -16,8 +15,6 @@ dojo.require("dojo.io.iframe");
 //NOT the parent page location. This iframe document's URL will be (dojo.moduleUrl("dojo", "resources/blank.html")
 //or djConfig.dojoBlankHtmlUrl (for xdomain loading).
 
-(function(){
-	var ioScript = dojo.io.script;
 	dojox.io.scriptFrame = {
 		_waiters: {},
 		_loadedIds: {},
@@ -39,7 +36,7 @@ dojo.require("dojo.io.iframe");
 
 			for(var i = 0; i < waiters.length; i++){
 				var ioArgs = waiters[i];
-				ioArgs.frameDoc = dojo.io.iframe.doc(dojo.byId(frameId));
+				ioArgs.frameDoc = iframe.doc(dojo.byId(frameId));
 				ioScript.attach(ioArgs.id, ioArgs.url, ioArgs.frameDoc);
 			}
 		}
@@ -66,11 +63,11 @@ dojo.require("dojo.io.iframe");
 				//if using xdomain loading). Loading of the frame document is asynchronous,
 				//so we need to do callback stuff.
 				waiters.push(ioArgs);
-				dojo.io.iframe.create(fId, dojox._scopeName + ".io.scriptFrame._loaded('" + fId + "');");
+				iframe.create(fId, dojox._scopeName + ".io.scriptFrame._loaded('" + fId + "');");
 			}else{
 				//Frame loading could still be happening. Only call attach if the frame has loaded.
 				if(scriptFrame._loadedIds[fId]){
-					ioArgs.frameDoc = dojo.io.iframe.doc(frame);
+					ioArgs.frameDoc = iframe.doc(frame);
 					this.attach(ioArgs.id, ioArgs.url, ioArgs.frameDoc);
 				}else{
 					waiters.push(ioArgs);
@@ -80,6 +77,8 @@ dojo.require("dojo.io.iframe");
 		}else{
 			return oldCanAttach.apply(this, arguments);
 		}
-	}
-})();
+	};
+
+	return dojox.io.scriptFrame;
+});
 
diff --git a/dojox/io/tests/scriptFrame.html b/dojox/io/tests/scriptFrame.html
index a360eb5..e55c7b7 100644
--- a/dojox/io/tests/scriptFrame.html
+++ b/dojox/io/tests/scriptFrame.html
@@ -9,15 +9,12 @@
 		<script type="text/javascript" 
 			src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
 		<script type="text/javascript">
-			dojo.require("doh.runner");
-			dojo.require("dojox.io.scriptFrame");
-
-			dojo.addOnLoad(function(){
+			require(['doh/runner', 'dojo/io/script', 'dojox/io/scriptFrame'], function(doh, script, scriptFrame){
 				doh.register("t", 
 					[
 						function ioScriptJsonp(t){
 							var d = new doh.Deferred();
-							var td = dojo.io.script.get({
+							var td = script.get({
 								//Note that this URL path is relative to the URL of the iframe document
 								//(dojo.moduleUrl("dojo.resources", "blank.html")
 								url: "../tests/io/scriptJsonp.js",
@@ -37,7 +34,7 @@
 						},
 						function ioScriptJsonpTimeout(t){
 							var d = new doh.Deferred();
-							var td = dojo.io.script.get({
+							var td = script.get({
 								//Note that this URL path is relative to the URL of the iframe document
 								//(dojo.moduleUrl("dojo.resources", "blank.html")
 								url: "../tests/_base/timeout.php",
diff --git a/dojox/io/tests/scriptFrame.js b/dojox/io/tests/scriptFrame.js
index 09a3702..be2d74c 100644
--- a/dojox/io/tests/scriptFrame.js
+++ b/dojox/io/tests/scriptFrame.js
@@ -1,5 +1,7 @@
-dojo.provide("dojox.io.tests.scriptFrame");
+require(['doh', 'dojo/_base/kernel', 'dojo/_base/sniff', 'dojo/_base/url'], function(doh, dojo){
 
 if(dojo.isBrowser){
 	doh.registerUrl("dojox.io.tests.scriptFrame", dojo.moduleUrl("dojox.io.tests", "scriptFrame.html"));
 }
+
+});
diff --git a/dojox/io/tests/scriptFrameRepeat.html b/dojox/io/tests/scriptFrameRepeat.html
index 4be97a9..057d544 100644
--- a/dojox/io/tests/scriptFrameRepeat.html
+++ b/dojox/io/tests/scriptFrameRepeat.html
@@ -9,32 +9,29 @@
 		<script type="text/javascript" 
 			src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
 		<script type="text/javascript">
-			dojo.require("dojox.io.scriptFrame");
+			require(['dojo/io/script', 'dojox/io/scriptFrame'], function(script, scriptFrame){
+				function repeatCall(){
+					var td = script.get({
+						//Note that this URL path is relative to the URL of the iframe document
+						//(dojo.moduleUrl("dojo.resources", "blank.html")
+						url: "../tests/io/scriptJsonp.js",
+						content: { foo: "bar" },
+						callbackParamName: "callback",
+						frameDoc: "testFrame",
+						timeout: 3000
+					});
+					td.addBoth(function(res){
+						if(!(res instanceof Error) && "mammal" == res.animalType){
+							console.log("success");
+						}else{
+							console.error(res);
+						}
+						return res;
+					});
+				};
 
-			function repeatCall(){
-				var td = dojo.io.script.get({
-					//Note that this URL path is relative to the URL of the iframe document
-					//(dojo.moduleUrl("dojo.resources", "blank.html")
-					url: "../tests/io/scriptJsonp.js",
-					content: { foo: "bar" },
-					callbackParamName: "callback",
-					frameDoc: "testFrame",
-					timeout: 3000
-				});
-				td.addBoth(function(res){
-					if(!(res instanceof Error) && "mammal" == res.animalType){
-						console.log("success");
-					}else{
-						console.error(res);
-					}
-					return res;
-				});
-			};
-
-			dojo.addOnLoad(function(){
 				setInterval(repeatCall, 2000);
 			});
-
 		</script>
 	</head>
 	<body>
diff --git a/dojox/io/tests/windowName.html b/dojox/io/tests/windowName.html
index 680d01c..be303bb 100644
--- a/dojox/io/tests/windowName.html
+++ b/dojox/io/tests/windowName.html
@@ -8,39 +8,41 @@
 	</style>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true"></script>
-	<script type="text/javascript" src="../windowName.js"></script>
 	<script type="text/javascript">
+		var test, testPost;
+		require(['dojox/io/windowName'], function(windowName){
 	//dojox.io.xhrWindowNamePlugin("http://localhost");
-function test(auth) {
-	var authTarget = auth && document.getElementById("authTarget");
-	var dfd = dojox.io.windowName.send("GET",{
-				url: prompt("Enter an address to retrieve data from",
-						auth ? "http://sitepen.com:80/labs/code/secure/dojox/io/tests/testResource.html" : "http://persevere.sitepen.com/Customer/550"),
-				handleAs:"text",
-				authElement: authTarget,
-				onAuthLoad: auth && function(){
-					authTarget.style.display='block';
-				}});
-	dfd.addBoth(function(result){
-		auth && (authTarget.style.display='none');
-		alert(result)
-	});
-}
-function testPost(auth) {
-	var authTarget = auth && document.getElementById("authTarget");
-	var dfd = dojox.io.windowName.send("POST",{
-				url: prompt("Enter an address to post data to",
-						"http://persevere.sitepen.com/Customer/"),
-				content:{foo:"bar"},
-				authElement: authTarget,
-				onAuthLoad: auth && function(){
-					authTarget.style.display='block';
-				}});
-	dfd.addBoth(function(result){
-		auth && (authTarget.style.display='none');
-		alert(result)
-	});
-}
+			test = function(auth) {
+				var authTarget = auth && document.getElementById("authTarget");
+				var dfd = windowName.send("GET",{
+							url: prompt("Enter an address to retrieve data from",
+									auth ? "http://sitepen.com:80/labs/code/secure/dojox/io/tests/testResource.html" : "http://persevere.sitepen.com/Customer/550"),
+							handleAs:"text",
+							authElement: authTarget,
+							onAuthLoad: auth && function(){
+								authTarget.style.display='block';
+							}});
+				dfd.addBoth(function(result){
+					auth && (authTarget.style.display='none');
+					alert(result)
+				});
+			};
+			testPost = function(auth) {
+				var authTarget = auth && document.getElementById("authTarget");
+				var dfd = windowName.send("POST",{
+							url: prompt("Enter an address to post data to",
+									"http://persevere.sitepen.com/Customer/"),
+							content:{foo:"bar"},
+							authElement: authTarget,
+							onAuthLoad: auth && function(){
+								authTarget.style.display='block';
+							}});
+				dfd.addBoth(function(result){
+					auth && (authTarget.style.display='none');
+					alert(result)
+				});
+			}
+		});
 	</script>
 </head>
 <body class="tundra">
diff --git a/dojox/io/tests/windowName.js b/dojox/io/tests/windowName.js
index 5e5b337..9ae0a7c 100644
--- a/dojox/io/tests/windowName.js
+++ b/dojox/io/tests/windowName.js
@@ -1,15 +1,13 @@
-dojo.provide("dojox.io.tests.xhrPlugins");
-dojo.require("dojox.io.xhrPlugins");
+define(['doh', 'dojo/_base/kernel', 'dojo/_base/xhr', 'dojox/io/xhrPlugins', 'dojo/_base/url'], function(doh, dojo, xhr, xhrPlugins){
 
-dojox.io.xhrPlugins.addXdr("http://xdrsupportingsite.com/"); // make sure the registry is setup
-var url = dojo.moduleUrl("dojox.io.tests.crossSite");
+xhrPlugins.addXdr("http://xdrsupportingsite.com/"); // make sure the registry is setup
+var url = dojo.moduleUrl("dojox.io", "tests/crossSite.php");
 url = url.toString();
-url = url.substring(0,url.length-1) + ".php";
 
 doh.register("dojox.io.tests.xhrPlugins", [
 	function getLocal(t){
 		var d = new doh.Deferred();
-		var dfd = dojo.xhr("GET",{url:url});
+		var dfd = xhr("GET",{url:url});
 		dfd.addCallback(function(result){
 			d.callback(result.match(/response/));
 		});
@@ -24,7 +22,7 @@ doh.register("dojox.io.tests.xhrPlugins", [
 		dojox.io.xhrPlugins.addXdr("http://persevere.sitepen.com/");
 		dojox.io.xhrPlugins.addCrossSiteXhr("http://persevere.sitepen.com/");
 		try {
-			var dfd = dojo.xhr("GET",{url:"http://persevere.sitepen.com/SMD"});
+			var dfd = xhr("GET",{url:"http://persevere.sitepen.com/SMD"});
 		}
 		catch (e){
 			if(e.message.match(/No match/)){
@@ -40,7 +38,7 @@ doh.register("dojox.io.tests.xhrPlugins", [
 /*		dojox.io.xhrPlugins.addXdr("http://dojotoolkit.org/...");
 		dojox.io.xhrPlugins.addCrossSiteXhr("http://dojotoolkit.org/...");
 				
-		var dfd = dojo.xhr("GET",{url:"http://dojotoolkit.org/.../dojox/io/tests/crossSite.php"});
+		var dfd = xhr("GET",{url:"http://dojotoolkit.org/.../dojox/io/tests/crossSite.php"});
 		dfd.addCallback(function(result){
 			d.callback(result.match(/response/));
 		}); */
@@ -50,10 +48,12 @@ doh.register("dojox.io.tests.xhrPlugins", [
 		var d = new doh.Deferred();
 		dojox.io.xhrPlugins.addProxy(url+"?url=");
 
-		var dfd = dojo.xhr("GET",{url:"http://someforeignsite.com/SMD"});
+		var dfd = xhr("GET",{url:"http://someforeignsite.com/SMD"});
 		dfd.addCallback(function(result){
 			d.callback(result.match(/proxied/));
 		});
 		return d;
 	}
 ]);
+
+});
diff --git a/dojox/io/tests/xhrMultiPart.html b/dojox/io/tests/xhrMultiPart.html
index d377f72..6127c71 100644
--- a/dojox/io/tests/xhrMultiPart.html
+++ b/dojox/io/tests/xhrMultiPart.html
@@ -10,49 +10,52 @@
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true"></script>
 	<script type="text/javascript" src="../xhrMultiPart.js"></script>
 	<script type="text/javascript">
-		dojo.require("dojox.io.xhrMultiPart");
-		var content = [
-			{ name: "foo", content: "FOObarbaz", filename: "foo.txt" },
-			{ name: "bar", content: "fooBARbaz", filename: "bar.txt" },
-			{ name: "baz", content: "foobarBAZ", filename: "baz.txt" }
-		];
+		var testXhrMulti, testXhrMultiForm, testXhrMultiFormWithFile;
 
-		function testXhrMulti(){
-			dojox.io.xhrMultiPart({
-				url: "result.txt",
-				file: content,
-				load: function(data){ console.log("Test with file: ", data); }
-			});
+		require(['dojox/io/xhrMultiPart'], function(xhrMultiPart){
+			var content = [
+				{ name: "foo", content: "FOObarbaz", filename: "foo.txt" },
+				{ name: "bar", content: "fooBARbaz", filename: "bar.txt" },
+				{ name: "baz", content: "foobarBAZ", filename: "baz.txt" }
+			];
 
-			//	should be the same.
-			dojox.io.xhrMultiPart({
-				url: "result.txt",
-				content: content,
-				load: function(data){ console.log("Test with content: ", data); }
-			});
-		}
+			testXhrMulti = function(){
+				xhrMultiPart({
+					url: "result.txt",
+					file: content,
+					load: function(data){ console.log("Test with file: ", data); }
+				});
 
-		function testXhrMultiForm(){
-			dojox.io.xhrMultiPart({
-				url: "result.txt",
-				form: dojo.byId("formTest"),
-				load: function(data){ console.log("Test with form: ", data); }
-			});
-			return false;	//	stop the submission
-		}
+				//	should be the same.
+				xhrMultiPart({
+					url: "result.txt",
+					content: content,
+					load: function(data){ console.log("Test with content: ", data); }
+				});
+			}
 
-		function testXhrMultiFormWithFile(){
-			try {
-				dojox.io.xhrMultiPart({
+			testXhrMultiForm = function(){
+				xhrMultiPart({
 					url: "result.txt",
-					form: dojo.byId("formTestWithFile"),
+					form: dojo.byId("formTest"),
 					load: function(data){ console.log("Test with form: ", data); }
 				});
-			} catch(e){
-				console.warn("xhrMultiPart failed because the form contains a FILE element!");
+				return false;	//	stop the submission
+			}
+
+			testXhrMultiFormWithFile = function(){
+				try {
+					xhrMultiPart({
+						url: "result.txt",
+						form: dojo.byId("formTestWithFile"),
+						load: function(data){ console.log("Test with form: ", data); }
+					});
+				} catch(e){
+					console.warn("xhrMultiPart failed because the form contains a FILE element!");
+				}
+				return false;	//	stop the submission
 			}
-			return false;	//	stop the submission
-		}
+		});
 	</script>
 </head>
 <body class="tundra">
diff --git a/dojox/io/tests/xhrPlugins.js b/dojox/io/tests/xhrPlugins.js
index 991a63c..2e9ce94 100644
--- a/dojox/io/tests/xhrPlugins.js
+++ b/dojox/io/tests/xhrPlugins.js
@@ -1,15 +1,13 @@
-dojo.provide("dojox.io.tests.xhrPlugins");
-dojo.require("dojox.io.xhrPlugins");
+define(['doh', 'dojo/_base/kernel', 'dojo/_base/xhr', 'dojox/io/xhrPlugins', 'dojo/_base/url'], function(doh, dojo, xhr, xhrPlugins){
 
-dojox.io.xhrPlugins.addCrossSiteXhr("http://cssupportingsite.com/"); // make sure the registry is setup
-var url = dojo.moduleUrl("dojox.io.tests.crossSite");
+xhrPlugins.addCrossSiteXhr("http://cssupportingsite.com/"); // make sure the registry is setup
+var url = dojo.moduleUrl("dojox.io", "tests/crossSite.php");
 url = url.toString();
-url = url.substring(0,url.length-1) + ".php";
 
 doh.register("dojox.io.tests.xhrPlugins", [
 	function getLocal(t){
 		var d = new doh.Deferred();
-		var dfd = dojo.xhr("GET",{url:url});
+		var dfd = xhr("GET",{url:url});
 		dfd.addCallback(function(result){
 			d.callback(result.match(/response/));
 		});
@@ -21,9 +19,9 @@ doh.register("dojox.io.tests.xhrPlugins", [
 		// browser that supports cross-site XHR (maybe FF3.1?)
 		var d = new doh.Deferred();
 		// persevere supports cross-site XHR so we can use it for cross-site testing for now
-		dojox.io.xhrPlugins.addCrossSiteXhr("http://persevere.sitepen.com/");
+		xhrPlugins.addCrossSiteXhr("http://persevere.sitepen.com/");
 		try {
-			var dfd = dojo.xhr("GET",{url:"http://persevere.sitepen.com/SMD"});
+			var dfd = xhr("GET",{url:"http://persevere.sitepen.com/SMD"});
 		}
 		catch (e){
 			if(e.message.match(/No match/)){
@@ -36,10 +34,10 @@ doh.register("dojox.io.tests.xhrPlugins", [
 		});
 		// TODO: This should run off a fixed URL on some Dojo server.
 		
-/*		dojox.io.xhrPlugins.addXdr("http://dojotoolkit.org/...");
-		dojox.io.xhrPlugins.addCrossSiteXhr("http://dojotoolkit.org/...");
+/*		xhrPlugins.addXdr("http://dojotoolkit.org/...");
+		xhrPlugins.addCrossSiteXhr("http://dojotoolkit.org/...");
 				
-		var dfd = dojo.xhr("GET",{url:"http://dojotoolkit.org/.../dojox/io/tests/crossSite.php"});
+		var dfd = xhr("GET",{url:"http://dojotoolkit.org/.../dojox/io/tests/crossSite.php"});
 		dfd.addCallback(function(result){
 			d.callback(result.match(/response/));
 		}); */
@@ -47,12 +45,14 @@ doh.register("dojox.io.tests.xhrPlugins", [
 	},
 	function proxiedRequest(t){
 		var d = new doh.Deferred();
-		dojox.io.xhrPlugins.addProxy(url+"?url=");
+		xhrPlugins.addProxy(url+"?url=");
 
-		var dfd = dojo.xhr("GET",{url:"http://someforeignsite.com/SMD"});
+		var dfd = xhr("GET",{url:"http://someforeignsite.com/SMD"});
 		dfd.addCallback(function(result){
 			d.callback(result.match(/proxied/));
 		});
 		return d;
 	}
 ]);
+
+});
diff --git a/dojox/io/windowName.js b/dojox/io/windowName.js
index 401ef0f..7a302ba 100644
--- a/dojox/io/windowName.js
+++ b/dojox/io/windowName.js
@@ -1,4 +1,5 @@
-dojo.provide("dojox.io.windowName");
+define(["dojo/_base/kernel", "dojo/_base/window", "dojo/_base/xhr", "dojo/_base/sniff", "dojo/_base/url", "dojo/domReady!"], function(dojo){
+dojo.getObject("io.windowName", true, dojox);
 // Implements the window.name transport
 
 dojox.io.windowName = {
@@ -78,16 +79,7 @@ dojox.io.windowName = {
 				args.timeout
 			);
 		}
-		var self = dojox.io.windowName;
-		if(dojo.body()){
-			// the DOM is ready
-			self._send(dfd, method, authElement, args.onAuthLoad);
-		}else{
-			// we will wait for the DOM to be ready to proceed
-			dojo.addOnLoad(function(){
-				self._send(dfd, method, authElement, args.onAuthLoad);
-			});
-		}
+		dojox.io.windowName._send(dfd, method, authElement, args.onAuthLoad);
 		return dfd;
 	},
 	_send: function(dfd, method, authTarget, onAuthLoad){
@@ -112,7 +104,7 @@ dojox.io.windowName = {
 				outerFrame.style.display='none';
 			}
 			frameContainer.appendChild(outerFrame);
-			
+
 			var firstWindow = outerFrame.contentWindow;
 			doc = firstWindow.document;
 			doc.write("<html><body margin='0px'><iframe style='width:100%;height:100%;border:0px' name='protectedFrame'></iframe></body></html>");
@@ -180,7 +172,7 @@ dojox.io.windowName = {
 			}
 			catch(e){
 			}
-			
+
 		};
 		frame.name = frameName;
 		if(method.match(/GET/i)){
@@ -212,7 +204,7 @@ dojox.io.windowName = {
 			form.method = 'POST';
 			form.action = ioArgs.url;
 			form.target = frameName;// connect the form to the iframe
-			
+
 			form.submit();
 			form.parentNode.removeChild(form);
 		}else{
@@ -223,5 +215,9 @@ dojox.io.windowName = {
 		}
 	},
 	_frameNum: 0
-	
-}
+
+};
+
+return dojox.io.windowName;
+
+});
diff --git a/dojox/io/xhrMultiPart.js b/dojox/io/xhrMultiPart.js
index 157d8f9..7797d11 100644
--- a/dojox/io/xhrMultiPart.js
+++ b/dojox/io/xhrMultiPart.js
@@ -1,7 +1,12 @@
-dojo.provide("dojox.io.xhrMultiPart");
-dojo.require("dojox.uuid.generateRandomUuid");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/array",
+	"dojo/_base/xhr",
+	 "dojo/query",
+	"dojox/uuid/generateRandomUuid"
+], function(dojo, array, xhr, query, generateRandomUuid){
+	dojo.getObject("io.xhrMultiPart", true, dojox);
 
-(function(){
 	/*=====
 	dojox.io.__xhrContentArgs = function(){
 		//	name: String
@@ -124,7 +129,7 @@ dojo.require("dojox.uuid.generateRandomUuid");
 		}
 
 		// unique guid as a boundary value for multipart posts
-		var boundary=dojox.uuid.generateRandomUuid(), tmp=[], out="";
+		var boundary=generateRandomUuid(), tmp=[], out="";
 		if(args["file"] || args["content"]){
 			var v = args["file"] || args["content"];
 			dojo.forEach((dojo.isArray(v) ? v : [v]), function(item){
@@ -132,7 +137,7 @@ dojo.require("dojox.uuid.generateRandomUuid");
 			});
 		}
 		else if(args["form"]){
-			if(dojo.query("input[type=file]", args["form"]).length){
+			if(query("input[type=file]", args["form"]).length){
 				throw new Error("dojox.io.xhrMultiPart cannot post files that are values of an INPUT TYPE=FILE.  Use dojo.io.iframe.send() instead.");
 			}
 			tmp = _partsFromNode(args["form"], boundary);
@@ -149,5 +154,7 @@ dojo.require("dojox.uuid.generateRandomUuid");
 			contentType: "multipart/form-data; boundary=" + boundary,
 			postData: out
 		}));	//	dojo.Deferred
-	}
-})();
+	};
+
+	return dojox.io.xhrMultiPart;
+});
diff --git a/dojox/io/xhrPlugins.js b/dojox/io/xhrPlugins.js
index 2de3f57..8b930c3 100644
--- a/dojox/io/xhrPlugins.js
+++ b/dojox/io/xhrPlugins.js
@@ -1,12 +1,10 @@
-dojo.provide("dojox.io.xhrPlugins");
-dojo.require("dojo.AdapterRegistry");
-dojo.require("dojo._base.xhr");
+define(["dojo/_base/kernel", "dojo/_base/xhr", "dojo/AdapterRegistry"], function(dojo, xhr, AdapterRegistry){
+	dojo.getObject("io.xhrPlugins", true, dojox);
 
-(function() {
 	var registry;
 	var plainXhr;
 	function getPlainXhr(){
-		return plainXhr = dojox.io.xhrPlugins.plainXhr = plainXhr || dojo._defaultXhr || dojo.xhr;
+		return plainXhr = dojox.io.xhrPlugins.plainXhr = plainXhr || dojo._defaultXhr || xhr;
 	}
 	dojox.io.xhrPlugins.register = function(){
 		//	summary:
@@ -14,7 +12,7 @@ dojo.require("dojo._base.xhr");
 		// 		xhr handlers
 		var plainXhr = getPlainXhr();
 		if(!registry){
-			registry = new dojo.AdapterRegistry();
+			registry = new AdapterRegistry();
 			// replaces the default xhr() method. Can we just use connect() instead?
 			dojo[dojo._defaultXhr ? "_defaultXhr" : "xhr"] = function(/*String*/ method, /*dojo.__XhrArgs*/ args, /*Boolean?*/ hasBody){
 				return registry.match.apply(registry,arguments);
@@ -167,7 +165,6 @@ dojo.require("dojo._base.xhr");
 			return plainXhr.call(dojo,method,args,hasBody);
 		};
 	};
-})();
-
-
 
+	return dojox.io.xhrPlugins;
+});
diff --git a/dojox/io/xhrScriptPlugin.js b/dojox/io/xhrScriptPlugin.js
index fe3eb81..d64b480 100644
--- a/dojox/io/xhrScriptPlugin.js
+++ b/dojox/io/xhrScriptPlugin.js
@@ -1,7 +1,5 @@
-dojo.provide("dojox.io.xhrScriptPlugin");
-dojo.require("dojox.io.xhrPlugins");
-dojo.require("dojo.io.script");
-dojo.require("dojox.io.scriptFrame");
+define(["dojo/_base/kernel", "dojo/_base/window", "dojo/io/script", "dojox/io/xhrPlugins", "dojox/io/scriptFrame"], function(dojo, window, script, xhrPlugins, scriptFrame){
+dojo.getObject("io.xhrScriptPlugin", true, dojox);
 
 dojox.io.xhrScriptPlugin = function(/*String*/url, /*String*/callbackParamName, /*Function?*/httpAdapter){
 	// summary:
@@ -13,7 +11,7 @@ dojox.io.xhrScriptPlugin = function(/*String*/url, /*String*/callbackParamName,
 	//		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.
-	dojox.io.xhrPlugins.register(
+	xhrPlugins.register(
 		"script",
 		function(method,args){
 			 return args.sync !== true &&
@@ -26,9 +24,12 @@ dojox.io.xhrScriptPlugin = function(/*String*/url, /*String*/callbackParamName,
 				if(dojo.body()){
 					args.frameDoc = "frame" + Math.random();
 				}
-				return dojo.io.script.get(args);
-			}
+				return script.get(args);
+			};
 			return (httpAdapter ? httpAdapter(send, true) : send)(method, args, hasBody); // use the JSONP transport
 		}
 	);
-};
\ No newline at end of file
+};
+
+return dojox.io.xhrScriptPlugin;
+});
diff --git a/dojox/io/xhrWindowNamePlugin.js b/dojox/io/xhrWindowNamePlugin.js
index c8b1c27..4ea5d8a 100644
--- a/dojox/io/xhrWindowNamePlugin.js
+++ b/dojox/io/xhrWindowNamePlugin.js
@@ -1,8 +1,13 @@
-dojo.provide("dojox.io.xhrWindowNamePlugin");
-dojo.require("dojox.io.xhrPlugins");
-dojo.require("dojox.io.windowName");
-dojo.require("dojox.io.httpParse");
-dojo.require("dojox.secure.capability"); // would like to have a safe JSON verifier instead (more compact)
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/json",
+	"dojo/_base/xhr",
+	"dojox/io/xhrPlugins",
+	"dojox/io/windowName",
+	"dojox/io/httpParse",
+	"dojox/secure/capability"
+], function(dojo, json, xhr, xhrPlugins, windowName, httpParse, capability){
+dojo.getObject("io.xhrWindowNamePlugin", true, dojox);
 
 dojox.io.xhrWindowNamePlugin = function(/*String*/url, /*Function?*/httpAdapter, /*Boolean?*/trusted){
 	// summary:
@@ -12,7 +17,7 @@ dojox.io.xhrWindowNamePlugin = function(/*String*/url, /*Function?*/httpAdapter,
 	//		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.
-	dojox.io.xhrPlugins.register(
+	xhrPlugins.register(
 		"windowName",
 		function(method,args){
 			 return args.sync !== true &&
@@ -20,7 +25,7 @@ dojox.io.xhrWindowNamePlugin = function(/*String*/url, /*Function?*/httpAdapter,
 				(args.url.substring(0,url.length) == url);
 		},
 		function(method,args,hasBody){
-			var send = dojox.io.windowName.send;
+			var send = windowName.send;
 			var load = args.load;
 			args.load = undefined; //we don't want send to set this callback
 			var dfd = (httpAdapter ? httpAdapter(send, true) : send)(method, args, hasBody); // use the windowName transport
@@ -36,7 +41,7 @@ dojox.io.xhrWindowNamePlugin = function(/*String*/url, /*Function?*/httpAdapter,
 				if(ioArgs.handleAs == 'json'){
 					// use a secure json verifier, using object capability validator for now
 					if(!trusted){
-						dojox.secure.capability.validate(result,["Date"],{});
+						capability.validate(result,["Date"],{});
 					}
 					return dojo.fromJson(result);
 				}
@@ -49,4 +54,7 @@ dojox.io.xhrWindowNamePlugin = function(/*String*/url, /*Function?*/httpAdapter,
 			return dfd;
 		}
 	);
-};
\ No newline at end of file
+};
+
+return dojox.io.xhrWindowNamePlugin;
+});
diff --git a/dojox/json/query.js b/dojox/json/query.js
index 047d4f9..05b7e7e 100644
--- a/dojox/json/query.js
+++ b/dojox/json/query.js
@@ -1,6 +1,7 @@
-dojo.provide("dojox.json.query");
+define(["dojo/_base/kernel", "dojox", "dojo/_base/array"], function(dojo, dojox){
+
+	dojo.getObject("json", true, dojox);
 
-(function(){
 	dojox.json._slice = function(obj,start,end,step){
 		// handles slice operations: [3:6:2]
 		var len=obj.length,results = [];
@@ -32,7 +33,7 @@ dojo.provide("dojox.json.query");
 					// if we don't have a name we are just getting all the properties values (.* or [*])
 					results.push(val);
 				}else if(val && typeof val == 'object'){
-					
+
 					walk(val);
 				}
 			}
@@ -54,7 +55,7 @@ dojo.provide("dojox.json.query");
 		}
 		return results;
 	}
-	
+
 	dojox.json._distinctFilter = function(array, callback){
 		// does the filter with removal of duplicates in O(n)
 		var outArr = [];
@@ -83,7 +84,7 @@ dojo.provide("dojox.json.query");
 		}
 		return outArr;
 	}
-	dojox.json.query = function(/*String*/query,/*Object?*/obj){
+	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
@@ -197,8 +198,8 @@ dojo.provide("dojox.json.query");
 		query.replace(/(\]|\)|push|pop|shift|splice|sort|reverse)\s*\(/,function(){
 			throw new Error("Unsafe function call");
 		});
-		
-		query = query.replace(/([^=]=)([^=])/g,"$1=$2"). // change the equals to comparisons
+
+		query = query.replace(/([^<>=]=)([^=])/g,"$1=$2"). // change the equals to comparisons except operators ==, <=, >=
 			replace(/@|(\.\s*)?[a-zA-Z\$_]+(\s*:)?/g,function(t){
 				return t.charAt(0) == '.' ? t : // leave .prop alone
 					t == '@' ? "$obj" :// the reference to the current object
@@ -249,12 +250,12 @@ dojo.provide("dojox.json.query");
 			return a == ']' ? ']' : str[a];
 		});
 		// create a function within this scope (so it can use expand and slice)
-		
+
 		var executor = eval("1&&function($,$1,$2,$3,$4,$5,$6,$7,$8,$9){var $obj=$;return " + query + "}");
 		for(var i = 0;i<arguments.length-1;i++){
 			arguments[i] = arguments[i+1];
 		}
 		return obj ? executor.apply(this,arguments) : executor;
 	};
-	
-})();
\ No newline at end of file
+
+});
\ No newline at end of file
diff --git a/dojox/json/ref.js b/dojox/json/ref.js
index 0d5a661..4d87b1f 100644
--- a/dojox/json/ref.js
+++ b/dojox/json/ref.js
@@ -1,8 +1,8 @@
-dojo.provide("dojox.json.ref");
-dojo.require("dojo.date.stamp");
+define(["dojo/_base/kernel", "dojox", "dojo/date/stamp", "dojo/_base/array", "dojo/_base/json"], function(dojo, dojox){
 
+dojo.getObject("json", true, dojox);
 
-dojox.json.ref = {
+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,
@@ -355,4 +355,5 @@ dojox.json.ref = {
 	refAttribute: "$ref",
 	_useRefs: false,
 	serializeFunctions: false
-}
+};
+});
diff --git a/dojox/json/schema.js b/dojox/json/schema.js
index b2379d8..10c69b6 100644
--- a/dojox/json/schema.js
+++ b/dojox/json/schema.js
@@ -1,4 +1,6 @@
-dojo.provide("dojox.json.schema");
+define(["dojo/_base/kernel", "dojox", "dojo/_base/array"], function(dojo, dojox){
+
+dojo.getObject("json.schema", true, dojox);
 
 
 dojox.json.schema.validate = function(/*Any*/instance,/*Object*/schema){
@@ -216,3 +218,5 @@ dojox.json.schema._validate = function(/*Any*/instance,/*Object*/schema,/*Boolea
 	return {valid:!errors.length,errors:errors};
 };
 
+return dojox.json.schema;
+});
diff --git a/dojox/json/tests/query.js b/dojox/json/tests/query.js
index b6bdb85..7316ca2 100644
--- a/dojox/json/tests/query.js
+++ b/dojox/json/tests/query.js
@@ -92,6 +92,14 @@ doh.register("dojox.json.tests.query",
 			}
 		},
 		{
+			name: "$..book[0]?price>=20",
+			runTest: function(t) {
+				var result = dojo.toJson(dojox.json.query(this.name,dojox.json.tests.testData));
+				var success =  '[{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the\\nRings","isbn":"0-395-19395-8","price":22.99}]';
+				doh.assertEqual(success,result);
+			}
+		},
+		{
 			name: "$..book[0][-1:]",
 			runTest: function(t) {
 				var result = dojo.toJson(dojox.json.query(this.name,dojox.json.tests.testData));
diff --git a/dojox/lang/functional.js b/dojox/lang/functional.js
index 9d8411e..fd559bd 100644
--- a/dojox/lang/functional.js
+++ b/dojox/lang/functional.js
@@ -1,5 +1,3 @@
-dojo.provide("dojox.lang.functional");
-
-dojo.require("dojox.lang.functional.lambda");
-dojo.require("dojox.lang.functional.array");
-dojo.require("dojox.lang.functional.object");
+define(["./functional/lambda", "./functional/array", "./functional/object"], function(df){
+	return df;
+});
diff --git a/dojox/lang/functional/array.js b/dojox/lang/functional/array.js
index 36e105e..4d49b89 100755
--- a/dojox/lang/functional/array.js
+++ b/dojox/lang/functional/array.js
@@ -1,6 +1,5 @@
-dojo.provide("dojox.lang.functional.array");
-
-dojo.require("dojox.lang.functional.lambda");
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "./lambda"], 
+	function(dojo, lang, arr, win, df){
 
 // This module adds high-level functions and related constructs:
 //	- array-processing functions similar to standard JS functions
@@ -15,19 +14,21 @@ dojo.require("dojox.lang.functional.lambda");
 //	- take a string as the array argument
 //	- take an iterator objects as the array argument
 
-(function(){
-	var d = dojo, df = dojox.lang.functional, empty = {};
+	var empty = {};
 
-	d.mixin(df, {
+/*=====
+	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.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || d.global; f = df.lambda(f);
+			o = o || win.global; f = df.lambda(f);
 			var t = [], v, i, n;
-			if(d.isArray(a)){
+			if(lang.isArray(a)){
 				// array
 				for(i = 0, n = a.length; i < n; ++i){
 					v = a[i];
@@ -53,9 +54,9 @@ dojo.require("dojox.lang.functional.lambda");
 		forEach: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
 			// summary: executes a provided function once per array element.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || d.global; f = df.lambda(f);
+			o = o || win.global; f = df.lambda(f);
 			var i, n;
-			if(d.isArray(a)){
+			if(lang.isArray(a)){
 				// array
 				for(i = 0, n = a.length; i < n; f.call(o, a[i], i, a), ++i);
 			}else if(typeof a.hasNext == "function" && typeof a.next == "function"){
@@ -75,9 +76,9 @@ dojo.require("dojox.lang.functional.lambda");
 			// 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 || d.global; f = df.lambda(f);
+			o = o || win.global; f = df.lambda(f);
 			var t, n, i;
-			if(d.isArray(a)){
+			if(lang.isArray(a)){
 				// array
 				t = new Array(n = a.length);
 				for(i = 0; i < n; t[i] = f.call(o, a[i], i, a), ++i);
@@ -100,9 +101,9 @@ dojo.require("dojox.lang.functional.lambda");
 			// 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 || d.global; f = df.lambda(f);
+			o = o || win.global; f = df.lambda(f);
 			var i, n;
-			if(d.isArray(a)){
+			if(lang.isArray(a)){
 				// array
 				for(i = 0, n = a.length; i < n; ++i){
 					if(!f.call(o, a[i], i, a)){
@@ -132,9 +133,9 @@ dojo.require("dojox.lang.functional.lambda");
 			// 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 || d.global; f = df.lambda(f);
+			o = o || win.global; f = df.lambda(f);
 			var i, n;
-			if(d.isArray(a)){
+			if(lang.isArray(a)){
 				// array
 				for(i = 0, n = a.length; i < n; ++i){
 					if(f.call(o, a[i], i, a)){
@@ -161,4 +162,6 @@ dojo.require("dojox.lang.functional.lambda");
 			return false;	// Boolean
 		}
 	});
-})();
+	
+	return df;
+});
diff --git a/dojox/lang/functional/fold.js b/dojox/lang/functional/fold.js
index e49b7c9..32887ff 100755
--- a/dojox/lang/functional/fold.js
+++ b/dojox/lang/functional/fold.js
@@ -1,6 +1,5 @@
-dojo.provide("dojox.lang.functional.fold");
-
-dojo.require("dojox.lang.functional.lambda");
+define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "./lambda"],
+	function(lang, arr, win, df){
 
 // This module adds high-level functions and related constructs:
 //	- "fold" family of functions
@@ -18,19 +17,21 @@ dojo.require("dojox.lang.functional.lambda");
 //	- take a string as the array argument
 //	- take an iterator objects as the array argument (only foldl, foldl1, and reduce)
 
-(function(){
-	var d = dojo, df = dojox.lang.functional, empty = {};
+	var empty = {};
 
-	d.mixin(df, {
+/*=====
+	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.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || d.global; f = df.lambda(f);
+			o = o || win.global; f = df.lambda(f);
 			var i, n;
-			if(d.isArray(a)){
+			if(lang.isArray(a)){
 				// array
 				for(i = 0, n = a.length; i < n; z = f.call(o, z, a[i], i, a), ++i);
 			}else if(typeof a.hasNext == "function" && typeof a.next == "function"){
@@ -50,9 +51,9 @@ dojo.require("dojox.lang.functional.lambda");
 			// 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 || d.global; f = df.lambda(f);
+			o = o || win.global; f = df.lambda(f);
 			var z, i, n;
-			if(d.isArray(a)){
+			if(lang.isArray(a)){
 				// array
 				z = a[0];
 				for(i = 1, n = a.length; i < n; z = f.call(o, z, a[i], i, a), ++i);
@@ -83,7 +84,7 @@ dojo.require("dojox.lang.functional.lambda");
 			//	to left using a seed value as a starting point; returns the final
 			//	value.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || d.global; f = df.lambda(f);
+			o = o || win.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
 		},
@@ -91,7 +92,7 @@ dojo.require("dojox.lang.functional.lambda");
 			// 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 || d.global; f = df.lambda(f);
+			o = o || win.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
@@ -111,10 +112,10 @@ dojo.require("dojox.lang.functional.lambda");
 		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 || d.global; f = df.lambda(f); g = df.lambda(g); pr = df.lambda(pr);
+			o = o || win.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 95d68d4..deeb064 100755
--- a/dojox/lang/functional/lambda.js
+++ b/dojox/lang/functional/lambda.js
@@ -1,4 +1,5 @@
-dojo.provide("dojox.lang.functional.lambda");
+define(["../..", "dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array"], function(dojox, dojo, 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
@@ -17,8 +18,7 @@ dojo.provide("dojox.lang.functional.lambda");
 //	- converts strings to functions
 //	- converts arrays to a functional composition
 
-(function(){
-	var df = dojox.lang.functional, lcache = {};
+	var lcache = {};
 
 	// split() is augmented on IE6 to ensure the uniform behavior
 	var split = "ab".split(/a*/).length > 1 ? String.prototype.split :
@@ -57,7 +57,7 @@ dojo.provide("dojox.lang.functional.lambda");
 				var vars = s.
 					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 = {};
-				dojo.forEach(vars, function(v){
+				arr.forEach(vars, function(v){
 					if(!(v in t)){
 						args.push(v);
 						t[v] = 1;
@@ -80,7 +80,7 @@ dojo.provide("dojox.lang.functional.lambda");
 					function(x){ return x; };
 	};
 
-	dojo.mixin(df, {
+	lang.mixin(df, {
 		// lambda
 		rawLambda: function(/*String*/ s){
 			// summary:
@@ -127,4 +127,6 @@ dojo.provide("dojox.lang.functional.lambda");
 			lcache = {};
 		}
 	});
-})();
+	
+	return df;
+});
diff --git a/dojox/lang/functional/object.js b/dojox/lang/functional/object.js
index 525ccd8..b186b5b 100755
--- a/dojox/lang/functional/object.js
+++ b/dojox/lang/functional/object.js
@@ -1,6 +1,4 @@
-dojo.provide("dojox.lang.functional.object");
-
-dojo.require("dojox.lang.functional.lambda");
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/window", "./lambda"], function(dojo, lang, win, df){
 
 // This module adds high-level functions and related constructs:
 //	- object/dictionary helpers
@@ -10,10 +8,12 @@ dojo.require("dojox.lang.functional.lambda");
 //	- skip all attributes that are present in the empty object
 //		(IE and/or 3rd-party libraries).
 
-(function(){
-	var d = dojo, df = dojox.lang.functional, empty = {};
+	var empty = {};
 
-	d.mixin(df, {
+/*=====
+	var df = dojox.lang.functional;
+ =====*/
+	lang.mixin(df, {
 		// object helpers
 		keys: function(/*Object*/ obj){
 			// summary: returns an array of all keys in the object
@@ -38,7 +38,7 @@ dojo.require("dojox.lang.functional.lambda");
 		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 || d.global; f = df.lambda(f);
+			o = o || win.global; f = df.lambda(f);
 			var t = {}, v, i;
 			for(i in obj){
 				if(!(i in empty)){
@@ -50,7 +50,7 @@ dojo.require("dojox.lang.functional.lambda");
 		},
 		forIn: function(/*Object*/ obj, /*Function|String|Array*/ f, /*Object?*/ o){
 			// summary: iterates over all object attributes.
-			o = o || d.global; f = df.lambda(f);
+			o = o || win.global; f = df.lambda(f);
 			for(var i in obj){
 				if(!(i in empty)){
 					f.call(o, obj[i], i, obj);
@@ -61,7 +61,7 @@ dojo.require("dojox.lang.functional.lambda");
 		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 || d.global; f = df.lambda(f);
+			o = o || win.global; f = df.lambda(f);
 			var t = {}, i;
 			for(i in obj){
 				if(!(i in empty)){
@@ -71,4 +71,6 @@ dojo.require("dojox.lang.functional.lambda");
 			return t;	// Object
 		}
 	});
-})();
+	
+	return df;
+});
diff --git a/dojox/lang/functional/reversed.js b/dojox/lang/functional/reversed.js
index 656f36a..6659366 100755
--- a/dojox/lang/functional/reversed.js
+++ b/dojox/lang/functional/reversed.js
@@ -1,7 +1,5 @@
-dojo.provide("dojox.lang.functional.reversed");
-
-dojo.require("dojox.lang.functional.lambda");
-
+define(["dojo/_base/lang", "dojo/_base/window" ,"./lambda"], 
+	function(lang, win, df){
 // This module adds high-level functions and related constructs:
 //	- reversed versions of array-processing functions similar to standard JS functions
 
@@ -14,17 +12,17 @@ dojo.require("dojox.lang.functional.lambda");
 //	- operate on dense arrays
 //	- take a string as the array argument
 
-(function(){
-	var d = dojo, df = dojox.lang.functional;
-
-	d.mixin(df, {
+/*=====
+	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.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || d.global; f = df.lambda(f);
+			o = o || win.global; f = df.lambda(f);
 			var t = [], v, i = a.length - 1;
 			for(; i >= 0; --i){
 				v = a[i];
@@ -35,14 +33,14 @@ dojo.require("dojox.lang.functional.lambda");
 		forEachRev: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
 			// summary: executes a provided function once per array element.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || d.global; f = df.lambda(f);
+			o = o || win.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.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || d.global; f = df.lambda(f);
+			o = o || win.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
@@ -51,7 +49,7 @@ dojo.require("dojox.lang.functional.lambda");
 			// 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 || d.global; f = df.lambda(f);
+			o = o || win.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
@@ -63,7 +61,7 @@ dojo.require("dojox.lang.functional.lambda");
 			// 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 || d.global; f = df.lambda(f);
+			o = o || win.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
@@ -72,4 +70,6 @@ dojo.require("dojox.lang.functional.lambda");
 			return false;	// Boolean
 		}
 	});
-})();
+	
+	return df;
+});
diff --git a/dojox/lang/functional/scan.js b/dojox/lang/functional/scan.js
index 35978f6..444b46a 100755
--- a/dojox/lang/functional/scan.js
+++ b/dojox/lang/functional/scan.js
@@ -1,6 +1,4 @@
-dojo.provide("dojox.lang.functional.scan");
-
-dojo.require("dojox.lang.functional.lambda");
+define(["dojo/_base/kernel", "dojo/_base/lang", "./lambda"], function(d, darray, df){
 
 // This module adds high-level functions and related constructs:
 //	- "scan" family of functions
@@ -15,8 +13,7 @@ dojo.require("dojox.lang.functional.lambda");
 //	- take a string as the array argument
 //	- take an iterator objects as the array argument (only scanl, and scanl1)
 
-(function(){
-	var d = dojo, df = dojox.lang.functional, empty = {};
+	var empty = {};
 
 	d.mixin(df, {
 		// classic reduce-class functions
@@ -63,11 +60,11 @@ dojo.require("dojox.lang.functional.lambda");
 				// iterator
 				if(a.hasNext()){
 					t = [z = a.next()];
-					for(var i = 1; a.hasNext(); t.push(z = f.call(o, z, a.next(), i++, a)));
+					for(i = 1; a.hasNext(); t.push(z = f.call(o, z, a.next(), i++, a)));
 				}
 			}else{
 				// object/dictionary
-				for(var i in a){
+				for(i in a){
 					if(!(i in empty)){
 						if(first){
 							t = [z = a[i]];
@@ -103,4 +100,4 @@ dojo.require("dojox.lang.functional.lambda");
 			return t;	// Array
 		}
 	});
-})();
+});
diff --git a/dojox/lang/functional/sequence.js b/dojox/lang/functional/sequence.js
index 7e03054..bd1b398 100755
--- a/dojox/lang/functional/sequence.js
+++ b/dojox/lang/functional/sequence.js
@@ -1,6 +1,4 @@
-dojo.provide("dojox.lang.functional.sequence");
-
-dojo.require("dojox.lang.functional.lambda");
+define(["dojo/_base/lang", "./lambda"], function(lang, df){
 
 // This module adds high-level functions and related constructs:
 //	- sequence generators
@@ -11,15 +9,16 @@ dojo.require("dojox.lang.functional.lambda");
 // Defined methods:
 //	- take any valid lambda argument as the functional argument
 
-(function(){
-	var d = dojo, df = dojox.lang.functional;
+/*=====
+	var df = dojox.lang.functional;
+ =====*/
 
-	d.mixin(df, {
+	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 || d.global; f = df.lambda(f);
+			o = o || dojo.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);
@@ -28,10 +27,12 @@ dojo.require("dojox.lang.functional.lambda");
 		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 || d.global; f = df.lambda(f); pr = df.lambda(pr);
+			o = o || dojo.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
 		}
 	});
-})();
+	
+	return df;
+});
diff --git a/dojox/lang/utils.js b/dojox/lang/utils.js
index 519437a..56dcf7c 100644
--- a/dojox/lang/utils.js
+++ b/dojox/lang/utils.js
@@ -1,7 +1,8 @@
-dojo.provide("dojox.lang.utils");
-
-(function(){
-	var empty = {}, du = dojox.lang.utils, opts = Object.prototype.toString;
+define(["..", "dojo/_base/lang"], 
+  function(dojox, lang){
+	var du = lang.getObject("lang.utils", true, dojox);
+	
+	var empty = {}, opts = Object.prototype.toString;
 
 	var clone = function(o){
 		if(o){
@@ -9,13 +10,13 @@ dojo.provide("dojox.lang.utils");
 				case "[object Array]":
 					return o.slice(0);
 				case "[object Object]":
-					return dojo.delegate(o);
+					return lang.delegate(o);
 			}
 		}
 		return o;
 	}
 	
-	dojo.mixin(du, {
+	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.
@@ -80,7 +81,7 @@ dojo.provide("dojox.lang.utils");
 						return mixin.slice(0);
 					case "[object Object]":
 						if(mtype == otype && object){
-							t = dojo.delegate(object);
+							t = lang.delegate(object);
 							for(i in mixin){
 								if(i in object){
 									l = object[i];
@@ -89,15 +90,17 @@ dojo.provide("dojox.lang.utils");
 										t[i] = du.merge(l, m);
 									}
 								}else{
-									t[i] = dojo.clone(mixin[i]);
+									t[i] = lang.clone(mixin[i]);
 								}
 							}
 							return t;
 						}
-						return dojo.clone(mixin);
+						return lang.clone(mixin);
 				}
 			}
 			return mixin;
 		}
 	});
-})();
+	
+	return du;
+});
diff --git a/dojox/layout/ContentPane.js b/dojox/layout/ContentPane.js
index 12e328b..3bdb1dd 100755
--- a/dojox/layout/ContentPane.js
+++ b/dojox/layout/ContentPane.js
@@ -1,9 +1,13 @@
-dojo.provide("dojox.layout.ContentPane");
+define([
+	"dojo/_base/lang",
+	"dojo/_base/xhr",
+	"dijit/layout/ContentPane",
+	"dojox/html/_base",
+	"dojo/_base/declare"
+], function (lang, xhrUtil, ContentPane, htmlUtil, declare) {
 
-dojo.require("dijit.layout.ContentPane");
-dojo.require("dojox.html._base");
-
-dojo.declare("dojox.layout.ContentPane", dijit.layout.ContentPane, {
+/*===== 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=''
@@ -43,20 +47,10 @@ dojo.declare("dojox.layout.ContentPane", dijit.layout.ContentPane, {
 	// NOTE this name might change in the near future
 	scriptHasHooks: false,
 
-	/*======
-	// ioMethod: dojo.xhrGet|dojo.xhrPost
-	//		reference to the method that should grab the content
-	ioMethod: dojo.xhrGet,
-	
-	// ioArgs: Object
-	//		makes it possible to add custom args to xhrGet, like ioArgs.headers['X-myHeader'] = 'true'
-	ioArgs: {},
-	======*/
-
 	constructor: function(){
 		// init per instance properties, initializer doesn't work here because how things is hooked up in dijit._Widget
 		this.ioArgs = {};
-		this.ioMethod = dojo.xhrGet;
+		this.ioMethod = xhrUtil.get;
 	},
 
 	onExecError: function(e){
@@ -70,11 +64,11 @@ dojo.declare("dojox.layout.ContentPane", dijit.layout.ContentPane, {
 		// override dijit.layout.ContentPane._setContent, to enable path adjustments
 		
 		var setter = this._contentSetter;
-		if(! (setter && setter instanceof dojox.html._ContentSetter)) {
-			setter = this._contentSetter = new dojox.html._ContentSetter({
+		if(! (setter && setter instanceof htmlUtil._ContentSetter)) {
+			setter = this._contentSetter = new htmlUtil._ContentSetter({
 				node: this.containerNode,
-				_onError: dojo.hitch(this, this._onError),
-				onContentError: dojo.hitch(this, function(e){
+				_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);
@@ -102,3 +96,4 @@ dojo.declare("dojox.layout.ContentPane", dijit.layout.ContentPane, {
 	}
 	// could put back _renderStyles by wrapping/aliasing dojox.html._ContentSetter.prototype._renderStyles
 });
+});
\ No newline at end of file
diff --git a/dojox/layout/DragPane.js b/dojox/layout/DragPane.js
index b4254bb..93405fb 100644
--- a/dojox/layout/DragPane.js
+++ b/dojox/layout/DragPane.js
@@ -1,8 +1,7 @@
-dojo.provide("dojox.layout.DragPane");
-
-dojo.require("dijit._Widget");
-
-dojo.declare("dojox.layout.DragPane", dijit._Widget, {
+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
 	//
 	// description:
@@ -26,20 +25,20 @@ dojo.declare("dojox.layout.DragPane", dijit._Widget, {
 		// summary: mousedown handler, start the dragging
 		var t = this.domNode;
 		e.preventDefault();
-		dojo.style(t, "cursor", "move");
+		domStyle.set(t, "cursor", "move");
 		this._x = e.pageX;
 		this._y = e.pageY;
 		if ((this._x < t.offsetLeft + t.clientWidth) &&
 			(this._y < t.offsetTop + t.clientHeight)) {
-			dojo.setSelectable(t,false);
+			htmlUtil.setSelectable(t,false);
 			this._mover = this.connect(t, "onmousemove", "_move");
 		}
 	},
 	
 	_up: function(e){
 		// summary: mouseup handler, stop the dragging
-		dojo.setSelectable(this.domNode,true);
-		dojo.style(this.domNode, "cursor", "pointer");
+		htmlUtil.setSelectable(this.domNode,true);
+		domStyle.set(this.domNode, "cursor", "pointer");
 		this._mover && this.disconnect(this._mover);
 		delete this._mover;
 	},
@@ -57,3 +56,4 @@ dojo.declare("dojox.layout.DragPane", dijit._Widget, {
 	}
 	
 });
+});
\ No newline at end of file
diff --git a/dojox/layout/ExpandoPane.js b/dojox/layout/ExpandoPane.js
index 562e295..5777d93 100644
--- a/dojox/layout/ExpandoPane.js
+++ b/dojox/layout/ExpandoPane.js
@@ -1,13 +1,18 @@
-dojo.provide("dojox.layout.ExpandoPane");
-dojo.experimental("dojox.layout.ExpandoPane"); // just to show it can be done?
+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?
 
-dojo.require("dijit.layout.ContentPane");
-dojo.require("dijit._Templated");
-dojo.require("dijit._Contained");
-
-dojo.declare("dojox.layout.ExpandoPane",
-	[dijit.layout.ContentPane, dijit._Templated, dijit._Contained, dijit._Container],
-	{
+return declare("dojox.layout.ExpandoPane", [ContentPane, TemplatedMixin, Contained, Container],{
 	// summary: An experimental collapsing-pane for dijit.layout.BorderContainer
 	//
 	// description:
@@ -18,19 +23,19 @@ dojo.declare("dojox.layout.ExpandoPane",
 	//maxHeight: "",
 	//maxWidth: "",
 	//splitter: false,
-	attributeMap: dojo.delegate(dijit.layout.ContentPane.prototype.attributeMap, {
-	        title: { node: "titleNode", type: "innerHTML" }
+	attributeMap: lang.delegate(ContentPane.prototype.attributeMap, {
+		title: { node: "titleNode", type: "innerHTML" }
 	}),
 	
-	templateString: dojo.cache("dojox.layout","resources/ExpandoPane.html"),
+	templateString: template,
 
 	// easeOut: String|Function
 	//		easing function used to hide pane
-	easeOut: "dojo._DefaultEasing",
+	easeOut: "dojo._DefaultEasing", // FIXME: This won't work with globalless AMD
 	
 	// easeIn: String|Function
 	//		easing function use to show pane
-	easeIn: "dojo._DefaultEasing",
+	easeIn: "dojo._DefaultEasing", // FIXME: This won't work with globalless AMD
 	
 	// duration: Integer
 	//		duration to run show/hide animations
@@ -58,11 +63,11 @@ dojo.declare("dojox.layout.ExpandoPane",
 
 		this._isHorizontal = true;
 		
-		if(dojo.isString(this.easeOut)){
-			this.easeOut = dojo.getObject(this.easeOut);
+		if(lang.isString(this.easeOut)){
+			this.easeOut = lang.getObject(this.easeOut);
 		}
-		if(dojo.isString(this.easeIn)){
-			this.easeIn = dojo.getObject(this.easeIn);
+		if(lang.isString(this.easeIn)){
+			this.easeIn = lang.getObject(this.easeIn);
 		}
 	
 		var thisClass = "", rtl = !this.isLeftToRight();
@@ -83,11 +88,11 @@ dojo.declare("dojox.layout.ExpandoPane",
 					thisClass = "Bottom";
 					break;
 			}
-			dojo.addClass(this.domNode, "dojoxExpando" + thisClass);
-			dojo.addClass(this.iconNode, "dojoxExpandoIcon" + thisClass);
+			domClass.add(this.domNode, "dojoxExpando" + thisClass);
+			domClass.add(this.iconNode, "dojoxExpandoIcon" + thisClass);
 			this._isHorizontal = /top|bottom/.test(this.region);
 		}
-		dojo.style(this.domNode, {
+		domStyle.set(this.domNode, {
 			overflow: "hidden",
 			padding:0
 		});
@@ -95,7 +100,7 @@ dojo.declare("dojox.layout.ExpandoPane",
 		this.connect(this.domNode, "ondblclick", this.previewOnDblClick ? "preview" : "toggle");
 		
 		if(this.previewOnDblClick){
-			this.connect(this.getParent(), "_layoutChildren", dojo.hitch(this, function(){
+			this.connect(this.getParent(), "_layoutChildren", lang.hitch(this, function(){
 				this._isonlypreview = false;
 			}));
 		}
@@ -105,19 +110,19 @@ dojo.declare("dojox.layout.ExpandoPane",
 	_startupSizes: function(){
 		
 		this._container = this.getParent();
-		this._closedSize = this._titleHeight = dojo.marginBox(this.titleWrapper).h;
+		this._closedSize = this._titleHeight = domGeom.getMarginBox(this.titleWrapper).h;
 		
 		if(this.splitter){
 			// find our splitter and tie into it's drag logic
 			var myid = this.id;
-			dijit.registry.filter(function(w){
-				return w && w.child && w.child.id == myid;
-			}).forEach(dojo.hitch(this,function(w){
-				this.connect(w,"_stopDrag","_afterResize");
-			}));
+			arrayUtil.forEach(dijit.registry.toArray(), function(w){
+				if(w && w.child && w.child.id == myid){
+					this.connect(w,"_stopDrag","_afterResize");
+				}
+			}, this);
 		}
 		
-		this._currentSize = dojo.contentBox(this.domNode);	// TODO: can compute this from passed in value to resize(), see _LayoutWidget for example
+		this._currentSize = domGeom.getContentBox(this.domNode);	// TODO: can compute this from passed in value to resize(), see _LayoutWidget for example
 		this._showSize = this._currentSize[(this._isHorizontal ? "h" : "w")];
 		this._setupAnims();
 
@@ -134,7 +139,7 @@ dojo.declare("dojox.layout.ExpandoPane",
 	
 	_afterResize: function(e){
 		var tmp = this._currentSize;						// the old size
-		this._currentSize = dojo.marginBox(this.domNode);	// the new size
+		this._currentSize = domGeom.getMarginBox(this.domNode);	// the new size
 		var n = this._currentSize[(this._isHorizontal ? "h" : "w")]
 		if(n > this._titleHeight){
 			if(!this._showing){
@@ -154,7 +159,7 @@ dojo.declare("dojox.layout.ExpandoPane",
 	
 	_setupAnims: function(){
 		// summary: Create the show and hide animations
-		dojo.forEach(this._animConnects, dojo.disconnect);
+		arrayUtil.forEach(this._animConnects, connectUtil.disconnect);
 		
 		var _common = {
 				node:this.domNode,
@@ -173,18 +178,18 @@ dojo.declare("dojox.layout.ExpandoPane",
 			end: this._closedSize
 		};
 		
-		this._showAnim = dojo.animateProperty(dojo.mixin(_common,{
+		this._showAnim = baseFx.animateProperty(lang.mixin(_common,{
 			easing:this.easeIn,
 			properties: showProps
 		}));
-		this._hideAnim = dojo.animateProperty(dojo.mixin(_common,{
+		this._hideAnim = baseFx.animateProperty(lang.mixin(_common,{
 			easing:this.easeOut,
 			properties: hideProps
 		}));
 
 		this._animConnects = [
-			dojo.connect(this._showAnim, "onEnd", this, "_showEnd"),
-			dojo.connect(this._hideAnim, "onEnd", this, "_hideEnd")
+			connectUtil.connect(this._showAnim, "onEnd", this, "_showEnd"),
+			connectUtil.connect(this._hideAnim, "onEnd", this, "_hideEnd")
 		];
 	},
 	
@@ -212,9 +217,9 @@ dojo.declare("dojox.layout.ExpandoPane",
 	
 	_hideWrapper: function(){
 		// summary: Set the Expando state to "closed"
-		dojo.addClass(this.domNode, "dojoxExpandoClosed");
+		domClass.add(this.domNode, "dojoxExpandoClosed");
 		
-		dojo.style(this.cwrapper,{
+		domStyle.set(this.cwrapper,{
 			visibility: "hidden",
 			opacity: "0",
 			overflow: "hidden"
@@ -223,16 +228,16 @@ dojo.declare("dojox.layout.ExpandoPane",
 	
 	_showEnd: function(){
 		// summary: Common animation onEnd code - "unclose"
-		dojo.style(this.cwrapper, {
+		domStyle.set(this.cwrapper, {
 			opacity: 0,
 			visibility:"visible"
 		});
-		dojo.anim(this.cwrapper, {
+		baseFx.anim(this.cwrapper, {
 			opacity: this._isonlypreview ? this.previewOpacity : 1
 		}, 227);
-		dojo.removeClass(this.domNode, "dojoxExpandoClosed");
+		domClass.remove(this.domNode, "dojoxExpandoClosed");
 		if(!this._isonlypreview){
-			setTimeout(dojo.hitch(this._container, "layout"), 15);
+			setTimeout(lang.hitch(this._container, "layout"), 15);
 		}else{
 			this._previewShowing = true;
 			this.resize();
@@ -244,7 +249,7 @@ dojo.declare("dojox.layout.ExpandoPane",
 
 		// every time we hide, reset the "only preview" state
 		if(!this._isonlypreview){
-			setTimeout(dojo.hitch(this._container, "layout"), 25);
+			setTimeout(lang.hitch(this._container, "layout"), 25);
 		}else{
 			this._previewShowing = false;
 		}
@@ -261,15 +266,15 @@ dojo.declare("dojox.layout.ExpandoPane",
 		if(!this._hasSizes){ this._startupSizes(newSize); }
 		
 		// compute size of container (ie, size left over after title bar)
-		var currentSize = dojo.marginBox(this.domNode);
+		var currentSize = domGeom.getMarginBox(this.domNode);
 		this._contentBox = {
 			w: newSize && "w" in newSize ? newSize.w : currentSize.w,
 			h: (newSize && "h" in newSize ? newSize.h : currentSize.h) - this._titleHeight
 		};
-		dojo.style(this.containerNode, "height", this._contentBox.h + "px");
+		domStyle.set(this.containerNode, "height", this._contentBox.h + "px");
 
 		if(newSize){
-			dojo.marginBox(this.domNode, newSize);
+			domGeom.setMarginBox(this.domNode, newSize);
 		}
 
 		this._layoutChildren();
@@ -277,7 +282,7 @@ dojo.declare("dojox.layout.ExpandoPane",
 	
 	_trap: function(e){
 		// summary: Trap stray events
-		dojo.stopEvent(e);
+		eventUtil.stop(e);
 	}
-
+});
 });
diff --git a/dojox/layout/FloatingPane.js b/dojox/layout/FloatingPane.js
index 0797708..6959486 100644
--- a/dojox/layout/FloatingPane.js
+++ b/dojox/layout/FloatingPane.js
@@ -1,25 +1,26 @@
-dojo.provide("dojox.layout.FloatingPane");
-dojo.experimental("dojox.layout.FloatingPane");
-
-dojo.require("dojo.window");
-
-dojo.require("dijit._Templated");
-dojo.require("dijit._Widget");
-dojo.require("dojo.dnd.Moveable");
-
-dojo.require("dojox.layout.ContentPane");
-dojo.require("dojox.layout.ResizeHandle");
-
-dojo.declare("dojox.layout.FloatingPane",
-	[ dojox.layout.ContentPane, dijit._Templated ],
-	{
+define(["dojo/_base/kernel","dojo/_base/lang","dojo/_base/window","dojo/_base/declare",
+		"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(
+	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;
+=====*/
+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]
+	//		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
@@ -77,15 +78,15 @@ dojo.declare("dojox.layout.FloatingPane",
 	_allFPs: [],
 	_startZ: 100,
 
-	templateString: dojo.cache("dojox.layout","resources/FloatingPane.html"),
+	templateString: template,
 	
-	attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
+	attributeMap: lang.delegate(Widget.prototype.attributeMap, {
 		title: { type:"innerHTML", node:"titleNode" }
 	}),
 	
 	postCreate: function(){
 		this.inherited(arguments);
-		new dojo.dnd.Moveable(this.domNode,{ handle: this.focusNode });
+		new Moveable(this.domNode,{ handle: this.focusNode });
 		//this._listener = dojo.subscribe("/dnd/move/start",this,"bringToTop");
 
 		if(!this.dockable){ this.dockNode.style.display = "none"; }
@@ -97,13 +98,13 @@ dojo.declare("dojox.layout.FloatingPane",
 		if(!this.resizable){
 			this.resizeHandle.style.display = "none";
 		}else{
-			this.domNode.style.width = dojo.marginBox(this.domNode).w + "px";
+			this.domNode.style.width = domGeom.getMarginBox(this.domNode).w + "px";
 		}
 		this._allFPs.push(this);
 		this.domNode.style.position = "absolute";
 		
-		this.bgIframe = new dijit.BackgroundIframe(this.domNode);
-		this._naturalState = dojo.coords(this.domNode);
+		this.bgIframe = new BackgroundIframe(this.domNode);
+		this._naturalState = domGeom.position(this.domNode);
 	},
 	
 	startup: function(){
@@ -112,13 +113,13 @@ dojo.declare("dojox.layout.FloatingPane",
 		this.inherited(arguments);
 
 		if(this.resizable){
-			if(dojo.isIE){
+			if(has("ie")){
 				this.canvas.style.overflow = "auto";
 			}else{
 				this.containerNode.style.overflow = "auto";
 			}
 			
-			this._resizeHandle = new dojox.layout.ResizeHandle({
+			this._resizeHandle = new ResizeHandle({
 				targetId: this.id,
 				resizeAxis: this.resizeAxis
 			},this.resizeHandle);
@@ -143,13 +144,13 @@ dojo.declare("dojox.layout.FloatingPane",
 				// once, and use it on empty OR invalid dockTo="" node?
 				if(tmpName){
 					tmpId = tmpName;
-					tmpNode = dojo.byId(tmpName);
+					tmpNode = dom.byId(tmpName);
 				}else{
-					tmpNode = dojo.create('div', null, dojo.body());
-					dojo.addClass(tmpNode,"dojoxFloatingDockDefault");
+					tmpNode = domConstruct.create('div', null, winUtil.body());
+					domClass.add(tmpNode,"dojoxFloatingDockDefault");
 					tmpId = 'dojoxGlobalFloatingDock';
 				}
-				this.dockTo = new dojox.layout.Dock({ id: tmpId, autoPosition: "south" }, tmpNode);
+				this.dockTo = new Dock({ id: tmpId, autoPosition: "south" }, tmpNode);
 				this.dockTo.startup();
 			}
 			
@@ -162,33 +163,32 @@ dojo.declare("dojox.layout.FloatingPane",
 		this.connect(this.domNode,	"onmousedown","bringToTop");
 
 		// Initial resize to give child the opportunity to lay itself out
-		this.resize(dojo.coords(this.domNode));
+		this.resize(domGeom.position(this.domNode));
 		
 		this._started = true;
 	},
 
 	setTitle: function(/* String */ title){
 		// summary: Update the Title bar with a new string
-		dojo.deprecated("pane.setTitle", "Use pane.set('title', someTitle)", "2.0");
+		kernel.deprecated("pane.setTitle", "Use pane.set('title', someTitle)", "2.0");
 		this.set("title", title);
-		// this.setTitle = dojo.hitch(this, "setTitle") ??
 	},
 		
 	close: function(){
 		// summary: Close and destroy this widget
 		if(!this.closable){ return; }
-		dojo.unsubscribe(this._listener);
-		this.hide(dojo.hitch(this,function(){
+		connectUtil.unsubscribe(this._listener);
+		this.hide(lang.hitch(this,function(){
 			this.destroyRecursive();
 		}));
 	},
 
 	hide: function(/* Function? */ callback){
 		// summary: Close, but do not destroy this FloatingPane
-		dojo.fadeOut({
+		baseFx.fadeOut({
 			node:this.domNode,
 			duration:this.duration,
-			onEnd: dojo.hitch(this,function() {
+			onEnd: lang.hitch(this,function() {
 				this.domNode.style.display = "none";
 				this.domNode.style.visibility = "hidden";
 				if(this.dockTo && this.dockable){
@@ -203,8 +203,8 @@ dojo.declare("dojox.layout.FloatingPane",
 
 	show: function(/* Function? */callback){
 		// summary: Show the FloatingPane
-		var anim = dojo.fadeIn({node:this.domNode, duration:this.duration,
-			beforeBegin: dojo.hitch(this,function(){
+		var anim = baseFx.fadeIn({node:this.domNode, duration:this.duration,
+			beforeBegin: lang.hitch(this,function(){
 				this.domNode.style.display = "";
 				this.domNode.style.visibility = "visible";
 				if (this.dockTo && this.dockable) { this.dockTo._positionDock(null); }
@@ -216,32 +216,32 @@ dojo.declare("dojox.layout.FloatingPane",
 				}
 			})
 		}).play();
-		this.resize(dojo.coords(this.domNode));
+		this.resize(domGeom.position(this.domNode));
 		this._onShow(); // lazy load trigger
 	},
 
 	minimize: function(){
 		// summary: Hide and dock the FloatingPane
-		if(!this._isDocked){ this.hide(dojo.hitch(this,"_dock")); }
+		if(!this._isDocked){ this.hide(lang.hitch(this,"_dock")); }
 	},
 
 	maximize: function(){
 		// summary: Make this FloatingPane full-screen (viewport)
 		if(this._maximized){ return; }
-		this._naturalState = dojo.position(this.domNode);
+		this._naturalState = domGeom.position(this.domNode);
 		if(this._isDocked){
 			this.show();
-			setTimeout(dojo.hitch(this,"maximize"),this.duration);
+			setTimeout(lang.hitch(this,"maximize"),this.duration);
 		}
-		dojo.addClass(this.focusNode,"floatingPaneMaximized");
-		this.resize(dojo.window.getBox());
+		domClass.add(this.focusNode,"floatingPaneMaximized");
+		this.resize(windowLib.getBox());
 		this._maximized = true;
 	},
 
 	_restore: function(){
 		if(this._maximized){
 			this.resize(this._naturalState);
-			dojo.removeClass(this.focusNode,"floatingPaneMaximized");
+			domClass.remove(this.focusNode,"floatingPaneMaximized");
 			this._maximized = false;
 		}
 	},
@@ -261,13 +261,15 @@ dojo.declare("dojox.layout.FloatingPane",
 		// From the ResizeHandle we only get width and height information
 		var dns = this.domNode.style;
 		if("t" in dim){ dns.top = dim.t + "px"; }
+		else if("y" in dim){ dns.top = dim.y + "px"; }
 		if("l" in dim){ dns.left = dim.l + "px"; }
+		else if("x" in dim){ dns.left = dim.x + "px"; }
 		dns.width = dim.w + "px";
 		dns.height = dim.h + "px";
 
 		// Now resize canvas
 		var mbCanvas = { l: 0, t: 0, w: dim.w, h: (dim.h - this.focusNode.offsetHeight) };
-		dojo.marginBox(this.canvas, mbCanvas);
+		domGeom.setMarginBox(this.canvas, mbCanvas);
 
 		// If the single child can resize, forward resize event to it so it can
 		// fit itself properly into the content area
@@ -279,7 +281,7 @@ dojo.declare("dojox.layout.FloatingPane",
 	
 	bringToTop: function(){
 		// summary: bring this FloatingPane above all other panes
-		var windows = dojo.filter(
+		var windows = arrayUtil.filter(
 			this._allFPs,
 			function(i){
 				return i !== this;
@@ -290,16 +292,16 @@ dojo.declare("dojox.layout.FloatingPane",
 		});
 		windows.push(this);
 		
-		dojo.forEach(windows, function(w, x){
+		arrayUtil.forEach(windows, function(w, x){
 			w.domNode.style.zIndex = this._startZ + (x * 2);
-			dojo.removeClass(w.domNode, "dojoxFloatingPaneFg");
+			domClass.remove(w.domNode, "dojoxFloatingPaneFg");
 		}, this);
-		dojo.addClass(this.domNode, "dojoxFloatingPaneFg");
+		domClass.add(this.domNode, "dojoxFloatingPaneFg");
 	},
 	
 	destroy: function(){
 		// summary: Destroy this FloatingPane completely
-		this._allFPs.splice(dojo.indexOf(this._allFPs, this), 1);
+		this._allFPs.splice(arrayUtil.indexOf(this._allFPs, this), 1);
 		if(this._resizeHandle){
 			this._resizeHandle.destroy();
 		}
@@ -307,10 +309,7 @@ dojo.declare("dojox.layout.FloatingPane",
 	}
 });
 
-
-dojo.declare("dojox.layout.Dock",
-	[dijit._Widget,dijit._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
@@ -327,8 +326,8 @@ dojo.declare("dojox.layout.Dock",
 	addNode: function(refNode){
 		// summary: Instert a dockNode refernce into the dock
 		
-		var div = dojo.create('li', null, this.containerNode),
-			node = new dojox.layout._DockNode({
+		var div = domConstruct.create('li', null, this.containerNode),
+			node = new DockNode({
 				title: refNode.title,
 				paneRef: refNode
 			}, div)
@@ -343,7 +342,7 @@ dojo.declare("dojox.layout.Dock",
 			// attach window.onScroll, and a position like in presentation/dialog
 			this.connect(window, 'onresize', "_positionDock");
 			this.connect(window, 'onscroll', "_positionDock");
-			if(dojo.isIE){
+			if(has("ie")){
 				this.connect(this.domNode, "onresize", "_positionDock");
 			}
 		}
@@ -356,9 +355,9 @@ dojo.declare("dojox.layout.Dock",
 		if(!this._inPositioning){
 			if(this.autoPosition == "south"){
 				// Give some time for scrollbars to appear/disappear
-				setTimeout(dojo.hitch(this, function() {
+				setTimeout(lang.hitch(this, function() {
 					this._inPositiononing = true;
-					var viewport = dojo.window.getBox();
+					var viewport = windowLib.getBox();
 					var s = this.domNode.style;
 					s.left = viewport.l + "px";
 					s.width = (viewport.w-2) + "px";
@@ -372,9 +371,7 @@ dojo.declare("dojox.layout.Dock",
 
 });
 
-dojo.declare("dojox.layout._DockNode",
-	[dijit._Widget,dijit._Templated],
-	{
+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.
@@ -399,5 +396,7 @@ dojo.declare("dojox.layout._DockNode",
 		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 36a5a60..fe5c8f0 100644
--- a/dojox/layout/GridContainer.js
+++ b/dojox/layout/GridContainer.js
@@ -1,621 +1,629 @@
-dojo.provide("dojox.layout.GridContainer");
-
-dojo.require("dojox.layout.GridContainerLite");
-
-dojo.declare(
-	"dojox.layout.GridContainer",
-	dojox.layout.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.
-	// example:
-	// 	|	<div dojoType="dojox.layout.GridContainer" nbZones="3" isAutoOrganized="true">
-	// 	|		<div dojoType="dijit.layout.ContentPane">Content Pane 1 : Drag Me !</div>
-	// 	|		<div dojoType="dijit.layout.ContentPane">Content Pane 2 : Drag Me !</div>
-	// 	|		<div dojoType="dijit.layout.ContentPane">Content Pane 3 : Drag Me !</div>
-	// 	|	</div>
-	//
-	// example:
-	// 	|	dojo.ready(function(){
-	// 	|		var cpane1 = new dijit.layout.ContentPane({ title:"cpane1", content: "Content Pane 1 : Drag Me !" }),
-	// 	|			cpane2 = new dijit.layout.ContentPane({ title:"cpane2", content: "Content Pane 2 : Drag Me !" }),
-	// 	|			cpane3 = new dijit.layout.ContentPane({ title:"cpane3", content: "Content Pane 3 : Drag Me !" });
-	// 	|
-	// 	|		var widget = new dojox.layout.GridContainer({
-	// 	|			nbZones: 3,
-	// 	|			isAutoOrganized: true
-	// 	|		}, dojo.byId("idNode"));
-	// 	|		widget.addChild(cpane1, 0, 0);
-	// 	|		widget.addChild(cpane2, 1, 0);
-	// 	|		widget.addChild(cpane3, 2, 1);
-	// 	|		widget.startup();
-	// 	|	});
-
-	// hasResizableColumns: Boolean
-	//		Allow or not resizing of columns by a grip handle.
-	hasResizableColumns: true,
-
-	// liveResizeColumns: Boolean
-	//		Specifies whether columns resize as you drag (true) or only upon mouseup (false)
-	liveResizeColumns : false,
-
-	// minColWidth: Integer
-	//		Minimum column width in percentage.
-	minColWidth: 20,
-
-	// minChildWidth: Integer
-	// 		Minimum children width in pixel (only used for IE6 which doesn't handle min-width css property)
-	minChildWidth: 150,
-
-	// mode: String
-	//		Location to add/remove columns, must be set to 'left' or 'right' (default).
-	mode: "right",
-
-	// isRightFixed: Boolean
-	//		Define if the last right column is fixed.
-	//		Used when you add or remove columns by calling setColumns method.
-	isRightFixed: false,
-
-	// isLeftFixed: Boolean
-	//		Define if the last left column is fixed.
-	//		Used when you add or remove columns by calling setColumns method.
-	isLeftFixed: false,
-
-	startup: function(){
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/_base/html",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/ready",	// dojo.ready
+	"dojox/layout/GridContainerLite"
+],function(dojo){
+	return dojo.declare(
+		"dojox.layout.GridContainer",
+		dojox.layout.GridContainerLite,
+	{
 		// summary:
-		//		Call the startup of GridContainerLite and place grips
-		//		if user has chosen the hasResizableColumns attribute to true.
-
-		//console.log("dojox.layout.GridContainer ::: startup");
-		this.inherited(arguments);
-		if(this.hasResizableColumns){
-			for(var i = 0; i < this._grid.length - 1; i++){
-				this._createGrip(i);
+		//		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.
+		// example:
+		// 	|	<div dojoType="dojox.layout.GridContainer" nbZones="3" isAutoOrganized="true">
+		// 	|		<div dojoType="dijit.layout.ContentPane">Content Pane 1 : Drag Me !</div>
+		// 	|		<div dojoType="dijit.layout.ContentPane">Content Pane 2 : Drag Me !</div>
+		// 	|		<div dojoType="dijit.layout.ContentPane">Content Pane 3 : Drag Me !</div>
+		// 	|	</div>
+		//
+		// example:
+		// 	|	dojo.ready(function(){
+		// 	|		var cpane1 = new dijit.layout.ContentPane({ title:"cpane1", content: "Content Pane 1 : Drag Me !" }),
+		// 	|			cpane2 = new dijit.layout.ContentPane({ title:"cpane2", content: "Content Pane 2 : Drag Me !" }),
+		// 	|			cpane3 = new dijit.layout.ContentPane({ title:"cpane3", content: "Content Pane 3 : Drag Me !" });
+		// 	|
+		// 	|		var widget = new dojox.layout.GridContainer({
+		// 	|			nbZones: 3,
+		// 	|			isAutoOrganized: true
+		// 	|		}, dojo.byId("idNode"));
+		// 	|		widget.addChild(cpane1, 0, 0);
+		// 	|		widget.addChild(cpane2, 1, 0);
+		// 	|		widget.addChild(cpane3, 2, 1);
+		// 	|		widget.startup();
+		// 	|	});
+
+		// hasResizableColumns: Boolean
+		//		Allow or not resizing of columns by a grip handle.
+		hasResizableColumns: true,
+
+		// liveResizeColumns: Boolean
+		//		Specifies whether columns resize as you drag (true) or only upon mouseup (false)
+		liveResizeColumns : false,
+
+		// minColWidth: Integer
+		//		Minimum column width in percentage.
+		minColWidth: 20,
+
+		// minChildWidth: Integer
+		// 		Minimum children width in pixel (only used for IE6 which doesn't handle min-width css property)
+		minChildWidth: 150,
+
+		// mode: String
+		//		Location to add/remove columns, must be set to 'left' or 'right' (default).
+		mode: "right",
+
+		// isRightFixed: Boolean
+		//		Define if the last right column is fixed.
+		//		Used when you add or remove columns by calling setColumns method.
+		isRightFixed: false,
+
+		// isLeftFixed: Boolean
+		//		Define if the last left column is fixed.
+		//		Used when you add or remove columns by calling setColumns method.
+		isLeftFixed: false,
+
+		startup: function(){
+			// summary:
+			//		Call the startup of GridContainerLite and place grips
+			//		if user has chosen the hasResizableColumns attribute to true.
+
+			//console.log("dojox.layout.GridContainer ::: startup");
+			this.inherited(arguments);
+			if(this.hasResizableColumns){
+				for(var i = 0; i < this._grid.length - 1; i++){
+					this._createGrip(i);
+				}
+				// If widget has a container parent, grips will be placed
+				// by method onShow.
+				if(!this.getParent()){
+					// Fix IE7 :
+					//		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"));
+				}
 			}
-			// If widget has a container parent, grips will be placed
-			// by method onShow.
-			if(!this.getParent()){
-				// Fix IE7 :
-				//		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"));
+		},
+
+		resizeChildAfterDrop : function(/*Node*/node, /*Object*/targetArea, /*Integer*/indexChild){
+			// summary:
+			//		Call when a child is dropped.
+			// description:
+			//		Allow to resize and put grips
+			// node:
+			//		domNode of dropped widget.
+			// targetArea:
+			//		AreaManager Object containing information of targetArea
+			// indexChild:
+			// 		Index where the dropped widget has been placed
+
+			if(this.inherited(arguments)){
+				this._placeGrips();
 			}
-		}
-	},
-
-	resizeChildAfterDrop : function(/*Node*/node, /*Object*/targetArea, /*Integer*/indexChild){
-		// summary:
-		//		Call when a child is dropped.
-		// description:
-		//		Allow to resize and put grips
-		// node:
-		//		domNode of dropped widget.
-		// targetArea:
-		//		AreaManager Object containing information of targetArea
-		// indexChild:
-		// 		Index where the dropped widget has been placed
-
-		if(this.inherited(arguments)){
-			this._placeGrips();
-		}
-	},
-
-	onShow: function(){
-		// summary:
-		//		Place grips in the right place when the GridContainer becomes visible.
+		},
 
-		//console.log("dojox.layout.GridContainer ::: onShow");
-		this.inherited(arguments);
-		this._placeGrips();
-	},
+		onShow: function(){
+			// summary:
+			//		Place grips in the right place when the GridContainer becomes visible.
 
-	resize: function(){
-		// summary:
-		//		Resize the GridContainer widget and columns.
-		//		Replace grips if it's necessary.
-		// tags:
-		//		callback
-
-		//console.log("dojox.layout.GridContainer ::: resize");
-		this.inherited(arguments);
-		// Fix IE6 :
-		//		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)
-		if(this._isShown() && this.hasResizableColumns){
+			//console.log("dojox.layout.GridContainer ::: onShow");
+			this.inherited(arguments);
 			this._placeGrips();
-		}
-	},
-
-	_createGrip: function(/*Integer*/ index){
-		// summary:
-		//		Create a grip for a specific zone.
-		// index:
-		//		index where the grip has to be created.
-		// tags:
-		//		protected
-
-		//console.log("dojox.layout.GridContainer ::: _createGrip");
-		var dropZone = this._grid[index],
-			grip = dojo.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")){
-						gridContainerGripShow = true;
-						break;
+		},
+
+		resize: function(){
+			// summary:
+			//		Resize the GridContainer widget and columns.
+			//		Replace grips if it's necessary.
+			// tags:
+			//		callback
+
+			//console.log("dojox.layout.GridContainer ::: resize");
+			this.inherited(arguments);
+			// Fix IE6 :
+			//		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)
+			if(this._isShown() && this.hasResizableColumns){
+				this._placeGrips();
+			}
+		},
+
+		_createGrip: function(/*Integer*/ index){
+			// summary:
+			//		Create a grip for a specific zone.
+			// index:
+			//		index where the grip has to be created.
+			// tags:
+			//		protected
+
+			//console.log("dojox.layout.GridContainer ::: _createGrip");
+			var dropZone = this._grid[index],
+				grip = dojo.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")){
+							gridContainerGripShow = true;
+							break;
+						}
+					}
+					if(!gridContainerGripShow){
+						dojo.removeClass(e.target, "gridContainerGrip");
+						dojo.addClass(e.target, "gridContainerGripShow");
+					}
+				})[0],
+				this.connect(grip, "onmouseout", function(e){
+					if(!this._isResized){
+						dojo.removeClass(e.target, "gridContainerGripShow");
+						dojo.addClass(e.target, "gridContainerGrip");
+					}
+				})[0],
+				this.connect(grip, "onmousedown", "_resizeColumnOn")[0],
+				this.connect(grip, "ondblclick", "_onGripDbClick")[0]
+			];
+		},
+
+		_placeGrips: function(){
+			// summary:
+			//		Define the position of a grip and place it on page.
+			// tags:
+			//		protected
+
+			//console.log("dojox.layout.GridContainer ::: _placeGrips");
+			var gripWidth, height, left = 0, grip;
+			var scroll = this.domNode.style.overflowY;
+
+			dojo.forEach(this._grid, function(dropZone){
+				if(dropZone.grip){
+					grip = dropZone.grip;
+					if(!gripWidth){
+						gripWidth = grip.offsetWidth / 2;
 					}
-				}
-				if(!gridContainerGripShow){
-					dojo.removeClass(e.target, "gridContainerGrip");
-					dojo.addClass(e.target, "gridContainerGripShow");
-				}
-			})[0],
-			this.connect(grip, "onmouseout", function(e){
-				if(!this._isResized){
-					dojo.removeClass(e.target, "gridContainerGripShow");
-					dojo.addClass(e.target, "gridContainerGrip");
-				}
-			})[0],
-			this.connect(grip, "onmousedown", "_resizeColumnOn")[0],
-			this.connect(grip, "ondblclick", "_onGripDbClick")[0]
-		];
-	},
-
-	_placeGrips: function(){
-		// summary:
-		//		Define the position of a grip and place it on page.
-		// tags:
-		//		protected
-
-		//console.log("dojox.layout.GridContainer ::: _placeGrips");
-		var gripWidth, height, left = 0, grip;
-		var scroll = this.domNode.style.overflowY;
-
-		dojo.forEach(this._grid, function(dropZone){
-			if(dropZone.grip){
-				grip = dropZone.grip;
-				if(!gripWidth){
-					gripWidth = grip.offsetWidth / 2;
-				}
 
-				left += dojo.marginBox(dropZone.node).w;
+					left += dojo.marginBox(dropZone.node).w;
 
-				dojo.style(grip, "left", (left - gripWidth) + "px");
-				//if(dojo.isIE == 6){ do it fot all navigators
-				if(!height){
-					height = dojo.contentBox(this.gridNode).h;
-				}
-				if(height > 0){
-					dojo.style(grip, "height", height + "px");
+					dojo.style(grip, "left", (left - gripWidth) + "px");
+					//if(dojo.isIE == 6){ do it fot all navigators
+					if(!height){
+						height = dojo.contentBox(this.gridNode).h;
+					}
+					if(height > 0){
+						dojo.style(grip, "height", height + "px");
+					}
+					//}
 				}
-				//}
-			}
-		}, this);
-	},
+			}, this);
+		},
+
+		_onGripDbClick: function(){
+			// summary:
+			//		Called when a double click is catch. Resize all columns with the same width.
+			//		The method resize of children have to be called.
+			// tags:
+			//		callback protected
+
+			//console.log("dojox.layout.GridContainer ::: _onGripDbClick");
+			this._updateColumnsWidth(this._dragManager);
+			this.resize();
+		},
+
+		_resizeColumnOn: function(/*Event*/e){
+			// summary:
+			//		Connect events to listen the resize action.
+			//		Change the type of width columns (% to px).
+			//		Calculate the minwidth according to the children.
+			// tags:
+			//		callback
+
+			//console.log("dojox.layout.GridContainer ::: _resizeColumnOn", e);
+			this._activeGrip = e.target;
+			this._initX = e.pageX;
+			e.preventDefault();
 
-	_onGripDbClick: function(){
-		// summary:
-		//		Called when a double click is catch. Resize all columns with the same width.
-		//		The method resize of children have to be called.
-		// tags:
-		//		callback protected
+			dojo.body().style.cursor = "ew-resize";
 
-		//console.log("dojox.layout.GridContainer ::: _onGripDbClick");
-		this._updateColumnsWidth(this._dragManager);
-		this.resize();
-	},
+			this._isResized = true;
 
-	_resizeColumnOn: function(/*Event*/e){
-		// summary:
-		//		Connect events to listen the resize action.
-		//		Change the type of width columns (% to px).
-		//		Calculate the minwidth according to the children.
-		// tags:
-		//		callback
+			var tabSize = [];
+			var grid;
+			var i;
 
-		//console.log("dojox.layout.GridContainer ::: _resizeColumnOn", e);
-		this._activeGrip = e.target;
-		this._initX = e.pageX;
-		e.preventDefault();
+			for(i = 0; i < this._grid.length; i++){
+				tabSize[i] = dojo.contentBox(this._grid[i].node).w;
+			}
 
-		dojo.body().style.cursor = "ew-resize";
+			this._oldTabSize = tabSize;
 
-		this._isResized = true;
+			for(i = 0; i < this._grid.length; i++){
+				grid = this._grid[i];
+				if(this._activeGrip == grid.grip){
+					this._currentColumn = grid.node;
+					this._currentColumnWidth = tabSize[i];
+					this._nextColumn = this._grid[i + 1].node;
+					this._nextColumnWidth = tabSize[i + 1];
+				}
+				grid.node.style.width = tabSize[i] + "px";
+			}
 
-		var tabSize = [];
-		var grid;
-		var i;
+			// calculate the minWidh of all children for current and next column
+			var calculateChildMinWidth = function(childNodes, minChild){
+				var width = 0;
+				var childMinWidth = 0;
 
-		for(i = 0; i < this._grid.length; i++){
-			tabSize[i] = dojo.contentBox(this._grid[i].node).w;
-		}
+				dojo.forEach(childNodes, function(child){
+					if(child.nodeType == 1){
+						var objectStyle = dojo.getComputedStyle(child);
+						var minWidth = (dojo.isIE) ? minChild : parseInt(objectStyle.minWidth);
 
-		this._oldTabSize = tabSize;
+						childMinWidth = minWidth +
+									parseInt(objectStyle.marginLeft) +
+									parseInt(objectStyle.marginRight);
 
-		for(i = 0; i < this._grid.length; i++){
-			grid = this._grid[i];
-			if(this._activeGrip == grid.grip){
-				this._currentColumn = grid.node;
-				this._currentColumnWidth = tabSize[i];
-				this._nextColumn = this._grid[i + 1].node;
-				this._nextColumnWidth = tabSize[i + 1];
+						if(width < childMinWidth){
+							width = childMinWidth;
+						}
+					}
+				});
+				return width;
 			}
-			grid.node.style.width = tabSize[i] + "px";
-		}
+			var currentColumnMinWidth = calculateChildMinWidth(this._currentColumn.childNodes, this.minChildWidth);
 
-		// calculate the minWidh of all children for current and next column
-		var calculateChildMinWidth = function(childNodes, minChild){
-			var width = 0;
-			var childMinWidth = 0;
+			var nextColumnMinWidth = calculateChildMinWidth(this._nextColumn.childNodes, this.minChildWidth);
 
-			dojo.forEach(childNodes, function(child){
-				if(child.nodeType == 1){
-					var objectStyle = dojo.getComputedStyle(child);
-					var minWidth = (dojo.isIE) ? minChild : parseInt(objectStyle.minWidth);
+			var minPix = Math.round((dojo.marginBox(this.gridContainerTable).w * this.minColWidth) / 100);
 
-					childMinWidth = minWidth +
-								parseInt(objectStyle.marginLeft) +
-								parseInt(objectStyle.marginRight);
+			this._currentMinCol = currentColumnMinWidth;
+			this._nextMinCol = nextColumnMinWidth;
 
-					if(width < childMinWidth){
-						width = childMinWidth;
-					}
-				}
-			});
-			return width;
-		}
-		var currentColumnMinWidth = calculateChildMinWidth(this._currentColumn.childNodes, this.minChildWidth);
-
-		var nextColumnMinWidth = calculateChildMinWidth(this._nextColumn.childNodes, this.minChildWidth);
+			if(minPix > this._currentMinCol){
+				this._currentMinCol = minPix;
+			}
+			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");
+		},
 
-		var minPix = Math.round((dojo.marginBox(this.gridContainerTable).w * this.minColWidth) / 100);
+		_onGripMouseUp: function(){
+			// summary:
+			//		Call on the onMouseUp only if the reiszeColumnMove was not called.
+			// tags:
+			//		callback
 
-		this._currentMinCol = currentColumnMinWidth;
-		this._nextMinCol = nextColumnMinWidth;
+			//console.log(dojox.layout.GridContainer ::: _onGripMouseUp");
+			dojo.body().style.cursor = "default";
 
-		if(minPix > this._currentMinCol){
-			this._currentMinCol = minPix;
-		}
-		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");
-	},
+			dojo.disconnect(this._connectResizeColumnMove);
+			dojo.disconnect(this._connectOnGripMouseUp);
 
-	_onGripMouseUp: function(){
-		// summary:
-		//		Call on the onMouseUp only if the reiszeColumnMove was not called.
-		// tags:
-		//		callback
+			this._connectOnGripMouseUp = this._connectResizeColumnMove = null;
 
-		//console.log(dojox.layout.GridContainer ::: _onGripMouseUp");
-		dojo.body().style.cursor = "default";
+			if(this._activeGrip){
+				dojo.removeClass(this._activeGrip, "gridContainerGripShow");
+				dojo.addClass(this._activeGrip, "gridContainerGrip");
+			}
 
-		dojo.disconnect(this._connectResizeColumnMove);
-		dojo.disconnect(this._connectOnGripMouseUp);
+			this._isResized = false;
+		},
+
+		_resizeColumnMove: function(/*Event*/e){
+			// summary:
+			//		Change columns size.
+			// tags:
+			//		callback
+
+			//console.log("dojox.layout.GridContainer ::: _resizeColumnMove");
+			e.preventDefault();
+			if(!this._connectResizeColumnOff){
+				dojo.disconnect(this._connectOnGripMouseUp);
+				this._connectOnGripMouseUp = null;
+				this._connectResizeColumnOff = dojo.connect(dojo.doc, "onmouseup", this, "_resizeColumnOff");
+			}
 
-		this._connectOnGripMouseUp = this._connectResizeColumnMove = null;
+			var d = e.pageX - this._initX;
+			if(d == 0){ return; }
 
-		if(this._activeGrip){
-			dojo.removeClass(this._activeGrip, "gridContainerGripShow");
-			dojo.addClass(this._activeGrip, "gridContainerGrip");
-		}
+			if(!(this._currentColumnWidth + d < this._currentMinCol ||
+					this._nextColumnWidth - d < this._nextMinCol)){
 
-		this._isResized = false;
-	},
+				this._currentColumnWidth += d;
+				this._nextColumnWidth -= d;
+				this._initX = e.pageX;
+				this._activeGrip.style.left = parseInt(this._activeGrip.style.left) + d + "px";
 
-	_resizeColumnMove: function(/*Event*/e){
-		// summary:
-		//		Change columns size.
-		// tags:
-		//		callback
+				if(this.liveResizeColumns){
+					this._currentColumn.style["width"] = this._currentColumnWidth + "px";
+					this._nextColumn.style["width"] = this._nextColumnWidth + "px";
+					this.resize();
+				}
+			}
+		},
 
-		//console.log("dojox.layout.GridContainer ::: _resizeColumnMove");
-		e.preventDefault();
-		if(!this._connectResizeColumnOff){
-			dojo.disconnect(this._connectOnGripMouseUp);
-			this._connectOnGripMouseUp = null;
-			this._connectResizeColumnOff = dojo.connect(dojo.doc, "onmouseup", this, "_resizeColumnOff");
-		}
+		_resizeColumnOff: function(/*Event*/e){
+			// summary:
+			//		Disconnect resize events.
+			//		Change the type of width columns (px to %).
+			// tags:
+			//		callback
 
-		var d = e.pageX - this._initX;
-		if(d == 0){ return; }
+			//console.log("dojox.layout.GridContainer ::: _resizeColumnOff");
+			dojo.body().style.cursor = "default";
 
-		if(!(this._currentColumnWidth + d < this._currentMinCol ||
-				this._nextColumnWidth - d < this._nextMinCol)){
+			dojo.disconnect(this._connectResizeColumnMove);
+			dojo.disconnect(this._connectResizeColumnOff);
 
-			this._currentColumnWidth += d;
-			this._nextColumnWidth -= d;
-			this._initX = e.pageX;
-			this._activeGrip.style.left = parseInt(this._activeGrip.style.left) + d + "px";
+			this._connectResizeColumnOff = this._connectResizeColumnMove = null;
 
-			if(this.liveResizeColumns){
+			if(!this.liveResizeColumns){
 				this._currentColumn.style["width"] = this._currentColumnWidth + "px";
 				this._nextColumn.style["width"] = this._nextColumnWidth + "px";
-				this.resize();
+				//this.resize();
 			}
-		}
-	},
-
-	_resizeColumnOff: function(/*Event*/e){
-		// summary:
-		//		Disconnect resize events.
-		//		Change the type of width columns (px to %).
-		// tags:
-		//		callback
-
-		//console.log("dojox.layout.GridContainer ::: _resizeColumnOff");
-		dojo.body().style.cursor = "default";
 
-		dojo.disconnect(this._connectResizeColumnMove);
-		dojo.disconnect(this._connectResizeColumnOff);
+			var tabSize = [],
+				testSize = [],
+				tabWidth = this.gridContainerTable.clientWidth,
+				node,
+				update = false,
+				i;
 
-		this._connectResizeColumnOff = this._connectResizeColumnMove = null;
-
-		if(!this.liveResizeColumns){
-			this._currentColumn.style["width"] = this._currentColumnWidth + "px";
-			this._nextColumn.style["width"] = this._nextColumnWidth + "px";
-			//this.resize();
-		}
-
-		var tabSize = [],
-			testSize = [],
-			tabWidth = this.gridContainerTable.clientWidth,
-			node,
-			update = false,
-			i;
-
-		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;
-			}
-			else{
-				tabSize[i] = dojo.contentBox(node).w;
-				testSize = tabSize;
+			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;
+				}
+				else{
+					tabSize[i] = dojo.contentBox(node).w;
+					testSize = tabSize;
+				}
 			}
-		}
 
-		for(i = 0; i < testSize.length; i++){
-			if(testSize[i] != this._oldTabSize[i]){
-				update = true;
-				break;
+			for(i = 0; i < testSize.length; i++){
+				if(testSize[i] != this._oldTabSize[i]){
+					update = true;
+					break;
+				}
 			}
-		}
 
-		if(update){
-			var mul = dojo.isIE ? 100 : 10000;
-			for(i = 0; i < this._grid.length; i++){
-				this._grid[i].node.style.width = Math.round((100 * mul * tabSize[i]) / tabWidth) / mul + "%";
+			if(update){
+				var mul = dojo.isIE ? 100 : 10000;
+				for(i = 0; i < this._grid.length; i++){
+					this._grid[i].node.style.width = Math.round((100 * mul * tabSize[i]) / tabWidth) / mul + "%";
+				}
+				this.resize();
 			}
-			this.resize();
-		}
 
-		if(this._activeGrip){
-			dojo.removeClass(this._activeGrip, "gridContainerGripShow");
-			dojo.addClass(this._activeGrip, "gridContainerGrip");
-		}
-
-		this._isResized = false;
-	},
+			if(this._activeGrip){
+				dojo.removeClass(this._activeGrip, "gridContainerGripShow");
+				dojo.addClass(this._activeGrip, "gridContainerGrip");
+			}
 
-	setColumns: function(/*Integer*/nbColumns){
-		// summary:
-		//		Set the number of columns.
-		// nbColumns:
-		//		Number of columns
-
-		//console.log("dojox.layout.GridContainer ::: setColumns");
-		var z, j;
-		if(nbColumns > 0){
-			var length = this._grid.length,
-				delta = length - nbColumns;
-			if(delta > 0){
-				var count = [], zone, start, end, nbChildren;
-				// Check if right or left columns are fixed
-				// Columns are not taken in account and can't be deleted
-				if(this.mode == "right"){
-					end = (this.isLeftFixed && length > 0) ? 1 : 0;
-					start = (this.isRightFixed) ? length - 2 : length - 1
-					for(z = start; z >= end; z--){
-						nbChildren = 0;
-						zone = this._grid[z].node;
-						for(j = 0; j < zone.childNodes.length; j++){
-							if(zone.childNodes[j].nodeType == 1 && !(zone.childNodes[j].id == "")){
-								nbChildren++;
+			this._isResized = false;
+		},
+
+		setColumns: function(/*Integer*/nbColumns){
+			// summary:
+			//		Set the number of columns.
+			// nbColumns:
+			//		Number of columns
+
+			//console.log("dojox.layout.GridContainer ::: setColumns");
+			var z, j;
+			if(nbColumns > 0){
+				var length = this._grid.length,
+					delta = length - nbColumns;
+				if(delta > 0){
+					var count = [], zone, start, end, nbChildren;
+					// Check if right or left columns are fixed
+					// Columns are not taken in account and can't be deleted
+					if(this.mode == "right"){
+						end = (this.isLeftFixed && length > 0) ? 1 : 0;
+						start = (this.isRightFixed) ? length - 2 : length - 1
+						for(z = start; z >= end; z--){
+							nbChildren = 0;
+							zone = this._grid[z].node;
+							for(j = 0; j < zone.childNodes.length; j++){
+								if(zone.childNodes[j].nodeType == 1 && !(zone.childNodes[j].id == "")){
+									nbChildren++;
+									break;
+								}
+							}
+							if(nbChildren == 0){ count[count.length] = z; }
+							if(count.length >= delta){
+								this._deleteColumn(count);
 								break;
 							}
 						}
-						if(nbChildren == 0){ count[count.length] = z; }
-						if(count.length >= delta){
-							this._deleteColumn(count);
-							break;
+						if(count.length < delta){
+							dojo.publish("/dojox/layout/gridContainer/noEmptyColumn", [this]);
 						}
 					}
-					if(count.length < delta){
-						dojo.publish("/dojox/layout/gridContainer/noEmptyColumn", [this]);
-					}
-				}
-				else{ // mode = "left"
-					start = (this.isLeftFixed && length > 0) ? 1 : 0;
-					end = (this.isRightFixed) ? length - 1 : length;
-					for(z = start; z < end; z++){
-						nbChildren = 0;
-						zone = this._grid[z].node;
-						for(j = 0; j < zone.childNodes.length; j++){
-							if(zone.childNodes[j].nodeType == 1 && !(zone.childNodes[j].id == "")){
-								nbChildren++;
+					else{ // mode = "left"
+						start = (this.isLeftFixed && length > 0) ? 1 : 0;
+						end = (this.isRightFixed) ? length - 1 : length;
+						for(z = start; z < end; z++){
+							nbChildren = 0;
+							zone = this._grid[z].node;
+							for(j = 0; j < zone.childNodes.length; j++){
+								if(zone.childNodes[j].nodeType == 1 && !(zone.childNodes[j].id == "")){
+									nbChildren++;
+									break;
+								}
+							}
+							if(nbChildren == 0){ count[count.length] = z; }
+							if(count.length >= delta){
+								this._deleteColumn(count);
 								break;
 							}
 						}
-						if(nbChildren == 0){ count[count.length] = z; }
-						if(count.length >= delta){
-							this._deleteColumn(count);
-							break;
+						if(count.length < delta){
+							//Not enough empty columns
+							dojo.publish("/dojox/layout/gridContainer/noEmptyColumn", [this]);
 						}
 					}
-					if(count.length < delta){
-						//Not enough empty columns
-						dojo.publish("/dojox/layout/gridContainer/noEmptyColumn", [this]);
-					}
 				}
+				else{
+					if(delta < 0){ this._addColumn(Math.abs(delta)); }
+				}
+				if(this.hasResizableColumns){ this._placeGrips(); }
 			}
-			else{
-				if(delta < 0){ this._addColumn(Math.abs(delta)); }
+		},
+
+		_addColumn: function(/*Integer*/nbColumns){
+			// summary:
+			//		Add some columns.
+			// nbColumns:
+			//		Number of column to added
+			// tags:
+			//		private
+
+			//console.log("dojox.layout.GridContainer ::: _addColumn");
+			var grid = this._grid,
+				dropZone,
+				node,
+				index,
+				length,
+				isRightMode = (this.mode == "right"),
+				accept = this.acceptTypes.join(","),
+				m = this._dragManager;
+
+			//Add a grip to the last column
+			if(this.hasResizableColumns && ((!this.isRightFixed && isRightMode)
+				|| (this.isLeftFixed && !isRightMode && this.nbZones == 1) )){
+				this._createGrip(grid.length - 1);
 			}
-			if(this.hasResizableColumns){ this._placeGrips(); }
-		}
-	},
 
-	_addColumn: function(/*Integer*/nbColumns){
-		// summary:
-		//		Add some columns.
-		// nbColumns:
-		//		Number of column to added
-		// tags:
-		//		private
-
-		//console.log("dojox.layout.GridContainer ::: _addColumn");
-		var grid = this._grid,
-			dropZone,
-			node,
-			index,
-			length,
-			isRightMode = (this.mode == "right"),
-			accept = this.acceptTypes.join(","),
-			m = this._dragManager;
-
-		//Add a grip to the last column
-		if(this.hasResizableColumns && ((!this.isRightFixed && isRightMode)
-			|| (this.isLeftFixed && !isRightMode && this.nbZones == 1) )){
-			this._createGrip(grid.length - 1);
-		}
+			for(var i = 0; i < nbColumns; i++){
+				// Fix CODEX defect #53025 :
+				//		Apply acceptType attribute on each new column.
+				node = dojo.create("td", {
+					'class': "gridContainerZone dojoxDndArea" ,
+					'accept': accept,
+					'id': this.id + "_dz" + this.nbZones
+				});
 
-		for(var i = 0; i < nbColumns; i++){
-			// Fix CODEX defect #53025 :
-			//		Apply acceptType attribute on each new column.
-			node = dojo.create("td", {
-				'class': "gridContainerZone dojoxDndArea" ,
-				'accept': accept,
-				'id': this.id + "_dz" + this.nbZones
-			});
-
-			length = grid.length;
-
-			if(isRightMode){
-				if(this.isRightFixed){
-					index = length - 1;
-					grid.splice(index, 0, {
-						'node': grid[index].node.parentNode.insertBefore(node, grid[index].node)
-					});
+				length = grid.length;
+
+				if(isRightMode){
+					if(this.isRightFixed){
+						index = length - 1;
+						grid.splice(index, 0, {
+							'node': grid[index].node.parentNode.insertBefore(node, grid[index].node)
+						});
+					}
+					else{
+						index = length;
+						grid.push({ 'node': this.gridNode.appendChild(node) });
+					}
 				}
 				else{
-					index = length;
-					grid.push({ 'node': this.gridNode.appendChild(node) });
-				}
-			}
-			else{
-				if(this.isLeftFixed){
-					index = (length == 1) ? 0 : 1;
-					this._grid.splice(1, 0, {
-						'node': this._grid[index].node.parentNode.appendChild(node, this._grid[index].node)
-					});
-					index = 1;
+					if(this.isLeftFixed){
+						index = (length == 1) ? 0 : 1;
+						this._grid.splice(1, 0, {
+							'node': this._grid[index].node.parentNode.appendChild(node, this._grid[index].node)
+						});
+						index = 1;
+					}
+					else{
+						index = length - this.nbZones;
+						this._grid.splice(index, 0, {
+							'node': grid[index].node.parentNode.insertBefore(node, grid[index].node)
+						});
+					}
 				}
-				else{
-					index = length - this.nbZones;
-					this._grid.splice(index, 0, {
-						'node': grid[index].node.parentNode.insertBefore(node, grid[index].node)
-					});
+				if(this.hasResizableColumns){
+					//Add a grip to resize columns
+					if((!isRightMode && this.nbZones != 1) ||
+							(!isRightMode && this.nbZones == 1 && !this.isLeftFixed) ||
+								(isRightMode && i < nbColumns-1) ||
+									(isRightMode && i == nbColumns-1 && this.isRightFixed)){
+						this._createGrip(index);
+					}
 				}
+				// register tnbZoneshe new area into the areaManager
+				m.registerByNode(grid[index].node);
+				this.nbZones++;
 			}
-			if(this.hasResizableColumns){
-				//Add a grip to resize columns
-				if((!isRightMode && this.nbZones != 1) ||
-						(!isRightMode && this.nbZones == 1 && !this.isLeftFixed) ||
-							(isRightMode && i < nbColumns-1) ||
-								(isRightMode && i == nbColumns-1 && this.isRightFixed)){
-					this._createGrip(index);
+			this._updateColumnsWidth(m);
+		},
+
+		_deleteColumn: function(/*Array*/indices){
+			// summary:
+			//		Remove some columns with indices passed as an array.
+			// indices:
+			//		Column index array
+			// tags:
+			//		private
+
+			//console.log("dojox.layout.GridContainer ::: _deleteColumn");
+			var child, grid, index,
+				nbDelZones = 0,
+				length = indices.length,
+				m = this._dragManager;
+			for(var i = 0; i < length; i++){
+				index = (this.mode == "right") ? indices[i] : indices[i] - nbDelZones;
+				grid = this._grid[index];
+
+				if(this.hasResizableColumns && grid.grip){
+					dojo.forEach(grid.gripHandler, function(handler){
+						dojo.disconnect(handler);
+					});
+					dojo.destroy(this.domNode.removeChild(grid.grip));
+					grid.grip = null;
 				}
-			}
-			// register tnbZoneshe new area into the areaManager
-			m.registerByNode(grid[index].node);
-			this.nbZones++;
-		}
-		this._updateColumnsWidth(m);
-	},
 
-	_deleteColumn: function(/*Array*/indices){
-		// summary:
-		//		Remove some columns with indices passed as an array.
-		// indices:
-		//		Column index array
-		// tags:
-		//		private
-
-		//console.log("dojox.layout.GridContainer ::: _deleteColumn");
-		var child, grid, index,
-			nbDelZones = 0,
-			length = indices.length,
-			m = this._dragManager;
-		for(var i = 0; i < length; i++){
-			index = (this.mode == "right") ? indices[i] : indices[i] - nbDelZones;
-			grid = this._grid[index];
-
-			if(this.hasResizableColumns && grid.grip){
-				dojo.forEach(grid.gripHandler, function(handler){
-					dojo.disconnect(handler);
-				});
-				dojo.destroy(this.domNode.removeChild(grid.grip));
-				grid.grip = null;
+				m.unregister(grid.node);
+				dojo.destroy(this.gridNode.removeChild(grid.node));
+				this._grid.splice(index, 1);
+				this.nbZones--;
+				nbDelZones++;
 			}
 
-			m.unregister(grid.node);
-			dojo.destroy(this.gridNode.removeChild(grid.node));
-			this._grid.splice(index, 1);
-			this.nbZones--;
-			nbDelZones++;
-		}
+			// 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));
+				lastGrid.grip = null;
+			}
 
-		// 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));
-			lastGrid.grip = null;
+			this._updateColumnsWidth(m);
+		},
+
+		_updateColumnsWidth: function(/*Object*/ manager){
+			// summary:
+			//		Update the columns width.
+			// manager:
+			//		dojox.mdnd.AreaManager singleton
+			// tags:
+			//		private
+
+			//console.log("dojox.layout.GridContainer ::: _updateColumnsWidth");
+			this.inherited(arguments);
+			manager._dropMode.updateAreas(manager._areaList);
+		},
+
+		destroy: function(){
+			dojo.unsubscribe(this._dropHandler);
+			this.inherited(arguments);
 		}
-
-		this._updateColumnsWidth(m);
-	},
-
-	_updateColumnsWidth: function(/*Object*/ manager){
-		// summary:
-		//		Update the columns width.
-		// manager:
-		//		dojox.mdnd.AreaManager singleton
-		// tags:
-		//		private
-
-		//console.log("dojox.layout.GridContainer ::: _updateColumnsWidth");
-	 	this.inherited(arguments);
-		manager._dropMode.updateAreas(manager._areaList);
-	},
-
-	destroy: function(){
-		dojo.unsubscribe(this._dropHandler);
-		this.inherited(arguments);
-	}
-});
\ No newline at end of file
+	});
+});
diff --git a/dojox/layout/GridContainerLite.js b/dojox/layout/GridContainerLite.js
index 5e38d5b..e234d20 100644
--- a/dojox/layout/GridContainerLite.js
+++ b/dojox/layout/GridContainerLite.js
@@ -1,822 +1,826 @@
-dojo.provide("dojox.layout.GridContainerLite");
-
-dojo.require("dijit._Templated");
-dojo.require("dijit.layout._LayoutWidget");
-
-dojo.require("dojox.mdnd.AreaManager");
-dojo.require("dojox.mdnd.DropIndicator");
-dojo.require("dojox.mdnd.dropMode.OverDropMode");
-dojo.require("dojox.mdnd.AutoScroll");
-
-dojo.declare(
-	"dojox.layout.GridContainerLite",
-	[dijit.layout._LayoutWidget, dijit._Templated],
-{
-	// summary:
-	// 		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).
-	//		Each child is movable by drag and drop inside the GridContainer.
-	//		The position of other children is automatically calculated when a child is moved.
-	//
-	// example:
-	// 	|	<div dojoType="dojox.layout.GridContainerLite" nbZones="3" isAutoOrganized="true">
-	// 	|		<div dojoType="dijit.layout.ContentPane">Content Pane 1 : Drag Me !</div>
-	// 	|		<div dojoType="dijit.layout.ContentPane">Content Pane 2 : Drag Me !</div>
-	// 	|		<div dojoType="dijit.layout.ContentPane">Content Pane 3 : Drag Me !</div>
-	// 	|	</div>
-	//
-	// example:
-	// 	|	dojo.ready(function(){
-	// 	|		var cpane1 = new dijit.layout.ContentPane({
-	//	|			title:"cpane1", content: "Content Pane 1 : Drag Me !"
-	//	|		}),
-	// 	|		cpane2 = new dijit.layout.ContentPane({
-	//	|			title:"cpane2",
-	//	|			content: "Content Pane 2 : Drag Me !"
-	//	|		}),
-	// 	|		cpane3 = new dijit.layout.ContentPane({
-	//	|			title:"cpane3",
-	//	|			content: "Content Pane 3 : Drag Me !"
-	//	|		});
-	// 	|
-	// 	|		var widget = new dojox.layout.GridContainerLite({
-	// 	|			nbZones: 3,
-	// 	|			isAutoOrganized: true
-	// 	|		}, dojo.byId("idNode"));
-	// 	|		widget.addChild(cpane1, 0, 0);
-	// 	|		widget.addChild(cpane2, 1, 0);
-	// 	|		widget.addChild(cpane3, 2, 1);
-	// 	|		widget.startup();
-	// 	|	});
-	
-	//	autoRefresh: Boolean
-	//		Enable the refresh of registered areas on drag start.
-	autoRefresh: true,
-
-
-	// templateString: String
-	//		template of gridContainer.
-	templateString: dojo.cache("dojox.layout", "resources/GridContainer.html"),
-
-	// dragHandleClass: Array :
-	//		CSS class enabling a drag handle on a child.
-	dragHandleClass: "dojoxDragHandle",
-
-	// nbZones: Integer
-	//		The number of dropped zones, by default 1.
-	nbZones: 1,
-
-	// doLayout: Boolean
-	//		If true, change the size of my currently displayed child to match my size.
-	doLayout: true,
-
-	// isAutoOrganized: Boolean
-	//		If true, widgets are organized automatically,
-	//		else the attribute colum of child will define the right column.
-	isAutoOrganized: true,
-
-	// acceptTypes: Array
-	//		The GridContainer will only accept the children that fit to the types.
-	acceptTypes: [],
-	
-	// colWidths: String
-	//		A comma separated list of column widths. If the column widths do not add up
-	//		to 100, the remaining columns split the rest of the width evenly
-	//		between them.
-	colWidths: "",
-
-	constructor: function(/*Object*/props, /*DOMNode*/node){
-		this.acceptTypes = (props || {}).acceptTypes || ["text"];
-		this._disabled = true;
-	},
-
-	postCreate: function(){
-		//console.log("dojox.layout.GridContainerLite ::: postCreate");
-		this.inherited(arguments);
-		this._grid = [];
-
-		this._createCells();
-
-		// need to resize dragged child when it's dropped.
-		this.subscribe("/dojox/mdnd/drop", "resizeChildAfterDrop");
-		this.subscribe("/dojox/mdnd/drag/start", "resizeChildAfterDragStart");
-
-		this._dragManager = dojox.mdnd.areaManager();
-		// console.info("autorefresh ::: ", this.autoRefresh);
-		this._dragManager.autoRefresh = this.autoRefresh;
-
-		//	Add specific dragHandleClass to the manager.
-		this._dragManager.dragHandleClass = this.dragHandleClass;
-
-		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");
-		}
-		// Call postCreate of dijit.layout._LayoutWidget.
-		this.inherited(arguments);
-
-	},
-
-	startup: function(){
-		//console.log("dojox.layout.GridContainerLite ::: startup");
-		if(this._started){ return; }
+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",
+	"dijit/layout/_LayoutWidget",
+	"dijit/focus",			// dijit.focus()
+	"dijit/_base/focus"		// dijit.getFocus()
+],function(dojo,template){
+
+	var gcl = dojo.declare(
+		"dojox.layout.GridContainerLite",
+		[dijit.layout._LayoutWidget, dijit._TemplatedMixin],
+	{
+		// summary:
+		// 		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).
+		//		Each child is movable by drag and drop inside the GridContainer.
+		//		The position of other children is automatically calculated when a child is moved.
+		//
+		// example:
+		// 	|	<div dojoType="dojox.layout.GridContainerLite" nbZones="3" isAutoOrganized="true">
+		// 	|		<div dojoType="dijit.layout.ContentPane">Content Pane 1 : Drag Me !</div>
+		// 	|		<div dojoType="dijit.layout.ContentPane">Content Pane 2 : Drag Me !</div>
+		// 	|		<div dojoType="dijit.layout.ContentPane">Content Pane 3 : Drag Me !</div>
+		// 	|	</div>
+		//
+		// example:
+		// 	|	dojo.ready(function(){
+		// 	|		var cpane1 = new dijit.layout.ContentPane({
+		//	|			title:"cpane1", content: "Content Pane 1 : Drag Me !"
+		//	|		}),
+		// 	|		cpane2 = new dijit.layout.ContentPane({
+		//	|			title:"cpane2",
+		//	|			content: "Content Pane 2 : Drag Me !"
+		//	|		}),
+		// 	|		cpane3 = new dijit.layout.ContentPane({
+		//	|			title:"cpane3",
+		//	|			content: "Content Pane 3 : Drag Me !"
+		//	|		});
+		// 	|
+		// 	|		var widget = new dojox.layout.GridContainerLite({
+		// 	|			nbZones: 3,
+		// 	|			isAutoOrganized: true
+		// 	|		}, dojo.byId("idNode"));
+		// 	|		widget.addChild(cpane1, 0, 0);
+		// 	|		widget.addChild(cpane2, 1, 0);
+		// 	|		widget.addChild(cpane3, 2, 1);
+		// 	|		widget.startup();
+		// 	|	});
+
+		//	autoRefresh: Boolean
+		//		Enable the refresh of registered areas on drag start.
+		autoRefresh: true,
+
+
+		// templateString: String
+		//		template of gridContainer.
+		templateString: template,
+
+		// dragHandleClass: Array :
+		//		CSS class enabling a drag handle on a child.
+		dragHandleClass: "dojoxDragHandle",
+
+		// nbZones: Integer
+		//		The number of dropped zones, by default 1.
+		nbZones: 1,
+
+		// doLayout: Boolean
+		//		If true, change the size of my currently displayed child to match my size.
+		doLayout: true,
+
+		// isAutoOrganized: Boolean
+		//		If true, widgets are organized automatically,
+		//		else the attribute colum of child will define the right column.
+		isAutoOrganized: true,
+
+		// acceptTypes: Array
+		//		The GridContainer will only accept the children that fit to the types.
+		acceptTypes: [],
+
+		// colWidths: String
+		//		A comma separated list of column widths. If the column widths do not add up
+		//		to 100, the remaining columns split the rest of the width evenly
+		//		between them.
+		colWidths: "",
+
+		constructor: function(/*Object*/props, /*DOMNode*/node){
+			this.acceptTypes = (props || {}).acceptTypes || ["text"];
+			this._disabled = true;
+		},
+
+		postCreate: function(){
+			//console.log("dojox.layout.GridContainerLite ::: postCreate");
+			this.inherited(arguments);
+			this._grid = [];
 
-		if(this.isAutoOrganized){
-			this._organizeChildren();
-		}
-		else{
-			this._organizeChildrenManually();
-		}
+			this._createCells();
 
-		// 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(); });
+			// need to resize dragged child when it's dropped.
+			this.subscribe("/dojox/mdnd/drop", "resizeChildAfterDrop");
+			this.subscribe("/dojox/mdnd/drag/start", "resizeChildAfterDragStart");
 
-		// Need to enable the Drag And Drop only if the GridContainer is visible.
-		if(this._isShown()){
-			this.enableDnd();
-		}
-		this.inherited(arguments);
-	},
+			this._dragManager = dojox.mdnd.areaManager();
+			// console.info("autorefresh ::: ", this.autoRefresh);
+			this._dragManager.autoRefresh = this.autoRefresh;
 
-	resizeChildAfterDrop: function(/*Node*/node, /*Object*/targetArea, /*Integer*/indexChild){
-		// summary:
-		//		Resize the GridContainerLite inner table and the dropped widget.
-		// description:
-		//		These components are resized only if the targetArea.node is a
-		//		child of this instance of gridContainerLite.
-		//		To be resized, the dropped node must have also a method resize.
-		// node:
-		//		domNode of dropped widget.
-		// targetArea:
-		//		AreaManager Object containing information of targetArea
-		// indexChild:
-		// 		Index where the dropped widget has been placed
-		// returns:
-		//		True if resized.
-
-		//console.log("dojox.layout.GridContainerLite ::: resizeChildAfterDrop");
-		if(this._disabled){
-			return false;
-		}
-		if(dijit.getEnclosingWidget(targetArea.node) == this){
-			var widget = dijit.byNode(node);
-			if(widget.resize && dojo.isFunction(widget.resize)){
-				widget.resize();
-			}
+			//	Add specific dragHandleClass to the manager.
+			this._dragManager.dragHandleClass = this.dragHandleClass;
 
-			// Update the column of the widget
-			widget.set("column", node.parentNode.cellIndex);
-			
 			if(this.doLayout){
-				var domNodeHeight = this._contentBox.h,
-					divHeight = dojo.contentBox(this.gridContainerDiv).h;
-				if(divHeight >= domNodeHeight){
-					dojo.style(this.gridContainerTable, "height",
-							(domNodeHeight - this._border.h) + "px");
+				this._border = {
+					'h':(dojo.isIE) ? dojo._getBorderExtents(this.gridContainerTable).h : 0,
+					'w': (dojo.isIE == 6) ? 1 : 0
 				}
 			}
-			return true;
-		}
-		return false;
-	},
-
-	resizeChildAfterDragStart: function(/*Node*/node, /*Object*/sourceArea, /*Integer*/indexChild){
-		// summary:
-		//		Resize the GridContainerLite inner table only if the drag source
-		//		is a child of this gridContainer.
-		// node:
-		//		domNode of dragged widget.
-		// sourceArea:
-		//		AreaManager Object containing information of sourceArea
-		// indexChild:
-		// 		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){
-			this._draggedNode = node;
-			if(this.doLayout){
-				dojo.marginBox(this.gridContainerTable, {
-					'h': dojo.contentBox(this.gridContainerDiv).h - this._border.h
-				});
+			else{
+				dojo.style(this.domNode, "overflowY", "hidden");
+				dojo.style(this.gridContainerTable, "height", "auto");
 			}
-			return true;
-		}
-		return false;
-	},
+			// Call postCreate of dijit.layout._LayoutWidget.
+			this.inherited(arguments);
 
-	getChildren: function(){
-		// summary:
-		//		A specific method which returns children after they were placed in zones.
-		// returns:
-		//		An array 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));
-		});
-		return children;	// Array
-	},
-
-	_isShown: function(){
-		// summary:
-		//		Check if the domNode is visible or not.
-		// returns:
-		//		true if the content is currently shown
-		// tags:
-		//		protected
-
-		//console.log("dojox.layout.GridContainerLite ::: _isShown");
-		if("open" in this){		// for TitlePane, etc.
-			return this.open;		// Boolean
-		}
-		else{
-			var node = this.domNode;
-			return (node.style.display != 'none') && (node.style.visibility != 'hidden') && !dojo.hasClass(node, "dijitHidden"); // Boolean
-		}
-	},
+		},
 
-	layout: function(){
-		// summary:
-		//		Resize of each child
+		startup: function(){
+			//console.log("dojox.layout.GridContainerLite ::: startup");
+			if(this._started){ return; }
 
-		//console.log("dojox.layout.GridContainerLite ::: layout");
-		if(this.doLayout){
-			var contentBox = this._contentBox;
-			dojo.marginBox(this.gridContainerTable, {
-				'h': contentBox.h - this._border.h
-			});
-			dojo.contentBox(this.domNode, {
-				'w': contentBox.w - this._border.w
-			});
-		}
-		dojo.forEach(this.getChildren(), function(widget){
-			if(widget.resize && dojo.isFunction(widget.resize)){
-				widget.resize();
+			if(this.isAutoOrganized){
+				this._organizeChildren();
+			}
+			else{
+				this._organizeChildrenManually();
 			}
-		});
-	},
 
-	onShow: function(){
-		// summary:
-		//		Enabled the Drag And Drop if it's necessary.
+			// 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(); });
 
-		//console.log("dojox.layout.GridContainerLite ::: onShow");
-		if(this._disabled){
-			this.enableDnd();
-		}
-	},
+			// Need to enable the Drag And Drop only if the GridContainer is visible.
+			if(this._isShown()){
+				this.enableDnd();
+			}
+			this.inherited(arguments);
+		},
+
+		resizeChildAfterDrop: function(/*Node*/node, /*Object*/targetArea, /*Integer*/indexChild){
+			// summary:
+			//		Resize the GridContainerLite inner table and the dropped widget.
+			// description:
+			//		These components are resized only if the targetArea.node is a
+			//		child of this instance of gridContainerLite.
+			//		To be resized, the dropped node must have also a method resize.
+			// node:
+			//		domNode of dropped widget.
+			// targetArea:
+			//		AreaManager Object containing information of targetArea
+			// indexChild:
+			// 		Index where the dropped widget has been placed
+			// returns:
+			//		True if resized.
+
+			//console.log("dojox.layout.GridContainerLite ::: resizeChildAfterDrop");
+			if(this._disabled){
+				return false;
+			}
+			if(dijit.getEnclosingWidget(targetArea.node) == this){
+				var widget = dijit.byNode(node);
+				if(widget.resize && dojo.isFunction(widget.resize)){
+					widget.resize();
+				}
 
-	onHide: function(){
-		// summary:
-		//		Disabled the Drag And Drop if it's necessary.
+				// Update the column of the widget
+				widget.set("column", node.parentNode.cellIndex);
 
-		//console.log("dojox.layout.GridContainerLite ::: onHide");
-		if(!this._disabled){
-			this.disableDnd();
-		}
-	},
+				if(this.doLayout){
+					var domNodeHeight = this._contentBox.h,
+						divHeight = dojo.contentBox(this.gridContainerDiv).h;
+					if(divHeight >= domNodeHeight){
+						dojo.style(this.gridContainerTable, "height",
+								(domNodeHeight - this._border.h) + "px");
+					}
+				}
+				return true;
+			}
+			return false;
+		},
+
+		resizeChildAfterDragStart: function(/*Node*/node, /*Object*/sourceArea, /*Integer*/indexChild){
+			// summary:
+			//		Resize the GridContainerLite inner table only if the drag source
+			//		is a child of this gridContainer.
+			// node:
+			//		domNode of dragged widget.
+			// sourceArea:
+			//		AreaManager Object containing information of sourceArea
+			// indexChild:
+			// 		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){
+				this._draggedNode = node;
+				if(this.doLayout){
+					dojo.marginBox(this.gridContainerTable, {
+						'h': dojo.contentBox(this.gridContainerDiv).h - this._border.h
+					});
+				}
+				return true;
+			}
+			return false;
+		},
+
+		getChildren: function(){
+			// summary:
+			//		A specific method which returns children after they were placed in zones.
+			// returns:
+			//		An array 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));
+			});
+			return children;	// Array
+		},
+
+		_isShown: function(){
+			// summary:
+			//		Check if the domNode is visible or not.
+			// returns:
+			//		true if the content is currently shown
+			// tags:
+			//		protected
+
+			//console.log("dojox.layout.GridContainerLite ::: _isShown");
+			if("open" in this){		// for TitlePane, etc.
+				return this.open;		// Boolean
+			}
+			else{
+				var node = this.domNode;
+				return (node.style.display != 'none') && (node.style.visibility != 'hidden') && !dojo.hasClass(node, "dijitHidden"); // Boolean
+			}
+		},
 
-	_createCells: function(){
-		// summary:
-		//		Create the columns of the GridContainer.
-		// tags:
-		//		protected
+		layout: function(){
+			// summary:
+			//		Resize of each child
 
-		//console.log("dojox.layout.GridContainerLite ::: _createCells");
-		if(this.nbZones === 0){ this.nbZones = 1; }
-		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);
+			//console.log("dojox.layout.GridContainerLite ::: layout");
+			if(this.doLayout){
+				var contentBox = this._contentBox;
+				dojo.marginBox(this.gridContainerTable, {
+					'h': contentBox.h - this._border.h
+				});
+				dojo.contentBox(this.domNode, {
+					'w': contentBox.w - this._border.w
+				});
+			}
+			dojo.forEach(this.getChildren(), function(widget){
+				if(widget.resize && dojo.isFunction(widget.resize)){
+					widget.resize();
 				}
-				widths.push(colWidth);
+			});
+		},
+
+		onShow: function(){
+			// summary:
+			//		Enabled the Drag And Drop if it's necessary.
+
+			//console.log("dojox.layout.GridContainerLite ::: onShow");
+			if(this._disabled){
+				this.enableDnd();
 			}
-		}
+		},
 
-		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", {
-					'class': "gridContainerZone",
-					'accept': accept,
-					'id': this.id + "_dz" + i,
-					'style': {
-						'width': widths[i] + "%"
-					}
-				}, this.gridNode)
-			});
-			i++;
-		}
-	},
-	
-	_getZonesAttr: function(){
-		// summary:
-		//   return array of zone (domNode)
-		return dojo.query(".gridContainerZone",  this.containerNode);
-	},
+		onHide: function(){
+			// summary:
+			//		Disabled the Drag And Drop if it's necessary.
 
-	enableDnd: function(){
-		// summary:
-		//		Enable the Drag And Drop for children of GridContainer.
-
-		//console.log("dojox.layout.GridContainerLite ::: enableDnd");
-		var m = this._dragManager;
-		dojo.forEach(this._grid, function(dropZone){
-			m.registerByNode(dropZone.node);
-		});
-		m._dropMode.updateAreas(m._areaList);
-		this._disabled = false;
-	},
-
-	disableDnd: function(){
-		// summary:
-		//		Disable the Drag And Drop for children of GridContainer.
-
-		//console.log("dojox.layout.GridContainerLite ::: disableDnd");
-		var m = this._dragManager;
-		dojo.forEach(this._grid, function(dropZone){
-			m.unregister(dropZone.node);
-		});
-		m._dropMode.updateAreas(m._areaList);
-		this._disabled = true;
-	},
-
-	_organizeChildren: function(){
-		// summary:
-		//		List all zones and insert child into columns.
+			//console.log("dojox.layout.GridContainerLite ::: onHide");
+			if(!this._disabled){
+				this.disableDnd();
+			}
+		},
+
+		_createCells: function(){
+			// summary:
+			//		Create the columns of the GridContainer.
+			// tags:
+			//		protected
+
+			//console.log("dojox.layout.GridContainerLite ::: _createCells");
+			if(this.nbZones === 0){ this.nbZones = 1; }
+			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);
+				}
+			}
 
-		//console.log("dojox.layout.GridContainerLite ::: _organizeChildren");
-		var children = dojox.layout.GridContainerLite.superclass.getChildren.call(this);
-		var numZones = this.nbZones,
-			numPerZone = Math.floor(children.length / numZones),
-			mod = children.length % numZones,
 			i = 0;
-//		console.log('numPerZone', numPerZone, ':: mod', mod);
-		for(var z = 0; z < numZones; z++){
-			for(var r = 0; r < numPerZone; r++){
-				this._insertChild(children[i], z);
+			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", {
+						'class': "gridContainerZone",
+						'accept': accept,
+						'id': this.id + "_dz" + i,
+						'style': {
+							'width': widths[i] + "%"
+						}
+					}, this.gridNode)
+				});
 				i++;
 			}
-			if(mod > 0){
-				try{
+		},
+
+		_getZonesAttr: function(){
+			// summary:
+			//   return array of zone (domNode)
+			return dojo.query(".gridContainerZone",  this.containerNode);
+		},
+
+		enableDnd: function(){
+			// summary:
+			//		Enable the Drag And Drop for children of GridContainer.
+
+			//console.log("dojox.layout.GridContainerLite ::: enableDnd");
+			var m = this._dragManager;
+			dojo.forEach(this._grid, function(dropZone){
+				m.registerByNode(dropZone.node);
+			});
+			m._dropMode.updateAreas(m._areaList);
+			this._disabled = false;
+		},
+
+		disableDnd: function(){
+			// summary:
+			//		Disable the Drag And Drop for children of GridContainer.
+
+			//console.log("dojox.layout.GridContainerLite ::: disableDnd");
+			var m = this._dragManager;
+			dojo.forEach(this._grid, function(dropZone){
+				m.unregister(dropZone.node);
+			});
+			m._dropMode.updateAreas(m._areaList);
+			this._disabled = true;
+		},
+
+		_organizeChildren: function(){
+			// summary:
+			//		List all zones and insert child into columns.
+
+			//console.log("dojox.layout.GridContainerLite ::: _organizeChildren");
+			var children = dojox.layout.GridContainerLite.superclass.getChildren.call(this);
+			var numZones = this.nbZones,
+				numPerZone = Math.floor(children.length / numZones),
+				mod = children.length % numZones,
+				i = 0;
+	//		console.log('numPerZone', numPerZone, ':: mod', mod);
+			for(var z = 0; z < numZones; z++){
+				for(var r = 0; r < numPerZone; r++){
 					this._insertChild(children[i], z);
 					i++;
 				}
+				if(mod > 0){
+					try{
+						this._insertChild(children[i], z);
+						i++;
+					}
+					catch(e){
+						console.error("Unable to insert child in GridContainer", e);
+					}
+					mod--;
+				}
+				else if(numPerZone === 0){
+					break;	// Optimization
+				}
+			}
+		},
+
+		_organizeChildrenManually: function (){
+			// summary:
+			//		Organize children by column property of widget.
+
+			//console.log("dojox.layout.GridContainerLite ::: _organizeChildrenManually");
+			var children = dojox.layout.GridContainerLite.superclass.getChildren.call(this),
+				length = children.length,
+				child;
+			for(var i = 0; i < length; i++){
+				child = children[i];
+				try{
+					this._insertChild(child, child.column - 1);
+				}
 				catch(e){
 					console.error("Unable to insert child in GridContainer", e);
 				}
-				mod--;
 			}
-			else if(numPerZone === 0){
-				break;	// Optimization
+		},
+
+		_insertChild: function(/*Widget*/child, /*Integer*/column, /*Integer?*/p){
+			// summary:
+			//		Insert a child in a specific column of the GridContainer widget.
+			// column:
+			//		Column number
+			// p:
+			//		Place in the zone (0 - first)
+			// returns:
+			//		The widget inserted
+
+			//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){
+				p = length;
 			}
-		}
-	},
-
-	_organizeChildrenManually: function (){
-		// summary:
-		//		Organize children by column property of widget.
-
-		//console.log("dojox.layout.GridContainerLite ::: _organizeChildrenManually");
-		var children = dojox.layout.GridContainerLite.superclass.getChildren.call(this),
-			length = children.length,
-			child;
-		for(var i = 0; i < length; i++){
-			child = children[i];
-			try{
-				this._insertChild(child, child.column - 1);
+			if(this._disabled){
+				dojo.place(child.domNode, zone, p);
+				dojo.attr(child.domNode, "tabIndex", "0");
 			}
-			catch(e){
-				console.error("Unable to insert child in GridContainer", e);
+			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");
+				}
 			}
-		}
-	},
-
-	_insertChild: function(/*Widget*/child, /*Integer*/column, /*Integer?*/p){
-		// summary:
-		//		Insert a child in a specific column of the GridContainer widget.
-		// column:
-		//		Column number
-		// p:
-		//		Place in the zone (0 - first)
-		// returns:
-		//		The widget inserted
-
-		//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){
-			p = length;
-		}
-		if(this._disabled){
-			dojo.place(child.domNode, zone, p);
-			dojo.attr(child.domNode, "tabIndex", "0");
-		}
-		else{
-			if(!child.dragRestriction){
-				this._dragManager.addDragItem(zone, child.domNode, p, true);
+			child.set("column", column);
+			return child; // Widget
+		},
+
+		removeChild: function(/*Widget*/ widget){
+			//console.log("dojox.layout.GridContainerLite ::: removeChild");
+			if(this._disabled){
+				this.inherited(arguments);
 			}
 			else{
-				dojo.place(child.domNode, zone, p);
-				dojo.attr(child.domNode, "tabIndex", "0");
+				this._dragManager.removeDragItem(widget.domNode.parentNode, widget.domNode);
 			}
-		}
-		child.set("column", column);
-		return child; // Widget
-	},
-
-	removeChild: function(/*Widget*/ widget){
-		//console.log("dojox.layout.GridContainerLite ::: removeChild");
-		if(this._disabled){
-			this.inherited(arguments);
-		}
-		else{
-			this._dragManager.removeDragItem(widget.domNode.parentNode, widget.domNode);
-		}
-	},
+		},
+
+		addService: function(/*Object*/child, /*Integer?*/column, /*Integer?*/p){
+			//console.log("dojox.layout.GridContainerLite ::: addService");
+			dojo.deprecated("addService is deprecated.", "Please use  instead.", "Future");
+			this.addChild(child, column, p);
+		},
+
+		addChild: function(/*Object*/child, /*Integer?*/column, /*Integer?*/p){
+			// summary:
+			//		Add a child in a specific column of the GridContainer widget.
+			// child:
+			//		widget to insert
+			// column:
+			//		column number
+			// p:
+			//		place in the zone (first = 0)
+			// returns:
+			//		The widget inserted
+
+			//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(p <= 0){ p = 0; }
+			try{
+				return this._insertChild(child, column, p);
+			}
+			catch(e){
+				console.error("Unable to insert child in GridContainer", e);
+			}
+			return null; 	// Widget
+		},
 
-	addService: function(/*Object*/child, /*Integer?*/column, /*Integer?*/p){
-		//console.log("dojox.layout.GridContainerLite ::: addService");
-		dojo.deprecated("addService is deprecated.", "Please use  instead.", "Future");
-		this.addChild(child, column, p);
-	},
+		_setColWidthsAttr: function(value){
+			this.colWidths = dojo.isString(value) ? value.split(",") : (dojo.isArray(value) ? value : [value]);
 
-	addChild: function(/*Object*/child, /*Integer?*/column, /*Integer?*/p){
-		// summary:
-		//		Add a child in a specific column of the GridContainer widget.
-		// child:
-		//		widget to insert
-		// column:
-		//		column number
-		// p:
-		//		place in the zone (first = 0)
-		// returns:
-		//		The widget inserted
-
-		//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(p <= 0){ p = 0; }
-		try{
-			return this._insertChild(child, column, p);
-		}
-		catch(e){
-			console.error("Unable to insert child in GridContainer", e);
-		}
-		return null; 	// Widget
-	},
-	
-	_setColWidthsAttr: function(value){
-		this.colWidths = dojo.isString(value) ? value.split(",") : (dojo.isArray(value) ? value : [value]);
-		
-		if(this._started){
-			this._updateColumnsWidth();
-		}
-	},
-	
-	_updateColumnsWidth: function(/*Object*/ manager){
-		// summary:
-		//		Update the columns width.
-		// manager:
-		//		dojox.mdnd.AreaManager singleton
-		// tags:
-		//		private
-
-		//console.log("dojox.layout.GridContainer ::: _updateColumnsWidth");
-		var length = this._grid.length;
-
-		var origWidths = this.colWidths || [];
-		var widths = [];
-		var colWidth;
-		var widthSum = 0;
-		var i;
-
-		// Calculate the widths of each column.
-		for(i = 0; i < length; i++){
-			if(widths.length < origWidths.length){
-				widthSum += origWidths[i] * 1;
-				widths.push(origWidths[i]);
-			}else{
-				if(!colWidth){
-					colWidth = (100 - widthSum)/(this.nbZones - i);
-					
-					// If the numbers don't work out, make the remaining columns
-					// an even width and let the code below average
-					// out the differences.
-					if(colWidth < 0){
-						colWidth = 100 / this.nbZones;
+			if(this._started){
+				this._updateColumnsWidth();
+			}
+		},
+
+		_updateColumnsWidth: function(/*Object*/ manager){
+			// summary:
+			//		Update the columns width.
+			// manager:
+			//		dojox.mdnd.AreaManager singleton
+			// tags:
+			//		private
+
+			//console.log("dojox.layout.GridContainer ::: _updateColumnsWidth");
+			var length = this._grid.length;
+
+			var origWidths = this.colWidths || [];
+			var widths = [];
+			var colWidth;
+			var widthSum = 0;
+			var i;
+
+			// Calculate the widths of each column.
+			for(i = 0; i < length; i++){
+				if(widths.length < origWidths.length){
+					widthSum += origWidths[i] * 1;
+					widths.push(origWidths[i]);
+				}else{
+					if(!colWidth){
+						colWidth = (100 - widthSum)/(this.nbZones - i);
+
+						// If the numbers don't work out, make the remaining columns
+						// an even width and let the code below average
+						// out the differences.
+						if(colWidth < 0){
+							colWidth = 100 / this.nbZones;
+						}
 					}
+					widths.push(colWidth);
+					widthSum += colWidth * 1;
 				}
-				widths.push(colWidth);
-				widthSum += colWidth * 1;
 			}
-		}
 
-		// If the numbers are wrong, divide them all so they add up to 100
-		if(widthSum > 100){
-			var divisor = 100 / widthSum;
-			for(i = 0; i < widths.length; i++){
-				widths[i] *= divisor;
+			// If the numbers are wrong, divide them all so they add up to 100
+			if(widthSum > 100){
+				var divisor = 100 / widthSum;
+				for(i = 0; i < widths.length; i++){
+					widths[i] *= divisor;
+				}
 			}
-		}
 
-		// Set the widths of each node
-		for(i = 0; i < length; i++){
-			this._grid[i].node.style.width = widths[i] + "%";
-		}
-	},
-
-	_selectFocus: function(/*Event*/event){
-		// summary:
-		//		Enable keyboard accessibility into the GridContainer.
-		// description:
-		//		Possibility to move focus into the GridContainer (TAB, LEFT ARROW, RIGHT ARROW, UP ARROW, DOWN ARROW).
-		//		Possibility to move GridContainer's children (Drag and Drop) with keyboard. (SHIFT +  ARROW).
-		//		If the type of widget is not draggable, a popup is displayed.
-
-		//console.log("dojox.layout.GridContainerLite ::: _selectFocus");
-		if(this._disabled){ return; }
-		var key = event.keyCode,
-			k = dojo.keys,
-			zone = null,
-			focus = dijit.getFocus(),
-			focusNode = focus.node,
-			m = this._dragManager,
-			found,
-			i,
-			j,
-			r,
-			children,
-			area,
-			widget;
-		if(focusNode == this.containerNode){
-			area = this.gridNode.childNodes;
-			switch(key){
-				case k.DOWN_ARROW:
-				case k.RIGHT_ARROW:
-					found = false;
-					for(i = 0; i < area.length; i++){
-						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);
-								found = true;
-								break;
-							}
-						}
-						if(found){ break };
-					}
-				break;
-				case k.UP_ARROW:
-				case k.LEFT_ARROW:
-					area = this.gridNode.childNodes;
-					found = false;
-					for(i = area.length-1; i >= 0 ; i--){
-						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);
-								found = true;
-								break;
-							}
-						}
-						if(found){ break };
-					}
-				break;
+			// Set the widths of each node
+			for(i = 0; i < length; i++){
+				this._grid[i].node.style.width = widths[i] + "%";
 			}
-		}
-		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";
+		},
+
+		_selectFocus: function(/*Event*/event){
+			// summary:
+			//		Enable keyboard accessibility into the GridContainer.
+			// description:
+			//		Possibility to move focus into the GridContainer (TAB, LEFT ARROW, RIGHT ARROW, UP ARROW, DOWN ARROW).
+			//		Possibility to move GridContainer's children (Drag and Drop) with keyboard. (SHIFT +  ARROW).
+			//		If the type of widget is not draggable, a popup is displayed.
+
+			//console.log("dojox.layout.GridContainerLite ::: _selectFocus");
+			if(this._disabled){ return; }
+			var key = event.keyCode,
+				k = dojo.keys,
+				zone = null,
+				focus = dijit.getFocus(),
+				focusNode = focus.node,
+				m = this._dragManager,
+				found,
+				i,
+				j,
+				r,
+				children,
+				area,
+				widget;
+			if(focusNode == this.containerNode){
+				area = this.gridNode.childNodes;
 				switch(key){
-					case k.UP_ARROW:
 					case k.DOWN_ARROW:
-						dojo.stopEvent(event);
+					case k.RIGHT_ARROW:
 						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(num > 1){ break; }
-							}
-							if(num == 1){ return; }
-							if(focusTemp[pos] == null){
-								zone = focusTemp.parentNode[child];
-							}
-							else{
-								zone = focusTemp[pos];
-							}
-							if(zone.style.display === "none"){
-								focusTemp = zone;
-							}
-							else{
-								found = true;
-							}
-						}
-						if(event.shiftKey){
-							var parent = focusNode.parentNode;
-							for(i = 0; i < this.gridNode.childNodes.length; i++){
-								if(parent == this.gridNode.childNodes[i]){
-									break;
-								}
-							}
-							children = this.gridNode.childNodes[i].childNodes;
+						for(i = 0; i < area.length; i++){
+							children = area[i].childNodes;
 							for(j = 0; j < children.length; j++){
-								if(zone == children[j]){
+								zone = children[j];
+								if(zone != null && zone.style.display != "none"){
+									dijit.focus(zone);
+									dojo.stopEvent(event);
+									found = true;
 									break;
 								}
 							}
-							if(dojo.isMoz || dojo.isWebKit){ i-- };
-
-							widget = dijit.byNode(focusNode);
-							if(!widget.dragRestriction){
-								r = m.removeDragItem(parent, focusNode);
-								this.addChild(widget, i, j);
-								dojo.attr(focusNode, "tabIndex", "0");
-								dijit.focus(focusNode);
-							}
-							else{
-								dojo.publish("/dojox/layout/gridContainer/moveRestriction", [this]);
-							}
-						}
-						else{
-							dijit.focus(zone);
+							if(found){ break };
 						}
 					break;
-					case k.RIGHT_ARROW:
+					case k.UP_ARROW:
 					case k.LEFT_ARROW:
-						dojo.stopEvent(event);
-						if(event.shiftKey){
-							var z = 0;
-							if(focusNode.parentNode[pos] == null){
-								if(dojo.isIE && key == k.LEFT_ARROW){
-									z = this.gridNode.childNodes.length-1;
+						area = this.gridNode.childNodes;
+						found = false;
+						for(i = area.length-1; i >= 0 ; i--){
+							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);
+									found = true;
+									break;
 								}
 							}
-							else if(focusNode.parentNode[pos].nodeType == 3){
-								z = this.gridNode.childNodes.length - 2;
+							if(found){ break };
+						}
+					break;
+				}
+			}
+			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);
+							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(num > 1){ break; }
+								}
+								if(num == 1){ return; }
+								if(focusTemp[pos] == null){
+									zone = focusTemp.parentNode[child];
+								}
+								else{
+									zone = focusTemp[pos];
+								}
+								if(zone.style.display === "none"){
+									focusTemp = zone;
+								}
+								else{
+									found = true;
+								}
 							}
-							else{
+							if(event.shiftKey){
+								var parent = focusNode.parentNode;
 								for(i = 0; i < this.gridNode.childNodes.length; i++){
-									if(focusNode.parentNode[pos] == this.gridNode.childNodes[i]){
+									if(parent == this.gridNode.childNodes[i]){
 										break;
 									}
-									z++;
 								}
-								if(dojo.isMoz || dojo.isWebKit){ z-- };
-							}
-							widget = dijit.byNode(focusNode);
-							var _dndType = focusNode.getAttribute("dndtype");
-							if(_dndType == null){
-								//check if it's a dijit object
-								if(widget && widget.dndType){
-									_dndType = widget.dndType.split(/\s*,\s*/);
+								children = this.gridNode.childNodes[i].childNodes;
+								for(j = 0; j < children.length; j++){
+									if(zone == children[j]){
+										break;
+									}
+								}
+								if(dojo.isMoz || dojo.isWebKit){ i-- };
+
+								widget = dijit.byNode(focusNode);
+								if(!widget.dragRestriction){
+									r = m.removeDragItem(parent, focusNode);
+									this.addChild(widget, i, j);
+									dojo.attr(focusNode, "tabIndex", "0");
+									dijit.focus(focusNode);
 								}
 								else{
-									_dndType = ["text"];
+									dojo.publish("/dojox/layout/gridContainer/moveRestriction", [this]);
 								}
 							}
 							else{
-								_dndType = _dndType.split(/\s*,\s*/);
+								dijit.focus(zone);
 							}
-							var accept = false;
-							for(i = 0; i < this.acceptTypes.length; i++){
-								for(j = 0; j < _dndType.length; j++){
-									if(_dndType[j] == this.acceptTypes[i]){
-										accept = true;
-										break;
+						break;
+						case k.RIGHT_ARROW:
+						case k.LEFT_ARROW:
+							dojo.stopEvent(event);
+							if(event.shiftKey){
+								var z = 0;
+								if(focusNode.parentNode[pos] == null){
+									if(dojo.isIE && key == k.LEFT_ARROW){
+										z = this.gridNode.childNodes.length-1;
 									}
 								}
-							}
-							if(accept && !widget.dragRestriction){
-								var parentSource = focusNode.parentNode,
-									place = 0;
-								if(k.LEFT_ARROW == key){
-									var t = z;
-									if(dojo.isMoz || dojo.isWebKit){ 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);
-							}
-							else{
-								dojo.publish("/dojox/layout/gridContainer/moveRestriction", [this]);
-							}
-						}
-						else{
-							var node = focusNode.parentNode;
-							while(zone === null){
-								if(node[pos] !== null && node[pos].nodeType !== 3){
-									node = node[pos];
+								else if(focusNode.parentNode[pos].nodeType == 3){
+									z = this.gridNode.childNodes.length - 2;
 								}
 								else{
-									if(pos === "previousSibling"){
-										node = node.parentNode.childNodes[node.parentNode.childNodes.length-1];
+									for(i = 0; i < this.gridNode.childNodes.length; i++){
+										if(focusNode.parentNode[pos] == this.gridNode.childNodes[i]){
+											break;
+										}
+										z++;
+									}
+									if(dojo.isMoz || dojo.isWebKit){ z-- };
+								}
+								widget = dijit.byNode(focusNode);
+								var _dndType = focusNode.getAttribute("dndtype");
+								if(_dndType == null){
+									//check if it's a dijit object
+									if(widget && widget.dndType){
+										_dndType = widget.dndType.split(/\s*,\s*/);
 									}
 									else{
-										node = (dojo.isIE)? node.parentNode.childNodes[0]: node.parentNode.childNodes[1];
+										_dndType = ["text"];
 									}
 								}
-								zone = node[child];
-								if(zone && zone.style.display == "none"){
-									// check that all elements are not hidden
-									children = zone.parentNode.childNodes;
-									var childToSelect = null;
-									if(pos == "previousSibling"){
-										for(i = children.length-1; i >= 0; i--){
-											if(children[i].style.display != "none"){
-												childToSelect = children[i];
-												break;
-											}
+								else{
+									_dndType = _dndType.split(/\s*,\s*/);
+								}
+								var accept = false;
+								for(i = 0; i < this.acceptTypes.length; i++){
+									for(j = 0; j < _dndType.length; j++){
+										if(_dndType[j] == this.acceptTypes[i]){
+											accept = true;
+											break;
 										}
 									}
-									else{
-										for(i = 0; i < children.length; i++){
-											if(children[i].style.display != "none"){
-												childToSelect = children[i];
-												break;
-											}
-										}
+								}
+								if(accept && !widget.dragRestriction){
+									var parentSource = focusNode.parentNode,
+										place = 0;
+									if(k.LEFT_ARROW == key){
+										var t = z;
+										if(dojo.isMoz || dojo.isWebKit){ t = z + 1 };
+										place = this.gridNode.childNodes[t].childNodes.length;
 									}
-									if(!childToSelect){
-										focusNode = zone;
-										node = focusNode.parentNode;
-										zone = null;
+									// delete of manager :
+									r = m.removeDragItem(parentSource, focusNode);
+									this.addChild(widget, z, place);
+									dojo.attr(r, "tabIndex", "0");
+									dijit.focus(r);
+								}
+								else{
+									dojo.publish("/dojox/layout/gridContainer/moveRestriction", [this]);
+								}
+							}
+							else{
+								var node = focusNode.parentNode;
+								while(zone === null){
+									if(node[pos] !== null && node[pos].nodeType !== 3){
+										node = node[pos];
 									}
 									else{
-										zone = childToSelect;
+										if(pos === "previousSibling"){
+											node = node.parentNode.childNodes[node.parentNode.childNodes.length-1];
+										}
+										else{
+											node = (dojo.isIE)? node.parentNode.childNodes[0]: node.parentNode.childNodes[1];
+										}
+									}
+									zone = node[child];
+									if(zone && zone.style.display == "none"){
+										// check that all elements are not hidden
+										children = zone.parentNode.childNodes;
+										var childToSelect = null;
+										if(pos == "previousSibling"){
+											for(i = children.length-1; i >= 0; i--){
+												if(children[i].style.display != "none"){
+													childToSelect = children[i];
+													break;
+												}
+											}
+										}
+										else{
+											for(i = 0; i < children.length; i++){
+												if(children[i].style.display != "none"){
+													childToSelect = children[i];
+													break;
+												}
+											}
+										}
+										if(!childToSelect){
+											focusNode = zone;
+											node = focusNode.parentNode;
+											zone = null;
+										}
+										else{
+											zone = childToSelect;
+										}
 									}
 								}
+								dijit.focus(zone);
 							}
-							dijit.focus(zone);
-						}
-					break;
+						break;
+					}
 				}
 			}
+		},
+
+		destroy: function(){
+			//console.log("dojox.layout.GridContainerLite ::: destroy");
+			var m = this._dragManager;
+			dojo.forEach(this._grid, function(dropZone){
+				m.unregister(dropZone.node);
+			});
+			this.inherited(arguments);
 		}
-	},
-
-	destroy: function(){
-		//console.log("dojox.layout.GridContainerLite ::: destroy");
-		var m = this._dragManager;
-		dojo.forEach(this._grid, function(dropZone){
-			m.unregister(dropZone.node);
-		});
-		this.inherited(arguments);
-	}
-});
-
-dojo.extend(dijit._Widget, {
-
-	// column: String
-	//		Column of the grid to place the widget.
-	//		Defined only if dojo.require("dojox.layout.GridContainerLite") is done.
-	column : "1",
-
-	// dragRestriction: Boolean
-	//		If true, the widget can not be draggable.
-	//		Defined only if dojo.require("dojox.layout.GridContainerLite") is done.
-	dragRestriction : false
+	});
+
+	dojo.extend(dijit._Widget, {
+
+		// column: String
+		//		Column of the grid to place the widget.
+		//		Defined only if dojo.require("dojox.layout.GridContainerLite") is done.
+		column : "1",
+
+		// dragRestriction: Boolean
+		//		If true, the widget can not be draggable.
+		//		Defined only if dojo.require("dojox.layout.GridContainerLite") is done.
+		dragRestriction : false
+	});
+	return gcl;
 });
\ No newline at end of file
diff --git a/dojox/layout/RadioGroup.js b/dojox/layout/RadioGroup.js
index 14dfefe..cacaed1 100644
--- a/dojox/layout/RadioGroup.js
+++ b/dojox/layout/RadioGroup.js
@@ -1,5 +1,10 @@
-dojo.provide("dojox.layout.RadioGroup");
-dojo.experimental("dojox.layout.RadioGroup");
+define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/lang","dojo/_base/query",
+		"dijit/_Widget","dijit/_Templated","dijit/_Contained","dijit/layout/StackContainer",
+		"dojo/fx/easing","dojo/_base/fx","dojo/dom-construct","dojo/dom-class"],function(
+	kernel,declare,html,lang,query,Widget,Templated,Contained,StackContainer,easing,baseFx,domConstruct,domClass){
+
+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
@@ -8,15 +13,14 @@ dojo.experimental("dojox.layout.RadioGroup");
 //	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?
 //
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._Contained");
-dojo.require("dijit.layout.StackContainer");
-dojo.require("dojo.fx.easing");
-
-dojo.declare("dojox.layout.RadioGroup",
-	[dijit.layout.StackContainer,dijit._Templated],
-	{
+/*=====
+	var StackContainer = dijit.layout.StackContainer,
+		Templated = dijit._Templated,
+		Contained = dijit._Contained,
+		Widget = dijit._Widget;
+=====*/
+
+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
 	//
@@ -48,27 +52,27 @@ dojo.declare("dojox.layout.RadioGroup",
 		this.inherited(arguments);
 		this._children = this.getChildren();
 		this._buttons = this._children.length;
-		this._size = dojo.coords(this.containerNode);
+		this._size = html.coords(this.containerNode);
 		if(this.hasButtons){
-			dojo.style(this.buttonHolder, "display", "block");
+			html.style(this.buttonHolder, "display", "block");
 		}
 	},
 
 	_setupChild: function(/* dijit._Widget */child){
 		// summary: Creates a hover button for a child node of the RadioGroup
-		dojo.style(child.domNode, "position", "absolute");
+		html.style(child.domNode, "position", "absolute");
 		if(this.hasButtons){
 			
-			var tmp = this.buttonNode.appendChild(dojo.create('td'));
-			var n = dojo.create("div", null, tmp),
-				_Button = dojo.getObject(this.buttonClass),
+			var tmp = this.buttonNode.appendChild(domConstruct.create('td'));
+			var n = domConstruct.create("div", null, tmp),
+				_Button = lang.getObject(this.buttonClass),
 				tmpw = new _Button({
 					label: child.title,
 					page: child
 				}, n)
 			;
 			
-			dojo.mixin(child, { _radioButton: tmpw });
+			lang.mixin(child, { _radioButton: tmpw });
 			tmpw.startup();
 		}
 		child.domNode.style.display = "none";
@@ -125,34 +129,30 @@ dojo.declare("dojox.layout.RadioGroup",
 
 });
 
-dojo.declare("dojox.layout.RadioGroupFade",
-	dojox.layout.RadioGroup,
-	{
+declare("dojox.layout.RadioGroupFade", RadioGroup, {
 	// summary: An extension on a stock RadioGroup, that fades the panes.
 
 	_hideChild: function(page){
 		// summary: hide the specified child widget
-		dojo.fadeOut({
+		baseFx.fadeOut({
 			node:page.domNode,
 			duration:this.duration,
-			onEnd: dojo.hitch(this,"inherited", arguments, arguments)
+			onEnd: lang.hitch(this,"inherited", arguments, arguments)
 		}).play();
 	},
 
 	_showChild: function(page){
 		// summary: show the specified child widget
 		this.inherited(arguments);
-		dojo.style(page.domNode, "opacity", 0);
-		dojo.fadeIn({
+		html.style(page.domNode, "opacity", 0);
+		baseFx.fadeIn({
 			node:page.domNode,
 			duration:this.duration
 		}).play();
 	}
 });
 
-dojo.declare("dojox.layout.RadioGroupSlide",
-	dojox.layout.RadioGroup,
-	{
+declare("dojox.layout.RadioGroupSlide", RadioGroup, {
 	// summary: A Sliding Radio Group
 	// description:
 	//		An extension on a stock RadioGroup widget, sliding the pane
@@ -169,15 +169,16 @@ dojo.declare("dojox.layout.RadioGroupSlide",
 	zTop: 99,
 	
 	constructor: function(){
-		if(dojo.isString(this.easing)){
-			this.easing = dojo.getObject(this.easing);
+		if(lang.isString(this.easing)){
+			this.easing = lang.getObject(this.easing);
 		}
 	},
 	
 	_positionChild: function(page){
 		// summary: set the child out of view immediately after being hidden
-		
-		if(!this._size){ return; } // FIXME: is there a real "size" floating around always?
+
+		// FIXME: is there a real "size" floating around always?
+		if(!this._size){ return; } 
 		
 		// there should be a contest: obfuscate this function as best you can.
 		var rA = true, rB = true;
@@ -194,7 +195,7 @@ dojo.declare("dojox.layout.RadioGroupSlide",
 		var prop = rA ? "top" : "left",
 			val = (rB ? "-" : "") + (this._size[rA ? "h" : "w" ] + 20) + "px";
 			
-		dojo.style(page.domNode, prop, val);
+		html.style(page.domNode, prop, val);
 
 	},
 
@@ -206,7 +207,7 @@ dojo.declare("dojox.layout.RadioGroupSlide",
 		page.isLastChild = (page == children[children.length-1]);
 		page.selected = true;
 
-		dojo.style(page.domNode,{
+		html.style(page.domNode,{
 			zIndex: this.zTop, display:""
 		})
 
@@ -214,7 +215,7 @@ dojo.declare("dojox.layout.RadioGroupSlide",
 			this._anim.gotoPercent(100,true);
 		}
 		
-		this._anim = dojo.animateProperty({
+		this._anim = baseFx.animateProperty({
 			node:page.domNode,
 			properties: {
 				left: 0,
@@ -222,11 +223,11 @@ dojo.declare("dojox.layout.RadioGroupSlide",
 			},
 			duration: this.duration,
 			easing: this.easing,
-			onEnd: dojo.hitch(page, function(){
+			onEnd: lang.hitch(page, function(){
 				if(this.onShow){ this.onShow(); }
 				if(this._onShow){ this._onShow(); }
 			}),
-			beforeBegin: dojo.hitch(this, "_positionChild", page)
+			beforeBegin: lang.hitch(this, "_positionChild", page)
 		});
 		this._anim.play();
 	},
@@ -244,9 +245,7 @@ dojo.declare("dojox.layout.RadioGroupSlide",
 	
 });
 
-dojo.declare("dojox.layout._RadioButton",
-	[dijit._Widget,dijit._Templated,dijit._Contained],
-	{
+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.
@@ -270,7 +269,7 @@ dojo.declare("dojox.layout._RadioButton",
 		// summary: set the selected child on hover, and set our hover state class
 		this.getParent().selectChild(this.page);
 		this._clearSelected();
-		dojo.addClass(this.domNode,"dojoxRadioButtonSelected");
+		domClass.add(this.domNode,"dojoxRadioButtonSelected");
 
 	},
 
@@ -279,14 +278,14 @@ dojo.declare("dojox.layout._RadioButton",
 		//	than setting up an additional connection to onMouseOut
 		
 		// FIXME: this relies on the template being [div][span]node[/span][/div]
-		dojo.query(".dojoxRadioButtonSelected", this.domNode.parentNode.parentNode)
+		query(".dojoxRadioButtonSelected", this.domNode.parentNode.parentNode)
 			.removeClass("dojoxRadioButtonSelected")
 		;
 	}
 	
 });
 
-dojo.extend(dijit._Widget,{
+lang.extend(Widget,{
 	// slideFrom: String
 	//		A parameter needed by RadioGroupSlide only. An optional paramter to force
 	//		the ContentPane to slide in from a set direction. Defaults
@@ -294,3 +293,4 @@ dojo.extend(dijit._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 83adc52..f678921 100644
--- a/dojox/layout/ResizeHandle.js
+++ b/dojox/layout/ResizeHandle.js
@@ -1,13 +1,17 @@
-dojo.provide("dojox.layout.ResizeHandle");
-dojo.experimental("dojox.layout.ResizeHandle");
+define(["dojo/_base/kernel","dojo/_base/lang","dojo/_base/connect","dojo/_base/array","dojo/_base/event",
+	"dojo/_base/fx","dojo/_base/window","dojo/fx","dojo/window","dojo/dom","dojo/dom-class",
+	"dojo/dom-geometry","dojo/dom-style","dijit/_base/manager","dijit/_Widget","dijit/_TemplatedMixin",
+	"dojo/_base/declare"], function (
+	kernel, lang, connect, arrayUtil, eventUtil, fxBase, windowBase, fxUtil, windowUtil, 
+	domUtil, domClass, domGeometry, domStyle, manager, Widget, TemplatedMixin, declare) {
 
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dojo.fx");
-dojo.require("dojo.window");
+kernel.experimental("dojox.layout.ResizeHandle");
 
-dojo.declare("dojox.layout.ResizeHandle",
-	[dijit._Widget, dijit._Templated],
+/*===== 
+	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.
 	//
@@ -103,12 +107,12 @@ dojo.declare("dojox.layout.ResizeHandle",
 			// level so that we can overlay it on anything whenever the user
 			// resizes something. Since there is only one mouse pointer he
 			// can't at once resize multiple things interactively.
-			this._resizeHelper = dijit.byId('dojoxGlobalResizeHelper');
+			this._resizeHelper = manager.byId('dojoxGlobalResizeHelper');
 			if(!this._resizeHelper){
-				this._resizeHelper = new dojox.layout._ResizeHelper({
+				this._resizeHelper = new _ResizeHelper({
 						id: 'dojoxGlobalResizeHelper'
-				}).placeAt(dojo.body());
-				dojo.addClass(this._resizeHelper.domNode, this.activeResizeClass);
+				}).placeAt(windowBase.body());
+				domClass.add(this._resizeHelper.domNode, this.activeResizeClass);
 			}
 		}else{ this.animateSizing = false; }
 
@@ -122,7 +126,7 @@ dojo.declare("dojox.layout.ResizeHandle",
 		
 		// should we modify the css for the cursor hover to n-resize nw-resize and w-resize?
 		this._resizeX = this._resizeY = false;
-		var addClass = dojo.partial(dojo.addClass, this.resizeHandle);
+		var addClass = lang.partial(domClass.add, this.resizeHandle);
 		switch(this.resizeAxis.toLowerCase()){
 			case "xy" :
 				this._resizeX = this._resizeY = true;
@@ -144,48 +148,46 @@ dojo.declare("dojox.layout.ResizeHandle",
 	_beginSizing: function(/*Event*/ e){
 		// summary: setup movement listeners and calculate initial size
 		
-		if(this._isSizing){ return false; }
+		if(this._isSizing){ return; }
 
-		dojo.publish(this.startTopic, [ this ]);
-		this.targetWidget = dijit.byId(this.targetId);
+		connect.publish(this.startTopic, [ this ]);
+		this.targetWidget = manager.byId(this.targetId);
 
-		this.targetDomNode = this.targetWidget ? this.targetWidget.domNode : dojo.byId(this.targetId);
+		this.targetDomNode = this.targetWidget ? this.targetWidget.domNode : domUtil.byId(this.targetId);
 		if(this.targetContainer){ this.targetDomNode = this.targetContainer; }
-		if(!this.targetDomNode){ return false; }
+		if(!this.targetDomNode){ return; }
 
 		if(!this.activeResize){
-			var c = dojo.position(this.targetDomNode, true);
-			console.log(c);
-			console.log(dojo.window.getBox());
+			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();
 		}
 
 		this._isSizing = true;
-		this.startPoint  = { x:e.clientX, y:e.clientY};
+		this.startPoint  = { x:e.clientX, y:e.clientY };
 
-		// FIXME: this is funky: marginBox adds height, contentBox ignores padding (expected, but foo!)
-		var mb = this.targetWidget ? dojo.marginBox(this.targetDomNode) : dojo.contentBox(this.targetDomNode);
-		this.startSize  = { w:mb.w, h:mb.h };
+		// widget.resize() or setting style.width/height expects native box model dimension 
+		// (in most cases content-box, but it may be border-box if in backcompact mode)
+		var style = domStyle.getComputedStyle(this.targetDomNode), 
+			borderModel = domGeometry.boxModel==='border-model',
+			padborder = borderModel?{w:0,h:0}:domGeometry.getPadBorderExtents(this.targetDomNode, style),
+			margin = domGeometry.getMarginExtents(this.targetDomNode, style),
+			mb;
+		mb = this.startSize = { 
+				w: domStyle.get(this.targetDomNode, 'width', style), 
+				h: domStyle.get(this.targetDomNode, 'height', style),
+				//ResizeHelper.resize expects a bounding box of the
+				//border box, so let's keep track of padding/border
+				//width/height as well
+				pbw: padborder.w, pbh: padborder.h,
+				mw: margin.w, mh: margin.h};
 		
-		if(this.fixedAspect){
-			var max, val;
-			if(mb.w > mb.h){
-				max = "w";
-				val = mb.w / mb.h
-			}else{
-				max = "h";
-				val = mb.h / mb.w
-			}
-			this._aspect = { prop: max };
-			this._aspect[max] = val;
-		}
-
-		this._pconnects = [];
-		this._pconnects.push(dojo.connect(dojo.doc,"onmousemove",this,"_updateSizing"));
-		this._pconnects.push(dojo.connect(dojo.doc,"onmouseup", this, "_endSizing"));
+		this._pconnects = [
+			connect.connect(windowBase.doc,"onmousemove",this,"_updateSizing"),
+			connect.connect(windowBase.doc,"onmouseup", this, "_endSizing")
+		];
 		
-		dojo.stopEvent(e);
+		eventUtil.stop(e);
 	},
 
 	_updateSizing: function(/*Event*/ e){
@@ -195,14 +197,14 @@ dojo.declare("dojox.layout.ResizeHandle",
 		if(this.activeResize){
 			this._changeSizing(e);
 		}else{
-			var tmp = this._getNewCoords(e);
+			var tmp = this._getNewCoords(e, 'border');
 			if(tmp === false){ return; }
 			this._resizeHelper.resize(tmp);
 		}
 		e.preventDefault();
 	},
 
-	_getNewCoords: function(/* Event */ e){
+	_getNewCoords: function(/* Event */ e, /* String */ box){
 		
 		// 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.
@@ -214,13 +216,26 @@ dojo.declare("dojox.layout.ResizeHandle",
 		}
 		this._activeResizeLastEvent = e;
 
-		var dx = (this.isLeftToRight()? this.startPoint.x - e.clientX: e.clientX - this.startPoint.x),
+		var dx = (this.isLeftToRight()?1:-1) * (this.startPoint.x - e.clientX),
 			dy = this.startPoint.y - e.clientY,
 			newW = this.startSize.w - (this._resizeX ? dx : 0),
-			newH = this.startSize.h - (this._resizeY ? dy : 0)
+			newH = this.startSize.h - (this._resizeY ? dy : 0),
+			r = this._checkConstraints(newW, newH)
 		;
-			
-		return this._checkConstraints(newW, newH); // Object
+		
+		switch(box){
+			case 'margin':
+				r.w += this.startSize.mw;
+				r.h += this.startSize.mh;
+				//pass through
+			case "border":
+				r.w += this.startSize.pbw;
+				r.h += this.startSize.pbh;
+				break;
+			//default: //native, do nothing
+		}
+
+		return r; // Object
 	},
 	
 	_checkConstraints: function(newW, newH){
@@ -249,11 +264,12 @@ dojo.declare("dojox.layout.ResizeHandle",
 		}
 		
 		if(this.fixedAspect){
-			var ta = this._aspect[this._aspect.prop];
-			if(newW < newH){
-				newH = newW * ta;
-			}else if(newH < newW){
-				newW = newH * ta;
+			var w = this.startSize.w, h = this.startSize.h,
+				delta = w * newH - h * newW;
+			if(delta<0){
+				newW = newH * w / h;
+			}else if(delta>0){
+				newH = newW * h / w;
 			}
 		}
 		
@@ -262,22 +278,24 @@ dojo.declare("dojox.layout.ResizeHandle",
 		
 	_changeSizing: function(/*Event*/ e){
 		// summary: apply sizing information based on information in (e) to attached node
-		var tmp = this._getNewCoords(e);
+		
+		var isWidget = this.targetWidget && lang.isFunction(this.targetWidget.resize),
+			tmp = this._getNewCoords(e, isWidget && 'margin');
 		if(tmp === false){ return; }
 
-		if(this.targetWidget && dojo.isFunction(this.targetWidget.resize)){
+		if(isWidget){
 			this.targetWidget.resize(tmp);
 		}else{
 			if(this.animateSizing){
-				var anim = dojo.fx[this.animateMethod]([
-					dojo.animateProperty({
+				var anim = fxUtil[this.animateMethod]([
+					fxBase.animateProperty({
 						node: this.targetDomNode,
 						properties: {
 							width: { start: this.startSize.w, end: tmp.w }
 						},
 						duration: this.animateDuration
 					}),
-					dojo.animateProperty({
+					fxBase.animateProperty({
 						node: this.targetDomNode,
 						properties: {
 							height: { start: this.startSize.h, end: tmp.h }
@@ -287,7 +305,7 @@ dojo.declare("dojox.layout.ResizeHandle",
 				]);
 				anim.play();
 			}else{
-				dojo.style(this.targetDomNode,{
+				domStyle.set(this.targetDomNode,{
 					width: tmp.w + "px",
 					height: tmp.h + "px"
 				});
@@ -300,8 +318,8 @@ dojo.declare("dojox.layout.ResizeHandle",
 
 	_endSizing: function(/*Event*/ e){
 		// summary: disconnect listenrs and cleanup sizing
-		dojo.forEach(this._pconnects, dojo.disconnect);
-		var pub = dojo.partial(dojo.publish, this.endTopic, [ this ]);
+		arrayUtil.forEach(this._pconnects, connect.disconnect);
+		var pub = lang.partial(connect.publish, this.endTopic, [ this ]);
 		if(!this.activeResize){
 			this._resizeHelper.hide();
 			this._changeSizing(e);
@@ -321,35 +339,25 @@ dojo.declare("dojox.layout.ResizeHandle",
 	
 });
 
-dojo.declare("dojox.layout._ResizeHelper",
-	dijit._Widget,
-	{
+var _ResizeHelper = dojo.declare("dojox.layout._ResizeHelper", Widget, {
 	// summary: A global private resize helper shared between any
 	//		`dojox.layout.ResizeHandle` with activeSizing off.
 	
 	show: function(){
 		// summary: show helper to start resizing
-		dojo.fadeIn({
-			node: this.domNode,
-			duration: 120,
-			beforeBegin: function(n){ dojo.style(n, "display", "") }
-		}).play();
+		domStyle.set(this.domNode, "display", "");
 	},
 	
 	hide: function(){
 		// summary: hide helper after resizing is complete
-		dojo.fadeOut({
-			node: this.domNode,
-			duration: 250,
-			onEnd: function(n){ dojo.style(n, "display", "none") }
-		}).play();
+		domStyle.set(this.domNode, "display", "none");
 	},
 	
 	resize: function(/* Object */dim){
 		// summary: size the widget and place accordingly
-
-		// FIXME: this is off when padding present
-		dojo.marginBox(this.domNode, dim);
+		domGeometry.setMarginBox(this.domNode, dim);
 	}
 	
 });
+return ResizeHandle;
+});
diff --git a/dojox/layout/RotatorContainer.js b/dojox/layout/RotatorContainer.js
index 33718de..a5c6b19 100755
--- a/dojox/layout/RotatorContainer.js
+++ b/dojox/layout/RotatorContainer.js
@@ -1,14 +1,17 @@
-dojo.provide("dojox.layout.RotatorContainer");
-
-dojo.require("dojo.fx");
-dojo.require("dijit.layout.StackContainer");
-dojo.require("dijit.layout.StackController");
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._Contained");
-
-dojo.declare("dojox.layout.RotatorContainer",
-	[dijit.layout.StackContainer, dijit._Templated], {
+define(["dojo/_base/declare","dojo/_base/html","dojo/_base/connect","dojo/_base/lang","dojo/_base/array",
+	"dojo/_base/fx","dojo/fx","dijit/_base/manager","dijit/layout/StackContainer","dijit/layout/StackController","dijit/_Widget",
+	"dijit/_Templated","dijit/_Contained"
+],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.
@@ -90,7 +93,7 @@ dojo.declare("dojox.layout.RotatorContainer",
 		this.inherited(arguments);
 
 		// force this DOM node to a relative position and make sure the children are absolute positioned
-		dojo.style(this.domNode, "position", "relative");
+		html.style(this.domNode, "position", "relative");
 
 		// validate the cycles counter
 		if(this.cycles-0 == this.cycles && this.cycles != -1){
@@ -108,18 +111,18 @@ dojo.declare("dojox.layout.RotatorContainer",
 
 		// create the stack controller if we are using tabs
 		var id = this.id || "rotator"+(new Date()).getTime(),
-			sc = new dijit.layout.StackController({ containerId:id }, this.tabNode);
+			sc = new StackController({ containerId:id }, this.tabNode);
 		this.tabNode = sc.domNode;
 		this._stackController = sc;
-		dojo.style(this.tabNode, "display", this.showTabs ? "" : "none");
+		html.style(this.tabNode, "display", this.showTabs ? "" : "none");
 
 		// if the controller's tabs are clicked, check if we should pause and reset the cycle counter
 		this.connect(sc, "onButtonClick","_manualChange");
 
 		// set up our topic listeners
 		this._subscriptions = [
-			dojo.subscribe(this.id+"-cycle", this, "_cycle"),
-			dojo.subscribe(this.id+"-state", this, "_state")
+			connect.subscribe(this.id+"-cycle", this, "_cycle"),
+			connect.subscribe(this.id+"-state", this, "_state")
 		];
 
 		// make sure the transition duration isn't less than the transition delay
@@ -154,7 +157,7 @@ dojo.declare("dojox.layout.RotatorContainer",
 		// check if we should start automatically
 		if(this.autoStart){
 			// start playing
-			setTimeout(dojo.hitch(this, "_play"), 10);
+			setTimeout(lang.hitch(this, "_play"), 10);
 		}else{
 			// update the pagers with the initial state
 			this._updatePager();
@@ -163,19 +166,19 @@ dojo.declare("dojox.layout.RotatorContainer",
 
 	destroy: function(){
 		// summary: Unsubscribe to all of our topics
-		dojo.forEach(this._subscriptions, dojo.unsubscribe);
+		array.forEach(this._subscriptions, connect.unsubscribe);
 		this.inherited(arguments);
 	},
 
 	_setShowTabsAttr: function(/*anything*/value){
 		this.showTabs = value;
-		dojo.style(this.tabNode, "display", value ? "" : "none");
+		html.style(this.tabNode, "display", value ? "" : "none");
 	},
 
 	_updatePager: function(){
 		// summary: Notify the pager's current and total numbers.
 		var c = this.getChildren();
-		dojo.publish(this.id+"-update", [this._playing, dojo.indexOf(c, this.selectedChildWidget)+1, c.length]);
+		connect.publish(this.id+"-update", [this._playing, array.indexOf(c, this.selectedChildWidget)+1, c.length]);
 	},
 
 	_onMouseOver: function(){
@@ -194,7 +197,7 @@ dojo.declare("dojox.layout.RotatorContainer",
 		// we need to wait because we may be moused over again right away
 		if(this._playing){
 			clearTimeout(this._timer);
-			this._timer = setTimeout(dojo.hitch(this, "_play", true), 200);
+			this._timer = setTimeout(lang.hitch(this, "_play", true), 200);
 		}
 	},
 
@@ -215,7 +218,7 @@ dojo.declare("dojox.layout.RotatorContainer",
 
 		var c = this.getChildren(),
 			len = c.length,
-			i = dojo.indexOf(c, this.selectedChildWidget) + (next === false || (next !== true && this.reverse) ? -1 : 1);
+			i = array.indexOf(c, this.selectedChildWidget) + (next === false || (next !== true && this.reverse) ? -1 : 1);
 		this.selectChild(c[(i < len ? (i < 0 ? len-1 : i) : 0)]);
 		this._updatePager();
 	},
@@ -240,7 +243,7 @@ dojo.declare("dojox.layout.RotatorContainer",
 			this._pause();
 		}else if((!this.suspendOnHover || !this._over) && this.transitionDelay){
 			// check if current pane has a delay
-			this._timer = setTimeout(dojo.hitch(this, "_cycle"), this.selectedChildWidget.domNode.getAttribute("transitionDelay") || this.transitionDelay);
+			this._timer = setTimeout(lang.hitch(this, "_cycle"), this.selectedChildWidget.domNode.getAttribute("transitionDelay") || this.transitionDelay);
 		}
 		this._updatePager();
 	},
@@ -298,12 +301,12 @@ dojo.declare("dojox.layout.RotatorContainer",
 
 		// create the crossfade animation
 		var args = { duration:this.transitionDuration },
-			anim = dojo.fx.combine([
-				dojo["fadeOut"](dojo.mixin({node:prev.domNode}, args)),
-				dojo["fadeIn"](dojo.mixin({node:next.domNode}, args))
+			anim = coreFx.combine([
+				baseFx["fadeOut"](lang.mixin({node:prev.domNode}, args)),
+				baseFx["fadeIn"](lang.mixin({node:next.domNode}, args))
 			]);
 
-		this.connect(anim, "onEnd", dojo.hitch(this,function(){
+		this.connect(anim, "onEnd", lang.hitch(this,function(){
 			this._hideChild(prev);
 			this._transitionEnd();
 		}));
@@ -313,13 +316,13 @@ dojo.declare("dojox.layout.RotatorContainer",
 
 	_styleNode: function(/*DOMnode*/node, /*number*/opacity, /*int*/zIndex){
 		// summary: Helper function to style the children.
-		dojo.style(node, "opacity", opacity);
-		dojo.style(node, "zIndex", zIndex);
-		dojo.style(node, "position", "absolute");
+		html.style(node, "opacity", opacity);
+		html.style(node, "zIndex", zIndex);
+		html.style(node, "position", "absolute");
 	}
 });
 
-dojo.declare("dojox.layout.RotatorPager", [dijit._Widget, dijit._Templated, dijit._Contained], {
+declare("dojox.layout.RotatorPager", [Widget, Templated, Contained], {
 	// summary:
 	//		Defines controls used to manipulate a RotatorContainer
 	//
@@ -398,34 +401,34 @@ dojo.declare("dojox.layout.RotatorPager", [dijit._Widget, dijit._Templated, diji
 	},
 
 	postCreate: function(){
-		var p = dijit.byId(this.rotatorId) || this.getParent();
+		var p = manager.byId(this.rotatorId) || this.getParent();
 		if(p && p.declaredClass == "dojox.layout.RotatorContainer"){
 			if(this.previous){
-				dojo.connect(this.previous, "onClick", function(){
-					dojo.publish(p.id+"-cycle", [false]);
+				connect.connect(this.previous, "onClick", function(){
+					connect.publish(p.id+"-cycle", [false]);
 				});
 			}
 			if(this.next){
-				dojo.connect(this.next, "onClick", function(){
-					dojo.publish(p.id+"-cycle", [true]);
+				connect.connect(this.next, "onClick", function(){
+					connect.publish(p.id+"-cycle", [true]);
 				});
 			}
 			if(this.playPause){
-				dojo.connect(this.playPause, "onClick", function(){
+				connect.connect(this.playPause, "onClick", function(){
 					this.set('label', this.checked ? "Pause" : "Play");
-					dojo.publish(p.id+"-state", [this.checked]);
+					connect.publish(p.id+"-state", [this.checked]);
 				});
 			}
 			this._subscriptions = [
-				dojo.subscribe(p.id+"-state", this, "_state"),
-				dojo.subscribe(p.id+"-update", this, "_update")
+				connect.subscribe(p.id+"-state", this, "_state"),
+				connect.subscribe(p.id+"-update", this, "_update")
 			];
 		}
 	},
 
 	destroy: function(){
 		// summary: Unsubscribe to all of our topics
-		dojo.forEach(this._subscriptions, dojo.unsubscribe);
+		array.forEach(this._subscriptions, connect.unsubscribe);
 		this.inherited(arguments);
 	},
 
@@ -448,3 +451,5 @@ dojo.declare("dojox.layout.RotatorPager", [dijit._Widget, dijit._Templated, diji
 		}
 	}
 });
+return RotatorContainer;
+});
\ No newline at end of file
diff --git a/dojox/layout/ScrollPane.js b/dojox/layout/ScrollPane.js
index 2fb4f5d..fd437b6 100644
--- a/dojox/layout/ScrollPane.js
+++ b/dojox/layout/ScrollPane.js
@@ -1,12 +1,18 @@
-dojo.provide("dojox.layout.ScrollPane");
-dojo.experimental("dojox.layout.ScrollPane");
+define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/fx",
+		"dijit/_Templated","dijit/layout/ContentPane","dojo/dom-class",
+		"dojo/text!./resources/ScrollPane.html"],
+function(kernel,declare,html,baseFx,Templated,ContentPane,domClass,template){
 
-dojo.require("dijit.layout.ContentPane");
-dojo.require("dijit._Templated");
+kernel.experimental("dojox.layout.ScrollPane");
 
-dojo.declare("dojox.layout.ScrollPane",
-	[dijit.layout.ContentPane, dijit._Templated],
-	{
+// FIXME: need to adust the _line somehow, it stops scrolling
+	
+/*===== 
+	var ContentPane = dijit.layout.ContentPane,
+		Templated = dijit._Templated;
+=====*/
+
+declare("dojox.layout.ScrollPane",[ContentPane, Templated],{
 	// summary: A pane that "scrolls" its content based on the mouse poisition inside
 	//
 	// description:
@@ -17,8 +23,6 @@ dojo.declare("dojox.layout.ScrollPane",
 	//
 	// 		Horizontal scrolling is supported. Combination scrolling is not.
 	//
-	//		FIXME: need to adust the _line somehow, it stops scrolling
-	//
 	// example:
 	// |	<div dojoType="dojox.layout.ScrollPane" style="width:150px height:300px;">
 	// |		<!-- any height content -->
@@ -40,7 +44,7 @@ dojo.declare("dojox.layout.ScrollPane",
 	// alwaysShow: Boolean
 	//		whether the scroll helper should hide when mouseleave
 	autoHide: true,
-	templateString: dojo.cache("dojox.layout","resources/ScrollPane.html"),
+	templateString: template,
 	
 	resize: function(size){
 		// summary: calculates required sizes. Call this if you add/remove content manually, or reload the content.
@@ -48,18 +52,18 @@ dojo.declare("dojox.layout.ScrollPane",
 		// if size is passed, it means we need to take care of sizing ourself (this is for IE<8)
 		if(size){
 			if(size.h){
-				dojo.style(this.domNode,'height',size.h+'px');
+				html.style(this.domNode,'height',size.h+'px');
 			}
 			if(size.w){
-				dojo.style(this.domNode,'width',size.w+'px');
+				html.style(this.domNode,'width',size.w+'px');
 			}
 		}
 		var dir = this._dir,
 			vert = this._vertical,
 			val = this.containerNode[(vert ? "scrollHeight" : "scrollWidth")];
 
-		dojo.style(this.wrapper, this._dir, this.domNode.style[this._dir]);
-		this._lo = dojo.coords(this.wrapper, true);
+		html.style(this.wrapper, this._dir, this.domNode.style[this._dir]);
+		this._lo = html.coords(this.wrapper, true);
 		
 		this._size = Math.max(0, val - this._lo[(vert ? "h" : "w")]);
 		if(!this._size){
@@ -70,7 +74,7 @@ dojo.declare("dojox.layout.ScrollPane",
 		}else{
 			this.helper.style.display="";
 		}
-		this._line = new dojo._Line(0 - this._offset, this._size + (this._offset * 2));
+		this._line = new baseFx._Line(0 - this._offset, this._size + (this._offset * 2));
 	
 		// share a relative position w the scroll offset via a line
 		var u = this._lo[(vert ? "h" : "w")],
@@ -78,10 +82,10 @@ dojo.declare("dojox.layout.ScrollPane",
 			s = u * r, // size
 			c = Math.floor(u - (u * r)); // center
 			  
-		this._helpLine = new dojo._Line(0, c);
+		this._helpLine = new baseFx._Line(0, c);
 	
 		// size the helper
-		dojo.style(this.helper, dir, Math.floor(s) + "px");
+		html.style(this.helper, dir, Math.floor(s) + "px");
 		
 	},
 	
@@ -89,14 +93,14 @@ dojo.declare("dojox.layout.ScrollPane",
 		this.inherited(arguments);
 		// for the helper
 		if(this.autoHide){
-			this._showAnim = dojo._fade({ node:this.helper, end:0.5, duration:350 });
-			this._hideAnim = dojo.fadeOut({ node:this.helper, duration: 750 });
+			this._showAnim = baseFx._fade({ node:this.helper, end:0.5, duration:350 });
+			this._hideAnim = baseFx.fadeOut({ node:this.helper, duration: 750 });
 		}
 	
 		// orientation helper
 		this._vertical = (this.orientation == "vertical");
 		if(!this._vertical){
-			dojo.addClass(this.containerNode,"dijitInline");
+			domClass.add(this.containerNode,"dijitInline");
 			this._dir = "width";
 			this._edge = "left";
 			this._scroll = "scrollLeft";
@@ -109,7 +113,7 @@ dojo.declare("dojox.layout.ScrollPane",
 		if(this._hideAnim){
 			this._hideAnim.play();
 		}
-		dojo.style(this.wrapper,"overflow","hidden");
+		html.style(this.wrapper,"overflow","hidden");
 	
 	},
 	
@@ -117,7 +121,7 @@ dojo.declare("dojox.layout.ScrollPane",
 		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));
-		dojo.style(this.helper, this._edge, Math.floor(this._helpLine.getValue(n)) + "px");
+		html.style(this.helper, this._edge, Math.floor(this._helpLine.getValue(n)) + "px");
 	},
 	
 	_calc: function(/* Event */e){
@@ -142,6 +146,6 @@ dojo.declare("dojox.layout.ScrollPane",
 		if(this._hideAnim){
 			this._hideAnim.play();
 		}
-	}
-    
+	} 
 });
+});
\ No newline at end of file
diff --git a/dojox/layout/TableContainer.js b/dojox/layout/TableContainer.js
index f9e112f..ef58754 100644
--- a/dojox/layout/TableContainer.js
+++ b/dojox/layout/TableContainer.js
@@ -1,10 +1,11 @@
-dojo.experimental("dojox.layout.TableContainer");
-dojo.provide("dojox.layout.TableContainer");
-dojo.require("dijit.layout._LayoutWidget");
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/dom-class", "dojo/dom-construct", 
+		"dojo/_base/array", "dojo/dom-prop", "dojo/dom-style", "dijit/_WidgetBase", "dijit/layout/_LayoutWidget"],
+function(kernel, lang, declare, domClass, domConstruct, arrayUtil, domProp, domStyle, _WidgetBase, _LayoutWidget){
 
-dojo.declare("dojox.layout.TableContainer",
-	dijit.layout._LayoutWidget,
-	{
+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.
 	//
@@ -62,7 +63,7 @@ dojo.declare("dojox.layout.TableContainer",
 			if(value && (name == "orientation" || name == "customClass" || name == "cols")) {
 				this.layout();
 			}
-		})
+		});
 	},
 
 	startup: function() {
@@ -79,10 +80,10 @@ dojo.declare("dojox.layout.TableContainer",
 		}
 		this._initialized = true;
 
-		dojo.addClass(this.domNode, "dijitTableLayout");
+		domClass.add(this.domNode, "dijitTableLayout");
 
 		// Call startup on all child widgets
-		dojo.forEach(children, function(child){
+		arrayUtil.forEach(children, function(child){
 			if(!child.started && !child._started) {
 				child.startup();
 			}
@@ -96,7 +97,7 @@ dojo.declare("dojox.layout.TableContainer",
 		//		Resizes all children.  This widget itself
 		//		does not resize, as it takes up 100% of the
 		//		available width.
-		dojo.forEach(this.getChildren(), function(child){
+		arrayUtil.forEach(this.getChildren(), function(child){
 			if(typeof child.resize == "function") {
 				child.resize();
 			}
@@ -118,20 +119,20 @@ dojo.declare("dojox.layout.TableContainer",
 		function addCustomClass(node, type, count) {
 			if(_this.customClass != "") {
 				var clazz = _this.customClass+ "-" + (type || node.tagName.toLowerCase());
-				dojo.addClass(node, clazz);
+				domClass.add(node, clazz);
 
 				if(arguments.length > 2) {
-					dojo.addClass(node, clazz + "-" + count);
+					domClass.add(node, clazz + "-" + count);
 				}
 			}
 		}
 
 		// Find any new children that have been added since the last layout() call
-		dojo.forEach(this._children, dojo.hitch(this, function(child){
+		arrayUtil.forEach(this._children, lang.hitch(this, function(child){
 			childIds[child.id] = child;
 		}));
 
-		dojo.forEach(children, dojo.hitch(this, function(child, index){
+		arrayUtil.forEach(children, lang.hitch(this, function(child, index){
 			if(!childIds[child.id]) {
 				// Add pre-existing children to the start of the array
 				this._children.push(child);
@@ -139,28 +140,28 @@ dojo.declare("dojox.layout.TableContainer",
 		}));
 
 		// Create the table.  It fills the width of it's container.
-		var table = dojo.create("table", {
+		var table = domConstruct.create("table", {
 			"width": "100%",
 			 "class": "tableContainer-table tableContainer-table-" + this.orientation,
 			 "cellspacing" : this.spacing
 			},
 			this.domNode);
 
-		var tbody = dojo.create("tbody");
+		var tbody = domConstruct.create("tbody");
 		table.appendChild(tbody);
 
 		addCustomClass(table, "table", this.orientation);
 
 		var width = Math.floor(100 / this.cols) + "%";
 
-		var labelRow = dojo.create("tr", {}, tbody);
+		var labelRow = domConstruct.create("tr", {}, tbody);
 		var childRow = (!this.showLabels || this.orientation == "horiz")
-											? labelRow : dojo.create("tr", {}, tbody);
+						? labelRow : domConstruct.create("tr", {}, tbody);
 		var maxCols = this.cols * (this.showLabels ? 2 : 1);
 		var numCols = 0;
 
 		// Iterate over the children, adding them to the table.
-		dojo.forEach(this._children, dojo.hitch(this, function(child, index){
+		arrayUtil.forEach(this._children, lang.hitch(this, function(child, index){
 			
 			var colspan = child.colspan || 1;
 			
@@ -172,31 +173,31 @@ dojo.declare("dojox.layout.TableContainer",
 			// Create a new row if we need one
 			if(numCols + colspan - 1 + (this.showLabels ? 1 : 0)>= maxCols) {
 				numCols = 0;
-				labelRow = dojo.create("tr", {}, tbody);
-				childRow = this.orientation == "horiz" ? labelRow : dojo.create("tr", {}, tbody);
+				labelRow = domConstruct.create("tr", {}, tbody);
+				childRow = this.orientation == "horiz" ? labelRow : domConstruct.create("tr", {}, tbody);
 			}
 			var labelCell;
 			
 			// If labels should be visible, add them
 			if(this.showLabels) {
-				labelCell = dojo.create("td", {"class": "tableContainer-labelCell"}, labelRow);
+				labelCell = domConstruct.create("td", {"class": "tableContainer-labelCell"}, labelRow);
 
 				// If the widget should take up both the label and value,
 				// then just set the class on it.
 				if(child.spanLabel) {
-					dojo.attr(labelCell, this.orientation == "vert" ? "rowspan" : "colspan", 2);
+					domProp.set(labelCell, this.orientation == "vert" ? "rowspan" : "colspan", 2);
 				}
 				else {
 					// Add the custom label class to the label cell
 					addCustomClass(labelCell, "labelCell");
 					var labelProps = {"for": child.get("id")};
-					var label = dojo.create("label", labelProps, labelCell);
+					var label = domConstruct.create("label", labelProps, labelCell);
 
 					if(Number(this.labelWidth) > -1 ||
 						String(this.labelWidth).indexOf("%") > -1) {
 							
 						// Set the width of the label cell with either a pixel or percentage value
-						dojo.style(labelCell, "width",
+						domStyle.set(labelCell, "width",
 							String(this.labelWidth).indexOf("%") < 0
 								? this.labelWidth + "px" : this.labelWidth);
 					}
@@ -209,12 +210,12 @@ dojo.declare("dojox.layout.TableContainer",
 			if(child.spanLabel && labelCell) {
 				childCell = labelCell;
 			} else {
-				 childCell = dojo.create("td", {
+				 childCell = domConstruct.create("td", {
 				 	"class" : "tableContainer-valueCell"
 				}, childRow);
 			}
 			if(colspan > 1) {
-				dojo.attr(childCell, "colspan", colspan);
+				domProp.set(childCell, "colspan", colspan);
 			}
 			
 			// Add the widget cell's custom class, if one exists.
@@ -229,7 +230,7 @@ dojo.declare("dojox.layout.TableContainer",
 		}
 		// Refresh the layout of any child widgets, allowing them to resize
 		// to their new parent.
-		dojo.forEach(children, function(child){
+		arrayUtil.forEach(children, function(child){
 			if(typeof child.layout == "function") {
 				child.layout();
 			}
@@ -242,7 +243,7 @@ dojo.declare("dojox.layout.TableContainer",
 		// summary:
 		//      Destroys all the widgets inside this.containerNode,
 		//      but not this widget itself
-		dojo.forEach(this._children, function(child){ child.destroyRecursive(preserveDom); });
+		arrayUtil.forEach(this._children, function(child){ child.destroyRecursive(preserveDom); });
 	},
 	
 	_setSpacingAttr: function(value) {
@@ -257,7 +258,7 @@ dojo.declare("dojox.layout.TableContainer",
 
 // Extend the default widget with both label and title elements, as
 // well as a "spanLabel" attribute.  If a widget
-dojo.extend(dijit._Widget, {
+lang.extend(_WidgetBase, {
 	// label: String
 	//		The label to display for a given widget
 	label: "",
@@ -277,3 +278,5 @@ dojo.extend(dijit._Widget, {
 	//		The number of columns this widget should span.
 	colspan: 1
 });
+return TableContainer;
+});
diff --git a/dojox/layout/ToggleSplitter.js b/dojox/layout/ToggleSplitter.js
index 0a2ba63..25c3941 100644
--- a/dojox/layout/ToggleSplitter.js
+++ b/dojox/layout/ToggleSplitter.js
@@ -1,68 +1,71 @@
-define("dojox/layout/ToggleSplitter", ["dojo", "dojox"], function(dojo, dojox) {
+define("dojox/layout/ToggleSplitter", ["dojo", "dijit", "dijit/layout/BorderContainer"], function(dojo, dijit) {
 
 dojo.experimental("dojox.layout.ToggleSplitter");
 
-dojo.require("dijit.layout.BorderContainer");
-
-dojo.declare("dojox.layout.ToggleSplitter", [ dijit.layout._Splitter ],
-{
+dojo.declare("dojox.layout.ToggleSplitter", dijit.layout._Splitter, {
 	// summary:
-	//		A draggable and toggle-to-close/open spacer between two items in a BorderContainer
-	//
+	//		A draggable and clickable spacer between two items in a dijit.layout.BorderContainer`.
 	// description:
-	// 		Extends the dijit.layout._Splitter to add a toggling behavior
-	// 		on double-click
-	//
+	//		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,
 =====*/
 
-	// open: Boolean
-	//	the initial and current state of the splitter (and its attached pane)
-	open: true,
-
-	// closedThreshold: Integer
-	//	how small the attached pane can be before its considered closed
-	closedThreshold: 5,
-
-	// openSize: String
-	//	the css height/width value to apply by default when the attached pane is open
-	openSize: "",
+	// state: String
+	//		the initial and current state of the splitter (and its attached pane)
+	//		It has three values: full, collapsed (optional), closed
+	state: "full",
 
 	// _closedSize: String
 	//	the css height/width value to apply by default when the attached pane is closed
 	_closedSize: "0",
-	
-	templateString: '<div class="dijitSplitter dojoxToggleSplitter" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onMouseDown" tabIndex="0" role="separator"><div dojoAttachPoint="toggleNode" class="dijitSplitterThumb dojoxToggleSplitterIcon"></div></div>',
 
-	postCreate: function(){
-		this._started = false;
+	baseClass: "dojoxToggleSplitter",
 
-		this.inherited(arguments);
-		
-		// add a region css hook
-		var region = this.region;
-		dojo.addClass(this.domNode, "dojoxToggleSplitter"+region.charAt(0).toUpperCase() + region.substring(1));
+	templateString: '<div class="dijitSplitter dojoxToggleSplitter" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_startDrag,onmouseenter:_onMouse,onmouseleave:_onMouse">' +
+						'<div dojoAttachPoint="toggleNode" class="dijitSplitterThumb dojoxToggleSplitterIcon" tabIndex="0" role="separator" ' +
+							'dojoAttachEvent="onmousedown:_onToggleNodeMouseDown,onclick:_toggle,onmouseenter:_onToggleNodeMouseMove,onmouseleave:_onToggleNodeMouseMove,onfocus:_onToggleNodeMouseMove,onblur:_onToggleNodeMouseMove">' +
+							'<span class="dojoxToggleSplitterA11y" dojoAttachPoint="a11yText"></span></div>' +
+					'</div>',
 
-		// hook up double-clicks to toggle the splitter -
-		this.connect(this, "onDblClick", "_toggleMe");
+	postCreate: function(){
+		this.inherited(arguments);
 
+		// add a region css hook so that it can figure out the region correctly
+		var region = this.region;
+		dojo.addClass(this.domNode, this.baseClass + region.charAt(0).toUpperCase() + region.substring(1));
 	},
+
 	startup: function(){
 		this.inherited(arguments);
 
 		// we have to wait until startup to be sure the child exists in the dom
 		// and has non-zero size (if its supposed to be showing)
-		var paneNode = this.child.domNode,
+		var parentPane = this.child,
+			paneNode = this.child.domNode,
 			intPaneSize = dojo.style(paneNode, (this.horizontal ? "height" : "width"));
-		
+
+		this.domNode.setAttribute("aria-controls", paneNode.id);
+
 		// creation of splitters is an opaque process in BorderContainer,
 		// so if we want to get init params, we have to retrieve them from the attached BC child
 		// NOTE: for this to work we have to extend the prototype of dijit._Widget (some more)
-		dojo.forEach(["toggleSplitterOpen", "toggleSplitterClosedThreshold", "toggleSplitterOpenSize"], function(name){
+		dojo.forEach(["toggleSplitterState", "toggleSplitterFullSize", "toggleSplitterCollapsedSize"], function(name){
 			var pname = name.substring("toggleSplitter".length);
 			pname = pname.charAt(0).toLowerCase() + pname.substring(1);
 			if(name in this.child){
@@ -70,92 +73,110 @@ dojo.declare("dojox.layout.ToggleSplitter", [ dijit.layout._Splitter ],
 			}
 		}, this);
 
-		if(!this.openSize){
-			// store the current size as the openSize if none was provided
-
+		if(!this.fullSize){
+			// Store the current size as the fullSize if none was provided
 			// dojo.style always returns a integer (pixel) value for height/width
-			// use an arbirary default if a pane was initalized closed and no openSize provided
-			this.openSize = (this.open) ? intPaneSize + "px" : "75px";
+			// use an arbitrary default if a pane was initialized closed and no fullSize provided
+			// If collapsedSize is not specified, collapsed state does not exist.
+			this.fullSize = this.state == "full" ? intPaneSize + "px" : "75px";
 		}
-		this._openStyleProps = this._getStyleProps(paneNode, true);
+
+		this._openStyleProps = this._getStyleProps(paneNode, "full");
 
 		// update state
 		this._started = true;
-		this.set("open", this.open);
+		this.set("state", this.state);
 
 		return this;
 	},
-	_onMouseUp: function(evt){
-		dojo.disconnect(this._onMoveHandle);
-		dojo.disconnect(this._onUpHandle);
-		delete this._onMoveHandle;
-		delete this._onUpHandle;
-		delete this._startPosn;
-	},
-	_onPrelimMouseMove: function(evt){
-		// only start dragging when a mouse down AND a significant mousemove occurs
-		var startPosn = this._startPosn || 0;
-		// allow a little fudging in a click before we consider a drag started
-		var dragThreshold = 3;
-		var offset = Math.abs( startPosn - (this.horizontal ? evt.clientY : evt.clientX) );
-		if(offset >= dragThreshold){
-			// treat as a drag and dismantle this preliminary handlers
-			dojo.disconnect(this._onMoveHandle);
-			this._startDrag(evt);
+
+	_onKeyPress: function(evt){
+		if(this.state == "full"){
+			this.inherited(arguments);
 		}
-	},
-	_onMouseDown: function(evt){
-		// summary:
-		// 	handle mousedown events from the domNode
-		if(!this.open){
-			// ignore mousedown while closed
-			// - this has the effect of preventing dragging while closed, which is the prefered behavior (for now)
-			return;
+		if(evt.charCode == dojo.keys.SPACE || evt.keyCode == dojo.keys.ENTER){
+			this._toggle(evt);
 		}
-		// Mousedown can fire more than once (!)
-		// ..so check before connecting
-		if(!this._onUpHandle){
-			this._onUpHandle = dojo.connect(dojo.body(), "onmouseup", this, "_onMouseUp");
+	},
+
+	_onToggleNodeMouseDown: function(evt){
+		dojo.stopEvent(evt);
+		this.toggleNode.focus();
+	},
+
+	_startDrag: function(e){
+		if(this.state == "full"){
+			this.inherited(arguments);
 		}
-		if(!this._onMoveHandle){
-			this._startPosn = this.horizontal ? evt.clientY : evt.clientX;
-			// start listening for mousemove
-			this._onMoveHandle = dojo.connect(dojo.body(), "onmousemove", this, "_onPrelimMouseMove");
+	},
+
+	_stopDrag: function(e){
+		this.inherited(arguments);
+		this.toggleNode.blur();
+	},
+
+	_toggle: function(evt){
+		var state;
+		switch(this.state){
+			case "full":
+				state = this.collapsedSize ? "collapsed" : "closed";
+				break;
+			case "collapsed":
+				state = "closed";
+				break;
+			default:
+				state = "full";
 		}
+		this.set("state", state);
+	},
+
+	_onToggleNodeMouseMove: function(evt){
+		var baseClass = this.baseClass,
+			toggleNode = this.toggleNode,
+			on = this.state == "full" || this.state == "collapsed",
+			leave = evt.type == "mouseout" || evt.type == "blur";
+
+		dojo.toggleClass(toggleNode, baseClass + "IconOpen", leave && on);
+		dojo.toggleClass(toggleNode, baseClass + "IconOpenHover", !leave && on);
+		dojo.toggleClass(toggleNode, baseClass + "IconClosed", leave && !on);
+		dojo.toggleClass(toggleNode, baseClass + "IconClosedHover", !leave && !on);
 	},
-	_handleOnChange: function(){
-		// summary
-		// 	effect the state change with the new value of this.open
 
-		// TODO: animate the open/close
-		
+	_handleOnChange: function(preState){
+		// summary
+		//		Effect the state change with the new value of this.state
 		var paneNode = this.child.domNode,
-			openProps,
+			openProps, paneStyle,
 			dim = this.horizontal ? "height" : "width";
 
-		if(this.open){
-			// change to open state
+		if(this.state == "full"){
+			// change to full open state
 			var styleProps = dojo.mixin({
 				display: "block",
 				overflow: "auto",
 				visibility: "visible"
 			}, this._openStyleProps);
+			styleProps[dim] = (this._openStyleProps && this._openStyleProps[dim]) ? this._openStyleProps[dim] : this.fullSize;
 
-			styleProps[dim] = (this._openStyleProps && this._openStyleProps[dim]) ? this._openStyleProps[dim] : this.openSize;
+			dojo.style(this.domNode, "cursor", "");
 			dojo.style(paneNode, styleProps);
-			
-			// and re-hook up the mouse event handler
-			this.connect(this.domNode, "onmousedown", "_onMouseDown");
+		}else if(this.state == "collapsed"){
+			paneStyle  = dojo.getComputedStyle(paneNode);
+			openProps = this._getStyleProps(paneNode, "full", paneStyle);
+			this._openStyleProps = openProps;
 
-		} else {
+			dojo.style(this.domNode, "cursor", "auto");
+			dojo.style(paneNode, dim, this.collapsedSize);
+		}else{
 			// change to closed state
-			// FIXME: this wont work in a drag-to-closed scenario
-			var paneStyle  = dojo.getComputedStyle(paneNode);
-			
-			openProps = this._getStyleProps(paneNode, true, paneStyle);
-			var closedProps = this._getStyleProps(paneNode, false, paneStyle);
+			if(!this.collapsedSize){
+				paneStyle  = dojo.getComputedStyle(paneNode);
+				openProps = this._getStyleProps(paneNode, "full", paneStyle);
+				this._openStyleProps = openProps;
+			}
+			var closedProps = this._getStyleProps(paneNode, "closed", paneStyle);
 
-			this._openStyleProps = openProps;
+			dojo.style(this.domNode, "cursor", "auto");
 			dojo.style(paneNode, closedProps);
 		}
 		this._setStateClass();
@@ -163,102 +184,112 @@ dojo.declare("dojox.layout.ToggleSplitter", [ dijit.layout._Splitter ],
 			this.container._layoutChildren(this.region);
 		}
 	},
-	
-	_getStyleProps: function(paneNode, open, paneStyle){
+
+	_getStyleProps: function(paneNode, state, paneStyle){
 		// summary:
-		//	create an object with the style property name: values
-		// 	that will need to be applied to the child pane render the given state
+		//		Create an object with the style property name: values
+		//		that will need to be applied to the child pane render the given state
 		if(!paneStyle){
 			paneStyle  = dojo.getComputedStyle(paneNode);
 		}
 		var styleProps = {},
 			dim = this.horizontal ? "height" : "width";
-			
-		styleProps["overflow"] = (open) ? paneStyle["overflow"] : "hidden";
-		styleProps["visibility"] = (open) ? paneStyle["visibility"] : "hidden";
 
-		// use the inline width/height style value, in preference to the computedStyle
+		styleProps["overflow"] = (state != "closed") ? paneStyle["overflow"] : "hidden";
+		styleProps["visibility"] = (state != "closed") ? paneStyle["visibility"] : "hidden";
+
+		// Use the inline width/height style value, in preference to the computedStyle
 		// for the open width/height
-		styleProps[dim] = (open) ? paneNode.style[dim] || paneStyle[dim] : this._closedSize;
+		styleProps[dim] = (state != "closed") ? paneNode.style[dim] || paneStyle[dim] : this._closedSize;
 
-		// We include the padding,border,margin width values for restoring on open
+		// We include the padding, border, margin width values for restoring on state full open
 		var edgeNames = ["Top", "Right", "Bottom", "Left"];
-		dojo.forEach(["padding","margin","border"], function(pname){
-			for(var i=0; i<edgeNames.length; i++){
-				var fullname = pname+edgeNames[i];
-				if(pname=="border"){
-					pname+="Width";
+		dojo.forEach(["padding", "margin", "border"], function(pname){
+			for(var i = 0; i < edgeNames.length; i++){
+				var fullName = pname + edgeNames[i];
+				if(pname == "border"){
+					fullName += "Width";
 				}
-				if(undefined !== paneStyle[fullname]){
-					styleProps[fullname] = (open) ?
-						paneStyle[fullname] : 0;
+				if(undefined !== paneStyle[fullName]){
+					styleProps[fullName] = (state != "closed") ? paneStyle[fullName] : 0;
 				}
 			}
 		});
+
 		return styleProps;
 	},
-	
+
 	_setStateClass: function(){
-		// sumamry:
-		//	apply the appropriate classes for the current open state
-		if(this.open){
-			dojo.removeClass(this.domNode, "dojoxToggleSplitterClosed");
-			dojo.addClass(this.domNode, "dojoxToggleSplitterOpen");
-			dojo.removeClass(this.toggleNode, "dojoxToggleSplitterIconClosed");
-			dojo.addClass(this.toggleNode, "dojoxToggleSplitterIconOpen");
-		} else {
-			dojo.addClass(this.domNode, "dojoxToggleSplitterClosed");
-			dojo.removeClass(this.domNode, "dojoxToggleSplitterOpen");
-			dojo.addClass(this.toggleNode, "dojoxToggleSplitterIconClosed");
-			dojo.removeClass(this.toggleNode, "dojoxToggleSplitterIconOpen");
+		// Summary:
+		//		Apply the appropriate classes for the current open state
+		var arrow = "&#9652", region = this.region.toLowerCase(),
+			baseClass = this.baseClass,
+			toggleNode = this.toggleNode,
+			on = this.state == "full" || this.state == "collapsed",
+			focused = this.focused;
+
+		dojo.toggleClass(toggleNode, baseClass + "IconOpen", on && !focused);
+		dojo.toggleClass(toggleNode, baseClass + "IconClosed", !on && !focused);
+		dojo.toggleClass(toggleNode, baseClass + "IconOpenHover", on && focused);
+		dojo.toggleClass(toggleNode, baseClass + "IconClosedHover", !on && focused);
+
+		// For a11y
+		if(region == "top" && on || region == "bottom" && !on){
+			arrow = "&#9650";
+		}else if(region == "top" && !on || region == "bottom" && on){
+			arrow = "&#9660";
+		}else if(region == "right" && on || region == "left" && !on){
+			arrow = "&#9654";
+		}else if(region == "right" && !on || region == "left" && on){
+			arrow = "&#9664";
 		}
+
+		this.a11yText.innerHTML = arrow;
 	},
-	_setOpenAttr: function(/*Boolean*/ value){
+
+	_setStateAttr: function(/*Strring*/ state){
 		// summary:
-		// 	setter for the open property
+		//		setter for the state property
 		if(!this._started) {
 			return;
 		}
-		this.open = value;
-		this._handleOnChange(value, true);
-		var evt = this.open ? "onOpen" : "onClose";
-		this[evt](this.child);
-	},
-	onOpen: function(){
-		// stub
-	},
-	onClose: function(){
-		// stub
-	},
+		var preState = this.state;
+		this.state = state;
 
-	_toggleMe: function(evt){
-		// summary:
-		// 	event handle, toggle the open state
-		if(evt){
-			dojo.stopEvent(evt);
+		this._handleOnChange(preState);
+		var evtName;
+		switch(state){
+			case "full":
+				this.domNode.setAttribute("aria-expanded", true);
+				evtName = "onOpen";
+				break;
+			case "collapsed":
+				this.domNode.setAttribute("aria-expanded", true);
+				evtName = "onCollapsed";
+				break;
+			default:
+				this.domNode.setAttribute("aria-expanded", false);
+				evtName = "onClosed";
 		}
-		this.set("open", !this.open);
+		this[evtName](this.child);
 	},
 
-	_onKeyPress: function(/*Event*/ e){
-		this.inherited(arguments);
-		// TODO: add support for space, enter to cause toggle
-	}
-
+	onOpen: function(pane){ /*Stub*/ },
+	onCollapsed: function(pane){ /*Stub*/ },
+	onClosed: function(pane){ /*Stub*/ }
 });
 
 // As BC places no constraints on what kind of widgets can be children
 // we have to extend the base class to ensure the properties we need can be set (both in markup and programatically)
 dojo.extend(dijit._Widget, {
 	// toggleSplitterOpen: Boolean
-	toggleSplitterOpen: true,
-	
-	// toggleSplitterClosedThreshold: Integer
-	toggleSplitterClosedThreshold: 5,
+	toggleSplitterState: "full",
 
 	// toggleSplitterClosedThreshold: String
-	// 		a css size value (e.g. "100px")
-	toggleSplitterOpenSize: ""
+	//		A css size value (e.g. "100px")
+	toggleSplitterFullSize: "",
+
+	toggleSplitterCollapsedSize: ""
 });
 
 });
\ No newline at end of file
diff --git a/dojox/layout/resources/FloatingPane.css b/dojox/layout/resources/FloatingPane.css
index 579f604..613cd11 100644
--- a/dojox/layout/resources/FloatingPane.css
+++ b/dojox/layout/resources/FloatingPane.css
@@ -129,7 +129,7 @@
 }
 
 .dojoxDockRestoreButton {
-	background:url('../../../dijit/themes/tundra/images/arrowUp.png') no-repeat center center;
+	background:url('../../../dijit/themes/tundra/images/folderClosed.gif') no-repeat center center;
 	width:16px; height:16px;
 	overflow:hidden; 
 	float:left;
diff --git a/dojox/layout/resources/ToggleSplitter.css b/dojox/layout/resources/ToggleSplitter.css
index a00d546..2f18625 100644
--- a/dojox/layout/resources/ToggleSplitter.css
+++ b/dojox/layout/resources/ToggleSplitter.css
@@ -1,87 +1,87 @@
-.dijitBorderContainer .dojoxToggleSplitterTop,
-.dijitBorderContainer .dojoxToggleSplitterBottom {
-	height:16px;
+.dijitBorderContainer .dijitSplitterH {
+	height: 6px;
 }
-.dijitBorderContainer .dojoxToggleSplitterLeft,
-.dijitBorderContainer .dojoxToggleSplitterRight {
-	width:16px;
+
+.dijitBorderContainer .dijitSplitterV {
+	width: 6px;
 }
 
 .dijitBorderContainer .dijitSplitterH .dojoxToggleSplitterIcon {
-	width:16px;
-	height:16px;
+	background-image: url('icons/splitterToggleH.png');
+	background-repeat: no-repeat;
+	width: 71px;
+	height: 6px;
 	top: 0;
+	left: 45%;
 	cursor: pointer;
 }
+
 .dijitBorderContainer .dijitSplitterV .dojoxToggleSplitterIcon {
-	width:16px;
-	height:16px;
+	background-image: url('icons/splitterToggleV.png');
+	background-repeat: no-repeat;
+	vertical-align: middle;
+	width: 6px;
+	height: 71px;
 	left: 0;
+	top: 45%;
 	cursor: pointer;
 }
 
-.tundra .dojoxToggleSplitterTop .dojoxToggleSplitterIconOpen, 
-.tundra .dojoxToggleSplitterBottom .dojoxToggleSplitterIconClosed 
- {
-	background: transparent url('../../../dijit/themes/tundra/images/spriteRoundedIconsSmall.png') no-repeat -45px 50%;
-}
-.tundra .dojoxToggleSplitterBottom .dojoxToggleSplitterIconOpen, 
-.tundra .dojoxToggleSplitterTop .dojoxToggleSplitterIconClosed 
- {
-	background: transparent url('../../../dijit/themes/tundra/images/spriteRoundedIconsSmall.png') no-repeat -15px 50%;
+.dojoxToggleSplitterTop .dojoxToggleSplitterIconOpen, 
+.dojoxToggleSplitterBottom .dojoxToggleSplitterIconClosed {
+	background-position: 0 -12px !important;
 }
 
-.tundra .dojoxToggleSplitterLeft .dojoxToggleSplitterIconOpen, 
-.tundra .dojoxToggleSplitterRight .dojoxToggleSplitterIconClosed 
- {
-	background: transparent url('../../../dijit/themes/tundra/images/spriteRoundedIconsSmall.png') no-repeat 0px 50%;
+.dojoxToggleSplitterBottom .dojoxToggleSplitterIconOpen, 
+.dojoxToggleSplitterTop .dojoxToggleSplitterIconClosed {
+	background-position: 0 0 !important;
 }
-.tundra .dojoxToggleSplitterRight .dojoxToggleSplitterIconOpen, 
-.tundra .dojoxToggleSplitterLeft .dojoxToggleSplitterIconClosed 
- {
-	background: transparent url('../../../dijit/themes/tundra/images/spriteRoundedIconsSmall.png') no-repeat -30px 50%;
+
+.dojoxToggleSplitterLeft .dojoxToggleSplitterIconOpen, 
+.dojoxToggleSplitterRight .dojoxToggleSplitterIconClosed {
+	background-position: -12px 0 !important;
 }
 
-.soria .dojoxToggleSplitterTop .dojoxToggleSplitterIconOpen, 
-.soria .dojoxToggleSplitterBottom .dojoxToggleSplitterIconClosed 
- {
-	background: transparent url('../../../dijit/themes/soria/images/spriteRoundedIconsSmall.png') no-repeat -45px 50%;
+.dojoxToggleSplitterRight .dojoxToggleSplitterIconOpen, 
+.dojoxToggleSplitterLeft .dojoxToggleSplitterIconClosed {
+	background-position: 0 0 !important;
 }
-.soria .dojoxToggleSplitterBottom .dojoxToggleSplitterIconOpen, 
-.soria .dojoxToggleSplitterTop .dojoxToggleSplitterIconClosed 
- {
-	background: transparent url('../../../dijit/themes/soria/images/spriteRoundedIconsSmall.png') no-repeat -15px 50%;
+
+.dojoxToggleSplitterTop .dojoxToggleSplitterIconOpenHover, 
+.dojoxToggleSplitterBottom .dojoxToggleSplitterIconClosedHover {
+	background-position: 0 -18px !important;
 }
 
-.soria .dojoxToggleSplitterLeft .dojoxToggleSplitterIconOpen, 
-.soria .dojoxToggleSplitterRight .dojoxToggleSplitterIconClosed 
- {
-	background: transparent url('../../../dijit/themes/soria/images/spriteRoundedIconsSmall.png') no-repeat 0px 50%;
+.dojoxToggleSplitterBottom .dojoxToggleSplitterIconOpenHover, 
+.dojoxToggleSplitterTop .dojoxToggleSplitterIconClosedHover {
+	background-position: 0 -6px !important;
 }
-.soria .dojoxToggleSplitterRight .dojoxToggleSplitterIconOpen, 
-.soria .dojoxToggleSplitterLeft .dojoxToggleSplitterIconClosed 
- {
-	background: transparent url('../../../dijit/themes/soria/images/spriteRoundedIconsSmall.png') no-repeat -30px 50%;
+
+.dojoxToggleSplitterLeft .dojoxToggleSplitterIconOpenHover, 
+.dojoxToggleSplitterRight .dojoxToggleSplitterIconClosedHover {
+	background-position: -18px 0 !important;
 }
 
-.nihilo .dojoxToggleSplitterTop .dojoxToggleSplitterIconOpen, 
-.nihilo .dojoxToggleSplitterBottom .dojoxToggleSplitterIconClosed 
- {
-	background: transparent url('../../../dijit/themes/nihilo/images/spriteRoundedIconsSmall.png') no-repeat -45px 50%;
+.dojoxToggleSplitterRight .dojoxToggleSplitterIconOpenHover, 
+.dojoxToggleSplitterLeft .dojoxToggleSplitterIconClosedHover {
+	background-position: -6px 0 !important;
 }
-.nihilo .dojoxToggleSplitterBottom .dojoxToggleSplitterIconOpen, 
-.nihilo .dojoxToggleSplitterTop .dojoxToggleSplitterIconClosed 
- {
-	background: transparent url('../../../dijit/themes/nihilo/images/spriteRoundedIconsSmall.png') no-repeat -15px 50%;
+
+.dojoxToggleSplitterTop .dojoxToggleSplitterA11y,
+.dojoxToggleSplitterBottom .dojoxToggleSplitterA11y {
+	display: none;
+	font-size: 6px;
+	text-align: center;
 }
 
-.nihilo .dojoxToggleSplitterLeft .dojoxToggleSplitterIconOpen, 
-.nihilo .dojoxToggleSplitterRight .dojoxToggleSplitterIconClosed 
- {
-	background: transparent url('../../../dijit/themes/nihilo/images/spriteRoundedIconsSmall.png') no-repeat 0px 50%;
+.dojoxToggleSplitterRight .dojoxToggleSplitterA11y,
+.dojoxToggleSplitterLeft .dojoxToggleSplitterA11y {
+	display: none;
+	font-size: 8px;
+	position: relative;
+	top: 48%;
 }
-.nihilo .dojoxToggleSplitterRight .dojoxToggleSplitterIconOpen, 
-.nihilo .dojoxToggleSplitterLeft .dojoxToggleSplitterIconClosed 
- {
-	background: transparent url('../../../dijit/themes/nihilo/images/spriteRoundedIconsSmall.png') no-repeat -30px 50%;
+
+.dijit_a11y .dojoxToggleSplitterA11y {
+	display: block;
 }
diff --git a/dojox/layout/resources/icons/splitterToggleH.png b/dojox/layout/resources/icons/splitterToggleH.png
new file mode 100755
index 0000000..72a3723
Binary files /dev/null and b/dojox/layout/resources/icons/splitterToggleH.png differ
diff --git a/dojox/layout/resources/icons/splitterToggleV.png b/dojox/layout/resources/icons/splitterToggleV.png
new file mode 100755
index 0000000..55ecf04
Binary files /dev/null and b/dojox/layout/resources/icons/splitterToggleV.png differ
diff --git a/dojox/layout/tests/ContentPane.html b/dojox/layout/tests/ContentPane.html
index a4fe8a5..63e4091 100644
--- a/dojox/layout/tests/ContentPane.html
+++ b/dojox/layout/tests/ContentPane.html
@@ -25,15 +25,13 @@
 		}
 	</style>
 	<script src='../../../dojo/dojo.js' djConfig='isDebug:true, parseOnLoad:true'></script>
-	<script src='../../../dojo/html.js'></script>
-	<script src='../../../dojox/html/_base.js'></script>
-	<script src='../../../dojox/layout/ContentPane.js'></script>
 	<script>
 		dojo.require('doh.runner');
 		dojo.require('dojox.layout.ContentPane');
 		dojo.require('dojo.parser');
 		dojo.require('dijit._Container');
 		dojo.require('dijit._Templated');
+		dojo.require('dojo._base.url');
 
 
 		// create a do nothing, only for test widget
@@ -1092,4 +1090,4 @@
 		<tbody>
 	</table>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/dojox/layout/tests/remote/getResponse.php b/dojox/layout/tests/remote/getResponse.php
index ac3b94b..01f3d20 100644
--- a/dojox/layout/tests/remote/getResponse.php
+++ b/dojox/layout/tests/remote/getResponse.php
@@ -102,7 +102,7 @@
 				break;
 	
 			default:
-				echo "unkown mode {$_GET['mode']}";
+				echo "unkown mode ".htmlspecialchars($_GET['mode']);
 		}
 	}
-?>
\ No newline at end of file
+?>
diff --git a/dojox/layout/tests/test_ExpandoPane.html b/dojox/layout/tests/test_ExpandoPane.html
index d0dfe7a..ff83ec9 100644
--- a/dojox/layout/tests/test_ExpandoPane.html
+++ b/dojox/layout/tests/test_ExpandoPane.html
@@ -14,9 +14,6 @@
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 
-	<!-- for debugging: -->
-	<script src="../ExpandoPane.js" type="text/javascript"></script>
-
 	<script type="text/javascript">
 		dojo.require("dojox.layout.ExpandoPane");
 		dojo.require("dojo.data.ItemFileReadStore");
diff --git a/dojox/layout/tests/test_ExpandoPane_more.html b/dojox/layout/tests/test_ExpandoPane_more.html
index 4656543..c229fd6 100644
--- a/dojox/layout/tests/test_ExpandoPane_more.html
+++ b/dojox/layout/tests/test_ExpandoPane_more.html
@@ -23,8 +23,8 @@
 	</style>
 
 	<!-- for debugging -->
-	<script src="../ExpandoPane.js" type="text/javascript"></script>
 	<script type="text/javascript">
+		dojo.require("dojox.layout.ExpandoPane");
 		dojo.require("dijit.layout.TabContainer");
 		dojo.require("dijit.Tree");
 		dojo.require("dijit.layout.ContentPane");
diff --git a/dojox/layout/tests/test_ExpandoPane_prog.html b/dojox/layout/tests/test_ExpandoPane_prog.html
index 79f73d8..dfc7228 100644
--- a/dojox/layout/tests/test_ExpandoPane_prog.html
+++ b/dojox/layout/tests/test_ExpandoPane_prog.html
@@ -25,7 +25,6 @@
 	</style>
 
 	<!-- for debugging -->
-	<script src="../ExpandoPane.js" type="text/javascript"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.layout.ExpandoPane");
 		dojo.require("dijit.layout.TabContainer");
diff --git a/dojox/layout/tests/test_FloatingPane.html b/dojox/layout/tests/test_FloatingPane.html
index f334ffe..9666131 100644
--- a/dojox/layout/tests/test_FloatingPane.html
+++ b/dojox/layout/tests/test_FloatingPane.html
@@ -15,9 +15,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="../FloatingPane.js"></script>
-	
 	<script type="text/javascript">
 		dojo.require("dojox.layout.FloatingPane"); 
 		dojo.require("dijit.layout.TabContainer");
diff --git a/dojox/layout/tests/test_GridContainer.html b/dojox/layout/tests/test_GridContainer.html
index 8a0dfe7..e50ecf3 100644
--- a/dojox/layout/tests/test_GridContainer.html
+++ b/dojox/layout/tests/test_GridContainer.html
@@ -41,8 +41,6 @@
 		</style>
 		
 		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
-		<script type="text/javascript" src="../../../dojox/layout/GridContainerLite.js"></script>
-		<script type="text/javascript" src="../../../dojox/layout/GridContainer.js"></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 2721e3c..546f982 100644
--- a/dojox/layout/tests/test_GridContainerColWidths.html
+++ b/dojox/layout/tests/test_GridContainerColWidths.html
@@ -57,8 +57,6 @@
 		
 		<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" src="../GridContainerLite.js"></script>
-		<script type="text/javascript" src="../GridContainer.js"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
 			dojo.require("dijit.TitlePane");
diff --git a/dojox/layout/tests/test_GridContainer_TitlePanes.html b/dojox/layout/tests/test_GridContainer_TitlePanes.html
index f5fb0cf..a4698af 100644
--- a/dojox/layout/tests/test_GridContainer_TitlePanes.html
+++ b/dojox/layout/tests/test_GridContainer_TitlePanes.html
@@ -51,7 +51,6 @@
 		
 		<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" src="../GridContainer.js"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
 			dojo.require("dijit.TitlePane");
diff --git a/dojox/layout/tests/test_GridContainer_in_BorderContainer_prog.html b/dojox/layout/tests/test_GridContainer_in_BorderContainer_prog.html
index 24197d7..46c5f58 100644
--- a/dojox/layout/tests/test_GridContainer_in_BorderContainer_prog.html
+++ b/dojox/layout/tests/test_GridContainer_in_BorderContainer_prog.html
@@ -104,21 +104,21 @@
 					title:'Panel 1', 
 					dndType:'TitlePane'
 				});
-				tp1.attr('content', 'lorem ipsum');
+				tp1.set('content', 'lorem ipsum');
 				gc1.addChild(tp1);
 
 				tp2 = new dijit.TitlePane({
 					title:'Panel 2', 
 					dndType:'TitlePane'
 				});
-				tp2.attr('content', 'lorem ipsum');
+				tp2.set('content', 'lorem ipsum');
 				gc1.addChild(tp2);
 
 				tp3 = new dijit.TitlePane({
 					title:'Panel 3', 
 					dndType:'TitlePane'
 				});
-				tp3.attr('content', 'lorem ipsum');
+				tp3.set('content', 'lorem ipsum');
 				gc1.addChild(tp3,0,2);
 				
 				// Create the central GridContainer
@@ -136,14 +136,14 @@
 					label:'Content Pane', 
 					dndType:'ContentPane'
 				});
-				cp1.attr('content', 'ContentPane n*1 !');
+				cp1.set('content', 'ContentPane n*1 !');
 				gc2.addChild(cp1);
 
 				tp4 = new dijit.TitlePane({
 					title:'Ergo', 
 					dndType:'TitlePane'
 				});
-				tp4.attr('content', '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 sol [...]
+				tp4.set('content', '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 soll [...]
 				gc2.addChild(tp4,0,1);
 
 				cp2 = new dijit.layout.ContentPane({
@@ -151,14 +151,14 @@
 					label:"Content Pane", 
 					dndType:'ContentPane'
 				});
-				cp2.attr('content', 'Content Pane n*2 !');
+				cp2.set('content', 'Content Pane n*2 !');
 				gc2.addChild(cp2,1,0);
 
 				cp3 = new dijit.layout.ContentPane({
 					title:"Itellectum", 
 					dndType:'ContentPane'
 				});
-				cp3.attr('content', '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 da [...]
+				cp3.set('content', '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 dat [...]
 				gc2.addChild(cp3,1,1);
 
 				cp4 = new dijit.layout.ContentPane({
@@ -166,7 +166,7 @@
 					label:'Content Pane', 
 					dndType:'ContentPane'
 				});
-				cp4.attr('content', 'Content Pane n*3 !');
+				cp4.set('content', 'Content Pane n*3 !');
 				gc2.addChild(cp4,1,2);
 
 				cp5 = new dijit.layout.ContentPane({
@@ -174,7 +174,7 @@
 					label:'Content Pane', 
 					dndType:'ContentPane'
 				});
-				cp5.attr('content', 'Content Pane n*4 !');
+				cp5.set('content', 'Content Pane n*4 !');
 				gc2.addChild(cp5,2,0);
 
 				dp = new dijit.Calendar({dndType:'Calendar'});
@@ -195,21 +195,21 @@
 					title:'Panel 1', 
 					dndType:'TitlePane'
 				});
-				tp4.attr('content', 'lorem ipsum');
+				tp4.set('content', 'lorem ipsum');
 				gc3.addChild(tp4,0,0);
 
 				tp5 = new dijit.TitlePane({
 					title:'Panel 2', 
 					dndType:'TitlePane'
 				});
-				tp5.attr('content', 'lorem ipsum');
+				tp5.set('content', 'lorem ipsum');
 				gc3.addChild(tp5,0,1);
 
 				tp6 = new dijit.TitlePane({
 					title:'Panel 3', 
 					dndType:'TitlePane'
 				});
-				tp6.attr('content', 'lorem ipsum');
+				tp6.set('content', 'lorem ipsum');
 				gc3.addChild(tp6,0,2);
 
 				gc1.startup();
diff --git a/dojox/layout/tests/test_ResizeHandle.html b/dojox/layout/tests/test_ResizeHandle.html
index 16fb7ee..feb228e 100644
--- a/dojox/layout/tests/test_ResizeHandle.html
+++ b/dojox/layout/tests/test_ResizeHandle.html
@@ -6,12 +6,11 @@
 
 	<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="../ResizeHandle.js"></script>
 	<script language="JavaScript" type="text/javascript">
 		dojo.require("dojo.parser"); 
 		dojo.require("dijit.layout.ContentPane");
 		dojo.require("dijit.form.Button");
-		// dojo.require("dojox.layout.ResizeHandle");
+		dojo.require("dojox.layout.ResizeHandle");
 	
 		function makeNewSizer(){
 			var handle = document.createElement('div');
diff --git a/dojox/layout/tests/test_RotatorContainer.html b/dojox/layout/tests/test_RotatorContainer.html
index f21a4ec..39dadc3 100644
--- a/dojox/layout/tests/test_RotatorContainer.html
+++ b/dojox/layout/tests/test_RotatorContainer.html
@@ -27,6 +27,7 @@
 	<script type="text/javascript">
 		dojo.require("dojo.parser");
 		dojo.require("dijit.form.Button");
+		dojo.require("dijit.form.ToggleButton");
 		dojo.require("dojox.layout.RotatorContainer");
 		dojo.require("dijit.layout.ContentPane");
 		dojo.require("dijit.form.ComboBox");
diff --git a/dojox/layout/tests/test_ScrollPane.html b/dojox/layout/tests/test_ScrollPane.html
index 1b5a12f..964258a 100644
--- a/dojox/layout/tests/test_ScrollPane.html
+++ b/dojox/layout/tests/test_ScrollPane.html
@@ -14,9 +14,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="../ScrollPane.js"></script>
-	
 	<script language="JavaScript" type="text/javascript">
 		
 		dojo.require("dojox.layout.ScrollPane");
diff --git a/dojox/layout/tests/test_ScrollPaneSingle.html b/dojox/layout/tests/test_ScrollPaneSingle.html
index d003556..83ba23f 100644
--- a/dojox/layout/tests/test_ScrollPaneSingle.html
+++ b/dojox/layout/tests/test_ScrollPaneSingle.html
@@ -15,10 +15,9 @@
 	<!-- 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="../ScrollPane.js"></script>
 	<script language="JavaScript" type="text/javascript">
 		dojo.require("dojo.parser");
+		dojo.require("dojox.layout.ScrollPane");
 		dojo.addOnLoad(function(){
 			var i;
 			var n = dojo.byId("hold");
@@ -28,7 +27,7 @@
 				n.appendChild(b); // dojo.clone(dojo.byId("clone")));
 			}
 			dojo.parser.parse();
-			dijit.byId("horiz").layout(); 
+//			dijit.byId("horiz").layout(); 
 		});
 	</script>
 	<style type="text/css">
diff --git a/dojox/layout/tests/test_TableContainer.html b/dojox/layout/tests/test_TableContainer.html
index ca52b1c..7f6d6d4 100644
--- a/dojox/layout/tests/test_TableContainer.html
+++ b/dojox/layout/tests/test_TableContainer.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 language="JavaScript" type="text/javascript" src="../TableContainer.js"></script>
 	
 	<script language="JavaScript" type="text/javascript">
 		
diff --git a/dojox/layout/tests/test_ToggleSplitter.html b/dojox/layout/tests/test_ToggleSplitter.html
index 3cfb1f9..829f5f6 100644
--- a/dojox/layout/tests/test_ToggleSplitter.html
+++ b/dojox/layout/tests/test_ToggleSplitter.html
@@ -4,7 +4,7 @@
 	<title>dojox.layout.ToggleSplitter Test</title>
 
 	<!-- required: a default theme file -->
-	<link rel="stylesheet" id="themeStyles" href="../../../dijit/themes/tundra/tundra.css">
+	<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>
@@ -12,121 +12,65 @@
 	<!-- 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="../ToggleSplitter.js"></script>
-
-	<script type="text/javascript">
-		dojo.require("dojox.layout.ToggleSplitter");
-		dojo.require("dojo.parser");
-	</script>
-
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/tests/css/dijitTests.css";
 		@import "../resources/ToggleSplitter.css";
-		
+		body, html { width:100%; height:100%; margin-left:10px; padding:0; overflow:hidden; }
 	</style>
 	
 	<script type="text/javascript">
+		dojo.require("dojo.parser");
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.BorderContainer");
 		dojo.require("dijit.layout.AccordionContainer");
+		dojo.require("dijit.layout.BorderContainer");
 		dojo.require("dijit.layout.ContentPane");
 		dojo.require("dojox.layout.ToggleSplitter");
-
-		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
-						});
-					})
-					
-				});
-				dojo.connect(spl, "_stopDrag", function(evt) {
-					dojo.style(spl.child.domNode, "opacity", 1);
-					dojo.disconnect(moveConnects[spl.widgetId]); 
-					delete moveConnects[spl.widgetId];
-				});
-				dojo.connect(spl, "onOpen", function() {
-					out.innerHTML = spl.region + ": open";
-				});
-				dojo.connect(spl, "onClose", function() {
-					out.innerHTML = spl.region + ": closed";
-				});
-			})
+		
+		function watchSplitters(bc){
+			var spl = bc.getSplitter("bottom");
+			dojo.connect(spl, "onOpen", function(pane){
+				dojo.style(pane.domNode, "backgroundColor", "#f6f6f6");
+			});
+			dojo.connect(spl, "onCollapsed", function(pane){
+				dojo.style(pane.domNode, "backgroundColor", "#e2effc");
+			});
 		}
+		
 		dojo.addOnLoad(function() {
-			watchSplitters( dijit.byId("watchedBC") );
+			watchSplitters(dijit.byId("border1"));
 		})
 	</script>
 </head>
-<body class="tundra" id="testpage">
+<body class="claro" id="testpage">
 
 	<h2 class="testTitle">dojox.layout.ToggleSplitter tests</h2>
-	<p>Double click the splitters to toggle them open/closed</p>
+	<p>Click the splitters to toggle them <b>open/collapsed(optional)/closed</b>. If <b>toggleSplitterCollapsedSize</b> is set on the content pane, the pane has the optional collapsed state. Or it only has two states.</p>
 
-	<div id="border1" dojoType="dijit.layout.BorderContainer"
-		style="width: 90%; height: 300px; border: 2px solid blue; ">
+	<div id="border1" dojoType="dijit.layout.BorderContainer" style="width: 90%; height: 80%; background: #ffffff; border: 1px solid #b5bcc7; ">
 		<script type="dojo/method">
-			this._splitterClass="dojox.layout.ToggleSplitter";
+			this._splitterClass = "dojox.layout.ToggleSplitter";
 		</script>
-
-		<div dojoType="dijit.layout.ContentPane" region="top" style="background-color: #b39b86; border: 1px black solid; height: 50px;" splitter="true">
-			top bar (resizable)
+		<div dojoType="dijit.layout.ContentPane" region="top" style="background-color: #f6f6f6; border: 1px solid #b5bcc7; height: 50px;" splitter="true" toggleSplitterCollapsedSize="30px">
+			Resizable top bar with three states (open/collapsed/closed). The toggleSplitterCollapsedSize is "20px" here.
 		</div>
-		<div dojoType="dijit.layout.AccordionContainer"
-			minSize="20" style="width: 300px;" id="leftAccordion" region="leading" splitter="true">
-
-			<div dojoType="dijit.layout.ContentPane" title="Popups and Alerts">
-			</div>
-
-			<div dojoType="dijit.layout.ContentPane" title="Dojo Tree from Store">
-			</div>
-
-			<div dojoType="dijit.layout.ContentPane" title="Calendar" selected="true">
-			</div>
-
+		<div dojoType="dijit.layout.AccordionContainer" minSize="20" style="width: 300px;" id="leftAccordion" region="leading" splitter="true">
+			<div dojoType="dijit.layout.ContentPane" title="Popups and Alerts"></div>
+			<div dojoType="dijit.layout.ContentPane" title="Dojo Tree from Store"></div>
+			<div dojoType="dijit.layout.ContentPane" title="Calendar" selected="true"></div>
 			<div dojoType="dijit.layout.ContentPane" title="Color Picker">
 			</div>
-
 		</div><!-- end AccordionContainer -->
-		<div dojoType="dijit.layout.ContentPane" region="center" style="background-color: #f5ffbf; padding: 3px;">
-			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
+		<div dojoType="dijit.layout.ContentPane" region="center" style="background-color: #ffffff; padding: 5px;">
+			Main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 			(to check we're copying children around properly).<br />
 		</div>
-		<div dojoType="dijit.layout.ContentPane" region="right" toggleSplitterOpen="false" style="background-color: #acb386; width: 100px;" splitter="true">
-			initialized closed
+		<div dojoType="dijit.layout.ContentPane" region="right" toggleSplitterState="closed" style="background-color: #f6f6f6; width: 100px;" splitter="true" toggleSplitterCollapsedSize="30px">
+			Initialized closed
 		</div>
-		<div dojoType="dijit.layout.ContentPane" region="bottom" style="background-color: #b39b86; height: 50px;" splitter="true">
-			bottom bar (resizable)
+		<div dojoType="dijit.layout.ContentPane" region="bottom" style="background-color: #f6f6f6; height: 50px;" splitter="true" toggleSplitterCollapsedSize="20px">
+			Resizable bottom bar which background color is changed when the toggle button is clicked.
 		</div>
 	</div>
-	
-	<br />
-	<p>Watching the splitter events</p>
-	<div dojoType="dijit.layout.BorderContainer" id="watchedBC" persist="false" style="height: 200px; width: 100%">
-		<script type="dojo/method">
-			this._splitterClass="dojox.layout.ToggleSplitter";
-		</script>
-		<div dojoType="dijit.layout.ContentPane" region="top" splitter="true" style="background-color: #ccffcc; height: 50px;">Top:</div>
-		<div dojoType="dijit.layout.ContentPane" region="left" style="background-color: #ccccff; width: 40px" splitter="true"><span>Bottom</span></div>
-		<div dojoType="dijit.layout.ContentPane" 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>
-
-
 </body>
 </html>
diff --git a/dojox/layout/tests/test_TouchStackContainer.html b/dojox/layout/tests/test_TouchStackContainer.html
index 85647a4..5240fae 100644
--- a/dojox/layout/tests/test_TouchStackContainer.html
+++ b/dojox/layout/tests/test_TouchStackContainer.html
@@ -24,22 +24,23 @@
 		djConfig="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
 		dojo.require("dijit.layout.ContentPane");
 		dojo.require("dojox.layout.ext-dijit.layout.StackContainer-touch");
 		dojo.require("dijit.form.Button");
+		dojo.require("dijit.layout.StackController");
 		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 
 		function selected(page){
 			console.debug("page selected " + page.id);
 			var widget=dijit.byId("myStackContainer");
-			dijit.byId("previous").attr("disabled", page.isFirstChild);
-			dijit.byId("next").attr("disabled", page.isLastChild);
-			dijit.byId("previous2").attr("disabled", page.isFirstChild);
-			dijit.byId("next2").attr("disabled", page.isLastChild);
+			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>
diff --git a/dojox/main.js b/dojox/main.js
new file mode 100644
index 0000000..6095f00
--- /dev/null
+++ b/dojox/main.js
@@ -0,0 +1,8 @@
+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 dojo.dojox;
+});
\ No newline at end of file
diff --git a/dojox/math/BigInteger-ext.js b/dojox/math/BigInteger-ext.js
index 4b6697d..f48a304 100644
--- a/dojox/math/BigInteger-ext.js
+++ b/dojox/math/BigInteger-ext.js
@@ -1,12 +1,10 @@
 // AMD-ID "dojox/math/BigInteger-ext"
 define(["dojo", "dojox", "dojox/math/BigInteger"], function(dojo, dojox) {
-dojo.experimental("dojox.math.BigInteger-ext");
+	dojo.experimental("dojox.math.BigInteger-ext");
 
 // Contributed under CLA by Tom Wu
 
 // Extended JavaScript BN functions, required for RSA private ops.
-
-(function(){
 	var BigInteger = dojox.math.BigInteger,
 		nbi = BigInteger._nbi, nbv = BigInteger._nbv,
 		nbits = BigInteger._nbits,
@@ -654,7 +652,5 @@ dojo.experimental("dojox.math.BigInteger-ext");
 	// long longValue()
 	// static BigInteger valueOf(long val)
 
-})();
-
-return dojox.math.BigInteger;
+	return dojox.math.BigInteger;
 });
diff --git a/dojox/math/BigInteger.js b/dojox/math/BigInteger.js
index 55a24b0..545fd8b 100644
--- a/dojox/math/BigInteger.js
+++ b/dojox/math/BigInteger.js
@@ -1,7 +1,8 @@
 // AMD-ID "dojox/math/BigInteger"
 define(["dojo", "dojox"], function(dojo, dojox) {
-dojo.getObject("math.BigInteger", true, dojox);
-dojo.experimental("dojox.math.BigInteger");
+
+	dojo.getObject("math.BigInteger", true, dojox);
+	dojo.experimental("dojox.math.BigInteger");
 
 // Contributed under CLA by Tom Wu <tjw at cs.Stanford.EDU>
 // See http://www-cs-students.stanford.edu/~tjw/jsbn/ for details.
@@ -9,8 +10,6 @@ dojo.experimental("dojox.math.BigInteger");
 // Basic JavaScript BN library - subset useful for RSA encryption.
 // The API for dojox.math.BigInteger closely resembles that of the java.math.BigInteger class in Java.
 
-(function(){
-
 	// Bits per digit
 	var dbits;
 
@@ -585,7 +584,6 @@ dojo.experimental("dojox.math.BigInteger");
 
 	// export to DojoX
 	dojox.math.BigInteger = BigInteger;
-})();
 
-return dojox.math.BigInteger;
+	return dojox.math.BigInteger;
 });
diff --git a/dojox/math/_base.js b/dojox/math/_base.js
index a05788d..bdc9222 100644
--- a/dojox/math/_base.js
+++ b/dojox/math/_base.js
@@ -1,8 +1,7 @@
 // AMD-ID "dojox/math/_base"
 define(["dojo", "dojox"], function(dojo, dojox) {
-dojo.getObject("math", true, dojox);
+	dojo.getObject("math", true, dojox);
 
-(function(){
 	var m = dojox.math;
 	dojo.mixin(dojox.math, {
 		toRadians: function(/* Number */n){
@@ -158,7 +157,6 @@ dojo.getObject("math", true, dojox);
 			return m;	//	Array
 		}
 	});
-})();
 
-return dojox.math;
+	return dojox.math;
 });
diff --git a/dojox/math/random/Simple.js b/dojox/math/random/Simple.js
index 467aa18..c8324d2 100644
--- a/dojox/math/random/Simple.js
+++ b/dojox/math/random/Simple.js
@@ -1,27 +1,24 @@
-// AMD-ID "dojox/math/random/Simple"
 define(["dojo"], function(dojo) {
 
-dojo.declare("dojox.math.random.Simple", null, {
-	// summary:
-	//	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)
-	},
-
-	nextBytes: function(/* Array */ byteArray){
+	return dojo.declare("dojox.math.random.Simple", null, {
 		// 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.
-		for(var i = 0, l = byteArray.length; i < l; ++i){
-			byteArray[i] = Math.floor(256 * 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)
+		},
+	
+		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.
+			for(var i = 0, l = byteArray.length; i < l; ++i){
+				byteArray[i] = Math.floor(256 * Math.random());
+			}
 		}
-	}
-});
-
-return dojox.math.random.Simple;
+	});
 });
diff --git a/dojox/math/random/prng4.js b/dojox/math/random/prng4.js
index f7b00cd..ebb47c1 100644
--- a/dojox/math/random/prng4.js
+++ b/dojox/math/random/prng4.js
@@ -1,12 +1,12 @@
 // AMD-ID "dojox/math/random/prng4"
 define(["dojo", "dojox"], function(dojo, dojox) {
-dojo.getObject("math.random.prng4", true, dojox);
+	
+	dojo.getObject("math.random.prng4", true, dojox);
 
 // Copyright (c) 2005  Tom Wu
 // All Rights Reserved.
 // See "LICENSE-BigInteger" for details.
 
-(function(){
 	// prng4.js - uses Arcfour as a PRNG
 
 	function Arcfour() {
@@ -54,7 +54,6 @@ dojo.getObject("math.random.prng4", true, dojox);
 	// Pool size must be a multiple of 4 and greater than 32.
 	// An array of bytes the size of the pool will be passed to init()
 	dojox.math.random.prng4.size = 256;
-})();
-
-return dojox.math.random.prng4;
+	
+	return dojox.math.random.prng4;
 });
diff --git a/dojox/math/round.js b/dojox/math/round.js
index c94f92e..fced6ba 100644
--- a/dojox/math/round.js
+++ b/dojox/math/round.js
@@ -1,56 +1,56 @@
 // AMD-ID "dojox/math/round"
 define(["dojo", "dojox"], function(dojo, dojox) {
-dojo.getObject("math.round", true, dojox);
-dojo.experimental("dojox.math.round");
 
-dojox.math.round = function(/*Number*/value, /*Number?*/places, /*Number?*/increment){
-	//	summary:
-	//		Similar to dojo.number.round, but compensates for binary floating point artifacts
-	//	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
-	//		of Javascript Numbers.  See http://speleotrove.com/decimal/decifaq.html for more information.
-	//		Because of this adjustment, the rounding may not be mathematically correct for full precision
-	//		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:
-	//		The number to round
-	//	places:
-	//		The number of decimal places where rounding takes place.  Defaults to 0 for whole rounding.
-	//		Must be non-negative.
-	//	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
-	var wholeFigs = Math.log(Math.abs(value))/Math.log(10);
-	var factor = 10 / (increment || 10);
-	var delta = Math.pow(10, -15 + wholeFigs);
-	return (factor * (+value + (value > 0 ? delta : -delta))).toFixed(places) / factor; // Number
-}
+	dojo.getObject("math.round", true, dojox);
+	dojo.experimental("dojox.math.round");
 
-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
-	(function(){
+	dojox.math.round = function(/*Number*/value, /*Number?*/places, /*Number?*/increment){
+		//	summary:
+		//		Similar to dojo.number.round, but compensates for binary floating point artifacts
+		//	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
+		//		of Javascript Numbers.  See http://speleotrove.com/decimal/decifaq.html for more information.
+		//		Because of this adjustment, the rounding may not be mathematically correct for full precision
+		//		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:
+		//		The number to round
+		//	places:
+		//		The number of decimal places where rounding takes place.  Defaults to 0 for whole rounding.
+		//		Must be non-negative.
+		//	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
+		var wholeFigs = Math.log(Math.abs(value))/Math.log(10);
+		var factor = 10 / (increment || 10);
+		var delta = Math.pow(10, -15 + wholeFigs);
+		return (factor * (+value + (value > 0 ? delta : -delta))).toFixed(places) / factor; // Number
+	}
+
+	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 = dojox.math.round;
 		dojox.math.round = function(v, p, m){
 			var d = Math.pow(10, -p || 0), a = Math.abs(v);
@@ -59,8 +59,7 @@ if((0.9).toFixed() == 0){
 			}
 			return round(v, p, m) + (v > 0 ? d : -d);
 		}
-	})();
-}
+	}
 
-return dojox.math.round;
+	return dojox.math.round;
 });
diff --git a/dojox/math/stats.js b/dojox/math/stats.js
index 8d275bf..fec0313 100644
--- a/dojox/math/stats.js
+++ b/dojox/math/stats.js
@@ -1,8 +1,8 @@
 // AMD-ID "dojox/math/stats"
-define(["dojo", "dojox"], function(dojo, dojox) {
-dojo.getObject("math.stats", true, dojox);
+define(["dojo", "../main"], function(dojo, dojox) {
+	
+	dojo.getObject("math.stats", true, dojox);
 
-(function(){
 	var st = dojox.math.stats;
 	dojo.mixin(st, {
 		sd: function(/* Number[] */a){
@@ -189,7 +189,6 @@ dojo.getObject("math.stats", true, dojox);
 			return result;	// Object
 		}
 	});
-})();
 
-return dojox.math.stats;
+	return dojox.math.stats;
 });
diff --git a/dojox/mdnd/AreaManager.js b/dojox/mdnd/AreaManager.js
index c10034a..b6061f9 100644
--- a/dojox/mdnd/AreaManager.js
+++ b/dojox/mdnd/AreaManager.js
@@ -1,307 +1,310 @@
-dojo.provide("dojox.mdnd.AreaManager");
-dojo.require("dojox.mdnd.Moveable");
-
-dojo.declare(
-	"dojox.mdnd.AreaManager",
-	null,
-{
-	// summary:
-	//		Drag And Drop manager
-
-	// autoRefresh: Boolean
-	//		Enable the refresh of registered areas on drag start.
-	autoRefresh: true,
-
-
-	// areaClass: String
-	//		CSS class enabled an area if areaClass is defined
-	areaClass: "dojoxDndArea",
-
-	// dragHandleClass: String
-	//		CSS class enabled a drag handle.
-	dragHandleClass: "dojoxDragHandle",
-
-	constructor: function(){
+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(
+		"dojox.mdnd.AreaManager",
+		null,
+	{
 		// summary:
-		//		Constructor of AreaManager class.
-		//		Initialize arrays, connects and subscribes.
-
-		//console.log("dojox.mdnd.AreaManager ::: constructor");
-		this._areaList = [];
-		this.resizeHandler = dojo.connect(dojo.global,"onresize", this, function(){
-			this._dropMode.updateAreas(this._areaList);
-		});
-
-		this._oldIndexArea = this._currentIndexArea = this._oldDropIndex = this._currentDropIndex = this._sourceIndexArea = this._sourceDropIndex = -1;
-	},
-
-	init: function(){
-		// summary:
-		//		Initialize the manager by calling the registerByClass method
-
-		//console.log("dojox.mdnd.AreaManager ::: init");
-		this.registerByClass();
-	},
-
-	registerByNode: function(/*DOMNode*/area, /*Boolean*/notInitAreas){
-		// summary:
-		//		To register Dnd Area : insert the DndArea using the specific sort of dropMode.
-		// area:
-		//		a DOM node corresponding to the Dnd Area
-		// notInitAreas:
-		//		if false or undefined, init the areas.
-
-		//console.log("dojox.mdnd.AreaManager ::: registerByNode", area);
-		var index = this._getIndexArea(area);
-		if(area && index == -1){
-			var acceptType = area.getAttribute("accept");
-			var accept = (acceptType) ? acceptType.split(/\s*,\s*/) : ["text"];
-			var obj = {
-				'node': area,
-				'items': [],
-				'coords': {},
-				'margin': null,
-				'accept': accept,
-				'initItems': false
-			};
-			dojo.forEach(this._getChildren(area), function(item){
-				this._setMarginArea(obj, item);
-				obj.items.push(this._addMoveableItem(item));
-			}, this);
-			this._areaList = this._dropMode.addArea(this._areaList, obj);
-			if(!notInitAreas){
+		//		Drag And Drop manager
+	
+		// autoRefresh: Boolean
+		//		Enable the refresh of registered areas on drag start.
+		autoRefresh: true,
+	
+	
+		// areaClass: String
+		//		CSS class enabled an area if areaClass is defined
+		areaClass: "dojoxDndArea",
+	
+		// dragHandleClass: String
+		//		CSS class enabled a drag handle.
+		dragHandleClass: "dojoxDragHandle",
+	
+		constructor: function(){
+			// summary:
+			//		Constructor of AreaManager class.
+			//		Initialize arrays, connects and subscribes.
+	
+			//console.log("dojox.mdnd.AreaManager ::: constructor");
+			this._areaList = [];
+			this.resizeHandler = dojo.connect(dojo.global,"onresize", this, function(){
 				this._dropMode.updateAreas(this._areaList);
+			});
+	
+			this._oldIndexArea = this._currentIndexArea = this._oldDropIndex = this._currentDropIndex = this._sourceIndexArea = this._sourceDropIndex = -1;
+		},
+	
+		init: function(){
+			// summary:
+			//		Initialize the manager by calling the registerByClass method
+	
+			//console.log("dojox.mdnd.AreaManager ::: init");
+			this.registerByClass();
+		},
+	
+		registerByNode: function(/*DOMNode*/area, /*Boolean*/notInitAreas){
+			// summary:
+			//		To register Dnd Area : insert the DndArea using the specific sort of dropMode.
+			// area:
+			//		a DOM node corresponding to the Dnd Area
+			// notInitAreas:
+			//		if false or undefined, init the areas.
+	
+			//console.log("dojox.mdnd.AreaManager ::: registerByNode", area);
+			var index = this._getIndexArea(area);
+			if(area && index == -1){
+				var acceptType = area.getAttribute("accept");
+				var accept = (acceptType) ? acceptType.split(/\s*,\s*/) : ["text"];
+				var obj = {
+					'node': area,
+					'items': [],
+					'coords': {},
+					'margin': null,
+					'accept': accept,
+					'initItems': false
+				};
+				dojo.forEach(this._getChildren(area), function(item){
+					this._setMarginArea(obj, item);
+					obj.items.push(this._addMoveableItem(item));
+				}, this);
+				this._areaList = this._dropMode.addArea(this._areaList, obj);
+				if(!notInitAreas){
+					this._dropMode.updateAreas(this._areaList);
+				}
+				dojo.publish("/dojox/mdnd/manager/register",[area]);
 			}
-			dojo.publish("/dojox/mdnd/manager/register",[area]);
-		}
-	},
-
-	registerByClass: function(){
-		// summary:
-		//		Register all Dnd Areas identified by the attribute areaClass :
-		//		insert Dnd Areas using the specific sort of dropMode.
-
-		//console.log("dojox.mdnd.AreaManager ::: registerByClass");
-		dojo.query('.'+this.areaClass).forEach(function(area){
-			this.registerByNode(area, true);
-		}, this);
-		this._dropMode.updateAreas(this._areaList);
-	},
-
-	unregister: function(/*DOMNode*/area){
-		// summary:
-		//		Unregister a D&D Area and its children into the AreaManager.
-		// area:
-		//		A node corresponding to the D&D Area.
-		// returns:
-		//		True if the area is found and unregistered.
-
-		//console.log("dojox.mdnd.AreaManager ::: unregister");
-		var index = this._getIndexArea(area);
-		if(index != -1){
-			dojo.forEach(this._areaList[index].items, function(item){
-				this._deleteMoveableItem(item);
+		},
+	
+		registerByClass: function(){
+			// summary:
+			//		Register all Dnd Areas identified by the attribute areaClass :
+			//		insert Dnd Areas using the specific sort of dropMode.
+	
+			//console.log("dojox.mdnd.AreaManager ::: registerByClass");
+			dojo.query('.'+this.areaClass).forEach(function(area){
+				this.registerByNode(area, true);
 			}, this);
-			this._areaList.splice(index,1);
-			// refresh target area
 			this._dropMode.updateAreas(this._areaList);
-			return true; // Boolean
-		}
-		return false; // Boolean
-	},
-
-	_addMoveableItem: function(/*DOMNode*/node){
-		// summary:
-		//		Create a draggable item with a DOM node.
-		// node:
-		//		A child of the D&D Area.
-		// returns:
-		//		The draggable item.
-		// tags:
-		//		protected
-
-		//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);
-		// add a css style :
-		dojo.addClass(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")]
-		}
-		// 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(widget){
-				item.type = widget.dndType ? widget.dndType.split(/\s*,\s*/) : ["text"];
-				item.handlers.push(
-					dojo.connect(widget, "uninitialize", this, function(){
-						this.removeDragItem(node.parentNode, moveable.node);
-					})
-				);
+		},
+	
+		unregister: function(/*DOMNode*/area){
+			// summary:
+			//		Unregister a D&D Area and its children into the AreaManager.
+			// area:
+			//		A node corresponding to the D&D Area.
+			// returns:
+			//		True if the area is found and unregistered.
+	
+			//console.log("dojox.mdnd.AreaManager ::: unregister");
+			var index = this._getIndexArea(area);
+			if(index != -1){
+				dojo.forEach(this._areaList[index].items, function(item){
+					this._deleteMoveableItem(item);
+				}, this);
+				this._areaList.splice(index,1);
+				// refresh target area
+				this._dropMode.updateAreas(this._areaList);
+				return true; // Boolean
 			}
-		}
-		return item; // Object
-	},
-
-	_deleteMoveableItem: function(/*Object*/ objItem){
-		// summary:
-		//		Delete the Moveable object associated with a node.
-		// item:
-		//		A moveable Object.
-		// tags:
-		//		protected
-
-		//console.log("dojox.mdnd.AreaManager ::: _deleteMoveableItem", objItem);
-		// disconnect the handle
-		dojo.forEach(objItem.handlers, function(handler){
-			dojo.disconnect(handler);
-		});
-		// delete css style :
-		var node = objItem.item.node,
-			handle = this._searchDragHandle(node);
-		dojo.removeClass(handle || node, "dragHandle");
-		// call destroy of Moveable class
-		objItem.item.destroy();
-	},
-
-	_getIndexArea: function(/*DOMNode*/area){
-		// summary:
-		//		Get the index of an area.
-	 	// area:
-	 	//		A moveable Object.
-	 	// returns:
-	 	//		area index or -1
-	 	// tags:
-	 	//		protected
-
-		//console.log("dojox.mdnd.AreaManager ::: _getIndexArea");
-		if(area){
-			for(var i = 0; i < this._areaList.length; i++){
-				if(this._areaList[i].node === area){
-					return i;	// Integer
-				}
+			return false; // Boolean
+		},
+	
+		_addMoveableItem: function(/*DOMNode*/node){
+			// summary:
+			//		Create a draggable item with a DOM node.
+			// node:
+			//		A child of the D&D Area.
+			// returns:
+			//		The draggable item.
+			// tags:
+			//		protected
+	
+			//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);
+			// add a css style :
+			dojo.addClass(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")]
 			}
-		}
-		return -1;	// Integer
-	},
-
-	_searchDragHandle: function(/*DOMNode*/node){
-		// summary:
-		//		Return the node which contains the first specific CSS class handle.
-		// node:
-		//		A child of the D&D Area.
-		// returns:
-		//		The drag handle node.
-		// tags:
-		//		protected
-
-		//console.log("dojox.mdnd.AreaManager ::: _searchDragHandle");
-		if(node){
-			var cssArray = this.dragHandleClass.split(' '),
-				length = cssArray.length,
-				queryCss = "";
-			dojo.forEach(cssArray, function(css, i){
-				queryCss += "." + css;
-				if(i != length - 1){
-					queryCss += ", ";
+			// 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(widget){
+					item.type = widget.dndType ? widget.dndType.split(/\s*,\s*/) : ["text"];
+					item.handlers.push(
+						dojo.connect(widget, "uninitialize", this, function(){
+							this.removeDragItem(node.parentNode, moveable.node);
+						})
+					);
 				}
+			}
+			return item; // Object
+		},
+	
+		_deleteMoveableItem: function(/*Object*/ objItem){
+			// summary:
+			//		Delete the Moveable object associated with a node.
+			// item:
+			//		A moveable Object.
+			// tags:
+			//		protected
+	
+			//console.log("dojox.mdnd.AreaManager ::: _deleteMoveableItem", objItem);
+			// disconnect the handle
+			dojo.forEach(objItem.handlers, function(handler){
+				dojo.disconnect(handler);
 			});
-			return dojo.query(queryCss, node)[0]; // DomNode
-		}
-	},
-
-	addDragItem: function(/*DOMNode*/area, /*DOMNode*/node, /*Integer*/index, /*Boolean*/notCheckParent){
-		// summary:
-		//		To add an item programmatically.
-		// area:
-		//		a node corresponding to the D&D Area
-		// node:
-		//		the node which has to be treated.
-		// index:
-		//		the place in the area
-		// noCheckParent:
-		//		if true, doesn't check if node has a parent.
-		// returns:
-		//		True if the node has been inserted else false.
-
-		//console.log("dojox.mdnd.AreaManager ::: addDragItem");
-		var add = true;
-		if(!notCheckParent){
-			add = area && node && (node.parentNode === null || (node.parentNode && node.parentNode.nodeType !== 1));
-		}
-		if(add){
-			var indexArea = this._getIndexArea(area);
-			if(indexArea !== -1){
-				var item = this._addMoveableItem(node),
-					items = this._areaList[indexArea].items;
-				if(0 <= index && index < items.length){
-					var firstListChild = items.slice(0, index),
-						lastListChild = items.slice(index, items.length);
-					firstListChild[firstListChild.length] = item;
-					this._areaList[indexArea].items = firstListChild.concat(lastListChild);
-					area.insertBefore(node, items[index].item.node);
+			// delete css style :
+			var node = objItem.item.node,
+				handle = this._searchDragHandle(node);
+			dojo.removeClass(handle || node, "dragHandle");
+			// call destroy of Moveable class
+			objItem.item.destroy();
+		},
+	
+		_getIndexArea: function(/*DOMNode*/area){
+			// summary:
+			//		Get the index of an area.
+			// area:
+			//		A moveable Object.
+			// returns:
+			//		area index or -1
+			// tags:
+			//		protected
+	
+			//console.log("dojox.mdnd.AreaManager ::: _getIndexArea");
+			if(area){
+				for(var i = 0; i < this._areaList.length; i++){
+					if(this._areaList[i].node === area){
+						return i;	// Integer
+					}
 				}
-				else{
-					this._areaList[indexArea].items.push(item);
-					area.appendChild(node);
+			}
+			return -1;	// Integer
+		},
+	
+		_searchDragHandle: function(/*DOMNode*/node){
+			// summary:
+			//		Return the node which contains the first specific CSS class handle.
+			// node:
+			//		A child of the D&D Area.
+			// returns:
+			//		The drag handle node.
+			// tags:
+			//		protected
+	
+			//console.log("dojox.mdnd.AreaManager ::: _searchDragHandle");
+			if(node){
+				var cssArray = this.dragHandleClass.split(' '),
+					length = cssArray.length,
+					queryCss = "";
+				dojo.forEach(cssArray, function(css, i){
+					queryCss += "." + css;
+					if(i != length - 1){
+						queryCss += ", ";
+					}
+				});
+				return dojo.query(queryCss, node)[0]; // DomNode
+			}
+		},
+	
+		addDragItem: function(/*DOMNode*/area, /*DOMNode*/node, /*Integer*/index, /*Boolean*/notCheckParent){
+			// summary:
+			//		To add an item programmatically.
+			// area:
+			//		a node corresponding to the D&D Area
+			// node:
+			//		the node which has to be treated.
+			// index:
+			//		the place in the area
+			// noCheckParent:
+			//		if true, doesn't check if node has a parent.
+			// returns:
+			//		True if the node has been inserted else false.
+	
+			//console.log("dojox.mdnd.AreaManager ::: addDragItem");
+			var add = true;
+			if(!notCheckParent){
+				add = area && node && (node.parentNode === null || (node.parentNode && node.parentNode.nodeType !== 1));
+			}
+			if(add){
+				var indexArea = this._getIndexArea(area);
+				if(indexArea !== -1){
+					var item = this._addMoveableItem(node),
+						items = this._areaList[indexArea].items;
+					if(0 <= index && index < items.length){
+						var firstListChild = items.slice(0, index),
+							lastListChild = items.slice(index, items.length);
+						firstListChild[firstListChild.length] = item;
+						this._areaList[indexArea].items = firstListChild.concat(lastListChild);
+						area.insertBefore(node, items[index].item.node);
+					}
+					else{
+						this._areaList[indexArea].items.push(item);
+						area.appendChild(node);
+					}
+					this._setMarginArea(this._areaList[indexArea], node);
+					this._areaList[indexArea].initItems = false;
+					return true;	// Boolean
 				}
-				this._setMarginArea(this._areaList[indexArea], node);
-				this._areaList[indexArea].initItems = false;
-				return true;	// Boolean
 			}
-		}
-		return false;	// Boolean
-	},
-
-	removeDragItem: function(/*DOMNode*/area, /*DOMNode*/node){
-		// summary:
-		//		Delete a moveable item programmatically. The node is removed from the area.
-		// area:
-		//		A node corresponding to the DndArea.
-		// node:
-		//		The node which has to be treated.
-		// returns:
-		//		the removed node
-
-		//console.log("dojox.mdnd.AreaManager ::: removeDragItem");
-		var index = this._getIndexArea(area);
-		if(area && index !== -1){
-			var items = this._areaList[index].items;
-			for(var j = 0; j < items.length; j++){
-				if(items[j].item.node === node){
-					this._deleteMoveableItem(items[j]);
-					// delete item of the array
-					items.splice(j, 1);
-					return area.removeChild(node); // Object
+			return false;	// Boolean
+		},
+	
+		removeDragItem: function(/*DOMNode*/area, /*DOMNode*/node){
+			// summary:
+			//		Delete a moveable item programmatically. The node is removed from the area.
+			// area:
+			//		A node corresponding to the DndArea.
+			// node:
+			//		The node which has to be treated.
+			// returns:
+			//		the removed node
+	
+			//console.log("dojox.mdnd.AreaManager ::: removeDragItem");
+			var index = this._getIndexArea(area);
+			if(area && index !== -1){
+				var items = this._areaList[index].items;
+				for(var j = 0; j < items.length; j++){
+					if(items[j].item.node === node){
+						this._deleteMoveableItem(items[j]);
+						// delete item of the array
+						items.splice(j, 1);
+						return area.removeChild(node); // Object
+					}
 				}
 			}
-		}
-		return null;
-	},
-
-	_getChildren: function(/*DOMNode*/area){
-		// summary:
-		//		Get the children of a D&D area.
-		// area:
-		//		A DnD area.
-		// returns:
-		//		The children of a DnD area
-		// tags:
-		//		protected
-
-		//console.log("dojox.mdnd.AreaManager ::: _getChildren");
-		var children = [];
-		dojo.forEach(area.childNodes, function(child){
-			// delete \n
-			if(child.nodeType == 1){
-				if(dijit && dijit.byNode){
-					var widget = dijit.byNode(child);
-					if(widget){
-						if(!widget.dragRestriction){
+			return null;
+		},
+	
+		_getChildren: function(/*DOMNode*/area){
+			// summary:
+			//		Get the children of a D&D area.
+			// area:
+			//		A DnD area.
+			// returns:
+			//		The children of a DnD area
+			// tags:
+			//		protected
+	
+			//console.log("dojox.mdnd.AreaManager ::: _getChildren");
+			var children = [];
+			dojo.forEach(area.childNodes, function(child){
+				// delete \n
+				if(child.nodeType == 1){
+					if(dijit && dijit.byNode){
+						var widget = dijit.byNode(child);
+						if(widget){
+							if(!widget.dragRestriction){
+								children.push(child);
+							}
+						}
+						else{
 							children.push(child);
 						}
 					}
@@ -309,399 +312,397 @@ dojo.declare(
 						children.push(child);
 					}
 				}
-				else{
-					children.push(child);
+			});
+			return children;	//Array
+		},
+	
+		_setMarginArea: function(/*Object*/area,/*DOMNode*/node){
+			// summary:
+			//		Set the value of margin in the data type of areaManager
+			//		only when the margin has never been computed.
+			// area:
+			//		The object of a D&D Area.
+			// node:
+			//		The node which contains margins
+			// tags:
+			//		protected
+	
+			//console.log("dojox.mdnd.AreaManager ::: _setMarginArea");
+			if(area && area.margin === null && node){
+				area.margin = dojo._getMarginExtents(node);
+			}
+		},
+	
+		findCurrentIndexArea: function(/*Object*/coords, /*Object*/size){
+			// summary:
+			//		find the nearest target area according to coordinates.
+			//		Coordinates are representing by an object : for example, {'x':10,'y':10}
+			// coords:
+			//		an object encapsulating X and Y position
+			// size:
+			//		an object encapsulating the area size
+			// returns:
+			//		an index of area
+	
+			//console.log("dojox.mdnd.AreaManager ::: findCurrentIndexArea");
+			this._oldIndexArea = this._currentIndexArea;
+			this._currentIndexArea = this._dropMode.getTargetArea(this._areaList, coords, this._currentIndexArea);
+			if(this._currentIndexArea != this._oldIndexArea){
+				if(this._oldIndexArea != -1){
+					this.onDragExit(coords, size);
+				}
+				if(this._currentIndexArea != -1){
+					this.onDragEnter(coords, size);
 				}
 			}
-		});
-		return children;	//Array
-	},
-
-	_setMarginArea: function(/*Object*/area,/*DOMNode*/node){
-		// summary:
-		//		Set the value of margin in the data type of areaManager
-		//		only when the margin has never been computed.
-		// area:
-		//		The object of a D&D Area.
-		// node:
-		//		The node which contains margins
-		// tags:
-		//		protected
-
-		//console.log("dojox.mdnd.AreaManager ::: _setMarginArea");
-		if(area && area.margin === null && node){
-			area.margin = dojo._getMarginExtents(node);
-		}
-	},
-
-	findCurrentIndexArea: function(/*Object*/coords, /*Object*/size){
-		// summary:
-		//		find the nearest target area according to coordinates.
-		//		Coordinates are representing by an object : for example, {'x':10,'y':10}
-		// coords:
-		//		an object encapsulating X and Y position
-		// size:
-		//		an object encapsulating the area size
-		// returns:
-		//		an index of area
-
-		//console.log("dojox.mdnd.AreaManager ::: findCurrentIndexArea");
-		this._oldIndexArea = this._currentIndexArea;
-		this._currentIndexArea = this._dropMode.getTargetArea(this._areaList, coords, this._currentIndexArea);
-		if(this._currentIndexArea != this._oldIndexArea){
-			if(this._oldIndexArea != -1){
-				this.onDragExit(coords, size);
-			}
-			if(this._currentIndexArea != -1){
-				this.onDragEnter(coords, size);
+			return this._currentIndexArea;	//Integer
+		},
+	
+		_isAccepted: function(/*Array*/ type, /*Array*/ accept){
+			// summary:
+			//		True if user can drop widget on this node.
+			// type:
+			//		Array containing item type
+			// accept:
+			//		Array containing types
+			this._accept = false;
+			for(var i = 0; i < accept.length; ++i){
+				for(var j = 0; j < type.length;++j){
+					if(type[j] == accept[i]){
+						this._accept = true;
+						break;
+					}
+				}
 			}
-		}
-		return this._currentIndexArea;	//Integer
-	},
-
-	_isAccepted: function(/*Array*/ type, /*Array*/ accept){
-		// summary:
-		//		True if user can drop widget on this node.
-		// type:
-		//		Array containing item type
-		// accept:
-		//		Array containing types
-		this._accept = false;
-		for(var i = 0; i < accept.length; ++i){
-			for(var j = 0; j < type.length;++j){
-				if(type[j] == accept[i]){
-					this._accept = true;
+		},
+	
+		onDragStart: function(/*DOMNode*/node, /*Object*/coords, /*Object*/size){
+			// summary:
+			//		Initialize the drag (see dojox.mdnd.Moveable.initOffsetDrag())
+			// node:
+			//		The node which is about to be dragged
+			// coords:
+			//		an object encapsulating X and Y position
+			// size:
+			//		an object encapsulating width and height values
+			// tags:
+			//		callback
+	
+			//console.log("dojox.mdnd.AreaManager ::: onDragStart");
+			if(this.autoRefresh){
+				this._dropMode.updateAreas(this._areaList);
+			}
+	
+			// Create the cover :
+			var _html = (dojo.isWebKit) ? dojo.body() : dojo.body().parentNode;
+			if(!this._cover){
+				this._cover = dojo.create('div', {
+					'class': "dndCover"
+				});
+				this._cover2 = dojo.clone(this._cover);
+				dojo.addClass(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");
+			// to know the source
+			this._sourceIndexArea = this._lastValidIndexArea = this._currentIndexArea = this._getIndexArea(node.parentNode);
+			// delete the dragItem into the source area
+			var sourceArea = this._areaList[this._sourceIndexArea];
+			var children = sourceArea.items;
+			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"));
+					children.splice(i,1);
+					this._currentDropIndex = this._sourceDropIndex = i;
 					break;
 				}
 			}
-		}
-	},
-
-	onDragStart: function(/*DOMNode*/node, /*Object*/coords, /*Object*/size){
-		// summary:
-		//		Initialize the drag (see dojox.mdnd.Moveable.initOffsetDrag())
-		// node:
-		//		The node which is about to be dragged
-		// coords:
-		//		an object encapsulating X and Y position
-		// size:
-		//		an object encapsulating width and height values
-		// tags:
-		//		callback
-
-		//console.log("dojox.mdnd.AreaManager ::: onDragStart");
-		if(this.autoRefresh){
-			this._dropMode.updateAreas(this._areaList);
-		}
-
-		// Create the cover :
-		var _html = (dojo.isWebKit) ? dojo.body() : dojo.body().parentNode;
-		if(!this._cover){
-			this._cover = dojo.create('div', {
-				'class': "dndCover"
-			});
-			this._cover2 = dojo.clone(this._cover);
-			dojo.addClass(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");
-		// to know the source
-		this._sourceIndexArea = this._lastValidIndexArea = this._currentIndexArea = this._getIndexArea(node.parentNode);
-		// delete the dragItem into the source area
-		var sourceArea = this._areaList[this._sourceIndexArea];
-		var children = sourceArea.items;
-		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"));
-				children.splice(i,1);
-				this._currentDropIndex = this._sourceDropIndex = i;
-				break;
+			var nodeRef = null;
+			if(this._sourceDropIndex !== sourceArea.items.length){
+				nodeRef = sourceArea.items[this._sourceDropIndex].item.node;
 			}
-		}
-		var nodeRef = null;
-		if(this._sourceDropIndex !== sourceArea.items.length){
-			nodeRef = sourceArea.items[this._sourceDropIndex].item.node;
-		}
-		// IE7 OPTIMIZATION
-		if(dojo.isIE > 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")
-			];
-		}
-
-		var s = node.style;
-		s.left = coords.x+"px";
-		s.top = coords.y+"px";
-		// attach the node to the cover
-		if(s.position == "relative" || s.position == ""){
-			s.position = "absolute"; // enforcing the absolute mode
-		}
-		this._cover.appendChild(node);
-
-		this._dropIndicator.place(sourceArea.node, nodeRef, size);
-		// add a style to place the _dragNode in foreground
-		dojo.addClass(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]);
-	},
-
-	onDragEnter: function(/*Object*/coords, /*Object*/size){
-		// summary:
-		//		Optionally called by the getTargetArea method of TargetFinder class.
-		// coords:
-		//		coordinates of the dragged Node.
-		// size:
-		//		size of the dragged Node.
-		// tags:
-		//		callback
-
-		//console.log("dojox.mdnd.AreaManager ::: onDragEnter", coords, size);
-		if(this._currentIndexArea === this._sourceIndexArea){
+			// IE7 OPTIMIZATION
+			if(dojo.isIE > 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")
+				];
+			}
+	
+			var s = node.style;
+			s.left = coords.x+"px";
+			s.top = coords.y+"px";
+			// attach the node to the cover
+			if(s.position == "relative" || s.position == ""){
+				s.position = "absolute"; // enforcing the absolute mode
+			}
+			this._cover.appendChild(node);
+	
+			this._dropIndicator.place(sourceArea.node, nodeRef, size);
+			// add a style to place the _dragNode in foreground
+			dojo.addClass(node, "dragNode");
+			// A dragged node is always draggable in this source area.
 			this._accept = true;
-		}
-		else{
-			this._isAccepted(this._dragItem.type, this._areaList[this._currentIndexArea].accept);
-		}
-	},
-
-	onDragExit: function(/*Object*/coords, /*Object*/size){
-		// summary:
-		//		Optionally called by the getTargetArea method of TargetFinder class.
-		// coords:
-		//		coordinates of the dragged Node.
-		// size:
-		//		size of the dragged Node.
-		// tags:
-		//		callback
-
-		//console.log("dojox.mdnd.AreaManager ::: onDragExit");
-		this._accept = false;
-	},
-
-	onDrag: function(/*DOMNode*/node, /*Object*/coords, /*Object*/size, /*Object*/mousePosition){
-		// summary:
-		//		Occurs when the dojo.dnd.Moveable.onDrag is fired.
-		//		Search the nearest target area and called the placeDropIndicator
-		// node:
-		//		The node which is dragged
-		// coords:
-		//		an object encapsulating X and Y position
-		// size:
-		//		an object encapsulating width and height values
-		// mousePosition:
-		//		coordinates of mouse
-		// tags:
-		//		callback
-
-		//console.log("dojox.mdnd.AreaManager ::: onDrag", node, ",", coords,size);
-		var coordinates = this._dropMode.getDragPoint(coords, size, mousePosition);
-		this.findCurrentIndexArea(coordinates, size);
-		if(this._currentIndexArea !== -1 && this._accept){
-			this.placeDropIndicator(coordinates, size);
-		}
-	},
-
-	placeDropIndicator: function(/*Object*/coords, /*Object*/size){
-		// summary:
-		//		Search the right place to insert the dropIndicator and display the dropIndicator.
-		// coords:
-		//		an object encapsulating X and Y position
-		// size:
-		//		an object encapsulating width and height values
-		// returns:
-		//		the current drop index
-
-		//console.log("dojox.mdnd.AreaManager ::: placeDropIndicator");
-		//keep old drop Index
-		this._oldDropIndex = this._currentDropIndex;
-		// calculate all children marker (see VerticalDropMode.initItems())
-		var area = this._areaList[this._currentIndexArea];
-		if(!area.initItems){
-			this._dropMode.initItems(area);
-		}
-		//get the index where the drop has to be placed.
-		this._currentDropIndex = this._dropMode.getDropIndex(area, coords);
-		if(!(this._currentIndexArea === this._oldIndexArea && this._oldDropIndex === this._currentDropIndex)){
-			this._placeDropIndicator(size);
-		}
-		return this._currentDropIndex;	//Integer
-	},
-
-	_placeDropIndicator: function(/*Object*/size){
-		// summary:
-		//		place the dropIndicator
-		// size:
-		//		an object encapsulating width and height values
-		// tags:
-		//		protected
-
-		var oldArea = this._areaList[this._lastValidIndexArea];
-		var currentArea = this._areaList[this._currentIndexArea];
-		//refresh the previous area after moving out the drop indicator
-		this._dropMode.refreshItems(oldArea, this._oldDropIndex, size, false);
-		// place dropIndicator
-		var node = null;
-		if(this._currentDropIndex != -1){
-			node = currentArea.items[this._currentDropIndex].item.node;
-		}
-		this._dropIndicator.place(currentArea.node, node);
-		this._lastValidIndexArea = this._currentIndexArea;
-		//refresh the current area after placing the drop indicator
-		this._dropMode.refreshItems(currentArea, this._currentDropIndex, size, true);
-	},
-
-	onDropCancel: function(){
-		// summary:
-		//		Cancel the drop.
-		//		The dragNode returns into the source.
-		// tags:
-		//		callback
-
-		//console.log("dojox.mdnd.AreaManager ::: onDropCancel");
-		if(!this._accept){
-			var index = this._getIndexArea(this._dropIndicator.node.parentNode);
-			if(index != -1){
-				this._currentIndexArea = index;
+			dojo.publish("/dojox/mdnd/drag/start",[node, sourceArea, this._sourceDropIndex]);
+		},
+	
+		onDragEnter: function(/*Object*/coords, /*Object*/size){
+			// summary:
+			//		Optionally called by the getTargetArea method of TargetFinder class.
+			// coords:
+			//		coordinates of the dragged Node.
+			// size:
+			//		size of the dragged Node.
+			// tags:
+			//		callback
+	
+			//console.log("dojox.mdnd.AreaManager ::: onDragEnter", coords, size);
+			if(this._currentIndexArea === this._sourceIndexArea){
+				this._accept = true;
+			}
+			else{
+				this._isAccepted(this._dragItem.type, this._areaList[this._currentIndexArea].accept);
+			}
+		},
+	
+		onDragExit: function(/*Object*/coords, /*Object*/size){
+			// summary:
+			//		Optionally called by the getTargetArea method of TargetFinder class.
+			// coords:
+			//		coordinates of the dragged Node.
+			// size:
+			//		size of the dragged Node.
+			// tags:
+			//		callback
+	
+			//console.log("dojox.mdnd.AreaManager ::: onDragExit");
+			this._accept = false;
+		},
+	
+		onDrag: function(/*DOMNode*/node, /*Object*/coords, /*Object*/size, /*Object*/mousePosition){
+			// summary:
+			//		Occurs when the dojo.dnd.Moveable.onDrag is fired.
+			//		Search the nearest target area and called the placeDropIndicator
+			// node:
+			//		The node which is dragged
+			// coords:
+			//		an object encapsulating X and Y position
+			// size:
+			//		an object encapsulating width and height values
+			// mousePosition:
+			//		coordinates of mouse
+			// tags:
+			//		callback
+	
+			//console.log("dojox.mdnd.AreaManager ::: onDrag", node, ",", coords,size);
+			var coordinates = this._dropMode.getDragPoint(coords, size, mousePosition);
+			this.findCurrentIndexArea(coordinates, size);
+			if(this._currentIndexArea !== -1 && this._accept){
+				this.placeDropIndicator(coordinates, size);
+			}
+		},
+	
+		placeDropIndicator: function(/*Object*/coords, /*Object*/size){
+			// summary:
+			//		Search the right place to insert the dropIndicator and display the dropIndicator.
+			// coords:
+			//		an object encapsulating X and Y position
+			// size:
+			//		an object encapsulating width and height values
+			// returns:
+			//		the current drop index
+	
+			//console.log("dojox.mdnd.AreaManager ::: placeDropIndicator");
+			//keep old drop Index
+			this._oldDropIndex = this._currentDropIndex;
+			// calculate all children marker (see VerticalDropMode.initItems())
+			var area = this._areaList[this._currentIndexArea];
+			if(!area.initItems){
+				this._dropMode.initItems(area);
+			}
+			//get the index where the drop has to be placed.
+			this._currentDropIndex = this._dropMode.getDropIndex(area, coords);
+			if(!(this._currentIndexArea === this._oldIndexArea && this._oldDropIndex === this._currentDropIndex)){
+				this._placeDropIndicator(size);
+			}
+			return this._currentDropIndex;	//Integer
+		},
+	
+		_placeDropIndicator: function(/*Object*/size){
+			// summary:
+			//		place the dropIndicator
+			// size:
+			//		an object encapsulating width and height values
+			// tags:
+			//		protected
+	
+			var oldArea = this._areaList[this._lastValidIndexArea];
+			var currentArea = this._areaList[this._currentIndexArea];
+			//refresh the previous area after moving out the drop indicator
+			this._dropMode.refreshItems(oldArea, this._oldDropIndex, size, false);
+			// place dropIndicator
+			var node = null;
+			if(this._currentDropIndex != -1){
+				node = currentArea.items[this._currentDropIndex].item.node;
+			}
+			this._dropIndicator.place(currentArea.node, node);
+			this._lastValidIndexArea = this._currentIndexArea;
+			//refresh the current area after placing the drop indicator
+			this._dropMode.refreshItems(currentArea, this._currentDropIndex, size, true);
+		},
+	
+		onDropCancel: function(){
+			// summary:
+			//		Cancel the drop.
+			//		The dragNode returns into the source.
+			// tags:
+			//		callback
+	
+			//console.log("dojox.mdnd.AreaManager ::: onDropCancel");
+			if(!this._accept){
+				var index = this._getIndexArea(this._dropIndicator.node.parentNode);
+				if(index != -1){
+					this._currentIndexArea = index;
+				}
+				else{
+					// case if the dropIndicator is in the area which has been unregistered during the drag.
+					// chose by default the first area.
+					this._currentIndexArea = 0;
+				}
+			}
+		},
+	
+		onDrop: function(/*DOMNode*/node){
+			// summary:
+			//		Drop the dragged item where the dropIndicator is displayed.
+			// node:
+			//		The node which is about to be dropped
+			// tags:
+			//		callback
+	
+			//console.log("dojox.mdnd.AreaManager ::: onDrop");
+			//dropCancel
+			this.onDropCancel();
+			var targetArea = this._areaList[this._currentIndexArea];
+			dojo.removeClass(node, "dragNode");
+			var style = node.style;
+			style.position = "relative";
+			style.left = "0";
+			style.top = "0";
+			style.width = "auto";
+			if(targetArea.node == this._dropIndicator.node.parentNode){
+				targetArea.node.insertBefore(node, this._dropIndicator.node);
 			}
 			else{
 				// case if the dropIndicator is in the area which has been unregistered during the drag.
-				// chose by default the first area.
-				this._currentIndexArea = 0;
+				targetArea.node.appendChild(node);
+				this._currentDropIndex = targetArea.items.length;
 			}
-		}
-	},
-
-	onDrop: function(/*DOMNode*/node){
-		// summary:
-		//		Drop the dragged item where the dropIndicator is displayed.
-		// node:
-		//		The node which is about to be dropped
-		// tags:
-		//		callback
-
-		//console.log("dojox.mdnd.AreaManager ::: onDrop");
-		//dropCancel
-		this.onDropCancel();
-		var targetArea = this._areaList[this._currentIndexArea];
-		dojo.removeClass(node, "dragNode");
-		var style = node.style;
-		style.position = "relative";
-		style.left = "0";
-		style.top = "0";
-		style.width = "auto";
-		if(targetArea.node == this._dropIndicator.node.parentNode){
-			targetArea.node.insertBefore(node, this._dropIndicator.node);
-		}
-		else{
-			// case if the dropIndicator is in the area which has been unregistered during the drag.
-			targetArea.node.appendChild(node);
-			this._currentDropIndex = targetArea.items.length;
-		}
-		// add child into the new target area.
-		var indexChild = this._currentDropIndex;
-		if(indexChild == -1){
-			indexChild = targetArea.items.length;
-		}
-		var children = targetArea.items;
-		var firstListArea = children.slice(0, indexChild);
-		var lastListArea = children.slice(indexChild, children.length);
-		firstListArea[firstListArea.length] = this._dragItem;
-		targetArea.items = firstListArea.concat(lastListArea);
-
-		this._setMarginArea(targetArea, node);
-		dojo.forEach(this._areaList, function(obj){
-			obj.initItems = false;
-		});
-		// disconnect onDrop handler
-		dojo.disconnect(this._dragItem.handlers.pop());
-		dojo.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]);
-	},
-
-	_resetAfterDrop: function(){
-		// summary:
-		//		reset manager properties after dropping an item
-		// tags:
-		//		protected
-
-		this._accept = false;
-		this._dragItem = null;
-		this._currentDropIndex = -1;
-		this._currentIndexArea = -1;
-		this._oldDropIndex = -1;
-		this._sourceIndexArea = -1;
-		this._sourceDropIndex = -1;
-		this._dropIndicator.remove();
-		if(this._dragStartHandler){
-			dojo.disconnect(this._dragStartHandler);
-		}
-		if(dojo.isIE > 7){
-			dojo.forEach(this._eventsIE7, dojo.disconnect);
-		}
-	},
-
-	destroy: function(){
-		// summary:
-		//		Destroy the component.
-
-		//console.log("dojox.mdnd.AreaManager ::: destroy");
-		//see implementation of unregister()
-		while(this._areaList.length > 0){
-			if(!this.unregister(this._areaList[0].node)){
-				throw new Error("Error while destroying AreaManager");
+			// add child into the new target area.
+			var indexChild = this._currentDropIndex;
+			if(indexChild == -1){
+				indexChild = targetArea.items.length;
+			}
+			var children = targetArea.items;
+			var firstListArea = children.slice(0, indexChild);
+			var lastListArea = children.slice(indexChild, children.length);
+			firstListArea[firstListArea.length] = this._dragItem;
+			targetArea.items = firstListArea.concat(lastListArea);
+	
+			this._setMarginArea(targetArea, node);
+			dojo.forEach(this._areaList, function(obj){
+				obj.initItems = false;
+			});
+			// disconnect onDrop handler
+			dojo.disconnect(this._dragItem.handlers.pop());
+			dojo.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]);
+		},
+	
+		_resetAfterDrop: function(){
+			// summary:
+			//		reset manager properties after dropping an item
+			// tags:
+			//		protected
+	
+			this._accept = false;
+			this._dragItem = null;
+			this._currentDropIndex = -1;
+			this._currentIndexArea = -1;
+			this._oldDropIndex = -1;
+			this._sourceIndexArea = -1;
+			this._sourceDropIndex = -1;
+			this._dropIndicator.remove();
+			if(this._dragStartHandler){
+				dojo.disconnect(this._dragStartHandler);
+			}
+			if(dojo.isIE > 7){
+				dojo.forEach(this._eventsIE7, dojo.disconnect);
+			}
+		},
+	
+		destroy: function(){
+			// summary:
+			//		Destroy the component.
+	
+			//console.log("dojox.mdnd.AreaManager ::: destroy");
+			//see implementation of unregister()
+			while(this._areaList.length > 0){
+				if(!this.unregister(this._areaList[0].node)){
+					throw new Error("Error while destroying AreaManager");
+				}
+			}
+			dojo.disconnect(this.resizeHandler);
+			this._dropIndicator.destroy();
+			this._dropMode.destroy();
+			if(dojox.mdnd.autoScroll){
+				dojox.mdnd.autoScroll.destroy();
+			}
+			if(this.refreshListener){
+				dojo.unsubscribe(this.refreshListener);
+			}
+			// destroy the cover
+			if(this._cover){
+				dojo._destroyElement(this._cover);
+				dojo._destroyElement(this._cover2);
+				delete this._cover;
+				delete this._cover2;
 			}
 		}
-		dojo.disconnect(this.resizeHandler);
-		this._dropIndicator.destroy();
-		this._dropMode.destroy();
-		if(dojox.mdnd.autoScroll){
-			dojox.mdnd.autoScroll.destroy();
-		}
-		if(this.refreshListener){
-			dojo.unsubscribe(this.refreshListener);
-		}
-		// destroy the cover
-		if(this._cover){
-			dojo._destroyElement(this._cover);
-			dojo._destroyElement(this._cover2);
-			delete this._cover;
-			delete this._cover2;
-		}
-	}
-});
-
-if(dijit && dijit._Widget){
-	//	Add a new property to widget
-	dojo.extend(dijit._Widget, {
-		// dndType: String
-		//		Defines a type of widget.
-		dndType : "text"
 	});
-}
-
-dojox.mdnd._areaManager = null;
-dojox.mdnd.areaManager = function(){
-	// summary:
-	//		Returns the current areaManager, creates one if it is not created yet.
-	if(!dojox.mdnd._areaManager){
-		dojox.mdnd._areaManager = new dojox.mdnd.AreaManager();
+	
+	if(dijit && dijit._Widget){
+		//	Add a new property to widget
+		dojo.extend(dijit._Widget, {
+			// dndType: String
+			//		Defines a type of widget.
+			dndType : "text"
+		});
 	}
-	return dojox.mdnd._areaManager;	// Object
-};
+	
+	dojox.mdnd._areaManager = null;
+	dojox.mdnd.areaManager = function(){
+		// summary:
+		//		Returns the current areaManager, creates one if it is not created yet.
+		if(!dojox.mdnd._areaManager){
+			dojox.mdnd._areaManager = new dojox.mdnd.AreaManager();
+		}
+		return dojox.mdnd._areaManager;	// Object
+	};
+	return am;
+});
\ No newline at end of file
diff --git a/dojox/mdnd/AutoScroll.js b/dojox/mdnd/AutoScroll.js
index 3647ac8..7efd7a0 100644
--- a/dojox/mdnd/AutoScroll.js
+++ b/dojox/mdnd/AutoScroll.js
@@ -1,195 +1,196 @@
-dojo.provide("dojox.mdnd.AutoScroll");
-
-dojo.declare(
-	"dojox.mdnd.AutoScroll",
-	null,
-{
-	// summary:
-	//		Activate scrolling while dragging a widget.
-
-	// interval: Integer
-	//		default mouse move offset
-	interval: 3,
-
-	// recursiveTimer: Integer
-	recursiveTimer: 10,
-
-	// marginMouse: Integer
-	//		Default mouse margin
-	marginMouse: 50,
-
-	constructor: function(){
-		//console.log("dojox.mdnd.AutoScroll ::: constructor ");
-		this.resizeHandler = dojo.connect(dojo.global,"onresize", this, function(){
-			this.getViewport();
-		});
-		dojo.ready(dojo.hitch(this, "init"));
-	},
-
-	init: function(){
-		//console.log("dojox.mdnd.AutoScroll ::: init ");
-		this._html = (dojo.isWebKit) ? dojo.body() : dojo.body().parentNode;
-		this.getViewport();
-	},
-
-	getViewport:function(){
-		// summary:
-		//		Set the visible part of the window. Varies accordion to Navigator.
-
-		//console.log("dojox.mdnd.AutoScroll ::: getViewport ");
-		var d = dojo.doc, dd = d.documentElement, w = window, b = dojo.body();
-		if(dojo.isMozilla){
-			this._v = { 'w': dd.clientWidth, 'h': w.innerHeight };	// Object
-		}
-		else if(!dojo.isOpera && w.innerWidth){
-			this._v = { 'w': w.innerWidth, 'h': w.innerHeight };		// Object
-		}
-		else if(!dojo.isOpera && dd && dd.clientWidth){
-			this._v = { 'w': dd.clientWidth, 'h': dd.clientHeight };	// Object
-		}
-		else if(b.clientWidth){
-			this._v = { 'w': b.clientWidth, 'h': b.clientHeight };	// Object
-		}
-	},
-
-	setAutoScrollNode: function(/*Node*/node){
-		// summary:
-		//		set the node which is dragged
-		// node:
-		//		node to scroll
-
-		//console.log("dojox.mdnd.AutoScroll ::: setAutoScrollNode ");
-		this._node = node;
-	},
-
-	setAutoScrollMaxPage: function(){
-		// summary:
-		//		Set the hightest heigh and width authorized scroll.
-
-		//console.log("dojox.mdnd.AutoScroll ::: setAutoScrollMaxPage ");
-		this._yMax = this._html.scrollHeight;
-		this._xMax = this._html.scrollWidth;
-	},
-
-	checkAutoScroll: function(/*Event*/e){
+define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/lang","dojo/_base/connect",
+	"dojo/_base/window"],function(dojo){
+	var as = dojo.declare(
+		"dojox.mdnd.AutoScroll",
+		null,
+	{
 		// summary:
-		//		Check if an autoScroll have to be launched.
-
-		//console.log("dojox.mdnd.AutoScroll ::: checkAutoScroll");
-		if(this._autoScrollActive){
-			this.stopAutoScroll();
-		}
-		this._y = e.pageY;
-		this._x = e.pageX;
-		if(e.clientX < this.marginMouse){
-			this._autoScrollActive = true;
-			this._autoScrollLeft(e);
-		}
-		else if(e.clientX > this._v.w - this.marginMouse){
-			this._autoScrollActive = true;
-			this._autoScrollRight(e);
-		}
-		if(e.clientY < this.marginMouse){
-			this._autoScrollActive = true;
-			this._autoScrollUp(e);
+		//		Activate scrolling while dragging a widget.
+	
+		// interval: Integer
+		//		default mouse move offset
+		interval: 3,
+	
+		// recursiveTimer: Integer
+		recursiveTimer: 10,
+	
+		// marginMouse: Integer
+		//		Default mouse margin
+		marginMouse: 50,
+	
+		constructor: function(){
+			//console.log("dojox.mdnd.AutoScroll ::: constructor ");
+			this.resizeHandler = dojo.connect(dojo.global,"onresize", this, function(){
+				this.getViewport();
+			});
+			dojo.ready(dojo.hitch(this, "init"));
+		},
+	
+		init: function(){
+			//console.log("dojox.mdnd.AutoScroll ::: init ");
+			this._html = (dojo.isWebKit) ? dojo.body() : dojo.body().parentNode;
+			this.getViewport();
+		},
+	
+		getViewport:function(){
+			// summary:
+			//		Set the visible part of the window. Varies accordion to Navigator.
+	
+			//console.log("dojox.mdnd.AutoScroll ::: getViewport ");
+			var d = dojo.doc, dd = d.documentElement, w = window, b = dojo.body();
+			if(dojo.isMozilla){
+				this._v = { 'w': dd.clientWidth, 'h': w.innerHeight };	// Object
+			}
+			else if(!dojo.isOpera && w.innerWidth){
+				this._v = { 'w': w.innerWidth, 'h': w.innerHeight };		// Object
+			}
+			else if(!dojo.isOpera && dd && dd.clientWidth){
+				this._v = { 'w': dd.clientWidth, 'h': dd.clientHeight };	// Object
+			}
+			else if(b.clientWidth){
+				this._v = { 'w': b.clientWidth, 'h': b.clientHeight };	// Object
+			}
+		},
+	
+		setAutoScrollNode: function(/*Node*/node){
+			// summary:
+			//		set the node which is dragged
+			// node:
+			//		node to scroll
+	
+			//console.log("dojox.mdnd.AutoScroll ::: setAutoScrollNode ");
+			this._node = node;
+		},
+	
+		setAutoScrollMaxPage: function(){
+			// summary:
+			//		Set the hightest heigh and width authorized scroll.
+	
+			//console.log("dojox.mdnd.AutoScroll ::: setAutoScrollMaxPage ");
+			this._yMax = this._html.scrollHeight;
+			this._xMax = this._html.scrollWidth;
+		},
+	
+		checkAutoScroll: function(/*Event*/e){
+			// summary:
+			//		Check if an autoScroll have to be launched.
+	
+			//console.log("dojox.mdnd.AutoScroll ::: checkAutoScroll");
+			if(this._autoScrollActive){
+				this.stopAutoScroll();
+			}
+			this._y = e.pageY;
+			this._x = e.pageX;
+			if(e.clientX < this.marginMouse){
+				this._autoScrollActive = true;
+				this._autoScrollLeft(e);
+			}
+			else if(e.clientX > this._v.w - this.marginMouse){
+				this._autoScrollActive = true;
+				this._autoScrollRight(e);
+			}
+			if(e.clientY < this.marginMouse){
+				this._autoScrollActive = true;
+				this._autoScrollUp(e);
+				
+			}
+			else if(e.clientY > this._v.h - this.marginMouse){
+				this._autoScrollActive = true;
+				this._autoScrollDown();
+			}
+		},
+	
+		_autoScrollDown: function(){
+			// summary:
+			//		Manage the down autoscroll.
+			// tags:
+			//		protected
+	
+			//console.log("dojox.mdnd.AutoScroll ::: _autoScrollDown ");
+			if(this._timer){
+				clearTimeout(this._timer);
+			}
+			if(this._autoScrollActive && this._y + this.marginMouse < this._yMax){
+				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);
+			}
+		},
+	
+		_autoScrollUp: function(){
+			// summary:
+			//		Manage the up autoscroll.
+			// tags:
+			//		protected
+	
+			//console.log("dojox.mdnd.AutoScroll ::: _autoScrollUp ");
+			if(this._timer){
+				clearTimeout(this._timer);
+			}
+			if(this._autoScrollActive && this._y - this.marginMouse > 0){
+				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);
+			}
+		},
+	
+		_autoScrollRight: function(){
+			// summary:
+			//		Manage the right autoscroll.
+			// tags:
+			//		protected
+	
+			//console.log("dojox.mdnd.AutoScroll ::: _autoScrollRight ");
+			if(this._timer){
+				clearTimeout(this._timer);
+			}
+			if(this._autoScrollActive && this._x + this.marginMouse < this._xMax){
+				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);
+			}
+		},
+	
+		_autoScrollLeft: function(/*Event*/e){
+			// summary:
+			//		Manage the left autoscroll.
+			// tags:
+			//		protected
+	
+			//console.log("dojox.mdnd.AutoScroll ::: _autoScrollLeft ");
+			if(this._timer){
+				clearTimeout(this._timer);
+			}
+			if(this._autoScrollActive && this._x - this.marginMouse > 0){
+				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);
+			}
+		},
+	
+		stopAutoScroll: function(){
+			// summary:
+			//		Stop the autoscroll.
 			
-		}
-		else if(e.clientY > this._v.h - this.marginMouse){
-			this._autoScrollActive = true;
-			this._autoScrollDown();
-		}
-	},
-
-	_autoScrollDown: function(){
-		// summary:
-		//		Manage the down autoscroll.
-		// tags:
-		//		protected
-
-		//console.log("dojox.mdnd.AutoScroll ::: _autoScrollDown ");
-		if(this._timer){
-			clearTimeout(this._timer);
-		}
-		if(this._autoScrollActive && this._y + this.marginMouse < this._yMax){
-			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);
-		}
-	},
-
-	_autoScrollUp: function(){
-		// summary:
-		//		Manage the up autoscroll.
-		// tags:
-		//		protected
-
-		//console.log("dojox.mdnd.AutoScroll ::: _autoScrollUp ");
-		if(this._timer){
-			clearTimeout(this._timer);
-		}
-		if(this._autoScrollActive && this._y - this.marginMouse > 0){
-			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);
-		}
-	},
-
-	_autoScrollRight: function(){
-		// summary:
-		//		Manage the right autoscroll.
-		// tags:
-		//		protected
-
-		//console.log("dojox.mdnd.AutoScroll ::: _autoScrollRight ");
-		if(this._timer){
-			clearTimeout(this._timer);
-		}
-		if(this._autoScrollActive && this._x + this.marginMouse < this._xMax){
-			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);
-		}
-	},
-
-	_autoScrollLeft: function(/*Event*/e){
-		// summary:
-		//		Manage the left autoscroll.
-		// tags:
-		//		protected
-
-		//console.log("dojox.mdnd.AutoScroll ::: _autoScrollLeft ");
-		if(this._timer){
-			clearTimeout(this._timer);
-		}
-		if(this._autoScrollActive && this._x - this.marginMouse > 0){
-			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);
-		}
-	},
-
-	stopAutoScroll: function(){
-		// summary:
-		//		Stop the autoscroll.
-		
-		//console.log("dojox.mdnd.AutoScroll ::: stopAutoScroll ");
-		if(this._timer){
-			clearTimeout(this._timer);
-		}
-		this._autoScrollActive = false;
-	},
-
-	destroy: function(){
-		//console.log("dojox.mdnd.AutoScroll ::: destroy ");
-		dojo.disconnect(this.resizeHandler);
-	}
-});
-
-dojox.mdnd.autoScroll = null;
-(function(){
+			//console.log("dojox.mdnd.AutoScroll ::: stopAutoScroll ");
+			if(this._timer){
+				clearTimeout(this._timer);
+			}
+			this._autoScrollActive = false;
+		},
+	
+		destroy: function(){
+			//console.log("dojox.mdnd.AutoScroll ::: destroy ");
+			dojo.disconnect(this.resizeHandler);
+		}
+	});
+	
+	dojox.mdnd.autoScroll = null;
+	
 	dojox.mdnd.autoScroll = new dojox.mdnd.AutoScroll();
-}());
+	return as;
+});
diff --git a/dojox/mdnd/DropIndicator.js b/dojox/mdnd/DropIndicator.js
index c212e6b..437f415 100644
--- a/dojox/mdnd/DropIndicator.js
+++ b/dojox/mdnd/DropIndicator.js
@@ -1,86 +1,84 @@
-dojo.provide("dojox.mdnd.DropIndicator");
-
-dojo.require("dojox.mdnd.AreaManager");
-
-dojo.declare(
-	"dojox.mdnd.DropIndicator",
-	null,
-{
-	// summary:
-	//		DropIndicator managment for DnD.
-
-	// node: DOMNode
-	//		the drop indicator node
-	node : null,
+define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","./AreaManager"],function(dojo){
+	var di = dojo.declare(
+		"dojox.mdnd.DropIndicator",
+		null,
+	{
+		// summary:
+		//		DropIndicator managment for DnD.
+	
+		// node: DOMNode
+		//		the drop indicator node
+		node : null,
+			
+		constructor: function(){
+			//console.log("dojox.mdnd.DropIndicator ::: constructor");
+			var dropIndicator = document.createElement("div");
+			var subDropIndicator = document.createElement("div");
+			dropIndicator.appendChild(subDropIndicator);
+			dojo.addClass(dropIndicator, "dropIndicator");
+			this.node = dropIndicator;
+		},
 		
-	constructor: function(){
-		//console.log("dojox.mdnd.DropIndicator ::: constructor");
-		var dropIndicator = document.createElement("div");
-		var subDropIndicator = document.createElement("div");
-		dropIndicator.appendChild(subDropIndicator);
-		dojo.addClass(dropIndicator, "dropIndicator");
-		this.node = dropIndicator;
-	},
+		place: function(/*Node*/area, /*Node*/nodeRef, /*Object*/size){
+			// summary:
+			//		Place the DropIndicator in the right place
+			// area:
+			//		the dnd targer area node
+			// nodeRef:
+			//		node where the dropIndicator have to be placed into the area
+			// dragNode:
+			//		the node which is dragged
+			// returns:
+			//		the node inserted or null if it crashes
 	
-	place: function(/*Node*/area, /*Node*/nodeRef, /*Object*/size){
-		// summary:
-		//		Place the DropIndicator in the right place
-		// area:
-		//		the dnd targer area node
-		// nodeRef:
-		//		node where the dropIndicator have to be placed into the area
-		// dragNode:
-		//		the node which is dragged
-		// returns:
-		//		the node inserted or null if it crashes
-
-		//console.log("dojox.mdnd.DropIndicator ::: place");
-		if(size){
-			this.node.style.height = size.h + "px";
-		}
-		try{
-			if(nodeRef){
-				area.insertBefore(this.node, nodeRef);
+			//console.log("dojox.mdnd.DropIndicator ::: place");
+			if(size){
+				this.node.style.height = size.h + "px";
 			}
-			else{
-				// empty target area or last node => appendChild
-				area.appendChild(this.node);
+			try{
+				if(nodeRef){
+					area.insertBefore(this.node, nodeRef);
+				}
+				else{
+					// empty target area or last node => appendChild
+					area.appendChild(this.node);
+				}
+				return this.node;	// DOMNode
+			}catch(e){
+				return null;
 			}
-			return this.node;	// DOMNode
-		}catch(e){
-			return null;
-		}
-	},
+		},
+		
+		remove: function(){
+			// summary:
+			//		remove the DropIndicator (not destroy)
 	
-	remove: function(){
-		// summary:
-		//		remove the DropIndicator (not destroy)
-
-		//console.log("dojox.mdnd.DropIndicator ::: remove");
-		if(this.node){
-			//FIX : IE6 problem
-			this.node.style.height = "";
-			if(this.node.parentNode){
-				this.node.parentNode.removeChild(this.node);
+			//console.log("dojox.mdnd.DropIndicator ::: remove");
+			if(this.node){
+				//FIX : IE6 problem
+				this.node.style.height = "";
+				if(this.node.parentNode){
+					this.node.parentNode.removeChild(this.node);
+				}
 			}
-		}
-	},
-	 
-	destroy: function(){
-		// summary:
-		//		destroy the dropIndicator
-
-		//console.log("dojox.mdnd.DropIndicator ::: destroy");
-		if(this.node){
-			if(this.node.parentNode){
-				this.node.parentNode.removeChild(this.node);
+		},
+		 
+		destroy: function(){
+			// summary:
+			//		destroy the dropIndicator
+	
+			//console.log("dojox.mdnd.DropIndicator ::: destroy");
+			if(this.node){
+				if(this.node.parentNode){
+					this.node.parentNode.removeChild(this.node);
+				}
+				dojo._destroyElement(this.node);
+				delete this.node;
 			}
-			dojo._destroyElement(this.node);
-			delete this.node;
 		}
-	}
-});
+	});
 
-(function(){
 	dojox.mdnd.areaManager()._dropIndicator = new dojox.mdnd.DropIndicator();
-}());
+	
+	return di;
+});
diff --git a/dojox/mdnd/LazyManager.js b/dojox/mdnd/LazyManager.js
index 3f24f1f..aaf2654 100644
--- a/dojox/mdnd/LazyManager.js
+++ b/dojox/mdnd/LazyManager.js
@@ -1,68 +1,72 @@
-dojo.provide("dojox.mdnd.LazyManager");
-
-dojo.require("dojo.dnd.Manager");
-dojo.require("dojox.mdnd.PureSource");
-
-dojo.declare(
-	"dojox.mdnd.LazyManager",
-	null,
-{
-	// summary:
-	//		This class allows to launch a drag and drop dojo on the fly.
-	
-	constructor: function(){
-		//console.log("dojox.mdnd.LazyManager ::: constructor");
-		this._registry = {};
-		// initialization of the _fakeSource to enabled DragAndDrop :
-		this._fakeSource = new dojox.mdnd.PureSource(dojo.create("div"), {
-			'copyOnly': false
-		});
-		this._fakeSource.startup();
-		dojo.addOnUnload(dojo.hitch(this, "destroy"));
-		this.manager = dojo.dnd.manager();
-	},
-	
-	getItem: function(/*DOMNode*/draggedNode){
-		//console.log("dojox.mdnd.LazyManager ::: getItem");
-		var type = draggedNode.getAttribute("dndType");
-		return {
-			'data' : draggedNode.getAttribute("dndData") || draggedNode.innerHTML,
-			'type' : type ? type.split(/\s*,\s*/) : ["text"]
-		}
-	},
-	
-	startDrag: function(/*Event*/e, /*DOMNode?*/draggedNode){
+define([
+	"dojo/_base/kernel",	// dojo.addOnUnload
+	"dojo/_base/lang",	// dojo.hitch
+	"dojo/_base/declare",
+	"dojo/_base/html",	// dojo.create, dojo.attr, dojo.addClass
+	"dojo/dnd/Manager",
+	"./PureSource"
+],function(dojo){
+	return dojo.declare(
+		"dojox.mdnd.LazyManager",
+		null,
+	{
 		// summary:
-		//		launch a dojo drag and drop on the fly.
-
-		//console.log("dojox.mdnd.LazyManager ::: startDrag");
-		draggedNode = draggedNode || e.target;
-		if(draggedNode){
-			var m = this.manager,
-				object = this.getItem(draggedNode);
-			if(draggedNode.id == ""){
-				dojo.attr(draggedNode, "id", dojo.dnd.getUniqueId());
+		//		This class allows to launch a drag and drop dojo on the fly.
+		
+		constructor: function(){
+			//console.log("dojox.mdnd.LazyManager ::: constructor");
+			this._registry = {};
+			// initialization of the _fakeSource to enabled DragAndDrop :
+			this._fakeSource = new dojox.mdnd.PureSource(dojo.create("div"), {
+				'copyOnly': false
+			});
+			this._fakeSource.startup();
+			dojo.addOnUnload(dojo.hitch(this, "destroy"));
+			this.manager = dojo.dnd.manager();
+		},
+		
+		getItem: function(/*DOMNode*/draggedNode){
+			//console.log("dojox.mdnd.LazyManager ::: getItem");
+			var type = draggedNode.getAttribute("dndType");
+			return {
+				'data' : draggedNode.getAttribute("dndData") || draggedNode.innerHTML,
+				'type' : type ? type.split(/\s*,\s*/) : ["text"]
 			}
-			dojo.addClass(draggedNode, "dojoDndItem");
-			this._fakeSource.setItem(draggedNode.id, object);
-			m.startDrag(this._fakeSource, [draggedNode], false);
-			m.onMouseMove(e);
-		}
-	},
-	
-	cancelDrag: function(){
-		// summary:
-		//		cancel a drag and drop dojo on the fly.
-
-		//console.log("dojox.mdnd.LazyManager ::: cancelDrag");
-		var m = this.manager;
-		m.target = null;
-		m.onMouseUp();
-	},
+		},
+		
+		startDrag: function(/*Event*/e, /*DOMNode?*/draggedNode){
+			// summary:
+			//		launch a dojo drag and drop on the fly.
 	
+			//console.log("dojox.mdnd.LazyManager ::: startDrag");
+			draggedNode = draggedNode || e.target;
+			if(draggedNode){
+				var m = this.manager,
+					object = this.getItem(draggedNode);
+				if(draggedNode.id == ""){
+					dojo.attr(draggedNode, "id", dojo.dnd.getUniqueId());
+				}
+				dojo.addClass(draggedNode, "dojoDndItem");
+				this._fakeSource.setItem(draggedNode.id, object);
+				m.startDrag(this._fakeSource, [draggedNode], false);
+				m.onMouseMove(e);
+			}
+		},
+		
+		cancelDrag: function(){
+			// summary:
+			//		cancel a drag and drop dojo on the fly.
 	
-	destroy: function(){
-		//console.log("dojox.mdnd.LazyManager ::: destroy");
-		this._fakeSource.destroy();
-	}
+			//console.log("dojox.mdnd.LazyManager ::: cancelDrag");
+			var m = this.manager;
+			m.target = null;
+			m.onMouseUp();
+		},
+		
+		
+		destroy: function(){
+			//console.log("dojox.mdnd.LazyManager ::: destroy");
+			this._fakeSource.destroy();
+		}
+	});
 });
diff --git a/dojox/mdnd/Moveable.js b/dojox/mdnd/Moveable.js
index dee5ce6..2669206 100644
--- a/dojox/mdnd/Moveable.js
+++ b/dojox/mdnd/Moveable.js
@@ -1,253 +1,262 @@
-dojo.provide("dojox.mdnd.Moveable");
-
-dojo.declare(
-	"dojox.mdnd.Moveable",
-	null,
-{
-	// summary:
-	//		Allow end-users to track a DOM node into the web page
-
-	// handle: DOMNode
-	//		The node on which the user clicks to drag the main node.
-	handle: null,
-	
-	// skip: Boolean
-	// 		A flag to control a drag action if a form element has been focused.
-	//		If true, the drag action is not executed.
-	skip: true,
-
-	// dragDistance: Integer
-	//		The user clicks on the handle, but the drag action will really begin
-	//		if he tracks the main node to more than 3 pixels.
-	dragDistance: 3,
-	
-	constructor: function(/*Object*/params, /*DOMNode*/node){
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/_base/event",
+	"dojo/_base/html",
+	"dojo/_base/sniff",
+	"dojo/_base/window"
+],function(dojo){
+	return dojo.declare(
+		"dojox.mdnd.Moveable",
+		null,
+	{
 		// summary:
-		// 		Configure parameters and listen to mousedown events from handle
-		//		node.
-		// params:
-		//		Hash of parameters
-		// node:
-		//		The draggable node
-
-		//console.log("dojox.mdnd.Moveable ::: constructor");
-		this.node = dojo.byId(node);
-		
-		this.d = this.node.ownerDocument;
+		//		Allow end-users to track a DOM node into the web page
+	
+		// handle: DOMNode
+		//		The node on which the user clicks to drag the main node.
+		handle: null,
 		
-		if(!params){ params = {}; }
-		this.handle = params.handle ? dojo.byId(params.handle) : null;
-		if(!this.handle){ this.handle = this.node; }
-		this.skip = params.skip;
-		this.events = [
-			dojo.connect(this.handle, "onmousedown", this, "onMouseDown")
-		];
-		if(dojox.mdnd.autoScroll){
-			this.autoScroll = dojox.mdnd.autoScroll;
-		}
+		// skip: Boolean
+		// 		A flag to control a drag action if a form element has been focused.
+		//		If true, the drag action is not executed.
+		skip: true,
+	
+		// dragDistance: Integer
+		//		The user clicks on the handle, but the drag action will really begin
+		//		if he tracks the main node to more than 3 pixels.
+		dragDistance: 3,
 		
-	},
+		constructor: function(/*Object*/params, /*DOMNode*/node){
+			// summary:
+			// 		Configure parameters and listen to mousedown events from handle
+			//		node.
+			// params:
+			//		Hash of parameters
+			// node:
+			//		The draggable node
 	
-	isFormElement: function(/*DOMEvent*/ e){
-		// summary:
-		//		identify the type of target node associated with a DOM event.
-		// e:
-		//		a DOM event
-		// returns:
-		//		if true, the target is one of those specific nodes.
-
-		//console.log("dojox.mdnd.Moveable ::: isFormElement");
-		var t = e.target;
-		if(t.nodeType == 3 /*TEXT_NODE*/){
-			t = t.parentNode;
-		}
-		return " a button textarea input select option ".indexOf(" " + t.tagName.toLowerCase() + " ") >= 0;	// Boolean
-	},
+			//console.log("dojox.mdnd.Moveable ::: constructor");
+			this.node = dojo.byId(node);
+			
+			this.d = this.node.ownerDocument;
+			
+			if(!params){ params = {}; }
+			this.handle = params.handle ? dojo.byId(params.handle) : null;
+			if(!this.handle){ this.handle = this.node; }
+			this.skip = params.skip;
+			this.events = [
+				dojo.connect(this.handle, "onmousedown", this, "onMouseDown")
+			];
+			if(dojox.mdnd.autoScroll){
+				this.autoScroll = dojox.mdnd.autoScroll;
+			}
+			
+		},
+		
+		isFormElement: function(/*DOMEvent*/ e){
+			// summary:
+			//		identify the type of target node associated with a DOM event.
+			// e:
+			//		a DOM event
+			// returns:
+			//		if true, the target is one of those specific nodes.
 	
-	onMouseDown: function(/*DOMEvent*/e){
-		// summary:
-		//		Occurs when the user clicks on the handle node.
-		//		Skip the drag action if a specific node is targeted.
-		//		Listens to mouseup and mousemove events on to the HTML document.
-		// e:
-		//		a DOM event
-		// tags:
-		//		callback
-
-		//console.log("dojox.mdnd.Moveable ::: onMouseDown");
-		if(this._isDragging){ return;}
-		var isLeftButton = dojo.isIE ? (e.button == 1) : (e.which == 1);
-		if(!isLeftButton){
-			return;
-		}
-		if(this.skip && this.isFormElement(e)){ return; }
-		if(this.autoScroll){
-			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._firstX = e.clientX;
-		this._firstY = e.clientY;
-		dojo.stopEvent(e);
-	},
+			//console.log("dojox.mdnd.Moveable ::: isFormElement");
+			var t = e.target;
+			if(t.nodeType == 3 /*TEXT_NODE*/){
+				t = t.parentNode;
+			}
+			return " a button textarea input select option ".indexOf(" " + t.tagName.toLowerCase() + " ") >= 0;	// Boolean
+		},
+		
+		onMouseDown: function(/*DOMEvent*/e){
+			// summary:
+			//		Occurs when the user clicks on the handle node.
+			//		Skip the drag action if a specific node is targeted.
+			//		Listens to mouseup and mousemove events on to the HTML document.
+			// e:
+			//		a DOM event
+			// tags:
+			//		callback
 	
-	onFirstMove: function(/*DOMEvent*/e){
-		// summary:
-		//		Occurs when the user moves the mouse after clicking on the
-		//		handle.
-		//		Determinate when the drag action will have to begin (see
-		//		dragDistance).
-		// e:
-		//		A DOM event
-		// tags:
-		//		callback
-
-		//console.log("dojox.mdnd.Moveable ::: onFirstMove");
-		dojo.stopEvent(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");
-			this.initOffsetDrag(e);
-			this.events.push(dojo.connect(this.d, "onmousemove", this, "onMove"));
-		}
-	},
+			//console.log("dojox.mdnd.Moveable ::: onMouseDown");
+			if(this._isDragging){ return;}
+			var isLeftButton = (e.which || e.button) == 1;
+			if(!isLeftButton){
+				return;
+			}
+			if(this.skip && this.isFormElement(e)){ return; }
+			if(this.autoScroll){
+				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._firstX = e.clientX;
+			this._firstY = e.clientY;
+			dojo.stopEvent(e);
+		},
+		
+		onFirstMove: function(/*DOMEvent*/e){
+			// summary:
+			//		Occurs when the user moves the mouse after clicking on the
+			//		handle.
+			//		Determinate when the drag action will have to begin (see
+			//		dragDistance).
+			// e:
+			//		A DOM event
+			// tags:
+			//		callback
 	
-	initOffsetDrag: function(/*DOMEvent*/e){
-		// summary:
-		//		Initialize the gap between main node coordinates and the clicked point.
-		//		Call the onDragStart method.
-		// e:
-		//		A DOM event
-
-		//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);
-		/*if(s.position == "relative" || s.position == ""){
-			s.position = "absolute"; // enforcing the absolute mode
-		}*/
-		this.offsetDrag.l = position.x - this.offsetDrag.l;
-		this.offsetDrag.t = position.y - this.offsetDrag.t;
-		var coords = {
-			'x': position.x,
-			'y': position.y
-		};
-		this.size = {
-			'w': position.w,
-			'h': position.h
-		};
-		// method to catch
-		this.onDragStart(this.node, coords, this.size);
-	},
+			//console.log("dojox.mdnd.Moveable ::: onFirstMove");
+			dojo.stopEvent(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");
+				this.initOffsetDrag(e);
+				this.events.push(dojo.connect(this.d, "onmousemove", this, "onMove"));
+			}
+		},
+		
+		initOffsetDrag: function(/*DOMEvent*/e){
+			// summary:
+			//		Initialize the gap between main node coordinates and the clicked point.
+			//		Call the onDragStart method.
+			// e:
+			//		A DOM event
 	
-	onMove: function(/*DOMEvent*/e){
-		// summary:
-		//		Occurs when the user moves the mouse.
-		//		Calls the onDrag method.
-		// e:
-		//		a DOM event
-		// tags:
-		//		callback
-
-		//console.log("dojox.mdnd.Moveable ::: onMove");
-		dojo.stopEvent(e);
-		// hack to avoid too many calls to onMove in IE8 causing sometimes slowness
-		if(dojo.isIE == 8 && new Date() - this.date < 20){
-			return;
-		}
-		if(this.autoScroll){
-			this.autoScroll.checkAutoScroll(e);
-		}
-		var coords = {
-			'x': this.offsetDrag.l + e.pageX,
-			'y': this.offsetDrag.t + e.pageY
-		};
-		var s = this.node.style;
-		s.left = coords.x + "px";
-		s.top = coords.y + "px";
+			//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);
+			/*if(s.position == "relative" || s.position == ""){
+				s.position = "absolute"; // enforcing the absolute mode
+			}*/
+			this.offsetDrag.l = position.x - this.offsetDrag.l;
+			this.offsetDrag.t = position.y - this.offsetDrag.t;
+			var coords = {
+				'x': position.x,
+				'y': position.y
+			};
+			this.size = {
+				'w': position.w,
+				'h': position.h
+			};
+			// method to catch
+			this.onDragStart(this.node, coords, this.size);
+		},
 		
-		// method to catch
-		this.onDrag(this.node, coords, this.size, {'x':e.pageX, 'y':e.pageY});
-		if(dojo.isIE == 8){
-			this.date = new Date();
-		}
-	},
+		onMove: function(/*DOMEvent*/e){
+			// summary:
+			//		Occurs when the user moves the mouse.
+			//		Calls the onDrag method.
+			// e:
+			//		a DOM event
+			// tags:
+			//		callback
 	
-	onMouseUp: function(/*DOMEvent*/e){
-		// summary:
-		//		Occurs when the user releases the mouse
-		//		Calls the onDragEnd method.
-		// e:
-		//		a DOM event
-
-		if (this._isDragging){
+			//console.log("dojox.mdnd.Moveable ::: onMove");
 			dojo.stopEvent(e);
-			this._isDragging = false;
+			// hack to avoid too many calls to onMove in IE8 causing sometimes slowness
+			if(dojo.isIE == 8 && new Date() - this.date < 20){
+				return;
+			}
 			if(this.autoScroll){
-				this.autoScroll.stopAutoScroll();
+				this.autoScroll.checkAutoScroll(e);
+			}
+			var coords = {
+				'x': this.offsetDrag.l + e.pageX,
+				'y': this.offsetDrag.t + e.pageY
+			};
+			var s = this.node.style;
+			s.left = coords.x + "px";
+			s.top = coords.y + "px";
+			
+			// method to catch
+			this.onDrag(this.node, coords, this.size, {'x':e.pageX, 'y':e.pageY});
+			if(dojo.isIE == 8){
+				this.date = new Date();
 			}
-			delete this.onMove;
-			this.onDragEnd(this.node);
-			this.node.focus();
- 		}
-		dojo.disconnect(this.events.pop());
-		dojo.disconnect(this.events.pop());
-	},
+		},
+		
+		onMouseUp: function(/*DOMEvent*/e){
+			// summary:
+			//		Occurs when the user releases the mouse
+			//		Calls the onDragEnd method.
+			// e:
+			//		a DOM event
 	
-	onDragStart: function(/*DOMNode*/node, /*Object*/coords, /*Object*/size){
-		// summary:
-		//		Stub function.
-		//		Notes : border box model
-		// node:
-		//		a DOM node
-		//	coords:
-		//		absolute position of the main node
-		// size:
-		//		an object encapsulating width an height values
-		// tags:
-		//		callback
-
-	},
+			if (this._isDragging){
+				dojo.stopEvent(e);
+				this._isDragging = false;
+				if(this.autoScroll){
+					this.autoScroll.stopAutoScroll();
+				}
+				delete this.onMove;
+				this.onDragEnd(this.node);
+				this.node.focus();
+			}
+			dojo.disconnect(this.events.pop());
+			dojo.disconnect(this.events.pop());
+		},
+		
+		onDragStart: function(/*DOMNode*/node, /*Object*/coords, /*Object*/size){
+			// summary:
+			//		Stub function.
+			//		Notes : border box model
+			// node:
+			//		a DOM node
+			//	coords:
+			//		absolute position of the main node
+			// size:
+			//		an object encapsulating width an height values
+			// tags:
+			//		callback
 	
-	onDragEnd: function(/*DOMNode*/node){
-		// summary:
-		//		Stub function
-		//		Notes : Coordinates don't contain margins
-		// node:
-		//		a DOM node
-		// tags:
-		//		callback
-
-	},
+		},
+		
+		onDragEnd: function(/*DOMNode*/node){
+			// summary:
+			//		Stub function
+			//		Notes : Coordinates don't contain margins
+			// node:
+			//		a DOM node
+			// tags:
+			//		callback
 	
-	onDrag: function(/*DOMNode*/node, /*Object*/coords, /*Object*/size, /*Object*/mousePosition){
-		// summary:
-		//		Stub function.
-		//		Notes : border box model for size value, margin box model for coordinates
-		// node:
-		//		a DOM node
-		// coords:
-		//		position of the main node (equals to css left/top properties)
-		// size:
-		//		an object encapsulating width and height values
-		// mousePosition:
-		//		coordiantes of mouse
-		// tags:
-		//		callback
-
-	},
-
-	destroy: function(){
-		// summary:
-		//		Delecte associated events
-
-		// console.log("dojox.mdnd.Moveable ::: destroy");
-		dojo.forEach(this.events, dojo.disconnect);
-		this.events = this.node = null;
-	}
+		},
+		
+		onDrag: function(/*DOMNode*/node, /*Object*/coords, /*Object*/size, /*Object*/mousePosition){
+			// summary:
+			//		Stub function.
+			//		Notes : border box model for size value, margin box model for coordinates
+			// node:
+			//		a DOM node
+			// coords:
+			//		position of the main node (equals to css left/top properties)
+			// size:
+			//		an object encapsulating width and height values
+			// mousePosition:
+			//		coordiantes of mouse
+			// tags:
+			//		callback
+	
+		},
+	
+		destroy: function(){
+			// summary:
+			//		Delecte associated events
+	
+			// console.log("dojox.mdnd.Moveable ::: destroy");
+			dojo.forEach(this.events, dojo.disconnect);
+			this.events = this.node = null;
+		}
+	});
 });
diff --git a/dojox/mdnd/PureSource.js b/dojox/mdnd/PureSource.js
index 01ce7ce..56feb5a 100644
--- a/dojox/mdnd/PureSource.js
+++ b/dojox/mdnd/PureSource.js
@@ -1,208 +1,206 @@
-dojo.provide("dojox.mdnd.PureSource");
-
-dojo.require("dojo.dnd.Selector");
-dojo.require("dojo.dnd.Manager");
-
-dojo.declare(
-	"dojox.mdnd.PureSource",
-	dojo.dnd.Selector,
-{
-	// summary:
-	//		A Source Object, which can be used only as a DnD source.
-	//		A Source can contained several dnd items.
-	//		A dnd item is not a source.
-	
-	horizontal: false,
-	copyOnly: true,
-	skipForm: false,
-	withHandles: false,
-	isSource: true,
-	targetState: "Disabled",
-	generateText: true,
-	
-	constructor: function(/*DOMNode|String*/node, /*dojo.dnd.__SourceArgs?*/params){
+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(
+		"dojox.mdnd.PureSource",
+		dojo.dnd.Selector,
+	{
 		// summary:
-		//		Initialize a new PureSource.
-		// 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.
-
-		//console.log('dojox.mdnd.PureSource ::: constructor');
-		dojo.mixin(this, dojo.mixin({}, params));
-		var type = this.accept;
+		//		A Source Object, which can be used only as a DnD source.
+		//		A Source can contained several dnd items.
+		//		A dnd item is not a source.
 		
-		// class-specific variables
-		this.isDragging = false;
-		this.mouseDown = false;
-
-		// states
-		this.sourceState = "";
-		dojo.addClass(this.node, "dojoDndSource");
-		if(this.horizontal){
-			dojo.addClass(this.node, "dojoDndHorizontal");
-		}
-		// set up events
-		this.topics = [
-			dojo.subscribe("/dnd/cancel", this, "onDndCancel"),
-			dojo.subscribe("/dnd/drop", this, "onDndCancel")
-		];
-	},
-	
-	onDndCancel: function(){
-		// summary:
-		//		Topic event processor for /dnd/cancel, called to cancel the Dnd
-		//		operation.
-		// tags:
-		//		callback
-
-		//console.log('dojox.mdnd.PureSource ::: onDndCancel');
-		this.isDragging = false;
-		this.mouseDown = false;
-		delete this.mouseButton;
-	},
-	
-	copyState: function(/*Boolean*/keyPressed){
-		// summary:
-		//		Returns true, if we need to copy items, false to move.
-		//		It is separated to be overwritten dynamically, if needed.
-		// keyPressed:
-		//		The "copy" was pressed.
-		// returns:
-		//		True, if we need to copy items, false to move.
-
-		//console.log('dojox.mdnd.PureSource ::: copyState');
-		return this.copyOnly || keyPressed;	// Boolean
-	},
-	
-	destroy: function(){
-		// summary:
-		//		Prepares the object to be garbage-collected.
-
-		//console.log('dojox.mdnd.PureSource ::: destroy');
-		dojox.mdnd.PureSource.superclass.destroy.call(this);
-		dojo.forEach(this.topics, dojo.unsubscribe);
-		this.targetAnchor = null;
-	},
-
-	markupFactory: function(/*Object*/params, /*DomNode*/node){
-		// summary:
-		//		Markup methods.
-		// params:
-		//		???
-		// node:
-		//		???
-		// returns:
-		//		New dojox.mdnd.PureSource instance.
-
-		//console.log('dojox.mdnd.PureSource ::: markupFactory');
-		params._skipStartup = true;
-		return new dojox.mdnd.PureSource(node, params);
-	},
-
-	onMouseMove: function(/*Event*/e){
-		// summary:
-		//		Event processor for onmousemove.
-		// e:
-		//		Mouse event.
-
-		//console.log('dojox.mdnd.PureSource ::: onMouseMove');
-		if(this.isDragging){
-			return;
-		}
-		dojox.mdnd.PureSource.superclass.onMouseMove.call(this, e);
-		var m = dojo.dnd.manager();
-		if(this.mouseDown && !this.isDragging && this.isSource){
-			var nodes = this.getSelectedNodes();
-			if(nodes.length){
-				m.startDrag(this, nodes, this.copyState(dojo.isCopyKey(e)));
-				this.isDragging = true;
-			}
-		}
+		horizontal: false,
+		copyOnly: true,
+		skipForm: false,
+		withHandles: false,
+		isSource: true,
+		targetState: "Disabled",
+		generateText: true,
 		
-	},
+		constructor: function(/*DOMNode|String*/node, /*dojo.dnd.__SourceArgs?*/params){
+			// summary:
+			//		Initialize a new PureSource.
+			// 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.
 	
-	onMouseDown: function(/*Event*/e){
-		// summary:
-		//		Event processor for onmousedown.
-		// e:
-		//		Mouse event.
-		// tags:
-		//		callback
-
-		//console.log('dojox.mdnd.PureSource ::: onMouseDown');
-		if(this._legalMouseDown(e) && (!this.skipForm || !dojo.dnd.isFormElement(e))){
-			this.mouseDown = true;
-			this.mouseButton = e.button;
-			dojox.mdnd.PureSource.superclass.onMouseDown.call(this, e);
-		}
-	},
+			//console.log('dojox.mdnd.PureSource ::: constructor');
+			dojo.mixin(this, dojo.mixin({}, params));
+			var type = this.accept;
+			
+			// class-specific variables
+			this.isDragging = false;
+			this.mouseDown = false;
 	
-	onMouseUp: function(/*Event*/e){
-		// summary:
-		//		Event processor for onmouseup.
-		// e:
-		//		Mouse event
-		// tags:
-		//		callback
-
-		//console.log('.dnd.PureSource ::: onMouseUp');
-		if(this.mouseDown){
+			// states
+			this.sourceState = "";
+			dojo.addClass(this.node, "dojoDndSource");
+			if(this.horizontal){
+				dojo.addClass(this.node, "dojoDndHorizontal");
+			}
+			// set up events
+			this.topics = [
+				dojo.subscribe("/dnd/cancel", this, "onDndCancel"),
+				dojo.subscribe("/dnd/drop", this, "onDndCancel")
+			];
+		},
+		
+		onDndCancel: function(){
+			// summary:
+			//		Topic event processor for /dnd/cancel, called to cancel the Dnd
+			//		operation.
+			// tags:
+			//		callback
+	
+			//console.log('dojox.mdnd.PureSource ::: onDndCancel');
+			this.isDragging = false;
 			this.mouseDown = false;
-			dojox.mdnd.PureSource.superclass.onMouseUp.call(this, e);
-		}
-	},
-
-	onOverEvent: function(){
-		// summary:
-		//		Called once, when mouse is over our container.
-		// tags:
-		//		callback
-
-		//console.log('dojox.mdnd.PureSource ::: onOverEvent');
-		dojox.mdnd.PureSource.superclass.onOverEvent.call(this);
-		dojo.dnd.manager().overSource(this);
-	},
-	
-	onOutEvent: function(){
-		// summary:
-		//		Called once, when mouse is out our container.
-		// tags:
-		//		callback
-
-		//console.log('dojox.mdnd.PureSource ::: onOutEvent');
-		dojox.mdnd.PureSource.superclass.onOutEvent.call(this);
-		dojo.dnd.manager().outSource(this);
-	},
-	
-	_markDndStatus: function(/*Boolean*/copy){
-		// summary:
-		//		Changes source's state based on "copy" status.
-		// copy:
-		//		Copy status.
-		// tags:
-		//		protected
-
-		//console.log('dojox.mdnd.PureSource ::: _markDndStatus');
-		this._changeState("Source", copy ? "Copied" : "Moved");
-	},
-
-	_legalMouseDown: function(/*Event*/e){
-		// summary:
-		//		Checks if user clicked on "approved" items.
-		// e:
-		//		Mouse event.
-		// returns:
-		//		True if user clicked on "approved" items.
-		// tags:
-		// 		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; }
+			delete this.mouseButton;
+		},
+		
+		copyState: function(/*Boolean*/keyPressed){
+			// summary:
+			//		Returns true, if we need to copy items, false to move.
+			//		It is separated to be overwritten dynamically, if needed.
+			// keyPressed:
+			//		The "copy" was pressed.
+			// returns:
+			//		True, if we need to copy items, false to move.
+	
+			//console.log('dojox.mdnd.PureSource ::: copyState');
+			return this.copyOnly || keyPressed;	// Boolean
+		},
+		
+		destroy: function(){
+			// summary:
+			//		Prepares the object to be garbage-collected.
+	
+			//console.log('dojox.mdnd.PureSource ::: destroy');
+			dojox.mdnd.PureSource.superclass.destroy.call(this);
+			dojo.forEach(this.topics, dojo.unsubscribe);
+			this.targetAnchor = null;
+		},
+	
+		markupFactory: function(/*Object*/params, /*DomNode*/node){
+			// summary:
+			//		Markup methods.
+			// params:
+			//		???
+			// node:
+			//		???
+			// returns:
+			//		New dojox.mdnd.PureSource instance.
+	
+			//console.log('dojox.mdnd.PureSource ::: markupFactory');
+			params._skipStartup = true;
+			return new dojox.mdnd.PureSource(node, params);
+		},
+	
+		onMouseMove: function(/*Event*/e){
+			// summary:
+			//		Event processor for onmousemove.
+			// e:
+			//		Mouse event.
+	
+			//console.log('dojox.mdnd.PureSource ::: onMouseMove');
+			if(this.isDragging){
+				return;
+			}
+			dojox.mdnd.PureSource.superclass.onMouseMove.call(this, e);
+			var m = dojo.dnd.manager();
+			if(this.mouseDown && !this.isDragging && this.isSource){
+				var nodes = this.getSelectedNodes();
+				if(nodes.length){
+					m.startDrag(this, nodes, this.copyState(dojo.isCopyKey(e)));
+					this.isDragging = true;
+				}
+			}
+			
+		},
+		
+		onMouseDown: function(/*Event*/e){
+			// summary:
+			//		Event processor for onmousedown.
+			// e:
+			//		Mouse event.
+			// tags:
+			//		callback
+	
+			//console.log('dojox.mdnd.PureSource ::: onMouseDown');
+			if(this._legalMouseDown(e) && (!this.skipForm || !dojo.dnd.isFormElement(e))){
+				this.mouseDown = true;
+				this.mouseButton = e.button;
+				dojox.mdnd.PureSource.superclass.onMouseDown.call(this, e);
+			}
+		},
+		
+		onMouseUp: function(/*Event*/e){
+			// summary:
+			//		Event processor for onmouseup.
+			// e:
+			//		Mouse event
+			// tags:
+			//		callback
+	
+			//console.log('.dnd.PureSource ::: onMouseUp');
+			if(this.mouseDown){
+				this.mouseDown = false;
+				dojox.mdnd.PureSource.superclass.onMouseUp.call(this, e);
+			}
+		},
+	
+		onOverEvent: function(){
+			// summary:
+			//		Called once, when mouse is over our container.
+			// tags:
+			//		callback
+	
+			//console.log('dojox.mdnd.PureSource ::: onOverEvent');
+			dojox.mdnd.PureSource.superclass.onOverEvent.call(this);
+			dojo.dnd.manager().overSource(this);
+		},
+		
+		onOutEvent: function(){
+			// summary:
+			//		Called once, when mouse is out our container.
+			// tags:
+			//		callback
+	
+			//console.log('dojox.mdnd.PureSource ::: onOutEvent');
+			dojox.mdnd.PureSource.superclass.onOutEvent.call(this);
+			dojo.dnd.manager().outSource(this);
+		},
+		
+		_markDndStatus: function(/*Boolean*/copy){
+			// summary:
+			//		Changes source's state based on "copy" status.
+			// copy:
+			//		Copy status.
+			// tags:
+			//		protected
+	
+			//console.log('dojox.mdnd.PureSource ::: _markDndStatus');
+			this._changeState("Source", copy ? "Copied" : "Moved");
+		},
+	
+		_legalMouseDown: function(/*Event*/e){
+			// summary:
+			//		Checks if user clicked on "approved" items.
+			// e:
+			//		Mouse event.
+			// returns:
+			//		True if user clicked on "approved" items.
+			// tags:
+			// 		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; }
+			}
+			return false;	// Boolean
 		}
-		return false;	// Boolean
-	}
-});
+	});
+});
\ No newline at end of file
diff --git a/dojox/mdnd/adapter/DndFromDojo.js b/dojox/mdnd/adapter/DndFromDojo.js
index a65420f..14dff87 100644
--- a/dojox/mdnd/adapter/DndFromDojo.js
+++ b/dojox/mdnd/adapter/DndFromDojo.js
@@ -1,366 +1,364 @@
-dojo.provide("dojox.mdnd.adapter.DndFromDojo");
-dojo.require("dojox.mdnd.AreaManager");
-dojo.require("dojo.dnd.Manager");
-
-dojo.declare(
-	"dojox.mdnd.adapter.DndFromDojo",
-	null,
-{
-	// summary
-	//		Allow communication between Dojo dnd items and DojoX D&D areas
-
-	// dropIndicatorSize: Object
-	//		size by default of dropIndicator (display only into a D&D Area)
-	dropIndicatorSize : {'w':0,'h':50},
-
-	// dropIndicatorSize: Object
-	//		size by default of dropIndicator (display only into a D&D Area)
-	dropIndicatorSize: {'w':0,'h':50},
-
-	// _areaManager: Object
-	//		Reference to the current DojoX Dnd Manager
-	_areaManager: null,
-
-	// _dojoManager
-	//		Reference to the current Dojo Manager
-	_dojoManager: null,
-
-	// _currentArea: Object
-	//		The current Area on mouse over
-	_currentArea: null,
-
-	// _oldArea: Object
-	//		The old area the mouse has passed over
-	_oldArea: null,
-
-	// _moveHandler: Object
-	//		The handler of mouse connection
-	_moveHandler: null,
-
-	// _subscribeHandler: Array
-	//		The list of dojo dnd topics
-	_subscribeHandler: null,
-
-	constructor: function(){
-		this._areaManager = dojox.mdnd.areaManager();
-		this._dojoManager = dojo.dnd.manager();
-		this._currentArea = null;
-		this._moveHandler = null;
-		this.subscribeDnd();
-	},
-
-	subscribeDnd: function(){
-		// summary:
-		//		Subscribe to somes topics of dojo drag and drop.
-
-		//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")
-		]
-	},
-
-	unsubscribeDnd: function(){
-		// summary:
-		//		Unsubscribe to some topics of dojo drag and drop.
-
-		//console.log(("dojox.mdnd.adapter.DndFromDojo ::: unsubscribeDnd");
-		dojo.forEach(this._subscribeHandler, dojo.unsubscribe);
-	},
-
-	_getHoverArea: function(/*Object*/ coords){
-		// summary:
-		//		Get a D&D dojoX area as a DOM node positioned under a specific point.
-		// coords:
-		//		Object containing the coordinates x and y (mouse position)
-		// tags:
-		//		protected
-
-		//console.log("dojox.mdnd.adapter.DndFromDojo ::: _getHoverArea");
-		var x = coords.x;
-		var y = coords.y;
-		this._oldArea = this._currentArea;
-		this._currentArea = null;
-		var areas = this._areaManager._areaList;
-		for(var i = 0; i < areas.length; i++){
-			var area = areas[i];
-			var startX = area.coords.x;
-			var endX = startX + area.node.offsetWidth;
-			var startY = area.coords.y;
-			var endY = startY + area.node.offsetHeight;
-			// check if the coordinates mouse is in a D&D Area
-			if(startX <= x && x <= endX && startY <= y && y <= endY){
-				this._areaManager._oldIndexArea = this._areaManager._currentIndexArea;
-				this._areaManager._currentIndexArea = i;
-				this._currentArea = area.node;
-				break;
-			}
-		}
-		if(this._currentArea != this._oldArea){
-			if(this._currentArea == null){
-				// case when the dragNode was in a D&D area but it's out now.
-				this.onDragExit();
-			}
-			else if(this._oldArea == null){
-				// case when the dragNode was out a D&D area but it's in now.
-				this.onDragEnter();
-			}
-			else{
-				// case when the dragNode was in a D&D area and enter in an other D&D area directly.
-				this.onDragExit();
-				this.onDragEnter();
+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(
+		"dojox.mdnd.adapter.DndFromDojo",
+		null,
+	{
+		// summary
+		//		Allow communication between Dojo dnd items and DojoX D&D areas
+	
+		// dropIndicatorSize: Object
+		//		size by default of dropIndicator (display only into a D&D Area)
+		dropIndicatorSize : {'w':0,'h':50},
+	
+		// dropIndicatorSize: Object
+		//		size by default of dropIndicator (display only into a D&D Area)
+		dropIndicatorSize: {'w':0,'h':50},
+	
+		// _areaManager: Object
+		//		Reference to the current DojoX Dnd Manager
+		_areaManager: null,
+	
+		// _dojoManager
+		//		Reference to the current Dojo Manager
+		_dojoManager: null,
+	
+		// _currentArea: Object
+		//		The current Area on mouse over
+		_currentArea: null,
+	
+		// _oldArea: Object
+		//		The old area the mouse has passed over
+		_oldArea: null,
+	
+		// _moveHandler: Object
+		//		The handler of mouse connection
+		_moveHandler: null,
+	
+		// _subscribeHandler: Array
+		//		The list of dojo dnd topics
+		_subscribeHandler: null,
+	
+		constructor: function(){
+			this._areaManager = dojox.mdnd.areaManager();
+			this._dojoManager = dojo.dnd.manager();
+			this._currentArea = null;
+			this._moveHandler = null;
+			this.subscribeDnd();
+		},
+	
+		subscribeDnd: function(){
+			// summary:
+			//		Subscribe to somes topics of dojo drag and drop.
+	
+			//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")
+			]
+		},
+	
+		unsubscribeDnd: function(){
+			// summary:
+			//		Unsubscribe to some topics of dojo drag and drop.
+	
+			//console.log(("dojox.mdnd.adapter.DndFromDojo ::: unsubscribeDnd");
+			dojo.forEach(this._subscribeHandler, dojo.unsubscribe);
+		},
+	
+		_getHoverArea: function(/*Object*/ coords){
+			// summary:
+			//		Get a D&D dojoX area as a DOM node positioned under a specific point.
+			// coords:
+			//		Object containing the coordinates x and y (mouse position)
+			// tags:
+			//		protected
+	
+			//console.log("dojox.mdnd.adapter.DndFromDojo ::: _getHoverArea");
+			var x = coords.x;
+			var y = coords.y;
+			this._oldArea = this._currentArea;
+			this._currentArea = null;
+			var areas = this._areaManager._areaList;
+			for(var i = 0; i < areas.length; i++){
+				var area = areas[i];
+				var startX = area.coords.x;
+				var endX = startX + area.node.offsetWidth;
+				var startY = area.coords.y;
+				var endY = startY + area.node.offsetHeight;
+				// check if the coordinates mouse is in a D&D Area
+				if(startX <= x && x <= endX && startY <= y && y <= endY){
+					this._areaManager._oldIndexArea = this._areaManager._currentIndexArea;
+					this._areaManager._currentIndexArea = i;
+					this._currentArea = area.node;
+					break;
+				}
 			}
-		}
-
-		//console.log("dojox.mdnd.adapter.DndFromDojo ::: _getHoverArea",this._dojoManager.avatar.node,this._currentArea,this._oldArea);
-	},
-
-	onDragStart: function(/*Object*/source, /*Array*/nodes, /*Boolean*/copy){
-		// summary:
-		//		Occurs when the "/dnd/start" topic is published.
-		// source:
-		//		the source which provides items
-		// nodes:
-		//		the list of transferred items
-		// copy:
-		//		copy items, if true, move items otherwise
-		// tags:
-		//		callback
-
-		//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDragStart");
-		// catch the dragNode to get the type when it's necessary.
-		this._dragNode = nodes[0];
-		this._copy = copy; this._source = source;
-		// 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(){
-			//dojo.disconnect(this._outSourceHandler);
-			if(this._moveHandler == null){
-				this._moveHandler = dojo.connect(dojo.doc, "mousemove", this, "onMouseMove");
+			if(this._currentArea != this._oldArea){
+				if(this._currentArea == null){
+					// case when the dragNode was in a D&D area but it's out now.
+					this.onDragExit();
+				}
+				else if(this._oldArea == null){
+					// case when the dragNode was out a D&D area but it's in now.
+					this.onDragEnter();
+				}
+				else{
+					// case when the dragNode was in a D&D area and enter in an other D&D area directly.
+					this.onDragExit();
+					this.onDragEnter();
+				}
 			}
-		});
-	},
-
-	onMouseMove: function(/*DOMEvent*/e){
-		// summary:
-		//		Occurs when the user moves the mouse.
-		// e:
-		//		the DOM event
-		// tags:
-		//		callback
-
-		//console.log("dojox.mdnd.adapter.DndFromDojo ::: onMouseMove");
-		// calculate the coordonates of the mouse.
-		var coords = {
-			'x': e.pageX,
-			'y': e.pageY
-		};
-		this._getHoverArea(coords);
-		// if a D&D area has been found and if it's accepted to drop this type of dragged node
-		if(this._currentArea && this._areaManager._accept){
-			// 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");
+	
+			//console.log("dojox.mdnd.adapter.DndFromDojo ::: _getHoverArea",this._dojoManager.avatar.node,this._currentArea,this._oldArea);
+		},
+	
+		onDragStart: function(/*Object*/source, /*Array*/nodes, /*Boolean*/copy){
+			// summary:
+			//		Occurs when the "/dnd/start" topic is published.
+			// source:
+			//		the source which provides items
+			// nodes:
+			//		the list of transferred items
+			// copy:
+			//		copy items, if true, move items otherwise
+			// tags:
+			//		callback
+	
+			//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDragStart");
+			// catch the dragNode to get the type when it's necessary.
+			this._dragNode = nodes[0];
+			this._copy = copy; this._source = source;
+			// 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(){
+				//dojo.disconnect(this._outSourceHandler);
+				if(this._moveHandler == null){
+					this._moveHandler = dojo.connect(dojo.doc, "mousemove", this, "onMouseMove");
+				}
+			});
+		},
+	
+		onMouseMove: function(/*DOMEvent*/e){
+			// summary:
+			//		Occurs when the user moves the mouse.
+			// e:
+			//		the DOM event
+			// tags:
+			//		callback
+	
+			//console.log("dojox.mdnd.adapter.DndFromDojo ::: onMouseMove");
+			// calculate the coordonates of the mouse.
+			var coords = {
+				'x': e.pageX,
+				'y': e.pageY
+			};
+			this._getHoverArea(coords);
+			// if a D&D area has been found and if it's accepted to drop this type of dragged node
+			if(this._currentArea && this._areaManager._accept){
+				// 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");
+				}
+				// place the dropIndicator in D&D Area with a default size.
+				this._areaManager.placeDropIndicator(coords, this.dropIndicatorSize);
 			}
-			// place the dropIndicator in D&D Area with a default size.
-			this._areaManager.placeDropIndicator(coords, this.dropIndicatorSize);
-		}
-	},
-
-	onDragEnter: function(){
-		// summary:
-		//		Occurs when the user drages an DOJO dnd item inside a D&D dojoX area.
-		// tags:
-		//		callback
-
-		//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDragEnter");
-		// Check if the type of dragged node is accepted in the selected D&D dojoX Area.
-		var _dndType = this._dragNode.getAttribute("dndType");
-		// need to have an array as type
-		var type = (_dndType) ? _dndType.split(/\s*,\s*/) : ["text"];
-		this._areaManager._isAccepted(type, this._areaManager._areaList[this._areaManager._currentIndexArea].accept);
-		// 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");
+		},
+	
+		onDragEnter: function(){
+			// summary:
+			//		Occurs when the user drages an DOJO dnd item inside a D&D dojoX area.
+			// tags:
+			//		callback
+	
+			//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDragEnter");
+			// Check if the type of dragged node is accepted in the selected D&D dojoX Area.
+			var _dndType = this._dragNode.getAttribute("dndType");
+			// need to have an array as type
+			var type = (_dndType) ? _dndType.split(/\s*,\s*/) : ["text"];
+			this._areaManager._isAccepted(type, this._areaManager._areaList[this._areaManager._currentIndexArea].accept);
+			// 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");
+				}
+				else{
+					dojo.removeClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
+				}
 			}
-			else{
+		},
+	
+		onDragExit: function(){
+			// summary:
+			//		Occurs when the user leaves a D&D dojoX area after dragging an DOJO dnd item over it.
+	
+			//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDragExit");
+			// if the dragged node exits of a D&D dojoX Area :
+			this._areaManager._accept = false;
+			// change color of avatar
+			if(this._dojoManager.avatar){
 				dojo.removeClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
 			}
-		}
-	},
-
-	onDragExit: function(){
-		// summary:
-		//		Occurs when the user leaves a D&D dojoX area after dragging an DOJO dnd item over it.
-
-		//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDragExit");
-		// if the dragged node exits of a D&D dojoX Area :
-		this._areaManager._accept = false;
-		// change color of avatar
-		if(this._dojoManager.avatar){
-			dojo.removeClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
-		}
-		// reset all variables and remove the dropIndicator.
-		if(this._currentArea == null){
-			this._areaManager._dropMode.refreshItems(this._areaManager._areaList[this._areaManager._oldIndexArea], this._areaManager._oldDropIndex, this.dropIndicatorSize, false);
-			this._areaManager._resetAfterDrop();
-		}
-		else{
-			this._areaManager._dropIndicator.remove();
-		}
-	},
-
-	isAccepted: function(/*Node*/node, /*Object*/accept){
-		// summary:
-		//		Check if a dragNode is accepted into a dojo target.
-		// node:
-		//		The dragged node.
-		// accept:
-		//		Object containing the type accepted for a target dojo.
-		// returns:
-		//		true if the dragged node is accepted in the target dojo.
-
-		//console.log("dojox.mdnd.adapter.DndFromDojo ::: isAccepted");
-		var type = (node.getAttribute("dndType")) ? node.getAttribute("dndType") : "text";
-		if(type && type in accept)
-			return true;	// Boolean
-		else
-			return false;	// Boolean
-	},
-
-	onDndSource: function(/*Object*/ source){
-		// summary:
-		//		Called when the mouse enters or exits of a source dojo.
-		// source:
-		//		the dojo source/target
-		// tags:
-		//		callback
-
-		//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDndSource",source);
-		// Only the case : "source dojo into a D&D dojoX Area" is treated.
-		if(this._currentArea == null){
-			return;
-		}
-		if(source){
-			// Enter in a source/target dojo.
-			// test if the type of draggedNode is accepted :
-			var accept = false;
-			if(this._dojoManager.target == source){
-				accept = true;
+			// reset all variables and remove the dropIndicator.
+			if(this._currentArea == null){
+				this._areaManager._dropMode.refreshItems(this._areaManager._areaList[this._areaManager._oldIndexArea], this._areaManager._oldDropIndex, this.dropIndicatorSize, false);
+				this._areaManager._resetAfterDrop();
 			}
 			else{
-				accept = this.isAccepted(this._dragNode, source.accept);
+				this._areaManager._dropIndicator.remove();
 			}
-			if(accept){
-				// disconnect the onMouseMove to disabled the search of a drop zone in the D&D dojoX Area.
-				dojo.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.
-				var dropIndicator = this._areaManager._dropIndicator.node;
-				if(dropIndicator && dropIndicator.parentNode !== null && dropIndicator.parentNode.nodeType == 1)
-					dropIndicator.style.visibility = "hidden";
+		},
+	
+		isAccepted: function(/*Node*/node, /*Object*/accept){
+			// summary:
+			//		Check if a dragNode is accepted into a dojo target.
+			// node:
+			//		The dragged node.
+			// accept:
+			//		Object containing the type accepted for a target dojo.
+			// returns:
+			//		true if the dragged node is accepted in the target dojo.
+	
+			//console.log("dojox.mdnd.adapter.DndFromDojo ::: isAccepted");
+			var type = (node.getAttribute("dndType")) ? node.getAttribute("dndType") : "text";
+			if(type && type in accept)
+				return true;	// Boolean
+			else
+				return false;	// Boolean
+		},
+	
+		onDndSource: function(/*Object*/ source){
+			// summary:
+			//		Called when the mouse enters or exits of a source dojo.
+			// source:
+			//		the dojo source/target
+			// tags:
+			//		callback
+	
+			//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDndSource",source);
+			// Only the case : "source dojo into a D&D dojoX Area" is treated.
+			if(this._currentArea == null){
+				return;
+			}
+			if(source){
+				// Enter in a source/target dojo.
+				// test if the type of draggedNode is accepted :
+				var accept = false;
+				if(this._dojoManager.target == source){
+					accept = true;
+				}
+				else{
+					accept = this.isAccepted(this._dragNode, source.accept);
+				}
+				if(accept){
+					// disconnect the onMouseMove to disabled the search of a drop zone in the D&D dojoX Area.
+					dojo.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.
+					var dropIndicator = this._areaManager._dropIndicator.node;
+					if(dropIndicator && dropIndicator.parentNode !== null && dropIndicator.parentNode.nodeType == 1)
+						dropIndicator.style.visibility = "hidden";
+				}
+				else{
+					// if the type of dragged node is not accepted in the target dojo, the color of avatar
+					// have to be the same that the color of D&D dojoX Area acceptance.
+					this._resetAvatar();
+				}
 			}
 			else{
-				// if the type of dragged node is not accepted in the target dojo, the color of avatar
-				// have to be the same that the color of D&D dojoX Area acceptance.
+				// 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._resetAvatar();
 			}
-		}
-		else{
-			// 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._resetAvatar();
-		}
-	},
-
-	_resetAvatar: function(){
-		// summary:
-		//		Function executed in onDndSource function to set the avatar
-		//		acceptance according to the dojox DnD AreaManager Acceptance.
-	 	//		It is used when The mouse exit a source/target dojo or if the
-		//		dragged node is not accepted in dojo source / target.
-		// tags:
-		//		protected
-
-		//console.log("dojox.mdnd.adapter.DndFromDojo ::: _resetAvatar");
-		if(this._dojoManager.avatar){
-			if(this._areaManager._accept){
-				dojo.addClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
+		},
+	
+		_resetAvatar: function(){
+			// summary:
+			//		Function executed in onDndSource function to set the avatar
+			//		acceptance according to the dojox DnD AreaManager Acceptance.
+			//		It is used when The mouse exit a source/target dojo or if the
+			//		dragged node is not accepted in dojo source / target.
+			// tags:
+			//		protected
+	
+			//console.log("dojox.mdnd.adapter.DndFromDojo ::: _resetAvatar");
+			if(this._dojoManager.avatar){
+				if(this._areaManager._accept){
+					dojo.addClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
+				}
+				else{
+					dojo.removeClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
+				}
+			}
+		},
+	
+		onDropCancel: function(){
+			// summary:
+			//		Occurs when the "/dnd/cancel" topic is published.
+			// tags:
+			//		callback
+	
+			//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDropCancel");
+			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);
+				this._currentArea = this._moveHandler = this._outSourceHandler = null;
 			}
 			else{
-				dojo.removeClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
+				// the dragged node is in the D&D dojox Area
+				//		(catch when dragged node exits of a source/target dojo and stays in the same D&D dojox Area)
+				// dojo cancel the drop but it's authorized in the D&D Area
+				if(this._areaManager._accept){
+					this.onDrop(this._source, [this._dragNode], this._copy, this._currentArea);
+				}
+				else{
+					this._currentArea = null;
+					dojo.disconnect(this._outSourceHandler);
+					dojo.disconnect(this._moveHandler);
+					this._moveHandler = this._outSourceHandler = null;
+				}
 			}
-		}
-	},
-
-	onDropCancel: function(){
-		// summary:
-		//		Occurs when the "/dnd/cancel" topic is published.
-		// tags:
-		//		callback
-
-		//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDropCancel");
-		if(this._currentArea == null){
-			// the dragged node is not in the D&D dojox Area => Cancel
-			this._areaManager._resetAfterDrop();
+		},
+	
+		onDrop: function(/*Object*/source, /*Array*/nodes, /*Boolean*/copy){
+			// summary:
+			//		Occurs when the user leaves a D&D dojox area after dragging an DOJO dnd item over it.
+			// source:
+			//		the source which provides items
+			// nodes:
+			//		the list of transferred items
+			// copy:
+			//		copy items, if true, move items otherwise
+			// tags:
+			//		callback
+	
+			//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDrop", this._currentArea);
 			dojo.disconnect(this._moveHandler);
 			dojo.disconnect(this._outSourceHandler);
-			this._currentArea = this._moveHandler = this._outSourceHandler = null;
-		}
-		else{
-			// the dragged node is in the D&D dojox Area
-			//		(catch when dragged node exits of a source/target dojo and stays in the same D&D dojox Area)
-			// dojo cancel the drop but it's authorized in the D&D Area
-			if(this._areaManager._accept){
-				this.onDrop(this._source, [this._dragNode], this._copy, this._currentArea);
-			}
-			else{
+			this._moveHandler = this._outSourceHandler = null;
+			if(this._currentArea){
+				var dropIndex = this._areaManager._currentDropIndex;
+				dojo.publish("/dnd/drop/after", [source, nodes, copy, this._currentArea, dropIndex]);
 				this._currentArea = null;
-				dojo.disconnect(this._outSourceHandler);
-				dojo.disconnect(this._moveHandler);
-				this._moveHandler = this._outSourceHandler = null;
 			}
+			if(this._areaManager._dropIndicator.node.style.visibility == "hidden"){
+				this._areaManager._dropIndicator.node.style.visibility = "";
+			}
+			this._areaManager._resetAfterDrop();
 		}
-	},
-
-	onDrop: function(/*Object*/source, /*Array*/nodes, /*Boolean*/copy){
-		// summary:
-		//		Occurs when the user leaves a D&D dojox area after dragging an DOJO dnd item over it.
-		// source:
-		//		the source which provides items
-		// nodes:
-		//		the list of transferred items
-		// copy:
-		//		copy items, if true, move items otherwise
-		// tags:
-		//		callback
-
-		//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDrop", this._currentArea);
-		dojo.disconnect(this._moveHandler);
-		dojo.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]);
-			this._currentArea = null;
-		}
-		if(this._areaManager._dropIndicator.node.style.visibility == "hidden"){
-			this._areaManager._dropIndicator.node.style.visibility = "";
-		}
-		this._areaManager._resetAfterDrop();
-	}
-});
-
-dojox.mdnd.adapter._dndFromDojo = null;
-(function(){
+	});
+	
+	dojox.mdnd.adapter._dndFromDojo = null;
 	dojox.mdnd.adapter._dndFromDojo = new dojox.mdnd.adapter.DndFromDojo();
-}());
+	return dfd; 
+});
diff --git a/dojox/mdnd/adapter/DndToDojo.js b/dojox/mdnd/adapter/DndToDojo.js
index e9d0d93..c93bf95 100644
--- a/dojox/mdnd/adapter/DndToDojo.js
+++ b/dojox/mdnd/adapter/DndToDojo.js
@@ -1,484 +1,483 @@
-dojo.provide("dojox.mdnd.adapter.DndToDojo");
-
-dojo.require("dojox.mdnd.PureSource");
-dojo.require("dojox.mdnd.LazyManager");
-
-dojo.declare(
-	"dojox.mdnd.adapter.DndToDojo",
-	null,
-{
-	// summary:
-	//		Allow communication between an item of dojox D&D area to a target dojo.
-
-	// _dojoList: Array
-	//		Array containing object references the dojo Target list
-	_dojoList: null,
-
-	// _currentDojoArea: DOMNode
-	//		Representing the current dojo area
-	_currentDojoArea: null,
-
-	// _dojoxManager: dojox.mdnd.AreaManager
-	//		The reference to the dojox AreaManager
-	_dojoxManager: null,
-
-	// _dragStartHandler: Object
-	//		Handle to keep start subscribe
-	_dragStartHandler: null,
-
-	// _dropHandler: Object
-	//		Handle to keep drop subscribe
-	_dropHandler: null,
-
-	// _moveHandler: Object
-	//		Handle to keep move subscribe
-	_moveHandler: null,
-
-	// _moveUpHandler: Object
-	//		Handle to kee move up subscribe
-	_moveUpHandler: null,
-
-	// _draggedNode: DOMNode
-	// 		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._draggedNode = node;
-			this._moveHandler = dojo.connect(dojo.doc, "onmousemove", this, "onMouseMove");
-		});
-		this._dropHandler = dojo.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]);
-			}
-			this._draggedNode = null;
-			this._currentDojoArea = null;
-			dojo.disconnect(this._moveHandler);
-		});
-	},
-
-	_getIndexDojoArea: function(/*node*/area){
+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(
+		"dojox.mdnd.adapter.DndToDojo",
+		null,
+	{
 		// summary:
-		//		Check if a dojo area is registered.
-		// area: DOMNode
-		//		A node corresponding to the target dojo.
-		// returns:
-		//		The index of area if it's registered else -1.
-		// tags:
-		//		protected
-
-		//console.log('dojox.mdnd.adapter.DndToDojo ::: _getIndexDojoArea');
-		if(area){
-			for(var i = 0, l = this._dojoList.length; i < l; i++){
-				if(this._dojoList[i].node === area){
-					return i;
+		//		Allow communication between an item of dojox D&D area to a target dojo.
+	
+		// _dojoList: Array
+		//		Array containing object references the dojo Target list
+		_dojoList: null,
+	
+		// _currentDojoArea: DOMNode
+		//		Representing the current dojo area
+		_currentDojoArea: null,
+	
+		// _dojoxManager: dojox.mdnd.AreaManager
+		//		The reference to the dojox AreaManager
+		_dojoxManager: null,
+	
+		// _dragStartHandler: Object
+		//		Handle to keep start subscribe
+		_dragStartHandler: null,
+	
+		// _dropHandler: Object
+		//		Handle to keep drop subscribe
+		_dropHandler: null,
+	
+		// _moveHandler: Object
+		//		Handle to keep move subscribe
+		_moveHandler: null,
+	
+		// _moveUpHandler: Object
+		//		Handle to kee move up subscribe
+		_moveUpHandler: null,
+	
+		// _draggedNode: DOMNode
+		// 		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._draggedNode = node;
+				this._moveHandler = dojo.connect(dojo.doc, "onmousemove", this, "onMouseMove");
+			});
+			this._dropHandler = dojo.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]);
+				}
+				this._draggedNode = null;
+				this._currentDojoArea = null;
+				dojo.disconnect(this._moveHandler);
+			});
+		},
+	
+		_getIndexDojoArea: function(/*node*/area){
+			// summary:
+			//		Check if a dojo area is registered.
+			// area: DOMNode
+			//		A node corresponding to the target dojo.
+			// returns:
+			//		The index of area if it's registered else -1.
+			// tags:
+			//		protected
+	
+			//console.log('dojox.mdnd.adapter.DndToDojo ::: _getIndexDojoArea');
+			if(area){
+				for(var i = 0, l = this._dojoList.length; i < l; i++){
+					if(this._dojoList[i].node === area){
+						return i;
+					}
 				}
 			}
-		}
-		return -1;
-	},
-
-	_initCoordinates: function(/*DOMNode*/area){
-		// summary:
-		//		Initialize the coordinates of the target dojo.
-		// area:
-		//		A registered DOM node.
-		// returns:
-		//		An object which contains coordinates : *{x:0,y:,x1:0,y1:0}*
-		// tags:
-		//		protected
-
- 		//console.log('dojox.mdnd.adapter.DndToDojo ::: _initCoordinates');
-		if(area){
-			var position = dojo.position(area, true),
-				coords = {};
-			coords.x = position.x
-			coords.y = position.y
-			coords.x1 = position.x + position.w;
-			coords.y1 = position.y + position.h;
-			return coords;	// 	Object
-		}
-		return null;
-	},
-
-	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
-		// area:
-		//		The DOM node which has to be registered.
-		// type:
-		//		A String to identify the node.
-		// dojoTarger:
-		//		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);
-		if(this._getIndexDojoArea(area) == -1){
-			var coords = this._initCoordinates(area),
-				object = {
-					'node': area,
-					'type': type,
-					'dojo': (dojoTarget)?dojoTarget:false,
-					'coords': coords
-				};
-			this._dojoList.push(object);
-			// initialization of the _fakeSource to allow Dnd switching
-			if(dojoTarget && !this._lazyManager){
-				this._lazyManager = new dojox.mdnd.LazyManager();
+			return -1;
+		},
+	
+		_initCoordinates: function(/*DOMNode*/area){
+			// summary:
+			//		Initialize the coordinates of the target dojo.
+			// area:
+			//		A registered DOM node.
+			// returns:
+			//		An object which contains coordinates : *{x:0,y:,x1:0,y1:0}*
+			// tags:
+			//		protected
+	
+			//console.log('dojox.mdnd.adapter.DndToDojo ::: _initCoordinates');
+			if(area){
+				var position = dojo.position(area, true),
+					coords = {};
+				coords.x = position.x
+				coords.y = position.y
+				coords.x1 = position.x + position.w;
+				coords.y1 = position.y + position.h;
+				return coords;	// 	Object
 			}
-		}
-	},
-
-	unregisterByNode: function(/*DOMNode*/area){
-		// summary:
-		//		Unregister a target dojo.
-		// area:
-		//		The DOM node of target dojo.
-
-		//console.log("dojox.mdnd.adapter.DndToDojo ::: unregisterByNode", area);
-		var index = this._getIndexDojoArea(area);
-		// if area is registered
-		if(index != -1){
-			this._dojoList.splice(index, 1);
-		}
-	},
-
-	unregisterByType: function(/*String*/type){
-		// summary:
-		//		Unregister several targets dojo having the same type passing in parameter.
-		// type:
-		//		A String to identify dojo targets.
-
-		//console.log("dojox.mdnd.adapter.DndToDojo ::: unregisterByType", type);
-		if(type){
-			var tempList = [];
-			dojo.forEach(this._dojoList, function(item, i){
-				if(item.type != type){
-					tempList.push(item);
+			return null;
+		},
+	
+		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
+			// area:
+			//		The DOM node which has to be registered.
+			// type:
+			//		A String to identify the node.
+			// dojoTarger:
+			//		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);
+			if(this._getIndexDojoArea(area) == -1){
+				var coords = this._initCoordinates(area),
+					object = {
+						'node': area,
+						'type': type,
+						'dojo': (dojoTarget)?dojoTarget:false,
+						'coords': coords
+					};
+				this._dojoList.push(object);
+				// initialization of the _fakeSource to allow Dnd switching
+				if(dojoTarget && !this._lazyManager){
+					this._lazyManager = new dojox.mdnd.LazyManager();
 				}
-			});
-			this._dojoList = tempList;
-		}
-	},
-
-	unregister: function(){
-		// summary:
-		//		Unregister all targets dojo.
-
-		//console.log("dojox.mdnd.adapter.DndToDojo ::: unregister");
-		this._dojoList = [];
-	},
-
-	refresh: function(){
-		// summary:
-		//		Refresh the coordinates of all registered dojo target.
-
-		//console.log("dojox.mdnd.adapter.DndToDojo ::: refresh");
-		var dojoList = this._dojoList;
-		this.unregister();
-		dojo.forEach(dojoList, function(dojo){
-			dojo.coords = this._initCoordinates(dojo.node);
-		}, this);
-		this._dojoList = dojoList;
-	},
-
-	refreshByType: function(/*String*/ type){
-		// summary:
-		//		Refresh the coordinates of registered dojo target with a specific type.
-		// type:
-		//		A String to identify dojo targets.
-
-		//console.log("dojox.mdnd.adapter.DndToDojo ::: refresh");
-		var dojoList = this._dojoList;
-		this.unregister();
-		dojo.forEach(dojoList, function(dojo){
-			if(dojo.type == type){
-				dojo.coords = this._initCoordinates(dojo.node);
 			}
-		}, this);
-		this._dojoList = dojoList;
-	},
-
-	_getHoverDojoArea: function(/*Object*/coords){
-		// summary:
-		//		Check if the coordinates of the mouse is in a dojo target.
-		// coords:
-		//		Coordinates of the mouse.
-		// tags:
-		//		protected
-
-		//console.log("dojox.mdnd.adapter.DndToDojo ::: _getHoverDojoArea");
-		this._oldDojoArea = this._currentDojoArea;
-		this._currentDojoArea = null;
-		var x = coords.x;
-		var y = coords.y;
-		var length = this._dojoList.length;
-		for(var i = 0; i < length; i++){
-			var dojoArea = this._dojoList[i];
-			var coordinates = dojoArea.coords;
-			if(coordinates.x <= x && x <= coordinates.x1 && coordinates.y <= y && y <= coordinates.y1){
-				this._currentDojoArea = dojoArea;
-				break;
+		},
+	
+		unregisterByNode: function(/*DOMNode*/area){
+			// summary:
+			//		Unregister a target dojo.
+			// area:
+			//		The DOM node of target dojo.
+	
+			//console.log("dojox.mdnd.adapter.DndToDojo ::: unregisterByNode", area);
+			var index = this._getIndexDojoArea(area);
+			// if area is registered
+			if(index != -1){
+				this._dojoList.splice(index, 1);
 			}
-		}
-	},
-
-	onMouseMove: function(/*DOMEvent*/e){
-		// summary:
-		//		Call when the mouse moving after an onStartDrag of AreaManger.
-		//		Check if the coordinates of the mouse is in a dojo target.
-		// e:
-		//		Event object.
-		// tags:
-		//		callback
-
-		//console.log("dojox.mdnd.adapter.DndToDojo ::: onMouseMove");
-		var coords = {
-			'x': e.pageX,
-			'y': e.pageY
-		};
-		this._getHoverDojoArea(coords);
-		if(this._currentDojoArea != this._oldDojoArea){
-			if(this._currentDojoArea == null){
-				this.onDragExit(e);
+		},
+	
+		unregisterByType: function(/*String*/type){
+			// summary:
+			//		Unregister several targets dojo having the same type passing in parameter.
+			// type:
+			//		A String to identify dojo targets.
+	
+			//console.log("dojox.mdnd.adapter.DndToDojo ::: unregisterByType", type);
+			if(type){
+				var tempList = [];
+				dojo.forEach(this._dojoList, function(item, i){
+					if(item.type != type){
+						tempList.push(item);
+					}
+				});
+				this._dojoList = tempList;
 			}
-			else if(this._oldDojoArea == null){
-				this.onDragEnter(e);
+		},
+	
+		unregister: function(){
+			// summary:
+			//		Unregister all targets dojo.
+	
+			//console.log("dojox.mdnd.adapter.DndToDojo ::: unregister");
+			this._dojoList = [];
+		},
+	
+		refresh: function(){
+			// summary:
+			//		Refresh the coordinates of all registered dojo target.
+	
+			//console.log("dojox.mdnd.adapter.DndToDojo ::: refresh");
+			var dojoList = this._dojoList;
+			this.unregister();
+			dojo.forEach(dojoList, function(dojo){
+				dojo.coords = this._initCoordinates(dojo.node);
+			}, this);
+			this._dojoList = dojoList;
+		},
+	
+		refreshByType: function(/*String*/ type){
+			// summary:
+			//		Refresh the coordinates of registered dojo target with a specific type.
+			// type:
+			//		A String to identify dojo targets.
+	
+			//console.log("dojox.mdnd.adapter.DndToDojo ::: refresh");
+			var dojoList = this._dojoList;
+			this.unregister();
+			dojo.forEach(dojoList, function(dojo){
+				if(dojo.type == type){
+					dojo.coords = this._initCoordinates(dojo.node);
+				}
+			}, this);
+			this._dojoList = dojoList;
+		},
+	
+		_getHoverDojoArea: function(/*Object*/coords){
+			// summary:
+			//		Check if the coordinates of the mouse is in a dojo target.
+			// coords:
+			//		Coordinates of the mouse.
+			// tags:
+			//		protected
+	
+			//console.log("dojox.mdnd.adapter.DndToDojo ::: _getHoverDojoArea");
+			this._oldDojoArea = this._currentDojoArea;
+			this._currentDojoArea = null;
+			var x = coords.x;
+			var y = coords.y;
+			var length = this._dojoList.length;
+			for(var i = 0; i < length; i++){
+				var dojoArea = this._dojoList[i];
+				var coordinates = dojoArea.coords;
+				if(coordinates.x <= x && x <= coordinates.x1 && coordinates.y <= y && y <= coordinates.y1){
+					this._currentDojoArea = dojoArea;
+					break;
+				}
 			}
-			else{
-				this.onDragExit(e);
-				this.onDragEnter(e);
+		},
+	
+		onMouseMove: function(/*DOMEvent*/e){
+			// summary:
+			//		Call when the mouse moving after an onStartDrag of AreaManger.
+			//		Check if the coordinates of the mouse is in a dojo target.
+			// e:
+			//		Event object.
+			// tags:
+			//		callback
+	
+			//console.log("dojox.mdnd.adapter.DndToDojo ::: onMouseMove");
+			var coords = {
+				'x': e.pageX,
+				'y': e.pageY
+			};
+			this._getHoverDojoArea(coords);
+			if(this._currentDojoArea != this._oldDojoArea){
+				if(this._currentDojoArea == null){
+					this.onDragExit(e);
+				}
+				else if(this._oldDojoArea == null){
+					this.onDragEnter(e);
+				}
+				else{
+					this.onDragExit(e);
+					this.onDragEnter(e);
+				}
 			}
-		}
-	},
-
-	isAccepted: function(/*DOMNode*/draggedNode, /*Object*/ target){
-		// summary:
-		//		Return true if the dragged node is accepted.
-		//		This method has to be overwritten according to registered target.
-
-		//console.log("dojox.mdnd.adapter.DndToDojo ::: isAccepted");
-		return true;
-	},
-
-
-	onDragEnter: function(/*DOMEvent*/e){
-		// summary:
-		//		Call when the mouse enters in a registered dojo target.
-		// e:
-		//		The current Javascript Event.
-		// tags:
-		//		callback
-
-		//console.log("dojox.mdnd.adapter.DndToDojo ::: onDragEnter");
-		// 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());
-			//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);
-			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();
+		},
+	
+		isAccepted: function(/*DOMNode*/draggedNode, /*Object*/ target){
+			// summary:
+			//		Return true if the dragged node is accepted.
+			//		This method has to be overwritten according to registered target.
+	
+			//console.log("dojox.mdnd.adapter.DndToDojo ::: isAccepted");
+			return true;
+		},
+	
+	
+		onDragEnter: function(/*DOMEvent*/e){
+			// summary:
+			//		Call when the mouse enters in a registered dojo target.
+			// e:
+			//		The current Javascript Event.
+			// tags:
+			//		callback
+	
+			//console.log("dojox.mdnd.adapter.DndToDojo ::: onDragEnter");
+			// 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());
+				//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);
+				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, {
+					'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);
+					if(this._lazyManager.manager.canDropFlag){
+						// remove dropIndicator
+						this._dojoxManager._dropIndicator.node.style.display = "none";
+					}
+				});
+	
+				this.cancelHandler = dojo.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")
+					];
+					// replace the cover and the dragNode in the cover.
+					dojo.body().appendChild(this._dojoxManager._cover);
+					dojo.body().appendChild(this._dojoxManager._cover2);
+					this._dojoxManager._cover.appendChild(moveableItem.node);
+	
+					var objectArea = this._dojoxManager._areaList[this._dojoxManager._sourceIndexArea];
+					var dropIndex = this._dojoxManager._sourceDropIndex;
+					var nodeRef = null;
+					if(dropIndex != objectArea.items.length
+							&& dropIndex != -1){
+						nodeRef = objectArea.items[this._dojoxManager._sourceDropIndex].item.node;
+					}
+					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._draggedNode.style.display = "";
+					this._dojoxManager.onDrop(this._draggedNode);
+					dojo.unsubscribe(this.cancelHandler);
+					dojo.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.onDrop();
+				});
 			}
-			dojo.style(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);
-				if(this._lazyManager.manager.canDropFlag){
+			else{
+				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());
 					// remove dropIndicator
 					this._dojoxManager._dropIndicator.node.style.display = "none";
+					if(!this._moveUpHandler){
+						this._moveUpHandler = dojo.connect(dojo.doc, "onmouseup", this, "onDrop");
+					}
 				}
-			});
-
-			this.cancelHandler = dojo.subscribe("/dnd/cancel", this, function(){
+			}
+			// publish a topic
+			dojo.publish("/dojox/mdnd/adapter/dndToDojo/over",[this._currentDojoArea.node, this._currentDojoArea.type, this._draggedNode, this.accept]);
+		},
+	
+		onDragExit: function(/*DOMEvent*/e){
+			// summary:
+			//		Call when the mouse exit of a registered dojo target.
+			// e:
+			//		current javscript event
+	
+			//console.log("dojox.mdnd.adapter.DndToDojo ::: onDragExit",e, this._dojoxManager._dragItem.item);
+			// 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);
+				// launch Drag and Drop
 				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")
-				];
+				this._dojoxManager._dragItem.item.events.push(dojo.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);
 				this._dojoxManager._cover.appendChild(moveableItem.node);
-
-				var objectArea = this._dojoxManager._areaList[this._dojoxManager._sourceIndexArea];
-				var dropIndex = this._dojoxManager._sourceDropIndex;
-				var nodeRef = null;
-				if(dropIndex != objectArea.items.length
-						&& dropIndex != -1){
-					nodeRef = objectArea.items[this._dojoxManager._sourceDropIndex].item.node;
+				// fix style :
+				var style = moveableItem.node.style;
+				style.position = "absolute";
+				style.left = (moveableItem.offsetDrag.l + e.pageX)+"px";
+				style.top = (moveableItem.offsetDrag.t + e.pageX)+"px";
+				style.display = "";
+				// stop dojoDrag
+				this._lazyManager.cancelDrag();
+				// reconnect the dndFromDojo
+				if(dojox.mdnd.adapter._dndFromDojo){
+					dojox.mdnd.adapter._dndFromDojo.subscribeDnd();
 				}
 				if(this._dojoxManager._dropIndicator.node.style.display == "none"){
-					this._dojoxManager._dropIndicator.node.style.display == "";
+					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._draggedNode.style.display = "";
-				this._dojoxManager.onDrop(this._draggedNode);
-				dojo.unsubscribe(this.cancelHandler);
-				dojo.unsubscribe(this.dropHandler);
+				this._dojoxManager._dragItem.item.onMove(e);
+			}
+			else{
+				if(this.accept){
+					// disconnect the mouseUp event.
+					if(this._moveUpHandler){
+						dojo.disconnect(this._moveUpHandler);
+						this._moveUpHandler = null;
+					}
+					// redisplay dropIndicator
+					if(this._dojoxManager._dropIndicator.node.style.display == "none"){
+						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.item.onMove(e);
+				}
+			}
+			// publish a topic
+			dojo.publish("/dojox/mdnd/adapter/dndToDojo/out",[this._oldDojoArea.node, this._oldDojoArea.type, this._draggedNode, this.accept]);
+		},
+	
+		onDrop: function(/*DOMEvent*/e){
+			// summary:
+			//		Called when an onmouseup event is loaded on a registered target dojo.
+			// e:
+			//		Event object.
+	
+	//		console.log("dojox.mdnd.adapter.DndToDojo ::: onDrop", this._currentDojoArea);
+			if(this._currentDojoArea.dojo){
+				// reconnect the dojoDndAdapter
 				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.onDrop();
-			});
-		}
-		else{
-			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());
-				// remove dropIndicator
-				this._dojoxManager._dropIndicator.node.style.display = "none";
-				if(!this._moveUpHandler){
-					this._moveUpHandler = dojo.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]);
-	},
-
-	onDragExit: function(/*DOMEvent*/e){
-		// summary:
-		//		Call when the mouse exit of a registered dojo target.
-		// e:
-		//		current javscript event
-
-		//console.log("dojox.mdnd.adapter.DndToDojo ::: onDragExit",e, this._dojoxManager._dragItem.item);
-		// 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);
-			// launch Drag and Drop
-			var moveableItem = this._dojoxManager._dragItem.item;
-			// connect onmousemove of moveable item
-			this._dojoxManager._dragItem.item.events.push(dojo.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);
-			this._dojoxManager._cover.appendChild(moveableItem.node);
-			// fix style :
-			var style = moveableItem.node.style;
-			style.position = "absolute";
-			style.left = (moveableItem.offsetDrag.l + e.pageX)+"px";
-			style.top = (moveableItem.offsetDrag.t + e.pageX)+"px";
-			style.display = "";
-			// stop dojoDrag
-			this._lazyManager.cancelDrag();
-			// reconnect the dndFromDojo
-			if(dojox.mdnd.adapter._dndFromDojo){
-				dojox.mdnd.adapter._dndFromDojo.subscribeDnd();
 			}
 			if(this._dojoxManager._dropIndicator.node.style.display == "none"){
 				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.item.onMove(e);
-		}
-		else{
-			if(this.accept){
-				// disconnect the mouseUp event.
-				if(this._moveUpHandler){
-					dojo.disconnect(this._moveUpHandler);
-					this._moveUpHandler = null;
-				}
-				// redisplay dropIndicator
-				if(this._dojoxManager._dropIndicator.node.style.display == "none"){
-					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.item.onMove(e);
+			// 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);
 			}
-		}
-		// publish a topic
-		dojo.publish("/dojox/mdnd/adapter/dndToDojo/out",[this._oldDojoArea.node, this._oldDojoArea.type, this._draggedNode, this.accept]);
-	},
-
-	onDrop: function(/*DOMEvent*/e){
-		// summary:
-		//		Called when an onmouseup event is loaded on a registered target dojo.
-		// e:
-		//		Event object.
-
-//		console.log("dojox.mdnd.adapter.DndToDojo ::: onDrop", this._currentDojoArea);
-		if(this._currentDojoArea.dojo){
-			// reconnect the dojoDndAdapter
-			if(dojox.mdnd.adapter._dndFromDojo){
-				dojox.mdnd.adapter._dndFromDojo.subscribeDnd();
+			// 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);
+			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");
+			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);
+			this._dojoxManager._deleteMoveableItem(this._dojoxManager._dragItem);
+			this._draggedNode = null;
+			this._currentDojoArea = null;
+			// reset of area manager.
+			this._dojoxManager._resetAfterDrop();
 		}
-		if(this._dojoxManager._dropIndicator.node.style.display == "none"){
-			this._dojoxManager._dropIndicator.node.style.display = "";
-		}
-		// 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);
-		}
-		// remove draggedNode of target :
-		if(this._draggedNode.parentNode == this._dojoxManager._cover){
-			this._dojoxManager._cover.removeChild(this._draggedNode);
+	});
+	
+	dojox.mdnd.adapter._dndToDojo = null;
+	dojox.mdnd.adapter.dndToDojo = function(){
+		// summary:
+		// 		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();
 		}
-		dojo.disconnect(this._moveHandler);
-		dojo.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");
-		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);
-		this._dojoxManager._deleteMoveableItem(this._dojoxManager._dragItem);
-		this._draggedNode = null;
-		this._currentDojoArea = null;
-		// reset of area manager.
-		this._dojoxManager._resetAfterDrop();
-	}
-});
-
-dojox.mdnd.adapter._dndToDojo = null;
-dojox.mdnd.adapter.dndToDojo = function(){
-	// summary:
-	// 		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 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 0539167..673a7b2 100644
--- a/dojox/mdnd/dropMode/DefaultDropMode.js
+++ b/dojox/mdnd/dropMode/DefaultDropMode.js
@@ -1,333 +1,337 @@
-dojo.provide("dojox.mdnd.dropMode.DefaultDropMode");
-dojo.require("dojox.mdnd.AreaManager");
-
-dojo.declare("dojox.mdnd.dropMode.DefaultDropMode", null, {
-	// summary:
-	//		Enabled a type of calcul for Dnd.
-	//		Default class to find the nearest target.
-
-	// _oldXPoint: Integer
-	//		used to save a X position
-	_oldXPoint: null,
-
-	// _oldYPoint: Integer
-	//		used to save a Y position
-	_oldYPoint: null,
-
-	// _oldBehaviour: String
-	// 		see <getDragPoint>
-	_oldBehaviour: "up",
-
-	addArea: function(/*Array*/areas, /*Object*/object){
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/html",
+	"dojox/mdnd/AreaManager"
+],function(dojo){
+	var ddm = dojo.declare("dojox.mdnd.dropMode.DefaultDropMode", null, {
 		// summary:
-		//		Add a DnD Area into an array sorting by the x position.
-		// areas:
-		//		array of areas
-		// object:
-		//		data type of a DndArea
-		// returns:
-		//		a sorted area
-
-		//console.log("dojox.mdnd.dropMode.DefaultDropMode ::: addArea");
-		var length =  areas.length;
-		var position = dojo.position(object.node, true);
-		object.coords = {'x':position.x, 'y':position.y};
-		if (length == 0) {
-			areas.push(object);
-		}else{
-			var x =  object.coords.x;
-			for (var i = 0; i < length; i++) {
-				if (x < areas[i].coords.x) {
-					for (var j = length-1; j >= i; j--)
-						areas[j + 1] = areas[j];
-					areas[i] = object;
-					break;
-				}
-			}
-			if (i == length)
+		//		Enabled a type of calcul for Dnd.
+		//		Default class to find the nearest target.
+	
+		// _oldXPoint: Integer
+		//		used to save a X position
+		_oldXPoint: null,
+	
+		// _oldYPoint: Integer
+		//		used to save a Y position
+		_oldYPoint: null,
+	
+		// _oldBehaviour: String
+		// 		see <getDragPoint>
+		_oldBehaviour: "up",
+	
+		addArea: function(/*Array*/areas, /*Object*/object){
+			// summary:
+			//		Add a DnD Area into an array sorting by the x position.
+			// areas:
+			//		array of areas
+			// object:
+			//		data type of a DndArea
+			// returns:
+			//		a sorted area
+	
+			//console.log("dojox.mdnd.dropMode.DefaultDropMode ::: addArea");
+			var length =  areas.length;
+			var position = dojo.position(object.node, true);
+			object.coords = {'x':position.x, 'y':position.y};
+			if (length == 0) {
 				areas.push(object);
-		}
-		return areas;	// Array
-	},
-
-	updateAreas: function(/*Array*/areaList){
-		// summary:
-		//		Refresh intervals between areas to determinate the nearest area to drop an item.
-		//		Algorithm :
-		//		the marker should be the vertical line passing by the
-		//		central point between two contiguous areas.
-		//		Note:
-		//		If the page has only one targetArea, it's not necessary to calculate coords.
-		// areaList:
-		//		array of areas
-
-		//console.log("dojox.mdnd.dropMode.DefaultDropMode ::: initAreas");
-		var length = areaList.length;
-		if (length > 1){
-			var currentRight, nextLeft;
-			for (var i = 0; i < length; i++) {
-				var area = areaList[i];
-				var nextArea;
-				area.coords.x1 = -1;
-				area.coords.x2 = -1;
-				if (i == 0) {
-					nextArea = areaList[i+1];
-					this._updateArea(area);
-					this._updateArea(nextArea);
-					currentRight = area.coords.x + area.node.offsetWidth;
-					nextLeft =  nextArea.coords.x;
-					area.coords.x2 = currentRight + (nextLeft-currentRight)/2;
-				}
-				else if (i == length-1) {
-					area.coords.x1 = areaList[i-1].coords.x2;
-				}else{
-					nextArea = areaList[i+1];
-					this._updateArea(nextArea);
-					currentRight = area.coords.x + area.node.offsetWidth;
-					nextLeft =  nextArea.coords.x;
-					area.coords.x1 = areaList[i-1].coords.x2;
-					area.coords.x2 = currentRight + (nextLeft-currentRight)/2;
+			}else{
+				var x =  object.coords.x;
+				for (var i = 0; i < length; i++) {
+					if (x < areas[i].coords.x) {
+						for (var j = length-1; j >= i; j--)
+							areas[j + 1] = areas[j];
+						areas[i] = object;
+						break;
+					}
 				}
+				if (i == length)
+					areas.push(object);
 			}
-		}
-	},
-
-	_updateArea : function(/*Object*/area){
-		// summary:
-		//		update the DnD area object (i.e. update coordinates of its DOM node)
-		// area:
-		//		the DnD area
-		// tags:
-		//		protected
-
-		//console.log("dojox.mdnd.dropMode.DefaultDropMode  ::: _updateArea");
-		var position = dojo.position(area.node, true);
-		area.coords.x = position.x;
-		area.coords.y = position.y;
-	},
-
-	initItems: function(/*Object*/area){
-		// summary:
-		//		initialize the horizontal line in order to determinate the drop zone.
-		// area:
-		//		the DnD area
-
-		//console.log("dojox.mdnd.dropMode.DefaultDropMode ::: initItems");
-		dojo.forEach(area.items, function(obj){
-			//get the vertical middle of the item
-			var node = obj.item.node;
-			var position = dojo.position(node, true);
-			var y = position.y + position.h/2;
-			obj.y = y;
-		});
-		area.initItems = true;
-	},
-
-	refreshItems: function(/*Object*/area, /*Integer*/indexItem, /*Object*/size, /*Boolean*/added){
-		// summary:
-		//		take into account the drop indicator DOM element in order to compute horizontal lines
-		// area:
-		//		a DnD area object
-		// indexItem:
-		// 		index of a draggable item
-		// size:
-		//		dropIndicator size
-		// added:
-		//		boolean to know if a dropIndicator has been added or deleted
-
-		//console.log("dojox.mdnd.dropMode.DefaultDropMode ::: refreshItems");
-		if (indexItem == -1) {
-			return;
-		}else if(area && size && size.h){
-			var height = size.h;
-			if (area.margin){
-				height += area.margin.t;
-			}
-			var length = area.items.length;
-			for (var i=indexItem; i<length; i++){
-				var item = area.items[i];
-				if (added) {
-					item.y += height;
-				}else{
-					item.y -= height;
+			return areas;	// Array
+		},
+	
+		updateAreas: function(/*Array*/areaList){
+			// summary:
+			//		Refresh intervals between areas to determinate the nearest area to drop an item.
+			//		Algorithm :
+			//		the marker should be the vertical line passing by the
+			//		central point between two contiguous areas.
+			//		Note:
+			//		If the page has only one targetArea, it's not necessary to calculate coords.
+			// areaList:
+			//		array of areas
+	
+			//console.log("dojox.mdnd.dropMode.DefaultDropMode ::: initAreas");
+			var length = areaList.length;
+			if (length > 1){
+				var currentRight, nextLeft;
+				for (var i = 0; i < length; i++) {
+					var area = areaList[i];
+					var nextArea;
+					area.coords.x1 = -1;
+					area.coords.x2 = -1;
+					if (i == 0) {
+						nextArea = areaList[i+1];
+						this._updateArea(area);
+						this._updateArea(nextArea);
+						currentRight = area.coords.x + area.node.offsetWidth;
+						nextLeft =  nextArea.coords.x;
+						area.coords.x2 = currentRight + (nextLeft-currentRight)/2;
+					}
+					else if (i == length-1) {
+						area.coords.x1 = areaList[i-1].coords.x2;
+					}else{
+						nextArea = areaList[i+1];
+						this._updateArea(nextArea);
+						currentRight = area.coords.x + area.node.offsetWidth;
+						nextLeft =  nextArea.coords.x;
+						area.coords.x1 = areaList[i-1].coords.x2;
+						area.coords.x2 = currentRight + (nextLeft-currentRight)/2;
+					}
 				}
 			}
-		}
-	},
-
-	getDragPoint: function(/*Object*/coords, /*Object*/size, /*Object*/mousePosition){
-		// summary:
-		//		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
-		// coords:
-		//		an object encapsulating X and Y position
-		// size:
-		//		an object encapsulating width and height values
-		// mousePosition:
-		//		coordinates of mouse
-		// returns:
-		//		an object of coordinates
-		// 		example : {'x':10,'y':10}
-
-		//console.log("dojox.mdnd.dropMode.DefaultDropMode ::: getDragPoint");
-		var y = coords.y;
-		if (this._oldYPoint){
-			if (y > this._oldYPoint) {
-				this._oldBehaviour = "down";
-				y += size.h;
-			}
-			else
-				if (y <= this._oldYPoint) {
-					this._oldBehaviour = "up";
+		},
+	
+		_updateArea : function(/*Object*/area){
+			// summary:
+			//		update the DnD area object (i.e. update coordinates of its DOM node)
+			// area:
+			//		the DnD area
+			// tags:
+			//		protected
+	
+			//console.log("dojox.mdnd.dropMode.DefaultDropMode  ::: _updateArea");
+			var position = dojo.position(area.node, true);
+			area.coords.x = position.x;
+			area.coords.y = position.y;
+		},
+	
+		initItems: function(/*Object*/area){
+			// summary:
+			//		initialize the horizontal line in order to determinate the drop zone.
+			// area:
+			//		the DnD area
+	
+			//console.log("dojox.mdnd.dropMode.DefaultDropMode ::: initItems");
+			dojo.forEach(area.items, function(obj){
+				//get the vertical middle of the item
+				var node = obj.item.node;
+				var position = dojo.position(node, true);
+				var y = position.y + position.h/2;
+				obj.y = y;
+			});
+			area.initItems = true;
+		},
+	
+		refreshItems: function(/*Object*/area, /*Integer*/indexItem, /*Object*/size, /*Boolean*/added){
+			// summary:
+			//		take into account the drop indicator DOM element in order to compute horizontal lines
+			// area:
+			//		a DnD area object
+			// indexItem:
+			// 		index of a draggable item
+			// size:
+			//		dropIndicator size
+			// added:
+			//		boolean to know if a dropIndicator has been added or deleted
+	
+			//console.log("dojox.mdnd.dropMode.DefaultDropMode ::: refreshItems");
+			if (indexItem == -1) {
+				return;
+			}else if(area && size && size.h){
+				var height = size.h;
+				if (area.margin){
+					height += area.margin.t;
 				}
-		}
-		this._oldYPoint = y;
-		return {
-			'x': coords.x + (size.w / 2),
-			'y': y
-			};	// Object
-	},
-
-	getTargetArea: function(/*Array*/areaList, /*Object*/ coords, /*integer*/currentIndexArea ){
-		// summary:
-		//		get the nearest DnD area.
-		//		Coordinates are basically provided by the <getDragPoint> method.
-		// areaList:
-		//		a list of DnD areas objects
-		// coords:
-		//		coordinates [x,y] of the dragItem
-		// currentIndexArea:
-		//		an index representing the active DnD area
-		// returns:
-		//		the index of the DnD area
-
-		//console.log("dojox.mdnd.dropMode.DefaultDropMode ::: getTargetArea");
-		var index = 0;
-		var x = coords.x;
-		var end = areaList.length;
-		if (end > 1) {
-			var start = 0, direction = "right", compute = false;
-			if (currentIndexArea == -1 || arguments.length<3) {
-				// first time : Need to search the nearest area in all areas.
-				compute = true;
-			}
-			else {
-				// check if it's always the same area
-				if (this._checkInterval(areaList, currentIndexArea, x)){
-					index = currentIndexArea;
-				}else{
-					if (this._oldXPoint < x){
-						start = currentIndexArea + 1;
+				var length = area.items.length;
+				for (var i=indexItem; i<length; i++){
+					var item = area.items[i];
+					if (added) {
+						item.y += height;
 					}else{
-						start = currentIndexArea - 1;
-						end = 0;
-						direction = "left";
+						item.y -= height;
 					}
-					compute = true;
 				}
 			}
-			if (compute) {
-				if (direction === "right") {
-					for (var i = start; i < end; i++) {
-						if (this._checkInterval(areaList, i, x)) {
-							index = i;
-							break;
-						}
+		},
+	
+		getDragPoint: function(/*Object*/coords, /*Object*/size, /*Object*/mousePosition){
+			// summary:
+			//		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
+			// coords:
+			//		an object encapsulating X and Y position
+			// size:
+			//		an object encapsulating width and height values
+			// mousePosition:
+			//		coordinates of mouse
+			// returns:
+			//		an object of coordinates
+			// 		example : {'x':10,'y':10}
+	
+			//console.log("dojox.mdnd.dropMode.DefaultDropMode ::: getDragPoint");
+			var y = coords.y;
+			if (this._oldYPoint){
+				if (y > this._oldYPoint) {
+					this._oldBehaviour = "down";
+					y += size.h;
+				}
+				else
+					if (y <= this._oldYPoint) {
+						this._oldBehaviour = "up";
 					}
-				}else{
-					for (var i = start; i >= end; i--) {
-						if (this._checkInterval(areaList, i, x)) {
-							index = i;
-							break;
+			}
+			this._oldYPoint = y;
+			return {
+				'x': coords.x + (size.w / 2),
+				'y': y
+				};	// Object
+		},
+	
+		getTargetArea: function(/*Array*/areaList, /*Object*/ coords, /*integer*/currentIndexArea ){
+			// summary:
+			//		get the nearest DnD area.
+			//		Coordinates are basically provided by the <getDragPoint> method.
+			// areaList:
+			//		a list of DnD areas objects
+			// coords:
+			//		coordinates [x,y] of the dragItem
+			// currentIndexArea:
+			//		an index representing the active DnD area
+			// returns:
+			//		the index of the DnD area
+	
+			//console.log("dojox.mdnd.dropMode.DefaultDropMode ::: getTargetArea");
+			var index = 0;
+			var x = coords.x;
+			var end = areaList.length;
+			if (end > 1) {
+				var start = 0, direction = "right", compute = false;
+				if (currentIndexArea == -1 || arguments.length<3) {
+					// first time : Need to search the nearest area in all areas.
+					compute = true;
+				}
+				else {
+					// check if it's always the same area
+					if (this._checkInterval(areaList, currentIndexArea, x)){
+						index = currentIndexArea;
+					}else{
+						if (this._oldXPoint < x){
+							start = currentIndexArea + 1;
+						}else{
+							start = currentIndexArea - 1;
+							end = 0;
+							direction = "left";
 						}
+						compute = true;
 					}
 				}
-			}
-		}
-		this._oldXPoint = x;
-		return index;	// Integer
-	},
-
-	_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.
-		// areaList:
-		//		a list of DnD areas objects
-		// index:
-		//		index of a DnD area (to get the interval)
-		// x:
-		//		coordinate x, of the dragNode
-		// returns:
-		//		true if the dragNode is in intervall
-		// tags:
-		//		protected
-
-		var coords = areaList[index].coords;
-		if (coords.x1 == -1) {
-			if (x <= coords.x2) {
-				return true;
-			}
-		}
-		else
-			if (coords.x2 == -1) {
-				if (x > coords.x1) {
-					return true;
+				if (compute) {
+					if (direction === "right") {
+						for (var i = start; i < end; i++) {
+							if (this._checkInterval(areaList, i, x)) {
+								index = i;
+								break;
+							}
+						}
+					}else{
+						for (var i = start; i >= end; i--) {
+							if (this._checkInterval(areaList, i, x)) {
+								index = i;
+								break;
+							}
+						}
+					}
 				}
 			}
-			else {
-				if (coords.x1 < x && x <= coords.x2) {
+			this._oldXPoint = x;
+			return index;	// Integer
+		},
+	
+		_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.
+			// areaList:
+			//		a list of DnD areas objects
+			// index:
+			//		index of a DnD area (to get the interval)
+			// x:
+			//		coordinate x, of the dragNode
+			// returns:
+			//		true if the dragNode is in intervall
+			// tags:
+			//		protected
+	
+			var coords = areaList[index].coords;
+			if (coords.x1 == -1) {
+				if (x <= coords.x2) {
 					return true;
 				}
 			}
-		return false;	// Boolean
-	},
-
-	getDropIndex: function(/*Object*/ targetArea, /*Object*/ coords){
-		// summary:
-		//		Return the index where the drop has to be placed.
-		// targetArea:
-		//		a DnD area object
-		// coords:
-		//		coordinates [x,y] of the draggable item
-		// returns:
-		// 		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");
-		var length = targetArea.items.length;
-		var coordinates = targetArea.coords;
-		var y = coords.y;
-		if (length > 0) {
-			// course all children in the target area.
-			for (var i = 0; i < length; i++) {
-				// compare y value with y value of children
-				if (y < targetArea.items[i].y) {
-					return i;	// Integer
+			else
+				if (coords.x2 == -1) {
+					if (x > coords.x1) {
+						return true;
+					}
 				}
 				else {
-					if (i == length-1) {
-						return -1;
+					if (coords.x1 < x && x <= coords.x2) {
+						return true;
+					}
+				}
+			return false;	// Boolean
+		},
+	
+		getDropIndex: function(/*Object*/ targetArea, /*Object*/ coords){
+			// summary:
+			//		Return the index where the drop has to be placed.
+			// targetArea:
+			//		a DnD area object
+			// coords:
+			//		coordinates [x,y] of the draggable item
+			// returns:
+			// 		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");
+			var length = targetArea.items.length;
+			var coordinates = targetArea.coords;
+			var y = coords.y;
+			if (length > 0) {
+				// course all children in the target area.
+				for (var i = 0; i < length; i++) {
+					// compare y value with y value of children
+					if (y < targetArea.items[i].y) {
+						return i;	// Integer
+					}
+					else {
+						if (i == length-1) {
+							return -1;
+						}
 					}
 				}
 			}
+			return -1;
+		},
+	
+		destroy: function(){
+			//	can be overwritten.
 		}
-		return -1;
-	},
-
-	destroy: function(){
-		//	can be overwritten.
-	}
-});
-
-//------------
-//Singleton
-//------------
-(function(){
+	});
+	
+	//------------
+	//Singleton
+	//------------
 	dojox.mdnd.areaManager()._dropMode = new dojox.mdnd.dropMode.DefaultDropMode();
-}());
\ No newline at end of file
+	return ddm;
+});
diff --git a/dojox/mdnd/dropMode/OverDropMode.js b/dojox/mdnd/dropMode/OverDropMode.js
index 9c4b158..fabdac6 100644
--- a/dojox/mdnd/dropMode/OverDropMode.js
+++ b/dojox/mdnd/dropMode/OverDropMode.js
@@ -1,308 +1,306 @@
-dojo.provide("dojox.mdnd.dropMode.OverDropMode");
-
-dojo.require("dojox.mdnd.AreaManager");
-
-dojo.declare(
-	"dojox.mdnd.dropMode.OverDropMode",
-	null,
-{
-	// summary:
-	//		Default class to find the nearest target only if the mouse is over an area.
-
-	// _oldXPoint: Integer
-	//		used to save a X position
-	_oldXPoint: null,
-
-	// _oldYPoint: Integer
-	//		used to save a Y position
-	_oldYPoint: null,
-
-	// _oldBehaviour: Integer
-	//		see getDragpoint()
-	_oldBehaviour: "up",
-
-	constructor: function(){
-		//console.log("dojox.mdnd.dropMode.OverDropMode ::: constructor");
-		this._dragHandler = [
-			dojo.connect(dojox.mdnd.areaManager(), "onDragEnter", function(coords, size){
-				var m = dojox.mdnd.areaManager();
-				if(m._oldIndexArea == -1){
-					m._oldIndexArea = m._lastValidIndexArea;
-				}
-			})
-		];
-
-	},
-
-	addArea: function(/*Array*/areas, /*Object*/object){
+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(
+		"dojox.mdnd.dropMode.OverDropMode",
+		null,
+	{
 		// summary:
-		//		Add a D&D Area into an array sorting by the x position.
-		// areas:
-		//		array of areas
-		// object:
-		//		data type of a DndArea
-		// returns:
-		//		a sorted area
-
-		//console.log("dojox.mdnd.dropMode.OverDropMode ::: addArea");
-		var length = areas.length,
-			position = dojo.position(object.node, true);
-		object.coords = {'x':position.x, 'y':position.y};
-		if(length == 0){
-			areas.push(object);
-		}
-		else{
-			var x = object.coords.x;
-			for(var i = 0; i < length; i++){
-				if(x < areas[i].coords.x){
-					for(var j = length-1; j >= i; j--)
-						areas[j + 1] = areas[j];
-					areas[i] = object;
-					break;
-				}
-			}
-			if(i == length){
+		//		Default class to find the nearest target only if the mouse is over an area.
+	
+		// _oldXPoint: Integer
+		//		used to save a X position
+		_oldXPoint: null,
+	
+		// _oldYPoint: Integer
+		//		used to save a Y position
+		_oldYPoint: null,
+	
+		// _oldBehaviour: Integer
+		//		see getDragpoint()
+		_oldBehaviour: "up",
+	
+		constructor: function(){
+			//console.log("dojox.mdnd.dropMode.OverDropMode ::: constructor");
+			this._dragHandler = [
+				dojo.connect(dojox.mdnd.areaManager(), "onDragEnter", function(coords, size){
+					var m = dojox.mdnd.areaManager();
+					if(m._oldIndexArea == -1){
+						m._oldIndexArea = m._lastValidIndexArea;
+					}
+				})
+			];
+	
+		},
+	
+		addArea: function(/*Array*/areas, /*Object*/object){
+			// summary:
+			//		Add a D&D Area into an array sorting by the x position.
+			// areas:
+			//		array of areas
+			// object:
+			//		data type of a DndArea
+			// returns:
+			//		a sorted area
+	
+			//console.log("dojox.mdnd.dropMode.OverDropMode ::: addArea");
+			var length = areas.length,
+				position = dojo.position(object.node, true);
+			object.coords = {'x':position.x, 'y':position.y};
+			if(length == 0){
 				areas.push(object);
 			}
-		}
-		return areas;	// Array
-	},
-
-	updateAreas: function(/*Array*/areaList){
-		// summary:
-		//		refresh areas position and size to determinate the nearest area to drop an item
-		// description:
-		//		the area position (and size) is equal to the postion of the domNode associated.
-		// areaList:
-		//		array of areas
-
-		//console.log("dojox.mdnd.dropMode.OverDropMode ::: updateAreas");
-		var length = areaList.length;
-		for(var i = 0; i < length; i++){
-			this._updateArea(areaList[i]);
-		}
-	},
-
-	_updateArea : function(/*Object*/area){
-		// summary:
-		//		update the D&D area object (i.e. update coordinates of its DOM node)
-		// area:
-		// 		the D&D area.
-		// tags:
-		//		protected
-
-		//console.log("dojox.mdnd.dropMode.OverDropMode ::: addArea");
-		var position = dojo.position(area.node, true);
-		area.coords.x = position.x;
-		area.coords.x2 = position.x + position.w;
-		area.coords.y = position.y;
-	},
-
-	initItems: function(/*Object*/area){
-		// summary:
-		//		initialize the horizontal line in order to determinate the drop zone.
-		// area:
-		//		the D&D area.
-
-		//console.log("dojox.mdnd.dropMode.OverDropMode ::: initItems");
-		dojo.forEach(area.items, function(obj){
-			//get the vertical middle of the item
-			var node = obj.item.node;
-			var position = dojo.position(node, true);
-			var y = position.y + position.h/2;
-			obj.y = y;
-		});
-		area.initItems = true;
-	},
-
-	refreshItems: function(/*Object*/area, /*Integer*/indexItem, /*Object*/size, /*Boolean*/added){
-		// summary:
-		//		take into account the drop indicator DOM element in order to compute horizontal lines
-		// area:
-		//		a D&D area object
-		// indexItem:
-		//		index of a draggable item
-		// size:
-		//		dropIndicator size
-		// added:
-		//		boolean to know if a dropIndicator has been added or deleted
-
-		//console.log("dojox.mdnd.dropMode.OverDropMode ::: refreshItems", area, indexItem, size, added);
-		if(indexItem == -1){
-			return;
-		}
-		else if(area && size && size.h){
-			var height = size.h;
-			if(area.margin){
-				height += area.margin.t;
-			}
-			var length = area.items.length;
-			for(var i = indexItem; i < length; i++){
-				var item = area.items[i];
-				if(added){
-					item.y += height;
+			else{
+				var x = object.coords.x;
+				for(var i = 0; i < length; i++){
+					if(x < areas[i].coords.x){
+						for(var j = length-1; j >= i; j--)
+							areas[j + 1] = areas[j];
+						areas[i] = object;
+						break;
+					}
 				}
-				else{
-					item.y -= height;
+				if(i == length){
+					areas.push(object);
 				}
 			}
-		}
-	},
-
-	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}
-		// coords:
-		//		an object encapsulating X and Y position
-		// size:
-		// 		an object encapsulating width and height values
-		// mousePosition:
-		// 		coordinates of mouse
-
-		//console.log("dojox.mdnd.OverDropMode ::: getDragPoint");
-		return {			// Object
-			'x': mousePosition.x,
-			'y': mousePosition.y
+			return areas;	// Array
+		},
+	
+		updateAreas: function(/*Array*/areaList){
+			// summary:
+			//		refresh areas position and size to determinate the nearest area to drop an item
+			// description:
+			//		the area position (and size) is equal to the postion of the domNode associated.
+			// areaList:
+			//		array of areas
+	
+			//console.log("dojox.mdnd.dropMode.OverDropMode ::: updateAreas");
+			var length = areaList.length;
+			for(var i = 0; i < length; i++){
+				this._updateArea(areaList[i]);
 			}
-	},
-
-
-	getTargetArea: function(/*Array*/areaList, /*Object*/ coords, /*integer*/currentIndexArea ){
-		// summary:
-		//		get the nearest D&D area.
-		// areaList:
-		// 		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:
-		//		the index of the D&D area
-
-		//console.log("dojox.mdnd.dropMode.OverDropMode ::: getTargetArea");
-		var index = 0;
-		var x = coords.x;
-		var y = coords.y;
-		var end = areaList.length;
-		var start = 0, direction = "right", compute = false;
-		if(currentIndexArea == -1 || arguments.length < 3){
-			// first time : Need to search the nearest area in all areas.
-			compute = true;
-		}
-		else{
-			// check if it's always the same area
-			if(this._checkInterval(areaList, currentIndexArea, x, y)){
-				index = currentIndexArea;
+		},
+	
+		_updateArea : function(/*Object*/area){
+			// summary:
+			//		update the D&D area object (i.e. update coordinates of its DOM node)
+			// area:
+			// 		the D&D area.
+			// tags:
+			//		protected
+	
+			//console.log("dojox.mdnd.dropMode.OverDropMode ::: addArea");
+			var position = dojo.position(area.node, true);
+			area.coords.x = position.x;
+			area.coords.x2 = position.x + position.w;
+			area.coords.y = position.y;
+		},
+	
+		initItems: function(/*Object*/area){
+			// summary:
+			//		initialize the horizontal line in order to determinate the drop zone.
+			// area:
+			//		the D&D area.
+	
+			//console.log("dojox.mdnd.dropMode.OverDropMode ::: initItems");
+			dojo.forEach(area.items, function(obj){
+				//get the vertical middle of the item
+				var node = obj.item.node;
+				var position = dojo.position(node, true);
+				var y = position.y + position.h/2;
+				obj.y = y;
+			});
+			area.initItems = true;
+		},
+	
+		refreshItems: function(/*Object*/area, /*Integer*/indexItem, /*Object*/size, /*Boolean*/added){
+			// summary:
+			//		take into account the drop indicator DOM element in order to compute horizontal lines
+			// area:
+			//		a D&D area object
+			// indexItem:
+			//		index of a draggable item
+			// size:
+			//		dropIndicator size
+			// added:
+			//		boolean to know if a dropIndicator has been added or deleted
+	
+			//console.log("dojox.mdnd.dropMode.OverDropMode ::: refreshItems", area, indexItem, size, added);
+			if(indexItem == -1){
+				return;
 			}
-			else{
-				if(this._oldXPoint < x){
-					start = currentIndexArea + 1;
-				}
-				else{
-					start = currentIndexArea - 1;
-					end = 0;
-					direction = "left";
+			else if(area && size && size.h){
+				var height = size.h;
+				if(area.margin){
+					height += area.margin.t;
 				}
-				compute = true;
-			}
-		}
-		if(compute){
-			if(direction === "right"){
-				for(var i = start; i < end; i++){
-					if(this._checkInterval(areaList, i, x, y)){
-						index = i;
-						break;
+				var length = area.items.length;
+				for(var i = indexItem; i < length; i++){
+					var item = area.items[i];
+					if(added){
+						item.y += height;
+					}
+					else{
+						item.y -= height;
 					}
 				}
-				if(i == end){
-					index = -1;
+			}
+		},
+	
+		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}
+			// coords:
+			//		an object encapsulating X and Y position
+			// size:
+			// 		an object encapsulating width and height values
+			// mousePosition:
+			// 		coordinates of mouse
+	
+			//console.log("dojox.mdnd.OverDropMode ::: getDragPoint");
+			return {			// Object
+				'x': mousePosition.x,
+				'y': mousePosition.y
 				}
+		},
+	
+	
+		getTargetArea: function(/*Array*/areaList, /*Object*/ coords, /*integer*/currentIndexArea ){
+			// summary:
+			//		get the nearest D&D area.
+			// areaList:
+			// 		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:
+			//		the index of the D&D area
+	
+			//console.log("dojox.mdnd.dropMode.OverDropMode ::: getTargetArea");
+			var index = 0;
+			var x = coords.x;
+			var y = coords.y;
+			var end = areaList.length;
+			var start = 0, direction = "right", compute = false;
+			if(currentIndexArea == -1 || arguments.length < 3){
+				// first time : Need to search the nearest area in all areas.
+				compute = true;
 			}
 			else{
-				for(var i = start; i >= end; i--){
-					if(this._checkInterval(areaList, i, x, y)){
-						index = i;
-						break;
-					}
+				// check if it's always the same area
+				if(this._checkInterval(areaList, currentIndexArea, x, y)){
+					index = currentIndexArea;
 				}
-				if(i == end-1){
-					index = -1;
+				else{
+					if(this._oldXPoint < x){
+						start = currentIndexArea + 1;
+					}
+					else{
+						start = currentIndexArea - 1;
+						end = 0;
+						direction = "left";
+					}
+					compute = true;
 				}
 			}
-		}
-		this._oldXPoint = x;
-		return index; // Integer
-	},
-
-	_checkInterval: function(/*Array*/areaList, /*Integer*/index, /*Coord*/x, /*Coord*/y){
-		// summary:
-		//		check if the dragNode is in the interval.
-		// returns:
-		//		true if the dragNode is in intervall
-		// areaList:
-		//		a list of D&D areas objects
-		// index:
-		//		index of a D&D area (to get the interval)
-		// x:
-		//		coordinate x, of the dragNode (see getDragPoint())
-		// tags:
-		//		protected
-
-		//console.log("dojox.mdnd.dropMode.OverDropMode ::: _checkInterval");
-		var area = areaList[index];
-		var node = area.node;
-		var coords = area.coords;
-		var startX = coords.x;
-		var endX = coords.x2;
-		var startY = coords.y;
-		var endY = startY + node.offsetHeight;
-		if(startX <= x && x <= endX && startY <= y && y <= endY){
-			return true;
-		}
-		return false; // Boolean
-	},
-
-	getDropIndex: function(/*Object*/ targetArea, /*Object*/ coords){
-		// summary:
-		//		Return the index where the drop has to be placed.
-		// targetArea:
-		//		a D&D area object.
-		// coords:
-		//		coordinates [x,y] of the draggable item.
-		// returns:
-		//		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.OverDropMode ::: getDropIndex");
-		var length = targetArea.items.length;
-		var coordinates = targetArea.coords;
-		var y = coords.y;
-		if(length > 0){
-			// course all children in the target area.
-			for(var i = 0; i < length; i++){
-				// compare y value with y value of children
-				if(y < targetArea.items[i].y){
-					return i;	// integer
+			if(compute){
+				if(direction === "right"){
+					for(var i = start; i < end; i++){
+						if(this._checkInterval(areaList, i, x, y)){
+							index = i;
+							break;
+						}
+					}
+					if(i == end){
+						index = -1;
+					}
 				}
 				else{
-					if(i == length-1){
-						return -1; // integer
+					for(var i = start; i >= end; i--){
+						if(this._checkInterval(areaList, i, x, y)){
+							index = i;
+							break;
+						}
+					}
+					if(i == end-1){
+						index = -1;
+					}
+				}
+			}
+			this._oldXPoint = x;
+			return index; // Integer
+		},
+	
+		_checkInterval: function(/*Array*/areaList, /*Integer*/index, /*Coord*/x, /*Coord*/y){
+			// summary:
+			//		check if the dragNode is in the interval.
+			// returns:
+			//		true if the dragNode is in intervall
+			// areaList:
+			//		a list of D&D areas objects
+			// index:
+			//		index of a D&D area (to get the interval)
+			// x:
+			//		coordinate x, of the dragNode (see getDragPoint())
+			// tags:
+			//		protected
+	
+			//console.log("dojox.mdnd.dropMode.OverDropMode ::: _checkInterval");
+			var area = areaList[index];
+			var node = area.node;
+			var coords = area.coords;
+			var startX = coords.x;
+			var endX = coords.x2;
+			var startY = coords.y;
+			var endY = startY + node.offsetHeight;
+			if(startX <= x && x <= endX && startY <= y && y <= endY){
+				return true;
+			}
+			return false; // Boolean
+		},
+	
+		getDropIndex: function(/*Object*/ targetArea, /*Object*/ coords){
+			// summary:
+			//		Return the index where the drop has to be placed.
+			// targetArea:
+			//		a D&D area object.
+			// coords:
+			//		coordinates [x,y] of the draggable item.
+			// returns:
+			//		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.OverDropMode ::: getDropIndex");
+			var length = targetArea.items.length;
+			var coordinates = targetArea.coords;
+			var y = coords.y;
+			if(length > 0){
+				// course all children in the target area.
+				for(var i = 0; i < length; i++){
+					// compare y value with y value of children
+					if(y < targetArea.items[i].y){
+						return i;	// integer
+					}
+					else{
+						if(i == length-1){
+							return -1; // integer
+						}
 					}
 				}
 			}
+			return -1;	//integer
+		},
+	
+		destroy: function(){
+			dojo.forEach(this._dragHandler, dojo.disconnect);
 		}
-		return -1;	//integer
-	},
-
-	destroy: function(){
-		dojo.forEach(this._dragHandler, dojo.disconnect);
-	}
-});
-
-(function(){
+	});
+	
 	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 3bcf3e0..612c640 100644
--- a/dojox/mdnd/dropMode/VerticalDropMode.js
+++ b/dojox/mdnd/dropMode/VerticalDropMode.js
@@ -1,343 +1,347 @@
-dojo.provide("dojox.mdnd.dropMode.VerticalDropMode");
-dojo.require("dojox.mdnd.AreaManager");
-
-dojo.declare(
-	"dojox.mdnd.dropMode.VerticalDropMode",
-	null,
-{
-	// summary:
-	//		Enabled a type of calcul for Dnd.
-	//		Default class to find the nearest target.
-
-	// _oldXPoint: Integer
-	//		used to save a X position
-	_oldXPoint: null,
-
-	// _oldYPoint: Integer
-	//		used to save a Y position
-	_oldYPoint: null,
-
-	// _oldBehaviour: String
-	// 		see <getDragPoint>
-	_oldBehaviour: "up",
-
-	addArea: function(/*Array*/areas, /*Object*/object){
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/html",
+	"dojo/_base/array",
+	"dojox/mdnd/AreaManager"
+],function(dojo){
+	var vdm = dojo.declare(
+		"dojox.mdnd.dropMode.VerticalDropMode",
+		null,
+	{
 		// summary:
-		//		Add a DnD Area into an array sorting by the x position.
-		// areas:
-		//		array of areas
-		// object:
-		//		data type of a DndArea
-		// returns:
-		//		a sorted area
-
-		//console.log("dojox.mdnd.dropMode.VerticalDropMode ::: addArea");
-		var length = areas.length;
-		var position = dojo.position(object.node, true);
-		object.coords = {'x':position.x, 'y':position.y};
-		if(length == 0){
-			areas.push(object);
-		}
-		else{
-			var x = object.coords.x;
-			for(var i = 0; i < length; i++){
-				if(x < areas[i].coords.x){
-					for(var j = length-1; j >= i; j--)
-						areas[j + 1] = areas[j];
-					areas[i] = object;
-					break;
-				}
-			}
-			if(i == length){
+		//		Enabled a type of calcul for Dnd.
+		//		Default class to find the nearest target.
+	
+		// _oldXPoint: Integer
+		//		used to save a X position
+		_oldXPoint: null,
+	
+		// _oldYPoint: Integer
+		//		used to save a Y position
+		_oldYPoint: null,
+	
+		// _oldBehaviour: String
+		// 		see <getDragPoint>
+		_oldBehaviour: "up",
+	
+		addArea: function(/*Array*/areas, /*Object*/object){
+			// summary:
+			//		Add a DnD Area into an array sorting by the x position.
+			// areas:
+			//		array of areas
+			// object:
+			//		data type of a DndArea
+			// returns:
+			//		a sorted area
+	
+			//console.log("dojox.mdnd.dropMode.VerticalDropMode ::: addArea");
+			var length = areas.length;
+			var position = dojo.position(object.node, true);
+			object.coords = {'x':position.x, 'y':position.y};
+			if(length == 0){
 				areas.push(object);
 			}
-		}
-		return areas;	// Array
-	},
-
-	updateAreas: function(/*Array*/areaList){
-		// summary:
-		//		Refresh intervals between areas to determinate the nearest area to drop an item.
-		//		Algorithm :
-		//		the marker should be the vertical line passing by the
-		//		central point between two contiguous areas.
-		//		Note:
-		//		If the page has only one targetArea, it's not necessary to calculate coords.
-		// areaList:
-		//		array of areas
-
-		//console.log("dojox.mdnd.dropMode.VerticalDropMode ::: initAreas");
-		var length = areaList.length;
-		if(length > 1){
-			var currentRight, nextLeft;
-			for(var i = 0; i < length; i++){
-				var area = areaList[i];
-				var nextArea;
-				area.coords.x1 = -1;
-				area.coords.x2 = -1;
-				if(i == 0){
-					nextArea = areaList[i+1];
-					this._updateArea(area);
-					this._updateArea(nextArea);
-					currentRight = area.coords.x + area.node.offsetWidth;
-					nextLeft = nextArea.coords.x;
-					area.coords.x2 = currentRight + (nextLeft-currentRight)/2;
+			else{
+				var x = object.coords.x;
+				for(var i = 0; i < length; i++){
+					if(x < areas[i].coords.x){
+						for(var j = length-1; j >= i; j--)
+							areas[j + 1] = areas[j];
+						areas[i] = object;
+						break;
+					}
 				}
-				else if(i == length-1){
-					area.coords.x1 = areaList[i-1].coords.x2;
+				if(i == length){
+					areas.push(object);
 				}
-				else{
-					nextArea = areaList[i+1];
-					this._updateArea(nextArea);
-					currentRight = area.coords.x + area.node.offsetWidth;
-					nextLeft = nextArea.coords.x;
-					area.coords.x1 = areaList[i-1].coords.x2;
-					area.coords.x2 = currentRight + (nextLeft-currentRight)/2;
+			}
+			return areas;	// Array
+		},
+	
+		updateAreas: function(/*Array*/areaList){
+			// summary:
+			//		Refresh intervals between areas to determinate the nearest area to drop an item.
+			//		Algorithm :
+			//		the marker should be the vertical line passing by the
+			//		central point between two contiguous areas.
+			//		Note:
+			//		If the page has only one targetArea, it's not necessary to calculate coords.
+			// areaList:
+			//		array of areas
+	
+			//console.log("dojox.mdnd.dropMode.VerticalDropMode ::: initAreas");
+			var length = areaList.length;
+			if(length > 1){
+				var currentRight, nextLeft;
+				for(var i = 0; i < length; i++){
+					var area = areaList[i];
+					var nextArea;
+					area.coords.x1 = -1;
+					area.coords.x2 = -1;
+					if(i == 0){
+						nextArea = areaList[i+1];
+						this._updateArea(area);
+						this._updateArea(nextArea);
+						currentRight = area.coords.x + area.node.offsetWidth;
+						nextLeft = nextArea.coords.x;
+						area.coords.x2 = currentRight + (nextLeft-currentRight)/2;
+					}
+					else if(i == length-1){
+						area.coords.x1 = areaList[i-1].coords.x2;
+					}
+					else{
+						nextArea = areaList[i+1];
+						this._updateArea(nextArea);
+						currentRight = area.coords.x + area.node.offsetWidth;
+						nextLeft = nextArea.coords.x;
+						area.coords.x1 = areaList[i-1].coords.x2;
+						area.coords.x2 = currentRight + (nextLeft-currentRight)/2;
+					}
 				}
 			}
-		}
-	},
-
-	_updateArea : function(/*Object*/area){
-		// summary:
-		//		update the DnD area object (i.e. update coordinates of its DOM node)
-		// area:
-		//		the DnD area
-		// tags:
-		//		protected
-
-		//console.log("dojox.mdnd.dropMode.VerticalDropMode  ::: _updateArea");
-		var position = dojo.position(area.node, true);
-		area.coords.x = position.x;
-		area.coords.y = position.y;
-	},
-
-	initItems: function(/*Object*/area){
-		// summary:
-		//		initialize the horizontal line in order to determinate the drop zone.
-		// area:
-		//		the DnD area
-
-		//console.log("dojox.mdnd.dropMode.VerticalDropMode ::: initItems");
-		dojo.forEach(area.items, function(obj){
-			//get the vertical middle of the item
-			var node = obj.item.node;
-			var position = dojo.position(node, true);
-			var y = position.y + position.h/2;
-			obj.y = y;
-		});
-		area.initItems = true;
-	},
-
-	refreshItems: function(/*Object*/area, /*Integer*/indexItem, /*Object*/size, /*Boolean*/added){
-		// summary:
-		//		take into account the drop indicator DOM element in order to compute horizontal lines
-		// area:
-		//		a DnD area object
-		// indexItem:
-		// 		index of a draggable item
-		// size:
-		//		dropIndicator size
-		// added:
-		//		boolean to know if a dropIndicator has been added or deleted
-
-		//console.log("dojox.mdnd.dropMode.VerticalDropMode ::: refreshItems");
-		if(indexItem == -1){
-			return;
-		}
-		else if(area && size && size.h){
-			var height = size.h;
-			if(area.margin){
-				height += area.margin.t;
+		},
+	
+		_updateArea : function(/*Object*/area){
+			// summary:
+			//		update the DnD area object (i.e. update coordinates of its DOM node)
+			// area:
+			//		the DnD area
+			// tags:
+			//		protected
+	
+			//console.log("dojox.mdnd.dropMode.VerticalDropMode  ::: _updateArea");
+			var position = dojo.position(area.node, true);
+			area.coords.x = position.x;
+			area.coords.y = position.y;
+		},
+	
+		initItems: function(/*Object*/area){
+			// summary:
+			//		initialize the horizontal line in order to determinate the drop zone.
+			// area:
+			//		the DnD area
+	
+			//console.log("dojox.mdnd.dropMode.VerticalDropMode ::: initItems");
+			dojo.forEach(area.items, function(obj){
+				//get the vertical middle of the item
+				var node = obj.item.node;
+				var position = dojo.position(node, true);
+				var y = position.y + position.h/2;
+				obj.y = y;
+			});
+			area.initItems = true;
+		},
+	
+		refreshItems: function(/*Object*/area, /*Integer*/indexItem, /*Object*/size, /*Boolean*/added){
+			// summary:
+			//		take into account the drop indicator DOM element in order to compute horizontal lines
+			// area:
+			//		a DnD area object
+			// indexItem:
+			// 		index of a draggable item
+			// size:
+			//		dropIndicator size
+			// added:
+			//		boolean to know if a dropIndicator has been added or deleted
+	
+			//console.log("dojox.mdnd.dropMode.VerticalDropMode ::: refreshItems");
+			if(indexItem == -1){
+				return;
 			}
-			var length = area.items.length;
-			for(var i = indexItem; i < length; i++){
-				var item = area.items[i];
-				if(added){
-					item.y += height;
+			else if(area && size && size.h){
+				var height = size.h;
+				if(area.margin){
+					height += area.margin.t;
 				}
-				else{
-					item.y -= height;
+				var length = area.items.length;
+				for(var i = indexItem; i < length; i++){
+					var item = area.items[i];
+					if(added){
+						item.y += height;
+					}
+					else{
+						item.y -= height;
+					}
 				}
 			}
-		}
-	},
-
-	getDragPoint: function(/*Object*/coords, /*Object*/size, /*Object*/mousePosition){
-		// summary:
-		//		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
-		// coords:
-		//		an object encapsulating X and Y position
-		// size:
-		//		an object encapsulating width and height values
-		// mousePosition:
-		//		coordinates of mouse
-		// returns:
-		//		an object of coordinates
-		// 		example : {'x':10,'y':10}
-
-		//console.log("dojox.mdnd.dropMode.VerticalDropMode ::: getDragPoint");
-		var y = coords.y;
-		if(this._oldYPoint){
-			if(y > this._oldYPoint){
-				this._oldBehaviour = "down";
-				y += size.h;
-			}
-			else
-				if(y <= this._oldYPoint){
-					this._oldBehaviour = "up";
+		},
+	
+		getDragPoint: function(/*Object*/coords, /*Object*/size, /*Object*/mousePosition){
+			// summary:
+			//		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
+			// coords:
+			//		an object encapsulating X and Y position
+			// size:
+			//		an object encapsulating width and height values
+			// mousePosition:
+			//		coordinates of mouse
+			// returns:
+			//		an object of coordinates
+			// 		example : {'x':10,'y':10}
+	
+			//console.log("dojox.mdnd.dropMode.VerticalDropMode ::: getDragPoint");
+			var y = coords.y;
+			if(this._oldYPoint){
+				if(y > this._oldYPoint){
+					this._oldBehaviour = "down";
+					y += size.h;
 				}
-		}
-		this._oldYPoint = y;
-		return {
-			'x': coords.x + (size.w / 2),
-			'y': y
-			};	// Object
-	},
-
-	getTargetArea: function(/*Array*/areaList, /*Object*/ coords, /*integer*/currentIndexArea ){
-		// summary:
-		//		get the nearest DnD area.
-		//		Coordinates are basically provided by the <getDragPoint> method.
-		// areaList:
-		//		a list of DnD areas objects
-		// coords:
-		//		coordinates [x,y] of the dragItem
-		// currentIndexArea:
-		//		an index representing the active DnD area
-		// returns:
-		//		the index of the DnD area
-
-		//console.log("dojox.mdnd.dropMode.VerticalDropMode ::: getTargetArea");
-		var index = 0;
-		var x = coords.x;
-		var end = areaList.length;
-		if(end > 1){
-			var start = 0, direction = "right", compute = false;
-			if(currentIndexArea == -1 || arguments.length < 3){
-				// first time : Need to search the nearest area in all areas.
-				compute = true;
+				else
+					if(y <= this._oldYPoint){
+						this._oldBehaviour = "up";
+					}
 			}
-			else{
-				// check if it's always the same area
-				if(this._checkInterval(areaList, currentIndexArea, x)){
-					index = currentIndexArea;
+			this._oldYPoint = y;
+			return {
+				'x': coords.x + (size.w / 2),
+				'y': y
+				};	// Object
+		},
+	
+		getTargetArea: function(/*Array*/areaList, /*Object*/ coords, /*integer*/currentIndexArea ){
+			// summary:
+			//		get the nearest DnD area.
+			//		Coordinates are basically provided by the <getDragPoint> method.
+			// areaList:
+			//		a list of DnD areas objects
+			// coords:
+			//		coordinates [x,y] of the dragItem
+			// currentIndexArea:
+			//		an index representing the active DnD area
+			// returns:
+			//		the index of the DnD area
+	
+			//console.log("dojox.mdnd.dropMode.VerticalDropMode ::: getTargetArea");
+			var index = 0;
+			var x = coords.x;
+			var end = areaList.length;
+			if(end > 1){
+				var start = 0, direction = "right", compute = false;
+				if(currentIndexArea == -1 || arguments.length < 3){
+					// first time : Need to search the nearest area in all areas.
+					compute = true;
 				}
 				else{
-					if(this._oldXPoint < x){
-						start = currentIndexArea + 1;
+					// check if it's always the same area
+					if(this._checkInterval(areaList, currentIndexArea, x)){
+						index = currentIndexArea;
 					}
 					else{
-						start = currentIndexArea - 1;
-						end = 0;
-						direction = "left";
+						if(this._oldXPoint < x){
+							start = currentIndexArea + 1;
+						}
+						else{
+							start = currentIndexArea - 1;
+							end = 0;
+							direction = "left";
+						}
+						compute = true;
 					}
-					compute = true;
 				}
-			}
-			if(compute){
-				if(direction === "right"){
-					for(var i = start; i < end; i++){
-						if(this._checkInterval(areaList, i, x)){
-							index = i;
-							break;
+				if(compute){
+					if(direction === "right"){
+						for(var i = start; i < end; i++){
+							if(this._checkInterval(areaList, i, x)){
+								index = i;
+								break;
+							}
 						}
 					}
-				}
-				else{
-					for(var i = start; i >= end; i--){
-						if(this._checkInterval(areaList, i, x)){
-							index = i;
-							break;
+					else{
+						for(var i = start; i >= end; i--){
+							if(this._checkInterval(areaList, i, x)){
+								index = i;
+								break;
+							}
 						}
 					}
 				}
 			}
-		}
-		this._oldXPoint = x;
-		return index;	// Integer
-	},
-
-	_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.
-		// areaList:
-		//		a list of DnD areas objects
-		// index:
-		//		index of a DnD area (to get the interval)
-		// x:
-		//		coordinate x, of the dragNode
-		// returns:
-		//		true if the dragNode is in intervall
-		// tags:
-		//		protected
-		var coords = areaList[index].coords;
-		if(coords.x1 == -1){
-			if(x <= coords.x2){
-				return true;
-			}
-		}
-		else
-			if(coords.x2 == -1){
-				if(x > coords.x1){
-					return true;
-				}
-			}
-			else{
-				if(coords.x1 < x && x <= coords.x2){
+			this._oldXPoint = x;
+			return index;	// Integer
+		},
+	
+		_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.
+			// areaList:
+			//		a list of DnD areas objects
+			// index:
+			//		index of a DnD area (to get the interval)
+			// x:
+			//		coordinate x, of the dragNode
+			// returns:
+			//		true if the dragNode is in intervall
+			// tags:
+			//		protected
+			var coords = areaList[index].coords;
+			if(coords.x1 == -1){
+				if(x <= coords.x2){
 					return true;
 				}
 			}
-		return false;	// Boolean
-	},
-
-	getDropIndex: function(/*Object*/ targetArea, /*Object*/ coords){
-		// summary:
-		//		Return the index where the drop has to be placed.
-		// targetArea:
-		//		a DnD area object
-		// coords:
-		//		coordinates [x,y] of the draggable item
-		// returns:
-		// 		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");
-		var length = targetArea.items.length;
-		var coordinates = targetArea.coords;
-		var y = coords.y;
-		if(length > 0){
-			// course all children in the target area.
-			for(var i = 0; i < length; i++){
-				// compare y value with y value of children
-				if(y < targetArea.items[i].y){
-					return i;	// Integer
+			else
+				if(coords.x2 == -1){
+					if(x > coords.x1){
+						return true;
+					}
 				}
 				else{
-					if(i == length-1){
-						return -1;
+					if(coords.x1 < x && x <= coords.x2){
+						return true;
+					}
+				}
+			return false;	// Boolean
+		},
+	
+		getDropIndex: function(/*Object*/ targetArea, /*Object*/ coords){
+			// summary:
+			//		Return the index where the drop has to be placed.
+			// targetArea:
+			//		a DnD area object
+			// coords:
+			//		coordinates [x,y] of the draggable item
+			// returns:
+			// 		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");
+			var length = targetArea.items.length;
+			var coordinates = targetArea.coords;
+			var y = coords.y;
+			if(length > 0){
+				// course all children in the target area.
+				for(var i = 0; i < length; i++){
+					// compare y value with y value of children
+					if(y < targetArea.items[i].y){
+						return i;	// Integer
+					}
+					else{
+						if(i == length-1){
+							return -1;
+						}
 					}
 				}
 			}
+			return -1;
+		},
+	
+		destroy: function(){
+			//	can be overwritten.
 		}
-		return -1;
-	},
-
-	destroy: function(){
-		//	can be overwritten.
-	}
-});
-
-//------------
-//Singleton
-//------------
-(function(){
+	});
+	
+	//------------
+	//Singleton
+	//------------
 	dojox.mdnd.areaManager()._dropMode = new dojox.mdnd.dropMode.VerticalDropMode();
-}());
\ No newline at end of file
+	return vdm;
+});
diff --git a/dojox/mdnd/tests/module.js b/dojox/mdnd/tests/module.js
index 5bf31db..af3c1fe 100644
--- a/dojox/mdnd/tests/module.js
+++ b/dojox/mdnd/tests/module.js
@@ -6,11 +6,3 @@ try{
 }catch(e){
 	doh.debug(e);
 }
-dojo.provide("dojox.mdnd.tests.module");
-
-try{
-	dojo.require("dojox.mdnd.tests.unitTests.module");
-	dojo.require("dojox.mdnd.tests.robot.module");
-}catch(e){
-	doh.debug(e);
-}
diff --git a/dojox/mdnd/tests/robot/test_dnd_acceptance.html b/dojox/mdnd/tests/robot/test_dnd_acceptance.html
index 24b6a31..1f48b5d 100644
--- a/dojox/mdnd/tests/robot/test_dnd_acceptance.html
+++ b/dojox/mdnd/tests/robot/test_dnd_acceptance.html
@@ -4,155 +4,12 @@
 		
 		<script type="text/javascript" 
 			src="../../../../dojo/dojo.js" 
-			djConfig="isDebug: true, parseOnLoad: true">
+			djConfig="isDebug: true">
 		</script>
 		
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");	
-			dojo.require("dojo.parser");
-			
-			dojo.addOnLoad(function(){			
-				
-				doh.robot.initRobot('../functionalTests/test_dnd_acceptance.html');
-				doh.register("test_dnd_acceptance", 
-					[
-						{
-							name: "dropAccepted",
-							timeout:10000,
-							runTest: function(){
-
-								// Tries to drag and drop an item between two dnd 
-								// area :
-								// 		- Item's type : 1
-								//		- Drop area accept types : 1 & 2
-								// -> In this case, drop is accepted
-
-								var d = new doh.Deferred();
-
-								var areaType1 = dojo.query('.dndArea[accept=type1]')[0];
-								var areaTypeAll = dojo.query('.dndArea[accept*=type1][accept*=type2]')[0];
-
-								var itemType1 =	dojo.query('.dndItem[dndType=type1] > .dragHandle')[0];
-								var itemTypeAll = dojo.query('.dndItem[dndType*=type1][dndType*=type2] > .dragHandle')[0];
-								
-								var sizeA = areaType1.childNodes.length;
-	                			var sizeB = areaTypeAll.childNodes.length;
-	                			
-	                			doh.robot.mouseMoveAt(itemType1,200);
-	                			doh.robot.mousePress({left:true}, 200);
-	                			doh.robot.mouseMoveAt(areaTypeAll,200);
-	                			doh.robot.mouseRelease({left:true}, 200);
-	                			
-	                			doh.robot.sequence(function(){
-	                				try{
-	                					doh.assertEqual(areaTypeAll.childNodes.length, sizeB + 1, "An item should be drop on third area.");
-	                					doh.assertEqual(areaType1.childNodes.length, sizeA - 1, "An item should be remove from first area");
-	                					d.callback(true);
-	                				}
-	                				catch(e){
-	                					d.errback(e);
-	                				}
-	               				}, 200);
-	               				return d;
-							}
-						},
-						{
-							name: "dropAccepted2",
-							timeout:10000,
-							runTest: function(){
-
-								// Tries to drag and drop an item between two dnd area.
-								// 		- Item's type : 1 & 2
-								//		- Drop area accept type : 2
-								// -> In this case, drop is accepted
-
-								var d = new doh.Deferred();
-
-								var areaType2 = dojo.query('.dndArea[accept=type2]')[0];
-								var areaTypeAll = dojo.query('.dndArea[accept*=type1][accept*=type2]')[0];
-
-								var itemTypeAll = dojo.query('.dndItem[dndType*=type1][dndType*=type2] > .dragHandle')[0];
-
-	                			var sizeA = areaTypeAll.childNodes.length;
-								var sizeB = areaType2.childNodes.length;
-	                			
-	                			doh.robot.mouseMoveAt(itemTypeAll, 200);
-	                			doh.robot.mousePress({left:true}, 200);
-	                			doh.robot.mouseMoveAt(areaType2, 200);
-	                			doh.robot.mouseRelease({left:true}, 200);
-	                			
-	                			doh.robot.sequence(function(){
-	                				try{
-		                				doh.assertEqual(areaType2.childNodes.length, sizeB + 1, "An item should be drop on second area.");
-		                				doh.assertEqual(areaTypeAll.childNodes.length, sizeA - 1, "An item should be remove from third area.");
-		                      			d.callback(true);
-		                      		}catch(e){
-		                      			d.errback(e);
-		                      		}
-	               				}, 200);
-	               				return d;
-							}
-						},
-						{
-							name: "refused",
-							timeout:10000,
-							runTest: function(){
 
-								// Tries to drag and drop an item between two dnd area.
-								// 		- Item's type : 1
-								//		- Drop area accept type : 2
-								// -> In this case, drop is refused
-
-								var d = new doh.Deferred();
-
-								var areaType2 = dojo.query('.dndArea[accept=type2]')[0];
-								var areaTypeAll = dojo.query('.dndArea[accept*=type1][accept*=type2]')[0];
-
-								var itemType1 = dojo.query('.dndItem[dndType=type1] > .dragHandle')[0];
-								
-								var sizeA = areaType2.childNodes.length;
-	                			var sizeB = areaTypeAll.childNodes.length;
-	                			
-	                			doh.robot.mouseMoveAt(itemType1, 200);
-	                			doh.robot.mousePress({left:true}, 200);
-	                			doh.robot.mouseMoveAt(areaType2, 200);
-	                			doh.robot.mouseRelease({left:true}, 200);
-	                			
-	                			doh.robot.sequence(function(){
-	                				try{
-		                				doh.assertEqual(areaType2.childNodes.length, sizeA, "No change !");
-		                				doh.assertEqual(areaTypeAll.childNodes.length, sizeB, "No change !");
-		                      			d.callback(true);
-		                      		}catch(e){
-		                      			d.errback(e);
-		                      		}
-	               				 }, 200);
-	               				 return d;
-							}
-						}
-					]
-				);
-				doh.run();
-			});
-		</script>
-		<style type="text/css"></style>
-	</head>
-	<body class="tundra">
-	</body>
-</html>
-<html>
-	<head>
-		<title>Robot - Acceptance</title>
-		
-		<script type="text/javascript" 
-			src="../../../../dojo/dojo.js" 
-			djConfig="isDebug: true, parseOnLoad: true">
-		</script>
-		
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");	
-			dojo.require("dojo.parser");
-			
 			dojo.addOnLoad(function(){			
 				
 				doh.robot.initRobot('../functionalTests/test_dnd_acceptance.html');
@@ -279,6 +136,6 @@
 		</script>
 		<style type="text/css"></style>
 	</head>
-	<body class="tundra">
+	<body>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/dojox/mdnd/tests/robot/test_dnd_defaultDropMode.html b/dojox/mdnd/tests/robot/test_dnd_defaultDropMode.html
index b122eb2..88460c3 100644
--- a/dojox/mdnd/tests/robot/test_dnd_defaultDropMode.html
+++ b/dojox/mdnd/tests/robot/test_dnd_defaultDropMode.html
@@ -4,14 +4,12 @@
 		
 		<script type="text/javascript" 
 			src="../../../../dojo/dojo.js" 
-			djConfig="isDebug: true, parseOnLoad: true">
+			djConfig="isDebug: true">
 		</script>
 		
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");	
-			dojo.require("dojo.parser");
-			dojo.require("dojox.mdnd.dropMode.DefaultDropMode");
-			
+
 			dojo.addOnLoad(function(){			
 				
 				doh.robot.initRobot('../functionalTests/test_dnd_defaultDropMode.html');
@@ -96,6 +94,6 @@
 		</script>
 		<style type="text/css"></style>
 	</head>
-	<body class="tundra">
+	<body>
 	</body>
 </html>
\ No newline at end of file
diff --git a/dojox/mdnd/tests/robot/test_dnd_dndFromDojo.html b/dojox/mdnd/tests/robot/test_dnd_dndFromDojo.html
index 1afa12e..04179a2 100644
--- a/dojox/mdnd/tests/robot/test_dnd_dndFromDojo.html
+++ b/dojox/mdnd/tests/robot/test_dnd_dndFromDojo.html
@@ -4,174 +4,12 @@
 		
 		<script type="text/javascript" 
 			src="../../../../dojo/dojo.js" 
-			djConfig="isDebug: true, parseOnLoad: true">
+			djConfig="isDebug: true">
 		</script>
 		
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");	
-			dojo.require("dojo.parser");
-			
-			dojo.addOnLoad(function(){			
-				
-				doh.robot.initRobot('../functionalTests/test_dnd_dndFromDojo.html');
-				
-				doh.register("test_dnd_dndFromDojo", 
-				[
-					{
-						name: "dndFromPureSource",
-						timeout:6000,
-						runTest: function(){
 
-							// Moves an item from a dojo source to a dojox 
-							// target.
-
-							var d = new doh.Deferred();
-
-							var itemType1 = dojo.query("#dojoPureSource > [dndType*=type1]")[0];
-							var area = dojo.query(".dndArea")[0];
-
-							var sizeArea = area.childNodes.length
-							doh.robot.mouseMoveAt(itemType1, 100);
-                			doh.robot.mousePress({left:true}, 100);
-                			doh.robot.mouseMoveAt(area, 100);
-                			doh.robot.mouseRelease({left:true}, 100);
-                			
-                			doh.robot.sequence(function(){
-                				try{
-                					doh.assertEqual(area.childNodes.length ,sizeArea + 1, "A child should be drop in the dojox area.");
-                					d.callback(true);
-                				}
-                				catch(e){
-                					d.errback(e);
-                				}
-               				}, 100);
-               				return d;
-						}
-					},
-					{
-						name: "dndFromDojoSource",
-						timeout:10000,
-						runTest: function(){
-
-							// Moves an item from a dojo source/target to a 
-							// dojox target.
-
-							var d = new doh.Deferred();
-
-							var itemType1 = dojo.query("#dojoSource > [dndType*=type1]")[0];
-							var area = dojo.query(".dndArea")[0];
-
-							var sizeArea = area.childNodes.length
-							doh.robot.mouseMoveAt(itemType1, 200);
-                			doh.robot.mousePress({left:true}, 200);
-                			doh.robot.mouseMoveAt(area, 200);
-                			doh.robot.mouseRelease({left:true}, 200);
-                			
-                			doh.robot.sequence(function(){
-                				try{
-                					doh.assertEqual(area.childNodes.length ,sizeArea + 1, "A child should be drop in the dojox area.");
-                					d.callback(true);
-                				}
-                				catch(e){
-                					d.errback(e);
-                				}
-               				}, 200);
-               				return d;
-						}
-					},
-					{
-						name: "dndAcceptanceFromPureSource",
-						timeout:10000,
-						runTest: function(){
-
-							// Tries to move an item from  a dojo source to a 
-							// dojox areas :
-							// 		- Item's type : 2
-							//		- Drop area accept types : 1
-							// -> In this case, drop is refused
-
-							var d = new doh.Deferred();
-
-							var itemType2 = dojo.query("#dojoPureSource > [dndType*=type2]")[0];
-							var area = dojo.query(".dndArea")[0];
-
-							var sizeArea = area.childNodes.length
-							doh.robot.mouseMoveAt(itemType2, 200);
-                			doh.robot.mousePress({left:true}, 200);
-                			doh.robot.mouseMoveAt(area, 200);
-                			doh.robot.mouseRelease({left:true}, 200);
-                			
-                			doh.robot.sequence(function(){
-                				try{
-                					doh.assertEqual(area.childNodes.length ,sizeArea, "A type 2 item should not be drop in the dojox area.");
-                					d.callback(true);
-                				}
-                				catch(e){
-                					d.errback(e);
-                				}
-               				}, 200);
-               				return d;
-						}
-					},
-					{
-						name: "dndAcceptanceFromDojoSource",
-						timeout:10000,
-						runTest: function(){
-
-							// Tries to move an item from  a dojo source/target
-							// to a dojox area :
-							// 		- Item's type : 2
-							//		- Drop area accept types : 1
-							// -> In this case, drop is refused
-
-							var d = new doh.Deferred();
-
-							var itemType2 = dojo.query("#dojoSource > [dndType*=type2]")[0];
-							var area = dojo.query(".dndArea")[0];
-
-							var sizeArea = area.childNodes.length
-							
-							doh.robot.mouseMoveAt(itemType2, 200);
-                			doh.robot.mousePress({left:true}, 200);
-                			doh.robot.mouseMoveAt(area, 200);
-                			doh.robot.mouseRelease({left:true}, 200);
-                			
-                			doh.robot.sequence(function(){
-                				try{
-                					doh.assertEqual(area.childNodes.length ,sizeArea, "A type 2 item should not be drop in the dojox area.");
-                					d.callback(true);
-                				}
-                				catch(e){
-                					d.errback(e);
-                				}
-               				}, 200);
-                			doh.robot.mouseRelease({left:true}, 200);
-               				return d;
-						}
-					}
-				]
-				);
-				doh.run();
-			});
-		</script>
-		<style type="text/css"></style>
-	</head>
-	<body class="tundra">
-	</body>
-</html>
-<html>
-	<head>
-		<title>Robot - Adapter - DndFromDojo</title>
-		
-		<script type="text/javascript" 
-			src="../../../../dojo/dojo.js" 
-			djConfig="isDebug: true, parseOnLoad: true">
-		</script>
-		
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");	
-			dojo.require("dojo.parser");
-			
 			dojo.addOnLoad(function(){			
 				
 				doh.robot.initRobot('../functionalTests/test_dnd_dndFromDojo.html');
@@ -317,6 +155,6 @@
 		</script>
 		<style type="text/css"></style>
 	</head>
-	<body class="tundra">
+	<body>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/dojox/mdnd/tests/robot/test_dnd_dndToDojo.html b/dojox/mdnd/tests/robot/test_dnd_dndToDojo.html
index ccdeeb7..d52bf95 100644
--- a/dojox/mdnd/tests/robot/test_dnd_dndToDojo.html
+++ b/dojox/mdnd/tests/robot/test_dnd_dndToDojo.html
@@ -4,112 +4,12 @@
 		
 		<script type="text/javascript" 
 			src="../../../../dojo/dojo.js" 
-			djConfig="isDebug: true, parseOnLoad: true">
+			djConfig="isDebug: true">
 		</script>
 		
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");	
-			dojo.require("dojo.parser");
-			
-			dojo.addOnLoad(function(){			
-				
-				doh.robot.initRobot('../functionalTests/test_dnd_dndToDojo.html');
-				
-				doh.register("test_dnd_dndToDojo", 
-				[
-					{
-						name: "dndToDojoSource",
-						timeout:10000,
-						runTest: function(){
-
-							// Moves an item from a dojox source to a dojo
-							// target.
-
-							var d = new doh.Deferred();
-
-							var itemType1 = dojo.query(".dndItem[dndType=type1] > .dragHandle")[0];
-							var source = dojo.query(".dndArea")[0];
-							var dojoTarget = dojo.query(".dojoDndTarget")[0];
-
-							var sizeArea = source.childNodes.length
-							
-							doh.robot.mouseMoveAt(itemType1, 200);
-                			doh.robot.mousePress({left:true}, 200);
-                			doh.robot.mouseMoveAt(dojoTarget, 200);
-                			doh.robot.mouseRelease({left:true}, 200);
-                			
-                			doh.robot.sequence(function(){
-                				try{
-                					doh.assertEqual(source.childNodes.length , sizeArea-1, "A child should be delete from dojox dnd area.");
-                					d.callback(true);
-                				}
-                				catch(e){
-                					d.errback(e);
-                				}
-               				}, 200);
-               				return d;
-						}
-					},
-					{
-						name: "dndToDojoAcceptance",
-						timeout:10000,
-						runTest: function(){
 
-							// Tries to move an item from a dojox source to
-							// a dojo area :
-							// 		- Item's type : 2
-							//		- Drop area accept types : 1
-							// -> In this case, drop is refused
-
-							var d = new doh.Deferred();
-							
-							var itemType2 = dojo.query(".dndItem[dndType=type2] > .dragHandle")[0];
-							var source = dojo.query(".dndArea")[0];
-							var dojoTarget = dojo.query(".dojoDndTarget")[0];
-
-							var sizeArea = source.childNodes.length
-							
-							doh.robot.mouseMoveAt(itemType2, 200);
-                			doh.robot.mousePress({left:true}, 200);
-                			doh.robot.mouseMoveAt(dojoTarget, 200);
-                			doh.robot.mouseRelease({left:true}, 200);
-                			
-                			doh.robot.sequence(function(){
-                				try{
-                					doh.assertEqual(source.childNodes.length ,sizeArea, "DnD restriction. No change !");
-                					d.callback(true);
-                				}
-                				catch(e){
-                					d.errback(e);
-                				}
-               				}, 200);
-               				
-               				return d;
-						}
-					}
-				]
-				);
-				doh.run();
-			});
-		</script>
-		<style type="text/css"></style>
-	</head>
-	<body class="tundra">
-	</body>
-</html>
-<html>
-	<head>
-		<title>Robot - Adapter - DndFromDojo</title>
-		
-		<script type="text/javascript" 
-			src="../../../../dojo/dojo.js" 
-			djConfig="isDebug: true, parseOnLoad: true">
-		</script>
-		
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");	
-			dojo.require("dojo.parser");
-			
 			dojo.addOnLoad(function(){			
 				
 				doh.robot.initRobot('../functionalTests/test_dnd_dndToDojo.html');
@@ -193,6 +93,6 @@
 		</script>
 		<style type="text/css"></style>
 	</head>
-	<body class="tundra">
+	<body>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/dojox/mdnd/tests/robot/test_dnd_overDropMode.html b/dojox/mdnd/tests/robot/test_dnd_overDropMode.html
index c6c4bd6..ad08492 100644
--- a/dojox/mdnd/tests/robot/test_dnd_overDropMode.html
+++ b/dojox/mdnd/tests/robot/test_dnd_overDropMode.html
@@ -4,7 +4,7 @@
 		
 		<script type="text/javascript" 
 			src="../../../../dojo/dojo.js" 
-			djConfig="isDebug: true, parseOnLoad: true">
+			djConfig="isDebug: true">
 		</script>
 		
 		<script type="text/javascript">
@@ -131,142 +131,6 @@
 			});
 		</script>
 	</head>
-	<body class="tundra">
+	<body>
 	</body>
 </html>
-<html>	
-	<head>
-		<title>OverDropMode</title>
-		
-		<script type="text/javascript" 
-			src="../../../../dojo/dojo.js" 
-			djConfig="isDebug: true, parseOnLoad: true">
-		</script>
-		
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");	
-			
-			dojo.addOnLoad(function(){			
-				
-				doh.robot.initRobot('../functionalTests/test_dnd_overDropMode.html');
-				
-				doh.register("test_dnd_overDropMode", 
-					[
-						{
-							name: "horizontalMovement",
-							timeout:10000,
-							runTest: function(){
-
-								// Tries to drag and drop an item between 
-								// horizontal Dnd areas.
-
-								var d = new doh.Deferred();
-
-								var topLefArea = dojo.byId('topLeftArea');
-								var topRightArea = dojo.byId('topRightArea');
-
-								var itemA = dojo.query('#itemA > .dragHandle')[0];
-								
-								var sizeA = topLefArea.childNodes.length;
-	                			var sizeB = topRightArea.childNodes.length;
-	                			
-	                			doh.robot.mouseMoveAt(itemA,200);
-	                			doh.robot.mousePress({left:true}, 200);
-	                			doh.robot.mouseMoveAt(topRightArea,200);
-	                			doh.robot.mouseRelease({left:true}, 200);
-	                			
-	                			doh.robot.sequence(function(){
-	                				try{
-	                					doh.assertEqual(topRightArea.childNodes.length, sizeB + 1, 'Item should be drop on top right area.');
-	                					doh.assertEqual(topLefArea.childNodes.length, sizeA - 1, 'Item should be remove from top left area.');
-	                					d.callback(true);
-	                				}
-	                				catch(e){
-	                					d.errback(e);
-	                				}
-	               				}, 200);
-	               				return d;
-							}
-						},
-						{
-							name: "verticalMovement",
-							timeout:10000,
-							runTest: function(){
-
-								// Tries to drag and drop an item between 
-								// vertical Dnd areas.
-
-								var d = new doh.Deferred();
-
-								var topLefArea = dojo.byId('topLeftArea');
-								var bottomLeftArea = dojo.byId('bottomLeftArea');
-
-								var itemB = dojo.query('#itemB > .dragHandle')[0];
-								
-								var sizeA = bottomLeftArea.childNodes.length;
-	                			var sizeB = topLefArea.childNodes.length;
-	                			
-	                			doh.robot.mouseMoveAt(itemB,200);
-	                			doh.robot.mousePress({left:true}, 200);
-	                			doh.robot.mouseMoveAt(topLefArea,200);
-	                			doh.robot.mouseRelease({left:true}, 200);
-	                			
-	                			doh.robot.sequence(function(){
-	                				try{
-	                					doh.assertEqual(topLefArea.childNodes.length, sizeB + 1, "Item should be drop on top left area.");
-	                					doh.assertEqual(bottomLeftArea.childNodes.length, sizeA - 1, "Item should be remove from botton left area.");
-	                					d.callback(true);
-	                				}
-	                				catch(e){
-	                					d.errback(e);
-	                				}
-	               				}, 200);
-	               				return d;
-							}
-						},
-						{
-							name: "dropIndicator",
-							timeout:10000,
-							runTest: function(){
-							
-								// Checks if the the dropIndicator is displayed.
-							
-								var d = new doh.Deferred();
-
-								var topLefArea = dojo.byId('topLeftArea');
-								var topRightArea = dojo.byId('topRightArea');
-
-								var itemB = dojo.query('#itemB > .dragHandle')[0];
-								
-	                			var sizeA = topLefArea.childNodes.length;
-	                			var sizeB = topRightArea.childNodes.length;
-	                			
-	                			doh.robot.mouseMoveAt(itemB, 200);
-	                			doh.robot.mousePress({left:true}, 200);
-	                			doh.robot.mouseMoveAt(topRightArea, 200);
-	                			
-	    			 			doh.robot.sequence(function(){
-	    			 				try{
-	    			 					doh.assertEqual(topLefArea.childNodes.length, sizeA - 1, "Item should be remove from top left area.");
-	    								doh.assertEqual(topRightArea.childNodes.length, sizeB + 1, "An item should be add to top right area.");
-	    								doh.assertEqual(dojo.query('.dropIndicator').length, 1, "Item added should be a drop indicator.");
-	    								d.callback(true);
-	    							}
-	    							catch(e){
-	    								d.errback(e);
-	    							}
-	   								}, 
-	   							200);
-	    			 			doh.robot.mouseRelease({left:true}, 200);
-	               				return d;
-							}
-						}
-					]
-				);
-				doh.run();
-			});
-		</script>
-	</head>
-	<body class="tundra">
-	</body>
-</html>
\ No newline at end of file
diff --git a/dojox/mdnd/tests/robot/test_dnd_verticalDropMode.html b/dojox/mdnd/tests/robot/test_dnd_verticalDropMode.html
index b9e131f..7877e91 100644
--- a/dojox/mdnd/tests/robot/test_dnd_verticalDropMode.html
+++ b/dojox/mdnd/tests/robot/test_dnd_verticalDropMode.html
@@ -4,14 +4,12 @@
 		
 		<script type="text/javascript" 
 			src="../../../../dojo/dojo.js" 
-			djConfig="isDebug: true, parseOnLoad: true">
+			djConfig="isDebug: true">
 		</script>
 		
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");	
-			dojo.require("dojo.parser");
-			dojo.require("dojox.mdnd.dropMode.VerticalDropMode");
-			
+
 			dojo.addOnLoad(function(){			
 				
 				doh.robot.initRobot('../functionalTests/test_dnd_verticalDropMode.html');
@@ -96,6 +94,6 @@
 		</script>
 		<style type="text/css"></style>
 	</head>
-	<body class="tundra">
+	<body>
 	</body>
 </html>
\ No newline at end of file
diff --git a/dojox/mdnd/tests/unitTests/dropMode/resources/domElement.html b/dojox/mdnd/tests/unitTests/dropMode/resources/domElement.html
index 154fb4b..0b41285 100644
--- a/dojox/mdnd/tests/unitTests/dropMode/resources/domElement.html
+++ b/dojox/mdnd/tests/unitTests/dropMode/resources/domElement.html
@@ -62,69 +62,4 @@
 	<div class="item" id="itemD">Item D <br/>{1000, 100}</div>
 
 </body>
-</html>
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<style>
-	.area{
-		position:absolute;
-		border:1px solid orange;
-		height:200px;
-		width:100px;
-	}
-	.item{
-		position:absolute;
-		border:1px solid pink;
-		height:100px;
-		width:100px;
-	}
-	#areaA{
-		top:50px;
-		left:50px;
-	}
-	#areaB{
-		top:150px;
-		left:200px;
-	}
-	#areaC{
-		top:50px;
-		left:350px;
-	}
-	#areaD{
-		top:10px;
-		left:750px;
-	}
-	
-	#itemA{
-		top:500px;
-		left:50px;
-	}
-	#itemB{
-		top:650px;
-		left:10px;
-	}
-	#itemC{
-		top:800px;
-		left:10px;
-	}
-	#itemD{
-		top:1000px;
-		left:100px;
-	}
-</style>
-</head>
-<body>
-	<div class="area" id="areaA">Area A <br/>{50, 50}</div>
-	<div class="area" id="areaB">Area B <br/>{150, 200}</div>
-	<div class="area" id="areaC">Area C <br/>{50, 350}</div>
-	<div class="area" id="areaD">Area D <br/>{10, 750}</div>
-	
-	<div class="item" id="itemA">Item A <br/>{500, 50}</div>
-	<div class="item" id="itemB">Item B <br/>{650, 10}</div>
-	<div class="item" id="itemC">Item C <br/>{800, 10}</div>
-	<div class="item" id="itemD">Item D <br/>{1000, 100}</div>
-
-</body>
 </html>
\ No newline at end of file
diff --git a/dojox/mobile.js b/dojox/mobile.js
index 439f6f7..63cf910 100755
--- a/dojox/mobile.js
+++ b/dojox/mobile.js
@@ -1,4 +1,8 @@
-dojo.provide("dojox.mobile");
-dojo.require("dojox.mobile._base");
-dojo.experimental("dojox.mobile");
-
+define([
+	".",
+	"dojo/_base/lang",
+	"dojox/mobile/_base"
+], function(dojox, lang, base){
+	lang.getObject("mobile", true, dojox);
+	return dojox.mobile;
+});
diff --git a/dojox/mobile/Button.js b/dojox/mobile/Button.js
new file mode 100644
index 0000000..712b176
--- /dev/null
+++ b/dojox/mobile/Button.js
@@ -0,0 +1,77 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dijit/_WidgetBase",
+	"dijit/form/_ButtonMixin",
+	"dijit/form/_FormWidgetMixin"
+],
+	function(array, declare, domClass, domConstruct, WidgetBase, ButtonMixin, FormWidgetMixin){
+
+	/*=====
+		WidgetBase = dijit._WidgetBase;
+		FormWidgetMixin = dijit.form._FormWidgetMixin;
+		ButtonMixin = dijit.form._ButtonMixin;
+	=====*/
+	return declare("dojox.mobile.Button", [WidgetBase, FormWidgetMixin, ButtonMixin], {
+		// summary:
+		//	Non-templated BUTTON widget with a thin API wrapper for click events and 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.
+		// example:
+		// |    <button dojoType="dijit.form.Button" onClick="...">Hello world</button>
+
+		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: null,
+
+		// duration: Number
+		//	duration of selection, milliseconds or -1 for no post-click CSS styling
+		duration: 1000,
+
+		_onClick: function(e){
+			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(){
+					domClass.remove(button, newStateClasses);
+				}, this.duration);
+			}
+			return ret;
+		},
+
+		isFocusable: function(){ return false; },
+
+		buildRendering: function(){
+			if(!this.srcNodeRef){
+				this.srcNodeRef = domConstruct.create("button", {"type": this.type});
+			}else if(this._cv){
+				var n = this.srcNodeRef.firstChild;
+				if(n && n.nodeType === 3){
+					n.nodeValue = this._cv(n.nodeValue);
+				}
+			}
+			this.inherited(arguments);
+			this.focusNode = this.domNode;
+		},
+
+		postCreate: function(){
+			this.inherited(arguments);
+			this.connect(this.domNode, "onclick", "_onClick");
+		},
+
+		_setLabelAttr: function(/*String*/ content){
+			this.inherited(arguments, [this._cv ? this._cv(content) : content]);
+		}
+	});
+
+});
diff --git a/dojox/mobile/Carousel.js b/dojox/mobile/Carousel.js
new file mode 100644
index 0000000..90ef6cc
--- /dev/null
+++ b/dojox/mobile/Carousel.js
@@ -0,0 +1,322 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/_base/event",
+	"dojo/_base/lang",
+	"dojo/_base/sniff",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+	"dijit/_Contained",
+	"dijit/_Container",
+	"dijit/_WidgetBase",
+	"./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;
+=====*/
+
+	// 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], {
+		// summary:
+		//		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.
+
+		// numVisible: Number
+		//		The number of visible items.
+		numVisible: 3,
+
+		// title: String
+		//		A title of the carousel to be displayed on the title bar.
+		title: "",
+
+		// pageIndicator: Boolean
+		//		If true, a page indicator, a series of small dots that indicate
+		//		the current page, is displayed on the title bar.
+		pageIndicator: true,
+
+		// navButton: Boolean
+		//		If true, navigation buttons are displyaed on the title bar.
+		navButton: false,
+
+		// height: String
+		//		Explicitly specified height of the widget (ex. "300px"). If
+		//		"inherit" is specified, the height is inherited from its offset
+		//		parent.
+		height: "300px",
+
+		// 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,
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			this.domNode.className = "mblCarousel";
+			var h;
+			if(this.height === "inherit"){
+				if(this.domNode.offsetParent){
+					h = this.domNode.offsetParent.offsetHeight + "px";
+				}
+			}else if(this.height){
+				h = this.height;
+			}
+			this.domNode.style.height = h;
+			this.headerNode = domConstruct.create("DIV", {className:"mblCarouselHeaderBar"}, this.domNode);
+
+			if(this.navButton){
+				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", {
+					className: "mblCarouselBtn",
+					title: "Previous",
+					innerHTML: "<"
+				}, this.btnContainerNode);
+				this.nextBtnNode = domConstruct.create("BUTTON", {
+					className: "mblCarouselBtn",
+					title: "Next",
+					innerHTML: ">"
+				}, this.btnContainerNode);
+				this.connect(this.prevBtnNode, "onclick", "onPrevBtnClick");
+				this.connect(this.nextBtnNode, "onclick", "onNextBtnClick");
+			}
+
+			if(this.pageIndicator){
+				if(!this.title){
+					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", {
+				className: "mblCarouselTitle"
+			}, this.headerNode);
+
+			this.containerNode = domConstruct.create("DIV", {className:"mblCarouselPages"}, this.domNode);
+			connect.subscribe("/dojox/mobile/viewChanged", this, "handleViewChanged");
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+			if(this.store){
+				var store = this.store;
+				this.store = null;
+				this.setStore(store, this.query, this.queryOptions);
+			}
+			this.inherited(arguments);
+		},
+
+		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;
+			this.refresh();
+		},
+
+		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")
+			});
+		},
+
+		generate: function(/*Array*/items, /*Object*/ dataObject){
+			array.forEach(this.getChildren(), function(child){
+				if(child instanceof SwapView){
+					child.destroyRecursive();
+				}
+			});
+			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"});
+				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(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();
+			}
+		},
+
+		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;
+		},
+
+		createHeaderText: function(item){
+			this.headerTextNode = domConstruct.create("DIV", {
+				className: "mblCarouselImgHeaderText",
+				innerHTML: item.headerText ? item.headerText : " "
+			});
+			return this.headerTextNode;
+		},
+
+		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;
+		},
+
+		createFooterText: function(item){
+			this.footerTextNode = domConstruct.create("DIV", {
+				className: "mblCarouselImgFooterText",
+				innerHTML: item.footerText ? item.footerText : " "
+			});
+			return this.footerTextNode;
+		},
+
+		resizeContent: function(item, box, img){
+			if(item.height !== "1px"){
+				img.style.height = (box.offsetHeight  - this.headerTextNode.offsetHeight - this.footerTextNode.offsetHeight) + "px";
+			}
+		},
+
+		onError: function(errText){
+		},
+
+		onPrevBtnClick: function(e){
+			if(this.currentView){
+				this.currentView.goTo(-1);
+			}
+		},
+
+		onNextBtnClick: function(e){
+			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");
+				}
+			}
+			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]);
+		},
+
+		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;
+				}
+			}, this);
+		},
+
+		handleViewChanged: function(view){
+			if(view.getParent() !== this){ return; }
+			this.currentView = view;
+			// lazy-load images in the next view
+			this.loadImages(view.nextView(view.domNode));
+		},
+
+		_setTitleAttr: function(/*String*/title){
+			this.title = title;
+			this.titleNode.innerHTML = this._cv ? this._cv(title) : title;
+		}
+	});
+});
diff --git a/dojox/mobile/CheckBox.js b/dojox/mobile/CheckBox.js
new file mode 100644
index 0000000..43031a0
--- /dev/null
+++ b/dojox/mobile/CheckBox.js
@@ -0,0 +1,35 @@
+define([
+	"dojo/_base/declare",
+	"dojo/dom-construct",
+	"dijit/form/_CheckBoxMixin",
+	"./ToggleButton"
+],
+	function(declare, domConstruct, CheckBoxMixin, ToggleButton){
+
+	/*=====
+		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).
+
+		baseClass: "mblCheckBox",
+
+		_setTypeAttr: function(){}, // cannot be changed: IE complains w/o this
+
+		buildRendering: function(){
+			if(!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;
+		},
+		
+		_getValueAttr: function(){
+			return (this.checked ? this.value : false);
+		}
+	});
+});
diff --git a/dojox/mobile/ComboBox.js b/dojox/mobile/ComboBox.js
new file mode 100644
index 0000000..6ab11c9
--- /dev/null
+++ b/dojox/mobile/ComboBox.js
@@ -0,0 +1,224 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/dom-geometry",
+	"dojo/dom-style",
+	"dojo/window",
+	"dijit/form/_AutoCompleterMixin",
+	"dijit/popup",
+	"./_ComboBoxMenu",
+	"./TextBox",
+	"./sniff"
+], function(kernel, declare, lang, win, domGeometry, domStyle, windowUtils, 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
+		//
+
+		// dropDownClass: [protected extension] String
+		//		Name of the dropdown widget class used to select a date/time.
+		//		Subclasses should specify this.
+		dropDownClass: "dojox.mobile._ComboBoxMenu",
+
+		// initially disable selection since iphone displays selection handles that makes it hard to pick from the list
+		selectOnClick: false,
+		autoComplete: false,
+
+		// dropDown: [protected] Widget
+		//		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: -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
+		//
+		//		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
+			if(this._throttleHandler){
+				clearTimeout(this._throttleHandler);
+			}
+			this._throttleHandler = setTimeout(lang.hitch(this, function(){ this._throttleHandler = null; }), 500);
+		},
+
+		_onFocus: function(){
+			this.inherited(arguments);
+			if(!this._opened && !this._throttleHandler){
+				this._startSearchAll(); // show dropdown if user is selecting Next/Previous from virtual keyboard
+			}
+		},
+
+		onInput: function(e){
+			this._onKey(e);
+			this.inherited(arguments);
+		},
+
+		_setListAttr: function(v){
+			this._set('list', v); // needed for Firefox 4+ to prevent HTML5 mode
+		},
+
+		closeDropDown: function(){
+			// summary:
+			//		Closes the drop down on this widget
+			// tags:
+			//		protected
+
+			this._throttleOpenClose();
+			if(this.startHandler){
+				this.disconnect(this.startHandler);
+				this.startHandler = null;
+				if(this.moveHandler){ this.disconnect(this.moveHandler); }
+				if(this.endHandler){ this.disconnect(this.endHandler); }
+			}
+			this.inherited(arguments);
+			popup.close(this.dropDown);
+			this._opened = false;
+		},
+
+		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).
+			// returns:
+			//		return value of popup.open()
+			// tags:
+			//		protected
+
+			var wasClosed = !this._opened;
+			var dropDown = this.dropDown,
+				ddNode = dropDown.domNode,
+				aroundNode = this.domNode,
+				self = this;
+
+
+			// TODO: isn't maxHeight dependent on the return value from 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)
+			var myStyle = {
+				display: "",
+				overflow: "hidden",
+				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 = windowUtils.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.position(this.dropDown.containerNode, false);
+			var overHeight = (maxHeight && mb.h > maxHeight);
+			if(overHeight){
+				mb.h = maxHeight;
+			}
+
+			// Adjust dropdown width to match or be larger than my width
+			mb.w = Math.max(mb.w, aroundNode.offsetWidth);
+			domGeometry.setMarginBox(ddNode, mb);
+
+			var retVal = popup.open({
+				parent: this,
+				popup: dropDown,
+				around: aroundNode,
+				orient: this.dropDownPosition,
+				onExecute: function(){
+					self.closeDropDown();
+				},
+				onCancel: function(){
+					self.closeDropDown();
+				},
+				onClose: function(){
+					self._opened = false;
+				}
+			});
+			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(); } });
+					})
+				);
+			}
+			return retVal;
+		},
+
+		postCreate: function(){
+			this.inherited(arguments);
+			this.connect(this.domNode, "onclick", "_onClick");
+		},
+
+		_onClick: function(/*Event*/ e){
+			// throttle clicks to prevent double click from doing double actions
+			if(!this._throttleHandler){
+				if(this.opened){
+					this.closeDropDown();
+				}else{
+					this._startSearchAll();
+				}
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/ContentPane.js b/dojox/mobile/ContentPane.js
new file mode 100644
index 0000000..d9e5f4f
--- /dev/null
+++ b/dojox/mobile/ContentPane.js
@@ -0,0 +1,125 @@
+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;
+=====*/
+
+	// module:
+	//		dojox/mobile/ContentPane
+	// summary:
+	//		A very simple content pane to embed an HTML fragment.
+
+	return declare("dojox.mobile.ContentPane", [WidgetBase, Contained],{
+		// 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")
+			});
+		},
+
+		_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();
+		}
+	});
+});
diff --git a/dojox/mobile/EdgeToEdgeCategory.js b/dojox/mobile/EdgeToEdgeCategory.js
new file mode 100644
index 0000000..cc9c933
--- /dev/null
+++ b/dojox/mobile/EdgeToEdgeCategory.js
@@ -0,0 +1,23 @@
+define([
+	"dojo/_base/declare",
+	"./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:
+		//		A category header for an edge-to-edge list.
+		buildRendering: function(){
+			this.inherited(arguments);
+			this.domNode.className = "mblEdgeToEdgeCategory";
+		}
+	});
+});
diff --git a/dojox/mobile/EdgeToEdgeDataList.js b/dojox/mobile/EdgeToEdgeDataList.js
new file mode 100644
index 0000000..7471eb1
--- /dev/null
+++ b/dojox/mobile/EdgeToEdgeDataList.js
@@ -0,0 +1,24 @@
+define([
+	"dojo/_base/declare",
+	"./EdgeToEdgeList",
+	"./_DataListMixin"
+], function(declare, EdgeToEdgeList, DataListMixin){
+
+/*=====
+	var EdgeToEdgeList = dojox.mobile.EdgeToEdgeList;
+	var DataListMixin = dojox.mobile._DataListMixin;
+=====*/
+
+	// module:
+	//		dojox/mobile/EdgeToEdgeDataList
+	// summary:
+	//		An enhanced version of EdgeToEdgeList.
+
+	return declare("dojox.mobile.EdgeToEdgeDataList", [EdgeToEdgeList, DataListMixin],{
+		// summary:
+		//		An enhanced version of EdgeToEdgeList.
+		// description:
+		//		EdgeToEdgeDataList is an enhanced version of EdgeToEdgeList. It
+		//		can generate ListItems according to the given dojo.data store.
+	});
+});
diff --git a/dojox/mobile/EdgeToEdgeList.js b/dojox/mobile/EdgeToEdgeList.js
new file mode 100644
index 0000000..d129dea
--- /dev/null
+++ b/dojox/mobile/EdgeToEdgeList.js
@@ -0,0 +1,28 @@
+define([
+	"dojo/_base/declare",
+	"./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.
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			this.domNode.className = "mblEdgeToEdgeList";
+		}
+	});
+});
diff --git a/dojox/mobile/ExpandingTextArea.js b/dojox/mobile/ExpandingTextArea.js
new file mode 100644
index 0000000..4a6bf8c
--- /dev/null
+++ b/dojox/mobile/ExpandingTextArea.js
@@ -0,0 +1,27 @@
+define([
+	"dojo/_base/declare",
+	"dijit/form/_ExpandingTextAreaMixin",
+	"./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.
+		//
+		// description:
+		//		A textarea that dynamically expands/contracts (changing it's 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.
+		//
+		// example:
+		// |	<textarea dojoType="dojox.mobile.ExpandingTextArea">...</textarea>
+
+		baseClass: "mblTextArea mblExpandingTextArea"
+	});
+});
diff --git a/dojox/mobile/FixedSplitter.js b/dojox/mobile/FixedSplitter.js
index 8cf750a..88271f1 100644
--- a/dojox/mobile/FixedSplitter.js
+++ b/dojox/mobile/FixedSplitter.js
@@ -1,97 +1,115 @@
-dojo.provide("dojox.mobile.FixedSplitter");
+define([
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/window",
+	"dojo/dom-class",
+	"dojo/dom-geometry",
+	"dijit/_Contained",
+	"dijit/_Container",
+	"dijit/_WidgetBase",
+	"./FixedSplitterPane"
+], function(array, declare, win, domClass, domGeometry, Contained, Container, WidgetBase, FixedSplitterPane){
 
-dojo.require("dijit._WidgetBase");
+/*=====
+	var Contained = dijit._Contained;
+	var Container = dijit._Container;
+	var WidgetBase = dijit._WidgetBase;
+=====*/
 
-// summary:
-//		A layout container that splits the window horizontally or vertically.
-// description:
-//		FixedSplitter is a very simple container widget that layouts its 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 can be a plain <div> or dojox.mobile.FixedSplitterPane.
-// example:
-// |	<div dojoType="dojox.mobile.FixedSplitter" orientation="H">
-// |		<div style="width:200px;border-right:1px solid black;">
-// |			pane #1 (width=200px)
-// |		</div>
-// |		<div>
-// |			pane #2
-// |		</div>
-// |	</div>
+	// module:
+	//		dojox/mobile/FixedSplitter
+	// summary:
+	//		A layout container that splits the window horizontally or vertically.
 
-dojo.declare(
-	"dojox.mobile.FixedSplitter",
-	dijit._WidgetBase,
-{
-	orientation: "H", // "H" or "V"
+	return declare("dojox.mobile.FixedSplitter", [WidgetBase, Container, Contained], {
+		// summary:
+		//		A layout container that splits the window horizontally or
+		//		vertically.
+		// description:
+		//		FixedSplitter is a very simple container widget that layouts its
+		//		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.
+		//
+		// 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>
 
-	isContainer: true,
+		// orientation: String
+		//		The direction of split. If "H" is specified, panes are split
+		//		horizontally. If "V" is specified, panes are split vertically.
+		orientation: "H",
 
-	buildRendering: function(){
-		this.domNode = this.containerNode = this.srcNodeRef ? this.srcNodeRef : dojo.doc.createElement("DIV");
-		dojo.addClass(this.domNode, "mblFixedSpliter");
-	},
 
-	startup: function(){
-		var children = dojo.filter(this.domNode.childNodes, function(node){ return node.nodeType == 1; });
-		dojo.forEach(children, function(node){
-			dojo.addClass(node, "mblFixedSplitterPane"+this.orientation);
-		}, this);
+		buildRendering: function(){
+			this.domNode = this.containerNode = this.srcNodeRef ? this.srcNodeRef : win.doc.createElement("DIV");
+			domClass.add(this.domNode, "mblFixedSpliter");
+		},
 
-		dojo.forEach(this.getChildren(), function(child){if(child.startup){child.startup();}});
-		this._started = true;
+		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);
+			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();
+		},
 
-		var _this = this;
-		setTimeout(function(){
-			_this.resize();
-		}, 0);
-
-		var parent = dijit.getEnclosingWidget(this.domNode.parentNode);
-		if(!parent){
-			if(dojo.global.onorientationchange !== undefined){
-				this.connect(dojo.global, "onorientationchange", "resize");
-			}else{
-				this.connect(dojo.global, "onresize", "resize");
+		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(changeSize, resultSize){
-		this.layout();
-	},
-
-	layout: function(){
-		var sz = this.orientation == "H" ? "w" : "h";
-		var children = dojo.filter(this.domNode.childNodes, function(node){ return node.nodeType == 1; });
-		var offset = 0;
-		for(var i = 0; i < children.length; i++){
-			dojo.marginBox(children[i], this.orientation == "H" ? {l:offset} : {t:offset});
-			if(i < children.length - 1){
-				offset += dojo.marginBox(children[i])[sz];
+	
+			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){
+						h = (win.global.innerHeight||win.doc.documentElement.clientHeight);
+					}
+				}
 			}
-		}
+			var l = (h || domGeometry.getMarginBox(this.domNode)[sz]) - offset;
+			var props = {};
+			props[sz] = l;
+			domGeometry.setMarginBox(children[children.length - 1], props);
+	
+			array.forEach(this.getChildren(), function(child){
+				if(child.resize){ child.resize(); }
+			});
+		},
 
-		var l = dojo.marginBox(this.domNode)[sz] - offset;
-		var props = {};
-		props[sz] = l;
-		dojo.marginBox(children[children.length - 1], props);
-
-		dojo.forEach(this.getChildren(), function(child){
-			if(child.resize){ child.resize(); }
-		});
-	}
-});
-
-dojo.declare(
-	"dojox.mobile.FixedSplitterPane",
-	dijit._WidgetBase,
-{
-	buildRendering: function(){
-		this.inherited(arguments);
-		dojo.addClass(this.domNode, "mblFixedSplitterPane");
-	}
+		addChild: function(widget, /*Number?*/insertIndex){
+			domClass.add(widget.domNode, "mblFixedSplitterPane"+this.orientation);
+			this.inherited(arguments);
+		}
+	});
 });
diff --git a/dojox/mobile/FixedSplitterPane.js b/dojox/mobile/FixedSplitterPane.js
new file mode 100644
index 0000000..2490bf0
--- /dev/null
+++ b/dojox/mobile/FixedSplitterPane.js
@@ -0,0 +1,40 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/dom-class",
+	"dijit/_Contained",
+	"dijit/_Container",
+	"dijit/_WidgetBase"
+], function(array, declare, domClass, Contained, Container, WidgetBase){
+
+/*=====
+	var Contained = dijit._Contained;
+	var Container = dijit._Container;
+	var WidgetBase = dijit._WidgetBase;
+=====*/
+
+	// module:
+	//		dojox/mobile/FixedSplitterPane
+	// summary:
+	//		A pane widget that is used in a dojox.mobile.FixedSplitter.
+
+	return declare("dojox.mobile.FixedSplitterPane",[WidgetBase, Container, Contained],{
+		// 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.
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			domClass.add(this.domNode, "mblFixedSplitterPane");
+		},
+
+		resize: function(){
+			array.forEach(this.getChildren(), function(child){
+				if(child.resize){ child.resize(); }
+			});
+		}
+	});
+});
diff --git a/dojox/mobile/FlippableView.js b/dojox/mobile/FlippableView.js
index 2ff79f4..48b8329 100644
--- a/dojox/mobile/FlippableView.js
+++ b/dojox/mobile/FlippableView.js
@@ -1,132 +1,8 @@
-dojo.provide("dojox.mobile.FlippableView");
-
-dojo.require("dijit._WidgetBase");
-dojo.require("dojox.mobile");
-dojo.require("dojox.mobile._ScrollableMixin");
-
-// summary:
-//		A container that can be flipped horizontally.
-// description:
-//		FlippableView allows the user to swipe the screen left or right to
-//		flip between the views.
-//		When FlippableView is flipped, it finds an adjacent FlippableView,
-//		and opens it.
-
-dojo.declare(
-	"dojox.mobile.FlippableView",
-	[dojox.mobile.View, dojox.mobile._ScrollableMixin],
-{
-	scrollDir: "f",
-	weight: 1.2,
-
-	buildRendering: function(){
-		this.inherited(arguments);
-		dojo.addClass(this.domNode, "mblFlippableView");
-		this.containerNode = this.domNode;
-		this.containerNode.style.position = "absolute";
-	},
-
-	onTouchStart: function(e){
-		var nextView = this._nextView(this.domNode);
-		if(nextView){
-			nextView.stopAnimation();
-		}
-		var prevView = this._previousView(this.domNode);
-		if(prevView){
-			prevView.stopAnimation();
-		}
-		this.inherited(arguments);
-	},
-
-	_nextView: function(node){
-		for(var n = node.nextSibling; n; n = n.nextSibling){
-			if(n.nodeType == 1){ return dijit.byNode(n); }
-		}
-		return null;
-	},
-
-	_previousView: function(node){
-		for(var n = node.previousSibling; n; n = n.previousSibling){
-			if(n.nodeType == 1){ return dijit.byNode(n); }
-		}
-		return null;
-	},
-
-	scrollTo: function(/*Object*/to){
-		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(newView){
-				newView.domNode.style.display = "";
-				newView._beingFlipped = true;
-				newView.scrollTo({x:x});
-				newView._beingFlipped = false;
-			}
-		}
-		this.inherited(arguments);
-	},
-
-	slideTo: function(/*Object*/to, /*Number*/duration, /*String*/easing){
-		if(!this._beingFlipped){
-			var w = this.domNode.offsetWidth;
-			var pos = this.getPos();
-			var newView, newX;
-			if(pos.x < 0){ // moving to left
-				newView = this._nextView(this.domNode);
-				if(pos.x < -w/4){ // slide to next
-					if(newView){
-						to.x = -w;
-						newX = 0;
-					}
-				}else{ // go back
-					if(newView){
-						newX = w;
-					}
-				}
-			}else{ // moving to right
-				newView = this._previousView(this.domNode);
-				if(pos.x > w/4){ // slide to previous
-					if(newView){
-						to.x = w;
-						newX = 0;
-					}
-				}else{ // go back
-					if(newView){
-						newX = -w;
-					}
-				}
-			}
-
-			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;
-				}
-			}
-		}
-		this.inherited(arguments);
-	},
-
-	onFlickAnimationEnd: function(e){
-		// 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(c.nodeType == 1 && c != dojox.mobile.currentView.domNode){
-				c.style.display = "none";
-			}
-		}
-		this.inherited(arguments);
-	}
+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/Heading.js b/dojox/mobile/Heading.js
new file mode 100644
index 0000000..52c786a
--- /dev/null
+++ b/dojox/mobile/Heading.js
@@ -0,0 +1,266 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+	"dijit/registry",	// registry.byId
+	"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;
+=====*/
+
+	// module:
+	//		dojox/mobile/Heading
+	// summary:
+	//		A widget that represents a navigation bar.
+
+	return declare("dojox.mobile.Heading", [WidgetBase, Container, Contained],{
+		// summary:
+		//		A widget that represents a navigation bar.
+		// description:
+		//		Heading is a widget that represents a navigation bar, which
+		//		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
+		//		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.
+		back: "",
+
+		// href: String
+		//		A URL to open when the navigational control is pressed.
+		href: "",
+
+		// 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 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.
+		//
+		//		If null, transitions to a blank view.
+		//		If '#', returns immediately without transition.
+		moveTo: "",
+
+		// 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.
+		transition: "slide",
+
+		// label: String
+		//		A title text of the heading. If the label is not specified, the
+		//		innerHTML of the node is used as a label.
+		label: "",
+
+		// iconBase: String
+		//		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",
+
+		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");
+						}
+					}
+				}, 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);
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+			var parent = this.getParent && this.getParent();
+			if(!parent || !parent.resize){ // top level widget
+				var _this = this;
+				setTimeout(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)
+				// +-----------------------------+
+				// | |A| |B|             |C| |D| |
+				// +-----------------------------+
+				var leftBtn, rightBtn;
+				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"){
+							rightBtn = c;
+						}
+						if(!leftBtn && (domClass.contains(c, "mblToolBarButton") && domStyle.get(c, "float") === "left" || c === this._btn)){
+							leftBtn = c;
+						}
+					}
+				}
+
+				if(!this.labelNodeLen && this.label){
+					this.labelNode.style.display = "inline";
+					this.labelNodeLen = this.labelNode.offsetWidth;
+					this.labelNode.style.display = "";
+				}
+
+				var bw = this.domNode.offsetWidth; // bar width
+				var rw = rightBtn ? bw - rightBtn.offsetLeft + 5 : 0; // rightBtn width
+				var lw = leftBtn ? leftBtn.offsetLeft + leftBtn.offsetWidth + 5 : 0; // leftBtn width
+				var tw = this.labelNodeLen || 0; // title width
+				domClass[bw - Math.max(rw,lw)*2 > tw ? "add" : "remove"](this.domNode, "mblHeadingCenterTitle");
+			}
+			array.forEach(this.getChildren(), function(child){
+				if(child.resize){ child.resize(); }
+			});
+		},
+
+		_setBackAttr: function(/*String*/back){
+			if (!back){
+				domConstruct.destroy(this._btn);
+				this._btn = null;
+				this.back = "";
+			}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.resize();
+		},
+	
+		_setLabelAttr: function(/*String*/label){
+			this.label = label;
+			this.labelNode.innerHTML = this.labelDivNode.innerHTML = this._cv ? this._cv(label) : label;
+		},
+	
+		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; }
+			}
+			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;
+			}
+			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);
+					}
+				}
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/IconContainer.js b/dojox/mobile/IconContainer.js
index 120b78d..3e968a2 100644
--- a/dojox/mobile/IconContainer.js
+++ b/dojox/mobile/IconContainer.js
@@ -1,307 +1,184 @@
-dojo.provide("dojox.mobile.IconContainer");
-
-dojo.require("dojox.mobile");
-
-dojo.declare(
-	"dojox.mobile.IconContainer",
-	dijit._WidgetBase,
-{
-	defaultIcon: "",
-	transition: "below", // slide, flip, or below
-	pressedIconOpacity: 0.4,
-	iconBase: "",
-	iconPos: "",
-	back: "Home",
-	label: "My Application",
-	single: false,
-
-	buildRendering: function(){
-		this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("UL");
-		this.domNode.className = "mblIconContainer";
-		var t = this._terminator = dojo.create("LI");
-		t.className = "mblIconItemTerminator";
-		t.innerHTML = " ";
-		this.domNode.appendChild(t);
-	},
+define([
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/window",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+	"dijit/registry",	// registry.byNode
+	"dijit/_Contained",
+	"dijit/_Container",
+	"dijit/_WidgetBase",
+	"./IconItem",
+	"./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;
+=====*/
+
+	// 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.
+		// description:
+		//		IconContainer is a container widget that holds multiple icons
+		//		each of which represents application component.
+
+		// defaultIcon: String
+		//		The default fall-back icon, which is displayed only when the
+		//		specified icon has failed to load.
+		defaultIcon: "",
+
+		// 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. If "below" is specified,
+		//		the application contents are displayed below the icons.
+		transition: "below",
+
+		// pressedIconOpacity: Number
+		//		The opacity of the pressed icon image.
+		pressedIconOpacity: 0.4,
+
+		// iconBase: String
+		//		The default icon path for child items.
+		iconBase: "",
+
+		// iconPos: String
+		//		The default icon position for child items.
+		iconPos: "",
+
+		// back: String
+		//		A label for the navigational control.
+		back: "Home",
+
+		// label: String
+		//		A title text of the heading.
+		label: "My Application",
+
+		// single: Boolean
+		//		If true, only one icon content can be opened at a time.
+		single: false,
+
+		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);
+		},
+
+		_setupSubNodes: function(ul){
+			array.forEach(this.getChildren(), function(w){
+				ul.appendChild(w.subNode);
+			});
+		},
+
+		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;
+					}
+				}
+				if(!target){ target = win.body(); }
+				target.appendChild(view.domNode);
 
-	_setupSubNodes: function(ul){
-		var len = this.domNode.childNodes.length - 1; // -1 for terminator
-		for(i = 0; i < len; i++){
-			child = this.domNode.childNodes[i];
-			if(child.nodeType != 1){ continue; }
-			w = dijit.byNode(child);
-			if(this.single){
-				w.subNode.firstChild.style.display = "none";
+				view.startup();
 			}
-			ul.appendChild(w.subNode);
-		}
-	},
-
-	startup: function(){
-		var ul, i, len, child, w;
-		if(this.transition == "below"){
-			this._setupSubNodes(this.domNode);
-		}else{
-			var view = new dojox.mobile.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 dojox.mobile.Heading({back:this.back, label:this.label, moveTo:this.domNode.parentNode.id, transition:this.transition});
-			view.addChild(heading);
-			ul = dojo.doc.createElement("UL");
-			ul.className = "mblIconContainer";
-			ul.style.marginTop = "0px";
-			this._setupSubNodes(ul);
-			view.domNode.appendChild(ul);
-			dojo.doc.body.appendChild(view.domNode);
-			heading.startup();
-		}
-	},
-
-	closeAll: function(){
-		var len = this.domNode.childNodes.length;
-		for(var i = 0; i < len; i++){
-			child = this.domNode.childNodes[i];
-			if(child.nodeType != 1){ continue; }
-			if(child == this._terminator){ break; }
-			w = dijit.byNode(child);
-			w.containerNode.parentNode.style.display = "none";
-			w.setOpacity(w.iconNode, 1);
-		}
-	},
-
-	addChild: function(widget){
-		this.domNode.insertBefore(widget.domNode, this._terminator);
-		widget.transition = this.transition;
-		if(this.transition == "below"){
-			this.domNode.appendChild(widget.subNode);
-		}
-		widget.inheritParams();
-		widget.setIcon();
-	}
-});
-
-dojo.declare(
-	"dojox.mobile.IconItem",
-	dojox.mobile.AbstractItem,
-{
-	// description:
-	//		Dynamic creation is not supported.
-	lazy: false,
-	requires: "",
-	timeout: 10,
-
-	templateString: '<li class="mblIconItem">'+
-						'<div class="mblIconArea" dojoAttachPoint="iconDivNode">'+
-							'<div><img src="${icon}" dojoAttachPoint="iconNode"></div>${label}'+
-						'</div>'+
-					'</li>',
-	templateStringSub: '<li class="mblIconItemSub" lazy="${lazy}" style="display:none;" dojoAttachPoint="contentNode">'+
-						'<h2 class="mblIconContentHeading" dojoAttachPoint="closeNode">'+
-							'<div class="mblBlueMinusButton" style="position:absolute;left:4px;top:2px;" dojoAttachPoint="closeIconNode"><div></div></div>${label}'+
-						'</h2>'+
-						'<div class="mblContent" dojoAttachPoint="containerNode"></div>'+
-					'</li>',
-
-	createTemplate: function(s){
-		dojo.forEach(["lazy","icon","label"], function(v){
-			while(s.indexOf("${"+v+"}") != -1){
-				s = s.replace("${"+v+"}", this[v]);
+			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);
 			}
-		}, this);
-		var div = dojo.doc.createElement("DIV");
-		div.innerHTML = s;
+		},
 
-		/*
-		dojo.forEach(dojo.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];
+		addChild: function(widget, /*Number?*/insertIndex){
+			var children = this.getChildren();
+			if(typeof insertIndex !== "number" || insertIndex > children.length){
+				insertIndex = children.length;
 			}
-		}
-		var domNode = div.removeChild(div.firstChild);
-		div = null;
-		return domNode;
-	},
-
-	buildRendering: function(){
-		this.inheritParams();
-		this.domNode = this.createTemplate(this.templateString);
-		this.subNode = this.createTemplate(this.templateStringSub);
-		this.subNode._parentNode = this.domNode; // [custom property]
-
-		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));
+			var idx = insertIndex;
+			var refNode = this.containerNode;
+			if(idx > 0){
+				refNode = children[idx - 1].domNode;
+				idx = "after";
 			}
-			this.srcNodeRef.parentNode.replaceChild(this.domNode, this.srcNodeRef);
-			this.srcNodeRef = null;
-		}
-		this.setIcon();
-	},
-
-	setIcon: function(){
-		this.iconNode.src = this.icon;
-		dojox.mobile.setupIcon(this.iconNode, this.iconPos);
-	},
-
-	postCreate: function(){
-		this.connect(this.iconNode, "onmousedown", "onMouseDownIcon");
-		this.connect(this.iconNode, "onclick", "iconClicked");
-		this.connect(this.closeIconNode, "onclick", "closeIconClicked");
-		this.connect(this.iconNode, "onerror", "onError");
-	},
-
-	highlight: function(){
-		dojo.addClass(this.iconDivNode, "mblVibrate");
-		if(this.timeout > 0){
-			var _this = this;
-			setTimeout(function(){
-				_this.unhighlight();
-			}, this.timeout*1000);
-		}
-	},
-
-	unhighlight: function(){
-		dojo.removeClass(this.iconDivNode, "mblVibrate");
-	},
-
-	setOpacity: function(node, val){
-		node.style.opacity = val;
-		node.style.mozOpacity = val;
-		node.style.khtmlOpacity = val;
-		node.style.webkitOpacity = val;
-	},
+			domConstruct.place(widget.domNode, refNode, idx);
 
-	instantiateWidget: function(e){
-		// avoid use of dojo.query
-		/*
-		var list = dojo.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);
+			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);
 			}
-		}
-
-		if(len > 0){
-			(dojox.mobile.parser || dojo.parser).parse(this.containerNode);
-		}
-		this.lazy = false;
-	},
+			widget.inheritParams();
+			widget._setIconAttr(widget.icon);
 
-	isOpen: function(e){
-		return this.containerNode.style.display != "none";
-	},
-
-	onMouseDownIcon: function (e){
-		this.setOpacity(this.iconNode, this.getParentWidget().pressedIconOpacity);
-	},
-
-	iconClicked: function(e){
-		if(e){
-			setTimeout(dojo.hitch(this, function(d){ this.iconClicked(); }), 0);
-			return;
-		}
-		if(this.moveTo || this.href || this.url){
-			this.transitionTo(this.moveTo, this.href, this.url);
-			setTimeout(dojo.hitch(this, function(d){
-				this.setOpacity(this.iconNode, 1);
-			}), 1500);
-		}else{
-			this.open();
-		}
-	},
-
-	closeIconClicked: function(e){
-		if(e){
-			setTimeout(dojo.hitch(this, function(d){ this.closeIconClicked(); }), 0);
-			return;
-		}
-		this.close();
-	},
-
-	open: function(){
-		var parent = this.getParentWidget(); // IconContainer
-		if(this.transition == "below"){
-			if(parent.single){
-				parent.closeAll();
-				this.setOpacity(this.iconNode, this.getParentWidget().pressedIconOpacity);
-			}
-			this._open_1();
-		}else{
-			parent._opening = this;
-			if(parent.single){
-				parent.closeAll();
-				var view = dijit.byId(parent.id+"_mblApplView");
-				view._heading.setLabel(this.label);
+			if(this._started && !widget._started){
+				widget.startup();
 			}
-			this.transitionTo(parent.id+"_mblApplView");
-		}
-	},
+		},
 
-	_open_1: function(){
-		this.contentNode.style.display = "";
-		this.unhighlight();
-		if(this.lazy){
-			if(this.requires){
-				dojo.forEach(this.requires.split(/,/), function(c){
-					dojo["require"](c);
-				});
+		removeChild: function(/*Widget|Number*/widget){
+			if(typeof widget === "number"){
+				widget = this.getChildren()[widget];
 			}
-			this.instantiateWidget();
-		}
-		this.contentNode.scrollIntoView();
-		this.onOpen();
-	},
-
-	close: function(){
-		if(dojo.isWebKit){
-			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(widget){
+				this.inherited(arguments);
+				if(this.transition === "below"){
+					this.containerNode.removeChild(widget.subNode);
+				}else{
+					this.appView._ul.removeChild(widget.subNode);
 				}
 			}
-			dojo.addClass(this.containerNode.parentNode, "mblCloseContent mblShrink"+pos);
-		}else{
-			this.containerNode.parentNode.style.display = "none";
 		}
-		this.setOpacity(this.iconNode, 1);
-		this.onClose();
-	},
-
-	onOpen: function(){
-		// stub method to allow the application to connect to.
-	},
-
-	onClose: function(){
-		// stub method to allow the application to connect to.
-	},
-
-	onError: function(){
-		this.iconNode.src = this.getParentWidget().defaultIcon;
-	}
+	});
 });
diff --git a/dojox/mobile/IconItem.js b/dojox/mobile/IconItem.js
new file mode 100644
index 0000000..1b39dff
--- /dev/null
+++ b/dojox/mobile/IconItem.js
@@ -0,0 +1,331 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/sniff",
+	"dojo/_base/window",
+	"dojo/dom-attr",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"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;
+=====*/
+
+	// module:
+	//		dojox/mobile/IconItem
+	// summary:
+	//		An icon item widget.
+
+	return declare("dojox.mobile.IconItem", ItemBase, {
+		// summary:
+		//		An icon item widget.
+		// description:
+		//		IconItem represents an item that has an application component
+		//		and its icon image. You can tap the icon to open the
+		//		corresponding application component. You can also use the icon
+		//		to move to a different view by specifying either of the moveTo,
+		//		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.
+		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.
+		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);
+			}
+			var domNode = div.removeChild(div.firstChild);
+			div = null;
+			return domNode;
+		},
+
+		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("LI");
+			domClass.add(this.domNode, "mblIconItem");
+			if(this.srcNodeRef){
+				// reparent
+				for(var i = 0, len = this.srcNodeRef.childNodes.length; i < len; i++){
+					this.containerNode.appendChild(this.srcNodeRef.firstChild);
+				}
+			}
+			this.domNode.appendChild(node);
+		},
+
+		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");
+		},
+	
+		highlight: function(){
+			// summary:
+			//		Shakes the icon 10 seconds.
+			domClass.add(this.iconDivNode, "mblVibrate");
+			if(this.timeout > 0){
+				var _this = this;
+				setTimeout(function(){
+					_this.unhighlight();
+				}, this.timeout*1000);
+			}
+		},
+
+		unhighlight: function(){
+			// summary:
+			//		Stops shaking the icon.
+			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";
+		},
+	
+		onMouseDownIcon: function (e){
+			domStyle.set(this.iconNode, "opacity", this.getParent().pressedIconOpacity);
+		},
+	
+		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;
+			}
+
+			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;
+			}
+			if(transOpts){
+				setTimeout(lang.hitch(this, function(d){
+					domStyle.set(this.iconNode, "opacity", 1);
+				}), 1500);
+			}else{
+				return this.open(e);
+			}
+	
+			if(transOpts){
+				return new TransitionEvent(this.domNode,transOpts,e).dispatch();
+			}
+		},
+	
+		closeIconClicked: function(e){
+			if(e){
+				setTimeout(lang.hitch(this, function(d){ this.closeIconClicked(); }), 0);
+				return;
+			}
+			this.close();
+		},
+	
+		open: function(e){
+			// summary:
+			//		Opens the icon content, or makes a transition.
+			var parent = this.getParent(); // IconContainer
+			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);
+				}
+				var transOpts = this.transitionOptions || {transition: this.transition, transitionDir: this.transitionDir, moveTo: parent.id + "_mblApplView"};		
+				new TransitionEvent(this.domNode, transOpts, e).dispatch();
+			}
+		},
+	
+		_open_1: function(){
+			this.contentNode.style.display = "";
+			this.unhighlight();
+			if(this.lazy){
+				if(this.requires){
+					array.forEach(this.requires.split(/,/), function(c){
+						dojo["require"](c);
+					});
+				}
+				this.instantiateWidget();
+			}
+			this.contentNode.scrollIntoView();
+			this.onOpen();
+		},
+	
+		close: function(){
+			// 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;
+					}
+				}
+				domClass.add(this.containerNode.parentNode, "mblCloseContent mblShrink"+pos);
+			}else{
+				this.containerNode.parentNode.style.display = "none";
+			}
+			domStyle.set(this.iconNode, "opacity", 1);
+			this.onClose();
+		},
+	
+		onOpen: function(){
+			// summary:
+			//		Stub method to allow the application to connect to.
+		},
+	
+		onClose: function(){
+			// summary:
+			//		Stub method to allow the application to connect to.
+		},
+	
+		onError: function(){
+			var icon = this.getParent().defaultIcon;
+			if(icon){
+				this.iconNode.src = icon;
+			}
+		},
+	
+		_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"
+				});
+			}
+		},
+	
+		_setLabelAttr: function(/*String*/text){
+			this.label = text;
+			var s = this._cv ? this._cv(text) : text;
+			this.labelNode1.innerHTML = s;
+			this.labelNode2.innerHTML = s;
+		}
+	});
+});
diff --git a/dojox/mobile/ListItem.js b/dojox/mobile/ListItem.js
new file mode 100644
index 0000000..d560ec8
--- /dev/null
+++ b/dojox/mobile/ListItem.js
@@ -0,0 +1,375 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/has",
+	"./common",
+	"./_ItemBase",
+	"./TransitionEvent"
+], function(array, connect, declare, lang, domClass, domConstruct, has, common, ItemBase, TransitionEvent){
+
+/*=====
+	var ItemBase = dojox.mobile._ItemBase;
+=====*/
+
+	// module:
+	//		dojox/mobile/ListItem
+	// summary:
+	//		An item of either RoundRectList or EdgeToEdgeList.
+
+	return declare("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.
+
+		// rightText: String
+		//		A right-aligned text to display on the item.
+		rightText: "",
+
+		// rightIcon: String
+		//		An icon to display at the right hand side of the item. The value
+		//		can be either a path for an image file or a class name of a DOM
+		//		button.
+		rightIcon: "",
+
+		// rightIcon2: String
+		//		An icon to display at the left of the rightIcon. The value can
+		//		be either a path for an image file or a class name of a DOM
+		//		button.
+		rightIcon2: "",
+
+
+		// anchorLabel: Boolean
+		//		If true, the label text becomes a clickable anchor text. When
+		//		the user clicks on the text, the onAnchorLabelClicked handler is
+		//		called. You can override or connect to the handler and implement
+		//		any action. The handler has no default action.
+		anchorLabel: false,
+
+		// noArrow: Boolean
+		//		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,
+
+		// 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",
+
+		// 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",
+
+		// 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.
+		variableHeight: false,
+
+
+		// rightIconTitle: String
+		//		An alt text for the right icon.
+		rightIconTitle: "",
+
+		// rightIcon2Title: String
+		//		An alt text for the right icon2.
+		rightIcon2Title: "",
+
+
+		// btnClass: String
+		//		Deprecated. For backward compatibility.
+		btnClass: "",
+
+		// btnClass2: String
+		//		Deprecated. For backward compatibility.
+		btnClass2: "",
+
+		// 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;
+		},
+
+		buildRendering: function(){
+			this.domNode = 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";
+			}
+			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
+			}
+
+			var a = this.anchorNode = domConstruct.create("A");
+			a.className = "mblListItemAnchor";
+			this.domNode.appendChild(a);
+			a.appendChild(box);
+		},
+
+		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");
+			}
+			this.setArrow();
+
+			if(domClass.contains(this.domNode, "mblVariableHeight")){
+				this.variableHeight = true;
+			}
+			if(this.variableHeight){
+				domClass.add(this.domNode, "mblVariableHeight");
+				setTimeout(lang.hitch(this, "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);
+			}
+			this.inherited(arguments);
+		},
+
+		resize: function(){
+			if(this.variableHeight){
+				this.layoutVariableHeight();
+			}
+		},
+
+		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;
+					}
+				}
+			}
+			var parent = this.getParent();
+			if(parent.select){
+				if(parent.select === "single"){
+					if(!this.checked){
+						this.set("checked", true);
+					}
+				}else if(parent.select === "multiple"){
+					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();
+			}
+		},
+	
+		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(){
+			// summary:
+			//		Makes this widget in the deselected state.
+			domClass.remove(this.domNode, "mblItemSelected");
+		},
+	
+		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);
+						n.style.marginTop = t + "px";
+					}
+				});
+		},
+
+		setArrow: function(){
+			// summary:
+			//		Sets the arrow icon if necessary.
+			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;
+				}
+			}
+			if(c){
+				this._setRightIconAttr(c);
+			}
+		},
+
+		_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);
+			}
+			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");
+			}
+		},
+	
+		_setCheckedAttr: function(/*Boolean*/checked){
+			var parent = this.getParent();
+			if(parent && parent.select === "single" && checked){
+				array.forEach(parent.getChildren(), function(child){
+					child.set("checked", false);
+				});
+			}
+			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";
+			}
+
+			domClass.toggle(this.domNode, "mblListItemChecked", checked);
+			if(parent && this.checked !== checked){
+				parent.onCheckStateChanged(this, checked);
+			}
+			this.checked = checked;
+		},
+	
+		_setRightTextAttr: function(/*String*/text){
+			if(!this.rightTextNode){
+				this.rightTextNode = domConstruct.create("DIV", {className:"mblListItemRightText"}, this.box, "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);
+			}
+			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);
+			}
+		},
+	
+		_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);
+			}
+			this.rightIcon2 = icon;
+			common.createIcon(icon, null, null, this.rightIcon2Title, this.rightIcon2Node);
+		},
+	
+		_setLabelAttr: function(/*String*/text){
+			this.label = text;
+			this.labelNode.innerHTML = this._cv ? this._cv(text) : text;
+		}
+	});
+});
diff --git a/dojox/mobile/Opener.js b/dojox/mobile/Opener.js
new file mode 100644
index 0000000..6b9adf5
--- /dev/null
+++ b/dojox/mobile/Opener.js
@@ -0,0 +1,73 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+	"dojo/dom-geometry",
+	"./Tooltip",
+	"./Overlay"
+], function(declare, lang, win, domClass, domConstruct, domStyle, domGeometry, Tooltip, Overlay){
+
+	/*=====
+		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
+		//
+		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();
+				}
+			}));
+		},
+
+		onShow: function(/*DomNode*/node){},
+		onHide: function(/*DomNode*/node, /*Anything*/v){},
+
+		show: function(node, positions){
+			this.node = node;
+			this.onShow(node);
+			this._resizeCover();
+			return this.inherited(arguments);
+		},
+
+		hide: function(/*Anything*/ val){
+			this.inherited(arguments);
+			domStyle.set(this.cover, { height:'0px' });
+			this.onHide(this.node, val);
+		},
+		
+		_resizeCover: function(){
+			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);
+			}else{
+				domStyle.set(this.cover, { 
+					width:Math.max(win.doc.documentElement.scrollWidth || win.body().scrollWidth || win.doc.documentElement.clientWidth)+'px', 
+					height:Math.max(win.doc.documentElement.scrollHeight || win.body().scrollHeight || win.doc.documentElement.clientHeight)+'px' 
+				});
+			}			
+		},
+		
+		_onBlur: function(e){
+			var ret = this.onBlur(e);
+			if(ret !== false){ // only exactly false prevents hide()
+				this.hide(e);
+			}
+			return ret;
+		}
+	});
+	cls.prototype.baseClass += " mblOpener"; // add to either mblOverlay or mblTooltip
+	return cls;
+});
diff --git a/dojox/mobile/Overlay.js b/dojox/mobile/Overlay.js
new file mode 100644
index 0000000..5db7b0d
--- /dev/null
+++ b/dojox/mobile/Overlay.js
@@ -0,0 +1,95 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/sniff",
+	"dojo/_base/window",
+	"dojo/dom-class",
+	"dojo/dom-geometry",
+	"dojo/dom-style",
+	"dojo/window",
+	"dijit/_WidgetBase",
+	"dojo/_base/array",
+	"dijit/registry"
+], function(declare, lang, has, win, domClass, domGeometry, domStyle, windowUtils, WidgetBase, array, registry){
+
+	/*=====
+		WidgetBase = dijit._WidgetBase;
+	=====*/
+	return declare("dojox.mobile.Overlay", WidgetBase, {
+		// summary:
+		//		A non-templated widget that animates up from the bottom, overlaying the current content
+		//
+
+		baseClass: "mblOverlay mblOverlayHidden",
+
+		show: function(/*DomNode?*/aroundNode){
+			// summary:
+			//		Scroll the overlay up into view
+			array.forEach(registry.findWidgets(this.domNode), function(w){
+				if(w && w.height == "auto" && typeof w.resize == "function"){
+					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();
+			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();
+				}
+			}
+			domClass.replace(this.domNode, ["mblCoverv", "mblIn"], ["mblOverlayHidden", "mblRevealv", "mblOut", "mblReverse"]);
+			var _domNode = this.domNode;
+			setTimeout(function(){
+				domClass.add(_domNode, "mblTransition");
+			}, 100);
+			var timeoutHandler = null;
+			this._moveHandle = this.connect(win.doc.documentElement, "ontouchmove", function(){
+				if(timeoutHandler){
+					clearTimeout(timeoutHandler);
+				}
+				timeoutHandler = setTimeout(function(){
+					reposition();
+					timeoutHandler = null;
+				}, 0);
+			});
+		},
+
+		hide: function(){
+			// summary:
+			//		Scroll the overlay down and then make it invisible
+			if(this._moveHandle){
+				this.disconnect(this._moveHandle);
+				this._moveHandle = 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(){
+					domClass.add(_domNode, "mblTransition");
+				}, 100);
+			}else{
+				domClass.replace(this.domNode, ["mblOverlayHidden"], ["mblCoverv", "mblIn", "mblRevealv", "mblOut", "mblReverse"]);
+			}
+		},
+
+		onBlur: function(/*Event*/e){
+			return false; // touching outside the overlay area does not call hide()
+		}
+	});
+});
diff --git a/dojox/mobile/PageIndicator.js b/dojox/mobile/PageIndicator.js
new file mode 100644
index 0000000..44c24d5
--- /dev/null
+++ b/dojox/mobile/PageIndicator.js
@@ -0,0 +1,104 @@
+define([
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/_base/window",
+	"dojo/dom",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dijit/registry",	// registry.byNode
+	"dijit/_Contained",
+	"dijit/_WidgetBase"
+], function(connect, declare, win, dom, domClass, domConstruct, registry, Contained, WidgetBase){
+
+/*=====
+	var Contained = dijit._Contained;
+	var WidgetBase = dijit._WidgetBase;
+=====*/
+
+	// module:
+	//		dojox/mobile/PageIndicator
+	// summary:
+	//		A current page indicator.
+
+	return declare("dojox.mobile.PageIndicator", [WidgetBase, Contained],{
+		// summary:
+		//		A current page indicator.
+		// 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.
+
+		// refId: String
+		//		An ID of a DOM node to be searched. Siblings of the reference
+		//		node will be searched for views. If not specified, this.domNode
+		//		will be the reference node.
+		refId: "",
+
+		buildRendering: function(){
+			this.domNode = this.srcNodeRef || win.doc.createElement("DIV");
+			this.domNode.className = "mblPageIndicator";
+			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.reset();
+			});
+		},
+
+		startup: function(){
+			var _this = this;
+			setTimeout(function(){ // to wait until views' visibility is determined
+				_this.reset();
+			}, 0);
+		},
+
+		reset: function(){
+			// summary:
+			//		Updates the indicator.
+			var r = this._tblNode.rows[0];
+			var i, c, a = [], dot;
+			var refNode = (this.refId && dom.byId(this.refId)) || this.domNode;
+			var children = refNode.parentNode.childNodes;
+			for(i = 0; i < children.length; i++){
+				c = children[i];
+				if(this.isView(c)){
+					a.push(c);
+				}
+			}
+			if(r.cells.length !== a.length){
+				domConstruct.empty(r);
+				for(i = 0; i < a.length; i++){
+					c = a[i];
+					dot = domConstruct.create("DIV", {className:"mblPageIndicatorDot"});
+					r.insertCell(-1).appendChild(dot);
+				}
+			}
+			if(a.length === 0){ return; }
+			var currentView = registry.byNode(a[0]).getShowingView();
+			for(i = 0; i < r.cells.length; i++){
+				dot = r.cells[i].firstChild;
+				if(a[i] === currentView.domNode){
+					domClass.add(dot, "mblPageIndicatorDotSelected");
+				}else{
+					domClass.remove(dot, "mblPageIndicatorDotSelected");
+				}
+			}
+		},
+
+		isView: function(node){
+			// summary:
+			//		Returns true if the given node is a view.
+			return (node && node.nodeType === 1 && domClass.contains(node, "mblView"));
+		},
+
+		onClick: function(e){
+			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]);
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/ProgressIndicator.js b/dojox/mobile/ProgressIndicator.js
new file mode 100644
index 0000000..083ea69
--- /dev/null
+++ b/dojox/mobile/ProgressIndicator.js
@@ -0,0 +1,111 @@
+define([
+	"dojo/_base/config",
+	"dojo/_base/declare",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+	"dojo/has"
+], function(config, declare, domConstruct, domStyle, has){
+
+	// module:
+	//		dojox/mobile/ProgressIndicator
+	// summary:
+	//		A progress indication widget.
+
+	var cls = declare("dojox.mobile.ProgressIndicator", null, {
+		// summary:
+		//		A progress indication widget.
+		// description:
+		//		ProgressIndicator is a round spinning graphical representation
+		//		that indicates the current task is on-going.
+
+		// 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"
+		],
+
+		constructor: function(){
+			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)");
+			}
+			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._bars.push(div);
+			}
+		},
+	
+		start: function(){
+			// summary:
+			//		Starts the ProgressIndicator spinning.
+			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);
+				img.style.margin = t+"px "+l+"px";
+				return;
+			}
+			var cntr = 0;
+			var _this = this;
+			var n = this.colors.length;
+			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];
+				}
+			}, this.interval);
+		},
+	
+		stop: function(){
+			// summary:
+			//		Stops the ProgressIndicator spinning.
+			if(this.timer){
+				clearInterval(this.timer);
+			}
+			this.timer = null;
+			if(this.domNode.parentNode){
+				this.domNode.parentNode.removeChild(this.domNode);
+			}
+		},
+
+		setImage: function(/*String*/file){
+			// summary:
+			//		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.spinnerNode.style.display = "none";
+			}else{
+				if(this.imageNode){
+					this.domNode.removeChild(this.imageNode);
+					this.imageNode = null;
+				}
+				this.spinnerNode.style.display = "";
+			}
+		}
+	});
+
+	cls._instance = null;
+	cls.getInstance = function(){
+		if(!cls._instance){
+			cls._instance = new cls();
+		}
+		return cls._instance;
+	};
+
+	return cls;
+});
diff --git a/dojox/mobile/README b/dojox/mobile/README
index 35ac66a..d9ede45 100755
--- a/dojox/mobile/README
+++ b/dojox/mobile/README
@@ -32,11 +32,11 @@ required in separately.
 -------------------------------------------------------------------------------
 Dependencies:
         dojo base
-        dijit/_Widget.js
+        dijit/_WidgetBase.js
 -------------------------------------------------------------------------------
 Documentation
-        Documentatation will reside at:
-        http://docs.dojocampus.org/dojox/mobile
+        Documentation resides at:
+        http://dojotoolkit.org/reference-guide/dojox/mobile.html
 
 -------------------------------------------------------------------------------
 Installation instructions
diff --git a/dojox/mobile/RadioButton.js b/dojox/mobile/RadioButton.js
new file mode 100644
index 0000000..da29f0b
--- /dev/null
+++ b/dojox/mobile/RadioButton.js
@@ -0,0 +1,20 @@
+define([
+	"dojo/_base/declare",
+	"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).
+
+		// 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: null,
+
+		baseClass: "mblRadioButton"
+	});
+});
diff --git a/dojox/mobile/RoundRect.js b/dojox/mobile/RoundRect.js
new file mode 100644
index 0000000..ef5b815
--- /dev/null
+++ b/dojox/mobile/RoundRect.js
@@ -0,0 +1,48 @@
+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;
+=====*/
+
+	// module:
+	//		dojox/mobile/RoundRect
+	// summary:
+	//		A simple round rectangle container.
+
+	return declare("dojox.mobile.RoundRect", [WidgetBase, Container, Contained], {
+		// summary:
+		//		A simple round rectangle container.
+		// description:
+		//		RoundRect is a simple round rectangle container for any HTML
+		//		and/or widgets. You can achieve the same appearance by just
+		//		applying the -webkit-border-radius style to a div tag. However,
+		//		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: false,
+
+		buildRendering: function(){
+			this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("DIV");
+			this.domNode.className = this.shadow ? "mblRoundRect mblShadow" : "mblRoundRect";
+		},
+
+		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/RoundRectCategory.js b/dojox/mobile/RoundRectCategory.js
new file mode 100644
index 0000000..32f1c75
--- /dev/null
+++ b/dojox/mobile/RoundRectCategory.js
@@ -0,0 +1,40 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/window",
+	"dijit/_Contained",
+	"dijit/_WidgetBase"
+], function(declare, win, Contained, WidgetBase){
+
+/*=====
+	var Contained = dijit._Contained;
+	var WidgetBase = dijit._WidgetBase;
+=====*/
+
+	// module:
+	//		dojox/mobile/RoundRectCategory
+	// summary:
+	//		A category header for a rounded rectangle list.
+
+	return declare("dojox.mobile.RoundRectCategory", [WidgetBase, Contained],{
+		// summary:
+		//		A category header for a rounded rectangle list.
+
+		// label: String
+		//		A label text for the widget.
+		label: "",
+
+		buildRendering: function(){
+			this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("H2");
+			this.domNode.className = "mblRoundRectCategory";
+			if(!this.label){
+				this.label = this.domNode.innerHTML;
+			}
+		},
+
+		_setLabelAttr: function(/*String*/label){
+			this.label = label;
+			this.domNode.innerHTML = this._cv ? this._cv(label) : label;
+		}
+	});
+
+});
diff --git a/dojox/mobile/RoundRectDataList.js b/dojox/mobile/RoundRectDataList.js
new file mode 100644
index 0000000..4c0d3f5
--- /dev/null
+++ b/dojox/mobile/RoundRectDataList.js
@@ -0,0 +1,24 @@
+define([
+	"dojo/_base/declare",
+	"./RoundRectList",
+	"./_DataListMixin"
+], function(declare, RoundRectList, DataListMixin){
+
+/*=====
+	var RoundRectList = dojox.mobile.RoundRectList;
+	var DataListMixin = dojox.mobile._DataListMixin;
+=====*/
+
+	// module:
+	//		dojox/mobile/RoundRectDataList
+	// summary:
+	//		An enhanced version of RoundRectList.
+
+	return declare("dojox.mobile.RoundRectDataList", [RoundRectList, DataListMixin], {
+		// summary:
+		//		An enhanced version of RoundRectList.
+		// description:
+		//		RoundRectDataList is an enhanced version of RoundRectList. It
+		//		can generate ListItems according to the given dojo.data store.
+	});
+});
diff --git a/dojox/mobile/RoundRectList.js b/dojox/mobile/RoundRectList.js
new file mode 100644
index 0000000..464027d
--- /dev/null
+++ b/dojox/mobile/RoundRectList.js
@@ -0,0 +1,99 @@
+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;
+=====*/
+
+	// 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.
+
+		// 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: "",
+
+		// 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.
+		//		If "multiple", there can be multiple selected items at a time.
+		select: "",
+
+		// stateful: String
+		//		If true, the last selected item remains highlighted.
+		stateful: false,
+
+		buildRendering: function(){
+			this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("UL");
+			this.domNode.className = "mblRoundRectList";
+		},
+	
+		resize: function(){
+			// summary:
+			//		Calls resize() of each child widget.
+			array.forEach(this.getChildren(), function(child){
+				if(child.resize){ child.resize(); }
+			});
+		},
+
+		onCheckStateChanged: function(/*Widget*/listItem, /*String*/newState){
+			// summary:
+			//		Stub function to connect to from your application.
+			// description:
+			//		Called when the check state has been changed.
+		},
+
+		_setStatefulAttr: function(stateful){
+			this.stateful = stateful;
+			array.forEach(this.getChildren(), function(child){
+				child.setArrow && child.setArrow();
+			});
+		},
+
+		deselectItem: function(/*ListItem*/item){
+			// summary:
+			//		Deselects the given item.
+			item.deselect();
+		},
+
+		deselectAll: function(){
+			// summary:
+			//		Deselects all the items.
+			array.forEach(this.getChildren(), function(child){
+				child.deselect && child.deselect();
+			});
+		},
+
+		selectItem: function(/*ListItem*/item){
+			// summary:
+			//		Selects the given item.
+			item.select();
+		}
+	});
+});
diff --git a/dojox/mobile/ScrollableView.js b/dojox/mobile/ScrollableView.js
index 8408418..597291c 100644
--- a/dojox/mobile/ScrollableView.js
+++ b/dojox/mobile/ScrollableView.js
@@ -1,118 +1,139 @@
-dojo.provide("dojox.mobile.ScrollableView");
+define([
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dijit/registry",	// registry.byNode
+	"./View",
+	"./_ScrollableMixin"
+], function(array, declare, domClass, domConstruct, registry, View, ScrollableMixin){
 
-dojo.require("dijit._WidgetBase");
-dojo.require("dojox.mobile");
-dojo.require("dojox.mobile._ScrollableMixin");
+	/*=====
+		var View = dojox.mobile.View;
+		var ScrollableMixin = dojox.mobile._ScrollableMixin;
+	=====*/
 
-// summary:
-//		A container that has a touch scrolling capability.
-// description:
-//		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).
-//		The main purpose of this widget is to realize fixed-positioned header
-//		and/or footer bars.
+	// module:
+	//		dojox/mobile/ScrollableView
+	// summary:
+	//		A container that has a touch scrolling capability.
 
-dojo.declare(
-	"dojox.mobile.ScrollableView",
-	[dojox.mobile.View, dojox.mobile._ScrollableMixin],
-{
-	flippable: false,
+	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).
+		//		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).
+		//		The main purpose of this widget is to realize fixed-positioned header
+		//		and/or footer bars.
 
-	buildRendering: function(){
-		this.inherited(arguments);
-		dojo.addClass(this.domNode, "mblScrollableView");
-		this.domNode.style.overflow = "hidden";
-		this.domNode.style.top = "0px";
-		this.domNode.style.height = "100%";
-		this.containerNode = dojo.create("DIV",
-			{className:"mblScrollableViewContainer"}, this.domNode);
-		this.containerNode.style.position = "absolute";
-		if(this.scrollDir === "v" || this.flippable){
-			this.containerNode.style.width = "100%";
-		}
-		this.reparent();
-		this.findAppBars();
-	},
+		// scrollableParams: Object
+		//		Parameters for dojox.mobile.scrollable.init().
+		scrollableParams: null,
+
+		// keepScrollPos: Boolean
+		//		Overrides dojox.mobile.View.keepScrollPos.
+		keepScrollPos: false,
+
+		constructor: function(){
+			this.scrollableParams = {noResize: true};
+		},
 
-	addChild: function(widget){
-		var c = widget.domNode;
-		var fixed = this._checkFixedBar(c, true);
-		if(fixed){
-			this.domNode.appendChild(c);
-			if(fixed === "top"){
-				this.fixedHeaderHeight = c.offsetHeight;
-				this.containerNode.style.paddingTop = this.fixedHeaderHeight + "px";
-			}else if(fixed === "bottom"){
-				this.fixedFooterHeight = c.offsetHeight;
-				this.isLocalFooter = true;
-				c.style.bottom = "0px";
+		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.resizeView();
-		}else{
-			this.containerNode.appendChild(c);
-		}
-	},
+			this.reparent();
+			this.findAppBars();
+		},
+
+		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(); }
+			});
+		},
+
+		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
+		},
 
-	reparent: function(){
-		// move all the children, except header and footer, 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 || this._checkFixedBar(c, true)){
-				idx++;
-				continue;
+		addChild: function(widget, /*Number?*/insertIndex){
+			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);
 			}
-			this.containerNode.appendChild(this.domNode.removeChild(c));
-		}
-	},
+		},
 
-	findAppBars: function(){
-		// search for application-specific header or footer
-		var i, len, c;
-		for(i = 0, len = dojo.body().childNodes.length; i < len; i++){
-			c = dojo.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);
+		reparent: function(){
+			// summary:
+			//		Moves all the children, except header and footer, 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 || this.checkFixedBar(c, true)){
+					idx++;
+					continue;
+				}
+				this.containerNode.appendChild(this.domNode.removeChild(c));
 			}
-		}
-		this.fixedHeaderHeight = this.fixedHeader ? this.fixedHeader.offsetHeight : 0;
-		this.fixedFooterHeight = this.fixedFooter ? this.fixedFooter.offsetHeight : 0;
-	},
+		},
 
-	_checkFixedBar: function(/*DomNode*/node){
-		if(node.nodeType === 1){
-			var fixed = node.getAttribute("fixed")
-				|| (dijit.byNode(node) && dijit.byNode(node).fixed);
-			if(fixed){
-				dojo.style(node, {
-					position: "absolute",
-					width: "100%",
-					zIndex: 1
-				});
+		onAfterTransitionIn: function(moveTo, dir, transition, context, method){
+			this.flashScrollBar();
+		},
+	
+		getChildren: function(){
+			// summary:
+			//		Overrides _WidgetBase#getChildren to add local fixed bars,
+			//		which are not under containerNode, to the children array.
+			var children = this.inherited(arguments);
+			if(this.fixedHeader && this.fixedHeader.parentNode === this.domNode){
+				children.push(registry.byNode(this.fixedHeader));
 			}
-			if(fixed === "top"){
-				node.style.top = "0px";
-				this.fixedHeader = node;
-				return fixed;
-			}else if(fixed === "bottom"){
-				this.fixedFooter = node;
-				return fixed;
+			if(this.fixedFooter && this.fixedFooter.parentNode === this.domNode){
+				children.push(registry.byNode(this.fixedFooter));
 			}
+			return children;
 		}
-		return null;
-	},
-
-	onAfterTransitionIn: function(moveTo, dir, transition, context, method){
-		this.flashScrollBar();
-	}
+	});
 });
diff --git a/dojox/mobile/Slider.js b/dojox/mobile/Slider.js
new file mode 100644
index 0000000..222ed96
--- /dev/null
+++ b/dojox/mobile/Slider.js
@@ -0,0 +1,163 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-geometry",
+	"dojo/dom-style",
+	"dijit/_WidgetBase",
+	"dijit/form/_FormValueMixin"
+],
+	function(array, connect, declare, lang, win, domClass, domConstruct, domGeometry, domStyle, 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.
+		value: 0,
+
+		// min: [const] Number
+		//		The first value the slider can be set to.
+		min: 0,
+
+		// max: [const] Number
+		//		The last value the slider can be set to.
+		max: 100,
+
+		// step: [const] Number
+		//		The delta from 1 value to another.
+		//		This causes the slider handle to snap/jump to the closest possible value.
+		//		A value of 0 means continuous (as much as allowed by pixel resolution).
+		step: 1,
+
+		baseClass: "mblSlider",
+
+		// flip: [const] Boolean
+		//		Specifies if the slider should change its default: ascending <--> descending.
+		flip: false,
+
+		// 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)
+		orientation: "auto",
+
+		// halo: Number
+		//		Size of the boundary that extends beyond the edges of the slider
+		//		to make it easier to touch.
+		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");
+			this.inherited(arguments);
+		},
+
+		_setValueAttr: function(/*Number*/ value, /*Boolean?*/ priorityChange){
+			// summary:
+			//		Hook so set('value', value) works.
+			var fromPercent = (this.value - this.min) * 100 / (this.max - this.min);
+			this.valueNode.value = value;
+			this.inherited(arguments);
+			if(!this._started){ return; } // don't move images until all the properties are set
+			this.focusNode.setAttribute("aria-valuenow", value);
+			var toPercent = (value - this.min) * 100 / (this.max - this.min);
+			// now perform visual slide
+			var horizontal = this.orientation != "V";
+			if(priorityChange === true){
+				domClass.add(this.handle, "mblSliderTransition");
+				domClass.add(this.progressBar, "mblSliderTransition");
+			}else{
+				domClass.remove(this.handle, "mblSliderTransition");
+				domClass.remove(this.progressBar, "mblSliderTransition");
+			}
+			domStyle.set(this.handle, this._attrs.handleLeft, (this._reversed ? (100-toPercent) : toPercent) + "%");
+			domStyle.set(this.progressBar, this._attrs.width, toPercent + "%");
+		},
+
+		postCreate: function(){
+			this.inherited(arguments);
+
+			function beginDrag(e){
+				function getEventData(e){
+					point = isMouse ? e[this._attrs.pageX] : (e.touches ? e.touches[0][this._attrs.pageX] : e[this._attrs.clientX]);
+					pixelValue = point - startPixel;
+					pixelValue = Math.min(Math.max(pixelValue, 0), maxPixels);
+					var discreteValues = this.step ? ((this.max - this.min) / this.step) : maxPixels;
+					if(discreteValues <= 1 || discreteValues == Infinity ){ discreteValues = maxPixels; }
+					var wholeIncrements = Math.round(pixelValue * discreteValues / maxPixels);
+					value = (this.max - this.min) * wholeIncrements / discreteValues;
+					value = this._reversed ? (this.max - value) : (this.min + value);
+				}
+				function continueDrag(e){
+					e.preventDefault();
+					lang.hitch(this, getEventData)(e);
+					this.set('value', value, false);
+				}
+		
+				function endDrag(e){
+					e.preventDefault();
+					array.forEach(actionHandles, lang.hitch(this, "disconnect"));
+					actionHandles = [];
+					this.set('value', this.value, true);
+				}
+
+				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;
+				if(isNaN(bodyZoom)){ bodyZoom = 1; }
+				var nodeZoom = 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;
+				lang.hitch(this, getEventData)(e);
+				if(e.target == this.touchBox){
+					this.set('value', value, true);
+				}
+				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)
+				];
+			}
+
+			var point, pixelValue, value;
+			var 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;
+			// _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._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.startup();
+			this.set('value', this.value);
+		}
+	});
+});
diff --git a/dojox/mobile/SpinWheel.js b/dojox/mobile/SpinWheel.js
new file mode 100644
index 0000000..c8b58f6
--- /dev/null
+++ b/dojox/mobile/SpinWheel.js
@@ -0,0 +1,97 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/dom-class",
+	"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;
+=====*/
+
+	// module:
+	//		dojox/mobile/SpinWheel
+	// summary:
+	//		A value picker widget that has spin wheels.
+
+	return declare("dojox.mobile.SpinWheel", [WidgetBase, Container, Contained],{
+		// summary:
+		//		A value picker widget that has spin wheels.
+		// description:
+		//		SpinWheel is a value picker component. It is a sectioned wheel
+		//		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,
+
+		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);
+		},
+
+		startup: function(){
+			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);
+		},
+
+		reset: function(){
+			// summary:
+			//		Resets the SpinWheel to show the initial values.
+			array.forEach(this.getChildren(), function(w){
+				if(w instanceof SpinWheelSlot){
+					w.setInitialValue();
+				}
+			}, this);
+		}
+	});
+});
diff --git a/dojox/mobile/SpinWheelDatePicker.js b/dojox/mobile/SpinWheelDatePicker.js
new file mode 100644
index 0000000..3a533d0
--- /dev/null
+++ b/dojox/mobile/SpinWheelDatePicker.js
@@ -0,0 +1,109 @@
+define([
+	"dojo/_base/declare",
+	"dojo/dom-class",
+	"dojo/date",
+	"dojo/date/locale",
+	"./SpinWheel",
+	"./SpinWheelSlot"
+], function(declare, domClass, ddate, datelocale, SpinWheel, SpinWheelSlot){
+
+/*=====
+	var SpinWheel = dojox.mobile.SpinWheel;
+	var SpinWheelSlot = dojox.mobile.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, {
+		// 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.
+
+		slotClasses: [
+			SpinWheelYearSlot,
+			SpinWheelMonthSlot,
+			SpinWheelDaySlot
+		],
+		slotProps: [
+			{labelFrom:1970, labelTo:2038},
+			{},
+			{labelFrom:1, labelTo:31}
+		],
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			domClass.add(this.domNode, "mblSpinWheelDatePicker");
+			this.connect(this.slots[1], "onFlickAnimationEnd", "onMonthSet");
+			this.connect(this.slots[2], "onFlickAnimationEnd", "onDaySet");
+		},
+
+		reset: function(){
+			// 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;
+		}
+	});
+});
diff --git a/dojox/mobile/SpinWheelSlot.js b/dojox/mobile/SpinWheelSlot.js
new file mode 100644
index 0000000..e31ce9c
--- /dev/null
+++ b/dojox/mobile/SpinWheelSlot.js
@@ -0,0 +1,327 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/window",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"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;
+=====*/
+
+	// module:
+	//		dojox/mobile/SpinWheelSlot
+	// summary:
+	//		A slot of a SpinWheel.
+
+	return declare("dojox.mobile.SpinWheelSlot", [WidgetBase, Contained, ScrollableMixin], {
+		// 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
+		//		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
+		//		items property.
+		labels: [],
+
+		// labelFrom: Number
+		//		The start value of display values of the slot. This parameter is
+		//		especially useful when slot has serial values.
+		labelFrom: 0,
+
+		// labelTo: Number
+		//		The end value of display values of the slot.
+		labelTo: 0,
+
+		// value: String
+		//		The initial value of the slot.
+		value: "",
+
+		/* internal properties */	
+		maxSpeed: 500,
+		minItems: 15,
+		centerPos: 0,
+		scrollBar: false,
+		constraint: false,
+		allowNestedScrolls: false,
+		androidWorkaroud: false, // disable workaround in SpinWheel
+
+		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);
+				}
+			}
+			if(this.labels.length > 0){
+				this.items = [];
+				for(i = 0; i < this.labels.length; i++){
+					this.items.push([i, this.labels[i]]);
+				}
+			}
+
+			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"});
+				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]);
+					}
+				}
+				this.containerNode.appendChild(this.panelNodes[k]);
+			}
+			this.domNode.appendChild(this.containerNode);
+			this.touchNode = domConstruct.create("DIV", {className:"mblSpinWheelSlotTouch"}, this.domNode);
+			this.setSelectable(this.domNode, false);
+		},
+	
+		startup: function(){
+			this.inherited(arguments);
+			this.centerPos = this.getParent().centerPos;
+			var items = this.panelNodes[1].childNodes;
+			this._itemHeight = items[0].offsetHeight;
+			this.adjust();
+		},
+	
+		adjust: function(){
+			// summary:
+			//		Adjusts the position of slot panels.
+			var items = this.panelNodes[1].childNodes;
+			var adjustY;
+			for(var i = 0, len = items.length; i < len; i++){
+				var item = items[i];
+				if(item.offsetTop <= this.centerPos && this.centerPos < item.offsetTop + item.offsetHeight){
+					adjustY = this.centerPos - (item.offsetTop + Math.round(item.offsetHeight/2));
+					break;
+				}
+			}
+			var h = this.panelNodes[0].offsetHeight;
+			this.panelNodes[0].style.top = -h + adjustY + "px";
+			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);
+			}
+		},
+	
+		getCenterPanel: function(){
+			// summary:
+			//		Gets a panel that contains the currently selected item.
+			var pos = this.getPos();
+			for(var i = 0, len = this.panelNodes.length; i < len; i++){
+				var top = pos.y + this.panelNodes[i].offsetTop;
+				if(top <= this.centerPos && this.centerPos < top + this.panelNodes[i].offsetHeight){
+					return this.panelNodes[i];
+				}
+			}
+			return null;
+		},
+	
+		setColor: function(/*String*/value){
+			// 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");
+					}
+				}
+			}
+		},
+	
+		disableValues: function(/*Array*/values){
+			// 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;
+						}
+					}
+				}
+			}
+		},
+	
+		getCenterItem: function(){
+			// summary:
+			//		Gets the currently selected item.
+			var pos = this.getPos();
+			var centerPanel = this.getCenterPanel();
+			if(centerPanel){
+				var top = pos.y + centerPanel.offsetTop;
+				var items = centerPanel.childNodes;
+				for(var i = 0, len = items.length; i < len; i++){
+					if(top + items[i].offsetTop <= this.centerPos && this.centerPos < top + items[i].offsetTop + items[i].offsetHeight){
+						return items[i];
+					}
+				}
+			}
+			return null;
+	
+		},
+	
+		getValue: function(){
+			// summary:
+			//		Gets the currently selected value.
+			var item = this.getCenterItem();
+			return (item && item.innerHTML);
+		},
+	
+		getKey: function(){
+			// summary:
+			//		Gets the key for the currently selected value.
+			return this.getCenterItem().getAttribute("name");
+		},
+	
+		setValue: function(newValue){
+			// summary:
+			//		Sets the newValue to this slot.
+			var idx0, idx1;
+			var curValue = this.getValue();
+			if(!curValue){
+				this._penddingValue = newValue;
+				return;
+			}
+			this._penddingValue = undefined;
+			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)){
+					idx1 = i;
+				}
+				if(idx0 !== undefined && idx1 !== undefined){
+					break;
+				}
+			}
+			var d = idx1 - (idx0 || 0);
+			var m;
+			if(d > 0){
+				m = (d < n - d) ? -d : n - d;
+			}else{
+				m = (-d < n + d) ? -d : -(n + d);
+			}
+			var to = this.getPos();
+			to.y += m * this._itemHeight;
+			this.slideTo(to, 1);
+		},
+	
+		getSpeed: function(){
+			// summary:
+			//		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){
+				var dy = this._posY[n - 1] - this._posY[(n - 6) >= 0 ? n - 6 : 0];
+				var dt = this._time[n - 1] - this._time[(n - 6) >= 0 ? n - 6 : 0];
+				y = this.calcSpeed(dy, dt);
+			}
+			return {x:0, y:y};
+		},
+
+		calcSpeed: function(/*Number*/d, /*Number*/t){
+			// summary:
+			//		Overrides dojox.mobile.scrollable.calcSpeed().
+			var speed = this.inherited(arguments);
+			if(!speed){ return 0; }
+			var v = Math.abs(speed);
+			var ret = speed;
+			if(v > this.maxSpeed){
+				ret = this.maxSpeed*(speed/v);
+			}
+			return ret;
+		},
+	
+		adjustDestination: function(to, pos){
+			// summary:
+			//		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;
+		},
+	
+		resize: function(e){
+			if(this._penddingValue){
+				this.setValue(this._penddingValue);
+			}
+		},
+
+		slideTo: function(/*Object*/to, /*Number*/duration, /*String*/easing){
+			// summary:
+			//		Overrides dojox.mobile.scrollable.slideTo().
+			var pos = this.getPos();
+			var top = pos.y + this.panelNodes[1].offsetTop;
+			var bottom = top + this.panelNodes[1].offsetHeight;
+			var vh = this.domNode.parentNode.offsetHeight;
+			var t;
+			if(pos.y < to.y){ // going down
+				if(bottom > vh){
+					// move up the bottom panel
+					t = this.panelNodes[2];
+					t.style.top = this.panelNodes[0].offsetTop - this.panelNodes[0].offsetHeight + "px";
+					this.panelNodes[2] = this.panelNodes[1];
+					this.panelNodes[1] = this.panelNodes[0];
+					this.panelNodes[0] = t;
+				}
+			}else if(pos.y > to.y){ // going up
+				if(top < 0){
+					// move down the top panel
+					t = this.panelNodes[0];
+					t.style.top = this.panelNodes[2].offsetTop + this.panelNodes[2].offsetHeight + "px";
+					this.panelNodes[0] = this.panelNodes[1];
+					this.panelNodes[1] = this.panelNodes[2];
+					this.panelNodes[2] = t;
+				}
+			}
+			if(!this._initialized){
+				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
+		}
+	});
+});
diff --git a/dojox/mobile/SpinWheelTimePicker.js b/dojox/mobile/SpinWheelTimePicker.js
new file mode 100644
index 0000000..c94745e
--- /dev/null
+++ b/dojox/mobile/SpinWheelTimePicker.js
@@ -0,0 +1,57 @@
+define([
+	"dojo/_base/declare",
+	"dojo/dom-class",
+	"./SpinWheel",
+	"./SpinWheelSlot"
+], function(declare, domClass, SpinWheel, SpinWheelSlot){
+
+/*=====
+	var SpinWheel = dojox.mobile.SpinWheel;
+=====*/
+
+	// module:
+	//		dojox/mobile/SpinWheelTimePicker
+	// summary:
+	//		A SpinWheel-based time picker widget.
+
+	return declare("dojox.mobile.SpinWheelTimePicker", SpinWheel, {
+		// 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.
+
+		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"]}
+		],
+
+		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/SwapView.js b/dojox/mobile/SwapView.js
new file mode 100644
index 0000000..fce753a
--- /dev/null
+++ b/dojox/mobile/SwapView.js
@@ -0,0 +1,228 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/dom",
+	"dojo/dom-class",
+	"dijit/registry",	// registry.byNode
+	"./View",
+	"./_ScrollableMixin"
+], function(array, connect, declare, dom, domClass, registry, View, ScrollableMixin){
+
+/*=====
+	var View = dojox.mobile.View;
+	var ScrollableMixin = dojox.mobile._ScrollableMixin;
+=====*/
+
+	// module:
+	//		dojox/mobile/SwapView
+	// summary:
+	//		A container that can be flipped horizontally.
+
+	return declare("dojox.mobile.SwapView", [View, ScrollableMixin], {
+		// summary:
+		//		A container that can be flipped 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.
+
+		/* internal properties */	
+		scrollDir: "f",
+		weight: 1.2,
+
+		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();
+		},
+
+		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(); }
+			});
+		},
+
+		onTouchStart: function(e){
+			// summary:
+			//		Internal function to handle touchStart events.
+			var fromTop = this.domNode.offsetTop;
+			var nextView = this.nextView(this.domNode);
+			if(nextView){
+				nextView.stopAnimation();
+				domClass.add(nextView.domNode, "mblIn");
+				// Temporarily add padding to align with the fromNode while transition
+				nextView.containerNode.style.paddingTop = fromTop + "px";
+			}
+			var prevView = this.previousView(this.domNode);
+			if(prevView){
+				prevView.stopAnimation();
+				domClass.add(prevView.domNode, "mblIn");
+				// Temporarily add padding to align with the fromNode while transition
+				prevView.containerNode.style.paddingTop = fromTop + "px";
+			}
+			this.inherited(arguments);
+		},
+
+		handleNextPage: function(/*Widget*/w){
+			// summary:
+			//		Called when the "/dojox/mobile/nextPage" topic is published.
+			var refNode = w.refId && dom.byId(w.refId) || w.domNode;
+			if(this.domNode.parentNode !== refNode.parentNode){ return; }
+			if(this.getShowingView() !== this){ return; }
+			this.goTo(1);
+		},
+
+		handlePrevPage: function(/*Widget*/w){
+			// summary:
+			//		Called when the "/dojox/mobile/prevPage" topic is published.
+			var refNode = w.refId && dom.byId(w.refId) || w.domNode;
+			if(this.domNode.parentNode !== refNode.parentNode){ return; }
+			if(this.getShowingView() !== this){ return; }
+			this.goTo(-1);
+		},
+
+		goTo: function(/*Number*/dir){
+			// 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){
+			// summary:
+			//		Returns true if the given node is a SwapView widget.
+			return (node && node.nodeType === 1 && domClass.contains(node, "mblSwapView"));
+		},
+
+		nextView: function(node){
+			// summary:
+			//		Returns the next view.
+			for(var n = node.nextSibling; n; n = n.nextSibling){
+				if(this.isSwapView(n)){ return registry.byNode(n); }
+			}
+			return null;
+		},
+
+		previousView: function(node){
+			// summary:
+			//		Returns the previous view.
+			for(var n = node.previousSibling; n; n = n.previousSibling){
+				if(this.isSwapView(n)){ return registry.byNode(n); }
+			}
+			return null;
+		},
+
+		scrollTo: function(/*Object*/to){
+			// summary:
+			//		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(newView){
+					newView.domNode.style.display = "";
+					newView._beingFlipped = true;
+					newView.scrollTo({x:x});
+					newView._beingFlipped = false;
+				}
+			}
+			this.inherited(arguments);
+		},
+
+		slideTo: function(/*Object*/to, /*Number*/duration, /*String*/easing, fake_pos){
+			// summary:
+			//		Overrides dojox.mobile.scrollable.slideTo().
+			if(!this._beingFlipped){
+				var w = this.domNode.offsetWidth;
+				var pos = fake_pos || this.getPos();
+				var newView, newX;
+				if(pos.x < 0){ // moving to left
+					newView = this.nextView(this.domNode);
+					if(pos.x < -w/4){ // slide to next
+						if(newView){
+							to.x = -w;
+							newX = 0;
+						}
+					}else{ // go back
+						if(newView){
+							newX = w;
+						}
+					}
+				}else{ // moving to right
+					newView = this.previousView(this.domNode);
+					if(pos.x > w/4){ // slide to previous
+						if(newView){
+							to.x = w;
+							newX = 0;
+						}
+					}else{ // go back
+						if(newView){
+							newX = -w;
+						}
+					}
+				}
+	
+				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){
+			// 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";
+					}
+				}
+			}
+			this.inherited(arguments);
+			if(this.getShowingView() === this){
+				connect.publish("/dojox/mobile/viewChanged", [this]);
+				// Reset the temporary padding
+				this.containerNode.style.paddingTop = "";
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/Switch.js b/dojox/mobile/Switch.js
new file mode 100644
index 0000000..f4b258e
--- /dev/null
+++ b/dojox/mobile/Switch.js
@@ -0,0 +1,222 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/_base/event",
+	"dojo/_base/window",
+	"dojo/dom-class",
+	"dijit/_Contained",
+	"dijit/_WidgetBase",
+	"./sniff"
+], function(array, connect, declare, event, win, domClass, Contained, WidgetBase, has){
+
+/*=====
+	Contained = dijit._Contained;
+	WidgetBase = dijit._WidgetBase;
+=====*/
+
+	// module:
+	//		dojox/mobile/Switch
+	// summary:
+	//		A toggle switch with a sliding knob.
+
+	return declare("dojox.mobile.Switch", [WidgetBase, Contained],{
+		// summary:
+		//		A toggle switch with a sliding knob.
+		// description:
+		//		Switch is a toggle switch with a sliding knob. You can either
+		//		tap or slide the knob to toggle the switch. The onStateChanged
+		//		handler is called when the switch is manipulated.
+
+		// value: String
+		//		The initial state of the switch. "on" or "off". The default
+		//		value is "on".
+		value: "on",
+
+		// name: String
+		//		A name for a hidden input field, which holds the current value.
+		name: "",
+
+		// leftLabel: String
+		//		The left-side label of the switch.
+		leftLabel: "ON",
+
+		// rightLabel: String
+		//		The right-side label of the switch.
+		rightLabel: "OFF",
+
+		/* internal properties */	
+		_width: 53,
+
+		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];
+		},
+
+		postCreate: function(){
+			this.connect(this.domNode, "onclick", "onClick");
+			this.connect(this.domNode, has('touch') ? "touchstart" : "onmousedown", "onTouchStart");
+			this._initialValue = this.value; // for reset()
+		},
+
+		_changeState: function(/*String*/state, /*Boolean*/anim){
+			var on = (state === "on");
+			this.left.style.display = "";
+			this.right.style.display = "";
+			this.inner.style.left = "";
+			if(anim){
+				domClass.add(this.domNode, "mblSwitchAnimation");
+			}
+			domClass.remove(this.domNode, on ? "mblSwitchOff" : "mblSwitchOn");
+			domClass.add(this.domNode, on ? "mblSwitchOn" : "mblSwitchOff");
+	
+			var _this = this;
+			setTimeout(function(){
+				_this.left.style.display = on ? "" : "none";
+				_this.right.style.display = !on ? "" : "none";
+				domClass.remove(_this.domNode, "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);
+			}
+		},
+	
+		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){
+			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){
+			// 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.touchStartX = e.touches ? e.touches[0].pageX : e.clientX;
+			this.left.style.display = "";
+			this.right.style.display = "";
+			event.stop(e);
+		},
+	
+		onTouchMove: function(e){
+			// summary:
+			//		Internal function to handle touchMove events.
+			e.preventDefault();
+			var dx;
+			if(e.targetTouches){
+				if(e.targetTouches.length != 1){ return false; }
+				dx = e.targetTouches[0].clientX - this.touchStartX;
+			}else{
+				dx = e.clientX - this.touchStartX;
+			}
+			var pos = this.innerStartX + dx;
+			var d = 10;
+			if(pos <= -(this._width-d)){ pos = -this._width; }
+			if(pos >= -d){ pos = 0; }
+			this.inner.style.left = pos + "px";
+			if(Math.abs(dx) > d){
+				this._moved = true;
+			}
+		},
+	
+		onTouchEnd: function(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);
+				}
+				return;
+			}
+			var newState = (this.inner.offsetLeft < -(this._width/2)) ? "off" : "on";
+			this._changeState(newState, true);
+			if(newState != this.value){
+				this.value = this.input.value = newState;
+				this.onStateChanged(newState);
+			}
+		},
+	
+		onStateChanged: function(/*String*/newState){
+			// summary:
+			//		Stub function to connect to from your application.
+			// description:
+			//		Called when the state has been changed.
+		},
+	
+		_setValueAttr: function(/*String*/value){
+			this._changeState(value, false);
+			if(this.value != value){
+				this.onStateChanged(value);
+			}
+			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;
+		},
+
+		reset: function(){
+			// summary:
+			//		Reset the widget's value to what it was at initialization time
+			this.set("value", this._initialValue);
+		}
+	});
+});
diff --git a/dojox/mobile/TabBar.js b/dojox/mobile/TabBar.js
index 7b603f7..6d719d8 100644
--- a/dojox/mobile/TabBar.js
+++ b/dojox/mobile/TabBar.js
@@ -1,205 +1,153 @@
-dojo.provide("dojox.mobile.TabBar");
-
-dojo.require("dojox.mobile");
-
-dojo.declare(
-	"dojox.mobile.TabBar",
-	dijit._WidgetBase,
-{
-	iconBase: "",
-	iconPos: "",
-	barType: "tabBar", // "tabBar"(default) or "segmentedControl"
-	inHeading: false,
-
-	_fixedButtonWidth: 76,
-	_fixedButtonMargin: 17,
-	_largeScreenWidth: 500,
-
-	buildRendering: function(){
-		this._clsName = this.barType == "segmentedControl" ? "mblTabButton" : "mblTabBarButton";
-		this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("H1");
-		this.domNode.className = this.barType == "segmentedControl" ? "mblTabPanelHeader" : "mblTabBar";
-	},
-
-	postCreate: function(){
-		if(dojo.global.onorientationchange !== undefined){
-			this.connect(dojo.global, "onorientationchange", "onResize");
-		}else{
-			this.connect(dojo.global, "onresize", "onResize");
-		}
-	},
-
-	startup: function(){
-		var _this = this;
-		setTimeout(function(){ // to get proper dimension
-			_this.onResize();
-		}, 0);
-	},
-
-	onResize: function(){
-		var i;
-		var w = dojo.marginBox(this.domNode.parentNode).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(dojo.hasClass(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 -= dojo.marginBox(arr[i]).w;
-				arr[i].style.marginTop = "3px";
-				totalW += arr[i].offsetWidth;
+define([
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-geometry",
+	"dojo/dom-style",
+	"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;
+=====*/
+
+	// module:
+	//		dojox/mobile/TabBar
+	// summary:
+	//		A bar widget that has buttons to control visibility of views.
+
+	return declare("dojox.mobile.TabBar", [WidgetBase, Container, Contained],{
+		// summary:
+		//		A bar widget that has buttons to control visibility of views.
+		// description:
+		//		TabBar is a container widget that has typically multiple
+		//		TabBarButtons which controls visibility of views. It can be used
+		//		as a tab container.
+
+		// iconBase: String
+		//		The default icon path for child items.
+		iconBase: "",
+
+		// iconPos: String
+		//		The default icon position for child items.
+		iconPos: "",
+
+		// barType: String
+		//		"tabBar"(default) or "segmentedControl".
+		barType: "tabBar",
+
+		// inHeading: Boolean
+		//		A flag that indicates whether this widget is in a Heading
+		//		widget.
+		inHeading: false,
+
+		// tag: String
+		//		A name of html tag to create as domNode.
+		tag: "UL",
+
+		/* internal properties */	
+		_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";
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+			this.inherited(arguments);
+			this.resize();
+		},
+
+		resize: function(size){
+			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;
 			}
-			margin = Math.floor(margin/2);
-			var parent = dijit.getEnclosingWidget(this.domNode.parentNode);
-			var inHeading = this.inHeading || parent instanceof dojox.mobile.Heading;
-			this.containerNode.style.padding = "3px 0px 0px " + (inHeading ? 0 : margin) + "px";
-			if(inHeading){
-				dojo.style(this.domNode, {
-					background: "none",
-					border: "none",
-					width: totalW + 2 + "px"
-				});
+			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);
+				}
 			}
-		}else{
-			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)
+	
+			var margin;
+			if(this.barType == "segmentedControl"){
+				margin = w;
+				var totalW = 0; // total width of all the buttons
 				for(i = 0; i < arr.length; i++){
-					arr[i].style.width = Math.round(98/arr.length) + "%";
-					arr[i].style.margin = "0px";
+					margin -= domGeometry.getMarginBox(arr[i]).w;
+					totalW += arr[i].offsetWidth;
 				}
-				this.containerNode.style.padding = "0px 0px 0px 1%";
+				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{
-				// Fixed width buttons. Mainly for larger screen such as iPad.
-				for(i = 0; i < arr.length; i++){
-					arr[i].style.width = bw + "px";
-					arr[i].style.margin = "0 " + bm + "px";
+				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)
+					for(i = 0; i < arr.length; i++){
+						arr[i].style.width = Math.round(98/arr.length) + "%";
+						arr[i].style.margin = "0px";
+					}
+					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++){
+						arr[i].style.width = bw + "px";
+						arr[i].style.margin = "0 " + bm + "px";
+					}
+					if(arr.length > 0){
+						arr[0].style.marginLeft = margin + bm + "px";
+					}
+					this.containerNode.style.padding = "0px";
 				}
-				this.containerNode.style.padding = "0px 0px 0px " + margin + "px";
 			}
-		}
-	}
-});
 
-dojo.declare(
-	"dojox.mobile.TabBarButton",
-	dojox.mobile.AbstractItem,
-{
-	icon1: "", // unselected (dark) icon
-	icon2: "", // selected (highlight) icon
-	iconPos1: "", // unselected (dark) icon position
-	iconPos2: "", // selected (highlight) icon position
-	selected: false,
-	transition: "none",
-	tag: "LI",
-	selectOne: true,
-
-	inheritParams: function(){
-		var parent = this.getParentWidget();
-		this.parent = parent;
-		if(parent){
-			if(!this.transition){ this.transition = parent.transition; }
-			if(!this.icon1){ this.icon1 = parent.iconBase; }
-			if(!this.iconPos1){ this.iconPos1 = parent.iconPos; }
-			if(!this.icon2){ this.icon2 = parent.iconBase || this.icon1; }
-			if(!this.iconPos2){ this.iconPos2 = parent.iconPos || this.iconPos1; }
-		}
-	},
-
-	buildRendering: function(){
-		this.inheritParams();
-
-		this.anchorNode = dojo.create("A", {className:"mblTabBarButtonAnchor"});
-		var a = this.anchorNode;
-		this.connect(a, "onclick", "onClick");
-
-		var div = dojo.create("DIV", {className:"mblTabBarButtonDiv"}, a);
-		var divInner = dojo.create("DIV", {className:"mblTabBarButtonDiv mblTabBarButtonDivInner"}, div);
-
-		this.img1 = dojo.create("IMG", {className:"mblTabBarButtonIcon", src:this.icon1}, divInner);
-		this.img1.style.visibility = this.selected ? "hidden" : "";
-		dojox.mobile.setupIcon(this.img1, this.iconPos1);
-		this.img1.onload = function(){
-			// iPhone and Windows Safari sometimes fail to draw icon images.
-			// For some reason, this code solves the problem.
-			// Other browsers, including Chrome, do not have this problem.
-			this.style.width = this.width + "px";
-			this.style.height = this.height + "px";
-		};
-
-		this.img2 = dojo.create("IMG", {className:"mblTabBarButtonIcon", src:this.icon2}, divInner);
-		this.img2.style.visibility = this.selected ? "" : "hidden";
-		dojox.mobile.setupIcon(this.img2, this.iconPos2);
-		this.img2.onload = function(){
-			this.style.width = this.width + "px";
-			this.style.height = this.height + "px";
-		};
-
-		this.box = dojo.create("DIV", {className:"mblTabBarButtonTextBox"}, a);
-		var box = this.box;
-		var r = this.srcNodeRef;
-		if(r){
-			for(var i = 0, len = r.childNodes.length; i < len; i++){
-				box.appendChild(r.firstChild);
+			if(!array.some(this.getChildren(), function(child){ return child.iconNode1; })){
+				domClass.add(this.domNode, "mblTabBarNoIcons");
+			}else{
+				domClass.remove(this.domNode, "mblTabBarNoIcons");
 			}
-		}
-		if(this.label){
-			box.appendChild(dojo.doc.createTextNode(this.label));
-		}
-
-		this.domNode = this.srcNodeRef || dojo.create(this.tag);
-		this.containerNode = this.domNode;
-		var _clsName = this.parent ? this.parent._clsName : "mblTabBarButton";
-		dojo.addClass(this.domNode, _clsName + (this.selected ? " mblTabButtonSelected" : ""));
-		this.domNode.appendChild(a);
-
-		this.createDomButton(this.domNode, a);
-	},
 
-	startup: function(){
-		var parent = this.getParentWidget();
-		this.parent = parent;
-		if(parent && parent.barType == "segmentedControl"){
-			// proper className may not be set when created dynamically
-			dojo.removeClass(this.domNode, "mblTabBarButton");
-			dojo.addClass(this.domNode, parent._clsName);
-			this.box.className = "";
-		}
-	},
-
-	select: function(deselect){
-		if(deselect){
-			this.selected = false;
-			dojo.removeClass(this.domNode, "mblTabButtonSelected");
-		}else{
-			this.selected = true;
-			dojo.addClass(this.domNode, "mblTabButtonSelected");
-			for(var i = 0, c = this.domNode.parentNode.childNodes; i < c.length; i++){
-				if(c[i].nodeType != 1){ continue; }
-				var w = dijit.byNode(c[i]); // sibling widget
-				if(w && w != this){
-					w.select(true);
-				}
+			if(!array.some(this.getChildren(), function(child){ return child.label; })){
+				domClass.add(this.domNode, "mblTabBarNoText");
+			}else{
+				domClass.remove(this.domNode, "mblTabBarNoText");
 			}
 		}
-		this.img1.style.visibility = this.selected ? "hidden" : "";
-		this.img2.style.visibility = this.selected ? "" : "hidden";
-	},
+	});
 
-	onClick: function(e){
-		this.defaultClickAction();
-	}
 });
diff --git a/dojox/mobile/TabBarButton.js b/dojox/mobile/TabBarButton.js
new file mode 100644
index 0000000..aef79fe
--- /dev/null
+++ b/dojox/mobile/TabBarButton.js
@@ -0,0 +1,231 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"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;
+=====*/
+
+	// module:
+	//		dojox/mobile/TabBarButton
+	// summary:
+	//		A button widget that is placed in the TabBar widget.
+
+	return declare("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
+		//		IconItem. So, unlike Button, it has similar capability as
+		//		ListItem or IconItem, such as icon support, transition, etc.
+
+		// 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 comma separated 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
+		//		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.
+		selected: false,
+
+		// transition: String
+		//		A type of animated transition effect.
+		transition: "none",
+
+		// tag: String
+		//		A name of html tag to create as domNode.
+		tag: "LI",
+
+		/* internal properties */	
+		selectOne: true,
+
+	
+		inheritParams: function(){
+			// summary:
+			//		Overrides dojox.mobile._ItemBase.inheritParams().
+			if(this.icon && !this.icon1){ this.icon1 = this.icon; }
+			var parent = this.getParent();
+			if(parent){
+				if(!this.transition){ this.transition = parent.transition; }
+				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; }
+			}
+		},
+	
+		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);
+					}
+					box.appendChild(n);
+				}
+			}
+			if(!this.label){
+				this.label = label;
+			}
+	
+			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.icon1 || this.icon).indexOf("mblDomButton") != -1){
+				domClass.add(this.domNode, "mblTabButtonDomButton");
+			}
+		},
+	
+		startup: function(){
+			if(this._started){ return; }
+			this.inheritParams();
+			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 = "";
+			}
+			this.set({icon1:this.icon1, icon2:this.icon2});
+			this.inherited(arguments);
+		},
+	
+		select: function(){
+			// 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";
+			}
+		},
+		
+		deselect: function(){
+			// summary:
+			//		Makes this widget in the deselected state.
+			this.select(true);
+		},
+	
+		onClick: function(e){
+			this.defaultClickAction();
+		},
+	
+		_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;
+			}
+			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);
+				}else{
+					domConstruct.empty(this[n]);
+				}
+				common.createIcon(icon, this[p], null, this.alt, this[n]);
+				if(this[p]){
+					domClass.add(this[n].firstChild, "mblTabBarButtonSpriteIcon");
+				}
+				domClass.remove(this.iconDivNode, "mblTabBarButtonNoIcon");
+				this[n].style.visibility = sel ? "hidden" : "";
+			}else if(this.iconDivNode){
+				domClass.add(this.iconDivNode, "mblTabBarButtonNoIcon");
+			}
+		},
+	
+		_setIcon1Attr: function(icon){
+			this._setIcon(icon, null, 1, this.selected);
+		},
+	
+		_setIcon2Attr: function(icon){
+			this._setIcon(icon, null, 2, !this.selected);
+		},
+	
+		_setIconPos1Attr: function(pos){
+			this._setIcon(null, pos, 1, this.selected);
+		},
+	
+		_setIconPos2Attr: function(pos){
+			this._setIcon(null, pos, 2, !this.selected);
+		},
+
+		_setLabelAttr: function(/*String*/text){
+			this.label = text;
+			this.box.innerHTML = this._cv ? this._cv(text) : text;
+		}
+	});
+});
diff --git a/dojox/mobile/TabContainer.js b/dojox/mobile/TabContainer.js
deleted file mode 100644
index bbd3d20..0000000
--- a/dojox/mobile/TabContainer.js
+++ /dev/null
@@ -1,151 +0,0 @@
-dojo.provide("dojox.mobile.TabContainer");
-
-dojo.require("dojox.mobile");
-
-// Deprecated. Use dojox.mobile.TabBar instead.
-dojo.declare(
-	"dojox.mobile.TabContainer",
-	dijit._WidgetBase,
-{
-	iconBase: "",
-	iconPos: "",
-	fixedHeader: false,
-
-	constructor: function(){
-		dojo.deprecated("dojox.mobile.TabContainer is deprecated", "use dojox.mobile.TabBar instead", 2.0);
-	},
-
-	buildRendering: function(){
-		var node = this.domNode = this.srcNodeRef;
-		node.className = "mblTabContainer";
-		var headerNode = this.tabHeaderNode = dojo.doc.createElement("DIV");
-		var paneNode = this.containerNode = dojo.doc.createElement("DIV");
-
-		// reparent
-		for(var i = 0, len = node.childNodes.length; i < len; i++){
-			paneNode.appendChild(node.removeChild(node.firstChild));
-		}
-
-		headerNode.className = "mblTabPanelHeader";
-		headerNode.align = "center";
-		if(this.fixedHeader){
-			var view = dijit.getEnclosingWidget(this.domNode.parentNode); // parentNode is null if created programmatically
-			view.domNode.insertBefore(headerNode, view.domNode.firstChild);
-			dojo.style(headerNode, {
-				position: "absolute",
-				width: "100%",
-				top: "0px",
-				zIndex: "1"
-			});
-			view.fixedHeader = headerNode;
-		}else{
-			node.appendChild(headerNode);
-		}
-		paneNode.className = "mblTabPanelPane";
-		node.appendChild(paneNode);
-	},
-
-	startup: function(){
-		this.createTabButtons();
-		this.inherited(arguments);
-	},
-
-	createTabButtons: function(){
-		var div = dojo.doc.createElement("DIV");
-		div.align = "center";
-		var tbl = dojo.doc.createElement("TABLE");
-		var cell = tbl.insertRow(-1).insertCell(-1);
-		var children = this.containerNode.childNodes;
-		for(var i = 0; i < children.length; i++){
-			var pane = children[i];
-			if(pane.nodeType != 1){ continue; }
-			var widget = dijit.byNode(pane);
-			if(widget.selected || !this._selectedPane){
-				this._selectedPane = widget;
-			}
-			pane.style.display = "none";
-			var tab = dojo.doc.createElement("DIV");
-			tab.className = "mblTabButton";
-			if(widget.icon){
-				var imgDiv = dojo.create("DIV");
-				var img = dojo.create("IMG");
-				imgDiv.className = "mblTabButtonImgDiv";
-				img.src = widget.icon;
-				dojox.mobile.setupIcon(img, widget.iconPos);
-				imgDiv.appendChild(img);
-				tab.appendChild(imgDiv);
-			}
-			tab.appendChild(dojo.doc.createTextNode(widget.label));
-			tab.pane = widget;
-			widget.tab = tab;
-			this.connect(tab, "onclick", "onTabClick");
-			cell.appendChild(tab);
-		}
-		div.appendChild(tbl);
-		this.tabHeaderNode.appendChild(div);
-		this.selectTab(this._selectedPane.tab);
-	},
-
-	selectTab: function(/*DomNode*/tab){
-		this._selectedPane.domNode.style.display = "none";
-		dojo.removeClass(this._selectedPane.tab, "mblTabButtonSelected");
-		this._selectedPane = tab.pane;
-		this._selectedPane.domNode.style.display = "";
-		dojo.addClass(tab, "mblTabButtonSelected");
-		if(dojo.isBB){
-			var ref = tab.nextSibling;
-			tab.parentNode.insertBefore(tab.parentNode.removeChild(tab), ref);
-		}
-		var view = dijit.getEnclosingWidget(this.domNode.parentNode);
-		if(this.fixedHeader){
-			// This widget stacks multiple panes and controls their visibility.
-			// Each pane cannot have its own scroll position status, because
-			// the entire widget scrolls.
-			// When in the fixedHeader mode, the user can always select a tab
-			// even when the current pane is scrolled down to the bottom.
-			// Even in such cases, the next page should be shown from the top.
-			if(view && view.scrollTo){
-				view.scrollTo({y:0});
-			}
-		}
-		view.flashScrollBar && view.flashScrollBar();
-	},
-
-	onTabClick: function(e){
-		var tab = e.currentTarget;
-		dojo.addClass(tab, "mblTabButtonHighlighted");
-		setTimeout(function(){
-			dojo.removeClass(tab, "mblTabButtonHighlighted");
-		}, 200);
-		this.selectTab(tab);
-	}
-});
-
-dojo.declare(
-	"dojox.mobile.TabPane",
-	dijit._WidgetBase,
-{
-	label: "",
-	icon: "",
-	iconPos: "",
-	selected: false,
-
-	inheritParams: function(){
-		var parent = this.getParentWidget();
-		if(parent){
-			if(!this.icon){ this.icon = parent.iconBase; }
-			if(!this.iconPos){ this.iconPos = parent.iconPos; }
-		}
-	},
-
-	buildRendering: function(){
-		this.inheritParams();
-		this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("DIV");
-		this.domNode.className = "mblTabPane";
-	},
-
-	getParentWidget: function(){
-		var ref = this.srcNodeRef || this.domNode;
-		return ref && ref.parentNode ? dijit.getEnclosingWidget(ref.parentNode) : null;
-	}
-});
diff --git a/dojox/mobile/TextArea.js b/dojox/mobile/TextArea.js
new file mode 100644
index 0000000..c24d398
--- /dev/null
+++ b/dojox/mobile/TextArea.js
@@ -0,0 +1,39 @@
+define([
+	"dojo/_base/declare",
+	"dojo/dom-construct",
+	"./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>
+
+		baseClass: "mblTextArea",
+
+		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(){
+			if(!this.srcNodeRef){
+				this.srcNodeRef = domConstruct.create("textarea", {});
+			}
+			this.inherited(arguments);
+		}
+	});
+});
diff --git a/dojox/mobile/TextBox.js b/dojox/mobile/TextBox.js
new file mode 100644
index 0000000..0fa1c13
--- /dev/null
+++ b/dojox/mobile/TextBox.js
@@ -0,0 +1,41 @@
+define([
+	"dojo/_base/declare",
+	"dojo/dom-construct",
+	"dijit/_WidgetBase",
+	"dijit/form/_FormValueMixin",
+	"dijit/form/_TextBoxMixin"
+], function(declare, domConstruct, WidgetBase, FormValueMixin, TextBoxMixin){
+
+	/*=====
+		WidgetBase = dijit._WidgetBase;
+		FormValueMixin = dijit.form._FormValueMixin;
+		TextBoxMixin = dijit.form._TextBoxMixin;
+	=====*/
+	return declare("dojox.mobile.TextBox",[WidgetBase, FormValueMixin, TextBoxMixin],{
+		// summary:
+		//		A non-templated base class for textbox form inputs
+
+		baseClass: "mblTextBox",
+
+		// 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: null,
+
+		// Map widget attributes to DOMNode attributes.
+		_setPlaceHolderAttr: "textbox",
+
+		buildRendering: function(){
+			if(!this.srcNodeRef){
+				this.srcNodeRef = domConstruct.create("input", {"type":this.type});
+			}
+			this.inherited(arguments);
+			this.textbox = this.focusNode = this.domNode;
+		},
+
+		postCreate: function(){
+			this.inherited(arguments);
+			this.connect(this.textbox, "onfocus", "_onFocus");
+			this.connect(this.textbox, "onblur", "_onBlur");
+		}
+	});
+});
diff --git a/dojox/mobile/ToggleButton.js b/dojox/mobile/ToggleButton.js
new file mode 100644
index 0000000..f6073ca
--- /dev/null
+++ b/dojox/mobile/ToggleButton.js
@@ -0,0 +1,25 @@
+define([
+	"dojo/_base/declare",
+	"dojo/dom-class",
+	"dijit/form/_ToggleButtonMixin",
+	"./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).
+		//		Can be base class for things like tabs or checkbox or radio buttons
+
+		baseClass: "mblToggleButton",
+
+		_setCheckedAttr: function(){
+			this.inherited(arguments);
+			var newStateClasses = (this.baseClass+' '+this["class"]).replace(/(\S+)\s*/g, "$1Checked ").split(" ");
+			domClass[this.checked ? "add" : "remove"](this.focusNode || this.domNode, newStateClasses);
+		}
+	});
+});
diff --git a/dojox/mobile/ToolBarButton.js b/dojox/mobile/ToolBarButton.js
new file mode 100644
index 0000000..904b88b
--- /dev/null
+++ b/dojox/mobile/ToolBarButton.js
@@ -0,0 +1,107 @@
+define([
+	"dojo/_base/declare",
+	"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;
+=====*/
+
+	// module:
+	//		dojox/mobile/ToolBarButton
+	// summary:
+	//		A button widget that is placed in the Heading widget.
+
+	return declare("dojox.mobile.ToolBarButton", ItemBase, {
+		// summary:
+		//		A button widget that 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.
+
+		// selected: Boolean
+		//		If true, the button is in the selected status.
+		selected: false,
+
+		// btnClass: String
+		//		Deprecated.
+		btnClass: "",
+
+		/* internal properties */	
+		_defaultColor: "mblColorDefault",
+		_selColor: "mblColorDefaultSel",
+
+		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;
+			}
+			domClass.add(this.domNode, color);
+	
+			if(!this.label){
+				this.label = this.domNode.innerHTML;
+			}
+
+			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.connect(this.domNode, "onclick", "onClick");
+		},
+	
+		select: function(){
+			// summary:
+			//		Makes this widget in the selected state.
+			domClass.toggle(this.domNode, this._selColor, !arguments[0]);
+			this.selected = !arguments[0];
+		},
+		
+		deselect: function(){
+			// summary:
+			//		Makes this widget in the deselected state.
+			this.select(true);
+		},
+	
+		onClick: function(e){
+			this.setTransitionPos(e);
+			this.defaultClickAction();
+		},
+	
+		_setBtnClassAttr: function(/*String*/btnClass){
+			var node = this.domNode;
+			if(node.className.match(/(mblDomButton\w+)/)){
+				domClass.remove(node, RegExp.$1);
+			}
+			domClass.add(node, btnClass);
+			if(common.createDomButton(this.domNode)){
+				domClass.add(this.domNode, "mblToolBarButtonDomButton");
+			}
+		},
+
+		_setLabelAttr: function(/*String*/text){
+			this.label = text;
+			this.domNode.innerHTML = this._cv ? this._cv(text) : text;
+		}
+	});
+});
diff --git a/dojox/mobile/Tooltip.js b/dojox/mobile/Tooltip.js
new file mode 100644
index 0000000..ed1a460
--- /dev/null
+++ b/dojox/mobile/Tooltip.js
@@ -0,0 +1,99 @@
+define([
+	"dojo/_base/array", // array.forEach
+	"dijit/registry",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-geometry",
+	"dojo/dom-style",
+	"dijit/place",
+	"dijit/_WidgetBase"
+], function(array, registry, declare, lang, domClass, domConstruct, domGeometry, domStyle, place, WidgetBase){
+
+	/*=====
+		WidgetBase = dijit._WidgetBase;
+	=====*/
+	return declare("dojox.mobile.Tooltip", WidgetBase, {
+		// summary:
+		//		A non-templated popup bubble widget
+		//
+
+		baseClass: "mblTooltip mblTooltipHidden",
+
+		buildRendering: function(){
+			// create the helper nodes here in case the user overwrote domNode.innerHTML
+			this.inherited(arguments);
+			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);
+		},
+
+		show: function(/*DomNode*/ aroundNode, 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
+			var domNode = this.domNode;
+			var connectorClasses = {
+				"MRM": "mblTooltipAfter",
+				"MLM": "mblTooltipBefore",
+				"BMT": "mblTooltipBelow",
+				"TMB": "mblTooltipAbove",
+				"BLT": "mblTooltipBelow",
+				"TLB": "mblTooltipAbove",
+				"BRT": "mblTooltipBelow",
+				"TRB": "mblTooltipAbove",
+				"TLT": "mblTooltipBefore",
+				"TRT": "mblTooltipAfter",
+				"BRB": "mblTooltipAfter",
+				"BLB": "mblTooltipBefore"
+			};
+			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;
+					}
+					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)] || '';
+			domClass.add(domNode, connectorClass);
+			var pos = domGeometry.position(aroundNode, true);
+			domStyle.set(this.anchor, (connectorClass == "mblTooltipAbove" || connectorClass == "mblTooltipBelow")
+				? { top: "", left: Math.max(0, pos.x - best.x + (pos.w >> 1) - (this.arrow.offsetWidth >> 1)) + "px" }
+				: { left: "", top: Math.max(0, pos.y - best.y + (pos.h >> 1) - (this.arrow.offsetHeight >> 1)) + "px" }
+			);
+			domClass.replace(domNode, "mblTooltipVisible", "mblTooltipHidden");
+			this.resize = lang.hitch(this, "show", aroundNode, positions); // orientation changes
+			return best;
+		},
+
+		hide: function(){
+			// summary:
+			//		Pop down the tooltip
+			this.resize = undefined;
+			domClass.replace(this.domNode, "mblTooltipHidden", "mblTooltipVisible");
+		},
+
+		onBlur: function(/*Event*/e){
+			return true; // touching outside the overlay area does call hide() by default
+		},
+
+		destroy: function(){
+			if(this.anchor){
+				this.anchor.removeChild(this.innerArrow);
+				this.anchor.removeChild(this.arrow);
+				this.domNode.removeChild(this.anchor);
+				this.anchor = this.arrow = this.innerArrow = undefined;
+			}
+			this.inherited(arguments);
+		}
+	});
+});
diff --git a/dojox/mobile/TransitionEvent.js b/dojox/mobile/TransitionEvent.js
new file mode 100644
index 0000000..c21ed26
--- /dev/null
+++ b/dojox/mobile/TransitionEvent.js
@@ -0,0 +1,35 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/Deferred",
+	"dojo/_base/lang",
+	"dojo/on",
+	"./transition"
+], function(declare, Deferred, lang, on, transitDeferred){
+
+	return declare("dojox.mobile.TransitionEvent", null, {
+		constructor: function(target, transitionOptions, triggerEvent){
+			this.transitionOptions=transitionOptions;	
+			this.target = target;
+			this.triggerEvent=triggerEvent||null;	
+		},
+
+		dispatch: function(){
+			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/View.js b/dojox/mobile/View.js
new file mode 100644
index 0000000..65b2e60
--- /dev/null
+++ b/dojox/mobile/View.js
@@ -0,0 +1,512 @@
+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/_base/window",
+	"dojo/_base/Deferred",
+	"dojo/dom",
+	"dojo/dom-class",
+	"dojo/dom-geometry",
+	"dojo/dom-style",
+//	"dojo/hash", // optionally prereq'ed
+	"dijit/registry",	// registry.byNode
+	"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;
+=====*/
+
+	// module:
+	//		dojox/mobile/View
+	// summary:
+	//		A widget that represents a view that occupies the full screen
+
+	var dm = lang.getObject("dojox.mobile", true);
+
+	return declare("dojox.mobile.View", [WidgetBase, Container, Contained], {
+		// 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.
+	
+		// selected: Boolean
+		//		If true, the view is displayed at startup time.
+		selected: false,
+
+		// keepScrollPos: Boolean
+		//		If true, the scroll position is kept between views.
+		keepScrollPos: true,
+	
+		constructor: function(params, node){
+			if(node){
+				dom.byId(node).style.visibility = "hidden";
+			}
+			this._aw = has('android') >= 2.2 && has('android') < 3; // flag for android animation workaround
+		},
+	
+		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(!config['mblCSS3Transition']){
+			    this.connect(this.domNode, "webkitTransitionEnd", "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;
+			}
+		},
+
+		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;
+				}
+			}
+			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;
+			}
+			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
+			this.inherited(arguments);
+		},
+	
+		resize: function(){
+			// summary:
+			//		Calls resize() of each child widget.
+			array.forEach(this.getChildren(), function(child){
+				if(child.resize){ child.resize(); }
+			});
+		},
+
+		onStartView: function(){
+			// summary:
+			//		Stub function to connect to from your application.
+			// 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]);
+				}
+			}
+		},
+		
+		_fixViewState: function(/*DomNode*/toNode){
+			// summary:
+			//		Sanity check for view transition states.
+			// description:
+			//		Sometimes uninitialization of Views fails after making view transition,
+			//		and that results in failure of subsequent view transitions.
+			//		This function does the uninitialization for all the sibling views.
+			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")){
+					n.className = "mblView"; //TODO: Should remove classes one by one. This would clear user defined classes or even mblScrollableView.
+				}
+			}
+			toNode.className = "mblView"; // just in case toNode is a sibling of an ancestor.
+		},
+	
+		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;
+		},
+	
+		performTransition: function(/*String*/moveTo, /*Number*/dir, /*String*/transition,
+									/*Object|null*/context, /*String|Function*/method /*optional args*/){
+			// 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
+			//		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.
+			//		If null, transitions to a blank view.
+			//		If '#', returns immediately without transition.
+			// dir: 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.
+			// 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.
+			// 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 function reference, or name of a function in context.
+			// tags:
+			//		public
+			//
+			// example:
+			//		Transition backward to a view whose id is "foo" with the slide animation.
+			//	|	performTransition("foo", -1, "slide");
+			//
+			// 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;
+				}
+			}
+			this._saveState.apply(this, arguments);
+			var toNode;
+			if(moveTo){
+				toNode = this.convertToId(moveTo);
+			}else{
+				if(!this._dummyNode){
+					this._dummyNode = win.doc.createElement("DIV");
+					win.body().appendChild(this._dummyNode);
+				}
+				toNode = this._dummyNode;
+			}
+			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";
+			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);
+					toWidget._resized = true;
+				}
+	
+				if(transition && transition != "none"){
+					// Temporarily add padding to align with the fromNode while transition
+					toWidget.containerNode.style.paddingTop = fromTop + "px";
+				}
+
+				toWidget.movedFrom = fromNode.id;
+			}
+	
+			this.onBeforeTransitionOut.apply(this, arguments);
+			connect.publish("/dojox/mobile/beforeTransitionOut", [this].concat(lang._toArray(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);
+					toNode.style.top = "0px";
+					if(scrollTop > 1 || toTop !== 0){
+						fromNode.style.top = toTop - scrollTop + "px";
+						if(config["mblHideAddressBar"] !== false){
+							setTimeout(function(){ // iPhone needs setTimeout
+								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);
+			}
+		},
+		_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 = "";
+			}
+			if(!transition || transition == "none"){
+				this.domNode.style.display = "none";
+				this.invokeCallback();
+			}else if(config['mblCSS3Transition']){
+				//get dojox/css3/transit first
+				Deferred.when(transitDeferred, lang.hitch(this, function(transit){
+					//follow the style of .mblView.mblIn in View.css
+					//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(){
+						domStyle.set(toNode, "position", toPosition);
+						this.invokeCallback();
+					}));
+				}));
+			}else{
+				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);
+				// set transform origin
+				var fromOrigin = "50% 50%";
+				var toOrigin = "50% 50%";
+				var scrollTop, posX, posY;
+				if(transition.indexOf("swirl") != -1 || transition.indexOf("zoom") != -1){
+					if(this.keepScrollPos && !this.getParent()){
+						scrollTop = win.body().scrollTop || win.doc.documentElement.scrollTop || win.global.pageYOffset || 0;
+					}else{
+						scrollTop = -domGeometry.position(fromNode, true).y;
+					}
+					posY = win.global.innerHeight / 2 + scrollTop;
+					fromOrigin = "50% " + posY + "px";
+					toOrigin = "50% " + posY + "px";
+				}else if(transition.indexOf("scale") != -1){
+					var viewPos = domGeometry.position(fromNode, true);
+					posX = ((this.clickedPosX !== undefined) ? this.clickedPosX : win.global.innerWidth / 2) - viewPos.x;
+					if(this.keepScrollPos && !this.getParent()){
+						scrollTop = win.body().scrollTop || win.doc.documentElement.scrollTop || win.global.pageYOffset || 0;
+					}else{
+						scrollTop = -viewPos.y;
+					}
+					posY = ((this.clickedPosY !== undefined) ? this.clickedPosY : win.global.innerHeight / 2) + scrollTop;
+					fromOrigin = posX + "px " + posY + "px";
+					toOrigin = posX + "px " + posY + "px";
+				}
+				domStyle.set(fromNode, {webkitTransformOrigin:fromOrigin});
+				domStyle.set(toNode, {webkitTransformOrigin:toOrigin});
+			}
+			dm.currentView = registry.byNode(toNode);
+		},
+	
+		onAnimationStart: function(e){
+		},
+
+
+		onAnimationEnd: function(e){
+			var name = e.animationName || e.target.className;
+			if(name.indexOf("Out") === -1 &&
+				name.indexOf("In") === -1 &&
+				name.indexOf("Shrink") === -1){ return; }
+			var isOut = false;
+			if(domClass.contains(this.domNode, "mblOut")){
+				isOut = true;
+				this.domNode.style.display = "none";
+				domClass.remove(this.domNode, [this._toCls(this._transition), "mblIn", "mblOut", "mblReverse"]);
+			}else{
+				// Reset the temporary padding
+				this.containerNode.style.paddingTop = "";
+			}
+			domStyle.set(this.domNode, {webkitTransformOrigin:""});
+			if(name.indexOf("Shrink") !== -1){
+				var li = e.target;
+				li.style.display = "none";
+				domClass.remove(li, "mblCloseContent");
+			}
+			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");
+
+			// clear the clicked position
+			this.clickedPosX = this.clickedPosY = undefined;
+		},
+
+		invokeCallback: function(){
+			this.onAfterTransitionOut.apply(this, this._arguments);
+			connect.publish("/dojox/mobile/afterTransitionOut", [this].concat(this._arguments));
+			var toWidget = registry.byNode(this.toNode);
+			if(toWidget){
+				toWidget.onAfterTransitionIn.apply(toWidget, this._arguments);
+				connect.publish("/dojox/mobile/afterTransitionIn", [toWidget].concat(this._arguments));
+				toWidget.movedFrom = undefined;
+			}
+
+			var c = this._context, m = this._method;
+			if(!c && !m){ return; }
+			if(!m){
+				m = c;
+				c = null;
+			}
+			c = c || win.global;
+			if(typeof(m) == "string"){
+				c[m].apply(c, this._args);
+			}else{
+				m.apply(c, this._args);
+			}
+		},
+	
+		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.
+			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"){
+					return registry.byNode(n);
+				}
+			}
+			return null;
+		},
+	
+		show: function(){
+			// summary:
+			//		Shows this view without a transition animation.
+			var view = this.getShowingView();
+			if(view){
+				view.domNode.style.display = "none"; // from-style
+			}
+			this.domNode.style.display = ""; // to-style
+			dm.currentView = this;
+		}
+	});
+});
diff --git a/dojox/mobile/ViewController.js b/dojox/mobile/ViewController.js
new file mode 100644
index 0000000..8266cfe
--- /dev/null
+++ b/dojox/mobile/ViewController.js
@@ -0,0 +1,263 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/dom",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+//	"dojo/hash", // optionally prereq'ed
+	"dojo/on",
+	"dojo/ready",
+	"dijit/registry",	// registry.byId
+	"./ProgressIndicator",
+	"./TransitionEvent"
+], function(dojo, array, connect, declare, lang, win, dom, domClass, domConstruct, on, ready, registry, ProgressIndicator, TransitionEvent){
+
+	// 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.
+		// 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.
+
+		constructor: function(){
+			this.viewMap={};
+			this.currentView=null;
+			this.defaultView=null;
+			ready(lang.hitch(this, function(){
+				on(win.body(), "startTransition", lang.hitch(this, "onStartTransition"));
+			}));
+		},
+
+		findCurrentView: function(moveTo,src){
+			// 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; }
+			}
+			return w;
+		},
+
+		onStartTransition: function(evt){
+			// summary:
+			//		A handler that performs view transition.
+
+			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];
+				}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;
+				}
+				moveTo = id;
+				w = this.findCurrentView(moveTo,registry.byId(evt.target.id)) || w; // the current view widget
+			}
+			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];
+				if(c.nodeType === 1){
+					if(c.getAttribute("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 + ")");
+							}
+						}
+					}
+					widget = new cls(params, node);
+					if(node){ // to call View's startup()
+						widget._visible = true;
+						this._ws.push(widget);
+					}
+					if(parent && parent.addChild){
+						parent.addChild(widget);
+					}
+					this._instantiate(objs[i], null, widget);
+				}
+			}
+			return widget && widget.domNode;
+		}
+	});
+	new Controller(); // singleton
+	return Controller;
+});
+
diff --git a/dojox/mobile/_ComboBoxMenu.js b/dojox/mobile/_ComboBoxMenu.js
new file mode 100644
index 0000000..eaf7f69
--- /dev/null
+++ b/dojox/mobile/_ComboBoxMenu.js
@@ -0,0 +1,81 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dijit/form/_ComboBoxMenuMixin",
+	"dijit/_WidgetBase",
+	"dojox/mobile/_ListTouchMixin",
+	"./scrollable"
+],
+	function(dojo, declare, domClass, domConstruct, ComboBoxMenuMixin, WidgetBase, ListTouchMixin, Scrollable){
+
+	/*=====
+		ComboBoxMenuMixin = dijit.form._ComboBoxMenuMixin;
+		WidgetBase = dijit._WidgetBase;
+		ListTouchMixin = dojox.mobile._ListTouchMixin;
+	=====*/
+	return declare("dojox.mobile._ComboBoxMenu", [WidgetBase, ListTouchMixin, 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
+		// tags:
+		//		private
+
+		baseClass: "mblComboBoxMenu",
+		bgIframe: true, // so it's not created for IE and FF
+
+		buildRendering: function(){
+			this.domNode = this.focusNode = domConstruct.create("div", { "class":"mblReset" });
+			this.containerNode = domConstruct.create("div", { style: { position:"absolute", top:0, left:0 } }, this.domNode); // needed for scrollable
+			this.previousButton = domConstruct.create("div", { "class":"mblReset mblComboBoxMenuItem mblComboBoxMenuPreviousButton", role:"option" }, this.containerNode);
+			this.nextButton = domConstruct.create("div", { "class":"mblReset mblComboBoxMenuItem mblComboBoxMenuNextButton", role:"option" }, this.containerNode);
+			this.inherited(arguments);
+		},
+
+		_createMenuItem: function(){
+			return domConstruct.create("div", {
+				"class": "mblReset mblComboBoxMenuItem" +(this.isLeftToRight() ? "" : " mblComboBoxMenuItemRtl"),
+				role: "option"
+			});
+		},
+
+		onSelect: function(/*DomNode*/ node){
+			// summary:
+			//		Add selected CSS
+			domClass.add(node, "mblComboBoxMenuItemSelected");
+		},
+
+		onDeselect: function(/*DomNode*/ node){
+			// summary:
+			//		Remove selected CSS
+			domClass.remove(node, "mblComboBoxMenuItemSelected");
+		},
+
+		onOpen: function(){
+			this.scrollable.init({
+				domNode: this.domNode,
+				containerNode: this.containerNode
+			});
+			this.scrollable.scrollTo({x:0, y:0});
+		},
+
+		onClose: function(){
+			this.scrollable.cleanup();
+		},
+
+		destroyRendering: function(){
+			this.bgIframe = false; // no iframe to destroy
+			this.inherited(arguments);
+		},
+
+		postCreate: function(){
+			this.inherited(arguments);
+			this.scrollable = new Scrollable(dojo, dojox);
+			this.scrollable.resize = function(){}; // resize changes the height rudely
+			this.scrollable.androidWorkaroud = false; // disable Android workaround
+		}
+	});
+});
diff --git a/dojox/mobile/_DataListMixin.js b/dojox/mobile/_DataListMixin.js
new file mode 100644
index 0000000..4b3fb52
--- /dev/null
+++ b/dojox/mobile/_DataListMixin.js
@@ -0,0 +1,133 @@
+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){
+
+	// 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,{
+		// 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.
+
+		// store: Object
+		//		Reference to data provider object
+		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,
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			if(!this.store){ return; }
+			var store = this.store;
+			this.store = null;
+			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.
+			var attr = {};
+			var arr = this.store.getLabelAttributes(item);
+			var labelAttr = arr ? arr[0] : null;
+			array.forEach(this.store.getAttributes(item), function(name){
+				if(name === labelAttr){
+					attr["label"] = this.store.getLabel(item);
+				}else{
+					attr[name] = this.store.getValue(item, name);
+				}
+			}, this);
+			var w = new ListItem(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();
+			});
+			array.forEach(items, function(item, index){
+				this.addChild(this.createListItem(item));
+			}, this);
+		},
+
+		onComplete: function(/*Array*/items, /*Object*/request){
+			// summary:
+			//		An handler that is called after the fetch completes.
+			this.generateList(items, request);
+		},
+
+		onError: function(/*Object*/errorData, /*Object*/request){
+			// summary:
+			//		An error handler.
+		},
+
+		onSet: function(/*Object*/item, /*String*/attribute, /*Object|Array*/oldValue, /*Object|Array*/newValue){
+			//	summary:
+			//		See dojo.data.api.Notification.onSet()
+		},
+
+		onNew: function(/*Object*/newItem, /*Object?*/parentInfo){
+			//	summary:
+			//		See dojo.data.api.Notification.onNew()
+			this.addChild(this.createListItem(newItem));
+		},
+
+		onDelete: function(/*Object*/deletedItem){
+			//	summary:
+			//		See dojo.data.api.Notification.onDelete()
+			registry.byId(deletedItem._widgetId).destroyRecursive();
+		}
+	});
+});
diff --git a/dojox/mobile/_ItemBase.js b/dojox/mobile/_ItemBase.js
new file mode 100644
index 0000000..2427010
--- /dev/null
+++ b/dojox/mobile/_ItemBase.js
@@ -0,0 +1,248 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/config",
+	"dojo/_base/declare",
+	"dijit/registry",	// registry.getEnclosingWidget
+	"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;
+=====*/
+
+	// module:
+	//		dojox/mobile/_ItemBase
+	// summary:
+	//		A base class for item classes (e.g. ListItem, IconItem, etc.)
+
+	return declare("dojox.mobile._ItemBase", [WidgetBase, Container, Contained],{
+		// summary:
+		//		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.
+
+		// icon: String
+		//		An icon image to display. The value can be either a path for an
+		//		image file or a class name of a DOM button. If icon is not
+		//		specified, the iconBase parameter of the parent widget is used.
+		icon: "",
+
+		// iconPos: String
+		//		The position of an aggregated icon. IconPos is comma separated
+		//		values like top,left,width,height (ex. "0,0,29,29"). If iconPos
+		//		is not specified, the iconPos parameter of the parent widget is
+		//		used.
+		iconPos: "", // top,left,width,height (ex. "0,0,29,29")
+
+		// alt: String
+		//		An alt text for the icon image.
+		alt: "",
+
+		// href: String
+		//		A URL of another web page to go to.
+		href: "",
+
+		// hrefTarget: String
+		//		A target that specifies where to open a page specified by
+		//		href. The value will be passed to the 2nd argument of
+		//		window.open().
+		hrefTarget: "",
+
+		// 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 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.
+		//
+		//		If null, transitions to a blank view.
+		//		If '#', returns immediately without transition.
+		moveTo: "",
+
+		// scene: String
+		//		The name of a scene. Used from dojox.mobile.app.
+		scene: "",
+
+		// clickable: Boolean
+		//		If true, this item becomes clickable even if a transition
+		//		destination (moveTo, etc.) is not specified.
+		clickable: false,
+
+		// url: String
+		//		A URL of an html fragment page or JSON data that represents a
+		//		new view content. The view content is loaded with XHR and
+		//		inserted in the current page. Then a view transition occurs to
+		//		the newly created view. The view is cached so that subsequent
+		//		requests would not load the content again.
+		url: "",
+
+		// urlTarget: String
+		//		Node id under which a new view will be created according to the
+		//		url parameter. If not specified, The new view will be created as
+		//		a sibling of the current view.
+		urlTarget: "",
+
+		// 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.
+		transition: "",
+
+		// 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.
+		transitionDir: 1,
+
+		// transitionOptions: Object
+		//		A hash object that holds transition options.
+		transitionOptions: null,
+
+		// callback: Function|String
+		//		A callback function that is called when the transition has been
+		//		finished. A function reference, or name of a function in
+		//		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.
+		label: "",
+
+		// toggle: Boolean
+		//		If true, the item acts like a toggle button.
+		toggle: false,
+
+		// _duration: Number
+		//		Duration of selection, milliseconds.
+		_duration: 800,
+
+	
+		inheritParams: function(){
+			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;
+				}
+				if(!this.icon){ this.icon = parent.iconBase; }
+				if(!this.iconPos){ this.iconPos = parent.iconPos; }
+			}
+		},
+	
+		select: function(){
+			// summary:
+			//		Makes this widget in the selected state.
+			// description:
+			//		Subclass must implement.
+		},
+	
+		deselect: function(){
+			// summary:
+			//		Makes this widget in the deselected state.
+			// description:
+			//		Subclass must implement.
+		},
+	
+		defaultClickAction: function(e){
+			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._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();
+				}
+			}
+		},
+	
+		getParent: 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;
+		},
+
+		setTransitionPos: function(e){
+			// summary:
+			//		Stores the clicked position for later use.
+			// description:
+			//		Some of the transition animations (e.g. ScaleIn) needs the
+			//		clicked position.
+			var w = this;
+			while(true){
+				w = w.getParent();
+				if(!w || w instanceof View){ break; }
+			}
+			if(w){
+				w.clickedPosX = e.clientX;
+				w.clickedPosY = e.clientY;
+			}
+		},
+
+		transitionTo: function(moveTo, href, url, 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;
+				}
+			}
+			new TransitionEvent(this.domNode, {moveTo: moveTo, href: href, url: url, scene: scene,
+						transition: this.transition, transitionDir: this.transitionDir}).dispatch();
+		}
+	});
+});
diff --git a/dojox/mobile/_ListTouchMixin.js b/dojox/mobile/_ListTouchMixin.js
new file mode 100644
index 0000000..265f44c
--- /dev/null
+++ b/dojox/mobile/_ListTouchMixin.js
@@ -0,0 +1,32 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/event",
+	"dijit/form/_ListBase"
+], function(declare, event, 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
+	
+		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);
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/_ScrollableMixin.js b/dojox/mobile/_ScrollableMixin.js
index be9b992..f402616 100644
--- a/dojox/mobile/_ScrollableMixin.js
+++ b/dojox/mobile/_ScrollableMixin.js
@@ -1,51 +1,123 @@
-dojo.provide("dojox.mobile._ScrollableMixin");
-
-dojo.require("dijit._WidgetBase");
-dojo.require("dojox.mobile.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.
-
-dojo.declare(
-	"dojox.mobile._ScrollableMixin",
-	null,
-{
-	fixedHeader: "",
-	fixedFooter: "",
-
-	destroy: function(){
-		this.cleanup();
-		this.inherited(arguments);
-	},
-
-	startup: function(){
-		var params = {};
-		if(this.fixedHeader){
-			params.fixedHeaderHeight = dojo.byId(this.fixedHeader).offsetHeight;
-		}
-		if(this.fixedFooter){
-			var node = dojo.byId(this.fixedFooter);
-			if(node.parentNode == this.domNode){ // local footer
-				this.isLocalFooter = true;
-				node.style.bottom = "0px";
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/dom",
+	"dojo/dom-class",
+	"dijit/registry",	// registry.byNode
+	"./scrollable"
+], function(dojo, 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, {
+		// 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: "",
+
+		// fixedFooter: String
+		//		Id of the fixed footer.
+		fixedFooter: "",
+
+		// scrollableParams: Object
+		//		Parameters for dojox.mobile.scrollable.init().
+		scrollableParams: null,
+
+		// allowNestedScrolls: Boolean
+		//		e.g. Allow ScrollableView in a SwapView.
+		allowNestedScrolls: true,
+
+		constructor: function(){
+			this.scrollableParams = {};
+		},
+
+		destroy: function(){
+			this.cleanup();
+			this.inherited(arguments);
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+			var node;
+			var 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);
+			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;
+					}
+				}
+			}
+			this.inherited(arguments);
+		},
+
+		findAppBars: function(){
+			// summary:
+			//		Search for application-specific header or footer.
+			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("fixed")
+					|| (registry.byNode(node) && registry.byNode(node).fixed);
+				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");
+					this.fixedFooter = node;
+					return fixed;
+				}
 			}
-			params.fixedFooterHeight = node.offsetHeight;
+			return null;
 		}
-		this.init(params);
-		this.inherited(arguments);
-	}
+	});
+	lang.extend(cls, new Scrollable(dojo, dojox));
+	return cls;
 });
-(function(){
-	var obj = new dojox.mobile.scrollable();
-	dojo.extend(dojox.mobile._ScrollableMixin, obj);
-	if(dojo.version.major == 1 && dojo.version.minor == 4){
-		// dojo-1.4 had a problem in inheritance behavior. (#10709 and #10788)
-		// This is a workaround to avoid the problem.
-		// There is no such a problem in dojo-1.3 and dojo-1.5.
-		dojo.mixin(dojox.mobile._ScrollableMixin._meta.hidden, obj);
-	}
-})();
diff --git a/dojox/mobile/_base.js b/dojox/mobile/_base.js
index 5cd4a6b..317050a 100644
--- a/dojox/mobile/_base.js
+++ b/dojox/mobile/_base.js
@@ -1,1212 +1,21 @@
-dojo.provide("dojox.mobile._base");
-
-dojo.require("dijit._WidgetBase");
-dojo.isBB = (navigator.userAgent.indexOf("BlackBerry") != -1) && !dojo.isWebKit;
-
-// summary:
-//		Mobile Widgets
-// description:
-//		This module provides a number of widgets that can be used to build
-//		web-based applications for mobile devices such as iPhone or Android.
-//		These widgets work best with webkit-based browsers, such as Safari or
-//		Chrome, since webkit-specific CSS3 features are used.
-//		However, the widgets should work in a "graceful degradation" manner
-//		even on non-CSS3 browsers, such as IE or Firefox. In that case,
-//		fancy effects, such as animation, gradient color, or round corner
-//		rectangle, may not work, but you can still operate your application.
-//
-//		Furthermore, as a separate file, a compatibility module,
-//		dojox.mobile.compat, is available that simulates some of CSS3 features
-//		used in this module. If you use the compatibility module, fancy visual
-//		effects work better even on non-CSS3 browsers.
-//
-//		Note that use of dijit._Container, dijit._Contained, dijit._Templated,
-//		and dojo.query is intentionally avoided to reduce download code size.
-
-dojo.declare(
-	"dojox.mobile.View",
-	dijit._WidgetBase,
-{
+define([
+	"./common",
+	"./View",
+	"./Heading",
+	"./RoundRect",
+	"./RoundRectCategory",
+	"./EdgeToEdgeCategory",
+	"./RoundRectList",
+	"./EdgeToEdgeList",
+	"./ListItem",
+	"./Switch",
+	"./ToolBarButton",
+	"./ProgressIndicator"
+], function(common, View, Heading, RoundRect, RoundRectCategory, EdgeToEdgeCategory, RoundRectList, EdgeToEdgeList, ListItem, Switch, ToolBarButton, ProgressIndicator){
+	// module:
+	//		dojox/mobile/_base
 	// 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.
-
-	// selected: Boolean
-	//		If true, the view is displayed at startup time.
-	selected: false,
-
-	// keepScrollPos: Boolean
-	//		If true, the scroll position is kept between views.
-	keepScrollPos: true,
-
-	_started: false,
-
-	constructor: function(params, node){
-		if(node){
-			dojo.byId(node).style.visibility = "hidden";
-		}
-	},
-
-	buildRendering: function(){
-		this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("DIV");
-		this.domNode.className = "mblView";
-		this.connect(this.domNode, "webkitAnimationEnd", "onAnimationEnd");
-		this.connect(this.domNode, "webkitAnimationStart", "onAnimationStart");
-		var id = location.href.match(/#(\w+)([^\w=]|$)/) ? RegExp.$1 : null;
-
-		this._visible = this.selected && !id || this.id == id;
-
-		if(this.selected){
-			dojox.mobile._defaultView = this;
-		}
-	},
-
-	startup: function(){
-		if(this._started){ return; }
-		var _this = this;
-		setTimeout(function(){
-			if(!_this._visible){
-				_this.domNode.style.display = "none";
-			}else{
-				dojox.mobile.currentView = _this;
-				_this.onStartView();
-			}
-			_this.domNode.style.visibility = "visible";
-		}, dojo.isIE?100:0); // give IE a little time to complete drawing
-		this._started = true;
-	},
-
-	onStartView: function(){
-		// Stub function to connect to from your application.
-		// Called only when this view is shown at startup time.
-	},
-
-	onBeforeTransitionIn: function(moveTo, dir, transition, context, method){
-		// Stub function to connect to from your application.
-	},
-
-	onAfterTransitionIn: function(moveTo, dir, transition, context, method){
-		// Stub function to connect to from your application.
-	},
-
-	onBeforeTransitionOut: function(moveTo, dir, transition, context, method){
-		// Stub function to connect to from your application.
-	},
+	//		Includes the basic dojox.mobile modules
 
-	onAfterTransitionOut: function(moveTo, dir, transition, context, method){
-		// Stub function to connect to from your application.
-	},
-
-	_saveState: function(moveTo, dir, transition, context, method){
-		this._context = context;
-		this._method = method;
-		if(transition == "none" || !dojo.isWebKit){
-			transition = null;
-		}
-		this._moveTo = moveTo;
-		this._dir = dir;
-		this._transition = transition;
-		this._arguments = [];
-		var i;
-		for(i = 0; i < arguments.length; i++){
-			this._arguments.push(arguments[i]);
-		}
-		this._args = [];
-		if(context || method){
-			for(i = 5; i < arguments.length; i++){
-				this._args.push(arguments[i]);
-			}
-		}
-	},
-
-	performTransition: function(/*String*/moveTo, /*Number*/dir, /*String*/transition,
-								/*Object|null*/context, /*String|Function*/method /*optional args*/){
-		// summary:
-		//		Function to perform the various types of view transitions, such as fade, slide, and flip.
-		// moveTo: String
-		//		The destination view id to transition the current view to.
-		//		If null, transitions to a blank view.
-		// dir: 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.
-		// transision: String
-		//		The type of transition to perform. "slide", "fade", or "flip"
-		// 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 function reference, or name of a function in context.
-		// tags:
-		//		public
-		// example:
-		//		Transitions to the blank view, and then opens another page.
-		//	|	performTransition(null, 1, "slide", null, function(){location.href = href;});
-		if(dojo.hash){
-			if(typeof(moveTo) == "string" && moveTo.charAt(0) == '#' && !dojox.mobile._params){
-				dojox.mobile._params = [];
-				for(var i = 0; i < arguments.length; i++){
-					dojox.mobile._params.push(arguments[i]);
-				}
-				dojo.hash(moveTo);
-				return;
-			}
-		}
-		this._saveState.apply(this, arguments);
-		var toNode;
-		if(moveTo){
-			if(typeof(moveTo) == "string"){
-				// removes a leading hash mark (#) and params if exists
-				// ex. "#bar&myParam=0003" -> "bar"
-				moveTo.match(/^#?([^&]+)/);
-				toNode = RegExp.$1;
-			}else{
-				toNode = moveTo;
-			}
-		}else{
-			if(!this._dummyNode){
-				this._dummyNode = dojo.doc.createElement("DIV");
-				dojo.body().appendChild(this._dummyNode);
-			}
-			toNode = this._dummyNode;
-		}
-		var fromNode = this.domNode;
-		toNode = this.toNode = dojo.byId(toNode);
-		if(!toNode){ alert("dojox.mobile.View#performTransition: destination view not found: "+toNode); }
-		toNode.style.visibility = "hidden";
-		toNode.style.display = "";
-		this.onBeforeTransitionOut.apply(this, arguments);
-		var toWidget = dijit.byNode(toNode);
-		if(toWidget){
-			// perform view transition keeping the scroll position
-			if(this.keepScrollPos && !dijit.getEnclosingWidget(this.domNode.parentNode)){
-				var scrollTop = dojo.body().scrollTop || dojo.doc.documentElement.scrollTop || dojo.global.pageYOffset || 0;
-				if(dir == 1){
-					toNode.style.top = "0px";
-					if(scrollTop > 1){
-						fromNode.style.top = -scrollTop + "px";
-						if(dojo.config["mblHideAddressBar"] !== false){
-							setTimeout(function(){ // iPhone needs setTimeout
-								dojo.global.scrollTo(0, 1);
-							}, 0);
-						}
-					}
-				}else{
-					if(scrollTop > 1 || toNode.offsetTop !== 0){
-						var toTop = -toNode.offsetTop;
-						toNode.style.top = "0px";
-						fromNode.style.top = toTop - scrollTop + "px";
-						if(dojo.config["mblHideAddressBar"] !== false && toTop > 0){
-							setTimeout(function(){ // iPhone needs setTimeout
-								dojo.global.scrollTo(0, toTop + 1);
-							}, 0);
-						}
-					}
-				}
-			}else{
-				toNode.style.top = "0px";
-			}
-			toWidget.onBeforeTransitionIn.apply(toWidget, arguments);
-		}
-		toNode.style.display = "none";
-		toNode.style.visibility = "visible";
-		this._doTransition(fromNode, toNode, transition, dir);
-	},
-
-	_doTransition: function(fromNode, toNode, transition, dir){
-		var rev = (dir == -1) ? " reverse" : "";
-		toNode.style.display = "";
-		if(!transition || transition == "none"){
-			this.domNode.style.display = "none";
-			this.invokeCallback();
-		}else{
-			dojo.addClass(fromNode, transition + " out" + rev);
-			dojo.addClass(toNode, transition + " in" + rev);
-		}
-	},
-
-	onAnimationStart: function(e){
-	},
-
-	onAnimationEnd: function(e){
-		var isOut = false;
-		if(dojo.hasClass(this.domNode, "out")){
-			isOut = true;
-			this.domNode.style.display = "none";
-			dojo.forEach([this._transition,"in","out","reverse"], function(s){
-				dojo.removeClass(this.domNode, s);
-			}, this);
-		}
-		if(e.animationName.indexOf("shrink") === 0){
-			var li = e.target;
-			li.style.display = "none";
-			dojo.removeClass(li, "mblCloseContent");
-		}
-		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");
-	},
-
-	invokeCallback: function(){
-		this.onAfterTransitionOut.apply(this, this._arguments);
-		var toWidget = dijit.byNode(this.toNode);
-		if(toWidget){
-			toWidget.onAfterTransitionIn.apply(toWidget, this._arguments);
-		}
-
-		dojox.mobile.currentView = toWidget;
-
-		var c = this._context, m = this._method;
-		if(!c && !m){ return; }
-		if(!m){
-			m = c;
-			c = null;
-		}
-		c = c || dojo.global;
-		if(typeof(m) == "string"){
-			c[m].apply(c, this._args);
-		}else{
-			m.apply(c, this._args);
-		}
-	},
-
-	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.
-		var nodes = this.domNode.parentNode.childNodes;
-		for(var i = 0; i < nodes.length; i++){
-			if(dojo.hasClass(nodes[i], "mblView") && dojo.style(nodes[i], "display") != "none"){
-				return dijit.byNode(nodes[i]);
-			}
-		}
-	},
-
-	show: function(){
-		// summary:
-		//		Shows this view without a transition animation.
-		var fs = this.getShowingView().domNode.style; // from-style
-		var ts = this.domNode.style; // to-style
-		fs.display = "none";
-		ts.display = "";
-		dojox.mobile.currentView = this;
-	},
-
-	addChild: function(widget){
-		this.containerNode.appendChild(widget.domNode);
-	}
+	return common;
 });
-
-dojo.declare(
-	"dojox.mobile.Heading",
-	dijit._WidgetBase,
-{
-	back: "",
-	href: "",
-	moveTo: "",
-	transition: "slide",
-	label: "",
-	iconBase: "",
-
-	buildRendering: function(){
-		this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("H1");
-		this.domNode.className = "mblHeading";
-		this._view = dijit.getEnclosingWidget(this.domNode.parentNode); // parentNode is null if created programmatically
-		if(this.label){
-			this.domNode.appendChild(document.createTextNode(this.label));
-		}else{
-			this.label = "";
-			dojo.forEach(this.domNode.childNodes, function(n){
-				if(n.nodeType == 3){ this.label += n.nodeValue; }
-			}, this);
-			this.label = dojo.trim(this.label);
-		}
-		if(this.back){
-			var btn = dojo.create("DIV", {className:"mblArrowButton"}, this.domNode, "first");
-			var head = dojo.create("DIV", {className:"mblArrowButtonHead"}, btn);
-			var body = dojo.create("DIV", {className:"mblArrowButtonBody mblArrowButtonText"}, btn);
-
-			this._body = body;
-			this._head = head;
-			this._btn = btn;
-			body.innerHTML = this.back;
-			this.connect(body, "onclick", "onClick");
-			var neck = dojo.create("DIV", {className:"mblArrowButtonNeck"}, btn);
-			btn.style.width = body.offsetWidth + head.offsetWidth + "px";
-			this.setLabel(this.label);
-		}
-	},
-
-	startup: function(){
-		if(this._btn){
-			this._btn.style.width = this._body.offsetWidth + this._head.offsetWidth + "px";
-		}
-	},
-
-	onClick: function(e){
-		var h1 = this.domNode;
-		dojo.addClass(h1, "mblArrowButtonSelected");
-		setTimeout(function(){
-			dojo.removeClass(h1, "mblArrowButtonSelected");
-		}, 1000);
-		this.goTo(this.moveTo, this.href);
-	},
-
-	setLabel: function(label){
-		if(label != this.label){
-			this.label = label;
-			this.domNode.firstChild.nodeValue = label;
-		}
-	},
-
-	goTo: function(moveTo, href){
-		if(!this._view){
-			this._view = dijit.byNode(this.domNode.parentNode);
-		}
-		if(!this._view){ return; }
-		if(href){
-			this._view.performTransition(null, -1, this.transition, this, function(){location.href = href;});
-		}else{
-			if(dojox.mobile.app && dojox.mobile.app.STAGE_CONTROLLER_ACTIVE){
-				// If in a full mobile app, then use its mechanisms to move back a scene
-				dojo.publish("/dojox/mobile/app/goback");
-			}
-			else{
-				this._view.performTransition(moveTo, -1, this.transition);
-			}
-
-		}
-	}
-});
-
-dojo.declare(
-	"dojox.mobile.RoundRect",
-	dijit._WidgetBase,
-{
-	shadow: false,
-
-	buildRendering: function(){
-		this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("DIV");
-		this.domNode.className = this.shadow ? "mblRoundRect mblShadow" : "mblRoundRect";
-	}
-});
-
-dojo.declare(
-	"dojox.mobile.RoundRectCategory",
-	dijit._WidgetBase,
-{
-	label: "",
-
-	buildRendering: function(){
-		this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("H2");
-		this.domNode.className = "mblRoundRectCategory";
-		if(this.label){
-			this.domNode.innerHTML = this.label;
-		}else{
-			this.label = this.domNode.innerHTML;
-		}
-	}
-});
-
-dojo.declare(
-	"dojox.mobile.EdgeToEdgeCategory",
-	dojox.mobile.RoundRectCategory,
-{
-	buildRendering: function(){
-		this.inherited(arguments);
-		this.domNode.className = "mblEdgeToEdgeCategory";
-	}
-});
-
-dojo.declare(
-	"dojox.mobile.RoundRectList",
-	dijit._WidgetBase,
-{
-	transition: "slide",
-	iconBase: "",
-	iconPos: "",
-
-	buildRendering: function(){
-		this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("UL");
-		this.domNode.className = "mblRoundRectList";
-	},
-
-	addChild: function(widget){
-		this.containerNode.appendChild(widget.domNode);
-		widget.inheritParams();
-		widget.setIcon();
-	}
-});
-
-dojo.declare(
-	"dojox.mobile.EdgeToEdgeList",
-	dojox.mobile.RoundRectList,
-{
-	stateful: false, // keep the selection state or not
-	buildRendering: function(){
-		this.inherited(arguments);
-		this.domNode.className = "mblEdgeToEdgeList";
-	}
-});
-
-dojo.declare(
-	"dojox.mobile.AbstractItem",
-	dijit._WidgetBase,
-{
-	icon: "",
-	iconPos: "", // top,left,width,height (ex. "0,0,29,29")
-	href: "",
-	hrefTarget: "",
-	moveTo: "",
-	scene: "",
-	clickable: false,
-	url: "",
-	urlTarget: "", // node id under which a new view is created
-	transition: "",
-	transitionDir: 1,
-	callback: null,
-	sync: true,
-	label: "",
-	toggle: false,
-	_duration: 800, // duration of selection, milliseconds
-
-	inheritParams: function(){
-		var parent = this.getParentWidget();
-		if(parent){
-			if(!this.transition){ this.transition = parent.transition; }
-			if(!this.icon){ this.icon = parent.iconBase; }
-			if(!this.iconPos){ this.iconPos = parent.iconPos; }
-		}
-	},
-
-	findCurrentView: function(moveTo){
-		var w;
-		if(moveTo){
-			w = dijit.byId(moveTo);
-			if(w){ return w.getShowingView(); }
-		}
-		var n = this.domNode.parentNode;
-		while(true){
-			w = dijit.getEnclosingWidget(n);
-			if(!w){ return null; }
-			if(w.performTransition){ break; }
-			n = w.domNode.parentNode;
-		}
-		return w;
-	},
-
-	transitionTo: function(moveTo, href, url, scene){
-		var w = this.findCurrentView(moveTo); // the current view widget
-		if(!w || moveTo && w === dijit.byId(moveTo)){ return; }
-		if(href){
-			if(this.hrefTarget){
-				dojox.mobile.openWindow(this.href, this.hrefTarget);
-			}else{
-				w.performTransition(null, this.transitionDir, this.transition, this, function(){location.href = href;});
-			}
-			return;
-		} else if(scene){
-			dojo.publish("/dojox/mobile/app/pushScene", [scene]);
-			return;
-		}
-		if(url){
-			var id;
-			if(dojox.mobile._viewMap && dojox.mobile._viewMap[url]){
-				// external view has already been loaded
-				id = dojox.mobile._viewMap[url];
-			}else{
-				// get the specified external view and append it to the <body>
-				var text = this._text;
-				if(!text){
-					if(this.sync){
-						text = dojo.trim(dojo._getText(url));
-					}else{
-						dojo["require"]("dojo._base.xhr");
-						var prog = dojox.mobile.ProgressIndicator.getInstance();
-						dojo.body().appendChild(prog.domNode);
-						prog.start();
-						var xhr = dojo.xhrGet({
-							url: url,
-							handleAs: "text"
-						});
-						xhr.addCallback(dojo.hitch(this, function(response, ioArgs){
-							prog.stop();
-							if(response){
-								this._text = response;
-								this.transitionTo(moveTo, href, url, scene);
-							}
-						}));
-						xhr.addErrback(function(error){
-							prog.stop();
-							alert("Failed to load "+url+"\n"+(error.description||error));
-						});
-						return;
-					}
-				}
-				this._text = null;
-				id = this._parse(text);
-				if(!dojox.mobile._viewMap){
-					dojox.mobile._viewMap = [];
-				}
-				dojox.mobile._viewMap[url] = id;
-			}
-			moveTo = id;
-			w = this.findCurrentView(moveTo) || w; // the current view widget
-		}
-		w.performTransition(moveTo, this.transitionDir, this.transition, this.callback && this, this.callback);
-	},
-
-	_parse: function(text){
-		var container = dojo.create("DIV");
-		var view;
-		var id = this.urlTarget;
-		var target = dijit.byId(id) && dijit.byId(id).containerNode ||
-			dojo.byId(id) ||
-			dojox.mobile.currentView && dojox.mobile.currentView.domNode.parentNode ||
-			dojo.body();
-		if(text.charAt(0) == "<"){ // html markup
-			container.innerHTML = text;
-			view = container.firstChild; // <div dojoType="dojox.mobile.View">
-			if(!view && view.nodeType != 1){
-				alert("dojox.mobile.AbstractItem#transitionTo: invalid view content");
-				return;
-			}
-			view.setAttribute("_started", "true"); // to avoid startup() is called
-			view.style.visibility = "hidden";
-			target.appendChild(container);
-			(dojox.mobile.parser || dojo.parser).parse(container);
-			target.appendChild(target.removeChild(container).firstChild); // reparent
-		}else if(text.charAt(0) == "{"){ // json
-			target.appendChild(container);
-			this._ws = [];
-			view = this._instantiate(eval('('+text+')'), container);
-			for(var 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";
-		var id = view.id;
-		return dojo.hash ? "#" + id : id;
-	},
-
-	_instantiate: function(/*Object*/obj, /*DomNode*/node, /*Widget*/parent){
-		var widget;
-		for(var key in obj){
-			if(key.charAt(0) == "@"){ continue; }
-			var cls = dojo.getObject(key);
-			if(!cls){ continue; }
-			var params = {};
-			var proto = cls.prototype;
-			var objs = dojo.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 + ")");
-						}
-					}
-				}
-				widget = new cls(params, node);
-				if(!node){ // not to call View's startup()
-					this._ws.push(widget);
-				}
-				if(parent && parent.addChild){
-					parent.addChild(widget);
-				}
-				this._instantiate(objs[i], null, widget);
-			}
-		}
-		return widget && widget.domNode;
-	},
-
-	createDomButton: function(/*DomNode*/refNode, /*DomNode?*/toNode){
-		var s = refNode.className;
-		if(s.match(/mblDomButton\w+_(\d+)/)){
-			var nDiv = RegExp.$1 - 0;
-			for(var i = 0, p = (toNode||refNode); i < nDiv; i++){
-				p = dojo.create("DIV", null, p);
-			}
-		}
-	},
-
-	select: function(/*Boolean?*/deselect){
-		// subclass must implement
-	},
-
-	defaultClickAction: function(){
-		if(this.toggle){
-			this.select(this.selected);
-		}else if(!this.selected){
-			this.select();
-			if(!this.selectOne){
-				var _this = this;
-				setTimeout(function(){
-					_this.select(true);
-				}, this._duration);
-			}
-			if(this.moveTo || this.href || this.url || this.scene){
-				this.transitionTo(this.moveTo, this.href, this.url, this.scene);
-			}
-		}
-	},
-
-	getParentWidget: function(){
-		var ref = this.srcNodeRef || this.domNode;
-		return ref && ref.parentNode ? dijit.getEnclosingWidget(ref.parentNode) : null;
-	}
-});
-
-dojo.declare(
-	"dojox.mobile.ListItem",
-	dojox.mobile.AbstractItem,
-{
-	rightText: "",
-	btnClass: "",
-	anchorLabel: false,
-	noArrow: false,
-	selected: false,
-
-	buildRendering: function(){
-		this.inheritParams();
-		var a = this.anchorNode = dojo.create("A");
-		a.className = "mblListItemAnchor";
-		var box = dojo.create("DIV");
-		box.className = "mblListItemTextBox";
-		if(this.anchorLabel){
-			box.style.cursor = "pointer";
-		}
-		var r = this.srcNodeRef;
-		if(r){
-			for(var i = 0, len = r.childNodes.length; i < len; i++){
-				box.appendChild(r.removeChild(r.firstChild));
-			}
-		}
-		if(this.label){
-			box.appendChild(dojo.doc.createTextNode(this.label));
-		}
-		a.appendChild(box);
-		if(this.rightText){
-			this._setRightTextAttr(this.rightText);
-		}
-
-		if(this.moveTo || this.href || this.url || this.clickable){
-			var parent = this.getParentWidget();
-			if(!this.noArrow && !(parent && parent.stateful)){
-				var arrow = dojo.create("DIV");
-				arrow.className = "mblArrow";
-				a.appendChild(arrow);
-			}
-			this.connect(a, "onclick", "onClick");
-		}else if(this.btnClass){
-			var div = this.btnNode = dojo.create("DIV");
-			div.className = this.btnClass+" mblRightButton";
-			div.appendChild(dojo.create("DIV"));
-			div.appendChild(dojo.create("P"));
-
-			var dummyDiv = dojo.create("DIV");
-			dummyDiv.className = "mblRightButtonContainer";
-			dummyDiv.appendChild(div);
-			a.appendChild(dummyDiv);
-			dojo.addClass(a, "mblListItemAnchorHasRightButton");
-			setTimeout(function(){
-				dummyDiv.style.width = div.offsetWidth + "px";
-				dummyDiv.style.height = div.offsetHeight + "px";
-				if(dojo.isIE){
-					// IE seems to ignore the height of LI without this..
-					a.parentNode.style.height = a.parentNode.offsetHeight + "px";
-				}
-			}, 0);
-		}
-		if(this.anchorLabel){
-			box.style.display = "inline"; // to narrow the text region
-		}
-		var li = this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("LI");
-		li.className = "mblListItem" + (this.selected ? " mblItemSelected" : "");
-		li.appendChild(a);
-		this.setIcon();
-	},
-
-	setIcon: function(){
-		if(this.iconNode){ return; }
-		var a = this.anchorNode;
-		if(this.icon && this.icon != "none"){
-			var img = this.iconNode = dojo.create("IMG");
-			img.className = "mblListItemIcon";
-			img.src = this.icon;
-			this.domNode.insertBefore(img, a);
-			dojox.mobile.setupIcon(this.iconNode, this.iconPos);
-			dojo.removeClass(a, "mblListItemAnchorNoIcon");
-		}else{
-			dojo.addClass(a, "mblListItemAnchorNoIcon");
-		}
-	},
-
-	onClick: function(e){
-		var a = e.currentTarget;
-		var li = a.parentNode;
-		if(dojo.hasClass(li, "mblItemSelected")){ return; } // already selected
-		if(this.anchorLabel){
-			for(var p = e.target; p.tagName != "LI"; p = p.parentNode){
-				if(p.className == "mblListItemTextBox"){
-					dojo.addClass(p, "mblListItemTextBoxSelected");
-					setTimeout(function(){
-						dojo.removeClass(p, "mblListItemTextBoxSelected");
-					}, 1000);
-					this.onAnchorLabelClicked(e);
-					return;
-				}
-			}
-		}
-		if(this.getParentWidget().stateful){
-			for(var i = 0, c = li.parentNode.childNodes; i < c.length; i++){
-				dojo.removeClass(c[i], "mblItemSelected");
-			}
-		}else{
-			setTimeout(function(){
-				dojo.removeClass(li, "mblItemSelected");
-			}, 1000);
-		}
-		dojo.addClass(li, "mblItemSelected");
-		this.transitionTo(this.moveTo, this.href, this.url, this.scene);
-	},
-
-	onAnchorLabelClicked: function(e){
-	},
-
-	_setRightTextAttr: function(/*String*/text){
-		this.rightText = text;
-		if(!this._rightTextNode){
-			this._rightTextNode = dojo.create("DIV", {className:"mblRightText"}, this.anchorNode);
-		}
-		this._rightTextNode.innerHTML = text;
-	}
-});
-
-dojo.declare(
-	"dojox.mobile.Switch",
-	dijit._WidgetBase,
-{
-	value: "on",
-	leftLabel: "ON",
-	rightLabel: "OFF",
-	_width: 53,
-
-	buildRendering: function(){
-		this.domNode = this.srcNodeRef || dojo.doc.createElement("DIV");
-		this.domNode.className = "mblSwitch";
-		this.domNode.innerHTML =
-			  '<div class="mblSwitchInner">'
-			+	'<div class="mblSwitchBg mblSwitchBgLeft">'
-			+		'<div class="mblSwitchText mblSwitchTextLeft">'+this.leftLabel+'</div>'
-			+	'</div>'
-			+	'<div class="mblSwitchBg mblSwitchBgRight">'
-			+		'<div class="mblSwitchText mblSwitchTextRight">'+this.rightLabel+'</div>'
-			+	'</div>'
-			+	'<div class="mblSwitchKnob"></div>'
-			+ '</div>';
-		var n = this.inner = this.domNode.firstChild;
-		this.left = n.childNodes[0];
-		this.right = n.childNodes[1];
-		this.knob = n.childNodes[2];
-
-		dojo.addClass(this.domNode, (this.value == "on") ? "mblSwitchOn" : "mblSwitchOff");
-		this[this.value == "off" ? "left" : "right"].style.display = "none";
-	},
-
-	postCreate: function(){
-		this.connect(this.knob, "onclick", "onClick");
-		this.connect(this.knob, "touchstart", "onTouchStart");
-		this.connect(this.knob, "mousedown", "onTouchStart");
-	},
-
-	_changeState: function(/*String*/state){
-		this.inner.style.left = "";
-		dojo.addClass(this.domNode, "mblSwitchAnimation");
-		dojo.removeClass(this.domNode, (state == "on") ? "mblSwitchOff" : "mblSwitchOn");
-		dojo.addClass(this.domNode, (state == "on") ? "mblSwitchOn" : "mblSwitchOff");
-
-		var _this = this;
-		setTimeout(function(){
-			_this[state == "off" ? "left" : "right"].style.display = "none";
-			dojo.removeClass(_this.domNode, "mblSwitchAnimation");
-		}, 300);
-	},
-
-	onClick: function(e){
-		if(this._moved){ return; }
-		this.value = (this.value == "on") ? "off" : "on";
-		this._changeState(this.value);
-		this.onStateChanged(this.value);
-	},
-
-	onTouchStart: function(e){
-		this._moved = false;
-		this.innerStartX = this.inner.offsetLeft;
-		if(e.targetTouches){
-			this.touchStartX = e.targetTouches[0].clientX;
-			this._conn1 = dojo.connect(this.inner, "touchmove", this, "onTouchMove");
-			this._conn2 = dojo.connect(this.inner, "touchend", this, "onTouchEnd");
-		}
-		this.left.style.display = "block";
-		this.right.style.display = "block";
-		dojo.stopEvent(e);
-	},
-
-	onTouchMove: function(e){
-		e.preventDefault();
-		var dx;
-		if(e.targetTouches){
-			if(e.targetTouches.length != 1){ return false; }
-			dx = e.targetTouches[0].clientX - this.touchStartX;
-		}else{
-			dx = e.clientX - this.touchStartX;
-		}
-		var pos = this.innerStartX + dx;
-		var d = 10;
-		if(pos <= -(this._width-d)){ pos = -this._width; }
-		if(pos >= -d){ pos = 0; }
-		this.inner.style.left = pos + "px";
-		this._moved = true;
-	},
-
-	onTouchEnd: function(e){
-		dojo.disconnect(this._conn1);
-		dojo.disconnect(this._conn2);
-		if(this.innerStartX == this.inner.offsetLeft){
-			if(dojo.isWebKit){
-				var ev = dojo.doc.createEvent("MouseEvents");
-				ev.initEvent("click", true, true);
-				this.knob.dispatchEvent(ev);
-			}
-			return;
-		}
-		var newState = (this.inner.offsetLeft < -(this._width/2)) ? "off" : "on";
-		this._changeState(newState);
-		if(newState != this.value){
-			this.value = newState;
-			this.onStateChanged(this.value);
-		}
-	},
-
-	onStateChanged: function(/*String*/newState){
-	}
-});
-
-dojo.declare(
-	"dojox.mobile.Button",
-	dijit._WidgetBase,
-{
-	btnClass: "mblBlueButton",
-	duration: 1000, // duration of selection, milliseconds
-
-	label: null,
-
-	buildRendering: function(){
-		this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("BUTTON");
-		this.domNode.className = "mblButton "+this.btnClass;
-
-		if(this.label){
-			this.domNode.innerHTML = this.label;
-		}
-
-		this.connect(this.domNode, "onclick", "onClick");
-	},
-
-	onClick: function(e){
-		var button = this.domNode;
-		var c = "mblButtonSelected "+this.btnClass+"Selected";
-		dojo.addClass(button, c);
-		setTimeout(function(){
-			dojo.removeClass(button, c);
-		}, this.duration);
-	}
-});
-
-dojo.declare(
-	"dojox.mobile.ToolBarButton",
-	dojox.mobile.AbstractItem,
-{
-	selected: false,
-	_defaultColor: "mblColorDefault",
-	_selColor: "mblColorDefaultSel",
-
-	buildRendering: function(){
-		this.inheritParams();
-		this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("div");
-		dojo.addClass(this.domNode, "mblToolbarButton mblArrowButtonText");
-		var color;
-		if(this.selected){
-			color = this._selColor;
-		}else if(this.domNode.className.indexOf("mblColor") == -1){
-			color = this._defaultColor;
-		}
-		dojo.addClass(this.domNode, color);
-
-		if(this.label){
-			this.domNode.innerHTML = this.label;
-		}else{
-			this.label = this.domNode.innerHTML;
-		}
-
-		if(this.icon && this.icon != "none"){
-			var img;
-			if(this.iconPos){
-				var iconDiv = dojo.create("DIV", null, this.domNode);
-				img = dojo.create("IMG", null, iconDiv);
-				img.style.position = "absolute";
-				var arr = this.iconPos.split(/[ ,]/);
-				dojo.style(iconDiv, {
-					position: "relative",
-					width: arr[2] + "px",
-					height: arr[3] + "px"
-				});
-			}else{
-				img = dojo.create("IMG", null, this.domNode);
-			}
-			img.src = this.icon;
-			dojox.mobile.setupIcon(img, this.iconPos);
-			this.iconNode = img;
-		}
-		this.createDomButton(this.domNode);
-		this.connect(this.domNode, "onclick", "onClick");
-	},
-
-	select: function(/*Boolean?*/deselect){
-		dojo.toggleClass(this.domNode, this._selColor, !deselect);
-		this.selected = !deselect;
-	},
-
-	onClick: function(e){
-		this.defaultClickAction();
-	}
-});
-
-dojo.declare(
-	"dojox.mobile.ProgressIndicator",
-	null,
-{
-	interval: 100, // milliseconds
-	colors: [
-		"#C0C0C0", "#C0C0C0", "#C0C0C0", "#C0C0C0",
-		"#C0C0C0", "#C0C0C0", "#B8B9B8", "#AEAFAE",
-		"#A4A5A4", "#9A9A9A", "#8E8E8E", "#838383"
-	],
-
-	_bars: [],
-
-	constructor: function(){
-		this.domNode = dojo.create("DIV");
-		this.domNode.className = "mblProgContainer";
-		for(var i = 0; i < 12; i++){
-			var div = dojo.create("DIV");
-			div.className = "mblProg mblProg"+i;
-			this.domNode.appendChild(div);
-			this._bars.push(div);
-		}
-	},
-
-	start: function(){
-		var cntr = 0;
-		var _this = this;
-		this.timer = setInterval(function(){
-			cntr--;
-			cntr = cntr < 0 ? 11 : cntr;
-			var c = _this.colors;
-			for(var i = 0; i < 12; i++){
-				var idx = (cntr + i) % 12;
-				_this._bars[i].style.backgroundColor = c[idx];
-			}
-		}, this.interval);
-	},
-
-	stop: function(){
-		if(this.timer){
-			clearInterval(this.timer);
-		}
-		this.timer = null;
-		if(this.domNode.parentNode){
-			this.domNode.parentNode.removeChild(this.domNode);
-		}
-	}
-});
-dojox.mobile.ProgressIndicator._instance = null;
-dojox.mobile.ProgressIndicator.getInstance = function(){
-	if(!dojox.mobile.ProgressIndicator._instance){
-		dojox.mobile.ProgressIndicator._instance = new dojox.mobile.ProgressIndicator();
-	}
-	return dojox.mobile.ProgressIndicator._instance;
-};
-
-dojox.mobile.addClass = function(){
-	// summary:
-	//		Adds a theme class name to <body>.
-	// description:
-	//		Finds the currently applied theme name, such as 'iphone' or 'android'
-	//		from link elements, and adds it as a class name for the body element.
-	var elems = document.getElementsByTagName("link");
-	for(var i = 0, len = elems.length; i < len; i++){
-		if(elems[i].href.match(/dojox\/mobile\/themes\/(\w+)\//)){
-			dojox.mobile.theme = RegExp.$1;
-			dojo.addClass(dojo.body(), dojox.mobile.theme);
-			break;
-		}
-	}
-};
-
-dojox.mobile.setupIcon = function(/*DomNode*/iconNode, /*String*/iconPos){
-	if(iconNode && iconPos){
-		var arr = dojo.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
-		iconNode.style.clip = "rect("+t+"px "+r+"px "+b+"px "+l+"px)";
-		iconNode.style.top = dojo.style(iconNode, "top") - t + "px";
-		iconNode.style.left = dojo.style(iconNode.parentNode, "paddingLeft") - l + "px";
-	}
-};
-
-dojox.mobile.hideAddressBar = function(){
-	dojo.body().style.minHeight = "1000px"; // to ensure enough height for scrollTo to work
-	setTimeout(function(){ scrollTo(0, 1); }, 100);
-	setTimeout(function(){ scrollTo(0, 1); }, 400);
-	setTimeout(function(){
-		scrollTo(0, 1);
-		// re-define the min-height with the actual height
-		dojo.body().style.minHeight = (dojo.global.innerHeight||dojo.doc.documentElement.clientHeight) + "px";
-	}, 1000);
-};
-
-dojox.mobile.openWindow = function(url, target){
-	dojo.global.open(url, target || "_blank");
-};
-
-dojo._loaders.unshift(function(){
-	// avoid use of dojo.query
-	/*
-	var list = dojo.query('[lazy=true] [dojoType]', null);
-	list.forEach(function(node, index, nodeList){
-		node.setAttribute("__dojoType", node.getAttribute("dojoType"));
-		node.removeAttribute("dojoType");
-	});
-	*/
-
-	var nodes = dojo.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");
-			}
-		}
-	}
-});
-
-dojo.addOnLoad(function(){
-	dojox.mobile.addClass();
-	if(dojo.config["mblApplyPageStyles"] !== false){
-		dojo.addClass(dojo.doc.documentElement, "mobile");
-	}
-
-	//	You can disable hiding the address bar with the following djConfig.
-	//	var djConfig = { mblHideAddressBar: false };
-	if(dojo.config["mblHideAddressBar"] !== false){
-		dojox.mobile.hideAddressBar();
-		if(dojo.config["mblAlwaysHideAddressBar"] == true){
-			if(dojo.global.onorientationchange !== undefined){
-				dojo.connect(dojo.global, "onorientationchange", dojox.mobile.hideAddressBar);
-			}else{
-				dojo.connect(dojo.global, "onresize", dojox.mobile.hideAddressBar);
-			}
-		}
-	}
-
-	// avoid use of dojo.query
-	/*
-	var list = dojo.query('[__dojoType]', null);
-	list.forEach(function(node, index, nodeList){
-		node.setAttribute("dojoType", node.getAttribute("__dojoType"));
-		node.removeAttribute("__dojoType");
-	});
-	*/
-
-	var nodes = dojo.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){
-			var arr;
-			arr = dijit.findWidgets(root);
-			var widgets = arr;
-			for(var i = 0; i < widgets.length; i++){
-				arr = arr.concat(findWidgets(widgets[i].containerNode));
-			}
-			return arr;
-		};
-		dojo.subscribe("/dojo/hashchange", null, function(value){
-			var view = dojox.mobile.currentView;
-			if(!view){ return; }
-			var params = dojox.mobile._params;
-			if(!params){ // browser back/forward button was pressed
-				var moveTo = value ? value : dojox.mobile._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 dojox.mobile.Heading) ? -1 : 1;
-						break;
-					}
-				}
-				params = [ moveTo, dir, transition ];
-			}
-			view.performTransition.apply(view, params);
-			dojox.mobile._params = null;
-		});
-	}
-
-	dojo.body().style.visibility = "visible";
-});
-
-dijit.getEnclosingWidget = function(node){
-	while(node && node.tagName !== "BODY"){
-		if(node.getAttribute && node.getAttribute("widgetId")){
-			return dijit.registry.byId(node.getAttribute("widgetId"));
-		}
-		node = node._parentNode || node.parentNode;
-	}
-	return null;
-};
diff --git a/dojox/mobile/_compat.js b/dojox/mobile/_compat.js
new file mode 100644
index 0000000..ecbe21a
--- /dev/null
+++ b/dojox/mobile/_compat.js
@@ -0,0 +1,544 @@
+define([
+	"dojo/_base/array",	// array.forEach
+	"dojo/_base/config",
+	"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/_base/window",	// win.doc, win.body
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+	"dojo/fx",
+	"dojo/fx/easing",
+	"dojo/ready",
+	"dojo/uacss",
+	"dijit/registry",	// registry.byNode
+	"dojox/fx",
+	"dojox/fx/flip",
+	"./EdgeToEdgeList",
+	"./IconContainer",
+	"./RoundRect",
+	"./RoundRectList",
+	"./ScrollableView",
+	"./Switch",
+	"./View",
+	"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;
+=====*/
+
+	// module:
+	//		dojox/mobile/compat
+	// summary:
+	//		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.
+	//
+	//		dojo.require("dojox.mobile");
+	//		dojo.requireIf(!has("webkit"), "dojox.mobile.compat");
+	//
+	//		This module also loads compatibility CSS files, which has -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.
+
+	var dm = lang.getObject("dojox.mobile", true);
+	/*=====
+	dm = dojox.mobile
+	=====*/
+
+	if(!has("webkit")){
+		lang.extend(View, {
+			_doTransition: function(fromNode, toNode, transition, dir){
+				var anim;
+				this.wakeUp(toNode);
+				if(!transition || transition == "none"){
+					toNode.style.display = "";
+					fromNode.style.display = "none";
+					toNode.style.left = "0px";
+					this.invokeCallback();
+				}else if(transition == "slide" || transition == "cover" || transition == "reveal"){
+					var w = fromNode.offsetWidth;
+					var s1 = fx.slideTo({
+						node: fromNode,
+						duration: 400,
+						left: -w*dir,
+						top: domStyle.get(fromNode, "top")
+					});
+					var s2 = fx.slideTo({
+						node: toNode,
+						duration: 400,
+						left: 0,
+						top: domStyle.get(toNode, "top")
+					});
+					toNode.style.position = "absolute";
+					toNode.style.left = w*dir + "px";
+					toNode.style.display = "";
+					anim = fx.combine([s1,s2]);
+					connect.connect(anim, "onEnd", this, function(){
+						fromNode.style.display = "none";
+						fromNode.style.left = "0px";
+						toNode.style.position = "relative";
+						var toWidget = registry.byNode(toNode);
+						if(toWidget && !domClass.contains(toWidget.domNode, "out")){
+							// Reset the temporary padding
+							toWidget.containerNode.style.paddingTop = "";
+						}
+						this.invokeCallback();
+					});
+					anim.play();
+				}else if(transition == "slidev" || transition == "coverv" || transition == "reavealv"){
+					var h = fromNode.offsetHeight;
+					var s1 = fx.slideTo({
+						node: fromNode,
+						duration: 400,
+						left: 0,
+						top: -h*dir
+					});
+					var s2 = fx.slideTo({
+						node: toNode,
+						duration: 400,
+						left: 0,
+						top: 0
+					});
+					toNode.style.position = "absolute";
+					toNode.style.top = h*dir + "px";
+					toNode.style.left = "0px";
+					toNode.style.display = "";
+					anim = fx.combine([s1,s2]);
+					connect.connect(anim, "onEnd", this, function(){
+						fromNode.style.display = "none";
+						toNode.style.position = "relative";
+						this.invokeCallback();
+					});
+					anim.play();
+				}else if(transition == "flip"){
+					anim = xfx.flip({
+						node: fromNode,
+						dir: "right",
+						depth: 0.5,
+						duration: 400
+					});
+					toNode.style.position = "absolute";
+					toNode.style.left = "0px";
+					connect.connect(anim, "onEnd", this, function(){
+						fromNode.style.display = "none";
+						toNode.style.position = "relative";
+						toNode.style.display = "";
+						this.invokeCallback();
+					});
+					anim.play();
+				}else {
+					// other transitions - "fade", "dissolve", "swirl"
+					anim = fx.chain([
+						bfx.fadeOut({
+							node: fromNode,
+							duration: 600
+						}),
+						bfx.fadeIn({
+							node: toNode,
+							duration: 600
+						})
+					]);
+					toNode.style.position = "absolute";
+					toNode.style.left = "0px";
+					toNode.style.display = "";
+					domStyle.set(toNode, "opacity", 0);
+					connect.connect(anim, "onEnd", this, function(){
+						fromNode.style.display = "none";
+						toNode.style.position = "relative";
+						domStyle.set(fromNode, "opacity", 1);
+						this.invokeCallback();
+					});
+					anim.play();
+				}
+				dm.currentView = registry.byNode(toNode);
+			},
+		
+			wakeUp: function(/*DomNode*/node){
+				// summary:
+				//		Function to force IE to redraw a node since its layout
+				//		code tends to misrender in partial draws.
+				// node: DomNode
+				//		The node to forcibly redraw.
+				// tags:
+				//		public
+				if(has("ie") && !node._wokeup){
+					node._wokeup = true;
+					var disp = node.style.display;
+					node.style.display = "";
+					var nodes = node.getElementsByTagName("*");
+					for(var i = 0, len = nodes.length; i < len; i++){
+						var val = nodes[i].style.display;
+						nodes[i].style.display = "none";
+						nodes[i].style.display = "";
+						nodes[i].style.display = val;
+					}
+					node.style.display = disp;
+				}
+			}
+		});	
+
+	
+		lang.extend(Switch, {
+			_changeState: function(/*String*/state, /*Boolean*/anim){
+				// summary:
+				//		Function to toggle the switch state on the switch
+				// state:
+				//		The state to toggle, switch 'on' or 'off'
+				// anim:
+				//		Whether to use animation or not
+				// tags:
+				//		private
+				var on = (state === "on");
+		
+				var pos;
+				if(!on){
+					pos = -this.inner.firstChild.firstChild.offsetWidth;
+				}else{
+					pos = 0;
+				}
+		
+				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";
+				};
+		
+				if(anim){
+					var a = fx.slideTo({
+						node: this.inner,
+						duration: 300,
+						left: pos,
+						onEnd: f
+					});
+					a.play();
+				}else{
+					if(on || pos){
+						this.inner.style.left = pos + "px";
+					}
+					f();
+				}
+			}
+		});	
+
+	
+		if(has("ie")){
+			lang.extend(RoundRect, {
+				buildRendering: function(){
+					// summary:
+					//		Function to simulate the borderRadius appearance on
+					//		IE, since IE does not support this CSS style.
+					// tags:
+					//		protected
+					dm.createRoundRect(this);
+					this.domNode.className = "mblRoundRect";
+				}
+			});
+
+
+			RoundRectList._addChild = RoundRectList.prototype.addChild;
+			lang.extend(RoundRectList, {
+				buildRendering: function(){
+					// summary:
+					//		Function to simulate the borderRadius appearance on
+					//		IE, since IE does not support this CSS style.
+					// tags:
+					//		protected
+					dm.createRoundRect(this, true);
+					this.domNode.className = "mblRoundRectList";
+				},
+			
+				postCreate: function(){
+					this.redrawBorders();
+				},
+		
+				addChild: function(widget, /*Number?*/insertIndex){
+					RoundRectList._addChild.apply(this, arguments);
+					this.redrawBorders();
+					if(dm.applyPngFilter){
+						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.
+
+					if(this instanceof EdgeToEdgeList){ return; }
+					var lastChildFound = false;
+					for(var i = this.containerNode.childNodes.length - 1; i >= 0; i--){
+						var c = this.containerNode.childNodes[i];
+						if(c.tagName == "LI"){
+							c.style.borderBottomStyle = lastChildFound ? "solid" : "none";
+							lastChildFound = true;
+						}
+					}
+				}
+			});	
+
+
+			lang.extend(EdgeToEdgeList, {
+				buildRendering: function(){
+				this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("UL");
+					this.domNode.className = "mblEdgeToEdgeList";
+				}
+			});
+
+
+			IconContainer._addChild = IconContainer.prototype.addChild;
+			lang.extend(IconContainer, {
+				addChild: function(widget, /*Number?*/insertIndex){
+					IconContainer._addChild.apply(this, arguments);
+					if(dm.applyPngFilter){
+						dm.applyPngFilter(widget.domNode);
+					}
+				}
+			});
+
+
+			lang.mixin(dm, {
+				createRoundRect: function(_this, isList){
+					// summary:
+					//		Function to adjust the creation of rounded rectangles on IE.
+					//		Deals with IE's lack of borderRadius support
+					// tags:
+					//		public
+					var i, len;
+					_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.className = "mblRoundRectContainer";
+					if(_this.srcNodeRef){
+						_this.srcNodeRef.parentNode.replaceChild(_this.domNode, _this.srcNodeRef);
+						for(i = 0, len = _this.srcNodeRef.childNodes.length; i < len; i++){
+							_this.containerNode.appendChild(_this.srcNodeRef.removeChild(_this.srcNodeRef.firstChild));
+						}
+						_this.srcNodeRef = null;
+					}
+					_this.domNode.appendChild(_this.containerNode);
+		
+					for(i = 0; i <= 5; i++){
+						var top = domConstruct.create("DIV");
+						top.className = "mblRoundCorner mblRoundCorner"+i+"T";
+						_this.domNode.insertBefore(top, _this.containerNode);
+		
+						var bottom = domConstruct.create("DIV");
+						bottom.className = "mblRoundCorner mblRoundCorner"+i+"B";
+						_this.domNode.appendChild(bottom);
+					}
+				}
+			});
+
+
+			lang.extend(ScrollableView, {
+				postCreate: function(){
+					// 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");
+					domStyle.set(dummy, {
+						position: "relative",
+						marginBottom: "-2px",
+						fontSize: "1px"
+					});
+				}
+			});
+		} // if	(has("ie"))
+
+
+		if(has("ie") <= 6){
+			dm.applyPngFilter = function(root){
+				root = root || win.body();
+				var nodes = root.getElementsByTagName("IMG");
+				var blank = require.toUrl("dojo/resources/blank.gif");
+				for(var i = 0, len = nodes.length; i < len; i++){
+					var img = nodes[i];
+					var w = img.offsetWidth;
+					var h = img.offsetHeight;
+					if(w === 0 || h === 0){
+						// The reason why the image has no width/height may be because
+						// display is "none". If that is the case, let's change the
+						// display to "" temporarily and see if the image returns them.
+						if(domStyle.get(img, "display") != "none"){ continue; }
+						img.style.display = "";
+						w = img.offsetWidth;
+						h = img.offsetHeight;
+						img.style.display = "none";
+						if(w === 0 || h === 0){ continue; }
+					}
+					var src = img.src;
+					if(src.indexOf("resources/blank.gif") != -1){ continue; }
+					img.src = blank;
+					img.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src+"')";
+					img.style.width = w + "px";
+					img.style.height = h + "px";
+				}
+			};
+
+			if(!dm._disableBgFilter && dm.createDomButton){
+				dm._createDomButton_orig = dm.createDomButton;
+				dm.createDomButton = function(/*DomNode*/refNode, /*Object?*/style, /*DomNode?*/toNode){
+					var node = dm._createDomButton_orig.apply(this, arguments);
+					if(node && node.className && node.className.indexOf("mblDomButton") !== -1){
+						var f = function(){
+							if(node.currentStyle && node.currentStyle.backgroundImage.match(/url.*(mblDomButton.*\.png)/)){
+								var img = RegExp.$1;
+								var src = require.toUrl("dojox/mobile/themes/common/domButtons/compat/") + img;
+								node.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src+"',sizingMethod='crop')";
+								node.style.background = "none";
+							}
+						};
+						setTimeout(f, 1000);
+						setTimeout(f, 5000);
+					}
+					return node;
+				};
+			}
+		} // if(has("ie") <= 6)
+
+		dm.loadCssFile = function(/*String*/file){
+			// summary:
+			//		Overrides dojox.mobile.loadCssFile() defined in
+			//		deviceTheme.js.
+			if(!dm.loadedCssFiles){ dm.loadedCssFiles = []; }
+			if(win.doc.createStyleSheet){
+				// for some reason, IE hangs when you try to load
+				// multiple css files almost at once.
+				setTimeout(function(file){
+					return function(){
+						var ss = win.doc.createStyleSheet(file);
+						ss && dm.loadedCssFiles.push(ss.owningElement);
+					};
+				}(file), 0);
+			}else{
+				dm.loadedCssFiles.push(domConstruct.create("LINK", {
+					href: file,
+					type: "text/css",
+					rel: "stylesheet"
+				}, win.doc.getElementsByTagName('head')[0]));
+			}
+		};
+
+		dm.loadCss = function(/*String|Array*/files){
+			// summary:
+			//		Function to load and register CSS files with the page
+			// files: String|Array
+			//		The CSS files to load and register with the page.
+			// tags:
+			//		private
+			if(!dm._loadedCss){
+				var obj = {};
+				array.forEach(dm.getCssPaths(), function(path){
+					obj[path] = true;
+				});
+				dm._loadedCss = obj;
+			}
+			if(!lang.isArray(files)){ files = [files]; }
+			for(var i = 0; i < files.length; i++){
+				var file = files[i];
+				if(!dm._loadedCss[file]){
+					dm._loadedCss[file] = true;
+					dm.loadCssFile(file);
+				}
+			}
+		};
+
+		dm.getCssPaths = function(){
+			var paths = [];
+			var i, j, len;
+
+			// find @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){
+						paths.push(r[j].href);
+					}
+				}
+			}
+		
+			// find <link>
+			var elems = win.doc.getElementsByTagName("link");
+			for(i = 0, len = elems.length; i < len; i++){
+				if(elems[i].href){
+					paths.push(elems[i].href);
+				}
+			}
+			return paths;
+		};
+
+		dm.loadCompatPattern = /\/mobile\/themes\/.*\.css$/;
+
+		dm.loadCompatCssFiles = function(/*Boolean?*/force){
+			// summary:
+			//		Function to perform page-level adjustments on browsers such as
+			//		IE and firefox.  It loads compat specific css files into the
+			//		page header.
+			if(has("ie") && !force){
+				setTimeout(function(){ // IE needs setTimeout
+					dm.loadCompatCssFiles(true);
+				}, 0);
+			}
+			dm._loadedCss = undefined;
+			var paths = dm.getCssPaths();
+			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){
+					var compatCss = href.substring(0, href.length-4)+"-compat.css";
+					dm.loadCss(compatCss);
+				}
+			}
+		};
+	
+		dm.hideAddressBar = function(/*Event?*/evt, /*Boolean?*/doResize){
+			if(doResize !== false){ dm.resizeAll(); }
+		};
+
+		ready(function(){
+			if(config["mblLoadCompatCssFiles"] !== false){
+				dm.loadCompatCssFiles();
+			}
+			if(dm.applyPngFilter){
+				dm.applyPngFilter();
+			}
+		});
+
+	} // end of if(!has("webkit")){
+
+	return dm;
+});
diff --git a/dojox/mobile/app.js b/dojox/mobile/app.js
index 1d5b8eb..174ad28 100755
--- a/dojox/mobile/app.js
+++ b/dojox/mobile/app.js
@@ -1,3 +1,5 @@
-dojo.provide("dojox.mobileApp");
-
-dojo.require("dojox.mobile.app._base");
\ No newline at end of file
+define([
+	"./app/_base"
+], function(appBase){
+	return appBase;
+});
diff --git a/dojox/mobile/app/TextBox.js b/dojox/mobile/app/TextBox.js
index 3485bbf..570f2c1 100644
--- a/dojox/mobile/app/TextBox.js
+++ b/dojox/mobile/app/TextBox.js
@@ -1,319 +1,6 @@
 dojo.provide("dojox.mobile.app.TextBox");
-dojo.experimental("dojox.mobile.app.TextBox");
+dojo.deprecated("dojox.mobile.app.TextBox is deprecated", "dojox.mobile.app.TextBox moved to dojox.mobile.TextBox", 1.8);
 
-dojo.require("dojox.mobile.app._Widget");
-dojo.require("dojox.mobile.app._FormWidget");
+dojo.require("dojox.mobile.TextBox");
 
-dojo.declare(
-	"dojox.mobile.app.TextBox",
-	dojox.mobile.app._FormValueWidget, {
-
-		// summary:
-		//		A base class for textbox form inputs
-
-		// 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: "",
-
-		baseClass: "mblTextBox",
-
-		attributeMap: dojo.delegate(dojox.mobile.app._FormValueWidget.prototype.attributeMap, {
-			maxLength: "focusNode"
-		}),
-
-		buildRendering: function(){
-			var node = this.srcNodeRef;
-
-			// If an input is used as the source node, wrap it in a div
-			if(!node || node.tagName != "INPUT"){
-				node = dojo.create("input", {});
-			}
-
-			dojo.attr(node, {
-				type: "text",
-				value: dojo.attr(node, "value") || "",
-				placeholder: this.placeHolder || null
-			});
-
-			this.domNode = this.textbox = this.focusNode = node;
-		},
-
-		_setPlaceHolderAttr: function(v){
-			this.placeHolder = v;
-			if(this.textbox){
-				dojo.attr(this.textbox, "placeholder", v);
-			}
-		},
-
-
-		_getValueAttr: function(){
-			// summary:
-			//		Hook so attr('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 attr('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.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 attr('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 attr('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)
-
-			return this.filter(this.textbox.value);
-		},
-
-		_setDisplayedValueAttr: function(/*String*/value){
-			// summary:
-			//		Hook so attr('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;
-			this._setValueAttr(this.get('value'), undefined, value);
-		},
-
-		format: function(/* String */ value, /* Object */ constraints){
-			// summary:
-			//		Replacable function to convert a value to a properly formatted string.
-			// tags:
-			//		protected extension
-			return ((value == null || value == undefined) ? "" : (value.toString ? value.toString() : value));
-		},
-
-		parse: function(/* String */ value, /* Object */ constraints){
-			// summary:
-			//		Replacable function to convert a formatted string to a value
-			// 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(e){
-			if(e && e.type && /key/i.test(e.type) && e.keyCode){
-				switch(e.keyCode){
-					case dojo.keys.SHIFT:
-					case dojo.keys.ALT:
-					case dojo.keys.CTRL:
-					case dojo.keys.TAB:
-						return;
-				}
-			}
-			if(this.intermediateChanges){
-				var _this = this;
-				// the setTimeout allows the key to post to the widget input box
-				setTimeout(function(){ _this._handleOnChange(_this.get('value'), false); }, 0);
-			}
-			this._refreshState();
-		},
-
-		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 shuld be the same
-			this.inherited(arguments);
-			if(dojo.isMoz || dojo.isOpera){
-				this.connect(this.textbox, "oninput", this._onInput);
-			}else{
-				this.connect(this.textbox, "onkeydown", this._onInput);
-				this.connect(this.textbox, "onkeyup", this._onInput);
-				this.connect(this.textbox, "onpaste", this._onInput);
-				this.connect(this.textbox, "oncut", this._onInput);
-			}
-		},
-
-		_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 attr('value', ...)
-			//		and attr('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 = dojo.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);
-			}
-			if(this.selectOnClick && dojo.isMoz){
-				this.textbox.selectionStart = this.textbox.selectionEnd = undefined; // clear selection so that the next mouse click doesn't reselect
-			}
-
-		},
-
-		_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
-					var textIsNotSelected;
-					textIsNotSelected = this.textbox.selectionStart == this.textbox.selectionEnd;
-					if(textIsNotSelected){
-						this.selectInputText(this.textbox);
-					}
-				});
-			}
-
-			this._refreshState();
-			this.inherited(arguments);
-		},
-
-		reset: function(){
-			// Overrides dijit._FormWidget.reset().
-			// Additionally resets the displayed textbox value to ''
-			this.textbox.value = '';
-			this.inherited(arguments);
-		}
-	}
-);
\ No newline at end of file
+dojox.mobile.app.TextBox = dojox.mobile.TextBox;
\ No newline at end of file
diff --git a/dojox/mobile/app/_FormWidget.js b/dojox/mobile/app/_FormWidget.js
index 0dab50f..09ea3cd 100644
--- a/dojox/mobile/app/_FormWidget.js
+++ b/dojox/mobile/app/_FormWidget.js
@@ -4,6 +4,7 @@ dojo.experimental("dojox.mobile.app._FormWidget");
 dojo.require("dojo.window");
 
 dojo.require("dijit._WidgetBase");
+dojo.require("dijit.focus");	// dijit.focus()
 
 dojo.declare("dojox.mobile.app._FormWidget", dijit._WidgetBase, {
 	// summary:
diff --git a/dojox/mobile/app/_base.js b/dojox/mobile/app/_base.js
index f8b82c9..1fd3d97 100755
--- a/dojox/mobile/app/_base.js
+++ b/dojox/mobile/app/_base.js
@@ -5,6 +5,7 @@ dojo.require("dijit._base");
 dojo.require("dijit._WidgetBase");
 dojo.require("dojox.mobile");
 dojo.require("dojox.mobile.parser");
+dojo.require("dojox.mobile.Button");
 
 dojo.require("dojox.mobile.app._event");
 dojo.require("dojox.mobile.app._Widget");
@@ -52,9 +53,9 @@ dojo.require("dojox.mobile.app.ImageThumbView");
 			if (resource.source) {
 				url = resource.source;
 			}else if (resource.module) {
-				url = dojo.baseUrl + dojo._getModuleSymbols(resource.module).join("/") + '.js';
+				url= dojo.moduleUrl(resource.module)+".js";
 			}else {
-				alert("Error: invalid JavaScript resource " + dojo.toJson(resource));
+				console.log("Error: invalid JavaScript resource " + dojo.toJson(resource));
 				return;
 			}
 		}while (resources.length > 0 && loadedResources[url]);
@@ -78,7 +79,7 @@ dojo.require("dojox.mobile.app.ImageThumbView");
 			}
 		},
 		function(){
-			alert("Failed to load resource " + url);
+			console.log("Failed to load resource " + url);
 		});
 	}
 
diff --git a/dojox/mobile/app/_event.js b/dojox/mobile/app/_event.js
index c4f3074..330a0ae 100644
--- a/dojox/mobile/app/_event.js
+++ b/dojox/mobile/app/_event.js
@@ -111,10 +111,10 @@ dojo._connect = function(obj, event, context, method, dontFix){
 	if(event == "flick" || event == "onflick"){
 		if(dojo.global["Mojo"]){
 			event = Mojo.Event.flick;
-		}else{
+		} else{
 			return dojox.mobile.app.connectFlick(obj, context, method);
 		}
 	}
 
 	return dojo._oldConnect(obj, event, context, method, dontFix);
-}
\ No newline at end of file
+};
\ No newline at end of file
diff --git a/dojox/mobile/build/build.bat b/dojox/mobile/build/build.bat
index bb52fe2..adf5820 100755
--- a/dojox/mobile/build/build.bat
+++ b/dojox/mobile/build/build.bat
@@ -1,25 +1,6 @@
 @echo off
 
 rem Build script for dojox.mobile
-rem 
-rem Note:
-rem You may need to manually apply the following patch to your build script
-rem in order to completely remove all the unused modules from your build.
-rem The patch disables finding the dojo base modules being used from the
-rem dependent modules with a simple pattern matching, which sometimes
-rem unexpectedly picks up unused modules.
-rem For example, if you see query.js and NodeList.js baked into your build,
-rem while you are not using them, then it is worth trying the patch.
-rem The file to be patched is util/buildscripts/jslib/buildUtil.js.
-rem 
-rem --- buildUtil.js-orig
-rem +++ buildUtil.js
-rem @@ -1506,7 +1506,7 @@
-rem    var addedResources = {};
-rem -  while((matches = buildUtil.baseMappingRegExp.exec(tempContents))){
-rem +  while(false&&(matches = buildUtil.baseMappingRegExp.exec(tempContents))){
-rem        var baseResource = buildUtil.baseMappings[matches[1]];
-rem        //Make sure we do not add the dependency to its source resource.
 
 if "%1"=="separate" goto ok
 if "%1"=="single" goto ok
@@ -30,17 +11,23 @@ echo   webkit    Enable webkitMobile=true option (Loses PC browser support)
 goto end
 :ok
 
-set optimize=shrinksafe
+rem set optimize=shrinksafe
+set optimize=closure
 set profile=mobile
 set dir=release-mobile-separate
 set webkit=
-if "%1"=="single" set profile=mobile-all
-if "%1"=="single" set dir=release-mobile-single
-if "%2"=="webkit" set webkit=webkitMobile=true
+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 customDijitBase=true optimize=%optimize% layerOptimize=%optimize% cssOptimize=comments releaseDir=../../%dir%/ %webkit%
+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
 
 cd ..\..\dojox\mobile\build
 
diff --git a/dojox/mobile/build/build.sh b/dojox/mobile/build/build.sh
index 5f9d958..6ecb656 100755
--- a/dojox/mobile/build/build.sh
+++ b/dojox/mobile/build/build.sh
@@ -1,25 +1,6 @@
 #!/bin/sh
 
 # Build script for dojox.mobile
-# 
-# Note:
-# You may need to manually apply the following patch to your build script
-# in order to completely remove all the unused modules from your build.
-# The patch disables finding the dojo base modules being used from the
-# dependent modules with a simple pattern matching, which sometimes
-# unexpectedly picks up unused modules.
-# For example, if you see query.js and NodeList.js baked into your build,
-# while you are not using them, then it is worth trying the patch.
-# The file to be patched is util/buildscripts/jslib/buildUtil.js.
-# 
-# --- buildUtil.js-orig
-# +++ buildUtil.js
-# @@ -1506,7 +1506,7 @@
-#    var addedResources = {};
-# -  while((matches = buildUtil.baseMappingRegExp.exec(tempContents))){
-# +  while(false&&(matches = buildUtil.baseMappingRegExp.exec(tempContents))){
-#        var baseResource = buildUtil.baseMappings[matches[1]];
-#        //Make sure we do not add the dependency to its source resource.
 
 if [ $# -eq 0 ]; then
   echo 'Usage: build separate|single [webkit]'
@@ -29,22 +10,26 @@ if [ $# -eq 0 ]; then
   exit 1
 fi
 
-optimize=shrinksafe
+#optimize=shrinksafe
+optimize=closure
 profile=mobile
 dir=release-mobile-separate
 webkit=
+#standalone=standaloneScrollable=true
 if [ "$1" == "single" ]; then
   profile=mobile-all
 fi
 if [ "$1" == "single" ]; then
   dir=release-mobile-single
 fi
-if [ "$2" == "webkit" ]; then
+shift 1
+if [ "$1" == "webkit" ]; then
   webkit=webkitMobile=true
+  shift 1
 fi
 
 cd ../../../util/buildscripts
 
-./build.sh profile=$profile action=release customDijitBase=true optimize=$optimize layerOptimize=$optimize cssOptimize=comments releaseDir=../../$dir/ $webkit
+./build.sh profile=$profile action=release optimize=$optimize layerOptimize=$optimize cssOptimize=comments releaseDir=../../$dir/ $webkit $standalone $*
 
 cd ../../dojox/mobile/build
diff --git a/dojox/mobile/common.js b/dojox/mobile/common.js
new file mode 100644
index 0000000..f97a9d2
--- /dev/null
+++ b/dojox/mobile/common.js
@@ -0,0 +1,496 @@
+define([
+	"dojo/_base/kernel", // to test dojo.hash
+	"dojo/_base/array",
+	"dojo/_base/config",
+	"dojo/_base/connect",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+//	"dojo/hash", // optionally prereq'ed
+	"dojo/ready",
+	"dijit/registry",	// registry.toArray
+	"./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;
+=====*/
+
+	// 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.
+
+	dm.getScreenSize = function(){
+		// summary:
+		//		Returns the dimensions of the browser window.
+		return {
+			h: win.global.innerHeight || win.doc.documentElement.clientHeight,
+			w: win.global.innerWidth || win.doc.documentElement.clientWidth
+		};
+	};
+
+	dm.updateOrient = function(){
+		// summary:
+		//		Updates the orientation specific css classes, 'dj_portrait' and
+		//		'dj_landscape'.
+		var dim = dm.getScreenSize();
+		domClass.replace(win.doc.documentElement,
+				  dim.h > dim.w ? "dj_portrait" : "dj_landscape",
+				  dim.h > dim.w ? "dj_landscape" : "dj_portrait");
+	};
+	dm.updateOrient();
+
+	dm.tabletSize = 500;
+	dm.detectScreenSize = function(/*Boolean?*/force){
+		// 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'
+		var dim = dm.getScreenSize();
+		var sz = Math.min(dim.w, dim.h);
+		var from, to;
+		if(sz >= dm.tabletSize && (force || (!this._sz || this._sz < dm.tabletSize))){
+			from = "phone";
+			to = "tablet";
+		}else if(sz < dm.tabletSize && (force || (!this._sz || this._sz >= dm.tabletSize))){
+			from = "tablet";
+			to = "phone";
+		}
+		if(to){
+			domClass.replace(win.doc.documentElement, "dj_"+to, "dj_"+from);
+			connect.publish("/dojox/mobile/screenSize/"+to, [dim]);
+		}
+		this._sz = sz;
+	};
+	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
+	//		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){
+		// summary:
+		//		Internal function to hide the address bar.
+		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.resizeAll();
+			}
+		}
+		dm._h = h;
+	};
+
+	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
+		//		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.resizeAll = function(/*Event?*/evt, /*Widget?*/root){
+		// summary:
+		//		Call 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
+		//		resize() is its parent's responsibility.
+		// evt:
+		//		Native event object
+		// root:
+		//		If specified, search 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(dm.disableResizeAll){ return; }
+		connect.publish("/dojox/mobile/resizeAll", [evt, root]);
+		dm.updateOrient();
+		dm.detectScreenSize();
+		var isTopLevel = function(w){
+			var parent = w.getParent && w.getParent();
+			return !!((!parent || !parent.resize) && w.resize);
+		};
+		var resizeRecursively = function(w){
+			array.forEach(w.getChildren(), function(child){
+				if(isTopLevel(child)){ child.resize(); }
+				resizeRecursively(child);
+			});
+		};
+		if(root){
+			if(root.resize){ root.resize(); }
+			resizeRecursively(root);
+		}else{
+			array.forEach(array.filter(registry.toArray(), isTopLevel),
+					function(w){ w.resize(); });
+		}
+	};
+
+	dm.openWindow = function(url, target){
+		// summary:
+		//		Opens a new browser window with the given url.
+		win.global.open(url, target || "_blank");
+	};
+
+	dm.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(!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 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);
+			}
+			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");
+		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"
+				});
+			}
+		}
+		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.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");
+					}
+				}
+			}
+		});
+	}
+	
+	ready(function(){
+		dm.detectScreenSize(true);
+		if(config["mblApplyPageStyles"] !== false){
+			domClass.add(win.doc.documentElement, "mobile");
+		}
+		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(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 };
+		var f = dm.resizeAll;
+		if(config["mblHideAddressBar"] !== false &&
+			navigator.appVersion.indexOf("Mobile") != -1 ||
+			config["mblForceHideAddressBar"] === true){
+			dm.hideAddressBar();
+			if(config["mblAlwaysHideAddressBar"] === true){
+				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));
+				}
+				return arr;
+			};
+			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;
+						}
+					}
+					params = [ moveTo, dir, transition ];
+				}
+				view.performTransition.apply(view, params);
+				dm._params = null;
+			});
+		}
+	
+		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;
+	};
+
+	return dm;
+});
diff --git a/dojox/mobile/compat.js b/dojox/mobile/compat.js
index f7ef5bf..6d3ca38 100644
--- a/dojox/mobile/compat.js
+++ b/dojox/mobile/compat.js
@@ -1,469 +1,11 @@
-dojo.provide("dojox.mobile.compat");
-dojo.require("dijit._base.sniff");
-dojo.require("dojo._base.fx");
-dojo.require("dojo.fx");
-dojo.require("dojox.fx.flip");
-
-// summary:
-//		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.
-//
-//		dojo.require("dojox.mobile");
-//		dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-//
-//		This module also loads compatibility CSS files, which has -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.
-
-if(!dojo.isWebKit){
-
-dojo.extend(dojox.mobile.View, {
-	_doTransition: function(fromNode, toNode, transition, dir){
-		var anim;
-		this.wakeUp(toNode);
-		if(!transition || transition == "none"){
-			toNode.style.display = "";
-			fromNode.style.display = "none";
-			toNode.style.left = "0px";
-			this.invokeCallback();
-		}else if(transition == "slide"){
-			var w = fromNode.offsetWidth;
-			var s1 = dojo.fx.slideTo({
-				node: fromNode,
-				duration: 400,
-				left: -w*dir,
-				top: fromNode.offsetTop
-			});
-			var s2 = dojo.fx.slideTo({
-				node: toNode,
-				duration: 400,
-				left: 0
-			});
-			toNode.style.position = "absolute";
-			toNode.style.left = w*dir + "px";
-			toNode.style.display = "";
-			anim = dojo.fx.combine([s1,s2]);
-			dojo.connect(anim, "onEnd", this, function(){
-				fromNode.style.display = "none";
-				toNode.style.position = "relative";
-				this.invokeCallback();
-			});
-			anim.play();
-		}else if(transition == "flip"){
-			anim = dojox.fx.flip({
-				node: fromNode,
-				dir: "right",
-				depth: 0.5,
-				duration: 400
-			});
-			toNode.style.position = "absolute";
-			toNode.style.left = "0px";
-			dojo.connect(anim, "onEnd", this, function(){
-				fromNode.style.display = "none";
-				toNode.style.position = "relative";
-				toNode.style.display = "";
-				this.invokeCallback();
-			});
-			anim.play();
-		}else if(transition == "fade"){
-			anim = dojo.fx.chain([
-				dojo.fadeOut({
-					node: fromNode,
-					duration: 600
-				}),
-				dojo.fadeIn({
-					node: toNode,
-					duration: 600
-				})
-			]);
-			toNode.style.position = "absolute";
-			toNode.style.left = "0px";
-			toNode.style.display = "";
-			dojo.style(toNode, "opacity", 0);
-			dojo.connect(anim, "onEnd", this, function(){
-				fromNode.style.display = "none";
-				toNode.style.position = "relative";
-				dojo.style(fromNode, "opacity", 1);
-				this.invokeCallback();
-			});
-			anim.play();
-		}
-	},
-
-	wakeUp: function(node){
-		// summary:
-		//		Function to force IE to redraw a node since its layout code tends to misrender
-		//		in partial draws.
-		//	node:
-		//		The node to forcibly redraw.
-		// tags:
-		//		public
-		if(dojo.isIE && !node._wokeup){
-			node._wokeup = true;
-			var disp = node.style.display;
-			node.style.display = "";
-			var nodes = node.getElementsByTagName("*");
-			for(var i = 0, len = nodes.length; i < len; i++){
-				var val = nodes[i].style.display;
-				nodes[i].style.display = "none";
-				nodes[i].style.display = "";
-				nodes[i].style.display = val;
-			}
-			node.style.display = disp;
-		}
+define([
+	"dojo/_base/lang",
+	"dojo/_base/sniff"
+], function(lang, has){
+	var dm = lang.getObject("dojox.mobile", true);
+	if(!has("webkit")){
+		var s = "dojox/mobile/_compat"; // assign to a variable so as not to be picked up by the build tool
+		require([s]);
 	}
+	return dm;
 });
-
-dojo.extend(dojox.mobile.Switch, {
-	buildRendering: function(){
-		// summary:
-		//		Function to simulate the mobile device style switches on
-		//		browsers such as IE and FireFox.
-		// tags:
-		//		protected
-		this.domNode = this.srcNodeRef || dojo.doc.createElement("DIV");
-		this.domNode.className = "mblSwitch";
-		this.domNode.innerHTML =
-			  '<div class="mblSwitchInner">'
-			+	'<div class="mblSwitchBg mblSwitchBgLeft">'
-			+		'<div class="mblSwitchCorner mblSwitchCorner1T"></div>'
-			+		'<div class="mblSwitchCorner mblSwitchCorner2T"></div>'
-			+		'<div class="mblSwitchCorner mblSwitchCorner3T"></div>'
-			+		'<div class="mblSwitchText mblSwitchTextLeft">'+this.leftLabel+'</div>'
-			+		'<div class="mblSwitchCorner mblSwitchCorner1B"></div>'
-			+		'<div class="mblSwitchCorner mblSwitchCorner2B"></div>'
-			+		'<div class="mblSwitchCorner mblSwitchCorner3B"></div>'
-			+	'</div>'
-			+	'<div class="mblSwitchBg mblSwitchBgRight">'
-			+		'<div class="mblSwitchCorner mblSwitchCorner1T"></div>'
-			+		'<div class="mblSwitchCorner mblSwitchCorner2T"></div>'
-			+		'<div class="mblSwitchCorner mblSwitchCorner3T"></div>'
-			+		'<div class="mblSwitchText mblSwitchTextRight">'+this.rightLabel+'</div>'
-			+		'<div class="mblSwitchCorner mblSwitchCorner1B"></div>'
-			+		'<div class="mblSwitchCorner mblSwitchCorner2B"></div>'
-			+		'<div class="mblSwitchCorner mblSwitchCorner3B"></div>'
-			+	'</div>'
-			+	'<div class="mblSwitchKnobContainer">'
-			+		'<div class="mblSwitchCorner mblSwitchCorner1T"></div>'
-			+		'<div class="mblSwitchCorner mblSwitchCorner2T"></div>'
-			+		'<div class="mblSwitchCorner mblSwitchCorner3T"></div>'
-			+		'<div class="mblSwitchKnob"></div>'
-			+		'<div class="mblSwitchCorner mblSwitchCorner1B"></div>'
-			+		'<div class="mblSwitchCorner mblSwitchCorner2B"></div>'
-			+		'<div class="mblSwitchCorner mblSwitchCorner3B"></div>'
-			+	'</div>'
-			+ '</div>';
-		var n = this.inner = this.domNode.firstChild;
-		this.left = n.childNodes[0];
-		this.right = n.childNodes[1];
-		this.knob = n.childNodes[2];
-
-		dojo.addClass(this.domNode, (this.value == "on") ? "mblSwitchOn" : "mblSwitchOff");
-		this[this.value == "off" ? "left" : "right"].style.display = "none";
-	},
-
-	_changeState: function(/*String*/state){
-		// summary:
-		//		Function to toggle the switch state on the switch
-		// state:
-		//		Thhe state to toggle, switch 'on' or 'off'
-		// tags:
-		//		private
-		if(!this.inner.parentNode || !this.inner.parentNode.tagName){
-			dojo.addClass(this.domNode, (state == "on") ? "mblSwitchOn" : "mblSwitchOff");
-			return;
-		}
-		var pos;
-		if(this.inner.offsetLeft == 0){ // currently ON
-			if(state == "on"){ return; }
-			pos = -53;
-		}else{ // currently OFF
-			if(state == "off"){ return; }
-			pos = 0;
-		}
-
-		var a = dojo.fx.slideTo({
-			node: this.inner,
-			duration: 500,
-			left: pos
-		});
-		var _this = this;
-		dojo.connect(a, "onEnd", function(){
-			_this[state == "off" ? "left" : "right"].style.display = "none";
-		});
-		a.play();
-	}
-});
-
-if(dojo.isIE || dojo.isBB){
-
-dojo.extend(dojox.mobile.RoundRect, {
-	buildRendering: function(){
-		// summary:
-		//		Function to simulate the borderRadius appearance on IE, since
-		//		IE does not support this CSS style.
-		// tags:
-		//		protected
-		dojox.mobile.createRoundRect(this);
-		this.domNode.className = "mblRoundRect";
-	}
-});
-
-dojox.mobile.RoundRectList._addChild = dojox.mobile.RoundRectList.prototype.addChild;
-dojo.extend(dojox.mobile.RoundRectList, {
-	buildRendering: function(){
-		// summary:
-		//		Function to simulate the borderRadius appearance on IE, since
-		//		IE does not support this CSS style.
-		// tags:
-		//		protected
-		dojox.mobile.createRoundRect(this, true);
-		this.domNode.className = "mblRoundRectList";
-	},
-
-	postCreate: function(){
-		this.redrawBorders();
-	},
-
-	addChild: function(widget){
-		dojox.mobile.RoundRectList._addChild.apply(this, arguments);
-		this.redrawBorders();
-		if(dojox.mobile.applyPngFilter){
-			dojox.mobile.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.
-
-		var lastChildFound = false;
-		for(var i = this.containerNode.childNodes.length - 1; i >= 0; i--){
-			var c = this.containerNode.childNodes[i];
-			if(c.tagName == "LI"){
-				c.style.borderBottomStyle = lastChildFound ? "solid" : "none";
-				lastChildFound = true;
-			}
-		}
-	}
-});
-
-dojo.extend(dojox.mobile.EdgeToEdgeList, {
-	buildRendering: function(){
-		this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("UL");
-		this.domNode.className = "mblEdgeToEdgeList";
-	}
-});
-
-if(dojox.mobile.IconContainer){
-
-dojox.mobile.IconContainer._addChild = dojox.mobile.IconContainer.prototype.addChild;
-dojo.extend(dojox.mobile.IconContainer, {
-	addChild: function(widget){
-		dojox.mobile.IconContainer._addChild.apply(this, arguments);
-		if(dojox.mobile.applyPngFilter){
-			dojox.mobile.applyPngFilter(widget.domNode);
-		}
-	}
-});
-
-} // if(dojox.mobile.IconContainer)
-
-dojo.mixin(dojox.mobile, {
-	createRoundRect: function(_this, isList){
-		// summary:
-		//		Function to adjust the creation of rounded rectangles on IE.
-		//		Deals with IE's lack of borderRadius support
-		// tags:
-		//		public
-		var i;
-		_this.domNode = dojo.doc.createElement("DIV");
-		_this.domNode.style.padding = "0px";
-		_this.domNode.style.backgroundColor = "transparent";
-		_this.domNode.style.borderStyle = "none";
-		_this.containerNode = dojo.doc.createElement(isList?"UL":"DIV");
-		_this.containerNode.className = "mblRoundRectContainer";
-		if(_this.srcNodeRef){
-			_this.srcNodeRef.parentNode.replaceChild(_this.domNode, _this.srcNodeRef);
-			for(i = 0, len = _this.srcNodeRef.childNodes.length; i < len; i++){
-				_this.containerNode.appendChild(_this.srcNodeRef.removeChild(_this.srcNodeRef.firstChild));
-			}
-			_this.srcNodeRef = null;
-		}
-		_this.domNode.appendChild(_this.containerNode);
-
-		for(i = 0; i <= 5; i++){
-			var top = dojo.create("DIV");
-			top.className = "mblRoundCorner mblRoundCorner"+i+"T";
-			_this.domNode.insertBefore(top, _this.containerNode);
-
-			var bottom = dojo.create("DIV");
-			bottom.className = "mblRoundCorner mblRoundCorner"+i+"B";
-			_this.domNode.appendChild(bottom);
-		}
-	}
-});
-
-if(dojox.mobile.ScrollableView){
-
-dojo.extend(dojox.mobile.ScrollableView, {
-	postCreate: function(){
-		// 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 = dojo.create("DIV", {className:"mblDummyForIE", innerHTML:" "}, this.containerNode, "first");
-		dojo.style(dummy, {
-			position: "relative",
-			marginBottom: "-2px",
-			fontSize: "1px"
-		});
-	}
-});
-
-} // if(dojox.mobile.ScrollableView)
-
-} // if(dojo.isIE)
-
-if(dojo.isIE <= 6){
-	dojox.mobile.applyPngFilter = function(root){
-		root = root || dojo.body();
-		var nodes = root.getElementsByTagName("IMG");
-		var blank = dojo.moduleUrl("dojo", "resources/blank.gif");
-		for(var i = 0, len = nodes.length; i < len; i++){
-			var img = nodes[i];
-			var w = img.offsetWidth;
-			var h = img.offsetHeight;
-			if(w === 0 || h === 0){
-				// The reason why the image has no width/height may be because
-				// display is "none". If that is the case, let's change the
-				// display to "" temporarily and see if the image returns them.
-				if(dojo.style(img, "display") != "none"){ continue; }
-				img.style.display = "";
-				w = img.offsetWidth;
-				h = img.offsetHeight;
-				img.style.display = "none";
-				if(w === 0 || h === 0){ continue; }
-			}
-			var src = img.src;
-			if(src.indexOf("resources/blank.gif") != -1){ continue; }
-			img.src = blank;
-			img.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src+"')";
-			img.style.width = w + "px";
-			img.style.height = h + "px";
-		}
-	};
-} // if(dojo.isIE <= 6)
-
-dojox.mobile.loadCss = function(/*String|Array*/files){
-	// summary:
-	//		Function to load and register CSS files with the page
-	//	files: String|Array
-	//		The CSS files to load and register with the page.
-	// tags:
-	//		private
-	if(!dojo.global._loadedCss){
-		var obj = {};
-		dojo.forEach(dojox.mobile.getCssPaths(), function(path){
-			obj[path] = true;
-		});
-		dojo.global._loadedCss = obj;
-	}
-	if(!dojo.isArray(files)){ files = [files]; }
-	for(var i = 0; i < files.length; i++){
-		var file = files[i];
-		if(!dojo.global._loadedCss[file]){
-			dojo.global._loadedCss[file] = true;
-			if(dojo.doc.createStyleSheet){
-				// for some reason, IE hangs when you try to load
-				// multiple css files almost at once.
-				setTimeout(function(file){
-					return function(){
-						dojo.doc.createStyleSheet(file);
-					};
-				}(file), 0);
-			}else{
-				var link = dojo.doc.createElement("link");
-				link.href = file;
-				link.type = "text/css";
-				link.rel = "stylesheet";
-				var head = dojo.doc.getElementsByTagName('head')[0];
-				head.appendChild(link);
-			}
-		}
-	}
-};
-
-dojox.mobile.getCssPaths = function(){
-	var paths = [];
-	var i, j;
-
-	// find @import
-	var s = dojo.doc.styleSheets;
-	for(i = 0; i < s.length; i++){
-		var r = s[i].cssRules || s[i].imports;
-		if(!r){ continue; }
-		for(j = 0; j < r.length; j++){
-			if(r[j].href){
-				paths.push(r[j].href);
-			}
-		}
-	}
-	
-	// find <link>
-	var elems = dojo.doc.getElementsByTagName("link");
-	for(i = 0, len = elems.length; i < len; i++){
-		if(elems[i].href){
-			paths.push(elems[i].href);
-		}
-	}
-	return paths;
-};
-
-dojox.mobile.loadCompatPattern = /\/themes\/(domButtons|buttons|iphone|android).*\.css$/;
-
-dojox.mobile.loadCompatCssFiles = function(){
-	// summary:
-	//		Function to perform page-level adjustments on browsers such as
-	//		IE and firefox.  It loads compat specific css files into the
-	//		page header.
-	var paths = dojox.mobile.getCssPaths();
-	for(var i = 0; i < paths.length; i++){
-		var href = paths[i];
-		if(href.match(dojox.mobile.loadCompatPattern) && href.indexOf("-compat.css") == -1){
-			var compatCss = href.substring(0, href.length-4)+"-compat.css";
-			dojox.mobile.loadCss(compatCss);
-		}
-	}
-};
-
-dojox.mobile.hideAddressBar = function(){
-	// nop
-};
-
-dojo.addOnLoad(function(){
-	if(dojo.config["mblLoadCompatCssFiles"] !== false){
-		dojox.mobile.loadCompatCssFiles();
-	}
-	if(dojox.mobile.applyPngFilter){
-		dojox.mobile.applyPngFilter();
-	}
-});
-
-} // end of if(!dojo.isWebKit){
diff --git a/dojox/mobile/deviceTheme.js b/dojox/mobile/deviceTheme.js
new file mode 100644
index 0000000..75d7258
--- /dev/null
+++ b/dojox/mobile/deviceTheme.js
@@ -0,0 +1,188 @@
+define([
+	"dojo/_base/array",
+	"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
+=====*/
+
+	// 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",
+			[]
+		]
+	];
+
+	dm.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"];
+		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();
+				}
+				break;
+			}
+		}
+	};
+	
+	if(dm.configDeviceTheme){
+		dm.configDeviceTheme();
+	}
+	dm.loadDeviceTheme();
+
+	return dm;
+});
diff --git a/dojox/mobile/i18n.js b/dojox/mobile/i18n.js
new file mode 100644
index 0000000..ae7ca52
--- /dev/null
+++ b/dojox/mobile/i18n.js
@@ -0,0 +1,46 @@
+define([
+	"dojo/_base/lang",
+	"dojo/i18n",
+	"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;
+=====*/
+
+	i18n.load = function(/*String*/packageName, /*String*/bundleName, /*String?*/locale){
+		// summary:
+		//		Loads an nls resouce 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
+		//		it.
+		if(!i18n.bundle){ i18n.bundle = []; }
+		return lang.mixin(i18n.bundle, bundle);
+	};
+
+	lang.extend(WidgetBase, {
+		mblNoConv: false,
+		_cv: function(s){
+			if(this.mblNoConv || !i18n.bundle){ return s; }
+			return i18n.bundle[lang.trim(s)] || s;
+		}
+	});
+
+	return i18n;
+});
diff --git a/dojox/mobile/mobile-all.js b/dojox/mobile/mobile-all.js
new file mode 100644
index 0000000..24684bf
--- /dev/null
+++ b/dojox/mobile/mobile-all.js
@@ -0,0 +1,47 @@
+define([
+	"./_base",
+	"./compat",
+	"./Button",
+	"./Carousel",
+	"./CheckBox",
+	"./ComboBox",
+	"./ContentPane",
+	"./EdgeToEdgeDataList",
+	"./ExpandingTextArea",
+	"./FixedSplitter",
+	"./FixedSplitterPane",
+	"./FlippableView",
+	"./IconContainer",
+	"./IconItem",
+	"./Opener",
+	"./Overlay",
+	"./PageIndicator",
+	"./RadioButton",
+	"./RoundRectDataList",
+	"./ScrollableView",
+	"./Slider",
+	"./SpinWheel",
+	"./SpinWheelDatePicker",
+	"./SpinWheelSlot",
+	"./SpinWheelTimePicker",
+	"./SwapView",
+	"./Switch",
+	"./TabBar",
+	"./TabBarButton",
+	"./TextArea",
+	"./TextBox",
+	"./ToggleButton",
+	"./Tooltip",
+	"./transition",
+	"./TransitionEvent",
+	"./ViewController"
+], 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.");
+
+	return common;
+});
diff --git a/dojox/mobile/parser.js b/dojox/mobile/parser.js
index a9da7bd..7128f4d 100644
--- a/dojox/mobile/parser.js
+++ b/dojox/mobile/parser.js
@@ -1,85 +1,113 @@
-dojo.provide("dojox.mobile.parser");
-dojo.provide("dojo.parser"); // not to load dojo.parser unexpectedly
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/config",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/ready"
+], function(dojo, config, lang, win, ready){
 
-dojox.mobile.parser = new function(){
-	this.instantiate = function(list, defaultParams){
+	// module:
+	//		dojox/mobile/parser
+	// summary:
+	//		A lightweight parser.
+
+	var dm = lang.getObject("dojox.mobile", true);
+
+	var parser = new function(){
 		// summary:
-		//		Function for instantiating a list of widget nodes.
-		// list:
-		//		The list of DOMNodes to walk and instantiate widgets on.
-		var ws = [];
-		if(list){
-			var i, len;
-			len = list.length;
-			for(i = 0; i < len; i++){
-				var node = list[i];
-				var cls = dojo.getObject(dojo.attr(node, "dojoType"));
-				var proto = cls.prototype;
-				var params = {};
+		//		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.
 
-				if(defaultParams){
-					for(var name in defaultParams){
-						params[name] = defaultParams[name];
+		this.instantiate = function(/* Array */nodes, /* Object? */mixin, /* Object? */args){
+			// summary:
+			//		Function for instantiating a list of widget nodes.
+			// nodes:
+			//		The list of DOMNodes to walk and instantiate widgets on.
+			mixin = mixin || {};
+			args = args || {};
+			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);
+					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"){
+							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] = eval("(" + v + ")");
+						}
 					}
-				}
-				for(var prop in proto){
-					var val = dojo.attr(node, prop);
-					if(!val){ continue; }
-					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 + ")");
+					params["class"] = n.className;
+					params.style = n.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);
+					ws.push(instance);
+					var jsId = n.getAttribute("jsId") || n.getAttribute("data-dojo-id");
+					if(jsId){
+						lang.setObject(jsId, instance);
 					}
 				}
-				params["class"] = node.className;
-				params["style"] = node.style && node.style.cssText;
-				var instance = new cls(params, node);
-				ws.push(instance);
-				var jsId = node.getAttribute("jsId");
-				if(jsId){
-					dojo.setObject(jsId, instance);
+				for(i = 0; i < ws.length; i++){
+					var w = ws[i];
+					!args.noStart && w.startup && !w._started && w.startup();
 				}
 			}
-			len = ws.length;
-			for(i = 0; i < len; i++){
-				var w = ws[i];
-				w.startup && !w._started && (!w.getParent || !w.getParent()) && w.startup();
-			}
-		}
-		return ws;
-	};
+			return ws;
+		};
 
-	this.parse = function(rootNode, defaultParams){
-		// summary:
-		//		Function to handle parsing for widgets in the current document.
-		//		It is not as powerful as the full dojo parser, but it will handle basic
-		//		use cases fine.
-		// rootNode:
-		//		The root node in the document to parse from
-		if(!rootNode){
-			rootNode = dojo.body();
-		}else if(!defaultParams && rootNode.rootNode){
-			// Case where 'rootNode' is really a params object.
-			rootNode = rootNode.rootNode;
- 		}
+		this.parse = function(rootNode, args){
+			// 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
+			//		use cases fine.
+			// rootNode:
+			//		The root node in the document to parse from
+			if(!rootNode){
+				rootNode = win.body();
+			}else if(!args && rootNode.rootNode){
+				// Case where 'rootNode' is really a params object.
+				args = rootNode;
+				rootNode = rootNode.rootNode;
+			}
 
-		var nodes = rootNode.getElementsByTagName("*");
-		var list = [];
-		for(var i = 0, len = nodes.length; i < len; i++){
-			if(nodes[i].getAttribute("dojoType")){
-				list.push(nodes[i]);
+			var nodes = rootNode.getElementsByTagName("*");
+			var i, list = [];
+			for(i = 0; i < nodes.length; i++){
+				var n = nodes[i];
+				if(n.getAttribute("dojoType") || n.getAttribute("data-dojo-type")){
+					list.push(n);
+				}
 			}
-		}
-		return this.instantiate(list, defaultParams);
-	};
-}();
-dojo._loaders.unshift(function(){
-	if(dojo.config.parseOnLoad){
-		dojox.mobile.parser.parse();
+			var mixin = args && args.template ? {template: true} : null;
+			return this.instantiate(list, mixin, args);
+		};
+	}();
+	if(config.parseOnLoad){
+		ready(100, parser, "parse");
 	}
+	dm.parser = parser; // for backward compatibility
+	dojo.parser = parser; // in case user application calls dojo.parser
+	return parser;
 });
-
diff --git a/dojox/mobile/scrollable.js b/dojox/mobile/scrollable.js
index 36f7b45..cd1d0de 100644
--- a/dojox/mobile/scrollable.js
+++ b/dojox/mobile/scrollable.js
@@ -1,3 +1,147 @@
+//>>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",
+	"dojo/_base/event",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+	"./sniff"
+], function(dojo, connect, event, lang, win, domClass, domConstruct, domStyle, has){
+
+	var dm = lang.getObject("dojox.mobile", true);
+
 /*=====
 // summary:
 //		Utility for enabling touch scrolling capability.
@@ -28,44 +172,38 @@
 //		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 excludeStart and excludeEnd directives
-//		so that they will be excluded from the build.
+//		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();
+//		| 	var scrollable = new dojox.mobile.scrollable(dojo, dojox);
 //		| 	scrollable.init({
 //		| 		domNode: "outer", // id or node
-//		| 		containerNode: "inner", // id or node
-//		| 		fixedHeaderHeight: document.getElementById("hd1").offsetHeight
+//		| 		containerNode: "inner" // id or node
 //		| 	});
 //		| }
 //		| <body onload="onLoad()">
-//		| 	<h1 id="hd1" style="position:absolute;width:100%;z-index:1;">
+//		| 	<h1 id="hd1" style="position:relative;width:100%;z-index:1;">
 //		| 		Fixed Header
 //		| 	</h1>
-//		| 	<div id="outer" style="height:100%;overflow:hidden;">
+//		| 	<div id="outer" style="position:relative;height:100%;overflow:hidden;">
 //		| 		<div id="inner" style="position:absolute;width:100%;">
 //		| 			... content ...
 //		| 		</div>
 //		| 	</div>
 //		| </body>
-//
 =====*/
 
-if(typeof dojo != "undefined" && dojo.provide){
-	dojo.provide("dojox.mobile.scrollable");
-}else{
-	dojo = {doc:document, global:window, isWebKit:navigator.userAgent.indexOf("WebKit") != -1};
-	dojox = {mobile:{}};
-}
-
-dojox.mobile.scrollable = function(){
+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)
@@ -74,134 +212,313 @@ dojox.mobile.scrollable = function(){
 	this.weight = 0.6; // frictional drag
 	this.fadeScrollBar = true;
 	this.disableFlashScrollBar = false;
-	this.threshold = 0; // drag threshold value in pixels
-
-//>>excludeStart("dojo", true);
-	if(!dojo.version){ // seems running in a non-dojo environment
-		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);
-			}
-		};
-		dojo.create = function(tag, attrs, refNode){
-			return refNode.appendChild(dojo.doc.createElement(tag));
-		};
-		dojo.stopEvent = function(evt){
-			if(evt.preventDefault){
-				evt.preventDefault();
-				evt.stopPropagation();
-			}else{
-				evt.cancelBubble = true;
-			}
-			return false;
-		};
-		dojo.style = function(node, style){
-			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.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, "");
-		};
+	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;
 	}
-//>>excludeEnd("dojo");
+//>>includeEnd("standaloneScrollable");
 
 	this.init = function(/*Object?*/params){
-		if (params){
+		if(params){
 			for(var p in params){
-				if (params.hasOwnProperty(p)) {
+				if(params.hasOwnProperty(p)){
 					this[p] = ((p == "domNode" || p == "containerNode") && typeof params[p] == "string") ?
-						dojo.doc.getElementById(params[p]) : params[p]; // mix-in params
+						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(dojo.connect(this.containerNode,
-			dojox.mobile.hasTouch ? "touchstart" : "onmousedown", this, "onTouchStart"));
-		if(dojo.isWebKit){
-			this._ch.push(dojo.connect(this.domNode, "webkitAnimationEnd", this, "onFlickAnimationEnd"));
-			this._ch.push(dojo.connect(this.domNode, "webkitAnimationStart", this, "onFlickAnimationStart"));
-		}
+		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"));
 
-		if(dojo.global.onorientationchange !== undefined){
-			this._ch.push(dojo.connect(dojo.global, "onorientationchange", this, "resizeView"));
-		}else{
-			this._ch.push(dojo.connect(dojo.global, "onresize", this, "resizeView"));
+			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();
+			}
+
+			// 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();
 		}
-		this.resizeView();
 		var _this = this;
 		setTimeout(function(){
 			_this.flashScrollBar();
 		}, 600);
 	};
 
+	this.isTopLevel = function(){
+		// subclass may want to override
+		return true;
+	};
+
 	this.cleanup = function(){
-		for(var i = 0; i < this._ch.length; i++){
-			dojo.disconnect(this._ch[i]);
+		if(this._ch){
+			for(var i = 0; i < this._ch.length; i++){
+				connect.disconnect(this._ch[i]);
+			}
+			this._ch = null;
 		}
-		this._ch = null;
 	};
 
-	this.resizeView = function(e){
+	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;
+	};
+
+	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
+		};
+	};
+
+	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;
+	};
+
+	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();
+		}
+	};
+
+	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());
+	};
+
+	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;
+	};
+
+	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;
-		this.containerNode.style.paddingTop = this.fixedHeaderHeight + "px";
+		if(this.isLocalHeader){
+			this.containerNode.style.marginTop = this.fixedHeaderHeight + "px";
+		}
 
-		// has to wait a little for completion of hideAddressBar()
-		var c = 0;
-		var _this = this;
-		var id = setInterval(function() {
-			// adjust the height of this view a couple of times
-			_this.domNode.style.height = (dojo.global.innerHeight||dojo.doc.documentElement.clientHeight) - _this._appFooterHeight + "px";
-			_this.resetScrollBar();
-			if(c++ >= 4) { clearInterval(id); }
-		}, 300);
+		// 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;
+		}
+
+		// 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;
+				}
+			}
+			// 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.onFlickAnimationStart = function(e){
-		dojo.stopEvent(e);
+		event.stop(e);
 	};
 
 	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 = ""; }
+			}
+			return;
+		}
 		if(e && e.srcElement){
-			dojo.stopEvent(e);
+			event.stop(e);
 		}
 		this.stopAnimation();
 		if(this._bounce){
@@ -214,23 +531,36 @@ dojox.mobile.scrollable = function(){
 		}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");
+	};
+
 	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(dojo.connect(dojo.doc, dojox.mobile.hasTouch ? "touchmove" : "onmousemove", this, "onTouchMove"));
-			this._conn.push(dojo.connect(dojo.doc, dojox.mobile.hasTouch ? "touchend" : "onmouseup", this, "onTouchEnd"));
+			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"));
 		}
 
 		this._aborted = false;
-		if(dojo.hasClass(this.containerNode, "mblScrollableScrollTo2")){
+		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();
@@ -239,13 +569,15 @@ dojox.mobile.scrollable = function(){
 		this._time = [0];
 		this._posX = [this.touchStartX];
 		this._posY = [this.touchStartY];
+		this._locked = false;
 
-		if(e.target.nodeType != 1 || (e.target.tagName != "SELECT" && e.target.tagName != "INPUT" && e.target.tagName != "TEXTAREA")){
-			dojo.stopEvent(e);
+		if(!this.isFormElement(e.target) && !this.isNested){
+			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;
@@ -253,14 +585,26 @@ dojox.mobile.scrollable = function(){
 		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(dx < this.threshold && dy < this.threshold){ return; }
+			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 && Math.abs(dy) < this.threshold ||
+				(this._h || this._f) && Math.abs(dx) < this.threshold){
+				return;
+			}
 			this.addCover();
 			this.showScrollBar();
 		}
 
 		var weight = this.weight;
-		if(this._v){
+		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
@@ -271,7 +615,7 @@ dojox.mobile.scrollable = function(){
 				}
 			}
 		}
-		if(this._h || this._f){
+		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){
@@ -316,49 +660,55 @@ dojox.mobile.scrollable = function(){
 	};
 
 	this.onTouchEnd = function(e){
-		if(!this._conn){ return; } // if we get onTouchEnd without onTouchStart, ignore it.
-		for(var i = 0; i < this._conn.length; i++){
-			dojo.disconnect(this._conn[i]);
-		}
-		this._conn = null;
-
-		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){
-				clicked = true;
+		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]);
 			}
-		}
-		if(clicked){ // clicked, not dragged or flicked
-			this.hideScrollBar();
-			this.removeCover();
-			if(dojox.mobile.hasTouch){
-				var elem = e.target;
-				if(elem.nodeType != 1){
-					elem = elem.parentNode;
+			this._conn = null;
+	
+			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()
+					clicked = true;
 				}
-				var ev = dojo.doc.createEvent("MouseEvents");
-				ev.initEvent("click", true, true);
-				elem.dispatchEvent(ev);
 			}
-			return;
-		}
-		var speed = {x:0, y:0};
-		// 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];
-			speed.y = this.calcSpeed(dy, dt);
-			speed.x = this.calcSpeed(dx, dt);
+			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;
+					}
+					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;
+			}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();
 		}
 
-		var pos = this.getPos();
-		var to = {}; // destination
-		var dim = this._dim;
-
 		if(this._v){
 			to.y = pos.y + speed.y;
 		}
@@ -366,20 +716,22 @@ dojox.mobile.scrollable = function(){
 			to.x = pos.x + speed.x;
 		}
 
-		if(this.scrollDir == "v" && dim.c.h <= dim.d.h){ // content is shorter than display
+		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
+		}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){
+		}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){
+		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;
@@ -400,7 +752,7 @@ dojox.mobile.scrollable = function(){
 				}
 			}
 		}
-		if(this._h || this._f){
+		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;
@@ -435,11 +787,16 @@ dojox.mobile.scrollable = function(){
 				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();
@@ -448,7 +805,10 @@ dojox.mobile.scrollable = function(){
 
 	this.stopAnimation = function(){
 		// stop the currently running animation
-		dojo.removeClass(this.containerNode, "mblScrollableScrollTo2");
+		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 = "";
 		}
@@ -457,13 +817,28 @@ dojox.mobile.scrollable = function(){
 		}
 	};
 
+	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){ // to: {x, y}
-		var s = this.containerNode.style;
-		if(dojo.isWebKit){
+	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){
@@ -479,6 +854,8 @@ dojox.mobile.scrollable = function(){
 	};
 
 	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);
 	};
@@ -486,29 +863,32 @@ dojox.mobile.scrollable = function(){
 	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 dojox.mobile.hasTranslate3d ?
+		return dm.hasTranslate3d ?
 				"translate3d("+x+","+y+",0px)" : "translate("+x+","+y+")";
 	};
 
 	this.getPos = function(){
 		// summary:
 		//		Get the top position in the midst of animation
-		if(dojo.isWebKit){
-			var m = dojo.doc.defaultView.getComputedStyle(this.containerNode, '')["-webkit-transform"];
+		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{
-			return {y:this.containerNode.offsetTop, x:this.containerNode.offsetLeft};
+			// 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 - this.fixedHeaderHeight, w:this.containerNode.offsetWidth};
+		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};
@@ -532,7 +912,7 @@ dojox.mobile.scrollable = function(){
 		var createBar = function(self, dir){
 			var bar = self["_scrollBarNode" + dir];
 			if(!bar){
-				var wrapper = dojo.create("div", null, self.domNode);
+				var wrapper = domConstruct.create("div", null, self.domNode);
 				var props = { position: "absolute", overflow: "hidden" };
 				if(dir == "V"){
 					props.right = "2px";
@@ -541,12 +921,12 @@ dojox.mobile.scrollable = function(){
 					props.bottom = (self.isLocalFooter ? self.fixedFooterHeight : 0) + 2 + "px";
 					props.height = "5px";
 				}
-				dojo.style(wrapper, props);
+				domStyle.set(wrapper, props);
 				wrapper.className = "mblScrollBarWrapper";
 				self["_scrollBarWrapper"+dir] = wrapper;
 
-				bar = dojo.create("div", null, wrapper);
-				dojo.style(bar, {
+				bar = domConstruct.create("div", null, wrapper);
+				domStyle.set(bar, {
 					opacity: 0.6,
 					position: "absolute",
 					backgroundColor: "#606060",
@@ -556,7 +936,7 @@ dojox.mobile.scrollable = function(){
 					webkitTransformOrigin: "0 0",
 					zIndex: 2147483647 // max of signed 32-bit integer
 				});
-				dojo.style(bar, dir == "V" ? {width: "5px"} : {height: "5px"});
+				domStyle.set(bar, dir == "V" ? {width: "5px"} : {height: "5px"});
 				self["_scrollBarNode" + dir] = bar;
 			}
 			return bar;
@@ -572,35 +952,38 @@ dojox.mobile.scrollable = function(){
 
 	this.hideScrollBar = function(){
 		var fadeRule;
-		if(this.fadeScrollBar && dojo.isWebKit){
-			if(!dojox.mobile._fadeRule){
-				var node = dojo.create("style", null, dojo.doc.getElementsByTagName("head")[0]);
+		if(this.fadeScrollBar && has("webkit")){
+			if(!dm._fadeRule){
+				var node = domConstruct.create("style", null, win.doc.getElementsByTagName("head")[0]);
 				node.textContent =
-					".mblScrollableFadeOutScrollBar{"+
+					".mblScrollableFadeScrollBar{"+
 					"  -webkit-animation-duration: 1s;"+
-					"  -webkit-animation-name: scrollableViewFadeOutScrollBar;}"+
-					"@-webkit-keyframes scrollableViewFadeOutScrollBar{"+
+					"  -webkit-animation-name: scrollableViewFadeScrollBar;}"+
+					"@-webkit-keyframes scrollableViewFadeScrollBar{"+
 					"  from { opacity: 0.6; }"+
-					"  50% { opacity: 0.6; }"+
 					"  to { opacity: 0; }}";
-				dojox.mobile._fadeRule = node.sheet.cssRules[1];
+				dm._fadeRule = node.sheet.cssRules[1];
 			}
-			fadeRule = dojox.mobile._fadeRule;
+			fadeRule = dm._fadeRule;
 		}
 		if(!this.scrollBar){ return; }
-		var f = function(bar){
-			dojo.style(bar, {
+		var f = function(bar, self){
+			domStyle.set(bar, {
 				opacity: 0,
 				webkitAnimationDuration: ""
 			});
-			bar.className = "mblScrollableFadeOutScrollBar";
+			if(self._aw){ // android workaround
+				bar.style.webkitTransform = "";
+			}else{
+				bar.className = "mblScrollableFadeScrollBar";
+			}
 		};
 		if(this._scrollBarV){
-			f(this._scrollBarV);
+			f(this._scrollBarV, this);
 			this._scrollBarV = null;
 		}
 		if(this._scrollBarH){
-			f(this._scrollBarH);
+			f(this._scrollBarH, this);
 			this._scrollBarH = null;
 		}
 	};
@@ -630,14 +1013,14 @@ dojox.mobile.scrollable = function(){
 	this.scrollScrollBarTo = function(/*Object*/to){ // to: {x, y}
 		if(!this.scrollBar){ return; }
 		if(this._v && this._scrollBarV && typeof to.y == "number"){
-			if(dojo.isWebKit){
+			if(has("webkit")){
 				this._scrollBarV.style.webkitTransform = this.makeTranslateStr({y:to.y});
 			}else{
 				this._scrollBarV.style.top = to.y + "px";
 			}
 		}
 		if(this._h && this._scrollBarH && typeof to.x == "number"){
-			if(dojo.isWebKit){
+			if(has("webkit")){
 				this._scrollBarH.style.webkitTransform = this.makeTranslateStr({x:to.x});
 			}else{
 				this._scrollBarH.style.left = to.x + "px";
@@ -659,20 +1042,20 @@ dojox.mobile.scrollable = function(){
 
 	this._runSlideAnimation = function(/*Object*/from, /*Object*/to, /*Number*/duration, /*String*/easing, node, idx){
 		// idx: 0:scrollbarV, 1:scrollbarH, 2:content
-		if(dojo.isWebKit){
+		if(has("webkit")){
 			this.setKeyframes(from, to, idx);
-			dojo.style(node, {
+			domStyle.set(node, {
 				webkitAnimationDuration: duration + "s",
 				webkitAnimationTimingFunction: easing
 			});
-			dojo.addClass(node, "mblScrollableScrollTo"+idx);
+			domClass.add(node, "mblScrollableScrollTo"+idx);
 			if(idx == 2){
-				this.scrollTo(to, true);
+				this.scrollTo(to, true, node);
 			}else{
 				this.scrollScrollBarTo(to);
 			}
 //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		}else if(dojo.fx && dojo.fx.easing){
+		}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:
 			//
@@ -688,12 +1071,12 @@ dojox.mobile.scrollable = function(){
 				easing: (easing == "ease-out") ? dojo.fx.easing.quadOut : dojo.fx.easing.linear
 			}).play();
 			if(idx == 2){
-				dojo.connect(s, "onEnd", this, "onFlickAnimationEnd");
+				connect.connect(s, "onEnd", this, "onFlickAnimationEnd");
 			}
 		}else{
 			// directly jump to the destination without animation
 			if(idx == 2){
-				this.scrollTo(to);
+				this.scrollTo(to, false, node);
 				this.onFlickAnimationEnd();
 			}else{
 				this.scrollScrollBarTo(to);
@@ -709,12 +1092,13 @@ dojox.mobile.scrollable = function(){
 			if(!bar){ return; }
 			var props = {};
 			props[v ? "top" : "left"] = hd + 4 + "px"; // +4 is for top or left margin
-			props[v ? "height" : "width"] = d - 8 + "px";
-			dojo.style(wrapper, props);
+			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), d - 8); // -8 is for margin for both ends
+			l = Math.min(Math.max(l - 8, 5), t); // -8 is for margin for both ends
 			bar.style[v ? "height" : "width"] = l + "px";
-			dojo.style(bar, {"opacity": 0.6});
+			domStyle.set(bar, {"opacity": 0.6});
 		};
 		var dim = this.getDim();
 		f(this._scrollBarWrapperV, this._scrollBarV, dim.d.h, dim.c.h, this.fixedHeaderHeight, true);
@@ -729,11 +1113,11 @@ dojox.mobile.scrollable = function(){
 		//		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(!dojo.isWebKit){ return; }
+		if(!has("webkit")){ return; }
 		var ctx;
 		if(this._scrollBarWrapperV){
 			var h = this._scrollBarWrapperV.offsetHeight;
-			ctx = dojo.doc.getCSSCanvasContext("2d", "scrollBarMaskV", 5, h);
+			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);
@@ -745,7 +1129,7 @@ dojox.mobile.scrollable = function(){
 		}
 		if(this._scrollBarWrapperH){
 			var w = this._scrollBarWrapperH.offsetWidth;
-			ctx = dojo.doc.getCSSCanvasContext("2d", "scrollBarMaskH", w, 5);
+			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);
@@ -758,7 +1142,7 @@ dojox.mobile.scrollable = function(){
 	};
 
 	this.flashScrollBar = function(){
-		if(this.disableFlashScrollBar){ return; }
+		if(this.disableFlashScrollBar || !this.domNode){ return; }
 		this._dim = this.getDim();
 		if(this._dim.d.h <= 0){ return; } // dom is not ready
 		this.showScrollBar();
@@ -770,10 +1154,10 @@ dojox.mobile.scrollable = function(){
 
 	this.addCover = function(){
 //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		if(!dojox.mobile.hasTouch && !this.noCover){
+		if(!has('touch') && !this.noCover){
 			if(!this._cover){
-				this._cover = dojo.create("div", null, dojo.doc.body);
-				dojo.style(this._cover, {
+				this._cover = domConstruct.create("div", null, win.doc.body);
+				domStyle.set(this._cover, {
 					backgroundColor: "#ffff00",
 					opacity: 0,
 					position: "absolute",
@@ -783,47 +1167,40 @@ dojox.mobile.scrollable = function(){
 					height: "100%",
 					zIndex: 2147483647 // max of signed 32-bit integer
 				});
-				this._ch.push(dojo.connect(this._cover,
-					dojox.mobile.hasTouch ? "touchstart" : "onmousedown", this, "onTouchEnd"));
+				this._ch.push(connect.connect(this._cover,
+					has('touch') ? "touchstart" : "onmousedown", this, "onTouchEnd"));
 			}else{
 				this._cover.style.display = "";
 			}
+			this.setSelectable(this._cover, false);
+			this.setSelectable(this.domNode, false);
 		}
 //>>excludeEnd("webkitMobile");
-		this.setSelectable(this.domNode, false);
-		var sel;
-		if(dojo.global.getSelection){
-			sel = dojo.global.getSelection();
-			sel.collapse(dojo.doc.body, 0);
-		}else{
-			sel = dojo.doc.selection.createRange();
-			sel.setEndPoint("EndToStart", sel);
-			sel.select();
-		}
 	};
 
 	this.removeCover = function(){
 //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		if(!dojox.mobile.hasTouch && this._cover){
+		if(!has('touch') && this._cover){
 			this._cover.style.display = "none";
+			this.setSelectable(this._cover, true);
+			this.setSelectable(this.domNode, true);
 		}
 //>>excludeEnd("webkitMobile");
-		this.setSelectable(this.domNode, true);
 	};
 
 	this.setKeyframes = function(/*Object*/from, /*Object*/to, /*Number*/idx){
-		if(!dojox.mobile._rule){
-			dojox.mobile._rule = [];
+		if(!dm._rule){
+			dm._rule = [];
 		}
 		// idx: 0:scrollbarV, 1:scrollbarH, 2:content
-		if(!dojox.mobile._rule[idx]){
-            var node = dojo.create("style", null, dojo.doc.getElementsByTagName("head")[0]);
-            node.textContent =
+		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+"{}";
-			dojox.mobile._rule[idx] = node.sheet.cssRules[1];
+			dm._rule[idx] = node.sheet.cssRules[1];
 		}
-		var rule = dojox.mobile._rule[idx];
+		var rule = dm._rule[idx];
 		if(rule){
 			if(from){
 				rule.deleteRule("from");
@@ -843,22 +1220,29 @@ dojox.mobile.scrollable = function(){
 		node.style.KhtmlUserSelect = selectable ? "auto" : "none";
 		node.style.MozUserSelect = selectable ? "" : "none";
 		node.onselectstart = selectable ? null : function(){return false;};
-		node.unselectable = selectable ? "" : "on";
+		if(has("ie")){
+			node.unselectable = selectable ? "" : "on";
+			var nodes = node.getElementsByTagName("*");
+			for(var i = 0; i < nodes.length; i++){
+				nodes[i].unselectable = selectable ? "" : "on";
+			}
+		}
 	};
 
-};
-
-(function(){
 	// feature detection
-	if(dojo.isWebKit){
-		var elem = dojo.doc.createElement("div");
+	if(has("webkit")){
+		var elem = win.doc.createElement("div");
 		elem.style.webkitTransform = "translate3d(0px,1px,0px)";
-		dojo.doc.documentElement.appendChild(elem);
-		var v = dojo.doc.defaultView.getComputedStyle(elem, '')["-webkit-transform"];
-		dojox.mobile.hasTranslate3d = v && v.indexOf("matrix") === 0;
-		dojo.doc.documentElement.removeChild(elem);
-	
-		dojox.mobile.hasTouch = (typeof dojo.doc.documentElement.ontouchstart != "undefined" &&
-			navigator.appVersion.indexOf("Mobile") != -1);
+		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;
+});
diff --git a/dojox/mobile/sniff.js b/dojox/mobile/sniff.js
new file mode 100644
index 0000000..9fa269d
--- /dev/null
+++ b/dojox/mobile/sniff.js
@@ -0,0 +1,31 @@
+define([
+	"dojo/_base/window",
+	"dojo/_base/sniff"
+], function(win, 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);
+	}
+
+	return has;
+});
diff --git a/dojox/mobile/tests/carousel-categ.json b/dojox/mobile/tests/carousel-categ.json
new file mode 100644
index 0000000..c2320db
--- /dev/null
+++ b/dojox/mobile/tests/carousel-categ.json
@@ -0,0 +1,8 @@
+{
+	items: [
+		{src:"images/dish1.jpg", value:"dish", headerText:"dish"},
+		{src:"images/glass1.jpg", value:"glass", headerText:"glass"},
+		{src:"images/stone1.jpg", value:"stone", headerText:"stone"},
+		{src:"images/shell1.jpg", value:"shell", headerText:"shell"}
+	]
+}
diff --git a/dojox/mobile/tests/carousel-dish.json b/dojox/mobile/tests/carousel-dish.json
new file mode 100644
index 0000000..2f968ef
--- /dev/null
+++ b/dojox/mobile/tests/carousel-dish.json
@@ -0,0 +1,13 @@
+{
+	items: [
+		{src:"images/dish1.jpg", design:"Mifune", model: "1392", produced: "1968", size: "H5.5cm D11cm", price: "6,300yen"},
+		{src:"images/dish2.jpg", design:"Mifune", model: "Cera S", produced: "1960", size: "H4cm D17.8cm", price: "(sold)"},
+		{src:"images/dish3.jpg", design:"Mifune", model: "92-a7", produced: "1977", size: "H12cm D12cm", price: "13,000yen"},
+		{src:"images/dish4.jpg", design:"Mifune", model: "2387", produced: "1967", size: "H6.7cm D9.2cm", price: "5,200yen"},
+		{src:"images/dish5.jpg", design:"Mifune", model: "1388", produced: "1970", size: "25cm", price: "3,500yen"},
+		{src:"images/dish6.jpg", design:"Mifune", model: "GO3", produced: "1960'", size: "H14cm D9cm", price: "8,800yen"},
+		{src:"images/dish7.jpg", design:"Mifune", model: "92-n8", produced: "1978", size: "H10.5cm D9cm", price: "10,300yen"},
+		{src:"images/dish8.jpg", design:"Mifune", model: "3382", produced: "1966", size: "H8cm D9cm", price: "4,000yen"},
+		{src:"images/dish9.jpg", design:"Mifune", model: "FC 13a", produced: "1973", size: "D17cm", price: "(sold)"}
+	]
+}
diff --git a/dojox/mobile/tests/carousel-glass.json b/dojox/mobile/tests/carousel-glass.json
new file mode 100644
index 0000000..941a69f
--- /dev/null
+++ b/dojox/mobile/tests/carousel-glass.json
@@ -0,0 +1,20 @@
+{
+	items: [
+		{src:"images/glass1.jpg", design:"Scott", model: "5659", produced: "2011", size: "H3.5cm W4cm", price: "300yen"},
+		{src:"images/glass2.jpg", design:"Scott", model: "5659", produced: "2011", size: "H3.5cm W4cm", price: "100yen"},
+		{src:"images/glass3.jpg", design:"Scott", model: "5659", produced: "2011", size: "H3.5cm W4cm", price: "250yen"},
+		{src:"images/glass4.jpg", design:"Scott", model: "5659", produced: "2011", size: "H3.5cm W4cm", price: "400yen"},
+		{src:"images/glass5.jpg", design:"Scott", model: "5659", produced: "2011", size: "H3.5cm W4cm", price: "240yen"},
+		{src:"images/glass6.jpg", design:"Scott", model: "5659", produced: "2011", size: "H3.5cm W4cm", price: "150yen"},
+		{src:"images/glass7.jpg", design:"Scott", model: "5659", produced: "2011", size: "H3.5cm W4cm", price: "220yen"},
+		{src:"images/glass8.jpg", design:"Scott", model: "5659", produced: "2011", size: "H3.5cm W4cm", price: "310yen"},
+		{src:"images/glass9.jpg", design:"Scott", model: "5659", produced: "2011", size: "H3.5cm W4cm", price: "90yen"},
+		{src:"images/glass10.jpg", design:"Scott", model: "5659", produced: "2011", size: "H3.5cm W4cm", price: "360yen"},
+		{src:"images/glass11.jpg", design:"Scott", model: "5659", produced: "2011", size: "H3.5cm W4cm", price: "370yen"},
+		{src:"images/glass12.jpg", design:"Scott", model: "5659", produced: "2011", size: "H3.5cm W4cm", price: "280yen"},
+		{src:"images/glass13.jpg", design:"Scott", model: "5659", produced: "2011", size: "H3.5cm W4cm", price: "190yen"},
+		{src:"images/glass14.jpg", design:"Scott", model: "5659", produced: "2011", size: "H3.5cm W4cm", price: "200yen"},
+		{src:"images/glass15.jpg", design:"Scott", model: "5659", produced: "2011", size: "H3.5cm W4cm", price: "700yen"},
+		{src:"images/glass16.jpg", design:"Scott", model: "5659", produced: "2011", size: "H3.5cm W4cm", price: "800yen"}
+	]
+}
diff --git a/dojox/mobile/tests/carousel-shell.json b/dojox/mobile/tests/carousel-shell.json
new file mode 100644
index 0000000..8bf2e6b
--- /dev/null
+++ b/dojox/mobile/tests/carousel-shell.json
@@ -0,0 +1,15 @@
+{
+	items: [
+		{src:"images/shell1.jpg", design:"Lion", model: "984", produced: "1990'", size: "H3.5cm W4cm", price: "3,300yen"},
+		{src:"images/shell2.jpg", design:"Lion", model: "984", produced: "1990'", size: "H3.5cm W4cm", price: "2,800yen"},
+		{src:"images/shell3.jpg", design:"Lion", model: "984", produced: "1990'", size: "H3.5cm W4cm", price: "1,800yen"},
+		{src:"images/shell4.jpg", design:"Lion", model: "984", produced: "1990'", size: "H3.5cm W4cm", price: "800yen"},
+		{src:"images/shell5.jpg", design:"Lion", model: "984", produced: "1990'", size: "H3.5cm W4cm", price: "100yen"},
+		{src:"images/shell6.jpg", design:"Lion", model: "984", produced: "1990'", size: "H3.5cm W4cm", price: "4,800yen"},
+		{src:"images/shell7.jpg", design:"Lion", model: "984", produced: "1990'", size: "H3.5cm W4cm", price: "10yen"},
+		{src:"images/shell8.jpg", design:"Lion", model: "984", produced: "1990'", size: "H3.5cm W4cm", price: "5yen"},
+		{src:"images/shell9.jpg", design:"Lion", model: "984", produced: "1990'", size: "H3.5cm W4cm", price: "20yen"},
+		{src:"images/shell10.jpg", design:"Lion", model: "984", produced: "1990'", size: "H3.5cm W4cm", price: "2,600yen"},
+		{src:"images/shell11.jpg", design:"Lion", model: "984", produced: "1990'", size: "H3.5cm W4cm", price: "1,200yen"}
+	]
+}
diff --git a/dojox/mobile/tests/carousel-stone.json b/dojox/mobile/tests/carousel-stone.json
new file mode 100644
index 0000000..131ca42
--- /dev/null
+++ b/dojox/mobile/tests/carousel-stone.json
@@ -0,0 +1,14 @@
+{
+	items: [
+		{src:"images/stone1.jpg", design:"Tiger", model: "DX167", produced: "2000'", size: "H3.5cm W4cm", price: "7,000yen"},
+		{src:"images/stone2.jpg", design:"Tiger", model: "DX167", produced: "2000'", size: "H3.5cm W4cm", price: "3,000yen"},
+		{src:"images/stone3.jpg", design:"Tiger", model: "DX167", produced: "2000'", size: "H3.5cm W4cm", price: "4,000yen"},
+		{src:"images/stone4.jpg", design:"Tiger", model: "DX167", produced: "2000'", size: "H3.5cm W4cm", price: "800yen"},
+		{src:"images/stone5.jpg", design:"Tiger", model: "DX167", produced: "2000'", size: "H3.5cm W4cm", price: "1,200yen"},
+		{src:"images/stone6.jpg", design:"Tiger", model: "DX167", produced: "2000'", size: "H3.5cm W4cm", price: "2,000yen"},
+		{src:"images/stone7.jpg", design:"Tiger", model: "DX167", produced: "2000'", size: "H3.5cm W4cm", price: "100yen"},
+		{src:"images/stone8.jpg", design:"Tiger", model: "DX167", produced: "2000'", size: "H3.5cm W4cm", price: "3,000yen"},
+		{src:"images/stone9.jpg", design:"Tiger", model: "DX167", produced: "2000'", size: "H3.5cm W4cm", price: "12,000yen"},
+		{src:"images/stone10.jpg", design:"Tiger", model: "DX167", produced: "2000'", size: "H3.5cm W4cm", price: "10yen"}
+	]
+}
diff --git a/dojox/mobile/tests/complexListApp/app/assistants/main-assistant.js b/dojox/mobile/tests/complexListApp/app/assistants/main-assistant.js
index fc73483..ef3fb06 100644
--- a/dojox/mobile/tests/complexListApp/app/assistants/main-assistant.js
+++ b/dojox/mobile/tests/complexListApp/app/assistants/main-assistant.js
@@ -1,4 +1,3 @@
-dojo.provide("MainAssistant");
 dojo.require("dojox.mobile.app.SceneAssistant");
 
 dojo.declare("MainAssistant", dojox.mobile.app.SceneAssistant, {
diff --git a/dojox/mobile/tests/complexListApp/index.html b/dojox/mobile/tests/complexListApp/index.html
index f766c4c..2447e0c 100644
--- a/dojox/mobile/tests/complexListApp/index.html
+++ b/dojox/mobile/tests/complexListApp/index.html
@@ -14,21 +14,17 @@
 		</style>
 		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: false"></script>
     
-    <!-- 
-      Include the files directly, as some mobile operating systems do not
-      allow synchronous XHR, and therefore break dojo.require
-    -->
-		<script type="text/javascript" src="../../../mobile/app.js"></script>
 		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojox.mobile.app");
 			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.app.compat");
       
-      var appInfo = {
-        id: "org.dojo.simpleApp",
-        title: "Mobile App With Complex List",
-        initialScene: "main"
-      };
-      
-      dojo.ready(dojox.mobile.app.init);
+			  var appInfo = {
+				id: "org.dojo.simpleApp",
+				title: "Mobile App With Complex List",
+				initialScene: "main"
+			  };
+
+			  dojo.ready(dojox.mobile.app.init);
 		</script>
 	</head>
 	<body>
diff --git a/dojox/mobile/tests/dialogApp/app/assistants/main-assistant.js b/dojox/mobile/tests/dialogApp/app/assistants/main-assistant.js
index 392276a..2d587b8 100644
--- a/dojox/mobile/tests/dialogApp/app/assistants/main-assistant.js
+++ b/dojox/mobile/tests/dialogApp/app/assistants/main-assistant.js
@@ -1,4 +1,3 @@
-dojo.provide("MainAssistant");
 dojo.require("dojox.mobile.app.SceneAssistant");
 
 dojo.declare("MainAssistant", dojox.mobile.app.SceneAssistant, {
diff --git a/dojox/mobile/tests/dialogApp/app/views/main/main-scene.html b/dojox/mobile/tests/dialogApp/app/views/main/main-scene.html
index d192973..1ae155e 100644
--- a/dojox/mobile/tests/dialogApp/app/views/main/main-scene.html
+++ b/dojox/mobile/tests/dialogApp/app/views/main/main-scene.html
@@ -6,5 +6,5 @@
 <pre class="appInfoArea"></pre>
 
 
-<button id="btn1" dojoType="dojox.mobile.Button">Dialog 1</button>
-<button id="btn2" dojoType="dojox.mobile.Button" btnClass="mblRedButton">Dialog 2</button>
+<button id="btn1" dojoType="dojox.mobile.Button" class="mblBlueButton">Dialog 1</button>
+<button id="btn2" dojoType="dojox.mobile.Button" class="mblRedButton">Dialog 2</button>
diff --git a/dojox/mobile/tests/dialogApp/index.html b/dojox/mobile/tests/dialogApp/index.html
index 0b13f64..4b4fc90 100644
--- a/dojox/mobile/tests/dialogApp/index.html
+++ b/dojox/mobile/tests/dialogApp/index.html
@@ -14,12 +14,8 @@
 		</style>
 		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: false"></script>
     
-    <!-- 
-      Include the files directly, as some mobile operating systems do not
-      allow synchronous XHR, and therefore break dojo.require
-    -->
-		<script type="text/javascript" src="../../../mobile/app.js"></script>
 		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojox.mobile.app");
 			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.app.compat");
       
             var appInfo = {
diff --git a/dojox/mobile/tests/doh/Button.html b/dojox/mobile/tests/doh/Button.html
new file mode 100644
index 0000000..3259830
--- /dev/null
+++ b/dojox/mobile/tests/doh/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" 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
new file mode 100644
index 0000000..20b4c5a
--- /dev/null
+++ b/dojox/mobile/tests/doh/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" 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
new file mode 100644
index 0000000..72f0b9d
--- /dev/null
+++ b/dojox/mobile/tests/doh/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", 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
new file mode 100644
index 0000000..153ed5c
--- /dev/null
+++ b/dojox/mobile/tests/doh/CreateListItem_Programmatic.js
@@ -0,0 +1,50 @@
+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/EdgeToEdgeCatagory.js b/dojox/mobile/tests/doh/EdgeToEdgeCatagory.js
new file mode 100644
index 0000000..5e22ade
--- /dev/null
+++ b/dojox/mobile/tests/doh/EdgeToEdgeCatagory.js
@@ -0,0 +1,71 @@
+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
new file mode 100644
index 0000000..0c02ea4
--- /dev/null
+++ b/dojox/mobile/tests/doh/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" 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
new file mode 100644
index 0000000..3eb6635
--- /dev/null
+++ b/dojox/mobile/tests/doh/EdgeToEdgeDataList.html
@@ -0,0 +1,155 @@
+<!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
new file mode 100644
index 0000000..1e50f44
--- /dev/null
+++ b/dojox/mobile/tests/doh/EdgeToEdgeDataList_Programmatic.html
@@ -0,0 +1,157 @@
+<!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/Heading.html b/dojox/mobile/tests/doh/Heading.html
new file mode 100644
index 0000000..7b15059
--- /dev/null
+++ b/dojox/mobile/tests/doh/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" 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
new file mode 100644
index 0000000..966ac43
--- /dev/null
+++ b/dojox/mobile/tests/doh/Heading2.html
@@ -0,0 +1,166 @@
+<!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
new file mode 100644
index 0000000..3a9e1d3
--- /dev/null
+++ b/dojox/mobile/tests/doh/Heading2_Programmatic.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>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/Heading_Programmatic.html b/dojox/mobile/tests/doh/Heading_Programmatic.html
new file mode 100644
index 0000000..fc15805
--- /dev/null
+++ b/dojox/mobile/tests/doh/Heading_Programmatic.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>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
new file mode 100644
index 0000000..eea0299
--- /dev/null
+++ b/dojox/mobile/tests/doh/IconContainer.html
@@ -0,0 +1,151 @@
+<!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
new file mode 100644
index 0000000..035d491
--- /dev/null
+++ b/dojox/mobile/tests/doh/IconContainer2.html
@@ -0,0 +1,120 @@
+<!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
new file mode 100644
index 0000000..5016fca
--- /dev/null
+++ b/dojox/mobile/tests/doh/IconContainer3.html
@@ -0,0 +1,125 @@
+<!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/IconContainer_Programmatic.html b/dojox/mobile/tests/doh/IconContainer_Programmatic.html
new file mode 100644
index 0000000..e8e235e
--- /dev/null
+++ b/dojox/mobile/tests/doh/IconContainer_Programmatic.html
@@ -0,0 +1,148 @@
+<!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/ListItem.html b/dojox/mobile/tests/doh/ListItem.html
new file mode 100644
index 0000000..cb5798a
--- /dev/null
+++ b/dojox/mobile/tests/doh/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" 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
new file mode 100644
index 0000000..dd2611d
--- /dev/null
+++ b/dojox/mobile/tests/doh/ListItem.js
@@ -0,0 +1,113 @@
+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
new file mode 100644
index 0000000..e06ea75
--- /dev/null
+++ b/dojox/mobile/tests/doh/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" 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
new file mode 100644
index 0000000..5aeee8d
--- /dev/null
+++ b/dojox/mobile/tests/doh/ListItem2.js
@@ -0,0 +1,44 @@
+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
new file mode 100644
index 0000000..7bb8ce5
--- /dev/null
+++ b/dojox/mobile/tests/doh/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" 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
new file mode 100644
index 0000000..05b6828
--- /dev/null
+++ b/dojox/mobile/tests/doh/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" 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/RoundRect.html b/dojox/mobile/tests/doh/RoundRect.html
new file mode 100644
index 0000000..ece544c
--- /dev/null
+++ b/dojox/mobile/tests/doh/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" 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
new file mode 100644
index 0000000..f8a6fb6
--- /dev/null
+++ b/dojox/mobile/tests/doh/RoundRectDataList.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"></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.js b/dojox/mobile/tests/doh/RoundRectDataList.js
new file mode 100644
index 0000000..dac4483
--- /dev/null
+++ b/dojox/mobile/tests/doh/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_Programmatic.html b/dojox/mobile/tests/doh/RoundRectDataList_Programmatic.html
new file mode 100644
index 0000000..5068448
--- /dev/null
+++ b/dojox/mobile/tests/doh/RoundRectDataList_Programmatic.html
@@ -0,0 +1,77 @@
+<!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
new file mode 100644
index 0000000..78e8610
--- /dev/null
+++ b/dojox/mobile/tests/doh/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" 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
new file mode 100644
index 0000000..099b1f9
--- /dev/null
+++ b/dojox/mobile/tests/doh/RoundRectList.js
@@ -0,0 +1,71 @@
+
+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
new file mode 100644
index 0000000..9f98e04
--- /dev/null
+++ b/dojox/mobile/tests/doh/RoundRectList_Programmatic.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>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
new file mode 100644
index 0000000..fee850e
--- /dev/null
+++ b/dojox/mobile/tests/doh/RoundRect_Programmatic.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>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
new file mode 100644
index 0000000..c52b661
--- /dev/null
+++ b/dojox/mobile/tests/doh/Switch.html
@@ -0,0 +1,143 @@
+<!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
new file mode 100644
index 0000000..e97f757
--- /dev/null
+++ b/dojox/mobile/tests/doh/Switch_Programmatic.html
@@ -0,0 +1,126 @@
+<!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
new file mode 100644
index 0000000..4772fee
--- /dev/null
+++ b/dojox/mobile/tests/doh/TabBar.html
@@ -0,0 +1,143 @@
+<!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
new file mode 100644
index 0000000..527dfbc
--- /dev/null
+++ b/dojox/mobile/tests/doh/TabBar_Programmatic.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>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/TestUtil.js b/dojox/mobile/tests/doh/TestUtil.js
new file mode 100644
index 0000000..de560ba
--- /dev/null
+++ b/dojox/mobile/tests/doh/TestUtil.js
@@ -0,0 +1,83 @@
+dojo.require("doh.runner");
+
+function fireOnClick(obj){
+	var anchorNode;
+	if(typeof obj === "string"){
+		var demoWidget = dijit.byId(obj);
+		anchorNode = demoWidget.anchorNode;
+	}else{
+		anchorNode = obj;
+	}
+	if(dojo.isIE<9){
+		anchorNode.fireEvent( "onclick" );
+	}else{
+		var e = document.createEvent('Events');
+		e.initEvent('click', true, true);
+		anchorNode.dispatchEvent(e);
+	}
+}
+
+
+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);
+	
+	doh.assertEqual('A', childNodes[0].tagName);
+	
+	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());
+		}
+		doh.assertEqual('mblListItemIcon', childNodes[i++].className);
+	}
+
+	if(hasRightIcon){
+		if(domButtonType){
+			doh.assertEqual(domButtonType + ' mblDomButton', childNodes[i].childNodes[0].className);
+		}
+		doh.assertEqual('mblListItemRightIcon', childNodes[i++].className);
+	}
+
+	if(hasIcon2){
+		doh.assertEqual('mblListItemRightIcon2', childNodes[i++].className);
+	}
+
+	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('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,"")));
+	} catch (e) {
+		if(dojo.isFF ==3.6){
+			doh.assertEqual(text, dojo.trim(childNodes[i].childNodes[0].childNodes[0].innerHTML.replace(/\r\n/g,"")));
+		}else{
+			throw e;
+		}
+	}
+
+}
+
+function verifyListItemPos(id, rTop, rRight, rBottom, rLeft, sTop, sLeft) {
+	var demoWidget = dijit.byId(id);
+	verifyRect(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0], 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);
+}
+
+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]);
+}
diff --git a/dojox/mobile/tests/doh/ToolBarButton.html b/dojox/mobile/tests/doh/ToolBarButton.html
new file mode 100644
index 0000000..8b85abc
--- /dev/null
+++ b/dojox/mobile/tests/doh/ToolBarButton.html
@@ -0,0 +1,89 @@
+<!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
new file mode 100644
index 0000000..0de8cf2
--- /dev/null
+++ b/dojox/mobile/tests/doh/ToolBarButton.js
@@ -0,0 +1,93 @@
+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
new file mode 100644
index 0000000..4b3538c
--- /dev/null
+++ b/dojox/mobile/tests/doh/ToolBarButton_Programmatic.html
@@ -0,0 +1,195 @@
+<!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
new file mode 100644
index 0000000..e0a8e46
--- /dev/null
+++ b/dojox/mobile/tests/doh/View-demo.html
@@ -0,0 +1,821 @@
+<!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
new file mode 100644
index 0000000..c7c0153
--- /dev/null
+++ b/dojox/mobile/tests/doh/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" 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
new file mode 100644
index 0000000..9650c8f
--- /dev/null
+++ b/dojox/mobile/tests/doh/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" 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
new file mode 100644
index 0000000..f0406b3
--- /dev/null
+++ b/dojox/mobile/tests/doh/View3_Programmatic.html
@@ -0,0 +1,139 @@
+<!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
new file mode 100644
index 0000000..36b7007
--- /dev/null
+++ b/dojox/mobile/tests/doh/View_Programmatic.html
@@ -0,0 +1,139 @@
+<!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/index.html b/dojox/mobile/tests/doh/index.html
new file mode 100644
index 0000000..bb4ce30
--- /dev/null
+++ b/dojox/mobile/tests/doh/index.html
@@ -0,0 +1,47 @@
+<!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="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>
+		<hr>
+		<a href="runTests.html">runTests.html</a><br>
+	
+
+</body></html>
\ No newline at end of file
diff --git a/dojox/mobile/tests/doh/module.js b/dojox/mobile/tests/doh/module.js
new file mode 100644
index 0000000..3a70a77
--- /dev/null
+++ b/dojox/mobile/tests/doh/module.js
@@ -0,0 +1,42 @@
+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);
+}
+
+
diff --git a/dojox/mobile/tests/doh/progress-indicator.html b/dojox/mobile/tests/doh/progress-indicator.html
new file mode 100644
index 0000000..4ddf277
--- /dev/null
+++ b/dojox/mobile/tests/doh/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" 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/runTests.html b/dojox/mobile/tests/doh/runTests.html
new file mode 100644
index 0000000..a6613ea
--- /dev/null
+++ b/dojox/mobile/tests/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.doh.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/settings.json b/dojox/mobile/tests/doh/settings.json
new file mode 100644
index 0000000..7d53b60
--- /dev/null
+++ b/dojox/mobile/tests/doh/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/topHeading_defect.html b/dojox/mobile/tests/doh/topHeading_defect.html
new file mode 100644
index 0000000..96037e6
--- /dev/null
+++ b/dojox/mobile/tests/doh/topHeading_defect.html
@@ -0,0 +1,60 @@
+<!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/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>
+	</head>
+	<body>
+		<div id="general" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="foo">General</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/fragment1.html b/dojox/mobile/tests/fragment1.html
new file mode 100644
index 0000000..927b871
--- /dev/null
+++ b/dojox/mobile/tests/fragment1.html
@@ -0,0 +1,3 @@
+<div dojoType="dojox.mobile.RoundRect" shadow="true">
+  HTML fragment example
+</div>
diff --git a/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-image-thumb-view-assistant.js b/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-image-thumb-view-assistant.js
index e558124..3fbdcda 100644
--- a/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-image-thumb-view-assistant.js
+++ b/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-image-thumb-view-assistant.js
@@ -1,4 +1,3 @@
-dojo.provide("FlickrImageThumbViewAssistant");
 dojo.require("dojox.mobile.app.SceneAssistant");
 
 dojo.declare("FlickrImageThumbViewAssistant", dojox.mobile.app.SceneAssistant, {
@@ -44,13 +43,13 @@ dojo.declare("FlickrImageThumbViewAssistant", dojox.mobile.app.SceneAssistant, {
 			}
 		});
 
-		this.connect(dijit.byId("btnSmall"), "onClick", function(event){
+		this.connect(dijit.byId("btnSmall"), "onClick", function(){
 			_this.setThumbSize("small");
 		});
-		this.connect(dijit.byId("btnMedium"), "onClick", function(event){
+		this.connect(dijit.byId("btnMedium"), "onClick", function(){
 			_this.setThumbSize("medium");
 		});
-		this.connect(dijit.byId("btnLarge"), "onClick", function(event){
+		this.connect(dijit.byId("btnLarge"), "onClick", function(){
 			_this.setThumbSize("large");
 		});
 
@@ -59,7 +58,7 @@ dojo.declare("FlickrImageThumbViewAssistant", dojox.mobile.app.SceneAssistant, {
 		// the thumbnails fill the horizontal space
 		// This is fairly pointless for mobile, but makes it work
 		// better in desktop browsers
-		this.connect(window, "resize", function(event){
+		this.connect(window, "resize", function(){
 			if(resizeTimer){
 				clearTimeout(resizeTimer);
 			}
@@ -137,7 +136,6 @@ dojo.declare("FlickrImageThumbViewAssistant", dojox.mobile.app.SceneAssistant, {
 
 	loadInteresting: function(){
 		console.log("loading interesting");
-		var _this = this;
 
 		var url = "http://api.flickr.com/services/rest/?method=" +
 					"flickr.interestingness.getList";
@@ -156,7 +154,6 @@ dojo.declare("FlickrImageThumbViewAssistant", dojox.mobile.app.SceneAssistant, {
 
 	loadText: function(text){
 		console.log("loading text ", text);
-		var _this = this;
 
 		var url = "http://api.flickr.com/services/rest/?method=" +
 					"flickr.photos.search";
@@ -177,7 +174,6 @@ dojo.declare("FlickrImageThumbViewAssistant", dojox.mobile.app.SceneAssistant, {
 
 	loadTags: function(text){
 		console.log("loading tags ", text);
-		var _this = this;
 
 		var url = "http://api.flickr.com/services/rest/?method=" +
 					"flickr.photos.search";
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 8287f03..23ec791 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
@@ -1,4 +1,3 @@
-dojo.provide("FlickrImageViewAssistant");
 dojo.require("dojox.mobile.app.SceneAssistant");
 
 dojo.declare("FlickrImageViewAssistant", dojox.mobile.app.SceneAssistant, {
@@ -27,8 +26,6 @@ dojo.declare("FlickrImageViewAssistant", dojox.mobile.app.SceneAssistant, {
 			}
 		});
 		
-		var index = 1;
-		
 		var reportDiv = this.controller.query(".report")[0];
 		
 		this.connect(viewer, "onChange", function(direction){
@@ -87,8 +84,7 @@ dojo.declare("FlickrImageViewAssistant", dojox.mobile.app.SceneAssistant, {
   
 	loadInteresting: function(){
 		console.log("loading interesting");
-		var _this = this;
-		
+
 		var url = "http://api.flickr.com/services/rest/?method=" +
 					"flickr.interestingness.getList";
 					
@@ -106,8 +102,7 @@ dojo.declare("FlickrImageViewAssistant", dojox.mobile.app.SceneAssistant, {
 
 	loadGroup: function(groupData){
 		console.log("loading group ", groupData);
-		var _this = this;
-		
+
 		var url = "http://api.flickr.com/services/rest/?method=" +
 					"flickr.groups.pools.getPhotos";
 					
diff --git a/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-search-group-assistant.js b/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-search-group-assistant.js
index 7db0c67..6a8fccc 100644
--- a/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-search-group-assistant.js
+++ b/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-search-group-assistant.js
@@ -1,4 +1,3 @@
-dojo.provide("FlickrSearchGroupAssistant");
 dojo.require("dojox.mobile.app.SceneAssistant");
 
 dojo.declare("FlickrSearchGroupAssistant", dojox.mobile.app.SceneAssistant, {
diff --git a/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-search-selection-assistant.js b/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-search-selection-assistant.js
index 55477c8..e7e5624 100644
--- a/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-search-selection-assistant.js
+++ b/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-search-selection-assistant.js
@@ -1,4 +1,3 @@
-dojo.provide("FlickrSearchSelectionAssistant");
 dojo.require("dojox.mobile.app.SceneAssistant");
 
 dojo.declare("FlickrSearchSelectionAssistant", dojox.mobile.app.SceneAssistant, {
diff --git a/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-search-text-assistant.js b/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-search-text-assistant.js
index 69c1d0d..000b0c2 100644
--- a/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-search-text-assistant.js
+++ b/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-search-text-assistant.js
@@ -1,4 +1,3 @@
-dojo.provide("FlickrSearchTextAssistant");
 dojo.require("dojox.mobile.app.SceneAssistant");
 
 dojo.declare("FlickrSearchTextAssistant", dojox.mobile.app.SceneAssistant, {
diff --git a/dojox/mobile/tests/imageControlsApp/app/assistants/image-view-assistant.js b/dojox/mobile/tests/imageControlsApp/app/assistants/image-view-assistant.js
index cd6bf9b..623e48f 100644
--- a/dojox/mobile/tests/imageControlsApp/app/assistants/image-view-assistant.js
+++ b/dojox/mobile/tests/imageControlsApp/app/assistants/image-view-assistant.js
@@ -1,4 +1,3 @@
-dojo.provide("ImageViewAssistant");
 dojo.require("dojox.mobile.app.SceneAssistant");
 
 dojo.declare("ImageViewAssistant", dojox.mobile.app.SceneAssistant, {
diff --git a/dojox/mobile/tests/imageControlsApp/app/assistants/main-assistant.js b/dojox/mobile/tests/imageControlsApp/app/assistants/main-assistant.js
index 2e8ab2e..cd7e9fb 100644
--- a/dojox/mobile/tests/imageControlsApp/app/assistants/main-assistant.js
+++ b/dojox/mobile/tests/imageControlsApp/app/assistants/main-assistant.js
@@ -1,4 +1,3 @@
-dojo.provide("MainAssistant");
 dojo.require("dojox.mobile.app.SceneAssistant");
 
 dojo.declare("MainAssistant", dojox.mobile.app.SceneAssistant, {
diff --git a/dojox/mobile/tests/imageControlsApp/app/views/flickr-image-thumb-view/flickr-image-thumb-view-scene.html b/dojox/mobile/tests/imageControlsApp/app/views/flickr-image-thumb-view/flickr-image-thumb-view-scene.html
index 8854eeb..26adb6e 100644
--- a/dojox/mobile/tests/imageControlsApp/app/views/flickr-image-thumb-view/flickr-image-thumb-view-scene.html
+++ b/dojox/mobile/tests/imageControlsApp/app/views/flickr-image-thumb-view/flickr-image-thumb-view-scene.html
@@ -2,7 +2,7 @@
 	Flickr ImageThumbView
 </h1>
 <input
-	dojoType="dojox.mobile.app.TextBox"
+	dojoType="dojox.mobile.TextBox"
 	value="mountain"
 	class="halfWidthInput"
 	style="visibility: hidden;"
diff --git a/dojox/mobile/tests/imageControlsApp/app/views/flickr-search-group/flickr-search-group-scene.html b/dojox/mobile/tests/imageControlsApp/app/views/flickr-search-group/flickr-search-group-scene.html
index c436e44..6951def 100644
--- a/dojox/mobile/tests/imageControlsApp/app/views/flickr-search-group/flickr-search-group-scene.html
+++ b/dojox/mobile/tests/imageControlsApp/app/views/flickr-search-group/flickr-search-group-scene.html
@@ -2,7 +2,7 @@
 	Search Flickr
 </h1>
 <input 
-	dojoType="dojox.mobile.app.TextBox"
+	dojoType="dojox.mobile.TextBox"
 	value="kinsale"
 	class="fullWidthInput"
 	placeholder="Enter Search Text"
diff --git a/dojox/mobile/tests/imageControlsApp/app/views/flickr-search-text/flickr-search-group-scene.html b/dojox/mobile/tests/imageControlsApp/app/views/flickr-search-text/flickr-search-group-scene.html
index 9e161b4..abb1d64 100644
--- a/dojox/mobile/tests/imageControlsApp/app/views/flickr-search-text/flickr-search-group-scene.html
+++ b/dojox/mobile/tests/imageControlsApp/app/views/flickr-search-text/flickr-search-group-scene.html
@@ -2,7 +2,7 @@
 	Search Flickr
 </h1>
 <input 
-	dojoType="dojox.mobile.app.TextBox"
+	dojoType="dojox.mobile.TextBox"
 	value=""
 	class="fullWidthInput"
 	placeholder="Enter Search Text"
diff --git a/dojox/mobile/tests/imageControlsApp/index.html b/dojox/mobile/tests/imageControlsApp/index.html
index dda8384..b4c8e04 100644
--- a/dojox/mobile/tests/imageControlsApp/index.html
+++ b/dojox/mobile/tests/imageControlsApp/index.html
@@ -15,13 +15,9 @@
 		<script type="text/javascript" src="../../../../dojo/dojo.js" 
 				djConfig="parseOnLoad: false, mobileAnim:'slide'"></script>
     
-    <!-- 
-      Include the files directly, as some mobile operating systems do not
-      allow synchronous XHR, and therefore break dojo.require
-    -->
-		<script type="text/javascript" src="../../../mobile/app.js"></script>
-		<script type="text/javascript" src="../../../../dojo/io/script.js"></script>
 		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.io.script");
+			dojo.require("dojox.mobile.app");
 			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.app.compat");
       
 			var appInfo = {
diff --git a/dojox/mobile/tests/images/a-icon-3.png b/dojox/mobile/tests/images/a-icon-3.png
index 77671cb..dc3941f 100755
Binary files a/dojox/mobile/tests/images/a-icon-3.png and b/dojox/mobile/tests/images/a-icon-3.png differ
diff --git a/dojox/mobile/tests/images/a-icon-all.png b/dojox/mobile/tests/images/a-icon-all.png
new file mode 100644
index 0000000..d779606
Binary files /dev/null and b/dojox/mobile/tests/images/a-icon-all.png differ
diff --git a/dojox/mobile/tests/images/a-icon1.png b/dojox/mobile/tests/images/a-icon1.png
new file mode 100644
index 0000000..2bcf7c2
Binary files /dev/null and b/dojox/mobile/tests/images/a-icon1.png differ
diff --git a/dojox/mobile/tests/images/a-icon10.png b/dojox/mobile/tests/images/a-icon10.png
new file mode 100644
index 0000000..7d6ffbe
Binary files /dev/null and b/dojox/mobile/tests/images/a-icon10.png differ
diff --git a/dojox/mobile/tests/images/a-icon2.png b/dojox/mobile/tests/images/a-icon2.png
new file mode 100644
index 0000000..ce97095
Binary files /dev/null and b/dojox/mobile/tests/images/a-icon2.png differ
diff --git a/dojox/mobile/tests/images/a-icon3.png b/dojox/mobile/tests/images/a-icon3.png
new file mode 100644
index 0000000..2cdd217
Binary files /dev/null and b/dojox/mobile/tests/images/a-icon3.png differ
diff --git a/dojox/mobile/tests/images/a-icon4.png b/dojox/mobile/tests/images/a-icon4.png
new file mode 100644
index 0000000..510e0c9
Binary files /dev/null and b/dojox/mobile/tests/images/a-icon4.png differ
diff --git a/dojox/mobile/tests/images/a-icon5.png b/dojox/mobile/tests/images/a-icon5.png
new file mode 100644
index 0000000..7334b1c
Binary files /dev/null and b/dojox/mobile/tests/images/a-icon5.png differ
diff --git a/dojox/mobile/tests/images/a-icon6.png b/dojox/mobile/tests/images/a-icon6.png
new file mode 100644
index 0000000..4f82cd7
Binary files /dev/null and b/dojox/mobile/tests/images/a-icon6.png differ
diff --git a/dojox/mobile/tests/images/a-icon7.png b/dojox/mobile/tests/images/a-icon7.png
new file mode 100644
index 0000000..c92de35
Binary files /dev/null and b/dojox/mobile/tests/images/a-icon7.png differ
diff --git a/dojox/mobile/tests/images/a-icon8.png b/dojox/mobile/tests/images/a-icon8.png
new file mode 100644
index 0000000..2d0820c
Binary files /dev/null and b/dojox/mobile/tests/images/a-icon8.png differ
diff --git a/dojox/mobile/tests/images/a-icon9.png b/dojox/mobile/tests/images/a-icon9.png
new file mode 100644
index 0000000..b26453f
Binary files /dev/null and b/dojox/mobile/tests/images/a-icon9.png differ
diff --git a/dojox/mobile/tests/images/b-app-icon-1.png b/dojox/mobile/tests/images/b-app-icon-1.png
new file mode 100644
index 0000000..e6c072c
Binary files /dev/null and b/dojox/mobile/tests/images/b-app-icon-1.png differ
diff --git a/dojox/mobile/tests/images/b-app-icon-2.png b/dojox/mobile/tests/images/b-app-icon-2.png
new file mode 100644
index 0000000..1252683
Binary files /dev/null and b/dojox/mobile/tests/images/b-app-icon-2.png differ
diff --git a/dojox/mobile/tests/images/b-app-icon-3.png b/dojox/mobile/tests/images/b-app-icon-3.png
new file mode 100644
index 0000000..0d239a8
Binary files /dev/null and b/dojox/mobile/tests/images/b-app-icon-3.png differ
diff --git a/dojox/mobile/tests/images/b-app-icon-4.png b/dojox/mobile/tests/images/b-app-icon-4.png
new file mode 100644
index 0000000..16eb0d7
Binary files /dev/null and b/dojox/mobile/tests/images/b-app-icon-4.png differ
diff --git a/dojox/mobile/tests/images/b-app-icon-5.png b/dojox/mobile/tests/images/b-app-icon-5.png
new file mode 100644
index 0000000..38e69cc
Binary files /dev/null and b/dojox/mobile/tests/images/b-app-icon-5.png differ
diff --git a/dojox/mobile/tests/images/b-app-icon-6.png b/dojox/mobile/tests/images/b-app-icon-6.png
new file mode 100644
index 0000000..04bf53c
Binary files /dev/null and b/dojox/mobile/tests/images/b-app-icon-6.png differ
diff --git a/dojox/mobile/tests/images/b-app-icon-7.png b/dojox/mobile/tests/images/b-app-icon-7.png
new file mode 100644
index 0000000..0a92e0c
Binary files /dev/null and b/dojox/mobile/tests/images/b-app-icon-7.png differ
diff --git a/dojox/mobile/tests/images/b-app-icon-8.png b/dojox/mobile/tests/images/b-app-icon-8.png
new file mode 100644
index 0000000..9beadfe
Binary files /dev/null and b/dojox/mobile/tests/images/b-app-icon-8.png differ
diff --git a/dojox/mobile/tests/images/b-icon-1.png b/dojox/mobile/tests/images/b-icon-1.png
new file mode 100644
index 0000000..3dee072
Binary files /dev/null and b/dojox/mobile/tests/images/b-icon-1.png differ
diff --git a/dojox/mobile/tests/images/b-icon-2.png b/dojox/mobile/tests/images/b-icon-2.png
new file mode 100644
index 0000000..4b5ab9c
Binary files /dev/null and b/dojox/mobile/tests/images/b-icon-2.png differ
diff --git a/dojox/mobile/tests/images/b-icon-3.png b/dojox/mobile/tests/images/b-icon-3.png
new file mode 100644
index 0000000..bfbf682
Binary files /dev/null and b/dojox/mobile/tests/images/b-icon-3.png differ
diff --git a/dojox/mobile/tests/images/b-icon-4.png b/dojox/mobile/tests/images/b-icon-4.png
new file mode 100644
index 0000000..18e26a6
Binary files /dev/null and b/dojox/mobile/tests/images/b-icon-4.png differ
diff --git a/dojox/mobile/tests/images/b-icon-5.png b/dojox/mobile/tests/images/b-icon-5.png
new file mode 100644
index 0000000..52befc8
Binary files /dev/null and b/dojox/mobile/tests/images/b-icon-5.png differ
diff --git a/dojox/mobile/tests/images/b-icon-6.png b/dojox/mobile/tests/images/b-icon-6.png
new file mode 100644
index 0000000..59ed1d9
Binary files /dev/null and b/dojox/mobile/tests/images/b-icon-6.png differ
diff --git a/dojox/mobile/tests/images/b-icon-7.png b/dojox/mobile/tests/images/b-icon-7.png
new file mode 100644
index 0000000..026e3f0
Binary files /dev/null and b/dojox/mobile/tests/images/b-icon-7.png differ
diff --git a/dojox/mobile/tests/images/b-icon-8.png b/dojox/mobile/tests/images/b-icon-8.png
new file mode 100644
index 0000000..f7190f4
Binary files /dev/null and b/dojox/mobile/tests/images/b-icon-8.png differ
diff --git a/dojox/mobile/tests/images/chart.png b/dojox/mobile/tests/images/chart.png
new file mode 100644
index 0000000..3887ba8
Binary files /dev/null and b/dojox/mobile/tests/images/chart.png differ
diff --git a/dojox/mobile/tests/images/checkboxRadioButtonStates.png b/dojox/mobile/tests/images/checkboxRadioButtonStates.png
new file mode 100644
index 0000000..2d06a82
Binary files /dev/null and b/dojox/mobile/tests/images/checkboxRadioButtonStates.png differ
diff --git a/dojox/mobile/tests/images/dish1.jpg b/dojox/mobile/tests/images/dish1.jpg
new file mode 100644
index 0000000..2b147ef
Binary files /dev/null and b/dojox/mobile/tests/images/dish1.jpg differ
diff --git a/dojox/mobile/tests/images/dish2.jpg b/dojox/mobile/tests/images/dish2.jpg
new file mode 100644
index 0000000..32cac74
Binary files /dev/null and b/dojox/mobile/tests/images/dish2.jpg differ
diff --git a/dojox/mobile/tests/images/dish3.jpg b/dojox/mobile/tests/images/dish3.jpg
new file mode 100644
index 0000000..d57cc3e
Binary files /dev/null and b/dojox/mobile/tests/images/dish3.jpg differ
diff --git a/dojox/mobile/tests/images/dish4.jpg b/dojox/mobile/tests/images/dish4.jpg
new file mode 100644
index 0000000..342569c
Binary files /dev/null and b/dojox/mobile/tests/images/dish4.jpg differ
diff --git a/dojox/mobile/tests/images/dish5.jpg b/dojox/mobile/tests/images/dish5.jpg
new file mode 100644
index 0000000..ab97da6
Binary files /dev/null and b/dojox/mobile/tests/images/dish5.jpg differ
diff --git a/dojox/mobile/tests/images/dish6.jpg b/dojox/mobile/tests/images/dish6.jpg
new file mode 100644
index 0000000..c954329
Binary files /dev/null and b/dojox/mobile/tests/images/dish6.jpg differ
diff --git a/dojox/mobile/tests/images/dish7.jpg b/dojox/mobile/tests/images/dish7.jpg
new file mode 100644
index 0000000..ce51f3a
Binary files /dev/null and b/dojox/mobile/tests/images/dish7.jpg differ
diff --git a/dojox/mobile/tests/images/dish8.jpg b/dojox/mobile/tests/images/dish8.jpg
new file mode 100644
index 0000000..73a4d6c
Binary files /dev/null and b/dojox/mobile/tests/images/dish8.jpg differ
diff --git a/dojox/mobile/tests/images/dish9.jpg b/dojox/mobile/tests/images/dish9.jpg
new file mode 100644
index 0000000..4cc815c
Binary files /dev/null and b/dojox/mobile/tests/images/dish9.jpg differ
diff --git a/dojox/mobile/tests/images/glass1.jpg b/dojox/mobile/tests/images/glass1.jpg
new file mode 100644
index 0000000..65edf8d
Binary files /dev/null and b/dojox/mobile/tests/images/glass1.jpg differ
diff --git a/dojox/mobile/tests/images/glass10.jpg b/dojox/mobile/tests/images/glass10.jpg
new file mode 100644
index 0000000..be890a2
Binary files /dev/null and b/dojox/mobile/tests/images/glass10.jpg differ
diff --git a/dojox/mobile/tests/images/glass11.jpg b/dojox/mobile/tests/images/glass11.jpg
new file mode 100644
index 0000000..c51a991
Binary files /dev/null and b/dojox/mobile/tests/images/glass11.jpg differ
diff --git a/dojox/mobile/tests/images/glass12.jpg b/dojox/mobile/tests/images/glass12.jpg
new file mode 100644
index 0000000..0d03c6b
Binary files /dev/null and b/dojox/mobile/tests/images/glass12.jpg differ
diff --git a/dojox/mobile/tests/images/glass13.jpg b/dojox/mobile/tests/images/glass13.jpg
new file mode 100644
index 0000000..afa1ab6
Binary files /dev/null and b/dojox/mobile/tests/images/glass13.jpg differ
diff --git a/dojox/mobile/tests/images/glass14.jpg b/dojox/mobile/tests/images/glass14.jpg
new file mode 100644
index 0000000..9b3f904
Binary files /dev/null and b/dojox/mobile/tests/images/glass14.jpg differ
diff --git a/dojox/mobile/tests/images/glass15.jpg b/dojox/mobile/tests/images/glass15.jpg
new file mode 100644
index 0000000..6ca4e4c
Binary files /dev/null and b/dojox/mobile/tests/images/glass15.jpg differ
diff --git a/dojox/mobile/tests/images/glass16.jpg b/dojox/mobile/tests/images/glass16.jpg
new file mode 100644
index 0000000..e695221
Binary files /dev/null and b/dojox/mobile/tests/images/glass16.jpg differ
diff --git a/dojox/mobile/tests/images/glass2.jpg b/dojox/mobile/tests/images/glass2.jpg
new file mode 100644
index 0000000..2ff3476
Binary files /dev/null and b/dojox/mobile/tests/images/glass2.jpg differ
diff --git a/dojox/mobile/tests/images/glass3.jpg b/dojox/mobile/tests/images/glass3.jpg
new file mode 100644
index 0000000..eebaf31
Binary files /dev/null and b/dojox/mobile/tests/images/glass3.jpg differ
diff --git a/dojox/mobile/tests/images/glass4.jpg b/dojox/mobile/tests/images/glass4.jpg
new file mode 100644
index 0000000..c1e34a1
Binary files /dev/null and b/dojox/mobile/tests/images/glass4.jpg differ
diff --git a/dojox/mobile/tests/images/glass5.jpg b/dojox/mobile/tests/images/glass5.jpg
new file mode 100644
index 0000000..30520c4
Binary files /dev/null and b/dojox/mobile/tests/images/glass5.jpg differ
diff --git a/dojox/mobile/tests/images/glass6.jpg b/dojox/mobile/tests/images/glass6.jpg
new file mode 100644
index 0000000..444f9f4
Binary files /dev/null and b/dojox/mobile/tests/images/glass6.jpg differ
diff --git a/dojox/mobile/tests/images/glass7.jpg b/dojox/mobile/tests/images/glass7.jpg
new file mode 100644
index 0000000..1672ab2
Binary files /dev/null and b/dojox/mobile/tests/images/glass7.jpg differ
diff --git a/dojox/mobile/tests/images/glass8.jpg b/dojox/mobile/tests/images/glass8.jpg
new file mode 100644
index 0000000..a4d1e4d
Binary files /dev/null and b/dojox/mobile/tests/images/glass8.jpg differ
diff --git a/dojox/mobile/tests/images/glass9.jpg b/dojox/mobile/tests/images/glass9.jpg
new file mode 100644
index 0000000..ff98ce0
Binary files /dev/null and b/dojox/mobile/tests/images/glass9.jpg differ
diff --git a/dojox/mobile/tests/images/icon-all.png b/dojox/mobile/tests/images/icon-all.png
new file mode 100644
index 0000000..e3ad155
Binary files /dev/null and b/dojox/mobile/tests/images/icon-all.png differ
diff --git a/dojox/mobile/tests/images/icon1.png b/dojox/mobile/tests/images/icon1.png
new file mode 100644
index 0000000..d1e98c8
Binary files /dev/null and b/dojox/mobile/tests/images/icon1.png differ
diff --git a/dojox/mobile/tests/images/icon10.png b/dojox/mobile/tests/images/icon10.png
new file mode 100644
index 0000000..fad8480
Binary files /dev/null and b/dojox/mobile/tests/images/icon10.png differ
diff --git a/dojox/mobile/tests/images/icon2.png b/dojox/mobile/tests/images/icon2.png
new file mode 100644
index 0000000..018801b
Binary files /dev/null and b/dojox/mobile/tests/images/icon2.png differ
diff --git a/dojox/mobile/tests/images/icon3.png b/dojox/mobile/tests/images/icon3.png
new file mode 100644
index 0000000..f393f2c
Binary files /dev/null and b/dojox/mobile/tests/images/icon3.png differ
diff --git a/dojox/mobile/tests/images/icon4.png b/dojox/mobile/tests/images/icon4.png
new file mode 100644
index 0000000..8137de5
Binary files /dev/null and b/dojox/mobile/tests/images/icon4.png differ
diff --git a/dojox/mobile/tests/images/icon5.png b/dojox/mobile/tests/images/icon5.png
new file mode 100644
index 0000000..6a32983
Binary files /dev/null and b/dojox/mobile/tests/images/icon5.png differ
diff --git a/dojox/mobile/tests/images/icon6.png b/dojox/mobile/tests/images/icon6.png
new file mode 100644
index 0000000..ee0425f
Binary files /dev/null and b/dojox/mobile/tests/images/icon6.png differ
diff --git a/dojox/mobile/tests/images/icon7.png b/dojox/mobile/tests/images/icon7.png
new file mode 100644
index 0000000..b6ee2eb
Binary files /dev/null and b/dojox/mobile/tests/images/icon7.png differ
diff --git a/dojox/mobile/tests/images/icon8.png b/dojox/mobile/tests/images/icon8.png
new file mode 100644
index 0000000..bc7870d
Binary files /dev/null and b/dojox/mobile/tests/images/icon8.png differ
diff --git a/dojox/mobile/tests/images/icon9.png b/dojox/mobile/tests/images/icon9.png
new file mode 100644
index 0000000..ad2a5b6
Binary files /dev/null and b/dojox/mobile/tests/images/icon9.png differ
diff --git a/dojox/mobile/tests/images/pic1.jpg b/dojox/mobile/tests/images/pic1.jpg
new file mode 100644
index 0000000..a8ef25f
Binary files /dev/null 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
new file mode 100644
index 0000000..eed3321
Binary files /dev/null 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
new file mode 100644
index 0000000..5998cec
Binary files /dev/null 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
new file mode 100644
index 0000000..10c593b
Binary files /dev/null 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
new file mode 100644
index 0000000..7abbaa9
Binary files /dev/null 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
new file mode 100644
index 0000000..7c02ed7
Binary files /dev/null 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
new file mode 100644
index 0000000..a3045f2
Binary files /dev/null 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
new file mode 100644
index 0000000..c182569
Binary files /dev/null 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
new file mode 100644
index 0000000..d83c21d
Binary files /dev/null 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
new file mode 100644
index 0000000..663ae58
Binary files /dev/null and b/dojox/mobile/tests/images/pic9.jpg differ
diff --git a/dojox/mobile/tests/images/shell1.jpg b/dojox/mobile/tests/images/shell1.jpg
new file mode 100644
index 0000000..7f236d3
Binary files /dev/null and b/dojox/mobile/tests/images/shell1.jpg differ
diff --git a/dojox/mobile/tests/images/shell10.jpg b/dojox/mobile/tests/images/shell10.jpg
new file mode 100644
index 0000000..a4ddf98
Binary files /dev/null and b/dojox/mobile/tests/images/shell10.jpg differ
diff --git a/dojox/mobile/tests/images/shell11.jpg b/dojox/mobile/tests/images/shell11.jpg
new file mode 100644
index 0000000..ff212e5
Binary files /dev/null and b/dojox/mobile/tests/images/shell11.jpg differ
diff --git a/dojox/mobile/tests/images/shell2.jpg b/dojox/mobile/tests/images/shell2.jpg
new file mode 100644
index 0000000..8a13ade
Binary files /dev/null and b/dojox/mobile/tests/images/shell2.jpg differ
diff --git a/dojox/mobile/tests/images/shell3.jpg b/dojox/mobile/tests/images/shell3.jpg
new file mode 100644
index 0000000..7e88f8c
Binary files /dev/null and b/dojox/mobile/tests/images/shell3.jpg differ
diff --git a/dojox/mobile/tests/images/shell4.jpg b/dojox/mobile/tests/images/shell4.jpg
new file mode 100644
index 0000000..04e70d4
Binary files /dev/null and b/dojox/mobile/tests/images/shell4.jpg differ
diff --git a/dojox/mobile/tests/images/shell5.jpg b/dojox/mobile/tests/images/shell5.jpg
new file mode 100644
index 0000000..c252082
Binary files /dev/null and b/dojox/mobile/tests/images/shell5.jpg differ
diff --git a/dojox/mobile/tests/images/shell6.jpg b/dojox/mobile/tests/images/shell6.jpg
new file mode 100644
index 0000000..92a19eb
Binary files /dev/null and b/dojox/mobile/tests/images/shell6.jpg differ
diff --git a/dojox/mobile/tests/images/shell7.jpg b/dojox/mobile/tests/images/shell7.jpg
new file mode 100644
index 0000000..4750752
Binary files /dev/null and b/dojox/mobile/tests/images/shell7.jpg differ
diff --git a/dojox/mobile/tests/images/shell8.jpg b/dojox/mobile/tests/images/shell8.jpg
new file mode 100644
index 0000000..cc568f3
Binary files /dev/null and b/dojox/mobile/tests/images/shell8.jpg differ
diff --git a/dojox/mobile/tests/images/shell9.jpg b/dojox/mobile/tests/images/shell9.jpg
new file mode 100644
index 0000000..9b5b029
Binary files /dev/null and b/dojox/mobile/tests/images/shell9.jpg differ
diff --git a/dojox/mobile/tests/images/stone1.jpg b/dojox/mobile/tests/images/stone1.jpg
new file mode 100644
index 0000000..a012158
Binary files /dev/null and b/dojox/mobile/tests/images/stone1.jpg differ
diff --git a/dojox/mobile/tests/images/stone10.jpg b/dojox/mobile/tests/images/stone10.jpg
new file mode 100644
index 0000000..b25e375
Binary files /dev/null and b/dojox/mobile/tests/images/stone10.jpg differ
diff --git a/dojox/mobile/tests/images/stone2.jpg b/dojox/mobile/tests/images/stone2.jpg
new file mode 100644
index 0000000..596b64a
Binary files /dev/null and b/dojox/mobile/tests/images/stone2.jpg differ
diff --git a/dojox/mobile/tests/images/stone3.jpg b/dojox/mobile/tests/images/stone3.jpg
new file mode 100644
index 0000000..8c2424b
Binary files /dev/null and b/dojox/mobile/tests/images/stone3.jpg differ
diff --git a/dojox/mobile/tests/images/stone4.jpg b/dojox/mobile/tests/images/stone4.jpg
new file mode 100644
index 0000000..bab8eac
Binary files /dev/null and b/dojox/mobile/tests/images/stone4.jpg differ
diff --git a/dojox/mobile/tests/images/stone5.jpg b/dojox/mobile/tests/images/stone5.jpg
new file mode 100644
index 0000000..3a65c85
Binary files /dev/null and b/dojox/mobile/tests/images/stone5.jpg differ
diff --git a/dojox/mobile/tests/images/stone6.jpg b/dojox/mobile/tests/images/stone6.jpg
new file mode 100644
index 0000000..c1cd4aa
Binary files /dev/null and b/dojox/mobile/tests/images/stone6.jpg differ
diff --git a/dojox/mobile/tests/images/stone7.jpg b/dojox/mobile/tests/images/stone7.jpg
new file mode 100644
index 0000000..2d20a5f
Binary files /dev/null and b/dojox/mobile/tests/images/stone7.jpg differ
diff --git a/dojox/mobile/tests/images/stone8.jpg b/dojox/mobile/tests/images/stone8.jpg
new file mode 100644
index 0000000..03c2fe4
Binary files /dev/null and b/dojox/mobile/tests/images/stone8.jpg differ
diff --git a/dojox/mobile/tests/images/stone9.jpg b/dojox/mobile/tests/images/stone9.jpg
new file mode 100644
index 0000000..6b8d588
Binary files /dev/null and b/dojox/mobile/tests/images/stone9.jpg differ
diff --git a/dojox/mobile/tests/images/tab-icon-10w.png b/dojox/mobile/tests/images/tab-icon-10w.png
new file mode 100644
index 0000000..fd8425a
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-10w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-11w.png b/dojox/mobile/tests/images/tab-icon-11w.png
new file mode 100644
index 0000000..4af4d0d
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-11w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-12w.png b/dojox/mobile/tests/images/tab-icon-12w.png
new file mode 100644
index 0000000..ebb2e0e
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-12w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-13w.png b/dojox/mobile/tests/images/tab-icon-13w.png
new file mode 100644
index 0000000..44dcf83
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-13w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-14w.png b/dojox/mobile/tests/images/tab-icon-14w.png
new file mode 100644
index 0000000..16f1e52
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-14w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-15w.png b/dojox/mobile/tests/images/tab-icon-15w.png
new file mode 100644
index 0000000..78c5bc3
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-15w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-16w.png b/dojox/mobile/tests/images/tab-icon-16w.png
new file mode 100644
index 0000000..810afe8
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-16w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-17w.png b/dojox/mobile/tests/images/tab-icon-17w.png
new file mode 100644
index 0000000..26125d6
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-17w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-18w.png b/dojox/mobile/tests/images/tab-icon-18w.png
new file mode 100644
index 0000000..fdd1cc7
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-18w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-19.png b/dojox/mobile/tests/images/tab-icon-19.png
new file mode 100644
index 0000000..584cc2a
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-19.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-19h.png b/dojox/mobile/tests/images/tab-icon-19h.png
new file mode 100644
index 0000000..d1b2c74
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-19h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-19w.png b/dojox/mobile/tests/images/tab-icon-19w.png
new file mode 100644
index 0000000..be2ddbd
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-19w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-20.png b/dojox/mobile/tests/images/tab-icon-20.png
new file mode 100644
index 0000000..7c130d3
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-20.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-20h.png b/dojox/mobile/tests/images/tab-icon-20h.png
new file mode 100644
index 0000000..84bc0a1
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-20h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-20w.png b/dojox/mobile/tests/images/tab-icon-20w.png
new file mode 100644
index 0000000..091f32a
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-20w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-21.png b/dojox/mobile/tests/images/tab-icon-21.png
new file mode 100644
index 0000000..5a6b99a
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-21.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-21h.png b/dojox/mobile/tests/images/tab-icon-21h.png
new file mode 100644
index 0000000..780a3f8
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-21h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-21w.png b/dojox/mobile/tests/images/tab-icon-21w.png
new file mode 100644
index 0000000..33622a0
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-21w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-22.png b/dojox/mobile/tests/images/tab-icon-22.png
new file mode 100644
index 0000000..7614809
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-22.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-22h.png b/dojox/mobile/tests/images/tab-icon-22h.png
new file mode 100644
index 0000000..e841921
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-22h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-22w.png b/dojox/mobile/tests/images/tab-icon-22w.png
new file mode 100644
index 0000000..684d304
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-22w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-23.png b/dojox/mobile/tests/images/tab-icon-23.png
new file mode 100644
index 0000000..0bf828f
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-23.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-23h.png b/dojox/mobile/tests/images/tab-icon-23h.png
new file mode 100644
index 0000000..d532855
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-23h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-23w.png b/dojox/mobile/tests/images/tab-icon-23w.png
new file mode 100644
index 0000000..7625c89
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-23w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-24.png b/dojox/mobile/tests/images/tab-icon-24.png
new file mode 100644
index 0000000..ad1de05
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-24.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-24h.png b/dojox/mobile/tests/images/tab-icon-24h.png
new file mode 100644
index 0000000..da40442
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-24h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-24w.png b/dojox/mobile/tests/images/tab-icon-24w.png
new file mode 100644
index 0000000..cb6bb7e
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-24w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-25.png b/dojox/mobile/tests/images/tab-icon-25.png
new file mode 100644
index 0000000..82f39df
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-25.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-25h.png b/dojox/mobile/tests/images/tab-icon-25h.png
new file mode 100644
index 0000000..301bebb
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-25h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-25w.png b/dojox/mobile/tests/images/tab-icon-25w.png
new file mode 100644
index 0000000..65d4af6
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-25w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-26.png b/dojox/mobile/tests/images/tab-icon-26.png
new file mode 100644
index 0000000..4e65746
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-26.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-26h.png b/dojox/mobile/tests/images/tab-icon-26h.png
new file mode 100644
index 0000000..5fe3e8c
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-26h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-26w.png b/dojox/mobile/tests/images/tab-icon-26w.png
new file mode 100644
index 0000000..2792120
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-26w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-27.png b/dojox/mobile/tests/images/tab-icon-27.png
new file mode 100644
index 0000000..01ac2f9
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-27.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-27h.png b/dojox/mobile/tests/images/tab-icon-27h.png
new file mode 100644
index 0000000..dfedeeb
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-27h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-27w.png b/dojox/mobile/tests/images/tab-icon-27w.png
new file mode 100644
index 0000000..b3b9bca
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-27w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-28.png b/dojox/mobile/tests/images/tab-icon-28.png
new file mode 100644
index 0000000..09acadf
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-28.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-28h.png b/dojox/mobile/tests/images/tab-icon-28h.png
new file mode 100644
index 0000000..d4601bc
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-28h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-28w.png b/dojox/mobile/tests/images/tab-icon-28w.png
new file mode 100644
index 0000000..29368f1
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-28w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-29.png b/dojox/mobile/tests/images/tab-icon-29.png
new file mode 100644
index 0000000..e6f2128
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-29.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-29h.png b/dojox/mobile/tests/images/tab-icon-29h.png
new file mode 100644
index 0000000..5ff3418
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-29h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-29w.png b/dojox/mobile/tests/images/tab-icon-29w.png
new file mode 100644
index 0000000..78819b9
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-29w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-30.png b/dojox/mobile/tests/images/tab-icon-30.png
new file mode 100644
index 0000000..dcb1414
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-30.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-30h.png b/dojox/mobile/tests/images/tab-icon-30h.png
new file mode 100644
index 0000000..d9dbb31
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-30h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-30w.png b/dojox/mobile/tests/images/tab-icon-30w.png
new file mode 100644
index 0000000..1cd0a1d
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-30w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-31.png b/dojox/mobile/tests/images/tab-icon-31.png
new file mode 100644
index 0000000..417b0c9
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-31.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-31h.png b/dojox/mobile/tests/images/tab-icon-31h.png
new file mode 100644
index 0000000..2641318
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-31h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-31w.png b/dojox/mobile/tests/images/tab-icon-31w.png
new file mode 100644
index 0000000..8c9ffef
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-31w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-32.png b/dojox/mobile/tests/images/tab-icon-32.png
new file mode 100644
index 0000000..dae8de1
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-32.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-32h.png b/dojox/mobile/tests/images/tab-icon-32h.png
new file mode 100644
index 0000000..b07f972
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-32h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-32w.png b/dojox/mobile/tests/images/tab-icon-32w.png
new file mode 100644
index 0000000..aa5f3dd
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-32w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-33.png b/dojox/mobile/tests/images/tab-icon-33.png
new file mode 100644
index 0000000..f6f86f4
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-33.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-33h.png b/dojox/mobile/tests/images/tab-icon-33h.png
new file mode 100644
index 0000000..2bdee59
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-33h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-33w.png b/dojox/mobile/tests/images/tab-icon-33w.png
new file mode 100644
index 0000000..e92f8c7
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-33w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-34.png b/dojox/mobile/tests/images/tab-icon-34.png
new file mode 100644
index 0000000..b43b714
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-34.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-34h.png b/dojox/mobile/tests/images/tab-icon-34h.png
new file mode 100644
index 0000000..1edafe5
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-34h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-34w.png b/dojox/mobile/tests/images/tab-icon-34w.png
new file mode 100644
index 0000000..20bc3ae
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-34w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-35.png b/dojox/mobile/tests/images/tab-icon-35.png
new file mode 100644
index 0000000..f94c3d3
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-35.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-35h.png b/dojox/mobile/tests/images/tab-icon-35h.png
new file mode 100644
index 0000000..5c08ea9
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-35h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-35w.png b/dojox/mobile/tests/images/tab-icon-35w.png
new file mode 100644
index 0000000..5b49c33
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-35w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-36.png b/dojox/mobile/tests/images/tab-icon-36.png
new file mode 100644
index 0000000..b142d65
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-36.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-36h.png b/dojox/mobile/tests/images/tab-icon-36h.png
new file mode 100644
index 0000000..75fe56d
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-36h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-36w.png b/dojox/mobile/tests/images/tab-icon-36w.png
new file mode 100644
index 0000000..0df405b
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-36w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-37.png b/dojox/mobile/tests/images/tab-icon-37.png
new file mode 100644
index 0000000..929181b
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-37.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-37h.png b/dojox/mobile/tests/images/tab-icon-37h.png
new file mode 100644
index 0000000..ad3b017
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-37h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-37w.png b/dojox/mobile/tests/images/tab-icon-37w.png
new file mode 100644
index 0000000..c607d72
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-37w.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-38.png b/dojox/mobile/tests/images/tab-icon-38.png
new file mode 100644
index 0000000..d4d89c0
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-38.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-38h.png b/dojox/mobile/tests/images/tab-icon-38h.png
new file mode 100644
index 0000000..cc176d4
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-38h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-38w.png b/dojox/mobile/tests/images/tab-icon-38w.png
new file mode 100644
index 0000000..1e8e370
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-38w.png differ
diff --git a/dojox/mobile/tests/index.html b/dojox/mobile/tests/index.html
index c419aa3..aa18e7a 100644
--- a/dojox/mobile/tests/index.html
+++ b/dojox/mobile/tests/index.html
@@ -15,13 +15,22 @@
 		<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-TabContainer.html">test_iPhone-TabContainer.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>
@@ -31,26 +40,59 @@
 		<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-TabContainer.html">test_Android-TabContainer.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-FlippableView.html">test_iPhone-FlippableView.html</a><br>
-		<hr>
-		<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_Android-TabBar.html">test_Android-TabBar.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>
@@ -59,8 +101,12 @@
 		<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_buttons.html">test_buttons.html</a><br>
+		<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>
@@ -77,12 +123,59 @@
 		<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>
diff --git a/dojox/mobile/tests/inputApp/app/assistants/text-input-assistant.js b/dojox/mobile/tests/inputApp/app/assistants/text-input-assistant.js
index cd69687..9d75689 100644
--- a/dojox/mobile/tests/inputApp/app/assistants/text-input-assistant.js
+++ b/dojox/mobile/tests/inputApp/app/assistants/text-input-assistant.js
@@ -1,4 +1,3 @@
-dojo.provide("TextInputAssistant");
 dojo.require("dojox.mobile.app.SceneAssistant");
 
 dojo.declare("TextInputAssistant", dojox.mobile.app.SceneAssistant, {
diff --git a/dojox/mobile/tests/inputApp/app/views/text-input/text-input-scene.html b/dojox/mobile/tests/inputApp/app/views/text-input/text-input-scene.html
index 9e9366b..18dde59 100644
--- a/dojox/mobile/tests/inputApp/app/views/text-input/text-input-scene.html
+++ b/dojox/mobile/tests/inputApp/app/views/text-input/text-input-scene.html
@@ -2,39 +2,39 @@
 
 <div>
 	Simple Text Input	
-	<input dojoType="dojox.mobile.app.TextBox" value="Joe Bloggs" id="simpleTextInput">
+	<input dojoType="dojox.mobile.TextBox" value="Joe Bloggs" id="simpleTextInput">
 </div>
 <div>
 	Uppercase Text Input 
-	<input 	dojoType="dojox.mobile.app.TextBox" 
+	<input 	dojoType="dojox.mobile.TextBox"
 			value="Joe Bloggs"
 			uppercase="true" 
 			id="upperCaseTextInput">
 </div>
 <div>
 	Lowercase Text Input 
-	<input 	dojoType="dojox.mobile.app.TextBox" 
+	<input 	dojoType="dojox.mobile.TextBox"
 			value="Joe Bloggs"
 			lowercase="true" 
 			id="lowerCaseTextInput">
 </div>
 <div>
 	Propercase Text Input 
-	<input 	dojoType="dojox.mobile.app.TextBox" 
+	<input 	dojoType="dojox.mobile.TextBox"
 			value="Joe Bloggs"
 			propercase="true" 
 			id="properCaseTextInput">
 </div>
 <div>
 	Max Length = 6 Text Input 
-	<input 	dojoType="dojox.mobile.app.TextBox" 
+	<input 	dojoType="dojox.mobile.TextBox"
 			value="Joe Bloggs"
 			maxLength="6" 
 			id="maxLengthTextInput">
 </div>
 <div>
 	PlaceHolder Text Input 
-	<input 	dojoType="dojox.mobile.app.TextBox" 
+	<input 	dojoType="dojox.mobile.TextBox"
 			value=""
 			placeHolder="Enter Name"
 			maxLength="6" 
@@ -42,7 +42,7 @@
 </div>
 <div>
 	Select On Click Text Input 
-	<input 	dojoType="dojox.mobile.app.TextBox" 
+	<input 	dojoType="dojox.mobile.TextBox"
 			value="Joe Bloggs"
 			selectOnClick="true" 
 			id="selectOnClickTextInput">
diff --git a/dojox/mobile/tests/inputApp/index.html b/dojox/mobile/tests/inputApp/index.html
index c467e6c..361aeb4 100644
--- a/dojox/mobile/tests/inputApp/index.html
+++ b/dojox/mobile/tests/inputApp/index.html
@@ -13,13 +13,9 @@
 		</style>
 		
 		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: false"></script>
-    
-    <!-- 
-      Include the files directly, as some mobile operating systems do not
-      allow synchronous XHR, and therefore break dojo.require
-    -->
-		<script type="text/javascript" src="../../../mobile/app.js"></script>
+
 		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojox.mobile.app");
 			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.app.compat");
       
 			var appInfo = {
diff --git a/dojox/mobile/tests/insurance-car-coverage.html b/dojox/mobile/tests/insurance-car-coverage.html
new file mode 100644
index 0000000..50573be
--- /dev/null
+++ b/dojox/mobile/tests/insurance-car-coverage.html
@@ -0,0 +1,6 @@
+<div dojoType="dojox.mobile.View">
+	<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="CarInsuranceView">Coverage Options</h1>
+	<div dojoType="dojox.mobile.RoundRect" shadow="true">
+		<b>Would you like to learn more about Coverage Options?</b>
+	</div>
+</div>
diff --git a/dojox/mobile/tests/insurance-car-safe.html b/dojox/mobile/tests/insurance-car-safe.html
new file mode 100644
index 0000000..3e8fba0
--- /dev/null
+++ b/dojox/mobile/tests/insurance-car-safe.html
@@ -0,0 +1,6 @@
+<div dojoType="dojox.mobile.View">
+	<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="CarInsuranceView">Safe Driving Bonus</h1>
+	<div dojoType="dojox.mobile.RoundRect" shadow="true">
+		<b>Would you like to learn more about Safe Driving Bonus?</b>
+	</div>
+</div>
diff --git a/dojox/mobile/tests/insurance-car.json b/dojox/mobile/tests/insurance-car.json
new file mode 100644
index 0000000..23ce8d0
--- /dev/null
+++ b/dojox/mobile/tests/insurance-car.json
@@ -0,0 +1,6 @@
+{
+  "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-child.html b/dojox/mobile/tests/insurance-life-child.html
new file mode 100644
index 0000000..7f4153a
--- /dev/null
+++ b/dojox/mobile/tests/insurance-life-child.html
@@ -0,0 +1,6 @@
+<div dojoType="dojox.mobile.View">
+	<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="LifeInsuranceView">Child's Education</h1>
+	<div dojoType="dojox.mobile.RoundRect" shadow="true">
+		<b>Would you like to learn more about Child's Education?</b>
+	</div>
+</div>
diff --git a/dojox/mobile/tests/insurance-life-long.html b/dojox/mobile/tests/insurance-life-long.html
new file mode 100644
index 0000000..3ea9648
--- /dev/null
+++ b/dojox/mobile/tests/insurance-life-long.html
@@ -0,0 +1,6 @@
+<div dojoType="dojox.mobile.View">
+	<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="LifeInsuranceView">Long Term Care</h1>
+	<div dojoType="dojox.mobile.RoundRect" shadow="true">
+		<b>Would you like to learn more about Long Term Care?</b>
+	</div>
+</div>
diff --git a/dojox/mobile/tests/insurance-life.json b/dojox/mobile/tests/insurance-life.json
new file mode 100644
index 0000000..dab22f8
--- /dev/null
+++ b/dojox/mobile/tests/insurance-life.json
@@ -0,0 +1,6 @@
+{
+  "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-boat.html b/dojox/mobile/tests/insurance-sports-boat.html
new file mode 100644
index 0000000..e49b73a
--- /dev/null
+++ b/dojox/mobile/tests/insurance-sports-boat.html
@@ -0,0 +1,6 @@
+<div dojoType="dojox.mobile.View">
+	<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="SportsInsuranceView">Boat</h1>
+	<div dojoType="dojox.mobile.RoundRect" shadow="true">
+		<b>Would you like to learn more about Boat Insurance?</b>
+	</div>
+</div>
diff --git a/dojox/mobile/tests/insurance-sports-moto.html b/dojox/mobile/tests/insurance-sports-moto.html
new file mode 100644
index 0000000..b3c9065
--- /dev/null
+++ b/dojox/mobile/tests/insurance-sports-moto.html
@@ -0,0 +1,6 @@
+<div dojoType="dojox.mobile.View">
+	<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="SportsInsuranceView">Motorcycle</h1>
+	<div dojoType="dojox.mobile.RoundRect" shadow="true">
+		<b>Would you like to learn more about Motorcycle Insurance?</b>
+	</div>
+</div>
diff --git a/dojox/mobile/tests/insurance-sports-snow.html b/dojox/mobile/tests/insurance-sports-snow.html
new file mode 100644
index 0000000..730e2e6
--- /dev/null
+++ b/dojox/mobile/tests/insurance-sports-snow.html
@@ -0,0 +1,6 @@
+<div dojoType="dojox.mobile.View">
+	<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="SportsInsuranceView">Snowmobile</h1>
+	<div dojoType="dojox.mobile.RoundRect" shadow="true">
+		<b>Would you like to learn more about Snowmobile Insurance?</b>
+	</div>
+</div>
diff --git a/dojox/mobile/tests/insurance-sports.json b/dojox/mobile/tests/insurance-sports.json
new file mode 100644
index 0000000..a3c24d4
--- /dev/null
+++ b/dojox/mobile/tests/insurance-sports.json
@@ -0,0 +1,7 @@
+{
+  "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
new file mode 100644
index 0000000..df4dafd
--- /dev/null
+++ b/dojox/mobile/tests/insurance.json
@@ -0,0 +1,7 @@
+{
+  "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/module.js b/dojox/mobile/tests/module.js
new file mode 100644
index 0000000..b724633
--- /dev/null
+++ b/dojox/mobile/tests/module.js
@@ -0,0 +1,12 @@
+dojo.provide("dojox.mobile.tests.module");
+
+try{
+	dojo.require("dojox.mobile.tests.doh.module");
+	if(!dojo.isBB && !dojo.isAndroid && !dojo.isIPhone && !dojo.isIPad && !dojo.isIPod) {
+		dojo.require("dojox.mobile.tests.robot.module");
+	}
+
+}catch(e){
+	doh.debug(e);
+}
+
diff --git a/dojox/mobile/tests/multiSceneApp/app/assistants/main-assistant.js b/dojox/mobile/tests/multiSceneApp/app/assistants/main-assistant.js
index a8e110d..9f09051 100644
--- a/dojox/mobile/tests/multiSceneApp/app/assistants/main-assistant.js
+++ b/dojox/mobile/tests/multiSceneApp/app/assistants/main-assistant.js
@@ -1,4 +1,3 @@
-dojo.provide("MainAssistant");
 dojo.require("dojox.mobile.app.SceneAssistant");
 
 dojo.declare("MainAssistant", dojox.mobile.app.SceneAssistant, {
@@ -19,7 +18,7 @@ dojo.declare("MainAssistant", dojox.mobile.app.SceneAssistant, {
     var launcher = dijit.byId("secondSceneLauncher");
     
     console.log("launcher = " , launcher, " node = ", this.domNode);
-    this.connect(launcher, "onClick", function(){
+    this.connect(launcher.domNode, "onclick", function(){
       console.log("launching the second scene");
       
       _this.controller.stageController.pushScene("second", "Came from Main Scene");
diff --git a/dojox/mobile/tests/multiSceneApp/app/assistants/second-assistant.js b/dojox/mobile/tests/multiSceneApp/app/assistants/second-assistant.js
index e07fa1d..6526cf9 100644
--- a/dojox/mobile/tests/multiSceneApp/app/assistants/second-assistant.js
+++ b/dojox/mobile/tests/multiSceneApp/app/assistants/second-assistant.js
@@ -1,4 +1,3 @@
-dojo.provide("SecondAssistant");
 dojo.require("dojox.mobile.app.SceneAssistant");
 
 dojo.declare("SecondAssistant", dojox.mobile.app.SceneAssistant, {
@@ -10,8 +9,7 @@ dojo.declare("SecondAssistant", dojox.mobile.app.SceneAssistant, {
     this.controller.parse();
     
     var _this = this;
-    var launcher = dijit.byId("secondSceneLauncher");
-    this.connect(dijit.byId("btn1"), "onClick", function(){
+     this.connect(dijit.byId("btn1"), "onClick", function(){
       _this.controller.stageController.popScene("Button 1");
     });
     this.connect(dijit.byId("btn2"), "onClick", function(){
diff --git a/dojox/mobile/tests/multiSceneApp/app/assistants/third-assistant.js b/dojox/mobile/tests/multiSceneApp/app/assistants/third-assistant.js
index bf58f3b..1cea51e 100644
--- a/dojox/mobile/tests/multiSceneApp/app/assistants/third-assistant.js
+++ b/dojox/mobile/tests/multiSceneApp/app/assistants/third-assistant.js
@@ -1,4 +1,3 @@
-dojo.provide("ThirdAssistant");
 dojo.require("dojox.mobile.app.SceneAssistant");
 
 dojo.declare("ThirdAssistant", dojox.mobile.app.SceneAssistant, {
@@ -10,7 +9,6 @@ dojo.declare("ThirdAssistant", dojox.mobile.app.SceneAssistant, {
     this.controller.parse();
     
     var _this = this;
-    var launcher = dijit.byId("secondSceneLauncher");
     this.connect(dijit.byId("btn3"), "onClick", function(){
       _this.controller.stageController.popScenesTo("main", "From Third Scene");
     });
diff --git a/dojox/mobile/tests/multiSceneApp/index.html b/dojox/mobile/tests/multiSceneApp/index.html
index 3da165a..cd97251 100644
--- a/dojox/mobile/tests/multiSceneApp/index.html
+++ b/dojox/mobile/tests/multiSceneApp/index.html
@@ -14,12 +14,8 @@
 		<script type="text/javascript" src="../../../../dojo/dojo.js" 
 			djConfig="parseOnLoad: false,mobileAnim:'slide'"></script>
     
-		<!-- 
-			Include the files directly, as some mobile operating systems do not
-			allow synchronous XHR, and therefore break dojo.require
-		-->
-		<script type="text/javascript" src="../../../mobile/app.js"></script>
 		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojox.mobile.app");
 			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.app.compat");
       
 			var appInfo = {
diff --git a/dojox/mobile/tests/nls/it/sample.js b/dojox/mobile/tests/nls/it/sample.js
new file mode 100644
index 0000000..74963ee
--- /dev/null
+++ b/dojox/mobile/tests/nls/it/sample.js
@@ -0,0 +1,11 @@
+define(
+//begin v1.x content
+({
+	"MINUTES": "%1 Minuto",
+	"Second": "secondo",
+	"Day of the Week": "giorno della settimana",
+	"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
new file mode 100644
index 0000000..de5a707
--- /dev/null
+++ b/dojox/mobile/tests/nls/ja/sample.js
@@ -0,0 +1,13 @@
+define(
+//begin v1.x content
+({
+	"MINUTES": "%1 分",
+	"Second": "秒",
+	"Day of the Week": "曜日",
+	"Sunday": "日曜日",
+	"Monday": "月曜日",
+	"ON": "オン",
+	"OFF": "オフ"
+})
+//end v1.x content
+);
diff --git a/dojox/mobile/tests/nls/sample.js b/dojox/mobile/tests/nls/sample.js
new file mode 100644
index 0000000..2fbf618
--- /dev/null
+++ b/dojox/mobile/tests/nls/sample.js
@@ -0,0 +1,14 @@
+define({ root:
+//begin v1.x content
+({
+	"MINUTES": "%1 Minute(s)"
+
+	// In this example, English resources are not necessary,
+	// because English strings are used as resource keys,
+	// and they are automatically used as fall back values.
+})
+//end v1.x content
+,
+"ja": true,
+"it": true
+});
diff --git a/dojox/mobile/tests/progressBarAnim.gif b/dojox/mobile/tests/progressBarAnim.gif
new file mode 100644
index 0000000..30c0d9d
Binary files /dev/null and b/dojox/mobile/tests/progressBarAnim.gif differ
diff --git a/dojox/mobile/tests/robot/Animation.html b/dojox/mobile/tests/robot/Animation.html
new file mode 100644
index 0000000..bf15bbb
--- /dev/null
+++ b/dojox/mobile/tests/robot/Animation.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>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"
+			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;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dojox/mobile/tests/robot/Animation2.html b/dojox/mobile/tests/robot/Animation2.html
new file mode 100644
index 0000000..bf15bbb
--- /dev/null
+++ b/dojox/mobile/tests/robot/Animation2.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>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"
+			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;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dojox/mobile/tests/robot/ButtonList.html b/dojox/mobile/tests/robot/ButtonList.html
new file mode 100644
index 0000000..c56183d
--- /dev/null
+++ b/dojox/mobile/tests/robot/ButtonList.html
@@ -0,0 +1,50 @@
+<!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"
+			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;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dojox/mobile/tests/robot/ButtonList2.html b/dojox/mobile/tests/robot/ButtonList2.html
new file mode 100644
index 0000000..b9ecd49
--- /dev/null
+++ b/dojox/mobile/tests/robot/ButtonList2.html
@@ -0,0 +1,50 @@
+<!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"
+			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;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dojox/mobile/tests/robot/Flippable.html b/dojox/mobile/tests/robot/Flippable.html
new file mode 100644
index 0000000..e16bda7
--- /dev/null
+++ b/dojox/mobile/tests/robot/Flippable.html
@@ -0,0 +1,56 @@
+<!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"
+			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-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;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dojox/mobile/tests/robot/Icon.html b/dojox/mobile/tests/robot/Icon.html
new file mode 100644
index 0000000..fc2b0d8
--- /dev/null
+++ b/dojox/mobile/tests/robot/Icon.html
@@ -0,0 +1,50 @@
+<!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"
+			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-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;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dojox/mobile/tests/robot/Icon2.html b/dojox/mobile/tests/robot/Icon2.html
new file mode 100644
index 0000000..2ff50a0
--- /dev/null
+++ b/dojox/mobile/tests/robot/Icon2.html
@@ -0,0 +1,50 @@
+<!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"
+			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_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;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dojox/mobile/tests/robot/ListItem.html b/dojox/mobile/tests/robot/ListItem.html
new file mode 100644
index 0000000..d74ef80
--- /dev/null
+++ b/dojox/mobile/tests/robot/ListItem.html
@@ -0,0 +1,47 @@
+<!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"
+			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_ajax-html.html");
+
+				doh.register("dojox.mobile.ListItem mouse tests", [
+					{
+						name: "ListItem mouse tests",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt(dojo.query(".mblListItemTextBox", dijit.byId("dojox_mobile_ListItem_0").domNode)[0], 2000);
+							doh.robot.mouseClick({left: true}, 500);
+
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("view1.html", dijit.byId("dojox_mobile_Heading_1").get("label"));
+							}), 500);
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dojox/mobile/tests/robot/ScrollableView.html b/dojox/mobile/tests/robot/ScrollableView.html
new file mode 100644
index 0000000..e75e2e4
--- /dev/null
+++ b/dojox/mobile/tests/robot/ScrollableView.html
@@ -0,0 +1,54 @@
+<!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"
+			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-ScrollableView-v.html");
+
+				doh.register("dojox.mobile.ScrollableView mouse tests", [
+					{
+						name: "ScrollableView mouse tests",
+						timeout: 40000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt(dijit.byId("foo").domNode, 1000,100,100,300);
+							doh.robot.mousePress({left: true}, 500);
+
+							doh.robot.mouseMoveAt(dijit.byId("foo").domNode, 1000,100,100,50);
+							doh.robot.mouseRelease({left: true}, 0,5000);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								var pos = dijit.byId("foo").getPos();
+								doh.assertTrue(pos.y<0);
+							}), 500);
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dojox/mobile/tests/robot/ScrollableView2.html b/dojox/mobile/tests/robot/ScrollableView2.html
new file mode 100644
index 0000000..d14dd71
--- /dev/null
+++ b/dojox/mobile/tests/robot/ScrollableView2.html
@@ -0,0 +1,54 @@
+<!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"
+			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-ScrollableView-v-vh-af.html");
+
+				doh.register("dojox.mobile.ScrollableView mouse tests", [
+					{
+						name: "ScrollableView mouse tests",
+						timeout: 40000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt(dijit.byId("foo").domNode, 1000,100,100,150);
+							doh.robot.mousePress({left: true}, 500);
+
+							doh.robot.mouseMoveAt(dijit.byId("foo").domNode, 1000,100,100,50);
+							doh.robot.mouseRelease({left: true}, 0,5000);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								var pos = dijit.byId("foo").getPos();
+								doh.assertTrue(pos.y<0);
+							}), 500);
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dojox/mobile/tests/robot/ScrollableView3.html b/dojox/mobile/tests/robot/ScrollableView3.html
new file mode 100644
index 0000000..1de9573
--- /dev/null
+++ b/dojox/mobile/tests/robot/ScrollableView3.html
@@ -0,0 +1,54 @@
+<!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"
+			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-ScrollableView-v-vh-vf.html");
+
+				doh.register("dojox.mobile.ScrollableView mouse tests", [
+					{
+						name: "ScrollableView mouse tests",
+						timeout: 40000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt(dijit.byId("foo").domNode, 1000,100,100,150);
+							doh.robot.mousePress({left: true}, 500);
+
+							doh.robot.mouseMoveAt(dijit.byId("foo").domNode, 1000,100,100,50);
+							doh.robot.mouseRelease({left: true}, 0,5000);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								var pos = dijit.byId("foo").getPos();
+								doh.assertTrue(pos.y<0);
+							}), 500);
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dojox/mobile/tests/robot/Settings.html b/dojox/mobile/tests/robot/Settings.html
new file mode 100644
index 0000000..28ac414
--- /dev/null
+++ b/dojox/mobile/tests/robot/Settings.html
@@ -0,0 +1,119 @@
+<!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"
+			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_iPad-Settings.html");
+
+				doh.register("dojox.mobile.Settings mouse tests", [
+					{
+						name: "Settings mouse tests",
+						timeout: 40000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_20").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_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.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_23").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_24").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_25").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_26").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_27").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_28").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_29").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_30").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.sequence(d.getTestCallback(function(){
+								doh.assertEqual("General",  dijit.byId("dojox_mobile_Heading_1").get("label"));
+							}), 500);
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dojox/mobile/tests/robot/Switch.html b/dojox/mobile/tests/robot/Switch.html
new file mode 100644
index 0000000..daf458b
--- /dev/null
+++ b/dojox/mobile/tests/robot/Switch.html
@@ -0,0 +1,50 @@
+<!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"
+			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-Switch.html");
+
+				doh.register("dojox.mobile.Switch mouse tests", [
+					{
+						name: "Switch mouse tests",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt(dojo.query(".mblSwitchKnob", dijit.byId("dojox_mobile_Switch_0").domNode)[0], 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(dojo.query(".mblSwitchKnob", dijit.byId("dojox_mobile_Switch_1").domNode)[0], 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"));
+							}), 500);
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dojox/mobile/tests/robot/Switch2.html b/dojox/mobile/tests/robot/Switch2.html
new file mode 100644
index 0000000..aba8a98
--- /dev/null
+++ b/dojox/mobile/tests/robot/Switch2.html
@@ -0,0 +1,50 @@
+<!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"
+			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-Switch.html");
+
+				doh.register("dojox.mobile.Switch mouse tests", [
+					{
+						name: "Switch mouse tests",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt(dojo.query(".mblSwitchKnob", dijit.byId("dojox_mobile_Switch_0").domNode)[0], 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(dojo.query(".mblSwitchKnob", dijit.byId("dojox_mobile_Switch_1").domNode)[0], 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"));
+							}), 500);
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dojox/mobile/tests/robot/TabBar.html b/dojox/mobile/tests/robot/TabBar.html
new file mode 100644
index 0000000..ae617b0
--- /dev/null
+++ b/dojox/mobile/tests/robot/TabBar.html
@@ -0,0 +1,65 @@
+<!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"
+			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.require("dojox.mobile.TabBar");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot("../test_iPhone-TabBar.html");
+
+				doh.register("dojox.mobile.TabBar mouse tests", [
+					{
+						name: "TabBar mouse tests",
+						timeout: 15000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_0").domNode)[1], 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_0").domNode)[2], 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_0").domNode)[0], 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_1").domNode)[1], 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_1").domNode)[0], 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_1").domNode)[2], 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);
+							}), 1000);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dojox/mobile/tests/robot/TabBar2.html b/dojox/mobile/tests/robot/TabBar2.html
new file mode 100644
index 0000000..8cfa227
--- /dev/null
+++ b/dojox/mobile/tests/robot/TabBar2.html
@@ -0,0 +1,65 @@
+<!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"
+			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.require("dojox.mobile.TabBar");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot("../test_Android-TabBar.html");
+
+				doh.register("dojox.mobile.TabBar mouse tests", [
+					{
+						name: "TabBar mouse tests",
+						timeout: 15000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_0").domNode)[1], 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_0").domNode)[2], 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_0").domNode)[0], 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_1").domNode)[1], 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_1").domNode)[0], 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_1").domNode)[2], 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);
+							}), 1000);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dojox/mobile/tests/robot/module.js b/dojox/mobile/tests/robot/module.js
new file mode 100644
index 0000000..2db94d1
--- /dev/null
+++ b/dojox/mobile/tests/robot/module.js
@@ -0,0 +1,28 @@
+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.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);
+		doh.registerUrl("dojox.mobile.tests.robot.switch", dojo.moduleUrl("dojox.mobile", "tests/robot/Switch2.html"), 999999);
+		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.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.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);
+		}
+	}
+}catch(e){
+	doh.debug(e);
+}
diff --git a/dojox/mobile/tests/robot/runTests.html b/dojox/mobile/tests/robot/runTests.html
new file mode 100644
index 0000000..a61dcaf
--- /dev/null
+++ b/dojox/mobile/tests/robot/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.robot.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/runTests.html b/dojox/mobile/tests/runTests.html
new file mode 100644
index 0000000..3860429
--- /dev/null
+++ b/dojox/mobile/tests/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.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/settings.json b/dojox/mobile/tests/settings.json
new file mode 100644
index 0000000..d34293a
--- /dev/null
+++ b/dojox/mobile/tests/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/simpleApp/app/assistants/main-assistant.js b/dojox/mobile/tests/simpleApp/app/assistants/main-assistant.js
index 15c26af..bbd7ee6 100644
--- a/dojox/mobile/tests/simpleApp/app/assistants/main-assistant.js
+++ b/dojox/mobile/tests/simpleApp/app/assistants/main-assistant.js
@@ -1,4 +1,3 @@
-dojo.provide("MainAssistant");
 dojo.require("dojox.mobile.app.SceneAssistant");
 
 dojo.declare("MainAssistant", dojox.mobile.app.SceneAssistant, {
diff --git a/dojox/mobile/tests/simpleApp/index.html b/dojox/mobile/tests/simpleApp/index.html
index 2bfe9d1..213c094 100644
--- a/dojox/mobile/tests/simpleApp/index.html
+++ b/dojox/mobile/tests/simpleApp/index.html
@@ -13,12 +13,8 @@
 		</style>
 		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: false"></script>
     
-		<!-- 
-			Include the files directly, as some mobile operating systems do not
-			allow synchronous XHR, and therefore break dojo.require
-		-->
-		<script type="text/javascript" src="../../../mobile/app.js"></script>
 		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojox.mobile.app");
 			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.app.compat");
       
 			var appInfo = {
diff --git a/dojox/mobile/tests/simpleListApp/app/assistants/main-assistant.js b/dojox/mobile/tests/simpleListApp/app/assistants/main-assistant.js
index 584a9ba..f7aac68 100644
--- a/dojox/mobile/tests/simpleListApp/app/assistants/main-assistant.js
+++ b/dojox/mobile/tests/simpleListApp/app/assistants/main-assistant.js
@@ -1,4 +1,3 @@
-dojo.provide("MainAssistant");
 dojo.require("dojox.mobile.app.SceneAssistant");
 
 dojo.declare("MainAssistant", dojox.mobile.app.SceneAssistant, {
diff --git a/dojox/mobile/tests/simpleListApp/index.html b/dojox/mobile/tests/simpleListApp/index.html
index 195b777..5640c38 100644
--- a/dojox/mobile/tests/simpleListApp/index.html
+++ b/dojox/mobile/tests/simpleListApp/index.html
@@ -13,12 +13,8 @@
 		</style>
 		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: false"></script>
     
-		<!-- 
-			Include the files directly, as some mobile operating systems do not
-			allow synchronous XHR, and therefore break dojo.require
-		-->
-		<script type="text/javascript" src="../../../mobile/app.js"></script>
 		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojox.mobile.app");
 			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.app.compat");
       
 			var appInfo = {
diff --git a/dojox/mobile/tests/sliderHthumb.png b/dojox/mobile/tests/sliderHthumb.png
new file mode 100644
index 0000000..485073a
Binary files /dev/null and b/dojox/mobile/tests/sliderHthumb.png differ
diff --git a/dojox/mobile/tests/sliderVthumb.png b/dojox/mobile/tests/sliderVthumb.png
new file mode 100644
index 0000000..a4720ee
Binary files /dev/null and b/dojox/mobile/tests/sliderVthumb.png differ
diff --git a/dojox/mobile/tests/test_Accessibility_Support.html b/dojox/mobile/tests/test_Accessibility_Support.html
new file mode 100644
index 0000000..552e343
--- /dev/null
+++ b/dojox/mobile/tests/test_Accessibility_Support.html
@@ -0,0 +1,116 @@
+<!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_Android-ButtonList.html b/dojox/mobile/tests/test_Android-ButtonList.html
index 5a70c0c..a24b92f 100644
--- a/dojox/mobile/tests/test_Android-ButtonList.html
+++ b/dojox/mobile/tests/test_Android-ButtonList.html
@@ -6,54 +6,48 @@
 		<meta name="apple-mobile-web-app-capable" content="yes" />
 
 		<title>Button List</title>
-		<link href="../themes/android/android.css" rel="stylesheet"></link>
-		<link href="../themes/buttons.css" rel="stylesheet"></link>
+		<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("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-			dojo.addOnLoad(function(){
+			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);
+				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 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));
+				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>
+	<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="mblCheckOffButton">
+			    <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="mblCheckOnButton">
+			    <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)
diff --git a/dojox/mobile/tests/test_Android-EdgeToEdge.html b/dojox/mobile/tests/test_Android-EdgeToEdge.html
index 69456b7..a096bed 100644
--- a/dojox/mobile/tests/test_Android-EdgeToEdge.html
+++ b/dojox/mobile/tests/test_Android-EdgeToEdge.html
@@ -5,19 +5,18 @@
 		<meta name="viewport" content="width=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/android.css" rel="stylesheet"></link>
+		<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("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			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>
+	<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">
@@ -37,7 +36,6 @@
 		<div id="hello" dojoType="dojox.mobile.View">
 			<h1 dojoType="dojox.mobile.Heading">Hello</h1>
 			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
 				<li dojoType="dojox.mobile.ListItem" moveTo="settings">
 					Hello
 				</li>
diff --git a/dojox/mobile/tests/test_Android-EdgeToEdgeCategory.html b/dojox/mobile/tests/test_Android-EdgeToEdgeCategory.html
index 477e2ee..7201f86 100644
--- a/dojox/mobile/tests/test_Android-EdgeToEdgeCategory.html
+++ b/dojox/mobile/tests/test_Android-EdgeToEdgeCategory.html
@@ -4,17 +4,16 @@
 		<meta name="viewport" content="width=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/android.css" rel="stylesheet"></link>
+		<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("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			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>
+	<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>
diff --git a/dojox/mobile/tests/test_Android-Heading.html b/dojox/mobile/tests/test_Android-Heading.html
index 1d056ac..58f6ae9 100644
--- a/dojox/mobile/tests/test_Android-Heading.html
+++ b/dojox/mobile/tests/test_Android-Heading.html
@@ -4,55 +4,54 @@
 		<meta name="viewport" content="width=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>
-		<link href="../themes/domButtons.css" rel="stylesheet"></link>
+		<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("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.addOnLoad(function(){
+			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(){
-					alert(this.label + " button was clicked");
+					console.log(this.label + " button was clicked");
 				});
 			});
 		</script>
 	</head>
-	<body>
+	<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</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 style="color:white;">Heading with buttons</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">Edit</div>
-			<div dojoType="dojox.mobile.ToolBarButton" class="mblDomButton mblDomButtonPlus_2" style="float:right;" onclick="alert('+ was clicked')"></div>
+			<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">Edit</div>
-			<div dojoType="dojox.mobile.ToolBarButton" class="mblDomButton mblDomButtonPlus_2" style="float:right;"></div>
+			<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"></div>
+			<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">
-			<!-- dummy hidden button to center the label -->
-			<div dojoType="dojox.mobile.ToolBarButton" label="Update All" style="visibility:hidden;"></div>
 			<div dojoType="dojox.mobile.ToolBarButton" label="Update All" style="float:right;"></div>
 		</h1><br>
 
@@ -71,9 +70,54 @@
 		<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="mblDomButton mblDomButtonPlus_2" moveTo="view3" style="float:right;"></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
index c71dfc8..e17eaee 100755
--- a/dojox/mobile/tests/test_Android-Icon.html
+++ b/dojox/mobile/tests/test_Android-Icon.html
@@ -4,8 +4,8 @@
 		<meta name="viewport" content="width=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/android.css" rel="stylesheet"></link>
-		<link href="../themes/buttons.css" rel="stylesheet"></link>
+		<link href="../themes/android/base.css" rel="stylesheet">
+		<link href="../themes/android/IconContainer.css" rel="stylesheet">
 
 		<style>
 			.box {
@@ -20,14 +20,13 @@
 		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
 		</script>
 	</head>
-	<body>
+	<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">
diff --git a/dojox/mobile/tests/test_Android-RoundRectList.html b/dojox/mobile/tests/test_Android-RoundRectList.html
index 3dac089..9f62148 100755
--- a/dojox/mobile/tests/test_Android-RoundRectList.html
+++ b/dojox/mobile/tests/test_Android-RoundRectList.html
@@ -4,18 +4,17 @@
 		<meta name="viewport" content="width=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/android.css" rel="stylesheet"></link>
+		<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("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			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>
+	<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>
diff --git a/dojox/mobile/tests/test_Android-Settings.html b/dojox/mobile/tests/test_Android-Settings.html
index e45ba39..bcc05a7 100644
--- a/dojox/mobile/tests/test_Android-Settings.html
+++ b/dojox/mobile/tests/test_Android-Settings.html
@@ -4,17 +4,17 @@
 		<meta name="viewport" content="width=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/android.css" rel="stylesheet"></link>
-		<link href="../themes/buttons.css" rel="stylesheet"></link>
+		<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("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.addOnLoad(function(){
+			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];
@@ -38,7 +38,7 @@
 			}
 		</script>
 	</head>
-	<body>
+	<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">
@@ -78,18 +78,19 @@
 				<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="mblCheckOffButton">
+				<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="mblCheckOnButton">
+				<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)
diff --git a/dojox/mobile/tests/test_Android-Switch.html b/dojox/mobile/tests/test_Android-Switch.html
index 8603cfb..3a983cd 100644
--- a/dojox/mobile/tests/test_Android-Switch.html
+++ b/dojox/mobile/tests/test_Android-Switch.html
@@ -4,20 +4,73 @@
 		<meta name="viewport" content="width=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/android.css" rel="stylesheet"></link>
+		<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("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			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="padding:15px;visibility:visible">
-		<div dojoType="dojox.mobile.Switch" value="off"></div>
-		<hr>
-		<div dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
+	<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
index 39447a3..a02bdef 100644
--- a/dojox/mobile/tests/test_Android-TabBar.html
+++ b/dojox/mobile/tests/test_Android-TabBar.html
@@ -4,17 +4,17 @@
 		<meta name="viewport" content="width=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/android.css" rel="stylesheet"></link>
+		<link href="../themes/android/base.css" rel="stylesheet">
+		<link href="../themes/android/TabBar.css" rel="stylesheet">
 		<style>
 		.label {
-			color: white;
 			font-family: "Helvetica Neue", Helvetica;
 			font-size: 13px;
 			margin-top: 20px;
 		}
 		.view {
 			font-size: 30px;
-			margin-top: 30px;
+			padding-top: 30px;
 			text-align: center;
 		}
 		</style>
@@ -22,14 +22,13 @@
 		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
 		</script>
 	</head>
-	<body>
+	<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>
@@ -37,14 +36,14 @@
 			<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<br>(style is not optimized for Android yet)</div>
+		<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)<br>(style is not optimized for Android yet)</div>
+		<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>
diff --git a/dojox/mobile/tests/test_Android-TabContainer.html b/dojox/mobile/tests/test_Android-TabContainer.html
deleted file mode 100644
index 4cb94fb..0000000
--- a/dojox/mobile/tests/test_Android-TabContainer.html
+++ /dev/null
@@ -1,144 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<!--
-	Deprecated: Use dojox.mobile.TabBar instead.
-	See test_iPhone-TabBar-seg-grouped.html for an equivalent example.
--->
-	<head>
-		<meta name="viewport" content="width=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 Container (deprecated)</title>
-		<link href="../themes/android/android.css" rel="stylesheet"></link>
-		<style>
-		.lnk {
-			font-size: 17px;
-			color: cyan;
-			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.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.TabContainer");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		</script>
-	</head>
-	<body>
-		<div id="general" dojoType="dojox.mobile.View" selected="true">
-			<div dojoType="dojox.mobile.TabContainer">
-				<div dojoType="dojox.mobile.TabPane" label="Phone" icon="images/a-icon-10.png">
-					<ul id="list1" dojoType="dojox.mobile.EdgeToEdgeList">
-						<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-							<table>
-								<tr>
-									<td><img src="images/a-icon-2-41x41.png"></td>
-							        <td>
-								        <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-								        Sarah Connor Hardcover<br>
-								        Eligible for FREE Super Saver Shipping
-							        </td>
-								</tr>
-							</table>
-						</li>
-						<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-							<table>
-								<tr>
-									<td><img src="images/a-icon-2-41x41.png"></td>
-							        <td>
-								        <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-								        Martin Parker Hardcover<br>
-								        Eligible for FREE Super Saver Shipping<br>
-							        </td>
-								</tr>
-							</table>
-						</li>
-						<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-							<table>
-								<tr>
-									<td><img src="images/a-icon-2-41x41.png"></td>
-							        <td>
-								        <a href="#" class="lnk">Total Solar Eclipse</a><br>
-								        Steven Young Hardcover<br>
-								        Eligible for FREE Super Saver Shipping<br>
-							        </td>
-								</tr>
-							</table>
-						</li>
-						<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-							<table>
-								<tr>
-									<td><img src="images/a-icon-2-41x41.png"></td>
-							        <td>
-								        <a href="#" class="lnk">The History of Java Coffee</a><br>
-								        Marco Rodriguez Hardcover<br>
-								        Eligible for FREE Super Saver Shipping<br>
-							        </td>
-								</tr>
-							</table>
-						</li>
-						<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-							<table>
-								<tr>
-									<td><img src="images/a-icon-2-41x41.png"></td>
-							        <td>
-								        <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-								        Melissa Morgan Hardcover<br>
-								        Eligible for FREE Super Saver Shipping<br>
-							        </td>
-								</tr>
-							</table>
-						</li>
-					</ul>
-				</div>
-
-				<div dojoType="dojox.mobile.TabPane" label="Call log" icon="images/a-icon-11.png">
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-4.png" moveTo="hello">
-							Sounds
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-4.png" moveTo="hello">
-							Brightness
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-4.png" moveTo="hello">
-							Wallpaper
-						</li>
-					</ul>
-				</div>
-
-				<div dojoType="dojox.mobile.TabPane" label="Contacts" icon="images/a-icon-12.png">
-					<h1 dojoType="dojox.mobile.Heading">J</h1>
-					<ul dojoType="dojox.mobile.EdgeToEdgeList">
-						<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-4.png" moveTo="hello">
-							John Doe
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-4.png" moveTo="hello">
-							John Smith
-						</li>
-					</ul>
-				</div>
-
-				<div dojoType="dojox.mobile.TabPane" label="Farovites" icon="images/a-icon-13.png">
-					<div style="margin:16px;font-size:20px;color:#949694">
-					  You don't have any favorites.
-					</div>
-				</div>
-			</div>
-		</div>
-
-		<div id="hello" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading">Hello</h1>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="general">
-					Hello
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="general">
-					Carrier
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Android-VariableHeightList.html b/dojox/mobile/tests/test_Android-VariableHeightList.html
index aa6fed4..b8f23e2 100755
--- a/dojox/mobile/tests/test_Android-VariableHeightList.html
+++ b/dojox/mobile/tests/test_Android-VariableHeightList.html
@@ -4,7 +4,7 @@
 		<meta name="viewport" content="width=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/android.css" rel="stylesheet"></link>
+		<link href="../themes/android/base.css" rel="stylesheet">
 		<style>
 		.content {
 			padding:0px 10px;
@@ -43,14 +43,12 @@
 		<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("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>
+	<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>
diff --git a/dojox/mobile/tests/test_Animation.html b/dojox/mobile/tests/test_Animation.html
new file mode 100755
index 0000000..0973164
--- /dev/null
+++ b/dojox/mobile/tests/test_Animation.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>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_BlackBerry-EdgeToEdgeList.html b/dojox/mobile/tests/test_BlackBerry-EdgeToEdgeList.html
new file mode 100755
index 0000000..d7841ca
--- /dev/null
+++ b/dojox/mobile/tests/test_BlackBerry-EdgeToEdgeList.html
@@ -0,0 +1,59 @@
+<!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
new file mode 100755
index 0000000..eff7d53
--- /dev/null
+++ b/dojox/mobile/tests/test_BlackBerry-Heading.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/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
new file mode 100755
index 0000000..f879b99
--- /dev/null
+++ b/dojox/mobile/tests/test_BlackBerry-IconContainer.html
@@ -0,0 +1,57 @@
+<!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
new file mode 100755
index 0000000..6a7d3a3
--- /dev/null
+++ b/dojox/mobile/tests/test_BlackBerry-RoundRectList.html
@@ -0,0 +1,59 @@
+<!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
new file mode 100755
index 0000000..1bbdacf
--- /dev/null
+++ b/dojox/mobile/tests/test_BlackBerry-ScrollableView.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 name="viewport" content="width=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
new file mode 100755
index 0000000..0d71162
--- /dev/null
+++ b/dojox/mobile/tests/test_BlackBerry-Settings.html
@@ -0,0 +1,111 @@
+<!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
new file mode 100755
index 0000000..7d0ddfa
--- /dev/null
+++ b/dojox/mobile/tests/test_BlackBerry-SwapView.html
@@ -0,0 +1,92 @@
+<!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
new file mode 100755
index 0000000..44da622
--- /dev/null
+++ b/dojox/mobile/tests/test_BlackBerry-Switch.html
@@ -0,0 +1,76 @@
+<!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
new file mode 100755
index 0000000..8a66a52
--- /dev/null
+++ b/dojox/mobile/tests/test_BlackBerry-TabBar.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>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
new file mode 100755
index 0000000..e293dda
--- /dev/null
+++ b/dojox/mobile/tests/test_BlackBerry-VariableHeightList.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"/>
+		<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_Carousel-async.html b/dojox/mobile/tests/test_Carousel-async.html
new file mode 100644
index 0000000..dfbf69e
--- /dev/null
+++ b/dojox/mobile/tests/test_Carousel-async.html
@@ -0,0 +1,58 @@
+<!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-slideshow.html b/dojox/mobile/tests/test_Carousel-slideshow.html
new file mode 100644
index 0000000..e189eb3
--- /dev/null
+++ b/dojox/mobile/tests/test_Carousel-slideshow.html
@@ -0,0 +1,40 @@
+<!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
new file mode 100644
index 0000000..783d958
--- /dev/null
+++ b/dojox/mobile/tests/test_Carousel.html
@@ -0,0 +1,49 @@
+<!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>
+		<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 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>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_ComboBox.html b/dojox/mobile/tests/test_ComboBox.html
new file mode 100644
index 0000000..d9ce66a
--- /dev/null
+++ b/dojox/mobile/tests/test_ComboBox.html
@@ -0,0 +1,212 @@
+<!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 tests</title>
+
+	<style type="text/css">
+		@import "../themes/iphone/TextBox.css";
+		@import "../themes/iphone/ComboBox.css";
+	</style>
+
+	<script type="text/javascript" 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 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"});
+						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;">
+	<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">attributes</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">events</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>
+		</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/test_ContentPane.html b/dojox/mobile/tests/test_ContentPane.html
new file mode 100644
index 0000000..573cd3d
--- /dev/null
+++ b/dojox/mobile/tests/test_ContentPane.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>ContentPane</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("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
+				});
+				dom.innerHTML = "DOM Tree";
+				dijit.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>
+
+			<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 dojoType="dojox.mobile.RoundRectCategory">Pane2</h2>
+			<div id="pane2" dojoType="dojox.mobile.ContentPane"
+			     href="fragment1.html"></div>
+
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Pane3</h2>
+			<div id="pane3" dojoType="dojox.mobile.ContentPane"></div>
+
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Pane4</h2>
+			<div id="pane4" dojoType="dojox.mobile.ContentPane"></div>
+
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Pane5</h2>
+			<div id="pane5" dojoType="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
new file mode 100644
index 0000000..5d82fe2
--- /dev/null
+++ b/dojox/mobile/tests/test_Custom-EdgeToEdgeList.html
@@ -0,0 +1,59 @@
+<!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
new file mode 100644
index 0000000..25deac8
--- /dev/null
+++ b/dojox/mobile/tests/test_Custom-FormControls.html
@@ -0,0 +1,173 @@
+<!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
new file mode 100644
index 0000000..e9c03a7
--- /dev/null
+++ b/dojox/mobile/tests/test_Custom-Heading.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>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
new file mode 100644
index 0000000..081b90f
--- /dev/null
+++ b/dojox/mobile/tests/test_Custom-Icon.html
@@ -0,0 +1,58 @@
+<!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
new file mode 100644
index 0000000..0c3232f
--- /dev/null
+++ b/dojox/mobile/tests/test_Custom-Opener.html
@@ -0,0 +1,156 @@
+<!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
new file mode 100644
index 0000000..a1968d8
--- /dev/null
+++ b/dojox/mobile/tests/test_Custom-RoundRectList.html
@@ -0,0 +1,59 @@
+<!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
new file mode 100644
index 0000000..518365a
--- /dev/null
+++ b/dojox/mobile/tests/test_Custom-Settings.html
@@ -0,0 +1,167 @@
+<!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
new file mode 100644
index 0000000..70ae2b2
--- /dev/null
+++ b/dojox/mobile/tests/test_Custom-TabBar.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>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
new file mode 100644
index 0000000..c56f468
--- /dev/null
+++ b/dojox/mobile/tests/test_Custom-Tooltip.html
@@ -0,0 +1,117 @@
+<!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
new file mode 100644
index 0000000..757e457
--- /dev/null
+++ b/dojox/mobile/tests/test_Custom-css-sprite.html
@@ -0,0 +1,170 @@
+<!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
new file mode 100644
index 0000000..e4a4fed
--- /dev/null
+++ b/dojox/mobile/tests/test_Custom-list-domButtons.html
@@ -0,0 +1,227 @@
+<!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_EdgeToEdgeDataList.html b/dojox/mobile/tests/test_EdgeToEdgeDataList.html
new file mode 100644
index 0000000..df4ec46
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeDataList.html
@@ -0,0 +1,64 @@
+<!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("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");
+			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>
+	</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>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeList-check.html b/dojox/mobile/tests/test_EdgeToEdgeList-check.html
new file mode 100644
index 0000000..4ae56e6
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeList-check.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>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");
+				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);
+			});
+		</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">
+
+			<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>
+
+			<div id="msgArea" style="margin-left:10px;"></div><br><br>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_FixedSplitter-H2-prog.html b/dojox/mobile/tests/test_FixedSplitter-H2-prog.html
index 91b8ae3..a46763a 100644
--- a/dojox/mobile/tests/test_FixedSplitter-H2-prog.html
+++ b/dojox/mobile/tests/test_FixedSplitter-H2-prog.html
@@ -3,7 +3,7 @@
 	<head>
 		<title>FixedSplitter Test</title>
 		<style type="text/css">
-			@import "../themes/FixedSplitter.css";
+			@import "../themes/common/FixedSplitter.css";
 			html, body{
 				width: 100%;
 				height: 100%;
@@ -18,17 +18,24 @@
 		<script language="JavaScript" type="text/javascript">
 			dojo.require("dojo.parser");
 			dojo.require("dojox.mobile.FixedSplitter");
-			dojo.addOnLoad(function(){
-					var w = new dojox.mobile.FixedSplitter({orientation:"H"}, dojo.byId("container"));
-					dojo.create("div", {
-						style: "background-color:yellow;width:200px;",
+			dojo.ready(function(){
+					var w = new dojox.mobile.FixedSplitter({
+						orientation: "H"
+					}, dojo.byId("container"));
+					w.startup();
+
+					var p0 = new dojox.mobile.FixedSplitterPane({
 						innerHTML: "pane #1 (width=200px)"
-					}, w.containerNode);
-					dojo.create("div", {
-						style:"background-color:pink;",
+					});
+					p0.domNode.style.backgroundColor = "yellow";
+					p0.domNode.style.width = "200px";
+					w.addChild(p0);
+
+					var p1 = new dojox.mobile.FixedSplitterPane({
 						innerHTML: "pane #2"
-					}, w.containerNode);
-					w.startup();
+					});
+					p1.domNode.style.backgroundColor = "pink";
+					w.addChild(p1);
 			});
 		</script>
 	</head>
diff --git a/dojox/mobile/tests/test_FixedSplitter-H2.html b/dojox/mobile/tests/test_FixedSplitter-H2.html
index 4938ae7..4b224dc 100644
--- a/dojox/mobile/tests/test_FixedSplitter-H2.html
+++ b/dojox/mobile/tests/test_FixedSplitter-H2.html
@@ -3,7 +3,7 @@
 	<head>
 		<title>FixedSplitter Test</title>
 		<style type="text/css">
-			@import "../themes/FixedSplitter.css";
+			@import "../themes/common/FixedSplitter.css";
 			html, body{
 				width: 100%;
 				height: 100%;
@@ -12,9 +12,7 @@
 				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");
@@ -22,10 +20,10 @@
 	</head>
 	<body>
 		<div dojoType="dojox.mobile.FixedSplitter" orientation="H">
-			<div style="background-color:yellow;width:200px;">
+			<div dojoType="dojox.mobile.FixedSplitterPane" style="background-color:yellow;width:200px;">
 				pane #1 (width=200px)
 			</div>
-			<div style="background-color:pink;">
+			<div dojoType="dojox.mobile.FixedSplitterPane" style="background-color:pink;">
 				pane #2
 			</div>
 		</div>
diff --git a/dojox/mobile/tests/test_FixedSplitter-V2H2.html b/dojox/mobile/tests/test_FixedSplitter-V2H2.html
index fd8ca10..50be726 100644
--- a/dojox/mobile/tests/test_FixedSplitter-V2H2.html
+++ b/dojox/mobile/tests/test_FixedSplitter-V2H2.html
@@ -3,7 +3,7 @@
 	<head>
 		<title>FixedSplitter Test</title>
 		<style type="text/css">
-			@import "../themes/FixedSplitter.css";
+			@import "../themes/common/FixedSplitter.css";
 			html, body{
 				width: 100%;
 				height: 100%;
@@ -12,9 +12,7 @@
 				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");
@@ -22,15 +20,15 @@
 	</head>
 	<body>
 		<div dojoType="dojox.mobile.FixedSplitter" style="width:100%;height:100%;" orientation="V">
-			<div style="background-color:yellow;height:20%">
+			<div dojoType="dojox.mobile.FixedSplitterPane" style="background-color:yellow;height:20%">
 				pane #1
 			</div>
 
-			<div id="gomi" dojoType="dojox.mobile.FixedSplitter" style="width:100%;height:100%;" orientation="H">
-				<div style="background-color:pink;width:20%;">
+			<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 style="background-color:cyan;">
+				<div dojoType="dojox.mobile.FixedSplitterPane" style="background-color:cyan;">
 					pane #3
 				</div>
 			</div>
diff --git a/dojox/mobile/tests/test_FixedSplitter-V3.html b/dojox/mobile/tests/test_FixedSplitter-V3.html
index 2d79f3b..850774a 100644
--- a/dojox/mobile/tests/test_FixedSplitter-V3.html
+++ b/dojox/mobile/tests/test_FixedSplitter-V3.html
@@ -3,7 +3,7 @@
 	<head>
 		<title>FixedSplitter Test</title>
 		<style type="text/css">
-			@import "../themes/FixedSplitter.css";
+			@import "../themes/common/FixedSplitter.css";
 			html, body{
 				width: 100%;
 				height: 100%;
@@ -12,9 +12,7 @@
 				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");
@@ -22,13 +20,13 @@
 	</head>
 	<body>
 		<div dojoType="dojox.mobile.FixedSplitter" orientation="V">
-			<div style="background-color:cyan;height:200px;">
+			<div dojoType="dojox.mobile.FixedSplitterPane" style="background-color:cyan;height:200px;">
 				pane #1 (height=200px)
 			</div>
-			<div style="background-color:yellow;height:100px;border-bottom:1px solid black">
+			<div dojoType="dojox.mobile.FixedSplitterPane" style="background-color:yellow;height:100px;border-bottom:1px solid black">
 				pane #2 (height=100px)
 			</div>
-			<div style="background-color:pink;">
+			<div dojoType="dojox.mobile.FixedSplitterPane" style="background-color:pink;">
 				pane #3
 			</div>
 		</div>
diff --git a/dojox/mobile/tests/test_FormControls.html b/dojox/mobile/tests/test_FormControls.html
new file mode 100644
index 0000000..c414f53
--- /dev/null
+++ b/dojox/mobile/tests/test_FormControls.html
@@ -0,0 +1,173 @@
+<!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>
+
+		<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>
+
+		<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_Opener-ActionSheet-async.html b/dojox/mobile/tests/test_Opener-ActionSheet-async.html
new file mode 100644
index 0000000..603b881
--- /dev/null
+++ b/dojox/mobile/tests/test_Opener-ActionSheet-async.html
@@ -0,0 +1,91 @@
+<!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>Action Sheet Sample</title>
+	<style>
+		/* Tooltip styles */
+		.mblTooltip.mblOpener {
+			padding: 2px;
+			-webkit-box-shadow: 0 0 60px #808080;
+		}
+		.mblTooltip.mblOpener #cancel {
+			display: none;
+		}
+		.mblTooltip.mblOpener button {
+			margin: 4px;
+			width: 240px;
+			height: 40px;
+			-webkit-box-shadow: 0 1px 1px #343a4b;
+			font-size: 18px;
+			line-height: 38px;
+		}
+		/* Overlay styles */
+		.mblOverlay.mblOpener {
+			padding-top: 10px;
+			background-color: #60656f;
+			background-image: -webkit-gradient(linear, left top, left bottom, from(#a6abb4), to(#5b616c), color-stop(0.1, #7b808b), color-stop(0.1, #60656f));
+		}
+		.mblOverlay.mblOpener button {
+			margin: 5px;
+			width: 90%;
+			height: 44px;
+			border: 3px inset #3a3d43;
+			-webkit-border-radius: 12px;
+			-webkit-box-shadow: 0 1px 1px #787c84;
+			font-size: 18px;
+			line-height: 38px;
+		}
+		.mblOverlay.mblOpener #cancel {
+			margin: 15px 5px;
+			background-color: #293039; /* for non-webkit browser */
+			background-image: none; /* for non-webkit browser */
+			background-image: -webkit-gradient(linear, left top, left bottom, from(#6d7278), to(#383f49), color-stop(0.5, #343c44), color-stop(0.5, #293039));
+			color: white;
+		}
+		.dj_bb button { /* BB BoxShadow Workaround */
+			-webkit-box-shadow: none !important;
+		}
+	</style>
+	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, async:true"></script>
+	<script language="JavaScript" type="text/javascript">
+		require([
+			"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
+			"dojox/mobile/deviceTheme",	// This mobile app automatically changes it's theme to match devices
+			"dojox/mobile/Button",
+			"dojox/mobile/Opener"
+		]);
+
+		function clicked(id){
+			dijit.byId("actionSheet").hide();
+			var span = dojo.byId("msgArea");
+			span.innerHTML += """ + dojo.byId(id).innerHTML + "" button was clicked.";
+			setTimeout(function(){
+				span.innerHTML = "";
+			}, 2000);
+		}
+
+	</script>
+</head>
+<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>
+	<div id="msgArea" style="margin-top:5px;"></div>
+	</center>
+
+	<!-- Action Sheet -->
+	<div id="actionSheet" data-dojo-type="dojox.mobile.Opener">
+		<button id="Bookmark" dojoType="dojox.mobile.Button" onclick="clicked(this.id)">Add Bookmark</button><br>
+		<button id="HomeScreen" dojoType="dojox.mobile.Button" onclick="clicked(this.id)">Add to Home Screen</button><br>
+		<button id="MailLink" dojoType="dojox.mobile.Button" onclick="clicked(this.id)">Mail Link to this Page</button><br>
+		<button id="cancel" dojoType="dojox.mobile.Button" onclick="clicked(this.id)">Cancel</button>		
+	</div>
+	<!-- Action Sheet -->
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Opener-Calendar-async.html b/dojox/mobile/tests/test_Opener-Calendar-async.html
new file mode 100644
index 0000000..f403625
--- /dev/null
+++ b/dojox/mobile/tests/test_Opener-Calendar-async.html
@@ -0,0 +1,65 @@
+<!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-ColorPalette-async.html b/dojox/mobile/tests/test_Opener-ColorPalette-async.html
new file mode 100644
index 0000000..cd932c1
--- /dev/null
+++ b/dojox/mobile/tests/test_Opener-ColorPalette-async.html
@@ -0,0 +1,59 @@
+<!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-ColorPicker.html b/dojox/mobile/tests/test_Opener-ColorPicker.html
new file mode 100644
index 0000000..0250f16
--- /dev/null
+++ b/dojox/mobile/tests/test_Opener-ColorPicker.html
@@ -0,0 +1,58 @@
+<!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
new file mode 100644
index 0000000..900ba08
--- /dev/null
+++ b/dojox/mobile/tests/test_Opener-DateSpinWheel-async.html
@@ -0,0 +1,63 @@
+<!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-RoundSelectList-async.html b/dojox/mobile/tests/test_Opener-RoundSelectList-async.html
new file mode 100644
index 0000000..b791267
--- /dev/null
+++ b/dojox/mobile/tests/test_Opener-RoundSelectList-async.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>Opener-RoundSelectList</title>
+	<style>
+		.mblTooltip.mblOpener DIV[label='Cancel'] {
+			display: none;
+		}
+		.mblTooltip #header1 {
+			width: 300px;
+		}
+		.mblOverlay#listPicker {
+			height: 200px;
+		}
+	</style>
+	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, async: true"></script>
+
+	<script type="text/javascript">
+		var ringtone, listPicker, trim;
+		require([
+			"dojo/ready",			// ready
+			"dojo/_base/html",		// dojo.byId
+			"dojo/_base/lang",		// dojo.trim
+			"dijit/registry",		// 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/Opener",
+			"dojox/mobile/ScrollableView"
+		], function(ready, html, lang, registry){
+			ready(function(){
+				ringtone = html.byId('ringtone');
+				listPicker = registry.byId('listPicker');
+				trim = lang.trim;
+			});
+		});
+		var checkedItem = 'Marimba';
+
+		function getSelectedRingtone(node, accept){
+			if(accept === true){
+				ringtone.value = checkedItem || '';
+			}
+		}
+		function setSelectedRingtone(node){
+		// NOOP
+		}
+		function onCheck(item, checked){
+			setTimeout(function(){
+				if(checked){
+					checkedItem = trim(item.labelNode.innerText || item.labelNode.textContent || '');
+				}
+			}, 500);
+		}
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<table cellspacing="20" style="margin-top:100px;padding-bottom:1500px;z-index:9999;"><!-- scrollable for testing purposes -->
+	<tr>
+		<td style="text-align:right;font-weight:bold;z-index:9999;">Ringtone</td>
+		<td><input id="ringtone" readOnly value="" placeholder="Select a ringtone"
+			onclick="listPicker.show(this, ['above-centered','below-centered','after','before'])" /></td>
+	</tr>
+	</table>
+
+	<!-- if onBlur returns !false, then the popup is closed when a click event is received away from the popup -->
+	<!-- 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>
+		</h1>
+		<div dojoType="dojox.mobile.ScrollableView" selected="true" height="auto">
+			<ul id="list1" dojoType="dojox.mobile.RoundRectList" select="single" data-dojo-props="onCheckStateChanged:onCheck">
+				<li id="item1" dojoType="dojox.mobile.ListItem" checked="true">
+					Marimba
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Alarm
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Ascending
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Bark
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Bell Tower
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Blues
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Boing
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Crickets
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Digital
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Doorbell
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Duck
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Harp
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Motorcycle
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Old Car Horn
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Old Phone
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Piano Roll
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Pinball
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Robot
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Sci-Fi
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Sonar
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Strum
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Timba
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Time Passing
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Trill
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Xylophone
+				</li>
+			</ul>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Opener-SearchList-async.html b/dojox/mobile/tests/test_Opener-SearchList-async.html
new file mode 100644
index 0000000..0954ebd
--- /dev/null
+++ b/dojox/mobile/tests/test_Opener-SearchList-async.html
@@ -0,0 +1,130 @@
+<!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>Opener-SearchList</title>
+	<style>
+		.mblTooltip.mblOpener DIV[label='Done'],
+		.mblTooltip.mblOpener DIV[label='Cancel'] {
+			display: none;
+		}
+		#search1 {
+			height: 24px;
+			width: 300px;
+		}
+		.mblOverlay #search1 {
+			margin: 0 70px;
+			width: 160px;
+		}
+		.mblOverlay#listPicker {
+			height: 200px;
+		}
+	</style>
+	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, async:true"></script>
+
+	<script language="JavaScript" type="text/javascript">
+		require([
+			"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
+			"dojox/mobile/deviceTheme",	// This mobile app automatically changes it's theme to match devices
+			"dojox/mobile/Opener",
+			"dojox/mobile/ScrollableView"
+		]);
+
+		var checkedItem = 'Aaron Smith';
+
+		function getSelectedContact(node, accept){
+			if(accept === true){
+				dojo.byId('contact1').value = checkedItem || '';
+			}
+		}
+		function setSearch(node){
+		// NOOP: Set search input text
+		}
+		function onCheck(item, checked){
+			setTimeout(function(){
+				if(checked){
+					checkedItem = item.labelNode.innerText || dojo.trim(item.labelNode.textContent) || '';
+					if(dojo.hasClass(dijit.byId('listPicker').domNode, 'mblTooltip')){
+						dijit.byId('listPicker').hide(true); // Tooltip + selection = auto-hide
+					}
+				}
+			}, 500);
+		}
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<table cellspacing="20">
+	<tr>
+		<td style="text-align:right;">Contact:</td>
+		<td><input id="contact1" readOnly value="Aaron Smith" placeholder="Select a contact"
+			onclick="dijit.byId('listPicker').show(this, ['above-centered','below-centered','after','before'])" /></td>
+	</tr>
+	</table>
+
+	<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>
+			<input id="search1" type="search" results="5" autosave="myrecentcontactsearches" name="searchContacts" placeholder="Search" />
+		</h1>
+		<div dojoType="dojox.mobile.ScrollableView" selected="true" height="auto">
+			<ul id="list1" dojoType="dojox.mobile.EdgeToEdgeList" select="single" data-dojo-props="onCheckStateChanged:onCheck">
+			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">A</h2>
+				<li id="item1" dojoType="dojox.mobile.ListItem" checked="true">
+					Aaron Smith
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Adam Peller
+				</li>
+			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">J</h2>
+				<li dojoType="dojox.mobile.ListItem">
+					Jack Coleman
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					James Evans
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Jason Griffin
+				</li>
+			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">K</h2>
+				<li dojoType="dojox.mobile.ListItem">
+					Karen Hughes
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Kelly Perry
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Kevin Rivera
+				</li>
+			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">S</h2>
+				<li dojoType="dojox.mobile.ListItem">
+					Sam Jones
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Sandy Smith
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Susan Smith
+				</li>
+			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">T</h2>
+				<li dojoType="dojox.mobile.ListItem">
+					Tim Jones
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Tina Smith
+				</li>
+				<li dojoType="dojox.mobile.ListItem">
+					Tom Smith
+				</li>
+			</ul>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Overlay.html b/dojox/mobile/tests/test_Overlay.html
new file mode 100644
index 0000000..dcf3167
--- /dev/null
+++ b/dojox/mobile/tests/test_Overlay.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>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>
+
+		<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.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>
+		</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_RoundRectDataList.html b/dojox/mobile/tests/test_RoundRectDataList.html
new file mode 100644
index 0000000..ba27d5a
--- /dev/null
+++ b/dojox/mobile/tests/test_RoundRectDataList.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 name="viewport" content="width=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");
+
+			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>
+	</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>
+</html>
diff --git a/dojox/mobile/tests/test_RoundRectList-check.html b/dojox/mobile/tests/test_RoundRectList-check.html
new file mode 100644
index 0000000..7e8eefc
--- /dev/null
+++ b/dojox/mobile/tests/test_RoundRectList-check.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>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");
+				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);
+			});
+		</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>
+
+			<div id="msgArea" style="margin-left:10px;"></div><br><br>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableMixin-custom.html b/dojox/mobile/tests/test_ScrollableMixin-custom.html
index 710f387..8b18872 100644
--- a/dojox/mobile/tests/test_ScrollableMixin-custom.html
+++ b/dojox/mobile/tests/test_ScrollableMixin-custom.html
@@ -13,11 +13,12 @@
 			padding: 0px;
 		}
 		#foo {
+			position: relative;
 			height: 100%;
 			overflow: hidden;
 		}
 		#header1 {
-			position: absolute;
+			position: relative;
 			margin: 0px;
 			width: 100%;
 			top: 0px;
@@ -26,43 +27,35 @@
 		}
 			
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
+		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
-
-dojo.declare(
-	"dojox.mobile.ScrollablePane",
-	[dijit._WidgetBase, dojox.mobile._ScrollableMixin],
-{
-	buildRendering: function(){
-		this.inherited(arguments);
-		this.containerNode = dojo.doc.createElement("DIV");
-		this.containerNode.className = "mblScrollableViewContainer";
-		this.containerNode.style.backgroundColor = "yellow";
-		this.containerNode.style.border = "1px solid red";
-		this.containerNode.style.position = "absolute";
-		this.containerNode.style.width = "100%";
-			
-		for(var i = 0, idx = 0, len = this.srcNodeRef.childNodes.length; i < len; i++){
-			var c = this.srcNodeRef.childNodes[idx];
-			this.containerNode.appendChild(this.srcNodeRef.removeChild(c));
-		}
-		this.domNode.appendChild(this.containerNode);
-	}
-});
+			dojo.declare("dojox.mobile.ScrollablePane",
+				[dijit._WidgetBase, dojox.mobile._ScrollableMixin, dijit._Container, dijit._Contained],{
+				buildRendering: function(){
+					this.inherited(arguments);
+					this.containerNode = dojo.doc.createElement("DIV");
+					this.containerNode.className = "mblScrollableViewContainer";
+					this.containerNode.style.backgroundColor = "yellow";
+					this.containerNode.style.border = "1px solid red";
+					this.containerNode.style.position = "absolute";
+					this.containerNode.style.width = "100%";
+					for(var i = 0, idx = 0, len = this.srcNodeRef.childNodes.length; i < len; i++){
+						var c = this.srcNodeRef.childNodes[idx];
+						this.containerNode.appendChild(this.srcNodeRef.removeChild(c));
+					}
+					this.domNode.appendChild(this.containerNode);
+				}
+			});
 			
 		</script>
 	</head>
-	<body>
+	<body style="visibility:hidden;">
 		<h1 id="header1">Fixed Header</h1>
-		<div id="foo" dojoType="dojox.mobile.ScrollablePane" fixedHeader="header1">
+		<div id="foo" dojoType="dojox.mobile.ScrollablePane">
 			<ol>
 				<li>Item</li>
 				<li>Item</li>
@@ -104,7 +97,7 @@ dojo.declare(
 				<li>Item</li>
 				<li>Item</li>
 				<li>Item</li>
-			<ol>
+			</ol>
 		</div>
 	</body>
 </html>
diff --git a/dojox/mobile/tests/test_Slider.html b/dojox/mobile/tests/test_Slider.html
new file mode 100644
index 0000000..914fef1
--- /dev/null
+++ b/dojox/mobile/tests/test_Slider.html
@@ -0,0 +1,491 @@
+<!DOCTYPE html>
+<html>
+<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">
+		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;
+			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 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){
+						switch(type){
+							case 'touchstart': type = 'mousedown'; break;
+							case 'touchmove': type = 'mousemove'; break;
+							case 'touchend': type = 'mouseup'; break;
+						}
+					}
+					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(delay){
+					setTimeout(doit, delay);
+				}else{
+					doit();
+				}
+			}
+			var sh = dijit.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_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");
+
+			doh.register("tap", [
+				{
+					name: "horizontal end",
+					timeout: 1000+speed,
+					runTest: function(){
+						function onChange(v){
+							d.getTestCallback(function(){
+								doh.is(v, sh.max);
+							})();
+						}
+						var d = new doh.Deferred();
+						handle = sh.connect(sh, 'onChange', onChange);
+						fireTouchEvent('touchstart', sh, sh_width, sh_height >> 1, speed);
+						return d;
+					},
+					tearDown: function(){
+						fireTouchEvent('touchend', sh, sh_width, sh_height >> 1);
+						sh.disconnect(handle);
+					}
+				},
+				{
+					name: "horizontal start",
+					timeout: 1000+speed,
+					runTest: function(){
+						function onChange(v){
+							d.getTestCallback(function(){
+								doh.is(v, sh.min);
+							})();
+						}
+						var d = new doh.Deferred();
+						handle = sh.connect(sh, 'onChange', onChange);
+						fireTouchEvent('touchstart', sh, 0, sh_height >> 1, speed);
+						return d;
+					},
+					tearDown: function(){
+						fireTouchEvent('touchend', sh, 0, sh_height >> 1);
+						sh.disconnect(handle);
+					}
+				},
+				{
+					name: "horizontal middle",
+					timeout: 1000+speed,
+					runTest: function(){
+						function onChange(v){
+							d.getTestCallback(function(){
+								doh.t(Math.abs(v - ((sh.max+sh.min) >> 1)) <= sh.step);
+							})();
+						}
+						var d = new doh.Deferred();
+						handle = sh.connect(sh, 'onChange', onChange);
+						fireTouchEvent('touchstart', sh, sh_width >> 1, sh_height >> 1, speed);
+						return d;
+					},
+					tearDown: function(){
+						fireTouchEvent('touchend', sh, sh_width >> 1, sh_height >> 1);
+						sh.disconnect(handle);
+					}
+				},
+				{
+					name: "vertical end",
+					timeout: 1000+speed,
+					runTest: function(){
+						function onChange(v){
+							d.getTestCallback(function(){
+								doh.is(v, sv.max);
+							})();
+						}
+						var d = new doh.Deferred();
+						handle = sv.connect(sv, 'onChange', onChange);
+						fireTouchEvent('touchstart', sv, sv_width >> 1, 0, speed);
+						return d;
+					},
+					tearDown: function(){
+						fireTouchEvent('touchend', sv, sv_width >> 1, 0);
+						sv.disconnect(handle);
+					}
+				},
+				{
+					name: "vertical start",
+					timeout: 1000+speed,
+					runTest: function(){
+						function onChange(v){
+							d.getTestCallback(function(){
+								doh.is(v, sv.min);
+							})();
+						}
+						var d = new doh.Deferred();
+						handle = sv.connect(sv, 'onChange', onChange);
+						fireTouchEvent('touchstart', sv, sv_width >> 1, sv_height, speed);
+						return d;
+					},
+					tearDown: function(){
+						fireTouchEvent('touchend', sv, sv_width >> 1, sv_height);
+						sv.disconnect(handle);
+					}
+				},
+				{
+					name: "vertical middle",
+					timeout: 1000+speed,
+					runTest: function(){
+						function onChange(v){
+							d.getTestCallback(function(){
+								doh.t(Math.abs(v - ((sv.max+sv.min) >> 1)) <= sv.step);
+							})();
+						}
+						var d = new doh.Deferred();
+						handle = sv.connect(sv, 'onChange', onChange);
+						fireTouchEvent('touchstart', sv, sv_width >> 1, sv_height >> 1, speed);
+						return d;
+					},
+					tearDown: function(){
+						fireTouchEvent('touchend', sv, sv_width >> 1, sv_height >> 1);
+						sv.disconnect(handle);
+					}
+				}
+			]);
+
+			doh.register("move", [
+				{
+					name: "horizontal right",
+					timeout: 1000+speed*2,
+					runTest: function(){
+						function onChange(v){
+							d.getTestCallback(function(){
+								doh.is(v, sh.max);
+							})();
+						}
+						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);
+						return d;
+					},
+					tearDown: function(){
+						sh.disconnect(handle);
+					}
+				},
+				{
+					name: "horizontal left",
+					timeout: 1000+speed*2,
+					runTest: function(){
+						function onChange(v){
+							d.getTestCallback(function(){
+								doh.is(v, sh.min);
+							})();
+						}
+						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);
+						return d;
+					},
+					tearDown: function(){
+						sh.disconnect(handle);
+					}
+				},
+				{
+					name: "vertical up",
+					timeout: 1000+speed,
+					runTest: function(){
+						function onChange(v){
+							d.getTestCallback(function(){
+								doh.is(v, sv.max);
+							})();
+						}
+						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);
+						return d;
+					},
+					tearDown: function(){
+						sv.disconnect(handle);
+					}
+				},
+				{
+					name: "vertical down",
+					timeout: 1000+speed,
+					runTest: function(){
+						function onChange(v){
+							d.getTestCallback(function(){
+								doh.is(v, sv.min);
+							})();
+						}
+						var d = new doh.Deferred();
+						handle = sv.connect(sv, 'onChange', onChange);
+						fireTouchEvent('touchmove', sv, sv_width >> 1, sv_height, speed);
+						return d;
+					},
+					tearDown: function(){
+						fireTouchEvent('touchend', sv, sv_width >> 1, sv_height);
+						sv.disconnect(handle);
+					}
+				}
+			]);
+
+			doh.register("click handle", [
+				{
+					name: "horizontal right",
+					timeout: 1000+speed,
+					runTest: function(){
+						var mid = (sh.max + sh.min) >> 1;
+						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);
+						setTimeout(d.getTestCallback(function(){
+							doh.is(mid, sh.get('value'), 'right value');
+						}), 500+speed);
+						return d;
+					}
+				},
+				{
+					name: "horizontal left",
+					timeout: 1000+speed,
+					runTest: function(){
+						var mid = (sh.max + sh.min) >> 1;
+						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);
+						setTimeout(d.getTestCallback(function(){
+							doh.is(mid, sh.get('value'), 'left value');
+						}), 500+speed);
+						return d;
+					}
+				},
+				{
+					name: "horizontal change right",
+					timeout: 1000+speed,
+					runTest: function(){
+						var mid = (sh.max + sh.min) >> 1;
+						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);
+						setTimeout(d.getTestCallback(function(){
+							doh.t(sh.get('value') > mid, 'right changed value ' + sh.get('value'));
+						}), 500+speed);
+						return d;
+					}
+				},
+				{
+					name: "horizontal change left",
+					timeout: 1000+speed,
+					runTest: function(){
+						var mid = (sh.max + sh.min) >> 1;
+						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);
+						setTimeout(d.getTestCallback(function(){
+							doh.t(sh.get('value') < mid, 'left changed value ' + sh.get('value'));
+						}), 500+speed);
+						return d;
+					}
+				},
+				{
+					name: "vertical bottom",
+					timeout: 1000+speed,
+					runTest: function(){
+						var mid = (sv.max + sv.min) >> 1;
+						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);
+						setTimeout(d.getTestCallback(function(){
+							doh.is(mid, sv.get('value'), 'bottom value');
+						}), 500+speed);
+						return d;
+					}
+				},
+				{
+					name: "vertical top",
+					timeout: 1000+speed,
+					runTest: function(){
+						var mid = (sv.max + sv.min) >> 1;
+						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));
+						setTimeout(d.getTestCallback(function(){
+							doh.is(mid, sv.get('value'), 'top value');
+						}), 500+speed);
+						return d;
+					}
+				},
+				{
+					name: "vertical change bottom",
+					timeout: 1000+speed,
+					runTest: function(){
+						var mid = (sv.max + sv.min) >> 1;
+						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);
+						setTimeout(d.getTestCallback(function(){
+							doh.t(sv.get('value') < mid, 'bottom changed value ' + sv.get('value'));
+						}), 500+speed);
+						return d;
+					}
+				},
+				{
+					name: "vertical change top",
+					timeout: 1000+speed,
+					runTest: function(){
+						var mid = (sv.max + sv.min) >> 1;
+						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);
+						setTimeout(d.getTestCallback(function(){
+							doh.t(sv.get('value') > mid, 'top changed value ' + sv.get('value'));
+						}), 500+speed);
+						return d;
+					}
+				}
+			]);
+
+			if(dojo.isWebKit){
+				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);
+						sh.set('value', sh.max, true);
+						setTimeout(function(){
+							midX = dojo.position(sh.handle).x;
+						}, 400); 
+						setTimeout(d.getTestCallback(function(){
+							endX = Math.round(dojo.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);
+						}), 1100);
+						return d;
+					},
+					tearDown: function(){
+						dojo.style(sh.handle, "WebkitTransitionDuration", "");
+						dojo.style(sv.handle, "WebkitTransitionDuration", "");
+					}
+				})
+			}
+
+			doh.register("log", function(){
+				dojo.byId('failures').innerHTML = doh._failureCount;
+				dojo.byId('errors').innerHTML = doh._errorCount;
+			});
+
+			doh.run();
+		});
+	</script>
+</head>
+<body style="visibility:hidden;zoom:1.2;">
+	<form>
+		<br>
+		<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>20</td>
+			</tr><tr>
+				<td></td><td><center>Value: <span id="sh_val">0</span></center></td><td></td>
+			</tr></table>
+		</center>
+		<br>
+		<center>
+			<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;" />
+					-20
+				</center>
+			</td><td style="width:80px;">
+				Value: <span id="sv_val">0</span>
+			</td></tr></table>
+		</center>
+		<br>
+		<input type=submit>
+	</form>
+	Errors: <span id="errors">?</span><br>
+	Failures: <span id="failures">?</span>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_SpinWheel-1slot.html b/dojox/mobile/tests/test_SpinWheel-1slot.html
new file mode 100644
index 0000000..f5d30cb
--- /dev/null
+++ b/dojox/mobile/tests/test_SpinWheel-1slot.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<!--
+  A SpinWheel that has only one slot.
+  padding-right:4px is to adjust the right border width.
+  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>
+
+		<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>
+</html>
diff --git a/dojox/mobile/tests/test_SpinWheel-custom.html b/dojox/mobile/tests/test_SpinWheel-custom.html
new file mode 100644
index 0000000..2563835
--- /dev/null
+++ b/dojox/mobile/tests/test_SpinWheel-custom.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>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>
+
+		<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>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_SpinWheel-icons.html b/dojox/mobile/tests/test_SpinWheel-icons.html
new file mode 100644
index 0000000..6b5a56a
--- /dev/null
+++ b/dojox/mobile/tests/test_SpinWheel-icons.html
@@ -0,0 +1,76 @@
+<!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>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="[
+					'<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="text-align: center;">
+				</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="text-align: center;">
+				</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="text-align: center;">
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_SpinWheelDatePicker-sv.html b/dojox/mobile/tests/test_SpinWheelDatePicker-sv.html
new file mode 100644
index 0000000..d1406aa
--- /dev/null
+++ b/dojox/mobile/tests/test_SpinWheelDatePicker-sv.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>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();
+			}
+			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.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>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_SpinWheelDatePicker.html b/dojox/mobile/tests/test_SpinWheelDatePicker.html
new file mode 100644
index 0000000..97793eb
--- /dev/null
+++ b/dojox/mobile/tests/test_SpinWheelDatePicker.html
@@ -0,0 +1,38 @@
+<!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>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>
+</html>
diff --git a/dojox/mobile/tests/test_SpinWheelTimePicker.html b/dojox/mobile/tests/test_SpinWheelTimePicker.html
new file mode 100644
index 0000000..a2c2e0c
--- /dev/null
+++ b/dojox/mobile/tests/test_SpinWheelTimePicker.html
@@ -0,0 +1,39 @@
+<!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>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();
+			}
+			function showSelectedValue() {
+				var w = dijit.byId("spin1");
+				console.log(w.slots[0].getValue()+ ":" + w.slots[1].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="Now"></div>
+			</h1>
+			<div id="spin1" dojoType="dojox.mobile.SpinWheelTimePicker"></div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_Switch-setter.html b/dojox/mobile/tests/test_Switch-setter.html
new file mode 100644
index 0000000..d7499f7
--- /dev/null
+++ b/dojox/mobile/tests/test_Switch-setter.html
@@ -0,0 +1,43 @@
+<!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 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");
+			}
+			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);
+				});
+			});
+		</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>
+			<input type="button" onclick="swOn()" value="on">
+			<input type="button" onclick="swOff()" value="off">
+			<span id="msgArea"></span>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_Tooltip.html b/dojox/mobile/tests/test_Tooltip.html
new file mode 100644
index 0000000..fd61873
--- /dev/null
+++ b/dojox/mobile/tests/test_Tooltip.html
@@ -0,0 +1,117 @@
+<!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>
+
+		<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>
+	</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_ajax-html.html b/dojox/mobile/tests/test_ajax-html.html
index b707681..e201134 100644
--- a/dojox/mobile/tests/test_ajax-html.html
+++ b/dojox/mobile/tests/test_ajax-html.html
@@ -4,17 +4,16 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<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.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			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>
+	<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>
diff --git a/dojox/mobile/tests/test_ajax-json.html b/dojox/mobile/tests/test_ajax-json.html
index 5995b2c..28b1802 100644
--- a/dojox/mobile/tests/test_ajax-json.html
+++ b/dojox/mobile/tests/test_ajax-json.html
@@ -4,17 +4,16 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<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.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			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>
+	<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>
diff --git a/dojox/mobile/tests/test_anchor-label.html b/dojox/mobile/tests/test_anchor-label.html
index f415f0b..ca0af5f 100644
--- a/dojox/mobile/tests/test_anchor-label.html
+++ b/dojox/mobile/tests/test_anchor-label.html
@@ -4,15 +4,14 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<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.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			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",
@@ -32,7 +31,7 @@
 			});
 		</script>
 	</head>
-	<body>
+	<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>
diff --git a/dojox/mobile/tests/test_bookmarkable.html b/dojox/mobile/tests/test_bookmarkable.html
index 9257bdc..f8b9b2d 100755
--- a/dojox/mobile/tests/test_bookmarkable.html
+++ b/dojox/mobile/tests/test_bookmarkable.html
@@ -4,7 +4,7 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<link href="../themes/iphone/base.css" rel="stylesheet">
 		<style>
 		.lnk {
 			font-size: 14px;
@@ -16,14 +16,13 @@
 		<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("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>
+	<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>
@@ -39,7 +38,7 @@
 				</li>
 			</ul>
 			<div dojoType="dojox.mobile.RoundRect">
-				After you moves 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.
+				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>
 
diff --git a/dojox/mobile/tests/test_buttons.html b/dojox/mobile/tests/test_buttons.html
deleted file mode 100644
index 8f81b6c..0000000
--- a/dojox/mobile/tests/test_buttons.html
+++ /dev/null
@@ -1,21 +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>Button</title>
-		<link href="../themes/buttons.css" rel="stylesheet"></link>
-		<link href="../themes/buttons-compat.css" rel="stylesheet"></link>
-	</head>
-	<body style="padding:20px;background-color: rgb(197,204,211);">
-		<div class="mblBlueMinusButton"><div></div><p></p></div>
-		<div class="mblDarkBlueMinusButton"><div></div><p></p></div>
-		<div class="mblRedMinusButton"><div></div></div>
-		<br>
-		<div class="mblBluePlusButton"><div></div><p></p></div>
-		<div class="mblDarkBluePlusButton"><div></div><p></p></div>
-		<div class="mblRedPlusButton"><div></div><p></p></div>
-		<br>
-		<div class="mblCheckOnButton"><div></div><p></p></div>
-		<div class="mblCheckOffButton"><div></div><p></p></div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_css-sprite.html b/dojox/mobile/tests/test_css-sprite.html
index 6410872..74f8617 100644
--- a/dojox/mobile/tests/test_css-sprite.html
+++ b/dojox/mobile/tests/test_css-sprite.html
@@ -4,21 +4,20 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<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.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			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){
-				alert("CSS Sprite is not supported for the BlackBerry browser");
+				console.log("CSS Sprite is not supported for the BlackBerry browser");
 			}
 		</script>
 	</head>
-	<body>
+	<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">
diff --git a/dojox/mobile/tests/test_domButtons.html b/dojox/mobile/tests/test_domButtons.html
new file mode 100644
index 0000000..664a642
--- /dev/null
+++ b/dojox/mobile/tests/test_domButtons.html
@@ -0,0 +1,85 @@
+<!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>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>
+
+		<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 setIconValue(id, val){
+				var txt = dojo.doc.createTextNode(val);
+				dojo.byId(id).firstChild.appendChild(txt);
+			}
+			dojo.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);
+				}
+				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>
+
+			<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="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="mblDomButtonYellowStar"></div></td><td>mblDomButtonYellowStar</td></tr>
+			<tr><td><div class="mblDomButtonGrayStar"></div></td><td>mblDomButtonGrayStar</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 a4d31e2..94a53e0 100644
--- a/dojox/mobile/tests/test_dynamic-ScrollableView-ah-af.html
+++ b/dojox/mobile/tests/test_dynamic-ScrollableView-ah-af.html
@@ -4,17 +4,24 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<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.parser");
-			dojo.require("dojox.mobile");
+			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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
+				// ==== App Header has to be at the top position ====
+				var heading1 = new dojox.mobile.Heading({
+					label: "Fixed App Header",
+					fixed: "top"
+				});
+				dojo.body().appendChild(heading1.domNode);
+
+
 				// ==== view1 ====
 				var view1 = new dojox.mobile.ScrollableView({
 					id: "foo",
@@ -42,13 +49,6 @@
 					counter++;
 				}
 
-				var heading1 = new dojox.mobile.Heading({
-					label: "Fixed App Header",
-					fixed: "top"
-				});
-				dojo.body().appendChild(heading1.domNode);
-
-
 				// ==== view2 ====
 				var view2 = new dojox.mobile.ScrollableView({
 					id: "bar"
@@ -74,12 +74,12 @@
 
 				// ==== Initialize each view when the dom is ready ====
 				view1.findAppBars();
-				view1.resizeView();
+				view1.resize();
 				view2.findAppBars();
-				view2.resizeView();
+				view2.resize();
 			});
 		</script>
 	</head>
-	<body>
+	<body style="visibility:hidden;">
 	</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 28b9522..f6fb30c 100644
--- a/dojox/mobile/tests/test_dynamic-ScrollableView-vh-vf.html
+++ b/dojox/mobile/tests/test_dynamic-ScrollableView-vh-vf.html
@@ -4,17 +4,16 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<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.parser");
-			dojo.require("dojox.mobile");
+			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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				// ==== view1 ====
 				var view1 = new dojox.mobile.ScrollableView({
 					id: "foo",
@@ -71,6 +70,6 @@
 			});
 		</script>
 	</head>
-	<body>
+	<body style="visibility:hidden;">
 	</body>
 </html>
diff --git a/dojox/mobile/tests/test_dynamic-icons.html b/dojox/mobile/tests/test_dynamic-icons.html
index 6c07303..5faee56 100644
--- a/dojox/mobile/tests/test_dynamic-icons.html
+++ b/dojox/mobile/tests/test_dynamic-icons.html
@@ -4,9 +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>Dynamic Icons</title>
-		<link href="../themes/iphone/iphone.css" rel="stylesheet"></link>
-		<link href="../themes/buttons.css" rel="stylesheet"></link>
-		<link href="../../../dijit/themes/tundra/tundra.css" rel="stylesheet"></link>
+		<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">
 
 		<style>
 			.box {
@@ -21,13 +22,13 @@
 		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			dojo.require("dojox.mobile.Button");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				var btnWidget = dijit.byId("btn1");
 				dojo.connect(btnWidget.domNode, "onclick", onBtnClicked);
 				function onBtnClicked(e){
@@ -43,12 +44,12 @@
 			});
 		</script>
 	</head>
-	<body class="tundra">
+	<body style="visibility:hidden;" class="tundra">
 		<div id="myhome" dojoType="dojox.mobile.View" selected="true">
-			<ul id="ic1" dojoType="dojox.mobile.IconContainer" type="slide">
+			<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" style="width:80px;margin-left:10px">More...</button>
+			<button id="btn1" dojoType="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
index a58d794..dde7657 100755
--- a/dojox/mobile/tests/test_dynamic-items.html
+++ b/dojox/mobile/tests/test_dynamic-items.html
@@ -4,19 +4,20 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<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("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");
 
 			var counter = 4;
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				var btnWidget = dijit.byId("btn1");
 				dojo.connect(btnWidget.domNode, "onclick", onBtnClicked);
 				function onBtnClicked(e){
@@ -44,28 +45,13 @@
 				var prog = dojox.mobile.ProgressIndicator.getInstance();
 				container.appendChild(prog.domNode);
 				prog.start();
-				/*
-				var url = "http://..." + param;
-				dojo.xhrGet({
-					url: url,
-					handleAs: "text",
-					load: function(response, ioArgs){
-						prog.stop();
-						container.innerHTML = response;
-						dojox.mobile.parser.parse(container);
-					}
-				});
-				*/
 				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,
-			{
+			dojo.declare("dojox.mobile.ViewEx",dojox.mobile.View,{
 				onStartView: function(){
 					loadPage(location.hash);
 				},
@@ -75,7 +61,7 @@
 			});
 		</script>
 	</head>
-	<body>
+	<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>
@@ -90,7 +76,7 @@
 					Document 0003
 				</li>
 			</ul>
-			<button id="btn1" dojoType="dojox.mobile.Button" style="width:80px;margin-left:10px">More...</button>
+			<button id="btn1" dojoType="dojox.mobile.Button" class="mblBlueButton" style="width:80px;margin-left:10px">More...</button>
 		</div>
 
 		<div id="bar" dojoType="dojox.mobile.ViewEx"></div>
diff --git a/dojox/mobile/tests/test_dynamic-view.html b/dojox/mobile/tests/test_dynamic-view.html
index 36b30b7..c619e16 100644
--- a/dojox/mobile/tests/test_dynamic-view.html
+++ b/dojox/mobile/tests/test_dynamic-view.html
@@ -4,7 +4,7 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<link href="../themes/iphone/base.css" rel="stylesheet">
 		<style>
 		.lnk {
 			font-size: 14px;
@@ -15,12 +15,11 @@
 		<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("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.addOnLoad(function(){
+			dojo.ready(function(){
 				var view1 = new dojox.mobile.View({
 					id: "foo",
 					selected: true
@@ -52,7 +51,7 @@
 			});
 		</script>
 	</head>
-	<body>
+	<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 1f4da26..ed25f85 100644
--- a/dojox/mobile/tests/test_grouped-scrollable-views.html
+++ b/dojox/mobile/tests/test_grouped-scrollable-views.html
@@ -4,21 +4,17 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<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.parser");
-			dojo.require("dojox.mobile");
+			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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
 		</script>
 	</head>
-	<body>
+	<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>
diff --git a/dojox/mobile/tests/test_grouped-views.html b/dojox/mobile/tests/test_grouped-views.html
index 279328c..9aee6a1 100644
--- a/dojox/mobile/tests/test_grouped-views.html
+++ b/dojox/mobile/tests/test_grouped-views.html
@@ -4,18 +4,16 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<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.parser");
-			dojo.require("dojox.mobile");
-
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			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>
+	<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>
diff --git a/dojox/mobile/tests/test_hash-parameter.html b/dojox/mobile/tests/test_hash-parameter.html
index 78ed3bd..b973f9a 100755
--- a/dojox/mobile/tests/test_hash-parameter.html
+++ b/dojox/mobile/tests/test_hash-parameter.html
@@ -4,7 +4,7 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<link href="../themes/iphone/base.css" rel="stylesheet">
 		<style>
 		.lnk {
 			font-size: 14px;
@@ -16,11 +16,10 @@
 		<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("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 loadPage(moveTo){
 				if(!(moveTo.match(/#(\w+)/))){ return; }
@@ -46,7 +45,7 @@
 			});
 		</script>
 	</head>
-	<body>
+	<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>
@@ -62,7 +61,7 @@
 				</li>
 			</ul>
 			<div dojoType="dojox.mobile.RoundRect">
-				After you moves 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.
+				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>
 
diff --git a/dojox/mobile/tests/test_html-form-controls.html b/dojox/mobile/tests/test_html-form-controls.html
new file mode 100644
index 0000000..a596854
--- /dev/null
+++ b/dojox/mobile/tests/test_html-form-controls.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 name="viewport" content="width=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>
+
+		<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>
+</html>
diff --git a/dojox/mobile/tests/test_html-inputs.html b/dojox/mobile/tests/test_html-inputs.html
new file mode 100644
index 0000000..8a569a0
--- /dev/null
+++ b/dojox/mobile/tests/test_html-inputs.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>many input fields</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");
+			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>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_i18n.html b/dojox/mobile/tests/test_i18n.html
new file mode 100644
index 0000000..5c8685e
--- /dev/null
+++ b/dojox/mobile/tests/test_i18n.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>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">
+
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			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"));
+			});
+		</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>
+
+			<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>
+
+			<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 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>
+
+			<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
new file mode 100644
index 0000000..8e9896f
--- /dev/null
+++ b/dojox/mobile/tests/test_iPad-Heading.html
@@ -0,0 +1,124 @@
+<!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
new file mode 100644
index 0000000..5de8426
--- /dev/null
+++ b/dojox/mobile/tests/test_iPad-Settings-async.html
@@ -0,0 +1,241 @@
+<!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
index 1999cf5..c57614b 100644
--- a/dojox/mobile/tests/test_iPad-Settings.html
+++ b/dojox/mobile/tests/test_iPad-Settings.html
@@ -5,37 +5,34 @@
 		<meta name="apple-mobile-web-app-capable" content="yes" />
 		<title>iPad Settings</title>
 		<style>
-		@import "../themes/iphone/iphone.css";
+		@import "../themes/iphone/base.css";
 		@import "../themes/iphone/ipad.css";
-		@import "../themes/FixedSplitter.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"></script>
+		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
+			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
 		</script>
 	</head>
-	<body>
+	<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="none" stateful="true">
+					<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>
@@ -222,8 +219,8 @@
 				<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">
-						<li dojoType="dojox.mobile.ListItem">
+					<ul dojoType="dojox.mobile.RoundRectList" select="single">
+						<li dojoType="dojox.mobile.ListItem" checked="true">
 							Dissolve
 						</li>
 						<li dojoType="dojox.mobile.ListItem">
diff --git a/dojox/mobile/tests/test_iPad-TabBar.html b/dojox/mobile/tests/test_iPad-TabBar.html
new file mode 100644
index 0000000..1011092
--- /dev/null
+++ b/dojox/mobile/tests/test_iPad-TabBar.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>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
new file mode 100644
index 0000000..0dedca5
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-Animation-async.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>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
index f3455ab..9920579 100644
--- a/dojox/mobile/tests/test_iPhone-Animation.html
+++ b/dojox/mobile/tests/test_iPhone-Animation.html
@@ -4,7 +4,7 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<link href="../themes/iphone/base.css" rel="stylesheet">
 		<style>
 		.lnk {
 			font-size: 14px;
@@ -15,14 +15,12 @@
 		<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("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>
+	<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>
diff --git a/dojox/mobile/tests/test_iPhone-Button.html b/dojox/mobile/tests/test_iPhone-Button.html
index fc7a32b..5fd53d5 100755
--- a/dojox/mobile/tests/test_iPhone-Button.html
+++ b/dojox/mobile/tests/test_iPhone-Button.html
@@ -4,14 +4,15 @@
 		<meta name="viewport" content="width=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"></link>
+		<link href="../themes/iphone/base.css" rel="stylesheet">
+		<link href="../themes/iphone/Button.css" rel="stylesheet">
 		<style>
-		.redButton {
+		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));
 		}
-		.redButtonSelected {
+		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));
 		}
@@ -19,12 +20,12 @@
 		<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("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.addOnLoad(function(){
+			dojo.ready(function(){
 				var btnWidget = dijit.byId("btn1");
 				dojo.connect(btnWidget.domNode, "onclick", onBtnClicked);
 				function onBtnClicked(e){
@@ -34,8 +35,8 @@
 		</script>
 	</head>
 	<body style="padding: 20px;visibility:visible">
-		<button id="btn1" dojoType="dojox.mobile.Button" style="width:120px">Default Button</button>
+		<button id="btn1" dojoType="dojox.mobile.Button" class="mblBlueButton" style="width:120px">Default Button</button>
 		<p></p>
-		<button id="btn2" dojoType="dojox.mobile.Button" btnClass="redButton" style="width:120px">Custom Button</button>
+		<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
index 7e2cf32..39334fd 100644
--- a/dojox/mobile/tests/test_iPhone-ButtonList.html
+++ b/dojox/mobile/tests/test_iPhone-ButtonList.html
@@ -4,47 +4,42 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
-		<link href="../themes/buttons.css" rel="stylesheet"></link>
+		<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("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.addOnLoad(function(){
+			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);
+					dojo.connect(w.rightIconNode, "onclick", btnClicked);
 				}
 			});
 			function btnClicked(e){
-				var btnDiv = e.currentTarget;
-				if(dojo.hasClass(btnDiv, "mblBluePlusButton")){
-					dojo.removeClass(btnDiv, "mblBluePlusButton");
-					dojo.addClass(btnDiv, "mblRedMinusButton");
-				}else if(dojo.hasClass(btnDiv, "mblRedMinusButton")){
-					dojo.removeClass(btnDiv, "mblRedMinusButton");
-					dojo.addClass(btnDiv, "mblBluePlusButton");
-				}
-				if(dojo.isBB){
-					btnDiv.parentNode.appendChild(btnDiv.parentNode.removeChild(btnDiv));
+				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>
+	<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="mblBluePlusButton">
+				<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="mblRedMinusButton">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" btnClass="mblDomButtonRedMinus">
 					YY Widget
 				</li>
 			</ul>
diff --git a/dojox/mobile/tests/test_iPhone-EdgeToEdge.html b/dojox/mobile/tests/test_iPhone-EdgeToEdge.html
index e2c3ce6..9117567 100644
--- a/dojox/mobile/tests/test_iPhone-EdgeToEdge.html
+++ b/dojox/mobile/tests/test_iPhone-EdgeToEdge.html
@@ -4,17 +4,20 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<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.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			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>
+	<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">
@@ -34,7 +37,6 @@
 		<div id="hello" dojoType="dojox.mobile.View">
 			<h1 dojoType="dojox.mobile.Heading">Hello</h1>
 			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
 				<li dojoType="dojox.mobile.ListItem" moveTo="settings">
 					Hello
 				</li>
diff --git a/dojox/mobile/tests/test_iPhone-EdgeToEdgeCategory.html b/dojox/mobile/tests/test_iPhone-EdgeToEdgeCategory.html
index e148b90..0d24a9e 100644
--- a/dojox/mobile/tests/test_iPhone-EdgeToEdgeCategory.html
+++ b/dojox/mobile/tests/test_iPhone-EdgeToEdgeCategory.html
@@ -4,17 +4,16 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<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.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			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>
+	<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>
diff --git a/dojox/mobile/tests/test_iPhone-FlippableView.html b/dojox/mobile/tests/test_iPhone-FlippableView.html
deleted file mode 100644
index 85b8138..0000000
--- a/dojox/mobile/tests/test_iPhone-FlippableView.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>FlippableView</title>
-		<link href="../themes/iphone/iphone.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("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.IconContainer");
-			dojo.require("dojox.mobile.FlippableView");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
-		</script>
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.FlippableView" 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.
-				Virtical scrolling and page indicator are not supported.
-			</div>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.FlippableView">
-			<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.FlippableView">
-			<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.FlippableView">
-			<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-Heading.html b/dojox/mobile/tests/test_iPhone-Heading.html
index 146b401..269190b 100644
--- a/dojox/mobile/tests/test_iPhone-Heading.html
+++ b/dojox/mobile/tests/test_iPhone-Heading.html
@@ -4,56 +4,54 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
-		<link href="../themes/domButtons.css" rel="stylesheet"></link>
+		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				var btn1 = dijit.byId("btn1");
 				btn1.connect(btn1.domNode, "onclick", function(){
-					alert(this.label + " button was clicked");
+					console.log(this.label + " button was clicked");
 				});
 			});
 		</script>
 	</head>
-	<body>
+	<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</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</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">Edit</div>
-			<div dojoType="dojox.mobile.ToolBarButton" class="mblDomButton mblDomButtonPlus_2" style="float:right;" onclick="alert('+ was clicked')"></div>
+			<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">Edit</div>
-			<div dojoType="dojox.mobile.ToolBarButton" class="mblDomButton mblDomButtonPlus_2" style="float:right;"></div>
+			<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"></div>
+			<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">
-			<!-- dummy hidden button to center the label -->
-			<div dojoType="dojox.mobile.ToolBarButton" label="Update All" style="visibility:hidden;"></div>
 			<div dojoType="dojox.mobile.ToolBarButton" label="Update All" style="float:right;"></div>
 		</h1><br>
 
@@ -72,9 +70,9 @@
 		<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="mblDomButton mblDomButtonPlus_2" moveTo="view3" style="float:right;"></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>
 
 
@@ -84,13 +82,13 @@
 				<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" class="mblDomButton mblDomButtonSearch_2" style="float:right;"></div>
+			<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" class="mblDomButton mblDomButtonPlus_2"></div></td>
+			<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>
@@ -102,23 +100,23 @@
 
 		<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" class="mblDomButton mblDomButtonUpArrow_2" selectOne="false"></li>
-				<li dojoType="dojox.mobile.TabBarButton" class="mblDomButton mblDomButtonDownArrow_2" selectOne="false"></li>
+				<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" class="mblDomButton mblDomButtonSearch_2" style="float:right;"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" class="mblDomButton mblDomButtonUpArrow_2" style="float:right;"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" class="mblDomButton mblDomButtonDownArrow_2" style="float:right;"></div>
+			<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" class="mblDomButton mblDomButtonUpArrow_2" selectOne="false"></li>
-				<li dojoType="dojox.mobile.TabBarButton" class="mblDomButton mblDomButtonSearch_2" selectOne="false"></li>
+				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteUpArrow" selectOne="false"></li>
+				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteSearch" selectOne="false"></li>
 			</ul>
 		</h1><br>
 	</body>
diff --git a/dojox/mobile/tests/test_iPhone-Icon-sprite.html b/dojox/mobile/tests/test_iPhone-Icon-sprite.html
new file mode 100644
index 0000000..245dd83
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-Icon-sprite.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 (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
index b8355be..b898456 100644
--- a/dojox/mobile/tests/test_iPhone-Icon.html
+++ b/dojox/mobile/tests/test_iPhone-Icon.html
@@ -4,8 +4,8 @@
 		<meta name="viewport" content="width=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>
-		<link href="../themes/buttons.css" rel="stylesheet"></link>
+		<link href="../themes/iphone/base.css" rel="stylesheet">
+		<link href="../themes/iphone/IconContainer.css" rel="stylesheet">
 
 		<style>
 			.box {
@@ -20,14 +20,16 @@
 		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			dojo.require("dojox.mobile.RoundRectCategory");
+			dojo.require("dojox.mobile.RoundRectList");
+			dojo.require("dojox.mobile.ListItem");
 		</script>
 	</head>
-	<body>
+	<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">
@@ -36,7 +38,9 @@
 				<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>
 
diff --git a/dojox/mobile/tests/test_iPhone-IconMulti.html b/dojox/mobile/tests/test_iPhone-IconMulti.html
index c1320c6..9d6355d 100644
--- a/dojox/mobile/tests/test_iPhone-IconMulti.html
+++ b/dojox/mobile/tests/test_iPhone-IconMulti.html
@@ -4,31 +4,38 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
-		<link href="../themes/buttons.css" rel="stylesheet"></link>
-		<link href="../../../dijit/themes/tundra/tundra.css" rel="stylesheet"></link>
+		<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("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
+			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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
 		</script>
 	</head>
-	<body class="tundra" style="background-color:white">
+	<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" requires="dijit._base.wai,dijit._base.typematic,dojo._base.query">
-					<div dojoType='dijit._Calendar'></div>
+				<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" requires="dijit._base.wai,dijit._base.typematic,dojo._base.Color">
+				<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" requires="dijit._base.wai">
+				<li dojoType="dojox.mobile.IconItem" label="Progress Bar" icon="images/icon-1.png" lazy="true">
 					<div dojoType='dijit.ProgressBar'></div>
 				</li>
 			</ul>
diff --git a/dojox/mobile/tests/test_iPhone-IconSingle.html b/dojox/mobile/tests/test_iPhone-IconSingle.html
index b1f1314..b86ad0e 100644
--- a/dojox/mobile/tests/test_iPhone-IconSingle.html
+++ b/dojox/mobile/tests/test_iPhone-IconSingle.html
@@ -4,30 +4,30 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
-		<link href="../../../dijit/themes/tundra/tundra.css" rel="stylesheet"></link>
+		<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("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
+			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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
 		</script>
 	</head>
-	<body class="tundra" style="background-color:white">
+	<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" requires="dijit._base.wai,dijit._base.typematic,dojo._base.query">
-					<div dojoType='dijit._Calendar'></div>
+				<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" requires="dijit._base.wai,dijit._base.typematic,dojo._base.Color">
+				<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" requires="dijit._base.wai">
+				<li dojoType="dojox.mobile.IconItem" label="Progress Bar" icon="images/icon-1.png" lazy="true">
 					<div dojoType='dijit.ProgressBar'></div>
 				</li>
 			</ul>
diff --git a/dojox/mobile/tests/test_iPhone-IconSingleBelow.html b/dojox/mobile/tests/test_iPhone-IconSingleBelow.html
index 8961cc2..9a8eec5 100644
--- a/dojox/mobile/tests/test_iPhone-IconSingleBelow.html
+++ b/dojox/mobile/tests/test_iPhone-IconSingleBelow.html
@@ -4,30 +4,30 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
-		<link href="../../../dijit/themes/tundra/tundra.css" rel="stylesheet"></link>
+		<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("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
+			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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
 		</script>
 	</head>
-	<body class="tundra" style="background-color:white">
+	<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" requires="dijit._base.wai,dijit._base.typematic,dojo._base.query">
-					<div dojoType='dijit._Calendar'></div>
+				<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" requires="dijit._base.wai,dijit._base.typematic,dojo._base.Color">
+				<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" requires="dijit._base.wai">
+				<li dojoType="dojox.mobile.IconItem" label="Progress Bar" icon="images/icon-1.png" lazy="true">
 					<div dojoType='dijit.ProgressBar'></div>
 				</li>
 			</ul>
diff --git a/dojox/mobile/tests/test_iPhone-ResultList.html b/dojox/mobile/tests/test_iPhone-ResultList.html
index fa44d89..aadbf9c 100644
--- a/dojox/mobile/tests/test_iPhone-ResultList.html
+++ b/dojox/mobile/tests/test_iPhone-ResultList.html
@@ -4,7 +4,7 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<link href="../themes/iphone/base.css" rel="stylesheet">
 		<style>
 			.lnk {
 				font-size: 14px;
@@ -16,13 +16,12 @@
 		<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("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>
+	<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">
diff --git a/dojox/mobile/tests/test_iPhone-RoundRect.html b/dojox/mobile/tests/test_iPhone-RoundRect.html
index f8f0ae9..2054fca 100644
--- a/dojox/mobile/tests/test_iPhone-RoundRect.html
+++ b/dojox/mobile/tests/test_iPhone-RoundRect.html
@@ -4,18 +4,17 @@
 		<meta name="viewport" content="width=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"></link>
+		<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.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			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>
+	<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">
diff --git a/dojox/mobile/tests/test_iPhone-RoundRectList.html b/dojox/mobile/tests/test_iPhone-RoundRectList.html
index b59b454..ef03989 100644
--- a/dojox/mobile/tests/test_iPhone-RoundRectList.html
+++ b/dojox/mobile/tests/test_iPhone-RoundRectList.html
@@ -4,18 +4,17 @@
 		<meta name="viewport" content="width=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>
+		<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.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			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>
+	<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>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-demo-async.html b/dojox/mobile/tests/test_iPhone-ScrollableView-demo-async.html
new file mode 100644
index 0000000..55c8a37
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-demo-async.html
@@ -0,0 +1,393 @@
+<!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
new file mode 100644
index 0000000..1d0809c
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-demo-long.html
@@ -0,0 +1,389 @@
+<!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
index 8cfb756..597338c 100644
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-demo.html
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-demo.html
@@ -4,7 +4,8 @@
 	<meta name="viewport" content="width=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/iphone.css" rel="stylesheet">
+	<link href="../themes/iphone/base.css" rel="stylesheet">
+	<link href="../themes/iphone/TabBar.css" rel="stylesheet">
 	<style>
 	html,body{
 		height: 100%;
@@ -83,7 +84,7 @@
 		dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
 	</script>
 </head>
-<body>
+<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>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-h.html b/dojox/mobile/tests/test_iPhone-ScrollableView-h.html
index 952b350..bb3e29d 100644
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-h.html
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-h.html
@@ -4,7 +4,7 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet">
+		<link href="../themes/iphone/base.css" rel="stylesheet">
 		<style>
 		.lnk {
 			font-size: 14px;
@@ -22,16 +22,13 @@
 		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
 		</script>
 	</head>
-	<body>
+	<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;">
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-hv-ah-af.html b/dojox/mobile/tests/test_iPhone-ScrollableView-hv-ah-af.html
index c6ae0a0..f0044b7 100644
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-hv-ah-af.html
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-hv-ah-af.html
@@ -4,7 +4,7 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet">
+		<link href="../themes/iphone/base.css" rel="stylesheet">
 		<style>
 		.lnk {
 			font-size: 14px;
@@ -22,16 +22,13 @@
 		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
 		</script>
 	</head>
-	<body>
+	<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;">
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-hv-vh-vf.html b/dojox/mobile/tests/test_iPhone-ScrollableView-hv-vh-vf.html
index e057b2f..2e322e4 100644
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-hv-vh-vf.html
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-hv-vh-vf.html
@@ -4,7 +4,7 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet">
+		<link href="../themes/iphone/base.css" rel="stylesheet">
 		<style>
 		.lnk {
 			font-size: 14px;
@@ -22,16 +22,13 @@
 		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
 		</script>
 	</head>
-	<body>
+	<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;">
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-hv.html b/dojox/mobile/tests/test_iPhone-ScrollableView-hv.html
index a468256..d9c7e70 100644
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-hv.html
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-hv.html
@@ -4,7 +4,7 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet">
+		<link href="../themes/iphone/base.css" rel="stylesheet">
 		<style>
 		.lnk {
 			font-size: 14px;
@@ -22,16 +22,13 @@
 		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
 		</script>
 	</head>
-	<body>
+	<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;">
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-short-inp.html b/dojox/mobile/tests/test_iPhone-ScrollableView-short-inp.html
new file mode 100644
index 0000000..4d29717
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-short-inp.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 name="viewport" content="width=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
new file mode 100644
index 0000000..08a0301
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-short.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 name="viewport" content="width=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
new file mode 100644
index 0000000..ab006c7
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-v-ah-af-inp.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>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
index 82097c2..b1da855 100644
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-v-ah-af.html
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-v-ah-af.html
@@ -4,7 +4,7 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet">
+		<link href="../themes/iphone/base.css" rel="stylesheet">
 		<style>
 		.lnk {
 			font-size: 14px;
@@ -19,16 +19,13 @@
 		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
 		</script>
 	</head>
-	<body>
+	<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>
@@ -94,6 +91,33 @@
 				<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>
 
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-v-inp.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v-inp.html
new file mode 100644
index 0000000..91b5586
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-v-inp.html
@@ -0,0 +1,171 @@
+<!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
new file mode 100644
index 0000000..d07f9de
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-af-inp.html
@@ -0,0 +1,173 @@
+<!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
index 6e3d9e9..3247e1f 100644
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-af.html
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-af.html
@@ -4,7 +4,7 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet">
+		<link href="../themes/iphone/base.css" rel="stylesheet">
 		<style>
 		.lnk {
 			font-size: 14px;
@@ -19,16 +19,13 @@
 		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
 		</script>
 	</head>
-	<body>
+	<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>
@@ -94,6 +91,33 @@
 				<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>
 
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-inp.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-inp.html
new file mode 100644
index 0000000..931d8c5
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-inp.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>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
new file mode 100644
index 0000000..a7db815
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-vf-inp.html
@@ -0,0 +1,174 @@
+<!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
index efadd99..9781cda 100644
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-vf.html
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-vf.html
@@ -4,7 +4,7 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet">
+		<link href="../themes/iphone/base.css" rel="stylesheet">
 		<style>
 		.lnk {
 			font-size: 14px;
@@ -19,16 +19,13 @@
 		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
 		</script>
 	</head>
-	<body>
+	<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>
@@ -94,6 +91,33 @@
 				<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>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh.html
index 86984cc..490cffc 100644
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh.html
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh.html
@@ -4,7 +4,7 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet">
+		<link href="../themes/iphone/base.css" rel="stylesheet">
 		<style>
 		.lnk {
 			font-size: 14px;
@@ -19,16 +19,13 @@
 		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
 		</script>
 	</head>
-	<body>
+	<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>
@@ -94,6 +91,33 @@
 				<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>
 
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-v.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v.html
index 32cb93a..b07b3fb 100644
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-v.html
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-v.html
@@ -4,7 +4,7 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet">
+		<link href="../themes/iphone/base.css" rel="stylesheet">
 		<style>
 		.lnk {
 			font-size: 14px;
@@ -19,16 +19,13 @@
 		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
 		</script>
 	</head>
-	<body>
+	<body style="visibility:hidden;">
 		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true">
 			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
 
@@ -93,10 +90,38 @@
 				<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>
diff --git a/dojox/mobile/tests/test_iPhone-Settings.html b/dojox/mobile/tests/test_iPhone-Settings.html
index 0f7545f..8934298 100644
--- a/dojox/mobile/tests/test_iPhone-Settings.html
+++ b/dojox/mobile/tests/test_iPhone-Settings.html
@@ -4,18 +4,17 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<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.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			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>
+	<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">
diff --git a/dojox/mobile/tests/test_iPhone-SwapView-demo-async.html b/dojox/mobile/tests/test_iPhone-SwapView-demo-async.html
new file mode 100644
index 0000000..0bd141c
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-SwapView-demo-async.html
@@ -0,0 +1,219 @@
+<!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
new file mode 100644
index 0000000..1c5300b
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-SwapView-demo.html
@@ -0,0 +1,217 @@
+<!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
new file mode 100644
index 0000000..4bfd4da
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-SwapView-slideshow-async.html
@@ -0,0 +1,98 @@
+<!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
new file mode 100644
index 0000000..04ef8c4
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-SwapView-slideshow.html
@@ -0,0 +1,95 @@
+<!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
new file mode 100644
index 0000000..a545500
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-SwapView.html
@@ -0,0 +1,83 @@
+<!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
index 0e41a0d..42c4be6 100644
--- a/dojox/mobile/tests/test_iPhone-Switch.html
+++ b/dojox/mobile/tests/test_iPhone-Switch.html
@@ -4,20 +4,73 @@
 		<meta name="viewport" content="width=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"></link>
+		<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.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			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="padding:15px;visibility:visible">
-		<div dojoType="dojox.mobile.Switch" value="off"></div>
-		<hr>
-		<div dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
+	<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
index 26d8f52..8f3830e 100644
--- a/dojox/mobile/tests/test_iPhone-TabBar-seg-grouped-scroll.html
+++ b/dojox/mobile/tests/test_iPhone-TabBar-seg-grouped-scroll.html
@@ -4,8 +4,8 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
-		<!-- link href="../themes/android/android.css" rel="stylesheet"></link -->
+		<link href="../themes/iphone/base.css" rel="stylesheet">
+		<link href="../themes/iphone/TabBar.css" rel="stylesheet">
 
 		<style>
 			html,body{
@@ -36,17 +36,14 @@
 		<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");			// 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");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-			dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
 		</script>
 	</head>
-	<body>
+	<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>
diff --git a/dojox/mobile/tests/test_iPhone-TabBar-seg-grouped.html b/dojox/mobile/tests/test_iPhone-TabBar-seg-grouped.html
index bcded14..c5f7d79 100644
--- a/dojox/mobile/tests/test_iPhone-TabBar-seg-grouped.html
+++ b/dojox/mobile/tests/test_iPhone-TabBar-seg-grouped.html
@@ -4,8 +4,8 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
-		<!-- link href="../themes/android/android.css" rel="stylesheet"></link -->
+		<link href="../themes/iphone/base.css" rel="stylesheet">
+		<link href="../themes/iphone/TabBar.css" rel="stylesheet">
 
 		<style>
 			#list1 li{
@@ -32,14 +32,13 @@
 		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
 		</script>
 	</head>
-	<body>
+	<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>
diff --git a/dojox/mobile/tests/test_iPhone-TabBar-seg.html b/dojox/mobile/tests/test_iPhone-TabBar-seg.html
index 09821b1..b101769 100644
--- a/dojox/mobile/tests/test_iPhone-TabBar-seg.html
+++ b/dojox/mobile/tests/test_iPhone-TabBar-seg.html
@@ -4,8 +4,8 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
-		<!-- link href="../themes/android/android.css" rel="stylesheet"></link -->
+		<link href="../themes/iphone/base.css" rel="stylesheet">
+		<link href="../themes/iphone/TabBar.css" rel="stylesheet">
 
 		<style>
 			#list1 li{
@@ -32,14 +32,13 @@
 		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
 		</script>
 	</head>
-	<body>
+	<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>
diff --git a/dojox/mobile/tests/test_iPhone-TabBar.html b/dojox/mobile/tests/test_iPhone-TabBar.html
index ad9e212..4c1620b 100644
--- a/dojox/mobile/tests/test_iPhone-TabBar.html
+++ b/dojox/mobile/tests/test_iPhone-TabBar.html
@@ -4,7 +4,8 @@
 		<meta name="viewport" content="width=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>
+		<link href="../themes/iphone/base.css" rel="stylesheet">
+		<link href="../themes/iphone/TabBar.css" rel="stylesheet">
 		<style>
 		.label {
 			font-family: "Helvetica Neue", Helvetica;
@@ -13,7 +14,7 @@
 		}
 		.view {
 			font-size: 30px;
-			margin-top: 30px;
+			padding-top: 30px;
 			text-align: center;
 		}
 		</style>
@@ -21,14 +22,13 @@
 		<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");			// 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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
 		</script>
 	</head>
-	<body>
+	<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>
diff --git a/dojox/mobile/tests/test_iPhone-TabContainer.html b/dojox/mobile/tests/test_iPhone-TabContainer.html
deleted file mode 100644
index e453c2f..0000000
--- a/dojox/mobile/tests/test_iPhone-TabContainer.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>
-<!--
-	Deprecated: Use dojox.mobile.TabBar instead.
-	See test_iPhone-TabBar-seg-grouped.html for an equivalent example.
--->
-	<head>
-		<meta name="viewport" content="width=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 Container (deprecated)</title>
-		<link href="../themes/iphone/iphone.css" rel="stylesheet"></link>
-
-		<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("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.TabContainer");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		</script>
-	</head>
-	<body>
-		<div dojoType="dojox.mobile.View" id="general" selected="true">
-			<div dojoType="dojox.mobile.TabContainer">
-				<div dojoType="dojox.mobile.TabPane" label="New">
-					<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 dojoType="dojox.mobile.TabPane" label="What's Hot">
-					<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 dojoType="dojox.mobile.TabPane" label="Genius">
-					<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>
-		<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="general">
-					Hello
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="general">
-					Carrier
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-VariableHeightList.html b/dojox/mobile/tests/test_iPhone-VariableHeightList.html
index dbcbe81..8de6ba0 100755
--- a/dojox/mobile/tests/test_iPhone-VariableHeightList.html
+++ b/dojox/mobile/tests/test_iPhone-VariableHeightList.html
@@ -4,7 +4,7 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<link href="../themes/iphone/base.css" rel="stylesheet">
 		<style>
 		.content {
 			padding:0px 10px;
@@ -42,14 +42,13 @@
 		<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("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>
+	<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>
diff --git a/dojox/mobile/tests/test_list-actions.html b/dojox/mobile/tests/test_list-actions.html
new file mode 100644
index 0000000..2231b72
--- /dev/null
+++ b/dojox/mobile/tests/test_list-actions.html
@@ -0,0 +1,225 @@
+<!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
new file mode 100644
index 0000000..6dd7134
--- /dev/null
+++ b/dojox/mobile/tests/test_list-domButtons.html
@@ -0,0 +1,227 @@
+<!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_new_transition-animations-standard.html b/dojox/mobile/tests/test_new_transition-animations-standard.html
new file mode 100644
index 0000000..38e38e3
--- /dev/null
+++ b/dojox/mobile/tests/test_new_transition-animations-standard.html
@@ -0,0 +1,85 @@
+<!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>Standard Transitions</title>
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblCSS3Transition: 'dojox/css3/transit'"></script>
+
+		<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>
+
+		<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>
+
+		<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>
+
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_new_transition-animations.html b/dojox/mobile/tests/test_new_transition-animations.html
new file mode 100644
index 0000000..ce917db
--- /dev/null
+++ b/dojox/mobile/tests/test_new_transition-animations.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>Sample of View Transitions</title>
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblCSS3Transition: 'dojox/css3/transit'"></script>
+
+		<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>
+</html>
diff --git a/dojox/mobile/tests/test_new_transition-animations2.html b/dojox/mobile/tests/test_new_transition-animations2.html
new file mode 100644
index 0000000..de5f2bc
--- /dev/null
+++ b/dojox/mobile/tests/test_new_transition-animations2.html
@@ -0,0 +1,260 @@
+<!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 Animations on ScrollableView</title>
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar:true, mblCSS3Transition: 'dojox/css3/transit'"></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.deviceTheme");
+			dojo.require("dojox.mobile.ScrollableView");
+
+//			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>
+
+		<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>
+
+		<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>
+</html>
diff --git a/dojox/mobile/tests/test_orientation-transition.html b/dojox/mobile/tests/test_orientation-transition.html
index 62f099f..206fe22 100644
--- a/dojox/mobile/tests/test_orientation-transition.html
+++ b/dojox/mobile/tests/test_orientation-transition.html
@@ -4,39 +4,50 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<link href="../themes/iphone/base.css" rel="stylesheet">
 		<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.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-			dojo.addOnLoad(function(){
+			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");
+				var timer;
 				var onChange = function(){
-					if(window.orientation == 0 && dojox.mobile.currentView != portrait){
-						landscape.performTransition("portrait", 1, "fade");
-					}else if (window.orientation != 0 && dojox.mobile.currentView != landscape){
-						portrait.performTransition("landscape", 1, "fade");
+					var dim = dojox.mobile.getScreenSize();
+					var n, t;
+					if(timer){
+						clearTimeout(timer);
+					}
+					if(dim.h > dim.w && dojox.mobile.currentView != portrait){
+						n = landscape.domNode;
+						t = (dojo.hasClass(n, "mblIn") || dojo.hasClass(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){
+						n = portrait.domNode;
+						t = (dojo.hasClass(n, "mblIn") || dojo.hasClass(n, "mblOut")) ? 2000 : 0;
+						timer = setTimeout(function(){
+							portrait.performTransition("landscape", 1, "fade");
+							timer = null;
+						}, t);
 					}
 				};
-				if(window.orientation != 0){
+				if(dojo.hasClass(dojo.doc.documentElement, "dj_landscape")){
 					setTimeout(function(){
 						landscape.show();
 					}, 0);
 				}
-				if(window.onorientationchange !== undefined){
-					dojo.connect(dojo.global, "onorientationchange", onChange);
-				}else{
-					dojo.connect(dojo.global, "onresize", onChange);
-				}
+				dojo.connect(null, (dojo.global.onorientationchange !== undefined && !dojo.isAndroid)
+					? "onorientationchange" : "onresize", null, onChange);
 			});
 		</script>
 	</head>
-	<body>
+	<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;">
diff --git a/dojox/mobile/tests/test_progress-indicator.html b/dojox/mobile/tests/test_progress-indicator.html
index 4ee1857..0ce90bc 100755
--- a/dojox/mobile/tests/test_progress-indicator.html
+++ b/dojox/mobile/tests/test_progress-indicator.html
@@ -4,17 +4,16 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<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("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+)(.*)/);
@@ -26,28 +25,13 @@
 				var prog = dojox.mobile.ProgressIndicator.getInstance();
 				container.appendChild(prog.domNode);
 				prog.start();
-				/*
-				var url = "http://..." + param;
-				dojo.xhrGet({
-					url: url,
-					handleAs: "text",
-					load: function(response, ioArgs){
-						prog.stop();
-						container.innerHTML = response;
-						dojox.mobile.parser.parse(container);
-					}
-				});
-				*/
 				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,
-			{
+			dojo.declare("dojox.mobile.ViewEx",dojox.mobile.View,{
 				onStartView: function(){
 					loadPage(location.hash);
 				},
@@ -57,7 +41,7 @@
 			});
 		</script>
 	</head>
-	<body>
+	<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>
@@ -74,7 +58,7 @@
 			</ul>
 			<div dojoType="dojox.mobile.RoundRect">
 				A progress indicator shows up about 5 seconds before a view content is displayed.
-				After you moves 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.
+				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>
 
diff --git a/dojox/mobile/tests/test_screen-size-aware-async.html b/dojox/mobile/tests/test_screen-size-aware-async.html
new file mode 100644
index 0000000..46c5b8e
--- /dev/null
+++ b/dojox/mobile/tests/test_screen-size-aware-async.html
@@ -0,0 +1,315 @@
+<!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
new file mode 100644
index 0000000..245b6f4
--- /dev/null
+++ b/dojox/mobile/tests/test_screen-size-aware-demo.html
@@ -0,0 +1,175 @@
+<!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
new file mode 100644
index 0000000..fd3501b
--- /dev/null
+++ b/dojox/mobile/tests/test_screen-size-aware.html
@@ -0,0 +1,308 @@
+<!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
index 94c5783..ab4fe46 100644
--- a/dojox/mobile/tests/test_scrollable-no-dojo-af.html
+++ b/dojox/mobile/tests/test_scrollable-no-dojo-af.html
@@ -4,7 +4,16 @@
 		<meta name="viewport" content="width=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>
-		<link href="../themes/iphone/iphone.css" rel="stylesheet"></link>
+		<!--
+			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%;
@@ -12,6 +21,7 @@
 			visibility: visible;
 		}
 		.domNode {
+			position: relative;
 			height: 100%;
 			overflow: hidden;
 		}
@@ -35,6 +45,8 @@
 				containerNode: document.getElementById("inner"),
 				fixedFooterHeight: document.getElementById("footer1").offsetHeight
 			});
+			dojo.connect(dojo.global, (dojo.global.onorientationchange !== undefined)
+				? "onorientationchange" : "onresize", scrollable, "resize");
 		}
 		</script>
 	</head>
@@ -105,7 +117,27 @@
 						<li>Item</li>
 						<li>Item</li>
 						<li>Item</li>
-					<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>
+					</ol>
 				</div>
 			</div>
 		</div>
diff --git a/dojox/mobile/tests/test_scrollable-no-dojo-ah-af.html b/dojox/mobile/tests/test_scrollable-no-dojo-ah-af.html
index 239c89b..5e0fa54 100644
--- a/dojox/mobile/tests/test_scrollable-no-dojo-ah-af.html
+++ b/dojox/mobile/tests/test_scrollable-no-dojo-ah-af.html
@@ -4,7 +4,16 @@
 		<meta name="viewport" content="width=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>
-		<link href="../themes/iphone/iphone.css" rel="stylesheet"></link>
+		<!--
+			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%;
@@ -12,6 +21,7 @@
 			visibility: visible;
 		}
 		.domNode {
+			position: relative;
 			height: 100%;
 			overflow: hidden;
 		}
@@ -20,7 +30,7 @@
 			width: 100%;
 		}
 		#header1 {
-			position: absolute;
+			position: relative;
 			width: 100%;
 		}
 		#footer1 {
@@ -37,9 +47,10 @@
 			scrollable.init({
 				domNode: document.getElementById("outer"),
 				containerNode: document.getElementById("inner"),
-				fixedHeaderHeight: document.getElementById("header1").offsetHeight,
 				fixedFooterHeight: document.getElementById("footer1").offsetHeight
 			});
+			dojo.connect(dojo.global, (dojo.global.onorientationchange !== undefined)
+				? "onorientationchange" : "onresize", scrollable, "resize");
 		}
 		</script>
 	</head>
@@ -112,7 +123,27 @@
 						<li>Item</li>
 						<li>Item</li>
 						<li>Item</li>
-					<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>
+					</ol>
 				</div>
 			</div>
 		</div>
diff --git a/dojox/mobile/tests/test_scrollable-no-dojo-ah.html b/dojox/mobile/tests/test_scrollable-no-dojo-ah.html
index 4d43d8e..481d9b5 100644
--- a/dojox/mobile/tests/test_scrollable-no-dojo-ah.html
+++ b/dojox/mobile/tests/test_scrollable-no-dojo-ah.html
@@ -4,7 +4,16 @@
 		<meta name="viewport" content="width=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>
-		<link href="../themes/iphone/iphone.css" rel="stylesheet"></link>
+		<!--
+			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%;
@@ -12,6 +21,7 @@
 			visibility: visible;
 		}
 		.domNode {
+			position: relative;
 			height: 100%;
 			overflow: hidden;
 		}
@@ -20,7 +30,7 @@
 			width: 100%;
 		}
 		#header1 {
-			position: absolute;
+			position: relative;
 			width: 100%;
 		}
 		</style>
@@ -31,9 +41,10 @@
 			var scrollable = new dojox.mobile.scrollable();
 			scrollable.init({
 				domNode: document.getElementById("outer"),
-				containerNode: document.getElementById("inner"),
-				fixedHeaderHeight: document.getElementById("header1").offsetHeight
+				containerNode: document.getElementById("inner")
 			});
+			dojo.connect(dojo.global, (dojo.global.onorientationchange !== undefined)
+				? "onorientationchange" : "onresize", scrollable, "resize");
 		}
 		</script>
 	</head>
@@ -106,7 +117,27 @@
 						<li>Item</li>
 						<li>Item</li>
 						<li>Item</li>
-					<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>
+					</ol>
 				</div>
 			</div>
 		</div>
diff --git a/dojox/mobile/tests/test_scrollable-no-dojo.html b/dojox/mobile/tests/test_scrollable-no-dojo.html
index 203cbbb..1f671fe 100644
--- a/dojox/mobile/tests/test_scrollable-no-dojo.html
+++ b/dojox/mobile/tests/test_scrollable-no-dojo.html
@@ -4,6 +4,15 @@
 		<meta name="viewport" content="width=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%;
@@ -13,11 +22,12 @@
 			padding: 0px;
 		}
 		.domNode {
+			position: relative;
 			height: 100%;
 			overflow: hidden;
 		}
 		#header1 {
-			position: absolute;
+			position: relative;
 			margin: 0px;
 			width: 100%;
 			background-color: cyan;
@@ -33,9 +43,10 @@
 			var scrollable = new dojox.mobile.scrollable();
 			scrollable.init({
 				domNode: document.getElementById("outer"),
-				containerNode: document.getElementById("inner"),
-				fixedHeaderHeight: document.getElementById("header1").offsetHeight
+				containerNode: document.getElementById("inner")
 			});
+			dojo.connect(dojo.global, (dojo.global.onorientationchange !== undefined)
+				? "onorientationchange" : "onresize", scrollable, "resize");
 		}
 		</script>
 	</head>
@@ -84,7 +95,27 @@
 					<li>Item</li>
 					<li>Item</li>
 					<li>Item</li>
-				<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>
+				</ol>
 			</div>
 		</div>
 	</body>
diff --git a/dojox/mobile/tests/test_transition-animations-extended1.html b/dojox/mobile/tests/test_transition-animations-extended1.html
new file mode 100644
index 0000000..e7dd8e1
--- /dev/null
+++ b/dojox/mobile/tests/test_transition-animations-extended1.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>Extended Transitions 1</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 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>
+
+		<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>
+
+		<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>
+
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_transition-animations-extended2.html b/dojox/mobile/tests/test_transition-animations-extended2.html
new file mode 100644
index 0000000..d787662
--- /dev/null
+++ b/dojox/mobile/tests/test_transition-animations-extended2.html
@@ -0,0 +1,85 @@
+<!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>Extended Transitions 2</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 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>
+
+		<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>
+
+		<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>
+
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_transition-animations-extended3.html b/dojox/mobile/tests/test_transition-animations-extended3.html
new file mode 100644
index 0000000..0a19e4f
--- /dev/null
+++ b/dojox/mobile/tests/test_transition-animations-extended3.html
@@ -0,0 +1,85 @@
+<!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>Extended Transitions 3</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 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>
+
+		<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>
+
+		<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>
+
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_transition-animations-extended4.html b/dojox/mobile/tests/test_transition-animations-extended4.html
new file mode 100644
index 0000000..0b49c94
--- /dev/null
+++ b/dojox/mobile/tests/test_transition-animations-extended4.html
@@ -0,0 +1,73 @@
+<!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>Extended Transitions 4</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 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>
+
+		<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>
+
+		<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>
+
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_transition-animations-extended5.html b/dojox/mobile/tests/test_transition-animations-extended5.html
new file mode 100644
index 0000000..af7bf39
--- /dev/null
+++ b/dojox/mobile/tests/test_transition-animations-extended5.html
@@ -0,0 +1,59 @@
+<!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>Extended Transitions 5</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 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>
+
+		<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>
+
+		<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>
+
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_transition-animations-standard.html b/dojox/mobile/tests/test_transition-animations-standard.html
new file mode 100644
index 0000000..4f485d2
--- /dev/null
+++ b/dojox/mobile/tests/test_transition-animations-standard.html
@@ -0,0 +1,73 @@
+<!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>Standard Transitions</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 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>
+
+		<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>
+
+		<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>
+
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_transition-animations.html b/dojox/mobile/tests/test_transition-animations.html
new file mode 100644
index 0000000..96c3095
--- /dev/null
+++ b/dojox/mobile/tests/test_transition-animations.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>Sample of View Transitions</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 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>
+</html>
diff --git a/dojox/mobile/tests/test_transition-animations2.html b/dojox/mobile/tests/test_transition-animations2.html
new file mode 100644
index 0000000..e05d6dd
--- /dev/null
+++ b/dojox/mobile/tests/test_transition-animations2.html
@@ -0,0 +1,258 @@
+<!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 Animations on ScrollableView</title>
+		<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.deviceTheme");
+			dojo.require("dojox.mobile.ScrollableView");
+
+			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>
+
+		<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>
+
+		<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>
+
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_transition-connect.html b/dojox/mobile/tests/test_transition-connect.html
new file mode 100644
index 0000000..148d3b6
--- /dev/null
+++ b/dojox/mobile/tests/test_transition-connect.html
@@ -0,0 +1,68 @@
+<!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 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
+			var print = function(name, view, moveTo, dir, transition, context, method){
+				console.log(name +
+							": view=" + view +
+							", moveTo=" + moveTo +
+							", dir=" + dir +
+							", transition=" + transition +
+							", context=" + context +
+							", method=" + method +
+							", movedFrom=" + view.movedFrom);
+			};
+			dojo.ready(function(){
+				var view1 = dijit.byId("view1");
+				dojo.connect(view1, "onStartView", null, function(){
+					console.log("startView: view="+this);
+				});
+				dojo.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){
+					print("onBeforeTransitionIn", this, moveTo, dir, transition, context, method);
+				});
+				dojo.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){
+					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>
+
+		<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>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_transition-pubsub.html b/dojox/mobile/tests/test_transition-pubsub.html
new file mode 100644
index 0000000..6d6bab7
--- /dev/null
+++ b/dojox/mobile/tests/test_transition-pubsub.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 name="viewport" content="width=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>
+
+		<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
+
+			var print = function(name, view, moveTo, dir, transition, context, method){
+				console.log(name +
+							": view=" + view +
+							", moveTo=" + moveTo +
+							", dir=" + dir +
+							", transition=" + transition +
+							", context=" + context +
+							", method=" + method +
+							", movedFrom=" + view.movedFrom);
+			};
+
+			dojo.subscribe("/dojox/mobile/startView", function(view){
+				console.log("startView: view="+view);
+			});
+			dojo.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){
+				print("onBeforeTransitionIn", view, moveTo, dir, transition, context, method);
+			});
+			dojo.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){
+				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>
+
+		<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>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_transition-to-dynamic-view.html b/dojox/mobile/tests/test_transition-to-dynamic-view.html
index 5cbb792..8e93f05 100644
--- a/dojox/mobile/tests/test_transition-to-dynamic-view.html
+++ b/dojox/mobile/tests/test_transition-to-dynamic-view.html
@@ -4,59 +4,54 @@
 		<meta name="viewport" content="width=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/iphone.css" rel="stylesheet"></link>
+		<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.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-			dojo.declare(
-				"dojox.mobile.ListItemEx",
-				dojox.mobile.ListItem,
-			{
-				_parse: function(text){
-					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();
+			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
 
-					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
+			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"
 						});
-						list1.addChild(item1);
+						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;						
 					}
-					var id = view1.id;
-					return dojo.hash ? "#" + id : id;
+					this.inherited(arguments);
 				}
 			});
 		</script>
 	</head>
-	<body>
+	<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>
diff --git a/dojox/mobile/themes/android/Button-compat.css b/dojox/mobile/themes/android/Button-compat.css
new file mode 100644
index 0000000..c1bd8cf
--- /dev/null
+++ b/dojox/mobile/themes/android/Button-compat.css
@@ -0,0 +1,33 @@
+/* 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;
+}
+.mblButtonSelected {
+	background-color: #ffab00;
+	background-image: url(compat/button-sel-bg.png);
+}
+.mblButtonDisabled {
+	background-image: none;
+}
+.mblBlueButton {
+	background-color: #2261dd;
+	background-image: url(compat/blue-button-bg.png);
+}
+.mblBlueButtonSelected {
+	background-color: #ffab00;
+	background-image: url(compat/button-sel-bg.png);
+}
+.mblRedButton {
+	background-color: #ee4115;
+	background-image: url(compat/red-button-bg.png);
+}
+.mblRedButtonSelected {
+	background-color: #ffab00;
+	background-image: url(compat/button-sel-bg.png);
+}
diff --git a/dojox/mobile/themes/android/Button.css b/dojox/mobile/themes/android/Button.css
new file mode 100644
index 0000000..2eb8311
--- /dev/null
+++ b/dojox/mobile/themes/android/Button.css
@@ -0,0 +1,45 @@
+/* dojox.mobile.Button */
+.mblButton {
+  cursor: pointer;
+  outline: none;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  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));
+  color: black;
+  font-family: Helvetica;
+  font-size: 13px;
+  line-height: 29px;
+}
+.mblButton.mblBlueButton {
+  -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;
+}
+.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));
+  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;
+}
+.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));
+  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));
+  color: white;
+}
+.mblButtonDisabled, .mblButton:disabled {
+  cursor: default;
+  border-color: grey;
+  background-image: none;
+  color: grey;
+}
diff --git a/dojox/mobile/themes/android/Button.less b/dojox/mobile/themes/android/Button.less
new file mode 100644
index 0000000..ab3a96c
--- /dev/null
+++ b/dojox/mobile/themes/android/Button.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..a415950
--- /dev/null
+++ b/dojox/mobile/themes/android/Carousel.css
@@ -0,0 +1,60 @@
+/* dojox.mobile.Carousel */
+.mblCarousel {
+  overflow: hidden;
+}
+.mblCarouselBox {
+  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;
+}
+.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;
+}
diff --git a/dojox/mobile/themes/android/Carousel.less b/dojox/mobile/themes/android/Carousel.less
new file mode 100644
index 0000000..d717397
--- /dev/null
+++ b/dojox/mobile/themes/android/Carousel.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/Carousel.less";
diff --git a/dojox/mobile/themes/android/CheckBox-compat.css b/dojox/mobile/themes/android/CheckBox-compat.css
new file mode 100644
index 0000000..1a37a2a
--- /dev/null
+++ b/dojox/mobile/themes/android/CheckBox-compat.css
@@ -0,0 +1,37 @@
+/* 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);
+}
+.mblCheckBoxSelected {
+	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);
+}
+
diff --git a/dojox/mobile/themes/android/CheckBox.css b/dojox/mobile/themes/android/CheckBox.css
new file mode 100644
index 0000000..bf3c3f5
--- /dev/null
+++ b/dojox/mobile/themes/android/CheckBox.css
@@ -0,0 +1,44 @@
+/* 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;
+  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 {
+  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, .mblCheckBox:checked {
+  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));
+}
+.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);
+  -webkit-transform-origin: 50% 50%;
+}
+.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;
+}
diff --git a/dojox/mobile/themes/android/CheckBox.less b/dojox/mobile/themes/android/CheckBox.less
new file mode 100644
index 0000000..09f93b2
--- /dev/null
+++ b/dojox/mobile/themes/android/CheckBox.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..d9e9fa9
--- /dev/null
+++ b/dojox/mobile/themes/android/ComboBox-compat.css
@@ -0,0 +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;
+}
diff --git a/dojox/mobile/themes/android/ComboBox.css b/dojox/mobile/themes/android/ComboBox.css
new file mode 100644
index 0000000..8556a91
--- /dev/null
+++ b/dojox/mobile/themes/android/ComboBox.css
@@ -0,0 +1,45 @@
+/* dojox.mobile.ComboBox */
+.dijitPopup {
+  margin: 0;
+  padding: 0;
+  position: absolute;
+  border: 0;
+  background-color: transparent;
+  -webkit-box-shadow: 0px 0px 50px black;
+  -webkit-border-radius: 0px;
+}
+.mblReset {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  line-height: normal;
+  font: inherit;
+  color: inherit;
+}
+.mblComboBoxMenu {
+  overflow-y: hidden !important;
+  position: relative;
+  overflow: hidden;
+  border: 1px solid black;
+  -webkit-border-radius: 0px;
+  background-color: white;
+  color: black;
+}
+.mblComboBoxMenuItem {
+  white-space: nowrap;
+  padding: .1em .2em;
+  border-width: 1px 0 1px 0;
+  border-style: solid;
+  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));
+  color: white;
+}
+.mblComboBoxMenuPreviousButton, .mblComboBoxMenuNextButton {
+  font-style: italic;
+  overflow: hidden;
+}
diff --git a/dojox/mobile/themes/android/ComboBox.less b/dojox/mobile/themes/android/ComboBox.less
new file mode 100644
index 0000000..ab9458c
--- /dev/null
+++ b/dojox/mobile/themes/android/ComboBox.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/ComboBox.less";
diff --git a/dojox/mobile/themes/android/EdgeToEdgeCategory.css b/dojox/mobile/themes/android/EdgeToEdgeCategory.css
new file mode 100644
index 0000000..f585a35
--- /dev/null
+++ b/dojox/mobile/themes/android/EdgeToEdgeCategory.css
@@ -0,0 +1,18 @@
+/* dojox.mobile.EdgeToEdgeCategory */
+.mblEdgeToEdgeCategory {
+  position: relative;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  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;
+}
diff --git a/dojox/mobile/themes/android/EdgeToEdgeCategory.less b/dojox/mobile/themes/android/EdgeToEdgeCategory.less
new file mode 100644
index 0000000..3bb63da
--- /dev/null
+++ b/dojox/mobile/themes/android/EdgeToEdgeCategory.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..83e2a57
--- /dev/null
+++ b/dojox/mobile/themes/android/EdgeToEdgeList.css
@@ -0,0 +1,12 @@
+/* dojox.mobile.EdgeToEdgeList */
+.mblEdgeToEdgeList {
+  position: relative;
+  /* IE needs this */
+
+  margin: 0px;
+  padding: 0px;
+  background-color: black;
+}
+.mblEdgeToEdgeList .mblListItem:last-child {
+  border-bottom-color: #313431;
+}
diff --git a/dojox/mobile/themes/android/EdgeToEdgeList.less b/dojox/mobile/themes/android/EdgeToEdgeList.less
new file mode 100644
index 0000000..227627c
--- /dev/null
+++ b/dojox/mobile/themes/android/EdgeToEdgeList.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/EdgeToEdgeList.less";
diff --git a/dojox/mobile/themes/android/Heading-compat.css b/dojox/mobile/themes/android/Heading-compat.css
new file mode 100644
index 0000000..8b9b01f
--- /dev/null
+++ b/dojox/mobile/themes/android/Heading-compat.css
@@ -0,0 +1,22 @@
+/* mbl.widget.Heading */
+.mblHeading {
+	background-image: url(compat/heading-bg.png);
+}
+.mblHeadingSpanTitle {
+	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);
+}
diff --git a/dojox/mobile/themes/android/Heading.css b/dojox/mobile/themes/android/Heading.css
new file mode 100644
index 0000000..8147058
--- /dev/null
+++ b/dojox/mobile/themes/android/Heading.css
@@ -0,0 +1,81 @@
+/* dojox.mobile.Heading */
+.mblHeading {
+  position: relative;
+  margin: 0px;
+  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;
+  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;
+}
+.mblHeading * {
+  z-index: 2;
+}
+.mblHeadingDivTitle {
+  position: absolute;
+  width: 100%;
+  display: none;
+  left: 0px;
+  z-index: 1;
+}
+.mblHeadingCenterTitle .mblHeadingDivTitle {
+  display: block;
+}
+.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
new file mode 100644
index 0000000..cfc8580
--- /dev/null
+++ b/dojox/mobile/themes/android/Heading.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..adf6d49
--- /dev/null
+++ b/dojox/mobile/themes/android/IconContainer-compat.css
@@ -0,0 +1,11 @@
+ at import url("../common/domButtons/DomButtonColorButtons-compat.css");
+
+/* dojox.mobile.IconItem */
+.mblIconArea div {
+	*font-size: 60px; /* IE 7 quirks */
+}
+
+/* Icon Content Heading */
+.mblIconContentHeading {
+	background-image: url(compat/icon-content-heading-bg.png);
+}
diff --git a/dojox/mobile/themes/android/IconContainer.css b/dojox/mobile/themes/android/IconContainer.css
new file mode 100644
index 0000000..9e11d7b
--- /dev/null
+++ b/dojox/mobile/themes/android/IconContainer.css
@@ -0,0 +1,99 @@
+ at import url("../common/domButtons/DomButtonColorButtons.css");
+
+ at import url("../common/IconContainer_keyframes.css");
+/* dojox.mobile.IconContainer */
+.mblIconContainer {
+  margin: 20px 0px 0px 10px;
+  padding: 0px 0px 40px 0px;
+}
+/* dojox.mobile.IconItem */
+.mblIconItem {
+  list-style-type: none;
+  float: left;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblIconItemTerminator {
+  list-style-type: none;
+  clear: both;
+  height: 20px;
+}
+.mblIconItemSub {
+  list-style-type: none;
+  margin-left: -10px;
+  background-color: white;
+  color: black;
+}
+.mblIconArea {
+  margin-bottom: 10px;
+  height: 78px;
+  width: 74px;
+  font-family: Helvetica;
+  font-size: 12px;
+  color: white;
+  text-align: center;
+}
+.mblIconArea div {
+  position: relative;
+  height: 65px;
+  line-height: 65px;
+  text-align: center;
+}
+.mblIconArea img {
+  vertical-align: middle;
+}
+.mblIconItemSpriteIcon {
+  position: absolute;
+}
+.mblContent {
+  clear: both;
+  padding-bottom: 20px;
+}
+table.mblClose {
+  clear: both;
+  cursor: pointer;
+}
+.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);
+}
+.mblCloseContent {
+  -webkit-animation-duration: .3s;
+  -webkit-animation-timing-function: ease-in-out;
+  -webkit-animation-name: mblShrink;
+  -webkit-transform: scale(0.01);
+}
+.mblCloseContent.mblShrink0 {
+  -webkit-animation-name: mblShrink0;
+}
+.mblCloseContent.mblShrink1 {
+  -webkit-animation-name: mblShrink1;
+}
+.mblCloseContent.mblShrink2 {
+  -webkit-animation-name: mblShrink2;
+}
+.mblCloseContent.mblShrink3 {
+  -webkit-animation-name: mblShrink3;
+}
+/* Icon Content Heading */
+.mblIconContentHeading {
+  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;
+  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;
+}
diff --git a/dojox/mobile/themes/android/IconContainer.less b/dojox/mobile/themes/android/IconContainer.less
new file mode 100644
index 0000000..963eae6
--- /dev/null
+++ b/dojox/mobile/themes/android/IconContainer.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonColorButtons.css");
+ at import url("../common/IconContainer_keyframes.css");
+
+ at import "variables.less";
+ at import "../common/IconContainer.less";
diff --git a/dojox/mobile/themes/android/ListItem-compat.css b/dojox/mobile/themes/android/ListItem-compat.css
new file mode 100644
index 0000000..5ced8fe
--- /dev/null
+++ b/dojox/mobile/themes/android/ListItem-compat.css
@@ -0,0 +1,26 @@
+ at 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: 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%;
+}
+*html li.mblListItem.mblVariableHeight .mblListItemTextBox { /* IE6 hack */
+	height: auto;
+}
diff --git a/dojox/mobile/themes/android/ListItem.css b/dojox/mobile/themes/android/ListItem.css
new file mode 100644
index 0000000..8d61090
--- /dev/null
+++ b/dojox/mobile/themes/android/ListItem.css
@@ -0,0 +1,84 @@
+ at import url("../common/domButtons/DomButtonGrayArrow.css");
+
+ at import url("../common/domButtons/DomButtonWhiteCheck.css");
+/* dojox.mobile.ListItem */
+.mblListItem {
+  position: relative;
+  list-style-type: none;
+  vertical-align: bottom;
+  /* To avoid IE6 LI bug */
+
+  padding: 0px 0px 0px 7px;
+  height: 64px;
+  border-bottom: solid 1px #313431;
+  background-color: black;
+  font-size: 21px;
+  color: white;
+  line-height: 64px;
+}
+.mblListItem.mblVariableHeight {
+  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;
+}
+.mblListItem .mblListItemAnchor * {
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0.2);
+}
+.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));
+}
+.mblItemSelected .mblListItemAnchor {
+  color: black;
+}
+.mblItemSelected .mblDomButton div {
+  border-color: white;
+}
+.mblListItemTextBoxSelected {
+  background-color: #048BF4;
+}
+.mblListItemIcon {
+  float: left;
+  line-height: normal;
+  margin-top: 17px;
+  margin-right: 11px;
+}
+.mblListItemSpriteIcon {
+  position: absolute;
+  margin-top: 7px;
+  margin-left: 8px;
+}
+.mblListItemRightIcon, .mblListItemRightIcon2 {
+  position: relative;
+  float: right;
+  line-height: normal;
+  margin-top: 17px;
+  margin-bottom: -17px;
+}
+.mblListItemRightText {
+  position: relative;
+  float: right;
+  line-height: normal;
+  color: white;
+  margin: 20px 4px 0 0;
+}
+.mblListItemTextBox {
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+.mblVariableHeight .mblListItemTextBox {
+  white-space: normal;
+}
+.mblListItemSubText {
+  font-size: 14px;
+  color: gray;
+}
diff --git a/dojox/mobile/themes/android/ListItem.less b/dojox/mobile/themes/android/ListItem.less
new file mode 100644
index 0000000..45d4386
--- /dev/null
+++ b/dojox/mobile/themes/android/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/android/Opener-compat.css b/dojox/mobile/themes/android/Opener-compat.css
new file mode 100644
index 0000000..68cb1a8
--- /dev/null
+++ b/dojox/mobile/themes/android/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/android/Opener.css b/dojox/mobile/themes/android/Opener.css
new file mode 100644
index 0000000..8f2d4c8
--- /dev/null
+++ b/dojox/mobile/themes/android/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/android/Overlay-compat.css b/dojox/mobile/themes/android/Overlay-compat.css
new file mode 100644
index 0000000..3bc72a3
--- /dev/null
+++ b/dojox/mobile/themes/android/Overlay-compat.css
@@ -0,0 +1,13 @@
+/* dojox.mobile.Overlay */
+.mblOverlay {
+	_position: absolute;
+	text-align: center;
+}
+.dj_gecko .mblOverlay {
+	text-align: -moz-center;
+}
+.dj_ie9 .mblOverlay > *,
+.dj_ie8 .mblOverlay > *
+{
+	margin: 0 auto;
+}
diff --git a/dojox/mobile/themes/android/Overlay.css b/dojox/mobile/themes/android/Overlay.css
new file mode 100644
index 0000000..40a1228
--- /dev/null
+++ b/dojox/mobile/themes/android/Overlay.css
@@ -0,0 +1,18 @@
+ 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/android/Overlay.less b/dojox/mobile/themes/android/Overlay.less
new file mode 100644
index 0000000..e49ea9e
--- /dev/null
+++ b/dojox/mobile/themes/android/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/android/PageIndicator.css b/dojox/mobile/themes/android/PageIndicator.css
new file mode 100644
index 0000000..a175ad6
--- /dev/null
+++ b/dojox/mobile/themes/android/PageIndicator.css
@@ -0,0 +1,24 @@
+/* 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;
+  -webkit-border-radius: 3px;
+  -moz-border-radius: 3px;
+}
+.mblPageIndicatorDotSelected {
+  background-color: white;
+}
diff --git a/dojox/mobile/themes/android/PageIndicator.less b/dojox/mobile/themes/android/PageIndicator.less
new file mode 100644
index 0000000..9bb6c49
--- /dev/null
+++ b/dojox/mobile/themes/android/PageIndicator.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/PageIndicator.less";
diff --git a/dojox/mobile/themes/android/ProgressIndicator-compat.css b/dojox/mobile/themes/android/ProgressIndicator-compat.css
new file mode 100644
index 0000000..4ee0810
--- /dev/null
+++ b/dojox/mobile/themes/android/ProgressIndicator-compat.css
@@ -0,0 +1,46 @@
+/* Progress Indicator */
+.mblProg {
+	position: absolute;
+	top: 0px;
+	width: 4px;
+	font-size: 1px;
+	height: 36px;
+	overflow: hidden;
+	background-color: #C0C0C0;
+}
+.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;
+}
diff --git a/dojox/mobile/themes/android/ProgressIndicator.css b/dojox/mobile/themes/android/ProgressIndicator.css
new file mode 100644
index 0000000..2340637
--- /dev/null
+++ b/dojox/mobile/themes/android/ProgressIndicator.css
@@ -0,0 +1,58 @@
+/* Progress Indicator */
+.mblProgContainer {
+  position: absolute;
+  width: 40px;
+  height: 40px;
+  top: 180px;
+  left: 50%;
+  margin: -18px 0px 0px -18px;
+}
+.mblProg {
+  position: absolute;
+  left: 2px;
+  top: 0px;
+  width: 11px;
+  font-size: 1px;
+  height: 4px;
+  overflow: hidden;
+  -webkit-transform-origin: 0 2px;
+  background-color: #C0C0C0;
+  -webkit-border-radius: 2px;
+  -moz-border-radius: 2px;
+}
+.mblProg0 {
+  -webkit-transform: translate(18px, 10px) rotate(-90.1deg);
+}
+.mblProg1 {
+  -webkit-transform: translate(22px, 11px) rotate(-60deg);
+}
+.mblProg2 {
+  -webkit-transform: translate(25px, 14px) rotate(-30deg);
+}
+.mblProg3 {
+  -webkit-transform: translate(26px, 18px) rotate(0deg);
+}
+.mblProg4 {
+  -webkit-transform: translate(25px, 22px) rotate(30deg);
+}
+.mblProg5 {
+  -webkit-transform: translate(22px, 25px) rotate(60deg);
+}
+.mblProg6 {
+  -webkit-transform: translate(18px, 26px) rotate(90.1deg);
+}
+.mblProg7 {
+  -webkit-transform: translate(14px, 25px) rotate(120deg);
+}
+.mblProg8 {
+  -webkit-transform: translate(11px, 22px) rotate(150deg);
+}
+.mblProg9 {
+  -webkit-transform: translate(10px, 18px) rotate(180deg);
+}
+.mblProg10 {
+  -webkit-transform: translate(11px, 14px) rotate(210deg);
+}
+.mblProg11 {
+  -webkit-transform: translate(14px, 11px) rotate(240deg);
+}
diff --git a/dojox/mobile/themes/android/ProgressIndicator.less b/dojox/mobile/themes/android/ProgressIndicator.less
new file mode 100644
index 0000000..2ab2a2d
--- /dev/null
+++ b/dojox/mobile/themes/android/ProgressIndicator.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..17e473f
--- /dev/null
+++ b/dojox/mobile/themes/android/RadioButton-compat.css
@@ -0,0 +1,33 @@
+/* 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);
+}
+.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);
+}
diff --git a/dojox/mobile/themes/android/RadioButton.css b/dojox/mobile/themes/android/RadioButton.css
new file mode 100644
index 0000000..1f997dc
--- /dev/null
+++ b/dojox/mobile/themes/android/RadioButton.css
@@ -0,0 +1,41 @@
+/* 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;
+  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, .mblRadioButton:checked {
+  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));
+}
+.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);
+  -webkit-transform-origin: 50% 50%;
+}
+.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::after, .mblRadioButton:checked.mblRadioButtonSelected::after {
+  border-color: white;
+}
diff --git a/dojox/mobile/themes/android/RadioButton.less b/dojox/mobile/themes/android/RadioButton.less
new file mode 100644
index 0000000..0793ca6
--- /dev/null
+++ b/dojox/mobile/themes/android/RadioButton.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..cf3ce84
--- /dev/null
+++ b/dojox/mobile/themes/android/RoundRect-compat.css
@@ -0,0 +1,64 @@
+/* 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;
+}
diff --git a/dojox/mobile/themes/android/RoundRect.css b/dojox/mobile/themes/android/RoundRect.css
new file mode 100644
index 0000000..c76a82f
--- /dev/null
+++ b/dojox/mobile/themes/android/RoundRect.css
@@ -0,0 +1,13 @@
+/* dojox.mobile.RoundRect */
+.mblRoundRect {
+  margin: 7px 9px 16px;
+  padding: 8px;
+  border: 1px solid #ADAAAD;
+  -webkit-border-radius: 8px;
+  -moz-border-radius: 8px;
+  color: white;
+  background-color: black;
+}
+.mblRoundRect.mblShadow {
+  -webkit-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
new file mode 100644
index 0000000..efec816
--- /dev/null
+++ b/dojox/mobile/themes/android/RoundRect.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..9be5f0c
--- /dev/null
+++ b/dojox/mobile/themes/android/RoundRectCategory.css
@@ -0,0 +1,10 @@
+/* dojox.mobile.RoundRectCategory */
+.mblRoundRectCategory {
+  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
new file mode 100644
index 0000000..e9148cc
--- /dev/null
+++ b/dojox/mobile/themes/android/RoundRectCategory.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/RoundRectCategory.less";
diff --git a/dojox/mobile/themes/android/RoundRectList-compat.css b/dojox/mobile/themes/android/RoundRectList-compat.css
new file mode 100644
index 0000000..cf3ce84
--- /dev/null
+++ b/dojox/mobile/themes/android/RoundRectList-compat.css
@@ -0,0 +1,64 @@
+/* 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;
+}
diff --git a/dojox/mobile/themes/android/RoundRectList.css b/dojox/mobile/themes/android/RoundRectList.css
new file mode 100644
index 0000000..058587c
--- /dev/null
+++ b/dojox/mobile/themes/android/RoundRectList.css
@@ -0,0 +1,25 @@
+/* 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;
+}
+.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: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;
+}
diff --git a/dojox/mobile/themes/android/RoundRectList.less b/dojox/mobile/themes/android/RoundRectList.less
new file mode 100644
index 0000000..52e1164
--- /dev/null
+++ b/dojox/mobile/themes/android/RoundRectList.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/RoundRectList.less";
diff --git a/dojox/mobile/themes/android/Slider-compat.css b/dojox/mobile/themes/android/Slider-compat.css
new file mode 100644
index 0000000..c8a47f8
--- /dev/null
+++ b/dojox/mobile/themes/android/Slider-compat.css
@@ -0,0 +1,43 @@
+/* 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;
+}
+.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;
+}
+.mblSliderV .mblSliderProgressBar {
+	background: #00A200;
+}
+.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;
+}
diff --git a/dojox/mobile/themes/android/Slider.css b/dojox/mobile/themes/android/Slider.css
new file mode 100644
index 0000000..4a16e82
--- /dev/null
+++ b/dojox/mobile/themes/android/Slider.css
@@ -0,0 +1,62 @@
+/* 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;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bdbebd), to(#f7f3f7));
+  -webkit-border-radius: 2px;
+}
+.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 {
+  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;
+}
+.mblSliderHandle {
+  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));
+}
+.mblSliderTransition {
+  -webkit-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);
+}
diff --git a/dojox/mobile/themes/android/Slider.less b/dojox/mobile/themes/android/Slider.less
new file mode 100644
index 0000000..928972f
--- /dev/null
+++ b/dojox/mobile/themes/android/Slider.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/Slider.less";
diff --git a/dojox/mobile/themes/android/Switch-compat.css b/dojox/mobile/themes/android/Switch-compat.css
new file mode 100644
index 0000000..3756d95
--- /dev/null
+++ b/dojox/mobile/themes/android/Switch-compat.css
@@ -0,0 +1,70 @@
+/* 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 */
+.mblSwRoundShape1 .mblSwitchBgLeft {
+	background-image: url(compat/switch-round-l.gif);
+}
+.mblSwRoundShape1 .mblSwitchBgRight {
+	background-image: url(compat/switch-round-r.gif);
+}
+.mblSwRoundShape1 .mblSwitchKnob {
+	top: 1px;
+	height: 26px;
+	background-image: url(compat/switch-round1-k.gif);
+}
+/* Switch - Round Shape2 */
+.mblSwRoundShape2 .mblSwitchBgLeft {
+	background-image: url(compat/switch-round-l.gif);
+}
+.mblSwRoundShape2 .mblSwitchBgRight {
+	background-image: url(compat/switch-round-r.gif);
+}
+.mblSwRoundShape2 .mblSwitchKnob {
+	top: 1px;
+	height: 26px;
+	background-image: url(compat/switch-round2-k.gif);
+}
+/* Switch - Arc Shape1 */
+.mblSwArcShape1 .mblSwitchBgLeft {
+	background-image: url(compat/switch-arc-l.gif);
+}
+.mblSwArcShape1 .mblSwitchBgRight {
+	background-image: url(compat/switch-arc-r.gif);
+}
+.mblSwArcShape1 .mblSwitchKnob {
+	top: 1px;
+	height: 26px;
+	background-image: url(compat/switch-arc1-k.gif);
+}
+/* Switch - Arc Shape2 */
+.mblSwArcShape2 .mblSwitchBgLeft {
+	background-image: url(compat/switch-arc-l.gif);
+}
+.mblSwArcShape2 .mblSwitchBgRight {
+	background-image: url(compat/switch-arc-r.gif);
+}
+.mblSwArcShape2 .mblSwitchKnob {
+	top: 1px;
+	height: 26px;
+	background-image: url(compat/switch-arc2-k.gif);
+}
diff --git a/dojox/mobile/themes/android/Switch.css b/dojox/mobile/themes/android/Switch.css
new file mode 100644
index 0000000..f8d1147
--- /dev/null
+++ b/dojox/mobile/themes/android/Switch.css
@@ -0,0 +1,18 @@
+ at import url("../common/Switch.css");
+/* dojox.mobile.Switch */
+.mblItemSwitch {
+  top: 18px;
+}
+.mblSwitchBg {
+  -webkit-border-radius: 2px;
+}
+.mblSwitchBgLeft {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#00a200), to(#00d300), color-stop(0.2, #00ba00), color-stop(0.2, #00ba00));
+}
+.mblSwitchBgRight {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bdbebd), to(#f7f3f7));
+}
+.mblSwitchKnob {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#9c9a9c), to(#848284));
+  -webkit-border-radius: 2px;
+}
diff --git a/dojox/mobile/themes/android/Switch.less b/dojox/mobile/themes/android/Switch.less
new file mode 100644
index 0000000..84a1146
--- /dev/null
+++ b/dojox/mobile/themes/android/Switch.less
@@ -0,0 +1,4 @@
+ at import url("../common/Switch.css");
+
+ at import "variables.less";
+ at import "../common/Switch.less";
diff --git a/dojox/mobile/themes/android/TabBar-compat.css b/dojox/mobile/themes/android/TabBar-compat.css
new file mode 100644
index 0000000..94fbb13
--- /dev/null
+++ b/dojox/mobile/themes/android/TabBar-compat.css
@@ -0,0 +1,35 @@
+/* dojox.mobile.TabBarButton */
+.mblTabBar {
+	background-color: #1e1e1e;
+}
+.dj_ie6 .mblTabBarButtonDiv, .dj_ie7 .mblTabBarButtonDiv {
+	left: auto;
+}
+.dj_ie6 .mblTabBar .mblTabBarButton {
+  display: inline; /* IE bug*/
+}
+.mblTabBar .mblTabBarButton.mblTabButtonSelected {
+	-moz-border-radius: 3px;
+	background-image: none;
+}
+.mblTabPanelHeader .mblTabButton {
+	background-image: url(compat/tab-button-bg.png);
+}
+.mblTabPanelHeader .mblTabButton.mblTabButtonSelected {
+	background-image: url(compat/tab-sel-button-bg.png);
+}
+*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;
+}
+.mblHeading .mblTabPanelHeader .mblTabButton {
+	background-image: none;
+}
diff --git a/dojox/mobile/themes/android/TabBar.css b/dojox/mobile/themes/android/TabBar.css
new file mode 100644
index 0000000..99955c8
--- /dev/null
+++ b/dojox/mobile/themes/android/TabBar.css
@@ -0,0 +1,158 @@
+/* dojox.mobile.TabBar */
+.mblTabBar {
+  position: relative;
+  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-align: center;
+}
+.mblTabBarNoIcons {
+  height: 34px;
+}
+.mblTabBarNoText {
+  height: 34px;
+}
+/* dojox.mobile.TabBarButton */
+.mblTabBarButton {
+  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));
+}
+.mblTabBarButtonAnchor {
+  display: block;
+  text-decoration: none;
+}
+.mblTabBarButtonDiv {
+  position: relative;
+  margin-left: auto;
+  margin-right: auto;
+  width: 29px;
+  height: 32px;
+  margin-top: 2px;
+}
+.mblTabBarButtonIcon {
+  position: absolute;
+  left: 0px;
+  top: 0px;
+}
+.mblTabBarButtonSpriteIcon {
+  position: absolute;
+}
+.mblTabBarButtonTextBox {
+  font-family: "Helvetica Neue", Helvetica;
+  font-size: 11px;
+}
+.mblTabBarNoIcons .mblTabBarButtonDiv {
+  display: none;
+}
+.mblTabBarNoIcons .mblTabBarButtonTextBox {
+  line-height: 34px;
+  font-size: 20px;
+}
+.mblTabBarTop .mblTabButton .mblTabBarButtonDiv {
+  height: 38px;
+}
+.mblTabBarHead .mblTabButton .mblTabBarButtonDiv {
+  margin-top: -2px;
+}
+.mblTabButton {
+  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));
+  font-family: Helvetica;
+  font-size: 13px;
+  color: white;
+  text-align: center;
+}
+.mblTabButton img {
+  position: absolute;
+  left: 0px;
+  margin-top: 8px;
+}
+.mblTabButtonSelected .mblTabBarButtonTextBox {
+  color: white;
+}
+.mblTabButtonSelected.mblTabButton {
+  background-color: #8C8E8C;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#a59ea5), to(#848284));
+}
+.mblTabButtonHighlighted.mblTabButton {
+  background-color: #FFB600;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ffcb00), to(#ff9a00));
+}
+.mblTabButtonImgDiv {
+  position: relative;
+  margin-left: 24px;
+  height: 40px;
+}
+.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;
+  background-color: #000000;
+  font-family: Helvetica;
+  font-size: 20px;
+  color: white;
+  text-align: center;
+}
+.mblTabPanelHeader .mblTabButton {
+  margin-top: 3px;
+}
+.mblTabPanelHeader .mblTabButtonDomButton {
+  width: 43px;
+}
+.mblTabPanelHeader .mblTabButtonDomButtonClass {
+  left: 8px;
+}
+.mblHeading .mblTabPanelHeader {
+  height: 25px;
+}
+.mblHeading .mblTabPanelHeader .mblTabButton {
+  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));
+}
+.mblHeading .mblTabPanelHeader .mblTabButton:first-child {
+  border-left-width: 1px;
+}
+.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));
+}
diff --git a/dojox/mobile/themes/android/TabBar.less b/dojox/mobile/themes/android/TabBar.less
new file mode 100644
index 0000000..4875c40
--- /dev/null
+++ b/dojox/mobile/themes/android/TabBar.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/TabBar.less";
diff --git a/dojox/mobile/themes/android/TextArea-compat.css b/dojox/mobile/themes/android/TextArea-compat.css
new file mode 100644
index 0000000..a4312f1
--- /dev/null
+++ b/dojox/mobile/themes/android/TextArea-compat.css
@@ -0,0 +1,7 @@
+/* dojox.mobile.TextArea */
+.mblTextArea {
+	-moz-border-radius: 3px;
+	-o-border-radius: 3px;
+	-ms-border-radius: 3px;
+	border-radius: 3px;
+}
diff --git a/dojox/mobile/themes/android/TextArea.css b/dojox/mobile/themes/android/TextArea.css
new file mode 100644
index 0000000..4cb389c
--- /dev/null
+++ b/dojox/mobile/themes/android/TextArea.css
@@ -0,0 +1,14 @@
+/* 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;
+}
+/* dojox.mobile.ExpandingTextArea */
+.mblExpandingTextArea {
+  margin: 2px;
+}
diff --git a/dojox/mobile/themes/android/TextArea.less b/dojox/mobile/themes/android/TextArea.less
new file mode 100644
index 0000000..c16ffe0
--- /dev/null
+++ b/dojox/mobile/themes/android/TextArea.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..619c360
--- /dev/null
+++ b/dojox/mobile/themes/android/TextBox-compat.css
@@ -0,0 +1,7 @@
+/* dojox.mobile.TextBox */
+.mblTextBox {
+	-moz-border-radius: 3px;
+	-o-border-radius: 3px;
+	-ms-border-radius: 3px;
+	border-radius: 3px;
+}
diff --git a/dojox/mobile/themes/android/TextBox.css b/dojox/mobile/themes/android/TextBox.css
new file mode 100644
index 0000000..d847ab5
--- /dev/null
+++ b/dojox/mobile/themes/android/TextBox.css
@@ -0,0 +1,8 @@
+/* dojox.mobile.TextBox */
+.mblTextBox {
+  height: 22px;
+  border: #9CACC0 1px inset;
+  -webkit-border-radius: 3px;
+  font-family: Helvetica;
+  font-size: 13px;
+}
diff --git a/dojox/mobile/themes/android/TextBox.less b/dojox/mobile/themes/android/TextBox.less
new file mode 100644
index 0000000..c83890a
--- /dev/null
+++ b/dojox/mobile/themes/android/TextBox.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/TextBox.less";
diff --git a/dojox/mobile/themes/android/ToggleButton-compat.css b/dojox/mobile/themes/android/ToggleButton-compat.css
new file mode 100644
index 0000000..9891522
--- /dev/null
+++ b/dojox/mobile/themes/android/ToggleButton-compat.css
@@ -0,0 +1,30 @@
+/* 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;
+}
+.mblToggleButtonSelected {
+	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%;
+}
+.dj_ff3 .mblToggleButton.mblToggleButtonChecked::after {
+	-moz-transform: translate(-25px,-6px) rotate(45deg) skew(10deg);
+}
+.mblToggleButtonChecked.mblToggleButtonSelected {
+	background-image: url(compat/button-sel-bg.png);
+}
diff --git a/dojox/mobile/themes/android/ToggleButton.css b/dojox/mobile/themes/android/ToggleButton.css
new file mode 100644
index 0000000..31d0557
--- /dev/null
+++ b/dojox/mobile/themes/android/ToggleButton.css
@@ -0,0 +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;
+  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;
+  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));
+  color: white;
+}
+.mblToggleButton.mblToggleButtonChecked {
+  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;
+}
+.mblToggleButton.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);
+  -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 {
+  border-color: white;
+}
+.mblToggleButton:disabled {
+  cursor: default;
+  border-color: grey;
+  background-image: none;
+  color: grey;
+}
diff --git a/dojox/mobile/themes/android/ToggleButton.less b/dojox/mobile/themes/android/ToggleButton.less
new file mode 100644
index 0000000..bdce40f
--- /dev/null
+++ b/dojox/mobile/themes/android/ToggleButton.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/ToggleButton.less";
diff --git a/dojox/mobile/themes/android/ToolBarButton.css b/dojox/mobile/themes/android/ToolBarButton.css
new file mode 100644
index 0000000..968b029
--- /dev/null
+++ b/dojox/mobile/themes/android/ToolBarButton.css
@@ -0,0 +1,31 @@
+/* dojox.mobile.ToolBarButton */
+.mblToolBarButton {
+  float: left;
+  position: relative;
+  overflow: hidden;
+  cursor: pointer;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  margin: 0px 6px;
+  height: 22px;
+  border: 1px solid #555555;
+  font-family: Helvetica;
+  font-size: 13px;
+  font-weight: bold;
+  color: white;
+  line-height: 23px;
+  text-align: center;
+}
+div.mblToolBarButtonDomButton {
+  height: 23px;
+}
+.mblToolBarButtonIcon {
+  position: relative;
+  top: -2px;
+  padding: 0px;
+}
+.mblToolBarButtonSpriteIcon {
+  position: absolute;
+}
+.mblToolBarButtonText {
+  padding: 0px 10px;
+}
diff --git a/dojox/mobile/themes/android/ToolBarButton.less b/dojox/mobile/themes/android/ToolBarButton.less
new file mode 100644
index 0000000..3b67bdc
--- /dev/null
+++ b/dojox/mobile/themes/android/ToolBarButton.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/ToolBarButton.less";
diff --git a/dojox/mobile/themes/android/Tooltip-compat.css b/dojox/mobile/themes/android/Tooltip-compat.css
new file mode 100644
index 0000000..6fd514d
--- /dev/null
+++ b/dojox/mobile/themes/android/Tooltip-compat.css
@@ -0,0 +1,47 @@
+/* dojox.mobile.Tooltip */
+.mblTooltip {
+	-moz-border-radius: 8px;
+	-o-border-radius: 8px;
+	-ms-border-radius: 8px;
+	border-radius: 8px;
+	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_ie9 .mblTooltip .mblHeading {
+	width: auto;
+}
+.mblTooltip .mblHeading .mblToolBarButton {
+	*margin: auto 6px;
+}
diff --git a/dojox/mobile/themes/android/Tooltip.css b/dojox/mobile/themes/android/Tooltip.css
new file mode 100644
index 0000000..cc28997
--- /dev/null
+++ b/dojox/mobile/themes/android/Tooltip.css
@@ -0,0 +1,144 @@
+/* dojox.mobile.Tooltip */
+.mblTooltip {
+  position: absolute;
+  z-index: 2000;
+  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;
+  opacity: .97;
+}
+.mblTooltipBubble {
+  overflow: visible;
+  padding: 3px;
+  background-color: #FFC700;
+  background-image: none;
+  color: black;
+}
+.mblTooltipBubble.mblTooltipAbove .mblTooltipInnerArrow {
+  border-bottom-color: #FFC700;
+}
+.mblTooltipBubble.mblTooltipBelow .mblTooltipInnerArrow {
+  border-top-color: #FFC700;
+}
+.mblTooltipBubble.mblTooltipAfter .mblTooltipInnerArrow {
+  border-left-color: #FFC700;
+}
+.mblTooltipBubble.mblTooltipBefore .mblTooltipInnerArrow {
+  border-right-color: #FFC700;
+}
+.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;
+}
+.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/android/Tooltip.less b/dojox/mobile/themes/android/Tooltip.less
new file mode 100644
index 0000000..60af6d1
--- /dev/null
+++ b/dojox/mobile/themes/android/Tooltip.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/Tooltip.less";
diff --git a/dojox/mobile/themes/android/View.css b/dojox/mobile/themes/android/View.css
new file mode 100644
index 0000000..fe86a8c
--- /dev/null
+++ b/dojox/mobile/themes/android/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/android/View.less b/dojox/mobile/themes/android/View.less
new file mode 100644
index 0000000..910651f
--- /dev/null
+++ b/dojox/mobile/themes/android/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/android/android-app-compat.css b/dojox/mobile/themes/android/android-app-compat.css
index dc0a814..8a55bc6 100755
--- a/dojox/mobile/themes/android/android-app-compat.css
+++ b/dojox/mobile/themes/android/android-app-compat.css
@@ -1,5 +1,5 @@
 /* mbl.widget.Heading */
- at import url("iphone-compat.css");
+ at import url("android-compat.css");
 
 .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 77fc6cd..cb58fa3 100644
--- a/dojox/mobile/themes/android/android-app.css
+++ b/dojox/mobile/themes/android/android-app.css
@@ -50,31 +50,31 @@
 	margin-top: 5px;
 }
 
-.alertDialog.out {
+.alertDialog.mblOut {
 	position: absolute;
 }
 
-.alertDialog.in {
+.alertDialog.mblIn {
 	position: absolute;
 }
 
-.slidev.out {
+.mblSlidev.mblOut {
 	-webkit-animation-duration: .4s;
-	-webkit-animation-name: slideOut;
+	-webkit-animation-name: mblSlideOut;
 	-webkit-animation-timing-function: linear;
 	-webkit-transform: translateY(-100%);
 }
-.slidev.in {
+.mblSlidev.mblIn {
 	-webkit-animation-duration: .4s;
-	-webkit-animation-name: slideIn;
+	-webkit-animation-name: mblSlideIn;
 	-webkit-animation-timing-function: linear;
 	-webkit-transform: translateY(0px);
 }
-.slidev.out.reverse {
-	-webkit-animation-name: slideOutReverse;
+.mblSlidev.mblOut.mblReverse {
+	-webkit-animation-name: mblSlideOutReverse;
 }
-.slidev.in.reverse {
-	-webkit-animation-name: slideInReverse;
+.mblSlidev.mblIn.mblReverse {
+	-webkit-animation-name: mblSlideInReverse;
 }
 
 .dialogUnderlayWrapper {
diff --git a/dojox/mobile/themes/android/android-compat.css b/dojox/mobile/themes/android/android-compat.css
index a5552b2..f5a0140 100755
--- a/dojox/mobile/themes/android/android-compat.css
+++ b/dojox/mobile/themes/android/android-compat.css
@@ -1,290 +1,18 @@
-/* mbl.widget.Heading */
-.mblHeading {
-	background-image: url(compat/heading-bg.png);
-}
-
-/* Heading Arrow Button */
-.mblArrowButtonHead {
-	position: absolute;
-	top: 0px;
-	left: 8px;
-	width: 19px;
-	height: 29px;
-	border-style: none;
-	background-image: url(compat/arrow-button-head.png);
-}
-.mblArrowButtonBody {
-	padding: 0px 10px 0px 10px;
-	background-image: url(compat/arrow-button-bg.png);
-}
-
-/* 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;
-}
-
-/* mbl.widget.ListItem */
-*html li.mblListItem.mblVariableHeight { /* IE6 hack */
-	height: 0;
-}
-
-.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);
-}
-
-/* dojox.mobile.TabBarButton */
-.dj_ie6 .mblTabBarButtonDiv, .dj_ie7 .mblTabBarButtonDiv {
-	left: auto;
-}
-
-/* Switch */
-.mblSwitchInner {
-	width: 100px;
-}
-.mblSwitchBg {
-	border: none;
-}
-.mblSwitchBgLeft {
-	width: 89px;
-	background: none;
-}
-.mblSwitchBgRight {
-	width: 89px;
-	left: 58px;
-	background: none;
-}
-.mblSwitchKnobContainer {
-	position: relative;
-	left: 53px;
-	width: 41px;
-	height: 26px;
-}
-.mblSwitchKnob {
-	position: relative;
-	top: 0px;
-	left: 0px;
-	width: auto;
-	height: 21px;
-	background-image: url(compat/switch-knob-bg.png);
-	border-width: 0px 1px;
-	-moz-border-radius: 0px;
-}
-.mblSwitchCorner {
-	position: relative;
-	height: 1px;
-	font-size: 1px;
-	overflow: hidden;
-	border-style: solid;
-	border-color: #878787;
-}
-.mblSwitchCorner1T {
-	background-color: #848684;
-	margin: 0px 1px;
-	border-width: 0px;
-}
-.mblSwitchCorner2T {
-	background-color: #C0C0C0;
-	margin: 0px 0px;
-	border-width: 0px 1px;
-}
-.mblSwitchCorner3T {
-	background-color: #C6C7C6;
-	margin: 0px 0px;
-	border-width: 0px 1px;
-}
-
-.mblSwitchCorner1B {
-	background-color: #FBFBFB;
-	margin: 0px 0px;
-	border-width: 0px 1px;
-}
-.mblSwitchCorner2B {
-	background-color: #FBFBFB;
-	margin: 0px 0px;
-	border-width: 0px 1px;
-}
-.mblSwitchCorner3B {
-	background-color: #878787;
-	margin: 0px 1px;
-	border-width: 0px;
-}
-
-.mblSwitchBgLeft .mblSwitchCorner1T {
-	border-width: 0px 2px;
-	background-color: #00A600;
-}
-.mblSwitchBgLeft .mblSwitchCorner2T {
-	background-color: #00A600;
-}
-.mblSwitchBgLeft .mblSwitchCorner3T {
-	background-color: #00A600;
-}
-
-.mblSwitchBgLeft .mblSwitchCorner1B {
-	background-color: #00D700;
-}
-.mblSwitchBgLeft .mblSwitchCorner2B {
-	background-color: #00D700;
-}
-.mblSwitchBgLeft .mblSwitchCorner3B {
-	background-color: #00D700;
-}
-
-.mblSwitchText {
-	height: 21px;
-	line-height: 21px;
-}
-.mblSwitchTextLeft {
-	background-image: url(compat/switch-green-bg.png);
-	border-left: 1px solid #848684;
-}
-.mblSwitchTextRight {
-	background-image: url(compat/switch-gray-bg.png);
-	left: 35px;
-	border-right: 1px solid #848684;
-}
-
-/* Icon Content Heading */
-.mblIconContentHeading {
-	background-image: url(compat/icon-content-heading-bg.png);
-}
-
-/* dojox.mobile.Button */
-.mblBlueButton {
-	background-image: url(compat/blue-button-bg.png);
-}
-.mblBlueButtonSelected {
-	background-image: url(compat/blue-button-sel-bg.png);
-}
-
-/* Tab Container */
-.mblTabPanelHeader {
-}
-.mblTabButton {
-	background-image: url(compat/tab-button-bg.png);
-}
-.mblTabButtonSelected {
-	background-image: url(compat/tab-sel-button-bg.png);
-}
-*html .mblTabButton { /* IE6 hack */
-	behavior: expression(
-		(function(el){
-			if(!el.previousSibling)
-				el.style.borderWidth = "1px";
-			el.style.behavior = "none";
-		})(this)
-	);
-}
-
-/* Progress Indicator */
-.mblProg {
-	position: absolute;
-	top: 0px;
-	width: 4px;
-	font-size: 1px;
-	height: 36px;
-	overflow: hidden;
-	background-color: #C0C0C0;
-}
-.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;
-}
+ at import url("base-compat.css");
+
+/* common styles */
+ at import url("../common/domButtons-compat.css");
+ at import url("../common/SpinWheel-compat.css");
+
+/* widget styles */
+ 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("Opener-compat.css");
+ at import url("RadioButton-compat.css");
+ at import url("Slider-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");
diff --git a/dojox/mobile/themes/android/android.css b/dojox/mobile/themes/android/android.css
index 59620b0..a50e0ce 100755
--- a/dojox/mobile/themes/android/android.css
+++ b/dojox/mobile/themes/android/android.css
@@ -1,840 +1,22 @@
-body {
-	visibility: hidden;
-}
-
-html.mobile, .mobile body {
-	width: 100%;
-	margin: 0px;
-	padding: 0px;
-}
-.mobile body {
-	overflow-x: hidden;
-	-webkit-text-size-adjust: none;
-	background-color: black;
-	font-family: Helvetica;
-	font-size: 17px;
-}
-
-/* dojox.mobile.View */
-.mblView {
-	position: relative;
-	top: 0px;
-	left: 0px;
-	width: 100%;
-	color: white;
-}
-
-.mblView.out {
-}
-
-.mblView.in {
-	position: absolute;
-}
-
-.slide.out {
-	-webkit-animation-duration: .4s;
-	-webkit-animation-name: slideOut;
-	-webkit-animation-timing-function: linear;
-	-webkit-transform: translateX(-100%);
-}
-.slide.in {
-	-webkit-animation-duration: .4s;
-	-webkit-animation-name: slideIn;
-	-webkit-animation-timing-function: linear;
-	-webkit-transform: translateX(0px);
-}
-.slide.out.reverse {
-	-webkit-animation-name: slideOutReverse;
-}
-.slide.in.reverse {
-	-webkit-animation-name: slideInReverse;
-}
- at -webkit-keyframes slideOut {
-	from { -webkit-transform: translateX(0px); }
-	to { -webkit-transform: translateX(-100%); }
-}
- at -webkit-keyframes slideIn {
-	from { -webkit-transform: translateX(100%); }
-	to { -webkit-transform: translateX(0px); }
-}
- at -webkit-keyframes slideOutReverse {
-	from { -webkit-transform: translateX(0px); }
-	to { -webkit-transform: translateX(100%); }
-}
- at -webkit-keyframes slideInReverse {
-	from { -webkit-transform: translateX(-100%); }
-	to { -webkit-transform: translateX(0px); }
-}
-
-.flip.out {
-	-webkit-animation-duration: .6s;
-	-webkit-animation-name: flipOut;
-	-webkit-animation-timing-function: ease-in;
-	-webkit-transform: rotateY(90deg);
-}
-.flip.in {
-	-webkit-animation-duration: .6s;
-	-webkit-animation-name: flipIn;
-	-webkit-animation-timing-function: ease-out;
-}
- at -webkit-keyframes flipOut {
-	0% { -webkit-transform: rotateY(0deg) scale(1); }
-	50% { -webkit-transform: rotateY(90deg) scale(.8); }
-	100% { -webkit-transform: rotateY(90deg) scale(.8); }
-}
-
- at -webkit-keyframes flipIn {
-	0% { -webkit-transform: rotateY(90deg) scale(.8); }
-	50% { -webkit-transform: rotateY(90deg) scale(.8); }
-	100% { -webkit-transform: rotateY(0deg) scale(1); }
-}
-
-.fade.out {
-	-webkit-animation-duration: 1s;
-	-webkit-animation-name: fadeOut;
-	-webkit-animation-timing-function: ease-in;
-}
-.fade.in {
-	-webkit-animation-duration: 1s;
-	-webkit-animation-name: fadeIn;
-	-webkit-animation-timing-function: ease-out;
-}
- at -webkit-keyframes fadeOut {
-	from { opacity: 1; }
-	to { opacity: 0; }
-}
-
- at -webkit-keyframes fadeIn {
-	from { opacity: 0; }
-	to { opacity: 1; }
-}
-
-/* dojox.mobile.Heading */
-.mblHeading {
-	position: relative;
-	height: 25px;
-	margin: 0px;
-	padding: 0px 0px 0px 4px;
-	background-color: #8C8A8C;
-	background: -webkit-gradient(linear, left top, left bottom, from(#9C9E9C), to(#848284));
-	border-top: 1px solid #CDD5DF;
-	border-bottom: 1px solid #2D3642;
-	font-family: Helvetica;
-	font-size: 14px;
-	color: white;
-	text-align: center;
-	line-height: 23px;
-	text-shadow: rgba(0,0,0,0.6) 0px -1px 0px;
-	overflow: hidden;
-	white-space: nowrap;
-	text-overflow: ellipsis;
-}
-
-/* Heading Arrow Button */
-.mblArrowButton {
-	position: relative;
-	float: left;
-	height: 25px;
-	margin-right: 6px;
-}
-.mblArrowButtonHead {
-	position: absolute;
-	top: 5px;
-	left: 9px;
-	width: 19px;
-	height: 16px;
-	border-width: 1px;
-	border-style: solid;
-	border-color: #3F3E3E;
-	-webkit-transform: scale(.8,1) rotate(45deg);
-	background: -webkit-gradient(linear, left top, left bottom, from(#E5E5E5), to(#7F7F7F), color-stop(0.5, #ADADAD), color-stop(0.5, #909090));
-}
-.mblArrowButtonBody {
-	position: absolute;
-	top: 0px;
-	left: 19px;
-	padding: 0px 10px 0px 3px;
-	height: 23px;
-	border-width: 1px 1px 1px 0px;
-	border-style: inset;
-	border-color: #3F3E3E;
-	font-family: Helvetica;
-	font-size: 13px;
-	color: white;
-	line-height: 23px;
-	cursor: pointer;
-	-webkit-border-radius: 5px;
-	background-color: #ADADAD;
-	background: -webkit-gradient(linear, left top, left bottom, from(#E5E5E5), to(#7F7F7F), color-stop(0.5, #ADADAD), color-stop(0.5, #909090));
-	-webkit-tap-highlight-color: transparent;
-}
-.mblArrowButtonNeck {
-	position: absolute;
-	top: 0px;
-	left: 19px;
-	width: 4px;
-	height: 23px;
-	border-width: 1px 0px 1px 0px;
-	border-style: inset;
-	border-color: #3F3E3E;
-	background: -webkit-gradient(linear, left top, left bottom, from(#E5E5E5), to(#7F7F7F), color-stop(0.5, #ADADAD), color-stop(0.5, #909090));
-}
-.mblArrowButtonSelected .mblArrowButtonHead {
-	background: -webkit-gradient(linear, left top, left bottom, from(#AD7500), to(#FFAA00), color-stop(0.06, #FFB200), color-stop(0.5, #FFC700));
-}
-.mblArrowButtonSelected .mblArrowButtonBody, .mblArrowButtonSelected .mblArrowButtonNeck {
-	background-color: #FFC700;
-	background: -webkit-gradient(linear, left top, left bottom, from(#AD7500), to(#FFAA00), color-stop(0.06, #FFB200), color-stop(0.5, #FFC700));
-}
-
-/* ToolBarButton */
-.mblToolbarButton {
-	float: left;
-	position: relative;
-	margin: 0px 3px;
-	padding: 0px 10px;
-	height: 23px;
-	border: 1px inset #3F3E3E;
-	font-family: Helvetica;
-	font-size: 13px;
-	font-weight: bold;
-	color: white;
-	line-height: 23px;
-	text-align: center;
-	cursor: pointer;
-	-webkit-border-radius: 5px;
-	-moz-border-radius: 5px;
-	-webkit-tap-highlight-color: transparent;
-}
-
-/* dojox.mobile.TabBar */
-/*TODO: not optimized for android yet*/
-.mblTabBar {
-	position: relative;
-	height: 48px;
-	width: 100%;
-	margin: 0px;
-	padding: 0px;
-	background-color: #000000;
-	background: -webkit-gradient(linear, left top, left bottom, from(#2D2D2D), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
-	border-top: 1px solid #000000;
-	color: white;
-	text-align: center;
-	overflow: hidden;
-	white-space: nowrap;
-}
-
-.mblTabBar .mblTabBarButton {
-	position: relative;
-	list-style-type: none;
-	float: left;
-}
-
-/* dojox.mobile.TabBarButton */
-.mblTabBarButton {
-}
-.mblTabBarButtonAnchor {
-	display: block;
-	text-decoration: none;
-}
-.mblTabBarButtonDiv {
-	position: relative;
-	height: 34px;
-	width: 29px;
-	left: 50%;
-}
-.mblTabButton .mblTabBarButtonDiv {
-	height: 40px;
-}
-.mblTabBarButtonDivInner {
-	left: -50%;
-}
-.mblTabBarButtonIcon {
-	position: absolute;
-	left: 0px;
-	top: 2px;
-}
-.mblTabBar .mblTabBarButton.mblTabButtonSelected {
-	background-color: #404040;
-	background: -webkit-gradient(linear, left top, left bottom, from(#484848), to(#242424), color-stop(0.5, #353535), color-stop(0.5, #242424));
-	-webkit-border-radius: 3px;
-	-moz-border-radius: 3px;
-}
-.mblTabBarButtonTextBox {
-	color: #979797;
-	font-family: "Helvetica Neue", Helvetica;
-	font-size: 11px;
-}
-.mblTabButtonSelected .mblTabBarButtonTextBox {
-	color: white;
-}
-
-/* dojox.mobile.RoundRect */
-.mblRoundRect {
-	margin: 7px 9px 16px;
-	padding: 8px;
-	border: 1px solid #ADAAAD;
-	-webkit-border-radius: 8px;
-	-moz-border-radius: 8px;
-	color: white;
-	background-color: black;
-}
-.mblRoundRect.mblShadow {
-	-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
-}
-
-/* dojox.mobile.EdgeToEdgeCategory */
-.mblEdgeToEdgeCategory {
-	position: relative;
-	height: 22px;
-	margin: 0px;
-	padding: 0px 10px;
-	border-bottom: 1px solid #393439;
-	background-color: #212021;
-	font-family: Helvetica;
-	font-size: 16px;
-	color: white;
-	line-height: 22px;
-	text-shadow: rgba(0,0,0,0.6) 0px -1px 0px;
-	overflow: hidden;
-	white-space: nowrap;
-	text-overflow: ellipsis;
-}
-
-/* dojox.mobile.RoundRectCategory */
-.mblRoundRectCategory {
-	color: white;
-	margin: 18px 0px 0px 20px;
-	font-family: Helvetica;
-	font-size: 16px;
-	overflow: hidden;
-	white-space: nowrap;
-	text-overflow: ellipsis;
-}
-
-/* dojox.mobile.RoundRectList */
-.mblRoundRectList {
-	margin: 7px 9px 16px;
-	padding: 0px;
-	border: 1px solid #ADAAAD;
-	-webkit-border-radius: 8px;
-	-moz-border-radius: 8px;
-	background-color: white;
-	position: relative; /* IE needs this */
-}
-
-/* dojox.mobile.EdgeToEdgeList */
-.mblEdgeToEdgeList {
-	padding: 0px;
-	background-color: black;
-	position: relative; /* IE needs this */
-	margin: 0px; /* IE needs this */
-}
-
-/* dojox.mobile.ListItem */
-.mblListItem {
-	list-style-type: none;
-	height: 64px;
-	border-bottom: solid 1px #313431;
-	line-height: 64px;
-	font-size: 21px;
-	position: relative;
-	color: white;
-	background-color: black;
-	padding-left: 7px;
-}
-.mblListItemIcon {
-	position: absolute;
-	top: 18px;
-}
-.mblListItem.mblVariableHeight {
-	line-height: normal;
-	height: auto;
-	padding: 11px 6px 10px 6px;
-}
-.mblItemSelected {
-	background-color: #FFC700;
-	background: -webkit-gradient(linear, left top, left bottom, from(#AD7500), to(#FFAA00), color-stop(0.06, #FFB200), color-stop(0.5, #FFC700));
-}
-.mblListItemTextBox {
-	padding-right: 28px;
-}
-.mblListItemTextBoxSelected {
-	background-color: #048BF4;
-}
-.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: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;
-}
-.mblEdgeToEdgeList .mblListItem:last-child {
-	border-bottom-color: #313431;
-}
-.mblListItem a.mblListItemAnchor {
-	background-position: 14px 17px;
-	display: block;
-	padding-left: 53px;
-	text-decoration: none;
-	-webkit-tap-highlight-color: transparent;
-}
-.mblListItem a.mblListItemAnchorNoIcon {
-	padding-left: 14px;
-}
-.mblItemSelected a.mblListItemAnchor {
-	color: black;
-}
-.mblListItem a.mblListItemAnchorHasRightButton {
-	padding-right: 50px;
-}
-
-.mblListItem .mblArrow {
-	position: absolute;
-	top: 26px;
-	right: 12px;
-	width: 6px;
-	height: 6px;
-	font-size: 1px;
-	-webkit-transform: rotate(45deg);
-	border-width: 3px 3px 0px 0px;
-	border-style: solid;
-	border-color: #808080;
-}
-.mblItemSelected .mblArrow {
-	border-color: white;
-}
-.mblVariableHeight div.mblArrow {
-	top: 50%;
-	margin-top: -4px;
-}
-
-.mblRightText {
-	position: absolute;
-	top: 20px;
-	right: 30px;
-	color: white;
-	line-height: normal;
-}
-.mblListItem .mblRightButtonContainer {
-	position: absolute;
-	top: 50%;
-	right: 12px;
-}
-.mblListItem .mblRightButton {
-	position: absolute;
-	top: -50%;
-}
-.mblListItemSubText {
-	font-size: 14px;
-	color: gray;
-}
-
-/* Switch */
-.mblSwitch {
-	position: relative;
-	width: 94px;
-	height: 27px;
-	overflow: hidden;
-}
-.mblItemSwitch {
-	position: absolute;
-	top: 18px;
-	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-border-radius: 2px;
-	-moz-border-radius: 2px;
-	-webkit-box-sizing: border-box;
-	-moz-box-sizing: border-box;
-	-webkit-tap-highlight-color: transparent;
-}
-.mblSwitchBgLeft {
-	left: 0px;
-	width: 94px;
-	color: white;
-	background-color: #00D300;
-	background: -webkit-gradient(linear, left top, left bottom, from(#00A200), to(#00D300), color-stop(0.2, #00BA00), color-stop(0.2, #00BA00));
-}
-.mblSwitchBgRight {
-	left: 53px;
-	width: 94px;
-	color: #7F7F7F;
-	background-color: #EEEEEE;
-	background: -webkit-gradient(linear, left top, left bottom, from(#BDBEBD), to(#F7F3F7));
-}
-.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;
-	line-height: 29px;
-	background-color: #CCCCCC;
-	background: -webkit-gradient(linear, left top, left bottom, from(#9C9A9C), to(#848284));
-	-webkit-border-radius: 2px;
-	-moz-border-radius: 2px;
-	-webkit-box-sizing: border-box;
-	-moz-box-sizing: border-box;
-}
-.mblSwitchText {
-	position: relative;
-	top: 0px;
-	width: 53px;
-	height: 27px;
-	padding: 0px;
-	text-align: center;
-}
-.mblSwitchTextLeft {
-	left: 0px;
-}
-.mblSwitchTextRight {
-	left: 40px;
-}
-
-/* Icon Container */
-.mblIconContainer {
-	padding: 0px;
-	margin: 20px 0px 0px 10px;
-	padding: 0px 0px 40px 0px;
-}
-.mblIconItem {
-	list-style-type: none;
-	float: left;
-}
-.mblIconItemTerminator {
-	list-style-type: none;
-	height: 20px;
-	clear: both;
-}
-.mblIconItemSub {
-	list-style-type: none;
-	margin-left: -10px;
-	background-color: white;
-	color: black;
-}
-
-.mblIconArea {
-	font-family: Helvetica;
-	font-size: 12px;
-	height: 78px;
-	width: 74px;
-	text-align: center;
-	margin-bottom: 10px;
-	color: white;
-}
-
-.mblIconArea DIV {
-	position: relative;
-	height: 65px;
-}
-
-.mblIconArea IMG {
-	position: absolute;
-	top: 0px;
-	left: 6px;
-}
-
-.mblContent {
-	clear: both;
-	padding-bottom: 20px;
-}
-
-table.mblClose {
-	clear: both;
-	cursor: pointer;
-}
-
-.mblVibrate{
-	position: relative;
-	-webkit-animation-duration: .5s;
-	-webkit-animation-timing-function: ease-in-out;
-	-webkit-animation-iteration-count: 20;
-	-webkit-animation-name: vibrate;
-	-webkit-transform: rotate(0deg);
-}
- at -webkit-keyframes vibrate{
-	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;
-	}
-}
-
-.mblCloseContent{
-	-webkit-animation-duration: .3s;
-	-webkit-animation-timing-function: ease-in-out;
-	-webkit-animation-name: shrink;
-	-webkit-transform: scale(0.01);
-}
-.mblCloseContent.mblShrink0{
-	-webkit-animation-name: shrink0;
-}
-.mblCloseContent.mblShrink1{
-	-webkit-animation-name: shrink1;
-}
-.mblCloseContent.mblShrink2{
-	-webkit-animation-name: shrink2;
-}
-.mblCloseContent.mblShrink3{
-	-webkit-animation-name: shrink3;
-}
- at -webkit-keyframes shrink{
-	from { -webkit-transform: scale(1); }
-	to { -webkit-transform: scale(0.01); }
-}
- at -webkit-keyframes shrink0{
-	from { -webkit-transform: scale(1); }
-	to { -webkit-transform: translate(-40%,-70%) scale(0.01); }
-}
- at -webkit-keyframes shrink1{
-	from { -webkit-transform: scale(1); }
-	to { -webkit-transform: translate(-14%,-70%) scale(0.01); }
-}
- at -webkit-keyframes shrink2{
-	from { -webkit-transform: scale(1); }
-	to { -webkit-transform: translate(14%,-70%) scale(0.01); }
-}
- at -webkit-keyframes shrink3{
-	from { -webkit-transform: scale(1); }
-	to { -webkit-transform: translate(40%,-70%) scale(0.01); }
-}
-
-/* Icon Content Heading */
-.mblIconContentHeading {
-	position: relative;
-	clear: both;
-	height: 25px;
-	padding-left: 40px;
-	margin-top: 0px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#E0E4E7), to(#B4BEC6), color-stop(0.5, #C4CCD2), color-stop(0.5, #BFC8CE));
-	border-top: 1px solid #F1F3F4;
-	border-bottom: 1px solid #717D85;
-	font-family: Helvetica;
-	font-size: 14px;
-	color: white;
-	line-height: 26px;
-	text-shadow: rgba(0,0,0,0.6) 0px -1px 0px;
-	overflow: hidden;
-	white-space: nowrap;
-	text-overflow: ellipsis;
-}
-
-/* dojox.mobile.Button */
-.mblButton {
-	padding: 0px 10px;
-	height: 29px;
-	border-width: 1px 1px 1px 1px;
-	border-style: outset;
-	color: white;
-	font-family: Helvetica;
-	font-size: 13px;
-	line-height: 29px;
-	-webkit-border-radius: 5px;
-	-moz-border-radius: 5px;
-	-webkit-tap-highlight-color: transparent;
-}
-.mblBlueButton {
-	border-color: #9CACC0;
-	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));
-	-webkit-tap-highlight-color: transparent;
-}
-.mblBlueButtonSelected {
-	background: -webkit-gradient(linear, left top, left bottom, from(#8EA4C1), to(#4A6C9B), color-stop(0.5, #5877A2), color-stop(0.5, #476999));
-}
-
-/* Tab Container */
-.mblTabContainer {
-}
-
-.mblTabButton {
-	position: relative;
-	float: left;
-	list-style-type: none;
-	width: 78px;
-	text-align: center;
-	height: 61px;
-	margin-right: 2px;
-	border-width: 0px 1px 0px 1px;
-	border-style: solid;
-	border-color: black #182018 black #393C39;
-	font-family: Helvetica;
-	font-size: 13px;
-	color: white;
-	background-color: #212421;
-	background: -webkit-gradient(linear, left top, left bottom, from(#181818), to(#100C10), color-stop(0.1, #313031));
-	-webkit-tap-highlight-color: transparent;
-}
-.mblTabButtonSelected.mblTabButton {
-	background-color: #8C8E8C;
-	background: -webkit-gradient(linear, left top, left bottom, from(#A59EA5), to(#848284));
-}
-.mblTabButtonHighlighted.mblTabButton {
-	background-color: #FFB600;
-	background: -webkit-gradient(linear, left top, left bottom, from(#FFCB00), to(#FF9A00));
-}
-.mblTabButtonImgDiv {
-	position: relative;
-	margin-left: 24px;
-	height: 40px;
-}
-.mblTabButton IMG {
-	position: absolute;
-	left: 0px;
-	margin-top: 8px;
-}
-
-.mblTabPanelHeader {
-	position: relative;
-	height: 64px;
-	margin: 0px;
-	padding: 0px 0px 0px 0px;
-	background-color: #000000;
-	border-top: 1px solid #CDD5DF;
-	border-bottom: 2px solid #949694;
-	font-family: Helvetica;
-	font-size: 20px;
-	color: white;
-	text-align: center;
-	overflow: hidden;
-	white-space: nowrap;
-	text-overflow: ellipsis;
-}
-
-.mblTabPanelPane {
-}
-
-.mblTabPane {
-}
-
-/* Progress Indicator */
-.mblProgContainer {
-	position: absolute;
-	width: 36px;
-	height: 36px;
-	top: 180px;
-	left: 50%;
-	margin: -18px 0px 0px -18px;
-}
-.mblProg {
-	position: absolute;
-	left: 0px;
-	top: 0px;
-	width: 11px;
-	font-size: 1px;
-	height: 4px;
-	overflow: hidden;
-	-webkit-transform-origin: 0 2px;
-	background-color: #C0C0C0;
-	-webkit-border-radius: 2px;
-	-moz-border-radius: 2px;
-}
-.mblProg0 {
-	-webkit-transform: translate(18px,10px) rotate(-90deg);
-}
-.mblProg1 {
-	-webkit-transform: translate(22px,11px) rotate(-60deg);
-}
-.mblProg2 {
-	-webkit-transform: translate(25px,14px) rotate(-30deg);
-}
-.mblProg3 {
-	-webkit-transform: translate(26px,18px) rotate(0deg);
-}
-.mblProg4 {
-	-webkit-transform: translate(25px,22px) rotate(30deg);
-}
-.mblProg5 {
-	-webkit-transform: translate(22px,25px) rotate(60deg);
-}
-.mblProg6 {
-	-webkit-transform: translate(18px,26px) rotate(90deg);
-}
-.mblProg7 {
-	-webkit-transform: translate(14px,25px) rotate(120deg);
-}
-.mblProg8 {
-	-webkit-transform: translate(11px,22px) rotate(150deg);
-}
-.mblProg9 {
-	-webkit-transform: translate(10px,18px) rotate(180deg);
-}
-.mblProg10 {
-	-webkit-transform: translate(11px,14px) rotate(210deg);
-}
-.mblProg11 {
-	-webkit-transform: translate(14px,11px) rotate(240deg);
-}
-
-/* Button Colors */
-.mblColorBlue {
-	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));
-}
-
-/* Default Button Colors */
-.mblColorDefault { /* Gray */
-	background-color: #ADADAD;
-	background: -webkit-gradient(linear, left top, left bottom, from(#E5E5E5), to(#7F7F7F), color-stop(0.5, #ADADAD), color-stop(0.5, #909090));
-}
-
-.mblColorDefaultSel { /* Orange */
-	background-color: #FFC700;
-	background: -webkit-gradient(linear, left top, left bottom, from(#AD7500), to(#FFAA00), color-stop(0.06, #FFB200), color-stop(0.5, #FFC700));
-}
+ at import url("base.css");
+
+/* common styles */
+ at import url("../common/domButtons.css");
+ at import url("../common/FixedSplitter.css");
+ at import url("../common/SpinWheel.css");
+ at import url("../common/transitions.css");
+
+/* widget styles */
+ at import url("Button.css");
+ at import url("Carousel.css");
+ at import url("CheckBox.css");
+ at import url("ComboBox.css");
+ at import url("IconContainer.css");
+ at import url("Opener.css");
+ at import url("PageIndicator.css");
+ at import url("RadioButton.css");
+ at import url("Slider.css");
+ at import url("TabBar.css");
+ at import url("TextArea.css");
+ at import url("TextBox.css");
+ at import url("ToggleButton.css");
diff --git a/dojox/mobile/themes/android/base-compat.css b/dojox/mobile/themes/android/base-compat.css
new file mode 100644
index 0000000..d12cf2b
--- /dev/null
+++ b/dojox/mobile/themes/android/base-compat.css
@@ -0,0 +1,7 @@
+ at import url("Heading-compat.css");
+ at import url("RoundRect-compat.css");
+ at import url("RoundRectList-compat.css");
+ at import url("EdgeToEdgeCategory-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/android/base.css b/dojox/mobile/themes/android/base.css
new file mode 100644
index 0000000..2409467
--- /dev/null
+++ b/dojox/mobile/themes/android/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/android/common.css b/dojox/mobile/themes/android/common.css
new file mode 100644
index 0000000..7cf6b02
--- /dev/null
+++ b/dojox/mobile/themes/android/common.css
@@ -0,0 +1,27 @@
+html.mobile, .mobile body {
+  width: 100%;
+  margin: 0px;
+  padding: 0px;
+}
+.mobile body {
+  overflow-x: hidden;
+  -webkit-text-size-adjust: none;
+  background-color: black;
+  font-family: Helvetica;
+  font-size: 17px;
+  color: white;
+}
+/* Button Colors */
+.mblColorBlue {
+  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));
+}
+/* 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));
+}
+.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));
+}
diff --git a/dojox/mobile/themes/android/common.less b/dojox/mobile/themes/android/common.less
new file mode 100644
index 0000000..4e57a5c
--- /dev/null
+++ b/dojox/mobile/themes/android/common.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/common.less";
diff --git a/dojox/mobile/themes/android/compat/blue-button-sel-bg.png b/dojox/mobile/themes/android/compat/blue-button-sel-bg.png
deleted file mode 100755
index 6968458..0000000
Binary files a/dojox/mobile/themes/android/compat/blue-button-sel-bg.png and /dev/null differ
diff --git a/dojox/mobile/themes/android/compat/button-bg.png b/dojox/mobile/themes/android/compat/button-bg.png
new file mode 100644
index 0000000..0d378fa
Binary files /dev/null and b/dojox/mobile/themes/android/compat/button-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
new file mode 100644
index 0000000..75ff0f8
Binary files /dev/null and b/dojox/mobile/themes/android/compat/button-sel-bg.png differ
diff --git a/dojox/mobile/themes/android/compat/red-button-bg.png b/dojox/mobile/themes/android/compat/red-button-bg.png
new file mode 100644
index 0000000..799870f
Binary files /dev/null and b/dojox/mobile/themes/android/compat/red-button-bg.png differ
diff --git a/dojox/mobile/themes/android/compat/slider-h-bar-bg.png b/dojox/mobile/themes/android/compat/slider-h-bar-bg.png
new file mode 100644
index 0000000..970c7ff
Binary files /dev/null and b/dojox/mobile/themes/android/compat/slider-h-bar-bg.png differ
diff --git a/dojox/mobile/themes/android/compat/slider-h-bg.png b/dojox/mobile/themes/android/compat/slider-h-bg.png
new file mode 100644
index 0000000..0a08c57
Binary files /dev/null and b/dojox/mobile/themes/android/compat/slider-h-bg.png differ
diff --git a/dojox/mobile/themes/android/compat/slider-handle-bg.png b/dojox/mobile/themes/android/compat/slider-handle-bg.png
new file mode 100644
index 0000000..1988f04
Binary files /dev/null and b/dojox/mobile/themes/android/compat/slider-handle-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
new file mode 100644
index 0000000..3f01809
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-arc-l.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-arc-r.gif b/dojox/mobile/themes/android/compat/switch-arc-r.gif
new file mode 100644
index 0000000..3bb5901
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-arc-r.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-arc1-k.gif b/dojox/mobile/themes/android/compat/switch-arc1-k.gif
new file mode 100644
index 0000000..3dec6bd
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-arc1-k.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-arc2-k.gif b/dojox/mobile/themes/android/compat/switch-arc2-k.gif
new file mode 100644
index 0000000..638e76a
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-arc2-k.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-blue-bg.png b/dojox/mobile/themes/android/compat/switch-blue-bg.png
deleted file mode 100755
index 78c9647..0000000
Binary files a/dojox/mobile/themes/android/compat/switch-blue-bg.png and /dev/null differ
diff --git a/dojox/mobile/themes/android/compat/switch-default-k.gif b/dojox/mobile/themes/android/compat/switch-default-k.gif
new file mode 100644
index 0000000..61aca0b
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-default-k.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-default-l.gif b/dojox/mobile/themes/android/compat/switch-default-l.gif
new file mode 100644
index 0000000..9903c39
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-default-l.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-default-r.gif b/dojox/mobile/themes/android/compat/switch-default-r.gif
new file mode 100644
index 0000000..5dbc4bc
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-default-r.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-gray-bg.png b/dojox/mobile/themes/android/compat/switch-gray-bg.png
deleted file mode 100755
index 04e884e..0000000
Binary files a/dojox/mobile/themes/android/compat/switch-gray-bg.png and /dev/null differ
diff --git a/dojox/mobile/themes/android/compat/switch-green-bg.png b/dojox/mobile/themes/android/compat/switch-green-bg.png
deleted file mode 100644
index 182310a..0000000
Binary files a/dojox/mobile/themes/android/compat/switch-green-bg.png and /dev/null differ
diff --git a/dojox/mobile/themes/android/compat/switch-knob-bg.png b/dojox/mobile/themes/android/compat/switch-knob-bg.png
deleted file mode 100755
index e2d75fe..0000000
Binary files a/dojox/mobile/themes/android/compat/switch-knob-bg.png 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
new file mode 100644
index 0000000..0a50568
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-round-l.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-round-r.gif b/dojox/mobile/themes/android/compat/switch-round-r.gif
new file mode 100644
index 0000000..1cd3c95
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-round-r.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-round1-k.gif b/dojox/mobile/themes/android/compat/switch-round1-k.gif
new file mode 100644
index 0000000..2b4a9da
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-round1-k.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-round2-k.gif b/dojox/mobile/themes/android/compat/switch-round2-k.gif
new file mode 100644
index 0000000..08eb031
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-round2-k.gif differ
diff --git a/dojox/mobile/themes/android/compat/togglebutton-chk-bg.png b/dojox/mobile/themes/android/compat/togglebutton-chk-bg.png
new file mode 100644
index 0000000..4bfad06
Binary files /dev/null and b/dojox/mobile/themes/android/compat/togglebutton-chk-bg.png differ
diff --git a/dojox/mobile/themes/android/variables.less b/dojox/mobile/themes/android/variables.less
new file mode 100644
index 0000000..c7ffdfb
--- /dev/null
+++ b/dojox/mobile/themes/android/variables.less
@@ -0,0 +1,737 @@
+// common.less
+.mobile-body-styles () {
+	background-color: black;
+	font-family: Helvetica;
+	font-size: 17px;
+	color: white;
+}
+
+.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));
+}
+.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));
+}
+.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));
+}
+
+// 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;
+	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));
+}
+.mblArrowButtonHeadChrome-styles () {
+	border: 1px outset #555555;
+}
+.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));
+}
+.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));
+}
+.mblArrowButtonHeadSelected-styles () {
+}
+.mblArrowButtonBodySelected-styles () {
+}
+
+// ToolBarButton.less
+.mblToolBarButton-styles () {
+	margin: 0px 6px;
+	height: 22px;
+	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;
+}
+.mblToolBarButtonIcon-styles () {
+	top: -2px;
+	padding: 0px;
+}
+
+// RoundRect.less
+.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;
+}
+
+// RoundRectCategory.less
+.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 () {
+	border-bottom-color: #313431;
+}
+
+// ListItem.less
+.mblListItem-styles () {
+	padding: 0px 0px 0px 7px;
+	height: 64px;
+	border-bottom: solid 1px #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;
+}
+.mblItemSelected-mblListItemSubText-styles () {
+}
+.mblListItemTextBoxSelected-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 () {
+}
+.mblListItemSubText-styles () {
+	font-size: 14px;
+	color: gray;
+}
+
+// Switch.less
+.mblItemSwitch-styles () {
+	top: 18px;
+}
+.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));
+}
+.mblSwitchKnob-styles () {
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#9C9A9C), to(#848284));
+	-webkit-border-radius: 2px;
+}
+
+// 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));
+	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;
+}
+.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));
+	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));
+}
+.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
+.dijitPopup-styles () {
+	-webkit-box-shadow: 0px 0px 50px black;
+	-webkit-border-radius: 0px;
+}
+.mblComboBoxMenu-styles () {
+	border: 1px solid black;
+	-webkit-border-radius: 0px;
+	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;
+}
+
+// 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;
+	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;
+}
+
+// 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));
+}
+.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
+.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;
+}
+.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));
+}
+
+// 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: white;
+	text-align: center;
+}
+.mblTabBar-TabBarButton-styles () {
+}
+.mblTabBar-TabBarButton-Selected-styles () {
+	-webkit-border-radius: 3px;
+	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;
+	color: white;
+	text-align: center;
+}
+.mblTabButton-TabBarButtonAnchor-styles () {
+}
+.mblTabBarTop-TabButton-TabBarButtonDiv-styles () {
+	height: 38px;
+}
+.mblTabBarHead-TabButton-TabBarButtonDiv-styles () {
+	margin-top: -2px;
+}
+.mblTabButton-FirstTabButtom-styles () {
+}
+.mblTabButton-LastTabButton-styles () {
+}
+.mblTabButton-img-styles () {
+	position: absolute;
+	left: 0px;
+	margin-top: 8px;
+}
+.mblTabBarButtonTextBoxSelected-styles () {
+	color: white;
+}
+.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;
+}
+.mblTabPanelHeader-TabButton-styles () {
+	margin-top: 3px;
+}
+.mblTabPanelHeader-TabButtonSelected-styles () {
+}	
+.mblTabPanelHeader-TabButtonDomButton-styles () {
+	width: 43px;
+}
+.mblTabPanelHeader-TabButtonDomButtonClass-styles () {
+	left: 8px;
+}
+.mblTabPanelHeader-DomButton-styles () {
+}
+.mblTabPanelHeader-inHeading-styles () {
+	height: 25px;
+}
+.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));
+}
+.mblTabPanelHeader-TabButton-FirstTabButtom-inHeading-styles () {
+	border-left-width: 1px;
+}
+.mblTabPanelHeader-TabButton-LastTabButtom-inHeading-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));
+}
+
+// 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;
+}
+
+// TextBox.less
+.mblTextBox-styles () {
+	height: 22px;
+	border: #9CACC0 1px inset;
+	-webkit-border-radius: 3px;
+	font-family: Helvetica;
+	font-size: 13px;
+}
+
+// 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;
+	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
+.mblOverlay-styles () {
+	background-color: #333333;
+	background-image: none;
+}
+
+// Tooltip.less
+.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;
+}
+.mblTooltipBubble-styles () {
+	background-color: #FFC700;
+	background-image: none;
+	color: black;
+}
+.mblTooltipInnerArrow-Bubble-Above-styles () {
+	border-bottom-color: #FFC700;
+}
+.mblTooltipInnerArrow-Bubble-Below-styles () {
+	border-top-color: #FFC700;
+}
+.mblTooltipInnerArrow-Bubble-After-styles () {
+	border-left-color: #FFC700;
+}
+.mblTooltipInnerArrow-Bubble-Before-styles () {
+	border-right-color: #FFC700;
+}
+.mblTooltipArrow-styles () {
+	border: 11px solid transparent;
+}
+.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-ToolbarButton-styles () {
+}
diff --git a/dojox/mobile/themes/blackberry/Button-compat.css b/dojox/mobile/themes/blackberry/Button-compat.css
new file mode 100644
index 0000000..359e510
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Button-compat.css
@@ -0,0 +1,33 @@
+/* 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;
+}
+.mblButtonSelected {
+	background-color: #0852ae;
+	background-image: url(compat/button-sel-bg.png);
+}
+.mblButtonDisabled {
+	background-image: none;
+}
+.mblBlueButton {
+	background-color: #2261dd;
+	background-image: url(compat/blue-button-bg.png);
+}
+.mblBlueButtonSelected {
+	background-color: #0852ae;
+	background-image: url(compat/button-sel-bg.png);
+}
+.mblRedButton {
+	background-color: #ee4115;
+	background-image: url(compat/red-button-bg.png);
+}
+.mblRedButtonSelected {
+	background-color: #0852ae;
+	background-image: url(compat/button-sel-bg.png);
+}
diff --git a/dojox/mobile/themes/blackberry/Button.css b/dojox/mobile/themes/blackberry/Button.css
new file mode 100644
index 0000000..fa8dc66
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Button.css
@@ -0,0 +1,45 @@
+/* dojox.mobile.Button */
+.mblButton {
+  cursor: pointer;
+  outline: none;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  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));
+  color: black;
+  font-family: Helvetica;
+  font-size: 16px;
+  line-height: 29px;
+}
+.mblButton.mblBlueButton {
+  -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;
+}
+.mblButton.mblBlueButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  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;
+}
+.mblButton.mblRedButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  color: white;
+}
+.mblButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  color: white;
+}
+.mblButtonDisabled, .mblButton:disabled {
+  cursor: default;
+  border-color: grey;
+  color: grey;
+  background-image: none;
+}
diff --git a/dojox/mobile/themes/blackberry/Button.less b/dojox/mobile/themes/blackberry/Button.less
new file mode 100644
index 0000000..ab3a96c
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Button.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..a415950
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Carousel.css
@@ -0,0 +1,60 @@
+/* dojox.mobile.Carousel */
+.mblCarousel {
+  overflow: hidden;
+}
+.mblCarouselBox {
+  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;
+}
+.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;
+}
diff --git a/dojox/mobile/themes/blackberry/Carousel.less b/dojox/mobile/themes/blackberry/Carousel.less
new file mode 100644
index 0000000..d717397
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Carousel.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/Carousel.less";
diff --git a/dojox/mobile/themes/blackberry/CheckBox-compat.css b/dojox/mobile/themes/blackberry/CheckBox-compat.css
new file mode 100644
index 0000000..f926ffa
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/CheckBox-compat.css
@@ -0,0 +1,34 @@
+/* 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);
+}
+.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);
+}
diff --git a/dojox/mobile/themes/blackberry/CheckBox.css b/dojox/mobile/themes/blackberry/CheckBox.css
new file mode 100644
index 0000000..89f618c
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/CheckBox.css
@@ -0,0 +1,44 @@
+/* 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;
+  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 {
+  border-color: #9CACC0;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+}
+.mblCheckBoxChecked, .mblCheckBox:checked {
+  border-color: #9CACC0;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
+}
+.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);
+  -webkit-transform-origin: 50% 50%;
+}
+.mblCheckBoxChecked.mblCheckBoxSelected, .mblCheckBox:checked.mblCheckBoxSelected {
+  border-color: #9CACC0;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+}
+.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
new file mode 100644
index 0000000..09f93b2
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/CheckBox.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..b0504e4
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ComboBox-compat.css
@@ -0,0 +1,17 @@
+/* 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;
+}
+.mblComboBoxMenu {
+	-moz-border-radius: 12px;
+	-o-border-radius: 12px;
+	-ms-border-radius: 12px;
+	border-radius: 12px;
+}
diff --git a/dojox/mobile/themes/blackberry/ComboBox.css b/dojox/mobile/themes/blackberry/ComboBox.css
new file mode 100644
index 0000000..45dd699
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ComboBox.css
@@ -0,0 +1,44 @@
+/* dojox.mobile.ComboBox */
+.dijitPopup {
+  margin: 0;
+  padding: 0;
+  position: absolute;
+  border: 0;
+  background-color: transparent;
+  -webkit-box-shadow: none;
+  -webkit-border-radius: 12px;
+}
+.mblReset {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  line-height: normal;
+  font: inherit;
+  color: inherit;
+}
+.mblComboBoxMenu {
+  overflow-y: hidden !important;
+  position: relative;
+  overflow: hidden;
+  border: 1px solid black;
+  -webkit-border-radius: 12px;
+  background-color: black;
+}
+.mblComboBoxMenuItem {
+  white-space: nowrap;
+  padding: .1em .2em;
+  border-width: 1px 0 1px 0;
+  border-style: solid;
+  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));
+}
+.mblComboBoxMenuPreviousButton, .mblComboBoxMenuNextButton {
+  font-style: italic;
+  overflow: hidden;
+}
diff --git a/dojox/mobile/themes/blackberry/ComboBox.less b/dojox/mobile/themes/blackberry/ComboBox.less
new file mode 100644
index 0000000..ab9458c
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ComboBox.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/ComboBox.less";
diff --git a/dojox/mobile/themes/blackberry/EdgeToEdgeCategory.css b/dojox/mobile/themes/blackberry/EdgeToEdgeCategory.css
new file mode 100644
index 0000000..5951a20
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/EdgeToEdgeCategory.css
@@ -0,0 +1,18 @@
+/* dojox.mobile.EdgeToEdgeCategory */
+.mblEdgeToEdgeCategory {
+  position: relative;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  margin: 0px;
+  padding: 0px 10px;
+  height: 29px;
+  border-top: 1px solid #313439;
+  border-bottom: 1px solid #ADAAAD;
+  background-color: white;
+  font-family: Helvetica;
+  font-size: 16px;
+  font-weight: bold;
+  color: #7B7D84;
+  line-height: 29px;
+}
diff --git a/dojox/mobile/themes/blackberry/EdgeToEdgeCategory.less b/dojox/mobile/themes/blackberry/EdgeToEdgeCategory.less
new file mode 100644
index 0000000..3bb63da
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/EdgeToEdgeCategory.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..baac042
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/EdgeToEdgeList.css
@@ -0,0 +1,12 @@
+/* dojox.mobile.EdgeToEdgeList */
+.mblEdgeToEdgeList {
+  position: relative;
+  /* IE needs this */
+
+  margin: 0px;
+  padding: 0px;
+  background-color: white;
+}
+.mblEdgeToEdgeList .mblListItem:last-child {
+  border-bottom-width: 0px;
+}
diff --git a/dojox/mobile/themes/blackberry/EdgeToEdgeList.less b/dojox/mobile/themes/blackberry/EdgeToEdgeList.less
new file mode 100644
index 0000000..227627c
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/EdgeToEdgeList.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/EdgeToEdgeList.less";
diff --git a/dojox/mobile/themes/blackberry/Heading-compat.css b/dojox/mobile/themes/blackberry/Heading-compat.css
new file mode 100644
index 0000000..8c7dd88
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Heading-compat.css
@@ -0,0 +1,25 @@
+/* mbl.widget.Heading */
+.mblHeading {
+	background-image: url(compat/heading-bg.png);
+}
+.mblHeadingSpanTitle {
+	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);
+}
diff --git a/dojox/mobile/themes/blackberry/Heading.css b/dojox/mobile/themes/blackberry/Heading.css
new file mode 100644
index 0000000..d5267eb
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Heading.css
@@ -0,0 +1,83 @@
+/* dojox.mobile.Heading */
+.mblHeading {
+  position: relative;
+  margin: 0px;
+  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;
+  font-family: Helvetica;
+  font-size: 18px;
+  font-weight: normal;
+  text-align: center;
+  line-height: 40px;
+}
+.mblHeading * {
+  z-index: 2;
+}
+.mblHeadingDivTitle {
+  position: absolute;
+  width: 100%;
+  display: none;
+  left: 0px;
+  z-index: 1;
+}
+.mblHeadingCenterTitle .mblHeadingDivTitle {
+  display: block;
+}
+.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
new file mode 100644
index 0000000..cfc8580
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Heading.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..adf6d49
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/IconContainer-compat.css
@@ -0,0 +1,11 @@
+ at import url("../common/domButtons/DomButtonColorButtons-compat.css");
+
+/* dojox.mobile.IconItem */
+.mblIconArea div {
+	*font-size: 60px; /* IE 7 quirks */
+}
+
+/* Icon Content Heading */
+.mblIconContentHeading {
+	background-image: url(compat/icon-content-heading-bg.png);
+}
diff --git a/dojox/mobile/themes/blackberry/IconContainer.css b/dojox/mobile/themes/blackberry/IconContainer.css
new file mode 100644
index 0000000..73fa041
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/IconContainer.css
@@ -0,0 +1,97 @@
+ at import url("../common/domButtons/DomButtonColorButtons.css");
+
+ at import url("../common/IconContainer_keyframes.css");
+/* dojox.mobile.IconContainer */
+.mblIconContainer {
+  margin: 0px;
+  padding: 0px;
+}
+/* dojox.mobile.IconItem */
+.mblIconItem {
+  list-style-type: none;
+  float: left;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblIconItemTerminator {
+  list-style-type: none;
+  clear: both;
+  height: 0px;
+}
+.mblIconItemSub {
+  list-style-type: none;
+  background-color: white;
+  color: black;
+}
+.mblIconArea {
+  margin-bottom: 5px;
+  height: 78px;
+  width: 88px;
+  text-align: center;
+  font-family: Helvetica;
+  font-size: 12px;
+}
+.mblIconArea div {
+  position: relative;
+  height: 65px;
+  line-height: 65px;
+  text-align: center;
+}
+.mblIconArea img {
+  vertical-align: middle;
+}
+.mblIconItemSpriteIcon {
+  position: absolute;
+}
+.mblContent {
+  clear: both;
+  padding-bottom: 20px;
+}
+table.mblClose {
+  clear: both;
+  cursor: pointer;
+}
+.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);
+}
+.mblCloseContent {
+  -webkit-animation-duration: .3s;
+  -webkit-animation-timing-function: ease-in-out;
+  -webkit-animation-name: mblShrink;
+  -webkit-transform: scale(0.01);
+}
+.mblCloseContent.mblShrink0 {
+  -webkit-animation-name: mblShrink0;
+}
+.mblCloseContent.mblShrink1 {
+  -webkit-animation-name: mblShrink1;
+}
+.mblCloseContent.mblShrink2 {
+  -webkit-animation-name: mblShrink2;
+}
+.mblCloseContent.mblShrink3 {
+  -webkit-animation-name: mblShrink3;
+}
+/* Icon Content Heading */
+.mblIconContentHeading {
+  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;
+  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;
+}
diff --git a/dojox/mobile/themes/blackberry/IconContainer.less b/dojox/mobile/themes/blackberry/IconContainer.less
new file mode 100644
index 0000000..963eae6
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/IconContainer.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonColorButtons.css");
+ at import url("../common/IconContainer_keyframes.css");
+
+ at import "variables.less";
+ at import "../common/IconContainer.less";
diff --git a/dojox/mobile/themes/blackberry/ListItem-compat.css b/dojox/mobile/themes/blackberry/ListItem-compat.css
new file mode 100644
index 0000000..a44214e
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ListItem-compat.css
@@ -0,0 +1,26 @@
+ at 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);
+}
+*html .mblListItemTextBox { /* IE6 hack */
+	height: 100%;
+}
+*html li.mblListItem.mblVariableHeight .mblListItemTextBox { /* IE6 hack */
+	height: auto;
+}
diff --git a/dojox/mobile/themes/blackberry/ListItem.css b/dojox/mobile/themes/blackberry/ListItem.css
new file mode 100644
index 0000000..b8f9f9d
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ListItem.css
@@ -0,0 +1,86 @@
+ at import url("../common/domButtons/DomButtonGrayArrow.css");
+
+ at import url("../common/domButtons/DomButtonDarkBlueCheck.css");
+/* dojox.mobile.ListItem */
+.mblListItem {
+  position: relative;
+  list-style-type: none;
+  vertical-align: bottom;
+  /* To avoid IE6 LI bug */
+
+  padding: 6px;
+  height: 43px;
+  border-bottom: solid 1px #DEDFDE;
+  font-size: 18px;
+  color: black;
+  line-height: 43px;
+}
+.mblListItem.mblVariableHeight {
+  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;
+}
+.mblListItem .mblListItemAnchor * {
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0.2);
+}
+.mblItemSelected {
+  background-color: #0869C6;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+}
+.mblItemSelected .mblListItemSubText {
+  color: white;
+}
+.mblItemSelected .mblListItemAnchor {
+  color: white;
+}
+.mblItemSelected .mblDomButton div {
+  border-color: white;
+}
+.mblListItemTextBoxSelected {
+  background-color: #0869C6;
+}
+.mblListItemIcon {
+  float: left;
+  line-height: normal;
+  margin-top: 7px;
+  margin-right: 11px;
+}
+.mblListItemSpriteIcon {
+  position: absolute;
+  margin-top: 7px;
+  margin-left: 8px;
+}
+.mblListItemRightIcon, .mblListItemRightIcon2 {
+  position: relative;
+  float: right;
+  line-height: normal;
+  margin-top: 7px;
+  margin-bottom: -7px;
+}
+.mblListItemRightText {
+  position: relative;
+  float: right;
+  line-height: normal;
+  color: black;
+  margin: 11px 4px 0 0;
+}
+.mblListItemTextBox {
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+.mblVariableHeight .mblListItemTextBox {
+  white-space: normal;
+}
+.mblListItemSubText {
+  font-size: 14px;
+  color: #7B7D48;
+}
diff --git a/dojox/mobile/themes/blackberry/ListItem.less b/dojox/mobile/themes/blackberry/ListItem.less
new file mode 100644
index 0000000..f9f9d21
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ListItem.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonGrayArrow.css");
+ at import url("../common/domButtons/DomButtonDarkBlueCheck.css");
+
+ at import "variables.less";
+ at import "../common/ListItem.less";
diff --git a/dojox/mobile/themes/blackberry/Opener-compat.css b/dojox/mobile/themes/blackberry/Opener-compat.css
new file mode 100644
index 0000000..68cb1a8
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/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/blackberry/Opener.css b/dojox/mobile/themes/blackberry/Opener.css
new file mode 100644
index 0000000..141c72e
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Opener.css
@@ -0,0 +1,3 @@
+/* dojox.mobile.Opener */
+ at import url("Overlay.css");
+ at import url("Tooltip.css");
diff --git a/dojox/mobile/themes/blackberry/Overlay-compat.css b/dojox/mobile/themes/blackberry/Overlay-compat.css
new file mode 100644
index 0000000..3bc72a3
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Overlay-compat.css
@@ -0,0 +1,13 @@
+/* dojox.mobile.Overlay */
+.mblOverlay {
+	_position: absolute;
+	text-align: center;
+}
+.dj_gecko .mblOverlay {
+	text-align: -moz-center;
+}
+.dj_ie9 .mblOverlay > *,
+.dj_ie8 .mblOverlay > *
+{
+	margin: 0 auto;
+}
diff --git a/dojox/mobile/themes/blackberry/Overlay.css b/dojox/mobile/themes/blackberry/Overlay.css
new file mode 100644
index 0000000..0073339
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Overlay.css
@@ -0,0 +1,18 @@
+ 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: #000000;
+  background-image: none;
+}
+.mblOverlayHidden *, .mblOverlayHidden {
+  visibility: hidden !important;
+}
diff --git a/dojox/mobile/themes/blackberry/Overlay.less b/dojox/mobile/themes/blackberry/Overlay.less
new file mode 100644
index 0000000..e49ea9e
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/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/blackberry/PageIndicator.css b/dojox/mobile/themes/blackberry/PageIndicator.css
new file mode 100644
index 0000000..a175ad6
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/PageIndicator.css
@@ -0,0 +1,24 @@
+/* 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;
+  -webkit-border-radius: 3px;
+  -moz-border-radius: 3px;
+}
+.mblPageIndicatorDotSelected {
+  background-color: white;
+}
diff --git a/dojox/mobile/themes/blackberry/PageIndicator.less b/dojox/mobile/themes/blackberry/PageIndicator.less
new file mode 100644
index 0000000..9bb6c49
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/PageIndicator.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/PageIndicator.less";
diff --git a/dojox/mobile/themes/blackberry/ProgressIndicator-compat.css b/dojox/mobile/themes/blackberry/ProgressIndicator-compat.css
new file mode 100644
index 0000000..4ee0810
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ProgressIndicator-compat.css
@@ -0,0 +1,46 @@
+/* Progress Indicator */
+.mblProg {
+	position: absolute;
+	top: 0px;
+	width: 4px;
+	font-size: 1px;
+	height: 36px;
+	overflow: hidden;
+	background-color: #C0C0C0;
+}
+.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;
+}
diff --git a/dojox/mobile/themes/blackberry/ProgressIndicator.css b/dojox/mobile/themes/blackberry/ProgressIndicator.css
new file mode 100644
index 0000000..2340637
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ProgressIndicator.css
@@ -0,0 +1,58 @@
+/* Progress Indicator */
+.mblProgContainer {
+  position: absolute;
+  width: 40px;
+  height: 40px;
+  top: 180px;
+  left: 50%;
+  margin: -18px 0px 0px -18px;
+}
+.mblProg {
+  position: absolute;
+  left: 2px;
+  top: 0px;
+  width: 11px;
+  font-size: 1px;
+  height: 4px;
+  overflow: hidden;
+  -webkit-transform-origin: 0 2px;
+  background-color: #C0C0C0;
+  -webkit-border-radius: 2px;
+  -moz-border-radius: 2px;
+}
+.mblProg0 {
+  -webkit-transform: translate(18px, 10px) rotate(-90.1deg);
+}
+.mblProg1 {
+  -webkit-transform: translate(22px, 11px) rotate(-60deg);
+}
+.mblProg2 {
+  -webkit-transform: translate(25px, 14px) rotate(-30deg);
+}
+.mblProg3 {
+  -webkit-transform: translate(26px, 18px) rotate(0deg);
+}
+.mblProg4 {
+  -webkit-transform: translate(25px, 22px) rotate(30deg);
+}
+.mblProg5 {
+  -webkit-transform: translate(22px, 25px) rotate(60deg);
+}
+.mblProg6 {
+  -webkit-transform: translate(18px, 26px) rotate(90.1deg);
+}
+.mblProg7 {
+  -webkit-transform: translate(14px, 25px) rotate(120deg);
+}
+.mblProg8 {
+  -webkit-transform: translate(11px, 22px) rotate(150deg);
+}
+.mblProg9 {
+  -webkit-transform: translate(10px, 18px) rotate(180deg);
+}
+.mblProg10 {
+  -webkit-transform: translate(11px, 14px) rotate(210deg);
+}
+.mblProg11 {
+  -webkit-transform: translate(14px, 11px) rotate(240deg);
+}
diff --git a/dojox/mobile/themes/blackberry/ProgressIndicator.less b/dojox/mobile/themes/blackberry/ProgressIndicator.less
new file mode 100644
index 0000000..2ab2a2d
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ProgressIndicator.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..6f85871
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/RadioButton-compat.css
@@ -0,0 +1,33 @@
+/* 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);
+}
+.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);
+}
diff --git a/dojox/mobile/themes/blackberry/RadioButton.css b/dojox/mobile/themes/blackberry/RadioButton.css
new file mode 100644
index 0000000..f2a88c2
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/RadioButton.css
@@ -0,0 +1,41 @@
+/* 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;
+  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, .mblRadioButton:checked {
+  border-color: #9CACC0;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
+}
+.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);
+  -webkit-transform-origin: 50% 50%;
+}
+.mblRadioButtonChecked.mblRadioButtonSelected, .mblRadioButton:checked.mblRadioButtonSelected {
+  border-color: #9CACC0;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+}
+.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
new file mode 100644
index 0000000..0793ca6
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/RadioButton.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..0643874
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/RoundRect-compat.css
@@ -0,0 +1,64 @@
+/* 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;
+}
diff --git a/dojox/mobile/themes/blackberry/RoundRect.css b/dojox/mobile/themes/blackberry/RoundRect.css
new file mode 100644
index 0000000..a1f9991
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/RoundRect.css
@@ -0,0 +1,13 @@
+/* dojox.mobile.RoundRect */
+.mblRoundRect {
+  margin: 2px 3px 4px;
+  padding: 8px;
+  border: 1px solid #C6C7C6;
+  -webkit-border-radius: 6px;
+  -moz-border-radius: 6px;
+  color: black;
+  background-color: white;
+}
+.mblRoundRect.mblShadow {
+  -webkit-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
new file mode 100644
index 0000000..efec816
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/RoundRect.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/RoundRect.less";
diff --git a/dojox/mobile/themes/blackberry/RoundRectCategory.css b/dojox/mobile/themes/blackberry/RoundRectCategory.css
new file mode 100644
index 0000000..bc46c98
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/RoundRectCategory.css
@@ -0,0 +1,20 @@
+/* dojox.mobile.RoundRectCategory */
+.mblRoundRectCategory {
+  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;
+}
diff --git a/dojox/mobile/themes/blackberry/RoundRectCategory.less b/dojox/mobile/themes/blackberry/RoundRectCategory.less
new file mode 100644
index 0000000..e9148cc
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/RoundRectCategory.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/RoundRectCategory.less";
diff --git a/dojox/mobile/themes/blackberry/RoundRectList-compat.css b/dojox/mobile/themes/blackberry/RoundRectList-compat.css
new file mode 100644
index 0000000..0643874
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/RoundRectList-compat.css
@@ -0,0 +1,64 @@
+/* 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;
+}
diff --git a/dojox/mobile/themes/blackberry/RoundRectList.css b/dojox/mobile/themes/blackberry/RoundRectList.css
new file mode 100644
index 0000000..2830ad3
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/RoundRectList.css
@@ -0,0 +1,39 @@
+/* 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;
+}
+.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: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;
+}
diff --git a/dojox/mobile/themes/blackberry/RoundRectList.less b/dojox/mobile/themes/blackberry/RoundRectList.less
new file mode 100644
index 0000000..52e1164
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/RoundRectList.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/RoundRectList.less";
diff --git a/dojox/mobile/themes/blackberry/Slider-compat.css b/dojox/mobile/themes/blackberry/Slider-compat.css
new file mode 100644
index 0000000..d3ae9b6
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Slider-compat.css
@@ -0,0 +1,43 @@
+/* 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;
+}
+.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;
+}
+.mblSliderV .mblSliderProgressBar {
+	background: #088EEF;
+}
+.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;
+}
diff --git a/dojox/mobile/themes/blackberry/Slider.css b/dojox/mobile/themes/blackberry/Slider.css
new file mode 100644
index 0000000..5e3c183
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Slider.css
@@ -0,0 +1,62 @@
+/* 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;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f7f3f7), to(#cec5d6), color-stop(0.5, #ced3ce));
+  -webkit-border-radius: 6px;
+}
+.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 {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  -webkit-border-radius: 6px;
+}
+.mblSliderHandle {
+  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));
+}
+.mblSliderTransition {
+  -webkit-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);
+}
diff --git a/dojox/mobile/themes/blackberry/Slider.less b/dojox/mobile/themes/blackberry/Slider.less
new file mode 100644
index 0000000..928972f
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Slider.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/Slider.less";
diff --git a/dojox/mobile/themes/blackberry/Switch-compat.css b/dojox/mobile/themes/blackberry/Switch-compat.css
new file mode 100644
index 0000000..3756d95
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Switch-compat.css
@@ -0,0 +1,70 @@
+/* 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 */
+.mblSwRoundShape1 .mblSwitchBgLeft {
+	background-image: url(compat/switch-round-l.gif);
+}
+.mblSwRoundShape1 .mblSwitchBgRight {
+	background-image: url(compat/switch-round-r.gif);
+}
+.mblSwRoundShape1 .mblSwitchKnob {
+	top: 1px;
+	height: 26px;
+	background-image: url(compat/switch-round1-k.gif);
+}
+/* Switch - Round Shape2 */
+.mblSwRoundShape2 .mblSwitchBgLeft {
+	background-image: url(compat/switch-round-l.gif);
+}
+.mblSwRoundShape2 .mblSwitchBgRight {
+	background-image: url(compat/switch-round-r.gif);
+}
+.mblSwRoundShape2 .mblSwitchKnob {
+	top: 1px;
+	height: 26px;
+	background-image: url(compat/switch-round2-k.gif);
+}
+/* Switch - Arc Shape1 */
+.mblSwArcShape1 .mblSwitchBgLeft {
+	background-image: url(compat/switch-arc-l.gif);
+}
+.mblSwArcShape1 .mblSwitchBgRight {
+	background-image: url(compat/switch-arc-r.gif);
+}
+.mblSwArcShape1 .mblSwitchKnob {
+	top: 1px;
+	height: 26px;
+	background-image: url(compat/switch-arc1-k.gif);
+}
+/* Switch - Arc Shape2 */
+.mblSwArcShape2 .mblSwitchBgLeft {
+	background-image: url(compat/switch-arc-l.gif);
+}
+.mblSwArcShape2 .mblSwitchBgRight {
+	background-image: url(compat/switch-arc-r.gif);
+}
+.mblSwArcShape2 .mblSwitchKnob {
+	top: 1px;
+	height: 26px;
+	background-image: url(compat/switch-arc2-k.gif);
+}
diff --git a/dojox/mobile/themes/blackberry/Switch.css b/dojox/mobile/themes/blackberry/Switch.css
new file mode 100644
index 0000000..b8d62c7
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Switch.css
@@ -0,0 +1,18 @@
+ at import url("../common/Switch.css");
+/* dojox.mobile.Switch */
+.mblItemSwitch {
+  top: 14px;
+}
+.mblSwitchBg {
+  -webkit-border-radius: 6px;
+}
+.mblSwitchBgLeft {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+}
+.mblSwitchBgRight {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f7f3f7), to(#cec5d6), color-stop(0.5, #ced3ce));
+}
+.mblSwitchKnob {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fafafa), to(#999999), color-stop(0.5, #bbbbbb));
+  -webkit-border-radius: 6px;
+}
diff --git a/dojox/mobile/themes/blackberry/Switch.less b/dojox/mobile/themes/blackberry/Switch.less
new file mode 100644
index 0000000..84a1146
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Switch.less
@@ -0,0 +1,4 @@
+ at import url("../common/Switch.css");
+
+ at import "variables.less";
+ at import "../common/Switch.less";
diff --git a/dojox/mobile/themes/blackberry/TabBar-compat.css b/dojox/mobile/themes/blackberry/TabBar-compat.css
new file mode 100644
index 0000000..c1944a5
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/TabBar-compat.css
@@ -0,0 +1,49 @@
+/* dojox.mobile.TabBarButton */
+.dj_ie6 .mblTabBarButtonDiv, .dj_ie7 .mblTabBarButtonDiv {
+	left: auto;
+}
+.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;
+}
diff --git a/dojox/mobile/themes/blackberry/TabBar.css b/dojox/mobile/themes/blackberry/TabBar.css
new file mode 100644
index 0000000..06bc550
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/TabBar.css
@@ -0,0 +1,164 @@
+/* dojox.mobile.TabBar */
+.mblTabBar {
+  position: relative;
+  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-align: center;
+}
+.mblTabBarNoIcons {
+  height: 34px;
+}
+.mblTabBarNoText {
+  height: 34px;
+}
+/* dojox.mobile.TabBarButton */
+.mblTabBarButton {
+  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;
+}
+.mblTabBarButtonAnchor {
+  display: block;
+  text-decoration: none;
+}
+.mblTabBarButtonDiv {
+  position: relative;
+  margin-left: auto;
+  margin-right: auto;
+  height: 34px;
+  width: 29px;
+}
+.mblTabBarButtonIcon {
+  position: absolute;
+  left: 0;
+  top: 0;
+}
+.mblTabBarButtonSpriteIcon {
+  position: absolute;
+}
+.mblTabBarButtonTextBox {
+  color: #979797;
+  font-family: "Helvetica Neue", Helvetica;
+  font-size: 11px;
+}
+.mblTabBarNoIcons .mblTabBarButtonDiv {
+  display: none;
+}
+.mblTabBarNoIcons .mblTabBarButtonTextBox {
+  line-height: 34px;
+  font-size: 20px;
+}
+.mblTabBarTop .mblTabButton .mblTabBarButtonDiv {
+  height: 40px;
+}
+.mblTabButton {
+  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));
+  font-family: Helvetica;
+  font-size: 13px;
+  color: #979797;
+  text-align: center;
+}
+.mblTabButton img {
+  position: absolute;
+  left: 0px;
+  margin-top: 8px;
+}
+.mblTabButtonSelected .mblTabBarButtonTextBox {
+  color: white;
+}
+.mblTabButtonImgDiv {
+  position: relative;
+  margin-left: 24px;
+  height: 40px;
+}
+.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;
+  background-color: #000000;
+  font-family: Helvetica;
+  font-size: 20px;
+  color: white;
+  text-align: center;
+}
+.mblTabPanelHeader .mblTabButton {
+  margin-top: 3px;
+  -webkit-border-top-left-radius: 6px;
+  -webkit-border-top-right-radius: 6px;
+}
+.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;
+}
+.mblTabPanelHeader .mblTabButtonDomButton {
+  width: 43px;
+}
+.mblTabPanelHeader .mblTabButtonDomButtonClass {
+  left: 8px;
+}
+.mblHeading .mblTabPanelHeader {
+  height: 38px;
+}
+.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));
+  font-size: 14px;
+  font-weight: bold;
+  line-height: 30px;
+  color: black;
+}
+.mblHeading .mblTabPanelHeader .mblTabButton:first-child {
+  -webkit-border-top-left-radius: 6px;
+  -webkit-border-bottom-left-radius: 6px;
+}
+.mblHeading .mblTabPanelHeader .mblTabButton:last-child {
+  -webkit-border-top-right-radius: 6px;
+  -webkit-border-bottom-right-radius: 6px;
+  border-right: none;
+}
+.mblHeading .mblTabPanelHeader .mblTabButtonSelected {
+  background-color: #0869C6;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  color: white;
+}
diff --git a/dojox/mobile/themes/blackberry/TabBar.less b/dojox/mobile/themes/blackberry/TabBar.less
new file mode 100644
index 0000000..4875c40
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/TabBar.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/TabBar.less";
diff --git a/dojox/mobile/themes/blackberry/TextArea-compat.css b/dojox/mobile/themes/blackberry/TextArea-compat.css
new file mode 100644
index 0000000..c68fb12
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/TextArea-compat.css
@@ -0,0 +1,7 @@
+/* dojox.mobile.TextArea */
+.mblTextArea {
+	-moz-border-radius: 6px;
+	-o-border-radius: 6px;
+	-ms-border-radius: 6px;
+	border-radius: 6px;
+}
diff --git a/dojox/mobile/themes/blackberry/TextArea.css b/dojox/mobile/themes/blackberry/TextArea.css
new file mode 100644
index 0000000..a39e681
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/TextArea.css
@@ -0,0 +1,14 @@
+/* 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;
+}
+/* dojox.mobile.ExpandingTextArea */
+.mblExpandingTextArea {
+  margin: 2px;
+}
diff --git a/dojox/mobile/themes/blackberry/TextArea.less b/dojox/mobile/themes/blackberry/TextArea.less
new file mode 100644
index 0000000..c16ffe0
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/TextArea.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..8672e5f
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/TextBox-compat.css
@@ -0,0 +1,7 @@
+/* dojox.mobile.TextBox */
+.mblTextBox {
+	-moz-border-radius: 6px;
+	-o-border-radius: 6px;
+	-ms-border-radius: 6px;
+	border-radius: 6px;
+}
diff --git a/dojox/mobile/themes/blackberry/TextBox.css b/dojox/mobile/themes/blackberry/TextBox.css
new file mode 100644
index 0000000..126bae9
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/TextBox.css
@@ -0,0 +1,8 @@
+/* dojox.mobile.TextBox */
+.mblTextBox {
+  height: 22px;
+  border: #9CACC0 1px inset;
+  -webkit-border-radius: 6px;
+  font-family: Helvetica;
+  font-size: 13px;
+}
diff --git a/dojox/mobile/themes/blackberry/TextBox.less b/dojox/mobile/themes/blackberry/TextBox.less
new file mode 100644
index 0000000..c83890a
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/TextBox.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/TextBox.less";
diff --git a/dojox/mobile/themes/blackberry/ToggleButton-compat.css b/dojox/mobile/themes/blackberry/ToggleButton-compat.css
new file mode 100644
index 0000000..2f5214b
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ToggleButton-compat.css
@@ -0,0 +1,31 @@
+/* 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;
+}
+.mblToggleButtonSelected {
+	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%;
+	
+}
+.dj_ff3 .mblToggleButton.mblToggleButtonChecked::after {
+	-moz-transform: translate(-25px,-6px) rotate(45deg) skew(10deg);
+}
+.mblToggleButtonChecked.mblToggleButtonSelected {
+	background-image: url(compat/button-sel-bg.png);
+}
diff --git a/dojox/mobile/themes/blackberry/ToggleButton.css b/dojox/mobile/themes/blackberry/ToggleButton.css
new file mode 100644
index 0000000..0658f5f
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ToggleButton.css
@@ -0,0 +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;
+  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;
+  font-size: 16px;
+  color: black;
+  line-height: 29px;
+}
+.mblToggleButton.mblToggleButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  color: white;
+}
+.mblToggleButton.mblToggleButtonChecked {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
+  color: black;
+}
+.mblToggleButton.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);
+  -webkit-transform-origin: 50% 50%;
+}
+.mblToggleButton.mblToggleButtonChecked.mblToggleButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  color: white;
+}
+.mblToggleButton.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
new file mode 100644
index 0000000..bdce40f
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ToggleButton.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/ToggleButton.less";
diff --git a/dojox/mobile/themes/blackberry/ToolBarButton.css b/dojox/mobile/themes/blackberry/ToolBarButton.css
new file mode 100644
index 0000000..29c8284
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ToolBarButton.css
@@ -0,0 +1,27 @@
+/* dojox.mobile.ToolBarButton */
+.mblToolBarButton {
+  float: left;
+  position: relative;
+  overflow: hidden;
+  cursor: pointer;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  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;
+}
+.mblToolBarButtonIcon {
+  position: relative;
+  top: 1px;
+}
+.mblToolBarButtonSpriteIcon {
+  position: absolute;
+}
+.mblToolBarButtonText {
+  padding: 0px 10px;
+}
diff --git a/dojox/mobile/themes/blackberry/ToolBarButton.less b/dojox/mobile/themes/blackberry/ToolBarButton.less
new file mode 100644
index 0000000..3b67bdc
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ToolBarButton.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/ToolBarButton.less";
diff --git a/dojox/mobile/themes/blackberry/Tooltip-compat.css b/dojox/mobile/themes/blackberry/Tooltip-compat.css
new file mode 100644
index 0000000..bb5900d
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Tooltip-compat.css
@@ -0,0 +1,47 @@
+/* dojox.mobile.Tooltip */
+.mblTooltip {
+	-moz-border-radius: 8px;
+	-o-border-radius: 8px;
+	-ms-border-radius: 8px;
+	border-radius: 8px;
+	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_ie9 .mblTooltip .mblHeading {
+	width: auto;
+}
+.mblTooltip .mblHeading .mblToolBarButton {
+	*margin: auto 6px;
+}
diff --git a/dojox/mobile/themes/blackberry/Tooltip.css b/dojox/mobile/themes/blackberry/Tooltip.css
new file mode 100644
index 0000000..e94715c
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Tooltip.css
@@ -0,0 +1,143 @@
+/* dojox.mobile.Tooltip */
+.mblTooltip {
+  position: absolute;
+  z-index: 2000;
+  display: block;
+  margin: 0;
+  padding: 5px;
+  border: #ADAAAD 1px solid;
+  background-color: #424142;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#4a4d52), to(#292c31));
+  -webkit-border-radius: 6px;
+  opacity: .97;
+}
+.mblTooltipBubble {
+  overflow: visible;
+  padding: 3px;
+  background-color: #000000;
+  background-image: none;
+  color: #ffffff;
+}
+.mblTooltipBubble.mblTooltipAbove .mblTooltipInnerArrow {
+  border-bottom-color: #000000;
+}
+.mblTooltipBubble.mblTooltipBelow .mblTooltipInnerArrow {
+  border-top-color: #000000;
+}
+.mblTooltipBubble.mblTooltipAfter .mblTooltipInnerArrow {
+  border-left-color: #000000;
+}
+.mblTooltipBubble.mblTooltipBefore .mblTooltipInnerArrow {
+  border-right-color: #000000;
+}
+.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: #4A4D52;
+}
+.mblTooltipAfter .mblTooltipInnerArrow {
+  left: 0;
+  top: 0;
+  border-right-width: 0;
+  border-left-color: #4A4D52;
+}
+.mblTooltipAbove .mblTooltipInnerArrow {
+  bottom: 0;
+  left: 0;
+  border-top-width: 0;
+  border-bottom-color: #4A4D52;
+}
+.mblTooltipBelow .mblTooltipInnerArrow {
+  top: 0;
+  left: 0;
+  border-bottom-width: 0;
+  border-top-color: #292C31;
+}
+.mblTooltipHidden, .mblTooltipHidden * {
+  visibility: hidden !important;
+}
+.mblTooltip .mblHeading {
+  border-top: 1px solid transparent;
+  border-bottom: 1px solid transparent;
+  background-color: transparent;
+  background-image: none;
+}
diff --git a/dojox/mobile/themes/blackberry/Tooltip.less b/dojox/mobile/themes/blackberry/Tooltip.less
new file mode 100644
index 0000000..60af6d1
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Tooltip.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/Tooltip.less";
diff --git a/dojox/mobile/themes/blackberry/View.css b/dojox/mobile/themes/blackberry/View.css
new file mode 100644
index 0000000..363c9bd
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/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: black;
+}
+.mblView.mblIn {
+  position: absolute;
+}
+.mblFixedHeaderBar {
+  z-index: 1;
+}
+.mblFixedBottomBar {
+  position: absolute !important;
+  width: 100%;
+  z-index: 1;
+}
diff --git a/dojox/mobile/themes/blackberry/View.less b/dojox/mobile/themes/blackberry/View.less
new file mode 100644
index 0000000..910651f
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/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/blackberry/base-compat.css b/dojox/mobile/themes/blackberry/base-compat.css
new file mode 100644
index 0000000..d12cf2b
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/base-compat.css
@@ -0,0 +1,7 @@
+ at import url("Heading-compat.css");
+ at import url("RoundRect-compat.css");
+ at import url("RoundRectList-compat.css");
+ at import url("EdgeToEdgeCategory-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/blackberry/base.css b/dojox/mobile/themes/blackberry/base.css
new file mode 100644
index 0000000..2409467
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/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/blackberry/blackberry-compat.css b/dojox/mobile/themes/blackberry/blackberry-compat.css
new file mode 100644
index 0000000..f5a0140
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/blackberry-compat.css
@@ -0,0 +1,18 @@
+ at import url("base-compat.css");
+
+/* common styles */
+ at import url("../common/domButtons-compat.css");
+ at import url("../common/SpinWheel-compat.css");
+
+/* widget styles */
+ 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("Opener-compat.css");
+ at import url("RadioButton-compat.css");
+ at import url("Slider-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");
diff --git a/dojox/mobile/themes/blackberry/blackberry.css b/dojox/mobile/themes/blackberry/blackberry.css
new file mode 100644
index 0000000..a50e0ce
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/blackberry.css
@@ -0,0 +1,22 @@
+ at import url("base.css");
+
+/* common styles */
+ at import url("../common/domButtons.css");
+ at import url("../common/FixedSplitter.css");
+ at import url("../common/SpinWheel.css");
+ at import url("../common/transitions.css");
+
+/* widget styles */
+ at import url("Button.css");
+ at import url("Carousel.css");
+ at import url("CheckBox.css");
+ at import url("ComboBox.css");
+ at import url("IconContainer.css");
+ at import url("Opener.css");
+ at import url("PageIndicator.css");
+ at import url("RadioButton.css");
+ at import url("Slider.css");
+ at import url("TabBar.css");
+ at import url("TextArea.css");
+ at import url("TextBox.css");
+ at import url("ToggleButton.css");
diff --git a/dojox/mobile/themes/blackberry/common.css b/dojox/mobile/themes/blackberry/common.css
new file mode 100644
index 0000000..489bccb
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/common.css
@@ -0,0 +1,29 @@
+html.mobile, .mobile body {
+  width: 100%;
+  margin: 0px;
+  padding: 0px;
+}
+.mobile body {
+  overflow-x: hidden;
+  -webkit-text-size-adjust: none;
+  background-color: #DEDFDE;
+  font-family: Helvetica;
+  font-size: 18px;
+}
+/* Button Colors */
+.mblColorBlue {
+  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));
+}
+/* Default Button Colors */
+.mblColorDefault {
+  color: black;
+  background-color: #CED3CE;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
+}
+.mblColorDefaultSel {
+  color: white;
+  background-color: #0869C6;
+  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/common.less b/dojox/mobile/themes/blackberry/common.less
new file mode 100644
index 0000000..4e57a5c
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/common.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/common.less";
diff --git a/dojox/mobile/themes/blackberry/compat/arrow-button-bg.png b/dojox/mobile/themes/blackberry/compat/arrow-button-bg.png
new file mode 100644
index 0000000..55a6e27
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/arrow-button-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/arrow-button-head.gif b/dojox/mobile/themes/blackberry/compat/arrow-button-head.gif
new file mode 100644
index 0000000..3572fbf
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/arrow-button-head.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/blue-button-bg.png b/dojox/mobile/themes/blackberry/compat/blue-button-bg.png
new file mode 100644
index 0000000..3bd558b
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/blue-button-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/button-bg.png b/dojox/mobile/themes/blackberry/compat/button-bg.png
new file mode 100644
index 0000000..ba69969
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/button-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/button-sel-bg.png b/dojox/mobile/themes/blackberry/compat/button-sel-bg.png
new file mode 100644
index 0000000..4e7384a
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/button-sel-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/gray-arrow.png b/dojox/mobile/themes/blackberry/compat/gray-arrow.png
new file mode 100644
index 0000000..c93d17f
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/gray-arrow.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/heading-bg.png b/dojox/mobile/themes/blackberry/compat/heading-bg.png
new file mode 100644
index 0000000..f0546b4
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/heading-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/icon-content-heading-bg.png b/dojox/mobile/themes/blackberry/compat/icon-content-heading-bg.png
new file mode 100644
index 0000000..3daa1a8
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/icon-content-heading-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/red-button-bg.png b/dojox/mobile/themes/blackberry/compat/red-button-bg.png
new file mode 100644
index 0000000..799870f
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/red-button-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/slider-h-bar-bg.png b/dojox/mobile/themes/blackberry/compat/slider-h-bar-bg.png
new file mode 100644
index 0000000..e130b9c
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/slider-h-bar-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/slider-h-bg.png b/dojox/mobile/themes/blackberry/compat/slider-h-bg.png
new file mode 100644
index 0000000..955dc11
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/slider-h-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/slider-handle-bg.png b/dojox/mobile/themes/blackberry/compat/slider-handle-bg.png
new file mode 100644
index 0000000..d06d0dd
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/slider-handle-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
new file mode 100644
index 0000000..9abb5fb
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-arc-l.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-arc-r.gif b/dojox/mobile/themes/blackberry/compat/switch-arc-r.gif
new file mode 100644
index 0000000..a787840
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-arc-r.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-arc1-k.gif b/dojox/mobile/themes/blackberry/compat/switch-arc1-k.gif
new file mode 100644
index 0000000..6a4e89d
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-arc1-k.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-arc2-k.gif b/dojox/mobile/themes/blackberry/compat/switch-arc2-k.gif
new file mode 100644
index 0000000..5193586
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-arc2-k.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-default-k.gif b/dojox/mobile/themes/blackberry/compat/switch-default-k.gif
new file mode 100644
index 0000000..193cb73
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-default-k.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-default-l.gif b/dojox/mobile/themes/blackberry/compat/switch-default-l.gif
new file mode 100644
index 0000000..1fb3013
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-default-l.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-default-r.gif b/dojox/mobile/themes/blackberry/compat/switch-default-r.gif
new file mode 100644
index 0000000..6511b8b
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-default-r.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-round-l.gif b/dojox/mobile/themes/blackberry/compat/switch-round-l.gif
new file mode 100644
index 0000000..ed34d5d
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-round-l.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-round-r.gif b/dojox/mobile/themes/blackberry/compat/switch-round-r.gif
new file mode 100644
index 0000000..3825e83
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-round-r.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-round1-k.gif b/dojox/mobile/themes/blackberry/compat/switch-round1-k.gif
new file mode 100644
index 0000000..8d00c11
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-round1-k.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-round2-k.gif b/dojox/mobile/themes/blackberry/compat/switch-round2-k.gif
new file mode 100644
index 0000000..c4c7969
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-round2-k.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/tab-button-bg.png b/dojox/mobile/themes/blackberry/compat/tab-button-bg.png
new file mode 100644
index 0000000..548ef73
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/tab-button-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/tab-orange-button-bg.png b/dojox/mobile/themes/blackberry/compat/tab-orange-button-bg.png
new file mode 100644
index 0000000..56f555b
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/tab-orange-button-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/tab-sel-button-bg.png b/dojox/mobile/themes/blackberry/compat/tab-sel-button-bg.png
new file mode 100644
index 0000000..c454088
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/tab-sel-button-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/images/thumb-overlay-large.png b/dojox/mobile/themes/blackberry/images/thumb-overlay-large.png
new file mode 100644
index 0000000..dfac370
Binary files /dev/null and b/dojox/mobile/themes/blackberry/images/thumb-overlay-large.png differ
diff --git a/dojox/mobile/themes/blackberry/images/thumb-overlay-small.png b/dojox/mobile/themes/blackberry/images/thumb-overlay-small.png
new file mode 100644
index 0000000..b6836d9
Binary files /dev/null and b/dojox/mobile/themes/blackberry/images/thumb-overlay-small.png differ
diff --git a/dojox/mobile/themes/blackberry/images/thumb-overlay.png b/dojox/mobile/themes/blackberry/images/thumb-overlay.png
new file mode 100644
index 0000000..b16efec
Binary files /dev/null and b/dojox/mobile/themes/blackberry/images/thumb-overlay.png differ
diff --git a/dojox/mobile/themes/blackberry/variables.less b/dojox/mobile/themes/blackberry/variables.less
new file mode 100644
index 0000000..90d6e4b
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/variables.less
@@ -0,0 +1,763 @@
+// common.less
+.mobile-body-styles () {
+	background-color: #DEDFDE;
+	font-family: Helvetica;
+	font-size: 18px;
+}
+
+.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));
+}
+.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));
+}
+.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));
+}
+
+// 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 () {
+	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
+.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 () {
+}
+.mblToolBarButtonIcon-styles () {
+	top: 1px;
+}
+
+// RoundRect.less
+.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;
+	background-color: white;
+	font-family: Helvetica;
+	font-size: 16px;
+	font-weight: bold;
+	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;
+}
+
+// EdgeToEdgeList.less
+.mblEdgeToEdgeList-styles () {
+	margin: 0px;
+	padding: 0px;
+	background-color: white;
+}
+.mblEdgeToEdgeList-LastListItem-styles () {
+	border-bottom-width: 0px;
+}
+
+// ListItem.less
+.mblListItem-styles () {
+	padding: 6px;
+	height: 43px;
+	border-bottom: solid 1px #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;
+}
+.mblItemSelected-mblListItemSubText-styles () {
+	color: white;
+}
+.mblListItemTextBoxSelected-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 () {
+}
+.mblListItemSubText-styles () {
+	font-size: 14px;
+	color: #7B7D48;
+}
+
+// Switch.less
+.mblItemSwitch-styles () {
+	top: 14px;
+}
+.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));
+}
+.mblSwitchKnob-styles () {
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#FAFAFA), to(#999999), color-stop(0.5, #BBBBBB));
+	-webkit-border-radius: 6px;
+}
+
+// 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));
+	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));
+	color: white;
+}
+.mblButton-mblBlueButtonSelected-styles () {
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#088EEF), to(#0851AD), color-stop(0.5, #0869C6));
+	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));
+}
+.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));
+}
+.mblCheckBoxChecked-mblCheckBoxSelected-after-styles () {
+	border-color: white;
+}
+
+// ComboBox.less
+.dijitPopup-styles () {
+	-webkit-box-shadow: none;
+	-webkit-border-radius: 12px;
+}
+.mblComboBoxMenu-styles () {
+	border: 1px solid black;
+	-webkit-border-radius: 12px;
+	background-color: black;
+}
+.mblComboBoxMenuItemSelected-styles () {
+	color: white;
+	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;
+}
+
+// IconContainer.less
+.mblIconContainer-styles () {
+	margin: 0px;
+	padding: 0px;
+}
+
+// IconItem.less
+.mblIconItemTerminator-styles () {
+	height: 0px;
+}
+.mblIconItemSub-styles () {
+	background-color: white;
+	color: black;
+}
+.mblIconArea-styles () {
+	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;
+}
+
+// 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));
+}
+.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));
+}
+.mblRadioButtonChecked-Selected-after-styles () {
+	border-color: white;
+}
+
+// Slider.less
+.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;
+}
+.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));
+}
+
+// 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;
+}
+.mblTabBar-TabBarButton-styles () {
+}
+.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;
+}
+.mblTabBarButtonDiv-styles () {
+	height: 34px;
+	width: 29px;
+}
+.mblTabBarButtonIcon-styles () {
+	left: 0;
+	top: 0;
+}
+.mblTabBarButtonTextBox-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;
+}
+.mblTabButton-TabBarButtonAnchor-styles () {
+}
+.mblTabBarTop-TabButton-TabBarButtonDiv-styles () {
+	height: 40px;
+}
+.mblTabBarHead-TabButton-TabBarButtonDiv-styles () {
+}
+.mblTabButton-FirstTabButtom-styles () {
+}
+.mblTabButton-LastTabButton-styles () {
+}
+.mblTabButton-img-styles () {
+	position: absolute;
+	left: 0px;
+	margin-top: 8px;
+}
+.mblTabBarButtonTextBoxSelected-styles () {
+	color: white;
+}
+.mblTabButtonSelected-styles () {
+}
+.mblTabButtonHighlighted-styles () {
+}
+.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;
+}
+.mblTabPanelHeader-TabButton-styles () {
+	margin-top: 3px;
+	-webkit-border-top-left-radius: 6px;
+	-webkit-border-top-right-radius: 6px;
+}
+.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;
+}
+.mblTabPanelHeader-TabButtonDomButtonClass-styles () {
+	left: 8px;
+}
+.mblTabPanelHeader-DomButton-styles () {
+}
+.mblTabPanelHeader-inHeading-styles () {
+	height: 38px;
+}
+.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;
+}
+.mblTabPanelHeader-TabButton-FirstTabButtom-inHeading-styles () {
+	-webkit-border-top-left-radius: 6px;
+	-webkit-border-bottom-left-radius: 6px;
+}
+.mblTabPanelHeader-TabButton-LastTabButtom-inHeading-styles () {
+	-webkit-border-top-right-radius: 6px;
+	-webkit-border-bottom-right-radius: 6px;
+	border-right: none;
+}
+.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;
+}
+
+// TextBox.less
+.mblTextBox-styles () {
+	height: 22px;
+	border: #9CACC0 1px inset;
+	-webkit-border-radius: 6px;
+	font-family: Helvetica;
+	font-size: 13px;
+}
+
+// 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;
+	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%;
+}
+.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;
+}
+
+// Tooltip.less
+.mblTooltip-styles () {
+	padding: 5px;
+	border: #ADAAAD 1px solid;
+	background-color: #424142;
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#4A4D52), to(#292C31));
+	-webkit-border-radius: 6px;
+	opacity: .97;
+}
+.mblTooltipBubble-styles () {
+	background-color: #000000;
+	background-image: none;
+	color: #ffffff;
+}
+.mblTooltipInnerArrow-Bubble-Above-styles () {
+	border-bottom-color: #000000;
+}
+.mblTooltipInnerArrow-Bubble-Below-styles () {
+	border-top-color: #000000;
+}
+.mblTooltipInnerArrow-Bubble-After-styles () {
+	border-left-color: #000000;
+}
+.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;
+}
+.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: #4A4D52;
+}
+.mblTooltipInnerArrow-After-styles () {
+	border-right-width: 0;
+	border-left-color: #4A4D52;
+}
+.mblTooltipInnerArrow-Above-styles () {
+	border-top-width: 0;
+	border-bottom-color: #4A4D52;
+}
+.mblTooltipInnerArrow-Below-styles () {
+	border-bottom-width: 0;
+	border-top-color: #292C31;
+}
+.mblTooltip-Heading-styles () {
+	border-top: 1px solid transparent;
+	border-bottom: 1px solid transparent;
+	background-color: transparent;
+	background-image: none;
+}
+.mblTooltip-Heading-ToolbarButton-styles () {
+}
diff --git a/dojox/mobile/themes/buttons-compat.css b/dojox/mobile/themes/buttons-compat.css
deleted file mode 100755
index 0c2a925..0000000
--- a/dojox/mobile/themes/buttons-compat.css
+++ /dev/null
@@ -1,30 +0,0 @@
-.mblBlueMinusButton {
-	background-image: url(compat/small-blue-button-bg.png);
-}
-.mblDarkBlueMinusButton {
-	background-image: url(compat/small-darkblue-button-bg.png);
-}
-.mblRedMinusButton {
-	background-image: url(compat/small-red-button-bg.png);
-}
-.mblBluePlusButton {
-	background-image: url(compat/small-blue-button-bg.png);
-}
-.mblDarkBluePlusButton {
-	background-image: url(compat/small-darkblue-button-bg.png);
-}
-.mblRedPlusButton {
-	background-image: url(compat/small-red-button-bg.png);
-}
-.mblCheckOnButton {
-	background-image: url(compat/check-on-button.png);
-}
-.mblCheckOnButton DIV, .mblCheckOnButton P {
-	display: none;
-}
-.mblCheckOffButton {
-	background-image: url(compat/check-off-button.png);
-}
-.mblCheckOffButton DIV, .mblCheckOffButton P {
-	display: none;
-}
diff --git a/dojox/mobile/themes/buttons.css b/dojox/mobile/themes/buttons.css
deleted file mode 100755
index 0bf86ec..0000000
--- a/dojox/mobile/themes/buttons.css
+++ /dev/null
@@ -1,191 +0,0 @@
-/* Minus Button */
-.mblBlueMinusButton {
-	position: relative;
-	width: 22px;
-	height: 18px;
-	border-width: 1px 1px 1px 0px;
-	border-style: outset;
-	border-color: #6D89C7;
-	color: white;
-	-webkit-border-radius: 3px;
-	-moz-border-radius: 3px;
-	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));
-}
-.mblDarkBlueMinusButton {
-	position: relative;
-	width: 22px;
-	height: 18px;
-	border-width: 1px 1px 1px 0px;
-	border-style: outset;
-	border-color: #6D89C7;
-	color: white;
-	-webkit-border-radius: 3px;
-	-moz-border-radius: 3px;
-	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));
-}
-.mblRedMinusButton {
-	position: relative;
-	width: 22px;
-	height: 18px;
-	border-width: 1px 1px 1px 0px;
-	border-style: outset;
-	border-color: #cc1122;
-	color: white;
-	-webkit-border-radius: 3px;
-	-moz-border-radius: 3px;
-	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));
-}
-.mblBlueMinusButton DIV, .mblDarkBlueMinusButton DIV, .mblRedMinusButton DIV {
-	position: absolute;
-	top: 7px;
-	left: 7px;
-	width: 8px;
-	height: 2px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
-	border-top: 1px solid #4A5A71;
-}
-
-/* Plus Button */
-.mblBluePlusButton {
-	position: relative;
-	width: 22px;
-	height: 18px;
-	border-width: 1px 1px 1px 0px;
-	border-style: outset;
-	border-color: #6D89C7;
-	color: white;
-	-webkit-border-radius: 3px;
-	-moz-border-radius: 3px;
-	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));
-}
-.mblDarkBluePlusButton {
-	position: relative;
-	width: 22px;
-	height: 18px;
-	border-width: 1px 1px 1px 0px;
-	border-style: outset;
-	border-color: #6D89C7;
-	color: white;
-	-webkit-border-radius: 3px;
-	-moz-border-radius: 3px;
-	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));
-}
-.mblRedPlusButton {
-	position: relative;
-	width: 22px;
-	height: 18px;
-	border-width: 1px 1px 1px 0px;
-	border-style: outset;
-	border-color: #6D89C7;
-	color: white;
-	-webkit-border-radius: 3px;
-	-moz-border-radius: 3px;
-	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));
-}
-.mblBluePlusButton DIV, .mblDarkBluePlusButton DIV, .mblRedPlusButton DIV {
-	position: absolute;
-	top: 7px;
-	left: 7px;
-	width: 8px;
-	height: 2px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
-	border-top: 1px solid #4A5A71;
-}
-.mblBluePlusButton P, .mblDarkBluePlusButton P, .mblRedPlusButton P {
-	position: absolute;
-	top: 4px;
-	left: 10px;
-	width: 2px;
-	height: 8px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
-}
-
-.mblCheckOnButton {
-	position: relative;
-	width: 30px;
-	height: 30px;
-	border-width: 1px;
-	border-style: outset;
-	border-color: #A5A2A5;
-	color: white;
-	-webkit-border-radius: 3px;
-	-moz-border-radius: 3px;
-	background-color: #D6D3D6;
-	background: -webkit-gradient(linear, left top, left bottom, from(#EFF3EF), to(#BDBEBD));
-}
-.mblCheckOnButton 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);
-}
-.mblCheckOnButton P {
-	position: absolute;
-	top: 11px;
-	left: 9px;
-	width: 20px;
-	height: 4px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: #00CF00;
-	border-bottom: 1px solid #4A5A71;
-	-webkit-border-radius: 2px;
-	-webkit-transform: rotate(-50deg);
-}
-
-.mblCheckOffButton {
-	position: relative;
-	width: 30px;
-	height: 30px;
-	border-width: 1px;
-	border-style: outset;
-	border-color: #A5A2A5;
-	color: white;
-	-webkit-border-radius: 3px;
-	-moz-border-radius: 3px;
-	background-color: #D6D3D6;
-	background: -webkit-gradient(linear, left top, left bottom, from(#EFF3EF), to(#BDBEBD));
-}
-.mblCheckOffButton DIV {
-	position: absolute;
-	top: 11px;
-	left: 9px;
-	width: 20px;
-	height: 4px;
-	font-size: 1px;
-	background-color: #BDBABD;
-	border-top: 1px solid #8C8E8C;
-	-webkit-border-radius: 2px;
-	-webkit-transform: rotate(-50deg);
-}
-.mblCheckOffButton P {
-	position: absolute;
-	top: 15px;
-	left: 3px;
-	width: 14px;
-	height: 4px;
-	font-size: 1px;
-	background-color: #BDBABD;
-	border-bottom: 1px solid #8C8E8C;
-	-webkit-border-radius: 2px;
-	-webkit-transform: rotate(50deg);
-}
diff --git a/dojox/mobile/themes/common/Button.less b/dojox/mobile/themes/common/Button.less
new file mode 100644
index 0000000..d84460f
--- /dev/null
+++ b/dojox/mobile/themes/common/Button.less
@@ -0,0 +1,29 @@
+/* dojox.mobile.Button */
+.mblButton {
+	cursor: pointer;
+	outline: none;
+	-webkit-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 {
+	.mblButtonSelected-styles;
+}
+.mblButtonDisabled,
+.mblButton:disabled {
+	cursor: default;
+	.mblButtonDisabled-styles;
+}
diff --git a/dojox/mobile/themes/common/Carousel.less b/dojox/mobile/themes/common/Carousel.less
new file mode 100644
index 0000000..dd16627
--- /dev/null
+++ b/dojox/mobile/themes/common/Carousel.less
@@ -0,0 +1,58 @@
+/* dojox.mobile.Carousel */
+.mblCarousel {
+	overflow: hidden;
+}
+.mblCarouselBox {
+	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;
+}
+.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;
+}
diff --git a/dojox/mobile/themes/common/CheckBox.less b/dojox/mobile/themes/common/CheckBox.less
new file mode 100644
index 0000000..49e56f3
--- /dev/null
+++ b/dojox/mobile/themes/common/CheckBox.less
@@ -0,0 +1,25 @@
+/* dojox.mobile.CheckBox */
+.mblCheckBox {
+	position: relative;
+	cursor: pointer;
+	outline: none;
+	-webkit-appearance: none;
+	-webkit-tap-highlight-color: rgba(255,255,255,0);
+	.mblCheckBox-styles;
+}
+.mblCheckBoxSelected {
+	.mblCheckBoxSelected-styles;
+}
+.mblCheckBoxChecked,
+.mblCheckBox:checked {
+	.mblCheckBoxChecked-styles;
+	&::after {
+		.mblCheckBoxChecked-after-styles;
+	}
+	&.mblCheckBoxSelected {
+		.mblCheckBoxChecked-mblCheckBoxSelected-styles;
+		&::after {
+			.mblCheckBoxChecked-mblCheckBoxSelected-after-styles;
+		}
+	}
+}
diff --git a/dojox/mobile/themes/common/ComboBox.less b/dojox/mobile/themes/common/ComboBox.less
new file mode 100644
index 0000000..4358887
--- /dev/null
+++ b/dojox/mobile/themes/common/ComboBox.less
@@ -0,0 +1,40 @@
+/* dojox.mobile.ComboBox */
+.dijitPopup {
+	// Popup items have a wrapper div (dijitPopup)
+	// with the real popup inside, and maybe an iframe too
+	margin: 0;
+	padding: 0;
+	position: absolute;
+	border: 0;
+	background-color: transparent;
+	.dijitPopup-styles;
+}
+.mblReset {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	line-height: normal;
+	font: inherit;
+	color: inherit;
+}
+.mblComboBoxMenu {
+	overflow-y: hidden !important;
+	position: relative;
+	overflow: hidden;
+	.mblComboBoxMenu-styles;
+}
+.mblComboBoxMenuItem {
+	white-space: nowrap;
+	.mblComboBoxMenuItem-styles;
+}
+.mblComboBoxMenuItemSelected {
+	// dijitMenuItemHover refers to actual mouse over
+	// dijitMenuItemSelected is used after a menu has been "activated" by
+	// clicking it, tabbing into it, or being opened from a parent menu,
+	// and denotes that the menu item has focus or that focus is on a child menu
+	.mblComboBoxMenuItemSelected-styles;
+}
+.mblComboBoxMenuPreviousButton,
+.mblComboBoxMenuNextButton {
+	.mblComboBoxMenuPreviousButton-styles;
+}
diff --git a/dojox/mobile/themes/common/EdgeToEdgeCategory.less b/dojox/mobile/themes/common/EdgeToEdgeCategory.less
new file mode 100644
index 0000000..13d78e4
--- /dev/null
+++ b/dojox/mobile/themes/common/EdgeToEdgeCategory.less
@@ -0,0 +1,8 @@
+/* dojox.mobile.EdgeToEdgeCategory */
+.mblEdgeToEdgeCategory {
+	position: relative;
+	overflow: hidden;
+	white-space: nowrap;
+	text-overflow: ellipsis;
+	.mblEdgeToEdgeCategory-styles;
+}
diff --git a/dojox/mobile/themes/common/EdgeToEdgeList.less b/dojox/mobile/themes/common/EdgeToEdgeList.less
new file mode 100644
index 0000000..9fbed0e
--- /dev/null
+++ b/dojox/mobile/themes/common/EdgeToEdgeList.less
@@ -0,0 +1,8 @@
+/* dojox.mobile.EdgeToEdgeList */
+.mblEdgeToEdgeList {
+	position: relative; /* IE needs this */
+	.mblEdgeToEdgeList-styles;
+	.mblListItem:last-child {
+		.mblEdgeToEdgeList-LastListItem-styles;
+	}
+}
diff --git a/dojox/mobile/themes/FixedSplitter.css b/dojox/mobile/themes/common/FixedSplitter.css
similarity index 100%
rename from dojox/mobile/themes/FixedSplitter.css
rename to dojox/mobile/themes/common/FixedSplitter.css
diff --git a/dojox/mobile/themes/common/Heading.less b/dojox/mobile/themes/common/Heading.less
new file mode 100644
index 0000000..38083f9
--- /dev/null
+++ b/dojox/mobile/themes/common/Heading.less
@@ -0,0 +1,58 @@
+/* dojox.mobile.Heading */
+.mblHeading {
+	position: relative;
+	margin: 0px;
+	width: 100%;
+	overflow: hidden;
+	white-space: nowrap;
+	text-overflow: ellipsis;
+	z-index: 1;
+	.mblHeading-styles;
+}
+.mblHeading * {
+	z-index: 2;
+}
+.mblHeadingDivTitle {
+	position: absolute;
+	width: 100%;
+	display: none;
+	left: 0px;
+	z-index: 1;
+}
+.mblHeadingCenterTitle .mblHeadingDivTitle {
+	display: block;
+}
+.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.less b/dojox/mobile/themes/common/IconContainer.less
new file mode 100644
index 0000000..0f47a0f
--- /dev/null
+++ b/dojox/mobile/themes/common/IconContainer.less
@@ -0,0 +1,79 @@
+/* dojox.mobile.IconContainer */
+.mblIconContainer {
+	.mblIconContainer-styles;
+}
+
+/* dojox.mobile.IconItem */
+.mblIconItem {
+	list-style-type: none;
+	float: left;
+	-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblIconItemTerminator {
+	list-style-type: none;
+	clear: both;
+	.mblIconItemTerminator-styles;
+}
+.mblIconItemSub {
+	list-style-type: none;
+	.mblIconItemSub-styles;
+}
+.mblIconArea {
+	.mblIconArea-styles;
+	div {
+		position: relative;
+		height: 65px;
+		line-height: 65px;
+		text-align: center;
+	}
+	img {
+		vertical-align: middle;
+	}
+}
+.mblIconItemSpriteIcon {
+	position: absolute;
+}
+.mblContent {
+	clear: both;
+	.mblContent-styles;
+}
+table.mblClose {
+	clear: both;
+	cursor: pointer;
+}
+.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);
+}
+.mblCloseContent{
+	-webkit-animation-duration: .3s;
+	-webkit-animation-timing-function: ease-in-out;
+	-webkit-animation-name: mblShrink;
+	-webkit-transform: scale(0.01);
+	&.mblShrink0{
+		-webkit-animation-name: mblShrink0;
+	}
+	&.mblShrink1{
+		-webkit-animation-name: mblShrink1;
+	}
+	&.mblShrink2{
+		-webkit-animation-name: mblShrink2;
+	}
+	&.mblShrink3{
+		-webkit-animation-name: mblShrink3;
+	}
+}
+
+/* Icon Content Heading */
+.mblIconContentHeading {
+	position: relative;
+	clear: both;
+	overflow: hidden;
+	white-space: nowrap;
+	text-overflow: ellipsis;
+	.mblIconContentHeading-styles;
+}
diff --git a/dojox/mobile/themes/common/IconContainer_keyframes.css b/dojox/mobile/themes/common/IconContainer_keyframes.css
new file mode 100644
index 0000000..b96c6a6
--- /dev/null
+++ b/dojox/mobile/themes/common/IconContainer_keyframes.css
@@ -0,0 +1,48 @@
+/* Icon Container */
+ 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 -webkit-keyframes mblShrink{
+	from { -webkit-transform: scale(1); }
+	to { -webkit-transform: scale(0.01); }
+}
+ at -webkit-keyframes mblShrink0{
+	from { -webkit-transform: scale(1); }
+	to { -webkit-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 -webkit-keyframes mblShrink2{
+	from { -webkit-transform: scale(1); }
+	to { -webkit-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); }
+}
diff --git a/dojox/mobile/themes/common/ListItem.less b/dojox/mobile/themes/common/ListItem.less
new file mode 100644
index 0000000..2b49a2a
--- /dev/null
+++ b/dojox/mobile/themes/common/ListItem.less
@@ -0,0 +1,78 @@
+/* dojox.mobile.ListItem */
+.mblListItem {
+	position: relative;
+	list-style-type: none;
+	vertical-align: bottom; /* To avoid IE6 LI bug */
+	.mblListItem-styles;
+	&.mblVariableHeight {
+		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);
+		}
+	}
+}
+.mblItemSelected {
+	.mblItemSelected-styles;
+	.mblListItemSubText {
+		.mblItemSelected-mblListItemSubText-styles;
+	}
+	.mblListItemAnchor {
+		.mblItemSelected-mblListItemAnchor-styles;
+	}
+	.mblDomButton {
+		div {
+			.mblItemSelected-mblDomButton-Div-styles;
+		}
+	}
+}
+.mblListItemTextBoxSelected {
+	.mblListItemTextBoxSelected-styles;
+}
+.mblListItemChecked {
+	.mblListItemChecked-styles;
+}
+.mblListItemIcon {
+	float: left;
+	line-height: normal;
+	.mblListItemIcon-styles;
+}
+.mblListItemSpriteIcon {
+	position: absolute;
+	.mblListItemSpriteIcon-styles;
+
+}
+.mblListItemRightIcon,
+.mblListItemRightIcon2 {
+	position: relative;
+	float: right;
+	line-height: normal;
+	.mblListItemRightIcon-styles;
+}
+.mblListItemRightText {
+	position: relative;
+	float: right;
+	line-height: normal;
+	.mblListItemRightText-styles;
+}
+.mblListItemTextBox {
+	overflow: hidden;
+	white-space: nowrap;
+	text-overflow: ellipsis;
+	.mblListItemTextBox-styles;
+}
+.mblVariableHeight .mblListItemTextBox {
+	white-space: normal;
+}
+.mblListItemAnchorNoIcon .mblListItemTextBox {
+	.mblListItemAnchorNoIcon-mblListItemTextBox-styles;
+}
+.mblListItemSubText {
+	.mblListItemSubText-styles;
+}
diff --git a/dojox/mobile/themes/common/Overlay.less b/dojox/mobile/themes/common/Overlay.less
new file mode 100644
index 0000000..076928c
--- /dev/null
+++ b/dojox/mobile/themes/common/Overlay.less
@@ -0,0 +1,15 @@
+/* dojox.mobile.Overlay */
+.mblOverlay {
+	position: fixed;
+	z-index: 2000;
+	left: 0;
+	bottom: 0;
+	margin: 0;
+	width: 100%;
+	text-align: -webkit-center;
+	.mblOverlay-styles;
+}
+.mblOverlayHidden *,
+.mblOverlayHidden {
+	visibility: hidden !important;
+}
diff --git a/dojox/mobile/themes/common/PageIndicator.less b/dojox/mobile/themes/common/PageIndicator.less
new file mode 100644
index 0000000..6678f9e
--- /dev/null
+++ b/dojox/mobile/themes/common/PageIndicator.less
@@ -0,0 +1,24 @@
+/* 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;
+	-webkit-border-radius: 3px;
+	-moz-border-radius: 3px;
+}
+.mblPageIndicatorDotSelected {
+	background-color: white;
+}
diff --git a/dojox/mobile/themes/common/ProgressIndicator.less b/dojox/mobile/themes/common/ProgressIndicator.less
new file mode 100644
index 0000000..8d8b9ab
--- /dev/null
+++ b/dojox/mobile/themes/common/ProgressIndicator.less
@@ -0,0 +1,58 @@
+/* Progress Indicator */
+.mblProgContainer {
+	position: absolute;
+	width: 40px;
+	height: 40px;
+	top: 180px;
+	left: 50%;
+	margin: -18px 0px 0px -18px;
+}
+.mblProg {
+	position: absolute;
+	left: 2px;
+	top: 0px;
+	width: 11px;
+	font-size: 1px;
+	height: 4px;
+	overflow: hidden;
+	-webkit-transform-origin: 0 2px;
+	background-color: #C0C0C0;
+	-webkit-border-radius: 2px;
+	-moz-border-radius: 2px;
+}
+.mblProg0 {
+	-webkit-transform: translate(18px,10px) rotate(-90.1deg);
+}
+.mblProg1 {
+	-webkit-transform: translate(22px,11px) rotate(-60deg);
+}
+.mblProg2 {
+	-webkit-transform: translate(25px,14px) rotate(-30deg);
+}
+.mblProg3 {
+	-webkit-transform: translate(26px,18px) rotate(0deg);
+}
+.mblProg4 {
+	-webkit-transform: translate(25px,22px) rotate(30deg);
+}
+.mblProg5 {
+	-webkit-transform: translate(22px,25px) rotate(60deg);
+}
+.mblProg6 {
+	-webkit-transform: translate(18px,26px) rotate(90.1deg);
+}
+.mblProg7 {
+	-webkit-transform: translate(14px,25px) rotate(120deg);
+}
+.mblProg8 {
+	-webkit-transform: translate(11px,22px) rotate(150deg);
+}
+.mblProg9 {
+	-webkit-transform: translate(10px,18px) rotate(180deg);
+}
+.mblProg10 {
+	-webkit-transform: translate(11px,14px) rotate(210deg);
+}
+.mblProg11 {
+	-webkit-transform: translate(14px,11px) rotate(240deg);
+}
diff --git a/dojox/mobile/themes/common/RadioButton.less b/dojox/mobile/themes/common/RadioButton.less
new file mode 100644
index 0000000..0874ac8
--- /dev/null
+++ b/dojox/mobile/themes/common/RadioButton.less
@@ -0,0 +1,23 @@
+/* dojox.mobile.RadioButton */
+.mblRadioButton {
+	position: relative;
+	cursor: pointer;
+	outline: none;
+	-webkit-appearance: none;
+	-webkit-tap-highlight-color: rgba(255,255,255,0);
+	.mblRadioButton-styles;
+}
+.mblRadioButtonChecked,
+.mblRadioButton:checked {
+	.mblRadioButtonChecked-styles;
+	&::after {
+		position: absolute;
+		.mblRadioButtonChecked-after-styles;
+	}
+	&.mblRadioButtonSelected {
+		.mblRadioButtonChecked-Selected-styles;
+		&::after {
+			.mblRadioButtonChecked-Selected-after-styles;
+		}
+	}	
+}
diff --git a/dojox/mobile/themes/common/RoundRect.less b/dojox/mobile/themes/common/RoundRect.less
new file mode 100644
index 0000000..0cd6361
--- /dev/null
+++ b/dojox/mobile/themes/common/RoundRect.less
@@ -0,0 +1,7 @@
+/* dojox.mobile.RoundRect */
+.mblRoundRect {
+	.mblRoundRect-styles;
+	&.mblShadow {
+		.mblRoundRectShadowBox-styles;
+	}
+}
diff --git a/dojox/mobile/themes/common/RoundRectCategory.less b/dojox/mobile/themes/common/RoundRectCategory.less
new file mode 100644
index 0000000..cd4b311
--- /dev/null
+++ b/dojox/mobile/themes/common/RoundRectCategory.less
@@ -0,0 +1,7 @@
+/* dojox.mobile.RoundRectCategory */
+.mblRoundRectCategory {
+	white-space: nowrap;
+	text-overflow: ellipsis;
+	overflow: hidden;
+	.mblRoundRectCategory-styles;
+}
diff --git a/dojox/mobile/themes/common/RoundRectList.less b/dojox/mobile/themes/common/RoundRectList.less
new file mode 100644
index 0000000..b756d15
--- /dev/null
+++ b/dojox/mobile/themes/common/RoundRectList.less
@@ -0,0 +1,17 @@
+/* dojox.mobile.RoundRectList */
+.mblRoundRectList {
+	position: relative; /* IE needs this */
+	.mblRoundRectList-styles;
+	.mblListItem:first-child {
+		.mblRoundRectList-FirstListItem-styles;
+	}
+	.mblListItem:last-child {
+		.mblRoundRectList-LastListItem-styles;
+	}
+}
+.mblRoundRectCategory + .mblRoundRectList {
+	.mblRoundRectList-withCategory-styles;
+	.mblListItem:first-child {
+		.mblRoundRectList-withCategory-FirstListItem-styles;
+	}
+}
diff --git a/dojox/mobile/themes/common/Slider.less b/dojox/mobile/themes/common/Slider.less
new file mode 100644
index 0000000..ec57a17
--- /dev/null
+++ b/dojox/mobile/themes/common/Slider.less
@@ -0,0 +1,47 @@
+/* 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 */
+	.mblSlider-styles;
+}
+.mblSliderH {
+	width: 200px;
+	height: 8px;
+	.mblSliderProgressBar {
+		height: 100%;
+	}
+	.mblSliderHandle {
+		top: 50%;
+	}
+}
+.mblSliderV {
+	height: 200px;
+	width: 8px;
+	.mblSliderProgressBar {
+		width: 100%;
+	}
+	.mblSliderHandle {
+		left: 50%;
+	}
+}
+.mblSliderProgressBar {
+	.mblSliderProgressBar-styles;
+}
+.mblSliderHandle {
+	.mblSliderHandle-styles;
+}
+.mblSliderTransition {
+	-webkit-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);
+}
diff --git a/dojox/mobile/themes/common/SpinWheel-compat.css b/dojox/mobile/themes/common/SpinWheel-compat.css
new file mode 100644
index 0000000..36865f2
--- /dev/null
+++ b/dojox/mobile/themes/common/SpinWheel-compat.css
@@ -0,0 +1,36 @@
+.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.css b/dojox/mobile/themes/common/SpinWheel.css
new file mode 100644
index 0000000..e5eff56
--- /dev/null
+++ b/dojox/mobile/themes/common/SpinWheel.css
@@ -0,0 +1,77 @@
+.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/Switch.css b/dojox/mobile/themes/common/Switch.css
new file mode 100644
index 0000000..3aed56d
--- /dev/null
+++ b/dojox/mobile/themes/common/Switch.css
@@ -0,0 +1,224 @@
+/* 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
new file mode 100644
index 0000000..e9868bc
--- /dev/null
+++ b/dojox/mobile/themes/common/Switch.less
@@ -0,0 +1,16 @@
+/* dojox.mobile.Switch */
+.mblItemSwitch {
+	.mblItemSwitch-styles;
+}
+.mblSwitchBg {
+	.mblSwitchBg-styles;
+}
+.mblSwitchBgLeft {
+	.mblSwitchBgLeft-styles;
+}
+.mblSwitchBgRight {
+	.mblSwitchBgRight-styles;
+}
+.mblSwitchKnob {
+	.mblSwitchKnob-styles;
+}
diff --git a/dojox/mobile/themes/common/TabBar.less b/dojox/mobile/themes/common/TabBar.less
new file mode 100644
index 0000000..a63497a
--- /dev/null
+++ b/dojox/mobile/themes/common/TabBar.less
@@ -0,0 +1,147 @@
+/* dojox.mobile.TabBar */
+.mblTabBar {
+	position: relative;
+	overflow: hidden;
+	white-space: nowrap;
+	.mblTabBar-styles;
+}
+.mblTabBarNoIcons {
+	height: 34px;
+}
+.mblTabBarNoText {
+	height: 34px;
+}
+
+/* dojox.mobile.TabBarButton */
+.mblTabBarButton {
+	cursor: pointer;
+	-webkit-tap-highlight-color: rgba(255,255,255,0);
+}
+.mblTabBar .mblTabBarButton {
+	position: relative;
+	list-style-type: none;
+	float: left;
+	.mblTabBar-TabBarButton-styles;
+	&.mblTabButtonSelected {
+		.mblTabBar-TabBarButton-Selected-styles;
+	}
+}
+.mblTabBarButtonAnchor {
+	display: block;
+	text-decoration: none;
+}
+.mblTabBarButtonDiv {
+	position: relative;
+	margin-left: auto;
+	margin-right: auto;
+	.mblTabBarButtonDiv-styles;
+}
+.mblTabBarButtonIcon {
+	position: absolute;
+	.mblTabBarButtonIcon-styles;
+}
+.mblTabBarButtonSpriteIcon {
+	position: absolute;
+}
+.mblTabBarButtonTextBox {
+	.mblTabBarButtonTextBox-styles;
+}
+.mblTabBarNoIcons {
+	.mblTabBarButtonDiv {
+		display: none;
+	}
+	.mblTabBarButtonTextBox {
+		.mblTabBarNoIcons-TabBarButtonTextBox-styles;
+	}
+}
+.mblTabBarTop {
+	.mblTabButton {
+		.mblTabBarButtonDiv {
+			.mblTabBarTop-TabButton-TabBarButtonDiv-styles;
+		}
+	}
+}
+.mblTabBarHead {
+	.mblTabButton {
+		.mblTabBarButtonDiv {
+			.mblTabBarHead-TabButton-TabBarButtonDiv-styles;
+		}
+	}
+}
+.mblTabButton {
+	position: relative;
+	float: left;
+	list-style-type: none;
+	cursor: pointer;
+	-webkit-tap-highlight-color: rgba(255,255,255,0);
+	.mblTabButton-styles;
+	.mblTabBarButtonAnchor, .mblTabBarButtonDiv {
+		.mblTabButton-TabBarButtonAnchor-styles;
+	}
+	&:first-child {
+		.mblTabButton-FirstTabButtom-styles;
+	}
+	&:last-child {
+		.mblTabButton-LastTabButton-styles;
+	}
+	img {
+		.mblTabButton-img-styles;
+	}
+}
+.mblTabButtonSelected {
+	.mblTabBarButtonTextBox {
+		.mblTabBarButtonTextBoxSelected-styles;
+	}
+	&.mblTabButton {
+		.mblTabButtonSelected-styles;
+	}
+}
+.mblTabButtonHighlighted {
+	&.mblTabButton {
+		.mblTabButtonHighlighted-styles;
+	}
+}
+.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;
+	}
+	.mblTabButtonDomButtonClass {
+		.mblTabPanelHeader-TabButtonDomButtonClass-styles;
+	}
+	.mblDomButton {
+		.mblTabPanelHeader-DomButton-styles;
+	}
+}
+
+.mblHeading {
+	.mblTabPanelHeader {
+		.mblTabPanelHeader-inHeading-styles;
+		.mblTabButton {
+			.mblTabPanelHeader-TabButton-inHeading-styles;
+			&:first-child {
+				.mblTabPanelHeader-TabButton-FirstTabButtom-inHeading-styles;
+			}
+			&:last-child {
+				.mblTabPanelHeader-TabButton-LastTabButtom-inHeading-styles;
+			}
+		}
+		.mblTabButtonSelected {
+			.mblTabPanelHeader-TabButtonSelected-inHeading-styles;
+		}
+	}
+}
diff --git a/dojox/mobile/themes/common/TextArea.less b/dojox/mobile/themes/common/TextArea.less
new file mode 100644
index 0000000..57b80f9
--- /dev/null
+++ b/dojox/mobile/themes/common/TextArea.less
@@ -0,0 +1,9 @@
+/* dojox.mobile.TextArea */
+.mblTextArea {
+	.mblTextArea-styles;
+}
+
+/* dojox.mobile.ExpandingTextArea */
+.mblExpandingTextArea {
+	.mblExpandingTextArea-styles;
+}
diff --git a/dojox/mobile/themes/common/TextBox.less b/dojox/mobile/themes/common/TextBox.less
new file mode 100644
index 0000000..bee00c3
--- /dev/null
+++ b/dojox/mobile/themes/common/TextBox.less
@@ -0,0 +1,4 @@
+/* dojox.mobile.TextBox */
+.mblTextBox {
+	.mblTextBox-styles;
+}
diff --git a/dojox/mobile/themes/common/ToggleButton.less b/dojox/mobile/themes/common/ToggleButton.less
new file mode 100644
index 0000000..1796ab3
--- /dev/null
+++ b/dojox/mobile/themes/common/ToggleButton.less
@@ -0,0 +1,28 @@
+/* dojox.mobile.ToggleButton */
+.mblToggleButton {
+	position: relative;
+	cursor: pointer;
+	outline: none;
+	-webkit-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 {
+		cursor: default;
+		.mblToggleButtonDisabled-styles;
+	}
+}
diff --git a/dojox/mobile/themes/common/ToolBarButton.less b/dojox/mobile/themes/common/ToolBarButton.less
new file mode 100644
index 0000000..3d8ee62
--- /dev/null
+++ b/dojox/mobile/themes/common/ToolBarButton.less
@@ -0,0 +1,22 @@
+/* dojox.mobile.ToolBarButton */
+.mblToolBarButton {
+	float: left;
+	position: relative;
+	overflow: hidden;
+	cursor: pointer;
+	-webkit-tap-highlight-color: rgba(255,255,255,0);
+	.mblToolBarButton-styles;
+}
+div.mblToolBarButtonDomButton {
+	.mblToolBarButtonDomButton-styles;
+}
+.mblToolBarButtonIcon {
+	position: relative;
+	.mblToolBarButtonIcon-styles;
+}
+.mblToolBarButtonSpriteIcon {
+	position: absolute;
+}
+.mblToolBarButtonText {
+	padding: 0px 10px;
+}
diff --git a/dojox/mobile/themes/common/Tooltip.less b/dojox/mobile/themes/common/Tooltip.less
new file mode 100644
index 0000000..9c66e7d
--- /dev/null
+++ b/dojox/mobile/themes/common/Tooltip.less
@@ -0,0 +1,131 @@
+/* dojox.mobile.Tooltip */
+.mblTooltip {
+	position: absolute;
+	z-index: 2000;
+	display: block;
+	margin: 0;
+	.mblTooltip-styles;
+}
+.mblTooltipBubble {
+	overflow: visible;
+	padding: 3px;
+	.mblTooltipBubble-styles;
+}
+.mblTooltipBubble.mblTooltipAbove .mblTooltipInnerArrow {
+	.mblTooltipInnerArrow-Bubble-Above-styles;
+}
+.mblTooltipBubble.mblTooltipBelow .mblTooltipInnerArrow {
+	.mblTooltipInnerArrow-Bubble-Below-styles;
+}
+.mblTooltipBubble.mblTooltipAfter .mblTooltipInnerArrow {
+	.mblTooltipInnerArrow-Bubble-After-styles;
+}
+.mblTooltipBubble.mblTooltipBefore .mblTooltipInnerArrow {
+	.mblTooltipInnerArrow-Bubble-Before-styles;
+}
+.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;
+	.mblTooltipArrow-styles;
+}
+.mblTooltipBefore .mblTooltipArrow {
+	left: auto;
+	right: 1px;
+	top: 0;
+	bottom: auto;
+	.mblTooltipArrow-Before-styles;
+}
+.mblTooltipAfter .mblTooltipArrow {
+	left: 1px;
+	right: auto;
+	top: 0;
+	bottom: auto;
+	.mblTooltipArrow-After-styles;
+}
+.mblTooltipAbove .mblTooltipArrow {
+	top: auto;
+	bottom: 1px;
+	left: auto;
+	right: auto;
+	.mblTooltipArrow-Above-styles;
+}
+.mblTooltipBelow .mblTooltipArrow {
+	top: 1px;
+	bottom: auto;
+	left: auto;
+	right: auto;
+	.mblTooltipArrow-Below-styles;
+}
+.mblTooltipInnerArrow {
+	position: absolute;
+	width: 0;
+	height: 0;
+	line-height: 0;
+	border: 10px solid transparent;
+}
+.mblTooltipBefore .mblTooltipInnerArrow {
+	right: 0;
+	top: 0;
+	.mblTooltipInnerArrow-Before-styles;
+}
+.mblTooltipAfter .mblTooltipInnerArrow {
+	left: 0;
+	top: 0;
+	.mblTooltipInnerArrow-After-styles;
+}
+.mblTooltipAbove .mblTooltipInnerArrow {
+	bottom: 0;
+	left: 0;
+	.mblTooltipInnerArrow-Above-styles;
+}
+.mblTooltipBelow .mblTooltipInnerArrow {
+	top: 0;
+	left: 0;
+	.mblTooltipInnerArrow-Below-styles;
+}
+.mblTooltipHidden,
+.mblTooltipHidden * {
+	visibility: hidden !important;
+}
+
+// Headings and Button styles are overridden in Tooltips
+.mblTooltip .mblHeading {
+	.mblTooltip-Heading-styles;
+}
+.mblTooltip .mblHeading .mblToolBarButton {
+	.mblTooltip-Heading-ToolbarButton-styles;
+}
diff --git a/dojox/mobile/themes/common/View.less b/dojox/mobile/themes/common/View.less
new file mode 100644
index 0000000..70c43ed
--- /dev/null
+++ b/dojox/mobile/themes/common/View.less
@@ -0,0 +1,21 @@
+/* dojox.mobile.View */
+.mblView {
+	position: relative;
+	top: 0px;
+	left: 0px;
+	width: 100%;
+	.mblView-styles;
+	&.mblOut {
+	}
+	&.mblIn {
+		position: absolute;
+	}
+}
+.mblFixedHeaderBar {
+	z-index: 1;
+}
+.mblFixedBottomBar {
+	position: absolute !important;
+	width: 100%;
+	z-index: 1;
+}
diff --git a/dojox/mobile/themes/common/common.less b/dojox/mobile/themes/common/common.less
new file mode 100644
index 0000000..1c4ecf2
--- /dev/null
+++ b/dojox/mobile/themes/common/common.less
@@ -0,0 +1,24 @@
+html.mobile, .mobile body {
+	width: 100%;
+	margin: 0px;
+	padding: 0px;
+}
+.mobile body {
+	overflow-x: hidden;
+	-webkit-text-size-adjust: none;
+	.mobile-body-styles;
+}
+
+/* Button Colors */
+.mblColorBlue {
+	.mblColorBlue-styles;
+}
+
+/* Default Button Colors */
+.mblColorDefault {
+	.mblColorDefault-styles;
+}
+
+.mblColorDefaultSel {
+	.mblColorDefaultSel-styles;
+}
diff --git a/dojox/mobile/themes/common/compat/spinwheel-bar.png b/dojox/mobile/themes/common/compat/spinwheel-bar.png
new file mode 100644
index 0000000..1aeee2d
Binary files /dev/null and b/dojox/mobile/themes/common/compat/spinwheel-bar.png differ
diff --git a/dojox/mobile/themes/common/compat/spinwheel-bg.png b/dojox/mobile/themes/common/compat/spinwheel-bg.png
new file mode 100644
index 0000000..69c3768
Binary files /dev/null and b/dojox/mobile/themes/common/compat/spinwheel-bg.png differ
diff --git a/dojox/mobile/themes/common/compile.js b/dojox/mobile/themes/common/compile.js
new file mode 100644
index 0000000..159d06b
--- /dev/null
+++ b/dojox/mobile/themes/common/compile.js
@@ -0,0 +1,42 @@
+// 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/dijit/Calendar-compat.css b/dojox/mobile/themes/common/dijit/Calendar-compat.css
new file mode 100644
index 0000000..f180b2f
--- /dev/null
+++ b/dojox/mobile/themes/common/dijit/Calendar-compat.css
@@ -0,0 +1,9 @@
+.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.css b/dojox/mobile/themes/common/dijit/Calendar.css
new file mode 100644
index 0000000..4e27ae1
--- /dev/null
+++ b/dojox/mobile/themes/common/dijit/Calendar.css
@@ -0,0 +1,135 @@
+/*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/ColorPalette.css b/dojox/mobile/themes/common/dijit/ColorPalette.css
new file mode 100644
index 0000000..6184c9c
--- /dev/null
+++ b/dojox/mobile/themes/common/dijit/ColorPalette.css
@@ -0,0 +1,18 @@
+/*if you link this stylesheet directory, mobile/common/dijit/base.css must already be imported*/
+
+.dijitColorPalette {
+	border: 0 solid #B5BCC7;
+	outline: 0;
+	background: none;
+}
+.dijitColorPalette .dijitColorPaletteSwatch {
+	width: 25px;
+	height: 25px;
+	border-radius: 4px;
+	-moz-border-radius: 4px;
+}
+.dijitColorPalette .dijitPaletteImg {
+	border: 1px solid lightGrey;
+	border-radius: 4px;
+	-moz-border-radius: 4px;
+}
\ No newline at end of file
diff --git a/dojox/mobile/themes/common/dijit/ColorPicker.css b/dojox/mobile/themes/common/dijit/ColorPicker.css
new file mode 100644
index 0000000..b3989b4
--- /dev/null
+++ b/dojox/mobile/themes/common/dijit/ColorPicker.css
@@ -0,0 +1,12 @@
+/*if you link this stylesheet directory, mobile/common/dijit/base.css must already be imported*/
+
+/* import base dijit styles to override below */
+ at import url("../../../../../dojox/widget/ColorPicker/ColorPicker.css");
+
+.dojoxColorPicker {
+	padding: 8px;
+	-moz-border-radius: 4pt;
+	-webkit-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
new file mode 100644
index 0000000..53c6ac8
--- /dev/null
+++ b/dojox/mobile/themes/common/dijit/base.css
@@ -0,0 +1,15 @@
+/* base dijit stylesheets with styles to override.
+   in future releases, split these out */
+ at import url("../../../../../dijit/themes/dijit.css");
+ at import url("../../../../../dijit/icons/commonIcons.css");/*sprite containing common icons to be used by all themes*/
+ at import url("../../../../../dijit/themes/claro/Common.css");
+
+/* needed in IconContainerMulti tests
+ @import url("../../../../../dijit/themes/claro/ProgressBar.css");
+*/
+ at import url("../../../../../dijit/themes/claro/claro_rtl.css");
+
+/* mobile styling variants of dijit and dojox desktop widgets */
+ at import url("Calendar.css");
+ at import url("ColorPalette.css");
+ at import url("ColorPicker.css");
diff --git a/dojox/mobile/themes/common/dijit/compat/calendar-daylabel-bg.png b/dojox/mobile/themes/common/dijit/compat/calendar-daylabel-bg.png
new file mode 100644
index 0000000..9754278
Binary files /dev/null and b/dojox/mobile/themes/common/dijit/compat/calendar-daylabel-bg.png differ
diff --git a/dojox/mobile/themes/common/dijit/compat/calendar-month-bg.png b/dojox/mobile/themes/common/dijit/compat/calendar-month-bg.png
new file mode 100644
index 0000000..f32e5e3
Binary files /dev/null and b/dojox/mobile/themes/common/dijit/compat/calendar-month-bg.png differ
diff --git a/dojox/mobile/themes/common/dijit/compat/calendar-year-bg.png b/dojox/mobile/themes/common/dijit/compat/calendar-year-bg.png
new file mode 100644
index 0000000..6dcee1e
Binary files /dev/null and b/dojox/mobile/themes/common/dijit/compat/calendar-year-bg.png differ
diff --git a/dojox/mobile/themes/common/dijit/dijit-compat.css b/dojox/mobile/themes/common/dijit/dijit-compat.css
new file mode 100644
index 0000000..aea6c3c
--- /dev/null
+++ b/dojox/mobile/themes/common/dijit/dijit-compat.css
@@ -0,0 +1 @@
+ at import url("Calendar-compat.css");
diff --git a/dojox/mobile/themes/common/dijit/dijit.css b/dojox/mobile/themes/common/dijit/dijit.css
new file mode 100644
index 0000000..5345028
--- /dev/null
+++ b/dojox/mobile/themes/common/dijit/dijit.css
@@ -0,0 +1,4 @@
+ at import url("base.css");
+ at import url("Calendar.css");
+ at import url("ColorPalette.css");
+ at 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
new file mode 100644
index 0000000..751a376
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons-compat.css
@@ -0,0 +1,38 @@
+/* DOM Buttons */
+ at import url("domButtons/DomButtonWhitePlus-compat.css");
+ at import url("domButtons/DomButtonWhiteUpArrow-compat.css");
+ at import url("domButtons/DomButtonWhiteDownArrow-compat.css");
+ at import url("domButtons/DomButtonWhiteSearch-compat.css");
+ at import url("domButtons/DomButtonColorButtons-compat.css");
+ at import url("domButtons/DomButtonCheckboxOn-compat.css");
+ at import url("domButtons/DomButtonCheckboxOff-compat.css");
+
+ at import url("domButtons/DomButtonBlueCircleMinus-compat.css");
+ at import url("domButtons/DomButtonBlueCirclePlus-compat.css");
+ at import url("domButtons/DomButtonBlueCircleArrow-compat.css");
+
+ at import url("domButtons/DomButtonRedCircleMinus-compat.css");
+ at import url("domButtons/DomButtonRedCirclePlus-compat.css");
+ at import url("domButtons/DomButtonRedCircleArrow-compat.css");
+
+ at import url("domButtons/DomButtonGreenCircleMinus-compat.css");
+ at import url("domButtons/DomButtonGreenCirclePlus-compat.css");
+ at import url("domButtons/DomButtonGreenCircleArrow-compat.css");
+ at import url("domButtons/DomButtonBlackCircleCross-compat.css");
+
+ at import url("domButtons/DomButtonGrayRoundRect-compat.css");
+
+ at import url("domButtons/DomButtonSilverCircleDownArrow-compat.css");
+ at import url("domButtons/DomButtonSilverCircleGreenButton-compat.css");
+ at import url("domButtons/DomButtonSilverCircleGrayButton-compat.css");
+ at import url("domButtons/DomButtonSilverCircleOrangeButton-compat.css");
+ at import url("domButtons/DomButtonSilverCircleGreenPlus-compat.css");
+ at import url("domButtons/DomButtonSilverCircleRedCross-compat.css");
+
+ at import url("domButtons/DomButtonBlueBall-compat.css");
+ at import url("domButtons/DomButtonGreenBall-compat.css");
+ at import url("domButtons/DomButtonOrangeBall-compat.css");
+ at import url("domButtons/DomButtonRedBall-compat.css");
+
+ at import url("domButtons/DomButtonYellowStar-compat.css");
+ at import url("domButtons/DomButtonGrayStar-compat.css");
diff --git a/dojox/mobile/themes/common/domButtons.css b/dojox/mobile/themes/common/domButtons.css
new file mode 100644
index 0000000..9a1bf58
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons.css
@@ -0,0 +1,42 @@
+/* DOM Buttons */
+ at import url("domButtons/DomButtonWhitePlus.css");
+ at import url("domButtons/DomButtonWhiteUpArrow.css");
+ at import url("domButtons/DomButtonWhiteDownArrow.css");
+ at import url("domButtons/DomButtonWhiteSearch.css");
+ at import url("domButtons/DomButtonColorButtons.css");
+ at import url("domButtons/DomButtonCheckboxOn.css");
+ at import url("domButtons/DomButtonCheckboxOff.css");
+
+ at import url("domButtons/DomButtonBlueCircleMinus.css");
+ at import url("domButtons/DomButtonBlueCirclePlus.css");
+ at import url("domButtons/DomButtonBlueCircleArrow.css");
+
+ at import url("domButtons/DomButtonRedCircleMinus.css");
+ at import url("domButtons/DomButtonRedCirclePlus.css");
+ at import url("domButtons/DomButtonRedCircleArrow.css");
+
+ at import url("domButtons/DomButtonGreenCircleMinus.css");
+ at import url("domButtons/DomButtonGreenCirclePlus.css");
+ at import url("domButtons/DomButtonGreenCircleArrow.css");
+ at import url("domButtons/DomButtonBlackCircleCross.css");
+
+ at import url("domButtons/DomButtonGrayRoundRect.css");
+
+ at import url("domButtons/DomButtonSilverCircleDownArrow.css");
+ at import url("domButtons/DomButtonSilverCircleGreenButton.css");
+ at import url("domButtons/DomButtonSilverCircleGrayButton.css");
+ at import url("domButtons/DomButtonSilverCircleOrangeButton.css");
+ at import url("domButtons/DomButtonSilverCircleGreenPlus.css");
+ at import url("domButtons/DomButtonSilverCircleRedCross.css");
+
+ at import url("domButtons/DomButtonBlueBall.css");
+ at import url("domButtons/DomButtonGreenBall.css");
+ at import url("domButtons/DomButtonOrangeBall.css");
+ at import url("domButtons/DomButtonRedBall.css");
+
+ at import url("domButtons/DomButtonTransparent19.css");
+ at import url("domButtons/DomButtonTransparent29.css");
+ at import url("domButtons/DomButtonTransparent30.css");
+
+ at import url("domButtons/DomButtonYellowStar.css");
+ at import url("domButtons/DomButtonGrayStar.css");
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlackCircleCross-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonBlackCircleCross-compat.css
new file mode 100644
index 0000000..fa4f6ed
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlackCircleCross-compat.css
@@ -0,0 +1,8 @@
+/* === Black Circle Cross Button ==*/
+.mblDomButtonBlackCircleCross {
+	background-image: url(compat/mblDomButtonBlackCircleCross.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonBlackCircleCross > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlackCircleCross.css b/dojox/mobile/themes/common/domButtons/DomButtonBlackCircleCross.css
new file mode 100644
index 0000000..47bbab9
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlackCircleCross.css
@@ -0,0 +1,49 @@
+/* === 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;
+	-webkit-border-radius: 12px;
+	-webkit-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;
+}
+.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;
+}
+.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;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlueBall-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonBlueBall-compat.css
new file mode 100644
index 0000000..9564a12
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueBall-compat.css
@@ -0,0 +1,8 @@
+/* === Blue Ball Button ==*/
+.mblDomButtonBlueBall {
+	background-image: url(compat/mblDomButtonBlueBall.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonBlueBall > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlueBall.css b/dojox/mobile/themes/common/domButtons/DomButtonBlueBall.css
new file mode 100644
index 0000000..79eaf75
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueBall.css
@@ -0,0 +1,15 @@
+/* === Blue Ball Button ==*/
+.mblDomButtonBlueBall {
+	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));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleArrow-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleArrow-compat.css
new file mode 100644
index 0000000..22397d7
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleArrow-compat.css
@@ -0,0 +1,9 @@
+/* === Blue Circle Arrow Buttons ==*/
+.mblDomButtonBlueCircleArrow {
+	background-image: url(compat/mblDomButtonBlueCircleArrow.png);
+	background-repeat: no-repeat;
+}
+
+.mblDomButtonBlueCircleArrow > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleArrow.css b/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleArrow.css
new file mode 100644
index 0000000..2995fb1
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleArrow.css
@@ -0,0 +1,48 @@
+/* === 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;
+	-webkit-border-radius: 12px;
+	-webkit-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));
+}
+.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);
+}
+.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-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleMinus-compat.css
new file mode 100644
index 0000000..592531d
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleMinus-compat.css
@@ -0,0 +1,9 @@
+/* === Blue Circle Minus Buttons ==*/
+.mblDomButtonBlueCircleMinus {
+	background-image: url(compat/mblDomButtonBlueCircleMinus.png);
+	background-repeat: no-repeat;
+}
+
+.mblDomButtonBlueCircleMinus > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleMinus.css b/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleMinus.css
new file mode 100644
index 0000000..24d24c7
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleMinus.css
@@ -0,0 +1,37 @@
+/* === 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;
+	-webkit-border-radius: 12px;
+	-webkit-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));
+}
+.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-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonBlueCirclePlus-compat.css
new file mode 100644
index 0000000..1e36e02
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueCirclePlus-compat.css
@@ -0,0 +1,9 @@
+/* === Blue Circle Plus Buttons ==*/
+.mblDomButtonBlueCirclePlus {
+	background-image: url(compat/mblDomButtonBlueCirclePlus.png);
+	background-repeat: no-repeat;
+}
+
+.mblDomButtonBlueCirclePlus > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlueCirclePlus.css b/dojox/mobile/themes/common/domButtons/DomButtonBlueCirclePlus.css
new file mode 100644
index 0000000..af1d6ad
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueCirclePlus.css
@@ -0,0 +1,47 @@
+/* === 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;
+	-webkit-border-radius: 12px;
+	-webkit-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));
+}
+.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-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOff-compat.css
new file mode 100644
index 0000000..49c25bb
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOff-compat.css
@@ -0,0 +1,8 @@
+/* === Check Button (OFF) ==*/
+.mblDomButtonCheckboxOff {
+	background-image: url(compat/mblDomButtonCheckboxOff.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonCheckboxOff div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOff.css b/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOff.css
new file mode 100644
index 0000000..66fdd9d
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOff.css
@@ -0,0 +1,40 @@
+/* === 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));
+}
+.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);
+}
+.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);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOn-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOn-compat.css
new file mode 100644
index 0000000..933aece
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOn-compat.css
@@ -0,0 +1,8 @@
+/* === Check Button (ON) ==*/
+.mblDomButtonCheckboxOn {
+	background-image: url(compat/mblDomButtonCheckboxOn.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonCheckboxOn div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOn.css b/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOn.css
new file mode 100644
index 0000000..7c25a9e
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOn.css
@@ -0,0 +1,40 @@
+/* === 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));
+}
+.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);
+}
+.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);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonColorButtons-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonColorButtons-compat.css
new file mode 100644
index 0000000..8c77494
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonColorButtons-compat.css
@@ -0,0 +1,48 @@
+/* === Minus and Plus Buttons ==*/
+.mblDomButtonBlueMinus {
+	background-image: url(compat/mblDomButtonBlueMinus.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonBlueMinus div {
+	display: none;
+}
+
+.mblDomButtonBluePlus {
+	background-image: url(compat/mblDomButtonBluePlus.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonBluePlus div {
+	display: none;
+}
+
+.mblDomButtonDarkBlueMinus {
+	background-image: url(compat/mblDomButtonDarkBlueMinus.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonDarkBlueMinus div {
+	display: none;
+}
+
+.mblDomButtonDarkBluePlus {
+	background-image: url(compat/mblDomButtonDarkBluePlus.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonDarkBluePlus div {
+	display: none;
+}
+
+.mblDomButtonRedMinus {
+	background-image: url(compat/mblDomButtonRedMinus.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonRedMinus div {
+	display: none;
+}
+
+.mblDomButtonRedPlus {
+	background-image: url(compat/mblDomButtonRedPlus.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonRedPlus div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonColorButtons.css b/dojox/mobile/themes/common/domButtons/DomButtonColorButtons.css
new file mode 100644
index 0000000..8017cf2
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonColorButtons.css
@@ -0,0 +1,55 @@
+/* === 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;
+	-webkit-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));
+}
+.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));
+}
+.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));
+}
+.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-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonDarkBlueCheck-compat.css
new file mode 100644
index 0000000..1071a54
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonDarkBlueCheck-compat.css
@@ -0,0 +1,8 @@
+/* === Check Button ==*/
+.mblDomButtonDarkBlueCheck, .mblDomButtonCheck {
+	background-image: url(compat/mblDomButtonDarkBlueCheck.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonDarkBlueCheck div, .mblDomButtonCheck div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonDarkBlueCheck.css b/dojox/mobile/themes/common/domButtons/DomButtonDarkBlueCheck.css
new file mode 100644
index 0000000..6edc2b2
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonDarkBlueCheck.css
@@ -0,0 +1,18 @@
+/* === 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;
+	-webkit-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/DomButtonGrayArrow-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow-compat.css
new file mode 100644
index 0000000..bed275d
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow-compat.css
@@ -0,0 +1,8 @@
+/* === Arrow Button ==*/
+.mblDomButtonGrayArrow, .mblDomButtonArrow {
+	background-image: url(compat/mblDomButtonGrayArrow.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonGrayArrow div, .mblDomButtonArrow div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow.css
new file mode 100644
index 0000000..bfad471
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow.css
@@ -0,0 +1,18 @@
+/* === 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;
+	-webkit-transform: rotate(45deg);
+	border-width: 3px 3px 0px 0px;
+	border-style: solid;
+	border-color: #808080;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayRoundRect-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayRoundRect-compat.css
new file mode 100644
index 0000000..8ee029b
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayRoundRect-compat.css
@@ -0,0 +1,4 @@
+/* === Gray Round Rectangle Button ==*/
+.mblDomButtonGrayRoundRect > div {
+	-moz-border-radius: 4px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayRoundRect.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayRoundRect.css
new file mode 100644
index 0000000..5ceb481
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayRoundRect.css
@@ -0,0 +1,23 @@
+/* === 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;
+	-webkit-border-radius: 4px;
+	background-color: #949BA5;
+	text-align: center;
+}
+.mblDomButtonGrayRoundRect > div > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayStar-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayStar-compat.css
new file mode 100644
index 0000000..d92ec87
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayStar-compat.css
@@ -0,0 +1,8 @@
+/* === Gray Star ==*/
+.mblDomButtonGrayStar {
+	background-image: url(compat/mblDomButtonGrayStar.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonGrayStar > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayStar.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayStar.css
new file mode 100644
index 0000000..605de2c
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayStar.css
@@ -0,0 +1,49 @@
+/* === 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;
+	-webkit-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;
+	-webkit-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);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGreenBall-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonGreenBall-compat.css
new file mode 100644
index 0000000..b9335bd
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenBall-compat.css
@@ -0,0 +1,8 @@
+/* === Green Ball Button ==*/
+.mblDomButtonGreenBall {
+	background-image: url(compat/mblDomButtonGreenBall.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonGreenBall > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGreenBall.css b/dojox/mobile/themes/common/domButtons/DomButtonGreenBall.css
new file mode 100644
index 0000000..f7e928f
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenBall.css
@@ -0,0 +1,15 @@
+/* === Green Ball Button ==*/
+.mblDomButtonGreenBall {
+	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));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleArrow-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleArrow-compat.css
new file mode 100644
index 0000000..a62b1e5
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleArrow-compat.css
@@ -0,0 +1,9 @@
+/* === Green Circle Arrow Buttons ==*/
+.mblDomButtonGreenCircleArrow {
+	background-image: url(compat/mblDomButtonGreenCircleArrow.png);
+	background-repeat: no-repeat;
+}
+
+.mblDomButtonGreenCircleArrow > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleArrow.css b/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleArrow.css
new file mode 100644
index 0000000..53e6523
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleArrow.css
@@ -0,0 +1,48 @@
+/* === 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;
+	-webkit-border-radius: 12px;
+	-webkit-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));
+}
+.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);
+}
+.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-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleMinus-compat.css
new file mode 100644
index 0000000..a6381c4
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleMinus-compat.css
@@ -0,0 +1,9 @@
+/* === Green Circle Minus Buttons ==*/
+.mblDomButtonGreenCircleMinus {
+	background-image: url(compat/mblDomButtonGreenCircleMinus.png);
+	background-repeat: no-repeat;
+}
+
+.mblDomButtonGreenCircleMinus > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleMinus.css b/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleMinus.css
new file mode 100644
index 0000000..b406543
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleMinus.css
@@ -0,0 +1,37 @@
+/* === 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;
+	-webkit-border-radius: 12px;
+	-webkit-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));
+}
+.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-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonGreenCirclePlus-compat.css
new file mode 100755
index 0000000..053ccd9
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenCirclePlus-compat.css
@@ -0,0 +1,9 @@
+/* === Green Circle Plus Buttons ==*/
+.mblDomButtonGreenCirclePlus {
+	background-image: url(compat/mblDomButtonGreenCirclePlus.png);
+	background-repeat: no-repeat;
+}
+
+.mblDomButtonGreenCirclePlus > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGreenCirclePlus.css b/dojox/mobile/themes/common/domButtons/DomButtonGreenCirclePlus.css
new file mode 100644
index 0000000..148dfa4
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenCirclePlus.css
@@ -0,0 +1,47 @@
+/* === 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;
+	-webkit-border-radius: 12px;
+	-webkit-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));
+}
+.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-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonOrangeBall-compat.css
new file mode 100644
index 0000000..5fc2c62
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonOrangeBall-compat.css
@@ -0,0 +1,8 @@
+/* === Orange Ball Button ==*/
+.mblDomButtonOrangeBall {
+	background-image: url(compat/mblDomButtonOrangeBall.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonOrangeBall > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonOrangeBall.css b/dojox/mobile/themes/common/domButtons/DomButtonOrangeBall.css
new file mode 100644
index 0000000..32b8659
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonOrangeBall.css
@@ -0,0 +1,15 @@
+/* === Orange Ball Button ==*/
+.mblDomButtonOrangeBall {
+	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));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedBall-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonRedBall-compat.css
new file mode 100644
index 0000000..bb25172
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedBall-compat.css
@@ -0,0 +1,8 @@
+/* === Red Ball Button ==*/
+.mblDomButtonRedBall {
+	background-image: url(compat/mblDomButtonRedBall.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonRedBall > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedBall.css b/dojox/mobile/themes/common/domButtons/DomButtonRedBall.css
new file mode 100644
index 0000000..11a48cd
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedBall.css
@@ -0,0 +1,15 @@
+/* === Red Ball Button ==*/
+.mblDomButtonRedBall {
+	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));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedCircleArrow-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonRedCircleArrow-compat.css
new file mode 100644
index 0000000..b00c414
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedCircleArrow-compat.css
@@ -0,0 +1,9 @@
+/* === Red Circle Arrow Buttons ==*/
+.mblDomButtonRedCircleArrow {
+	background-image: url(compat/mblDomButtonRedCircleArrow.png);
+	background-repeat: no-repeat;
+}
+
+.mblDomButtonRedCircleArrow > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedCircleArrow.css b/dojox/mobile/themes/common/domButtons/DomButtonRedCircleArrow.css
new file mode 100644
index 0000000..c1506e7
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedCircleArrow.css
@@ -0,0 +1,48 @@
+/* === 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;
+	-webkit-border-radius: 12px;
+	-webkit-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));
+}
+.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);
+}
+.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-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonRedCircleMinus-compat.css
new file mode 100644
index 0000000..c437120
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedCircleMinus-compat.css
@@ -0,0 +1,9 @@
+/* === Red Circle Minus Buttons ==*/
+.mblDomButtonRedCircleMinus {
+	background-image: url(compat/mblDomButtonRedCircleMinus.png);
+	background-repeat: no-repeat;
+}
+
+.mblDomButtonRedCircleMinus > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedCircleMinus.css b/dojox/mobile/themes/common/domButtons/DomButtonRedCircleMinus.css
new file mode 100644
index 0000000..bd16b0c
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedCircleMinus.css
@@ -0,0 +1,37 @@
+/* === 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;
+	-webkit-border-radius: 12px;
+	-webkit-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));
+}
+.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-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonRedCirclePlus-compat.css
new file mode 100644
index 0000000..3f7a33c
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedCirclePlus-compat.css
@@ -0,0 +1,9 @@
+/* === Red Circle Plus Buttons ==*/
+.mblDomButtonRedCirclePlus {
+	background-image: url(compat/mblDomButtonRedCirclePlus.png);
+	background-repeat: no-repeat;
+}
+
+.mblDomButtonRedCirclePlus > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedCirclePlus.css b/dojox/mobile/themes/common/domButtons/DomButtonRedCirclePlus.css
new file mode 100644
index 0000000..a507bdd
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedCirclePlus.css
@@ -0,0 +1,47 @@
+/* === 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;
+	-webkit-border-radius: 12px;
+	-webkit-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));
+}
+.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/DomButtonSilverCircleDownArrow-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleDownArrow-compat.css
new file mode 100644
index 0000000..d9191e4
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleDownArrow-compat.css
@@ -0,0 +1,8 @@
+/* === Silver Circle Down Arrow ==*/
+.mblDomButtonSilverCircleDownArrow {
+	background-image: url(compat/mblDomButtonSilverCircleDownArrow.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonSilverCircleDownArrow > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleDownArrow.css b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleDownArrow.css
new file mode 100644
index 0000000..3f70ab8
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleDownArrow.css
@@ -0,0 +1,43 @@
+/* === 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;
+	-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));
+}
+.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));
+}
+.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;
+	-webkit-transform: scaleX(0.7) rotate(45deg);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGrayButton-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGrayButton-compat.css
new file mode 100644
index 0000000..dc3c7ca
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGrayButton-compat.css
@@ -0,0 +1,8 @@
+/* === Silver Circle Gray Button ==*/
+.mblDomButtonSilverCircleGrayButton {
+	background-image: url(compat/mblDomButtonSilverCircleGrayButton.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonSilverCircleGrayButton > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGrayButton.css b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGrayButton.css
new file mode 100644
index 0000000..0769c27
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGrayButton.css
@@ -0,0 +1,27 @@
+/* === 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;
+	-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));
+}
+.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));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenButton-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenButton-compat.css
new file mode 100644
index 0000000..df9e2a5
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenButton-compat.css
@@ -0,0 +1,8 @@
+/* === Silver Circle Green Button ==*/
+.mblDomButtonSilverCircleGreenButton {
+	background-image: url(compat/mblDomButtonSilverCircleGreenButton.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonSilverCircleGreenButton > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenButton.css b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenButton.css
new file mode 100644
index 0000000..2b59042
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenButton.css
@@ -0,0 +1,27 @@
+/* === 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;
+	-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));
+}
+.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));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenPlus-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenPlus-compat.css
new file mode 100644
index 0000000..d19cc2b
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenPlus-compat.css
@@ -0,0 +1,8 @@
+/* === Silver Circle Green Plus Button ==*/
+.mblDomButtonSilverCircleGreenPlus {
+	background-image: url(compat/mblDomButtonSilverCircleGreenPlus.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonSilverCircleGreenPlus > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenPlus.css b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenPlus.css
new file mode 100644
index 0000000..9808e86
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenPlus.css
@@ -0,0 +1,37 @@
+/* === 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;
+	-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));
+}
+.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-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleOrangeButton-compat.css
new file mode 100644
index 0000000..49eba72
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleOrangeButton-compat.css
@@ -0,0 +1,8 @@
+/* === Silver Circle Orange Button ==*/
+.mblDomButtonSilverCircleOrangeButton {
+	background-image: url(compat/mblDomButtonSilverCircleOrangeButton.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonSilverCircleOrangeButton > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleOrangeButton.css b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleOrangeButton.css
new file mode 100644
index 0000000..160ef4e
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleOrangeButton.css
@@ -0,0 +1,27 @@
+/* === 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;
+	-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));
+}
+.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));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleRedCross-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleRedCross-compat.css
new file mode 100644
index 0000000..68149e0
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleRedCross-compat.css
@@ -0,0 +1,8 @@
+/* === Silver Circle Red Cross Button ==*/
+.mblDomButtonSilverCircleRedCross {
+	background-image: url(compat/mblDomButtonSilverCircleRedCross.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonSilverCircleRedCross > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleRedCross.css b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleRedCross.css
new file mode 100644
index 0000000..14f4ec3
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleRedCross.css
@@ -0,0 +1,38 @@
+/* === 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;
+	-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));
+}
+.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);
+}
+.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
new file mode 100644
index 0000000..3626476
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonTransparent19.css
@@ -0,0 +1,6 @@
+/* === 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
new file mode 100644
index 0000000..3eb4891
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonTransparent29.css
@@ -0,0 +1,6 @@
+/* === 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
new file mode 100644
index 0000000..b95baf7
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonTransparent30.css
@@ -0,0 +1,6 @@
+/* === Transparent Button ==*/
+.mblDomButtonTransparent30 {
+	position: relative;
+	width: 30px;
+	height: 30px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteArrow-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteArrow-compat.css
new file mode 100644
index 0000000..39bff59
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteArrow-compat.css
@@ -0,0 +1,8 @@
+/* === Arrow Button ==*/
+.mblDomButtonWhiteArrow, .mblDomButtonArrow {
+	background-image: url(compat/mblDomButtonWhiteArrow.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonWhiteArrow div, .mblDomButtonArrow div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteArrow.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteArrow.css
new file mode 100644
index 0000000..9c9e332
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteArrow.css
@@ -0,0 +1,18 @@
+/* === 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;
+	-webkit-transform: rotate(45deg);
+	border-width: 3px 3px 0px 0px;
+	border-style: solid;
+	border-color: white;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck-compat.css
new file mode 100644
index 0000000..892a407
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck-compat.css
@@ -0,0 +1,8 @@
+/* === Check Button ==*/
+.mblDomButtonWhiteCheck, .mblDomButtonCheck {
+	background-image: url(compat/mblDomButtonWhiteCheck.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonWhiteCheck div, .mblDomButtonCheck div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck.css
new file mode 100644
index 0000000..1b51a8f
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck.css
@@ -0,0 +1,18 @@
+/* === 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;
+	-webkit-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/DomButtonWhiteDownArrow-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow-compat.css
new file mode 100644
index 0000000..6556323
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow-compat.css
@@ -0,0 +1,8 @@
+/* === Down Arrow Button ==*/
+.mblDomButtonWhiteDownArrow {
+	background-image: url(compat/mblDomButtonWhiteDownArrow.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonWhiteDownArrow div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow.css
new file mode 100644
index 0000000..33188b3
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow.css
@@ -0,0 +1,22 @@
+/* === 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;
+	-webkit-transform: scaleX(0.6) rotate(45deg);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhitePlus-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonWhitePlus-compat.css
new file mode 100644
index 0000000..24eb9be
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhitePlus-compat.css
@@ -0,0 +1,8 @@
+/* === Plus Button ==*/
+.mblDomButtonWhitePlus {
+	background-image: url(compat/mblDomButtonWhitePlus.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonWhitePlus div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhitePlus.css b/dojox/mobile/themes/common/domButtons/DomButtonWhitePlus.css
new file mode 100644
index 0000000..4de8a89
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhitePlus.css
@@ -0,0 +1,28 @@
+/* === Plus Button ==*/
+.mblDomButtonWhitePlus {
+	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 > 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/DomButtonWhiteSearch-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteSearch-compat.css
new file mode 100644
index 0000000..b3c927d
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteSearch-compat.css
@@ -0,0 +1,8 @@
+/* === Search Button ==*/
+.mblDomButtonWhiteSearch {
+	background-image: url(compat/mblDomButtonWhiteSearch.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonWhiteSearch div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteSearch.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteSearch.css
new file mode 100644
index 0000000..d8efeeb
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteSearch.css
@@ -0,0 +1,30 @@
+/* === 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;
+	-webkit-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;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow-compat.css
new file mode 100644
index 0000000..49ecb67
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow-compat.css
@@ -0,0 +1,8 @@
+/* === Up Arrow Button ==*/
+.mblDomButtonWhiteUpArrow {
+	background-image: url(compat/mblDomButtonWhiteUpArrow.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonWhiteUpArrow div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow.css
new file mode 100644
index 0000000..7c7d0da
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow.css
@@ -0,0 +1,22 @@
+/* === 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;
+	-webkit-transform: scaleX(0.6) rotate(45deg);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonYellowStar-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonYellowStar-compat.css
new file mode 100644
index 0000000..08dd2c4
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonYellowStar-compat.css
@@ -0,0 +1,8 @@
+/* === Yellow Star ==*/
+.mblDomButtonYellowStar {
+	background-image: url(compat/mblDomButtonYellowStar.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonYellowStar > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonYellowStar.css b/dojox/mobile/themes/common/domButtons/DomButtonYellowStar.css
new file mode 100644
index 0000000..96c07ce
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonYellowStar.css
@@ -0,0 +1,49 @@
+/* === 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;
+	-webkit-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;
+	-webkit-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);
+}
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonArrow.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonArrow.png
new file mode 100644
index 0000000..edc1165
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonArrow.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlackCircleCross.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlackCircleCross.png
new file mode 100644
index 0000000..2fde47f
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlackCircleCross.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlueBall.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlueBall.png
new file mode 100644
index 0000000..fc4d734
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlueBall.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlueCircleArrow.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlueCircleArrow.png
new file mode 100644
index 0000000..04526cc
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlueCircleArrow.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlueCircleMinus.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlueCircleMinus.png
new file mode 100644
index 0000000..2fa7350
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlueCircleMinus.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlueCirclePlus.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlueCirclePlus.png
new file mode 100644
index 0000000..670839f
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlueCirclePlus.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlueMinus.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlueMinus.png
new file mode 100644
index 0000000..5479d9a
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlueMinus.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBluePlus.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBluePlus.png
new file mode 100644
index 0000000..a916f9c
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBluePlus.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonCheck.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonCheck.png
new file mode 100644
index 0000000..0ba6933
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonCheck.png differ
diff --git a/dojox/mobile/themes/compat/check-off-button.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonCheckboxOff.png
old mode 100755
new mode 100644
similarity index 100%
rename from dojox/mobile/themes/compat/check-off-button.png
rename to dojox/mobile/themes/common/domButtons/compat/mblDomButtonCheckboxOff.png
diff --git a/dojox/mobile/themes/compat/check-on-button.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonCheckboxOn.png
old mode 100755
new mode 100644
similarity index 100%
rename from dojox/mobile/themes/compat/check-on-button.png
rename to dojox/mobile/themes/common/domButtons/compat/mblDomButtonCheckboxOn.png
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonDarkBlueCheck.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonDarkBlueCheck.png
new file mode 100644
index 0000000..0ba6933
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonDarkBlueCheck.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonDarkBlueMinus.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonDarkBlueMinus.png
new file mode 100644
index 0000000..1d7f918
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonDarkBlueMinus.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonDarkBluePlus.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonDarkBluePlus.png
new file mode 100644
index 0000000..465dc1e
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonDarkBluePlus.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayArrow.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayArrow.png
new file mode 100644
index 0000000..edc1165
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayArrow.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayStar.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayStar.png
new file mode 100644
index 0000000..68d62c0
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayStar.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGreenBall.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGreenBall.png
new file mode 100644
index 0000000..5a46c60
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGreenBall.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGreenCircleArrow.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGreenCircleArrow.png
new file mode 100644
index 0000000..27dbfb6
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGreenCircleArrow.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGreenCircleMinus.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGreenCircleMinus.png
new file mode 100644
index 0000000..a26de02
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGreenCircleMinus.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGreenCirclePlus.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGreenCirclePlus.png
new file mode 100644
index 0000000..3a5959e
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGreenCirclePlus.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonOrangeBall.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonOrangeBall.png
new file mode 100644
index 0000000..420428a
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonOrangeBall.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedBall.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedBall.png
new file mode 100644
index 0000000..aab2da6
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedBall.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedCircleArrow.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedCircleArrow.png
new file mode 100644
index 0000000..55b0167
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedCircleArrow.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedCircleMinus.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedCircleMinus.png
new file mode 100644
index 0000000..6171d0f
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedCircleMinus.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedCirclePlus.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedCirclePlus.png
new file mode 100644
index 0000000..f68f227
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedCirclePlus.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedMinus.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedMinus.png
new file mode 100644
index 0000000..ab25d93
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedMinus.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedPlus.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedPlus.png
new file mode 100644
index 0000000..61a76fc
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedPlus.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonSilverCircleDownArrow.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonSilverCircleDownArrow.png
new file mode 100644
index 0000000..bb9b377
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonSilverCircleDownArrow.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonSilverCircleGrayButton.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonSilverCircleGrayButton.png
new file mode 100644
index 0000000..7081f3f
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonSilverCircleGrayButton.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonSilverCircleGreenButton.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonSilverCircleGreenButton.png
new file mode 100644
index 0000000..857adac
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonSilverCircleGreenButton.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonSilverCircleGreenPlus.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonSilverCircleGreenPlus.png
new file mode 100644
index 0000000..a3ef930
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonSilverCircleGreenPlus.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonSilverCircleOrangeButton.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonSilverCircleOrangeButton.png
new file mode 100644
index 0000000..17d72e0
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonSilverCircleOrangeButton.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonSilverCircleRedCross.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonSilverCircleRedCross.png
new file mode 100644
index 0000000..7326243
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonSilverCircleRedCross.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteArrow.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteArrow.png
new file mode 100644
index 0000000..484ad60
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteArrow.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteCheck.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteCheck.png
new file mode 100644
index 0000000..a18d8b3
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteCheck.png differ
diff --git a/dojox/mobile/themes/domButtons/compat/downarrow-button.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteDownArrow.png
old mode 100755
new mode 100644
similarity index 100%
rename from dojox/mobile/themes/domButtons/compat/downarrow-button.png
rename to dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteDownArrow.png
diff --git a/dojox/mobile/themes/domButtons/compat/plus-button.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhitePlus.png
old mode 100755
new mode 100644
similarity index 100%
rename from dojox/mobile/themes/domButtons/compat/plus-button.png
rename to dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhitePlus.png
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteSearch.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteSearch.png
new file mode 100644
index 0000000..eb806d1
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteSearch.png differ
diff --git a/dojox/mobile/themes/domButtons/compat/uparrow-button.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteUpArrow.png
old mode 100755
new mode 100644
similarity index 100%
rename from dojox/mobile/themes/domButtons/compat/uparrow-button.png
rename to dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteUpArrow.png
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonYellowStar.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonYellowStar.png
new file mode 100644
index 0000000..eaa80d9
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonYellowStar.png differ
diff --git a/dojox/mobile/themes/common/transitions.css b/dojox/mobile/themes/common/transitions.css
new file mode 100644
index 0000000..e3d7a33
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions.css
@@ -0,0 +1,11 @@
+ at import url("transitions/dissolve.css");
+ at import url("transitions/cover.css");
+ at import url("transitions/reveal.css");
+ at import url("transitions/slidev.css");
+ at import url("transitions/coverv.css");
+ at import url("transitions/revealv.css");
+ at import url("transitions/swirl.css");
+ at import url("transitions/scaleOut.css");
+ at import url("transitions/scaleIn.css");
+ at import url("transitions/zoomOut.css");
+ at import url("transitions/zoomIn.css");
diff --git a/dojox/mobile/themes/common/transitions/cover.css b/dojox/mobile/themes/common/transitions/cover.css
new file mode 100644
index 0000000..5794f02
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/cover.css
@@ -0,0 +1,34 @@
+.mblCover.mblOut {
+	z-index: -100;
+	-webkit-transition-property: none;
+	-webkit-transition-duration: 0s;
+	-webkit-transform: translate3d(0%,0px,-1px) !important;
+}
+.mblCover.mblOut.mblTransition {
+	-webkit-transition-property: -webkit-transform;
+	-webkit-transition-duration: .4s;
+	-webkit-transform: translate3d(0%,0px,0px) !important;
+}
+.mblCover.mblIn {
+	z-index: 0;
+	-webkit-transition-property: none;
+	-webkit-transition-duration: 0s;
+	-webkit-transform: translate3d(100%,0px,0px) !important;
+}
+.mblCover.mblIn.mblTransition {
+	-webkit-transition-property: -webkit-transform;
+	-webkit-transition-duration: .4s;
+	-webkit-transform: translate3d(0%,0px,0px) !important;
+}
+.mblCover.mblIn.mblReverse {
+	-webkit-transform: translate3d(-100%,0px,0px) !important;
+}
+.mblCover.mblIn.mblReverse.mblTransition {
+	-webkit-transition-property: -webkit-transform;
+	-webkit-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;
+}
diff --git a/dojox/mobile/themes/common/transitions/coverv.css b/dojox/mobile/themes/common/transitions/coverv.css
new file mode 100644
index 0000000..2c80e16
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/coverv.css
@@ -0,0 +1,35 @@
+.mblCoverv.mblOut {
+	z-index: -100;
+	-webkit-transition-property: none;
+	-webkit-transition-duration: 0s;
+	-webkit-transform: translate3d(0px,0%,-1px) !important;
+}
+.mblCoverv.mblOut.mblTransition {
+	-webkit-transition-property: -webkit-transform;
+	-webkit-transition-duration: .4s;
+	-webkit-transform: translate3d(0px,0%,0px) !important;
+}
+.mblCoverv.mblIn {
+	z-index: 0;
+	-webkit-transition-property: none;
+	-webkit-transition-duration: 0s;
+	-webkit-transform: translate3d(0px,100%,0px) !important;
+}
+.mblCoverv.mblIn.mblTransition {
+	-webkit-transition-property: -webkit-transform;
+	-webkit-transition-duration: .4s;
+	-webkit-transform: translate3d(0px,0%,0px) !important;
+}
+.mblCoverv.mblIn.mblReverse {
+	-webkit-transition-property: none;
+	-webkit-transform: translate3d(0px,-100%,0px) !important;
+}
+.mblCoverv.mblIn.mblReverse.mblTransition {
+	-webkit-transition-property: -webkit-transform;
+	-webkit-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;
+}
diff --git a/dojox/mobile/themes/common/transitions/dissolve.css b/dojox/mobile/themes/common/transitions/dissolve.css
new file mode 100644
index 0000000..4cedc51
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/dissolve.css
@@ -0,0 +1,18 @@
+.mblDissolve.mblOut {
+	-webkit-animation-duration: 1s;
+	-webkit-animation-name: mblDissolveOut;
+	-webkit-animation-timing-function: cubic-bezier(.25,1,.75,0);
+}
+.mblDissolve.mblIn {
+	-webkit-animation-duration: 1s;
+	-webkit-animation-name: mblDissolveIn;
+	-webkit-animation-timing-function: cubic-bezier(.25,1,.75,0);
+}
+ at -webkit-keyframes mblDissolveOut {
+	from { opacity: 1; }
+	to { opacity: 0; }
+}
+ at -webkit-keyframes mblDissolveIn {
+	from { opacity: 0; }
+	to { opacity: 1; }
+}
\ No newline at end of file
diff --git a/dojox/mobile/themes/common/transitions/fade.css b/dojox/mobile/themes/common/transitions/fade.css
new file mode 100644
index 0000000..889231d
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/fade.css
@@ -0,0 +1,22 @@
+.mblFade.mblOut {
+	-webkit-transition-property: none;
+	-webkit-transition-duration: 0s;
+	opacity: 1;
+}
+.mblFade.mblOut.mblTransition {
+	-webkit-transition-property: opacity;
+	-webkit-transition-duration: .6s;
+	-webkit-transition-timing-function: ease-out;
+	opacity: 0;
+}
+.mblFade.mblIn {
+	-webkit-transition-property: none;
+	-webkit-transition-duration: 0s;
+	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
diff --git a/dojox/mobile/themes/common/transitions/flip.css b/dojox/mobile/themes/common/transitions/flip.css
new file mode 100644
index 0000000..0617361
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/flip.css
@@ -0,0 +1,35 @@
+.mblFlip.mblOut {
+	-webkit-transition-property: none;
+	-webkit-transition-duration: 0s;
+	opacity: 1;
+	-webkit-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;
+}
+.mblFlip.mblIn {
+	position: absolute;
+	-webkit-transition-property: none;
+	-webkit-transition-duration: 0s;
+	opacity: 0;
+	-webkit-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;
+}
+.dj_android.dj_tablet .mblFlip.mblOut.mblTransition {
+	-webkit-transition-duration: .4s;
+}
+.dj_android.dj_tablet .mblFlip.mblIn.mblTransition {
+	-webkit-transition-delay: .4s;
+	-webkit-transition-duration: .4s;
+}
diff --git a/dojox/mobile/themes/common/transitions/reveal.css b/dojox/mobile/themes/common/transitions/reveal.css
new file mode 100644
index 0000000..b711984
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/reveal.css
@@ -0,0 +1,35 @@
+.mblReveal.mblOut {
+	z-index: 0;
+	-webkit-transition-property: none;
+	-webkit-transition-duration: 0s;
+	-webkit-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;
+}
+.mblReveal.mblIn {
+	z-index: -100;
+	-webkit-transition-property: none;
+	-webkit-transition-duration: 0s;
+	-webkit-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;
+}
+.dj_android.dj_tablet .mblReveal.mblOut.mblTransition,
+.dj_android.dj_tablet .mblReveal.mblIn.mblTransition {
+	-webkit-transition-duration: .6s;
+	-webkit-transition-timing-function: linear;
+}
diff --git a/dojox/mobile/themes/common/transitions/revealv.css b/dojox/mobile/themes/common/transitions/revealv.css
new file mode 100644
index 0000000..3c74d46
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/revealv.css
@@ -0,0 +1,31 @@
+.mblRevealv.mblOut {
+	z-index: 0;
+	-webkit-transition-property: none;
+	-webkit-transition-duration: 0s;
+	-webkit-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;
+}
+.mblRevealv.mblIn {
+	z-index: -100;
+	-webkit-transition-property: none;
+	-webkit-transition-duration: 0s;
+	-webkit-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;
+}
+.dj_android.dj_tablet .mblRevealv.mblOut.mblTransition,
+.dj_android.dj_tablet .mblRevealv.mblIn.mblTransition {
+	-webkit-transition-duration: .6s;
+	-webkit-transition-timing-function: linear;
+}
diff --git a/dojox/mobile/themes/common/transitions/scaleIn.css b/dojox/mobile/themes/common/transitions/scaleIn.css
new file mode 100644
index 0000000..64e136c
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/scaleIn.css
@@ -0,0 +1,33 @@
+.mblScaleIn.mblOut {
+	z-index: -100;
+	-webkit-animation-duration: .5s;
+	-webkit-animation-name: mblScaleInOut;
+	-webkit-animation-timing-function: ease-out;
+}
+.mblScaleIn.mblIn {
+	z-index: 0;
+	-webkit-animation-duration: .5s;
+	-webkit-animation-name: mblScaleInIn;
+	-webkit-animation-timing-function: ease-out;
+}
+.dj_android .mblScaleIn.mblIn {
+	-webkit-animation-name: mblScaleInInAndroid;
+}
+ at -webkit-keyframes mblScaleInOut {
+	from { -webkit-transform: scale(1.0); }
+	to { -webkit-transform: scale(1.0); }
+}
+ at -webkit-keyframes mblScaleInIn {
+	from {
+		-webkit-transform: scale(0.0);
+		opacity: 0;
+	}
+	to {
+		-webkit-transform: scale(1.0);
+		opacity: 1;
+	}
+}
+ at -webkit-keyframes mblScaleInInAndroid {
+	from { -webkit-transform: scale(0.0); }
+	to { -webkit-transform: scale(1.0); }
+}
diff --git a/dojox/mobile/themes/common/transitions/scaleOut.css b/dojox/mobile/themes/common/transitions/scaleOut.css
new file mode 100644
index 0000000..d2f16e8
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/scaleOut.css
@@ -0,0 +1,33 @@
+.mblScaleOut.mblOut {
+	z-index: 0;
+	-webkit-animation-duration: .5s;
+	-webkit-animation-name: mblScaleOutOut;
+	-webkit-animation-timing-function: ease-in;
+}
+.dj_android .mblScaleOut.mblOut {
+	-webkit-animation-name: mblScaleOutOutAndroid;
+}
+.mblScaleOut.mblIn {
+	z-index: -100;
+	-webkit-animation-duration: .5s;
+	-webkit-animation-name: mblScaleOutIn;
+	-webkit-animation-timing-function: ease-in;
+}
+ at -webkit-keyframes mblScaleOutOut {
+	from {
+		-webkit-transform: scale(1.0);
+		opacity: 1;
+	}
+	to {
+		-webkit-transform: scale(0.0);
+		opacity: 0;
+	}
+}
+ at -webkit-keyframes mblScaleOutOutAndroid {
+	from { -webkit-transform: scale(1.0); }
+	to { -webkit-transform: scale(0.0); }
+}
+ at -webkit-keyframes mblScaleOutIn {
+	from { -webkit-transform: scale(1.0); }
+	to { -webkit-transform: scale(1.0); }
+}
diff --git a/dojox/mobile/themes/common/transitions/slide.css b/dojox/mobile/themes/common/transitions/slide.css
new file mode 100644
index 0000000..cd6b02e
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/slide.css
@@ -0,0 +1,41 @@
+.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.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;
+}
+.mblSlide.mblIn.mblReverse {
+	-webkit-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;
+}
diff --git a/dojox/mobile/themes/common/transitions/slidev.css b/dojox/mobile/themes/common/transitions/slidev.css
new file mode 100644
index 0000000..0f6a816
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/slidev.css
@@ -0,0 +1,42 @@
+.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.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;
+}
+.mblSlidev.mblIn.mblReverse {
+	-webkit-transform: translate3d(0px,-100%,0px) !important;
+}
+.mblSlidev.mblIn.mblReverse.mblTransition {
+	-webkit-transition-property: -webkit-transform;
+	-webkit-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;
+}
+
diff --git a/dojox/mobile/themes/common/transitions/swirl.css b/dojox/mobile/themes/common/transitions/swirl.css
new file mode 100644
index 0000000..529a931
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/swirl.css
@@ -0,0 +1,27 @@
+.mblSwirl.mblOut {
+	z-index: 0;
+	-webkit-animation-duration: .5s;
+	-webkit-animation-name: mblSwirlOut;
+	-webkit-animation-timing-function: ease-in;
+}
+.mblSwirl.mblIn {
+	z-index: -100;
+	-webkit-animation-duration: .5s;
+	-webkit-animation-name: mblSwirlIn;
+	-webkit-animation-timing-function: ease-in;
+}
+.mblSwirl.mblOut.mblReverse {
+	-webkit-animation-name: mblSwirlOutReverse;
+}
+ at -webkit-keyframes mblSwirlOut {
+	from { -webkit-transform: rotate(0deg) scale(1.0); }
+	to { -webkit-transform: rotate(-360deg) scale(0.0); }
+}
+ at -webkit-keyframes mblSwirlOutReverse {
+	from { -webkit-transform: rotate(0deg) scale(1.0); }
+	to { -webkit-transform: rotate(360deg) scale(0.0); }
+}
+ at -webkit-keyframes mblSwirlIn {
+	from { -webkit-transform: scale(1.0); }
+	to { -webkit-transform: scale(1.0); }
+}
diff --git a/dojox/mobile/themes/common/transitions/zoomIn.css b/dojox/mobile/themes/common/transitions/zoomIn.css
new file mode 100644
index 0000000..4ed7eca
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/zoomIn.css
@@ -0,0 +1,33 @@
+.mblZoomIn.mblOut {
+	z-index: -100;
+	-webkit-animation-duration: .5s;
+	-webkit-animation-name: mblZoomInOut;
+	-webkit-animation-timing-function: ease-out;
+}
+.mblZoomIn.mblIn {
+	z-index: 0;
+	-webkit-animation-duration: .5s;
+	-webkit-animation-name: mblZoomInIn;
+	-webkit-animation-timing-function: ease-out;
+}
+.dj_android .mblZoomIn.mblIn {
+	-webkit-animation-name: mblZoomInInAndroid;
+}
+ at -webkit-keyframes mblZoomInOut {
+	from { -webkit-transform: scale(1.0); }
+	to { -webkit-transform: scale(1.0); }
+}
+ at -webkit-keyframes mblZoomInIn {
+	from {
+		-webkit-transform: scale(0.0);
+		opacity: 0;
+	}
+	to {
+		-webkit-transform: scale(1.0);
+		opacity: 1;
+	}
+}
+ at -webkit-keyframes mblZoomInInAndroid {
+	from { -webkit-transform: scale(0.0); }
+	to { -webkit-transform: scale(1.0); }
+}
diff --git a/dojox/mobile/themes/common/transitions/zoomOut.css b/dojox/mobile/themes/common/transitions/zoomOut.css
new file mode 100644
index 0000000..8a292d4
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/zoomOut.css
@@ -0,0 +1,33 @@
+.mblZoomOut.mblOut {
+	z-index: 0;
+	-webkit-animation-duration: .5s;
+	-webkit-animation-name: mblZoomOutOut;
+	-webkit-animation-timing-function: ease-in;
+}
+.dj_android .mblZoomOut.mblOut {
+	-webkit-animation-name: mblZoomOutOutAndroid;
+}
+.mblZoomOut.mblIn {
+	z-index: -100;
+	-webkit-animation-duration: .5s;
+	-webkit-animation-name: mblZoomOutIn;
+	-webkit-animation-timing-function: ease-in;
+}
+ at -webkit-keyframes mblZoomOutOut {
+	from {
+		-webkit-transform: scale(1.0);
+		opacity: 1;
+	}
+	to {
+		-webkit-transform: scale(0.0);
+		opacity: 0;
+	}
+}
+ at -webkit-keyframes mblZoomOutOutAndroid {
+	from { -webkit-transform: scale(1.0); }
+	to { -webkit-transform: scale(0.0); }
+}
+ at -webkit-keyframes mblZoomOutIn {
+	from { -webkit-transform: scale(1.0); }
+	to { -webkit-transform: scale(1.0); }
+}
diff --git a/dojox/mobile/themes/compat/small-blue-button-bg.png b/dojox/mobile/themes/compat/small-blue-button-bg.png
deleted file mode 100755
index 8d524b7..0000000
Binary files a/dojox/mobile/themes/compat/small-blue-button-bg.png and /dev/null differ
diff --git a/dojox/mobile/themes/compat/small-darkblue-button-bg.png b/dojox/mobile/themes/compat/small-darkblue-button-bg.png
deleted file mode 100755
index f090e1d..0000000
Binary files a/dojox/mobile/themes/compat/small-darkblue-button-bg.png and /dev/null differ
diff --git a/dojox/mobile/themes/compat/small-red-button-bg.png b/dojox/mobile/themes/compat/small-red-button-bg.png
deleted file mode 100755
index f28eba3..0000000
Binary files a/dojox/mobile/themes/compat/small-red-button-bg.png and /dev/null differ
diff --git a/dojox/mobile/themes/custom/Button-compat.css b/dojox/mobile/themes/custom/Button-compat.css
new file mode 100644
index 0000000..32cc119
--- /dev/null
+++ b/dojox/mobile/themes/custom/Button-compat.css
@@ -0,0 +1,8 @@
+/* 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;
+}
diff --git a/dojox/mobile/themes/custom/Button.css b/dojox/mobile/themes/custom/Button.css
new file mode 100644
index 0000000..92d7b63
--- /dev/null
+++ b/dojox/mobile/themes/custom/Button.css
@@ -0,0 +1,48 @@
+/* dojox.mobile.Button */
+.mblButton {
+  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;
+}
+.mblButton.mblBlueButton {
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  color: #131313;
+  background-color: #0000FF;
+}
+.mblButton.mblBlueButtonSelected {
+  color: #000000;
+  border-color: #769dc0;
+  background-color: #000066;
+}
+.mblButton.mblRedButton {
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  color: #131313;
+  background-color: #FF0000;
+}
+.mblButton.mblRedButtonSelected {
+  color: #000000;
+  border-color: #769dc0;
+  background-color: #660000;
+}
+.mblButtonSelected {
+  color: #000000;
+  border-color: #769dc0;
+  background-color: #0064c2;
+}
+.mblButtonDisabled, .mblButton:disabled {
+  cursor: default;
+  color: grey;
+  border-color: grey;
+  background-color: #8fc9ff;
+}
diff --git a/dojox/mobile/themes/custom/Button.less b/dojox/mobile/themes/custom/Button.less
new file mode 100644
index 0000000..ab3a96c
--- /dev/null
+++ b/dojox/mobile/themes/custom/Button.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..a415950
--- /dev/null
+++ b/dojox/mobile/themes/custom/Carousel.css
@@ -0,0 +1,60 @@
+/* dojox.mobile.Carousel */
+.mblCarousel {
+  overflow: hidden;
+}
+.mblCarouselBox {
+  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;
+}
+.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;
+}
diff --git a/dojox/mobile/themes/custom/Carousel.less b/dojox/mobile/themes/custom/Carousel.less
new file mode 100644
index 0000000..d717397
--- /dev/null
+++ b/dojox/mobile/themes/custom/Carousel.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/Carousel.less";
diff --git a/dojox/mobile/themes/custom/CheckBox-compat.css b/dojox/mobile/themes/custom/CheckBox-compat.css
new file mode 100644
index 0000000..7545638
--- /dev/null
+++ b/dojox/mobile/themes/custom/CheckBox-compat.css
@@ -0,0 +1,26 @@
+/* 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%;
+}
diff --git a/dojox/mobile/themes/custom/CheckBox.css b/dojox/mobile/themes/custom/CheckBox.css
new file mode 100644
index 0000000..1891ba5
--- /dev/null
+++ b/dojox/mobile/themes/custom/CheckBox.css
@@ -0,0 +1,45 @@
+/* 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);
+}
+.mblCheckBoxSelected {
+  border-color: #769dc0;
+  background-color: #0064c2;
+}
+.mblCheckBoxChecked, .mblCheckBox:checked {
+  border-color: #769dc0;
+  background-color: #007ef5;
+}
+.mblCheckBoxChecked::after, .mblCheckBox:checked::after {
+  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);
+  -webkit-transform-origin: 50% 50%;
+}
+.mblCheckBoxChecked.mblCheckBoxSelected, .mblCheckBox:checked.mblCheckBoxSelected {
+  border-color: #769dc0;
+  background-color: #0064c2;
+}
+.mblCheckBoxChecked.mblCheckBoxSelected::after, .mblCheckBox:checked.mblCheckBoxSelected::after {
+  border-color: #000000;
+}
diff --git a/dojox/mobile/themes/custom/CheckBox.less b/dojox/mobile/themes/custom/CheckBox.less
new file mode 100644
index 0000000..09f93b2
--- /dev/null
+++ b/dojox/mobile/themes/custom/CheckBox.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..09c7b38
--- /dev/null
+++ b/dojox/mobile/themes/custom/ComboBox-compat.css
@@ -0,0 +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
diff --git a/dojox/mobile/themes/custom/ComboBox.css b/dojox/mobile/themes/custom/ComboBox.css
new file mode 100644
index 0000000..4247da7
--- /dev/null
+++ b/dojox/mobile/themes/custom/ComboBox.css
@@ -0,0 +1,44 @@
+/* dojox.mobile.ComboBox */
+.dijitPopup {
+  margin: 0;
+  padding: 0;
+  position: absolute;
+  border: 0;
+  background-color: transparent;
+  -webkit-box-shadow: 0px 0px 50px black;
+  -webkit-border-radius: 5px;
+}
+.mblReset {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  line-height: normal;
+  font: inherit;
+  color: inherit;
+}
+.mblComboBoxMenu {
+  overflow-y: hidden !important;
+  position: relative;
+  overflow: hidden;
+  border: 1px solid black;
+  background-color: #eff1f3;
+  -webkit-border-radius: 5px;
+}
+.mblComboBoxMenuItem {
+  white-space: nowrap;
+  text-align: left;
+  padding: .1em .2em;
+  color: #131313;
+  border-width: 1px 0 1px 0;
+  border-style: solid;
+  border-color: #eff1f3;
+}
+.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)));
+}
+.mblComboBoxMenuPreviousButton, .mblComboBoxMenuNextButton {
+  font-style: italic;
+  overflow: hidden;
+}
diff --git a/dojox/mobile/themes/custom/ComboBox.less b/dojox/mobile/themes/custom/ComboBox.less
new file mode 100644
index 0000000..ab9458c
--- /dev/null
+++ b/dojox/mobile/themes/custom/ComboBox.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/ComboBox.less";
diff --git a/dojox/mobile/themes/custom/EdgeToEdgeCategory-compat.css b/dojox/mobile/themes/custom/EdgeToEdgeCategory-compat.css
new file mode 100644
index 0000000..f62bc07
--- /dev/null
+++ b/dojox/mobile/themes/custom/EdgeToEdgeCategory-compat.css
@@ -0,0 +1,4 @@
+/* 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
new file mode 100644
index 0000000..289511f
--- /dev/null
+++ b/dojox/mobile/themes/custom/EdgeToEdgeCategory.css
@@ -0,0 +1,19 @@
+/* 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;
+  font-family: Helvetica;
+  font-weight: normal;
+  text-shadow: rgba(0, 0, 0, 0.2) 0px 1px 2px;
+  color: #000000;
+  line-height: 32px;
+}
diff --git a/dojox/mobile/themes/custom/EdgeToEdgeCategory.less b/dojox/mobile/themes/custom/EdgeToEdgeCategory.less
new file mode 100644
index 0000000..3bb63da
--- /dev/null
+++ b/dojox/mobile/themes/custom/EdgeToEdgeCategory.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..9ea0ea4
--- /dev/null
+++ b/dojox/mobile/themes/custom/EdgeToEdgeList.css
@@ -0,0 +1,12 @@
+/* dojox.mobile.EdgeToEdgeList */
+.mblEdgeToEdgeList {
+  position: relative;
+  /* IE needs this */
+
+  margin: 0;
+  padding: 0;
+  background-color: #ffffff;
+}
+.mblEdgeToEdgeList .mblListItem:last-child {
+  border-bottom-color: #b5bcc7;
+}
diff --git a/dojox/mobile/themes/custom/EdgeToEdgeList.less b/dojox/mobile/themes/custom/EdgeToEdgeList.less
new file mode 100644
index 0000000..227627c
--- /dev/null
+++ b/dojox/mobile/themes/custom/EdgeToEdgeList.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/EdgeToEdgeList.less";
diff --git a/dojox/mobile/themes/custom/Heading-compat.css b/dojox/mobile/themes/custom/Heading-compat.css
new file mode 100644
index 0000000..74befb9
--- /dev/null
+++ b/dojox/mobile/themes/custom/Heading-compat.css
@@ -0,0 +1,47 @@
+/* mbl.widget.Heading */
+.mblHeading {
+	background-image: url(compat/heading-bg.png);
+}
+.mblHeadingSpanTitle {
+	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;
+}
diff --git a/dojox/mobile/themes/custom/Heading.css b/dojox/mobile/themes/custom/Heading.css
new file mode 100644
index 0000000..86bd3b4
--- /dev/null
+++ b/dojox/mobile/themes/custom/Heading.css
@@ -0,0 +1,85 @@
+/* dojox.mobile.Heading */
+.mblHeading {
+  position: relative;
+  margin: 0px;
+  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;
+  font-family: Helvetica;
+  font-weight: normal;
+  text-shadow: rgba(0, 0, 0, 0.2) 0px 1px 2px;
+  text-align: center;
+  line-height: 42px;
+}
+.mblHeading * {
+  z-index: 2;
+}
+.mblHeadingDivTitle {
+  position: absolute;
+  width: 100%;
+  display: none;
+  left: 0px;
+  z-index: 1;
+}
+.mblHeadingCenterTitle .mblHeadingDivTitle {
+  display: block;
+}
+.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
new file mode 100644
index 0000000..cfc8580
--- /dev/null
+++ b/dojox/mobile/themes/custom/Heading.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..78efb95
--- /dev/null
+++ b/dojox/mobile/themes/custom/IconContainer-compat.css
@@ -0,0 +1,11 @@
+ at import url("../common/domButtons/DomButtonColorButtons-compat.css");
+
+/* dojox.mobile.IconItem */
+.mblIconArea div {
+	*font-size: 60px; /* IE 7 quirks */
+}
+
+/* Icon Content Heading */
+.mblIconContentHeading {
+	background-image: url(compat/heading-bg.png);
+}
diff --git a/dojox/mobile/themes/custom/IconContainer.css b/dojox/mobile/themes/custom/IconContainer.css
new file mode 100644
index 0000000..457a86a
--- /dev/null
+++ b/dojox/mobile/themes/custom/IconContainer.css
@@ -0,0 +1,101 @@
+ at import url("../common/domButtons/DomButtonColorButtons.css");
+
+ at import url("../common/IconContainer_keyframes.css");
+/* dojox.mobile.IconContainer */
+.mblIconContainer {
+  margin: 8px 0 8px 8px;
+  padding: 8px 0 8px;
+  background-color: #eff1f3;
+}
+/* dojox.mobile.IconItem */
+.mblIconItem {
+  list-style-type: none;
+  float: left;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblIconItemTerminator {
+  list-style-type: none;
+  clear: both;
+  height: 8px;
+}
+.mblIconItemSub {
+  list-style-type: none;
+  margin-left: -8px;
+  background-color: white;
+  color: #131313;
+}
+.mblIconArea {
+  height: 87px;
+  width: 73px;
+  text-align: center;
+  font-family: Helvetica;
+  font-weight: normal;
+  font-size: 14px;
+}
+.mblIconArea div {
+  position: relative;
+  height: 65px;
+  line-height: 65px;
+  text-align: center;
+}
+.mblIconArea img {
+  vertical-align: middle;
+}
+.mblIconItemSpriteIcon {
+  position: absolute;
+}
+.mblContent {
+  clear: both;
+  padding-bottom: 8px;
+}
+table.mblClose {
+  clear: both;
+  cursor: pointer;
+}
+.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);
+}
+.mblCloseContent {
+  -webkit-animation-duration: .3s;
+  -webkit-animation-timing-function: ease-in-out;
+  -webkit-animation-name: mblShrink;
+  -webkit-transform: scale(0.01);
+}
+.mblCloseContent.mblShrink0 {
+  -webkit-animation-name: mblShrink0;
+}
+.mblCloseContent.mblShrink1 {
+  -webkit-animation-name: mblShrink1;
+}
+.mblCloseContent.mblShrink2 {
+  -webkit-animation-name: mblShrink2;
+}
+.mblCloseContent.mblShrink3 {
+  -webkit-animation-name: mblShrink3;
+}
+/* Icon Content Heading */
+.mblIconContentHeading {
+  position: relative;
+  clear: both;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  margin-top: 0px;
+  padding-left: 37px;
+  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;
+  font-family: Helvetica;
+  font-weight: normal;
+  text-shadow: rgba(0, 0, 0, 0.2) 0px 1px 2px;
+  line-height: 26px;
+}
diff --git a/dojox/mobile/themes/custom/IconContainer.less b/dojox/mobile/themes/custom/IconContainer.less
new file mode 100644
index 0000000..963eae6
--- /dev/null
+++ b/dojox/mobile/themes/custom/IconContainer.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonColorButtons.css");
+ at import url("../common/IconContainer_keyframes.css");
+
+ at import "variables.less";
+ at import "../common/IconContainer.less";
diff --git a/dojox/mobile/themes/custom/ListItem-compat.css b/dojox/mobile/themes/custom/ListItem-compat.css
new file mode 100644
index 0000000..1192cdf
--- /dev/null
+++ b/dojox/mobile/themes/custom/ListItem-compat.css
@@ -0,0 +1,16 @@
+ at 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);
+}
+*html .mblListItemTextBox { /* IE6 hack */
+	height: 100%;
+}
+*html li.mblListItem.mblVariableHeight .mblListItemTextBox { /* IE6 hack */
+	height: auto;
+}
diff --git a/dojox/mobile/themes/custom/ListItem.css b/dojox/mobile/themes/custom/ListItem.css
new file mode 100644
index 0000000..8d3cb7c
--- /dev/null
+++ b/dojox/mobile/themes/custom/ListItem.css
@@ -0,0 +1,84 @@
+ at import url("../common/domButtons/DomButtonGrayArrow.css");
+
+ at import url("../common/domButtons/DomButtonDarkBlueCheck.css");
+/* dojox.mobile.ListItem */
+.mblListItem {
+  position: relative;
+  list-style-type: none;
+  vertical-align: bottom;
+  /* To avoid IE6 LI bug */
+
+  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;
+}
+.mblListItem.mblVariableHeight {
+  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: #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)));
+}
+.mblItemSelected .mblListItemAnchor {
+  color: #000000;
+}
+.mblItemSelected .mblDomButton div {
+  border-color: white;
+}
+.mblListItemTextBoxSelected {
+  background-color: #5cb0ff;
+}
+.mblListItemChecked {
+  color: #000000;
+}
+.mblListItemIcon {
+  float: left;
+  line-height: normal;
+  margin-top: 10.5px;
+  margin-right: 11px;
+}
+.mblListItemSpriteIcon {
+  position: absolute;
+  margin-top: 10.5px;
+  margin-left: 8px;
+}
+.mblListItemRightIcon, .mblListItemRightIcon2 {
+  position: relative;
+  float: right;
+  line-height: normal;
+  margin-top: 10.5px;
+}
+.mblListItemRightText {
+  position: relative;
+  float: right;
+  line-height: normal;
+  color: #131313;
+  margin: 14px 4px 0 0;
+}
+.mblListItemTextBox {
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+.mblVariableHeight .mblListItemTextBox {
+  white-space: normal;
+}
diff --git a/dojox/mobile/themes/custom/ListItem.less b/dojox/mobile/themes/custom/ListItem.less
new file mode 100644
index 0000000..f9f9d21
--- /dev/null
+++ b/dojox/mobile/themes/custom/ListItem.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonGrayArrow.css");
+ at import url("../common/domButtons/DomButtonDarkBlueCheck.css");
+
+ at import "variables.less";
+ at import "../common/ListItem.less";
diff --git a/dojox/mobile/themes/custom/Opener-compat.css b/dojox/mobile/themes/custom/Opener-compat.css
new file mode 100644
index 0000000..68cb1a8
--- /dev/null
+++ b/dojox/mobile/themes/custom/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/custom/Opener.css b/dojox/mobile/themes/custom/Opener.css
new file mode 100644
index 0000000..141c72e
--- /dev/null
+++ b/dojox/mobile/themes/custom/Opener.css
@@ -0,0 +1,3 @@
+/* dojox.mobile.Opener */
+ at import url("Overlay.css");
+ at import url("Tooltip.css");
diff --git a/dojox/mobile/themes/custom/Overlay-compat.css b/dojox/mobile/themes/custom/Overlay-compat.css
new file mode 100644
index 0000000..3bc72a3
--- /dev/null
+++ b/dojox/mobile/themes/custom/Overlay-compat.css
@@ -0,0 +1,13 @@
+/* dojox.mobile.Overlay */
+.mblOverlay {
+	_position: absolute;
+	text-align: center;
+}
+.dj_gecko .mblOverlay {
+	text-align: -moz-center;
+}
+.dj_ie9 .mblOverlay > *,
+.dj_ie8 .mblOverlay > *
+{
+	margin: 0 auto;
+}
diff --git a/dojox/mobile/themes/custom/Overlay.css b/dojox/mobile/themes/custom/Overlay.css
new file mode 100644
index 0000000..c2b7731
--- /dev/null
+++ b/dojox/mobile/themes/custom/Overlay.css
@@ -0,0 +1,18 @@
+ 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: #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)));
+}
+.mblOverlayHidden *, .mblOverlayHidden {
+  visibility: hidden !important;
+}
diff --git a/dojox/mobile/themes/custom/Overlay.less b/dojox/mobile/themes/custom/Overlay.less
new file mode 100644
index 0000000..e49ea9e
--- /dev/null
+++ b/dojox/mobile/themes/custom/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/custom/PageIndicator.css b/dojox/mobile/themes/custom/PageIndicator.css
new file mode 100644
index 0000000..a175ad6
--- /dev/null
+++ b/dojox/mobile/themes/custom/PageIndicator.css
@@ -0,0 +1,24 @@
+/* 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;
+  -webkit-border-radius: 3px;
+  -moz-border-radius: 3px;
+}
+.mblPageIndicatorDotSelected {
+  background-color: white;
+}
diff --git a/dojox/mobile/themes/custom/PageIndicator.less b/dojox/mobile/themes/custom/PageIndicator.less
new file mode 100644
index 0000000..9bb6c49
--- /dev/null
+++ b/dojox/mobile/themes/custom/PageIndicator.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/PageIndicator.less";
diff --git a/dojox/mobile/themes/custom/ProgressIndicator-compat.css b/dojox/mobile/themes/custom/ProgressIndicator-compat.css
new file mode 100644
index 0000000..4ee0810
--- /dev/null
+++ b/dojox/mobile/themes/custom/ProgressIndicator-compat.css
@@ -0,0 +1,46 @@
+/* Progress Indicator */
+.mblProg {
+	position: absolute;
+	top: 0px;
+	width: 4px;
+	font-size: 1px;
+	height: 36px;
+	overflow: hidden;
+	background-color: #C0C0C0;
+}
+.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;
+}
diff --git a/dojox/mobile/themes/custom/ProgressIndicator.css b/dojox/mobile/themes/custom/ProgressIndicator.css
new file mode 100644
index 0000000..2340637
--- /dev/null
+++ b/dojox/mobile/themes/custom/ProgressIndicator.css
@@ -0,0 +1,58 @@
+/* Progress Indicator */
+.mblProgContainer {
+  position: absolute;
+  width: 40px;
+  height: 40px;
+  top: 180px;
+  left: 50%;
+  margin: -18px 0px 0px -18px;
+}
+.mblProg {
+  position: absolute;
+  left: 2px;
+  top: 0px;
+  width: 11px;
+  font-size: 1px;
+  height: 4px;
+  overflow: hidden;
+  -webkit-transform-origin: 0 2px;
+  background-color: #C0C0C0;
+  -webkit-border-radius: 2px;
+  -moz-border-radius: 2px;
+}
+.mblProg0 {
+  -webkit-transform: translate(18px, 10px) rotate(-90.1deg);
+}
+.mblProg1 {
+  -webkit-transform: translate(22px, 11px) rotate(-60deg);
+}
+.mblProg2 {
+  -webkit-transform: translate(25px, 14px) rotate(-30deg);
+}
+.mblProg3 {
+  -webkit-transform: translate(26px, 18px) rotate(0deg);
+}
+.mblProg4 {
+  -webkit-transform: translate(25px, 22px) rotate(30deg);
+}
+.mblProg5 {
+  -webkit-transform: translate(22px, 25px) rotate(60deg);
+}
+.mblProg6 {
+  -webkit-transform: translate(18px, 26px) rotate(90.1deg);
+}
+.mblProg7 {
+  -webkit-transform: translate(14px, 25px) rotate(120deg);
+}
+.mblProg8 {
+  -webkit-transform: translate(11px, 22px) rotate(150deg);
+}
+.mblProg9 {
+  -webkit-transform: translate(10px, 18px) rotate(180deg);
+}
+.mblProg10 {
+  -webkit-transform: translate(11px, 14px) rotate(210deg);
+}
+.mblProg11 {
+  -webkit-transform: translate(14px, 11px) rotate(240deg);
+}
diff --git a/dojox/mobile/themes/custom/ProgressIndicator.less b/dojox/mobile/themes/custom/ProgressIndicator.less
new file mode 100644
index 0000000..2ab2a2d
--- /dev/null
+++ b/dojox/mobile/themes/custom/ProgressIndicator.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..9fd4ead
--- /dev/null
+++ b/dojox/mobile/themes/custom/RadioButton-compat.css
@@ -0,0 +1,26 @@
+/* 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%;
+}
diff --git a/dojox/mobile/themes/custom/RadioButton.css b/dojox/mobile/themes/custom/RadioButton.css
new file mode 100644
index 0000000..32b1ebb
--- /dev/null
+++ b/dojox/mobile/themes/custom/RadioButton.css
@@ -0,0 +1,41 @@
+/* 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);
+}
+.mblRadioButtonChecked, .mblRadioButton:checked {
+  border-color: #769dc0;
+  background-color: #007ef5;
+}
+.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);
+  -webkit-transform-origin: 50% 50%;
+}
+.mblRadioButtonChecked.mblRadioButtonSelected, .mblRadioButton:checked.mblRadioButtonSelected {
+  border-color: #769dc0;
+  background-color: #0064c2;
+}
+.mblRadioButtonChecked.mblRadioButtonSelected::after, .mblRadioButton:checked.mblRadioButtonSelected::after {
+  border-color: #000000;
+}
diff --git a/dojox/mobile/themes/custom/RadioButton.less b/dojox/mobile/themes/custom/RadioButton.less
new file mode 100644
index 0000000..0793ca6
--- /dev/null
+++ b/dojox/mobile/themes/custom/RadioButton.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..104ef49
--- /dev/null
+++ b/dojox/mobile/themes/custom/RoundRect-compat.css
@@ -0,0 +1,71 @@
+/* dojox.mobile.RoundRect */
+.mblRoundRect {
+	-moz-border-radius: 5px;
+	-o-border-radius: 5px;
+	-ms-border-radius: 5px;
+	border-radius: 5px;
+}
+/* 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;
+}
diff --git a/dojox/mobile/themes/custom/RoundRect.css b/dojox/mobile/themes/custom/RoundRect.css
new file mode 100644
index 0000000..86caed0
--- /dev/null
+++ b/dojox/mobile/themes/custom/RoundRect.css
@@ -0,0 +1,15 @@
+/* dojox.mobile.RoundRect */
+.mblRoundRect {
+  margin: 8px 8px 12px;
+  padding: 8px;
+  border: 1px solid #b5bcc7;
+  -webkit-border-radius: 5px;
+  background-color: #ffffff;
+  font-size: 18px;
+  font-family: Helvetica;
+  font-weight: normal;
+  text-shadow: none;
+}
+.mblRoundRect.mblShadow {
+  -webkit-box-shadow: 5px 5px 5px #b5bcc7;
+}
diff --git a/dojox/mobile/themes/custom/RoundRect.less b/dojox/mobile/themes/custom/RoundRect.less
new file mode 100644
index 0000000..efec816
--- /dev/null
+++ b/dojox/mobile/themes/custom/RoundRect.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..12485a8
--- /dev/null
+++ b/dojox/mobile/themes/custom/RoundRectCategory.css
@@ -0,0 +1,14 @@
+/* dojox.mobile.RoundRectCategory */
+.mblRoundRectCategory {
+  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
new file mode 100644
index 0000000..e9148cc
--- /dev/null
+++ b/dojox/mobile/themes/custom/RoundRectCategory.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/RoundRectCategory.less";
diff --git a/dojox/mobile/themes/custom/RoundRectList-compat.css b/dojox/mobile/themes/custom/RoundRectList-compat.css
new file mode 100644
index 0000000..d16eb00
--- /dev/null
+++ b/dojox/mobile/themes/custom/RoundRectList-compat.css
@@ -0,0 +1,91 @@
+/* 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;
+}
+/* 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;
+}
diff --git a/dojox/mobile/themes/custom/RoundRectList.css b/dojox/mobile/themes/custom/RoundRectList.css
new file mode 100644
index 0000000..3399016
--- /dev/null
+++ b/dojox/mobile/themes/custom/RoundRectList.css
@@ -0,0 +1,21 @@
+/* dojox.mobile.RoundRectList */
+.mblRoundRectList {
+  position: relative;
+  /* IE needs this */
+
+  margin: 8px 8px 12px;
+  padding: 0;
+  border: 1px solid #b5bcc7;
+  -webkit-border-radius: 5px;
+  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:last-child {
+  border-bottom-width: 0px;
+  -webkit-border-bottom-left-radius: 5px;
+  -webkit-border-bottom-right-radius: 5px;
+}
diff --git a/dojox/mobile/themes/custom/RoundRectList.less b/dojox/mobile/themes/custom/RoundRectList.less
new file mode 100644
index 0000000..52e1164
--- /dev/null
+++ b/dojox/mobile/themes/custom/RoundRectList.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/RoundRectList.less";
diff --git a/dojox/mobile/themes/custom/Slider-compat.css b/dojox/mobile/themes/custom/Slider-compat.css
new file mode 100644
index 0000000..936dcd6
--- /dev/null
+++ b/dojox/mobile/themes/custom/Slider-compat.css
@@ -0,0 +1,42 @@
+/* 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;
+}
+.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 */
+}
+.mblSliderV .mblSliderProgressBar {
+	background: #0D48A8;
+}
+.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;
+}
diff --git a/dojox/mobile/themes/custom/Slider.css b/dojox/mobile/themes/custom/Slider.css
new file mode 100644
index 0000000..888f96a
--- /dev/null
+++ b/dojox/mobile/themes/custom/Slider.css
@@ -0,0 +1,65 @@
+/* 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: 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;
+}
+.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 {
+  -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)));
+}
+.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;
+}
+.mblSliderTransition {
+  -webkit-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);
+}
diff --git a/dojox/mobile/themes/custom/Slider.less b/dojox/mobile/themes/custom/Slider.less
new file mode 100644
index 0000000..928972f
--- /dev/null
+++ b/dojox/mobile/themes/custom/Slider.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/Slider.less";
diff --git a/dojox/mobile/themes/custom/Switch-compat.css b/dojox/mobile/themes/custom/Switch-compat.css
new file mode 100644
index 0000000..7730ebb
--- /dev/null
+++ b/dojox/mobile/themes/custom/Switch-compat.css
@@ -0,0 +1,59 @@
+/* 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,
+.mblSwRoundShape2 .mblSwitchBg {
+	-moz-border-radius: 14px;
+	-o-border-radius: 14px;
+	-ms-border-radius: 14px;
+	border-radius: 14px;
+}
+.mblSwRoundShape1 .mblSwitchKnob,
+.mblSwRoundShape2 .mblSwitchKnob {
+	-moz-border-radius: 13px;
+	-o-border-radius: 13px;
+	-ms-border-radius: 13px;
+	border-radius: 13px;
+}
+/* Arc Shape */
+.mblSwArcShape1 .mblSwitchBg,
+.mblSwArcShape2 .mblSwitchBg {
+	-moz-border-radius: 6px/14px;
+	-o-border-radius: 6px/14px;
+	-ms-border-radius: 6px/14px;
+	border-radius: 6px/14px;
+}
+.mblSwArcShape1 .mblSwitchKnob,
+.mblSwArcShape2 .mblSwitchKnob {
+	-moz-border-radius: 5px/13px;
+	-o-border-radius: 5px/13px;
+	-ms-border-radius: 5px/13px;
+	border-radius: 5px/13px;
+}
diff --git a/dojox/mobile/themes/custom/Switch.css b/dojox/mobile/themes/custom/Switch.css
new file mode 100644
index 0000000..fa50ef9
--- /dev/null
+++ b/dojox/mobile/themes/custom/Switch.css
@@ -0,0 +1,23 @@
+ at import url("../common/Switch.css");
+/* dojox.mobile.Switch */
+.mblItemSwitch {
+  top: 12px;
+}
+.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)));
+}
+.mblSwitchBgLeft {
+  background-color: #007ef5;
+  color: #131313;
+}
+.mblSwitchBgRight {
+  background-color: #8fc9ff;
+}
+.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;
+}
diff --git a/dojox/mobile/themes/custom/Switch.less b/dojox/mobile/themes/custom/Switch.less
new file mode 100644
index 0000000..84a1146
--- /dev/null
+++ b/dojox/mobile/themes/custom/Switch.less
@@ -0,0 +1,4 @@
+ at import url("../common/Switch.css");
+
+ at import "variables.less";
+ at import "../common/Switch.less";
diff --git a/dojox/mobile/themes/custom/TabBar-compat.css b/dojox/mobile/themes/custom/TabBar-compat.css
new file mode 100644
index 0000000..fb2a1b2
--- /dev/null
+++ b/dojox/mobile/themes/custom/TabBar-compat.css
@@ -0,0 +1,55 @@
+/* dojox.mobile.TabBarButton */
+.dj_ie6 .mblTabBarButtonDiv, .dj_ie7 .mblTabBarButtonDiv {
+	left: auto;
+}
+.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;
+}
diff --git a/dojox/mobile/themes/custom/TabBar.css b/dojox/mobile/themes/custom/TabBar.css
new file mode 100644
index 0000000..3362235
--- /dev/null
+++ b/dojox/mobile/themes/custom/TabBar.css
@@ -0,0 +1,161 @@
+/* dojox.mobile.TabBar */
+.mblTabBar {
+  position: relative;
+  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-align: center;
+}
+.mblTabBarNoIcons {
+  height: 34px;
+}
+.mblTabBarNoText {
+  height: 34px;
+}
+/* dojox.mobile.TabBarButton */
+.mblTabBarButton {
+  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;
+}
+.mblTabBarButtonAnchor {
+  display: block;
+  text-decoration: none;
+}
+.mblTabBarButtonDiv {
+  position: relative;
+  margin-left: auto;
+  margin-right: auto;
+  height: 29px;
+  width: 29px;
+}
+.mblTabBarButtonIcon {
+  position: absolute;
+  left: 0;
+  top: 0;
+}
+.mblTabBarButtonSpriteIcon {
+  position: absolute;
+}
+.mblTabBarButtonTextBox {
+  color: #131313;
+  font-family: Helvetica;
+  font-size: 11px;
+  font-weight: normal;
+}
+.mblTabBarNoIcons .mblTabBarButtonDiv {
+  display: none;
+}
+.mblTabBarNoIcons .mblTabBarButtonTextBox {
+  line-height: 39px;
+  font-size: 17px;
+}
+.mblTabBarTop .mblTabButton .mblTabBarButtonDiv {
+  display: none;
+}
+.mblTabButton {
+  position: relative;
+  float: left;
+  list-style-type: none;
+  cursor: pointer;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  width: 90px;
+  height: 30px;
+  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;
+  text-align: center;
+  line-height: 30px;
+}
+.mblTabButton .mblTabBarButtonAnchor, .mblTabButton .mblTabBarButtonDiv {
+  height: 30px;
+}
+.mblTabButton:first-child {
+  -webkit-border-top-left-radius: 2px;
+  -webkit-border-bottom-left-radius: 2px;
+  border-left-width: 1px;
+}
+.mblTabButton:last-child {
+  -webkit-border-top-right-radius: 2px;
+  -webkit-border-bottom-right-radius: 2px;
+  border-right-color: #b5bcc7;
+}
+.mblTabButtonSelected .mblTabBarButtonTextBox {
+  color: #000000;
+}
+.mblTabButtonSelected.mblTabButton {
+  background-color: #0064c2;
+}
+.mblTabButtonHighlighted.mblTabButton {
+  background-color: #007ef5;
+}
+.mblTabButtonImgDiv {
+  display: none;
+}
+.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;
+  font-family: Helvetica;
+  font-weight: normal;
+  text-shadow: rgba(0, 0, 0, 0.2) 0px 1px 2px;
+  text-align: center;
+  line-height: 42px;
+}
+.mblTabPanelHeader .mblTabButton {
+  margin-top: 4px;
+}
+.mblTabPanelHeader .mblTabButton.mblTabButtonSelected {
+  background-color: #0064c2;
+}
+.mblTabPanelHeader .mblTabButtonDomButton {
+  width: 43px;
+}
+.mblTabPanelHeader .mblTabButtonDomButtonClass {
+  left: 8px;
+}
+.mblHeading .mblTabPanelHeader .mblTabButton {
+  margin-top: 5px;
+}
+.mblHeading .mblTabPanelHeader .mblTabButton:first-child {
+  -webkit-border-top-left-radius: 2px;
+  -webkit-border-bottom-left-radius: 2px;
+  border-left-width: 1px;
+}
+.mblHeading .mblTabPanelHeader .mblTabButton:last-child {
+  -webkit-border-top-right-radius: 2px;
+  -webkit-border-bottom-right-radius: 2px;
+}
diff --git a/dojox/mobile/themes/custom/TabBar.less b/dojox/mobile/themes/custom/TabBar.less
new file mode 100644
index 0000000..4875c40
--- /dev/null
+++ b/dojox/mobile/themes/custom/TabBar.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/TabBar.less";
diff --git a/dojox/mobile/themes/custom/TextArea-compat.css b/dojox/mobile/themes/custom/TextArea-compat.css
new file mode 100644
index 0000000..af7e363
--- /dev/null
+++ b/dojox/mobile/themes/custom/TextArea-compat.css
@@ -0,0 +1,7 @@
+/* dojox.mobile.TextArea */
+.mblTextArea {
+	-moz-border-radius: 5px;
+	-o-border-radius: 5px;
+	-ms-border-radius: 5px;
+	border-radius: 5px;
+}
diff --git a/dojox/mobile/themes/custom/TextArea.css b/dojox/mobile/themes/custom/TextArea.css
new file mode 100644
index 0000000..d56f3f4
--- /dev/null
+++ b/dojox/mobile/themes/custom/TextArea.css
@@ -0,0 +1,12 @@
+/* dojox.mobile.TextArea */
+.mblTextArea {
+  padding: 4px 1px;
+  border: #b5bcc7 1px inset;
+  font-family: Helvetica;
+  font-size: 14px;
+  -webkit-border-radius: 5px;
+}
+/* dojox.mobile.ExpandingTextArea */
+.mblExpandingTextArea {
+  margin: 2px;
+}
diff --git a/dojox/mobile/themes/custom/TextArea.less b/dojox/mobile/themes/custom/TextArea.less
new file mode 100644
index 0000000..c16ffe0
--- /dev/null
+++ b/dojox/mobile/themes/custom/TextArea.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..32dcf46
--- /dev/null
+++ b/dojox/mobile/themes/custom/TextBox-compat.css
@@ -0,0 +1,7 @@
+/* dojox.mobile.TextBox */
+.mblTextBox {
+	-moz-border-radius: 5px;
+	-o-border-radius: 5px;
+	-ms-border-radius: 5px;
+	border-radius: 5px;
+}
diff --git a/dojox/mobile/themes/custom/TextBox.css b/dojox/mobile/themes/custom/TextBox.css
new file mode 100644
index 0000000..65a63bf
--- /dev/null
+++ b/dojox/mobile/themes/custom/TextBox.css
@@ -0,0 +1,8 @@
+/* dojox.mobile.TextBox */
+.mblTextBox {
+  height: 30px;
+  border: #b5bcc7 1px inset;
+  font-family: Helvetica;
+  font-size: 14px;
+  -webkit-border-radius: 5px;
+}
diff --git a/dojox/mobile/themes/custom/TextBox.less b/dojox/mobile/themes/custom/TextBox.less
new file mode 100644
index 0000000..c83890a
--- /dev/null
+++ b/dojox/mobile/themes/custom/TextBox.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/TextBox.less";
diff --git a/dojox/mobile/themes/custom/ToggleButton-compat.css b/dojox/mobile/themes/custom/ToggleButton-compat.css
new file mode 100644
index 0000000..c1333a9
--- /dev/null
+++ b/dojox/mobile/themes/custom/ToggleButton-compat.css
@@ -0,0 +1,21 @@
+/* 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%;
+}
+.dj_ff3 .mblToggleButton.mblToggleButtonChecked::after {
+	-moz-transform: translate(-25px,-6px) rotate(45deg) skew(10deg);
+}
diff --git a/dojox/mobile/themes/custom/ToggleButton.css b/dojox/mobile/themes/custom/ToggleButton.css
new file mode 100644
index 0000000..9932572
--- /dev/null
+++ b/dojox/mobile/themes/custom/ToggleButton.css
@@ -0,0 +1,52 @@
+/* dojox.mobile.ToggleButton */
+.mblToggleButton {
+  position: relative;
+  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;
+}
+.mblToggleButton.mblToggleButtonSelected {
+  border-color: #769dc0;
+  background-color: #0064c2;
+}
+.mblToggleButton.mblToggleButtonChecked {
+  border-color: #769dc0;
+  background-color: #007ef5;
+}
+.mblToggleButton.mblToggleButtonChecked::after {
+  position: absolute;
+  content: "";
+  top: 7.5px;
+  left: 7px;
+  width: 5px;
+  height: 10px;
+  border-color: #000000;
+  border-width: 0.15em;
+  border-style: none solid solid none;
+  -webkit-transform: rotate(45deg) skew(10deg);
+  -webkit-transform-origin: 50% 50%;
+}
+.mblToggleButton.mblToggleButtonChecked.mblToggleButtonSelected {
+  border-color: #769dc0;
+  background-color: #0064c2;
+}
+.mblToggleButton.mblToggleButtonChecked.mblToggleButtonSelected::after {
+  border-color: #000000;
+}
+.mblToggleButton:disabled {
+  cursor: default;
+  color: grey;
+  border-color: grey;
+  background-color: #8fc9ff;
+}
diff --git a/dojox/mobile/themes/custom/ToggleButton.less b/dojox/mobile/themes/custom/ToggleButton.less
new file mode 100644
index 0000000..bdce40f
--- /dev/null
+++ b/dojox/mobile/themes/custom/ToggleButton.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/ToggleButton.less";
diff --git a/dojox/mobile/themes/custom/ToolBarButton.css b/dojox/mobile/themes/custom/ToolBarButton.css
new file mode 100644
index 0000000..c02a12e
--- /dev/null
+++ b/dojox/mobile/themes/custom/ToolBarButton.css
@@ -0,0 +1,32 @@
+/* dojox.mobile.ToolBarButton */
+.mblToolBarButton {
+  float: left;
+  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;
+  font-family: Helvetica;
+  font-weight: normal;
+  text-shadow: none;
+  color: #131313;
+  line-height: 30px;
+  text-align: center;
+}
+.mblToolBarButton.mblArrowButtonText {
+  margin: 6px 8px;
+}
+.mblToolBarButtonIcon {
+  position: relative;
+  top: 2px;
+}
+.mblToolBarButtonSpriteIcon {
+  position: absolute;
+}
+.mblToolBarButtonText {
+  padding: 0px 10px;
+}
diff --git a/dojox/mobile/themes/custom/ToolBarButton.less b/dojox/mobile/themes/custom/ToolBarButton.less
new file mode 100644
index 0000000..3b67bdc
--- /dev/null
+++ b/dojox/mobile/themes/custom/ToolBarButton.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/ToolBarButton.less";
diff --git a/dojox/mobile/themes/custom/Tooltip-compat.css b/dojox/mobile/themes/custom/Tooltip-compat.css
new file mode 100644
index 0000000..a028ad7
--- /dev/null
+++ b/dojox/mobile/themes/custom/Tooltip-compat.css
@@ -0,0 +1,47 @@
+/* dojox.mobile.Tooltip */
+.mblTooltip {
+	-moz-border-radius: 8px;
+	-o-border-radius: 8px;
+	-ms-border-radius: 8px;
+	border-radius: 8px;
+	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_ie9 .mblTooltip .mblHeading {
+	width: auto;
+}
+.mblTooltip .mblHeading .mblToolBarButton {
+	*margin: auto 6px;
+}
diff --git a/dojox/mobile/themes/custom/Tooltip.css b/dojox/mobile/themes/custom/Tooltip.css
new file mode 100644
index 0000000..2269de4
--- /dev/null
+++ b/dojox/mobile/themes/custom/Tooltip.css
@@ -0,0 +1,142 @@
+/* dojox.mobile.Tooltip */
+.mblTooltip {
+  position: absolute;
+  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;
+  opacity: .97;
+}
+.mblTooltipBubble {
+  overflow: visible;
+  padding: 3px;
+  background-color: #5cb0ff;
+  background-image: none;
+}
+.mblTooltipBubble.mblTooltipAbove .mblTooltipInnerArrow {
+  border-bottom-color: #5cb0ff;
+}
+.mblTooltipBubble.mblTooltipBelow .mblTooltipInnerArrow {
+  border-top-color: #5cb0ff;
+}
+.mblTooltipBubble.mblTooltipAfter .mblTooltipInnerArrow {
+  border-left-color: #5cb0ff;
+}
+.mblTooltipBubble.mblTooltipBefore .mblTooltipInnerArrow {
+  border-right-color: #5cb0ff;
+}
+.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: #769dc0;
+}
+.mblTooltipAfter .mblTooltipArrow {
+  left: 1px;
+  right: auto;
+  top: 0;
+  bottom: auto;
+  border-right-width: 0;
+  border-left-color: #769dc0;
+}
+.mblTooltipAbove .mblTooltipArrow {
+  top: auto;
+  bottom: 1px;
+  left: auto;
+  right: auto;
+  border-top-width: 0;
+  border-bottom-color: #769dc0;
+}
+.mblTooltipBelow .mblTooltipArrow {
+  top: 1px;
+  bottom: auto;
+  left: auto;
+  right: auto;
+  border-bottom-width: 0;
+  border-top-color: #769dc0;
+}
+.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: #deefff;
+}
+.mblTooltipAfter .mblTooltipInnerArrow {
+  left: 0;
+  top: 0;
+  border-right-width: 0;
+  border-left-color: #deefff;
+}
+.mblTooltipAbove .mblTooltipInnerArrow {
+  bottom: 0;
+  left: 0;
+  border-top-width: 0;
+  border-bottom-color: #ffffff;
+}
+.mblTooltipBelow .mblTooltipInnerArrow {
+  top: 0;
+  left: 0;
+  border-bottom-width: 0;
+  border-top-color: #aed8ff;
+}
+.mblTooltipHidden, .mblTooltipHidden * {
+  visibility: hidden !important;
+}
+.mblTooltip .mblHeading {
+  border-top: 1px solid transparent;
+  border-bottom: 1px solid transparent;
+  background-color: transparent;
+  background-image: none;
+}
diff --git a/dojox/mobile/themes/custom/Tooltip.less b/dojox/mobile/themes/custom/Tooltip.less
new file mode 100644
index 0000000..60af6d1
--- /dev/null
+++ b/dojox/mobile/themes/custom/Tooltip.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/Tooltip.less";
diff --git a/dojox/mobile/themes/custom/View.css b/dojox/mobile/themes/custom/View.css
new file mode 100644
index 0000000..1600cde
--- /dev/null
+++ b/dojox/mobile/themes/custom/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: #131313;
+}
+.mblView.mblIn {
+  position: absolute;
+}
+.mblFixedHeaderBar {
+  z-index: 1;
+}
+.mblFixedBottomBar {
+  position: absolute !important;
+  width: 100%;
+  z-index: 1;
+}
diff --git a/dojox/mobile/themes/custom/View.less b/dojox/mobile/themes/custom/View.less
new file mode 100644
index 0000000..910651f
--- /dev/null
+++ b/dojox/mobile/themes/custom/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/custom/base-compat.css b/dojox/mobile/themes/custom/base-compat.css
new file mode 100644
index 0000000..9c9c207
--- /dev/null
+++ b/dojox/mobile/themes/custom/base-compat.css
@@ -0,0 +1,8 @@
+ at import url("common-compat.css");
+ at import url("Heading-compat.css");
+ at import url("RoundRect-compat.css");
+ at import url("RoundRectList-compat.css");
+ at import url("EdgeToEdgeCategory-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/custom/base.css b/dojox/mobile/themes/custom/base.css
new file mode 100644
index 0000000..2409467
--- /dev/null
+++ b/dojox/mobile/themes/custom/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/custom/common-compat.css b/dojox/mobile/themes/custom/common-compat.css
new file mode 100644
index 0000000..963af00
--- /dev/null
+++ b/dojox/mobile/themes/custom/common-compat.css
@@ -0,0 +1,8 @@
+/* Button Colors */
+.mblColorBlue {
+  background-image: url(compat/ui-widget-bg.png);
+}
+/* Default Button Colors */
+.mblColorDefault {
+  background-image: url(compat/ui-widget-bg.png);
+}
diff --git a/dojox/mobile/themes/custom/common.css b/dojox/mobile/themes/custom/common.css
new file mode 100644
index 0000000..8c097ff
--- /dev/null
+++ b/dojox/mobile/themes/custom/common.css
@@ -0,0 +1,31 @@
+html.mobile, .mobile body {
+  width: 100%;
+  margin: 0px;
+  padding: 0px;
+}
+.mobile body {
+  overflow-x: hidden;
+  -webkit-text-size-adjust: none;
+  background-color: #eff1f3;
+  font-family: Helvetica;
+  font-size: 14px;
+}
+/* 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)));
+}
+/* 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)));
+}
+.mblColorDefault.mblDomButton {
+  background-color: #5cb0ff;
+}
+.mblColorDefaultSel {
+  background-color: #0064c2;
+}
+.mblColorDefaultSel.mblDomButton {
+  background-color: #0064c2;
+}
diff --git a/dojox/mobile/themes/custom/common.less b/dojox/mobile/themes/custom/common.less
new file mode 100644
index 0000000..4e57a5c
--- /dev/null
+++ b/dojox/mobile/themes/custom/common.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/common.less";
diff --git a/dojox/mobile/themes/custom/compat/arrow-button-head.png b/dojox/mobile/themes/custom/compat/arrow-button-head.png
new file mode 100644
index 0000000..12dad4e
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/arrow-button-head.png differ
diff --git a/dojox/mobile/themes/custom/compat/heading-bg.png b/dojox/mobile/themes/custom/compat/heading-bg.png
new file mode 100644
index 0000000..22328a7
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/heading-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
new file mode 100644
index 0000000..65510ba
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/slider-h-bar-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
new file mode 100644
index 0000000..cb787cb
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/ui-widget-bg.png differ
diff --git a/dojox/mobile/themes/custom/custom-compat.css b/dojox/mobile/themes/custom/custom-compat.css
new file mode 100644
index 0000000..f5a0140
--- /dev/null
+++ b/dojox/mobile/themes/custom/custom-compat.css
@@ -0,0 +1,18 @@
+ at import url("base-compat.css");
+
+/* common styles */
+ at import url("../common/domButtons-compat.css");
+ at import url("../common/SpinWheel-compat.css");
+
+/* widget styles */
+ 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("Opener-compat.css");
+ at import url("RadioButton-compat.css");
+ at import url("Slider-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");
diff --git a/dojox/mobile/themes/custom/custom.css b/dojox/mobile/themes/custom/custom.css
new file mode 100644
index 0000000..a50e0ce
--- /dev/null
+++ b/dojox/mobile/themes/custom/custom.css
@@ -0,0 +1,22 @@
+ at import url("base.css");
+
+/* common styles */
+ at import url("../common/domButtons.css");
+ at import url("../common/FixedSplitter.css");
+ at import url("../common/SpinWheel.css");
+ at import url("../common/transitions.css");
+
+/* widget styles */
+ at import url("Button.css");
+ at import url("Carousel.css");
+ at import url("CheckBox.css");
+ at import url("ComboBox.css");
+ at import url("IconContainer.css");
+ at import url("Opener.css");
+ at import url("PageIndicator.css");
+ at import url("RadioButton.css");
+ at import url("Slider.css");
+ at import url("TabBar.css");
+ at import url("TextArea.css");
+ at import url("TextBox.css");
+ at import url("ToggleButton.css");
diff --git a/dojox/mobile/themes/custom/images/thumb-overlay-large.png b/dojox/mobile/themes/custom/images/thumb-overlay-large.png
new file mode 100644
index 0000000..dfac370
Binary files /dev/null and b/dojox/mobile/themes/custom/images/thumb-overlay-large.png differ
diff --git a/dojox/mobile/themes/custom/images/thumb-overlay-small.png b/dojox/mobile/themes/custom/images/thumb-overlay-small.png
new file mode 100644
index 0000000..b6836d9
Binary files /dev/null and b/dojox/mobile/themes/custom/images/thumb-overlay-small.png differ
diff --git a/dojox/mobile/themes/custom/images/thumb-overlay.png b/dojox/mobile/themes/custom/images/thumb-overlay.png
new file mode 100644
index 0000000..b16efec
Binary files /dev/null and b/dojox/mobile/themes/custom/images/thumb-overlay.png differ
diff --git a/dojox/mobile/themes/custom/variables.less b/dojox/mobile/themes/custom/variables.less
new file mode 100644
index 0000000..9c22efc
--- /dev/null
+++ b/dojox/mobile/themes/custom/variables.less
@@ -0,0 +1,921 @@
+//----------------------------------------------------------------
+// 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
+//----------------------------------------------------------------
+
+//----------------------------------------------------------------
+// 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;
+}
+// .mblView
+.mblView-styles () {
+	color: @theme-default-color;
+}
+// .mblColorBlue
+.mblColorBlue-styles () {
+	background-color: #366EDF;
+	._background-image-gradient-mask-ui-widget;
+}
+// .mblColorDefault
+.mblColorDefault-styles () {
+	background-color: @theme-ui-widget-background-color;
+	._background-image-gradient-mask-ui-widget;
+	&.mblDomButton {
+		background-color: @theme-dom-button-background-color;
+	}
+}
+// .mblColorDefaultSel
+.mblColorDefaultSel-styles () {
+	background-color: @theme-ui-widget-selected-background-color;
+	&.mblDomButton {
+		background-color: @theme-ui-widget-selected-background-color;
+	}
+}
+
+//----------------------------------------------------------------
+// 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 () {
+}
+
+//----------------------------------------------------------------
+// ToolBarButton.less
+//----------------------------------------------------------------
+.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;
+}
+.mblRoundRectShadowBox-styles () {
+	-webkit-box-shadow: @theme-round-rect-box-shadow;
+}
+
+//----------------------------------------------------------------
+// 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;
+}
+
+//----------------------------------------------------------------
+// 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;
+}
+
+//----------------------------------------------------------------
+// EdgeToEdgeList.less
+//----------------------------------------------------------------
+.mblEdgeToEdgeList-styles () {
+	margin: 0;
+	padding: 0;
+	background-color: @theme-list-item-background-color;
+}
+.mblEdgeToEdgeList-LastListItem-styles () {
+	border-bottom-color: @theme-list-item-border-color;
+}
+
+//----------------------------------------------------------------
+// ListItem.less
+//----------------------------------------------------------------
+.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;
+}
+.mblListItem-mblListItemAnchor-styles () {
+	background-position: 9px 7px;
+	text-decoration: none;
+	padding-right: 7px;
+}
+.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;
+}
+.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;
+}
+.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 () {
+}
+.mblListItemSubText-styles () {
+}
+
+//----------------------------------------------------------------
+// Switch.less
+//----------------------------------------------------------------
+.mblItemSwitch-styles () {
+	top: (@theme-list-item-height - @mbl-switch-height + 1) * 0.5;
+}
+.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;
+}
+.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;
+}
+
+//----------------------------------------------------------------
+// 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;
+}
+.mblButton-mblBlueButton-styles () {
+	color: @theme-ui-widget-color;
+	background-color: #0000FF;
+}
+.mblButton-mblBlueButtonSelected-styles () {
+	color: @theme-ui-widget-selected-color;
+	border-color: @theme-ui-widget-selected-border-color;
+	background-color: darken(#0000FF, 30%);
+}
+.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;
+}
+
+//----------------------------------------------------------------
+// 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;
+}
+.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;
+}
+.mblCheckBoxChecked-mblCheckBoxSelected-after-styles () {
+	border-color: @theme-ui-widget-selected-color;
+}
+
+//----------------------------------------------------------------
+// ComboBox.less
+//----------------------------------------------------------------
+.dijitPopup-styles () {
+	-webkit-box-shadow: 0px 0px 50px black;
+	-webkit-border-radius: @theme-default-border-radius;
+}
+.mblComboBoxMenu-styles () {
+	border: 1px solid black;
+	background-color: @theme-default-background-color;
+	-webkit-border-radius: @theme-default-border-radius;
+}
+.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;
+}
+.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;
+}
+
+//----------------------------------------------------------------
+// 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;
+}
+.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;
+}
+
+//----------------------------------------------------------------
+// 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;
+}
+.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;
+}
+.mblRadioButtonChecked-Selected-after-styles () {
+	border-color: @theme-ui-widget-selected-color;
+}
+
+//----------------------------------------------------------------
+// Slider.less
+//----------------------------------------------------------------
+.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;
+}
+.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;
+}
+
+//----------------------------------------------------------------
+// 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;
+}
+.mblTabPanelHeader-TabButton-styles () {
+	margin-top: (@theme-heading-height - @theme-ui-widget-height - 2) * 0.5;
+}
+.mblTabPanelHeader-TabButtonSelected-styles () {
+	background-color: @theme-ui-widget-selected-background-color;
+}
+.mblTabPanelHeader-TabButtonDomButton-styles () {
+	width: 43px;
+}
+.mblTabPanelHeader-TabButtonDomButtonClass-styles () {
+	left: 8px;
+}
+.mblTabPanelHeader-DomButton-styles () {
+}
+.mblTabPanelHeader-inHeading-styles () {
+}
+.mblTabPanelHeader-TabButton-inHeading-styles () {
+	margin-top: (@theme-heading-height - @theme-ui-widget-height) * 0.5;
+}
+.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;
+}
+.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;
+}
+.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;
+}
+
+//----------------------------------------------------------------
+// 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;
+}
+
+//----------------------------------------------------------------
+// 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;
+}
+.mblToggleButtonSelected-styles () {
+	border-color: @theme-ui-widget-selected-border-color;
+	background-color: @theme-ui-widget-selected-background-color;
+}
+.mblToggleButtonChecked-styles () {
+	border-color: @theme-ui-widget-selected-border-color;
+	background-color: @theme-ui-widget-checked-background-color;
+}
+.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%;
+}
+.mblToggleButtonCheckedSelected-styles () {
+	border-color: @theme-ui-widget-selected-border-color;
+	background-color: @theme-ui-widget-selected-background-color;
+}
+.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;
+}
+
+// Overlay.less
+.mblOverlay-styles () {
+	background-color: @theme-default-background-color;
+	._background-image-gradient-mask-ui-widget;
+}
+
+// Tooltip.less
+.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;
+}
+.mblTooltipBubble-styles () {
+	background-color: @theme-heading-background-color;
+	background-image: none;
+}
+.mblTooltipInnerArrow-Bubble-Above-styles () {
+	border-bottom-color: @theme-heading-background-color;
+}
+.mblTooltipInnerArrow-Bubble-Below-styles () {
+	border-top-color: @theme-heading-background-color;
+}
+.mblTooltipInnerArrow-Bubble-After-styles () {
+	border-left-color: @theme-heading-background-color;
+}
+.mblTooltipInnerArrow-Bubble-Before-styles () {
+	border-right-color: @theme-heading-background-color;
+}
+.mblTooltipArrow-styles () {
+	border: 11px solid transparent;
+}
+.mblTooltipArrow-Before-styles () {
+	border-left-width: 0;
+	border-right-color: @theme-heading-border-color;
+}
+.mblTooltipArrow-After-styles () {
+	border-right-width: 0;
+	border-left-color: @theme-heading-border-color;
+}
+.mblTooltipArrow-Above-styles () {
+	border-top-width: 0;
+	border-bottom-color: @theme-heading-border-color;
+}
+.mblTooltipArrow-Below-styles () {
+	border-bottom-width: 0;
+	border-top-color: @theme-heading-border-color;
+}
+.mblTooltipInnerArrow-Before-styles () {
+	border-left-width: 0;
+	border-right-color: @theme-heading-background-color * 0.2 + #ffffff * 0.8;
+}
+.mblTooltipInnerArrow-After-styles () {
+	border-right-width: 0;
+	border-left-color: @theme-heading-background-color * 0.2 + #ffffff * 0.8;
+}
+.mblTooltipInnerArrow-Above-styles () {
+	border-top-width: 0;
+	border-bottom-color: @theme-heading-background-color * 0.0 + #ffffff * 1.0;
+}
+.mblTooltipInnerArrow-Below-styles () {
+	border-bottom-width: 0;
+	border-top-color: @theme-heading-background-color * 0.5 + #ffffff * 0.5;
+}
+.mblTooltip-Heading-styles () {
+	border-top: 1px solid transparent;
+	border-bottom: 1px solid transparent;
+	background-color: transparent;
+	background-image: none;
+}
+.mblTooltip-Heading-ToolbarButton-styles () {
+}
diff --git a/dojox/mobile/themes/domButtons-compat.css b/dojox/mobile/themes/domButtons-compat.css
deleted file mode 100644
index 7eb7954..0000000
--- a/dojox/mobile/themes/domButtons-compat.css
+++ /dev/null
@@ -1,6 +0,0 @@
-/* DOM Buttons */
- at import url("domButtons/Common-compat.css");
- at import url("domButtons/DomButtonPlus-compat.css");
- at import url("domButtons/DomButtonUpArrow-compat.css");
- at import url("domButtons/DomButtonDownArrow-compat.css");
- at import url("domButtons/DomButtonSearch-compat.css");
diff --git a/dojox/mobile/themes/domButtons.css b/dojox/mobile/themes/domButtons.css
deleted file mode 100644
index 54469e6..0000000
--- a/dojox/mobile/themes/domButtons.css
+++ /dev/null
@@ -1,6 +0,0 @@
-/* DOM Buttons */
- at import url("domButtons/Common.css");
- at import url("domButtons/DomButtonPlus.css");
- at import url("domButtons/DomButtonUpArrow.css");
- at import url("domButtons/DomButtonDownArrow.css");
- at import url("domButtons/DomButtonSearch.css");
diff --git a/dojox/mobile/themes/domButtons/Common-compat.css b/dojox/mobile/themes/domButtons/Common-compat.css
deleted file mode 100644
index 28d561c..0000000
--- a/dojox/mobile/themes/domButtons/Common-compat.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.mblTabPanelHeader .mblDomButton {
-	background-position: 8px;
-}
diff --git a/dojox/mobile/themes/domButtons/Common.css b/dojox/mobile/themes/domButtons/Common.css
deleted file mode 100644
index 623b7ff..0000000
--- a/dojox/mobile/themes/domButtons/Common.css
+++ /dev/null
@@ -1,6 +0,0 @@
-.mblDomButton {
-	width: 11px;
-}
-.mblTabPanelHeader .mblDomButton {
-	width: 43px;
-}
diff --git a/dojox/mobile/themes/domButtons/DomButtonDownArrow-compat.css b/dojox/mobile/themes/domButtons/DomButtonDownArrow-compat.css
deleted file mode 100644
index dfa3bb6..0000000
--- a/dojox/mobile/themes/domButtons/DomButtonDownArrow-compat.css
+++ /dev/null
@@ -1,8 +0,0 @@
-/* === Down Arrow Button ==*/
-.mblDomButtonDownArrow_2 {
-	background-image: url(compat/downarrow-button.png);
-	background-repeat: no-repeat;
-}
-.mblDomButtonDownArrow_2 DIV {
-	display: none;
-}
diff --git a/dojox/mobile/themes/domButtons/DomButtonDownArrow.css b/dojox/mobile/themes/domButtons/DomButtonDownArrow.css
deleted file mode 100644
index 0dd359d..0000000
--- a/dojox/mobile/themes/domButtons/DomButtonDownArrow.css
+++ /dev/null
@@ -1,21 +0,0 @@
-/* === Down Arrow Button ==*/
-.mblDomButtonDownArrow_2 DIV {
-	position: absolute;
-	left: 0px;
-	clip: rect(7px 50px 40px 0px);
-}
-.mblDomButtonDownArrow_2 DIV DIV {
-	top: -10px;
-	left: 4px;
-	width: 25px;
-	height: 25px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
-	border-top: 1px solid #4A5A71;
-	-webkit-transform: scaleX(0.6) rotate(45deg);
-	-moz-transform: scaleX(0.6) rotate(45deg);
-}
-.mblTabPanelHeader .mblDomButtonDownArrow_2 DIV DIV {
-	left: 11px;
-}
diff --git a/dojox/mobile/themes/domButtons/DomButtonPlus-compat.css b/dojox/mobile/themes/domButtons/DomButtonPlus-compat.css
deleted file mode 100644
index dc9c61c..0000000
--- a/dojox/mobile/themes/domButtons/DomButtonPlus-compat.css
+++ /dev/null
@@ -1,8 +0,0 @@
-/* === Plus Button ==*/
-.mblDomButtonPlus_2 {
-	background-image: url(compat/plus-button.png);
-	background-repeat: no-repeat;
-}
-.mblDomButtonPlus_2 DIV {
-	display: none;
-}
diff --git a/dojox/mobile/themes/domButtons/DomButtonPlus.css b/dojox/mobile/themes/domButtons/DomButtonPlus.css
deleted file mode 100644
index 34e79a6..0000000
--- a/dojox/mobile/themes/domButtons/DomButtonPlus.css
+++ /dev/null
@@ -1,18 +0,0 @@
-/* === Plus Button ==*/
-.mblDomButtonPlus_2 DIV { /* horiz line */
-	position: absolute;
-	top: 11px;
-	left: 9px;
-	width: 13px;
-	height: 3px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
-	border-top: 1px solid #4A5A71;
-}
-.mblDomButtonPlus_2 DIV DIV { /* vert line */
-	top: -6px;
-	left: 5px;
-	width: 3px;
-	height: 13px;
-}
diff --git a/dojox/mobile/themes/domButtons/DomButtonSearch-compat.css b/dojox/mobile/themes/domButtons/DomButtonSearch-compat.css
deleted file mode 100644
index f0f51dc..0000000
--- a/dojox/mobile/themes/domButtons/DomButtonSearch-compat.css
+++ /dev/null
@@ -1,12 +0,0 @@
-/* === Search Button ==*/
-.mblDomButtonSearch_2 {
-	background-image: url(compat/search-button.png);
-	background-repeat: no-repeat;
-}
-.mblDomButtonSearch_2 DIV {
-	display: none;
-}
-
-.dj_ie6 .mblDomButtonSearch_2 {
-	background-image: url(compat/search-button.gif);
-}
diff --git a/dojox/mobile/themes/domButtons/DomButtonSearch.css b/dojox/mobile/themes/domButtons/DomButtonSearch.css
deleted file mode 100644
index 477f569..0000000
--- a/dojox/mobile/themes/domButtons/DomButtonSearch.css
+++ /dev/null
@@ -1,33 +0,0 @@
-/* === Search Button ==*/
-.mblDomButtonSearch_2 DIV {
-	position: absolute;
-	top: 5px;
-	left: 6px;
-	width: 10px;
-	height: 10px;
-	margin: 0px;
-	font-size: 1px;
-	border: 2px solid white;
-	-webkit-border-radius: 6px;
-	-moz-border-radius: 6px;
-}
-.mblDomButtonSearch_2 DIV DIV {
-	top: 10px;
-	left: 7px;
-	width: 8px;
-	height: 3px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
-	border: none;
-	-webkit-transform: rotate(45deg);
-	-moz-transform: rotate(45deg);
-	-webkit-border-radius: 0px;
-	-moz-border-radius: 0px;
-}
-.mblTabPanelHeader .mblDomButtonSearch_2 DIV {
-	left: 11px;
-}
-.mblTabPanelHeader .mblDomButtonSearch_2 DIV DIV {
-	left: 7px;
-}
diff --git a/dojox/mobile/themes/domButtons/DomButtonUpArrow-compat.css b/dojox/mobile/themes/domButtons/DomButtonUpArrow-compat.css
deleted file mode 100644
index 6cc860a..0000000
--- a/dojox/mobile/themes/domButtons/DomButtonUpArrow-compat.css
+++ /dev/null
@@ -1,8 +0,0 @@
-/* === Up Arrow Button ==*/
-.mblDomButtonUpArrow_2 {
-	background-image: url(compat/uparrow-button.png);
-	background-repeat: no-repeat;
-}
-.mblDomButtonUpArrow_2 DIV {
-	display: none;
-}
diff --git a/dojox/mobile/themes/domButtons/DomButtonUpArrow.css b/dojox/mobile/themes/domButtons/DomButtonUpArrow.css
deleted file mode 100644
index b6298e4..0000000
--- a/dojox/mobile/themes/domButtons/DomButtonUpArrow.css
+++ /dev/null
@@ -1,21 +0,0 @@
-/* === Up Arrow Button ==*/
-.mblDomButtonUpArrow_2 DIV {
-	position: absolute;
-	left: 0px;
-	clip: rect(0px 30px 20px 0px);
-}
-.mblDomButtonUpArrow_2 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);
-	-moz-transform: scaleX(0.6) rotate(45deg);
-}
-.mblTabPanelHeader .mblDomButtonUpArrow_2 DIV DIV {
-	left: 11px;
-}
diff --git a/dojox/mobile/themes/domButtons/compat/search-button.gif b/dojox/mobile/themes/domButtons/compat/search-button.gif
deleted file mode 100755
index 7087ef6..0000000
Binary files a/dojox/mobile/themes/domButtons/compat/search-button.gif and /dev/null differ
diff --git a/dojox/mobile/themes/domButtons/compat/search-button.png b/dojox/mobile/themes/domButtons/compat/search-button.png
deleted file mode 100755
index ca09ddb..0000000
Binary files a/dojox/mobile/themes/domButtons/compat/search-button.png and /dev/null differ
diff --git a/dojox/mobile/themes/iphone/Button-compat.css b/dojox/mobile/themes/iphone/Button-compat.css
new file mode 100644
index 0000000..dccf89b
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Button-compat.css
@@ -0,0 +1,33 @@
+/* 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;
+}
+.mblButtonSelected {
+	background-color: #c0c0c0;
+	background-image: url(compat/button-sel-bg.png);
+}
+.mblButtonDisabled {
+	background-image: none;
+}
+.mblBlueButton {
+	background-color: #2261dd;
+	background-image: url(compat/blue-button-bg.png);
+}
+.mblBlueButtonSelected {
+	background-color: #4a6c9b;
+	background-image: url(compat/blue-button-sel-bg.png);
+}
+.mblRedButton {
+	background-color: #ee4115;
+	background-image: url(compat/red-button-bg.png);
+}
+.mblRedButtonSelected {
+	background-color: #9b6c4a;
+	background-image: url(compat/red-button-sel-bg.png);
+}
diff --git a/dojox/mobile/themes/iphone/Button.css b/dojox/mobile/themes/iphone/Button.css
new file mode 100644
index 0000000..9ed5a9d
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Button.css
@@ -0,0 +1,45 @@
+/* dojox.mobile.Button */
+.mblButton {
+  cursor: pointer;
+  outline: none;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  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));
+  color: black;
+  font-family: Helvetica;
+  font-size: 13px;
+  line-height: 29px;
+}
+.mblButton.mblBlueButton {
+  -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;
+}
+.mblButton.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;
+}
+.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;
+}
+.mblButton.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;
+}
diff --git a/dojox/mobile/themes/iphone/Button.less b/dojox/mobile/themes/iphone/Button.less
new file mode 100644
index 0000000..ab3a96c
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Button.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..a415950
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Carousel.css
@@ -0,0 +1,60 @@
+/* dojox.mobile.Carousel */
+.mblCarousel {
+  overflow: hidden;
+}
+.mblCarouselBox {
+  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;
+}
+.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;
+}
diff --git a/dojox/mobile/themes/iphone/Carousel.less b/dojox/mobile/themes/iphone/Carousel.less
new file mode 100644
index 0000000..d717397
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Carousel.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/Carousel.less";
diff --git a/dojox/mobile/themes/iphone/CheckBox-compat.css b/dojox/mobile/themes/iphone/CheckBox-compat.css
new file mode 100644
index 0000000..99aade2
--- /dev/null
+++ b/dojox/mobile/themes/iphone/CheckBox-compat.css
@@ -0,0 +1,36 @@
+/* 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);
+}
+.mblCheckBoxSelected {
+	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);
+}
diff --git a/dojox/mobile/themes/iphone/CheckBox.css b/dojox/mobile/themes/iphone/CheckBox.css
new file mode 100644
index 0000000..eb9069c
--- /dev/null
+++ b/dojox/mobile/themes/iphone/CheckBox.css
@@ -0,0 +1,44 @@
+/* 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;
+  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 {
+  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, .mblCheckBox:checked {
+  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));
+}
+.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);
+  -webkit-transform-origin: 50% 50%;
+}
+.mblCheckBoxChecked.mblCheckBoxSelected, .mblCheckBox:checked.mblCheckBoxSelected {
+  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, .mblCheckBox:checked.mblCheckBoxSelected::after {
+  border-color: #9CACC0;
+}
diff --git a/dojox/mobile/themes/iphone/CheckBox.less b/dojox/mobile/themes/iphone/CheckBox.less
new file mode 100644
index 0000000..09f93b2
--- /dev/null
+++ b/dojox/mobile/themes/iphone/CheckBox.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..09c7b38
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ComboBox-compat.css
@@ -0,0 +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
diff --git a/dojox/mobile/themes/iphone/ComboBox.css b/dojox/mobile/themes/iphone/ComboBox.css
new file mode 100644
index 0000000..259629d
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ComboBox.css
@@ -0,0 +1,44 @@
+/* dojox.mobile.ComboBox */
+.dijitPopup {
+  margin: 0;
+  padding: 0;
+  position: absolute;
+  border: 0;
+  background-color: transparent;
+  -webkit-box-shadow: 0px 0px 50px black;
+  -webkit-border-radius: 0px;
+}
+.mblReset {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  line-height: normal;
+  font: inherit;
+  color: inherit;
+}
+.mblComboBoxMenu {
+  overflow-y: hidden !important;
+  position: relative;
+  overflow: hidden;
+  border: 1px solid black;
+  -webkit-border-radius: 0px;
+  background-color: white;
+}
+.mblComboBoxMenuItem {
+  white-space: nowrap;
+  padding: .1em .2em;
+  border-width: 1px 0 1px 0;
+  border-style: solid;
+  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));
+  color: white;
+}
+.mblComboBoxMenuPreviousButton, .mblComboBoxMenuNextButton {
+  font-style: italic;
+  overflow: hidden;
+}
diff --git a/dojox/mobile/themes/iphone/ComboBox.less b/dojox/mobile/themes/iphone/ComboBox.less
new file mode 100644
index 0000000..ab9458c
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ComboBox.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/ComboBox.less";
diff --git a/dojox/mobile/themes/iphone/EdgeToEdgeCategory-compat.css b/dojox/mobile/themes/iphone/EdgeToEdgeCategory-compat.css
new file mode 100644
index 0000000..f6d50e2
--- /dev/null
+++ b/dojox/mobile/themes/iphone/EdgeToEdgeCategory-compat.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.EdgeToEdgeCategory */
+.mblEdgeToEdgeCategory {
+	background-image: url(compat/edge-categ-bg.png);
+}
diff --git a/dojox/mobile/themes/iphone/EdgeToEdgeCategory.css b/dojox/mobile/themes/iphone/EdgeToEdgeCategory.css
new file mode 100644
index 0000000..fc21dd8
--- /dev/null
+++ b/dojox/mobile/themes/iphone/EdgeToEdgeCategory.css
@@ -0,0 +1,19 @@
+/* dojox.mobile.EdgeToEdgeCategory */
+.mblEdgeToEdgeCategory {
+  position: relative;
+  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;
+  color: white;
+  line-height: 22px;
+  text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0px;
+}
diff --git a/dojox/mobile/themes/iphone/EdgeToEdgeCategory.less b/dojox/mobile/themes/iphone/EdgeToEdgeCategory.less
new file mode 100644
index 0000000..3bb63da
--- /dev/null
+++ b/dojox/mobile/themes/iphone/EdgeToEdgeCategory.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..9864276
--- /dev/null
+++ b/dojox/mobile/themes/iphone/EdgeToEdgeList.css
@@ -0,0 +1,12 @@
+/* dojox.mobile.EdgeToEdgeList */
+.mblEdgeToEdgeList {
+  position: relative;
+  /* IE needs this */
+
+  margin: 0px;
+  padding: 0px;
+  background-color: white;
+}
+.mblEdgeToEdgeList .mblListItem:last-child {
+  border-bottom-color: #707C84;
+}
diff --git a/dojox/mobile/themes/iphone/EdgeToEdgeList.less b/dojox/mobile/themes/iphone/EdgeToEdgeList.less
new file mode 100644
index 0000000..227627c
--- /dev/null
+++ b/dojox/mobile/themes/iphone/EdgeToEdgeList.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/EdgeToEdgeList.less";
diff --git a/dojox/mobile/themes/iphone/Heading-compat.css b/dojox/mobile/themes/iphone/Heading-compat.css
new file mode 100644
index 0000000..bc02fa1
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Heading-compat.css
@@ -0,0 +1,24 @@
+/* mbl.widget.Heading */
+.mblHeading {
+	background-image: url(compat/heading-bg.png);
+}
+.mblHeadingSpanTitle {
+	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);
+}
diff --git a/dojox/mobile/themes/iphone/Heading.css b/dojox/mobile/themes/iphone/Heading.css
new file mode 100644
index 0000000..613cf72
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Heading.css
@@ -0,0 +1,84 @@
+/* dojox.mobile.Heading */
+.mblHeading {
+  position: relative;
+  margin: 0px;
+  width: 100%;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  z-index: 1;
+  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;
+  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;
+}
+.mblHeading * {
+  z-index: 2;
+}
+.mblHeadingDivTitle {
+  position: absolute;
+  width: 100%;
+  display: none;
+  left: 0px;
+  z-index: 1;
+}
+.mblHeadingCenterTitle .mblHeadingDivTitle {
+  display: block;
+}
+.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));
+}
diff --git a/dojox/mobile/themes/iphone/Heading.less b/dojox/mobile/themes/iphone/Heading.less
new file mode 100644
index 0000000..cfc8580
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Heading.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/Heading.less";
diff --git a/dojox/mobile/themes/iphone/IconContainer-compat.css b/dojox/mobile/themes/iphone/IconContainer-compat.css
new file mode 100644
index 0000000..adf6d49
--- /dev/null
+++ b/dojox/mobile/themes/iphone/IconContainer-compat.css
@@ -0,0 +1,11 @@
+ at import url("../common/domButtons/DomButtonColorButtons-compat.css");
+
+/* dojox.mobile.IconItem */
+.mblIconArea div {
+	*font-size: 60px; /* IE 7 quirks */
+}
+
+/* Icon Content Heading */
+.mblIconContentHeading {
+	background-image: url(compat/icon-content-heading-bg.png);
+}
diff --git a/dojox/mobile/themes/iphone/IconContainer.css b/dojox/mobile/themes/iphone/IconContainer.css
new file mode 100644
index 0000000..bb33f89
--- /dev/null
+++ b/dojox/mobile/themes/iphone/IconContainer.css
@@ -0,0 +1,97 @@
+ at import url("../common/domButtons/DomButtonColorButtons.css");
+
+ at import url("../common/IconContainer_keyframes.css");
+/* dojox.mobile.IconContainer */
+.mblIconContainer {
+  margin: 20px 0px 0px 10px;
+  padding: 0px 0px 40px 0px;
+}
+/* dojox.mobile.IconItem */
+.mblIconItem {
+  list-style-type: none;
+  float: left;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblIconItemTerminator {
+  list-style-type: none;
+  clear: both;
+  height: 20px;
+}
+.mblIconItemSub {
+  list-style-type: none;
+  margin-left: -10px;
+  background-color: white;
+}
+.mblIconArea {
+  margin-bottom: 10px;
+  height: 78px;
+  width: 74px;
+  font-family: Helvetica;
+  font-size: 12px;
+  text-align: center;
+}
+.mblIconArea div {
+  position: relative;
+  height: 65px;
+  line-height: 65px;
+  text-align: center;
+}
+.mblIconArea img {
+  vertical-align: middle;
+}
+.mblIconItemSpriteIcon {
+  position: absolute;
+}
+.mblContent {
+  clear: both;
+  padding-bottom: 20px;
+}
+table.mblClose {
+  clear: both;
+  cursor: pointer;
+}
+.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);
+}
+.mblCloseContent {
+  -webkit-animation-duration: .3s;
+  -webkit-animation-timing-function: ease-in-out;
+  -webkit-animation-name: mblShrink;
+  -webkit-transform: scale(0.01);
+}
+.mblCloseContent.mblShrink0 {
+  -webkit-animation-name: mblShrink0;
+}
+.mblCloseContent.mblShrink1 {
+  -webkit-animation-name: mblShrink1;
+}
+.mblCloseContent.mblShrink2 {
+  -webkit-animation-name: mblShrink2;
+}
+.mblCloseContent.mblShrink3 {
+  -webkit-animation-name: mblShrink3;
+}
+/* Icon Content Heading */
+.mblIconContentHeading {
+  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;
+  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;
+}
diff --git a/dojox/mobile/themes/iphone/IconContainer.less b/dojox/mobile/themes/iphone/IconContainer.less
new file mode 100644
index 0000000..963eae6
--- /dev/null
+++ b/dojox/mobile/themes/iphone/IconContainer.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonColorButtons.css");
+ at import url("../common/IconContainer_keyframes.css");
+
+ at import "variables.less";
+ at import "../common/IconContainer.less";
diff --git a/dojox/mobile/themes/iphone/ListItem-compat.css b/dojox/mobile/themes/iphone/ListItem-compat.css
new file mode 100644
index 0000000..d153c4b
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ListItem-compat.css
@@ -0,0 +1,7 @@
+ at 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;
+}
diff --git a/dojox/mobile/themes/iphone/ListItem.css b/dojox/mobile/themes/iphone/ListItem.css
new file mode 100644
index 0000000..77d88d9
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ListItem.css
@@ -0,0 +1,82 @@
+ at import url("../common/domButtons/DomButtonGrayArrow.css");
+
+ at import url("../common/domButtons/DomButtonDarkBlueCheck.css");
+/* dojox.mobile.ListItem */
+.mblListItem {
+  position: relative;
+  list-style-type: none;
+  vertical-align: bottom;
+  /* To avoid IE6 LI bug */
+
+  padding: 0px 0px 0px 8px;
+  height: 43px;
+  border-bottom: 1px solid #ADAAAD;
+  font-weight: bold;
+  color: black;
+  line-height: 43px;
+}
+.mblListItem.mblVariableHeight {
+  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;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#048bf4), to(#005ce5));
+}
+.mblItemSelected .mblListItemAnchor {
+  color: white;
+}
+.mblItemSelected .mblDomButton div {
+  border-color: white;
+}
+.mblListItemTextBoxSelected {
+  background-color: #048BF4;
+}
+.mblListItemChecked {
+  color: #314E84;
+}
+.mblListItemIcon {
+  float: left;
+  line-height: normal;
+  margin-top: 7px;
+  margin-right: 11px;
+}
+.mblListItemSpriteIcon {
+  position: absolute;
+  margin-top: 7px;
+  margin-left: 8px;
+}
+.mblListItemRightIcon, .mblListItemRightIcon2 {
+  position: relative;
+  float: right;
+  line-height: normal;
+  margin-top: 7px;
+  margin-bottom: -7px;
+}
+.mblListItemRightText {
+  position: relative;
+  float: right;
+  line-height: normal;
+  color: #324F85;
+  margin: 11px 4px 0 0;
+}
+.mblListItemTextBox {
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+.mblVariableHeight .mblListItemTextBox {
+  white-space: normal;
+}
diff --git a/dojox/mobile/themes/iphone/ListItem.less b/dojox/mobile/themes/iphone/ListItem.less
new file mode 100644
index 0000000..f9f9d21
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ListItem.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonGrayArrow.css");
+ at import url("../common/domButtons/DomButtonDarkBlueCheck.css");
+
+ at import "variables.less";
+ at import "../common/ListItem.less";
diff --git a/dojox/mobile/themes/iphone/Opener-compat.css b/dojox/mobile/themes/iphone/Opener-compat.css
new file mode 100644
index 0000000..68cb1a8
--- /dev/null
+++ b/dojox/mobile/themes/iphone/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/iphone/Opener.css b/dojox/mobile/themes/iphone/Opener.css
new file mode 100644
index 0000000..141c72e
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Opener.css
@@ -0,0 +1,3 @@
+/* dojox.mobile.Opener */
+ at import url("Overlay.css");
+ at import url("Tooltip.css");
diff --git a/dojox/mobile/themes/iphone/Overlay-compat.css b/dojox/mobile/themes/iphone/Overlay-compat.css
new file mode 100644
index 0000000..bf8a160
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Overlay-compat.css
@@ -0,0 +1,15 @@
+/* dojox.mobile.Overlay */
+.mblOverlay {
+	*position: absolute;
+	background-color: #CECECE;
+	background-image: none;
+	text-align: center;
+}
+.dj_gecko .mblOverlay {
+	text-align: -moz-center;
+}
+.dj_ie9 .mblOverlay > *,
+.dj_ie8 .mblOverlay > *
+{
+	margin: 0 auto;
+}
diff --git a/dojox/mobile/themes/iphone/Overlay.css b/dojox/mobile/themes/iphone/Overlay.css
new file mode 100644
index 0000000..56c3778
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Overlay.css
@@ -0,0 +1,17 @@
+ 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-image: -webkit-gradient(linear, left top, left bottom, from(#fdfdfd), to(#cecece));
+}
+.mblOverlayHidden *, .mblOverlayHidden {
+  visibility: hidden !important;
+}
diff --git a/dojox/mobile/themes/iphone/Overlay.less b/dojox/mobile/themes/iphone/Overlay.less
new file mode 100644
index 0000000..e49ea9e
--- /dev/null
+++ b/dojox/mobile/themes/iphone/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/iphone/PageIndicator.css b/dojox/mobile/themes/iphone/PageIndicator.css
new file mode 100644
index 0000000..a175ad6
--- /dev/null
+++ b/dojox/mobile/themes/iphone/PageIndicator.css
@@ -0,0 +1,24 @@
+/* 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;
+  -webkit-border-radius: 3px;
+  -moz-border-radius: 3px;
+}
+.mblPageIndicatorDotSelected {
+  background-color: white;
+}
diff --git a/dojox/mobile/themes/iphone/PageIndicator.less b/dojox/mobile/themes/iphone/PageIndicator.less
new file mode 100644
index 0000000..9bb6c49
--- /dev/null
+++ b/dojox/mobile/themes/iphone/PageIndicator.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/PageIndicator.less";
diff --git a/dojox/mobile/themes/iphone/ProgressIndicator-compat.css b/dojox/mobile/themes/iphone/ProgressIndicator-compat.css
new file mode 100644
index 0000000..4ee0810
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ProgressIndicator-compat.css
@@ -0,0 +1,46 @@
+/* Progress Indicator */
+.mblProg {
+	position: absolute;
+	top: 0px;
+	width: 4px;
+	font-size: 1px;
+	height: 36px;
+	overflow: hidden;
+	background-color: #C0C0C0;
+}
+.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;
+}
diff --git a/dojox/mobile/themes/iphone/ProgressIndicator.css b/dojox/mobile/themes/iphone/ProgressIndicator.css
new file mode 100644
index 0000000..2340637
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ProgressIndicator.css
@@ -0,0 +1,58 @@
+/* Progress Indicator */
+.mblProgContainer {
+  position: absolute;
+  width: 40px;
+  height: 40px;
+  top: 180px;
+  left: 50%;
+  margin: -18px 0px 0px -18px;
+}
+.mblProg {
+  position: absolute;
+  left: 2px;
+  top: 0px;
+  width: 11px;
+  font-size: 1px;
+  height: 4px;
+  overflow: hidden;
+  -webkit-transform-origin: 0 2px;
+  background-color: #C0C0C0;
+  -webkit-border-radius: 2px;
+  -moz-border-radius: 2px;
+}
+.mblProg0 {
+  -webkit-transform: translate(18px, 10px) rotate(-90.1deg);
+}
+.mblProg1 {
+  -webkit-transform: translate(22px, 11px) rotate(-60deg);
+}
+.mblProg2 {
+  -webkit-transform: translate(25px, 14px) rotate(-30deg);
+}
+.mblProg3 {
+  -webkit-transform: translate(26px, 18px) rotate(0deg);
+}
+.mblProg4 {
+  -webkit-transform: translate(25px, 22px) rotate(30deg);
+}
+.mblProg5 {
+  -webkit-transform: translate(22px, 25px) rotate(60deg);
+}
+.mblProg6 {
+  -webkit-transform: translate(18px, 26px) rotate(90.1deg);
+}
+.mblProg7 {
+  -webkit-transform: translate(14px, 25px) rotate(120deg);
+}
+.mblProg8 {
+  -webkit-transform: translate(11px, 22px) rotate(150deg);
+}
+.mblProg9 {
+  -webkit-transform: translate(10px, 18px) rotate(180deg);
+}
+.mblProg10 {
+  -webkit-transform: translate(11px, 14px) rotate(210deg);
+}
+.mblProg11 {
+  -webkit-transform: translate(14px, 11px) rotate(240deg);
+}
diff --git a/dojox/mobile/themes/iphone/ProgressIndicator.less b/dojox/mobile/themes/iphone/ProgressIndicator.less
new file mode 100644
index 0000000..2ab2a2d
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ProgressIndicator.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..6566cc1
--- /dev/null
+++ b/dojox/mobile/themes/iphone/RadioButton-compat.css
@@ -0,0 +1,33 @@
+/* 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);
+}
+.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);
+}
diff --git a/dojox/mobile/themes/iphone/RadioButton.css b/dojox/mobile/themes/iphone/RadioButton.css
new file mode 100644
index 0000000..799f485
--- /dev/null
+++ b/dojox/mobile/themes/iphone/RadioButton.css
@@ -0,0 +1,41 @@
+/* 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;
+  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, .mblRadioButton:checked {
+  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));
+}
+.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);
+  -webkit-transform-origin: 50% 50%;
+}
+.mblRadioButtonChecked.mblRadioButtonSelected, .mblRadioButton:checked.mblRadioButtonSelected {
+  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.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
new file mode 100644
index 0000000..0793ca6
--- /dev/null
+++ b/dojox/mobile/themes/iphone/RadioButton.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..4f16c44
--- /dev/null
+++ b/dojox/mobile/themes/iphone/RoundRect-compat.css
@@ -0,0 +1,64 @@
+/* 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;
+}
diff --git a/dojox/mobile/themes/iphone/RoundRect.css b/dojox/mobile/themes/iphone/RoundRect.css
new file mode 100644
index 0000000..071a9da
--- /dev/null
+++ b/dojox/mobile/themes/iphone/RoundRect.css
@@ -0,0 +1,12 @@
+/* dojox.mobile.RoundRect */
+.mblRoundRect {
+  margin: 7px 9px 16px 9px;
+  padding: 8px;
+  border: 1px solid #ADAAAD;
+  -webkit-border-radius: 8px;
+  -moz-border-radius: 8px;
+  background-color: white;
+}
+.mblRoundRect.mblShadow {
+  -webkit-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
new file mode 100644
index 0000000..efec816
--- /dev/null
+++ b/dojox/mobile/themes/iphone/RoundRect.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..0a9b90b
--- /dev/null
+++ b/dojox/mobile/themes/iphone/RoundRectCategory.css
@@ -0,0 +1,12 @@
+/* dojox.mobile.RoundRectCategory */
+.mblRoundRectCategory {
+  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;
+}
diff --git a/dojox/mobile/themes/iphone/RoundRectCategory.less b/dojox/mobile/themes/iphone/RoundRectCategory.less
new file mode 100644
index 0000000..e9148cc
--- /dev/null
+++ b/dojox/mobile/themes/iphone/RoundRectCategory.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/RoundRectCategory.less";
diff --git a/dojox/mobile/themes/iphone/RoundRectList-compat.css b/dojox/mobile/themes/iphone/RoundRectList-compat.css
new file mode 100644
index 0000000..4f16c44
--- /dev/null
+++ b/dojox/mobile/themes/iphone/RoundRectList-compat.css
@@ -0,0 +1,64 @@
+/* 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;
+}
diff --git a/dojox/mobile/themes/iphone/RoundRectList.css b/dojox/mobile/themes/iphone/RoundRectList.css
new file mode 100644
index 0000000..cf0bea0
--- /dev/null
+++ b/dojox/mobile/themes/iphone/RoundRectList.css
@@ -0,0 +1,25 @@
+/* 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;
+}
+.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: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;
+}
diff --git a/dojox/mobile/themes/iphone/RoundRectList.less b/dojox/mobile/themes/iphone/RoundRectList.less
new file mode 100644
index 0000000..52e1164
--- /dev/null
+++ b/dojox/mobile/themes/iphone/RoundRectList.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/RoundRectList.less";
diff --git a/dojox/mobile/themes/iphone/Slider-compat.css b/dojox/mobile/themes/iphone/Slider-compat.css
new file mode 100644
index 0000000..f6987bd
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Slider-compat.css
@@ -0,0 +1,43 @@
+/* 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;
+}
+.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;
+}
+.mblSliderV .mblSliderProgressBar {
+	background: #0D48A8;
+}
+.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;
+}
diff --git a/dojox/mobile/themes/iphone/Slider.css b/dojox/mobile/themes/iphone/Slider.css
new file mode 100644
index 0000000..6866098
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Slider.css
@@ -0,0 +1,62 @@
+/* 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;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ababab), to(#fefefe));
+  -webkit-border-radius: 8px;
+}
+.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 {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#0d48a8), to(#68a6f8));
+  -webkit-border-radius: 8px;
+}
+.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));
+}
+.mblSliderTransition {
+  -webkit-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);
+}
diff --git a/dojox/mobile/themes/iphone/Slider.less b/dojox/mobile/themes/iphone/Slider.less
new file mode 100644
index 0000000..928972f
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Slider.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/Slider.less";
diff --git a/dojox/mobile/themes/iphone/Switch-compat.css b/dojox/mobile/themes/iphone/Switch-compat.css
new file mode 100644
index 0000000..3756d95
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Switch-compat.css
@@ -0,0 +1,70 @@
+/* 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 */
+.mblSwRoundShape1 .mblSwitchBgLeft {
+	background-image: url(compat/switch-round-l.gif);
+}
+.mblSwRoundShape1 .mblSwitchBgRight {
+	background-image: url(compat/switch-round-r.gif);
+}
+.mblSwRoundShape1 .mblSwitchKnob {
+	top: 1px;
+	height: 26px;
+	background-image: url(compat/switch-round1-k.gif);
+}
+/* Switch - Round Shape2 */
+.mblSwRoundShape2 .mblSwitchBgLeft {
+	background-image: url(compat/switch-round-l.gif);
+}
+.mblSwRoundShape2 .mblSwitchBgRight {
+	background-image: url(compat/switch-round-r.gif);
+}
+.mblSwRoundShape2 .mblSwitchKnob {
+	top: 1px;
+	height: 26px;
+	background-image: url(compat/switch-round2-k.gif);
+}
+/* Switch - Arc Shape1 */
+.mblSwArcShape1 .mblSwitchBgLeft {
+	background-image: url(compat/switch-arc-l.gif);
+}
+.mblSwArcShape1 .mblSwitchBgRight {
+	background-image: url(compat/switch-arc-r.gif);
+}
+.mblSwArcShape1 .mblSwitchKnob {
+	top: 1px;
+	height: 26px;
+	background-image: url(compat/switch-arc1-k.gif);
+}
+/* Switch - Arc Shape2 */
+.mblSwArcShape2 .mblSwitchBgLeft {
+	background-image: url(compat/switch-arc-l.gif);
+}
+.mblSwArcShape2 .mblSwitchBgRight {
+	background-image: url(compat/switch-arc-r.gif);
+}
+.mblSwArcShape2 .mblSwitchKnob {
+	top: 1px;
+	height: 26px;
+	background-image: url(compat/switch-arc2-k.gif);
+}
diff --git a/dojox/mobile/themes/iphone/Switch.css b/dojox/mobile/themes/iphone/Switch.css
new file mode 100644
index 0000000..84597f9
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Switch.css
@@ -0,0 +1,18 @@
+ at import url("../common/Switch.css");
+/* dojox.mobile.Switch */
+.mblItemSwitch {
+  top: 8px;
+}
+.mblSwitchBg {
+  -webkit-border-radius: 5px;
+}
+.mblSwitchBgLeft {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2859b1), to(#75acfb), color-stop(0.5, #3f84eb), color-stop(0.5, #4c8eee));
+}
+.mblSwitchBgRight {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#cecece), to(#fdfdfd), color-stop(0.5, #eeeeee), color-stop(0.5, #f8f8f8));
+}
+.mblSwitchKnob {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#cccccc), to(#fafafa));
+  -webkit-border-radius: 5px;
+}
diff --git a/dojox/mobile/themes/iphone/Switch.less b/dojox/mobile/themes/iphone/Switch.less
new file mode 100644
index 0000000..84a1146
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Switch.less
@@ -0,0 +1,4 @@
+ at import url("../common/Switch.css");
+
+ at import "variables.less";
+ at import "../common/Switch.less";
diff --git a/dojox/mobile/themes/iphone/TabBar-compat.css b/dojox/mobile/themes/iphone/TabBar-compat.css
new file mode 100644
index 0000000..2e12529
--- /dev/null
+++ b/dojox/mobile/themes/iphone/TabBar-compat.css
@@ -0,0 +1,36 @@
+/* dojox.mobile.TabBarButton */
+.dj_ie6 .mblTabBarButtonDiv, .dj_ie7 .mblTabBarButtonDiv {
+	left: auto;
+}
+.dj_ie6 .mblTabBar .mblTabBarButton {
+  display: inline; /* IE bug*/
+}
+.mblTabPanelHeader {
+	background-image: url(compat/heading-bg.png);
+}
+.mblTabContainer .mblTabButton {
+	background-image: url(compat/tab-button-bg.png);
+}
+.mblTabContainer .mblTabButtonSelected {
+	background-image: url(compat/tab-sel-button-bg.png);
+}
+*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:first-child {
+  -moz-border-radius-topleft: 5px;
+  -moz-border-radius-bottomleft: 5px;
+}
+.mblTabButton:last-child {
+  -moz-border-radius-topright: 5px;
+  -moz-border-radius-bottomright: 5px;
+}
diff --git a/dojox/mobile/themes/iphone/TabBar.css b/dojox/mobile/themes/iphone/TabBar.css
new file mode 100644
index 0000000..becc58a
--- /dev/null
+++ b/dojox/mobile/themes/iphone/TabBar.css
@@ -0,0 +1,142 @@
+/* dojox.mobile.TabBar */
+.mblTabBar {
+  position: relative;
+  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-align: center;
+}
+.mblTabBarNoIcons {
+  height: 34px;
+}
+.mblTabBarNoText {
+  height: 34px;
+}
+/* dojox.mobile.TabBarButton */
+.mblTabBarButton {
+  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));
+}
+.mblTabBarButtonAnchor {
+  display: block;
+  text-decoration: none;
+}
+.mblTabBarButtonDiv {
+  position: relative;
+  margin-left: auto;
+  margin-right: auto;
+  height: 34px;
+  width: 29px;
+}
+.mblTabBarButtonIcon {
+  position: absolute;
+  left: 0px;
+  top: 2px;
+}
+.mblTabBarButtonSpriteIcon {
+  position: absolute;
+}
+.mblTabBarButtonTextBox {
+  color: #979797;
+  font-family: "Helvetica Neue", Helvetica;
+  font-size: 11px;
+}
+.mblTabBarNoIcons .mblTabBarButtonDiv {
+  display: none;
+}
+.mblTabBarNoIcons .mblTabBarButtonTextBox {
+  line-height: 34px;
+  font-size: 20px;
+}
+.mblTabBarTop .mblTabButton .mblTabBarButtonDiv {
+  display: none;
+}
+.mblTabButton {
+  position: relative;
+  float: left;
+  list-style-type: none;
+  cursor: pointer;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  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;
+}
+.mblTabButton .mblTabBarButtonAnchor, .mblTabButton .mblTabBarButtonDiv {
+  height: 29px;
+}
+.mblTabButton:first-child {
+  -webkit-border-top-left-radius: 5px;
+  -webkit-border-bottom-left-radius: 5px;
+  border-left-width: 1px;
+}
+.mblTabButton:last-child {
+  -webkit-border-top-right-radius: 5px;
+  -webkit-border-bottom-right-radius: 5px;
+  border-right-color: #9CACC0;
+}
+.mblTabButtonSelected .mblTabBarButtonTextBox {
+  color: white;
+}
+.mblTabButtonImgDiv {
+  display: none;
+}
+.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;
+  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;
+}
+.mblTabPanelHeader .mblTabButton {
+  margin-top: 3px;
+}
+.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));
+}
+.mblTabPanelHeader .mblTabButtonDomButton {
+  width: 43px;
+}
+.mblTabPanelHeader .mblTabButtonDomButtonClass {
+  left: 8px;
+}
+.mblHeading .mblTabPanelHeader .mblTabButton {
+  margin-top: 6px;
+}
diff --git a/dojox/mobile/themes/iphone/TabBar.less b/dojox/mobile/themes/iphone/TabBar.less
new file mode 100644
index 0000000..4875c40
--- /dev/null
+++ b/dojox/mobile/themes/iphone/TabBar.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/TabBar.less";
diff --git a/dojox/mobile/themes/iphone/TextArea-compat.css b/dojox/mobile/themes/iphone/TextArea-compat.css
new file mode 100644
index 0000000..af7e363
--- /dev/null
+++ b/dojox/mobile/themes/iphone/TextArea-compat.css
@@ -0,0 +1,7 @@
+/* dojox.mobile.TextArea */
+.mblTextArea {
+	-moz-border-radius: 5px;
+	-o-border-radius: 5px;
+	-ms-border-radius: 5px;
+	border-radius: 5px;
+}
diff --git a/dojox/mobile/themes/iphone/TextArea.css b/dojox/mobile/themes/iphone/TextArea.css
new file mode 100644
index 0000000..0768622
--- /dev/null
+++ b/dojox/mobile/themes/iphone/TextArea.css
@@ -0,0 +1,14 @@
+/* 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;
+}
+/* dojox.mobile.ExpandingTextArea */
+.mblExpandingTextArea {
+  margin: 2px;
+}
diff --git a/dojox/mobile/themes/iphone/TextArea.less b/dojox/mobile/themes/iphone/TextArea.less
new file mode 100644
index 0000000..c16ffe0
--- /dev/null
+++ b/dojox/mobile/themes/iphone/TextArea.less
@@ -0,0 +1,2 @@
+ 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
new file mode 100644
index 0000000..32dcf46
--- /dev/null
+++ b/dojox/mobile/themes/iphone/TextBox-compat.css
@@ -0,0 +1,7 @@
+/* dojox.mobile.TextBox */
+.mblTextBox {
+	-moz-border-radius: 5px;
+	-o-border-radius: 5px;
+	-ms-border-radius: 5px;
+	border-radius: 5px;
+}
diff --git a/dojox/mobile/themes/iphone/TextBox.css b/dojox/mobile/themes/iphone/TextBox.css
new file mode 100644
index 0000000..d87404e
--- /dev/null
+++ b/dojox/mobile/themes/iphone/TextBox.css
@@ -0,0 +1,8 @@
+/* dojox.mobile.TextBox */
+.mblTextBox {
+  height: 22px;
+  border: #9CACC0 1px inset;
+  -webkit-border-radius: 5px;
+  font-family: Helvetica;
+  font-size: 13px;
+}
diff --git a/dojox/mobile/themes/iphone/TextBox.less b/dojox/mobile/themes/iphone/TextBox.less
new file mode 100644
index 0000000..c83890a
--- /dev/null
+++ b/dojox/mobile/themes/iphone/TextBox.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/TextBox.less";
diff --git a/dojox/mobile/themes/iphone/ToggleButton-compat.css b/dojox/mobile/themes/iphone/ToggleButton-compat.css
new file mode 100644
index 0000000..75bfb32
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ToggleButton-compat.css
@@ -0,0 +1,30 @@
+/* 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;
+}
+.mblToggleButtonSelected {
+	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%;
+}
+.dj_ff3 .mblToggleButton.mblToggleButtonChecked::after {
+	-moz-transform: translate(-25px,-6px) rotate(45deg) skew(10deg);
+}
+.mblToggleButtonChecked.mblToggleButtonSelected {
+	background-image: url(compat/blue-button-sel-bg.png);
+}
diff --git a/dojox/mobile/themes/iphone/ToggleButton.css b/dojox/mobile/themes/iphone/ToggleButton.css
new file mode 100644
index 0000000..17e7295
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ToggleButton.css
@@ -0,0 +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;
+  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;
+  font-size: 13px;
+  color: black;
+  line-height: 29px;
+}
+.mblToggleButton.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;
+}
+.mblToggleButton.mblToggleButtonChecked {
+  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;
+}
+.mblToggleButton.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);
+  -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 {
+  border-color: white;
+}
+.mblToggleButton:disabled {
+  cursor: default;
+  border-color: grey;
+  background-image: none;
+  color: grey;
+}
diff --git a/dojox/mobile/themes/iphone/ToggleButton.less b/dojox/mobile/themes/iphone/ToggleButton.less
new file mode 100644
index 0000000..bdce40f
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ToggleButton.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/ToggleButton.less";
diff --git a/dojox/mobile/themes/iphone/ToolBarButton.css b/dojox/mobile/themes/iphone/ToolBarButton.css
new file mode 100644
index 0000000..7299e04
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ToolBarButton.css
@@ -0,0 +1,28 @@
+/* dojox.mobile.ToolBarButton */
+.mblToolBarButton {
+  float: left;
+  position: relative;
+  overflow: hidden;
+  cursor: pointer;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  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;
+}
+.mblToolBarButtonIcon {
+  position: relative;
+}
+.mblToolBarButtonSpriteIcon {
+  position: absolute;
+}
+.mblToolBarButtonText {
+  padding: 0px 10px;
+}
diff --git a/dojox/mobile/themes/iphone/ToolBarButton.less b/dojox/mobile/themes/iphone/ToolBarButton.less
new file mode 100644
index 0000000..3b67bdc
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ToolBarButton.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/ToolBarButton.less";
diff --git a/dojox/mobile/themes/iphone/Tooltip-compat.css b/dojox/mobile/themes/iphone/Tooltip-compat.css
new file mode 100644
index 0000000..18b2623
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Tooltip-compat.css
@@ -0,0 +1,41 @@
+/* dojox.mobile.Tooltip */
+.mblTooltip {
+	-moz-border-radius: 8px;
+	-o-border-radius: 8px;
+	-ms-border-radius: 8px;
+	border-radius: 8px;
+	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 */
+}
+.mblTooltipAbove .mblTooltipInnerArrow {
+	border-bottom-color: #172035;
+}
+.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_ie9 .mblTooltip .mblHeading {
+	width: auto;
+}
+.mblTooltip .mblHeading .mblToolBarButton {
+	background-color: #000924;
+	background-image: url(compat/tooltip-button-bg.png);
+	*margin: auto 6px;
+}
diff --git a/dojox/mobile/themes/iphone/Tooltip.css b/dojox/mobile/themes/iphone/Tooltip.css
new file mode 100644
index 0000000..cfe2db4
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Tooltip.css
@@ -0,0 +1,150 @@
+/* dojox.mobile.Tooltip */
+.mblTooltip {
+  position: absolute;
+  z-index: 2000;
+  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;
+  opacity: .97;
+}
+.mblTooltipBubble {
+  overflow: visible;
+  padding: 3px;
+  background-color: #f9f7ba;
+  background-image: none;
+}
+.mblTooltipBubble.mblTooltipAbove .mblTooltipInnerArrow {
+  border-bottom-color: #f9f7ba;
+}
+.mblTooltipBubble.mblTooltipBelow .mblTooltipInnerArrow {
+  border-top-color: #f9f7ba;
+}
+.mblTooltipBubble.mblTooltipAfter .mblTooltipInnerArrow {
+  border-left-color: #f9f7ba;
+}
+.mblTooltipBubble.mblTooltipBefore .mblTooltipInnerArrow {
+  border-right-color: #f9f7ba;
+}
+.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: #5A5A5A;
+}
+.mblTooltipAfter .mblTooltipArrow {
+  left: 1px;
+  right: auto;
+  top: 0;
+  bottom: auto;
+  border-right-width: 0;
+  border-left-color: #5A5A5A;
+}
+.mblTooltipAbove .mblTooltipArrow {
+  top: auto;
+  bottom: 1px;
+  left: auto;
+  right: auto;
+  border-top-width: 0;
+  border-bottom-color: #5A5A5A;
+}
+.mblTooltipBelow .mblTooltipArrow {
+  top: 1px;
+  bottom: auto;
+  left: auto;
+  right: auto;
+  border-bottom-width: 0;
+  border-top-color: #5A5A5A;
+}
+.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: #192235;
+}
+.mblTooltipAfter .mblTooltipInnerArrow {
+  left: 0;
+  top: 0;
+  border-right-width: 0;
+  border-left-color: #192235;
+}
+.mblTooltipAbove .mblTooltipInnerArrow {
+  bottom: 0;
+  left: 0;
+  border-top-width: 0;
+  border-bottom-color: #656872;
+}
+.mblTooltipBelow .mblTooltipInnerArrow {
+  top: 0;
+  left: 0;
+  border-bottom-width: 0;
+  border-top-color: #172035;
+}
+.mblTooltipHidden, .mblTooltipHidden * {
+  visibility: hidden !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;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#5e6167), to(#1a1d24), color-stop(0.5, #2e322b));
+  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));
+  font-weight: normal;
+}
diff --git a/dojox/mobile/themes/iphone/Tooltip.less b/dojox/mobile/themes/iphone/Tooltip.less
new file mode 100644
index 0000000..60af6d1
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Tooltip.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/Tooltip.less";
diff --git a/dojox/mobile/themes/iphone/View.css b/dojox/mobile/themes/iphone/View.css
new file mode 100644
index 0000000..cf2151b
--- /dev/null
+++ b/dojox/mobile/themes/iphone/View.css
@@ -0,0 +1,23 @@
+ 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%;
+}
+.mblView.mblIn {
+  position: absolute;
+}
+.mblFixedHeaderBar {
+  z-index: 1;
+}
+.mblFixedBottomBar {
+  position: absolute !important;
+  width: 100%;
+  z-index: 1;
+}
diff --git a/dojox/mobile/themes/iphone/View.less b/dojox/mobile/themes/iphone/View.less
new file mode 100644
index 0000000..910651f
--- /dev/null
+++ b/dojox/mobile/themes/iphone/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/iphone/base-compat.css b/dojox/mobile/themes/iphone/base-compat.css
new file mode 100644
index 0000000..d12cf2b
--- /dev/null
+++ b/dojox/mobile/themes/iphone/base-compat.css
@@ -0,0 +1,7 @@
+ at import url("Heading-compat.css");
+ at import url("RoundRect-compat.css");
+ at import url("RoundRectList-compat.css");
+ at import url("EdgeToEdgeCategory-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/iphone/base.css b/dojox/mobile/themes/iphone/base.css
new file mode 100644
index 0000000..2409467
--- /dev/null
+++ b/dojox/mobile/themes/iphone/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/iphone/common.css b/dojox/mobile/themes/iphone/common.css
new file mode 100644
index 0000000..f2859e0
--- /dev/null
+++ b/dojox/mobile/themes/iphone/common.css
@@ -0,0 +1,26 @@
+html.mobile, .mobile body {
+  width: 100%;
+  margin: 0px;
+  padding: 0px;
+}
+.mobile body {
+  overflow-x: hidden;
+  -webkit-text-size-adjust: none;
+  background-color: #c5ccd3;
+  font-family: Helvetica;
+  font-size: 17px;
+}
+/* Button Colors */
+.mblColorBlue {
+  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));
+}
+/* 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));
+}
+.mblColorDefaultSel {
+  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));
+}
diff --git a/dojox/mobile/themes/iphone/common.less b/dojox/mobile/themes/iphone/common.less
new file mode 100644
index 0000000..4e57a5c
--- /dev/null
+++ b/dojox/mobile/themes/iphone/common.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/common.less";
diff --git a/dojox/mobile/themes/iphone/compat/button-bg.png b/dojox/mobile/themes/iphone/compat/button-bg.png
new file mode 100644
index 0000000..0d378fa
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/button-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/button-sel-bg.png b/dojox/mobile/themes/iphone/compat/button-sel-bg.png
new file mode 100644
index 0000000..c8a71b8
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/button-sel-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/red-button-bg.png b/dojox/mobile/themes/iphone/compat/red-button-bg.png
new file mode 100644
index 0000000..799870f
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/red-button-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/red-button-sel-bg.png b/dojox/mobile/themes/iphone/compat/red-button-sel-bg.png
new file mode 100644
index 0000000..cc57b2b
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/red-button-sel-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/slider-h-bar-bg.png b/dojox/mobile/themes/iphone/compat/slider-h-bar-bg.png
new file mode 100644
index 0000000..212d59f
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/slider-h-bar-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/slider-h-bg.png b/dojox/mobile/themes/iphone/compat/slider-h-bg.png
new file mode 100644
index 0000000..b5f77b1
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/slider-h-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/slider-handle-bg.png b/dojox/mobile/themes/iphone/compat/slider-handle-bg.png
new file mode 100644
index 0000000..4b5bb6c
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/slider-handle-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-arc-l.gif b/dojox/mobile/themes/iphone/compat/switch-arc-l.gif
new file mode 100644
index 0000000..60fa6e0
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-arc-l.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-arc-r.gif b/dojox/mobile/themes/iphone/compat/switch-arc-r.gif
new file mode 100644
index 0000000..2d1cbce
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-arc-r.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-arc1-k.gif b/dojox/mobile/themes/iphone/compat/switch-arc1-k.gif
new file mode 100644
index 0000000..6596e32
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-arc1-k.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-arc2-k.gif b/dojox/mobile/themes/iphone/compat/switch-arc2-k.gif
new file mode 100644
index 0000000..bf307b1
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-arc2-k.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-blue-bg.png b/dojox/mobile/themes/iphone/compat/switch-blue-bg.png
deleted file mode 100755
index 78c9647..0000000
Binary files a/dojox/mobile/themes/iphone/compat/switch-blue-bg.png and /dev/null differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-default-k.gif b/dojox/mobile/themes/iphone/compat/switch-default-k.gif
new file mode 100644
index 0000000..9accbf5
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-default-k.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-default-l.gif b/dojox/mobile/themes/iphone/compat/switch-default-l.gif
new file mode 100644
index 0000000..c42f5ba
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-default-l.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-default-r.gif b/dojox/mobile/themes/iphone/compat/switch-default-r.gif
new file mode 100644
index 0000000..74499d5
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-default-r.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-gray-bg.png b/dojox/mobile/themes/iphone/compat/switch-gray-bg.png
deleted file mode 100755
index 04e884e..0000000
Binary files a/dojox/mobile/themes/iphone/compat/switch-gray-bg.png and /dev/null differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-knob-bg.png b/dojox/mobile/themes/iphone/compat/switch-knob-bg.png
deleted file mode 100755
index e2d75fe..0000000
Binary files a/dojox/mobile/themes/iphone/compat/switch-knob-bg.png and /dev/null differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-round-l.gif b/dojox/mobile/themes/iphone/compat/switch-round-l.gif
new file mode 100644
index 0000000..6061d6d
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-round-l.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-round-r.gif b/dojox/mobile/themes/iphone/compat/switch-round-r.gif
new file mode 100644
index 0000000..cf53086
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-round-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
new file mode 100644
index 0000000..6b9fe0a
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-round1-k.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-round2-k.gif b/dojox/mobile/themes/iphone/compat/switch-round2-k.gif
new file mode 100644
index 0000000..dfa763e
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-round2-k.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/tooltip-button-bg.png b/dojox/mobile/themes/iphone/compat/tooltip-button-bg.png
new file mode 100644
index 0000000..03bf47f
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/tooltip-button-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/tooltip-heading-bg.png b/dojox/mobile/themes/iphone/compat/tooltip-heading-bg.png
new file mode 100644
index 0000000..e7a64fa
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/tooltip-heading-bg.png differ
diff --git a/dojox/mobile/themes/iphone/ipad-compat.css b/dojox/mobile/themes/iphone/ipad-compat.css
index 5775d6c..d48170e 100644
--- a/dojox/mobile/themes/iphone/ipad-compat.css
+++ b/dojox/mobile/themes/iphone/ipad-compat.css
@@ -1,12 +1,17 @@
 /* mbl.widget.Heading */
-.mblHeading {
+.dj_tablet .mblHeading {
 	background-image: url(compat/ipad-heading-bg.png);
 }
 
 /* Heading Arrow Button */
-.mblArrowButtonHead {
+.dj_tablet .mblArrowButtonHead {
 	background-image: url(compat/ipad-arrow-button-head.png);
 }
-.mblArrowButtonBody {
+.dj_tablet .mblArrowButtonBody {
 	background-image: url(compat/ipad-arrow-button-bg.png);
 }
+
+/* mbl.widget.TabBar */
+.dj_tablet .mblTabPanelHeader {
+	background-image: url(compat/ipad-heading-bg.png);
+}
diff --git a/dojox/mobile/themes/iphone/ipad.css b/dojox/mobile/themes/iphone/ipad.css
index 6e6ad62..b17502d 100644
--- a/dojox/mobile/themes/iphone/ipad.css
+++ b/dojox/mobile/themes/iphone/ipad.css
@@ -1,7 +1,7 @@
 /* dojox.mobile.View */
 
 /* dojox.mobile.Heading */
-.mblHeading {
+.dj_tablet .mblHeading {
 	background-color: #889BB3;
 	background: -webkit-gradient(linear, left top, left bottom, from(#F3F4F6), to(#A7ABB8));
 	border-top: 1px solid #FEFEFE;
@@ -10,48 +10,92 @@
 	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;
+	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 */
-.mblArrowButtonHead {
+.dj_tablet .mblArrowButtonHead {
 	border-color: #4D4E50;
 	background: -webkit-gradient(linear, left top, right bottom, from(#B1B5BB), to(#6A727D));
 }
-.mblArrowButtonBody {
+.dj_tablet .mblArrowButtonBody {
 	border-color: #C0C0C0;
-	background-color: #5877A2;
+	background-color: #8B919A;
 	background: -webkit-gradient(linear, left top, left bottom, from(#B1B5BB), to(#6A727D));
-	-webkit-tap-highlight-color: transparent;
+	-webkit-tap-highlight-color: rgba(255,255,255,0);
 	text-shadow: rgba(0,0,0,0.6) 0px -1px 0px;
 }
-.mblArrowButtonNeck {
-	border-color: #C0C0C0;
-	background: -webkit-gradient(linear, left top, left bottom, from(#B1B5BB), to(#6A727D));
-}
-.mblArrowButtonSelected .mblArrowButtonHead {
+.dj_tablet .mblArrowButtonSelected .mblArrowButtonHead {
 	background: -webkit-gradient(linear, left top, right bottom, from(#9DA0A3), to(#43484F));
 }
-.mblArrowButtonSelected .mblArrowButtonBody, .mblArrowButtonSelected .mblArrowButtonNeck {
+.dj_tablet .mblArrowButtonSelected .mblArrowButtonBody {
 	background: -webkit-gradient(linear, left top, left bottom, from(#9DA0A3), to(#43484F));
 }
 
 /* dojox.mobile.RoundRect */
-.mblRoundRect {
+.dj_tablet .mblRoundRect {
 	margin: 7px 30px 30px 30px;
 }
-.mblHeading + .mblRoundRect {
+.dj_tablet .mblHeading + .mblRoundRect {
 	margin-top: 30px;
 }
 
 /* dojox.mobile.EdgeToEdgeCategory */
 /* dojox.mobile.RoundRectCategory */
-.mblRoundRectCategory {
+.dj_tablet .mblRoundRectCategory {
 	margin: 18px 0px 0px 41px;
 }
 
 /* dojox.mobile.RoundRectList */
-.mblRoundRectList {
+.dj_tablet .mblRoundRectList {
 	margin: 7px 30px 30px 30px;
 }
-.mblHeading + .mblRoundRectList {
+.dj_tablet .mblRoundRectList:first-child {
+	margin-top: 25px;
+}
+.dj_tablet .mblHeading + .mblRoundRectList {
 	margin-top: 30px;
 }
 
@@ -64,3 +108,45 @@
 /* Tab Container */
 /* 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;
+	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 {
+	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));
+}
+
+/* dojox.mobile.ToolBarButton */
+.dj_tablet .mblToolBarButton {
+	text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0px;
+	border: 1px inset silver;
+}
+
+/* Default Button Colors */
+.dj_tablet .mblColorDefault {
+	background-color: #8B919A;
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#B1B5BB), to(#6A727D));
+
+}
+.dj_tablet .mblColorDefaultSel {
+	background-color: #515761;
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#7A7E85), to(#303845));
+}
diff --git a/dojox/mobile/themes/iphone/iphone-app.css b/dojox/mobile/themes/iphone/iphone-app.css
index 3cf25ce..d91d2f4 100644
--- a/dojox/mobile/themes/iphone/iphone-app.css
+++ b/dojox/mobile/themes/iphone/iphone-app.css
@@ -50,31 +50,31 @@
 	margin-top: 5px;
 }
 
-.alertDialog.out {
+.alertDialog.mblOut {
 	position: absolute;
 }
 
-.alertDialog.in {
+.alertDialog.mblIn {
 	position: absolute;
 }
 
-.slidev.out {
+.mblSlidev.mblOut {
 	-webkit-animation-duration: .4s;
-	-webkit-animation-name: slideOut;
+	-webkit-animation-name: mblSlideOut;
 	-webkit-animation-timing-function: linear;
 	-webkit-transform: translateY(-100%);
 }
-.slidev.in {
+.mblSlidev.mblIn {
 	-webkit-animation-duration: .4s;
-	-webkit-animation-name: slideIn;
+	-webkit-animation-name: mblSlideIn;
 	-webkit-animation-timing-function: linear;
 	-webkit-transform: translateY(0px);
 }
-.slidev.out.reverse {
-	-webkit-animation-name: slideOutReverse;
+.mblSlidev.mblOut.mblReverse {
+	-webkit-animation-name: mblSlideOutReverse;
 }
-.slidev.in.reverse {
-	-webkit-animation-name: slideInReverse;
+.mblSlidev.mblIn.mblReverse {
+	-webkit-animation-name: mblSlideInReverse;
 }
 
 .dialogUnderlayWrapper {
diff --git a/dojox/mobile/themes/iphone/iphone-compat.css b/dojox/mobile/themes/iphone/iphone-compat.css
index 874b489..f5a0140 100755
--- a/dojox/mobile/themes/iphone/iphone-compat.css
+++ b/dojox/mobile/themes/iphone/iphone-compat.css
@@ -1,297 +1,18 @@
-/* mbl.widget.Heading */
-.mblHeading {
-	background-image: url(compat/heading-bg.png);
-}
-
-/* Heading Arrow Button */
-.mblArrowButtonHead {
-	position: absolute;
-	top: 6px;
-	left: 7px;
-	width: 19px;
-	height: 29px;
-	border-style: none;
-	background-image: url(compat/arrow-button-head.png);
-}
-.mblArrowButtonBody {
-	padding: 0px 10px 0px 10px;
-	background-image: url(compat/arrow-button-bg.png);
-}
-
-/* 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;
-}
-
-/* dojox.mobile.EdgeToEdgeCategory */
-.mblEdgeToEdgeCategory {
-	background-image: url(compat/edge-categ-bg.png);
-}
-
-/* mbl.widget.ListItem */
-*html li.mblListItem.mblVariableHeight { /* IE6 hack */
-	height: 0;
-}
-
-.mblListItem .mblArrow {
-	border-style: none;
-	top: 16px;
-	width: 9px;
-	height: 13px;
-	background-image: url(compat/gray-arrow.png);
-}
-.mblItemSelected .mblArrow {
-	background-image: url(compat/white-arrow.png);
-}
-
-/* dojox.mobile.TabBarButton */
-.dj_ie6 .mblTabBarButtonDiv, .dj_ie7 .mblTabBarButtonDiv {
-	left: auto;
-}
-
-/* Switch */
-.mblSwitchInner {
-	width: 100px;
-}
-.mblSwitchBg {
-	border: none;
-}
-.mblSwitchBgLeft {
-	width: 89px;
-	background: none;
-}
-.mblSwitchBgRight {
-	width: 89px;
-	left: 58px;
-	background: none;
-}
-.mblSwitchKnobContainer {
-	position: relative;
-	left: 53px;
-	width: 41px;
-	height: 26px;
-}
-.mblSwitchKnob {
-	position: relative;
-	top: 0px;
-	left: 0px;
-	width: auto;
-	height: 21px;
-	background-image: url(compat/switch-knob-bg.png);
-	border-width: 0px 1px;
-	-moz-border-radius: 0px;
-}
-.mblSwitchCorner {
-	position: relative;
-	height: 1px;
-	font-size: 1px;
-	overflow: hidden;
-	border-style: solid;
-	border-color: #878787;
-}
-.mblSwitchCorner1T {
-	background-color: #848684;
-	margin: 0px 4px;
-	border-width: 0px;
-}
-.mblSwitchCorner2T {
-	background-color: #C0C0C0;
-	margin: 0px 2px;
-	border-width: 0px 2px;
-}
-.mblSwitchCorner3T {
-	background-color: #C6C7C6;
-	margin: 0px 1px;
-	border-width: 0px 1px;
-}
-
-.mblSwitchCorner1B {
-	background-color: #FBFBFB;
-	margin: 0px 1px;
-	border-width: 0px 1px;
-}
-.mblSwitchCorner2B {
-	background-color: #FBFBFB;
-	margin: 0px 2px;
-	border-width: 0px 2px;
-}
-.mblSwitchCorner3B {
-	background-color: #878787;
-	margin: 0px 4px;
-	border-width: 0px;
-}
-
-.mblSwitchBgLeft .mblSwitchCorner1T {
-	border-width: 0px 2px;
-	background-color: #093889;
-}
-.mblSwitchBgLeft .mblSwitchCorner2T {
-	background-color: #285AB2;
-}
-.mblSwitchBgLeft .mblSwitchCorner3T {
-	background-color: #285AB2;
-}
-
-.mblSwitchBgLeft .mblSwitchCorner1B {
-	background-color: #66A1F6;
-}
-.mblSwitchBgLeft .mblSwitchCorner2B {
-	background-color: #66A1F6;
-}
-.mblSwitchBgLeft .mblSwitchCorner3B {
-	background-color: #5289D7;
-}
-
-.mblSwitchText {
-	height: 21px;
-	line-height: 21px;
-}
-.mblSwitchTextLeft {
-	background-image: url(compat/switch-blue-bg.png);
-	border-left: 1px solid #848684;
-}
-.mblSwitchTextRight {
-	background-image: url(compat/switch-gray-bg.png);
-	left: 35px;
-	border-right: 1px solid #848684;
-}
-
-/* Icon Content Heading */
-.mblIconContentHeading {
-	background-image: url(compat/icon-content-heading-bg.png);
-}
-
-/* dojox.mobile.Button */
-.mblBlueButton {
-	background-image: url(compat/blue-button-bg.png);
-}
-.mblBlueButtonSelected {
-	background-image: url(compat/blue-button-sel-bg.png);
-}
-
-/* Tab Container */
-.mblTabPanelHeader {
-	background-image: url(compat/heading-bg.png);
-}
-.mblTabContainer .mblTabButton {
-	background-image: url(compat/tab-button-bg.png);
-}
-.mblTabContainer .mblTabButtonSelected {
-	background-image: url(compat/tab-sel-button-bg.png);
-}
-*html .mblTabButton { /* IE6 hack */
-	behavior: expression(
-		(function(el){
-			if(!el.previousSibling)
-				el.style.borderWidth = "1px";
-			el.style.behavior = "none";
-		})(this)
-	);
-}
-
-/* Progress Indicator */
-.mblProg {
-	position: absolute;
-	top: 0px;
-	width: 4px;
-	font-size: 1px;
-	height: 36px;
-	overflow: hidden;
-	background-color: #C0C0C0;
-}
-.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;
-}
+ at import url("base-compat.css");
+
+/* common styles */
+ at import url("../common/domButtons-compat.css");
+ at import url("../common/SpinWheel-compat.css");
+
+/* widget styles */
+ 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("Opener-compat.css");
+ at import url("RadioButton-compat.css");
+ at import url("Slider-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");
diff --git a/dojox/mobile/themes/iphone/iphone.css b/dojox/mobile/themes/iphone/iphone.css
index c6b07c5..a50e0ce 100755
--- a/dojox/mobile/themes/iphone/iphone.css
+++ b/dojox/mobile/themes/iphone/iphone.css
@@ -1,858 +1,22 @@
-body {
-	visibility: hidden;
-}
-
-html.mobile, .mobile body {
-	width: 100%;
-	margin: 0px;
-	padding: 0px;
-}
-.mobile body {
-	overflow-x: hidden;
-	-webkit-text-size-adjust: none;
-	background-color: rgb(197,204,211);
-	font-family: Helvetica;
-	font-size: 17px;
-}
-
-/* dojox.mobile.View */
-.mblView {
-	position: relative;
-	top: 0px;
-	left: 0px;
-	width: 100%;
-}
-
-.mblView.out {
-}
-
-.mblView.in {
-	position: absolute;
-}
-
-.slide.out {
-	-webkit-animation-duration: .4s;
-	-webkit-animation-name: slideOut;
-	-webkit-animation-timing-function: linear;
-	-webkit-transform: translateX(-100%);
-}
-.slide.in {
-	-webkit-animation-duration: .4s;
-	-webkit-animation-name: slideIn;
-	-webkit-animation-timing-function: linear;
-	-webkit-transform: translateX(0px);
-}
-.slide.out.reverse {
-	-webkit-animation-name: slideOutReverse;
-}
-.slide.in.reverse {
-	-webkit-animation-name: slideInReverse;
-}
- at -webkit-keyframes slideOut {
-	from { -webkit-transform: translateX(0px); }
-	to { -webkit-transform: translateX(-100%); }
-}
- at -webkit-keyframes slideIn {
-	from { -webkit-transform: translateX(100%); }
-	to { -webkit-transform: translateX(0px); }
-}
- at -webkit-keyframes slideOutReverse {
-	from { -webkit-transform: translateX(0px); }
-	to { -webkit-transform: translateX(100%); }
-}
- at -webkit-keyframes slideInReverse {
-	from { -webkit-transform: translateX(-100%); }
-	to { -webkit-transform: translateX(0px); }
-}
-
-.flip.out {
-	-webkit-animation-duration: .6s;
-	-webkit-animation-name: flipOut;
-	-webkit-animation-timing-function: ease-in;
-	-webkit-transform: rotateY(90deg);
-}
-.flip.in {
-	-webkit-animation-duration: .6s;
-	-webkit-animation-name: flipIn;
-	-webkit-animation-timing-function: ease-out;
-}
- at -webkit-keyframes flipOut {
-	0% { -webkit-transform: rotateY(0deg) scale(1); }
-	50% { -webkit-transform: rotateY(90deg) scale(.8); }
-	100% { -webkit-transform: rotateY(90deg) scale(.8); }
-}
-
- at -webkit-keyframes flipIn {
-	0% { -webkit-transform: rotateY(90deg) scale(.8); }
-	50% { -webkit-transform: rotateY(90deg) scale(.8); }
-	100% { -webkit-transform: rotateY(0deg) scale(1); }
-}
-
-.fade.out {
-	-webkit-animation-duration: 1s;
-	-webkit-animation-name: fadeOut;
-	-webkit-animation-timing-function: ease-in;
-}
-.fade.out.fast {
-	-webkit-animation-duration: 0.3s;
-}
-.fade.in {
-	-webkit-animation-duration: 1s;
-	-webkit-animation-name: fadeIn;
-	-webkit-animation-timing-function: ease-out;
-}
- at -webkit-keyframes fadeOut {
-	from { opacity: 1; }
-	to { opacity: 0; }
-}
-
- at -webkit-keyframes fadeIn {
-	from { opacity: 0; }
-	to { opacity: 1; }
-}
-
-/* dojox.mobile.Heading */
-.mblHeading {
-	position: relative;
-	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;
-	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;
-	overflow: hidden;
-	white-space: nowrap;
-	text-overflow: ellipsis;
-	z-index: 1;
-}
-
-/* Heading Arrow Button */
-.mblArrowButton {
-	position: relative;
-	float: left;
-	height: 42px;
-	margin-right: 6px;
-}
-.mblArrowButtonHead {
-	position: absolute;
-	top: 11px;
-	left: 8px;
-	width: 19px;
-	height: 19px;
-	border-width: 1px;
-	border-style: solid;
-	border-color: #3A4655;
-	-webkit-transform: scale(.8,1) rotate(45deg);
-	background: -webkit-gradient(linear, left top, right bottom, from(#8EA4C1), to(#4A6C9B), color-stop(0.5, #5877A2), color-stop(0.5, #476999));
-}
-.mblArrowButtonBody {
-	position: absolute;
-	top: 6px;
-	left: 19px;
-	padding: 0px 10px 0px 3px;
-	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;
-	cursor: pointer;
-	-webkit-border-radius: 5px;
-	-moz-border-radius: 5px;
-	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));
-	-webkit-tap-highlight-color: transparent;
-}
-.mblArrowButtonNeck {
-	position: absolute;
-	top: 6px;
-	left: 19px;
-	width: 4px;
-	height: 29px;
-	border-width: 1px 0px 1px 0px;
-	border-style: inset;
-	border-color: #9CACC0;
-	background: -webkit-gradient(linear, left top, left bottom, from(#8EA4C1), to(#4A6C9B), color-stop(0.5, #5877A2), color-stop(0.5, #476999));
-}
-.mblArrowButtonSelected .mblArrowButtonHead {
-	background: -webkit-gradient(linear, left top, right bottom, from(#7C87A4), to(#263E6C), color-stop(0.5, #394D77), color-stop(0.5, #243B69));
-}
-.mblArrowButtonSelected .mblArrowButtonBody, .mblArrowButtonSelected .mblArrowButtonNeck {
-	background: -webkit-gradient(linear, left top, left bottom, from(#7C87A4), to(#263E6C), color-stop(0.5, #394D77), color-stop(0.5, #243B69));
-}
-
-/* ToolBarButton */
-.mblToolbarButton {
-	float: left;
-	position: relative;
-	margin: 6px;
-	padding: 0px 10px;
-	height: 29px;
-	border: 1px inset #9CACC0;
-	font-family: Helvetica;
-	font-size: 13px;
-	font-weight: bold;
-	color: white;
-	line-height: 29px;
-	text-align: center;
-	cursor: pointer;
-	-webkit-border-radius: 5px;
-	-moz-border-radius: 5px;
-	-webkit-tap-highlight-color: transparent;
-}
-
-/* dojox.mobile.TabBar */
-.mblTabBar {
-	position: relative;
-	height: 48px;
-	width: 100%;
-	margin: 0px;
-	padding: 0px;
-	background-color: #000000;
-	background: -webkit-gradient(linear, left top, left bottom, from(#2D2D2D), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
-	border-top: 1px solid #000000;
-	color: white;
-	text-align: center;
-	overflow: hidden;
-	white-space: nowrap;
-}
-
-.mblTabBar .mblTabBarButton {
-	position: relative;
-	list-style-type: none;
-	float: left;
-}
-
-/* dojox.mobile.TabBarButton */
-.mblTabBarButton {
-}
-.mblTabBarButtonAnchor {
-	display: block;
-	text-decoration: none;
-}
-.mblTabButton .mblTabBarButtonAnchor {
-	height: 28px;
-}
-.mblTabBarButtonDiv {
-	position: relative;
-	height: 34px;
-	width: 29px;
-	left: 50%;
-}
-.mblTabButton .mblTabBarButtonDiv {
-	display: none;
-}
-.mblTabBarButtonDivInner {
-	left: -50%;
-}
-.mblTabBarButtonIcon {
-	position: absolute;
-	left: 0px;
-	top: 2px;
-}
-.mblTabBar .mblTabBarButton.mblTabButtonSelected {
-	background-color: #404040;
-	background: -webkit-gradient(linear, left top, left bottom, from(#484848), to(#242424), color-stop(0.5, #353535), color-stop(0.5, #242424));
-	-webkit-border-radius: 3px;
-	-moz-border-radius: 3px;
-}
-.mblTabBarButtonTextBox {
-	color: #979797;
-	font-family: "Helvetica Neue", Helvetica;
-	font-size: 11px;
-}
-.mblTabButtonSelected .mblTabBarButtonTextBox {
-	color: white;
-}
-
-/* dojox.mobile.RoundRect */
-.mblRoundRect {
-	margin: 7px 9px 16px 9px;
-	padding: 8px;
-	border: 1px solid #ADAAAD;
-	-webkit-border-radius: 8px;
-	-moz-border-radius: 8px;
-	background-color: white;
-}
-.mblRoundRect.mblShadow {
-	-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
-}
-
-/* dojox.mobile.EdgeToEdgeCategory */
-.mblEdgeToEdgeCategory {
-	position: relative;
-	height: 22px;
-	margin: 0px;
-	padding: 0px 10px;
-	border-top: 1px solid #A4B0B9;
-	border-bottom: 1px solid #979DA3;
-	background: -webkit-gradient(linear, left top, left bottom, from(#8F9EA9), to(#B7C0C7));
-	font-family: Helvetica;
-	font-weight: bold;
-	font-size: 16px;
-	color: white;
-	line-height: 22px;
-	text-shadow: rgba(0,0,0,0.6) 0px -1px 0px;
-	overflow: hidden;
-	white-space: nowrap;
-	text-overflow: ellipsis;
-}
-
-/* dojox.mobile.RoundRectCategory */
-.mblRoundRectCategory {
-	color: #4C566C;
-	padding: 18px 0px 0px 20px;
-	margin: 0px;
-	text-shadow: rgba(255, 255, 255, 1) 0px 1px 0px;
-	font-family: Helvetica;
-	font-size: 16px;
-	overflow: hidden;
-	white-space: nowrap;
-	text-overflow: ellipsis;
-}
-
-/* dojox.mobile.RoundRectList */
-.mblRoundRectList {
-	margin: 7px 9px 16px 9px;
-	padding: 0px;
-	border: 1px solid #ADAAAD;
-	-webkit-border-radius: 8px;
-	-moz-border-radius: 8px;
-	background-color: white;
-	position: relative; /* IE needs this */
-}
-
-/* dojox.mobile.EdgeToEdgeList */
-.mblEdgeToEdgeList {
-	padding: 0px;
-	background-color: white;
-	position: relative; /* IE needs this */
-	margin: 0px; /* IE needs this */
-}
-
-/* dojox.mobile.ListItem */
-.mblListItem {
-	list-style-type: none;
-	height: 43px;
-	border-bottom: 1px solid #ADAAAD;
-	line-height: 43px;
-	font-weight: bold;
-	position: relative;
-	color: black;
-	vertical-align: bottom; /* To avoid IE6 LI bug */
-	padding-left: 8px;
-}
-.mblListItemIcon {
-	position: absolute;
-	top: 7px;
-}
-.mblListItem.mblVariableHeight {
-	line-height: normal;
-	height: auto;
-	padding: 11px 6px 10px 6px;
-}
-.mblItemSelected {
-	background-color: #048BF4;
-	background: -webkit-gradient(linear, left top, left bottom, from(#048BF4), to(#005CE5));
-}
-.mblListItemTextBox {
-	padding-right: 28px;
-}
-.mblListItemTextBoxSelected {
-	background-color: #048BF4;
-}
-.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: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;
-}
-.mblEdgeToEdgeList .mblListItem:last-child {
-	border-bottom-color: #707C84;
-}
-.mblListItem a.mblListItemAnchor {
-	background-position: 9px 7px;
-	display: block;
-	padding-left: 40px;
-	text-decoration: none;
-	-webkit-tap-highlight-color: transparent;
-}
-.mblListItem a.mblListItemAnchorNoIcon {
-	padding-left: 10px;
-}
-.mblItemSelected a.mblListItemAnchor {
-	color: white;
-}
-.mblListItem a.mblListItemAnchorHasRightButton {
-	padding-right: 40px;
-}
-
-.mblListItem .mblArrow {
-	position: absolute;
-	top: 18px;
-	right: 12px;
-	width: 6px;
-	height: 6px;
-	font-size: 1px;
-	-webkit-transform: rotate(45deg);
-	border-width: 3px 3px 0px 0px;
-	border-style: solid;
-	border-color: #808080;
-}
-.mblItemSelected .mblArrow {
-	border-color: white;
-}
-.mblVariableHeight div.mblArrow {
-	top: 50%;
-	margin-top: -4px;
-}
-
-.mblRightText {
-	position: absolute;
-	top: 12px;
-	right: 30px;
-	color: #324F85;
-	line-height: normal;
-}
-.mblListItem .mblRightButtonContainer {
-	position: absolute;
-	top: 50%;
-	right: 12px;
-}
-.mblListItem .mblRightButton {
-	position: absolute;
-	top: -50%;
-}
-
-/* Switch */
-.mblSwitch {
-	position: relative;
-	width: 94px;
-	height: 27px;
-	overflow: hidden;
-}
-.mblItemSwitch {
-	position: absolute;
-	top: 8px;
-	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-border-radius: 5px;
-	-moz-border-radius: 5px;
-	-webkit-box-sizing: border-box;
-	-moz-box-sizing: border-box;
-	-webkit-tap-highlight-color: transparent;
-}
-.mblSwitchBgLeft {
-	left: 0px;
-	width: 94px;
-	color: white;
-	background-color: #3F84EB;
-	background: -webkit-gradient(linear, left top, left bottom, from(#2859B1), to(#75ACFB), color-stop(0.5, #3F84EB), color-stop(0.5, #4C8EEE));
-}
-.mblSwitchBgRight {
-	left: 53px;
-	width: 94px;
-	color: #7F7F7F;
-	background-color: #EEEEEE;
-	background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
-}
-.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;
-	line-height: 29px;
-	background-color: #CCCCCC;
-	background: -webkit-gradient(linear, left top, left bottom, from(#CCCCCC), to(#FAFAFA));
-	-webkit-border-radius: 5px;
-	-moz-border-radius: 5px;
-	-webkit-box-sizing: border-box;
-	-moz-box-sizing: border-box;
-}
-.mblSwitchText {
-	position: relative;
-	top: 0px;
-	width: 53px;
-	height: 27px;
-	padding: 0px;
-	text-align: center;
-}
-.mblSwitchTextLeft {
-	left: 0px;
-}
-.mblSwitchTextRight {
-	left: 40px;
-}
-
-/* Icon Container */
-.mblIconContainer {
-	padding: 0px;
-	margin: 20px 0px 0px 10px;
-	padding: 0px 0px 40px 0px;
-}
-.mblIconItem {
-	list-style-type: none;
-	float: left;
-}
-.mblIconItemTerminator {
-	list-style-type: none;
-	height: 20px;
-	clear: both;
-}
-.mblIconItemSub {
-	list-style-type: none;
-	margin-left: -10px;
-	background-color: white;
-}
-
-.mblIconArea {
-	font-family: Helvetica;
-	font-size: 12px;
-	height: 78px;
-	width: 74px;
-	text-align: center;
-	margin-bottom: 10px;
-}
-
-.mblIconArea DIV {
-	position: relative;
-	height: 65px;
-}
-
-.mblIconArea IMG {
-	position: absolute;
-	top: 0px;
-	left: 6px;
-}
-
-.mblContent {
-	clear: both;
-	padding-bottom: 20px;
-}
-
-table.mblClose {
-	clear: both;
-	cursor: pointer;
-}
-
-.mblVibrate{
-	position: relative;
-	-webkit-animation-duration: .5s;
-	-webkit-animation-timing-function: ease-in-out;
-	-webkit-animation-iteration-count: 20;
-	-webkit-animation-name: vibrate;
-	-webkit-transform: rotate(0deg);
-}
- at -webkit-keyframes vibrate{
-	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;
-	}
-}
-
-.mblCloseContent{
-	-webkit-animation-duration: .3s;
-	-webkit-animation-timing-function: ease-in-out;
-	-webkit-animation-name: shrink;
-	-webkit-transform: scale(0.01);
-}
-.mblCloseContent.mblShrink0{
-	-webkit-animation-name: shrink0;
-}
-.mblCloseContent.mblShrink1{
-	-webkit-animation-name: shrink1;
-}
-.mblCloseContent.mblShrink2{
-	-webkit-animation-name: shrink2;
-}
-.mblCloseContent.mblShrink3{
-	-webkit-animation-name: shrink3;
-}
- at -webkit-keyframes shrink{
-	from { -webkit-transform: scale(1); }
-	to { -webkit-transform: scale(0.01); }
-}
- at -webkit-keyframes shrink0{
-	from { -webkit-transform: scale(1); }
-	to { -webkit-transform: translate(-40%,-70%) scale(0.01); }
-}
- at -webkit-keyframes shrink1{
-	from { -webkit-transform: scale(1); }
-	to { -webkit-transform: translate(-14%,-70%) scale(0.01); }
-}
- at -webkit-keyframes shrink2{
-	from { -webkit-transform: scale(1); }
-	to { -webkit-transform: translate(14%,-70%) scale(0.01); }
-}
- at -webkit-keyframes shrink3{
-	from { -webkit-transform: scale(1); }
-	to { -webkit-transform: translate(40%,-70%) scale(0.01); }
-}
-
-/* Icon Content Heading */
-.mblIconContentHeading {
-	position: relative;
-	clear: both;
-	height: 25px;
-	padding-left: 40px;
-	margin-top: 0px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#E0E4E7), to(#B4BEC6), color-stop(0.5, #C4CCD2), color-stop(0.5, #BFC8CE));
-	border-top: 1px solid #F1F3F4;
-	border-bottom: 1px solid #717D85;
-	font-family: Helvetica;
-	font-size: 14px;
-	color: white;
-	line-height: 26px;
-	text-shadow: rgba(0,0,0,0.6) 0px -1px 0px;
-	overflow: hidden;
-	white-space: nowrap;
-	text-overflow: ellipsis;
-}
-
-/* dojox.mobile.Button */
-.mblButton {
-	padding: 0px 10px;
-	height: 29px;
-	border-width: 1px 1px 1px 1px;
-	border-style: outset;
-	color: white;
-	font-family: Helvetica;
-	font-size: 13px;
-	line-height: 29px;
-	-webkit-border-radius: 5px;
-	-moz-border-radius: 5px;
-	-webkit-tap-highlight-color: transparent;
-}
-.mblBlueButton {
-	border-color: #9CACC0;
-	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));
-	-webkit-tap-highlight-color: transparent;
-}
-.mblBlueButtonSelected {
-	background: -webkit-gradient(linear, left top, left bottom, from(#8EA4C1), to(#4A6C9B), color-stop(0.5, #5877A2), color-stop(0.5, #476999));
-}
-.mblRedButton {
-	border-color: #9CACC0;
-	background-color: #366EDF;
-	background: -webkit-gradient(linear, left top, left bottom, from(#FA9D58), to(#EE4115), color-stop(0.5, #FF4D25), color-stop(0.5, #ED4D15));
-	-webkit-tap-highlight-color: transparent;
-}
-.mblRedButtonSelected {
-	background: -webkit-gradient(linear, left top, left bottom, from(#C1A48E), to(#9B6C4A), color-stop(0.5, #A27758), color-stop(0.5, #996947));
-}
-
-/* Tab Container */
-.mblTabContainer {
-}
-
-.mblTabButton {
-	float: left;
-	position: relative;
-	list-style-type: none;
-	width: 100px;
-	text-align: center;
-	height: 28px;
-	border-width: 1px 1px 1px 0px;
-	border-style: inset;
-	border-color: #9CACC0;
-	border-right-color: #5E708A;
-	font-family: Helvetica;
-	font-size: 13px;
-	color: white;
-	cursor: pointer;
-	line-height: 29px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#ABB9CA), to(#788DA9), color-stop(0.5, #8297AF), color-stop(0.5, #768BA7));
-	-webkit-tap-highlight-color: transparent;
-}
-.mblTabButton:first-child {
-	-webkit-border-top-left-radius: 5px;
-	-webkit-border-bottom-left-radius: 5px;
-	-moz-border-radius-topleft: 5px;
-	-moz-border-radius-bottomleft: 5px;
-	border-left-width: 1px;
-}
-.mblTabButton:last-child {
-	-webkit-border-top-right-radius: 5px;
-	-webkit-border-bottom-right-radius: 5px;
-	-moz-border-radius-topright: 5px;
-	-moz-border-radius-bottomright: 5px;
-	border-right-color: #9CACC0;
-}
-.mblTabPanelHeader .mblTabButton.mblTabButtonSelected {
-	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));
-}
-.mblTabButtonImgDiv {
-	display: none;
-}
-
-.mblTabPanelHeader {
-	position: relative;
-	height: 39px;
-	margin: 0px;
-	padding: 3px 0px 0px 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;
-	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;
-	overflow: hidden;
-	white-space: nowrap;
-	text-overflow: ellipsis;
-}
-
-.mblTabPanelPane {
-}
-
-.mblTabPane {
-}
-
-/* Progress Indicator */
-.mblProgContainer {
-	position: absolute;
-	width: 36px;
-	height: 36px;
-	top: 180px;
-	left: 50%;
-	margin: -18px 0px 0px -18px;
-}
-.mblProg {
-	position: absolute;
-	left: 0px;
-	top: 0px;
-	width: 11px;
-	font-size: 1px;
-	height: 4px;
-	overflow: hidden;
-	-webkit-transform-origin: 0 2px;
-	background-color: #C0C0C0;
-	-webkit-border-radius: 2px;
-	-moz-border-radius: 2px;
-}
-.mblProg0 {
-	-webkit-transform: translate(18px,10px) rotate(-90deg);
-}
-.mblProg1 {
-	-webkit-transform: translate(22px,11px) rotate(-60deg);
-}
-.mblProg2 {
-	-webkit-transform: translate(25px,14px) rotate(-30deg);
-}
-.mblProg3 {
-	-webkit-transform: translate(26px,18px) rotate(0deg);
-}
-.mblProg4 {
-	-webkit-transform: translate(25px,22px) rotate(30deg);
-}
-.mblProg5 {
-	-webkit-transform: translate(22px,25px) rotate(60deg);
-}
-.mblProg6 {
-	-webkit-transform: translate(18px,26px) rotate(90deg);
-}
-.mblProg7 {
-	-webkit-transform: translate(14px,25px) rotate(120deg);
-}
-.mblProg8 {
-	-webkit-transform: translate(11px,22px) rotate(150deg);
-}
-.mblProg9 {
-	-webkit-transform: translate(10px,18px) rotate(180deg);
-}
-.mblProg10 {
-	-webkit-transform: translate(11px,14px) rotate(210deg);
-}
-.mblProg11 {
-	-webkit-transform: translate(14px,11px) rotate(240deg);
-}
-
-/* Button Colors */
-.mblColorBlue {
-	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));
-}
-
-/* Default Button Colors */
-.mblColorDefault { /* Dark Blue */
-	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));
-}
-
-.mblColorDefaultSel { /* More Dark Blue */
-	background-color: #394D77;
-	background: -webkit-gradient(linear, left top, left bottom, from(#7C87A4), to(#263E6C), color-stop(0.5, #394D77), color-stop(0.5, #243B69));
-}
+ at import url("base.css");
+
+/* common styles */
+ at import url("../common/domButtons.css");
+ at import url("../common/FixedSplitter.css");
+ at import url("../common/SpinWheel.css");
+ at import url("../common/transitions.css");
+
+/* widget styles */
+ at import url("Button.css");
+ at import url("Carousel.css");
+ at import url("CheckBox.css");
+ at import url("ComboBox.css");
+ at import url("IconContainer.css");
+ at import url("Opener.css");
+ at import url("PageIndicator.css");
+ at import url("RadioButton.css");
+ at import url("Slider.css");
+ at import url("TabBar.css");
+ at import url("TextArea.css");
+ at import url("TextBox.css");
+ at import url("ToggleButton.css");
diff --git a/dojox/mobile/themes/iphone/variables.less b/dojox/mobile/themes/iphone/variables.less
new file mode 100644
index 0000000..007cab4
--- /dev/null
+++ b/dojox/mobile/themes/iphone/variables.less
@@ -0,0 +1,726 @@
+// common.less
+.mobile-body-styles () {
+	background-color: rgb(197,204,211);
+	font-family: Helvetica;
+	font-size: 17px;
+}
+
+.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));
+}
+.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));
+}
+.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));
+}
+
+// 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;
+	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));
+}
+
+// ToolBarButton.less
+.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 () {
+}
+.mblToolBarButtonIcon-styles () {
+}
+
+// RoundRect.less
+.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;
+	color: white;
+	line-height: 22px;
+	text-shadow: rgba(0,0,0,0.6) 0px -1px 0px;
+}
+
+// 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;
+}
+
+// EdgeToEdgeList.less
+.mblEdgeToEdgeList-styles () {
+	margin: 0px;
+	padding: 0px;
+	background-color: white;
+}
+.mblEdgeToEdgeList-LastListItem-styles () {
+	border-bottom-color: #707C84;
+}
+
+// ListItem.less
+.mblListItem-styles () {
+	padding: 0px 0px 0px 8px;
+	height: 43px;
+	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;
+}
+.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;
+}
+.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;
+}
+.mblListItemRightText-styles () {
+	color: #324F85;
+	margin: 11px 4px 0 0;
+}
+.mblListItemTextBox-styles () {
+}
+.mblListItemAnchorNoIcon-mblListItemTextBox-styles () {
+}
+.mblListItemSubText-styles () {
+}
+
+// Switch.less
+.mblItemSwitch-styles () {
+	top: 8px;
+}
+.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));
+}
+.mblSwitchKnob-styles () {
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#CCCCCC), to(#FAFAFA));
+	-webkit-border-radius: 5px;
+}
+
+// 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));
+	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;
+}
+.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));
+	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));
+}
+.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
+.dijitPopup-styles () {
+	-webkit-box-shadow: 0px 0px 50px black;
+	-webkit-border-radius: 0px;
+}
+.mblComboBoxMenu-styles () {
+	border: 1px solid black;
+	-webkit-border-radius: 0px;
+	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;
+}
+
+// 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;
+	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;
+}
+
+// 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));
+}
+.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
+.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;
+}
+.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));
+}
+
+// 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;
+}
+.mblTabBar-TabBarButton-styles () {
+}
+.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));
+}
+.mblTabBarButtonDiv-styles () {
+	height: 34px;
+	width: 29px;
+}
+.mblTabBarButtonIcon-styles () {
+	left: 0px;
+	top: 2px;
+}
+.mblTabBarButtonTextBox-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;
+}
+.mblTabButton-TabBarButtonAnchor-styles () {
+	height: 29px;
+}
+.mblTabBarTop-TabButton-TabBarButtonDiv-styles () {
+	display: none;
+}
+.mblTabBarHead-TabButton-TabBarButtonDiv-styles () {
+}
+.mblTabButton-FirstTabButtom-styles () {
+	-webkit-border-top-left-radius: 5px;
+	-webkit-border-bottom-left-radius: 5px;
+	border-left-width: 1px;
+}
+.mblTabButton-LastTabButton-styles () {
+	-webkit-border-top-right-radius: 5px;
+	-webkit-border-bottom-right-radius: 5px;
+	border-right-color: #9CACC0;
+}
+.mblTabButton-img-styles () {
+}
+.mblTabBarButtonTextBoxSelected-styles () {
+	color: white;
+}
+.mblTabButtonSelected-styles () {
+}
+.mblTabButtonHighlighted-styles () {
+}
+.mblTabButtonImgDiv-styles () {
+	display: none;
+}
+.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;
+}
+.mblTabPanelHeader-TabButton-styles () {
+	margin-top: 3px;
+}
+.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;
+}
+.mblTabPanelHeader-TabButtonDomButtonClass-styles () {
+	left: 8px;
+}
+.mblTabPanelHeader-DomButton-styles () {
+}
+.mblTabPanelHeader-inHeading-styles () {
+}
+.mblTabPanelHeader-TabButton-inHeading-styles () {
+	margin-top: 6px;
+}
+.mblTabPanelHeader-TabButton-FirstTabButtom-inHeading-styles () {
+}
+.mblTabPanelHeader-TabButton-LastTabButtom-inHeading-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;
+}
+
+// TextBox.less
+.mblTextBox-styles () {
+	height: 22px;
+	border: #9CACC0 1px inset;
+	-webkit-border-radius: 5px;
+	font-family: Helvetica;
+	font-size: 13px;
+}
+
+// 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;
+	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));
+}
+
+// Tooltip.less
+.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;
+}
+.mblTooltipBubble-styles () {
+	background-color: #f9f7ba;
+	background-image: none;
+}
+.mblTooltipInnerArrow-Bubble-Above-styles () {
+	border-bottom-color: #f9f7ba;
+}
+.mblTooltipInnerArrow-Bubble-Below-styles () {
+	border-top-color: #f9f7ba;
+}
+.mblTooltipInnerArrow-Bubble-After-styles () {
+	border-left-color: #f9f7ba;
+}
+.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;
+}
+.mblTooltipArrow-After-styles () {
+	border-right-width: 0;
+	border-left-color: #5A5A5A;
+}
+.mblTooltipArrow-Above-styles () {
+	border-top-width: 0;
+	border-bottom-color: #5A5A5A;
+}
+.mblTooltipArrow-Below-styles () {
+	border-bottom-width: 0;
+	border-top-color: #5A5A5A;
+}
+.mblTooltipInnerArrow-Before-styles () {
+	border-left-width: 0;
+	border-right-color: #192235;
+}
+.mblTooltipInnerArrow-After-styles () {
+	border-right-width: 0;
+	border-left-color: #192235;
+}
+.mblTooltipInnerArrow-Above-styles () {
+	border-top-width: 0;
+	border-bottom-color: #656872;
+}
+.mblTooltipInnerArrow-Below-styles () {
+	border-bottom-width: 0;
+	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));
+	font-weight: normal;
+}
+.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));
+	font-weight: normal;
+}
+
diff --git a/dojox/mobile/transition.js b/dojox/mobile/transition.js
new file mode 100644
index 0000000..aed509d
--- /dev/null
+++ b/dojox/mobile/transition.js
@@ -0,0 +1,19 @@
+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.
+	 */
+	if(config['mblCSS3Transition']){
+		//require dojox/css3/transit and resolve it as the result of transitDeferred.
+		var transitDeferred = new Deferred();
+		require([config['mblCSS3Transition']], function(transit){
+			transitDeferred.resolve(transit);
+		});
+		return transitDeferred;
+	}
+	return null;
+});
diff --git a/dojox/mobile/uacss.js b/dojox/mobile/uacss.js
new file mode 100644
index 0000000..d5d3b01
--- /dev/null
+++ b/dojox/mobile/uacss.js
@@ -0,0 +1,15 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojox/mobile/sniff"
+], function(dojo, lang, win, has){
+	win.doc.documentElement.className += lang.trim([
+		has('bb') ? "dj_bb" : "",
+		has('android') ? "dj_android" : "",
+		has('iphone') ? "dj_iphone" : "",
+		has('ipod') ? "dj_ipod" : "",
+		has('ipad') ? "dj_ipad" : ""
+	].join(" ").replace(/ +/g," "));
+	return dojo;
+});
diff --git a/dojox/mvc.js b/dojox/mvc.js
new file mode 100755
index 0000000..cf48514
--- /dev/null
+++ b/dojox/mvc.js
@@ -0,0 +1,8 @@
+define(["./mvc/_base"], function(dxmvc){
+	// module:
+	//		dojox/mvc
+	// summary:
+	//		Adds elements of MVC support to Dojo.
+
+	return dxmvc;
+});
diff --git a/dojox/mvc/Bind.js b/dojox/mvc/Bind.js
new file mode 100755
index 0000000..d7a6207
--- /dev/null
+++ b/dojox/mvc/Bind.js
@@ -0,0 +1,61 @@
+define([
+	"dojo/_base/lang",
+	"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,
+					/*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:
+			//		The name of the source's property whose change triggers the bind.
+			//	target:
+			//		The target dojo.Stateful object for the bind whose
+			//		property will be updated with the result of the function.
+			//	targetProp:
+			//		The name of the target's property to be updated with the
+			//		result of the function.
+			//	func:
+			//		The optional calculation to be performed to obtain the target
+			//		property value.
+			//	bindOnlyIfUnequal:
+			//		Whether the bind notification should happen only if the old and
+			//		new values are unequal (optional, defaults to false).
+			var convertedValue;
+			return source.watch(sourceProp, function(prop, oldValue, newValue){
+				convertedValue = lang.isFunction(func) ? func(newValue) : newValue;
+				if(!bindOnlyIfUnequal || convertedValue != target.get(targetProp)){
+					target.set(targetProp, convertedValue);
+				}
+			});
+		},
+
+		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:
+			//		The composing function that is called when any of the source
+			//		values changes.
+			// tags:
+			//		protected
+			var watchHandles = [];
+			array.forEach(sourceBindArray, function(h){
+				watchHandles.push(h.watch("value", func));
+			});
+			return watchHandles;
+		}
+	});
+});
diff --git a/dojox/mvc/Generate.js b/dojox/mvc/Generate.js
new file mode 100755
index 0000000..884f125
--- /dev/null
+++ b/dojox/mvc/Generate.js
@@ -0,0 +1,154 @@
+define([
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"./_Container",
+	"./Group",
+	"dijit/form/TextBox"
+], function(lang, declare, Container){
+	/*=====
+		Container = dojox.mvc._Container;
+		declare = dojo.declare;
+	=====*/
+
+	return declare("dojox.mvc.Generate", [Container], {
+		// summary:
+		//		A container that generates a view based on the data model its bound to.
+		//
+		// description:
+		//		A generate introspects its data binding and creates a view contained in
+		//		it that allows displaying the bound data. Child dijits or custom view
+		//		components inside it inherit their parent data binding context from it.
+	
+		// _counter: [private] Integer
+		//		A count maintained internally to always generate predictable widget
+		//		IDs in the view generated by this container.
+		_counter : 0,
+	
+		// defaultWidgetMapping: Object
+		//		The mapping of types to a widget class. Set widgetMapping to override this. 
+		//	
+		_defaultWidgetMapping: {"String" : "dijit.form.TextBox"},
+	
+		// defaultClassMapping: Object
+		//		The mapping of class to use. Set classMapping to override this. 
+		//	
+		_defaultClassMapping: {"Label" : "generate-label-cell", "String" : "generate-dijit-cell", "Heading" : "generate-heading", "Row" : "row"},
+	
+	
+		// defaultIdNameMapping: Object
+		//		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"},
+		
+		////////////////////// PRIVATE METHODS ////////////////////////
+	
+		_updateBinding: function(){
+			// summary:
+			//		Regenerate if the binding changes.
+			this.inherited(arguments);
+			this._buildContained();
+		},
+	
+		_buildContained: function(){
+			// summary:
+			//		Destroy any existing generated view, recreate it from scratch
+			//		parse the new contents.
+			// tags:
+			//		private
+			this._destroyBody();
+	
+			this._counter = 0;
+			this.srcNodeRef.innerHTML = this._generateBody(this.get("binding"));
+	
+			this._createBody();
+		},
+	
+		_generateBody: function(binding, hideHeading){
+			// summary:
+			//		Generate the markup for the view associated with this generate
+			//		container.
+			//	binding:
+			//		The associated data binding to generate a view for.
+			//	hideHeading:
+			//		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){
+						// TODO: Data types based widgets
+						body += this._generateTextBox(prop);
+					}else{
+						body += this._generateGroup(binding[prop], prop, hideHeading);
+					}
+				}
+			}
+			return body;
+		},
+	
+		_generateRepeat: function(binding, repeatHeading){
+			// summary:
+			//		Generate a repeating model-bound view.
+			//	binding:
+			//		The bound node (a collection/array node) to generate a
+			//		repeating UI/view for.
+			//	repeatHeading:
+			//		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;
+		},
+		
+		_generateGroup: function(binding, groupHeading, hideHeading){
+			// summary:
+			//		Generate a hierarchical model-bound view.
+			//	binding:
+			//		The bound (intermediate) node to generate a hierarchical
+			//		view portion for.
+			//	groupHeading:
+			//		The heading to be used for this portion.
+			//	hideHeading:
+			//		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++ + '">';
+			if(!hideHeading){
+				var headingClass = (this.classMapping && this.classMapping["Heading"]) ? this.classMapping["Heading"] : this._defaultClassMapping["Heading"];
+				group += '<div class="' + headingClass + '\">' + groupHeading + '</div>';
+			}
+			group += this._generateBody(binding);
+			group += '</div>';
+			return group;
+		},
+	
+		_generateTextBox: function(prop){
+			// summary:
+			//		Produce a widget for a simple value.
+			//	prop:
+			//		The data model property name.
+			// 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"];
+			
+			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>' +
+					'</div>';
+		}
+	});
+});
diff --git a/dojox/mvc/Group.js b/dojox/mvc/Group.js
new file mode 100755
index 0000000..a343f3b
--- /dev/null
+++ b/dojox/mvc/Group.js
@@ -0,0 +1,16 @@
+define(["dojo/_base/declare", "dijit/_WidgetBase"], function(declare, WidgetBase){
+	/*=====
+		WidgetBase = dijit._WidgetBase;
+		declare = dojo.declare;
+	=====*/
+
+	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.
+		//		Child dijits or custom view components inside a group inherit their parent
+		//		data binding context from it.
+	});
+});
diff --git a/dojox/mvc/Output.js b/dojox/mvc/Output.js
new file mode 100755
index 0000000..1ba6ec2
--- /dev/null
+++ b/dojox/mvc/Output.js
@@ -0,0 +1,91 @@
+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;
+	=====*/
+
+	return declare("dojox.mvc.Output", [_WidgetBase], {
+		// summary:
+		//		A simple widget that displays templated output, parts of which may
+		//		be data-bound.
+		//
+		// description:
+		//		Simple output example:
+		//
+		//		|  <span dojoType="dojox.mvc.Output" ref="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
+		//		updated accordingly.
+	
+		// templateString: [private] String
+		//		The template or data-bound output content.
+		templateString : "",
+	
+		postscript: function(params, srcNodeRef){
+			// summary:
+			//		Override and save template from body.
+			this.srcNodeRef = dom.byId(srcNodeRef);
+			if(this.srcNodeRef){
+				this.templateString = this.srcNodeRef.innerHTML;
+				this.srcNodeRef.innerHTML = "";
+			}
+			this.inherited(arguments);
+		},
+	
+		set: function(name, value){
+			// summary:
+			//		Override and refresh output on value change.
+			this.inherited(arguments);
+			if(name === "value"){
+				this._output();
+			}
+		},
+	
+		////////////////////// PRIVATE METHODS ////////////////////////
+	
+		_updateBinding: function(name, old, current){
+			// summary:
+			//		Rebuild output UI if data binding changes.
+			// tags:
+			//		private
+			this.inherited(arguments);
+			this._output();
+		},
+	
+		_output: function(){
+			// summary:
+			//		Produce the data-bound output.
+			// tags:
+			//		private
+			var outputNode = this.srcNodeRef || this.domNode;
+			outputNode.innerHTML = this.templateString ? this._exprRepl(this.templateString) : this.value;
+		},
+	
+		_exprRepl: function(tmpl){
+			// summary:
+			//		Does substitution of ${foo+bar} type expressions in template string.
+			// tags:
+			//		private
+			var pThis = this, transform = function(value, key){
+				if(!value){return "";}
+				var exp = value.substr(2);
+				exp = exp.substr(0, exp.length - 1);
+				with(pThis){return eval(exp) || "";}
+			};
+			transform = lang.hitch(this, transform);
+			return tmpl.replace(/\$\{.*?\}/g,
+				function(match, key, format){
+					return transform(match, key).toString();
+				});
+		}
+	});
+});
diff --git a/dojox/mvc/README b/dojox/mvc/README
new file mode 100755
index 0000000..f4b34a4
--- /dev/null
+++ b/dojox/mvc/README
@@ -0,0 +1,82 @@
+-------------------------------------------------------------------------------
+Project Name:  dojox.mvc
+-------------------------------------------------------------------------------
+Version 0.1
+Release date: May 16th, 2011
+-------------------------------------------------------------------------------
+Project state: experimental (code and API subject to change in future releases)
+-------------------------------------------------------------------------------
+Credits:
+       Rahul Akolkar (original author)
+       Ed Chatelain
+       Charlie Wiecha
+
+-------------------------------------------------------------------------------
+Project description:
+
+Enterprise Rich Internet Applications (RIAs) often focus more on rich data
+vs. the rich media aspects of RIAs more typical of consumer applications.
+For example, such RIAs depend on implementing the well-known CRUD operations
+on data stored in back-end systems. The dojox.mvc project focuses on
+separation of MVC concerns on the client, thereby on easing development
+of data-rich applications and accelerating the authoring of applications to
+Create, Read, Update, and Delete data using a set of Dojo-based patterns.
+
+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
+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
+varying configurations.
+
+We also add support for a set of commonly needed MVC widgets and containers
+such as:
+- Output: a data-bound output widget
+- Group: an aggregation of widgets with the same parent data binding context
+- Repeat: a model-bound repeater widget that binds to a data collection
+- Generate: an example of UI generation from a supplied data model
+
+For more, see descriptive class documentation at the top of the following
+files:
+dojox/mvc/StatefulModel.js
+dojox/mvc/_DataBindingMixin.js
+
+For an introductory page on the included samples, see:
+dojox/mvc/tests/mvc_index.html
+
+For mobile demos, see:
+dojox/mvc/tests/mobile/demo/demo.html
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+    Dojo Core (base, dojo.Stateful)
+    Dijit (dijit._WidgetBase, dijit.form.*)
+
+-------------------------------------------------------------------------------
+Documentation:
+
+Documentation resides at:
+    http://dojotoolkit.org/reference-guide/dojox/mvc.html
+
+-------------------------------------------------------------------------------
+Installation instructions:
+
+Grab the following from the Dojo SVN Repository:
+  http://svn.dojotoolkit.org/src/dojox/trunk/mvc.js
+  http://svn.dojotoolkit.org/src/dojox/trunk/mvc/*
+
+Install into the following directory structure:
+/dojox/mvc.js
+/dojox/mvc/*
+
+...which should be at the same level as your Dojo checkout.
+
+then dojo.require("dojox.mvc") in your application to load basic 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
new file mode 100755
index 0000000..607ed89
--- /dev/null
+++ b/dojox/mvc/Repeat.js
@@ -0,0 +1,108 @@
+define([
+	"dojo/_base/declare",
+	"dojo/dom",
+	"./_Container"
+], function(declare, dom, _Container){
+	/*=====
+		declare = dojo.declare;
+		dom = dojo.dom;
+		_Container = dojox.mvc._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
+		//		to an array in the data model. Child dijits or custom view components
+		//		inside it inherit their parent data binding context from it.
+
+		// index: Integer
+		//		An index used to track the current iteration when the repeating UI is
+		//		produced. This may be used to parameterize the content in the repeat
+		//		template for the current iteration.
+		//
+		//		For example, consider a collection of search or query results where
+		//		each item contains a "Name" property used to prime the "Results" data
+		//		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}">
+		//		|			<label for="nameInput${this.index}">Name:</label>
+		//		|			<input dojoType="dijit.form.TextBox" id="nameInput${this.index}" ref="'Name'"></input>
+		//		|		</div>
+		//		|	</div>
+		index : 0,
+
+		// summary:
+		//		Override and save template from body.
+		postscript: function(params, srcNodeRef){
+			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;
+				}
+				this.srcNodeRef.innerHTML = "";
+			}
+			this.inherited(arguments);
+		},
+
+		////////////////////// PRIVATE METHODS ////////////////////////
+
+		_updateBinding: function(name, old, current){
+			// summary:
+			//		Rebuild repeating UI if data binding changes.
+			// tags:
+			//		private
+			this.inherited(arguments);
+			this._buildContained();
+		},
+
+		_buildContained: function(){
+			// summary:
+			//		Destroy any existing contained view, recreate the repeating UI
+			//		markup and parse the new contents.
+			// tags:
+			//		private
+
+			// TODO: Potential optimization: only create new widgets for insert, only destroy for delete.
+			this._destroyBody();
+			this._updateAddRemoveWatch();
+
+			var insert = "";
+			for(this.index = 0; this.get("binding").get(this.index); this.index++){
+				insert += this._exprRepl(this.templateString);
+			}
+			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();
+		},
+
+		_updateAddRemoveWatch: function(){
+			// summary:
+			//		Updates the watch handle when binding changes.
+			// 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
+				}
+			});
+		}
+	});
+});
diff --git a/dojox/mvc/StatefulModel.js b/dojox/mvc/StatefulModel.js
new file mode 100755
index 0000000..aab1535
--- /dev/null
+++ b/dojox/mvc/StatefulModel.js
@@ -0,0 +1,462 @@
+define([
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/Stateful"
+], function(lang, array, declare, Stateful){
+	/*=====
+		declare = dojo.declare;
+		Stateful = dojo.Stateful;
+	=====*/
+
+	var StatefulModel = declare("dojox.mvc.StatefulModel", [Stateful], {
+		// summary:
+		//		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:
+		//		A data model is effectively instantiated with a plain JavaScript
+		//		object which specifies the initial data structure for the model.
+		//
+		//		|	var struct = {
+		//		|		order	: "abc123",
+		//		|		shipto	: {
+		//		|			address	: "123 Example St, New York, NY",
+		//		|			phone	: "212-000-0000"
+		//		|		},
+		//		|		items : [
+		//		|			{ part : "x12345", num : 1 },
+		//		|			{ part : "n09876", num : 3 }
+		//		|		]
+		//		|	};
+		//		|
+		//		|	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.
+		//
+		//		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 });
+		//
+		//		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
+		//		  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:
+		//
+		//		|	var model = dojox.mvc.newStatefulModel({ data : {
+		//		|		prop1	: "foo",
+		//		|		prop2	: {
+		//		|			leaf1	: "bar",
+		//		|			leaf2	: "baz"
+		//		|		}
+		//		|	}});
+		//		|
+		//		|	// The created dojo.Stateful tree is illustrated below (all nodes are dojo.Stateful objects)
+		//		|	//
+		//		|	//	                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
+		//		  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
+		//		  is maintained by the datamodel and may therefore be affected by
+		//		  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
+		//		  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
+		//		  over when the underlying data is persisted i.e. this can be more
+		//		  incremental or batched per application needs.
+		//
+		//		There need not be a one-to-one association between a datamodel and
+		//		a view or portion thereof. For example, multiple datamodels may
+		//		back the dijits in a view. Indeed, this may be useful where the
+		//		binding data comes from a number of data sources or queries, for
+		//		example. Just as well, dijits from multiple portions of the view
+		//		may be bound to a single datamodel.
+		//
+		//		Finally, requiring this class also enables all dijits to become data
+		//		binding aware. The data binding is commonly specified declaratively
+		//		via the "ref" property in the "data-dojo-props" attribute value.
+		//
+		//		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 : {
+		//		|				hello : "Hello World"
+		//		|			}});
+		//		|			parser.parse();
+		//		|		});
+		//		|	</script>
+		//		|
+		//		|	<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.
+		//
+		//		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.
+	
+		// data: Object
+		//		The plain JavaScript object / data structure used to initialize
+		//		this model. At any point in time, it holds the lasted saved model
+		//		state.
+		//		Either data or store property must be provided.
+		data: null,
+
+		// 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.
+		store: null,
+	
+		// valid: boolean
+		//		Whether this model deems the associated data to be valid.
+		valid: true,
+
+		// value: Object
+		//		The associated value (if this is a leaf node). The value of
+		//		intermediate nodes in the model is not defined.
+		value: "",
+
+		//////////////////////// PUBLIC METHODS / API ////////////////////////
+
+		reset: function(){
+			// summary:
+			//		Resets this data model values to its original state.
+			//		Structural changes to the data model (such as adds or removes)
+			//		are not restored.
+			if(lang.isObject(this.data) && !(this.data instanceof Date) && !(this.data instanceof RegExp)){	
+				for(var x in this){
+					if(this[x] && lang.isFunction(this[x].reset)){
+						this[x].reset();
+					}
+				}
+			}else{
+				this.set("value", this.data);
+			}
+		},
+
+		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
+			//		provided but one was provided at instantiation time, that store
+			//		will be used instead.
+			this._commit();
+			var ds = store || this.store;
+			if(ds){
+				this._saveToStore(ds);
+			}
+		},
+
+		toPlainObject: function(){
+			// summary:
+			//		Produces a plain JavaScript object representation of the data
+			//		currently within this data model.
+			// returns:
+			//		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 ret;
+		},
+
+		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:
+			//		The property name to use whose value will become the given
+			//		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
+			//		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);
+					}
+				}
+				this.set("length", this.get("length") + 1);
+			}else{
+				this.set(name, stateful);
+			}
+		},
+
+		remove: function(/*String*/ name){
+			// summary:
+			//		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
+			//		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){
+					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);
+				}
+			}else{
+				elem = this.get(name);
+				if(!elem){
+					throw new Error("Illegal delete attempted - no such property: " + name);
+				}else{
+					this._removals = this._removals || [];
+					this._removals.push(elem.toPlainObject());
+					this.set(name, undefined);
+					delete this[name];
+				}
+			}
+		},
+
+		valueOf: function(){
+			// summary:
+			//		Returns the value representation of the data currently within this data model.
+			// returns:
+			//		Object
+			//		The object representation of the data in this model.
+			return this.toPlainObject();
+		},
+
+		toString: function(){
+			// summary:
+			//		Returns the string representation of the data currently within this data model.
+			// returns:
+			//		String
+			//		The object representation of the data in this model.
+			return this.value === "" && this.data ? this.data.toString() : this.value.toString();
+		},
+
+		//////////////////////// PRIVATE INITIALIZATION METHOD ////////////////////////
+
+		constructor: function(/*Object*/ args){
+			// 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:
+			//		The mixin properties.
+			// description:
+			//		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; 
+			this._createModel(data);
+		},
+
+		//////////////////////// PRIVATE METHODS ////////////////////////
+
+		_createModel: function(/*Object*/ obj){
+			// 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);
+				}
+			}else{
+				this.set("value", obj);
+			}
+		},
+
+		_commit: function(){
+			// summary:
+			//		Commits this data model, saves the current state into data to become the saved state, 
+			//		so a reset will not undo any prior changes.  
+			// tags:
+			//		private
+			for(var x in this){
+				if(this[x] && lang.isFunction(this[x]._commit)){
+					this[x]._commit();
+				}
+			}
+			this.data = this.toPlainObject();
+		},
+
+		_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.
+			// tags:
+			//		private
+			if(this._removals){
+				array.forEach(this._removals, function(d){
+					store.remove(store.getIdentity(d));
+				}, this);
+				delete this._removals;
+			}
+			var dataToCommit = this.toPlainObject();
+			if(lang.isArray(dataToCommit)){
+				array.forEach(dataToCommit, function(d){
+					store.put(d);
+				}, this);
+			}else{
+				store.put(dataToCommit);
+			}
+		},
+
+		_copyStatefulProperties: function(/*dojo.Stateful*/ src, /*dojo.Stateful*/ dest){
+			// 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);
+				}
+			}
+		}
+	});
+
+	return StatefulModel;
+});
diff --git a/dojox/mvc/_Container.js b/dojox/mvc/_Container.js
new file mode 100755
index 0000000..6c475f2
--- /dev/null
+++ b/dojox/mvc/_Container.js
@@ -0,0 +1,107 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dijit/_WidgetBase",
+	"dojo/regexp"
+], function(declare, lang, _WidgetBase, regexp){
+	/*=====
+		declare = dojo.declare;
+		_WidgetBase = dijit._WidgetBase;
+	=====*/
+
+	return declare("dojox.mvc._Container", [_WidgetBase], {
+	
+		// stopParser: [private] Boolean
+		//		Flag to parser to not try and parse widgets declared inside the container.
+		stopParser: true,
+
+		// exprchar:  Character
+		//		Character to use for a substitution expression, for a substitution string like ${this.index}
+		exprchar: '$',
+	
+		// templateString: [private] String
+		//		The template or content for this container. It is usually obtained from the
+		//		body of the container and may be modified or repeated over a collection/array.
+		//		In this simple implementation, attach points, attach events and WAI
+		//		attributes are not supported in the template.
+		templateString : "",
+	
+		// _containedWidgets: [protected] dijit._Widget[]
+		//		The array of contained widgets at any given point in time within this container.
+		_containedWidgets : [],
+	
+		////////////////////// PROTECTED METHODS ////////////////////////
+	
+		_parser : null,
+		
+		_createBody: function(){
+			// summary:
+			//		Parse the body of this MVC container widget.
+			// description:
+			//		The bodies of MVC containers may be model-bound views generated dynamically.
+			//		Parse the body, start an contained widgets and attach template nodes for
+			//		contained widgets as necessary.
+			// tags:
+			//		protected
+			if(!this._parser){
+				try{
+					// returns dojo/parser if loaded, otherwise throws
+					this._parser = require("dojo/parser");
+				}catch(e){
+					// if here, dojo/parser not loaded
+					try{
+						// returns dojox/mobile/parser if loaded, otherwise throws
+						this._parser = require("dojox/mobile/parser");
+					}catch(e){
+						// if here, both dojox/mobile/parser and dojo/parser are not loaded
+						console.error("Add explicit require(['dojo/parser']) or explicit require(['dojox/mobile/parser']), one of the parsers is required!");
+					}
+				}
+			}
+			if(this._parser){
+				this._containedWidgets = this._parser.parse(this.srcNodeRef,{
+					template: true,
+					inherited: {dir: this.dir, lang: this.lang},
+					propsThis: this,
+					scope: "dojo"
+				});
+			}
+		},
+	
+		_destroyBody: function(){
+			// summary:
+			//		Destroy the body of this MVC container widget. Also destroys any
+			//		contained widgets.
+			// tags:
+			//		protected
+			if(this._containedWidgets && this._containedWidgets.length > 0){
+				for(var n = this._containedWidgets.length - 1; n > -1; n--){
+					var w = this._containedWidgets[n];
+					if(w && !w._destroyed && w.destroy){
+						w.destroy();
+					}
+				}
+			}
+		},
+	
+		////////////////////// PRIVATE METHODS ////////////////////////
+
+		_exprRepl: function(tmpl){
+			// summary:
+			//		Does substitution of ${foo+bar} type expressions in template string.
+			// tags:
+			//		private
+			var pThis = this, transform = function(value, key){
+				if(!value){return "";}
+				var exp = value.substr(2);
+				exp = exp.substr(0, exp.length - 1);
+				with(pThis){return eval(exp);}
+			};
+			transform = lang.hitch(this, transform);
+			return tmpl.replace(new RegExp(regexp.escapeString(this.exprchar)+"(\{.*?\})","g"),
+				function(match, key, format){
+					return transform(match, key).toString();
+				});
+		}
+	});
+});
diff --git a/dojox/mvc/_DataBindingMixin.js b/dojox/mvc/_DataBindingMixin.js
new file mode 100755
index 0000000..5a97a0f
--- /dev/null
+++ b/dojox/mvc/_DataBindingMixin.js
@@ -0,0 +1,389 @@
+define([
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/Stateful",
+	"dijit/registry"
+], function(lang, array, declare, Stateful, registry){
+	/*=====
+	registry = dijit.registry;
+	=====*/
+
+	return declare("dojox.mvc._DataBindingMixin", null, {
+		// summary:
+		//		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
+		//		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
+		//		as changes to other properties such as "valid", "required",
+		//		"readOnly" etc.
+		//
+		//		The data binding is commonly specified declaratively via the "ref"
+		//		property in the "data-dojo-props" attribute value.
+		//
+		//		Consider the following simple example:
+		//
+		//		|	<script>
+		//		|		var model;
+		//		|		require(["dijit/StatefulModel", "dojo/parser"], function(StatefulModel, parser){
+		//		|			model = new StatefulModel({ data : {
+		//		|				hello : "Hello World"
+		//		|			}});
+		//		|			parser.parse();
+		//		|		});
+		//		|	</script>
+		//		|
+		//		|	<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"
+		//		|		data-dojo-props="ref: model.hello"></input>
+		//
+		//		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".
+		//		Thereafter, a change in the value of either of the two textboxes
+		//		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.
+	
+		// ref: 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
+		//		parent / container data binding (dot-separated string).
+		ref: null,
+
+/*=====
+		// 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.
+		binding: null,
+=====*/
+
+		//////////////////////// PUBLIC METHODS ////////////////////////
+	
+		isValid: function(){
+			// summary:
+			//		Returns the validity of the data binding.
+			// returns:
+			//		Boolean
+			//		The validity associated with the data binding.
+			// 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;
+		},
+
+		//////////////////////// LIFECYCLE METHODS ////////////////////////
+
+		_dbstartup: function(){
+			// summary:
+			//		Tie data binding initialization into the widget lifecycle, at
+			//		widget startup.
+			// tags:
+			//		private
+			if(this._databound){
+				return;
+			}
+			this._unwatchArray(this._viewWatchHandles);
+			// add 2 new view watches, active only after widget has started up
+			this._viewWatchHandles = [
+				// 1. data binding refs
+				this.watch("ref", function(name, old, current){
+					if(this._databound){
+						this._setupBinding();
+					}
+				}),
+				// 2. widget values
+				this.watch("value", function(name, old, current){
+					if(this._databound){
+						var binding = this.get("binding");
+						if(binding){
+							// dont set value if the valueOf current and old match.
+							if(!((current && old) && (old.valueOf() === current.valueOf()))){
+								binding.set("value", current);
+							}
+						}
+					}
+				})
+			];
+			this._beingBound = true;
+			this._setupBinding();
+			delete this._beingBound;
+			this._databound = true;
+		},
+
+		//////////////////////// PRIVATE METHODS ////////////////////////
+
+		_setupBinding: function(parentBinding){
+			// summary:
+			//		Calculate and set the dojo.Stateful data binding for the
+			//		associated dijit or custom view component.
+			//	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
+			//		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,
+			//		  we walk up their DOM hierarchy to obtain the first container
+			//		  dijit that has a data binding set up and use the reference String
+			//		  as a property name relative to the parent's data binding context.
+			//		- 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:
+			//		- 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.
+			// tags:
+			//		private
+			if(!this.ref){
+				return; // nothing to do here
+			}
+			var ref = this.ref, pw, pb, binding;
+			// Now compute the model node to bind to
+			if(ref && lang.isFunction(ref.toPlainObject)){ // programmatic instantiation or direct ref
+				binding = ref;
+			}else if(/^\s*expr\s*:\s*/.test(ref)){ // declarative: refs as dot-separated expressions
+				ref = ref.replace(/^\s*expr\s*:\s*/, "");
+				binding = lang.getObject(ref);
+			}else if(/^\s*rel\s*:\s*/.test(ref)){ // declarative: refs relative to parent binding, dot-separated 
+				ref = ref.replace(/^\s*rel\s*:\s*/, "");
+				parentBinding = parentBinding || this._getParentBindingFromDOM();
+				if(parentBinding){
+					binding = lang.getObject("" + ref, false, parentBinding);
+				}
+			}else if(/^\s*widget\s*:\s*/.test(ref)){ // declarative: refs relative to another dijits binding, dot-separated
+				ref = ref.replace(/^\s*widget\s*:\s*/, "");
+				var tokens = ref.split(".");
+				if(tokens.length == 1){
+					binding = registry.byId(ref).get("binding");
+				}else{
+					pb = registry.byId(tokens.shift()).get("binding");
+					binding = lang.getObject(tokens.join("."), false, pb);
+				}
+			}else{ // defaults: outermost refs are expressions, nested are relative to parents
+				parentBinding = parentBinding || this._getParentBindingFromDOM();
+				if(parentBinding){
+					binding = lang.getObject("" + ref, false, parentBinding);
+				}else{
+					try{
+						if(lang.getObject(ref) instanceof Stateful){
+							binding = lang.getObject(ref);
+						}						
+					}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 + "'");
+						}
+					}
+				}
+			}
+			if(binding){
+				if(lang.isFunction(binding.toPlainObject)){
+					this.binding = 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 + "'");
+				}
+			}
+		},
+
+		_isEqual: function(one, other){
+        	// test for equality
+			return one === other ||
+				// test for NaN === NaN
+				isNaN(one) && typeof one === 'number' &&
+				isNaN(other) && typeof other === 'number';
+		},
+
+		_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:
+			//		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.
+			// description:
+			//		Applies the specified data binding to the attached widget.
+			//		Loses any prior watch registrations on the previously active
+			//		bind, registers the new one, updates data binds of any contained
+			//		widgets and also refreshes all associated properties (valid,
+			//		required etc.)
+			// tags:
+			//		private
+	
+			// remove all existing watches (if there are any, there will be 5)
+			this._unwatchArray(this._modelWatchHandles);
+			// add 5 new model watches
+			var binding = this.get("binding");
+			if(binding && lang.isFunction(binding.watch)){
+				var pThis = this;
+				this._modelWatchHandles = [
+					// 1. value - no default
+					binding.watch("value", function (name, old, current){
+						if(pThis._isEqual(old, current)){return;}
+						if(pThis._isEqual(pThis.get('value'), current)){return;}
+						pThis.set("value", current);
+					}),
+					// 2. valid - default "true"
+					binding.watch("valid", function (name, old, current){
+						pThis._updateProperty(name, old, current, true);
+						if(current !== pThis.get(name)){
+							if(pThis.validate && lang.isFunction(pThis.validate)){
+								pThis.validate();
+							}
+						}
+					}),
+					// 3. required - default "false"
+					binding.watch("required", function (name, old, current){
+						pThis._updateProperty(name, old, current, false, name, current);
+					}),
+					// 4. readOnly - default "false"
+					binding.watch("readOnly", function (name, old, current){
+						pThis._updateProperty(name, old, current, false, name, current);
+					}),
+					// 5. relevant - default "true"
+					binding.watch("relevant", function (name, old, current){
+						pThis._updateProperty(name, old, current, false, "disabled", !current);
+					})
+				];
+				var val = binding.get("value");
+				if(val != null){
+					this.set("value", val);
+				}
+			}
+			this._updateChildBindings();
+		},
+	
+		_updateProperty: function(name, old, current, defaultValue, setPropName, setPropValue){
+			// summary:
+			//		Update a binding property of the bound widget.
+			//	name:
+			//		The binding property name.
+			//	old:
+			//		The old value of the binding property.
+			//	current:
+			//		The new or current value of the binding property.
+			//	defaultValue:
+			//		The optional value to be applied as the current value of the
+			//		binding property if the current value is null.
+			//	setPropName:
+			//		The optional name of a stateful property to set on the bound
+			//		widget.
+			//	setPropValue:
+			//		The value, if an optional name is provided, for the stateful
+			//		property of the bound widget.
+			// tags:
+			//		private
+			if(old === current){
+				return;
+			}
+			if(current === null && defaultValue !== undefined){
+				current = defaultValue;
+			}
+			if(current !== this.get("binding").get(name)){
+				this.get("binding").set(name, current);
+			}
+			if(setPropName){
+				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
+			//		update children of widgets which are not bound but may hold widgets which are.
+			//	parentBind:
+			//		The binding on the parent of a widget whose children may have bindings 
+			//		which need to be updated.
+			// tags:
+			//		private
+			var binding = this.get("binding") || parentBind;
+			if(binding && !this._beingBound){
+				array.forEach(registry.findWidgets(this.domNode), function(widget){
+					if(widget.ref && widget._setupBinding){
+						widget._setupBinding(binding);
+					}else{	
+						widget._updateChildBindings(binding);
+					}
+				});
+			}
+		},
+
+		_getParentBindingFromDOM: function(){
+			// summary:
+			//		Get the parent binding by traversing the DOM ancestors to find
+			//		the first enclosing data-bound widget.
+			// returns:
+			//		The parent binding, if one exists along the DOM parent axis.
+			// tags:
+			//		private
+			var pn = this.domNode.parentNode, pw, pb;
+			while(pn){
+				pw = registry.getEnclosingWidget(pn);
+				if(pw){
+					pb = pw.get("binding");
+					if(pb && lang.isFunction(pb.toPlainObject)){
+						break;
+					}
+				}
+				pn = pw ? pw.domNode.parentNode : null;
+			}
+			return pb;
+		},
+
+		_unwatchArray: function(watchHandles){
+			// summary:
+			//		Given an array of watch handles, unwatch all.
+			//	watchHandles:
+			//		The array of watch handles.
+			// tags:
+			//		private
+			array.forEach(watchHandles, function(h){ h.unwatch(); });
+		}
+	});
+});
diff --git a/dojox/mvc/_base.js b/dojox/mvc/_base.js
new file mode 100755
index 0000000..fee784d
--- /dev/null
+++ b/dojox/mvc/_base.js
@@ -0,0 +1,64 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"./StatefulModel",
+	"./Bind",
+	"./_DataBindingMixin",
+	"./_patches"
+], function(kernel, lang, StatefulModel){
+	// module:
+	//		dojox/mvc/_base
+	// summary:
+	//		Pulls in essential MVC dependencies such as basic support for
+	//		data binds, a data model and data binding mixin for dijits.
+	kernel.experimental("dojox.mvc");
+
+	var mvc = lang.getObject("dojox.mvc", true);
+	/*=====
+		mvc = dojox.mvc;
+	=====*/
+
+	// Factory method for dojox.mvc.StatefulModel instances
+	mvc.newStatefulModel = function(/*Object*/args){
+		// summary:
+		//		Factory method that instantiates a new data model that view
+		//		components may bind to.
+		//	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
+		//		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){
+			return new StatefulModel({ data : args.data });
+		}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.store = args.store;
+					return model;
+				}));
+			}else{
+				model = new StatefulModel({ data : result });
+				model.store = args.store;
+				return model;
+			}
+		}
+	};
+
+	return mvc;
+});
diff --git a/dojox/mvc/_patches.js b/dojox/mvc/_patches.js
new file mode 100755
index 0000000..61fc563
--- /dev/null
+++ b/dojox/mvc/_patches.js
@@ -0,0 +1,49 @@
+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]));
+	};
+});
diff --git a/dojox/mvc/tests/_data/mvcGenerateData.json b/dojox/mvc/tests/_data/mvcGenerateData.json
new file mode 100755
index 0000000..12dfaa3
--- /dev/null
+++ b/dojox/mvc/tests/_data/mvcGenerateData.json
@@ -0,0 +1,9 @@
+{
+  "identifier": "Serial",
+   "items": [
+    { "Serial" : "12321312", "First" : "Andy", "Last" : "Anderson" },
+    { "Serial" : "34432423", "First" : "Buck", "Last" : "Benjamin" },
+    { "Serial" : "64343423", "First" : "Chad", "Last" : "Chambers" },
+    { "Serial" : "76574534", "First" : "Dean", "Last" : "Davidson" }
+  ]
+}
diff --git a/dojox/mvc/tests/_data/mvcRepeatData.json b/dojox/mvc/tests/_data/mvcRepeatData.json
new file mode 100755
index 0000000..191b80b
--- /dev/null
+++ b/dojox/mvc/tests/_data/mvcRepeatData.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/mvc/tests/css/android-format.css b/dojox/mvc/tests/css/android-format.css
new file mode 100755
index 0000000..2cec0eb
--- /dev/null
+++ b/dojox/mvc/tests/css/android-format.css
@@ -0,0 +1,27 @@
+.mobile label { 
+		overflow-x: hidden;
+		-webkit-text-size-adjust: none;
+		background-color: black;
+		color: white;
+		font-family: Helvetica;
+		font-size: 14px;
+		margin-left: 2px;			
+}
+.mobile body {
+    font-family: Helvetica;
+    font-size: 17px;
+    color: white;
+}
+input { 
+		width: 196px;
+		margin-left: 2px;
+}
+.row { 
+		width: 300px; display: inline-block;
+		margin-bottom: 1; margin-top: 3px; 
+}
+.spacer {display: block; margin-bottom:10px; padding-bottom:5px;}
+*[class~="spacer"] {display: block; margin-bottom:10px; padding-bottom:5px; }
+.generate-heading { font-size:1.2em; font-weight:bold; }
+.generate-label-cell { text-align: left; width: 20%;  display:inline-block; }
+.generate-dijit-cell { text-align: left; width: 20%;  display:inline-block; }
diff --git a/dojox/mvc/tests/css/app-format.css b/dojox/mvc/tests/css/app-format.css
new file mode 100755
index 0000000..3f3fdc0
--- /dev/null
+++ b/dojox/mvc/tests/css/app-format.css
@@ -0,0 +1,85 @@
+body {
+	padding: 0em 1em 1em 50px;
+	margin: 0;
+	font-family: sans-serif;
+	color: black;
+	background: white;
+	background-image: url(../images/MVC_patterns_in_Dojo.png);
+	background-position: top left;
+	background-attachment: fixed;
+	background-repeat: no-repeat;
+}
+
+.rule {display: block; background-color: #6682b5;}
+*[class~="rule"] {display: block; background-color: #aaa;}
+.spacer {display: block; margin-bottom:10px; padding-bottom:5px;}
+*[class~="spacer"] {display: block; margin-bottom:10px; padding-bottom:5px; }
+
+/*table { width: 500px; display: inline-block; } */ 
+tbody { display: inline-block; width: 100%; }
+.row { width: 500px; display: inline-block; margin: 5px; }
+.cell { width: 20%;  display:inline-block; }
+.widerow { width: 900px; display: inline-block; margin: 5px; }
+.narrowcell { width: 5%;  display:inline-block; }
+label { text-align: right; width: 98%; display: inline-block; font-weight: bold; }
+
+.generate-heading { font-size:1.2em; font-weight:bold; }
+.generate-label-cell { text-align: left; width: 20%;  display:inline-block; }
+.generate-dijit-cell { text-align: left; width: 20%;  display:inline-block; }
+
+#wrapper{
+	margin-top:0px;
+	margin-left:-5px;
+	width:100%;
+	min-width:770px;
+	font-family:"Arial";
+	font-size:0.8em;
+	background-image: url("../images/background.jpg");
+}
+#header{
+	height:100px;
+	width: 100%;
+	min-width:760px;
+	margin-left:-10px;
+	margin-top:20px;
+	z-index:1;
+}
+#headerInsert{
+	width:80%; margin:auto;
+	margin-top:0px;
+	height:100px;
+	z-index:2;
+	color: #005A9C;
+}
+#main{
+	min-height:600px;
+	width:80%; 
+	min-width:880px;
+	text-align: left;
+	padding:10px;
+	margin-top:35px;
+	font-weight:normal;
+}
+#mainContent{
+	float:left;
+	width:85%;
+	min-width:520px;
+	margin-top:-500px;
+	margin-left:140px;
+}
+#leftNav{
+	padding-top:30px;
+	height:500px;
+	width:110px;
+	margin-right:10px;
+	float:left;
+}
+#navigation{
+	width:380px;
+	height:50px;
+	margin-left:60px;
+	font-weight:bold;
+}
+#navigation ul{list-style:none; }
+#navigation ul li{float:left; display:block; margin-top:-10px;width:90px;height:30px; padding:5px;}
+#navigation ul li:hover{ color:#aaa;}
diff --git a/dojox/mvc/tests/css/dijitTests.css b/dojox/mvc/tests/css/dijitTests.css
new file mode 100644
index 0000000..33efb89
--- /dev/null
+++ b/dojox/mvc/tests/css/dijitTests.css
@@ -0,0 +1,116 @@
+/* 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
new file mode 100755
index 0000000..acf9696
--- /dev/null
+++ b/dojox/mvc/tests/css/index-format.css
@@ -0,0 +1,26 @@
+body {
+	padding: 2em 1em 2em 70px;
+	margin: 0;
+	font-family: sans-serif;
+	color: black;
+	background: white;
+	background-image: url(../images/MVC_patterns_in_Dojo.png);
+	background-position: top left;
+	background-attachment: fixed;
+	background-repeat: no-repeat;
+}
+:link { color: #00C; background: transparent }
+:visited { color: #609; background: transparent }
+a:active { color: #C00; background: transparent }
+a:link img, a:visited img { border-style: none }
+h1 { text-align : center }
+h2, h3, h4, h5, h6 { text-align: left }
+h1, h2, h3 { color: #005A9C; background: white }
+h1 { font: 170% sans-serif; ; font-weight: bold }
+h2 { font: 140% sans-serif }
+h3 { font: 120% sans-serif }
+h4 { font: bold 100% sans-serif }
+h5 { font: italic 100% sans-serif }
+h6 { font: small-caps 100% sans-serif }
+dt, dd { margin-top: 0; margin-bottom: 0 }
+dt { font-weight: bold }
diff --git a/dojox/mvc/tests/css/iphone-format.css b/dojox/mvc/tests/css/iphone-format.css
new file mode 100755
index 0000000..675e0bb
--- /dev/null
+++ b/dojox/mvc/tests/css/iphone-format.css
@@ -0,0 +1,28 @@
+.mobile label {
+font-size: 15px;
+font-weight: bold;
+color: #333;
+padding-left: 3px;
+text-shadow: rgba(255, 255, 255, 0.25);
+}
+input { 
+		width: 196px;
+		margin-left: 2px;
+}
+.row { 
+		width: 300px; display: inline-block;
+		margin-bottom: 1; margin-top: 3px; 
+}
+.spacer {display: block; margin-bottom:10px; padding-bottom:5px;}
+*[class~="spacer"] {display: block; margin-bottom:10px; padding-bottom:5px; }
+.generate-heading { font-size:1.0em; font-weight:bold; }
+.generate-label-cell { text-align: left; width: 20%;  display:inline-block; }
+.generate-dijit-cell { text-align: left; width: 66%;  display:inline-block; }
+.generate-textarea-row { text-align: left; width: 400px;  display:inline-block; }
+.generate-textarea-cell { text-align: left; width: 400px; height: 220px;  display:inline-block; }
+.generate-maincontent { text-align: left; width: 440px;}
+
+body {
+	visibility: visible;
+	width: 500px;
+}
\ No newline at end of file
diff --git a/dojox/mvc/tests/doh_async_mvc_14491-input-output.html b/dojox/mvc/tests/doh_async_mvc_14491-input-output.html
new file mode 100644
index 0000000..82bbbad
--- /dev/null
+++ b/dojox/mvc/tests/doh_async_mvc_14491-input-output.html
@@ -0,0 +1,162 @@
+<!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
new file mode 100644
index 0000000..2328349
--- /dev/null
+++ b/dojox/mvc/tests/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 "./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
new file mode 100644
index 0000000..e07e1ef
--- /dev/null
+++ b/dojox/mvc/tests/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._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
new file mode 100755
index 0000000..7a24741
--- /dev/null
+++ b/dojox/mvc/tests/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 "./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
new file mode 100644
index 0000000..5923e86
--- /dev/null
+++ b/dojox/mvc/tests/doh_mvc_date_test.html
@@ -0,0 +1,711 @@
+<!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
new file mode 100644
index 0000000..2c52b3a
--- /dev/null
+++ b/dojox/mvc/tests/doh_mvc_form-kitchensink.html
@@ -0,0 +1,1417 @@
+<!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
new file mode 100644
index 0000000..dbc8e22
--- /dev/null
+++ b/dojox/mvc/tests/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 "./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
new file mode 100644
index 0000000..c5187a5
--- /dev/null
+++ b/dojox/mvc/tests/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 "./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
new file mode 100755
index 0000000..c5523a7
--- /dev/null
+++ b/dojox/mvc/tests/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 "./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
new file mode 100755
index 0000000..69e7ac0
--- /dev/null
+++ b/dojox/mvc/tests/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 "./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
new file mode 100644
index 0000000..9e4ccdb
--- /dev/null
+++ b/dojox/mvc/tests/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 "./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
new file mode 100755
index 0000000..7c4408a
--- /dev/null
+++ b/dojox/mvc/tests/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 "./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
new file mode 100644
index 0000000..09c1a67
--- /dev/null
+++ b/dojox/mvc/tests/doh_mvc_template_repeat_exprchar.html
@@ -0,0 +1,236 @@
+<!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
new file mode 100644
index 0000000..f1e9231
--- /dev/null
+++ b/dojox/mvc/tests/doh_mvc_validation-test-simple.html
@@ -0,0 +1,133 @@
+<!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/helpers.js b/dojox/mvc/tests/helpers.js
new file mode 100644
index 0000000..a1cfe3f
--- /dev/null
+++ b/dojox/mvc/tests/helpers.js
@@ -0,0 +1,74 @@
+// 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/mvc/tests/images/MVC_patterns_in_Dojo.png b/dojox/mvc/tests/images/MVC_patterns_in_Dojo.png
new file mode 100755
index 0000000..9577e1e
Binary files /dev/null and b/dojox/mvc/tests/images/MVC_patterns_in_Dojo.png differ
diff --git a/dojox/mvc/tests/images/background.jpg b/dojox/mvc/tests/images/background.jpg
new file mode 100755
index 0000000..eee0997
Binary files /dev/null and b/dojox/mvc/tests/images/background.jpg differ
diff --git a/dojox/mvc/tests/images/master_detail.png b/dojox/mvc/tests/images/master_detail.png
new file mode 100755
index 0000000..a680d6e
Binary files /dev/null and b/dojox/mvc/tests/images/master_detail.png differ
diff --git a/dojox/mvc/tests/images/validating_form_pattern.png b/dojox/mvc/tests/images/validating_form_pattern.png
new file mode 100755
index 0000000..7356f87
Binary files /dev/null and b/dojox/mvc/tests/images/validating_form_pattern.png differ
diff --git a/dojox/mvc/tests/mobile/demo/demo-async-store.html b/dojox/mvc/tests/mobile/demo/demo-async-store.html
new file mode 100644
index 0000000..14aa506
--- /dev/null
+++ b/dojox/mvc/tests/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/mobile/demo/demo-async.html b/dojox/mvc/tests/mobile/demo/demo-async.html
new file mode 100644
index 0000000..2fdc0c5
--- /dev/null
+++ b/dojox/mvc/tests/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/mobile/demo/demo-sync.html b/dojox/mvc/tests/mobile/demo/demo-sync.html
new file mode 100644
index 0000000..accfd3e
--- /dev/null
+++ b/dojox/mvc/tests/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/mobile/demo/demo.css
new file mode 100755
index 0000000..6f04d16
--- /dev/null
+++ b/dojox/mvc/tests/mobile/demo/demo.css
@@ -0,0 +1,469 @@
+.iphone label {
+	font-size: 15px;
+	font-weight: bold;
+	color: #333;
+	padding-left: 3px;
+	text-shadow: rgba(255, 255, 255, 0.25);
+}
+
+.iphone body {
+	min-height: 200px;
+}
+
+.android label { 
+		overflow-x: hidden;
+		-webkit-text-size-adjust: none;
+		background-color: black;
+		color: white;
+		font-family: Helvetica;
+		font-size: 14px;
+		margin-left: 2px;			
+}
+
+.android body {
+	font-family: Helvetica;
+	font-size: 17px;
+	color: white;
+}
+
+input { 
+		width: 60%;
+		display:inline-block; 
+	
+}
+
+.row { 
+		width: 100%;
+		margin-bottom: 1px; margin-top: 3px;
+		display:inline-block; 
+}
+
+/* Generate Demo */
+div#view {
+	display: table;
+	border: 1px solid #ddd;
+	border-radius: 10px;
+	margin: 3px;
+	padding: 3px;
+	width: 100%;
+	background-color: #F7F7F7;
+	color: #333;
+}
+
+.generate-row {
+	display:inline-block;
+	width: 100%;
+	font-size: 15px;
+	font-weight: bold;
+	text-shadow: white 0 1px 1px;
+	color: #333;
+	font-weight: bold;
+}
+
+form#testForm div.row, form#repeatTestForm div.row {
+	width: 100%;
+	display:inline-block; 
+	
+}
+
+form#testForm, form#repeatTestForm, button#generate1, .generate-textarea-row, button#updateModel, div#view, div#generateModel, div#generateView {
+	margin-left: 15px;
+	margin-right: 15px;
+}
+
+.spacer {display: block; margin-bottom:10px; padding-bottom:5px;}
+
+.generate-heading { font-size:1.0em; font-weight:bold; }
+.generate-label-cell { 
+	text-align: left; 
+	width: 20%;	 
+	display:inline-block;
+}
+.generate-dijit-cell { text-align: left; width: 66%;  display:inline-block; }
+
+.generate-textarea-row { text-align: left; width: 90%;	display:inline-block; }
+.generate-textarea-cell { text-align: left; width: 90%; min-height: 220px;	display:inline-block; }
+.generate-maincontent { text-align: left; width: 100%;}
+
+/* CSS for buttons show case */
+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;
+}
+
+button.roundBtn {
+	border-bottom-left-radius: 17px;
+	border-bottom-right-radius: 17px;
+	border-top-left-radius: 17px;
+	border-top-right-radius: 17px;
+}
+
+button.backBtn {
+	border-bottom-left-radius: 0.4em 0.4em;
+	border-bottom-right-radius: 0.4em 0.4em;
+	border-top-left-radius: 0.4em 0.4em;
+	border-top-right-radius: 0.4em 0.4em;
+	margin-left: 0.893em;
+	padding-left: 0.4em;
+	height: 1.8em;
+	overflow: visible;
+	position: relative;
+	z-index: 1;
+}
+
+button.backBtn:before, button.backBtn:after {
+	content: "";
+	width: .773em;
+	height: 1.8em;
+	top: -0.1em;
+	left: auto;
+	position: absolute;
+	z-index: 2;
+	-webkit-mask: 0 0 url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAABGCAYAAADb7SQ4AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAiNJREFUeNrEWb9LQlEUvj5BcHoQvMnVKXD1D3CLwqBJbHJsazQaWoSCxgbHJiMIAiNok6AhCDdXVycnJ8EQOgeOYaG+d39998KH+HyP753zzjnfd325xfdSgVeV8B6BScuEV0IRSbxHeCMk/AVFXCA8ScQKSXxPqK0fQBBfE5r/D+Y8VzUT9jb94DPimqRYIYkrhGcpKhhxIqTxrpNcExdlQJTTTnRJnCc8ykhUSOIOoZ71ZFfEZ4S2zgUu+rguxZRHEnPbfKRVsOtUl0RtYpOLTYljIS2Z3nVk2DY9SbNCEt8RDm0rUpe4La1jvXSqmtum72raZI24KuNQIYl/nSGSOJb0Jq [...]
+	-webkit-mask-size: .773em 1.8em;
+	overflow: hidden;
+}
+
+button.backBtn:before {
+	left: -0.693em;
+}
+
+button.backBtn:after {
+	left: -0.628em;
+}
+
+button.greyBtn {
+	text-shadow: rgba(255, 255, 255, 0.246094) 0px 0.08em 0px;
+	border-color: #999;
+	border-top-color: #A6A6A6;
+	background-color: #CCC;
+	background-image: -webkit-gradient(linear, 0% 0, 0% 100%, from(white), color-stop(0.02, #E6E6E6), to(#BABABA));
+}
+
+button.greyBtn.backBtn:before {
+	background: #999;
+}
+
+button.greyBtn.backBtn:after {
+	background-color: #CCC;
+	background-image: -webkit-gradient(linear, 0% 0, 0% 100%, from(white), color-stop(0.02, #E6E6E6), to(#BABABA));
+}
+
+button.greyBtnSelected, button.greyBtnSelected.backBtn:after {
+	background-color:#bababa;
+	background-image:-webkit-gradient(linear,0% 0,0% 100%,color-stop(0%,#a1a1a1),color-stop(10%,#adadad),color-stop(65%,#bababa),color-stop(100%,#bbb));
+	background-image:linear-gradient(top,#a1a1a1 0,#adadad 10%,#bababa 65%,#bbb 100%);
+}
+
+/* CSS for forms show case */
+form#testForm div.fieldset, form#repeatTestForm div.fieldset {
+	display: table;
+	border: 1px solid #ddd;
+	border-radius: 10px;
+	background-color: white;
+	margin: 3px;
+	padding: 3px;
+	width: 100%;
+}
+
+form#testForm div.field-row, form#repeatTestForm div.field-row {
+		display: table-row;
+		width: 100%;
+}
+
+form#testForm div.field-title, form#repeatTestForm div.field-title {
+    font-size: 18px;
+    font-weight: bold;
+    margin: 1em .7em .3em;
+}
+
+form#testForm span, form#repeatTestForm span {
+	display: table-cell;
+	font-size: 15px;
+	font-weight: bold;
+	background-color: #F7F7F7;
+	color: #333;
+	padding-left: 3px;
+	text-shadow: rgba(255, 255, 255, 0.25);
+	vertical-align: middle;
+	width: 25%;
+}
+
+form#testForm input {
+	display: table-cell;
+	width: 75%;
+}
+
+form#testForm input[type="radio"], form#testForm input[type="checkbox"] {
+	width: 15px;
+}
+
+form#testForm select, form#testForm textarea {
+	margin-left: 0px;
+}
+
+/* CSS for headings show case */
+ul#headingTabBar {
+	display:inline;
+}
+ul#headingTabBar li {
+	margin: 6px 0 6px 0 !important;
+}
+
+ul#headingTabBar li.mblTabButton {
+	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));
+}
+
+ul#headingTabBar li.mblTabButtonSelected {
+	background-color: #394D77;
+	background: -webkit-gradient(linear, left top, left bottom, from(#7C87A4), to(#263E6C), color-stop(0.5, #394D77), color-stop(0.5, #243B69));
+}
+
+div#headings button.baseBtn {
+	display: block;
+	float: left;
+	-webkit-background-clip: padding-box;
+	-webkit-box-align: center;
+	background-clip: padding-box;
+	border-style: solid;
+	border-width: 1px;
+	margin: 6px 30px;
+	color: white;
+	font-family: 'Helvetica Neue', HelveticaNeue, Helvetica-Neue, Helvetica, 'BBAlpha Sans';
+	font-size: 13px;
+	font-weight: bold;
+	-webkit-box-shadow: rgba(255, 255, 255, 0.0976563) 0px 0.1em 0px;
+	vertical-align: middle;
+	height: 29px;
+	border-bottom-left-radius: 7px;
+	border-bottom-right-radius: 7px;
+	border-top-left-radius: 7px;
+	border-top-right-radius: 7px;
+}
+
+div#headings button.backBtn:before, div#headings button.backBtn:after {
+	content: "";
+	width: .773em;
+	height: 29px;
+	top: -0.1em;
+	left: auto;
+	position: absolute;
+	z-index: 2;
+	-webkit-mask: 0 0 url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAABGCAYAAADb7SQ4AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAiNJREFUeNrEWb9LQlEUvj5BcHoQvMnVKXD1D3CLwqBJbHJsazQaWoSCxgbHJiMIAiNok6AhCDdXVycnJ8EQOgeOYaG+d39998KH+HyP753zzjnfd325xfdSgVeV8B6BScuEV0IRSbxHeCMk/AVFXCA8ScQKSXxPqK0fQBBfE5r/D+Y8VzUT9jb94DPimqRYIYkrhGcpKhhxIqTxrpNcExdlQJTTTnRJnCc8ykhUSOIOoZ71ZFfEZ4S2zgUu+rguxZRHEnPbfKRVsOtUl0RtYpOLTYljIS2Z3nVk2DY9SbNCEt8RDm0rUpe4La1jvXSqmtum72raZI24KuNQIYl/nSGSOJb0Jq [...]
+	-webkit-mask-size: .773em 29px;
+	overflow: hidden;
+}
+
+div#headings button.backBtn:before {
+	left: -0.5em;
+}
+
+div#headings button.backBtn:after {
+	left: -0.5em;
+}
+
+button.defaultBtn {
+	text-shadow: rgba(255, 255, 255, 0.246094) 0px 0.08em 0px;
+	border-color: #9CACC0;
+	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));
+
+}
+
+button.defaultBtn.backBtn:before {
+	background: #999;
+}
+
+button.defaultBtn.backBtn:after {
+	background-color: #CCC;
+	background: -webkit-gradient(linear, left top, left bottom, from(#8EA4C1), to(#4A6C9B), color-stop(0.5, #5877A2), color-stop(0.5, #476999));
+}
+
+button.defaultBtnSelected, button.defaultBtnSelected.backBtn:after {
+	background-color: #394D77;
+	background: -webkit-gradient(linear, left top, left bottom, from(#7C87A4), to(#263E6C), color-stop(0.5, #394D77), color-stop(0.5, #243B69));
+}
+
+/* CSS for jsonp show case */
+div div.searchResult {
+	border: 2px solid #999;
+	border-bottom-left-radius: 15px 15px;
+	border-bottom-right-radius: 15px 15px;
+	border-top-left-radius: 15px 15px;
+	border-top-right-radius: 15px 15px;
+	color: white;
+	margin: 1%;
+	padding: 15px;
+	text-align: center;
+	text-shadow: grey 0px 2px 0px;
+	list-style-type: none;
+}
+
+div div.searchResult .user {
+	margin: 10px 0;
+	font-size: 24px;
+	line-height: 20px;
+}
+
+div div.searchResult .text {
+	margin: 10px 0 5px;
+	font-size: 12px;
+	font-weight: bold;
+}
+
+div.searchResult img {
+	width:48px;
+	height:48px;
+}
+
+/* CSS for overall layout */
+.hidden {
+	display:none;
+}
+
+div .navPane {
+	width:250px;
+	border-right:1px solid black;
+}
+
+/* CSS for list show case */
+.list .row {
+	padding: 10px;
+	border-bottom: 1px solid #444;
+	position: relative;
+	background-color: white;
+	z-index: 6; /* Must be greater than the .buttons z-index */
+}
+.list .row.mblListItem {
+	padding: 0px;
+}
+
+.list .row.last {
+	border-bottom: none;
+}
+
+.list .row.hold {
+	background-color: #ddd;
+}
+
+.list .buttons {
+	position: absolute;
+	text-align: center;
+	padding-top: 10px;
+	width: 100%;
+	height: 100%;
+	z-index: 5;
+}
+
+.list .buttons .mblButton {
+}
+
+.list .buttons .deleteBtn {
+	background-color: red;
+
+}
+.list .buttons .cancelBtn {
+	margin-left: 10px;
+	background-color: blue;
+}
+
+.row.collapsed {
+	-webkit-animation-name: collapse-vert;
+	-webkit-animation-duration: 0.5s;
+	-webkit-animation-timing-function: linear;
+}
+
+div#list .mblRoundRectList, div#list .mblRoundRect {
+	margin: 10px 10px 10px 10px;
+}
+
+ at -webkit-keyframes collapse-vert {
+	from {
+		height: 100%;
+		padding: 10px;
+	}
+	to {
+		height: 0px;
+		padding: 0px;
+	}
+}
+
+/* CSS for tabs show case */
+div.tabContent {
+	width: 100%;
+	text-align: center;
+	display: table;
+	overflow: hidden;
+	height: 100px;
+	font-size: 20px;
+}
+
+div.tabContent span {
+	width: 100%;
+	vertical-align: middle;
+	display: table-cell;
+}
+
+div#tabBarContent {
+	border-top-left-radius: 7px;
+	border-top-right-radius: 7px;
+}
+
+div.mblTabButton {
+	height: 61px;
+}
+
+div.mblTabButtonImgDiv {
+	display: block;
+	height: 40px;
+}
+
+div.mblTabButtonImgDiv IMG {
+	margin-top: 8px;
+}
+
+#tabContainer .mblTabPanelHeader {
+	height: 70px;
+}
+
+ul#demoTabBar img.mblTabBarButtonIcon, ul#demoTabs img.mblTabBarButtonIcon {
+	height: 30px;
+	width: 30px;
+}
+
+ul#demoTabBar, ul#demoTabs {
+	height: 36px;
+}
+
+div#tContainer .mblTabPanelPane, div#tabBarContent {
+	border-style: solid;
+	border-width: 1px;
+}
+
+div#tContainer .mblTabPanelPane, ul#demoTabBar, ul#demoTabs {
+	border-bottom-left-radius: 7px;
+	border-bottom-right-radius: 7px;
+}
+
+div#tContainer, div#tabPanel {
+	-moz-box-shadow: 10px 10px 5px #888;
+	-webkit-box-shadow: 10px 10px 5px #888;
+	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
new file mode 100755
index 0000000..67e1465
--- /dev/null
+++ b/dojox/mvc/tests/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/mobile/demo/demo.profile.js
new file mode 100755
index 0000000..275476e
--- /dev/null
+++ b/dojox/mvc/tests/mobile/demo/demo.profile.js
@@ -0,0 +1,17 @@
+dependencies = {
+	layers: [
+		{
+			name: "../demos/mvcMobile/src.js",
+			resourceName: "demos.mvcMobile.src",
+			dependencies: [
+				"demos.mvcMobile.src"
+			]
+		}
+	],
+
+	prefixes: [
+		[ "dijit", "../dijit" ],
+		[ "dojox", "../dojox" ],
+		[ "demos", "../demos" ]
+	]
+}
diff --git a/dojox/mvc/tests/mobile/demo/generateView.html b/dojox/mvc/tests/mobile/demo/generateView.html
new file mode 100755
index 0000000..5ce2ef5
--- /dev/null
+++ b/dojox/mvc/tests/mobile/demo/generateView.html
@@ -0,0 +1,62 @@
+<div id="generate" data-dojo-type="dojox.mobile.ScrollableView"  style="width: 100%;">
+    <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>
+              		<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>
diff --git a/dojox/mvc/tests/mobile/demo/iPad-Demo.html b/dojox/mvc/tests/mobile/demo/iPad-Demo.html
new file mode 100644
index 0000000..24a0a63
--- /dev/null
+++ b/dojox/mvc/tests/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/mobile/demo/images/i-icon-1.png
new file mode 100755
index 0000000..b9bb9b1
Binary files /dev/null and b/dojox/mvc/tests/mobile/demo/images/i-icon-1.png differ
diff --git a/dojox/mvc/tests/mobile/demo/images/i-icon-2.png b/dojox/mvc/tests/mobile/demo/images/i-icon-2.png
new file mode 100755
index 0000000..82d57a2
Binary files /dev/null and b/dojox/mvc/tests/mobile/demo/images/i-icon-2.png differ
diff --git a/dojox/mvc/tests/mobile/demo/images/i-icon-3.png b/dojox/mvc/tests/mobile/demo/images/i-icon-3.png
new file mode 100755
index 0000000..0323444
Binary files /dev/null and b/dojox/mvc/tests/mobile/demo/images/i-icon-3.png differ
diff --git a/dojox/mvc/tests/mobile/demo/images/mvc.png b/dojox/mvc/tests/mobile/demo/images/mvc.png
new file mode 100755
index 0000000..3e6c63d
Binary files /dev/null and b/dojox/mvc/tests/mobile/demo/images/mvc.png differ
diff --git a/dojox/mvc/tests/mobile/demo/repeatDataBinding.html b/dojox/mvc/tests/mobile/demo/repeatDataBinding.html
new file mode 100755
index 0000000..d3b9840
--- /dev/null
+++ b/dojox/mvc/tests/mobile/demo/repeatDataBinding.html
@@ -0,0 +1,45 @@
+<div id="repeat" dojoType="dojox.mobile.ScrollableView"  style="width: 100%;">
+    <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"></input>
+                	<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'"></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="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>
diff --git a/dojox/mvc/tests/mobile/demo/shipToBillTo.html b/dojox/mvc/tests/mobile/demo/shipToBillTo.html
new file mode 100755
index 0000000..ddbec48
--- /dev/null
+++ b/dojox/mvc/tests/mobile/demo/shipToBillTo.html
@@ -0,0 +1,51 @@
+<div id="settings" dojoType="dojox.mobile.ScrollableView"  style="width: 100%;">
+    <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 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', 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'"></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="model.reset()">Reset</button>
+	</form>
+</div>
diff --git a/dojox/mvc/tests/mobile/demo/src-async-store.js b/dojox/mvc/tests/mobile/demo/src-async-store.js
new file mode 100644
index 0000000..1c78299
--- /dev/null
+++ b/dojox/mvc/tests/mobile/demo/src-async-store.js
@@ -0,0 +1,137 @@
+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(['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");	
+				});
+	
+		});
+
+dojo.addOnLoad(function() {
+});
+
+}); // end function
+
diff --git a/dojox/mvc/tests/mobile/demo/src-async.js b/dojox/mvc/tests/mobile/demo/src-async.js
new file mode 100644
index 0000000..aebbe4a
--- /dev/null
+++ b/dojox/mvc/tests/mobile/demo/src-async.js
@@ -0,0 +1,167 @@
+var repeatModel, setRef, nextIndexToAdd, selectedIndex;
+var setRef, setDetailsContext, insertResult, updateView, updateModel;
+
+require(['dojo/has',
+	//'dojox/mobile/parser',
+	'dojo/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',
+	'dijit/registry',
+	'dojo/_base/json',
+	'dojo/dom'
+], function(has, parser, mvc, mobile, ScrollableView, Button, TextArea, Group, Generate, Repeat, TextBox, ViewController,
+		FixedSplitter, EdgeToEdgeList, EdgeToEdgeCategory, deviceTheme, RoundRectCategory, Heading, WidgetRegistry,
+		json, dom){
+
+	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.
+
+
+	require(["dojo/ready"], function(ready){
+		//dojox.mobile.parser.parse();
+		//dojo.parser.parse();
+		parser.parse();
+	});
+
+	require(['dojo/domReady!'], function(){
+		//console.log("dom is now ready 2a");
+		dom.byId("wholepage").style.display = "";
+	});
+
+}); // end function
+
diff --git a/dojox/mvc/tests/mobile/demo/src-sync.js b/dojox/mvc/tests/mobile/demo/src-sync.js
new file mode 100644
index 0000000..a63d89b
--- /dev/null
+++ b/dojox/mvc/tests/mobile/demo/src-sync.js
@@ -0,0 +1,148 @@
+dojo.provide("dojox.mvc.tests.mobile.demo.src");
+
+//dojo.require("dojo.parser"); // no longer needed for repeat demo
+dojo.require("dojox.mobile.parser");
+dojo.require("dojox.mobile");
+dojo.require("dojox.mobile.ScrollableView");
+dojo.require("dojox.mobile.TextBox");
+dojo.require("dojox.mvc");
+dojo.require("dojox.mvc.Generate");
+dojo.require("dojox.mvc.Group");
+dojo.require("dojox.mvc.Repeat");
+dojo.require("dojox.mobile.FlippableView");
+dojo.require("dojox.mobile.ViewController");
+dojo.require("dojox.mobile.TextArea");
+dojo.require("dojox.mobile.Button");
+
+dojo.require("dojox.mobile.FixedSplitter");
+dojo.require("dojox.mobile.EdgeToEdgeList");
+dojo.require("dojox.mobile.EdgeToEdgeCategory");
+dojo.require("dojox.mobile.Heading");
+dojo.require("dojox.mobile.FixedSplitterPane");
+dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+dojo.requireIf(!dojo.isWebKit, "dojo.fx");
+dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
+dojo.require("dojox.mobile.deviceTheme"); // used for device detection
+
+
+// Initial data for Ship to - Bill demo
+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"
+	}
+];
+
+var selectedIndex = 0;
+
+var model = dojox.mvc.newStatefulModel({ data : names });
+var repeatmodel = dojox.mvc.newStatefulModel({ data : repeatData });
+var nextIndexToAdd = repeatmodel.data.length;
+
+// used in the Ship to - Bill to demo
+function setRef(id, addrRef) {
+	var widget = dijit.byId(id);
+	widget.set("ref", addrRef);
+}
+
+// used in the Repeat Data binding demo
+function setDetailsContext(index){
+	selectedIndex = index;
+	var groupRoot = dijit.byId("detailsGroup");
+	groupRoot.set("ref", index);
+}
+
+// used in the Repeat Data binding demo
+function insertResult(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;
+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("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);
+	};
+};
+
+function setup() {
+	dojox.mobile.parser.parse();
+};
+
+dojo.ready(setup);
diff --git a/dojox/mvc/tests/mobile/demo/src.js b/dojox/mvc/tests/mobile/demo/src.js
new file mode 100755
index 0000000..787cb6b
--- /dev/null
+++ b/dojox/mvc/tests/mobile/demo/src.js
@@ -0,0 +1,167 @@
+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){
+
+	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
+
diff --git a/dojox/mvc/tests/mobile/test_Android-repeat-data-store.html b/dojox/mvc/tests/mobile/test_Android-repeat-data-store.html
new file mode 100755
index 0000000..a0a736e
--- /dev/null
+++ b/dojox/mvc/tests/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/mobile/test_iPhone-shipto-billto.html b/dojox/mvc/tests/mobile/test_iPhone-shipto-billto.html
new file mode 100755
index 0000000..700caae
--- /dev/null
+++ b/dojox/mvc/tests/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 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/models/LoanWizardModel.js b/dojox/mvc/tests/models/LoanWizardModel.js
new file mode 100755
index 0000000..62314ba
--- /dev/null
+++ b/dojox/mvc/tests/models/LoanWizardModel.js
@@ -0,0 +1,113 @@
+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
new file mode 100755
index 0000000..56fb9e9
--- /dev/null
+++ b/dojox/mvc/tests/module.js
@@ -0,0 +1,31 @@
+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_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);
+}
diff --git a/dojox/mvc/tests/moduleFullSet.js b/dojox/mvc/tests/moduleFullSet.js
new file mode 100644
index 0000000..a83a79a
--- /dev/null
+++ b/dojox/mvc/tests/moduleFullSet.js
@@ -0,0 +1,31 @@
+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/mvc_index.html b/dojox/mvc/tests/mvc_index.html
new file mode 100755
index 0000000..66896c9
--- /dev/null
+++ b/dojox/mvc/tests/mvc_index.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>Dojo MVC Patterns</title>
+		<link type="text/css" href="css/index-format.css" rel="stylesheet"></link>
+	</head>
+	<body>
+		<h1>Dojo MVC Patterns</h1>
+		<h2>Examples</h2>
+		<p>
+			<dl>
+				<dt><a href="test_mvc_shipto-billto-simple.html">Simple data-bound fields</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>
+				<dd>Widgets are nested hierarchically showing relative binding context.</dd>
+
+				<dt><a href="test_mvc_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
+				failures and block flushing the value to the model.  Try driving housing percent above 33% to raise
+				warnings on that field through its model validity as well.  Try zero'ing out all housing
+				expenses to see the effect of relevance=false on the total housing field.</dd>
+
+				<dt><a href="test_mvc_search-results-repeat.html">Repeating templated widget content</a></dt>
+				<dd>Container "repeat" widget expands templated content and provides data binding context to child widgets.</dd>
+
+				<dt><a href="test_mvc_search-results-ins-del.html">Repeating content with insert/delete operations</a></dt>
+				<dd>Above repeat example with mutable list for insert/delete.</dd>
+	
+				<dt><a href="test_mvc_generate-view.html">Model-bound view generation</a></dt>
+				<dd>Form generated based on JSON model provided in a text area and updated based on structural and value changes to the model.</dd>
+			</dl>
+		</p>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/robot/android_repeat-ins.html b/dojox/mvc/tests/robot/android_repeat-ins.html
new file mode 100755
index 0000000..34b04cb
--- /dev/null
+++ b/dojox/mvc/tests/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/robot/iphone_shipto-billto.html b/dojox/mvc/tests/robot/iphone_shipto-billto.html
new file mode 100755
index 0000000..a479fa4
--- /dev/null
+++ b/dojox/mvc/tests/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/robot/mobile-demo-test.html b/dojox/mvc/tests/robot/mobile-demo-test.html
new file mode 100644
index 0000000..0289b85
--- /dev/null
+++ b/dojox/mvc/tests/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('.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
new file mode 100755
index 0000000..4d14245
--- /dev/null
+++ b/dojox/mvc/tests/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/robot/mvc_loan-stateful.html b/dojox/mvc/tests/robot/mvc_loan-stateful.html
new file mode 100755
index 0000000..8855c1c
--- /dev/null
+++ b/dojox/mvc/tests/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/robot/mvc_ref-set-repeat.html b/dojox/mvc/tests/robot/mvc_ref-set-repeat.html
new file mode 100644
index 0000000..4659394
--- /dev/null
+++ b/dojox/mvc/tests/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/robot/mvc_search-results-ins-del.html b/dojox/mvc/tests/robot/mvc_search-results-ins-del.html
new file mode 100755
index 0000000..6fdac2e
--- /dev/null
+++ b/dojox/mvc/tests/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_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
new file mode 100755
index 0000000..fbf92ea
--- /dev/null
+++ b/dojox/mvc/tests/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/robot/mvc_shipto-billto-hierarchical.html b/dojox/mvc/tests/robot/mvc_shipto-billto-hierarchical.html
new file mode 100755
index 0000000..46dd43f
--- /dev/null
+++ b/dojox/mvc/tests/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/robot/mvc_shipto-billto-simple.html b/dojox/mvc/tests/robot/mvc_shipto-billto-simple.html
new file mode 100755
index 0000000..78018dc
--- /dev/null
+++ b/dojox/mvc/tests/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/runTests.html b/dojox/mvc/tests/runTests.html
new file mode 100755
index 0000000..92b5c3b
--- /dev/null
+++ b/dojox/mvc/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?testModule=dojox.mvc.tests.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mvc/tests/runTestsFullSet.html b/dojox/mvc/tests/runTestsFullSet.html
new file mode 100644
index 0000000..305cfcb
--- /dev/null
+++ b/dojox/mvc/tests/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.moduleFullSet"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mvc/tests/test_async-mvc_group-simple.html b/dojox/mvc/tests/test_async-mvc_group-simple.html
new file mode 100644
index 0000000..b4d0279
--- /dev/null
+++ b/dojox/mvc/tests/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/test_async-mvc_input-output-simple.html b/dojox/mvc/tests/test_async-mvc_input-output-simple.html
new file mode 100644
index 0000000..efe2b47
--- /dev/null
+++ b/dojox/mvc/tests/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/test_async-mvc_repeat-simple.html b/dojox/mvc/tests/test_async-mvc_repeat-simple.html
new file mode 100644
index 0000000..e9055bd
--- /dev/null
+++ b/dojox/mvc/tests/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/test_mvc_bindings-simple.html b/dojox/mvc/tests/test_mvc_bindings-simple.html
new file mode 100755
index 0000000..4535d78
--- /dev/null
+++ b/dojox/mvc/tests/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/test_mvc_dates.html b/dojox/mvc/tests/test_mvc_dates.html
new file mode 100644
index 0000000..e402908
--- /dev/null
+++ b/dojox/mvc/tests/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/test_mvc_form-kitchensink.html b/dojox/mvc/tests/test_mvc_form-kitchensink.html
new file mode 100644
index 0000000..1649366
--- /dev/null
+++ b/dojox/mvc/tests/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/test_mvc_generate-view-store.html b/dojox/mvc/tests/test_mvc_generate-view-store.html
new file mode 100755
index 0000000..d63d811
--- /dev/null
+++ b/dojox/mvc/tests/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/test_mvc_generate-view.html b/dojox/mvc/tests/test_mvc_generate-view.html
new file mode 100755
index 0000000..95e0b77
--- /dev/null
+++ b/dojox/mvc/tests/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/test_mvc_input-output-simple.html b/dojox/mvc/tests/test_mvc_input-output-simple.html
new file mode 100755
index 0000000..2531b7a
--- /dev/null
+++ b/dojox/mvc/tests/test_mvc_input-output-simple.html
@@ -0,0 +1,74 @@
+<!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',
+				'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="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/test_mvc_loan-stateful.html b/dojox/mvc/tests/test_mvc_loan-stateful.html
new file mode 100755
index 0000000..9eb9bc9
--- /dev/null
+++ b/dojox/mvc/tests/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/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_programmatic-repeat-store.html b/dojox/mvc/tests/test_mvc_programmatic-repeat-store.html
new file mode 100644
index 0000000..3be7256
--- /dev/null
+++ b/dojox/mvc/tests/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/test_mvc_ref-kitchensink.html b/dojox/mvc/tests/test_mvc_ref-kitchensink.html
new file mode 100755
index 0000000..2726a81
--- /dev/null
+++ b/dojox/mvc/tests/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/test_mvc_ref-set-repeat-simple.html b/dojox/mvc/tests/test_mvc_ref-set-repeat-simple.html
new file mode 100644
index 0000000..7034d80
--- /dev/null
+++ b/dojox/mvc/tests/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/test_mvc_repeat-declarative-sync.html b/dojox/mvc/tests/test_mvc_repeat-declarative-sync.html
new file mode 100755
index 0000000..61e1818
--- /dev/null
+++ b/dojox/mvc/tests/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/test_mvc_repeat-store-declarative-async.html b/dojox/mvc/tests/test_mvc_repeat-store-declarative-async.html
new file mode 100755
index 0000000..9f250c9
--- /dev/null
+++ b/dojox/mvc/tests/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: 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_search-results-ins-del.html b/dojox/mvc/tests/test_mvc_search-results-ins-del.html
new file mode 100755
index 0000000..2b99dd5
--- /dev/null
+++ b/dojox/mvc/tests/test_mvc_search-results-ins-del.html
@@ -0,0 +1,239 @@
+<!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">
+		 <!--
+			 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(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
new file mode 100755
index 0000000..f6191df
--- /dev/null
+++ b/dojox/mvc/tests/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/test_mvc_search-results-repeat.html b/dojox/mvc/tests/test_mvc_search-results-repeat.html
new file mode 100755
index 0000000..6f2dc88
--- /dev/null
+++ b/dojox/mvc/tests/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/test_mvc_shipto-billto-hierarchical.html b/dojox/mvc/tests/test_mvc_shipto-billto-hierarchical.html
new file mode 100755
index 0000000..e903644
--- /dev/null
+++ b/dojox/mvc/tests/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/test_mvc_shipto-billto-simple-declarative.html b/dojox/mvc/tests/test_mvc_shipto-billto-simple-declarative.html
new file mode 100755
index 0000000..723e680
--- /dev/null
+++ b/dojox/mvc/tests/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/test_mvc_shipto-billto-simple-oldparser.html b/dojox/mvc/tests/test_mvc_shipto-billto-simple-oldparser.html
new file mode 100755
index 0000000..d1653d0
--- /dev/null
+++ b/dojox/mvc/tests/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/test_mvc_shipto-billto-simple.html b/dojox/mvc/tests/test_mvc_shipto-billto-simple.html
new file mode 100755
index 0000000..23092ab
--- /dev/null
+++ b/dojox/mvc/tests/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/test_mvc_simple-programmatic.html b/dojox/mvc/tests/test_mvc_simple-programmatic.html
new file mode 100755
index 0000000..7d325b7
--- /dev/null
+++ b/dojox/mvc/tests/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/test_templatedWidget/myMvcTemplated.js b/dojox/mvc/tests/test_templatedWidget/myMvcTemplated.js
new file mode 100644
index 0000000..3ed5040
--- /dev/null
+++ b/dojox/mvc/tests/test_templatedWidget/myMvcTemplated.js
@@ -0,0 +1,22 @@
+/*
+ * 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(){
+			console.log("call myMvcTemplated buildRendering");
+			this.inherited(arguments);
+		},
+		
+        getParent: function(){
+            console.log("Call myMvcTemplated getParent");
+            return null;
+        }
+    });
+});
diff --git a/dojox/mvc/tests/test_templatedWidget/readme.txt b/dojox/mvc/tests/test_templatedWidget/readme.txt
new file mode 100644
index 0000000..d90a6fd
--- /dev/null
+++ b/dojox/mvc/tests/test_templatedWidget/readme.txt
@@ -0,0 +1,3 @@
+1. This directory in dojox/mvc/test/templatedWidget is used to test the exprchar which is need for a custom templated widget. 
+2. test_mvc_widget_template show how to use exprchar in a template for a widget to avoid a problem with ${..} error in repeat data binding.
+3. Use test_mvc_widget.html to see the results.
diff --git a/dojox/mvc/tests/test_templatedWidget/test_mvc_widget.html b/dojox/mvc/tests/test_templatedWidget/test_mvc_widget.html
new file mode 100644
index 0000000..2691854
--- /dev/null
+++ b/dojox/mvc/tests/test_templatedWidget/test_mvc_widget.html
@@ -0,0 +1,78 @@
+<!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>
+	<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>
diff --git a/dojox/mvc/tests/test_templatedWidget/test_mvc_widget_template.html b/dojox/mvc/tests/test_templatedWidget/test_mvc_widget_template.html
new file mode 100644
index 0000000..13b2244
--- /dev/null
+++ b/dojox/mvc/tests/test_templatedWidget/test_mvc_widget_template.html
@@ -0,0 +1,39 @@
+<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>
\ No newline at end of file
diff --git a/dojox/mvc/tests/zips/10024.json b/dojox/mvc/tests/zips/10024.json
new file mode 100755
index 0000000..6952bf4
--- /dev/null
+++ b/dojox/mvc/tests/zips/10024.json
@@ -0,0 +1,12 @@
+{"postalcodes":[
+	{"adminName2":"Manhattan",
+	 "adminCode2":"119",
+	 "postalcode":"10024",
+	 "adminCode1":"NY",
+	 "countryCode":"US",
+	 "lng":-73.862969,
+	 "placeName":"New York",
+	 "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
new file mode 100755
index 0000000..4c242dc
--- /dev/null
+++ b/dojox/mvc/tests/zips/10706.json
@@ -0,0 +1,12 @@
+{"postalcodes":[
+	{"adminName2":"Westchester",
+	 "adminCode2":"119",
+	 "postalcode":"10706",
+	 "adminCode1":"NY",
+	 "countryCode":"US",
+	 "lng":-73.862969,
+	 "placeName":"Hastings On Hudson",
+	 "lat":40.987797,
+	 "adminName1":"New York"
+	}
+]}
\ No newline at end of file
diff --git a/dojox/package.json b/dojox/package.json
new file mode 100644
index 0000000..7a3642f
--- /dev/null
+++ b/dojox/package.json
@@ -0,0 +1,23 @@
+{
+	"name": "dojox",
+	"version":"1.7.2",
+	"directories": {
+		"lib": "."
+	},
+	"main": "main",
+	"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": [
+		 {
+				 "type": "AFLv2.1",
+				 "url": "http://trac.dojotoolkit.org/browser/dojox/trunk/LICENSE#L43"
+		 },
+		 {
+				 "type": "BSD",
+				 "url": "http://trac.dojotoolkit.org/browser/dojox/trunk/LICENSE#L13"
+		 }
+	],
+	"bugs": "http://bugs.dojotoolkit.org/",
+	"keywords": ["JavaScript", "Dojo", "Toolkit", "DojoX"],
+	"homepage": "http://dojotoolkit.org/",
+	"dojoBuild": "dojox.profile.js"
+}
diff --git a/dojox/rails/README b/dojox/rails/README
index 732184a..44c8a32 100644
--- a/dojox/rails/README
+++ b/dojox/rails/README
@@ -21,8 +21,7 @@ Dependencies:
         dojo base
 -------------------------------------------------------------------------------
 Documentation
-        Documentatation will reside at:
-        http://docs.dojocampus.org/dojox/rails
+        Apparently none
 
 -------------------------------------------------------------------------------
 Installation instructions
diff --git a/dojox/rpc/Client.js b/dojox/rpc/Client.js
index f8702e4..8703a13 100644
--- a/dojox/rpc/Client.js
+++ b/dojox/rpc/Client.js
@@ -1,6 +1,9 @@
-define("dojox/rpc/Client", ["dojo"], function(dojo) {
-// Provide extra headers for robust client and server communication
-(function() {
+define("dojox/rpc/Client", ["dojo", "dojox"], function(dojo, dojox) {
+
+	dojo.getObject("rpc.Client", true, dojox);
+
+	// Provide extra headers for robust client and server communication
+
 	dojo._defaultXhr = dojo.xhr;
 	dojo.xhr = function(method,args){
 		var headers = args.headers = args.headers || {};
@@ -16,10 +19,10 @@ define("dojox/rpc/Client", ["dojo"], function(dojo) {
 		headers["Seq-Id"] = dojox._reqSeqId = (dojox._reqSeqId||0)+1;
 		return dojo._defaultXhr.apply(dojo,arguments);
 	}
-})();
-// initiate the client id to a good random number
-dojox.rpc.Client.clientId = (Math.random() + '').substring(2,14) + (new Date().getTime() + '').substring(8,13);
 
-return dojox.rpc.Client;
+	// initiate the client id to a good random number
+	dojox.rpc.Client.clientId = (Math.random() + '').substring(2,14) + (new Date().getTime() + '').substring(8,13);
+
+	return dojox.rpc.Client;
 
 });
diff --git a/dojox/rpc/JsonRest.js b/dojox/rpc/JsonRest.js
index f6f9e70..88231ac 100644
--- a/dojox/rpc/JsonRest.js
+++ b/dojox/rpc/JsonRest.js
@@ -436,10 +436,15 @@ define("dojox/rpc/JsonRest", ["dojo", "dojox", "dojox/json/ref", "dojox/rpc/Rest
 				callback(result);
 			});
 		},
-		isDirty: function(item){
+		isDirty: function(item, store){
 			// summary
 			//		returns true if the item is marked as dirty or true if there are any dirty items
 			if(!item){
+				if(store){
+					return dojo.some(dirtyObjects, function(dirty){
+						return dojox.data._getStoreForItem(dirty.object || dirty.old) == store;
+					});
+				}
 				return !!dirtyObjects.length;
 			}
 			return item.__isDirty;
diff --git a/dojox/rpc/Rest.js b/dojox/rpc/Rest.js
index 8f56fb3..c74107f 100644
--- a/dojox/rpc/Rest.js
+++ b/dojox/rpc/Rest.js
@@ -19,6 +19,9 @@ define("dojox/rpc/Rest", ["dojo", "dojox"], function(dojo, dojox) {
 //  	| 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){
 		// register it as an RPC service if the registry is available
 		dojox.rpc.transportRegistry.register(
diff --git a/dojox/rpc/Service.js b/dojox/rpc/Service.js
index f7c3ae5..79564b5 100644
--- a/dojox/rpc/Service.js
+++ b/dojox/rpc/Service.js
@@ -1,4 +1,4 @@
-define("dojox/rpc/Service", ["dojo", "dojox", "dojo.AdapterRegistry"], function(dojo, dojox) {
+define("dojox/rpc/Service", ["dojo", "dojox", "dojo/AdapterRegistry", "dojo/_base/url"], function(dojo, dojox) {
 
 dojo.declare("dojox.rpc.Service", null, {
 	constructor: function(smd, options){
@@ -111,7 +111,7 @@ dojo.declare("dojox.rpc.Service", null, {
 						delete args[i];
 					}
 				}
-				
+
 			}
 			// setting default values
 			for(i=0; i< parameters.length; i++){
@@ -134,11 +134,11 @@ dojo.declare("dojox.rpc.Service", null, {
 				args = args[0];
 			}
 		}
-		
+
 		if(dojo.isObject(this._options)){
 			args = dojo.mixin(args, this._options);
 		}
-		
+
 		var schema = method._schema || method.returns; // serialize with the right schema for the context;
 		var request = envDef.serialize.apply(this, [smd, method, args]);
 		request._envDef = envDef;// save this for executeMethod
@@ -169,7 +169,7 @@ dojo.declare("dojox.rpc.Service", null, {
 		}
 		var request = this._getRequest(method,args);
 		var deferred = dojox.rpc.transportRegistry.match(request.transport).fire(request);
-		
+
 		deferred.addBoth(function(results){
 			return request._envDef.deserialize.call(this,results);
 		});
diff --git a/dojox/rpc/tests/module.js b/dojox/rpc/tests/module.js
index 0017254..e4c8742 100644
--- a/dojox/rpc/tests/module.js
+++ b/dojox/rpc/tests/module.js
@@ -2,7 +2,7 @@ dojo.provide("dojox.rpc.tests.module");
 
 try{
 	dojo.require("dojox.rpc.tests.Service");
-	dojo.require("dojox.rpc.tests.JsonReferencing");
+	dojo.require("dojox.rpc.tests.stores.JsonRestStore");
 }catch(e){
 	doh.debug(e);
 }
diff --git a/dojox/rpc/tests/stores/JsonRestStore.js b/dojox/rpc/tests/stores/JsonRestStore.js
index 444e268..9e39a50 100644
--- a/dojox/rpc/tests/stores/JsonRestStore.js
+++ b/dojox/rpc/tests/stores/JsonRestStore.js
@@ -1,9 +1,10 @@
-dojo.provide("dojox.data.tests.stores.JsonRestStore");
+dojo.provide("dojox.rpc.tests.stores.JsonRestStore");
+
 dojo.require("dojox.data.JsonRestStore");
 dojo.require("dojo.data.api.Read");
 dojo.require("dojox.rpc.Service");
 
-dojox.data.tests.stores.JsonRestStore.error = function(t, d, errData){
+dojox.rpc.tests.stores.JsonRestStore.error = function(t, d, errData){
 	//  summary:
 	//		The error callback function to be used for all of the tests.
 	d.errback(errData);
@@ -11,7 +12,7 @@ dojox.data.tests.stores.JsonRestStore.error = function(t, d, errData){
 var testServices = new dojox.rpc.Service(dojo.moduleUrl("dojox.rpc.tests.resources", "test.smd"));
 var jsonStore = new dojox.data.JsonRestStore({service:testServices.jsonRestStore});
 
-doh.register("dojox.data.tests.stores.JsonRestStore",
+doh.register("dojox.rpc.tests.stores.JsonRestStore",
 	[
 		{
 			name: "Fetch some items",
@@ -25,7 +26,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 						t.is(4, items.length);
 						d.callback(true);
 					},
-					onError: dojo.partial(dojox.data.tests.stores.JsonRestStore.error, doh, d)});
+					onError: dojo.partial(dojox.rpc.tests.stores.JsonRestStore.error, doh, d)});
 				return d; //Object
 			}
 		},
@@ -44,7 +45,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 						t.t(jsonStore.isItem(item));
 						d.callback(true);
 					},
-					onError: dojo.partial(dojox.data.tests.stores.JsonRestStore.error, doh, d)});
+					onError: dojo.partial(dojox.rpc.tests.stores.JsonRestStore.error, doh, d)});
 				return d; //Object
 			}
 		},
@@ -71,9 +72,9 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 								t.is(item.obj, item['obj dup']);
 								d.callback(true);
 							},
-							onError: dojo.partial(dojox.data.tests.stores.JsonRestStore.error, doh, d)});
+							onError: dojo.partial(dojox.rpc.tests.stores.JsonRestStore.error, doh, d)});
 					},
-					onError: dojo.partial(dojox.data.tests.stores.JsonRestStore.error, doh, d)});
+					onError: dojo.partial(dojox.rpc.tests.stores.JsonRestStore.error, doh, d)});
 				return d; //Object
 			}
 		},
@@ -99,7 +100,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 						jsonStore.save();
 						d.callback(true);
 					},
-					onError: dojo.partial(dojox.data.tests.stores.JsonRestStore.error, doh, d)});
+					onError: dojo.partial(dojox.rpc.tests.stores.JsonRestStore.error, doh, d)});
 				return d; //Object
 			}
 		},
@@ -124,7 +125,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 						t.t(typeof jsonStore.getValue(item,"updated") == 'number');
 						d.callback(true);
 					},
-					onError: dojo.partial(dojox.data.tests.stores.JsonRestStore.error, doh, d)});
+					onError: dojo.partial(dojox.rpc.tests.stores.JsonRestStore.error, doh, d)});
 				return d; //Object
 			}
 		},
@@ -144,7 +145,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 							d.callback(true);
 						});
 					},
-					onError: dojo.partial(dojox.data.tests.stores.JsonRestStore.error, doh, d)});
+					onError: dojo.partial(dojox.rpc.tests.stores.JsonRestStore.error, doh, d)});
 				return d; //Object
 			}
 		},
@@ -167,7 +168,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 						};
 						jsonStore.save();
 					},
-					onError: dojo.partial(dojox.data.tests.stores.JsonRestStore.error, doh, d)});
+					onError: dojo.partial(dojox.rpc.tests.stores.JsonRestStore.error, doh, d)});
 				return d; //Object
 			}
 		},
@@ -199,7 +200,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 					count: 5,
 					onItem: onItem,
 					onComplete: onComplete,
-					onError: dojo.partial(dojox.data.tests.stores.JsonRestStore.error, t, d)
+					onError: dojo.partial(dojox.rpc.tests.stores.JsonRestStore.error, t, d)
 				});
 				return d; //Object
 			}
diff --git a/dojox/secure/capability.js b/dojox/secure/capability.js
index afb4ded..35cbdd6 100644
--- a/dojox/secure/capability.js
+++ b/dojox/secure/capability.js
@@ -41,7 +41,7 @@ dojox.secure.capability = {
 			// now clear line comments, block comments, regular expressions, and strings.
 			// By doing it all at once, the regular expression uses left to right parsing, and the most
 			// left token is read first. It is also more compact.
-			replace(/\/\/.*|\/\*[\w\W]*?\*\/|\/(\\[\/\\]|[^*\/])(\\.|[^\/\n\\])*\/[gim]*|("[^"]*")|('[^']*')/g,function(t) {
+			replace(/\/\/.*|\/\*[\w\W]*?\*\/|("[^"]*")|('[^']*')/g,function(t) {
 				return t.match(/^\/\/|^\/\*/) ? ' ' : '0'; // comments are replaced with a space, strings and regex are replaced with a single safe token (0)
 			}).
 			replace(/\.\s*([a-z\$_A-Z][\w\$_]*)|([;,{])\s*([a-z\$_A-Z][\w\$_]*\s*):/g,function(t,prop,prefix,key) {
diff --git a/dojox/secure/sandbox.js b/dojox/secure/sandbox.js
index 4d2196d..033abe2 100644
--- a/dojox/secure/sandbox.js
+++ b/dojox/secure/sandbox.js
@@ -2,6 +2,7 @@ dojo.provide("dojox.secure.sandbox");
 dojo.require("dojox.secure.DOM");
 dojo.require("dojox.secure.capability");
 dojo.require("dojo.NodeList-fx");
+dojo.require("dojo._base.url");
 
 (function() {
 	var oldTimeout = setTimeout;
@@ -173,7 +174,7 @@ dojo.require("dojo.NodeList-fx");
 					proto = new F;
 				}
 			}
-	
+
 			if(arg) { // the next object should be the properties
 				// apply binding checking on all the functions
 				for (var j in arg) {
@@ -238,7 +239,7 @@ dojo.require("dojo.NodeList-fx");
 			//if(!alreadyValidated) {
 			dojox.secure.capability.validate(script,safeCalls, // the safe dojo library and standard operators
 											{document:1,element:1}); // these are secured DOM starting points
-		
+
 			//}
 			if(script.match(/^\s*[\[\{]/)) {
 				var result = eval('(' + script + ')');
@@ -270,7 +271,7 @@ dojo.require("dojo.NodeList-fx");
 				//
 				//	url:
 				//		The url of the web page to load
-				
+
 				wrap.rootUrl = url;
 				return xhrGet({url:url,secure:true}).addCallback(function(result){
 					element.innerHTML = result;
diff --git a/dojox/secure/tests/fromJson.js b/dojox/secure/tests/fromJson.js
index 4bd08e9..9fde27f 100644
--- a/dojox/secure/tests/fromJson.js
+++ b/dojox/secure/tests/fromJson.js
@@ -1,6 +1,6 @@
 dojo.provide("dojox.secure.tests.fromJson");
+
 dojo.require("dojox.secure.fromJson");
-dojo.require("dojox.secure.tests.otherParsers");
 
 var smallDataSet = {
 	prop1: null,
diff --git a/dojox/secure/tests/sandbox.js b/dojox/secure/tests/sandbox.js
index 7d09d17..9995fbd 100644
--- a/dojox/secure/tests/sandbox.js
+++ b/dojox/secure/tests/sandbox.js
@@ -1,7 +1,6 @@
-dojo.provide("dojox.secure.tests.secure");
-dojo.require("dojox.secure.secure");
+dojo.provide("dojox.secure.tests.sandbox");
 
-doh.register("dojox.secure.tests.secure.good",
+doh.register("dojox.secure.tests.sandbox.good",
 	[
 		function setup(){
 			var div = document.createElement("div");
@@ -40,7 +39,7 @@ function violater(func) {
 		t.f(insecure);
 	}};
 }
-doh.register("dojox.secure.tests.secure.bad",
+doh.register("dojox.secure.tests.sandbox.bad",
 	[
 		function parentNode(t){
 			t.f(dojox.secure.evaluate("document.body",container));
diff --git a/dojox/sketch.js b/dojox/sketch.js
index f05405e..0fd903c 100644
--- a/dojox/sketch.js
+++ b/dojox/sketch.js
@@ -1,5 +1,11 @@
-dojo.provide("dojox.sketch");
-dojo.require("dojox.xml.DomParser");
-dojo.require("dojox.sketch.UndoStack");
-dojo.require("dojox.sketch.Figure");
-dojo.require("dojox.sketch.Toolbar");
\ No newline at end of file
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang", 
+	"./xml/DomParser", 
+	"./sketch/UndoStack", 
+	"./sketch/Figure", 
+	"./sketch/Toolbar"
+], function(dojo){
+	dojo.getObject("sketch", true, dojox);
+	return dojox.sketch;
+});
diff --git a/dojox/sketch/Anchor.js b/dojox/sketch/Anchor.js
index 66518f7..3a22544 100644
--- a/dojox/sketch/Anchor.js
+++ b/dojox/sketch/Anchor.js
@@ -1,9 +1,11 @@
-dojo.provide("dojox.sketch.Anchor");
-dojo.require("dojox.gfx");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"../gfx"
+], function(dojo){
+	dojo.getObject("sketch", true, dojox);
 
-(function(){
-	var ta=dojox.sketch;
-	ta.Anchor=function(an, id, isControl){
+	dojox.sketch.Anchor=function(an, id, isControl){
 		var self=this;
 		var size=4;	//	.5 * size of anchor.
 		var rect=null;
@@ -12,12 +14,12 @@ dojo.require("dojox.gfx");
 		this.annotation=an;
 
 		this.id=id;
-		this._key="anchor-" + ta.Anchor.count++;
+		this._key="anchor-" + dojox.sketch.Anchor.count++;
 		this.shape=null;
 		this.isControl=(isControl!=null)?isControl:true;
 
 		this.beginEdit=function(){
-			this.annotation.beginEdit(ta.CommandTypes.Modify);
+			this.annotation.beginEdit(dojox.sketch.CommandTypes.Modify);
 		};
 		this.endEdit=function(){
 			this.annotation.endEdit();
@@ -62,5 +64,6 @@ dojo.require("dojox.gfx");
 			rect=null;
 		};
 	};
-	ta.Anchor.count=0;
-})();
+	dojox.sketch.Anchor.count=0;
+	return dojox.sketch.Anchor;
+});
diff --git a/dojox/sketch/Annotation.js b/dojox/sketch/Annotation.js
index 0616c3b..23d76dd 100644
--- a/dojox/sketch/Annotation.js
+++ b/dojox/sketch/Annotation.js
@@ -1,10 +1,12 @@
-dojo.provide("dojox.sketch.Annotation");
-dojo.require("dojox.sketch.Anchor");
-dojo.require("dojox.sketch._Plugin");
-
-(function(){
-	var ta=dojox.sketch;
-	dojo.declare("dojox.sketch.AnnotationTool", ta._Plugin, {
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dojo/_base/json",
+	"./Anchor",
+	"./_Plugin"
+], function(dojo){
+	dojo.declare("dojox.sketch.AnnotationTool", dojox.sketch._Plugin, {
 		onMouseDown: function(e){
 			this._omd=true;
 		},
@@ -68,19 +70,19 @@ dojo.require("dojox.sketch._Plugin");
 			a.initialize();
 			f.select(a);
 			f.onCreateShape(a);
-			f.history.add(ta.CommandTypes.Create,a);
+			f.history.add(dojox.sketch.CommandTypes.Create,a);
 		}
 	});
 
-	ta.Annotation=function(figure, id){
+	dojox.sketch.Annotation=function(figure, id){
 		//	for editing stuff.
 		this.id=this._key=id;
 		this.figure=figure;
-		this.mode=ta.Annotation.Modes.View;
+		this.mode=dojox.sketch.Annotation.Modes.View;
 		this.shape=null;	// dojox.gfx.Group
 		this.boundingBox=null;	// rect for boundaries
 		this.hasAnchors=true;
-		this.anchors={};	//	ta.Anchor
+		this.anchors={};	//	dojox.sketch.Anchor
 		this._properties={
 			'stroke':{ color:"blue", width:2 },
 			'font': {family:"Arial", size:16, weight:"bold"},
@@ -93,13 +95,13 @@ dojo.require("dojox.sketch._Plugin");
 		}
 	};
 
-	var p=ta.Annotation.prototype;
-	p.constructor=ta.Annotation;
+	var p=dojox.sketch.Annotation.prototype;
+	p.constructor=dojox.sketch.Annotation;
 	p.type=function(){ return ''; };
-	p.getType=function(){ return ta.Annotation; };
+	p.getType=function(){ return dojox.sketch.Annotation; };
 	p.onRemove=function(noundo){
 		//this.figure._delete([this],noundo);
-		this.figure.history.add(ta.CommandTypes.Delete, this, this.serialize());
+		this.figure.history.add(dojox.sketch.CommandTypes.Delete, this, this.serialize());
 	};
 	p.property=function(name,/*?*/value){
 		var r;
@@ -117,12 +119,12 @@ dojo.require("dojox.sketch._Plugin");
 	};
 	p.onPropertyChange=function(name,oldvalue){};
 	p.onCreate=function(){
-		this.figure.history.add(ta.CommandTypes.Create,this);
+		this.figure.history.add(dojox.sketch.CommandTypes.Create,this);
 	}
 	p.onDblClick=function(e){
 		var l=prompt('Set new text:',this.property('label'));
 		if(l!==false){
-			this.beginEdit(ta.CommandTypes.Modify);
+			this.beginEdit(dojox.sketch.CommandTypes.Modify);
 			this.property('label',l);
 			this.draw();
 			this.endEdit();
@@ -136,7 +138,7 @@ dojo.require("dojox.sketch._Plugin");
 	p.getBBox=function(){ };
 	p.beginEdit=function(type){
 		if(!this._type){
-			this._type=type||ta.CommandTypes.Move;
+			this._type=type||dojox.sketch.CommandTypes.Move;
 			this._prevState=this.serialize();
 		}
 	};
@@ -193,7 +195,7 @@ dojo.require("dojox.sketch._Plugin");
 		if(this.mode==m){ return; }
 		this.mode=m;
 		var method="disable";
-		if(m==ta.Annotation.Modes.Edit){ method="enable"; }
+		if(m==dojox.sketch.Annotation.Modes.Edit){ method="enable"; }
 		if(method=="enable"){
 			//	draw the bounding box
 			this.drawBBox();
@@ -257,15 +259,17 @@ dojo.require("dojox.sketch._Plugin");
 			this.transform.dy=parseFloat(pt[1],10);
 		}
 	};
-	ta.Annotation.Modes={ View:0, Edit:1 };
-	ta.Annotation.register=function(name,toolclass){
-		var cls=ta[name+'Annotation'];
-		ta.registerTool(name, function(p){
+	dojox.sketch.Annotation.Modes={ View:0, Edit:1 };
+	dojox.sketch.Annotation.register=function(name,toolclass){
+		var cls=dojox.sketch[name+'Annotation'];
+		dojox.sketch.registerTool(name, function(p){
 			dojo.mixin(p, {
 				shape: name,
 				annotation:cls
 			});
-			return new (toolclass || ta.AnnotationTool)(p);
+			return new (toolclass || dojox.sketch.AnnotationTool)(p);
 		});
 	};
-})();
+
+	return dojox.sketch.Annotation;
+});
diff --git a/dojox/sketch/DoubleArrowAnnotation.js b/dojox/sketch/DoubleArrowAnnotation.js
index 4048e3d..c5d7050 100644
--- a/dojox/sketch/DoubleArrowAnnotation.js
+++ b/dojox/sketch/DoubleArrowAnnotation.js
@@ -1,10 +1,7 @@
-dojo.provide("dojox.sketch.DoubleArrowAnnotation");
-
-dojo.require("dojox.sketch.Annotation");
-dojo.require("dojox.sketch.Anchor");
-
-(function(){
+define(["dojo/_base/kernel", "dojo/_base/lang", "./Annotation", "./Anchor"], function(dojo){
+	dojo.getObject("sketch", true, dojox);
 	var ta=dojox.sketch;
+	console.log(ta);
 	ta.DoubleArrowAnnotation=function(figure, id){
 		ta.Annotation.call(this, figure, id);
 		this.transform={ dx:0, dy:0 };
@@ -231,4 +228,5 @@ dojo.require("dojox.sketch.Anchor");
 	};
 
 	ta.Annotation.register("DoubleArrow");
-})();
+	return dojox.sketch.DoubleArrowAnnotation;
+});
diff --git a/dojox/sketch/Figure.js b/dojox/sketch/Figure.js
index 437ed3c..358a232 100644
--- a/dojox/sketch/Figure.js
+++ b/dojox/sketch/Figure.js
@@ -1,10 +1,14 @@
-dojo.provide("dojox.sketch.Figure");
-dojo.experimental("dojox.sketch");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/connect",
+	"dojo/_base/html",
+	"../gfx",
+	"../xml/DomParser",
+	"./UndoStack"
+], function(dojo){
+	dojo.experimental("dojox.sketch");
 
-dojo.require("dojox.gfx");
-dojo.require("dojox.sketch.UndoStack");
-
-(function(){
 	var ta=dojox.sketch;
 	ta.tools={};
 	ta.registerTool=function(type, fn){ ta.tools[type]=fn; };
@@ -523,4 +527,6 @@ dojo.require("dojox.sketch.UndoStack");
 		return s;
 	};
 	p.getValue=p.serialize;
-})();
+
+	return dojox.sketch.Figure;
+});
diff --git a/dojox/sketch/LeadAnnotation.js b/dojox/sketch/LeadAnnotation.js
index f9a88ef..12f366f 100644
--- a/dojox/sketch/LeadAnnotation.js
+++ b/dojox/sketch/LeadAnnotation.js
@@ -1,8 +1,6 @@
-dojo.provide("dojox.sketch.LeadAnnotation");
-dojo.require("dojox.sketch.Annotation");
-dojo.require("dojox.sketch.Anchor");
+define(["dojo/_base/kernel", "dojo/_base/lang", "./Annotation", "./Anchor"], function(dojo){
+	dojo.getObject("sketch", true, dojox);
 
-(function(){
 	var ta=dojox.sketch;
 	ta.LeadAnnotation=function(figure, id){
 		ta.Annotation.call(this, figure, id);
@@ -159,4 +157,5 @@ dojo.require("dojox.sketch.Anchor");
 	};
 
 	ta.Annotation.register("Lead");
-})();
+	return dojox.sketch.LeadAnnotation;
+});
diff --git a/dojox/sketch/PreexistingAnnotation.js b/dojox/sketch/PreexistingAnnotation.js
index 330f5f5..7949285 100644
--- a/dojox/sketch/PreexistingAnnotation.js
+++ b/dojox/sketch/PreexistingAnnotation.js
@@ -1,9 +1,6 @@
-dojo.provide("dojox.sketch.PreexistingAnnotation");
+define(["dojo/_base/kernel", "dojo/_base/lang", "./Annotation", "./Anchor"], function(dojo){
+	dojo.getObject("sketch", true, dojox);
 
-dojo.require("dojox.sketch.Annotation");
-dojo.require("dojox.sketch.Anchor");
-
-(function(){
 	var ta=dojox.sketch;
 	ta.PreexistingAnnotation=function(figure, id){
 		ta.Annotation.call(this, figure, id);
@@ -162,4 +159,5 @@ dojo.require("dojox.sketch.Anchor");
 	};
 
 	ta.Annotation.register("Preexisting");
-})();
+	return dojox.sketch.PreexistingAnnotation;
+});
diff --git a/dojox/sketch/SingleArrowAnnotation.js b/dojox/sketch/SingleArrowAnnotation.js
index 0a883a2..9409069 100644
--- a/dojox/sketch/SingleArrowAnnotation.js
+++ b/dojox/sketch/SingleArrowAnnotation.js
@@ -1,8 +1,6 @@
-dojo.provide("dojox.sketch.SingleArrowAnnotation");
-dojo.require("dojox.sketch.Annotation");
-dojo.require("dojox.sketch.Anchor");
+define(["dojo/_base/kernel", "dojo/_base/lang", "./Annotation", "./Anchor"], function(dojo){
+	dojo.getObject("sketch", true, dojox);
 
-(function(){
 	var ta=dojox.sketch;
 	ta.SingleArrowAnnotation=function(figure, id){
 		ta.Annotation.call(this, figure, id);
@@ -224,4 +222,5 @@ dojo.require("dojox.sketch.Anchor");
 	};
 
 	ta.Annotation.register("SingleArrow");
-})();
+	return dojox.sketch.SingleArrowAnnotation;
+});
diff --git a/dojox/sketch/Slider.js b/dojox/sketch/Slider.js
index fa8b8ef..f5cfc3a 100644
--- a/dojox/sketch/Slider.js
+++ b/dojox/sketch/Slider.js
@@ -1,36 +1,42 @@
-dojo.provide("dojox.sketch.Slider");
-
-dojo.require("dijit.form.HorizontalSlider");
-
-dojo.declare("dojox.sketch.Slider",dojox.sketch._Plugin,{
-	_initButton: function(){
-		this.slider=new dijit.form.HorizontalSlider({minimum:5,maximum:100,style:"width:100px;",baseClass:'dijitInline dijitSlider'});
-		this.slider._movable.node.title='Double Click to "Zoom to Fit"'; //I18N
-		this.connect(this.slider,'onChange','_setZoom');
-		this.connect(this.slider.sliderHandle,'ondblclick','_zoomToFit');
-	},
-	_zoomToFit: function(){
-		var r=this.figure.getFit();
-		this.slider.attr('value',this.slider.maximum<r?this.slider.maximum:(this.slider.minimum>r?this.slider.minimum:r));
-	},
-	_setZoom: function(v){
-		if(v && this.figure){
-			this.figure.zoom(v);
-		}
-	},
-	reset: function(){
-		//reset slider to maximum so that onChange will be fired when _zoomToFit is called
-		this.slider.attr('value',this.slider.maximum);
-		this._zoomToFit();
-	},
-	setToolbar: function(t){
-		this._initButton();
-		t.addChild(this.slider);
-		if(!t._reset2Zoom){
-			t._reset2Zoom=true;
-			this.connect(t,'reset','reset');
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dijit/form/HorizontalSlider",
+	"./_Plugin"
+], function(dojo){
+	dojo.getObject("sketch", true, dojox);
+	dojo.declare("dojox.sketch.Slider", dojox.sketch._Plugin,{
+		_initButton: function(){
+			this.slider=new dijit.form.HorizontalSlider({minimum:5,maximum:100,style:"width:100px;",baseClass:'dijitInline dijitSlider'});
+			this.slider._movable.node.title='Double Click to "Zoom to Fit"'; //I18N
+			this.connect(this.slider,'onChange','_setZoom');
+			this.connect(this.slider.sliderHandle,'ondblclick','_zoomToFit');
+		},
+		_zoomToFit: function(){
+			var r=this.figure.getFit();
+			this.slider.attr('value',this.slider.maximum<r?this.slider.maximum:(this.slider.minimum>r?this.slider.minimum:r));
+		},
+		_setZoom: function(v){
+			if(v && this.figure){
+				this.figure.zoom(v);
+			}
+		},
+		reset: function(){
+			//reset slider to maximum so that onChange will be fired when _zoomToFit is called
+			this.slider.attr('value',this.slider.maximum);
+			this._zoomToFit();
+		},
+		setToolbar: function(t){
+			this._initButton();
+			t.addChild(this.slider);
+			if(!t._reset2Zoom){
+				t._reset2Zoom=true;
+				this.connect(t,'reset','reset');
+			}
 		}
-	}
-});
+	});
 
-dojox.sketch.registerTool("Slider", dojox.sketch.Slider);
+	dojox.sketch.registerTool("Slider", dojox.sketch.Slider);
+	return dojox.sketch.Slider;
+});
diff --git a/dojox/sketch/Toolbar.js b/dojox/sketch/Toolbar.js
index c5cc851..99262d2 100644
--- a/dojox/sketch/Toolbar.js
+++ b/dojox/sketch/Toolbar.js
@@ -1,97 +1,103 @@
-dojo.provide("dojox.sketch.Toolbar");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"./Annotation",
+	"dijit/Toolbar",
+	"dijit/form/Button"
+], function(dojo){
+	dojo.getObject("sketch", true, dojox);
+	dojo.declare("dojox.sketch.ButtonGroup", null, {
+		constructor: function(){
+			this._childMaps={};
+			this._children=[];
+		},
+		add: function(/*_Plugin*/ plugin){
+			this._childMaps[plugin]=plugin.connect(plugin,'onActivate',dojo.hitch(this,'_resetGroup',plugin));
+			this._children.push(plugin);
+		},
+	//	remove: function(/*_Plugin*/ plugin){
+	//		widget.disconnect(this._childMaps[widget.id]);
+	//		delete this._childMaps[widget.id];
+	//		this._children.splice(this._children.indexOf(widget.id),1);
+	//	},
+		_resetGroup: function(p){
+			var cs=this._children;
+			dojo.forEach(cs,function(c){
+				if(p!=c && c['attr']){
+					c.attr('checked',false);
+				}
+			});
+		}
+	});
 
-dojo.require("dojox.sketch.Annotation");
-dojo.require("dijit.Toolbar");
-dojo.require("dijit.form.Button");
+	dojo.declare("dojox.sketch.Toolbar", dijit.Toolbar, {
+		figure: null,
+		plugins: null,
+		postCreate: function(){
+			this.inherited(arguments);
+			this.shapeGroup=new dojox.sketch.ButtonGroup;
 
-dojo.declare("dojox.sketch.ButtonGroup", null, {
-	constructor: function(){
-		this._childMaps={};
-		this._children=[];
-	},
-	add: function(/*_Plugin*/ plugin){
-		this._childMaps[plugin]=plugin.connect(plugin,'onActivate',dojo.hitch(this,'_resetGroup',plugin));
-		this._children.push(plugin);
-	},
-//	remove: function(/*_Plugin*/ plugin){
-//		widget.disconnect(this._childMaps[widget.id]);
-//		delete this._childMaps[widget.id];
-//		this._children.splice(this._children.indexOf(widget.id),1);
-//	},
-	_resetGroup: function(p){
-		var cs=this._children;
-		dojo.forEach(cs,function(c){
-			if(p!=c && c['attr']){
-				c.attr('checked',false);
+			if(!this.plugins){
+				this.plugins=['Lead','SingleArrow','DoubleArrow','Underline','Preexisting','Slider'];
 			}
-		});
-	}
-});
-
-dojo.declare("dojox.sketch.Toolbar", dijit.Toolbar, {
-	figure: null,
-	plugins: null,
-	postCreate: function(){
-		this.inherited(arguments);
-		this.shapeGroup=new dojox.sketch.ButtonGroup;
-
-		if(!this.plugins){
-			this.plugins=['Lead','SingleArrow','DoubleArrow','Underline','Preexisting','Slider'];
-		}
-		this._plugins=[];
+			this._plugins=[];
 
-		dojo.forEach(this.plugins,function(obj){
-			var name=dojo.isString(obj)?obj:obj.name;
-			var p=new dojox.sketch.tools[name](obj.args||{});
-			this._plugins.push(p);
-			p.setToolbar(this);
-			if(!this._defaultTool && p.button){
-				this._defaultTool=p;
+			dojo.forEach(this.plugins,function(obj){
+				var name=dojo.isString(obj)?obj:obj.name;
+				var p=new dojox.sketch.tools[name](obj.args||{});
+				this._plugins.push(p);
+				p.setToolbar(this);
+				if(!this._defaultTool && p.button){
+					this._defaultTool=p;
+				}
+			},this);
+		},
+		setFigure: function(f){
+			this.figure = f;
+			this.connect(f,'onLoad','reset');
+			dojo.forEach(this._plugins, function(p){
+				p.setFigure(f);
+			});
+		},
+		destroy: function(){
+			dojo.forEach(this._plugins,function(p){
+				p.destroy();
+			});
+			this.inherited(arguments);
+			delete this._defaultTool;
+			delete this._plugins;
+		},
+		addGroupItem: function(/*_Plugin*/item,group){
+			if(group!='toolsGroup'){
+				console.error('not supported group '+group);
+				return;
 			}
-		},this);
-	},
-	setFigure: function(f){
-		this.figure = f;
-		this.connect(f,'onLoad','reset');
-		dojo.forEach(this._plugins, function(p){
-			p.setFigure(f);
-		});
-	},
-	destroy: function(){
-		dojo.forEach(this._plugins,function(p){
-			p.destroy();
-		});
-		this.inherited(arguments);
-		delete this._defaultTool;
-		delete this._plugins;
-	},
-	addGroupItem: function(/*_Plugin*/item,group){
-		if(group!='toolsGroup'){
-			console.error('not supported group '+group);
-			return;
-		}
 
-		this.shapeGroup.add(item);
-	},
-	reset: function(){
-		this._defaultTool.activate();
-	},
-	_setShape: function(s){
-		if(!this.figure.surface) return;
-		//	now do the action.
-		if(this.figure.hasSelections()){
-			for(var i=0; i<this.figure.selected.length; i++){
-				var before=this.figure.selected[i].serialize();
-				this.figure.convert(this.figure.selected[i], s);
-				this.figure.history.add(dojox.sketch.CommandTypes.Convert, this.figure.selected[i], before);
+			this.shapeGroup.add(item);
+		},
+		reset: function(){
+			this._defaultTool.activate();
+		},
+		_setShape: function(s){
+			if(!this.figure.surface) return;
+			//	now do the action.
+			if(this.figure.hasSelections()){
+				for(var i=0; i<this.figure.selected.length; i++){
+					var before=this.figure.selected[i].serialize();
+					this.figure.convert(this.figure.selected[i], s);
+					this.figure.history.add(dojox.sketch.CommandTypes.Convert, this.figure.selected[i], before);
+				}
 			}
 		}
-	}
-});
+	});
 
-dojox.sketch.makeToolbar=function(node,figure){
-	var toolbar=new dojox.sketch.Toolbar();
-	toolbar.setFigure(figure);
-	node.appendChild(toolbar.domNode);
-	return toolbar;
-};
+	dojox.sketch.makeToolbar=function(node,figure){
+		var toolbar=new dojox.sketch.Toolbar();
+		toolbar.setFigure(figure);
+		node.appendChild(toolbar.domNode);
+		return toolbar;
+	};
+
+	return dojox.sketch.Toolbar;
+});
diff --git a/dojox/sketch/UnderlineAnnotation.js b/dojox/sketch/UnderlineAnnotation.js
index 95b4725..e80ab9e 100644
--- a/dojox/sketch/UnderlineAnnotation.js
+++ b/dojox/sketch/UnderlineAnnotation.js
@@ -1,8 +1,4 @@
-dojo.provide("dojox.sketch.UnderlineAnnotation");
-dojo.require("dojox.sketch.Annotation");
-dojo.require("dojox.sketch.Anchor");
-
-(function(){
+define(["./Annotation", "./Anchor"], function(){
 	var ta=dojox.sketch;
 	ta.UnderlineAnnotation=function(figure, id){
 		ta.Annotation.call(this, figure, id);
@@ -144,4 +140,5 @@ dojo.require("dojox.sketch.Anchor");
 		onMouseMove: function(){}
 	});
 	ta.Annotation.register("Underline", ta.UnderlineAnnotationTool);
-})();
+	return dojox.sketch.UnderlineAnnotation;
+});
diff --git a/dojox/sketch/UndoStack.js b/dojox/sketch/UndoStack.js
index 150dd0b..4d124c6 100644
--- a/dojox/sketch/UndoStack.js
+++ b/dojox/sketch/UndoStack.js
@@ -1,7 +1,10 @@
-dojo.provide("dojox.sketch.UndoStack");
-dojo.require("dojox.xml.DomParser");
-
-(function(){
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"../xml/DomParser"
+], function(dojo){
+	dojo.getObject("sketch", true, dojox);
 	var ta=dojox.sketch;
 	ta.CommandTypes={ Create:"Create", Move:"Move", Modify:"Modify", Delete:"Delete", Convert:"Convert"};
 
@@ -97,4 +100,6 @@ dojo.require("dojox.xml.DomParser");
 			}
 		}
 	});
-})();
+
+	return dojox.sketch.UndoStack;
+});
diff --git a/dojox/sketch/_Plugin.js b/dojox/sketch/_Plugin.js
index c3777c4..5d01ae9 100644
--- a/dojox/sketch/_Plugin.js
+++ b/dojox/sketch/_Plugin.js
@@ -1,74 +1,81 @@
-dojo.provide("dojox.sketch._Plugin");
-//dojo.require("dojox.sketch");
-dojo.require("dijit.form.Button");
-
-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){
-		if(args){
-			dojo.mixin(this, args);
-		}
-		this._connects=[];
-	},
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/connect",
+	"dijit/form/ToggleButton"
+], function(dojo){
+	dojo.getObject("sketch", true, dojox);
+	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){
+			if(args){
+				dojo.mixin(this, args);
+			}
+			this._connects=[];
+		},
 
-	figure: null,
-	iconClassPrefix: "dojoxSketchIcon",
-	itemGroup: 'toolsGroup',
-	button: null,
-	queryCommand: null,
-	shape: "",
-	useDefaultCommand: true,
-	buttonClass: dijit.form.ToggleButton,
-	_initButton: function(){
-		if(this.shape.length){
-			//TODO: i18n
-//			var label = dojox.sketch.shapes[this.shape];
-			var className = this.iconClassPrefix+" "+this.iconClassPrefix + this.shape.charAt(0).toUpperCase() + this.shape.substr(1);
-			if(!this.button){
-				var props = {
-					label: this.shape, //I18N
-					showLabel: false,
-					iconClass: className,
-					dropDown: this.dropDown,
-					tabIndex: "-1"
-				};
-				this.button = new this.buttonClass(props);
-				this.connect(this.button,'onClick','activate');
+		figure: null,
+		iconClassPrefix: "dojoxSketchIcon",
+		itemGroup: 'toolsGroup',
+		button: null,
+		queryCommand: null,
+		shape: "",
+		useDefaultCommand: true,
+		buttonClass: dijit.form.ToggleButton,
+		_initButton: function(){
+			if(this.shape.length){
+				//TODO: i18n
+	//			var label = dojox.sketch.shapes[this.shape];
+				var className = this.iconClassPrefix+" "+this.iconClassPrefix + this.shape.charAt(0).toUpperCase() + this.shape.substr(1);
+				if(!this.button){
+					var props = {
+						label: this.shape, //I18N
+						showLabel: false,
+						iconClass: className,
+						dropDown: this.dropDown,
+						tabIndex: "-1"
+					};
+					this.button = new this.buttonClass(props);
+					this.connect(this.button,'onClick','activate');
+				}
+			}
+		},
+		attr: function(name,/*?*/value){
+			return this.button.attr(name,value);
+		},
+		onActivate: function(){},
+		activate: function(/*?*/e){
+			this.onActivate();
+			this.figure.setTool(this);
+			this.attr('checked',true);
+		},
+		onMouseDown: function(e){},
+		onMouseMove: function(e){},
+		onMouseUp: function(e){},
+		destroy: function(f){
+			dojo.forEach(this._connects,dojo.disconnect);
+		},
+		connect: function(o,f,tf){
+			this._connects.push(dojo.connect(o,f,this,tf));
+		},
+		setFigure: function(/*dijit._Widget*/ figure){
+			// FIXME: detatch from previous figure!!
+			this.figure = figure;
+		},
+		setToolbar: function(/*dijit._Widget*/ toolbar){
+			// FIXME: prevent creating this if we don't need to (i.e., figure can't handle our command)
+			this._initButton();
+			if(this.button){
+				toolbar.addChild(this.button);
+			}
+			if(this.itemGroup){
+				toolbar.addGroupItem(this,this.itemGroup);
 			}
 		}
-	},
-	attr: function(name,/*?*/value){
-		return this.button.attr(name,value);
-	},
-	onActivate: function(){},
-	activate: function(/*?*/e){
-		this.onActivate();
-		this.figure.setTool(this);
-		this.attr('checked',true);
-	},
-	onMouseDown: function(e){},
-	onMouseMove: function(e){},
-	onMouseUp: function(e){},
-	destroy: function(f){
-		dojo.forEach(this._connects,dojo.disconnect);
-	},
-	connect: function(o,f,tf){
-		this._connects.push(dojo.connect(o,f,this,tf));
-	},
-	setFigure: function(/*dijit._Widget*/ figure){
-		// FIXME: detatch from previous figure!!
-		this.figure = figure;
-	},
-	setToolbar: function(/*dijit._Widget*/ toolbar){
-		// FIXME: prevent creating this if we don't need to (i.e., figure can't handle our command)
-		this._initButton();
-		if(this.button){
-			toolbar.addChild(this.button);
-		}
-		if(this.itemGroup){
-			toolbar.addGroupItem(this,this.itemGroup);
-		}
-	}
+	});
+	return dojox.sketch._Plugin;
 });
diff --git a/dojox/sketch/tests/test_full.html b/dojox/sketch/tests/test_full.html
index ff133c6..e2e3cd1 100755
--- a/dojox/sketch/tests/test_full.html
+++ b/dojox/sketch/tests/test_full.html
@@ -23,9 +23,8 @@
 		</style>
 		<script>var djConfig={ isDebug: false };</script>
 		<script src="../../../dojo/dojo.js"></script>
-		<script src="../Toolbar.js"></script>
 		<script>
-            dojo.require("dijit.robot");
+			dojo.require("dijit.robot");
 			dojo.require("dojox.sketch");
 			dojo.require("dojox.sketch.Slider");
 			dojo.require("dojox.sketch.LeadAnnotation");
@@ -51,13 +50,13 @@
 						dojo.byId("output").value=f.serialize();
 					}
 				});
-                
+
                 setTimeout(function(){
                     doh.robot.startRobot();
                     setTimeout(function(){
                         rundoh();
                     },1000);
-                },1000);
+				},1000);
 			}
 			dojo.addOnLoad(init);
             
@@ -117,7 +116,7 @@
 		</script>
 	</head>
 	<body class="tundra">
-    <button onclick="rundoh()">FT</button>
+		<button onclick="rundoh()">FT</button>
 		<h1>Annotator/Figure Testing Platform</h1>
 		<p>This is a generic test to create a figure from an existing SVG file, to edit that figure, and to test the undo stack. Double click a shape to set new text for it.</p>
 		<div id="container">
diff --git a/dojox/socket.js b/dojox/socket.js
index 9a5b17e..52df546 100644
--- a/dojox/socket.js
+++ b/dojox/socket.js
@@ -1,4 +1,4 @@
-define("dojox/socket", ["dojo", "dojo/cookie"], function(dojo) {
+define("dojox/socket", ["dojo", "dojo/Evented", "dojo/cookie", "dojo/_base/url"], function(dojo, Evented) {
 
 var WebSocket = window.WebSocket;
 
@@ -110,7 +110,7 @@ var cancelled = false,
 		first = true,
 		timeoutId,
 		connections = [];
-	
+
 	// create the socket object
 	var socket = {
 		send: function(data){
@@ -171,9 +171,7 @@ var cancelled = false,
 		dispatchEvent: function(event){
 			fire(event.type, event);
 		},
-		on: function(type, callback){
-			return dojo.connect(this, "on" + type, callback);
-		},
+		on: Evented.prototype.on,
 		firstRequest: function(args){
 			// summary:
 			// 		This allows for special handling for the first request. This is useful for
diff --git a/dojox/store/LightstreamerStore.js b/dojox/store/LightstreamerStore.js
new file mode 100644
index 0000000..052c56a
--- /dev/null
+++ b/dojox/store/LightstreamerStore.js
@@ -0,0 +1,204 @@
+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
new file mode 100644
index 0000000..123a4e7
--- /dev/null
+++ b/dojox/store/README
@@ -0,0 +1,47 @@
+-------------------------------------------------------------------------------
+DojoX Stores (data)
+-------------------------------------------------------------------------------
+Version 1.000
+Release date: 03/04/2011
+-------------------------------------------------------------------------------
+Project state:
+LightstreamerStore:	beta
+-------------------------------------------------------------------------------
+[   ]	l18n support?
+[   ]	a11y support?
+-------------------------------------------------------------------------------
+Credits
+LightstreamerStore:	Kris Zyp (kris at sitepen.com)
+					Tom Trenka (ttrenka at gmail.com)
+					Lightstreamer (http://lightstreamer.com)
+-------------------------------------------------------------------------------
+Project description
+
+DojoX Stores is intended to serve as a place where experimental stores based
+on the dojo.store APIs can live.  At the time of writing, only the 
+LightstreamerStore is available, but more stores may be added in the future.
+
+The LightstreamerStore is a lightweight object store that is intended to be
+used with the Lightstreamer Web Client and the Lightstreamer Server.  It allows
+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).
+-------------------------------------------------------------------------------
+Dependencies:
+
+The main dependency of the LightstreamerStore is dojo/store/util/QueryResults.
+-------------------------------------------------------------------------------
+Documentation
+
+LightstreamerStore: inline API documentation is included.
+-------------------------------------------------------------------------------
+Installation instructions
+
+Download the Dojo distribution and set up your Lightstreamer instance, and go!
+-------------------------------------------------------------------------------
+Additional Notes
+
+LightstreamerStore: The main place to hook your code to is to define an "observe"
+	function on the results from a query; this function will be passed a JSON-like
+	object, with which you can do anything you want.
diff --git a/dojox/store/tests/test_LightstreamerStore.html b/dojox/store/tests/test_LightstreamerStore.html
new file mode 100644
index 0000000..99ef181
--- /dev/null
+++ b/dojox/store/tests/test_LightstreamerStore.html
@@ -0,0 +1,74 @@
+<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 e04fa78..912aaca 100644
--- a/dojox/string/BidiComplex.js
+++ b/dojox/string/BidiComplex.js
@@ -1,17 +1,18 @@
-dojo.provide("dojox.string.BidiComplex");
-dojo.experimental("dojox.string.BidiComplex");
-
 // summary:
 //		BiDiComplex module handles complex expression issues known when using BiDi characters
 //		in File Paths, URLs, E-mail Address, XPATH, etc.
 //		this module adds property listeners to the text fields to correct the text representation
 //		in both static text and dynamic text during user input.
 
-(function(){
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/connect", "dojo/_base/sniff",
+		"dojo/keys"], 
+  function(dojo, lang, arr, hub, has, keys){
+	dojo.experimental("dojox.string.BidiComplex");
+	var bdc = lang.getObject("string.BidiComplex", true, dojox);
 
 	var _str0 = []; //FIXME: shared reference here among various functions means the functions can't be reused
 
-	dojox.string.BidiComplex.attachInput = function(/*DOMNode*/field, /*String*/pattern){
+	bdc.attachInput = function(/*DOMNode*/field, /*String*/pattern){
 		// summary:
 		//		Attach key listeners to the INPUT field to accomodate dynamic complex BiDi expressions
 		// field: INPUT DOM node
@@ -19,26 +20,26 @@ dojo.experimental("dojox.string.BidiComplex");
 
 		field.alt = pattern;
 
-		dojo.connect(field, "onkeydown",  this, "_ceKeyDown");
-		dojo.connect(field, "onkeyup", this, "_ceKeyUp");
+		hub.connect(field, "onkeydown",  this, "_ceKeyDown");
+		hub.connect(field, "onkeyup", this, "_ceKeyUp");
 
-		dojo.connect(field, "oncut", this, "_ceCutText");
-		dojo.connect(field, "oncopy", this, "_ceCopyText");
+		hub.connect(field, "oncut", this, "_ceCutText");
+		hub.connect(field, "oncopy", this, "_ceCopyText");
 
-		field.value = dojox.string.BidiComplex.createDisplayString(field.value, field.alt);
+		field.value = bdc.createDisplayString(field.value, field.alt);
 	};
 		
-	dojox.string.BidiComplex.createDisplayString = function(/*String*/str, /*String*/pattern){
+	bdc.createDisplayString = function(/*String*/str, /*String*/pattern){
 		// summary:
 		//		Create the display string by adding the Unicode direction Markers
 		// pattern: Complex Expression Pattern type. One of "FILE_PATH", "URL", "EMAIL", "XPATH"
 
-		str = dojox.string.BidiComplex.stripSpecialCharacters(str);
-		var segmentsPointers = dojox.string.BidiComplex._parse(str, pattern);
+		str = bdc.stripSpecialCharacters(str);
+		var segmentsPointers = bdc._parse(str, pattern);
 		
 		var buf = '\u202A'/*LRE*/ + str;
 		var shift = 1;
-		dojo.forEach(segmentsPointers, function(n){
+		arr.forEach(segmentsPointers, function(n){
 			if(n != null){
 				var preStr = buf.substring(0, n + shift);
 				var postStr = buf.substring(n + shift, buf.length);
@@ -49,51 +50,51 @@ dojo.experimental("dojox.string.BidiComplex");
 		return buf;
 	};
 
-	dojox.string.BidiComplex.stripSpecialCharacters = function(str){
+	bdc.stripSpecialCharacters = function(str){
 		// summary:
 		//		removes all Unicode directional markers from the string
 
 		return str.replace(/[\u200E\u200F\u202A-\u202E]/g, ""); // String
 	};
 
-	dojox.string.BidiComplex._ceKeyDown = function(event){
-		var elem = dojo.isIE ? event.srcElement : event.target;
+	bdc._ceKeyDown = function(event){
+		var elem = has("ie") ? event.srcElement : event.target;
 		_str0 = elem.value;
 	};
 				
-	dojox.string.BidiComplex._ceKeyUp = function(event){
+	bdc._ceKeyUp = function(event){
 		var LRM = '\u200E';
-		var elem = dojo.isIE ? event.srcElement : event.target;
+		var elem = has("ie") ? event.srcElement : event.target;
 
 		var str1 = elem.value;
 		var ieKey = event.keyCode;
 		
-		if((ieKey == dojo.keys.HOME)
-			|| (ieKey == dojo.keys.END)
-			|| (ieKey == dojo.keys.SHIFT)){
+		if((ieKey == keys.HOME)
+			|| (ieKey == keys.END)
+			|| (ieKey == keys.SHIFT)){
 			return;
 		}
 
 		var cursorStart, cursorEnd;
-		var selection = dojox.string.BidiComplex._getCaretPos(event, elem);
+		var selection = bdc._getCaretPos(event, elem);
 		if(selection){
 			cursorStart = selection[0];
 			cursorEnd = selection[1];
 		}
 
 	//Jump over a cursor processing
-		if(dojo.isIE){
+		if(has("ie")){
 			var cursorStart1 = cursorStart, cursorEnd1 = cursorEnd;
 
-			if(ieKey == dojo.keys.LEFT_ARROW){
+			if(ieKey == keys.LEFT_ARROW){
 				if((str1.charAt(cursorEnd-1) == LRM)
 						&& (cursorStart == cursorEnd)){
-					dojox.string.BidiComplex._setSelectedRange(elem,cursorStart - 1, cursorEnd - 1);
+					bdc._setSelectedRange(elem,cursorStart - 1, cursorEnd - 1);
 				}
 				return;
 			}
 
-			if(ieKey == dojo.keys.RIGHT_ARROW){
+			if(ieKey == keys.RIGHT_ARROW){
 				if(str1.charAt(cursorEnd-1) == LRM){
 					cursorEnd1 = cursorEnd + 1;
 					if(cursorStart == cursorEnd){
@@ -101,55 +102,55 @@ dojo.experimental("dojox.string.BidiComplex");
 					}
 				}
 
-				dojox.string.BidiComplex._setSelectedRange(elem, cursorStart1, cursorEnd1);
+				bdc._setSelectedRange(elem, cursorStart1, cursorEnd1);
 				return;
 			}
 		}else{ //Firefox
-			if(ieKey == dojo.keys.LEFT_ARROW){
+			if(ieKey == keys.LEFT_ARROW){
 				if(str1.charAt(cursorEnd-1) == LRM){
-					dojox.string.BidiComplex._setSelectedRange(elem, cursorStart - 1, cursorEnd - 1);
+					bdc._setSelectedRange(elem, cursorStart - 1, cursorEnd - 1);
 				}
 				return;
 			}
-			if(ieKey == dojo.keys.RIGHT_ARROW){
+			if(ieKey == keys.RIGHT_ARROW){
 				if(str1.charAt(cursorEnd-1) == LRM){
-					dojox.string.BidiComplex._setSelectedRange(elem, cursorStart + 1, cursorEnd + 1);
+					bdc._setSelectedRange(elem, cursorStart + 1, cursorEnd + 1);
 				}
 				return;
 			}
 		}
 		
-		var str2 = dojox.string.BidiComplex.createDisplayString(str1, elem.alt);
+		var str2 = bdc.createDisplayString(str1, elem.alt);
 
 		if(str1 != str2)
 		{
 			window.status = str1 + " c=" + cursorEnd;
 			elem.value = str2;
 
-			if((ieKey == dojo.keys.DELETE) && (str2.charAt(cursorEnd)==LRM)){
+			if((ieKey == keys.DELETE) && (str2.charAt(cursorEnd)==LRM)){
 				elem.value = str2.substring(0, cursorEnd) + str2.substring(cursorEnd+2, str2.length);
 			}
 
-			if(ieKey == dojo.keys.DELETE){
-				dojox.string.BidiComplex._setSelectedRange(elem,cursorStart,cursorEnd);
-			}else if(ieKey == dojo.keys.BACKSPACE){
+			if(ieKey == keys.DELETE){
+				bdc._setSelectedRange(elem,cursorStart,cursorEnd);
+			}else if(ieKey == keys.BACKSPACE){
 				if((_str0.length >= cursorEnd) && (_str0.charAt(cursorEnd-1)==LRM)){
-					dojox.string.BidiComplex._setSelectedRange(elem, cursorStart - 1, cursorEnd - 1);
+					bdc._setSelectedRange(elem, cursorStart - 1, cursorEnd - 1);
 				}else{
-					dojox.string.BidiComplex._setSelectedRange(elem, cursorStart, cursorEnd);
+					bdc._setSelectedRange(elem, cursorStart, cursorEnd);
 				}
 			}else if(elem.value.charAt(cursorEnd) != LRM){
-				dojox.string.BidiComplex._setSelectedRange(elem, cursorStart + 1, cursorEnd + 1);
+				bdc._setSelectedRange(elem, cursorStart + 1, cursorEnd + 1);
 			}
 		}
 	};
 
-	dojox.string.BidiComplex._processCopy = function(elem, text, isReverse){
+	bdc._processCopy = function(elem, text, isReverse){
 		// summary:
 		//		This function strips the unicode directional controls when the text copied to the Clipboard
 
 		if(text == null){
-			if(dojo.isIE){
+			if(has("ie")){
 				var range = document.selection.createRange();
 				text = range.text;
 			}else{
@@ -157,29 +158,29 @@ dojo.experimental("dojox.string.BidiComplex");
 			}
 		}
 
-		var textToClipboard = dojox.string.BidiComplex.stripSpecialCharacters(text);
+		var textToClipboard = bdc.stripSpecialCharacters(text);
 	
-		if(dojo.isIE){
+		if(has("ie")){
 			window.clipboardData.setData("Text", textToClipboard);
 		}
 		return true;
 	};
 
-	dojox.string.BidiComplex._ceCopyText = function(elem){
-		if(dojo.isIE){
+	bdc._ceCopyText = function(elem){
+		if(has("ie")){
 			elem.returnValue = false;
 		}
-		return dojox.string.BidiComplex._processCopy(elem, null, false);
+		return bdc._processCopy(elem, null, false);
 	};
 
-	dojox.string.BidiComplex._ceCutText = function(elem){
+	bdc._ceCutText = function(elem){
 
-		var ret = dojox.string.BidiComplex._processCopy(elem, null, false);
+		var ret = bdc._processCopy(elem, null, false);
 		if(!ret){
 			return false;
 		}
 
-		if(dojo.isIE){
+		if(has("ie")){
 	//		curPos = elem.selectionStart;
 			document.selection.clear();
 		}else{
@@ -192,8 +193,8 @@ dojo.experimental("dojox.string.BidiComplex");
 	};
 
 	// is there dijit code to do this?
-	dojox.string.BidiComplex._getCaretPos = function(event, elem){
-		if(dojo.isIE){
+	bdc._getCaretPos = function(event, elem){
+		if(has("ie")){
 			var position = 0,
 			range = document.selection.createRange().duplicate(),
 			range2 = range.duplicate(),
@@ -216,8 +217,8 @@ dojo.experimental("dojox.string.BidiComplex");
 	};
 
 	// is there dijit code to do this?
-	dojox.string.BidiComplex._setSelectedRange = function(elem,selectionStart,selectionEnd){
-		if(dojo.isIE){
+	bdc._setSelectedRange = function(elem,selectionStart,selectionEnd){
+		if(has("ie")){
 			var range = elem.createTextRange();
 			if(range){
 				if(elem.type == "textarea"){
@@ -262,7 +263,7 @@ dojo.experimental("dojox.string.BidiComplex");
 	};
 
 
-	dojox.string.BidiComplex._parse = function(/*String*/str, /*String*/pattern){
+	bdc._parse = function(/*String*/str, /*String*/pattern){
 		var previous = -1, segmentsPointers = [];
 		var delimiters = {
 			FILE_PATH: "/\\:.",
@@ -275,7 +276,7 @@ dojo.experimental("dojox.string.BidiComplex");
 			case "FILE_PATH":
 			case "URL":
 			case "XPATH":
-				dojo.forEach(str, function(ch, i){
+				arr.forEach(str, function(ch, i){
 					if(delimiters.indexOf(ch) >= 0 && _isCharBeforeBiDiChar(str, i, previous)){
 						previous = i;
 						segmentsPointers.push(i);
@@ -285,7 +286,7 @@ dojo.experimental("dojox.string.BidiComplex");
 			case "EMAIL":
 				var inQuotes = false; // FIXME: unused?
 	
-				dojo.forEach(str, function(ch, i){
+				arr.forEach(str, function(ch, i){
 					if(ch== '\"'){
 						if(_isCharBeforeBiDiChar(str, i, previous)){
 							previous = i;
@@ -310,4 +311,5 @@ dojo.experimental("dojox.string.BidiComplex");
 		}
 		return segmentsPointers;
 	};
-})();
+	return dojox.string.BidiComplex;
+});
diff --git a/dojox/string/BidiEngine.js b/dojox/string/BidiEngine.js
new file mode 100644
index 0000000..3d3625a
--- /dev/null
+++ b/dojox/string/BidiEngine.js
@@ -0,0 +1,1506 @@
+define(["dojo/_base/lang", "dojo/_base/declare"], 
+  function(lang,declare){
+lang.getObject("string", true, dojox);
+
+declare("dojox.string.BidiEngine", null, {
+	// summary:
+	//		This class provides a bidi transformation engine, i.e.
+	//		functions for reordering and shaping bidi text.
+	// description:
+	//		Bidi stands for support for languages with a bidirectional script. 
+	//
+	//		Usually Unicode Bidi Algorithm used by OS platform (and web browsers) is capable of properly transforming
+	//		Bidi text and as a result it is adequately displayed on the screen. However, in some situations, 
+	//		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/. 
+	//
+	//		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
+	//
+	//		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).
+	
+	bidiTransform: function (/*String*/text, /*String*/formatIn, /*String*/formatOut){
+		// summary:
+		//		Central public API for Bidi engine. Transforms the text according to formatIn, formatOut parameters.
+		//		If formatIn or formatOut parametrs are not valid throws an exception.
+		// inputText:
+		//		Input text subject to application of Bidi transformation.
+		// formatIn:
+		//		Input Bidi layout in which inputText is passed to the function.
+		// formatOut:
+		//		Output Bidi layout to which inputText should be transformed.
+		// description:
+		//		Both formatIn and formatOut parameters are 5 letters long strings. 
+		//		For example - "ILYNN". Each letter is associated with specific attribute of Bidi layout. 
+		//		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
+		//
+		//		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		
+		//
+		//		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		
+		//
+		//		Fourth letter:
+		//			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				
+		//
+		//		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). 
+		//
+		//		Sample call:
+		//	|	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.
+		//		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.
+		// tags:
+		//		public
+		
+		if(!text){
+			return '';
+		}
+		if(!formatIn && !formatOut){
+			return text;
+		}
+
+		// regex for format validation
+		// Allowed values for format string are:
+		// 1st letter- I, V
+		// 2nd letter- L, R, C, D
+		// 3rd letter- Y, N
+		// 4th letter- S, N
+		// 5th letter- N
+		var validFormat = /^[(I|V)][(L|R|C|D)][(Y|N)][(S|N)][N]$/;
+		if(!validFormat.test(formatIn) || !validFormat.test(formatOut)){
+			throw new Error("dojox.string.BidiEngine: the bidi layout string is wrong!");
+		}
+
+		if(formatIn == formatOut){
+			return text;
+		}
+
+		var orientIn = getOrientation(formatIn.charAt(1))
+			, orientOut = getOrientation(formatOut.charAt(1))
+			, os_in = (formatIn.charAt(0) == 'I') ? 'L' : formatIn.charAt(0)
+			, os_out = (formatOut.charAt(0) == 'I') ? 'L' : formatOut.charAt(0)
+			, inFormat = os_in + orientIn
+			, outFormat = os_out + orientOut
+			, swap = formatIn.charAt(2) + formatOut.charAt(2)
+			;
+
+		if(inFormat){
+			bdx.defInFormat = inFormat;
+		}
+		if(outFormat){
+			bdx.defOutFormat = outFormat;
+		}
+		if(swap){
+			bdx.defSwap = swap;
+		}
+		
+		var stage1_text = doBidiReorder(text, os_in + orientIn, os_out + orientOut, formatIn.charAt(2) + formatOut.charAt(2))
+			, isRtl = false;
+
+		if(formatOut.charAt(1) == 'R'){
+			isRtl = true;
+		}else if(formatOut.charAt(1) == 'C' || formatOut.charAt(1) == 'D'){
+			isRtl = this.checkContextual(stage1_text);
+		}
+		if(formatIn.charAt(3) == formatOut.charAt(3)){
+			return stage1_text;
+		}else if(formatOut.charAt(3) == 'S'){
+			return shape(isRtl, stage1_text, true);
+		}
+		if(formatOut.charAt(3) == 'N'){
+			return deshape(stage1_text, isRtl, true);
+		}
+	},
+	checkContextual: function(/*String*/text){
+		// summary: 	
+		//		Determine the base direction of a bidi text according
+		//		to its first strong directional character.
+		// text: 
+		//		The text to check.
+		// returns: /*String*/
+		//		"ltr" or "rtl" according to the first strong character.
+		//		If there is no strong character, returns the value of the
+		//		document dir property.
+		// tags:
+		//		public		
+		var dir = firstStrongDir(text);
+		if(dir != "ltr" && dir != "rtl"){
+			dir = document.dir.toLowerCase();
+			if(dir != "ltr" && dir != "rtl"){dir = "ltr";}
+		}
+		return dir;
+	},
+	hasBidiChar: function(/*String*/text){
+		// summary:
+		//		Return true if text contains RTL directed character.
+		// text:
+		//		The source string.
+		// description:
+		//		Iterates over the text string, letter by letter starting from its beginning,
+		//		searching for RTL directed character. 
+		//		Return true if found else false. Needed for vml transformation.
+		// returns: /*Boolean*/
+		//		true - if text has a RTL directed character.
+		//		false - otherwise. 
+		// tags:
+		//		public
+
+		var type = null, uc = null,	hi = null;
+		for(var i = 0; i < text.length; i++){
+			uc = text.charAt(i).charCodeAt(0);
+			hi = MasterTable[uc >> 8];
+			type = hi < TBBASE ? hi : UnicodeTable[hi - TBBASE][uc & 0xFF];
+			if(type == UBAT_R || type == UBAT_AL){
+				return true;
+			}
+			if(type == UBAT_B){
+				break;
+			}
+		}
+		return false;
+	}	
+
+});
+
+
+function doBidiReorder(/*String*/text, /*String*/inFormat,
+						/*String*/outFormat, /*String*/swap){
+	// summary: 	
+	//		Reorder the source text according to the bidi attributes
+	//		of source and result.
+	//	text:
+	//		The text to reorder.
+	//	inFormat:	
+	//		Ordering scheme and base direction of the source text.
+	//		Can be "LLTR", "LRTL", "LCLR", "LCRL", "VLTR", "VRTL",
+	//		"VCLR", "VCRL".
+	//		The first letter is "L" for logical ordering scheme,
+	//		"V" for visual ordering scheme.
+	//		The other letters specify the base direction.
+	//		"CLR" means contextual direction defaulting to LTR if
+	//		there is no strong letter.
+	//		"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:	
+	//		Required ordering scheme and base direction of the
+	//		result. Has the same format as inFormat.
+	//		If none, the initial value "VLTR" is used.
+	//	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
+	//		of the source, the second letter that of the result.	
+	// returns:
+	//		Text reordered according to source and result attributes.
+
+	if(inFormat == undefined){
+		inFormat = bdx.defInFormat;
+	}
+	if(outFormat == undefined){
+		outFormat = bdx.defOutFormat;
+	}
+	if(swap == undefined){
+		swap = bdx.defSwap;
+	}
+	if(inFormat == outFormat){
+		return text;
+	}
+	var dir, inOrdering = inFormat.substring(0,1)
+		, inOrientation = inFormat.substring(1,4)
+		, outOrdering = outFormat.substring(0,1)
+		, outOrientation = outFormat.substring(1,4)
+		;
+	if(inOrientation.charAt(0) == "C"){
+		dir = firstStrongDir(text);
+		if(dir == "ltr" || dir == "rtl"){
+			inOrientation = dir.toUpperCase();
+		}else{
+			inOrientation = inFormat.charAt(2) == "L" ? "LTR" : "RTL";
+		}
+		inFormat = inOrdering + inOrientation;
+	}
+	if(outOrientation.charAt(0) == "C"){
+		dir = firstStrongDir(text);
+		if(dir == "rtl"){
+			outOrientation = "RTL";
+		}else if(dir == "ltr"){
+			dir = lastStrongDir(text);
+			outOrientation = dir.toUpperCase();
+		}else{
+			outOrientation = outFormat.charAt(2) == "L" ? "LTR" : "RTL";
+		}
+		outFormat = outOrdering + outOrientation;
+	}
+	if(inFormat == outFormat){
+		return text;
+	}
+	bdx.inFormat = inFormat;
+	bdx.outFormat = outFormat;
+	bdx.swap = swap;
+	if((inOrdering == "L") && (outFormat == "VLTR")){ //core cases
+		//cases: LLTR->VLTR, LRTL->VLTR
+		if(inOrientation == "LTR"){
+			bdx.dir = LTR;
+			return doReorder(text);
+		}
+		if(inOrientation == "RTL"){
+			bdx.dir = RTL;
+			return doReorder(text);
+		}
+	}
+	if((inOrdering == "V") && (outOrdering == "V")){
+		//inOrientation != outOrientation
+		//cases: VRTL->VLTR, VLTR->VRTL
+		return invertStr(text);
+	}
+	if((inOrdering == "L") && (outFormat == "VRTL")){
+		//cases: LLTR->VRTL, LRTL->VRTL
+		if(inOrientation == "LTR"){
+			bdx.dir = LTR;
+			text = doReorder(text);
+		}else{
+			//inOrientation == RTL
+			bdx.dir = RTL;
+			text = doReorder(text);
+		}
+		return invertStr(text);
+	}
+	if((inFormat == "VLTR") && (outFormat == "LLTR")){
+		//case: VLTR->LLTR
+		bdx.dir = LTR;
+		return doReorder(text);
+	}
+	if((inOrdering == "V") && (outOrdering == "L") && (inOrientation != outOrientation)){
+		//cases: VLTR->LRTL, VRTL->LLTR
+		text = invertStr(text);
+
+		return (inOrientation == "RTL") ? doBidiReorder(text, "LLTR","VLTR", swap) : doBidiReorder(text, "LRTL","VRTL", swap);
+	}
+	if((inFormat == "VRTL") && (outFormat == "LRTL")){
+		//case VRTL->LRTL
+		return doBidiReorder(text, "LRTL","VRTL", swap);
+	}
+	if((inOrdering == "L") && (outOrdering == "L")){
+		//inOrientation != outOrientation
+		//cases: LRTL->LLTR, LLTR->LRTL
+		var saveSwap = bdx.swap;
+		bdx.swap = saveSwap.substr(0, 1) + "N";
+		if(inOrientation == "RTL"){
+			//LRTL->LLTR
+			bdx.dir = RTL;
+			text = doReorder(text);
+			bdx.swap = "N" + saveSwap.substr(1, 2);
+			bdx.dir = LTR;
+			text = doReorder(text);
+		}else{ //LLTR->LRTL
+			bdx.dir = LTR;
+			text = doReorder(text);
+			bdx.swap = "N" + saveSwap.substr(1, 2);
+			text = doBidiReorder(text, "VLTR","LRTL", bdx.swap);
+		}
+		return text;
+	}
+
+};
+
+function shape(/*boolean*/rtl, /*String*/text, /*boolean*/compress){
+	// summary:
+	//		Shape the source text.
+	// rtl:
+	//		Flag indicating if the text is in RTL direction (logical
+	//		direction for Arabic words).
+	// text:
+	//		The text to shape.
+	// 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:
+	//		- 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:
+	//		text shaped.
+	// tags:
+	//		private.
+	
+	if(text.length == 0){
+		return;
+	}
+	if(rtl == undefined){
+		rtl = true;
+	}
+	if(compress == undefined){
+		compress = true;
+	}
+	text = new String(text);
+	
+	var str06 = text.split("")
+		, Ix = 0
+		, step = +1
+		, nIEnd = str06.length
+		;
+	if(!rtl){
+		Ix = str06.length - 1;
+		step = -1;
+		nIEnd = 1;
+	}
+	var previousCursive = 0, compressArray = [], compressArrayIndx = 0;
+	for(var index = Ix; index * step < nIEnd; index = index + step){
+		if(isArabicAlefbet(str06[index]) || isArabicDiacritics(str06[index])){
+			// Arabic letter Lam
+			if(str06[index] == '\u0644'){
+				if(isNextAlef(str06, (index + step), step, nIEnd)){
+					str06[index] = (previousCursive == 0) ? getLamAlefFE(str06[index + step], LamAlefInialTableFE) : getLamAlefFE(str06[index + step], LamAlefMedialTableFE);
+					index += step;
+					setAlefToSpace(str06, index, step, nIEnd);
+					if(compress){
+						compressArray[compressArrayIndx] = index;
+						compressArrayIndx++;
+					}
+					previousCursive = 0;
+					continue;
+				}
+			}
+			var currentChr = str06[index];
+			if(previousCursive == 1){
+				// if next is Arabic
+				//Character is in medial form
+				// else character is in final form
+				str06[index] = (isNextArabic(str06, (index + step), step, nIEnd)) ? 
+					getMedialFormCharacterFE(str06[index]) : getFormCharacterFE(str06[index], FinalForm);
+			}else{
+				if(isNextArabic(str06, (index + step), step, nIEnd) == true){
+					//character is in Initial form
+					str06[index] = getFormCharacterFE(str06[index],InitialForm);
+				}else{
+					str06[index] = getFormCharacterFE(str06[index], IsolatedForm);
+				}
+			}
+			//exam if the current character is cursive
+			if(!isArabicDiacritics(currentChr)){
+				previousCursive = 1;
+			}
+			if(isStandAlonCharacter(currentChr) == true){
+				previousCursive = 0;
+			}
+		}else{
+			previousCursive = 0;
+		}
+	}
+	var outBuf = "";
+	for(idx = 0; idx < str06.length; idx++){
+		if(!(compress && indexOf(compressArray, compressArray.length, idx) > -1)){
+			outBuf += str06[idx];
+		}
+	}
+	return outBuf;
+};
+function firstStrongDir(/*String*/text){
+	// summary:
+	//		Return the first strong character direction
+	// text:
+	//		The source string.
+	// description:
+	//		Iterates over the text string, letter by letter starting from its beginning,
+	//		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*/
+	//		"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.
+	// tags:
+	//		private
+
+	var type = null, uc = null, hi = null;
+	for(var i = 0; i < text.length; i++){
+		uc = text.charAt(i).charCodeAt(0);
+		hi = MasterTable[uc >> 8];
+		type = hi < TBBASE ? hi : UnicodeTable[hi - TBBASE][uc & 0xFF];
+		if(type == UBAT_R || type == UBAT_AL){
+			return "rtl";
+		}
+		if(type == UBAT_L){
+			return	"ltr";
+		}
+		if(type == UBAT_B){
+			break;
+		}
+	}
+	return "";
+};
+function lastStrongDir(text){
+	// summary:
+	//		Return the last strong character direction
+	// text:
+	//		The source string.
+	// description:
+	//		Iterates over the text string, letter by letter starting from its end,
+	//		searching for first (from the end) "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.
+	// tags:
+	//		private		
+	var type = null;
+	for(var i = text.length - 1; i >= 0; i--){
+		type = getCharacterType(text.charAt(i));
+		if(type == UBAT_R || type == UBAT_AL){
+			return "rtl";
+		}
+		if(type == UBAT_L){
+			return	"ltr";
+		}
+		if(type == UBAT_B){
+			break;
+		}
+	}
+	return "";
+};
+function deshape(/*String*/text, /*boolean*/rtl, /*boolean*/consume_next_space){
+	// summary:
+	//		deshape the source text.
+	// text:
+	//		the text to be deshape.
+	// rtl:
+	//		flag indicating if the text is in RTL direction (logical
+	//		direction for Arabic words).
+	// consume_next_space:
+	//		flag indicating whether to consume the space next to the 
+	//		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.
+	if(text.length == 0){
+		return;
+	}
+	if(consume_next_space == undefined){
+		consume_next_space = true;
+	}
+	if(rtl == undefined){
+		rtl = true;
+	}
+	text = new String(text);
+
+	var outBuf = "", strFE = [], textBuff = "";
+	if(consume_next_space){
+		for(var j = 0; j < text.length; j++){
+			if(text.charAt(j) == ' '){
+				if(rtl){
+					if(j > 0){
+						if(text.charAt(j - 1) >= '\uFEF5' && text.charAt(j - 1) <= '\uFEFC'){
+							continue;
+						}
+					}
+				}else{
+					if(j+1 < text.length){
+						if(text.charAt(j + 1) >= '\uFEF5' && text.charAt(j + 1) <= '\uFEFC'){
+							continue;
+						}
+					}				
+				}
+			}
+			textBuff += text.charAt(j);
+		}
+	}else{
+		textBuff = new String(text);
+	}
+	strFE = textBuff.split("");
+	for(var i = 0; i < textBuff.length; i++){
+		if(strFE[i] >= '\uFE70' && strFE[i] < '\uFEFF'){
+			var chNum = textBuff.charCodeAt(i);
+			if(strFE[i] >= '\uFEF5' && strFE[i] <= '\uFEFC'){
+				//expand the LamAlef
+				if(rtl){
+					//Lam + Alef
+					outBuf += '\u0644';
+					outBuf += AlefTable[parseInt((chNum - 65269) / 2)];
+				}else{
+					outBuf += AlefTable[parseInt((chNum - 65269) / 2)];
+					outBuf += '\u0644';
+				}
+			}else{
+				outBuf += FETo06Table[chNum - 65136];
+			}
+		}else{
+			outBuf += strFE[i];
+		}
+	}
+	return outBuf;
+};
+function doReorder(str){
+	// summary:
+	//		Helper to the doBidiReorder. Manages the UBA.
+	// str:
+	//		the string to reorder.
+	// returns:
+	//		text reordered according to source and result attributes.
+	// tags: 
+	//		private	
+	var chars = str.split(""), levels = [];
+
+	computeLevels(chars, levels);
+	swapChars(chars, levels);
+	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
+		, prevState = null, newClass = null, newLevel = null, newState = 0
+		, action = null, cond = null, condPos = -1, i = null, ix = null
+		, types = []
+		, classes = []
+		;
+	bdx.hiLevel = bdx.dir;
+	bdx.lastArabic = false;
+	bdx.hasUBAT_AL = false,
+	bdx.hasUBAT_B = false;
+	bdx.hasUBAT_S = false;
+	for(i = 0; i < len; i++){
+		types[i] = getCharacterType(chars[i]);
+	}
+	for(ix = 0; ix < len; ix++){
+		prevState = newState;
+		classes[ix] = newClass = getCharClass(chars, types, classes, ix);
+		newState = impTab[prevState][newClass];
+		action = newState & 0xF0;
+		newState &= 0x0F;
+		levels[ix] = newLevel = impTab[newState][ITIL];
+		if(action > 0){
+			if(action == 0x10){	// set conditional run to level 1
+				for(i = condPos; i < ix; i++){
+					levels[i] = 1;
+				}
+				condPos = -1;
+			}else{	// 0x20 confirm the conditional run
+				condPos = -1;
+			}
+		}
+		cond = impTab[newState][ITCOND];
+		if(cond){
+			if(condPos == -1){
+				condPos = ix;
+			}
+		}else{	// unconditional level
+			if(condPos > -1){
+				for(i = condPos; i < ix; i++){
+					levels[i] = newLevel;
+				}
+				condPos = -1;
+			}
+		}
+		if(types[ix] == UBAT_B){
+			levels[ix] = 0;
+		}
+		bdx.hiLevel |= newLevel;
+	}
+	if(bdx.hasUBAT_S){
+		for(i = 0; i < len; i++){
+			if(types[i] == UBAT_S){
+				levels[i] = bdx.dir;
+				for(var j = i - 1; j >= 0; j--){
+					if(types[j] == UBAT_WS){
+						levels[j] = bdx.dir;
+					}else{
+						break;
+					}
+				}
+			}
+		}
+	}
+};
+function swapChars(chars, levels){
+	// summary:
+	//		Swap characters with symmetrical mirroring as all kinds of parenthesis.
+	//		(When needed).
+	// chars:
+	//		The source string as Array of characters.
+	// levels:
+	//		An array (like hash) of flags for each character in the source string,
+	//		that defines if swapping should be applied on the following character.
+	// description:
+	//		First checks if the swapping should be applied, if not returns, else 
+	//		uses the levels "hash" to find what characters should be swapped.
+	// tags:
+	//		private	
+
+	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.
+	// ch:
+	//		The character to be checked.
+
+	// description:
+	//		Check the type of the character according to MasterTable,
+	//		type = LTR, RTL, neutral,Arabic-Indic digit etc.
+	// tags:
+	//		private			
+	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.
+	// str:
+	//		The string to be reversed.
+	// description:
+	//		Reverse the string str.
+	// tags:
+	//		private					
+	var chars = str.split("");
+	chars.reverse();
+	return chars.join("");
+};
+function indexOf(cArray, cLength, idx){
+	var counter = -1;
+	for(var i = 0; i < cLength; i++){
+		if(cArray[i] == idx){
+			return i;
+		}
+	}
+	return -1;
+};
+function isArabicAlefbet(c){
+	for(var i = 0; i < ArabicAlefBetIntervalsBegine.length; i++){
+		if(c >= ArabicAlefBetIntervalsBegine[i] && c <= ArabicAlefBetIntervalsEnd[i]){
+			return true;
+		}
+	}
+	return false;
+};
+function isNextArabic(str06, index, step, nIEnd){
+	while(((index) * step) < nIEnd && isArabicDiacritics(str06[index])){
+		index += step;
+	}
+	if(((index) * step) < nIEnd && isArabicAlefbet(str06[index])){
+		return true;
+	}
+	return false;
+};
+function isNextAlef(str06, index, step, nIEnd){
+	while(((index) * step) < nIEnd && isArabicDiacritics(str06[index])){
+		index += step;
+	}
+	var c = ' ';
+	if(((index) * step) < nIEnd){
+		c = str06[index];
+	}else{
+		return false;
+	}
+	for(var i = 0; i < AlefTable.length; i++){
+		if(AlefTable[i] == c){
+			return true;
+		}
+	}
+	return false;
+};
+function invertLevel(lev, chars, levels){
+	if(bdx.hiLevel < lev){
+		return;
+	}
+	if(lev == 1 && bdx.dir == RTL && !bdx.hasUBAT_B){
+		chars.reverse();
+		return;
+	}
+	var len = chars.length, start = 0, end, lo, hi, tmp;
+	while(start < len){
+		if(levels[start] >= lev){
+			end = start + 1;
+			while(end < len && levels[end] >= lev){
+				end++;
+			}
+			for(lo = start, hi = end - 1 ; lo < hi; lo++, hi--){
+				tmp = chars[lo];
+				chars[lo] = chars[hi];
+				chars[hi] = tmp;
+			}
+			start = end;
+		}
+		start++;
+	}
+};
+function getCharClass(chars, types, classes, ix){
+	// summary:
+	//		Return the class if ix character in chars.
+	// chars:
+	//		The source string as Array of characters.
+	// types:
+	//		Array of types, for each character in chars.
+	// classes:
+	//		Array of classes that already been solved. 
+	// ix:
+	//		the index of checked character.
+	// tags:
+	//		private				
+	var cType = types[ix], wType, nType, len, i;
+	switch(cType){
+		case UBAT_L:
+		case UBAT_R:
+			bdx.lastArabic = false;
+		case UBAT_ON:
+		case UBAT_AN:
+			return cType;
+		case UBAT_EN:
+			return bdx.lastArabic ? UBAT_AN : UBAT_EN;
+		case UBAT_AL:
+			bdx.lastArabic = true;
+			bdx.hasUBAT_AL = true;
+			return UBAT_R;
+		case UBAT_WS:
+			return UBAT_ON;
+		case UBAT_CS:
+			if(ix < 1 || (ix + 1) >= types.length ||
+				((wType = classes[ix - 1]) != UBAT_EN && wType != UBAT_AN) ||
+				((nType = types[ix + 1]) != UBAT_EN && nType != UBAT_AN)){
+				return UBAT_ON;
+			}
+			if(bdx.lastArabic){nType = UBAT_AN;}
+			return nType == wType ? nType : UBAT_ON;
+		case UBAT_ES:
+			wType = ix > 0 ? classes[ix - 1] : UBAT_B;
+			if(wType == UBAT_EN && (ix + 1) < types.length && types[ix + 1] == UBAT_EN){
+				return UBAT_EN;
+			}
+			return UBAT_ON;
+		case UBAT_ET:
+			if(ix > 0 && classes[ix - 1] == UBAT_EN){
+				return UBAT_EN;
+			}
+			if(bdx.lastArabic){
+				return UBAT_ON;
+			}
+			i = ix + 1;
+			len = types.length;
+			while(i < len && types[i] == UBAT_ET){
+				i++;
+			}
+			if(i < len && types[i] == UBAT_EN){
+				return UBAT_EN;
+			}
+			return UBAT_ON;
+		case UBAT_NSM:
+			if(bdx.inFormat == "VLTR"){	// visual to implicit transformation
+				len = types.length;
+				i = ix + 1;
+				while(i < len && types[i] == UBAT_NSM){
+					i++;
+				}
+				if(i < len){
+					var c = chars[ix]
+						, rtlCandidate = (c >= 0x0591 && c <= 0x08FF) || c == 0xFB1E
+						;
+					wType = types[i];
+					if(rtlCandidate && (wType == UBAT_R || wType == UBAT_AL)){
+						return UBAT_R;
+					}
+				}
+			}
+			if(ix < 1 || (wType = types[ix - 1]) == UBAT_B){
+				return UBAT_ON;
+			}
+			return classes[ix - 1];
+		case UBAT_B:
+			lastArabic = false;
+			bdx.hasUBAT_B = true;
+			return bdx.dir;
+		case UBAT_S:
+			bdx.hasUBAT_S = true;
+			return UBAT_ON;
+		case UBAT_LRE:
+		case UBAT_RLE:
+		case UBAT_LRO:
+		case UBAT_RLO:
+		case UBAT_PDF:
+			lastArabic = false;
+		case UBAT_BN:
+			return UBAT_ON;
+	}
+};
+function getMirror(c){
+	// summary:
+	//		Calculates the mirrored character of c
+	// c:
+	//		The character to be mirrored.
+	// tags:
+	//		private					
+	var mid, low = 0, high = SwapTable.length - 1;
+
+	while(low <= high){
+		mid = Math.floor((low + high) / 2);
+		if(c < SwapTable[mid][0]){
+			high = mid - 1;
+		}else if(c > SwapTable[mid][0]){
+			low = mid + 1;
+		}else{
+			return SwapTable[mid][1];
+		}
+	}
+	return c;
+};
+function isStandAlonCharacter(c){
+	for(var i = 0; i < StandAlonForm.length; i++){
+		if(StandAlonForm[i] == c){
+			return true;
+		}
+	}
+	return false;
+};
+function getMedialFormCharacterFE(c){
+	for(var i = 0; i < BaseForm.length; i++){
+		if(c == BaseForm[i]){
+			return MedialForm[i];
+		}
+	}
+	return c;
+};
+function getFormCharacterFE(/*char*/ c, /*char[]*/formArr){
+	for(var i = 0; i < BaseForm.length; i++){
+		if(c == BaseForm[i]){
+			return formArr[i];
+		}
+	}
+	return c;
+};
+function isArabicDiacritics(c){
+	return	(c >= '\u064b' && c <= '\u0655') ? true : false;
+};
+function getOrientation(/*Char*/ oc){
+	if(oc == 'L'){
+		return "LTR";
+	}
+	if(oc == 'R'){
+		return "RTL";
+	}
+	if(oc == 'C'){
+		return "CLR";
+	}
+	if(oc == 'D'){
+		return "CRL";
+	}
+};
+function setAlefToSpace(str06, index, step, nIEnd){
+	while(((index) * step) < nIEnd && isArabicDiacritics(str06[index])){
+		index += step;
+	}
+	if(((index) * step) < nIEnd){
+		str06[index] = ' ';
+		return true;
+	}
+	return false;
+};
+function getLamAlefFE(alef06, LamAlefForm){
+	for(var i = 0; i < AlefTable.length; i++){
+		if(alef06 == AlefTable[i]){
+			return LamAlefForm[i];
+		}
+	}
+	return alef06;
+};
+function LamAlef(alef){
+	// summary:
+	//		If the alef variable is an ARABIC ALEF letter,
+	//		return the LamAlef code associated with the specific 
+	//		alef character.
+	// alef:
+	//		The alef code type.
+	// description:
+	//		If "alef" is an ARABIC ALEF letter, identify which alef is it,
+	//		using AlefTable, then return the LamAlef associated with it.
+	// tags:
+	//		private			
+	for(var i = 0; i < AlefTable.length; i++){
+		if(AlefTable[i] == alef){
+			return AlefTable[i];
+		}
+	}
+	return 0;
+};
+
+var	bdx = {
+		dir: 0,
+		defInFormat: "LLTR",
+		defoutFormat: "VLTR",
+		defSwap: "YN",
+		inFormat: "LLTR",
+		outFormat: "VLTR",
+		swap: "YN",
+		hiLevel: 0,
+		lastArabic: false,
+		hasUBAT_AL: false,
+		hasBlockSep: false,
+		hasSegSep: false
+};
+
+var ITIL = 5;
+
+var ITCOND = 6;
+
+var LTR = 0;
+
+var RTL = 1;
+
+/****************************************************************************/
+/* Array in which directional characters are replaced by their symmetric.	*/
+/****************************************************************************/
+var SwapTable = [
+	[ "\u0028", "\u0029" ],	/* Round brackets					*/
+	[ "\u0029", "\u0028" ],
+	[ "\u003C", "\u003E" ],	/* Less than/greater than			*/
+	[ "\u003E", "\u003C" ],
+	[ "\u005B", "\u005D" ],	/* Square brackets					*/
+	[ "\u005D", "\u005B" ],
+	[ "\u007B", "\u007D" ],	/* Curly brackets					*/
+	[ "\u007D", "\u007B" ],
+	[ "\u00AB", "\u00BB" ],	/* Double angle quotation marks	*/
+	[ "\u00BB", "\u00AB" ],
+	[ "\u2039", "\u203A" ],	/* single angle quotation mark		*/
+	[ "\u203A", "\u2039" ],
+	[ "\u207D", "\u207E" ],	/* Superscript parentheses			*/
+	[ "\u207E", "\u207D" ],
+	[ "\u208D", "\u208E" ],	/* Subscript parentheses			*/
+	[ "\u208E", "\u208D" ],
+	[ "\u2264", "\u2265" ],	/* Less/greater than or equal		*/
+	[ "\u2265", "\u2264" ],
+	[ "\u2329", "\u232A" ],	/* Angle brackets					*/
+	[ "\u232A", "\u2329" ],
+	[ "\uFE59", "\uFE5A" ],	/* Small round brackets			*/
+	[ "\uFE5A", "\uFE59" ],
+	[ "\uFE5B", "\uFE5C" ],	/* Small curly brackets			*/
+	[ "\uFE5C", "\uFE5B" ],
+	[ "\uFE5D", "\uFE5E" ],	/* Small tortoise shell brackets	*/
+	[ "\uFE5E", "\uFE5D" ],
+	[ "\uFE64", "\uFE65" ],	/* Small less than/greater than	*/
+	[ "\uFE65", "\uFE64" ]
+];
+var AlefTable = ['\u0622', '\u0623', '\u0625', '\u0627'];
+
+var AlefTableFE = [0xFE81, 0xFE82, 0xFE83, 0xFE84, 0xFE87, 0xFE88, 0xFE8D, 0xFE8E];
+
+var LamTableFE = [0xFEDD, 0xFEDE, 0xFEDF, 0xFEE0];
+
+var LamAlefInialTableFE = ['\ufef5', '\ufef7', '\ufef9', '\ufefb'];
+
+var LamAlefMedialTableFE = ['\ufef6', '\ufef8', '\ufefa', '\ufefc'];
+/**
+ * Arabic Characters in the base form
+ */
+var BaseForm = ['\u0627', '\u0628', '\u062A', '\u062B', '\u062C', '\u062D', '\u062E', '\u062F', '\u0630', '\u0631', '\u0632', '\u0633', '\u0634', '\u0635', '\u0636', '\u0637', '\u0638', '\u0639', '\u063A', '\u0641', '\u0642', '\u0643', '\u0644', '\u0645', '\u0646', '\u0647', '\u0648', '\u064A', '\u0625', '\u0623', '\u0622', '\u0629', '\u0649', '\u06CC', '\u0626', '\u0624', '\u064B', '\u064C', '\u064D', '\u064E', '\u064F', '\u0650', '\u0651', '\u0652', '\u0621'];
+
+/**
+ * Arabic shaped characters in Isolated form
+ */
+var IsolatedForm = ['\uFE8D', '\uFE8F', '\uFE95', '\uFE99', '\uFE9D', '\uFEA1', '\uFEA5', '\uFEA9', '\uFEAB', '\uFEAD', '\uFEAF', '\uFEB1', '\uFEB5', '\uFEB9', '\uFEBD', '\uFEC1', '\uFEC5', '\uFEC9', '\uFECD', '\uFED1', '\uFED5', '\uFED9', '\uFEDD', '\uFEE1', '\uFEE5', '\uFEE9', '\uFEED', '\uFEF1', '\uFE87', '\uFE83', '\uFE81', '\uFE93', '\uFEEF', '\uFBFC', '\uFE89', '\uFE85', '\uFE70', '\uFE72', '\uFE74', '\uFE76', '\uFE78', '\uFE7A', '\uFE7C', '\uFE7E', '\uFE80'];
+
+/**
+ * Arabic shaped characters in Final form
+ */
+var FinalForm = ['\uFE8E', '\uFE90', '\uFE96', '\uFE9A', '\uFE9E', '\uFEA2', '\uFEA6', '\uFEAA', '\uFEAC', '\uFEAE', '\uFEB0', '\uFEB2', '\uFEB6', '\uFEBA', '\uFEBE', '\uFEC2', '\uFEC6', '\uFECA', '\uFECE', '\uFED2', '\uFED6', '\uFEDA', '\uFEDE', '\uFEE2', '\uFEE6', '\uFEEA', '\uFEEE', '\uFEF2', '\uFE88', '\uFE84', '\uFE82', '\uFE94', '\uFEF0', '\uFBFD', '\uFE8A', '\uFE86', '\uFE70', '\uFE72', '\uFE74', '\uFE76', '\uFE78', '\uFE7A', '\uFE7C', '\uFE7E', '\uFE80'];
+
+/**
+ * Arabic shaped characters in Media form
+ */
+var MedialForm = ['\uFE8E', '\uFE92', '\uFE98', '\uFE9C', '\uFEA0', '\uFEA4', '\uFEA8', '\uFEAA', '\uFEAC', '\uFEAE', '\uFEB0', '\uFEB4', '\uFEB8', '\uFEBC', '\uFEC0', '\uFEC4', '\uFEC8', '\uFECC', '\uFED0', '\uFED4', '\uFED8', '\uFEDC', '\uFEE0', '\uFEE4', '\uFEE8', '\uFEEC', '\uFEEE', '\uFEF4', '\uFE88', '\uFE84', '\uFE82', '\uFE94', '\uFEF0', '\uFBFF', '\uFE8C', '\uFE86', '\uFE71', '\uFE72', '\uFE74', '\uFE77', '\uFE79', '\uFE7B', '\uFE7D', '\uFE7F', '\uFE80'];
+
+/**
+ * Arabic shaped characters in Initial form
+ */
+var InitialForm = ['\uFE8D', '\uFE91', '\uFE97', '\uFE9B', '\uFE9F', '\uFEA3', '\uFEA7', '\uFEA9', '\uFEAB', '\uFEAD', '\uFEAF', '\uFEB3', '\uFEB7', '\uFEBB', '\uFEBF', '\uFEC3', '\uFEC7', '\uFECB', '\uFECF', '\uFED3', '\uFED7', '\uFEDB', '\uFEDF', '\uFEE3', '\uFEE7', '\uFEEB', '\uFEED', '\uFEF3', '\uFE87', '\uFE83', '\uFE81', '\uFE93', '\uFEEF', '\uFBFE', '\uFE8B', '\uFE85', '\uFE70', '\uFE72', '\uFE74', '\uFE76', '\uFE78', '\uFE7A', '\uFE7C', '\uFE7E', '\uFE80'];
+
+/**
+ * Arabic characters that couldn't join to the next character
+ */
+var StandAlonForm = ['\u0621', '\u0627', '\u062F', '\u0630', '\u0631', '\u0632', '\u0648', '\u0622', '\u0629', '\u0626', '\u0624', '\u0625', '\u0675', '\u0623'];
+
+var FETo06Table = ['\u064B', '\u064B', '\u064C', '\u061F', '\u064D', '\u061F', '\u064E', '\u064E', '\u064F', '\u064F', '\u0650', '\u0650', '\u0651', '\u0651', '\u0652', '\u0652', '\u0621', '\u0622', '\u0622', '\u0623', '\u0623', '\u0624', '\u0624', '\u0625', '\u0625', '\u0626', '\u0626', '\u0626', '\u0626', '\u0627', '\u0627', '\u0628', '\u0628', '\u0628', '\u0628', '\u0629', '\u0629', '\u062A', '\u062A', '\u062A', '\u062A', '\u062B', '\u062B', '\u062B', '\u062B', '\u062C', '\u062C', '\u [...]
+
+var ArabicAlefBetIntervalsBegine = ['\u0621', '\u0641'];
+
+var ArabicAlefBetIntervalsEnd = ['\u063A', '\u064a'];
+
+var Link06 = [
+	1			+ 32 + 256 * 0x11,
+	1			+ 32 + 256 * 0x13,
+	1			+ 256 * 0x15,
+	1			+ 32 + 256 * 0x17,
+	1 + 2		+ 256 * 0x19,
+	1			+ 32 + 256 * 0x1D,
+	1 + 2		+ 256 * 0x1F,
+	1			+ 256 * 0x23,
+	1 + 2		+ 256 * 0x25,
+	1 + 2		+ 256 * 0x29,
+	1 + 2		+ 256 * 0x2D,
+	1 + 2		+ 256 * 0x31,
+	1 + 2		+ 256 * 0x35,
+	1			+ 256 * 0x39,
+	1			+ 256 * 0x3B,
+	1			+ 256 * 0x3D,
+	1			+ 256 * 0x3F,
+	1 + 2		+ 256 * 0x41,
+	1 + 2		+ 256 * 0x45,
+	1 + 2		+ 256 * 0x49,
+	1 + 2		+ 256 * 0x4D,
+	1 + 2		+ 256 * 0x51,
+	1 + 2		+ 256 * 0x55,
+	1 + 2		+ 256 * 0x59,
+	1 + 2		+ 256 * 0x5D,
+	0, 0, 0, 0, 0,	/* 0x63B - 0x63F */
+	1 + 2,
+	1 + 2		+ 256 * 0x61,
+	1 + 2		+ 256 * 0x65,
+	1 + 2		+ 256 * 0x69,
+	1 + 2		+ 16 + 256 * 0x6D,
+	1 + 2		+ 256 * 0x71,
+	1 + 2		+ 256 * 0x75,
+	1 + 2		+ 256 * 0x79,
+	1			+ 256 * 0x7D,
+	1			+ 256 * 0x7F,
+	1 + 2		+ 256 * 0x81,
+	4, 4, 4, 4,
+	4, 4, 4, 4, 	/* 0x64B - 0x652 */
+	0, 0, 0, 0, 0,
+	0, 0, 0, 0, 	/* 0x653 - 0x65B */
+	1			+ 256 * 0x85,
+	1			+ 256 * 0x87,
+	1			+ 256 * 0x89,
+	1			+ 256 * 0x8B,
+	0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0,/* 0x660 - 0x66F */
+	4,
+	0,
+	1			+ 32,
+	1			+ 32,
+	0,
+	1			+ 32,
+	1, 1,
+	1+2, 1+2, 1+2, 1+2, 1+2, 1+2,
+	1+2, 1+2, 1+2, 1+2, 1+2, 1+2,
+	1+2, 1+2, 1+2, 1+2,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1,
+	1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2,
+	1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2,
+	1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2,
+	1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2,
+	1,
+	1+2,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1+2,
+	1,
+	1+2, 1+2, 1+2, 1+2,
+	1, 1
+];
+
+var LinkFE = [
+	1 + 2,
+	1 + 2,
+	1 + 2, 0, 1+ 2, 0, 1+ 2,
+	1 + 2,
+	1+ 2, 1 + 2, 1+2, 1 + 2,
+	1+ 2, 1 + 2, 1+2, 1 + 2,
+	0, 0 + 32, 1 + 32, 0 + 32,
+	1 + 32, 0, 1, 0 + 32,
+	1 + 32, 0, 2, 1 + 2,
+	1, 0 + 32, 1 + 32, 0,
+	2, 1 + 2, 1, 0,
+	1, 0, 2, 1 + 2,
+	1, 0, 2, 1 + 2,
+	1, 0, 2, 1 + 2,
+	1, 0, 2, 1 + 2,
+	1, 0, 2, 1 + 2,
+	1, 0, 1, 0,
+	1, 0, 1, 0,
+	1, 0, 2, 1+2,
+	1, 0, 2, 1+2,
+	1, 0, 2, 1+2,
+	1, 0, 2, 1+2,
+	1, 0, 2, 1+2,
+	1, 0, 2, 1+2,
+	1, 0, 2, 1+2,
+	1, 0, 2, 1+2,
+	1, 0, 2, 1+2,
+	1, 0, 2, 1+2,
+	1, 0, 2, 1+2,
+	1, 0 + 16, 2 + 16, 1 + 2 +16,
+	1 + 16, 0, 2, 1+2,
+	1, 0, 2, 1+2,
+	1, 0, 2, 1+2,
+	1, 0, 1, 0,
+	1, 0, 2, 1+2,
+	1, 0, 1, 0,
+	1, 0, 1, 0,
+	1
+];
+var	impTab_LTR = [
+					/*		L,		R,		EN,		AN,		N,		IL,		Cond */
+	/* 0 LTR text	*/	[	0,		3,		0,		1,		0,		0,		0	],
+	/* 1 LTR+AN		*/	[	0,		3,		0,		1,		2,		2,		0	],
+	/* 2 LTR+AN+N	*/	[	0,		3,		0,		0x11,	2,		0,		1	],
+	/* 3 RTL text	*/	[	0,		3,		5,		5,		4,		1,		0	],
+	/* 4 RTL cont	*/	[	0,		3,		0x15,	0x15,	4,		0,		1	],
+	/* 5 RTL+EN/AN	*/	[	0,		3,		5,		5,		4,		2,		0	]
+];
+var impTab_RTL = [
+					/*		L,		R,		EN,		AN,		N,		IL,		Cond */
+	/* 0 RTL text	*/	[	2,		0,		1,		1,		0,		1,		0	],
+	/* 1 RTL+EN/AN	*/	[	2,		0,		1,		1,		0,		2,		0	],
+	/* 2 LTR text	*/	[	2,		0,		2,		1,		3,		2,		0	],
+	/* 3 LTR+cont	*/	[	2,		0,		2,		0x21,	3,		1,		1	]
+];
+
+var UBAT_L	= 0; /* left to right				*/
+var UBAT_R	= 1; /* right to left				*/
+var UBAT_EN = 2; /* European digit				*/
+var UBAT_AN = 3; /* Arabic-Indic digit			*/
+var UBAT_ON = 4; /* neutral						*/
+var UBAT_B	= 5; /* block separator				*/
+var UBAT_S	= 6; /* segment separator			*/
+var UBAT_AL = 7; /* Arabic Letter				*/
+var UBAT_WS = 8; /* white space					*/
+var UBAT_CS = 9; /* common digit separator		*/
+var UBAT_ES = 10; /* European digit separator	*/
+var UBAT_ET = 11; /* European digit terminator	*/
+var UBAT_NSM = 12; /* Non Spacing Mark			*/
+var UBAT_LRE = 13; /* LRE						*/
+var UBAT_RLE = 14; /* RLE						*/
+var UBAT_PDF = 15; /* PDF						*/
+var UBAT_LRO = 16; /* LRO						*/
+var UBAT_RLO = 17; /* RLO						*/
+var UBAT_BN	= 18; /* Boundary Neutral			*/
+
+var TBBASE = 100;
+
+var TB00 = TBBASE + 0;
+var TB05 = TBBASE + 1;
+var TB06 = TBBASE + 2;
+var TB07 = TBBASE + 3;
+var TB20 = TBBASE + 4;
+var TBFB = TBBASE + 5;
+var TBFE = TBBASE + 6;
+var TBFF = TBBASE + 7;
+
+var L	= UBAT_L;
+var R	= UBAT_R;
+var EN	= UBAT_EN;
+var AN	= UBAT_AN;
+var ON	= UBAT_ON;
+var B	= UBAT_B;
+var S	= UBAT_S;
+var AL	= UBAT_AL;
+var WS	= UBAT_WS;
+var CS	= UBAT_CS;
+var ES	= UBAT_ES;
+var ET	= UBAT_ET;
+var NSM	= UBAT_NSM;
+var LRE	= UBAT_LRE;
+var RLE	= UBAT_RLE;
+var PDF	= UBAT_PDF;
+var LRO	= UBAT_LRO;
+var RLO	= UBAT_RLO;
+var BN	= UBAT_BN;
+
+var MasterTable = [
+	/************************************************************************************************************************************/
+	/*		0		1		2		3		4		5		6		7		8		9		A		B		C		D		E		F	*/
+	/************************************************************************************************************************************/
+	/*0-*/	TB00,	L	,	L	,	L	,	L	,	TB05,	TB06,	TB07,	R	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*1-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*2-*/	TB20,	ON	,	ON	,	ON	,	L	,	ON	,	L	,	ON	,	L	,	ON	,	ON	,	ON	,	L	,	L	,	ON	,	ON	,
+	/*3-*/	L	,	L	,	L	,	L	,	L	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*4-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	L	,	L	,	ON	,
+	/*5-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*6-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*7-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*8-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*9-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	L	,
+	/*A-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	ON	,	ON	,	ON	,
+	/*B-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*C-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*D-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	L	,	L	,	ON	,	ON	,	L	,	L	,	ON	,	ON	,	L	,
+	/*E-*/	L	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*F-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	L	,	L	,	L	,	TBFB,	AL	,	AL	,	TBFE,	TBFF
+];
+
+delete TB00;
+delete TB05;
+delete TB06;
+delete TB07;
+delete TB20;
+delete TBFB;
+delete TBFE;
+delete TBFF;
+
+var UnicodeTable = [
+	[ /*	Table 00: Unicode 00xx */
+	/************************************************************************************************************************************/
+	/*		0		1		2		3		4		5		6		7		8		9		A		B		C		D		E		F	*/
+	/************************************************************************************************************************************/
+	/*0-*/	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	S	,	B	,	S	,	WS	,	B	,	BN	,	BN	,
+	/*1-*/	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	B	,	B	,	B	,	S	,
+	/*2-*/	WS	,	ON	,	ON	,	ET	,	ET	,	ET	,	ON	,	ON	,	ON	,	ON	,	ON	,	ES	,	CS	,	ES	,	CS	,	CS	,
+	/*3-*/	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	CS	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*4-*/	ON	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*5-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*6-*/	ON	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*7-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	ON	,	ON	,	ON	,	ON	,	BN	,
+	/*8-*/	BN	,	BN	,	BN	,	BN	,	BN	,	B	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,
+	/*9-*/	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,
+	/*A-*/	CS	,	ON	,	ET	,	ET	,	ET	,	ET	,	ON	,	ON	,	ON	,	ON	,	L	,	ON	,	ON	,	BN	,	ON	,	ON	,
+	/*B-*/	ET	,	ET	,	EN	,	EN	,	ON	,	L	,	ON	,	ON	,	ON	,	EN	,	L	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*C-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*D-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	ON	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*E-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*F-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	ON	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L
+	],
+	[ /*	Table 01: Unicode 05xx */
+	/************************************************************************************************************************************/
+	/*		0		1		2		3		4		5		6		7		8		9		A		B		C		D		E		F	*/
+	/************************************************************************************************************************************/
+	/*0-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*1-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*2-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	 , ON	,	ON	,
+	/*3-*/	ON	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*4-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*5-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	ON	,	ON	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*6-*/	ON	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*7-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*8-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	ON	,	L	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*9-*/	ON	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,
+	/*A-*/	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,
+	/*B-*/	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	R	,	NSM	,
+	/*C-*/	R	,	NSM	,	NSM	,	R	,	NSM	,	NSM	,	R	,	NSM	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*D-*/	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,
+	/*E-*/	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*F-*/	R	,	R	,	R	,	R	,	R	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON
+	],
+	[ /*	Table 02: Unicode 06xx */
+	/************************************************************************************************************************************/
+	/*		0		1		2		3		4		5		6		7		8		9		A		B		C		D		E		F	*/
+	/************************************************************************************************************************************/
+	/*0-*/	AN	,	AN	,	AN	,	AN	,	ON	,	ON	,	ON	,	ON	,	AL	,	ET	,	ET	,	AL	,	CS	,	AL	,	ON	,	ON	,
+	/*1-*/	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	AL	,	ON	,	ON	,	AL	,	AL	,
+	/*2-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*3-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*4-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,
+	/*5-*/	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,
+	/*6-*/	AN	,	AN	,	AN	,	AN	,	AN	,	AN	,	AN	,	AN	,	AN	,	AN	,	ET	,	AN	,	AN	,	AL	,	AL	,	AL	,
+	/*7-*/	NSM	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*8-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*9-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*A-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*B-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*C-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*D-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	AN	,	ON	,	NSM	,
+	/*E-*/	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	AL	,	AL	,	NSM	,	NSM	,	ON	,	NSM	,	NSM	,	NSM	,	NSM	,	AL	,	AL	,
+	/*F-*/	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL
+	],
+	[	/*	Table	03:	Unicode	07xx	*/
+	/************************************************************************************************************************************/
+	/*		0		1		2		3		4		5		6		7		8		9		A		B		C		D		E		F	*/
+	/************************************************************************************************************************************/
+	/*0-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	ON	,	AL	,
+	/*1-*/	AL	,	NSM	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*2-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*3-*/	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,
+	/*4-*/	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	ON	,	ON	,	AL	,	AL	,	AL	,
+	/*5-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*6-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*7-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*8-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*9-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*A-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,
+	/*B-*/	NSM	,	AL	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*C-*/	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,
+	/*D-*/	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,
+	/*E-*/	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,
+	/*F-*/	NSM	,	NSM	,	NSM	,	NSM	,	R	,	R	,	ON	,	ON	,	ON	,	ON	,	R	,	ON	,	ON	,	ON	,	ON	,	ON
+	],
+	[	/*	Table	04:	Unicode	20xx	*/
+	/************************************************************************************************************************************/
+	/*		0		1		2		3		4		5		6		7		8		9		A		B		C		D		E		F	*/
+	/************************************************************************************************************************************/
+	/*0-*/	WS	,	WS	,	WS	,	WS	,	WS	,	WS	,	WS	,	WS	,	WS	,	WS	,	WS	,	BN	,	BN	,	BN	,	L	,	R	,
+	/*1-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*2-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	WS	,	B	,	LRE	,	RLE	,	PDF	,	LRO	,	RLO	,	CS	,
+	/*3-*/	ET	,	ET	,	ET	,	ET	,	ET	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*4-*/	ON	,	ON	,	ON	,	ON	,	CS	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*5-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	WS	,
+	/*6-*/	BN	,	BN	,	BN	,	BN	,	BN	,	ON	,	ON	,	ON	,	ON	,	ON	,	BN	,	BN	,	BN	,	BN	,	BN	,	BN	,
+	/*7-*/	EN	,	L	,	ON	,	ON	,	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	ES	,	ES	,	ON	,	ON	,	ON	,	L	,
+	/*8-*/	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	ES	,	ES	,	ON	,	ON	,	ON	,	ON	,
+	/*9-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	ON	,	ON	,	ON	,
+	/*A-*/	ET	,	ET	,	ET	,	ET	,	ET	,	ET	,	ET	,	ET	,	ET	,	ET	,	ET	,	ET	,	ET	,	ET	,	ET	,	ET	,
+	/*B-*/	ET	,	ET	,	ET	,	ET	,	ET	,	ET	,	ET	,	ET	,	ET	,	ET	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*C-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*D-*/	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,
+	/*E-*/	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,
+	/*F-*/	NSM	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON
+	],
+	[	/*	Table	05:	Unicode	FBxx	*/
+	/************************************************************************************************************************************/
+	/*		0		1		2		3		4		5		6		7		8		9		A		B		C		D		E		F	*/
+	/************************************************************************************************************************************/
+	/*0-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*1-*/	ON	,	ON	,	ON	,	L	,	L	,	L	,	L	,	L	,	ON	,	ON	,	ON	,	ON	,	ON	,	R	,	NSM	,	R	,
+	/*2-*/	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	ES	,	R	,	R	,	R	,	R	,	R	,	R	,
+	/*3-*/	R	,	R	,	R	,	R	,	R	,	R	,	R	,	ON	,	R	,	R	,	R	,	R	,	R	,	ON	,	R	,	ON	,
+	/*4-*/	R	,	R	,	ON	,	R	,	R	,	ON	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,	R	,
+	/*5-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*6-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*7-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*8-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*9-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*A-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*B-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*C-*/	AL	,	AL	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*D-*/	ON	,	ON	,	ON	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*E-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*F-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL
+	],
+	[	/*	Table	06:	Unicode	FExx	*/
+	/************************************************************************************************************************************/
+	/*		0		1		2		3		4		5		6		7		8		9		A		B		C		D		E		F	*/
+	/************************************************************************************************************************************/
+	/*0-*/	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,
+	/*1-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*2-*/	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	NSM	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*3-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*4-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*5-*/	CS	,	ON	,	CS	,	ON	,	ON	,	CS	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ET	,
+	/*6-*/	ON	,	ON	,	ES	,	ES	,	ON	,	ON	,	ON	,	ON	,	ON	,	ET	,	ET	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*7-*/	AL	,	AL	,	AL	,	AL	,	AL	,	ON	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*8-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*9-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*A-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*B-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*C-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*D-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*E-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,
+	/*F-*/	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	AL	,	ON	,	ON	,	BN
+	],
+	[	/*	Table	07:	Unicode	FFxx	*/
+	/************************************************************************************************************************************/
+	/*		0		1		2		3		4		5		6		7		8		9		A		B		C		D		E		F	*/
+	/************************************************************************************************************************************/
+	/*0-*/	ON	,	ON	,	ON	,	ET	,	ET	,	ET	,	ON	,	ON	,	ON	,	ON	,	ON	,	ES	,	CS	,	ES	,	CS	,	CS	,
+	/*1-*/	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	EN	,	CS	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*2-*/	ON	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*3-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*4-*/	ON	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*5-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*6-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*7-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*8-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*9-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*A-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*B-*/	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	L	,	ON	,
+	/*C-*/	ON	,	ON	,	L	,	L	,	L	,	L	,	L	,	L	,	ON	,	ON	,	L	,	L	,	L	,	L	,	L	,	L	,
+	/*D-*/	ON	,	ON	,	L	,	L	,	L	,	L	,	L	,	L	,	ON	,	ON	,	L	,	L	,	L	,	ON	,	ON	,	ON	,
+	/*E-*/	ET	,	ET	,	ON	,	ON	,	ON	,	ET	,	ET	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,
+	/*F-*/	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON	,	ON
+	]
+];
+
+delete L;
+delete R;
+delete EN;
+delete AN;
+delete ON;
+delete B;
+delete S;
+delete AL;
+delete WS;
+delete CS;
+delete ES;
+delete ET;
+delete NSM;
+delete LRE;
+delete RLE;
+delete PDF;
+delete LRO;
+delete RLO;
+delete BN;
+
+return dojox.string.BidiEngine;
+});
diff --git a/dojox/string/Builder.js b/dojox/string/Builder.js
index d5df55f..4ceb9c5 100644
--- a/dojox/string/Builder.js
+++ b/dojox/string/Builder.js
@@ -1,130 +1,133 @@
-dojo.provide("dojox.string.Builder");
-
-dojox.string.Builder = function(/*String?*/str){
-	//	summary:
-	//		A fast buffer for creating large strings.
-	//
-	//	length: Number
-	//		The current length of the internal string.
+define(["dojo/_base/lang"], 
+  function(lang){
+	lang.getObject("string", true, dojox).Builder = 
+	  function(/*String?*/str){
+		//	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 = "";
-	this.length = 0;
-	
-	this.append = function(/* String... */s){
-		// summary: Append all arguments to the end of the buffer
-		if(arguments.length>1){
-			/*
-				This is a loop unroll was designed specifically for Firefox;
-				it would seem that static index access on an Arguments
-				object is a LOT faster than doing dynamic index access.
-				Therefore, we create a buffer string and take advantage
-				of JS's switch fallthrough.  The peformance of this method
-				comes very close to straight up string concatenation (+=).
+		//	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 = "";
+		this.length = 0;
+		
+		this.append = function(/* String... */s){
+			// summary: Append all arguments to the end of the buffer
+			if(arguments.length>1){
+				/*
+					This is a loop unroll was designed specifically for Firefox;
+					it would seem that static index access on an Arguments
+					object is a LOT faster than doing dynamic index access.
+					Therefore, we create a buffer string and take advantage
+					of JS's switch fallthrough.  The peformance of this method
+					comes very close to straight up string concatenation (+=).
 
-				If the arguments object length is greater than 9, we fall
-				back to standard dynamic access.
+					If the arguments object length is greater than 9, we fall
+					back to standard dynamic access.
 
-				This optimization seems to have no real effect on either
-				Safari or Opera, so we just use it for all.
+					This optimization seems to have no real effect on either
+					Safari or Opera, so we just use it for all.
 
-				It turns out also that this loop unroll can increase performance
-				significantly with Internet Explorer, particularly when
-				as many arguments are provided as possible.
+					It turns out also that this loop unroll can increase performance
+					significantly with Internet Explorer, particularly when
+					as many arguments are provided as possible.
 
-				Loop unroll per suggestion from Kris Zyp, implemented by
-				Tom Trenka.
+					Loop unroll per suggestion from Kris Zyp, implemented by
+					Tom Trenka.
 
-				Note: added empty string to force a string cast if needed.
-			 */
-			var tmp="", l=arguments.length;
-			switch(l){
-				case 9: tmp=""+arguments[8]+tmp;
-				case 8: tmp=""+arguments[7]+tmp;
-				case 7: tmp=""+arguments[6]+tmp;
-				case 6: tmp=""+arguments[5]+tmp;
-				case 5: tmp=""+arguments[4]+tmp;
-				case 4: tmp=""+arguments[3]+tmp;
-				case 3: tmp=""+arguments[2]+tmp;
-				case 2: {
-					b+=""+arguments[0]+arguments[1]+tmp;
-					break;
-				}
-				default: {
-					var i=0;
-					while(i<arguments.length){
-						tmp += arguments[i++];
+					Note: added empty string to force a string cast if needed.
+				 */
+				var tmp="", l=arguments.length;
+				switch(l){
+					case 9: tmp=""+arguments[8]+tmp;
+					case 8: tmp=""+arguments[7]+tmp;
+					case 7: tmp=""+arguments[6]+tmp;
+					case 6: tmp=""+arguments[5]+tmp;
+					case 5: tmp=""+arguments[4]+tmp;
+					case 4: tmp=""+arguments[3]+tmp;
+					case 3: tmp=""+arguments[2]+tmp;
+					case 2: {
+						b+=""+arguments[0]+arguments[1]+tmp;
+						break;
+					}
+					default: {
+						var i=0;
+						while(i<arguments.length){
+							tmp += arguments[i++];
+						}
+						b += tmp;
 					}
-					b += tmp;
 				}
+			} else {
+				b += s;
 			}
-		} else {
-			b += s;
-		}
-		this.length = b.length;
-		return this;	//	dojox.string.Builder
-	};
-	
-	this.concat = function(/*String...*/s){
-		//	summary:
-		//		Alias for append.
-		return this.append.apply(this, arguments);	//	dojox.string.Builder
-	};
-	
-	this.appendArray = function(/*Array*/strings) {
-		//	summary:
-		//		Append an array of items to the internal buffer.
+			this.length = b.length;
+			return this;	//	dojox.string.Builder
+		};
+		
+		this.concat = function(/*String...*/s){
+			//	summary:
+			//		Alias for append.
+			return this.append.apply(this, arguments);	//	dojox.string.Builder
+		};
+		
+		this.appendArray = function(/*Array*/strings) {
+			//	summary:
+			//		Append an array of items to the internal buffer.
 
-		//	Changed from String.prototype.concat.apply because of IE.
-		return this.append.apply(this, strings);	//	dojox.string.Builder
-	};
-	
-	this.clear = function(){
-		//	summary:
-		//		Remove all characters from the buffer.
-		b = "";
-		this.length = 0;
-		return this;	//	dojox.string.Builder
-	};
-	
-	this.replace = function(/* String */oldStr, /* String */ newStr){
-		// 	summary:
-		//		Replace instances of one string with another in the buffer.
-		b = b.replace(oldStr,newStr);
-		this.length = b.length;
-		return this;	//	dojox.string.Builder
-	};
-	
-	this.remove = function(/* Number */start, /* Number? */len){
-		//	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; }
-		if(len == 0){ return this; }
-		b = b.substr(0, start) + b.substr(start+len);
-		this.length = b.length;
-		return this;	//	dojox.string.Builder
-	};
-	
-	this.insert = function(/* Number */index, /* String */str){
-		//	summary:
-		//		Insert string str starting at index.
-		if(index == 0){
-			b = str + b;
-		}else{
-			b = b.slice(0, index) + str + b.slice(index);
-		}
-		this.length = b.length;
-		return this;	//	dojox.string.Builder
-	};
-	
-	this.toString = function(){
-		//	summary:
-		//		Return the string representation of the internal buffer.
-		return b;	//	String
-	};
+			//	Changed from String.prototype.concat.apply because of IE.
+			return this.append.apply(this, strings);	//	dojox.string.Builder
+		};
+		
+		this.clear = function(){
+			//	summary:
+			//		Remove all characters from the buffer.
+			b = "";
+			this.length = 0;
+			return this;	//	dojox.string.Builder
+		};
+		
+		this.replace = function(/* String */oldStr, /* String */ newStr){
+			// 	summary:
+			//		Replace instances of one string with another in the buffer.
+			b = b.replace(oldStr,newStr);
+			this.length = b.length;
+			return this;	//	dojox.string.Builder
+		};
+		
+		this.remove = function(/* Number */start, /* Number? */len){
+			//	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; }
+			if(len == 0){ return this; }
+			b = b.substr(0, start) + b.substr(start+len);
+			this.length = b.length;
+			return this;	//	dojox.string.Builder
+		};
+		
+		this.insert = function(/* Number */index, /* String */str){
+			//	summary:
+			//		Insert string str starting at index.
+			if(index == 0){
+				b = str + b;
+			}else{
+				b = b.slice(0, index) + str + b.slice(index);
+			}
+			this.length = b.length;
+			return this;	//	dojox.string.Builder
+		};
+		
+		this.toString = function(){
+			//	summary:
+			//		Return the string representation of the internal buffer.
+			return b;	//	String
+		};
 
-	//	initialize the buffer.
-	if(str){ this.append(str); }
-};
+		//	initialize the buffer.
+		if(str){ this.append(str); }
+	};
+	return dojox.string.Builder;
+});
diff --git a/dojox/string/sprintf.js b/dojox/string/sprintf.js
index 57601cf..7da4fc3 100644
--- a/dojox/string/sprintf.js
+++ b/dojox/string/sprintf.js
@@ -1,402 +1,409 @@
-dojo.provide("dojox.string.sprintf");
+define([
+	"dojo/_base/kernel",	// dojo.getObject, dojo.mixin
+	"dojo/_base/lang",	// dojo.extend
+	"dojo/_base/sniff",	// dojo.isOpera
+	 "./tokenize"
+], function(dojo, lang, has, tokenize){
+	var strLib = lang.getObject("string", true, dojox);
 
-dojo.require("dojox.string.tokenize");
+	strLib.sprintf = function(/*String*/ format, /*mixed...*/ filler){
+		for(var args = [], i = 1; i < arguments.length; i++){
+			args.push(arguments[i]);
+		}
+		var formatter = new strLib.sprintf.Formatter(format);
+		return formatter.format.apply(formatter, args);
+	};
 
-dojox.string.sprintf = function(/*String*/ format, /*mixed...*/ filler){
-	for(var args = [], i = 1; i < arguments.length; i++){
-		args.push(arguments[i]);
-	}
-	var formatter = new dojox.string.sprintf.Formatter(format);
-	return formatter.format.apply(formatter, args);
-}
+	strLib.sprintf.Formatter = function(/*String*/ format){
+		var tokens = [];
+		this._mapped = false;
+		this._format = format;
+		this._tokens = tokenize(format, this._re, this._parseDelim, this);
+	};
 
-dojox.string.sprintf.Formatter = function(/*String*/ format){
-	var tokens = [];
-	this._mapped = false;
-	this._format = format;
-	this._tokens = dojox.string.tokenize(format, this._re, this._parseDelim, this);
-}
-dojo.extend(dojox.string.sprintf.Formatter, {
-	_re: /\%(?:\(([\w_]+)\)|([1-9]\d*)\$)?([0 +\-\#]*)(\*|\d+)?(\.)?(\*|\d+)?[hlL]?([\%scdeEfFgGiouxX])/g,
-	_parseDelim: function(mapping, intmapping, flags, minWidth, period, precision, specifier){
-		if(mapping){
-			this._mapped = true;
-		}
-		return {
-			mapping: mapping,
-			intmapping: intmapping,
-			flags: flags,
-			_minWidth: minWidth, // May be dependent on parameters
-			period: period,
-			_precision: precision, // May be dependent on parameters
-			specifier: specifier
-		};
-	},
-	_specifiers: {
-		b: {
-			base: 2,
-			isInt: true
-		},
-		o: {
-			base: 8,
-			isInt: true
-		},
-		x: {
-			base: 16,
-			isInt: true
-		},
-		X: {
-			extend: ["x"],
-			toUpper: true
-		},
-		d: {
-			base: 10,
-			isInt: true
-		},
-		i: {
-			extend: ["d"]
-		},
-		u: {
-			extend: ["d"],
-			isUnsigned: true
+	lang.extend(strLib.sprintf.Formatter, {
+		_re: /\%(?:\(([\w_]+)\)|([1-9]\d*)\$)?([0 +\-\#]*)(\*|\d+)?(\.)?(\*|\d+)?[hlL]?([\%scdeEfFgGiouxX])/g,
+		_parseDelim: function(mapping, intmapping, flags, minWidth, period, precision, specifier){
+			if(mapping){
+				this._mapped = true;
+			}
+			return {
+				mapping: mapping,
+				intmapping: intmapping,
+				flags: flags,
+				_minWidth: minWidth, // May be dependent on parameters
+				period: period,
+				_precision: precision, // May be dependent on parameters
+				specifier: specifier
+			};
 		},
-		c: {
-			setArg: function(token){
-				if(!isNaN(token.arg)){
-					var num = parseInt(token.arg);
-					if(num < 0 || num > 127){
-						throw new Error("invalid character code passed to %c in sprintf");
+		_specifiers: {
+			b: {
+				base: 2,
+				isInt: true
+			},
+			o: {
+				base: 8,
+				isInt: true
+			},
+			x: {
+				base: 16,
+				isInt: true
+			},
+			X: {
+				extend: ["x"],
+				toUpper: true
+			},
+			d: {
+				base: 10,
+				isInt: true
+			},
+			i: {
+				extend: ["d"]
+			},
+			u: {
+				extend: ["d"],
+				isUnsigned: true
+			},
+			c: {
+				setArg: function(token){
+					if(!isNaN(token.arg)){
+						var num = parseInt(token.arg);
+						if(num < 0 || num > 127){
+							throw new Error("invalid character code passed to %c in sprintf");
+						}
+						token.arg = isNaN(num) ? "" + num : String.fromCharCode(num);
 					}
-					token.arg = isNaN(num) ? "" + num : String.fromCharCode(num);
 				}
+			},
+			s: {
+				setMaxWidth: function(token){
+					token.maxWidth = (token.period == ".") ? token.precision : -1;
+				}
+			},
+			e: {
+				isDouble: true,
+				doubleNotation: "e"
+			},
+			E: {
+				extend: ["e"],
+				toUpper: true
+			},
+			f: {
+				isDouble: true,
+				doubleNotation: "f"
+			},
+			F: {
+				extend: ["f"]
+			},
+			g: {
+				isDouble: true,
+				doubleNotation: "g"
+			},
+			G: {
+				extend: ["g"],
+				toUpper: true
 			}
 		},
-		s: {
-			setMaxWidth: function(token){
-				token.maxWidth = (token.period == ".") ? token.precision : -1;
+		format: function(/*mixed...*/ filler){
+			if(this._mapped && typeof filler != "object"){
+				throw new Error("format requires a mapping");
 			}
-		},
-		e: {
-			isDouble: true,
-			doubleNotation: "e"
-		},
-		E: {
-			extend: ["e"],
-			toUpper: true
-		},
-		f: {
-			isDouble: true,
-			doubleNotation: "f"
-		},
-		F: {
-			extend: ["f"]
-		},
-		g: {
-			isDouble: true,
-			doubleNotation: "g"
-		},
-		G: {
-			extend: ["g"],
-			toUpper: true
-		}
-	},
-	format: function(/*mixed...*/ filler){
-		if(this._mapped && typeof filler != "object"){
-			throw new Error("format requires a mapping");
-		}
 
-		var str = "";
-		var position = 0;
-		for(var i = 0, token; i < this._tokens.length; i++){
-			token = this._tokens[i];
-			if(typeof token == "string"){
-				str += token;
-			}else{
-				if(this._mapped){
-					if(typeof filler[token.mapping] == "undefined"){
-						throw new Error("missing key " + token.mapping);
-					}
-					token.arg = filler[token.mapping];
+			var str = "";
+			var position = 0;
+			for(var i = 0, token; i < this._tokens.length; i++){
+				token = this._tokens[i];
+				if(typeof token == "string"){
+					str += token;
 				}else{
-					if(token.intmapping){
-						var position = parseInt(token.intmapping) - 1;
-					}
-					if(position >= arguments.length){
-						throw new Error("got " + arguments.length + " printf arguments, insufficient for '" + this._format + "'");
+					if(this._mapped){
+						if(typeof filler[token.mapping] == "undefined"){
+							throw new Error("missing key " + token.mapping);
+						}
+						token.arg = filler[token.mapping];
+					}else{
+						if(token.intmapping){
+							var position = parseInt(token.intmapping) - 1;
+						}
+						if(position >= arguments.length){
+							throw new Error("got " + arguments.length + " printf arguments, insufficient for '" + this._format + "'");
+						}
+						token.arg = arguments[position++];
 					}
-					token.arg = arguments[position++];
-				}
 
-				if(!token.compiled){
-					token.compiled = true;
-					token.sign = "";
-					token.zeroPad = false;
-					token.rightJustify = false;
-					token.alternative = false;
+					if(!token.compiled){
+						token.compiled = true;
+						token.sign = "";
+						token.zeroPad = false;
+						token.rightJustify = false;
+						token.alternative = false;
 
-					var flags = {};
-					for(var fi = token.flags.length; fi--;){
-						var flag = token.flags.charAt(fi);
-						flags[flag] = true;
-						switch(flag){
-							case " ":
-								token.sign = " ";
-								break;
-							case "+":
-								token.sign = "+";
-								break;
-							case "0":
-								token.zeroPad = (flags["-"]) ? false : true;
-								break;
-							case "-":
-								token.rightJustify = true;
-								token.zeroPad = false;
-								break;
-							case "\#":
-								token.alternative = true;
-								break;
-							default:
-								throw Error("bad formatting flag '" + token.flags.charAt(fi) + "'");
+						var flags = {};
+						for(var fi = token.flags.length; fi--;){
+							var flag = token.flags.charAt(fi);
+							flags[flag] = true;
+							switch(flag){
+								case " ":
+									token.sign = " ";
+									break;
+								case "+":
+									token.sign = "+";
+									break;
+								case "0":
+									token.zeroPad = (flags["-"]) ? false : true;
+									break;
+								case "-":
+									token.rightJustify = true;
+									token.zeroPad = false;
+									break;
+								case "\#":
+									token.alternative = true;
+									break;
+								default:
+									throw Error("bad formatting flag '" + token.flags.charAt(fi) + "'");
+							}
 						}
-					}
 
-					token.minWidth = (token._minWidth) ? parseInt(token._minWidth) : 0;
-					token.maxWidth = -1;
-					token.toUpper = false;
-					token.isUnsigned = false;
-					token.isInt = false;
-					token.isDouble = false;
-					token.precision = 1;
-					if(token.period == '.'){
-						if(token._precision){
-							token.precision = parseInt(token._precision);
-						}else{
-							token.precision = 0;
+						token.minWidth = (token._minWidth) ? parseInt(token._minWidth) : 0;
+						token.maxWidth = -1;
+						token.toUpper = false;
+						token.isUnsigned = false;
+						token.isInt = false;
+						token.isDouble = false;
+						token.precision = 1;
+						if(token.period == '.'){
+							if(token._precision){
+								token.precision = parseInt(token._precision);
+							}else{
+								token.precision = 0;
+							}
 						}
-					}
 
-					var mixins = this._specifiers[token.specifier];
-					if(typeof mixins == "undefined"){
-						throw new Error("unexpected specifier '" + token.specifier + "'");
-					}
-					if(mixins.extend){
-						dojo.mixin(mixins, this._specifiers[mixins.extend]);
-						delete mixins.extend;
+						var mixins = this._specifiers[token.specifier];
+						if(typeof mixins == "undefined"){
+							throw new Error("unexpected specifier '" + token.specifier + "'");
+						}
+						if(mixins.extend){
+							lang.mixin(mixins, this._specifiers[mixins.extend]);
+							delete mixins.extend;
+						}
+						lang.mixin(token, mixins);
 					}
-					dojo.mixin(token, mixins);
-				}
-
-				if(typeof token.setArg == "function"){
-					token.setArg(token);
-				}
-
-				if(typeof token.setMaxWidth == "function"){
-					token.setMaxWidth(token);
-				}
 
-				if(token._minWidth == "*"){
-					if(this._mapped){
-						throw new Error("* width not supported in mapped formats");
+					if(typeof token.setArg == "function"){
+						token.setArg(token);
 					}
-					token.minWidth = parseInt(arguments[position++]);
-					if(isNaN(token.minWidth)){
-						throw new Error("the argument for * width at position " + position + " is not a number in " + this._format);
-					}
-					// negative width means rightJustify
-					if (token.minWidth < 0) {
-						token.rightJustify = true;
-						token.minWidth = -token.minWidth;
-					}
-				}
 
-				if(token._precision == "*" && token.period == "."){
-					if(this._mapped){
-						throw new Error("* precision not supported in mapped formats");
-					}
-					token.precision = parseInt(arguments[position++]);
-					if(isNaN(token.precision)){
-						throw Error("the argument for * precision at position " + position + " is not a number in " + this._format);
+					if(typeof token.setMaxWidth == "function"){
+						token.setMaxWidth(token);
 					}
-					// negative precision means unspecified
-					if (token.precision < 0) {
-						token.precision = 1;
-						token.period = '';
+
+					if(token._minWidth == "*"){
+						if(this._mapped){
+							throw new Error("* width not supported in mapped formats");
+						}
+						token.minWidth = parseInt(arguments[position++]);
+						if(isNaN(token.minWidth)){
+							throw new Error("the argument for * width at position " + position + " is not a number in " + this._format);
+						}
+						// negative width means rightJustify
+						if (token.minWidth < 0) {
+							token.rightJustify = true;
+							token.minWidth = -token.minWidth;
+						}
 					}
-				}
 
-				if(token.isInt){
-					// a specified precision means no zero padding
-					if(token.period == '.'){
-						token.zeroPad = false;
+					if(token._precision == "*" && token.period == "."){
+						if(this._mapped){
+							throw new Error("* precision not supported in mapped formats");
+						}
+						token.precision = parseInt(arguments[position++]);
+						if(isNaN(token.precision)){
+							throw Error("the argument for * precision at position " + position + " is not a number in " + this._format);
+						}
+						// negative precision means unspecified
+						if (token.precision < 0) {
+							token.precision = 1;
+							token.period = '';
+						}
 					}
-					this.formatInt(token);
-				}else if(token.isDouble){
-					if(token.period != '.'){
-						token.precision = 6;
+
+					if(token.isInt){
+						// a specified precision means no zero padding
+						if(token.period == '.'){
+							token.zeroPad = false;
+						}
+						this.formatInt(token);
+					}else if(token.isDouble){
+						if(token.period != '.'){
+							token.precision = 6;
+						}
+						this.formatDouble(token);
 					}
-					this.formatDouble(token);
-				}
-				this.fitField(token);
+					this.fitField(token);
 
-				str += "" + token.arg;
+					str += "" + token.arg;
+				}
 			}
-		}
 
-		return str;
-	},
-	_zeros10: '0000000000',
-	_spaces10: '          ',
-	formatInt: function(token) {
-		var i = parseInt(token.arg);
-		if(!isFinite(i)){ // isNaN(f) || f == Number.POSITIVE_INFINITY || f == Number.NEGATIVE_INFINITY)
-			// allow this only if arg is number
-			if(typeof token.arg != "number"){
-				throw new Error("format argument '" + token.arg + "' not an integer; parseInt returned " + i);
+			return str;
+		},
+		_zeros10: '0000000000',
+		_spaces10: '          ',
+		formatInt: function(token) {
+			var i = parseInt(token.arg);
+			if(!isFinite(i)){ // isNaN(f) || f == Number.POSITIVE_INFINITY || f == Number.NEGATIVE_INFINITY)
+				// allow this only if arg is number
+				if(typeof token.arg != "number"){
+					throw new Error("format argument '" + token.arg + "' not an integer; parseInt returned " + i);
+				}
+				//return '' + i;
+				i = 0;
 			}
-			//return '' + i;
-			i = 0;
-		}
 
-		// if not base 10, make negatives be positive
-		// otherwise, (-10).toString(16) is '-a' instead of 'fffffff6'
-		if(i < 0 && (token.isUnsigned || token.base != 10)){
-			i = 0xffffffff + i + 1;
-		}
+			// if not base 10, make negatives be positive
+			// otherwise, (-10).toString(16) is '-a' instead of 'fffffff6'
+			if(i < 0 && (token.isUnsigned || token.base != 10)){
+				i = 0xffffffff + i + 1;
+			}
 
-		if(i < 0){
-			token.arg = (- i).toString(token.base);
-			this.zeroPad(token);
-			token.arg = "-" + token.arg;
-		}else{
-			token.arg = i.toString(token.base);
-			// need to make sure that argument 0 with precision==0 is formatted as ''
-			if(!i && !token.precision){
-				token.arg = "";
-			}else{
+			if(i < 0){
+				token.arg = (- i).toString(token.base);
 				this.zeroPad(token);
+				token.arg = "-" + token.arg;
+			}else{
+				token.arg = i.toString(token.base);
+				// need to make sure that argument 0 with precision==0 is formatted as ''
+				if(!i && !token.precision){
+					token.arg = "";
+				}else{
+					this.zeroPad(token);
+				}
+				if(token.sign){
+					token.arg = token.sign + token.arg;
+				}
 			}
-			if(token.sign){
-				token.arg = token.sign + token.arg;
-			}
-		}
-		if(token.base == 16){
-			if(token.alternative){
-				token.arg = '0x' + token.arg;
+			if(token.base == 16){
+				if(token.alternative){
+					token.arg = '0x' + token.arg;
+				}
+				token.arg = token.toUpper ? token.arg.toUpperCase() : token.arg.toLowerCase();
 			}
-			token.arg = token.toUpper ? token.arg.toUpperCase() : token.arg.toLowerCase();
-		}
-		if(token.base == 8){
-			if(token.alternative && token.arg.charAt(0) != '0'){
-				token.arg = '0' + token.arg;
+			if(token.base == 8){
+				if(token.alternative && token.arg.charAt(0) != '0'){
+					token.arg = '0' + token.arg;
+				}
 			}
-		}
-	},
-	formatDouble: function(token) {
-		var f = parseFloat(token.arg);
-		if(!isFinite(f)){ // isNaN(f) || f == Number.POSITIVE_INFINITY || f == Number.NEGATIVE_INFINITY)
-			// allow this only if arg is number
-			if(typeof token.arg != "number"){
-				throw new Error("format argument '" + token.arg + "' not a float; parseFloat returned " + f);
+		},
+		formatDouble: function(token) {
+			var f = parseFloat(token.arg);
+			if(!isFinite(f)){ // isNaN(f) || f == Number.POSITIVE_INFINITY || f == Number.NEGATIVE_INFINITY)
+				// allow this only if arg is number
+				if(typeof token.arg != "number"){
+					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')
+				// this is not commonly implemented though.
+				//return '' + f;
+				f = 0;
 			}
-			// C99 says that 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;
-		}
 
-		switch(token.doubleNotation) {
-			case 'e': {
-				token.arg = f.toExponential(token.precision);
-				break;
-			}
-			case 'f': {
-				token.arg = f.toFixed(token.precision);
-				break;
-			}
-			case 'g': {
-				// C says use 'e' notation if exponent is < -4 or is >= prec
-				// ECMAScript for toPrecision says use exponential notation if exponent is >= prec,
-				// though step 17 of toPrecision indicates a test for < -6 to force exponential.
-				if(Math.abs(f) < 0.0001){
-					//print("forcing exponential notation for f=" + f);
-					token.arg = f.toExponential(token.precision > 0 ? token.precision - 1 : token.precision);
-				}else{
-					token.arg = f.toPrecision(token.precision);
+			switch(token.doubleNotation) {
+				case 'e': {
+					token.arg = f.toExponential(token.precision);
+					break;
+				}
+				case 'f': {
+					token.arg = f.toFixed(token.precision);
+					break;
 				}
+				case 'g': {
+					// C says use 'e' notation if exponent is < -4 or is >= prec
+					// ECMAScript for toPrecision says use exponential notation if exponent is >= prec,
+					// though step 17 of toPrecision indicates a test for < -6 to force exponential.
+					if(Math.abs(f) < 0.0001){
+						//print("forcing exponential notation for f=" + f);
+						token.arg = f.toExponential(token.precision > 0 ? token.precision - 1 : token.precision);
+					}else{
+						token.arg = f.toPrecision(token.precision);
+					}
 
-				// In C, unlike 'f', 'gG' removes trailing 0s from fractional part, unless alternative format flag ("#").
-				// But ECMAScript formats toPrecision as 0.00100000. So remove trailing 0s.
-				if(!token.alternative){
-					//print("replacing trailing 0 in '" + s + "'");
-					token.arg = token.arg.replace(/(\..*[^0])0*/, "$1");
-					// if fractional part is entirely 0, remove it and decimal point
-					token.arg = token.arg.replace(/\.0*e/, 'e').replace(/\.0$/,'');
+					// In C, unlike 'f', 'gG' removes trailing 0s from fractional part, unless alternative format flag ("#").
+					// But ECMAScript formats toPrecision as 0.00100000. So remove trailing 0s.
+					if(!token.alternative){
+						//print("replacing trailing 0 in '" + s + "'");
+						token.arg = token.arg.replace(/(\..*[^0])0*/, "$1");
+						// if fractional part is entirely 0, remove it and decimal point
+						token.arg = token.arg.replace(/\.0*e/, 'e').replace(/\.0$/,'');
+					}
+					break;
 				}
-				break;
+				default: throw new Error("unexpected double notation '" + token.doubleNotation + "'");
 			}
-			default: throw new Error("unexpected double notation '" + token.doubleNotation + "'");
-		}
 
-		// C says that exponent must have at least two digits.
-		// But ECMAScript does not; toExponential results in things like "1.000000e-8" and "1.000000e+8".
-		// Note that s.replace(/e([\+\-])(\d)/, "e$10$2") won't work because of the "$10" instead of "$1".
-		// And replace(re, func) isn't supported on IE50 or Safari1.
-		token.arg = token.arg.replace(/e\+(\d)$/, "e+0$1").replace(/e\-(\d)$/, "e-0$1");
+			// C says that exponent must have at least two digits.
+			// But ECMAScript does not; toExponential results in things like "1.000000e-8" and "1.000000e+8".
+			// Note that s.replace(/e([\+\-])(\d)/, "e$10$2") won't work because of the "$10" instead of "$1".
+			// And replace(re, func) isn't supported on IE50 or Safari1.
+			token.arg = token.arg.replace(/e\+(\d)$/, "e+0$1").replace(/e\-(\d)$/, "e-0$1");
 
-		// Ensure a '0' before the period.
-		// Opera implements (0.001).toString() as '0.001', but (0.001).toFixed(1) is '.001'
-		if(dojo.isOpera){
-			token.arg = token.arg.replace(/^\./, '0.');
-		}
+			// Ensure a '0' before the period.
+			// Opera implements (0.001).toString() as '0.001', but (0.001).toFixed(1) is '.001'
+			if(has("opera")){
+				token.arg = token.arg.replace(/^\./, '0.');
+			}
 
-		// if alt, ensure a decimal point
-		if(token.alternative){
-			token.arg = token.arg.replace(/^(\d+)$/,"$1.");
-			token.arg = token.arg.replace(/^(\d+)e/,"$1.e");
-		}
+			// if alt, ensure a decimal point
+			if(token.alternative){
+				token.arg = token.arg.replace(/^(\d+)$/,"$1.");
+				token.arg = token.arg.replace(/^(\d+)e/,"$1.e");
+			}
 
-		if(f >= 0 && token.sign){
-			token.arg = token.sign + token.arg;
-		}
+			if(f >= 0 && token.sign){
+				token.arg = token.sign + token.arg;
+			}
 
-		token.arg = token.toUpper ? token.arg.toUpperCase() : token.arg.toLowerCase();
-	},
-	zeroPad: function(token, /*Int*/ length) {
-		length = (arguments.length == 2) ? length : token.precision;
-		if(typeof token.arg != "string"){
-			token.arg = "" + token.arg;
-		}
+			token.arg = token.toUpper ? token.arg.toUpperCase() : token.arg.toLowerCase();
+		},
+		zeroPad: function(token, /*Int*/ length) {
+			length = (arguments.length == 2) ? length : token.precision;
+			if(typeof token.arg != "string"){
+				token.arg = "" + token.arg;
+			}
 
-		var tenless = length - 10;
-		while(token.arg.length < tenless){
-			token.arg = (token.rightJustify) ? token.arg + this._zeros10 : this._zeros10 + token.arg;
-		}
-		var pad = length - token.arg.length;
-		token.arg = (token.rightJustify) ? token.arg + this._zeros10.substring(0, pad) : this._zeros10.substring(0, pad) + token.arg;
-	},
-	fitField: function(token) {
-		if(token.maxWidth >= 0 && token.arg.length > token.maxWidth){
-			return token.arg.substring(0, token.maxWidth);
-		}
-		if(token.zeroPad){
-			this.zeroPad(token, token.minWidth);
-			return;
-		}
-		this.spacePad(token);
-	},
-	spacePad: function(token, /*Int*/ length) {
-		length = (arguments.length == 2) ? length : token.minWidth;
-		if(typeof token.arg != 'string'){
-			token.arg = '' + token.arg;
-		}
+			var tenless = length - 10;
+			while(token.arg.length < tenless){
+				token.arg = (token.rightJustify) ? token.arg + this._zeros10 : this._zeros10 + token.arg;
+			}
+			var pad = length - token.arg.length;
+			token.arg = (token.rightJustify) ? token.arg + this._zeros10.substring(0, pad) : this._zeros10.substring(0, pad) + token.arg;
+		},
+		fitField: function(token) {
+			if(token.maxWidth >= 0 && token.arg.length > token.maxWidth){
+				return token.arg.substring(0, token.maxWidth);
+			}
+			if(token.zeroPad){
+				this.zeroPad(token, token.minWidth);
+				return;
+			}
+			this.spacePad(token);
+		},
+		spacePad: function(token, /*Int*/ length) {
+			length = (arguments.length == 2) ? length : token.minWidth;
+			if(typeof token.arg != 'string'){
+				token.arg = '' + token.arg;
+			}
 
-		var tenless = length - 10;
-		while(token.arg.length < tenless){
-			token.arg = (token.rightJustify) ? token.arg + this._spaces10 : this._spaces10 + token.arg;
+			var tenless = length - 10;
+			while(token.arg.length < tenless){
+				token.arg = (token.rightJustify) ? token.arg + this._spaces10 : this._spaces10 + token.arg;
+			}
+			var pad = length - token.arg.length;
+			token.arg = (token.rightJustify) ? token.arg + this._spaces10.substring(0, pad) : this._spaces10.substring(0, pad) + token.arg;
 		}
-		var pad = length - token.arg.length;
-		token.arg = (token.rightJustify) ? token.arg + this._spaces10.substring(0, pad) : this._spaces10.substring(0, pad) + token.arg;
-	}
-});
\ No newline at end of file
+	});
+	return strLib.sprintf;
+});
diff --git a/dojox/string/tests/BidiEngine/BidiEngineTest.js b/dojox/string/tests/BidiEngine/BidiEngineTest.js
new file mode 100644
index 0000000..15c86af
--- /dev/null
+++ b/dojox/string/tests/BidiEngine/BidiEngineTest.js
@@ -0,0 +1,1113 @@
+dojo.provide("dojox.string.tests.BidiEngine.BidiEngineTest");
+dojo.require("dojox.string.BidiEngine");
+dojo.addOnLoad(function(){
+			
+	var unilisrc = [
+		// 0
+		"abc def ghij",
+		// 1
+		"abc\u0020\u05d4\u05d5\u05d6\u05d7\u0020\u05d8\u05d9\u05da\u0020\u05da\u05db\u05dc\u05dd\u0020opq rstu",
+		// 2
+		"abc !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ def",
+		// 3
+		"abc !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ \u05d4\u05d5\u05d6",
+		// 4
+		".-= abc def /\\",
+		// 5
+		".-= abc \u05d4\u05d5\u05d6 /\\",
+		// 6
+		"abc 123",
+		// 7
+		"abc 123 401",
+		// 8
+		"abc 123 ghi",
+		// 9
+		"abc 123 401 ghi",
+		// 10
+		"abc 123 \u05d7\u05d8\u05d9",
+		// 11
+		"abc 123 401 \u05d7\u05d8\u05d9",
+		// 12
+		"abc0123",
+		// 13
+		"abc0123 401",
+		// 14
+		"abc0123ghi",
+		// 15
+		"abc0123 401ghi",
+		// 16
+		"abc0123\u05d7\u05d8\u05d9",
+		// 17
+		"abc0123 401\u05d7\u05d8\u05d9",
+		// 18
+		"abc \u05d4\u05d5\u05d6 123",
+		// 19
+		"abc \u05d4\u05d5\u05d6 123 401",
+		// 20
+		"abc \u05d4\u05d5\u05d6 123 ghi",
+		// 21
+		"abc \u05d4\u05d5\u05d6 123 401 ghi",
+		// 22
+		"abc \u05d4\u05d5\u05d6 123 \u05d7\u05d8\u05d9",
+		// 23
+		"abc \u05d4\u05d5\u05d6 123 401 \u05d7\u05d8\u05d9",
+		// 24
+		"abc \u05d4\u05d5\u05d60123",
+		// 25
+		"abc \u05d4\u05d5\u05d60123 401",
+		// 26
+		"abc \u05d4\u05d5\u05d601234ghi",
+		// 27
+		"abc \u05d4\u05d5\u05d60123 401ghi",
+		// 28
+		"abc \u05d4\u05d5\u05d601234\u05d7\u05d8\u05d9",
+		// 29
+		"abc \u05d4\u05d5\u05d60123 401\u05d7\u05d8\u05d9",
+		// 30
+		"123 401 abc def",
+		// 31
+		"abc(\u05d4\u05d5\u05d6)\u05d7\u05d8\u05d9",
+		// 32
+		"abc(\u05d4\u05d5\u05d6)ghi",
+		// 33
+		"abc(def)\u05d7\u05d8\u05d9",
+		// 34
+		"abc(def)ghi",
+		// 35
+		"abc\u05bbde\u05b8fg",
+		// 36
+		"abc\u05bb\u05d4\u05d5\u05b8fg",
+		// 37
+		"abc \u05d4\u05d5\u05d6\u05d7	\u05d8\u05d9\u05da klm",
+		// 38
+		"abc \u05d4\u05d5\u05d6\u05d7	hij klm",
+		// 39
+		"abc defg	\u05d8\u05d9\u05da klm",
+		// 40
+		"abc defg	hij klm",
+		// 41
+		"abc \u05d4\u05d5\u05d6\u05d7    	  \u05d8\u05d9\u05da klm",
+		// 42
+		"abc \u05d4\u05d5\u05d6\u05d7    	  hij klm",
+		// 43
+		"abc defg    	  \u05d8\u05d9\u05da klm",
+		// 44
+		"abc defg    	  hij klm",
+		// 45
+		"abc \u05d4\u05d5\u05d6\u05d7 ._-	=\u005c\u05d8\u05d9\u05da klm",
+		// 46
+		"abc \u05d4\u05d5\u05d6\u05d7 ._-	=\hij klm",
+		// 47
+		"abc defg ._-	=\u005c\u05d8\u05d9\u05da klm",
+		// 48
+		"abc defg ._-	=\hij klm",
+		// 49
+		"abc \u05d4\u05d5\u05d6\u05d7 ._-    	  =\u005c\u05d8\u05d9\u05da klm",
+		// 50
+		"abc \u05d4\u05d5\u05d6\u05d7 ._-    	  =\hij klm",
+		// 51
+		"abc defg ._-    	  =\u005c\u05d8\u05d9\u05da klm",
+		// 52
+		"abc defg ._-    	  =\hij klm",
+		// 53
+		"   abc \u05d4\u05d5\u05d6 ghi",
+		// 54
+		".- abc \u05d4\u05d5\u05d6 ghi",
+		// 55
+		"12 abc \u05d4\u05d5\u05d6 ghi",
+		// 56
+		"/* 012$ % 3401$ < = 12 */"
+		];
+
+	var uniliout = [
+		// 0
+		"abc def ghij",
+		// 1
+		"abc \u05dd\u05dc\u05db\u05da\u0020\u05da\u05d9\u05d8\u0020\u05d7\u05d6\u05d5\u05d4 opq rstu",
+		// 2
+		"abc !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ def",
+		// 3
+		"abc !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ \u05d6\u05d5\u05d4",
+		// 4
+		".-= abc def /\\",
+		// 5
+		".-= abc \u05d6\u05d5\u05d4 /\\",
+		// 6
+		"abc 123",
+		// 7
+		"abc 123 401",
+		// 8
+		"abc 123 ghi",
+		// 9
+		"abc 123 401 ghi",
+		// 10
+		"abc 123 \u05d9\u05d8\u05d7",
+		// 11
+		"abc 123 401 \u05d9\u05d8\u05d7",
+		// 12
+		"abc0123",
+		// 13
+		"abc0123 401",
+		// 14
+		"abc0123ghi",
+		// 15
+		"abc0123 401ghi",
+		// 16
+		"abc0123\u05d9\u05d8\u05d7",
+		// 17
+		"abc0123 401\u05d9\u05d8\u05d7",
+		// 18
+		"abc 123 \u05d6\u05d5\u05d4",
+		// 19
+		"abc 401 123 \u05d6\u05d5\u05d4",
+		// 20
+		"abc 123 \u05d6\u05d5\u05d4 ghi",
+		// 21
+		"abc 401 123 \u05d6\u05d5\u05d4 ghi",
+		// 22
+		"abc \u05d9\u05d8\u05d7 123 \u05d6\u05d5\u05d4",
+		// 23
+		"abc \u05d9\u05d8\u05d7 401 123 \u05d6\u05d5\u05d4",
+		// 24
+		"abc 0123\u05d6\u05d5\u05d4",
+		// 25
+		"abc 401 0123\u05d6\u05d5\u05d4",
+		// 26
+		"abc 01234\u05d6\u05d5\u05d4ghi",
+		// 27
+		"abc 401 0123\u05d6\u05d5\u05d4ghi",
+		// 28
+		"abc \u05d9\u05d8\u05d701234\u05d6\u05d5\u05d4",
+		// 29
+		"abc \u05d9\u05d8\u05d7401 0123\u05d6\u05d5\u05d4",
+		// 30
+		"123 401 abc def",
+		// 31
+		"abc(\u05d9\u05d8\u05d7(\u05d6\u05d5\u05d4",
+		// 32
+		"abc(\u05d6\u05d5\u05d4)ghi",
+		// 33
+		"abc(def)\u05d9\u05d8\u05d7",
+		// 34
+		"abc(def)ghi",
+		// 35
+		"abc\u05bbde\u05b8fg",
+		// 36
+		"abc\u05bb\u05b8\u05d5\u05d4fg",
+		// 37
+		"abc \u05d7\u05d6\u05d5\u05d4	\u05da\u05d9\u05d8 klm",
+		// 38
+		"abc \u05d7\u05d6\u05d5\u05d4	hij klm",
+		// 39
+		"abc defg	\u05da\u05d9\u05d8 klm",
+		// 40
+		"abc defg	hij klm",
+		// 41
+		"abc \u05d7\u05d6\u05d5\u05d4    	\u05da\u05d9\u05d8   klm",
+		// 42
+		"abc \u05d7\u05d6\u05d5\u05d4    	  hij klm",
+		// 43
+		"abc defg    	  \u05da\u05d9\u05d8 klm",
+		// 44
+		"abc defg    	  hij klm",
+		// 45
+		"abc -_. \u05d7\u05d6\u05d5\u05d4	\u05da\u05d9\u05d8\u005c= klm",
+		// 46
+		"abc \u05d7\u05d6\u05d5\u05d4 ._-	=\hij klm",
+		// 47
+		"abc defg ._-	=\u005c\u05da\u05d9\u05d8 klm",
+		// 48
+		"abc defg ._-	=\hij klm",
+		// 49
+		"abc -_. \u05d7\u05d6\u05d5\u05d4    	\u05da\u05d9\u05d8\u005c=   klm",
+		// 50
+		"abc \u05d7\u05d6\u05d5\u05d4 ._-    	  =\hij klm",
+		// 51
+		"abc defg ._-    	  =\u005c\u05da\u05d9\u05d8 klm",
+		// 52
+		"abc defg ._-    	  =\hij klm",
+		// 53
+		"   abc \u05d6\u05d5\u05d4 ghi",
+		// 54
+		".- abc \u05d6\u05d5\u05d4 ghi",
+		// 55
+		"12 abc \u05d6\u05d5\u05d4 ghi",
+		// 56
+		"/* 012$ % 3401$ < = 12 */"
+		];
+	var unirisrc = [
+		// 0
+		"\u05d1\u05d2\u05d3\u0020\u05d4\u05d5\u05d6\u0020\u05d7\u05d8\u05d9\u05da",
+		// 1
+		"\u05d1\u05d2\u05d3 defg hij klmn \u05d6\u05d7\u05d8\u0020\u05d9\u05da\u05db\u05dc",
+		// 2
+		"\u05d1\u05d2\u05d3 #123 $234 %340 +401 -012 \u05d4\u05d5\u05d6",
+		// 3
+		"\u05d1\u05d2\u05d3 123# 234$ 340% 401+ 012- \u05d4\u05d5\u05d6",
+		// 4
+		"\u05d1\u05d2\u05d3 123#234$340%401+012-024 \u05d4\u05d5\u05d6",
+		// 5
+		"\u05d1\u05d2\u05d3 123-",
+		// 6
+		"\u05d9\u05d6 20 + 14 = 34?",
+		// 7
+		"\u05d1\u05d2\u05d3 123.",
+		// 8
+		"\u05d1\u05d2\u05d3 12,340,123.40:13:24/30/41 \u05d4\u05d5\u05d6",
+		// 9
+		"\u05d1\u05d2\u05d3 -12,340.13$ \u05d4\u05d5\u05d6",
+		// 10
+		"\u05d9\u0020\u05d3\u05dc\u05d1\u05d9\u05dd: 4.4-0.4=4.0, ok?",
+		// 11
+		"\u05d1\u05d2\u05d3 ,123 .234 :340 /401 \u05d4\u05d5\u05d6",
+		// 12
+		"\u05d1\u05d2\u05d3 123, 234. 340: 401/ \u05d4\u05d5\u05d6",
+		// 13
+		"\u05d1\u05d2\u05d3 123..40 \u05d4\u05d5\u05d6",
+		// 14
+		"\u05d1\u05d2\u05d3 123.,40 \u05d4\u05d5\u05d6",
+		// 15
+		"\u05d1\u05d2\u05d3 123/.40 \u05d4\u05d5\u05d6",
+		// 16
+		"\u05d1\u05d2\u05d3 ---123$$ \u05d4\u05d5\u05d6",
+		// 17
+		"\u05d1\u05d2\u05d3 +-123#$% \u05d4\u05d5\u05d6",
+		// 18
+		"\u05d1\u05d2\u05d3 123###234$%340%%%401+--012-++130 \u05d4\u05d5\u05d6",
+		// 19
+		"\u05d1\u05d2\u05d3 !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ \u05d4\u05d5\u05d6",
+		// 20
+		"\u05d1\u05d2\u05d3 !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ def",
+		// 21
+		".-= \u05d1\u05d2\u05d3 \u05d4\u05d5\u05d6 /\\",
+		// 22
+		".-= \u05d1\u05d2\u05d3 def /\\",
+		// 23
+		"\u05d1\u05d2\u05d3 123",
+		// 24
+		"\u05d1\u05d2\u05d3 123 401",
+		// 25
+		"\u05d1\u05d2\u05d3 123 \u05d7\u05d8\u05d9",
+		// 26
+		"\u05d1\u05d2\u05d3 123 401 \u05d7\u05d8\u05d9",
+		// 27
+		"\u05d1\u05d2\u05d3 123 ghi",
+		// 28
+		"\u05d1\u05d2\u05d3 123 401 ghi",
+		// 29
+		"\u05d1\u05d2\u05d30123",
+		// 30
+		"\u05d1\u05d2\u05d30123 401",
+		// 31
+		"\u05d1\u05d2\u05d301234\u05d7\u05d8\u05d9",
+		// 32
+		"\u05d1\u05d2\u05d30123 401\u05d7\u05d8\u05d9",
+		// 33
+		"\u05d1\u05d2\u05d301234ghi",
+		// 34
+		"\u05d1\u05d2\u05d30123 401ghi",
+		// 35
+		"\u05d1\u05d2\u05d3 def 123",
+		// 36
+		"\u05d1\u05d2\u05d3 def 123 401",
+		// 37
+		"\u05d1\u05d2\u05d3 def 123 \u05d7\u05d8\u05d9",
+		// 38
+		"\u05d1\u05d2\u05d3 def 123 401 \u05d7\u05d8\u05d9",
+		// 39
+		"\u05d1\u05d2\u05d3 def 123 ghi",
+		// 40
+		"\u05d1\u05d2\u05d3 def 123 401 ghi",
+		// 41
+		"\u05d1\u05d2\u05d3 def123",
+		// 42
+		"\u05d1\u05d2\u05d3 def0123 401",
+		// 43
+		"\u05d1\u05d2\u05d3 def01234\u05d7\u05d8\u05d9",
+		// 44
+		"\u05d1\u05d2\u05d3 def0123 401\u05d7\u05d8\u05d9",
+		// 45
+		"\u05d1\u05d2\u05d3 def01234ghi",
+		// 46
+		"\u05d1\u05d2\u05d3 def0123 401ghi",
+		// 47
+		"123 401 \u05d1\u05d2\u05d3 \u05d4\u05d5\u05d6",
+		// 48
+		"\u05d1\u05d2\u05d3(\u05d4\u05d5\u05d6)\u05d7\u05d8\u05d9",
+		// 49
+		"\u05d1\u05d2\u05d3(\u05d4\u05d5\u05d6)ghi",
+		// 50
+		"\u05d1\u05d2\u05d3(def)\u05d7\u05d8\u05d9",
+		// 51
+		"\u05d1\u05d2\u05d3(def)ghi",
+		// 52
+		"\u05d1\u05d2\u05d3 (\u05d4\u05d5\u05d6) [\u05d7\u05d8\u05d9] {\u05da\u05db\u05dc} <\u05dd\u05d1> \u05d2\u05d3\u05d4",
+		// 53
+		"\u05d1\u05d2\u05d3\u05bb\u05d4\u05d5\u05b8\u05d6\u05d7",
+		// 54
+		"\u05d1\u05d2\u05d3\u05bb\u0064\u05d5\u05b8\u05d6\u05d7",
+		// 55
+		"\u05bb\u05d4\u05d5",
+		// 56
+		"\u05d1\u05d2\u05d3 defg	hij \u05db\u05dc\u05dd",
+		// 57
+		"\u05d1\u05d2\u05d3 defg	\u05d8\u05d9\u05da \u05db\u05dc\u05dd",
+		// 58
+		"\u05d1\u05d2\u05d3 \u05d4\u05d5\u05d6\u05d7	hij \u05db\u05dc\u05dd",
+		// 59
+		"\u05d1\u05d2\u05d3 \u05d4\u05d5\u05d6\u05d7	\u05d8\u05d9\u05da \u05db\u05dc\u05dd",
+		// 60
+		"\u05d1\u05d2\u05d3 defg    	  hij \u05db\u05dc\u05dd",
+		// 61
+		"\u05d1\u05d2\u05d3 defg    	  \u05d8\u05d9\u05da \u05db\u05dc\u05dd",
+		// 62
+		"\u05d1\u05d2\u05d3 \u05d4\u05d5\u05d6\u05d7    	  hij \u05db\u05dc\u05dd",
+		// 63
+		"\u05d1\u05d2\u05d3 \u05d4\u05d5\u05d6\u05d7    	  \u05d8\u05d9\u05da \u05db\u05dc\u05dd",
+		// 64
+		"\u05d1\u05d2\u05d3 defg ._-	=\hij \u05db\u05dc\u05dd",
+		// 65
+		"\u05d1\u05d2\u05d3 defg ._-	=\u005c\u05d8\u05d9\u05da \u05db\u05dc\u05dd",
+		// 66
+		"\u05d1\u05d2\u05d3 \u05d4\u05d5\u05d6\u05d7 ._-	=\hij \u05db\u05dc\u05dd",
+		// 67
+		"\u05d1\u05d2\u05d3 \u05d4\u05d5\u05d6\u05d7 ._-	=\u005c\u05d8\u05d9\u05da \u05db\u05dc\u05dd",
+		// 68
+		"\u05d1\u05d2\u05d3 defg ._-    	  =\hij \u05db\u05dc\u05dd",
+		// 69
+		"\u05d1\u05d2\u05d3 defg ._-    	  =\u005c\u05d8\u05d9\u05da \u05db\u05dc\u05dd",
+		// 70
+		"\u05d1\u05d2\u05d3 \u05d4\u05d5\u05d6\u05d7 ._-    	  =\hij \u05db\u05dc\u05dd",
+		// 71
+		"\u05d1\u05d2\u05d3 \u05d4\u05d5\u05d6\u05d7 ._-    	  =\u005c\u05d8\u05d9\u05da \u05db\u05dc\u05dd",
+		// 72
+		"   \u05d1\u05d2\u05d3 def \u05d7\u05d8\u05d9",
+		// 73
+		".- \u05d1\u05d2\u05d3 def \u05d7\u05d8\u05d9",
+		// 74
+		"12 \u05d1\u05d2\u05d3 def \u05d7\u05d8\u05d9",
+		// 75
+		"1. \u05d1\u05d2\u05d3 def \u05d7\u05d8\u05d9",
+		// 76
+		"1) \u05d1\u05d2\u05d3 def \u05d7\u05d8\u05d9",
+		// 77
+		".3 \u05d1\u05d2\u05d3 def \u05d7\u05d8\u05d9"
+	];
+	var uniriout = [
+		// 0
+		"\u05da\u05d9\u05d8\u05d7\u0020\u05d6\u05d5\u05d4\u0020\u05d3\u05d2\u05d1",
+		// 1
+		"\u05dc\u05db\u05da\u05d9 \u05d8\u05d7\u05d6 defg hij klmn \u05d3\u05d2\u05d1",
+		// 2
+		"\u05d6\u05d5\u05d4 012- 401+ %340 $234 #123 \u05d3\u05d2\u05d1",
+		// 3
+		"\u05d6\u05d5\u05d4 -012 +401 340% 234$ 123# \u05d3\u05d2\u05d1",
+		// 4
+		"\u05d6\u05d5\u05d4 123#234$340%401+012-024 \u05d3\u05d2\u05d1",
+		// 5
+		"-123 \u05d3\u05d2\u05d1",
+		// 6
+		"?34 = 14 + 20 \u05d6\u05d9",
+		// 7
+		".123 \u05d3\u05d2\u05d1",
+		// 8
+		"\u05d6\u05d5\u05d4 12,340,123.40:13:24/30/41 \u05d3\u05d2\u05d1",
+		// 9
+		"\u05d6\u05d5\u05d4 12,340.13$- \u05d3\u05d2\u05d1",
+		// 10
+		"?ok ,4.0=4.4-0.4 :\u05dd\u05d9\u05d1\u05dc\u05d3\u0020\u05d9",
+		// 11
+		"\u05d6\u05d5\u05d4 401/ 340: 234. 123, \u05d3\u05d2\u05d1",
+		// 12
+		"\u05d6\u05d5\u05d4 /401 :340 .234 ,123 \u05d3\u05d2\u05d1",
+		// 13
+		"\u05d6\u05d5\u05d4 40..123 \u05d3\u05d2\u05d1",
+		// 14
+		"\u05d6\u05d5\u05d4 40,.123 \u05d3\u05d2\u05d1",
+		// 15
+		"\u05d6\u05d5\u05d4 40./123 \u05d3\u05d2\u05d1",
+		// 16
+		"\u05d6\u05d5\u05d4 123$$--- \u05d3\u05d2\u05d1",
+		// 17
+		"\u05d6\u05d5\u05d4 123#$%-+ \u05d3\u05d2\u05d1",
+		// 18
+		"\u05d6\u05d5\u05d4 130++-012--+123###234$%340%%%401 \u05d3\u05d2\u05d1",
+		// 19
+		"\u05d6\u05d5\u05d4 ~{|}`_^[\\]@?<=>;:/.-,+*()'&%$#\"! \u05d3\u05d2\u05d1",
+		// 20
+		"def ~{|}`_^[\\]@?<=>;:/.-,+*()'&%$#\"! \u05d3\u05d2\u05d1",
+		// 21
+		"\\/ \u05d6\u05d5\u05d4 \u05d3\u05d2\u05d1 =-.",
+		// 22
+		"\\/ def \u05d3\u05d2\u05d1 =-.",
+		// 23
+		"123 \u05d3\u05d2\u05d1",
+		// 24
+		"401 123 \u05d3\u05d2\u05d1",
+		// 25
+		"\u05d9\u05d8\u05d7 123 \u05d3\u05d2\u05d1",
+		// 26
+		"\u05d9\u05d8\u05d7 401 123 \u05d3\u05d2\u05d1",
+		// 27
+		"ghi 123 \u05d3\u05d2\u05d1",
+		// 28
+		"ghi 401 123 \u05d3\u05d2\u05d1",
+		// 29
+		"0123\u05d3\u05d2\u05d1",
+		// 30
+		"401 0123\u05d3\u05d2\u05d1",
+		// 31
+		"\u05d9\u05d8\u05d701234\u05d3\u05d2\u05d1",
+		// 32
+		"\u05d9\u05d8\u05d7401 0123\u05d3\u05d2\u05d1",
+		// 33
+		"01234ghi\u05d3\u05d2\u05d1",
+		// 34
+		"401ghi 0123\u05d3\u05d2\u05d1",
+		// 35
+		"def 123 \u05d3\u05d2\u05d1",
+		// 36
+		"def 123 401 \u05d3\u05d2\u05d1",
+		// 37
+		"\u05d9\u05d8\u05d7 def 123 \u05d3\u05d2\u05d1",
+		// 38
+		"\u05d9\u05d8\u05d7 def 123 401 \u05d3\u05d2\u05d1",
+		// 39
+		"def 123 ghi \u05d3\u05d2\u05d1",
+		// 40
+		"def 123 401 ghi \u05d3\u05d2\u05d1",
+		// 41
+		"def123 \u05d3\u05d2\u05d1",
+		// 42
+		"def0123 401 \u05d3\u05d2\u05d1",
+		// 43
+		"\u05d9\u05d8\u05d7def01234 \u05d3\u05d2\u05d1",
+		// 44
+		"\u05d9\u05d8\u05d7def0123 401 \u05d3\u05d2\u05d1",
+		// 45
+		"def01234ghi \u05d3\u05d2\u05d1",
+		// 46
+		"def0123 401ghi \u05d3\u05d2\u05d1",
+		// 47
+		"\u05d6\u05d5\u05d4 \u05d3\u05d2\u05d1 401 123",
+		// 48
+		"\u05d9\u05d8\u05d7(\u05d6\u05d5\u05d4)\u05d3\u05d2\u05d1",
+		// 49
+		"ghi(\u05d6\u05d5\u05d4)\u05d3\u05d2\u05d1",
+		// 50
+		"\u05d9\u05d8\u05d7(def)\u05d3\u05d2\u05d1",
+		// 51
+		"def)ghi)\u05d3\u05d2\u05d1",
+		// 52
+		"\u05d4\u05d3\u05d2 <\u05d1\u05dd> {\u05dc\u05db\u05da} [\u05d9\u05d8\u05d7] (\u05d6\u05d5\u05d4) \u05d3\u05d2\u05d1",
+		// 53
+		"\u05d7\u05d6\u05b8\u05d5\u05d4\u05bb\u05d3\u05d2\u05d1",
+		// 54
+		"\u05d7\u05d6\u05b8\u05d5\u0064\u05bb\u05d3\u05d2\u05d1",
+		// 55
+		"\u05d5\u05d4\u05bb",
+		// 56
+		"\u05dd\u05dc\u05db hij	defg \u05d3\u05d2\u05d1",
+		// 57
+		"\u05dd\u05dc\u05db \u05da\u05d9\u05d8	defg \u05d3\u05d2\u05d1",
+		// 58
+		"\u05dd\u05dc\u05db hij	\u05d7\u05d6\u05d5\u05d4 \u05d3\u05d2\u05d1",
+		// 59
+		"\u05dd\u05dc\u05db \u05da\u05d9\u05d8	\u05d7\u05d6\u05d5\u05d4 \u05d3\u05d2\u05d1",
+		// 60
+		"\u05dd\u05dc\u05db   hij	    defg \u05d3\u05d2\u05d1",
+		// 61
+		"\u05dd\u05dc\u05db \u05da\u05d9\u05d8  	    defg \u05d3\u05d2\u05d1",
+		// 62
+		"\u05dd\u05dc\u05db hij  	    \u05d7\u05d6\u05d5\u05d4 \u05d3\u05d2\u05d1",
+		// 63
+		"\u05dd\u05dc\u05db \u05da\u05d9\u05d8  	    \u05d7\u05d6\u05d5\u05d4 \u05d3\u05d2\u05d1",
+		// 64
+		"\u05dd\u05dc\u05db =\hij	defg ._- \u05d3\u05d2\u05d1",
+		// 65
+		"\u05dd\u05dc\u05db \u05da\u05d9\u05d8\u005c=	-_. defg \u05d3\u05d2\u05d1",
+		// 66
+		"\u05dd\u05dc\u05db hij\=	-_. \u05d7\u05d6\u05d5\u05d4 \u05d3\u05d2\u05d1",
+		// 67
+		"\u05dd\u05dc\u05db \u05da\u05d9\u05d8\u005c=	-_. \u05d7\u05d6\u05d5\u05d4 \u05d3\u05d2\u05d1",
+		// 68
+		"\u05dd\u05dc\u05db   =\hij	    defg ._- \u05d3\u05d2\u05d1",
+		// 69
+		"\u05dd\u05dc\u05db \u05da\u05d9\u05d8\u005c=  	    -_. defg \u05d3\u05d2\u05d1",
+		// 70
+		"\u05dd\u05dc\u05db hij\=  	    -_. \u05d7\u05d6\u05d5\u05d4 \u05d3\u05d2\u05d1",
+		// 71
+		"\u05dd\u05dc\u05db \u05da\u05d9\u05d8\u005c=  	    -_. \u05d7\u05d6\u05d5\u05d4 \u05d3\u05d2\u05d1",
+		// 72
+		"\u05d9\u05d8\u05d7 def \u05d3\u05d2\u05d1   ",
+		// 73
+		"\u05d9\u05d8\u05d7 def \u05d3\u05d2\u05d1 -.",
+		// 74
+		"\u05d9\u05d8\u05d7 def \u05d3\u05d2\u05d1 12",
+		// 75
+		"\u05d9\u05d8\u05d7 def \u05d3\u05d2\u05d1 .1",
+		// 76
+		"\u05d9\u05d8\u05d7 def \u05d3\u05d2\u05d1 (1",
+		// 77
+		"\u05d9\u05d8\u05d7 def \u05d3\u05d2\u05d1 3."
+	];
+			
+	var unilicrs = [
+	    // 0
+	    "jihg fed cba",
+		// 1
+		"utsr qpo \u05dd\u05dc\u05db\u05da\u0020\u05da\u05d9\u05d8\u0020\u05d7\u05d6\u05d5\u05d4 cba",
+		// 2
+		"fed ~}|{`_^]\[@?>=<;:/.-,+*)('&%$#\"! cba",
+		// 3
+		"\u05d6\u05d5\u05d4 ~}|{`_^]\[@?>=<;:/.-,+*)('&%$#\"! cba",
+		// 4
+		"\\/ fed cba =-.",
+		// 5
+		"\\/ \u05d6\u05d5\u05d4 cba =-.",
+		// 6
+		"321 cba",
+		// 7
+		"104 321 cba",
+		// 8
+		"ihg 321 cba",
+		// 9
+		"ihg 104 321 cba",
+		// 10
+		"\u05d9\u05d8\u05d7 321 cba",
+		// 11
+		"\u05d9\u05d8\u05d7 104 321 cba",
+		// 12
+		"3210cba",
+		// 13
+		"104 3210cba",
+		// 14
+		"ihg3210cba",
+		// 15
+		"ihg104 3210cba",
+		// 16
+		"\u05d9\u05d8\u05d73210cba",
+		// 17
+		"\u05d9\u05d8\u05d7104 3210cba",
+		// 18
+		"321 \u05d6\u05d5\u05d4 cba",
+		// 19
+		"104 321 \u05d6\u05d5\u05d4 cba",
+		// 20
+		"ihg 321 \u05d6\u05d5\u05d4 cba",
+		// 21
+		"ihg 104 321 \u05d6\u05d5\u05d4 cba",
+		// 22
+		"\u05d9\u05d8\u05d7 321 \u05d6\u05d5\u05d4 cba",
+		// 23
+		"\u05d9\u05d8\u05d7 104 321 \u05d6\u05d5\u05d4 cba",
+		// 24
+		"3210\u05d6\u05d5\u05d4 cba",
+		// 25
+		"104 3210\u05d6\u05d5\u05d4 cba",
+		// 26
+		"ihg43210\u05d6\u05d5\u05d4 cba",
+		// 27
+		"ihg104 3210\u05d6\u05d5\u05d4 cba",
+		// 28
+		"\u05d9\u05d8\u05d743210\u05d6\u05d5\u05d4 cba",
+		// 29
+		"\u05d9\u05d8\u05d7104 3210\u05d6\u05d5\u05d4 cba",
+		// 30
+		"fed cba 104 321",
+		// 31
+		"\u05d9\u05d8\u05d7)\u05d6\u05d5\u05d4(cba",
+		// 32
+		"ihg)\u05d6\u05d5\u05d4(cba",
+		// 33
+		"\u05d9\u05d8\u05d7)fed(cba",
+		// 34
+		"ihg)fed(cba",
+		// 35
+		"gf\u05b8ed\u05bbcba",
+		// 36
+		"gf\u05b8\u05d5\u05d4\u05bbcba",
+		// 37
+		"mlk \u05da\u05d9\u05d8	\u05d7\u05d6\u05d5\u05d4 cba",
+		// 38
+		"mlk jih	\u05d7\u05d6\u05d5\u05d4 cba",
+		// 39
+		"mlk \u05da\u05d9\u05d8	gfed cba",
+		// 40
+		"mlk jih	gfed cba",
+		// 41
+		"mlk \u05da\u05d9\u05d8  	    \u05d7\u05d6\u05d5\u05d4 cba",
+		// 42
+		"mlk jih  	    \u05d7\u05d6\u05d5\u05d4 cba",
+		// 43
+		"mlk \u05da\u05d9\u05d8  	    gfed cba",
+		// 44
+		"mlk jih  	    gfed cba",
+		// 45
+		"mlk \u05da\u05d9\u05d8\u005c=	-_. \u05d7\u05d6\u05d5\u05d4 cba",
+		// 46
+		"mlk jih\=	-_. \u05d7\u05d6\u05d5\u05d4 cba",
+		// 47
+		"mlk \u05da\u05d9\u05d8\u005c=	-_. gfed cba",
+		// 48
+		"mlk jih\=	-_. gfed cba",
+		// 49
+		"mlk \u05da\u05d9\u05d8\u005c=  	    -_. \u05d7\u05d6\u05d5\u05d4 cba",
+		// 50
+		"mlk jih\=  	    -_. \u05d7\u05d6\u05d5\u05d4 cba",
+		// 51
+		"mlk \u05da\u05d9\u05d8\u005c=  	    -_. gfed cba",
+		// 52
+		"mlk jih\=  	    -_. gfed cba",
+		// 53
+		"ihg \u05d6\u05d5\u05d4 cba   ",
+		// 54
+		"ihg \u05d6\u05d5\u05d4 cba -.",
+		// 55
+		"ihg \u05d6\u05d5\u05d4 cba 21",
+		// 56
+		"/* 21 = < $1043 % $210 */"
+	];
+	var allcases = [
+	    // 0
+		"*** .-=",
+	    // 1
+		"=-. ***",
+	    // 2
+		"=-. ABC \u05d0\u05d1\u05d2",
+	    // 3
+		"ABC DEF \u05d0\u05d1\u05d2",
+	    // 4
+		"ABC \u05d0\u05d1\u05d2 DEF",
+	    // 5
+		"\u05d0(\u05d1)\u05d2 ABC \u05d3\u05d4\u05d5",
+	    // 6
+		"\u05d0\u05d1\u05d2 A(B)C \u05d3\u05d4\u05d5",
+	    // 7
+		"\u05d0\u05d1\u05d2 ABC DEF",
+	    // 8
+		"\u05d0\u05d1\u05d2 ABC \u05d3\u05d4\u05d5",
+	    // 9
+		"\u05d1\u05d2\u05d3 #123 $234 %340 +401 -012 \u05d4\u05d5\u05d6",
+	    // 10
+		"\u05d0\u05d1\u05d2 ABC .-=",
+	    // 11
+		"\u05d0\u05d1\u05d2 ABC \u05d3(\u05d4)\u05d5",
+	    // 12
+		"ABC 123 \u05d0\u05d1\u05d2\u05d3",
+	    // 13
+		"\u05d0\u05d1\u05d2\u05d3 123 DEF"
+	];
+		
+	var allinvrs  = [
+   	    // 0
+		"=-. ***",
+	    // 1
+		"*** .-=",
+	    // 2
+		"\u05d2\u05d1\u05d0 CBA .-=",
+	    // 3
+		"\u05d2\u05d1\u05d0 FED CBA",
+	    // 4
+		"FED \u05d2\u05d1\u05d0 CBA",
+	    // 5
+		"\u05d5\u05d4\u05d3 CBA \u05d2)\u05d1(\u05d0",
+	    // 6
+		"\u05d5\u05d4\u05d3 C)B(A \u05d2\u05d1\u05d0",
+	    // 7
+		"FED CBA \u05d2\u05d1\u05d0",
+	    // 8
+		"\u05d5\u05d4\u05d3 CBA \u05d2\u05d1\u05d0",
+	    // 9
+		"\u05d6\u05d5\u05d4 210- 104+ 043% 432$ 321# \u05d3\u05d2\u05d1",
+	    // 10
+		"=-. CBA \u05d2\u05d1\u05d0",
+	    // 11
+		"\u05d5)\u05d4(\u05d3 CBA \u05d2\u05d1\u05d0",
+	    // 12
+		"\u05d3\u05d2\u05d1\u05d0 321 CBA",
+	    // 13
+		"FED 321 \u05d3\u05d2\u05d1\u05d0"
+	];	
+	var il2vlmdl = [
+   	    // 0
+		"*** .-=",
+	    // 1
+		"=-. ***",
+	    // 2
+		"=-. ABC \u05d2\u05d1\u05d0",
+	    // 3
+		"ABC DEF \u05d2\u05d1\u05d0",
+	    // 4
+		"ABC \u05d2\u05d1\u05d0 DEF",
+	    // 5
+		"\u05d2(\u05d1)\u05d0 ABC \u05d5\u05d4\u05d3",
+	    // 6
+		"\u05d2\u05d1\u05d0 A(B)C \u05d5\u05d4\u05d3",
+	    // 7
+		"\u05d2\u05d1\u05d0 ABC DEF",
+	    // 8
+		"\u05d2\u05d1\u05d0 ABC \u05d5\u05d4\u05d3",
+	    // 9
+		"\u05d6\u05d5\u05d4 012- 401+ %340 $234 #123 \u05d3\u05d2\u05d1",
+	    // 10
+		"\u05d2\u05d1\u05d0 ABC .-=",
+	    // 11
+		"\u05d2\u05d1\u05d0 ABC \u05d5(\u05d4)\u05d3",
+	    // 12
+		"ABC 123 \u05d3\u05d2\u05d1\u05d0",
+	    // 13
+		"123 \u05d3\u05d2\u05d1\u05d0 DEF"
+	];
+	var ir2vlmdl = [
+   	    // 0
+		"=-. ***",
+	    // 1
+		"*** .-=",
+	    // 2
+		"\u05d2\u05d1\u05d0 ABC .-=",
+	    // 3
+		"\u05d2\u05d1\u05d0 ABC DEF",
+	    // 4
+		"DEF \u05d2\u05d1\u05d0 ABC",
+	    // 5
+		"\u05d5\u05d4\u05d3 ABC \u05d2(\u05d1)\u05d0",
+	    // 6
+		"\u05d5\u05d4\u05d3 A(B)C \u05d2\u05d1\u05d0",
+	    // 7
+		"ABC DEF \u05d2\u05d1\u05d0",
+	    // 8
+		"\u05d5\u05d4\u05d3 ABC \u05d2\u05d1\u05d0",
+	    // 9
+		"\u05d6\u05d5\u05d4 012- 401+ %340 $234 #123 \u05d3\u05d2\u05d1",
+	    // 10
+		"=-. ABC \u05d2\u05d1\u05d0",
+	    // 11
+		"\u05d5(\u05d4)\u05d3 ABC \u05d2\u05d1\u05d0",
+	    // 12
+		"\u05d3\u05d2\u05d1\u05d0 ABC 123",
+	    // 13
+		"DEF 123 \u05d3\u05d2\u05d1\u05d0"
+	];
+	var il2vrmdl = [
+   	    // 0
+		"=-. ***",
+	    // 1
+		"*** .-=",
+	    // 2
+		"\u05d0\u05d1\u05d2 CBA .-=",
+	    // 3
+		"\u05d0\u05d1\u05d2 FED CBA",
+	    // 4
+		"FED \u05d0\u05d1\u05d2 CBA",
+	    // 5
+		"\u05d3\u05d4\u05d5 CBA \u05d0)\u05d1(\u05d2",
+	    // 6
+		"\u05d3\u05d4\u05d5 C)B(A \u05d0\u05d1\u05d2",
+	    // 7
+		"FED CBA \u05d0\u05d1\u05d2",
+	    // 8
+		"\u05d3\u05d4\u05d5 CBA \u05d0\u05d1\u05d2",
+	    // 9
+		"\u05d1\u05d2\u05d3 321# 432$ 043% +104 -210 \u05d4\u05d5\u05d6",
+	    // 10
+		"=-. CBA \u05d0\u05d1\u05d2",
+	    // 11
+		"\u05d3)\u05d4(\u05d5 CBA \u05d0\u05d1\u05d2",
+	    // 12
+		"\u05d0\u05d1\u05d2\u05d3 321 CBA",
+	    // 13
+		"FED \u05d0\u05d1\u05d2\u05d3 321"
+	];
+	var ir2vrmdl = [
+   	    // 0
+		"*** .-=",
+	    // 1
+		"=-. ***",
+	    // 2
+		"=-. CBA \u05d0\u05d1\u05d2",
+	    // 3
+		"FED CBA \u05d0\u05d1\u05d2",
+	    // 4
+		"CBA \u05d0\u05d1\u05d2 FED",
+	    // 5
+		"\u05d0)\u05d1(\u05d2 CBA \u05d3\u05d4\u05d5",
+	    // 6
+		"\u05d0\u05d1\u05d2 C)B(A \u05d3\u05d4\u05d5",
+	    // 7
+		"\u05d0\u05d1\u05d2 FED CBA",
+	    // 8
+		"\u05d0\u05d1\u05d2 CBA \u05d3\u05d4\u05d5",
+	    // 9
+		"\u05d1\u05d2\u05d3 321# 432$ 043% +104 -210 \u05d4\u05d5\u05d6",
+	    // 10
+		"\u05d0\u05d1\u05d2 CBA .-=",
+	    // 11
+		"\u05d0\u05d1\u05d2 CBA \u05d3)\u05d4(\u05d5",
+	    // 12
+		"321 CBA \u05d0\u05d1\u05d2\u05d3",
+	    // 13
+		"\u05d0\u05d1\u05d2\u05d3 321 FED"
+	];	
+	var vr2ilmdl = [
+   	    // 0
+		"=-. ***",
+	    // 1
+		"*** .-=",
+	    // 2
+		"\u05d0\u05d1\u05d2 CBA .-=",
+	    // 3
+		"\u05d0\u05d1\u05d2 FED CBA",
+	    // 4
+		"FED \u05d0\u05d1\u05d2 CBA",
+	    // 5
+		"\u05d3\u05d4\u05d5 CBA \u05d0)\u05d1(\u05d2",
+	    // 6
+		"\u05d3\u05d4\u05d5 C)B(A \u05d0\u05d1\u05d2",
+	    // 7
+		"FED CBA \u05d0\u05d1\u05d2",
+	    // 8
+		"\u05d3\u05d4\u05d5 CBA \u05d0\u05d1\u05d2",
+	    // 9
+		"\u05d1\u05d2\u05d3 321# 432$ 043% +104 -210 \u05d4\u05d5\u05d6",
+	    // 10
+		"=-. CBA \u05d0\u05d1\u05d2",
+	    // 11
+		"\u05d3)\u05d4(\u05d5 CBA \u05d0\u05d1\u05d2",
+	    // 12
+		"321 \u05d0\u05d1\u05d2\u05d3 CBA",
+	    // 13
+		"FED 321 \u05d0\u05d1\u05d2\u05d3"
+	];
+	var vl2irmdl = [
+   	    // 0
+		"=-. ***",
+	    // 1
+		"*** .-=",
+	    // 2
+		"\u05d2\u05d1\u05d0 ABC .-=",
+	    // 3
+		"\u05d2\u05d1\u05d0 ABC DEF",
+	    // 4
+		"DEF \u05d2\u05d1\u05d0 ABC",
+	    // 5
+		"\u05d5\u05d4\u05d3 ABC \u05d2(\u05d1)\u05d0",
+	    // 6
+		"\u05d5\u05d4\u05d3 A(B)C \u05d2\u05d1\u05d0",
+	    // 7
+		"ABC DEF \u05d2\u05d1\u05d0",
+	    // 8
+		"\u05d5\u05d4\u05d3 ABC \u05d2\u05d1\u05d0",
+	    // 9
+		"\u05d6\u05d5\u05d4 012- 401+ %340 $234 #123 \u05d3\u05d2\u05d1",
+	    // 10
+		"=-. ABC \u05d2\u05d1\u05d0",
+	    // 11
+		"\u05d5(\u05d4)\u05d3 ABC \u05d2\u05d1\u05d0",
+	    // 12
+		"\u05d3\u05d2\u05d1\u05d0 123 ABC",
+	    // 13
+		"123 DEF \u05d3\u05d2\u05d1\u05d0"
+	];	
+	
+	var bdEngine;
+	doh.register('dojox.string.tests.BidiEngine.BidiEngine', [
+		{	
+		
+			// testmati - case 37
+			name:'1. typeoftext=implicit:visual, orientation=ltr, swapping=yes:no',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){	
+					doh.is(uniliout[i], bdEngine.bidiTransform(el, 'ILYNN', 'VLNNN'),"bidiTransform: string num: " + i + " in: unilisrc out: uniliout");
+				},this);
+			}
+		},
+		{
+			// testmati - case 38
+			name:'2. typeoftext=implicit:visual, orientation=rtl:ltr, swapping=yes:no',
+
+			runTest:function() {
+				dojo.forEach(unirisrc, function(el, i){	
+					doh.is(uniriout[i], bdEngine.bidiTransform(el, 'IRYNN', 'VLNNN'),"bidiTransform: string num: " + i + " in: unirisrc out: uniriout");
+				},this);
+			}
+		},
+		{
+			// testmati - case 41
+			name:'3. typeoftext=imsplicit:imsplicit, orientation=ltr:contextual, context=ltr, swapping=yes',
+
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){	
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'ILYNN', 'ILYNN'),"bidiTransform: string num: " + i + " in: unilisrc out: unilisrc");
+				},this);
+			}
+		},
+		{
+			// testmati - case 42
+			name:'4. typeoftext=visual:visual, orientation=ltr:ltr, swapping=no:no',
+
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){	
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VLYNN', 'VLYNN'),"bidiTransform: string num: " + i + " in: unilisrc out: unilisrc");
+				},this);
+			}
+		},
+		{
+			// testmati - case 43
+			name:'5. typeoftext=visual:visual, orientation=ltr:rtl, swapping=no:no',
+
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){	
+					doh.is(unilicrs[i], bdEngine.bidiTransform(el, 'VLYNN', 'VRYNN'),"bidiTransform: string num: " + i + " in: unilisrc out: unilicrs");
+				},this);
+			}
+		},
+		{
+			// testmati - case 44
+			name:'6. typeoftext=visual:visual, orientation=rtl:ltr, swapping=no:no',
+
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){	
+					doh.is(unilicrs[i], bdEngine.bidiTransform(el, 'VRNNN', 'VLYNN'),"bidiTransform: string num: " + i + " in: unilisrc out: unilicrs");
+				},this);
+			}
+		},
+		{
+			// testmati - case 1
+			name:'7. typeoftext=visual:visual, orientation=ltr:ltr, swapping=no:no',
+
+			runTest:function() {
+				dojo.forEach(allcases, function(el, i){	
+					doh.is(allcases[i], bdEngine.bidiTransform(el, 'VLNNN', 'VLNNN'),"bidiTransform: string num: " + i + " in: allcases out: allcases");
+				},this);
+			}
+		},
+		{
+			// testmati - case 2
+			name:'8. typeoftext=visual:visual, orientation=rtl:ltr, swapping=no:no',
+
+			runTest:function() {
+				dojo.forEach(allcases, function(el, i){	
+					doh.is(allinvrs[i], bdEngine.bidiTransform(el, 'VRNNN', 'VLNNN'),"bidiTransform: string num: " + i + " in: allcases out: allinvrs");
+				},this);
+			}
+		},
+		{
+			// testmati - case 3
+			name:'9. typeoftext=visual:visual, orientation=ltr:rtl, swapping=no:no',
+
+			runTest:function() {
+				dojo.forEach(allcases, function(el, i){	
+					doh.is(allinvrs[i], bdEngine.bidiTransform(el, 'VLNNN', 'VRNNN'),"bidiTransform: string num: " + i + " in: allcases out: allinvrs");
+				},this);
+			}
+		},
+		{
+			// testmati - case 4
+			name:'10. typeoftext=visual:visual, orientation=rtl:rtl, swapping=no:no',
+
+			runTest:function() {
+				dojo.forEach(allcases, function(el, i){	
+					doh.is(allcases[i], bdEngine.bidiTransform(el, 'VRNNN', 'VRNNN'), "bidiTransform: string num: " + i + " in: allcases out: allcases");
+				},this);
+			}
+		},
+		{
+			// testmati - case 5
+			name:'11. typeoftext=implicit:visual, orientation=ltr:ltr, swapping=yes:no',
+
+			runTest:function() {
+				dojo.forEach(allcases, function(el, i){	
+					doh.is(il2vlmdl[i], bdEngine.bidiTransform(el, 'ILYNN', 'VLNNN'), "bidiTransform: string num: " + i + " in: allcases out: il2vlmdl");
+				},this);
+			}
+		},
+		{
+			// testmati - case 6
+			name:'12. typeoftext=implicit:visual, orientation=rtl:ltr, swapping=yes:no',
+
+			runTest:function() {
+				dojo.forEach(allcases, function(el, i){	
+					doh.is(ir2vlmdl[i], bdEngine.bidiTransform(el, 'IRYNN', 'VLNNN'), "bidiTransform: string num: " + i + " in: allcases out: ir2vlmdl");
+				},this);
+			}
+		},
+		{
+			// testmati - case 7
+			name:'13. typeoftext=implicit:visual, orientation=ltr:rtl, swapping=yes:no',
+
+			runTest:function() {
+				dojo.forEach(allcases, function(el, i){	
+					doh.is(il2vrmdl[i], bdEngine.bidiTransform(el, 'ILYNN', 'VRNNN'), "bidiTransform: string num: " + i + " in: allcases out: il2vrmdl");
+				},this);
+			}
+		},
+		{
+			// testmati - case 8
+			name:'14. typeoftext=implicit:visual, orientation=rtl:rtl, swapping=yes:no',
+
+			runTest:function() {
+				dojo.forEach(allcases, function(el, i){	
+					doh.is(ir2vrmdl[i], bdEngine.bidiTransform(el, 'IRYNN', 'VRNNN'), "bidiTransform: string num: " + i + " in: allcases out: ir2vrmdl");
+				},this);
+			}
+		},
+		{
+			// testmati - case 9
+			name:'15. typeoftext=visual:implicit, orientation=ltr:ltr, swapping=no:yes',
+
+			runTest:function() {
+				dojo.forEach(allcases, function(el, i){	
+					doh.is(il2vlmdl[i], bdEngine.bidiTransform(el, 'VLNNN', 'ILYNN'), "bidiTransform: string num: " + i + " in: allcases out: il2vlmdl");
+				},this);
+			}
+		},
+		{
+			// testmati - case 10
+			name:'16. typeoftext=visual:implicit, orientation=rtl:ltr, swapping=no:yes',
+
+			runTest:function() {
+				dojo.forEach(allcases, function(el, i){	
+					doh.is(vr2ilmdl[i], bdEngine.bidiTransform(el, 'VRNNN', 'ILYNN'), "bidiTransform: string num: " + i + " in: allcases out: vr2ilmdl");
+				},this);
+			}
+		},
+		{
+			// testmati - case 11
+			name:'17. typeoftext=visual:implicit, orientation=ltr:rtl, swapping=no:yes',
+
+			runTest:function() {
+				dojo.forEach(allcases, function(el, i){	
+					doh.is(vl2irmdl[i], bdEngine.bidiTransform(el, 'VLNNN', 'IRYNN'), "bidiTransform: string num: " + i + " in: allcases out: vl2irmdl");
+				},this);
+			}
+		},
+		{
+			// testmati - case 12
+			name:'18. typeoftext=visual:implicit, orientation=rtl:rtl, swapping=no:yes',
+
+			runTest:function() {
+				dojo.forEach(allcases, function(el, i){	
+					doh.is(ir2vrmdl[i], bdEngine.bidiTransform(el, 'VRNNN', 'IRYNN'), "bidiTransform: string num: " + i + " in: allcases out: ir2vrmdl");
+				},this);
+			}
+		},
+		{
+			// testmati - case 13
+			name:'19. typeoftext=implicit:implicit, orientation=ltr:ltr, swapping=no:no',
+
+			runTest:function() {
+				dojo.forEach(allcases, function(el, i){	
+					doh.is(allcases[i], bdEngine.bidiTransform(el, 'ILNNN', 'ILNNN'), "bidiTransform: string num: " + i + " in: allcases out: allcases");
+				},this);
+			}
+		}
+	]);
+	
+
+});
\ No newline at end of file
diff --git a/dojox/string/tests/BidiEngine/BidiEngineTestLayouts.js b/dojox/string/tests/BidiEngine/BidiEngineTestLayouts.js
new file mode 100644
index 0000000..ea0ee40
--- /dev/null
+++ b/dojox/string/tests/BidiEngine/BidiEngineTestLayouts.js
@@ -0,0 +1,351 @@
+dojo.provide("dojox.string.tests.BidiEngine.BidiEngineTestLayouts");
+dojo.require("dojox.string.BidiEngine");
+dojo.addOnLoad(function(){
+			
+	var unilisrc = [
+		"11"
+	];
+
+	var bdEngine;
+	var errorMessage = "dojox.string.BidiEngine: the bidi layout string is wrong!";
+	doh.register('dojox.string.tests.BidiEngine.BidiEngine', [
+		{	
+			name:'1. test empty',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){	
+					doh.is('', bdEngine.bidiTransform('', 'VLNNN', 'IRYNN'),"empty string.");
+				},this);
+			}
+		},
+		{	
+			name:'2. empty format string.',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){	
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, '', ''),"bidi layouts empty");
+				},this);
+			}
+		},
+		{	
+			name:'3. show error.',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){
+					try{
+						doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'ILYNN', ''),"bidi layouts empty");
+						throw new Error("Didn't threw error!!");
+					}catch(e){
+					 doh.is(errorMessage, e.message,"should throw wrong format message!");
+					}
+				},this);
+			}
+		},
+		{	
+			name:'4. show error.',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){
+					try{
+						doh.is(unilisrc[i], bdEngine.bidiTransform(el, '', 'ILYNN'),"bidi layouts empty");
+						throw new Error("Didn't threw error!!");
+					}catch(e){
+					 doh.is(errorMessage, e.message,"should throw wrong format message!");
+					}
+				},this);
+			}
+		},
+		{	
+			name:'5. show error.',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){
+					try{
+						doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'V', 'I'),"bidi layouts empty");
+						throw new Error("Didn't threw error!!");
+					}catch(e){
+					 doh.is(errorMessage, e.message,"should throw wrong format message!");
+					}
+				},this);
+			}
+		},
+		{	
+			name:'6. Test first letter.',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){
+					try{
+						doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'KLYNN', 'ILNNN'),"bidi layouts empty");
+						throw new Error("Didn't threw error!!");
+					}catch(e){
+					 doh.is(errorMessage, e.message,"should throw wrong format message!");
+					}
+				},this);
+			}
+		},
+		{	
+			name:'7. Test first letter.',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){
+					try{
+						doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VLYNN', 'KLNNN'),"bidi layouts empty");
+						throw new Error("Didn't threw error!!");
+					}catch(e){
+					 doh.is(errorMessage, e.message,"should throw wrong format message!");
+					}
+				},this);
+			}
+		},
+		{	
+			name:'8. Test second letter.',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){
+					try{
+						doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VKYNN', 'ILNNN'),"bidi layouts empty");
+						throw new Error("Didn't threw error!!");
+					}catch(e){
+					 doh.is(errorMessage, e.message,"should throw wrong format message!");
+					}
+				},this);
+			}
+		},
+		{	
+			name:'9. Test second letter.',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){
+					try{
+						doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VRYNN', 'IKNNN'),"bidi layouts empty");
+						throw new Error("Didn't threw error!!");
+					}catch(e){
+					 doh.is(errorMessage, e.message,"should throw wrong format message!");
+					}
+				},this);
+			}
+		},
+		{	
+			name:'10. Test third letter.',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){
+					try{
+						doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VRSNN', 'IRNNN'),"bidi layouts empty");
+						throw new Error("Didn't threw error!!");
+					}catch(e){
+					 doh.is(errorMessage, e.message,"should throw wrong format message!");
+					}
+				},this);
+			}
+		},
+		{	
+			name:'11. Test third letter.',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){
+					try{
+						doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VRYNN', 'IRLNN'),"bidi layouts empty");
+						throw new Error("Didn't threw error!!");
+					}catch(e){
+					 doh.is(errorMessage, e.message,"should throw wrong format message!");
+					}
+				},this);
+			}
+		},
+		{	
+			name:'12. Test fourth letter.',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){
+					try{
+						doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VRSNN', 'IRNNN'),"bidi layouts empty");
+						throw new Error("Didn't threw error!!");
+					}catch(e){
+					 doh.is(errorMessage, e.message,"should throw wrong format message!");
+					}
+				},this);
+			}
+		},
+		{	
+			name:'13. Test fourth letter.',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){
+					try{
+						doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VRYNN', 'IRSNN'),"bidi layouts empty");
+						throw new Error("Didn't threw error!!");
+					}catch(e){
+					 doh.is(errorMessage, e.message,"should throw wrong format message!");
+					}
+				},this);
+			}
+		},
+		{	
+			name:'14. Test fifth letter.',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){
+					try{
+						doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VRYNA', 'IRCNN'),"bidi layouts empty");
+						throw new Error("Didn't threw error!!");
+					}catch(e){
+					 doh.is(errorMessage, e.message,"should throw wrong format message!");
+					}
+				},this);
+			}
+		},
+		{	
+			name:'15. Test fifth letter.',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){
+					try{
+						doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VRYNN', 'ICNNA'),"bidi layouts empty");
+						throw new Error("Didn't threw error!!");
+					}catch(e){
+					 doh.is(errorMessage, e.message,"should throw wrong format message!");
+					}
+				},this);
+			}
+		},
+		{	
+			name:'16. Too much letters.',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){
+					try{
+						doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VRYNNN', 'IDYNN'),"bidi layouts empty");
+						throw new Error("Didn't threw error!!");
+					}catch(e){
+					 doh.is(errorMessage, e.message,"should throw wrong format message!");
+					}
+				},this);
+			}
+		},
+		{	
+			name:'16. Too much letters.',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){
+					try{
+						doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VRYNN', 'ICYNNN'),"bidi layouts empty");
+						throw new Error("Didn't threw error!!");
+					}catch(e){
+					 doh.is(errorMessage, e.message,"should throw wrong format message!");
+					}
+				},this);
+			}
+		},
+		{	
+			name:'17. Good formats.',
+
+			setUp: function(){
+				bdEngine = new dojox.string.BidiEngine();
+			},
+			
+			runTest:function() {
+				dojo.forEach(unilisrc, function(el, i){
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'ILNNN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VLNNN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'IRNNN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VRNNN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'ICNNN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'IDNNN', 'ILNNN'),"bidi layouts empty");
+
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'ILYNN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VLYNN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'IRYNN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VRYNN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'ICYNN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'IDYNN', 'ILNNN'),"bidi layouts empty");
+					
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'ILYSN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VLYSN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'IRYSN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VRYSN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'ICYSN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'IDYSN', 'ILNNN'),"bidi layouts empty");
+					
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'ILNSN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VLNSN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'IRNSN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'VRNSN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'ICNSN', 'ILNNN'),"bidi layouts empty");
+					doh.is(unilisrc[i], bdEngine.bidiTransform(el, 'IDNSN', 'ILNNN'),"bidi layouts empty");
+					
+				},this);
+			}
+		}
+	]);
+	
+
+});
diff --git a/dojox/string/tests/BidiEngine/module.js b/dojox/string/tests/BidiEngine/module.js
new file mode 100644
index 0000000..ddfd08e
--- /dev/null
+++ b/dojox/string/tests/BidiEngine/module.js
@@ -0,0 +1,10 @@
+dojo.provide("dojox.string.tests.BidiEngine.module");
+
+try{
+   	dojo.require("dojox.string.tests.BidiEngine.BidiEngineTest");
+   	
+   	dojo.require("dojox.string.tests.BidiEngine.BidiEngineTestLayouts");
+
+}catch(e){
+     doh.debug(e);
+}
\ No newline at end of file
diff --git a/dojox/string/tests/BidiEngine/runTests.html b/dojox/string/tests/BidiEngine/runTests.html
new file mode 100644
index 0000000..38b24d9
--- /dev/null
+++ b/dojox/string/tests/BidiEngine/runTests.html
@@ -0,0 +1,11 @@
+!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+  <head>
+    <title>textDirTests Unit Test Runner</title>
+    <meta http-equiv="REFRESH"         
+content="0;url=../../../../util/doh/runner.html?testModule=dojox.string.tests.BidiEngine.module">
+  </head>
+  <body>
+      Redirecting to D.O.H runner.
+  </body>
+</html>
\ No newline at end of file
diff --git a/dojox/string/tokenize.js b/dojox/string/tokenize.js
index 7dc7c12..5aa20b1 100644
--- a/dojox/string/tokenize.js
+++ b/dojox/string/tokenize.js
@@ -1,38 +1,44 @@
-dojo.provide("dojox.string.tokenize");
+define([
+	"dojo/_base/lang",
+	"dojo/_base/sniff"	
+], function(lang, has){
+	var tokenize = lang.getObject("dojox.string", true).tokenize;
 
-dojox.string.tokenize = function(/*String*/ str, /*RegExp*/ re, /*Function?*/ parseDelim, /*Object?*/ instance){
-	// summary:
-	//		Split a string by a regular expression with the ability to capture the delimeters
-	// parseDelim:
-	//		Each group (excluding the 0 group) is passed as a parameter. If the function returns
-	//		a value, it's added to the list of tokens.
-	// instance:
-	//		Used as the "this" instance when calling parseDelim
-	var tokens = [];
-	var match, content, lastIndex = 0;
-	while(match = re.exec(str)){
-		content = str.slice(lastIndex, re.lastIndex - match[0].length);
-		if(content.length){
-			tokens.push(content);
-		}
-		if(parseDelim){
-			if(dojo.isOpera){
-				var copy = match.slice(0);
-				while(copy.length < match.length){
-					copy.push(null);
-				}
-				match = copy;
+	tokenize = function(/*String*/ str, /*RegExp*/ re, /*Function?*/ parseDelim, /*Object?*/ instance){
+		// summary:
+		//		Split a string by a regular expression with the ability to capture the delimeters
+		// parseDelim:
+		//		Each group (excluding the 0 group) is passed as a parameter. If the function returns
+		//		a value, it's added to the list of tokens.
+		// instance:
+		//		Used as the "this" instance when calling parseDelim
+		var tokens = [];
+		var match, content, lastIndex = 0;
+		while(match = re.exec(str)){
+			content = str.slice(lastIndex, re.lastIndex - match[0].length);
+			if(content.length){
+				tokens.push(content);
 			}
-			var parsed = parseDelim.apply(instance, match.slice(1).concat(tokens.length));
-			if(typeof parsed != "undefined"){
-				tokens.push(parsed);
+			if(parseDelim){
+				if(has("opera")){
+					var copy = match.slice(0);
+					while(copy.length < match.length){
+						copy.push(null);
+					}
+					match = copy;
+				}
+				var parsed = parseDelim.apply(instance, match.slice(1).concat(tokens.length));
+				if(typeof parsed != "undefined"){
+					tokens.push(parsed);
+				}
 			}
+			lastIndex = re.lastIndex;
+		}
+		content = str.slice(lastIndex);
+		if(content.length){
+			tokens.push(content);
 		}
-		lastIndex = re.lastIndex;
-	}
-	content = str.slice(lastIndex);
-	if(content.length){
-		tokens.push(content);
-	}
-	return tokens;
-}
\ No newline at end of file
+		return tokens;
+	};
+	return tokenize;
+});
diff --git a/dojox/timing.js b/dojox/timing.js
index 9cc843f..b595ef3 100644
--- a/dojox/timing.js
+++ b/dojox/timing.js
@@ -1,2 +1,3 @@
-dojo.provide("dojox.timing");
-dojo.require("dojox.timing._base");
+define(["./timing/_base"], function(timing){
+	return timing;
+});
diff --git a/dojox/timing/Sequence.js b/dojox/timing/Sequence.js
index 9de4d41..abc0116 100644
--- a/dojox/timing/Sequence.js
+++ b/dojox/timing/Sequence.js
@@ -1,147 +1,154 @@
-dojo.provide("dojox.timing.Sequence");
-dojo.experimental("dojox.timing.Sequence");
-
-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
-	//	some parameters for each (like: pauseBefore) and they will
-	//	be run one after another. This can be very useful for slideshows
-	//	or alike things.
-	//
-	// description:
-	//	This array will contain the sequence defines resolved, so that
-	// 	ie. repeat:10 will result in 10 elements in the sequence, so
-	// 	the repeat handling is easier and we don't need to handle that
-	// 	many extra cases. Also the doneFunction, if given is added at the
-	// 	end of the resolved-sequences.
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"./_base"
+], function(dojo){
+	dojo.experimental("dojox.timing.Sequence");
+	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
+		//	some parameters for each (like: pauseBefore) and they will
+		//	be run one after another. This can be very useful for slideshows
+		//	or alike things.
+		//
+		// description:
+		//	This array will contain the sequence defines resolved, so that
+		// 	ie. repeat:10 will result in 10 elements in the sequence, so
+		// 	the repeat handling is easier and we don't need to handle that
+		// 	many extra cases. Also the doneFunction, if given is added at the
+		// 	end of the resolved-sequences.
 
-/*=====
-	// _defsResolved: Array
-	// 	The resolved sequence, for easier handling.
-	_defsResolved: [],
-=====*/
+	/*=====
+		// _defsResolved: Array
+		// 	The resolved sequence, for easier handling.
+		_defsResolved: [],
+	=====*/
 
-	// This is the time to wait before goOn() calls _go(), which
-	// mostly results from a pauseAfter for a function that returned
-	// false and is later continued by the external goOn() call.
-	// The time to wait needs to be waited in goOn() where the
-	// sequence is continued.
+		// This is the time to wait before goOn() calls _go(), which
+		// mostly results from a pauseAfter for a function that returned
+		// false and is later continued by the external goOn() call.
+		// The time to wait needs to be waited in goOn() where the
+		// sequence is continued.
 
-	// _goOnPause: Integer
-	//	The pause to wait before really going on.
-	_goOnPause: 0,
+		// _goOnPause: Integer
+		//	The pause to wait before really going on.
+		_goOnPause: 0,
 
-	_running: false,
+		_running: false,
 
-	constructor: function(){
-		this._defsResolved = [];
-	},
+		constructor: function(){
+			this._defsResolved = [];
+		},
 
-	go: function(/* Array */defs, /* Function|Array? */doneFunction){
-		// summary: Run the passed sequence definition
-		//
-		// defs: Array
-		//		The sequence of actions
-		// doneFunction: Function|Array?
-		//		The function to call when done
-		this._running = true;
-		dojo.forEach(defs, function(cur){
-			if(cur.repeat > 1){
-				var repeat = cur.repeat;
-				for(var j = 0; j < repeat; j++){
-					cur.repeat = 1;
+		go: function(/* Array */defs, /* Function|Array? */doneFunction){
+			// summary: Run the passed sequence definition
+			//
+			// defs: Array
+			//		The sequence of actions
+			// doneFunction: Function|Array?
+			//		The function to call when done
+			this._running = true;
+			dojo.forEach(defs, function(cur){
+				if(cur.repeat > 1){
+					var repeat = cur.repeat;
+					for(var j = 0; j < repeat; j++){
+						cur.repeat = 1;
+						this._defsResolved.push(cur);
+					}
+				}else{
 					this._defsResolved.push(cur);
 				}
-			}else{
-				this._defsResolved.push(cur);
+			}, this);
+			var last = defs[defs.length - 1];
+			if(doneFunction){
+				this._defsResolved.push({ func: doneFunction });
 			}
-		}, this);
-		var last = defs[defs.length - 1];
-		if(doneFunction){
-			this._defsResolved.push({ func: doneFunction });
-		}
-		// stop the sequence, this actually just sets this._running to false
-		this._defsResolved.push({ func: [this.stop, this] });
-		this._curId = 0;
-		this._go();
-	},
+			// stop the sequence, this actually just sets this._running to false
+			this._defsResolved.push({ func: [this.stop, this] });
+			this._curId = 0;
+			this._go();
+		},
 
-	_go: function(){
-		// summary: Execute one task of this._defsResolved.
+		_go: function(){
+			// 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.
-		if(!this._running){
-			return;
-		}
-		var cur = this._defsResolved[this._curId];
-		this._curId += 1;
-		// create the function to call, the func property might be an array, which means
-		// [function, context, parameter1, parameter2, ...]
-		function resolveAndCallFunc(func) {
-			var ret = null;
-			if(dojo.isArray(func)){
-				// Two elements might only be given when the function+context
-				// is given, this is nice for using this, ie: [this.func, this]
-				if(func.length>2){
-					ret = func[0].apply(func[1], func.slice(2));
+			// if _running was set to false stop the sequence, this is the
+			// case when i.e. stop() was called.
+			if(!this._running){
+				return;
+			}
+			var cur = this._defsResolved[this._curId];
+			this._curId += 1;
+			// create the function to call, the func property might be an array, which means
+			// [function, context, parameter1, parameter2, ...]
+			function resolveAndCallFunc(func) {
+				var ret = null;
+				if(dojo.isArray(func)){
+					// Two elements might only be given when the function+context
+					// is given, this is nice for using this, ie: [this.func, this]
+					if(func.length>2){
+						ret = func[0].apply(func[1], func.slice(2));
+					}else{
+						ret = func[0].apply(func[1]);
+					}
 				}else{
-					ret = func[0].apply(func[1]);
+					ret = func();
 				}
-			}else{
-				ret = func();
+				return ret;
 			}
-			return ret;
-		}
 
-		if(this._curId >= this._defsResolved.length){
-			resolveAndCallFunc(cur.func); // call the last function, since it is the doneFunction we dont need to handle pause stuff
-			// don't go on and call this._go() again, we are done
-			return;
-		}
+			if(this._curId >= this._defsResolved.length){
+				resolveAndCallFunc(cur.func); // call the last function, since it is the doneFunction we dont need to handle pause stuff
+				// don't go on and call this._go() again, we are done
+				return;
+			}
 
-		if(cur.pauseAfter){
-			if(resolveAndCallFunc(cur.func) !== false){
-				setTimeout(dojo.hitch(this, "_go"), cur.pauseAfter);
+			if(cur.pauseAfter){
+				if(resolveAndCallFunc(cur.func) !== false){
+					setTimeout(dojo.hitch(this, "_go"), cur.pauseAfter);
+				}else{
+					this._goOnPause = cur.pauseAfter;
+				}
+			}else if(cur.pauseBefore){
+				var x = dojo.hitch(this,function(){
+					if(resolveAndCallFunc(cur.func) !== false){
+						this._go()
+					}
+				});
+				setTimeout(x, cur.pauseBefore);
 			}else{
-				this._goOnPause = cur.pauseAfter;
-			}
-		}else if(cur.pauseBefore){
-			var x = dojo.hitch(this,function(){
 				if(resolveAndCallFunc(cur.func) !== false){
-					this._go()
+					this._go();
 				}
-			});
-			setTimeout(x, cur.pauseBefore);
-		}else{
-			if(resolveAndCallFunc(cur.func) !== false){
-				this._go();
 			}
-		}
-	},
+		},
 
-	goOn: function(){
-		// 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);
-			this._goOnPause = 0; // reset it, so if the next one doesnt set it we dont use the old pause
-		}else{ this._go(); }
-	},
+		goOn: function(){
+			// 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);
+				this._goOnPause = 0; // reset it, so if the next one doesnt set it we dont use the old pause
+			}else{ this._go(); }
+		},
 
-	stop: function(){
-		// 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
-		//		that is handled inside a function that you have given as
-		//		one sequence item it cant be stopped, since it is not controlled
-		//		by this object here. In this case it would be smarter to
-		//		run the slideshow using a sequence object so you can also stop
-		//		it using this method.
-		this._running = false;
-	}
+		stop: function(){
+			// 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
+			//		that is handled inside a function that you have given as
+			//		one sequence item it cant be stopped, since it is not controlled
+			//		by this object here. In this case it would be smarter to
+			//		run the slideshow using a sequence object so you can also stop
+			//		it using this method.
+			this._running = false;
+		}
 
+	});
+	return dojox.timing.Sequence;
 });
diff --git a/dojox/timing/Streamer.js b/dojox/timing/Streamer.js
index 91a4540..12d90ba 100644
--- a/dojox/timing/Streamer.js
+++ b/dojox/timing/Streamer.js
@@ -1,90 +1,90 @@
-dojo.provide("dojox.timing.Streamer");
-
-dojo.require("dojox.timing._base");
+define(["./_base"], function(){
+	dojo.experimental("dojox.timing.Streamer");
+	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
+		//		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.
 
-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
-	//		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.
+		var self = this;
+		var queue = [];
 
-	var self = this;
-	var queue = [];
+		//	public properties
+		this.interval = interval || 1000;
+		this.minimumSize = minimum || 10;	//	latency usually == interval * minimumSize
+		this.inputFunction = input || function(q){ };
+		this.outputFunction = output || function(point){ };
 
-	//	public properties
-	this.interval = interval || 1000;
-	this.minimumSize = minimum || 10;	//	latency usually == interval * minimumSize
-	this.inputFunction = input || function(q){ };
-	this.outputFunction = output || function(point){ };
+		//	more setup
+		var timer = new dojox.timing.Timer(this.interval);
+		var tick = function(){
+			self.onTick(self);
 
-	//	more setup
-	var timer = new dojox.timing.Timer(this.interval);
-	var tick = function(){
-		self.onTick(self);
+			if(queue.length < self.minimumSize){
+				self.inputFunction(queue);
+			}
 
-		if(queue.length < self.minimumSize){
-			self.inputFunction(queue);
-		}
+			var obj = queue.shift();
+			while(typeof(obj) == "undefined" && queue.length > 0){
+				obj = queue.shift();
+			}
+			
+			//	check to see if the input function needs to be fired
+			//	stop before firing the output function
+			//	TODO: relegate this to the output function?
+			if(typeof(obj) == "undefined"){
+				self.stop();
+				return;
+			}
 
-		var obj = queue.shift();
-		while(typeof(obj) == "undefined" && queue.length > 0){
-			obj = queue.shift();
-		}
-		
-		//	check to see if the input function needs to be fired
-		//	stop before firing the output function
-		//	TODO: relegate this to the output function?
-		if(typeof(obj) == "undefined"){
-			self.stop();
-			return;
-		}
+			//	call the output function.
+			self.outputFunction(obj);
+		};
 
-		//	call the output function.
-		self.outputFunction(obj);
-	};
+		this.setInterval = function(/* int */ms){
+			//	summary
+			//	sets the interval in milliseconds of the internal timer
+			this.interval = ms;
+			timer.setInterval(ms);
+		};
 
-	this.setInterval = function(/* int */ms){
-		//	summary
-		//	sets the interval in milliseconds of the internal timer
-		this.interval = ms;
-		timer.setInterval(ms);
-	};
+		this.onTick = function(/* dojox.timing.Streamer */obj){ };
+		// wrap the timer functions so that we can connect to them if needed.
+		this.start = function(){
+			//	summary
+			//	starts the Streamer
+			if(typeof(this.inputFunction) == "function" && typeof(this.outputFunction) == "function"){
+				timer.start();
+				return;
+			}
+			throw new Error("You cannot start a Streamer without an input and an output function.");
+		};
+		this.onStart = function(){ };
+		this.stop = function(){
+			//	summary
+			//	stops the Streamer
+			timer.stop();
+		};
+		this.onStop = 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
-		//	starts the Streamer
-		if(typeof(this.inputFunction) == "function" && typeof(this.outputFunction) == "function"){
-			timer.start();
-			return;
+		//	finish initialization
+		timer.onTick = this.tick;
+		timer.onStart = this.onStart;
+		timer.onStop = this.onStop;
+		if(initialData){
+			queue.concat(initialData);
 		}
-		throw new Error("You cannot start a Streamer without an input and an output function.");
 	};
-	this.onStart = function(){ };
-	this.stop = function(){
-		//	summary
-		//	stops the Streamer
-		timer.stop();
-	};
-	this.onStop = function(){ };
-
-	//	finish initialization
-	timer.onTick = this.tick;
-	timer.onStart = this.onStart;
-	timer.onStop = this.onStop;
-	if(initialData){
-		queue.concat(initialData);
-	}
-};
+	return dojox.timing.Streamer;
+});
diff --git a/dojox/timing/ThreadPool.js b/dojox/timing/ThreadPool.js
index 4641608..51bc186 100644
--- a/dojox/timing/ThreadPool.js
+++ b/dojox/timing/ThreadPool.js
@@ -1,7 +1,5 @@
-dojo.provide("dojox.timing.ThreadPool");
-dojo.require("dojox.timing");
-
-dojo.experimental("dojox.timing.ThreadPool");
+define(["./_base"], function(){
+	dojo.experimental("dojox.timing.ThreadPool");
 
 //	dojox.timing.Timer is included as part of _base
 /********************************************************************
@@ -10,7 +8,6 @@ dojo.experimental("dojox.timing.ThreadPool");
 	
 	Donated to the Dojo toolkit by the author :)
 *********************************************************************/
-(function(){
 	var t=dojox.timing;
 	t.threadStates={
 		UNSTARTED:"unstarted",
@@ -150,4 +147,5 @@ dojo.experimental("dojox.timing.ThreadPool");
 		//	dedicate the timer to us.
 		timer.onTick=self.invoke;
 	})(16, 5000);
-})();
+	return dojox.timing.ThreadPool;
+});
diff --git a/dojox/timing/_base.js b/dojox/timing/_base.js
index 9b57312..3a7ffc7 100644
--- a/dojox/timing/_base.js
+++ b/dojox/timing/_base.js
@@ -1,54 +1,57 @@
-dojo.provide("dojox.timing._base");
-dojo.experimental("dojox.timing");
+define(["dojo/_base/kernel", "dojo/_base/lang"], function(dojo){
+	dojo.experimental("dojox.timing");
+	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.
-	this.timer = null;
-	this.isRunning = false;
-	this.interval = interval;
+	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.
+		this.timer = null;
+		this.isRunning = false;
+		this.interval = interval;
 
-	this.onStart = null;
-	this.onStop = null;
-};
+		this.onStart = null;
+		this.onStop = null;
+	};
 
-dojo.extend(dojox.timing.Timer, {
-	onTick : function(){
-		// summary: Method called every time the interval passes.  Override to do something useful.
-	},
+	dojo.extend(dojox.timing.Timer, {
+		onTick: function(){
+			// 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.
+			if (this.isRunning){
+				window.clearInterval(this.timer);
+			}
+			this.interval = interval;
+			if (this.isRunning){
+				this.timer = window.setInterval(dojo.hitch(this, "onTick"), this.interval);
+			}
+		},
 		
-	setInterval : function(interval){
-		// summary: Reset the interval of a timer, whether running or not.
-		// interval: New interval, in milliseconds.
-		if (this.isRunning){
-			window.clearInterval(this.timer);
-		}
-		this.interval = interval;
-		if (this.isRunning){
+		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.
+			if (typeof this.onStart == "function"){
+				this.onStart();
+			}
+			this.isRunning = true;
 			this.timer = window.setInterval(dojo.hitch(this, "onTick"), this.interval);
+		},
+		
+		stop: function(){
+			// summary: Stop the timer.
+			// description: Calls the "onStop()" handler, if defined.
+			if (typeof this.onStop == "function"){
+				this.onStop();
+			}
+			this.isRunning = false;
+			window.clearInterval(this.timer);
 		}
-	},
-	
-	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.
-		if (typeof this.onStart == "function"){
-			this.onStart();
-		}
-		this.isRunning = true;
-		this.timer = window.setInterval(dojo.hitch(this, "onTick"), this.interval);
-	},
-	
-	stop : function(){
-		// summary: Stop the timer.
-		// description: Calls the "onStop()" handler, if defined.
-		if (typeof this.onStop == "function"){
-			this.onStop();
-		}
-		this.isRunning = false;
-		window.clearInterval(this.timer);
-	}
+	});
+	return dojox.timing;
 });
diff --git a/dojox/timing/doLater.js b/dojox/timing/doLater.js
index ad1e37a..61b23ee 100644
--- a/dojox/timing/doLater.js
+++ b/dojox/timing/doLater.js
@@ -1,42 +1,46 @@
-dojo.provide("dojox.timing.doLater");
-dojo.experimental("dojox.timing.doLater");
-
-dojox.timing.doLater = function(/*anything*/conditional,/*Object ?*/context, /* Number ? */interval){
-	// summary:
-	//		Check if a parameter is ready, and if not,
-	//		"do later". doLater will ping the parameter
-	//		until it evaluates to something (truthy).
-	//		It thens calls the caller with original
-	//		arguments, using the supplied context or
-	//		window.
-	//	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
-	// example:
-	//		| 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 = dojox.timing.doLater.caller,
-		args = dojox.timing.doLater.caller.arguments;
-	interval = interval || 100;
-	context = context || dojo.global;
-	
-	setTimeout(function(){
-		callback.apply(context, args);
-	},interval);
-	return true; // Boolean
-}
+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,
+		//		"do later". doLater will ping the parameter
+		//		until it evaluates to something (truthy).
+		//		It thens calls the caller with original
+		//		arguments, using the supplied context or
+		//		window.
+		//	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
+		// example:
+		//		| 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;
+		interval = interval || 100;
+		context = context || dojo.global;
+		
+		setTimeout(function(){
+			callback.apply(context, args);
+		},interval);
+		return true; // Boolean
+	};
+	return dxt.doLater;
+});
diff --git a/dojox/timing/tests/test_Sequence.html b/dojox/timing/tests/test_Sequence.html
index 1d0513d..5f93e59 100644
--- a/dojox/timing/tests/test_Sequence.html
+++ b/dojox/timing/tests/test_Sequence.html
@@ -11,7 +11,9 @@
 	</style>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true" ></script>
+	<!--
 	<script type="text/javascript" src="../Sequence.js"></script>
+	-->
 	<script type="text/javascript">
 		dojo.require("dojox.timing.Sequence"); 
 
diff --git a/dojox/timing/tests/test_ThreadPool.html b/dojox/timing/tests/test_ThreadPool.html
index 53e4bfb..8328df2 100644
--- a/dojox/timing/tests/test_ThreadPool.html
+++ b/dojox/timing/tests/test_ThreadPool.html
@@ -2,7 +2,6 @@
 	<head>
 		<title>Quick Thread Pool Test</title>
 		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true" ></script>
-		<script type="text/javascript" src="../ThreadPool.js"></script>
 		<style type="text/css">
 			@import "../../../dojo/resources/dojo.css";
 		</style>
diff --git a/dojox/uuid.js b/dojox/uuid.js
index c85931c..962bd99 100644
--- a/dojox/uuid.js
+++ b/dojox/uuid.js
@@ -1,2 +1,3 @@
-dojo.provide("dojox.uuid");
-dojo.require("dojox.uuid._base");
+define(['dojox/uuid/_base'], function(uuid){
+	return uuid;
+});
diff --git a/dojox/uuid/Uuid.js b/dojox/uuid/Uuid.js
index bc8ab4a..740b229 100644
--- a/dojox/uuid/Uuid.js
+++ b/dojox/uuid/Uuid.js
@@ -1,5 +1,4 @@
-dojo.provide("dojox.uuid.Uuid");
-dojo.require("dojox.uuid");
+define(['dojo/_base/lang', './_base'], function(dojo, uuid){
 
 dojox.uuid.Uuid = function(/*String?*/ input){
 	// summary:
@@ -194,3 +193,7 @@ dojox.uuid.Uuid.prototype.getTimestamp = function(/*String?*/ returnType){
 			break;
 	}
 };
+
+return dojox.uuid.Uuid;
+
+});
diff --git a/dojox/uuid/_base.js b/dojox/uuid/_base.js
index 8a58bde..5a6fa98 100644
--- a/dojox/uuid/_base.js
+++ b/dojox/uuid/_base.js
@@ -1,4 +1,6 @@
-dojo.provide("dojox.uuid._base");
+define(['dojo/_base/kernel', 'dojo/_base/lang'], function(dojo){
+
+dojo.getObject("uuid", true, dojox);
 
 // Public constants:
 dojox.uuid.NIL_UUID = "00000000-0000-0000-0000-000000000000";
@@ -239,3 +241,7 @@ dojox.uuid.getTimestamp = function(/*String*/ uuidString, /*String?*/ returnType
 			break;
 	}
 };
+
+return dojox.uuid;
+
+});
diff --git a/dojox/uuid/generateRandomUuid.js b/dojox/uuid/generateRandomUuid.js
index 869c272..9543f2b 100644
--- a/dojox/uuid/generateRandomUuid.js
+++ b/dojox/uuid/generateRandomUuid.js
@@ -1,4 +1,4 @@
-dojo.provide("dojox.uuid.generateRandomUuid");
+define(['./_base'], function(){
 
 dojox.uuid.generateRandomUuid = function(){
 	// summary:
@@ -50,3 +50,7 @@ dojox.uuid.generateRandomUuid = function(){
 	returnValue = returnValue.toLowerCase();
 	return returnValue; // String
 };
+
+return dojox.uuid.generateRandomUuid;
+
+});
diff --git a/dojox/uuid/generateTimeBasedUuid.js b/dojox/uuid/generateTimeBasedUuid.js
index cd40fe1..da58816 100644
--- a/dojox/uuid/generateTimeBasedUuid.js
+++ b/dojox/uuid/generateTimeBasedUuid.js
@@ -1,4 +1,4 @@
-dojo.provide("dojox.uuid.generateTimeBasedUuid");
+define([ 'dojo/_base/lang', './_base'], function(lang){
 
 dojox.uuid.generateTimeBasedUuid = function(/*String?*/ node){
 	// summary:
@@ -28,7 +28,7 @@ dojox.uuid.generateTimeBasedUuid = function(/*String?*/ node){
 dojox.uuid.generateTimeBasedUuid.isValidNode = function(/*String?*/ node){
 	var HEX_RADIX = 16;
 	var integer = parseInt(node, HEX_RADIX);
-	var valid = dojo.isString(node) && node.length == 12 && isFinite(integer);
+	var valid = lang.isString(node) && node.length == 12 && isFinite(integer);
 	return valid; // Boolean
 };
 
@@ -107,8 +107,8 @@ dojox.uuid.generateTimeBasedUuid._generator = new function(){
 		//		that is the sum of the two original numbers.
 		// arrayA: An array with 4 elements, each of which is a 16-bit number.
 		// arrayB: An array with 4 elements, each of which is a 16-bit number.
-		dojox.uuid.assert(dojo.isArray(arrayA));
-		dojox.uuid.assert(dojo.isArray(arrayB));
+		dojox.uuid.assert(lang.isArray(arrayA));
+		dojox.uuid.assert(lang.isArray(arrayB));
 		dojox.uuid.assert(arrayA.length == 4);
 		dojox.uuid.assert(arrayB.length == 4);
 	
@@ -128,8 +128,8 @@ dojox.uuid.generateTimeBasedUuid._generator = new function(){
 		//		that is the product of the two original numbers.
 		// arrayA: An array with 4 elements, each of which is a 16-bit number.
 		// arrayB: An array with 4 elements, each of which is a 16-bit number.
-		dojox.uuid.assert(dojo.isArray(arrayA));
-		dojox.uuid.assert(dojo.isArray(arrayB));
+		dojox.uuid.assert(lang.isArray(arrayA));
+		dojox.uuid.assert(lang.isArray(arrayB));
 		dojox.uuid.assert(arrayA.length == 4);
 		dojox.uuid.assert(arrayB.length == 4);
 	
@@ -284,3 +284,7 @@ dojox.uuid.generateTimeBasedUuid._generator = new function(){
 	}
 
 }();
+
+return dojox.uuid.generateTimeBasedUuid;
+
+});
diff --git a/dojox/uuid/tests/uuid.js b/dojox/uuid/tests/uuid.js
index 090c822..ab5bcf8 100644
--- a/dojox/uuid/tests/uuid.js
+++ b/dojox/uuid/tests/uuid.js
@@ -1,10 +1,6 @@
-dojo.provide("dojox.uuid.tests.uuid");
-dojo.require("dojox.uuid");
-dojo.require("dojox.uuid.Uuid");
-dojo.require("dojox.uuid.generateRandomUuid");
-dojo.require("dojox.uuid.generateTimeBasedUuid");
+define(['doh', 'dojo/_base/lang', '../_base', '../Uuid', '../generateRandomUuid', '../generateTimeBasedUuid'], function(doh, dojo, dxuuid, Uuid, generateRandomUuid, generateTimeBasedUuid){
 
-dojox.uuid.tests.uuid.checkValidityOfUuidString = function(/*String*/uuidString){
+var checkValidityOfUuidString = function(/*String*/uuidString){
 	// summary:
 	//		A helper function that's used by the registered test functions
 	var NIL_UUID = "00000000-0000-0000-0000-000000000000";
@@ -44,16 +40,16 @@ dojox.uuid.tests.uuid.checkValidityOfUuidString = function(/*String*/uuidString)
 	doh.assertTrue(binaryString.charAt(1) == '0'); // second bit of section 3 is 0
 }
 
-dojox.uuid.tests.uuid.checkValidityOfTimeBasedUuidString = function(/*String*/uuidString){
+var checkValidityOfTimeBasedUuidString = function(/*String*/uuidString){
 	// summary:
 	//		A helper function that's used by the registered test functions
-	dojox.uuid.tests.uuid.checkValidityOfUuidString(uuidString);
+	checkValidityOfUuidString(uuidString);
 	var arrayOfParts = uuidString.split("-");
 	var section2 = arrayOfParts[2];
 	doh.assertTrue(section2.charAt(0) == "1"); // Section 2 starts with a 1
 }
 
-dojox.uuid.tests.uuid.checkForPseudoNodeBitInTimeBasedUuidString = function(/*String*/uuidString){
+var checkForPseudoNodeBitInTimeBasedUuidString = function(/*String*/uuidString){
 	// summary:
 	//		A helper function that's used by the registered test functions
 	var arrayOfParts = uuidString.split("-");
@@ -105,11 +101,11 @@ doh.register("dojox.uuid.tests.uuid",
 			var timebasedLowercaseString = "b4308fb0-86cd-11da-a72b-0800200c9a66";
 			var timebasedUppercaseString = "B4308FB0-86CD-11DA-A72B-0800200C9A66";
 			
-			var uuidRL = new dojox.uuid.Uuid(randomLowercaseString);
-			var uuidRU = new dojox.uuid.Uuid(randomUppercaseString);
+			var uuidRL = new Uuid(randomLowercaseString);
+			var uuidRU = new Uuid(randomUppercaseString);
 			
-			var uuidTL = new dojox.uuid.Uuid(timebasedLowercaseString);
-			var uuidTU = new dojox.uuid.Uuid(timebasedUppercaseString);
+			var uuidTL = new Uuid(timebasedLowercaseString);
+			var uuidTU = new Uuid(timebasedUppercaseString);
 			
 			doh.assertTrue(uuidRL.isEqual(uuidRU));
 			doh.assertTrue(uuidRU.isEqual(uuidRL));
@@ -122,22 +118,22 @@ doh.register("dojox.uuid.tests.uuid",
 			var uuid, uuidToo;
 			
 			var nilUuid = '00000000-0000-0000-0000-000000000000';
-			uuid = new dojox.uuid.Uuid();
+			uuid = new Uuid();
 			doh.assertTrue(uuid == nilUuid); // 'new dojox.uuid.Uuid()' returns the Nil UUID
 			
 			var randomUuidString = "3b12f1df-5232-4804-897e-917bf397618a";
-			uuid = new dojox.uuid.Uuid(randomUuidString);
+			uuid = new Uuid(randomUuidString);
 			doh.assertTrue(uuid.isValid());
-			doh.assertTrue(uuid.getVariant() == dojox.uuid.variant.DCE);
-			doh.assertTrue(uuid.getVersion() == dojox.uuid.version.RANDOM);
-			uuidToo = new dojox.uuid.Uuid(new String(randomUuidString));
+			doh.assertTrue(uuid.getVariant() == dxuuid.variant.DCE);
+			doh.assertTrue(uuid.getVersion() == dxuuid.version.RANDOM);
+			uuidToo = new Uuid(new String(randomUuidString));
 			doh.assertTrue(uuid.isEqual(uuidToo));
 		
 			var timeBasedUuidString = "b4308fb0-86cd-11da-a72b-0800200c9a66";
-			uuid = new dojox.uuid.Uuid(timeBasedUuidString);
+			uuid = new Uuid(timeBasedUuidString);
 			doh.assertTrue(uuid.isValid());
-			doh.assertTrue(uuid.getVariant() == dojox.uuid.variant.DCE);
-			doh.assertTrue(uuid.getVersion() == dojox.uuid.version.TIME_BASED);
+			doh.assertTrue(uuid.getVariant() == dxuuid.variant.DCE);
+			doh.assertTrue(uuid.getVersion() == dxuuid.version.TIME_BASED);
 			doh.assertTrue(uuid.getNode() == "0800200c9a66");
 			var timestamp = uuid.getTimestamp();
 			var date = uuid.getTimestamp(Date);
@@ -151,9 +147,9 @@ doh.register("dojox.uuid.tests.uuid",
 		
 		function test_uuid_generators(){
 			var generators = [
-				dojox.uuid.generateNilUuid,
-				dojox.uuid.generateRandomUuid,
-				dojox.uuid.generateTimeBasedUuid
+				dxuuid.generateNilUuid,
+				generateRandomUuid,
+				generateTimeBasedUuid
 			];
 			
 			for(var i in generators){
@@ -161,35 +157,35 @@ doh.register("dojox.uuid.tests.uuid",
 				var uuidString = generator();
 
 				doh.assertTrue((typeof uuidString) == 'string');
-				dojox.uuid.tests.uuid.checkValidityOfUuidString(uuidString);
+				checkValidityOfUuidString(uuidString);
 
-				var uuid = new dojox.uuid.Uuid(uuidString);
-				if(generator != dojox.uuid.generateNilUuid){
-					doh.assertTrue(uuid.getVariant() == dojox.uuid.variant.DCE);
+				var uuid = new Uuid(uuidString);
+				if(generator != dxuuid.generateNilUuid){
+					doh.assertTrue(uuid.getVariant() == dxuuid.variant.DCE);
 				}
 
 				doh.assertTrue(uuid.isEqual(uuid));
 				doh.assertTrue(uuid.compare(uuid) == 0);
-				doh.assertTrue(dojox.uuid.Uuid.compare(uuid, uuid) == 0);
-				dojox.uuid.tests.uuid.checkValidityOfUuidString(uuid.toString());
+				doh.assertTrue(Uuid.compare(uuid, uuid) == 0);
+				checkValidityOfUuidString(uuid.toString());
 				doh.assertTrue(uuid.toString().length == 36);
 		
-				if(generator != dojox.uuid.generateNilUuid){
+				if(generator != dxuuid.generateNilUuid){
 					var uuidStringOne = generator();
 					var uuidStringTwo = generator();
 					doh.assertTrue(uuidStringOne != uuidStringTwo);
 					
-					dojox.uuid.Uuid.setGenerator(generator);
-					var uuidOne = new dojox.uuid.Uuid();
-					var uuidTwo = new dojox.uuid.Uuid();
-					doh.assertTrue(generator === dojox.uuid.Uuid.getGenerator());
-					dojox.uuid.Uuid.setGenerator(null);
+					Uuid.setGenerator(generator);
+					var uuidOne = new Uuid();
+					var uuidTwo = new Uuid();
+					doh.assertTrue(generator === Uuid.getGenerator());
+					Uuid.setGenerator(null);
 					doh.assertTrue(uuidOne != uuidTwo);
 					doh.assertTrue(!uuidOne.isEqual(uuidTwo));
 					doh.assertTrue(!uuidTwo.isEqual(uuidOne));
 					
-					var oneVsTwo = dojox.uuid.Uuid.compare(uuidOne, uuidTwo); // either 1 or -1
-					var twoVsOne = dojox.uuid.Uuid.compare(uuidTwo, uuidOne); // either -1 or 1
+					var oneVsTwo = Uuid.compare(uuidOne, uuidTwo); // either 1 or -1
+					var twoVsOne = Uuid.compare(uuidTwo, uuidOne); // either -1 or 1
 					doh.assertTrue(oneVsTwo + twoVsOne == 0);
 					doh.assertTrue(oneVsTwo != 0);
 					doh.assertTrue(twoVsOne != 0);
@@ -197,13 +193,13 @@ doh.register("dojox.uuid.tests.uuid",
 					doh.assertTrue(!uuidTwo.isEqual(uuidOne));
 				}
 				
-				if(generator == dojox.uuid.generateRandomUuid){
-					doh.assertTrue(uuid.getVersion() == dojox.uuid.version.RANDOM);
+				if(generator == generateRandomUuid){
+					doh.assertTrue(uuid.getVersion() == dxuuid.version.RANDOM);
 				}
 				
-				if(generator == dojox.uuid.generateTimeBasedUuid){
-					dojox.uuid.tests.uuid.checkValidityOfTimeBasedUuidString(uuid.toString());
-					doh.assertTrue(uuid.getVersion() == dojox.uuid.version.TIME_BASED);
+				if(generator == generateTimeBasedUuid){
+					checkValidityOfTimeBasedUuidString(uuid.toString());
+					doh.assertTrue(uuid.getVersion() == dxuuid.version.TIME_BASED);
 					doh.assertTrue(dojo.isString(uuid.getNode()));
 					doh.assertTrue(uuid.getNode().length == 12);
 					var timestamp = uuid.getTimestamp();
@@ -219,34 +215,34 @@ doh.register("dojox.uuid.tests.uuid",
 		
 		function test_uuid_nilGenerator(){
 			var nilUuidString = '00000000-0000-0000-0000-000000000000';
-			var uuidString = dojox.uuid.generateNilUuid();
+			var uuidString = dxuuid.generateNilUuid();
 			doh.assertTrue(uuidString == nilUuidString);
 		},
 		
 		function test_uuid_timeBasedGenerator(){
 			var uuid;   // an instance of dojox.uuid.Uuid
 			var string; // a simple string literal
-			var generator = dojox.uuid.generateTimeBasedUuid;
+			var generator = generateTimeBasedUuid;
 
 			var string1 = generator();
-			var uuid2    = new dojox.uuid.Uuid(generator());
+			var uuid2    = new Uuid(generator());
 			var string3 = generator("017bf397618a");         // hardwareNode
 			var string4 = generator("f17bf397618a");         // pseudoNode
 			var string5 = generator(new String("017BF397618A"));
 			
-			dojox.uuid.generateTimeBasedUuid.setNode("017bf397618a");
+			generateTimeBasedUuid.setNode("017bf397618a");
 			var string6 = generator(); // the generated UUID has node == "017bf397618a"
-			var uuid7   = new dojox.uuid.Uuid(generator()); // the generated UUID has node == "017bf397618a"
-			var returnedNode = dojox.uuid.generateTimeBasedUuid.getNode();
+			var uuid7   = new Uuid(generator()); // the generated UUID has node == "017bf397618a"
+			var returnedNode = generateTimeBasedUuid.getNode();
 			doh.assertTrue(returnedNode == "017bf397618a");
 		
 			function getNode(string){
 				var arrayOfStrings = string.split('-');
 				return arrayOfStrings[4];
 			}
-			dojox.uuid.tests.uuid.checkForPseudoNodeBitInTimeBasedUuidString(string1);
-			dojox.uuid.tests.uuid.checkForPseudoNodeBitInTimeBasedUuidString(uuid2.toString());
-			dojox.uuid.tests.uuid.checkForPseudoNodeBitInTimeBasedUuidString(string4);
+			checkForPseudoNodeBitInTimeBasedUuidString(string1);
+			checkForPseudoNodeBitInTimeBasedUuidString(uuid2.toString());
+			checkForPseudoNodeBitInTimeBasedUuidString(string4);
 			
 			doh.assertTrue(getNode(string3) == "017bf397618a");
 			doh.assertTrue(getNode(string4) == "f17bf397618a");
@@ -254,13 +250,13 @@ doh.register("dojox.uuid.tests.uuid",
 			doh.assertTrue(getNode(string6) == "017bf397618a");
 			doh.assertTrue(uuid7.getNode() == "017bf397618a");
 			
-			dojox.uuid.tests.uuid.checkValidityOfTimeBasedUuidString(string1);
-			dojox.uuid.tests.uuid.checkValidityOfTimeBasedUuidString(uuid2.toString());
-			dojox.uuid.tests.uuid.checkValidityOfTimeBasedUuidString(string3);
-			dojox.uuid.tests.uuid.checkValidityOfTimeBasedUuidString(string4);
-			dojox.uuid.tests.uuid.checkValidityOfTimeBasedUuidString(string5);
-			dojox.uuid.tests.uuid.checkValidityOfTimeBasedUuidString(string6);
-			dojox.uuid.tests.uuid.checkValidityOfTimeBasedUuidString(uuid7.toString());
+			checkValidityOfTimeBasedUuidString(string1);
+			checkValidityOfTimeBasedUuidString(uuid2.toString());
+			checkValidityOfTimeBasedUuidString(string3);
+			checkValidityOfTimeBasedUuidString(string4);
+			checkValidityOfTimeBasedUuidString(string5);
+			checkValidityOfTimeBasedUuidString(string6);
+			checkValidityOfTimeBasedUuidString(uuid7.toString());
 		},
 
 		function test_uuid_invalidUuids(){
@@ -275,7 +271,7 @@ doh.register("dojox.uuid.tests.uuid",
 			for(var i in uuidStrings){
 				var uuidString = uuidStrings[i];
 				try{
-					new dojox.uuid.Uuid(uuidString);
+					new Uuid(uuidString);
 				}catch (e){
 					++numberOfFailures;
 				}
@@ -293,7 +289,7 @@ function test_uuid_get64bitArrayFromFloat(){
 	//		This is a test we'd like to be able to run, but we can't run it
 	//		because it tests a function which is private in generateTimeBasedUuid
 	var x = Math.pow(2, 63) + Math.pow(2, 15);
-	var result = dojox.uuid.generateTimeBasedUuid._get64bitArrayFromFloat(x);
+	var result = generateTimeBasedUuid._get64bitArrayFromFloat(x);
 	doh.assertTrue(result[0] === 0x8000);
 	doh.assertTrue(result[1] === 0x0000);
 	doh.assertTrue(result[2] === 0x0000);
@@ -301,7 +297,7 @@ function test_uuid_get64bitArrayFromFloat(){
 
 	var date = new Date();
 	x = date.valueOf();
-	result = dojox.uuid.generateTimeBasedUuid._get64bitArrayFromFloat(x);
+	result = generateTimeBasedUuid._get64bitArrayFromFloat(x);
 	var reconstructedFloat = result[0];
 	reconstructedFloat *= 0x10000;
 	reconstructedFloat += result[1];
@@ -319,7 +315,7 @@ function test_uuid_addTwo64bitArrays(){
 	//		because it tests a function which is private in generateTimeBasedUuid
 	var a = [0x0000, 0x0000, 0x0000, 0x0001];
 	var b = [0x0FFF, 0xFFFF, 0xFFFF, 0xFFFF];
-	var result = dojox.uuid.generateTimeBasedUuid._addTwo64bitArrays(a, b);
+	var result = generateTimeBasedUuid._addTwo64bitArrays(a, b);
 	doh.assertTrue(result[0] === 0x1000);
 	doh.assertTrue(result[1] === 0x0000);
 	doh.assertTrue(result[2] === 0x0000);
@@ -327,7 +323,7 @@ function test_uuid_addTwo64bitArrays(){
 
 	a = [0x4000, 0x8000, 0x8000, 0x8000];
 	b = [0x8000, 0x8000, 0x8000, 0x8000];
-	result = dojox.uuid.generateTimeBasedUuid._addTwo64bitArrays(a, b);
+	result = generateTimeBasedUuid._addTwo64bitArrays(a, b);
 	doh.assertTrue(result[0] === 0xC001);
 	doh.assertTrue(result[1] === 0x0001);
 	doh.assertTrue(result[2] === 0x0001);
@@ -335,7 +331,7 @@ function test_uuid_addTwo64bitArrays(){
 
 	a = [7, 6, 2, 5];
 	b = [1, 0, 3, 4];
-	result = dojox.uuid.generateTimeBasedUuid._addTwo64bitArrays(a, b);
+	result = generateTimeBasedUuid._addTwo64bitArrays(a, b);
 	doh.assertTrue(result[0] === 8);
 	doh.assertTrue(result[1] === 6);
 	doh.assertTrue(result[2] === 5);
@@ -348,7 +344,7 @@ function test_uuid_multiplyTwo64bitArrays(){
 	//		because it tests a function which is private in generateTimeBasedUuid
 	var a = [     0, 0x0000, 0x0000, 0x0003];
 	var b = [0x1111, 0x1234, 0x0000, 0xFFFF];
-	var result = dojox.uuid.generateTimeBasedUuid._multiplyTwo64bitArrays(a, b);
+	var result = generateTimeBasedUuid._multiplyTwo64bitArrays(a, b);
 	doh.assertTrue(result[0] === 0x3333);
 	doh.assertTrue(result[1] === 0x369C);
 	doh.assertTrue(result[2] === 0x0002);
@@ -356,7 +352,7 @@ function test_uuid_multiplyTwo64bitArrays(){
 
 	a = [0, 0, 0, 5];
 	b = [0, 0, 0, 4];
-	result = dojox.uuid.generateTimeBasedUuid._multiplyTwo64bitArrays(a, b);
+	result = generateTimeBasedUuid._multiplyTwo64bitArrays(a, b);
 	doh.assertTrue(result[0] === 0);
 	doh.assertTrue(result[1] === 0);
 	doh.assertTrue(result[2] === 0);
@@ -364,10 +360,11 @@ function test_uuid_multiplyTwo64bitArrays(){
 
 	a = [0, 0, 2, 5];
 	b = [0, 0, 3, 4];
-	result = dojox.uuid.generateTimeBasedUuid._multiplyTwo64bitArrays(a, b);
+	result = generateTimeBasedUuid._multiplyTwo64bitArrays(a, b);
 	doh.assertTrue(result[0] === 0);
 	doh.assertTrue(result[1] === 6);
 	doh.assertTrue(result[2] === 23);
 	doh.assertTrue(result[3] === 20);
 }
 */
+});
diff --git a/dojox/validate.js b/dojox/validate.js
index b81ed0c..a6e10d1 100644
--- a/dojox/validate.js
+++ b/dojox/validate.js
@@ -1,2 +1,8 @@
-dojo.provide("dojox.validate");
-dojo.require("dojox.validate._base");
+define(["./validate/_base"], function(validate){
+	/*===== 
+	dojox.validate = {
+		// summary: Additional validation routines for Strings, Numbers, credit cards, and other esoteric needs. 
+	};
+	=====*/
+	return validate;
+});
diff --git a/dojox/validate/_base.js b/dojox/validate/_base.js
index b8d2091..f612d30 100644
--- a/dojox/validate/_base.js
+++ b/dojox/validate/_base.js
@@ -1,11 +1,16 @@
-dojo.provide("dojox.validate._base");
-dojo.experimental("dojox.validate");
+define([
+	"dojo/_base/lang",
+	"dojo/regexp", // dojo core expressions
+	"dojo/number", // dojo number expressions
+	"./regexp" // additional expressions
+], function(lang, regexp, number, xregexp) {
 
-dojo.require("dojo.regexp");		// dojo core expressions
-dojo.require("dojo.number");		// dojo number expressions
-dojo.require("dojox.validate.regexp"); 	// additional expressions
+	var validate = lang.getObject("dojox.validate", true);
+	/*=====
+		validate = dojox.validate;
+	=====*/
 
-dojox.validate.isText = function(/*String*/value, /*Object?*/flags){
+validate.isText = function(/*String*/value, /*Object?*/flags){
 	// summary:
 	//	Checks if a string has non whitespace characters.
 	//	Parameters allow you to constrain the length.
@@ -28,10 +33,10 @@ dojox.validate.isText = function(/*String*/value, /*Object?*/flags){
 	
 	return true; // Boolean
 
-}
+};
 
-dojox.validate._isInRangeCache = {};
-dojox.validate.isInRange = function(/*String*/value, /*Object?*/flags){
+validate._isInRangeCache = {};
+validate.isInRange = function(/*String*/value, /*Object?*/flags){
 	// summary:
 	//	Validates whether a string denoting a number
 	//	is between a max and min.
@@ -42,7 +47,7 @@ dojox.validate.isInRange = function(/*String*/value, /*Object?*/flags){
 	//    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 = dojo.number.parse(value, flags);
+	value = number.parse(value, flags);
 	if(isNaN(value)){
 		return false; // Boolean
 	}
@@ -53,7 +58,7 @@ dojox.validate.isInRange = function(/*String*/value, /*Object?*/flags){
 		min = (typeof flags.min == "number") ? flags.min : -Infinity,
 		dec = (typeof flags.decimal == "string") ? flags.decimal : ".",
 	
-		cache = dojox.validate._isInRangeCache,
+		cache = validate._isInRangeCache,
 		cacheIdx = value + "max" + max + "min" + min + "dec" + dec
 	;
 	if(typeof cache[cacheIdx] != "undefined"){
@@ -63,9 +68,9 @@ dojox.validate.isInRange = function(/*String*/value, /*Object?*/flags){
 	cache[cacheIdx] = !(value < min || value > max);
 	return cache[cacheIdx]; // Boolean
 
-}
+};
 
-dojox.validate.isNumberFormat = function(/* String */value, /* Object? */flags){
+validate.isNumberFormat = function(/* String */value, /* Object? */flags){
 	// summary: Validates any sort of number based format
 	//
 	// description:
@@ -103,18 +108,18 @@ dojox.validate.isNumberFormat = function(/* String */value, /* Object? */flags){
 	// |	});
 	//
 
-	var re = new RegExp("^" + dojox.validate.regexp.numberFormat(flags) + "$", "i");
+	var re = new RegExp("^" + xregexp.numberFormat(flags) + "$", "i");
 	return re.test(value); // Boolean
-}
+};
 
-dojox.validate.isValidLuhn = function(/* String */value){
+validate.isValidLuhn = function(/* String */value){
 	// summary: Validate a String value against the Luhn algorithm.
 	// description:
 	//		Validate a String value against the Luhn algorithm to verify
 	//		its integrity.
 	
 	var sum = 0, parity, curDigit;
-	if(!dojo.isString(value)){
+	if(!lang.isString(value)){
 		value = String(value);
 	}
 	value = value.replace(/[- ]/g,''); //ignore dashes and whitespaces
@@ -131,5 +136,8 @@ dojox.validate.isValidLuhn = function(/* String */value){
 		sum += curDigit;
 	}
 	return !(sum % 10); // Boolean
-}
+};
 
+return validate;
+
+});
diff --git a/dojox/validate/br.js b/dojox/validate/br.js
index 0d08711..ac7907b 100755
--- a/dojox/validate/br.js
+++ b/dojox/validate/br.js
@@ -1,14 +1,14 @@
-dojo.provide("dojox.validate.br");
-dojo.require("dojox.validate._base");
+define(["dojo/_base/lang", "./_base"], function(lang, validate){
 
-dojox.validate.br.isValidCnpj = function(/*String*/value){
+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
-	if(!dojo.isString(value)){
+	if(!lang.isString(value)){
 		if(!value){
 			return false;
 		}
@@ -25,7 +25,7 @@ dojox.validate.br.isValidCnpj = function(/*String*/value){
 			"##############"
 		]
 	};
-	if(dojox.validate.isNumberFormat(value, flags)){
+	if(validate.isNumberFormat(value, flags)){
 		// Matched the initial test, so break this down into the
 		// parts to be validated.
 		value = value.replace("/", "").replace(/\./g, "").replace("-", "");
@@ -77,11 +77,11 @@ dojox.validate.br.isValidCnpj = function(/*String*/value){
 	return false;
 };
 
-dojox.validate.br.computeCnpjDv = 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
-	if(!dojo.isString(value)){
+	if(!lang.isString(value)){
 		if(!value){
 			return "";
 		}
@@ -97,7 +97,7 @@ dojox.validate.br.computeCnpjDv = function(/*String*/value){
 			"############"
 		]
 	};
-	if(dojox.validate.isNumberFormat(value, flags)){
+	if(validate.isNumberFormat(value, flags)){
 		// Matched the initial test, so break this down into the
 		// parts to compute the DV.
 		value = value.replace("/", "").replace(/\./g, "");
@@ -138,14 +138,14 @@ dojox.validate.br.computeCnpjDv = function(/*String*/value){
 };
 
 
-dojox.validate.br.isValidCpf = function(/*String*/value){
+br.isValidCpf = function(/*String*/value){
 	// summary:
 	//		Validates a CPF number
 	//
 	// value: String
 	//		The CPF number in #########-## or ###########,
 	//		format
-	if(!dojo.isString(value)){
+	if(!lang.isString(value)){
 		if(!value){
 			return false;
 		}
@@ -161,7 +161,7 @@ dojox.validate.br.isValidCpf = function(/*String*/value){
 			"###########"
 		]
 	};
-	if(dojox.validate.isNumberFormat(value, flags)){
+	if(validate.isNumberFormat(value, flags)){
 		// Matched the initial test, so break this down into the
 		// parts to be validated.
 		value = value.replace("-", "").replace(/\./g, "");
@@ -213,13 +213,13 @@ dojox.validate.br.isValidCpf = function(/*String*/value){
 	return false;
 };
 
-dojox.validate.br.computeCpfDv = 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(!dojo.isString(value)){
+	if(!lang.isString(value)){
 		if(!value){
 			return "";
 		}
@@ -234,7 +234,7 @@ dojox.validate.br.computeCpfDv = function(/*String*/value){
 			"#########"
 		]
 	};
-	if(dojox.validate.isNumberFormat(value, flags)){
+	if(validate.isNumberFormat(value, flags)){
 		// Matched the initial test, so break this down into the
 		// parts to compute the DV.
 		value = value.replace(/\./g, "");
@@ -273,3 +273,5 @@ dojox.validate.br.computeCpfDv = function(/*String*/value){
 	return "";
 };
 
+return br;
+});
diff --git a/dojox/validate/ca.js b/dojox/validate/ca.js
index 61eb1c2..e991d18 100644
--- a/dojox/validate/ca.js
+++ b/dojox/validate/ca.js
@@ -1,4 +1,5 @@
-dojo.provide("dojox.validate.ca");
+define(["dojo/_base/lang", "./_base", "./regexp", "./us"], 
+ function(lang, validate, xregexp, us){
 /*=====
 
 	dojox.validate.ca = {
@@ -6,18 +7,18 @@ dojo.provide("dojox.validate.ca");
 	}
 
 =====*/
-dojo.require("dojox.validate._base");
 
-dojo.mixin(dojox.validate.ca,{
+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
-		return dojox.validate.us.isPhoneNumber(value);  // Boolean
+		return us.isPhoneNumber(value);  // Boolean
 	},
 
 	isProvince: function(/* String[2] */value) {
 		// summary: Validates Canadian province abbreviations (2 characters)
-		var re = new RegExp("^" + dojox.validate.regexp.ca.province() + "$", "i");
+		var re = new RegExp("^" + xregexp.ca.province() + "$", "i");
 		return re.test(value); // Boolean
 	},
  
@@ -31,7 +32,7 @@ dojo.mixin(dojox.validate.ca,{
 		//		use the Luhn Algorithm to validate number.
 		//
 		var flags = { format: [ "###-###-###", "### ### ###", "#########" ]};
-		return dojox.validate.isNumberFormat(value, flags); // Boolean
+		return validate.isNumberFormat(value, flags); // Boolean
 	},
 
 	isPostalCode: function(value) {
@@ -43,8 +44,11 @@ dojo.mixin(dojox.validate.ca,{
 		//		where A is a letter and N is a digit, with a space
 		//		separating the third and fourth characters.
 		//
-		var re = new RegExp("^" + dojox.validate.regexp.ca.postalCode() + "$", "i");
+		var re = new RegExp("^" + xregexp.ca.postalCode() + "$", "i");
 		return re.test(value); // Boolean
 	}
 
 });
+
+return ca;
+});
diff --git a/dojox/validate/check.js b/dojox/validate/check.js
index 200b8da..bd515d3 100644
--- a/dojox/validate/check.js
+++ b/dojox/validate/check.js
@@ -1,7 +1,12 @@
-dojo.provide("dojox.validate.check");
-dojo.experimental
-dojo.require("dojox.validate._base");
+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?
 
@@ -69,7 +74,7 @@ dojo.require("dojox.validate._base");
 
 */
 
-dojox.validate.check = function(/*HTMLFormElement*/form, /*Object*/profile){
+validate.check = function(/*HTMLFormElement*/form, /*Object*/profile){
 	// summary: validates user input of an HTML form based on input profile
 	//
 	// description:
@@ -154,7 +159,7 @@ dojox.validate.check = function(/*HTMLFormElement*/form, /*Object*/profile){
 	// See if required input fields have values missing.
 	if(profile.required instanceof Array){
 		for(var i = 0; i < profile.required.length; i++){
-			if(!dojo.isString(profile.required[i])){ continue; }
+			if(!lang.isString(profile.required[i])){ continue; }
 			var elem = form[profile.required[i]];
 			// Are textbox, textarea, or password fields blank.
 			if(!_undef("type", elem)
@@ -184,7 +189,7 @@ dojox.validate.check = function(/*HTMLFormElement*/form, /*Object*/profile){
 	// See if checkbox groups and select boxes have x number of required values.
 	if(profile.required instanceof Array){
 		for (var i = 0; i < profile.required.length; i++){
-			if(!dojo.isObject(profile.required[i])){ continue; }
+			if(!lang.isObject(profile.required[i])){ continue; }
 			var elem, numRequired;
 			for(var name in profile.required[i]){
 				elem = form[name];
@@ -217,7 +222,7 @@ dojox.validate.check = function(/*HTMLFormElement*/form, /*Object*/profile){
 	// Todo: Support dependent and target fields that are radio button groups, or select drop-down lists.
 	// Todo: Make the dependency based on a specific value of the target field.
 	// Todo: allow dependent fields to have several required values, like {checkboxgroup: 3}.
-	if(dojo.isObject(profile.dependencies)){
+	if(lang.isObject(profile.dependencies)){
 		// properties of dependencies object are the names of dependent fields to be checked
 		for(name in profile.dependencies){
 			var elem = form[name];	// the dependent element
@@ -233,7 +238,7 @@ dojox.validate.check = function(/*HTMLFormElement*/form, /*Object*/profile){
 	}
 
 	// Find invalid input fields.
-	if(dojo.isObject(profile.constraints)){
+	if(lang.isObject(profile.constraints)){
 		// constraint properties are the names of fields to bevalidated
 		for(name in profile.constraints){
 			var elem = form[name];
@@ -250,20 +255,20 @@ dojox.validate.check = function(/*HTMLFormElement*/form, /*Object*/profile){
 			
 			var isValid = true;
 			// case 1: constraint value is validation function
-			if(dojo.isFunction(profile.constraints[name])){
+			if(lang.isFunction(profile.constraints[name])){
 				isValid = profile.constraints[name](elem.value);
-			}else if(dojo.isArray(profile.constraints[name])){
+			}else if(lang.isArray(profile.constraints[name])){
 				
 				// handle nested arrays for multiple constraints
-				if(dojo.isArray(profile.constraints[name][0])){
+				if(lang.isArray(profile.constraints[name][0])){
 					for (var i=0; i<profile.constraints[name].length; i++){
-						isValid = dojox.validate.evaluateConstraint(profile, profile.constraints[name][i], name, elem);
+						isValid = validate.evaluateConstraint(profile, profile.constraints[name][i], name, elem);
 						if(!isValid){ break; }
 					}
 				}else{
 					// case 2: constraint value is array, first elem is function,
 					// tail is parameters
-					isValid = dojox.validate.evaluateConstraint(profile, profile.constraints[name], name, elem);
+					isValid = validate.evaluateConstraint(profile, profile.constraints[name], name, elem);
 				}
 			}
 			
@@ -274,7 +279,7 @@ dojox.validate.check = function(/*HTMLFormElement*/form, /*Object*/profile){
 	}
 
 	// Find unequal confirm fields and report them as Invalid.
-	if(dojo.isObject(profile.confirm)){
+	if(lang.isObject(profile.confirm)){
 		for(name in profile.confirm){
 			var elem = form[name];	// the confirm element
 			var target = form[profile.confirm[name]];
@@ -293,7 +298,7 @@ dojox.validate.check = function(/*HTMLFormElement*/form, /*Object*/profile){
 };
 
 //TODO: evaluateConstraint doesn't use profile or fieldName args?
-dojox.validate.evaluateConstraint=function(profile, /*Array*/constraint, fieldName, elem){
+validate.evaluateConstraint=function(profile, /*Array*/constraint, fieldName, elem){
 	// summary:
 	//	Evaluates dojo.validate.check() constraints that are specified as array
 	//	arguments
@@ -321,4 +326,7 @@ dojox.validate.evaluateConstraint=function(profile, /*Array*/constraint, fieldNa
 		return isValidSomething.apply(null, params);
 	}
 	return false; // Boolean
-}
+};
+
+return validate.check;
+});
diff --git a/dojox/validate/creditCard.js b/dojox/validate/creditCard.js
index 1709ada..b979c27 100644
--- a/dojox/validate/creditCard.js
+++ b/dojox/validate/creditCard.js
@@ -1,4 +1,4 @@
-dojo.provide("dojox.validate.creditCard");
+define(["dojo/_base/lang", "./_base"], function(lang, validate){
 /*=====
 
 	dojox.validate.creditCard = {
@@ -6,11 +6,12 @@ dojo.provide("dojox.validate.creditCard");
 		//		Module provides validation functions for Credit Cards, using account number
 		//		rules in conjunction with the Luhn algorigthm, with a plugable card info database.
 	};
-	
+
+	validate = dojox.validate;
+
 =====*/
-dojo.require("dojox.validate._base");
 
-dojox.validate._cardInfo = {
+validate._cardInfo = {
 	// summary: A dictionary list of credit card abbreviations
 	//
 	// description:
@@ -43,9 +44,9 @@ dojox.validate._cardInfo = {
 	'di':'6011[0-9]{12}',
 	'jcb':'(?:3[0-9]{15}|(2131|1800)[0-9]{11})',
 	'er':'2(?:014|149)[0-9]{11}'
-}
+};
 
-dojox.validate.isValidCreditCard = function(value, ccType){
+validate.isValidCreditCard = function(value, ccType){
 	// summary: Validate a credit card number by type with Luhn checking.
 	//
 	// description:
@@ -64,11 +65,11 @@ dojox.validate.isValidCreditCard = function(value, ccType){
 	// |		console.log('inconceivable');
 	// |	}
 	
-	return ((ccType.toLowerCase() == 'er' || dojox.validate.isValidLuhn(value)) &&
-			dojox.validate.isValidCreditCardNumber(value, ccType.toLowerCase())); // Boolean
-}
+	return ((ccType.toLowerCase() == 'er' || validate.isValidLuhn(value)) &&
+			validate.isValidCreditCardNumber(value, ccType.toLowerCase())); // Boolean
+};
 
-dojox.validate.isValidCreditCardNumber = 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
 	//
@@ -82,7 +83,7 @@ dojox.validate.isValidCreditCardNumber = function(value, ccType){
 
 	value = String(value).replace(/[- ]/g,''); //ignore dashes and whitespaces
 
-	var cardinfo = dojox.validate._cardInfo, results = [];
+	var cardinfo = validate._cardInfo, results = [];
 	if(ccType){
 		var expr = '^' + cardinfo[ccType.toLowerCase()] + '$';
 		return expr ? !!value.match(expr) : false; // boolean
@@ -94,9 +95,9 @@ dojox.validate.isValidCreditCardNumber = function(value, ccType){
 		}
 	}
 	return results.length ? results.join('|') : false; // String | boolean
-}
+};
 
-dojox.validate.isValidCvv = function(/* String|Int */value, /* String */ccType) {
+validate.isValidCvv = function(/* String|Int */value, /* String */ccType) {
 	// summary:
 	//  	Validate the security code (CCV) for a passed credit-card type.
 	//
@@ -104,7 +105,7 @@ dojox.validate.isValidCvv = function(/* String|Int */value, /* String */ccType)
 	//
 	// value:
 	
-	if(!dojo.isString(value)){
+	if(!lang.isString(value)){
 		value = String(value);
 	}
 	var format;
@@ -120,5 +121,8 @@ dojox.validate.isValidCvv = function(/* String|Int */value, /* String */ccType)
 			break;
 	}
 	
-	return !!format && value.length && dojox.validate.isNumberFormat(value, { format: format }); // Boolean
-}
+	return !!format && value.length && validate.isNumberFormat(value, { format: format }); // Boolean
+};
+
+return validate;
+});
diff --git a/dojox/validate/isbn.js b/dojox/validate/isbn.js
index 46e62ae..9553f9b 100644
--- a/dojox/validate/isbn.js
+++ b/dojox/validate/isbn.js
@@ -1,13 +1,20 @@
-dojo.provide("dojox.validate.isbn");
+define(["dojo/_base/lang", "./_base"], function(lang, validate){
 // summary: Provides ISBN validation functions in `dojox.validate`
 //
-dojox.validate.isValidIsbn = function(/* String */value) {
+
+/*=====
+
+	validate = dojox.validate;
+
+=====*/
+
+validate.isValidIsbn = function(/* String */value) {
 	// summary: Validate ISBN-10 or ISBN-13 based on the length of value
 	// value: String
 	//		An ISBN to validate
 	// returns: Boolean
 	var len, sum = 0, weight;
-	if(!dojo.isString(value)){
+	if(!lang.isString(value)){
 		value = String(value);
 	}
 	value = value.replace(/[- ]/g,''); //ignore dashes and whitespaces
@@ -35,4 +42,7 @@ dojox.validate.isValidIsbn = function(/* String */value) {
 			break;
 	}
 	return false;
-}
+};
+
+return validate.isValidIsbn;
+});
diff --git a/dojox/validate/regexp.js b/dojox/validate/regexp.js
index ebb1f09..4c4fcff 100644
--- a/dojox/validate/regexp.js
+++ b/dojox/validate/regexp.js
@@ -1,8 +1,8 @@
-dojo.provide("dojox.validate.regexp");
+define(["dojo/_base/lang", "dojo/regexp", "dojox/main"], 
+  function(lang, regexp, dojox){
 
-dojo.require("dojo.regexp");
-
-dojo.mixin(dojox.validate.regexp, {
+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
@@ -109,7 +109,7 @@ dojo.mixin(dojox.validate.regexp, {
 
 		// build host RE
 		var hostNameRE = "((?:" + domainLabelRE + "\\.)+" + domainNameRE + "\\.?)";
-		if(flags.allowIP){ hostNameRE += "|" +  dojox.validate.regexp.ipAddress(flags); }
+		if(flags.allowIP){ hostNameRE += "|" +  dxregexp.ipAddress(flags); }
 		if(flags.allowLocal){ hostNameRE += "|localhost"; }
 		if(flags.allowNamed){ hostNameRE += "|^[^-][a-zA-Z0-9_-]*"; }
 		return "(" + hostNameRE + ")" + portRE; // String
@@ -130,14 +130,14 @@ dojo.mixin(dojox.validate.regexp, {
 		if(!("scheme" in flags)){ flags.scheme = [true, false]; }
 
 		// Scheme RE
-		var protocolRE = dojo.regexp.buildGroupRE(flags.scheme,
+		var protocolRE = regexp.buildGroupRE(flags.scheme,
 			function(q){ if(q){ return "(https?|ftps?)\\://"; } return ""; }
 		);
 
 		// Path and query and anchor RE
 		var pathRE = "(/(?:[^?#\\s/]+/)*(?:[^?#\\s/]+(?:\\?[^?#\\s/]*)?(?:#[A-Za-z][\\w.:-]*)?)?)?";
 
-		return protocolRE + dojox.validate.regexp.host(flags) + pathRE;
+		return protocolRE + dxregexp.host(flags) + pathRE;
 	},
 
 	emailAddress: function(/*Object?*/flags){
@@ -158,7 +158,7 @@ dojo.mixin(dojox.validate.regexp, {
 		var usernameRE = "([!#-'*+\\-\\/-9=?A-Z^-~]+[.])*[!#-'*+\\-\\/-9=?A-Z^-~]+";
 
 		// build emailAddress RE
-		var emailAddressRE = usernameRE + "@" + dojox.validate.regexp.host(flags);
+		var emailAddressRE = usernameRE + "@" + dxregexp.host(flags);
 
 		// Allow email addresses with cruft
 		if ( flags.allowCruft ) {
@@ -182,7 +182,7 @@ dojo.mixin(dojox.validate.regexp, {
 		if(typeof flags.listSeparator != "string"){ flags.listSeparator = "\\s;,"; }
 
 		// build a RE for an Email Address List
-		var emailAddressRE = dojox.validate.regexp.emailAddress(flags);
+		var emailAddressRE = dxregexp.emailAddress(flags);
 		var emailAddressListRE = "(" + emailAddressRE + "\\s*[" + flags.listSeparator + "]\\s*)*" +
 			emailAddressRE + "\\s*[" + flags.listSeparator + "]?\\s*";
 
@@ -216,7 +216,7 @@ dojo.mixin(dojox.validate.regexp, {
 		// Converts a number format to RE.
 		var digitRE = function(format){
 			// escape all special characters, except '?'
-			return dojo.regexp.escapeString(format, "?")
+			return regexp.escapeString(format, "?")
 				// Now replace '?' with Regular Expression
 				.replace(/\?/g, "\\d?")
 				// replace # with Regular Expression
@@ -225,56 +225,59 @@ dojo.mixin(dojox.validate.regexp, {
 		};
 
 		// build RE for multiple number formats
-		return dojo.regexp.buildGroupRE(flags.format, digitRE); //String
-	}
+		return regexp.buildGroupRE(flags.format, digitRE); //String
+	},
 	
-});
+	ca: {
 
-dojox.validate.regexp.ca = {
-	
-	postalCode: function(){
-		// summary: String regular Express to match Canadain Postal Codes
-		return "([A-Z][0-9][A-Z] [0-9][A-Z][0-9])";
-	},
+		postalCode: function(){
+			// 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
-		return "(AB|BC|MB|NB|NL|NS|NT|NU|ON|PE|QC|SK|YT)";
-	}
-	
-};
+		province: function(){
+			// summary: a regular expression to match Canadian Province Abbreviations
+			return "(AB|BC|MB|NB|NL|NS|NT|NU|ON|PE|QC|SK|YT)";
+		}
 
-dojox.validate.regexp.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.
+	us:{
 
-		// assign default values to missing paramters
-		flags = (typeof flags == "object") ? flags : {};
-		if(typeof flags.allowTerritories != "boolean"){ flags.allowTerritories = true; }
-		if(typeof flags.allowMilitary != "boolean"){ flags.allowMilitary = true; }
+		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
+			flags = (typeof flags == "object") ? flags : {};
+			if(typeof flags.allowTerritories != "boolean"){ flags.allowTerritories = true; }
+			if(typeof flags.allowMilitary != "boolean"){ flags.allowMilitary = true; }
 
-		// state RE
-		var statesRE =
-			"AL|AK|AZ|AR|CA|CO|CT|DE|DC|FL|GA|HI|ID|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|" +
-			"NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY";
+			// state RE
+			var statesRE =
+				"AL|AK|AZ|AR|CA|CO|CT|DE|DC|FL|GA|HI|ID|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|" +
+				"NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY";
 
-		// territories RE
-		var territoriesRE = "AS|FM|GU|MH|MP|PW|PR|VI";
+			// territories RE
+			var territoriesRE = "AS|FM|GU|MH|MP|PW|PR|VI";
 
-		// military states RE
-		var militaryRE = "AA|AE|AP";
+			// military states RE
+			var militaryRE = "AA|AE|AP";
 
-		// Build states and territories RE
-		if(flags.allowTerritories){ statesRE += "|" + territoriesRE; }
-		if(flags.allowMilitary){ statesRE += "|" + militaryRE; }
+			// Build states and territories RE
+			if(flags.allowTerritories){ statesRE += "|" + territoriesRE; }
+			if(flags.allowMilitary){ statesRE += "|" + militaryRE; }
+
+			return "(" + statesRE + ")"; // String
+		}
 
-		return "(" + statesRE + ")"; // String
 	}
 	
 };
 
+return dxregexp;
+
+});
diff --git a/dojox/validate/tests/br.js b/dojox/validate/tests/br.js
index 4c6815f..cc83c94 100755
--- a/dojox/validate/tests/br.js
+++ b/dojox/validate/tests/br.js
@@ -1,104 +1,104 @@
-dojo.provide("dojox.validate.tests.br");
-dojo.require("dojox.validate.br");
+define(["doh", "../br"], function(doh, br){
 
-
-tests.register("dojox.validate.tests.br",[
+doh.register("dojox.validate.tests.br",[
 	//Randomy generated valid CNJP/CGC numbers.
 	{
 		name:"isValidCnpj",
 		runTest: function(doh) {
-			doh.assertTrue(dojox.validate.br.isValidCnpj('75.730.657/0001-03'), "1 Checking ##.###.###/####-## format");
-			doh.assertTrue(dojox.validate.br.isValidCnpj('75730657/0001-03'), "1 Checking ########/####-## format");
-			doh.assertTrue(dojox.validate.br.isValidCnpj('757306570001-03'), "1 Checking ############-## format");
-			doh.assertTrue(dojox.validate.br.isValidCnpj('75730657000103'), "1 Checking ############## format");
-			doh.assertTrue(dojox.validate.br.isValidCnpj(75730657000103), "1 Checking numeric ############## format");
+			doh.assertTrue(br.isValidCnpj('75.730.657/0001-03'), "1 Checking ##.###.###/####-## format");
+			doh.assertTrue(br.isValidCnpj('75730657/0001-03'), "1 Checking ########/####-## format");
+			doh.assertTrue(br.isValidCnpj('757306570001-03'), "1 Checking ############-## format");
+			doh.assertTrue(br.isValidCnpj('75730657000103'), "1 Checking ############## format");
+			doh.assertTrue(br.isValidCnpj(75730657000103), "1 Checking numeric ############## format");
 
-			doh.assertTrue(dojox.validate.br.isValidCnpj('05.101.993/0001-01'), "2 Checking ##.###.###/####-## format");
-			doh.assertTrue(dojox.validate.br.isValidCnpj('05101993/0001-01'), "2 Checking ########/####-## format");
-			doh.assertTrue(dojox.validate.br.isValidCnpj('051019930001-01'), "2 Checking ############-## format");
-			doh.assertTrue(dojox.validate.br.isValidCnpj('05101993000101'), "2 Checking ############## format");
-			doh.assertTrue(dojox.validate.br.isValidCnpj(5101993000101), "2 Checking numeric ############## format");
+			doh.assertTrue(br.isValidCnpj('05.101.993/0001-01'), "2 Checking ##.###.###/####-## format");
+			doh.assertTrue(br.isValidCnpj('05101993/0001-01'), "2 Checking ########/####-## format");
+			doh.assertTrue(br.isValidCnpj('051019930001-01'), "2 Checking ############-## format");
+			doh.assertTrue(br.isValidCnpj('05101993000101'), "2 Checking ############## format");
+			doh.assertTrue(br.isValidCnpj(5101993000101), "2 Checking numeric ############## format");
 
-			doh.assertTrue(dojox.validate.br.isValidCnpj('79.577.986/0001-17'), "3 Checking ##.###.###/####-## format");
-			doh.assertTrue(dojox.validate.br.isValidCnpj('79577986/0001-17'), "3 Checking ########/####-## format");
-			doh.assertTrue(dojox.validate.br.isValidCnpj('795779860001-17'), "3 Checking ############-## format");
-			doh.assertTrue(dojox.validate.br.isValidCnpj('79577986000117'), "3 Checking ############## format");
-			doh.assertTrue(dojox.validate.br.isValidCnpj(79577986000117), "3 Checking numeric ############## format");
+			doh.assertTrue(br.isValidCnpj('79.577.986/0001-17'), "3 Checking ##.###.###/####-## format");
+			doh.assertTrue(br.isValidCnpj('79577986/0001-17'), "3 Checking ########/####-## format");
+			doh.assertTrue(br.isValidCnpj('795779860001-17'), "3 Checking ############-## format");
+			doh.assertTrue(br.isValidCnpj('79577986000117'), "3 Checking ############## format");
+			doh.assertTrue(br.isValidCnpj(79577986000117), "3 Checking numeric ############## format");
 
-			doh.assertFalse(dojox.validate.br.isValidCnpj('79.577.986/0001-18'), "4 Checking ##.###.###/####-## format");
-			doh.assertFalse(dojox.validate.br.isValidCnpj('79577986/0001-18'), "4 Checking ########/####-## format");
-			doh.assertFalse(dojox.validate.br.isValidCnpj('795779860001-18'), "4 Checking ############-## format");
-			doh.assertFalse(dojox.validate.br.isValidCnpj('79577986000118'), "4 Checking ############## format");
-			doh.assertFalse(dojox.validate.br.isValidCnpj(79577986000118), "4 Checking numeric ############## format");
-			doh.assertFalse(dojox.validate.br.isValidCnpj(0), "5 Checking numeric ############## format");
-			doh.assertFalse(dojox.validate.br.isValidCnpj('00000000000000'), "4 Checking numeric ############## format");
-			doh.assertFalse(dojox.validate.br.isValidCnpj('11111111111111'), "4 Checking numeric ############## format");
-			doh.assertFalse(dojox.validate.br.isValidCnpj('22222222222222'), "4 Checking numeric ############## format");
+			doh.assertFalse(br.isValidCnpj('79.577.986/0001-18'), "4 Checking ##.###.###/####-## format");
+			doh.assertFalse(br.isValidCnpj('79577986/0001-18'), "4 Checking ########/####-## format");
+			doh.assertFalse(br.isValidCnpj('795779860001-18'), "4 Checking ############-## format");
+			doh.assertFalse(br.isValidCnpj('79577986000118'), "4 Checking ############## format");
+			doh.assertFalse(br.isValidCnpj(79577986000118), "4 Checking numeric ############## format");
+			doh.assertFalse(br.isValidCnpj(0), "5 Checking numeric ############## format");
+			doh.assertFalse(br.isValidCnpj('00000000000000'), "4 Checking numeric ############## format");
+			doh.assertFalse(br.isValidCnpj('11111111111111'), "4 Checking numeric ############## format");
+			doh.assertFalse(br.isValidCnpj('22222222222222'), "4 Checking numeric ############## format");
 		}
 	},
 	{
 		name:"computeCnpjDv",
 		runTest: function(doh) {
-			doh.assertEqual("03", dojox.validate.br.computeCnpjDv('75.730.657/0001'), "1 Checking ##.###.###/#### format");
-			doh.assertEqual("03", dojox.validate.br.computeCnpjDv('75730657/0001'), "1 Checking ########/#### format");
-			doh.assertEqual("03", dojox.validate.br.computeCnpjDv('757306570001'), "1 Checking ############ format");
-			doh.assertEqual("03", dojox.validate.br.computeCnpjDv(757306570001), "1 Checking numeric ############ format");
+			doh.assertEqual("03", br.computeCnpjDv('75.730.657/0001'), "1 Checking ##.###.###/#### format");
+			doh.assertEqual("03", br.computeCnpjDv('75730657/0001'), "1 Checking ########/#### format");
+			doh.assertEqual("03", br.computeCnpjDv('757306570001'), "1 Checking ############ format");
+			doh.assertEqual("03", br.computeCnpjDv(757306570001), "1 Checking numeric ############ format");
 
-			doh.assertEqual("01", dojox.validate.br.computeCnpjDv('05.101.993/0001'), "2 Checking ##.###.###/#### format");
-			doh.assertEqual("01", dojox.validate.br.computeCnpjDv('05101993/0001'), "2 Checking ########/#### format");
-			doh.assertEqual("01", dojox.validate.br.computeCnpjDv('051019930001'), "2 Checking ############ format");
-			doh.assertEqual("01", dojox.validate.br.computeCnpjDv(51019930001), "2 Checking numeric ############ format");
+			doh.assertEqual("01", br.computeCnpjDv('05.101.993/0001'), "2 Checking ##.###.###/#### format");
+			doh.assertEqual("01", br.computeCnpjDv('05101993/0001'), "2 Checking ########/#### format");
+			doh.assertEqual("01", br.computeCnpjDv('051019930001'), "2 Checking ############ format");
+			doh.assertEqual("01", br.computeCnpjDv(51019930001), "2 Checking numeric ############ format");
 
-			doh.assertEqual("17", dojox.validate.br.computeCnpjDv('79.577.986/0001'), "3 Checking ##.###.###/#### format");
-			doh.assertEqual("17", dojox.validate.br.computeCnpjDv('79577986/0001'), "3 Checking ########/#### format");
-			doh.assertEqual("17", dojox.validate.br.computeCnpjDv('795779860001'), "3 Checking ############ format");
-			doh.assertEqual("17", dojox.validate.br.computeCnpjDv(795779860001), "3 Checking numeric ############ format");
+			doh.assertEqual("17", br.computeCnpjDv('79.577.986/0001'), "3 Checking ##.###.###/#### format");
+			doh.assertEqual("17", br.computeCnpjDv('79577986/0001'), "3 Checking ########/#### format");
+			doh.assertEqual("17", br.computeCnpjDv('795779860001'), "3 Checking ############ format");
+			doh.assertEqual("17", br.computeCnpjDv(795779860001), "3 Checking numeric ############ format");
 		}
 	},
 	//All CPF numbers randomly generated from: http://www.gerardocumentos.com.br
 	{
 		name:"isValidCpf",
 		runTest: function(doh) {
-			doh.assertTrue(dojox.validate.br.isValidCpf('362.866.226-59'), "1 Checking ###.###.###-## format");
-			doh.assertTrue(dojox.validate.br.isValidCpf('362866226-59'), "1 Checking #########-## format");
-			doh.assertTrue(dojox.validate.br.isValidCpf('36286622659'), "1 Checking ########### format");
-			doh.assertTrue(dojox.validate.br.isValidCpf(36286622659), "1 Checking numeric ########### format");
+			doh.assertTrue(br.isValidCpf('362.866.226-59'), "1 Checking ###.###.###-## format");
+			doh.assertTrue(br.isValidCpf('362866226-59'), "1 Checking #########-## format");
+			doh.assertTrue(br.isValidCpf('36286622659'), "1 Checking ########### format");
+			doh.assertTrue(br.isValidCpf(36286622659), "1 Checking numeric ########### format");
 
-			doh.assertTrue(dojox.validate.br.isValidCpf('781.215.062-39'), "2 Checking ###.###.###-## format");
-			doh.assertTrue(dojox.validate.br.isValidCpf('781215062-39'), "2 Checking #########-## format");
-			doh.assertTrue(dojox.validate.br.isValidCpf('78121506239'), "2 Checking ########### format");
-			doh.assertTrue(dojox.validate.br.isValidCpf(78121506239), "2 Checking numeric ########### format");
+			doh.assertTrue(br.isValidCpf('781.215.062-39'), "2 Checking ###.###.###-## format");
+			doh.assertTrue(br.isValidCpf('781215062-39'), "2 Checking #########-## format");
+			doh.assertTrue(br.isValidCpf('78121506239'), "2 Checking ########### format");
+			doh.assertTrue(br.isValidCpf(78121506239), "2 Checking numeric ########### format");
 
-			doh.assertTrue(dojox.validate.br.isValidCpf('670.832.400-86'), "3 Checking ###.###.###-## format");
-			doh.assertTrue(dojox.validate.br.isValidCpf('670832400-86'), "3 Checking #########-## format");
-			doh.assertTrue(dojox.validate.br.isValidCpf('67083240086'), "3 Checking ########### format");
-			doh.assertTrue(dojox.validate.br.isValidCpf(67083240086), "3 Checking numeric ########### format");
+			doh.assertTrue(br.isValidCpf('670.832.400-86'), "3 Checking ###.###.###-## format");
+			doh.assertTrue(br.isValidCpf('670832400-86'), "3 Checking #########-## format");
+			doh.assertTrue(br.isValidCpf('67083240086'), "3 Checking ########### format");
+			doh.assertTrue(br.isValidCpf(67083240086), "3 Checking numeric ########### format");
 
-			doh.assertTrue(dojox.validate.br.isValidCpf('271.034.755-55'), "4 Checking ###.###.###-## format");
-			doh.assertTrue(dojox.validate.br.isValidCpf('271034755-55'), "4 Checking #########-## format");
-			doh.assertTrue(dojox.validate.br.isValidCpf('27103475555'), "4 Checking ########### format");
-			doh.assertTrue(dojox.validate.br.isValidCpf(27103475555), "4 Checking numeric ########### format");
+			doh.assertTrue(br.isValidCpf('271.034.755-55'), "4 Checking ###.###.###-## format");
+			doh.assertTrue(br.isValidCpf('271034755-55'), "4 Checking #########-## format");
+			doh.assertTrue(br.isValidCpf('27103475555'), "4 Checking ########### format");
+			doh.assertTrue(br.isValidCpf(27103475555), "4 Checking numeric ########### format");
 		}
 	},
 	{
 		name:"computeCpfDv",
 		runTest: function(doh) {
-			doh.assertEqual("59", dojox.validate.br.computeCpfDv('362.866.226'), "1 Checking ###.###.### format");
-			doh.assertEqual("59", dojox.validate.br.computeCpfDv('362866226'), "1 Checking ######### format");
-			doh.assertEqual("59", dojox.validate.br.computeCpfDv(362866226), "1 Checking numeric ######### format");
+			doh.assertEqual("59", br.computeCpfDv('362.866.226'), "1 Checking ###.###.### format");
+			doh.assertEqual("59", br.computeCpfDv('362866226'), "1 Checking ######### format");
+			doh.assertEqual("59", br.computeCpfDv(362866226), "1 Checking numeric ######### format");
 
-			doh.assertEqual("39", dojox.validate.br.computeCpfDv('781.215.062'), "2 Checking ###.###.### format");
-			doh.assertEqual("39", dojox.validate.br.computeCpfDv('781215062'), "2 Checking ######### format");
-			doh.assertEqual("39", dojox.validate.br.computeCpfDv(781215062), "2 Checking numeric ######### format");
+			doh.assertEqual("39", br.computeCpfDv('781.215.062'), "2 Checking ###.###.### format");
+			doh.assertEqual("39", br.computeCpfDv('781215062'), "2 Checking ######### format");
+			doh.assertEqual("39", br.computeCpfDv(781215062), "2 Checking numeric ######### format");
 
-			doh.assertEqual("86", dojox.validate.br.computeCpfDv('670.832.400'), "3 Checking ###.###.### format");
-			doh.assertEqual("86", dojox.validate.br.computeCpfDv('670832400'), "3 Checking ######### format");
-			doh.assertEqual("86", dojox.validate.br.computeCpfDv(670832400), "3 Checking numeric ######### format");
+			doh.assertEqual("86", br.computeCpfDv('670.832.400'), "3 Checking ###.###.### format");
+			doh.assertEqual("86", br.computeCpfDv('670832400'), "3 Checking ######### format");
+			doh.assertEqual("86", br.computeCpfDv(670832400), "3 Checking numeric ######### format");
 
-			doh.assertEqual("55", dojox.validate.br.computeCpfDv('271.034.755'), "4 Checking ###.###.### format");
-			doh.assertEqual("55", dojox.validate.br.computeCpfDv('271034755'), "4 Checking ######### format");
-			doh.assertEqual("55", dojox.validate.br.computeCpfDv(271034755), "4 Checking numeric ######### format");
+			doh.assertEqual("55", br.computeCpfDv('271.034.755'), "4 Checking ###.###.### format");
+			doh.assertEqual("55", br.computeCpfDv('271034755'), "4 Checking ######### format");
+			doh.assertEqual("55", br.computeCpfDv(271034755), "4 Checking numeric ######### format");
 
 		}
 	}
 ]);
+
+});
diff --git a/dojox/validate/tests/creditcard.js b/dojox/validate/tests/creditcard.js
index d957928..a81a9c6 100644
--- a/dojox/validate/tests/creditcard.js
+++ b/dojox/validate/tests/creditcard.js
@@ -1,115 +1,116 @@
-dojo.provide("dojox.validate.tests.creditcard");
-dojo.require("dojox.validate.creditCard");
+define(["doh", "../creditCard"], function(doh, validate){
 
-tests.register("dojox.validate.tests.creditcard",
+doh.register("dojox.validate.tests.creditcard",
 	[{
 		name:"isValidLuhn",
 		runTest: function(tests) {
-			tests.t(dojox.validate.isValidLuhn('5105105105105100')); //test string input
-			tests.t(dojox.validate.isValidLuhn('5105-1051 0510-5100')); //test string input with dashes and spaces (commonly used when entering card #'s)
-			tests.t(dojox.validate.isValidLuhn(38520000023237)); //test numerical input as well
-			tests.f(dojox.validate.isValidLuhn(3852000002323)); //testing failures
-			tests.t(dojox.validate.isValidLuhn(18)); //length doesnt matter
-			tests.f(dojox.validate.isValidLuhn(818181)); //short length failure
+			tests.t(validate.isValidLuhn('5105105105105100')); //test string input
+			tests.t(validate.isValidLuhn('5105-1051 0510-5100')); //test string input with dashes and spaces (commonly used when entering card #'s)
+			tests.t(validate.isValidLuhn(38520000023237)); //test numerical input as well
+			tests.f(validate.isValidLuhn(3852000002323)); //testing failures
+			tests.t(validate.isValidLuhn(18)); //length doesnt matter
+			tests.f(validate.isValidLuhn(818181)); //short length failure
 		}
 	},
 	{
 		name:"isValidCvv",
 		runTest: function(tests) {
-			tests.t(dojox.validate.isValidCvv('123','mc')); //string is ok
-			tests.f(dojox.validate.isValidCvv('5AA','ec')); //invalid characters are not ok
-			tests.t(dojox.validate.isValidCvv(723,'mc')); //numbers are ok too
-			tests.f(dojox.validate.isValidCvv(7234,'mc')); //too long
-			tests.t(dojox.validate.isValidCvv(612,'ec'));
-			tests.t(dojox.validate.isValidCvv(421,'vi'));
-			tests.t(dojox.validate.isValidCvv(543,'di'));
-			tests.t(dojox.validate.isValidCvv('1234','ax'));
-			tests.t(dojox.validate.isValidCvv(4321,'ax'));
-			tests.f(dojox.validate.isValidCvv(43215,'ax')); //too long
-			tests.f(dojox.validate.isValidCvv(215,'ax')); //too short
+			tests.t(validate.isValidCvv('123','mc')); //string is ok
+			tests.f(validate.isValidCvv('5AA','ec')); //invalid characters are not ok
+			tests.t(validate.isValidCvv(723,'mc')); //numbers are ok too
+			tests.f(validate.isValidCvv(7234,'mc')); //too long
+			tests.t(validate.isValidCvv(612,'ec'));
+			tests.t(validate.isValidCvv(421,'vi'));
+			tests.t(validate.isValidCvv(543,'di'));
+			tests.t(validate.isValidCvv('1234','ax'));
+			tests.t(validate.isValidCvv(4321,'ax'));
+			tests.f(validate.isValidCvv(43215,'ax')); //too long
+			tests.f(validate.isValidCvv(215,'ax')); //too short
 		}
 	},
 	{
 		name:"isValidCreditCard",
 		runTest: function(tests) {
 			//misc checks
-			tests.t(dojox.validate.isValidCreditCard('5105105105105100','mc')); //test string input
-			tests.t(dojox.validate.isValidCreditCard('5105-1051 0510-5100','mc')); //test string input with dashes and spaces (commonly used when entering card #'s)
-			tests.t(dojox.validate.isValidCreditCard(5105105105105100,'mc')); //test numerical input as well
-			tests.f(dojox.validate.isValidCreditCard('5105105105105100','vi')); //fails, wrong card type
+			tests.t(validate.isValidCreditCard('5105105105105100','mc')); //test string input
+			tests.t(validate.isValidCreditCard('5105-1051 0510-5100','mc')); //test string input with dashes and spaces (commonly used when entering card #'s)
+			tests.t(validate.isValidCreditCard(5105105105105100,'mc')); //test numerical input as well
+			tests.f(validate.isValidCreditCard('5105105105105100','vi')); //fails, wrong card type
 			//Mastercard/Eurocard checks
-			tests.t(dojox.validate.isValidCreditCard('5105105105105100','mc'));
-			tests.t(dojox.validate.isValidCreditCard('5204105105105100','ec'));
-			tests.t(dojox.validate.isValidCreditCard('5303105105105100','mc'));
-			tests.t(dojox.validate.isValidCreditCard('5402105105105100','ec'));
-			tests.t(dojox.validate.isValidCreditCard('5501105105105100','mc'));
+			tests.t(validate.isValidCreditCard('5105105105105100','mc'));
+			tests.t(validate.isValidCreditCard('5204105105105100','ec'));
+			tests.t(validate.isValidCreditCard('5303105105105100','mc'));
+			tests.t(validate.isValidCreditCard('5402105105105100','ec'));
+			tests.t(validate.isValidCreditCard('5501105105105100','mc'));
 			//Visa card checks
-			tests.t(dojox.validate.isValidCreditCard('4111111111111111','vi'));
-			tests.t(dojox.validate.isValidCreditCard('4111111111010','vi'));
+			tests.t(validate.isValidCreditCard('4111111111111111','vi'));
+			tests.t(validate.isValidCreditCard('4111111111010','vi'));
 			//American Express card checks
-			tests.t(dojox.validate.isValidCreditCard('378 2822 4631 0005','ax'));
-			tests.t(dojox.validate.isValidCreditCard('341-1111-1111-1111','ax'));
+			tests.t(validate.isValidCreditCard('378 2822 4631 0005','ax'));
+			tests.t(validate.isValidCreditCard('341-1111-1111-1111','ax'));
 			//Diners Club/Carte Blanch card checks
-			tests.t(dojox.validate.isValidCreditCard('36400000000000','dc'));
-			tests.t(dojox.validate.isValidCreditCard('38520000023237','bl'));
-			tests.t(dojox.validate.isValidCreditCard('30009009025904','dc'));
-			tests.t(dojox.validate.isValidCreditCard('30108009025904','bl'));
-			tests.t(dojox.validate.isValidCreditCard('30207009025904','dc'));
-			tests.t(dojox.validate.isValidCreditCard('30306009025904','bl'));
-			tests.t(dojox.validate.isValidCreditCard('30405009025904','dc'));
-			tests.t(dojox.validate.isValidCreditCard('30504009025904','bl'));
+			tests.t(validate.isValidCreditCard('36400000000000','dc'));
+			tests.t(validate.isValidCreditCard('38520000023237','bl'));
+			tests.t(validate.isValidCreditCard('30009009025904','dc'));
+			tests.t(validate.isValidCreditCard('30108009025904','bl'));
+			tests.t(validate.isValidCreditCard('30207009025904','dc'));
+			tests.t(validate.isValidCreditCard('30306009025904','bl'));
+			tests.t(validate.isValidCreditCard('30405009025904','dc'));
+			tests.t(validate.isValidCreditCard('30504009025904','bl'));
 			//Discover card checks
-			tests.t(dojox.validate.isValidCreditCard('6011111111111117','di'));
+			tests.t(validate.isValidCreditCard('6011111111111117','di'));
 			//JCB card checks
-			tests.t(dojox.validate.isValidCreditCard('3530111333300000','jcb'));
-			tests.t(dojox.validate.isValidCreditCard('213100000000001','jcb'));
-			tests.t(dojox.validate.isValidCreditCard('180000000000002','jcb'));
-			tests.f(dojox.validate.isValidCreditCard('1800000000000002','jcb')); //should fail, good checksum, good prefix, but wrong length'
+			tests.t(validate.isValidCreditCard('3530111333300000','jcb'));
+			tests.t(validate.isValidCreditCard('213100000000001','jcb'));
+			tests.t(validate.isValidCreditCard('180000000000002','jcb'));
+			tests.f(validate.isValidCreditCard('1800000000000002','jcb')); //should fail, good checksum, good prefix, but wrong length'
 			//Enroute card checks
-			tests.t(dojox.validate.isValidCreditCard('201400000000000','er'));
-			tests.t(dojox.validate.isValidCreditCard('214900000000000','er'));
+			tests.t(validate.isValidCreditCard('201400000000000','er'));
+			tests.t(validate.isValidCreditCard('214900000000000','er'));
 		}
 	},
 	{
 		name:"isValidCreditCardNumber",
 		runTest: function(tests) {
 			//misc checks
-			tests.t(dojox.validate.isValidCreditCardNumber('5105105105105100','mc')); //test string input
-			tests.t(dojox.validate.isValidCreditCardNumber('5105-1051 0510-5100','mc')); //test string input with dashes and spaces (commonly used when entering card #'s)
-			tests.t(dojox.validate.isValidCreditCardNumber(5105105105105100,'mc')); //test numerical input as well
-			tests.f(dojox.validate.isValidCreditCardNumber('5105105105105100','vi')); //fails, wrong card type
+			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
+			tests.f(validate.isValidCreditCardNumber('5105105105105100','vi')); //fails, wrong card type
 			//Mastercard/Eurocard checks
-			tests.is("mc|ec", dojox.validate.isValidCreditCardNumber('5100000000000000')); //should match 'mc|ec'
-			tests.is("mc|ec", dojox.validate.isValidCreditCardNumber('5200000000000000')); //should match 'mc|ec'
-			tests.is("mc|ec", dojox.validate.isValidCreditCardNumber('5300000000000000')); //should match 'mc|ec'
-			tests.is("mc|ec", dojox.validate.isValidCreditCardNumber('5400000000000000')); //should match 'mc|ec'
-			tests.is("mc|ec", dojox.validate.isValidCreditCardNumber('5500000000000000')); //should match 'mc|ec'
-			tests.f(dojox.validate.isValidCreditCardNumber('55000000000000000')); //should fail, too long
+			tests.is("mc|ec", validate.isValidCreditCardNumber('5100000000000000')); //should match 'mc|ec'
+			tests.is("mc|ec", validate.isValidCreditCardNumber('5200000000000000')); //should match 'mc|ec'
+			tests.is("mc|ec", validate.isValidCreditCardNumber('5300000000000000')); //should match 'mc|ec'
+			tests.is("mc|ec", validate.isValidCreditCardNumber('5400000000000000')); //should match 'mc|ec'
+			tests.is("mc|ec", validate.isValidCreditCardNumber('5500000000000000')); //should match 'mc|ec'
+			tests.f(validate.isValidCreditCardNumber('55000000000000000')); //should fail, too long
 			//Visa card checks
-			tests.is("vi", dojox.validate.isValidCreditCardNumber('4111111111111111')); //should match 'vi'
-			tests.is("vi", dojox.validate.isValidCreditCardNumber('4111111111010')); //should match 'vi'
+			tests.is("vi", validate.isValidCreditCardNumber('4111111111111111')); //should match 'vi'
+			tests.is("vi", validate.isValidCreditCardNumber('4111111111010')); //should match 'vi'
 			//American Express card checks
-			tests.is("ax", dojox.validate.isValidCreditCardNumber('378 2822 4631 0005')); //should match 'ax'
-			tests.is("ax", dojox.validate.isValidCreditCardNumber('341-1111-1111-1111')); //should match 'ax'
+			tests.is("ax", validate.isValidCreditCardNumber('378 2822 4631 0005')); //should match 'ax'
+			tests.is("ax", validate.isValidCreditCardNumber('341-1111-1111-1111')); //should match 'ax'
 			//Diners Club/Carte Blanch card checks
-			tests.is("dc|bl", dojox.validate.isValidCreditCardNumber('36400000000000')); //should match 'dc|bl'
-			tests.is("dc|bl", dojox.validate.isValidCreditCardNumber('38520000023237')); //should match 'dc|bl'
-			tests.is("dc|bl", dojox.validate.isValidCreditCardNumber('30009009025904')); //should match 'di|bl'
-			tests.is("dc|bl", dojox.validate.isValidCreditCardNumber('30108009025904')); //should match 'di|bl'
-			tests.is("dc|bl", dojox.validate.isValidCreditCardNumber('30207009025904')); //should match 'di|bl'
-			tests.is("dc|bl", dojox.validate.isValidCreditCardNumber('30306009025904')); //should match 'di|bl'
-			tests.is("dc|bl", dojox.validate.isValidCreditCardNumber('30405009025904')); //should match 'di|bl'
-			tests.is("dc|bl", dojox.validate.isValidCreditCardNumber('30504009025904')); //should match 'di|bl'
+			tests.is("dc|bl", validate.isValidCreditCardNumber('36400000000000')); //should match 'dc|bl'
+			tests.is("dc|bl", validate.isValidCreditCardNumber('38520000023237')); //should match 'dc|bl'
+			tests.is("dc|bl", validate.isValidCreditCardNumber('30009009025904')); //should match 'di|bl'
+			tests.is("dc|bl", validate.isValidCreditCardNumber('30108009025904')); //should match 'di|bl'
+			tests.is("dc|bl", validate.isValidCreditCardNumber('30207009025904')); //should match 'di|bl'
+			tests.is("dc|bl", validate.isValidCreditCardNumber('30306009025904')); //should match 'di|bl'
+			tests.is("dc|bl", validate.isValidCreditCardNumber('30405009025904')); //should match 'di|bl'
+			tests.is("dc|bl", validate.isValidCreditCardNumber('30504009025904')); //should match 'di|bl'
 			//Discover card checks
-			tests.is("di", dojox.validate.isValidCreditCardNumber('6011111111111117')); //should match 'di'
+			tests.is("di", validate.isValidCreditCardNumber('6011111111111117')); //should match 'di'
 			//JCB card checks
-			tests.is("jcb", dojox.validate.isValidCreditCardNumber('3530111333300000')); //should match 'jcb'
-			tests.is("jcb", dojox.validate.isValidCreditCardNumber('213100000000001')); //should match 'jcb'
-			tests.is("jcb", dojox.validate.isValidCreditCardNumber('180000000000002')); //should match 'jcb'
-			tests.f(dojox.validate.isValidCreditCardNumber('1800000000000002')); //should fail, good checksum, good prefix, but wrong length'
+			tests.is("jcb", validate.isValidCreditCardNumber('3530111333300000')); //should match 'jcb'
+			tests.is("jcb", validate.isValidCreditCardNumber('213100000000001')); //should match 'jcb'
+			tests.is("jcb", validate.isValidCreditCardNumber('180000000000002')); //should match 'jcb'
+			tests.f(validate.isValidCreditCardNumber('1800000000000002')); //should fail, good checksum, good prefix, but wrong length'
 			//Enroute card checks
-			tests.is("er", dojox.validate.isValidCreditCardNumber('201400000000000')); //should match 'er'
-			tests.is("er", dojox.validate.isValidCreditCardNumber('214900000000000')); //should match 'er'
+			tests.is("er", validate.isValidCreditCardNumber('201400000000000')); //should match 'er'
+			tests.is("er", validate.isValidCreditCardNumber('214900000000000')); //should match 'er'
 		}
 	}
 ]);
+
+});
diff --git a/dojox/validate/tests/module.js b/dojox/validate/tests/module.js
index c58145c..3046f66 100644
--- a/dojox/validate/tests/module.js
+++ b/dojox/validate/tests/module.js
@@ -1,11 +1,5 @@
-dojo.provide("dojox.validate.tests.module");
-
-try{
-	dojo.require("dojox.validate.tests.creditcard");
-	dojo.require("dojox.validate.tests.validate");
-	dojo.require("dojox.validate.tests.br");
-
-}catch(e){
-	doh.debug(e);
-	console.debug(e);
-}
+define([
+	"./creditcard",
+	"./validate",
+	"./br"
+],1);
diff --git a/dojox/validate/tests/validate.js b/dojox/validate/tests/validate.js
index 44148e2..ec91fea 100644
--- a/dojox/validate/tests/validate.js
+++ b/dojox/validate/tests/validate.js
@@ -1,13 +1,6 @@
-dojo.provide("dojox.validate.tests.validate");
+define(["doh", "../_base", "../check", "../us", "../ca", "../isbn", "../web"], function(doh, validate, check, us, ca, isbn){
 
-dojo.require("dojox.validate._base");
-dojo.require("dojox.validate.check");
-dojo.require("dojox.validate.us");
-dojo.require("dojox.validate.ca");
-dojo.require("dojox.validate.web");
-dojo.require("dojox.validate.isbn");
-
-tests.register("dojox.validate.tests.validate",
+doh.register("dojox.validate.tests.validate",
 	[{
 		name: "isText",
 
@@ -20,93 +13,93 @@ tests.register("dojox.validate.tests.validate",
 		},
 
 		runTest: function(tests){
-			tests.t(dojox.validate.isValidIsbn('0596007590')); //test string input
-			tests.t(dojox.validate.isValidIsbn('0-596-00759-0')); //test string input with dashes
-			tests.f(dojox.validate.isValidIsbn(596007590)); //test numerical input as well
-			tests.t(dojox.validate.isValidIsbn("960-425-059-0"));
-			tests.t(dojox.validate.isValidIsbn(9604250590)); //test numerical input as well
-			tests.t(dojox.validate.isValidIsbn('0-9752298-0-X')); // test string with X
-			tests.t(dojox.validate.isValidIsbn('0-9752298-0-x'));
-			tests.t(dojox.validate.isValidIsbn('097522980x'));
-			tests.t(dojox.validate.isValidIsbn('097522980X'));
-			tests.f(dojox.validate.isValidIsbn(596007598)); //testing failures
-			tests.f(dojox.validate.isValidIsbn('059-600759-X')); //testing failures
-			tests.f(dojox.validate.isValidIsbn('059600')); // too short
+			tests.t(isbn('0596007590')); //test string input
+			tests.t(isbn('0-596-00759-0')); //test string input with dashes
+			tests.f(isbn(596007590)); //test numerical input as well
+			tests.t(isbn("960-425-059-0"));
+			tests.t(isbn(9604250590)); //test numerical input as well
+			tests.t(isbn('0-9752298-0-X')); // test string with X
+			tests.t(isbn('0-9752298-0-x'));
+			tests.t(isbn('097522980x'));
+			tests.t(isbn('097522980X'));
+			tests.f(isbn(596007598)); //testing failures
+			tests.f(isbn('059-600759-X')); //testing failures
+			tests.f(isbn('059600')); // too short
 
-			tests.t(dojox.validate.isValidIsbn('9780596007591'));
-			tests.t(dojox.validate.isValidIsbn('978-0-596 00759-1'));
-			tests.t(dojox.validate.isValidIsbn(9780596007591));
-			tests.f(dojox.validate.isValidIsbn('978059600759X'));
-			tests.f(dojox.validate.isValidIsbn('978-3250-596 00759-1 '));
-			tests.f(dojox.validate.isValidIsbn('3250-596 00759 '));
+			tests.t(isbn('9780596007591'));
+			tests.t(isbn('978-0-596 00759-1'));
+			tests.t(isbn(9780596007591));
+			tests.f(isbn('978059600759X'));
+			tests.f(isbn('978-3250-596 00759-1 '));
+			tests.f(isbn('3250-596 00759 '));
 
-			tests.t(dojox.validate.isText('            x'));
-			tests.t(dojox.validate.isText('x             '));
-			tests.t(dojox.validate.isText('        x     '));
-			tests.f(dojox.validate.isText('   '));
-			tests.f(dojox.validate.isText(''));
+			tests.t(validate.isText('            x'));
+			tests.t(validate.isText('x             '));
+			tests.t(validate.isText('        x     '));
+			tests.f(validate.isText('   '));
+			tests.f(validate.isText(''));
 		
 			// test lengths
-			tests.t(dojox.validate.isText('123456', {length: 6} ));
-			tests.f(dojox.validate.isText('1234567', {length: 6} ));
-			tests.t(dojox.validate.isText('1234567', {minlength: 6} ));
-			tests.t(dojox.validate.isText('123456', {minlength: 6} ));
-			tests.f(dojox.validate.isText('12345', {minlength: 6} ));
-			tests.f(dojox.validate.isText('1234567', {maxlength: 6} ));
-			tests.t(dojox.validate.isText('123456', {maxlength: 6} ));
+			tests.t(validate.isText('123456', {length: 6} ));
+			tests.f(validate.isText('1234567', {length: 6} ));
+			tests.t(validate.isText('1234567', {minlength: 6} ));
+			tests.t(validate.isText('123456', {minlength: 6} ));
+			tests.f(validate.isText('12345', {minlength: 6} ));
+			tests.f(validate.isText('1234567', {maxlength: 6} ));
+			tests.t(validate.isText('123456', {maxlength: 6} ));
 		}
 	},
 	{
 		name: "isIpAddress",
 		runTest: function(tests){
-			tests.t(dojox.validate.isIpAddress('24.17.155.40'));
-			tests.f(dojox.validate.isIpAddress('024.17.155.040'));
-			tests.t(dojox.validate.isIpAddress('255.255.255.255'));
-			tests.f(dojox.validate.isIpAddress('256.255.255.255'));
-			tests.f(dojox.validate.isIpAddress('255.256.255.255'));
-			tests.f(dojox.validate.isIpAddress('255.255.256.255'));
-			tests.f(dojox.validate.isIpAddress('255.255.255.256'));
+			tests.t(validate.isIpAddress('24.17.155.40'));
+			tests.f(validate.isIpAddress('024.17.155.040'));
+			tests.t(validate.isIpAddress('255.255.255.255'));
+			tests.f(validate.isIpAddress('256.255.255.255'));
+			tests.f(validate.isIpAddress('255.256.255.255'));
+			tests.f(validate.isIpAddress('255.255.256.255'));
+			tests.f(validate.isIpAddress('255.255.255.256'));
 
 			// test dotted hex
-			tests.t(dojox.validate.isIpAddress('0x18.0x11.0x9b.0x28'));
-			tests.f(dojox.validate.isIpAddress('0x18.0x11.0x9b.0x28', {allowDottedHex: false}) );
-			tests.t(dojox.validate.isIpAddress('0x18.0x000000011.0x9b.0x28'));
-			tests.t(dojox.validate.isIpAddress('0xff.0xff.0xff.0xff'));
-			tests.f(dojox.validate.isIpAddress('0x100.0xff.0xff.0xff'));
+			tests.t(validate.isIpAddress('0x18.0x11.0x9b.0x28'));
+			tests.f(validate.isIpAddress('0x18.0x11.0x9b.0x28', {allowDottedHex: false}) );
+			tests.t(validate.isIpAddress('0x18.0x000000011.0x9b.0x28'));
+			tests.t(validate.isIpAddress('0xff.0xff.0xff.0xff'));
+			tests.f(validate.isIpAddress('0x100.0xff.0xff.0xff'));
 
 			// test dotted octal
-			tests.t(dojox.validate.isIpAddress('0030.0021.0233.0050'));
-			tests.f(dojox.validate.isIpAddress('0030.0021.0233.0050', {allowDottedOctal: false}) );
-			tests.t(dojox.validate.isIpAddress('0030.0000021.0233.00000050'));
-			tests.t(dojox.validate.isIpAddress('0377.0377.0377.0377'));
-			tests.f(dojox.validate.isIpAddress('0400.0377.0377.0377'));
-			tests.f(dojox.validate.isIpAddress('0377.0378.0377.0377'));
-			tests.f(dojox.validate.isIpAddress('0377.0377.0380.0377'));
-			tests.f(dojox.validate.isIpAddress('0377.0377.0377.377'));
+			tests.t(validate.isIpAddress('0030.0021.0233.0050'));
+			tests.f(validate.isIpAddress('0030.0021.0233.0050', {allowDottedOctal: false}) );
+			tests.t(validate.isIpAddress('0030.0000021.0233.00000050'));
+			tests.t(validate.isIpAddress('0377.0377.0377.0377'));
+			tests.f(validate.isIpAddress('0400.0377.0377.0377'));
+			tests.f(validate.isIpAddress('0377.0378.0377.0377'));
+			tests.f(validate.isIpAddress('0377.0377.0380.0377'));
+			tests.f(validate.isIpAddress('0377.0377.0377.377'));
 		
 			// test decimal
-			tests.t(dojox.validate.isIpAddress('3482223595'));
-			tests.t(dojox.validate.isIpAddress('0'));
-			tests.t(dojox.validate.isIpAddress('4294967295'));
-			tests.f(dojox.validate.isIpAddress('4294967296'));
-			tests.f(dojox.validate.isIpAddress('3482223595', {allowDecimal: false}));
+			tests.t(validate.isIpAddress('3482223595'));
+			tests.t(validate.isIpAddress('0'));
+			tests.t(validate.isIpAddress('4294967295'));
+			tests.f(validate.isIpAddress('4294967296'));
+			tests.f(validate.isIpAddress('3482223595', {allowDecimal: false}));
 		
 			// test hex
-			tests.t(dojox.validate.isIpAddress('0xCF8E83EB'));
-			tests.t(dojox.validate.isIpAddress('0x0'));
-			tests.t(dojox.validate.isIpAddress('0x00ffffffff'));
-			tests.f(dojox.validate.isIpAddress('0x100000000'));
-			tests.f(dojox.validate.isIpAddress('0xCF8E83EB', {allowHex: false}));
+			tests.t(validate.isIpAddress('0xCF8E83EB'));
+			tests.t(validate.isIpAddress('0x0'));
+			tests.t(validate.isIpAddress('0x00ffffffff'));
+			tests.f(validate.isIpAddress('0x100000000'));
+			tests.f(validate.isIpAddress('0xCF8E83EB', {allowHex: false}));
 			
 			// IPv6
-			tests.t(dojox.validate.isIpAddress('fedc:BA98:7654:3210:FEDC:BA98:7654:3210'));
-			tests.t(dojox.validate.isIpAddress('1080:0:0:0:8:800:200C:417A'));
-			tests.f(dojox.validate.isIpAddress('1080:0:0:0:8:800:200C:417A', {allowIPv6: false}));
+			tests.t(validate.isIpAddress('fedc:BA98:7654:3210:FEDC:BA98:7654:3210'));
+			tests.t(validate.isIpAddress('1080:0:0:0:8:800:200C:417A'));
+			tests.f(validate.isIpAddress('1080:0:0:0:8:800:200C:417A', {allowIPv6: false}));
 		
 			// Hybrid of IPv6 and IPv4
-			tests.t(dojox.validate.isIpAddress('0:0:0:0:0:0:13.1.68.3'));
-			tests.t(dojox.validate.isIpAddress('0:0:0:0:0:FFFF:129.144.52.38'));
-			tests.f(dojox.validate.isIpAddress('0:0:0:0:0:FFFF:129.144.52.38', {allowHybrid: false}));
+			tests.t(validate.isIpAddress('0:0:0:0:0:0:13.1.68.3'));
+			tests.t(validate.isIpAddress('0:0:0:0:0:FFFF:129.144.52.38'));
+			tests.f(validate.isIpAddress('0:0:0:0:0:FFFF:129.144.52.38', {allowHybrid: false}));
 			
 		}
 	},
@@ -114,101 +107,101 @@ tests.register("dojox.validate.tests.validate",
 		name: "isUrlTest",
 		runTest: function(tests){
 			
-			tests.t(dojox.validate.isUrl('www.yahoo.com'));
-			tests.t(dojox.validate.isUrl('http://www.yahoo.com'));
-			tests.t(dojox.validate.isUrl('https://www.yahoo.com'));
-			tests.f(dojox.validate.isUrl('http://.yahoo.com'));
-			tests.f(dojox.validate.isUrl('http://www.-yahoo.com'));
-			tests.f(dojox.validate.isUrl('http://www.yahoo-.com'));
-			tests.t(dojox.validate.isUrl('http://y-a---h-o-o.com'));
-			tests.t(dojox.validate.isUrl('http://www.y.com'));
-			tests.t(dojox.validate.isUrl('http://www.yahoo.museum'));
-			tests.t(dojox.validate.isUrl('http://www.yahoo.co.uk'));
-			tests.f(dojox.validate.isUrl('http://www.micro$oft.com'));
+			tests.t(validate.isUrl('www.yahoo.com'));
+			tests.t(validate.isUrl('http://www.yahoo.com'));
+			tests.t(validate.isUrl('https://www.yahoo.com'));
+			tests.f(validate.isUrl('http://.yahoo.com'));
+			tests.f(validate.isUrl('http://www.-yahoo.com'));
+			tests.f(validate.isUrl('http://www.yahoo-.com'));
+			tests.t(validate.isUrl('http://y-a---h-o-o.com'));
+			tests.t(validate.isUrl('http://www.y.com'));
+			tests.t(validate.isUrl('http://www.yahoo.museum'));
+			tests.t(validate.isUrl('http://www.yahoo.co.uk'));
+			tests.f(validate.isUrl('http://www.micro$oft.com'));
 		
-			tests.t(dojox.validate.isUrl('http://www.y.museum:8080'));
-			tests.t(dojox.validate.isUrl('http://12.24.36.128:8080'));
-			tests.f(dojox.validate.isUrl('http://12.24.36.128:8080', {allowIP: false} ));
-			tests.t(dojox.validate.isUrl('www.y.museum:8080'));
-			tests.f(dojox.validate.isUrl('www.y.museum:8080', {scheme: true} ));
-			tests.t(dojox.validate.isUrl('localhost:8080', {allowLocal: true} ));
-			tests.f(dojox.validate.isUrl('localhost:8080', {} ));
-			tests.t(dojox.validate.isUrl('http://www.yahoo.com/index.html?a=12&b=hello%20world#anchor'));
-			tests.t(dojox.validate.isUrl('http://www.yahoo.xyz'));
-			tests.t(dojox.validate.isUrl('http://www.yahoo.com/index.html#anchor'));
-			tests.t(dojox.validate.isUrl('http://cocoon.apache.org/2.1/'));
+			tests.t(validate.isUrl('http://www.y.museum:8080'));
+			tests.t(validate.isUrl('http://12.24.36.128:8080'));
+			tests.f(validate.isUrl('http://12.24.36.128:8080', {allowIP: false} ));
+			tests.t(validate.isUrl('www.y.museum:8080'));
+			tests.f(validate.isUrl('www.y.museum:8080', {scheme: true} ));
+			tests.t(validate.isUrl('localhost:8080', {allowLocal: true} ));
+			tests.f(validate.isUrl('localhost:8080', {} ));
+			tests.t(validate.isUrl('http://www.yahoo.com/index.html?a=12&b=hello%20world#anchor'));
+			tests.t(validate.isUrl('http://www.yahoo.xyz'));
+			tests.t(validate.isUrl('http://www.yahoo.com/index.html#anchor'));
+			tests.t(validate.isUrl('http://cocoon.apache.org/2.1/'));
 		}
 	},
 	{
 		name: "isEmailAddress",
 		runTest: function(tests) {
-			tests.t(dojox.validate.isEmailAddress('x at yahoo.com'));
-			tests.f(dojox.validate.isEmailAddress('x at yahoo'));
-			tests.t(dojox.validate.isEmailAddress('x.y.z.w at yahoo.com'));
-			tests.f(dojox.validate.isEmailAddress('x..y.z.w at yahoo.com'));
-			tests.f(dojox.validate.isEmailAddress('x. at yahoo.com'));
-			tests.f(dojox.validate.isEmailAddress('.x at yahoo.com'));
-			tests.t(dojox.validate.isEmailAddress('azAZ09!#$%.&\'*+-/=?_`{|}y at yahoo.com'));
-			tests.t(dojox.validate.isEmailAddress('x=y at yahoo.com'));
-			tests.f(dojox.validate.isEmailAddress('x(y at yahoo.com'));
-			tests.f(dojox.validate.isEmailAddress('x)y at yahoo.com'));
-			tests.f(dojox.validate.isEmailAddress('x<y at yahoo.com'));
-			tests.f(dojox.validate.isEmailAddress('x>y at yahoo.com'));
-			tests.f(dojox.validate.isEmailAddress('x[y at yahoo.com'));
-			tests.f(dojox.validate.isEmailAddress('x]y at yahoo.com'));
-			tests.f(dojox.validate.isEmailAddress('x:y at yahoo.com'));
-			tests.f(dojox.validate.isEmailAddress('x;y at yahoo.com'));
-			tests.f(dojox.validate.isEmailAddress('x at y@yahoo.com'));
-			tests.f(dojox.validate.isEmailAddress('x\\y at yahoo.com'));
-			tests.f(dojox.validate.isEmailAddress('x,y at yahoo.com'));
-			tests.f(dojox.validate.isEmailAddress('x\"y at yahoo.com'));
-			tests.t(dojox.validate.isEmailAddress('x at z.com'));
-			tests.t(dojox.validate.isEmailAddress('x at yahoo.x'));
-			tests.t(dojox.validate.isEmailAddress('x at yahoo.museum'));
-			tests.t(dojox.validate.isEmailAddress("o'mally at yahoo.com"));
-			tests.t(dojox.validate.isEmailAddress("o''mally at yahoo.com"));
-			tests.t(dojox.validate.isEmailAddress("'mally at yahoo.com"));
-			tests.t(dojox.validate.isEmailAddress("fred&barney at stonehenge.com"));
-			tests.t(dojox.validate.isEmailAddress("fred&&barney at stonehenge.com"));
+			tests.t(validate.isEmailAddress('x at yahoo.com'));
+			tests.f(validate.isEmailAddress('x at yahoo'));
+			tests.t(validate.isEmailAddress('x.y.z.w at yahoo.com'));
+			tests.f(validate.isEmailAddress('x..y.z.w at yahoo.com'));
+			tests.f(validate.isEmailAddress('x. at yahoo.com'));
+			tests.f(validate.isEmailAddress('.x at yahoo.com'));
+			tests.t(validate.isEmailAddress('azAZ09!#$%.&\'*+-/=?_`{|}y at yahoo.com'));
+			tests.t(validate.isEmailAddress('x=y at yahoo.com'));
+			tests.f(validate.isEmailAddress('x(y at yahoo.com'));
+			tests.f(validate.isEmailAddress('x)y at yahoo.com'));
+			tests.f(validate.isEmailAddress('x<y at yahoo.com'));
+			tests.f(validate.isEmailAddress('x>y at yahoo.com'));
+			tests.f(validate.isEmailAddress('x[y at yahoo.com'));
+			tests.f(validate.isEmailAddress('x]y at yahoo.com'));
+			tests.f(validate.isEmailAddress('x:y at yahoo.com'));
+			tests.f(validate.isEmailAddress('x;y at yahoo.com'));
+			tests.f(validate.isEmailAddress('x at y@yahoo.com'));
+			tests.f(validate.isEmailAddress('x\\y at yahoo.com'));
+			tests.f(validate.isEmailAddress('x,y at yahoo.com'));
+			tests.f(validate.isEmailAddress('x\"y at yahoo.com'));
+			tests.t(validate.isEmailAddress('x at z.com'));
+			tests.t(validate.isEmailAddress('x at yahoo.x'));
+			tests.t(validate.isEmailAddress('x at yahoo.museum'));
+			tests.t(validate.isEmailAddress("o'mally at yahoo.com"));
+			tests.t(validate.isEmailAddress("o''mally at yahoo.com"));
+			tests.t(validate.isEmailAddress("'mally at yahoo.com"));
+			tests.t(validate.isEmailAddress("fred&barney at stonehenge.com"));
+			tests.t(validate.isEmailAddress("fred&&barney at stonehenge.com"));
 		
 			// local addresses
-			tests.t(dojox.validate.isEmailAddress("fred&barney at localhost", {allowLocal: true} ));
-			tests.f(dojox.validate.isEmailAddress("fred&barney at localhost"));
+			tests.t(validate.isEmailAddress("fred&barney at localhost", {allowLocal: true} ));
+			tests.f(validate.isEmailAddress("fred&barney at localhost"));
 		
 			// addresses with cruft
-			tests.t(dojox.validate.isEmailAddress("mailto:fred&barney at stonehenge.com", {allowCruft: true} ));
-			tests.t(dojox.validate.isEmailAddress("<fred&barney at stonehenge.com>", {allowCruft: true} ));
-			tests.f(dojox.validate.isEmailAddress("mailto:fred&barney at stonehenge.com"));
-			tests.f(dojox.validate.isEmailAddress("<fred&barney at stonehenge.com>"));
+			tests.t(validate.isEmailAddress("mailto:fred&barney at stonehenge.com", {allowCruft: true} ));
+			tests.t(validate.isEmailAddress("<fred&barney at stonehenge.com>", {allowCruft: true} ));
+			tests.f(validate.isEmailAddress("mailto:fred&barney at stonehenge.com"));
+			tests.f(validate.isEmailAddress("<fred&barney at stonehenge.com>"));
 	
 			// local addresses with cruft
-			tests.t(dojox.validate.isEmailAddress("<mailto:fred&barney at localhost>", {allowLocal: true, allowCruft: true} ));
-			tests.f(dojox.validate.isEmailAddress("<mailto:fred&barney at localhost>", {allowCruft: true} ));
-			tests.f(dojox.validate.isEmailAddress("<mailto:fred&barney at localhost>", {allowLocal: true} ));
+			tests.t(validate.isEmailAddress("<mailto:fred&barney at localhost>", {allowLocal: true, allowCruft: true} ));
+			tests.f(validate.isEmailAddress("<mailto:fred&barney at localhost>", {allowCruft: true} ));
+			tests.f(validate.isEmailAddress("<mailto:fred&barney at localhost>", {allowLocal: true} ));
 		}
 	},
 	{
 		name: "isEmailsAddressList",
 		runTest: function(tests) {
-			tests.t(dojox.validate.isEmailAddressList(
+			tests.t(validate.isEmailAddressList(
 				"x at yahoo.com \n x.y.z.w at yahoo.com ; o'mally at yahoo.com , fred&barney at stonehenge.com \n" )
 			);
-			tests.t(dojox.validate.isEmailAddressList(
+			tests.t(validate.isEmailAddressList(
 				"x at yahoo.com \n x.y.z.w at localhost \n o'mally at yahoo.com \n fred&barney at localhost",
 				{allowLocal: true} )
 			);
-			tests.f(dojox.validate.isEmailAddressList(
+			tests.f(validate.isEmailAddressList(
 				"x at yahoo.com; x.y.z.w at localhost; o'mally at yahoo.com; fred&barney at localhost", {listSeparator: ";"} )
 			);
-			tests.t(dojox.validate.isEmailAddressList(
+			tests.t(validate.isEmailAddressList(
 					"mailto:x at yahoo.com; <x.y.z.w at yahoo.com>; <mailto:o'mally at yahoo.com>; fred&barney at stonehenge.com",
 					{allowCruft: true, listSeparator: ";"} )
 			);
-			tests.f(dojox.validate.isEmailAddressList(
+			tests.f(validate.isEmailAddressList(
 					"mailto:x at yahoo.com; <x.y.z.w at yahoo.com>; <mailto:o'mally at yahoo.com>; fred&barney at stonehenge.com",
 					{listSeparator: ";"} )
 			);
-			tests.t(dojox.validate.isEmailAddressList(
+			tests.t(validate.isEmailAddressList(
 					"mailto:x at yahoo.com; <x.y.z.w at localhost>; <mailto:o'mally at localhost>; fred&barney at localhost",
 					{allowLocal: true, allowCruft: true, listSeparator: ";"} )
 			);
@@ -218,104 +211,106 @@ tests.register("dojox.validate.tests.validate",
 		name: "getEmailAddressList",
 		runTest: function(tests) {
 			var list = "x at yahoo.com \n x.y.z.w at yahoo.com ; o'mally at yahoo.com , fred&barney at stonehenge.com";
-			tests.is(4, dojox.validate.getEmailAddressList(list).length);
+			tests.is(4, validate.getEmailAddressList(list).length);
 
 			var localhostList = "x at yahoo.com; x.y.z.w at localhost; o'mally at yahoo.com; fred&barney at localhost";
-			tests.is(0, dojox.validate.getEmailAddressList(localhostList).length);
-			tests.is(4, dojox.validate.getEmailAddressList(localhostList, {allowLocal: true} ).length);
+			tests.is(0, validate.getEmailAddressList(localhostList).length);
+			tests.is(4, validate.getEmailAddressList(localhostList, {allowLocal: true} ).length);
 		}
 	},
 	{
 		name: "isInRangeInt",
 		runTest: function(tests) {
 			// test integers
-			tests.f(dojox.validate.isInRange( '0', {min: 1, max: 100} ));
-			tests.t(dojox.validate.isInRange( '1', {min: 1, max: 100} ));
-			tests.f(dojox.validate.isInRange( '-50', {min: 1, max: 100} ));
-//			tests.t(dojox.validate.isInRange( '+50', {min: 1, max: 100} )); //TODO: dojo.number.parse does not support plus sign
-			tests.t(dojox.validate.isInRange( '100', {min: 1, max: 100} ));
-			tests.f(dojox.validate.isInRange( '101', {min: 1, max: 100} ));
+			tests.f(validate.isInRange( '0', {min: 1, max: 100} ));
+			tests.t(validate.isInRange( '1', {min: 1, max: 100} ));
+			tests.f(validate.isInRange( '-50', {min: 1, max: 100} ));
+//			tests.t(validate.isInRange( '+50', {min: 1, max: 100} )); //TODO: dojo.number.parse does not support plus sign
+			tests.t(validate.isInRange( '100', {min: 1, max: 100} ));
+			tests.f(validate.isInRange( '101', {min: 1, max: 100} ));
 		}
 	},
 	{
 		name:"isInRangeReal",
 		runTest: function(tests){
 	
-			tests.f(dojox.validate.isInRange( '0.9', {min: 1.0, max: 10.0, locale: 'en-us'} ));
-			tests.t(dojox.validate.isInRange( '1.0', {min: 1.0, max: 10.0, locale: 'en-us'} ));
-			tests.f(dojox.validate.isInRange( '-5.0', {min: 1.0, max: 10.0, locale: 'en-us'} ));
-//			tests.t(dojox.validate.isInRange( '+5.50', {min: 1.0, max: 10.0, locale: 'en-us'} )); //TODO: dojo.number.parse does not support plus sign
-			tests.t(dojox.validate.isInRange( '10.0', {min: 1.0, max: 10.0, locale: 'en-us'} ));
-			tests.f(dojox.validate.isInRange( '10.1', {min: 1.0, max: 10.0, locale: 'en-us'} ));
+			tests.f(validate.isInRange( '0.9', {min: 1.0, max: 10.0, locale: 'en-us'} ));
+			tests.t(validate.isInRange( '1.0', {min: 1.0, max: 10.0, locale: 'en-us'} ));
+			tests.f(validate.isInRange( '-5.0', {min: 1.0, max: 10.0, locale: 'en-us'} ));
+//			tests.t(validate.isInRange( '+5.50', {min: 1.0, max: 10.0, locale: 'en-us'} )); //TODO: dojo.number.parse does not support plus sign
+			tests.t(validate.isInRange( '10.0', {min: 1.0, max: 10.0, locale: 'en-us'} ));
+			tests.f(validate.isInRange( '10.1', {min: 1.0, max: 10.0, locale: 'en-us'} ));
 // TODO: dojo.number.parse does not support scientific notation at this time
-//			tests.f(dojox.validate.isInRange( '5.566e28', {min: 5.567e28, max: 6.000e28, locale: 'en-us'} ));
-//			tests.t(dojox.validate.isInRange( '5.7e28', {min: 5.567e28, max: 6.000e28, locale: 'en-us'} ));
-//			tests.f(dojox.validate.isInRange( '6.00000001e28', {min: 5.567e28, max: 6.000e28, locale: 'en-us'} ));
-//			tests.f(dojox.validate.isInRange( '10.000.000,12345e-5', {decimal: ",", max: 10000000.1e-5, locale: 'de-de'} ));
-//			tests.f(dojox.validate.isInRange( '10.000.000,12345e-5', {decimal: ",", min: 10000000.2e-5, locale: 'de-de'} ));
-			tests.t(dojox.validate.isInRange('1,500,000', { min: 0, locale: 'en-us'}));
-			tests.f(dojox.validate.isInRange('1,500,000', { min: 1000, max: 20000, locale: 'en-us'}));
+//			tests.f(validate.isInRange( '5.566e28', {min: 5.567e28, max: 6.000e28, locale: 'en-us'} ));
+//			tests.t(validate.isInRange( '5.7e28', {min: 5.567e28, max: 6.000e28, locale: 'en-us'} ));
+//			tests.f(validate.isInRange( '6.00000001e28', {min: 5.567e28, max: 6.000e28, locale: 'en-us'} ));
+//			tests.f(validate.isInRange( '10.000.000,12345e-5', {decimal: ",", max: 10000000.1e-5, locale: 'de-de'} ));
+//			tests.f(validate.isInRange( '10.000.000,12345e-5', {decimal: ",", min: 10000000.2e-5, locale: 'de-de'} ));
+			tests.t(validate.isInRange('1,500,000', { min: 0, locale: 'en-us'}));
+			tests.f(validate.isInRange('1,500,000', { min: 1000, max: 20000, locale: 'en-us'}));
 		}
 	},
 	{
 		name: "isUsPhoneNumber",
 		runTest: function(tests) {
-			tests.t(dojox.validate.us.isPhoneNumber('(111) 111-1111'));
-			tests.t(dojox.validate.us.isPhoneNumber('(111) 111 1111'));
-			tests.t(dojox.validate.us.isPhoneNumber('111 111 1111'));
-			tests.t(dojox.validate.us.isPhoneNumber('111.111.1111'));
-			tests.t(dojox.validate.us.isPhoneNumber('111-111-1111'));
-			tests.t(dojox.validate.us.isPhoneNumber('111/111-1111'));
-			tests.f(dojox.validate.us.isPhoneNumber('111 111-1111'));
-			tests.f(dojox.validate.us.isPhoneNumber('111-1111'));
-			tests.f(dojox.validate.us.isPhoneNumber('(111)-111-1111'));
+			tests.t(us.isPhoneNumber('(111) 111-1111'));
+			tests.t(us.isPhoneNumber('(111) 111 1111'));
+			tests.t(us.isPhoneNumber('111 111 1111'));
+			tests.t(us.isPhoneNumber('111.111.1111'));
+			tests.t(us.isPhoneNumber('111-111-1111'));
+			tests.t(us.isPhoneNumber('111/111-1111'));
+			tests.f(us.isPhoneNumber('111 111-1111'));
+			tests.f(us.isPhoneNumber('111-1111'));
+			tests.f(us.isPhoneNumber('(111)-111-1111'));
 		
 			// test extensions
-			tests.t(dojox.validate.us.isPhoneNumber('111-111-1111 x1'));
-			tests.t(dojox.validate.us.isPhoneNumber('111-111-1111 x12'));
-			tests.t(dojox.validate.us.isPhoneNumber('111-111-1111 x1234'));
+			tests.t(us.isPhoneNumber('111-111-1111 x1'));
+			tests.t(us.isPhoneNumber('111-111-1111 x12'));
+			tests.t(us.isPhoneNumber('111-111-1111 x1234'));
 		}
 	},
 	{
 		name: "isUsSocialSecurityNumber",
 		runTest: function(tests) {
-			tests.t(dojox.validate.us.isSocialSecurityNumber('123-45-6789'));
-			tests.t(dojox.validate.us.isSocialSecurityNumber('123 45 6789'));
-			tests.t(dojox.validate.us.isSocialSecurityNumber('123456789'));
-			tests.f(dojox.validate.us.isSocialSecurityNumber('123-45 6789'));
-			tests.f(dojox.validate.us.isSocialSecurityNumber('12345 6789'));
-			tests.f(dojox.validate.us.isSocialSecurityNumber('123-456789'));
+			tests.t(us.isSocialSecurityNumber('123-45-6789'));
+			tests.t(us.isSocialSecurityNumber('123 45 6789'));
+			tests.t(us.isSocialSecurityNumber('123456789'));
+			tests.f(us.isSocialSecurityNumber('123-45 6789'));
+			tests.f(us.isSocialSecurityNumber('12345 6789'));
+			tests.f(us.isSocialSecurityNumber('123-456789'));
 		}
 	},
 	{
 		name:"isUsZipCode",
 		runTest: function(tests) {
-			tests.t(dojox.validate.us.isZipCode('12345-6789'));
-			tests.t(dojox.validate.us.isZipCode('12345 6789'));
-			tests.t(dojox.validate.us.isZipCode('123456789'));
-			tests.t(dojox.validate.us.isZipCode('12345'));
+			tests.t(us.isZipCode('12345-6789'));
+			tests.t(us.isZipCode('12345 6789'));
+			tests.t(us.isZipCode('123456789'));
+			tests.t(us.isZipCode('12345'));
 		}
 	},
 	{
 		name:"isCaZipCode",
 		runTest: function(tests) {
-			tests.t(dojox.validate.ca.isPostalCode('A1Z 3F3'));
-			tests.f(dojox.validate.ca.isPostalCode('1AZ 3F3'));
-			tests.t(dojox.validate.ca.isPostalCode('a1z 3f3'));
-			tests.f(dojox.validate.ca.isPostalCode('xxxxxx'));
-			tests.f(dojox.validate.ca.isPostalCode('A1Z3F3'));
+			tests.t(ca.isPostalCode('A1Z 3F3'));
+			tests.f(ca.isPostalCode('1AZ 3F3'));
+			tests.t(ca.isPostalCode('a1z 3f3'));
+			tests.f(ca.isPostalCode('xxxxxx'));
+			tests.f(ca.isPostalCode('A1Z3F3'));
 			
 		}
 	},
 	{
 		name:"isUsState",
 		runTest: function(tests) {
-			tests.t(dojox.validate.us.isState('CA'));
-			tests.t(dojox.validate.us.isState('ne'));
-			tests.t(dojox.validate.us.isState('PR'));
-			tests.f(dojox.validate.us.isState('PR', {allowTerritories: false} ));
-			tests.t(dojox.validate.us.isState('AA'));
-			tests.f(dojox.validate.us.isState('AA', {allowMilitary: false} ));
+			tests.t(us.isState('CA'));
+			tests.t(us.isState('ne'));
+			tests.t(us.isState('PR'));
+			tests.f(us.isState('PR', {allowTerritories: false} ));
+			tests.t(us.isState('AA'));
+			tests.f(us.isState('AA', {allowMilitary: false} ));
 		}
 	}
 ]);
+
+});
diff --git a/dojox/validate/us.js b/dojox/validate/us.js
index 07166ee..8669cbe 100644
--- a/dojox/validate/us.js
+++ b/dojox/validate/us.js
@@ -1,8 +1,8 @@
-dojo.provide("dojox.validate.us");
-dojo.require("dojox.validate._base");
+define(["dojo/_base/lang", "./_base", "./regexp"], 
+ function(lang, validate, xregexp){
 
-
-dojox.validate.us.isState = function(/*String*/value, /*Object?*/flags){
+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
@@ -10,11 +10,11 @@ dojox.validate.us.isState = function(/*String*/value, /*Object?*/flags){
 	//    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("^" + dojox.validate.regexp.us.state(flags) + "$", "i");
+	var re = new RegExp("^" + xregexp.us.state(flags) + "$", "i");
 	return re.test(value); // Boolean
-}
+};
 
-dojox.validate.us.isPhoneNumber = function(/*String*/value){
+us.isPhoneNumber = function(/*String*/value){
 	// summary: Validates 10 US digit phone number for several common formats
 	// value: The telephone number string
 
@@ -35,10 +35,10 @@ dojox.validate.us.isPhoneNumber = function(/*String*/value){
 			"##########"
 		]
 	};
-	return dojox.validate.isNumberFormat(value, flags); // Boolean
-}
+	return validate.isNumberFormat(value, flags); // Boolean
+};
 
-dojox.validate.us.isSocialSecurityNumber = function(/*String*/value){
+us.isSocialSecurityNumber = function(/*String*/value){
 	// summary: Validates social security number
 	var flags = {
 		format: [
@@ -47,10 +47,10 @@ dojox.validate.us.isSocialSecurityNumber = function(/*String*/value){
 			"#########"
 		]
 	};
-	return dojox.validate.isNumberFormat(value, flags); // Boolean
-}
+	return validate.isNumberFormat(value, flags); // Boolean
+};
 
-dojox.validate.us.isZipCode = function(/*String*/value){
+us.isZipCode = function(/*String*/value){
 	// summary: Validates U.S. zip-code
 	var flags = {
 		format: [
@@ -60,5 +60,8 @@ dojox.validate.us.isZipCode = function(/*String*/value){
 			"#####"
 		]
 	};
-	return dojox.validate.isNumberFormat(value, flags); // Boolean
-}
+	return validate.isNumberFormat(value, flags); // Boolean
+};
+
+return us;
+});
diff --git a/dojox/validate/web.js b/dojox/validate/web.js
index bd58f22..c6665fa 100644
--- a/dojox/validate/web.js
+++ b/dojox/validate/web.js
@@ -1,7 +1,12 @@
-dojo.provide("dojox.validate.web");
-dojo.require("dojox.validate._base");
+define(["./_base", "./regexp"], function(validate, xregexp){
 
-dojox.validate.isIpAddress = function(/*String*/value, /*Object?*/flags) {
+/*=====
+
+	validate = dojox.validate;
+
+=====*/
+
+validate.isIpAddress = function(/*String*/value, /*Object?*/flags) {
 	// summary: Validates an IP address
 	//
 	// description:
@@ -20,12 +25,12 @@ dojox.validate.isIpAddress = function(/*String*/value, /*Object?*/flags) {
 	//    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("^" + dojox.validate.regexp.ipAddress(flags) + "$", "i");
+	var re = new RegExp("^" + xregexp.ipAddress(flags) + "$", "i");
 	return re.test(value); // Boolean
-}
+};
 
 
-dojox.validate.isUrl = function(/*String*/value, /*Object?*/flags) {
+validate.isUrl = function(/*String*/value, /*Object?*/flags) {
 	// summary: Checks if a string could be a valid URL
 	// value: A string
 	// flags: An object
@@ -35,11 +40,11 @@ dojox.validate.isUrl = function(/*String*/value, /*Object?*/flags) {
 	//    flags in regexp.ipAddress can be applied.
 	//    flags in regexp.tld can be applied.
 
-	var re = new RegExp("^" + dojox.validate.regexp.url(flags) + "$", "i");
+	var re = new RegExp("^" + xregexp.url(flags) + "$", "i");
 	return re.test(value); // Boolean
-}
+};
 
-dojox.validate.isEmailAddress = function(/*String*/value, /*Object?*/flags) {
+validate.isEmailAddress = function(/*String*/value, /*Object?*/flags) {
 	// summary: Checks if a string could be a valid email address
 	//
 	// value: A string
@@ -49,11 +54,11 @@ dojox.validate.isEmailAddress = function(/*String*/value, /*Object?*/flags) {
 	//    flags in regexp.ipAddress can be applied.
 	//    flags in regexp.tld can be applied.
 
-	var re = new RegExp("^" + dojox.validate.regexp.emailAddress(flags) + "$", "i");
+	var re = new RegExp("^" + xregexp.emailAddress(flags) + "$", "i");
 	return re.test(value); // Boolean
-}
+};
 
-dojox.validate.isEmailAddressList = function(/*String*/value, /*Object?*/flags) {
+validate.isEmailAddressList = function(/*String*/value, /*Object?*/flags) {
 	// summary: Checks if a string could be a valid email address list.
 	//
 	// value  A string.
@@ -64,11 +69,11 @@ dojox.validate.isEmailAddressList = function(/*String*/value, /*Object?*/flags)
 	//    flags in regexp.ipAddress can be applied.
 	//    flags in regexp.tld can be applied.
 
-	var re = new RegExp("^" + dojox.validate.regexp.emailAddressList(flags) + "$", "i");
+	var re = new RegExp("^" + xregexp.emailAddressList(flags) + "$", "i");
 	return re.test(value); // Boolean
-}
+};
 
-dojox.validate.getEmailAddressList = function(/*String*/value, /*Object?*/flags) {
+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.
 	//
@@ -78,8 +83,11 @@ dojox.validate.getEmailAddressList = function(/*String*/value, /*Object?*/flags)
 	if(!flags) { flags = {}; }
 	if(!flags.listSeparator) { flags.listSeparator = "\\s;,"; }
 
-	if ( dojox.validate.isEmailAddressList(value, flags) ) {
+	if ( validate.isEmailAddressList(value, flags) ) {
 		return value.split(new RegExp("\\s*[" + flags.listSeparator + "]\\s*")); // Array
 	}
 	return []; // Array
-}
+};
+
+return validate;
+});
diff --git a/dojox/widget/AnalogGauge.js b/dojox/widget/AnalogGauge.js
index a3c9c32..70299d4 100644
--- a/dojox/widget/AnalogGauge.js
+++ b/dojox/widget/AnalogGauge.js
@@ -1,355 +1,7 @@
+// backward compatibility for dojox.widget.AnalogGauge
 dojo.provide("dojox.widget.AnalogGauge");
-
-dojo.require("dojox.gfx");
 dojo.require("dojox.widget.gauge._Gauge");
 
-dojo.experimental("dojox.widget.AnalogGauge");
-
-dojo.declare("dojox.widget.gauge.AnalogLineIndicator",[dojox.widget.gauge._Indicator],{
-	_getShapes: function(){
-		// summary:
-		//		Private function for generating the shapes for this indicator. An indicator that behaves the
-		//		same might override this one and simply replace the shapes (such as ArrowIndicator).
-		return [this._gauge.surface.createLine({x1: 0, y1: -this.offset,
-													x2: 0, y2: -this.length-this.offset})
-					.setStroke({color: this.color, width: this.width})];
-	},
-	draw: function(/*Boolean?*/ dontAnimate){
-		// summary:
-		//		Override of dojox.widget.gauge._Indicator.draw
-		// dontAnimate: Boolean
-		//		Indicates if the drawing should not be animated (vs. the default of doing an animation)
-		if(this.shapes){
-			this._move(dontAnimate);
-		}else{
-			if(this.text){
-				this._gauge.surface.rawNode.removeChild(this.text);
-				this.text = null;
-			}
-			var a = this._gauge._getAngle(Math.min(Math.max(this.value, this._gauge.min), this._gauge.max));
-
-			this.color = this.color || '#000000';
-			this.length = this.length || this._gauge.radius;
-			this.width = this.width || 1;
-			this.offset = this.offset || 0;
-			this.highlight = this.highlight || '#D0D0D0';
-
-			this.shapes = this._getShapes(this._gauge, this);
-
-			if(this.shapes){
-				for(var s = 0; s < this.shapes.length; s++){
-					this.shapes[s].setTransform([{dx:this._gauge.cx,dy:this._gauge.cy}, dojox.gfx.matrix.rotateg(a)]);
-					if(this.hover){
-						this.shapes[s].getEventSource().setAttribute('hover',this.hover);
-					}
-					if(this.onDragMove && !this.noChange){
-						//TODO
-						this._gauge.connect(this.shapes[s].getEventSource(), 'onmousedown', this._gauge.handleMouseDown);
-						this.shapes[s].getEventSource().style.cursor = 'pointer';
-					}
-				}
-			}
-	
-			if(this.label){
-				var len=this.length+this.offset,
-					rad=this._gauge._getRadians(a),
-					x=this._gauge.cx+(len+5)*Math.sin(rad),
-					y=this._gauge.cy-(len+5)*Math.cos(rad),
-					align = 'start',
-					aa = Math.abs(a)
-				;
-				if(a <= -10){align = 'end';}
-				if(aa < 10){align='middle';}
-				var vAlign = 'bottom';
-				if(aa > 90){vAlign = 'top';}
-				this.text = this._gauge.drawText(''+this.label, x, y, align, vAlign, this.color, this.font);
-			}
-			this.currentValue = this.value;
-		}
-	},
-	_move: function(/*Boolean?*/ dontAnimate){
-		// 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)
-		var v = Math.min(Math.max(this.value, this._gauge.min), this._gauge.max),
-			c = this.currentValue
-		;
-		if(dontAnimate){
-			var angle = this._gauge._getAngle(v);
-			for(var i in this.shapes){
-				this.shapes[i].setTransform([{dx:this._gauge.cx,dy:this._gauge.cy}, dojox.gfx.matrix.rotateg(angle)]);
-				if(this.hover){
-					this.shapes[i].getEventSource().setAttribute('hover',this.hover);
-				}
-			}
-		}else{
-			if(c!=v){
-				var anim = new dojo.Animation({curve: [c, v], duration: this.duration, easing: this.easing});
-				dojo.connect(anim, "onAnimate", dojo.hitch(this, function(step){
-					for(var i in this.shapes){
-						this.shapes[i].setTransform([{dx:this._gauge.cx,dy:this._gauge.cy}, dojox.gfx.matrix.rotateg(this._gauge._getAngle(step))]);
-						if(this.hover){
-							this.shapes[i].getEventSource().setAttribute('hover',this.hover);
-						}
-					}
-					this.currentValue = step;
-				}));
-				anim.play();
-			}
-		}
-	}
-});
-dojo.declare("dojox.widget.AnalogGauge",dojox.widget.gauge._Gauge,{
-	// summary:
-	//		a gauge built using the dojox.gfx package.
-	//
-	// description:
-	//		using dojo.gfx (and thus either SVG or VML based on what is supported), this widget
-	//		builds a gauge component, used to display numerical data in a familiar format
-	//
-	// usage:
-	//		<script type="text/javascript">
-	//			dojo.require("dojox.widget.AnalogGauge");
-	//			dojo.require("dijit.util.parser");
-	//		</script>
-	//		...
-	//		<div	dojoType="dojox.widget.AnalogGauge"
-	//				id="testGauge"
-	//				width="300"
-	//				height="200"
-	//				cx=150
-	//				cy=175
-	//				radius=125
-	//				image="gaugeOverlay.png"
-	//				imageOverlay="false"
-	//				imageWidth="280"
-	//				imageHeight="155"
-	//				imageX="12"
-	//				imageY="38">
-	//		</div>
-
-	// startAngle: Number
-	// angle (in degrees) for start of gauge (default is -90)
-	startAngle: -90,
-
-	// endAngle: Number
-	// angle (in degrees) for end of gauge (default is 90)
-	endAngle: 90,
-
-	// cx: Number
-	// center of gauge x coordinate (default is gauge width / 2)
-	cx: 0,
-
-	// cy: Number
-	// 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: 0,
-
-	// _defaultIndicator: override of dojox.widget._Gauge._defaultIndicator
-	_defaultIndicator: dojox.widget.gauge.AnalogLineIndicator,
-
-	startup: function(){
-		// handle settings from HTML by making sure all the options are
-		// converted correctly to numbers and that we calculate defaults
-		// for cx, cy and radius
-		// also connects mouse handling events
-
-		if(this.getChildren){
-			dojo.forEach(this.getChildren(), function(child){ child.startup(); });
-		}
-
-		this.startAngle = Number(this.startAngle);
-		this.endAngle = Number(this.endAngle);
-
-		this.cx = Number(this.cx);
-		if(!this.cx){this.cx = this.width/2;}
-		this.cy = Number(this.cy);
-		if(!this.cy){this.cy = this.height/2;}
-		this.radius = Number(this.radius);
-		if(!this.radius){this.radius = Math.min(this.cx,this.cy) - 25;}
-		this._oppositeMiddle = (this.startAngle+this.endAngle)/2+180;
-
-		this.inherited(arguments);
-	},
-
-	_getAngle: function(/*Number*/value){
-		// summary:
-		//		This is a helper function used to determine the angle that represents
-		//		a given value on the gauge
-		// value:	Number
-		//			A value to be converted to an angle for this gauage.
-		return (value - this.min)/(this.max - this.min)*(this.endAngle - this.startAngle) + this.startAngle;
-	},
-
-	_getValueForAngle: function(/*Number*/angle){
-		// summary:
-		//		This is a helper function used to determie the value represented by a
-		//		given angle on the gauge
-		// angle:	Number
-		//			A angle to be converted to a value for this gauge.
-		if(angle > this._oppositeMiddle){ angle -= 360; }
-		return (angle - this.startAngle)*(this.max - this.min)/(this.endAngle - this.startAngle) + this.min;
-	},
-
-	_getRadians: function(/*Number*/angle){
-		// summary:
-		//		This is a helper function than converts degrees to radians
-		// angle:	Number
-		//			An angle, in degrees, to be converted to radians.
-		return angle*Math.PI/180;
-	},
-
-	_getDegrees: function(/*Number*/radians){
-		// summary:
-		//		This is a helper function that converts radians to degrees
-		// radians:	Number
-		//			An angle, in radians, to be converted to degrees.
-		return radians*180/Math.PI;
-	},
-
-	draw: function(){
-		// summary:
-		//		This function is used to draw (or redraw) the gauge.
-		// description:
-		//		Draws the gauge by drawing the surface, the ranges, and the indicators.
-		var i;
-		if(this._rangeData){
-			for(i=0; i<this._rangeData.length; i++){
-				this.drawRange(this._rangeData[i]);
-			}
-			if(this._img && this.image.overlay){
-				this._img.moveToFront();
-			}
-		}
-		if(this._indicatorData){
-			for(i=0; i<this._indicatorData.length; i++){
-				this._indicatorData[i].draw();
-			}
-		}
-	},
-
-	drawRange: function(/*Object*/range){
-		// summary:
-		//		This function is used to draw (or redraw) a range
-		// description:
-		//		Draws a range (colored area on the background of the gauge)
-		//		based on the given arguments.
-		// range:
-		//		A range is a dojox.widget.gauge.Range or an object
-		//		with similar parameters (low, high, hover, etc.).
-		var path;
-		if(range.shape){
-			this.surface.remove(range.shape);
-			range.shape = null;
-		}
-		var a1, a2;
-		if((range.low == this.min) && (range.high == this.max) && ((this.endAngle - this.startAngle) == 360)){
-			path = this.surface.createCircle({cx: this.cx, cy: this.cy, r: this.radius});
-		}else{
-			a1 = this._getRadians(this._getAngle(range.low));
-			a2 = this._getRadians(this._getAngle(range.high));
-			var x1=this.cx+this.radius*Math.sin(a1),
-				y1=this.cy-this.radius*Math.cos(a1),
-				x2=this.cx+this.radius*Math.sin(a2),
-				y2=this.cy-this.radius*Math.cos(a2),
-				big=0
-			;
-			if((a2-a1)>Math.PI){big=1;}
-
-			path = this.surface.createPath();
-			if(range.size){
-				path.moveTo(this.cx+(this.radius-range.size)*Math.sin(a1),
-							this.cy-(this.radius-range.size)*Math.cos(a1));
-			}else{
-				path.moveTo(this.cx,this.cy);
-			}
-			path.lineTo(x1,y1);
-			path.arcTo(this.radius,this.radius,0,big,1,x2,y2);
-			if(range.size){
-				path.lineTo(this.cx+(this.radius-range.size)*Math.sin(a2),
-							this.cy-(this.radius-range.size)*Math.cos(a2));
-				path.arcTo((this.radius-range.size),(this.radius-range.size),0,big,0,
-							this.cx+(this.radius-range.size)*Math.sin(a1),
-							this.cy-(this.radius-range.size)*Math.cos(a1));
-			}
-			path.closePath();
-		}
-
-		if(dojo.isArray(range.color) || dojo.isString(range.color)){
-			path.setStroke({color: range.color});
-			path.setFill(range.color);
-		}else if(range.color.type){
-			// Color is a gradient
-			a1 = this._getRadians(this._getAngle(range.low));
-			a2 = this._getRadians(this._getAngle(range.high));
-			range.color.x1 = this.cx+(this.radius*Math.sin(a1))/2;
-			range.color.x2 = this.cx+(this.radius*Math.sin(a2))/2;
-			range.color.y1 = this.cy-(this.radius*Math.cos(a1))/2;
-			range.color.y2 = this.cy-(this.radius*Math.cos(a2))/2;
-			path.setFill(range.color);
-			path.setStroke({color: range.color.colors[0].color});
-		}else{
-			// We've defined a style rather than an explicit color
-			path.setStroke({color: "green"});	// Arbitrary color, just have to indicate
-			path.setFill("green");				// that we want it filled
-			path.getEventSource().setAttribute("class", range.color.style);
-		}
-		if(range.hover){
-			path.getEventSource().setAttribute('hover',range.hover);
-		}
-		range.shape = path;
-	},
-
-	getRangeUnderMouse: function(/*Object*/event){
-		// summary:
-		//		Determines which range the mouse is currently over
-		// event:	Object
-		//			The event object as received by the mouse handling functions below.
-		var range = null,
-			pos = dojo.coords(this.gaugeContent),
-			x = event.clientX - pos.x,
-			y = event.clientY - pos.y,
-			r = Math.sqrt((y - this.cy)*(y - this.cy) + (x - this.cx)*(x - this.cx))
-		;
-		if(r < this.radius){
-			var angle = this._getDegrees(Math.atan2(y - this.cy, x - this.cx) + Math.PI/2),
-			//if(angle > this.endAngle){angle = angle - 360;}
-				value = this._getValueForAngle(angle)
-			;
-			if(this._rangeData){
-				for(var i=0; (i<this._rangeData.length) && !range; i++){
-					if((Number(this._rangeData[i].low) <= value) && (Number(this._rangeData[i].high) >= value)){
-						range = this._rangeData[i];
-					}
-				}
-			}
-		}
-		return range;
-	},
-
-	_dragIndicator: function(/*Object*/ widget, /*Object*/ event){
-		// summary:
-		//		Handles the dragging of an indicator, including moving/re-drawing
-		// get angle for mouse position
-		var pos = dojo.coords(widget.gaugeContent),
-			x = event.clientX - pos.x,
-			y = event.clientY - pos.y,
-			angle = widget._getDegrees(Math.atan2(y - widget.cy, x - widget.cx) + Math.PI/2),
-		//if(angle > widget.endAngle){angle = angle - 360;}
-		// get value and restrict to our min/max
-			value = widget._getValueForAngle(angle)
-		;
-		value = Math.min(Math.max(value, widget.min), widget.max);
-		// update the indicator
-		widget._drag.value = widget._drag.currentValue = value;
-		// callback
-		widget._drag.onDragMove(widget._drag);
-		// rotate indicator
-		widget._drag.draw(true);
-		dojo.stopEvent(event);
-	}
-});
+dojo.require("dojox.gauges.AnalogGauge");
+dojox.widget.AnalogGauge = dojox.gauges.AnalogGauge;
+dojox.widget.gauge.AnalogLineIndicator = dojox.gauges.AnalogLineIndicator;
diff --git a/dojox/widget/BarGauge.js b/dojox/widget/BarGauge.js
index 290a702..a354d9d 100644
--- a/dojox/widget/BarGauge.js
+++ b/dojox/widget/BarGauge.js
@@ -1,292 +1,6 @@
+// backward compatibility for dojox.widget.BarGauge
 dojo.provide("dojox.widget.BarGauge");
-
-dojo.require("dojox.gfx");
 dojo.require("dojox.widget.gauge._Gauge");
-
-dojo.experimental("dojox.widget.BarGauge");
-
-dojo.declare("dojox.widget.gauge.BarLineIndicator",[dojox.widget.gauge._Indicator],{
-	width: 1,
-	_getShapes: function(){
-		// summary:
-		//		Private function for generating the shapes for this indicator. An indicator that behaves the
-		//		same might override this one and simply replace the shapes (such as BarIndicator).
-		if(!this._gauge){
-			return null;
-		}
-		var v = this.value;
-		if(v < this._gauge.min){v = this._gauge.min;}
-		if(v > this._gauge.max){v = this._gauge.max;}
-		var pos = this._gauge._getPosition(v);
-		var shapes = [];
-		if(this.width > 1){
-			shapes[0] = this._gauge.surface.createRect({
-				x:pos,
-				y:this._gauge.dataY + this.offset,
-				width:this.width,
-				height:this.length
-			});
-			shapes[0].setStroke({color: this.color});
-			shapes[0].setFill(this.color);
-		}else{
-			shapes[0] = this._gauge.surface.createLine({
-				x1:pos,
-				y1:this._gauge.dataY + this.offset,
-				x2:pos,
-				y2:this._gauge.dataY + this.offset + this.length
-			});
-			shapes[0].setStroke({color: this.color});
-		}
-		return shapes;
-	},
-	draw: function(/*Boolean?*/ dontAnimate){
-		// summary:
-		//		Override of dojox.widget.gauge._Indicator.draw
-		// dontAnimate: Boolean
-		//		Indicates if the drawing should not be animated (vs. the default of doing an animation)
-		var i;
-		if(this.shapes){
-			this._move(dontAnimate);
-		}else{
-			if(this.shapes){
-				for(i=0; i<this.shapes.length; i++){
-					this._gauge.surface.remove(this.shapes[i]);
-				}
-				this.shapes = null;
-			}
-			if(this.text){
-				this._gauge.surface.rawNode.removeChild(this.text);
-				this.text = null;
-			}
-	
-			this.color = this.color || '#000000';
-			this.length = this.length || this._gauge.dataHeight;
-			this.width = this.width || 3;
-			this.offset = this.offset || 0;
-			this.highlight = this.highlight || '#4D4D4D';
-			this.highlight2 = this.highlight2 || '#A3A3A3';
-	
-			this.shapes = this._getShapes(this._gauge, this);
-			if(this.label){
-				var v = this.value;
-				if(v < this._gauge.min){v = this._gauge.min;}
-				if(v > this._gauge.max){v = this._gauge.max;}
-				var pos = this._gauge._getPosition(v);
-				this.text = this._gauge.drawText(''+this.label, pos, this._gauge.dataY + this.offset - 5, 'middle','top', this.color, this.font);
-			}
-	
-			for(i=0; i<this.shapes.length; i++){
-				if(this.hover){
-					this.shapes[i].getEventSource().setAttribute('hover',this.hover);
-				}
-				if(this.onDragMove && !this.noChange){
-					this._gauge.connect(this.shapes[i].getEventSource(), 'onmousedown', this._gauge.handleMouseDown);
-					this.shapes[i].getEventSource().style.cursor = 'pointer';
-				}
-			}
-			this.currentValue = this.value;
-		}
-	},
-	_move: function(/*Boolean?*/ dontAnimate){
-		// 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)
-		var v = this.value ;
-		if(v < this.min){v = this.min;}
-		if(v > this.max){v = this.max;}
-		var c = this._gauge._getPosition(this.currentValue);
-		this.currentValue = v;
-		v = this._gauge._getPosition(v)-this._gauge.dataX;
-		if(dontAnimate){
-			this.shapes[0].applyTransform(dojox.gfx.matrix.translate(v-(this.shapes[0].matrix?this.shapes[0].matrix.dx:0),0));
-		}else{
-			var anim = new dojo.Animation({curve: [c, v], duration: this.duration, easing: this.easing});
-			dojo.connect(anim, "onAnimate", dojo.hitch(this, function(jump){
-				this.shapes[0].applyTransform(dojox.gfx.matrix.translate(jump-(this.shapes[0].matrix?this.shapes[0].matrix.dx:0),0));
-			}));
-			anim.play();
-		}
-	}
-});
-dojo.declare("dojox.widget.BarGauge",dojox.widget.gauge._Gauge,{
-	// summary:
-	//		a bar graph built using the dojox.gfx package.
-	//
-	// description:
-	//		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">
-	//			dojo.require("dojox.widget.BarGauge");
-	//			dojo.require("dijit.util.parser");
-	//		</script>
-	//		...
-	//		<div 	dojoType="dojox.widget.BarGauge"
-	//				id="testBarGauge"
-	//				barGaugeHeight="55"
-	//				dataY="25"
-	//				dataHeight="25"
-	//				dataWidth="225">
-	//		</div>
-
-	// dataX: Number
-	// x position of data area (default 5)
-	dataX: 5,
-
-	// dataY: Number
-	// y position of data area (default 5)
-	dataY: 5,
-
-	// dataWidth: Number
-	// width of data area (default is bar graph width - 10)
-	dataWidth: 0,
-
-	// dataHeight: Number
-	// height of data area (default is bar graph width - 10)
-	dataHeight: 0,
-
-	// _defaultIndicator: override of dojox.widget._Gauge._defaultIndicator
-	_defaultIndicator: dojox.widget.gauge.BarLineIndicator,
-
-	startup: function(){
-		// handle settings from HTML by making sure all the options are
-		// converted correctly to numbers
-		//
-		// also connects mouse handling events
-
-		if(this.getChildren){
-			dojo.forEach(this.getChildren(), function(child){ child.startup(); });
-		}
-
-		if(!this.dataWidth){this.dataWidth = this.gaugeWidth - 10;}
-		if(!this.dataHeight){this.dataHeight = this.gaugeHeight - 10;}
-
-		this.inherited(arguments);
-	},
-
-	_getPosition: function(/*Number*/value){
-		// 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.
-
-		return this.dataX + Math.floor((value - this.min)/(this.max - this.min)*this.dataWidth);
-	},
-
-	_getValueForPosition: function(/*Number*/pos){
-		// 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.
-		return (pos - this.dataX)*(this.max - this.min)/this.dataWidth + this.min;
-	},
-
-	draw: function(){
-		// summary:
-		//		This function is used to draw (or redraw) the bar graph
-		// description:
-		//		Draws the bar graph by drawing the surface, the ranges, and the indicators.
-
-		if(!this.surface){this.createSurface();}
-
-		var i;
-		if(this._rangeData){
-			for(i=0; i<this._rangeData.length; i++){
-				this.drawRange(this._rangeData[i]);
-			}
-			if(this._img && this.image.overlay){
-				this._img.moveToFront();
-			}
-		}
-		if(this._indicatorData){
-			for(i=0; i<this._indicatorData.length; i++){
-				this._indicatorData[i].draw();
-			}
-		}
-	},
-
-	drawRange: function(/*Object*/range){
-		// summary:
-		//		This function is used to draw (or redraw) a range
-		// description:
-		//		Draws a range (colored area on the background of the gauge)
-		//		based on the given arguments.
-		// range:
-		//		A range is either a dojox.widget.gauge.Range or an object
-		//		with similar parameters (low, high, hover, etc.).
-		if(range.shape){
-			this.surface.remove(range.shape);
-			range.shape = null;
-		}
-
-		var x1 = this._getPosition(range.low);
-		var x2 = this._getPosition(range.high);
-		var path = this.surface.createRect({x:x1,
-											y:this.dataY,
-											width:x2-x1,
-											height:this.dataHeight});
-		if(dojo.isArray(range.color) || dojo.isString(range.color)){
-			path.setStroke({color: range.color});
-			path.setFill(range.color);
-		}else if(range.color.type){
-			// Color is a gradient
-			var y = this.dataY + this.dataHeight/2;
-			range.color.x1 = x1;
-			range.color.x2 = x2;
-			range.color.y1 = y;
-			range.color.y2 = y;
-			path.setFill(range.color);
-			path.setStroke({color: range.color.colors[0].color});
-		}else{
-			// We've defined a style rather than an explicit color
-			path.setStroke({color: "green"});	// Arbitrary color, just have to indicate
-			path.setFill("green");				// that we want it filled
-			path.getEventSource().setAttribute("class", range.color.style);
-		}
-		if(range.hover){
-			path.getEventSource().setAttribute('hover',range.hover);
-		}
-		range.shape = path;
-	},
-
-	getRangeUnderMouse: function(/*Object*/event){
-		// summary:
-		//		Determines which range the mouse is currently over
-		// event:	Object
-		//			The event object as received by the mouse handling functions below.
-		var range = null;
-		var pos = dojo.coords(this.gaugeContent);
-		var x = event.clientX - pos.x;
-		var value = this._getValueForPosition(x);
-		if(this._rangeData){
-			for(var i=0; (i<this._rangeData.length) && !range; i++){
-				if((Number(this._rangeData[i].low) <= value) && (Number(this._rangeData[i].high) >= value)){
-					range = this._rangeData[i];
-				}
-			}
-		}
-		return range;
-	},
-
-	_dragIndicator: function(/*Object*/ widget, /*Object*/ event){
-		// summary:
-		//		Handles the dragging of an indicator, including moving/re-drawing
-		// get new value based on mouse position
-		var pos = dojo.coords(widget.gaugeContent);
-		var x = event.clientX - pos.x;
-		var value = widget._getValueForPosition(x);
-		if(value < widget.min){value = widget.min;}
-		if(value > widget.max){value = widget.max;}
-		// update the indicator
-		widget._drag.value = value;
-		// callback
-		widget._drag.onDragMove(widget._drag);
-		// redraw/move indicator(s)
-		widget._drag.draw(true);
-		dojo.stopEvent(event);
-	}
-});
+dojo.require("dojox.gauges.BarGauge");
+dojox.widget.BarGauge = dojox.gauges.BarGauge;
+dojox.widget.gauge.BarLineIndicator = dojox.gauges.BarLineIndicator;
diff --git a/dojox/widget/Calendar.js b/dojox/widget/Calendar.js
index 5595c03..9a44fae 100644
--- a/dojox/widget/Calendar.js
+++ b/dojox/widget/Calendar.js
@@ -1,8 +1,13 @@
 dojo.provide("dojox.widget.Calendar");
 dojo.experimental("dojox.widget.Calendar");
 
-dojo.require("dijit.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:
diff --git a/dojox/widget/Calendar/Calendar.css b/dojox/widget/Calendar/Calendar.css
index 5a49e02..4837459 100644
--- a/dojox/widget/Calendar/Calendar.css
+++ b/dojox/widget/Calendar/Calendar.css
@@ -10,6 +10,10 @@
 	width: 180px;
 	overflow: hidden;
 }
+.dj_ie6 .dojoxCalendarContainer {
+	width: auto;
+	position: relative;
+}
 
 .dojoxCalendarBody {
 	height: 138px;
diff --git a/dojox/widget/CalendarViews.js b/dojox/widget/CalendarViews.js
index 501f0bb..587d38d 100644
--- a/dojox/widget/CalendarViews.js
+++ b/dojox/widget/CalendarViews.js
@@ -3,7 +3,6 @@ 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
diff --git a/dojox/widget/ColorPicker.js b/dojox/widget/ColorPicker.js
index 7686dde..f724557 100644
--- a/dojox/widget/ColorPicker.js
+++ b/dojox/widget/ColorPicker.js
@@ -1,26 +1,26 @@
-dojo.provide("dojox.widget.ColorPicker");
-dojo.experimental("dojox.widget.ColorPicker"); // level: beta //TODO: which?
+define([
+	"dojo/_base/kernel","dojo/_base/declare","dojo/_base/lang","dojo/_base/array",
+	"dojo/_base/html","dojo/_base/connect","dojo/_base/sniff","dojo/_base/window",
+	"dojo/_base/event","dojo/dom","dojo/dom-class","dojo/keys","dojo/fx","dojo/dnd/move",
+	"dijit/registry","dijit/_base/focus","dijit/form/_FormWidget","dijit/typematic",
+	"dojox/color","dojo/i18n","dojo/i18n!./nls/ColorPicker","dojo/i18n!dojo/cldr/nls/number",
+	"dojo/text!./ColorPicker/ColorPicker.html"
+], function(kernel,declare,lang,ArrayUtil,html,Hub,has,win,Event,DOM,DOMClass,Keys,fx,move,
+		registry,FocusManager,FormWidget,Typematic,color,i18n,bundle1,bundle2,template){
 
-dojo.requireLocalization("dojox.widget","ColorPicker");
-dojo.requireLocalization("dojo.cldr","number");
-
-dojo.require("dijit.form._FormWidget");
-dojo.require("dojo.dnd.move");
-dojo.require("dojo.fx");
-dojo.require("dojox.color");
-dojo.require("dojo.i18n");
-
-(function(d){
+	kernel.experimental("dojox.widget.ColorPicker");
 	
 	var webSafeFromHex = function(hex){
 		// stub, this is planned later:
 		return hex;
 	};
-	
-	dojo.declare("dojox.widget.ColorPicker",
-		dijit.form._FormWidget,
-		{
-		// summary: a HSV color picker - similar to Photoshop picker
+/*===== 
+	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
@@ -102,27 +102,26 @@ dojo.require("dojo.i18n");
 		//	to cause the points to adjust and the values to reflect the current color.
 		value: "#ffffff",
 		
-		_underlay: d.moduleUrl("dojox.widget","ColorPicker/images/underlay.png"),
+		_underlay: kernel.moduleUrl("dojox.widget","ColorPicker/images/underlay.png"),
 
-		_hueUnderlay: d.moduleUrl("dojox.widget","ColorPicker/images/hue.png"),
+		_hueUnderlay: kernel.moduleUrl("dojox.widget","ColorPicker/images/hue.png"),
 
-		_pickerPointer: d.moduleUrl("dojox.widget","ColorPicker/images/pickerPointer.png"),
+		_pickerPointer: kernel.moduleUrl("dojox.widget","ColorPicker/images/pickerPointer.png"),
 
-		_huePickerPointer: d.moduleUrl("dojox.widget","ColorPicker/images/hueHandle.png"),
+		_huePickerPointer: kernel.moduleUrl("dojox.widget","ColorPicker/images/hueHandle.png"),
 
-		_huePickerPointerAlly: d.moduleUrl("dojox.widget","ColorPicker/images/hueHandleA11y.png"),
+		_huePickerPointerAlly: kernel.moduleUrl("dojox.widget","ColorPicker/images/hueHandleA11y.png"),
 
-		// don't change to d.moduleUrl, build won't intern it.
-		templateString: dojo.cache("dojox.widget","ColorPicker/ColorPicker.html"),
+		templateString: template,
 
 		postMixInProperties: function(){
-			if(dojo.hasClass(dojo.body(), "dijit_a11y")){
+			if(DOMClass.contains(win.body(), "dijit_a11y")){
 				// Use the pointer that will show up in high contrast.
 				this._huePickerPointer = this._huePickerPointerAlly;
 			}
-			this._uId = dijit.getUniqueId(this.id);
-			dojo.mixin(this, dojo.i18n.getLocalization("dojox.widget", "ColorPicker"));
-			dojo.mixin(this, dojo.i18n.getLocalization("dojo.cldr", "number"));
+			this._uId = registry.getUniqueId(this.id);
+			lang.mixin(this, i18n.getLocalization("dojox.widget", "ColorPicker"));
+			lang.mixin(this, i18n.getLocalization("dojo.cldr", "number"));
 			this.inherited(arguments);
 		},
 
@@ -132,7 +131,7 @@ dojo.require("dojo.i18n");
 			//		underlay.  we don't do image handles (done in css), just the 'core'
 			//		of this widget: the underlay.
 			this.inherited(arguments);
-			if(d.isIE < 7){
+			if(has("ie") < 7){
 				this.colorUnderlay.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this._underlay+"', sizingMethod='scale')";
 				this.colorUnderlay.src = this._blankGif.toString();
 			}
@@ -149,7 +148,7 @@ dojo.require("dojo.i18n");
 			}
 			this._started = true;
 			this.set("value", this.value);
-			this._mover = new d.dnd.move.boxConstrainedMoveable(this.cursorNode, {
+			this._mover = new move.boxConstrainedMoveable(this.cursorNode, {
 				box: {
 					t: -(this.PICKER_SAT_SELECTOR_H/2),
 					l: -(this.PICKER_SAT_SELECTOR_W/2),
@@ -158,7 +157,7 @@ dojo.require("dojo.i18n");
 				}
 			});
 			
-			this._hueMover = new d.dnd.move.boxConstrainedMoveable(this.hueCursorNode, {
+			this._hueMover = new move.boxConstrainedMoveable(this.hueCursorNode, {
 				box: {
 					t: -(this.PICKER_HUE_SELECTOR_H/2),
 					l:0,
@@ -169,53 +168,53 @@ dojo.require("dojo.i18n");
 			
 			this._subs = [];
 			// no dnd/move/move published ... use a timer:
-			this._subs.push(d.subscribe("/dnd/move/stop", d.hitch(this, "_clearTimer")));
-			this._subs.push(d.subscribe("/dnd/move/start", d.hitch(this, "_setTimer")));
+			this._subs.push(Hub.subscribe("/dnd/move/stop", lang.hitch(this, "_clearTimer")));
+			this._subs.push(Hub.subscribe("/dnd/move/start", lang.hitch(this, "_setTimer")));
 
 			// Bind to up, down, left and right  arrows on the hue and saturation nodes.
 			this._keyListeners = [];
-			this._connects.push(dijit.typematic.addKeyListener(this.hueCursorNode,{
-				charOrCode: dojo.keys.UP_ARROW,
+			this._connects.push(Typematic.addKeyListener(this.hueCursorNode,{
+				charOrCode: Keys.UP_ARROW,
 				shiftKey: false,
 				metaKey: false,
 				ctrlKey: false,
 				altKey: false
-			}, this, dojo.hitch(this, this._updateHueCursorNode), 25, 25));
-			this._connects.push(dijit.typematic.addKeyListener(this.hueCursorNode,{
-				charOrCode: dojo.keys.DOWN_ARROW,
+			}, this, lang.hitch(this, this._updateHueCursorNode), 25, 25));
+			this._connects.push(Typematic.addKeyListener(this.hueCursorNode,{
+				charOrCode: Keys.DOWN_ARROW,
 				shiftKey: false,
 				metaKey: false,
 				ctrlKey: false,
 				altKey: false
-			}, this, dojo.hitch(this, this._updateHueCursorNode), 25, 25));
-			this._connects.push(dijit.typematic.addKeyListener(this.cursorNode,{
-				charOrCode: dojo.keys.UP_ARROW,
+			}, this, lang.hitch(this, this._updateHueCursorNode), 25, 25));
+			this._connects.push(Typematic.addKeyListener(this.cursorNode,{
+				charOrCode: Keys.UP_ARROW,
 				shiftKey: false,
 				metaKey: false,
 				ctrlKey: false,
 				altKey: false
-			}, this, dojo.hitch(this, this._updateCursorNode), 25, 25));
-			this._connects.push(dijit.typematic.addKeyListener(this.cursorNode,{
-				charOrCode: dojo.keys.DOWN_ARROW,
+			}, this, lang.hitch(this, this._updateCursorNode), 25, 25));
+			this._connects.push(Typematic.addKeyListener(this.cursorNode,{
+				charOrCode: Keys.DOWN_ARROW,
 				shiftKey: false,
 				metaKey: false,
 				ctrlKey: false,
 				altKey: false
-			}, this, dojo.hitch(this, this._updateCursorNode), 25, 25));
-			this._connects.push(dijit.typematic.addKeyListener(this.cursorNode,{
-				charOrCode: dojo.keys.LEFT_ARROW,
+			}, this, lang.hitch(this, this._updateCursorNode), 25, 25));
+			this._connects.push(Typematic.addKeyListener(this.cursorNode,{
+				charOrCode: Keys.LEFT_ARROW,
 				shiftKey: false,
 				metaKey: false,
 				ctrlKey: false,
 				altKey: false
-			}, this, dojo.hitch(this, this._updateCursorNode), 25, 25));
-			this._connects.push(dijit.typematic.addKeyListener(this.cursorNode,{
-				charOrCode: dojo.keys.RIGHT_ARROW,
+			}, this, lang.hitch(this, this._updateCursorNode), 25, 25));
+			this._connects.push(Typematic.addKeyListener(this.cursorNode,{
+				charOrCode: Keys.RIGHT_ARROW,
 				shiftKey: false,
 				metaKey: false,
 				ctrlKey: false,
 				altKey: false
-			}, this, dojo.hitch(this, this._updateCursorNode), 25, 25));
+			}, this, lang.hitch(this, this._updateCursorNode), 25, 25));
 		},
 		
 		_setValueAttr: function(value){
@@ -223,28 +222,30 @@ dojo.require("dojo.i18n");
 			this.setColor(value, true);
 		},
 		
-		setColor: function(/* String */color, force){
+		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.
-			var col = dojox.color.fromString(color);
+			col = color.fromString(col);
 			this._updatePickerLocations(col);
 			this._updateColorInputs(col);
 			this._updateValue(col, force);
 		},
 		
 		_setTimer: function(/* d.dnd.Mover */mover){
+			if(mover.node != this.cursorNode){ return; }
 			// FIXME: should I assume this? focus on mouse down so on mouse up
-			dijit.focus(mover.node);
-			d.setSelectable(this.domNode,false);
-			this._timer = setInterval(d.hitch(this, "_updateColor"), 45);
+			FocusManager.focus(mover.node);
+			DOM.setSelectable(this.domNode,false);
+			this._timer = setInterval(lang.hitch(this, "_updateColor"), 45);
 		},
 		
 		_clearTimer: function(/* d.dnd.Mover */mover){
+			if(!this._timer){ return; }
 			clearInterval(this._timer);
 			this._timer = null;
 			this.onChange(this.value);
-			d.setSelectable(this.domNode,true);
+			DOM.setSelectable(this.domNode,true);
 		},
 		
 		_setHue: function(/* Decimal */h){
@@ -252,7 +253,7 @@ dojo.require("dojo.i18n");
 			//		Sets a natural color background for the
 			//		underlay image against closest hue value (full saturation)
 			//		h: 0..360
-			d.style(this.colorUnderlay, "backgroundColor", dojox.color.fromHsv(h,100,100).toHex());
+			html.style(this.colorUnderlay, "backgroundColor", color.fromHsv(h,100,100).toHex());
 			
 		},
 
@@ -267,18 +268,18 @@ dojo.require("dojo.i18n");
 			// e:
 			//		The event.
 			if(count !== -1){
-				var y = dojo.style(this.hueCursorNode, "top");
-				var selCenter = (this.PICKER_HUE_SELECTOR_H/2);
+				var y = html.style(this.hueCursorNode, "top");
+				var selCenter = this.PICKER_HUE_SELECTOR_H/2;
 
 				// Account for our offset
 				y += selCenter;
 				var update = false;
-				if(e.charOrCode == dojo.keys.UP_ARROW){
+				if(e.charOrCode == Keys.UP_ARROW){
 					if(y > 0){
 						y -= 1;
 						update = true;
 					}
-				}else if(e.charOrCode == dojo.keys.DOWN_ARROW){
+				}else if(e.charOrCode == Keys.DOWN_ARROW){
 					if(y < this.PICKER_HUE_H){
 						y += 1;
 						update = true;
@@ -286,7 +287,7 @@ dojo.require("dojo.i18n");
 				}
 				y -= selCenter;
 				if(update){
-					dojo.style(this.hueCursorNode, "top", y + "px");
+					html.style(this.hueCursorNode, "top", y + "px");
 				}
 			}else{
 				this._updateColor(true);
@@ -307,30 +308,30 @@ dojo.require("dojo.i18n");
 			var selCenterW = this.PICKER_SAT_SELECTOR_W/2;
 
 			if(count !== -1){
-				var y = dojo.style(this.cursorNode, "top");
-				var x = dojo.style(this.cursorNode, "left");
+				var y = html.style(this.cursorNode, "top");
+				var x = html.style(this.cursorNode, "left");
 				
 				// Account for our offsets to center
 				y += selCenterH;
 				x += selCenterW;
 
 				var update = false;
-				if(e.charOrCode == dojo.keys.UP_ARROW){
+				if(e.charOrCode == Keys.UP_ARROW){
 					if(y > 0){
 						y -= 1;
 						update = true;
 					}
-				}else if(e.charOrCode == dojo.keys.DOWN_ARROW){
+				}else if(e.charOrCode == Keys.DOWN_ARROW){
 					if(y < this.PICKER_SAT_VAL_H){
 						y += 1;
 						update = true;
 					}
-				}else if(e.charOrCode == dojo.keys.LEFT_ARROW){
+				}else if(e.charOrCode == Keys.LEFT_ARROW){
 					if(x > 0){
 						x -= 1;
 						update = true;
 					}
-				}else if(e.charOrCode == dojo.keys.RIGHT_ARROW){
+				}else if(e.charOrCode == Keys.RIGHT_ARROW){
 					if(x < this.PICKER_SAT_VAL_W){
 						x += 1;
 						update = true;
@@ -340,8 +341,8 @@ dojo.require("dojo.i18n");
 					// Account for our offsets to center
 					y -= selCenterH;
 					x -= selCenterW;
-					dojo.style(this.cursorNode, "top", y + "px");
-					dojo.style(this.cursorNode, "left", x + "px");
+					html.style(this.cursorNode, "top", y + "px");
+					html.style(this.cursorNode, "left", x + "px");
 				}
 			}else{
 				this._updateColor(true);
@@ -355,18 +356,18 @@ dojo.require("dojo.i18n");
 				satSelCenterH = this.PICKER_SAT_SELECTOR_H/2,
 				satSelCenterW = this.PICKER_SAT_SELECTOR_W/2;
 
-			var _huetop = d.style(this.hueCursorNode,"top") + hueSelCenter,
-				_pickertop = d.style(this.cursorNode,"top") + satSelCenterH,
-				_pickerleft = d.style(this.cursorNode,"left") + satSelCenterW,
+			var _huetop = html.style(this.hueCursorNode,"top") + hueSelCenter,
+				_pickertop = html.style(this.cursorNode,"top") + satSelCenterH,
+				_pickerleft = html.style(this.cursorNode,"left") + satSelCenterW,
 				h = Math.round(360 - (_huetop / this.PICKER_HUE_H * 360)),
-				col = dojox.color.fromHsv(h, _pickerleft / this.PICKER_SAT_VAL_W * 100, 100 - (_pickertop / this.PICKER_SAT_VAL_H * 100))
+				col = color.fromHsv(h, _pickerleft / this.PICKER_SAT_VAL_W * 100, 100 - (_pickertop / this.PICKER_SAT_VAL_H * 100))
 			;
 			
 			this._updateColorInputs(col);
 			this._updateValue(col, true);
 			
 			// update hue, not all the pickers
-			if (h!=this._hue) {
+			if(h!=this._hue){
 				this._setHue(h);
 			}
 		},
@@ -375,24 +376,24 @@ dojo.require("dojo.i18n");
 			//summary: updates picker position and inputs
 			//         according to rgb, hex or hsv input changes
 			var col, hasit = false;
-			switch (e.target) {
+			switch(e.target){
 				//transform to hsv to pixels
 
 				case this.hexCode:
-					col = dojox.color.fromString(e.target.value);
+					col = color.fromString(e.target.value);
 					hasit = true;
 					
 					break;
 				case this.Rval:
 				case this.Gval:
 				case this.Bval:
-					col = dojox.color.fromArray([this.Rval.value, this.Gval.value, this.Bval.value]);
+					col = color.fromArray([this.Rval.value, this.Gval.value, this.Bval.value]);
 					hasit = true;
 					break;
 				case this.Hval:
 				case this.Sval:
 				case this.Vval:
-					col = dojox.color.fromHsv(this.Hval.value, this.Sval.value, this.Vval.value);
+					col = color.fromHsv(this.Hval.value, this.Sval.value, this.Vval.value);
 					hasit = true;
 					break;
 			}
@@ -413,7 +414,7 @@ dojo.require("dojo.i18n");
 			this.value = this.valueNode.value = hex;
 			
 			// anytime we muck with the color, fire onChange?
-			if(fireChange && (!this._timer || this.liveUpdate)) {
+			if(fireChange && (!this._timer || this.liveUpdate)){
 				this.onChange(hex);
 			}
 		},
@@ -425,21 +426,21 @@ dojo.require("dojo.i18n");
 				satSelCenterH = this.PICKER_SAT_SELECTOR_H/2,
 				satSelCenterW = this.PICKER_SAT_SELECTOR_W/2;
 
-            var hsv = col.toHsv(),
+			var hsv = col.toHsv(),
 				ypos = Math.round(this.PICKER_HUE_H - hsv.h / 360 * this.PICKER_HUE_H) - hueSelCenter,
 				newLeft = Math.round(hsv.s / 100 * this.PICKER_SAT_VAL_W) - satSelCenterW,
 				newTop = Math.round(this.PICKER_SAT_VAL_H - hsv.v / 100 * this.PICKER_SAT_VAL_H) - satSelCenterH
 			;
 			
-			if (this.animatePoint) {
-				d.fx.slideTo({
+			if(this.animatePoint){
+				fx.slideTo({
 					node: this.hueCursorNode,
 					duration: this.slideDuration,
 					top: ypos,
 					left: 0
 				}).play();
 				
-				d.fx.slideTo({
+				fx.slideTo({
 					node: this.cursorNode,
 					duration: this.slideDuration,
 					top: newTop,
@@ -448,15 +449,15 @@ dojo.require("dojo.i18n");
 				
 			}
 			else {
-				d.style(this.hueCursorNode, "top", ypos + "px");
-				d.style(this.cursorNode, {
+				html.style(this.hueCursorNode, "top", ypos + "px");
+				html.style(this.cursorNode, {
 					left: newLeft + "px",
 					top: newTop + "px"
 				});
 			}
 			
 			// limit hue calculations to only when it changes
-			if (hsv.h != this._hue) {
+			if(hsv.h != this._hue){
 				this._setHue(hsv.h);
 			}
 			
@@ -468,44 +469,44 @@ dojo.require("dojo.i18n");
 			
 			var hex = col.toHex();
 			
-			if (this.showRgb) {
+			if(this.showRgb){
 				this.Rval.value = col.r;
 				this.Gval.value = col.g;
 				this.Bval.value = col.b;
 			}
 			
-			if (this.showHsv) {
+			if(this.showHsv){
 				var hsv = col.toHsv();
 				this.Hval.value = Math.round((hsv.h)); // convert to 0..360
 				this.Sval.value = Math.round(hsv.s);
 				this.Vval.value = Math.round(hsv.v);
 			}
 			
-			if (this.showHex) {
+			if(this.showHex){
 				this.hexCode.value = hex;
 			}
 			
 			this.previewNode.style.backgroundColor = hex;
 			
-			if (this.webSafe) {
+			if(this.webSafe){
 				this.safePreviewNode.style.backgroundColor = webSafeFromHex(hex);
 			}
 		},
 		
 		_setHuePoint: function(/* Event */evt){
 			// summary: set the hue picker handle on relative y coordinates
-			var selCenter = (this.PICKER_HUE_SELECTOR_H/2);
+			var selCenter = this.PICKER_HUE_SELECTOR_H/2;
 			var ypos = evt.layerY - selCenter;
 			if(this.animatePoint){
-				d.fx.slideTo({
+				fx.slideTo({
 					node: this.hueCursorNode,
 					duration:this.slideDuration,
 					top: ypos,
 					left: 0,
-					onEnd: d.hitch(this, function() {this._updateColor(true); dijit.focus(this.hueCursorNode);})
+					onEnd: lang.hitch(this, function(){ this._updateColor(true); FocusManager.focus(this.hueCursorNode); })
 				}).play();
 			}else{
-				d.style(this.hueCursorNode, "top", ypos + "px");
+				html.style(this.hueCursorNode, "top", ypos + "px");
 				this._updateColor(false);
 			}
 		},
@@ -518,18 +519,18 @@ dojo.require("dojo.i18n");
 			var newTop = evt.layerY - satSelCenterH;
 			var newLeft = evt.layerX - satSelCenterW;
 			
-			if(evt){ dijit.focus(evt.target); }
+			if(evt){ FocusManager.focus(evt.target); }
 
 			if(this.animatePoint){
-				d.fx.slideTo({
+				fx.slideTo({
 					node: this.cursorNode,
 					duration: this.slideDuration,
 					top: newTop,
 					left: newLeft,
-					onEnd: d.hitch(this, function() {this._updateColor(true); dijit.focus(this.cursorNode);})
+					onEnd: lang.hitch(this, function(){ this._updateColor(true); FocusManager.focus(this.cursorNode); })
 				}).play();
 			}else{
-				d.style(this.cursorNode, {
+				html.style(this.cursorNode, {
 					left: newLeft + "px",
 					top: newTop + "px"
 				});
@@ -545,8 +546,8 @@ dojo.require("dojo.i18n");
 		focus: function(){
 			// summary:
 			//		Put focus on this widget, only if focus isn't set on it already.
-			if(!this._focused){
-				dijit.focus(this.focusNode);
+			if(!this.focused){
+				FocusManager.focus(this.focusNode);
 			}
 		},
 
@@ -555,17 +556,17 @@ dojo.require("dojo.i18n");
 			//		Function to hald the mouse down default
 			//		to disable draggong of images out of the color
 			//		picker.
-			dojo.stopEvent(e);
+			Event.stop(e);
 		},
 
 		destroy: function(){
 			// summary:
 			//		Over-ride to clean up subscriptions, etc.
 			this.inherited(arguments);
-			dojo.forEach(this._subs, function(sub){
-				dojo.unsubscribe(sub);
+			ArrayUtil.forEach(this._subs, function(sub){
+				Hub.unsubscribe(sub);
 			});
 			delete this._subs;
 		}
 	});
-})(dojo);
+});
diff --git a/dojox/widget/Dialog.js b/dojox/widget/Dialog.js
index 49730eb..6845f38 100644
--- a/dojox/widget/Dialog.js
+++ b/dojox/widget/Dialog.js
@@ -1,245 +1,250 @@
-dojo.provide('dojox.widget.Dialog');
-dojo.experimental('dojox.widget.Dialog');
-
-dojo.require("dojo.window");
-dojo.require('dojox.fx');
-dojo.require("dojox.widget.DialogSimple");
-
-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.
-	//
-	//		This Dialog is also very easy to apply custom styles to.
-	//
-	//		It works identically to a `dijit.Dialog` with several
-	//		additional parameters.
-	
-	templateString: dojo.cache('dojox.widget','Dialog/Dialog.html'),
-	
-	// 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
-	//		extends beyond the viewport size for whatever reason.
-	sizeToViewport: false,
-	
-	// viewportPadding: Integer
-	//		If sizeToViewport="true", this is the amount of padding in pixels to leave
-	//		between the dialog border and the viewport edge.
-	//		This value is also used when sizeToViewport="false" and dimensions exceeded
-	//		by dialog content to ensure dialog does not go outside viewport boundary
-	viewportPadding: 35,
-	
-	// dimensions: Array
-	//		A two-element array of [widht,height] to animate the Dialog to if sizeToViewport="false"
-	//		Defaults to [300,300]
-	dimensions: null,
-	
-	// easing: Function?|String?
-	//		An easing function to apply to the sizing animation.
-	easing: null,
-	
-	// sizeDuration: Integer
-	//		Time (in ms) to use in the Animation for sizing.
-	sizeDuration: dijit._defaultDuration,
-	
-	// sizeMethod: String
-	//		To be passed to dojox.fx.sizeTo, one of "chain" or "combine" to effect
-	//		the animation sequence.
-	sizeMethod: "chain",
-	
-	// showTitle: Boolean
-	//		Toogle to show or hide the Title area. Can only be set at startup.
-	showTitle: false,
-	
-	// draggable: Boolean
-	//		Make the pane draggable. Differs from dijit.Dialog by setting default to false
-	draggable: false, // simply over-ride the default from dijit.Dialog
-	
-	// modal: Boolean
-	//		If true, this Dialog instance will be truly modal and prevent closing until
-	//		explicitly told to by calling hide() - Defaults to false to preserve previous
-	//		behaviors.
-	modal: false,
-	
-	constructor: function(props, node){
-		this.easing = props.easing || dojo._defaultEasing;
-		this.dimensions = props.dimensions || [300, 300];
-	},
-	
-	_setup: function(){
-		// summary: Piggyback on dijit.Dialog's _setup for load-time options, deferred to
-
-		this.inherited(arguments);
-		if(!this._alreadyInitialized){
-			this._navIn = dojo.fadeIn({ node: this.closeButtonNode });
-			this._navOut = dojo.fadeOut({ node: this.closeButtonNode });
-			if(!this.showTitle){
-				dojo.addClass(this.domNode,"dojoxDialogNoTitle");
-			}
-		}
-	},
-	
-	layout: function(e){
-		this._setSize();
-		this.inherited(arguments);
-	},
-	
-	_setSize: function(){
-		// summary: cache and set our desired end position
-		this._vp = dojo.window.getBox();
-		var tc = this.containerNode,
-			vpSized = this.sizeToViewport
-		;
-		return this._displaysize = {
-			w: vpSized ? tc.scrollWidth : this.dimensions[0],
-			h: vpSized ? tc.scrollHeight : this.dimensions[1]
-		}; // Object
-	},
-	
-	show: function(){
-		if(this.open){ return; }
-		
-		this._setSize();
-		dojo.style(this.closeButtonNode,"opacity", 0);
-		dojo.style(this.domNode, {
-			overflow: "hidden",
-			opacity: 0,
-			width: "1px",
-			height: "1px"
-		});
-		dojo.style(this.containerNode, {
-			opacity: 0,
-			overflow: "hidden"
-		});
-		
-		this.inherited(arguments);
-
-		if(this.modal){
-			// prevent escape key from closing dialog
-			// connect to body to trap this event from the Dialog a11y code, and stop escape key
-			// from doing anything in the modal:true case:
-			this._modalconnects.push(dojo.connect(dojo.body(), "onkeypress", function(e){
-				if(e.charOrCode == dojo.keys.ESCAPE){
-					dojo.stopEvent(e);
+define([
+	"dojo", "dojox", "dojo/text!./Dialog/Dialog.html", 
+	"dijit/Dialog", "dojo/window", "dojox/fx", "./DialogSimple"
+], function(dojo, dojox, template){
+
+	dojo.getObject('widget', true, dojox);
+	
+	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.
+		//
+		//		This Dialog is also very easy to apply custom styles to.
+		//
+		//		It works identically to a `dijit.Dialog` with several
+		//		additional parameters.
+
+		templateString: template,
+
+		// 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
+		//		extends beyond the viewport size for whatever reason.
+		sizeToViewport: false,
+
+		// viewportPadding: Integer
+		//		If sizeToViewport="true", this is the amount of padding in pixels to leave
+		//		between the dialog border and the viewport edge.
+		//		This value is also used when sizeToViewport="false" and dimensions exceeded
+		//		by dialog content to ensure dialog does not go outside viewport boundary
+		viewportPadding: 35,
+
+		// dimensions: Array
+		//		A two-element array of [widht,height] to animate the Dialog to if sizeToViewport="false"
+		//		Defaults to [300,300]
+		dimensions: null,
+
+		// easing: Function?|String?
+		//		An easing function to apply to the sizing animation.
+		easing: null,
+
+		// sizeDuration: Integer
+		//		Time (in ms) to use in the Animation for sizing.
+		sizeDuration: dijit._defaultDuration,
+
+		// sizeMethod: String
+		//		To be passed to dojox.fx.sizeTo, one of "chain" or "combine" to effect
+		//		the animation sequence.
+		sizeMethod: "chain",
+
+		// showTitle: Boolean
+		//		Toogle to show or hide the Title area. Can only be set at startup.
+		showTitle: false,
+
+		// draggable: Boolean
+		//		Make the pane draggable. Differs from dijit.Dialog by setting default to false
+		draggable: false, // simply over-ride the default from dijit.Dialog
+
+		// modal: Boolean
+		//		If true, this Dialog instance will be truly modal and prevent closing until
+		//		explicitly told to by calling hide() - Defaults to false to preserve previous
+		//		behaviors.
+		modal: false,
+
+		constructor: function(props, node){
+			this.easing = props.easing || dojo._defaultEasing;
+			this.dimensions = props.dimensions || [300, 300];
+		},
+
+		_setup: function(){
+			// summary: Piggyback on dijit.Dialog's _setup for load-time options, deferred to
+
+			this.inherited(arguments);
+			if(!this._alreadyInitialized){
+				this._navIn = dojo.fadeIn({ node: this.closeButtonNode });
+				this._navOut = dojo.fadeOut({ node: this.closeButtonNode });
+				if(!this.showTitle){
+					dojo.addClass(this.domNode,"dojoxDialogNoTitle");
 				}
-			}));
-		}else{
-			// otherwise, allow clicking on the underlay to close
-			this._modalconnects.push(dojo.connect(dijit._underlay.domNode, "onclick", this, "onCancel"));
-		}
-		this._modalconnects.push(dojo.connect(this.domNode,"onmouseenter",this,"_handleNav"));
-		this._modalconnects.push(dojo.connect(this.domNode,"onmouseleave",this,"_handleNav"));
-		
-	},
-	
-	_handleNav: function(e){
-		// summary: Handle's showing or hiding the close icon
-
-		var navou = "_navOut",
-			navin = "_navIn",
-			animou = (e.type == "mouseout" ? navin : navou),
-			animin = (e.type == "mouseout" ? navou : navin)
-		;
-		
-		this[animou].stop();
-		this[animin].play();
-		
-	},
-	
-	// an experiment in a quicksilver-like hide. too choppy for me.
-	/*
-	hide: function(){
-		// summary: Hide the dialog
-
-		// if we haven't been initialized yet then we aren't showing and we can just return
-		if(!this._alreadyInitialized){
-			return;
-		}
+			}
+		},
 
-		this._fadeIn && this._fadeIn.stop();
+		layout: function(e){
+			this._setSize();
+			this.inherited(arguments);
+		},
 
-		if (this._scrollConnected){
-			this._scrollConnected = false;
-		}
-		dojo.forEach(this._modalconnects, dojo.disconnect);
-		this._modalconnects = [];
-		if(this.refocus){
-			this.connect(this._fadeOut,"onEnd",dojo.hitch(dijit,"focus",this._savedFocus));
-		}
-		if(this._relativePosition){
-			delete this._relativePosition;
-		}
-		
-		dojox.fx.sizeTo({
-			node: this.domNode,
-			duration:this.sizeDuration || this.duration,
-			width: this._vp.w - 1,
-			height: 5,
-			onBegin: dojo.hitch(this,function(){
-				this._fadeOut.play(this.sizeDuration / 2);
-			})
-		}).play();
-		
-		this.open = false;
-	}, */
-
-	_position: function(){
-		
-		if(!this._started){ return; } // prevent content: from firing this anim #8914
-		
-		if(this._sizing){
-			this._sizing.stop();
-			this.disconnect(this._sizingConnect);
-			delete this._sizing;
+		_setSize: function(){
+			// summary: cache and set our desired end position
+			this._vp = dojo.window.getBox();
+			var tc = this.containerNode,
+				vpSized = this.sizeToViewport
+			;
+			return this._displaysize = {
+				w: vpSized ? tc.scrollWidth : this.dimensions[0],
+				h: vpSized ? tc.scrollHeight : this.dimensions[1]
+			}; // Object
+		},
+
+		show: function(){
+			if(this.open){ return; }
+
+			this._setSize();
+			dojo.style(this.closeButtonNode,"opacity", 0);
+			dojo.style(this.domNode, {
+				overflow: "hidden",
+				opacity: 0,
+				width: "1px",
+				height: "1px"
+			});
+			dojo.style(this.containerNode, {
+				opacity: 0,
+				overflow: "hidden"
+			});
+
+			this.inherited(arguments);
+
+			if(this.modal){
+				// prevent escape key from closing dialog
+				// connect to body to trap this event from the Dialog a11y code, and stop escape key
+				// from doing anything in the modal:true case:
+				this._modalconnects.push(dojo.connect(dojo.body(), "onkeypress", function(e){
+					if(e.charOrCode == dojo.keys.ESCAPE){
+						dojo.stopEvent(e);
+					}
+				}));
+			}else{
+				// otherwise, allow clicking on the underlay to close
+				this._modalconnects.push(dojo.connect(dijit._underlay.domNode, "onclick", this, "onCancel"));
+			}
+			this._modalconnects.push(dojo.connect(this.domNode,"onmouseenter",this,"_handleNav"));
+			this._modalconnects.push(dojo.connect(this.domNode,"onmouseleave",this,"_handleNav"));
+
+		},
+
+		_handleNav: function(e){
+			// summary: Handle's showing or hiding the close icon
+
+			var navou = "_navOut",
+				navin = "_navIn",
+				animou = (e.type == "mouseout" ? navin : navou),
+				animin = (e.type == "mouseout" ? navou : navin)
+			;
+
+			this[animou].stop();
+			this[animin].play();
+
+		},
+
+		// an experiment in a quicksilver-like hide. too choppy for me.
+		/*
+		hide: function(){
+			// summary: Hide the dialog
+
+			// if we haven't been initialized yet then we aren't showing and we can just return
+			if(!this._alreadyInitialized){
+				return;
+			}
+
+			this._fadeIn && this._fadeIn.stop();
+
+			if (this._scrollConnected){
+				this._scrollConnected = false;
+			}
+			dojo.forEach(this._modalconnects, dojo.disconnect);
+			this._modalconnects = [];
+			if(this.refocus){
+				this.connect(this._fadeOut,"onEnd",dojo.hitch(dijit,"focus",this._savedFocus));
+			}
+			if(this._relativePosition){
+				delete this._relativePosition;
+			}
+
+			dojox.fx.sizeTo({
+				node: this.domNode,
+				duration:this.sizeDuration || this.duration,
+				width: this._vp.w - 1,
+				height: 5,
+				onBegin: dojo.hitch(this,function(){
+					this._fadeOut.play(this.sizeDuration / 2);
+				})
+			}).play();
+
+			this.open = false;
+		}, */
+
+		_position: function(){
+
+			if(!this._started){ return; } // prevent content: from firing this anim #8914
+
+			if(this._sizing){
+				this._sizing.stop();
+				this.disconnect(this._sizingConnect);
+				delete this._sizing;
+			}
+
+			this.inherited(arguments);
+
+			if(!this.open){ dojo.style(this.containerNode, "opacity", 0); }
+			var pad = this.viewportPadding * 2;
+
+			var props = {
+				node: this.domNode,
+				duration: this.sizeDuration || dijit._defaultDuration,
+				easing: this.easing,
+				method: this.sizeMethod
+			};
+
+			var ds = this._displaysize || this._setSize();
+			props['width'] = ds.w = (ds.w + pad >= this._vp.w || this.sizeToViewport)
+				? this._vp.w - pad : ds.w;
+
+			props['height'] = ds.h = (ds.h + pad >= this._vp.h || this.sizeToViewport)
+				? this._vp.h - pad : ds.h;
+
+			this._sizing = dojox.fx.sizeTo(props);
+			this._sizingConnect = this.connect(this._sizing,"onEnd","_showContent");
+			this._sizing.play();
+
+		},
+
+		_showContent: function(e){
+			// summary: Show the inner container after sizing animation
+
+			var container = this.containerNode;
+			dojo.style(this.domNode, {
+				overflow: "visible",
+				opacity: 1
+			});
+			dojo.style(this.closeButtonNode,"opacity",1);
+			dojo.style(container, {
+				height: this._displaysize.h - this.titleNode.offsetHeight + "px",
+				width: this._displaysize.w + "px",
+				overflow:"auto"
+			});
+			dojo.anim(container, { opacity:1 });
 		}
-		
-		this.inherited(arguments);
-		
-		if(!this.open){ dojo.style(this.containerNode, "opacity", 0); }
-		var pad = this.viewportPadding * 2;
-		
-		var props = {
-			node: this.domNode,
-			duration: this.sizeDuration || dijit._defaultDuration,
-			easing: this.easing,
-			method: this.sizeMethod
-		};
-
-		var ds = this._displaysize || this._setSize();
-		props['width'] = ds.w = (ds.w + pad >= this._vp.w || this.sizeToViewport)
-			? this._vp.w - pad : ds.w;
-			
-		props['height'] = ds.h = (ds.h + pad >= this._vp.h || this.sizeToViewport)
-			? this._vp.h - pad : ds.h;
-		
-		this._sizing = dojox.fx.sizeTo(props);
-		this._sizingConnect = this.connect(this._sizing,"onEnd","_showContent");
-		this._sizing.play();
-
-	},
-
-	_showContent: function(e){
-		// summary: Show the inner container after sizing animation
-
-		var container = this.containerNode;
-		dojo.style(this.domNode, {
-			overflow: "visible",
-			opacity: 1
-		});
-		dojo.style(this.closeButtonNode,"opacity",1);
-		dojo.style(container, {
-			height: this._displaysize.h - this.titleNode.offsetHeight + "px",
-			width: this._displaysize.w + "px",
-			overflow:"auto"
-		});
-		dojo.anim(container, { opacity:1 });
-	}
-	
-});
\ No newline at end of file
+
+	});
+
+	return dojox.widget.Dialog;
+
+});
+
diff --git a/dojox/widget/DialogSimple.js b/dojox/widget/DialogSimple.js
index b6a8c9f..6a8e32a 100644
--- a/dojox/widget/DialogSimple.js
+++ b/dojox/widget/DialogSimple.js
@@ -1,10 +1,11 @@
-dojo.provide("dojox.widget.DialogSimple");
+define(["dojo", "dijit", "dojox", "dijit/Dialog", "dojox/layout/ContentPane"], function(dojo, dijit, dojox){
 
-dojo.require('dijit.Dialog');
-dojo.require("dojox.layout.ContentPane");
-
-dojo.declare("dojox.widget.DialogSimple", [dojox.layout.ContentPane, dijit._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.
+	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
+		//		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/FisheyeList.js b/dojox/widget/FisheyeList.js
index 73f0156..86cc17a 100644
--- a/dojox/widget/FisheyeList.js
+++ b/dojox/widget/FisheyeList.js
@@ -263,12 +263,11 @@ dojo.declare("dojox.widget.FisheyeList", [dijit._Widget, dijit._Templated, dijit
 		// Node: Must must be display:block (ie, not a <span>)
 		node = dojo.byId(node);
 		var mouse = {x: e.pageX, y: e.pageY};
-		var bb = dojo._getBorderBox(node);
-		var absolute = dojo.coords(node, true);
+		var absolute = dojo.position(node, true);
 		var top = absolute.y;
-		var bottom = top + bb.h;
+		var bottom = top + absolute.h;
 		var left = absolute.x;
-		var right = left + bb.w;
+		var right = left + absolute.w;
 
 		return (mouse.x >= left
 			&& mouse.x <= right
diff --git a/dojox/widget/FisheyeLite.js b/dojox/widget/FisheyeLite.js
index 997b2ca..78e635e 100644
--- a/dojox/widget/FisheyeLite.js
+++ b/dojox/widget/FisheyeLite.js
@@ -1,149 +1,150 @@
-dojo.provide("dojox.widget.FisheyeLite");
-dojo.experimental("dojox.widget.FisheyeLite");
-
-dojo.require("dijit._Widget");
-dojo.require("dojo.fx.easing");
-
-dojo.declare("dojox.widget.FisheyeLite",
-	dijit._Widget,
-	{
-	// 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.
-	//
-	//		use position:absolute/relative nodes to prevent layout
-	//		changes, and use caution when seleting properties to
-	//		scale. Negative scaling works, but some properties
-	//		react poorly to being set to negative values, IE being
-	//		particularly annoying in that regard.
-	//
-	//		quirk: uses the domNode as the target of the animation
-	//		unless it finds a node class="fisheyeTarget" in the container
-	//		being turned into a FisheyeLite instance
-	//
-	// example:
-	//	|	// make all the LI's in a node Fisheye's:
-	//	|   dojo.query("#node li").forEach(function(n){
-	// 	|		new dojox.widget.FisheyeLite({},n);
-	//	|	});
-	//
-	//
-	// example:
-	//	|	new dojox.widget.FisheyeLite({
-	//	|		properties:{
-	//	|			// height is literal, width is multiplied
-	//	|			height:{ end: 200 }, width:2.3
-	//	|		}
-	//	|	}, "someNode");
-	//
-	// duationIn: Integer
-	//		The time (in ms) the run the show animation
-	durationIn: 350,
+define(["dojo", "dojox", "dijit/_Widget", "dojo/fx/easing"], function(dojo, dojox, widget, easing){
 	
-	// easeIn: Function
-	//		An easing function to use for the show animation
-	easeIn: dojo.fx.easing.backOut,
-	
-	// durationOut: Integer
-	//		The Time (in ms) to run the hide animation
-	durationOut: 1420,
-	
-	// easeOut: Function
-	// 		An easing function to use for the hide animation
-	easeOut: dojo.fx.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: null,
-	
-	// units: String
-	//		Sometimes, you need to specify a unit. Should be part of
-	//		properties attrib, but was trying to shorthand the logic there
-	units:"px",
-	
-	constructor: function(props, node){
-		this.properties = props.properties || {
-			fontSize: 2.75
-		}
-	},
-	
-	postCreate: function(){
-		
-		this.inherited(arguments);
-		this._target = dojo.query(".fisheyeTarget", this.domNode)[0] || this.domNode;
-		this._makeAnims();
-		
-		this.connect(this.domNode, "onmouseover", "show");
-		this.connect(this.domNode, "onmouseout", "hide");
-		this.connect(this._target, "onclick", "onClick");
-
-	},
-	
-	show: function(){
-		// summary:
-		//		Show this Fisheye item.
-		this._runningOut.stop();
-		this._runningIn.play();
-	},
-	
-	hide: function(){
-		// summary:
-		//		Hide this fisheye item on mouse leave
-		this._runningIn.stop();
-		this._runningOut.play();
-	},
-	
-	_makeAnims: function(){
-		// summary:
-		//		Pre-generate the animations
-
-		// create two properties: objects, one for each "state"
-		var _in = {}, _out = {}, cs = dojo.getComputedStyle(this._target);
-		for(var p in this.properties){
-			var prop = this.properties[p],
-				deep = dojo.isObject(prop),
-				v = parseInt(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 ?
-			_out[p] = { end: v, units:this.units };
-			_in[p] = deep ? prop : { end: prop * v, units:this.units };
+	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 ...
+		//
+		// 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.
+		//
+		//		use position:absolute/relative nodes to prevent layout
+		//		changes, and use caution when seleting properties to
+		//		scale. Negative scaling works, but some properties
+		//		react poorly to being set to negative values, IE being
+		//		particularly annoying in that regard.
+		//
+		//		quirk: uses the domNode as the target of the animation
+		//		unless it finds a node class="fisheyeTarget" in the container
+		//		being turned into a FisheyeLite instance
+		//
+		// example:
+		//	|	// make all the LI's in a node Fisheye's:
+		//	|   dojo.query("#node li").forEach(function(n){
+		// 	|		new dojox.widget.FisheyeLite({},n);
+		//	|	});
+		//
+		//
+		// example:
+		//	|	new dojox.widget.FisheyeLite({
+		//	|		properties:{
+		//	|			// height is literal, width is multiplied
+		//	|			height:{ end: 200 }, width:2.3
+		//	|		}
+		//	|	}, "someNode");
+		//
+		// duationIn: Integer
+		//		The time (in ms) the run the show animation
+		durationIn: 350,
+
+		// easeIn: Function
+		//		An easing function to use for the show animation
+		easeIn: easing.backOut,
+
+		// durationOut: Integer
+		//		The Time (in ms) to run the hide animation
+		durationOut: 1420,
+
+		// easeOut: Function
+		// 		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: null,
+
+		// units: String
+		//		Sometimes, you need to specify a unit. Should be part of
+		//		properties attrib, but was trying to shorthand the logic there
+		units:"px",
+
+		constructor: function(props, node){
+			this.properties = props.properties || {
+				fontSize: 2.75
+			}
+		},
+
+		postCreate: function(){
+
+			this.inherited(arguments);
+			this._target = dojo.query(".fisheyeTarget", this.domNode)[0] || this.domNode;
+			this._makeAnims();
+
+			this.connect(this.domNode, "onmouseover", "show");
+			this.connect(this.domNode, "onmouseout", "hide");
+			this.connect(this._target, "onclick", "onClick");
+
+		},
+
+		show: function(){
+			// summary:
+			//		Show this Fisheye item.
+			this._runningOut.stop();
+			this._runningIn.play();
+		},
+
+		hide: function(){
+			// summary:
+			//		Hide this fisheye item on mouse leave
+			this._runningIn.stop();
+			this._runningOut.play();
+		},
+
+		_makeAnims: function(){
+			// summary:
+			//		Pre-generate the animations
+
+			// create two properties: objects, one for each "state"
+			var _in = {}, _out = {}, cs = dojo.getComputedStyle(this._target);
+			for(var p in this.properties){
+				var prop = this.properties[p],
+					deep = dojo.isObject(prop),
+					v = parseInt(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 ?
+				_out[p] = { end: v, units:this.units };
+				_in[p] = deep ? prop : { end: prop * v, units:this.units };
+			}
+
+			this._runningIn = dojo.animateProperty({
+				node: this._target,
+				easing: this.easeIn,
+				duration: this.durationIn,
+				properties: _in
+			});
+
+			this._runningOut = dojo.animateProperty({
+				node: this._target,
+				duration: this.durationOut,
+				easing: this.easeOut,
+				properties: _out
+			});
+
+			this.connect(this._runningIn, "onEnd", dojo.hitch(this, "onSelected", this));
+		},
+
+		onClick: function(/* Event */e){
+			// 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.
 		}
-		
-		this._runningIn = dojo.animateProperty({
-			node: this._target,
-			easing: this.easeIn,
-			duration: this.durationIn,
-			properties: _in
-		});
-		
-		this._runningOut = dojo.animateProperty({
-			node: this._target,
-			duration: this.durationOut,
-			easing: this.easeOut,
-			properties: _out
-		});
-		
-		this.connect(this._runningIn, "onEnd", dojo.hitch(this, "onSelected", this));
-	},
-	
-	onClick: function(/* Event */e){
-		// 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.
-	}
+
+	});
 	
-});
+});
\ No newline at end of file
diff --git a/dojox/widget/MultiSelectCalendar.js b/dojox/widget/MultiSelectCalendar.js
new file mode 100644
index 0000000..3718835
--- /dev/null
+++ b/dojox/widget/MultiSelectCalendar.js
@@ -0,0 +1,974 @@
+define("dojox/widget/MultiSelectCalendar", [
+    "dojo/main", "dijit", 
+    "dojo/text!./MultiSelectCalendar/MultiSelectCalendar.html", 
+    "dojo/cldr/supplemental", 
+    "dojo/date", 
+    "dojo/date/locale", 
+    "dijit/_Widget", "dijit/_Templated", "dijit/_CssStateMixin", "dijit/form/DropDownButton", "dijit/typematic"],
+    function(dojo, dijit, template) {
+
+dojo.experimental("dojox.widget.MultiSelectCalendar");
+
+dojo.declare(
+	"dojox.widget.MultiSelectCalendar",
+	[dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin, dijit._CssStateMixin],
+	{
+		// summary:
+		//		A simple GUI for choosing several dates in the context of a monthly calendar.
+		//
+		// description:
+		//		A simple GUI for choosing several dates in the context of a monthly calendar.
+		//		This widget serialises its selected dates to ISO dates or ISO ranges of dates, 
+		//		depending on developer selection
+		//		Note that it accepts an Array of ISO dates as its input
+		//
+		// example:
+		//	|	var calendar = new dojox.widget.MultiSelectCalendar({value: ['2011-05-07,'2011-05-08',2011-05-09','2011-05-23']}, dojo.byId("calendarNode"));
+		//
+		// example:
+		//	|	<div dojoType="dojox.widget.MultiSelectCalendar"></div>
+
+		templateString: template,
+		widgetsInTemplate: true,
+
+		// value: Date
+		//		The currently selected Dates, initially set to an empty object to indicate no selection.
+		value: {},
+
+		// datePackage: String
+		//		JavaScript namespace to find Calendar routines.  Uses Gregorian Calendar routines
+		//		at dojo.date by default.
+		datePackage: "dojo.date",
+
+		// dayWidth: String
+		//		How to represent the days of the week in the calendar header. See dojo.date.locale
+		dayWidth: "narrow",
+
+		// tabIndex: Integer
+		//		Order fields are traversed when user hits the tab key
+		tabIndex: "0",
+		
+		// if returnIsoRanges is true, the selected dates will be returned as ISO ranges
+		// else each selected date will be returned sequentially
+		returnIsoRanges : false,
+		
+		// currentFocus: Date
+		//		Date object containing the currently focused date, or the date which would be focused
+		//		if the calendar itself was focused.   Also indicates which year and month to display,
+		//		i.e. the current "page" the calendar is on.
+		currentFocus: new Date(),
+
+		baseClass:"dijitCalendar",
+		
+		cssStateNodes: {
+			"decrementMonth": "dijitCalendarArrow",
+			"incrementMonth": "dijitCalendarArrow",
+			"previousYearLabelNode": "dijitCalendarPreviousYear",
+			"nextYearLabelNode": "dijitCalendarNextYear"			
+		},
+
+		_areValidDates: function(/*Date*/ value){
+			// summary:
+			//		Runs various tests on each selected date, checking that they're a valid date, rather
+			//		than blank or NaN.
+			// tags:
+			//		private
+			for (var selDate in this.value){
+				valid = (selDate && !isNaN(selDate) && typeof value == "object" && selDate.toString() != this.constructor.prototype.value.toString());
+				if(!valid){ return false; }
+			}
+			return true;
+		},
+
+		_getValueAttr: function(){
+			// summary: this method returns the list of selected dates in an array structure
+			if(this.returnIsoRanges){
+				datesWithRanges = this._returnDatesWithIsoRanges(this._sort());
+				return datesWithRanges;
+			}else{
+				return this._sort();
+			}
+		},
+		
+		_setValueAttr: function(/*Date|Number|array*/ value, /*Boolean*/ priorityChange){
+			// summary:
+			//		Support set("value", ...)
+			// description:
+			// 		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
+			
+			//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
+			this.value = {};
+			if(dojo.isArray(value)) {
+				dojo.forEach(value,function(element, i){
+					//Each element of the array could be a date or a date range
+					var slashPosition = element.indexOf("/");
+					if(slashPosition == -1){
+						//The element is a single date
+						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));
+						
+						this.toggleDate(dateA,[],[]);
+						if((dateA - dateB) > 0){
+							//We select the first date then the rest is handled as if we had selected a range
+							this._addToRangeRTL(dateA, dateB, [], []);	
+						}else{
+							//We select the first date then the rest is handled as if we had selected a range
+							this._addToRangeLTR(dateA, dateB, [], []);	
+						}
+					}
+				},this);
+			if(value.length > 0){
+				this.focusOnLastDate(value[value.length-1]);
+			}
+			}else{
+				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);
+				}
+				if(this._isValidDate(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)){
+						dateIndex = dojo.date.stamp.toISOString(value).substring(0,10);
+						
+						this.value[dateIndex] = 1;
+		
+						// 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'));
+							this.onValueSelected(this.get('value'));	// remove in 2.0
+						}
+					}
+				}
+			}
+			this._populateGrid();
+		},
+		focusOnLastDate : function(lastElement){
+			//We put the focus on the last date so that when the user re-clicks on the calendar it will be 
+			//on the proper month
+			var slashPositionLastDate = lastElement.indexOf("/");
+			var dateA,dateB;
+			if(slashPositionLastDate == -1){
+				//This is a singleDate
+				lastDate = lastElement;
+			}else{
+				dateA=new dojo.date.stamp.fromISOString(lastElement.substr(0,10));
+				dateB=new dojo.date.stamp.fromISOString(lastElement.substr(11,10));
+				if((dateA - dateB) > 0){
+					lastDate = dateA;
+				}else{
+					lastDate = dateB;
+				}
+			}
+			this.set("currentFocus", lastDate);		
+		},
+		_isValidDate: function(/*Date*/ value){
+			// summary:
+			//		Runs various tests on the value, checking that it's a valid date, rather
+			//		than blank or NaN.
+			// tags:
+			//		private
+			return value && !isNaN(value) && typeof value == "object" &&
+				value.toString() != this.constructor.prototype.value.toString();
+		},
+		_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
+			while(node.firstChild){
+				node.removeChild(node.firstChild);
+			}
+			node.appendChild(dojo.doc.createTextNode(text));
+		},
+
+		_populateGrid: function(){
+			// summary:
+			//      Fills in the calendar grid with each day (1-31)
+			// tags:
+			//      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)),
+				today = new this.dateClassObj(),
+				dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
+			if(dayOffset > firstDay){ dayOffset -= 7; }
+
+			//List of all 42 displayed days in the calendar
+			this.listOfNodes = dojo.query(".dijitCalendarDateTemplate", this.domNode);
+
+			// Iterate through dates in the calendar and fill in date numbers and style info
+			this.listOfNodes.forEach(function(template, i){
+				i += dayOffset;
+				var date = new this.dateClassObj(month),
+					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 = this.dateFuncObj.add(date, "month", adj);
+				}
+				date.setDate(number);
+
+				if(!this.dateFuncObj.compare(date, today, "date")){
+					clazz = "dijitCalendarCurrentDate " + clazz;
+				}
+
+				//If the date falls outside of the min or max constraints, we do nothing
+				dateIndex = dojo.date.stamp.toISOString(date).substring(0,10);
+				
+				if(!this.isDisabledDate(date, this.lang)){
+					//If the node is already selected, the user clicking on it once more will deselect it 
+					//so we will destroy it in the value object. If the date was not previously selected
+					//The user wants to select it so we add it to the value object
+					if(this._isSelectedDate(date, this.lang)){
+						if(this.value[dateIndex]){
+							clazz = "dijitCalendarSelectedDate " + clazz;
+						}else{
+							clazz = clazz.replace("dijitCalendarSelectedDate ","");
+						}
+					}
+				}
+				if(this._isSelectedDate(date, this.lang)){
+					clazz = "dijitCalendarBrowsingDate " + clazz;
+				}
+
+				if(this.isDisabledDate(date, this.lang)){
+					clazz = "dijitCalendarDisabledDate " + clazz;
+				}
+
+				var clazz2 = this.getClassForDate(date, this.lang);
+				if(clazz2){
+					clazz = clazz2 + " " + clazz;
+				}
+
+				template.className = clazz + "Month dijitCalendarDateTemplate";
+				template.dijitDateValue = date.valueOf();				// original code
+				dojo.attr(template, "dijitDateValue", date.valueOf());	// so I can dojo.query() it
+				var label = dojo.query(".dijitCalendarDateLabel", template)[0],
+					text = date.getDateLocalized ? date.getDateLocalized(this.lang) : date.getDate();
+				this._setText(label, text);
+			}, this);
+
+			// Repopulate month drop down list based on current year.
+			// Need to do this to hide leap months in Hebrew calendar.
+			var monthNames = this.dateLocaleModule.getNames('months', 'wide', 'standAlone', this.lang, month);
+			this.monthDropDownButton.dropDown.set("months", monthNames);
+
+			// 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.monthDropDownButton.containerNode.innerHTML =
+				(dojo.isIE == 6 ? "" : "<div class='dijitSpacer'>" + this.monthDropDownButton.dropDown.domNode.innerHTML + "</div>") + 
+				"<div class='dijitCalendarMonthLabel dijitCalendarCurrentMonthLabel'>" +  monthNames[month.getMonth()] + "</div>";
+
+			// Fill in localized prev/current/next years
+			var y = month.getFullYear() - 1;
+			var d = new this.dateClassObj();
+			dojo.forEach(["previous", "current", "next"], function(name){
+				d.setFullYear(y++);
+				this._setText(this[name+"YearLabelNode"],
+					this.dateLocaleModule.format(d, {selector:'year', locale:this.lang}));
+			}, this);
+		},
+
+		goToToday: function(){
+			// summary:
+			//      We go to today but we do no select it
+			this.set('currentFocus', new this.dateClassObj(), false);
+		},
+
+		constructor: function(/*Object*/args){
+			var dateClass = (args.datePackage && (args.datePackage != "dojo.date"))? args.datePackage + ".Date" : "Date";
+			this.dateClassObj = dojo.getObject(dateClass, false);
+			this.datePackage = args.datePackage || this.datePackage;
+			this.dateFuncObj = dojo.getObject(this.datePackage, false);
+			this.dateLocaleModule = dojo.getObject(this.datePackage + ".locale", false);
+		},
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			dojo.setSelectable(this.domNode, false);
+
+			var cloneClass = dojo.hitch(this, function(clazz, n){
+				var template = dojo.query(clazz, this.domNode)[0];
+	 			for(var i=0; i<n; i++){
+					template.parentNode.appendChild(template.cloneNode(true));
+				}
+			});
+
+			// clone the day label and calendar day templates 6 times to make 7 columns
+			cloneClass(".dijitCalendarDayLabelTemplate", 6);
+			cloneClass(".dijitCalendarDateTemplate", 6);
+
+			// now make 6 week rows
+			cloneClass(".dijitCalendarWeekTemplate", 5);
+
+			// insert localized day names in the header
+			var dayNames = this.dateLocaleModule.getNames('days', this.dayWidth, 'standAlone', this.lang);
+			var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
+			dojo.query(".dijitCalendarDayLabel", this.domNode).forEach(function(label, i){
+				this._setText(label, dayNames[(i + dayOffset) % 7]);
+			}, this);
+
+			var dateObj = new this.dateClassObj(this.currentFocus);
+
+			this.monthDropDownButton.dropDown = new dojox.widget._MonthDropDown({
+				id: this.id + "_mdd",
+				onChange: dojo.hitch(this, "_onMonthSelect")
+			});
+
+			this.set('currentFocus', dateObj, false);	// draw the grid to the month specified by currentFocus
+
+			// Set up repeating mouse behavior for increment/decrement of months/years
+			var _this = this;
+			var typematic = function(nodeProp, dateProp, adj){
+				_this._connects.push(
+					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);
+			typematic("nextYearLabelNode", "year", 1);
+			typematic("previousYearLabelNode", "year", -1);
+		},
+
+		_adjustDisplay: function(/*String*/ part, /*int*/ amount){
+			// summary:
+			//      Moves calendar forwards or backwards by months or years
+			// part:
+			//      "month" or "year"
+			// amount:
+			//      Number of months or years
+			// tags:
+			//      private
+			this._setCurrentFocusAttr(this.dateFuncObj.add(this.currentFocus, part, amount));
+		},
+
+		_setCurrentFocusAttr: function(/*Date*/ date, /*Boolean*/ forceFocus){
+			// summary:
+			//		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.
+			// forceFocus:
+			//		If true, will focus() the cell even if calendar itself doesn't have focus
+
+			var oldFocus = this.currentFocus,
+				oldCell = oldFocus ? dojo.query("[dijitDateValue=" + oldFocus.valueOf() + "]", this.domNode)[0] : 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); 
+
+			this._set("currentFocus", date);
+			var currentMonth = dojo.date.stamp.toISOString(date).substring(0,7);
+			//We only redraw the grid if we're in a new month
+			if(currentMonth != this.previousMonth){
+				this._populateGrid();
+				this.previousMonth = currentMonth;
+			}
+
+			// 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];
+			newCell.setAttribute("tabIndex", this.tabIndex);
+			if(this._focused || forceFocus){
+				newCell.focus();
+			}
+
+			// set tabIndex=-1 on old focusable cell
+			if(oldCell && oldCell != newCell){
+				if(dojo.isWebKit){	// see #11064 about webkit bug
+					oldCell.setAttribute("tabIndex", "-1");
+				}else{
+						oldCell.removeAttribute("tabIndex");				
+				}
+			}
+		},
+
+		focus: function(){
+			// summary:
+			//		Focus the calendar by focusing one of the calendar cells
+			this._setCurrentFocusAttr(this.currentFocus, true);
+		},
+
+		_onMonthSelect: function(/*Number*/ newMonth){
+			// summary:
+			//      Handler for when user selects a month from the drop down list
+			// tags:
+			//      protected
+
+			// move to selected month, bounding by the number of days in the month
+			// (ex: dec 31 --> jan 28, not jan 31)
+			this.currentFocus = this.dateFuncObj.add(this.currentFocus, "month",
+				newMonth - this.currentFocus.getMonth());
+			this._populateGrid();
+		},
+		
+		toggleDate : function(/*date*/ dateToToggle, /*array of dates*/ selectedDates, /*array of dates*/ unselectedDates){
+			
+			//Obtain CSS class before toggling if necessary
+			var dateIndex = dojo.date.stamp.toISOString(dateToToggle).substring(0,10);			 
+			//If previously selected we unselect and vice-versa
+			if(this.value[dateIndex]){
+				this.unselectDate(dateToToggle, unselectedDates);			
+			}else{
+				this.selectDate(dateToToggle, selectedDates);
+			}		
+		},
+		
+		selectDate : function(/*date*/ dateToSelect, /*array of dates*/ selectedDates){
+			//Selects the passed iso date, changes its class and records it in the selected dates array
+			var node = this._getNodeByDate(dateToSelect);
+			var clazz = node.className;
+			var dateIndex = dojo.date.stamp.toISOString(dateToSelect).substring(0,10);
+			this.value[dateIndex] = 1;
+			selectedDates.push(dateIndex);			
+			clazz = "dijitCalendarSelectedDate " + clazz;
+			//We update CSS class
+			node.className = clazz;
+		},
+		
+		unselectDate : function(/*date*/ dateToUnselect, /*array of dates*/ unselectedDates){
+			//Unselects the passed iso date, changes its class and records it in the unselected dates array
+			var node = this._getNodeByDate(dateToUnselect);
+			var clazz = node.className;
+			var dateIndex = dojo.date.stamp.toISOString(dateToUnselect).substring(0,10);
+			delete(this.value[dateIndex]);
+			unselectedDates.push(dateIndex);
+			clazz = clazz.replace("dijitCalendarSelectedDate ","");
+			//We update CSS class
+			node.className = clazz;
+		},
+
+		_getNodeByDate : function(/*ISO date*/ dateNode){
+			//return the node that corresponds to the passed ISO date
+			var firstDate = new this.dateClassObj(this.listOfNodes[0].dijitDateValue);
+			var difference = Math.abs(dojo.date.difference(firstDate, dateNode, "day"));
+			return this.listOfNodes[difference];
+		},
+
+		_onDayClick: function(/*Event*/ evt){
+			// summary:
+			//      Handler for day clicks, selects the date if appropriate
+			// tags:
+			//      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 
+			//selected
+				dojo.stopEvent(evt);
+				for(var node = evt.target; node && !node.dijitDateValue; node = node.parentNode);
+				if(node && !dojo.hasClass(node, "dijitCalendarDisabledDate")){
+					value = new this.dateClassObj(node.dijitDateValue);
+					if(!this.rangeJustSelected){
+						this.toggleDate(value,[],[]);
+						//To record the date that was selected prior to the one currently selected
+						//needed in the event we are selecting a range of dates
+						this.previouslySelectedDay = value;
+						this.set("currentFocus", value);
+						this.onValueSelected([dojo.date.stamp.toISOString(value).substring(0,10)]);
+						
+					}else{
+						this.rangeJustSelected = false;
+						this.set("currentFocus", value);
+					}
+				}
+		},
+
+		_onDayMouseOver: function(/*Event*/ evt){
+			// summary:
+			//      Handler for mouse over events on days, sets hovered style
+			// tags:
+			//      protected
+
+			// event can occur on <td> or the <span> inside the td,
+			// set node to the <td>.
+			var node =
+				dojo.hasClass(evt.target, "dijitCalendarDateLabel") ?
+				evt.target.parentNode :
+				evt.target;
+
+			if(node && (node.dijitDateValue || node == this.previousYearLabelNode || node == this.nextYearLabelNode) ){
+				dojo.addClass(node, "dijitCalendarHoveredDate");
+				this._currentNode = node;
+			}
+		},
+		_setEndRangeAttr: function(/*Date*/ value){
+			// description:
+			// 		records the end of a date range
+			// tags:
+			//      protected
+			value = new this.dateClassObj(value);
+			value.setHours(1); // to avoid issues when DST shift occurs at midnight, see #8521, #9366
+			this.endRange = value;
+		},
+		_getEndRangeAttr: function(){
+		//		Returns the EndRange date that is set when selecting a range
+			var value = new this.dateClassObj(this.endRange);
+			value.setHours(0, 0, 0, 0); // return midnight, local time for back-compat
+		
+			// 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.endRange.getDate()){
+				value = this.dateFuncObj.add(value, "hour", 1);
+			}
+			return value;
+		},
+
+		_onDayMouseOut: function(/*Event*/ evt){
+			// summary:
+			//      Handler for mouse out events on days, clears hovered style
+			// tags:
+			//      protected
+	
+			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; }
+			var cls = "dijitCalendarHoveredDate";
+			if(dojo.hasClass(this._currentNode, "dijitCalendarActiveDate")) {
+				cls += " dijitCalendarActiveDate";
+			}
+			dojo.removeClass(this._currentNode, cls);
+			this._currentNode = null;
+		},
+		_onDayMouseDown: function(/*Event*/ evt){ 
+			var node = evt.target.parentNode;
+			if(node && node.dijitDateValue){
+				dojo.addClass(node, "dijitCalendarActiveDate");
+				this._currentNode = node;
+			}
+			//if shift is pressed, we know the user is selecting a range,
+			//in which case we are going to select a range of date 
+			if(evt.shiftKey && this.previouslySelectedDay){
+				//necessary to know whether or not we are in the process of selecting a range of dates	
+				this.selectingRange = true;
+				this.set('endRange', node.dijitDateValue);
+				this._selectRange();
+			}else{
+				this.selectingRange = false;
+				this.previousRangeStart = null;
+				this.previousRangeEnd = null;
+			}
+		},
+		
+		_onDayMouseUp: function(/*Event*/ evt){
+			var node = evt.target.parentNode;
+			if(node && node.dijitDateValue){
+				dojo.removeClass(node, "dijitCalendarActiveDate");
+			}
+		},
+
+//TODO: use typematic
+		handleKey: function(/*Event*/ evt){
+			// 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
+			// 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
+			// tags:
+			//		protected
+			var dk = dojo.keys,
+				increment = -1,
+				interval,
+				newValue = this.currentFocus;
+			switch(evt.keyCode){
+				case dk.RIGHT_ARROW:
+					increment = 1;
+					//fallthrough...
+				case dk.LEFT_ARROW:
+					interval = "day";
+					if(!this.isLeftToRight()){ increment *= -1; }
+					break;
+				case dk.DOWN_ARROW:
+					increment = 1;
+					//fallthrough...
+				case dk.UP_ARROW:
+					interval = "week";
+					break;
+				case dk.PAGE_DOWN:
+					increment = 1;
+					//fallthrough...
+				case dk.PAGE_UP:
+					interval = evt.ctrlKey || evt.altKey ? "year" : "month";
+					break;
+				case dk.END:
+					// go to the next month
+					newValue = this.dateFuncObj.add(newValue, "month", 1);
+					// subtract a day from the result when we're done
+					interval = "day";
+					//fallthrough...
+				case dk.HOME:
+					newValue = new this.dateClassObj(newValue);
+					newValue.setDate(1);
+					break;
+				case dk.ENTER:
+				case dk.SPACE:
+					if(evt.shiftKey && this.previouslySelectedDay){
+						this.selectingRange = true;
+						this.set('endRange', newValue);
+						this._selectRange();
+					}else{
+						this.selectingRange = false;				
+						this.toggleDate(newValue,[],[]);
+						//We record the selected date as the previous one 
+						//In case we are selecting the first date of a range
+						this.previouslySelectedDay = newValue;
+						this.previousRangeStart = null;
+						this.previousRangeEnd = null;
+						this.onValueSelected([dojo.date.stamp.toISOString(newValue).substring(0,10)]);
+						
+					}
+					break;
+				default:
+					return true;
+			}
+
+			if(interval){
+				newValue = this.dateFuncObj.add(newValue, interval, increment);
+			}
+
+			this.set("currentFocus", newValue);
+
+			return false;
+		},
+
+		_onKeyPress: function(/*Event*/ evt){
+			// summary:
+			//		For handling keypress events on a stand alone calendar
+			if(!this.handleKey(evt)){
+				dojo.stopEvent(evt);
+			}
+		},
+		
+		_removeFromRangeLTR : function(/*date*/ beginning, /*date*/ end, /*array*/selectedDates, /*array*/unselectedDates){
+	//In this method we remove some dates from a range from left to right
+			difference = Math.abs(dojo.date.difference(beginning, end, "day"));
+			for(var i = 0; i <= difference; i++){
+				var nextDay = dojo.date.add(beginning, 'day',i);
+				this.toggleDate(nextDay, selectedDates, unselectedDates);
+			}
+			if(this.previousRangeEnd == null){
+				//necessary to keep track of the previous range's end date
+				this.previousRangeEnd = end;
+			}else{
+				if(dojo.date.compare(end, this.previousRangeEnd, 'date') > 0 )
+					this.previousRangeEnd = end;
+			}
+			if(this.previousRangeStart == null){
+				//necessary to keep track of the previous range's start date
+				this.previousRangeStart = end;
+			}else{
+				if(dojo.date.compare(end, this.previousRangeStart, 'date') > 0 )
+					this.previousRangeStart = end;
+			}
+			this.previouslySelectedDay = dojo.date.add(nextDay, 'day',1);	
+		},
+		_removeFromRangeRTL : function(/*date*/ beginning, /*date*/ end, /*array*/selectedDates, /*array*/unselectedDates){
+			//If the end of the range is earlier than the beginning (back in time), 
+			//we are going to start from the end and move backward 
+	
+			difference = Math.abs(dojo.date.difference(beginning, end, "day"));
+			for(var i = 0; i <= difference; i++){
+				var nextDay = dojo.date.add(beginning, 'day',-i);
+				this.toggleDate(nextDay, selectedDates, unselectedDates);
+			}
+			if(this.previousRangeEnd == null){
+				this.previousRangeEnd = end;
+			}else{
+				if(dojo.date.compare(end, this.previousRangeEnd, 'date') < 0 ){
+					this.previousRangeEnd = end;
+				}
+			}
+			if(this.previousRangeStart == null){
+				this.previousRangeStart = end;
+			}else{
+				if(dojo.date.compare(end, this.previousRangeStart, 'date') < 0 ){
+					this.previousRangeStart = end;
+				}
+			}
+			this.previouslySelectedDay = dojo.date.add(nextDay, 'day',-1);
+		},
+		_addToRangeRTL : function(/*date*/ beginning, /*date*/ end, /*array*/selectedDates, /*array*/unselectedDates){
+		
+			difference = Math.abs(dojo.date.difference(beginning, end, "day"));
+			//If the end of the range is earlier than the beginning (back in time), 
+			//we are going to start from the end and move backward 
+			for(var i = 1; i <= difference; i++){
+				var nextDay = dojo.date.add(beginning, 'day',-i);
+				this.toggleDate(nextDay, selectedDates, unselectedDates);
+			}
+	
+			if(this.previousRangeStart == null){
+				this.previousRangeStart = end;
+			}else{
+				if(dojo.date.compare(end, this.previousRangeStart, 'date') < 0 ){
+					this.previousRangeStart = end;
+				}
+			}
+			if(this.previousRangeEnd == null){
+				this.previousRangeEnd = beginning;
+			}else{
+				if(dojo.date.compare(beginning, this.previousRangeEnd, 'date') > 0 ){
+					this.previousRangeEnd = beginning;
+				}
+			}
+			this.previouslySelectedDay = nextDay;
+		},
+		_addToRangeLTR : function(/*date*/ beginning, /*date*/ end, /*array*/selectedDates, /*array*/unselectedDates){
+			//If the end of the range is later than the beginning, 
+			//adding dates from left to right
+			difference = Math.abs(dojo.date.difference(beginning, end, "day"));
+			for(var i = 1; i <= difference; i++){
+				var nextDay = dojo.date.add(beginning, 'day',i);
+				this.toggleDate(nextDay, selectedDates, unselectedDates);
+			}
+			if(this.previousRangeStart == null){
+				this.previousRangeStart = beginning;
+			}else{
+				if(dojo.date.compare(beginning, this.previousRangeStart, 'date') < 0 ){
+					this.previousRangeStart = beginning;
+				}
+			}
+			if(this.previousRangeEnd == null){
+				this.previousRangeEnd = end;
+			}else{
+				if(dojo.date.compare(end, this.previousRangeEnd, 'date') > 0 ){
+					this.previousRangeEnd = end;
+				}
+			}
+			this.previouslySelectedDay = nextDay;
+		},
+		_selectRange : function(){
+			//This method will toggle the dates in the selected range.
+			var selectedDates = []; //Will gather the list of ISO dates that are selected
+			var unselectedDates = []; //Will gather the list of ISO dates that are unselected
+			var beginning = this.previouslySelectedDay;
+			var end = this.get('endRange');
+			
+			if(!this.previousRangeStart && !this.previousRangeEnd){
+				removingFromRange = false;
+			}else{
+				if((dojo.date.compare(end, this.previousRangeStart, 'date') < 0) || (dojo.date.compare(end, this.previousRangeEnd, 'date') > 0)){
+				//We are adding to range
+					removingFromRange = false;
+				}else{// Otherwise we are removing from the range
+					removingFromRange = true;
+				}
+			}
+			if(removingFromRange == true){
+				if(dojo.date.compare(end, beginning, 'date') < 0){
+					//We are removing from the range, starting from the end (Right to left)
+					this._removeFromRangeRTL(beginning, end, selectedDates, unselectedDates);
+				}else{
+				//The end of the range is later in time than the beginning: We go from left to right
+					this._removeFromRangeLTR(beginning, end, selectedDates, unselectedDates);
+				}
+			}else{
+				//We are adding to the range
+				if(dojo.date.compare(end, beginning, 'date') < 0){
+					this._addToRangeRTL(beginning, end, selectedDates, unselectedDates);
+				}else{
+					this._addToRangeLTR(beginning, end, selectedDates, unselectedDates);
+				}
+			}
+			//We call the extension point with the changed dates
+			if(selectedDates.length > 0){
+				this.onValueSelected(selectedDates);
+			}
+			if(unselectedDates.length > 0){
+				this.onValueUnselected(unselectedDates);
+			}
+			this.rangeJustSelected = true; //Indicates that we just selected a range.
+		},
+
+		onValueSelected: function(/*array of ISO dates*/ dates){
+			// summary:
+			//		Notification that a date cell or more were selected.
+			// description:
+			//      Passes on the list of ISO dates that are selected
+			// tags:
+			//      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
+			// tags:
+			//      protected
+		},
+		onChange: function(/*Date*/ date){
+			// summary:
+			//		Called only when the selected date has changed
+		},
+
+		_isSelectedDate: function(/*Date*/ dateObject, /*String?*/ locale){
+			// summary:
+			//		Returns true if the passed date is part of the selected dates of the calendar
+			
+				dateIndex = dojo.date.stamp.toISOString(dateObject).substring(0,10);
+				return this.value[dateIndex];
+		},
+
+		isDisabledDate: function(/*Date*/ dateObject, /*String?*/ locale){
+			// summary:
+			//		May be overridden to disable certain dates in the calendar e.g. `isDisabledDate=dojo.date.locale.isWeekend`
+			// tags:
+			//      extension
+/*=====
+			return false; // Boolean
+=====*/
+		},
+
+		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.
+			// tags:
+			//      extension
+
+/*=====
+			return ""; // String
+=====*/
+		},
+		_sort : function(){
+			//This function returns a sorted version of the value array that represents the selected dates.
+			if(this.value == {}){return [];}
+			//We create an array of date objects with the dates that were selected by the user.
+			var selectedDates = [];
+			for (var selDate in this.value){
+				selectedDates.push(selDate);
+			}
+			//Actual sorting
+			selectedDates.sort(function(a, b){
+				var dateA=new Date(a), dateB=new Date(b);
+				return dateA-dateB;
+			});
+			return selectedDates;
+		},
+		_returnDatesWithIsoRanges : function(selectedDates /*Array of sorted ISO dates*/){
+		//this method receives a sorted array of dates and returns an array of dates and date ranges where
+		//such range exist. For instance when passed with selectedDates = ['2010-06-14', '2010-06-15', '2010-12-25']
+		//it would return [2010-06-14/2010-06-15,  '2010-12-25']
+		var returnDates = [];
+		if(selectedDates.length > 1){
+			//initialisation
+			var weHaveRange = false,
+				rangeCount = 0,
+				startRange = null,
+				lastDayRange = null,
+				previousDate = dojo.date.stamp.fromISOString(selectedDates[0]);
+			
+			for(var i = 1; i < selectedDates.length+1; i++){
+				currentDate = dojo.date.stamp.fromISOString(selectedDates[i]);
+				if(weHaveRange){
+				//We are in the middle of a range				
+					difference = Math.abs(dojo.date.difference(previousDate, currentDate, "day"));
+					if(difference == 1){
+						//we continue with the range
+						lastDayRange = currentDate;
+					}else{
+						//end of the range, reset variables for maybe the next range..
+						range = dojo.date.stamp.toISOString(startRange).substring(0,10)
+								+ "/" + dojo.date.stamp.toISOString(lastDayRange).substring(0,10);
+						returnDates.push(range);
+						weHaveRange = false;
+					}
+				}else{
+					//We are not in a range to begin with
+					difference = Math.abs(dojo.date.difference(previousDate, currentDate, "day"));
+					if(difference == 1){
+						//These are two consecutive dates: This is a range!
+						weHaveRange = true;
+						startRange = previousDate;
+						lastDayRange = currentDate;
+					}else{
+						//this is a standalone date
+						returnDates.push(dojo.date.stamp.toISOString(previousDate).substring(0,10));
+					}
+				}
+				previousDate = currentDate;
+			}
+			return returnDates;
+		}else{
+			//If there's only one selected date we return only it
+				return selectedDates;
+			}
+		}
+	}	
+);
+
+//FIXME: can we use dijit.Calendar._MonthDropDown directly?
+dojo.declare("dojox.widget._MonthDropDown", [dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
+	// summary:
+	//		The month drop down
+
+	// months: String[]
+	//		List of names of months, possibly w/some undefined entries for Hebrew leap months
+	//		(ex: ["January", "February", undefined, "April", ...])
+	months: [],
+
+	templateString: "<div class='dijitCalendarMonthMenu dijitMenu' " +
+		"dojoAttachEvent='onclick:_onClick,onmouseover:_onMenuHover,onmouseout:_onMenuHover'></div>",
+
+	_setMonthsAttr: function(/*String[]*/ months){
+		this.domNode.innerHTML = dojo.map(months, function(month, idx){
+				return month ? "<div class='dijitCalendarMonthLabel' month='" + idx +"'>" + month + "</div>" : "";
+			}).join("");
+	},
+
+	_onClick: function(/*Event*/ evt){
+		this.onChange(dojo.attr(evt.target, "month"));
+	},
+
+	onChange: function(/*Number*/ month){
+		// summary:
+		//		Callback when month is selected from drop down
+	},
+
+	_onMenuHover: function(evt){
+		dojo.toggleClass(evt.target, "dijitCalendarMonthLabelHover", evt.type == "mouseover");
+	}
+});
+
+return dojox.widget.MultiSelectCalendar;
+});
diff --git a/dijit/templates/Calendar.html b/dojox/widget/MultiSelectCalendar/MultiSelectCalendar.html
similarity index 100%
copy from dijit/templates/Calendar.html
copy to dojox/widget/MultiSelectCalendar/MultiSelectCalendar.html
diff --git a/dojox/widget/PlaceholderMenuItem.js b/dojox/widget/PlaceholderMenuItem.js
index 6f939db..e3fec6b 100644
--- a/dojox/widget/PlaceholderMenuItem.js
+++ b/dojox/widget/PlaceholderMenuItem.js
@@ -1,9 +1,6 @@
-dojo.provide("dojox.widget.PlaceholderMenuItem");
-
+define(["dojo", "dijit", "dojox", "dijit/Menu","dijit/MenuItem"], function(dojo, dijit, dojox){
 dojo.experimental("dojox.widget.PlaceholderMenuItem");
 
-dojo.require("dijit.Menu");
-
 dojo.declare("dojox.widget.PlaceholderMenuItem", dijit.MenuItem, {
 	// summary:
 	//		A menu item that can be used as a placeholder.  Set the label
@@ -104,4 +101,7 @@ dojo.extend(dijit.Menu, {
 		}, this);
 		return r; // dojox.widget.PlaceholderMenuItem[]
 	}
-}); 
\ No newline at end of file
+});
+
+return dojox.widget.PlaceholderMenuItem;
+});
diff --git a/dojox/widget/Roller.js b/dojox/widget/Roller.js
index 1359c4c..f177374 100644
--- a/dojox/widget/Roller.js
+++ b/dojox/widget/Roller.js
@@ -1,228 +1,231 @@
-dojo.provide("dojox.widget.Roller");
-dojo.require("dijit._Widget");
-
-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
-	//		to style it) and loops continually, fading between items.
-	//
-	//		In it's current state, it requires it be created from an unordered (or ordered)
-	//		list, though can contain complex markup.
-	//
-	//		You can manipulate the `items` array at any point during the cycle with
-	//		standard array manipulation techniques.
-	//
-	//		The class "dojoxRoller" is added to the UL element for styling purposes.
-	//
-	//	example:
-	//	|	// create a scroller from a unordered list with id="lister"
-	//  |	var thinger = new dojox.widget.Roller.Roller({},"lister");
-	//
-	//	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:
-	//	|	// add an item:
-	//	|	dijit.byId("roller").items.push("I am a new Label");
-	//
-	//  example:
-	//	|	// stop a roller from rolling:
-	//	|	dijit.byId("roller").stop();
-	//
-	// delay: Integer
-	//		Interval between rolls
-	delay: 2000,
-
-	// autoStart: Boolean
-	//		Toggle to control starup behavior. Call .start() manually
-	//		if set to `false`
-	autoStart: true,
-	
-	// itemSelector: String
-	//		A CSS selector to be used by `dojo.query` to find the children
-	//		items in this widget. Defaults to "> li", finding only first-children
-	//		list-items in the list, allowing for embedded lists to occur.
-	itemSelector: "> li",
-	
-	// durationIn: Integer
-	// 		Speed (in ms) to apply to the "in" animation (show the node)
-	durationIn: 400,
-	
-	// durationOut: Integer
-	//		Speed (in ms) to apply to the "out" animation (hide the showing node)
-	durationOut: 275,
-/*=====
-	// items: Array
-	//		If populated prior to instantiation, is used as the Items over the children
-	items: [],
-=====*/
-
-	// _idx: Integer
-	//		Index of the the currently visible item in the list of items[]
-	_idx: -1,
-	
-	postCreate: function(){
+define(["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit){
 
-		// add some instance vars:
-		if(!this["items"]){
-			this.items = [];
-		}
-		
-		dojo.addClass(this.domNode,"dojoxRoller");
-		
-		// find all the items in this list, and popuplate
-		dojo.query(this.itemSelector, this.domNode).forEach(function(item, i){
-			this.items.push(item.innerHTML);
-			// reuse the first match, destroy the rest
-			if(i == 0){
-				this._roller = item;
-				this._idx = 0;
-			}else{ dojo.destroy(item); }
-		}, this);
-		
-		// handle the case where items[] were passed, and no srcNodeRef exists
-		if(!this._roller){
-			this._roller = dojo.create('li', null, this.domNode);
-		}
-		// stub out animation creation (for overloading maybe later)
-		this.makeAnims();
-		
-		// and start, if true:
-		if(this.autoStart){ this.start(); }
-		
-	},
-
-	makeAnims: function(){
-		// 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, {
-			_anim: {
-				"in": dojo.fadeIn({ node:n, duration: this.durationIn }),
-				"out": dojo.fadeOut({ node:n, duration: this.durationOut })
-			}
-		});
-		this._setupConnects();
-		
-	},
-	
-	_setupConnects: function(){
-		// summary: setup the loop connection logic
-		var anim = this._anim;
-
-		this.connect(anim["out"], "onEnd", function(){
-			// onEnd of the `out` animation, select the next items and play `in` animation
-			this._setIndex(this._idx + 1);
-			anim["in"].play(15);
-		});
-		
-		this.connect(anim["in"], "onEnd", function(){
-			// onEnd of the `in` animation, call `start` again after some delay:
-			this._timeout = setTimeout(dojo.hitch(this, "_run"), this.delay);
-		});
-	},
-	
-	start: function(){
-		// summary: Starts to Roller looping
-		if(!this.rolling){
-			this.rolling = true;
-			this._run();
-		}
-	},
-	
-	_run: function(){
-		this._anim["out"].gotoPercent(0, true);
-	},
+	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
+		//		to style it) and loops continually, fading between items.
+		//
+		//		In it's current state, it requires it be created from an unordered (or ordered)
+		//		list, though can contain complex markup.
+		//
+		//		You can manipulate the `items` array at any point during the cycle with
+		//		standard array manipulation techniques.
+		//
+		//		The class "dojoxRoller" is added to the UL element for styling purposes.
+		//
+		//	example:
+		//	|	// create a scroller from a unordered list with id="lister"
+		//  |	var thinger = new dojox.widget.Roller.Roller({},"lister");
+		//
+		//	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:
+		//	|	// add an item:
+		//	|	dijit.byId("roller").items.push("I am a new Label");
+		//
+		//  example:
+		//	|	// stop a roller from rolling:
+		//	|	dijit.byId("roller").stop();
+		//
+		// delay: Integer
+		//		Interval between rolls
+		delay: 2000,
 
-	stop: function(){
-		// summary: Stops the Roller from looping anymore.
-		this.rolling = false;
+		// autoStart: Boolean
+		//		Toggle to control starup behavior. Call .start() manually
+		//		if set to `false`
+		autoStart: true,
 
-		var m = this._anim,
-			t = this._timeout;
+		// itemSelector: String
+		//		A CSS selector to be used by `dojo.query` to find the children
+		//		items in this widget. Defaults to "> li", finding only first-children
+		//		list-items in the list, allowing for embedded lists to occur.
+		itemSelector: "> li",
 
-		if(t){ clearTimeout(t); }
-		m["in"].stop();
-		m["out"].stop();
-	},
-	
-	_setIndex: function(i){
-		// 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; }
-		this._roller.innerHTML = this.items[i] || "error!";
-		this._idx = i;
-	}
+		// durationIn: Integer
+		// 		Speed (in ms) to apply to the "in" animation (show the node)
+		durationIn: 400,
 
-});
+		// durationOut: Integer
+		//		Speed (in ms) to apply to the "out" animation (hide the showing node)
+		durationOut: 275,
+	/*=====
+		// items: Array
+		//		If populated prior to instantiation, is used as the Items over the children
+		items: [],
+	=====*/
 
-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
-		//		will reuse.
-
-		var n = this.domNode, pos = "position",
-			props = {
-				top: { end: 0, start: 25 },
-				opacity: 1
+		// _idx: Integer
+		//		Index of the the currently visible item in the list of items[]
+		_idx: -1,
+
+		postCreate: function(){
+
+			// add some instance vars:
+			if(!this["items"]){
+				this.items = [];
 			}
-		;
-		
-		dojo.style(n, pos, "relative");
-		dojo.style(this._roller, pos, "absolute");
-
-		dojo.mixin(this, {
-			_anim: {
-				
-				"in": dojo.animateProperty({
-					node: n,
-					duration: this.durationIn,
-					properties: props
-				}),
-				
-				"out": dojo.fadeOut({ node: n, duration: this.durationOut })
+
+			dojo.addClass(this.domNode,"dojoxRoller");
+
+			// find all the items in this list, and popuplate
+			dojo.query(this.itemSelector, this.domNode).forEach(function(item, i){
+				this.items.push(item.innerHTML);
+				// reuse the first match, destroy the rest
+				if(i == 0){
+					this._roller = item;
+					this._idx = 0;
+				}else{ dojo.destroy(item); }
+			}, this);
+
+			// handle the case where items[] were passed, and no srcNodeRef exists
+			if(!this._roller){
+				this._roller = dojo.create('li', null, this.domNode);
 			}
-		});
-		// don't forget to do this in the class. override if necessary.
-		this._setupConnects();
-	}
-	
-});
+			// stub out animation creation (for overloading maybe later)
+			this.makeAnims();
+
+			// and start, if true:
+			if(this.autoStart){ this.start(); }
+
+		},
+
+		makeAnims: function(){
+			// 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, {
+				_anim: {
+					"in": dojo.fadeIn({ node:n, duration: this.durationIn }),
+					"out": dojo.fadeOut({ node:n, duration: this.durationOut })
+				}
+			});
+			this._setupConnects();
+
+		},
+
+		_setupConnects: function(){
+			// summary: setup the loop connection logic
+			var anim = this._anim;
+
+			this.connect(anim["out"], "onEnd", function(){
+				// onEnd of the `out` animation, select the next items and play `in` animation
+				this._setIndex(this._idx + 1);
+				anim["in"].play(15);
+			});
+
+			this.connect(anim["in"], "onEnd", function(){
+				// onEnd of the `in` animation, call `start` again after some delay:
+				this._timeout = setTimeout(dojo.hitch(this, "_run"), this.delay);
+			});
+		},
+
+		start: function(){
+			// summary: Starts to Roller looping
+			if(!this.rolling){
+				this.rolling = true;
+				this._run();
+			}
+		},
+
+		_run: function(){
+			this._anim["out"].gotoPercent(0, true);
+		},
+
+		stop: function(){
+			// summary: Stops the Roller from looping anymore.
+			this.rolling = false;
+
+			var m = this._anim,
+				t = this._timeout;
+
+			if(t){ clearTimeout(t); }
+			m["in"].stop();
+			m["out"].stop();
+		},
+
+		_setIndex: function(i){
+			// 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; }
+			this._roller.innerHTML = this.items[i] || "error!";
+			this._idx = i;
+		}
+
+	});
+
+	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
+			//		will reuse.
+
+			var n = this.domNode, pos = "position",
+				props = {
+					top: { end: 0, start: 25 },
+					opacity: 1
+				}
+			;
+
+			dojo.style(n, pos, "relative");
+			dojo.style(this._roller, pos, "absolute");
+
+			dojo.mixin(this, {
+				_anim: {
+
+					"in": dojo.animateProperty({
+						node: n,
+						duration: this.durationIn,
+						properties: props
+					}),
+
+					"out": dojo.fadeOut({ node: n, duration: this.durationOut })
+				}
+			});
+			// don't forget to do this in the class. override if necessary.
+			this._setupConnects();
+		}
+
+	});
+
+	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.
+		//		Simply mix this class into a `dojox.widget.Roller` variant, and instantiate
+		//		as you would. The hover connection is done automatically.
+		//
+		//		The "hover" functionality is as such: Stop rotation while the mouse is over the
+		//		instance, and resume again once leaving. Even if autoStart is disabled, the widget
+		//		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");
+
+		postCreate: function(){
+			this.inherited(arguments);
+			this.connect(this.domNode, "onmouseenter", "stop");
+			this.connect(this.domNode, "onmouseleave", "start");
+		}
 
-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.
-	//		Simply mix this class into a `dojox.widget.Roller` variant, and instantiate
-	//		as you would. The hover connection is done automatically.
-	//
-	//		The "hover" functionality is as such: Stop rotation while the mouse is over the
-	//		instance, and resume again once leaving. Even if autoStart is disabled, the widget
-	//		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");
+	});
 	
-	postCreate: function(){
-		this.inherited(arguments);
-		this.connect(this.domNode, "onmouseenter", "stop");
-		this.connect(this.domNode, "onmouseleave", "start");
-	}
+	return dojox.widget.Roller;
 	
 });
diff --git a/dojox/widget/RollingList.js b/dojox/widget/RollingList.js
index 674dbb1..413b567 100644
--- a/dojox/widget/RollingList.js
+++ b/dojox/widget/RollingList.js
@@ -9,6 +9,8 @@ dojo.require("dijit._Contained");
 dojo.require("dijit.layout._LayoutWidget");
 dojo.require("dijit.Menu");
 dojo.require("dijit.form.Button");
+dojo.require("dijit.focus");		// dijit.focus()
+dojo.require("dijit._base.focus");	// dijit.getFocus()
 
 dojo.require("dojox.html.metrics");
 
diff --git a/dojox/widget/Standby.js b/dojox/widget/Standby.js
index 957d9d4..2f9bdbb 100755
--- a/dojox/widget/Standby.js
+++ b/dojox/widget/Standby.js
@@ -1,8 +1,42 @@
-define("dojox/widget/Standby", ["dojo", "dijit", "dojox", "dojo/window", "dojo/fx", "dijit/_Widget", "dijit/_Templated"], function(dojo, dijit, dojox) {
-
-dojo.experimental("dojox.widget.Standby");
-
-dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
+define(["dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/event",
+	"dojo/_base/sniff",
+	"dojo/dom",
+	"dojo/dom-attr",
+	"dojo/dom-construct",
+	"dojo/dom-geometry",
+	"dojo/dom-style",
+	"dojo/window",
+	"dojo/_base/window",
+	"dojo/_base/fx",
+	"dojo/fx",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dijit/registry"],
+
+function(kernel,
+		declare,
+		array,
+		event,
+		has,
+		dom,
+		attr,
+		construct,
+		geometry,
+		domStyle,
+		window,
+		baseWindow,
+		baseFx,
+		fx,
+		_Widget,
+		_TemplatedMixin,
+		registry) {
+
+kernel.experimental("dojox.widget.Standby");
+
+return declare("dojox.widget.Standby", [_Widget, _TemplatedMixin],{
 	// summary:
 	//		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.
@@ -72,11 +106,11 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 
 	// image: String
 	//		The URL to the image to center in the overlay.
-	image: dojo.moduleUrl("dojox", "widget/Standby/images/loading.gif").toString(),
+	image: require.toUrl("dojox/widget/Standby/images/loading.gif").toString(),
 
 	// imageText: String
 	//		Text for the ALT tag.
-	imageText: "Please Wait...",
+	imageText: "Please Wait...", // TODO: i18n
 
 	// text: String
 	//		Text/HTML to display in the center of the overlay
@@ -134,12 +168,8 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		//		Configures the target node and sets the image to use.
 		if(!this._started){
 			if(typeof this.target === "string"){
-				var w = dijit.byId(this.target);
-				if(w){
-					this.target = w.domNode;
-				}else{
-					this.target = dojo.byId(this.target);
-				}
+				var w = registry.byId(this.target);
+				this.target = w ? w.domNode : dom.byId(this.target);
 			}
 
 			if(this.text){
@@ -147,38 +177,39 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 			}
 			if(this.centerIndicator === "image"){
 				this._centerNode = this._imageNode;
-				dojo.attr(this._imageNode, "src", this.image);
-				dojo.attr(this._imageNode, "alt", this.imageText);
+				attr.set(this._imageNode, "src", this.image);
+				attr.set(this._imageNode, "alt", this.imageText);
 			}else{
 				this._centerNode = this._textNode;
 			}
-			dojo.style(this._underlayNode, {
+			domStyle.set(this._underlayNode, {
 				display: "none",
 				backgroundColor: this.color
 			});
-			dojo.style(this._centerNode, "display", "none");
+			domStyle.set(this._centerNode, "display", "none");
 			this.connect(this._underlayNode, "onclick", "_ignore");
 
 			//Last thing to do is move the widgets parent, if any, to the current document body.
 			//Avoids having to deal with parent relative/absolute mess.  Otherwise positioning
 			//tends to go goofy.
-			if(this.domNode.parentNode && this.domNode.parentNode != dojo.body()){
-				dojo.body().appendChild(this.domNode);
+			if(this.domNode.parentNode && this.domNode.parentNode != baseWindow.body()){
+				baseWindow.body().appendChild(this.domNode);
 			}
 
 			//IE 7 has a horrible bug with zoom, so we have to create this node
 			//to cross-check later.  Sigh.
-			if(dojo.isIE == 7){
-				this._ieFixNode = dojo.doc.createElement("div");
-				dojo.style(this._ieFixNode, {
+			if(has("ie") == 7){
+				this._ieFixNode = construct.create("div");
+				domStyle.set(this._ieFixNode, {
 					opacity: "0",
 					zIndex: "-1000",
 					position: "absolute",
 					top: "-1000px"
 				});
-				dojo.body().appendChild(this._ieFixNode);
+				baseWindow.body().appendChild(this._ieFixNode);
 			}
-		}
+			this.inherited(arguments);
+		}		
 	},
 
 	show: function(){
@@ -239,10 +270,10 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		if(this._resizeCheck){
 			clearInterval(this._resizeCheck);
 		}
-		dojo.style(this._centerNode, "display", "none");
-		dojo.style(this._underlayNode, "display", "none");
-		if(dojo.isIE == 7){
-			dojo.body().removeChild(this._ieFixNode);
+		domStyle.set(this._centerNode, "display", "none");
+		domStyle.set(this._underlayNode, "display", "none");
+		if(has("ie") == 7 && this._ieFixNode){
+			baseWindow.body().removeChild(this._ieFixNode);
 			delete this._ieFixNode;
 		}
 		if(this._anim){
@@ -263,7 +294,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		// tags:
 		//		private
 		if(this._displayed){
-			var dir = dojo.attr(dojo.body(), "dir");
+			var dir = attr.get(baseWindow.body(), "dir");
 			if(dir){dir = dir.toLowerCase();}
 			var _ie7zoom;
 			var scrollers = this._scrollerWidths();
@@ -271,18 +302,18 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 			var target = this.target;
 
 			//Show the image and make sure the zIndex is set high.
-			var curStyle = dojo.style(this._centerNode, "display");
-			dojo.style(this._centerNode, "display", "block");
-			var box = dojo.position(target, true);
-			if(target === dojo.body() || target === dojo.doc){
+			var curStyle = domStyle.get(this._centerNode, "display");
+			domStyle.set(this._centerNode, "display", "block");
+			var box = geometry.position(target, true);
+			if(target === baseWindow.body() || target === baseWindow.doc){
 				// Target is the whole doc, so scale to viewport.
-				box = dojo.window.getBox();
+				box = window.getBox();
 				box.x = box.l;
 				box.y = box.t;
 			}
 
-			var cntrIndicator = dojo.marginBox(this._centerNode);
-			dojo.style(this._centerNode, "display", curStyle);
+			var cntrIndicator = geometry.getMarginBox(this._centerNode);
+			domStyle.set(this._centerNode, "display", curStyle);
 
 			//IE has a horrible zoom bug.  So, we have to try and account for
 			//it and fix up the scaling.
@@ -295,7 +326,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 			}
 
 			//Figure out how to zIndex this thing over the target.
-			var zi = dojo.style(target, "zIndex");
+			var zi = domStyle.get(target, "zIndex");
 			var ziUl = zi;
 			var ziIn = zi;
 
@@ -308,8 +339,8 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 					//are any parent zIndexs to overlay.
 					var cNode = target.parentNode;
 					var oldZi = -100000;
-					while(cNode && cNode !== dojo.body()){
-						zi = dojo.style(cNode, "zIndex");
+					while(cNode && cNode !== baseWindow.body()){
+						zi = domStyle.get(cNode, "zIndex");
 						if(!zi || zi === "auto"){
 							cNode = cNode.parentNode;
 						}else{
@@ -329,14 +360,14 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 				ziIn = parseInt(this.zIndex, 10) + 2;
 			}
 
-			dojo.style(this._centerNode, "zIndex", ziIn);
-			dojo.style(this._underlayNode, "zIndex", ziUl);
+			domStyle.set(this._centerNode, "zIndex", ziIn);
+			domStyle.set(this._underlayNode, "zIndex", ziUl);
 
 
 			var pn = target.parentNode;
-			if(pn && pn !== dojo.body() &&
-				target !== dojo.body() &&
-				target !== dojo.doc){
+			if(pn && pn !== baseWindow.body() &&
+				target !== baseWindow.body() &&
+				target !== baseWindow.doc){
 				
 				// If the parent is the body tag itself,
 				// we can avoid all this, the body takes
@@ -346,7 +377,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 				// anyway.
 				var obh = box.h;
 				var obw = box.w;
-				var pnBox = dojo.position(pn, true);
+				var pnBox = geometry.position(pn, true);
 
 				//More IE zoom corrections.  Grr.
 				if(this._ieFixNode){
@@ -367,15 +398,15 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 				//(and differently depending on browser, ugh!)
 				//WebKit and others still need work.
 				if(dir === "rtl"){
-					if(dojo.isOpera){
+					if(has("opera")){
 						box.x += pn.scrollHeight > pn.clientHeight &&
 							pn.clientHeight > 0 ? scrollers.v: 0;
 						pnBox.x += pn.scrollHeight > pn.clientHeight &&
 							pn.clientHeight > 0 ? scrollers.v: 0;
-					}else if(dojo.isIE){
+					}else if(has("ie")){
 						pnBox.x += pn.scrollHeight > pn.clientHeight &&
 							pn.clientHeight > 0 ? scrollers.v: 0;
-					}else if(dojo.isWebKit){
+					}else if(has("webkit")){
 						//TODO:  FIX THIS!
 					}
 				}
@@ -455,7 +486,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 
 			if(box.h > 0 && box.w > 0){
 				//Set position and size of the blocking div overlay.
-				dojo.style(this._underlayNode, {
+				domStyle.set(this._underlayNode, {
 					display: "block",
 					width: box.w + "px",
 					height: box.h + "px",
@@ -467,7 +498,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 					"borderTopRightRadius","borderBottomLeftRadius",
 					"borderBottomRightRadius"];
 				this._cloneStyles(styles);
-				if(!dojo.isIE){
+				if(!has("ie")){
 					//Browser specific styles to try and clone if non-IE.
 					styles = ["MozBorderRadius", "MozBorderRadiusTopleft",
 						"MozBorderRadiusTopright","MozBorderRadiusBottomleft",
@@ -481,18 +512,18 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 				var cntrIndicatorLeft = (box.w/2) - (cntrIndicator.w/2);
 				//Only show the image if there is height and width room.
 				if(box.h >= cntrIndicator.h && box.w >= cntrIndicator.w){
-					dojo.style(this._centerNode, {
+					domStyle.set(this._centerNode, {
 						top: (cntrIndicatorTop + box.y) + "px",
 						left: (cntrIndicatorLeft + box.x) + "px",
 						display: "block"
 					});
 				}else{
-					dojo.style(this._centerNode, "display", "none");
+					domStyle.set(this._centerNode, "display", "none");
 				}
 			}else{
 				//Target has no size, display nothing on it!
-				dojo.style(this._underlayNode, "display", "none");
-				dojo.style(this._centerNode, "display", "none");
+				domStyle.set(this._underlayNode, "display", "none");
+				domStyle.set(this._centerNode, "display", "none");
 			}
 			if(this._resizeCheck === null){
 				//Set an interval timer that checks the target size and scales as needed.
@@ -512,8 +543,8 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		//
 		// tags:
 		//		private
-		dojo.forEach(list, function(style){
-			dojo.style(this._underlayNode,style,dojo.style(this.target,style));
+		array.forEach(list, function(s){
+			domStyle.set(this._underlayNode, s, domStyle.get(this.target, s));
 		}, this);
 	},
 
@@ -523,12 +554,12 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		// tags:
 		//		private
 		var self = this;
-		var underlayNodeAnim = dojo.animateProperty({
+		var underlayNodeAnim = baseFx.animateProperty({
 			duration: self.duration,
 			node: self._underlayNode,
 			properties: {opacity: {start: 0, end: 0.75}}
 		});
-		var imageAnim = dojo.animateProperty({
+		var imageAnim = baseFx.animateProperty({
 			duration: self.duration,
 			node: self._centerNode,
 			properties: {opacity: {start: 0, end: 1}},
@@ -537,7 +568,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 				delete self._anim;
 			}
 		});
-		this._anim = dojo.fx.combine([underlayNodeAnim,imageAnim]);
+		this._anim = fx.combine([underlayNodeAnim,imageAnim]);
 		this._anim.play();
 	},
 
@@ -547,38 +578,38 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		// tags:
 		//		private
 		var self = this;
-		var underlayNodeAnim = dojo.animateProperty({
+		var underlayNodeAnim = baseFx.animateProperty({
 			duration: self.duration,
 			node: self._underlayNode,
 			properties: {opacity: {start: 0.75, end: 0}},
 			onEnd: function(){
-				dojo.style(this.node,{"display":"none", "zIndex": "-1000"});
+				domStyle.set(this.node,{"display":"none", "zIndex": "-1000"});
 			}
 		});
-		var imageAnim = dojo.animateProperty({
+		var imageAnim = baseFx.animateProperty({
 			duration: self.duration,
 			node: self._centerNode,
 			properties: {opacity: {start: 1, end: 0}},
 			onEnd: function(){
-				dojo.style(this.node,{"display":"none", "zIndex": "-1000"});
+				domStyle.set(this.node,{"display":"none", "zIndex": "-1000"});
 				self.onHide();
 				self._enableOverflow();
 				delete self._anim;
 			}
 		});
-		this._anim = dojo.fx.combine([underlayNodeAnim,imageAnim]);
+		this._anim = fx.combine([underlayNodeAnim,imageAnim]);
 		this._anim.play();
 	},
 
-	_ignore: function(event){
+	_ignore: function(e){
 		// summary:
 		//		Function to ignore events that occur on the overlay.
 		// event: Event
 		//		The event to halt
 		// tags:
 		//		private
-		if(event){
-			dojo.stopEvent(event);
+		if(e){
+			event.stop(e);
 		}
 	},
 
@@ -591,8 +622,8 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		//		and h is horizontal scrollbar width.
 		// tags:
 		//		private
-		var div = dojo.doc.createElement("div");
-		dojo.style(div, {
+		var div = construct.create("div");
+		domStyle.set(div, {
 			position: "absolute",
 			opacity: 0,
 			overflow: "hidden",
@@ -600,25 +631,24 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 			height: "50px",
 			zIndex: "-100",
 			top: "-200px",
-			left: "-200px",
 			padding: "0px",
 			margin: "0px"
 		});
-		var iDiv = dojo.doc.createElement("div");
-		dojo.style(iDiv, {
+		var iDiv = construct.create("div");
+		domStyle.set(iDiv, {
 			width: "200px",
 			height: "10px"
 		});
 		div.appendChild(iDiv);
-		dojo.body().appendChild(div);
+		baseWindow.body().appendChild(div);
 
 		//Figure out content size before and after
 		//scrollbars are there, then just subtract to
 		//get width.
-		var b = dojo.contentBox(div);
-		dojo.style(div, "overflow", "scroll");
-		var a = dojo.contentBox(div);
-		dojo.body().removeChild(div);
+		var b = geometry.getContentBox(div);
+		domStyle.set(div, "overflow", "scroll");
+		var a = geometry.getContentBox(div);
+		baseWindow.body().removeChild(div);
 		return { v: b.w - a.w, h: b.h - a.h };
 	},
 
@@ -640,7 +670,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		//		div overlay.
 		// c: String
 		//		The color to set the background underlay to in #XXXXXX format..
-		dojo.style(this._underlayNode, "backgroundColor", c);
+		domStyle.set(this._underlayNode, "backgroundColor", c);
 		this.color = c;
 	},
 
@@ -650,7 +680,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		//		the image (if using image center display).
 		// text: String
 		//		The text to set.
-		dojo.attr(this._imageNode, "alt", text);
+		attr.set(this._imageNode, "alt", text);
 		this.imageText = text;
 	},
 
@@ -659,7 +689,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		//		Function to allow widget.attr to set the url source for the center image
 		// text: String
 		//		The url to set for the image.
-		dojo.attr(this._imageNode, "src", url);
+		attr.set(this._imageNode, "src", url);
 		this.image = url;
 	},
 
@@ -672,10 +702,10 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		this.centerIndicator = indicator;
 		if(indicator === "image"){
 			this._centerNode = this._imageNode;
-			dojo.style(this._textNode, "display", "none");
+			domStyle.set(this._textNode, "display", "none");
 		}else{
 			this._centerNode = this._textNode;
-			dojo.style(this._imageNode, "display", "none");
+			domStyle.set(this._imageNode, "display", "none");
 		}
 	},
 
@@ -683,17 +713,17 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		 // summary:
 		 //		Function to disable scrollbars on the body.  Only used if the overlay
 		 //		targets the body or the document.
-		 if(this.target === dojo.body() || this.target === dojo.doc){
+		 if(this.target === baseWindow.body() || this.target === baseWindow.doc){
 			 // Store the overflow state we have to restore later.
 			 // IE had issues, so have to check that it's defined.  Ugh.
 			 this._overflowDisabled = true;
-			 var body = dojo.body();
+			 var body = baseWindow.body();
 			 if(body.style && body.style.overflow){
-				 this._oldOverflow = dojo.style(body, "overflow");
+				 this._oldOverflow = domStyle.set(body, "overflow");
 			 }else{
 				 this._oldOverflow = "";
 			 }
-			 if(dojo.isIE && !dojo.isQuirks){
+			 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.
@@ -703,14 +733,14 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 					 this._oldBodyParentOverflow = body.parentNode.style.overflow;
 				 }else{
 					 try{
-						this._oldBodyParentOverflow = dojo.style(body.parentNode, "overflow");
+						this._oldBodyParentOverflow = domStyle.set(body.parentNode, "overflow");
 					 }catch(e){
 						 this._oldBodyParentOverflow = "scroll";
 					 }
 				 }
-				 dojo.style(body.parentNode, "overflow", "hidden");
+				 domStyle.set(body.parentNode, "overflow", "hidden");
 			 }
-			 dojo.style(body, "overflow", "hidden");
+			 domStyle.set(body, "overflow", "hidden");
 		 }
 	},
 
@@ -720,16 +750,16 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		 //		targets the body or the document.
 		 if(this._overflowDisabled){
 			delete this._overflowDisabled;
-			var body = dojo.body();
+			var body = baseWindow.body();
 			// Restore all the overflow.
-			if(dojo.isIE && !dojo.isQuirks){
+			if(has("ie") && !has("quirks")){
 				body.parentNode.style.overflow = this._oldBodyParentOverflow;
 				delete this._oldBodyParentOverflow;
 			}
-			dojo.style(body, "overflow", this._oldOverflow);
-			if(dojo.isWebKit){
+			domStyle.set(body, "overflow", this._oldOverflow);
+			if(has("webkit")){
 				//Gotta poke WebKit, or scrollers don't come back. :-(
-				var div = dojo.create("div", { style: {
+				var div = construct.create("div", { style: {
 						height: "2px"
 					}
 				});
@@ -743,6 +773,4 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 	}
 });
 
-return dojox.widget.Standby;
-
 });
diff --git a/dojox/widget/TitleGroup.js b/dojox/widget/TitleGroup.js
index 96461e3..e06cccf 100644
--- a/dojox/widget/TitleGroup.js
+++ b/dojox/widget/TitleGroup.js
@@ -1,11 +1,6 @@
-dojo.provide("dojox.widget.TitleGroup");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit.TitlePane");
-
-(function(d){
+define(["dojo", "dijit/registry", "dijit/_Widget", "dijit/TitlePane"], function(dojo, registry, widget, titlepane){
 	
-	var tp = dijit.TitlePane.prototype,
+	var tp = titlepane.prototype,
 		lookup = function(){
 			// generic handler function for click and keypress
 			var parent = this._dxfindParent && this._dxfindParent();
@@ -16,26 +11,26 @@ dojo.require("dijit.TitlePane");
 	// 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
-		//		`dojox.widget.TitleGroup`. Find a possible parent TitleGroup of a TitlePane
+		//		`dojox.widget.TitleGroup`. Finds a possible parent TitleGroup of a TitlePane
 		var n = this.domNode.parentNode;
 		if(n){
-			n = dijit.getEnclosingWidget(n);
+			n = registry.getEnclosingWidget(n);
 			return n && n instanceof dojox.widget.TitleGroup && n;
 		}
 		return n;
 	};
 
 	// if we click our own title, hide everyone
-	d.connect(tp, "_onTitleClick", lookup);
-	d.connect(tp, "_onTitleKey", function(e){
+	dojo.connect(tp, "_onTitleClick", lookup);
+	dojo.connect(tp, "_onTitleKey", function(e){
 		// if we're tabbing through the items in a group, don't do toggles.
 		// if we hit enter, let it happen.
-		if(!(e && e.type && e.type == "keypress" && e.charOrCode == d.keys.TAB)){
+		if(!(e && e.type && e.type == "keypress" && e.charOrCode == dojo.keys.TAB)){
 			lookup.apply(this, arguments);
 		}
 	});
 		
-	d.declare("dojox.widget.TitleGroup", dijit._Widget, {
+	return dojo.declare("dojox.widget.TitleGroup", dijit._Widget, {
 		// summary: A container which controls a series of `dijit.TitlePane`s,
 		//		allowing one to be visible and hiding siblings
 		//
@@ -76,12 +71,12 @@ dojo.require("dijit.TitlePane");
 			// 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 = dijit.getEnclosingWidget(n);
-				tp && tp !== widget && tp.open && tp.set("open", false);
+				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
 		}
 	
 	});
 
-})(dojo);
+});
diff --git a/dojox/widget/Toaster.js b/dojox/widget/Toaster.js
index 634b5ae..bf87d5f 100644
--- a/dojox/widget/Toaster.js
+++ b/dojox/widget/Toaster.js
@@ -1,12 +1,28 @@
-dojo.provide("dojox.widget.Toaster");
-
-dojo.require("dojo.fx");
-dojo.require("dojo.window");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-
-dojo.declare("dojox.widget.Toaster", [dijit._Widget, dijit._Templated], {
+define([
+	"dojo/_base/declare", // declare
+        "dojo/_base/lang", // lang.getObject...
+	"dojo/_base/connect", // connect.connect, connect.subscribe
+	"dojo/_base/fx", // fx.fadeOut
+        "dojo/dom-style", // domStyle.set
+	"dojo/dom-class", // domClass.add
+	"dojo/dom-geometry", // domGeometry.getMarginBox
+	"dijit/registry",    // registry.getUniqueId()
+	"dijit/_WidgetBase",
+	"dijit/_TemplatedMixin",
+	"dijit/BackgroundIframe",
+	"dojo/fx",
+	"dojo/has",
+	"dojo/_base/window",
+	"dojo/window"
+], function(declare, lang, connect, baseFx, domStyle, domClass, domGeometry, registry, WidgetBase, Templated, BackgroundIframe, coreFx, has, baseWindow, window){
+
+	lang.getObject("dojox.widget", true);
+	
+	var capitalize = function(/* String */w){
+	    return w.substring(0,1).toUpperCase() + w.substring(1);
+	};
+
+	return declare("dojox.widget.Toaster", [WidgetBase, Templated], {
 		// summary:
 		//		Message that slides in from the corner of the screen, used for notifications
 		//		like "new email".
@@ -38,7 +54,7 @@ dojo.declare("dojox.widget.Toaster", [dijit._Widget, dijit._Templated], {
 		//		Position from which message slides into screen, one of
 		//		["br-up", "br-left", "bl-up", "bl-right", "tr-down", "tr-left", "tl-down", "tl-right"]
 		positionDirection: "br-up",
-		
+
 		// positionDirectionTypes: Array
 		//		Possible values for positionDirection parameter
 		positionDirectionTypes: ["br-up", "br-left", "bl-up", "bl-right", "tr-down", "tr-left", "tl-down", "tl-right"],
@@ -59,27 +75,23 @@ dojo.declare("dojox.widget.Toaster", [dijit._Widget, dijit._Templated], {
 		postCreate: function(){
 			this.inherited(arguments);
 			this.hide();
-			
+
 			// place node as a child of body for positioning
-			dojo.body().appendChild(this.domNode);
-			
+			baseWindow.body().appendChild(this.domNode);
+
 			if(this.messageTopic){
-				dojo.subscribe(this.messageTopic, this, "_handleMessage");
+				connect.subscribe(this.messageTopic, this, "_handleMessage");
 			}
 		},
 
 		_handleMessage: function(/*String|Object*/message){
-			if(dojo.isString(message)){
+			if(lang.isString(message)){
 				this.setContent(message);
 			}else{
 				this.setContent(message.message, message.type, message.duration);
 			}
 		},
 
-		_capitalize: function(/* String */w){
-				return w.substring(0,1).toUpperCase() + w.substring(1);
-		},
-
 		setContent: function(/*String|Function*/message, /*String*/messageType, /*int?*/duration){
 			// summary:
 			//		sets and displays the given message and show duration
@@ -96,7 +108,7 @@ dojo.declare("dojox.widget.Toaster", [dijit._Widget, dijit._Templated], {
 					this.slideAnim.stop();
 				}
 				if(this.slideAnim.status() == "playing" || (this.fadeAnim && this.fadeAnim.status() == "playing")){
-					setTimeout(dojo.hitch(this, function(){
+					setTimeout(lang.hitch(this, function(){
 						this.setContent(message, messageType, duration);
 					}), 50);
 					return;
@@ -105,19 +117,19 @@ dojo.declare("dojox.widget.Toaster", [dijit._Widget, dijit._Templated], {
 
 			// determine type of content and apply appropriately
 			for(var type in this.messageTypes){
-				dojo.removeClass(this.containerNode, "dijitToaster" + this._capitalize(this.messageTypes[type]));
+				domClass.remove(this.containerNode, "dijitToaster" + capitalize(this.messageTypes[type]));
 			}
 
-			dojo.style(this.containerNode, "opacity", 1);
+			domStyle.set(this.containerNode, "opacity", 1);
 
 			this._setContent(message);
 
-			dojo.addClass(this.containerNode, "dijitToaster" + this._capitalize(messageType || this.defaultType));
+			domClass.add(this.containerNode, "dijitToaster" + capitalize(messageType || this.defaultType));
 
 			// now do funky animation of widget appearing from
 			// bottom right of page and up
 			this.show();
-			var nodeSize = dojo.marginBox(this.containerNode);
+			var nodeSize = domGeometry.getMarginBox(this.containerNode);
 			this._cancelHideTimer();
 			if(this.isVisible){
 				this._placeClip();
@@ -144,7 +156,7 @@ dojo.declare("dojox.widget.Toaster", [dijit._Widget, dijit._Templated], {
 				}else{
 					throw new Error(this.id + ".positionDirection is invalid: " + pd);
 				}
-				this.slideAnim = dojo.fx.slideTo({
+				this.slideAnim = coreFx.slideTo({
 					node: this.containerNode,
 					top: 0, left: 0,
 					duration: this.slideDuration});
@@ -152,7 +164,7 @@ dojo.declare("dojox.widget.Toaster", [dijit._Widget, dijit._Templated], {
 						//we build the fadeAnim here so we dont have to duplicate it later
 						// can't do a fadeHide because we're fading the
 						// inner node rather than the clipping node
-						this.fadeAnim = dojo.fadeOut({
+						this.fadeAnim = baseFx.fadeOut({
 							node: this.containerNode,
 							duration: 1000});
 						this.connect(this.fadeAnim, "onEnd", function(evt){
@@ -172,9 +184,9 @@ dojo.declare("dojox.widget.Toaster", [dijit._Widget, dijit._Templated], {
 				this.slideAnim.play();
 			}
 		},
-		
+
 		_setContent: function(message){
-			if(dojo.isFunction(message)){
+			if(lang.isFunction(message)){
 				message(this);
 				return;
 			}
@@ -189,13 +201,13 @@ dojo.declare("dojox.widget.Toaster", [dijit._Widget, dijit._Templated], {
 				this._hideTimer=null;
 			}
 		},
-		
+
 		_setHideTimer:function(duration){
 			this._cancelHideTimer();
 			//if duration == 0 we keep the message displayed until clicked
 			if(duration>0){
 				this._cancelHideTimer();
-				this._hideTimer=setTimeout(dojo.hitch(this, function(evt){
+				this._hideTimer=setTimeout(lang.hitch(this, function(evt){
 					// we must hide the iframe in order to fade
 					// TODO: figure out how to fade with a BackgroundIframe
 					if(this.bgIframe && this.bgIframe.iframe){
@@ -210,11 +222,11 @@ dojo.declare("dojox.widget.Toaster", [dijit._Widget, dijit._Templated], {
 			else
 				this._stickyMessage=true;
 		},
-		
+
 		_placeClip: function(){
-			var view = dojo.window.getBox();
+			var view = window.getBox();
 
-			var nodeSize = dojo.marginBox(this.containerNode);
+			var nodeSize = domGeometry.getMarginBox(this.containerNode);
 
 			var style = this.clipNode.style;
 			// sets up the size of the clipping node
@@ -235,10 +247,10 @@ dojo.declare("dojox.widget.Toaster", [dijit._Widget, dijit._Templated], {
 			}
 
 			style.clip = "rect(0px, " + nodeSize.w + "px, " + nodeSize.h + "px, 0px)";
-			if(dojo.isIE){
+			if(has("ie")){
 				if(!this.bgIframe){
-					this.clipNode.id = dijit.getUniqueId("dojox_widget_Toaster_clipNode");
-					this.bgIframe = new dijit.BackgroundIframe(this.clipNode);
+					this.clipNode.id = registry.getUniqueId("dojox_widget_Toaster_clipNode");
+					this.bgIframe = new BackgroundIframe(this.clipNode);
 				}
 				var iframe = this.bgIframe.iframe;
 				if(iframe){ iframe.style.display="block"; }
@@ -251,26 +263,27 @@ dojo.declare("dojox.widget.Toaster", [dijit._Widget, dijit._Templated], {
 
 		show: function(){
 			// summary: show the Toaster
-			dojo.style(this.domNode, 'display', 'block');
+			domStyle.set(this.domNode, 'display', 'block');
 
 			this._placeClip();
 
 			if(!this._scrollConnected){
-				this._scrollConnected = dojo.connect(window, "onscroll", this, this._placeClip);
+				this._scrollConnected = connect.connect(window, "onscroll", this, this._placeClip);
 			}
 		},
 
 		hide: function(){
 			// summary: hide the Toaster
 
-			dojo.style(this.domNode, 'display', 'none');
+			domStyle.set(this.domNode, 'display', 'none');
 
 			if(this._scrollConnected){
-				dojo.disconnect(this._scrollConnected);
+				connect.disconnect(this._scrollConnected);
 				this._scrollConnected = false;
 			}
 
-			dojo.style(this.containerNode, "opacity", 1);
+			domStyle.set(this.containerNode, "opacity", 1);
 		}
-	}
-);
+	});
+
+});
diff --git a/dojox/widget/Toaster/Toaster.css b/dojox/widget/Toaster/Toaster.css
index b933063..5ac90b5 100644
--- a/dojox/widget/Toaster/Toaster.css
+++ b/dojox/widget/Toaster/Toaster.css
@@ -18,14 +18,10 @@
 }
 
 .dijitToasterWarning .dijitToasterContent{
-	padding:1em;
-	padding-top:0.25em;
 	background:#d4d943;
 } 
 
 .dijitToasterError .dijitToasterContent{
-	padding:1em;
-	padding-top:0.25em;
 	background:#c46600;
 }
 
@@ -42,6 +38,5 @@
 	position: absolute;
 	width: 17.5em;
 	margin: 0px;
-	font:0.75em Tahoma, Helvetica, Verdana, Arial;
+	font:0.75em;
 }
- 
diff --git a/dojox/widget/Wizard.js b/dojox/widget/Wizard.js
index 11c3b3e..8ac0665 100644
--- a/dojox/widget/Wizard.js
+++ b/dojox/widget/Wizard.js
@@ -1,21 +1,25 @@
-dojo.provide("dojox.widget.Wizard");
-
-dojo.require("dijit.layout.StackContainer");
-dojo.require("dijit.layout.ContentPane");
-dojo.require("dijit.form.Button");
-
-dojo.require("dojo.i18n");
-dojo.requireLocalization("dijit", "common");
-dojo.requireLocalization("dojox.widget", "Wizard");
-
-dojo.declare("dojox.widget.Wizard", [dijit.layout.StackContainer, dijit._Templated], {
+define([
+	"dojo/_base/lang",
+	"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) {
+  
+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
 	//
 	
-	widgetsInTemplate: true,
-	templateString: dojo.cache("dojox.widget", "Wizard/Wizard.html"),
+	templateString: template,
 	
 	// nextButtonLabel: String
 	//		Label override for the "Next" button.
@@ -45,8 +49,8 @@ dojo.declare("dojox.widget.Wizard", [dijit.layout.StackContainer, dijit._Templat
 
 	postMixInProperties: function(){
 		this.inherited(arguments);
-		var labels = dojo.mixin({cancel: dojo.i18n.getLocalization("dijit", "common", this.lang).buttonCancel},
-			dojo.i18n.getLocalization("dojox.widget", "Wizard", this.lang));
+		var labels = lang.mixin({cancel: i18n.getLocalization("dijit", "common", this.lang).buttonCancel},
+			i18n.getLocalization("dojox.widget", "Wizard", this.lang));
 		var prop;
 		for(prop in labels){
 			if(!this[prop + "ButtonLabel"]){
@@ -66,8 +70,8 @@ dojo.declare("dojox.widget.Wizard", [dijit.layout.StackContainer, dijit._Templat
 		this.connect(this.previousButton, "onClick", "back");
 
 		if(this.cancelFunction){
-			if(dojo.isString(this.cancelFunction)){
-				this.cancelFunction = dojo.getObject(this.cancelFunction);
+			if(lang.isString(this.cancelFunction)){
+				this.cancelFunction = lang.getObject(this.cancelFunction);
 			}
 			this.connect(this.cancelButton, "onClick", this.cancelFunction);
 		}else{
@@ -75,7 +79,7 @@ dojo.declare("dojox.widget.Wizard", [dijit.layout.StackContainer, dijit._Templat
 		}
 		this.connect(this.doneButton, "onClick", "done");
 
-		this._subscription = dojo.subscribe(this.id + "-selectChild", dojo.hitch(this,"_checkButtons"));
+		this._subscription = connect.subscribe(this.id + "-selectChild", lang.hitch(this,"_checkButtons"));
 		this._started = true;
 		
 	},
@@ -123,13 +127,13 @@ dojo.declare("dojox.widget.Wizard", [dijit.layout.StackContainer, dijit._Templat
 	},
 	
 	destroy: function(){
-		dojo.unsubscribe(this._subscription);
+		connect.unsubscribe(this._subscription);
 		this.inherited(arguments);
 	}
 	
 });
 
-dojo.declare("dojox.widget.WizardPane", dijit.layout.ContentPane, {
+declare("dojox.widget.WizardPane", ContentPane, {
 	// summary: A panel in a `dojox.widget.Wizard`
 	//
 	// description:
@@ -155,11 +159,11 @@ dojo.declare("dojox.widget.WizardPane", dijit.layout.ContentPane, {
 	startup: function(){
 		this.inherited(arguments);
 		if(this.isFirstChild){ this.canGoBack = false; }
-		if(dojo.isString(this.passFunction)){
-			this.passFunction = dojo.getObject(this.passFunction);
+		if(lang.isString(this.passFunction)){
+			this.passFunction = lang.getObject(this.passFunction);
 		}
-		if(dojo.isString(this.doneFunction) && this.doneFunction){
-			this.doneFunction = dojo.getObject(this.doneFunction);
+		if(lang.isString(this.doneFunction) && this.doneFunction){
+			this.doneFunction = lang.getObject(this.doneFunction);
 		}
 	},
 
@@ -177,7 +181,7 @@ dojo.declare("dojox.widget.WizardPane", dijit.layout.ContentPane, {
 		//		returns a string, it is assumed to be a custom error message, and
 		//		is alert()'ed
 		var r = true;
-		if(this.passFunction && dojo.isFunction(this.passFunction)){
+		if(this.passFunction && lang.isFunction(this.passFunction)){
 			var failMessage = this.passFunction();
 			switch(typeof failMessage){
 				case "boolean":
@@ -193,7 +197,11 @@ dojo.declare("dojox.widget.WizardPane", dijit.layout.ContentPane, {
 	},
 
 	done: function(){
-		if(this.doneFunction && dojo.isFunction(this.doneFunction)){ this.doneFunction(); }
+		if(this.doneFunction && lang.isFunction(this.doneFunction)){ this.doneFunction(); }
 	}
 
 });
+
+return Wizard;
+
+});
diff --git a/dojox/widget/gauge/AnalogArcIndicator.js b/dojox/widget/gauge/AnalogArcIndicator.js
index d485a0a..40365fb 100644
--- a/dojox/widget/gauge/AnalogArcIndicator.js
+++ b/dojox/widget/gauge/AnalogArcIndicator.js
@@ -1,66 +1,4 @@
 dojo.provide('dojox.widget.gauge.AnalogArcIndicator');
-dojo.require('dojox.widget.AnalogGauge');
+dojo.require("dojox.gauges.AnalogArcIndicator");
 
-dojo.experimental("dojox.widget.gauge.AnalogArcIndicator");
-
-dojo.declare("dojox.widget.gauge.AnalogArcIndicator",[dojox.widget.gauge.AnalogLineIndicator],{
-	_createArc: function(val){
-		// Creating the Arc Path string manually.  This is instead of creating new dojox.gfx.Path object
-		// each time since we really just need the Path string (to use with setShape) and we don't want to
-		// have to redo the connects, etc.
-		if(this.shapes[0]){
-			var a = this._gauge._getRadians(this._gauge._getAngle(val));
-			var cosa = Math.cos(a);
-			var sina = Math.sin(a);
-			var sa = this._gauge._getRadians(this._gauge.startAngle);
-			var cossa = Math.cos(sa);
-			var sinsa = Math.sin(sa);
-			var off = this.offset + this.width;
-			var p = ['M'];
-			p.push(this._gauge.cx+this.offset*sinsa);
-			p.push(this._gauge.cy-this.offset*cossa);
-			p.push('A', this.offset, this.offset, 0, ((a-sa)>Math.PI)?1:0, 1);
-			p.push(this._gauge.cx+this.offset*sina);
-			p.push(this._gauge.cy-this.offset*cosa);
-			p.push('L');
-			p.push(this._gauge.cx+off*sina);
-			p.push(this._gauge.cy-off*cosa);
-			p.push('A', off, off, 0, ((a-sa)>Math.PI)?1:0, 0);
-			p.push(this._gauge.cx+off*sinsa);
-			p.push(this._gauge.cy-off*cossa);
-			this.shapes[0].setShape(p.join(' '));
-			this.currentValue = val;
-		}
-	},
-	draw: function(/*Boolean?*/ dontAnimate){
-		// summary:
-		//		Override of dojox.widget._Indicator.draw
-		var v = this.value;
-		if(v < this._gauge.min){v = this._gauge.min;}
-		if(v > this._gauge.max){v = this._gauge.max;}
-		if(this.shapes){
-			if(dontAnimate){
-				this._createArc(v);
-			}else{
-				var anim = new dojo.Animation({curve: [this.currentValue, v], duration: this.duration, easing: this.easing});
-				dojo.connect(anim, "onAnimate", dojo.hitch(this, this._createArc));
-				anim.play();
-			}
-		}else{
-			var stroke = {color: this.color, width: 1};
-			if(this.color.type){
-				stroke.color = this.color.colors[0].color;
-			}
-			this.shapes = [this._gauge.surface.createPath()
-							.setStroke(stroke).setFill(this.color)];
-			this._createArc(v);
-			if(this.hover){
-				this.shapes[0].getEventSource().setAttribute('hover',this.hover);
-			}
-			if(this.onDragMove && !this.noChange){
-				this._gauge.connect(this.shapes[0].getEventSource(), 'onmousedown', this._gauge.handleMouseDown);
-				this.shapes[0].getEventSource().style.cursor = 'pointer';
-			}
-		}
-	}
-});
+dojox.widget.gauge.AnalogArcIndicator = dojox.gauges.AnalogArcIndicator;
diff --git a/dojox/widget/gauge/AnalogArrowIndicator.js b/dojox/widget/gauge/AnalogArrowIndicator.js
index ea1a02f..22e5132 100644
--- a/dojox/widget/gauge/AnalogArrowIndicator.js
+++ b/dojox/widget/gauge/AnalogArrowIndicator.js
@@ -1,37 +1,4 @@
 dojo.provide('dojox.widget.gauge.AnalogArrowIndicator');
-dojo.require('dojox.widget.AnalogGauge');
+dojo.require("dojox.gauges.AnalogArrowIndicator");
 
-dojo.experimental("dojox.widget.gauge.AnalogArrowIndicator");
-
-dojo.declare("dojox.widget.gauge.AnalogArrowIndicator",[dojox.widget.gauge.AnalogLineIndicator],{
-	_getShapes: function(){
-		// summary:
-		//		Override of dojox.widget.AnalogLineIndicator._getShapes
-		if(!this._gauge){
-			return null;
-		}
-		var x = Math.floor(this.width/2);
-		var head = this.width * 5;
-		var odd = (this.width & 1);
-		var shapes = [];
-		var points = [{x:-x,	 y:0},
-					  {x:-x,	 y:-this.length+head},
-					  {x:-2*x,	 y:-this.length+head},
-					  {x:0,		 y:-this.length},
-					  {x:2*x+odd,y:-this.length+head},
-					  {x:x+odd,	 y:-this.length+head},
-					  {x:x+odd,	 y:0},
-					  {x:-x,	 y:0}];
-		shapes[0] = this._gauge.surface.createPolyline(points)
-					.setStroke({color: this.color})
-					.setFill(this.color);
-		shapes[1] = this._gauge.surface.createLine({ x1:-x, y1: 0, x2: -x, y2:-this.length+head })
-					.setStroke({color: this.highlight});
-		shapes[2] = this._gauge.surface.createLine({ x1:-x-3, y1: -this.length+head, x2: 0, y2:-this.length })
-					.setStroke({color: this.highlight});
-		shapes[3] = this._gauge.surface.createCircle({cx: 0, cy: 0, r: this.width})
-					.setStroke({color: this.color})
-					.setFill(this.color);
-		return shapes;
-	}
-});
+dojox.widget.gauge.AnalogArrowIndicator = dojox.gauges.AnalogArrowIndicator;
diff --git a/dojox/widget/gauge/AnalogNeedleIndicator.js b/dojox/widget/gauge/AnalogNeedleIndicator.js
index 59c9e9e..cc5ba6b 100644
--- a/dojox/widget/gauge/AnalogNeedleIndicator.js
+++ b/dojox/widget/gauge/AnalogNeedleIndicator.js
@@ -1,31 +1,4 @@
 dojo.provide('dojox.widget.gauge.AnalogNeedleIndicator');
-dojo.require('dojox.widget.AnalogGauge');
+dojo.require('dojox.gauges.AnalogNeedleIndicator');
 
-dojo.experimental("dojox.widget.gauge.AnalogNeedleIndicator");
-
-dojo.declare("dojox.widget.gauge.AnalogNeedleIndicator",[dojox.widget.gauge.AnalogLineIndicator],{
-	_getShapes: function(){
-		// summary:
-		//		Override of dojox.widget.AnalogLineIndicator._getShapes
-		if(!this._gauge){
-			return null;
-		}
-		var x = Math.floor(this.width/2);
-		var head = this.width * 5;
-		var odd = (this.width & 1);
-		var shapes = [];
-		var stroke = {color: this.color, width: 1};
-		if(this.color.type){
-			stroke.color = this.color.colors[0].color;
-		}
-		var xy = (Math.sqrt(2) * (x));
-		shapes[0] = this._gauge.surface.createPath()
-					.setStroke(stroke).setFill(this.color)
-					.moveTo(xy, -xy).arcTo((2*x), (2*x), 0, 0, 0, -xy, -xy)
-					.lineTo(0, -this.length).closePath();
-		shapes[1] = this._gauge.surface.createCircle({cx: 0, cy: 0, r: this.width})
-					.setStroke({color: this.color})
-					.setFill(this.color);
-		return shapes;
-	}
-});
+dojox.widget.gauge.AnalogNeedleIndicator = dojox.gauges.AnalogNeedleIndicator;
diff --git a/dojox/widget/gauge/BarIndicator.js b/dojox/widget/gauge/BarIndicator.js
index fd837de..f181595 100644
--- a/dojox/widget/gauge/BarIndicator.js
+++ b/dojox/widget/gauge/BarIndicator.js
@@ -1,72 +1,4 @@
 dojo.provide('dojox.widget.gauge.BarIndicator');
-dojo.require('dojox.widget.BarGauge');
+dojo.require('dojox.gauges.BarIndicator');
 
-dojo.experimental("dojox.widget.gauge.BarIndicator");
-
-dojo.declare("dojox.widget.gauge.BarIndicator",[dojox.widget.gauge.BarLineIndicator],{
-	_getShapes: function(){
-		// summary:
-		//		Override of dojox.widget.BarLineIndicator._getShapes
-		if(!this._gauge){
-			return null;
-		}
-		var v = this.value;
-		if(v < this._gauge.min){v = this._gauge.min;}
-		if(v > this._gauge.max){v = this._gauge.max;}
-		var pos = this._gauge._getPosition(v);
-		if(pos == this.dataX){pos = this.dataX+1;}
-		var y = this._gauge.dataY + Math.floor((this._gauge.dataHeight - this.width)/2) + this.offset;
-
-		var shapes = [];
-		shapes[0] = this._gauge.surface.createRect({x:this._gauge.dataX, y:y, width:pos - this._gauge.dataX, height:this.width});
-		shapes[0].setStroke({color: this.color});
-		shapes[0].setFill(this.color);
-		shapes[1] = this._gauge.surface.createLine({ x1:this._gauge.dataX, y1:y, x2:pos, y2:y });
-		shapes[1].setStroke({color: this.highlight});
-		if(this.highlight2){
-			y--;
-			shapes[2] = this._gauge.surface.createLine({ x1:this._gauge.dataX, y1:y, x2:pos, y2:y });
-			shapes[2].setStroke({color: this.highlight2});
-		}
-
-		return shapes;
-	},
-	_createShapes: function(val){
-		// summary:
-		//		Creates a shallow copy of the current shapes while adjusting for the new value
-		for(var i in this.shapes){
-			i = this.shapes[i];
-			var newShape = {};
-			for(var j in i){
-				newShape[j] = i[j];
-			}
-			if(i.shape.type == "line"){
-				newShape.shape.x2 = val+newShape.shape.x1;
-			}else if(i.shape.type == "rect"){
-				newShape.width = val;
-			}
-			i.setShape(newShape);
-		}
-	},
-	_move: function(/*Boolean?*/ dontAnimate){
-		// summary:
-		//		Override of dojox.widget.BarLineIndicator._move to resize the bar (rather than moving it)
-		var changed = false;
-		var c;
-		var v = this.value ;
-		if(v < this.min){v = this.min;}
-		if(v > this.max){v = this.max;}
-		c = this._gauge._getPosition(this.currentValue);
-		this.currentValue = v;
-		v = this._gauge._getPosition(v)-this._gauge.dataX;
-		if(dontAnimate){
-			this._createShapes(v);
-		}else{
-			if(c!=v){
-				var anim = new dojo.Animation({curve: [c, v], duration: this.duration, easing: this.easing});
-				dojo.connect(anim, "onAnimate", dojo.hitch(this, this._createShapes));
-				anim.play();
-			}
-		}
-	}
-});
+dojox.widget.gauge.BarIndicator = dojox.gauges.BarIndicator;
diff --git a/dojox/widget/gauge/_Gauge.css b/dojox/widget/gauge/_Gauge.css
deleted file mode 100644
index 7eaa756..0000000
--- a/dojox/widget/gauge/_Gauge.css
+++ /dev/null
@@ -1,63 +0,0 @@
- at CHARSET "ISO-8859-1";
-
-.dojoxGaugeContent {
-	font-family: Verdana;
-	border-width: 1px;
-	border-style: solid;
-	border-color: #CCCCCC;
-}
-
-.dojoxGaugeRange1 {
-	fill: #606060 ;
-	stroke: #606060 ;
-}
-
-.dojoxGaugeRange2 {
-	fill: #707070 ;
-	stroke: #707070 ;
-}
-
-.dojoxGaugeRange3 {
-	fill: #808080 ;
-	stroke: #808080 ;
-}
-
-.dojoxGaugeRange4 {
-	fill: #909090 ;
-	stroke: #909090 ;
-}
-
-.dojoxGaugeRange5 {
-	fill: #A0A0A0;
-	stroke: #A0A0A0;
-}
-
-.dojoxGaugeRange6 {
-	fill: #B0B0B0;
-	stroke: #B0B0B0;
-}
-
-.dojoxGaugeRange7 {
-	fill: #C0C0C0;
-	stroke: #C0C0C0;
-}
-
-.dojoxGaugeRange8 {
-	fill: #D0D0D0;
-	stroke: #D0D0D0;
-}
-
-.dojoxGaugeRange9 {
-	fill: #E0E0E0;
-	stroke: #E0E0E0;
-}
-
-.dojoxGaugeRange10 {
-	fill: #F0F0F0;
-	stroke: #F0F0F0;
-}
-
-.testing {
-	fill: blue;
-	stroke: blue;
-}
\ No newline at end of file
diff --git a/dojox/widget/gauge/_Gauge.html b/dojox/widget/gauge/_Gauge.html
deleted file mode 100644
index 3c4bdf9..0000000
--- a/dojox/widget/gauge/_Gauge.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<div>
-	<div class="dojoxGaugeContent" dojoAttachPoint="gaugeContent"></div>
-	<div dojoAttachPoint="containerNode"></div>
-	<div dojoAttachPoint="mouseNode"></div>
-</div>
\ No newline at end of file
diff --git a/dojox/widget/gauge/_Gauge.js b/dojox/widget/gauge/_Gauge.js
index 75558bc..605b771 100644
--- a/dojox/widget/gauge/_Gauge.js
+++ b/dojox/widget/gauge/_Gauge.js
@@ -1,756 +1,6 @@
 dojo.provide("dojox.widget.gauge._Gauge");
+dojo.require("dojox.gauges._Gauge");
 
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._Container");
-dojo.require("dijit._Contained");
-dojo.require("dijit.Tooltip");
-dojo.require("dojo.fx.easing");
-dojo.require("dojox.gfx");
-
-dojo.experimental("dojox.widget.gauge._Gauge");
-
-dojo.declare("dojox.widget.gauge._Gauge",[dijit._Widget, dijit._Templated, dijit._Container],{
-	// summary:
-	//		a gauge built using the dojox.gfx package.
-	//
-	// description:
-	//		using dojo.gfx (and thus either SVG or VML based on what is supported), this widget
-	//		builds a gauge component, used to display numerical data in a familiar format
-	//
-	// usage:
-	//		this widget is not to be used alone. it is meant to be subclassed, such as
-	//		dojox.widget.BarGauge or dojox.widget.AnalogGauge
-
-	// width: Number
-	// the width of the gauge (default is 300)
-	width: 0,
-
-	// height: Number
-	// the height of the gauge (default is 200)
-	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'}] }
-	background: null,
-
-	// min: Number
-	// minimum value displayed by gauge (default is lowest range value)
-	min: 0,
-
-	// max: Number
-	// maximum value displayed by gauge (default is largest range value)
-	max: 0,
-
-	// image: String
-	// 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)
-	useRangeStyles: 0,
-
-	// useTooltip: Boolean
-	// 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 *):
-	//		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"}
-	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.
-	minorTicks: null,
-
-	// _defaultIndicator: Objection
-	// 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 anonmyous object is passed into
-	// addIndicator.
-	_defaultIndicator: null,
-
-	// defaultColors: Array
-	// Set of default colors to color ranges with.
-	defaultColors: [[0x00,0x54,0xAA,1],
-					[0x44,0x77,0xBB,1],
-					[0x66,0x99,0xCC,1],
-					[0x99,0xBB,0xEE,1],
-					[0x99,0xCC,0xFF,1],
-					[0xCC,0xEE,0xFF,1],
-					[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.
-	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.
-	max: null,
-	
-	// surface: Object
-	// The SVG/VML 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.
-	hideValues: false,
-
-	// internal data
-	gaugeContent: undefined,
-	templateString: dojo.cache("dojox.widget.gauge", "_Gauge.html"),
-	_backgroundDefault: {color: '#E0E0E0'},
-	_rangeData: null,
-	_indicatorData: null,
-	_drag: null,
-	_img: null,
-	_overOverlay: false,
-	_lastHover: '',
-
-	startup: function(){
-		// handle settings from HTML by making sure all the options are
-		// converted correctly to numbers and that we calculate defaults
-		// for cx, cy and radius
-		if(this.image === null){
-			this.image={};
-		}
-
-		this.connect(this.gaugeContent, 'onmousemove', this.handleMouseMove);
-		this.connect(this.gaugeContent, 'onmouseover', this.handleMouseOver);
-		this.connect(this.gaugeContent, 'onmouseout', this.handleMouseOut);
-		this.connect(this.gaugeContent, 'onmouseup', this.handleMouseUp);
-
-		if(!dojo.isArray(this.ranges)){ this.ranges = []; }
-		if(!dojo.isArray(this.indicators)){ this.indicators = []; }
-		var ranges = [], indicators = [];
-		var i;
-		if(this.hasChildren()){
-			var children = this.getChildren();
-			for(i=0; i<children.length; i++){
-				if(/dojox\.widget\..*Indicator/.test(children[i].declaredClass)){
-					indicators.push(children[i]);
-					//this.addIndicator(children[i]);
-					continue;
-				}
-				switch(children[i].declaredClass){
-					case "dojox.widget.gauge.Range":
-						ranges.push(children[i]);
-						break;
-				}
-			}
-			this.ranges = this.ranges.concat(ranges);
-			this.indicators = this.indicators.concat(indicators);
-		}
-		if(!this.background){ this.background = this._backgroundDefault; }
-		this.background = this.background.color || this.background;
-		if(!this.surface){ this.createSurface(); }
-
-		this.addRanges(this.ranges);
-		if(this.minorTicks && this.minorTicks.interval){
-			this.setMinorTicks(this.minorTicks);
-		}
-		if(this.majorTicks && this.majorTicks.interval){
-			this.setMajorTicks(this.majorTicks);
-		}
-		for(i=0; i<this.indicators.length; i++){
-			this.addIndicator(this.indicators[i]);
-		}
-	},
-
-	_setTicks: function(/*Object*/ oldTicks, /*Object*/ newTicks, /*Boolean*/ label){
-		// summary:
-		//		internal method used to clear existing tick marks, then add new ones
-		var i;
-		if(oldTicks && dojo.isArray(oldTicks._ticks)){
-			for(i=0; i<oldTicks._ticks.length; i++){
-				this.removeIndicator(oldTicks._ticks[i]);
-			}
-		}
-		var t = {length: newTicks.length,
-					offset: newTicks.offset,
-					noChange: true};
-		if(newTicks.color){ t.color = newTicks.color; }
-		if(newTicks.font){ t.font = newTicks.font; }
-		newTicks._ticks = [];
-		for(i=this.min; i<=this.max; i+=newTicks.interval){
-			t.value = i;
-			if(label){t.label = ''+i;}
-			newTicks._ticks.push(this.addIndicator(t));
-		}
-		return newTicks;
-	},
-	
-	setMinorTicks: function(/*Object*/ ticks){
-		// summary:
-		//		Creates and draws the minor tick marks based on the passed object (expecting the same format
-		//		as the minorTicks object documented above)
-		this.minorTicks = this._setTicks(this.minorTicks, ticks, false);
-	},
-
-	setMajorTicks: function(/*Object*/ ticks){
-		// summary:
-		//		Creates and draws the major tick marks based on the passed object (expecting the same format
-		//		as the majorTicks object documented above)
-		this.majorTicks = this._setTicks(this.majorTicks, ticks, true);
-	},
-
-	postCreate: function(){
-		if(this.hideValues){
-			dojo.style(this.containerNode, "display", "none");
-		}
-		dojo.style(this.mouseNode, 'width', '0');
-		dojo.style(this.mouseNode, 'height', '0');
-		dojo.style(this.mouseNode, 'position', 'absolute');
-		dojo.style(this.mouseNode, 'z-index', '100');
-		if(this.useTooltip){
-			dijit.showTooltip('test',this.mouseNode, !this.isLeftToRight());
-			dijit.hideTooltip(this.mouseNode);
-		}
-	},
-
-	createSurface: function(){
-		// summary:
-		//		internal method used by the gauge to create the graphics surface area
-		this.gaugeContent.style.width = this.width + 'px';
-		this.gaugeContent.style.height = this.height + 'px';
-		this.surface = dojox.gfx.createSurface(this.gaugeContent, this.width, this.height);
-		this._background = this.surface.createRect({x: 0, y: 0, width: this.width, height: this.height });
-		this._background.setFill(this.background);
-
-		if(this.image.url){
-			this._img = this.surface.createImage({width: this.image.width || this.width, height: this.image.height || this.height, src: this.image.url});
-			if(this.image.overlay){
-				this._img.getEventSource().setAttribute('overlay',true);
-			}
-			if(this.image.x || this.image.y){
-				this._img.setTransform({dx: this.image.x || 0, dy: this.image.y || 0});
-			}
-		}
-	},
-
-	setBackground: function(background){
-		// summary:
-		//		This method is used to set the background of the gauge after it is created.
-		// description:
-		//		Sets the background using the given object.  Must be the same 'type' of object
-		//		as the original background argument.
-		// background:
-		//		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'}] }
-		//		If background is null or undefined, this will set the fill to this._backgroundDefault
-		if(!background){ background = this._backgroundDefault; }
-		this.background = background.color || background;
-		this._background.setFill(this.background);
-	},
-
-	addRange: function(/*Object*/range){
-		// summary:
-		//		This method is used to add a range to the gauge.
-		// description:
-		//		Creates a range (colored area on the background of the gauge)
-		//		based on the given arguments.
-		// range:
-		//		A range is either a dojox.widget.gauge.Range object, or a object
-		//		with similar parameters (low, high, hover, etc.).
-		this.addRanges([range]);
-	},
-
-	addRanges: function(/*Array*/ranges){
-		// summary:
-		//		This method is used to add ranges to the gauge.
-		// description:
-		//		Creates a range (colored area on the background of the gauge)
-		//		based on the given arguments.
-		// range:
-		//		A range is either a dojox.widget.gauge.Range object, or a object
-		//		with similar parameters (low, high, hover, etc.).
-		if(!this._rangeData){
-			this._rangeData = [];
-		}
-		var range;
-		for(var i=0; i<ranges.length; i++){
-			range = ranges[i];
-			if((this.min === null) || (range.low < this.min)){this.min = range.low;}
-			if((this.max === null) || (range.high > this.max)){this.max = range.high;}
-
-			if(!range.color){
-				var colorIndex = this._rangeData.length % this.defaultColors.length;
-				if(dojox.gfx.svg && this.useRangeStyles > 0){
-					colorIndex = (this._rangeData.length % this.useRangeStyles)+1;
-					range.color = {style: "dojoxGaugeRange"+colorIndex};
-				}else{
-					colorIndex = this._rangeData.length % this.defaultColors.length;
-					range.color = this.defaultColors[colorIndex];
-				}
-			}
-			this._rangeData[this._rangeData.length] = range;
-		}
-		this.draw();
-	},
-
-	addIndicator: function(/*Object*/indicator){
-		// summary:
-		//		This method is used to add an indicator to the bar graph.
-		// description:
-		//		This method adds an indicator, such as a tick mark or needle,
-		//		to the bar graph.
-		// indicator:
-		//		A dojox.widget.gauge._Indicator or an object with similar parameters
-		//		(value, color, offset, etc.).
-
-		indicator._gauge = this;
-		if(!indicator.declaredClass){// !== 'dojox.widget.gauge.Indicator'){
-			// We were passed a plain object, need to make an indicator out of it.
-			indicator = new this._defaultIndicator(indicator);
-		}
-		if(!indicator.hideValue){
-			this.containerNode.appendChild(indicator.domNode);
-		}
-		if(!this._indicatorData){this._indicatorData = [];}
-		this._indicatorData[this._indicatorData.length] = indicator;
-		indicator.draw();
-		return indicator;
-	},
-
-	removeIndicator: function(/*Object*/indicator){
-		// summary:
-		//		Removes the given indicator from the gauge by calling it's remove function
-		//		and removing it from the local cache.
-		for(var i=0; i<this._indicatorData.length; i++){
-			if(this._indicatorData[i] === indicator){
-				this._indicatorData.splice(i, 1);
-				indicator.remove();
-				break;
-			}
-		}
-	},
-
-	moveIndicatorToFront: function(/*Object*/indicator){
-		// summary:
-		//		This function is used to move an indicator the the front (top)
-		//		of the gauge
-		// indicator:
-		//		A dojox.widget.gauge._Indicator or an object with similar parameters
-		//		(value, color, offset, etc.).
-		if(indicator.shapes){
-			for(var i=0; i<indicator.shapes.length; i++){
-				indicator.shapes[i].moveToFront();
-			}
-		}
-	},
-
-	drawText: function(/*String*/txt, /*Number*/x, /*Number*/y, /*String?*/align, /*String?*/vAlign, /*String?*/color, /*Object?*/font){
-		// summary:
-		//		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
-		// 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
-		// vAlign?:	String
-		//			Indicates how to align the text vertically.
-		//			Valid value is 'top', otherwise text is bottom-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 = this.surface.createText({x: x, y: y, text: txt, align: align});
-		t.setFill(color);
-		t.setFont(font);
-		return t;
-	},
-
-	removeText:function(/*String*/t){
-		// summary:
-		//		Removes a text element from the gauge.
-		// t:	String
-		//		The text to remove.
-		this.surface.rawNode.removeChild(t);
-	},
-
-	updateTooltip: function(/*String*/txt, /*Event*/ e){
-		// summary:
-		//		Updates the tooltip for the gauge to display the given text.
-		// txt:		String
-		//			The text to put in the tooltip.
-		if(this._lastHover != txt){
-			if(txt !== ''){
-				dijit.hideTooltip(this.mouseNode);
-				dijit.showTooltip(txt,this.mouseNode, !this.isLeftToRight());
-			}else{
-				dijit.hideTooltip(this.mouseNode);
-			}
-			this._lastHover = txt;
-		}
-	},
-
-	handleMouseOver: function(/*Object*/event){
-		// summary:
-		//		This is an internal handler used by the gauge to support
-		//		hover text
-		// event:	Object
-		//			The event object
-		var hover = event.target.getAttribute('hover');
-		if(event.target.getAttribute('overlay')){
-			this._overOverlay = true;
-			var r = this.getRangeUnderMouse(event);
-			if(r && r.hover){
-				hover = r.hover;
-			}
-		}
-		if(this.useTooltip && !this._drag){
-			if(hover){
-				this.updateTooltip(hover, event);
-			}else{
-				this.updateTooltip('', event);
-			}
-		}
-	},
-
-	handleMouseOut: function(/*Object*/event){
-		// summary:
-		//		This is an internal handler used by the gauge to support
-		//		hover text
-		// event:	Object
-		//			The event object
-		if(event.target.getAttribute('overlay')){
-			this._overOverlay = false;
-		}
-		if(this.useTooltip && this.mouseNode){
-			dijit.hideTooltip(this.mouseNode);
-		}
-	},
-
-	handleMouseDown: function(/*Object*/event){
-		// summary:
-		//		This is an internal handler used by the gauge to support using
-		//		the mouse to drag an indicator to modify it's value
-		// event:	Object
-		//			The event object
-
-		// find the indicator being dragged
-		for(var i=0; i<this._indicatorData.length; i++){
-			var shapes = this._indicatorData[i].shapes;
-			for(var s=0; s<shapes.length; s++){
-				if(shapes[s].getEventSource() == event.target){
-					 this._drag = this._indicatorData[i];
-					 s = shapes.length;
-					 i = this._indicatorData.length;
-				}
-			}
-		}
-		dojo.stopEvent(event);
-	},
-
-	handleMouseUp: function(/*Object*/event){
-		// summary:
-		//		This is an internal handler used by the gauge to support using
-		//		the mouse to drag an indicator to modify it's value
-		// event:	Object
-		//			The event object
-		this._drag = null;
-		dojo.stopEvent(event);
-	},
-
-	handleMouseMove: function(/*Object*/event){
-		// summary:
-		//		This is an internal handler used by the gauge to support using
-		//		the mouse to drag an indicator to modify it's value
-		// event:	Object
-		//			The event object
-		if(event){
-			dojo.style(this.mouseNode, 'left', event.pageX+1+'px');
-			dojo.style(this.mouseNode, 'top', event.pageY+1+'px');
-		}
-		if(this._drag){
-			this._dragIndicator(this, event);
-		}else{
-			if(this.useTooltip && this._overOverlay){
-				var r = this.getRangeUnderMouse(event);
-				if(r && r.hover){
-					this.updateTooltip(r.hover, event);
-				}else{
-					this.updateTooltip('', event);
-				}
-			}
-		}
-	}
-});
-
-dojo.declare("dojox.widget.gauge.Range",[dijit._Widget, dijit._Contained],{
-	// summary:
-	//		a range to be used in a _Gauge
-	//
-	// description:
-	//		a range widget, which has given properties.  drawn by a _Gauge.
-	//
-	// usage:
-	//		<script type="text/javascript">
-	//			dojo.require("dojox.widget.AnalogGauge");
-	//			dojo.require("dijit.util.parser");
-	//		</script>
-	//		...
-	//		<div	dojoType="dojox.widget.AnalogGauge"
-	//				id="testGauge"
-	//				width="300"
-	//				height="200"
-	//				cx=150
-	//				cy=175
-	//				radius=125
-	//				image="gaugeOverlay.png"
-	//				imageOverlay="false"
-	//				imageWidth="280"
-	//				imageHeight="155"
-	//				imageX="12"
-	//				imageY="38">
-	//			<div	dojoType="dojox.widget.gauge.Range"
-	//					low=5
-	//					high=10
-	//					hover="5 - 10"
-	//			></div>
-	//			<div	dojoType="dojox.widget.gauge.Range"
-	//					low=10
-	//					high=20
-	//					hover="10 - 20"
-	//			></div>
-	//		</div>
-	
-	// low: Number
-	// the low value of the range
-	low: 0,
-	
-	// high: Numbe
-	// the high value of the range
-	high: 0,
-	
-	// hover: String
-	// 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'}] }
-	color: null,
-	
-	// size: Number
-	// for a circular gauge (such as an AnalogGauge), this dictates the size of the arc
-	size: 0,
-
-	startup: function(){
-		this.color = this.color.color || this.color;
-	}
-});
-
-dojo.declare("dojox.widget.gauge._Indicator",[dijit._Widget, dijit._Contained, dijit._Templated],{
-	// summary:
-	//		a indicator to be used in a gauge
-	//
-	// description:
-	//		an indicator widget, which has given properties.  drawn by a gauge.
-	//
-	// usage:
-	//		<script type="text/javascript">
-	//			dojo.require("dojox.widget.AnalogGauge");
-	//			dojo.require("dijit.util.parser");
-	//		</script>
-	//		...
-	//		<div	dojoType="dojox.widget.AnalogGauge"
-	//				id="testGauge"
-	//				width="300"
-	//				height="200"
-	//				cx=150
-	//				cy=175
-	//				radius=125
-	//				image="gaugeOverlay.png"
-	//				imageOverlay="false"
-	//				imageWidth="280"
-	//				imageHeight="155"
-	//				imageX="12"
-	//				imageY="38">
-	//			<div 	dojoType="dojox.widget.gauge.Indicator"
-	//					value=17
-	//					type="arrow"
-	//					length=135
-	//					width=3
-	//					hover="Value: 17"
-	//					onDragMove="handleDragMove">
-	//			</div>
-	//		</div>
-
-	// value: Number
-	// 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"
-	type: '',
-
-	// color: String
-	// The color of the indicator.
-	color: 'black',
-
-	// label: String
-	// The text label for the indicator.
-	label: '',
-
-	// font: Object
-	// Generally 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
-	length: 0,
-
-	// width: Number
-	// The width of the indicator.
-	width: 0,
-
-	// offset: Number
-	// The offset of the indicator
-	offset: 0,
-
-	// hover: String
-	// The string to put in the tooltip when this indicator is hovered over.
-	hover: '',
-
-	// front: boolean
-	// Keep this indicator at the front
-	front: false,
-
-	// onDragMove: String
-	// 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.
-	easing: dojo._defaultEasing,
-
-	// duration: Number
-	// 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.
-	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).
-	noChange: false,
-
-	_gauge: null,
-	
-	// title: String
-	// The title of the indicator, to be displayed next to it's input box for the text-representation.
-	title: "",
-
-	templateString: dojo.cache("dojox.widget.gauge", "_Indicator.html"),
-
-	startup: function(){
-		if(this.onDragMove){
-			this.onDragMove = dojo.hitch(this.onDragMove);
-		}
-	},
-
-	postCreate: function(){
-		if(this.title === ""){
-			dojo.style(this.domNode, "display", "none");
-		}
-		if(dojo.isString(this.easing)){
-			this.easing = dojo.getObject(this.easing);
-		}
-	},
-
-	_update: function(event){
-		// summary:
-		//		A private function, handling the updating of the gauge
-		var value = this.valueNode.value;
-		if(value === ''){
-			this.value = null;
-		}else{
-			this.value = Number(value);
-			this.hover = this.title+': '+value;
-		}
-		if(this._gauge){
-			this.draw();
-			this.valueNode.value = this.value;
-			if((this.title == 'Target' || this.front) && this._gauge.moveIndicator){
-				// if re-drawing value, make sure target is still on top
-				this._gauge.moveIndicatorToFront(this);
-			}
-		}
-	},
-
-	update: function(value){
-		// summary:
-		//		Updates the value of the indicator, including moving/re-drawing at it's new location and
-		//		updating the text box
-		if(!this.noChange){
-			this.valueNode.value = value;
-			this._update();
-		}
-	},
-
-	onDragMove: function(){
-		// summary:
-		//		Handles updating the text box and the hover text while dragging an indicator
-		this.value = Math.floor(this.value);
-		this.valueNode.value = this.value;
-		this.hover = this.title+': '+this.value;
-	},
-
-	draw: function(/* Boolean? */ dontAnimate){
-		// summary:
-		//		Performs the initial drawing of the indicator.
-		// dontAnimate:
-		//		Indicates if the drawing should not be animated (rather than teh default, to animate)
-	},
-
-	remove: function(){
-		// summary:
-		//		Removes the indicator's shapes from the gauge surface.
-		for(var i=0; i<this.shapes.length; i++){
-			this._gauge.surface.remove(this.shapes[i]);
-		}
-		if(this.text){
-			this._gauge.surface.remove(this.text);
-		}
-	}
-});
+dojox.widget.gauge._Gauge = dojox.gauges._Gauge;
+dojox.widget.gauge.Range = dojox.gauges.Range;
+dojox.widget.gauge._indicator = dojox.gauges._indicator;
diff --git a/dojox/widget/gauge/_Indicator.html b/dojox/widget/gauge/_Indicator.html
deleted file mode 100644
index 2942996..0000000
--- a/dojox/widget/gauge/_Indicator.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<div class="dojoxGaugeIndicatorDiv">
-	<label class="dojoxGaugeIndicatorLabel" for="${title}">${title}:</label>
-	<input class="dojoxGaugeIndicatorInput" name="${title}" size="5" value="${value}" dojoAttachPoint="valueNode" dojoAttachEvent="onchange:_update"></input>
-</div>
\ No newline at end of file
diff --git a/dojox/widget/nls/ColorPicker.js b/dojox/widget/nls/ColorPicker.js
index 799144a..c06981f 100644
--- a/dojox/widget/nls/ColorPicker.js
+++ b/dojox/widget/nls/ColorPicker.js
@@ -1,3 +1,5 @@
+define({ root:
+//begin v1.x content
 ({
 redLabel: "r",
 greenLabel: "g",
@@ -10,3 +12,37 @@ hexLabel: "hex",
 huePickerTitle: "Hue Selector",
 saturationPickerTitle: "Saturation Selector"
 })
+//end v1.x content
+,
+"zh": true,
+"zh-tw": 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,
+"az": true,
+"ar": true
+});
diff --git a/dojox/widget/nls/FilePicker.js b/dojox/widget/nls/FilePicker.js
index 1869be9..810c63c 100644
--- a/dojox/widget/nls/FilePicker.js
+++ b/dojox/widget/nls/FilePicker.js
@@ -1,5 +1,41 @@
+define({ root:
+//begin v1.x content
 ({
-name: "Name",
-path: "Path",
-size: "Size (in bytes)"
+	name: "Name",
+	path: "Path",
+	size: "Size (in bytes)"
 })
+//end v1.x content
+,
+"zh": true,
+"zh-tw": 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,
+"az": true,
+"ar": true
+});
diff --git a/dojox/widget/nls/Wizard.js b/dojox/widget/nls/Wizard.js
index 9f03c21..2bd73a4 100644
--- a/dojox/widget/nls/Wizard.js
+++ b/dojox/widget/nls/Wizard.js
@@ -1,5 +1,41 @@
+define({ root:
+//begin v1.x content
 ({
 next: "Next",
 previous: "Previous",
 done: "Done"
 })
+//end v1.x content
+,
+"zh": true,
+"zh-tw": 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,
+"az": true,
+"ar": true
+});
diff --git a/dojox/widget/nls/ar/ColorPicker.js b/dojox/widget/nls/ar/ColorPicker.js
index 1caa8fa..4e15b89 100644
--- a/dojox/widget/nls/ar/ColorPicker.js
+++ b/dojox/widget/nls/ar/ColorPicker.js
@@ -1,5 +1,8 @@
+define(
+//begin v1.x content
 ({
 huePickerTitle: "محدد تدرج اللون",
 saturationPickerTitle: "محدد درجة التشبع"
 })
-
+//end v1.x content
+);
diff --git a/dojox/widget/nls/ar/Wizard.js b/dojox/widget/nls/ar/Wizard.js
index 0c950c2..ee3f305 100644
--- a/dojox/widget/nls/ar/Wizard.js
+++ b/dojox/widget/nls/ar/Wizard.js
@@ -1,6 +1,9 @@
+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
new file mode 100644
index 0000000..bbf0e9b
--- /dev/null
+++ b/dojox/widget/nls/az/ColorPicker.js
@@ -0,0 +1,16 @@
+define(
+//begin v1.x content
+({
+	"redLabel" : "q",
+	"valueLabel" : "d",
+	"hexLabel" : "onaltılıq",
+	"hueLabel" : "ç",
+	"saturationLabel" : "d",
+	"greenLabel" : "y",
+	"blueLabel" : "m",
+	"saturationPickerTitle" : "Doldurmaq seçimi",
+	"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
new file mode 100644
index 0000000..c74413d
--- /dev/null
+++ b/dojox/widget/nls/az/FilePicker.js
@@ -0,0 +1,9 @@
+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
new file mode 100644
index 0000000..c6ba9ce
--- /dev/null
+++ b/dojox/widget/nls/az/Wizard.js
@@ -0,0 +1,9 @@
+define(
+//begin v1.x content
+({
+	"next" : "Irəli",
+	"done" : "Qurtardı",
+	"previous" : "Geri"
+})
+//end v1.x content
+);
diff --git a/dojox/widget/nls/ca/ColorPicker.js b/dojox/widget/nls/ca/ColorPicker.js
index 7e4781e..3fdd070 100644
--- a/dojox/widget/nls/ca/ColorPicker.js
+++ b/dojox/widget/nls/ca/ColorPicker.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 redLabel: "v",
 greenLabel: "e",
@@ -5,3 +7,4 @@ hueLabel: "m",
 huePickerTitle: "Selector de matís",
 saturationPickerTitle: "Selector de saturació"
 })
+);
\ No newline at end of file
diff --git a/dojox/widget/nls/ca/Wizard.js b/dojox/widget/nls/ca/Wizard.js
index dad929c..9d1b280 100644
--- a/dojox/widget/nls/ca/Wizard.js
+++ b/dojox/widget/nls/ca/Wizard.js
@@ -1,6 +1,9 @@
+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 b1a8c8f..2af46cc 100644
--- a/dojox/widget/nls/cs/ColorPicker.js
+++ b/dojox/widget/nls/cs/ColorPicker.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 redLabel: "č",
 greenLabel: "z",
@@ -8,4 +10,4 @@ valueLabel: "j", /* aka intensity or brightness */
 huePickerTitle: "Selektor odstínu",
 saturationPickerTitle: "Selektor sytosti"
 })
-
+);
diff --git a/dojox/widget/nls/cs/Wizard.js b/dojox/widget/nls/cs/Wizard.js
index 70f1996..18a312e 100644
--- a/dojox/widget/nls/cs/Wizard.js
+++ b/dojox/widget/nls/cs/Wizard.js
@@ -1,5 +1,9 @@
+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 e8e45b7..d7b545f 100644
--- a/dojox/widget/nls/da/ColorPicker.js
+++ b/dojox/widget/nls/da/ColorPicker.js
@@ -1,5 +1,7 @@
+define(
+//begin v1.x content
 ({
 huePickerTitle: "Vælg nuance",
 saturationPickerTitle: "Vælg mætning"
 })
-
+);
diff --git a/dojox/widget/nls/da/Wizard.js b/dojox/widget/nls/da/Wizard.js
index f7ebe6b..569fe3e 100644
--- a/dojox/widget/nls/da/Wizard.js
+++ b/dojox/widget/nls/da/Wizard.js
@@ -1,5 +1,9 @@
+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 6417219..92c05eb 100644
--- a/dojox/widget/nls/de/ColorPicker.js
+++ b/dojox/widget/nls/de/ColorPicker.js
@@ -1,5 +1,7 @@
+define(
+//begin v1.x content
 ({
 huePickerTitle: "Farbtonauswahl",
 saturationPickerTitle: "Sättigungsauswahl"
 })
-
+);
diff --git a/dojox/widget/nls/de/Wizard.js b/dojox/widget/nls/de/Wizard.js
index edbbd7e..6624ca5 100644
--- a/dojox/widget/nls/de/Wizard.js
+++ b/dojox/widget/nls/de/Wizard.js
@@ -1,5 +1,9 @@
+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 bbf09ce..6252042 100644
--- a/dojox/widget/nls/el/ColorPicker.js
+++ b/dojox/widget/nls/el/ColorPicker.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 redLabel: "κ",
 greenLabel: "π",
@@ -9,4 +11,4 @@ hexLabel: "16-αδικό",
 huePickerTitle: "Επιλογή απόχρωσης",
 saturationPickerTitle: "Επιλογή κορεσμού"
 })
-
+);
diff --git a/dojox/widget/nls/el/Wizard.js b/dojox/widget/nls/el/Wizard.js
index 588844a..035a222 100644
--- a/dojox/widget/nls/el/Wizard.js
+++ b/dojox/widget/nls/el/Wizard.js
@@ -1,5 +1,9 @@
+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 45d64d9..1eec6a1 100644
--- a/dojox/widget/nls/es/ColorPicker.js
+++ b/dojox/widget/nls/es/ColorPicker.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 greenLabel: "v",
 blueLabel: "a",
@@ -5,4 +7,4 @@ hueLabel: "m",
 huePickerTitle: "Selector de tono",
 saturationPickerTitle: "Selector de saturación"
 })
-
+);
diff --git a/dojox/widget/nls/es/Wizard.js b/dojox/widget/nls/es/Wizard.js
index 80dd2b6..257a7d9 100644
--- a/dojox/widget/nls/es/Wizard.js
+++ b/dojox/widget/nls/es/Wizard.js
@@ -1,5 +1,9 @@
+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 b501a12..99a1467 100644
--- a/dojox/widget/nls/fi/ColorPicker.js
+++ b/dojox/widget/nls/fi/ColorPicker.js
@@ -1,5 +1,7 @@
+define(
+//begin v1.x content
 ({
 huePickerTitle: "Sävyn valitsin",
 saturationPickerTitle: "Kylläisyyden valitsin"
 })
-
+);
diff --git a/dojox/widget/nls/fi/Wizard.js b/dojox/widget/nls/fi/Wizard.js
index 907f6d1..ea05b1f 100644
--- a/dojox/widget/nls/fi/Wizard.js
+++ b/dojox/widget/nls/fi/Wizard.js
@@ -1,5 +1,9 @@
+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 c2c9087..c49f4f4 100644
--- a/dojox/widget/nls/fr/ColorPicker.js
+++ b/dojox/widget/nls/fr/ColorPicker.js
@@ -1,7 +1,9 @@
+define(
+//begin v1.x content
 ({
 greenLabel: "v",
 hueLabel: "t",
 huePickerTitle: "Sélecteur de teinte",
 saturationPickerTitle: "Sélecteur de saturation"
 })
-
+);
diff --git a/dojox/widget/nls/fr/Wizard.js b/dojox/widget/nls/fr/Wizard.js
index 76062ed..5fcab0e 100644
--- a/dojox/widget/nls/fr/Wizard.js
+++ b/dojox/widget/nls/fr/Wizard.js
@@ -1,5 +1,9 @@
+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 cc469c1..b4bb8af 100644
--- a/dojox/widget/nls/he/ColorPicker.js
+++ b/dojox/widget/nls/he/ColorPicker.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 redLabel: "א",
 greenLabel: "י",
@@ -10,4 +12,4 @@ hexLabel: "הקס",
 huePickerTitle: "בורר גוון",
 saturationPickerTitle: "בורר רוויה"
 })
-
+);
diff --git a/dojox/widget/nls/he/Wizard.js b/dojox/widget/nls/he/Wizard.js
index 0885317..07e2e47 100644
--- a/dojox/widget/nls/he/Wizard.js
+++ b/dojox/widget/nls/he/Wizard.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 next: "הבא",
 previous: "הקודם",
 done: "סיום"
 })
+//end v1.x content
+);
diff --git a/dojox/widget/nls/hr/ColorPicker.js b/dojox/widget/nls/hr/ColorPicker.js
new file mode 100644
index 0000000..8e1650a
--- /dev/null
+++ b/dojox/widget/nls/hr/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: "Izbornik nijanse boje",
+saturationPickerTitle: "Izbornik zasićenosti"
+})
+);
diff --git a/dojox/widget/nls/hr/FilePicker.js b/dojox/widget/nls/hr/FilePicker.js
new file mode 100644
index 0000000..9a2d2f6
--- /dev/null
+++ b/dojox/widget/nls/hr/FilePicker.js
@@ -0,0 +1,7 @@
+define(
+({
+	name: "Ime",
+	path: "Staza",
+	size: "Veličina (u bajtovima)"
+})
+);
diff --git a/dojox/widget/nls/hr/Wizard.js b/dojox/widget/nls/hr/Wizard.js
new file mode 100644
index 0000000..d241bcd
--- /dev/null
+++ b/dojox/widget/nls/hr/Wizard.js
@@ -0,0 +1,7 @@
+define(
+({
+next: "Sljedeće",
+previous: "Prethodno",
+done: "Gotovo"
+})
+);
diff --git a/dojox/widget/nls/hu/ColorPicker.js b/dojox/widget/nls/hu/ColorPicker.js
index 1cd6930..56838e2 100644
--- a/dojox/widget/nls/hu/ColorPicker.js
+++ b/dojox/widget/nls/hu/ColorPicker.js
@@ -1,5 +1,7 @@
+define(
+//begin v1.x content
 ({
 huePickerTitle: "Árnyalat kiválasztó",
 saturationPickerTitle: "Telítettség kiválasztó"
 })
-
+);
diff --git a/dojox/widget/nls/hu/Wizard.js b/dojox/widget/nls/hu/Wizard.js
index 83a8b52..735ff4e 100644
--- a/dojox/widget/nls/hu/Wizard.js
+++ b/dojox/widget/nls/hu/Wizard.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 next: "Következő",
 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 d43606c..248bb12 100644
--- a/dojox/widget/nls/it/ColorPicker.js
+++ b/dojox/widget/nls/it/ColorPicker.js
@@ -1,5 +1,7 @@
+define(
+//begin v1.x content
 ({
 huePickerTitle: "Selettore tonalità",
 saturationPickerTitle: "Selettore saturazione"
 })
-
+);
diff --git a/dojox/widget/nls/it/Wizard.js b/dojox/widget/nls/it/Wizard.js
index 816ab45..7586baf 100644
--- a/dojox/widget/nls/it/Wizard.js
+++ b/dojox/widget/nls/it/Wizard.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 next: "Successivo",
 previous: "Precedente",
 done: "Eseguito"
 })
+//end v1.x content
+);
diff --git a/dojox/widget/nls/ja/ColorPicker.js b/dojox/widget/nls/ja/ColorPicker.js
index f4fa716..a4d1779 100644
--- a/dojox/widget/nls/ja/ColorPicker.js
+++ b/dojox/widget/nls/ja/ColorPicker.js
@@ -1,5 +1,8 @@
+define(
+//begin v1.x content
 ({
 hexLabel: "16 進",
 huePickerTitle: "色調セレクター",
 saturationPickerTitle: "彩度セレクター"
 })
+);
\ No newline at end of file
diff --git a/dojox/widget/nls/ja/Wizard.js b/dojox/widget/nls/ja/Wizard.js
index 8f11a3c..963db06 100644
--- a/dojox/widget/nls/ja/Wizard.js
+++ b/dojox/widget/nls/ja/Wizard.js
@@ -1,5 +1,9 @@
+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 a2e033c..5022643 100644
--- a/dojox/widget/nls/kk/ColorPicker.js
+++ b/dojox/widget/nls/kk/ColorPicker.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 redLabel: "r",
 greenLabel: "д",
@@ -9,4 +11,4 @@ hexLabel: "алтылық",
 huePickerTitle: "Реңкті іріктеу",
 saturationPickerTitle: "Қанықтықты іріктеу"
 })
-
+);
diff --git a/dojox/widget/nls/kk/Wizard.js b/dojox/widget/nls/kk/Wizard.js
index f3ef373..4c796ee 100644
--- a/dojox/widget/nls/kk/Wizard.js
+++ b/dojox/widget/nls/kk/Wizard.js
@@ -1,6 +1,9 @@
+define(
+//begin v1.x content
 ({
 next: "Келесі",
 previous: "Алдыңғы",
 done: "Орындалған"
 })
-
+//end v1.x content
+);
diff --git a/dojox/widget/nls/ko/ColorPicker.js b/dojox/widget/nls/ko/ColorPicker.js
index ed3eaeb..d0d75d4 100644
--- a/dojox/widget/nls/ko/ColorPicker.js
+++ b/dojox/widget/nls/ko/ColorPicker.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 redLabel: "R",
 greenLabel: "G",
@@ -9,3 +11,4 @@ hexLabel: "16진",
 huePickerTitle: "색상 선택자",
 saturationPickerTitle: "채도 선택자"
 })
+);
\ No newline at end of file
diff --git a/dojox/widget/nls/ko/Wizard.js b/dojox/widget/nls/ko/Wizard.js
index e9dea10..4347eb1 100644
--- a/dojox/widget/nls/ko/Wizard.js
+++ b/dojox/widget/nls/ko/Wizard.js
@@ -1,5 +1,9 @@
+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 b2bc168..4fac4eb 100644
--- a/dojox/widget/nls/nb/ColorPicker.js
+++ b/dojox/widget/nls/nb/ColorPicker.js
@@ -1,4 +1,7 @@
+define(
+//begin v1.x content
 ({
 huePickerTitle: "Nyansevelger",
 saturationPickerTitle: "Metningsvelger"
 })
+);
\ No newline at end of file
diff --git a/dojox/widget/nls/nb/Wizard.js b/dojox/widget/nls/nb/Wizard.js
index 1f8d0bc..453de26 100644
--- a/dojox/widget/nls/nb/Wizard.js
+++ b/dojox/widget/nls/nb/Wizard.js
@@ -1,5 +1,9 @@
+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 151d0af..a3b4bec 100644
--- a/dojox/widget/nls/nl/ColorPicker.js
+++ b/dojox/widget/nls/nl/ColorPicker.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 hueLabel: "t",
 saturationLabel: "i",
@@ -5,4 +7,4 @@ valueLabel: "h", /* aka intensity or brightness */
 huePickerTitle: "Tint selecteren",
 saturationPickerTitle: "Intensiteit selecteren"
 })
-
+);
diff --git a/dojox/widget/nls/nl/Wizard.js b/dojox/widget/nls/nl/Wizard.js
index 2d40908..fae9a5b 100644
--- a/dojox/widget/nls/nl/Wizard.js
+++ b/dojox/widget/nls/nl/Wizard.js
@@ -1,5 +1,9 @@
+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 09f18db..0b07a8c 100644
--- a/dojox/widget/nls/pl/ColorPicker.js
+++ b/dojox/widget/nls/pl/ColorPicker.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 redLabel: "c",
 greenLabel: "z",
@@ -9,4 +11,4 @@ hexLabel: "szesnastkowe",
 huePickerTitle: "Selektor barwy",
 saturationPickerTitle: "Selektor nasycenia"
 })
-
+);
diff --git a/dojox/widget/nls/pl/Wizard.js b/dojox/widget/nls/pl/Wizard.js
index 9329bbf..159c701 100644
--- a/dojox/widget/nls/pl/Wizard.js
+++ b/dojox/widget/nls/pl/Wizard.js
@@ -1,6 +1,9 @@
+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 7f7d003..f74664d 100644
--- a/dojox/widget/nls/pt-pt/ColorPicker.js
+++ b/dojox/widget/nls/pt-pt/ColorPicker.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 redLabel: "e",
 greenLabel: "v",
@@ -7,4 +9,4 @@ valueLabel: "val", /* aka intensity or brightness */
 huePickerTitle: "Selector de tonalidade",
 saturationPickerTitle: "Selector de saturação"
 })
-
+);
diff --git a/dojox/widget/nls/pt-pt/Wizard.js b/dojox/widget/nls/pt-pt/Wizard.js
index c6c9ec7..cd77ad2 100644
--- a/dojox/widget/nls/pt-pt/Wizard.js
+++ b/dojox/widget/nls/pt-pt/Wizard.js
@@ -1,5 +1,9 @@
+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 1e5b105..026d356 100644
--- a/dojox/widget/nls/pt/ColorPicker.js
+++ b/dojox/widget/nls/pt/ColorPicker.js
@@ -1,4 +1,7 @@
+define(
+//begin v1.x content
 ({
 huePickerTitle: "Seletor de Matiz",
 saturationPickerTitle: "Seletor de Saturação"
 })
+);
\ No newline at end of file
diff --git a/dojox/widget/nls/pt/Wizard.js b/dojox/widget/nls/pt/Wizard.js
index 2beb4f2..fc5040d 100644
--- a/dojox/widget/nls/pt/Wizard.js
+++ b/dojox/widget/nls/pt/Wizard.js
@@ -1,5 +1,9 @@
+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 85fa9ae..781c510 100644
--- a/dojox/widget/nls/ro/ColorPicker.js
+++ b/dojox/widget/nls/ro/ColorPicker.js
@@ -1,5 +1,7 @@
+define(
+//begin v1.x content
 ({
 huePickerTitle: "Selector nuanţă",
 saturationPickerTitle: "Selector saturaţie"
 })
-
+);
diff --git a/dojox/widget/nls/ro/Wizard.js b/dojox/widget/nls/ro/Wizard.js
index 0c6a488..29c3075 100644
--- a/dojox/widget/nls/ro/Wizard.js
+++ b/dojox/widget/nls/ro/Wizard.js
@@ -1,6 +1,9 @@
+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 764d174..a3d672f 100644
--- a/dojox/widget/nls/ru/ColorPicker.js
+++ b/dojox/widget/nls/ru/ColorPicker.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 redLabel: "к",
 greenLabel: "з",
@@ -9,4 +11,4 @@ hexLabel: "шест",
 huePickerTitle: "Выбор оттенка",
 saturationPickerTitle: "Выбор насыщенности"
 })
-
+);
diff --git a/dojox/widget/nls/ru/Wizard.js b/dojox/widget/nls/ru/Wizard.js
index c4a361c..f597ba2 100644
--- a/dojox/widget/nls/ru/Wizard.js
+++ b/dojox/widget/nls/ru/Wizard.js
@@ -1,5 +1,9 @@
+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 1fe2a1b..b2e8961 100644
--- a/dojox/widget/nls/sk/ColorPicker.js
+++ b/dojox/widget/nls/sk/ColorPicker.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 })
-
+);
diff --git a/dojox/widget/nls/sk/Wizard.js b/dojox/widget/nls/sk/Wizard.js
index e35147e..32a1796 100644
--- a/dojox/widget/nls/sk/Wizard.js
+++ b/dojox/widget/nls/sk/Wizard.js
@@ -1,6 +1,9 @@
+define(
+//begin v1.x content
 ({
 next: "Ďalej",
 previous: "Späť",
 done: "Hotovo"
 })
-
+//end v1.x content
+);
diff --git a/dojox/widget/nls/sl/ColorPicker.js b/dojox/widget/nls/sl/ColorPicker.js
index 6f693ea..8591d25 100644
--- a/dojox/widget/nls/sl/ColorPicker.js
+++ b/dojox/widget/nls/sl/ColorPicker.js
@@ -1,5 +1,7 @@
+define(
+//begin v1.x content
 ({
 huePickerTitle: "Izbirnik odtenka ",
 saturationPickerTitle: "Izbirnik nasičenosti"
 })
-
+);
diff --git a/dojox/widget/nls/sl/Wizard.js b/dojox/widget/nls/sl/Wizard.js
index 2ace11a..8880d1b 100644
--- a/dojox/widget/nls/sl/Wizard.js
+++ b/dojox/widget/nls/sl/Wizard.js
@@ -1,6 +1,9 @@
+define(
+//begin v1.x content
 ({
 next: "Naprej",
 previous: "Nazaj",
 done: "Opravljeno"
 })
-
+//end v1.x content
+);
diff --git a/dojox/widget/nls/sv/ColorPicker.js b/dojox/widget/nls/sv/ColorPicker.js
index d50b6fe..523365d 100644
--- a/dojox/widget/nls/sv/ColorPicker.js
+++ b/dojox/widget/nls/sv/ColorPicker.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 hueLabel: "n",
 saturationLabel: "m",
@@ -5,4 +7,4 @@ valueLabel: "l", /* aka intensity or brightness */
 huePickerTitle: "Välj färgton",
 saturationPickerTitle: "Välj mättnad"
 })
-
+);
diff --git a/dojox/widget/nls/sv/Wizard.js b/dojox/widget/nls/sv/Wizard.js
index 6542886..fab4300 100644
--- a/dojox/widget/nls/sv/Wizard.js
+++ b/dojox/widget/nls/sv/Wizard.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 next: "Nästa",
 previous: "Föregående",
 done: "Stäng"
 })
+//end v1.x content
+);
diff --git a/dojox/widget/nls/th/ColorPicker.js b/dojox/widget/nls/th/ColorPicker.js
index 8ead10c..44769f2 100644
--- a/dojox/widget/nls/th/ColorPicker.js
+++ b/dojox/widget/nls/th/ColorPicker.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 redLabel: "อาร์",
 greenLabel: "จี",
@@ -8,4 +10,4 @@ valueLabel: "วี", /* aka intensity or brightness */
 huePickerTitle: "ตัวเลือกสี",
 saturationPickerTitle: "ตัวเลือกความอิ่มของสี"
 })
-
+);
diff --git a/dojox/widget/nls/th/Wizard.js b/dojox/widget/nls/th/Wizard.js
index 2aaffd3..2e91467 100644
--- a/dojox/widget/nls/th/Wizard.js
+++ b/dojox/widget/nls/th/Wizard.js
@@ -1,6 +1,9 @@
+define(
+//begin v1.x content
 ({
 next: "ถัดไป",
 previous: "ก่อนหน้า",
 done: "เสร็จสิ้น"
 })
-
+//end v1.x content
+);
diff --git a/dojox/widget/nls/tr/ColorPicker.js b/dojox/widget/nls/tr/ColorPicker.js
index be8470d..0e989a6 100644
--- a/dojox/widget/nls/tr/ColorPicker.js
+++ b/dojox/widget/nls/tr/ColorPicker.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 redLabel: "k",
 greenLabel: "y",
@@ -9,4 +11,4 @@ hexLabel: "onaltılı",
 huePickerTitle: "Ton Seçici",
 saturationPickerTitle: "Doygunluk Seçici"
 })
-
+);
diff --git a/dojox/widget/nls/tr/Wizard.js b/dojox/widget/nls/tr/Wizard.js
index a2655aa..cba09c9 100644
--- a/dojox/widget/nls/tr/Wizard.js
+++ b/dojox/widget/nls/tr/Wizard.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 next: "İleri",
 previous: "Geri",
 done: "Bitti"
 })
+//end v1.x content
+);
diff --git a/dojox/widget/nls/zh-tw/ColorPicker.js b/dojox/widget/nls/zh-tw/ColorPicker.js
index 3ff7f19..11cbe6d 100644
--- a/dojox/widget/nls/zh-tw/ColorPicker.js
+++ b/dojox/widget/nls/zh-tw/ColorPicker.js
@@ -1,5 +1,8 @@
+define(
+//begin v1.x content
 ({
 hexLabel: "十六進位",
 huePickerTitle: "色調選取元",
 saturationPickerTitle: "飽和度選取元"
 })
+);
\ No newline at end of file
diff --git a/dojox/widget/nls/zh-tw/Wizard.js b/dojox/widget/nls/zh-tw/Wizard.js
index 3d9f229..017f106 100644
--- a/dojox/widget/nls/zh-tw/Wizard.js
+++ b/dojox/widget/nls/zh-tw/Wizard.js
@@ -1,5 +1,9 @@
+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 f6397a9..e5afeac 100644
--- a/dojox/widget/nls/zh/ColorPicker.js
+++ b/dojox/widget/nls/zh/ColorPicker.js
@@ -1,5 +1,8 @@
+define(
+//begin v1.x content
 ({
 hexLabel: "十六进制",
 huePickerTitle: "色彩选择器",
 saturationPickerTitle: "饱和度选择器"
 })
+);
\ No newline at end of file
diff --git a/dojox/widget/nls/zh/Wizard.js b/dojox/widget/nls/zh/Wizard.js
index 3d9f229..017f106 100644
--- a/dojox/widget/nls/zh/Wizard.js
+++ b/dojox/widget/nls/zh/Wizard.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 next: "下一步",
 previous: "上一步",
 done: "完成"
 })
+//end v1.x content
+);
diff --git a/dojox/widget/tests/test_AnalogGaugeWidget.html b/dojox/widget/tests/test_AnalogGaugeWidget.html
deleted file mode 100644
index e15d8e0..0000000
--- a/dojox/widget/tests/test_AnalogGaugeWidget.html
+++ /dev/null
@@ -1,554 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<title>Analog Gauge Widget</title>
-<style>
-	@import "../gauge/_Gauge.css";
-	@import "../../../dojo/resources/dojo.css";
-	@import "../../../dijit/themes/tundra/tundra.css";
-</style>
-<script type="text/javascript">
-	djConfig = {
-		parseOnLoad: true,
-		isDebug: true
-	};
-</script>
-<script type="text/javascript" src="../../../dojo/dojo.js"></script>
-<script language="JavaScript" type="text/javascript">
-	dojo.require('dojox.widget.AnalogGauge');
-	dojo.require('dojox.widget.gauge.AnalogArcIndicator');
-	dojo.require('dojox.widget.gauge.AnalogNeedleIndicator');
-	dojo.require('dojox.widget.gauge.AnalogArrowIndicator');
-	dojo.require('dijit.form.Button');
-	dojo.require('dojo.parser');
-
-	dojo.addOnLoad(init);
-
-	var gauge, valueIndicator, targetIndicator, handle;
-	var ranges1 = [ {low:5, high:10, hover:'5 - 10'},
-				   {low:10, high:20, hover:'10 - 20'},
-				   {low:20, high:30, hover:'20 - 30'},
-				   {low:30, high:40, hover:'30 - 40'},
-				   {low:40, high:50, hover:'40 - 50'},
-				   {low:50, high:60, hover:'50 - 60'},
-				   {low:60, high:70, hover:'60 - 70'},
-				   {low:70, high:75, hover:'70 - 75'}
-				 ];
-	var ranges2 = [ {low:5, high:10, hover:'5 - 10'},
-				   {low:10, high:20, hover:'10 - 20'},
-				   {low:20, high:30, hover:'20 - 30'},
-				   {low:30, high:40, hover:'30 - 40'},
-				   {low:40, high:50, hover:'40 - 50'},
-				   {low:50, high:60, hover:'50 - 60'},
-				   {low:60, high:70, hover:'60 - 70'},
-				   {low:70, high:75, hover:'70 - 75'}
-				 ];
-	
-	function init() {
-		gauge = dojo.byId("defaultGauge");
-		gauge = new dojox.widget.AnalogGauge({
-			id: "defaultGauge",
-			width: 350,
-			height: 200,
-			cx: 175,
-			cy: 175,
-			radius: 125,
-			ranges: ranges1,
-			minorTicks: {
-				offset: 125,
-				interval: 2.5,
-				length: 5,
-				color: 'gray'
-			},
-			majorTicks: {
-				offset: 125,
-				interval: 5,
-				length: 10
-			},
-			indicators: [
-				new dojox.widget.gauge.AnalogArrowIndicator({
-					value:17, 
-					width: 3,
-					hover:'Value: 17', 
-					title: 'Value'
-				}),
-				new dojox.widget.gauge.AnalogLineIndicator({
-					value:6, 
-					color:'#D00000',
-					width: 3,
-					hover:'Target: 6',
-					title: 'Target'
-				})
-			]
-		}, gauge);
-		gauge.startup();
-		var g = gauge;
-		var int = 10
-		dojo.connect(dijit.byId('changeTicks'), 'onClick', function(){
-			var o = g.majorTicks;
-			o.interval = ++int;
-			g.setMajorTicks(o);
-		});
-
-		/* Entirely programmatic gauge (ranges, ticks, indicators, etc.) */
-		var fill = {
-			'type': 'linear',
-			'x1': 0,
-			'x2': 0,
-			'y2': 0,
-			'y1': gauge.height,
-			'colors': [{offset: 0, color: "#ECECEC"}, {offset: 1, color: "white"}]
-		};
-		gauge = dojo.byId("programmaticGauge");
-		gauge = new dojox.widget.AnalogGauge({
-			id: "programmaticGauge",
-			width: 350,
-			height: 200,
-			cx: 175,
-			cy: 175,
-			radius: 125,
-			background: fill,
-			image: {
-				url: "images/gaugeOverlay.png",
-				width: 280,
-				height: 155,
-				x: 35,
-				y: 38,
-				overlay: true
-			},
-			useRangeStyles: 8
-		}, gauge);
-		gauge.startup();
-		gauge.addRanges(ranges2);
-		gauge.setMajorTicks({
-			length: 5,
-			interval: 5,
-			offset: 125,
-			font: {family: "Arial", style: "italic", variant: 'small-caps', weight: 'bold', size: "18px"}
-		});
-		valueIndicator = new dojox.widget.gauge.AnalogArrowIndicator({
-			value:17, 
-			width: 3,
-			hover:'Value: 17', 
-			title: 'Value',
-			easing: dojo.fx.easing.bounceOut
-		});
-		gauge.addIndicator(valueIndicator);
-		targetIndicator = new dojox.widget.gauge.AnalogLineIndicator({
-			value:6, 
-			color:'#D00000', 
-			width: 3,
-			hover:'Target: 6', 
-			title: 'Target',
-			// Can use string to indicate easing function (just like in de
-			easing: 'dojo.fx.easing.linear'
-		});
-		gauge.addIndicator(targetIndicator);
-		handle = setInterval((function(t, v){
-			return (function(){
-				t.update(Math.floor(Math.random() * 70) + 5);
-				v.update(Math.floor(Math.random() * 70) + 5);
-			});
-		})(valueIndicator, targetIndicator), 3000);
-		dojo.connect(dijit.byId('stop'), 'onClick', function(){
-			clearInterval(handle);
-		});
-
-		gauge = dojo.byId("speedometer");
-		gauge = new dojox.widget.AnalogGauge({
-			id: "speedometer",
-			width:270,
-			height: 230,
-			cx: 135,
-			cy: 135,
-			radius: 125,
-			image: {
-				url: "images/flare.png",
-				width: 112,
-				height: 116,
-				x: 140,
-				y: 40,
-				overlay: true
-			},
-			startAngle: -135,
-			endAngle: 135,
-			useRangeStyles: 8,
-			ranges: [{low:0, high:180, color: 'black'}],
-			majorTicks: {
-				offset: 85,
-				length: 10,
-				interval: 20,
-				color: 'gray'
-			},
-			minorTicks: {
-				offset: 85,
-				length: 5,
-				interval: 5,
-				color: 'gray'
-			},
-			indicators: [new dojox.widget.gauge.AnalogNeedleIndicator({
-							value:0, 
-							width: 3,
-							length: 100,
-							hover:'Value: 0', 
-							title: 'Value',
-							color: 'red'
-			})]
-		}, gauge);
-		gauge.startup();
-
-		gauge = dojo.byId("tachometer");
-		gauge = new dojox.widget.AnalogGauge({
-			id: "tachometer",
-			width:270,
-			height: 230,
-			cx: 135,
-			cy: 135,
-			radius: 125,
-			image: {
-				url: "images/flare.png",
-				width: 112,
-				height: 116,
-				x: 140,
-				y: 40,
-				overlay: true
-			},
-			startAngle: -135,
-			endAngle: 135,
-			useRangeStyles: 8,
-			ranges: [{low:0, high:9000, color: 'black'}],
-			majorTicks: {
-				offset: 75,
-				length: 10,
-				color: 'gray',
-				interval: 1000
-			},
-			minorTicks: {
-				offset: 75,
-				length: 5,
-				color: 'gray',
-				interval: 500
-			},
-			indicators: [new dojox.widget.gauge.AnalogNeedleIndicator({
-							value:0, 
-							width: 3,
-							length: 100,
-							hover:'Value: 0', 
-							title: 'Value',
-							color: 'red'
-			})]
-		}, gauge);
-		gauge.startup();
-
-		// Used for a gradient arc indicator below:
-		var fill = {
-			'type': 'linear',
-			'x1': 50,
-			'y1': 50,
-			'x2': 550,
-			'y2': 550,
-			'colors': [{offset: 0, color: 'black'}, {offset: 0.5, color: 'black'}, {offset: 0.75, color: 'yellow'}, {offset: 1, color: 'red'}]
-		};
-		gauge = dojo.byId("arctest");
-		gauge = new dojox.widget.AnalogGauge({
-			id: "arctest",
-			width: 650,
-			height: 550,
-			radius: 300,
-			cx: 320,
-			cy: 310,
-			startAngle: -135,
-			endAngle: 135,
-			ranges: [
-				{low: 0, high: 100, color: 'black'},
-				{low: 100, high: 200, color: 'black'}
-			],
-			minorTicks: {
-				offset: 235,
-				interval: 5,
-				length: 5,
-				color: 'gray'
-			},
-			majorTicks: {
-				offset: 235,
-				interval: 10,
-				length: 10,
-				color: 'gray'
-			},
-			indicators: [new dojox.widget.gauge.AnalogArcIndicator({
-							value: 200, 
-							width: 20,
-							offset: 280,
-							color: fill,
-							noChange: true,
-							hideValue: true
-						}),
-						new dojox.widget.gauge.AnalogArcIndicator({
-							value: 80, 
-							width: 10,
-							offset: 280,
-							hover:'Arc: 80', 
-							title: 'Arc',
-							color: 'blue'
-						}),
-						new dojox.widget.gauge.AnalogLineIndicator({
-							value:6, 
-							color:'#D00000', 
-							width: 8,
-							hover:'Target: 6', 
-							title: 'Target',
-							// Can use string to indicate easing function (just like in declarative version) 
-							easing: 'dojo.fx.easing.linear'
-						}),
-						new dojox.widget.gauge.AnalogArrowIndicator({
-							value: 20, 
-							width: 8,
-							length: 300,
-							hover:'Arrow: 20', 
-							title: 'Arrow',
-							color: 'red',
-							easing: dojo.fx.easing.bounceOut
-						}),
-						new dojox.widget.gauge.AnalogNeedleIndicator({
-							value: 100, 
-							width: 8,
-							length: 300,
-							hover: 'Needle: 100', 
-							title: 'Needle',
-							color: 'red'
-						})
-			]
-		}, gauge);
-		gauge.startup();
-
-		var fill = {
-			'type': 'linear',
-			'x1': 0,
-			'x2': 0,
-			'y2': 0,
-			'y1': gauge.height,
-			'colors': [{offset: 0, color: "#ECECEC"}, {offset: 1, color: "white"}]
-		};
-		gauge.setBackground(fill);
-	}
-	dojo.addOnUnload(function(){
-		clearInterval(handle);
-	});
-</script>
-</head>
-<body class="tundra">
-<h1>Analog Gauge Widget</h1>
-<h2>Default Colored Gauge</h2>
-<div id="defaultGauge"></div>
-<button dojoType="dijit.form.Button" id="changeTicks">Change Ticks</button>
-<h2>CSS Themed Ranges, Image Overlay, Gradient Background, Updating to Random Values on 3s Timer</h2>
-<div id="programmaticGauge"></div>
-<button dojoType="dijit.form.Button" id="stop">Stop Timer</button>
-<div style="float: left;">
-	<h2>Speedometer</h2>
-	<div id="speedometer"></div>
-</div>
-<div style="float: left;">
-	<h2>Tachometer</h2>
-	<div id="tachometer"></div>
-</div>
-<div style="clear: both;">
-	<h2>Various Indicators Test</h2>
-	<div id="arctest"></div>
-</div>
-<h2>Declarative, Gradient Ranges, Gradient Background, No Indicator Boxes</h2>
-<div	dojoType="dojox.widget.AnalogGauge"
-		id="declarativeGauge"
-		width="270"
-		height="265"
-		cx="110"
-		cy="150"
-		radius="125"
-		startAngle="-45"
-		endAngle="135"
-		useRangeStyles="0"
-		hideValues="true"
-		majorTicks="{length: 5, offset: 125, interval: 5}"
-		background="{
-			'type': 'linear',
-			'x1': 0,
-			'y1': 265,
-			'x2': 0,
-			'y2': 0,
-			'colors': [{offset: 0, color: '#ECECEC'}, {offset: 1, color: 'white'}]
-		}">
-	<div	dojoType="dojox.widget.gauge.Range"
-			low="5"
-			high="10"
-			hover="5 - 10"
-			color="{
-				'type': 'linear',
-				'colors': [{offset: 0, color:'#606060'}, {offset: 1, color: '#707070'}]
-			}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			id="range1"
-			low="10"
-			high="20"
-			hover="10 - 20"
-			color="{
-				'type': 'linear',
-				'colors': [{offset: 0, color:'#707070'}, {offset: 1, color: '#808080'}]
-			}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			id="range2"
-			low="20"
-			high="30"
-			hover="20 - 30"
-			color="{
-				'type': 'linear',
-				'colors': [{offset: 0, color:'#808080'}, {offset: 1, color: '#909090'}]
-			}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			id="range3"
-			low="30"
-			high="40"
-			hover="30 - 40"
-			color="{
-				'type': 'linear',
-				'colors': [{offset: 0, color:'#909090'}, {offset: 1, color: '#A0A0A0'}]
-			}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			id="range4"
-			low="40"
-			high="50"
-			hover="40 - 50"
-			color="{
-				'type': 'linear',
-				'colors': [{offset: 0, color:'#A0A0A0'}, {offset: 1, color: '#B0B0B0'}]
-			}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			id="range5"
-			low="50"
-			high="60"
-			hover="50 - 60"
-			color="{
-				'type': 'linear',
-				'colors': [{offset: 0, color:'#B0B0B0'}, {offset: 1, color: '#C0C0C0'}]
-			}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			id="range6"
-			low="60"
-			high="70"
-			hover="60 - 70"
-			color="{
-				'type': 'linear',
-				'colors': [{offset: 0, color:'#C0C0C0'}, {offset: 1, color: '#D0D0D0'}]
-			}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			id="range7"
-			low="70"
-			high="75"
-			hover="70 - 75"
-			color="{
-				'type': 'linear',
-				'colors': [{offset: 0, color:'#D0D0D0'}, {offset: 1, color: '#E0E0E0'}]
-			}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.AnalogLineIndicator"
-			id="target"
-			value="6"
-			color="#D00000"
-			width="3"
-			hover="Target: 6"
-			title="Target">
-	</div>
-	<div 	dojoType="dojox.widget.gauge.AnalogArrowIndicator"
-			id="value"
-			value="17"
-			type="arrow"
-			length="135"
-			width="3"
-			hover="Value: 17"
-			title="Value">
-	</div>
-</div>
-<h2>Declarative, (Ugly) Colored Ranges, No Numbers, No Indicator Boxes</h2>
-<div	dojoType="dojox.widget.AnalogGauge"
-		id="declarativeGauge2"
-		width="270"
-		height="270"
-		cx="135"
-		cy="135"
-		radius="125"
-		startAngle="-90"
-		endAngle="270"
-		useRangeStyles="0"
-		hideValues="true"
-		background="{color: 'green'}">
-	<div	dojoType="dojox.widget.gauge.Range"
-			low="5"
-			high="10"
-			hover="5 - 10"
-			color="{color: 'red'}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			low="10"
-			high="20"
-			hover="10 - 20"
-			color="{color: '#FFA500'}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			low="20"
-			high="30"
-			hover="20 - 30"
-			color="{color: 'yellow'}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			low="30"
-			high="40"
-			hover="30 - 40"
-			color="{color: '#7FFF00'}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			low="40"
-			high="50"
-			hover="40 - 50"
-			color="{color: '#00FFFF'}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			low="50"
-			high="60"
-			hover="50 - 60"
-			color="{color: 'blue'}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			low="60"
-			high="70"
-			hover="60 - 70"
-			color="{color: '#191970'}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			low="70"
-			high="75"
-			hover="70 - 75"
-			color="{color: 'purple'}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.AnalogLineIndicator"
-			value="6"
-			color="#D00000"
-			width="3"
-			hover="Target: 6"
-			title="Target">
-	</div>
-	<div 	dojoType="dojox.widget.gauge.AnalogArrowIndicator"
-			value="55"
-			length="135"
-			width="3"
-			hover="Value: 55"
-			title="Value">
-	</div>
-</div>
-</body>
-</html>
diff --git a/dojox/widget/tests/test_BarGaugeWidget.html b/dojox/widget/tests/test_BarGaugeWidget.html
deleted file mode 100644
index a74aafc..0000000
--- a/dojox/widget/tests/test_BarGaugeWidget.html
+++ /dev/null
@@ -1,339 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<title>Bar Gauge Widget</title>
-<style>
-	@import "../gauge/_Gauge.css";
-	@import "../../../dojo/resources/dojo.css";
-	@import "../../../dijit/themes/tundra/tundra.css";
-</style>
-<script type="text/javascript">
-	djConfig = {
-		parseOnLoad: true,
-		isDebug: true
-	};
-</script>
-<script type="text/javascript" src="../../../dojo/dojo.js"></script>
-<script language="JavaScript" type="text/javascript">
-	dojo.require('dojox.widget.BarGauge');
-	dojo.require('dojox.widget.gauge.BarIndicator');
-	dojo.require('dijit.form.Button');
-	dojo.require('dojo.parser');
-
-	dojo.addOnLoad(init);
-
-	var gauge, valueIndicator, targetIndicator, handle;
-	var ranges1 = [ {low:5, high:10, hover:'5 - 10'},
-				   {low:10, high:20, hover:'10 - 20'},
-				   {low:20, high:30, hover:'20 - 30'},
-				   {low:30, high:40, hover:'30 - 40'},
-				   {low:40, high:50, hover:'40 - 50'},
-				   {low:50, high:60, hover:'50 - 60'},
-				   {low:60, high:70, hover:'60 - 70'},
-				   {low:70, high:75, hover:'70 - 75'}
-				 ];
-	var ranges2 = [ {low:5, high:10, hover:'5 - 10'},
-				   {low:10, high:20, hover:'10 - 20'},
-				   {low:20, high:30, hover:'20 - 30'},
-				   {low:30, high:40, hover:'30 - 40'},
-				   {low:40, high:50, hover:'40 - 50'},
-				   {low:50, high:60, hover:'50 - 60'},
-				   {low:60, high:70, hover:'60 - 70'},
-				   {low:70, high:75, hover:'70 - 75'}
-				 ];
-	
-	function init() {
-		gauge = dojo.byId("defaultGauge");
-		gauge = new dojox.widget.BarGauge({
-			id: "defaultGauge",
-			width: 300,
-			height: 55,
-			dataHeight: 25,
-			dataWidth: 275,
-			dataY: 25,
-			dataX: 10,
-			ranges: ranges1,
-			majorTicks: {
-				length: 5,
-				width: 1,
-				offset: -5,
-				interval: 5
-			},
-			indicators: [
-				new dojox.widget.gauge.BarIndicator({
-					value:17,
-					width: 7,
-					hover:'Value: 17',
-					title: 'Value'
-				}),
-				new dojox.widget.gauge.BarLineIndicator({
-					value:6,
-					color:'#D00000',
-					hover:'Target: 6',
-					title: 'Target'
-				})
-			]
-		}, gauge);
-		gauge.startup();
-
-		var fill = {
-			type: "linear",
-			x1: 0,
-			y1: gauge.height,
-			x2: 0,
-			y2: 0,
-			colors: [{offset: 0, color: "#ECECEC"}, {offset: 1, color: "white"}]
-		};
-		gauge = dojo.byId("programmaticGauge");
-		gauge = new dojox.widget.BarGauge({
-			id: "programmaticGauge",
-			width: 300,
-			height: 55,
-			dataHeight: 25,
-			dataWidth: 275,
-			dataX: 10,
-			dataY: 25,
-			useRangeStyles: 8,
-			background: fill
-		}, gauge);
-		gauge.startup();
-		
-		gauge.addRanges(ranges2);
-		gauge.setMinorTicks({interval: 1,
-							 length:2,
-							 offset:-2,
-							 width: 1});
-		gauge.setMajorTicks({interval: 5,
-							 length:5,
-							 offset:-5,
-							 width: 1,
-							 font: {family: "Arial", style: "italic", variant: 'small-caps', weight: 'bold', size: "12px"}});
-		valueIndicator = new dojox.widget.gauge.BarIndicator({
-			value:17,
-			width: 7,
-			hover:'Value: 17', 
-			title: 'Value',
-			easing: dojo.fx.easing.bounceOut
-		});
-		targetIndicator = new dojox.widget.gauge.BarLineIndicator({
-			value:6,
-			color:'#D00000',
-			hover:'Target: 6',
-			title: 'Target',
-			// Can use string to indicate easing function (just like in declarative)
-			easing: 'dojo.fx.easing.linear'
-		});
-		gauge.addIndicator(targetIndicator);
-		gauge.addIndicator(valueIndicator);
-		//targetIndicator.update(Math.floor(Math.random() * 70) + 5);
-		handle = setInterval((function(t, v){
-			return (function(){
-				t.update(Math.floor(Math.random() * 70) + 5);
-				v.update(Math.floor(Math.random() * 70) + 5);
-			});
-		})(valueIndicator, targetIndicator), 3000);
-		dojo.connect(dijit.byId('stop'), 'onClick', function(){
-			clearInterval(handle);
-		});
-	}
-	dojo.addOnUnload(function(){
-		clearInterval(handle);
-	});
-</script>
-</head>
-<body class="tundra">
-<h1>Bar Gauge Widget</h1>
-<h2>Default Colored Gauge</h2>
-<div id="defaultGauge"></div>
-<h2>CSS Themed Ranges, Gradient Background, Updating to Random Values on 3s Timer</h2>
-<div id="programmaticGauge"></div>
-<button dojoType="dijit.form.Button" id="stop">Stop Timer</button>
-<h2>Declarative, Gradient Ranges, Gradient Background, No Indicator Boxes</h2>
-<div	dojoType="dojox.widget.BarGauge"
-		id="declarativeGauge"
-		width="300"
-		height="55"
-		dataHeight="25"
-		dataWidth="275"
-		dataX="10"
-		dataY="25"
-		useRangeStyles="0"
-		hideValues="true"
-		majorTicks="{length: 5, width: 1, offset: -5, interval: 5}"
-		background="{
-			type: 'linear',
-			x1: 0,
-			x2: 0,
-			y1: 55,
-			y2: 0,
-			colors: [{offset: 0, color: '#ECECEC'}, {offset: 1, color: 'white'}]
-		}">
-	<div	dojoType="dojox.widget.gauge.Range"
-			low="5"
-			high="10"
-			hover="5 - 10"
-			color="{
-				'type': 'linear',
-				'colors': [{offset: 0, color:'#606060'}, {offset: 1, color: '#707070'}]
-			}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			id="range1"
-			low="10"
-			high="20"
-			hover="10 - 20"
-			color="{
-				'type': 'linear',
-				'colors': [{offset: 0, color:'#707070'}, {offset: 1, color: '#808080'}]
-			}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			id="range2"
-			low="20"
-			high="30"
-			hover="20 - 30"
-			color="{
-				'type': 'linear',
-				'colors': [{offset: 0, color:'#808080'}, {offset: 1, color: '#909090'}]
-			}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			id="range3"
-			low="30"
-			high="40"
-			hover="30 - 40"
-			color="{
-				'type': 'linear',
-				'colors': [{offset: 0, color:'#909090'}, {offset: 1, color: '#A0A0A0'}]
-			}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			id="range4"
-			low="40"
-			high="50"
-			hover="40 - 50"
-			color="{
-				'type': 'linear',
-				'colors': [{offset: 0, color:'#A0A0A0'}, {offset: 1, color: '#B0B0B0'}]
-			}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			id="range5"
-			low="50"
-			high="60"
-			hover="50 - 60"
-			color="{
-				'type': 'linear',
-				'colors': [{offset: 0, color:'#B0B0B0'}, {offset: 1, color: '#C0C0C0'}]
-			}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			id="range6"
-			low="60"
-			high="70"
-			hover="60 - 70"
-			color="{
-				'type': 'linear',
-				'colors': [{offset: 0, color:'#C0C0C0'}, {offset: 1, color: '#C0C0C0'}]
-			}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			id="range7"
-			low="70"
-			high="75"
-			hover="70 - 75"
-			color="{
-				'type': 'linear',
-				'colors': [{offset: 0, color:'#C0C0C0'}, {offset: 1, color: '#E0E0E0'}]
-			}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.BarLineIndicator"
-			id="target"
-			value="6"
-			color="#D00000"
-			width="3"
-			hover="Target: 6"
-			title="Target">
-	</div>
-	<div 	dojoType="dojox.widget.gauge.BarIndicator"
-			id="value"
-			value="17"
-			length="135"
-			width="3"
-			hover="Value: 17"
-			title="Value">
-	</div>
-</div>
-<h2>Declarative, (Ugly) Colored Ranges, No Numbers, No Indicator Boxes</h2>
-<div	dojoType="dojox.widget.BarGauge"
-		id="declarativeGauge2"
-		width="300"
-		height="35"
-		dataHeight="25"
-		dataWidth="290"
-		useRangeStyles="0"
-		hideValues="true"
-		background="{color: 'green'}">
-	<div	dojoType="dojox.widget.gauge.Range"
-			low="5"
-			high="10"
-			hover="5 - 10"
-			color="{color: 'red'}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			low="10"
-			high="20"
-			hover="10 - 20"
-			color="{color: '#FFA500'}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			low="20"
-			high="30"
-			hover="20 - 30"
-			color="{color: 'yellow'}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			low="30"
-			high="40"
-			hover="30 - 40"
-			color="{color: '#7FFF00'}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			low="40"
-			high="50"
-			hover="40 - 50"
-			color="{color: '#00FFFF'}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			low="50"
-			high="60"
-			hover="50 - 60"
-			color="{color: 'blue'}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			low="60"
-			high="70"
-			hover="60 - 70"
-			color="{color: '#191970'}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.Range"
-			low="70"
-			high="75"
-			hover="70 - 75"
-			color="{color: 'purple'}">
-	</div>
-	<div	dojoType="dojox.widget.gauge.BarLineIndicator"
-			value="6"
-			color="#D00000"
-			hover="Target: 6"
-			title="Target">
-	</div>
-	<div 	dojoType="dojox.widget.gauge.BarIndicator"
-			value="55"
-			width="7"
-			hover="Value: 55"
-			title="Value">
-	</div>
-</div>
-</body>
-</html>
diff --git a/dojox/widget/tests/test_Calendar.html b/dojox/widget/tests/test_Calendar.html
index a3b38a2..c78ca7e 100644
--- a/dojox/widget/tests/test_Calendar.html
+++ b/dojox/widget/tests/test_Calendar.html
@@ -19,14 +19,12 @@
 
 		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 
-		<script type="text/javascript" src="../../../dijit/dijit.js"></script>
-		<script type="text/javascript" src="../../../dijit/_Calendar.js"></script>
-		<script type="text/javascript" src="../FisheyeLite.js"></script>
-		<script type="text/javascript" src="../../fx/_base.js"></script>
-		<script type="text/javascript" src="../Calendar.js"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-			dojo.require("dojox.fx");
+			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(
diff --git a/dojox/widget/tests/test_CalendarViews.html b/dojox/widget/tests/test_CalendarViews.html
index b9d08ea..358d7fc 100644
--- a/dojox/widget/tests/test_CalendarViews.html
+++ b/dojox/widget/tests/test_CalendarViews.html
@@ -22,13 +22,11 @@
 		<!-- not needed, for testing alternate themes -->
 		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 
-		<script type="text/javascript" src="../../../dijit/dijit.js"></script>
-		<script type="text/javascript" src="../../../dijit/_Calendar.js"></script>
-		<script type="text/javascript" src="../Calendar.js"></script>
-		<script type="text/javascript" src="../CalendarViews.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){
diff --git a/dojox/widget/tests/test_ColorPicker-async.html b/dojox/widget/tests/test_ColorPicker-async.html
new file mode 100644
index 0000000..87782cc
--- /dev/null
+++ b/dojox/widget/tests/test_ColorPicker-async.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>Dojox ColorPicker Test</title>
+	
+	<!-- required: a default theme file, and ColorPicker css -->
+	<link rel="stylesheet" id="themeStyles" href="../../../dijit/themes/tundra/tundra.css">
+	<link rel="stylesheet" href="../ColorPicker/ColorPicker.css">
+
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../../../dijit/tests/css/dijitTests.css"; 
+		#absolutey {
+			position:absolute;
+			top: 62px;
+			left: 362px;
+		}
+	</style>
+	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad:1,isDebug:1,async:1"></script>
+	<script type="text/javascript">
+		require([
+				"dojo",
+				"dijit",
+				"dijit/form/Button",
+				"dojox/widget/ColorPicker",
+				"dojo/parser"], function(dojo,dijit){
+			dojo.ready(function(){
+				dojo.connect(dijit.byId("testFocusButton"), "onClick", function(){
+					dijit.byId("picker").focus();
+				});
+			});
+		});
+		var handler = function(val,id){
+			dojo.byId(id).value = val;
+		};
+	</script>
+</head>
+<body class="tundra">
+
+	<h1 class="testTitle">Dojox ColorPicker test</h1>
+
+	<h3>defaults:</h3>
+	<div id="picker" dojoType="dojox.widget.ColorPicker"
+		value="#9ebf6c"
+		onChange="handler(arguments[0],'onchangeOne')"
+	></div>
+	<p>Current value: <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"
+		animatePoint="false"
+		showHsv="false"
+		showRgb="false"	
+		webSafe="false"
+		onChange="handler(arguments[0],'onchangeTwo')"
+	></div>
+	<p>Current value: <input readonly="true" id="onchangeTwo" value="???" /></p>
+	
+	<h3>Fires onChange a lot:</h3>
+	<div id="pickerLive" dojoType="dojox.widget.ColorPicker"
+		webSafe="false"
+		liveUpdate="true"
+		onChange="handler(arguments[0],'onchangeThree')"
+	></div>
+	<p>Current value: <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>
+		<input dojoType="dojox.widget.ColorPicker" value="#ededed">
+	</div>
+
+	<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_ColorPicker.html b/dojox/widget/tests/test_ColorPicker.html
index fb6bc54..592e541 100644
--- a/dojox/widget/tests/test_ColorPicker.html
+++ b/dojox/widget/tests/test_ColorPicker.html
@@ -22,11 +22,9 @@
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
 
-	<!-- do not use! only for testing dynamic themes -->
+	<!-- do not use! only for testing dynamic themes 
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
-	
-	<!-- debugging include -->
-	<script type="text/javascript" src="../ColorPicker.js"></script>
+-->	
 	<script type="text/javascript">
 		dojo.require("dojox.widget.ColorPicker");
 		dojo.require("dijit.form.Button");
diff --git a/dojox/widget/tests/test_Dialog.html b/dojox/widget/tests/test_Dialog.html
index be9ef6d..aa36ff8 100644
--- a/dojox/widget/tests/test_Dialog.html
+++ b/dojox/widget/tests/test_Dialog.html
@@ -25,12 +25,8 @@
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 	
 	<script type="text/javascript">
-	    dojo.require("dojox.widget.DialogSimple");
-		dojo.require("dojox.widget.Dialog");
-		dojo.require("dojo.fx.easing");
-		dojo.require("dijit.form.Button");
-		dojo.addOnLoad(function(){
-			
+	    require(["dojo/parser","dojox/widget/DialogSimple", "dojox/widget/Dialog", "dojo/fx/easing", "dijit/form/Button", "dojo/domReady!"], function(){
+	                    
 			// a programatic test:
 			var thinger = new dojox.widget.Dialog({
 				title:"foobar",
@@ -79,8 +75,11 @@
 				},
 				label:"double show."
 			}).placeAt("testholder");
-			
-		});
+	       
+	        dojo.parser.parse();
+	        
+	    });
+
 	</script>
 </head>
 <body class="claro">
diff --git a/dojox/widget/tests/test_MultiSelectCalendar-async.html b/dojox/widget/tests/test_MultiSelectCalendar-async.html
new file mode 100644
index 0000000..b9d4194
--- /dev/null
+++ b/dojox/widget/tests/test_MultiSelectCalendar-async.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Multi select calendar test </title>
+<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">
+		require([
+				"dojox/widget/MultiSelectCalendar",
+				"dojo/parser"], function(){});
+	</script>
+</head>
+<body class="claro">
+	<div>Calendar #1: No date selected dijit.byId('MSC1').get('value') should return an empty array. Add some dates and check again. You can select/unselect single dates or ranges from right to left or left to right. Use your mouse or keyboard</div>
+	<div dojoType="dojox.widget.MultiSelectCalendar" id="MSC1" style="display:inline-block"></div>
+
+	<div style="margin-top: 2em;">Calendar #2: a few date selected upon instantiation dijit.byId('MSC2').get('value') should return those selected dates. Since returnIsoRanges is by default set to false, it will return all the dates individually</div>
+	<div dojoType="dojox.widget.MultiSelectCalendar" value=['2011-05-07','2011-05-08','2011-05-09','2011-05-23'] id="MSC2" style="display:inline-block"></div>
+	
+	<div style="margin-top: 2em;">Calendar #3: same dates selected as #2 but with returnIsoRanges=true. dijit.byId('MSC3').get('value') should return all selected dates individually</div>
+	<div dojoType="dojox.widget.MultiSelectCalendar" returnIsoRanges=true value=['2011-05-07','2011-05-08','2011-05-09','2011-05-23'] id="MSC3" style="display:inline-block"></div>
+	
+	<div style="margin-top: 2em;">Calendar #4: We instantiate calendar with a range (with the two dates in the wrong order,) with returnIsoRanges=false dijit.byId('MSC4').get('value') should return all the dates in the month of may. Do the following: dijit.byId('MSC4').set('returnIsoRanges',true)  and then re-poll the value, you should have it returned as an iso range</div>
+	<div dojoType="dojox.widget.MultiSelectCalendar" value=['2011-05-31/2011-05-01'] id="MSC4" style="display:inline-block"></div>
+</body>
+</html>
+ 
\ No newline at end of file
diff --git a/dojox/widget/tests/test_MultiSelectCalendar.html b/dojox/widget/tests/test_MultiSelectCalendar.html
new file mode 100644
index 0000000..2bc5fc0
--- /dev/null
+++ b/dojox/widget/tests/test_MultiSelectCalendar.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Multi select calendar test </title>
+<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">
+       dojo.require("dojo.parser");
+		dojo.require('dojox.widget.MultiSelectCalendar');
+    </script>
+</head>
+
+
+<body class="claro">
+<div>Calendar #1: No date selected dijit.byId('MSC1').get('value') should return an empty array. Add some dates and check again. You can select/unselect single dates or ranges from right to left or left to right. Use your mouse or keyboard</div>
+<div dojoType="dojox.widget.MultiSelectCalendar" id="MSC1" value="[]" style="display:inline-block"></div>
+</br>
+<div style="margin-top: 2em;">Calendar #2: a few date selected upon instantiation dijit.byId('MSC2').get('value') should return those selected dates. Since returnIsoRanges is by default set to false, it will return all the dates individually</div>
+<div dojoType="dojox.widget.MultiSelectCalendar" value=['2011-05-07','2011-05-08','2011-05-09','2011-05-23'] id="MSC2" style="display:inline-block"></div>
+
+<div style="margin-top: 2em;">Calendar #3: same dates selected as #2 but with returnIsoRanges=true. dijit.byId('MSC3').get('value') should return all selected dates individually</div>
+<div dojoType="dojox.widget.MultiSelectCalendar" returnIsoRanges=true value=['2011-05-07','2011-05-08','2011-05-09','2011-05-23'] id="MSC3" style="display:inline-block"></div>
+
+<div style="margin-top: 2em;">Calendar #4: We instantiate calendar with a range (with the two dates in the wrong order,) with returnIsoRanges=false dijit.byId('MSC4').get('value') should return all the dates in the month of may. Do the following: dijit.byId('MSC4').set('returnIsoRanges',true)  and then re-poll the value, you should have it returned as an iso range</div>
+<div dojoType="dojox.widget.MultiSelectCalendar" value=['2011-05-31/2011-05-01'] id="MSC4" style="display:inline-block"></div>
+</body>
+</html>
+ 
diff --git a/dojox/widget/tests/test_TitleGroup.html b/dojox/widget/tests/test_TitleGroup.html
index 3d126e2..33e21ac 100644
--- a/dojox/widget/tests/test_TitleGroup.html
+++ b/dojox/widget/tests/test_TitleGroup.html
@@ -30,32 +30,30 @@
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 	
-	<!-- debugging include -->
-	<script type="text/javascript" src="../TitleGroup.js"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.widget.TitleGroup");
 		dojo.require("dijit.form.Button");
 		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-		
+
 		dojo.ready(function(){
-			
+
 			var tg = new dojox.widget.TitleGroup({
 				style:"width:500px;"
 			}).placeAt("holder");
-			
+
 			tg.addChild(new dijit.TitlePane({ title:"Woot.", open:true }));
 			tg.addChild(new dijit.TitlePane({ title:"Second", open:false }));
 			new dijit.TitlePane({ title:"Testing placeAt", open:false }).placeAt(tg);
 			new dijit.TitlePane({ title:"Removed", open:false, id:"killer" }).placeAt(tg);
-			
+
 			tg.startup();
-			
+
 			setTimeout(function(){
 				tg.removeChild(dijit.byId("killer")).placeAt("graveyard");
 			}, 3000);
-			
+
 		});
-		
+
 	</script>
 </head>
 <body class="claro">
@@ -88,19 +86,19 @@
 	</div>
 
 	<div class="clear"></div>
-	
+
 	<h2>A TitlePane for good measure:</h2>
-	
+
 	<div dojoType="dijit.TitlePane" title="Basic, for Sanity" style="width:300px">
 		<p>Lorem, ipsum <a href="#">dolor</a></p>
 	</div>
-	
+
 	<h2>Programattic</h2>
-	
+
 	<div id="holder"></div>
-	
+
 	<h2>Once removed, will show up here:</h2>
 	<div id="graveyard"></div>
-	
+
 </body>
 </html>
diff --git a/dojox/widget/tests/test_Wizard.html b/dojox/widget/tests/test_Wizard.html
index 1d390b3..711f28c 100644
--- a/dojox/widget/tests/test_Wizard.html
+++ b/dojox/widget/tests/test_Wizard.html
@@ -13,8 +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="../Wizard.js"></script>
 
 	<script type="text/javascript">
 		dojo.require("dojox.widget.Wizard");
diff --git a/dojox/wire/demos/WidgetRepeater.js b/dojox/wire/demos/WidgetRepeater.js
index 6585520..3304ec5 100644
--- a/dojox/wire/demos/WidgetRepeater.js
+++ b/dojox/wire/demos/WidgetRepeater.js
@@ -19,7 +19,7 @@ dojo.declare("dojox.wire.demos.WidgetRepeater", [ dijit._Widget, dijit._Template
 		//		The parameters to pass to the widget.
 		try{
 			if(dojo.isString(this.widget)){
-				dojo.require(this.widget);
+				// dojo.require(this.widget);	confuses new AMD builder, include resource manually first
 				this.widget = dojo.getObject(this.widget);
 			}
 			this.addChild(new this.widget(obj));
diff --git a/dojox/wire/ml/Action.js b/dojox/wire/ml/Action.js
index a36d7a5..0f249e0 100644
--- a/dojox/wire/ml/Action.js
+++ b/dojox/wire/ml/Action.js
@@ -1,5 +1,4 @@
 dojo.provide("dojox.wire.ml.Action");
-dojo.provide("dojox.wire.ml.ActionFilter");
 
 dojo.require("dijit._Widget");
 dojo.require("dijit._Container");
diff --git a/dojox/wire/ml/Data.js b/dojox/wire/ml/Data.js
index 44e2c79..0d62e24 100644
--- a/dojox/wire/ml/Data.js
+++ b/dojox/wire/ml/Data.js
@@ -1,5 +1,4 @@
 dojo.provide("dojox.wire.ml.Data");
-dojo.provide("dojox.wire.ml.DataProperty");
 
 dojo.require("dijit._Widget");
 dojo.require("dijit._Container");
diff --git a/dojox/wire/ml/JsonHandler.js b/dojox/wire/ml/JsonHandler.js
new file mode 100644
index 0000000..ab98184
--- /dev/null
+++ b/dojox/wire/ml/JsonHandler.js
@@ -0,0 +1,42 @@
+dojo.provide("dojox.wire.ml.JsonHandler");
+
+dojo.require("dojox.wire.ml.RestHandler");
+dojo.require("dojox.wire._base");
+dojo.require("dojox.wire.ml.util");
+
+
+dojo.declare("dojox.wire.ml.JsonHandler", dojox.wire.ml.RestHandler, {
+	//	summary:
+	//		A REST service handler for JSON
+	//	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:
+		//		Generate a request content
+		//	description:
+		//		If 'method' is "POST" or "PUT", the first parameter in
+		//		'parameter' is used to generate a JSON content.
+		//	method:
+		//		A method name
+		//	parameters:
+		//		An array of parameters
+		//	returns:
+		//		A request content
+		var content = null;
+		if(method == "POST" || method == "PUT"){
+			var p = (parameters ? parameters[0] : undefined);
+			if(p){
+				if(dojo.isString(p)){
+					content = p;
+				}else{
+					content = dojo.toJson(p);
+				}
+			}
+		}
+		return content; //String
+	}
+});
diff --git a/dojox/wire/ml/RestHandler.js b/dojox/wire/ml/RestHandler.js
new file mode 100644
index 0000000..7c70b98
--- /dev/null
+++ b/dojox/wire/ml/RestHandler.js
@@ -0,0 +1,143 @@
+dojo.provide("dojox.wire.ml.RestHandler");
+
+dojo.require("dojox.wire._base");
+dojo.require("dojox.wire.ml.util");
+
+dojo.declare("dojox.wire.ml.RestHandler", null, {
+	//	summary:
+	//		A REST service handler
+	//	description:
+	//		This class serves as a base REST service.
+	//		Sub-classes may override _getContent() and _getResult() to handle
+	//		specific content types.
+	contentType: "text/plain",
+	handleAs: "text",
+
+	bind: function(method, parameters, deferred, url){
+		//	summary:
+		//		Call a service method with parameters.
+		//	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:
+		//		A method name
+		//	parameters:
+		//		An array of parameters
+		//	deferred:
+		//		'Deferred'
+		//	url:
+		//		A URL for the method
+		method = method.toUpperCase();
+		var self = this;
+		var args = {
+			url: this._getUrl(method, parameters, url),
+			contentType: this.contentType,
+			handleAs: this.handleAs,
+			headers: this.headers,
+			preventCache: this.preventCache
+		};
+		var d = null;
+		if(method == "POST"){
+			args.postData = this._getContent(method, parameters);
+			d = dojo.rawXhrPost(args);
+		}else if(method == "PUT"){
+			args.putData = this._getContent(method, parameters);
+			d = dojo.rawXhrPut(args);
+		}else if(method == "DELETE"){
+			d = dojo.xhrDelete(args);
+		}else{ // "GET"
+			d = dojo.xhrGet(args);
+		}
+		d.addCallbacks(function(result){
+			deferred.callback(self._getResult(result));
+		}, function(error){
+			deferred.errback(error);
+		});
+	},
+
+	_getUrl: function(/*String*/method, /*Array*/parameters, /*String*/url){
+		//	summary:
+		//		Generate a URL
+		//	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:
+		//		A method name
+		//	parameters:
+		//		An array of parameters
+		//	url:
+		//		A base URL
+		//	returns:
+		//		A URL
+		var query;
+		if(method == "GET" || method == "DELETE"){
+			if(parameters.length > 0){
+				query = parameters[0];
+			}
+		}else{ // "POST" || "PUT"
+			if(parameters.length > 1){
+				query = parameters[1];
+			}
+		}
+		if(query){
+			var queryString = "";
+			for(var name in query){
+				var value = query[name];
+				if(value){
+					value = encodeURIComponent(value);
+					var variable = "{" + name + "}";
+					var index = url.indexOf(variable);
+					if(index >= 0){ // encode in path
+						url = url.substring(0, index) + value + url.substring(index + variable.length);
+					}else{ // encode as query string
+						if(queryString){
+							queryString += "&";
+						}
+						queryString += (name + "=" + value);
+					}
+				}
+			}
+			if(queryString){
+				url += "?" + queryString;
+			}
+		}
+		return url; //String
+	},
+
+	_getContent: function(/*String*/method, /*Array*/parameters){
+		//	summary:
+		//		Generate a request content
+		//	description:
+		//		If 'method' is "POST" or "PUT", the first parameter in
+		//		'parameters' is returned.
+		//	method:
+		//		A method name
+		//	parameters:
+		//		An array of parameters
+		//	returns:
+		//		A request content
+		if(method == "POST" || method == "PUT"){
+			return (parameters ? parameters[0] : null); //anything
+		}else{
+			return null; //null
+		}
+	},
+
+	_getResult: function(/*anything*/data){
+		//	summary:
+		//		Extract a result
+		//	description:
+		//		A response data is returned as is.
+		//	data:
+		//		A response data returned by a service
+		//	returns:
+		//		A result object
+		return data; //anything
+	}
+});
diff --git a/dojox/wire/ml/Service.js b/dojox/wire/ml/Service.js
index 8ecc11c..c454622 100644
--- a/dojox/wire/ml/Service.js
+++ b/dojox/wire/ml/Service.js
@@ -1,7 +1,4 @@
 dojo.provide("dojox.wire.ml.Service");
-dojo.provide("dojox.wire.ml.RestHandler");
-dojo.provide("dojox.wire.ml.XmlHandler");
-dojo.provide("dojox.wire.ml.JsonHandler");
 
 dojo.require("dijit._Widget");
 dojo.require("dojox.xml.parser");
@@ -103,234 +100,3 @@ dojo.declare("dojox.wire.ml.Service", dijit._Widget, {
 		return deferred;
 	}
 });
-
-dojo.declare("dojox.wire.ml.RestHandler", null, {
-	//	summary:
-	//		A REST service handler
-	//	description:
-	//		This class serves as a base REST service.
-	//		Sub-classes may override _getContent() and _getResult() to handle
-	//		specific content types.
-	contentType: "text/plain",
-	handleAs: "text",
-
-	bind: function(method, parameters, deferred, url){
-		//	summary:
-		//		Call a service method with parameters.
-		//	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:
-		//		A method name
-		//	parameters:
-		//		An array of parameters
-		//	deferred:
-		//		'Deferred'
-		//	url:
-		//		A URL for the method
-		method = method.toUpperCase();
-		var self = this;
-		var args = {
-			url: this._getUrl(method, parameters, url),
-			contentType: this.contentType,
-			handleAs: this.handleAs,
-			headers: this.headers,
-			preventCache: this.preventCache
-		};
-		var d = null;
-		if(method == "POST"){
-			args.postData = this._getContent(method, parameters);
-			d = dojo.rawXhrPost(args);
-		}else if(method == "PUT"){
-			args.putData = this._getContent(method, parameters);
-			d = dojo.rawXhrPut(args);
-		}else if(method == "DELETE"){
-			d = dojo.xhrDelete(args);
-		}else{ // "GET"
-			d = dojo.xhrGet(args);
-		}
-		d.addCallbacks(function(result){
-			deferred.callback(self._getResult(result));
-		}, function(error){
-			deferred.errback(error);
-		});
-	},
-
-	_getUrl: function(/*String*/method, /*Array*/parameters, /*String*/url){
-		//	summary:
-		//		Generate a URL
-		//	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:
-		//		A method name
-		//	parameters:
-		//		An array of parameters
-		//	url:
-		//		A base URL
-		//	returns:
-		//		A URL
-		var query;
-		if(method == "GET" || method == "DELETE"){
-			if(parameters.length > 0){
-				query = parameters[0];
-			}
-		}else{ // "POST" || "PUT"
-			if(parameters.length > 1){
-				query = parameters[1];
-			}
-		}
-		if(query){
-			var queryString = "";
-			for(var name in query){
-				var value = query[name];
-				if(value){
-					value = encodeURIComponent(value);
-					var variable = "{" + name + "}";
-					var index = url.indexOf(variable);
-					if(index >= 0){ // encode in path
-						url = url.substring(0, index) + value + url.substring(index + variable.length);
-					}else{ // encode as query string
-						if(queryString){
-							queryString += "&";
-						}
-						queryString += (name + "=" + value);
-					}
-				}
-			}
-			if(queryString){
-				url += "?" + queryString;
-			}
-		}
-		return url; //String
-	},
-
-	_getContent: function(/*String*/method, /*Array*/parameters){
-		//	summary:
-		//		Generate a request content
-		//	description:
-		//		If 'method' is "POST" or "PUT", the first parameter in
-		//		'parameters' is returned.
-		//	method:
-		//		A method name
-		//	parameters:
-		//		An array of parameters
-		//	returns:
-		//		A request content
-		if(method == "POST" || method == "PUT"){
-			return (parameters ? parameters[0] : null); //anything
-		}else{
-			return null; //null
-		}
-	},
-
-	_getResult: function(/*anything*/data){
-		//	summary:
-		//		Extract a result
-		//	description:
-		//		A response data is returned as is.
-		//	data:
-		//		A response data returned by a service
-		//	returns:
-		//		A result object
-		return data; //anything
-	}
-});
-
-dojo.declare("dojox.wire.ml.XmlHandler", dojox.wire.ml.RestHandler, {
-	//	summary:
-	//		A REST service handler for XML
-	//	description:
-	//		This class provides XML handling for a REST service.
-	contentType: "text/xml",
-	handleAs: "xml",
-
-	_getContent: function(/*String*/method, /*Array*/parameters){
-		//	description:
-		//		If 'method' is "POST" or "PUT", the first parameter in
-		//		'parameters' is used to generate an XML content.
-		//	method:
-		//		A method name
-		//	parameters:
-		//		An array of parameters
-		//	returns:
-		//		A request content
-		var content = null;
-		if(method == "POST" || method == "PUT"){
-			var p = parameters[0];
-			if(p){
-				if(dojo.isString(p)){
-					content = p;
-				}else{
-					var element = p;
-					if(element instanceof dojox.wire.ml.XmlElement){
-						element = element.element;
-					}else if(element.nodeType === 9 /* DOCUMENT_NODE */){
-						element = element.documentElement;
-					}
-					var declaration = "<?xml version=\"1.0\"?>"; // TODO: encoding?
-					content = declaration + dojox.xml.parser.innerXML(element);
-				}
-			}
-		}
-		return content;
-	},
-
-	_getResult: function(/*Document*/data){
-		//	summary:
-		//		Extract a result
-		//	description:
-		//		A response data (XML Document) is returned wrapped with
-		//		XmlElement.
-		//	data:
-		//		A response data returned by a service
-		//	returns:
-		//		A result object
-		if(data){
-			data = new dojox.wire.ml.XmlElement(data);
-		}
-		return data;
-	}
-});
-
-dojo.declare("dojox.wire.ml.JsonHandler", dojox.wire.ml.RestHandler, {
-	//	summary:
-	//		A REST service handler for JSON
-	//	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:
-		//		Generate a request content
-		//	description:
-		//		If 'method' is "POST" or "PUT", the first parameter in
-		//		'parameter' is used to generate a JSON content.
-		//	method:
-		//		A method name
-		//	parameters:
-		//		An array of parameters
-		//	returns:
-		//		A request content
-		var content = null;
-		if(method == "POST" || method == "PUT"){
-			var p = (parameters ? parameters[0] : undefined);
-			if(p){
-				if(dojo.isString(p)){
-					content = p;
-				}else{
-					content = dojo.toJson(p);
-				}
-			}
-		}
-		return content; //String
-	}
-});
diff --git a/dojox/wire/ml/Transfer.js b/dojox/wire/ml/Transfer.js
index 221fc95..047e914 100644
--- a/dojox/wire/ml/Transfer.js
+++ b/dojox/wire/ml/Transfer.js
@@ -1,8 +1,4 @@
 dojo.provide("dojox.wire.ml.Transfer");
-dojo.provide("dojox.wire.ml.ChildWire");
-dojo.provide("dojox.wire.ml.ColumnWire");
-dojo.provide("dojox.wire.ml.NodeWire");
-dojo.provide("dojox.wire.ml.SegmentWire");
 
 dojo.require("dijit._Widget");
 dojo.require("dijit._Container");
diff --git a/dojox/wire/ml/XmlHandler.js b/dojox/wire/ml/XmlHandler.js
new file mode 100644
index 0000000..5763233
--- /dev/null
+++ b/dojox/wire/ml/XmlHandler.js
@@ -0,0 +1,63 @@
+dojo.provide("dojox.wire.ml.XmlHandler");
+
+dojo.require("dojox.wire.ml.RestHandler");
+dojo.require("dojox.xml.parser");
+dojo.require("dojox.wire._base");
+dojo.require("dojox.wire.ml.util");
+
+
+dojo.declare("dojox.wire.ml.XmlHandler", dojox.wire.ml.RestHandler, {
+	//	summary:
+	//		A REST service handler for XML
+	//	description:
+	//		This class provides XML handling for a REST service.
+	contentType: "text/xml",
+	handleAs: "xml",
+
+	_getContent: function(/*String*/method, /*Array*/parameters){
+		//	description:
+		//		If 'method' is "POST" or "PUT", the first parameter in
+		//		'parameters' is used to generate an XML content.
+		//	method:
+		//		A method name
+		//	parameters:
+		//		An array of parameters
+		//	returns:
+		//		A request content
+		var content = null;
+		if(method == "POST" || method == "PUT"){
+			var p = parameters[0];
+			if(p){
+				if(dojo.isString(p)){
+					content = p;
+				}else{
+					var element = p;
+					if(element instanceof dojox.wire.ml.XmlElement){
+						element = element.element;
+					}else if(element.nodeType === 9 /* DOCUMENT_NODE */){
+						element = element.documentElement;
+					}
+					var declaration = "<?xml version=\"1.0\"?>"; // TODO: encoding?
+					content = declaration + dojox.xml.parser.innerXML(element);
+				}
+			}
+		}
+		return content;
+	},
+
+	_getResult: function(/*Document*/data){
+		//	summary:
+		//		Extract a result
+		//	description:
+		//		A response data (XML Document) is returned wrapped with
+		//		XmlElement.
+		//	data:
+		//		A response data returned by a service
+		//	returns:
+		//		A result object
+		if(data){
+			data = new dojox.wire.ml.XmlElement(data);
+		}
+		return data;
+	}
+});
diff --git a/dojox/xml/DomParser.js b/dojox/xml/DomParser.js
index 43c0c3b..dfe536c 100644
--- a/dojox/xml/DomParser.js
+++ b/dojox/xml/DomParser.js
@@ -1,4 +1,8 @@
-dojo.provide("dojox.xml.DomParser");
+define([
+	"dojo/_base/kernel",// dojo.getObject
+	"dojo/_base/array"	// dojo.forEach
+], function(dojo){
+dojo.getObject("xml", true, dojox);
 
 dojox.xml.DomParser=new (function(){
 	/**********************************************************
@@ -387,3 +391,5 @@ dojox.xml.DomParser=new (function(){
 		return root;
 	};
 })();
+return dojox.xml.DomParser;
+});
diff --git a/dojox/xml/Script.js b/dojox/xml/Script.js
index 9b0a2e8..0bb6464 100644
--- a/dojox/xml/Script.js
+++ b/dojox/xml/Script.js
@@ -1,11 +1,20 @@
-dojo.provide("dojox.xml.Script");
-dojo.require("dojo.parser");
-dojo.require("dojox.xml.widgetParser");
+define([
+	"dojo/_base/kernel",	// dojo.getObject
+	"dojo/_base/declare",
+	"dojo/parser",
+	"./widgetParser"
+], function(declare, parser, widgetParser){
 
-dojo.declare("dojox.xml.Script", null, {
+dojo.getObject("xml", true, dojox);
+
+declare("dojox.xml.Script", null, {
 	constructor: function(props, node){
-		dojo.parser.instantiate(
-			dojox.xml.widgetParser._processScript(node)
+		parser.instantiate(
+			widgetParser._processScript(node)
 		);
 	}
 });
+
+return dojox.xml.Script;
+
+});
diff --git a/dojox/xml/parser.js b/dojox/xml/parser.js
index 1d8ae4c..0559b7a 100644
--- a/dojox/xml/parser.js
+++ b/dojox/xml/parser.js
@@ -1,4 +1,6 @@
-dojo.provide("dojox.xml.parser");
+define(['dojo/_base/kernel', 'dojo/_base/lang', 'dojo/_base/array', 'dojo/_base/window', 'dojo/_base/sniff'], function(dojo){
+
+dojo.getObject("xml.parser", true, dojox);
 
 //DOM type to int value for reference.
 //Ints make for more compact code than full constant names.
@@ -84,7 +86,7 @@ dojox.xml.parser.parse = function(/*String?*/ str, /*String?*/ mimetype){
 		}
 	}
 	return null;	//	null
-}
+};
 
 dojox.xml.parser.textContent = function(/*Node*/node, /*String?*/text){
 	//	summary:
@@ -122,7 +124,7 @@ dojox.xml.parser.textContent = function(/*Node*/node, /*String?*/text){
 		}
 		return _result;	//	String
 	}
-}
+};
 
 dojox.xml.parser.replaceChildren = function(/*Element*/node, /*Node || Array*/ newChildren){
 	//	summary:
@@ -154,7 +156,7 @@ dojox.xml.parser.replaceChildren = function(/*Element*/node, /*Node || Array*/ n
 			node.appendChild(child);
 		});
 	}
-}
+};
 
 dojox.xml.parser.removeChildren = function(/*Element*/node){
 	//	summary:
@@ -168,7 +170,7 @@ dojox.xml.parser.removeChildren = function(/*Element*/node){
 		node.removeChild(node.firstChild);
 	}
 	return count; // int
-}
+};
 
 
 dojox.xml.parser.innerXML = function(/*Node*/node){
@@ -184,4 +186,8 @@ dojox.xml.parser.innerXML = function(/*Node*/node){
 		return (new XMLSerializer()).serializeToString(node);	//	String
 	}
 	return null;
-}
+};
+
+return dojox.xml.parser;
+
+});
diff --git a/dojox/xml/tests/mail.html b/dojox/xml/tests/mail.html
index a09fd9d..cc8d0ab 100644
--- a/dojox/xml/tests/mail.html
+++ b/dojox/xml/tests/mail.html
@@ -25,7 +25,6 @@
 
 		dojo.require("dijit.dijit");
 		dojo.require("dijit.Declaration");
-		dojo.require("dijit.form.Button");
 		dojo.require("dijit.Menu");
 		dojo.require("dijit.Tree");
 		dojo.require("dijit.Tooltip");
@@ -37,6 +36,7 @@
 		dojo.require("dijit._editor.plugins.LinkDialog");
 		dojo.require("dijit.ProgressBar");
 
+		dojo.require("dijit.form.ComboButton");
 		dojo.require("dijit.form.ComboBox");
 		dojo.require("dijit.form.CheckBox");
 		dojo.require("dijit.form.FilteringSelect");
diff --git a/dojox/xml/tests/module.js b/dojox/xml/tests/module.js
index b61b228..962416c 100644
--- a/dojox/xml/tests/module.js
+++ b/dojox/xml/tests/module.js
@@ -1,8 +1 @@
-dojo.provide("dojox.xml.tests.module");
-
-try{
-	dojo.require("dojox.xml.tests.parser");
-	//dojo.require("dojox.xml.tests.widgetParser");
-}catch(e){
-	doh.debug(e);
-}
+define(['./parser'], {});
diff --git a/dojox/xml/tests/parser.js b/dojox/xml/tests/parser.js
index 68f6916..70c3af1 100755
--- a/dojox/xml/tests/parser.js
+++ b/dojox/xml/tests/parser.js
@@ -1,15 +1,14 @@
-dojo.provide("dojox.xml.tests.parser");
-dojo.require("dojox.xml.parser");
+define(['doh', 'dojo/_base/html', '../parser'], function(doh, html, dxparser){
 
-tests.register("dojox.xml.tests.parser",
+doh.register("dojox.xml.tests.parser",
 	[
 		function testParse(t){
-			var document = dojox.xml.parser.parse();
+			var document = dxparser.parse();
 			t.assertTrue(document !== null);
 		},
 		function testParseFromText(t){
 			var simpleXml = "<parentNode><childNode><grandchildNode/></childNode><childNode/></parentNode>";
-			var document = dojox.xml.parser.parse(simpleXml, "text/xml");
+			var document = dxparser.parse(simpleXml, "text/xml");
 			
 			var parent = document.firstChild;
 			t.assertTrue(parent !== null);
@@ -32,7 +31,7 @@ tests.register("dojox.xml.tests.parser",
 		},
 		function testParseEmptyString(t){
 			var simpleXml = "";
-			var document = dojox.xml.parser.parse(simpleXml, "text/xml");
+			var document = dxparser.parse(simpleXml, "text/xml");
 			
 			t.assertTrue(typeof document != "undefined");
 
@@ -41,7 +40,7 @@ tests.register("dojox.xml.tests.parser",
 		},
 		function testParseEmpty(t){
 			var simpleXml;
-			var document = dojox.xml.parser.parse();
+			var document = dxparser.parse();
 			
 			t.assertTrue(typeof document != "undefined");
 
@@ -51,36 +50,36 @@ tests.register("dojox.xml.tests.parser",
 		function testReadTextContent(t){
 			var text = "This is a bunch of child text on the node";
 			var simpleXml = "<parentNode>" + text + "</parentNode>";
-			var document = dojox.xml.parser.parse(simpleXml, "text/xml");
+			var document = dxparser.parse(simpleXml, "text/xml");
             
 			var topNode = document.firstChild;
 			t.assertTrue(topNode !== null);
 			t.assertTrue(topNode.tagName === "parentNode");
-			t.assertTrue(text === dojox.xml.parser.textContent(topNode));
-			dojo.destroy(topNode);
+			t.assertTrue(text === dxparser.textContent(topNode));
+			html.destroy(topNode);
 			t.assertTrue(document.firstChild === null);
 		},
 		function testSetTextContent(t){
 			var text = "This is a bunch of child text on the node";
 			var text2 = "This is the new text";
 			var simpleXml = "<parentNode>" + text + "</parentNode>";
-			var document = dojox.xml.parser.parse(simpleXml, "text/xml");
+			var document = dxparser.parse(simpleXml, "text/xml");
             
 			var topNode = document.firstChild;
 			t.assertTrue(topNode !== null);
 			t.assertTrue(topNode.tagName === "parentNode");
-			t.assertTrue(text === dojox.xml.parser.textContent(topNode));
-			dojox.xml.parser.textContent(topNode, text2);
-			t.assertTrue(text2 === dojox.xml.parser.textContent(topNode));
-			dojo.destroy(topNode);
+			t.assertTrue(text === dxparser.textContent(topNode));
+			dxparser.textContent(topNode, text2);
+			t.assertTrue(text2 === dxparser.textContent(topNode));
+			html.destroy(topNode);
 			t.assertTrue(document.firstChild === null);
 
 		},
 		function testReplaceChildrenArray(t){
 			var simpleXml1 = "<parentNode><child1/><child2/><child3/></parentNode>";
 			var simpleXml2 = "<parentNode><child4/><child5/><child6/><child7/></parentNode>";
-			var doc1 = dojox.xml.parser.parse(simpleXml1, "text/xml");
-			var doc2 = dojox.xml.parser.parse(simpleXml2, "text/xml");
+			var doc1 = dxparser.parse(simpleXml1, "text/xml");
+			var doc2 = dxparser.parse(simpleXml2, "text/xml");
             
 			var topNode1 = doc1.firstChild;
 			var topNode2 = doc2.firstChild;
@@ -88,13 +87,13 @@ tests.register("dojox.xml.tests.parser",
 			t.assertTrue(topNode1.tagName === "parentNode");
 			t.assertTrue(topNode2 !== null);
 			t.assertTrue(topNode2.tagName === "parentNode");
-			dojox.xml.parser.removeChildren(topNode1);
+			dxparser.removeChildren(topNode1);
 			var newChildren=[];
 			for(var i=0;i<topNode2.childNodes.length;i++){
 				newChildren.push(topNode2.childNodes[i]);
 			}
-			dojox.xml.parser.removeChildren(topNode2);
-			dojox.xml.parser.replaceChildren(topNode1,newChildren);
+			dxparser.removeChildren(topNode2);
+			dxparser.replaceChildren(topNode1,newChildren);
 			t.assertEqual(4, topNode1.childNodes.length);
 			t.assertEqual("child4", topNode1.firstChild.tagName);
 			t.assertEqual("child7", topNode1.lastChild.tagName);
@@ -103,8 +102,8 @@ tests.register("dojox.xml.tests.parser",
 		function testReplaceChildrenSingle(t){
 			var simpleXml1 = "<parentNode><child1/><child2/><child3/></parentNode>";
 			var simpleXml2 = "<parentNode><child4/></parentNode>";
-			var doc1 = dojox.xml.parser.parse(simpleXml1, "text/xml");
-			var doc2 = dojox.xml.parser.parse(simpleXml2, "text/xml");
+			var doc1 = dxparser.parse(simpleXml1, "text/xml");
+			var doc2 = dxparser.parse(simpleXml2, "text/xml");
             
 			var topNode1 = doc1.firstChild;
 			var topNode2 = doc2.firstChild;
@@ -112,36 +111,38 @@ tests.register("dojox.xml.tests.parser",
 			t.assertTrue(topNode1.tagName === "parentNode");
 			t.assertTrue(topNode2 !== null);
 			t.assertTrue(topNode2.tagName === "parentNode");
-			dojox.xml.parser.removeChildren(topNode1);
+			dxparser.removeChildren(topNode1);
 			
 			var newChildren = topNode2.firstChild;
-			dojox.xml.parser.removeChildren(topNode2);
-			dojox.xml.parser.replaceChildren(topNode1,newChildren);
+			dxparser.removeChildren(topNode2);
+			dxparser.replaceChildren(topNode1,newChildren);
 			t.assertTrue(topNode1.childNodes.length === 1);
 			t.assertTrue(topNode1.firstChild.tagName === "child4");
 			t.assertTrue(topNode1.lastChild.tagName === "child4");
 		},
 		function testRemoveChildren(t){
 			var simpleXml1 = "<parentNode><child1/><child2/><child3/></parentNode>";
-			var doc1 = dojox.xml.parser.parse(simpleXml1, "text/xml");
+			var doc1 = dxparser.parse(simpleXml1, "text/xml");
             
 			var topNode1 = doc1.firstChild;
 			t.assertTrue(topNode1 !== null);
 			t.assertTrue(topNode1.tagName === "parentNode");
-			dojox.xml.parser.removeChildren(topNode1);
+			dxparser.removeChildren(topNode1);
 			t.assertTrue(topNode1.childNodes.length === 0);
 			t.assertTrue(topNode1.firstChild === null);
 		},
 		function testInnerXML(t){
 			var simpleXml1 = "<parentNode><child1/><child2/><child3/></parentNode>";
-			var doc1 = dojox.xml.parser.parse(simpleXml1, "text/xml");
+			var doc1 = dxparser.parse(simpleXml1, "text/xml");
             
 			var topNode1 = doc1.firstChild;
 			t.assertTrue(topNode1 !== null);
 			t.assertTrue(topNode1.tagName === "parentNode");
 
-			var innerXml = dojox.xml.parser.innerXML(topNode1);
+			var innerXml = dxparser.innerXML(topNode1);
 			t.assertTrue(simpleXml1 === innerXml);
 		}
 	]
 );
+
+});
diff --git a/dojox/xml/tests/widgetParser.html b/dojox/xml/tests/widgetParser.html
index 77e30c1..06b0c7a 100644
--- a/dojox/xml/tests/widgetParser.html
+++ b/dojox/xml/tests/widgetParser.html
@@ -12,13 +12,15 @@
 	<script type="text/javascript" src="../../../dojo/dojo.js"
 		djConfig="isDebug: true, parseOnLoad: true"></script>
 		
-	<script type="text/javascript" src="../widgetParser.js"></script>
-		
 	<script type="text/javascript">
-		dojo.require("dijit.form.Button");
-		dojo.require("dijit.layout.AccordionContainer");
-		dojo.require("dijit.form.TextBox");
-		dojo.require("dojox.xml.Script");
+		require([
+			'dijit/form/Button',
+			'dijit/layout/AccordionContainer',
+			'dijit/layout/AccordionPane',
+			'dijit/form/TextBox',
+			'dojox/xml/widgetParser',
+			'dojox/xml/Script'
+		]);
 	</script>
 
 		
@@ -28,7 +30,6 @@
 
 <h1 class="testTitle">AccordionContainer Tests</h1>
 
-
 <script type="text/xml" dojoType="dojox.xml.Script">
 <ui xmlns:dijit="dijit" xmlns:html="html">
 <html:h2>Accordion from markup:</html:h2>
diff --git a/dojox/xml/widgetParser.js b/dojox/xml/widgetParser.js
index fdc0649..8cdfc76 100644
--- a/dojox/xml/widgetParser.js
+++ b/dojox/xml/widgetParser.js
@@ -1,14 +1,20 @@
+define([
+	"dojo/_base/lang",	// dojo.getObject
+	"dojo/_base/window",	// dojo.doc
+	"dojo/_base/sniff",	// dojo.isIE
+	"dojo/query",
+	"dojo/parser",
+	"dojox/xml/parser"
+], function(dojo, window, has, query, parser, dxparser){
+
+var dXml = lang.getObject("dojox.xml", true);
+
 /**
 Take some sort of xml block
 * like <dojo.button caption="blah"/> and turn
 * it into a widget..
 */
 
-dojo.provide("dojox.xml.widgetParser");
-dojo.require("dojox.xml.parser");
-dojo.require("dojo.parser");
-
-
 	/**
 	 * We want to support something like:
 	 * <body>
@@ -42,7 +48,7 @@ dojo.require("dojo.parser");
 	 *
 	 */
 
-dojox.xml.widgetParser = new function(){
+xXml.widgetParser = new function(){
 	
 	var d = dojo;
 	
@@ -68,7 +74,7 @@ dojox.xml.widgetParser = new function(){
 		//small as possible
 		var ret = d.query('[dojoType]', htmlNode);
 		//remove the script tag and replace with new HTML block
-		dojo.query(">", htmlNode).place(script, "before")
+		query(">", htmlNode).place(script, "before")
 		script.parentNode.removeChild(script);
 		return ret;
 	};
@@ -81,7 +87,7 @@ dojox.xml.widgetParser = new function(){
 	this.toHTML = function (/*XmlNode*/ node){
 		var newNode;
 		var nodeName = node.nodeName;
-		var dd = dojo.doc;
+		var dd = window.doc;
 		var type = node.nodeType;
 		
 		
@@ -143,7 +149,7 @@ dojox.xml.widgetParser = new function(){
 				// is uses the browser HTML parsing exactly at is and won't
 				// cause any sort of issues. We could just special case style
 				// as well?
-				if(dojo.isIE && name == "style"){
+				if(has("ie") && name == "style"){
 					newNode.style.setAttribute("cssText", value);
 				}else{
 					newNode.setAttribute(name, value);
@@ -167,3 +173,6 @@ dojox.xml.widgetParser = new function(){
 	
 }();
 
+return dXml.widgetParser;
+
+});
diff --git a/dojox/xmpp/tests/test_xmppService.html b/dojox/xmpp/tests/test_xmppService.html
index 9ad288c..c8f6eef 100644
--- a/dojox/xmpp/tests/test_xmppService.html
+++ b/dojox/xmpp/tests/test_xmppService.html
@@ -49,7 +49,8 @@
 			src="../../../dojo/dojo.js" djConfig="isDebug:true,parseOnLoad:true">
 		</script>
 		<script type="text/javascript">
-			
+
+			dojo.require("dijit._base.popup");
 			dojo.require('dijit.layout.LayoutContainer');
 			dojo.require('dijit.layout.ContentPane');
 			dojo.require("dijit.layout.TabContainer");
diff --git a/dojox/xmpp/widget/ChatSession.js b/dojox/xmpp/widget/ChatSession.js
index cbfc0d3..4af74e9 100644
--- a/dojox/xmpp/widget/ChatSession.js
+++ b/dojox/xmpp/widget/ChatSession.js
@@ -1,4 +1,8 @@
 dojo.provide("dojox.xmpp.widget.ChatSession");
+
+dojo.require("dijit.layout.LayoutContainer");
+dojo.require("dijit._Templated");
+
 dojo.declare("dojox.xmpp.widget.ChatSession",
 	[dijit.layout.LayoutContainer, dijit._Templated],
 	{
diff --git a/util/build/argv.js b/util/build/argv.js
new file mode 100644
index 0000000..cd21ebe
--- /dev/null
+++ b/util/build/argv.js
@@ -0,0 +1,583 @@
+define([
+	"require",
+	"dojo",
+	"dojo/has",
+	"./fs",
+	"./fileUtils",
+	"./process",
+	"commandLineArgs",
+	"./stringify",
+	"./version",
+	"./messages",
+	"./v1xProfiles",
+	"dojo/text!./help.txt"
+], 	function(require, dojo, has, fs, fileUtils, process, argv, stringify, version, messages, v1xProfiles, help){
+	///
+	// AMD-ID build/argv
+	//
+	// This module parses the command line and returns the result as a hash of from switch-name to switch value
+	// plus the additional property profiles which is a a vector of profile objects build objects, ordered as
+	// provided on the command line.
+	//
+	// Design of relative paths:
+	//
+	//	 * All relative source paths and relative bc.releaseDir are relative to bc.basePath
+	//	 * All relative destination paths are relative to bc.releaseDir
+	//	 * Relative bd.basePath found in a build control script is relative to the directory that contains the script
+	//	 * Any relative path found on the command line is relative to the current working directory
+	//
+	// For each build control script that is compiled, if bc.basePath is undefined, it is set to the directory that
+	// contains the script. Notice that this feature can be disabled by setting e.g., "basePath==0" in any build control script.
+
+	eval(require.scopeify("./fileUtils"));
+	var
+		// used to build up the result
+		result = {
+			profiles:[]
+		},
+
+		cwd = process.cwd(),
+
+		// we need to know the dojo path and the path to /util/buildscripts to process v1.x profiles and profiles in the
+		// /util/buildscripts/profiles directory
+		dojoPath = computePath(require.toUrl("dojo/package.json").match(/(.+)\/package\.json$/)[1], cwd),
+		utilBuildscriptsPath = compactPath(catPath(dojoPath, "/../util/buildscripts")),
+
+		printVersion = 0,
+		printHelp = 0,
+		checkArgs = 0,
+
+		illegalArgumentValue = function(argumentName, position){
+			messages.log("inputIllegalCommandlineArg", ["switch", argumentName, "position", position]);
+		},
+
+		evalScriptArg=
+			function(arg){
+				if(arg=="true"){
+					return true;
+				}else if(arg=="false"){
+					return false;
+				}else if(arg=="null"){
+					return null;
+				}else if(isNaN(arg)){
+					return dojo.fromJson("{\"result\":\"" + arg + "\"}").result;
+				}else{
+					return Number(arg);
+				}
+			},
+
+		readProfile = function(
+			scriptType,
+			filename
+		){
+			///
+			// Load, evaluate and return the result of the contents of the file given by
+			// filename in a scope type given by scriptType as follows:
+			//
+			// When scriptType is "require", contents of filename should be either an application of require to a configuration object or
+			// a bare require object. The contents is evaluated as follows:
+			// `code
+			// (function(){
+			//	 var __result = 0, require = function(config){__result=config;};
+			//	 <contents>
+			//	 return __result || require;
+			// })();
+			//
+			// Notice if <contents> defines require as a bare object, it will overwrite the provided require, result will be 0, and the bare
+			// object will be returned; otherwise, if <contents> contains an application to a configuration object, result will be truthy
+			// and therefore be returned.
+			//
+			// When scriptType is "dojoConfig", contents of filename should include the variable "dojoConfig" which should hold a
+			// a dojo loader configuration:
+			// `code
+			// (function(){
+			//	 <contents>
+			//	 return dojoConfig;
+			// })();
+			//
+			// When scriptType is "profile", contents of filename should be Javascript code that either defines the variable "dependencies"
+			// or the variable "profile". The name dependencies is deprecated; if both names exist, then the value of dependencies is ignored.
+			// The value should be a Javascript object that contains profile properties necessary to effect the desired output. If filename does not
+			// contain a ".js" suffix, then it is assumed to be a profile in the /util/buildscripts/profile directory
+			// `code
+			// (function(selfPath, profile, dependencies){
+			//	 return profile || dependencies;
+			// })(<filename>, 0, 0);
+			//
+			// For script types "require" and "dojoConfig", if filename gives the filetype ".html" or ".htm", then the file is assumed to be
+			// an html file that contains a <script> element that contains Javascript source code as described above.
+			//
+			// If a profile is processed and it contains the property prefixes or the property layers with a layer further containing the property
+			// dependencies, then it is assumed to be a pre-version 1.7 build profile and the following additional processing is accomplished:
+			//
+			// If result contains the property basePath and/or build.basePath that is a relative path, then these are normalized
+			// with respect to the path given by filename.
+
+			// remember the the directory of the last build script processed; this is the default location of basePath
+			var path = getFilepath(filename);
+
+			if(!fileExists(filename)){
+				messages.log("inputFileDoesNotExist", [scriptType, filename]);
+				return 0;
+			}
+
+			try{
+				var src = fs.readFileSync(filename, "utf8");
+			}catch (e){
+				messages.log("inputFailedReadfile", [scriptType, filename, "error", e]);
+				return 0;
+			}
+
+			if(scriptType=="profileFile"){
+				messages.log("inputProfileFileDeprecated");
+				scriptType = "profile";
+			}
+
+			var fixupBasePath = function(profile){
+					// relative basePath is relative to the directory in which the profile resides
+					// all other relative paths are relative to basePath or releaseDir, and releaseDir, if relative, is relative to basePath
+					var fixupBasePath = function(path, referencePath){
+						if(path){
+							path = computePath(path, referencePath);
+						}else if(typeof path == "undefined"){
+							path = referencePath;
+						}
+						return path;
+					};
+					profile.basePath = fixupBasePath(profile.basePath, path);
+					if(profile.build && profile.build.basePath){
+						profile.build.basePath = fixupBasePath(profile.build.basePath, path);
+					}
+				},
+				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();
+					fixupBasePath(profile);
+				}else if(scriptType=="dojoConfig"){
+					f = new Function(src + "; return dojoConfig;");
+					profile = f();
+					fixupBasePath(profile);
+				}else if(scriptType=="profile"){
+					f = new Function("selfPath", "logger", "profile", "dependencies",
+									 src + "; return {profile:profile, dependencies:dependencies}");
+					profile = f(path, messages, 0, 0, 0);
+					if(profile.profile){
+						profile = profile.profile;
+						fixupBasePath(profile);
+					}else{
+						profile = v1xProfiles.processProfile(profile.dependencies, dojoPath, utilBuildscriptsPath, path);
+						// notice we do *not* fixup the basePath for legacy profiles since they have no concept of basePath
+					}
+				}
+				profile.selfFilename = filename;
+				messages.log("pacify", "processing " + scriptType + " resource " + filename);
+				return profile;
+			}catch(e){
+				messages.log("inputFailedToEvalProfile", [scriptType, filename, "error", e]);
+				return 0;
+			}
+		},
+
+		processHtmlDir = function(arg){
+			if(!fileUtils.dirExists(arg)){
+				messages.log("inputHTMLDirDoesNotExist", ["directory", arg]);
+				return 0;
+			}else{
+				var htmlFiles = [];
+				fs.readdirSync(arg).forEach(function(filename){
+					if(/\.html$/.test(filename)){
+						htmlFiles.push(arg + "/" + filename);
+					}
+				});
+				if(!htmlFiles.length){
+					messages.log("inputHTMLDirNoFiles", ["directory", arg]);
+					return 0;
+				}else{
+					return v1xProfiles.processHtmlFiles(htmlFiles, dojoPath, utilBuildscriptsPath);
+				}
+			}
+		},
+
+		processHtmlFiles = function(arg){
+			var htmlFiles = arg.split(",").filter(function(filename){
+				if(!fileUtils.fileExists(filename)){
+					messages.log("inputHTMLFileDoesNotExist", ["filename", filename]);
+					return 0;
+				}else{
+					return 1;
+				}
+			});
+			if(htmlFiles.length){
+				return v1xProfiles.processHtmlFiles(htmlFiles, dojoPath, utilBuildscriptsPath);
+			}else{
+				return 0;
+			}
+		},
+
+		readPackageJson = function(filename, missingMessageId){
+			if(!fileUtils.fileExists(filename)){
+				messages.log(missingMessageId, ["filename", filename]);
+			}else{
+				try{
+					var result = dojo.fromJson(fs.readFileSync(filename, "utf8"));
+					result.selfFilename = filename;
+					return result;
+				}catch(e){
+					messages.log("inputMalformedPackageJson", ["filename", filename]);
+				}
+			}
+			return 0;
+		},
+
+		processPackageJson = function(packageRoot){
+			// process all the packages given by package.json first since specific profiles are intended to override the defaults
+			// packageRoot gives a path to a location where a package.json rides
+			var packageJsonFilename = catPath(packageRoot, "package.json"),
+				packageJson= readPackageJson(packageJsonFilename, "inputMissingPackageJson");
+			if(packageJson){
+				// use package.json to define a package config
+				packageJson.selfFilename = packageJsonFilename;
+				result.profiles.push({
+					packages:[{
+						name:packageJson.progName || packageJson.name,
+						packageJson:packageJson
+					}]
+				});
+			}
+		},
+
+		readCopyrightOrBuildNotice = function(filename, hint){
+			if(!fileExists(filename)){
+				messages.log("inputFileDoesNotExist", [hint, filename]);
+			}
+			try{
+				var prop = hint=="copyrightFile" ? "copyright" : "buildNotice";
+				result[prop] = fs.readFileSync(filename, "utf8");
+			}catch (e){
+				messages.log("inputFailedReadfile", [hint, filename, "error", e]);
+			}
+		},
+
+		normalizeSwitch = {
+			"-p":"profile",
+			"--profile":"profile",
+			"--profileFile":"profileFile",
+			"p":"profile",
+			"profile":"profile",
+			"profileFile":"profileFile",
+
+			"--package":"package",
+			"package":"package",
+
+			"--require":"require",
+			"require":"require",
+
+			"--dojoConfig":"dojoConfig",
+			"dojoConfig":"dojoConfig",
+
+			"--htmlDir":"htmlDir",
+			"htmlDir":"htmlDir",
+
+			"--htmlFiles":"htmlFiles",
+			"htmlFiles":"htmlFiles",
+
+			"--copyrightFile":"copyrightFile",
+			"copyrightFile":"copyrightFile",
+
+			"--buildNoticeFile":"buildNoticeFile",
+			"buildNoticeFile":"buildNoticeFile"
+		};
+
+	//arg[0] is "load=build"; therefore, start with argv[1]
+	for (var arg, processVector = [], i = 1, end = argv.length; i<end;){
+		arg = argv[i++];
+		switch (arg){
+			case "-p":
+			case "--profile":
+				if(i<end){
+					processVector.push([normalizeSwitch[arg], argv[i++], cwd]);
+				}else{
+					illegalArgumentValue(arg, i);
+				}
+				break;
+
+			case "--profileFile":
+			case "--require":
+			case "--dojoConfig":
+			case "--htmlDir":
+			case "--htmlFiles":
+			case "--copyrightFile":
+			case "--buildNoticeFile":
+				if(i<end){
+					processVector.push([normalizeSwitch[arg], getAbsolutePath(argv[i++], cwd)]);
+				}else{
+					illegalArgumentValue(arg, i);
+				}
+				break;
+
+			case "--package":
+				if(i<end){
+					argv[i++].split(",").forEach(function(path){
+						processVector.push(["package", getAbsolutePath(path, cwd)]);
+					});
+				}else{
+					illegalArgumentValue(arg, i);
+				}
+				break;
+
+			case "--writeProfile":
+				if(i<end){
+					result.writeProfile = getAbsolutePath(argv[i++], cwd);
+				}else{
+					illegalArgumentValue(arg, i);
+				}
+				break;
+
+			case "--check":
+				// read, process, and send the profile to the console and then exit
+				result.check = true;
+				break;
+
+			case "--check-args":
+				// read and process the command line args, send the profile to the console and then exit
+				checkArgs = true;
+				break;
+
+			case "--check-discovery":
+				// echo discovery and exit
+				result.checkDiscovery = true;
+				result.release = true;
+				break;
+
+			case "--debug-check":
+				// read, process, and send the profile to the console, including gory details, and then exit
+				result.debugCheck = true;
+				break;
+
+			case "--clean":
+				// deprecated; warning given when the profile is processed
+				result.clean = true;
+				break;
+
+			case "-r":
+			case "--release":
+				// do a build
+				result.release = true;
+				break;
+
+			case "--help":
+				// print help message
+				printHelp = true;
+				break;
+
+			case "-v":
+				// print the version
+				printVersion = function(){
+					messages.log("pacify", version+"");
+				};
+				break;
+
+			case "--unit-test":
+				// special hook for testing
+				if(i<end){
+					result.unitTest = argv[i++];
+				}else{
+					illegalArgumentValue("unit-test", i);
+				}
+				break;
+
+			case "--unit-test-param":
+				// special hook for testing
+				if(i<end){
+					result.unitTestParam = result.unitTestParam || [];
+					result.unitTestParam.push(evalScriptArg(argv[i++]));
+				}else{
+					illegalArgumentValue("unit-test", i);
+				}
+				break;
+
+			default:
+				// possible formats
+				//
+				//   -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++]);
+				}else{
+					// the form switch=value does *not* provide an individual value arg (it's all one string)
+					var parts = arg.split("=");
+					if(parts.length==2){
+						switch(parts[0]){
+							case "p":
+							case "profile":
+								processVector.push([normalizeSwitch[parts[0]], parts[1]]);
+								break;
+
+							case "package":
+								parts[1].split(",").forEach(function(path){
+									processVector.push(["package", getAbsolutePath(path, cwd)]);
+								});
+								break;
+
+							case "profileFile":
+							case "require":
+							case "dojoConfig":
+							case "htmlDir":
+							case "htmlFiles":
+							case "copyrightFile":
+							case "buildNoticeFile":
+								processVector.push([normalizeSwitch[parts[0]], getAbsolutePath(parts[1], cwd)]);
+								break;
+							default:
+								result[parts[0]] = evalScriptArg(parts[1]);
+						}
+					}else{
+						illegalArgumentValue(arg, i);
+					}
+				}
+		}
+	}
+
+	// if processing html files and a nonexisting profile file is given, then assume the user intends to write
+	// the computed profile to that file. This feature is deprecated; use the switch --writeProfile
+	var processingHtmlFiles = processVector.some(function(item){ return item[0]=="htmlFiles" || item[0]=="htmlDir"; });
+	if(processingHtmlFiles){
+		for(i= 0; i<processVector.length; i++){
+			if(processVector[i][0]=="profileFile" && !fileExists(processVector[i][1])){
+				messages.log("outputToProfileFileDeprecated");
+				result.writeProfile = processVector[i][1];
+				processVector.splice(i, 1);
+				break;
+			}
+		}
+	}
+	processVector.forEach(function(item){
+		// item[0] is the switch
+		// item[1] is an absolute filename
+		var profile;
+		switch(item[0]){
+			case "profile":
+				var type = getFiletype(item[1], true), filename;
+				if(type==""){
+					// prefer a user profile, then the stock profiles
+					filename = getAbsolutePath(item[1] + ".profile.js", cwd);
+					if(!fileExists(filename) && !/\//.test(item[1])){
+						// the name given include no path; maybe it's a stock profile
+						filename = catPath(utilBuildscriptsPath, "profiles/" + item[1] + ".profile.js");
+					}
+					if(!fileExists(filename)){
+						messages.log("inputFileDoesNotExist", ["filename", filename]);
+						break;
+					}
+				}else if(/^(html|htm)$/.test(type)){
+					messages.log("inputProcessingHtmlFileNotImplemented", ["profile", filename]);
+					return;
+				}else{
+					filename = getAbsolutePath(item[1], cwd);
+				}
+				profile = readProfile(item[0], filename);
+				break;
+			case "htmlDir":
+				profile = processHtmlDir(item[1]);
+				break;
+			case "htmlFiles":
+				profile = processHtmlFiles(item[1]);
+				break;
+			case "package":
+				profile = processPackageJson(item[1]);
+				break;
+			case "copyrightFile":
+			case "buildNoticeFile":
+				profile = readCopyrightOrBuildNotice(item[1], item[0]);
+				break;
+			default:
+				profile = readProfile(item[0], item[1]);
+		}
+		if(profile){
+			result.profiles.push(profile);
+		}
+	});
+
+
+
+	if(((printHelp || printVersion) && argv.length==2) || (printHelp && printVersion && argv.length==3)){
+		//just asked for either help or version or both; don't do more work or reporting
+		if(printHelp){
+			messages.log("pacify", help);
+			messages.log("pacify", version+"");
+			has("host-rhino") && messages.log("pacify", "running under rhino");
+			has("host-node") && messages.log("pacify", "running under node");
+		}
+		printVersion && printVersion();
+		process.exit(0);
+		return 0;
+	}
+
+	printVersion && printVersion();
+
+	if (checkArgs){
+		messages.log("pacify", stringify(result));
+		process.exit(0);
+		return 0;
+	}
+
+	if(messages.getErrorCount()){
+		messages.log("pacify", "errors on command line; terminating application.");
+		process.exit(-1);
+		return 0;
+	}
+
+	if(!result.profiles.length){
+		messages.log("pacify", "no profile provided; use the option --help for help");
+		process.exit(-1);
+		return 0;
+	}
+
+	if(result.unitTest=="argv"){
+		var testId = result.unitTestParam[0],
+			writingExpected = testId<0;
+		if(writingExpected){
+			testId = -testId;
+		}
+		result.unitTestParam = testId;
+		var expectedFilename = compactPath(utilBuildscriptsPath + "/../build/tests/argvTestsExpected.js"),
+			expected = dojo.fromJson(fs.readFileSync(expectedFilename, "utf8")),
+			pathNormalize = utilBuildscriptsPath.match(/(.*)\/util\/buildscripts/)[1],
+			testResult = stringify(result).replace(RegExp(pathNormalize, "g"), "~"),
+			passed = 1;
+
+		if(writingExpected){
+			// write out the expected result;
+			console.log("result:");
+			debug(testResult);
+			expected[result.unitTestParam] = testResult;
+			fs.writeFileSync(expectedFilename, dojo.toJson(expected), "utf8");
+		}else{
+			passed = testResult==expected[result.unitTestParam];
+			console.log(result.unitTestParam + ":" + (passed ? "PASSED" : "FAILED"));
+			if(!passed){
+				console.log("Expected:");
+				console.log(expected[result.unitTestParam]);
+				console.log("But Got:");
+				console.log(testResult);
+			}
+		}
+		process.exit(passed ? 0 : -1);
+	}
+
+	return {
+		args:result,
+		readPackageJson:readPackageJson,
+		readProfile:readProfile
+	};
+});
+
+
diff --git a/util/build/buildControl.js b/util/build/buildControl.js
new file mode 100644
index 0000000..45c5e63
--- /dev/null
+++ b/util/build/buildControl.js
@@ -0,0 +1,678 @@
+define([
+	"require",
+	"dojo/_base/lang",
+	"./argv",
+	"./fs",
+	"./fileUtils",
+	"./buildControlDefault",
+	"./v1xProfiles",
+	"./stringify",
+	"./process",
+	"./messages",
+	"dojo/text!./help.txt"
+], 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.
+	//
+	// This modules is a bit tedious. Is methodically goes through each option set, cleaning and conditioning user input making it
+	// easy to use for the remainder of the program. Readers are advised to tackle it top-to-bottom. There is no magic...just
+	// a whole bunch of imperative programming.
+	//
+
+	if(!isNaN(argv)){
+		// if argv is a number, then it's an exit code
+		bc.exitCode = argv;
+		return bc;
+	}
+
+	eval(require.scopeify("./fs, ./fileUtils, ./v1xProfiles"));
+	var
+		isString= function(it) {
+			return typeof it === "string";
+		},
+
+		isNonemptyString= function(it){
+			return isString(it) && it.length;
+		},
+
+		isDefined= function(it){
+			return typeof it !="undefined";
+		},
+
+		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 (!isAbsolutePath(result[0]) || !isAbsolutePath(result[1])) {
+				bc.log("inputInvalidPath", ["path", item, "hint", hint]);
+			}
+			return result;
+		},
+
+		slashTerminate= function(path){
+			return path + /\/$/.test(path) ? "" : "/";
+		},
+
+		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];
+			return dest;
+		},
+
+		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) {
+			// 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];
+				}
+			}
+
+			// the one-level-deep mixers
+			["paths","plugins","transforms","staticHasFeatures"].forEach(function(p) {
+				bc[p]= mix(bc[p], src[p]);
+			});
+
+			// messages require special handling
+			if(src.messageCategories){
+				for(p in src.messageCategories){
+					bc.addCategory(p, src.messageCategories[p]);
+				}
+			}
+			(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};
+					}
+					packageInfo.location= catPath(base, packageInfo.name);
+					mixPackage(packageInfo);
+				});
+			};
+			(src.packages || []).forEach(function(packageInfo) {
+					if (isString(packageInfo)) {
+						packageInfo= {name:packageInfo};
+					}
+					mixPackage(packageInfo);
+			});
+
+			// defaultConfig requires special handling
+			for(p in src.defaultConfig){
+				if(p=="hasCache"){
+					mix(bc.defaultConfig.hasCache, src.defaultConfig.hasCache);
+				}else{
+					bc.defaultConfig[p]= src.defaultConfig[p];
+				}
+			}
+		};
+
+	argv.args.profiles.forEach(function(item) {
+		var temp= mix({}, item),
+			build= item.build;
+		delete temp.build;
+		mixProfileObject(temp);
+		build && mixProfileObject(build);
+	});
+
+	// lastly, explicit command line switches override any evaluated profile objects
+	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());
+	var releaseDir = catPath(bc.releaseDir || "../release", bc.releaseName || "");
+	bc.destBasePath= computePath(releaseDir, bc.basePath);
+
+	// compute global copyright, if any
+	bc.copyright = isNonemptyString(bc.copyright) ? (maybeRead(computePath(bc.copyright, bc.basePath)) || bc.copyright) : "";
+	bc.copyrightLayers = !!bc.copyrightLayers;
+	bc.copyrightNonlayers = !!bc.copyrightNonlayers;
+
+	// compute files, dirs, and trees
+	(function () {
+		for (var property in {files:1, dirs:1, trees:1}) {
+			if(bc[property] instanceof Array){
+				bc[property]= bc[property].map(function(item) {
+					return cleanupFilenamePair(item, bc.basePath, bc.destBasePath, property);
+				});
+			}
+		}
+	})();
+
+	// cleanup the replacements (if any)
+	(function() {
+		var cleanSet= {}, src, dest;
+		for (src in bc.replacements) {
+			cleanSet[computePath(src, bc.basePath)]= bc.replacements[src];
+		}
+		bc.replacements= cleanSet;
+	})();
+
+	// explicit mini and/or copyTests wins; explicit copyTests ignores explicit mini
+	if(!("mini" in bc)){
+		bc.mini = true;
+	}
+	if(!("copyTests" in bc)){
+		bc.copyTests = !bc.mini;
+	}
+	if(isString(bc.copyTests)){
+		bc.copyTests = bc.copyTests.toLowerCase();
+	}
+	if(bc.copyTests!="build"){
+		// convert to pure boolean
+		bc.copyTests = !!bc.copyTests;
+	}
+
+	if(isString(bc.localeList)){
+		bc.localeList = bc.localeList.split(",");
+	}
+	bc.localeList = bc.localeList ? bc.localeList.map(lang.trim) : [];
+
+	// 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 processPackage(pack){
+			var packName = pack.name,
+				basePath = pack.basePath || bc.basePath;
+			if(!pack.packageJson){
+				pack.packageJson = argv.readPackageJson(catPath(computePath(pack.location || ("./" + packName), basePath), "package.json"), "missingPackageJson");
+			}
+			var packageJson = pack.packageJson;
+			if(packageJson){
+				if(packageJson.version){
+					bc.log("packageVersion", ["package", packName, "version", packageJson.version]);
+
+					// new for 1.7, if version is not provided, the version of the dojo package is used
+					if(typeof bc.version=="undefined" && packName=="dojo"){
+						bc.version = packageJson.version;
+					}
+				}
+				if(packageJson.main && !pack.main){
+					pack.main= packageJson.main;
+				}
+				if(packageJson.directories && packageJson.directories.lib && !pack.location){
+					pack.location = catPath(getFilepath(packageJson.selfFilename), packageJson.directories.lib);
+				}
+				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];
+						}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]);
+						}
+					}
+				}
+			}
+
+			// 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";
+			if(pack.main.indexOf("./")==0){
+				pack.main = pack.main.substring(2);
+			}
+			if(pack.destMain && pack.destMain.indexOf("./")==0){
+				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.copyright = isNonemptyString(pack.copyright) ?
+				(maybeRead(computePath(pack.copyright, pack.location)) || maybeRead(computePath(pack.copyright, bc.basePath)) || pack.copyright) :
+				(pack.copyright ? bc.copyright : "");
+			pack.copyrightLayers = isDefined(pack.copyrightLayers) ? !!pack.copyrightLayers : bc.copyrightLayers;
+			pack.copyrightNonlayers = isDefined(pack.copyrightNonlayers) ? !!pack.copyrightNonlayers : bc.copyrightNonlayers;
+
+			// dest says where to output the compiled code stack
+			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
+			};
+			require.computeMapProg(pack.destPackageMap, (destPack.mapProg= []));
+			delete pack.destName;
+			delete pack.destMain;
+			delete pack.destLocation;
+			delete pack.destPackageMap;
+
+
+			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, /(\/\.)|(~$)/]];
+			} // 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) {
+					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];
+			pack.name = pack.name || packageName;
+			processPackage(pack);
+		}
+
+		// now that we know the dojo path, we can automatically add DOH, if required
+		if(bc.copyTests && !bc.packages.doh){
+			bc.packages.doh = {
+				name:"doh",
+				location:compactPath(bc.packages.dojo.location + "/../util/doh"),
+				destLocation:"util/doh"
+			};
+			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= []));
+
+		// add some methods to bc to help with resolving AMD module info
+		bc.srcModules= {};
+		bc.destModules= {};
+
+		var trimLastChars= function(text, n){
+			return text.substring(0, text.length-n);
+		};
+
+		bc.getSrcModuleInfo= function(mid, referenceModule, ignoreFileType) {
+			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);
+				return result;
+			}else{
+				return require.getModuleInfo(mid, referenceModule, bc.packages, bc.srcModules, bc.basePath + "/", bc.packageMapProg, bc.pathsMapProg, 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
+			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);
+				return result;
+			}else{
+				return require.getModuleInfo(mid, referenceModule, bc.destPackages, bc.destModules, bc.destBasePath + "/", bc.destPackageMapProg, bc.destPathsMapProg, true);
+			}
+		};
+	})();
+
+
+	if(bc.selectorEngine && bc.defaultConfig && bc.defaultConfig.hasCache){
+		bc.defaultConfig.hasCache["config-selectorEngine"] = bc.selectorEngine;
+	}
+
+	(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 || [];
+			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 ||"");
+
+			var tlm = mid.split("/")[0],
+				pack = bc.packages[tlm],
+				packLocation = pack && pack.location,
+				packCopyright = pack && pack.copyright,
+				packCopyrightLayers = pack && pack.copyrightLayers;
+			if(isNonemptyString(layer.copyright)){
+				// if relative, first try basePath, then try package location, otherwise, just use what's given
+				layer.copyright = (packLocation && maybeRead(computePath(layer.copyright, packLocation))) || maybeRead(computePath(layer.copyright, bc.basePath)) || layer.copyright;
+			}else if(isDefined(layer.copyright)){
+				// some kind of truthy other than a string
+				layer.copyright = layer.copyright ? (packCopyright || bc.copyright) : "";
+			}else{
+				layer.copyright = pack ? (packCopyrightLayers && (packCopyright || bc.copyright)) : (bc.copyrightLayers && bc.copyright);
+			}
+			if(!layer.copyright){
+				layer.copyright = "";
+			}
+			fixedLayers[mid]= layer;
+		}
+		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
+		if(bc.packages.dojo){
+			if(!bc.layers["dojo/dojo"]){
+				bc.layers["dojo/dojo"] = {name:"dojo/dojo", copyright:bc.defaultCopyright + bc.defaultBuildNotice, include:["dojo/main"], exclude:[]};
+			}
+			for(var p in bc.layers){
+				layer = bc.layers[p];
+				if(p=="dojo/dojo"){
+					if(!layer.customBase){
+						// the purpose of the layer is to simply add some additional modules to a standard dojo boot
+						if(layer.include.indexOf("dojo/main")==-1){
+							layer.include.push("dojo/main");
+						}
+					}else{
+						// this is a custom base dojo.js; it's up the the user to say exactly what they want
+					}
+				}else{
+					if((layer.boot || !layer.customBase) && layer.exclude.indexOf("dojo/dojo")==-1){
+						// the layer has dojo/dojo if it is booting, or assumes dojo/dojo if its not explicitly saying customBase
+						layer.exclude.push("dojo/dojo");
+					}
+					// by definition...
+					layer.customBase = layer.boot;
+				}
+			}
+		}
+
+	})();
+
+
+	// 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);
+	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];
+			switch(action){
+				case "check":
+					bc.check= true;
+					break;
+				case "clean":
+					bc.clean= true;
+					break;
+				case "release":
+					bc.release= true;
+					break;
+				default:
+					bc.log("inputUnknownAction", ["action", action]);
+			}
+		});
+	}
+
+	if(bc.clean){
+		bc.log("cleanRemoved");
+	}
+
+	// understand stripConsole from dojo 1.3 and before
+	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") {
+		bc.log("inputDeprecatedStripConsole", ["deprecated", "normal,error", "use", "all"]);
+		stripConsole = "all";
+	} else if (!/normal|warn|all|none/.test(stripConsole)){
+		bc.log("inputUnknownStripConsole", ["value", stripConsole]);
+	}
+	bc.stripConsole= stripConsole;
+
+	function fixupOptimize(value){
+		if(value){
+			value= value + "";
+			value= value.toLowerCase();
+			if(!/^(comments|shrinksafe(\.keeplines)?|closure(\.keeplines)?)$/.test(value)){
+				bc.log("inputUnknownOptimize", ["value", value]);
+				value = 0;
+			}else{
+				if(/shrinksafe/.test(value) && stripConsole){
+					value+= "." + stripConsole;
+				}
+			}
+		}
+		return value;
+	}
+	bc.optimize = fixupOptimize(bc.optimize);
+	bc.layerOptimize = fixupOptimize(bc.layerOptimize);
+
+	(function(){
+		var fixedScopeMap = {dojo:"dojo", dijit:"dijit", dojox:"dojox"};
+		(bc.scopeMap || []).forEach(function(pair){
+			fixedScopeMap[pair[0]] = pair[1];
+		});
+		bc.scopeMap = fixedScopeMap;
+
+		bc.scopeNames = [];
+		for(var p in fixedScopeMap){
+			bc.scopeNames.push(p);
+		}
+	})();
+
+	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]);
+		}
+	}
+	deprecated.forEach(function(p){
+		delete bc[p];
+	});
+
+	// dump bc (if requested) before changing gate names to gate ids below
+	if(bc.check){
+		(function() {
+			var toDump = {
+				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,
+				internStringsSkipList:1,
+				layers:1,
+				localeList:1,
+				maxOptimizationProcesses:1,
+				mini:1,
+				"package":1,
+				packageMap:1,
+				packageMapProg:1,
+				packages:1,
+				paths:1,
+				pathsMapProg:1,
+				plugins:1,
+				replacements:1,
+				startTimestamp:1,
+				staticHasFeatures:1,
+				stripConsole:1,
+				trees:1
+			};
+			for(var p in toDump){
+				toDump[p] = bc[p];
+			}
+			bc.log("pacify", stringify(toDump));
+		})();
+		bc.release = 0;
+	}
+
+	if(bc.writeProfile){
+
+	}
+
+	if(bc.debugCheck){
+		(function(){
+			var toDump = {};
+			for(var p in bc){
+				if(bc[p]!==messages[p] && typeof bc[p]!="function"){
+					toDump[p] = bc[p];
+				}
+			}
+			console.log("profile:");
+			console.log(stringify(toDump));
+			toDump = {};
+			for(p in require){
+				if(p!="modules" && p!="module" && p!="rawConfig" && typeof require[p]!="function"){
+					toDump[p] = require[p];
+				}
+			}
+			console.log("require config:");
+			console.log(stringify(toDump));
+		})();
+		bc.release = 0;
+	}
+
+	// clean up the gates and transforms
+	(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;
+		}
+		var
+			transforms= bc.transforms,
+			gateId;
+		for (var transformId in transforms) {
+			// each item is a [AMD-MID, gateName] pair
+			gateId= gates[transforms[transformId][1]];
+			if (typeof gateId == "undefined") {
+				bc.log("inputUnknownGate", ["transform", transformId, "gate", transforms[transformId][1]]);
+			} else {
+				transforms[transformId][1]= gateId;
+			}
+		}
+	})();
+
+	// clean up the transformJobs
+	(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) {
+			// item is a [predicate, vector of transformId] pairs
+			var error= false;
+			var tlist= item[1].map(function(id) {
+				// item is a transformId
+				if (transforms[id]) {
+					// return a [trandformId, gateId] pair
+					return [id, transforms[id][1]];
+				} 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;
+						i && i--;
+					} else {
+						i++;
+					}
+				}
+				// now replace the vector of transformIds with the sorted list
+				item[1]= tlist;
+			}
+		});
+	})();
+
+	if (argv.args.unitTest=="dumpbc") {
+		console.log(stringify(bc) + "\n");
+	}
+
+	if(bc.quiet){
+		(function(){
+			var delSet = {};
+			for(var p in bc.pacifySet){
+				if(bc.messageMap[p][1]>199){
+					delSet[p] = 1;
+				}
+			}
+			for(p in delSet){
+				delete bc.pacifySet[p];
+			}
+		})();
+	}
+
+	if(bc.unitTestComputedProfile){
+		bc.unitTestComputedProfile();
+		// stop the build
+		bc.release = 0;
+	}
+
+	if(!bc.unitTestComputedProfile && !bc.check && !bc.debugCheck && !bc.clean && !bc.release){
+		bc.log("pacify", "Nothing to do; you must explicitly instruct the application to do something; use the option --help for help.");
+	}
+
+	return bc;
+});
diff --git a/util/build/buildControlBase.js b/util/build/buildControlBase.js
new file mode 100644
index 0000000..5053739
--- /dev/null
+++ b/util/build/buildControlBase.js
@@ -0,0 +1,51 @@
+define([
+	"dojo",
+	"./messages",
+	"dojo/text!./copyright.txt",
+	"dojo/text!./buildNotice.txt"
+], function(dojo, messages, defaultCopyright, defaultBuildNotice) {
+	var bc= {
+		exitCode:0,
+
+
+		// use this variable for all newlines inserted by build transforms
+		newline:"\n",
+
+		// user profiles may replace this with a function from string to string that filters newlines
+		// 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");
+		// }
+		//
+		newlineFilter:function(s, resource, hint){return s;},
+
+
+		// useful for dojo pragma including/excluding
+		built:true,
+
+		startTimestamp:new Date(),
+
+		paths:{},
+		destPathTransforms:[],
+		packageMap:{},
+
+		// resource sets
+		resources:{},
+		resourcesByDest:{},
+		amdResources:{},
+
+		closureCompilerPath:"../closureCompiler/compiler.jar",
+		maxOptimizationProcesses:5,
+		buildReportDir:".",
+		buildReportFilename:"build-report.txt",
+
+		defaultCopyright:defaultCopyright,
+		defaultBuildNotice:defaultBuildNotice
+	};
+	for(var p in messages){
+		bc[p] = messages[p];
+	};
+	return bc;
+});
diff --git a/util/build/buildControlDefault.js b/util/build/buildControlDefault.js
new file mode 100644
index 0000000..83fad71
--- /dev/null
+++ b/util/build/buildControlDefault.js
@@ -0,0 +1,251 @@
+define(["./buildControlBase"], function(bc) {
+	var defaultBc= {
+		// v1.6- default values
+		internStrings:true,
+		internSkipList:[],
+		optimize:"",
+		layerOptimize:"shrinksafe",
+		cssOptimize:"",
+		cssImportIgnore:"",
+		stripConsole:"normal",
+		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(","),
+
+
+		// this is a dojo pragma
+		replaceLoaderConfig:1,
+
+		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,
+				"config-tlmSiblingOfDojo":1,
+
+				// default
+				"config-selectorEngine":"acme"
+			},
+			async:0
+		},
+
+		files:[],
+		dirs:[],
+		trees:[],
+		replacements:{},
+
+		staticHasFeatures:{
+			// consider turning these hard on for standard 1.x build
+			//'config-publishRequireResult':1,
+			//'config-tlmSiblingOfDojo':1,
+
+			'extend-dojo':1,
+			'dojo-amd-factory-scan':0,
+			'dojo-built':1,
+			'dojo-combo-api':0,
+			'dojo-log-api':1,
+			'dojo-test-sniff':0,// must be turned on for several tests to work
+			'dojo-config-addOnLoad':1,
+			'dojo-config-api':1,
+			'dojo-config-require':1,
+			'dojo-dom-ready-api':1,
+			'dojo-guarantee-console':1,
+			'dojo-has-api':1,
+			'dojo-inject-api':1,
+			'dojo-loader':1,
+			'dojo-modulePaths':1,
+			'dojo-moduleUrl':1,
+			'dojo-publish-privates':0,
+			'dojo-requirejs-api':0,
+			'dojo-sniff':1,
+			'dojo-sync-loader':1,
+			'dojo-timeout-api':1,
+			'dojo-trace-api':0,
+			'dojo-undef-api':0,
+			'dojo-v1x-i18n-Api':1,
+			'dojo-xhr-factory':1,
+			'dom':1,
+			'host-browser':1,
+			'host-node':0,
+			'host-rhino':0
+		},
+
+		buildFlags:{
+			stripConsole:"error",
+			optimizeHas:1
+		},
+
+		discoveryProcs:["build/discover"],
+
+		plugins:{
+			"dojo/text":"build/plugins/text",
+			"dojo/i18n":"build/plugins/i18n",
+			"dojo/has":"build/plugins/has",
+			"dojo/domReady":"build/plugins/domReady",
+			"dojo/loadInit":"build/plugins/loadInit",
+			"dojo/require":"build/plugins/require",
+			"dojo/selector/_loader":"build/plugins/querySelector"
+		},
+
+		gates:[
+			// [synchronized?, gate-name, gate-message]
+			[0, "read", "reading resources"],
+			[0, "text", "processing raw resource content"],
+			[0, "tokenize", "tokenizing resource"],
+			[0, "tokens", "processing resource tokens"],
+			[0, "parse", "parsing resource"],
+			[1, "ast", "processing resource AST"],
+			[1, "optimize", "executing global optimizations"],
+			[1, "write", "writing resources"],
+			[1, "cleanup", "cleaning up"],
+			[1, "report", "reporting"]
+		],
+
+		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"]
+		},
+
+		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);
+				},
+				[]
+			],[
+				// if the tag says just copy, then just copy
+				function(resource) {
+					return resource.tag.copyOnly;
+				},
+				["copy"]
+			],[
+				// the synthetic report module
+				function(resource) {
+					return resource.tag.report;
+				},
+				["dojoReport", "insertSymbols", "report"]
+			],[
+				// dojo.js, the loader
+				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;
+						return true;
+					}
+					return false;
+				},
+				["read", "dojoPragmas", "hasFindAll", "hasFixup", "writeDojo", "writeOptimized"]
+			],[
+				// package has module
+				function(resource) {
+					if (/^\w+\/has$/.test(resource.mid)) {
+						bc.amdResources[resource.mid]= resource;
+						return true;
+					}
+					return false;
+				},
+				["read", "dojoPragmas", "hasFindAll", "hasFixup", "depsScan", "writeAmd", "writeOptimized", "hasReport", "depsDump"]
+			],[
+				// nls resources
+				function(resource) {
+					if (/\/nls\//.test(resource.mid) ||	/\/nls\/.+\.js$/.test(resource.src)) {
+						resource.tag.nls= 1;
+						bc.amdResources[resource.mid]= resource;
+						return true;
+					}
+					return false;
+				},
+				["read", "dojoPragmas", "hasFindAll", "hasFixup", "depsScan", "writeAmd"]
+			],[
+				// synthetic AMD modules (used to create layers on-the-fly
+				function(resource) {
+					if (resource.tag.synthetic && resource.tag.amd){
+						bc.amdResources[resource.mid]= resource;
+						return true;
+					}
+					return false;
+				},
+				// just like regular AMD modules, but without a bunch of unneeded transforms
+				["depsScan", "writeAmd", "writeOptimized"]
+			],[
+				// 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;
+						return true;
+					}
+					return false;
+				},
+				// just like regular AMD modules (the next transform job), but without a bunch of unneeded transforms
+				["writeAmd", "writeOptimized"]
+			],[
+				// AMD module:
+				// 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;
+						return true;
+					}
+					return false;
+				},
+				["read", "dojoPragmas", "hasFindAll", "insertSymbols", "hasFixup", "depsScan", "writeAmd", "writeOptimized"]
+			],[
+				// 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) {
+					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) {
+					return /\.(html|htm)$/.test(resource.src);
+				},
+				["read", "dojoPragmas", "write"]
+			],[
+				// css that are designated to compact
+				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) {
+					return !resource.tag.test;
+				},
+				["copy"]
+			]
+		]
+	};
+	for (var p in defaultBc) {
+		bc[p]= defaultBc[p];
+	}
+	return bc;
+});
diff --git a/util/build/buildNotice.txt b/util/build/buildNotice.txt
new file mode 100644
index 0000000..65d78b0
--- /dev/null
+++ b/util/build/buildNotice.txt
@@ -0,0 +1,7 @@
+/*
+	This is an optimized version of Dojo, built for deployment and not for
+	development. To get sources and documentation, please visit:
+
+		http://dojotoolkit.org
+*/
+
diff --git a/util/build/copyright.txt b/util/build/copyright.txt
new file mode 100644
index 0000000..28781c0
--- /dev/null
+++ b/util/build/copyright.txt
@@ -0,0 +1,6 @@
+/*
+	Copyright (c) 2004-2011, 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/build/discover.js b/util/build/discover.js
new file mode 100644
index 0000000..741e8b2
--- /dev/null
+++ b/util/build/discover.js
@@ -0,0 +1,296 @@
+define(["./buildControl", "./fileUtils", "./fs", "./stringify", "dojo/has", "./process"], function(bc, fileUtils, fs, stringify, has, process){
+	// find all files as given by files, dirs, trees, and packages
+	var
+		dirsProcessed =
+			// a set of the directory names that have been inspected
+			{},
+
+		treesDirsFiles = ["trees", "dirs", "files"],
+
+		srcDirs = {},
+
+		destDirs = {},
+
+		getFilepath = fileUtils.getFilepath,
+		catPath = fileUtils.catPath,
+		compactPath = fileUtils.compactPath,
+
+		start = function(resource, tagResource){
+			if(!resource.tag){
+				resource.tag = {};
+			}
+			if(tagResource){
+				tagResource(resource);
+			}
+			bc.start(resource);
+			srcDirs[getFilepath(resource.src)] = 1;
+			destDirs[getFilepath(resource.dest)] = 1;
+		},
+
+		getResourceTagFunction = function(resourceTags){
+			//resource tags is a map from tag to a function or a regular expression
+			var getFilterFunction = function(item){
+					return typeof item=="function" ?
+						item :
+						function(filename){
+							return item.test(filename);
+						};
+				},
+				tag = {},
+				gotOne  = false;
+			for(var p in resourceTags){
+				tag[p] = getFilterFunction(resourceTags[p]);
+				gotOne  = true;
+			}
+			if(!gotOne){
+				return 0;
+			}
+			return function(resource){
+				for(var p in tag){
+					if(tag[p](resource.src, resource.mid, resource)){
+						resource.tag[p] = 1;
+					}
+				}
+			};
+		},
+
+		neverExclude = function(){
+			return 0;
+		},
+
+		getExcludes = function(excludes){
+			// excludes is falsy, a function, or a regulare expression
+			if(!excludes){
+				return neverExclude;
+			}else if(typeof excludes=="function"){
+				return excludes;
+			}else{
+				return function(filename){
+					return excludes.test(filename);
+				};
+			}
+		},
+
+		readSingleDir = function(srcPath, destPath, excludes, advise, traverse){
+			if(dirsProcessed[srcPath]){
+				return;
+			}
+			dirsProcessed[srcPath] = 1;
+			if(!fileUtils.dirExists(srcPath)){
+				bc.log("missingDirDuringDiscovery", ["directory", srcPath]);
+				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);
+					if(stats.isDirectory()){
+						subdirs.push(fullFilename);
+					}else{
+						advise(fullFilename, destPath + "/" + filename);
+					}
+				}
+			});
+			if(traverse && subdirs.length){
+				subdirs.forEach(function(path){
+					readSingleDir(path, destPath + path.substring(srcPathLength), excludes, advise, 1);
+				});
+			}
+		},
+
+		readFile = function(item, advise){
+			advise(item[0], item[1]);
+		},
+
+		readDir = function(item, advise){
+			readSingleDir(item[0], item[1], getExcludes(item[2]), advise, 0, 0);
+		},
+
+		readTree = function(item, advise){
+			readSingleDir(item[0], item[1], getExcludes(item[2]), advise, 1);
+		},
+
+		discover = {
+			files:readFile,
+			dirs:readDir,
+			trees:readTree
+		},
+
+		processPackage = function(pack, destPack){
+			// treeItem is the package location tree; it may give explicit exclude instructions
+			var treeItem;
+			for(var trees = pack.trees || [], i = 0; i<trees.length; i++){
+				if(trees[i][0]==pack.location){
+					treeItem = trees[i];
+					break;
+				}
+			}
+			if(!treeItem){
+				// create a tree item; don't traverse into hidden, backup, etc. files (e.g., .svn, .git, etc.)
+				treeItem = [pack.location, destPack.location, /(\/\.)|(~$)/];
+			}
+
+			var filenames = [];
+			readTree(treeItem, function(filename){ filenames.push(filename); });
+
+			// next, sift filenames to find AMD modules
+			var
+				maybeAmdModules = {},
+				notModules = {},
+				locationPathLength = pack.location.length + 1,
+				packName = pack.name,
+				prefix = packName ? packName + "/" : "",
+				mainModuleInfo = packName && bc.getSrcModuleInfo(packName),
+				mainModuleFilename = packName && mainModuleInfo.url;
+			filenames.forEach(function(filename){
+				// strip the package location path and the .js suffix(iff any) to get the mid
+				var
+					maybeModule = /\.js$/.test(filename),
+					mid = prefix + filename.substring(locationPathLength, maybeModule ? filename.length-3 : filename.length),
+					moduleInfo = maybeModule && bc.getSrcModuleInfo(mid);
+				if(!maybeModule){
+					notModules[mid] = [filename, mid];
+				}else if(filename==mainModuleFilename){
+					maybeAmdModules[packName] = mainModuleInfo;
+				}else{
+					maybeAmdModules[mid] = moduleInfo;
+				}
+			});
+
+			// add modules as per explicit pack.modules vector; this is a way to add modules that map strangely
+			// (for example "myPackage/foo" maps to the file "myPackage/bar"); recall, packageInfo.modules has two forms:
+			//
+			//	 modules:{
+			//		 "foo":1,
+			//		 "foo":"path/to/foo/filename.js"
+			//	 }
+			for(var mid in pack.modules){
+				var
+					fullMid = prefix + mid,
+					moduleInfo = bc.getSrcModuleInfo(fullMid);
+				if(typeof pack.modules[mid]=="string"){
+					moduleInfo.url = pack.modules[mid];
+				}
+				maybeAmdModules[fullMid] = moduleInfo;
+				delete notModules[fullMid];
+			};
+
+			var tagResource = getResourceTagFunction(pack.resourceTags);
+
+			// start all the package modules; each property holds a module info object
+			for(var p in maybeAmdModules){
+				moduleInfo = maybeAmdModules[p];
+				var resource = {
+					src:moduleInfo.url,
+					dest:bc.getDestModuleInfo(moduleInfo.mid).url,
+					pid:moduleInfo.pid,
+					mid:moduleInfo.mid,
+					pack:pack,
+					deps:[]
+				};
+				start(resource, tagResource);
+			}
+
+			// start all the "notModules"
+			var prefixLength = prefix.length;
+			for(p in notModules){
+				resource = {
+					src:notModules[p][0],
+					// not really an AMD mid, but the filename with installation-dependent prefix stripped
+					// this makes tagging easier
+					mid:notModules[p][1],
+					dest:catPath(destPack.location, p.substring(prefixLength))
+				};
+				start(resource, tagResource);
+			}
+
+			// finish by processing all the trees, dirs, and files explicitly specified for the package
+			for(i = 0; i<treesDirsFiles.length; i++){
+				var set = treesDirsFiles[i];
+				if(pack[set]){
+					pack[set].forEach(function(item){
+						discover[set](item, function(src, dest){
+							start({src:src, dest:dest}, tagResource);
+						});
+					});
+				}
+			}
+		},
+
+		discoverPackages = function(){
+			// discover all the package modules; discover the default package last since it may overlap
+			// into other packages and we want modules in those other packages to be discovered as members
+			// of those other packages; not as a module in the default package
+			for(var p in bc.packages){
+				processPackage(bc.packages[p], bc.destPackages[p]);
+			}
+		};
+
+	return function(){
+		///
+		// build/discover
+
+		bc.waiting++; // matches *1*
+
+		// start the synthetic report resource
+		start({
+			tag:{report:1},
+			src:"*report",
+			dest:"*report",
+			reports:[]
+		});
+
+		discoverPackages();
+
+		// discover all trees, dirs, and files
+		var tagResource = getResourceTagFunction(bc.resourceTags);
+		for(var i = 0; i<treesDirsFiles.length; i++){
+			var set = treesDirsFiles[i];
+			bc[set].forEach(function(item){
+				discover[set](item, function(src, dest){
+					start({src:src, dest:dest}, tagResource);
+				});
+			});
+		}
+
+		// advise all modules that are to be written as a layer
+		// advise the loader of boot layers
+		for(var mid in bc.layers){
+			var
+				layer = bc.layers[mid],
+				moduleInfo = bc.getSrcModuleInfo(mid),
+				resource = bc.resources[moduleInfo.url];
+			if(!resource){
+				// this is a synthetic layer (just a set of real modules aggregated but doesn't exist in the source)
+				resource = {
+					tag:{synthetic:1, amd:1},
+					src:moduleInfo.url,
+					dest:bc.getDestModuleInfo(moduleInfo.mid).url,
+					pid:moduleInfo.pid,
+					mid:moduleInfo.mid,
+					pack:moduleInfo.pack,
+					deps:[],
+					text:"define([], 1);" + bc.newline,
+					getText:function(){
+						return this.text;
+					},
+					encoding:"utf8"
+				};
+				start(resource);
+			}
+			resource.layer = layer;
+			if(layer.boot){
+				if(bc.loader){
+					bc.loader.boots.push(resource);
+				}else{
+					bc.log("inputNoLoaderForBoot", ["boot layer", mid]);
+				}
+			}
+		}
+
+		bc.passGate(); // matches *1*
+	};
+});
diff --git a/util/build/examples/dojo-base-json-dot.profile.js b/util/build/examples/dojo-base-json-dot.profile.js
new file mode 100644
index 0000000..ea8c991
--- /dev/null
+++ b/util/build/examples/dojo-base-json-dot.profile.js
@@ -0,0 +1,4 @@
+var profile = {
+	depsDumpDotFilename:"dojo-base-json.dot",
+	dotModules:"dojo/_base/json"
+};
\ No newline at end of file
diff --git a/util/build/examples/dojoConfig.js b/util/build/examples/dojoConfig.js
new file mode 100644
index 0000000..58fbfb2
--- /dev/null
+++ b/util/build/examples/dojoConfig.js
@@ -0,0 +1,9 @@
+var dojoConfig = {
+	packages:[{
+		name:"dojo",
+		location:"../../../dojo"
+	},{
+		name:"dijit",
+		location:"../../../dijig"
+	}]
+};
diff --git a/util/build/examples/profile-with-code.profile.js b/util/build/examples/profile-with-code.profile.js
new file mode 100644
index 0000000..6958cae
--- /dev/null
+++ b/util/build/examples/profile-with-code.profile.js
@@ -0,0 +1,12 @@
+function timestamp(){
+	// this function isn't really necessary...
+	// just using it to show you can call a function to get a profile property value
+	var d = new Date();
+	return d.getFullYear() + '-' + (d.getMonth()+1) + "-" + d.getDate() + "-" +
+		d.getHours() + ':' + d.getMinutes() + ":" + d.getSeconds();
+}
+
+var profile = {
+	basePath:".",
+	buildTimestamp:timestamp()
+};
diff --git a/util/build/examples/relative-base-path.profile.js b/util/build/examples/relative-base-path.profile.js
new file mode 100644
index 0000000..96250e3
--- /dev/null
+++ b/util/build/examples/relative-base-path.profile.js
@@ -0,0 +1,3 @@
+var profile = {
+	basePath:"."
+};
diff --git a/util/build/examples/require.js b/util/build/examples/require.js
new file mode 100644
index 0000000..55af9a3
--- /dev/null
+++ b/util/build/examples/require.js
@@ -0,0 +1,10 @@
+require({
+	packages:[{
+		name:"dojo",
+		location:"../../../dojo"
+	},{
+		name:"dijit",
+		location:"../../../dijig"
+	}]
+});
+
diff --git a/util/build/examples/simple1.profile.js b/util/build/examples/simple1.profile.js
new file mode 100644
index 0000000..c5f8901
--- /dev/null
+++ b/util/build/examples/simple1.profile.js
@@ -0,0 +1,4 @@
+var profile = {
+  someProperty:"someValue",
+  someOtherProperty:"someOtherValue"
+};
diff --git a/util/build/examples/trees-dirs-files.profile.js b/util/build/examples/trees-dirs-files.profile.js
new file mode 100644
index 0000000..7a1571e
--- /dev/null
+++ b/util/build/examples/trees-dirs-files.profile.js
@@ -0,0 +1,22 @@
+var profile = {
+	basePath:"../../..",
+	releaseDir:"./trees-dirs-files-ouput",
+	releaseName:"",
+	trees:[
+		["dojo/tests", "./dojo-tests", /(\/\.)|(~$)/],
+		["dijit/tests", "./dijit-tests", /(\/\.)|(~$)/]
+ 	],
+	dirs:[
+		["dojo", "./dojo-root", /(\/\.)|(~$)/],
+		["dijit", "./dijit-root", /(\/\.)|(~$)/]
+	],
+	files:[
+		["dojo/dojo.js", "./dojo.js"],
+		["dijit/dijit.js", "./dijit.js"]
+	],
+	resourceTags:{
+		copyOnly: function(filename, mid){
+			return true;
+		}
+	}
+};
diff --git a/util/build/fileHandleThrottle.js b/util/build/fileHandleThrottle.js
new file mode 100644
index 0000000..86af065
--- /dev/null
+++ b/util/build/fileHandleThrottle.js
@@ -0,0 +1,23 @@
+define([], function(){
+	var
+		count= 0,
+		max= 10,
+		queue= [];
+	return {
+		release: function(){
+			if(queue.length){
+				(queue.shift())();
+			}else{
+				count--;
+			}
+		},
+		enqueue: function(proc){
+			if(count<max){
+				count++;
+				proc();
+			}else{
+				queue.push(proc);
+			}
+		}
+	};
+});
diff --git a/util/build/fileUtils.js b/util/build/fileUtils.js
new file mode 100644
index 0000000..7f34ed3
--- /dev/null
+++ b/util/build/fileUtils.js
@@ -0,0 +1,185 @@
+define(["./fs", "./buildControlBase", "dojo/has"], function(fs, bc, has) {
+	var
+		getFilename= function(filename) {
+			if (/\//.test(filename)) {
+				return filename.match(/^.*\/([^\/]+)$/)[1];
+			}
+			return filename;
+		},
+
+		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(/(\.([^\/]*))$/);
+			return (match && (trimDot ? match[2] : match[1])) || "";
+		},
+
+		cleanupPath= function(path) {
+			// change any falsy to ""
+			path= path || "";
+
+			// change all backslashes to forward slashes for those with bad habits from windows
+			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);
+			}
+			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, "/");
+			}
+		},
+
+		compactPath = function(path){
+			var result = [],
+				segment, lastSegment;
+			path = path.replace(/\\/g, '/').split('/');
+			while(path.length){
+				segment = path.shift();
+				if(segment==".." && result.length && lastSegment!=".."){
+					result.pop();
+					lastSegment = result[result.length - 1];
+				}else if(segment!="."){
+					result.push(lastSegment= segment);
+				} // else ignore "."
+			}
+			return result.join("/");
+		},
+
+		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) {
+			return path && path.length && isAbsolutePathRe.test(path);
+		},
+
+		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);
+			}
+			return compactPath(src);
+		},
+
+		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); };
+			return ts.getFullYear() + f(ts.getMonth()+1) + f(ts.getDate()) + f(ts.getHours()) + f(ts.getMinutes()) + f(ts.getSeconds());
+		},
+
+		dirExists= function(
+			filename
+		) {
+			try {
+				return fs.statSync(filename).isDirectory();
+			} catch(e) {
+				return false;
+			}
+		},
+
+		fileExists= function(
+			filename
+		) {
+			try {
+				return fs.statSync(filename).isFile();
+			} catch(e) {
+				return false;
+			}
+		},
+
+		checkedDirectories= {},
+
+		clearCheckedDirectoriesCache= function() {
+			checkedDirectories= {};
+		},
+		ensureDirectory= function(path) {
+			if (!checkedDirectories[path]) {
+				if (!dirExists(path)) {
+					ensureDirectory(getFilepath(path));
+					try {
+						fs.mkdirSync(path, 0755);
+					} catch (e) {
+						//squelch
+					}
+				}
+				checkedDirectories[path]= 1;
+			}
+		},
+
+		ensureDirectoryByFilename= function(filename) {
+			ensureDirectory(getFilepath(filename));
+		},
+
+		readAndEval= function(filename, type) {
+			try {
+				if (fileExists(filename)) {
+					return eval("(" + fs.readFileSync(filename, "utf8") + ")");
+				}
+			} catch (e) {
+				bc.log("failedReadAndEval", ["filename", filename, "type", type, "error", e]);
+			}
+			return {};
+		},
+
+		maybeRead = function(filename) {
+			try {
+				if (fileExists(filename)) {
+					return fs.readFileSync(filename, "utf8");
+				}
+			} catch (e) {
+			}
+			return 0;
+		};
+
+
+	return {
+		getFilename:getFilename,
+		getFilepath:getFilepath,
+		getFiletype:getFiletype,
+		cleanupPath:cleanupPath,
+		isAbsolutePath:isAbsolutePath,
+		normalize:normalize,
+		getAbsolutePath:getAbsolutePath,
+		catPath:catPath,
+		compactPath:compactPath,
+		computePath:computePath,
+		getTimestamp:getTimestamp,
+		dirExists:dirExists,
+		ensureDirectory:ensureDirectory,
+		ensureDirectoryByFilename:ensureDirectoryByFilename,
+		clearCheckedDirectoriesCache:clearCheckedDirectoriesCache,
+		readAndEval:readAndEval,
+		maybeRead:maybeRead,
+		fileExists:fileExists
+	};
+});
diff --git a/util/build/fs.js b/util/build/fs.js
new file mode 100644
index 0000000..bc52ff2
--- /dev/null
+++ b/util/build/fs.js
@@ -0,0 +1,3 @@
+define(["dojo/has!host-node?./node/fs:./rhino/fs"], function(result){
+  return result;
+});
diff --git a/util/build/help.txt b/util/build/help.txt
new file mode 100644
index 0000000..feebcbc
--- /dev/null
+++ b/util/build/help.txt
@@ -0,0 +1,77 @@
+NAME
+     The Dojo Builder - Read, process, and write a set of resources as instructed by a profile.
+
+DESCRIPTION
+     Discover and process a set of resources with an ordered synchronized set of transforms.
+
+     See http://dojotoolkit.org/reference-guide/build/index.html for reference documentation.
+     
+     See http://dojotoolkit.org/reference-guide/build/qref.html for a quick reference manual.
+
+     Typically this program is executed with the convience wrapper /util/buildscripts/build.bat (Window) or
+     /util/buildscripts/build.sh (all other environments); it may also be executed explicitly.
+
+     Usage with the build script on non-windows:
+     path/to/util/buildscripts/build.sh [options]
+     
+     Usage with the build script on windows:
+     IMPORTANT: the util/buildscripts directory must be the current working directory
+     build.bat [options]
+
+     Explicit usage with node.js:
+     node path/to/dojo/dojo.js load=build [options] 
+     
+     Explicit usage with java:
+     java -Xms256m -Xmx256m -jar path/to/util/shrinksafe/js.jar path/to/dojo/dojo.js baseUrl=path/to/dojo load=build [options]
+     
+     IMPORTANT:
+     This program assumes the default directory structure provided with the standard dojo source release.
+     
+     IMPORTANT:
+     When using v1.6- profiles, this program assumes the current working directory is utils/buildscripts.
+
+OPTIONS
+     -p <filename>
+     --profile <filename>      read profile for file
+     
+     -p <profile>
+     --profile <profile>       read profile from profile in util/buildscripts/profiles
+     
+     --package <path>          read profile from package.json located in the directory path
+     
+     --require <filename>
+     --dojoConfig              read profile from loader configuration 
+     
+     --htmlFiles <file-list>   deduce profile from HTML file(s); file-list is a comma-separated list of filenames
+     
+     --htmlDir <path>          deduce profile from all HTML files in directory at path
+     
+     --check-args              print computed raw command line input, including raw profiles, then terminate
+     
+     --check                   print computed profile, then terminate
+     
+     --check-discovery         print all discovered resources, then terminate
+     
+     --debug-check             print computed profile, including internal structures
+     
+     -r
+     --release                 process the build control script(s) and/or profile(s) and transform sources into a release
+     
+     --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.
+     
+     --mini                    Ignore resources tagged as not mini (e.g. tests, demos dijit/bench, etc.)
+     
+     -v                        print the program's version number
+     
+     --help                    this help message
+     
+     Scalar profile property values may also be specified as options with the syntax
+     
+          --<profile-property-name> <value>
+     
diff --git a/util/build/main.js b/util/build/main.js
new file mode 100644
index 0000000..4cc4f9e
--- /dev/null
+++ b/util/build/main.js
@@ -0,0 +1,284 @@
+//
+// The Dojo Build System
+//
+// This is application is implemented as an AMD package intended to be loaded and executed by dojo. It is known to work correctly
+// with node.js (fast!) and rhino (slow!). The program may be started from a command prompt as follows:
+//
+// node.js:
+//	 >node path/to/dojotoolkit/dojo/dojo.js load=build <arguments>
+//
+// rhino:
+//	 >java -jar path/to/js.jar path/to/dojotoolkit/dojo/dojo.js baseUrl=path/to/dojotoolkit/dojo load=build <arguments>
+//
+//	 * notice that, owing to the defective design of rhino, it is impossible for a script to know the location from
+//		 which it was executed; therefore, the baseUrl must be provided.
+//
+// util/buildscripts/bng:
+//	 TODOC
+//
+// The application proceeds as follows:
+//
+// 1. Process the command line and then process the build control script(s)/profile as specified by the command line.
+// 2. Discover all resources as instructed by the build control script
+// 3. Move the resources through an ordered set of gates. Zero to many synchronous and/or asynchronous transforms may be applied to various
+//		resources as specified by the build control script. Different resources can be subject to different transforms. Resources are allowed
+//		to move through gates without stopping until a "synchronized" gate is encountered. All transforms must complete for the previous gate before
+//		any transform is allowed on the synchronized gate.
+// 4. After the last gate has been completed, print a done message and terminate.
+//
+// See also:
+//
+// project home: http://bdframework.org/bdBuild/index
+// fossil: http://bdframework.org/bdBuild/repo
+// github: https://github.com/altoviso/bdBuild
+// docs: http://bdframework.org/bdBuild/docs
+
+define(["require", "dojo/has"], function(require, has) {
+
+	// host-dependent environment initialization
+	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){
+			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") {
+					result.push(item);
+				}
+			});
+			return result;
+		});
+		// TODO: make this real
+		has.add("is-windows", /indows/.test(environment["os.name"]));
+	} 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) {
+				text+= "var " + p + "=" + mid + "." + p + ";\n";
+			}
+		}
+		return text;
+	};
+
+	// run the build program
+	require(["./buildControl", "./process"], function(bc, process) {
+		var
+			gateListeners= bc.gateListeners= [],
+
+			transforms= bc.transforms,
+			transformJobs= bc.transformJobs,
+			transformJobsLength= transformJobs.length,
+
+			// all discovered resources
+			resources= [],
+
+			reportError= function(resource, err) {
+				bc.log("transformFailed", ["resource", resource.src, "transform", resource.jobPos, "error", err]);
+				resource.error= true;
+			},
+
+			returnFromAsyncProc= function(resource, err) {
+				bc.waiting--;
+				if (err) {
+					// notice reportError can decide to continue or panic
+					reportError(resource, err);
+				}
+				advance(resource, true);
+			},
+
+			advance= function(resource, continuingSameGate) {
+				if (resource.error) {
+					return;
+				}
+				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];
+					// candidate (if any) is a [transformProc, gateId] pair
+					if (candidate && candidate[1]<=bc.currentGate) {
+						resource.jobPos++;
+						bc.waiting++;
+						err= candidate[0](resource, returnFromAsyncProc);
+						if (err===returnFromAsyncProc) {
+							// the transform proc must call returnFromAsyncProc when complete
+							return;
+						}
+						bc.waiting--;
+						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
+							// gate; when all resources have cleared the next gate, passGate will notice error count and
+							// quit
+							break;
+						}
+					} else {
+						break;
+					}
+				}
+
+				// got through the gate; advise passGate which will decrement the lock we set at top of this function
+				passGate();
+			},
+
+			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 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) {
+					return;
+				} //	else all processes have passed through bc.currentGate
+
+				if(bc.checkDiscovery){
+					//passing the first gate which is dicovery and just echoing discovery; therefore
+					process.exit(0);
+				}
+
+				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) {
+						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");
+					process.exit(bc.exitCode);
+					// that's all, folks...
+				}
+			};
+
+		bc.start= function(resource) {
+			// check for collisions
+			var
+				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]) {
+				// 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;
+
+			if(bc.checkDiscovery){
+				bc.log("pacify", src + "-->" + dest);
+				return;
+			}
+
+			// find the transformJob and start it...
+			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;
+					advance(resource);
+					return;
+				}
+			}
+			bc.log("noTransform", ["resoures", resource.src]);
+		};
+
+		function doBuild(){
+			var
+				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) {
+				pluginNames.push(p);
+				deps.push(bc.plugins[p]);
+			}
+			bc.plugins= {};
+			require(deps, function() {
+				// pull out the discovery procedures
+				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++];
+					// replace every occurence of id with proc
+					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;
+								break;
+							}
+						}
+					});
+				}
+				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.log("pacify", "discovering resources...");
+				advanceGate(-1);
+				discoveryProcs.forEach(function(proc) { proc(); });
+				passGate();  // matched *1*
+			});
+		}
+
+		if(!bc.errorCount && bc.release){
+			doBuild();
+		}
+	});
+});
diff --git a/util/build/messages.js b/util/build/messages.js
new file mode 100644
index 0000000..44785a4
--- /dev/null
+++ b/util/build/messages.js
@@ -0,0 +1,302 @@
+define([], function(){
+	var categories = {
+			info:[[100, 199]],
+			warn:[[200, 299]],
+			error:[[300, 399]],
+			report:[[400, 499]]
+		},
+
+		messages = [
+		// [order, numeric-id, symbolic-id, message]
+		// info 100-199
+		[1, 100, "legacyAssumed", "Assumed module uses legacy loader API."],
+		[1, 101, "legacyUsingLoadInitPlug", "Using dojo/loadInit plugin for module."],
+		[1, 102, "optimize", "Optimizing module"],
+		[1, 103, "optimizeDone", "Optimizing module complete."],
+		[1, 104, "optimizeMessages", "Optimizer messages."],
+		[1, 105, "pacify", ""],
+		[1, 106, "cssOptimize", "Optimizing CSS."],
+		[1, 107, "packageVersion", "Package Version:"],
+		[1, 108, "internStrings", "Interning strings."],
+		[1, 109, "processHtmlFiles", "Processing HTML files."],
+		[1, 110, "userTrace", "User trace:"],
+		[1, 110, "userInfo", "User info:"],
+
+		// warn 200-299
+		[1, 200, "configUnresolvedValues", "Configuration contains unsolved values."],
+		[1, 201, "amdCircularDependency", "Cycle detected in layer dependencies."],
+		[1, 202, "amdInconsistentMid", "AMD module specified and absolute module identifier that is not consistent with the configuration and filename"],
+		[1, 203, "amdPureContainedLegacyApi", "Module tagged as pure AMD yet it contains legacy loader API applications."],
+		[1, 205, "amdNotPureContainedNoLegacyApi", "Module not tagged as pure AMD yet it contains AMD API applications."],
+		[1, 206, "legacyMultipleProvides", "Module included multiple dojo.provide applications."],
+		[1, 207, "legacyImproperProvide", "dojo.provide application identifier inconsistent with module identifier."],
+		[1, 208, "inputDeprecatedProfileFile", "The \"profileFile\" switch has been deprecated; use \"profile\" instead."],
+		[1, 209, "missingPackageJson", "Missing or empty package.json."],
+		[1, 210, "inputDeprecatedStripConsole", "Given strip console value is deprecated."],
+		[1, 211, "inputDeprecated", "Deprecated switch; ignored"],
+		[1, 212, "oddDojoPath", "No profile.basePath provided, yet dojo path is relative and running build with the current working directory different than util/buildscripts"],
+		[1, 213, "buildUsingDifferentDojo", "Dojo path specified in profile is different than the dojo being used for the build program"],
+		[1, 214, "ignoringReleaseDirName", "DestBasePath given; ignoring releaseDir and releaseName."],
+		[1, 215, "inputLoggerRemoved", "Logger has been removed; all calls ignored"],
+		[1, 216, "dojoHasUnresolvedMid", "dojo/has plugin resource could not be resolved during build-time."],
+		[1, 217, "cleanRemoved", "the clean action has been removed; use rm (*nix) or rmdir (Windows)"],
+		[1, 218, "inputProfileFileDeprecated", "the command line switch profileFile is deprectated; use profile for both files and profiles"],
+		[1, 219, "userWarn", "User warn:"],
+		[1, 220, "outputToProfileFileDeprecated", "Writing htmlFiles- or htmlDirs-derived profile via the profileFile option is deprecated; use the writeProfile option instead"],
+		[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, 225, "missingDirDuringDiscovery", "A directory that was scheduled to be read during discovery did not exist."],
+
+		// error 300-399
+		[1, 300, "dojoHasMissingPlugin", "Missing dojo/has module."],
+		[1, 302, "dojoHasMissingMid", "Missing dojo/has plugin resource that was resolved at build-time."],
+		[1, 303, "amdMissingLayerIncludeModule", "Missing include module for layer."],
+		[1, 304, "amdMissingLayerExcludeModule", "Missing exclude module for layer."],
+		[1, 305, "amdMissingLayerModuleText", "Missing module text for layer."],
+		[1, 306, "legacyFailedEval", "Failed to evaluate legacy API application."],
+		[1, 307, "amdFailedEval", "Failed to evaluate module tagged as pure AMD (fell back to processing with regular expressions)."],
+		[1, 308, "amdFailedDefineEval", "Failed to evaluate AMD define function."],
+		[1, 309, "i18nNoRoot", "Missing root bundle for locale-specific legacy i18n bundle"],
+		[1, 310, "i18nImproperBundle", "Non-i18n module found in nls tree (copied only)."],
+		[1, 311, "amdMissingDependency", "Missing dependency."],
+		[1, 312, "optimizeFailedWrite", "Failed to write optimized file."],
+		[1, 313, "cssOptimizeFailed", "Failed to optimize CSS file."],
+		[1, 314, "execFailed", "(Rhino)External process threw."],
+		[1, 315, "inputInvalidPath", "Unable to compute absolute path."],
+		[1, 316, "inputUnknownAction", "Unknown action."],
+		[1, 317, "inputUnknownStripConsole", "Unknown strip console value."],
+		[1, 318, "inputUnknownLayerOptimize", "Unknown layer optimize value."],
+		[1, 319, "inputUnknownOptimize", "Unknown optimize value."],
+		[1, 320, "inputUnknownTransform", "Unknown transform."],
+		[1, 321, "inputUnknownGate", "Unknown gate."],
+		[1, 322, "inputNoLoaderForBoot", "Unable to find loader for boot layer."],
+		[1, 323, "failedReadAndEval", "failed to read and eval file."],
+		[1, 324, "transformFailed", "Error while transforming resource."],
+		[1, 325, "discoveryFailed", "Failed to discover any resources to transform. Nothing to do; terminating application"],
+		[1, 326, "overwrite", "Output intersects input"],
+		[1, 327, "outputCollide", "Multiple resources are destined for same filename."],
+		[1, 328, "noTransform", "No transform found for discovered resouce."],
+		[1, 329, "layerToMidFailed", "Failed to resolve layer name into a module identifier."],
+		[1, 330, "layerMissingDependency", "Failed to resolve layer dependency."],
+		[1, 331, "getDependencyListRemoved", "load(\"getDependencyList.js\") is no supported."],
+		[1, 332, "invalidMessageId", "Invalid message identifier."],
+		[1, 333, "legacyMissingDependency", "Missing dependency in legacy module."],
+		[1, 334, "amdCannotInstantiateLayer", "Cannot instantiate all modules in layer."],
+		[1, 335, "dojoPragmaEvalFail", "Failed to evaluate dojo pragma."],
+		[1, 336, "dojoPragmaInvalid", "Failed to find end marker for dojo pragma."],
+		[1, 337, "inputMissingPackageJson", "Missing or empty package.json file at location specified by package flag."],
+		[1, 337, "inputMalformedPackageJson", "Malformed package.json file."],
+		[1, 338, "inputProfileDoesNotExist", "Profile given for \"profile\" switch does not exist."],
+		[1, 339, "inputProfileFileDoesNotExist", "Profile file given for \"profileFile\" switch does not exist."],
+		[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, 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."],
+		[1, 347, "inputFailedToEvalProfile", "Failed to evaluate profile file."],
+		[1, 348, "userError", "User error:"],
+		[1, 349, "missingPrefix", "Missing prefix for top-level module."],
+		[1, 350, "cannotDeduceModuleIdFrom16LayerName", "Cannot deduce module identifier from layer name"],
+		[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."],
+
+
+
+		// reports 400-499
+		[1, 400, "hasReport", "Has Features Detected"],
+		[3, 499, "signoff", "Process completed normally:"]],
+
+		// 500-999, reserved by build programs
+		// 1000+, may be used by extension apps
+
+		lastReportId = 400,
+
+		lastUserId = 500,
+
+		warnCount = 0,
+
+		errorCount = 0,
+
+		messageMap = {},
+
+		pacifySet = {},
+
+		getNewMessageId = function(report){
+			return report ? ++lastReportId : ++lastUserId;
+		},
+
+		addMessage = function(order, numericId, symbolicId, message, pacifyMessage){
+			for(var i= 0; i<messages.length; i++){
+				if(messages[i][0]>order){
+					break;
+				}
+			}
+			messages.splice(i, 0, [order, numericId, symbolicId, message, []]);
+			messageMap[symbolicId] = messages[i];
+
+			if(pacifyMessage){
+				pacifySet[symbolicId] = 1;
+			}
+		},
+
+		addCategory = function(name, range){
+			if(categories[name]){
+				categories[name].push(range);
+			}else{
+				categories[name] = [range];
+			}
+		},
+
+		getPrefix = function(id){
+			var result;
+			for(var p in categories){
+				if(categories[p].some(function(range){
+					if(range[0]<=id && id<range[1]){
+						return result = p + "(" + id + ")";
+					}
+					return 0;
+				})){
+					return result;
+				}
+			}
+			return "message-id(" + id + ")";
+		},
+
+		getArgs = function(args){
+			var result = "";
+			if(typeof args=="undefined"){
+				// nothing to decode
+			}else if(typeof args=="string"){
+				result+= args;
+			}else if(args.length==1){
+				result+= args[0];
+			}else{
+				for(var i= 0; i<args.length;){
+					result+= args[i++];
+					if(i<args.length){
+						result+= ": " + args[i++];
+					}
+					if(i<args.length){
+						result+= "; ";
+					}
+				}
+			}
+			return result;
+		},
+
+		stop = 0,
+
+		log = function(id, args){
+			if(stop){
+				return;
+			}
+			if(id=="pacify"){
+				console.log(args);
+			}else if(id in messageMap){
+				var item = messageMap[id];
+				item[4].push(args);
+				if(200<=item[1] && item[1]<=299){
+					warnCount++;
+				}else if(300<=item[1] && item[1]<=399){
+					errorCount++;
+				}
+				if(id in pacifySet){
+					console.log(getPrefix(item[1]) + " " + item[3] + " " + getArgs(args));
+				}
+			}else{
+				//require.nodeRequire("assert").fail(1, 2, "here", "x");
+				messageMap.invalidMessageId[4].push(["id", id].concat(args));
+			}
+		},
+
+		optimizerReportedErrors = 0,
+
+		logOptimizerReportedErrors = function(){
+			if(!optimizerReportedErrors){
+				log("optimizerReportedErrors");
+				optimizerReportedErrors = 1;
+			}
+		},
+
+		optimizerOutput= "",
+
+		logOptimizerOutput = function(text){
+			if(/\sERROR\s/.test(text)){
+				// the google closure error format
+				logOptimizerReportedErrors();
+			}
+			optimizerOutput+= text;
+		},
+
+		getOptimizerOutput = function(){
+			return optimizerOutput;
+		},
+
+		getAllNonreportMessages = function(){
+			var result = "";
+			messages.forEach(function(item){
+				if ((item[1]<400 || 499<item[1]) && item[4].length){
+					result+= getPrefix(item[1]) + " " + item[3] + "\n";
+					item[4].forEach(function(item){
+						result+= "\t" + getArgs(item) + "\n";
+					});
+				}
+			});
+			return result;
+		},
+
+		getAllReportMessages = function(){
+			var result = "";
+			messages.forEach(function(item){
+				if (400<=item[1] && item[1]<=499 && item[4].length){
+					result+= "\n\n" + item[3] + "\n";
+					item[4].forEach(function(item){
+						result+= "\t" + getArgs(item) + "\n";
+					});
+				}
+			});
+			return result;
+		};
+
+	// sort the messages; maybe some added, maybe they are out of order above
+	var temp = messages;
+	messages = [];
+	temp.forEach(function(item){
+		addMessage(item[0], item[1], item[2], item[3]);
+
+		// by default, send all warnings and errors to the console
+		if(200<=item[1] && item[1]<=399){
+			pacifySet[item[2]] = 1;
+		}
+	});
+
+	//also send this to the console
+	pacifySet.packageVersion = 1;
+	pacifySet.signoff = 1;
+
+	return {
+		stop:function(){stop = 1;},
+		messages:messages,
+		messageMap:messageMap,
+		pacifySet:pacifySet,
+		getNewMessageId:getNewMessageId,
+		addMessage:addMessage,
+		addCategory:addCategory,
+		log:log,
+		logOptimizerOutput:logOptimizerOutput,
+		getOptimizerOutput:getOptimizerOutput,
+		getAllNonreportMessages:getAllNonreportMessages,
+		getAllReportMessages:getAllReportMessages,
+		getWarnCount:function(){return warnCount;},
+		getErrorCount:function(){return errorCount;},
+		trace:function(message){log("userTrace", message);},
+		info:function(message){log("userInfo", message);},
+		warn:function(message){log("userWarn", message);},
+		error:function(message){log("userError", message);}
+	};
+});
diff --git a/util/build/node/fs.js b/util/build/node/fs.js
new file mode 100644
index 0000000..093dd47
--- /dev/null
+++ b/util/build/node/fs.js
@@ -0,0 +1,28 @@
+define(["../fileHandleThrottle"], function(fht) {
+	var fs= require.nodeRequire("fs");
+	return {
+		statSync:fs.statSync,
+		mkdirSync:fs.mkdirSync,
+		readFileSync:fs.readFileSync,
+		writeFileSync:fs.writeFileSync,
+		readdirSync:fs.readdirSync,
+
+		readFile: function(filename, encoding, cb) {
+			fht.enqueue(function(){
+				fs.readFile(filename, encoding, function(code){
+					fht.release();
+					cb.apply(null, arguments);
+				});
+			});
+		},
+
+		writeFile: function(filename, contents, encoding, cb) {
+			fht.enqueue(function(){
+				fs.writeFile(filename, contents, encoding, function(code){
+					fht.release();
+					cb.apply(null, arguments);
+				});
+			});
+		}
+	};
+});
diff --git a/util/build/node/process.js b/util/build/node/process.js
new file mode 100644
index 0000000..80c2687
--- /dev/null
+++ b/util/build/node/process.js
@@ -0,0 +1,45 @@
+define(["../fileHandleThrottle", "../messages"], function(fht, messages) {
+	var 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);
+			});
+		},
+
+		exec:function() {
+			// signature is (command, arg1, ..., argn, errorMessage, bc, callback)
+			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];
+			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);
+				});
+				process.stdout.on("data", function(data){
+					text+= data;
+				});
+				process.stderr.on("data", function(data){
+					text+= data;
+				});
+			});
+		}
+	};
+});
+
diff --git a/util/build/optimizeRunner.js b/util/build/optimizeRunner.js
new file mode 100644
index 0000000..92c5c1f
--- /dev/null
+++ b/util/build/optimizeRunner.js
@@ -0,0 +1,141 @@
+function writeFile(filename, contents, encoding, cb) {
+	if (arguments.length==3 && typeof encoding!="string") {
+		cb= encoding;
+		encoding= 0;
+	}
+	var
+		outFile = new java.io.File(filename),
+		outWriter;
+	if(encoding){
+		outWriter = new java.io.OutputStreamWriter(new java.io.FileOutputStream(outFile), encoding);
+	}else{
+		outWriter = new java.io.OutputStreamWriter(new java.io.FileOutputStream(outFile));
+	}
+
+	var os = new java.io.BufferedWriter(outWriter);
+	try{
+		os.write(contents);
+	}finally{
+		os.close();
+	}
+	if (cb) {
+		cb(0);
+	};
+}
+
+var built = "//>>built\n";
+
+function sscompile(src, 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);
+
+		var text= readFile(src, "utf-8");
+		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();
+	}
+	writeFile(dest, copyright + built + text, "utf-8");
+}
+
+var JSSourceFilefromCode, closurefromCode, jscomp= 0;
+function ccompile(src, 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(readFile(src, "utf-8")));
+
+	//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);
+	writeFile(dest, copyright + built + compiler.toSource(), "utf-8");
+}
+
+
+var
+	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;
+
+while(1){
+	// the + "" convert to a Javascript string
+	src= readLine();
+	if(src=="."){
+		break;
+	}
+	dest= readLine();
+	optimizeSwitch= readLine();
+	copyright= eval(readLine());
+	print(dest + ":");
+	var start= (new Date()).getTime();
+	if(/closure/.test(optimizeSwitch)){
+		ccompile(src, dest, optimizeSwitch, copyright);
+	}else{
+		sscompile(src, dest, optimizeSwitch, copyright);
+	}
+	print("Done (compile time:" + ((new Date()).getTime()-start)/1000 + "s)");
+}
+
diff --git a/util/build/plugins/domReady.js b/util/build/plugins/domReady.js
new file mode 100644
index 0000000..944f7e7
--- /dev/null
+++ b/util/build/plugins/domReady.js
@@ -0,0 +1,13 @@
+///
+// \module build/plugins/domReady
+//
+define(["../buildControl"], function(bc) {
+	return {
+		start:function(
+			mid,
+			referenceModule
+		){
+			return bc.amdResources[bc.getSrcModuleInfo("dojo/domReady", referenceModule).mid];
+		}
+	};
+});
diff --git a/util/build/plugins/has.js b/util/build/plugins/has.js
new file mode 100644
index 0000000..af292c6
--- /dev/null
+++ b/util/build/plugins/has.js
@@ -0,0 +1,81 @@
+define(["dojo/regexp"], function(dojoRegExp) {
+	return {
+		start:function(
+			id,
+			referenceModule,
+			bc
+		) {
+			var
+				getHasPluginDependency= function(){
+					var hasPlugin= bc.amdResources["dojo/has"];
+					if(!hasPlugin){
+						bc.log("dojoHasMissingPlugin");
+						return [];
+					}else{
+						return [hasPlugin];
+					}
+				},
+
+				has = function(featureId) {
+					var value = bc.staticHasFeatures[featureId];
+					return (value===undefined || value==-1) ? undefined : value;
+				},
+
+				tokens = id.match(/[\?:]|[^:\?]*/g),
+
+				i = 0,
+
+				get = function(skip){
+					var operator, term = tokens[i++];
+					if(term == ":"){
+						// empty string module name; therefore, no dependency
+						return "";
+					}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);
+							if(hasResult===undefined){
+								return undefined;
+							}else if(!skip && hasResult){
+								// matched the feature, get the first value from the options
+								return get();
+							}else{
+								// did not match, get the second value, passing over the first
+								get(true);
+								return get(skip);
+							}
+						}
+						// a module
+						return term===undefined ? "" : term;
+					}
+				},
+
+				resolvedId = get();
+
+			// we only need the plugin if we need to resolve at run time
+			if(resolvedId===undefined){
+				bc.log("dojoHasUnresolvedMid", ["plugin resource id", id, "reference module id", referenceModule && referenceModule.mid]);
+				return getHasPluginDependency();
+			}
+
+			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");
+				return [];
+			}else{
+				var
+					moduleInfo= bc.getSrcModuleInfo(resolvedId, referenceModule),
+					module= bc.amdResources[moduleInfo.mid];
+				if(module){
+					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]);
+					return getHasPluginDependency();
+				}
+			}
+		}
+	};
+});
diff --git a/util/build/plugins/i18n.js b/util/build/plugins/i18n.js
new file mode 100644
index 0000000..d10a8d3
--- /dev/null
+++ b/util/build/plugins/i18n.js
@@ -0,0 +1,67 @@
+///
+// \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(\/|$))([^\/]*)\/?([^\/]*)/,
+
+		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(
+			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];
+
+			if (!i18nPlugin) {
+				throw new Error("i18n! plugin missing");
+			}
+			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
+	};
+});
diff --git a/util/build/plugins/loadInit.js b/util/build/plugins/loadInit.js
new file mode 100644
index 0000000..4c7545d
--- /dev/null
+++ b/util/build/plugins/loadInit.js
@@ -0,0 +1,13 @@
+///
+// \module build/plugins/loadInit
+//
+define(["../buildControl"], function(bc) {
+	return {
+		start:function(
+			mid,
+			referenceModule
+		){
+			return bc.amdResources[bc.getSrcModuleInfo(mid, referenceModule).mid];
+		}
+	};
+});
diff --git a/util/build/plugins/querySelector.js b/util/build/plugins/querySelector.js
new file mode 100644
index 0000000..e9932b9
--- /dev/null
+++ b/util/build/plugins/querySelector.js
@@ -0,0 +1,15 @@
+define(function() {
+	return {
+		start:function(
+			id,
+			referenceModule,
+			bc
+		) {
+			var result = [bc.amdResources["dojo/selector/_loader"]];
+			if(bc.selectorEngine){
+				result = result.concat(bc.amdResources["dojo/selector/" + bc.selectorEngine]);
+			}
+			return result;
+		}
+	};
+});
diff --git a/util/build/plugins/require.js b/util/build/plugins/require.js
new file mode 100644
index 0000000..430382f
--- /dev/null
+++ b/util/build/plugins/require.js
@@ -0,0 +1,24 @@
+///
+// \module build/plugins/require
+//
+define([], function() {
+	return {
+		start:function(
+			mid,
+			referenceModule,
+			bc
+		) {
+			var result = [];
+			mid.split(",").map(function(mid){
+				var module = bc.amdResources[mid];
+				if (!module) {
+					bc.log("legacyMissingDependency", ["reference module", referenceModule.mid, "dependency", mid]);
+				}else{
+					result.push(module);
+				}
+			});
+			return result;
+		}
+	};
+});
+
diff --git a/util/build/plugins/text.js b/util/build/plugins/text.js
new file mode 100644
index 0000000..1ae5ab0
--- /dev/null
+++ b/util/build/plugins/text.js
@@ -0,0 +1,59 @@
+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(
+			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];
+
+			// 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;
+
+			// 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(bc.internStrings){
+				textResource.tag.noWrite= 0;
+			}
+			return [textPlugin, makePluginPseudoModule(textResource, moduleInfo)];
+		};
+
+	return {
+		start:start
+	};
+});
diff --git a/util/build/process.js b/util/build/process.js
new file mode 100644
index 0000000..369c3f2
--- /dev/null
+++ b/util/build/process.js
@@ -0,0 +1,3 @@
+define(["dojo/has!host-node?./node/process:./rhino/process"], function(result){
+  return result;
+});
diff --git a/util/build/removeComments.js b/util/build/removeComments.js
new file mode 100644
index 0000000..8c6b898
--- /dev/null
+++ b/util/build/removeComments.js
@@ -0,0 +1,17 @@
+define(["dojo/has"], function(has){
+	// FIXME: this module should be replaced with a proper parser to correctly remove comments
+	// see extensive commentary in dojo/_base/loader.js
+
+	if(has("host-rhino")){
+		return function(text){
+			return text.replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, "");
+			// FIXME: try something like the following in rhino...
+			//var f = new Function(text);
+			//return f.toString();
+		};
+	}else{
+		return function(text){
+			return text.replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, "");
+		};
+	}
+});
diff --git a/util/build/replace.js b/util/build/replace.js
new file mode 100644
index 0000000..7e26b79
--- /dev/null
+++ b/util/build/replace.js
@@ -0,0 +1,47 @@
+define(["./fs"], function(fs) {
+	var cached= {};
+
+	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);
+			}
+		} else {
+			// replacement is a single replacement [search, replacement, type] triple
+			replacement= [replacement];
+		}
+		// at this point, encoding has been determined and replacement is a vector of [search, replacement, type] triples
+
+		replacement.forEach(function(item) {
+			var
+				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));
+			}
+			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);
+				}
+			}
+		});
+		return contents;
+	};
+});
+
diff --git a/util/build/rhino/fs.js b/util/build/rhino/fs.js
new file mode 100644
index 0000000..5b8974c
--- /dev/null
+++ b/util/build/rhino/fs.js
@@ -0,0 +1,74 @@
+define([], function() {
+	var
+		readFileSync= function(filename, encoding) {
+			if (encoding=="utf8") {
+				// convert node.js idiom to rhino idiom
+				encoding= "utf-8";
+			}
+			return readFile(filename, encoding || "utf-8");
+		},
+
+		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";
+			}
+			if(encoding){
+				outWriter = new java.io.OutputStreamWriter(new java.io.FileOutputStream(outFile), encoding);
+			}else{
+				outWriter = new java.io.OutputStreamWriter(new java.io.FileOutputStream(outFile));
+			}
+
+			var os = new java.io.BufferedWriter(outWriter);
+			try{
+				os.write(contents);
+			}finally{
+				os.close();
+			}
+		};
+
+	return {
+		statSync: function(filename) {
+			return new java.io.File(filename);
+		},
+
+		mkdirSync: function(filename) {
+			var dir= new java.io.File(filename);
+			if (!dir.exists()) {
+				dir.mkdirs();
+			}
+		},
+
+		readFileSync: readFileSync,
+
+		readdirSync: function(path) {
+			// java returns the complete path with each filename in listFiles; node returns just the filename
+			// 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); });
+		},
+
+		readFile: function(filename, encoding, cb) {
+			var result= readFileSync(filename, encoding);
+			if (cb) {
+				cb(0, result);
+			}
+		},
+
+		writeFileSync:writeFileSync,
+
+		writeFile: function(filename, contents, encoding, cb) {
+			if (arguments.length==3 && typeof encoding!="string") {
+				cb= encoding;
+				encoding= 0;
+			}
+			writeFileSync(filename, contents, encoding);
+			if (cb) {
+				cb(0);
+			};
+		}
+	};
+});
diff --git a/util/build/rhino/process.js b/util/build/rhino/process.js
new file mode 100644
index 0000000..17eef9c
--- /dev/null
+++ b/util/build/rhino/process.js
@@ -0,0 +1,35 @@
+define([], function() {
+	return {
+		cwd:function() {
+			return environment["user.dir"];
+		},
+
+		exit:function(resultCode) {
+			// no documented way to return an exit code in rhino
+			if (resultCode) {
+				java.lang.System.exit(resultCode);
+			}
+			quit();
+		},
+
+		exec:function() {
+			// signature is (command, arg1, ..., argn, errorMessage, bc, callback)
+			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:""};
+			args.push(options);
+			try{
+				runCommand.apply(this, args);
+				callback && callback(0, options.output);
+			}catch(e){
+				bc.log("execFailed", ["message", errorMessage, "output", options.output+"", "error", e]);
+				callback && callback(-1, errorMessage + "\n" + options.output + "\n" + e);
+			}
+		}
+	};
+});
diff --git a/util/build/stringify.js b/util/build/stringify.js
new file mode 100644
index 0000000..41686fe
--- /dev/null
+++ b/util/build/stringify.js
@@ -0,0 +1,150 @@
+///
+// \amd-mid build/stringify
+//
+define(["dojo", "./buildControlBase"], function(dojo, bc) {
+var
+	spaces= "					 ",
+	indentFactor= 2,
+
+	setIndentFactor= function(factor) {
+		indentFactor= factor;
+	},
+
+	indent= function(n, factor) {
+		n= n * (factor || indentFactor);
+		while (spaces.length<n) spaces+= spaces;
+		return spaces.substring(0, n);
+	},
+
+	propName= function(name) {
+		return /^[\w\$]+$/.test(name) ?
+			name + ":" :
+			"'" + name + "':";
+	},
+
+	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");
+		},
+
+	stringify= function(it, level) {
+		if (!level) {
+			text= "";
+			unsolved= false;
+			level= 1;
+		} else {
+			level++;
+		}
+		var temp, space, p, i, newline = bc.newline;
+		switch (typeof it) {
+			case "undefined":
+				text+= "undefined";
+				break;
+
+			case "boolean":
+				text+= (it ? "true" : "false");
+				break;
+
+			case "number":
+				text+= it.toString();
+				break;
+
+			case "string":
+				text+= dojo.toJson(it);
+				break;
+
+			case "object":
+				if (it===null) {
+					text+= "null";
+				} else if (it instanceof RegExp) {
+					text+= RegExp.toString();
+				} else if (it instanceof Array) {
+					if (it.length>1) {
+						text+= "[" + newline;
+						for (i= 0; i<it.length-1; i++) {
+							text+= indent(level);
+							stringify(it[i], level);
+							text+= "," + newline;
+						}
+						text+= indent(level);
+						stringify(it[i], level);
+						text+= newline + indent(level-1) + "]";
+					} else if (it.length) {
+						text+= "[";
+						stringify(it[0], level);
+						text+= "]";
+					} else {
+						text+= "[]";
+					}
+				} else {
+					temp= [];
+					for (p in it) temp.push(p);
+					temp.sort();
+					if (temp.length>1) {
+						text+= "{" + newline;
+						for (i= 0; i<temp.length-1; i++) {
+							text+= indent(level) + propName(temp[i]);
+							stringify(it[temp[i]], level);
+							text+= "," + newline;
+						}
+						text+= indent(level) + propName(temp[i]);
+						stringify(it[temp[i]], level);
+						text+= newline;
+						text+= indent(level-1) + "}";
+					} else if (temp.length) {
+						text+= "{" + propName(temp[0]);
+						stringify(it[temp[0]], level);
+						text+= "}";
+					} else {
+						text+= "{}";
+					}
+				}
+				break;
+
+			case "function":
+				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) {
+					// ignoring lines that have no non-space chars
+					var match= line.match(/(\s*)\S/);
+					if (match) minSpaces= Math.min(minSpaces, match[1].length);
+				});
+				if (minSpaces==Number.MAX_VALUE) {
+					//every line started without any spaces and we never got a match
+					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);
+				break;
+
+			default:
+				text+= "undefined /* unsolved */";
+				unsolved= true;
+		}
+		text.unsolved= unsolved;
+		return text;
+	};
+
+stringify.setIndentFactor= setIndentFactor;
+stringify.split= split;
+return stringify;
+
+});
diff --git a/util/build/transforms/copy.js b/util/build/transforms/copy.js
new file mode 100644
index 0000000..913bda3
--- /dev/null
+++ b/util/build/transforms/copy.js
@@ -0,0 +1,15 @@
+define(["../buildControl", "../process", "../fileUtils", "dojo/has"], function(bc, process, fileUtils, has) {
+	return function(resource, callback) {
+		fileUtils.ensureDirectoryByFilename(resource.dest);
+		var
+			cb= function(code, text){
+				callback(resource, code);
+			},
+			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);
+		return callback;
+	};
+});
diff --git a/util/build/transforms/depsDump.js b/util/build/transforms/depsDump.js
new file mode 100644
index 0000000..b7a8e6d
--- /dev/null
+++ b/util/build/transforms/depsDump.js
@@ -0,0 +1,101 @@
+define([
+	"../buildControl",
+	"../fileUtils",
+	"../fs",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/json"
+], function(bc, fileUtils, fs, lang, array, json){
+	return function(resource, callback){
+		if(!bc.depsDumpDotFilename && !bc.depsDumpFilename){
+			return 0;
+		}
+
+		var dotModules = 0, traceForDot = {}, traceForDotDone = {};
+		if(bc.dotModules){
+			dotModules = {};
+			array.forEach(bc.dotModules.split(","), function(module){
+				dotModules[lang.trim(module)] = traceForDot;
+			});
+		}
+
+		var modules = [],
+			midToId = {},
+			i = 0,
+			dotOutput = "digraph {\n",
+			r, p, destFilename;
+		for(p in bc.resources){
+			r = bc.resources[p];
+			if(r.deps){
+				if(!dotModules || dotModules[r.mid]){
+					dotModules[r.mid] = traceForDotDone;
+					r.deps.forEach(function(module){
+						dotOutput += '"' + r.mid + '" -> "' + module.mid + '";\n';
+						if (dotModules[module.mid]!==traceForDotDone){
+							dotModules[module.mid] = traceForDot;
+						}
+	 				});
+				}
+				r.uid = i;
+				midToId[bc.resources[p].mid] = i;
+				modules.push(r);
+				i++;
+			}
+		}
+
+		if(bc.depsDumpDotFilename){
+			var foundOne = dotModules;
+			while(foundOne){
+				foundOne = false;
+				for(p in bc.resources){
+					r = bc.resources[p];
+					if(dotModules[r.mid]==traceForDot){
+						foundOne = true;
+						dotModules[r.mid] = traceForDotDone;
+						if(r.deps){
+							r.deps.forEach(function(module){
+								dotOutput += '"' + r.mid + '" -> "' + module.mid + '";\n';
+								if (dotModules[module.mid]!==traceForDotDone){
+									dotModules[module.mid] = traceForDot;
+								}
+	 						});
+						}
+					}
+				}
+			}
+			dotOutput += "}\n";
+
+			var filename = fileUtils.computePath(bc.depsDumpDotFilename, bc.destBasePath);
+			fileUtils.ensureDirectory(fileUtils.getFilepath(filename));
+			fs.writeFileSync(filename, dotOutput, "ascii");
+		}
+
+		if(bc.depsDumpFilename){
+			var depsTree = modules.map(function(module){
+					return module.deps.map(function(item){ return item.uid; });
+				}),
+				idTree = {},
+				getItem = function(parts, bag){
+					var part = parts.shift();
+					if(!(part in bag)){
+						bag[part] = {};
+					}
+					if(parts.length){
+						return getItem(parts, bag[part]);
+					}else{
+						return bag[part];
+					}
+				};
+			modules.forEach(function(item, i){
+				var parts = item.mid.split("/");
+				getItem(parts, idTree)["*"] = i;
+			});
+
+			filename = fileUtils.computePath(bc.depsDumpFilename, bc.destBasePath);
+			fileUtils.ensureDirectory(fileUtils.getFilepath(filename));
+			fs.writeFileSync(filename, json.stringify({depsTree:depsTree, idTree:idTree}), "ascii");
+		}
+
+		return 0;
+	};
+});
diff --git a/util/build/transforms/depsScan.js b/util/build/transforms/depsScan.js
new file mode 100644
index 0000000..d43ef72
--- /dev/null
+++ b/util/build/transforms/depsScan.js
@@ -0,0 +1,627 @@
+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
+			mix = function(dest, src){
+				dest = dest || {};
+				for(var p in src){
+					dest[p] = src[p];
+				}
+				return dest;
+			},
+
+			absMid = 0,
+
+			aggregateDeps = [],
+
+			defineApplied = 0,
+
+			simulatedDefine= function(mid, dependencies, factory) {
+				defineApplied = 1;
+				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 (!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);})){
+					throw new Error("define dependency vector contains elements that are not of type string.");
+				}
+
+				absMid = args[0];
+				aggregateDeps= aggregateDeps.concat(args[1]);
+			},
+
+			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);
+				}
+			},
+
+			slashName = function(dottedName){
+				return dottedName.replace(/\./g, "/");
+			},
+
+			pluginStrategyRequired =
+				// truthy if dojo.loadInit|require[After]If|platformRequire detected that cannot be resolved at build-time; falsy otherwise
+				0,
+
+			dojoProvides =
+				// vector of modules dojo.provide'd by the resource
+				[],
+
+			dojoRequires =
+				// vector of modules dojo.require'd by the resource
+				[],
+
+			simulatedDojo =
+				// the dojo legacy loader API
+				{
+					require:function(moduleName, omitModuleCheck) {
+						dojoRequires.push(slashName(moduleName));
+					},
+					provide:function(moduleName) {
+						dojoProvides.push(slashName(moduleName));
+					},
+					requireLocalization: function(moduleName, bundleName, locale) {
+						aggregateDeps.push("dojo/i18n!" + slashName(moduleName) + "/nls/" + (!locale || /root/i.test(locale) ? "" : locale + "/") + slashName(bundleName));
+					},
+					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));
+						});
+					},
+					loadInit:function(callback){
+						pluginStrategyRequired = 1;
+						callback();
+					},
+					requireIf:function(expr, moduleName, omitModuleCheck) {
+						pluginStrategyRequired = 1;
+						expr && dojoRequires.push(slashName(moduleName));
+					},
+					requireAfterIf:function(expr, moduleName, omitModuleCheck) {
+						pluginStrategyRequired = 1;
+						expr && dojoRequires.push(slashName(moduleName));
+					}
+				},
+
+			evaluatorWithNoRuntime =
+				new Function("dojo", "__text", "eval(__text);"),
+
+			applyLegacyCalls = function(callList){
+				var evaluator;
+				if(resource.pack.runtime){
+					// if a runtime is provided, then a special evaluator has to be constructed
+					var runtime = resource.pack.runtime,
+						args = [],
+						params = [],
+						p;
+					runtime.dojo = mix(runtime.dojo, simulatedDojo);
+					for(p in runtime){
+						args.push(runtime[p]);
+						params.push(p);
+					}
+					evaluator = new Function("__bc", "__args", "__text", "(function(" + params.join(",") + "){ eval(__text); }).apply(__bc, __args);");
+					args = [bc, args];
+				}else{
+					args = [simulatedDojo];
+					evaluator = evaluatorWithNoRuntime;
+				}
+
+				// apply the legacy API calls
+				var results = callList.map(function(application){
+					try{
+						evaluator.apply(bc, args.concat(application));
+						return 0;
+					}catch(e){
+						pluginStrategyRequired = 1;
+						return [e, application];
+					}
+				});
+
+				// report the results
+				results.forEach(function(item){
+					if(item){
+						bc.log("legacyFailedEval", ["module", resource.mid, "text", item[0], "error", item[1]]);
+					}
+				});
+			},
+
+			getAmdModule = function(
+				mid,
+				referenceModule
+			) {
+				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];
+					if(!pluginModule){
+						return 0;
+					}else if(!pluginProc){
+						if(!pluginModule.noBuildResolver){
+							bc.log("missingPluginResolver", ["module", resource.mid, "plugin", pluginId]);
+						}
+						return pluginModule;
+					}else{
+						return pluginProc.start(match[2], referenceModule, bc);
+					}
+				} else {
+					var moduleInfo= bc.getSrcModuleInfo(mid, referenceModule),
+						module= moduleInfo && bc.amdResources[moduleInfo.mid];
+					return module;
+				}
+			},
+
+			tagAbsMid = function(){
+				if(absMid && absMid!=resource.mid){
+					bc.log("amdInconsistentMid", ["module", resource.mid, "specified", absMid]);
+				}
+				if(absMid){
+					resource.tag.hasAbsMid = 1;
+				}
+			},
+
+			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 {
+					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) {
+					bc.log("amdFailedEval", ["module", resource.mid, "error", e]);
+				}
+			},
+
+			convertToStrings= function(text){
+				var strings = [],
+
+					// a DFA, the states...
+					spaces = "spaces",
+					string = "string",
+					endOfString = "endOfString",
+					done = "done",
+					error = "error",
+
+					// the machine...
+					dfa = {
+						spaces:function(c){
+							if(/\s/.test(c)){
+								return spaces;
+							}
+							if(c=="'" || c=='"'){
+								quoteType= c;
+								current = "";
+								return string;
+							}
+							if(c==0){
+								return done;
+							}
+							return error;
+						},
+						string:function(c){
+							if(c==quoteType){
+								strings.push(current);
+								return "endOfString";
+							}else{
+								current+= c;
+								return "string";
+							}
+						},
+						endOfString:function(c){
+							if(/\s/.test(c)){
+								return endOfString;
+							}
+							if(c==0){
+								return done;
+							}
+							if(c==","){
+								return spaces;
+							}
+							return error;
+						}
+					},
+
+					state = spaces,
+
+					quoteType, current;
+
+
+				for (var i= 0; i<text.length; i++){
+					state = dfa[state](text.charAt(i));
+					if(state==error){
+						return 0;
+					}
+				}
+				if(dfa[state](0)!=error){
+					return strings;
+				}
+				return 0;
+			},
+
+			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)
+
+				var amdCallCount =
+						// the number of AMD applications found
+						0,
+
+					defineExp=
+						// look for define applications with an optional string first arg and an optional array second arg;
+						// notice the regex stops after the second arg
+						// a test run in the console
+						// test = [
+						//	'define("test")',
+						//	'define("test", ["test1"])',
+						//	'define("test", ["test1", "test2"])',
+						//	'define(["test1"])',
+ 						//	'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
+						/(^|\s)define\s*\(\s*(["'][^'"]+['"])?\s*(,)?\s*(\[[^\]]*?\])?\s*(,)?/g,
+
+					result;
+				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] + "{})";
+								}else if(result[4]){
+									// (mid, <factory:array value>)
+									result = result[0] + ")";
+								}else {
+									// (mid, <factory>)
+									result = result[0] + "{})";
+								}
+							}else{
+								// (<factory:string-value>)
+								result= result[0]  + ")";
+							}
+						}else if(result[4]){
+							// first arg an array
+							if(result[5]){
+								// (deps, <factory>)
+								result = result[0] + "{})";
+							}else{
+								// (<factory:array-value>)
+								result = result[0] + ")";
+							}
+						}else{
+							//just a factory
+							result = "define({})";
+						}
+						amdCallCount++;
+						(new Function("define", result))(simulatedDefine);
+						tagAbsMid();
+					} catch (e) {
+						amdCallCount--;
+						bc.log("amdFailedDefineEval", ["module", resource.mid, "text", result, "error", e]);
+					}
+				}
+
+				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) {
+					var mids = convertToStrings(result[2]);
+					if(mids){
+						amdCallCount++;
+						aggregateDeps= aggregateDeps.concat(mids.filter(function(item){return item.charAt(0)!=".";}));
+					}
+				}
+				return amdCallCount;
+			},
+
+			amdBundle= {},
+
+			syncBundle= {},
+
+			evalNlsResource= function(text){
+				try{
+					(new Function("define", resource.text))(simulatedDefine);
+					if(defineApplied){
+						return amdBundle;
+					}
+				}catch(e){
+				}
+				try{
+					var result= eval("(" + text + ")");
+					if(lang.isObject(result)){
+						return syncBundle;
+					}
+				}catch(e){
+				}
+				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 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*$/, "");
+						}
+
+						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]);
+				}
+			},
+
+			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
+				"(((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(){
+				var getText = function(src){
+						return fs.readFileSync(src, "utf8");
+					},
+					skipping = [],
+					notFound = [],
+					nothing = [];
+
+				resource.text = resource.text.replace(interningGlobalDojoUriRegExp, function(matchString){
+
+					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);
+						return matchString;
+					}
+
+					var textModule = bc.resources[textModuleInfo.url];
+					if(!textModule){
+						notFound.push(textModuleInfo.url);
+						return matchString;
+					}
+
+					// note: it's possible the module is being processed by a set of transforms that don't add a
+					// getText method (e.g., copy); therefore, we provide one for these cases
+					var text = (textModule.getText && textModule.getText()) || getText(textModule.src);
+					if(!text){
+						nothing.push(textModule.src);
+						return matchString;
+					}
+
+					text = json.stringify(text);
+
+					if(matchString.indexOf("dojo.cache") != -1){
+						//Handle dojo.cache-related interning.
+						var endContent = parts[11];
+						if(!endContent){
+							endContent = text;
+						}else{
+							var braceIndex = endContent.indexOf("{");
+							if(braceIndex != -1){
+								endContent = endContent.substring(0, braceIndex + 1)
+									+ 'value: ' + text + ','
+									+ endContent.substring(braceIndex + 1, endContent.length);
+							}
+						}
+						return 'dojo.cache("' + parts[6] + '", "' + parts[9] + '", ' + endContent + ')';
+					}else if(parts[3] == "templatePath"){
+						//Replace templatePaths
+						return "templateString" + parts[4] + text;
+					}else{
+						//Dealing with templateCssPath; not doing this anymore
+						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);
+				}
+				bc.log("internStrings", logArgs);
+			},
+
+			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.
+				//
+				// TODO: replace this process with a parser
+				//
+				// do it the unreliable way; first try to find "dojo.provide" et al since those names are less likely
+				// to be overloaded than "define" and "require"
+				if(bc.internStrings){
+					internStrings();
+				}
+
+				var newline = bc.newline,
+
+					text =
+						// apply any replacements before processing
+						resource.getText(),
+
+					names =
+						bc.scopeNames,
+
+					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
+						// See dojo.js
+						syncLoader.extractLegacyApiApplications(text, removeComments(text));
+				if(!extractResult.extractText && processPossibleAmdWithRegExs(removeComments(text))){
+					// zero legacy calls detected *and* at least one AMD call detected; therefore, assume it's AMD
+					bc.log("amdNotPureContainedNoLegacyApi", ["module", resource.mid]);
+					return;
+				}
+				bc.log("legacyAssumed", ["module", resource.mid]);
+
+				if(!extractResult){
+					// no legacy API calls to worry about; therefore...
+					resource.getText = function(){ return "define(" + json.stringify(names) + ", function(" + names.join(",") + "){" + newline + text + "});" + newline; };
+					return;
+				}
+				// apply the legacy calls in a special environment
+				applyLegacyCalls(extractResult[2]);
+
+				// check for multiple or irrational dojo.provides
+				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) {
+							bc.log("legacyImproperProvide", ["module", resource.mid, "provide", item]);
+						}
+					});
+				}
+
+				if(pluginStrategyRequired){
+					// some loadInit and/or require[After]If and/or platformRequire applications that could not be resolved at build time
+					bc.log("legacyUsingLoadInitPlug", ["module", resource.mid]);
+
+					// construct and start the synthetic plugin resource
+					var pluginText, mid, pluginResource, pluginResourceId;
+					pluginText =
+						"// generated by build app" + newline +
+						"define([], {" + newline +
+						"\tnames:" + json.stringify(names) + "," + newline +
+						"\tdef:function(" + names.join(",") + "){" + newline + extractResult[1] + "}" + newline +
+						"});" + newline;
+					mid = resource.mid + "-loadInit";
+					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},
+						deps:[],
+						getText:function() { return pluginText; }
+					}));
+					bc.start(pluginResource);
+
+					pluginResourceId = "dojo/loadInit!" + mid;
+					aggregateDeps.push(pluginResourceId);
+				}else if(dojoRequires.length){
+					aggregateDeps.push("dojo/require!" + dojoRequires.join(","));
+				}
+				aggregateDeps = names.concat(aggregateDeps);
+				// need to use extractResult[0] since it may delete the dojo.loadInit applications
+				resource.getText = function(){ return "// wrapped by build app" + newline + "define(" + json.stringify(aggregateDeps) + ", function(" + names.join(",") + "){" + newline + extractResult[0] + newline + "});" + newline; };
+			};
+
+		// scan the resource for dependencies
+		if(resource.tag.nls){
+			processNlsBundle();
+		}else if(resource.tag.amd || /\/\/>>\s*pure-amd/.test(resource.text)) {
+			processPureAmdModule();
+		}else{
+			processWithRegExs();
+		}
+
+		// resolve the dependencies into modules
+		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)) {
+						module.forEach(function(module){ deps.push(module); });
+					} else if (module) {
+						deps.push(module);
+					} else {
+						bc.log("amdMissingDependency", ["module", resource.mid, "dependency", dep]);
+					}
+				} catch (e) {
+					bc.log("amdMissingDependency", ["module", resource.mid, "dependency", dep, "error", e]);
+				}
+			}
+		});
+
+	};
+});
diff --git a/util/build/transforms/dojoBoot.js b/util/build/transforms/dojoBoot.js
new file mode 100644
index 0000000..5f7278b
--- /dev/null
+++ b/util/build/transforms/dojoBoot.js
@@ -0,0 +1,8 @@
+(function(){
+	// must use this.require to make this work in node.js
+	var require = this.require;
+	// consume the cached dojo layer
+	require({cache:{}});
+	!require.async && require(["dojo"]);
+	require.boot && require.apply(null, require.boot);
+})();
diff --git a/util/build/transforms/dojoPragmas.js b/util/build/transforms/dojoPragmas.js
new file mode 100644
index 0000000..e0e4261
--- /dev/null
+++ b/util/build/transforms/dojoPragmas.js
@@ -0,0 +1,80 @@
+define(["../buildControl"], function(bc) {
+	var evalPragma= function(code, kwArgs, fileName) {
+			return !!eval("(" + code + ")");
+		};
+
+	return function(resource) {
+		if(!bc.applyDojoPragmas){
+			return;
+		}
+		if(typeof resource.text!="string"){
+			return;
+		}
+
+		var
+			foundIndex = -1,
+			startIndex = 0,
+			text= resource.text;
+		while((foundIndex = text.indexOf("//>>", startIndex)) != -1){
+			//Found a conditional. Get the conditional line.
+			var lineEndIndex = text.indexOf("\n", foundIndex);
+			if(lineEndIndex == -1){
+				lineEndIndex = text.length - 1;
+			}
+
+			//Increment startIndex past the line so the next conditional search can be done.
+			startIndex = lineEndIndex + 1;
+
+			//Break apart the conditional.
+			var conditionLine = text.substring(foundIndex, lineEndIndex + 1);
+			var matches = conditionLine.match(/(exclude|include)Start\s*\(\s*["'](\w+)["']\s*,(.*)\)/);
+			if(matches){
+				var type = matches[1];
+				var marker = matches[2];
+				var condition = matches[3];
+				var isTrue = false;
+				//See if the condition is true.
+				try{
+					isTrue = evalPragma(condition, bc, resource.src);
+				}catch(e){
+					bc.log("dojoPragmaEvalFail", ["module", resource.mid, "expression", conditionLine, "error", e]);
+					return;
+				}
+
+				//Find the endpoint marker.
+				var endRegExp = new RegExp('\\/\\/\\>\\>\\s*' + type + 'End\\(\\s*[\'"]' + marker + '[\'"]\\s*\\)', "g");
+				var endMatches = endRegExp.exec(text.substring(startIndex, text.length));
+				if(endMatches){
+
+					var endMarkerIndex = startIndex + endRegExp.lastIndex - endMatches[0].length;
+
+					//Find the next line return based on the match position.
+					lineEndIndex = text.indexOf("\n", endMarkerIndex);
+					if(lineEndIndex == -1){
+						lineEndIndex = text.length - 1;
+					}
+
+					//Should we include the segment?
+					var shouldInclude = ((type == "exclude" && !isTrue) || (type == "include" && isTrue));
+
+					//Remove the conditional comments, and optionally remove the content inside
+					//the conditional comments.
+					var startLength = startIndex - foundIndex;
+					text = text.substring(0, foundIndex)
+						+ (shouldInclude ? text.substring(startIndex, endMarkerIndex) : "")
+						+ text.substring(lineEndIndex + 1, text.length);
+
+					//Move startIndex to foundIndex, since that is the new position in the file
+					//where we need to look for more conditionals in the next while loop pass.
+					startIndex = foundIndex;
+				}else{
+					bc.log("dojoPragmaInvalid", ["module", resource.mid, "expression", conditionLine]);
+					return;
+				}
+			}else if(/^\/\/>>\s*noBuildResolver\s*$/.test(conditionLine)){
+				resource.noBuildResolver = 1;
+			}
+		}
+		resource.text= text;
+	};
+});
diff --git a/util/build/transforms/dojoReport.js b/util/build/transforms/dojoReport.js
new file mode 100644
index 0000000..f6466a4
--- /dev/null
+++ b/util/build/transforms/dojoReport.js
@@ -0,0 +1,46 @@
+define(["../buildControl", "../version", "../fileUtils"], function(bc, version, fileUtils) {
+	var dir = bc.buildReportDir || ".",
+		filename = bc.buildReportFilename || "build-report.txt";
+
+	return function(resource, callback) {
+		resource.reports.push({
+			dir:dir,
+			filename:filename,
+			content: function(){
+				var result= "";
+
+				result+= "Build started: " + bc.startTimestamp + "\n";
+				result+= "Build application version: " + version + "\n";
+
+				result+= "Messages:\n" + bc.getAllNonreportMessages();
+
+				result+= "Layer Contents:\n";
+				for(var p in bc.resources){
+					resource= bc.resources[p];
+					if(resource.moduleSet){
+						result+= resource.mid + ":\n";
+						var moduleSet= resource.moduleSet;
+						for(var q in moduleSet){
+							result+= "\t" + moduleSet[q].mid + "\n";
+						}
+						result+= "\n";
+					}
+				}
+
+				var optimizerOutput = bc.getOptimizerOutput();
+				if(optimizerOutput.length){
+					result+= "Optimizer Messages:\n" + optimizerOutput;
+				}
+
+				result+= bc.getAllReportMessages();
+
+				bc.log("pacify", "Report written to " + fileUtils.computePath(fileUtils.catPath(dir, filename), bc.destBasePath));
+
+				result+= "\n\nProcess finished normally\n";
+				result+= "\terrors: " + bc.getErrorCount() + "\n\twarnings: " + bc.getWarnCount() + "\n\tbuild time: " + ((new Date()).getTime() - bc.startTimestamp.getTime()) / 1000 + " seconds";
+				return result;
+			}
+		});
+		return 0;
+	};
+});
diff --git a/util/build/transforms/hasFindAll.js b/util/build/transforms/hasFindAll.js
new file mode 100644
index 0000000..626385f
--- /dev/null
+++ b/util/build/transforms/hasFindAll.js
@@ -0,0 +1,19 @@
+define(["../buildControl"], function(bc) {
+	return function(resource) {
+		if (resource.hasTest) {
+			return 0;
+		}
+		var
+			hasFeatures= bc.hasFeatures= bc.hasFeatures || {},
+			text= resource.text,
+			hasRe= /[^\w\.]has\s*\(\s*["']([^"']+)["']\s*\)/g,
+			result;
+		while ((result= hasRe.exec(text)) != null) {
+			var
+				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
new file mode 100644
index 0000000..0804845
--- /dev/null
+++ b/util/build/transforms/hasFixup.js
@@ -0,0 +1,46 @@
+define(["../buildControl"], function(bc) {
+	var
+		mappedNames= 0,
+
+		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();
+		}
+
+		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 + ")";
+			}
+		});
+
+		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 {
+				return match;
+			}
+		});
+
+		resource.text= result;
+
+		return 0;
+	};
+});
diff --git a/util/build/transforms/hasReport.js b/util/build/transforms/hasReport.js
new file mode 100644
index 0000000..5760dd7
--- /dev/null
+++ b/util/build/transforms/hasReport.js
@@ -0,0 +1,28 @@
+define(["../buildControl", "../stringify"], function(bc, stringify) {
+	return function() {
+		if(bc.hasReport){
+			var
+				p,
+				features= bc.hasFeatures,
+				sorted= [];
+			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 sorted= [];
+				for (var p in set) {
+					sorted.push(p);
+				}
+				return sorted.sort();
+			};
+
+			var newline = bc.newline;
+			bc.log("hasReport", sorted.map(function(item) {
+				return "	// " + sort(item[1]).join(", ") + newline + "	 '" + item[0] + "':1";
+			}).join("," + newline + newline));
+		}
+		return 0;
+	};
+});
diff --git a/util/build/transforms/insertSymbols.js b/util/build/transforms/insertSymbols.js
new file mode 100644
index 0000000..a38632b
--- /dev/null
+++ b/util/build/transforms/insertSymbols.js
@@ -0,0 +1,103 @@
+define(["../buildControl", "../fileUtils", "../fs", "../replace"], function(bc, fileUtils, fs, replace) {
+	var symctr = 1,
+		m = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+		len = m.length,
+
+		generateSym = function(name, symtbl){
+			var ret = name; //defaults to long symbol
+			if(bc.symbol === "short"){
+				var s=[], c = symctr;
+				while(c){
+					s.unshift(m[c%len]);
+					c = Math.floor(c/len);
+				}
+				s = "$D" + s.join('');
+				symctr++;
+				symtbl[s + "_"] = name;
+				ret = s + "_";
+			}
+			return ret;
+		},
+
+		convertSym = function(orig_name, symtbl){
+			var name = orig_name.replace(/\./g, "_");
+			if(bc.symbol !== "short" && orig_name === name){
+				if(name === 'define'){
+					//if the function is assigned to a variable named define, use
+					//DEFINE instead to prevent messing up other transform steps
+					name = 'DEFINE';
+				}
+
+				//if the original name does not have dot in it, don't use
+				//the name directly: it will mess up the original logic, such as
+				//in the following case:
+				//		if(some_condition){
+				//			var my_special_func=function(){...};
+				//		}else{
+				//			var my_special_func=function(){...};
+				//		}
+				//if the two anonymous functions are named my_special_func,
+				//no matter what "some_condition" evaluates to, in the built
+				//code, my_special_func will always be equal to the
+				//implementation in the else branch
+				//so we have to append something random to the name
+				return name+"__"+Math.floor(Math.random()*10000);
+			}
+			return generateSym(name, symtbl);
+		},
+
+		insertSymbols = function(resource, symtbl){
+			var content = resource.getText(),
+				prefixes = [],
+				addFunctionName = function(str, p1, p2, p3, p4){
+					return p1+p2+p3+" "+generateSym(prefixes+p2, symtbl)+p4;
+				};
+
+			if(resource.pid){
+				prefixes.push(resource.pid);
+			}
+			if(resource.mid){
+				prefixes.push(resource.mid.replace(/\//g,'_'));
+			}
+			if(!prefixes.length){
+				var m = content.match(/dojo\.provide\("(.*)"\);/);
+				if(m){
+					prefixes.push(m[1].replace(/\./g, "_"));
+				}
+			}
+			if(prefixes.length){
+				prefixes = prefixes.join('_').replace(/\.|\-/g,'_')+"_";
+				content = content.replace(/^(\s*)(\w+)(\s*:\s*function)\s*(\(.*)$/mg, addFunctionName).
+					replace(/^(\s*this\.)(\w+)(\s*=\s*function)\s*(\(.*)$/mg, addFunctionName);
+			}
+			content = content.replace(/^(\s*)([\w\.]+)(\s*=\s*function)\s*(\(.*)/mg,function(str, p1, p2, p3, p4){
+				return p1+p2+p3+" "+convertSym(p2, symtbl)+p4;
+			});
+			return content;
+		};
+
+	return function(resource, callback) {
+		if(bc.symbol){
+			if(resource.tag.report){
+				if(bc.symbol === 'short'){
+					bc.symbolTable = {};
+					resource.reports.push({
+						dir:".",
+						filename:"symboltable.txt",
+						content: function(){
+							var symbolText = [], key, symtbl = bc.symbolTable;
+							for(key in symtbl){
+								symbolText.push(key + ": \"" + symtbl[key] + "\"" + bc.newline);
+							}
+							return symbolText.join('');
+						}
+					});
+				}
+			}else{
+				fileUtils.ensureDirectoryByFilename(resource.dest);
+				resource.text = insertSymbols(resource, bc.symbolTable);
+			}
+		}
+		return 0;
+	};
+});
diff --git a/util/build/transforms/optimizeCss.js b/util/build/transforms/optimizeCss.js
new file mode 100644
index 0000000..acf374d
--- /dev/null
+++ b/util/build/transforms/optimizeCss.js
@@ -0,0 +1,134 @@
+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){
+			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.
+
+			//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) == "\""){
+				url = url.substring(1, url.length - 1);
+			}
+			return url;
+		},
+
+		removeComments = function(text, fileName){
+			var startIndex = -1;
+			//Get rid of comments.
+			while((startIndex = text.indexOf("/*")) != -1){
+				var endIndex = text.indexOf("*/", startIndex + 2);
+				if(endIndex == -1){
+					throw "Improper comment in CSS file: " + fileName;
+				}
+				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.
+
+			text= removeComments(text, fileName);
+
+			// get the path of the reference resource
+			var referencePath = fileUtils.getFilepath(checkSlashes(fileName));
+
+			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;
+				}
+
+				importFileName = cleanCssUrlQuotes(importFileName);
+
+				//Ignore the file import if it is part of an ignore list.
+				if(cssImportIgnore && cssImportIgnore.indexOf(importFileName + ",") != -1){
+					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]);
+					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);
+
+					//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]);
+					}
+					return "url(" + fileUtils.compactPath(urlMatch) + ")";
+				});
+
+				return importContents;
+			});
+		},
+
+		skipped, nonrelative;
+
+
+	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, "}");
+			}
+			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/read.js b/util/build/transforms/read.js
new file mode 100644
index 0000000..a286597
--- /dev/null
+++ b/util/build/transforms/read.js
@@ -0,0 +1,57 @@
+define(["../buildControl", "../fileUtils", "../fs", "../replace"], function(bc, fileUtils, fs, replace) {
+	var
+		getFiletype= fileUtils.getFiletype,
+
+		encodingMap=
+			// map from file type to encoding
+			(bc.transformConfig.read && bc.transformConfig.read.encoding) || {
+				css:"utf8",
+				html:"utf8",
+				htm:"utf8",
+				js:"utf8",
+				json:"utf8",
+				asc:"utf8",
+				c:"utf8",
+				cpp:"utf8",
+				log:"utf8",
+				conf:"utf8",
+				text:"utf8",
+				txt:"utf8",
+				dtd:"utf8",
+				xml:"utf8",
+				png:undefined,
+				jpg:undefined,
+				jpeg:undefined,
+				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 this.text;
+		};
+
+		resource.setText = function(text){
+			resource.text = text;
+			resource.getText = function(){ return this.text; };
+			return text;
+		};
+
+
+		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;
+			}
+			callback(resource, err);
+		});
+		return callback;
+	};
+});
diff --git a/util/build/transforms/report.js b/util/build/transforms/report.js
new file mode 100644
index 0000000..f8aac95
--- /dev/null
+++ b/util/build/transforms/report.js
@@ -0,0 +1,22 @@
+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;
+			if(typeof content=="function"){
+				content= content(bc);
+			};
+			bc.waiting++; // matches *1*
+			fileUtils.ensureDirectory(fileUtils.getFilepath(dest));
+			fs.writeFile(dest, content, "utf8", function(err){
+				if(err){
+					//TODO
+				}
+				bc.passGate(); // matches *1*
+			});
+		});
+		return 0;
+	};
+});
diff --git a/util/build/transforms/trace.js b/util/build/transforms/trace.js
new file mode 100644
index 0000000..645d2e6
--- /dev/null
+++ b/util/build/transforms/trace.js
@@ -0,0 +1,5 @@
+define([], function() {
+	return function(resource) {
+		return 0;
+	};
+});
diff --git a/util/build/transforms/write.js b/util/build/transforms/write.js
new file mode 100644
index 0000000..fc77ead
--- /dev/null
+++ b/util/build/transforms/write.js
@@ -0,0 +1,12 @@
+define(["../buildControl", "../fileUtils", "../fs", "../replace"], function(bc, fileUtils, fs, replace) {
+	return function(resource, callback) {
+		if(resource.tag.noWrite){
+			return 0;
+		}
+		fileUtils.ensureDirectoryByFilename(resource.dest);
+		fs.writeFile(resource.dest, bc.newlineFilter(resource.getText(), resource, "write"), resource.encoding, function(err) {
+			callback(resource, err);
+		});
+		return callback;
+	};
+});
diff --git a/util/build/transforms/writeAmd.js b/util/build/transforms/writeAmd.js
new file mode 100644
index 0000000..b1f7ce2
--- /dev/null
+++ b/util/build/transforms/writeAmd.js
@@ -0,0 +1,343 @@
+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(
+			layerModule,
+			include,
+			exclude
+		) {
+			// add property layerSet (a set of mid) to layerModule that...
+			//
+			//	 * 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]){
+				bc.log("amdCircularDependency", ["module", layerModule.mid]);
+				return {};
+			}
+			computingLayers[layerModule.mid]= 1;
+
+			var
+				includeSet= {},
+				visited,
+				includePhase,
+				traverse= function(module) {
+					var mid= module.mid;
+
+					if (visited[mid]) {
+						return;
+					}
+					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);
+						for(var p in layerModuleSet){
+							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++])){
+						}
+					}
+				};
+
+			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 {
+					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 {
+					traverse(module);
+				}
+			});
+
+			if(layerModule){
+				layerModule.moduleSet= includeSet;
+				delete computingLayers[layerModule.mid];
+			}
+			return includeSet;
+		},
+
+		insertAbsMid = function(
+			text,
+			resource
+		){
+			return (!resource.mid || resource.tag.hasAbsMid || !bc.insertAbsMids) ?
+				text : text.replace(/(define\s*\(\s*)(.*)/, "$1\"" + resource.mid + "\", $2");
+		},
+
+		getCacheEntry = function(
+			pair
+		){
+			return "'" + 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]);
+			}
+			return result;
+		},
+
+		getPreloadLocalizationsRootPath = function(dest){
+			var match= dest.match(/(.+)\/([^\/]+)$/);
+			return match[1] + "/nls/" + match[2];
+		},
+
+		getFlattenedNlsBundles = function(
+			resource,
+			rootBundles,
+			noref
+		){
+			var newline = bc.newline,
+				rootPath = getPreloadLocalizationsRootPath(resource.dest.match(/(.+)(\.js)$/)[1]),
+				result = resource.flattenedNlsBundles = {};
+			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 + "}");
+					});
+				});
+				if(cache.length && noref){
+					cache.push("'*noref':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 : ""];
+			});
+		},
+
+		getLayerText= function(
+			resource,
+			include,
+			exclude,
+			noref
+		) {
+			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);
+				}
+			}
+
+			// construct the cache text
+			if(cache.length && 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;
+		},
+
+		getStrings= function(
+			resource
+		){
+			var cache = [],
+				newline = bc.newline;
+			resource.deps && resource.deps.forEach(function(dep){
+				if(dep.internStrings){
+					cache.push(getCacheEntry(dep.internStrings()));
+				}
+			});
+			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))){
+				return resource.dest + ".uncompressed.js";
+			}else{
+				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);
+					}
+					if(--waitCount==0){
+						callback(rootResource, errors.length && errors);
+					}
+				},
+				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);
+				}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 = 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);
+
+			var copyright;
+			if(resource.pack){
+				copyright= resource.pack.copyrightNonlayers && (resource.pack.copyright || bc.copyright);
+			}else{
+				copyright = bc.copyrightNonlayers &&  bc.copyright;
+			}
+			if(!copyright){
+				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.layer.compat=="1.6"){
+					text= resource.layerText= text + "require(" + json.stringify(resource.layer.include) + ");" + bc.newline;
+				}
+
+				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);
+				}
+			}
+
+			fs.writeFile(getDestFilename(resource), bc.newlineFilter(copyright + "//>>built" + bc.newline + text, resource, "writeAmd"), resource.encoding, onWriteComplete);
+			return callback;
+		};
+		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
new file mode 100644
index 0000000..8146aec
--- /dev/null
+++ b/util/build/transforms/writeCss.js
@@ -0,0 +1,66 @@
+///
+// \amd-mid build/transforms/writeCssResources
+//
+// A function to compact CSS resources.
+//
+//
+define(["../buildControl", "../fileUtils", "../fs"], function(bc, fileUtils, fs) {
+	return function(resource, callback) {
+		var
+			waitCount= 0,
+
+			errors= [],
+
+			onWriteComplete= function(err) {
+				if (err) {
+					errors.push(err);
+				}
+				if (--waitCount==0) {
+					callback(resource, errors.length && errors);
+				}
+			},
+
+			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;
+
+		try {
+			doWrite(resource.dest, resource.text);
+			if (resource.compactDest!=resource.dest) {
+				doWrite(resource.compactDest, resource.compactText);
+			}
+
+			// only need to tranverse bc.destDirToExternSet once...
+			if (wroteExterns) {
+				return callback;
+			}
+			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,
+				dir, resourceSet, src;
+			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) {
+				// can't return the error since there are async processes already going
+				errors.push(e);
+				return 0;
+			} else {
+				return e;
+			}
+		}
+		return callback;
+	};
+});
diff --git a/util/build/transforms/writeDojo.js b/util/build/transforms/writeDojo.js
new file mode 100644
index 0000000..8f48b56
--- /dev/null
+++ b/util/build/transforms/writeDojo.js
@@ -0,0 +1,184 @@
+///
+// \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",
+	"../fs",
+	"../stringify",
+	"./writeAmd",
+	"../process",
+	"dojo/json",
+	"dojo/text!./dojoBoot.js"
+], function(bc, fileUtils, fs, stringify, writeAmd, process, json, dojoBootText) {
+	return function(resource, callback) {
+		var
+			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) {
+					bc.log("configUnresolvedValues");
+				}
+				return result;
+			},
+
+			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--) {
+					 prefix+= (prefix ? "/.." : "..");
+					var check= parts.slice(0, i).join("/") + "/";
+					if (path.indexOf(check)==0) {
+						return prefix + path.substring(check.length-1);
+					}
+				}
+				return path;
+			},
+
+			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= {};
+				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);
+				}
+				var packageDefaultConfig = bc.defaultConfig && bc.defaultConfig.packages && bc.defaultConfig.packages[name];
+				for(var p in packageDefaultConfig){
+					result[p] = packageDefaultConfig[p];
+				}
+				return result;
+			},
+
+			getDefaultConfig= function() {
+				var p, config = {packages:[], hasCache:{}};
+				if (bc.baseUrl) {
+					config.baseUrl= bc.baseUrl;
+				}
+				for (p in bc.packages) {
+					config.packages.push(getPackage(p));
+				}
+				for(p in bc.defaultConfig){
+					if(p!=="packages"){
+						// per-package default config was handled above
+						config[p] = bc.defaultConfig[p];
+					}
+				}
+				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;
+				if(version){
+					//First, break apart the version string.
+					var verSegments = (version+"").match(/^(\d*)\.?(\d*)\.?(\d*)\.?(.*)$/);
+					var majorValue = verSegments[1] || 0;
+					var minorValue = verSegments[2] || 0;
+					var patchValue = verSegments[3] || 0;
+					var flagValue  = verSegments[4] || "";
+					//Do the final version replacement.
+					return text.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 + "\","
+					);
+				}else{
+					return text;
+				}
+			},
+
+			waitCount= 1, // matches *1*
+
+			errors= [],
+
+			onWriteComplete= function(err) {
+				if (err) {
+					errors.push(err);
+				}
+				if (--waitCount==0) {
+					callback(resource, errors.length && errors);
+				}
+			},
+
+			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);
+
+			var
+				// the default application to the loader constructor is replaced with purpose-build user and default config values
+				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),
+
+				// 1.6 compat chunk
+				compat = (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);
+
+			//write any bootstraps; boots is a vector of resources that have been marked as bootable by the discovery process
+			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);
+				}
+			});
+
+			onWriteComplete(0); // matches *1*
+		} catch (e) {
+			if (waitCount) {
+				// can't return the error since there are async processes already going
+				errors.push(e);
+				return 0;
+			} else {
+				return e;
+			}
+		}
+		return callback;
+	};
+});
diff --git a/util/build/transforms/writeOptimized.js b/util/build/transforms/writeOptimized.js
new file mode 100644
index 0000000..3b04029
--- /dev/null
+++ b/util/build/transforms/writeOptimized.js
@@ -0,0 +1,299 @@
+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;
+		};
+	}
+	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);
+		});
+
+		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 = [];
+			}
+		});
+
+		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);
+		}else if(bc.layerOptimize && resource.layer && !resource.layer.discard){
+			return compile(resource, resource.layerText, resource.layer.copyright, bc.layerOptimize, callback);
+		}else{
+			return 0;
+		}
+	};
+});
diff --git a/util/build/v1xProfiles.js b/util/build/v1xProfiles.js
new file mode 100644
index 0000000..07c598d
--- /dev/null
+++ b/util/build/v1xProfiles.js
@@ -0,0 +1,346 @@
+define([
+	"require",
+	"./buildControlBase",
+	"./fs", "./fileUtils",
+	"./process",
+	"dojo"
+], function(require, bc, fs, fileUtils, process, dojo){
+	eval(require.scopeify("./fs, ./fileUtils"));
+	var mix = function(dest, src){
+			dest = dest || {};
+			src = src || {};
+			for(var p in src) dest[p] = src[p];
+			return dest;
+		},
+
+		// any profile properties default values that are different in a 1.6- profile are listed below
+		defaultBuildProps = {
+			// these are computed explicitly in processProfile() below
+			//releaseName:"dojo",
+			//releaseDir:"../../release",
+
+			staticHasFeatures:{
+				// consider turning these hard on for standard 1.x build
+				//'config-publishRequireResult':1,
+				//'config-tlmSiblingOfDojo':1,
+			},
+
+			defaultConfig:{
+				// no changes
+				hasCache:{
+					// no changes
+				}
+			}
+		},
+
+		processProfile = function(profile, dojoPath, utilBuildscriptsPath, profilePath){
+			// process a v1.6- profile
+			//
+			// v1.6- has the following relative path behavior:
+			//
+			//	 * 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.
+			//	 * 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
+			//
+			// 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
+			// that does not report the full path of the script being executed.
+			//
+			var
+				p,
+				result = {},
+				layers = profile.layers || [],
+				prefixes = profile.prefixes || [];
+
+			for(p in defaultBuildProps){
+				result[p] = defaultBuildProps[p];
+			}
+			for(p in profile){
+				if(/^(loader|xdDojoPath|scopeDjConfig|xdScopeArgs|xdDojoScopeName|expandProvide|buildLayers|query|removeDefaultNameSpaces|addGuards)$/.test(p)){
+					bc.log("inputDeprecated", ["switch", p]);
+				}else if(p=="staticHasFeatures"){
+					mix(result.staticHasFeatures, profile.staticHasFeatures);
+				}else if(p=="defaultConfig"){
+					for(p in profile.defaultConfig){
+						if(p=="hasCache"){
+							mix(result.defaultConfig.hasCache, profile.defaultConfig.hasCache);
+						}else{
+							result.defaultConfig[p] = profile.defaultConfig[p];
+						}
+					}
+				}else{
+					// this is gross, but it's in the v1.6 app...and it's used in some of our own profiles as of [26706]
+					result[p] = (profile[p]=="false" ? false : profile[p]);
+				}
+			}
+
+			// convert the prefix vector to a map
+			var prefixMap =
+					// map from top-level mid --> path
+					{},
+				copyrightMap =
+					// map from top-level mid --> copyright message (usually undefined)
+					{},
+				runtimeMap =
+					// map from top-level mid --> runtime environment for computing depenencies in transforms/depsScan (usually undefined)
+					{};
+			prefixes.forEach(function(pair){
+				// pair a [mid, path], mid, a top-level module id, path relative to dojo directory
+				var mid = pair[0];
+				prefixMap[mid]= pair[1];
+				// copyright is relaxed in 1.7+: it can be a string or a filename
+				copyrightMap[mid] = (pair[2] && (maybeRead(computePath(pair[2], utilBuildscriptsPath)) || maybeRead(computePath(pair[2], profilePath)) || pair[2])) || "";
+				runtimeMap[mid] = pair[3];
+			});
+
+			// make sure we have a dojo path; notice we default to the dojo being used to run the build program as per the v1.6- build system
+			// the only place basePath is used when processing a v1.6- profile is to compute releaseDir when releaseDir is relative
+			// in this case, basePath in v1.6- is always assumed to be /util/buildscripts
+			var basePath = result.basePath = utilBuildscriptsPath;
+
+			if(!prefixMap.dojo){
+				prefixMap.dojo = dojoPath;
+			}
+			// make sure it is absolute
+			prefixMap.dojo = computePath(prefixMap.dojo, basePath);
+			if(prefixMap.dojo!=dojoPath){
+				bc.log("buildUsingDifferentDojo");
+			}
+			dojoPath = prefixMap.dojo;
+
+			// now we can compute an absolute path for each prefix (top-level module)
+			// (recall , in v1.6-, relative prefix paths are relative to the dojo path because of "flattening"
+			for(var mid in prefixMap){
+				if(mid!="dojo"){
+					prefixMap[mid] = computePath(prefixMap[mid], dojoPath);
+				}
+			}
+
+			// now fixup and make absolute the releaseDir; releaseDir, if relative, is relative to /util/buildscripts
+			// by making it absolute, later profiles can change basePath without affecting releaseDir
+			result.releaseDir = computePath((profile.releaseDir || "../../release").replace(/\\/g, "/"), basePath);
+
+			// make sure releaseName is clean
+			if(typeof profile.releaseName == "undefined"){
+				profile.releaseName = "dojo";
+			}
+			if(!profile.releaseName){
+				profile.releaseName = "";
+			}
+
+			result.releaseName = profile.releaseName.replace(/\\/g, "/");
+
+			// now make a package for each top-level module
+			var packages = result.packages = [];
+			for(mid in prefixMap){
+				packages.push({
+					name:mid,
+					location:prefixMap[mid],
+					copyright:copyrightMap[mid]!==undefined ? copyrightMap[mid] : bc.defaultCopyright,
+					runtime:runtimeMap[mid]
+				});
+			}
+
+			// recall the v1.6- build system "flattens" the module structure, no matter how it is arranged on input, into a set of sibling
+			// top-level modules (dojo, dijit, dojox, demos, myStuff, yourStuff, etc.). The layer.name property is just a filename. Theoretically,
+			// it could be placed anywhere, but in practice, it's always places somewhere in this flattened forest of module trees by giving
+			// a name like "../myTopLevelModule/someModule.js". Therefore, the intendeded module name can be deduced by chopping off the "../"
+			// prefix and ".js" suffix. Again, in theory, this won't work 100% of the time, but we don't have any examples of it not working. This
+			// technique also works for layerDependencies. Therefore, transform a v1.6 layer object into a v1.7 layer object
+			var getLayerCopyrightMessage = function(explicit, mid){
+					// this is a bit obnoxious as a default, but it's the v1.6- behavior
+					// TODO: consider changing
+					if(explicit!==undefined){
+						return explicit;
+					}
+					var copyright = copyrightMap[mid.split('/',1)[0]];
+					if(copyright){
+						return copyright;
+					}else{
+						return bc.defaultCopyright + bc.defaultBuildNotice;
+					}
+				},
+
+				transformDependencies = function(list){
+					return list ? list.map(function(mid){
+						modulesSeen[mid = mid.replace(/\./g, "/")] = 1;
+						return mid;
+					}) : [];
+				},
+
+				transformLayerDependencies = function(list, layerName){
+					return list ? list.map(function(mid){
+						if(!/\//.test(mid) && !/\.js$/.test(mid)){
+							// not a slash and doesn't end in .js; therefore, must be a module name
+							modulesSeen[mid.split(".")[0]] = 1;
+							return mid;
+						}
+						var match;
+						if(/^\.\//.test(mid)){
+							mid = mid.substring(2);
+						}
+						if(mid=="dojo/dojo"){
+							return mid;
+						}else if(mid=="dojo.js"){
+							return "dojo/dojo";
+						}else if((match = mid.match(nameRe))){
+							// sibling of dojo
+							modulesSeen[match[1]] = 1;
+							return match[1];
+						}else if((match = mid.match(dojoModuleRe))){
+							// assuming a dojo module
+							bc.log("assumeLayerDependencyIsDojoModule", ["layer dependency", mid]);
+							return match[1];
+						}else{
+							bc.log("cannotDeduceModuleIdFrom16LayerDependency", ["layer name", layerName, "layer dependency name", mid]);
+							return "error";
+						}
+					}) : [];
+				},
+
+				nameRe = /^\.\.\/([^\.].*)\.js$/,
+
+				dojoModuleRe = /^([^\.].*)\.js$/,
+
+				modulesSeen = {},
+
+				fixedLayers = {};
+			layers.forEach(function(layer){
+				var match, name;
+				if(layer.resourceName){
+					name = layer.resourceName.replace(/\./g, "/");
+				}else{
+					name = layer.name;
+					if(/^\.\//.test(name)){
+						name = name.substring(2);
+					}
+					if(layer.name=="dojo.js"){
+						// custom base
+						name = "dojo/dojo";
+						if(!layer.customBase){
+							layer.dependencies.push("dojo/main");
+						}
+						layer.boot = true;
+					}else if((match = name.match(nameRe))){
+						// sibling of dojo
+						name = match[1];
+					}else if((match = name.match(dojoModuleRe))){
+						// hopefully a dojo module
+						name = "dojo/" + match[1];
+						bc.log("assumeLayerIsDojoModule", ["layer name", layer.name]);
+					}else{
+						bc.log("cannotDeduceModuleIdFrom16LayerName", ["layer name", layer.name]);
+					}
+				}
+				layer.include = transformDependencies(layer.dependencies);
+				layer.exclude = transformLayerDependencies(layer.layerDependencies, layer.name);
+				if(name!="dojo/dojo" && !layer.customBase){
+					layer.exclude.push("dojo/dojo");
+				}
+				layer.name = name;
+				modulesSeen[name.split("/")[0]] = 1;
+				layer.copyright = getLayerCopyrightMessage(layer.copyright, name);
+				fixedLayers[name] = layer;
+			});
+
+			// lastly, check that all the top-level module seen were in the prefixes vector
+			for(p in modulesSeen){
+				var tlm = p.split("/")[0];
+				if(!prefixMap[tlm]){
+					bc.log("missingPrefix", ["top-level module", tlm]);
+				}
+			}
+			result.layers = fixedLayers;
+
+			return result;
+		},
+
+		processHtmlFiles = function(files, dojoPath, utilBuildscriptsPath){
+			bc.log("processHtmlFiles", ["files", files.join(", ")]);
+			var
+				basePath = "",
+				layers = {},
+				prefix = "",
+				prefixes = {dijit: true, dojox: true};
+			files.forEach(function(htmlFile){
+				var
+					priorLayers = [],
+					addLayer = function(scriptName){
+						if(layers[scriptName]){
+						// if this module has been added before, find the intersection of dependencies
+							layers[scriptName] = layers[scriptName].filter(function(scriptName){
+								return priorLayers.indexOf(scriptName) > -1;
+							});
+						}else{
+							layers[scriptName] = priorLayers.concat();
+						}
+						if(scriptName.indexOf('.') > -1){
+							prefixes[scriptName.substring(scriptName, scriptName.indexOf('.'))] = true;
+						}
+						priorLayers.push(scriptName);
+					};
+
+				var html = fs.readFileSync(htmlFile, "utf8");
+				html.replace(/<script [^>]*src=["']([^'"]+)["']/gi, function(t, scriptName){
+					// for each script tag
+					if(scriptName.indexOf("dojo/dojo.js") > -1){
+						// use dojo.js to determine the prefix for our namespaces
+						prefix = scriptName.substring(0, scriptName.indexOf("dojo/dojo.js"));
+
+						// the release dir is relative to the dir that contains the html file(s)
+						// the prefix, if relative, is relative to basePath
+						if(!basePath){
+							basePath = fileUtils.getFilepath(htmlFile);
+						}
+					}else{
+						// non-dojo.js script files, add it to our list of layers
+						addLayer(scriptName = scriptName.substring(prefix.length, scriptName.length - 3).replace(/\//g, '.'));
+					}
+				});
+				html.replace(/dojo\.require\(["']([^'"]+)["']\)/g, function(t, scriptName){
+					// for each dojo.require call add it to the layers as well
+					addLayer(scriptName);
+				});
+			});
+
+			var prefixPaths = [];
+			// normalize the prefixes into the arrays that the build expects
+			for(prefix in prefixes){
+				prefixPaths.push([prefix, "../" + prefix]);
+			}
+			var layersArray = [];
+			for(var name in layers){
+				// for each layer, create a layer object
+				layersArray.push({
+					name: "../" + name.replace(/\./g,'/') + ".js", // use filename
+					dependencies: [
+						name.replace(/\//g,'.') // use module name
+					],
+					//use all previous layers as layer dependencies
+					layerDependencies: layers[name].map(function(name){
+						return "../" + name.replace(/\./g,'/') + ".js";
+					})
+				});
+			}
+			var profileProperties = {
+				layers: layersArray,
+				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);
+		};
+
+	return {
+		processProfile:processProfile,
+		processHtmlFiles:processHtmlFiles
+	};
+});
diff --git a/util/build/version.js b/util/build/version.js
new file mode 100644
index 0000000..73e8dcd
--- /dev/null
+++ b/util/build/version.js
@@ -0,0 +1,13 @@
+define([], function(){
+	var
+		rev = "$Rev: 23930 $".match(/\d+/),
+		version= {
+			major: 1, minor: 7, patch: 0, flag: "dev",
+			revision: rev ? +rev[0] : NaN,
+			toString: function(){
+				var v= version;
+				return v.major + "." + v.minor + "." + v.patch + v.flag + " (" + v.revision + ")";
+			}
+		};
+	return version;
+});
diff --git a/util/buildscripts/build.bat b/util/buildscripts/build.bat
index 9e00b95..fa38e58 100644
--- a/util/buildscripts/build.bat
+++ b/util/buildscripts/build.bat
@@ -1,3 +1,12 @@
-java -classpath ../shrinksafe/js.jar;../shrinksafe/shrinksafe.jar org.mozilla.javascript.tools.shell.Main build.js %*
+ at rem set NODE_HOME=C:\Users\IBM_ADMIN\Downloads\node
+ at rem set PATH=%NODE_HOME%;%PATH%
+ at rem Something like this will be required for cygwin... node is not 100% confirmed working at this point
+ at 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 %*
+
+
+ at rem java -classpath ../shrinksafe/js.jar;../shrinksafe/shrinksafe.jar org.mozilla.javascript.tools.shell.Main build.js %*
 
 @rem java -Xms256m -Xmx256m -classpath ../shrinksafe/js.jar;../shrinksafe/shrinksafe.jar org.mozilla.javascript.tools.shell.Main  build.js %*
diff --git a/util/buildscripts/build.sh b/util/buildscripts/build.sh
index bacfe03..9b9bfb6 100755
--- a/util/buildscripts/build.sh
+++ b/util/buildscripts/build.sh
@@ -1,6 +1,105 @@
 #!/bin/sh
+usage() {
+cat <<-__EOF__;
+NAME
+     build.sh - a convenience wrapper around the Dojo Build Application
 
-java -classpath ../shrinksafe/js.jar:../shrinksafe/shrinksafe.jar org.mozilla.javascript.tools.shell.Main build.js "$@"
+SYNOPSIS
+     path/to/build.sh [--help] [--bin environment] [build system options]
 
-# if you experience an "Out of Memory" error, you can increase it as follows:
-#java -Xms256m -Xmx256m -classpath ../shrinksafe/js.jar:../shrinksafe/shrinksafe.jar org.mozilla.javascript.tools.shell.Main  build.js "$@"
+DESCRIPTION
+     build.sh is a shell script that wraps the Dojo Build Application located at /util/build/main.js
+     to simplify executing the application in various, selectable, Javascript environments. Currently
+     both node.js and Java are supported.
+
+OPTIONS
+     --help     print the help message
+     
+     --bin      environment
+                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
+                java             use java
+     
+     Note: the alternative syntax bin=option is supported but deprecated.
+
+__EOF__
+}
+
+if [ "$#" = "0" ]; then
+ usage
+fi
+
+while [ -n "$1" ]
+do
+	arg="$1"
+    case $arg in
+    --help)
+        usage
+        ba="$ba $arg"
+        ;;
+    bin=node)
+        use_node=0
+        ;;
+    bin=node-debug)
+        use_node=0
+        debug_node="--debug"
+		;;
+    bin=node-debug-brk)
+        use_node=0
+        debug_node="--debug-brk"
+        ;;
+    bin=java)
+        use_node=1
+        ;;
+    bin=*)
+        echo "Invalid bin= option: only node/java is supported"
+        exit 1
+        ;;
+    *)
+		if [ "$arg" = "--bin" ]; then
+			case $2 in
+			node)
+				use_node=0
+				;;
+			node-debug)
+				use_node=0
+				debug_node="--debug"
+				;;
+			node-debug-brk)
+				use_node=0
+				debug_node="--debug-brk"
+				;;
+			java)
+				use_node=1
+				;;
+			*)
+		        echo "Invalid --bin option: only node/java is supported"
+				exit 1
+		        ;;
+			esac
+			shift
+		else
+	        ba="$ba $arg"
+		fi
+        ;;
+    esac
+    shift
+done
+
+if [ -z "$use_node" ]; then
+    which node > /dev/null 2>&1
+    use_node=$?
+fi
+
+if [ "$use_node" = "0" ]; then
+    cmd="node $debug_node"
+    cmdflags="`dirname $0`/../../dojo/dojo.js"
+else
+    cmd="java"
+    cmdflags="-Xms256m -Xmx256m -cp `dirname $0`/../shrinksafe/js.jar:`dirname $0`/../closureCompiler/compiler.jar:`dirname $0`/../shrinksafe/shrinksafe.jar org.mozilla.javascript.tools.shell.Main  `dirname $0`/../../dojo/dojo.js baseUrl=`dirname $0`/../../dojo"
+fi
+
+$cmd $cmdflags load=build $ba
diff --git a/util/buildscripts/build_release.sh b/util/buildscripts/build_release.sh
index 5d7d2bf..fc45f57 100755
--- a/util/buildscripts/build_release.sh
+++ b/util/buildscripts/build_release.sh
@@ -7,9 +7,9 @@ svnUserName=$2
 #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 he repo.
+#If no svnRevision number, get the latest one from the repo.
 if [ "$svnRevision" = "" ]; then
-	svnRevision=`svn info http://svn.dojotoolkit.org/src/util/trunk/buildscripts/build_release.sh | grep Revision | sed 's/Revision: //'`
+	svnRevision=`svn info http://svn.dojotoolkit.org/src/branches/1.7/util/buildscripts/build_release.sh | grep Revision | sed 's/Revision: //'`
 fi
 
 tagName=release-$version
@@ -20,11 +20,11 @@ read -p "If you mean to create a tag for Dojo $version from r$svnRevision ... pr
 
 #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.6/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.6/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.6/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.6/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.6/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.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."
 
 #Check out the tag
 mkdir ../../build
@@ -33,9 +33,16 @@ 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/_loader/bootstrap.js
+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
 cd ../../dojo
-svn commit -m "Updating dojo version for the tag. \!strict" _base/_loader/bootstrap.js
+svn commit -m "Updating dojo version for the tag. \!strict" package.json _base/kernel.js
+cd ../dijit
+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.
 cd ../..
@@ -76,7 +83,7 @@ mv $srcName $buildName
 #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 
+./build.sh profile=standard version=$1 releaseName=$buildName cssOptimize=comments.keepLines optimize=shrinksafe.keepLines action=release insertAbsMids=1
 # remove tests and demos, but only for the actual release:
 chmod +x ./clean_release.sh
 ./clean_release.sh ../../release $buildName
@@ -103,7 +110,7 @@ tar -xzvf $srcName.tar.gz
 cd $srcName/util/buildscripts/
 
 # build the version that will be extracted and live on downloads.dojotoolkit.org (with tests)
-./build.sh action=release version=$1 profile=standard cssOptimize=comments.keepLines releaseName=$buildName copyTests=true mini=false
+./build.sh action=release version=$1 profile=standard cssOptimize=comments.keepLines releaseName=$buildName copyTests=true mini=false insertAbsMids=1
 
 # cleanup the -src extraction, moving the newly built tree into place. 
 cd ../../release
@@ -114,7 +121,7 @@ rm -rf release/
 # generate api.xml and api.json
 cd util/docscripts/
 php -q generate.php
-mv api.* ../../../../build/
+mv cache/api.* ../../../../build/
 cd ../../../../
 
 # make a folder structure appropriate for directly extracting on downloads.dojotoolkit.org
@@ -123,15 +130,20 @@ rm -rf release-$1/$srcName/
 cd release-$1
 
 # md5sum the release files -- OSX doesn't have md5sum, foundation servers don't have md5
-if [ -e `which md5` ]; then
-	md5=`which md5`
-elif [ -e `which md5sum` ]; then
+md5=`which md5`
+if [[ -n $md5 && -x $md5 ]]; then
+	echo "Found $md5";
+else
 	md5=`which md5sum`
 fi
 
-for i in *.zip; do $md5 $i > $i.md5; done
-for i in *.gz; do $md5 $i > $i.md5; done
-for i in *.js; do $md5 $i > $i.md5; done
+if [[ -n $md5 && -x $md5 ]]; then
+	for i in *.zip; do $md5 $i > $i.md5; done
+	for i in *.gz; do $md5 $i > $i.md5; done
+	for i in *.js; do $md5 $i > $i.md5; done
+else
+	echo "ERROR: Failed to generate md5 checksums" 
+fi
 
 # pack up the whole thing for easy copying
 cd ..
@@ -140,7 +152,7 @@ tar -czvf dj-$1-dtk.tar.gz release-$1
 #Finished.
 outDirName=`pwd`
 echo "Build complete. Files are in: $outDirName"
-echo "A copy/paste command to push files to downloads.dojotoolkit.org with permission:"
-echo "scp dj-$1-dtk.tar.gz download.dojotoolkit.org:/srv/www/vhosts/download.dojotoolkit.org"
+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 9e0f946..23ace95 100755
--- a/util/buildscripts/cdnBuild.sh
+++ b/util/buildscripts/cdnBuild.sh
@@ -12,9 +12,9 @@ if [ -z $version ]; then
 fi
 
 dobuild() {
-	java -classpath ../shrinksafe/js.jar:../shrinksafe/shrinksafe.jar org.mozilla.javascript.tools.shell.Main build.js profile=standard releaseName=$1 cssOptimize=comments.keepLines optimize=shrinksafe stripConsole=normal loader=xdomain xdDojoPath=$3 version=$1 copyTests=false mini=true action=release xdDojoScopeName=window[\(typeof\(djConfig\)\!\=\"undefined\"\&\&djConfig.scopeMap\&\&djConfig.scopeMap[0][1]\)\|\|\"dojo\"]
-	mv ../../release/$1 ../../release/$1-cdn/$2
-	cd ../../release/$1-cdn/$2
+	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
+	mv ../../release/$1 ../../release/$1-cdn
+	cd ../../release/$1-cdn
 	zip -rq $1.zip $1/*
 	sha1sum $1.zip > sha1.txt
 	cd $1
@@ -24,16 +24,12 @@ dobuild() {
 
 # Generate locale info
 cd cldr
+ant clean  # necessary until cldr scripts can handle existing AMD files
 ant
 cd ..
 
 # Setup release area
-mkdir ../../release
-mkdir ../../release/$version-cdn
-mkdir ../../release/$version-cdn/google
-mkdir ../../release/$version-cdn/aol
+mkdir -p ../../release/$version-cdn
 
 # Google build
-dobuild $version "google" "http://ajax.googleapis.com/ajax/libs/dojo/$version"
-# AOL build
-dobuild $version "aol" "http://o.aolcdn.com/dojo/$version"
+dobuild $version
diff --git a/util/buildscripts/changeVersion.js b/util/buildscripts/changeVersion.js
index 38058de..36e6848 100644
--- a/util/buildscripts/changeVersion.js
+++ b/util/buildscripts/changeVersion.js
@@ -1,13 +1,54 @@
 //Changes the Dojo version in a file. Used during the release process.
 
-var version = new String(arguments[0]);
-var fileName = new String(arguments[1]);
+var
+	version = new String(arguments[0]),
 
-load("jslib/logger.js");
-load("jslib/fileUtil.js");
-load("jslib/buildUtil.js");
+	filename = new String(arguments[1]),
 
-var fileContents = fileUtil.readFile(fileName);
-fileContents = buildUtil.changeVersion(version, fileContents);
+	writeFile= function(filename, contents){
+		var
+			outFile = new java.io.File(filename),
+			outWriter;
+		outWriter = new java.io.OutputStreamWriter(new java.io.FileOutputStream(outFile), "UTF-8");
+		var os = new java.io.BufferedWriter(outWriter);
+		try{
+			os.write(contents);
+		}finally{
+			os.close();
+		}
+	},
 
-fileUtil.saveUtf8File(fileName, fileContents);
\ No newline at end of file
+
+	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.
+
+		//Set version number.
+		//First, break apart the version string.
+		var verSegments = version.match(/^(\d*)\.?(\d*)\.?(\d*)\.?(.*)$/);
+		var majorValue = verSegments[1] || 0;
+		var minorValue = verSegments[2] || 0;
+		var patchValue = verSegments[3] || 0;
+		var flagValue  = verSegments[4] || "";
+
+		//Do the final version replacement.
+		if(/package/.test(filename)){
+			fileContents = fileContents.replace(
+				/['"]version['"]\s*\:\s*['"][\w\.\-]+?["']/,
+				'"version":"' + 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 + "\","
+			);
+		}
+
+		return fileContents; //String
+	};
+
+print(version);
+print(filename);
+var fileContents = readFile(filename, "utf-8");
+fileContents = changeVersion(version, fileContents);
+writeFile(filename, fileContents);
\ No newline at end of file
diff --git a/util/buildscripts/cldr/alias.js b/util/buildscripts/cldr/alias.js
index 2f2a6b4..21f663d 100644
--- a/util/buildscripts/cldr/alias.js
+++ b/util/buildscripts/cldr/alias.js
@@ -45,17 +45,17 @@ for(var i = 0; i < BUNDLES.length; i++){
 		var locale = jsFilePath[jsFilePath.length-2];
 		if(locale=="nls"){continue;} // no need for root bundle
 		try{
-			dojo.i18n._requireLocalization('dojo.cldr', BUNDLES[i], locale); //declare bundle
+//			dojo.i18n._requireLocalization('dojo.cldr', BUNDLES[i], locale); //declare bundle
 			var bundle = dojo.i18n.getLocalization('dojo.cldr', BUNDLES[i], locale); //get bundle
 			var nativeSrcBundle = getNativeBundle(jsFileName);//bundle not flattened
-		}catch(e){print(e);/* simply ignore if no bundle found*/}
+		}catch(e){/*logStr += "alias: an exception occurred: "+e;/* simply ignore if no bundle found*/}
 		
 		if(!bundle) continue;
 		
 		updated = false;
 		//logStr += locale + ":" + BUNDLES[i] + "=========================================================================\n";
 		
-		_calculateAliasPath(bundle);
+		_calculateAliasPath(bundle, BUNDLES[i]);
 		//logStr += "all alias paths=" + dojo.toJson(localeAliasPaths) + "\n";
 				
 		_processLocaleAlias(localeAliasPaths, bundle, nativeSrcBundle,locale);
@@ -72,7 +72,7 @@ for(var i = 0; i < BUNDLES.length; i++){
 //print('CLDR finished, please refer to logs at ' + logDir + ' for more details.');
 
 
-function _calculateAliasPath(bundle){
+function _calculateAliasPath(bundle, name/*String*/){
 	for(p in bundle){
 		var index = p.indexOf(LOCALE_ALIAS_MARK);
 		if(index >= 0 /*p like 'xxx at localeAlias6'*/){
@@ -94,6 +94,8 @@ function _calculateAliasPath(bundle){
 				mapping[LOCALE_ALIAS_SOURCE_PROPERTY] = src;
 				mapping[LOCALE_ALIAS_TARGET_PROPERTY] = bundle[localeAliasSource + LOCALE_ALIAS_MARK + i][LOCALE_ALIAS_TARGET_PROPERTY];
 				mapping[LOCALE_ALIAS_TARGET_BUNDLE] = bundle[localeAliasSource + LOCALE_ALIAS_MARK + i][LOCALE_ALIAS_TARGET_BUNDLE];
+				//whether aliased to the bundle itself
+				mapping.inSelf = mapping[LOCALE_ALIAS_TARGET_BUNDLE] === name;
 				path.push(mapping);
 				records[src] = true;
 				src = bundle[localeAliasSource + LOCALE_ALIAS_MARK + i][LOCALE_ALIAS_TARGET_PROPERTY];
@@ -117,7 +119,7 @@ function _processLocaleAlias(localeAliasPaths/*Array*/, bundle/*JSON Obj*/, nati
 		var path = localeAliasPaths[i];
 		for(var j = 0; j < path.length; j++){
 			var mapping = path[j];
-			if(mapping[LOCALE_ALIAS_SOURCE_PROPERTY] != mapping[LOCALE_ALIAS_TARGET_PROPERTY]
+			if(mapping.inSelf && mapping[LOCALE_ALIAS_SOURCE_PROPERTY] != mapping[LOCALE_ALIAS_TARGET_PROPERTY]
 			   && bundle[mapping[LOCALE_ALIAS_TARGET_PROPERTY]]/*target existed*/){
 				//e.g. {'source':'months-format-abbr','target':"months-format-wide",'bundle':"gregorian"},
 				//currently source and target bundles are the same - gregorian
@@ -128,7 +130,7 @@ function _processLocaleAlias(localeAliasPaths/*Array*/, bundle/*JSON Obj*/, nati
 				_updateLocaleAlias(bundle, mapping[LOCALE_ALIAS_SOURCE_PROPERTY], bundle,
 								   mapping[LOCALE_ALIAS_TARGET_PROPERTY], nativeSrcBundle);
 				processed[mapping[LOCALE_ALIAS_SOURCE_PROPERTY]] =  true;
-			}else{
+			}else if(!mapping.inSelf){
 				//For other non-gregorian calendars. e.g. "hebrew" etc.
 				//Get the bundle according to the locale.
 				var targetBundle = dojo.i18n.getLocalization('dojo.cldr', mapping[LOCALE_ALIAS_TARGET_BUNDLE], locale);
diff --git a/util/buildscripts/cldr/arrayInherit.js b/util/buildscripts/cldr/arrayInherit.js
index 1b17aa6..b1ed693 100644
--- a/util/buildscripts/cldr/arrayInherit.js
+++ b/util/buildscripts/cldr/arrayInherit.js
@@ -40,11 +40,34 @@ djConfig={baseUrl: "../../../dojo/"};
 load("../../../dojo/dojo.js");
 load("../jslib/logger.js");
 load("../jslib/fileUtil.js");
-load("../jslib/buildUtil.js");
 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".                                                         
+
+    locale = dojo.i18n.normalizeLocale(locale);
+
+    var elements = locale.split('-');
+    var searchlist = [];
+    for(var i = elements.length; i > 0; i--){
+	searchlist.push(elements.slice(0, i).join('-'));
+    }
+    searchlist.push(false);
+    if(down){searchlist.reverse();}
+
+    for(var j = searchlist.length - 1; j >= 0; j--){
+	var loc = searchlist[j] || "ROOT";
+	var stop = searchFunc(loc);
+	if(stop){ break; }
+    }
+};
+
 var dir = arguments[0];
 var logDir = arguments[1];
 var logStr = "";
@@ -65,11 +88,11 @@ for(var i= 0; i < fileList.length; i++){
 	var hasChanged = false;
 	
 	try{
-		dojo.i18n._requireLocalization('dojo.cldr', 'gregorian', locale);
+//		dojo.i18n._requireLocalization('dojo.cldr', 'gregorian', locale);
 		var bundle = dojo.i18n.getLocalization('dojo.cldr', 'gregorian', locale); //flattened bundle
-	}catch(e){print(e);/* simply ignore if no bundle found*/}
+	}catch(e){/* logStr += "arrayInherit: an exception occurred: "+e;/* simply ignore if no bundle found*/}
 	
-	dojo.i18n._searchLocalePath(locale, true, function(variant){
+	_searchLocalePath(locale, true, function(variant){
 		var isComplete = false;
 		var path = jsPath;
 		if(variant=="ROOT"){
diff --git a/util/buildscripts/cldr/cldrUtil.js b/util/buildscripts/cldr/cldrUtil.js
index 4bb2f35..66357cd 100644
--- a/util/buildscripts/cldr/cldrUtil.js
+++ b/util/buildscripts/cldr/cldrUtil.js
@@ -1,3 +1,8 @@
+// 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;
diff --git a/util/buildscripts/cldr/ldml/core.zip b/util/buildscripts/cldr/ldml/core.zip
index 6a4988f..402537c 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/specialLocale.js b/util/buildscripts/cldr/specialLocale.js
index 8157a2c..c918723 100644
--- a/util/buildscripts/cldr/specialLocale.js
+++ b/util/buildscripts/cldr/specialLocale.js
@@ -129,13 +129,13 @@ for(var i= 0; i < srcLocaleList.length; i++){
 	for(var len = 0; len < BUNDLE_MAP.length; len++){
 		try{
 			//declare bundles
-			dojo.i18n._requireLocalization('dojo.cldr', BUNDLE_MAP[len], srcLocale);
-			dojo.i18n._requireLocalization('dojo.cldr', BUNDLE_MAP[len], aliasLocale);
+//			dojo.i18n._requireLocalization('dojo.cldr', BUNDLE_MAP[len], srcLocale);
+//			dojo.i18n._requireLocalization('dojo.cldr', BUNDLE_MAP[len], aliasLocale);
 						
 			//get bundles
 			var srcBundle = dojo.i18n.getLocalization('dojo.cldr', BUNDLE_MAP[len], srcLocale);
 			var aliasBundle = dojo.i18n.getLocalization('dojo.cldr', BUNDLE_MAP[len], aliasLocale);
-		}catch(e){print(e);/*it's ok if no bundle found*/}
+		}catch(e){/* logStr+="specialLocale: an exception occurred: "+e; /* it's ok if no bundle found*/}
 		
 		if(!aliasBundle && !srcBundle){
 			break;
diff --git a/util/buildscripts/jslib/buildUtil.js b/util/buildscripts/jslib/buildUtil.js
deleted file mode 100644
index 264e75c..0000000
--- a/util/buildscripts/jslib/buildUtil.js
+++ /dev/null
@@ -1,2125 +0,0 @@
-var buildUtil = {};
-
-//Default build options.
-buildUtil.DojoBuildOptions = {
-	"profile": {
-		defaultValue: "base",
-		helpText: "The name of the profile to use for the build. It must be the first part of "
-			+ "the profile file name in the profiles/ directory. For instance, to use base.profile.js, "
-			+ "specify profile=base."
-	},
-	"profileFile": {
-		defaultValue: "",
-		helpText: "A file path to the the profile file. Use this if your profile is outside of the profiles "
-			+ "directory. Do not specify the \"profile\" build option if you use \"profileFile\"."
-	},
-	"htmlFiles": {
-		defaultValue: "",
-		helpText: "A list of HTML files to generate the profile from. The HTML files will be "
-			+ "scanned for script tags and dojo.require calls to create a set of layers. "
-			+ "If a profile or profileFile is specified, the profile will be written to that destination "
-			+ "and the build will continue."
-	},
-	"htmlDir": {
-		defaultValue: "",
-		helpText: "A directory to use to get a list of HTML files for generating the profile"
-	},
-	"action": {
-		defaultValue: "help",
-		helpText: "The build action(s) to run. Can be a comma-separated list, like action=clean,release. "
-			+ "The possible build actions are: clean, release."
-	},
-	"version": {
-		defaultValue: "0.0.0.dev",
-		helpText: "The build will be stamped with this version string."
-	},
-	"localeList": {
-		defaultValue: "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",
-		helpText: "The set of locales to use when flattening i18n bundles."
-	},
-	
-	"releaseName": {
-		defaultValue: "dojo",
-		helpText: "The name of the release. A directory inside 'releaseDir' will be created with this name."
-	},
-	"releaseDir": {
-		defaultValue: "../../release/",
-		helpText: "The top level release directory where builds end up. The 'releaseName' directories will "
-			+ " be placed inside this directory."
-	},
-	"loader": {
-		defaultValue: "default",
-		helpText: "The type of dojo loader to use. \"default\" or \"xdomain\" are acceptable values."
-	},
-	"internStrings": {
-		defaultValue: true,
-		helpText: "Turn on or off widget template file interning."
-	},
-	"optimize": {
-		defaultValue: "",
-		helpText: "Specifies how to optimize module files. If \"comments\" is specified, "
-			+ "then code comments are stripped. If \"shrinksafe\" is specified, then "
-			+ "Dojo Shrinksafe will be used on the files, and line returns will be removed. "
-			+ "If \"shrinksafe.keepLines\" is specified, then Dojo Shrinksafe will be used "
-			+ "on the files, and line returns will be preserved.  See also \"stripConsole\". "
-			+ "Google Closure's compiler can be used by specifying \"closure\" as the value. "
-			+ "It does not use the stripConsole build option, and it REQUIRES Java 6 to run, and it may make "
-			+ "some complaints about the code and print out 'error's, but if the build completes, "
-			+ "then the code should work. Do not taunt happy Closure compiler. To use Closure compiler, "
-			+ "download it from here:\n"
-			+ "http://code.google.com/p/closure-compiler/downloads/list\n"
-			+ "And place the compiler.jar file somewhere you can easily reference. Then use the following "
-			+ "to execute the build (remember Java 6):\n"
-			+ "java -classpath ../shrinksafe/js.jar:../closurecompiler/compiler.jar org.mozilla.javascript.tools.shell.Main build.js\n"
-			+ "and place your build arguments on the same line after that text. Change the ../closurecompiler "
-			+ "path to the path where you keep Closure's compiler.jar."
-	},
-	"layerOptimize": {
-		defaultValue: "shrinksafe",
-		helpText: "Specifies how to optimize the layer files. If \"comments\" is specified, "
-			+ "then code comments are stripped. If \"shrinksafe\" is specified, then "
-			+ "Dojo Shrinksafe will be used on the files, and line returns will be removed. "
-			+ "If \"shrinksafe.keepLines\" is specified, then Dojo Shrinksafe will be used "
-			+ "on the layer files, and line returns will be preserved. "
-			+ "Google Closure's compiler can be used by specifying \"closure\" as the value. "
-			+ "It does not use the stripConsole build option, and it REQUIRES Java 6 to run, and it may make "
-			+ "some complaints about the code and print out 'error's, but if the build completes, "
-			+ "then the code should work. Do not taunt happy Closure compiler. To use Closure compiler, "
-			+ "download it from here:\n"
-			+ "http://code.google.com/p/closure-compiler/downloads/list\n"
-			+ "And place the compiler.jar file somewhere you can easily reference. Then use the following "
-			+ "to execute the build (remember Java 6):\n"
-			+ "java -classpath ../shrinksafe/js.jar:../closurecompiler/compiler.jar org.mozilla.javascript.tools.shell.Main build.js\n"
-			+ "and place your build arguments on the same line after that text. Change the ../closurecompiler "
-			+ "path to the path where you keep Closure's compiler.jar."
-	},
-	"cssOptimize": {
-		defaultValue: "",
-		helpText: "Specifies how to optimize CSS files. If \"comments\" is specified, "
-			+ "then code comments and line returns are stripped, and files referenced via @import "
-			+ "are inlined. If \"comments.keepLines\" "
-			+ "is specified, then code comments are stripped and @import calls are inlined, but line returns are preserved."
-	},
-
-	"cssImportIgnore": {
-		defaultValue: "",
-		helpText: "If using cssOptimize=\"comments\", then you can force the @import inlining step "
-			+ "to ignore a set of files by using this option. The value of this option should be a comma "
-			+ "separated list of CSS files names to ignore. The file names should match whatever strings "
-			+ "are used for the @import calls."
-	},
-	
-	"stripConsole": {
-		defaultValue: undefined,
-		helpText: "Strips console method calls from JS source. Applied to layers and individual modules "
-			+ "resource files. Valid values are \"none\" (leaves all console calls alone, same as "
-			+ "default \"\"), \"normal\" (strips all but console.warn and console.error calls), "
-			+ "\"warn\" (strips all but console.error calls), \"all\" (strips all console calls).  "
-			+ "NOTE: only has effect if optimize includes use of shrinksafe."
-	},
-
-	"copyTests": {
-		defaultValue: false,
-		helpText: "Turn on or off copying of test files."
-	},
-	"mini": {
-		defaultValue: true,
-		helpText: "Removes files like tests, demos dijit/bench, unfinished themes, and interned "
-			+ "Dijit templates from the build. Overrides the value set for copyTests."
-	},
-	"log": {
-		defaultValue: logger.TRACE,
-		helpText: "Sets the logging verbosity. See jslib/logger.js for possible integer values."
-	},
-	"xdDojoPath": {
-		defaultValue: "",
-		helpText: "If the loader=xdomain build option is used, then the value of this option "
-			+ "will be used to call dojo.registerModulePath() for dojo, dijit and dojox. "
-			+ "The xdDojoPath should be the directory that contains the dojo, dijit and dojox "
-			+ "directories, and it should NOT end in a slash. For instance: 'http://some.domain.com/path/to/dojo090'."
-	},
-	"symbol": {
-		defaultValue: "",
-		helpText: "Inserts function symbols as global references so that anonymous "
-			+ "functions will show up in all debuggers (esp. IE which does not attempt "
-			+ "to infer function names from the context of their definition). Valid values "
-			+ "are \"long\" and \"short\". If \"short\" is used, then a symboltables.txt file "
-			+ "will be generated in each module prefix's release directory which maps the "
-			+ "short symbol names to more descriptive names."
-	},
-	"scopeDjConfig": {
-		defaultValue: "",
-		helpText: "Burn in a djConfig object into the built dojo.js file. Useful if you are making your own scoped dojo and you want a "
-			+ "djConfig object local to your version that will not be affected by any globally declared djConfig object in the page. "
-			+ "Value must be a string that will look like a javascript object literal once it is placed in the built source. "
-			+ "use Dojo as part of a JS library, but want to make a self-contained library with no external dojo/dijit/dojox. Example "
-			+ "(note that the backslashes below are required to avoid shell escaping if you type this on the command line):\n"
-			+ "scopeDjConfig={isDebug:true,scopeMap:[[\\\"dojo\\\",\\\"mydojo\\\"],[\\\"dijit\\\",\\\"mydijit\\\"],[\\\"dojox\\\",\\\"mydojox\\\"]]}"
-	},
-	"scopeMap": {
-		defaultValue: "",
-		helpText: "Change the default dojo, dijit and dojox scope names to something else. Useful if you want to "
-			+ "use Dojo as part of a JS library, but want to make a self-contained library with no external dojo/dijit/dojox "
-			+ "references. Format is a string that contains no spaces, and is similar to the djConfig.scopeMap value (note that the "
-			+ "backslashes below are required to avoid shell escaping):\n"
-			+ "scopeMap=[[\\\"dojo\\\",\\\"mydojo\\\"],[\\\"dijit\\\",\\\"mydijit\\\"],[\\\"dojox\\\",\\\"mydojox\\\"]]"
-	},
-	"xdScopeArgs": {
-		defaultValue: "",
-		helpText: "If the loader=xdomain build option is used, then the value of this option "
-			+ "will be used as the arguments to the function that defines the modules in the .xd.js files. "
-			+ "This allows for more than one version of the same module to be in a page. See documentation on "
-			+ "djConfig.scopeMap for more information."
-	},
-	"xdDojoScopeName": {
-		defaultValue: "dojo",
-		helpText: "If the loader=xdomain build option is used, then the value of this option "
-			+ "will be used instead of 'dojo' for the 'dojo._xdResourceLoaded()' calls that are done in the .xd.js files. "
-			+ "This allows for dojo to be under a different scope name but still allow xdomain loading with that scope name."
-	},
-	"expandProvide": {
-		defaultValue: false,
-		helpText: "Expands dojo.provide calls with faster calls at the expense of a larger file size. Only use the option "
-			+ "if your profiling reveals that dojo.provide calls are taking a noticeable amount of time. Even then, it could "
-			+ "cause errors in the built files. If you find an error after building, turn this option off. It replaces "
-			+ "dojo.provide(\"foo.bar\") statements with the shortest valid programmatic equivalent:\n"
-			+ "if(typeof foo==\"undefined\"){foo={};};foo.bar=foo.bar||{};\nIgnored for xdomain builds."
-	},
-	"buildLayers": {
-		defaultValue: "",
-		helpText: "A comma-separated list of layer names to build. Using this option means that only those layers will be built. "
-			+ "This helps if you are doing quick development and test cycles with layers. If you have problems using this option, "
-			+ "try removing it and doing a full build with action=clean,release. This build option assumes you have done at least one full build first."
-	},
-	"query": {
-		defaultValue: "default",
-		helpText: "Select a DOM query engine. Default value is the normal dojo.query engine. Using query=sizzle will use the Sizzle engine."
-			+ "Normal Dojo tests are not run routinely with the Sizzle engine. See dojo/_base/sizzle.js for the version of Sizzle."
-	},
-	"removeDefaultNameSpaces": {
-		defaultValue: false,
-		helpText: "Removes the default 'com', 'org' and 'net' namespaces that are present in Rhino. This is hazardous to use if "
-			+ "the build system is used as part of a Rhino-based server-side solution, so use with caution. Weird build errors "
-			+ "might occur. Only use if your own code includes things in a com, org or net namespace."
-	},
-	"addGuards": {
-		defaultValue: true,
-		helpText: "Set to false to remove the code guards that protect modules from re-definition. In general you SHOULD NOT "
-			+ "set this value to false. Only do it if you want an even smaller Dojo Base build and you know the implications "
-			+ "of re-defining modules. It is bad. Do not do it."
-	}
-};
-
-buildUtil.makeBuildOptions = function(/*Array*/scriptArgs){
-	//summary: constructs the build options by combining the scriptArgs with
-	//default build options and anything specified in a profile file.
-
-	var kwArgs = {}, param, profileProperties;
-
-	//Parse the command line arguments
-	kwArgs = buildUtil.convertArrayToObject(scriptArgs);
-	if(!kwArgs["profileFile"] && kwArgs["profile"]){
-		kwArgs.profileFile = "profiles/" + kwArgs.profile + ".profile.js";
-	}
-	function processHtmlFile(htmlFile){
-		var priorLayers = [];
-		
-		var html = fileUtil.readFile(htmlFile);
-		html.replace(/<script [^>]*src=["']([^'"]+)["']/gi, function(t, scriptName){
-			// for each script tag
-			if(scriptName.indexOf("dojo/dojo.js") > -1){
-				// use dojo.js to determine the prefix for our namespaces
-				prefix = scriptName.substring(0, scriptName.indexOf("dojo/dojo.js"));
-			}else{
-				// non-dojo.js script files, add it to our list of layers
-				addLayer(scriptName = scriptName.substring(prefix.length, scriptName.length - 3).replace(/\//g, '.'));
-			}
-		});
-		html.replace(/dojo\.require\(["']([^'"]+)["']\)/g, function(t, scriptName){
-			// for each dojo.require call add it to the layers as well
-			addLayer(scriptName);
-		});
-		function addLayer(scriptName){
-			if(layers[scriptName]){
-				// if this module has been added before, find the intersection of dependencies
-				layers[scriptName] = layers[scriptName].filter(function(scriptName){
-					return priorLayers.indexOf(scriptName) > -1;
-				});
-			}else{
-				layers[scriptName] = priorLayers.concat();
-			}
-			if(scriptName.indexOf('.') > -1){
-				prefixes[scriptName.substring(scriptName, scriptName.indexOf('.'))] = true;
-			}
-			priorLayers.push(scriptName);
-		}
-		return layers;
-	}
-	//Load dependencies object from profile file, if there is one.
-	var dependencies = {};
-	if(kwArgs.htmlDir){
-		kwArgs.htmlFiles = fileUtil.getFilteredFileList(kwArgs.htmlDir, /\.html/, false, false, true);
-	}
-	if(kwArgs.htmlFiles){
-		var layers = {}, prefix = "", prefixes = {dijit: true, dojox: true};
-		print("kwArgs.htmlFiles " + kwArgs.htmlFiles);
-		(kwArgs.htmlFiles instanceof Array ? kwArgs.htmlFiles : kwArgs.htmlFiles.split(',')).forEach(function(file){
-			// process each html file
-			processHtmlFile(file);
-		});
-		
-		
-		// we are rocessing an HTML file, first read it
-		var prefixPaths = [];
-		// normalize the prefixes into the arrays that the build expects
-		for(prefix in prefixes){
-			prefixPaths.push([prefix, "../" + prefix]);
-		}
-		var layersArray = [];
-		for(var name in layers){
-			// for each layer, create a layer object
-			layersArray.push({
-						name: "../" + name.replace(/\./g,'/') + ".js", // use filename
-						dependencies: [
-							name.replace(/\//g,'.') // use module name
-						],
-						//use all previous layers as layer dependencies
-						layerDependencies: layers[name].map(function(name){
-							return "../" + name.replace(/\./g,'/') + ".js"
-						})
-					});
-		}
-		profileProperties = {
-				layers: layersArray,
-				prefixes: prefixPaths
-			};
-		if(kwArgs.profileFile){
-			fileUtil.saveFile(kwArgs.profileFile, "dependencies = " + profileProperties.toSource());
-		}
-		// now create the profile object
-		profileProperties = kwArgs.profileProperties = buildUtil.processProfile(profileProperties);
-		dependencies = profileProperties.dependencies;
-	}
-	else if(kwArgs["profileFile"]){
-		profileProperties = buildUtil.evalProfile(kwArgs.profileFile);
-		//logger.info(profileProperties.toSource());
-		
-		if(profileProperties){
-			kwArgs.profileProperties = profileProperties;
-			dependencies = kwArgs.profileProperties.dependencies;
-			
-			//Allow setting build options from on the profile's dependencies object.
-			//Do not override existing values from the command line though.
-			for(param in dependencies){
-				if(!(param in kwArgs) && param != "layers" && param != "prefixes"){
-					kwArgs[param] = dependencies[param];
-				}
-			}
-		}
-	}
-
-	//Set up default options
-	for(param in buildUtil.DojoBuildOptions){
-		//Only use default if there is no value so far.
-		if(typeof kwArgs[param] == "undefined"){
-			kwArgs[param] = buildUtil.DojoBuildOptions[param].defaultValue;
-		}else if(kwArgs[param] === "false"){
-			//Make sure "false" strings get translated to proper false value.
-			kwArgs[param] = false;
-		}
-	}
-
-	//Make sure releaseDir uses / since rest of build assumes / paths.
-	kwArgs.releaseDir = kwArgs.releaseDir.replace(/\\/g, "/");
-
-	//Set up some compound values
-	if(kwArgs["releaseName"]){
-		///Make sure releaseDir ends in a / so releaseName concat works.
-		if(!kwArgs.releaseDir.match(/\/$/)){
-			kwArgs.releaseDir += "/";
-		}
-		kwArgs.releaseDir += kwArgs["releaseName"];
-	}else{
-		//No releaseName, so strip off trailing slash
-		kwArgs.releaseDir = kwArgs.releaseDir.replace(/\/$/, "");
-	}
-
-	kwArgs.action = kwArgs.action.split(",");
-	kwArgs.localeList = kwArgs.localeList.split(",");
-
-	//Attach the final loader type to the dependencies
-	dependencies.loader = kwArgs.loader;
-
-	//Fix args for bugs
-	if(kwArgs.expandProvide && kwArgs.loader == "xdomain"){
-		logger.info("NOTE: expandProvide not compatible with xdomain builds. Ignoring expandProvide option.");
-		kwArgs.expandProvide = false;
-	}
-	
-	//Notify on incompatible options.
-	if(kwArgs.optimize && kwArgs.optimize != "shrinksafe" && kwArgs.stripConsole){
-		logger.info("NOTE: stripConsole is only supported for an optimize=shrinksafe value.");
-	}
-	if(kwArgs.layerOptimize && kwArgs.layerOptimize != "shrinksafe" && kwArgs.stripConsole){
-		logger.info("layerOPtimize: [" + kwArgs.layerOptimize + "]");
-		logger.info("NOTE: stripConsole is only supported for an layerOptimize=shrinksafe value.");
-	}
-
-	//Validate some values.
-	if(typeof kwArgs.scopeDjConfig != "string") {
-		throw "Due to deficiencies in the build system, scopeDjConfig needs to be a string.";
-	}
-
-
-	//Do some hackery for closure compiler.
-	if(kwArgs.optimize.indexOf("closure") == 0 || kwArgs.layerOptimize.indexOf("closure") == 0){
-		//directly call JSSourceFile.fromCode will actually invoke SourceFile.fromCode,
-		//which will lead to error: "Cannot convert com.google.javascript.jscomp.SourceFile$Preloaded at 26afa68a to com.google.javascript.jscomp.JSSourceFile"
-		//don't know whether it's a bug in closure or rhino - liucougar
-		var JSSourceFilefromCode=java.lang.Class.forName('com.google.javascript.jscomp.JSSourceFile').getMethod('fromCode',[java.lang.String,java.lang.String]);
-		buildUtil.closurefromCode = function(filename,content){
-			return JSSourceFilefromCode.invoke(null,[filename,content])
-		}
-	}
-
-	return kwArgs;
-}
-
-//Even though these are i18n-specific, they are not in i18nUtil.js since one is referenced
-//in this file. Want to avoid circular dependency loading issues.
-buildUtil.masterRequireLocalizationRegExpString = "dojo.(requireLocalization)\\(([\\w\\W]*?)\\)";
-buildUtil.globalRequireLocalizationRegExp = new RegExp(buildUtil.masterRequireLocalizationRegExpString, "mg");
-buildUtil.requireLocalizationRegExp = new RegExp(buildUtil.masterRequireLocalizationRegExpString);
-
-//FIXME: This should take the build kwArgs now instead.
-buildUtil.getDojoLoader = function(/*Object?*/dependencies){
-	//summary: gets the type of Dojo loader for the build. For example default or
-	//xdomain loading. Override for web builds.
-	return (dependencies && dependencies["loader"] ? dependencies["loader"] : java.lang.System.getProperty("DOJO_LOADER"));
-}
-
-buildUtil.includeLoaderFiles = function(/*String*/dojoLoader, /*String or Array*/hostenvType, /*String*/buildscriptsPath){
-	//summary: adds the loader files to the file list for a build file.
-	dojo._loadedUrls.push(buildscriptsPath + "jslib/dojoGuardStart.jsfrag");
-	dojo._loadedUrls.push(buildscriptsPath + "../../dojo/_base/_loader/bootstrap.js");
-	
-	if(dojoLoader == "default"){
-		dojo._loadedUrls.push(buildscriptsPath + "../../dojo/_base/_loader/loader.js");
-	}else if(dojoLoader == "xdomain"){
-		dojo._loadedUrls.push(buildscriptsPath + "../../dojo/_base/_loader/loader.js");
-		dojo._loadedUrls.push(buildscriptsPath + "../../dojo/_base/_loader/loader_xd.js");
-	}
-
-	if(hostenvType.constructor == Array){
-		for(var x=0; x<hostenvType.length; x++){
-			dojo._loadedUrls.push(buildscriptsPath + "../../dojo/_base/_loader/hostenv_"+hostenvType[x]+".js");
-		}
-		hostenvType = hostenvType.pop();
-	}else{
-		dojo._loadedUrls.push(buildscriptsPath + "../../dojo/_base/_loader/hostenv_"+hostenvType+".js");
-	}
-}
-
-buildUtil.getDependencyList = function(/*Object*/dependencies, /*String or Array*/hostenvType, /*Object?*/kwArgs, /*String?*/buildscriptsPath){
-	//summary: Main function that traces the files that are needed for a give list of dependencies.
-
-	if(!dependencies){
-		dependencies = {}
-	}
-
-	buildscriptsPath = buildscriptsPath || "./";
-	
-	var dojoLoader = buildUtil.getDojoLoader(dependencies);
-	if(!dojoLoader || dojoLoader=="null" || dojoLoader==""){
-		dojoLoader = "default";
-	}
-
-
-	//Now build the URI list, starting with the main dojo.js file
-	if(!dependencies["layers"]){
-		dependencies.layers = [];
-	}
-
-	//Set up the dojo.js layer. Add _base if the profile already
-	//defines a dojo.js layer. If the profile defines a dojo.js
-	//layer it MUST be the first layer.
-	if(dependencies.layers[0] && dependencies.layers[0].name == "dojo.js"){
-		if(!dependencies.layers[0].customBase){
-			dependencies.layers[0].dependencies.unshift("dojo._base");
-		}
-	}else{
-		dependencies.layers.unshift({
-			name: "dojo.js",
-			dependencies: [
-				"dojo._base"
-			]
-		});
-	}
-
-	currentProvideList = [];
-	var result = [];
-	var layers = dependencies["layers"];
-	var layerCount = layers.length;
-	
-	//Process dojo layer files
-	if(layerCount){
-		//Set up a lookup table for the layer URIs based on layer file name.
-		var namedLayerUris = {};
-				
-		//If xd build, cycle over the layers twice. Second time through
-		//are the xd files.
-		var endCount = layerCount;
-		if(dojoLoader == "xdomain"){
-			endCount = endCount * 2;
-		}
-		
-		for(var i = 0; i < endCount; i++){
-			var j = i;
-			var isXd = false;
-			if(i >= layerCount){
-				//Dealing with the xd files.
-				if(i == layerCount){
-					//Reset the dependencies.
-					namedLayerUris = {};
-				}
-				j = i - layerCount;
-				isXd = true;
-			}
-			var layer = layers[j];
-			var layerName = layers[j].name;
-			if(isXd){
-				layerName = layerName.replace(/\.js$/, ".xd.js");
-			}
-
-			//Add dojo.i18n to dojo.xd.js. Too complicated to dynamically load it in that case.
-			if(isXd && layerName == "dojo.xd.js"){
-				layer.dependencies.splice(1, 0, "dojo.i18n");
-			}
-
-			djConfig = {
-				baseRelativePath: "../../dojo/"
-				// isDebug: true
-			};
-
-	
-			load(buildscriptsPath + "../../dojo/_base/_loader/bootstrap.js");
-			load(buildscriptsPath + "../../dojo/_base/_loader/loader.js");
-			load(buildscriptsPath + "../../dojo/_base/_loader/hostenv_rhino.js");
-			dojo.global = {};
-
-		
-			if(!hostenvType){
-				hostenvType = "browser";
-			}
-		
-			if(dependencies["prefixes"]){
-				var tmp = dependencies.prefixes;
-				for(var x=0; x<tmp.length; x++){
-					dojo.registerModulePath(tmp[x][0], tmp[x][1]);
-				}
-			}
-		
-			dojo._name = hostenvType;
-			if(hostenvType == "browser" || hostenvType == "ff_ext"){
-				//Make sure we setup the env so that dojo
-				//thinks we are running in a browser.
-				dojo.isBrowser = true;
-			}
-			
-			//Override dojo.provide to get a list of resource providers.
-			var currentProvideList = [];
-			dojo._provide = dojo.provide;
-			dojo.provide = function(resourceName){
-				currentProvideList.push(resourceName);
-				dojo._provide(resourceName);
-			}
-			
-			// over-write dojo.eval to prevent actual loading of subsequent files
-			dojo._oldEval = dojo["eval"];
-			dojo["eval"] = function(){ return true; }
-			var old_load = load;
-			load = function(uri){
-				try{
-					//Strip comments and apply conditional directives before tracing the dependencies.
-					var text = fileUtil.readFile(uri);
-					text = (kwArgs ? buildUtil.processConditionals(layerName, text, kwArgs) : text);
-					text = buildUtil.removeComments(text);
-
-					var requires = dojo._getRequiresAndProvides(text);
-					eval(requires.join(";"));
-					dojo._loadedUrls.push(uri);
-					dojo._loadedUrls[uri] = true;
-					var delayRequires = dojo._getDelayRequiresAndProvides(text);
-					
-					//Now do the requireIfs. Since they contain some code tests that could
-					//not be valid in the current scope (access variables that are not defined
-					//when running in Rhino, for instance), then do a try/catch around each
-					//one. If the expression fails, then it was not meant for this context.
-					for(var i = 0; i < delayRequires.length; i++){
-						try{
-							eval(delayRequires[i]);
-						}catch(e){
-							//logger.trace("A requireIf failed for text [" + delayRequires[i] + "], error: " + e);
-						}
-					}
-				}catch(e){
-					java.lang.System.err.println("error loading uri: " + uri + ", exception: " + e);
-					quit(-1);
-				}
-				return true;
-			}
-
-			dojo._getRequiresAndProvides = function(contents){
-				// FIXME: should probably memoize this!
-				if(!contents){ return []; }
-			
-				// check to see if we need to load anything else first. Ugg.
-				var deps = [];
-				var tmp;
-				RegExp.lastIndex = 0;
-				var testExp = /dojo.(require|platformRequire|provide)\s*\([\w\W]*?\)/mg;
-				while((tmp = testExp.exec(contents)) != null){
-					deps.push(tmp[0]);
-				}
-				
-				//If there is a dojo.requireLocalization() call, make sure to add dojo.i18n
-				if(contents.match(/dojo\.requireLocalization\(.*?\)/)){
-					deps.push('dojo.require("dojo.i18n")');
-				}
-		
-				return deps;
-			}
-			
-			dojo._getDelayRequiresAndProvides = function(contents){
-				// FIXME: should probably memoize this!
-				if(!contents){ return []; }
-			
-				// check to see if we need to load anything else first. Ugg.
-				var deps = [];
-				var tmp;
-				RegExp.lastIndex = 0;
-				var testExp = /dojo.(requireAfterIf|requireIf)\([\w\W]*?\)/mg;
-				while((tmp = testExp.exec(contents)) != null){
-					deps.push(tmp[0]);
-				}
-				return deps;
-			}
-		
-			if(dependencies["dojoLoaded"]){
-				dependencies["dojoLoaded"]();
-			}
-	
-			//Add the loader files if this is a loader layer.
-			if(layerName == "dojo.js"){
-				buildUtil.includeLoaderFiles("default", hostenvType, buildscriptsPath);
-			}else if(layerName == "dojo.xd.js"){
-				buildUtil.includeLoaderFiles("xdomain", hostenvType, buildscriptsPath);
-			}
-		
-			//Set up list of module URIs that are already defined for this layer's
-			//layer dependencies. Always include the dojo.js layer uris. dojo.js could
-			//have more than _base, and in xdomain, it has dojo.i18n.
-			var layerUris = [];
-			if(layer.name != "dojo.js"){
-				layerUris = layerUris.concat(namedLayerUris["dojo.js"]);
-			}
-			
-			if(layer["layerDependencies"]){
-				for(j = 0; j < layer.layerDependencies.length; j++){
-					if(namedLayerUris[layer.layerDependencies[j]]){
-						layerUris = layerUris.concat(namedLayerUris[layer.layerDependencies[j]]);
-					}
-				}
-			}
-
-			//Get the final list of dependencies in this layer
-			var depList = buildUtil.determineUriList(layer.dependencies, layerUris, dependencies["filters"]);
-
-			//If dojo.xd.js, need to put dojo.i18n before the code in dojo._base.browser that does the
-			//auto dojo.require calls based on dojo.config.require array.
-			//This is a little bit hackish, but it allows dojo.i18n to use any Base methods
-			//in the future.
-			if(layerName == "dojo.xd.js"){
-				//Find the dojo.i18n line. Start at the end of depList because it is likely closer
-				//to the end than the beginning.
-				var i18nXdEntry = null;
-				for(var i18nIndex = depList.length - 1; i18nIndex >= 0; i18nIndex--){
-					if(depList[i18nIndex].match(/\/dojo\/i18n\.js$/)){
-						i18nXdEntry = depList.splice(i18nIndex, 1)[0];
-						break;
-					}
-				}
-				
-				//Only operate if we have an i18n entry. We may allow building without
-				//dojo.i18n as part of the xd file.
-				if(i18nXdEntry){
-					var foundBrowserJs = false;
-					for(i18nIndex = depList.length - 1; i18nIndex >= 0; i18nIndex--){
-						if(depList[i18nIndex].match(/dojo\/_base\/browser\.js$/)){
-							depList.splice(i18nIndex, 0, i18nXdEntry);
-							foundBrowserJs = true;
-							break;
-						}
-					}
-					//If did not find browser entry (maybe a customBase build),
-					//Just add the i18n entry to the end.
-					if(!foundBrowserJs){
-						depList.push(i18nXdEntry);
-					}
-				}
-			}
-			
-			//Add the final closure guard to the list.
-			if(layerName == "dojo.js" || layerName == "dojo.xd.js"){
-				depList.push(buildscriptsPath + "jslib/dojoGuardEnd.jsfrag");
-			}
-
-			//Store the layer URIs that are in this file as well as all files it depends on.
-			namedLayerUris[layer.name] = layerUris.concat(depList);
-		
-			//Add to the results object.
-			if(!layer["discard"]){
-				result.push({
-					layerName: layerName,
-					resourceName: layer.resourceName,
-					copyrightFile: layer.copyrightFile,
-					depList: depList,
-					provideList: currentProvideList
-				});
-			}
-
-			//Reset for another run through the loop.
-			currentProvideList = [];
-
-			load = old_load; // restore the original load function
-			dojo["eval"] = dojo._oldEval; // restore the original dojo.eval function
-	
-			var djGlobal = dojo.global;
-			djGlobal['djConfig'] = undefined;
-	
-			delete dojo;
-			delete define;
-		}
-	}
-
-	return result; //Object with properties: name (String), depList (Array) and provideList (Array)
-}
-
-buildUtil.removeComments = function(/*String*/contents){
-	//summary: strips JS comments from a string. Not bulletproof, but does a good enough job
-	//for stripping out stuff that is not related to mapping resource dependencies.
-
-	//If we get the contents of the file from Rhino, it might not be a JS
-	//string, but rather a Java string, which will cause the replace() method
-	//to bomb.
-	contents = contents ? new String(contents) : "";
-	//clobber all comments
-	return contents.replace( /(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg , "");
-}
-
-//Function to do the actual collection of file names to join.
-buildUtil.determineUriList = function(/*Array*/dependencies, /*Array*/layerUris, /*Object*/filters){
-	for(var x=0; x<dependencies.length; x++){
-		try{
-			var dep = dependencies[x];
-
-			//Don't process loader_xd.js since it has some regexps
-			//and mentions of dojo.require/provide, which will cause
-			//havoc in the dojo._loadModule() method.
-			if(dep.indexOf("loader_xd.js") == -1){
-				dojo._loadModule(dep, true);
-			}
-		}catch(e){
-			java.lang.System.err.println("Error loading module!" + e);
-			quit(-1);
-		}
-	}
-
-	var depList = [];
-	var seen = {};
-	uris: for(x=0; x<dojo._loadedUrls.length; x++){
-		var curi = dojo._loadedUrls[x];
-		if(!seen[curi]){
-			seen[curi] = true;
-			if(filters){
-				for(var i in filters){
-					if(curi.match(filters[i])){
-						continue uris;
-					}
-				}
-			}
-			
-			//If the uri is already accounted for in another
-			//layer, skip it.
-			if(layerUris){
-				for(i = 0; i < layerUris.length; i++){
-					if(curi == layerUris[i]){
-						continue uris;
-					}
-				}
-			}
-
-			//No filter or layerUri matches, so it is good to keep.
-			depList.push(curi);
-		}
-	}
-	
-	//Clear out the loadedUris for the next run.
-	dojo._loadedUrls = [];
-	return depList;
-}
-
-
-buildUtil.evalProfile = function(/*String*/profileFile, /*Boolean*/fileIsProfileText){
-	var dependencies = {};
-	var profileText = fileIsProfileText ? profileFile : fileUtil.readFile(profileFile);
-
-	//Remove the call to getDependencyList.js because it is not supported anymore.
-	profileText = profileText.replace(/load\(("|')getDependencyList.js("|')\)/, "");
-	eval(profileText);
-	return buildUtil.processProfile(dependencies);
-}
-
-buildUtil.processProfile = function(dependencies){
-	var hostenvType = null;
-	//Build up the prefixes so the rest of the scripts
-	//do not have to guess where things are at.
-	if(!dependencies["prefixes"]){
-		dependencies.prefixes = [];
-	}
-	
-	//Find prefixes that are used.
-	var usedPrefixes = ["dojo"];
-	usedPrefixes._entries = { dojo: true };
-	
-	//Check normal dependencies.
-	buildUtil.addPrefixesFromDependencies(usedPrefixes, dependencies);
-
-	//Check layer dependencies
-	var layerDeps = dependencies.layers;
-	
-	if(layerDeps){
-		for(var i = 0; i < layerDeps.length; i++){
-			buildUtil.addPrefixesFromDependencies(usedPrefixes, layerDeps[i].dependencies);
-		}
-	}
-
-	//Now add to the real prefix array.
-	//If not already in the prefix array, assume the default
-	//location, as a sibling to dojo (and util).
-	for(i = 0; i < usedPrefixes.length; i++){
-		var hasPrefix = false;
-		for(var j = 0; j < dependencies.prefixes.length; j++){
-			if(dependencies.prefixes[j][0] == usedPrefixes[i]){
-				hasPrefix = true;
-				break;
-			}
-		}
-		if(!hasPrefix){
-			//Assumptions are that any prefixes that are not dojo
-			//are a sibling to dojo. Dojo path is special, it needs
-			//to be relative to util/buildscripts. The dojo path is
-			//prepended to other paths later.
-			var dirPrefix = "../";
-			if(usedPrefixes[i] == "dojo"){
-				dirPrefix = "../../";
-			}
-			dependencies.prefixes.push([usedPrefixes[i], dirPrefix + usedPrefixes[i]]);
-		}
-	}
-
-	return {
-		dependencies: dependencies,
-		hostenvType: hostenvType
-	};
-}
-
-buildUtil.getDojoPrefixPath = function(/*Array*/prefixes){
-	//summary: Gets the path to Dojo from the prefixes.
-	var result = null;
-	for(var i = 0; i < prefixes.length; i++){
-		if(prefixes[i][0] == "dojo"){
-			result = prefixes[i][1];
-			break;
-		}
-	}
-	return result;
-}
-
-buildUtil.addPrefixesFromDependencies = function(/*Array*/prefixStore, /*Array*/dependencies){
-	//summary: finds the top level prefixes in the build process that
-	//we need to track for the build process.
-	for(var i = 0; i < dependencies.length; i++){
-		var topPrefix = dependencies[i].split(".")[0];
-		if(!prefixStore._entries[topPrefix]){
-			prefixStore.push(topPrefix);
-			prefixStore._entries[topPrefix] = true;
-		}
-	}
-}
-
-buildUtil.loadDependencyList = function(/*Object*/profile, /*Object?*/kwArgs, /*String?*/buildscriptsPath){
-	//summary: Traverses the dependencies in the profile object.
-	//profile:
-	//		The profile object that is a result of a buildUtil.evalProfile() call.
-	var depResult = buildUtil.getDependencyList(profile.dependencies, profile.hostenvType, kwArgs, buildscriptsPath);
-	depResult.dependencies = profile.dependencies;
-	
-	return depResult;
-}
-
-buildUtil.createLayerContents = function(
-	/*String*/layerName,
-	/*String*/resourceName,
-	/*Array*/depList,
-	/*Array*/provideList,
-	/*String*/version,
-	/*Object?*/kwArgs){
-	//summary: Creates the core contents for a build layer (including dojo.js).
-
-	//Concat the files together, and mark where we should insert all the
-	//provide statements.
-	var dojoContents = resourceName ? "dojo.provide(\"" + resourceName + "\");\r\n" : "";
-	for(var i = 0; i < depList.length; i++){
-		//Run the file contents through the include/exclude "preprocessor".
-		var depContents = fileUtil.readFile(depList[i]);
-		dojoContents += (kwArgs ? buildUtil.processConditionals(layerName, depContents, kwArgs) : depContents)
-			+ "\r\n";
-	}
-
-	//Find out if the layer has any dojo.require calls we should not strip out,
-	//via the layer.keepRequires array. If there is one, convert to an object
-	//for each key lookup.
-	var keepRequires = null;
-	var layers = kwArgs.profileProperties.dependencies.layers;
-	for(i = 0; i < layers.length; i++){
-		if(layerName == layers[i].name){
-			var keepArray = layers[i].keepRequires;
-			if(keepArray){
-				keepRequires = {};
-				for(var j = 0; j < keepArray.length; j++){
-					keepRequires[keepArray[j]] = true;
-				}
-			}
-			break;
-		}
-	}
-
-	//Construct a string of all the dojo.provide statements.
-	//This string will be used to construct the regexp that will be
-	//used to remove matching dojo.require statements.
-	//Sort the provide list alphabetically to make it easy to read.
-	//Order of provide statements do not matter.
-	provideList = provideList.sort();
-	var depRegExpString = "";
-	for(i = 0; i < provideList.length; i++){
-		//Skip keepRequire matches.
-		if(keepRequires && keepRequires[provideList[i]]){
-			continue;
-		}
-		if(depRegExpString){
-			depRegExpString += "|";
-		}
-		depRegExpString += '([\'"]' + provideList[i] + '[\'"])';
-	}
-
-	//If we have a string for a regexp, do the dojo.require() and requireIf() removal now.
-	if(depRegExpString){
-		//Make to escape regexp-sensitive characters
-		depRegExpString = buildUtil.regExpEscape(depRegExpString);
-		//Build the regexp
-		var depRegExp = new RegExp("dojo\\.(require|requireIf)\\(.*?(" + depRegExpString + ")\\)(;?)", "g");
-		dojoContents = dojoContents.replace(depRegExp, "");
-	}
-
-	if(kwArgs.expandProvide){
-		// replace dojo.provide("foo.bar.Baz") statements with the shortest valid
-		// programmatic equivalent:
-		//		foo = foo||{};
-		//		foo.bar = foo.bar||{};
-		//		foo.bar.Baz = foo.bar.Baz||{};
-		//		dojo._loadedModules["foo.bar.Baz"] = foo.bar.Baz = foo.bar.Baz||{};
-	
-		var seenProvides = {};
-		var provideRegExp = /dojo.provide\(([\w\W]*?)\)/mg;
-		dojoContents = dojoContents.replace(provideRegExp, function(s, p1){
-			if(p1){
-				var ret = "";
-				p1 = p1.slice(1, -1); // trim the " or ' chars
-				var splits = p1.split(".");
-				splits.forEach(function(i, idx, a){
-					var simpleShortName = a.slice(0, idx+1).join(".");
-					var shortName = a[0];
-					for(var x=1; x<(idx+1); x++){
-						if(a[x].indexOf("-") >= 0){
-							shortName += '["'+a[x]+'"]';
-						}else{
-							shortName += "."+a[x];
-						}
-					}
-					// make sure that if, in a given module, we've already seen a
-					// parent that we don't re-generate its stub detection
-					if(!seenProvides[simpleShortName]){
-						seenProvides[simpleShortName] = true;
-						if(idx == 0){
-							ret += 'if(typeof ' + shortName + '=="undefined"){' + shortName + '={};};';
-						}else{
-							ret += shortName+'='+shortName+'||{};';
-						}
-					}
-					// at the last one?
-					if(idx == (a.length-1)){
-						// register in _loadedModules:
-						ret += 'dojo._loadedModules["'+simpleShortName+'"] = '+shortName+';';
-					}
-				});
-				return ret;
-			}else{
-				return s;
-			}
-		});
-	}
-
-	//Set version number.
-	dojoContents = buildUtil.changeVersion(version, dojoContents);
-
-	return dojoContents; //String
-}
-
-buildUtil.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.
-	
-	//Set version number.
-	//First, break apart the version string.
-	var verSegments = version.match(/^(\d*)\.?(\d*)\.?(\d*)\.?(.*)$/);
-	var majorValue = verSegments[1] || 0;
-	var minorValue = verSegments[2] || 0;
-	var patchValue = verSegments[3] || 0;
-	var flagValue  = verSegments[4] || "";
-
-	//Do the final version replacement.
-	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 + "\","
-	);
-
-	return fileContents; //String
-}
-
-buildUtil.makeDojoJs = function(/*Object*/dependencyResult, /*String*/version, /*Object?*/kwArgs){
-	//summary: Makes the uncompressed contents for dojo.js using the object
-	//returned from buildUtil.getDependencyList()
-
-	var lineSeparator = fileUtil.getLineSeparator();
-
-	//Cycle through the layers to create the content for each layer.
-	for(var i = 0; i< dependencyResult.length; i++){
-		var layerResult = dependencyResult[i];
-		layerResult.contents = buildUtil.createLayerContents(layerResult.layerName, layerResult.resourceName, layerResult.depList, layerResult.provideList, version, kwArgs);
-	}
-
-	//Object with properties:
-	//depList: Array of file paths (src/io/js)
-	//provideList: Array of module resource names (dojo.io)
-	//name: name of the layer file
-	//contents: the file contents for that layer file.
-	return dependencyResult;
-
-	//Return the dependency list, since it is used for other things in the ant file.
-	return {
-		resourceDependencies: depList,
-		dojoContents: dojoContents
-	};
-}
-
-
-buildUtil.getDependencyPropertyFromProfile = function(/*String*/profileFile, /*String*/propName){
-	//summary: Gets a dependencies property from the profile file. The value
-	//of the property is assumed to be an array. An array will always be returned,
-	//but it may be an empty array.
-
-	//Use new String to make sure we have a JS string (not a Java string)
-	var profileText = fileUtil.readFile(profileFile);
-	//Get rid of CR and LFs since they seem to mess with the regexp match.
-	//Using the "m" option on the regexp was not enough.
-	profileText = profileText.replace(/\r/g, "");
-	profileText = profileText.replace(/\n/g, "");
-
-
-	var result = [];
-	var matchRegExp = new RegExp("(dependencies\\." + propName + "\\s*=\\s*\\[[^;]*\\s*\\])", "m");
-
-	var matches = profileText.match(matchRegExp);
-	//Create a shell object to hold the evaled properties.
-	var dependencies = {};
-	
-	if(matches && matches.length > 0){
-		eval(matches[0]);
-		if(dependencies && dependencies[propName] && dependencies[propName].length > 0){
-			result = dependencies[propName];
-		}
-	}
-
-	return result; //Array
-}
-
-buildUtil.configPrefixes = function(/*Object*/prefixes){
-	//summary: Registers the prefixes with Dojo.
-	if(prefixes && prefixes.length > 0){
-		for(i = 0; i < prefixes.length; i++){
-			dojo.registerModulePath(prefixes[i][0], prefixes[i][1]);
-		}
-	}
-}
-
-
-//The regular expressions that will help find dependencies in the file contents.
-buildUtil.masterDependencyRegExpString = "dojo.(requireLocalization|require|requireIf|provide|requireAfterIf|platformRequire|i18n\._preloadLocalizations)\\s*\\(([\\w\\W]*?)\\)";
-buildUtil.globalDependencyRegExp = new RegExp(buildUtil.masterDependencyRegExpString, "mg");
-buildUtil.dependencyPartsRegExp = new RegExp(buildUtil.masterDependencyRegExpString);
-
-buildUtil.mapPathToResourceName = function(pathName, prefixes){
-	//summary: converts a path name to the best fit for a resource name
-	//based on the available prefixes.
-	//Returns a value like "foo.bar" given an input of /some/path/to/foo/bar.js"
-
-	//First, find best fit prefix.
-	var bestPrefix = "";
-	var bestPrefixPath = "";
-	var bestPrefixPathIndex = 0;
-	var currentIndex = 0;
-	for(var i = 0; i < prefixes.length; i++){
-		//Prefix path must match somewhere in the pathName
-		currentIndex = pathName.lastIndexOf("/" + prefixes[i][0].replace(/\./g, "/") + "/");
-		if(currentIndex != -1 && currentIndex > bestPrefixPathIndex){
-			bestPrefix = prefixes[i][0];
-			bestPrefixPath = prefixes[i][1];
-			bestPrefixPathIndex = currentIndex;
-		}
-	}
-	
-	//Adjust the bestPrefixPathIndex by 2, to account for the slashes in the test above.
-	bestPrefixPathIndex += 2;
-	
-	if(!bestPrefix){
-		throw "Could not find a matching prefix for pathName: " + pathName;
-	}
-	
-	//Strip off first part of file name that is not relevant.
-	var startIndex = bestPrefixPathIndex + bestPrefix.length;
-	var newPathName = pathName.substring(startIndex, pathName.length);
-	
-	//Remove file extensions and any front slash.
-	newPathName = newPathName.replace(/^\//, "").replace(/\..*?$/, "");
-	
-	return bestPrefix + "." + newPathName.replace(/\//g, ".");
-}
-
-buildUtil.mapResourceToPath = function(resourceName, prefixes){
-	//summary: converts a resourceName to a path.
-	//resourceName: String: like dojo.foo or mymodule.bar
-	//prefixes: Array: Actually an array of arrays. Comes from profile js file.
-	//          dependencies.prefixes = [["mymodule.foo", "../mymoduledir"]];
-	
-	var bestPrefix = "";
-	var bestPrefixPath = "";
-	if(prefixes){
-		for(var i = 0; i < prefixes.length; i++){
-			//Prefix must match from the start of the resourceName string.
-			if(resourceName.indexOf(prefixes[i][0]) == 0){
-				if(prefixes[i][0].length > bestPrefix.length){
-					bestPrefix = prefixes[i][0];
-					bestPrefixPath = prefixes[i][1];
-				}
-			}
-		}
-	}
-
-	//Get rid of matching prefix from resource name.
-	resourceName = resourceName.replace(bestPrefix, "");
-	
-	if(resourceName.charAt(0) == '.'){
-		resourceName = resourceName.substring(1, resourceName.length);
-	}
-	
-	resourceName = resourceName.replace(/\./g, "/");
-
-	var finalPath = bestPrefixPath;
-	if(finalPath.charAt(finalPath.length - 1) != "/"){
-		finalPath += "/";
-	}
-	if (resourceName){
-		finalPath += resourceName + "/";
-	}
-	
-	return finalPath;
-}
-
-buildUtil.makeResourceUri = function(resourceName, templatePath, srcRoot, prefixes){
-	var bestPrefix = "";
-	var bestPrefixPath = "";
-	if(prefixes){
-		for (var i = 0; i < prefixes.length; i++){
-			var prefix = prefixes[i];
-			//Prefix must match from the start of the resourceName string.
-			if(resourceName.indexOf(prefix[0]) == 0){
-				if(prefix[0].length > bestPrefix.length){
-					bestPrefix = prefix[0];
-					bestPrefixPath = prefix[1];
-				}
-			}
-		}
-
-		if(bestPrefixPath != ""){
-			//Convert resourceName to a path
-			resourceName = resourceName.replace(bestPrefix, "");
-			if(resourceName.indexOf(".") == 0){
-				resourceName = resourceName.substring(1, resourceName.length);
-			}
-			resourceName = resourceName.replace(/\./g, "/");
-
-			//Final path construction
-			var finalPath = bestPrefixPath + "/";
-			if(resourceName){
-				finalPath += resourceName + "/";
-			}
-			finalPath += templatePath;
-
-			return finalPath;
-		}
-	}
-
-	return srcRoot + templatePath;
-}
-
-buildUtil.internTemplateStrings = function(/*Object*/dependencies, /*String*/srcRoot, /*RegExp*/optimizeIgnoreRegExp){
-	//summary: interns strings in files for all .js files in the srcRoot directory.
-	var prefixes = dependencies["prefixes"] || [];
-	var skiplist = dependencies["internSkipList"] || [];
-
-	//Intern strings for all files in widget dir (xdomain and regular files)
-	var fileList = fileUtil.getFilteredFileList(srcRoot, /\.js$/, true);
-	if(fileList){
-		for(var i = 0; i < fileList.length; i++){
-			//Skip nls directories.
-			var fileName = fileList[i];
-			if(!fileName.match(/\/nls\//) && !fileName.match(optimizeIgnoreRegExp)){
-				buildUtil.internTemplateStringsInFile(fileList[i], srcRoot, prefixes, skiplist);
-			}
-		}
-	}
-}
-
-buildUtil.internTemplateStringsInFile = function(resourceFile, srcRoot, prefixes, skiplist){
-	var resourceContent = fileUtil.readFile(resourceFile);
-	resourceContent = buildUtil.interningRegexpMagic(resourceFile, resourceContent, srcRoot, prefixes, skiplist);
-	fileUtil.saveUtf8File(resourceFile, resourceContent);
-}
-
-buildUtil.interningDojoUriRegExpString = "(((templatePath|templateCssPath)\\s*(=|:)\\s*)dojo\\.(module)?Url\\(|dojo\\.cache\\s*\\(\\s*)\\s*?[\\\"\\']([\\w\\.\\/]+)[\\\"\\'](([\\,\\s]*)[\\\"\\']([\\w\\.\\/-]*)[\\\"\\'])?(\\s*,\\s*)?([^\\)]*)?\\s*\\)";
-buildUtil.interningGlobalDojoUriRegExp = new RegExp(buildUtil.interningDojoUriRegExpString, "g");
-buildUtil.interningLocalDojoUriRegExp = new RegExp(buildUtil.interningDojoUriRegExpString);
-
-buildUtil.interningRegexpMagic = function(resourceFile, resourceContent, srcRoot, prefixes, skiplist){
-	var shownFileName = false;
-
-	return resourceContent.replace(buildUtil.interningGlobalDojoUriRegExp, function(matchString){
-		var parts = matchString.match(buildUtil.interningLocalDojoUriRegExp);
-
-		var filePath = "";
-		var resourceNsName = "";
-
-		if(!shownFileName){
-			logger.trace("Interning strings for : " + resourceFile);
-			shownFileName = true;
-		}
-
-		//logger.trace("Module match: " + parts[6] + " and " + parts[9]);
-		filePath = buildUtil.makeResourceUri(parts[6], parts[9], srcRoot, prefixes);
-		resourceNsName = parts[6] + ':' + parts[9];
-
-		if(!filePath || buildUtil.isValueInArray(resourceNsName, skiplist)){
-			logger.trace("    skipping " + filePath);
-		}else{
-			logger.trace("    " + filePath);
-			//buildUtil.jsEscape will add starting and ending double-quotes.
-			var jsEscapedContent = buildUtil.jsEscape(fileUtil.readFile(filePath));
-			if(jsEscapedContent){
-				if(matchString.indexOf("dojo.cache") != -1){
-					//Handle dojo.cache-related interning.
-					var endContent = parts[11];
-					if(!endContent){
-						endContent = jsEscapedContent;
-					}else{
-						var braceIndex = endContent.indexOf("{");
-						if(braceIndex != -1){
-							endContent = endContent.substring(0, braceIndex + 1)
-								+ 'value: ' + jsEscapedContent + ','
-								+ endContent.substring(braceIndex + 1, endContent.length);
-						}
-					}
-					matchString = 'dojo.cache("' + parts[6] + '", "' + parts[9] + '", ' + endContent + ')';
-				}else{
-					//Handle templatePath/templateCssPath-related interning.
-					if(parts[3] == "templatePath"){
-						//Replace templatePaths
-						matchString = "templateString" + parts[4] + jsEscapedContent;
-					}else{
-						//Dealing with templateCssPath
-						//For the CSS we need to keep the template path in there
-						//since the widget loading stuff uses the template path to
-						//know whether the CSS has been processed yet.
-						//Could have matched assignment via : or =. Need different statement separators at the end.
-						var assignSeparator = parts[4];
-						var statementSeparator = ",";
-						var statementPrefix = "";
-			
-						//FIXME: this is a little weak because it assumes a "this" in front of the templateCssPath
-						//when it is assigned using an "=", as in 'this.templateCssPath = dojo.uri.dojoUri("some/path/to/Css.css");'
-						//In theory it could be something else, but in practice it is not, and it gets a little too weird
-						//to figure out, at least for now.
-						if(assignSeparator == "="){
-							statementSeparator = ";";
-							statementPrefix = "this.";
-						}
-						matchString = "templateCssString" + assignSeparator + jsEscapedContent + statementSeparator + statementPrefix + parts[0];
-					}
-				}
-			}
-		}
-
-		return matchString;
-	});
-}
-
-buildUtil.regExpEscape = function(/*String*/value){
-	//summary: Makes sure regexp-sensitive characters in a string are escaped correctly.
-	return value.replace(/([\.\*\/])/g, "\\$1");
-}
-
-buildUtil.jsEscape = function(/*string*/str){
-//summary:
-//	Adds escape sequences for non-visual characters, double quote and backslash
-//	and surrounds with double quotes to form a valid string literal.
-//	Take from the old dojo.string.escapeString code.
-//	Include it here so we don't have to load dojo.
-	return ('"' + str.replace(/(["\\])/g, '\\$1') + '"'
-		).replace(/[\f]/g, "\\f"
-		).replace(/[\b]/g, "\\b"
-		).replace(/[\n]/g, "\\n"
-		).replace(/[\t]/g, "\\t"
-		).replace(/[\r]/g, "\\r"); // string
-}
-
-buildUtil.isValueInArray = function(/*Object*/value, /*Array*/ary){
-	//summary: sees if value is in the ary array. Uses == to see if the
-	//array item matches value.
-	for(var i = 0; i < ary.length; i++){
-		if(ary[i] == value){
-			return true; //boolean
-		}
-	}
-	return false; //boolean
-}
-
-buildUtil.convertArrayToObject = function(/*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
-}
-
-buildUtil.optimizeJs = function(/*String fileName*/fileName, /*String*/fileContents, /*String*/copyright, /*String*/optimizeType, /*String*/stripConsole){
-	//summary: either strips comments from string or compresses it.
-	copyright = copyright || "";
-
-	// understand stripConsole from dojo 1.3 and before
-	if (stripConsole == "none") {
-		stripConsole = undefined;
-	} else if (stripConsole == "normal,warn") {
-		//logger.info("Converting stripConsole "normal,warn" to \"warn\"
-		logger.warn("stripConsole value \"normal,warn\" replaced with \"warn\".  Please update your build scripts.");
-		stripConsole = "warn";
-	} else if (stripConsole == "normal,error") {
-		logger.warn("stripConsole value \"normal,error\" replaced with \"all\".  Please update your build scripts.");
-		stripConsole = "all";
-	}
-
-	// sanity check stripConsole
-	if (stripConsole != undefined && !stripConsole.match(/normal|warn|all/)) {
-		throw "Invalid stripConsole provided (" + stripConsole + ")";
-	}
-	if (stripConsole == undefined) {
-		// java will receive undefined as "undefined" but null as null.
-		stripConsole = null;
-	}
-
-	//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(optimizeType.indexOf("shrinksafe") == 0 || optimizeType == "packer"){
-			//Apply compression using custom compression call in Dojo-modified rhino.
-			fileContents = new String(Packages.org.dojotoolkit.shrinksafe.Compressor.compressScript(fileContents, 0, 1, stripConsole));
-			if(optimizeType.indexOf(".keepLines") == -1){
-				fileContents = fileContents.replace(/[\r\n]/g, "");
-			}
-		}else if(optimizeType.indexOf("closure") == 0){
-			var jscomp = com.google.javascript.jscomp;
-			var flags = com.google.common.flags;
-
-			//Fake extern
-			var externSourceFile = buildUtil.closurefromCode("fakeextern.js", " ");
-
-			//Set up source input
-			var jsSourceFile = buildUtil.closurefromCode(String(fileName), String(fileContents));
-		
-			//Set up options
-			var options = new jscomp.CompilerOptions();
-			options.prettyPrint = optimizeType.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);
-			result = compiler.compile(externSourceFile, jsSourceFile, options);
-			fileContents = compiler.toSource();
-		}else if(optimizeType == "comments"){
-			//Strip comments
-			var script = context.compileString(fileContents, fileName, 1, null);
-			fileContents = new String(context.decompileScript(script, 0));
-			
-			//Replace the spaces with tabs.
-			//Ideally do this in the pretty printer rhino code.
-			fileContents = fileContents.replace(/    /g, "\t");
-
-			//If this is an nls bundle, make sure it does not end in a ;
-			//Otherwise, bad things happen.
-			if(fileName.match(/\/nls\//)){
-				fileContents = fileContents.replace(/;\s*$/, "");
-			}
-		}
-	}finally{
-		Packages.org.mozilla.javascript.Context.exit();
-	}
-
-
-	return copyright + fileContents;
-}
-
-
-buildUtil.setupPacker = function(){
-	// no-op.
-}
-
-buildUtil.optimizeJsDir = function(/*String*/startDir, /*RegeExp*/optimizeIgnoreRegExp, /*String?*/copyrightText, /*String?*/optimizeType, /*String?*/stripConsole){
-	//summary: strips the JS comments from all the files in "startDir", and all subdirectories.
-	//Also runs shrinksafe minification, and console call removal.
-	var copyright = (copyrightText || fileUtil.readFile("copyright.txt")) + fileUtil.getLineSeparator();
-	var fileList = fileUtil.getFilteredFileList(startDir, /\.js$/, true);
-	
-	var messageType = optimizeType;
-	if(stripConsole){
-		messageType += (optimizeType ? ", " : "") + "stripConsole=" + stripConsole;
-	}
-
-	if(fileList){
-		for(var i = 0; i < fileList.length; i++){
-			//Don't process dojo.js since it has already been processed.
-			//Don't process dojo.js.uncompressed.js because it is huge.
-			//Don't process anything that might be in a buildscripts folder (only a concern for webbuild.sh)
-			if(!fileList[i].match(optimizeIgnoreRegExp)
-				&& !fileList[i].match(/buildscripts/)
-				&& !fileList[i].match(/nls/)
-				&& !fileList[i].match(/tests\//)){
-
-				if(messageType){
-					logger.trace("Optimizing (" + messageType + ") file: " + fileList[i]);
-				}
-
-				//Read in the file. Make sure we have a JS string.
-				var fileContents = fileUtil.readFile(fileList[i]);
-
-				//Do comment removal.
-				if(optimizeType){
-					try{
-						fileContents = buildUtil.optimizeJs(fileList[i], fileContents, copyright, optimizeType, stripConsole);
-					}catch(e){
-						logger.error("Could not strip comments for file: " + fileList[i] + ", error: " + e);
-					}
-				}else{
-					//Just apply copyright.
-					fileContents = copyright + fileContents;
-				}
-
-				//Write out the file with appropriate copyright.
-				fileUtil.saveUtf8File(fileList[i], fileContents);
-			}
-		}
-	}
-}
-
-buildUtil.optimizeCss = function(/*String*/startDir, /*String*/optimizeType, /*String?*/cssImportIgnore){
-	//summmary: Optimizes CSS files in a directory.
-	
-	if(optimizeType.indexOf("comments") != -1){
-		//Make sure we have a delimited ignore list to make matching faster
-		if(cssImportIgnore){
-			cssImportIgnore = cssImportIgnore + ",";
-		}
-
-		var fileList = fileUtil.getFilteredFileList(startDir, /\.css$/, true);
-		if(fileList){
-			for(var i = 0; i < fileList.length; i++){
-				var fileName = fileList[i];
-				logger.trace("Optimizing (" + optimizeType + ") CSS file: " + fileName);
-				
-				//Read in the file. Make sure we have a JS string.
-				var originalFileContents = fileUtil.readFile(fileName);
-				var fileContents = buildUtil.flattenCss(fileName, originalFileContents, cssImportIgnore);
-
-				//Do comment removal.
-				try{
-					var startIndex = -1;
-					//Get rid of comments.
-					while((startIndex = fileContents.indexOf("/*")) != -1){
-						var endIndex = fileContents.indexOf("*/", startIndex + 2);
-						if(endIndex == -1){
-							throw "Improper comment in CSS file: " + fileName;
-						}
-						fileContents = fileContents.substring(0, startIndex) + fileContents.substring(endIndex + 2, fileContents.length);
-					}
-					//Get rid of newlines.
-					if(optimizeType.indexOf(".keepLines") == -1){
-						fileContents = fileContents.replace(/[\r\n]/g, "");
-						fileContents = fileContents.replace(/\s+/g, " ");
-						fileContents = fileContents.replace(/\{\s/g, "{");
-						fileContents = fileContents.replace(/\s\}/g, "}");
-					}else{
-						//Remove multiple empty lines.
-						fileContents = fileContents.replace(/(\r\n)+/g, "\r\n");
-						fileContents = fileContents.replace(/(\n)+/g, "\n");
-					}
-				}catch(e){
-					fileContents = originalFileContents;
-					logger.error("Could not optimized CSS file: " + fileName + ", error: " + e);
-				}
-	
-				//Write out the file with appropriate copyright.
-				fileUtil.saveUtf8File(fileName, fileContents);
-			}
-		}
-	}
-}
-
-buildUtil.backSlashRegExp = /\\/g;
-buildUtil.cssImportRegExp = /\@import\s+(url\()?\s*([^);]+)\s*(\))?([\w, ]*)(;)?/g;
-buildUtil.cssUrlRegExp = /\url\(\s*([^\)]+)\s*\)?/g;
-
-buildUtil.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.
-
-	//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) == "\""){
-		url = url.substring(1, url.length - 1);
-	}
-
-	return url;
-}
-
-buildUtil.flattenCss = function(/*String*/fileName, /*String*/fileContents, /*String?*/cssImportIgnore){
-	//summary: inlines nested stylesheets that have @import calls in them.
-
-	//Find the last slash in the name.
-	fileName = fileName.replace(buildUtil.backSlashRegExp, "/");
-	var endIndex = fileName.lastIndexOf("/");
-
-	//Make a file path based on the last slash.
-	//If no slash, so must be just a file name. Use empty string then.
-	var filePath = (endIndex != -1) ? fileName.substring(0, endIndex + 1) : "";
-
-	return fileContents.replace(buildUtil.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;
-		}
-
-		importFileName = buildUtil.cleanCssUrlQuotes(importFileName);
-		
-		//Ignore the file import if it is part of an ignore list.
-		if(cssImportIgnore && cssImportIgnore.indexOf(importFileName + ",") != -1){
-			return fullMatch;
-		}
-
-		//Make sure we have a unix path for the rest of the operation.
-		importFileName = importFileName.replace(buildUtil.backSlashRegExp, "/");
-
-		try{
-			//if a relative path, then tack on the filePath.
-			//If it is not a relative path, then the readFile below will fail,
-			//and we will just skip that import.
-			var fullImportFileName = importFileName.charAt(0) == "/" ? importFileName : filePath + importFileName;
-			var importContents = fileUtil.readFile(fullImportFileName);
-
-			//Make sure to flatten any nested imports.
-			importContents = buildUtil.flattenCss(fullImportFileName, importContents);
-			
-			//Make the full import path
-			var importEndIndex = importFileName.lastIndexOf("/");
-
-			//Make a file path based on the last slash.
-			//If no slash, so must be just a file name. Use empty string then.
-			var importPath = (importEndIndex != -1) ? importFileName.substring(0, importEndIndex + 1) : "";
-
-			//Modify URL paths to match the path represented by this file.
-			importContents = importContents.replace(buildUtil.cssUrlRegExp, function(fullMatch, urlMatch){
-				var fixedUrlMatch = buildUtil.cleanCssUrlQuotes(urlMatch);
-				fixedUrlMatch = fixedUrlMatch.replace(buildUtil.backSlashRegExp, "/");
-
-				//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 = importPath + fixedUrlMatch;
-				}else{
-					logger.trace(importFileName + "\n  URL not a relative URL, skipping: " + urlMatch);
-				}
-
-				//Collapse .. and .
-				var parts = urlMatch.split("/");
-				for(var i = parts.length - 1; i > 0; i--){
-					if(parts[i] == "."){
-						parts.splice(i, 1);
-					}else if(parts[i] == ".."){
-						if(i != 0 && parts[i - 1] != ".."){
-							parts.splice(i - 1, 2);
-							i -= 1;
-						}
-					}
-				}
-
-				return "url(" + parts.join("/") + ")";
-			});
-
-			return importContents;
-		}catch(e){
-			logger.trace(fileName + "\n  Cannot inline css import, skipping: " + importFileName);
-			return fullMatch;
-		}
-	});
-}
-
-buildUtil.guardProvideRegExpString = "dojo\\s*\\.\\s*provide\\s*\\(\\s*([\\'\\\"][^\\'\\\"]*[\\'\\\"])\\s*\\)";
-buildUtil.guardProvideRegExp = new RegExp(buildUtil.guardProvideRegExpString);
-buildUtil.guardProvideRegExpGlobal = new RegExp(buildUtil.guardProvideRegExpString, "g");
-
-buildUtil.addGuardsAndBaseRequires = function(/*String || Array*/startDir, /*Boolean*/needBaseRequires){
-	//summary: adds a definition guard around code in a file to protect
-	//against redefinition cases when layered builds are used. Also injects
-	//dojo._base require calls if needBaseRequires is true. Accepts a string
-	//of the start directory to use, or an array of file name strings to process.
-	var lineSeparator = fileUtil.getLineSeparator();
-
-	var fileList = startDir;
-	if(fileList instanceof String){
-		fileList = fileUtil.getFilteredFileList(fileList, /\.js$/, true);
-	}else{
-		//Make sure we only process .js files
-		for(var i = fileList.length - 1; i >= 0; i--){
-			if(!fileList[i].match(/\.js$/)){
-				fileList.splice(i, 1);
-			}
-		}
-	}
-
-	if(fileList){
-		for(i = 0; i < fileList.length; i++){
-			var fileContents = fileUtil.readFile(fileList[i]);
-			
-			//See if we need to inject dojo._base require calls.
-			//Do not process _base.js since it already has the require calls in there.
-			if(needBaseRequires
-				&& fileList[i].indexOf("/tests/") == -1
-				&& fileList[i].indexOf("/demos/") == -1
-				&& fileList[i].indexOf("/themes/") == -1
-				&& fileList[i].indexOf("dojo/_base.js") == -1){
-				buildUtil.baseMappingRegExp.lastIndex = 0;
-				var matches = null;
-				
-				//Strip out comments to get a better picture.
-				var tempContents = buildUtil.removeComments(fileContents);
-				
-				//Find where we can place the new require calls. This should be after
-				//any dojo.provide calls, so we do not hit a weird problem with a circular dependency
-				//that does not get resolved since the dojo.provide call does not fire indicating
-				//the file has been loaded.
-				buildUtil.guardProvideRegExpGlobal.lastIndex = 0;
-				var lastPosition = -1;
-				while((matches = buildUtil.guardProvideRegExpGlobal.exec(fileContents))){
-					lastPosition = buildUtil.guardProvideRegExpGlobal.lastIndex;
-				}
-				
-				//If no dojo.provide calls found, do not bother with the file.
-				if(lastPosition != -1){
-					var contentChunks = [
-						fileContents.substring(0, lastPosition + 1) + "\n",
-						fileContents.substring(lastPosition + 1, fileContents.length)
-					];
-					
-					var addedResources = {};
-					while((matches = buildUtil.baseMappingRegExp.exec(tempContents))){
-						var baseResource = buildUtil.baseMappings[matches[1]];
-						//Make sure we do not add the dependency to its source resource.
-						if(!addedResources[baseResource] && fileList[i].indexOf("_base/" + baseResource) == -1){
-							logger.trace("Adding dojo._base." + baseResource + " because of match: " + matches[1] + " to file: " + fileList[i]);
-							contentChunks[0] += 'dojo.require("dojo._base.' + baseResource + '");\n';
-							addedResources[baseResource] = true;
-						}
-					}
-					
-					fileContents = contentChunks.join("");
-				}
-			}
-
-			buildUtil.guardProvideRegExp.lastIndex = 0;
-			var match = buildUtil.guardProvideRegExp.exec(fileContents);
-			if(match){
-				//Only add the guard if there is not already one in the file.
-				var existingGuardRegExp = new RegExp('if\\(\\!dojo\\._hasResource\\[' + match[1] + '\\]\\)');
-				if(!fileContents.match(existingGuardRegExp)){
-					fileContents = 'if(!dojo._hasResource[' + match[1] + ']){ //_hasResource checks added by build. Do not use _hasResource directly in your code.'
-						+ lineSeparator
-						+ 'dojo._hasResource[' + match[1] + '] = true;'
-						+ lineSeparator
-						+ fileContents
-						+ lineSeparator
-						+ '}'
-						+ lineSeparator;
-	
-					fileUtil.saveUtf8File(fileList[i], fileContents);
-				}
-			}
-		}
-	}
-}
-
-//TODO: generate this via an algorithm.
-buildUtil.baseMappings = {
-	"trim": "lang",
-	"clone": "lang",
-	"_toArray": "lang",
-	"partial": "lang",
-	"delegate": "lang",
-	"_delegate": "lang",
-	"hitch": "lang",
-	"_hitchArgs": "lang",
-	"extend": "lang",
-	"isAlien": "lang",
-	"isArrayLike": "lang",
-	"isObject": "lang",
-	"isFunction": "lang",
-	"isArray": "lang",
-	"isString": "lang",
-	
-	"declare": "declare",
-	
-	"subscribe": "connect",
-	"unsubscribe": "connect",
-	"publish": "connect",
-	"connectPublisher": "connect",
-	
-	"Deferred": "Deferred",
-	
-	"fromJson": "json",
-	"_escapeString": "json",
-	"toJson": "json",
-	
-	"indexOf": "array",
-	"lastIndexOf": "array",
-	"forEach": "array",
-	"every": "array",
-	"some": "array",
-	"map": "array",
-	"filter": "array",
-	
-	"Color": "Color",
-	"blendColors": "Color",
-	"colorFromRgb": "Color",
-	"colorFromHex": "Color",
-	"colorFromArray": "Color",
-	"colorFromString": "Color",
-
-	"doc": "window",
-	"body": "window",
-	"setContext": "window",
-	"_fireCallback": "window",
-	"withGlobal": "window",
-	"withDoc": "window",
-	
-	"connect": "event",
-	"disconnect": "event",
-	"fixEvent": "event",
-	"stopEvent": "event",
-	"_connect": "event",
-	"_disconnect": "event",
-	"_ieDispatcher": "event",
-	"_getIeDispatcher": "event",
-	
-	"byId": "html",
-	"destroy": "html",
-	"_destroyElement": "html",
-	"isDescendant": "html",
-	"setSelectable": "html",
-	"place": "html",
-	"getComputedStyle": "html",
-	"_toPixelValue": "html",
-	"_getOpacity": "html",
-	"_setOpacity": "html",
-	"style": "html",
-	"_getPadExtents": "html",
-	"_getBorderExtents": "html",
-	"_getPadBorderExtents": "html",
-	"_getMarginExtents": "html",
-	"_getMarginBox": "html",
-	"_getContentBox": "html",
-	"_getBorderBox": "html",
-	"_setBox": "html",
-	"_usesBorderBox": "html",
-	"_setContentSize": "html",
-	"_setMarginBox": "html",
-	"marginBox": "html",
-	"contentBox": "html",
-	"_docScroll": "html",
-	"_isBodyLtr": "html",
-	"_getIeDocumentElementOffset": "html",
-	"_fixIeBiDiScrollLeft": "html",
-	"_abs": "html",
-	"coords": "html",
-	"hasAttr": "html",
-	"attr": "html",
-	"removeAttr": "html",
-	"create": "html",
-	"empty": "html",
-	"_toDom": "html",
-	"hasClass": "html",
-	"addClass": "html",
-	"removeClass": "html",
-	"toggleClass": "html",
-	
-	"NodeList": "NodeList",
-	
-	"_filterQueryResult": "query",
-	"query": "query",
-	
-	"formToObject": "xhr",
-	"objectToQuery": "xhr",
-	"formToQuery": "xhr",
-	"formToJson": "xhr",
-	"queryToObject": "xhr",
-	"_ioSetArgs": "xhr",
-	"_ioCancelAll": "xhr",
-	"_ioAddQueryToUrl": "xhr",
-	"xhr": "xhr",
-	"xhrGet": "xhr",
-	"rawXhrPost": "xhr",
-	"rawXhrPut": "xhr",
-	"xhrDelete": "xhr",
-	"wrapForm": "xhr",
-	
-	"_Line": "fx",
-	"_Animation": "fx",
-	"Animation":"fx",
-	"_fade": "fx",
-	"fadeIn": "fx",
-	"fadeOut": "fx",
-	"_defaultEasing": "fx",
-	"animateProperty": "fx",
-	"anim": "fx"
-};
-
-(function(){
-	var names = "(";
-	for(var param in buildUtil.baseMappings){
-		if(names != "("){
-			names += "|";
-		}
-		names += param;
-	}
-	names += ")";
-	
-	buildUtil.baseMappingRegExp = new RegExp("\\." + names + "\\W", "g");
-})();
-
-buildUtil.processConditionalsForDir = function(/*String*/startDir, /*RegExp*/layerIgnoreRegExp, /*Object*/kwArgs){
-	//summary: processes build conditionals for a directory, but ignores files in the layerIgnoreRegExp argument.
-	var fileList = fileUtil.getFilteredFileList(startDir, /\.js$/, true);
-	if(fileList){
-		for(var i = 0; i < fileList.length; i++){
-			//Skip nls directories.
-			var fileName = fileList[i];
-			if(!fileName.match(layerIgnoreRegExp)){
-				var fileContents = fileUtil.readFile(fileName);
-				if(fileContents.indexOf("//>>") != -1){
-					fileUtil.saveFile(fileName, buildUtil.processConditionals(fileName, fileContents, kwArgs));
-				}
-			}
-		}
-	}
-}
-
-buildUtil.conditionalRegExp = /(exclude|include)Start\s*\(\s*["'](\w+)["']\s*,(.*)\)/;
-buildUtil.processConditionals = function(/*String*/fileName, /*String*/fileContents, /*Object*/kwArgs){
-	//summary: processes the fileContents for some Dojo-specific conditional comments.
-	var foundIndex = -1;
-	var startIndex = 0;
-	
-	while((foundIndex = fileContents.indexOf("//>>", startIndex)) != -1){
-		//Found a conditional. Get the conditional line.
-		var lineEndIndex = fileContents.indexOf("\n", foundIndex);
-		if(lineEndIndex == -1){
-			lineEndIndex = fileContents.length - 1;
-		}
-
-		//Increment startIndex past the line so the next conditional search can be done.
-		startIndex = lineEndIndex + 1;
-
-		//Break apart the conditional.
-		var conditionLine = fileContents.substring(foundIndex, lineEndIndex + 1);
-		var matches = conditionLine.match(buildUtil.conditionalRegExp);
-		if(matches){
-			var type = matches[1];
-			var marker = matches[2];
-			var condition = matches[3];
-			var isTrue = false;
-			//See if the condition is true.
-			try{
-				isTrue = !!eval("(" + condition + ")");
-			}catch(e){
-				throw "Error in file: "
-					+ fileName
-					+ ". Conditional comment: "
-					+ conditionLine
-					+ " failed with this error: " + e;
-			}
-		
-			//Find the endpoint marker.
-			var endRegExp = new RegExp('\\/\\/\\>\\>\\s*' + type + 'End\\(\\s*[\'"]' + marker + '[\'"]\\s*\\)', "g");
-			var endMatches = endRegExp.exec(fileContents.substring(startIndex, fileContents.length));
-			if(endMatches){
-				
-				var endMarkerIndex = startIndex + endRegExp.lastIndex - endMatches[0].length;
-				
-				//Find the next line return based on the match position.
-				lineEndIndex = fileContents.indexOf("\n", endMarkerIndex);
-				if(lineEndIndex == -1){
-					lineEndIndex = fileContents.length - 1;
-				}
-
-				//Should we include the segment?
-				var shouldInclude = ((type == "exclude" && !isTrue) || (type == "include" && isTrue));
-				
-				//Remove the conditional comments, and optionally remove the content inside
-				//the conditional comments.
-				var startLength = startIndex - foundIndex;
-				fileContents = fileContents.substring(0, foundIndex)
-					+ (shouldInclude ? fileContents.substring(startIndex, endMarkerIndex) : "")
-					+ fileContents.substring(lineEndIndex + 1, fileContents.length);
-				
-				//Move startIndex to foundIndex, since that is the new position in the file
-				//where we need to look for more conditionals in the next while loop pass.
-				startIndex = foundIndex;
-			}else{
-				throw "Error in file: "
-					+ fileName
-					+ ". Cannot find end marker for conditional comment: "
-					+ conditionLine;
-				
-			}
-		}
-	}
-
-	return fileContents;
-}
-
-buildUtil.setScopeDjConfig = function(/*String*/fileContents, /*String*/djConfigString){
-	//summary: burns in a local djConfig for the file contents.
-	//djConfigString should be a string.
-	//Have to use eval to avoid name condensing by shrinksafe.
-	return fileContents.replace(/\/\*\*Build will replace this comment with a scoped djConfig \*\*\//, 'eval("var djConfig = ' + djConfigString.replace(/(['"])/g, '\\$1') + ';");');
-}
-
-buildUtil.setScopeNames = function(/*String*/fileContents, /*String*/scopeMap){
-	//summary: burns in the scope names into the file contents.
-	//scopeMap should be a [["name","value"],["name","value"]] string. Notice the lack of spaces.
-	//Single quotes can be used instead of double quotes.
-	return fileContents.replace(/var\s+sMap\s+=\s+null/, "var sMap = " + scopeMap);
-}
-
-buildUtil.symctr = 0;
-buildUtil.symtbl = null;
-buildUtil.generateSym = function(/*String*/name){
-	var m = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
-	var len = m.length;
-	var s;
-	if(buildUtil.symctr < len*len){
-		s = m.charAt(Math.floor(buildUtil.symctr/len))
-			+m.charAt(buildUtil.symctr%len);
-	}else{
-		s = m.charAt(Math.floor(buildUtil.symctr/(len*len))-1)
-			+m.charAt(Math.floor(buildUtil.symctr/len)%len)
-			+m.charAt(buildUtil.symctr%len);
-	}
-	s = "$D" + s;
-	buildUtil.symctr++;
-	var ret;
-	
-	//Make sure name is valid JS
-	name = name.replace(/-/g, "__");
-	if(kwArgs.symbol == "long"){
-		ret = name; // + "_" + s;
-	}else if(kwArgs.symbol == "short"){
-		buildUtil.symtbl[s + "_"] = name;
-		ret = s + "_";
-	}
-	return ret;
-}
-
-buildUtil.insertSymbols = function(/*String*/startDir, /*Object*/kwArgs){
-	//summary: add global function symbols to anonymous functions.
-	buildUtil.symtbl = {};
-	var fileList = fileUtil.getFilteredFileList(startDir, /\.js$/, true);
-	if(fileList){
-		logger.trace("Inserting global function symbols in: "+startDir);
-		for(var i = 0; i < fileList.length; i++){
-			//Don't process loader_debug.js since global symbols conflict with loader.js.
-			//Don't process dojo.js.uncompressed.js because it is huge.
-			//Don't process anything that might be in a buildscripts folder (only a concern for webbuild.sh)
-			if(!fileList[i].match(/loader_debug\.js/)
-				&& !fileList[i].match(/\.uncompressed\.js/)
-				&& !fileList[i].match(/buildscripts/)
-				&& !fileList[i].match(/nls/)
-				&& !fileList[i].match(/tests\//)){
-				
-				//Read in the file. Make sure we have a JS string.
-				var fileContents = fileUtil.readFile(fileList[i]);
-
-				//Do insertion.
-				var className;
-				if(fileContents.match(/dojo\.provide\("(.*)"\);/)){
-					className = RegExp.$1.replace(/\./g, "_")+"_";
-				}
-				if(className){
-					fileContents = fileContents.replace(/^(\s*)(\w+)(\s*:\s*function)\s*(\(.*)$/mg, function(str, p1, p2, p3, p4){
-						return p1+p2+p3+" "+buildUtil.generateSym(className+p2)+p4;
-					});
-					fileContents = fileContents.replace(/^(\s*this\.)(\w+)(\s*=\s*function)\s*(\(.*)$/mg, function(str, p1, p2, p3, p4){
-						return p1+p2+p3+" "+buildUtil.generateSym(className+p2)+p4;
-					});
-				}
-				fileContents = fileContents.replace(/^(\s*)([\w\.]+)(\s*=\s*function)\s*(\(.*)/mg, function(str, p1, p2, p3, p4){
-					return p1+p2+p3+" "+buildUtil.generateSym(p2.replace(/\./g, "_"))+p4;
-				});
-
-				//Write out the file
-				fileUtil.saveUtf8File(fileList[i], fileContents);
-			}
-		}
-
-		if(kwArgs.symbol == "short"){
-			var symbolText = "";
-			var lineSeparator = fileUtil.getLineSeparator();
-			for(var key in buildUtil.symtbl){
-				symbolText += key + ": \"" + buildUtil.symtbl[key] + "\"" + lineSeparator;
-			}
-			fileUtil.saveFile(startDir + "/symboltable.txt", symbolText);
-		}
-	}
-}
-
-buildUtil.extractMatchedParens = function(/*RegExp*/ regexp, /*String*/fileContents, /*Boolean*/removeTrailingComma){
-	//summary: Pass in a regexp that includes a start parens: (, and this function will
-	//find the matching end parens for that regexp, remove the matches from fileContents,
-	//and return an array where the first member of the array is the modified fileContents
-	//and the rest of the array members are the matches found. If no matches are found,
-	//then returns null.
-
-	//Extracts
-	regexp.lastIndex = 0;
-
-	var parenRe = /[\(\)]/g;
-	parenRe.lastIndex = 0;
-
-	var results = [],
-		matches,
-		cleanedContent = [],
-		previousLastIndex = 0
-	;
-	
-	while((matches = regexp.exec(fileContents))){
-		
-		//Find end of the call by finding the matching end paren
-		parenRe.lastIndex = regexp.lastIndex;
-		var matchCount = 1;
-		var parenMatch;
-		while((parenMatch = parenRe.exec(fileContents))){
-			if(parenMatch[0] == ")"){
-				matchCount -= 1;
-			}else{
-				matchCount += 1;
-			}
-			if(matchCount == 0){
-				break;
-			}
-		}
-
-		if(matchCount != 0){
-			throw "unmatched paren around character " + parenRe.lastIndex + " in: " + fileContents;
-		}
-
-		// Put the master matching string in the results.
-		var startIndex = regexp.lastIndex - matches[0].length;
-		results.push(fileContents.substring(startIndex, parenRe.lastIndex));
-		// add file's fragment from previous console.* match to current match
-		cleanedContent.push(fileContents.substring(previousLastIndex, startIndex));
-		
-		// Account for ending semicolon if desired.
-		var endPoint = parenRe.lastIndex;
-		if(removeTrailingComma && fileContents.charAt(endPoint) == ";"){
-			endPoint += 1;
-		}
-
-		previousLastIndex = regexp.lastIndex = endPoint;
-
-	}
-
-	// add the last matched fragment to the cleaned output
-	cleanedContent.push(fileContents.substring(previousLastIndex, fileContents.length));
-
-	if(results.length > 0){
-		results.unshift(cleanedContent.join(''));
-	}
-
-	return (results.length ? results : null);
-}
-
diff --git a/util/buildscripts/profiles/base.profile.js b/util/buildscripts/profiles/base.profile.js
index 66d5bfa..e7f7c3c 100644
--- a/util/buildscripts/profiles/base.profile.js
+++ b/util/buildscripts/profiles/base.profile.js
@@ -1 +1,3 @@
 //To build just Dojo base, you just need an empty file.
+dependencies= {
+};
diff --git a/util/buildscripts/profiles/cdn.profile.js b/util/buildscripts/profiles/cdn.profile.js
new file mode 100644
index 0000000..12e8f14
--- /dev/null
+++ b/util/buildscripts/profiles/cdn.profile.js
@@ -0,0 +1,6 @@
+require(["build/buildControlDefault"], function(bc){
+	bc.defaultConfig.async = "legacyAsync";
+	bc.defaultConfig.hasCache["dojo-cdn"] = 1;
+});
+var profile = {
+};
diff --git a/util/buildscripts/profiles/demos-all.profile.js b/util/buildscripts/profiles/demos-all.profile.js
index b38d01a..4ab48f5 100644
--- a/util/buildscripts/profiles/demos-all.profile.js
+++ b/util/buildscripts/profiles/demos-all.profile.js
@@ -2,13 +2,13 @@
 // repo for easy debugging. We are not to link to the demos in nightly in a static fashion, but rather use
 // this repo as a testing place for versioned demos to be pushed onto dojotoolkit.org
 dependencies = {
-	
+
 	action:"clean,release",
 	optimize:"shrinksafe",
 	cssOptimize:"comments.keepLines",
 	releaseName:"demosite",
 	mini:"false",
-	
+
 	layers: [
 		// standard:
 		{
@@ -26,9 +26,47 @@ dependencies = {
 				"dijit.dijit-all"
 			]
 		},
-			
+
 		// Here are the various demos with promotion:
 		{
+			name: "../demos/editor/layer.js",
+			dependencies: [
+				"dijit.layout.BorderContainer",
+				"dijit.layout.ContentPane",
+				"dijit.layout.AccordionContainer",
+				"dijit.layout.ContentPane",
+				"dojox.fx.text",
+				"dijit.Editor",
+				"dijit._editor.plugins.FullScreen",
+				"dijit._editor.plugins.LinkDialog",
+				"dijit._editor.plugins.Print",
+				"dijit._editor.plugins.ViewSource",
+				"dijit._editor.plugins.FontChoice",
+				"dijit._editor.plugins.NewPage",
+				"dijit._editor.plugins.ToggleDir",
+				"dojox.editor.plugins.ShowBlockNodes",
+				"dojox.editor.plugins.ToolbarLineBreak",
+				"dojox.editor.plugins.Save",
+				"dojox.editor.plugins.InsertEntity",
+				"dojox.editor.plugins.Preview",
+				"dojox.editor.plugins.PageBreak",
+				"dojox.editor.plugins.PrettyPrint",
+				"dojox.editor.plugins.NormalizeIndentOutdent",
+				"dojox.editor.plugins.FindReplace",
+				"dojox.editor.plugins.Breadcrumb",
+				"dojox.editor.plugins.TextColor",
+				"dojox.editor.plugins.CollapsibleToolbar",
+				"dojox.editor.plugins.Blockquote",
+				"dojox.editor.plugins.PasteFromWord",
+				"dojox.editor.plugins.InsertAnchor",
+				"dojox.editor.plugins.TablePlugins",
+				"dojox.editor.plugins.PasteFromWord",
+				"dojox.editor.plugins.Smiley",
+				"dojox.editor.plugins.NormalizeStyle",
+				"dojox.editor.plugins.StatusBar"
+			]
+		},
+		{
 			// the dojo.moj.oe demo
 			name: "../demos/mojo/src.js",
 			dependencies: [
@@ -97,15 +135,177 @@ dependencies = {
 				"demos.faces.src"
 			]
 		},
+        {
+        name: "../demos/mobileMvc/src.js",
+			dependencies:[
+				"demos.mobileMvc.src"
+			]
+		},
+		{
+			name: "../demos/mobileGauges/src.js",
+			dependencies:[
+				"demos.mobileGauges.src"
+			]
+		},
+		{
+			name: "../demos/mobileCharting/src.js",
+			dependencies:[
+				"demos.mobileCharting.src"
+			]
+		},
+		{
+			name: "../demos/mobileGeoCharting/src.js",
+			dependencies:[
+				"demos.mobileGeoCharting.src"
+			]
+		},
+		{
+			name: "../demos/mobileFileBrowser/src.js",
+			dependencies:[
+				"demos.mobileFileBrowser.src"
+			]
+		},
+		{
+			name: "../demos/mobileOpenLayers/src.js",
+			dependencies:[
+				"demos.mobileOpenLayers.src"
+			]
+		},
+		{
+			name: "../demos/mobileGallery/src.js",
+			dependencies:[
+				"demos.mobileGallery.src"
+			]
+		},
+		{
+			name: "../demos/touch/src.js",
+			dependencies:[
+				"demos.touch.src"
+			]
+		},
 		{
 			// the CSS3 animations demo
 			name: "../demos/css3/src.js",
 			dependencies:[
 				"demos.css3.src"
 			]
+		},
+		{
+			name: "../demos/bezier/src.js",
+			dependencies:[
+				"demos.bezier.src"
+			]
+		},
+		{
+			name: "../demos/butterfly/src.js",
+			dependencies:[
+				"demos.butterfly.src"
+			]
+		},
+		{
+			name: "../demos/chartTypes/src.js",
+			dependencies:[
+				"demos.chartTypes.src"
+			]
+		},
+		{
+			name: "../demos/clock/src.js",
+			dependencies:[
+				"demos.clock.src"
+			]
+		},
+		{
+			name: "../demos/drillDownChart/src.js",
+			dependencies:[
+				"demos.drillDownChart.src"
+			]
+		},
+		{
+			name: "../demos/dynamicChart/src.js",
+			dependencies:[
+				"demos.dynamicChart.src"
+			]
+		},
+		{
+			name: "../demos/gauges/src.js",
+			dependencies:[
+				"demos.gauges.src"
+			]
+		},
+		{
+			name: "../demos/gfxserialization/src.js",
+			dependencies:[
+				"demos.gfxserialization.src"
+			]
+		},
+		{
+			name: "../demos/grid/src.js",
+			dependencies:[
+				"demos.grid.src"
+			]
+		},
+		{
+			name: "../demos/mapTileProviders/src.js",
+			dependencies:[
+				"demos.mapTileProviders.src"
+			]
+		},
+		{
+			name: "../demos/mobileCatalog/src.js",
+			dependencies:[
+				"demos.mobileCatalog.src"
+			]
+		},
+		{
+			name: "../demos/mobileScrollableView/src.js",
+			dependencies:[
+				"demos.mobileScrollableView.src"
+			]
+		},
+		{
+			name: "../demos/mobileSlideShow/src.js",
+			dependencies:[
+				"demos.mobileSlideShow.src"
+			]
+		},
+		{
+			name: "../demos/mobileStockPortfolio/src.js",
+			dependencies:[
+				"demos.mobileStockPortfolio.src"
+			]
+		},
+		{
+			name: "../demos/pieChart/src.js",
+			dependencies:[
+				"demos.pieChart.src"
+			]
+		},
+		{
+			name: "../demos/shippingRoutes/src.js",
+			dependencies:[
+				"demos.shippingRoutes.src"
+			]
+		},
+		{
+			name: "../demos/spiderChart/src.js",
+			dependencies:[
+				"demos.spiderChart.src"
+			]
+		},
+		{
+			name: "../demos/sunMap/src.js",
+			dependencies:[
+				"demos.sunMap.src"
+			]
+		},
+		{
+			name: "../demos/themePreviewer/src.js",
+			dependencies:[
+				"demos.themePreviewer.src"
+			]
 		}
 	],
-	
+
 	prefixes: [
 		[ "dijit", "../dijit" ],
 		[ "dojox", "../dojox" ],
diff --git a/util/buildscripts/profiles/gfx.profile.js b/util/buildscripts/profiles/gfx.profile.js
new file mode 100644
index 0000000..edf6882
--- /dev/null
+++ b/util/buildscripts/profiles/gfx.profile.js
@@ -0,0 +1,26 @@
+dependencies = {
+	action:"clean,release",
+	optimize:"shrinksafe",
+	stripConsole: "normal",
+	layers: [{
+		name: "dojo.js",
+		dependencies: [
+		"dojo.colors",
+		"dojox.gfx",
+		"dojox.gfx.util",
+		"dojox.fx",
+		"dojox.gfx.renderer",
+		"dojox.gfx.svg_attach",
+		"dojox.gfx.vml_attach",
+		"dojox.gfx.silverlight_attach",
+		"dojox.gfx.canvas_attach",
+		"dojox.gfx.canvasWithEvents",
+		"dojox.gfx.gradutils",
+		"dojox.gfx.VectorText",
+		"dojox.gfx.move"]}
+	],
+	prefixes: [
+		[ "dijit", "../dijit" ],
+		[ "dojox", "../dojox" ]
+	]
+}
diff --git a/util/buildscripts/profiles/layers.profile.js b/util/buildscripts/profiles/layers.profile.js
deleted file mode 100644
index b35d68f..0000000
--- a/util/buildscripts/profiles/layers.profile.js
+++ /dev/null
@@ -1,66 +0,0 @@
-//This profile is used just to illustrate the layout of a layered build.
-//All layers have an implicit dependency on dojo.js.
-
-//Normally you should not specify a layer object for dojo.js. It is normally
-//implicitly built containing the dojo "base" functionality (dojo._base).
-//However, if you prefer the Dojo 0.4.x build behavior, you can specify a
-//"dojo.js" layer to get that behavior. It is shown below, but the normal
-//0.9 approach is to *not* specify it.
-
-//
-
-dependencies = {
-	layers: [
-		{
-			//For 0.9 you normally do not specify a dojo.js layer.
-			//Note that you do not need to specify dojo.js as a dependency for
-			//other layers -- it is always an implicit dependency.
-			name: "dojo.js",
-			dependencies: [
-				"dojo.parser"
-			]
-		},
-		{
-			//This layer will be discarded, it is just used
-			//to specify some modules that should not be included
-			//in a later layer, but something that should not be
-			//saved as an actual layer output. The important property
-			//is the "discard" property. If set to true, then the layer
-			//will not be a saved layer in the release directory.
-			name: "string.discard",
-			resourceName: "string.discard",
-			discard: true,
-			//Path to the copyright file must be relative to
-			//the util/buildscripts directory, or an absolute path.
-			copyrightFile: "myCopyright.txt",
-			dependencies: [
-				"dojo.string"
-			]
-		},
-		{
-			name: "../dijit/dijit.js",
-			resourceName: "dijit.dijit",
-			layerDependencies: [
-			"string.discard"
-			],
-			dependencies: [
-				"dijit.dijit"
-			]
-		}
-	],
-
-	prefixes: [
-		[ "dijit", "../dijit" ],
-		[ "dojox", "../dojox" ]
-	]
-}
-
-//If you choose to optimize the JS files in a prefix directory (via the optimize= build parameter),
-//you can choose to have a custom copyright text prepended to the optimized file. To do this, specify
-//the path to a file tha contains the copyright info as the third array item in the prefixes array. For
-//instance:
-//	prefixes: [
-//		[ "mycompany", "/path/to/mycompany", "/path/to/mycompany/copyright.txt"]
-//	]
-//
-//	If no copyright is specified in this optimize case, then by default, the dojo copyright will be used.
diff --git a/util/buildscripts/profiles/mobile-all.profile.js b/util/buildscripts/profiles/mobile-all.profile.js
index 1e63d91..7893314 100755
--- a/util/buildscripts/profiles/mobile-all.profile.js
+++ b/util/buildscripts/profiles/mobile-all.profile.js
@@ -6,25 +6,18 @@ dependencies = {
 			name: "dojo.js",
 			customBase: true,
 			dependencies: [
-				"dojo._base.declare",
-				"dojo._base.lang",
-				"dojo._base.array",
-				"dojo._base.window",
-				"dojo._base.event",
-				"dojo._base.connect",
-				"dojo._base.html",
-				"dijit._WidgetBase",
-				"dijit._base.manager",
 				"dojox.mobile.parser",
-				"dojox.mobile"
+				"dojox.mobile",
+				"dojox.mobile.compat"
 			]
 		},
 		{
-			name: "../dojox/mobile/compat.js",
+			name: "../dojox/mobile/_compat.js",
+			layerDependencies: [
+				"dojo.js"
+			],
 			dependencies: [
-				"dijit._base.sniff",
-				"dojo._base.fx",
-				"dojox.mobile.compat"
+				"dojox.mobile._compat"
 			]
 		}
 	],
diff --git a/util/buildscripts/profiles/mobile.profile.js b/util/buildscripts/profiles/mobile.profile.js
index 35421cb..3e0792a 100755
--- a/util/buildscripts/profiles/mobile.profile.js
+++ b/util/buildscripts/profiles/mobile.profile.js
@@ -5,35 +5,60 @@ dependencies = {
 			name: "dojo.js",
 			dependencies: [
 				"dijit._WidgetBase",
-				"dijit._base.manager"
+				"dijit._Container",
+				"dijit._Contained",
+				"dijit.registry"
 			]
 		},
 		{
 			name: "../dojox/mobile.js",
+			layerDependencies: [
+				"dojo.js"
+			],
 			dependencies: [
-				"dojox.mobile"
+				"dojox.mobile",
+				"dojox.mobile.compat"
 			]
 		},
 		{
 			name: "../dojox/mobile/app.js",
+			layerDependencies: [
+				"dojo.js",
+				"../dojox/mobile.js"
+			],
 			dependencies: [
 				"dojox.mobile.app"
 			]
 		},
 		{
-			name: "../dojox/mobile/compat.js",
+			name: "../dojox/mobile/_compat.js",
+			layerDependencies: [
+				"dojo.js",
+				"../dojox/mobile.js"
+			],
 			dependencies: [
-				"dojox.mobile.compat"
+				"dojox.mobile._compat"
 			]
 		},
 		{
 			name: "../dojox/mobile/app/compat.js",
+			layerDependencies: [
+				"dojo.js",
+				"../dojox/mobile/_compat.js",
+				"../dojox/mobile/app.js"
+			],
 			dependencies: [
 				"dojox.mobile.app.compat"
 			]
 		}
 	],
 
+	plugins: { // workaround to exclude acme.js from the build (until #13198 is fixed)
+		"dojo/text":"build/plugins/text",
+		"dojo/i18n":"build/plugins/i18n",
+		"dojo/has":"build/plugins/has"
+	},
+
 	prefixes: [
 		[ "dijit", "../dijit" ],
 		[ "dojox", "../dojox" ]
diff --git a/util/buildscripts/profiles/rhino.profile.js b/util/buildscripts/profiles/rhino.profile.js
index 87bb5ff..ed7bb04 100644
--- a/util/buildscripts/profiles/rhino.profile.js
+++ b/util/buildscripts/profiles/rhino.profile.js
@@ -3,14 +3,27 @@
   be able to run the DOH unit tests directly from the release directory.
 */
 
-hostenvType = "rhino";
-
 dependencies = {
-	layers: [
-	],
-
-	prefixes: [
-		[ "dojox", "../dojox" ],
-		[ "shrinksafe", "../util/shrinksafe" ]
-	]
+	staticHasFeatures:{
+		"host-rhino":1,
+		"host-browser":0,
+		"host-node":0,
+		"dom":0,
+		"dojo-has-api":1,
+		"dojo-xhr-factory":0,
+		"dojo-inject-api":1,
+		"dojo-timeout-api":0,
+		"dojo-trace-api":1,
+		"dojo-loader-catches":0,
+		"dojo-dom-ready-api":0,
+		"dojo-dom-ready-plugin":0,
+		"dojo-ready-api":1,
+		"dojo-error-api":1,
+		"dojo-publish-privates":1,
+		"dojo-gettext-api":1,
+		"dojo-sniff":0,
+		"dojo-loader":1,
+		"dojo-test-xd":0,
+		"dojo-test-sniff":0
+	}
 };
diff --git a/util/buildscripts/profiles/standard.profile.js b/util/buildscripts/profiles/standard.profile.js
index 585b9e9..6d7ea9a 100644
--- a/util/buildscripts/profiles/standard.profile.js
+++ b/util/buildscripts/profiles/standard.profile.js
@@ -5,8 +5,18 @@ dependencies = {
 	//But in general for a build, console.warn/error should be the only things to survive anyway.
 	stripConsole: "normal",
 
+	selectorEngine:"acme",
+
 	layers: [
 		{
+			name: "dojo.js",
+			dependencies: [
+				"dojo.loadInit",
+				"dojo.text",
+				"dojo.i18n"
+			]
+		},
+		{
 			name: "../dijit/dijit.js",
 			dependencies: [
 				"dijit.dijit"
diff --git a/util/buildscripts/profiles/standardCustomBase.profile.js b/util/buildscripts/profiles/standardCustomBase.profile.js
index c4151cf..bc04135 100644
--- a/util/buildscripts/profiles/standardCustomBase.profile.js
+++ b/util/buildscripts/profiles/standardCustomBase.profile.js
@@ -7,13 +7,13 @@ dependencies = {
 			]
 		},
 		{
-			name: "_base.js",
+			name: "main.js",
 			customBase: true,
 			layerDependencies: [
 				"dojo.js"
 			],
 			dependencies: [
-				"dojo._base"
+				"dojo.main"
 			]
 		},
 		{
diff --git a/util/checkstyle/checkstyleReport.html b/util/checkstyle/checkstyleReport.html
index a4a3563..57ba0cc 100644
--- a/util/checkstyle/checkstyleReport.html
+++ b/util/checkstyle/checkstyleReport.html
@@ -41,6 +41,7 @@
 		dojo.require("dijit.layout.BorderContainer");
 		dojo.require("dijit.form.FilteringSelect");
 		dojo.require("dijit.form.Button");
+		dojo.require("dijit.form.ToggleButton");
 		dojo.require("dijit.layout.TabContainer");
 		dojo.require("dijit.layout.ContentPane");
 		dojo.require("dojox.grid.DataGrid");
@@ -396,7 +397,7 @@
 								+ saveErrorMsg);
 						} else {
 							successes++;
-							if (successes = inputs.length) {
+							if (successes == inputs.length) {
 								alert("All files saved successfully");
 								dijit.byId("changedFilesDlg").hide();
 							}
diff --git a/util/closureCompiler/COPYING b/util/closureCompiler/COPYING
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/util/closureCompiler/COPYING
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the 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.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/util/closureCompiler/README b/util/closureCompiler/README
new file mode 100644
index 0000000..ece7175
--- /dev/null
+++ b/util/closureCompiler/README
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2009 The Closure Compiler Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Contents
+//
+
+The Closure Compiler performs checking, instrumentation, and
+optimizations on JavaScript code. The purpose of this README is to
+explain how to build and run the Closure Compiler.
+
+The Closure Compiler requires Java 6 or higher.
+http://www.java.com/
+
+
+//
+// Building The Closure Compiler
+//
+
+There are three ways to get a Closure Compiler executable.
+
+1) Use one we built for you.
+
+Pre-built Closure binaries can be found at
+http://code.google.com/p/closure-compiler/downloads/list
+
+
+2) Check out the source and build it with Apache Ant.
+
+First, check out the full source tree of the Closure Compiler. There
+are instructions on how to do this at the project site.
+http://code.google.com/p/closure-compiler/source/checkout
+
+Apache Ant is a cross-platform build tool.
+http://ant.apache.org/
+
+At the root of the source tree, there is an Ant file named
+build.xml. To use it, navigate to the same directory and type the
+command
+
+ant jar
+
+This will produce a jar file called "build/compiler.jar".
+
+
+3) Check out the source and build it with Eclipse.
+
+Eclipse is a cross-platform IDE.
+http://www.eclipse.org/
+
+Under Eclipse's File menu, click "New > Project ..." and create a
+"Java Project."  You will see an options screen. Give the project a
+name, select "Create project from existing source," and choose the
+root of the checked-out source tree as the existing directory. Verify
+that you are using JRE version 6 or higher.
+
+Eclipse can use the build.xml file to discover rules. When you
+navigate to the build.xml file, you will see all the build rules in
+the "Outline" pane. Run the "jar" rule to build the compiler in
+build/compiler.jar.
+
+
+//
+// Running The Closure Compiler
+//
+
+Once you have the jar binary, running the Closure Compiler is straightforward.
+
+On the command line, type
+
+java -jar compiler.jar
+
+This starts the compiler in interactive mode. Type
+
+var x = 17 + 25;
+
+then hit "Enter", then hit "Ctrl-Z" (on Windows) or "Ctrl-D" (on Mac or Linux)
+and "Enter" again. The Compiler will respond:
+
+var x=42;
+
+The Closure Compiler has many options for reading input from a file,
+writing output to a file, checking your code, and running
+optimizations. To learn more, type
+
+java -jar compiler.jar --help
+
+You can read more detailed documentation about the many flags at
+http://code.google.com/closure/compiler/docs/gettingstarted_app.html
+
+
+//
+// Compiling Multiple Scripts
+//
+
+If you have multiple scripts, you should compile them all together with
+one compile command.
+
+java -jar compiler.jar --js=in1.js --js=in2.js ... --js_output_file=out.js
+
+The Closure Compiler will concatenate the files in the order they're
+passed at the command line.
+
+If you need to compile many, many scripts together, you may start to
+run into problems with managing dependencies between scripts. You
+should check out the Closure Library. It contains functions for
+enforcing dependencies between scripts, and a tool called calcdeps.py
+that knows how to give scripts to the Closure Compiler in the right
+order.
+
+http://code.google.com/p/closure-library/
+
+//
+// Licensing
+//
+
+Unless otherwise stated, all source files are licensed under
+the Apache License, Version 2.0.
+
+
+-----
+Code under:
+src/com/google/javascript/rhino
+test/com/google/javascript/rhino
+
+URL: http://www.mozilla.org/rhino
+Version:  1.5R3, with heavy modifications
+License:  Netscape Public License and MPL / GPL dual license
+
+Description: A partial copy of Mozilla Rhino. Mozilla Rhino is an
+implementation of JavaScript for the JVM.  The JavaScript parser and
+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
+system have been added.
+
+
+-----
+Code in:
+lib/libtrunk_rhino_parser_jarjared.jar
+
+Rhino
+URL: http://www.mozilla.org/rhino
+Version:  Trunk
+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/
+
+
+-----
+Code in:
+lib/args4j.jar
+
+Args4j
+URL: https://args4j.dev.java.net/
+Version: 2.0.12
+License: MIT
+
+Description:
+args4j is a small Java class library that makes it easy to parse command line
+options/arguments in your CUI application.
+
+Local Modifications: None.
+
+
+-----
+Code in:
+lib/guava.jar
+
+Guava Libraries
+URL: http://code.google.com/p/guava-libraries/
+Version:  r08
+License: Apache License 2.0
+
+Description: Google's core Java libraries.
+
+Local Modifications: None.
+
+
+-----
+Code in:
+lib/jsr305.jar
+
+Annotations for software defect detection
+URL: http://code.google.com/p/jsr-305/
+Version: svn revision 47
+License: BSD License
+
+Description: Annotations for software defect detection.
+
+Local Modifications: None.
+
+
+----
+Code in:
+lib/junit.jar
+
+JUnit
+URL:  http://sourceforge.net/projects/junit/
+Version:  4.8.2
+License:  Common Public License 1.0
+
+Description: A framework for writing and running automated tests in Java.
+
+Local Modifications: None.
+
+
+---
+Code in:
+lib/protobuf-java.jar
+
+Protocol Buffers
+URL: http://code.google.com/p/protobuf/
+Version: 2.3.0
+License: New BSD License
+
+Description: Supporting libraries for protocol buffers,
+an encoding of structured data.
+
+Local Modifications: None
+
+
+---
+Code in:
+lib/ant.jar
+lib/ant-launcher.jar
+
+URL: http://ant.apache.org/bindownload.cgi
+Version: 1.8.1
+License: Apache License 2.0
+Description:
+  Ant is a Java based build tool. In theory it is kind of like "make"
+  without make's wrinkles and with the full portability of pure java code.
+
+Local Modifications: None
+
+
+---
+Code in:
+lib/json.jar
+URL: http://json.org/java/index.html
+Version: JSON version 20090211
+License: MIT license
+Description:
+JSON is a set of java files for use in transmitting data in JSON format.
+
+Local Modifications: None
+
+---
+Code in:
+tools/maven-ant-tasks-2.1.1.jar
+URL: http://maven.apache.org
+Version 2.1.1
+License: Apache License 2.0
+Description:
+  Maven Ant tasks are used to manage dependencies and to install/deploy to
+  maven repositories.
+
+Local Modifications: None
diff --git a/util/closureCompiler/compiler.jar b/util/closureCompiler/compiler.jar
new file mode 100644
index 0000000..2f6837d
Binary files /dev/null and b/util/closureCompiler/compiler.jar differ
diff --git a/util/docscripts/_browse.php b/util/docscripts/_browse.php
deleted file mode 100755
index 79ca364..0000000
--- a/util/docscripts/_browse.php
+++ /dev/null
@@ -1,236 +0,0 @@
-<?php /*
-
-  _browse.php - rudimentary api browser designed to expose flaws in
-  either the dojo doc parser or the effort to document the Dojo Toolkit
-  API. it is embarasingly inefficient and sloppy, but works.
-  
-  this file requires PHP5, and a full source tree of the dojo toolkit.
-
-  it parses a module, and dumps relevant API information made in real
-  time. PLEASE use this to preview how the parse tool will interpret
-  your code.
-
-  it covers all files in dojtool's modules/ directory dynamically, so
-  can be used to preview documentation in custom namespace code, as well.
-
-*/
-
-// hide warnings
-error_reporting(1);
-$ajaxy = !empty($_REQUEST['ajaxy']);
-
-?>
-
-<?php if(!$ajaxy){ ?>
-	<html>
-		<head>
-		
-		  <title>API Preview tool | The Dojo Toolkit </title>
-		
-		  <script type="text/javascript" src="../../dojo/dojo.js" djConfig="parseOnLoad:true"></script>
-		
-		  <script type="text/javascript">
-			dojo.require("dijit.layout.BorderContainer");
-			dojo.require("dojox.layout.ExpandoPane");
-			dojo.require("dijit.layout.ContentPane");
-			dojo.require("dijit.layout.TabContainer");
-			dojo.require("dijit.layout.AccordionContainer");
-			dojo.require("dojo.fx.easing");
-			dojo.require("dijit.TitlePane");
-			function tgShow(id){
-			  var identity=document.getElementById(id);
-					if(identity.className=="sho"){ identity.className="nosho";
-					}else{ identity.className="sho"; }
-			}
-			dojo.addOnLoad(function(e){
-				dojo.connect(window,"onclick",function(e){
-					if(e.target && e.target.href){
-						e.preventDefault();
-						dijit.byId('apiPane').attr("href", e.target.href + "&ajaxy=true");
-					}
-				});
-			});
-		  </script>
-		  <style type="text/css">
-			@import "../../dijit/themes/soria/soria.css";
-			@import "../../dojox/layout/resources/ExpandoPane.css";
-			@import "../../dojo/resources/dojo.css"; 
-			body, html { width:100%; height:100%; margin:0; padding:0; }
-			.sho { display:block; }
-			.nosho { display:none; } 
-			.topbar li { display:inline; padding:5px; } 
-			.pad {
-				padding:20px;
-				padding-top:8px;
-			}
-			</style>
-		  </style>
-		</head>
-	<body class="soria">
-<?php
-
-} // $ajaxy
-
-include_once('includes/dojo.inc');
-
-$tree = '';
-// no dojo.require() call made?
-$u = 0; 
-$files = dojo_get_files(); 
-foreach ($files as $set){ 
-  list($namespace, $file) = $set;
-  $data[$namespace][] = $file;
-}
-$namespaces = array_keys($data); 
-
-$trees = array();
-$regexp = "";
-foreach ($data as $ns => $file){
-  $tree = "<ul>";
-  foreach ($data[$ns] as $file){
-    if(!preg_match('/tests\//i',$file)){
-      if($ifile == $file){ $tree .= "<li>".$file."</li>"; 
-      }else{ $tree .= "<li><a href=\"?ns=".$ns."&file=".$file."\">".$ns."/".$file."</a></li>"; }
-    }else{ $testfiles[] = $ns."/".$file; } 
-  }
-  $tree .= "</ul>";
-  $trees[$ns] = $tree;
-}
-
-
-unset($files); 
-
-if(!empty($_REQUEST['ns'])){
-  $ns = $_REQUEST['ns'];
-  $ifile = $_REQUEST['file'];
-  
-
-  if($ifile){
-    $apiData = dojo_get_contents($ns,$ifile);
-
-    $print .= "<h2>".$ns."/".$ifile."</h2><ul>";
-    foreach($apiData as $key => $val){
-      switch($key){
-        case "#resource" : break;
-        case "#requires" : 
-          $print .= "<li><h3>Requires:</h3><ul>";
-          foreach($val as $resource){
-            $print .= "<li>{$resource[1]} in {$resource[0]}";
-            if ($resource[2]) {
-              $print .= " in project {$resource[2]}";
-            }
-            $print .= "</li>"; 
-          }
-          $print .= "</ul></li>"; 
-          break;
-        case "#provides" :
-          $print .= "<li><h3>Provides:</h3><ul>";
-          $print .= "<li>$val</li>"; 
-          $print .= "</ul></li>"; 
-          break;
-        default:
-          $print .= "<li><h4>".$key."</h4><ul> ";
-          foreach($val as $key2 => $val2){
-  
-              switch($key2){
-                // most things using dojo.declare() trigger this, eg: dijits
-                case "classlike": $knownClasses[] = $key; break;
-
-                // these are partially useless for our "overview" api, but set showall=1 in the
-                // url if you want to see these, too. sortof.
-                case "type" : $print .= "<li><em>".$key2."</em><div><pre>".htmlentities($val2)."</pre></div></li>"; break;
-                case "private_parent" :
-                case "prototype" :
-                case "instance" :
-                case "private" :
-                  if($_REQUEST['showall']){ $print .= "<li>".$key2." - ".$val2."</li>"; }
-                  break;
-                
-                // another array we want inspect more closely 
-                case "parameters" : 
-                  $print .= "<li><em>parameters:</em> <ul>"; 
-                  foreach($val2 as $param => $paramData){
-                    $print .= "<li>".$param.": <em>(typeof ".$paramData['type'].")</em><div>";
-                    if(!empty($paramData['summary'])){
-                      $print .= "<pre>".htmlentities($paramData['summary'])."</pre>";
-                    }
-                    $print .= "</div></li>";
-                  } //print_r($val2);             
-                  $print .= "</ul></li>";
-                  break;
-                
-                // the stripped source, and some minimal toggling to show/hide  
-                case "source" : 
-                  $print .= "<li class=\"source\"><em>source: [<a onclick=\"tgShow('unique".++$u."');\">view</a>]</em> 
-                    <div class=\"nosho\" id=\"unique".$u."\">\n
-                    ".ltrim(str_replace("\n","<br>",str_replace("\t"," ",$val2)))."
-                    </div>
-                    ";  
-                  break;
-
-                case "tags":
-                  $print .= "<li><em>$key2</em>: " . implode(' ', $val2) . '</li>';
-                  break;
-
-                case "chains" :
-                case "mixins" :
-                  if (!empty($val2)) {
-                    $print .= "<li><em>" . $key2 . ":</em> <ul>";
-                    foreach ($val2 as $subtype => $chains) {
-                      foreach ($chains as $chain) {
-                        $print .= "<li>$chain: <em>($subtype)</em></li>";
-                      }
-                    }
-                    $print .= "</ul></li>";
-                  }
-                  break;
-
-                // these are the ones we care about, and are fulltext/sometimes html
-                case "examples" :
-                  foreach ($val2 as $example){
-                    $print .= "<li><em>example</em><div><pre>".htmlentities($example)."</pre></div></li>";
-                  }
-                  break;
-                case "returns" :
-                case "return_summary" :
-                case "exceptions" :
-                case "description" :
-                case "summary" : $print .= "<li><em>".$key2."</em><div><pre>".htmlentities($val2)."</pre></div></li>"; break;
-
-                // this is a key we don't know about above, so show it just in case
-                default: $print .= "<li>?? ".$key2." = ".$val2." (debug: ".gettype($val2).") ??</li>"; break;
-              }
-          } 
-          $print .= "</ul></li>"; break;
-      }
-    }
-    $print .= "</ul>";
-  }
-}
-
-if(!$ajaxy){ ?>
-<div dojoType="dijit.layout.BorderContainer" style="width:100%; height:100%;">
-	<div dojoType="dojox.layout.ExpandoPane" easeOut="dojo.fx.easing.backIn" easeIn="dojo.fx.easing.backOut" title="Namespaces" region="left" style="width:250px" splitter="true">
-		<div dojoType="dijit.layout.AccordionContainer" style="width:250px" tabPosition="top">
-			<?php
-				foreach($trees as $ns => $list){
-					print "\n\n<div dojoType=\"dijit.layout.ContentPane\" title=\"".$ns."\">";
-					print $list;
-					print "</div>";
-				}
-			?>
-		</div>
-	</div>
-    <div dojoType="dijit.layout.TabContainer" closeable="false" region="center">
-		<div dojoType="dijit.layout.ContentPane" id="apiPane" title="Crude API Browser">
-			<div class="pad"><?php echo $print; ?></div>
-		</div>
-    </div>
-</div>
-</body>
-</html>
-<?php }else{
-	// we just want the content we parsed
-	echo '<div class="pad">'.$print.'</div>';
-}
-?>
diff --git a/util/docscripts/_browse2.php b/util/docscripts/_browse2.php
deleted file mode 100644
index 4fe6da0..0000000
--- a/util/docscripts/_browse2.php
+++ /dev/null
@@ -1,289 +0,0 @@
-<?php /*
-
-  _browse.php - rudimentary api browser designed to expose flaws in
-  either the dojo doc parser or the effort to document the Dojo Toolkit
-  API. it is embarasingly inefficient and sloppy, but works.
-  
-  this file requires PHP5, and a full source tree of the dojo toolkit.
-
-  it parses a module, and dumps relevant API information made in real
-  time. PLEASE use this to preview how the parse tool will interpret
-  your code.
-
-  it covers all files in dojtool's modules/ directory dynamically, so
-  can be used to preview documentation in custom namespace code, as well.
-
-*/
-
-// hide warnings
-error_reporting(1);
-$ajaxy = !empty($_REQUEST['ajaxy']);
-$showall = isset($_REQUEST['showall']);
-
-?>
-<?php if(!$ajaxy){ ?>
-	<!DOCTYPE html>
-	<html>
-		<head>
-		
-			<title>API Preview tool | The Dojo Toolkit</title>
-		
-			<style type="text/css">
-				@import "../../dojo/resources/dojo.css"; 
-				@import "../../dijit/themes/claro/claro.css";
-				@import "../../dojox/layout/resources/ExpandoPane.css";
-				
-				body, html { width:100%; height:100%; margin:0; padding:0; overflow:hidden; }
-				.sho { display:block; }
-				.nosho { display:none; } 
-				.topbar li { display:inline; padding:5px; } 
-				.pad {
-					padding:20px;
-					padding-top:8px;
-				}
-				#main { 
-					width:100%; height:100%;
-				}
-			</style>
-			
-			<script type="text/javascript" src="../../dojo/dojo.js" djConfig="parseOnLoad:true"></script>
-			<script type="text/javascript">
-				dojo.require("dijit.layout.BorderContainer");
-				dojo.require("dojox.layout.ExpandoPane");
-				dojo.require("dijit.layout.ContentPane");
-				dojo.require("dijit.layout.TabContainer");
-				dojo.require("dojo.fx.easing");
-
-				function tgShow(id){
-					var identity = dojo.byId(id);
-					if(identity.className=="sho"){ 
-						identity.className="nosho";
-					}else{ 
-						identity.className="sho"; 
-					}
-				}
-
-				dojo.ready(function(){
-					var apipane = dijit.byId("apiTabs");
-					dojo.connect(window,"onclick",function(e){
-						if(e.target && e.target.href){
-							e.preventDefault();
-							var id = dojo.attr(e.target, "rel");
-							var dij = dijit.byId(id);
-							if(!dij){
-								dij = new dijit.layout.ContentPane({
-									id: id,
-									href: e.target.href + "&ajaxy=true",
-									title: id,
-									closable: true
-								}).placeAt(apipane);
-								
-							}else{
-								dij.set("href", e.target.href + "&ajaxy=true&bust=" + (+new Date()));
-							}
-							
-							apipane.selectChild(dij);
-						}
-					});
-				});
-			</script>
-
-		</head>
-		<body class="claro">
-<?php
-
-} // $ajaxy
-
-include_once('lib/parser2/dojo2.inc');
-
-$tree = '';
-// no dojo.require() call made?
-$u = 0; 
-$files = dojo_get_files(); 
-foreach ($files as $set){ 
-	list($namespace, $file) = $set;
-	$data[$namespace][] = $file;
-}
-$namespaces = array_keys($data); 
-
-$trees = array();
-$regexp = "";
-foreach ($data as $ns => $file){
-	$tree = "<ul>";
-	foreach ($data[$ns] as $file){
-		if(!preg_match('/tests\//i',$file)){
-			if($ifile == $file){ 
-				$tree .= "<li>".$file."</li>"; 
-			}else{ 
-				$tree .= "<li><a rel=\"". str_replace("/", ".", $file) . "\" href=\"?ns=".$ns."&file=".$file."&showall=".$showall."\">".$ns."/".$file."</a></li>"; 
-			}
-		}else{ $testfiles[] = $ns."/".$file; } 
-	}
-	$tree .= "</ul>";
-	$trees[$ns] = $tree;
-}
-
-unset($files); 
-
-if(!empty($_REQUEST['ns'])){
-
-	$ns = $_REQUEST['ns'];
-	$ifile = $_REQUEST['file'];
-  
-
-	if($ifile){
-		$apiData = dojo_get_contents($ns,$ifile);
-
-		$print .= "<h2>".$ns."/".$ifile."</h2><ul>";
-		foreach($apiData as $key => $val){
-			switch($key){
-				case "#resource" : break;
-				case "#requires" : 
-					$print .= "<li><h3>Requires:</h3><ul>";
-					foreach($val as $resource){
-						$print .= "<li>{$resource[1]} in {$resource[0]}";
-						if ($resource[2]) {
-							$print .= " in project {$resource[2]}";
-						}
-						$print .= "</li>"; 
-					}
-					$print .= "</ul></li>"; 
-					break;
-				case "#provides" :
-					$print .= "<li><h3>Provides:</h3><ul>";
-					$print .= "<li>$val</li>"; 
-					$print .= "</ul></li>"; 
-					break;
-				default:
-					$print .= "<li><h4>".$key."</h4><ul> ";
-					foreach($val as $key2 => $val2){
-  
-						switch($key2){
-							// most things using dojo.declare() trigger this, eg: dijits
-							case "classlike":
-								$knownClasses[] = $key;
-								if ($_REQUEST['showall']) {
-									$print .= "<li>$key2</li>";
-								}
-								break;
-
-							// these are partially useless for our "overview" api, but set showall=1 in the
-							// url if you want to see these, too. sortof.
-							case "type" : 
-								$print .= "<li><em>".$key2."</em><div><pre>".htmlentities($val2)."</pre></div></li>"; 
-								break;
-							case "private_parent" :
-							case "prototype" :
-							case "instance" :
-							case "private" :
-							case "deprecated" :
-							case "protected" :
-							case "attached" :
-								if($_REQUEST['showall']){ $print .= "<li>".$key2." - ".$val2."</li>"; }
-								break;
-							case "alias" :
-							case "constructor" :
-								$print .= "<li>".$key2." - ".$val2."</li>";
-								break;
-				
-							// another array we want inspect more closely 
-							case "parameters" : 
-								$print .= "<li><em>parameters:</em> <ul>"; 
-								foreach($val2 as $param => $paramData){
-									$print .= "<li>".$param;
-									if (!empty($paramData['type'])) {
-										$print .= ": <em>(typeof ".$paramData['type'].")</em>";
-									}
-									$print .= "<div>";
-									if(!empty($paramData['summary'])){
-										$print .= "<pre>".htmlentities($paramData['summary'])."</pre>";
-									}
-									$print .= "</div></li>";
-								} //print_r($val2);				
-								$print .= "</ul></li>";
-								break;
-				
-								// the stripped source, and some minimal toggling to show/hide	
-							case "source" : 
-								$print .= "<li class=\"source\"><em>source: [<a onclick=\"tgShow('unique".++$u."');\">view</a>]</em> 
-									<div class=\"nosho\" id=\"unique".$u."\">\n
-									".ltrim(str_replace("\n","<br>",str_replace("\t"," ",$val2)))."
-									</div>";  
-								break;
-
-							case "tags":
-								$print .= "<li><em>$key2</em>: " . implode(' ', $val2) . '</li>';
-								break;
-
-							case "optional":
-								if ($val2) {
-									$print .= "<li><em>$key2</em></li>";
-								}
-								break;
-
-							case "chains" :
-							case "mixins" :
-								if (!empty($val2)) {
-									$print .= "<li><em>" . $key2 . ":</em> <ul>";
-									foreach ($val2 as $subtype => $chains) {
-										foreach ($chains as $chain) {
-											$print .= "<li>$chain: <em>($subtype)</em></li>";
-										}
-									}
-									$print .= "</ul></li>";
-								}
-								break;
-
-							// these are the ones we care about, and are fulltext/sometimes html
-							case "examples" :
-								foreach ($val2 as $example){
-									$print .= "<li><em>example</em><div><pre>".htmlentities($example)."</pre></div></li>";
-								}
-								break;
-
-							case "returns" :
-							case "return_summary" :
-							case "exceptions" :
-							case "description" :
-							case "summary" : $print .= "<li><em>".$key2."</em><div><pre>".htmlentities($val2)."</pre></div></li>"; break;
-
-							// this is a key we don't know about above, so show it just in case
-							default: 
-								$print .= "<li>?? ".$key2." = ".$val2." (debug: ".gettype($val2).") ??</li>"; 
-								break;
-						}
-					} 
-					$print .= "</ul></li>"; 
-					break;
-				}
-			}
-			$print .= "</ul>";
-		}
-	}
-
-if(!$ajaxy){ ?>
-<div dojoType="dijit.layout.BorderContainer" id="main">
-	<div dojoType="dojox.layout.ExpandoPane" easeOut="dojo.fx.easing.backIn" easeIn="dojo.fx.easing.backOut" title="Namespaces" region="left" style="width:250px" splitter="true">
-		<div dojoType="dijit.layout.TabContainer" id="nstabs" tabPosition="bottom">
-			<?php
-				foreach($trees as $ns => $list){
-					print "<div attachParent=\"true\" dojoType=\"dijit.layout.ContentPane\" title=\"".$ns."\">";
-					print $list;
-					print "</div>";
-				}
-			?>
-		</div>
-	</div>
-	<div dojoType="dijit.layout.TabContainer" id="apiTabs" region="center">
-		<div dojoType="dijit.layout.ContentPane" id="apiPane" title="Crude API Browser">
-			<div class="pad"><?php echo $print; ?></div>
-		</div>
-	</div>
-</div>
-</body>
-</html>
-<?php }else{
-	// we just want the content we parsed
-	echo '<div class="pad">'.$print.'</div>';
-}
-?>
diff --git a/util/docscripts/_browse_tree.php b/util/docscripts/_browse_tree.php
new file mode 100644
index 0000000..e312391
--- /dev/null
+++ b/util/docscripts/_browse_tree.php
@@ -0,0 +1,142 @@
+<?php
+header("Content-Type: application/json");
+
+include_once('lib/parser2/dojo2.inc');
+
+// no dojo.require() call made?
+$files = dojo_get_files(); 
+foreach ($files as $set){ 
+	list($namespace, $file) = $set;
+	$data[$namespace][] = $file;
+}
+$namespaces = array_keys($data); 
+
+//	$data takes the form of $namespace[], where the value is the rest of the file.  So let's break it up.
+//	note that $namespaces is the root of each branch.
+$id_counter = 0;
+$tree = array();
+$folders = array();
+$indexed = array();
+
+//	temporary
+//$namespaces = array("dojo");
+foreach($namespaces as $nm){
+	//	loop through the namespaces, build up our tree "json"
+	$obj = array(
+		"id" => "data-" . $id_counter++,
+		"name" => $nm,
+		"full_name" => $nm,
+		"type" => "namespace",
+		"children" => array()
+	);
+	$tree[] = &$obj;
+	foreach($data[$nm] as $f){
+		//	we know each one is unique here, but we have to break it up.
+		$pieces = explode("/", $f);
+		$name = array_pop($pieces);
+		$file_obj = array(
+			"id" => "data-" . $id_counter++,
+			"name" => $name,
+			"full_name" => $f,
+			"ns" => $nm,
+			"type" => "file"
+		);
+
+		//	push it into the tree regardless
+		$tree[] = $file_obj;
+		$indexed[$file_obj["id"]] = $file_obj;
+		if(!count($pieces)){
+			//	this is a direct child of the namespace, so just add it.
+			$obj["children"][] = array("_reference" => $file_obj["id"]);
+		} else {
+			while(count($pieces)){
+				$full_name = implode("/", $pieces);
+				$name = array_pop($pieces);
+				if(!array_key_exists($full_name, $folders)){
+					//	add this directory object
+					$folder_obj = array(
+						"id" => "data-" . $id_counter++,
+						"name" => $name,
+						"full_name" => $full_name,
+						"ns" => $nm,
+						"type" => "folder",
+						"added" => false,
+						"children" => array()
+					);
+					//	keep track of it.
+					$folders[$full_name] = $folder_obj;
+				}
+
+				//	check to see if there's a parent folder
+				if(count($pieces)){
+					//	there should be a parent
+					$tmp = explode("/", $full_name);
+					array_pop($tmp);
+					$tmp = implode("/", $tmp);
+					if(array_key_exists($tmp, $folders) && !$folders[$full_name]["added"]){
+						$folders[$tmp]["children"][] = array("_reference"=>$folders[$full_name]["id"]);
+						$folders[$full_name]["added"] = true;
+					}
+				}
+			}
+
+			//	finally, add our file to the right folder.
+			$tmp = explode("/", $f);
+			array_pop($tmp);
+			$tmp = implode("/", $tmp);
+			$folders[$tmp]["children"][] = array("_reference" => $file_obj["id"]);
+		}
+	}
+
+	//	add in our folder objects and merge with the main namespace
+	$tmp = array();
+	foreach($folders as $f=>$folder){
+		$tree[] = $folder;
+		$indexed[$folder["id"]] = $folder;
+		if(strpos($f, "/") === false){
+			$tmp[] = array("_reference"=>$folder["id"]);
+		}
+	}
+	$obj["children"] = array_merge($tmp, $obj["children"]);
+
+	//	fugly sorting by rebuilding all children.
+	foreach($tree as $key=>&$item){
+		if(array_key_exists("children", $item) && count($item["children"])){
+			$folder_objs = array();
+			$privates = array();
+			$file_objs = array();
+
+			//	here's where it gets ugly.  Loop through the children, get the indexed object and push
+			//	into the various arrays in order to rebuild the children.
+			foreach($item["children"] as $child=>$value){
+				$test = $indexed[$value["_reference"]];
+				if($test["type"] == "folder"){
+					$folder_objs[] = $value;
+				}
+				else if(strpos($test["name"], "_")===0){
+					$privates[] = $value;
+				}
+				else {
+					$file_objs[] = $value;
+				}
+			}
+
+			//	TODO: we need the file objects to be sorted case-insensitive.
+
+
+			//	rebuild the children array
+			$item["children"] = array_merge($folder_objs, $privates, $file_objs);
+		}
+	}
+
+	$folders = array();
+	$indexed = array();
+	unset($obj);
+}
+$storeData = array(
+	"identifier"=>"id",
+	"label"=>"name",
+	"items"=>&$tree
+);
+print json_encode($storeData);
+?>
diff --git a/util/docscripts/cheat.php b/util/docscripts/cheat.php
index d5e535a..10ab246 100644
--- a/util/docscripts/cheat.php
+++ b/util/docscripts/cheat.php
@@ -2,10 +2,9 @@
 	
 	// for this to work, the file api.html needs to be writable locally. pass a "?build" to
 	// this url to trigger the generation. otherwise, work live from here. No JS ends up 
-	// in the output. api.css gets inlined in the output, making api.html standalone. 
+	// in the output. api.css gets inlined in the output, making cheat.html standalone. 
 	
-	$head = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+	$head = '<!DOCTYPE html>
 	<html>
 		<head>
 			<title>API Overview - Dojo Toolkit</title>
diff --git a/util/docscripts/cheat/lib.js b/util/docscripts/cheat/lib.js
index 594b244..0853288 100644
--- a/util/docscripts/cheat/lib.js
+++ b/util/docscripts/cheat/lib.js
@@ -66,14 +66,14 @@ dojo.require("util.docscripts.cheat.floatup");
 
 				"Event-System":[
 					"connect", "publish", "subscribe", "pub", "sub", "unsubscribe", "disconnect",
-					"fixEvent", "stopEvent", "connectPublisher", "isCopyKey", "mouseButtons"
+					"fixEvent", "stopEvent", "connectPublisher", "isCopyKey", "mouseButtons", "on"
 				],
 
 				"NodeList-Events":[
 					"onmousedown", "onmouseenter", "onmouseleave", "onmousemove", "onmouseover",
 					 "onmouseout", "onblur",
 					"onfocus", "onclick", "onchange", "onload", "onmousedown", "onmouseup", "onsubmit",
-					"onerror", "onkeydown", "onkeypress", "onkeyup", "hover"
+					"onerror", "onkeydown", "onkeypress", "onkeyup", "hover", "on"
 				],
 
 				"NodeList-Misc":[
@@ -87,7 +87,7 @@ dojo.require("util.docscripts.cheat.floatup");
 
 				"Package-System":[
 					"require", "provide", "load", "requireLocalization", "requireIf", "dfdLoad",
-					"moduleUrl", "requireAfterIf", "registerModulePath", "platformRequire"
+					"moduleUrl", "requireAfterIf", "registerModulePath", "platformRequire", "isAsync"
 				],
 
 				"Document-Lifecycle":[
@@ -95,7 +95,6 @@ dojo.require("util.docscripts.cheat.floatup");
 					"unloaded", "loadInit",  "windowUnloaded", "ready"
 				],
 
-
 				"DOM-Manipulation":[
 					"create", "wrap", "place", "byId", "query", "empty", "destroy", "generateId", "clone",
 					"body", "append", "appendTo", "addContent", "adopt", "orphan"
@@ -130,7 +129,7 @@ dojo.require("util.docscripts.cheat.floatup");
 
 				"Sniffing":[
 					"isBrowser", "isFF", "isKhtml", "isMoz", "isMozilla", "isIE", "isOpera", "isBrowser",
-					"isQuirks", "isWebKit", "isChrome", /* new 1.4 */ "isMac"
+					"isQuirks", "isWebKit", "isChrome", "isSafari", "isAIR", /* new 1.4 */ "isMac"
 				]
 			},
 			
diff --git a/util/docscripts/dumpObj.php b/util/docscripts/dumpObj.php
new file mode 100755
index 0000000..7e42691
--- /dev/null
+++ b/util/docscripts/dumpObj.php
@@ -0,0 +1,29 @@
+<?php
+
+ini_set("ERROR_REPORTING", 0);
+include_once('lib/parser2/dojo2.inc');
+$allfiles = @dojo_get_files();
+
+if($argc || !empty($_GET['f'])){
+
+	$argfile = empty($_GET['f']) ? $argv[1] : $_GET['f'];
+
+	$parts = explode("/", $argfile);
+	$ns = array_shift($parts);
+	$file = implode("/", $parts);
+	
+	try{
+		$data = @dojo_get_contents($ns, $file);
+	}catch (Exception $e){
+		$data = array(
+			"success" => False,
+			"error" => $e
+		);
+	}
+
+	if(!empty($_GET['f'])){
+		header("Content-type: application/json");
+	}
+
+	print json_encode($data);
+}
diff --git a/util/docscripts/generate.php b/util/docscripts/generate.php
index c949d20..7850baa 100755
--- a/util/docscripts/generate.php
+++ b/util/docscripts/generate.php
@@ -8,7 +8,7 @@
 # -- Runs only the module starting with custom, custom2, etc.
 # php generate.php --store=file
 # php generate.php --store=mysql --db_host=localhost --db_user=api --db_password=password --db_name=api
-# -- Specifies storage type. "file" and "resource" currently supported
+# -- Specifies storage type. "hash", "file" and "resource" currently supported
 # php generate.php --serialize=xml,json
 # -- Comma-separated list of serializations. "xml" and "json" supported
 # php generate.php --outfile=custom-api custom
@@ -24,7 +24,6 @@ error_reporting(E_ALL ^ E_NOTICE);
 $debug = true;
 
 require_once('lib/parser2/dojo2.inc');
-// Use file serializers by default
 
 $keys = array();
 $namespaces = array();
@@ -82,8 +81,9 @@ if (!isset($kwargs['serialize'])) {
     'xml' => true
   );
 }
+// Use hash storage by default
 if (!isset($kwargs['store'])) {
-  $kwargs['store'] = 'file';
+  $kwargs['store'] = 'hash';
 }
 
 require_once('lib/generator/' . $kwargs['store'] . '/Freezer.php');
@@ -142,6 +142,11 @@ foreach ($files as $set){
   $requires = $contents['#requires'];
   unset($contents['#requires']);
 
+  // set by debugging in parsing
+  unset($contents['#debug']);
+  unset($contents['#unwrapped_source']);
+  unset($contents['#raw_source']);
+
   foreach ($contents as $var => $content) {
     foreach ($content as $key_key => $key_value) {
       $key_type = 'undefined';
@@ -292,8 +297,9 @@ foreach ($files as $set){
           $short_parameters = (count($node_parameters) >  count($content_parameters)) ? $content_parameters : $node_parameters;
 
           $match = true;
+	  $total_short = count($short_parameters);
           foreach ($long_parameters as $i => $parameter) {
-            if ($i < count($short_parameters) && $parameter != $short_parameters[$i]) {
+            if ($i < $total_short && $parameter != $short_parameters[$i]) {
               $match = false;
             }
           }
@@ -334,10 +340,12 @@ $ids = $nodes->ids();
 
 $percent = 0;
 
+$total = count($ids);
+$count_args = count($args);
 foreach ($ids as $pos => $id) {
-  $new_percent = floor($pos / count($ids) * 50);
+  $new_percent = floor($pos / $total * 50);
   if ($new_percent % 5 == 0 && $percent % 5 != 0) {
-    print floor($new_percent) . "%\n";
+    print $new_percent . "%\n";
   }
   $percent = $new_percent;
 
@@ -347,7 +355,7 @@ foreach ($ids as $pos => $id) {
     $parent = implode('.', $parts);
 
     $node = $nodes->open($id, array());
-    if (!is_array($node['#namespaces']) || (count($args) && !count(array_intersect($args, $node['#namespaces'])))) {
+    if (!is_array($node['#namespaces']) || ($count_args && !count(array_intersect($args, $node['#namespaces'])))) {
       continue;
     }
     if (!array_key_exists($parent, $roots)) {
@@ -365,28 +373,36 @@ foreach ($ids as $pos => $id) {
 // Figure out whether a root item has children or not
 $pos = 0;
 $root_count = count($roots);
-foreach ($roots as $id => $root) {
+$has_children_map = array();
+$rootids = array_keys($roots);
+//descending sort rootids, so children are processed before parents
+rsort($rootids);
+foreach ($rootids as $id) {
+  $root = $roots[$id];
   $new_percent = floor(50 + ($pos++ / $root_count * 50));
   if ($new_percent % 5 == 0 && $percent % 5 != 0) {
     print floor($new_percent) . "%\n";
   }
   $percent = $new_percent;
 
-  if ($root['function'] && !$root['classlike']) {
-    $has_children = false;
-    $parts = explode('.', $id);
-    if (count($parts) > 1) {
-      foreach ($roots as $possible_child_id => $possible_child) {
-        $child_parts = explode('.', $possible_child_id);
-        if (count($child_parts) == count($parts)+1 && strpos($possible_child_id, "$id.") === 0) {
-          $has_children = true;
-          break;
-        }
-      }
-      if (!$has_children) {
-        unset($roots[$id]);
+  $parts = explode('.', $id);
+  $parts_count = count($parts);
+  if ($parts_count > 1) {
+    if ($root['function'] && !$root['classlike']) {
+      if(!array_key_exists($id, $has_children_map)){
+          unset($roots[$id]);
       }
     }
+
+    $name = array_pop($parts);
+    $parent_id = implode('.', $parts);
+    $obj = array("name"=>$name, "id"=>$id);
+    if(array_key_exists($parent_id, $has_children_map)) {
+      array_push($has_children_map[$parent_id], $obj);
+    }
+    else{
+      $has_children_map[$parent_id] = array($obj);
+    }
   }
 }
 
@@ -419,11 +435,9 @@ foreach ($roots as $id => $root) {
 
   $node = $nodes->open($id, null);
 
-  $parts = explode('.', $id);
-  foreach ($ids as $child_id) {
-    $child_parts = explode('.', $child_id);
-    if (count($child_parts) == count($parts)+1 && strpos($child_id, "$id.") === 0 && !array_key_exists($child_id, $roots)) {
-      $node['#children'][array_pop($child_parts)] = $nodes->open($child_id, null);
+  if(array_key_exists($id, $has_children_map)){
+    foreach ($has_children_map[$id] as $child) {
+      $node['#children'][$child['name']] = $nodes->open($child['id'], null);
     }
   }
 
diff --git a/util/docscripts/lib/generator/hash/Freezer.php b/util/docscripts/lib/generator/hash/Freezer.php
new file mode 100644
index 0000000..a602faa
--- /dev/null
+++ b/util/docscripts/lib/generator/hash/Freezer.php
@@ -0,0 +1,63 @@
+<?php
+
+final class Freezer
+{
+  protected $key_delimeter = '%%%';
+
+  private $length = 99999;
+  private $nodes_location = '';
+  private $nodes = array();
+
+  public static function clean($directory, $suffix) {
+    $loc = $directory . '/' . $suffix;
+    file_exists($loc) && unlink($loc);
+  }
+
+  public function __construct($directory, $suffix) {
+    $this->nodes_location = $directory . '/' . $suffix;
+    touch($this->nodes_location);
+    $nodes_file = fopen($this->nodes_location, 'r');
+    $this->_readFromFile($nodes_file);
+    fclose($nodes_file);
+  }
+
+  public function __destruct() {
+    $this->flush();
+  }
+
+  private function _readFromFile($nodes_file) {
+    while (!feof($nodes_file)) {
+      $line = stream_get_line($nodes_file, $this->length, "\n");
+      list($key, $value) = explode($this->key_delimeter, $line);
+      
+      if (trim($key)) {
+        $this->nodes[$key] = $value;
+      }
+    } 
+  }
+
+  public function ids($flush = TRUE) {
+    return array_keys($this->nodes);
+  }
+
+  public function open($key, $default) {
+    if(array_key_exists($key, $this->nodes)){
+        return unserialize(str_replace("\\n", "\n", $this->nodes[$key]));
+    }
+    return $default;
+  }
+
+  public function save($key, $content) {
+    $this->nodes[$key] =  str_replace("\n", "\\n", serialize($content));
+  }
+
+  private function flush() {
+    $tmp = fopen($this->nodes_location . '_tmp', 'w');
+    foreach ($this->nodes as $key => $value) {
+      fwrite($tmp, $key . $this->key_delimeter . $value . "\n");
+    }
+    fclose($tmp);
+    unlink($this->nodes_location);
+    rename($this->nodes_location . '_tmp', $this->nodes_location);
+  }
+}
diff --git a/util/docscripts/lib/generator/hash/Serializer.php b/util/docscripts/lib/generator/hash/Serializer.php
new file mode 100644
index 0000000..9fdcfc1
--- /dev/null
+++ b/util/docscripts/lib/generator/hash/Serializer.php
@@ -0,0 +1,89 @@
+<?php
+
+require_once('lib/generator/common/AbstractSerializer.php');
+
+abstract class Serializer extends AbstractSerializer
+{
+  private $file_location;
+
+  private $length = 9999;
+
+  private $data = array();
+
+  public static function clean($directory, $suffix, $filename='api') {
+    $loc = $directory . '/' . $filename . '.' . $suffix;
+    file_exists($loc) && unlink($loc);
+  }
+
+  public function __construct($directory, $suffix, $filename='api') {
+    $this->file_location = $directory . '/' . $filename . '.' . $suffix;
+    touch($this->file_location);
+    $file = fopen($this->file_location, 'r');
+    $this->_readFromFile($file);
+    fclose($file);
+  }
+
+  private function _readFromFile($file) {
+    $id = null;
+    while (!feof($file)) {
+      $line = stream_get_line($file, $this->length, "\n");
+      if ($id) {
+        $this->data[$id] .= $line . "\n";
+        if ($this->lineEnds($line)) {
+          $id = null;
+        }
+      }
+      elseif ($id = $this->lineStarts($line)) {
+        $this->data[$id] = $line . "\n";
+      }
+    }
+  }
+
+  public function __destruct() {
+    $tmp = fopen($this->file_location . '_tmp', 'w');
+
+    foreach ($this->header as $header_line) {
+      fwrite($tmp, $header_line . "\n");
+    }
+    foreach ($this->data as $id => $value) {
+      fwrite($tmp, $value . "\n");
+    }
+    /*foreach ($this->ids() as $id) {
+      foreach (explode("\n", $this->getString($id)) as $line) {
+        if ($line) {
+          fwrite($tmp, $this->indent . $line . "\n");
+        }
+      }
+    }*/
+    foreach ($this->footer as $footer_line) {
+      fwrite($tmp, $footer_line . "\n");
+    }
+
+    fclose($tmp);
+
+    unlink($this->file_location);
+
+    rename($this->file_location . '_tmp', $this->file_location);
+  }
+
+  public function ids() {
+    return array_keys($this->data);
+  }
+
+  protected function getString($id) {
+    if(array_key_exists($id, $this->data)){
+        return $this->data[$id];
+    }
+  }
+
+  public function set($id, $value) {
+    if (!$id) {
+      debug_print_backtrace();
+      die("Called set without an ID\n");
+    }
+
+    $content = $this->toString($value, $id);
+
+    $this->data[$id] = preg_replace('/^/m', $this->indent, $content);
+  }
+}
diff --git a/util/docscripts/lib/parser2/Dojo.php b/util/docscripts/lib/parser2/Dojo.php
index 280c48a..943c745 100644
--- a/util/docscripts/lib/parser2/Dojo.php
+++ b/util/docscripts/lib/parser2/Dojo.php
@@ -201,6 +201,7 @@ class Dojo {
   }
 
   private static function format_summary($summary) {
-    return preg_replace('%`([^`]+)`%', '<code>$1</code>', htmlentities($summary));
+      return htmlentities($summary);
+    //return preg_replace('%`([^`]+)`%', '<code>$1</code>', htmlentities($summary));
   }
 }
\ No newline at end of file
diff --git a/util/docscripts/lib/parser2/dojo2.inc b/util/docscripts/lib/parser2/dojo2.inc
index 9453bc3..ce50a45 100644
--- a/util/docscripts/lib/parser2/dojo2.inc
+++ b/util/docscripts/lib/parser2/dojo2.inc
@@ -13,430 +13,515 @@ require_once('DojoCommentBlock.php');
 $_dojo_properties_modules = array();
 
 function _dojo_get_namespaces($limit=null){
-  static $namespaces;
-  if (!isset($namespaces)) {
-    $namespaces = array();
-    $files = scandir('modules');
-    foreach ($files as $file) {
-      if (substr($file, -7) == '.module') {
-        $namespace = substr($file, 0, -7);
-        if (!$limit || in_array($namespace, $limit)) {
-          include_once('modules/' . $file);
-          $namespaces[] = substr($file, 0, -7);
-        }
-      }
-      elseif (substr($file, -18) == '.module.properties') {
-        $namespace = substr($file, 0, -18);
-        if (!$limit || in_array($namespace, $limit)) {
-          global $_dojo_properties_modules;
-          foreach (preg_split('%[\n\r]+%', file_get_contents('modules/' . $file)) as $line) {
-            list($line, ) = preg_split('%[!#]%', $line, 2);
-            if ($line = trim($line)) {
-              list($key, $line) = explode('=', $line, 2);
-              $key = str_replace('\\ ', ' ', trim($key));
-              $line = preg_replace('%^\s+%', '', $line);
-              if ($key == 'location') {
-                $line = _dojo_ensure_directory($line);
-              }
-              $_dojo_properties_modules[$namespace][$key] = $line;
-            }
-          }
-          $namespaces[] = substr($file, 0, -18);
-        }
-      }
-    }
-  }
-  return $namespaces;
+	static $namespaces;
+	if (!isset($namespaces)) {
+		$namespaces = array();
+		$files = scandir('modules');
+		foreach ($files as $file) {
+			if (substr($file, -7) == '.module') {
+				$namespace = substr($file, 0, -7);
+				if (!$limit || in_array($namespace, $limit)) {
+					include_once('modules/' . $file);
+					$namespaces[] = substr($file, 0, -7);
+				}
+			}
+			elseif (substr($file, -18) == '.module.properties') {
+				$namespace = substr($file, 0, -18);
+				if (!$limit || in_array($namespace, $limit)) {
+					global $_dojo_properties_modules;
+					foreach (preg_split('%[\n\r]+%', file_get_contents('modules/' . $file)) as $line) {
+						list($line, ) = preg_split('%[!#]%', $line, 2);
+						if ($line = trim($line)) {
+							list($key, $line) = explode('=', $line, 2);
+							$key = str_replace('\\ ', ' ', trim($key));
+							$line = preg_replace('%^\s+%', '', $line);
+							if ($key == 'location') {
+								$line = _dojo_ensure_directory($line);
+							}
+							$_dojo_properties_modules[$namespace][$key] = $line;
+						}
+					}
+					$namespaces[] = substr($file, 0, -18);
+				}
+			}
+		}
+	}
+	return $namespaces;
 }
 
 function dojo_get_include($node, $provide) {
-  if ($node->jsdoc_project_name == $provide->title) {
-    return 'Included automatically';
-  }
-  else {
-    return 'dojo.require("%s");';
-  }
+	if ($node->jsdoc_project_name == $provide->title) {
+		return 'Included automatically';
+	}
+	else {
+		return 'dojo.require("%s");';
+	}
 }
 
 function _dojo_ensure_directory($directory) {
-  if (!is_dir($directory)) {
-    die("$directory is not a directory\n");
-  }
-  else {
-    if(substr($directory, -1) != '/'){
-      $directory .= '/';
-    }
-  }
-  return $directory;
+	if (!is_dir($directory)) {
+		die("$directory is not a directory\n");
+	}
+	else {
+		if(substr($directory, -1) != '/'){
+			$directory .= '/';
+		}
+	}
+	return $directory;
 }
 
 function dojo_get_file_time($namespace, $file) {
-  if (function_exists($namespace . '_code_location')) {
-    return filectime(_dojo_ensure_directory(call_user_func($namespace . '_code_location')) . $file);
-  }
-  else {
-    global $_dojo_properties_modules;
-    return filectime($_dojo_properties_modules[$namespace]['location'] . $file);
-  }
+	if (function_exists($namespace . '_code_location')) {
+		return filectime(_dojo_ensure_directory(call_user_func($namespace . '_code_location')) . $file);
+	}
+	else {
+		global $_dojo_properties_modules;
+		return filectime($_dojo_properties_modules[$namespace]['location'] . $file);
+	}
 }
 
 function _jsdoc_file_list($dir = false, $recurse = false){
-  $output = array();
-
-  if (!$recurse) {
-    $old_dir = getcwd();
-    if (!is_dir($dir)) {
-      return array();
-    }
-    chdir($dir);
-    $dir = '.';
-  }
-  $files = scandir($dir);
-
-  foreach ($files as $file) {
-    if ($file{0} == '.') continue;
-    if (is_dir($dir . '/' . $file)) {
-      if ($recurse) {
-        $file = $dir . '/' . $file;
-      }
-      $output = array_merge($output, _jsdoc_file_list($file, true));
-    }else{
-      if (substr($file, -3) == '.js' && substr($file, -6) != '.xd.js') {
-        if ($recurse) {
-          $file = $dir . '/' . $file;
-        }
-        $output[] = $file;
-      }
-    }
-  }
-
-  if (!$recurse) {
-    chdir($old_dir);
-  }
-  return $output;
+	$output = array();
+
+	if (!$recurse) {
+		$old_dir = getcwd();
+		if (!is_dir($dir)) {
+			return array();
+		}
+		chdir($dir);
+		$dir = '.';
+	}
+	$files = scandir($dir);
+
+	foreach ($files as $file) {
+		if ($file{0} == '.') continue;
+		if (is_dir($dir . '/' . $file)) {
+			if ($recurse) {
+				$file = $dir . '/' . $file;
+			}
+			$output = array_merge($output, _jsdoc_file_list($file, true));
+		}else{
+			if (substr($file, -3) == '.js' && substr($file, -6) != '.xd.js') {
+				if ($recurse) {
+					$file = $dir . '/' . $file;
+				}
+				$output[] = $file;
+			}
+		}
+	}
+
+	if (!$recurse) {
+		chdir($old_dir);
+	}
+	return $output;
 }
 
 function dojo_get_files($limit=null) {
-    $namespaces = _dojo_get_namespaces($limit);
-    $files = array();
-    foreach ($namespaces as $namespace) {
-        if (function_exists($namespace . '_code_location')) {
-          $location = _dojo_ensure_directory(call_user_func($namespace . '_code_location'));
-        }
-        else {
-          global $_dojo_properties_modules;
-          $location = $_dojo_properties_modules[$namespace]['location'];
-        }
-        if (!$location) die($namespace . '_code_location does not return useful result');
-        $list = _jsdoc_file_list($location);
-        foreach ($list as $i => $item) {
-            // Skip internationalization/tests/demos files
-            if (preg_match('%(^|/|\\\\)(nls|tests|demos)(\\\\|/)%', $item)) {
-              unset($list[$i]);
-              continue;
-            }
-            $list[$i] = array($namespace, $item);
-        }
-        $files = array_merge($files, array_values($list));
-    }
-
-    return $files;
+		$namespaces = _dojo_get_namespaces($limit);
+		$files = array();
+		foreach ($namespaces as $namespace) {
+				// skip util directory, parser chokes on util/less
+				if($namespace == "util") continue;
+				if (function_exists($namespace . '_code_location')) {
+					$location = _dojo_ensure_directory(call_user_func($namespace . '_code_location'));
+				}
+				else {
+					global $_dojo_properties_modules;
+					$location = $_dojo_properties_modules[$namespace]['location'];
+				}
+				if (!$location) die($namespace . '_code_location does not return useful result');
+				$list = _jsdoc_file_list($location);
+				foreach ($list as $i => $item) {
+						// Skip internationalization/tests/demos files
+						if (preg_match('%(^|/|\\\\)(nls|tests|demos)(\\\\|/)%', $item)) {
+							unset($list[$i]);
+							continue;
+						}
+						$list[$i] = array($namespace, $item);
+				}
+				$files = array_merge($files, array_values($list));
+		}
+
+		return $files;
 }
 
-function _slashtoname($thing){
-    return str_replace("/", ".", $thing);
+function _amd_pseudodoc_fix($matches){
+	// adds a pseudo-block of aliases to trick parser into believing the things inside of define() callbacks
+	// are in fact global
+//	$out = $matches[1];
+//	$args = trim($matches[2]);
+//	if($args != ""){
+//		$pseudo = "){\n\n/*=====\n";
+//		$newargs = array();
+//		foreach(explode(",", $args) as $arg){
+//			$arg = trim($arg);
+//			$newargs[] = "_$arg";
+//			$pseudo .= "\tvar _$arg = $arg;\n";
+//		}
+//		$out .= join(",", $newargs);
+//		$pseudo .= "\n=====*/\n\n";
+//		$out .= $pseudo;
+//	}else{
+//		$out .= "){";
+//	}
+//	
+//	return $out;
+
+	// turn (dojo, dijit) into (this.dojo, this.dijit);
+	$args = $matches[3];
+	$freshargs = preg_replace('/\w+/', "_$0", $args);
+	$newargs = $args; // preg_replace('/\w+/', "this.$0", $args);
+	$body = $matches[4];
+
+	return ";(function" . $freshargs . "{" . $body . "})" . $args . ";";
+	
 }
 
-function _amd_unwrap($text){
-
-    $re = '/\/\/\s*AMD\-ID\s*"([^\n]+)"/i';
-    $bre = '/define\(([^\]]+)\]\s*\,[\s\n]*function.+/';
-    $depre = '/^[\'"]([-_a-zA-Z\/]+)[\'"]\s*,\s*\[(.*)$/';
-
-    preg_match($re, $text, $foo);
-    $anonmoduleid = $foo[1];
-    
-    // either speciam AMD-ID string found, or file startswith("define(")
-    if($anonmoduleid || substr($text, 0, 8) == "define(\""){
-
-        preg_match($bre, $text, $matches);
-        preg_match($depre, $matches[1], $parts);
-
-        $provide = _slashtoname($anonmoduleid ? $anonmoduleid : $parts[1]);
-        preg_match_all('/[\'"]([\w\/-_\!]+)[\'"],?/', $anonmoduleid ? $matches[0] : $parts[2], $deps);
-        $requires = $deps[1];
-        
-        $prefixtext = 'dojo.provide("' . $provide . '");';
-        $prefixtext .= "\n";
-        
-        preg_match_all('/[\'"]([\w\/-_\!]+)[\'"],?/', $parts[2], $deps);        
-        if(is_array($requires)){
-            foreach($requires as $dep){
-                $firstbit = substr($dep, 0, 5);
-                if($firstbit == "text!"){
-                    // do nothing
-                }else if($firstbit == "i18n!"){
-                    preg_match('/i18n\!(.+)\/nls\/(\w+)/', $dep, $bundlebits);
-                    $prefixtext .= 'dojo.requireLocalization("' . $bundlebits[1] . '", "' . $bundlebits[2] . '");';
-                    $prefixtext .= "\n";
-                }else if($dep != "dojo" && $dep != "dijit" && $dep != "dojox"){
-                    $prefixtext .= 'dojo.require("' . _slashtoname($dep) . '");';
-                    $prefixtext .= "\n";
-                }
-            }
-        }
-        
-        // strip out "AMD-result" comments? not sure what these are. 
-
-        $text = preg_replace($bre, "", $text);        
-        $text = preg_replace('/\s*(return\s+[_a-zA-Z\.0-9]+\s*;\s)?(\/\/.+)?\s*\}\);\s*$/', "", $text);
-
-        $text = $prefixtext . $text;
-        
-    }
-
-    return $text; 
-
+function _amd_unwrap($text, $namespace, $file_name) {
+	// looking for something like...
+	//
+	//	 define("my/module", ["path/to/module", "another/module"]
+	//	 define(["path/to/module", "another/module"]
+	//	 define(["path/to/module"]
+	//	 define([]
+	//
+	// if the mid is missing (which is the usual case), then the mid is given by the namespace + filename
+
+	if (preg_match('/\/\/>>not-amd/', $text) || !preg_match('/define\s*\(\s*([\'"]([^\'"]+)[\'"]\s*,\s*)?\[\s*([^\]]*?)\s*\]/', $text, $matches)) {
+		// not an AMD module
+		//print "not an AMD module\n\n\n"; //for debugging
+		return $text;
+	}
+
+	$mid = trim($matches[2]);
+	if ($mid=="" || empty($mid)) {
+		// prefix the namespace; remove the .js filetype
+		if (preg_match('/(.+)\.js/', $file_name, $midMatches)) {
+			$mid = $namespace . "/" . $midMatches[1];
+		} else {
+			//print "not an AMD module\n\n\n";	//for debugging
+			return $text;
+		}
+	}
+
+	$requires = "";
+	foreach (explode(",", $matches[3]) as $dep) {
+		// regex is looking for the trimmed contents of a quoted string
+		// if a plugin resource is given (e.g., "dojo/text!./path/to/template.html"), then return the plugin (e.g., "dojo/text")
+		if (preg_match('/[\'"]\s*([^\'"!]+)\!?[^\'"]*\s*[\'"]/', $dep, $match)) {
+			$dep = $match[1];
+			if (substr($dep, 0, 1)==".") {
+				// path is relative to mid
+				$dep = explode("/", $dep);
+				$ref = explode("/", $mid);
+				array_pop($ref);
+				foreach($dep as $part){
+					if ($part=="..") {
+						array_pop($ref);
+					} else if ($part!=".") {
+						array_push($ref, $part);
+					} 
+				}
+				$dep = implode(".", $ref);
+			} else {
+				// absolute path
+				$dep = str_replace("/", ".", $dep);
+			}
+			// don't dojo.require dojo or the CommonJs module lexical vars
+			if ($dep!="dojo" && $dep!="require" && $dep!="exports" && $dep!="module") {
+				$requires.= "dojo.require(\"" . $dep	. "\");\n";
+			}
+		} else {
+			// print "failed to find dependency name in what looks like an AMD module (" .	 $namespace . "/" . $file_name . ").\n";
+			// print $matches[0];
+		}
+	}
+	$result = "dojo.provide(\"" . str_replace("/", ".", $mid)	. "\");\n" . $requires; //
+	
+	// FIXME: temporary fix, inject pseudo-docs for AMD style define([], function(a,b,c))
+	// tricks parser into thinking a b and c are aliases to global objects:
+	// FIXME: regexp is really greedy. also breaks define statements in docs if doesn't match first one
+	// FIXME: will only break on define([ "eval!function() { return 'fml'; }" ); so don't do that.
+	$text = preg_replace_callback('/(define\((.*?)function(\s*\(.*?)\{(.*)\}\);)/s', "_amd_pseudodoc_fix", $text, 1);
+	
+	// old re:
+	// '/(define\(.*?function.*\()(.*)\)\s?\{/'
+	
+	//print $result . "\n\n"; //for debugging
+	return $result . $text;
 }
 
 function dojo_get_contents($namespace, $file_name) {
-  if (function_exists($namespace . '_code_location')) {
-    $location = _dojo_ensure_directory(call_user_func($namespace . '_code_location'));
-  }
-  else {
-    global $_dojo_properties_modules;
-    $location = $_dojo_properties_modules[$namespace]['location'];
-  }
-
-  $filedata = file_get_contents($location . '/' . $file_name);
-  $filedata = _amd_unwrap($filedata);
-
-  $lines = preg_replace('%/\*={3,}|={3,}\*/%', '', $filedata);
-  $parser = new JavaScriptParser(JavaScriptLanguage::tokenize($lines));
-  // print '<pre>';
-  // $statements = $parser->statements();
-  // print $statements[0]->resolve();
-  // print '</pre>';
-  // die();
-  $package = new JavaScriptStatements($parser->statements());
-
-  $output = array();
-
-  // Handle dojo.provide calls
-  foreach ($package->function_calls(TRUE, 'dojo.provide') as $call) {
-    if ($module = $call->arguments()->getString(0)) {
-      $output['#provides'] = $module;
-    }
-  }
-
-  $output['#resource'] = $file_name;
-
-  // Handle dojo.require calls
-  foreach ($package->function_calls(TRUE, 'dojo.require') as $call) {
-    if ($module = $call->arguments()->getString(0)) {
-      $output['#requires'][] = array('common', $module);
-    }
-  }
-
-  // Handle mixin/extend calls
-  foreach ($package->function_calls(TRUE, 'dojo.mixin', 'dojo.extend') as $call) {
-    $arguments = $call->arguments();
-    $assignment = $call->assignment();
-    $root = NULL;
-    if ($constructor = $arguments->getFunction(0)) {
-      if ($assignment) {
-        Dojo::roll_out($constructor, $assignment, FALSE, $output);
-      }
-    }
-    else {
-      $root = $arguments->getVariable(0, TRUE);
-      if ($call->name() == 'dojo.extend') {
-        $output[$root]['type'] = 'Function';
-      }
-    }
-
-    foreach (array_diff(array_unique(array($assignment, $root)), array(NULL)) as $root) {
-      $mixin = $call->name() == 'dojo.mixin';
-      for ($i = 1; $i < $arguments->length; $i++) {
-        if ($arguments->getObject($i)) {
-          $keys = array();
-          foreach ($arguments->getObject($i)->values() as $key => $values) {
-            $keys[] = $key;
-            $full_name = "$root.$key";
-            foreach ($values as $value) {
-              if ($value instanceof JavaScriptVariable) {
-                $key = $mixin ? $full_name : "$root.prototype.$key";
-                if ($key != $value->value()) {
-                  $output[$key]['alias'] = $value->value();
-                }
-              }
-              else {
-                Dojo::roll_out($value, $full_name, FALSE, $output);
-                $output[$full_name][$mixin ? 'attached' : 'prototype'] = $root;
-              }
-            }
-          }
-          Dojo::roll_out_comment_block($arguments->getObject($i), $root, $output, $keys);
-        }
-        elseif ($root && $full_name = $arguments->getVariable($i)) {
-          if ($mixin) {
-            $output[$root]['mixins']['normal'][] = $full_name;
-          }
-          else {
-            $output[$root]['chains']['prototype'][] = $full_name;
-          }
-        }
-      }
-    }
-  }
-
-  foreach ($package->function_calls(TRUE, 'dojo.declare') as $call) {
-    $arguments = $call->arguments();
-    $name = $arguments->getString(0);
-    if (!$name) {
-      continue;
-    }
-    $output[$name]['type'] = 'Function';
-    if ($superclass = $arguments->getVariable(1)) {
-      if ($superclass != 'null') {
-        $output[$name]['chains']['prototype'][] = $superclass;
-        $output[$name]['chains']['call'][] = $superclass;
-      }
-    }
-    elseif ($superclasses = $arguments->getArray(1)) {
-      for($i = 0; TRUE; $i++) {
-        if ($superclass = $superclasses->getVariable($i)) {
-          $output[$name]['chains']['prototype'][] = $superclass . ($i ? '.prototype' : '');
-          $output[$name]['chains']['call'][] = $superclass;
-        }
-        else {
-          break;
-        }
-      }
-    }
-    if ($mixin = $arguments->getObject(2)) {
-      $keys = $block_keys = Dojo::$block_keys;
-      $new_keys = array();
-      $constructors = array();
-      // Remember that bad code can have multiple matching keys
-      foreach ($mixin->values() as $key => $values) {
-        $new_keys[] = $key;
-        $full_name = "$name.$key";
-        foreach ($values as $value) {
-          if ($value instanceof JavaScriptFunction) {
-            if (in_array($key, array('constructor', 'preamble', 'postscript'))) {
-              $output[$full_name]['constructor'] = $key;
-              $output[$full_name]['prototype'] = $name;
-              $constructors[$full_name] = $value;
-              continue;
-            }
-          }
-          elseif ($value->type() == 'variable') {
-            if ($full_name != $value->value()) {
-              $output[$full_name]['alias'] = $value->value();
-            }
-            continue;
-          }
-
-          $output[$full_name]['prototype'] = $name;
-          $new_keys = array_unique(array_merge($new_keys, Dojo::roll_out($value, $full_name, FALSE, $output, $new_keys)));
-        }
-      }
-
-      foreach ($constructors as $full_name => $constructor) {
-        $new_keys = array_unique(array_merge($new_keys, Dojo::roll_out($constructor, $name, FALSE, $output, $new_keys)));
-        foreach ($output[$name] as $key => $value) {
-          if ($key != 'chains') {
-            $output[$full_name][$key] = $value;
-          }
-        }
-      }
-
-      Dojo::roll_out_comment_block($mixin, $name, $output, $new_keys);
-    }
-  }
-
-  // Variable assignments (global)
-  foreach ($package->assignments(TRUE) as $variable) {
-    foreach ($variable->names() as $name) {
-      $parts = explode('.', $name);
-      $name = implode('.', array_diff($parts, array('prototype')));
-      $last = array_pop($parts);
-
-      $is_prototype = ($last == 'prototype');
-
-      Dojo::roll_out($variable->value(), $name, FALSE, $output, array(), $is_prototype);
-
-      if (count($parts) && !$is_prototype) {
-        $output[$name]['attached'] = implode('.', $parts);
-      }
-    }
-  }
-
-  // dojo.provide creates new objects if needed
-  if (!empty($output['#provides'])) {
-    $parts = explode('.', $output['#provides']);
-    while (count($parts)) {
-      if (!array_key_exists(implode('.', $parts), $output)) {
-        $output[implode('.', $parts)] = array('type' => 'Object');
-      }
-      array_pop($parts);
-    }
-  }
-
-  // Set privacy, classlikeness, and clean up the summary a bit
-  foreach ($output as $object_name => $object) {
-    if ($object_name{0} == '#') {
-      continue;
-    }
-    $parts = explode('.', $object_name);
-    $last = array_pop($parts);
-    if ($last{0} == '_') {
-      $output[$object_name]['private'] = true;
-    }
-    if (preg_match('%\._+[^A-Z]%', implode('.', $parts), $match)) {
-        $output[$object_name]['private_parent'] = true;
-    }
-    if (is_array($object['tags'])) {
-      foreach ($object['tags'] as $tag) {
-        if ($tag == 'protected') {
-          unset($output[$object_name]['private']);
-          $output[$object_name]['protected'] = true;
-        }
-        elseif ($tag == 'private') {
-          unset($output[$object_name]['protected']);
-          $output[$object_name]['private'] = true;
-        }
-        elseif ($tag == 'deprecated') {
-          $output[$object_name]['deprecated'] = true;
-        }
-      }
-      $output[$object_name]['tags'] = array_diff($object['tags'], array('private', 'protected', 'deprecated'));
-    }
-
-    if (isset($object['inferred_type'])) {
-      if (empty($object['type'])) {
-        $output[$object_name]['type'] = $object['inferred_type'];
-      }
-      unset($output[$object_name]['inferred_type']);
-    }
-
-    if ($object['type'] == 'Function') {
-      if (preg_match('%^(_*)[A-Z]%', $last, $match)) {
-        if (strlen($match[1]) < 2) {
-          unset($output[$object_name]['private']);
-        }
-        $output[$object_name]['classlike'] = true;
-      }
-    }
-
-    if ($object['prototype'] && $output[$object['prototype']]) {
-      $output[$object['prototype']]['classlike'] = true;
-    }
-    elseif ($object['instance'] && $output[$object['instance']]) {
-      $output[$object['instance']]['classlike'] = true;
-    }
-  }
-
-  return $output;
-}
\ No newline at end of file
+
+	if (function_exists($namespace . '_code_location')) {
+		$location = _dojo_ensure_directory(call_user_func($namespace . '_code_location'));
+	}
+	else {
+		global $_dojo_properties_modules;
+		$location = $_dojo_properties_modules[$namespace]['location'];
+	}
+
+	$output = array();
+	$output['#debug'] = array();
+
+	$filedata = file_get_contents($location . '/' . $file_name);
+	$output['#raw_source'] = $filedata;
+	$filedata_amd = _amd_unwrap($filedata, $namespace, $file_name);
+	if($filedata_amd != $filedata){
+		$output['#unwrapped_source'] = $filedata_amd;
+	}
+	$filedata = $filedata_amd;
+	
+	$lines = preg_replace('%/\*={3,}|={3,}\*/%', '', $filedata);
+	
+	try{
+		$parser = new JavaScriptParser(JavaScriptLanguage::tokenize($lines));
+	}catch(Exception $e){
+		$output['#debug'][] = "Died parsing $file_name";
+		$output['#debug'][] = $e;
+		return $output;
+	}
+	
+//	print '<pre>';
+//	$statements = $parser->statements();
+//	print $statements[0]->resolve();
+//	print '</pre>';
+//	die();
+	
+	try{
+		$package = new JavaScriptStatements($parser->statements());		
+	}catch(Exception $e){
+		$output['#debug'][] = "Died parsing statements";
+		$output['#debug'][] = $e;
+		return $output;
+	}
+
+	// Handle dojo.provide calls
+	foreach ($package->function_calls(TRUE, 'dojo.provide') as $call) {
+		if ($module = $call->arguments()->getString(0)) {
+			$output['#provides'] = $module;
+		}
+	}
+
+	$output['#resource'] = $file_name;
+	
+	// Handle dojo.require calls
+	foreach ($package->function_calls(TRUE, 'dojo.require') as $call) {
+		if ($module = $call->arguments()->getString(0)) {
+			$output['#requires'][] = array('common', $module);
+		}
+	}
+
+	// Handle mixin/extend calls
+	foreach ($package->function_calls(TRUE, 'dojo.mixin', 'dojo.extend', 'lang.extend', 'lang.mixin', 'lang._mixin', 'dojo._mixin') as $call) {
+		$arguments = $call->arguments();
+		$assignment = $call->assignment();
+		$name = $call->name();
+		$root = NULL;
+		if ($constructor = $arguments->getFunction(0)) {
+			if ($assignment) {
+				Dojo::roll_out($constructor, $assignment, FALSE, $output);
+			}
+		}
+		else {
+			$root = $arguments->getVariable(0, TRUE);
+			if (endswith($name, 'extend')) {
+				$output[$root]['type'] = 'Function';
+			}
+		}
+
+		foreach (array_diff(array_unique(array($assignment, $root)), array(NULL)) as $root) {
+			$mixin = endswith($name, "mixin");
+			for ($i = 1; $i < $arguments->length; $i++) {
+				if ($arguments->getObject($i)) {
+					$keys = array();
+					foreach ($arguments->getObject($i)->values() as $key => $values) {
+						$keys[] = $key;
+						$full_name = "$root.$key";
+						foreach ($values as $value) {
+							if ($value instanceof JavaScriptVariable) {
+								$key = $mixin ? $full_name : "$root.prototype.$key";
+								if ($key != $value->value()) {
+									$output[$key]['alias'] = $value->value();
+								}
+							}
+							else {
+								Dojo::roll_out($value, $full_name, FALSE, $output);
+								$output[$full_name][$mixin ? 'attached' : 'prototype'] = $root;
+							}
+						}
+					}
+					Dojo::roll_out_comment_block($arguments->getObject($i), $root, $output, $keys);
+				}
+				elseif ($root && $full_name = $arguments->getVariable($i)) {
+					if ($mixin) {
+						$output[$root]['mixins']['normal'][] = $full_name;
+					}
+					else {
+						$output[$root]['chains']['prototype'][] = $full_name;
+					}
+				}
+			}
+		}
+	}
+
+	foreach ($package->function_calls(TRUE, 'dojo.declare', 'declare') as $call) {
+		$arguments = $call->arguments();
+		$name = $arguments->getString(0);
+		if (!$name) {
+			$assignment = $call->assignment();
+			$output['#debug'][] = "Found declare() without a name? check return value?" + $assignments;
+			continue;
+		} else{
+			// $output['#debug'][] = "Found declare w/ $name";
+		}
+		$output[$name]['type'] = 'Function';
+		if ($superclass = $arguments->getVariable(1)) {
+			if ($superclass != 'null') {
+				$output[$name]['chains']['prototype'][] = $superclass;
+				$output[$name]['chains']['call'][] = $superclass;
+			}
+		}
+		elseif ($superclasses = $arguments->getArray(1)) {
+			for($i = 0; TRUE; $i++) {
+				if ($superclass = $superclasses->getVariable($i)) {
+					$output[$name]['chains']['prototype'][] = $superclass . ($i ? '.prototype' : '');
+					$output[$name]['chains']['call'][] = $superclass;
+				}
+				else {
+					break;
+				}
+			}
+		}
+		if ($mixin = $arguments->getObject(2)) {
+			$keys = $block_keys = Dojo::$block_keys;
+			$new_keys = array();
+			$constructors = array();
+			// Remember that bad code can have multiple matching keys
+			foreach ($mixin->values() as $key => $values) {
+				$new_keys[] = $key;
+				$full_name = "$name.$key";
+				foreach ($values as $value) {
+					if ($value instanceof JavaScriptFunction) {
+						if (in_array($key, array('constructor', 'preamble', 'postscript'))) {
+							$output[$full_name]['constructor'] = $key;
+							$output[$full_name]['prototype'] = $name;
+							$constructors[$full_name] = $value;
+							continue;
+						}
+					}
+					elseif ($value->type() == 'variable') {
+						if ($full_name != $value->value()) {
+							$output[$full_name]['alias'] = $value->value();
+						}
+						continue;
+					}
+
+					$output[$full_name]['prototype'] = $name;
+					$new_keys = array_unique(array_merge($new_keys, Dojo::roll_out($value, $full_name, FALSE, $output, $new_keys)));
+				}
+			}
+
+			foreach ($constructors as $full_name => $constructor) {
+				$new_keys = array_unique(array_merge($new_keys, Dojo::roll_out($constructor, $name, FALSE, $output, $new_keys)));
+				foreach ($output[$name] as $key => $value) {
+					if ($key != 'chains') {
+						$output[$full_name][$key] = $value;
+					}
+				}
+			}
+
+			Dojo::roll_out_comment_block($mixin, $name, $output, $new_keys);
+		}
+	}
+
+	// Variable assignments (global)
+	foreach ($package->assignments(TRUE) as $variable) {
+		foreach ($variable->names() as $name) {
+			$parts = explode('.', $name);
+			$name = implode('.', array_diff($parts, array('prototype')));
+			$last = array_pop($parts);
+
+			$is_prototype = ($last == 'prototype');
+
+			Dojo::roll_out($variable->value(), $name, FALSE, $output, array(), $is_prototype);
+
+			if (count($parts) && !$is_prototype) {
+				$output[$name]['attached'] = implode('.', $parts);
+			}
+		}
+	}
+
+	// dojo.provide creates new objects if needed
+	if (!empty($output['#provides'])) {
+		$parts = explode('.', $output['#provides']);
+		while (count($parts)) {
+			if (!array_key_exists(implode('.', $parts), $output)) {
+				$output[implode('.', $parts)] = array('type' => 'Object');
+			}
+			array_pop($parts);
+		}
+	}
+
+	// Set privacy, classlikeness, and clean up the summary a bit
+	foreach ($output as $object_name => $object) {
+		if ($object_name{0} == '#') {
+			continue;
+		}
+		$parts = explode('.', $object_name);
+		$last = array_pop($parts);
+		if ($last{0} == '_') {
+			$output[$object_name]['private'] = true;
+		}
+		if (preg_match('%\._+[^A-Z]%', implode('.', $parts), $match)) {
+				$output[$object_name]['private_parent'] = true;
+		}
+		if (is_array($object['tags'])) {
+			foreach ($object['tags'] as $tag) {
+				if ($tag == 'protected') {
+					unset($output[$object_name]['private']);
+					$output[$object_name]['protected'] = true;
+				}
+				elseif ($tag == 'private') {
+					unset($output[$object_name]['protected']);
+					$output[$object_name]['private'] = true;
+				}
+				elseif ($tag == 'deprecated') {
+					$output[$object_name]['deprecated'] = true;
+				}
+			}
+			$output[$object_name]['tags'] = array_diff($object['tags'], array('private', 'protected', 'deprecated'));
+		}
+
+		if (isset($object['inferred_type'])) {
+			if (empty($object['type'])) {
+				$output[$object_name]['type'] = $object['inferred_type'];
+			}
+			unset($output[$object_name]['inferred_type']);
+		}
+
+		if ($object['type'] == 'Function') {
+			if (preg_match('%^(_*)[A-Z]%', $last, $match)) {
+				if (strlen($match[1]) < 2) {
+					unset($output[$object_name]['private']);
+				}
+				$output[$object_name]['classlike'] = true;
+			}
+		}
+
+		if ($object['prototype'] && $output[$object['prototype']]) {
+			$output[$object['prototype']]['classlike'] = true;
+		}
+		elseif ($object['instance'] && $output[$object['instance']]) {
+			$output[$object['instance']]['classlike'] = true;
+		}
+	}
+
+	return $output;
+}
+
+function endswith($haystack, $needle){
+	$length = strlen($needle);
+	$start = $length * -1; 
+	return (substr($haystack, $start) === $needle);
+}
diff --git a/util/docscripts/modules/util.module b/util/docscripts/modules/util.module
new file mode 100755
index 0000000..b60aa70
--- /dev/null
+++ b/util/docscripts/modules/util.module
@@ -0,0 +1,28 @@
+<?php
+
+function util_code_location() {
+  return '../../util/';
+}
+
+function util_project_name() {
+  return 'util';
+}
+
+function util_resource_name($namespace, $file) {
+  return $file;
+}
+
+function util_package_name($namespace, $file) {
+  //return;
+  $parts = explode('/', $file);
+  if ($parts[0] == '_base') {
+    return $namespace;
+  }
+  $file_parts = explode('.', array_pop($parts));
+  array_pop($file_parts);
+  array_push($parts, implode('.', $file_parts));
+  array_unshift($parts, $namespace);
+  return implode('.', $parts);
+}
+
+?>
\ No newline at end of file
diff --git a/util/docscripts/parsefile.php b/util/docscripts/parsefile.php
index 721c116..ca02231 100644
--- a/util/docscripts/parsefile.php
+++ b/util/docscripts/parsefile.php
@@ -52,6 +52,8 @@ function doc_test($ns, $file, $debug){
 		if(count($data) == 0){
 			if($debug){ print "Error: No data found. [" . $ns . "/" . $file . "]"; }
 			$ret = false;
+		}else{
+		    
 		}
 		
 		return $ret;
diff --git a/util/docscripts/preview.php b/util/docscripts/preview.php
new file mode 100644
index 0000000..2e73fac
--- /dev/null
+++ b/util/docscripts/preview.php
@@ -0,0 +1,389 @@
+<?php /*
+
+  preview.php - rudimentary api browser designed to expose flaws in
+  either the dojo doc parser or the effort to document the Dojo Toolkit
+  API. it is embarasingly inefficient and sloppy, but works.
+  
+  this file requires PHP5, and a full source tree of the dojo toolkit.
+
+  it parses a module, and dumps relevant API information made in real
+  time. PLEASE use this to preview how the parse tool will interpret
+  your code.
+
+  it covers all files in dojtool's modules/ directory dynamically, so
+  can be used to preview documentation in custom namespace code, as well.
+  
+  deep linking is possible via hash tags, eg:
+  http://archive.dojotoolkit.org/nightly/dojotoolkit/util/docscripts/preview.php#dojo/dom-class.js
+
+*/
+
+// hide warnings
+error_reporting(1);
+$ajaxy = !empty($_REQUEST['ajaxy']);
+$showall = isset($_REQUEST['showall']);
+
+?>
+<?php if(!$ajaxy){ ?>
+	<!DOCTYPE html>
+	<html>
+		<head>
+		
+			<title>API Preview tool | The Dojo Toolkit</title>
+		
+			<style type="text/css">
+				@import "../../dojo/resources/dojo.css"; 
+				@import "../../dijit/themes/claro/claro.css";
+				@import "../../dijit/themes/claro/document.css";
+				
+				body, html { width:100%; height:100%; margin:0; padding:0; overflow:hidden; }
+				
+				.dnone { display:none; } 
+				.topbar li { display:inline; padding:5px; } 
+				.pad {
+					padding:20px;
+					padding-top:8px;
+				}
+				#main { 
+					width:100%; height:100%;
+				}
+				
+				.claro ul {
+				    margin-left:10px;
+				}
+				
+				.claro ul ul {
+				    border-left: 1px dotted #ccc;
+				    margin-top:5px;
+				    padding-left:10px;
+				    list-style:none;
+				}
+				
+				.source pre {
+					margin:0; padding:0;
+					border: none;
+				}
+				pre.error {
+					color:red;
+					background:yellow;
+				}
+				
+				.claro ul .source ol {
+				    list-style: number;
+				}
+			</style>
+			
+			<script type="text/javascript" src="../../dojo/dojo.js" djConfig="parseOnLoad:true"></script>
+			<script type="text/javascript">
+				dojo.require("dojo.data.ItemFileReadStore");
+				dojo.require("dojo.hash");
+				dojo.require("dijit.Tree");
+				dojo.require("dijit.layout.BorderContainer");
+				dojo.require("dijit.layout.ContentPane");
+				dojo.require("dijit.layout.TabContainer");
+				dojo.require("dojox.NodeList.delegate");
+				
+				var fileStore, fileTree, apiPane;
+				
+				function tgShow(id){
+					dojo.toggleClass(id, "dnone");
+				}
+
+				function addTab(ns, file){
+					
+					var id = ns + "." + (file.split("/").join(".")),
+						dij = dijit.byId(id),
+						href = "?ns=" + ns + "&file=" + file + "&ajaxy=1&showall=1"
+					;
+					
+
+					if(!dij){
+						dij = new dijit.layout.ContentPane({
+							id: id, 
+							href: href,
+							title: id,
+							closable: true
+						});
+						dij.placeAt(apiPane);
+					}else{
+						dij.set("href", href + "&bust=" + (+new Date()));
+					}
+					apiPane.selectChild(dij);
+				};
+				
+				function gohash(hash){
+					// do an addTab for a ns/file extraction from the `hash` value
+					var all = hash.split("/"),
+						ns = all.shift(),
+						file = all.join("/")
+					;
+					console.warn("go hash:", ns, file);
+					ns && file && addTab(ns, file);
+				}
+				
+				dojo.subscribe("/dojo/hashchange", gohash);
+				
+				dojo.ready(function(){
+					
+					apiPane = dijit.byId("apiTabs");
+				//	dojo.connect(apiPane, "selectChild", function(child){
+				//		var hash = dojo.hash();
+				//		if(child.id !== hash){
+				//			dojo.hash(child.id);
+				//		}
+				//	});
+					
+					dojo.query("#apiTabs").delegate(".toggler", "onclick", function(e){
+						e && e.preventDefault();
+						dojo.query(this).parent().siblings(".t").toggleClass("dnone");
+					});
+
+					//	build the tree
+					fileStore = new dojo.data.ItemFileReadStore({
+						url: "_browse_tree.php"
+					});
+
+					fileTree = new dijit.Tree({
+						store: fileStore,
+						query: { type: "namespace" },
+						onClick: function(item){
+							var type = fileStore.getValue(item, "type");
+							if(type == "file"){
+								//	load it up
+								var ns = fileStore.getValue(item, "ns"),
+									file = fileStore.getValue(item, "full_name")
+								;
+								var c = dojo.hash();
+								console.warn(c, ns, file);
+								if(c == ns + "/" + file){
+									addTab(ns, file);
+								}else{
+									dojo.hash(ns + "/" + file);
+								}
+							}
+						}
+					});
+					dojo.place(fileTree.domNode, dijit.byId("fileTreePane").domNode);
+
+					// if we landed with a hash, lets use it:
+					var current = dojo.hash();
+					current && ~current.indexOf("/") && gohash(current);
+
+				});
+			</script>
+
+		</head>
+		<body class="claro">
+<?php
+
+} // $ajaxy
+
+include_once('lib/parser2/dojo2.inc');
+
+//*
+$tree = '';
+// no dojo.require() call made?
+$u = 0; 
+$files = dojo_get_files(); 
+foreach ($files as $set){ 
+	list($namespace, $file) = $set;
+	$data[$namespace][] = $file;
+}
+$namespaces = array_keys($data); 
+unset($files); 
+
+if(!empty($_REQUEST['ns'])){
+
+	$ns = $_REQUEST['ns'];
+	$ifile = $_REQUEST['file'];
+  
+
+	if($ifile){
+		$apiData = dojo_get_contents($ns,$ifile);
+
+		$waserror = FALSE;
+		$errorline = 0;
+		
+		$print .= "<h2>".htmlspecialchars($ns)."/".htmlspecialchars($ifile)."</h2><ul>";
+		foreach($apiData as $key => $val){
+			switch($key){
+				case "#resource" : break;
+				case "#requires" : 
+					$print .= "<li><h3>Requires:</h3><ul>";
+					foreach($val as $resource){
+						$print .= "<li>{$resource[1]} in {$resource[0]}";
+						if ($resource[2]) {
+							$print .= " in project {$resource[2]}";
+						}
+						$print .= "</li>"; 
+					}
+					$print .= "</ul></li>"; 
+					break;
+				case "#provides" :
+					$print .= "<li><h3>Provides:</h3><ul>";
+					$print .= "<li>$val</li>"; 
+					$print .= "</ul></li>"; 
+					break;
+				case "#debug":
+					$print .= "<div><h4>Debugging:</h4><ul>";
+					foreach($val as $message){
+						$print .= "<li>";
+						if(is_string($message)){
+							$print .= $message;
+						}else{
+							$er = $message->getMessage();
+							preg_match("/Line\ (\d+)/", $er, $matches);
+							if($matches[1]){
+								$waserror = TRUE;
+								$errorline = $matches[1];
+							}
+							$print .= "<pre>" . $message->getMessage() . "</pre>";
+						}
+						$print .= "</li>";
+					}
+					$print .= "</ul></div>";
+					break;
+				case "#raw_source":
+					$lines = explode("\n", $val);
+					$print .= "<div class='source'><h4><a href='#' class='toggler'>Source</a></h4><div class='t dnone'><ol>";
+					$i = 0;
+					foreach($lines as $line){
+						$i++;
+						$print .= "<li value='$i'>";
+						if($waserror && ($i == $errorline || $errorline + 1 == $i || $errorline - 1 == $i)){ 
+							$print .= "<pre class='error'>";
+						}else{ 
+							$print .= "<pre>";
+						}
+						$print .= htmlentities($line) . " </pre></li>";
+					}
+					$print .= "</ol></div></div>";
+					break;
+				case "#unwrapped_source":
+					if(!empty($val)){
+						$print .= "<div><h4><a href='#' class='toggler'>" . $key . "</a></h4><pre class='t dnone'>" . htmlentities($val) . "</pre></div>";
+					}
+					break;
+				default:
+					$print .= "<li><h4>".$key."</h4><ul> ";
+					foreach($val as $key2 => $val2){
+  
+						switch($key2){
+							// most things using dojo.declare() trigger this, eg: dijits
+							case "classlike":
+								$knownClasses[] = $key;
+								if ($_REQUEST['showall']) {
+									$print .= "<li>$key2</li>";
+								}
+								break;
+
+							// these are partially useless for our "overview" api, but set showall=1 in the
+							// url if you want to see these, too. sortof.
+							case "type" : 
+								$print .= "<li><em>".$key2."</em><div><pre>".htmlentities($val2)."</pre></div></li>"; 
+								break;
+							case "private_parent" :
+							case "prototype" :
+							case "instance" :
+							case "private" :
+							case "deprecated" :
+							case "protected" :
+							case "attached" :
+								if($_REQUEST['showall']){ $print .= "<li>".$key2." - ".$val2."</li>"; }
+								break;
+							case "alias" :
+							case "constructor" :
+								$print .= "<li>".$key2." - ".$val2."</li>";
+								break;
+				
+							// another array we want inspect more closely 
+							case "parameters" : 
+								$print .= "<li><em>parameters:</em> <ul>"; 
+								foreach($val2 as $param => $paramData){
+									$print .= "<li>".$param;
+									if (!empty($paramData['type'])) {
+										$print .= ": <em>(typeof ".$paramData['type'].")</em>";
+									}
+									$print .= "<div>";
+									if(!empty($paramData['summary'])){
+										$print .= "<pre>".htmlentities($paramData['summary'])."</pre>";
+									}
+									$print .= "</div></li>";
+								} //print_r($val2);				
+								$print .= "</ul></li>";
+								break;
+				
+								// the stripped source, and some minimal toggling to show/hide	
+							case "source" : 
+								$print .= "<li class=\"source\"><em>source: [<a onclick=\"tgShow('unique".++$u."');\">view</a>]</em> 
+									<div class=\"dnone\" id=\"unique".$u."\">\n
+									".ltrim(str_replace("\n","<br>",str_replace("\t"," ",$val2)))."
+									</div>";  
+								break;
+
+							case "tags":
+								$print .= "<li><em>$key2</em>: " . implode(' ', $val2) . '</li>';
+								break;
+
+							case "optional":
+								if ($val2) {
+									$print .= "<li><em>$key2</em></li>";
+								}
+								break;
+
+							case "chains" :
+							case "mixins" :
+								if (!empty($val2)) {
+									$print .= "<li><em>" . $key2 . ":</em> <ul>";
+									foreach ($val2 as $subtype => $chains) {
+										foreach ($chains as $chain) {
+											$print .= "<li>$chain: <em>($subtype)</em></li>";
+										}
+									}
+									$print .= "</ul></li>";
+								}
+								break;
+
+							// these are the ones we care about, and are fulltext/sometimes html
+							case "examples" :
+								foreach ($val2 as $example){
+									$print .= "<li><em>example</em><div><pre>".htmlentities($example)."</pre></div></li>";
+								}
+								break;
+
+							case "returns" :
+							case "return_summary" :
+							case "exceptions" :
+							case "description" :
+							case "summary" : $print .= "<li><em>".$key2."</em><div><pre>".htmlentities($val2)."</pre></div></li>"; break;
+
+							// this is a key we don't know about above, so show it just in case
+							default: 
+								$print .= "<li>?? ".$key2." = ".$val2." (debug: ".gettype($val2).") ??</li>"; 
+								break;
+						}
+					} 
+					$print .= "</ul></li>"; 
+					break;
+				}
+			}
+			$print .= "</ul>";
+		}
+	}
+
+if(!$ajaxy){ ?>
+<div dojoType="dijit.layout.BorderContainer" id="main">
+	<div dojoType="dijit.layout.ContentPane" id="fileTreePane" region="left" style="width: 250px; overflow: auto;" splitter="true"></div>
+	<div dojoType="dijit.layout.TabContainer" id="apiTabs" region="center">
+		<div dojoType="dijit.layout.ContentPane" id="apiPane" title="Crude API Browser">
+			<div class="pad"><?php echo $print; ?></div>
+		</div>
+	</div>
+</div>
+</body>
+</html>
+<?php }else{
+	// we just want the content we parsed
+	echo '<div class="pad">'.$print.'</div>';
+}
+?>
diff --git a/util/docscripts/tests/alias.js b/util/docscripts/tests/alias.js
new file mode 100644
index 0000000..d6572f3
--- /dev/null
+++ b/util/docscripts/tests/alias.js
@@ -0,0 +1,10 @@
+// one would expect this to work. 
+dojo.provide("util.docscripts.tests.alias");
+(function(_dojo){
+
+    dojo.sampleFunction = function(a, b, c){
+        // summary: WTF
+        return ""; // String
+    }
+    
+})(dojo); // (this.dojo) works
\ No newline at end of file
diff --git a/util/docscripts/tests/alias_amd.js b/util/docscripts/tests/alias_amd.js
new file mode 100644
index 0000000..b05ee89
--- /dev/null
+++ b/util/docscripts/tests/alias_amd.js
@@ -0,0 +1,8 @@
+define(["dojo","dijit"], function(_dojo){
+
+    dojo.sampleFunction = function(a, b, c){
+        // summary: WTF
+        return ""; // String
+    }
+    
+});
\ No newline at end of file
diff --git a/util/docscripts/tests/basic.js b/util/docscripts/tests/basic.js
new file mode 100644
index 0000000..94e9ce0
--- /dev/null
+++ b/util/docscripts/tests/basic.js
@@ -0,0 +1,225 @@
+dojo.provide("util.docscripts.tests.basic");
+(function(){
+
+	var url = dojo.moduleUrl("util.docscripts", "dumpObj.php") + "";
+	function getdata(file){
+		
+		var r;
+		dojo.xhrGet({ 
+			url: url + "?f=" + file,
+			sync: true,
+			handleAs:"json",
+			handle: function(response){
+				r = response;
+			}
+		});
+		return r;
+		
+	}
+	
+	var docs;
+	function getmember(key, obj){
+		obj = obj || docs;
+		return obj[key];
+	}
+	
+	doh.register("doctests.basic", [
+	
+		function actual_fetching(t){
+			docs = getdata("util/docscripts/tests/simple.js");
+			t.t(docs);
+			t.t(typeof docs == "object");
+			t.is(docs["#provides"], "util.docscripts.tests.simple", "provide() object found");
+			t.is(docs["#resource"], "docscripts/tests/simple.js", "filename expansion");
+			t.t(docs["util.docscripts.tests"], "provide() expansion");
+		},
+		
+		function simple_requires(t){
+			t.t(dojo.isArray(docs['#requires'][0]), "populated require");
+			t.t(~dojo.indexOf(docs["#requires"][0], "dojo.cookie"), "found cookie require");
+		},
+		
+		function module_level_docs(t){
+			var fb = getmember("util.docscripts.tests.simple");
+			t.is("Module level summary", fb.summary, "summary from psuedo on module obj");
+		},
+		
+		function basic_class(t){
+			
+			var fb = getmember("dojo.FooBar");
+			
+			t.t(fb, "dojo.FooBar docs exist");
+			t.t(fb.classlike, "classlike thinger found");
+			t.is("A Class", fb.summary, "picked up summary from post-decalre docs");
+			t.is("Function", fb.type, "inference");
+			t.is("A Class description", fb.description, "description from post-declare docs");
+			
+			t.t(dojo.isArray(fb.examples), "found examples");
+			t.is(1, fb.examples.length, "found one example exactly");
+			
+			var fbc = getmember("dojo.FooBar.constructor");
+			t.is(fbc.prototype, "dojo.FooBar", "prototype binding");
+			t.is(fbc.parameters.args.name, fb.parameters.args.name, "params from constructor implied on class");
+			
+			var mf = getmember("dojo.FooBar.memberFn");
+			t.t(mf, "member function picked out of declaration");
+
+			var params = mf.parameters;
+			t.is("String", params.a.type);
+			t.f(params.b.optional);
+			t.is("String", params.b.type);
+			t.f(params.b.optional);
+			t.is("Boolean", params.c.type);
+			t.t(params.c.optional, "last arg optional");
+			t.is("Integer", mf.returns);
+			t.is("A member function", mf.summary);
+			
+		},
+		
+		function inherited_class(t){
+			var fb2 = getmember("dojo.FooBar2");
+			t.t(fb2);
+			// TODO:
+			// check fb2.chains for dojo.FooBar
+			// check fb2.inheritance
+			// FIXME: 
+			// what is chains v prototype
+		},
+		
+		function mixin_docs(t){
+			var mv = getmember("dojo.mixedValue");
+			t.is("External doc block, mixed", mv.summary, "summary found for mixed value");
+			t.is("Integer", mv.type, "type infered from mixed value");
+			t.is("dojo", mv.attached, "alias lookup in d.mixin");
+			
+			var mf = getmember("dojo.mixedFunction");
+			t.is("dojo", mf.attached, "alias lookup in d.mixin");
+			t.is("Integer", mf.returns, "returns from return line");
+			t.is("From mixin", mf.summary, "basic summary");
+			t.is("a", mf.parameters.a.name, "parameter picked up");
+			t.t(mf.parameters.a.optional, "param is optional");
+			t.is(mf.parameters.a.summary, "Some number or not", "parameter description picked up");
+		},
+		
+		function basic_function(t){
+			
+			var fb = getmember("dojo.thisIsAtestFunction");
+			t.t(fb, "testFunction docs exist");
+			t.is("Testing a function", fb.summary);
+			t.is("String", fb.returns, "return value determined");
+			t.is("Testing a string parameter", fb.parameters.a.summary, "parameter summary picked out");
+		},
+		
+		function testfunction2(t){
+			var tf = getmember("dojo.testFunction2");
+			t.is("Simple summary", tf.summary);
+			t.is("Simple Description.\nOn Multiple lines.", tf.description);
+			t.t(tf.parameters.id.optional);
+			t.is("Duplicate matched in signature and in line", tf.parameters.id.summary);
+			t.is("String", tf.parameters.id.type);
+		},
+		
+		function test_returner(t){
+
+			// FIXME: the absence of a return comment populates only return_summary
+			// when it's like:
+			// ---
+			// returns: Foo|Bar|Baz
+			//		You'd expect Foo|Bar|Baz to be return value, and this to be return_summary
+			// ---
+			
+			var r = getmember("dojo.returner");
+			t.t(r);
+			
+			// FIXME: expected but not getting:
+			// t.is("String|Integer", r.returns);
+			// t.is("This should be description", r.return_summary);
+			
+			// FIXME: actually getting:
+			t.is("String|Integer\nThis should be description", r.return_summary);
+			t.f(r.returns);
+		},
+		
+		function test_multireturner(t){
+			var r = getmember("dojo.multiReturns");
+			t.t(r);
+			t.is("String|Integer", r.returns, "found all return statement types in block");
+			t.is("Simple multireturn check", r.summary);
+		},
+		
+		function aliased_query(t){
+			var dq = getmember("dojo.query.stub");
+			t.t(dq, "$ -> dojo.query unwrapped from closure");
+			t.is("Integer", dq.returns);
+			t.is("aliased to `dojo.query`", dq.summary, "FIX: requires undone <code>");
+		},
+		
+		function kwarg_test(t){
+			var kw = getmember("util.docscripts.tests.simple.__kwArgs");
+			var args = kw.parameters;
+			
+			// FIXME: should this be actually mixed into something that has a type=__kwArgs?
+			// eg: dojo.kwArgFunction.parameter.args object?
+			var kwf = getmember("dojo.kwArgFunction");
+			var kwp = kwf.parameters.args;
+			
+			t.is("util.docscripts.tests.simple.__kwArgs", kwp.type);
+			
+		},
+		
+//		function fetch_amd_style(t){
+//			docs = getdata("util/docscripts/tests/simple_amd.js");
+//			console.warn("amd-basic", docs);
+//		},
+//		
+//		function fetch_amd_declare(t){
+//			docs = getdata("util/docscripts/tests/declare_amd.js");
+//			console.warn("amg-declare", docs);
+//		},
+		
+		function functional(t){
+			// refs #13345
+			docs = getdata("util/docscripts/tests/functional.js");
+			var hasit = getmember("util.docscripts.tests.FunctionalThinger");
+			t.t(hasit, "object exists in parsed output, meaning parsing happened");
+		},
+		
+		function raw_declare_init(t){
+			docs = getdata("util/docscripts/tests/extend_declare.js");
+			t.t(true);
+		},
+		
+		function raw_declare(t){
+			var barbaz = getmember("dojo.BarBaz");
+			t.t(barbaz, "raw declare() call defined a named class");
+		},
+		
+		function lang_extend(t){
+			var someprop = getmember("dojo.BarBaz.someProp");
+			t.t(someprop, "lang.extend worked");
+			t.is("String", someprop.type, "lang.extend unwrapped innards");
+		},
+
+// FIXME; dojo.mixin(a.b.prototype, { ... }) parses, but shows up differently in the obj
+// ... differently than dojo.extend(a.b, { ... }) ... the former is attached to "a.b", the
+// latter attached to "a.b.prototype". no sure how this pans out for generate.php
+//
+//		function lang_mixin(t){
+//			var someprop = getmember("dojo.BarBaz.moreProps");
+//			console.log(docs, someprop);
+//			t.t(someprop, "lang._mixin worked");
+//			t.is("String", someprop.type, "lang._mixin unwrapped innards");
+//		},
+//		
+		
+		function winning(t){
+			var prop = getmember("dojo.BarBaz.winning");
+			console.warn(prop);
+			t.t(prop, "aliased extend() call resolves properly");
+			t.is("Boolean", prop.type);
+			t.is("Always true.", prop.summary, "are we? rad.")
+		}
+	
+	]);
+
+})();
diff --git a/util/docscripts/tests/declare_amd.js b/util/docscripts/tests/declare_amd.js
new file mode 100644
index 0000000..bccc63e
--- /dev/null
+++ b/util/docscripts/tests/declare_amd.js
@@ -0,0 +1,31 @@
+define("util/docscripts/tests/declare_amd", ["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit){
+
+	dojo.declare("foo.Bar", [dijit._Widget], { // util.docscripts.tests.declare_amd
+		// summary: A Thinger
+		// description: Some Long Thinger
+		// 
+		// boo: Integer
+		boo: 10,
+		
+		constructor: function(args){
+			// summary: The constructor
+			dojo.mixin(this, args);
+		},
+		
+		aMemberFn: function(/* String? */a){
+			// summary: Does something
+			// a: String?
+			//		Foo.
+			return a || ""; // String
+		},
+		
+		postCreate: function(){
+			this.inherited(arguments);
+			this.boo *= 2;
+		}
+		
+	});
+	
+	return foo.Bar;
+});
+	
diff --git a/util/docscripts/tests/declare_returns.js b/util/docscripts/tests/declare_returns.js
new file mode 100644
index 0000000..55585f0
--- /dev/null
+++ b/util/docscripts/tests/declare_returns.js
@@ -0,0 +1,7 @@
+define(["dojo", "dojo/declare"], function(dojo){
+
+    return dojo.declare("foo.Bar", null, {
+        // summary: FOOBAR LIVES
+    })
+
+});
diff --git a/util/docscripts/tests/doctests.js b/util/docscripts/tests/doctests.js
new file mode 100644
index 0000000..a9bd30b
--- /dev/null
+++ b/util/docscripts/tests/doctests.js
@@ -0,0 +1,3 @@
+dojo.provide("util.docscripts.tests.doctests");
+
+dojo.require("util.docscripts.tests.basic");
diff --git a/util/docscripts/tests/extend_declare.js b/util/docscripts/tests/extend_declare.js
new file mode 100644
index 0000000..23884bb
--- /dev/null
+++ b/util/docscripts/tests/extend_declare.js
@@ -0,0 +1,57 @@
+define(["dojo/main", "dojo/_base/declare", "dojo/_base/lang", "dijit", "dijit/_Widget"], function(dojo, decalre, lang, dijit, _Widget){
+
+	/*===== var _Widget = dijit._Widget =====*/
+
+	var x = declare("dojo.BarBaz", [_Widget], { // util.docscripts.tests.declare_amd
+		// summary: A Thinger
+		// description: Some Long Thinger
+		// 
+		// boo: Integer
+		boo: 10,
+		
+		constructor: function(args){
+			// summary: The constructor
+			dojo.mixin(this, args);
+		},
+		
+		aMemberFn: function(/* String? */a){
+			// summary: Does something
+			// a: String?
+			//		Foo.
+			return a || ""; // String
+		},
+		
+		postCreate: function(){
+			this.inherited(arguments);
+			this.boo *= 2;
+		}
+		
+	});
+	
+	lang.extend(dojo.BarBaz, {
+		// someProp: String
+		someProp: "test",
+		
+		anotherFn: function(/* String? */b){
+			// summary: Another Function
+			return 10; // Integer
+		}
+	})
+	
+	lang.mixin(dojo.BarBaz.prototype, {
+		// moreProps: String
+		//		Some more props.
+		moreProps: "winning"
+	})
+	
+	var omg = lang.extend;
+	
+	omg(dojo.BarBaz, {
+		// winning: Boolean
+		//	Always true.
+		winning: true
+	});
+	
+	return x;
+});
+	
diff --git a/util/docscripts/tests/functional.js b/util/docscripts/tests/functional.js
new file mode 100644
index 0000000..0b8dc01
--- /dev/null
+++ b/util/docscripts/tests/functional.js
@@ -0,0 +1,12 @@
+define(["dojo", "dojox/lang/functional", "dijit"], function(dojo, dlf, dijit){
+
+	return dojo.declare("util.docscripts.tests.FunctionalThinger", null, {
+		// summary:
+		//		This is a test.
+		constructor: function(args){
+			dojo._mixin(this, args);
+		}
+		
+	});
+
+});
\ No newline at end of file
diff --git a/util/docscripts/tests/runTests.php b/util/docscripts/tests/runTests.php
new file mode 100644
index 0000000..e183460
--- /dev/null
+++ b/util/docscripts/tests/runTests.php
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+    <head>
+    <title>Dojo CORE and BASE D.O.H. Unit Test Runner</title>
+    <meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?test=util/docscripts/tests/basic"></HEAD>
+    <BODY>
+        Redirecting to D.O.H runner.
+    </BODY>
+</HTML> 
diff --git a/util/docscripts/tests/simple.js b/util/docscripts/tests/simple.js
new file mode 100644
index 0000000..d6e0832
--- /dev/null
+++ b/util/docscripts/tests/simple.js
@@ -0,0 +1,132 @@
+dojo.provide("util.docscripts.tests.simple");
+/*=====
+	util.docscripts.tests.simple = {
+		// summary: Module level summary
+	};
+=====*/
+dojo.require("dojo.cookie");
+(function(d, $){
+	
+	d.thisIsAtestFunction = function(/* String */a){
+		// summary: Testing a function
+		// a: String
+		//		Testing a string parameter
+		return a.toUpperCase(); // String
+	}
+	
+	d.testFunction2 = function(/* String? */id){
+		// summary: Simple summary
+		// description:
+		//		Simple Description.
+		//		On Multiple lines.
+		// id: String?
+		//		Duplicate matched in signature and in line
+		// returns: String
+		//		Whatever
+		return (id || "").toUpperCase();
+	}
+	
+	d.declare("dojo.FooBar", null, {
+		// summary: A Class
+		// description: A Class description
+		// example:
+		//	|	This is a test
+		//
+		// member: Integer
+		//		Used for counting things
+		member: 0,
+		
+		memberFn: function(a, b, c){
+			// summary: A member function
+			// a: String
+			// b: String
+			// c: Boolean?
+			return 10; // Integer
+		},
+		
+		constructor: function(args){
+			// summary: The constructor.
+			dojo.mixin(this, args);
+		}
+		
+	});
+	
+	d.declare("dojo.FooBar2", dojo.FooBar, {
+		// inheritance: String
+		//		Checking declare mixins
+		inheritance:"rules"
+	});
+	
+	d.mixin(d, {
+		
+		// mixedValue: Integer
+		//		External doc block, mixed
+		mixedValue: 10,
+		
+		mixedFunction: function(a){
+			// summary: From mixin
+			// a: Integer?
+			//		Some number or not
+			return a * 10; // Integer
+		}
+	});
+	
+	d.extend(d.FooBar, {
+		
+		// extendedMember: Integer
+		//		External doc block, extended
+		extendedMember: 10,
+		
+		secondMember: function(a, b, c){
+			// summary: Another member function
+			// a: String?
+			// b: String?
+			// c: Boolean?
+			// returns: String
+			//		Some return description text.
+			return "Hello, World";
+		}
+	});
+	
+	/*=====
+	util.docscripts.tests.simple.__kwArgs = function(a, b, c){
+		// summary: Simple kwarg definition
+		// a: String
+		// b: Integer
+		// c: Boolean?
+		this.a = a;
+		this.b = b;
+		this.c = c;
+	};
+	=====*/
+	
+	d.kwArgFunction = function(/* util.docscripts.tests.simple.__kwArgs */args){
+		// summary: kwarg function test
+		// returns: String
+		return "winning.";
+	}
+	
+	$.stub = function(a, b){
+		// summary: aliased to `dojo.query`
+		return a * b; // Integer
+	}
+	
+	d.returner = function(a){
+		// summary: Simple returner check
+		// a: String|Integer
+		//		Multiple types for param
+		// returns: String|Integer
+		//		This should be description
+		return a; 
+	}
+	
+	d.multiReturns = function(a){
+		// summary: Simple multireturn check
+		if(a > 10){
+			return "A"; // String
+		}else{
+			return 10; // Integer
+		}
+	}
+	
+})(dojo, dojo.query);
\ No newline at end of file
diff --git a/util/docscripts/tests/simple_amd.js b/util/docscripts/tests/simple_amd.js
new file mode 100644
index 0000000..639a350
--- /dev/null
+++ b/util/docscripts/tests/simple_amd.js
@@ -0,0 +1,25 @@
+define(["dojo", "dojo/cookie"], function(dojo, cook){
+
+	dojo.thisIsAtestFunction = function(/* String */a){
+		// summary: Testing a function
+		// a: String
+		//		Testing a string parameter
+		return a.toUpperCase(); // String
+	}
+	
+	dojo.testFunction2 = function(/* String? */id){
+		// summary: Simple summary
+		// description:
+		//		Simple Description.
+		//		On Multiple lines.
+		// id: String?
+		//		Duplicate matched in signature and in line
+		return (id || "").toUpperCase(); // String
+	}
+
+	dojo.declare("foo.Bar", null, {
+		// summary: Nondojo NS populated
+	})
+
+	return dojo;
+});
diff --git a/util/doh/README b/util/doh/README
index 2f1d91a..87a8e0d 100644
--- a/util/doh/README
+++ b/util/doh/README
@@ -1,12 +1,97 @@
-DOH may be run standalone by issuing a command like the following:
+DOH: The Dojo Object Harness
+============================
 
-java -jar ../shrinksafe/js.jar runner.js testModule=tests.colors
+DOH is a unit test framework developed by the Dojo Toolkit Community. For the tutorial published
+with the latest release see: http://dojotoolkit.org/reference-guide/util/doh.html#util-doh.
 
-where the testModule argument is optional and shrinksafe/js.jar is just a
-convenient copy of the Rhino JavaScript engine -- the custom patch is not
-required.
+DOH is a constructed as an AMD package that uses doh/main.js for its main entry point. It may
+be executed in the browser or by node.js or rhino. Typically, it is loaded by the dojo AMD
+loader; however, it is also possible to use any complying loader. 
 
-Optional arguments include:
- * dojoUrl - specifies the location of dojo.js
- * testUrl - specifies a Javascript file to load with initialization code
- * testModule - specifies a test module in the dojo package namespace
+
+node.js
+=======
+
+To run DOH via node.js, issue the command
+
+> node path/to/dojo/dojo.js load=doh test=path/to/test/module
+
+For example, from the util/doh/ directory you can run the self test as follows:
+
+~/dev/dojotoolkit/util/doh> node ../../dojo/dojo.js load=doh test=doh/tests/selfTest
+
+Since node.js includes executing scripts to discover their location, the dojo node bootstrap
+can discover baseUrl (the dojo directory) without further help.
+
+
+rhino
+=====
+
+To run DOH via rhino, issue the command
+
+>java -jar path/to/js.jar path/to/dojo/dojo.js baseUrl=path/to/dojo load=doh test=path/to/test/module
+
+For example, from the util/doh/ directory, you can run the self test as follows (assumes js.jar is in the user's
+home directory):
+
+~/dev/dojotoolkit/util/doh> java -jar ../shrinksafe/js.jar ../../dojo/dojo.js baseUrl=../../dojo load=doh test=doh/tests/selfTest
+
+Since rhino does not give scripts the ability to discover their location, you must do one of the following
+
+  * provide a baseUrl command line argument that specifies the dojo directory
+  * execute the command form the the dojo directory
+
+Here's the equivalent example command from the dojo directory:
+
+~/dev/dojotoolkit/dojo> java -jar ../util/shrinksafe/js.jar dojo.js load=doh test=doh/tests/selfTest
+
+
+browser
+=======
+
+To run DOH in the browser, point your browser to util/DOH/runner.html. You'll also need to provide at least one
+test module to execute by the query parameter "test". For example, to run the dojo unit tests, the URL would
+look something like...
+
+http://localhost/dev/dojotoolkit/util/doh/runner.html?test=dojo/tests/module
+
+(Of course the host and path--localhost and dev/dojotoolkit/util in the example--will depend on how you've configured
+your test environment.
+
+DOH includes the following query parameters:
+
+test: 
+a comma-separated-list of AMD module identifiers that contain the tests to load.
+
+testUrl:
+deprecated alias for test
+
+paths:
+a semicolon-separated-list of comma-separated-pairs of (module-identifier -> path-prefix) to provide to the loader's
+path configuration property.
+
+registerModulePath:
+deprecated alias for paths
+
+boot:
+a comma-separated-list of Javascript resources to script inject to bootstrap DOH. Defaults to "../../dojo/dojo.js",
+which causes DOH to use the dojo AMD loader. You may use this parameter to provide and alternate loader.
+
+dojoUrl:
+deprecated alias for boot
+
+async:
+If provided, instructs the dojo loader to operate in async mode.
+
+breakOnError:
+If provided, instructs DOH to break into the debugger upon an error.
+
+
+About Hard Dojo Dependency
+==========================
+
+As of v1.7 DOH depends on dojo base via AMD define dependency lists. If this causes you concern, you
+may sandbox dojo by setting dojoConfig.scopeMap.dojo to falsy which will result in *not* publishing
+dojo to the global namespace. Alternatively, you may provide a custom library that includes the
+part of the dojo base API used by DOH and map the AMD module identifier "dojo" to this custom library.
+However, we know of no good reason to follow either of these paths.
diff --git a/util/doh/Robot.html b/util/doh/Robot.html
index eef0f8f..677abe0 100644
--- a/util/doh/Robot.html
+++ b/util/doh/Robot.html
@@ -1,5 +1,6 @@
-<html style="margin:0px; padding:0px;">
-<body style="margin:0px; padding:0px; border:0px none;background-color:transparent;" onload="init()">
+<!DOCTYPE html>
+<html style="margin:0px; padding:0px; border:0px none; overflow:hidden;">
+<head>
 <script>
 	// support document.domain
 	// Yes, we need this try/catch to handle document.domain.
@@ -11,7 +12,7 @@
 	try{
 		// Was the passed domain just a stupid browser default?
 		// If so, this statement will work.
-		window.frameElement.ownerDocument;
+		var test=window.frameElement.ownerDocument;
 	}catch(e){
 		// Permission Denied.
 		// Means user explicitly set document.domain elsewhere.
@@ -117,28 +118,32 @@
 		return false;
 	}
 
+	var rf=null;
 	doh.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(){
-			var rf = document.getElementsByTagName('input')[0];
 			rf.style.visibility = "hidden";
 			doh.robot._run(window.frameElement);
  		}, 0);
 	};
 </script>
-<input type="text" tabIndex="-1" style="border:0px none;margin:0px;padding:0px;position:absolute;left:0px;top:0px;width:200px;height:42px;background-color:white;z-index:9999;opacity:0;filter:alpha(opacity=0);cursor:default;"
+</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;"
 	onmousewheel="_onmousewheel(arguments[0])"
 	onmousedown="_onmousedown(arguments[0])"
 	onkeypress="_onkeypress(arguments[0])"
 	onfocus="_onfocus(this)"
-	onblur="_onblur(arguments[0])">
+	onblur="_onblur(arguments[0])"></input>
 <script>
-	if(document.getElementsByTagName('input')[0].addEventListener){
-		document.getElementsByTagName('input')[0].addEventListener('DOMMouseScroll', _onmousewheel, false);
+	rf = document.getElementsByTagName('input')[0];
+	if(rf.addEventListener){
+		rf.addEventListener('DOMMouseScroll', _onmousewheel, false);
 	}
 </script>
+<img src="robot/signature.png" style="width:3px; height:3px; position:absolute; left:0px; top:0px; z-index:9999"></img>
 <script>
 	// taken from hostenv_browser.js
 	// Dojo is not always available to DOH
diff --git a/util/doh/_browserRunner.js b/util/doh/_browserRunner.js
index 59948b4..e4d525c 100644
--- a/util/doh/_browserRunner.js
+++ b/util/doh/_browserRunner.js
@@ -1,12 +1,8 @@
-// FIXME: need to add prompting for monkey-do testing
-
-(function(){
-
-//here's the definition of doh/_browserRunner
-
-var d= function(doh) {
+define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
+	doh.isBrowser= true;
+	var topdog;
 	try{
-		var topdog = (window.parent == window) || !Boolean(window.parent.doh);
+		topdog = (window.parent == window) || !Boolean(window.parent.doh);
 	}catch(e){
 		//can't access window.parent.doh, then consider ourselves as topdog
 		topdog=true;
@@ -19,7 +15,7 @@ var d= function(doh) {
 			return document.getElementById(id);
 		};
 
-		var _addOnEvt = function(	type,		// string
+		var _addOnEvt = function( type,		// string
 									refOrName,	// function or string
 									scope){		// object, defaults is window
 
@@ -66,7 +62,7 @@ var d= function(doh) {
 					return Math.round(n/360000)/10+"h";
 			}
 		};
-		
+
 		var _logBacklog = [], _loggedMsgLen = 0;
 		var sendToLogPane = function(args, skip){
 			var msg = "";
@@ -106,10 +102,10 @@ var d= function(doh) {
 			}
 			return n;
 		}
-		
+
 		doh._jumpToLog = function(e){
 			//console.log(e);
-			
+
 			var node = findTarget(e?e.target:window.event.srcElement);
 			if(!node){
 				return;
@@ -196,54 +192,46 @@ var d= function(doh) {
 				os.apply(doh,arguments);
 			}
 		})(doh._setupGroupForRun);
-		
-		doh._report = (function(or){
-			//overload _report to insert a tfoot
-			return function(){
-				var tb = byId("testList");
-				if(tb){
-					var tfoots=tb.getElementsByTagName('tfoot');
-					if(tfoots.length){
-						tb.removeChild(tfoots[0]);
-					}
-					var foot = tb.createTFoot();
-					var row = foot.insertRow(-1);
-					row.className = 'inProgress';
-					var cell=row.insertCell(-1);
-					cell.colSpan=2;
-					cell.innerHTML="Result";
-					cell = row.insertCell(-1);
-					cell.innerHTML=this._testCount+" tests in "+this._groupCount+" groups /<span class='failure'>"+this._errorCount+"</span> errors, <span class='failure'>"+this._failureCount+"</span> failures";
-					cell.setAttribute('_target',_loggedMsgLen+1);
-					row.insertCell(-1).innerHTML=formatTime(doh._totalTime);
+
+		var originalDohReport= doh._report;
+		doh._report = function(){
+			var tb = byId("testList");
+			if(tb){
+				var tfoots=tb.getElementsByTagName('tfoot');
+				if(tfoots.length){
+					tb.removeChild(tfoots[0]);
 				}
-				
-				//This location can do the final performance rendering for the results
-				//of any performance tests.
-				var plotResults = null;
-				var standby;
-				if(doh.perfTestResults){
-					if(window.dojo){
-						//If we have dojo and here are perf tests results,
-						//well, we'll use the dojo charting functions
-						dojo.require("dojox.charting.Chart2D");
-						dojo.require("dojox.charting.DataChart");
-						dojo.require("dojox.charting.plot2d.Scatter");
-						dojo.require("dojox.charting.plot2d.Lines");
-						dojo.require("dojo.data.ItemFileReadStore");
-						plotResults = doh._dojoPlotPerfResults;
-					}else{
-						plotResults = doh._asciiPlotPerfResults;
-					}
+				var foot = tb.createTFoot();
+				var row = foot.insertRow(-1);
+				row.className = 'inProgress';
+				var cell=row.insertCell(-1);
+				cell.colSpan=2;
+				cell.innerHTML="Result";
+				cell = row.insertCell(-1);
+				cell.innerHTML=this._testCount+" tests in "+this._groupCount+" groups /<span class='failure'>"+this._errorCount+"</span> errors, <span class='failure'>"+this._failureCount+"</span> failures";
+				cell.setAttribute('_target',_loggedMsgLen+1);
+				row.insertCell(-1).innerHTML=formatTime(doh._totalTime);
+			}
+
+			//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);
+
+					plotResults = doh._dojoPlotPerfResults;
 					try{
 						var g;
 						var pBody = byId("perfTestsBody");
 						var chartsToRender = [];
-
-						if(doh.perfTestResults){
-							doh.showPerfTestsPage();
-						}
+						// store analytics for reading later
+						// keyed on test group name, each value is in turn an object keyed on test name
+						doh.perfTestAnalytics={};
+						doh.showPerfTestsPage();
 						for(g in doh.perfTestResults){
+							doh.perfTestAnalytics[g]={};
 							var grp = doh.perfTestResults[g];
 							var hdr = document.createElement("h1");
 							hdr.appendChild(document.createTextNode("Group: " + g));
@@ -262,7 +250,7 @@ var d= function(doh) {
 								ind.appendChild(div);
 
 								//Figure out the basic info
-								var results = "<b>TRIAL SIZE: </b>"  + fResults.trials[0].testIterations + " iterations<br>" +
+								var results = "<b>TRIAL SIZE: </b>"	 + fResults.trials[0].testIterations + " iterations<br>" +
 									"<b>NUMBER OF TRIALS: </b>" + fResults.trials.length + "<br>";
 
 								//Figure out the average test pass cost.
@@ -273,13 +261,22 @@ var d= function(doh) {
 									iAvgArray.push(fResults.trials[i].average);
 									tAvgArray.push(fResults.trials[i].executionTime);
 								}
-								results += "<b>AVERAGE TRIAL EXECUTION TIME: </b>" + doh.average(tAvgArray).toFixed(10) + "ms.<br>";
-								results += "<b>MAXIMUM TEST ITERATION TIME: </b>" + doh.max(iAvgArray).toFixed(10) + "ms.<br>";
-								results += "<b>MINIMUM TEST ITERATION TIME: </b>" + doh.min(iAvgArray).toFixed(10) + "ms.<br>";
-								results += "<b>AVERAGE TEST ITERATION TIME: </b>" + doh.average(iAvgArray).toFixed(10) + "ms.<br>";
-								results += "<b>MEDIAN TEST ITERATION TIME: </b>" + doh.median(iAvgArray).toFixed(10) + "ms.<br>";
-								results += "<b>VARIANCE TEST ITERATION TIME: </b>" + doh.variance(iAvgArray).toFixed(10) + "ms.<br>";
-								results += "<b>STANDARD DEVIATION ON TEST ITERATION TIME: </b>" + doh.standardDeviation(iAvgArray).toFixed(10) + "ms.<br>";
+								var analytics=doh.perfTestAnalytics[g][f]={
+									averageTrialExecutionTime: doh.mean(tAvgArray),
+									maxTestIterationTime: doh.max(iAvgArray),
+									minTestIterationTime: doh.min(iAvgArray),
+									averageTestIterationTime: doh.mean(iAvgArray),
+									medianTestIterationTime: doh.median(iAvgArray),
+									varianceTestIterationTime: doh.variance(iAvgArray),
+									standardDeviationTestIterationTime: doh.sd(iAvgArray)
+								};
+								results += "<b>AVERAGE TRIAL EXECUTION TIME: </b>" + analytics.averageTrialExecutionTime.toFixed(10) + "ms.<br>";
+								results += "<b>MAXIMUM TEST ITERATION TIME: </b>" + analytics.maxTestIterationTime.toFixed(10) + "ms.<br>";
+								results += "<b>MINIMUM TEST ITERATION TIME: </b>" + analytics.minTestIterationTime.toFixed(10) + "ms.<br>";
+								results += "<b>AVERAGE TEST ITERATION TIME: </b>" + analytics.averageTestIterationTime.toFixed(10) + "ms.<br>";
+								results += "<b>MEDIAN TEST ITERATION TIME: </b>" + analytics.medianTestIterationTime.toFixed(10) + "ms.<br>";
+								results += "<b>VARIANCE TEST ITERATION TIME: </b>" + analytics.varianceTestIterationTime.toFixed(10) + "ms.<br>";
+								results += "<b>STANDARD DEVIATION ON TEST ITERATION TIME: </b>" +analytics.standardDeviationTestIterationTime.toFixed(10) + "ms.<br>";
 
 								//Okay, attach it all in.
 								div.innerHTML = results;
@@ -324,11 +321,12 @@ var d= function(doh) {
 					}catch(e){
 						doh.debug(e);
 					}
-				}
-				or.apply(doh,arguments);
+				});
 			}
-		})(doh._report);
-		
+			originalDohReport.apply(doh,arguments);
+		};
+
+
 		doh.error = undefined;
 		if(this["opera"] && opera.postError){
 			doh.debug = function(){
@@ -343,27 +341,23 @@ var d= function(doh) {
 			if(console.error){
 				doh.error = function(){
 					sendToLogPane.call(window, arguments);
-					console.error.apply(console, arguments);
+					console.error(Array.prototype.join.call(arguments, " "))
 				};
 			}
 			if(console.debug){
 				doh.debug = function(){
 					sendToLogPane.call(window, arguments);
-					console.debug.apply(console, arguments);
+					console.debug(Array.prototype.join.call(arguments, " "))
 				};
 			}else if(console.info){
 				doh.debug = function(){
 					sendToLogPane.call(window, arguments);
-					console.info.apply(console, arguments);
+					console.info(Array.prototype.join.call(arguments, " "))
 				};
 			}else{
 				doh.debug = function(){
-					var msg = "";
-					for(var x=0; x<arguments.length; x++){
-						msg += " "+arguments[x];
-					}
-					sendToLogPane([msg]);
-					console.log("DEBUG:"+msg);
+					sendToLogPane.call(window, arguments);
+					console.log("DEBUG:"+ Array.prototype.join.call(arguments, " "));
 				};
 			}
 		}else{
@@ -372,7 +366,6 @@ var d= function(doh) {
 			}
 		}
 		doh.error = doh.error || doh.debug;
-
 		var loaded = false;
 		var groupTemplate = null;
 		var testTemplate = null;
@@ -549,7 +542,7 @@ var d= function(doh) {
 
 		doh._updateGlobalProgressBar = function(p,success,group){
 			var outerContainer=byId("progressOuter");
-					
+
 			var gdiv=outerContainer.childNodes[doh._runedSuite-1];
 			if(!gdiv){
 				gdiv=document.createElement('div');
@@ -590,7 +583,7 @@ var d= function(doh) {
 				if(gn && doh._curTestCount){
 					var p = doh._runed/doh._curTestCount;
 					var groupfail = this._updateGlobalProgressBar((doh._runedSuite+p-1)/doh._groupCount,success,group);
-					
+
 					var pbar = gn.getElementsByTagName("td")[2].lastChild;
 					pbar.className = groupfail?"failure":"success";
 					pbar.style.width = parseInt(p*100)+"%";
@@ -599,19 +592,17 @@ var d= function(doh) {
 			}
 			this._groupTotalTime += elapsed;
 			this.debug((success ? "PASSED" : "FAILED"), "test:", fixture.name, elapsed, 'ms');
-		}
+		};
 
-		// FIXME: move implementation to _browserRunner?
-		doh.registerUrl = function(	/*String*/ group,
-										/*String*/ url,
-										/*Integer*/ timeout){
-			var tg = new String(group);
-			this.register(group, {
+		doh._registerUrl = function(group, url, timeout, type, dohArgs){
+			group= group || url;
+			this._registerTest(group, {
 				name: url,
 				setUp: function(){
-					doh.currentGroupName = tg;
+					doh.currentGroupName = group;
 					doh.currentGroup = this;
 					doh.currentUrl = url;
+					doh.dohArgs = dohArgs;
 					this.d = new doh.Deferred();
 					doh.currentTestDeferred = this.d;
 					doh.showTestPage();
@@ -632,8 +623,8 @@ var d= function(doh) {
 					// byId("testBody").src = "about:blank";
 					doh.showLogPage();
 				}
-			});
-		}
+			}, type);
+		};
 
 		//
 		// Utility code for runner.html
@@ -810,9 +801,6 @@ var d= function(doh) {
 					chart.setStore(ifs, {name:"*"}, "trials");
 				};
 
-				doh._asciiPlotPerfResults = function(){
-					//TODO:  Implement!
-				};
 			}
 		);
 	}else{
@@ -822,9 +810,6 @@ var d= function(doh) {
 		var _thisGroup = _doh.currentGroupName;
 		var _thisUrl = _doh.currentUrl;
 		if(_thisGroup){
-			doh._testRegistered = function(group, tObj){
-				_doh._updateTestList(_thisGroup, tObj);
-			}
 			doh._onEnd = function(){
 				_doh._errorCount += doh._errorCount;
 				_doh._failureCount += doh._failureCount;
@@ -832,19 +817,17 @@ var d= function(doh) {
 				// should we be really adding raw group counts?
 				//_doh._groupCount += doh._groupCount;
 				_doh.currentTestDeferred.callback(true);
-			}
-			var otr = doh._getTestObj;
-			doh._getTestObj = function(){
-				var tObj = otr.apply(doh, arguments);
-				tObj.name = _thisUrl+"::"+arguments[0]+"::"+tObj.name;
-				return tObj;
-			}
+			};
+			doh._testRegistered = function(group, fixture){
+				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._testStarted = function(group, fixture){
 				_doh._testStarted(_thisGroup, fixture);
-			}
+			};
 			doh._testFinished = function(g, f, s){
 				_doh._testFinished(_thisGroup, f, s);
 
@@ -868,33 +851,17 @@ var d= function(doh) {
 						doh.debug(e);
 					}
 				}
-			}
+			};
 			doh._groupStarted = function(g){
 				if(!this._setParent){
 					_doh._curTestCount = this._testCount;
 					_doh._curGroupCount = this._groupCount;
 					this._setParent = true;
 				}
-			}
+			};
 			doh._report = function(){
 			};
 		}
 	}
-};
-
-// this is guaranteed in the global scope, not matter what kind of eval is thrown at us
-// define global doh
-if(typeof doh == "undefined"){
-	doh = {};
-}
-if (typeof define == "undefined" || define.vendor=="dojotoolkit.org") {
-	// using dojo 1.x loader or no dojo on the page
-	if(typeof dojo !== "undefined"){
-		dojo.provide("doh._browserRunner");
-	}
-	d(doh);
-}else{
-	// using an AMD loader
-	doh.browserRunnerFactory= d;
-}
-}).call(null);
+	return doh;
+});
diff --git a/util/doh/_nodeRunner.js b/util/doh/_nodeRunner.js
new file mode 100644
index 0000000..827db47
--- /dev/null
+++ b/util/doh/_nodeRunner.js
@@ -0,0 +1,32 @@
+define(["doh/runner", "require"], function(doh, require) {
+	doh.debug= console.log;
+	doh.error= console.log;
+
+	// Override the doh._report method to make it quit with an
+	// appropriate exit code in case of test failures.
+	var oldReport = doh._report;
+	doh._report = function(){
+		oldReport.apply(doh, arguments);
+		if(this._failureCount > 0 || this._errorCount > 0){
+			process.exit(1);
+		}
+	};
+
+	console.log("\n"+doh._line);
+	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++) {
+		arg= args[i];
+		if (arg.length==2 && arg[0]=="test") {
+			var test= arg[1];
+			console.log("loading test " + test);
+			tests.push(test);
+		}
+	}
+	console.log(doh._line, "\n");
+
+	require(tests, function() {
+		doh.run();
+	});
+});
diff --git a/util/doh/_parseURLargs.js b/util/doh/_parseURLargs.js
new file mode 100644
index 0000000..c725092
--- /dev/null
+++ b/util/doh/_parseURLargs.js
@@ -0,0 +1,233 @@
+(function(){
+	var
+		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,
+
+		test= 
+			// zero to many AMD modules and/or URLs to load; provided by csv URL query parameter="test"
+			// For example, the URL...
+			//
+			//		 path-to-util/doh/runner.html?test=doh/selfTest,my/path/test.js
+			//
+			// ...will load...
+			//
+			//	 * the AMD module doh/selfTest
+			//	 * the plain old Javascript resource my/path/test.js
+			//
+			["dojo/tests/module"],
+
+		paths = 
+			// zero to many path items to pass to the AMD loader; provided by semicolon separated values 
+			// for URL query parameter="paths"; each path item has the form <from-path>,<to-path>
+			// i.e. path-to-util/doh/runner.html?paths=my/from/path,my/to/path;my/from/path2,my/to/path2
+			{},
+			
+		dohPlugins = 
+			// Semicolon separated list of files to load before the tests.
+			// Idea is to override aspects of DOH for reporting purposes.
+			"",
+
+		breakOnError = 
+			// boolean; instructs doh to call the debugger upon a test failures; this can be helpful when
+			// trying to isolate exactly where the test failed
+			false,
+
+		async = 
+			// boolean; config require.asyc==true before loading boot; this will have the effect of making
+			// version 1.7+ dojo bootstrap/loader operating in async mode
+			false,
+
+		sandbox = 
+			// boolean; use a loader configuration that sandboxes the dojo and dojox objects used by doh
+			false,
+
+		trim= function(text){
+			if(text instanceof Array){
+				for (var result= [], i= 0; i<text.length; i++) {
+					result.push(trim(text[i]));
+				}
+				return result;
+			}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++){
+			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){
+				// Note:
+				//	 * dojoUrl is deprecated, and is a synonym for boot
+				//	 * testUrl is deprecated, and is a synonym for test
+				//	 * testModule is deprecated, and is a synonym for test (dots are automatically replaced with slashes)
+				//	 * registerModulePath is deprecated, and is a synonym for paths
+				case "boot":
+				case "dojoUrl":
+					boot= trim(value.split(","));
+					break;
+
+				case "test":
+				case "testUrl":
+					test= trim(value.split(","));
+					break;
+
+				case "testModule":
+					test= trim(value.replace(/\./g, "/").split(","));
+					break;
+
+				// registerModulePath is deprecated; use "paths"
+				case "registerModulePath":
+				case "paths":
+					for(var path, modules = value.split(";"), i= 0; i<modules.length; i++){
+						path= modules[i].split(",");
+						paths[trim(path[0])]= trim(path[1]);
+					}
+					break;
+
+				case "breakOnError":
+					breakOnError= true;
+					break;
+
+				case "sandbox":
+					sandbox= true;
+					break;
+
+				case "async":
+					async= true;
+					break;
+				case "dohPlugins":
+					dohPlugins=value.split(";");
+					break;
+			}
+		}
+	}
+
+	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"
+				// module; same goes for dojox/dohDojox since doh uses dojox
+				packageMap:{dojo:"dohDojo", dojox:"dohDojox"} 
+			},{
+				// now define the dohDojo package...
+				name:'dohDojo',
+				location:'../dojo',
+				packageMap:{dojo:"dohDojo", dojox:"dohDojox"}
+			},{
+				// and the dohDojox package...
+				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"} 
+			}],
+			
+			// next, we need to preposition a special configuration for dohDojo
+			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
+					});
+				}
+			},
+
+			// 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
+			},
+
+			// no sniffing; therefore, set the baseUrl
+			baseUrl:"../../dojo",
+
+			deps:["dohDojo", "doh", "dohDojo/window"],
+
+			callback:function(dohDojo, doh){
+				dohDojo.ready(function(){
+					fixHeight(dohDojo);
+					doh.breakOnError= breakOnError;
+					require(test);
+					dohDojo.ready(doh, "run");
+				});
+			},
+
+			async:async
+		};
+	}else{
+		config= {
+			paths: paths,
+			deps:["dojo", "doh", "dojo/window"],
+			callback:function(dojo, doh){
+				dojo.ready(function(){
+					fixHeight(dojo);
+					doh.breakOnError= breakOnError;
+					require(test);
+					dojo.ready(doh, "run");
+				});
+			},
+			async:async,
+			isDebug:1
+		};
+	}
+	
+	// load all of the dohPlugins
+	if(dohPlugins){
+		var i=0;
+		for(i=0; i<dohPlugins.length; i++){
+			config.deps.push(dohPlugins[i]);
+		}
+	}
+	
+	require= config;
+
+	// now script inject any boots
+	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";
+			document.getElementsByTagName("head")[0].appendChild(e);
+		}
+	}
+})()
\ No newline at end of file
diff --git a/util/doh/_rhinoRunner.js b/util/doh/_rhinoRunner.js
index ebd4319..6fd4555 100644
--- a/util/doh/_rhinoRunner.js
+++ b/util/doh/_rhinoRunner.js
@@ -1,18 +1,31 @@
-if(this["dojo"]){
-	dojo.provide("doh._rhinoRunner");
-}
+define(["doh/runner"], function(doh) {
+	doh.debug= print;
+	doh.error= print;
 
-doh.debug = print;
-doh.error = print;
-
-// Override the doh._report method to make it quit with an
-// appropriate exit code in case of test failures.
-(function(){
+	// Override the doh._report method to make it quit with an
+	// appropriate exit code in case of test failures.
 	var oldReport = doh._report;
 	doh._report = function(){
 		oldReport.apply(doh, arguments);
 		if(this._failureCount > 0 || this._errorCount > 0){
 			quit(1);
 		}
+	};
+
+	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++) {
+		arg= (args[i]+"").split("=");
+		if (arg.length==2 && arg[0]=="test") {
+			var test= arg[1];
+			print("loading test " + test);
+			tests.push(test);
+		}
 	}
-})();
+	print(doh._line, "\n");
+
+	require(tests, function() {
+		doh.run();
+	});
+});
diff --git a/util/doh/doh.profile.js b/util/doh/doh.profile.js
new file mode 100644
index 0000000..33eaaf7
--- /dev/null
+++ b/util/doh/doh.profile.js
@@ -0,0 +1,30 @@
+var testResourceRe = /^doh\/tests/,
+	list = {
+		"doh/doh.profile":1,
+		"doh/package.json":1,
+		"doh/tests":1,
+		"doh/_parseURLargs":1
+	},
+	copyOnly = function(mid){
+		return (mid in list);
+	};
+
+var profile = {
+	resourceTags:{
+		test: function(filename, mid){
+			return testResourceRe.test(mid);
+		},
+
+		copyOnly: function(filename, mid){
+			return copyOnly(mid);
+		},
+
+		amd: function(filename, mid){
+			return !testResourceRe.test(mid) && !copyOnly(mid) && /\.js$/.test(filename);
+		}
+	},
+
+	trees:[
+		[".", ".", /(\/\.)|(~$)/]
+	]
+};
diff --git a/util/doh/main.js b/util/doh/main.js
new file mode 100644
index 0000000..85f1b69
--- /dev/null
+++ b/util/doh/main.js
@@ -0,0 +1,7 @@
+define([
+	"doh/runner",
+	"dojo/has!host-browser?doh/_browserRunner",
+	"dojo/has!host-node?doh/_nodeRunner",
+	"dojo/has!host-rhino?doh/_rhinoRunner"], function(doh) {
+	return doh;
+});
diff --git a/util/doh/mobileRunner.html b/util/doh/mobileRunner.html
new file mode 100644
index 0000000..b8b6de1
--- /dev/null
+++ b/util/doh/mobileRunner.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<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="apple-mobile-web-app-capable" content="yes">
+		<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
+		<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>
+
+		<script type="text/javascript" src="_parseURLargs.js"></script>
+	
+		<style type="text/css">
+			@import "../../dojo/resources/dojo.css";
+
+			#testLayout {
+				position: relative;
+				left: 0px;
+				top: 0px;
+				width: 100%;
+				height: 100%;
+				border: 1px solid black;
+				border: 0px;
+			}
+
+			.tabBody {
+				margin: 0px;
+				padding: 0px;
+				/*
+				border: 1px solid black;
+				*/
+				background-color: #DEDEDE;
+				border: 0px;
+				width: 100%;
+				height: 100%;
+				position: absolute;
+				left: 0px; 
+				top: 0px;
+				overflow: auto;
+			}
+
+			#logBody {
+				padding-left: 5px;
+				padding-top: 5px;
+				font-family: Monaco, monospace;
+				font-size: 11px;
+				white-space: pre;
+			}
+
+
+		</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>
+		<span id="hiddenAudio"></span>
+	</body>
+</html>
+
diff --git a/util/doh/package.json b/util/doh/package.json
new file mode 100644
index 0000000..1662064
--- /dev/null
+++ b/util/doh/package.json
@@ -0,0 +1,23 @@
+{
+	"name": "doh",
+	"version":"1.7.0dev",
+	"directories": {
+		"lib": "."
+	},
+	"main": "main",
+	"description": "DOH is a unit test framework developed by the Dojo Toolkit Community.",
+	"licenses": [
+		 {
+				 "type": "AFLv2.1",
+				 "url": "http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L43"
+		 },
+		 {
+				 "type": "BSD",
+				 "url": "http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L13"
+		 }
+	],
+	"bugs": "http://bugs.dojotoolkit.org/",
+	"keywords": ["JavaScript", "Dojo", "Toolkit", "DOH"],
+	"homepage": "http://dojotoolkit.org/",
+	"dojoBuild": "doh.profile.js"
+}
diff --git a/util/doh/plugins/README.txt b/util/doh/plugins/README.txt
new file mode 100644
index 0000000..ced8cfe
--- /dev/null
+++ b/util/doh/plugins/README.txt
@@ -0,0 +1,7 @@
+doh/plugins - plugins to configure and extend the DOH runner
+
+These are loaded after the test runner and test url, but before the runner begins. This provides an opportunity to wrap and monkey-patch doh, the test harness and the test runner.
+
+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
diff --git a/util/doh/plugins/alwaysAudio.js b/util/doh/plugins/alwaysAudio.js
new file mode 100644
index 0000000..2e7d676
--- /dev/null
+++ b/util/doh/plugins/alwaysAudio.js
@@ -0,0 +1,11 @@
+define(["dojo", "doh/runner"], function(dojo, doh) {
+
+	// Checks the 'sounds' checkbox in the browser test runner 
+	// so we get Homer's feedback on the test run
+	dojo.ready(function(){
+		var chkNode = dojo.byId("audio");
+	    if(chkNode) {
+			chkNode.checked=true;
+		}
+	});
+});
\ No newline at end of file
diff --git a/util/doh/plugins/hello.js b/util/doh/plugins/hello.js
new file mode 100644
index 0000000..a5e1f82
--- /dev/null
+++ b/util/doh/plugins/hello.js
@@ -0,0 +1,15 @@
+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
+	var origRun = doh.run, 
+		registered = false;
+
+	doh.run = function() {
+		if(!registered) {
+			doh.debug("doh.plugins.hello plugin says Hello!");
+			registered = true;
+		}
+		origRun.apply(doh, arguments);
+	}
+});
diff --git a/util/doh/robot.js b/util/doh/robot.js
index 716829e..79f9937 100644
--- a/util/doh/robot.js
+++ b/util/doh/robot.js
@@ -1,13 +1,4 @@
-if(window["dojo"]){
-	dojo.provide("doh.robot");
-	dojo.experimental("doh.robot");
-	dojo.require("doh.runner");
-}else if(!doh["robot"]){
-	doh.robot={};
-}
-
-if(!doh.robot["_robotLoaded"]){
-(function(){
+define(["doh/_browserRunner", "require"], function(doh, require){
 
 	// loading state
 	var _robot = null;
@@ -25,7 +16,7 @@ if(!doh.robot["_robotLoaded"]){
 	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
+			// have to do it here because browserRunner sets it in onload in standalone case
 			var __onEnd = doh._onEnd;
 			doh._onEnd = function(){
 				doh.robot.killRobot();
@@ -59,7 +50,7 @@ if(!doh.robot["_robotLoaded"]){
 	// prime the event pump for fast browsers like Google Chrome - it's so fast, it doesn't stop to listen for keypresses!
 	_spaceReceived: false,
 	_primePump: false,
-	
+
 	_killApplet: function(){}, // overridden by Robot.html
 
 	killRobot: function(){
@@ -86,7 +77,7 @@ if(!doh.robot["_robotLoaded"]){
 			}
 		}
 	},
-	
+
 	startRobot: function(){
 		//startRobot should be called to initialize the robot (after the java applet is loaded).
 		//one good place to do this is in a dojo.addOnLoad handler. This function will be called
@@ -487,7 +478,7 @@ if(!doh.robot["_robotLoaded"]){
 			_robot.wheelMouse(isSecure(), Number(wheelAmt), Number(0), Number(duration||0));
 		},delay,duration);
 	},
-	
+
 	setClipboard: function(/*String*/data,/*String, optional*/format){
 		// summary:
 		//		Set clipboard content.
@@ -525,9 +516,8 @@ if(!doh.robot["_robotLoaded"]){
 	// if loaded with dojo, there might not be a runner.js!
 	if(!iframesrc && window["dojo"]){
 		// if user set document.domain to something else, send it to the Robot too
-		iframesrc = dojo.moduleUrl("util", "doh/")+"Robot.html?domain="+escape(document.domain);
+		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>');
-})();
-}
+});
diff --git a/util/doh/robot/DOHRobot.jar b/util/doh/robot/DOHRobot.jar
index 22517cd..8d4479b 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 ecc70a8..23daa41 100644
--- a/util/doh/robot/DOHRobot.java
+++ b/util/doh/robot/DOHRobot.java
@@ -2,6 +2,7 @@ import java.security.*;
 import java.applet.Applet;
 import java.awt.*;
 import java.util.*;
+import java.util.concurrent.*;
 import java.awt.event.*;
 import netscape.javascript.*;
 import java.io.*;
@@ -10,6 +11,7 @@ import java.net.URL;
 import java.awt.datatransfer.*;
 import javax.swing.JOptionPane;
 import javax.swing.JDialog;
+import java.awt.image.*;
 
 public final class DOHRobot extends Applet{
 	// order of execution:
@@ -35,7 +37,9 @@ public final class DOHRobot extends Applet{
 	// we have to serialize commands by having them join() the previous one.
 	// Otherwise, if you run doh.robot.typeKeys("dijit"), you frequently get something
 	// like "diijt"
-	private static Thread previousThread = null;
+	//private static Thread previousThread = null;
+	
+	private static ExecutorService threadPool = null;
 
 	// Keyboard discovery.
 	// At init, the Robot types keys into a textbox and JavaScript tells the
@@ -89,6 +93,10 @@ public final class DOHRobot extends Applet{
 	// save a pointer to doh.robot for fast access
 	JSObject dohrobot = null;
 
+	// trackingImage to visually track robot down
+	private BufferedImage trackingImage;
+	Point locationOnScreen = null;
+
 	// java.awt.Applet methods
 	public void stop(){
 		window = null;
@@ -101,6 +109,9 @@ public final class DOHRobot extends Applet{
 			// It plays nice and restores the old security manager.
 			AccessController.doPrivileged(new PrivilegedAction(){
 				public Object run(){
+					if(threadPool!=null){
+						threadPool.shutdownNow();
+					}
 					log("Stop");
 					securitymanager.checkTopLevelWindow(null);
 					log("Security manager reset");
@@ -116,6 +127,7 @@ public final class DOHRobot extends Applet{
 			if(key != -1){ return; }
 			Thread thread = new Thread(){
 				public void run(){
+					log("Document root: ~"+applet().getLocationOnScreen().toString());
 					window = (JSObject) JSObject.getWindow(applet());   
 					AccessController.doPrivileged(new PrivilegedAction(){
 						public Object run(){
@@ -140,16 +152,12 @@ public final class DOHRobot extends Applet{
 									}
 									log("Found old security manager");
 								}catch(Exception e){
-									e.printStackTrace();
 									log("Making new security manager");
 									securitymanager = new RobotSecurityManager(needsSecurityManager,
 											oldsecurity);
 									securitymanager.checkTopLevelWindow(null);
 									System.setSecurityManager(securitymanager);
 								}
-								// instantiate the Robot
-								robot = new Robot();
-								robot.setAutoWaitForIdle(true);
 							}catch(Exception e){
 								log("Error calling _init_: "+e.getMessage());
 								key = -2;
@@ -175,16 +183,19 @@ public final class DOHRobot extends Applet{
 					}
 				}
 			};
-			thread.start();
+			threadPool.execute(thread);
 		}
 	}
 
 	public void init(){
+		threadPool = Executors.newFixedThreadPool(1);
 		// ensure isShowing = true
 		addComponentListener(new onvisible());
 		ProfilingThread jitProfile=new ProfilingThread ();
 		jitProfile.startProfiling();
 		jitProfile.endProfiling();
+		trackingImage=new BufferedImage(3,3,BufferedImage.TYPE_INT_RGB);
+		trackingImage.setRGB(0, 0, 3, 3, new int[]{new Color(255,174,201).getRGB(),new Color(255,127,39).getRGB(),new Color(0,0,0).getRGB(),new Color(237,28,36).getRGB(),new Color(63,72,204).getRGB(),new Color(34,177,76).getRGB(),new Color(181,230,29).getRGB(),new Color(255,255,255).getRGB(),new Color(200,191,231).getRGB()}, 0, 3);
 	}
 
 	// loading functions
@@ -196,20 +207,11 @@ public final class DOHRobot extends Applet{
 		}
 	}
 
-	private boolean mouseSecure() throws Exception{
-		// Use MouseInfo to ensure that mouse is inside browser.
-		// Only works in Java 1.5, but the DOHRobot must compile for 1.4.
-		if(!mouseSecurity){ return true; }
+	protected Point getDesktopMousePosition() throws Exception{
 		Class mouseInfoClass;
 		Class pointerInfoClass;
-		try{
-			mouseInfoClass = Class.forName("java.awt.MouseInfo");
-			pointerInfoClass = Class.forName("java.awt.PointerInfo");
-		}catch(ClassNotFoundException e){
-			// Java 1.4
-			e.printStackTrace();
-			return true;
-		}
+		mouseInfoClass = Class.forName("java.awt.MouseInfo");
+		pointerInfoClass = Class.forName("java.awt.PointerInfo");
 		Method getPointerInfo = mouseInfoClass.getMethod("getPointerInfo", new Class[0]);
 		Method getLocation = pointerInfoClass.getMethod("getLocation", new Class[0]);
 		Object pointer=null;
@@ -218,7 +220,23 @@ public final class DOHRobot extends Applet{
 		}catch(java.lang.reflect.InvocationTargetException e){
 			e.getTargetException().printStackTrace();
 		}
-		Point mousePosition = (Point)(getLocation.invoke(pointer,new Object[0]));
+		return (Point)(getLocation.invoke(pointer,new Object[0]));
+	}
+	
+	public Point getLocationOnScreen(){
+		return locationOnScreen==null? super.getLocationOnScreen(): locationOnScreen;
+	}
+	
+	private boolean mouseSecure() throws Exception{
+		// Use MouseInfo to ensure that mouse is inside browser.
+		// Only works in Java 1.5, but the DOHRobot must compile for 1.4.
+		if(!mouseSecurity){ return true; }
+		Point mousePosition=null;
+		try{
+			mousePosition=getDesktopMousePosition();
+		}catch(Exception e){
+			return true;
+		}
 		return mousePosition.x >= docScreenX
 			&& mousePosition.x <= docScreenXMax
 			&& mousePosition.y >= docScreenY
@@ -245,7 +263,7 @@ public final class DOHRobot extends Applet{
 
 	public void _callLoaded(final double sec){
 		log("> _callLoaded Robot");
-		Thread thread = new Thread(){
+		Runnable thread = new Runnable(){
 			public void run(){
 				if(!isSecure(sec)){
 					return;
@@ -253,6 +271,71 @@ public final class DOHRobot extends Applet{
 				AccessController.doPrivileged(new PrivilegedAction(){
 					public Object run(){
 						Point p = getLocationOnScreen();
+						if(os.indexOf("MAC") != -1){
+							// Work around stupid Apple OS X bug affecting Safari 5.1 and FF4.
+							// 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;
+							int mindifference=Integer.MAX_VALUE;
+							GraphicsDevice[] screens=GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
+							try{
+								for(screen=0; screen<screens.length; screen++){
+									// take picture
+									DisplayMode mode=screens[screen].getDisplayMode();
+									int width=mode.getWidth();
+									int height=mode.getHeight();
+									int twidth=trackingImage.getWidth();
+									int theight=trackingImage.getHeight();
+									Robot screenshooter=new Robot(screens[screen]);
+									log("screen dimensions: "+width+" "+height);
+									BufferedImage screenshot=screenshooter.createScreenCapture(new Rectangle(0,0,width,height));
+									// Ideally (in Windows) we would now slide trackingImage until we find an identical match inside screenshot.
+									// Unfortunately because the Mac (what we are trying to fix) does terrible, awful things to graphics it displays,
+									// we will need to find the "most similar" (smallest difference in pixels) square and click there.
+									int x=0,y=0;
+									for(x=0; x<=width-twidth; x++){
+										for(y=0; y<=height-theight; y++){
+											int count=0;
+											int difference=0;
+											scanImage:
+											for(int x2=0; x2<twidth; x2++){
+												for(int y2=0; y2<theight; y2++){
+													int rgbdiff=Math.abs(screenshot.getRGB(x+x2,y+y2)-trackingImage.getRGB(x2,y2));
+													difference=difference+rgbdiff;
+													// short circuit mismatches
+													if(difference>=mindifference){
+														break scanImage;
+													}
+												}
+											}
+											if(difference<mindifference){
+												p.x=x;
+												p.y=y;
+												mindifference=difference;
+												minscreen=screen;
+											}
+										}
+									}
+								}
+								// create temp robot to put mouse in right spot
+								robot=new Robot(screens[minscreen]);
+								robot.setAutoWaitForIdle(true);
+							}catch(Exception e){
+								e.printStackTrace();
+							}
+							if(p.x==0&&p.y==0){
+								// shouldn't happen...
+								throw new RuntimeException("Robot not found on screen");
+							}
+							locationOnScreen=p;
+						}else{
+							// create default temp robot that should work on non-Macs
+							try{
+								robot=new Robot();
+								robot.setAutoWaitForIdle(true);
+							}catch(Exception e){}
+						}
 						log("Document root: ~"+p.toString());
 						int x = p.x + 16;
 						int y = p.y + 8;
@@ -262,6 +345,9 @@ public final class DOHRobot extends Applet{
 						}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);
 							Thread.sleep(100);
 						}catch(Exception e){};
 						robot.mousePress(InputEvent.BUTTON1_MASK);
@@ -278,7 +364,7 @@ public final class DOHRobot extends Applet{
 				});
 			}
 		};
-		thread.start();
+		threadPool.execute(thread);
 	}
 
 	// convenience functions
@@ -371,19 +457,12 @@ public final class DOHRobot extends Applet{
 
 	public void _notified(final double sec, final String chars){
 		// decouple from JavaScript; thread join could hang it
-		Thread thread = new Thread("_notified"){
+		Runnable thread = new Runnable(){
 			public void run(){
 				if(!isSecure(sec))
 					return;
 				AccessController.doPrivileged(new PrivilegedAction(){
 					public Object run(){
-						try{
-							// wait for release shift/altgraph to resolve
-							if(previousThread != null){
-								previousThread.join();
-							}
-						}catch(Exception e){
-						}
 						keystring += chars;
 						if(altgraph && !shift){
 							shift = false;
@@ -427,20 +506,12 @@ public final class DOHRobot extends Applet{
 				});
 			}
 		};
-		thread.start();
+		threadPool.execute(thread);
 	}
 
 	private void pressNext(){
-		final Thread myPreviousThread = previousThread;
-		Thread thread = new Thread("pressNext"){
+		Runnable thread = new Runnable(){
 			public void run(){
-				try{
-					// wait for release shift/altgraph to resolve
-					if(myPreviousThread != null){
-						myPreviousThread.join();
-					}
-				}catch(Exception e){
-				}
 				// first time, press shift (have to do it here instead of
 				// _notified to avoid IllegalThreadStateException on Mac)
 				log("starting up, " + shift + " " + altgraph);
@@ -491,13 +562,12 @@ public final class DOHRobot extends Applet{
 				}
 			}
 		};
-		previousThread = thread;
-		thread.start();
+		threadPool.execute(thread);
 	}
 
 	public void _initWheel(final double sec){
 		log("> initWheel");
-		Thread thread=new Thread(){
+		Runnable thread=new Runnable(){
 			public void run(){
 				if(!isSecure(sec))
 					return;
@@ -543,7 +613,7 @@ public final class DOHRobot extends Applet{
 				log("< initWheel");
 			}
 		};
-		thread.start();
+		threadPool.execute(thread);
 	}
 
 	public void _initKeyboard(final double sec){
@@ -553,7 +623,7 @@ public final class DOHRobot extends Applet{
 			dohrobot.call("_onKeyboard", new Object[]{});
 			return;
 		}
-		Thread thread = new Thread(){
+		Runnable thread = new Runnable(){
 			public void run(){
 				if(!isSecure(sec))
 					return;
@@ -621,7 +691,7 @@ public final class DOHRobot extends Applet{
 				});
 			}
 		};
-		thread.start();
+		threadPool.execute(thread);
 	}
 
 	public void typeKey(double sec, final int charCode, final int keyCode,
@@ -636,9 +706,13 @@ public final class DOHRobot extends Applet{
 				try{
 					log("> typeKey Robot " + charCode + ", " + keyCode + ", " + async);
 					KeyPressThread thread = new KeyPressThread(charCode,
-							keyCode, alt, ctrl, shift, meta, delay, async?null:previousThread);
-					previousThread = async?previousThread:thread;
-					thread.start();
+							keyCode, alt, ctrl, shift, meta, delay);
+					if(async){
+						Thread asyncthread=new Thread(thread);
+						asyncthread.start();
+					}else{
+						threadPool.execute(thread);
+					}
 					log("< typeKey Robot");
 				}catch(Exception e){
 					log("Error calling typeKey");
@@ -658,9 +732,8 @@ public final class DOHRobot extends Applet{
 		AccessController.doPrivileged(new PrivilegedAction(){
 			public Object run(){
 				log("> upKey Robot " + charCode + ", " + keyCode);
-				KeyUpThread thread = new KeyUpThread(charCode, keyCode, delay, previousThread);
-				previousThread = thread;
-				thread.start();
+				KeyUpThread thread = new KeyUpThread(charCode, keyCode, delay);
+				threadPool.execute(thread);
 				log("< upKey Robot");
 				return null;
 			}
@@ -676,9 +749,8 @@ public final class DOHRobot extends Applet{
 		AccessController.doPrivileged(new PrivilegedAction(){
 			public Object run(){
 				log("> downKey Robot " + charCode + ", " + keyCode);
-				KeyDownThread thread = new KeyDownThread(charCode, keyCode, delay, previousThread);
-				previousThread = thread;
-				thread.start();
+				KeyDownThread thread = new KeyDownThread(charCode, keyCode, delay);
+				threadPool.execute(thread);
 				log("< downKey Robot");
 				return null;
 			}
@@ -698,10 +770,8 @@ public final class DOHRobot extends Applet{
 				MousePressThread thread = new MousePressThread(
 						(left ? InputEvent.BUTTON1_MASK : 0)
 								+ (middle ? InputEvent.BUTTON2_MASK : 0)
-								+ (right ? InputEvent.BUTTON3_MASK : 0), delay,
-						previousThread);
-				previousThread = thread;
-				thread.start();
+								+ (right ? InputEvent.BUTTON3_MASK : 0), delay);
+				threadPool.execute(thread);
 				log("< mousePress Robot");
 				return null;
 			}
@@ -722,16 +792,19 @@ public final class DOHRobot extends Applet{
 				MouseReleaseThread thread = new MouseReleaseThread(
 						(left ? InputEvent.BUTTON1_MASK : 0)
 								+ (middle ? InputEvent.BUTTON2_MASK : 0)
-								+ (right ? InputEvent.BUTTON3_MASK : 0), delay,
-						previousThread);
-				previousThread = thread;
-				thread.start();
+								+ (right ? InputEvent.BUTTON3_MASK : 0), delay
+						);
+				threadPool.execute(thread);
 				log("< mouseRelease Robot");
 				return null;
 			}
 		});
 	}
 
+	protected boolean destinationInView(int x, int y){
+		return !(x > docScreenXMax || y > docScreenYMax || x < docScreenX || y < docScreenY);
+	}
+	
 	public void moveMouse(double sec, final int x1, final int y1, final int d, final int duration){
 		// called by doh.robot.mouseMove
 		// see it for details
@@ -742,7 +815,7 @@ public final class DOHRobot extends Applet{
 			public Object run(){
 				int x = x1 + docScreenX;
 				int y = y1 + docScreenY;
-				if(x > docScreenXMax || y > docScreenYMax || x < docScreenX || y < docScreenY){
+				if(!destinationInView(x,y)){
 					// TODO: try to scroll view
 					log("Request to mouseMove denied");
 					return null;
@@ -750,9 +823,8 @@ public final class DOHRobot extends Applet{
 				int delay = d;
 				log("> mouseMove Robot " + x + ", " + y);
 				MouseMoveThread thread = new MouseMoveThread(x, y, delay,
-						duration, previousThread);
-				previousThread = thread;
-				thread.start();
+						duration);
+				threadPool.execute(thread);
 				log("< mouseMove Robot");
 				return null;
 			}
@@ -766,10 +838,8 @@ public final class DOHRobot extends Applet{
 			return;
 		AccessController.doPrivileged(new PrivilegedAction(){
 			public Object run(){
-				MouseWheelThread thread = new MouseWheelThread(amount, delay, duration,
-						previousThread);
-				previousThread = thread;
-				thread.start();
+				MouseWheelThread thread = new MouseWheelThread(amount, delay, duration);
+				threadPool.execute(thread);
 				return null;
 			}
 		});
@@ -1184,7 +1254,7 @@ public final class DOHRobot extends Applet{
 	// (so as not to tie up the browser rendering thread!)
 	// declared inside so they have private access to the robot
 	// we do *not* want to expose that guy!
-	private class ProfilingThread extends Thread{
+	private class ProfilingThread implements Runnable{
 		protected long delay=0;
 		protected long duration=0;
 		private long start;
@@ -1212,6 +1282,7 @@ public final class DOHRobot extends Applet{
 				timingError+=(end-start)-oldDelay;
 			}
 		}
+		public void run(){}
 	}
 	
 	final private class KeyPressThread extends ProfilingThread{
@@ -1221,10 +1292,9 @@ public final class DOHRobot extends Applet{
 		private boolean ctrl;
 		private boolean shift;
 		private boolean meta;
-		private Thread myPreviousThread = null;
 
 		public KeyPressThread(int charCode, int keyCode, boolean alt,
-				boolean ctrl, boolean shift, boolean meta, int delay, Thread myPreviousThread){
+				boolean ctrl, boolean shift, boolean meta, int delay){
 			log("KeyPressThread constructor " + charCode + ", " + keyCode);
 			this.charCode = charCode;
 			this.keyCode = keyCode;
@@ -1233,13 +1303,10 @@ public final class DOHRobot extends Applet{
 			this.shift = shift;
 			this.meta = meta;
 			this.delay = delay;
-			this.myPreviousThread = myPreviousThread;
 		}
 
 		public void run(){
 			try{
-				if(myPreviousThread != null)
-					myPreviousThread.join();
 				startProfiling();
 				// in different order so async works
 				while(!hasFocus()){
@@ -1263,20 +1330,16 @@ public final class DOHRobot extends Applet{
 	final private class KeyDownThread extends ProfilingThread{
 		private int charCode;
 		private int keyCode;
-		private Thread myPreviousThread = null;
 
-		public KeyDownThread(int charCode, int keyCode, int delay, Thread myPreviousThread){
+		public KeyDownThread(int charCode, int keyCode, int delay){
 			log("KeyDownThread constructor " + charCode + ", " + keyCode);
 			this.charCode = charCode;
 			this.keyCode = keyCode;
 			this.delay = delay;
-			this.myPreviousThread = myPreviousThread;
 		}
 
 		public void run(){
 			try{
-				if(myPreviousThread != null)
-					myPreviousThread.join();
 				Thread.sleep(delay);
 				log("> run KeyDownThread");
 				while(!hasFocus()){
@@ -1328,20 +1391,16 @@ public final class DOHRobot extends Applet{
 	final private class KeyUpThread extends ProfilingThread{
 		private int charCode;
 		private int keyCode;
-		private Thread myPreviousThread = null;
 
-		public KeyUpThread(int charCode, int keyCode, int delay, Thread myPreviousThread){
+		public KeyUpThread(int charCode, int keyCode, int delay){
 			log("KeyUpThread constructor " + charCode + ", " + keyCode);
 			this.charCode = charCode;
 			this.keyCode = keyCode;
 			this.delay = delay;
-			this.myPreviousThread = myPreviousThread;
 		}
 
 		public void run(){
 			try{
-				if(myPreviousThread != null)
-					myPreviousThread.join();
 				Thread.sleep(delay);
 				log("> run KeyUpThread");
 				while(!hasFocus()){
@@ -1391,18 +1450,14 @@ public final class DOHRobot extends Applet{
 
 	final private class MousePressThread extends ProfilingThread{
 		private int mask;
-		private Thread myPreviousThread = null;
 
-		public MousePressThread(int mask, int delay, Thread myPreviousThread){
+		public MousePressThread(int mask, int delay){
 			this.mask = mask;
 			this.delay = delay;
-			this.myPreviousThread = myPreviousThread;
 		}
 
 		public void run(){
 			try{
-				if(myPreviousThread != null)
-					myPreviousThread.join();
 				Thread.sleep(delay);
 				log("> run MousePressThread");
 				while(!hasFocus()){
@@ -1421,18 +1476,14 @@ public final class DOHRobot extends Applet{
 
 	final private class MouseReleaseThread extends ProfilingThread{
 		private int mask;
-		private Thread myPreviousThread = null;
 
-		public MouseReleaseThread(int mask, int delay, Thread myPreviousThread){
+		public MouseReleaseThread(int mask, int delay){
 			this.mask = mask;
 			this.delay = delay;
-			this.myPreviousThread = myPreviousThread;
 		}
 
 		public void run(){
 			try{
-				if(myPreviousThread != null)
-					myPreviousThread.join();
 				Thread.sleep(delay);
 				log("> run MouseReleaseThread ");
 				while(!hasFocus()){
@@ -1453,14 +1504,12 @@ public final class DOHRobot extends Applet{
 	final private class MouseMoveThread extends ProfilingThread{
 		private int x;
 		private int y;
-		private Thread myPreviousThread = null;
 
-		public MouseMoveThread(int x, int y, int delay, int duration, Thread myPreviousThread){
+		public MouseMoveThread(int x, int y, int delay, int duration){
 			this.x = x;
 			this.y = y;
 			this.delay = delay;
 			this.duration = duration;
-			this.myPreviousThread = myPreviousThread;
 		}
 
 		public double easeInOutQuad(double t, double b, double c, double d){
@@ -1473,8 +1522,6 @@ public final class DOHRobot extends Applet{
 
 		public void run(){
 			try{
-				if(myPreviousThread != null)
-					myPreviousThread.join();
 				Thread.sleep(delay);
 				log("> run MouseMoveThread " + x + ", " + y);
 				while(!hasFocus()){
@@ -1565,19 +1612,15 @@ public final class DOHRobot extends Applet{
 
 	final private class MouseWheelThread extends ProfilingThread{
 		private int amount;
-		private Thread myPreviousThread = null;
 
-		public MouseWheelThread(int amount, int delay, int duration, Thread myPreviousThread){
+		public MouseWheelThread(int amount, int delay, int duration){
 			this.amount = amount;
 			this.delay = delay;
 			this.duration = duration;
-			this.myPreviousThread = myPreviousThread;
 		}
 
 		public void run(){
 			try{
-				if(myPreviousThread != null)
-					myPreviousThread.join();
 				Thread.sleep(delay);
 				log("> run MouseWheelThread " + amount);
 				while(!hasFocus()){
diff --git a/util/doh/robot/compilerobot.bat b/util/doh/robot/compilerobot.bat
index e0769fe..276bcfc 100644
--- a/util/doh/robot/compilerobot.bat
+++ b/util/doh/robot/compilerobot.bat
@@ -1,10 +1,9 @@
 setlocal
-set JDK14_HOME=C:\j2sdk1.4.2_19
+set JDK14_HOME=C:\Program Files\IBM\Java60
 del DOHRobot*.class
-%JDK14_HOME%\bin\javac -target 1.4 -classpath %JDK14_HOME%\jre\lib\plugin.jar DOHRobot.java
-rem del DOHRobot.jar
-%JDK14_HOME%\bin\jar xvf DOHRobot.jar META-INF
-%JDK14_HOME%\bin\jar cvf DOHRobot.jar DOHRobot*.class META-INF
-rem %JDK14_HOME%\bin\jarsigner -keystore ./dohrobot DOHRobot.jar dojo <key
+"%JDK14_HOME%\bin\javac" -source 1.4 -target 1.4 -classpath "%JDK14_HOME%\jre\lib\plugin.jar" DOHRobot.java
+del DOHRobot.jar
+"%JDK14_HOME%\bin\jar" cvf DOHRobot.jar DOHRobot*.class META-INF
+"%JDK14_HOME%\bin\jarsigner" -keystore ./dohrobot DOHRobot.jar dojo <key
 del DOHRobot*.class
 endlocal
diff --git a/util/doh/robot/signature.png b/util/doh/robot/signature.png
new file mode 100644
index 0000000..bc5d0f5
Binary files /dev/null and b/util/doh/robot/signature.png differ
diff --git a/util/doh/runner.html b/util/doh/runner.html
index a97b559..647aa20 100644
--- a/util/doh/runner.html
+++ b/util/doh/runner.html
@@ -1,13 +1,10 @@
 <!DOCTYPE html>
 <html style="height:100%;">
-	<!--
-		// TODO: provide a UI for prompted tests
-	-->
 	<head>
-		<title>The Dojo Unit Test Harness, $Rev: 24358 $</title>
+		<title>The Dojo Unit Test Harness, $Rev: 25896 $</title>
 
 		<script type="text/javascript">
-			// workaround for bug in Safari 3.  See #7189
+			// workaround for bug in Safari 3.	See #7189
 			if (/3[\.0-9]+ Safari/.test(navigator.appVersion))
 			{
 				window.console = {
@@ -28,108 +25,8 @@
 			}
 		</script>
 
-		<script type="text/javascript">
-			window.dojoUrl = "../../dojo/dojo.js";
-			window.testUrl = "";
-			window.testModule = "";
-
-			// parse out our test URL and our Dojo URL from the query string
-			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 "dojoUrl":
-						case "testUrl":
-						case "testModule":
-							window[name] = value;
-							break;
-						case "registerModulePath":
-							var modules = value.split(";");
-							window.registerModulePath=[];
-							for (var i=0; i<modules.length;i++){
-								window.registerModulePath.push(modules[i].split(","));
-							}
-						break;
-					}
-				}
-			}
-			document.write("<scr"+"ipt type='text/javascript' djConfig='isDebug: true' src='"+dojoUrl+"'></scr"+"ipt>");
-		</script>
-		<script type="text/javascript">
-			function fixHeight(){
-				// 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;
-					}
-					dojo.byId('testLayout').style.height=(dojo.window.getBox().h-headerHeight)+"px";
-				}
-			}
-			if(this.dojo){
-				// we're in the browser and are going to have to require _browserRunner, DocTest and some kind of testModule
-				dojo.require("doh.runner");
-				dojo.require("doh._browserRunner");
-				dojo.require("dojox.testing.DocTest");
-				dojo.require("dojo.window"); // to size iframe
-				dojo.addOnLoad(function(){
-					for(var moduleList= (window.testModule || "dojo.tests.module").split(","), i= 0; i<moduleList.length; i++){
-						dojo.require(moduleList[i]);
-					}
-					window.testModule= "";
-
-					fixHeight();
-
-					//we want to ensure that doh.run is the *last* thing run
-					dojo.addOnLoad(function(){
-						setTimeout(function(){
-							dojo.global.doh.run();
-						}, 200);
-					});
-				});
-			}else if(typeof define == "function"){
-				// AMD loader
-				(function() {
-					require({baseUrl:"./"});
-					require(["runner.js", "_browserRunner.js","../../dojox/testing/DocTest.js","../../dojo/window.js"], function(){
-						// runner.js and _browserRunner.js create the global object doh and stuff the factories into it
-						// run the factories to bring doh to life. this is a bit awkward compared to how pure AMD modules
-						// would look, but doh is being asked to operate in many non-AMD environments today and this works.
-						var factories= doh;
-						doh= {};
-						factories.runnerFactory(doh);
-						factories.browserRunnerFactory(doh);
-
-						//tell the loader about our new doh module
-						define("doh", [], doh);
-
-						// now load all the testUrls/testModules; test modules don't make much sense since there
-						// is no specific paths/package config at this point to map module ids to URLs; therefore,
-						// we just treat both as if they are URLs.
-						var deps= (window.testUrl || window.testModule || "dojo.tests.module").split(",");
-						for (var i= 0; i<deps.length; i++) {
-							deps[i]+= (/\.js$/.test(deps[i]) ? "" : ".js");
-						}
-						require(deps);
-
-						fixHeight();
-					});
-				})();
-			}else{
-				document.write("<scr"+"ipt type='text/javascript' src='runner.js'></scr"+"ipt>");
-				if(testUrl.length){
-					document.write("<scr"+"ipt type='text/javascript' src='"+testUrl+".js'></scr"+"ipt>");
-				}
-			}
-		</script>
+		<script type="text/javascript" src="_parseURLargs.js"></script>
+	
 		<style type="text/css">
 			@import "../../dojo/resources/dojo.css";
 			/*
@@ -234,7 +131,7 @@
 				border: 1px solid black;
 				*/
 				position: relative;
-				height: 100%;
+				height: 99%;
 				width: 100%;
 				overflow: auto;
 			}
@@ -315,7 +212,7 @@
 				<td width="*" class="header" valign="bottom">
 					<button class="tab" onclick="doh.showTestPage();">Test Page</button>
 					<button class="tab" onclick="doh.showLogPage();">Log</button>
-                    <button class="tab" onclick="doh.showPerfTestsPage();">Performance Tests Results</button>
+										<button class="tab" onclick="doh.showPerfTestsPage();">Performance Tests Results</button>
 				</td>
 			</tr>
 			<tr valign="top" style="border: 0; padding: 0; margin: 0;">
diff --git a/util/doh/runner.js b/util/doh/runner.js
index ef6e8f5..e26420d 100644
--- a/util/doh/runner.js
+++ b/util/doh/runner.js
@@ -1,101 +1,20 @@
-//guarantee in global scope and scope protection
-(function(/* Array? */scriptArgs) {
-
-//here's the definition of doh.runner...which really defines global doh
-var d= function(doh) {
-
-//
-// Utility Functions and Classes
-//
-
-doh.selfTest = false;
-
-doh.global = this;
-
-doh.hitch = function(/*Object*/thisObject, /*Function|String*/method /*, ...*/){
-	var args = [];
-	for(var x=2; x<arguments.length; x++){
-		args.push(arguments[x]);
-	}
-	var fcn = ((typeof method == "string") ? thisObject[method] : method) || function(){};
-	return function(){
-		var ta = args.concat([]); // make a copy
-		for(var x=0; x<arguments.length; x++){
-			ta.push(arguments[x]);
-		}
-		return fcn.apply(thisObject, ta); // Function
-	};
-}
-
-doh._mixin = function(/*Object*/ obj, /*Object*/ props){
-	// summary:
-	//		Adds all properties and methods of props to obj. This addition is
-	//		"prototype extension safe", so that instances of objects will not
-	//		pass along prototype defaults.
-	var tobj = {};
-	for(var x in props){
-		// the "tobj" condition avoid copying properties in "props"
-		// inherited from Object.prototype.  For example, if obj has a custom
-		// toString() method, don't overwrite it with the toString() method
-		// that props inherited from Object.protoype
-		if(tobj[x] === undefined || tobj[x] != props[x]){
-			obj[x] = props[x];
-		}
-	}
-	// IE doesn't recognize custom toStrings in for..in
-	if(	this["document"]
-		&& document.all
-		&& (typeof props["toString"] == "function")
-		&& (props["toString"] != obj["toString"])
-		&& (props["toString"] != tobj["toString"])
-	){
-		obj.toString = props.toString;
-	}
-	return obj; // Object
-}
-
-doh.mixin = function(/*Object*/obj, /*Object...*/props){
-	// summary:	Adds all properties and methods of props to obj.
-	for(var i=1, l=arguments.length; i<l; i++){
-		doh._mixin(obj, arguments[i]);
-	}
-	return obj; // Object
-}
-
-doh.extend = function(/*Object*/ constructor, /*Object...*/ props){
-	// summary:
-	//		Adds all properties and methods of props to constructor's
-	//		prototype, making them available to all instances created with
-	//		constructor.
-	for(var i=1, l=arguments.length; i<l; i++){
-		doh._mixin(constructor.prototype, arguments[i]);
-	}
-	return constructor; // Object
-}
+define("doh/runner", ["dojo"], function(dojo) {
+var doh= dojo.mixin({}, dojo);
 
+// intentionally define global tests and global doh symbols
+// TODO: scrub these globals from tests and remove this pollution
+tests = doh;
+this.doh= doh;
 
 doh._line = "------------------------------------------------------------";
 
-/*
-doh._delegate = function(obj, props){
-	// boodman-crockford delegation
-	function TMP(){};
-	TMP.prototype = obj;
-	var tmp = new TMP();
-	if(props){
-		dojo.lang.mixin(tmp, props);
-	}
-	return tmp;
-}
-*/
-
 doh.debug = function(){
 	// summary:
 	//		takes any number of arguments and sends them to whatever debugging
 	//		or logging facility is available in this environment
 
 	// YOUR TEST RUNNER NEEDS TO IMPLEMENT THIS
-}
+};
 
 doh.error = function(){
 	// summary:
@@ -104,12 +23,12 @@ doh.error = function(){
 	//		as an Error object and show additional information - such as stack trace
 
 	// YOUR TEST RUNNER NEEDS TO IMPLEMENT THIS
-}
+};
 
 doh._AssertFailure = function(msg, hint){
-	// idea for this as way of dis-ambiguating error types is from JUM.
-	// The JUM is dead! Long live the JUM!
-
+	if (doh.breakOnError) {
+		debugger;
+	}
 	if(!(this instanceof doh._AssertFailure)){
 		return new doh._AssertFailure(msg, hint);
 	}
@@ -118,7 +37,7 @@ doh._AssertFailure = function(msg, hint){
 	}
 	this.message = new String(msg||"");
 	return this;
-}
+};
 doh._AssertFailure.prototype = new Error();
 doh._AssertFailure.prototype.constructor = doh._AssertFailure;
 doh._AssertFailure.prototype.name = "doh._AssertFailure";
@@ -160,6 +79,7 @@ doh.extend(doh.Deferred, {
 	},
 
 	getFunctionFromArgs: function(){
+		//TODO: this looks like dojo.hitch? remove and replace?
 		var a = arguments;
 		if((a[0])&&(!a[1])){
 			if(typeof a[0] == "function"){
@@ -198,7 +118,6 @@ doh.extend(doh.Deferred, {
 			this.results[0].cancel();
 		}
 	},
-			
 
 	_pause: function(){
 		this.paused++;
@@ -246,6 +165,7 @@ doh.extend(doh.Deferred, {
 	},
 
 	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);
@@ -254,6 +174,7 @@ doh.extend(doh.Deferred, {
 	},
 
 	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);
@@ -262,6 +183,7 @@ doh.extend(doh.Deferred, {
 	},
 
 	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);
@@ -330,116 +252,26 @@ doh._init = function(){
 	this._errorCount = 0;
 	this._failureCount = 0;
 	this.debug(this._testCount, "tests to run in", this._groupCount, "groups");
-}
+};
 
-// doh._urls = [];
 doh._groups = {};
 
 //
-// Test Registration
+// Test Types
 //
+doh._testTypes= {};
 
-doh.registerTestNs = function(/*String*/ group, /*Object*/ ns){
-	// summary:
-	//		adds the passed namespace object to the list of objects to be
-	//		searched for test groups. Only "public" functions (not prefixed
-	//		with "_") will be added as tests to be run. If you'd like to use
-	//		fixtures (setUp(), tearDown(), and runTest()), please use
-	//		registerTest() or registerTests().
-	for(var x in ns){
-		if(	(x.charAt(0) != "_") &&
-			(typeof ns[x] == "function") ){
-			this.registerTest(group, ns[x]);
-		}
-	}
-}
-
-doh._testRegistered = function(group, fixture){
-	// slot to be filled in
-}
-
-doh._groupStarted = function(group){
-	// slot to be filled in
-}
-
-doh._groupFinished = function(group, success){
-	// slot to be filled in
-}
-
-doh._testStarted = function(group, fixture){
-	// slot to be filled in
-}
-
-doh._testFinished = function(group, fixture, success){
-	// slot to be filled in
-}
-
-doh.registerGroup = function(	/*String*/ group,
-								/*Array||Function||Object*/ tests,
-								/*Function*/ setUp,
-								/*Function*/ tearDown,
-								/*String*/ type){
+doh.registerTestType= function(name, initProc){
 	// summary:
-	//		registers an entire group of tests at once and provides a setUp and
-	//		tearDown facility for groups. If you call this method with only
-	//		setUp and tearDown parameters, they will replace previously
-	//		installed setUp or tearDown functions for the group with the new
-	//		methods.
-	// group:
-	//		string name of the group
-	// tests:
-	//		either a function or an object or an array of functions/objects. If
-	//		an object, it must contain at *least* a "runTest" method, and may
-	//		also contain "setUp" and "tearDown" methods. These will be invoked
-	//		on either side of the "runTest" method (respectively) when the test
-	//		is run. If an array, it must contain objects matching the above
-	//		description or test functions.
-	// setUp: a function for initializing the test group
-	// tearDown: a function for initializing the test group
-	// type: The type of tests these are, such as a group of performance tests
-	//		null/undefied are standard DOH tests, the valye 'perf' enables
-	//		registering them as performance tests.
-	if(tests){
-		this.register(group, tests, type);
-	}
-	if(setUp){
-		this._groups[group].setUp = setUp;
-	}
-	if(tearDown){
-		this._groups[group].tearDown = tearDown;
-	}
-}
-
-doh._getTestObj = function(group, test, type){
-	var tObj = test;
-	if(typeof test == "string"){
-		if(test.substr(0, 4)=="url:"){
-			return this.registerUrl(group, test);
-		}else{
-			tObj = {
-				name: test.replace("/\s/g", "_") // FIXME: bad escapement
-			};
-			tObj.runTest = new Function("t", test);
-		}
-	}else if(typeof test == "function"){
-		// if we didn't get a fixture, wrap the function
-		tObj = { "runTest": test };
-		if(test["name"]){
-			tObj.name = test.name;
-		}else{
-			try{
-				var fStr = "function ";
-				var ts = tObj.runTest+"";
-				if(0 <= ts.indexOf(fStr)){
-					tObj.name = ts.split(fStr)[1].split("(", 1)[0];
-				}
-				// doh.debug(tObj.runTest.toSource());
-			}catch(e){
-			}
-		}
-		// FIXME: try harder to get the test name here
-	}
+	//	 Adds a test type and associates a function used to initialize each test of the given type
+	// name: String
+	//	 The name of the type.
+	// initProc: Function
+	//	 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.
 	if(type === "perf" || tObj.testType === "perf"){
@@ -458,13 +290,12 @@ doh._getTestObj = function(group, test, type){
 			doh.perfTestResults[group][tObj.name] = {};
 		}
 		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(!("trialDelay" in tObj)){
@@ -476,158 +307,568 @@ doh._getTestObj = function(group, test, type){
 			tObj.trialIterations = 10;
 		}
 	}
-	return tObj;
-}
+});
 
-doh.registerTest = function(/*String*/ group, /*Function||Object*/ test, /*String*/ type){
+
+//
+// Test Registration
+//
+var
+	createFixture= function(group, test, type){
+		// test is a function, string, or fixture object
+		var tObj = test;
+		if(dojo.isString(test)){
+			tObj = {
+				name: test.replace("/\s/g", "_"), // FIXME: bad escapement
+				runTest: new Function("t", test)
+			};
+		}else if(dojo.isFunction(test)){
+			// if we didn't get a fixture, wrap the function
+			tObj = { "runTest": test };
+			if(test["name"]){
+				tObj.name = test.name;
+			}else{
+				try{
+					var fStr = "function ";
+					var ts = tObj.runTest+"";
+					if(0 <= ts.indexOf(fStr)){
+						tObj.name = ts.split(fStr)[1].split("(", 1)[0];
+					}
+					// doh.debug(tObj.runTest.toSource());
+				}catch(e){
+				}
+			}
+			// FIXME: try harder to get the test name here
+		}else if(dojo.isString(tObj.runTest)){
+			tObj.runTest= new Function("t", tObj.runTest);
+		}
+		if(!tObj.runTest){
+			return 0;
+		}
+
+		// if the test is designated as a particular type, do type-specific initialization
+		var testType= doh._testTypes[type] || doh._testTypes[tObj.testType];
+		if(testType){
+			testType(group, tObj);
+		}
+
+		// add the test to this group
+		doh._groups[group].push(tObj);
+		doh._testCount++;
+		doh._testRegistered(group, tObj);
+
+		return tObj;
+	},
+
+	dumpArg= function(arg){
+		if(dojo.isString(arg)){
+			return "string(" + arg + ")";
+		} else {
+			return typeof arg;
+		}
+	},
+
+	illegalRegister= function(args, testArgPosition){
+		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.");
+		}else{
+			doh.debug("\tillegal arguments provided to dojo.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
+};
+
+doh._groupStarted = function(group){
+	// slot to be filled in
+};
+
+doh._groupFinished = function(group, success){
+	// slot to be filled in
+};
+
+doh._testStarted = function(group, fixture){
+	// slot to be filled in
+};
+
+doh._testFinished = function(group, fixture, success){
+	// slot to be filled in
+};
+
+doh._registerTest = function(group, test, type){
 	// summary:
 	//		add the provided test function or fixture object to the specified
 	//		test group.
-	// group:
+	// group: String
 	//		string name of the group to add the test to
-	// test:
-	//		either a function or an object. If an object, it must contain at
-	//		*least* a "runTest" method, and may also contain "setUp" and
-	//		"tearDown" methods. These will be invoked on either side of the
-	//		"runTest" method (respectively) when the test is run.
-	// type:
+	// test: Function||String||Object
+	//		TODOC
+	// type: String?
 	//		An identifier denoting the type of testing that the test performs, such
-	//		as a performance test.  If null, defaults to regular DOH test.
-	if(!this._groups[group]){
+	//		as a performance test. If falsy, defaults to test.type.
+
+	// get, possibly create, the group object
+
+	var groupObj= this._groups[group];
+	if(!groupObj){
 		this._groupCount++;
-		this._groups[group] = [];
-		this._groups[group].inFlight = 0;
+		groupObj= this._groups[group] = [];
+		groupObj.inFlight = 0;
+	}
+	if(!test){
+		return groupObj;
 	}
-	var tObj = this._getTestObj(group, test, type);
-	if(!tObj){ return null; }
-	this._groups[group].push(tObj);
-	this._testCount++;
-	this._testRegistered(group, tObj);
-	return tObj;
-}
 
-doh.registerTests = function(/*String*/ group, /*Array*/ testArr, /*String*/ type){
-	// summary:
-	//		registers a group of tests, treating each element of testArr as
-	//		though it were being (along with group) passed to the registerTest
-	//		method.  It also uses the type to decide how the tests should
-	//		behave, by defining the type of tests these are, such as performance tests
-	for(var x=0; x<testArr.length; x++){
-		this.registerTest(group, testArr[x], type);
+	// create the test fixture
+	var tObj;
+	if(dojo.isFunction(test) || dojo.isString(test) || "runTest" in test){
+		return createFixture(group, test, type) ? groupObj : 0;
+	}else if(dojo.isArray(test)){
+		// a vector of tests...
+		for(var i= 0; i<test.length; i++){
+			tObj = createFixture(group, test[i], type);
+			if(!tObj){
+				this.debug("ERROR:");
+				this.debug("\tillegal test is test array; more information follows...");
+				return null;
+			}
+		}
+		return groupObj;
+	}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);
+			}else{
+				// should be an object
+				theTest.name= theTest.name || testName;
+				tObj = createFixture(group, theTest, type);
+			}
+			if(!tObj){
+				this.debug("ERROR:");
+				this.debug("\tillegal test is test hash; more information follows...");
+				return null;
+			}
+		}
+		return groupObj;
 	}
-}
+};
 
-// FIXME: move implementation to _browserRunner?
-doh.registerUrl = function(	/*String*/ group,
-								/*String*/ url,
-								/*Integer*/ timeout,
-								/*String*/ type){
+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(/([^\!]+)\!(.+)/);
+			if(match){
+				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){
+				// either (amdMid, group) or (group, type)
+				if(parts[1] in doh._testTypes){
+					groupId= parts[0];
+					type= parts[1];
+				}else{
+					amdMid= parts[0];
+					groupId= parts[1];
+				}
+			} // else, no ! and just a groupId
+		}
+	}
+
+	var group= doh._registerTest(groupId, test, type);
+	if(group){
+		if(amdMid){
+			group.amdMid= amdMid;
+		}
+		if(setUp){
+			group.setUp= setUp;
+		}
+		if(tearDown){
+			group.tearDown= tearDown;
+		}
+	}else{
+		illegalRegister(arguments, testArgPosition);
+	}
+};
+
+doh._registerUrl = function(/*String*/ group, /*String*/ url, /*Integer*/ timeout, /*String*/ type, /*object*/ dohArgs){
+	// slot to be filled in
 	this.debug("ERROR:");
 	this.debug("\tNO registerUrl() METHOD AVAILABLE.");
-	// this._urls.push(url);
-}
+};
 
-doh.registerString = function(group, str, type){
-}
+var typeSigs= (function(){
+	// Generate machinery to decode the many register signatures; these are the possible signatures.
+
+	var sigs= [
+		// note: to===timeout, up===setUp, down===tearDown
+
+		// 1 arg
+		"test", function(args, a1){doh._registerTestAndCheck("ungrouped", a1, 0, 0, args, 0, 0);},
+		"url", function(args, a1){doh._registerUrl("ungrouped", a1);},
+
+		// 2 args
+		"group-test", function(args, a1, a2){doh._registerTestAndCheck(a1, a2, 0, 0, args, 0, 0);},
+		"test-type", function(args, a1, a2){doh._registerTestAndCheck("ungrouped", a1, a2, 1, args, 0, 0);},
+		"test-up", function(args, a1, a2){doh._registerTestAndCheck("ungrouped", a1, 0, 0, args, a2, 0);},
+		"group-url", function(args, a1, a2){doh._registerUrl(a1, a2);},
+		"url-to", function(args, a1, a2){doh._registerUrl("ungrouped", a1, a2);},
+		"url-type", function(args, a1, a2){doh._registerUrl("ungrouped", a1, undefined, a2);},
+		"url-args", function(args, a1, a2){doh._registerUrl("ungrouped", a1, undefined, 0, a2);},
+
+		// 3 args
+		"group-test-type", function(args, a1, a2, a3){doh._registerTestAndCheck(a1, a2, a3, 2, args, 0, 0);},
+		"group-test-up", function(args, a1, a2, a3){doh._registerTestAndCheck(a1, a2, 0, 2, args, a3, 0);},
+		"test-type-up", function(args, a1, a2, a3){doh._registerTestAndCheck("ungrouped", a1, a2, 0, args, a3, 0);},
+		"test-up-down", function(args, a1, a2, a3){doh._registerTestAndCheck("ungrouped", a1, 0, 0, args, a2, a3);},
+		"group-url-to", function(args, a1, a2, a3){doh._registerUrl(a1, a2, a3);},
+		"group-url-type", function(args, a1, a2, a3){doh._registerUrl(a1, a2, undefined, a3);},
+		"group-url-args", function(args, a1, a2, a3){doh._registerUrl(a1, a2, undefined, 0, a3);},
+		"url-to-type", function(args, a1, a2, a3){doh._registerUrl("ungrouped", a1, a2, a3);},
+		"url-to-args", function(args, a1, a2, a3){doh._registerUrl("ungrouped", a1, a2, 0, a3);},
+		"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-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);},
+		"group-url-to-args", function(args, a1, a2, a3, a4){doh._registerUrl(a1, a2, a3, 0, a4);},
+		"group-url-type-args", function(args, a1, a2, a3, a4){doh._registerUrl(a1, a2, undefined, a3, a4);},
+		"url-to-type-args", function(args, a1, a2, a3, a4){doh._registerUrl("ungrouped", a1, a2, a3, a4);},
+
+		// 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);}
+	];
+
+	// type-ids
+	// a - array
+	// st - string, possible type
+	// sf - string, possible function
+	// s - string not a type or function
+	// o - object
+	// f - function
+	// n - number
+    // see getTypeId inside doh.register
+	var argTypes= {
+		group:"st.sf.s",
+		test:"a.sf.o.f",
+		type:"st",
+		up:"f",
+		down:"f",
+		url:"s",
+		to:"n",
+		args:"o"
+	};
+	for(var p in argTypes){
+		argTypes[p]= argTypes[p].split(".");
+	};
 
-// FIXME: remove the doh.add alias SRTL.
-doh.register = doh.add = function(groupOrNs, testOrNull, type){
-	// summary:
-	// 		"magical" variant of registerTests, registerTest, and
-	// 		registerTestNs. Will accept the calling arguments of any of these
-	// 		methods and will correctly guess the right one to register with.
-	if(	(arguments.length == 1)&&
-		(typeof groupOrNs == "string") ){
-		if(groupOrNs.substr(0, 4)=="url:"){
-			this.registerUrl(groupOrNs, null, null, type);
-		}else{
-			this.registerTest("ungrouped", groupOrNs, type);
+	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];
+			if(reducedSig.length){
+				generateTypeSignature(reducedSig, nextPattern, dest, func);
+			}else{
+				dest.push(nextPattern, func);
+			}
 		}
 	}
-	if(arguments.length == 1){
-		this.debug("invalid args passed to doh.register():", groupOrNs, ",", testOrNull);
-		return;
+
+	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;
+})();
+
+
+doh.register = function(a1, a2, a3, a4, a5){
+	/*=====
+	doh.register = function(groupId, testOrTests, timeoutOrSetUp, tearDown){
+	// summary:
+	//	 Add a test or group of tests.
+	// 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
+	//		is given by [A-Za-z0-9_/.-]. If provided, prefix and suffix are denoted by "!". If
+	//		provided, type must be a valid test type.
+	// testOrTests: Array||Function||Object||String||falsy
+	//		When a function, implies a function that defines a single test. DOH passes the
+	//		DOH object to the function as the sole argument when the test is executed. When
+	//		a string, implies the definition of a single test given by `new Function("t", testOrTests)`.
+	//		When an object that contains the method `runTest` (which *must* be a function),
+	//		implies a single test given by the value of the property `runTest`. In this case,
+	//		the object may also contain the methods `setup` and `tearDown`, and, if provided, these
+	//		will be invoked on either side of the test function. Otherwise when an object (that is,
+	//		an object that does not contain the method `runTest`), then a hash from test name to
+	//		test function (either a function or string as described above); any names that begin
+	//		with "_" are ignored. When an array, the array must exclusively contain functions,
+	//		strings, and/or objects as described above and each item is added to the group as
+	//		per the items semantics.
+	// 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.
+	// 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
+	//
+	//	 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, 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.
+	// example:
+	// | var
+	// |	 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
+	// |
+	// |		 // runTest is always required...
+	// |		 runTest:function(t){
+	// |			 //the test...
+	// |		 },
+	// |
+	// |		 // name is optional, but recommended...
+	// |		 name:"myTest",
+	// |
+	// |		 // 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
+	// |		 }
+	// |	 }
+	// |
+	// |	 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.
+	// |		 },
+	// |
+	// |		 t6:{
+	// |			 runTest:function(t){
+	// |				//etc.
+	// |			 }
+	// |			 // name will be automatically added as "t6"
+	// |		 }
+	// |	 },
+	// |
+	// |	 aSetup:function(){
+	// |		 // etc.
+	// |	 },
+	// |
+	// |	 aTearDown:function(){
+	// |		 // etc.
+	// |	 };
+	// | // (test); note, can't provide setup/tearDown without a group
+	// | doh.register(t1);
+	// |
+	// | // (group, test, setUp, tearDown) test and/or setUp and/or tearDown can be missing
+	// | doh.register("myGroup", 0, aSetUp, aTearDown);
+	// | doh.register("myGroup", t1, aSetUp, aTearDown);
+	// | doh.register("myGroup", t1, aSetUp);
+	// | doh.register("myGroup", t1, 0, aTearDown);
+	// | doh.register("myGroup", t1);
+	// |
+	// | // various kinds of test arguments are allowed
+	// | doh.register("myGroup", t2);
+	// | doh.register("myGroup", t3);
+	// | doh.register("myGroup", t4);
+	// |
+	// | // add a perf test
+	// | doh.register("myGroup!perf", t1);
+	// |
+	// | // 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.
 	}
-	if(typeof testOrNull == "string"){
-		if(testOrNull.substr(0, 4)=="url:"){
-			this.registerUrl(testOrNull, null, null, type);
+	=====*/
+
+	function getTypeId(a){
+		if(a instanceof Array){
+			return "a";
+		}else if(typeof a == "function"){
+			return "f";
+		}else if(typeof a == "number"){
+			return "n";
+		}else if(typeof a == "string"){
+			if(a in doh._testTypes){
+				return "st";
+			}else if(/\(/.test(a)){
+				return "sf";
+			}else{
+				return "s";
+			}
 		}else{
-			this.registerTest(groupOrNs, testOrNull, type);
+			return "o";
 		}
-		// this.registerTestNs(groupOrNs, testOrNull);
-		return;
 	}
-	if(doh._isArray(testOrNull)){
-		this.registerTests(groupOrNs, testOrNull, type);
-		return;
+
+	var
+		arity= arguments.length,
+		search= typeSigs[arity-1],
+		sig= [],
+		i;
+	for(i= 0; i<arity; i++){
+		sig.push(getTypeId(arguments[i]));
+	}
+	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;
+		}
 	}
-	this.registerTest(groupOrNs, testOrNull, type);
+	illegalRegister(arguments);
 };
 
 doh.registerDocTests = function(module){
-	// no-op for when Dojo isn't loaded into the page
-	this.debug("registerDocTests() requires dojo to be loaded into the environment. Skipping doctest set for module:", module);
-};
-(function(){
-	if(typeof dojo != "undefined"){
-		try{
-			dojo.require("dojox.testing.DocTest");
-		}catch(e){
-			// if the DocTest module isn't available (e.g., the build we're
-			// running from doesn't include it), stub it out and log the error
-			console.debug(e);
-
-			doh.registerDocTests = function(){}
-			return;
+	//	summary:
+	//		Get 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;
+	var tests = [];
+	for (var i=0; i<len; i++){
+		var test = docTests[i];
+		// Extract comment on first line and add to test name.
+		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 :-).
 		}
-		doh.registerDocTests = function(module){
-			//	summary:
-			//		Get 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;
-			var tests = [];
-			for (var i=0; i<len; i++){
-				var test = docTests[i];
-				// Extract comment on first line and add to test name.
-				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 :-).
-				}
-				tests.push({
-					runTest: (function(test){
-						return function(t){
-							var r = docTest.runTest(test.commands, test.expectedResult);
-							t.assertTrue(r.success);
-						}
-					})(test),
-					name:"Line "+test.line+comment
-				}
-				);
-			}
-			this.register("DocTests: "+module, tests);
+		tests.push({
+			runTest: (function(test){
+				return function(t){
+					var r = docTest.runTest(test.commands, test.expectedResult);
+					t.assertTrue(r.success);
+				};
+			})(test),
+			name:"Line "+test.line+comment
 		}
+		);
 	}
-})();
+	this.register("DocTests: "+module, tests);
+};
 
 //
-// Assertions and In-Test Utilities
+// depricated 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
+	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];
+	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
+	doh.register(group, ns);
+};
+
+doh.registerTests = function(/*String*/ group, /*Array*/ testArr, /*String*/ type){
+	// summary:
+	//		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
+	doh.register(group + (type ? "!" + type : ""), url+"", timeout || 10000, args || {});
+};
+
+//
+// Assertions and In-Test Utilities
+//
 doh.t = doh.assertTrue = function(/*Object*/ condition, /*String?*/ hint){
 	// summary:
 	//		is the passed item "truthy"?
 	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){
+	//	return true;
+	//}
 	if(!eval(condition)){
 		throw new doh._AssertFailure("assertTrue('" + condition + "') failed", hint);
 	}
-}
+};
 
 doh.f = doh.assertFalse = function(/*Object*/ condition, /*String?*/ hint){
 	// summary:
@@ -638,7 +879,7 @@ doh.f = doh.assertFalse = function(/*Object*/ condition, /*String?*/ hint){
 	if(eval(condition)){
 		throw new doh._AssertFailure("assertFalse('" + condition + "') failed", hint);
 	}
-}
+};
 
 doh.e = doh.assertError = function(/*Error object*/expectedError, /*Object*/scope, /*String*/functionName, /*Array*/args, /*String?*/ hint){
 	//	summary:
@@ -650,16 +891,16 @@ doh.e = doh.assertError = function(/*Error object*/expectedError, /*Object*/scop
 		scope[functionName].apply(scope, args);
 	}catch (e){
 		if(e instanceof expectedError){
+
 			return true;
 		}else{
 			throw new doh._AssertFailure("assertError() failed:\n\texpected error\n\t\t"+expectedError+"\n\tbut got\n\t\t"+e+"\n\n", hint);
 		}
 	}
 	throw new doh._AssertFailure("assertError() failed:\n\texpected error\n\t\t"+expectedError+"\n\tbut no error caught\n\n", hint);
-}
-
+};
 
-doh.is = doh.assertEqual = function(/*Object*/ expected, /*Object*/ actual, /*String?*/ hint){
+doh.is = doh.assertEqual = function(/*Object*/ expected, /*Object*/ actual, /*String?*/ hint, doNotThrow){
 	// summary:
 	//		are the passed expected and actual objects/values deeply
 	//		equivalent?
@@ -674,9 +915,10 @@ doh.is = doh.assertEqual = function(/*Object*/ expected, /*Object*/ actual, /*St
 	}
 	if((expected === actual)||(expected == actual)||
 				( typeof expected == "number" && typeof actual == "number" && isNaN(expected) && isNaN(actual) )){
+
 		return true;
 	}
-	if(	(this._isArray(expected) && this._isArray(actual))&&
+	if( (this.isArray(expected) && this.isArray(actual))&&
 		(this._arrayEq(expected, actual)) ){
 		return true;
 	}
@@ -684,8 +926,11 @@ doh.is = doh.assertEqual = function(/*Object*/ expected, /*Object*/ actual, /*St
 		(this._objPropEq(expected, actual)) ){
 		return true;
 	}
+	if (doNotThrow) {
+		return false;
+	}
 	throw new doh._AssertFailure("assertEqual() failed:\n\texpected\n\t\t"+expected+"\n\tbut got\n\t\t"+actual+"\n\n", hint);
-}
+};
 
 doh.isNot = doh.assertNotEqual = function(/*Object*/ notExpected, /*Object*/ actual, /*String?*/ hint){
 	// summary:
@@ -695,15 +940,15 @@ doh.isNot = doh.assertNotEqual = function(/*Object*/ notExpected, /*Object*/ act
 	// Compare undefined always with three equal signs, because undefined==null
 	// is true, but undefined===null is false.
 	if((notExpected === undefined)&&(actual === undefined)){
-        throw new doh._AssertFailure("assertNotEqual() failed: not expected |"+notExpected+"| but got |"+actual+"|", hint);
+				throw new doh._AssertFailure("assertNotEqual() failed: not expected |"+notExpected+"| but got |"+actual+"|", hint);
 	}
 	if(arguments.length < 2){
 		throw doh._AssertFailure("assertEqual failed because it was not passed 2 arguments");
 	}
 	if((notExpected === actual)||(notExpected == actual)){
-        throw new doh._AssertFailure("assertNotEqual() failed: not expected |"+notExpected+"| but got |"+actual+"|", hint);
+				throw new doh._AssertFailure("assertNotEqual() failed: not expected |"+notExpected+"| but got |"+actual+"|", hint);
 	}
-	if(	(this._isArray(notExpected) && this._isArray(actual))&&
+	if( (this.isArray(notExpected) && this.isArray(actual))&&
 		(this._arrayEq(notExpected, actual)) ){
 		throw new doh._AssertFailure("assertNotEqual() failed: not expected |"+notExpected+"| but got |"+actual+"|", hint);
 	}
@@ -717,20 +962,20 @@ doh.isNot = doh.assertNotEqual = function(/*Object*/ notExpected, /*Object*/ act
 			}
 		}
 		if(isequal){
-        throw new doh._AssertFailure("assertNotEqual() failed: not expected |"+notExpected+"| but got |"+actual+"|", hint);
-	}
+				throw new doh._AssertFailure("assertNotEqual() failed: not expected |"+notExpected+"| but got |"+actual+"|", hint);
+		}
 	}
-    return true;
-}
+	return true;
+};
 
 doh._arrayEq = function(expected, actual){
 	if(expected.length != actual.length){ return false; }
 	// FIXME: we're not handling circular refs. Do we care?
 	for(var x=0; x<expected.length; x++){
-		if(!doh.assertEqual(expected[x], actual[x])){ return false; }
+		if(!doh.assertEqual(expected[x], actual[x], 0, true)){ return false; }
 	}
 	return true;
-}
+};
 
 doh._objPropEq = function(expected, actual){
 	// Degenerate case: if they are both null, then their "properties" are equal.
@@ -753,32 +998,23 @@ doh._objPropEq = function(expected, actual){
 	};
 
 	for(x in expected){
-		if(!doh.assertEqual(expected[x], actual[x])){
+		if(!doh.assertEqual(expected[x], actual[x], 0, true)){
 			return false;
 		}
 	}
 	return true;
-}
-
-doh._isArray = function(it){
-	return (it && it instanceof Array || typeof it == "array" ||
-		(
-			!!doh.global["dojo"] &&
-			doh.global["dojo"]["NodeList"] !== undefined &&
-			it instanceof doh.global["dojo"]["NodeList"]
-		)
-	);
-}
+};
 
 //
 // Runner-Wrapper
 //
 
-doh._setupGroupForRun = function(/*String*/ groupName, /*Integer*/ idx){
+doh._setupGroupForRun = function(/*String*/ groupName){
 	var tg = this._groups[groupName];
 	this.debug(this._line);
 	this.debug("GROUP", "\""+groupName+"\"", "has", tg.length, "test"+((tg.length > 1) ? "s" : "")+" to run");
-}
+	doh._groupStarted(groupName);
+};
 
 doh._handleFailure = function(groupName, fixture, e){
 	// this.debug("FAILED test:", fixture.name);
@@ -789,41 +1025,32 @@ doh._handleFailure = function(groupName, fixture, e){
 		this._failureCount++;
 		if(e["fileName"]){ out += e.fileName + ':'; }
 		if(e["lineNumber"]){ out += e.lineNumber + ' '; }
-		out += e+": "+e.message;
-		this.debug("\t_AssertFailure:", out);
+		out += e.message;
+		this.error("\t_AssertFailure:", out);
 	}else{
 		this._errorCount++;
+		this.error("\tError:", e.message || e); // printing Error on IE9 (and other browsers?) yields "[Object Error]"
 	}
-	this.error(e);
 	if(fixture.runTest["toSource"]){
 		var ss = fixture.runTest.toSource();
 		this.debug("\tERROR IN:\n\t\t", ss);
 	}else{
 		this.debug("\tERROR IN:\n\t\t", fixture.runTest);
 	}
-
 	if(e.rhinoException){
 		e.rhinoException.printStackTrace();
 	}else if(e.javaException){
 		e.javaException.printStackTrace();
 	}
-}
-
-try{
-	setTimeout(function(){}, 0);
-}catch(e){
-	setTimeout = function(func){
-		return func();
-	}
-}
+};
 
 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
+	//		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
 	//		iteration to allow for GC cleanup and the like.
 	//
@@ -869,7 +1096,7 @@ doh._runPerfFixture = function(/*String*/groupName, /*Object*/fixture){
 			def.errback(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){
 		if(timer){
@@ -893,14 +1120,14 @@ doh._runPerfFixture = function(/*String*/groupName, /*Object*/fixture){
 	});
 
 	//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.
+	//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);
+						"]\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.
@@ -921,8 +1148,8 @@ doh._runPerfFixture = function(/*String*/groupName, /*Object*/fixture){
 							if(state.countdown){
 								var ret = fixture.runTest(doh);
 								if(ret && ret.addCallback){
-									// Deferreds have to be handled async,
-									// otherwise we just keep looping.
+									//Deferreds have to be handled async,
+									//otherwise we just keep looping.
 									var atState = {
 										countdown: state.countdown
 									};
@@ -956,9 +1183,9 @@ doh._runPerfFixture = function(/*String*/groupName, /*Object*/fixture){
 					};
 					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.");
+								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--;
@@ -992,11 +1219,11 @@ doh._runPerfFixture = function(/*String*/groupName, /*Object*/fixture){
 	return def;
 };
 
-doh._calcTrialIterations =  function(/*String*/ groupName, /*Object*/ fixture){
+doh._calcTrialIterations =	function(/*String*/ groupName, /*Object*/ fixture){
 	//	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.
@@ -1007,8 +1234,8 @@ doh._calcTrialIterations =  function(/*String*/ groupName, /*Object*/ fixture){
 	var calibrate = function () {
 		var testFunc = doh.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
+		//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(),
@@ -1049,7 +1276,7 @@ doh._calcTrialIterations =  function(/*String*/ groupName, /*Object*/ fixture){
 						var nState = {
 							iterations: state.iterations * 2,
 							curIter: 0
-						}
+						};
 						state = null;
 						setTimeout(function(){
 							nState.start = new Date();
@@ -1071,7 +1298,7 @@ doh._calcTrialIterations =  function(/*String*/ groupName, /*Object*/ fixture){
 
 doh._runRegFixture = function(/*String*/groupName, /*Object*/fixture){
 	//	summary:
-	//		Function to run a generic doh test.  These are not
+	//		Function to run a generic doh test.	 These are not
 	//		specialized tests, like performance groups and such.
 	//
 	//	groupName:
@@ -1095,16 +1322,17 @@ doh._runRegFixture = function(/*String*/groupName, /*Object*/fixture){
 		});
 
 		var retEnd = function(){
+
 			if(fixture["tearDown"]){ fixture.tearDown(doh); }
 			tg.inFlight--;
+			doh._testFinished(groupName, fixture, ret.results[0]);
 			if((!tg.inFlight)&&(tg.iterated)){
 				doh._groupFinished(groupName, !tg.failures);
 			}
-			doh._testFinished(groupName, fixture, ret.results[0]);
 			if(doh._paused){
 				doh.run();
 			}
-		}
+		};
 
 		var timeoutFunction = function(){
 			fixture.endTime = new Date();
@@ -1139,7 +1367,7 @@ 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.
 				return doh._runPerfFixture(groupName, fixture);
@@ -1170,7 +1398,7 @@ doh._runFixture = function(groupName, fixture){
 			doh._groupFinished(groupName, !tg.failures);
 		}else if(tg.inFlight > 0){
 			setTimeout(this.hitch(this, function(){
-				doh.runGroup(groupName); // , idx);
+				doh.runGroup(groupName);
 			}), 100);
 			this._paused = true;
 		}
@@ -1180,9 +1408,8 @@ doh._runFixture = function(groupName, fixture){
 	}), 30);
 	doh.pause();
 	return d;
-}
+};
 
-doh._testId = 0;
 doh.runGroup = function(/*String*/ groupName, /*Integer*/ idx){
 	// summary:
 	//		runs the specified test group
@@ -1196,27 +1423,18 @@ doh.runGroup = function(/*String*/ groupName, /*Integer*/ idx){
 
 	// FIXME: need to make fixture execution async!!
 
+	idx= idx || 0;
 	var tg = this._groups[groupName];
 	if(tg.skip === true){ return; }
-	if(this._isArray(tg)){
-		if(idx<=tg.length){
-			if((!tg.inFlight)&&(tg.iterated == true)){
-				if(tg["tearDown"]){ tg.tearDown(this); }
-				doh._groupFinished(groupName, !tg.failures);
-				return;
-			}
-		}
-		if(!idx){
-			tg.inFlight = 0;
+	if(this.isArray(tg)){
+		if(tg.iterated===undefined){
 			tg.iterated = false;
+			tg.inFlight = 0;
 			tg.failures = 0;
-		}
-		doh._groupStarted(groupName);
-		if(!idx){
-			this._setupGroupForRun(groupName, idx);
+			this._setupGroupForRun(groupName);
 			if(tg["setUp"]){ tg.setUp(this); }
 		}
-		for(var y=(idx||0); y<tg.length; y++){
+		for(var y=idx; y<tg.length; y++){
 			if(this._paused){
 				this._currentTest = y;
 				// this.debug("PAUSED at:", tg[y].name, this._currentGroup, this._currentTest);
@@ -1225,7 +1443,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){
+				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);
@@ -1238,9 +1456,9 @@ doh.runGroup = function(/*String*/ groupName, /*Integer*/ idx){
 			doh._groupFinished(groupName, !tg.failures);
 		}
 	}
-}
+};
 
-doh._onEnd = function(){}
+doh._onEnd = function(){};
 
 doh._report = function(){
 	// summary:
@@ -1257,17 +1475,17 @@ doh._report = function(){
 	this.debug("\t", this._testCount, "tests in", this._groupCount, "groups");
 	this.debug("\t", this._errorCount, "errors");
 	this.debug("\t", this._failureCount, "failures");
-}
+};
 
 doh.togglePaused = function(){
 	this[(this._paused) ? "run" : "pause"]();
-}
+};
 
 doh.pause = function(){
 	// summary:
 	//		halt test run. Can be resumed.
 	this._paused = true;
-}
+};
 
 doh.run = function(){
 	// summary:
@@ -1283,7 +1501,6 @@ doh.run = function(){
 	}
 	this._currentGroup = null;
 	this._currentTest = null;
-
 	for(var x in this._groups){
 		if(
 			( (!found)&&(x == cg) )||( found )
@@ -1304,210 +1521,19 @@ doh.run = function(){
 	this._paused = false;
 	this._onEnd();
 	this._report();
-}
-
-//Statistics functions to handle computing performance metrics.
-//Taken from dojox.math
-//	basic statistics
-doh.standardDeviation = function(/* Number[] */a){
-	//	summary:
-	//		Returns the standard deviation of the passed arguments.
-	return Math.sqrt(this.variance(a));	//	Number
-};
-
-doh.variance = function(/* Number[] */a){
-	//	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
-};
-
-doh.mean = function(/* Number[] */a){
-	//	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
-};
-
-doh.min = function(/* Number[] */a){
-	//	summary:
-	//		Returns the min value in the passed array.
-	return Math.min.apply(null, a);		//	Number
 };
 
-doh.max = function(/* Number[] */a){
-	//	summary:
-	//		Returns the max value in the passed array.
-	return Math.max.apply(null, a);		//	Number
-},
-
-doh.median= function(/* Number[] */a){
-	//	summary:
-	//		Returns the value closest to the middle from a sorted version of the passed array.
-	return a.slice(0).sort()[Math.ceil(a.length/2)-1];	//	Number
-},
-
-doh.mode = function(/* Number[] */a){
-	//	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.
-	var o = {}, r = 0, m = Number.MIN_VALUE;
-	dojo.forEach(a, function(v){
-		(o[v]!==undefined)?o[v]++:o[v]=1;
-	});
-
-	//	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
+doh.runOnLoad = function(){
+	dojo.ready(doh, "run");
 };
 
-doh.average = function(/* Number [] */ a){
-	var i;
-	var s = 0;
-	for(i = 0; i < a.length; i++){
-		s += a[i];
-	}
-	return s/a.length;
-}
-
-tests = doh;
-
-(function(){
-	// scope protection
-	var x;
-	try{
-		if(typeof dojo != "undefined"){
-			dojo.require(dojo.isBrowser ? "doh._browserRunner" : "doh._rhinoRunner");
-			try{
-				var _shouldRequire = dojo.isBrowser ? (dojo.global == dojo.global["parent"] || !Boolean(dojo.global.parent.doh) ) : true;
-			}catch(e){
-				//can't access dojo.global.parent.doh, then we need to do require
-				_shouldRequire = true;
-			}
-			if(_shouldRequire && dojo.isBrowser){
-				dojo.addOnLoad(function(){
-					if (dojo.global.registerModulePath){
-						dojo.forEach(dojo.global.registerModulePath, function(m){
-							dojo.registerModulePath(m[0], m[1]);
-						});
-					}
-				});
-			}
-		}else if(typeof load == "function"){
-			throw new Error();
-		}else if(typeof define == "function" && define.vendor!="dojotoolkit.org"){
-			// using a real AMD loader; it will load runnerFile
-		}else if(this["document"]){
-			// if we survived all of that, we're probably in a browser but
-			// don't have Dojo handy and/or are using an AMD loader.
-			// Load _browserRunner.js using a document.write() call.
-
-			// find runner.js, load _browserRunner relative to it
-			var scripts = document.getElementsByTagName("script"), runnerFile;
-			for(x=0; x<scripts.length; x++){
-				var s = scripts[x].src;
-				if(s){
-					if(!runnerFile && s.substr(s.length - 9) == "runner.js"){
-						runnerFile = s;
-					}else if(s.substr(s.length - 17) == "_browserRunner.js"){
-						runnerFile = null;
-						break;
-					}
-				}
-			}
-			if(runnerFile){
-				document.write("<scri"+"pt src='" + runnerFile.substr(0, runnerFile.length - 9)
-					+ "_browserRunner.js' type='text/javascript'></scr"+"ipt>");
-			}
-		}
-	}catch(e){
-		print("\n"+doh._line);
-		print("The Dojo Unit Test Harness, $Rev: 24146 $");
-		print("Copyright (c) 2011, The Dojo Foundation, All Rights Reserved");
-		print(doh._line, "\n");
-
-		try{
-			var dojoUrl = "../../dojo/dojo.js";
-			var testUrl = "";
-			var testModule = "dojo.tests.module";
-			var dohBase = "";
-
-			for(x=0; x<scriptArgs.length; x++){
-				if(scriptArgs[x].indexOf("=") > 0){
-					var tp = scriptArgs[x].split("=");
-					if(tp[0] == "dohBase"){
-						dohBase = tp[1];
-						//Convert slashes to unix style and make sure properly ended.
-						dohBase = dohBase.replace(/\\/g, "/");
-						if(dohBase.charAt(dohBase.length - 1) != "/"){
-							dohBase += "/";
-						}
-					}
-					if(tp[0] == "dojoUrl"){
-						dojoUrl = tp[1];
-					}
-					if(tp[0] == "testUrl"){
-						testUrl = tp[1];
-					}
-					if(tp[0] == "testModule"){
-						testModule = tp[1];
-					}
-				}
-			}
-
-			load(dohBase + "_rhinoRunner.js");
-
-			if(dojoUrl.length){
-				if(!this["djConfig"]){
-					djConfig = {};
-				}
-				djConfig.baseUrl = dojoUrl.split("dojo.js")[0];
-				load(dojoUrl);
-			}
-			if(testUrl.length){
-				load(testUrl);
-			}
-			if(testModule.length){
-				dojo.forEach(testModule.split(","), dojo.require, dojo);
-			}
-		}catch(e){
-			print("An exception occurred: " + e);
-		}
-
-		doh.run();
-	}
-}).apply(this, []);
-
 return doh;
 
-};//end of definition of doh/runner, which really defines global doh
+});
 
-// this is guaranteed in the global scope, not matter what kind of eval is thrown at us
-// define global doh
-if(typeof doh == "undefined"){
-	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.
+if (typeof window!="undefined" && typeof location!="undefined" && typeof document!="undefined" && window.location==location && window.document==document) {
+	require(["doh/_browserRunner"]);
 }
-if(typeof define == "undefined" || define.vendor=="dojotoolkit.org"){
-	// using dojo 1.x loader or no dojo on the page
-	if(typeof dojo !== "undefined"){
-		dojo.provide("doh.runner");
-	}
-	d(doh);
-}else{
-	// using an AMD loader
-	doh.runnerFactory= d;
-}
-
-}).call(null, typeof arguments=="undefined" ? [] : Array.prototype.slice.call(arguments));
\ No newline at end of file
diff --git a/util/doh/runner.sh b/util/doh/runner.sh
index c4ced4a..b986005 100755
--- a/util/doh/runner.sh
+++ b/util/doh/runner.sh
@@ -1,3 +1,3 @@
 #!/bin/sh
 
-java -jar ../shrinksafe/js.jar runner.js "$@"
+java -jar ../shrinksafe/js.jar ../../dojo/dojo.js baseUrl=../../dojo load=doh "$@"
\ No newline at end of file
diff --git a/util/doh/tests/scopeTest.js b/util/doh/tests/scopeTest.js
new file mode 100644
index 0000000..34159d5
--- /dev/null
+++ b/util/doh/tests/scopeTest.js
@@ -0,0 +1,15 @@
+// to run this test and see it pass, try (note sandbox and async parameters)
+//	 * path/to/dojotoolkit/util/doh/runner.html?test=doh/tests/scopeTest&sandbox&async
+//
+// to run this test and see it fail, try either of (note no sandbox parameter)
+//	 * path/to/dojotoolkit/util/doh/runner.html?test=doh/tests/scopeTest
+//	 * path/to/dojotoolkit/util/doh/runner.html?test=doh/tests/scopeTest&async
+
+define(["doh/runner"], function(doh) {
+	var global= this;
+	doh.register("scope", function(t){
+		t.is(global.dojo, undefined, "dojo global was defined");
+		t.isNot(global.dohDojo, undefined, "dohDojo global was not defined");
+		t.isNot(require("dohDojo"), undefined, "dohDojo module was not defined");
+	});
+});
diff --git a/util/doh/tests/selfTest.js b/util/doh/tests/selfTest.js
new file mode 100644
index 0000000..5c6fbcd
--- /dev/null
+++ b/util/doh/tests/selfTest.js
@@ -0,0 +1,244 @@
+define(["doh/runner"], function(doh) {
+
+
+	doh.register("doh/selftest/lastTest", function(t){
+		t.assertTrue(true);
+	});
+
+	var
+	tObj1 = { a:0, b:1, c:true, d:false, e:{}, f:{a:"x"}, g:"", h:"hellp", i:null},
+	tObj2 = { a:0, b:1, c:true, d:false, e:{}, f:{a:"x"}, g:"", h:"hellp", i:null}, // equal
+	tObja = { a:1, b:1, c:true, d:false, e:{}, f:{a:"x"}, g:"", h:"hellp", i:null}, // delta a
+	tObjb = { a:0, b:2, c:true, d:false, e:{}, f:{a:"x"}, g:"", h:"hellp", i:null}, // delta b
+	tObjc = { a:0, b:1, c:false, d:false, e:{}, f:{a:"x"}, g:"", h:"hellp", i:null}, // delta c
+	tObjd = { a:0, b:1, c:true, d:true, e:{}, f:{a:"x"}, g:"", h:"hellp", i:null}, // delta d
+	tObje = { a:0, b:1, c:true, d:false, e:{a:"x"}, f:{a:"x"}, g:"", h:"hellp", i:null}, // delta e
+	tObjf1= { a:0, b:1, c:true, d:false, e:{}, f:{a:"y"}, g:"", h:"hellp", i:null}, // delta f.a
+	tObjf2= { a:0, b:1, c:true, d:false, e:{}, f:{b:"x"}, g:"", h:"hellp", i:null}, // delta f, property
+	tObjg = { a:0, b:1, c:true, d:false, e:{}, f:{}, g:"x", h:"hellp", i:null}, // delta g
+	tObjh = { a:0, b:1, c:true, d:false, e:{}, f:{}, g:"", h:"hello", i:null}, // delta h
+	tObji = { a:0, b:1, c:true, d:false, e:{}, f:{}, g:"", h:"hellp", i:0}, // delta i
+
+	tArray1 = [0, 1, true,	false, {},		{a:"x"}, "",  "hello", null],
+	tArray2 = [0, 1, true,	false, {},		{a:"x"}, "",  "hello", null],
+	tArraya = [1, 1, true,	false, {},		{a:"x"}, "",  "hellp", null], // delta a
+	tArrayb = [0, 2, true,	false, {},		{a:"x"}, "",  "hellp", null], // delta b
+	tArrayc = [0, 1, false, false, {},		{a:"x"}, "",  "hellp", null], // delta c
+	tArrayd = [0, 1, true,	true,  {},		{a:"x"}, "",  "hellp", null], // delta d
+	tArraye = [0, 1, true,	false, {a:"x"}, {a:"x"}, "",  "hellp", null], // delta e
+	tArrayf1= [0, 1, true,	false, {},		{a:"y"}, "",  "hellp", null], // delta f.a
+	tArrayf2= [0, 1, true,	false, {},		{b:"x"}, "",  "hellp", null], // delta f, property
+	tArrayg = [0, 1, true,	false, {},		{},		 "x", "hellp", null], // delta g
+	tArrayh = [0, 1, true,	false, {},		{},		 "",  "hello", null], // delta h
+	tArrayi = [0, 1, true,	false, {},		{},		 "",  "hellp", 0]; // delta i
+
+
+	doh.register("doh/asserts/pass", function(t){
+		function check(method, args){
+			t[method].apply(t, args);
+		};
+
+		check("assertTrue", [true]);
+		check("assertTrue", [{}]);
+		check("assertTrue", [1]);
+		//check("assertTrue", ["hello"]);
+
+		check("assertFalse", [false]);
+		check("assertFalse", [0]);
+		check("assertFalse", [null]);
+		check("assertFalse", [undefined]);
+		check("assertFalse", [(function(){})()]);
+
+		check("assertEqual", [[], []]);
+		check("assertEqual", [[1], [1]]);
+		check("assertEqual", [[1,2], [1,2]]);
+		check("assertEqual", [[1,2,3], [1,2,3]]);
+		check("assertEqual", [tObj1, tObj1]);
+		check("assertEqual", [tObj1, tObj2]);
+		check("assertEqual", [tArray1, tArray2]);
+
+		check("assertNotEqual", [tObj1, tObja]);
+		check("assertNotEqual", [tObj1, tObjb]);
+		check("assertNotEqual", [tObj1, tObjc]);
+		check("assertNotEqual", [tObj1, tObjd]);
+		check("assertNotEqual", [tObj1, tObje]);
+		check("assertNotEqual", [tObj1, tObjf1]);
+		check("assertNotEqual", [tObj1, tObjf2]);
+		check("assertNotEqual", [tObj1, tObjg]);
+		check("assertNotEqual", [tObj1, tObjh]);
+		check("assertNotEqual", [tObj1, tObji]);
+
+		check("assertNotEqual", [tArray1, tArraya]);
+		check("assertNotEqual", [tArray1, tArrayb]);
+		check("assertNotEqual", [tArray1, tArrayc]);
+		check("assertNotEqual", [tArray1, tArrayd]);
+		check("assertNotEqual", [tArray1, tArraye]);
+		check("assertNotEqual", [tArray1, tArrayf1]);
+		check("assertNotEqual", [tArray1, tArrayf2]);
+		check("assertNotEqual", [tArray1, tArrayg]);
+		check("assertNotEqual", [tArray1, tArrayh]);
+		check("assertNotEqual", [tArray1, tArrayi]);
+	});
+
+	doh.register("doh/asserts/fail", function(t){
+		function check(method, args){
+			try{
+				t[method].apply(t, args);
+			}catch(e){
+				t.assertTrue(true);
+				return;
+			}
+			throw new doh._AssertFailure("failed: " + method);
+		}
+		check("assertFalse", [true]);
+		check("assertFalse", [{}]);
+		check("assertFalse", [1]);
+		//check("assertFalse", ["hello"]);
+
+		check("assertTrue", [false]);
+		check("assertTrue", [0]);
+		check("assertTrue", [null]);
+		check("assertTrue", [undefined]);
+		check("assertTrue", [(function(){})()]);
+
+		check("assertNotEqual", [[], []]);
+		check("assertNotEqual", [[1], [1]]);
+		check("assertNotEqual", [[1,2], [1,2]]);
+		check("assertNotEqual", [[1,2,3], [1,2,3]]);
+		check("assertNotEqual", [tObj1, tObj1]);
+		check("assertNotEqual", [tObj1, tObj2]);
+		check("assertNotEqual", [tArray1, tArray2]);
+
+		check("assertEqual", [tObj1, tObja]);
+		check("assertEqual", [tObj1, tObjb]);
+		check("assertEqual", [tObj1, tObjc]);
+		check("assertEqual", [tObj1, tObjd]);
+		check("assertEqual", [tObj1, tObje]);
+		check("assertEqual", [tObj1, tObjf1]);
+		check("assertEqual", [tObj1, tObjf2]);
+		check("assertEqual", [tObj1, tObjg]);
+		check("assertEqual", [tObj1, tObjh]);
+		check("assertEqual", [tObj1, tObji]);
+
+		check("assertEqual", [tArray1, tArraya]);
+		check("assertEqual", [tArray1, tArrayb]);
+		check("assertEqual", [tArray1, tArrayc]);
+		check("assertEqual", [tArray1, tArrayd]);
+		check("assertEqual", [tArray1, tArraye]);
+		check("assertEqual", [tArray1, tArrayf1]);
+		check("assertEqual", [tArray1, tArrayf2]);
+		check("assertEqual", [tArray1, tArrayg]);
+		check("assertEqual", [tArray1, tArrayh]);
+		check("assertEqual", [tArray1, tArrayi]);
+	});
+
+	// test the highly overloaded doh.register signature
+	var currentFixture;
+	dojo.connect(doh, "_testStarted", function(groupId, fixture){
+		currentFixture= fixture;
+	});
+
+	var lastId;
+	function f(id, tid) {
+		return function() {
+			if(tid){
+				doh.assertTrue(currentFixture.name==tid);
+			}
+			if(id){
+				doh.assertTrue(lastId+1==id);
+				lastId= id;
+			}
+		};
+	};
+
+	var hijack= doh._setupGroupForRun;
+	doh._setupGroupForRun= function(groupName){
+		lastId= 0;
+		hijack.call(doh, groupName);
+	};
+
+	// note: the tests that are commented out below all have zero for the setup function
+	// and a real teardown function. For now, this is
+
+
+	doh.register("myGroup2-1", f(2), f(1), f(3));
+	doh.register("myGroup2-2", f(2), f(1));
+	doh.register("myGroup2-4", f(1));
+
+	dohSelfTestLog5= f(2);
+	dohSelfTestLog6= f(2);
+	dohSelfTestLog7= f(1);
+	dohSelfTestLog8= f(1);
+
+	doh.register("myGroup2-5", "dohSelfTestLog5();", f(1), f(3));
+	doh.register("myGroup2-6", "dohSelfTestLog6();", f(1));
+	doh.register("myGroup2-8", "dohSelfTestLog8();");
+
+	doh.register("myGroup2-9", [f(2), f(3)], f(1), f(4));
+	doh.register("myGroup2-10", [f(2), f(3)], f(1));
+	doh.register("myGroup2-12", [f(1), f(2)]);
+
+	doh.register("myGroup2-13", {t1:f(0, "t1"), t2:f(0, "t2")}, f(1), f(2));
+	doh.register("myGroup2-14", {t3:f(0, "t3"), t4:f(0, "t4")}, f(1));
+	doh.register("myGroup2-16", {t7:f(0, "t7"), t8:f(0, "t8")});
+
+	doh.register("myGroup2-17", {name:"t9", runTest:f(2, "t9")}, f(1), f(3));
+	doh.register("myGroup2-18", {name:"t10", runTest:f(2, "t10")}, f(1));
+	doh.register("myGroup2-20", {name:"t12", runTest:f(1, "t12")});
+
+	doh.register("myGroup2-21", {name:"tx", runTest:f(3), setUp:f(2)}, f(1), f(4));
+	doh.register("myGroup2-22", {name:"tx", runTest:f(3), setUp:f(2)}, f(1));
+	doh.register("myGroup2-24", {name:"tx", runTest:f(2), setUp:f(1)});
+
+	doh.register("myGroup2-25", {name:"tx", runTest:f(2), tearDown:f(3)}, f(1), f(4));
+	doh.register("myGroup2-26", {name:"tx", runTest:f(2), tearDown:f(3)}, f(1));
+	doh.register("myGroup2-28", {name:"tx", runTest:f(1), tearDown:f(2)});
+
+	doh.register("myGroup2-29", {name:"tx", runTest:f(3), setUp:f(2), tearDown:f(4)}, f(1), f(5));
+	doh.register("myGroup2-30", {name:"tx", runTest:f(3), setUp:f(2), tearDown:f(4)}, f(1));
+	doh.register("myGroup2-32", {name:"tx", runTest:f(2), setUp:f(1), tearDown:f(3)});
+
+	//v1.6- signatures
+	//TODO
+
+	doh.registerTestType("dohSelfTest", function(group, fixture){
+	});
+	// a stone-stupid async test
+	doh.register("doh/async", [{
+		name: "deferredSuccess",
+		runTest: function(t){
+			var d = new doh.Deferred();
+			setTimeout(d.getTestCallback(function(){
+				t.assertTrue(true);
+				t.assertFalse(false);
+			}), 50);
+			return d;
+		}
+	},{
+		name: "deferredFailure--SHOULD FAIL",
+		runTest: function(t){
+			console.log("running test that SHOULD FAIL");
+			var d = new doh.Deferred();
+			setTimeout(function(){
+				d.errback(new Error("hrm..."));
+			}, 50);
+			return d;
+		}
+	},{
+		name: "timeoutFailure--SHOULD FAIL",
+		timeout: 50,
+		runTest: function(t){
+			console.log("running test that SHOULD FAIL");
+			// timeout of 50
+			var d = new doh.Deferred();
+			setTimeout(function(){
+				d.callback(true);
+			}, 100);
+			return d;
+		}
+	}]);
+
+	doh.register("doh/selftest/lastTest", function(t){
+		t.assertTrue(true);
+	});
+});
diff --git a/util/less/LICENSE b/util/less/LICENSE
new file mode 100644
index 0000000..40f3b78
--- /dev/null
+++ b/util/less/LICENSE
@@ -0,0 +1,179 @@
+
+                              Apache License
+                        Version 2.0, January 2004
+                     http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the 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.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute must
+       include a readable copy of the attribution notices contained
+       within such NOTICE file, excluding those notices that do not
+       pertain to any part of the Derivative Works, in at least one
+       of the following places: within a NOTICE text file distributed
+       as part of the Derivative Works; within the Source form or
+       documentation, if provided along with the Derivative Works; or,
+       within a display generated by the Derivative Works, if and
+       wherever such third-party notices normally appear. The contents
+       of the NOTICE file are for informational purposes only and
+       do not modify the License. You may add Your own attribution
+       notices within Derivative Works that You distribute, alongside
+       or as an addendum to the NOTICE text from the Work, provided
+       that such additional attribution notices cannot be construed
+       as modifying the License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+Copyright (c) 2009-2010 Alexis Sellier
diff --git a/util/less/README b/util/less/README
new file mode 100644
index 0000000..5d91786
--- /dev/null
+++ b/util/less/README
@@ -0,0 +1,7 @@
+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/browser.js b/util/less/browser.js
new file mode 100755
index 0000000..ae2667d
--- /dev/null
+++ b/util/less/browser.js
@@ -0,0 +1,369 @@
+//
+// 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/functions.js b/util/less/functions.js
new file mode 100755
index 0000000..804b9e6
--- /dev/null
+++ b/util/less/functions.js
@@ -0,0 +1,174 @@
+(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
new file mode 100755
index 0000000..4c341f5
--- /dev/null
+++ b/util/less/index.js
@@ -0,0 +1,137 @@
+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/parser.js b/util/less/parser.js
new file mode 100755
index 0000000..8ca4e61
--- /dev/null
+++ b/util/less/parser.js
@@ -0,0 +1,1110 @@
+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/tree.js b/util/less/tree.js
new file mode 100755
index 0000000..eb08aa4
--- /dev/null
+++ b/util/less/tree.js
@@ -0,0 +1,13 @@
+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
new file mode 100755
index 0000000..551ccba
--- /dev/null
+++ b/util/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('less/tree'));
diff --git a/util/less/tree/anonymous.js b/util/less/tree/anonymous.js
new file mode 100755
index 0000000..89840d0
--- /dev/null
+++ b/util/less/tree/anonymous.js
@@ -0,0 +1,13 @@
+(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
new file mode 100755
index 0000000..4a72932
--- /dev/null
+++ b/util/less/tree/call.js
@@ -0,0 +1,45 @@
+(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
new file mode 100755
index 0000000..38d34f8
--- /dev/null
+++ b/util/less/tree/color.js
@@ -0,0 +1,98 @@
+(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
new file mode 100755
index 0000000..2d95dff
--- /dev/null
+++ b/util/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('less/tree'));
diff --git a/util/less/tree/dimension.js b/util/less/tree/dimension.js
new file mode 100755
index 0000000..41f3ca2
--- /dev/null
+++ b/util/less/tree/dimension.js
@@ -0,0 +1,34 @@
+(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
new file mode 100755
index 0000000..fbe9a93
--- /dev/null
+++ b/util/less/tree/directive.js
@@ -0,0 +1,33 @@
+(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
new file mode 100755
index 0000000..27cf822
--- /dev/null
+++ b/util/less/tree/element.js
@@ -0,0 +1,35 @@
+(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
new file mode 100755
index 0000000..f638a1b
--- /dev/null
+++ b/util/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(env);
+        }).join(' ');
+    }
+};
+
+})(require('less/tree'));
diff --git a/util/less/tree/import.js b/util/less/tree/import.js
new file mode 100755
index 0000000..2a95120
--- /dev/null
+++ b/util/less/tree/import.js
@@ -0,0 +1,77 @@
+(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
new file mode 100755
index 0000000..4ec66b9
--- /dev/null
+++ b/util/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('less/tree'));
+
diff --git a/util/less/tree/keyword.js b/util/less/tree/keyword.js
new file mode 100755
index 0000000..a4431ba
--- /dev/null
+++ b/util/less/tree/keyword.js
@@ -0,0 +1,9 @@
+(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
new file mode 100755
index 0000000..24cb8e4
--- /dev/null
+++ b/util/less/tree/mixin.js
@@ -0,0 +1,106 @@
+(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
new file mode 100755
index 0000000..d2e4d57
--- /dev/null
+++ b/util/less/tree/operation.js
@@ -0,0 +1,32 @@
+(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
new file mode 100755
index 0000000..6ddfa40
--- /dev/null
+++ b/util/less/tree/quoted.js
@@ -0,0 +1,29 @@
+(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
new file mode 100755
index 0000000..18cc49b
--- /dev/null
+++ b/util/less/tree/rule.js
@@ -0,0 +1,38 @@
+(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
new file mode 100755
index 0000000..3ba1c13
--- /dev/null
+++ b/util/less/tree/ruleset.js
@@ -0,0 +1,212 @@
+(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
new file mode 100755
index 0000000..eaaa042
--- /dev/null
+++ b/util/less/tree/selector.js
@@ -0,0 +1,28 @@
+(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
new file mode 100755
index 0000000..f427070
--- /dev/null
+++ b/util/less/tree/url.js
@@ -0,0 +1,25 @@
+(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
new file mode 100755
index 0000000..922096c
--- /dev/null
+++ b/util/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('less/tree'));
diff --git a/util/less/tree/variable.js b/util/less/tree/variable.js
new file mode 100755
index 0000000..10f7c08
--- /dev/null
+++ b/util/less/tree/variable.js
@@ -0,0 +1,24 @@
+(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'));

-- 
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